dev_dbg(&host->pdev->dev, args); \
} while (0)
-#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
-
static struct s3c2410_dma_client s3cmci_dma_client = {
.name = "s3c-mci",
};
if (pdata->gpio_detect == 0)
return -ENOSYS;
- ret = s3c2410_gpio_getpin(pdata->gpio_detect) ? 0 : 1;
+ ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
return ret ^ pdata->detect_invert;
}
switch (ios->power_mode) {
case MMC_POWER_ON:
case MMC_POWER_UP:
- s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
- s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
- s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
- s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
- s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
- s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(5), S3C2410_GPE5_SDCLK);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(6), S3C2410_GPE6_SDCMD);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(7), S3C2410_GPE7_SDDAT0);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(9), S3C2410_GPE9_SDDAT2);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(10), S3C2410_GPE10_SDDAT3);
if (host->pdata->set_power)
host->pdata->set_power(ios->power_mode, ios->vdd);
case MMC_POWER_OFF:
default:
- s3c2410_gpio_setpin(S3C2410_GPE5, 0);
- s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPIO_OUTPUT);
+ gpio_direction_output(S3C2410_GPE(5), 0);
if (host->is2440)
mci_con |= S3C2440_SDICON_SDRESET;
}
#endif
-static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
+
+static int __devinit s3cmci_probe(struct platform_device *pdev)
{
struct s3cmci_host *host;
struct mmc_host *mmc;
int ret;
+ int is2440;
+ int i;
+
+ is2440 = platform_get_device_id(pdev)->driver_data;
mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
if (!mmc) {
goto probe_out;
}
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
+ ret = gpio_request(i, dev_name(&pdev->dev));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get gpio %d\n", i);
+
+ for (i--; i >= S3C2410_GPE(5); i--)
+ gpio_free(i);
+
+ goto probe_free_host;
+ }
+ }
+
host = mmc_priv(mmc);
host->mmc = mmc;
host->pdev = pdev;
"failed to get io memory region resouce.\n");
ret = -ENOENT;
- goto probe_free_host;
+ goto probe_free_gpio;
}
host->mem = request_mem_region(host->mem->start,
- RESSIZE(host->mem), pdev->name);
+ resource_size(host->mem), pdev->name);
if (!host->mem) {
dev_err(&pdev->dev, "failed to request io memory region.\n");
ret = -ENOENT;
- goto probe_free_host;
+ goto probe_free_gpio;
}
- host->base = ioremap(host->mem->start, RESSIZE(host->mem));
+ host->base = ioremap(host->mem->start, resource_size(host->mem));
if (!host->base) {
dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
ret = -EINVAL;
disable_irq(host->irq);
+ if (host->pdata->gpio_detect) {
+ ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get detect gpio\n");
+ goto probe_free_irq;
+ }
+ }
+
host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
if (host->irq_cd >= 0) {
DRIVER_NAME, host)) {
dev_err(&pdev->dev, "can't get card detect irq.\n");
ret = -ENOENT;
- goto probe_free_irq;
+ goto probe_free_gpio_cd;
}
} else {
dev_warn(&pdev->dev, "host detect has no irq available\n");
- s3c2410_gpio_cfgpin(host->pdata->gpio_detect,
- S3C2410_GPIO_INPUT);
+ gpio_direction_input(host->pdata->gpio_detect);
}
- if (host->pdata->gpio_wprotect)
- s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect,
- S3C2410_GPIO_INPUT);
+ if (host->pdata->gpio_wprotect) {
+ ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get writeprotect\n");
+ goto probe_free_irq_cd;
+ }
+
+ gpio_direction_input(host->pdata->gpio_wprotect);
+ }
if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL) < 0) {
dev_err(&pdev->dev, "unable to get DMA channel.\n");
ret = -EBUSY;
- goto probe_free_irq_cd;
+ goto probe_free_gpio_wp;
}
host->clk = clk_get(&pdev->dev, "sdi");
clk_free:
clk_put(host->clk);
+ probe_free_gpio_wp:
+ if (host->pdata->gpio_wprotect)
+ gpio_free(host->pdata->gpio_wprotect);
+
+ probe_free_gpio_cd:
+ if (host->pdata->gpio_detect)
+ gpio_free(host->pdata->gpio_detect);
+
probe_free_irq_cd:
if (host->irq_cd >= 0)
free_irq(host->irq_cd, host);
iounmap(host->base);
probe_free_mem_region:
- release_mem_region(host->mem->start, RESSIZE(host->mem));
+ release_mem_region(host->mem->start, resource_size(host->mem));
+
+ probe_free_gpio:
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
probe_free_host:
mmc_free_host(mmc);
+
probe_out:
return ret;
}
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct s3cmci_host *host = mmc_priv(mmc);
+ struct s3c24xx_mci_pdata *pd = host->pdata;
+ int i;
s3cmci_shutdown(pdev);
free_irq(host->irq, host);
+ if (pd->gpio_wprotect)
+ gpio_free(pd->gpio_wprotect);
+
+ if (pd->gpio_detect)
+ gpio_free(pd->gpio_detect);
+
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
+
+
iounmap(host->base);
- release_mem_region(host->mem->start, RESSIZE(host->mem));
+ release_mem_region(host->mem->start, resource_size(host->mem));
mmc_free_host(mmc);
return 0;
}
-static int __devinit s3cmci_2410_probe(struct platform_device *dev)
-{
- return s3cmci_probe(dev, 0);
-}
+static struct platform_device_id s3cmci_driver_ids[] = {
+ {
+ .name = "s3c2410-sdi",
+ .driver_data = 0,
+ }, {
+ .name = "s3c2412-sdi",
+ .driver_data = 1,
+ }, {
+ .name = "s3c2440-sdi",
+ .driver_data = 1,
+ },
+ { }
+};
-static int __devinit s3cmci_2412_probe(struct platform_device *dev)
-{
- return s3cmci_probe(dev, 1);
-}
+MODULE_DEVICE_TABLE(platform, s3cmci_driver_ids);
-static int __devinit s3cmci_2440_probe(struct platform_device *dev)
-{
- return s3cmci_probe(dev, 1);
-}
#ifdef CONFIG_PM
-static int s3cmci_suspend(struct platform_device *dev, pm_message_t state)
+static int s3cmci_suspend(struct device *dev)
{
- struct mmc_host *mmc = platform_get_drvdata(dev);
+ struct mmc_host *mmc = platform_get_drvdata(to_platform_device(dev));
+ struct pm_message event = { PM_EVENT_SUSPEND };
- return mmc_suspend_host(mmc, state);
+ return mmc_suspend_host(mmc, event);
}
-static int s3cmci_resume(struct platform_device *dev)
+static int s3cmci_resume(struct device *dev)
{
- struct mmc_host *mmc = platform_get_drvdata(dev);
+ struct mmc_host *mmc = platform_get_drvdata(to_platform_device(dev));
return mmc_resume_host(mmc);
}
-#else /* CONFIG_PM */
-#define s3cmci_suspend NULL
-#define s3cmci_resume NULL
-#endif /* CONFIG_PM */
-
-
-static struct platform_driver s3cmci_2410_driver = {
- .driver.name = "s3c2410-sdi",
- .driver.owner = THIS_MODULE,
- .probe = s3cmci_2410_probe,
- .remove = __devexit_p(s3cmci_remove),
- .shutdown = s3cmci_shutdown,
+static struct dev_pm_ops s3cmci_pm = {
.suspend = s3cmci_suspend,
.resume = s3cmci_resume,
};
-static struct platform_driver s3cmci_2412_driver = {
- .driver.name = "s3c2412-sdi",
- .driver.owner = THIS_MODULE,
- .probe = s3cmci_2412_probe,
- .remove = __devexit_p(s3cmci_remove),
- .shutdown = s3cmci_shutdown,
- .suspend = s3cmci_suspend,
- .resume = s3cmci_resume,
-};
+#define s3cmci_pm_ops &s3cmci_pm
+#else /* CONFIG_PM */
+#define s3cmci_pm_ops NULL
+#endif /* CONFIG_PM */
+
-static struct platform_driver s3cmci_2440_driver = {
- .driver.name = "s3c2440-sdi",
- .driver.owner = THIS_MODULE,
- .probe = s3cmci_2440_probe,
+static struct platform_driver s3cmci_driver = {
+ .driver = {
+ .name = "s3c-sdi",
+ .owner = THIS_MODULE,
+ .pm = s3cmci_pm_ops,
+ },
+ .id_table = s3cmci_driver_ids,
+ .probe = s3cmci_probe,
.remove = __devexit_p(s3cmci_remove),
.shutdown = s3cmci_shutdown,
- .suspend = s3cmci_suspend,
- .resume = s3cmci_resume,
};
-
static int __init s3cmci_init(void)
{
- platform_driver_register(&s3cmci_2410_driver);
- platform_driver_register(&s3cmci_2412_driver);
- platform_driver_register(&s3cmci_2440_driver);
- return 0;
+ return platform_driver_register(&s3cmci_driver);
}
static void __exit s3cmci_exit(void)
{
- platform_driver_unregister(&s3cmci_2410_driver);
- platform_driver_unregister(&s3cmci_2412_driver);
- platform_driver_unregister(&s3cmci_2440_driver);
+ platform_driver_unregister(&s3cmci_driver);
}
module_init(s3cmci_init);
MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>");
-MODULE_ALIAS("platform:s3c2410-sdi");
-MODULE_ALIAS("platform:s3c2412-sdi");
-MODULE_ALIAS("platform:s3c2440-sdi");