summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorDaniel Mack <daniel@zonque.org>2018-07-03 22:10:26 +0200
committerUlf Hansson <ulf.hansson@linaro.org>2018-07-16 11:21:45 +0200
commit38a8dda908683c30bcabe7e03a3418aaf2022f5f (patch)
treef2dab04f77d62faa801da213cba7f154b9b125e1 /drivers/mmc
parentmmc: pxamci: let mmc core handle regulators (diff)
downloadlinux-38a8dda908683c30bcabe7e03a3418aaf2022f5f.tar.xz
linux-38a8dda908683c30bcabe7e03a3418aaf2022f5f.zip
mmc: pxamci: make GPIO lookups from pdata optional
A recent commit introduced a call to mmc_of_parse() and removed the explicit assignment of GPIOs in the pdata structure. This will leave them set to 0, which is a valid GPIO per se, so the code that looks at these members will try to allocate them and fail. To fix this properly, make the following changes: a) Refrain from allocating and assiging a pdata struct from pxamci_of_init(). It's a hack to do it this way anyway. Instead, move the only remaining member of interest in 'struct pxamci_host' and assign the value from either the passed in pdata pointer or with the value read from DT. b) Let the only user of 'detect_delay_ms' look at the member of 'struct pxamci_host', not the pdata. c) Make more code in pxamci_probe() dependent on the presence of actual pdata. This will also ease the removal of pdata one day. Signed-off-by: Daniel Mack <daniel@zonque.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/pxamci.c92
1 files changed, 47 insertions, 45 deletions
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index ed576809fae8..f1297080d0e0 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -62,6 +62,7 @@ struct pxamci_host {
unsigned int cmdat;
unsigned int imask;
unsigned int power_mode;
+ unsigned long detect_delay_ms;
struct pxamci_platform_data *pdata;
struct mmc_request *mrq;
@@ -567,7 +568,7 @@ static irqreturn_t pxamci_detect_irq(int irq, void *devid)
{
struct pxamci_host *host = mmc_priv(devid);
- mmc_detect_change(devid, msecs_to_jiffies(host->pdata->detect_delay_ms));
+ mmc_detect_change(devid, msecs_to_jiffies(host->detect_delay_ms));
return IRQ_HANDLED;
}
@@ -583,27 +584,21 @@ static int pxamci_of_init(struct platform_device *pdev,
struct mmc_host *mmc)
{
struct device_node *np = pdev->dev.of_node;
- struct pxamci_platform_data *pdata;
+ struct pxamci_host *host = mmc_priv(mmc);
u32 tmp;
int ret;
if (!np)
return 0;
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
-
/* pxa-mmc specific */
if (of_property_read_u32(np, "pxa-mmc,detect-delay-ms", &tmp) == 0)
- pdata->detect_delay_ms = tmp;
+ host->detect_delay_ms = tmp;
ret = mmc_of_parse(mmc);
if (ret < 0)
return ret;
- pdev->dev.platform_data = pdata;
-
return 0;
}
#else
@@ -619,7 +614,7 @@ static int pxamci_probe(struct platform_device *pdev)
struct mmc_host *mmc;
struct pxamci_host *host = NULL;
struct resource *r;
- int ret, irq, gpio_cd = -1, gpio_ro = -1, gpio_power = -1;
+ int ret, irq;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
@@ -734,47 +729,54 @@ static int pxamci_probe(struct platform_device *pdev)
}
if (host->pdata) {
- gpio_cd = host->pdata->gpio_card_detect;
- gpio_ro = host->pdata->gpio_card_ro;
- gpio_power = host->pdata->gpio_power;
- }
- if (gpio_is_valid(gpio_power)) {
- ret = devm_gpio_request(&pdev->dev, gpio_power,
- "mmc card power");
- if (ret) {
- dev_err(&pdev->dev, "Failed requesting gpio_power %d\n",
- gpio_power);
- goto out;
+ int gpio_cd = host->pdata->gpio_card_detect;
+ int gpio_ro = host->pdata->gpio_card_ro;
+ int gpio_power = host->pdata->gpio_power;
+
+ host->detect_delay_ms = host->pdata->detect_delay_ms;
+
+ if (gpio_is_valid(gpio_power)) {
+ ret = devm_gpio_request(&pdev->dev, gpio_power,
+ "mmc card power");
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Failed requesting gpio_power %d\n",
+ gpio_power);
+ goto out;
+ }
+ gpio_direction_output(gpio_power,
+ host->pdata->gpio_power_invert);
}
- gpio_direction_output(gpio_power,
- host->pdata->gpio_power_invert);
- }
- if (gpio_is_valid(gpio_ro)) {
- ret = mmc_gpio_request_ro(mmc, gpio_ro);
+
+ if (gpio_is_valid(gpio_ro)) {
+ ret = mmc_gpio_request_ro(mmc, gpio_ro);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Failed requesting gpio_ro %d\n",
+ gpio_ro);
+ goto out;
+ } else {
+ mmc->caps2 |= host->pdata->gpio_card_ro_invert ?
+ 0 : MMC_CAP2_RO_ACTIVE_HIGH;
+ }
+ }
+
+ if (gpio_is_valid(gpio_cd))
+ ret = mmc_gpio_request_cd(mmc, gpio_cd, 0);
if (ret) {
- dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n",
- gpio_ro);
+ dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n",
+ gpio_cd);
goto out;
- } else {
- mmc->caps2 |= host->pdata->gpio_card_ro_invert ?
- 0 : MMC_CAP2_RO_ACTIVE_HIGH;
}
- }
- if (gpio_is_valid(gpio_cd))
- ret = mmc_gpio_request_cd(mmc, gpio_cd, 0);
- if (ret) {
- dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n", gpio_cd);
- goto out;
- }
+ if (host->pdata->init)
+ host->pdata->init(&pdev->dev, pxamci_detect_irq, mmc);
- if (host->pdata && host->pdata->init)
- host->pdata->init(&pdev->dev, pxamci_detect_irq, mmc);
-
- if (gpio_is_valid(gpio_power) && host->pdata->setpower)
- dev_warn(&pdev->dev, "gpio_power and setpower() both defined\n");
- if (gpio_is_valid(gpio_ro) && host->pdata->get_ro)
- dev_warn(&pdev->dev, "gpio_ro and get_ro() both defined\n");
+ if (gpio_is_valid(gpio_power) && host->pdata->setpower)
+ dev_warn(&pdev->dev, "gpio_power and setpower() both defined\n");
+ if (gpio_is_valid(gpio_ro) && host->pdata->get_ro)
+ dev_warn(&pdev->dev, "gpio_ro and get_ro() both defined\n");
+ }
mmc_add_host(mmc);