mmc: omap_hsmmc: Add support for quirky omap3 hsmmc controller
authorNishanth Menon <nm@ti.com>
Fri, 14 Feb 2014 05:45:48 +0000 (23:45 -0600)
committerChris Ball <chris@printf.net>
Tue, 4 Mar 2014 16:44:31 +0000 (11:44 -0500)
When device is booted using devicetree, platforms impacted by Erratum
2.1.1.128 is not detected easily in the mmc driver. This erratum
indicates that the module cannot do multi-block transfers. Platforms
such as LDP which use OMAP3 ES revision prior to ES3.0 are impacted by
this.

Provide a new compatible property "ti,omap3-pre-es3-hsmmc" to allow
driver to determine if driver needs to implement quirks associated
with the specific module version (primarily because the IP revision
information is not sufficient for the same).

Signed-off-by: Nishanth Menon <nm@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Balaji T K <balajitk@ti.com>
Signed-off-by: Chris Ball <chris@printf.net>
Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
drivers/mmc/host/omap_hsmmc.c

index 8c8908a..ce80561 100644 (file)
@@ -10,6 +10,7 @@ Required properties:
 - compatible:
  Should be "ti,omap2-hsmmc", for OMAP2 controllers
  Should be "ti,omap3-hsmmc", for OMAP3 controllers
+ Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0
  Should be "ti,omap4-hsmmc", for OMAP4 controllers
 - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1
 
index 4ff906c..b1ac26a 100644 (file)
@@ -192,6 +192,11 @@ struct omap_hsmmc_host {
        struct  omap_mmc_platform_data  *pdata;
 };
 
+struct omap_mmc_of_data {
+       u32 reg_offset;
+       u8 controller_flags;
+};
+
 static int omap_hsmmc_card_detect(struct device *dev, int slot)
 {
        struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -1677,18 +1682,29 @@ static void omap_hsmmc_debugfs(struct mmc_host *mmc)
 #endif
 
 #ifdef CONFIG_OF
-static u16 omap4_reg_offset = 0x100;
+static const struct omap_mmc_of_data omap3_pre_es3_mmc_of_data = {
+       /* See 35xx errata 2.1.1.128 in SPRZ278F */
+       .controller_flags = OMAP_HSMMC_BROKEN_MULTIBLOCK_READ,
+};
+
+static const struct omap_mmc_of_data omap4_mmc_of_data = {
+       .reg_offset = 0x100,
+};
 
 static const struct of_device_id omap_mmc_of_match[] = {
        {
                .compatible = "ti,omap2-hsmmc",
        },
+       {
+               .compatible = "ti,omap3-pre-es3-hsmmc",
+               .data = &omap3_pre_es3_mmc_of_data,
+       },
        {
                .compatible = "ti,omap3-hsmmc",
        },
        {
                .compatible = "ti,omap4-hsmmc",
-               .data = &omap4_reg_offset,
+               .data = &omap4_mmc_of_data,
        },
        {},
 };
@@ -1758,6 +1774,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
        dma_cap_mask_t mask;
        unsigned tx_req, rx_req;
        struct pinctrl *pinctrl;
+       const struct omap_mmc_of_data *data;
 
        match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev);
        if (match) {
@@ -1767,8 +1784,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
                        return PTR_ERR(pdata);
 
                if (match->data) {
-                       const u16 *offsetp = match->data;
-                       pdata->reg_offset = *offsetp;
+                       data = match->data;
+                       pdata->reg_offset = data->reg_offset;
+                       pdata->controller_flags |= data->controller_flags;
                }
        }