diff options
Diffstat (limited to 'drivers/mmc/host/sh_mobile_sdhi.c')
-rw-r--r-- | drivers/mmc/host/sh_mobile_sdhi.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index cc701236d16f..b3654293017b 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -62,7 +62,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev) struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; struct tmio_mmc_host *host; char clk_name[8]; - int ret; + int i, irq, ret; priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL); if (priv == NULL) { @@ -71,6 +71,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev) } mmc_data = &priv->mmc_data; + p->pdata = mmc_data; snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id); priv->clk = clk_get(&pdev->dev, clk_name); @@ -116,11 +117,36 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev) if (ret < 0) goto eprobe; - pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), - (unsigned long)host->ctl, host->irq); + for (i = 0; i < 3; i++) { + irq = platform_get_irq(pdev, i); + if (irq < 0) { + if (i) { + continue; + } else { + ret = irq; + goto eirq; + } + } + ret = request_irq(irq, tmio_mmc_irq, 0, + dev_name(&pdev->dev), host); + if (ret) { + while (i--) { + irq = platform_get_irq(pdev, i); + if (irq >= 0) + free_irq(irq, host); + } + goto eirq; + } + } + dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n", + mmc_hostname(host->mmc), (unsigned long) + (platform_get_resource(pdev,IORESOURCE_MEM, 0)->start), + mmc_data->hclk / 1000000); return ret; +eirq: + tmio_mmc_host_remove(host); eprobe: clk_disable(priv->clk); clk_put(priv->clk); @@ -134,6 +160,16 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev) struct mmc_host *mmc = platform_get_drvdata(pdev); struct tmio_mmc_host *host = mmc_priv(mmc); struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data); + struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; + int i, irq; + + p->pdata = NULL; + + for (i = 0; i < 3; i++) { + irq = platform_get_irq(pdev, i); + if (irq >= 0) + free_irq(irq, host); + } tmio_mmc_host_remove(host); clk_disable(priv->clk); @@ -143,10 +179,18 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev) return 0; } +static const struct dev_pm_ops tmio_mmc_dev_pm_ops = { + .suspend = tmio_mmc_host_suspend, + .resume = tmio_mmc_host_resume, + .runtime_suspend = tmio_mmc_host_runtime_suspend, + .runtime_resume = tmio_mmc_host_runtime_resume, +}; + static struct platform_driver sh_mobile_sdhi_driver = { .driver = { .name = "sh_mobile_sdhi", .owner = THIS_MODULE, + .pm = &tmio_mmc_dev_pm_ops, }, .probe = sh_mobile_sdhi_probe, .remove = __devexit_p(sh_mobile_sdhi_remove), |