diff mbox

[3/3] mtd: cfi_cmdset_{0001, 0002}: use common MTD reboot boilerplate

Message ID 1417746968-28747-3-git-send-email-computersforpeace@gmail.com
State Deferred
Headers show

Commit Message

Brian Norris Dec. 5, 2014, 2:36 a.m. UTC
We don't have to implement this glue code in the chip driver any more.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
---
Not tested yet

 drivers/mtd/chips/cfi_cmdset_0001.c | 22 +++-------------------
 drivers/mtd/chips/cfi_cmdset_0002.c | 22 +++-------------------
 2 files changed, 6 insertions(+), 38 deletions(-)

Comments

Guenter Roeck Nov. 2, 2015, 8:05 p.m. UTC | #1
On Thu, Dec 04, 2014 at 06:36:08PM -0800, Brian Norris wrote:
> We don't have to implement this glue code in the chip driver any more.
> 
> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
> ---
> Not tested yet
> 
Tested-by: Guenter Roeck <linux@roeck-us.net>

>  drivers/mtd/chips/cfi_cmdset_0001.c | 22 +++-------------------
>  drivers/mtd/chips/cfi_cmdset_0002.c | 22 +++-------------------
>  2 files changed, 6 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
> index 286b97a304cf..3df9744496b2 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0001.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
> @@ -28,7 +28,6 @@
>  #include <linux/slab.h>
>  #include <linux/delay.h>
>  #include <linux/interrupt.h>
> -#include <linux/reboot.h>
>  #include <linux/bitmap.h>
>  #include <linux/mtd/xip.h>
>  #include <linux/mtd/map.h>
> @@ -80,7 +79,7 @@ static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
>  #endif
>  static int cfi_intelext_suspend (struct mtd_info *);
>  static void cfi_intelext_resume (struct mtd_info *);
> -static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *);
> +static void cfi_intelext_reset(struct mtd_info *);
>  
>  static void cfi_intelext_destroy(struct mtd_info *);
>  
> @@ -486,13 +485,12 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
>  	mtd->_is_locked = cfi_intelext_is_locked;
>  	mtd->_suspend = cfi_intelext_suspend;
>  	mtd->_resume  = cfi_intelext_resume;
> +	mtd->_reboot  = cfi_intelext_reset;
>  	mtd->flags   = MTD_CAP_NORFLASH;
>  	mtd->name    = map->name;
>  	mtd->writesize = 1;
>  	mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
>  
> -	mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
> -
>  	if (cfi->cfi_mode == CFI_MODE_CFI) {
>  		/*
>  		 * It's a real CFI chip, not one for which the probe
> @@ -646,7 +644,6 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
>  		goto setup_err;
>  
>  	__module_get(THIS_MODULE);
> -	register_reboot_notifier(&mtd->reboot_notifier);
>  	return mtd;
>  
>   setup_err:
> @@ -2605,7 +2602,7 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
>  		cfi_intelext_restore_locks(mtd);
>  }
>  
> -static int cfi_intelext_reset(struct mtd_info *mtd)
> +static void cfi_intelext_reset(struct mtd_info *mtd)
>  {
>  	struct map_info *map = mtd->priv;
>  	struct cfi_private *cfi = map->fldrv_priv;
> @@ -2626,18 +2623,6 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
>  		}
>  		mutex_unlock(&chip->mutex);
>  	}
> -
> -	return 0;
> -}
> -
> -static int cfi_intelext_reboot(struct notifier_block *nb, unsigned long val,
> -			       void *v)
> -{
> -	struct mtd_info *mtd;
> -
> -	mtd = container_of(nb, struct mtd_info, reboot_notifier);
> -	cfi_intelext_reset(mtd);
> -	return NOTIFY_DONE;
>  }
>  
>  static void cfi_intelext_destroy(struct mtd_info *mtd)
> @@ -2647,7 +2632,6 @@ static void cfi_intelext_destroy(struct mtd_info *mtd)
>  	struct mtd_erase_region_info *region;
>  	int i;
>  	cfi_intelext_reset(mtd);
> -	unregister_reboot_notifier(&mtd->reboot_notifier);
>  	kfree(cfi->cmdset_priv);
>  	kfree(cfi->cfiq);
>  	kfree(cfi->chips[0].priv);
> diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
> index c50d8cf0f60d..c4f63482cf96 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0002.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
> @@ -31,7 +31,6 @@
>  #include <linux/slab.h>
>  #include <linux/delay.h>
>  #include <linux/interrupt.h>
> -#include <linux/reboot.h>
>  #include <linux/of.h>
>  #include <linux/of_platform.h>
>  #include <linux/mtd/map.h>
> @@ -57,7 +56,7 @@ static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
>  static void cfi_amdstd_sync (struct mtd_info *);
>  static int cfi_amdstd_suspend (struct mtd_info *);
>  static void cfi_amdstd_resume (struct mtd_info *);
> -static int cfi_amdstd_reboot(struct notifier_block *, unsigned long, void *);
> +static void cfi_amdstd_reset(struct mtd_info *);
>  static int cfi_amdstd_get_fact_prot_info(struct mtd_info *, size_t,
>  					 size_t *, struct otp_info *);
>  static int cfi_amdstd_get_user_prot_info(struct mtd_info *, size_t,
> @@ -529,6 +528,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
>  	mtd->_sync    = cfi_amdstd_sync;
>  	mtd->_suspend = cfi_amdstd_suspend;
>  	mtd->_resume  = cfi_amdstd_resume;
> +	mtd->_reboot  = cfi_amdstd_reset;
>  	mtd->_read_user_prot_reg = cfi_amdstd_read_user_prot_reg;
>  	mtd->_read_fact_prot_reg = cfi_amdstd_read_fact_prot_reg;
>  	mtd->_get_fact_prot_info = cfi_amdstd_get_fact_prot_info;
> @@ -544,7 +544,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
>  			mtd->writebufsize);
>  
>  	mtd->_panic_write = cfi_amdstd_panic_write;
> -	mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
>  
>  	if (cfi->cfi_mode==CFI_MODE_CFI){
>  		unsigned char bootloc;
> @@ -717,7 +716,6 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
>  	}
>  
>  	__module_get(THIS_MODULE);
> -	register_reboot_notifier(&mtd->reboot_notifier);
>  	return mtd;
>  
>   setup_err:
> @@ -2871,7 +2869,7 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
>   * the flash is in query/program/erase mode will prevent the CPU from
>   * fetching the bootloader code, requiring a hard reset or power cycle.
>   */
> -static int cfi_amdstd_reset(struct mtd_info *mtd)
> +static void cfi_amdstd_reset(struct mtd_info *mtd)
>  {
>  	struct map_info *map = mtd->priv;
>  	struct cfi_private *cfi = map->fldrv_priv;
> @@ -2893,19 +2891,6 @@ static int cfi_amdstd_reset(struct mtd_info *mtd)
>  
>  		mutex_unlock(&chip->mutex);
>  	}
> -
> -	return 0;
> -}
> -
> -
> -static int cfi_amdstd_reboot(struct notifier_block *nb, unsigned long val,
> -			       void *v)
> -{
> -	struct mtd_info *mtd;
> -
> -	mtd = container_of(nb, struct mtd_info, reboot_notifier);
> -	cfi_amdstd_reset(mtd);
> -	return NOTIFY_DONE;
>  }
>  
>  
> @@ -2915,7 +2900,6 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
>  	struct cfi_private *cfi = map->fldrv_priv;
>  
>  	cfi_amdstd_reset(mtd);
> -	unregister_reboot_notifier(&mtd->reboot_notifier);
>  	kfree(cfi->cmdset_priv);
>  	kfree(cfi->cfiq);
>  	kfree(cfi);
Brian Norris Nov. 2, 2015, 9:58 p.m. UTC | #2
On Mon, Nov 02, 2015 at 12:05:13PM -0800, Guenter Roeck wrote:
> On Thu, Dec 04, 2014 at 06:36:08PM -0800, Brian Norris wrote:
> > We don't have to implement this glue code in the chip driver any more.
> > 
> > Signed-off-by: Brian Norris <computersforpeace@gmail.com>
> > ---
> > Not tested yet
> > 
> Tested-by: Guenter Roeck <linux@roeck-us.net>

