@@ -126,8 +126,9 @@ static struct cp500_devs cp520_devices = {
126126};
127127
128128struct cp500_nvmem {
129- struct nvmem_device * nvmem ;
129+ struct nvmem_device * base_nvmem ;
130130 unsigned int offset ;
131+ struct nvmem_device * nvmem ;
131132};
132133
133134struct cp500 {
@@ -581,8 +582,8 @@ static int cp500_nvmem_read(void *priv, unsigned int offset, void *val,
581582 struct cp500_nvmem * nvmem = priv ;
582583 int ret ;
583584
584- ret = nvmem_device_read (nvmem -> nvmem , nvmem -> offset + offset , bytes ,
585- val );
585+ ret = nvmem_device_read (nvmem -> base_nvmem , nvmem -> offset + offset ,
586+ bytes , val );
586587 if (ret != bytes )
587588 return ret ;
588589
@@ -595,15 +596,16 @@ static int cp500_nvmem_write(void *priv, unsigned int offset, void *val,
595596 struct cp500_nvmem * nvmem = priv ;
596597 int ret ;
597598
598- ret = nvmem_device_write (nvmem -> nvmem , nvmem -> offset + offset , bytes ,
599- val );
599+ ret = nvmem_device_write (nvmem -> base_nvmem , nvmem -> offset + offset ,
600+ bytes , val );
600601 if (ret != bytes )
601602 return ret ;
602603
603604 return 0 ;
604605}
605606
606- static int cp500_nvmem_register (struct cp500 * cp500 , struct nvmem_device * nvmem )
607+ static int cp500_nvmem_register (struct cp500 * cp500 ,
608+ struct nvmem_device * base_nvmem )
607609{
608610 struct device * dev = & cp500 -> pci_dev -> dev ;
609611 struct nvmem_config nvmem_config = {};
@@ -625,27 +627,52 @@ static int cp500_nvmem_register(struct cp500 *cp500, struct nvmem_device *nvmem)
625627 nvmem_config .reg_read = cp500_nvmem_read ;
626628 nvmem_config .reg_write = cp500_nvmem_write ;
627629
628- cp500 -> nvmem_cpu .nvmem = nvmem ;
630+ cp500 -> nvmem_cpu .base_nvmem = base_nvmem ;
629631 cp500 -> nvmem_cpu .offset = CP500_EEPROM_CPU_OFFSET ;
630632 nvmem_config .name = CP500_EEPROM_CPU_NAME ;
631633 nvmem_config .size = CP500_EEPROM_CPU_SIZE ;
632634 nvmem_config .priv = & cp500 -> nvmem_cpu ;
633- tmp = devm_nvmem_register ( dev , & nvmem_config );
635+ tmp = nvmem_register ( & nvmem_config );
634636 if (IS_ERR (tmp ))
635637 return PTR_ERR (tmp );
638+ cp500 -> nvmem_cpu .nvmem = tmp ;
636639
637- cp500 -> nvmem_user .nvmem = nvmem ;
640+ cp500 -> nvmem_user .base_nvmem = base_nvmem ;
638641 cp500 -> nvmem_user .offset = CP500_EEPROM_USER_OFFSET ;
639642 nvmem_config .name = CP500_EEPROM_USER_NAME ;
640643 nvmem_config .size = CP500_EEPROM_USER_SIZE ;
641644 nvmem_config .priv = & cp500 -> nvmem_user ;
642- tmp = devm_nvmem_register (dev , & nvmem_config );
643- if (IS_ERR (tmp ))
645+ tmp = nvmem_register (& nvmem_config );
646+ if (IS_ERR (tmp )) {
647+ nvmem_unregister (cp500 -> nvmem_cpu .nvmem );
648+ cp500 -> nvmem_cpu .nvmem = NULL ;
649+
644650 return PTR_ERR (tmp );
651+ }
652+ cp500 -> nvmem_user .nvmem = tmp ;
645653
646654 return 0 ;
647655}
648656
657+ static void cp500_nvmem_unregister (struct cp500 * cp500 )
658+ {
659+ int notified ;
660+
661+ if (cp500 -> nvmem_user .nvmem ) {
662+ nvmem_unregister (cp500 -> nvmem_user .nvmem );
663+ cp500 -> nvmem_user .nvmem = NULL ;
664+ }
665+ if (cp500 -> nvmem_cpu .nvmem ) {
666+ nvmem_unregister (cp500 -> nvmem_cpu .nvmem );
667+ cp500 -> nvmem_cpu .nvmem = NULL ;
668+ }
669+
670+ /* CPU and user nvmem use the same base_nvmem, put only once */
671+ notified = atomic_read (& cp500 -> nvmem_notified );
672+ if (notified )
673+ nvmem_device_put (cp500 -> nvmem_cpu .base_nvmem );
674+ }
675+
649676static int cp500_nvmem_match (struct device * dev , const void * data )
650677{
651678 const struct cp500 * cp500 = data ;
@@ -663,13 +690,6 @@ static int cp500_nvmem_match(struct device *dev, const void *data)
663690 return 0 ;
664691}
665692
666- static void cp500_devm_nvmem_put (void * data )
667- {
668- struct nvmem_device * nvmem = data ;
669-
670- nvmem_device_put (nvmem );
671- }
672-
673693static int cp500_nvmem (struct notifier_block * nb , unsigned long action ,
674694 void * data )
675695{
@@ -698,10 +718,6 @@ static int cp500_nvmem(struct notifier_block *nb, unsigned long action,
698718 return NOTIFY_DONE ;
699719 }
700720
701- ret = devm_add_action_or_reset (dev , cp500_devm_nvmem_put , nvmem );
702- if (ret )
703- return ret ;
704-
705721 ret = cp500_nvmem_register (cp500 , nvmem );
706722 if (ret )
707723 return ret ;
@@ -932,12 +948,17 @@ static void cp500_remove(struct pci_dev *pci_dev)
932948{
933949 struct cp500 * cp500 = pci_get_drvdata (pci_dev );
934950
951+ /*
952+ * unregister CPU and user nvmem and put base_nvmem before parent
953+ * auxiliary device of base_nvmem is unregistered
954+ */
955+ nvmem_unregister_notifier (& cp500 -> nvmem_notifier );
956+ cp500_nvmem_unregister (cp500 );
957+
935958 cp500_unregister_auxiliary_devs (cp500 );
936959
937960 cp500_disable (cp500 );
938961
939- nvmem_unregister_notifier (& cp500 -> nvmem_notifier );
940-
941962 pci_set_drvdata (pci_dev , 0 );
942963
943964 pci_free_irq_vectors (pci_dev );
0 commit comments