linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] MMC: davinci: fix card detect and write protect
@ 2016-11-15 16:28 Axel Haslam
  2016-11-15 16:28 ` [PATCH 1/2] MMC: davinci: use mmc_of_parse to parse common mmc configuration Axel Haslam
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Axel Haslam @ 2016-11-15 16:28 UTC (permalink / raw)
  To: ulf.hansson, nsekhar, khilman, david; +Cc: linux-mmc, linux-kernel, Axel Haslam

This series fixes the card detect and write protect parsing for
the davinci_mmc driver, and takes care of a technical debt to 
remove card polling when a card detect gpio is available.

In the case of a platform based boot we register the gpios
using the APIs provided by slot-gpio.

In the case of a DT based boot we use the mmc_of_parse API to parse
all DT properties and register the gpios.

If this series is accepted, the next series will convert all users
to use gpio descriptors and we could then remove the platform
callbacks.

This was tested on the omap138-lcdk, and the da850-evm, with 
additional patches to platform data and dts files.

Axel Haslam (2):
  MMC: davinci: use mmc_of_parse to parse common mmc configuration
  MMC: davinci: request gpios using gpio descriptors

 drivers/mmc/host/davinci_mmc.c | 130 +++++++++++++++++++++--------------------
 1 file changed, 66 insertions(+), 64 deletions(-)

-- 
2.10.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] MMC: davinci: use mmc_of_parse to parse common mmc configuration
  2016-11-15 16:28 [PATCH 0/2] MMC: davinci: fix card detect and write protect Axel Haslam
@ 2016-11-15 16:28 ` Axel Haslam
  2016-11-18 22:45   ` David Lechner
  2016-11-15 16:28 ` [PATCH 2/2] MMC: davinci: request gpios using gpio descriptors Axel Haslam
  2016-11-18 14:29 ` [PATCH 0/2] MMC: davinci: fix card detect and write protect Ulf Hansson
  2 siblings, 1 reply; 6+ messages in thread
From: Axel Haslam @ 2016-11-15 16:28 UTC (permalink / raw)
  To: ulf.hansson, nsekhar, khilman, david; +Cc: linux-mmc, linux-kernel, Axel Haslam

Card detect and write protect are currently not working on a DT
boot, and the driver relies on polling to get the state
of the card. The current code depends on platform data callbacks
to register and get the state of the gpios.

mmc core provides a generic way to parse device tree configuration,
which will take care of registering the gpios for us, lets use it
so that we don't need to poll, and parse the same properties.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 drivers/mmc/host/davinci_mmc.c | 119 +++++++++++++++++++----------------------
 1 file changed, 55 insertions(+), 64 deletions(-)

diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 8fa478c..619e50e 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -35,6 +35,7 @@
 #include <linux/mmc/mmc.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/mmc/slot-gpio.h>
 
 #include <linux/platform_data/mmc-davinci.h>
 
@@ -1029,9 +1030,10 @@ static int mmc_davinci_get_cd(struct mmc_host *mmc)
 	struct platform_device *pdev = to_platform_device(mmc->parent);
 	struct davinci_mmc_config *config = pdev->dev.platform_data;
 
-	if (!config || !config->get_cd)
-		return -ENOSYS;
-	return config->get_cd(pdev->id);
+	if (config && config->get_cd)
+		return config->get_cd(pdev->id);
+
+	return mmc_gpio_get_cd(mmc);
 }
 
 static int mmc_davinci_get_ro(struct mmc_host *mmc)
@@ -1039,9 +1041,10 @@ static int mmc_davinci_get_ro(struct mmc_host *mmc)
 	struct platform_device *pdev = to_platform_device(mmc->parent);
 	struct davinci_mmc_config *config = pdev->dev.platform_data;
 
-	if (!config || !config->get_ro)
-		return -ENOSYS;
-	return config->get_ro(pdev->id);
+	if (config && config->get_ro)
+		return config->get_ro(pdev->id);
+
+	return mmc_gpio_get_ro(mmc);
 }
 
 static void mmc_davinci_enable_sdio_irq(struct mmc_host *mmc, int enable)
@@ -1159,49 +1162,42 @@ static const struct of_device_id davinci_mmc_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, davinci_mmc_dt_ids);
 
-static struct davinci_mmc_config
-	*mmc_parse_pdata(struct platform_device *pdev)
+static int mmc_davinci_parse_pdata(struct mmc_host *mmc)
 {
-	struct device_node *np;
+	struct platform_device *pdev = to_platform_device(mmc->parent);
 	struct davinci_mmc_config *pdata = pdev->dev.platform_data;
-	const struct of_device_id *match =
-		of_match_device(davinci_mmc_dt_ids, &pdev->dev);
-	u32 data;
-
-	np = pdev->dev.of_node;
-	if (!np)
-		return pdata;
-
-	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata) {
-		dev_err(&pdev->dev, "Failed to allocate memory for struct davinci_mmc_config\n");
-		goto nodata;
-	}
+	struct mmc_davinci_host *host;
 
-	if (match)
-		pdev->id_entry = match->data;
+	if (!pdata)
+		return -EINVAL;
 
-	if (of_property_read_u32(np, "max-frequency", &pdata->max_freq))
-		dev_info(&pdev->dev, "'max-frequency' property not specified, defaulting to 25MHz\n");
+	host = mmc_priv(mmc);
+	if (!host)
+		return -EINVAL;
 
-	of_property_read_u32(np, "bus-width", &data);
-	switch (data) {
-	case 1:
-	case 4:
-	case 8:
-		pdata->wires = data;
-		break;
-	default:
-		pdata->wires = 1;
-		dev_info(&pdev->dev, "Unsupported buswidth, defaulting to 1 bit\n");
-	}
-nodata:
-	return pdata;
+	if (pdata && pdata->nr_sg)
+		host->nr_sg = pdata->nr_sg - 1;
+
+	if (pdata && (pdata->wires == 4 || pdata->wires == 0))
+		mmc->caps |= MMC_CAP_4_BIT_DATA;
+
+	if (pdata && (pdata->wires == 8))
+		mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
+
+	mmc->caps |= MMC_CAP_NEEDS_POLL;
+	mmc->f_min = 312500;
+	mmc->f_max = 25000000;
+	if (pdata && pdata->max_freq)
+		mmc->f_max = pdata->max_freq;
+	if (pdata && pdata->caps)
+		mmc->caps |= pdata->caps;
+
+	return 0;
 }
 
 static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 {
-	struct davinci_mmc_config *pdata = NULL;
+	const struct of_device_id *match;
 	struct mmc_davinci_host *host = NULL;
 	struct mmc_host *mmc = NULL;
 	struct resource *r, *mem = NULL;
@@ -1209,12 +1205,6 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 	size_t mem_size;
 	const struct platform_device_id *id_entry;
 
-	pdata = mmc_parse_pdata(pdev);
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "Couldn't get platform data\n");
-		return -ENOENT;
-	}
-
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r)
 		return -ENODEV;
@@ -1253,14 +1243,28 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 
 	host->mmc_input_clk = clk_get_rate(host->clk);
 
-	init_mmcsd_host(host);
-
-	if (pdata->nr_sg)
-		host->nr_sg = pdata->nr_sg - 1;
+	match = of_match_device(davinci_mmc_dt_ids, &pdev->dev);
+	if (match) {
+		pdev->id_entry = match->data;
+		ret = mmc_of_parse(mmc);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"could not parse of data: %d\n", ret);
+			goto parse_fail;
+		}
+	} else {
+		ret = mmc_davinci_parse_pdata(mmc);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"could not parse platform data: %d\n", ret);
+			goto parse_fail;
+	}	}
 
 	if (host->nr_sg > MAX_NR_SG || !host->nr_sg)
 		host->nr_sg = MAX_NR_SG;
 
+	init_mmcsd_host(host);
+
 	host->use_dma = use_dma;
 	host->mmc_irq = irq;
 	host->sdio_irq = platform_get_irq(pdev, 1);
@@ -1273,27 +1277,13 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 			host->use_dma = 0;
 	}
 
-	/* REVISIT:  someday, support IRQ-driven card detection.  */
-	mmc->caps |= MMC_CAP_NEEDS_POLL;
 	mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
 
-	if (pdata && (pdata->wires == 4 || pdata->wires == 0))
-		mmc->caps |= MMC_CAP_4_BIT_DATA;
-
-	if (pdata && (pdata->wires == 8))
-		mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
-
 	id_entry = platform_get_device_id(pdev);
 	if (id_entry)
 		host->version = id_entry->driver_data;
 
 	mmc->ops = &mmc_davinci_ops;
-	mmc->f_min = 312500;
-	mmc->f_max = 25000000;
-	if (pdata && pdata->max_freq)
-		mmc->f_max = pdata->max_freq;
-	if (pdata && pdata->caps)
-		mmc->caps |= pdata->caps;
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 
 	/* With no iommu coalescing pages, each phys_seg is a hw_seg.
@@ -1354,6 +1344,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 	mmc_davinci_cpufreq_deregister(host);
 cpu_freq_fail:
 	davinci_release_dma_channels(host);
+parse_fail:
 dma_probe_defer:
 	clk_disable_unprepare(host->clk);
 clk_prepare_enable_fail:
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] MMC: davinci: request gpios using gpio descriptors
  2016-11-15 16:28 [PATCH 0/2] MMC: davinci: fix card detect and write protect Axel Haslam
  2016-11-15 16:28 ` [PATCH 1/2] MMC: davinci: use mmc_of_parse to parse common mmc configuration Axel Haslam
