forked from luck/tmp_suning_uos_patched
au1xmmc: suspend/resume implementation
Basic suspend/resume support: disable peripheral on suspend and reinit on resume. Tested on Au1200. Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
This commit is contained in:
parent
d2f2761bb7
commit
dd8572af68
|
@ -1043,7 +1043,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
|
||||||
goto out6;
|
goto out6;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, mmc);
|
platform_set_drvdata(pdev, host);
|
||||||
|
|
||||||
printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X"
|
printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X"
|
||||||
" (mode=%s)\n", pdev->id, host->iobase,
|
" (mode=%s)\n", pdev->id, host->iobase,
|
||||||
|
@ -1087,13 +1087,10 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
static int __devexit au1xmmc_remove(struct platform_device *pdev)
|
static int __devexit au1xmmc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct mmc_host *mmc = platform_get_drvdata(pdev);
|
struct au1xmmc_host *host = platform_get_drvdata(pdev);
|
||||||
struct au1xmmc_host *host;
|
|
||||||
|
|
||||||
if (mmc) {
|
if (host) {
|
||||||
host = mmc_priv(mmc);
|
mmc_remove_host(host->mmc);
|
||||||
|
|
||||||
mmc_remove_host(mmc);
|
|
||||||
|
|
||||||
#ifdef CONFIG_LEDS_CLASS
|
#ifdef CONFIG_LEDS_CLASS
|
||||||
if (host->platdata && host->platdata->led)
|
if (host->platdata && host->platdata->led)
|
||||||
|
@ -1101,8 +1098,8 @@ static int __devexit au1xmmc_remove(struct platform_device *pdev)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (host->platdata && host->platdata->cd_setup &&
|
if (host->platdata && host->platdata->cd_setup &&
|
||||||
!(mmc->caps & MMC_CAP_NEEDS_POLL))
|
!(host->mmc->caps & MMC_CAP_NEEDS_POLL))
|
||||||
host->platdata->cd_setup(mmc, 0);
|
host->platdata->cd_setup(host->mmc, 0);
|
||||||
|
|
||||||
au_writel(0, HOST_ENABLE(host));
|
au_writel(0, HOST_ENABLE(host));
|
||||||
au_writel(0, HOST_CONFIG(host));
|
au_writel(0, HOST_CONFIG(host));
|
||||||
|
@ -1122,16 +1119,49 @@ static int __devexit au1xmmc_remove(struct platform_device *pdev)
|
||||||
release_resource(host->ioarea);
|
release_resource(host->ioarea);
|
||||||
kfree(host->ioarea);
|
kfree(host->ioarea);
|
||||||
|
|
||||||
mmc_free_host(mmc);
|
mmc_free_host(host->mmc);
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct au1xmmc_host *host = platform_get_drvdata(pdev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = mmc_suspend_host(host->mmc, state);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
au_writel(0, HOST_CONFIG2(host));
|
||||||
|
au_writel(0, HOST_CONFIG(host));
|
||||||
|
au_writel(0xffffffff, HOST_STATUS(host));
|
||||||
|
au_writel(0, HOST_ENABLE(host));
|
||||||
|
au_sync();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int au1xmmc_resume(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct au1xmmc_host *host = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
au1xmmc_reset_controller(host);
|
||||||
|
|
||||||
|
return mmc_resume_host(host->mmc);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define au1xmmc_suspend NULL
|
||||||
|
#define au1xmmc_resume NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct platform_driver au1xmmc_driver = {
|
static struct platform_driver au1xmmc_driver = {
|
||||||
.probe = au1xmmc_probe,
|
.probe = au1xmmc_probe,
|
||||||
.remove = au1xmmc_remove,
|
.remove = au1xmmc_remove,
|
||||||
.suspend = NULL,
|
.suspend = au1xmmc_suspend,
|
||||||
.resume = NULL,
|
.resume = au1xmmc_resume,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user