三星平台SD/MMC驱动主要有两个文件sdhci.c和sdhci-s3c.c,核心驱动在后者里面。
我们一步一步分析,先从平台驱动注册看起
sdhci-s3c.c:
static int __init sdhci_s3c_init(void)
{
return platform_driver_register(&sdhci_s3c_driver);
}
注册了sdhci-s3c-driver,看下该结构体定义:
static struct platform_driver sdhci_s3c_driver = {
.probe = sdhci_s3c_probe,
.remove = __devexit_p(sdhci_s3c_remove),
.suspend = sdhci_s3c_suspend,
.resume = sdhci_s3c_resume,
.driver = {
.owner = THIS_MODULE,
.name = "s3c-sdhci",
},
};
看重点——probe函数:
static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
{
struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
struct device *dev = &pdev->dev;
struct sdhci_host *host;
struct sdhci_s3c *sc;
struct resource *res;
int ret, irq, ptr, clks;
if (!pdata) {
dev_err(dev, "no device data specified\n");
return -ENOENT;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "no irq specified\n");
return irq;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "no memory specified\n");
return -ENOENT;
}
host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
if (IS_ERR(host)) {
dev_err(dev, "sdhci_alloc_host() failed\n");
return PTR_ERR(host);
}
sc = sdhci_priv(host);
sc->host = host;
sc->pdev = pdev;
sc->pdata = pdata;
sc->ext_cd_gpio = -1; /* invalid gpio number */
platform_set_drvdata(pdev, host);
sc->clk_io = clk_get(dev, "hsmmc");
if (IS_ERR(sc->clk_io)) {
dev_err(dev, "failed to get io clock\n");
ret = PTR_ERR(sc->clk_io);
goto err_io_clk;
}
/* enable the local io clock and keep it running for the moment. */
clk_enable(sc->clk_io);
for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
struct clk *clk;
char *name = pdata->clocks[ptr];
if (name == NULL)
continue;
clk = clk_get(dev, name);
if (IS_ERR(clk)) {
dev_err(dev, "failed to get clock %s\n", name);
continue;
}
clks++;
sc->clk_bus[ptr] = clk;
/*
* save current clock index to know which clock bus
*