@ 2016-11-15 16:28 ` Axel Haslam
  2016-11-18 22:45   ` David Lechner
  2016-11-18 14:29 ` [PATCH 0/2] MMC: davinci: fix card detect and write protect Ulf Hansson
  2 siblings, 1 reply; 6+ messages in thread
From: Axel Haslam @ 2016-11-15 16:28 UTC (permalink / raw)
  To: ulf.hansson, nsekhar, khilman, david; +Cc: linux-mmc, linux-kernel, Axel Haslam

Request card detect and write protect gpios using the provided API
by mmc core.

If a gpio is provided for card detect, we don't need to poll.
So only use polling when a gpio is not provided.

Once all pdata users register the gpios using gpio descriptors,
we could remove the platform callbacks.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 drivers/mmc/host/davinci_mmc.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 619e50e..36b5af8 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -1167,6 +1167,7 @@ static int mmc_davinci_parse_pdata(struct mmc_host *mmc)
 	struct platform_device *pdev = to_platform_device(mmc->parent);
 	struct davinci_mmc_config *pdata = pdev->dev.platform_data;
 	struct mmc_davinci_host *host;
+	int ret;
 
 	if (!pdata)
 		return -EINVAL;
@@ -1184,7 +1185,6 @@ static int mmc_davinci_parse_pdata(struct mmc_host *mmc)
 	if (pdata && (pdata->wires == 8))
 		mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
 
-	mmc->caps |= MMC_CAP_NEEDS_POLL;
 	mmc->f_min = 312500;
 	mmc->f_max = 25000000;
 	if (pdata && pdata->max_freq)
@@ -1192,6 +1192,17 @@ static int mmc_davinci_parse_pdata(struct mmc_host *mmc)
 	if (pdata && pdata->caps)
 		mmc->caps |= pdata->caps;
 
+	/* Register a cd gpio, if there is not one, enable polling */
+	ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
+	if (ret == -EPROBE_DEFER)
+		return ret;
+	else if (ret)
+		mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+	ret = mmc_gpiod_request_ro(mmc, "wp", 0, false, 0, NULL);
+	if (ret == -EPROBE_DEFER)
+		return ret;
+
 	return 0;
 }
 
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/2] MMC: davinci: fix card detect and write protect
  2016-11-15 16:28 [PATCH 0/2] MMC: davinci: fix card detect and write protect Axel Haslam
  2016-11-15 16:28 ` [PATCH 1/2] MMC: davinci: use mmc_of_parse to parse common mmc configuration Axel Haslam
  2016-11-15 16:28 ` [PATCH 2/2] MMC: davinci: request gpios using gpio descriptors Axel Haslam
@ 2016-11-18 14:29 ` Ulf Hansson
  2 siblings, 0 replies; 6+ messages in thread
