mmc: support sdhci-mmp2
Subsystems (4)
PATCH v2 1/3 mmc: support sdhci-mmp2
Instead of sharing sdhci-pxa.c, use sdhci-mmp2.c specificlly for mmp2. sdhci-pxa.c is used to share among pxa serious, like pxa910, mmp2, etc. The platfrom difference are put under arch/arm, while is not easy to track.
--- arch/arm/plat-pxa/include/plat/sdhci.h | 43 ++++- drivers/mmc/host/Kconfig | 11 +- drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/sdhci-mmp2.c | 303 ++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-pxa.c | 303 -------------------------------- 5 files changed, 349 insertions(+), 313 deletions(-) create mode 100644 drivers/mmc/host/sdhci-mmp2.c delete mode 100644 drivers/mmc/host/sdhci-pxa.c
arch/arm/plat-pxa/include/plat/sdhci.h +39 -4
@@ -13,23 +13,58 @@#ifndef __PLAT_PXA_SDHCI_H#define __PLAT_PXA_SDHCI_H +#include <linux/mmc/sdhci.h> +#include <linux/platform_device.h> +/* pxa specific flag */ /* Require clock free running */ #define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0) - +/* card alwayes wired to host, like on-chip emmc */ +#define PXA_FLAG_CARD_PERMANENT (1<<1)/* Board design supports 8-bit data on SD/SDIO BUS */ #define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (1<<2) +/* card not use wp, such as micro sd card */ +#define PXA_FLAG_CARD_NO_WP (1<<3) +struct sdhci_pxa ;/* * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI -* @max_speed: the maximum speed supported -* @quirks: quirks of specific device * @flags: flags for platform requirement +* @clk_delay_cycles: +* mmp2: each step is roughly 100ps, 5bits width +* pxa910: each step is 1ns, 4bits width +* @clk_delay_sel: select clk_delay, used on pxa910 +* 0: choose feedback clk +* 1: choose feedback clk + delay value +* 2: choose internal clk +* @ext_cd_gpio: gpio pin used for external CD line +* @ext_cd_gpio_invert: invert values for external CD gpio line +* @clk_delay_enable: enable clk_delay or not, used on pxa910 +* @max_speed: the maximum speed supported +* @host_caps: Standard MMC host capabilities bit field. +* @quirks: quirks of platfrom +* @pm_caps: pm_caps of platfrom */ struct sdhci_pxa_platdata { +unsigned int flags; +unsigned int clk_delay_cycles; +unsigned int clk_delay_sel; +unsigned int ext_cd_gpio; +bool ext_cd_gpio_invert; +bool clk_delay_enable;unsigned int max_speed; +unsigned int host_caps;unsigned int quirks; -unsigned int flags; +unsigned int pm_caps; +}; + +struct sdhci_pxa { +struct sdhci_pxa_platdata *pdata; +struct clk *clk; +struct sdhci_ops *ops; + +u8 clk_enable; +u8 power_mode; };#endif /* __PLAT_PXA_SDHCI_H */
drivers/mmc/host/Kconfig +6 -5
@@ -181,14 +181,15 @@ config MMC_SDHCI_S3C If unsure, say N. -config MMC_SDHCI_PXA - tristate "Marvell PXA168/PXA910/MMP2 SD Host Controller support" - depends on ARCH_PXA || ARCH_MMP +config MMC_SDHCI_MMP2 + tristate "Marvell MMP2 SD Host Controller support" + depends on ARCH_MMP select MMC_SDHCI + select MMC_SDHCI_PLTFM select MMC_SDHCI_IO_ACCESSORS help - This selects the Marvell(R) PXA168/PXA910/MMP2 SD Host Controller. - If you have a PXA168/PXA910/MMP2 platform with SD Host Controller + This selects the Marvell(R) MMP2 SD Host Controller. + If you have a MMP2 platform with SD Host Controller and a card slot, say Y or M here. If unsure, say N.
drivers/mmc/host/Makefile +1 -1
@@ -9,7 +9,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o obj-$(CONFIG_MMC_MXS) += mxs-mmc.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o -obj-$(CONFIG_MMC_SDHCI_PXA) += sdhci-pxa.o +obj-$(CONFIG_MMC_SDHCI_MMP2) += sdhci-mmp2.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o
drivers/mmc/host/sdhci-mmp2.c new file +303 -0
303 lines not on this page · raw message
drivers/mmc/host/sdhci-pxa.c deleted +0 -303
303 lines not on this page · raw message
Signature · 1 line
1.7.0.4
PATCH v2 1/3 mmc: support sdhci-mmp2
Quoted 5 lines · Zhangfei Gao
Instead of sharing
sdhci-pxa.c, usesdhci-mmp2.cspecificlly for mmp2.sdhci-pxa.cis used to share among pxa serious, like pxa910, mmp2, etc. The platfrom difference are put underarch/arm, while is not easy to track.Signed-off-by Zhangfei Gao <[email protected]>
Quoted 9 lines
--- arch/arm/plat-pxa/include/plat/sdhci.h | 43 ++++- drivers/mmc/host/Kconfig | 11 +- drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/sdhci-mmp2.c | 303 ++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-pxa.c | 303 -------------------------------- 5 files changed, 349 insertions(+), 313 deletions(-) create mode 100644 drivers/mmc/host/sdhci-mmp2.c delete mode 100644 drivers/mmc/host/sdhci-pxa.c
Yes, looks good for the most part. I was rather confused by the fact that the old and new file are both 303 lines, so I assumed they would be identical, when they are really completely different.
There is a little room for simplification, I think:
drivers/mmc/host/sdhci-mmp2.c line 82
Quoted 5 lines
drivers/mmc/host/sdhci-mmp2.c new file +5
-0+static unsigned int mmp2_get_ro (struct sdhci_host *host) +{ +/* Micro SD does not support write-protect feature */ +return 0 ; +}
You shouldn't need to provide an empty get_ro function, the default is that there is no write-protect.
drivers/mmc/host/sdhci-mmp2.c line 91
Quoted 8 lines
drivers/mmc/host/sdhci-mmp2.c new file +8
-0+static void mmp2_set_clock (struct sdhci_host *host,unsigned int clock) +{ +struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host); +struct sdhci_pxa *pxa = pltfm_host->priv; + +if (clock) +mmp2_soc_set_timing (host, pxa->pdata); +}
The mmp2_soc_set_timing() function is only called here, so you can easily merge the two into one, starting with
if (!clock) return;
drivers/mmc/host/sdhci-mmp2.c line 139
Quoted 9 lines
drivers/mmc/host/sdhci-mmp2.c new file +9
-0+static int __devinit sdhci_mmp2_probe (struct platform_device *pdev) +{ +struct sdhci_pltfm_host *pltfm_host; +struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; +struct device *dev = &pdev->dev; +struct sdhci_host *host =NULL ; +struct sdhci_pxa *pxa =NULL ; +int ret; +struct clk *clk;
The probe and release functions for mmp2 and pxa910 are almost identical. I'd suggest you leave them in sdhci-pxa.c as a library, and export them using EXPORT_SYMBOL_GPL. Then you can call them from the respective probe functions, e.g.
static struct sdhci_mmp2_ops = {
.set_clock = mmp2_set_clock,
.set_uhs_signaling = mmp2_set_uhs_signaling, .get_ro = mmp2_get_ro,
};
static int __devinit sdhci_mmp2_probe(struct platform_device *pdev)
{
unsigned int quirks = SDHCI_QUIRK_BROKEN_ADMA
| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
| SDHCI_QUIRK_32BIT_DMA_ADDR
| SDHCI_QUIRK_32BIT_DMA_SIZE
| SDHCI_QUIRK_32BIT_ADMA_SIZE
| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
return sdhci_pxa_probe(pdev, quirks, sdhci_mmp2_ops);
}drivers/mmc/host/sdhci-mmp2.c line 150
Quoted 10 lines
drivers/mmc/host/sdhci-mmp2.c new file +10
-0+ pxa =kzalloc (sizeof (struct sdhci_pxa ),GFP_KERNEL ); +if (!pxa) { + ret = -ENOMEM ; + goto out; + } + pxa->ops =kzalloc (sizeof (struct sdhci_ops ),GFP_KERNEL ); +if (!pxa->ops) { + ret = -ENOMEM ; + goto out; + }
I think you really shouldn't allocate the sdhci_ops dynamically. In fact, it would be much better if we were able to mark them as const in all drivers.
Quoted 9 lines
drivers/mmc/host/sdhci-mmp2.c new file +9
-0+ +#ifdef CONFIG_PM +static int sdhci_mmp2_suspend (struct platform_device *dev,pm_message_t state) +{ +struct sdhci_host *host =platform_get_drvdata (dev); + +return sdhci_suspend_host (host, state); +} +
drivers/mmc/host/sdhci-mmp2.c line 272
Quoted 10 lines
drivers/mmc/host/sdhci-mmp2.c new file +10
-0+static int sdhci_mmp2_resume (struct platform_device *dev) +{ +struct sdhci_host *host =platform_get_drvdata (dev); + +return sdhci_resume_host (host); +} +#else +#define sdhci_mmp2_suspend NULL +#define sdhci_mmp2_resume NULL +#endif
Similarly, I think it would be good if sdhci-pltfm.c would simply export these functions so you could refer to them in your driver. There is no need to have identical copies in each variant.
Arnd
PATCH v2 1/3 mmc: support sdhci-mmp2
Quoted 22 lines · Arnd Bergmann
Quoted 6 lines · Zhangfei Gao
? ? ? Instead of sharing
sdhci-pxa.c, usesdhci-mmp2.cspecificlly for mmp2. ? ? ?sdhci-pxa.cis used to share among pxa serious, like pxa910, mmp2, etc. ? ? ? The platfrom difference are put underarch/arm, while is not easy to track.Signed-off-by Zhangfei Gao <[email protected]>---
Quoted 8 lines
?arch/arm/plat-pxa/include/plat/sdhci.h | ? 43 ++++- ?drivers/mmc/host/Kconfig ? ? ? ? ? ? ? | ? 11 +- ?drivers/mmc/host/Makefile ? ? ? ? ? ? ?| ? ?2 +- ?drivers/mmc/host/sdhci-mmp2.c ? ? ? ? ?| ?303 ++++++++++++++++++++++++++++++++ ?drivers/mmc/host/sdhci-pxa.c ? ? ? ? ? | ?303 --------------------------------?5 files changed, 349 insertions(+), 313 deletions(-) ?create mode 100644
drivers/mmc/host/sdhci-mmp2.c?delete mode 100644drivers/mmc/host/sdhci-pxa.cYes, looks good for the most part. I was rather confused by the fact that the old and new file are both 303 lines, so I assumed they would be identical, when they are really completely different.
There is a little room for simplification, I think:
Quoted 8 lines
drivers/mmc/host/sdhci-mmp2.c line 82
Quoted 5 lines
drivers/mmc/host/sdhci-mmp2.c new file +5
-0+static unsigned int mmp2_get_ro (struct sdhci_host *host) +{ + ? ? /* Micro SD does not support write-protect feature */ + ? ? return 0; +}You shouldn't need to provide an empty
get_rofunction, the default is that there is no write-protect.
Thanks Arnd for review.
The reason to put get_ro here is some board use micro sd, while some board design is general sd card.
The micro sd do not use write-protect, while SDHCI_WRITE_PROTECT will return 1 in our controller, so it shows read only.
So add one call back for the board with micro sd card via flag.
Quoted 13 lines
drivers/mmc/host/sdhci-mmp2.c line 91
Quoted 9 lines
drivers/mmc/host/sdhci-mmp2.c new file +8
-0+static void mmp2_set_clock (struct sdhci_host *host,unsigned int clock) +{ + ? ? struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + ? ? struct sdhci_pxa *pxa = pltfm_host->priv; + + ? ? if (clock) + ? ? ? ? ? ? mmp2_soc_set_timing(host, pxa->pdata); +}The
mmp2_soc_set_timing()function is only called here, so you can easily merge the two into one, starting with
Quoted 2 lines
? ? ? ?if (!clock)
? ? ? ? ? ? ? ?return;
OK, thanks,
Quoted 44 lines
Review
Quoted 10 lines
(quoted diff) +9
-0+static int __devinit sdhci_mmp2_probe(struct platform_device *pdev) +{ + ? ? struct sdhci_pltfm_host *pltfm_host; + ? ? struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; + ? ? struct device *dev = &pdev->dev; + ? ? struct sdhci_host *host = NULL; + ? ? struct sdhci_pxa *pxa = NULL; + ? ? int ret; + ? ? struct clk *clk;The probe and release functions for mmp2 and pxa910 are almost identical. I'd suggest you leave them in
sdhci-pxa.cas a library, and export them usingEXPORT_SYMBOL_GPL. Then you can call them from the respective probe functions, e.g.static struct
sdhci_mmp2_ops= {
? ? ? ?.set_clock =mmp2_set_clock,
? ? ? ?.set_uhs_signaling =mmp2_set_uhs_signaling,
? ? ? ?.get_ro =mmp2_get_ro,
};
static int__devinitsdhci_mmp2_probe(struct platform_device *pdev){
? ? ? ? unsigned int quirks =SDHCI_QUIRK_BROKEN_ADMA? ? ? ? ? ? ? ?| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL ? ? ? ? ? ? ? ?| SDHCI_QUIRK_32BIT_DMA_ADDR ? ? ? ? ? ? ? ?| SDHCI_QUIRK_32BIT_DMA_SIZE ? ? ? ? ? ? ? ?| SDHCI_QUIRK_32BIT_ADMA_SIZE ? ? ? ? ? ? ? ?| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;? ? ? ?return
sdhci_pxa_probe(pdev, quirks, sdhci_mmp2_ops); }Quoted 10 lines
+ ? ? pxa =
kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL);
+ ? ? if (!pxa) {
+ ? ? ? ? ? ? ret =-ENOMEM;
+ ? ? ? ? ? ? goto out;
+ ? ? }
+ ? ?pxa->ops=kzalloc(sizeof(struct sdhci_ops), GFP_KERNEL);
+ ? ? if (!pxa->ops) {
+ ? ? ? ? ? ? ret =-ENOMEM;
+ ? ? ? ? ? ? goto out;
+ ? ? }
Quoted 3 lines
I think you really shouldn't allocate the
sdhci_opsdynamically. In fact, it would be much better if we were able to mark them as const in all drivers.
We found some issues when supporting multi-slot, each slot may have different ops.
So use the method of allocating the sdhci_ops dynamically instead of using static ops.
For example, emmc has 74_clocks call back, while mmc and sdio slot does not have such ops.
If not dynamically allocate sdhci_ops, all slot ops may become same, and 74_clocks may be called for every slot.
Also, some board may have get_ro, while other board may not, so transfer the ops via flags.
Not sure whether it is worthy to add additional common files to share probe and remove function.
Also the init the ops part are different.
Quoted 16 lines
Quoted 16 lines
drivers/mmc/host/sdhci-mmp2.c new file +15
-0+ +#ifdef CONFIG_PM +static int sdhci_mmp2_suspend (struct platform_device *dev,pm_message_t state) +{ + ? ? struct sdhci_host *host = platform_get_drvdata(dev); + + ? ? return sdhci_suspend_host(host, state); +} + +static int sdhci_mmp2_resume (struct platform_device *dev) +{ + ? ? struct sdhci_host *host = platform_get_drvdata(dev); + + ? ? return sdhci_resume_host(host); +}
Quoted 9 lines
drivers/mmc/host/sdhci-mmp2.c line 272
Quoted 4 lines
drivers/mmc/host/sdhci-mmp2.c new file +4
-0+#else +#define sdhci_mmp2_suspend ? NULL +#define sdhci_mmp2_resume ? ?NULL +#endif Similarly, I think it would be good if
sdhci-pltfm.cwould simply export these functions so you could refer to them in your driver. There is no need to have identical copies in each variant.
There are some additional code for suspend and resume, so sdhci_pltfm_suspend may not enough.
For example, when enable wifi host sleep feature, additional register have to be configured.
Quoted 6 lines
? ? ? ?Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo at vger.kernel.org
More majordomo info at ?http://vger.kernel.org/majordomo-info.html
PATCH v2 1/3 mmc: support sdhci-mmp2
Quoted 103 lines · zhangfei gao
Quoted 22 lines · Arnd Bergmann
Quoted 5 lines · Zhangfei Gao
Instead of sharing
sdhci-pxa.c, usesdhci-mmp2.cspecificlly for mmp2.sdhci-pxa.cis used to share among pxa serious, like pxa910, mmp2, etc. The platfrom difference are put underarch/arm, while is not easy to track.Signed-off-by Zhangfei Gao <[email protected]>Quoted 9 lines
--- arch/arm/plat-pxa/include/plat/sdhci.h | 43 ++++- drivers/mmc/host/Kconfig | 11 +- drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/sdhci-mmp2.c | 303 ++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-pxa.c | 303 -------------------------------- 5 files changed, 349 insertions(+), 313 deletions(-) create mode 100644 drivers/mmc/host/sdhci-mmp2.c delete mode 100644 drivers/mmc/host/sdhci-pxa.cYes, looks good for the most part. I was rather confused by the fact that the old and new file are both 303 lines, so I assumed they would be identical, when they are really completely different.
There is a little room for simplification, I think:
Quoted 8 lines
drivers/mmc/host/sdhci-mmp2.c line 82
Quoted 5 lines
drivers/mmc/host/sdhci-mmp2.c new file +5
-0+static unsigned int mmp2_get_ro (struct sdhci_host *host) +{ +/* Micro SD does not support write-protect feature */ +return 0 ; +}You shouldn't need to provide an empty
get_rofunction, the default is that there is no write-protect.Thanks Arnd for review.
The reason to putget_rohere is some board use micro sd, while some board design is general sd card.
The micro sd do not use write-protect, whileSDHCI_WRITE_PROTECTwill return 1 in our controller, so it shows read only.
So add one call back for the board with micro sd card via flag.Quoted 13 lines
drivers/mmc/host/sdhci-mmp2.c line 91
Quoted 9 lines
drivers/mmc/host/sdhci-mmp2.c new file +8
-0+static void mmp2_set_clock (struct sdhci_host *host,unsigned int clock) +{ +struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host); +struct sdhci_pxa *pxa = pltfm_host->priv; + +if (clock) +mmp2_soc_set_timing (host, pxa->pdata); +}The
mmp2_soc_set_timing()function is only called here, so you can easily merge the two into one, starting withQuoted 2 lines
if (!clock) return;OK, thanks,
Quoted 44 lines
drivers/mmc/host/sdhci-mmp2.c line 139
Quoted 10 lines
drivers/mmc/host/sdhci-mmp2.c new file +9
-0+static int __devinit sdhci_mmp2_probe (struct platform_device *pdev) +{ +struct sdhci_pltfm_host *pltfm_host; +struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; +struct device *dev = &pdev->dev; +struct sdhci_host *host =NULL ; +struct sdhci_pxa *pxa =NULL ; +int ret; +struct clk *clk;The probe and release functions for mmp2 and pxa910 are almost identical. I'd suggest you leave them in
sdhci-pxa.cas a library, and export them usingEXPORT_SYMBOL_GPL. Then you can call them from the respective probe functions, e.g.static struct
sdhci_mmp2_ops= {
.set_clock =mmp2_set_clock,
.set_uhs_signaling =mmp2_set_uhs_signaling, .get_ro =mmp2_get_ro,
};
static int__devinitsdhci_mmp2_probe(struct platform_device *pdev){ unsigned int quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; return sdhci_pxa_probe(pdev, quirks, sdhci_mmp2_ops); }drivers/mmc/host/sdhci-mmp2.c line 150
Quoted 10 lines
drivers/mmc/host/sdhci-mmp2.c new file +10
-0+ pxa =kzalloc (sizeof (struct sdhci_pxa ),GFP_KERNEL ); +if (!pxa) { + ret = -ENOMEM ; + goto out; + } + pxa->ops =kzalloc (sizeof (struct sdhci_ops ),GFP_KERNEL ); +if (!pxa->ops) { + ret = -ENOMEM ; + goto out; + }Quoted 3 lines
I think you really shouldn't allocate the
sdhci_opsdynamically. In fact, it would be much better if we were able to mark them as const in all drivers.
Quoted 10 lines
We found some issues when supporting multi-slot, each slot may have different ops.
So use the method of allocating thesdhci_opsdynamically instead of using static ops.
For example, emmc has 74_clocks call back, while mmc and sdio slot does not have such ops.
If not dynamically allocatesdhci_ops, all slot ops may become same, and 74_clocks may be called for every slot.
Also, some board may haveget_ro, while other board may not, so transfer the ops via flags.
74 clock code causes no harm for SD/eMMC/SDIO. You can
save 74 clocks if that really is important for SDIO. I do not know what a SD slot is. You cannot make any assumptions about what card the user will put into a slot.
Quoted 42 lines
Not sure whether it is worthy to add additional common files to share probe and remove function.
Also the init the ops part are different.Quoted 16 lines
Quoted 16 lines
drivers/mmc/host/sdhci-mmp2.c new file +15
-0+ +#ifdef CONFIG_PM +static int sdhci_mmp2_suspend (struct platform_device *dev,pm_message_t state) +{ +struct sdhci_host *host =platform_get_drvdata (dev); + +return sdhci_suspend_host (host, state); +} + +static int sdhci_mmp2_resume (struct platform_device *dev) +{ +struct sdhci_host *host =platform_get_drvdata (dev); + +return sdhci_resume_host (host); +}Quoted 9 lines
drivers/mmc/host/sdhci-mmp2.c line 272
Quoted 4 lines
drivers/mmc/host/sdhci-mmp2.c new file +4
-0+#else +#define sdhci_mmp2_suspend NULL +#define sdhci_mmp2_resume NULL +#endif Similarly, I think it would be good if
sdhci-pltfm.cwould simply export these functions so you could refer to them in your driver. There is no need to have identical copies in each variant.There are some additional code for suspend and resume, so
sdhci_pltfm_suspendmay not enough.
For example, when enable wifi host sleep feature, additional register have to be configured.Quoted 6 lines
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 1/3 mmc: support sdhci-mmp2
In reply to zhangfei gaoQuoted 11 lines · On Monday 30 May 2011 07:42:04 zhangfei gao wrote:
Quoted 9 lines · Arnd Bergmann
drivers/mmc/host/sdhci-mmp2.c line 82
Quoted 5 lines · Zhangfei Gao
drivers/mmc/host/sdhci-mmp2.c new file +5
-0+static unsigned int mmp2_get_ro (struct sdhci_host *host) +{ +/* Micro SD does not support write-protect feature */ +return 0 ; +}You shouldn't need to provide an empty
get_rofunction, the default is that there is no write-protect.
Quoted 6 lines
Thanks Arnd for review.
The reason to putget_rohere is some board use micro sd, while some board design is general sd card.
The micro sd do not use write-protect, whileSDHCI_WRITE_PROTECTwill return 1 in our controller, so it shows read only.
So add one call back for the board with micro sd card via flag.
Ok, I see.
Quoted 26 lines
Quoted 11 lines
drivers/mmc/host/sdhci-mmp2.c line 150
Quoted 10 lines
drivers/mmc/host/sdhci-mmp2.c new file +10
-0+ pxa =kzalloc (sizeof (struct sdhci_pxa ),GFP_KERNEL ); +if (!pxa) { + ret = -ENOMEM ; + goto out; + } + pxa->ops =kzalloc (sizeof (struct sdhci_ops ),GFP_KERNEL ); +if (!pxa->ops) { + ret = -ENOMEM ; + goto out; + }Quoted 3 lines
I think you really shouldn't allocate the
sdhci_opsdynamically. In fact, it would be much better if we were able to mark them as const in all drivers.We found some issues when supporting multi-slot, each slot may have different ops.
So use the method of allocating thesdhci_opsdynamically instead of using static ops.
For example, emmc has 74_clocks call back, while mmc and sdio slot does not have such ops.
If not dynamically allocatesdhci_ops, all slot ops may become same, and 74_clocks may be called for every slot.
Also, some board may haveget_ro, while other board may not, so transfer the ops via flags.
Quoted 3 lines
Not sure whether it is worthy to add additional common files to share probe and remove function.
Also the init the ops part are different.
IMHO, we should try much harder to keep the ops constant. For the two examples you gave, I would probably put a flag into private data for the get_ro operation to signify that it's never read-only, and provide a second set of operations for emmc, so that in the probe function you check the type of device and then set the appropriate one.
You could also do the same for all three cases:
if (emmc) host->ops = &sdhci_mmp2_emmc_ops; else if (!has_ro_switch) host->ops = &sdhci_mmp2_rw_ops; else host->ops = &sdhci_mmp2_default_ops;
Quoted 25 lines
Quoted 15 lines
Quoted 15 lines
drivers/mmc/host/sdhci-mmp2.c new file +15
-0+ +#ifdef CONFIG_PM +static int sdhci_mmp2_suspend (struct platform_device *dev,pm_message_t state) +{ +struct sdhci_host *host =platform_get_drvdata (dev); + +return sdhci_suspend_host (host, state); +} + +static int sdhci_mmp2_resume (struct platform_device *dev) +{ +struct sdhci_host *host =platform_get_drvdata (dev); + +return sdhci_resume_host (host); +}Quoted 9 lines
drivers/mmc/host/sdhci-mmp2.c line 272
Quoted 4 lines
drivers/mmc/host/sdhci-mmp2.c new file +4
-0+#else +#define sdhci_mmp2_suspend NULL +#define sdhci_mmp2_resume NULL +#endif Similarly, I think it would be good if
sdhci-pltfm.cwould simply export these functions so you could refer to them in your driver. There is no need to have identical copies in each variant.
Quoted 4 lines
There are some additional code for suspend and resume, so
sdhci_pltfm_suspendmay not enough.
For example, when enable wifi host sleep feature, additional register have to be configured.
Well, not all drivers would have to use the common functions, but right now there are a number of identical copies, so it's certainly worth sharing.
Note that this comment wasn't directed at your patch as much as at the overall design of the sdhci sub-drivers.
Arnd
PATCH v2 1/3 mmc: support sdhci-mmp2
Quoted 57 lines · Arnd Bergmann
Quoted 11 lines · On Monday 30 May 2011 07:42:04 zhangfei gao wrote:
Quoted 9 lines · Arnd Bergmann
drivers/mmc/host/sdhci-mmp2.c line 82
Quoted 5 lines · Zhangfei Gao
drivers/mmc/host/sdhci-mmp2.c new file +5
-0+static unsigned int mmp2_get_ro (struct sdhci_host *host) +{ + ? ? /* Micro SD does not support write-protect feature */ + ? ? return 0; +}You shouldn't need to provide an empty
get_rofunction, the default is that there is no write-protect.Quoted 6 lines
Thanks Arnd for review.
The reason to putget_rohere is some board use micro sd, while some board design is general sd card.
The micro sd do not use write-protect, whileSDHCI_WRITE_PROTECTwill return 1 in our controller, so it shows read only.
So add one call back for the board with micro sd card via flag.Ok, I see.
Quoted 26 lines
Quoted 11 lines
Quoted 10 lines
+ ? ? pxa =
kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL);
+ ? ? if (!pxa) {
+ ? ? ? ? ? ? ret =-ENOMEM;
+ ? ? ? ? ? ? goto out;
+ ? ? }
+ ? ?pxa->ops=kzalloc(sizeof(struct sdhci_ops), GFP_KERNEL);
+ ? ? if (!pxa->ops) {
+ ? ? ? ? ? ? ret =-ENOMEM;
+ ? ? ? ? ? ? goto out;
+ ? ? }Quoted 3 lines
I think you really shouldn't allocate the
sdhci_opsdynamically. In fact, it would be much better if we were able to mark them as const in all drivers.We found some issues when supporting multi-slot, each slot may have different ops.
So use the method of allocating thesdhci_opsdynamically instead of using static ops.
For example, emmc has 74_clocks call back, while mmc and sdio slot does not have such ops.
If not dynamically allocatesdhci_ops, all slot ops may become same, and 74_clocks may be called for every slot.
Also, some board may haveget_ro, while other board may not, so transfer the ops via flags.Quoted 3 lines
Not sure whether it is worthy to add additional common files to share probe and remove function.
Also the init the ops part are different.IMHO, we should try much harder to keep the ops constant. For the two examples you gave, I would probably put a flag into private data for the
get_rooperation to signify that it's never read-only, and provide a second set of operations for emmc, so that in the probe function you check the type of device and then set the appropriate one.
Quoted 8 lines
You could also do the same for all three cases:
? ? ? ?if (emmc)
? ? ? ? ? ? ? ?host->ops =&sdhci_mmp2_emmc_ops; ? ? ? ?else if (!has_ro_switch)
? ? ? ? ? ? ? ?host->ops =&sdhci_mmp2_rw_ops; ? ? ? ?else
? ? ? ? ? ? ? ?host->ops =&sdhci_mmp2_default_ops;
Thanks, will take this method to make the ops constant.
Quoted 26 lines
Quoted 26 lines
Quoted 25 lines
Quoted 10 lines
drivers/mmc/host/sdhci-mmp2.c new file +9
-0+ +#ifdef CONFIG_PM +static int sdhci_mmp2_suspend (struct platform_device *dev,pm_message_t state) +{ + ? ? struct sdhci_host *host = platform_get_drvdata(dev); + + ? ? return sdhci_suspend_host(host, state); +} +drivers/mmc/host/sdhci-mmp2.c line 272
Quoted 10 lines
drivers/mmc/host/sdhci-mmp2.c new file +10
-0+static int sdhci_mmp2_resume (struct platform_device *dev) +{ + ? ? struct sdhci_host *host = platform_get_drvdata(dev); + + ? ? return sdhci_resume_host(host); +} +#else +#define sdhci_mmp2_suspend ? NULL +#define sdhci_mmp2_resume ? ?NULL +#endif Similarly, I think it would be good if
sdhci-pltfm.cwould simply export these functions so you could refer to them in your driver. There is no need to have identical copies in each variant.
Quoted 8 lines
Quoted 4 lines
There are some additional code for suspend and resume, so
sdhci_pltfm_suspendmay not enough.
For example, when enable wifi host sleep feature, additional register have to be configured.Well, not all drivers would have to use the common functions, but right now there are a number of identical copies, so it's certainly worth sharing.
Then we use sdhci_pltfm_suspend first, and change to private suspend & resume when supporting additional feature.
Quoted 6 lines
Note that this comment wasn't directed at your patch as much as at the overall design of the sdhci sub-drivers.
? ? ? ?Arnd
PATCH v2 1/3 mmc: support sdhci-mmp2
In reply to zhangfei gaoQuoted 12 lines · zhangfei gao
Quoted 11 lines
There is a little room for simplification, I think:
drivers/mmc/host/sdhci-mmp2.c line 82
Quoted 5 lines
drivers/mmc/host/sdhci-mmp2.c new file +5
-0+static unsigned int mmp2_get_ro (struct sdhci_host *host) +{ +/* Micro SD does not support write-protect feature */ +return 0 ; +}You shouldn't need to provide an empty
get_rofunction, the default is that there is no write-protect.
Quoted 6 lines
Thanks Arnd for review.
The reason to putget_rohere is some board use micro sd, while some board design is general sd card.
The micro sd do not use write-protect, whileSDHCI_WRITE_PROTECTwill return 1 in our controller, so it shows read only.
So add one call back for the board with micro sd card via flag.
The code sets get_ro is for all the controllers. Some board designs may connect the WP signal.
The host->ops field should be filled in using information in the board file using a flag such as the example with PXA_FLAG_CARD_PERMANENT.
eg
if (pdata && pdata->flags & PXA_FLAG_NO_WP) {
***** etc ****
}PATCH v2 1/3 mmc: support sdhci-mmp2
Quoted 26 lines · Philip Rakity
Quoted 12 lines · zhangfei gao
Quoted 11 lines
There is a little room for simplification, I think:
drivers/mmc/host/sdhci-mmp2.c line 82
Quoted 5 lines
drivers/mmc/host/sdhci-mmp2.c new file +5
-0+static unsigned int mmp2_get_ro (struct sdhci_host *host) +{ + ? ? /* Micro SD does not support write-protect feature */ + ? ? return 0; +}You shouldn't need to provide an empty
get_rofunction, the default is that there is no write-protect.Quoted 6 lines
Thanks Arnd for review.
The reason to putget_rohere is some board use micro sd, while some board design is general sd card.
The micro sd do not use write-protect, whileSDHCI_WRITE_PROTECTwill return 1 in our controller, so it shows read only.
So add one call back for the board with micro sd card via flag.The code sets
get_rois for all the controllers. ? Some board designs may connect the WP signal.
Quoted 10 lines
The
host->opsfield should be filled in using information in the board file using a flag such as the example with ?PXA_FLAG_CARD_PERMANENT.eg
? ? ? ?if (pdata &&
pdata->flags&PXA_FLAG_NO_WP) { ? ? ? ? ? ? ? ?***** etc ****
? ? ? ?}
This method is used in v1,
The method makes sdhci_ops non-const and have to dynamically alloc sdhci_ops, since host->ops is pointer.
Will keep use const sdhci_ops, recommended by Arnd.
Quoted 3 lines
PATCH v2 1/3 mmc: support sdhci-mmp2
Quoted 38 lines · zhangfei gao
Quoted 26 lines · Philip Rakity
Quoted 12 lines · zhangfei gao
Quoted 11 lines
There is a little room for simplification, I think:
drivers/mmc/host/sdhci-mmp2.c line 82
Quoted 5 lines
drivers/mmc/host/sdhci-mmp2.c new file +5
-0+static unsigned int mmp2_get_ro (struct sdhci_host *host) +{ +/* Micro SD does not support write-protect feature */ +return 0 ; +}You shouldn't need to provide an empty
get_rofunction, the default is that there is no write-protect.Quoted 6 lines
Thanks Arnd for review.
The reason to putget_rohere is some board use micro sd, while some board design is general sd card.
The micro sd do not use write-protect, whileSDHCI_WRITE_PROTECTwill return 1 in our controller, so it shows read only.
So add one call back for the board with micro sd card via flag.The code sets
get_rois for all the controllers. Some board designs may connect the WP signal.Quoted 10 lines
The
host->opsfield should be filled in using information in the board file using a flag such as the example withPXA_FLAG_CARD_PERMANENT.eg
if (pdata && pdata->flags & PXA_FLAG_NO_WP) { ***** etc **** }
Quoted 4 lines
This method is used in v1,
The method makessdhci_opsnon-const and have to dynamically allocsdhci_ops, sincehost->opsis pointer.
Will keep use constsdhci_ops, recommended by Arnd.
Not acceptable.
There are 3 cases for WP signal
a) They are connected to the controller using GPIO
b( They are NOT connected and the corresponding pin is not used
c) They are NOT connected and the corresponding pin is used by something else.
case a)
program GPIO as is done today in brownstone and aspen
case b)
configure the MFP pin to be pull high/low to indicate NO WP. The pin cannot be left floating
case c)
you need a quirk and the call back.
PATCH v2 1/3 mmc: support sdhci-mmp2
Quoted 16 lines
Quoted 5 lines
This method is used in v1,
The method makessdhci_opsnon-const and have to dynamically allocsdhci_ops, sincehost->opsis pointer.
Will keep use constsdhci_ops, recommended by Arnd.Not acceptable.
There are ?3 cases for ?WP signal
a) They are connected to the controller using GPIO
b( They are NOT connected and the corresponding ?pin is not used
c) They are NOT connected and the corresponding ?pin is used by something else.
Quoted 5 lines
case a)
? ? ? ?program GPIO as is done today in brownstone and aspencase b)
? ? ? ?configure the MFP pin to be pull high/low to indicate NO WP. ?The pin cannot be left floating
Thanks, configure WP pin to LOW should be work for micro sd card.
Quoted 9 lines
case c)
? ? ? ?you need a quirk and the call back.