summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2017-10-12 12:26:51 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2017-10-17 08:45:49 +0200
commit22c64af6863b97556b9dc08b04a45350d1794f29 (patch)
tree0fc7cf6e6698852627fdd7f0b70c168c0377a481 /drivers
parent1c256a128362d75dfdb0f41cd8a03a59b8870a8f (diff)
downloadbarebox-22c64af6863b97556b9dc08b04a45350d1794f29.tar.gz
barebox-22c64af6863b97556b9dc08b04a45350d1794f29.tar.xz
mci: mmci: add DT support
Just adds the minimal implementation to fill platform_data from the DT properties with Linux binding. As all MMC controllers are supposed to support at least the 3.3V signalling level, this gets exposed regardless of the platform data, just as other controller drivers in Barebox handle this. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mci/mmci.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/mci/mmci.c b/drivers/mci/mmci.c
index 7489ee03a1..f45557d4f7 100644
--- a/drivers/mci/mmci.c
+++ b/drivers/mci/mmci.c
@@ -532,9 +532,37 @@ static void mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
udelay(CLK_CHANGE_DELAY);
}
+static int mmci_of_parse(struct device_node *np,
+ struct mmci_platform_data *plat)
+{
+ if (!IS_ENABLED(CONFIG_OFDEVICE))
+ return 0;
+
+ if (of_get_property(np, "st,sig-dir-dat0", NULL))
+ plat->sigdir |= MCI_ST_DATA0DIREN;
+ if (of_get_property(np, "st,sig-dir-dat2", NULL))
+ plat->sigdir |= MCI_ST_DATA2DIREN;
+ if (of_get_property(np, "st,sig-dir-dat31", NULL))
+ plat->sigdir |= MCI_ST_DATA31DIREN;
+ if (of_get_property(np, "st,sig-dir-dat74", NULL))
+ plat->sigdir |= MCI_ST_DATA74DIREN;
+ if (of_get_property(np, "st,sig-dir-cmd", NULL))
+ plat->sigdir |= MCI_ST_CMDDIREN;
+ if (of_get_property(np, "st,sig-pin-fbclk", NULL))
+ plat->sigdir |= MCI_ST_FBCLKEN;
+
+ if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL))
+ plat->capabilities |= MMC_CAP_MMC_HIGHSPEED;
+ if (of_get_property(np, "mmc-cap-sd-highspeed", NULL))
+ plat->capabilities |= MMC_CAP_SD_HIGHSPEED;
+
+ return 0;
+}
+
static int mmci_probe(struct amba_device *dev, const struct amba_id *id)
{
struct device_d *hw_dev = &dev->dev;
+ struct device_node *np = hw_dev->device_node;
struct mmci_platform_data *plat = hw_dev->platform_data;
struct variant_data *variant = id->data;
u32 sdi_u32;
@@ -542,11 +570,16 @@ static int mmci_probe(struct amba_device *dev, const struct amba_id *id)
struct clk *clk;
int ret;
- if (!plat) {
- dev_err(hw_dev, "missing platform data\n");
+ if (!plat && !np) {
+ dev_err(hw_dev, "missing platform data or DT node\n");
return -EINVAL;
}
+ if (!plat)
+ plat = xzalloc(sizeof(*plat));
+
+ mmci_of_parse(np, plat);
+
host = xzalloc(sizeof(*host));
host->base = amba_get_mem_region(dev);
@@ -625,7 +658,7 @@ static int mmci_probe(struct amba_device *dev, const struct amba_id *id)
host->mci.max_req_size = (1 << variant->datalength_bits) - 1;
host->mci.host_caps = plat->capabilities;
- host->mci.voltages = plat->ocr_mask;
+ host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | plat->ocr_mask;
mci_register(&host->mci);