From: Ulf Hansson @ 2016-11-18 14:29 UTC (permalink / raw)
  To: Axel Haslam
  Cc: Sekhar Nori, Kevin Hilman, David Lechner, linux-mmc, linux-kernel

On 15 November 2016 at 17:28, Axel Haslam <ahaslam@baylibre.com> wrote:
> This series fixes the card detect and write protect parsing for
> the davinci_mmc driver, and takes care of a technical debt to
> remove card polling when a card detect gpio is available.
>
> In the case of a platform based boot we register the gpios
> using the APIs provided by slot-gpio.
>
> In the case of a DT based boot we use the mmc_of_parse API to parse
> all DT properties and register the gpios.
>
> If this series is accepted, the next series will convert all users
> to use gpio descriptors and we could then remove the platform
> callbacks.
>
> This was tested on the omap138-lcdk, and the da850-evm, with
> additional patches to platform data and dts files.
>
> Axel Haslam (2):
>   MMC: davinci: use mmc_of_parse to parse common mmc configuration
>   MMC: davinci: request gpios using gpio descriptors
>
>  drivers/mmc/host/davinci_mmc.c | 130 +++++++++++++++++++++--------------------
>  1 file changed, 66 insertions(+), 64 deletions(-)
>
> --
> 2.10.1
>

