Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 261133
b: refs/heads/master
c: abfafc2
h: refs/heads/master
i:
  261131: 98d84c3
v: v3
  • Loading branch information
Shawn Guo committed Jul 27, 2011
1 parent 6ce4d50 commit 9ebd781
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a4d2177f00a5252d825236c5124bc1e9918bdb41
refs/heads/master: abfafc2d10ee2ad217be9ef06181819ca5dd6960
34 changes: 34 additions & 0 deletions trunk/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
* Freescale Enhanced Secure Digital Host Controller (eSDHC) for i.MX

The Enhanced Secure Digital Host Controller on Freescale i.MX family
provides an interface for MMC, SD, and SDIO types of memory cards.

Required properties:
- compatible : Should be "fsl,<chip>-esdhc"
- reg : Should contain eSDHC registers location and length
- interrupts : Should contain eSDHC interrupt

Optional properties:
- fsl,card-wired : Indicate the card is wired to host permanently
- fsl,cd-internal : Indicate to use controller internal card detection
- fsl,wp-internal : Indicate to use controller internal write protection
- cd-gpios : Specify GPIOs for card detection
- wp-gpios : Specify GPIOs for write protection

Examples:

esdhc@70004000 {
compatible = "fsl,imx51-esdhc";
reg = <0x70004000 0x4000>;
interrupts = <1>;
fsl,cd-internal;
fsl,wp-internal;
};

esdhc@70008000 {
compatible = "fsl,imx51-esdhc";
reg = <0x70008000 0x4000>;
interrupts = <2>;
cd-gpios = <&gpio0 6 0>; /* GPIO1_6 */
wp-gpios = <&gpio0 5 0>; /* GPIO1_5 */
};
78 changes: 69 additions & 9 deletions trunk/drivers/mmc/host/sdhci-esdhc-imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <mach/esdhc.h>
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
Expand Down Expand Up @@ -74,6 +77,15 @@ static struct platform_device_id imx_esdhc_devtype[] = {
};
MODULE_DEVICE_TABLE(platform, imx_esdhc_devtype);

static const struct of_device_id imx_esdhc_dt_ids[] = {
{ .compatible = "fsl,imx25-esdhc", .data = &imx_esdhc_devtype[IMX25_ESDHC], },
{ .compatible = "fsl,imx35-esdhc", .data = &imx_esdhc_devtype[IMX35_ESDHC], },
{ .compatible = "fsl,imx51-esdhc", .data = &imx_esdhc_devtype[IMX51_ESDHC], },
{ .compatible = "fsl,imx53-esdhc", .data = &imx_esdhc_devtype[IMX53_ESDHC], },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);

static inline int is_imx25_esdhc(struct pltfm_imx_data *data)
{
return data->devtype == IMX25_ESDHC;
Expand Down Expand Up @@ -290,8 +302,48 @@ static irqreturn_t cd_irq(int irq, void *data)
return IRQ_HANDLED;
};

#ifdef CONFIG_OF
static int __devinit
sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
struct esdhc_platform_data *boarddata)
{
struct device_node *np = pdev->dev.of_node;

if (!np)
return -ENODEV;

if (of_get_property(np, "fsl,card-wired", NULL))
boarddata->cd_type = ESDHC_CD_PERMANENT;

if (of_get_property(np, "fsl,cd-controller", NULL))
boarddata->cd_type = ESDHC_CD_CONTROLLER;

if (of_get_property(np, "fsl,wp-controller", NULL))
boarddata->wp_type = ESDHC_WP_CONTROLLER;

boarddata->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
if (gpio_is_valid(boarddata->cd_gpio))
boarddata->cd_type = ESDHC_CD_GPIO;

boarddata->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
if (gpio_is_valid(boarddata->wp_gpio))
boarddata->wp_type = ESDHC_WP_GPIO;

return 0;
}
#else
static inline int
sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
struct esdhc_platform_data *boarddata)
{
return -ENODEV;
}
#endif

static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(imx_esdhc_dt_ids, &pdev->dev);
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_host *host;
struct esdhc_platform_data *boarddata;
Expand All @@ -306,9 +358,13 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host);

imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
if (!imx_data)
return -ENOMEM;
if (!imx_data) {
err = -ENOMEM;
goto err_imx_data;
}

if (of_id)
pdev->id_entry = of_id->data;
imx_data->devtype = pdev->id_entry->driver_data;
pltfm_host->priv = imx_data;

Expand All @@ -331,14 +387,16 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
if (is_imx53_esdhc(imx_data))
imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;

if (!host->mmc->parent->platform_data) {
dev_err(mmc_dev(host->mmc), "no board data!\n");
err = -EINVAL;
goto no_board_data;
}
imx_data->boarddata = *((struct esdhc_platform_data *)
host->mmc->parent->platform_data);
boarddata = &imx_data->boarddata;
if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
if (!host->mmc->parent->platform_data) {
dev_err(mmc_dev(host->mmc), "no board data!\n");
err = -EINVAL;
goto no_board_data;
}
imx_data->boarddata = *((struct esdhc_platform_data *)
host->mmc->parent->platform_data);
}

/* write_protect */
if (boarddata->wp_type == ESDHC_WP_GPIO) {
Expand Down Expand Up @@ -407,6 +465,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
clk_put(pltfm_host->clk);
err_clk_get:
kfree(imx_data);
err_imx_data:
sdhci_pltfm_free(pdev);
return err;
}
Expand Down Expand Up @@ -442,6 +501,7 @@ static struct platform_driver sdhci_esdhc_imx_driver = {
.driver = {
.name = "sdhci-esdhc-imx",
.owner = THIS_MODULE,
.of_match_table = imx_esdhc_dt_ids,
},
.id_table = imx_esdhc_devtype,
.probe = sdhci_esdhc_imx_probe,
Expand Down

0 comments on commit 9ebd781

Please sign in to comment.