On Thu, Apr 21, 2011 at 03:19:57PM +0200, Domenico Andreoli wrote:
From: Domenico Andreoli cav...@gmail.com
This patch adds helpers to manage OF binding of MMC DeviceTree configs.
They don't cover all the MMC configuration cases, indeed are only a
slight generalization of those found in the MMC-over-SPI driver. More
will come later.
Can the mmc-over-spi driver be generalized to use this code too?
Signed-off-by: Domenico Andreoli cav...@gmail.com
---
drivers/of/Kconfig |4 +
drivers/of/Makefile|1 +
drivers/of/of_mmc.c| 165
+
include/linux/of_mmc.h | 50 +++
Personally I think it makes more sense for this code to live in
drivers/mmc/core.
4 files changed, 220 insertions(+)
Index: b/drivers/of/Kconfig
===
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -59,6 +59,10 @@ config OF_I2C
help
OpenFirmware I2C accessors
+config OF_MMC
+ depends on MMC
+ def_bool y
+
config OF_NET
depends on NETDEVICES
def_bool y
Index: b/drivers/of/Makefile
===
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_OF_DEVICE) += device.o plat
obj-$(CONFIG_OF_GPIO) += gpio.o
obj-$(CONFIG_OF_CLOCK) += clock.o
obj-$(CONFIG_OF_I2C) += of_i2c.o
+obj-$(CONFIG_OF_MMC) += of_mmc.o
obj-$(CONFIG_OF_NET) += of_net.o
obj-$(CONFIG_OF_SPI) += of_spi.o
obj-$(CONFIG_OF_MDIO)+= of_mdio.o
Index: b/drivers/of/of_mmc.c
===
--- /dev/null
+++ b/drivers/of/of_mmc.c
@@ -0,0 +1,165 @@
+/*
+ * OF helpers for the MMC API
+ *
+ * Copyright (c) 2011 Domenico Andreoli
+ *
+ * Heavily inspired by the OF support to the MMC-over-SPI driver made
+ * by Anton Vorontsov
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include linux/kernel.h
+#include linux/module.h
+#include linux/device.h
+#include linux/err.h
+#include linux/slab.h
+#include linux/mmc/core.h
+#include linux/gpio.h
+#include linux/of.h
+#include linux/of_mmc.h
+#include linux/of_gpio.h
+
+static int of_read_mmc_gpio(struct of_mmc_crg *crg, int gpio_num)
+{
+ int value, active_low;
+
+ BUG_ON(gpio_num = NUM_MMC_GPIOS);
+
+ /* hitting this means that DeviceTree left this gpio unspecified
+ * by purpose but driver didn't take any measure to define its
+ * behavior (i.e. aborting probe phase or disabling the feature).
+ * driver needs to call of_is_valid_mmc_crg() for each expected
+ * gpio to detect this case.
+ */
+ if (WARN_ON(crg-gpios[gpio_num] 0))
+ return -1;
+
+ value = gpio_get_value(crg-gpios[gpio_num]);
+ active_low = crg-alow_gpios[gpio_num];
+ return value ^ active_low;
+}
+
+int of_get_mmc_cd_gpio(struct of_mmc_crg *crg)
+{
+ return of_read_mmc_gpio(crg, CD_MMC_GPIO);
+}
+EXPORT_SYMBOL(of_get_mmc_cd_gpio);
+
+int of_get_mmc_ro_gpio(struct of_mmc_crg *crg)
+{
+ return of_read_mmc_gpio(crg, WP_MMC_GPIO);
+}
+EXPORT_SYMBOL(of_get_mmc_ro_gpio);
+
+int of_is_valid_mmc_crg(struct of_mmc_crg *crg, int gpio_num)
+{
+ BUG_ON(gpio_num = NUM_MMC_GPIOS);
+ return gpio_is_valid(crg-gpios[gpio_num]);
+}
+EXPORT_SYMBOL(of_is_valid_mmc_crg);
+
+int of_get_mmc_crg(struct device *dev, struct device_node *np,
+ int cd_off, struct of_mmc_crg *crg)
+{
+ int *gpio, *alow;
+ int i, ret;
+
+ memset(crg, 0, sizeof(*crg));
+ crg-cd_irq = -1;
+
+ gpio = crg-gpios;
+ alow = crg-alow_gpios;
+ for (i = 0; i NUM_MMC_GPIOS; i++, gpio++, alow++) {
+ enum of_gpio_flags gpio_flags;
+ *gpio = of_get_gpio_flags(np, cd_off+i, gpio_flags);
+ *alow = !!(gpio_flags OF_GPIO_ACTIVE_LOW);
+
+ if (*gpio == -EEXIST || *gpio == -ENOENT) {
+ /* driver needs to define proper meaning of this missing
+gpio (i.e. abort probe or disable the feature) */
+ pr_debug(%s: gpio #%d is not specified\n, __func__,
i);
+ continue;
+ }
+ if (*gpio 0) {
+ pr_debug(%s: invalid configuration\n, __func__);
+ ret = *gpio;
+ break;
+ }
+ if (!gpio_is_valid(*gpio)) {
+ pr_debug(%s: gpio #%d is not valid: %d\n, __func__,
i, *gpio);
+ ret = -EINVAL;
+ break;
+ }
+ ret =