Thanks, applied for next!

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] MMC: davinci: use mmc_of_parse to parse common mmc configuration
  2016-11-15 16:28 ` [PATCH 1/2] MMC: davinci: use mmc_of_parse to parse common mmc configuration Axel Haslam
@ 2016-11-18 22:45   ` David Lechner
  0 siblings, 0 replies; 6+ messages in thread
From: David Lechner @ 2016-11-18 22:45 UTC (permalink / raw)
  To: Axel Haslam, ulf.hansson, nsekhar, khilman; +Cc: linux-mmc, linux-kernel

On 11/15/2016 10:28 AM, Axel Haslam wrote:
> Card detect and write protect are currently not working on a DT
> boot, and the driver relies on polling to get the state
> of the card. The current code depends on platform data callbacks
> to register and get the state of the gpios.
>
> mmc core provides a generic way to parse device tree configuration,
> which will take care of registering the gpios for us, lets use it
> so that we don't need to poll, and parse the same properties.
>
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
> ---

Tested-by: David Lechner <david@lechnology.com>

Working for me on LEGO MINDSTORMS EV3.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] MMC: davinci: request gpios using gpio descriptors
  2016-11-15 16:28 ` [PATCH 2/2] MMC: davinci: request gpios using gpio descriptors Axel Haslam
@ 2016-11-18 22:45   ` David Lechner
  0 siblings, 0 replies; 6+ messages in thread
From: David Lechner @ 2016-11-18 22:45 UTC (permalink / raw)
  To: Axel Haslam, ulf.hansson, nsekhar, khilman; +Cc: linux-mmc, linux-kernel

On 11/15/2016 10:28 AM, Axel Haslam wrote:
> Request card detect and write protect gpios using the provided API
> by mmc core.
>
> If a gpio is provided for card detect, we don't need to poll.
> So only use polling when a gpio is not provided.
>
> Once all pdata users register the gpios using gpio descriptors,
> we could remove the platform callbacks.
>
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
> ---

Tested-by: David Lechner <david@lechnology.com>

Working for me on LEGO MINDSTORMS EV3.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-11-18 22:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-15 16:28 [PATCH 0/2] MMC: davinci: fix card detect and write protect Axel Haslam
2016-11-15 16:28 ` [PATCH 1/2] MMC: davinci: use mmc_of_parse to parse common mmc configuration Axel Haslam
2016-11-18 22:45   ` David Lechner
2016-11-15 16:28 ` [PATCH 2/2] MMC: davinci: request gpios using gpio descriptors Axel Haslam
2016-11-18 22:45   ` David Lechner
2016-11-18 14:29 ` [PATCH 0/2] MMC: davinci: fix card detect and write protect Ulf Hansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).