* [PATCH] mmc: sdhci-pxa: Add device tree support
@ 2012-06-12 19:05 Chris Ball
2012-06-13 3:11 ` zhangfei gao
2012-06-20 5:49 ` Chris Ball
0 siblings, 2 replies; 7+ messages in thread
From: Chris Ball @ 2012-06-12 19:05 UTC (permalink / raw)
To: Haojian Zhuang; +Cc: Zhangfei Gao, Philip Rakity, devicetree-discuss, linux-mmc
Tested on an OLPC XO-1.75. (MMP2, sdhci-pxav3, CONFIG_MACH_MMP2_DT=y)
Signed-off-by: Chris Ball <cjb@laptop.org>
---
.../devicetree/bindings/mmc/sdhci-pxa.txt | 21 ++++++++
drivers/mmc/host/sdhci-pxav2.c | 52 ++++++++++++++++++++
drivers/mmc/host/sdhci-pxav3.c | 50 +++++++++++++++++++
3 files changed, 123 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
new file mode 100644
index 0000000..5896c24
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
@@ -0,0 +1,21 @@
+* Marvell sdhci-pxa v2/v3 controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci-pxav2 and sdhci-pxav3 drivers.
+
+Required properties:
+- compatible: Should be "mrvl,pxav2-mmc" or "mrvl,pxav3-mmc".
+
+Optional properties:
+- clk-delay-cycles: Specify a number of cycles to delay for tuning.
+
+Example:
+
+sdhci@d4280800 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xd4280800 0x800>;
+ interrupts = <27>;
+ bus-width = <8>;
+ clk-delay-cycles = <31>;
+ non-removable;
+};
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index dbb75bf..b4b1c1d 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -28,6 +28,9 @@
#include <linux/mmc/host.h>
#include <linux/platform_data/pxa_sdhci.h>
#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
#include "sdhci.h"
#include "sdhci-pltfm.h"
@@ -121,6 +124,48 @@ static struct sdhci_ops pxav2_sdhci_ops = {
.platform_8bit_width = pxav2_mmc_set_width,
};
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_pxav2_of_match[] = {
+ {
+ .compatible = "mrvl,pxav2-mmc",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sdhci_pxav2_of_match);
+
+static struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev)
+{
+ struct sdhci_pxa_platdata *pdata;
+ struct device_node *np = dev->of_node;
+ u32 bus_width;
+ u32 clk_delay_cycles;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ if (of_find_property(np, "non-removable", NULL))
+ pdata->flags |= PXA_FLAG_CARD_PERMANENT;
+
+ of_property_read_u32(np, "bus-width", &bus_width);
+ if (bus_width == 8)
+ pdata->flags |= PXA_FLAG_SD_8_BIT_CAPABLE_SLOT;
+
+ of_property_read_u32(np, "clk-delay-cycles", &clk_delay_cycles);
+ if (clk_delay_cycles > 0) {
+ pdata->clk_delay_sel = 1;
+ pdata->clk_delay_cycles = clk_delay_cycles;
+ }
+
+ return pdata;
+}
+#else
+static inline struct sdhci_pxa_platdata pxav2_get_mmc_pdata(struct device *dev)
+{
+ return NULL;
+}
+#endif
+
static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
{
struct sdhci_pltfm_host *pltfm_host;
@@ -128,6 +173,8 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct sdhci_host *host = NULL;
struct sdhci_pxa *pxa = NULL;
+ const struct of_device_id *match;
+
int ret;
struct clk *clk;
@@ -156,6 +203,10 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
| SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
+ match = of_match_device(of_match_ptr(sdhci_pxav2_of_match), &pdev->dev);
+ if (match) {
+ pdata = pxav2_get_mmc_pdata(dev);
+ }
if (pdata) {
if (pdata->flags & PXA_FLAG_CARD_PERMANENT) {
/* on-chip device */
@@ -218,6 +269,7 @@ static struct platform_driver sdhci_pxav2_driver = {
.driver = {
.name = "sdhci-pxav2",
.owner = THIS_MODULE,
+ .of_match_table = sdhci_pxav2_of_match,
.pm = SDHCI_PLTFM_PMOPS,
},
.probe = sdhci_pxav2_probe,
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index f296956..1835c94 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -28,6 +28,9 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
#include "sdhci.h"
#include "sdhci-pltfm.h"
@@ -164,6 +167,46 @@ static struct sdhci_ops pxav3_sdhci_ops = {
.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
};
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_pxav3_of_match[] = {
+ {
+ .compatible = "mrvl,pxav3-mmc",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sdhci_pxav3_of_match);
+
+static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
+{
+ struct sdhci_pxa_platdata *pdata;
+ struct device_node *np = dev->of_node;
+ u32 bus_width;
+ u32 clk_delay_cycles;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ if (of_find_property(np, "non-removable", NULL))
+ pdata->flags |= PXA_FLAG_CARD_PERMANENT;
+
+ of_property_read_u32(np, "bus-width", &bus_width);
+ if (bus_width == 8)
+ pdata->flags |= PXA_FLAG_SD_8_BIT_CAPABLE_SLOT;
+
+ of_property_read_u32(np, "clk-delay-cycles", &clk_delay_cycles);
+ if (clk_delay_cycles > 0)
+ pdata->clk_delay_cycles = clk_delay_cycles;
+
+ return pdata;
+}
+#else
+static inline struct sdhci_pxa_platdata pxav3_get_mmc_pdata(struct device *dev)
+{
+ return NULL;
+}
+#endif
+
static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
{
struct sdhci_pltfm_host *pltfm_host;
@@ -171,6 +214,8 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct sdhci_host *host = NULL;
struct sdhci_pxa *pxa = NULL;
+ const struct of_device_id *match;
+
int ret;
struct clk *clk;
@@ -202,6 +247,10 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
/* enable 1/8V DDR capable */
host->mmc->caps |= MMC_CAP_1_8V_DDR;
+ match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev);
+ if (match)
+ pdata = pxav3_get_mmc_pdata(dev);
+
if (pdata) {
if (pdata->flags & PXA_FLAG_CARD_PERMANENT) {
/* on-chip device */
@@ -263,6 +312,7 @@ static int __devexit sdhci_pxav3_remove(struct platform_device *pdev)
static struct platform_driver sdhci_pxav3_driver = {
.driver = {
.name = "sdhci-pxav3",
+ .of_match_table = sdhci_pxav3_of_match,
.owner = THIS_MODULE,
.pm = SDHCI_PLTFM_PMOPS,
},
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] mmc: sdhci-pxa: Add device tree support
2012-06-12 19:05 [PATCH] mmc: sdhci-pxa: Add device tree support Chris Ball
@ 2012-06-13 3:11 ` zhangfei gao
2012-06-13 14:15 ` Chris Ball
2012-06-20 5:49 ` Chris Ball
1 sibling, 1 reply; 7+ messages in thread
From: zhangfei gao @ 2012-06-13 3:11 UTC (permalink / raw)
To: Chris Ball
Cc: Haojian Zhuang, Zhangfei Gao, Philip Rakity, devicetree-discuss,
linux-mmc
On Wed, Jun 13, 2012 at 3:05 AM, Chris Ball <cjb@laptop.org> wrote:
> Tested on an OLPC XO-1.75. (MMP2, sdhci-pxav3, CONFIG_MACH_MMP2_DT=y)
>
> Signed-off-by: Chris Ball <cjb@laptop.org>
> ---
> .../devicetree/bindings/mmc/sdhci-pxa.txt | 21 ++++++++
> drivers/mmc/host/sdhci-pxav2.c | 52 ++++++++++++++++++++
> drivers/mmc/host/sdhci-pxav3.c | 50 +++++++++++++++++++
> 3 files changed, 123 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
Thanks Chris for the great help, compile error if CONFIG_OF not defined.
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id sdhci_pxav2_of_match[] = {
> + {
> + .compatible = "mrvl,pxav2-mmc",
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, sdhci_pxav2_of_match);
> +
> +static struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev)
> +{
> + struct sdhci_pxa_platdata *pdata;
> + struct device_node *np = dev->of_node;
> + u32 bus_width;
> + u32 clk_delay_cycles;
> +
> + return pdata;
> +}
> +#else
> +static inline struct sdhci_pxa_platdata pxav2_get_mmc_pdata(struct device *dev)
Should be static struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct
device *dev)
> +{
> + return NULL;
> +}
> +#endif
> +
> static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
> {
> struct sdhci_pltfm_host *pltfm_host;
> @@ -128,6 +173,8 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
> struct device *dev = &pdev->dev;
> struct sdhci_host *host = NULL;
> struct sdhci_pxa *pxa = NULL;
> + const struct of_device_id *match;
> +
> int ret;
> struct clk *clk;
>
> @@ -156,6 +203,10 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
> | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
> | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
>
> + match = of_match_device(of_match_ptr(sdhci_pxav2_of_match), &pdev->dev);
> + if (match) {
> + pdata = pxav2_get_mmc_pdata(dev);
> + }
> if (pdata) {
> if (pdata->flags & PXA_FLAG_CARD_PERMANENT) {
> /* on-chip device */
> @@ -218,6 +269,7 @@ static struct platform_driver sdhci_pxav2_driver = {
> .driver = {
> .name = "sdhci-pxav2",
> .owner = THIS_MODULE,
#ifdef CONFIG_OF required, otherwise build fail.
> + .of_match_table = sdhci_pxav2_of_match,
#endif
> .pm = SDHCI_PLTFM_PMOPS,
> },
> .probe = sdhci_pxav2_probe,
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index f296956..1835c94 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> +#ifdef CONFIG_OF
> +static const struct of_device_id sdhci_pxav3_of_match[] = {
> + {
> + .compatible = "mrvl,pxav3-mmc",
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, sdhci_pxav3_of_match);
> +
> +static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
> +{
> +}
> +#else
> +static inline struct sdhci_pxa_platdata pxav3_get_mmc_pdata(struct device *dev)
Should be static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct
device *dev)
> +{
> + return NULL;
> +}
> +#endif
> +
> @@ -263,6 +312,7 @@ static int __devexit sdhci_pxav3_remove(struct platform_device *pdev)
> static struct platform_driver sdhci_pxav3_driver = {
> .driver = {
> .name = "sdhci-pxav3",
#ifdef CONFIG_OF required, otherwise build fail.
> + .of_match_table = sdhci_pxav3_of_match,
#endif
> .owner = THIS_MODULE,
> .pm = SDHCI_PLTFM_PMOPS,
> },
> --
> Chris Ball <cjb@laptop.org> <http://printf.net/>
> One Laptop Per Child
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mmc: sdhci-pxa: Add device tree support
2012-06-13 3:11 ` zhangfei gao
@ 2012-06-13 14:15 ` Chris Ball
[not found] ` <87sjdzxpqr.fsf-DGHOrqG7t0YzNDMTQreKSUB+6BGkLq7r@public.gmane.org>
0 siblings, 1 reply; 7+ messages in thread
From: Chris Ball @ 2012-06-13 14:15 UTC (permalink / raw)
To: zhangfei gao
Cc: Haojian Zhuang, Zhangfei Gao, Philip Rakity, devicetree-discuss,
linux-mmc
Hi Zhangfei,
On Tue, Jun 12 2012, zhangfei gao wrote:
> On Wed, Jun 13, 2012 at 3:05 AM, Chris Ball <cjb@laptop.org> wrote:
>> Tested on an OLPC XO-1.75. (MMP2, sdhci-pxav3, CONFIG_MACH_MMP2_DT=y)
>>
>> Signed-off-by: Chris Ball <cjb@laptop.org>
>> ---
>> .../devicetree/bindings/mmc/sdhci-pxa.txt | 21 ++++++++
>> drivers/mmc/host/sdhci-pxav2.c | 52 ++++++++++++++++++++
>> drivers/mmc/host/sdhci-pxav3.c | 50 +++++++++++++++++++
>> 3 files changed, 123 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
>
> Thanks Chris for the great help, compile error if CONFIG_OF not defined.
Thanks for catching this!
How do you feel about having the compatible node say "sdhci-pxav3"
instead of "mrvl,pxav3-mmc"? I used the mrvl prefix because it fits
in with the rest of your existing DT, but it seems like it would be
better to name the driver directly. The DTs here live inside the
source tree, so we're not depending on anyone else's terminology.
If you're okay with sdhci-pxav{2,3} in compatible, I'll include that
in v2 of the patch with the rest of your fixes.
- Chris.
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Re: [PATCH] mmc: sdhci-pxa: Add device tree support
[not found] ` <87sjdzxpqr.fsf-DGHOrqG7t0YzNDMTQreKSUB+6BGkLq7r@public.gmane.org>
@ 2012-06-14 2:15 ` haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w
2012-06-20 5:46 ` Chris Ball
0 siblings, 1 reply; 7+ messages in thread
From: haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w @ 2012-06-14 2:15 UTC (permalink / raw)
To: Chris Ball, Haojian Zhuang
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Philip Rakity,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Zhangfei Gao, zhangfei gao
[-- Attachment #1.1: Type: text/plain, Size: 1573 bytes --]
On , Chris Ball <cjb-2X9k7bc8m7Mdnm+yROfE0A@public.gmane.org> wrote:
> Hi Zhangfei,
> On Tue, Jun 12 2012, zhangfei gao wrote:
> > On Wed, Jun 13, 2012 at 3:05 AM, Chris Ball cjb-2X9k7bc8m7Mdnm+yROfE0A@public.gmane.org> wrote:
> How do you feel about having the compatible node say "sdhci-pxav3"
> instead of "mrvl,pxav3-mmc"? I used the mrvl prefix because it fits
> in with the rest of your existing DT, but it seems like it would be
> better to name the driver directly. The DTs here live inside the
> source tree, so we're not depending on anyone else's terminology.
> If you're okay with sdhci-pxav{2,3} in compatible, I'll include that
> in v2 of the patch with the rest of your fixes.
Compatible node could be "mrvl,pxav3-mmc" or "mrvl,sdhci-pxav3". It's
depend on your choice. I prefer to use vendor name in compatible property.
And we could avoid naming conflict.
+ if (of_find_property(np, "non-removable", NULL))
+ pdata->flags |= PXA_FLAG_CARD_PERMANENT;
+
+ of_property_read_u32(np, "bus-width", &bus_width);
+ if (bus_width == 8)
+ pdata->flags |= PXA_FLAG_SD_8_BIT_CAPABLE_SLOT;
+
+ of_property_read_u32(np, "clk-delay-cycles", &clk_delay_cycles);
+ if (clk_delay_cycles > 0)
+ pdata->clk_delay_cycles = clk_delay_cycles;
+
These properties should be "mrvl,non-removable", "mrvl,bus-width",
"mrvl,clk-delay-cycles". Since it's mentioned in
Documentations/devicetree/booting-without-of.txt. "It is recommended
that if you add any "custom" property whose name may clash with
standard defined ones, you prefix them with your vendor name and
a comma."
[-- Attachment #1.2: Type: text/html, Size: 2062 bytes --]
[-- Attachment #2: Type: text/plain, Size: 192 bytes --]
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mmc: sdhci-pxa: Add device tree support
2012-06-14 2:15 ` haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w
@ 2012-06-20 5:46 ` Chris Ball
0 siblings, 0 replies; 7+ messages in thread
From: Chris Ball @ 2012-06-20 5:46 UTC (permalink / raw)
To: haojian.zhuang
Cc: zhangfei gao, Zhangfei Gao, Philip Rakity, devicetree-discuss,
linux-mmc
Hi Haojian,
On Wed, Jun 13 2012, haojian.zhuang@gmail.com wrote:
> Compatible node could be "mrvl,pxav3-mmc" or "mrvl,sdhci-pxav3". It's
> depend on your choice. I prefer to use vendor name in compatible
> property.
> And we could avoid naming conflict.
Okay, I'll just stick with mrvl,pxav3-mmc.
> + if (of_find_property(np, "non-removable", NULL))
> + pdata->flags |= PXA_FLAG_CARD_PERMANENT;
> +
> + of_property_read_u32(np, "bus-width", &bus_width);
> + if (bus_width == 8)
> + pdata->flags |= PXA_FLAG_SD_8_BIT_CAPABLE_SLOT;
> +
> + of_property_read_u32(np, "clk-delay-cycles", &clk_delay_cycles);
> + if (clk_delay_cycles > 0)
> + pdata->clk_delay_cycles = clk_delay_cycles;
> +
>
> These properties should be "mrvl,non-removable", "mrvl,bus-width",
> "mrvl,clk-delay-cycles". Since it's mentioned in
> Documentations/devicetree/booting-without-of.txt. "It is recommended
> that if you add any "custom" property whose name may clash with
> standard defined ones, you prefix them with your vendor name and
> a comma."
Not quite -- the "non-removable" and "bus-width" properties are part of
the MMC core DT bindings as defined in:
Documentation/devicetree/bindings/mmc/mmc.txt
They are not custom Marvell properties. So, these two need to stay as
they are (one day we'll interpret them in the sdhci driver instead of in
sdhci-pxa) but I've changed clk_delay_cycles to mrvl,clk_delay_cycles in
v2 of the patch, which I'm about to send out. I also applied all of
Zhangfei's changes.
Thanks for the review!
- Chris.
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mmc: sdhci-pxa: Add device tree support
2012-06-12 19:05 [PATCH] mmc: sdhci-pxa: Add device tree support Chris Ball
2012-06-13 3:11 ` zhangfei gao
@ 2012-06-20 5:49 ` Chris Ball
2012-06-21 3:03 ` Haojian Zhuang
1 sibling, 1 reply; 7+ messages in thread
From: Chris Ball @ 2012-06-20 5:49 UTC (permalink / raw)
To: Haojian Zhuang
Cc: Zhangfei Gao, Philip Rakity, devicetree-discuss, linux-mmc, wmb
Tested on an OLPC XO-1.75. (MMP2, sdhci-pxav3, CONFIG_MACH_MMP2_DT=y)
Signed-off-by: Chris Ball <cjb@laptop.org>
---
Changes since v1:
* Add CONFIG_OF guard around of_match_table, per Zhangfei.
* Fix function prototypes under !CONFIG_OF, per Zhangfei.
* Change "clk-delay-cycles" to "mrvl,clk-delay-cycles", per Haojian.
.../devicetree/bindings/mmc/sdhci-pxa.txt | 21 ++++++++
drivers/mmc/host/sdhci-pxav2.c | 54 ++++++++++++++++++++
drivers/mmc/host/sdhci-pxav3.c | 52 +++++++++++++++++++
3 files changed, 127 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
new file mode 100644
index 0000000..1eb227f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
@@ -0,0 +1,21 @@
+* Marvell sdhci-pxa v2/v3 controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci-pxav2 and sdhci-pxav3 drivers.
+
+Required properties:
+- compatible: Should be "mrvl,pxav2-mmc" or "mrvl,pxav3-mmc".
+
+Optional properties:
+- mrvl,clk-delay-cycles: Specify a number of cycles to delay for tuning.
+
+Example:
+
+sdhci@d4280800 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xd4280800 0x800>;
+ interrupts = <27>;
+ bus-width = <8>;
+ mrvl,clk-delay-cycles = <31>;
+ non-removable;
+};
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index dbb75bf..b6ee885 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -28,6 +28,9 @@
#include <linux/mmc/host.h>
#include <linux/platform_data/pxa_sdhci.h>
#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
#include "sdhci.h"
#include "sdhci-pltfm.h"
@@ -121,6 +124,48 @@ static struct sdhci_ops pxav2_sdhci_ops = {
.platform_8bit_width = pxav2_mmc_set_width,
};
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_pxav2_of_match[] = {
+ {
+ .compatible = "mrvl,pxav2-mmc",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sdhci_pxav2_of_match);
+
+static struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev)
+{
+ struct sdhci_pxa_platdata *pdata;
+ struct device_node *np = dev->of_node;
+ u32 bus_width;
+ u32 clk_delay_cycles;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ if (of_find_property(np, "non-removable", NULL))
+ pdata->flags |= PXA_FLAG_CARD_PERMANENT;
+
+ of_property_read_u32(np, "bus-width", &bus_width);
+ if (bus_width == 8)
+ pdata->flags |= PXA_FLAG_SD_8_BIT_CAPABLE_SLOT;
+
+ of_property_read_u32(np, "mrvl,clk-delay-cycles", &clk_delay_cycles);
+ if (clk_delay_cycles > 0) {
+ pdata->clk_delay_sel = 1;
+ pdata->clk_delay_cycles = clk_delay_cycles;
+ }
+
+ return pdata;
+}
+#else
+static inline struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev)
+{
+ return NULL;
+}
+#endif
+
static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
{
struct sdhci_pltfm_host *pltfm_host;
@@ -128,6 +173,8 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct sdhci_host *host = NULL;
struct sdhci_pxa *pxa = NULL;
+ const struct of_device_id *match;
+
int ret;
struct clk *clk;
@@ -156,6 +203,10 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
| SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
+ match = of_match_device(of_match_ptr(sdhci_pxav2_of_match), &pdev->dev);
+ if (match) {
+ pdata = pxav2_get_mmc_pdata(dev);
+ }
if (pdata) {
if (pdata->flags & PXA_FLAG_CARD_PERMANENT) {
/* on-chip device */
@@ -218,6 +269,9 @@ static struct platform_driver sdhci_pxav2_driver = {
.driver = {
.name = "sdhci-pxav2",
.owner = THIS_MODULE,
+#ifdef CONFIG_OF
+ .of_match_table = sdhci_pxav2_of_match,
+#endif
.pm = SDHCI_PLTFM_PMOPS,
},
.probe = sdhci_pxav2_probe,
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index f296956..cb8be1d 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -28,6 +28,9 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
#include "sdhci.h"
#include "sdhci-pltfm.h"
@@ -164,6 +167,46 @@ static struct sdhci_ops pxav3_sdhci_ops = {
.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
};
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_pxav3_of_match[] = {
+ {
+ .compatible = "mrvl,pxav3-mmc",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sdhci_pxav3_of_match);
+
+static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
+{
+ struct sdhci_pxa_platdata *pdata;
+ struct device_node *np = dev->of_node;
+ u32 bus_width;
+ u32 clk_delay_cycles;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ if (of_find_property(np, "non-removable", NULL))
+ pdata->flags |= PXA_FLAG_CARD_PERMANENT;
+
+ of_property_read_u32(np, "bus-width", &bus_width);
+ if (bus_width == 8)
+ pdata->flags |= PXA_FLAG_SD_8_BIT_CAPABLE_SLOT;
+
+ of_property_read_u32(np, "mrvl,clk-delay-cycles", &clk_delay_cycles);
+ if (clk_delay_cycles > 0)
+ pdata->clk_delay_cycles = clk_delay_cycles;
+
+ return pdata;
+}
+#else
+static inline struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
+{
+ return NULL;
+}
+#endif
+
static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
{
struct sdhci_pltfm_host *pltfm_host;
@@ -171,6 +214,8 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct sdhci_host *host = NULL;
struct sdhci_pxa *pxa = NULL;
+ const struct of_device_id *match;
+
int ret;
struct clk *clk;
@@ -202,6 +247,10 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
/* enable 1/8V DDR capable */
host->mmc->caps |= MMC_CAP_1_8V_DDR;
+ match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev);
+ if (match)
+ pdata = pxav3_get_mmc_pdata(dev);
+
if (pdata) {
if (pdata->flags & PXA_FLAG_CARD_PERMANENT) {
/* on-chip device */
@@ -263,6 +312,9 @@ static int __devexit sdhci_pxav3_remove(struct platform_device *pdev)
static struct platform_driver sdhci_pxav3_driver = {
.driver = {
.name = "sdhci-pxav3",
+#ifdef CONfIG_OF
+ .of_match_table = sdhci_pxav3_of_match,
+#endif
.owner = THIS_MODULE,
.pm = SDHCI_PLTFM_PMOPS,
},
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] mmc: sdhci-pxa: Add device tree support
2012-06-20 5:49 ` Chris Ball
@ 2012-06-21 3:03 ` Haojian Zhuang
0 siblings, 0 replies; 7+ messages in thread
From: Haojian Zhuang @ 2012-06-21 3:03 UTC (permalink / raw)
To: Chris Ball
Cc: Zhangfei Gao, Philip Rakity, devicetree-discuss, linux-mmc, wmb
On Wed, Jun 20, 2012 at 1:49 PM, Chris Ball <cjb@laptop.org> wrote:
> Tested on an OLPC XO-1.75. (MMP2, sdhci-pxav3, CONFIG_MACH_MMP2_DT=y)
>
> Signed-off-by: Chris Ball <cjb@laptop.org>
> ---
> Changes since v1:
>
> * Add CONFIG_OF guard around of_match_table, per Zhangfei.
> * Fix function prototypes under !CONFIG_OF, per Zhangfei.
> * Change "clk-delay-cycles" to "mrvl,clk-delay-cycles", per Haojian.
>
> .../devicetree/bindings/mmc/sdhci-pxa.txt | 21 ++++++++
> drivers/mmc/host/sdhci-pxav2.c | 54 ++++++++++++++++++++
> drivers/mmc/host/sdhci-pxav3.c | 52 +++++++++++++++++++
> 3 files changed, 127 insertions(+)
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-06-21 3:03 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-12 19:05 [PATCH] mmc: sdhci-pxa: Add device tree support Chris Ball
2012-06-13 3:11 ` zhangfei gao
2012-06-13 14:15 ` Chris Ball
[not found] ` <87sjdzxpqr.fsf-DGHOrqG7t0YzNDMTQreKSUB+6BGkLq7r@public.gmane.org>
2012-06-14 2:15 ` haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w
2012-06-20 5:46 ` Chris Ball
2012-06-20 5:49 ` Chris Ball
2012-06-21 3:03 ` Haojian Zhuang
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).