Thanks! Did you verify that your reboot notifier callback (e.g.,
cfi_intelext_reset()) is actually called on reboot?

And actually, I do see a problem with this patch now, so I'm less likely
to take it as-is; we never guarantee that this mtd_info struct actually
gets registered via mtd_device_parse_register(), so even though we
stick the right callback in mtd->_reboot(), we haven't actually ensured
it will ever get called.

See, for instance, the calling path in (speaking of the devil)
arch/cris/arch-v10/drivers/axisflashmap.c:

static struct mtd_info *flash_probe(void)
{
...
	mtd_cse0 = probe_cs(&map_cse0);
	mtd_cse1 = probe_cs(&map_cse1);
...
        if (mtd_cse0 && mtd_cse1) {
                struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 };

...
                mtd_cse = mtd_concat_create(mtds, ARRAY_SIZE(mtds),
                                            "cse0+cse1");


So, either of map_cse0 or map_cse1 could be a CFI-based map, and so only the
concatenation would be registered, and therefore the reboot() notifier will
just be left assigned to the sub-device, but never registered with the core.

Now, it looks like this is one of very few cases that we'd have to worry
about... right now I've only found physmap_of.c that does the same
mtdconcat stuff. So maybe if we fixed mtdconcat, we could solve this...

MTD is too hairy :(

Anyway, I'll have to NAK my own patch still, and we should probalby go
with your other solution to your current problems from here:

http://lists.infradead.org/pipermail/linux-mtd/2015-November/063022.html

Regards,
Brian

> >  drivers/mtd/chips/cfi_cmdset_0001.c | 22 +++-------------------
> >  drivers/mtd/chips/cfi_cmdset_0002.c | 22 +++-------------------
> >  2 files changed, 6 insertions(+), 38 deletions(-)
> > 
> > diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
> > index 286b97a304cf..3df9744496b2 100644
> > --- a/drivers/mtd/chips/cfi_cmdset_0001.c
> > +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
> > @@ -28,7 +28,6 @@
> >  #include <linux/slab.h>
> >  #include <linux/delay.h>
> >  #include <linux/interrupt.h>
> > -#include <linux/reboot.h>
> >  #include <linux/bitmap.h>
> >  #include <linux/mtd/xip.h>
> >  #include <linux/mtd/map.h>
> > @@ -80,7 +79,7 @@ static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
> >  #endif
> >  static int cfi_intelext_suspend (struct mtd_info *);
> >  static void cfi_intelext_resume (struct mtd_info *);
> > -static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *);
> > +static void cfi_intelext_reset(struct mtd_info *);
> >  
> >  static void cfi_intelext_destroy(struct mtd_info *);
> >  
> > @@ -486,13 +485,12 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
> >  	mtd->_is_locked = cfi_intelext_is_locked;
> >  	mtd->_suspend = cfi_intelext_suspend;
> >  	mtd->_resume  = cfi_intelext_resume;
> > +	mtd->_reboot  = cfi_intelext_reset;
> >  	mtd->flags   = MTD_CAP_NORFLASH;
> >  	mtd->name    = map->name;
> >  	mtd->writesize = 1;
> >  	mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
> >  
> > -	mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
> > -
> >  	if (cfi->cfi_mode == CFI_MODE_CFI) {
> >  		/*
> >  		 * It's a real CFI chip, not one for which the probe
> > @@ -646,7 +644,6 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
> >  		goto setup_err;
> >  
> >  	__module_get(THIS_MODULE);
> > -	register_reboot_notifier(&mtd->reboot_notifier);
> >  	return mtd;
> >  
> >   setup_err:
> > @@ -2605,7 +2602,7 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
> >  		cfi_intelext_restore_locks(mtd);
> >  }
> >  
> > -static int cfi_intelext_reset(struct mtd_info *mtd)
> > +static void cfi_intelext_reset(struct mtd_info *mtd)
> >  {
> >  	struct map_info *map = mtd->priv;
> >  	struct cfi_private *cfi = map->fldrv_priv;
> > @@ -2626,18 +2623,6 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
> >  		}
> >  		mutex_unlock(&chip->mutex);
> >  	}
> > -
> > -	return 0;
> > -}
> > -
> > -static int cfi_intelext_reboot(struct notifier_block *nb, unsigned long val,
> > -			       void *v)
> > -{
> > -	struct mtd_info *mtd;
> > -
> > -	mtd = container_of(nb, struct mtd_info, reboot_notifier);
> > -	cfi_intelext_reset(mtd);
> > -	return NOTIFY_DONE;
> >  }
> >  
> >  static void cfi_intelext_destroy(struct mtd_info *mtd)
> > @@ -2647,7 +2632,6 @@ static void cfi_intelext_destroy(struct mtd_info *mtd)
> >  	struct mtd_erase_region_info *region;
> >  	int i;
> >  	cfi_intelext_reset(mtd);
> > -	unregister_reboot_notifier(&mtd->reboot_notifier);
> >  	kfree(cfi->cmdset_priv);
> >  	kfree(cfi->cfiq);
> >  	kfree(cfi->chips[0].priv);
> > diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
> > index c50d8cf0f60d..c4f63482cf96 100644
> > --- a/drivers/mtd/chips/cfi_cmdset_0002.c
> > +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
> > @@ -31,7 +31,6 @@
> >  #include <linux/slab.h>
> >  #include <linux/delay.h>
> >  #include <linux/interrupt.h>
> > -#include <linux/reboot.h>
> >  #include <linux/of.h>
> >  #include <linux/of_platform.h>
> >  #include <linux/mtd/map.h>
> > @@ -57,7 +56,7 @@ static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
> >  static void cfi_amdstd_sync (struct mtd_info *);
> >  static int cfi_amdstd_suspend (struct mtd_info *);
> >  static void cfi_amdstd_resume (struct mtd_info *);
> > -static int cfi_amdstd_reboot(struct notifier_block *, unsigned long, void *);
> > +static void cfi_amdstd_reset(struct mtd_info *);
> >  static int cfi_amdstd_get_fact_prot_info(struct mtd_info *, size_t,
> >  					 size_t *, struct otp_info *);
> >  static int cfi_amdstd_get_user_prot_info(struct mtd_info *, size_t,
> > @@ -529,6 +528,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
> >  	mtd->_sync    = cfi_amdstd_sync;
> >  	mtd->_suspend = cfi_amdstd_suspend;
> >  	mtd->_resume  = cfi_amdstd_resume;
> > +	mtd->_reboot  = cfi_amdstd_reset;
> >  	mtd->_read_user_prot_reg = cfi_amdstd_read_user_prot_reg;
> >  	mtd->_read_fact_prot_reg = cfi_amdstd_read_fact_prot_reg;
> >  	mtd->_get_fact_prot_info = cfi_amdstd_get_fact_prot_info;
> > @@ -544,7 +544,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
> >  			mtd->writebufsize);
> >  
> >  	mtd->_panic_write = cfi_amdstd_panic_write;
> > -	mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
> >  
> >  	if (cfi->cfi_mode==CFI_MODE_CFI){
> >  		unsigned char bootloc;
> > @@ -717,7 +716,6 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
> >  	}
> >  
> >  	__module_get(THIS_MODULE);
> > -	register_reboot_notifier(&mtd->reboot_notifier);
> >  	return mtd;
> >  
> >   setup_err:
> > @@ -2871,7 +2869,7 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
> >   * the flash is in query/program/erase mode will prevent the CPU from
> >   * fetching the bootloader code, requiring a hard reset or power cycle.
> >   */
> > -static int cfi_amdstd_reset(struct mtd_info *mtd)
> > +static void cfi_amdstd_reset(struct mtd_info *mtd)
> >  {
> >  	struct map_info *map = mtd->priv;
> >  	struct cfi_private *cfi = map->fldrv_priv;
> > @@ -2893,19 +2891,6 @@ static int cfi_amdstd_reset(struct mtd_info *mtd)
> >  
> >  		mutex_unlock(&chip->mutex);
> >  	}
> > -
> > -	return 0;
> > -}
> > -
> > -
> > -static int cfi_amdstd_reboot(struct notifier_block *nb, unsigned long val,
> > -			       void *v)
> > -{
> > -	struct mtd_info *mtd;
> > -
> > -	mtd = container_of(nb, struct mtd_info, reboot_notifier);
> > -	cfi_amdstd_reset(mtd);
> > -	return NOTIFY_DONE;
> >  }
> >  
> >  
> > @@ -2915,7 +2900,6 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
> >  	struct cfi_private *cfi = map->fldrv_priv;
> >  
> >  	cfi_amdstd_reset(mtd);
> > -	unregister_reboot_notifier(&mtd->reboot_notifier);
> >  	kfree(cfi->cmdset_priv);
> >  	kfree(cfi->cfiq);
> >  	kfree(cfi);
Brian Norris Nov. 2, 2015, 10:05 p.m. UTC | #3
On Mon, Nov 02, 2015 at 01:58:18PM -0800, Brian Norris wrote:
> Now, it looks like this is one of very few cases that we'd have to worry
> about... right now I've only found physmap_of.c that does the same
> mtdconcat stuff. So maybe if we fixed mtdconcat, we could solve this...

There's also physmap.c and drivers/mtd/maps/sc520cdp.c. But the problem
only lies when these drivers have to concatenate MTDs, so the original
mtd_info's never get registered on their own.

Brian
Guenter Roeck Nov. 2, 2015, 10:16 p.m. UTC | #4
On Mon, Nov 02, 2015 at 01:58:18PM -0800, Brian Norris wrote:
> On Mon, Nov 02, 2015 at 12:05:13PM -0800, Guenter Roeck wrote:
> > On Thu, Dec 04, 2014 at 06:36:08PM -0800, Brian Norris wrote:
> > > We don't have to implement this glue code in the chip driver any more.
> > > 
> > > Signed-off-by: Brian Norris <computersforpeace@gmail.com>
> > > ---
> > > Not tested yet
> > > 
> > Tested-by: Guenter Roeck <linux@roeck-us.net>
> 
> Thanks! Did you verify that your reboot notifier callback (e.g.,
> cfi_intelext_reset()) is actually called on reboot?
> 
No, I just verified that it boots and shuts down correctly.

Do you want me to verify if the notifier is called, given the
problems you discovered with the patch ?

Thanks,
Guenter

> And actually, I do see a problem with this patch now, so I'm less likely
> to take it as-is; we never guarantee that this mtd_info struct actually
> gets registered via mtd_device_parse_register(), so even though we
> stick the right callback in mtd->_reboot(), we haven't actually ensured
> it will ever get called.
> 
> See, for instance, the calling path in (speaking of the devil)
> arch/cris/arch-v10/drivers/axisflashmap.c:
> 
> static struct mtd_info *flash_probe(void)
> {
> ...
> 	mtd_cse0 = probe_cs(&map_cse0);
> 	mtd_cse1 = probe_cs(&map_cse1);
> ...
>         if (mtd_cse0 && mtd_cse1) {
>                 struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 };
> 
> ...
>                 mtd_cse = mtd_concat_create(mtds, ARRAY_SIZE(mtds),
>                                             "cse0+cse1");
> 
> 
> So, either of map_cse0 or map_cse1 could be a CFI-based map, and so only the
> concatenation would be registered, and therefore the reboot() notifier will
> just be left assigned to the sub-device, but never registered with the core.
> 
> Now, it looks like this is one of very few cases that we'd have to worry
> about... right now I've only found physmap_of.c that does the same
> mtdconcat stuff. So maybe if we fixed mtdconcat, we could solve this...
> 
> MTD is too hairy :(
> 
> Anyway, I'll have to NAK my own patch still, and we should probalby go
> with your other solution to your current problems from here:
> 
> http://lists.infradead.org/pipermail/linux-mtd/2015-November/063022.html
> 
> Regards,
> Brian
> 
> > >  drivers/mtd/chips/cfi_cmdset_0001.c | 22 +++-------------------
> > >  drivers/mtd/chips/cfi_cmdset_0002.c | 22 +++-------------------
> > >  2 files changed, 6 insertions(+), 38 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
> > > index 286b97a304cf..3df9744496b2 100644
> > > --- a/drivers/mtd/chips/cfi_cmdset_0001.c
> > > +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
> > > @@ -28,7 +28,6 @@
> > >  #include <linux/slab.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/interrupt.h>
> > > -#include <linux/reboot.h>
> > >  #include <linux/bitmap.h>
> > >  #include <linux/mtd/xip.h>
> > >  #include <linux/mtd/map.h>
> > > @@ -80,7 +79,7 @@ static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
> > >  #endif
> > >  static int cfi_intelext_suspend (struct mtd_info *);
> > >  static void cfi_intelext_resume (struct mtd_info *);
> > > -static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *);
> > > +static void cfi_intelext_reset(struct mtd_info *);
> > >  
> > >  static void cfi_intelext_destroy(struct mtd_info *);
> > >  
> > > @@ -486,13 +485,12 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
> > >  	mtd->_is_locked = cfi_intelext_is_locked;
> > >  	mtd->_suspend = cfi_intelext_suspend;
> > >  	mtd->_resume  = cfi_intelext_resume;
> > > +	mtd->_reboot  = cfi_intelext_reset;
> > >  	mtd->flags   = MTD_CAP_NORFLASH;
> > >  	mtd->name    = map->name;
> > >  	mtd->writesize = 1;
> > >  	mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
> > >  
> > > -	mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
> > > -
> > >  	if (cfi->cfi_mode == CFI_MODE_CFI) {
> > >  		/*
> > >  		 * It's a real CFI chip, not one for which the probe
> > > @@ -646,7 +644,6 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
> > >  		goto setup_err;
> > >  
> > >  	__module_get(THIS_MODULE);
> > > -	register_reboot_notifier(&mtd->reboot_notifier);
> > >  	return mtd;
> > >  
> > >   setup_err:
> > > @@ -2605,7 +2602,7 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
> > >  		cfi_intelext_restore_locks(mtd);
> > >  }
> > >  
> > > -static int cfi_intelext_reset(struct mtd_info *mtd)
> > > +static void cfi_intelext_reset(struct mtd_info *mtd)
> > >  {
> > >  	struct map_info *map = mtd->priv;
> > >  	struct cfi_private *cfi = map->fldrv_priv;
> > > @@ -2626,18 +2623,6 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
> > >  		}
> > >  		mutex_unlock(&chip->mutex);
> > >  	}
> > > -
> > > -	return 0;
> > > -}
> > > -
> > > -static int cfi_intelext_reboot(struct notifier_block *nb, unsigned long val,
> > > -			       void *v)
> > > -{
> > > -	struct mtd_info *mtd;
> > > -
> > > -	mtd = container_of(nb, struct mtd_info, reboot_notifier);
> > > -	cfi_intelext_reset(mtd);
> > > -	return NOTIFY_DONE;
> > >  }
> > >  
> > >  static void cfi_intelext_destroy(struct mtd_info *mtd)
> > > @@ -2647,7 +2632,6 @@ static void cfi_intelext_destroy(struct mtd_info *mtd)
> > >  	struct mtd_erase_region_info *region;
> > >  	int i;
> > >  	cfi_intelext_reset(mtd);
> > > -	unregister_reboot_notifier(&mtd->reboot_notifier);
> > >  	kfree(cfi->cmdset_priv);
> > >  	kfree(cfi->cfiq);
> > >  	kfree(cfi->chips[0].priv);
> > > diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
> > > index c50d8cf0f60d..c4f63482cf96 100644
> > > --- a/drivers/mtd/chips/cfi_cmdset_0002.c
> > > +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
> > > @@ -31,7 +31,6 @@
> > >  #include <linux/slab.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/interrupt.h>
> > > -#include <linux/reboot.h>
> > >  #include <linux/of.h>
> > >  #include <linux/of_platform.h>
> > >  #include <linux/mtd/map.h>
> > > @@ -57,7 +56,7 @@ static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
> > >  static void cfi_amdstd_sync (struct mtd_info *);
> > >  static int cfi_amdstd_suspend (struct mtd_info *);
> > >  static void cfi_amdstd_resume (struct mtd_info *);
> > > -static int cfi_amdstd_reboot(struct notifier_block *, unsigned long, void *);
> > > +static void cfi_amdstd_reset(struct mtd_info *);
> > >  static int cfi_amdstd_get_fact_prot_info(struct mtd_info *, size_t,
> > >  					 size_t *, struct otp_info *);
> > >  static int cfi_amdstd_get_user_prot_info(struct mtd_info *, size_t,
> > > @@ -529,6 +528,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
> > >  	mtd->_sync    = cfi_amdstd_sync;
> > >  	mtd->_suspend = cfi_amdstd_suspend;
> > >  	mtd->_resume  = cfi_amdstd_resume;
> > > +	mtd->_reboot  = cfi_amdstd_reset;
> > >  	mtd->_read_user_prot_reg = cfi_amdstd_read_user_prot_reg;
> > >  	mtd->_read_fact_prot_reg = cfi_amdstd_read_fact_prot_reg;
> > >  	mtd->_get_fact_prot_info = cfi_amdstd_get_fact_prot_info;
> > > @@ -544,7 +544,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
> > >  			mtd->writebufsize);
> > >  
> > >  	mtd->_panic_write = cfi_amdstd_panic_write;
> > > -	mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
> > >  
> > >  	if (cfi->cfi_mode==CFI_MODE_CFI){
> > >  		unsigned char bootloc;
> > > @@ -717,7 +716,6 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
> > >  	}
> > >  
> > >  	__module_get(THIS_MODULE);
> > > -	register_reboot_notifier(&mtd->reboot_notifier);
> > >  	return mtd;
> > >  
> > >   setup_err:
> > > @@ -2871,7 +2869,7 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
> > >   * the flash is in query/program/erase mode will prevent the CPU from
> > >   * fetching the bootloader code, requiring a hard reset or power cycle.
> > >   */
> > > -static int cfi_amdstd_reset(struct mtd_info *mtd)
> > > +static void cfi_amdstd_reset(struct mtd_info *mtd)
> > >  {
> > >  	struct map_info *map = mtd->priv;
> > >  	struct cfi_private *cfi = map->fldrv_priv;
> > > @@ -2893,19 +2891,6 @@ static int cfi_amdstd_reset(struct mtd_info *mtd)
> > >  
> > >  		mutex_unlock(&chip->mutex);
> > >  	}
> > > -
> > > -	return 0;
> > > -}
> > > -
> > > -
> > > -static int cfi_amdstd_reboot(struct notifier_block *nb, unsigned long val,
> > > -			       void *v)
> > > -{
> > > -	struct mtd_info *mtd;
> > > -
> > > -	mtd = container_of(nb, struct mtd_info, reboot_notifier);
> > > -	cfi_amdstd_reset(mtd);
> > > -	return NOTIFY_DONE;
> > >  }
> > >  
> > >  
> > > @@ -2915,7 +2900,6 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
> > >  	struct cfi_private *cfi = map->fldrv_priv;
> > >  
> > >  	cfi_amdstd_reset(mtd);
> > > -	unregister_reboot_notifier(&mtd->reboot_notifier);
> > >  	kfree(cfi->cmdset_priv);
> > >  	kfree(cfi->cfiq);
> > >  	kfree(cfi);
Brian Norris Nov. 2, 2015, 11:21 p.m. UTC | #5
On Mon, Nov 02, 2015 at 02:16:33PM -0800, Guenter Roeck wrote:
> On Mon, Nov 02, 2015 at 01:58:18PM -0800, Brian Norris wrote:
> > On Mon, Nov 02, 2015 at 12:05:13PM -0800, Guenter Roeck wrote:
> > > On Thu, Dec 04, 2014 at 06:36:08PM -0800, Brian Norris wrote:
> > > > We don't have to implement this glue code in the chip driver any more.
> > > > 
> > > > Signed-off-by: Brian Norris <computersforpeace@gmail.com>
> > > > ---
> > > > Not tested yet
> > > > 
> > > Tested-by: Guenter Roeck <linux@roeck-us.net>
> > 
> > Thanks! Did you verify that your reboot notifier callback (e.g.,
> > cfi_intelext_reset()) is actually called on reboot?
> > 
> No, I just verified that it boots and shuts down correctly.
> 
> Do you want me to verify if the notifier is called, given the
> problems you discovered with the patch ?

Up to you. It'd be nice to know, but even with that info, we'd have more
work to do before we can take this, since I'm pretty sure there are
platforms out there where the notifier won't be called.

(And sorry, my emails can be a little evolutionary as they progress,
when I start to type before I've finished investigating everything.)

BTW, do you want to send out the patch for your suggestion in the other
thread, or should I?

Thanks,
Brian
Guenter Roeck Nov. 3, 2015, 1 a.m. UTC | #6
On 11/02/2015 03:21 PM, Brian Norris wrote:
> On Mon, Nov 02, 2015 at 02:16:33PM -0800, Guenter Roeck wrote:
>> On Mon, Nov 02, 2015 at 01:58:18PM -0800, Brian Norris wrote:
>>> On Mon, Nov 02, 2015 at 12:05:13PM -0800, Guenter Roeck wrote:
>>>> On Thu, Dec 04, 2014 at 06:36:08PM -0800, Brian Norris wrote:
>>>>> We don't have to implement this glue code in the chip driver any more.
>>>>>
>>>>> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
>>>>> ---
>>>>> Not tested yet
>>>>>
>>>> Tested-by: Guenter Roeck <linux@roeck-us.net>
>>>
>>> Thanks! Did you verify that your reboot notifier callback (e.g.,
>>> cfi_intelext_reset()) is actually called on reboot?
>>>
>> No, I just verified that it boots and shuts down correctly.
>>
>> Do you want me to verify if the notifier is called, given the
>> problems you discovered with the patch ?
>
> Up to you. It'd be nice to know, but even with that info, we'd have more
> work to do before we can take this, since I'm pretty sure there are
> platforms out there where the notifier won't be called.
>

I added a WARN() into cfi_intelext_reset() and got:

WARNING: CPU: 0 PID: 504 at drivers/mtd/chips/cfi_cmdset_0001.c:2611 cfi_intelext_reset+0x44/0x130()
cfi_intelext_reset called

which we can take as hint that it was called.

> (And sorry, my emails can be a little evolutionary as they progress,
> when I start to type before I've finished investigating everything.)
>
> BTW, do you want to send out the patch for your suggestion in the other
> thread, or should I?
>
Please go ahead and do it. I can test it if you Cc: me on it.

Thanks,
Guenter
diff mbox

Patch

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 286b97a304cf..3df9744496b2 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -28,7 +28,6 @@ 
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/reboot.h>
 #include <linux/bitmap.h>
 #include <linux/mtd/xip.h>
 #include <linux/mtd/map.h>
@@ -80,7 +79,7 @@  static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
 #endif
 static int cfi_intelext_suspend (struct mtd_info *);
 static void cfi_intelext_resume (struct mtd_info *);
-static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *);
+static void cfi_intelext_reset(struct mtd_info *);
 
 static void cfi_intelext_destroy(struct mtd_info *);
 
@@ -486,13 +485,12 @@  struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
 	mtd->_is_locked = cfi_intelext_is_locked;
 	mtd->_suspend = cfi_intelext_suspend;
 	mtd->_resume  = cfi_intelext_resume;
+	mtd->_reboot  = cfi_intelext_reset;
 	mtd->flags   = MTD_CAP_NORFLASH;
 	mtd->name    = map->name;
 	mtd->writesize = 1;
 	mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
 
-	mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
-
 	if (cfi->cfi_mode == CFI_MODE_CFI) {
 		/*
 		 * It's a real CFI chip, not one for which the probe
@@ -646,7 +644,6 @@  static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
 		goto setup_err;
 
 	__module_get(THIS_MODULE);
-	register_reboot_notifier(&mtd->reboot_notifier);
 	return mtd;
 
  setup_err:
@@ -2605,7 +2602,7 @@  static void cfi_intelext_resume(struct mtd_info *mtd)
 		cfi_intelext_restore_locks(mtd);
 }
 
-static int cfi_intelext_reset(struct mtd_info *mtd)
+static void cfi_intelext_reset(struct mtd_info *mtd)
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
@@ -2626,18 +2623,6 @@  static int cfi_intelext_reset(struct mtd_info *mtd)
 		}
 		mutex_unlock(&chip->mutex);
 	}
-
-	return 0;
-}
-
-static int cfi_intelext_reboot(struct notifier_block *nb, unsigned long val,
-			       void *v)
-{
-	struct mtd_info *mtd;
-
-	mtd = container_of(nb, struct mtd_info, reboot_notifier);
-	cfi_intelext_reset(mtd);
-	return NOTIFY_DONE;
 }
 
 static void cfi_intelext_destroy(struct mtd_info *mtd)
@@ -2647,7 +2632,6 @@  static void cfi_intelext_destroy(struct mtd_info *mtd)
 	struct mtd_erase_region_info *region;
 	int i;
 	cfi_intelext_reset(mtd);
-	unregister_reboot_notifier(&mtd->reboot_notifier);
 	kfree(cfi->cmdset_priv);
 	kfree(cfi->cfiq);
 	kfree(cfi->chips[0].priv);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index c50d8cf0f60d..c4f63482cf96 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -31,7 +31,6 @@ 
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/reboot.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/mtd/map.h>
@@ -57,7 +56,7 @@  static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
 static void cfi_amdstd_sync (struct mtd_info *);
 static int cfi_amdstd_suspend (struct mtd_info *);
 static void cfi_amdstd_resume (struct mtd_info *);
-static int cfi_amdstd_reboot(struct notifier_block *, unsigned long, void *);
+static void cfi_amdstd_reset(struct mtd_info *);
 static int cfi_amdstd_get_fact_prot_info(struct mtd_info *, size_t,
 					 size_t *, struct otp_info *);
 static int cfi_amdstd_get_user_prot_info(struct mtd_info *, size_t,
@@ -529,6 +528,7 @@  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
 	mtd->_sync    = cfi_amdstd_sync;
 	mtd->_suspend = cfi_amdstd_suspend;
 	mtd->_resume  = cfi_amdstd_resume;
+	mtd->_reboot  = cfi_amdstd_reset;
 	mtd->_read_user_prot_reg = cfi_amdstd_read_user_prot_reg;
 	mtd->_read_fact_prot_reg = cfi_amdstd_read_fact_prot_reg;
 	mtd->_get_fact_prot_info = cfi_amdstd_get_fact_prot_info;
@@ -544,7 +544,6 @@  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
 			mtd->writebufsize);
 
 	mtd->_panic_write = cfi_amdstd_panic_write;
-	mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
 
 	if (cfi->cfi_mode==CFI_MODE_CFI){
 		unsigned char bootloc;
@@ -717,7 +716,6 @@  static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
 	}
 
 	__module_get(THIS_MODULE);
-	register_reboot_notifier(&mtd->reboot_notifier);
 	return mtd;
 
  setup_err:
@@ -2871,7 +2869,7 @@  static void cfi_amdstd_resume(struct mtd_info *mtd)
  * the flash is in query/program/erase mode will prevent the CPU from
  * fetching the bootloader code, requiring a hard reset or power cycle.
  */
-static int cfi_amdstd_reset(struct mtd_info *mtd)
+static void cfi_amdstd_reset(struct mtd_info *mtd)
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
@@ -2893,19 +2891,6 @@  static int cfi_amdstd_reset(struct mtd_info *mtd)
 
 		mutex_unlock(&chip->mutex);
 	}
-
-	return 0;
-}
-
-
-static int cfi_amdstd_reboot(struct notifier_block *nb, unsigned long val,
-			       void *v)
-{
-	struct mtd_info *mtd;
-
-	mtd = container_of(nb, struct mtd_info, reboot_notifier);
-	cfi_amdstd_reset(mtd);
-	return NOTIFY_DONE;
 }
 
 
@@ -2915,7 +2900,6 @@  static void cfi_amdstd_destroy(struct mtd_info *mtd)
 	struct cfi_private *cfi = map->fldrv_priv;
 
 	cfi_amdstd_reset(mtd);
-	unregister_reboot_notifier(&mtd->reboot_notifier);
 	kfree(cfi->cmdset_priv);
 	kfree(cfi->cfiq);
 	kfree(cfi);