Hi, On Mon, Jul 04, 2011 at 01:38:25PM +0200, Nicolas Ferre wrote: > Take care of slots while going to suspend state. > > Signed-off-by: Nicolas Ferre <nicolas.ferre@xxxxxxxxx> > --- > V3: take care of each slot SUSPENDED state > (adding a status bit in the slot "flags") > V2: move to pm_ops > > drivers/mmc/host/atmel-mci.c | 60 ++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 60 insertions(+), 0 deletions(-) > > diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c > index aa8039f..ed63bcd 100644 > --- a/drivers/mmc/host/atmel-mci.c > +++ b/drivers/mmc/host/atmel-mci.c > @@ -203,6 +203,7 @@ struct atmel_mci_slot { > #define ATMCI_CARD_PRESENT 0 > #define ATMCI_CARD_NEED_INIT 1 > #define ATMCI_SHUTDOWN 2 > +#define ATMCI_SUSPENDED 3 > > int detect_pin; > int wp_pin; > @@ -1878,10 +1879,69 @@ static int __exit atmci_remove(struct platform_device *pdev) > return 0; > } > > +#ifdef CONFIG_PM > +static int atmci_suspend(struct device *dev) > +{ > + struct atmel_mci *host = dev_get_drvdata(dev); > + int i; > + > + for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) { > + struct atmel_mci_slot *slot = host->slot[i]; > + int ret; > + > + if (!slot) > + continue; > + ret = mmc_suspend_host(slot->mmc); > + if (ret < 0) { > + while (--i >= 0) { > + slot = host->slot[i]; > + if (slot > + && test_bit(ATMCI_SUSPENDED, &slot->flags)) { > + mmc_resume_host(host->slot[i]->mmc); > + clear_bit(ATMCI_SUSPENDED, &slot->flags); > + } > + } > + return ret; > + } else { > + set_bit(ATMCI_SUSPENDED, &slot->flags); > + } > + } > + > + return 0; > +} > + > +static int atmci_resume(struct device *dev) > +{ > + struct atmel_mci *host = dev_get_drvdata(dev); > + int i; > + int ret = 0; > + > + for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) { > + struct atmel_mci_slot *slot = host->slot[i]; > + int err; > + > + slot = host->slot[i]; > + if (!slot) > + continue; > + if (!test_bit(ATMCI_SUSPENDED, &slot->flags)) > + continue; > + err = mmc_resume_host(slot->mmc); > + if (err < 0) > + ret = err; > + else > + clear_bit(ATMCI_SUSPENDED, &slot->flags); > + } > + > + return ret; > +} > +#endif > +static SIMPLE_DEV_PM_OPS(atmci_pm, atmci_suspend, atmci_resume); if you disable CONFIG_PM this won't work. atmci_resume and atmci_suspend will be undefined. > static struct platform_driver atmci_driver = { > .remove = __exit_p(atmci_remove), > .driver = { > .name = "atmel_mci", > + .pm = &atmci_pm, this pointer will also be invalid. what most people do is: #ifdef CONFIG_PM suspend() resume() static SIMPLE_DEV_PM_OPS(atmci_pm, suspend, resume); #define DEV_PM_OPS (&atmci_pm) #else #define DEV_PM_OPS NULL #endif -- balbi
Attachment:
signature.asc
Description: Digital signature