* [PATCH 0/3] Add DT support for davinci_mmc driver @ 2013-01-31 10:33 Manjunathappa, Prakash 2013-01-31 10:33 ` [PATCH 1/3] ARM: davinci: da850: override mmc DT node device name Manjunathappa, Prakash ` (2 more replies) 0 siblings, 3 replies; 8+ messages in thread From: Manjunathappa, Prakash @ 2013-01-31 10:33 UTC (permalink / raw) To: linux-arm-kernel Patch set adds DT support for davinci_mmc driver and is verified on da850-evm without card_detect/write_protect and EDMA support. This patch depends on below patches under review: 1) Patch "pinctrl: pinctrl-single: use arch_initcall and module_exit" http://www.gossamer-threads.com/lists/linux/kernel/1669067 2) Patch "drivers/pinctrl: grab default handles from device core" http://www.gossamer-threads.com/lists/linux/kernel/1664015?page=last 3) Patch "mmc: davinci: allow driver to work without DMA resource" http://permalink.gmane.org/gmane.linux.kernel.mmc/18978 Applies on top of v3.9/dt branch of linux_davinci tree: git://gitorious.org/linux-davinci/linux-davinci.git Manjunathappa, Prakash (3): ARM: davinci: da850: override mmc DT node device name mmc: davinci_mmc: add DT support ARM: davinci: da850: add mmc DT entries .../devicetree/bindings/mmc/davinci_mmc.txt | 23 +++++++ arch/arm/boot/dts/da850-evm.dts | 13 ++++ arch/arm/boot/dts/da850.dtsi | 15 ++++ arch/arm/mach-davinci/da8xx-dt.c | 8 ++- drivers/mmc/host/davinci_mmc.c | 69 +++++++++++++++++++- 5 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/davinci_mmc.txt -- 1.7.4.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/3] ARM: davinci: da850: override mmc DT node device name 2013-01-31 10:33 [PATCH 0/3] Add DT support for davinci_mmc driver Manjunathappa, Prakash @ 2013-01-31 10:33 ` Manjunathappa, Prakash 2013-01-31 10:33 ` [PATCH 2/3] mmc: davinci_mmc: add DT support Manjunathappa, Prakash 2013-01-31 10:33 ` [PATCH 3/3] ARM: davinci: da850: add mmc DT entries Manjunathappa, Prakash 2 siblings, 0 replies; 8+ messages in thread From: Manjunathappa, Prakash @ 2013-01-31 10:33 UTC (permalink / raw) To: linux-arm-kernel Populate OF_DEV_AUXDATA with desired device name expected by davinci_mmc driver. Without this clk_get of davinci_mmc DT driver fails. Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com> Cc: linux-mmc at vger.kernel.org Cc: linux-arm-kernel at lists.infradead.org Cc: linux-kernel at vger.kernel.org Cc: davinci-linux-open-source at linux.davincidsp.com Cc: devicetree-discuss at lists.ozlabs.org Cc: cjb at laptop.org Cc: Sekhar Nori <nsekhar@ti.com> --- arch/arm/mach-davinci/da8xx-dt.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c index 37c27af..c623db0 100644 --- a/arch/arm/mach-davinci/da8xx-dt.c +++ b/arch/arm/mach-davinci/da8xx-dt.c @@ -39,9 +39,15 @@ static void __init da8xx_init_irq(void) #ifdef CONFIG_ARCH_DAVINCI_DA850 +static const struct of_dev_auxdata da8xx_auxdata[] __initconst = { + OF_DEV_AUXDATA("ti,davinci_mmc", 0x01c40000, "davinci_mmc.0", NULL), + {}, +}; + static void __init da850_init_machine(void) { - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + of_platform_populate(NULL, of_default_bus_match_table, da8xx_auxdata, + NULL); da8xx_uart_clk_enable(); } -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3] mmc: davinci_mmc: add DT support 2013-01-31 10:33 [PATCH 0/3] Add DT support for davinci_mmc driver Manjunathappa, Prakash 2013-01-31 10:33 ` [PATCH 1/3] ARM: davinci: da850: override mmc DT node device name Manjunathappa, Prakash @ 2013-01-31 10:33 ` Manjunathappa, Prakash 2013-01-31 11:23 ` Mark Rutland 2013-01-31 10:33 ` [PATCH 3/3] ARM: davinci: da850: add mmc DT entries Manjunathappa, Prakash 2 siblings, 1 reply; 8+ messages in thread From: Manjunathappa, Prakash @ 2013-01-31 10:33 UTC (permalink / raw) To: linux-arm-kernel Adds device tree support for davinci_mmc. Also add binding documentation. Tested with non-dma PIO mode and without GPIO card_detect/write_protect option because of dependencies on EDMA and GPIO modules DT support. Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com> Cc: linux-mmc at vger.kernel.org Cc: linux-arm-kernel at lists.infradead.org Cc: linux-kernel at vger.kernel.org Cc: davinci-linux-open-source at linux.davincidsp.com Cc: devicetree-discuss at lists.ozlabs.org Cc: cjb at laptop.org Cc: Sekhar Nori <nsekhar@ti.com> Cc: mporter at ti.com --- .../devicetree/bindings/mmc/davinci_mmc.txt | 23 +++++++ drivers/mmc/host/davinci_mmc.c | 69 +++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/davinci_mmc.txt diff --git a/Documentation/devicetree/bindings/mmc/davinci_mmc.txt b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt new file mode 100644 index 0000000..144bee6 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt @@ -0,0 +1,23 @@ +* TI Highspeed MMC host controller for DaVinci + +The Highspeed MMC Host Controller on TI DaVinci family +provides an interface for MMC, SD and SDIO types of memory cards. + +This file documents differences between the core properties described +by mmc.txt and the properties used by the davinci_mmc driver. + +Required properties: +- compatible: + Should be "ti,davinci_mmc", for davinci controllers + +Optional properties: +- bus-width: Number of data lines, can be <1>, <4>, or <8>, default <1> +- max-frequency: maximum operating clock frequency. +- caps: Check for Host capabilities in <linux/mmc/host.h> +- version: version of controller. +Example: + mmc1: mmc at 0x4809c000 { + compatible = "ti,omap4-hsmmc"; + reg = <0x4809c000 0x400>; + bus-width = <4>; + }; diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 382b79d..ce6730d 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -34,6 +34,7 @@ #include <linux/dma-mapping.h> #include <linux/edma.h> #include <linux/mmc/mmc.h> +#include <linux/of.h> #include <linux/platform_data/mmc-davinci.h> @@ -1156,16 +1157,75 @@ static void __init init_mmcsd_host(struct mmc_davinci_host *host) mmc_davinci_reset_ctrl(host, 0); } +#ifdef CONFIG_OF +static struct davinci_mmc_config + *mmc_of_get_pdata(struct platform_device *pdev) +{ + struct device_node *np; + struct davinci_mmc_config *pdata = NULL; + u32 data; + int ret; + + pdata = pdev->dev.platform_data; + if (!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; + } + } + + np = pdev->dev.of_node; + if (!np) + goto nodata; + + ret = of_property_read_u32(np, "bus-width", &data); + if (ret) + dev_info(&pdev->dev, "wires not specified, defaulting to 4 bit mode\n"); + pdata->wires = data; + + ret = of_property_read_u32(np, "max-frequency", &data); + if (ret) + dev_info(&pdev->dev, "max-frequency not specified, defaulting to 25MHz\n"); + pdata->max_freq = data; + + ret = of_property_read_u32(np, "caps", &data); + if (ret) + dev_info(&pdev->dev, "card capability not specified\n"); + pdata->caps = data; + + ret = of_property_read_u32(np, "version", &data); + if (ret) + dev_err(&pdev->dev, "version not specified\n"); + pdata->version = data; + +nodata: + return pdata; +} + +#else +static struct davinci_mmc_config + *mmc_of_get_pdata(struct platform_device *pdev) +{ + return pdev->dev.platform_data; +} +#endif static int __init davinci_mmcsd_probe(struct platform_device *pdev) { - struct davinci_mmc_config *pdata = pdev->dev.platform_data; + struct davinci_mmc_config *pdata = NULL; struct mmc_davinci_host *host = NULL; struct mmc_host *mmc = NULL; struct resource *r, *mem = NULL; int ret = 0, irq = 0; size_t mem_size; + pdata = mmc_of_get_pdata(pdev); + if (pdata == NULL) { + dev_err(&pdev->dev, "Can not get platform data\n"); + return -ENOENT; + } + /* REVISIT: when we're fully converted, fail if pdata is NULL */ ret = -ENODEV; @@ -1403,11 +1463,18 @@ static const struct dev_pm_ops davinci_mmcsd_pm = { #define davinci_mmcsd_pm_ops NULL #endif +static const struct of_device_id davinci_mmc_of_match[] = { + {.compatible = "ti,davinci_mmc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, davinci_mmc_of_match); + static struct platform_driver davinci_mmcsd_driver = { .driver = { .name = "davinci_mmc", .owner = THIS_MODULE, .pm = davinci_mmcsd_pm_ops, + .of_match_table = of_match_ptr(davinci_mmc_of_match), }, .remove = __exit_p(davinci_mmcsd_remove), }; -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3] mmc: davinci_mmc: add DT support 2013-01-31 10:33 ` [PATCH 2/3] mmc: davinci_mmc: add DT support Manjunathappa, Prakash @ 2013-01-31 11:23 ` Mark Rutland 2013-02-04 13:28 ` Manjunathappa, Prakash 0 siblings, 1 reply; 8+ messages in thread From: Mark Rutland @ 2013-01-31 11:23 UTC (permalink / raw) To: linux-arm-kernel Hello, I have a few comments on the devicetree binding and the way it's parsed. On Thu, Jan 31, 2013 at 10:33:06AM +0000, Manjunathappa, Prakash wrote: > Adds device tree support for davinci_mmc. Also add > binding documentation. > Tested with non-dma PIO mode and without GPIO > card_detect/write_protect option because of > dependencies on EDMA and GPIO modules DT support. > > Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com> > Cc: linux-mmc at vger.kernel.org > Cc: linux-arm-kernel at lists.infradead.org > Cc: linux-kernel at vger.kernel.org > Cc: davinci-linux-open-source at linux.davincidsp.com > Cc: devicetree-discuss at lists.ozlabs.org > Cc: cjb at laptop.org > Cc: Sekhar Nori <nsekhar@ti.com> > Cc: mporter at ti.com > --- > .../devicetree/bindings/mmc/davinci_mmc.txt | 23 +++++++ > drivers/mmc/host/davinci_mmc.c | 69 +++++++++++++++++++- > 2 files changed, 91 insertions(+), 1 deletions(-) > create mode 100644 Documentation/devicetree/bindings/mmc/davinci_mmc.txt > > diff --git a/Documentation/devicetree/bindings/mmc/davinci_mmc.txt b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt > new file mode 100644 > index 0000000..144bee6 > --- /dev/null > +++ b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt > @@ -0,0 +1,23 @@ > +* TI Highspeed MMC host controller for DaVinci > + > +The Highspeed MMC Host Controller on TI DaVinci family > +provides an interface for MMC, SD and SDIO types of memory cards. > + > +This file documents differences between the core properties described > +by mmc.txt and the properties used by the davinci_mmc driver. > + > +Required properties: > +- compatible: > + Should be "ti,davinci_mmc", for davinci controllers "ti,davinci-mmc" (with '-' rather than '_') would be preferable. > + > +Optional properties: > +- bus-width: Number of data lines, can be <1>, <4>, or <8>, default <1> > +- max-frequency: maximum operating clock frequency. You said you only described differences from mmc.txt, but this is listed in mmc.txt. > +- caps: Check for Host capabilities in <linux/mmc/host.h> Is this a set of binary flags? Also, is this Linux-specific? I really don't think this should be in the devicetree binding. Why do you need this? > +- version: version of controller. This should be encoded as part of the compatible string. > +Example: > + mmc1: mmc at 0x4809c000 { > + compatible = "ti,omap4-hsmmc"; > + reg = <0x4809c000 0x400>; > + bus-width = <4>; > + }; It would be nice if the example referred to this binding rather than another. > diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c > index 382b79d..ce6730d 100644 > --- a/drivers/mmc/host/davinci_mmc.c > +++ b/drivers/mmc/host/davinci_mmc.c > @@ -34,6 +34,7 @@ > #include <linux/dma-mapping.h> > #include <linux/edma.h> > #include <linux/mmc/mmc.h> > +#include <linux/of.h> > > #include <linux/platform_data/mmc-davinci.h> > > @@ -1156,16 +1157,75 @@ static void __init init_mmcsd_host(struct mmc_davinci_host *host) > > mmc_davinci_reset_ctrl(host, 0); > } > +#ifdef CONFIG_OF > +static struct davinci_mmc_config > + *mmc_of_get_pdata(struct platform_device *pdev) > +{ > + struct device_node *np; > + struct davinci_mmc_config *pdata = NULL; > + u32 data; > + int ret; > + > + pdata = pdev->dev.platform_data; > + if (!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; > + } > + } Why do you need to conditionally allocate this? This only seems to be called once. > + > + np = pdev->dev.of_node; > + if (!np) > + goto nodata; Why not just return immediately here? You do nothing special at nodata. > + > + ret = of_property_read_u32(np, "bus-width", &data); > + if (ret) > + dev_info(&pdev->dev, "wires not specified, defaulting to 4 bit mode\n"); > + pdata->wires = data; That dev_info doesn't seem to match up with what the next line is doing (data might not have been initialised). Also, unless I've misunderstood, it doesn't match up with the default of 1 mentioned in the binding doc. > + > + ret = of_property_read_u32(np, "max-frequency", &data); > + if (ret) > + dev_info(&pdev->dev, "max-frequency not specified, defaulting to 25MHz\n"); > + pdata->max_freq = data; Again, the dev_info doesn't match up with the line below it. I notice the default's not one specified in the binding. Is this frequency chosen from the hardware docs, or is it an arbitrary choice. If not arbitrary, it might be worth specifying in the binding. > + > + ret = of_property_read_u32(np, "caps", &data); > + if (ret) > + dev_info(&pdev->dev, "card capability not specified\n"); > + pdata->caps = data; Again, you may be using garbage data. > + > + ret = of_property_read_u32(np, "version", &data); > + if (ret) > + dev_err(&pdev->dev, "version not specified\n"); > + pdata->version = data; And again, though I'd prefer to see this property go entirely. > + > +nodata: > + return pdata; > +} > + > +#else > +static struct davinci_mmc_config > + *mmc_of_get_pdata(struct platform_device *pdev) > +{ > + return pdev->dev.platform_data; > +} > +#endif This is poorly named if it's required for !CONFIG_OF. Why not change this to something like mmc_parse_pdata, returning an error code. For !CONFIG_OF, it can simply return 0, which should be less surprising for anyone else reading this code. > > static int __init davinci_mmcsd_probe(struct platform_device *pdev) > { > - struct davinci_mmc_config *pdata = pdev->dev.platform_data; > + struct davinci_mmc_config *pdata = NULL; > struct mmc_davinci_host *host = NULL; > struct mmc_host *mmc = NULL; > struct resource *r, *mem = NULL; > int ret = 0, irq = 0; > size_t mem_size; > > + pdata = mmc_of_get_pdata(pdev); > + if (pdata == NULL) { > + dev_err(&pdev->dev, "Can not get platform data\n"); > + return -ENOENT; > + } > + > /* REVISIT: when we're fully converted, fail if pdata is NULL */ > > ret = -ENODEV; > @@ -1403,11 +1463,18 @@ static const struct dev_pm_ops davinci_mmcsd_pm = { > #define davinci_mmcsd_pm_ops NULL > #endif > > +static const struct of_device_id davinci_mmc_of_match[] = { > + {.compatible = "ti,davinci_mmc", }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, davinci_mmc_of_match); For supporting multiple versions, you could either use some auxdata here, or check each one in davince_mmcsd_probe. > + > static struct platform_driver davinci_mmcsd_driver = { > .driver = { > .name = "davinci_mmc", > .owner = THIS_MODULE, > .pm = davinci_mmcsd_pm_ops, > + .of_match_table = of_match_ptr(davinci_mmc_of_match), > }, > .remove = __exit_p(davinci_mmcsd_remove), > }; Where does davinci_mmcsd_probe get called from, and how is the of_match_table used? Should it not be set as .probe on the driver? Thanks, Mark. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/3] mmc: davinci_mmc: add DT support 2013-01-31 11:23 ` Mark Rutland @ 2013-02-04 13:28 ` Manjunathappa, Prakash 2013-02-04 14:06 ` Mark Rutland 0 siblings, 1 reply; 8+ messages in thread From: Manjunathappa, Prakash @ 2013-02-04 13:28 UTC (permalink / raw) To: linux-arm-kernel Hi Mark, On Thu, Jan 31, 2013 at 16:53:03, Mark Rutland wrote: > Hello, > > I have a few comments on the devicetree binding and the way it's parsed. > Thanks for review. > On Thu, Jan 31, 2013 at 10:33:06AM +0000, Manjunathappa, Prakash wrote: > > Adds device tree support for davinci_mmc. Also add > > binding documentation. > > Tested with non-dma PIO mode and without GPIO > > card_detect/write_protect option because of > > dependencies on EDMA and GPIO modules DT support. > > > > Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com> > > Cc: linux-mmc at vger.kernel.org > > Cc: linux-arm-kernel at lists.infradead.org > > Cc: linux-kernel at vger.kernel.org > > Cc: davinci-linux-open-source at linux.davincidsp.com > > Cc: devicetree-discuss at lists.ozlabs.org > > Cc: cjb at laptop.org > > Cc: Sekhar Nori <nsekhar@ti.com> > > Cc: mporter at ti.com > > --- > > .../devicetree/bindings/mmc/davinci_mmc.txt | 23 +++++++ > > drivers/mmc/host/davinci_mmc.c | 69 +++++++++++++++++++- > > 2 files changed, 91 insertions(+), 1 deletions(-) > > create mode 100644 Documentation/devicetree/bindings/mmc/davinci_mmc.txt > > > > diff --git a/Documentation/devicetree/bindings/mmc/davinci_mmc.txt b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt > > new file mode 100644 > > index 0000000..144bee6 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt > > @@ -0,0 +1,23 @@ > > +* TI Highspeed MMC host controller for DaVinci > > + > > +The Highspeed MMC Host Controller on TI DaVinci family > > +provides an interface for MMC, SD and SDIO types of memory cards. > > + > > +This file documents differences between the core properties described > > +by mmc.txt and the properties used by the davinci_mmc driver. > > + > > +Required properties: > > +- compatible: > > + Should be "ti,davinci_mmc", for davinci controllers > > "ti,davinci-mmc" (with '-' rather than '_') would be preferable. > I agree, will correct it. > > + > > +Optional properties: > > +- bus-width: Number of data lines, can be <1>, <4>, or <8>, default <1> > > +- max-frequency: maximum operating clock frequency. > > You said you only described differences from mmc.txt, but this is listed in > mmc.txt. > Agreed, I will remove it from here. > > +- caps: Check for Host capabilities in <linux/mmc/host.h> > > Is this a set of binary flags? Also, is this Linux-specific? > > I really don't think this should be in the devicetree binding. Why do you need > this? > I was using this to specify the below controller capabilities: MMC_CAP_MMC_HIGHSPEED and MMC_CAP_SD_HIGHSPEED, Found from discussion[1] that this can be derived from max-frequency, That is above capabilities are supported when max-frequency >= 50MHz. [1] https://lkml.org/lkml/2012/10/15/231 > > +- version: version of controller. > > This should be encoded as part of the compatible string. > Agreed will make change accordingly to accommodate version info in compatible string. > > +Example: > > + mmc1: mmc at 0x4809c000 { > > + compatible = "ti,omap4-hsmmc"; > > + reg = <0x4809c000 0x400>; > > + bus-width = <4>; > > + }; > > It would be nice if the example referred to this binding rather than another. > Agreed, I will change. > > diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c > > index 382b79d..ce6730d 100644 > > --- a/drivers/mmc/host/davinci_mmc.c > > +++ b/drivers/mmc/host/davinci_mmc.c > > @@ -34,6 +34,7 @@ > > #include <linux/dma-mapping.h> > > #include <linux/edma.h> > > #include <linux/mmc/mmc.h> > > +#include <linux/of.h> > > > > #include <linux/platform_data/mmc-davinci.h> > > > > @@ -1156,16 +1157,75 @@ static void __init init_mmcsd_host(struct mmc_davinci_host *host) > > > > mmc_davinci_reset_ctrl(host, 0); > > } > > +#ifdef CONFIG_OF > > +static struct davinci_mmc_config > > + *mmc_of_get_pdata(struct platform_device *pdev) > > +{ > > + struct device_node *np; > > + struct davinci_mmc_config *pdata = NULL; > > + u32 data; > > + int ret; > > + > > + pdata = pdev->dev.platform_data; > > + if (!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; > > + } > > + } > > Why do you need to conditionally allocate this? This only seems to be called > once. > This is common function for DT and non-DT kernel(will be removing #ifdef CONFIG_OF), So above check is necessary for to allocate pdata for DT kernel. > > + > > + np = pdev->dev.of_node; > > + if (!np) > > + goto nodata; > > Why not just return immediately here? You do nothing special at nodata. > Following convention to not have more than 1 return from function and have Common exit point. May not be necessary now since we have devm_* calls now. Can I still prefer to keep this goto? > > + > > + ret = of_property_read_u32(np, "bus-width", &data); > > + if (ret) > > + dev_info(&pdev->dev, "wires not specified, defaulting to 4 bit mode\n"); > > + pdata->wires = data; > > That dev_info doesn't seem to match up with what the next line is doing (data > might not have been initialised). Also, unless I've misunderstood, it doesn't > match up with the default of 1 mentioned in the binding doc. > Yes with missing bus-width property module comes in 1 bit mode, I will correct it. > > + > > + ret = of_property_read_u32(np, "max-frequency", &data); > > + if (ret) > > + dev_info(&pdev->dev, "max-frequency not specified, defaulting to 25MHz\n"); > > + pdata->max_freq = data; > > Again, the dev_info doesn't match up with the line below it. I notice > the default's not one specified in the binding. Is this frequency chosen > from the hardware docs, or is it an arbitrary choice. If not arbitrary, > it might be worth specifying in the binding. > Agreed, I will make the changes for the default values. > > > + > > + ret = of_property_read_u32(np, "caps", &data); > > + if (ret) > > + dev_info(&pdev->dev, "card capability not specified\n"); > > + pdata->caps = data; > > Again, you may be using garbage data. > Ok I will correct it. > > + > > + ret = of_property_read_u32(np, "version", &data); > > + if (ret) > > + dev_err(&pdev->dev, "version not specified\n"); > > + pdata->version = data; > > And again, though I'd prefer to see this property go entirely. > Yes this is going to go away. > > + > > +nodata: > > + return pdata; > > +} > > + > > +#else > > +static struct davinci_mmc_config > > + *mmc_of_get_pdata(struct platform_device *pdev) > > +{ > > + return pdev->dev.platform_data; > > +} > > +#endif > > This is poorly named if it's required for !CONFIG_OF. > > Why not change this to something like mmc_parse_pdata, returning an > error code. For !CONFIG_OF, it can simply return 0, which should be less > surprising for anyone else reading this code. > I will remove #ifdef CONFIG_OF conditional compilation and consideration your suggestion to name function as mmc_parse_pdata. > > > > static int __init davinci_mmcsd_probe(struct platform_device *pdev) > > { > > - struct davinci_mmc_config *pdata = pdev->dev.platform_data; > > + struct davinci_mmc_config *pdata = NULL; > > struct mmc_davinci_host *host = NULL; > > struct mmc_host *mmc = NULL; > > struct resource *r, *mem = NULL; > > int ret = 0, irq = 0; > > size_t mem_size; > > > > + pdata = mmc_of_get_pdata(pdev); > > + if (pdata == NULL) { > > + dev_err(&pdev->dev, "Can not get platform data\n"); > > + return -ENOENT; > > + } > > + > > /* REVISIT: when we're fully converted, fail if pdata is NULL */ > > > > ret = -ENODEV; > > @@ -1403,11 +1463,18 @@ static const struct dev_pm_ops davinci_mmcsd_pm = { > > #define davinci_mmcsd_pm_ops NULL > > #endif > > > > +static const struct of_device_id davinci_mmc_of_match[] = { > > + {.compatible = "ti,davinci_mmc", }, > > + {}, > > +}; > > +MODULE_DEVICE_TABLE(of, davinci_mmc_of_match); > > For supporting multiple versions, you could either use some auxdata > here, or check each one in davince_mmcsd_probe. > I will consider keeping auxdata via compatible field. > > + > > static struct platform_driver davinci_mmcsd_driver = { > > .driver = { > > .name = "davinci_mmc", > > .owner = THIS_MODULE, > > .pm = davinci_mmcsd_pm_ops, > > + .of_match_table = of_match_ptr(davinci_mmc_of_match), > > }, > > .remove = __exit_p(davinci_mmcsd_remove), > > }; > > Where does davinci_mmcsd_probe get called from, and how is the > of_match_table used? Should it not be set as .probe on the driver? > Driver probe is registered in module_init. And are you suggesting me to use module_platform_driver? If yes can it not be taken separately as it is unrelated to DT support I am adding. of_match_table is used by device tree. (will point to NULL for !CONFIG_OF) Thanks, Prakash ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/3] mmc: davinci_mmc: add DT support 2013-02-04 13:28 ` Manjunathappa, Prakash @ 2013-02-04 14:06 ` Mark Rutland 2013-02-05 10:00 ` Manjunathappa, Prakash 0 siblings, 1 reply; 8+ messages in thread From: Mark Rutland @ 2013-02-04 14:06 UTC (permalink / raw) To: linux-arm-kernel Hi, On Mon, Feb 04, 2013 at 01:28:14PM +0000, Manjunathappa, Prakash wrote: > Hi Mark, > > On Thu, Jan 31, 2013 at 16:53:03, Mark Rutland wrote: > > Hello, > > > > I have a few comments on the devicetree binding and the way it's parsed. > > > > Thanks for review. > > > On Thu, Jan 31, 2013 at 10:33:06AM +0000, Manjunathappa, Prakash wrote: [...] > > > +- caps: Check for Host capabilities in <linux/mmc/host.h> > > > > Is this a set of binary flags? Also, is this Linux-specific? > > > > I really don't think this should be in the devicetree binding. Why do you need > > this? > > > > I was using this to specify the below controller capabilities: > MMC_CAP_MMC_HIGHSPEED and MMC_CAP_SD_HIGHSPEED, > Found from discussion[1] that this can be derived from max-frequency, > That is above capabilities are supported when max-frequency >= 50MHz. > > [1] https://lkml.org/lkml/2012/10/15/231 Great! [...] > > > @@ -1156,16 +1157,75 @@ static void __init init_mmcsd_host(struct mmc_davinci_host *host) > > > > > > mmc_davinci_reset_ctrl(host, 0); > > > } > > > +#ifdef CONFIG_OF > > > +static struct davinci_mmc_config > > > + *mmc_of_get_pdata(struct platform_device *pdev) > > > +{ > > > + struct device_node *np; > > > + struct davinci_mmc_config *pdata = NULL; > > > + u32 data; > > > + int ret; > > > + > > > + pdata = pdev->dev.platform_data; > > > + if (!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; > > > + } > > > + } > > > > Why do you need to conditionally allocate this? This only seems to be called > > once. > > > > This is common function for DT and non-DT kernel(will be removing #ifdef CONFIG_OF), > So above check is necessary for to allocate pdata for DT kernel. Ah. Am I right in thinking if you moved the check for pdev->dev.of_node above the pdata allocation, it wouldn't have to be done conditionally? > > > > + > > > + np = pdev->dev.of_node; > > > + if (!np) > > > + goto nodata; > > > > Why not just return immediately here? You do nothing special at nodata. > > > > Following convention to not have more than 1 return from function and have > Common exit point. May not be necessary now since we have devm_* calls now. > Can I still prefer to keep this goto? It just looks a little odd to me. I have no strong feelings here. [...] > > > + > > > + ret = of_property_read_u32(np, "version", &data); > > > + if (ret) > > > + dev_err(&pdev->dev, "version not specified\n"); > > > + pdata->version = data; > > > > And again, though I'd prefer to see this property go entirely. > > > > Yes this is going to go away. Great! > > > > + > > > +nodata: > > > + return pdata; > > > +} > > > + > > > +#else > > > +static struct davinci_mmc_config > > > + *mmc_of_get_pdata(struct platform_device *pdev) > > > +{ > > > + return pdev->dev.platform_data; > > > +} > > > +#endif > > > > This is poorly named if it's required for !CONFIG_OF. > > > > Why not change this to something like mmc_parse_pdata, returning an > > error code. For !CONFIG_OF, it can simply return 0, which should be less > > surprising for anyone else reading this code. > > > > I will remove #ifdef CONFIG_OF conditional compilation and consideration > your suggestion to name function as mmc_parse_pdata. Sounds good. > > > > > > > static int __init davinci_mmcsd_probe(struct platform_device *pdev) > > > { > > > - struct davinci_mmc_config *pdata = pdev->dev.platform_data; > > > + struct davinci_mmc_config *pdata = NULL; > > > struct mmc_davinci_host *host = NULL; > > > struct mmc_host *mmc = NULL; > > > struct resource *r, *mem = NULL; > > > int ret = 0, irq = 0; > > > size_t mem_size; > > > > > > + pdata = mmc_of_get_pdata(pdev); > > > + if (pdata == NULL) { > > > + dev_err(&pdev->dev, "Can not get platform data\n"); > > > + return -ENOENT; > > > + } > > > + > > > /* REVISIT: when we're fully converted, fail if pdata is NULL */ > > > > > > ret = -ENODEV; > > > @@ -1403,11 +1463,18 @@ static const struct dev_pm_ops davinci_mmcsd_pm = { > > > #define davinci_mmcsd_pm_ops NULL > > > #endif > > > > > > +static const struct of_device_id davinci_mmc_of_match[] = { > > > + {.compatible = "ti,davinci_mmc", }, > > > + {}, > > > +}; > > > +MODULE_DEVICE_TABLE(of, davinci_mmc_of_match); > > > > For supporting multiple versions, you could either use some auxdata > > here, or check each one in davince_mmcsd_probe. > > > > I will consider keeping auxdata via compatible field. > > > > + > > > static struct platform_driver davinci_mmcsd_driver = { > > > .driver = { > > > .name = "davinci_mmc", > > > .owner = THIS_MODULE, > > > .pm = davinci_mmcsd_pm_ops, > > > + .of_match_table = of_match_ptr(davinci_mmc_of_match), > > > }, > > > .remove = __exit_p(davinci_mmcsd_remove), > > > }; > > > > Where does davinci_mmcsd_probe get called from, and how is the > > of_match_table used? Should it not be set as .probe on the driver? > > > > Driver probe is registered in module_init. Ah, I'd missed the module_init when scanning through the code. I couldn't figure out how davinci_mmcsd_probe got called for elements matched by the match table. I see platform_driver_probe temporarily sets the .probe on the driver, so that makes sense now. > And are you suggesting me to use module_platform_driver? If yes can it not > be taken separately as it is unrelated to DT support I am adding. No, I'd just managed to miss that which got called via module_init. It should be fine as-is. Thanks, Mark. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/3] mmc: davinci_mmc: add DT support 2013-02-04 14:06 ` Mark Rutland @ 2013-02-05 10:00 ` Manjunathappa, Prakash 0 siblings, 0 replies; 8+ messages in thread From: Manjunathappa, Prakash @ 2013-02-05 10:00 UTC (permalink / raw) To: linux-arm-kernel Hi Mark, On Mon, Feb 04, 2013 at 19:36:16, Mark Rutland wrote: > Hi, > > On Mon, Feb 04, 2013 at 01:28:14PM +0000, Manjunathappa, Prakash wrote: > > Hi Mark, > > > > On Thu, Jan 31, 2013 at 16:53:03, Mark Rutland wrote: > > > Hello, > > > > > > I have a few comments on the devicetree binding and the way it's parsed. > > > > > > > Thanks for review. > > > > > On Thu, Jan 31, 2013 at 10:33:06AM +0000, Manjunathappa, Prakash wrote: > > [...] [...] > [...] > > > > > @@ -1156,16 +1157,75 @@ static void __init init_mmcsd_host(struct mmc_davinci_host *host) > > > > > > > > mmc_davinci_reset_ctrl(host, 0); > > > > } > > > > +#ifdef CONFIG_OF > > > > +static struct davinci_mmc_config > > > > + *mmc_of_get_pdata(struct platform_device *pdev) > > > > +{ > > > > + struct device_node *np; > > > > + struct davinci_mmc_config *pdata = NULL; > > > > + u32 data; > > > > + int ret; > > > > + > > > > + pdata = pdev->dev.platform_data; > > > > + if (!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; > > > > + } > > > > + } > > > > > > Why do you need to conditionally allocate this? This only seems to be called > > > once. > > > > > > > This is common function for DT and non-DT kernel(will be removing #ifdef CONFIG_OF), > > So above check is necessary for to allocate pdata for DT kernel. > > Ah. Am I right in thinking if you moved the check for pdev->dev.of_node above > the pdata allocation, it wouldn't have to be done conditionally? > Agreed. Will move below check up. > > > > > > + > > > > + np = pdev->dev.of_node; > > > > + if (!np) > > > > + goto nodata; > > > > > > Why not just return immediately here? You do nothing special at nodata. > > > > > > > Following convention to not have more than 1 return from function and have > > Common exit point. May not be necessary now since we have devm_* calls now. > > Can I still prefer to keep this goto? > > It just looks a little odd to me. I have no strong feelings here. > > [...] > After considering your inputs on moving above statement up, "return" makes sense. Thanks, Prakash [...] ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/3] ARM: davinci: da850: add mmc DT entries 2013-01-31 10:33 [PATCH 0/3] Add DT support for davinci_mmc driver Manjunathappa, Prakash 2013-01-31 10:33 ` [PATCH 1/3] ARM: davinci: da850: override mmc DT node device name Manjunathappa, Prakash 2013-01-31 10:33 ` [PATCH 2/3] mmc: davinci_mmc: add DT support Manjunathappa, Prakash @ 2013-01-31 10:33 ` Manjunathappa, Prakash 2 siblings, 0 replies; 8+ messages in thread From: Manjunathappa, Prakash @ 2013-01-31 10:33 UTC (permalink / raw) To: linux-arm-kernel Add DT entry for MMC. Also add entry for pinmux information. Tested on da850-evm without card detect and EDMA support as DT support for GPIO and EDMA are yet come. Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com> Cc: linux-mmc at vger.kernel.org Cc: linux-arm-kernel at lists.infradead.org Cc: linux-kernel at vger.kernel.org Cc: davinci-linux-open-source at linux.davincidsp.com Cc: devicetree-discuss at lists.ozlabs.org Cc: cjb at laptop.org Cc: Sekhar Nori <nsekhar@ti.com> --- arch/arm/boot/dts/da850-evm.dts | 13 +++++++++++++ arch/arm/boot/dts/da850.dtsi | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 0 deletions(-) diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts index fa04152..51c87e7 100644 --- a/arch/arm/boot/dts/da850-evm.dts +++ b/arch/arm/boot/dts/da850-evm.dts @@ -30,6 +30,19 @@ rtc0: rtc at 1c23000 { status = "okay"; }; + mmc0: mmc at 1c40000 { + status = "okay"; + bus-width = <4>; + max-frequency = <50000000>; + /* + * BIT(1) MMC_CAP_MMC_HIGHSPEED + * BIT(2) MMC_CAP_SD_HIGHSPEED + */ + caps = <6>; + version = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + }; }; nand_cs3 at 62000000 { status = "okay"; diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi index 099c81e..5978a83 100644 --- a/arch/arm/boot/dts/da850.dtsi +++ b/arch/arm/boot/dts/da850.dtsi @@ -56,6 +56,15 @@ 0x30 0x01100000 0x0ff00000 >; }; + mmc0_pins: pinmux_mmc_pins { + pinctrl-single,bits = < + /* MMCSD0_DAT[3] MMCSD0_DAT[2] + * MMCSD0_DAT[1] MMCSD0_DAT[0] + * MMCSD0_CMD MMCSD0_CLK + */ + 0x28 0x00222222 0x00ffffff + >; + }; }; serial0: serial at 1c42000 { compatible = "ns16550a"; @@ -88,6 +97,12 @@ 19>; status = "disabled"; }; + mmc0: mmc at 1c40000 { + compatible = "ti,davinci_mmc"; + reg = <0x40000 0x1000>; + interrupts = <16>; + status = "disabled"; + }; }; nand_cs3 at 62000000 { compatible = "ti,davinci-nand"; -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-02-05 10:00 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-01-31 10:33 [PATCH 0/3] Add DT support for davinci_mmc driver Manjunathappa, Prakash 2013-01-31 10:33 ` [PATCH 1/3] ARM: davinci: da850: override mmc DT node device name Manjunathappa, Prakash 2013-01-31 10:33 ` [PATCH 2/3] mmc: davinci_mmc: add DT support Manjunathappa, Prakash 2013-01-31 11:23 ` Mark Rutland 2013-02-04 13:28 ` Manjunathappa, Prakash 2013-02-04 14:06 ` Mark Rutland 2013-02-05 10:00 ` Manjunathappa, Prakash 2013-01-31 10:33 ` [PATCH 3/3] ARM: davinci: da850: add mmc DT entries Manjunathappa, Prakash
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).