linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v3 0/5] pinctrl: imx: add pinnmux support
@ 2011-12-20 17:40 Dong Aisheng
  2011-12-20 17:40 ` [RFC PATCH v3 1/5] dt: add of_get_child_count helper function Dong Aisheng
                   ` (4 more replies)
  0 siblings, 5 replies; 98+ messages in thread
From: Dong Aisheng @ 2011-12-20 17:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, linus.walleij, s.hauer, shawn.guo, kernel,
	grant.likely, rob.herring, devicetree-discuss, cjb, w.sang

The main changes of this new patch series are add dt binding
support in pinctrl core for pinmux mappings and shows an example
on using the standard API provided by pinctrl core to register
pinmux mappings from dts file.
Then we can remove the old board specifc pinmux mappings from
generic soc specific code (e.g. mach-imx6q.c).

Change v2->v3:
- change the name from of_get_child_number to of_get_child_count
- pinctrl: add dt binding support for pinmux mappings
- Add phandle for pinmux mappings for imx6q
- binding pinmux mappings via pinctrl core API
- follow the dt convention to use dash '-' for property name

Changes v1->v2:
- add a cover letter
- remove the pin functon and group defines out of driver
- parsing data from device tree for imx6q support
- a few minor fixes suggested by Shawn

Dong Aisheng (5):
  dt: add of_get_child_count helper function
  pinctrl: add dt binding support for pinmux mappings
  pinctrl: imx: add pinctrl imx driver
  ARM: imx6q: using pinmux subsystem
  mmc: sdhci-esdhc-imx: using pinmux subsystem

 .../devicetree/bindings/pinctrl/pinctrl-imx.txt    |   59 +++
 .../devicetree/bindings/pinctrl/pinctrl.txt        |   33 ++
 arch/arm/boot/dts/imx6q-sabreauto.dts              |   32 ++
 arch/arm/boot/dts/imx6q.dtsi                       |    1 +
 arch/arm/mach-imx/Kconfig                          |    1 +
 drivers/mmc/host/sdhci-esdhc-imx.c                 |   20 +
 drivers/pinctrl/Kconfig                            |   20 +
 drivers/pinctrl/Makefile                           |    3 +
 drivers/pinctrl/pinctrl-imx-core.c                 |  450 ++++++++++++++++++++
 drivers/pinctrl/pinctrl-imx-core.h                 |   86 ++++
 drivers/pinctrl/pinctrl-imx53.c                    |  443 +++++++++++++++++++
 drivers/pinctrl/pinctrl-imx6q.c                    |  433 +++++++++++++++++++
 drivers/pinctrl/pinmux.c                           |  101 +++++
 include/linux/of.h                                 |   16 +
 include/linux/pinctrl/machine.h                    |    6 +
 15 files changed, 1704 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl.txt
 create mode 100644 drivers/pinctrl/pinctrl-imx-core.c
 create mode 100644 drivers/pinctrl/pinctrl-imx-core.h
 create mode 100644 drivers/pinctrl/pinctrl-imx53.c
 create mode 100644 drivers/pinctrl/pinctrl-imx6q.c



^ permalink raw reply	[flat|nested] 98+ messages in thread

* [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
  2011-12-20 17:40 [RFC PATCH v3 0/5] pinctrl: imx: add pinnmux support Dong Aisheng
@ 2011-12-20 17:40 ` Dong Aisheng
  2011-12-20 18:35   ` Rob Herring
                     ` (2 more replies)
  2011-12-20 17:40 ` [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings Dong Aisheng
                   ` (3 subsequent siblings)
  4 siblings, 3 replies; 98+ messages in thread
From: Dong Aisheng @ 2011-12-20 17:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, linus.walleij, s.hauer, shawn.guo, kernel,
	grant.likely, rob.herring, devicetree-discuss, cjb, w.sang

From: Dong Aisheng <dong.aisheng@linaro.org>

Currently most code to get child count in kernel are almost same,
add a helper to implement this function for dt to use.

---
Changes v1->v2:
 * change the name from of_get_child_number to of_get_child_count

Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
---
 include/linux/of.h |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/include/linux/of.h b/include/linux/of.h
index 4948552..d0d91a1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -189,6 +189,17 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
 	for (child = of_get_next_child(parent, NULL); child != NULL; \
 	     child = of_get_next_child(parent, child))
 
+static inline int of_get_child_count(const struct device_node *np)
+{
+	struct device_node *child = NULL;
+	int num = 0;
+
+	while ((child = of_get_next_child(np, child)))
+		num++;
+
+	return num;
+}
+
 extern struct device_node *of_find_node_with_property(
 	struct device_node *from, const char *prop_name);
 #define for_each_node_with_property(dn, prop_name) \
@@ -262,6 +273,11 @@ static inline bool of_have_populated_dt(void)
 #define for_each_child_of_node(parent, child) \
 	while (0)
 
+static inline int of_get_child_count(const struct device_node *np)
+{
+	return -ENOSYS;
+}
+
 static inline int of_device_is_compatible(const struct device_node *device,
 					  const char *name)
 {
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-20 17:40 [RFC PATCH v3 0/5] pinctrl: imx: add pinnmux support Dong Aisheng
  2011-12-20 17:40 ` [RFC PATCH v3 1/5] dt: add of_get_child_count helper function Dong Aisheng
@ 2011-12-20 17:40 ` Dong Aisheng
  2011-12-20 19:48   ` Marek Vasut
                     ` (2 more replies)
  2011-12-20 17:40 ` [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver Dong Aisheng
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 98+ messages in thread
From: Dong Aisheng @ 2011-12-20 17:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, linus.walleij, s.hauer, shawn.guo, kernel,
	grant.likely, rob.herring, devicetree-discuss, cjb, w.sang

From: Dong Aisheng <dong.aisheng@linaro.org>

This patch provies a common API for driver to use to register pinmux
mappings from dts file. It is needed for dt support.

Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
---
 .../devicetree/bindings/pinctrl/pinctrl.txt        |   33 +++++++
 drivers/pinctrl/pinmux.c                           |  101 ++++++++++++++++++++
 include/linux/pinctrl/machine.h                    |    6 +
 3 files changed, 140 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
new file mode 100644
index 0000000..a27a7ce
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
@@ -0,0 +1,33 @@
+The pin control subsystem
+
+The pin control subsystem provides a common API to support parsing pinmux
+mappings data from device tree. Each board dts file should provide a device
+node of which all the child nodes are the corresponding pinmux mappings.
+
+The required properties for pinmux mapping are:
+- map-name: the name of this specific map entry
+- clk-dev-name: the name of the device controlling this specific mapping
+- funcion: a function in the driver to use for this mapping
+
+Optional properties:
+- group: a certain specific pin group to activate for the function
+- dev-name: the name of the device using this specific mapping
+- hog-on-boot: indicate wether hog the mappings(do not need to specify value)
+
+Examples:
+
+pinmux: imx6q-sabreauto-map {
+	map-sd4 {
+		map-name = "usdhc4";
+		ctrl-dev-name = "20e0000.iomuxc";
+		function = "sd4";
+		dev-name = "219c000.usdhc";
+	};
+	...
+};
+
+Then calling pinmux_of_register_mappings() with the device node of
+imx6q-sabreauto-map as parameter to register pinmux mappings from dts.
+
+Usually user can get this device node via a phandle in driver then call
+the function to register maps. Please refer to pinctrl-imx.txt for example.
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 432feb6..3ac3098 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -20,6 +20,7 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/of_device.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/sysfs.h>
@@ -410,6 +411,106 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps,
 	return 0;
 }
 
+static int __devinit pinmux_of_parse_mapping(struct device_node *np,
+					struct pinmux_map *maps, unsigned id)
+{
+	struct pinmux_map *map = &maps[id];
+	int ret = 0;
+
+	pr_debug("parse pinmux map %d\n", id + 1);
+
+	if (of_find_property(np, "map-name", NULL)) {
+		ret = of_property_read_string(np, "map-name", &map->name);
+		if (ret) {
+			pr_err("failed to get map-name");
+			return ret;
+		}
+	}
+
+	if (of_find_property(np, "ctrl-dev-name", NULL)) {
+		ret = of_property_read_string(np, "ctrl-dev-name",
+						&map->ctrl_dev_name);
+		if (ret) {
+			pr_err("failed to get ctrl-dev-name");
+			return ret;
+		}
+	}
+
+	if (of_find_property(np, "function", NULL)) {
+		ret = of_property_read_string(np, "function", &map->function);
+		if (ret) {
+			pr_err("failed to get function");
+			return ret;
+		}
+	}
+
+	if (of_find_property(np, "group", NULL)) {
+		ret = of_property_read_string(np, "group", &map->group);
+		if (ret) {
+			pr_err("failed to get group");
+			return ret;
+		}
+	}
+
+	if (of_find_property(np, "dev-name", NULL)) {
+		ret = of_property_read_string(np, "dev-name", &map->dev_name);
+		if (ret) {
+			pr_err("failed to get dev-name");
+			return ret;
+		}
+	}
+
+	if (of_find_property(np, "hog-on-boot", NULL))
+		map->hog_on_boot = true;
+
+	pr_debug("map-name: %s ctrl-dev-name: %s function: %s group: %s dev-name: %s hog-on-boot: %d\n",
+			map->name, map->ctrl_dev_name, map->function,
+			map->group, map->dev_name, map->hog_on_boot);
+
+	return 0;
+}
+
+/**
+ * pinmux_of_register_mappings() - parse and register pinmux mappings from dt
+ * &np: a device node containing pinmux map properties
+ *
+ * Like pinmux_register_mappings(), the memory of pinmux maps are owned by
+ * pinctrl core and can not be freed.
+ */
+int __devinit pinmux_of_register_mappings(struct device_node *np)
+{
+	struct pinmux_map *maps;
+	struct device_node *child = NULL;
+	int count, i;
+	int ret;
+
+	pr_debug("parse pinmux maps from device node %s\n", np->name);
+
+	if (!np)
+		return -EINVAL;
+
+	count = of_get_child_count(np);
+	if (!count) {
+		pr_err("no available pinmux maps found\n");
+		return -EINVAL;
+	}
+
+	maps = kzalloc(count * sizeof(struct pinmux_map), GFP_KERNEL);
+	if (!maps)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node(np, child) {
+		ret = pinmux_of_parse_mapping(child, maps, i++);
+		if (ret) {
+			pr_err("failed to parse pinmux map\n");
+			return ret;
+		}
+	}
+
+	return pinmux_register_mappings(maps, count);
+}
+
 /**
  * acquire_pins() - acquire all the pins for a certain funcion on a pinmux
  * @pctldev: the device to take the pins on
diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h
index ad430e0..74a695d 100644
--- a/include/linux/pinctrl/machine.h
+++ b/include/linux/pinctrl/machine.h
@@ -78,6 +78,7 @@ struct pinmux_map {
 extern int pinmux_register_mappings(struct pinmux_map const *map,
 				unsigned num_maps);
 
+extern int pinmux_of_register_mappings(struct device_node *np);
 #else
 
 static inline int pinmux_register_mappings(struct pinmux_map const *map,
@@ -86,5 +87,10 @@ static inline int pinmux_register_mappings(struct pinmux_map const *map,
 	return 0;
 }
 
+static inline int pinmux_of_register_mappings(struct device_node *np)
+{
+	return 0;
+}
+
 #endif /* !CONFIG_PINMUX */
 #endif
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2011-12-20 17:40 [RFC PATCH v3 0/5] pinctrl: imx: add pinnmux support Dong Aisheng
  2011-12-20 17:40 ` [RFC PATCH v3 1/5] dt: add of_get_child_count helper function Dong Aisheng
  2011-12-20 17:40 ` [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings Dong Aisheng
@ 2011-12-20 17:40 ` Dong Aisheng
  2011-12-20 19:50   ` Marek Vasut
                     ` (2 more replies)
  2011-12-20 17:40 ` [RFC PATCH v3 4/5] ARM: imx6q: using pinmux subsystem Dong Aisheng
  2011-12-20 17:40 ` [RFC PATCH v3 5/5] mmc: sdhci-esdhc-imx: " Dong Aisheng
  4 siblings, 3 replies; 98+ messages in thread
From: Dong Aisheng @ 2011-12-20 17:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, linus.walleij, s.hauer, shawn.guo, kernel,
	grant.likely, rob.herring, devicetree-discuss, cjb, w.sang

From: Dong Aisheng <dong.aisheng@linaro.org>

The driver contains the initial support for imx53 and
imx6q.

Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Shawn Guo <shanw.guo@freescale.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>

---
ChangeLog v2->v3:
- binding pinmux mappings via pinctrl core API
- follow the dt convention to use dash '-' for property name

ChangeLog v1->v2:
- add basic binding from device tree
---
 .../devicetree/bindings/pinctrl/pinctrl-imx.txt    |   59 +++
 drivers/pinctrl/Kconfig                            |   20 +
 drivers/pinctrl/Makefile                           |    3 +
 drivers/pinctrl/pinctrl-imx-core.c                 |  450 ++++++++++++++++++++
 drivers/pinctrl/pinctrl-imx-core.h                 |   86 ++++
 drivers/pinctrl/pinctrl-imx53.c                    |  443 +++++++++++++++++++
 drivers/pinctrl/pinctrl-imx6q.c                    |  433 +++++++++++++++++++
 7 files changed, 1494 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt
 create mode 100644 drivers/pinctrl/pinctrl-imx-core.c
 create mode 100644 drivers/pinctrl/pinctrl-imx-core.h
 create mode 100644 drivers/pinctrl/pinctrl-imx53.c
 create mode 100644 drivers/pinctrl/pinctrl-imx6q.c

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt
new file mode 100644
index 0000000..e45d745
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt
@@ -0,0 +1,59 @@
+* Freescale IOMUX Controller (IOMUXC) for i.MX
+
+The IOMUX Controller (IOMUXC), together with the IOMUX, enables the IC
+to share one PAD to several functional blocks. The sharing is done by
+multiplexing the PAD input/output signals. For each PAD there are up to
+8 muxing options (called ALT modes). Since different modules require
+different PAD settings (like pull up, keeper, etc) the IOMUXC controls
+also the PAD settings parameters.
+
+Required properties:
+- compatible : Should be "fsl,<chip>-iomuxc"
+- reg : Should contain IOMUXC registers location and length
+- fsl,pinmux-map: phandle of pinmux mappings. Refer to pinctrl.txt for
+  detailed format.
+- child nodes containing pinmux data
+  Each child node corresponds to a specific pinmux function and the required
+  properties of the pinmux function are:
+  - func-name: the name of a specific function
+  - grp-name: the name of a group pins correspding to this function
+  - grp-pins: the list of pins for the group of grp-name
+  - num-pins: the pins number of grp-pins list
+  - grp-mux: the corresponding mux mode list for grp-pins.
+    Each pin in the grp-pins should have a corresponding mux mode for the
+    specific function of func-name.
+  - num-numx: the mux number of grp-mux list
+
+Examples:
+
+pinmux: imx6q-sabreauto-map {
+	map-sd4 {
+		map-name = "usdhc4";
+		ctrl-dev-name = "20e0000.iomuxc";
+		function = "sd4";
+		dev-name = "219c000.usdhc";
+	};
+};
+
+iomuxc@020e0000 {
+	compatible = "fsl,imx6q-iomuxc";
+	reg = <0x020e0000 0x4000>;
+	fsl,pinmux-map = <&pinmux>;
+	pinmux_uart4 {
+		func-name = "uart4";
+		grp-name = "uart4grp";
+		grp-pins = <107 108>;
+		num-pins = <2>;
+		grp-mux = <4 4>;
+		num-mux = <2>;
+	};
+
+	pinmux_sd4 {
+		func-name = "sd4";
+		grp-name = "sd4grp";
+		grp-pins = <170 171 180 181 182 183 184 185 186 187>;
+		num-pins = <10>;
+		grp-mux = <0 0 1 1 1 1 1 1 1 1>;
+		num-mux = <10>;
+	};
+};
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index c63c721..f65bf5a 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -23,6 +23,26 @@ config DEBUG_PINCTRL
 	help
 	  Say Y here to add some extra checks and diagnostics to PINCTRL calls.
 
+config PINCTRL_IMX
+	bool "Freescale IMX core pinctrl driver"
+	depends on ARCH_MXC
+
+config PINCTRL_IMX53
+	bool "IMX53 pinctrl driver"
+	depends on SOC_IMX53
+	select PINMUX
+	select PINCTRL_IMX
+	help
+	  Say Y here to enable the imx53 pinctrl driver
+
+config PINCTRL_IMX6Q
+	bool "IMX6Q pinctrl driver"
+	depends on SOC_IMX6Q
+	select PINMUX
+	select PINCTRL_IMX
+	help
+	  Say Y here to enable the imx6q pinctrl driver
+
 config PINMUX_SIRF
 	bool "CSR SiRFprimaII pinmux driver"
 	depends on ARCH_PRIMA2
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index c046f78..cf85edc 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -5,6 +5,9 @@ ccflags-$(CONFIG_DEBUG_PINCTRL)	+= -DDEBUG
 obj-$(CONFIG_PINCTRL)		+= core.o
 obj-$(CONFIG_PINMUX)		+= pinmux.o
 obj-$(CONFIG_PINCONF)		+= pinconf.o
+obj-$(CONFIG_PINMUX_IMX)	+= pinmux-imx-core.o
+obj-$(CONFIG_PINMUX_IMX53)	+= pinmux-imx53.o
+obj-$(CONFIG_PINMUX_IMX6Q)	+= pinmux-imx6q.o
 obj-$(CONFIG_PINMUX_SIRF)	+= pinmux-sirf.o
 obj-$(CONFIG_PINMUX_U300)	+= pinmux-u300.o
 obj-$(CONFIG_PINCTRL_COH901)	+= pinctrl-coh901.o
diff --git a/drivers/pinctrl/pinctrl-imx-core.c b/drivers/pinctrl/pinctrl-imx-core.c
new file mode 100644
index 0000000..5c348ba
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-imx-core.c
@@ -0,0 +1,450 @@
+/*
+ * Core driver for the imx pin controller
+ *
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011 Linaro Ltd.
+ *
+ * Author: Dong Aisheng <dong.aisheng@linaro.org>
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/slab.h>
+
+#include "pinctrl-imx-core.h"
+
+#define DRIVER_NAME "pinmux-imx"
+
+/**
+ * @dev: a pointer back to containing device
+ * @virtbase: the offset to the controller in virtual memory
+ */
+struct imx_pmx {
+	struct device *dev;
+	struct pinctrl_dev *pctl;
+	void __iomem *virtbase;
+	struct imx_pinctrl_info *info;
+};
+
+#define IMX_PINCTRL_REG_SIZE 4
+#define IMX_PINCTRL_MAX_FUNC 7
+
+static int imx_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
+{
+	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
+	struct imx_pinctrl_info *info = ipmx->info;
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const char *imx_get_group_name(struct pinctrl_dev *pctldev,
+				       unsigned selector)
+{
+	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
+	struct imx_pinctrl_info *info = ipmx->info;
+
+	if (selector >= info->ngroups)
+		return NULL;
+
+	return info->groups[selector].name;
+}
+
+static int imx_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
+			       const unsigned **pins,
+			       unsigned *num_pins)
+{
+	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
+	struct imx_pinctrl_info *info = ipmx->info;
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	*pins = info->groups[selector].pins;
+	*num_pins = info->groups[selector].num_pins;
+
+	return 0;
+}
+
+static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+		   unsigned offset)
+{
+	seq_printf(s, " " DRIVER_NAME);
+}
+
+static struct pinctrl_ops imx_pctrl_ops = {
+	.list_groups = imx_list_groups,
+	.get_group_name = imx_get_group_name,
+	.get_group_pins = imx_get_group_pins,
+	.pin_dbg_show = imx_pin_dbg_show,
+};
+
+static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
+			   unsigned group)
+{
+	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
+	struct imx_pinctrl_info *info = ipmx->info;
+	const unsigned *pins, *mux;
+	unsigned int num_pins, num_mux;
+	u32 regval, offset;
+	int i;
+
+	/*
+	 * Configure the mux mode for each pin in the group for a specific
+	 * function.
+	 */
+	pins = info->groups[group].pins;
+	num_pins = info->groups[group].num_pins;
+	mux = info->groups[group].mux_mode;
+	num_mux = info->groups[group].num_mux;
+
+	dev_dbg(ipmx->dev, "function %s group %s\n",
+		info->functions[selector].name, info->groups[group].name);
+
+	if (num_pins != num_mux) {
+		dev_err(ipmx->dev, "num_mux is not equal to num_pins\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < num_pins; i++) {
+		if (mux[i] > IMX_PINCTRL_MAX_FUNC)
+			dev_err(ipmx->dev, "exceeds the maximum mux mode(0x7)\n");
+		offset = info->mux_offset + pins[i] * IMX_PINCTRL_REG_SIZE;
+		regval = readl(ipmx->virtbase + offset);
+		regval &= ~IMX_PINCTRL_MAX_FUNC;
+		writel(mux[i] | regval, ipmx->virtbase + offset);
+		dev_dbg(ipmx->dev, "write: offset 0x%x val 0x%x\n",
+			offset, regval | mux[i]);
+	}
+
+	return 0;
+}
+
+static void imx_pmx_disable(struct pinctrl_dev *pctldev, unsigned func_selector,
+			    unsigned group_selector)
+{
+	/* nothing to do here */
+}
+
+static int imx_pmx_list_funcs(struct pinctrl_dev *pctldev, unsigned selector)
+{
+	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
+	struct imx_pinctrl_info *info = ipmx->info;
+
+	if (selector >= info->nfunctions)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const char *imx_pmx_get_func_name(struct pinctrl_dev *pctldev,
+					  unsigned selector)
+{
+	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
+	struct imx_pinctrl_info *info = ipmx->info;
+
+	return info->functions[selector].name;
+}
+
+static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
+			       const char * const **groups,
+			       unsigned * const num_groups)
+{
+	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
+	struct imx_pinctrl_info *info = ipmx->info;
+
+	*groups = info->functions[selector].groups;
+	*num_groups = info->functions[selector].num_groups;
+
+	return 0;
+}
+
+static struct pinmux_ops imx_pmx_ops = {
+	.list_functions = imx_pmx_list_funcs,
+	.get_function_name = imx_pmx_get_func_name,
+	.get_function_groups = imx_pmx_get_groups,
+	.enable = imx_pmx_enable,
+	.disable = imx_pmx_disable,
+};
+
+static struct pinctrl_desc imx_pmx_desc = {
+	.name = DRIVER_NAME,
+	.pctlops = &imx_pctrl_ops,
+	.pmxops = &imx_pmx_ops,
+	.owner = THIS_MODULE,
+};
+
+#ifdef CONFIG_OF
+static int __devinit imx_pmx_parse_functions(struct device_node *np,
+			struct imx_pinctrl_info *info, u32 num)
+{
+	struct imx_pmx_func *function;
+	struct imx_pin_group *group;
+	int ret, len;
+
+	dev_dbg(info->dev, "parse function %d\n", num);
+
+	group = &info->groups[num];
+	function = &info->functions[num];
+
+	/* Initialise group */
+	ret = of_property_read_string(np, "grp-name", &group->name);
+	if (ret) {
+		dev_err(info->dev, "failed to get grp-name\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32(np, "num-pins", &group->num_pins);
+	if (ret) {
+		dev_err(info->dev, "failed to get num-pins\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32(np, "num-mux", &group->num_mux);
+	if (ret) {
+		dev_err(info->dev, "failed to get num-mux\n");
+		return ret;
+	}
+
+	if (group->num_pins != group->num_mux)
+		return -EINVAL;
+
+	group->pins = devm_kzalloc(info->dev, group->num_pins * sizeof(unsigned int),
+				GFP_KERNEL);
+	group->mux_mode = devm_kzalloc(info->dev, group->num_mux * sizeof(unsigned int),
+				GFP_KERNEL);
+	if (!group->pins || !group->mux_mode)
+		return -ENOMEM;
+
+	/* sanity check */
+	if (of_get_property(np, "grp-pins", &len) &&
+		len != group->num_pins * sizeof(unsigned int)) {
+		dev_err(info->dev, "wrong pins number?\n");
+		return -EINVAL;
+	}
+
+	if (of_get_property(np, "grp-mux", &len) &&
+		len != group->num_mux * sizeof(unsigned int)) {
+		dev_err(info->dev, "wrong pin mux number?\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_array(np, "grp-pins",
+			group->pins, group->num_pins);
+	if (ret) {
+		dev_err(info->dev, "failed to get grp-pins\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32_array(np, "grp-mux",
+			group->mux_mode, group->num_mux);
+	if (ret) {
+		dev_err(info->dev, "failed to get grp-mux\n");
+		return ret;
+	}
+
+	/* Initialise function */
+	ret = of_property_read_string(np, "func-name", &function->name);
+	if (ret) {
+		dev_err(info->dev, "failed to get func-name\n");
+		return ret;
+	}
+
+	function->groups = devm_kzalloc(info->dev, sizeof(char **), GFP_KERNEL);
+	function->num_groups = 1;
+	function->groups[0] = group->name;
+
+	dev_dbg(info->dev, "func-name %s grp-name %s num-groups %d\n",
+				function->name, function->groups[0],
+				function->num_groups);
+
+	return 0;
+}
+
+static int __devinit imx_pmx_probe_dt(struct platform_device *pdev,
+				struct imx_pinctrl_info *info)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *child = NULL;
+	struct device_node *map_np;
+	int ret, i;
+	u32 nfuncs = 0;
+
+	if (!np)
+		return -ENODEV;
+
+	nfuncs = of_get_child_count(np);
+	if (nfuncs <= 0) {
+		dev_err(&pdev->dev, "no functions defined\n");
+		return -EINVAL;
+	}
+
+	info->nfunctions = nfuncs;
+	info->functions = devm_kzalloc(&pdev->dev, nfuncs * sizeof(struct imx_pmx_func),
+					GFP_KERNEL);
+	if (!info->functions)
+		return -ENOMEM;
+
+	/* DT file only passes one group per one function */
+	info->ngroups = nfuncs;
+	info->groups = devm_kzalloc(&pdev->dev, nfuncs * sizeof(struct imx_pin_group),
+					GFP_KERNEL);
+	if (!info->groups)
+		return -ENOMEM;
+
+	child = NULL;
+	i = 0;
+	for_each_child_of_node(np, child) {
+		ret = imx_pmx_parse_functions(child, info, i++);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to parse function\n");
+			return ret;
+		}
+	}
+
+	/* parse pinmux map */
+	map_np = of_parse_phandle(np, "fsl,pinmux-map", 0);
+	if (!map_np) {
+		dev_err(&pdev->dev, "failed to parse phandle fsl,pinmux-map\n");
+		return -EINVAL;
+	}
+
+	ret = pinmux_of_register_mappings(map_np);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register pinmux mappings\n");
+		return ret;
+	}
+
+	return 0;
+}
+#else
+static int __devinit imx_pmx_probe_dt(struct platform_device *pdev,
+				struct imx_pinctrl_info *info)
+{
+	return -ENODEV;
+}
+#endif
+
+static inline void imx_pmx_desc_init(struct pinctrl_desc *pmx_desc,
+				const struct imx_pinctrl_info *info)
+{
+	pmx_desc->pins = info->pins;
+	pmx_desc->npins = info->npins;
+	pmx_desc->maxpin = info->maxpin;
+}
+
+static const struct of_device_id imx_pmx_dt_ids[] = {
+#ifdef CONFIG_PINMUX_IMX6Q
+	{ .compatible = "fsl,imx6q-iomuxc", .data = (void *) &imx6q_pinctrl_info, },
+#endif
+#ifdef CONFIG_PINMUX_IMX53
+	{ .compatible = "fsl,imx53-iomuxc", .data = (void *) &imx53_pinctrl_info, },
+#endif
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_pmx_dt_ids);
+
+static int __init imx_pmx_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *of_id =
+			of_match_device(imx_pmx_dt_ids, &pdev->dev);
+	struct device *dev = &pdev->dev;
+	struct imx_pmx *ipmx;
+	struct resource *res;
+	struct imx_pinctrl_info *info;
+	resource_size_t res_size;
+	int ret;
+
+	info = of_id->data;
+	if (!info || !info->pins || !(info->maxpin > info->npins)) {
+		dev_err(&pdev->dev, "wrong pinctrl info\n");
+		return -EINVAL;
+	}
+	info->dev = &pdev->dev;
+
+	/* Create state holders etc for this driver */
+	ipmx = devm_kzalloc(&pdev->dev, sizeof(*ipmx), GFP_KERNEL);
+	if (!ipmx)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENOENT;
+
+	res_size = resource_size(res);
+	if (!devm_request_mem_region(dev, res->start, res_size, res->name))
+		return -EBUSY;
+
+	ipmx->virtbase = devm_ioremap_nocache(dev, res->start, res_size);
+	if (!ipmx->virtbase)
+		return -EBUSY;
+
+	imx_pmx_desc_init(&imx_pmx_desc, info);
+	ret = imx_pmx_probe_dt(pdev, info);
+	if (ret) {
+		dev_err(&pdev->dev, "fail to probe dt properties\n");
+		return ret;
+	}
+
+	ipmx->pctl = pinctrl_register(&imx_pmx_desc, &pdev->dev, ipmx);
+	if (!ipmx->pctl) {
+		dev_err(&pdev->dev, "could not register IMX pinmux driver\n");
+		return -EINVAL;
+	}
+
+	ipmx->info = info;
+	ipmx->dev = info->dev;
+	platform_set_drvdata(pdev, ipmx);
+
+	dev_info(&pdev->dev, "initialized IMX pinmux driver\n");
+
+	return 0;
+}
+
+static int __exit imx_pmx_remove(struct platform_device *pdev)
+{
+	struct imx_pmx *ipmx = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(ipmx->pctl);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver imx_pmx_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = imx_pmx_dt_ids,
+	},
+	.remove = __exit_p(imx_pmx_remove),
+};
+
+static int __init imx_pmx_init(void)
+{
+	return platform_driver_probe(&imx_pmx_driver, imx_pmx_probe);
+}
+arch_initcall(imx_pmx_init);
+
+static void __exit imx_pmx_exit(void)
+{
+	platform_driver_unregister(&imx_pmx_driver);
+}
+module_exit(imx_pmx_exit);
+
+MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
+MODULE_DESCRIPTION("IMX Pin Control Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-imx-core.h b/drivers/pinctrl/pinctrl-imx-core.h
new file mode 100644
index 0000000..df69cd0
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-imx-core.h
@@ -0,0 +1,86 @@
+/*
+ * IMX pinmux core definitions
+ *
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011 Linaro Ltd.
+ *
+ * Author: Dong Aisheng <dong.aisheng@linaro.org>
+ *
+ * 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.
+ */
+
+#ifndef __DRIVERS_PINCTRL_PINMUX_IMX_H
+#define __DRIVERS_PINCTRL_PINMUX_IMX_H
+
+/* Supported Pinctrl type */
+enum imx_pinctrl_type {
+	IMX53_PINCTRL,
+	IMX6Q_PINCTRL,
+};
+
+/**
+ * struct imx_pin_group - describes an IMX pin group
+ * @name: the name of this specific pin group
+ * @pins: an array of discrete physical pins used in this group, taken
+ *	from the driver-local pin enumeration space
+ * @num_pins: the number of pins in this group array, i.e. the number of
+ *	elements in .pins so we can iterate over that array
+ * @mux_mode: the mux mode for each pins in this group. The size of this
+ *	array is the same as pins.
+ */
+struct imx_pin_group {
+	const char *name;
+	unsigned int *pins;
+	unsigned num_pins;
+	unsigned int *mux_mode;
+	unsigned num_mux;
+};
+
+/**
+ * struct imx_pmx_func - describes IMX pinmux functions
+ * @name: the name of this specific function
+ * @groups: corresponding pin groups
+ */
+struct imx_pmx_func {
+	const char *name;
+	const char **groups;
+	unsigned num_groups;
+};
+
+struct imx_pinctrl_info {
+	struct device *dev;
+	u32 type;
+	const struct pinctrl_pin_desc *pins;
+	unsigned int npins;
+	unsigned int maxpin;
+	struct imx_pin_group *groups;
+	unsigned int ngroups;
+	struct imx_pmx_func *functions;
+	unsigned int nfunctions;
+	u32 mux_offset;
+};
+
+#define IMX_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin)
+
+#define IMX_PIN_GROUP(n, p, m)  \
+	{			\
+		.name = n,	\
+		.pins = p,	\
+		.num_pins = ARRAY_SIZE(p),	\
+		.mux_mode = m,	\
+		.num_mux = ARRAY_SIZE(m),	\
+	}
+
+#define IMX_PMX_FUNC(n, g)  \
+	{			\
+		.name = n,	\
+		.groups = g,	\
+		.num_groups = ARRAY_SIZE(g),	\
+	}
+
+extern struct imx_pinctrl_info imx53_pinctrl_info;
+extern struct imx_pinctrl_info imx6q_pinctrl_info;
+#endif /* __DRIVERS_PINCTRL_PINMUX_IMX_H */
diff --git a/drivers/pinctrl/pinctrl-imx53.c b/drivers/pinctrl/pinctrl-imx53.c
new file mode 100644
index 0000000..079b25e
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-imx53.c
@@ -0,0 +1,443 @@
+/*
+ * imx53 pinctrl driver based on imx pinmux core
+ *
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011 Linaro, Inc.
+ *
+ * Author: Dong Aisheng <dong.aisheng@linaro.org>
+ *
+ * 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/init.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-imx-core.h"
+
+#define IMX53_IOMUXC_MUX_OFFSET 0x20
+#define IMX53_IOMUXC_MAXPIN	(23*23)
+
+enum imx_imx53_pinctrl_pads {
+	MX53_GPIO_19 = 0,
+	MX53_KEY_COL0 = 1,
+	MX53_KEY_ROW0 = 2,
+	MX53_KEY_COL1 = 3,
+	MX53_KEY_ROW1 = 4,
+	MX53_KEY_COL2 = 5,
+	MX53_KEY_ROW2 = 6,
+	MX53_KEY_COL3 = 7,
+	MX53_KEY_ROW3 = 8,
+	MX53_KEY_COL4 = 9,
+	MX53_KEY_ROW4 = 10,
+	MX53_DI0_DISP_CLK = 11,
+	MX53_DI0_PIN15 = 12,
+	MX53_DI0_PIN2 = 13,
+	MX53_DI0_PIN3 = 14,
+	MX53_DI0_PIN4 = 15,
+	MX53_DISP0_DAT0 = 16,
+	MX53_DISP0_DAT1 = 17,
+	MX53_DISP0_DAT2 = 18,
+	MX53_DISP0_DAT3 = 19,
+	MX53_DISP0_DAT4 = 20,
+	MX53_DISP0_DAT5 = 21,
+	MX53_DISP0_DAT6 = 22,
+	MX53_DISP0_DAT7 = 23,
+	MX53_DISP0_DAT8 = 24,
+	MX53_DISP0_DAT9 = 25,
+	MX53_DISP0_DAT10 = 26,
+	MX53_DISP0_DAT11 = 27,
+	MX53_DISP0_DAT12 = 28,
+	MX53_DISP0_DAT13 = 29,
+	MX53_DISP0_DAT14 = 30,
+	MX53_DISP0_DAT15 = 31,
+	MX53_DISP0_DAT16 = 32,
+	MX53_DISP0_DAT17 = 33,
+	MX53_DISP0_DAT18 = 34,
+	MX53_DISP0_DAT19 = 35,
+	MX53_DISP0_DAT20 = 36,
+	MX53_DISP0_DAT21 = 37,
+	MX53_DISP0_DAT22 = 38,
+	MX53_DISP0_DAT23 = 39,
+	MX53_CSI0_PIXCLK = 40,
+	MX53_CSI0_MCLK = 41,
+	MX53_CSI0_DATA_EN = 42,
+	MX53_CSI0_VSYNC = 43,
+	MX53_CSI0_DAT4 = 44,
+	MX53_CSI0_DAT5 = 45,
+	MX53_CSI0_DAT6 = 46,
+	MX53_CSI0_DAT7 = 47,
+	MX53_CSI0_DAT8 = 48,
+	MX53_CSI0_DAT9 = 49,
+	MX53_CSI0_DAT10 = 50,
+	MX53_CSI0_DAT11 = 51,
+	MX53_CSI0_DAT12 = 52,
+	MX53_CSI0_DAT13 = 53,
+	MX53_CSI0_DAT14 = 54,
+	MX53_CSI0_DAT15 = 55,
+	MX53_CSI0_DAT16 = 56,
+	MX53_CSI0_DAT17 = 57,
+	MX53_CSI0_DAT18 = 58,
+	MX53_CSI0_DAT19 = 59,
+	MX53_EIM_A25 = 60,
+	MX53_EIM_EB2 = 61,
+	MX53_EIM_D16 = 62,
+	MX53_EIM_D17 = 63,
+	MX53_EIM_D18 = 64,
+	MX53_EIM_D19 = 65,
+	MX53_EIM_D20 = 66,
+	MX53_EIM_D21 = 67,
+	MX53_EIM_D22 = 68,
+	MX53_EIM_D23 = 69,
+	MX53_EIM_EB3 = 70,
+	MX53_EIM_D24 = 71,
+	MX53_EIM_D25 = 72,
+	MX53_EIM_D26 = 73,
+	MX53_EIM_D27 = 74,
+	MX53_EIM_D28 = 75,
+	MX53_EIM_D29 = 76,
+	MX53_EIM_D30 = 77,
+	MX53_EIM_D31 = 78,
+	MX53_EIM_A24 = 79,
+	MX53_EIM_A23 = 80,
+	MX53_EIM_A22 = 81,
+	MX53_EIM_A21 = 82,
+	MX53_EIM_A20 = 83,
+	MX53_EIM_A19 = 84,
+	MX53_EIM_A18 = 85,
+	MX53_EIM_A17 = 86,
+	MX53_EIM_A16 = 87,
+	MX53_EIM_CS0 = 88,
+	MX53_EIM_CS1 = 89,
+	MX53_EIM_OE = 90,
+	MX53_EIM_RW = 91,
+	MX53_EIM_LBA = 92,
+	MX53_EIM_EB0 = 93,
+	MX53_EIM_EB1 = 94,
+	MX53_EIM_DA0 = 95,
+	MX53_EIM_DA1 = 96,
+	MX53_EIM_DA2 = 97,
+	MX53_EIM_DA3 = 98,
+	MX53_EIM_DA4 = 99,
+	MX53_EIM_DA5 = 100,
+	MX53_EIM_DA6 = 101,
+	MX53_EIM_DA7 = 102,
+	MX53_EIM_DA8 = 103,
+	MX53_EIM_DA9 = 104,
+	MX53_EIM_DA10 = 105,
+	MX53_EIM_DA11 = 106,
+	MX53_EIM_DA12 = 107,
+	MX53_EIM_DA13 = 108,
+	MX53_EIM_DA14 = 109,
+	MX53_EIM_DA15 = 110,
+	MX53_NANDF_WE_B = 111,
+	MX53_NANDF_RE_B = 112,
+	MX53_EIM_WAIT = 113,
+	MX53_EIM_BCLK = 114,
+	MX53_LVDS1_TX3_P = 115,
+	MX53_LVDS1_TX2_P = 116,
+	MX53_LVDS1_CLK_P = 117,
+	MX53_LVDS1_TX1_P = 118,
+	MX53_LVDS1_TX0_P = 119,
+	MX53_LVDS0_TX3_P = 120,
+	MX53_LVDS0_CLK_P = 121,
+	MX53_LVDS0_TX2_P = 122,
+	MX53_LVDS0_TX1_P = 123,
+	MX53_LVDS0_TX0_P = 124,
+	MX53_GPIO_10 = 125,
+	MX53_GPIO_11 = 126,
+	MX53_GPIO_12 = 127,
+	MX53_GPIO_13 = 128,
+	MX53_GPIO_14 = 129,
+	MX53_NANDF_CLE = 130,
+	MX53_NANDF_ALE = 131,
+	MX53_NANDF_WP_B = 132,
+	MX53_NANDF_RB0 = 133,
+	MX53_NANDF_CS0 = 134,
+	MX53_NANDF_CS1 = 135,
+	MX53_NANDF_CS2 = 136,
+	MX53_NANDF_CS3 = 137,
+	MX53_FEC_MDIO = 138,
+	MX53_FEC_REF_CLK = 139,
+	MX53_FEC_RX_ER = 140,
+	MX53_FEC_CRS_DV = 141,
+	MX53_FEC_RXD1 = 142,
+	MX53_FEC_RXD0 = 143,
+	MX53_FEC_TX_EN = 144,
+	MX53_FEC_TXD1 = 145,
+	MX53_FEC_TXD0 = 146,
+	MX53_FEC_MDC = 147,
+	MX53_PATA_DIOW = 148,
+	MX53_PATA_DMACK = 149,
+	MX53_PATA_DMARQ = 150,
+	MX53_PATA_BUFFER_EN = 151,
+	MX53_PATA_INTRQ = 152,
+	MX53_PATA_DIOR = 153,
+	MX53_PATA_RESET_B = 154,
+	MX53_PATA_IORDY = 155,
+	MX53_PATA_DA_0 = 156,
+	MX53_PATA_DA_1 = 157,
+	MX53_PATA_DA_2 = 158,
+	MX53_PATA_CS_0 = 159,
+	MX53_PATA_CS_1 = 160,
+	MX53_PATA_DATA0 = 161,
+	MX53_PATA_DATA1 = 162,
+	MX53_PATA_DATA2 = 163,
+	MX53_PATA_DATA3 = 164,
+	MX53_PATA_DATA4 = 165,
+	MX53_PATA_DATA5 = 166,
+	MX53_PATA_DATA6 = 167,
+	MX53_PATA_DATA7 = 168,
+	MX53_PATA_DATA8 = 169,
+	MX53_PATA_DATA9 = 170,
+	MX53_PATA_DATA10 = 171,
+	MX53_PATA_DATA11 = 172,
+	MX53_PATA_DATA12 = 173,
+	MX53_PATA_DATA13 = 174,
+	MX53_PATA_DATA14 = 175,
+	MX53_PATA_DATA15 = 176,
+	MX53_SD1_DATA0 = 177,
+	MX53_SD1_DATA1 = 178,
+	MX53_SD1_CMD = 179,
+	MX53_SD1_DATA2 = 180,
+	MX53_SD1_CLK = 181,
+	MX53_SD1_DATA3 = 182,
+	MX53_SD2_CLK = 183,
+	MX53_SD2_CMD = 184,
+	MX53_SD2_DATA3 = 185,
+	MX53_SD2_DATA2 = 186,
+	MX53_SD2_DATA1 = 187,
+	MX53_SD2_DATA0 = 188,
+	MX53_GPIO_0 = 189,
+	MX53_GPIO_1 = 190,
+	MX53_GPIO_9 = 191,
+	MX53_GPIO_3 = 192,
+	MX53_GPIO_6 = 193,
+	MX53_GPIO_2 = 194,
+	MX53_GPIO_4 = 195,
+	MX53_GPIO_5 = 196,
+	MX53_GPIO_7 = 197,
+	MX53_GPIO_8 = 198,
+	MX53_GPIO_16 = 199,
+	MX53_GPIO_17 = 200,
+	MX53_GPIO_18 = 201,
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx53_pinctrl_pads[] = {
+	IMX_PINCTRL_PIN(MX53_GPIO_19),
+	IMX_PINCTRL_PIN(MX53_KEY_COL0),
+	IMX_PINCTRL_PIN(MX53_KEY_ROW0),
+	IMX_PINCTRL_PIN(MX53_KEY_COL1),
+	IMX_PINCTRL_PIN(MX53_KEY_ROW1),
+	IMX_PINCTRL_PIN(MX53_KEY_COL2),
+	IMX_PINCTRL_PIN(MX53_KEY_ROW2),
+	IMX_PINCTRL_PIN(MX53_KEY_COL3),
+	IMX_PINCTRL_PIN(MX53_KEY_ROW3),
+	IMX_PINCTRL_PIN(MX53_KEY_COL4),
+	IMX_PINCTRL_PIN(MX53_KEY_ROW4),
+	IMX_PINCTRL_PIN(MX53_DI0_DISP_CLK),
+	IMX_PINCTRL_PIN(MX53_DI0_PIN15),
+	IMX_PINCTRL_PIN(MX53_DI0_PIN2),
+	IMX_PINCTRL_PIN(MX53_DI0_PIN3),
+	IMX_PINCTRL_PIN(MX53_DI0_PIN4),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT0),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT1),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT2),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT3),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT4),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT5),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT6),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT7),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT8),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT9),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT10),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT11),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT12),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT13),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT14),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT15),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT16),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT17),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT18),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT19),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT20),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT21),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT22),
+	IMX_PINCTRL_PIN(MX53_DISP0_DAT23),
+	IMX_PINCTRL_PIN(MX53_CSI0_PIXCLK),
+	IMX_PINCTRL_PIN(MX53_CSI0_MCLK),
+	IMX_PINCTRL_PIN(MX53_CSI0_DATA_EN),
+	IMX_PINCTRL_PIN(MX53_CSI0_VSYNC),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT4),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT5),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT6),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT7),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT8),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT9),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT10),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT11),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT12),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT13),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT14),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT15),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT16),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT17),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT18),
+	IMX_PINCTRL_PIN(MX53_CSI0_DAT19),
+	IMX_PINCTRL_PIN(MX53_EIM_A25),
+	IMX_PINCTRL_PIN(MX53_EIM_EB2),
+	IMX_PINCTRL_PIN(MX53_EIM_D16),
+	IMX_PINCTRL_PIN(MX53_EIM_D17),
+	IMX_PINCTRL_PIN(MX53_EIM_D18),
+	IMX_PINCTRL_PIN(MX53_EIM_D19),
+	IMX_PINCTRL_PIN(MX53_EIM_D20),
+	IMX_PINCTRL_PIN(MX53_EIM_D21),
+	IMX_PINCTRL_PIN(MX53_EIM_D22),
+	IMX_PINCTRL_PIN(MX53_EIM_D23),
+	IMX_PINCTRL_PIN(MX53_EIM_EB3),
+	IMX_PINCTRL_PIN(MX53_EIM_D24),
+	IMX_PINCTRL_PIN(MX53_EIM_D25),
+	IMX_PINCTRL_PIN(MX53_EIM_D26),
+	IMX_PINCTRL_PIN(MX53_EIM_D27),
+	IMX_PINCTRL_PIN(MX53_EIM_D28),
+	IMX_PINCTRL_PIN(MX53_EIM_D29),
+	IMX_PINCTRL_PIN(MX53_EIM_D30),
+	IMX_PINCTRL_PIN(MX53_EIM_D31),
+	IMX_PINCTRL_PIN(MX53_EIM_A24),
+	IMX_PINCTRL_PIN(MX53_EIM_A23),
+	IMX_PINCTRL_PIN(MX53_EIM_A22),
+	IMX_PINCTRL_PIN(MX53_EIM_A21),
+	IMX_PINCTRL_PIN(MX53_EIM_A20),
+	IMX_PINCTRL_PIN(MX53_EIM_A19),
+	IMX_PINCTRL_PIN(MX53_EIM_A18),
+	IMX_PINCTRL_PIN(MX53_EIM_A17),
+	IMX_PINCTRL_PIN(MX53_EIM_A16),
+	IMX_PINCTRL_PIN(MX53_EIM_CS0),
+	IMX_PINCTRL_PIN(MX53_EIM_CS1),
+	IMX_PINCTRL_PIN(MX53_EIM_OE),
+	IMX_PINCTRL_PIN(MX53_EIM_RW),
+	IMX_PINCTRL_PIN(MX53_EIM_LBA),
+	IMX_PINCTRL_PIN(MX53_EIM_EB0),
+	IMX_PINCTRL_PIN(MX53_EIM_EB1),
+	IMX_PINCTRL_PIN(MX53_EIM_DA0),
+	IMX_PINCTRL_PIN(MX53_EIM_DA1),
+	IMX_PINCTRL_PIN(MX53_EIM_DA2),
+	IMX_PINCTRL_PIN(MX53_EIM_DA3),
+	IMX_PINCTRL_PIN(MX53_EIM_DA4),
+	IMX_PINCTRL_PIN(MX53_EIM_DA5),
+	IMX_PINCTRL_PIN(MX53_EIM_DA6),
+	IMX_PINCTRL_PIN(MX53_EIM_DA7),
+	IMX_PINCTRL_PIN(MX53_EIM_DA8),
+	IMX_PINCTRL_PIN(MX53_EIM_DA9),
+	IMX_PINCTRL_PIN(MX53_EIM_DA10),
+	IMX_PINCTRL_PIN(MX53_EIM_DA11),
+	IMX_PINCTRL_PIN(MX53_EIM_DA12),
+	IMX_PINCTRL_PIN(MX53_EIM_DA13),
+	IMX_PINCTRL_PIN(MX53_EIM_DA14),
+	IMX_PINCTRL_PIN(MX53_EIM_DA15),
+	IMX_PINCTRL_PIN(MX53_NANDF_WE_B),
+	IMX_PINCTRL_PIN(MX53_NANDF_RE_B),
+	IMX_PINCTRL_PIN(MX53_EIM_WAIT),
+	IMX_PINCTRL_PIN(MX53_EIM_BCLK),
+	IMX_PINCTRL_PIN(MX53_LVDS1_TX3_P),
+	IMX_PINCTRL_PIN(MX53_LVDS1_TX2_P),
+	IMX_PINCTRL_PIN(MX53_LVDS1_CLK_P),
+	IMX_PINCTRL_PIN(MX53_LVDS1_TX1_P),
+	IMX_PINCTRL_PIN(MX53_LVDS1_TX0_P),
+	IMX_PINCTRL_PIN(MX53_LVDS0_TX3_P),
+	IMX_PINCTRL_PIN(MX53_LVDS0_CLK_P),
+	IMX_PINCTRL_PIN(MX53_LVDS0_TX2_P),
+	IMX_PINCTRL_PIN(MX53_LVDS0_TX1_P),
+	IMX_PINCTRL_PIN(MX53_LVDS0_TX0_P),
+	IMX_PINCTRL_PIN(MX53_GPIO_10),
+	IMX_PINCTRL_PIN(MX53_GPIO_11),
+	IMX_PINCTRL_PIN(MX53_GPIO_12),
+	IMX_PINCTRL_PIN(MX53_GPIO_13),
+	IMX_PINCTRL_PIN(MX53_GPIO_14),
+	IMX_PINCTRL_PIN(MX53_NANDF_CLE),
+	IMX_PINCTRL_PIN(MX53_NANDF_ALE),
+	IMX_PINCTRL_PIN(MX53_NANDF_WP_B),
+	IMX_PINCTRL_PIN(MX53_NANDF_RB0),
+	IMX_PINCTRL_PIN(MX53_NANDF_CS0),
+	IMX_PINCTRL_PIN(MX53_NANDF_CS1),
+	IMX_PINCTRL_PIN(MX53_NANDF_CS2),
+	IMX_PINCTRL_PIN(MX53_NANDF_CS3),
+	IMX_PINCTRL_PIN(MX53_FEC_MDIO),
+	IMX_PINCTRL_PIN(MX53_FEC_REF_CLK),
+	IMX_PINCTRL_PIN(MX53_FEC_RX_ER),
+	IMX_PINCTRL_PIN(MX53_FEC_CRS_DV),
+	IMX_PINCTRL_PIN(MX53_FEC_RXD1),
+	IMX_PINCTRL_PIN(MX53_FEC_RXD0),
+	IMX_PINCTRL_PIN(MX53_FEC_TX_EN),
+	IMX_PINCTRL_PIN(MX53_FEC_TXD1),
+	IMX_PINCTRL_PIN(MX53_FEC_TXD0),
+	IMX_PINCTRL_PIN(MX53_FEC_MDC),
+	IMX_PINCTRL_PIN(MX53_PATA_DIOW),
+	IMX_PINCTRL_PIN(MX53_PATA_DMACK),
+	IMX_PINCTRL_PIN(MX53_PATA_DMARQ),
+	IMX_PINCTRL_PIN(MX53_PATA_BUFFER_EN),
+	IMX_PINCTRL_PIN(MX53_PATA_INTRQ),
+	IMX_PINCTRL_PIN(MX53_PATA_DIOR),
+	IMX_PINCTRL_PIN(MX53_PATA_RESET_B),
+	IMX_PINCTRL_PIN(MX53_PATA_IORDY),
+	IMX_PINCTRL_PIN(MX53_PATA_DA_0),
+	IMX_PINCTRL_PIN(MX53_PATA_DA_1),
+	IMX_PINCTRL_PIN(MX53_PATA_DA_2),
+	IMX_PINCTRL_PIN(MX53_PATA_CS_0),
+	IMX_PINCTRL_PIN(MX53_PATA_CS_1),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA0),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA1),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA2),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA3),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA4),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA5),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA6),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA7),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA8),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA9),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA10),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA11),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA12),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA13),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA14),
+	IMX_PINCTRL_PIN(MX53_PATA_DATA15),
+	IMX_PINCTRL_PIN(MX53_SD1_DATA0),
+	IMX_PINCTRL_PIN(MX53_SD1_DATA1),
+	IMX_PINCTRL_PIN(MX53_SD1_CMD),
+	IMX_PINCTRL_PIN(MX53_SD1_DATA2),
+	IMX_PINCTRL_PIN(MX53_SD1_CLK),
+	IMX_PINCTRL_PIN(MX53_SD1_DATA3),
+	IMX_PINCTRL_PIN(MX53_SD2_CLK),
+	IMX_PINCTRL_PIN(MX53_SD2_CMD),
+	IMX_PINCTRL_PIN(MX53_SD2_DATA3),
+	IMX_PINCTRL_PIN(MX53_SD2_DATA2),
+	IMX_PINCTRL_PIN(MX53_SD2_DATA1),
+	IMX_PINCTRL_PIN(MX53_SD2_DATA0),
+	IMX_PINCTRL_PIN(MX53_GPIO_0),
+	IMX_PINCTRL_PIN(MX53_GPIO_1),
+	IMX_PINCTRL_PIN(MX53_GPIO_9),
+	IMX_PINCTRL_PIN(MX53_GPIO_3),
+	IMX_PINCTRL_PIN(MX53_GPIO_6),
+	IMX_PINCTRL_PIN(MX53_GPIO_2),
+	IMX_PINCTRL_PIN(MX53_GPIO_4),
+	IMX_PINCTRL_PIN(MX53_GPIO_5),
+	IMX_PINCTRL_PIN(MX53_GPIO_7),
+	IMX_PINCTRL_PIN(MX53_GPIO_8),
+	IMX_PINCTRL_PIN(MX53_GPIO_16),
+	IMX_PINCTRL_PIN(MX53_GPIO_17),
+	IMX_PINCTRL_PIN(MX53_GPIO_18),
+};
+
+struct imx_pinctrl_info imx53_pinctrl_info = {
+	.type = IMX53_PINCTRL,
+	.pins = imx53_pinctrl_pads,
+	.npins = ARRAY_SIZE(imx53_pinctrl_pads),
+	.maxpin = IMX53_IOMUXC_MAXPIN,
+	.mux_offset = IMX53_IOMUXC_MUX_OFFSET,
+};
diff --git a/drivers/pinctrl/pinctrl-imx6q.c b/drivers/pinctrl/pinctrl-imx6q.c
new file mode 100644
index 0000000..4c0e29f
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-imx6q.c
@@ -0,0 +1,433 @@
+/*
+ * imx6q pinctrl driver based on imx pinmux core
+ *
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011 Linaro, Inc.
+ *
+ * Author: Dong Aisheng <dong.aisheng@linaro.org>
+ *
+ * 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/init.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-imx-core.h"
+
+#define IMX6Q_IOMUXC_MUX_OFSSET	0x4c
+#define IMX6Q_IOMUXC_MAXPIN	(25*25)
+
+enum imx6q_pads {
+	MX6Q_SD2_DAT1 = 0,
+	MX6Q_SD2_DAT2 = 1,
+	MX6Q_SD2_DAT0 = 2,
+	MX6Q_RGMII_TXC = 3,
+	MX6Q_RGMII_TD0 = 4,
+	MX6Q_RGMII_TD1 = 5,
+	MX6Q_RGMII_TD2 = 6,
+	MX6Q_RGMII_TD3 = 7,
+	MX6Q_RGMII_RX_CTL = 8,
+	MX6Q_RGMII_RD0 = 9,
+	MX6Q_RGMII_TX_CTL = 10,
+	MX6Q_RGMII_RD1 = 11,
+	MX6Q_RGMII_RD2 = 12,
+	MX6Q_RGMII_RD3 = 13,
+	MX6Q_RGMII_RXC = 14,
+	MX6Q_EIM_A25 = 15,
+	MX6Q_EIM_EB2 = 16,
+	MX6Q_EIM_D16 = 17,
+	MX6Q_EIM_D17 = 18,
+	MX6Q_EIM_D18 = 19,
+	MX6Q_EIM_D19 = 20,
+	MX6Q_EIM_D20 = 21,
+	MX6Q_EIM_D21 = 22,
+	MX6Q_EIM_D22 = 23,
+	MX6Q_EIM_D23 = 24,
+	MX6Q_EIM_EB3 = 25,
+	MX6Q_EIM_D24 = 26,
+	MX6Q_EIM_D25 = 27,
+	MX6Q_EIM_D26 = 28,
+	MX6Q_EIM_D27 = 29,
+	MX6Q_EIM_D28 = 30,
+	MX6Q_EIM_D29 = 31,
+	MX6Q_EIM_D30 = 32,
+	MX6Q_EIM_D31 = 33,
+	MX6Q_EIM_A24 = 34,
+	MX6Q_EIM_A23 = 35,
+	MX6Q_EIM_A22 = 36,
+	MX6Q_EIM_A21 = 37,
+	MX6Q_EIM_A20 = 38,
+	MX6Q_EIM_A19 = 39,
+	MX6Q_EIM_A18 = 40,
+	MX6Q_EIM_A17 = 41,
+	MX6Q_EIM_A16 = 42,
+	MX6Q_EIM_CS0 = 43,
+	MX6Q_EIM_CS1 = 44,
+	MX6Q_EIM_OE = 45,
+	MX6Q_EIM_RW = 46,
+	MX6Q_EIM_LBA = 47,
+	MX6Q_EIM_EB0 = 48,
+	MX6Q_EIM_EB1 = 49,
+	MX6Q_EIM_DA0 = 50,
+	MX6Q_EIM_DA1 = 51,
+	MX6Q_EIM_DA2 = 52,
+	MX6Q_EIM_DA3 = 53,
+	MX6Q_EIM_DA4 = 54,
+	MX6Q_EIM_DA5 = 55,
+	MX6Q_EIM_DA6 = 56,
+	MX6Q_EIM_DA7 = 57,
+	MX6Q_EIM_DA8 = 58,
+	MX6Q_EIM_DA9 = 59,
+	MX6Q_EIM_DA10 = 60,
+	MX6Q_EIM_DA11 = 61,
+	MX6Q_EIM_DA12 = 62,
+	MX6Q_EIM_DA13 = 63,
+	MX6Q_EIM_DA14 = 64,
+	MX6Q_EIM_DA15 = 65,
+	MX6Q_EIM_WAIT = 66,
+	MX6Q_EIM_BCLK = 67,
+	MX6Q_DI0_DISP_CLK = 68,
+	MX6Q_DI0_PIN15 = 69,
+	MX6Q_DI0_PIN2 = 70,
+	MX6Q_DI0_PIN3 = 71,
+	MX6Q_DI0_PIN4 = 72,
+	MX6Q_DISP0_DAT0 = 73,
+	MX6Q_DISP0_DAT1 = 74,
+	MX6Q_DISP0_DAT2 = 75,
+	MX6Q_DISP0_DAT3 = 76,
+	MX6Q_DISP0_DAT4 = 77,
+	MX6Q_DISP0_DAT5 = 78,
+	MX6Q_DISP0_DAT6 = 79,
+	MX6Q_DISP0_DAT7 = 80,
+	MX6Q_DISP0_DAT8 = 81,
+	MX6Q_DISP0_DAT9 = 82,
+	MX6Q_DISP0_DAT10 = 83,
+	MX6Q_DISP0_DAT11 = 84,
+	MX6Q_DISP0_DAT12 = 85,
+	MX6Q_DISP0_DAT13 = 86,
+	MX6Q_DISP0_DAT14 = 87,
+	MX6Q_DISP0_DAT15 = 88,
+	MX6Q_DISP0_DAT16 = 89,
+	MX6Q_DISP0_DAT17 = 90,
+	MX6Q_DISP0_DAT18 = 91,
+	MX6Q_DISP0_DAT19 = 92,
+	MX6Q_DISP0_DAT20 = 93,
+	MX6Q_DISP0_DAT21 = 94,
+	MX6Q_DISP0_DAT22 = 95,
+	MX6Q_DISP0_DAT23 = 96,
+	MX6Q_ENET_MDIO = 97,
+	MX6Q_ENET_REF_CLK = 98,
+	MX6Q_ENET_RX_ER = 99,
+	MX6Q_ENET_CRS_DV = 100,
+	MX6Q_ENET_RXD1 = 101,
+	MX6Q_ENET_RXD0 = 102,
+	MX6Q_ENET_TX_EN = 103,
+	MX6Q_ENET_TXD1 = 104,
+	MX6Q_ENET_TXD0 = 105,
+	MX6Q_ENET_MDC = 106,
+	MX6Q_KEY_COL0 = 107,
+	MX6Q_KEY_ROW0 = 108,
+	MX6Q_KEY_COL1 = 109,
+	MX6Q_KEY_ROW1 = 110,
+	MX6Q_KEY_COL2 = 111,
+	MX6Q_KEY_ROW2 = 112,
+	MX6Q_KEY_COL3 = 113,
+	MX6Q_KEY_ROW3 = 114,
+	MX6Q_KEY_COL4 = 115,
+	MX6Q_KEY_ROW4 = 116,
+	MX6Q_GPIO_0 = 117,
+	MX6Q_GPIO_1 = 118,
+	MX6Q_GPIO_9 = 119,
+	MX6Q_GPIO_3 = 120,
+	MX6Q_GPIO_6 = 121,
+	MX6Q_GPIO_2 = 122,
+	MX6Q_GPIO_4 = 123,
+	MX6Q_GPIO_5 = 124,
+	MX6Q_GPIO_7 = 125,
+	MX6Q_GPIO_8 = 126,
+	MX6Q_GPIO_16 = 127,
+	MX6Q_GPIO_17 = 128,
+	MX6Q_GPIO_18 = 129,
+	MX6Q_GPIO_19 = 130,
+	MX6Q_CSI0_PIXCLK = 131,
+	MX6Q_CSI0_MCLK = 132,
+	MX6Q_CSI0_DATA_EN = 133,
+	MX6Q_CSI0_VSYNC = 134,
+	MX6Q_CSI0_DAT4 = 135,
+	MX6Q_CSI0_DAT5 = 136,
+	MX6Q_CSI0_DAT6 = 137,
+	MX6Q_CSI0_DAT7 = 138,
+	MX6Q_CSI0_DAT8 = 139,
+	MX6Q_CSI0_DAT9 = 140,
+	MX6Q_CSI0_DAT10 = 141,
+	MX6Q_CSI0_DAT11 = 142,
+	MX6Q_CSI0_DAT12 = 143,
+	MX6Q_CSI0_DAT13 = 144,
+	MX6Q_CSI0_DAT14 = 145,
+	MX6Q_CSI0_DAT15 = 146,
+	MX6Q_CSI0_DAT16 = 147,
+	MX6Q_CSI0_DAT17 = 148,
+	MX6Q_CSI0_DAT18 = 149,
+	MX6Q_CSI0_DAT19 = 150,
+	MX6Q_SD3_DAT7 = 151,
+	MX6Q_SD3_DAT6 = 152,
+	MX6Q_SD3_DAT5 = 153,
+	MX6Q_SD3_DAT4 = 154,
+	MX6Q_SD3_CMD = 155,
+	MX6Q_SD3_CLK = 156,
+	MX6Q_SD3_DAT0 = 157,
+	MX6Q_SD3_DAT1 = 158,
+	MX6Q_SD3_DAT2 = 159,
+	MX6Q_SD3_DAT3 = 160,
+	MX6Q_SD3_RST = 161,
+	MX6Q_NANDF_CLE = 162,
+	MX6Q_NANDF_ALE = 163,
+	MX6Q_NANDF_WP_B = 164,
+	MX6Q_NANDF_RB0 = 165,
+	MX6Q_NANDF_CS0 = 166,
+	MX6Q_NANDF_CS1 = 167,
+	MX6Q_NANDF_CS2 = 168,
+	MX6Q_NANDF_CS3 = 169,
+	MX6Q_SD4_CMD = 170,
+	MX6Q_SD4_CLK = 171,
+	MX6Q_NANDF_D0 = 172,
+	MX6Q_NANDF_D1 = 173,
+	MX6Q_NANDF_D2 = 174,
+	MX6Q_NANDF_D3 = 175,
+	MX6Q_NANDF_D4 = 176,
+	MX6Q_NANDF_D5 = 177,
+	MX6Q_NANDF_D6 = 178,
+	MX6Q_NANDF_D7 = 179,
+	MX6Q_SD4_DAT0 = 180,
+	MX6Q_SD4_DAT1 = 181,
+	MX6Q_SD4_DAT2 = 182,
+	MX6Q_SD4_DAT3 = 183,
+	MX6Q_SD4_DAT4 = 184,
+	MX6Q_SD4_DAT5 = 185,
+	MX6Q_SD4_DAT6 = 186,
+	MX6Q_SD4_DAT7 = 187,
+	MX6Q_SD1_DAT1 = 188,
+	MX6Q_SD1_DAT0 = 189,
+	MX6Q_SD1_DAT3 = 190,
+	MX6Q_SD1_CMD = 191,
+	MX6Q_SD1_DAT2 = 192,
+	MX6Q_SD1_CLK = 193,
+	MX6Q_SD2_CLK = 194,
+	MX6Q_SD2_CMD = 195,
+	MX6Q_SD2_DAT3 = 196
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx6q_pinctrl_pads[] = {
+	IMX_PINCTRL_PIN(MX6Q_SD2_DAT1),
+	IMX_PINCTRL_PIN(MX6Q_SD2_DAT2),
+	IMX_PINCTRL_PIN(MX6Q_SD2_DAT0),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_TXC),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_TD0),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_TD1),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_TD2),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_TD3),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_RX_CTL),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_RD0),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_TX_CTL),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_RD1),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_RD2),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_RD3),
+	IMX_PINCTRL_PIN(MX6Q_RGMII_RXC),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A25),
+	IMX_PINCTRL_PIN(MX6Q_EIM_EB2),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D16),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D17),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D18),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D19),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D20),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D21),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D22),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D23),
+	IMX_PINCTRL_PIN(MX6Q_EIM_EB3),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D24),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D25),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D26),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D27),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D28),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D29),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D30),
+	IMX_PINCTRL_PIN(MX6Q_EIM_D31),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A24),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A23),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A22),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A21),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A20),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A19),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A18),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A17),
+	IMX_PINCTRL_PIN(MX6Q_EIM_A16),
+	IMX_PINCTRL_PIN(MX6Q_EIM_CS0),
+	IMX_PINCTRL_PIN(MX6Q_EIM_CS1),
+	IMX_PINCTRL_PIN(MX6Q_EIM_OE),
+	IMX_PINCTRL_PIN(MX6Q_EIM_RW),
+	IMX_PINCTRL_PIN(MX6Q_EIM_LBA),
+	IMX_PINCTRL_PIN(MX6Q_EIM_EB0),
+	IMX_PINCTRL_PIN(MX6Q_EIM_EB1),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA0),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA1),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA2),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA3),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA4),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA5),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA6),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA7),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA8),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA9),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA10),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA11),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA12),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA13),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA14),
+	IMX_PINCTRL_PIN(MX6Q_EIM_DA15),
+	IMX_PINCTRL_PIN(MX6Q_EIM_WAIT),
+	IMX_PINCTRL_PIN(MX6Q_EIM_BCLK),
+	IMX_PINCTRL_PIN(MX6Q_DI0_DISP_CLK),
+	IMX_PINCTRL_PIN(MX6Q_DI0_PIN15),
+	IMX_PINCTRL_PIN(MX6Q_DI0_PIN2),
+	IMX_PINCTRL_PIN(MX6Q_DI0_PIN3),
+	IMX_PINCTRL_PIN(MX6Q_DI0_PIN4),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT0),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT1),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT2),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT3),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT4),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT5),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT6),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT7),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT8),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT9),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT10),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT11),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT12),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT13),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT14),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT15),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT16),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT17),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT18),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT19),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT20),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT21),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT22),
+	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT23),
+	IMX_PINCTRL_PIN(MX6Q_ENET_MDIO),
+	IMX_PINCTRL_PIN(MX6Q_ENET_REF_CLK),
+	IMX_PINCTRL_PIN(MX6Q_ENET_RX_ER),
+	IMX_PINCTRL_PIN(MX6Q_ENET_CRS_DV),
+	IMX_PINCTRL_PIN(MX6Q_ENET_RXD1),
+	IMX_PINCTRL_PIN(MX6Q_ENET_RXD0),
+	IMX_PINCTRL_PIN(MX6Q_ENET_TX_EN),
+	IMX_PINCTRL_PIN(MX6Q_ENET_TXD1),
+	IMX_PINCTRL_PIN(MX6Q_ENET_TXD0),
+	IMX_PINCTRL_PIN(MX6Q_ENET_MDC),
+	IMX_PINCTRL_PIN(MX6Q_KEY_COL0),
+	IMX_PINCTRL_PIN(MX6Q_KEY_ROW0),
+	IMX_PINCTRL_PIN(MX6Q_KEY_COL1),
+	IMX_PINCTRL_PIN(MX6Q_KEY_ROW1),
+	IMX_PINCTRL_PIN(MX6Q_KEY_COL2),
+	IMX_PINCTRL_PIN(MX6Q_KEY_ROW2),
+	IMX_PINCTRL_PIN(MX6Q_KEY_COL3),
+	IMX_PINCTRL_PIN(MX6Q_KEY_ROW3),
+	IMX_PINCTRL_PIN(MX6Q_KEY_COL4),
+	IMX_PINCTRL_PIN(MX6Q_KEY_ROW4),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_0),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_1),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_9),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_3),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_6),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_2),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_4),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_5),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_7),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_8),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_16),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_17),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_18),
+	IMX_PINCTRL_PIN(MX6Q_GPIO_19),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_PIXCLK),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_MCLK),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DATA_EN),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_VSYNC),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT4),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT5),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT6),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT7),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT8),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT9),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT10),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT11),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT12),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT13),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT14),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT15),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT16),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT17),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT18),
+	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT19),
+	IMX_PINCTRL_PIN(MX6Q_SD3_DAT7),
+	IMX_PINCTRL_PIN(MX6Q_SD3_DAT6),
+	IMX_PINCTRL_PIN(MX6Q_SD3_DAT5),
+	IMX_PINCTRL_PIN(MX6Q_SD3_DAT4),
+	IMX_PINCTRL_PIN(MX6Q_SD3_CMD),
+	IMX_PINCTRL_PIN(MX6Q_SD3_CLK),
+	IMX_PINCTRL_PIN(MX6Q_SD3_DAT0),
+	IMX_PINCTRL_PIN(MX6Q_SD3_DAT1),
+	IMX_PINCTRL_PIN(MX6Q_SD3_DAT2),
+	IMX_PINCTRL_PIN(MX6Q_SD3_DAT3),
+	IMX_PINCTRL_PIN(MX6Q_SD3_RST),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_CLE),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_ALE),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_WP_B),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_RB0),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_CS0),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_CS1),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_CS2),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_CS3),
+	IMX_PINCTRL_PIN(MX6Q_SD4_CMD),
+	IMX_PINCTRL_PIN(MX6Q_SD4_CLK),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_D0),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_D1),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_D2),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_D3),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_D4),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_D5),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_D6),
+	IMX_PINCTRL_PIN(MX6Q_NANDF_D7),
+	IMX_PINCTRL_PIN(MX6Q_SD4_DAT0),
+	IMX_PINCTRL_PIN(MX6Q_SD4_DAT1),
+	IMX_PINCTRL_PIN(MX6Q_SD4_DAT2),
+	IMX_PINCTRL_PIN(MX6Q_SD4_DAT3),
+	IMX_PINCTRL_PIN(MX6Q_SD4_DAT4),
+	IMX_PINCTRL_PIN(MX6Q_SD4_DAT5),
+	IMX_PINCTRL_PIN(MX6Q_SD4_DAT6),
+	IMX_PINCTRL_PIN(MX6Q_SD4_DAT7),
+	IMX_PINCTRL_PIN(MX6Q_SD1_DAT1),
+	IMX_PINCTRL_PIN(MX6Q_SD1_DAT0),
+	IMX_PINCTRL_PIN(MX6Q_SD1_DAT3),
+	IMX_PINCTRL_PIN(MX6Q_SD1_CMD),
+	IMX_PINCTRL_PIN(MX6Q_SD1_DAT2),
+	IMX_PINCTRL_PIN(MX6Q_SD1_CLK),
+	IMX_PINCTRL_PIN(MX6Q_SD2_CLK),
+	IMX_PINCTRL_PIN(MX6Q_SD2_CMD),
+	IMX_PINCTRL_PIN(MX6Q_SD2_DAT3),
+};
+
+struct imx_pinctrl_info imx6q_pinctrl_info = {
+	.type = IMX6Q_PINCTRL,
+	.pins = imx6q_pinctrl_pads,
+	.npins = ARRAY_SIZE(imx6q_pinctrl_pads),
+	.maxpin = IMX6Q_IOMUXC_MAXPIN,
+	.mux_offset = IMX6Q_IOMUXC_MUX_OFSSET,
+};
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [RFC PATCH v3 4/5] ARM: imx6q: using pinmux subsystem
  2011-12-20 17:40 [RFC PATCH v3 0/5] pinctrl: imx: add pinnmux support Dong Aisheng
                   ` (2 preceding siblings ...)
  2011-12-20 17:40 ` [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver Dong Aisheng
@ 2011-12-20 17:40 ` Dong Aisheng
  2011-12-20 17:40 ` [RFC PATCH v3 5/5] mmc: sdhci-esdhc-imx: " Dong Aisheng
  4 siblings, 0 replies; 98+ messages in thread
From: Dong Aisheng @ 2011-12-20 17:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, linus.walleij, s.hauer, shawn.guo, kernel,
	grant.likely, rob.herring, devicetree-discuss, cjb, w.sang

From: Dong Aisheng <dong.aisheng@linaro.org>

Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Shawn Guo <shanw.guo@freescale.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
---
ChangeLog v2->v3:
- Add phandle for pinmux mappings
- follow DT convention to use dash '-' for property name

ChangeLog v1->v2:
- Add basic binding for pinmux pins
---
 arch/arm/boot/dts/imx6q-sabreauto.dts |   32 ++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/imx6q.dtsi          |    1 +
 arch/arm/mach-imx/Kconfig             |    1 +
 3 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-sabreauto.dts b/arch/arm/boot/dts/imx6q-sabreauto.dts
index 072974e..c3e9070 100644
--- a/arch/arm/boot/dts/imx6q-sabreauto.dts
+++ b/arch/arm/boot/dts/imx6q-sabreauto.dts
@@ -25,7 +25,39 @@
 		reg = <0x10000000 0x80000000>;
 	};
 
+	pinmux: imx6q-sabreauto-map {
+		map-sd4 {
+			map-name = "usdhc4";
+			ctrl-dev-name = "20e0000.iomuxc";
+			function = "sd4";
+			dev-name = "219c000.usdhc";
+		};
+	};
+
 	soc {
+		aips-bus@02000000 { /* AIPS1 */
+			iomuxc@020e0000 {
+				fsl,pinmux-map = <&pinmux>;
+				pinmux-uart4 {
+					func-name = "uart4";
+					grp-name = "uart4grp";
+					grp-pins = <107 108>;
+					num-pins = <2>;
+					grp-mux = <4 4>;
+					num-mux = <2>;
+				};
+
+				pinmux-sd4 {
+					func-name = "sd4";
+					grp-name = "sd4grp";
+					grp-pins = <170 171 180 181 182 183 184 185 186 187>;
+					num-pins = <10>;
+					grp-mux = <0 0 1 1 1 1 1 1 1 1>;
+					num-mux = <10>;
+				};
+			};
+		};
+
 		aips-bus@02100000 { /* AIPS2 */
 			enet@02188000 {
 				phy-mode = "rgmii";
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 7dda599..42499bb 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -386,6 +386,7 @@
 			};
 
 			iomuxc@020e0000 {
+				compatible = "fsl,imx6q-iomuxc";
 				reg = <0x020e0000 0x4000>;
 			};
 
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 5f7f9c2..d6a88fe 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -615,6 +615,7 @@ config SOC_IMX6Q
 	select HAVE_IMX_GPC
 	select HAVE_IMX_MMDC
 	select HAVE_IMX_SRC
+	select PINCTRL
 	select USE_OF
 
 	help
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [RFC PATCH v3 5/5] mmc: sdhci-esdhc-imx: using pinmux subsystem
  2011-12-20 17:40 [RFC PATCH v3 0/5] pinctrl: imx: add pinnmux support Dong Aisheng
                   ` (3 preceding siblings ...)
  2011-12-20 17:40 ` [RFC PATCH v3 4/5] ARM: imx6q: using pinmux subsystem Dong Aisheng
@ 2011-12-20 17:40 ` Dong Aisheng
  2012-01-01 13:54   ` Linus Walleij
  4 siblings, 1 reply; 98+ messages in thread
From: Dong Aisheng @ 2011-12-20 17:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, linus.walleij, s.hauer, shawn.guo, kernel,
	grant.likely, rob.herring, devicetree-discuss, cjb, w.sang

From: Dong Aisheng <dong.aisheng@linaro.org>

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Chris Ball <cjb@laptop.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Wolfram Sang <w.sang@pengutronix.de>
---
 drivers/mmc/host/sdhci-esdhc-imx.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 4b976f0..4504136 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
+#include <linux/pinctrl/pinmux.h>
 #include <mach/esdhc.h>
 #include "sdhci-pltfm.h"
 #include "sdhci-esdhc.h"
@@ -68,6 +69,7 @@ struct pltfm_imx_data {
 	int flags;
 	u32 scratchpad;
 	enum imx_esdhc_type devtype;
+	struct pinmux *pmx;
 	struct esdhc_platform_data boarddata;
 };
 
@@ -439,6 +441,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	struct clk *clk;
 	int err;
 	struct pltfm_imx_data *imx_data;
+	struct pinmux *pmx;
 
 	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata);
 	if (IS_ERR(host))
@@ -466,6 +469,16 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	clk_enable(clk);
 	pltfm_host->clk = clk;
 
+	pmx = pinmux_get(&pdev->dev, NULL);
+	if (IS_ERR(pmx)) {
+		err = PTR_ERR(pmx);
+		goto err_pmx_get;
+	}
+	err = pinmux_enable(pmx);
+	if (err)
+		goto err_pmx_enable;
+	imx_data->pmx = pmx;
+
 	if (!is_imx25_esdhc(imx_data))
 		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
@@ -558,6 +571,10 @@ no_card_detect_irq:
 		gpio_free(boarddata->wp_gpio);
 no_card_detect_pin:
 no_board_data:
+	pinmux_disable(imx_data->pmx);
+err_pmx_enable:
+	pinmux_put(imx_data->pmx);
+err_pmx_get:
 	clk_disable(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
 err_clk_get:
@@ -585,6 +602,9 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
 		gpio_free(boarddata->cd_gpio);
 	}
 
+	pinmux_disable(imx_data->pmx);
+	pinmux_put(imx_data->pmx);
+
 	clk_disable(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
 	kfree(imx_data);
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
  2011-12-20 17:40 ` [RFC PATCH v3 1/5] dt: add of_get_child_count helper function Dong Aisheng
@ 2011-12-20 18:35   ` Rob Herring
  2011-12-21  2:56     ` Dong Aisheng-B29396
  2011-12-20 19:47   ` Marek Vasut
  2011-12-20 23:58   ` Stephen Warren
  2 siblings, 1 reply; 98+ messages in thread
From: Rob Herring @ 2011-12-20 18:35 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-kernel, linux-arm-kernel, linus.walleij, s.hauer,
	shawn.guo, kernel, grant.likely, devicetree-discuss, cjb, w.sang

On 12/20/2011 11:40 AM, Dong Aisheng wrote:
> From: Dong Aisheng <dong.aisheng@linaro.org>
> 
> Currently most code to get child count in kernel are almost same,
> add a helper to implement this function for dt to use.
> 
> ---
> Changes v1->v2:
>  * change the name from of_get_child_number to of_get_child_count
> 
> Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>

I assume you want this to go in with the rest of the series? If not, let
me know.

Acked-by: Rob Herring <rob.herring@calxeda.com>

Rob

> ---
>  include/linux/of.h |   16 ++++++++++++++++
>  1 files changed, 16 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 4948552..d0d91a1 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -189,6 +189,17 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
>  	for (child = of_get_next_child(parent, NULL); child != NULL; \
>  	     child = of_get_next_child(parent, child))
>  
> +static inline int of_get_child_count(const struct device_node *np)
> +{
> +	struct device_node *child = NULL;
> +	int num = 0;
> +
> +	while ((child = of_get_next_child(np, child)))
> +		num++;
> +
> +	return num;
> +}
> +
>  extern struct device_node *of_find_node_with_property(
>  	struct device_node *from, const char *prop_name);
>  #define for_each_node_with_property(dn, prop_name) \
> @@ -262,6 +273,11 @@ static inline bool of_have_populated_dt(void)
>  #define for_each_child_of_node(parent, child) \
>  	while (0)
>  
> +static inline int of_get_child_count(const struct device_node *np)
> +{
> +	return -ENOSYS;
> +}
> +
>  static inline int of_device_is_compatible(const struct device_node *device,
>  					  const char *name)
>  {

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
  2011-12-20 17:40 ` [RFC PATCH v3 1/5] dt: add of_get_child_count helper function Dong Aisheng
  2011-12-20 18:35   ` Rob Herring
@ 2011-12-20 19:47   ` Marek Vasut
  2011-12-21  3:27     ` Dong Aisheng-B29396
  2011-12-20 23:58   ` Stephen Warren
  2 siblings, 1 reply; 98+ messages in thread
From: Marek Vasut @ 2011-12-20 19:47 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Dong Aisheng, linux-kernel, linus.walleij, s.hauer, w.sang,
	rob.herring, grant.likely, kernel, cjb, devicetree-discuss,
	shawn.guo

> From: Dong Aisheng <dong.aisheng@linaro.org>
> 
> Currently most code to get child count in kernel are almost same,
> add a helper to implement this function for dt to use.
> 
> ---
> Changes v1->v2:
>  * change the name from of_get_child_number to of_get_child_count
> 
> Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>
> ---
>  include/linux/of.h |   16 ++++++++++++++++
>  1 files changed, 16 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 4948552..d0d91a1 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -189,6 +189,17 @@ extern struct device_node *of_get_next_child(const
> struct device_node *node, for (child = of_get_next_child(parent, NULL);
> child != NULL; \
>  	     child = of_get_next_child(parent, child))
> 
> +static inline int of_get_child_count(const struct device_node *np)
> +{
> +	struct device_node *child = NULL;
> +	int num = 0;
> +
> +	while ((child = of_get_next_child(np, child)))

The assignment in this condition really looks eerie, maybe just rewrite it to do  
{ } while () ? Also, aren't the parenthesis unnecessary?

M
> +		num++;
> +
> +	return num;
> +}
> +
>  extern struct device_node *of_find_node_with_property(
>  	struct device_node *from, const char *prop_name);
>  #define for_each_node_with_property(dn, prop_name) \
> @@ -262,6 +273,11 @@ static inline bool of_have_populated_dt(void)
>  #define for_each_child_of_node(parent, child) \
>  	while (0)
> 
> +static inline int of_get_child_count(const struct device_node *np)
> +{
> +	return -ENOSYS;
> +}
> +
>  static inline int of_device_is_compatible(const struct device_node
> *device, const char *name)
>  {

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-20 17:40 ` [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings Dong Aisheng
@ 2011-12-20 19:48   ` Marek Vasut
  2011-12-21  0:39   ` Stephen Warren
  2012-01-01 14:07   ` Linus Walleij
  2 siblings, 0 replies; 98+ messages in thread
From: Marek Vasut @ 2011-12-20 19:48 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Dong Aisheng, linux-kernel, linus.walleij, s.hauer, w.sang,
	rob.herring, grant.likely, kernel, cjb, devicetree-discuss,
	shawn.guo

> From: Dong Aisheng <dong.aisheng@linaro.org>
> 
> This patch provies a common API for driver to use to register pinmux
> mappings from dts file. It is needed for dt support.
> 
> Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>
> ---
>  .../devicetree/bindings/pinctrl/pinctrl.txt        |   33 +++++++
>  drivers/pinctrl/pinmux.c                           |  101
> ++++++++++++++++++++ include/linux/pinctrl/machine.h                    | 
>   6 +
>  3 files changed, 140 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> b/Documentation/devicetree/bindings/pinctrl/pinctrl.txt new file mode
> 100644
> index 0000000..a27a7ce
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> @@ -0,0 +1,33 @@
> +The pin control subsystem
> +
> +The pin control subsystem provides a common API to support parsing pinmux
> +mappings data from device tree. Each board dts file should provide a
> device +node of which all the child nodes are the corresponding pinmux
> mappings. +
> +The required properties for pinmux mapping are:
> +- map-name: the name of this specific map entry
> +- clk-dev-name: the name of the device controlling this specific mapping
> +- funcion: a function in the driver to use for this mapping
> +
> +Optional properties:
> +- group: a certain specific pin group to activate for the function
> +- dev-name: the name of the device using this specific mapping
> +- hog-on-boot: indicate wether hog the mappings(do not need to specify
> value) +
> +Examples:
> +
> +pinmux: imx6q-sabreauto-map {
> +	map-sd4 {
> +		map-name = "usdhc4";
> +		ctrl-dev-name = "20e0000.iomuxc";
> +		function = "sd4";
> +		dev-name = "219c000.usdhc";
> +	};
> +	...
> +};
> +
> +Then calling pinmux_of_register_mappings() with the device node of
> +imx6q-sabreauto-map as parameter to register pinmux mappings from dts.
> +
> +Usually user can get this device node via a phandle in driver then call
> +the function to register maps. Please refer to pinctrl-imx.txt for
> example. diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
> index 432feb6..3ac3098 100644
> --- a/drivers/pinctrl/pinmux.c
> +++ b/drivers/pinctrl/pinmux.c
> @@ -20,6 +20,7 @@
>  #include <linux/err.h>
>  #include <linux/list.h>
>  #include <linux/mutex.h>
> +#include <linux/of_device.h>
>  #include <linux/spinlock.h>
>  #include <linux/string.h>
>  #include <linux/sysfs.h>
> @@ -410,6 +411,106 @@ int __init pinmux_register_mappings(struct pinmux_map
> const *maps, return 0;
>  }
> 
> +static int __devinit pinmux_of_parse_mapping(struct device_node *np,
> +					struct pinmux_map *maps, unsigned id)
> +{
> +	struct pinmux_map *map = &maps[id];
> +	int ret = 0;
> +
> +	pr_debug("parse pinmux map %d\n", id + 1);
> +
> +	if (of_find_property(np, "map-name", NULL)) {
> +		ret = of_property_read_string(np, "map-name", &map->name);
> +		if (ret) {
> +			pr_err("failed to get map-name");
> +			return ret;
> +		}
> +	}
> +
> +	if (of_find_property(np, "ctrl-dev-name", NULL)) {
> +		ret = of_property_read_string(np, "ctrl-dev-name",
> +						&map->ctrl_dev_name);
> +		if (ret) {
> +			pr_err("failed to get ctrl-dev-name");
> +			return ret;
> +		}
> +	}
> +
> +	if (of_find_property(np, "function", NULL)) {
> +		ret = of_property_read_string(np, "function", &map->function);
> +		if (ret) {
> +			pr_err("failed to get function");
> +			return ret;
> +		}
> +	}
> +
> +	if (of_find_property(np, "group", NULL)) {
> +		ret = of_property_read_string(np, "group", &map->group);
> +		if (ret) {
> +			pr_err("failed to get group");
> +			return ret;
> +		}
> +	}
> +
> +	if (of_find_property(np, "dev-name", NULL)) {
> +		ret = of_property_read_string(np, "dev-name", &map->dev_name);
> +		if (ret) {
> +			pr_err("failed to get dev-name");
> +			return ret;
> +		}
> +	}
> +
> +	if (of_find_property(np, "hog-on-boot", NULL))
> +		map->hog_on_boot = true;
> +
> +	pr_debug("map-name: %s ctrl-dev-name: %s function: %s group: %s dev-
name:
> %s hog-on-boot: %d\n", +			map->name, map->ctrl_dev_name, 
map->function,
> +			map->group, map->dev_name, map->hog_on_boot);

Line too long maybe?

> +
> +	return 0;
> +}
> +
> +/**
> + * pinmux_of_register_mappings() - parse and register pinmux mappings from
> dt + * &np: a device node containing pinmux map properties
> + *
> + * Like pinmux_register_mappings(), the memory of pinmux maps are owned by
> + * pinctrl core and can not be freed.
> + */
> +int __devinit pinmux_of_register_mappings(struct device_node *np)
> +{
> +	struct pinmux_map *maps;
> +	struct device_node *child = NULL;
> +	int count, i;
> +	int ret;
> +
> +	pr_debug("parse pinmux maps from device node %s\n", np->name);
> +
> +	if (!np)
> +		return -EINVAL;
> +
> +	count = of_get_child_count(np);
> +	if (!count) {
> +		pr_err("no available pinmux maps found\n");
> +		return -EINVAL;
> +	}
> +
> +	maps = kzalloc(count * sizeof(struct pinmux_map), GFP_KERNEL);
> +	if (!maps)
> +		return -ENOMEM;
> +
> +	i = 0;
> +	for_each_child_of_node(np, child) {
> +		ret = pinmux_of_parse_mapping(child, maps, i++);
> +		if (ret) {
> +			pr_err("failed to parse pinmux map\n");
> +			return ret;
> +		}
> +	}
> +
> +	return pinmux_register_mappings(maps, count);
> +}
> +
>  /**
>   * acquire_pins() - acquire all the pins for a certain funcion on a pinmux
>   * @pctldev: the device to take the pins on
> diff --git a/include/linux/pinctrl/machine.h
> b/include/linux/pinctrl/machine.h index ad430e0..74a695d 100644
> --- a/include/linux/pinctrl/machine.h
> +++ b/include/linux/pinctrl/machine.h
> @@ -78,6 +78,7 @@ struct pinmux_map {
>  extern int pinmux_register_mappings(struct pinmux_map const *map,
>  				unsigned num_maps);
> 
> +extern int pinmux_of_register_mappings(struct device_node *np);
>  #else
> 
>  static inline int pinmux_register_mappings(struct pinmux_map const *map,
> @@ -86,5 +87,10 @@ static inline int pinmux_register_mappings(struct
> pinmux_map const *map, return 0;
>  }
> 
> +static inline int pinmux_of_register_mappings(struct device_node *np)
> +{
> +	return 0;
> +}
> +
>  #endif /* !CONFIG_PINMUX */
>  #endif

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2011-12-20 17:40 ` [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver Dong Aisheng
@ 2011-12-20 19:50   ` Marek Vasut
  2011-12-21  3:09     ` Dong Aisheng-B29396
  2012-01-01 14:02   ` Linus Walleij
  2012-01-08 13:05   ` Richard Zhao
  2 siblings, 1 reply; 98+ messages in thread
From: Marek Vasut @ 2011-12-20 19:50 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Dong Aisheng, linux-kernel, linus.walleij, s.hauer, w.sang,
	rob.herring, grant.likely, kernel, cjb, devicetree-discuss,
	shawn.guo

> From: Dong Aisheng <dong.aisheng@linaro.org>
> 
> The driver contains the initial support for imx53 and
> imx6q.
> 
> Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Shawn Guo <shanw.guo@freescale.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>
> 

Is this imx or mx6q/mx53 ?

M
> ---
> ChangeLog v2->v3:
> - binding pinmux mappings via pinctrl core API
> - follow the dt convention to use dash '-' for property name
> 
> ChangeLog v1->v2:
> - add basic binding from device tree
> ---
>  .../devicetree/bindings/pinctrl/pinctrl-imx.txt    |   59 +++
>  drivers/pinctrl/Kconfig                            |   20 +
>  drivers/pinctrl/Makefile                           |    3 +
>  drivers/pinctrl/pinctrl-imx-core.c                 |  450
> ++++++++++++++++++++ drivers/pinctrl/pinctrl-imx-core.h                 | 
>  86 ++++
>  drivers/pinctrl/pinctrl-imx53.c                    |  443
> +++++++++++++++++++ drivers/pinctrl/pinctrl-imx6q.c                    | 
> 433 +++++++++++++++++++ 7 files changed, 1494 insertions(+), 0
> deletions(-)
>  create mode 100644
> Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt create mode
> 100644 drivers/pinctrl/pinctrl-imx-core.c
>  create mode 100644 drivers/pinctrl/pinctrl-imx-core.h
>  create mode 100644 drivers/pinctrl/pinctrl-imx53.c
>  create mode 100644 drivers/pinctrl/pinctrl-imx6q.c
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt
> b/Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt new file mode
> 100644
> index 0000000..e45d745
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt
> @@ -0,0 +1,59 @@
> +* Freescale IOMUX Controller (IOMUXC) for i.MX
> +
> +The IOMUX Controller (IOMUXC), together with the IOMUX, enables the IC
> +to share one PAD to several functional blocks. The sharing is done by
> +multiplexing the PAD input/output signals. For each PAD there are up to
> +8 muxing options (called ALT modes). Since different modules require
> +different PAD settings (like pull up, keeper, etc) the IOMUXC controls
> +also the PAD settings parameters.
> +
> +Required properties:
> +- compatible : Should be "fsl,<chip>-iomuxc"
> +- reg : Should contain IOMUXC registers location and length
> +- fsl,pinmux-map: phandle of pinmux mappings. Refer to pinctrl.txt for
> +  detailed format.
> +- child nodes containing pinmux data
> +  Each child node corresponds to a specific pinmux function and the
> required +  properties of the pinmux function are:
> +  - func-name: the name of a specific function
> +  - grp-name: the name of a group pins correspding to this function
> +  - grp-pins: the list of pins for the group of grp-name
> +  - num-pins: the pins number of grp-pins list
> +  - grp-mux: the corresponding mux mode list for grp-pins.
> +    Each pin in the grp-pins should have a corresponding mux mode for the
> +    specific function of func-name.
> +  - num-numx: the mux number of grp-mux list
> +
> +Examples:
> +
> +pinmux: imx6q-sabreauto-map {
> +	map-sd4 {
> +		map-name = "usdhc4";
> +		ctrl-dev-name = "20e0000.iomuxc";
> +		function = "sd4";
> +		dev-name = "219c000.usdhc";
> +	};
> +};
> +
> +iomuxc@020e0000 {
> +	compatible = "fsl,imx6q-iomuxc";
> +	reg = <0x020e0000 0x4000>;
> +	fsl,pinmux-map = <&pinmux>;
> +	pinmux_uart4 {
> +		func-name = "uart4";
> +		grp-name = "uart4grp";
> +		grp-pins = <107 108>;
> +		num-pins = <2>;
> +		grp-mux = <4 4>;
> +		num-mux = <2>;
> +	};
> +
> +	pinmux_sd4 {
> +		func-name = "sd4";
> +		grp-name = "sd4grp";
> +		grp-pins = <170 171 180 181 182 183 184 185 186 187>;
> +		num-pins = <10>;
> +		grp-mux = <0 0 1 1 1 1 1 1 1 1>;
> +		num-mux = <10>;
> +	};
> +};
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index c63c721..f65bf5a 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -23,6 +23,26 @@ config DEBUG_PINCTRL
>  	help
>  	  Say Y here to add some extra checks and diagnostics to PINCTRL calls.
> 
> +config PINCTRL_IMX
> +	bool "Freescale IMX core pinctrl driver"
> +	depends on ARCH_MXC
> +
> +config PINCTRL_IMX53
> +	bool "IMX53 pinctrl driver"
> +	depends on SOC_IMX53
> +	select PINMUX
> +	select PINCTRL_IMX
> +	help
> +	  Say Y here to enable the imx53 pinctrl driver
> +
> +config PINCTRL_IMX6Q
> +	bool "IMX6Q pinctrl driver"
> +	depends on SOC_IMX6Q
> +	select PINMUX
> +	select PINCTRL_IMX
> +	help
> +	  Say Y here to enable the imx6q pinctrl driver
> +
>  config PINMUX_SIRF
>  	bool "CSR SiRFprimaII pinmux driver"
>  	depends on ARCH_PRIMA2
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index c046f78..cf85edc 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -5,6 +5,9 @@ ccflags-$(CONFIG_DEBUG_PINCTRL)	+= -DDEBUG
>  obj-$(CONFIG_PINCTRL)		+= core.o
>  obj-$(CONFIG_PINMUX)		+= pinmux.o
>  obj-$(CONFIG_PINCONF)		+= pinconf.o
> +obj-$(CONFIG_PINMUX_IMX)	+= pinmux-imx-core.o
> +obj-$(CONFIG_PINMUX_IMX53)	+= pinmux-imx53.o
> +obj-$(CONFIG_PINMUX_IMX6Q)	+= pinmux-imx6q.o
>  obj-$(CONFIG_PINMUX_SIRF)	+= pinmux-sirf.o
>  obj-$(CONFIG_PINMUX_U300)	+= pinmux-u300.o
>  obj-$(CONFIG_PINCTRL_COH901)	+= pinctrl-coh901.o
> diff --git a/drivers/pinctrl/pinctrl-imx-core.c
> b/drivers/pinctrl/pinctrl-imx-core.c new file mode 100644
> index 0000000..5c348ba
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-imx-core.c
> @@ -0,0 +1,450 @@
> +/*
> + * Core driver for the imx pin controller
> + *
> + * Copyright (C) 2011 Freescale Semiconductor, Inc.
> + * Copyright (C) 2011 Linaro Ltd.
> + *
> + * Author: Dong Aisheng <dong.aisheng@linaro.org>
> + *
> + * 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/init.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/pinmux.h>
> +#include <linux/pinctrl/machine.h>
> +#include <linux/slab.h>
> +
> +#include "pinctrl-imx-core.h"
> +
> +#define DRIVER_NAME "pinmux-imx"
> +
> +/**
> + * @dev: a pointer back to containing device
> + * @virtbase: the offset to the controller in virtual memory
> + */
> +struct imx_pmx {
> +	struct device *dev;
> +	struct pinctrl_dev *pctl;
> +	void __iomem *virtbase;
> +	struct imx_pinctrl_info *info;
> +};
> +
> +#define IMX_PINCTRL_REG_SIZE 4
> +#define IMX_PINCTRL_MAX_FUNC 7
> +
> +static int imx_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
> +{
> +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> +	struct imx_pinctrl_info *info = ipmx->info;
> +
> +	if (selector >= info->ngroups)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static const char *imx_get_group_name(struct pinctrl_dev *pctldev,
> +				       unsigned selector)
> +{
> +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> +	struct imx_pinctrl_info *info = ipmx->info;
> +
> +	if (selector >= info->ngroups)
> +		return NULL;
> +
> +	return info->groups[selector].name;
> +}
> +
> +static int imx_get_group_pins(struct pinctrl_dev *pctldev, unsigned
> selector, +			       const unsigned **pins,
> +			       unsigned *num_pins)
> +{
> +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> +	struct imx_pinctrl_info *info = ipmx->info;
> +
> +	if (selector >= info->ngroups)
> +		return -EINVAL;
> +
> +	*pins = info->groups[selector].pins;
> +	*num_pins = info->groups[selector].num_pins;
> +
> +	return 0;
> +}
> +
> +static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file
> *s, +		   unsigned offset)
> +{
> +	seq_printf(s, " " DRIVER_NAME);
> +}
> +
> +static struct pinctrl_ops imx_pctrl_ops = {
> +	.list_groups = imx_list_groups,
> +	.get_group_name = imx_get_group_name,
> +	.get_group_pins = imx_get_group_pins,
> +	.pin_dbg_show = imx_pin_dbg_show,
> +};
> +
> +static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
> +			   unsigned group)
> +{
> +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> +	struct imx_pinctrl_info *info = ipmx->info;
> +	const unsigned *pins, *mux;
> +	unsigned int num_pins, num_mux;
> +	u32 regval, offset;
> +	int i;
> +
> +	/*
> +	 * Configure the mux mode for each pin in the group for a specific
> +	 * function.
> +	 */
> +	pins = info->groups[group].pins;
> +	num_pins = info->groups[group].num_pins;
> +	mux = info->groups[group].mux_mode;
> +	num_mux = info->groups[group].num_mux;
> +
> +	dev_dbg(ipmx->dev, "function %s group %s\n",
> +		info->functions[selector].name, info->groups[group].name);
> +
> +	if (num_pins != num_mux) {
> +		dev_err(ipmx->dev, "num_mux is not equal to num_pins\n");
> +		return -EINVAL;
> +	}
> +
> +	for (i = 0; i < num_pins; i++) {
> +		if (mux[i] > IMX_PINCTRL_MAX_FUNC)
> +			dev_err(ipmx->dev, "exceeds the maximum mux 
mode(0x7)\n");
> +		offset = info->mux_offset + pins[i] * IMX_PINCTRL_REG_SIZE;
> +		regval = readl(ipmx->virtbase + offset);
> +		regval &= ~IMX_PINCTRL_MAX_FUNC;
> +		writel(mux[i] | regval, ipmx->virtbase + offset);
> +		dev_dbg(ipmx->dev, "write: offset 0x%x val 0x%x\n",
> +			offset, regval | mux[i]);
> +	}
> +
> +	return 0;
> +}
> +
> +static void imx_pmx_disable(struct pinctrl_dev *pctldev, unsigned
> func_selector, +			    unsigned group_selector)
> +{
> +	/* nothing to do here */
> +}
> +
> +static int imx_pmx_list_funcs(struct pinctrl_dev *pctldev, unsigned
> selector) +{
> +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> +	struct imx_pinctrl_info *info = ipmx->info;
> +
> +	if (selector >= info->nfunctions)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static const char *imx_pmx_get_func_name(struct pinctrl_dev *pctldev,
> +					  unsigned selector)
> +{
> +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> +	struct imx_pinctrl_info *info = ipmx->info;
> +
> +	return info->functions[selector].name;
> +}
> +
> +static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned
> selector, +			       const char * const **groups,
> +			       unsigned * const num_groups)
> +{
> +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> +	struct imx_pinctrl_info *info = ipmx->info;
> +
> +	*groups = info->functions[selector].groups;
> +	*num_groups = info->functions[selector].num_groups;
> +
> +	return 0;
> +}
> +
> +static struct pinmux_ops imx_pmx_ops = {
> +	.list_functions = imx_pmx_list_funcs,
> +	.get_function_name = imx_pmx_get_func_name,
> +	.get_function_groups = imx_pmx_get_groups,
> +	.enable = imx_pmx_enable,
> +	.disable = imx_pmx_disable,
> +};
> +
> +static struct pinctrl_desc imx_pmx_desc = {
> +	.name = DRIVER_NAME,
> +	.pctlops = &imx_pctrl_ops,
> +	.pmxops = &imx_pmx_ops,
> +	.owner = THIS_MODULE,
> +};
> +
> +#ifdef CONFIG_OF
> +static int __devinit imx_pmx_parse_functions(struct device_node *np,
> +			struct imx_pinctrl_info *info, u32 num)
> +{
> +	struct imx_pmx_func *function;
> +	struct imx_pin_group *group;
> +	int ret, len;
> +
> +	dev_dbg(info->dev, "parse function %d\n", num);
> +
> +	group = &info->groups[num];
> +	function = &info->functions[num];
> +
> +	/* Initialise group */
> +	ret = of_property_read_string(np, "grp-name", &group->name);
> +	if (ret) {
> +		dev_err(info->dev, "failed to get grp-name\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(np, "num-pins", &group->num_pins);
> +	if (ret) {
> +		dev_err(info->dev, "failed to get num-pins\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(np, "num-mux", &group->num_mux);
> +	if (ret) {
> +		dev_err(info->dev, "failed to get num-mux\n");
> +		return ret;
> +	}
> +
> +	if (group->num_pins != group->num_mux)
> +		return -EINVAL;
> +
> +	group->pins = devm_kzalloc(info->dev, group->num_pins * sizeof(unsigned
> int), +				GFP_KERNEL);
> +	group->mux_mode = devm_kzalloc(info->dev, group->num_mux *
> sizeof(unsigned int), +				GFP_KERNEL);
> +	if (!group->pins || !group->mux_mode)
> +		return -ENOMEM;
> +
> +	/* sanity check */
> +	if (of_get_property(np, "grp-pins", &len) &&
> +		len != group->num_pins * sizeof(unsigned int)) {
> +		dev_err(info->dev, "wrong pins number?\n");
> +		return -EINVAL;
> +	}
> +
> +	if (of_get_property(np, "grp-mux", &len) &&
> +		len != group->num_mux * sizeof(unsigned int)) {
> +		dev_err(info->dev, "wrong pin mux number?\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_u32_array(np, "grp-pins",
> +			group->pins, group->num_pins);
> +	if (ret) {
> +		dev_err(info->dev, "failed to get grp-pins\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32_array(np, "grp-mux",
> +			group->mux_mode, group->num_mux);
> +	if (ret) {
> +		dev_err(info->dev, "failed to get grp-mux\n");
> +		return ret;
> +	}
> +
> +	/* Initialise function */
> +	ret = of_property_read_string(np, "func-name", &function->name);
> +	if (ret) {
> +		dev_err(info->dev, "failed to get func-name\n");
> +		return ret;
> +	}
> +
> +	function->groups = devm_kzalloc(info->dev, sizeof(char **), GFP_KERNEL);
> +	function->num_groups = 1;
> +	function->groups[0] = group->name;
> +
> +	dev_dbg(info->dev, "func-name %s grp-name %s num-groups %d\n",
> +				function->name, function->groups[0],
> +				function->num_groups);
> +
> +	return 0;
> +}
> +
> +static int __devinit imx_pmx_probe_dt(struct platform_device *pdev,
> +				struct imx_pinctrl_info *info)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct device_node *child = NULL;
> +	struct device_node *map_np;
> +	int ret, i;
> +	u32 nfuncs = 0;
> +
> +	if (!np)
> +		return -ENODEV;
> +
> +	nfuncs = of_get_child_count(np);
> +	if (nfuncs <= 0) {
> +		dev_err(&pdev->dev, "no functions defined\n");
> +		return -EINVAL;
> +	}
> +
> +	info->nfunctions = nfuncs;
> +	info->functions = devm_kzalloc(&pdev->dev, nfuncs * sizeof(struct
> imx_pmx_func), +					GFP_KERNEL);
> +	if (!info->functions)
> +		return -ENOMEM;
> +
> +	/* DT file only passes one group per one function */
> +	info->ngroups = nfuncs;
> +	info->groups = devm_kzalloc(&pdev->dev, nfuncs * sizeof(struct
> imx_pin_group), +					GFP_KERNEL);
> +	if (!info->groups)
> +		return -ENOMEM;
> +
> +	child = NULL;
> +	i = 0;
> +	for_each_child_of_node(np, child) {
> +		ret = imx_pmx_parse_functions(child, info, i++);
> +		if (ret) {
> +			dev_err(&pdev->dev, "failed to parse function\n");
> +			return ret;
> +		}
> +	}
> +
> +	/* parse pinmux map */
> +	map_np = of_parse_phandle(np, "fsl,pinmux-map", 0);
> +	if (!map_np) {
> +		dev_err(&pdev->dev, "failed to parse phandle fsl,pinmux-map\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = pinmux_of_register_mappings(map_np);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to register pinmux mappings\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +#else
> +static int __devinit imx_pmx_probe_dt(struct platform_device *pdev,
> +				struct imx_pinctrl_info *info)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
> +static inline void imx_pmx_desc_init(struct pinctrl_desc *pmx_desc,
> +				const struct imx_pinctrl_info *info)
> +{
> +	pmx_desc->pins = info->pins;
> +	pmx_desc->npins = info->npins;
> +	pmx_desc->maxpin = info->maxpin;
> +}
> +
> +static const struct of_device_id imx_pmx_dt_ids[] = {
> +#ifdef CONFIG_PINMUX_IMX6Q
> +	{ .compatible = "fsl,imx6q-iomuxc", .data = (void *) 
&imx6q_pinctrl_info,
> }, +#endif
> +#ifdef CONFIG_PINMUX_IMX53
> +	{ .compatible = "fsl,imx53-iomuxc", .data = (void *) 
&imx53_pinctrl_info,
> }, +#endif
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, imx_pmx_dt_ids);
> +
> +static int __init imx_pmx_probe(struct platform_device *pdev)
> +{
> +	const struct of_device_id *of_id =
> +			of_match_device(imx_pmx_dt_ids, &pdev->dev);
> +	struct device *dev = &pdev->dev;
> +	struct imx_pmx *ipmx;
> +	struct resource *res;
> +	struct imx_pinctrl_info *info;
> +	resource_size_t res_size;
> +	int ret;
> +
> +	info = of_id->data;
> +	if (!info || !info->pins || !(info->maxpin > info->npins)) {
> +		dev_err(&pdev->dev, "wrong pinctrl info\n");
> +		return -EINVAL;
> +	}
> +	info->dev = &pdev->dev;
> +
> +	/* Create state holders etc for this driver */
> +	ipmx = devm_kzalloc(&pdev->dev, sizeof(*ipmx), GFP_KERNEL);
> +	if (!ipmx)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENOENT;
> +
> +	res_size = resource_size(res);
> +	if (!devm_request_mem_region(dev, res->start, res_size, res->name))
> +		return -EBUSY;
> +
> +	ipmx->virtbase = devm_ioremap_nocache(dev, res->start, res_size);
> +	if (!ipmx->virtbase)
> +		return -EBUSY;
> +
> +	imx_pmx_desc_init(&imx_pmx_desc, info);
> +	ret = imx_pmx_probe_dt(pdev, info);
> +	if (ret) {
> +		dev_err(&pdev->dev, "fail to probe dt properties\n");
> +		return ret;
> +	}
> +
> +	ipmx->pctl = pinctrl_register(&imx_pmx_desc, &pdev->dev, ipmx);
> +	if (!ipmx->pctl) {
> +		dev_err(&pdev->dev, "could not register IMX pinmux driver\n");
> +		return -EINVAL;
> +	}
> +
> +	ipmx->info = info;
> +	ipmx->dev = info->dev;
> +	platform_set_drvdata(pdev, ipmx);
> +
> +	dev_info(&pdev->dev, "initialized IMX pinmux driver\n");
> +
> +	return 0;
> +}
> +
> +static int __exit imx_pmx_remove(struct platform_device *pdev)
> +{
> +	struct imx_pmx *ipmx = platform_get_drvdata(pdev);
> +
> +	pinctrl_unregister(ipmx->pctl);
> +	platform_set_drvdata(pdev, NULL);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver imx_pmx_driver = {
> +	.driver = {
> +		.name = DRIVER_NAME,
> +		.owner = THIS_MODULE,
> +		.of_match_table = imx_pmx_dt_ids,
> +	},
> +	.remove = __exit_p(imx_pmx_remove),
> +};
> +
> +static int __init imx_pmx_init(void)
> +{
> +	return platform_driver_probe(&imx_pmx_driver, imx_pmx_probe);
> +}
> +arch_initcall(imx_pmx_init);
> +
> +static void __exit imx_pmx_exit(void)
> +{
> +	platform_driver_unregister(&imx_pmx_driver);
> +}
> +module_exit(imx_pmx_exit);
> +
> +MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
> +MODULE_DESCRIPTION("IMX Pin Control Driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/pinctrl/pinctrl-imx-core.h
> b/drivers/pinctrl/pinctrl-imx-core.h new file mode 100644
> index 0000000..df69cd0
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-imx-core.h
> @@ -0,0 +1,86 @@
> +/*
> + * IMX pinmux core definitions
> + *
> + * Copyright (C) 2011 Freescale Semiconductor, Inc.
> + * Copyright (C) 2011 Linaro Ltd.
> + *
> + * Author: Dong Aisheng <dong.aisheng@linaro.org>
> + *
> + * 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.
> + */
> +
> +#ifndef __DRIVERS_PINCTRL_PINMUX_IMX_H
> +#define __DRIVERS_PINCTRL_PINMUX_IMX_H
> +
> +/* Supported Pinctrl type */
> +enum imx_pinctrl_type {
> +	IMX53_PINCTRL,
> +	IMX6Q_PINCTRL,
> +};
> +
> +/**
> + * struct imx_pin_group - describes an IMX pin group
> + * @name: the name of this specific pin group
> + * @pins: an array of discrete physical pins used in this group, taken
> + *	from the driver-local pin enumeration space
> + * @num_pins: the number of pins in this group array, i.e. the number of
> + *	elements in .pins so we can iterate over that array
> + * @mux_mode: the mux mode for each pins in this group. The size of this
> + *	array is the same as pins.
> + */
> +struct imx_pin_group {
> +	const char *name;
> +	unsigned int *pins;
> +	unsigned num_pins;
> +	unsigned int *mux_mode;
> +	unsigned num_mux;
> +};
> +
> +/**
> + * struct imx_pmx_func - describes IMX pinmux functions
> + * @name: the name of this specific function
> + * @groups: corresponding pin groups
> + */
> +struct imx_pmx_func {
> +	const char *name;
> +	const char **groups;
> +	unsigned num_groups;
> +};
> +
> +struct imx_pinctrl_info {
> +	struct device *dev;
> +	u32 type;
> +	const struct pinctrl_pin_desc *pins;
> +	unsigned int npins;
> +	unsigned int maxpin;
> +	struct imx_pin_group *groups;
> +	unsigned int ngroups;
> +	struct imx_pmx_func *functions;
> +	unsigned int nfunctions;
> +	u32 mux_offset;
> +};
> +
> +#define IMX_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin)
> +
> +#define IMX_PIN_GROUP(n, p, m)  \
> +	{			\
> +		.name = n,	\
> +		.pins = p,	\
> +		.num_pins = ARRAY_SIZE(p),	\
> +		.mux_mode = m,	\
> +		.num_mux = ARRAY_SIZE(m),	\
> +	}
> +
> +#define IMX_PMX_FUNC(n, g)  \
> +	{			\
> +		.name = n,	\
> +		.groups = g,	\
> +		.num_groups = ARRAY_SIZE(g),	\
> +	}
> +
> +extern struct imx_pinctrl_info imx53_pinctrl_info;
> +extern struct imx_pinctrl_info imx6q_pinctrl_info;
> +#endif /* __DRIVERS_PINCTRL_PINMUX_IMX_H */
> diff --git a/drivers/pinctrl/pinctrl-imx53.c
> b/drivers/pinctrl/pinctrl-imx53.c new file mode 100644
> index 0000000..079b25e
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-imx53.c
> @@ -0,0 +1,443 @@
> +/*
> + * imx53 pinctrl driver based on imx pinmux core
> + *
> + * Copyright (C) 2011 Freescale Semiconductor, Inc.
> + * Copyright (C) 2011 Linaro, Inc.
> + *
> + * Author: Dong Aisheng <dong.aisheng@linaro.org>
> + *
> + * 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/init.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/pinmux.h>
> +
> +#include "pinctrl-imx-core.h"
> +
> +#define IMX53_IOMUXC_MUX_OFFSET 0x20
> +#define IMX53_IOMUXC_MAXPIN	(23*23)
> +
> +enum imx_imx53_pinctrl_pads {
> +	MX53_GPIO_19 = 0,
> +	MX53_KEY_COL0 = 1,
> +	MX53_KEY_ROW0 = 2,
> +	MX53_KEY_COL1 = 3,
> +	MX53_KEY_ROW1 = 4,
> +	MX53_KEY_COL2 = 5,
> +	MX53_KEY_ROW2 = 6,
> +	MX53_KEY_COL3 = 7,
> +	MX53_KEY_ROW3 = 8,
> +	MX53_KEY_COL4 = 9,
> +	MX53_KEY_ROW4 = 10,
> +	MX53_DI0_DISP_CLK = 11,
> +	MX53_DI0_PIN15 = 12,
> +	MX53_DI0_PIN2 = 13,
> +	MX53_DI0_PIN3 = 14,
> +	MX53_DI0_PIN4 = 15,
> +	MX53_DISP0_DAT0 = 16,
> +	MX53_DISP0_DAT1 = 17,
> +	MX53_DISP0_DAT2 = 18,
> +	MX53_DISP0_DAT3 = 19,
> +	MX53_DISP0_DAT4 = 20,
> +	MX53_DISP0_DAT5 = 21,
> +	MX53_DISP0_DAT6 = 22,
> +	MX53_DISP0_DAT7 = 23,
> +	MX53_DISP0_DAT8 = 24,
> +	MX53_DISP0_DAT9 = 25,
> +	MX53_DISP0_DAT10 = 26,
> +	MX53_DISP0_DAT11 = 27,
> +	MX53_DISP0_DAT12 = 28,
> +	MX53_DISP0_DAT13 = 29,
> +	MX53_DISP0_DAT14 = 30,
> +	MX53_DISP0_DAT15 = 31,
> +	MX53_DISP0_DAT16 = 32,
> +	MX53_DISP0_DAT17 = 33,
> +	MX53_DISP0_DAT18 = 34,
> +	MX53_DISP0_DAT19 = 35,
> +	MX53_DISP0_DAT20 = 36,
> +	MX53_DISP0_DAT21 = 37,
> +	MX53_DISP0_DAT22 = 38,
> +	MX53_DISP0_DAT23 = 39,
> +	MX53_CSI0_PIXCLK = 40,
> +	MX53_CSI0_MCLK = 41,
> +	MX53_CSI0_DATA_EN = 42,
> +	MX53_CSI0_VSYNC = 43,
> +	MX53_CSI0_DAT4 = 44,
> +	MX53_CSI0_DAT5 = 45,
> +	MX53_CSI0_DAT6 = 46,
> +	MX53_CSI0_DAT7 = 47,
> +	MX53_CSI0_DAT8 = 48,
> +	MX53_CSI0_DAT9 = 49,
> +	MX53_CSI0_DAT10 = 50,
> +	MX53_CSI0_DAT11 = 51,
> +	MX53_CSI0_DAT12 = 52,
> +	MX53_CSI0_DAT13 = 53,
> +	MX53_CSI0_DAT14 = 54,
> +	MX53_CSI0_DAT15 = 55,
> +	MX53_CSI0_DAT16 = 56,
> +	MX53_CSI0_DAT17 = 57,
> +	MX53_CSI0_DAT18 = 58,
> +	MX53_CSI0_DAT19 = 59,
> +	MX53_EIM_A25 = 60,
> +	MX53_EIM_EB2 = 61,
> +	MX53_EIM_D16 = 62,
> +	MX53_EIM_D17 = 63,
> +	MX53_EIM_D18 = 64,
> +	MX53_EIM_D19 = 65,
> +	MX53_EIM_D20 = 66,
> +	MX53_EIM_D21 = 67,
> +	MX53_EIM_D22 = 68,
> +	MX53_EIM_D23 = 69,
> +	MX53_EIM_EB3 = 70,
> +	MX53_EIM_D24 = 71,
> +	MX53_EIM_D25 = 72,
> +	MX53_EIM_D26 = 73,
> +	MX53_EIM_D27 = 74,
> +	MX53_EIM_D28 = 75,
> +	MX53_EIM_D29 = 76,
> +	MX53_EIM_D30 = 77,
> +	MX53_EIM_D31 = 78,
> +	MX53_EIM_A24 = 79,
> +	MX53_EIM_A23 = 80,
> +	MX53_EIM_A22 = 81,
> +	MX53_EIM_A21 = 82,
> +	MX53_EIM_A20 = 83,
> +	MX53_EIM_A19 = 84,
> +	MX53_EIM_A18 = 85,
> +	MX53_EIM_A17 = 86,
> +	MX53_EIM_A16 = 87,
> +	MX53_EIM_CS0 = 88,
> +	MX53_EIM_CS1 = 89,
> +	MX53_EIM_OE = 90,
> +	MX53_EIM_RW = 91,
> +	MX53_EIM_LBA = 92,
> +	MX53_EIM_EB0 = 93,
> +	MX53_EIM_EB1 = 94,
> +	MX53_EIM_DA0 = 95,
> +	MX53_EIM_DA1 = 96,
> +	MX53_EIM_DA2 = 97,
> +	MX53_EIM_DA3 = 98,
> +	MX53_EIM_DA4 = 99,
> +	MX53_EIM_DA5 = 100,
> +	MX53_EIM_DA6 = 101,
> +	MX53_EIM_DA7 = 102,
> +	MX53_EIM_DA8 = 103,
> +	MX53_EIM_DA9 = 104,
> +	MX53_EIM_DA10 = 105,
> +	MX53_EIM_DA11 = 106,
> +	MX53_EIM_DA12 = 107,
> +	MX53_EIM_DA13 = 108,
> +	MX53_EIM_DA14 = 109,
> +	MX53_EIM_DA15 = 110,
> +	MX53_NANDF_WE_B = 111,
> +	MX53_NANDF_RE_B = 112,
> +	MX53_EIM_WAIT = 113,
> +	MX53_EIM_BCLK = 114,
> +	MX53_LVDS1_TX3_P = 115,
> +	MX53_LVDS1_TX2_P = 116,
> +	MX53_LVDS1_CLK_P = 117,
> +	MX53_LVDS1_TX1_P = 118,
> +	MX53_LVDS1_TX0_P = 119,
> +	MX53_LVDS0_TX3_P = 120,
> +	MX53_LVDS0_CLK_P = 121,
> +	MX53_LVDS0_TX2_P = 122,
> +	MX53_LVDS0_TX1_P = 123,
> +	MX53_LVDS0_TX0_P = 124,
> +	MX53_GPIO_10 = 125,
> +	MX53_GPIO_11 = 126,
> +	MX53_GPIO_12 = 127,
> +	MX53_GPIO_13 = 128,
> +	MX53_GPIO_14 = 129,
> +	MX53_NANDF_CLE = 130,
> +	MX53_NANDF_ALE = 131,
> +	MX53_NANDF_WP_B = 132,
> +	MX53_NANDF_RB0 = 133,
> +	MX53_NANDF_CS0 = 134,
> +	MX53_NANDF_CS1 = 135,
> +	MX53_NANDF_CS2 = 136,
> +	MX53_NANDF_CS3 = 137,
> +	MX53_FEC_MDIO = 138,
> +	MX53_FEC_REF_CLK = 139,
> +	MX53_FEC_RX_ER = 140,
> +	MX53_FEC_CRS_DV = 141,
> +	MX53_FEC_RXD1 = 142,
> +	MX53_FEC_RXD0 = 143,
> +	MX53_FEC_TX_EN = 144,
> +	MX53_FEC_TXD1 = 145,
> +	MX53_FEC_TXD0 = 146,
> +	MX53_FEC_MDC = 147,
> +	MX53_PATA_DIOW = 148,
> +	MX53_PATA_DMACK = 149,
> +	MX53_PATA_DMARQ = 150,
> +	MX53_PATA_BUFFER_EN = 151,
> +	MX53_PATA_INTRQ = 152,
> +	MX53_PATA_DIOR = 153,
> +	MX53_PATA_RESET_B = 154,
> +	MX53_PATA_IORDY = 155,
> +	MX53_PATA_DA_0 = 156,
> +	MX53_PATA_DA_1 = 157,
> +	MX53_PATA_DA_2 = 158,
> +	MX53_PATA_CS_0 = 159,
> +	MX53_PATA_CS_1 = 160,
> +	MX53_PATA_DATA0 = 161,
> +	MX53_PATA_DATA1 = 162,
> +	MX53_PATA_DATA2 = 163,
> +	MX53_PATA_DATA3 = 164,
> +	MX53_PATA_DATA4 = 165,
> +	MX53_PATA_DATA5 = 166,
> +	MX53_PATA_DATA6 = 167,
> +	MX53_PATA_DATA7 = 168,
> +	MX53_PATA_DATA8 = 169,
> +	MX53_PATA_DATA9 = 170,
> +	MX53_PATA_DATA10 = 171,
> +	MX53_PATA_DATA11 = 172,
> +	MX53_PATA_DATA12 = 173,
> +	MX53_PATA_DATA13 = 174,
> +	MX53_PATA_DATA14 = 175,
> +	MX53_PATA_DATA15 = 176,
> +	MX53_SD1_DATA0 = 177,
> +	MX53_SD1_DATA1 = 178,
> +	MX53_SD1_CMD = 179,
> +	MX53_SD1_DATA2 = 180,
> +	MX53_SD1_CLK = 181,
> +	MX53_SD1_DATA3 = 182,
> +	MX53_SD2_CLK = 183,
> +	MX53_SD2_CMD = 184,
> +	MX53_SD2_DATA3 = 185,
> +	MX53_SD2_DATA2 = 186,
> +	MX53_SD2_DATA1 = 187,
> +	MX53_SD2_DATA0 = 188,
> +	MX53_GPIO_0 = 189,
> +	MX53_GPIO_1 = 190,
> +	MX53_GPIO_9 = 191,
> +	MX53_GPIO_3 = 192,
> +	MX53_GPIO_6 = 193,
> +	MX53_GPIO_2 = 194,
> +	MX53_GPIO_4 = 195,
> +	MX53_GPIO_5 = 196,
> +	MX53_GPIO_7 = 197,
> +	MX53_GPIO_8 = 198,
> +	MX53_GPIO_16 = 199,
> +	MX53_GPIO_17 = 200,
> +	MX53_GPIO_18 = 201,
> +};
> +
> +/* Pad names for the pinmux subsystem */
> +static const struct pinctrl_pin_desc imx53_pinctrl_pads[] = {
> +	IMX_PINCTRL_PIN(MX53_GPIO_19),
> +	IMX_PINCTRL_PIN(MX53_KEY_COL0),
> +	IMX_PINCTRL_PIN(MX53_KEY_ROW0),
> +	IMX_PINCTRL_PIN(MX53_KEY_COL1),
> +	IMX_PINCTRL_PIN(MX53_KEY_ROW1),
> +	IMX_PINCTRL_PIN(MX53_KEY_COL2),
> +	IMX_PINCTRL_PIN(MX53_KEY_ROW2),
> +	IMX_PINCTRL_PIN(MX53_KEY_COL3),
> +	IMX_PINCTRL_PIN(MX53_KEY_ROW3),
> +	IMX_PINCTRL_PIN(MX53_KEY_COL4),
> +	IMX_PINCTRL_PIN(MX53_KEY_ROW4),
> +	IMX_PINCTRL_PIN(MX53_DI0_DISP_CLK),
> +	IMX_PINCTRL_PIN(MX53_DI0_PIN15),
> +	IMX_PINCTRL_PIN(MX53_DI0_PIN2),
> +	IMX_PINCTRL_PIN(MX53_DI0_PIN3),
> +	IMX_PINCTRL_PIN(MX53_DI0_PIN4),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT0),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT1),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT2),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT3),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT4),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT5),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT6),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT7),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT8),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT9),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT10),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT11),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT12),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT13),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT14),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT15),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT16),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT17),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT18),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT19),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT20),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT21),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT22),
> +	IMX_PINCTRL_PIN(MX53_DISP0_DAT23),
> +	IMX_PINCTRL_PIN(MX53_CSI0_PIXCLK),
> +	IMX_PINCTRL_PIN(MX53_CSI0_MCLK),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DATA_EN),
> +	IMX_PINCTRL_PIN(MX53_CSI0_VSYNC),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT4),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT5),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT6),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT7),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT8),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT9),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT10),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT11),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT12),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT13),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT14),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT15),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT16),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT17),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT18),
> +	IMX_PINCTRL_PIN(MX53_CSI0_DAT19),
> +	IMX_PINCTRL_PIN(MX53_EIM_A25),
> +	IMX_PINCTRL_PIN(MX53_EIM_EB2),
> +	IMX_PINCTRL_PIN(MX53_EIM_D16),
> +	IMX_PINCTRL_PIN(MX53_EIM_D17),
> +	IMX_PINCTRL_PIN(MX53_EIM_D18),
> +	IMX_PINCTRL_PIN(MX53_EIM_D19),
> +	IMX_PINCTRL_PIN(MX53_EIM_D20),
> +	IMX_PINCTRL_PIN(MX53_EIM_D21),
> +	IMX_PINCTRL_PIN(MX53_EIM_D22),
> +	IMX_PINCTRL_PIN(MX53_EIM_D23),
> +	IMX_PINCTRL_PIN(MX53_EIM_EB3),
> +	IMX_PINCTRL_PIN(MX53_EIM_D24),
> +	IMX_PINCTRL_PIN(MX53_EIM_D25),
> +	IMX_PINCTRL_PIN(MX53_EIM_D26),
> +	IMX_PINCTRL_PIN(MX53_EIM_D27),
> +	IMX_PINCTRL_PIN(MX53_EIM_D28),
> +	IMX_PINCTRL_PIN(MX53_EIM_D29),
> +	IMX_PINCTRL_PIN(MX53_EIM_D30),
> +	IMX_PINCTRL_PIN(MX53_EIM_D31),
> +	IMX_PINCTRL_PIN(MX53_EIM_A24),
> +	IMX_PINCTRL_PIN(MX53_EIM_A23),
> +	IMX_PINCTRL_PIN(MX53_EIM_A22),
> +	IMX_PINCTRL_PIN(MX53_EIM_A21),
> +	IMX_PINCTRL_PIN(MX53_EIM_A20),
> +	IMX_PINCTRL_PIN(MX53_EIM_A19),
> +	IMX_PINCTRL_PIN(MX53_EIM_A18),
> +	IMX_PINCTRL_PIN(MX53_EIM_A17),
> +	IMX_PINCTRL_PIN(MX53_EIM_A16),
> +	IMX_PINCTRL_PIN(MX53_EIM_CS0),
> +	IMX_PINCTRL_PIN(MX53_EIM_CS1),
> +	IMX_PINCTRL_PIN(MX53_EIM_OE),
> +	IMX_PINCTRL_PIN(MX53_EIM_RW),
> +	IMX_PINCTRL_PIN(MX53_EIM_LBA),
> +	IMX_PINCTRL_PIN(MX53_EIM_EB0),
> +	IMX_PINCTRL_PIN(MX53_EIM_EB1),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA0),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA1),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA2),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA3),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA4),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA5),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA6),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA7),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA8),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA9),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA10),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA11),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA12),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA13),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA14),
> +	IMX_PINCTRL_PIN(MX53_EIM_DA15),
> +	IMX_PINCTRL_PIN(MX53_NANDF_WE_B),
> +	IMX_PINCTRL_PIN(MX53_NANDF_RE_B),
> +	IMX_PINCTRL_PIN(MX53_EIM_WAIT),
> +	IMX_PINCTRL_PIN(MX53_EIM_BCLK),
> +	IMX_PINCTRL_PIN(MX53_LVDS1_TX3_P),
> +	IMX_PINCTRL_PIN(MX53_LVDS1_TX2_P),
> +	IMX_PINCTRL_PIN(MX53_LVDS1_CLK_P),
> +	IMX_PINCTRL_PIN(MX53_LVDS1_TX1_P),
> +	IMX_PINCTRL_PIN(MX53_LVDS1_TX0_P),
> +	IMX_PINCTRL_PIN(MX53_LVDS0_TX3_P),
> +	IMX_PINCTRL_PIN(MX53_LVDS0_CLK_P),
> +	IMX_PINCTRL_PIN(MX53_LVDS0_TX2_P),
> +	IMX_PINCTRL_PIN(MX53_LVDS0_TX1_P),
> +	IMX_PINCTRL_PIN(MX53_LVDS0_TX0_P),
> +	IMX_PINCTRL_PIN(MX53_GPIO_10),
> +	IMX_PINCTRL_PIN(MX53_GPIO_11),
> +	IMX_PINCTRL_PIN(MX53_GPIO_12),
> +	IMX_PINCTRL_PIN(MX53_GPIO_13),
> +	IMX_PINCTRL_PIN(MX53_GPIO_14),
> +	IMX_PINCTRL_PIN(MX53_NANDF_CLE),
> +	IMX_PINCTRL_PIN(MX53_NANDF_ALE),
> +	IMX_PINCTRL_PIN(MX53_NANDF_WP_B),
> +	IMX_PINCTRL_PIN(MX53_NANDF_RB0),
> +	IMX_PINCTRL_PIN(MX53_NANDF_CS0),
> +	IMX_PINCTRL_PIN(MX53_NANDF_CS1),
> +	IMX_PINCTRL_PIN(MX53_NANDF_CS2),
> +	IMX_PINCTRL_PIN(MX53_NANDF_CS3),
> +	IMX_PINCTRL_PIN(MX53_FEC_MDIO),
> +	IMX_PINCTRL_PIN(MX53_FEC_REF_CLK),
> +	IMX_PINCTRL_PIN(MX53_FEC_RX_ER),
> +	IMX_PINCTRL_PIN(MX53_FEC_CRS_DV),
> +	IMX_PINCTRL_PIN(MX53_FEC_RXD1),
> +	IMX_PINCTRL_PIN(MX53_FEC_RXD0),
> +	IMX_PINCTRL_PIN(MX53_FEC_TX_EN),
> +	IMX_PINCTRL_PIN(MX53_FEC_TXD1),
> +	IMX_PINCTRL_PIN(MX53_FEC_TXD0),
> +	IMX_PINCTRL_PIN(MX53_FEC_MDC),
> +	IMX_PINCTRL_PIN(MX53_PATA_DIOW),
> +	IMX_PINCTRL_PIN(MX53_PATA_DMACK),
> +	IMX_PINCTRL_PIN(MX53_PATA_DMARQ),
> +	IMX_PINCTRL_PIN(MX53_PATA_BUFFER_EN),
> +	IMX_PINCTRL_PIN(MX53_PATA_INTRQ),
> +	IMX_PINCTRL_PIN(MX53_PATA_DIOR),
> +	IMX_PINCTRL_PIN(MX53_PATA_RESET_B),
> +	IMX_PINCTRL_PIN(MX53_PATA_IORDY),
> +	IMX_PINCTRL_PIN(MX53_PATA_DA_0),
> +	IMX_PINCTRL_PIN(MX53_PATA_DA_1),
> +	IMX_PINCTRL_PIN(MX53_PATA_DA_2),
> +	IMX_PINCTRL_PIN(MX53_PATA_CS_0),
> +	IMX_PINCTRL_PIN(MX53_PATA_CS_1),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA0),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA1),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA2),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA3),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA4),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA5),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA6),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA7),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA8),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA9),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA10),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA11),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA12),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA13),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA14),
> +	IMX_PINCTRL_PIN(MX53_PATA_DATA15),
> +	IMX_PINCTRL_PIN(MX53_SD1_DATA0),
> +	IMX_PINCTRL_PIN(MX53_SD1_DATA1),
> +	IMX_PINCTRL_PIN(MX53_SD1_CMD),
> +	IMX_PINCTRL_PIN(MX53_SD1_DATA2),
> +	IMX_PINCTRL_PIN(MX53_SD1_CLK),
> +	IMX_PINCTRL_PIN(MX53_SD1_DATA3),
> +	IMX_PINCTRL_PIN(MX53_SD2_CLK),
> +	IMX_PINCTRL_PIN(MX53_SD2_CMD),
> +	IMX_PINCTRL_PIN(MX53_SD2_DATA3),
> +	IMX_PINCTRL_PIN(MX53_SD2_DATA2),
> +	IMX_PINCTRL_PIN(MX53_SD2_DATA1),
> +	IMX_PINCTRL_PIN(MX53_SD2_DATA0),
> +	IMX_PINCTRL_PIN(MX53_GPIO_0),
> +	IMX_PINCTRL_PIN(MX53_GPIO_1),
> +	IMX_PINCTRL_PIN(MX53_GPIO_9),
> +	IMX_PINCTRL_PIN(MX53_GPIO_3),
> +	IMX_PINCTRL_PIN(MX53_GPIO_6),
> +	IMX_PINCTRL_PIN(MX53_GPIO_2),
> +	IMX_PINCTRL_PIN(MX53_GPIO_4),
> +	IMX_PINCTRL_PIN(MX53_GPIO_5),
> +	IMX_PINCTRL_PIN(MX53_GPIO_7),
> +	IMX_PINCTRL_PIN(MX53_GPIO_8),
> +	IMX_PINCTRL_PIN(MX53_GPIO_16),
> +	IMX_PINCTRL_PIN(MX53_GPIO_17),
> +	IMX_PINCTRL_PIN(MX53_GPIO_18),
> +};
> +
> +struct imx_pinctrl_info imx53_pinctrl_info = {
> +	.type = IMX53_PINCTRL,
> +	.pins = imx53_pinctrl_pads,
> +	.npins = ARRAY_SIZE(imx53_pinctrl_pads),
> +	.maxpin = IMX53_IOMUXC_MAXPIN,
> +	.mux_offset = IMX53_IOMUXC_MUX_OFFSET,
> +};
> diff --git a/drivers/pinctrl/pinctrl-imx6q.c
> b/drivers/pinctrl/pinctrl-imx6q.c new file mode 100644
> index 0000000..4c0e29f
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-imx6q.c
> @@ -0,0 +1,433 @@
> +/*
> + * imx6q pinctrl driver based on imx pinmux core
> + *
> + * Copyright (C) 2011 Freescale Semiconductor, Inc.
> + * Copyright (C) 2011 Linaro, Inc.
> + *
> + * Author: Dong Aisheng <dong.aisheng@linaro.org>
> + *
> + * 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/init.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/pinmux.h>
> +
> +#include "pinctrl-imx-core.h"
> +
> +#define IMX6Q_IOMUXC_MUX_OFSSET	0x4c
> +#define IMX6Q_IOMUXC_MAXPIN	(25*25)
> +
> +enum imx6q_pads {
> +	MX6Q_SD2_DAT1 = 0,
> +	MX6Q_SD2_DAT2 = 1,
> +	MX6Q_SD2_DAT0 = 2,
> +	MX6Q_RGMII_TXC = 3,
> +	MX6Q_RGMII_TD0 = 4,
> +	MX6Q_RGMII_TD1 = 5,
> +	MX6Q_RGMII_TD2 = 6,
> +	MX6Q_RGMII_TD3 = 7,
> +	MX6Q_RGMII_RX_CTL = 8,
> +	MX6Q_RGMII_RD0 = 9,
> +	MX6Q_RGMII_TX_CTL = 10,
> +	MX6Q_RGMII_RD1 = 11,
> +	MX6Q_RGMII_RD2 = 12,
> +	MX6Q_RGMII_RD3 = 13,
> +	MX6Q_RGMII_RXC = 14,
> +	MX6Q_EIM_A25 = 15,
> +	MX6Q_EIM_EB2 = 16,
> +	MX6Q_EIM_D16 = 17,
> +	MX6Q_EIM_D17 = 18,
> +	MX6Q_EIM_D18 = 19,
> +	MX6Q_EIM_D19 = 20,
> +	MX6Q_EIM_D20 = 21,
> +	MX6Q_EIM_D21 = 22,
> +	MX6Q_EIM_D22 = 23,
> +	MX6Q_EIM_D23 = 24,
> +	MX6Q_EIM_EB3 = 25,
> +	MX6Q_EIM_D24 = 26,
> +	MX6Q_EIM_D25 = 27,
> +	MX6Q_EIM_D26 = 28,
> +	MX6Q_EIM_D27 = 29,
> +	MX6Q_EIM_D28 = 30,
> +	MX6Q_EIM_D29 = 31,
> +	MX6Q_EIM_D30 = 32,
> +	MX6Q_EIM_D31 = 33,
> +	MX6Q_EIM_A24 = 34,
> +	MX6Q_EIM_A23 = 35,
> +	MX6Q_EIM_A22 = 36,
> +	MX6Q_EIM_A21 = 37,
> +	MX6Q_EIM_A20 = 38,
> +	MX6Q_EIM_A19 = 39,
> +	MX6Q_EIM_A18 = 40,
> +	MX6Q_EIM_A17 = 41,
> +	MX6Q_EIM_A16 = 42,
> +	MX6Q_EIM_CS0 = 43,
> +	MX6Q_EIM_CS1 = 44,
> +	MX6Q_EIM_OE = 45,
> +	MX6Q_EIM_RW = 46,
> +	MX6Q_EIM_LBA = 47,
> +	MX6Q_EIM_EB0 = 48,
> +	MX6Q_EIM_EB1 = 49,
> +	MX6Q_EIM_DA0 = 50,
> +	MX6Q_EIM_DA1 = 51,
> +	MX6Q_EIM_DA2 = 52,
> +	MX6Q_EIM_DA3 = 53,
> +	MX6Q_EIM_DA4 = 54,
> +	MX6Q_EIM_DA5 = 55,
> +	MX6Q_EIM_DA6 = 56,
> +	MX6Q_EIM_DA7 = 57,
> +	MX6Q_EIM_DA8 = 58,
> +	MX6Q_EIM_DA9 = 59,
> +	MX6Q_EIM_DA10 = 60,
> +	MX6Q_EIM_DA11 = 61,
> +	MX6Q_EIM_DA12 = 62,
> +	MX6Q_EIM_DA13 = 63,
> +	MX6Q_EIM_DA14 = 64,
> +	MX6Q_EIM_DA15 = 65,
> +	MX6Q_EIM_WAIT = 66,
> +	MX6Q_EIM_BCLK = 67,
> +	MX6Q_DI0_DISP_CLK = 68,
> +	MX6Q_DI0_PIN15 = 69,
> +	MX6Q_DI0_PIN2 = 70,
> +	MX6Q_DI0_PIN3 = 71,
> +	MX6Q_DI0_PIN4 = 72,
> +	MX6Q_DISP0_DAT0 = 73,
> +	MX6Q_DISP0_DAT1 = 74,
> +	MX6Q_DISP0_DAT2 = 75,
> +	MX6Q_DISP0_DAT3 = 76,
> +	MX6Q_DISP0_DAT4 = 77,
> +	MX6Q_DISP0_DAT5 = 78,
> +	MX6Q_DISP0_DAT6 = 79,
> +	MX6Q_DISP0_DAT7 = 80,
> +	MX6Q_DISP0_DAT8 = 81,
> +	MX6Q_DISP0_DAT9 = 82,
> +	MX6Q_DISP0_DAT10 = 83,
> +	MX6Q_DISP0_DAT11 = 84,
> +	MX6Q_DISP0_DAT12 = 85,
> +	MX6Q_DISP0_DAT13 = 86,
> +	MX6Q_DISP0_DAT14 = 87,
> +	MX6Q_DISP0_DAT15 = 88,
> +	MX6Q_DISP0_DAT16 = 89,
> +	MX6Q_DISP0_DAT17 = 90,
> +	MX6Q_DISP0_DAT18 = 91,
> +	MX6Q_DISP0_DAT19 = 92,
> +	MX6Q_DISP0_DAT20 = 93,
> +	MX6Q_DISP0_DAT21 = 94,
> +	MX6Q_DISP0_DAT22 = 95,
> +	MX6Q_DISP0_DAT23 = 96,
> +	MX6Q_ENET_MDIO = 97,
> +	MX6Q_ENET_REF_CLK = 98,
> +	MX6Q_ENET_RX_ER = 99,
> +	MX6Q_ENET_CRS_DV = 100,
> +	MX6Q_ENET_RXD1 = 101,
> +	MX6Q_ENET_RXD0 = 102,
> +	MX6Q_ENET_TX_EN = 103,
> +	MX6Q_ENET_TXD1 = 104,
> +	MX6Q_ENET_TXD0 = 105,
> +	MX6Q_ENET_MDC = 106,
> +	MX6Q_KEY_COL0 = 107,
> +	MX6Q_KEY_ROW0 = 108,
> +	MX6Q_KEY_COL1 = 109,
> +	MX6Q_KEY_ROW1 = 110,
> +	MX6Q_KEY_COL2 = 111,
> +	MX6Q_KEY_ROW2 = 112,
> +	MX6Q_KEY_COL3 = 113,
> +	MX6Q_KEY_ROW3 = 114,
> +	MX6Q_KEY_COL4 = 115,
> +	MX6Q_KEY_ROW4 = 116,
> +	MX6Q_GPIO_0 = 117,
> +	MX6Q_GPIO_1 = 118,
> +	MX6Q_GPIO_9 = 119,
> +	MX6Q_GPIO_3 = 120,
> +	MX6Q_GPIO_6 = 121,
> +	MX6Q_GPIO_2 = 122,
> +	MX6Q_GPIO_4 = 123,
> +	MX6Q_GPIO_5 = 124,
> +	MX6Q_GPIO_7 = 125,
> +	MX6Q_GPIO_8 = 126,
> +	MX6Q_GPIO_16 = 127,
> +	MX6Q_GPIO_17 = 128,
> +	MX6Q_GPIO_18 = 129,
> +	MX6Q_GPIO_19 = 130,
> +	MX6Q_CSI0_PIXCLK = 131,
> +	MX6Q_CSI0_MCLK = 132,
> +	MX6Q_CSI0_DATA_EN = 133,
> +	MX6Q_CSI0_VSYNC = 134,
> +	MX6Q_CSI0_DAT4 = 135,
> +	MX6Q_CSI0_DAT5 = 136,
> +	MX6Q_CSI0_DAT6 = 137,
> +	MX6Q_CSI0_DAT7 = 138,
> +	MX6Q_CSI0_DAT8 = 139,
> +	MX6Q_CSI0_DAT9 = 140,
> +	MX6Q_CSI0_DAT10 = 141,
> +	MX6Q_CSI0_DAT11 = 142,
> +	MX6Q_CSI0_DAT12 = 143,
> +	MX6Q_CSI0_DAT13 = 144,
> +	MX6Q_CSI0_DAT14 = 145,
> +	MX6Q_CSI0_DAT15 = 146,
> +	MX6Q_CSI0_DAT16 = 147,
> +	MX6Q_CSI0_DAT17 = 148,
> +	MX6Q_CSI0_DAT18 = 149,
> +	MX6Q_CSI0_DAT19 = 150,
> +	MX6Q_SD3_DAT7 = 151,
> +	MX6Q_SD3_DAT6 = 152,
> +	MX6Q_SD3_DAT5 = 153,
> +	MX6Q_SD3_DAT4 = 154,
> +	MX6Q_SD3_CMD = 155,
> +	MX6Q_SD3_CLK = 156,
> +	MX6Q_SD3_DAT0 = 157,
> +	MX6Q_SD3_DAT1 = 158,
> +	MX6Q_SD3_DAT2 = 159,
> +	MX6Q_SD3_DAT3 = 160,
> +	MX6Q_SD3_RST = 161,
> +	MX6Q_NANDF_CLE = 162,
> +	MX6Q_NANDF_ALE = 163,
> +	MX6Q_NANDF_WP_B = 164,
> +	MX6Q_NANDF_RB0 = 165,
> +	MX6Q_NANDF_CS0 = 166,
> +	MX6Q_NANDF_CS1 = 167,
> +	MX6Q_NANDF_CS2 = 168,
> +	MX6Q_NANDF_CS3 = 169,
> +	MX6Q_SD4_CMD = 170,
> +	MX6Q_SD4_CLK = 171,
> +	MX6Q_NANDF_D0 = 172,
> +	MX6Q_NANDF_D1 = 173,
> +	MX6Q_NANDF_D2 = 174,
> +	MX6Q_NANDF_D3 = 175,
> +	MX6Q_NANDF_D4 = 176,
> +	MX6Q_NANDF_D5 = 177,
> +	MX6Q_NANDF_D6 = 178,
> +	MX6Q_NANDF_D7 = 179,
> +	MX6Q_SD4_DAT0 = 180,
> +	MX6Q_SD4_DAT1 = 181,
> +	MX6Q_SD4_DAT2 = 182,
> +	MX6Q_SD4_DAT3 = 183,
> +	MX6Q_SD4_DAT4 = 184,
> +	MX6Q_SD4_DAT5 = 185,
> +	MX6Q_SD4_DAT6 = 186,
> +	MX6Q_SD4_DAT7 = 187,
> +	MX6Q_SD1_DAT1 = 188,
> +	MX6Q_SD1_DAT0 = 189,
> +	MX6Q_SD1_DAT3 = 190,
> +	MX6Q_SD1_CMD = 191,
> +	MX6Q_SD1_DAT2 = 192,
> +	MX6Q_SD1_CLK = 193,
> +	MX6Q_SD2_CLK = 194,
> +	MX6Q_SD2_CMD = 195,
> +	MX6Q_SD2_DAT3 = 196
> +};
> +
> +/* Pad names for the pinmux subsystem */
> +static const struct pinctrl_pin_desc imx6q_pinctrl_pads[] = {
> +	IMX_PINCTRL_PIN(MX6Q_SD2_DAT1),
> +	IMX_PINCTRL_PIN(MX6Q_SD2_DAT2),
> +	IMX_PINCTRL_PIN(MX6Q_SD2_DAT0),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_TXC),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_TD0),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_TD1),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_TD2),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_TD3),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_RX_CTL),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_RD0),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_TX_CTL),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_RD1),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_RD2),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_RD3),
> +	IMX_PINCTRL_PIN(MX6Q_RGMII_RXC),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A25),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_EB2),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D16),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D17),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D18),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D19),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D20),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D21),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D22),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D23),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_EB3),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D24),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D25),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D26),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D27),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D28),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D29),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D30),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_D31),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A24),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A23),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A22),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A21),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A20),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A19),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A18),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A17),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_A16),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_CS0),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_CS1),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_OE),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_RW),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_LBA),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_EB0),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_EB1),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA0),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA1),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA2),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA3),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA4),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA5),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA6),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA7),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA8),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA9),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA10),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA11),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA12),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA13),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA14),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_DA15),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_WAIT),
> +	IMX_PINCTRL_PIN(MX6Q_EIM_BCLK),
> +	IMX_PINCTRL_PIN(MX6Q_DI0_DISP_CLK),
> +	IMX_PINCTRL_PIN(MX6Q_DI0_PIN15),
> +	IMX_PINCTRL_PIN(MX6Q_DI0_PIN2),
> +	IMX_PINCTRL_PIN(MX6Q_DI0_PIN3),
> +	IMX_PINCTRL_PIN(MX6Q_DI0_PIN4),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT0),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT1),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT2),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT3),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT4),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT5),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT6),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT7),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT8),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT9),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT10),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT11),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT12),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT13),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT14),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT15),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT16),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT17),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT18),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT19),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT20),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT21),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT22),
> +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT23),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_MDIO),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_REF_CLK),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_RX_ER),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_CRS_DV),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_RXD1),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_RXD0),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_TX_EN),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_TXD1),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_TXD0),
> +	IMX_PINCTRL_PIN(MX6Q_ENET_MDC),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_COL0),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW0),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_COL1),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW1),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_COL2),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW2),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_COL3),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW3),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_COL4),
> +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW4),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_0),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_1),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_9),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_3),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_6),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_2),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_4),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_5),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_7),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_8),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_16),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_17),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_18),
> +	IMX_PINCTRL_PIN(MX6Q_GPIO_19),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_PIXCLK),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_MCLK),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DATA_EN),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_VSYNC),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT4),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT5),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT6),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT7),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT8),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT9),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT10),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT11),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT12),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT13),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT14),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT15),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT16),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT17),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT18),
> +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT19),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT7),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT6),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT5),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT4),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_CMD),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_CLK),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT0),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT1),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT2),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT3),
> +	IMX_PINCTRL_PIN(MX6Q_SD3_RST),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_CLE),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_ALE),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_WP_B),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_RB0),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_CS0),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_CS1),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_CS2),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_CS3),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_CMD),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_CLK),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_D0),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_D1),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_D2),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_D3),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_D4),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_D5),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_D6),
> +	IMX_PINCTRL_PIN(MX6Q_NANDF_D7),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT0),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT1),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT2),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT3),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT4),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT5),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT6),
> +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT7),
> +	IMX_PINCTRL_PIN(MX6Q_SD1_DAT1),
> +	IMX_PINCTRL_PIN(MX6Q_SD1_DAT0),
> +	IMX_PINCTRL_PIN(MX6Q_SD1_DAT3),
> +	IMX_PINCTRL_PIN(MX6Q_SD1_CMD),
> +	IMX_PINCTRL_PIN(MX6Q_SD1_DAT2),
> +	IMX_PINCTRL_PIN(MX6Q_SD1_CLK),
> +	IMX_PINCTRL_PIN(MX6Q_SD2_CLK),
> +	IMX_PINCTRL_PIN(MX6Q_SD2_CMD),
> +	IMX_PINCTRL_PIN(MX6Q_SD2_DAT3),
> +};
> +
> +struct imx_pinctrl_info imx6q_pinctrl_info = {
> +	.type = IMX6Q_PINCTRL,
> +	.pins = imx6q_pinctrl_pads,
> +	.npins = ARRAY_SIZE(imx6q_pinctrl_pads),
> +	.maxpin = IMX6Q_IOMUXC_MAXPIN,
> +	.mux_offset = IMX6Q_IOMUXC_MUX_OFSSET,
> +};

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
  2011-12-20 17:40 ` [RFC PATCH v3 1/5] dt: add of_get_child_count helper function Dong Aisheng
  2011-12-20 18:35   ` Rob Herring
  2011-12-20 19:47   ` Marek Vasut
@ 2011-12-20 23:58   ` Stephen Warren
  2011-12-21  3:18     ` Dong Aisheng-B29396
  2 siblings, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2011-12-20 23:58 UTC (permalink / raw)
  To: Dong Aisheng, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

Dong Aisheng wrote at Tuesday, December 20, 2011 10:41 AM:
> From: Dong Aisheng <dong.aisheng@linaro.org>
> 
> Currently most code to get child count in kernel are almost same,
> add a helper to implement this function for dt to use.

> diff --git a/include/linux/of.h b/include/linux/of.h

> +static inline int of_get_child_count(const struct device_node *np)
> +{
> +	return -ENOSYS;
> +}

Wouldn't it be better to return 0 here? -ENOSYS would be fine if the
function returned an error code, but it's really returning a count, and
other "dummy" functions that return data return 0/NULL already. This
would also allow you to just use the value directly in all cases rather
than having to check for a < 0 error case.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-20 17:40 ` [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings Dong Aisheng
  2011-12-20 19:48   ` Marek Vasut
@ 2011-12-21  0:39   ` Stephen Warren
  2011-12-22  8:18     ` Dong Aisheng-B29396
  2012-01-01 14:07   ` Linus Walleij
  2 siblings, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2011-12-21  0:39 UTC (permalink / raw)
  To: Dong Aisheng, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

Dong Aisheng wrote at Tuesday, December 20, 2011 10:41 AM:
> This patch provies a common API for driver to use to register pinmux
> mappings from dts file. It is needed for dt support.

Dong,

Thanks for providing a concrete binding to get discussion started. I had
intended to do this myself, but got side-tracked on other things.

I'll comment exclusively on the documentation in this patch, since any
changes there will require the code to be changed.

> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> +The pin control subsystem
> +
> +The pin control subsystem provides a common API to support parsing pinmux
> +mappings data from device tree. Each board dts file should provide a device
> +node of which all the child nodes are the corresponding pinmux mappings.

So, the binding you propose seems very reasonable from the point-of-view
of the Linux pinctrl subsystem. However, it violates basic device tree
philosophy in a few ways. Some background:

Device tree is supposed to be a pure representation of hardware, not the
software that runs on it. This means a couple of things: (a) the nodes
in the DT generally match 1:1 with specific HW on the board (b) the
design of the bindings should be justifiable given HW datasheets without
any reference to specific operating systems or software driver design
(c) the DT should be useful to all operating systems that run on the HW;
there should be no "DT for Linux", "DT for FreeBSD", "DT for Windows".
Hence, I see a few problems with this binding:

a) The binding is documented as being for the pinctrl subsystem, rather
than for pinmux hardware.

b) The top-level node ("imx6q-sabreauto-map" below) is not tied to any
particular piece of hardware (no compatible flag, not reg property etc.)

c) The design of the binding is very much derived from the design of the
pinctrl subsystem's internal data structures. This isn't necessarily bad,
since in general SW data structures might be very closely related to how
HW is put together. In this case though, the binding seems very SW oriented.

> +The required properties for pinmux mapping are:
> +- map-name: the name of this specific map entry
> +- clk-dev-name: the name of the device controlling this specific mapping
> +- funcion: a function in the driver to use for this mapping
> +
> +Optional properties:
> +- group: a certain specific pin group to activate for the function
> +- dev-name: the name of the device using this specific mapping
> +- hog-on-boot: indicate wether hog the mappings(do not need to specify value)
> +
> +Examples:
> +
> +pinmux: imx6q-sabreauto-map {

Here we have an all-encompassing standalone "pinctrl mapping table" node.
If we continue to have such an all-encompassing table, it should really
be part of (a child of) the pinmux HW's node in order to tie it directly
to the HW, rather than standing out as a HW concept. So, perhaps something
more like:

iomuxc@020e0000 {
    compatible = "fsl,imx6-pinmux";
    usage { // I can't think of a good name for the table right now
        sd4 {
        };
        sd3 {
        };
        ...
    };
};

Others have suggested that having this all-encompassing table isn't the
correct approach, and instead, it should be split into chunks that are
co-located with the devices that use the pinmux:

sdhci@1000 {
    compatible = "...";
    regs = <...>;
    pinmux = <&pmx>;
    pinmux-usage = {
        // Some representation of the pins/groups/functions used
        // by just this HW block.
    };
};
sdhci@2000 {
    compatible = "...";
    regs = <...>;
    pinmux = <&pmx>;
    pinmux-usage = {
        // Some representation of the pins/groups/functions used
        // by just this HW block.
    };
};

The latter probably is a little more idiomatic, although I haven't seen
or thought through any details on what goes inside such a "pinmux-usage"
node yet.

> +	map-sd4 {
> +		map-name = "usdhc4";

I don't think that field is needed; I'd suggest just using the name of
the DT node containing the entry (which could be renamed to your desired
names)

> +		ctrl-dev-name = "20e0000.iomuxc";
...
> +		dev-name = "219c000.usdhc";

That name is Linux-specific. Instead of using device names, we should
use phandle references, e.g. see the "dev" property below:

sdhci1: sdhci@1000 {
...
};
sdhci2: sdhci@1000 {
...
};
iomuxc@020e0000 {
    compatible = "fsl,imx6-pinmux";
    usage {
        sd4 {
            dev = <&sdhci1>;
        };
        sd3 {
            dev = <&sdhci2>;
        };
        ...
    };
};

(in the above, your ctrl-dev-name would be implied to be iomuxc@020e0000
since the table is part of that pinctrl device's node)

> +		function = "sd4";

Here it would be nice to use an integer instead. However, putting lots
of opaque integers in the device tree is going to be ripe for mistakes.
It's a real pity that dtc doesn't have a way of doing named integer
constants, so this could be re-written as e.g.:

SoC .dtsi file:

/define/ TEGRA_MUX_FUNC_SD4 234

Board .dts file:

function = <TEGRA_MUX_FUNC_SD4>;

Without that feature, using strings here seems the only reasonable thing
to do.

We also need to consider compatibility and extensibility. A DT binding
is an ABI between the kernel and whatever is providing it, and so we
need to be able to maintain and extend it in a compatible fashion, just
like the user-space syscall ABI. Now it's true that the .dts files are
currently part of the kernel source tree and can be rev'd in sync with
kernel changes, but that may not always be the case moving forward.

In other words, taking a board with an old device tree embedded into
Flash and running a new kernel using that device tree should work just
like running the original kernel did.

There are a couple of current active areas of change in the pinctrl
subsystem that impact this:

* Pin configuration is being added. We probably need to add the data to
configure pin config into the mapping table in the kernel, or some
parallel table.

* Support for pins being in multiple states (active, suspend, unused,
...) is being added to pinctrl. We need to be able to represent this in
DT too.

(and yes I know I wrote that from a Linux pinctrl SW perspective, but
the concepts apply to HW!)

To support this, we may just be able to add more fields to any mapping
table entries e.g. to describe pin config setup alongside mux setup.
It'd probably be a good idea to add some kind of "type" field to the
table entries though, so that we can transparently add new types in
the future, much like compatible does for HW nodes.

iomuxc@020e0000 {
    compatible = "fsl,imx6-pinmux";
    usage {
        sd4 {
            type = <0>; // 0 == mux setting
            dev = <&sdhci1>;
        };
        sd3 {
            type = <0>; // 0 == mux setting
            dev = <&sdhci2>;
        };
        foo {
            type = <1>; // 1 == pin config?
            dev = <&sdhci2>;
            pull-up;
            tri-state;
            ...
        };
        ...
    };
};

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
  2011-12-20 18:35   ` Rob Herring
@ 2011-12-21  2:56     ` Dong Aisheng-B29396
  2012-01-01 13:58       ` Linus Walleij
  0 siblings, 1 reply; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2011-12-21  2:56 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-kernel, linux-arm-kernel, linus.walleij, s.hauer,
	Guo Shawn-R65073, kernel, grant.likely, devicetree-discuss, cjb,
	w.sang

> -----Original Message-----
> From: Rob Herring [mailto:robherring2@gmail.com]
> Sent: Wednesday, December 21, 2011 2:35 AM
> To: Dong Aisheng-B29396
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> linus.walleij@stericsson.com; s.hauer@pengutronix.de; Guo Shawn-R65073;
> kernel@pengutronix.de; grant.likely@secretlab.ca; devicetree-
> discuss@lists.ozlabs.org; cjb@laptop.org; w.sang@pengutronix.de
> Subject: Re: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
> Importance: High
> 
> On 12/20/2011 11:40 AM, Dong Aisheng wrote:
> > From: Dong Aisheng <dong.aisheng@linaro.org>
> >
> > Currently most code to get child count in kernel are almost same, add
> > a helper to implement this function for dt to use.
> >
> > ---
> > Changes v1->v2:
> >  * change the name from of_get_child_number to of_get_child_count
> >
> > Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> > Cc: Grant Likely <grant.likely@secretlab.ca>
> > Cc: Rob Herring <rob.herring@calxeda.com>
> 
> I assume you want this to go in with the rest of the series? If not, let me know.
> 
> Acked-by: Rob Herring <rob.herring@calxeda.com>
> 
> Rob
>
Yes, since other patches in this series depend on this patch.
Thanks for the review.

Regards
Dong Aisheng 
> > ---
> >  include/linux/of.h |   16 ++++++++++++++++
> >  1 files changed, 16 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/linux/of.h b/include/linux/of.h index
> > 4948552..d0d91a1 100644
> > --- a/include/linux/of.h
> > +++ b/include/linux/of.h
> > @@ -189,6 +189,17 @@ extern struct device_node *of_get_next_child(const struct
> device_node *node,
> >  	for (child = of_get_next_child(parent, NULL); child != NULL; \
> >  	     child = of_get_next_child(parent, child))
> >
> > +static inline int of_get_child_count(const struct device_node *np) {
> > +	struct device_node *child = NULL;
> > +	int num = 0;
> > +
> > +	while ((child = of_get_next_child(np, child)))
> > +		num++;
> > +
> > +	return num;
> > +}
> > +
> >  extern struct device_node *of_find_node_with_property(
> >  	struct device_node *from, const char *prop_name);  #define
> > for_each_node_with_property(dn, prop_name) \ @@ -262,6 +273,11 @@
> > static inline bool of_have_populated_dt(void)  #define
> > for_each_child_of_node(parent, child) \
> >  	while (0)
> >
> > +static inline int of_get_child_count(const struct device_node *np) {
> > +	return -ENOSYS;
> > +}
> > +
> >  static inline int of_device_is_compatible(const struct device_node *device,
> >  					  const char *name)
> >  {



^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2011-12-20 19:50   ` Marek Vasut
@ 2011-12-21  3:09     ` Dong Aisheng-B29396
  0 siblings, 0 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2011-12-21  3:09 UTC (permalink / raw)
  To: Marek Vasut, linux-arm-kernel
  Cc: linux-kernel, linus.walleij, s.hauer, w.sang, rob.herring,
	grant.likely, kernel, cjb, devicetree-discuss, Guo Shawn-R65073

> -----Original Message-----
> From: Marek Vasut [mailto:marek.vasut@gmail.com]
> Sent: Wednesday, December 21, 2011 3:50 AM
> To: linux-arm-kernel@lists.infradead.org
> Cc: Dong Aisheng-B29396; linux-kernel@vger.kernel.org;
> linus.walleij@stericsson.com; s.hauer@pengutronix.de; w.sang@pengutronix.de;
> rob.herring@calxeda.com; grant.likely@secretlab.ca; kernel@pengutronix.de;
> cjb@laptop.org; devicetree-discuss@lists.ozlabs.org; Guo Shawn-R65073
> Subject: Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
> Importance: High
> 
> > From: Dong Aisheng <dong.aisheng@linaro.org>
> >
> > The driver contains the initial support for imx53 and imx6q.
> >
> > Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> > Cc: Linus Walleij <linus.walleij@linaro.org>
> > Cc: Sascha Hauer <s.hauer@pengutronix.de>
> > Cc: Shawn Guo <shanw.guo@freescale.com>
> > Cc: Grant Likely <grant.likely@secretlab.ca>
> > Cc: Rob Herring <rob.herring@calxeda.com>
> >
> 
> Is this imx or mx6q/mx53 ?
> 
It is a common driver and it is intended to support all imx-based
pinctrl driver in the future.
And it includes initial imx53&imx6q support to show as an example.
Maybe too many things included. :-)

> > ---
> > ChangeLog v2->v3:
> > - binding pinmux mappings via pinctrl core API
> > - follow the dt convention to use dash '-' for property name
> >
> > ChangeLog v1->v2:
> > - add basic binding from device tree
> > ---
> >  .../devicetree/bindings/pinctrl/pinctrl-imx.txt    |   59 +++
> >  drivers/pinctrl/Kconfig                            |   20 +
> >  drivers/pinctrl/Makefile                           |    3 +
> >  drivers/pinctrl/pinctrl-imx-core.c                 |  450
> > ++++++++++++++++++++ drivers/pinctrl/pinctrl-imx-core.h                 |
> >  86 ++++
> >  drivers/pinctrl/pinctrl-imx53.c                    |  443
> > +++++++++++++++++++ drivers/pinctrl/pinctrl-imx6q.c                    |
> > 433 +++++++++++++++++++ 7 files changed, 1494 insertions(+), 0
> > deletions(-)
> >  create mode 100644
> > Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt create mode
> > 100644 drivers/pinctrl/pinctrl-imx-core.c
> >  create mode 100644 drivers/pinctrl/pinctrl-imx-core.h
> >  create mode 100644 drivers/pinctrl/pinctrl-imx53.c  create mode
> > 100644 drivers/pinctrl/pinctrl-imx6q.c
> >
> > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt
> > b/Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt new file
> > mode
> > 100644
> > index 0000000..e45d745
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-imx.txt
> > @@ -0,0 +1,59 @@
> > +* Freescale IOMUX Controller (IOMUXC) for i.MX
> > +
> > +The IOMUX Controller (IOMUXC), together with the IOMUX, enables the
> > +IC to share one PAD to several functional blocks. The sharing is done
> > +by multiplexing the PAD input/output signals. For each PAD there are
> > +up to
> > +8 muxing options (called ALT modes). Since different modules require
> > +different PAD settings (like pull up, keeper, etc) the IOMUXC
> > +controls also the PAD settings parameters.
> > +
> > +Required properties:
> > +- compatible : Should be "fsl,<chip>-iomuxc"
> > +- reg : Should contain IOMUXC registers location and length
> > +- fsl,pinmux-map: phandle of pinmux mappings. Refer to pinctrl.txt
> > +for
> > +  detailed format.
> > +- child nodes containing pinmux data
> > +  Each child node corresponds to a specific pinmux function and the
> > required +  properties of the pinmux function are:
> > +  - func-name: the name of a specific function
> > +  - grp-name: the name of a group pins correspding to this function
> > +  - grp-pins: the list of pins for the group of grp-name
> > +  - num-pins: the pins number of grp-pins list
> > +  - grp-mux: the corresponding mux mode list for grp-pins.
> > +    Each pin in the grp-pins should have a corresponding mux mode for the
> > +    specific function of func-name.
> > +  - num-numx: the mux number of grp-mux list
> > +
> > +Examples:
> > +
> > +pinmux: imx6q-sabreauto-map {
> > +	map-sd4 {
> > +		map-name = "usdhc4";
> > +		ctrl-dev-name = "20e0000.iomuxc";
> > +		function = "sd4";
> > +		dev-name = "219c000.usdhc";
> > +	};
> > +};
> > +
> > +iomuxc@020e0000 {
> > +	compatible = "fsl,imx6q-iomuxc";
> > +	reg = <0x020e0000 0x4000>;
> > +	fsl,pinmux-map = <&pinmux>;
> > +	pinmux_uart4 {
> > +		func-name = "uart4";
> > +		grp-name = "uart4grp";
> > +		grp-pins = <107 108>;
> > +		num-pins = <2>;
> > +		grp-mux = <4 4>;
> > +		num-mux = <2>;
> > +	};
> > +
> > +	pinmux_sd4 {
> > +		func-name = "sd4";
> > +		grp-name = "sd4grp";
> > +		grp-pins = <170 171 180 181 182 183 184 185 186 187>;
> > +		num-pins = <10>;
> > +		grp-mux = <0 0 1 1 1 1 1 1 1 1>;
> > +		num-mux = <10>;
> > +	};
> > +};
> > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index
> > c63c721..f65bf5a 100644
> > --- a/drivers/pinctrl/Kconfig
> > +++ b/drivers/pinctrl/Kconfig
> > @@ -23,6 +23,26 @@ config DEBUG_PINCTRL
> >  	help
> >  	  Say Y here to add some extra checks and diagnostics to PINCTRL calls.
> >
> > +config PINCTRL_IMX
> > +	bool "Freescale IMX core pinctrl driver"
> > +	depends on ARCH_MXC
> > +
> > +config PINCTRL_IMX53
> > +	bool "IMX53 pinctrl driver"
> > +	depends on SOC_IMX53
> > +	select PINMUX
> > +	select PINCTRL_IMX
> > +	help
> > +	  Say Y here to enable the imx53 pinctrl driver
> > +
> > +config PINCTRL_IMX6Q
> > +	bool "IMX6Q pinctrl driver"
> > +	depends on SOC_IMX6Q
> > +	select PINMUX
> > +	select PINCTRL_IMX
> > +	help
> > +	  Say Y here to enable the imx6q pinctrl driver
> > +
> >  config PINMUX_SIRF
> >  	bool "CSR SiRFprimaII pinmux driver"
> >  	depends on ARCH_PRIMA2
> > diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index
> > c046f78..cf85edc 100644
> > --- a/drivers/pinctrl/Makefile
> > +++ b/drivers/pinctrl/Makefile
> > @@ -5,6 +5,9 @@ ccflags-$(CONFIG_DEBUG_PINCTRL)	+= -DDEBUG
> >  obj-$(CONFIG_PINCTRL)		+= core.o
> >  obj-$(CONFIG_PINMUX)		+= pinmux.o
> >  obj-$(CONFIG_PINCONF)		+= pinconf.o
> > +obj-$(CONFIG_PINMUX_IMX)	+= pinmux-imx-core.o
> > +obj-$(CONFIG_PINMUX_IMX53)	+= pinmux-imx53.o
> > +obj-$(CONFIG_PINMUX_IMX6Q)	+= pinmux-imx6q.o
> >  obj-$(CONFIG_PINMUX_SIRF)	+= pinmux-sirf.o
> >  obj-$(CONFIG_PINMUX_U300)	+= pinmux-u300.o
> >  obj-$(CONFIG_PINCTRL_COH901)	+= pinctrl-coh901.o
> > diff --git a/drivers/pinctrl/pinctrl-imx-core.c
> > b/drivers/pinctrl/pinctrl-imx-core.c new file mode 100644 index
> > 0000000..5c348ba
> > --- /dev/null
> > +++ b/drivers/pinctrl/pinctrl-imx-core.c
> > @@ -0,0 +1,450 @@
> > +/*
> > + * Core driver for the imx pin controller
> > + *
> > + * Copyright (C) 2011 Freescale Semiconductor, Inc.
> > + * Copyright (C) 2011 Linaro Ltd.
> > + *
> > + * Author: Dong Aisheng <dong.aisheng@linaro.org>
> > + *
> > + * 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/init.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/io.h>
> > +#include <linux/err.h>
> > +#include <linux/pinctrl/pinctrl.h>
> > +#include <linux/pinctrl/pinmux.h>
> > +#include <linux/pinctrl/machine.h>
> > +#include <linux/slab.h>
> > +
> > +#include "pinctrl-imx-core.h"
> > +
> > +#define DRIVER_NAME "pinmux-imx"
> > +
> > +/**
> > + * @dev: a pointer back to containing device
> > + * @virtbase: the offset to the controller in virtual memory  */
> > +struct imx_pmx {
> > +	struct device *dev;
> > +	struct pinctrl_dev *pctl;
> > +	void __iomem *virtbase;
> > +	struct imx_pinctrl_info *info;
> > +};
> > +
> > +#define IMX_PINCTRL_REG_SIZE 4
> > +#define IMX_PINCTRL_MAX_FUNC 7
> > +
> > +static int imx_list_groups(struct pinctrl_dev *pctldev, unsigned
> > +selector) {
> > +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> > +	struct imx_pinctrl_info *info = ipmx->info;
> > +
> > +	if (selector >= info->ngroups)
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +
> > +static const char *imx_get_group_name(struct pinctrl_dev *pctldev,
> > +				       unsigned selector)
> > +{
> > +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> > +	struct imx_pinctrl_info *info = ipmx->info;
> > +
> > +	if (selector >= info->ngroups)
> > +		return NULL;
> > +
> > +	return info->groups[selector].name;
> > +}
> > +
> > +static int imx_get_group_pins(struct pinctrl_dev *pctldev, unsigned
> > selector, +			       const unsigned **pins,
> > +			       unsigned *num_pins)
> > +{
> > +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> > +	struct imx_pinctrl_info *info = ipmx->info;
> > +
> > +	if (selector >= info->ngroups)
> > +		return -EINVAL;
> > +
> > +	*pins = info->groups[selector].pins;
> > +	*num_pins = info->groups[selector].num_pins;
> > +
> > +	return 0;
> > +}
> > +
> > +static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct
> > +seq_file
> > *s, +		   unsigned offset)
> > +{
> > +	seq_printf(s, " " DRIVER_NAME);
> > +}
> > +
> > +static struct pinctrl_ops imx_pctrl_ops = {
> > +	.list_groups = imx_list_groups,
> > +	.get_group_name = imx_get_group_name,
> > +	.get_group_pins = imx_get_group_pins,
> > +	.pin_dbg_show = imx_pin_dbg_show,
> > +};
> > +
> > +static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
> > +			   unsigned group)
> > +{
> > +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> > +	struct imx_pinctrl_info *info = ipmx->info;
> > +	const unsigned *pins, *mux;
> > +	unsigned int num_pins, num_mux;
> > +	u32 regval, offset;
> > +	int i;
> > +
> > +	/*
> > +	 * Configure the mux mode for each pin in the group for a specific
> > +	 * function.
> > +	 */
> > +	pins = info->groups[group].pins;
> > +	num_pins = info->groups[group].num_pins;
> > +	mux = info->groups[group].mux_mode;
> > +	num_mux = info->groups[group].num_mux;
> > +
> > +	dev_dbg(ipmx->dev, "function %s group %s\n",
> > +		info->functions[selector].name, info->groups[group].name);
> > +
> > +	if (num_pins != num_mux) {
> > +		dev_err(ipmx->dev, "num_mux is not equal to num_pins\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	for (i = 0; i < num_pins; i++) {
> > +		if (mux[i] > IMX_PINCTRL_MAX_FUNC)
> > +			dev_err(ipmx->dev, "exceeds the maximum mux
> mode(0x7)\n");
> > +		offset = info->mux_offset + pins[i] * IMX_PINCTRL_REG_SIZE;
> > +		regval = readl(ipmx->virtbase + offset);
> > +		regval &= ~IMX_PINCTRL_MAX_FUNC;
> > +		writel(mux[i] | regval, ipmx->virtbase + offset);
> > +		dev_dbg(ipmx->dev, "write: offset 0x%x val 0x%x\n",
> > +			offset, regval | mux[i]);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static void imx_pmx_disable(struct pinctrl_dev *pctldev, unsigned
> > func_selector, +			    unsigned group_selector)
> > +{
> > +	/* nothing to do here */
> > +}
> > +
> > +static int imx_pmx_list_funcs(struct pinctrl_dev *pctldev, unsigned
> > selector) +{
> > +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> > +	struct imx_pinctrl_info *info = ipmx->info;
> > +
> > +	if (selector >= info->nfunctions)
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +
> > +static const char *imx_pmx_get_func_name(struct pinctrl_dev *pctldev,
> > +					  unsigned selector)
> > +{
> > +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> > +	struct imx_pinctrl_info *info = ipmx->info;
> > +
> > +	return info->functions[selector].name; }
> > +
> > +static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned
> > selector, +			       const char * const **groups,
> > +			       unsigned * const num_groups) {
> > +	struct imx_pmx *ipmx = pinctrl_dev_get_drvdata(pctldev);
> > +	struct imx_pinctrl_info *info = ipmx->info;
> > +
> > +	*groups = info->functions[selector].groups;
> > +	*num_groups = info->functions[selector].num_groups;
> > +
> > +	return 0;
> > +}
> > +
> > +static struct pinmux_ops imx_pmx_ops = {
> > +	.list_functions = imx_pmx_list_funcs,
> > +	.get_function_name = imx_pmx_get_func_name,
> > +	.get_function_groups = imx_pmx_get_groups,
> > +	.enable = imx_pmx_enable,
> > +	.disable = imx_pmx_disable,
> > +};
> > +
> > +static struct pinctrl_desc imx_pmx_desc = {
> > +	.name = DRIVER_NAME,
> > +	.pctlops = &imx_pctrl_ops,
> > +	.pmxops = &imx_pmx_ops,
> > +	.owner = THIS_MODULE,
> > +};
> > +
> > +#ifdef CONFIG_OF
> > +static int __devinit imx_pmx_parse_functions(struct device_node *np,
> > +			struct imx_pinctrl_info *info, u32 num) {
> > +	struct imx_pmx_func *function;
> > +	struct imx_pin_group *group;
> > +	int ret, len;
> > +
> > +	dev_dbg(info->dev, "parse function %d\n", num);
> > +
> > +	group = &info->groups[num];
> > +	function = &info->functions[num];
> > +
> > +	/* Initialise group */
> > +	ret = of_property_read_string(np, "grp-name", &group->name);
> > +	if (ret) {
> > +		dev_err(info->dev, "failed to get grp-name\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = of_property_read_u32(np, "num-pins", &group->num_pins);
> > +	if (ret) {
> > +		dev_err(info->dev, "failed to get num-pins\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = of_property_read_u32(np, "num-mux", &group->num_mux);
> > +	if (ret) {
> > +		dev_err(info->dev, "failed to get num-mux\n");
> > +		return ret;
> > +	}
> > +
> > +	if (group->num_pins != group->num_mux)
> > +		return -EINVAL;
> > +
> > +	group->pins = devm_kzalloc(info->dev, group->num_pins *
> > +sizeof(unsigned
> > int), +				GFP_KERNEL);
> > +	group->mux_mode = devm_kzalloc(info->dev, group->num_mux *
> > sizeof(unsigned int), +				GFP_KERNEL);
> > +	if (!group->pins || !group->mux_mode)
> > +		return -ENOMEM;
> > +
> > +	/* sanity check */
> > +	if (of_get_property(np, "grp-pins", &len) &&
> > +		len != group->num_pins * sizeof(unsigned int)) {
> > +		dev_err(info->dev, "wrong pins number?\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (of_get_property(np, "grp-mux", &len) &&
> > +		len != group->num_mux * sizeof(unsigned int)) {
> > +		dev_err(info->dev, "wrong pin mux number?\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	ret = of_property_read_u32_array(np, "grp-pins",
> > +			group->pins, group->num_pins);
> > +	if (ret) {
> > +		dev_err(info->dev, "failed to get grp-pins\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = of_property_read_u32_array(np, "grp-mux",
> > +			group->mux_mode, group->num_mux);
> > +	if (ret) {
> > +		dev_err(info->dev, "failed to get grp-mux\n");
> > +		return ret;
> > +	}
> > +
> > +	/* Initialise function */
> > +	ret = of_property_read_string(np, "func-name", &function->name);
> > +	if (ret) {
> > +		dev_err(info->dev, "failed to get func-name\n");
> > +		return ret;
> > +	}
> > +
> > +	function->groups = devm_kzalloc(info->dev, sizeof(char **), GFP_KERNEL);
> > +	function->num_groups = 1;
> > +	function->groups[0] = group->name;
> > +
> > +	dev_dbg(info->dev, "func-name %s grp-name %s num-groups %d\n",
> > +				function->name, function->groups[0],
> > +				function->num_groups);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __devinit imx_pmx_probe_dt(struct platform_device *pdev,
> > +				struct imx_pinctrl_info *info)
> > +{
> > +	struct device_node *np = pdev->dev.of_node;
> > +	struct device_node *child = NULL;
> > +	struct device_node *map_np;
> > +	int ret, i;
> > +	u32 nfuncs = 0;
> > +
> > +	if (!np)
> > +		return -ENODEV;
> > +
> > +	nfuncs = of_get_child_count(np);
> > +	if (nfuncs <= 0) {
> > +		dev_err(&pdev->dev, "no functions defined\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	info->nfunctions = nfuncs;
> > +	info->functions = devm_kzalloc(&pdev->dev, nfuncs * sizeof(struct
> > imx_pmx_func), +					GFP_KERNEL);
> > +	if (!info->functions)
> > +		return -ENOMEM;
> > +
> > +	/* DT file only passes one group per one function */
> > +	info->ngroups = nfuncs;
> > +	info->groups = devm_kzalloc(&pdev->dev, nfuncs * sizeof(struct
> > imx_pin_group), +					GFP_KERNEL);
> > +	if (!info->groups)
> > +		return -ENOMEM;
> > +
> > +	child = NULL;
> > +	i = 0;
> > +	for_each_child_of_node(np, child) {
> > +		ret = imx_pmx_parse_functions(child, info, i++);
> > +		if (ret) {
> > +			dev_err(&pdev->dev, "failed to parse function\n");
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	/* parse pinmux map */
> > +	map_np = of_parse_phandle(np, "fsl,pinmux-map", 0);
> > +	if (!map_np) {
> > +		dev_err(&pdev->dev, "failed to parse phandle fsl,pinmux-map\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	ret = pinmux_of_register_mappings(map_np);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "failed to register pinmux mappings\n");
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +#else
> > +static int __devinit imx_pmx_probe_dt(struct platform_device *pdev,
> > +				struct imx_pinctrl_info *info)
> > +{
> > +	return -ENODEV;
> > +}
> > +#endif
> > +
> > +static inline void imx_pmx_desc_init(struct pinctrl_desc *pmx_desc,
> > +				const struct imx_pinctrl_info *info) {
> > +	pmx_desc->pins = info->pins;
> > +	pmx_desc->npins = info->npins;
> > +	pmx_desc->maxpin = info->maxpin;
> > +}
> > +
> > +static const struct of_device_id imx_pmx_dt_ids[] = { #ifdef
> > +CONFIG_PINMUX_IMX6Q
> > +	{ .compatible = "fsl,imx6q-iomuxc", .data = (void *)
> &imx6q_pinctrl_info,
> > }, +#endif
> > +#ifdef CONFIG_PINMUX_IMX53
> > +	{ .compatible = "fsl,imx53-iomuxc", .data = (void *)
> &imx53_pinctrl_info,
> > }, +#endif
> > +	{ /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, imx_pmx_dt_ids);
> > +
> > +static int __init imx_pmx_probe(struct platform_device *pdev) {
> > +	const struct of_device_id *of_id =
> > +			of_match_device(imx_pmx_dt_ids, &pdev->dev);
> > +	struct device *dev = &pdev->dev;
> > +	struct imx_pmx *ipmx;
> > +	struct resource *res;
> > +	struct imx_pinctrl_info *info;
> > +	resource_size_t res_size;
> > +	int ret;
> > +
> > +	info = of_id->data;
> > +	if (!info || !info->pins || !(info->maxpin > info->npins)) {
> > +		dev_err(&pdev->dev, "wrong pinctrl info\n");
> > +		return -EINVAL;
> > +	}
> > +	info->dev = &pdev->dev;
> > +
> > +	/* Create state holders etc for this driver */
> > +	ipmx = devm_kzalloc(&pdev->dev, sizeof(*ipmx), GFP_KERNEL);
> > +	if (!ipmx)
> > +		return -ENOMEM;
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	if (!res)
> > +		return -ENOENT;
> > +
> > +	res_size = resource_size(res);
> > +	if (!devm_request_mem_region(dev, res->start, res_size, res->name))
> > +		return -EBUSY;
> > +
> > +	ipmx->virtbase = devm_ioremap_nocache(dev, res->start, res_size);
> > +	if (!ipmx->virtbase)
> > +		return -EBUSY;
> > +
> > +	imx_pmx_desc_init(&imx_pmx_desc, info);
> > +	ret = imx_pmx_probe_dt(pdev, info);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "fail to probe dt properties\n");
> > +		return ret;
> > +	}
> > +
> > +	ipmx->pctl = pinctrl_register(&imx_pmx_desc, &pdev->dev, ipmx);
> > +	if (!ipmx->pctl) {
> > +		dev_err(&pdev->dev, "could not register IMX pinmux driver\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	ipmx->info = info;
> > +	ipmx->dev = info->dev;
> > +	platform_set_drvdata(pdev, ipmx);
> > +
> > +	dev_info(&pdev->dev, "initialized IMX pinmux driver\n");
> > +
> > +	return 0;
> > +}
> > +
> > +static int __exit imx_pmx_remove(struct platform_device *pdev) {
> > +	struct imx_pmx *ipmx = platform_get_drvdata(pdev);
> > +
> > +	pinctrl_unregister(ipmx->pctl);
> > +	platform_set_drvdata(pdev, NULL);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct platform_driver imx_pmx_driver = {
> > +	.driver = {
> > +		.name = DRIVER_NAME,
> > +		.owner = THIS_MODULE,
> > +		.of_match_table = imx_pmx_dt_ids,
> > +	},
> > +	.remove = __exit_p(imx_pmx_remove),
> > +};
> > +
> > +static int __init imx_pmx_init(void)
> > +{
> > +	return platform_driver_probe(&imx_pmx_driver, imx_pmx_probe); }
> > +arch_initcall(imx_pmx_init);
> > +
> > +static void __exit imx_pmx_exit(void) {
> > +	platform_driver_unregister(&imx_pmx_driver);
> > +}
> > +module_exit(imx_pmx_exit);
> > +
> > +MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
> > +MODULE_DESCRIPTION("IMX Pin Control Driver"); MODULE_LICENSE("GPL
> > +v2");
> > diff --git a/drivers/pinctrl/pinctrl-imx-core.h
> > b/drivers/pinctrl/pinctrl-imx-core.h new file mode 100644 index
> > 0000000..df69cd0
> > --- /dev/null
> > +++ b/drivers/pinctrl/pinctrl-imx-core.h
> > @@ -0,0 +1,86 @@
> > +/*
> > + * IMX pinmux core definitions
> > + *
> > + * Copyright (C) 2011 Freescale Semiconductor, Inc.
> > + * Copyright (C) 2011 Linaro Ltd.
> > + *
> > + * Author: Dong Aisheng <dong.aisheng@linaro.org>
> > + *
> > + * 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.
> > + */
> > +
> > +#ifndef __DRIVERS_PINCTRL_PINMUX_IMX_H #define
> > +__DRIVERS_PINCTRL_PINMUX_IMX_H
> > +
> > +/* Supported Pinctrl type */
> > +enum imx_pinctrl_type {
> > +	IMX53_PINCTRL,
> > +	IMX6Q_PINCTRL,
> > +};
> > +
> > +/**
> > + * struct imx_pin_group - describes an IMX pin group
> > + * @name: the name of this specific pin group
> > + * @pins: an array of discrete physical pins used in this group, taken
> > + *	from the driver-local pin enumeration space
> > + * @num_pins: the number of pins in this group array, i.e. the number of
> > + *	elements in .pins so we can iterate over that array
> > + * @mux_mode: the mux mode for each pins in this group. The size of this
> > + *	array is the same as pins.
> > + */
> > +struct imx_pin_group {
> > +	const char *name;
> > +	unsigned int *pins;
> > +	unsigned num_pins;
> > +	unsigned int *mux_mode;
> > +	unsigned num_mux;
> > +};
> > +
> > +/**
> > + * struct imx_pmx_func - describes IMX pinmux functions
> > + * @name: the name of this specific function
> > + * @groups: corresponding pin groups
> > + */
> > +struct imx_pmx_func {
> > +	const char *name;
> > +	const char **groups;
> > +	unsigned num_groups;
> > +};
> > +
> > +struct imx_pinctrl_info {
> > +	struct device *dev;
> > +	u32 type;
> > +	const struct pinctrl_pin_desc *pins;
> > +	unsigned int npins;
> > +	unsigned int maxpin;
> > +	struct imx_pin_group *groups;
> > +	unsigned int ngroups;
> > +	struct imx_pmx_func *functions;
> > +	unsigned int nfunctions;
> > +	u32 mux_offset;
> > +};
> > +
> > +#define IMX_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin)
> > +
> > +#define IMX_PIN_GROUP(n, p, m)  \
> > +	{			\
> > +		.name = n,	\
> > +		.pins = p,	\
> > +		.num_pins = ARRAY_SIZE(p),	\
> > +		.mux_mode = m,	\
> > +		.num_mux = ARRAY_SIZE(m),	\
> > +	}
> > +
> > +#define IMX_PMX_FUNC(n, g)  \
> > +	{			\
> > +		.name = n,	\
> > +		.groups = g,	\
> > +		.num_groups = ARRAY_SIZE(g),	\
> > +	}
> > +
> > +extern struct imx_pinctrl_info imx53_pinctrl_info; extern struct
> > +imx_pinctrl_info imx6q_pinctrl_info; #endif /*
> > +__DRIVERS_PINCTRL_PINMUX_IMX_H */
> > diff --git a/drivers/pinctrl/pinctrl-imx53.c
> > b/drivers/pinctrl/pinctrl-imx53.c new file mode 100644 index
> > 0000000..079b25e
> > --- /dev/null
> > +++ b/drivers/pinctrl/pinctrl-imx53.c
> > @@ -0,0 +1,443 @@
> > +/*
> > + * imx53 pinctrl driver based on imx pinmux core
> > + *
> > + * Copyright (C) 2011 Freescale Semiconductor, Inc.
> > + * Copyright (C) 2011 Linaro, Inc.
> > + *
> > + * Author: Dong Aisheng <dong.aisheng@linaro.org>
> > + *
> > + * 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/init.h>
> > +#include <linux/io.h>
> > +#include <linux/err.h>
> > +#include <linux/pinctrl/pinctrl.h>
> > +#include <linux/pinctrl/pinmux.h>
> > +
> > +#include "pinctrl-imx-core.h"
> > +
> > +#define IMX53_IOMUXC_MUX_OFFSET 0x20
> > +#define IMX53_IOMUXC_MAXPIN	(23*23)
> > +
> > +enum imx_imx53_pinctrl_pads {
> > +	MX53_GPIO_19 = 0,
> > +	MX53_KEY_COL0 = 1,
> > +	MX53_KEY_ROW0 = 2,
> > +	MX53_KEY_COL1 = 3,
> > +	MX53_KEY_ROW1 = 4,
> > +	MX53_KEY_COL2 = 5,
> > +	MX53_KEY_ROW2 = 6,
> > +	MX53_KEY_COL3 = 7,
> > +	MX53_KEY_ROW3 = 8,
> > +	MX53_KEY_COL4 = 9,
> > +	MX53_KEY_ROW4 = 10,
> > +	MX53_DI0_DISP_CLK = 11,
> > +	MX53_DI0_PIN15 = 12,
> > +	MX53_DI0_PIN2 = 13,
> > +	MX53_DI0_PIN3 = 14,
> > +	MX53_DI0_PIN4 = 15,
> > +	MX53_DISP0_DAT0 = 16,
> > +	MX53_DISP0_DAT1 = 17,
> > +	MX53_DISP0_DAT2 = 18,
> > +	MX53_DISP0_DAT3 = 19,
> > +	MX53_DISP0_DAT4 = 20,
> > +	MX53_DISP0_DAT5 = 21,
> > +	MX53_DISP0_DAT6 = 22,
> > +	MX53_DISP0_DAT7 = 23,
> > +	MX53_DISP0_DAT8 = 24,
> > +	MX53_DISP0_DAT9 = 25,
> > +	MX53_DISP0_DAT10 = 26,
> > +	MX53_DISP0_DAT11 = 27,
> > +	MX53_DISP0_DAT12 = 28,
> > +	MX53_DISP0_DAT13 = 29,
> > +	MX53_DISP0_DAT14 = 30,
> > +	MX53_DISP0_DAT15 = 31,
> > +	MX53_DISP0_DAT16 = 32,
> > +	MX53_DISP0_DAT17 = 33,
> > +	MX53_DISP0_DAT18 = 34,
> > +	MX53_DISP0_DAT19 = 35,
> > +	MX53_DISP0_DAT20 = 36,
> > +	MX53_DISP0_DAT21 = 37,
> > +	MX53_DISP0_DAT22 = 38,
> > +	MX53_DISP0_DAT23 = 39,
> > +	MX53_CSI0_PIXCLK = 40,
> > +	MX53_CSI0_MCLK = 41,
> > +	MX53_CSI0_DATA_EN = 42,
> > +	MX53_CSI0_VSYNC = 43,
> > +	MX53_CSI0_DAT4 = 44,
> > +	MX53_CSI0_DAT5 = 45,
> > +	MX53_CSI0_DAT6 = 46,
> > +	MX53_CSI0_DAT7 = 47,
> > +	MX53_CSI0_DAT8 = 48,
> > +	MX53_CSI0_DAT9 = 49,
> > +	MX53_CSI0_DAT10 = 50,
> > +	MX53_CSI0_DAT11 = 51,
> > +	MX53_CSI0_DAT12 = 52,
> > +	MX53_CSI0_DAT13 = 53,
> > +	MX53_CSI0_DAT14 = 54,
> > +	MX53_CSI0_DAT15 = 55,
> > +	MX53_CSI0_DAT16 = 56,
> > +	MX53_CSI0_DAT17 = 57,
> > +	MX53_CSI0_DAT18 = 58,
> > +	MX53_CSI0_DAT19 = 59,
> > +	MX53_EIM_A25 = 60,
> > +	MX53_EIM_EB2 = 61,
> > +	MX53_EIM_D16 = 62,
> > +	MX53_EIM_D17 = 63,
> > +	MX53_EIM_D18 = 64,
> > +	MX53_EIM_D19 = 65,
> > +	MX53_EIM_D20 = 66,
> > +	MX53_EIM_D21 = 67,
> > +	MX53_EIM_D22 = 68,
> > +	MX53_EIM_D23 = 69,
> > +	MX53_EIM_EB3 = 70,
> > +	MX53_EIM_D24 = 71,
> > +	MX53_EIM_D25 = 72,
> > +	MX53_EIM_D26 = 73,
> > +	MX53_EIM_D27 = 74,
> > +	MX53_EIM_D28 = 75,
> > +	MX53_EIM_D29 = 76,
> > +	MX53_EIM_D30 = 77,
> > +	MX53_EIM_D31 = 78,
> > +	MX53_EIM_A24 = 79,
> > +	MX53_EIM_A23 = 80,
> > +	MX53_EIM_A22 = 81,
> > +	MX53_EIM_A21 = 82,
> > +	MX53_EIM_A20 = 83,
> > +	MX53_EIM_A19 = 84,
> > +	MX53_EIM_A18 = 85,
> > +	MX53_EIM_A17 = 86,
> > +	MX53_EIM_A16 = 87,
> > +	MX53_EIM_CS0 = 88,
> > +	MX53_EIM_CS1 = 89,
> > +	MX53_EIM_OE = 90,
> > +	MX53_EIM_RW = 91,
> > +	MX53_EIM_LBA = 92,
> > +	MX53_EIM_EB0 = 93,
> > +	MX53_EIM_EB1 = 94,
> > +	MX53_EIM_DA0 = 95,
> > +	MX53_EIM_DA1 = 96,
> > +	MX53_EIM_DA2 = 97,
> > +	MX53_EIM_DA3 = 98,
> > +	MX53_EIM_DA4 = 99,
> > +	MX53_EIM_DA5 = 100,
> > +	MX53_EIM_DA6 = 101,
> > +	MX53_EIM_DA7 = 102,
> > +	MX53_EIM_DA8 = 103,
> > +	MX53_EIM_DA9 = 104,
> > +	MX53_EIM_DA10 = 105,
> > +	MX53_EIM_DA11 = 106,
> > +	MX53_EIM_DA12 = 107,
> > +	MX53_EIM_DA13 = 108,
> > +	MX53_EIM_DA14 = 109,
> > +	MX53_EIM_DA15 = 110,
> > +	MX53_NANDF_WE_B = 111,
> > +	MX53_NANDF_RE_B = 112,
> > +	MX53_EIM_WAIT = 113,
> > +	MX53_EIM_BCLK = 114,
> > +	MX53_LVDS1_TX3_P = 115,
> > +	MX53_LVDS1_TX2_P = 116,
> > +	MX53_LVDS1_CLK_P = 117,
> > +	MX53_LVDS1_TX1_P = 118,
> > +	MX53_LVDS1_TX0_P = 119,
> > +	MX53_LVDS0_TX3_P = 120,
> > +	MX53_LVDS0_CLK_P = 121,
> > +	MX53_LVDS0_TX2_P = 122,
> > +	MX53_LVDS0_TX1_P = 123,
> > +	MX53_LVDS0_TX0_P = 124,
> > +	MX53_GPIO_10 = 125,
> > +	MX53_GPIO_11 = 126,
> > +	MX53_GPIO_12 = 127,
> > +	MX53_GPIO_13 = 128,
> > +	MX53_GPIO_14 = 129,
> > +	MX53_NANDF_CLE = 130,
> > +	MX53_NANDF_ALE = 131,
> > +	MX53_NANDF_WP_B = 132,
> > +	MX53_NANDF_RB0 = 133,
> > +	MX53_NANDF_CS0 = 134,
> > +	MX53_NANDF_CS1 = 135,
> > +	MX53_NANDF_CS2 = 136,
> > +	MX53_NANDF_CS3 = 137,
> > +	MX53_FEC_MDIO = 138,
> > +	MX53_FEC_REF_CLK = 139,
> > +	MX53_FEC_RX_ER = 140,
> > +	MX53_FEC_CRS_DV = 141,
> > +	MX53_FEC_RXD1 = 142,
> > +	MX53_FEC_RXD0 = 143,
> > +	MX53_FEC_TX_EN = 144,
> > +	MX53_FEC_TXD1 = 145,
> > +	MX53_FEC_TXD0 = 146,
> > +	MX53_FEC_MDC = 147,
> > +	MX53_PATA_DIOW = 148,
> > +	MX53_PATA_DMACK = 149,
> > +	MX53_PATA_DMARQ = 150,
> > +	MX53_PATA_BUFFER_EN = 151,
> > +	MX53_PATA_INTRQ = 152,
> > +	MX53_PATA_DIOR = 153,
> > +	MX53_PATA_RESET_B = 154,
> > +	MX53_PATA_IORDY = 155,
> > +	MX53_PATA_DA_0 = 156,
> > +	MX53_PATA_DA_1 = 157,
> > +	MX53_PATA_DA_2 = 158,
> > +	MX53_PATA_CS_0 = 159,
> > +	MX53_PATA_CS_1 = 160,
> > +	MX53_PATA_DATA0 = 161,
> > +	MX53_PATA_DATA1 = 162,
> > +	MX53_PATA_DATA2 = 163,
> > +	MX53_PATA_DATA3 = 164,
> > +	MX53_PATA_DATA4 = 165,
> > +	MX53_PATA_DATA5 = 166,
> > +	MX53_PATA_DATA6 = 167,
> > +	MX53_PATA_DATA7 = 168,
> > +	MX53_PATA_DATA8 = 169,
> > +	MX53_PATA_DATA9 = 170,
> > +	MX53_PATA_DATA10 = 171,
> > +	MX53_PATA_DATA11 = 172,
> > +	MX53_PATA_DATA12 = 173,
> > +	MX53_PATA_DATA13 = 174,
> > +	MX53_PATA_DATA14 = 175,
> > +	MX53_PATA_DATA15 = 176,
> > +	MX53_SD1_DATA0 = 177,
> > +	MX53_SD1_DATA1 = 178,
> > +	MX53_SD1_CMD = 179,
> > +	MX53_SD1_DATA2 = 180,
> > +	MX53_SD1_CLK = 181,
> > +	MX53_SD1_DATA3 = 182,
> > +	MX53_SD2_CLK = 183,
> > +	MX53_SD2_CMD = 184,
> > +	MX53_SD2_DATA3 = 185,
> > +	MX53_SD2_DATA2 = 186,
> > +	MX53_SD2_DATA1 = 187,
> > +	MX53_SD2_DATA0 = 188,
> > +	MX53_GPIO_0 = 189,
> > +	MX53_GPIO_1 = 190,
> > +	MX53_GPIO_9 = 191,
> > +	MX53_GPIO_3 = 192,
> > +	MX53_GPIO_6 = 193,
> > +	MX53_GPIO_2 = 194,
> > +	MX53_GPIO_4 = 195,
> > +	MX53_GPIO_5 = 196,
> > +	MX53_GPIO_7 = 197,
> > +	MX53_GPIO_8 = 198,
> > +	MX53_GPIO_16 = 199,
> > +	MX53_GPIO_17 = 200,
> > +	MX53_GPIO_18 = 201,
> > +};
> > +
> > +/* Pad names for the pinmux subsystem */ static const struct
> > +pinctrl_pin_desc imx53_pinctrl_pads[] = {
> > +	IMX_PINCTRL_PIN(MX53_GPIO_19),
> > +	IMX_PINCTRL_PIN(MX53_KEY_COL0),
> > +	IMX_PINCTRL_PIN(MX53_KEY_ROW0),
> > +	IMX_PINCTRL_PIN(MX53_KEY_COL1),
> > +	IMX_PINCTRL_PIN(MX53_KEY_ROW1),
> > +	IMX_PINCTRL_PIN(MX53_KEY_COL2),
> > +	IMX_PINCTRL_PIN(MX53_KEY_ROW2),
> > +	IMX_PINCTRL_PIN(MX53_KEY_COL3),
> > +	IMX_PINCTRL_PIN(MX53_KEY_ROW3),
> > +	IMX_PINCTRL_PIN(MX53_KEY_COL4),
> > +	IMX_PINCTRL_PIN(MX53_KEY_ROW4),
> > +	IMX_PINCTRL_PIN(MX53_DI0_DISP_CLK),
> > +	IMX_PINCTRL_PIN(MX53_DI0_PIN15),
> > +	IMX_PINCTRL_PIN(MX53_DI0_PIN2),
> > +	IMX_PINCTRL_PIN(MX53_DI0_PIN3),
> > +	IMX_PINCTRL_PIN(MX53_DI0_PIN4),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT0),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT1),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT2),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT3),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT4),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT5),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT6),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT7),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT8),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT9),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT10),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT11),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT12),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT13),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT14),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT15),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT16),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT17),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT18),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT19),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT20),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT21),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT22),
> > +	IMX_PINCTRL_PIN(MX53_DISP0_DAT23),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_PIXCLK),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_MCLK),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DATA_EN),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_VSYNC),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT4),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT5),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT6),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT7),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT8),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT9),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT10),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT11),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT12),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT13),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT14),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT15),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT16),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT17),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT18),
> > +	IMX_PINCTRL_PIN(MX53_CSI0_DAT19),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A25),
> > +	IMX_PINCTRL_PIN(MX53_EIM_EB2),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D16),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D17),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D18),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D19),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D20),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D21),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D22),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D23),
> > +	IMX_PINCTRL_PIN(MX53_EIM_EB3),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D24),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D25),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D26),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D27),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D28),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D29),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D30),
> > +	IMX_PINCTRL_PIN(MX53_EIM_D31),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A24),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A23),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A22),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A21),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A20),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A19),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A18),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A17),
> > +	IMX_PINCTRL_PIN(MX53_EIM_A16),
> > +	IMX_PINCTRL_PIN(MX53_EIM_CS0),
> > +	IMX_PINCTRL_PIN(MX53_EIM_CS1),
> > +	IMX_PINCTRL_PIN(MX53_EIM_OE),
> > +	IMX_PINCTRL_PIN(MX53_EIM_RW),
> > +	IMX_PINCTRL_PIN(MX53_EIM_LBA),
> > +	IMX_PINCTRL_PIN(MX53_EIM_EB0),
> > +	IMX_PINCTRL_PIN(MX53_EIM_EB1),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA0),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA1),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA2),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA3),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA4),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA5),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA6),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA7),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA8),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA9),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA10),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA11),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA12),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA13),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA14),
> > +	IMX_PINCTRL_PIN(MX53_EIM_DA15),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_WE_B),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_RE_B),
> > +	IMX_PINCTRL_PIN(MX53_EIM_WAIT),
> > +	IMX_PINCTRL_PIN(MX53_EIM_BCLK),
> > +	IMX_PINCTRL_PIN(MX53_LVDS1_TX3_P),
> > +	IMX_PINCTRL_PIN(MX53_LVDS1_TX2_P),
> > +	IMX_PINCTRL_PIN(MX53_LVDS1_CLK_P),
> > +	IMX_PINCTRL_PIN(MX53_LVDS1_TX1_P),
> > +	IMX_PINCTRL_PIN(MX53_LVDS1_TX0_P),
> > +	IMX_PINCTRL_PIN(MX53_LVDS0_TX3_P),
> > +	IMX_PINCTRL_PIN(MX53_LVDS0_CLK_P),
> > +	IMX_PINCTRL_PIN(MX53_LVDS0_TX2_P),
> > +	IMX_PINCTRL_PIN(MX53_LVDS0_TX1_P),
> > +	IMX_PINCTRL_PIN(MX53_LVDS0_TX0_P),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_10),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_11),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_12),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_13),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_14),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_CLE),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_ALE),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_WP_B),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_RB0),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_CS0),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_CS1),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_CS2),
> > +	IMX_PINCTRL_PIN(MX53_NANDF_CS3),
> > +	IMX_PINCTRL_PIN(MX53_FEC_MDIO),
> > +	IMX_PINCTRL_PIN(MX53_FEC_REF_CLK),
> > +	IMX_PINCTRL_PIN(MX53_FEC_RX_ER),
> > +	IMX_PINCTRL_PIN(MX53_FEC_CRS_DV),
> > +	IMX_PINCTRL_PIN(MX53_FEC_RXD1),
> > +	IMX_PINCTRL_PIN(MX53_FEC_RXD0),
> > +	IMX_PINCTRL_PIN(MX53_FEC_TX_EN),
> > +	IMX_PINCTRL_PIN(MX53_FEC_TXD1),
> > +	IMX_PINCTRL_PIN(MX53_FEC_TXD0),
> > +	IMX_PINCTRL_PIN(MX53_FEC_MDC),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DIOW),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DMACK),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DMARQ),
> > +	IMX_PINCTRL_PIN(MX53_PATA_BUFFER_EN),
> > +	IMX_PINCTRL_PIN(MX53_PATA_INTRQ),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DIOR),
> > +	IMX_PINCTRL_PIN(MX53_PATA_RESET_B),
> > +	IMX_PINCTRL_PIN(MX53_PATA_IORDY),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DA_0),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DA_1),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DA_2),
> > +	IMX_PINCTRL_PIN(MX53_PATA_CS_0),
> > +	IMX_PINCTRL_PIN(MX53_PATA_CS_1),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA0),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA1),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA2),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA3),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA4),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA5),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA6),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA7),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA8),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA9),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA10),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA11),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA12),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA13),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA14),
> > +	IMX_PINCTRL_PIN(MX53_PATA_DATA15),
> > +	IMX_PINCTRL_PIN(MX53_SD1_DATA0),
> > +	IMX_PINCTRL_PIN(MX53_SD1_DATA1),
> > +	IMX_PINCTRL_PIN(MX53_SD1_CMD),
> > +	IMX_PINCTRL_PIN(MX53_SD1_DATA2),
> > +	IMX_PINCTRL_PIN(MX53_SD1_CLK),
> > +	IMX_PINCTRL_PIN(MX53_SD1_DATA3),
> > +	IMX_PINCTRL_PIN(MX53_SD2_CLK),
> > +	IMX_PINCTRL_PIN(MX53_SD2_CMD),
> > +	IMX_PINCTRL_PIN(MX53_SD2_DATA3),
> > +	IMX_PINCTRL_PIN(MX53_SD2_DATA2),
> > +	IMX_PINCTRL_PIN(MX53_SD2_DATA1),
> > +	IMX_PINCTRL_PIN(MX53_SD2_DATA0),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_0),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_1),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_9),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_3),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_6),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_2),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_4),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_5),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_7),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_8),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_16),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_17),
> > +	IMX_PINCTRL_PIN(MX53_GPIO_18),
> > +};
> > +
> > +struct imx_pinctrl_info imx53_pinctrl_info = {
> > +	.type = IMX53_PINCTRL,
> > +	.pins = imx53_pinctrl_pads,
> > +	.npins = ARRAY_SIZE(imx53_pinctrl_pads),
> > +	.maxpin = IMX53_IOMUXC_MAXPIN,
> > +	.mux_offset = IMX53_IOMUXC_MUX_OFFSET, };
> > diff --git a/drivers/pinctrl/pinctrl-imx6q.c
> > b/drivers/pinctrl/pinctrl-imx6q.c new file mode 100644 index
> > 0000000..4c0e29f
> > --- /dev/null
> > +++ b/drivers/pinctrl/pinctrl-imx6q.c
> > @@ -0,0 +1,433 @@
> > +/*
> > + * imx6q pinctrl driver based on imx pinmux core
> > + *
> > + * Copyright (C) 2011 Freescale Semiconductor, Inc.
> > + * Copyright (C) 2011 Linaro, Inc.
> > + *
> > + * Author: Dong Aisheng <dong.aisheng@linaro.org>
> > + *
> > + * 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/init.h>
> > +#include <linux/io.h>
> > +#include <linux/err.h>
> > +#include <linux/pinctrl/pinctrl.h>
> > +#include <linux/pinctrl/pinmux.h>
> > +
> > +#include "pinctrl-imx-core.h"
> > +
> > +#define IMX6Q_IOMUXC_MUX_OFSSET	0x4c
> > +#define IMX6Q_IOMUXC_MAXPIN	(25*25)
> > +
> > +enum imx6q_pads {
> > +	MX6Q_SD2_DAT1 = 0,
> > +	MX6Q_SD2_DAT2 = 1,
> > +	MX6Q_SD2_DAT0 = 2,
> > +	MX6Q_RGMII_TXC = 3,
> > +	MX6Q_RGMII_TD0 = 4,
> > +	MX6Q_RGMII_TD1 = 5,
> > +	MX6Q_RGMII_TD2 = 6,
> > +	MX6Q_RGMII_TD3 = 7,
> > +	MX6Q_RGMII_RX_CTL = 8,
> > +	MX6Q_RGMII_RD0 = 9,
> > +	MX6Q_RGMII_TX_CTL = 10,
> > +	MX6Q_RGMII_RD1 = 11,
> > +	MX6Q_RGMII_RD2 = 12,
> > +	MX6Q_RGMII_RD3 = 13,
> > +	MX6Q_RGMII_RXC = 14,
> > +	MX6Q_EIM_A25 = 15,
> > +	MX6Q_EIM_EB2 = 16,
> > +	MX6Q_EIM_D16 = 17,
> > +	MX6Q_EIM_D17 = 18,
> > +	MX6Q_EIM_D18 = 19,
> > +	MX6Q_EIM_D19 = 20,
> > +	MX6Q_EIM_D20 = 21,
> > +	MX6Q_EIM_D21 = 22,
> > +	MX6Q_EIM_D22 = 23,
> > +	MX6Q_EIM_D23 = 24,
> > +	MX6Q_EIM_EB3 = 25,
> > +	MX6Q_EIM_D24 = 26,
> > +	MX6Q_EIM_D25 = 27,
> > +	MX6Q_EIM_D26 = 28,
> > +	MX6Q_EIM_D27 = 29,
> > +	MX6Q_EIM_D28 = 30,
> > +	MX6Q_EIM_D29 = 31,
> > +	MX6Q_EIM_D30 = 32,
> > +	MX6Q_EIM_D31 = 33,
> > +	MX6Q_EIM_A24 = 34,
> > +	MX6Q_EIM_A23 = 35,
> > +	MX6Q_EIM_A22 = 36,
> > +	MX6Q_EIM_A21 = 37,
> > +	MX6Q_EIM_A20 = 38,
> > +	MX6Q_EIM_A19 = 39,
> > +	MX6Q_EIM_A18 = 40,
> > +	MX6Q_EIM_A17 = 41,
> > +	MX6Q_EIM_A16 = 42,
> > +	MX6Q_EIM_CS0 = 43,
> > +	MX6Q_EIM_CS1 = 44,
> > +	MX6Q_EIM_OE = 45,
> > +	MX6Q_EIM_RW = 46,
> > +	MX6Q_EIM_LBA = 47,
> > +	MX6Q_EIM_EB0 = 48,
> > +	MX6Q_EIM_EB1 = 49,
> > +	MX6Q_EIM_DA0 = 50,
> > +	MX6Q_EIM_DA1 = 51,
> > +	MX6Q_EIM_DA2 = 52,
> > +	MX6Q_EIM_DA3 = 53,
> > +	MX6Q_EIM_DA4 = 54,
> > +	MX6Q_EIM_DA5 = 55,
> > +	MX6Q_EIM_DA6 = 56,
> > +	MX6Q_EIM_DA7 = 57,
> > +	MX6Q_EIM_DA8 = 58,
> > +	MX6Q_EIM_DA9 = 59,
> > +	MX6Q_EIM_DA10 = 60,
> > +	MX6Q_EIM_DA11 = 61,
> > +	MX6Q_EIM_DA12 = 62,
> > +	MX6Q_EIM_DA13 = 63,
> > +	MX6Q_EIM_DA14 = 64,
> > +	MX6Q_EIM_DA15 = 65,
> > +	MX6Q_EIM_WAIT = 66,
> > +	MX6Q_EIM_BCLK = 67,
> > +	MX6Q_DI0_DISP_CLK = 68,
> > +	MX6Q_DI0_PIN15 = 69,
> > +	MX6Q_DI0_PIN2 = 70,
> > +	MX6Q_DI0_PIN3 = 71,
> > +	MX6Q_DI0_PIN4 = 72,
> > +	MX6Q_DISP0_DAT0 = 73,
> > +	MX6Q_DISP0_DAT1 = 74,
> > +	MX6Q_DISP0_DAT2 = 75,
> > +	MX6Q_DISP0_DAT3 = 76,
> > +	MX6Q_DISP0_DAT4 = 77,
> > +	MX6Q_DISP0_DAT5 = 78,
> > +	MX6Q_DISP0_DAT6 = 79,
> > +	MX6Q_DISP0_DAT7 = 80,
> > +	MX6Q_DISP0_DAT8 = 81,
> > +	MX6Q_DISP0_DAT9 = 82,
> > +	MX6Q_DISP0_DAT10 = 83,
> > +	MX6Q_DISP0_DAT11 = 84,
> > +	MX6Q_DISP0_DAT12 = 85,
> > +	MX6Q_DISP0_DAT13 = 86,
> > +	MX6Q_DISP0_DAT14 = 87,
> > +	MX6Q_DISP0_DAT15 = 88,
> > +	MX6Q_DISP0_DAT16 = 89,
> > +	MX6Q_DISP0_DAT17 = 90,
> > +	MX6Q_DISP0_DAT18 = 91,
> > +	MX6Q_DISP0_DAT19 = 92,
> > +	MX6Q_DISP0_DAT20 = 93,
> > +	MX6Q_DISP0_DAT21 = 94,
> > +	MX6Q_DISP0_DAT22 = 95,
> > +	MX6Q_DISP0_DAT23 = 96,
> > +	MX6Q_ENET_MDIO = 97,
> > +	MX6Q_ENET_REF_CLK = 98,
> > +	MX6Q_ENET_RX_ER = 99,
> > +	MX6Q_ENET_CRS_DV = 100,
> > +	MX6Q_ENET_RXD1 = 101,
> > +	MX6Q_ENET_RXD0 = 102,
> > +	MX6Q_ENET_TX_EN = 103,
> > +	MX6Q_ENET_TXD1 = 104,
> > +	MX6Q_ENET_TXD0 = 105,
> > +	MX6Q_ENET_MDC = 106,
> > +	MX6Q_KEY_COL0 = 107,
> > +	MX6Q_KEY_ROW0 = 108,
> > +	MX6Q_KEY_COL1 = 109,
> > +	MX6Q_KEY_ROW1 = 110,
> > +	MX6Q_KEY_COL2 = 111,
> > +	MX6Q_KEY_ROW2 = 112,
> > +	MX6Q_KEY_COL3 = 113,
> > +	MX6Q_KEY_ROW3 = 114,
> > +	MX6Q_KEY_COL4 = 115,
> > +	MX6Q_KEY_ROW4 = 116,
> > +	MX6Q_GPIO_0 = 117,
> > +	MX6Q_GPIO_1 = 118,
> > +	MX6Q_GPIO_9 = 119,
> > +	MX6Q_GPIO_3 = 120,
> > +	MX6Q_GPIO_6 = 121,
> > +	MX6Q_GPIO_2 = 122,
> > +	MX6Q_GPIO_4 = 123,
> > +	MX6Q_GPIO_5 = 124,
> > +	MX6Q_GPIO_7 = 125,
> > +	MX6Q_GPIO_8 = 126,
> > +	MX6Q_GPIO_16 = 127,
> > +	MX6Q_GPIO_17 = 128,
> > +	MX6Q_GPIO_18 = 129,
> > +	MX6Q_GPIO_19 = 130,
> > +	MX6Q_CSI0_PIXCLK = 131,
> > +	MX6Q_CSI0_MCLK = 132,
> > +	MX6Q_CSI0_DATA_EN = 133,
> > +	MX6Q_CSI0_VSYNC = 134,
> > +	MX6Q_CSI0_DAT4 = 135,
> > +	MX6Q_CSI0_DAT5 = 136,
> > +	MX6Q_CSI0_DAT6 = 137,
> > +	MX6Q_CSI0_DAT7 = 138,
> > +	MX6Q_CSI0_DAT8 = 139,
> > +	MX6Q_CSI0_DAT9 = 140,
> > +	MX6Q_CSI0_DAT10 = 141,
> > +	MX6Q_CSI0_DAT11 = 142,
> > +	MX6Q_CSI0_DAT12 = 143,
> > +	MX6Q_CSI0_DAT13 = 144,
> > +	MX6Q_CSI0_DAT14 = 145,
> > +	MX6Q_CSI0_DAT15 = 146,
> > +	MX6Q_CSI0_DAT16 = 147,
> > +	MX6Q_CSI0_DAT17 = 148,
> > +	MX6Q_CSI0_DAT18 = 149,
> > +	MX6Q_CSI0_DAT19 = 150,
> > +	MX6Q_SD3_DAT7 = 151,
> > +	MX6Q_SD3_DAT6 = 152,
> > +	MX6Q_SD3_DAT5 = 153,
> > +	MX6Q_SD3_DAT4 = 154,
> > +	MX6Q_SD3_CMD = 155,
> > +	MX6Q_SD3_CLK = 156,
> > +	MX6Q_SD3_DAT0 = 157,
> > +	MX6Q_SD3_DAT1 = 158,
> > +	MX6Q_SD3_DAT2 = 159,
> > +	MX6Q_SD3_DAT3 = 160,
> > +	MX6Q_SD3_RST = 161,
> > +	MX6Q_NANDF_CLE = 162,
> > +	MX6Q_NANDF_ALE = 163,
> > +	MX6Q_NANDF_WP_B = 164,
> > +	MX6Q_NANDF_RB0 = 165,
> > +	MX6Q_NANDF_CS0 = 166,
> > +	MX6Q_NANDF_CS1 = 167,
> > +	MX6Q_NANDF_CS2 = 168,
> > +	MX6Q_NANDF_CS3 = 169,
> > +	MX6Q_SD4_CMD = 170,
> > +	MX6Q_SD4_CLK = 171,
> > +	MX6Q_NANDF_D0 = 172,
> > +	MX6Q_NANDF_D1 = 173,
> > +	MX6Q_NANDF_D2 = 174,
> > +	MX6Q_NANDF_D3 = 175,
> > +	MX6Q_NANDF_D4 = 176,
> > +	MX6Q_NANDF_D5 = 177,
> > +	MX6Q_NANDF_D6 = 178,
> > +	MX6Q_NANDF_D7 = 179,
> > +	MX6Q_SD4_DAT0 = 180,
> > +	MX6Q_SD4_DAT1 = 181,
> > +	MX6Q_SD4_DAT2 = 182,
> > +	MX6Q_SD4_DAT3 = 183,
> > +	MX6Q_SD4_DAT4 = 184,
> > +	MX6Q_SD4_DAT5 = 185,
> > +	MX6Q_SD4_DAT6 = 186,
> > +	MX6Q_SD4_DAT7 = 187,
> > +	MX6Q_SD1_DAT1 = 188,
> > +	MX6Q_SD1_DAT0 = 189,
> > +	MX6Q_SD1_DAT3 = 190,
> > +	MX6Q_SD1_CMD = 191,
> > +	MX6Q_SD1_DAT2 = 192,
> > +	MX6Q_SD1_CLK = 193,
> > +	MX6Q_SD2_CLK = 194,
> > +	MX6Q_SD2_CMD = 195,
> > +	MX6Q_SD2_DAT3 = 196
> > +};
> > +
> > +/* Pad names for the pinmux subsystem */ static const struct
> > +pinctrl_pin_desc imx6q_pinctrl_pads[] = {
> > +	IMX_PINCTRL_PIN(MX6Q_SD2_DAT1),
> > +	IMX_PINCTRL_PIN(MX6Q_SD2_DAT2),
> > +	IMX_PINCTRL_PIN(MX6Q_SD2_DAT0),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_TXC),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_TD0),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_TD1),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_TD2),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_TD3),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_RX_CTL),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_RD0),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_TX_CTL),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_RD1),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_RD2),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_RD3),
> > +	IMX_PINCTRL_PIN(MX6Q_RGMII_RXC),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A25),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_EB2),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D16),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D17),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D18),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D19),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D20),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D21),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D22),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D23),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_EB3),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D24),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D25),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D26),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D27),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D28),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D29),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D30),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_D31),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A24),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A23),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A22),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A21),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A20),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A19),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A18),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A17),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_A16),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_CS0),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_CS1),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_OE),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_RW),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_LBA),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_EB0),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_EB1),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA0),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA1),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA2),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA3),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA4),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA5),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA6),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA7),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA8),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA9),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA10),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA11),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA12),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA13),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA14),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_DA15),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_WAIT),
> > +	IMX_PINCTRL_PIN(MX6Q_EIM_BCLK),
> > +	IMX_PINCTRL_PIN(MX6Q_DI0_DISP_CLK),
> > +	IMX_PINCTRL_PIN(MX6Q_DI0_PIN15),
> > +	IMX_PINCTRL_PIN(MX6Q_DI0_PIN2),
> > +	IMX_PINCTRL_PIN(MX6Q_DI0_PIN3),
> > +	IMX_PINCTRL_PIN(MX6Q_DI0_PIN4),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT0),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT1),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT2),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT3),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT4),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT5),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT6),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT7),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT8),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT9),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT10),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT11),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT12),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT13),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT14),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT15),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT16),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT17),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT18),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT19),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT20),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT21),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT22),
> > +	IMX_PINCTRL_PIN(MX6Q_DISP0_DAT23),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_MDIO),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_REF_CLK),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_RX_ER),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_CRS_DV),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_RXD1),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_RXD0),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_TX_EN),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_TXD1),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_TXD0),
> > +	IMX_PINCTRL_PIN(MX6Q_ENET_MDC),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_COL0),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW0),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_COL1),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW1),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_COL2),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW2),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_COL3),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW3),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_COL4),
> > +	IMX_PINCTRL_PIN(MX6Q_KEY_ROW4),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_0),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_1),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_9),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_3),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_6),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_2),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_4),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_5),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_7),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_8),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_16),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_17),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_18),
> > +	IMX_PINCTRL_PIN(MX6Q_GPIO_19),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_PIXCLK),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_MCLK),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DATA_EN),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_VSYNC),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT4),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT5),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT6),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT7),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT8),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT9),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT10),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT11),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT12),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT13),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT14),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT15),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT16),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT17),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT18),
> > +	IMX_PINCTRL_PIN(MX6Q_CSI0_DAT19),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT7),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT6),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT5),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT4),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_CMD),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_CLK),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT0),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT1),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT2),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_DAT3),
> > +	IMX_PINCTRL_PIN(MX6Q_SD3_RST),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_CLE),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_ALE),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_WP_B),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_RB0),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_CS0),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_CS1),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_CS2),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_CS3),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_CMD),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_CLK),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_D0),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_D1),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_D2),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_D3),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_D4),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_D5),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_D6),
> > +	IMX_PINCTRL_PIN(MX6Q_NANDF_D7),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT0),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT1),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT2),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT3),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT4),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT5),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT6),
> > +	IMX_PINCTRL_PIN(MX6Q_SD4_DAT7),
> > +	IMX_PINCTRL_PIN(MX6Q_SD1_DAT1),
> > +	IMX_PINCTRL_PIN(MX6Q_SD1_DAT0),
> > +	IMX_PINCTRL_PIN(MX6Q_SD1_DAT3),
> > +	IMX_PINCTRL_PIN(MX6Q_SD1_CMD),
> > +	IMX_PINCTRL_PIN(MX6Q_SD1_DAT2),
> > +	IMX_PINCTRL_PIN(MX6Q_SD1_CLK),
> > +	IMX_PINCTRL_PIN(MX6Q_SD2_CLK),
> > +	IMX_PINCTRL_PIN(MX6Q_SD2_CMD),
> > +	IMX_PINCTRL_PIN(MX6Q_SD2_DAT3),
> > +};
> > +
> > +struct imx_pinctrl_info imx6q_pinctrl_info = {
> > +	.type = IMX6Q_PINCTRL,
> > +	.pins = imx6q_pinctrl_pads,
> > +	.npins = ARRAY_SIZE(imx6q_pinctrl_pads),
> > +	.maxpin = IMX6Q_IOMUXC_MAXPIN,
> > +	.mux_offset = IMX6Q_IOMUXC_MUX_OFSSET, };



^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
  2011-12-20 23:58   ` Stephen Warren
@ 2011-12-21  3:18     ` Dong Aisheng-B29396
  0 siblings, 0 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2011-12-21  3:18 UTC (permalink / raw)
  To: Stephen Warren, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

> -----Original Message-----
> From: Stephen Warren [mailto:swarren@nvidia.com]
> Sent: Wednesday, December 21, 2011 7:59 AM
> To: Dong Aisheng-B29396; linux-kernel@vger.kernel.org
> Cc: linus.walleij@stericsson.com; s.hauer@pengutronix.de;
> rob.herring@calxeda.com; linux-arm-kernel@lists.infradead.org;
> kernel@pengutronix.de; cjb@laptop.org; devicetree-discuss@lists.ozlabs.org
> Subject: RE: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
> Importance: High
> 
> Dong Aisheng wrote at Tuesday, December 20, 2011 10:41 AM:
> > From: Dong Aisheng <dong.aisheng@linaro.org>
> >
> > Currently most code to get child count in kernel are almost same, add
> > a helper to implement this function for dt to use.
> 
> > diff --git a/include/linux/of.h b/include/linux/of.h
> 
> > +static inline int of_get_child_count(const struct device_node *np) {
> > +	return -ENOSYS;
> > +}
> 
> Wouldn't it be better to return 0 here? -ENOSYS would be fine if the function
> returned an error code, but it's really returning a count, and other "dummy"
> functions that return data return 0/NULL already. This would also allow you to
> just use the value directly in all cases rather than having to check for a < 0
> error case.
> 
Good point.
Will update it next.

Regards
Dong Aisheng



^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
  2011-12-20 19:47   ` Marek Vasut
@ 2011-12-21  3:27     ` Dong Aisheng-B29396
  2011-12-21  6:05       ` Lothar Waßmann
  0 siblings, 1 reply; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2011-12-21  3:27 UTC (permalink / raw)
  To: Marek Vasut, linux-arm-kernel
  Cc: linux-kernel, linus.walleij, s.hauer, w.sang, rob.herring,
	grant.likely, kernel, cjb, devicetree-discuss, Guo Shawn-R65073

> -----Original Message-----
> From: Marek Vasut [mailto:marek.vasut@gmail.com]
> Sent: Wednesday, December 21, 2011 3:47 AM
> To: linux-arm-kernel@lists.infradead.org
> Cc: Dong Aisheng-B29396; linux-kernel@vger.kernel.org;
> linus.walleij@stericsson.com; s.hauer@pengutronix.de; w.sang@pengutronix.de;
> rob.herring@calxeda.com; grant.likely@secretlab.ca; kernel@pengutronix.de;
> cjb@laptop.org; devicetree-discuss@lists.ozlabs.org; Guo Shawn-R65073
> Subject: Re: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
> Importance: High
> 
> > From: Dong Aisheng <dong.aisheng@linaro.org>
> >
> > Currently most code to get child count in kernel are almost same, add
> > a helper to implement this function for dt to use.
> >
> > ---
> > Changes v1->v2:
> >  * change the name from of_get_child_number to of_get_child_count
> >
> > Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> > Cc: Grant Likely <grant.likely@secretlab.ca>
> > Cc: Rob Herring <rob.herring@calxeda.com>
> > ---
> >  include/linux/of.h |   16 ++++++++++++++++
> >  1 files changed, 16 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/linux/of.h b/include/linux/of.h index
> > 4948552..d0d91a1 100644
> > --- a/include/linux/of.h
> > +++ b/include/linux/of.h
> > @@ -189,6 +189,17 @@ extern struct device_node
> > *of_get_next_child(const struct device_node *node, for (child =
> > of_get_next_child(parent, NULL); child != NULL; \
> >  	     child = of_get_next_child(parent, child))
> >
> > +static inline int of_get_child_count(const struct device_node *np) {
> > +	struct device_node *child = NULL;
> > +	int num = 0;
> > +
> > +	while ((child = of_get_next_child(np, child)))
> 
> The assignment in this condition really looks eerie, maybe just rewrite it to do
> { } while () ? Also, aren't the parenthesis unnecessary?
> 
Yes, one more parenthesis. I will remove it. Thanks.
For the condition, it's a little trick but I guess for a helper function
it's ok right? And there're already many places using like this.

Regards
Dong Aisheng

> M
> > +		num++;
> > +
> > +	return num;
> > +}
> > +
> >  extern struct device_node *of_find_node_with_property(
> >  	struct device_node *from, const char *prop_name);
> >  #define for_each_node_with_property(dn, prop_name) \
> > @@ -262,6 +273,11 @@ static inline bool of_have_populated_dt(void)
> >  #define for_each_child_of_node(parent, child) \
> >  	while (0)
> >
> > +static inline int of_get_child_count(const struct device_node *np)
> > +{
> > +	return -ENOSYS;
> > +}
> > +
> >  static inline int of_device_is_compatible(const struct device_node
> > *device, const char *name)
> >  {



^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
  2011-12-21  3:27     ` Dong Aisheng-B29396
@ 2011-12-21  6:05       ` Lothar Waßmann
  0 siblings, 0 replies; 98+ messages in thread
From: Lothar Waßmann @ 2011-12-21  6:05 UTC (permalink / raw)
  To: Dong Aisheng-B29396
  Cc: Marek Vasut, linux-arm-kernel, Guo Shawn-R65073, linus.walleij,
	s.hauer, w.sang, rob.herring, linux-kernel, grant.likely, kernel,
	cjb, devicetree-discuss

Hi,

Dong Aisheng-B29396 writes:
> > -----Original Message-----
> > From: Marek Vasut [mailto:marek.vasut@gmail.com]
> > Sent: Wednesday, December 21, 2011 3:47 AM
> > To: linux-arm-kernel@lists.infradead.org
> > Cc: Dong Aisheng-B29396; linux-kernel@vger.kernel.org;
> > linus.walleij@stericsson.com; s.hauer@pengutronix.de; w.sang@pengutronix.de;
> > rob.herring@calxeda.com; grant.likely@secretlab.ca; kernel@pengutronix.de;
> > cjb@laptop.org; devicetree-discuss@lists.ozlabs.org; Guo Shawn-R65073
> > Subject: Re: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
> > Importance: High
> > 
> > > From: Dong Aisheng <dong.aisheng@linaro.org>
> > >
> > > Currently most code to get child count in kernel are almost same, add
> > > a helper to implement this function for dt to use.
> > >
> > > ---
> > > Changes v1->v2:
> > >  * change the name from of_get_child_number to of_get_child_count
> > >
> > > Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> > > Cc: Grant Likely <grant.likely@secretlab.ca>
> > > Cc: Rob Herring <rob.herring@calxeda.com>
> > > ---
> > >  include/linux/of.h |   16 ++++++++++++++++
> > >  1 files changed, 16 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/include/linux/of.h b/include/linux/of.h index
> > > 4948552..d0d91a1 100644
> > > --- a/include/linux/of.h
> > > +++ b/include/linux/of.h
> > > @@ -189,6 +189,17 @@ extern struct device_node
> > > *of_get_next_child(const struct device_node *node, for (child =
> > > of_get_next_child(parent, NULL); child != NULL; \
> > >  	     child = of_get_next_child(parent, child))
> > >
> > > +static inline int of_get_child_count(const struct device_node *np) {
> > > +	struct device_node *child = NULL;
> > > +	int num = 0;
> > > +
> > > +	while ((child = of_get_next_child(np, child)))
> > 
> > The assignment in this condition really looks eerie, maybe just rewrite it to do
> > { } while () ? Also, aren't the parenthesis unnecessary?
> > 
> Yes, one more parenthesis. I will remove it. Thanks.
> For the condition, it's a little trick but I guess for a helper function
> it's ok right? And there're already many places using like this.
> 
It's a bad habit to use an assignment as an expression. It always
looks like someone used '=' instead of '=='.

You should make it clear that that's not the case like:
|	   while ((child = of_get_next_child(np, child)) != NULL)


Lothar Waßmann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-21  0:39   ` Stephen Warren
@ 2011-12-22  8:18     ` Dong Aisheng-B29396
  2011-12-25  3:37       ` Stephen Warren
  0 siblings, 1 reply; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2011-12-22  8:18 UTC (permalink / raw)
  To: Stephen Warren, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

Hi Stephen,

> -----Original Message-----
> From: Stephen Warren [mailto:swarren@nvidia.com]
> Sent: Wednesday, December 21, 2011 8:39 AM
> To: Dong Aisheng-B29396; linux-kernel@vger.kernel.org
> Cc: linus.walleij@stericsson.com; s.hauer@pengutronix.de;
> rob.herring@calxeda.com; linux-arm-kernel@lists.infradead.org;
> kernel@pengutronix.de; cjb@laptop.org; devicetree-discuss@lists.ozlabs.org
> Subject: RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> Dong Aisheng wrote at Tuesday, December 20, 2011 10:41 AM:
> > This patch provies a common API for driver to use to register pinmux
> > mappings from dts file. It is needed for dt support.
> 
> Dong,
> 
> Thanks for providing a concrete binding to get discussion started. I had
> intended to do this myself, but got side-tracked on other things.
> 
> I'll comment exclusively on the documentation in this patch, since any changes
> there will require the code to be changed.
> 
First, thanks for such a long and detailed comments.
I spent some time to read and understood.

> > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> > +The pin control subsystem
> > +
> > +The pin control subsystem provides a common API to support parsing
> > +pinmux mappings data from device tree. Each board dts file should
> > +provide a device node of which all the child nodes are the corresponding
> pinmux mappings.
> 
> So, the binding you propose seems very reasonable from the point-of-view of the
> Linux pinctrl subsystem. However, it violates basic device tree philosophy in a
> few ways. Some background:
> 
> Device tree is supposed to be a pure representation of hardware, not the
> software that runs on it. This means a couple of things: (a) the nodes in the DT
> generally match 1:1 with specific HW on the board (b) the design of the bindings
> should be justifiable given HW datasheets without any reference to specific
> operating systems or software driver design
> (c) the DT should be useful to all operating systems that run on the HW; there
> should be no "DT for Linux", "DT for FreeBSD", "DT for Windows".
>
I'm not DT expert, but it looks reasonable and correct.

> Hence, I see a few problems with this binding:
> 
> a) The binding is documented as being for the pinctrl subsystem, rather than for
> pinmux hardware.
>
Seems yes.

> b) The top-level node ("imx6q-sabreauto-map" below) is not tied to any
> particular piece of hardware (no compatible flag, not reg property etc.)
>
My original purpose was that it was not a hw device node, it was just created for
containing pin map information and referenced by a phandle in iomuxc deivce node
like:
iomuxc@020e0000 {
        compatible = "fsl,imx6q-iomuxc";
        reg = <0x020e0000 0x4000>;
        fsl,pinmux-map = <&pinmux>;
	  ...
}
I could also make it as a sub node of iomuxc, but original design is that sub nodes of
Ioxmuc are already representing each pinmux functions.
To avoid conflict, I put the imx6q-sabreauto-map node out of iomuxc since a phandle
(fsl,pinmux-map ) does the same work well.

For it's not a real hw device node, I was not aware of that DT has such restriction
Before. So I may use it wrongly.
But I have question that I did some research that it seemed not all the nodes in
dts file are pure hw device node
Like:
Sound in arch/arm/boot/dts/tegra-harmony.dts.
        sound {
                compatible = "nvidia,harmony-sound", "nvidia,tegra-wm8903";

                spkr-en-gpios = <&codec 2 0>;
                hp-det-gpios = <&gpio 178 0>;
                int-mic-en-gpios = <&gpio 184 0>;
                ext-mic-en-gpios = <&gpio 185 0>;
        };
I did not know how asoc to handle differenct devices binding like soc dai, pcm and machines,
But machine device seems not a real hw device.

Or even the chosen node:
chosen {
       bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk0p2 rw rootwait";
};
And I guess chosen is also Linux specific, right?

I don't know how DT define such restrictions or if there's an exception?

> c) The design of the binding is very much derived from the design of the pinctrl
> subsystem's internal data structures. This isn't necessarily bad, since in
> general SW data structures might be very closely related to how HW is put
> together. In this case though, the binding seems very SW oriented.
> 
I have the same doubt that some properties of a device node are not pure hw properties
and they're a little depending on the driver design.
Like atmel,use-dma-rx in arch/arm/boot/dts/at91sam9g20.dtsi
                        usart0: serial@fffb0000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfffb0000 0x200>;
                                interrupts = <6>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        };
And flash for partitions binding in arch/powerpc/boot/dts/mpc8378_mds.dts,
                flash@0,0 {
                        #address-cells = <1>;
                        #size-cells = <1>;
                        compatible = "cfi-flash";
                        reg = <0 0x0 0x2000000>;
                        bank-width = <2>;
                        device-width = <1>;

                        u-boot@0 {
                                reg = <0x0 0x100000>;
                                read-only;
                        };

                        fs@100000 {
                                reg = <0x100000 0x800000>;
                        };

                        kernel@1d00000 {
                                reg = <0x1d00000 0x200000>;
                        };

                        dtb@1f00000 {
                                reg = <0x1f00000 0x100000>;
                        };
                };
It depends on driver to implement it.

It loos like a historical issue since we have platform data in old way
to tell the driver what features to be enabled or not like pio or dma.
And the platform data is easily to be driver specific.

> > +The required properties for pinmux mapping are:
> > +- map-name: the name of this specific map entry
> > +- clk-dev-name: the name of the device controlling this specific
> > +mapping
> > +- funcion: a function in the driver to use for this mapping
> > +
> > +Optional properties:
> > +- group: a certain specific pin group to activate for the function
> > +- dev-name: the name of the device using this specific mapping
> > +- hog-on-boot: indicate wether hog the mappings(do not need to
> > +specify value)
> > +
> > +Examples:
> > +
> > +pinmux: imx6q-sabreauto-map {
> 
> Here we have an all-encompassing standalone "pinctrl mapping table" node.
> If we continue to have such an all-encompassing table, it should really be part
> of (a child of) the pinmux HW's node in order to tie it directly to the HW,
> rather than standing out as a HW concept. So, perhaps something more like:
> 
> iomuxc@020e0000 {
>     compatible = "fsl,imx6-pinmux";
>     usage { // I can't think of a good name for the table right now
>         sd4 {
>         };
>         sd3 {
>         };
>         ...
>     };
> };
> 
I already define pinmux functions like this:
iomuxc@020e0000 {
        fsl,pinmux-map = <&pinmux>;
        pinmux-uart4 {
                func-name = "uart4";
                grp-name = "uart4grp";
                grp-pins = <107 108>;
                num-pins = <2>;
                grp-mux = <4 4>;
                num-mux = <2>;
        };

        pinmux-sd4 {
                func-name = "sd4";
                grp-name = "sd4grp";
                grp-pins = <170 171 180 181 182 183 184 185 186 187>;
                num-pins = <10>;
                grp-mux = <0 0 1 1 1 1 1 1 1 1>;
                num-mux = <10>;
        };
};
So I move the pinmux mapping node out as I said above.

> Others have suggested that having this all-encompassing table isn't the correct
> approach, and instead, it should be split into chunks that are co-located with
> the devices that use the pinmux:
> 
> sdhci@1000 {
>     compatible = "...";
>     regs = <...>;
>     pinmux = <&pmx>;
>     pinmux-usage = {
>         // Some representation of the pins/groups/functions used
>         // by just this HW block.
>     };
> };
> sdhci@2000 {
>     compatible = "...";
>     regs = <...>;
>     pinmux = <&pmx>;
>     pinmux-usage = {
>         // Some representation of the pins/groups/functions used
>         // by just this HW block.
>     };
> };
> 
> The latter probably is a little more idiomatic, although I haven't seen or
> thought through any details on what goes inside such a "pinmux-usage"
> node yet.
> 
> > +	map-sd4 {
> > +		map-name = "usdhc4";
> 
> I don't think that field is needed; I'd suggest just using the name of the DT
> node containing the entry (which could be renamed to your desired
> names)
> 
Yes, I agree, could remove it.

> > +		ctrl-dev-name = "20e0000.iomuxc";
> ...
> > +		dev-name = "219c000.usdhc";
> 
> That name is Linux-specific. Instead of using device names, we should use
> phandle references, e.g. see the "dev" property below:
> 
Yes, I agree, will consider to change it.

> sdhci1: sdhci@1000 {
> ...
> };
> sdhci2: sdhci@1000 {
> ...
> };
> iomuxc@020e0000 {
>     compatible = "fsl,imx6-pinmux";
>     usage {
>         sd4 {
>             dev = <&sdhci1>;
>         };
>         sd3 {
>             dev = <&sdhci2>;
>         };
>         ...
>     };
> };
> 
> (in the above, your ctrl-dev-name would be implied to be iomuxc@020e0000 since
> the table is part of that pinctrl device's node)
> 
> > +		function = "sd4";
> 
> Here it would be nice to use an integer instead. However, putting lots of opaque
The question is that pinctrl is using string to address the functions.
struct pinmux_map {
        const char *name;
        struct device *ctrl_dev;
        const char *ctrl_dev_name;
        const char *function;
        const char *group;
        struct device *dev;
        const char *dev_name;
        bool hog_on_boot;
};
I wonder if using integer, we may still need to convert it to string to construct
a pinmux map.

> integers in the device tree is going to be ripe for mistakes.
> It's a real pity that dtc doesn't have a way of doing named integer constants,
> so this could be re-written as e.g.:
> 
> SoC .dtsi file:
> 
> /define/ TEGRA_MUX_FUNC_SD4 234
>
Actually I was also thinking if we could use macro in dts file, that could make
life much Easier.
 
> Board .dts file:
> 
> function = <TEGRA_MUX_FUNC_SD4>;
> 
> Without that feature, using strings here seems the only reasonable thing to do.
> 

Up to here I understand that your propose is co-locate pinmux Resource within device
Node definitions and define pinmux maps in the iomuxc device node.
(If I understand wrongly, please let me know)
It's just like:
Sdhci1: sdhci@1000 {
    compatible = "...";
    regs = <...>;
    pinmux = <&pmx>;
    pinmux-usage = {
        // Some representation of the pins/groups/functions used
        // by just this HW block.
    };
};

iomuxc@020e0000 {
    compatible = "fsl,imx6-pinmux";
    usage {
        sd4 {
            dev = <&sdhci1>;
        };
        sd3 {
            dev = <&sdhci2>;
        };
        ...
    };
};
My concern is that would pass the effort to each driver to handle pinmux-usage.

Take mx6q as an example, it may be:
Usdhc4: usdhc@0219c000 { /* uSDHC4 */
        compatible = "fsl,imx6q-usdhc";
        reg = <0x0219c000 0x4000>;
        interrupts = <0 25 0x04>;
        status = "disabled";
        pinmux-sd4 : sd4{
                func-name = "sd4";
                grp-name = "sd4grp";
                grp-pins = <170 171 180 181 182 183 184 185 186 187>;
                num-pins = <10>;
                grp-mux = <0 0 1 1 1 1 1 1 1 1>;
                num-mux = <10>;
        };

};

iomuxc@020e0000 {
    compatible = "fsl,imx6-pinmux";
    usage {
        sd4 {
            dev = <&usdhc4>;
	     function = <&pinmux-sd4>;
        };
        sd3 {
            dev = <&usdhc3>;
        };
        ...
    };
};
And I don't think it follows original design purpose: tell me how you are
and I will handle you everything.
The same question applies to clock and regulator: does each device need
Define its clock and regulator properties?

> We also need to consider compatibility and extensibility. A DT binding is an ABI
> between the kernel and whatever is providing it, and so we need to be able to
> maintain and extend it in a compatible fashion, just like the user-space syscall
> ABI. Now it's true that the .dts files are currently part of the kernel source
> tree and can be rev'd in sync with kernel changes, but that may not always be
> the case moving forward.
> 
Great, i agree and it's an idea state.

> In other words, taking a board with an old device tree embedded into Flash and
> running a new kernel using that device tree should work just like running the
> original kernel did.
> 
> There are a couple of current active areas of change in the pinctrl subsystem
> that impact this:
> 
> * Pin configuration is being added. We probably need to add the data to
> configure pin config into the mapping table in the kernel, or some parallel
> table.
> 
> * Support for pins being in multiple states (active, suspend, unused,
> ...) is being added to pinctrl. We need to be able to represent this in DT too.
> 
> (and yes I know I wrote that from a Linux pinctrl SW perspective, but the
> concepts apply to HW!)
> 
> To support this, we may just be able to add more fields to any mapping table
> entries e.g. to describe pin config setup alongside mux setup.
> It'd probably be a good idea to add some kind of "type" field to the table
> entries though, so that we can transparently add new types in the future, much
> like compatible does for HW nodes.
> 
> iomuxc@020e0000 {
>     compatible = "fsl,imx6-pinmux";
>     usage {
>         sd4 {
>             type = <0>; // 0 == mux setting
>             dev = <&sdhci1>;
>         };
>         sd3 {
>             type = <0>; // 0 == mux setting
>             dev = <&sdhci2>;
>         };
>         foo {
>             type = <1>; // 1 == pin config?
>             dev = <&sdhci2>;
>             pull-up;
>             tri-state;
>             ...
>         };
>         ...
>     };
> };
> 
Basically this is a good idea, it's very easy to understand and to use.
The key problem is where we define the pin groups its related functions
I only see pin mappings and configs here.
Since we need to pass these data to pinctrl subsystem, i don't think
it would be good to let the device driver to handle that things.

As well as pinmux, for pin config, I would also split it into two parts,
whether it shoud be handled by each pinctrl driver or pinctrl core.
If it should be handled by pinctrl driver, then ok, let it handled by
Driver and it's driver owner's responsibility to define those properties
in dt since each soc iomux controller may have different properties and
pinctrl core does not need to be aware of such dt things.

If it should be handled by pinctrl core, we may need to define some common
Properties as it needs to be parsed by pinctrl core like pin mappings.

Based on your idea, for pinconfig, one simple approach I could think is that
for pinctrl driver to handle it.
The properties could be:
iomuxc@020e0000 {
        fsl,pinmux-map = <&pinmux>;
        pinmux-uart4 {
                func-name = "uart4";
                grp-name = "uart4grp";
                grp-pins = <107 108>;
                num-pins = <2>;
                grp-mux = <4 4>;
                num-mux = <2>;
            	   pull-up; /* for group setting */
                tri-state; /* for group setting */
        };

        pinmux-sd4 {
                func-name = "sd4";
                grp-name = "sd4grp";
                grp-pins = <170 171 180 181 182 183 184 185 186 187>;
                num-pins = <10>;
                grp-mux = <0 0 1 1 1 1 1 1 1 1>;
                num-mux = <10>;
		   /* individual setting for each pin; 0: pull-up 1: tri-state */
		   conf = <0, 1, 2 ...>;
        };
};

Maybe finally remove the name properties would be better, like:
        pinmux-uart4 {
                grp-pins = <107 108>;
                num-pins = <2>;
                grp-mux = <4 4>;
                num-mux = <2>;
            	   pull-up; /* for group setting */
                tri-state; /* for group setting */
        };

Regards
Dong Aisheng


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-22  8:18     ` Dong Aisheng-B29396
@ 2011-12-25  3:37       ` Stephen Warren
  2011-12-27 14:41         ` Dong Aisheng-B29396
  2012-01-05 13:47         ` Dong Aisheng
  0 siblings, 2 replies; 98+ messages in thread
From: Stephen Warren @ 2011-12-25  3:37 UTC (permalink / raw)
  To: Dong Aisheng-B29396, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

Dong Aisheng-B29396 wrote at Thursday, December 22, 2011 1:18 AM:
> Stephen Warren wrote at Wednesday, December 21, 2011 8:39 AM:
> > Dong Aisheng wrote at Tuesday, December 20, 2011 10:41 AM:
> > > This patch provies a common API for driver to use to register pinmux
> > > mappings from dts file. It is needed for dt support.
> >
> > Dong,
> >
> > Thanks for providing a concrete binding to get discussion started. I had
> > intended to do this myself, but got side-tracked on other things.
> >
> > I'll comment exclusively on the documentation in this patch, since any changes
> > there will require the code to be changed.
>
> First, thanks for such a long and detailed comments.
> I spent some time to read and understood.
> 
> > > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> > > +The pin control subsystem
> > > +
> > > +The pin control subsystem provides a common API to support parsing
> > > +pinmux mappings data from device tree. Each board dts file should
> > > +provide a device node of which all the child nodes are the corresponding
> > pinmux mappings.
> >
> > So, the binding you propose seems very reasonable from the point-of-view of the
> > Linux pinctrl subsystem. However, it violates basic device tree philosophy in a
> > few ways. Some background:
> >
> > Device tree is supposed to be a pure representation of hardware, not the
> > software that runs on it. This means a couple of things: (a) the nodes in the DT
> > generally match 1:1 with specific HW on the board (b) the design of the bindings
> > should be justifiable given HW datasheets without any reference to specific
> > operating systems or software driver design
> > (c) the DT should be useful to all operating systems that run on the HW; there
> > should be no "DT for Linux", "DT for FreeBSD", "DT for Windows".
>
> I'm not DT expert, but it looks reasonable and correct.

I'm not sure if you're saying that the original binding seems reasonable
or my comments seem reasonable.

> > Hence, I see a few problems with this binding:
> >
> > a) The binding is documented as being for the pinctrl subsystem, rather than for
> > pinmux hardware.
>
> Seems yes.
> 
> > b) The top-level node ("imx6q-sabreauto-map" below) is not tied to any
> > particular piece of hardware (no compatible flag, not reg property etc.)
>
> My original purpose was that it was not a hw device node, it was just created for
> containing pin map information and referenced by a phandle in iomuxc deivce node
> like:
>
> iomuxc@020e0000 {
>         compatible = "fsl,imx6q-iomuxc";
>         reg = <0x020e0000 0x4000>;
>         fsl,pinmux-map = <&pinmux>;
> 	  ...
> }
>
> I could also make it as a sub node of iomuxc, but original design is that sub nodes of
> Ioxmuc are already representing each pinmux functions.
> To avoid conflict, I put the imx6q-sabreauto-map node out of iomuxc since a phandle
> (fsl,pinmux-map ) does the same work well.

You could have nested sub-nodes, say something like:

iomuxc@020e0000 {
    compatible = "fsl,imx6q-iomuxc";
    reg = <0x020e0000 0x4000>;
    fsl,pins {
        ... // fsl-specific pin properties
    };
    fsl,groups {
        ... // fsl-specific group properties
    };
    fsl,functions {
        ... // fsl-specific mux function properties
    };
    pinmux-usage {
        // standardized pinmux "table" properties
        sd4 { // pin group name
            function = "sdio4"; // this function active on it
            ...
        };
        ...
    }
    ...
}

> For it's not a real hw device node, I was not aware of that DT has such restriction
> Before. So I may use it wrongly.
> But I have question that I did some research that it seemed not all the nodes in
> dts file are pure hw device node

Certainly there are exceptions; "describe only HW" is more of a general
principle rather than a completely unbreakable rule I think.

I think that pinmux usage is a concept that's very HW oriented and can
hopefully have a pure HW binding, rather than something too influenced
by the pinctrl SW.

> Like:
> Sound in arch/arm/boot/dts/tegra-harmony.dts.
>         sound {
>                 compatible = "nvidia,harmony-sound", "nvidia,tegra-wm8903";
> 
>                 spkr-en-gpios = <&codec 2 0>;
>                 hp-det-gpios = <&gpio 178 0>;
>                 int-mic-en-gpios = <&gpio 184 0>;
>                 ext-mic-en-gpios = <&gpio 185 0>;
>         };
> I did not know how asoc to handle differenct devices binding like soc dai, pcm and machines,
> But machine device seems not a real hw device.

I'd still classify this as a pure HW description. While there certainly
isn't a single thing you can point at in the SoC or board that is the
sound card, a description of the components and wiring that makes up the
sound system certainly is a HW description. Note that the binding above
also isn't finished, and has been reworked a bit since then, although
the new one is conceptually very similar.

> Or even the chosen node:
> chosen {
>        bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk0p2 rw rootwait";
> };
> And I guess chosen is also Linux specific, right?

Yes, that's certainly SW-specific and an exception, and as you pointed
out below, there are some other exceptions.

My main point is that when we can design bindings that are purely HW
oriented we should, and when we can't, we should get as close as we can.

...
> Up to here I understand that your propose is co-locate pinmux Resource within device
> Node definitions and define pinmux maps in the iomuxc device node.
> (If I understand wrongly, please let me know)
> It's just like:
> Sdhci1: sdhci@1000 {
>     compatible = "...";
>     regs = <...>;
>     pinmux = <&pmx>;
>     pinmux-usage = {
>         // Some representation of the pins/groups/functions used
>         // by just this HW block.
>     };
> };
> 
> iomuxc@020e0000 {
>     compatible = "fsl,imx6-pinmux";
>     usage {
>         sd4 {
>             dev = <&sdhci1>;
>         };
>         sd3 {
>             dev = <&sdhci2>;
>         };
>         ...
>     };
> };
> My concern is that would pass the effort to each driver to handle pinmux-usage.

See a little above for what I was thinking.

That said, we could  probably handle a standardized pinmux-usage property
in each driver without impacting each driver too much; it's just that the
core driver code, or the pinctrl code, would have to scan all device nodes
for this property and act on it, rather than the drivers for each node,
rather like regs/interrupts are handled by core code and converted to
device resources.

...
> The same question applies to clock and regulator: does each device need
> Define its clock and regulator properties?

Yes, in those cases I believe each device does contain a phandle to the
resources it uses.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-25  3:37       ` Stephen Warren
@ 2011-12-27 14:41         ` Dong Aisheng-B29396
  2011-12-29  2:46           ` Shawn Guo
  2012-01-05 23:38           ` Stephen Warren
  2012-01-05 13:47         ` Dong Aisheng
  1 sibling, 2 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2011-12-27 14:41 UTC (permalink / raw)
  To: Stephen Warren, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

> -----Original Message-----
> From: Stephen Warren [mailto:swarren@nvidia.com]
> Sent: Sunday, December 25, 2011 11:37 AM
> To: Dong Aisheng-B29396; linux-kernel@vger.kernel.org
> Cc: linus.walleij@stericsson.com; s.hauer@pengutronix.de;
> rob.herring@calxeda.com; linux-arm-kernel@lists.infradead.org;
> kernel@pengutronix.de; cjb@laptop.org; devicetree-discuss@lists.ozlabs.org
> Subject: RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> Dong Aisheng-B29396 wrote at Thursday, December 22, 2011 1:18 AM:
> > Stephen Warren wrote at Wednesday, December 21, 2011 8:39 AM:
> > > Dong Aisheng wrote at Tuesday, December 20, 2011 10:41 AM:
> > > > This patch provies a common API for driver to use to register
> > > > pinmux mappings from dts file. It is needed for dt support.
> > >
> > > Dong,
> > >
> > > Thanks for providing a concrete binding to get discussion started. I
> > > had intended to do this myself, but got side-tracked on other things.
> > >
> > > I'll comment exclusively on the documentation in this patch, since
> > > any changes there will require the code to be changed.
> >
> > First, thanks for such a long and detailed comments.
> > I spent some time to read and understood.
> >
> > > > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> > > > +The pin control subsystem
> > > > +
> > > > +The pin control subsystem provides a common API to support
> > > > +parsing pinmux mappings data from device tree. Each board dts
> > > > +file should provide a device node of which all the child nodes
> > > > +are the corresponding
> > > pinmux mappings.
> > >
> > > So, the binding you propose seems very reasonable from the
> > > point-of-view of the Linux pinctrl subsystem. However, it violates
> > > basic device tree philosophy in a few ways. Some background:
> > >
> > > Device tree is supposed to be a pure representation of hardware, not
> > > the software that runs on it. This means a couple of things: (a) the
> > > nodes in the DT generally match 1:1 with specific HW on the board
> > > (b) the design of the bindings should be justifiable given HW
> > > datasheets without any reference to specific operating systems or
> > > software driver design
> > > (c) the DT should be useful to all operating systems that run on the
> > > HW; there should be no "DT for Linux", "DT for FreeBSD", "DT for Windows".
> >
> > I'm not DT expert, but it looks reasonable and correct.
> 
> I'm not sure if you're saying that the original binding seems reasonable or my
> comments seem reasonable.
> 
I mean your comments on DT background seems reasonable.

> > > Hence, I see a few problems with this binding:
> > >
> > > a) The binding is documented as being for the pinctrl subsystem,
> > > rather than for pinmux hardware.
> >
> > Seems yes.
> >
> > > b) The top-level node ("imx6q-sabreauto-map" below) is not tied to
> > > any particular piece of hardware (no compatible flag, not reg
> > > property etc.)
> >
> > My original purpose was that it was not a hw device node, it was just
> > created for containing pin map information and referenced by a phandle
> > in iomuxc deivce node
> > like:
> >
> > iomuxc@020e0000 {
> >         compatible = "fsl,imx6q-iomuxc";
> >         reg = <0x020e0000 0x4000>;
> >         fsl,pinmux-map = <&pinmux>;
> > 	  ...
> > }
> >
> > I could also make it as a sub node of iomuxc, but original design is
> > that sub nodes of Ioxmuc are already representing each pinmux functions.
> > To avoid conflict, I put the imx6q-sabreauto-map node out of iomuxc
> > since a phandle (fsl,pinmux-map ) does the same work well.
> 
> You could have nested sub-nodes, say something like:
> 
> iomuxc@020e0000 {
>     compatible = "fsl,imx6q-iomuxc";
>     reg = <0x020e0000 0x4000>;
>     fsl,pins {
>         ... // fsl-specific pin properties
>     };
>     fsl,groups {
>         ... // fsl-specific group properties
>     };
>     fsl,functions {
>         ... // fsl-specific mux function properties
>     };
>     pinmux-usage {
>         // standardized pinmux "table" properties
>         sd4 { // pin group name
>             function = "sdio4"; // this function active on it
>             ...
>         };
>         ...
>     }
>     ...
> }
> 
Yes, I could do that.
The extra effort is that we have to manually exclude one pinmux-usage
node in pinmux driver since originally i take the child node count of
iomuxc as the function count since all child nodes are functions,
that why I firstly took the mapping node out of iomuxc, in addition
the old way i used seems to be more brief and clear.

I tried adding pinmux-usage as a sub node of iomuxc and got two issues:
Taking imx6q as an example:
iomuxc@020e0000 {
        uart4 {
                func-name = "uart4";
                grp-name = "uart4grp";
                grp-pins = <107 108>;
                num-pins = <2>;
                grp-mux = <4 4>;
                num-mux = <2>;
        };

        sd4 {
                func-name = "sd4";
                grp-name = "sd4grp";
                grp-pins = <170 171 180 181 182 183 184 185 186 187>;
                num-pins = <10>;
                grp-mux = <0 0 1 1 1 1 1 1 1 1>;
                num-mux = <10>;
        };

        pinmux-mapping {
                uart4 {
                        function = "uart4";
                        dev = <&uart4>;
                };

                usdhc4 {
/*			    ctrl-dev-name = "20e0000.iomuxc"; */
                        function = "sd4";
                        dev = <&usdhc4>;
                };
        };
};

If we remove ctrl-dev-name and get it from its parent node in drivers as
you suggested,
first, since this work will be done in the common API (pinmux_of_register_mappings
Requires pass the pinmux mapping node to it for construct the mapping table)
It will introduce a restriction that all platforms should define this node
under their pinctrl device node.
Second, it seems we cannot get its parent node device or device name in driver
(can only get node Name which is not sufficient for construct the pin map table
required by pinctrl core) and current device tree subsystem seems do not support
get its associated device from a device node.
We may not be able to construct ctrl-dev-name or ctrl-dev for struct pinmux_map.
I'm not sure if I missed something, if missed please let me know.
To support it, we may need to add support for converting device node
to device. Not sure it's applicable since I still have not tried it.

The same issue applies to dev using a phandle.

> > For it's not a real hw device node, I was not aware of that DT has
> > such restriction Before. So I may use it wrongly.
> > But I have question that I did some research that it seemed not all
> > the nodes in dts file are pure hw device node
> 
> Certainly there are exceptions; "describe only HW" is more of a general
> principle rather than a completely unbreakable rule I think.
> 
> I think that pinmux usage is a concept that's very HW oriented and can hopefully
> have a pure HW binding, rather than something too influenced by the pinctrl SW.
> 
> > Like:
> > Sound in arch/arm/boot/dts/tegra-harmony.dts.
> >         sound {
> >                 compatible = "nvidia,harmony-sound",
> > "nvidia,tegra-wm8903";
> >
> >                 spkr-en-gpios = <&codec 2 0>;
> >                 hp-det-gpios = <&gpio 178 0>;
> >                 int-mic-en-gpios = <&gpio 184 0>;
> >                 ext-mic-en-gpios = <&gpio 185 0>;
> >         };
> > I did not know how asoc to handle differenct devices binding like soc
> > dai, pcm and machines, But machine device seems not a real hw device.
> 
> I'd still classify this as a pure HW description. While there certainly isn't a
> single thing you can point at in the SoC or board that is the sound card, a
> description of the components and wiring that makes up the sound system
> certainly is a HW description. Note that the binding above also isn't finished,
> and has been reworked a bit since then, although the new one is conceptually
> very similar.
> 
I agree from that point of view.

> > Or even the chosen node:
> > chosen {
> >        bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8
> > root=/dev/mmcblk0p2 rw rootwait"; }; And I guess chosen is also Linux
> > specific, right?
> 
> Yes, that's certainly SW-specific and an exception, and as you pointed out below,
> there are some other exceptions.
> 
> My main point is that when we can design bindings that are purely HW oriented we
> should, and when we can't, we should get as close as we can.
> 
> ...
> > Up to here I understand that your propose is co-locate pinmux Resource
> > within device Node definitions and define pinmux maps in the iomuxc device
> node.
> > (If I understand wrongly, please let me know) It's just like:
> > Sdhci1: sdhci@1000 {
> >     compatible = "...";
> >     regs = <...>;
> >     pinmux = <&pmx>;
> >     pinmux-usage = {
> >         // Some representation of the pins/groups/functions used
> >         // by just this HW block.
> >     };
> > };
> >
> > iomuxc@020e0000 {
> >     compatible = "fsl,imx6-pinmux";
> >     usage {
> >         sd4 {
> >             dev = <&sdhci1>;
> >         };
> >         sd3 {
> >             dev = <&sdhci2>;
> >         };
> >         ...
> >     };
> > };
> > My concern is that would pass the effort to each driver to handle pinmux-usage.
> 
> See a little above for what I was thinking.
> 
> That said, we could  probably handle a standardized pinmux-usage property in
> each driver without impacting each driver too much; it's just that the core
> driver code, or the pinctrl code, would have to scan all device nodes for this
> property and act on it, rather than the drivers for each node, rather like
> regs/interrupts are handled by core code and converted to device resources.
> 
> ...
> > The same question applies to clock and regulator: does each device
> > need Define its clock and regulator properties?
> 
> Yes, in those cases I believe each device does contain a phandle to the
> resources it uses.
> 
I was ever thought putting a phandle of pinmux function in each device,
Then pinmux mapping table seems not need anymore. Like:

usdhc4: usdhc@0219c000 { /* uSDHC4 */
        compatible = "fsl,imx6q-usdhc";
	....
        pinmux = <&pinmux-sd4>;
};

iomuxc@020e0000 {
        pinmux-sd4 : sd4 {
                func-name = "sd4";
                grp-name = "sd4grp";
                grp-pins = <170 171 180 181 182 183 184 185 186 187>;
                num-pins = <10>;
                grp-mux = <0 0 1 1 1 1 1 1 1 1>;
                num-mux = <10>;
        };

It is a pure hw point of view to define node.
And it may need to implement a of_pinmux_get.
But what about the pin maps without device associated?

Regards
Dong Aisheng


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-27 14:41         ` Dong Aisheng-B29396
@ 2011-12-29  2:46           ` Shawn Guo
  2012-01-05 13:14             ` Dong Aisheng
  2012-01-05 23:45             ` Stephen Warren
  2012-01-05 23:38           ` Stephen Warren
  1 sibling, 2 replies; 98+ messages in thread
From: Shawn Guo @ 2011-12-29  2:46 UTC (permalink / raw)
  To: Dong Aisheng-B29396
  Cc: Stephen Warren, linux-kernel, linus.walleij, s.hauer,
	rob.herring, kernel, cjb, devicetree-discuss, linux-arm-kernel

On Tue, Dec 27, 2011 at 02:41:25PM +0000, Dong Aisheng-B29396 wrote:
[...]
> > You could have nested sub-nodes, say something like:
> > 
> > iomuxc@020e0000 {
> >     compatible = "fsl,imx6q-iomuxc";
> >     reg = <0x020e0000 0x4000>;
> >     fsl,pins {
> >         ... // fsl-specific pin properties
> >     };
> >     fsl,groups {
> >         ... // fsl-specific group properties
> >     };
> >     fsl,functions {
> >         ... // fsl-specific mux function properties
> >     };
> >     pinmux-usage {
> >         // standardized pinmux "table" properties
> >         sd4 { // pin group name
> >             function = "sdio4"; // this function active on it
> >             ...
> >         };
> >         ...
> >     }
> >     ...
> > }
> > 
> Yes, I could do that.
> The extra effort is that we have to manually exclude one pinmux-usage
> node in pinmux driver since originally i take the child node count of
> iomuxc as the function count since all child nodes are functions,
> that why I firstly took the mapping node out of iomuxc, in addition
> the old way i used seems to be more brief and clear.
> 
Stephen suggested you put all the function nodes under node
'fsl,functions' (not sure prefix fsl is necessary).  In that case,
of_get_child_count() on 'fsl,functions' still get you the function
count you want, right?

But we do not bother with it, if we do not have pinmux-usage at all.
See below ...

> I tried adding pinmux-usage as a sub node of iomuxc and got two issues:
> Taking imx6q as an example:
> iomuxc@020e0000 {
>         uart4 {
>                 func-name = "uart4";
>                 grp-name = "uart4grp";
>                 grp-pins = <107 108>;
>                 num-pins = <2>;
>                 grp-mux = <4 4>;
>                 num-mux = <2>;
>         };
> 
>         sd4 {
>                 func-name = "sd4";
>                 grp-name = "sd4grp";
>                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
>                 num-pins = <10>;
>                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
>                 num-mux = <10>;
>         };
> 
>         pinmux-mapping {
>                 uart4 {
>                         function = "uart4";
>                         dev = <&uart4>;
>                 };
> 
>                 usdhc4 {
> /*			    ctrl-dev-name = "20e0000.iomuxc"; */
>                         function = "sd4";
>                         dev = <&usdhc4>;
>                 };
>         };
> };
> 
> If we remove ctrl-dev-name and get it from its parent node in drivers as
> you suggested,
> first, since this work will be done in the common API (pinmux_of_register_mappings
> Requires pass the pinmux mapping node to it for construct the mapping table)
> It will introduce a restriction that all platforms should define this node
> under their pinctrl device node.
> Second, it seems we cannot get its parent node device or device name in driver
> (can only get node Name which is not sufficient for construct the pin map table
> required by pinctrl core) and current device tree subsystem seems do not support
> get its associated device from a device node.
> We may not be able to construct ctrl-dev-name or ctrl-dev for struct pinmux_map.
> I'm not sure if I missed something, if missed please let me know.
> To support it, we may need to add support for converting device node
> to device. Not sure it's applicable since I still have not tried it.
> 
> The same issue applies to dev using a phandle.
> 
We do not bother with it, if we do not have pinmux-usage at all.
See below ...

[...]

> I was ever thought putting a phandle of pinmux function in each device,
> Then pinmux mapping table seems not need anymore. Like:
> 
> usdhc4: usdhc@0219c000 { /* uSDHC4 */
>         compatible = "fsl,imx6q-usdhc";
> 	....
>         pinmux = <&pinmux-sd4>;
> };
> 
> iomuxc@020e0000 {
>         pinmux-sd4 : sd4 {
>                 func-name = "sd4";
>                 grp-name = "sd4grp";
>                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
>                 num-pins = <10>;
>                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
>                 num-mux = <10>;
>         };
> 
> It is a pure hw point of view to define node.

That's the way we should go for.  This is exactly the same thing that
clk and regulator DT support is doing.  And right, in that way, we do
not need pinmux mapping for DT at all.

> And it may need to implement a of_pinmux_get.

To make the pinmux api generic for both dt and non-dt users, the pinmux
client driver should still see/call pinmux_get, something like
of_pinmux_get should be sorted out behind pinmux_get.

> But what about the pin maps without device associated?
> 
Do we have such cases?

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 5/5] mmc: sdhci-esdhc-imx: using pinmux subsystem
  2011-12-20 17:40 ` [RFC PATCH v3 5/5] mmc: sdhci-esdhc-imx: " Dong Aisheng
@ 2012-01-01 13:54   ` Linus Walleij
  0 siblings, 0 replies; 98+ messages in thread
From: Linus Walleij @ 2012-01-01 13:54 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss

On Tue, Dec 20, 2011 at 6:40 PM, Dong Aisheng <b29396@freescale.com> wrote:

> From: Dong Aisheng <dong.aisheng@linaro.org>

Looks idiomatically ideal from a pinctrl point of view, so
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 1/5] dt: add of_get_child_count helper function
  2011-12-21  2:56     ` Dong Aisheng-B29396
@ 2012-01-01 13:58       ` Linus Walleij
  0 siblings, 0 replies; 98+ messages in thread
From: Linus Walleij @ 2012-01-01 13:58 UTC (permalink / raw)
  To: Dong Aisheng-B29396, Rob Herring
  Cc: linus.walleij, s.hauer, linux-kernel, Guo Shawn-R65073, kernel,
	cjb, devicetree-discuss, linux-arm-kernel

On Wed, Dec 21, 2011 at 3:56 AM, Dong Aisheng-B29396
<B29396@freescale.com> wrote:
>> On 12/20/2011 11:40 AM, Dong Aisheng wrote:
>> > From: Dong Aisheng <dong.aisheng@linaro.org>
>> >
>> > Currently most code to get child count in kernel are almost same, add
>> > a helper to implement this function for dt to use.
>> >
>> > ---
>> > Changes v1->v2:
>> >  * change the name from of_get_child_number to of_get_child_count
>> >
>> > Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
>> > Cc: Grant Likely <grant.likely@secretlab.ca>
>> > Cc: Rob Herring <rob.herring@calxeda.com>
>>
>> I assume you want this to go in with the rest of the series? If not, let me know.
>>
>> Acked-by: Rob Herring <rob.herring@calxeda.com>
>>
>> Rob
>>
> Yes, since other patches in this series depend on this patch.
> Thanks for the review.

Does that mean the entire shebang needs to be merged through the
pinctrl subsystem?

If this patch stands on it's own, I think it's proper to merge it into
the DT for-next tree now, since we don't know if this entire series
will make it into the next merge window.

If the patch would anyway happen to end up in two trees,
no big deal.

Rob, can you merge it?

Thanks,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2011-12-20 17:40 ` [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver Dong Aisheng
  2011-12-20 19:50   ` Marek Vasut
@ 2012-01-01 14:02   ` Linus Walleij
  2012-01-08 13:05   ` Richard Zhao
  2 siblings, 0 replies; 98+ messages in thread
From: Linus Walleij @ 2012-01-01 14:02 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-kernel, linux-arm-kernel, linus.walleij, s.hauer,
	shawn.guo, kernel, grant.likely, rob.herring, devicetree-discuss,
	cjb, w.sang

On Tue, Dec 20, 2011 at 6:40 PM, Dong Aisheng <b29396@freescale.com> wrote:

> From: Dong Aisheng <dong.aisheng@linaro.org>
>
> The driver contains the initial support for imx53 and
> imx6q.

Looks real good from a pinctrl point of view.
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Now I guess it's that patch 2/5 that is at the heart of how we proceed
with this. I guess this patch depends on 2/5?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-20 17:40 ` [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings Dong Aisheng
  2011-12-20 19:48   ` Marek Vasut
  2011-12-21  0:39   ` Stephen Warren
@ 2012-01-01 14:07   ` Linus Walleij
  2012-01-01 15:22     ` Rob Herring
  2012-01-05 13:59     ` Dong Aisheng
  2 siblings, 2 replies; 98+ messages in thread
From: Linus Walleij @ 2012-01-01 14:07 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss

On Tue, Dec 20, 2011 at 6:40 PM, Dong Aisheng <b29396@freescale.com> wrote:

> From: Dong Aisheng <dong.aisheng@linaro.org>
>
> This patch provies a common API for driver to use to register pinmux
> mappings from dts file. It is needed for dt support.

Overall I feel lost in this discussion due to limited exposure to
device tree concepts. If I get Stephen Warrens and one of the
DT people's (Rob, Grant) ACK on this I'll be happy to merge it.

Until then, I guess it will need to be refined for the next kernel
cycle.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-01 14:07   ` Linus Walleij
@ 2012-01-01 15:22     ` Rob Herring
  2012-01-05 13:59     ` Dong Aisheng
  1 sibling, 0 replies; 98+ messages in thread
From: Rob Herring @ 2012-01-01 15:22 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Dong Aisheng, linus.walleij, s.hauer, linux-kernel, rob.herring,
	kernel, cjb, devicetree-discuss, linux-arm-kernel

On 01/01/2012 08:07 AM, Linus Walleij wrote:
> On Tue, Dec 20, 2011 at 6:40 PM, Dong Aisheng <b29396@freescale.com> wrote:
> 
>> From: Dong Aisheng <dong.aisheng@linaro.org>
>>
>> This patch provies a common API for driver to use to register pinmux
>> mappings from dts file. It is needed for dt support.
> 
> Overall I feel lost in this discussion due to limited exposure to
> device tree concepts. If I get Stephen Warrens and one of the
> DT people's (Rob, Grant) ACK on this I'll be happy to merge it.
> 
> Until then, I guess it will need to be refined for the next kernel
> cycle.

Yes. As Stephen has commented, this still needs a bit of work on the
binding.

Rob

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-29  2:46           ` Shawn Guo
@ 2012-01-05 13:14             ` Dong Aisheng
  2012-01-05 23:45             ` Stephen Warren
  1 sibling, 0 replies; 98+ messages in thread
From: Dong Aisheng @ 2012-01-05 13:14 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Dong Aisheng-B29396, Stephen Warren, linux-kernel, linus.walleij,
	s.hauer, rob.herring, kernel, cjb, devicetree-discuss,
	linux-arm-kernel

On Thu, Dec 29, 2011 at 10:46 AM, Shawn Guo <shawn.guo@freescale.com> wrote:
> On Tue, Dec 27, 2011 at 02:41:25PM +0000, Dong Aisheng-B29396 wrote:
> [...]
>> > You could have nested sub-nodes, say something like:
>> >
>> > iomuxc@020e0000 {
>> >     compatible = "fsl,imx6q-iomuxc";
>> >     reg = <0x020e0000 0x4000>;
>> >     fsl,pins {
>> >         ... // fsl-specific pin properties
>> >     };
>> >     fsl,groups {
>> >         ... // fsl-specific group properties
>> >     };
>> >     fsl,functions {
>> >         ... // fsl-specific mux function properties
>> >     };
>> >     pinmux-usage {
>> >         // standardized pinmux "table" properties
>> >         sd4 { // pin group name
>> >             function = "sdio4"; // this function active on it
>> >             ...
>> >         };
>> >         ...
>> >     }
>> >     ...
>> > }
>> >
>> Yes, I could do that.
>> The extra effort is that we have to manually exclude one pinmux-usage
>> node in pinmux driver since originally i take the child node count of
>> iomuxc as the function count since all child nodes are functions,
>> that why I firstly took the mapping node out of iomuxc, in addition
>> the old way i used seems to be more brief and clear.
>>
> Stephen suggested you put all the function nodes under node
> 'fsl,functions' (not sure prefix fsl is necessary).  In that case,
> of_get_child_count() on 'fsl,functions' still get you the function
> count you want, right?
>
> But we do not bother with it, if we do not have pinmux-usage at all.
> See below ...
>
>> I tried adding pinmux-usage as a sub node of iomuxc and got two issues:
>> Taking imx6q as an example:
>> iomuxc@020e0000 {
>>         uart4 {
>>                 func-name = "uart4";
>>                 grp-name = "uart4grp";
>>                 grp-pins = <107 108>;
>>                 num-pins = <2>;
>>                 grp-mux = <4 4>;
>>                 num-mux = <2>;
>>         };
>>
>>         sd4 {
>>                 func-name = "sd4";
>>                 grp-name = "sd4grp";
>>                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
>>                 num-pins = <10>;
>>                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
>>                 num-mux = <10>;
>>         };
>>
>>         pinmux-mapping {
>>                 uart4 {
>>                         function = "uart4";
>>                         dev = <&uart4>;
>>                 };
>>
>>                 usdhc4 {
>> /*                        ctrl-dev-name = "20e0000.iomuxc"; */
>>                         function = "sd4";
>>                         dev = <&usdhc4>;
>>                 };
>>         };
>> };
>>
>> If we remove ctrl-dev-name and get it from its parent node in drivers as
>> you suggested,
>> first, since this work will be done in the common API (pinmux_of_register_mappings
>> Requires pass the pinmux mapping node to it for construct the mapping table)
>> It will introduce a restriction that all platforms should define this node
>> under their pinctrl device node.
>> Second, it seems we cannot get its parent node device or device name in driver
>> (can only get node Name which is not sufficient for construct the pin map table
>> required by pinctrl core) and current device tree subsystem seems do not support
>> get its associated device from a device node.
>> We may not be able to construct ctrl-dev-name or ctrl-dev for struct pinmux_map.
>> I'm not sure if I missed something, if missed please let me know.
>> To support it, we may need to add support for converting device node
>> to device. Not sure it's applicable since I still have not tried it.
>>
>> The same issue applies to dev using a phandle.
>>
> We do not bother with it, if we do not have pinmux-usage at all.
> See below ...
>
> [...]
>
>> I was ever thought putting a phandle of pinmux function in each device,
>> Then pinmux mapping table seems not need anymore. Like:
>>
>> usdhc4: usdhc@0219c000 { /* uSDHC4 */
>>         compatible = "fsl,imx6q-usdhc";
>>       ....
>>         pinmux = <&pinmux-sd4>;
>> };
>>
>> iomuxc@020e0000 {
>>         pinmux-sd4 : sd4 {
>>                 func-name = "sd4";
>>                 grp-name = "sd4grp";
>>                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
>>                 num-pins = <10>;
>>                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
>>                 num-mux = <10>;
>>         };
>>
>> It is a pure hw point of view to define node.
>
> That's the way we should go for.  This is exactly the same thing that
> clk and regulator DT support is doing.  And right, in that way, we do
> not need pinmux mapping for DT at all.
>
I tried this way and basically it works but has a few limitations due to
via dt.
I will send out patch in this thread for discussion.

>> And it may need to implement a of_pinmux_get.
>
> To make the pinmux api generic for both dt and non-dt users, the pinmux
> client driver should still see/call pinmux_get, something like
> of_pinmux_get should be sorted out behind pinmux_get.
>
>> But what about the pin maps without device associated?
>>
> Do we have such cases?
>
It's hog_on_boot function.

Regards
Dong Aisheng

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-25  3:37       ` Stephen Warren
  2011-12-27 14:41         ` Dong Aisheng-B29396
@ 2012-01-05 13:47         ` Dong Aisheng
  2012-01-06  1:05           ` Stephen Warren
  1 sibling, 1 reply; 98+ messages in thread
From: Dong Aisheng @ 2012-01-05 13:47 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, linux-kernel, linus.walleij, s.hauer,
	rob.herring, linux-arm-kernel, kernel, cjb, devicetree-discuss

Hi Stephen,

On Sun, Dec 25, 2011 at 11:37 AM, Stephen Warren <swarren@nvidia.com> wrote:
> Dong Aisheng-B29396 wrote at Thursday, December 22, 2011 1:18 AM:
> ...
>> Up to here I understand that your propose is co-locate pinmux Resource within device
>> Node definitions and define pinmux maps in the iomuxc device node.
>> (If I understand wrongly, please let me know)
>> It's just like:
>> Sdhci1: sdhci@1000 {
>>     compatible = "...";
>>     regs = <...>;
>>     pinmux = <&pmx>;
>>     pinmux-usage = {
>>         // Some representation of the pins/groups/functions used
>>         // by just this HW block.
>>     };
>> };
>>
>> iomuxc@020e0000 {
>>     compatible = "fsl,imx6-pinmux";
>>     usage {
>>         sd4 {
>>             dev = <&sdhci1>;
>>         };
>>         sd3 {
>>             dev = <&sdhci2>;
>>         };
>>         ...
>>     };
>> };
>> My concern is that would pass the effort to each driver to handle pinmux-usage.
>
> See a little above for what I was thinking.
>
> That said, we could  probably handle a standardized pinmux-usage property
> in each driver without impacting each driver too much; it's just that the
> core driver code, or the pinctrl code, would have to scan all device nodes
> for this property and act on it, rather than the drivers for each node,
> rather like regs/interrupts are handled by core code and converted to
> device resources.
>
> ...
>> The same question applies to clock and regulator: does each device need
>> Define its clock and regulator properties?
>
> Yes, in those cases I believe each device does contain a phandle to the
> resources it uses.
>

I tried this way that each device node contains a phandle named
'pinmux' pointing
to a specific pinmux function. When the device calling pinmux_get we will
find the pinmux function and its pinctrl device via this phandle, then
we can construct
a pinmux map to use for this device.
Then we do not need define pinmux map table in dts file any more.
This looks better than before from hw point of vew in define device nodes.

I paste the initial patch here for your review to see if it's ok.
However there're still two issues:
1) since we still do not have a standardized pinmux function
definition(it looks not easy to define since it varies on different
platforms and pinctrl core also does not require a standardized
function, not sure if we should define one)
we can not get pin group info via dt in a standardized way for
construct pinmux map.
That means we do not support parsing multi pin groups for one function from dt.
However it will not affect the function in most case since board dts
file usually know which pin group for which function and usually one
pin group are defined.
I still do not see if any requirement of multi pin groups are needed via dt.
2) we still do not support hog_on_boot due to we do not have pinmux
map tables in dt and it varies a bit
on the using from non-dt platform,
I'm still trying to figuring out a way to cover this issue.
If you have any good suggestion please let me know.

>From 651113ff5909cd054396e97f25f386f846046a55 Mon Sep 17 00:00:00 2001
From: Dong Aisheng <b29396@freescale.com>
Date: Thu, 5 Jan 2012 21:11:08 +0800
Subject: [PATCH 1/1] pinctrl: add dt binding support for pinmux mappings

Since dt already has the pinmux map information in dts file, it does
not have a pinmux maps table registered in machine code as non-dt
platfrom does. Instead, it will create a pinmux map for each device
dynamically by parsing the device node when calling pinmux_get.

To support this, each device wanting to use a pinmux function should
define a phandle named 'pinmux' pointing to a specific pinmux function
under its device node. And the pinmux function nodes should be defined
under the pinctrl device it belongs to.

The pinmux core will use this phandle to find the pinmux function
name and the pinctrl device this function belongs to to construct
a pinmux map for this device to use.

The constraints are that we still do not support parsing multi groups
for a function via dt, that means only first group will be used.
Usually this does not affect the pinmux to work well via dt since the
board dts file knows which pin group for which function and we do not
need to define more than one useless groups for that function.

Another constraint is that we still do not support hog_on_boot via dt
since dt does not have a pinmux map table and we need to create it
dynamically. We still need to find a good way to cover this issue.

Signed-off-by: Dong Aisheng <b29396@freescale.com>
---
 .../devicetree/bindings/pinctrl/pinctrl.txt        |   49 ++++++++++++++
 arch/arm/boot/dts/imx6q-sabreauto.dts              |   24 +++++++
 drivers/pinctrl/core.c                             |   69 ++++++++++++++++++++
 drivers/pinctrl/core.h                             |    2 +
 drivers/pinctrl/pinmux.c                           |   27 +++++++-
 5 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
b/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
new file mode 100644
index 0000000..013e733
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
@@ -0,0 +1,49 @@
+The pin control subsystem
+
+The pin control subsystem supports parsing pinmux map from device tree.
+To support this, each device wanting to use a pinmux function should
+define a phandle named 'pinmux' pointing to a specific pinmux function
+under its device node. And the pinmux function nodes should be defined
+under the pinctrl device it belongs to.
+
+The pinmux core will use this phandle to find the pinmux function
+name and the pinctrl device this function belongs to to construct
+a pinmux map for this device to use.
+
+Examples:
+soc {
+	aips-bus@02000000 { /* AIPS1 */
+		iomuxc@020e0000 {
+			pinctrl_uart4: uart4 {
+				func-name = "uart4";
+				grp-name = "uart4grp";
+				grp-pins = <107 108>;
+				num-pins = <2>;
+				grp-mux = <4 4>;
+				num-mux = <2>;
+			};
+
+			pinctrl_sd4: sd4 {
+				func-name = "sd4";
+				grp-name = "sd4grp";
+				grp-pins = <170 171 180 181 182 183 184 185 186 187>;
+				num-pins = <10>;
+				grp-mux = <0 0 1 1 1 1 1 1 1 1>;
+				num-mux = <10>;
+			};
+		};
+	};
+
+	aips-bus@02100000 { /* AIPS2 */
+		usdhc@0219c000 { /* uSDHC4 */
+			fsl,card-wired;
+			status = "okay";
+			pinmux = <&pinctrl_sd4>;
+		};
+
+		uart3: uart@021f0000 { /* UART4 */
+			status = "okay";
+			pinmux = <&pinctrl_uart4>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-sabreauto.dts
b/arch/arm/boot/dts/imx6q-sabreauto.dts
index 072974e..0863b1d 100644
--- a/arch/arm/boot/dts/imx6q-sabreauto.dts
+++ b/arch/arm/boot/dts/imx6q-sabreauto.dts
@@ -26,6 +26,28 @@
 	};

 	soc {
+		aips-bus@02000000 { /* AIPS1 */
+			iomuxc@020e0000 {
+				pinctrl_uart4: uart4 {
+					func-name = "uart4";
+					grp-name = "uart4grp";
+					grp-pins = <107 108>;
+					num-pins = <2>;
+					grp-mux = <4 4>;
+					num-mux = <2>;
+				};
+
+				pinctrl_sd4: sd4 {
+					func-name = "sd4";
+					grp-name = "sd4grp";
+					grp-pins = <170 171 180 181 182 183 184 185 186 187>;
+					num-pins = <10>;
+					grp-mux = <0 0 1 1 1 1 1 1 1 1>;
+					num-mux = <10>;
+				};
+			};
+		};
+
 		aips-bus@02100000 { /* AIPS2 */
 			enet@02188000 {
 				phy-mode = "rgmii";
@@ -42,10 +64,12 @@
 			usdhc@0219c000 { /* uSDHC4 */
 				fsl,card-wired;
 				status = "okay";
+				pinmux = <&pinctrl_sd4>;
 			};

 			uart3: uart@021f0000 { /* UART4 */
 				status = "okay";
+				pinmux = <&pinctrl_uart4>;
 			};
 		};
 	};
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 39f393b..09de5fa 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -20,6 +20,7 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/of_device.h>
 #include <linux/spinlock.h>
 #include <linux/sysfs.h>
 #include <linux/debugfs.h>
@@ -48,6 +49,74 @@ void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev)
 EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata);

 /**
+ * of_get_pinctrl_dev_from_dev() - look up pin controller device via dt
+ * @dev: a device pointer
+ * @map: the pinmux map returned
+ *
+ * Looks up a pin control device matching a certain device name and return
+ * a pinmux map constructed from dt info.
+ */
+struct pinctrl_dev *of_get_pinctrl_dev_from_dev(struct device *dev,
+						struct pinmux_map **map)
+{
+	struct pinctrl_dev *pctldev = NULL;
+	struct device_node *pinmux_np;
+	struct device_node *pinctrl_np;
+	struct pinmux_map *p;
+	bool found = false;
+	char str[16];
+
+	if (!dev || !dev->of_node)
+		return NULL;
+
+	dev_dbg(dev, "find pinctrl dev and pinmux map from device tree\n");
+
+	pinmux_np = of_parse_phandle(dev->of_node, "pinmux", 0);
+	if (!pinmux_np) {
+		dev_err(dev, "unable to get the phandle pinmux\n");
+		return NULL;
+	}
+
+	/* pinmux function nodes should be subnodes of pinctrl device */
+	pinctrl_np = of_get_parent(pinmux_np);
+	if (!pinctrl_np)
+		return NULL;
+
+	mutex_lock(&pinctrldev_list_mutex);
+	list_for_each_entry(pctldev, &pinctrldev_list, node) {
+		if (pctldev->dev->of_node == pinctrl_np) {
+			found = true;
+			break;
+		}
+	}
+	mutex_unlock(&pinctrldev_list_mutex);
+
+	if (found) {
+		/*
+		 * construct a pinmux map from device tree for this device
+		 * Note: for dt we do not specify the pin group, instead we
+		 * use the first group as default.
+		 */
+		p = devm_kzalloc(dev, sizeof(struct pinmux_map), GFP_KERNEL);
+		if (!p)
+			return NULL;
+		*map = p;
+		snprintf(str, 15, "map_%s", pinmux_np->name);
+		p->name = kstrdup(str, GFP_KERNEL);
+		if (!p->name)
+			return NULL;
+		p->function = pinmux_np->name;
+		p->ctrl_dev = pctldev->dev;
+		p->dev = dev;
+		dev_dbg(dev, "found pinctrl: %s  map: %s function %s dev %s\n",
+			dev_name(p->ctrl_dev), p->name,
+			p->function, dev_name(dev));
+	}
+
+	return found ? pctldev : NULL;
+}
+
+/**
  * get_pinctrl_dev_from_dev() - look up pin controller device
  * @dev: a device pointer, this may be NULL but then devname needs to be
  *	defined instead
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 5375582..6077508 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -69,6 +69,8 @@ struct pin_desc {

 struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
 					     const char *dev_name);
+struct pinctrl_dev *of_get_pinctrl_dev_from_dev(struct device *dev,
+						struct pinmux_map **map);
 struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin);
 int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
 int pinctrl_get_device_gpio_range(unsigned gpio,
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 432feb6..cc1b32a 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -20,6 +20,7 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/of_device.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/sysfs.h>
@@ -696,7 +697,7 @@ static void pinmux_free_groups(struct pinmux *pmx)
 struct pinmux *pinmux_get(struct device *dev, const char *name)
 {

-	struct pinmux_map const *map = NULL;
+	struct pinmux_map *map = NULL;
 	struct pinctrl_dev *pctldev = NULL;
 	const char *devname = NULL;
 	struct pinmux *pmx;
@@ -727,7 +728,29 @@ struct pinmux *pinmux_get(struct device *dev,
const char *name)
 	pmx->func_selector = UINT_MAX;
 	INIT_LIST_HEAD(&pmx->groups);

-	/* Iterate over the pinmux maps to locate the right ones */
+	/*
+	 * do a dt based lookup first to see if we can find a pinctrl device
+	 * and a pinmux map for a specific device. If not found fallback
+	 * to search the pinmux_maps as before.
+	 */
+	pctldev = of_get_pinctrl_dev_from_dev(dev, &map);
+	if (pctldev) {
+		ret = pinmux_enable_muxmap(pctldev, pmx, dev,
+					   devname, map);
+		if (ret) {
+			pinmux_free_groups(pmx);
+			kfree(pmx);
+			return ERR_PTR(ret);
+		}
+		num_maps++;
+	}
+
+	/*
+	 * Iterate over the pinmux maps to locate the right ones
+	 * Note: if we're using dt binding, we do not have a predefined pinmux
+	 * maps table registered in machine code as non-dt platfrom does.
+	 * Then, pinmux_maps_num is 0 by default.
+	 */
 	for (i = 0; i < pinmux_maps_num; i++) {
 		map = &pinmux_maps[i];
 		found_map = false;
-- 
1.7.0.4


Regards
Dong Aisheng

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-01 14:07   ` Linus Walleij
  2012-01-01 15:22     ` Rob Herring
@ 2012-01-05 13:59     ` Dong Aisheng
  1 sibling, 0 replies; 98+ messages in thread
From: Dong Aisheng @ 2012-01-05 13:59 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Dong Aisheng, linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss

On Sun, Jan 1, 2012 at 10:07 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Tue, Dec 20, 2011 at 6:40 PM, Dong Aisheng <b29396@freescale.com> wrote:
>
>> From: Dong Aisheng <dong.aisheng@linaro.org>
>>
>> This patch provies a common API for driver to use to register pinmux
>> mappings from dts file. It is needed for dt support.
>
> Overall I feel lost in this discussion due to limited exposure to
> device tree concepts. If I get Stephen Warrens and one of the
> DT people's (Rob, Grant) ACK on this I'll be happy to merge it.
>
> Until then, I guess it will need to be refined for the next kernel
> cycle.
>
Yes, i refined the patch and sent out again.
The main issue formerly discussed are where to place the pinmux map
for binding.
The new found is that if we use the way as regulator does on dt binding,
it seems we do not need define pinmux map in dts file since the device node
relationship already reflects it.
I'm not sure if it's suitable for pinctrl subsystem,
but I tried that way in the new patch i sent.
However, it still have a few issues that it does not support hog_on_boot via
dt and does not support multi groups since the usage is a little
different without
pinmux map.
We may still need some discussion on how to cover that two issue.

Regards
Dong Aisheng

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-27 14:41         ` Dong Aisheng-B29396
  2011-12-29  2:46           ` Shawn Guo
@ 2012-01-05 23:38           ` Stephen Warren
  2012-01-06 10:51             ` Dong Aisheng-B29396
  1 sibling, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-05 23:38 UTC (permalink / raw)
  To: Dong Aisheng-B29396, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

Dong Aisheng-B29396 wrote at Tuesday, December 27, 2011 7:41 AM:
> Stephen Warren wrote at Sunday, December 25, 2011 11:37 AM:
> > Dong Aisheng-B29396 wrote at Thursday, December 22, 2011 1:18 AM:
> > > Stephen Warren wrote at Wednesday, December 21, 2011 8:39 AM:
> > > > Dong Aisheng wrote at Tuesday, December 20, 2011 10:41 AM:
> > > > > This patch provies a common API for driver to use to register
> > > > > pinmux mappings from dts file. It is needed for dt support.
> > > >
> > > > Dong,
> > > >
> > > > Thanks for providing a concrete binding to get discussion started. I
> > > > had intended to do this myself, but got side-tracked on other things.
> > > >
> > > > I'll comment exclusively on the documentation in this patch, since
> > > > any changes there will require the code to be changed.
...
> > > > b) The top-level node ("imx6q-sabreauto-map" below) is not tied to
> > > > any particular piece of hardware (no compatible flag, not reg
> > > > property etc.)
> > >
> > > My original purpose was that it was not a hw device node, it was just
> > > created for containing pin map information and referenced by a phandle
> > > in iomuxc deivce node
> > > like:
> > >
> > > iomuxc@020e0000 {
> > >         compatible = "fsl,imx6q-iomuxc";
> > >         reg = <0x020e0000 0x4000>;
> > >         fsl,pinmux-map = <&pinmux>;
> > > 	  ...
> > > }
> > >
> > > I could also make it as a sub node of iomuxc, but original design is
> > > that sub nodes of Ioxmuc are already representing each pinmux functions.
> > > To avoid conflict, I put the imx6q-sabreauto-map node out of iomuxc
> > > since a phandle (fsl,pinmux-map ) does the same work well.
> >
> > You could have nested sub-nodes, say something like:
> >
> > iomuxc@020e0000 {
> >     compatible = "fsl,imx6q-iomuxc";
> >     reg = <0x020e0000 0x4000>;
> >     fsl,pins {
> >         ... // fsl-specific pin properties
> >     };
> >     fsl,groups {
> >         ... // fsl-specific group properties
> >     };
> >     fsl,functions {
> >         ... // fsl-specific mux function properties
> >     };
> >     pinmux-usage {
> >         // standardized pinmux "table" properties
> >         sd4 { // pin group name
> >             function = "sdio4"; // this function active on it
> >             ...
> >         };
> >         ...
> >     }
> >     ...
> > }
> >
> Yes, I could do that.
> The extra effort is that we have to manually exclude one pinmux-usage
> node in pinmux driver since originally i take the child node count of
> iomuxc as the function count since all child nodes are functions,
> that why I firstly took the mapping node out of iomuxc, in addition
> the old way i used seems to be more brief and clear.
> 
> I tried adding pinmux-usage as a sub node of iomuxc and got two issues:
> Taking imx6q as an example:
>
> iomuxc@020e0000 {
>         uart4 {
>                 func-name = "uart4";
>                 grp-name = "uart4grp";
>                 grp-pins = <107 108>;
>                 num-pins = <2>;
>                 grp-mux = <4 4>;
>                 num-mux = <2>;
>         };
> 
>         sd4 {
>                 func-name = "sd4";
>                 grp-name = "sd4grp";
>                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
>                 num-pins = <10>;
>                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
>                 num-mux = <10>;
>         };
> 
>         pinmux-mapping {
>                 uart4 {
>                         function = "uart4";
>                         dev = <&uart4>;
>                 };
> 
>                 usdhc4 {
> /*			    ctrl-dev-name = "20e0000.iomuxc"; */
>                         function = "sd4";
>                         dev = <&usdhc4>;
>                 };
>         };
> };
> 
> If we remove ctrl-dev-name and get it from its parent node in drivers as
> you suggested,
> first, since this work will be done in the common API (pinmux_of_register_mappings
> Requires pass the pinmux mapping node to it for construct the mapping table)
> It will introduce a restriction that all platforms should define this node
> under their pinctrl device node.

This seems reasonable to me; the pinmux controller would be defining the
mux options/... that it's providing to the rest of the DT.

> Second, it seems we cannot get its parent node device or device name in driver
> (can only get node Name which is not sufficient for construct the pin map table
> required by pinctrl core) and current device tree subsystem seems do not support
> get its associated device from a device node.
> We may not be able to construct ctrl-dev-name or ctrl-dev for struct pinmux_map.
> I'm not sure if I missed something, if missed please let me know.
> To support it, we may need to add support for converting device node
> to device. Not sure it's applicable since I still have not tried it.

That functionality is pretty easy to implement; it already exists for
other subsystems that refer to parent/controller/... nodes using phandles.
for example, take a look at the implementation of of_node_to_gpiochip()
in drivers/of/gpio.c, which calls gpiochip_find() with a custom match
function that simply compares the gpio_chip's of_node field. Once you
have the chip, you have the device, and can store that in the constructed
mapping table, or call dev_name() on it. I assume there's something similar
for interrupts.

...
> > > The same question applies to clock and regulator: does each device
> > > need Define its clock and regulator properties?
> >
> > Yes, in those cases I believe each device does contain a phandle to the
> > resources it uses.
>
> I was ever thought putting a phandle of pinmux function in each device,
> Then pinmux mapping table seems not need anymore. Like:
> 
> usdhc4: usdhc@0219c000 { /* uSDHC4 */
>         compatible = "fsl,imx6q-usdhc";
> 	....
>         pinmux = <&pinmux-sd4>;
> };
> 
> iomuxc@020e0000 {
>         pinmux-sd4 : sd4 {
>                 func-name = "sd4";
>                 grp-name = "sd4grp";
>                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
>                 num-pins = <10>;
>                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
>                 num-mux = <10>;
>         };
> 
> It is a pure hw point of view to define node.
> And it may need to implement a of_pinmux_get.

> But what about the pin maps without device associated?

Indeed; that's why I'd tend towards defining a table of pinmux usage in
the pinmux node, and having other devices refer to that table.

Still, if the pinmux definitions are in the device nodes, we could simply
make the pinmux controller have such a definition itself too, for the
"system hog" case.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2011-12-29  2:46           ` Shawn Guo
  2012-01-05 13:14             ` Dong Aisheng
@ 2012-01-05 23:45             ` Stephen Warren
  2012-01-06  6:21               ` Shawn Guo
  1 sibling, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-05 23:45 UTC (permalink / raw)
  To: Shawn Guo, Dong Aisheng-B29396
  Cc: linux-kernel, linus.walleij, s.hauer, rob.herring, kernel, cjb,
	devicetree-discuss, linux-arm-kernel

Shawn Guo wrote at Wednesday, December 28, 2011 7:47 PM:
> On Tue, Dec 27, 2011 at 02:41:25PM +0000, Dong Aisheng-B29396 wrote:
...
> > I was ever thought putting a phandle of pinmux function in each device,
> > Then pinmux mapping table seems not need anymore. Like:
> >
> > usdhc4: usdhc@0219c000 { /* uSDHC4 */
> >         compatible = "fsl,imx6q-usdhc";
> > 	....
> >         pinmux = <&pinmux-sd4>;
> > };
> >
> > iomuxc@020e0000 {
> >         pinmux-sd4 : sd4 {
> >                 func-name = "sd4";
> >                 grp-name = "sd4grp";
> >                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
> >                 num-pins = <10>;
> >                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
> >                 num-mux = <10>;
> >         };
> >
> > It is a pure hw point of view to define node.
> 
> That's the way we should go for.  This is exactly the same thing that
> clk and regulator DT support is doing.  And right, in that way, we do
> not need pinmux mapping for DT at all.

Well, we'd probably want to have at least a semi-standardized notion of
how the per-device "pinmux" property worked, much like interrupts and
GPIOs work in the same way everywhere, albeit perhaps with different
property names (for GPIOs) and controller-specific flags arguments etc.

One other thing to note: The per-device data can't be a single phandle
reference, unless the referenced node is some kind of table, and then
we do need a pinmux mapping for DT to define the format of that table.
Reasons being:

* Devices most likely need to configure more than one pin or group of
pins, and may need to configure them to different functions, so we at
least need an array of (pin_group, selected_function) values somewhere.

* We need to represent both mux function selection and arbitrary other
per-pin/group configuration parameters.

* We need to represent pinmux configuration for multiple device/driver
states; suspend, active, idle, ...?

...
> To make the pinmux api generic for both dt and non-dt users, the pinmux
> client driver should still see/call pinmux_get, something like
> of_pinmux_get should be sorted out behind pinmux_get.
> 
> > But what about the pin maps without device associated?
>
> Do we have such cases?

I think so.

At least early on, not all drivers will be pinmux-aware, and we'll still
need to set up the pinmux for them. A system wide "pinmux initial
configuration table" or similar would be needed to do this, I think.
This may be transitional.

I can easily see cases where we don't have an explicit driver for HW,
but still need to set up random pinmux configuration as part of basic
system initialization. Perhaps ideally we'd always tie pinmux usage to
some specific device, but the flexibility of not having to do so seems
useful.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-05 13:47         ` Dong Aisheng
@ 2012-01-06  1:05           ` Stephen Warren
  2012-01-06  5:27             ` Shawn Guo
  2012-01-06 11:33             ` Dong Aisheng-B29396
  0 siblings, 2 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-06  1:05 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: Dong Aisheng-B29396, linux-kernel, linus.walleij, s.hauer,
	rob.herring, linux-arm-kernel, kernel, cjb, devicetree-discuss

Dong Aisheng wrote at Thursday, January 05, 2012 6:48 AM:
> On Sun, Dec 25, 2011 at 11:37 AM, Stephen Warren <swarren@nvidia.com> wrote:
> > Dong Aisheng-B29396 wrote at Thursday, December 22, 2011 1:18 AM:
...
> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
...
> +Examples:
> +soc {
> +	aips-bus@02000000 { /* AIPS1 */
> +		iomuxc@020e0000 {
> +			pinctrl_uart4: uart4 {
> +				func-name = "uart4";
> +				grp-name = "uart4grp";
> +				grp-pins = <107 108>;
> +				num-pins = <2>;
> +				grp-mux = <4 4>;
> +				num-mux = <2>;
> +			};

Before I get too far into reviewing this path, could you explain the
above node in a little more detail; what it is and what the properties
define?

I'm confused because the node has properties for function name and
group name which make sense to define the mux setting for that group.
However, I'm not sure what the grp-pins/num-pins/grp-mux/num-mux
properties are for; if those properties define the available mux options
and for the group and set of pins included in the group, I think the node
is representing too many things in one place. I'd expect to see:

a) Either data in the pinctrl driver or separate DT nodes to define each
available pin group, mux function, etc.; the definition of what the SoC
itself can do.

b) The configuration of each pin group that's used by the particular board.
All that's relevant here is the mux selection for each pin groups; things
like which pins are included in each group are defined by the SoC not the
board and hence wouldn't be included in a per-board node.

Thanks for enlightening me!

> +
> +			pinctrl_sd4: sd4 {
> +				func-name = "sd4";
> +				grp-name = "sd4grp";
> +				grp-pins = <170 171 180 181 182 183 184 185 186 187>;
> +				num-pins = <10>;
> +				grp-mux = <0 0 1 1 1 1 1 1 1 1>;
> +				num-mux = <10>;
> +			};
> +		};
> +	};
> +
> +	aips-bus@02100000 { /* AIPS2 */
> +		usdhc@0219c000 { /* uSDHC4 */
> +			fsl,card-wired;
> +			status = "okay";
> +			pinmux = <&pinctrl_sd4>;
> +		};
> +
> +		uart3: uart@021f0000 { /* UART4 */
> +			status = "okay";
> +			pinmux = <&pinctrl_uart4>;
> +		};
> +	};
> +};

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-06  1:05           ` Stephen Warren
@ 2012-01-06  5:27             ` Shawn Guo
  2012-01-06 11:33             ` Dong Aisheng-B29396
  1 sibling, 0 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-06  5:27 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng, Dong Aisheng-B29396, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss

On Thu, Jan 05, 2012 at 05:05:46PM -0800, Stephen Warren wrote:
> I'm confused because the node has properties for function name and
> group name which make sense to define the mux setting for that group.
> However, I'm not sure what the grp-pins/num-pins/grp-mux/num-mux
> properties are for; if those properties define the available mux options
> and for the group and set of pins included in the group, I think the node
> is representing too many things in one place. I'd expect to see:
> 
> a) Either data in the pinctrl driver

For imx, I'm against this.

> or separate DT nodes to define each
> available pin group, mux function, etc.; the definition of what the SoC
> itself can do.

This works for me.  But we do not necessarily need to enumerate all
the possible groups from the beginning.  Instead, we can add the groups
incrementally.

Regards,
Shawn

> 
> b) The configuration of each pin group that's used by the particular board.
> All that's relevant here is the mux selection for each pin groups; things
> like which pins are included in each group are defined by the SoC not the
> board and hence wouldn't be included in a per-board node.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-05 23:45             ` Stephen Warren
@ 2012-01-06  6:21               ` Shawn Guo
  0 siblings, 0 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-06  6:21 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Shawn Guo, Dong Aisheng-B29396, linux-kernel, linus.walleij,
	s.hauer, rob.herring, kernel, cjb, devicetree-discuss,
	linux-arm-kernel

On Thu, Jan 05, 2012 at 03:45:56PM -0800, Stephen Warren wrote:
> Shawn Guo wrote at Wednesday, December 28, 2011 7:47 PM:
> > On Tue, Dec 27, 2011 at 02:41:25PM +0000, Dong Aisheng-B29396 wrote:
> ...
> > > I was ever thought putting a phandle of pinmux function in each device,
> > > Then pinmux mapping table seems not need anymore. Like:
> > >
> > > usdhc4: usdhc@0219c000 { /* uSDHC4 */
> > >         compatible = "fsl,imx6q-usdhc";
> > > 	....
> > >         pinmux = <&pinmux-sd4>;
> > > };
> > >
> > > iomuxc@020e0000 {
> > >         pinmux-sd4 : sd4 {
> > >                 func-name = "sd4";
> > >                 grp-name = "sd4grp";
> > >                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
> > >                 num-pins = <10>;
> > >                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
> > >                 num-mux = <10>;
> > >         };
> > >
> > > It is a pure hw point of view to define node.
> > 
> > That's the way we should go for.  This is exactly the same thing that
> > clk and regulator DT support is doing.  And right, in that way, we do
> > not need pinmux mapping for DT at all.
> 
> Well, we'd probably want to have at least a semi-standardized notion of
> how the per-device "pinmux" property worked, much like interrupts and
> GPIOs work in the same way everywhere, albeit perhaps with different
> property names (for GPIOs) and controller-specific flags arguments etc.
> 
Agreed.

> One other thing to note: The per-device data can't be a single phandle
> reference, unless the referenced node is some kind of table,

Just like gpio and clock, it could reasonably be a phandle array
instead of a single phandle for some cases.

> and then
> we do need a pinmux mapping for DT to define the format of that table.
> Reasons being:
> 
> * Devices most likely need to configure more than one pin or group of
> pins, and may need to configure them to different functions, so we at
> least need an array of (pin_group, selected_function) values somewhere.
> 
> * We need to represent both mux function selection and arbitrary other
> per-pin/group configuration parameters.
> 
> * We need to represent pinmux configuration for multiple device/driver
> states; suspend, active, idle, ...?
> 
> ...
> > To make the pinmux api generic for both dt and non-dt users, the pinmux
> > client driver should still see/call pinmux_get, something like
> > of_pinmux_get should be sorted out behind pinmux_get.
> > 
> > > But what about the pin maps without device associated?
> >
> > Do we have such cases?
> 
> I think so.
> 
> At least early on, not all drivers will be pinmux-aware, and we'll still
> need to set up the pinmux for them. A system wide "pinmux initial
> configuration table" or similar would be needed to do this, I think.
> This may be transitional.

Ok.  But on imx, we usually have those early pinmux setting done in
bootloader.

Regards,
Shawn

> 
> I can easily see cases where we don't have an explicit driver for HW,
> but still need to set up random pinmux configuration as part of basic
> system initialization. Perhaps ideally we'd always tie pinmux usage to
> some specific device, but the flexibility of not having to do so seems
> useful.
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-05 23:38           ` Stephen Warren
@ 2012-01-06 10:51             ` Dong Aisheng-B29396
  2012-01-06 17:23               ` Stephen Warren
  0 siblings, 1 reply; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-06 10:51 UTC (permalink / raw)
  To: Stephen Warren, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

> -----Original Message-----
> From: Stephen Warren [mailto:swarren@nvidia.com]
> Sent: Friday, January 06, 2012 7:38 AM
> To: Dong Aisheng-B29396; linux-kernel@vger.kernel.org
> Cc: linus.walleij@stericsson.com; s.hauer@pengutronix.de;
> rob.herring@calxeda.com; linux-arm-kernel@lists.infradead.org;
> kernel@pengutronix.de; cjb@laptop.org; devicetree-discuss@lists.ozlabs.org
> Subject: RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> Dong Aisheng-B29396 wrote at Tuesday, December 27, 2011 7:41 AM:
> > Stephen Warren wrote at Sunday, December 25, 2011 11:37 AM:
> > > Dong Aisheng-B29396 wrote at Thursday, December 22, 2011 1:18 AM:
> > > > Stephen Warren wrote at Wednesday, December 21, 2011 8:39 AM:
> > > > > Dong Aisheng wrote at Tuesday, December 20, 2011 10:41 AM:
> > > > > > This patch provies a common API for driver to use to register
> > > > > > pinmux mappings from dts file. It is needed for dt support.
> > > > >
> > > > > Dong,
> > > > >
> > > > > Thanks for providing a concrete binding to get discussion
> > > > > started. I had intended to do this myself, but got side-tracked on other
> things.
> > > > >
> > > > > I'll comment exclusively on the documentation in this patch,
> > > > > since any changes there will require the code to be changed.
> ...
> > > > > b) The top-level node ("imx6q-sabreauto-map" below) is not tied
> > > > > to any particular piece of hardware (no compatible flag, not reg
> > > > > property etc.)
> > > >
> > > > My original purpose was that it was not a hw device node, it was
> > > > just created for containing pin map information and referenced by
> > > > a phandle in iomuxc deivce node
> > > > like:
> > > >
> > > > iomuxc@020e0000 {
> > > >         compatible = "fsl,imx6q-iomuxc";
> > > >         reg = <0x020e0000 0x4000>;
> > > >         fsl,pinmux-map = <&pinmux>;
> > > > 	  ...
> > > > }
> > > >
> > > > I could also make it as a sub node of iomuxc, but original design
> > > > is that sub nodes of Ioxmuc are already representing each pinmux functions.
> > > > To avoid conflict, I put the imx6q-sabreauto-map node out of
> > > > iomuxc since a phandle (fsl,pinmux-map ) does the same work well.
> > >
> > > You could have nested sub-nodes, say something like:
> > >
> > > iomuxc@020e0000 {
> > >     compatible = "fsl,imx6q-iomuxc";
> > >     reg = <0x020e0000 0x4000>;
> > >     fsl,pins {
> > >         ... // fsl-specific pin properties
> > >     };
> > >     fsl,groups {
> > >         ... // fsl-specific group properties
> > >     };
> > >     fsl,functions {
> > >         ... // fsl-specific mux function properties
> > >     };
> > >     pinmux-usage {
> > >         // standardized pinmux "table" properties
> > >         sd4 { // pin group name
> > >             function = "sdio4"; // this function active on it
> > >             ...
> > >         };
> > >         ...
> > >     }
> > >     ...
> > > }
> > >
> > Yes, I could do that.
> > The extra effort is that we have to manually exclude one pinmux-usage
> > node in pinmux driver since originally i take the child node count of
> > iomuxc as the function count since all child nodes are functions, that
> > why I firstly took the mapping node out of iomuxc, in addition the old
> > way i used seems to be more brief and clear.
> >
> > I tried adding pinmux-usage as a sub node of iomuxc and got two issues:
> > Taking imx6q as an example:
> >
> > iomuxc@020e0000 {
> >         uart4 {
> >                 func-name = "uart4";
> >                 grp-name = "uart4grp";
> >                 grp-pins = <107 108>;
> >                 num-pins = <2>;
> >                 grp-mux = <4 4>;
> >                 num-mux = <2>;
> >         };
> >
> >         sd4 {
> >                 func-name = "sd4";
> >                 grp-name = "sd4grp";
> >                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
> >                 num-pins = <10>;
> >                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
> >                 num-mux = <10>;
> >         };
> >
> >         pinmux-mapping {
> >                 uart4 {
> >                         function = "uart4";
> >                         dev = <&uart4>;
> >                 };
> >
> >                 usdhc4 {
> > /*			    ctrl-dev-name = "20e0000.iomuxc"; */
> >                         function = "sd4";
> >                         dev = <&usdhc4>;
> >                 };
> >         };
> > };
> >
> > If we remove ctrl-dev-name and get it from its parent node in drivers
> > as you suggested, first, since this work will be done in the common
> > API (pinmux_of_register_mappings Requires pass the pinmux mapping node
> > to it for construct the mapping table) It will introduce a restriction
> > that all platforms should define this node under their pinctrl device
> > node.
> 
> This seems reasonable to me; the pinmux controller would be defining the mux
> options/... that it's providing to the rest of the DT.
> 
> > Second, it seems we cannot get its parent node device or device name
> > in driver (can only get node Name which is not sufficient for
> > construct the pin map table required by pinctrl core) and current
> > device tree subsystem seems do not support get its associated device from a
> device node.
> > We may not be able to construct ctrl-dev-name or ctrl-dev for struct
> pinmux_map.
> > I'm not sure if I missed something, if missed please let me know.
> > To support it, we may need to add support for converting device node
> > to device. Not sure it's applicable since I still have not tried it.
> 
> That functionality is pretty easy to implement; it already exists for other
> subsystems that refer to parent/controller/... nodes using phandles.
> for example, take a look at the implementation of of_node_to_gpiochip() in
> drivers/of/gpio.c, which calls gpiochip_find() with a custom match function that
> simply compares the gpio_chip's of_node field. Once you have the chip, you have
> the device, and can store that in the constructed mapping table, or call
> dev_name() on it. I assume there's something similar for interrupts.
> 
Yes, that's indeed a way.
Thanks for the info.

> ...
> > > > The same question applies to clock and regulator: does each device
> > > > need Define its clock and regulator properties?
> > >
> > > Yes, in those cases I believe each device does contain a phandle to
> > > the resources it uses.
> >
> > I was ever thought putting a phandle of pinmux function in each
> > device, Then pinmux mapping table seems not need anymore. Like:
> >
> > usdhc4: usdhc@0219c000 { /* uSDHC4 */
> >         compatible = "fsl,imx6q-usdhc";
> > 	....
> >         pinmux = <&pinmux-sd4>;
> > };
> >
> > iomuxc@020e0000 {
> >         pinmux-sd4 : sd4 {
> >                 func-name = "sd4";
> >                 grp-name = "sd4grp";
> >                 grp-pins = <170 171 180 181 182 183 184 185 186 187>;
> >                 num-pins = <10>;
> >                 grp-mux = <0 0 1 1 1 1 1 1 1 1>;
> >                 num-mux = <10>;
> >         };
> >
> > It is a pure hw point of view to define node.
> > And it may need to implement a of_pinmux_get.
> 
> > But what about the pin maps without device associated?
> 
> Indeed; that's why I'd tend towards defining a table of pinmux usage in the
> pinmux node, and having other devices refer to that table.
>
Currently we still prefer to use device node relationship to reflect the pinmux
map if we can since as you said pinmux map is little depending on the pinctrl
subsystem implementation.
And I'm trying to do it now.
 
> Still, if the pinmux definitions are in the device nodes, we could simply make
> the pinmux controller have such a definition itself too, for the "system hog"
> case.
> 
Yes, that way I think is like:
iomuxc@020e0000 {
        pinctrl_uart4: uart4 {
                grp-pins = <107 108>;
                grp-mux = <4 4>;
		   hog_on_boot;
        };
}
I'm still trying to find a way to support it in pinctrl core.
Maybe we could do it in the next step and we want to implement pinmux binding first.

Regards
Dong Aisheng


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-06  1:05           ` Stephen Warren
  2012-01-06  5:27             ` Shawn Guo
@ 2012-01-06 11:33             ` Dong Aisheng-B29396
  2012-01-06 13:14               ` Shawn Guo
  2012-01-06 18:03               ` Stephen Warren
  1 sibling, 2 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-06 11:33 UTC (permalink / raw)
  To: Stephen Warren, Dong Aisheng
  Cc: linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss

> -----Original Message-----
> From: Stephen Warren [mailto:swarren@nvidia.com]
> Sent: Friday, January 06, 2012 9:06 AM
> To: Dong Aisheng
> Cc: Dong Aisheng-B29396; linux-kernel@vger.kernel.org;
> linus.walleij@stericsson.com; s.hauer@pengutronix.de; rob.herring@calxeda.com;
> linux-arm-kernel@lists.infradead.org; kernel@pengutronix.de; cjb@laptop.org;
> devicetree-discuss@lists.ozlabs.org
> Subject: RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> Dong Aisheng wrote at Thursday, January 05, 2012 6:48 AM:
> > On Sun, Dec 25, 2011 at 11:37 AM, Stephen Warren <swarren@nvidia.com> wrote:
> > > Dong Aisheng-B29396 wrote at Thursday, December 22, 2011 1:18 AM:
> ...
> > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> ...
> > +Examples:
> > +soc {
> > +	aips-bus@02000000 { /* AIPS1 */
> > +		iomuxc@020e0000 {
> > +			pinctrl_uart4: uart4 {
> > +				func-name = "uart4";
> > +				grp-name = "uart4grp";
> > +				grp-pins = <107 108>;
> > +				num-pins = <2>;
> > +				grp-mux = <4 4>;
> > +				num-mux = <2>;
> > +			};
> 
> Before I get too far into reviewing this path, could you explain the above node
> in a little more detail; what it is and what the properties define?
> 
grp-pins is the group of pins for this function.
grp-mux is the corresponding mux setting of each pin in that group for this specific
function.
num-pins and num-mux are the number of pins and mux. They're mainly used for sanity
Checking in driver since it's easy to make a mistake when write too many pins for a
function. These two could be removed finally.

> I'm confused because the node has properties for function name and group name
> which make sense to define the mux setting for that group.
> However, I'm not sure what the grp-pins/num-pins/grp-mux/num-mux properties are
> for; if those properties define the available mux options and for the group and
> set of pins included in the group, I think the node is representing too many
> things in one place. I'd expect to see:
> 
> a) Either data in the pinctrl driver or separate DT nodes to define each
> available pin group, mux function, etc.; the definition of what the SoC itself
> can do.
> 
> b) The configuration of each pin group that's used by the particular board.
> All that's relevant here is the mux selection for each pin groups; things like
> which pins are included in each group are defined by the SoC not the board and
> hence wouldn't be included in a per-board node.
> 
We still have not started pin config work.
For pinmux, one way we thought is trying to define pin groups
in soc dts file and reference that pin group by a phandle in board dts file.
It could be:
In the soc dts file arch/arm/boot/dts/imx6q.dtsi:
iomuxc@020e0000 {
        reg = <0x020e0000 0x4000>;
        pinmux-groups {
                pingrp_uart4: uart4 {
                        grp-pins = <107 108>;
                        grp-mux = <4 4>;
                };

                pingrp_sd4: sd4 {
                        grp-pins = <170 171 180 181 182 183 184 185 186 187>;
                        grp-mux = <0 0 1 1 1 1 1 1 1 1>;
                }
        }
};

In board dts file:
usdhc@0219c000 { /* uSDHC4 */
        fsl,card-wired;
        status = "okay";
        pinmux = <&pinctrl_sd4>;
};

uart3: uart@021f0000 { /* UART4 */
        status = "okay";
        pinmux = <&pinctrl_uart4>;
};

iomuxc@020e0000 {
        pinctrl_uart4: uart4 {
                group = <&pingrp_uart4>;
                pinconfig = ....;
        };

        pinctrl_sd4: sd4 {
                group = <&pingrp_sd4>;
                pinconfig = ....;
        };
};

Then we know the whole map information for a specific device without a pinmux map.
Do you think if it's ok?

BTW, for imx we won't define all possible groups since most are useless and
It's hard to cover all cases due to the issue raised by Sascha before.
We only define what we're most using firstly.

> Thanks for enlightening me!
> 
> > +
> > +			pinctrl_sd4: sd4 {
> > +				func-name = "sd4";
> > +				grp-name = "sd4grp";
> > +				grp-pins = <170 171 180 181 182 183 184 185 186 187>;
> > +				num-pins = <10>;
> > +				grp-mux = <0 0 1 1 1 1 1 1 1 1>;
> > +				num-mux = <10>;
> > +			};
> > +		};
> > +	};
> > +
> > +	aips-bus@02100000 { /* AIPS2 */
> > +		usdhc@0219c000 { /* uSDHC4 */
> > +			fsl,card-wired;
> > +			status = "okay";
> > +			pinmux = <&pinctrl_sd4>;
> > +		};
> > +
> > +		uart3: uart@021f0000 { /* UART4 */
> > +			status = "okay";
> > +			pinmux = <&pinctrl_uart4>;
> > +		};
> > +	};
> > +};
> 
> --
> nvpublic
> 

Regards
Dong Aisheng


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-06 11:33             ` Dong Aisheng-B29396
@ 2012-01-06 13:14               ` Shawn Guo
  2012-01-06 18:03               ` Stephen Warren
  1 sibling, 0 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-06 13:14 UTC (permalink / raw)
  To: Dong Aisheng-B29396
  Cc: Stephen Warren, Dong Aisheng, linus.walleij, s.hauer,
	linux-kernel, rob.herring, kernel, cjb, devicetree-discuss,
	linux-arm-kernel

On Fri, Jan 06, 2012 at 11:33:54AM +0000, Dong Aisheng-B29396 wrote:
> In board dts file:
> usdhc@0219c000 { /* uSDHC4 */
>         fsl,card-wired;
>         status = "okay";
>         pinmux = <&pinctrl_sd4>;

Would it be more proper to have the phandle named as 'pinctrl' than
'pinmux'?

> };

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-06 10:51             ` Dong Aisheng-B29396
@ 2012-01-06 17:23               ` Stephen Warren
  2012-01-10  7:02                 ` Dong Aisheng-B29396
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-06 17:23 UTC (permalink / raw)
  To: Dong Aisheng-B29396, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

Dong Aisheng-B29396 wrote at Friday, January 06, 2012 3:51 AM:
> Stephen Warren wrote at Friday, January 06, 2012 7:38 AM:
> > Dong Aisheng-B29396 wrote at Tuesday, December 27, 2011 7:41 AM:
...
> > > But what about the pin maps without device associated?
> >
> > Indeed; that's why I'd tend towards defining a table of pinmux usage in the
> > pinmux node, and having other devices refer to that table.
>
> Currently we still prefer to use device node relationship to reflect the pinmux
> map if we can since as you said pinmux map is little depending on the pinctrl
> subsystem implementation.
> And I'm trying to do it now.
> 
> > Still, if the pinmux definitions are in the device nodes, we could simply make
> > the pinmux controller have such a definition itself too, for the "system hog"
> > case.
>
> Yes, that way I think is like:
> iomuxc@020e0000 {
>         pinctrl_uart4: uart4 {
>                 grp-pins = <107 108>;
>                 grp-mux = <4 4>;
> 		   hog_on_boot;
>         };
> }

If pinmux usage is defined in each individual device node, and the "hog"
setup is included in the pinmux controller's own device node, then there's
no need for a "hog_on_boot" property; any pinmux setup node that's inside
the pinmux controller node would automatically be a "hog" entry, and
could be activated as soon as the pinmux controller was probed and
registered with the pinctrl subsystem.

(as a minor nit, DT usually uses - not _ in property names, so that would
be "hog-on-boot").

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-06 11:33             ` Dong Aisheng-B29396
  2012-01-06 13:14               ` Shawn Guo
@ 2012-01-06 18:03               ` Stephen Warren
  2012-01-07 13:54                 ` Shawn Guo
  2012-01-10  8:21                 ` Dong Aisheng-B29396
  1 sibling, 2 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-06 18:03 UTC (permalink / raw)
  To: Dong Aisheng-B29396, Dong Aisheng
  Cc: linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org)

Dong Aisheng-B29396 wrote at Friday, January 06, 2012 4:34 AM:
> Stephen Warren wrote at Friday, January 06, 2012 9:06 AM:
> > Dong Aisheng wrote at Thursday, January 05, 2012 6:48 AM:
> > > On Sun, Dec 25, 2011 at 11:37 AM, Stephen Warren <swarren@nvidia.com> wrote:
> > > > Dong Aisheng-B29396 wrote at Thursday, December 22, 2011 1:18 AM:
> > ...
> > > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> > ...
> > > +Examples:
> > > +soc {
> > > +	aips-bus@02000000 { /* AIPS1 */
> > > +		iomuxc@020e0000 {
> > > +			pinctrl_uart4: uart4 {
> > > +				func-name = "uart4";
> > > +				grp-name = "uart4grp";
> > > +				grp-pins = <107 108>;
> > > +				num-pins = <2>;
> > > +				grp-mux = <4 4>;
> > > +				num-mux = <2>;
> > > +			};
> >
> > Before I get too far into reviewing this path, could you explain the above node
> > in a little more detail; what it is and what the properties define?
> >
> grp-pins is the group of pins for this function.
> grp-mux is the corresponding mux setting of each pin in that group for this specific
> function.
> num-pins and num-mux are the number of pins and mux. They're mainly used for sanity
> Checking in driver since it's easy to make a mistake when write too many pins for a
> function. These two could be removed finally.

I see now.

I'd definitely be inclined to drop the num-pins and num-mux properties;
The values are just len(grp-pins)/4. You can still check that
len(grp-pins)==len(grp-mux) if you want to catch typos etc.

So, this does appear to be conflating the two things: The definition of
what pins are in a pingroup, and the mux function for a particular
setting of that pingroup. I think you need separate nodes for this.

Without separate nodes, there will eventually be a lot of duplication.
A made-up example of the same uart4grp allowing either of two functions
uart3, uart4 to be muxed out onto it:

aips-bus@02000000 { /* AIPS1 */
	iomuxc@020e0000 {
		pinctrl_uart4_3: uart4@option_3 {
			func-name = "uart3";
			grp-name = "uart4grp";
			grp-pins = <107 108>;
			num-pins = <2>;
			grp-mux = <3 3>;
			num-mux = <2>;
		};
		pinctrl_uart4_4: uart4@option_4 {
			func-name = "uart4";
			grp-name = "uart4grp";
			grp-pins = <107 108>;
			num-pins = <2>;
			grp-mux = <3 3>;
			num-mux = <2>;
		};
	}
};

Now I understand that initially you aren't going to type out the complete
list of every available option into imx6q.dtsi because it's probably huge,
but the binding does need to allow you to do so without duplicating a lot
of data, because eventually you'll get boards that use a larger and larger
subset of all the options, so the number you need to represent at once in
imx6q.dtsi will grow.

So I think you need to model the IMX pinmux controller's bindings more on
how the pinctrl subsystem represents objects; separate definitions of pins,
groups of pins, functions, and board settings. Something more like:

imx6q.dtsi:

aips-bus@02000000 { /* AIPS1 */
	iomuxc@020e0000 {
		/* FIXME: Perhaps need pin nodes here to name them too */

		/* A node per group of pins. Each lists the group name, and
		 * the list of pins in the group */
		foogrp: group@100 {
			grp-name = "foogrp";
			grp-pins = <100 101>;
		};
		bargrp: group@102 {
			grp-name = "bargrp";
			grp-pins = <102 103>;
		};
		bazgrp: group@104 {
			grp-name = "bargrp";
			grp-pins = <104 105>;
		};
		/* A node per function that can be muxed onto pin groups,
		 * each listing the function name, the set of groups it can
		 * be muxed onto, and the mux selector value to program into
		 * the groups' mux control register to select it */
		uart3func: func@0 {
			func-name = "uart3";
			/* Length of locations and mux-value must match */
			locations = <&foogrp &bargrp>;
			mux-value = <0 4>;
		};
		uart4func: func@1 {
			func-name = "uart4";
			locations = <&bargrp &bazgrp>;
			mux-value = <6 3>;
		};
	}
};

Or, instead of separate locations and mux-value properties with matching
lengths, perhaps a node for each location:

		uart3func: func@0 {
			func-name = "uart3";
			location@0 {
				location = <&foogrp>;
				mux-value = <0>;
			};
			location@1 {
				location = <&bargrp>;
				mux-value = <4>;
			};
		};

That's more long-winded, but might be more easily extensible if we need
to add more properties later.

Now in the board's .dts file, you need to specify for each device the
list of pinmux groups the device needs to use, and the function to
select for each group. Perhaps something like:

board.dts:

usdhc@0219c000 { /* uSDHC4 */
        fsl,card-wired;
        status = "okay";
        pinmux = <&foogrp &uart3func &bazgrp &uart4func>;
};

I haven't convinced myself that's actually a good binding, but I think
it does represent the data required for muxing. Some potential issues
as before:

* Do we need to add flags to each entry in the list; GPIO/interrupt do?

* Should "pinmux" be a node, and the configuration of each group be a
separate sub-node, so we can add more properties to each "table" entry
in the future, e.g. pin config parameters?

* For Tegra, I elected to put the definitions of pins, groups, and
functions into the driver rather than in the device tree. This avoids
parsing a heck of a lot of data from device tree. That means there isn't
any per-function node that can be referred to by phandle. Does it make
sense to refer to groups and functions by string name or integer ID
instead of phandle? Perhaps:

usdhc@0219c000 { /* uSDHC4 */
	fsl,card-wired;
	status = "okay";
	pinmux = {
		group@0 {
			group = "foo";
			function = "uart3";
			/* You could add pin config options here too */
		};
		group@1 {
			group = "baz";
			function = "uart4";
		};
	};
};

I guess referring to things by name isn't that idiomatic for device tree.
Using integers here would be fine too, so long as dtc gets support for
named constants:

imx6q.dtsi:

/define/ IMX_PINGRP_FOO 0
/define/ IMX_PINGRP_BAR 1
/define/ IMX_PINGRP_BAZ 2
/define/ IMX_PINFUNC_UART3 0
/define/ IMX_PINFUNC_UART4 1
...

board .dts:

usdhc@0219c000 { /* uSDHC4 */
	fsl,card-wired;
	status = "okay";
	pinmux = {
		group@0 {
			group = <IMX_PINGRP_FOO>;
			function = <IMX_PINFUNC_UART3>;
			/* You could add pin config options here too */
		};
		group@1 {
			group = <IMX_PINGRP_BAZ>;
			function = <IMX_PINFUNC_UART4>;
		};
	};
};

> > I'm confused because the node has properties for function name and group name
> > which make sense to define the mux setting for that group.
> > However, I'm not sure what the grp-pins/num-pins/grp-mux/num-mux properties are
> > for; if those properties define the available mux options and for the group and
> > set of pins included in the group, I think the node is representing too many
> > things in one place. I'd expect to see:
> >
> > a) Either data in the pinctrl driver or separate DT nodes to define each
> > available pin group, mux function, etc.; the definition of what the SoC itself
> > can do.
> >
> > b) The configuration of each pin group that's used by the particular board.
> > All that's relevant here is the mux selection for each pin groups; things like
> > which pins are included in each group are defined by the SoC not the board and
> > hence wouldn't be included in a per-board node.
>
> We still have not started pin config work.
> For pinmux, one way we thought is trying to define pin groups
> in soc dts file and reference that pin group by a phandle in board dts file.
> It could be:
> In the soc dts file arch/arm/boot/dts/imx6q.dtsi:
>
> iomuxc@020e0000 {
>         reg = <0x020e0000 0x4000>;
>         pinmux-groups {
>                 pingrp_uart4: uart4 {
>                         grp-pins = <107 108>;
>                         grp-mux = <4 4>;
>                 };
> 
>                 pingrp_sd4: sd4 {
>                         grp-pins = <170 171 180 181 182 183 184 185 186 187>;
>                         grp-mux = <0 0 1 1 1 1 1 1 1 1>;
>                 }
>         }
> };
> 
> In board dts file:
> usdhc@0219c000 { /* uSDHC4 */
>         fsl,card-wired;
>         status = "okay";
>         pinmux = <&pinctrl_sd4>;
> };
> 
> uart3: uart@021f0000 { /* UART4 */
>         status = "okay";
>         pinmux = <&pinctrl_uart4>;
> };
> 
> iomuxc@020e0000 {
>         pinctrl_uart4: uart4 {
>                 group = <&pingrp_uart4>;
>                 pinconfig = ....;
>         };
> 
>         pinctrl_sd4: sd4 {
>                 group = <&pingrp_sd4>;
>                 pinconfig = ....;
>         };
> };
> 
> Then we know the whole map information for a specific device without a pinmux map.
> Do you think if it's ok?
> 
> BTW, for imx we won't define all possible groups since most are useless and
> It's hard to cover all cases due to the issue raised by Sascha before.
> We only define what we're most using firstly.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-06 18:03               ` Stephen Warren
@ 2012-01-07 13:54                 ` Shawn Guo
  2012-01-08 12:51                   ` Richard Zhao
  2012-01-11 18:17                   ` Stephen Warren
  2012-01-10  8:21                 ` Dong Aisheng-B29396
  1 sibling, 2 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-07 13:54 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org)

On Fri, Jan 06, 2012 at 10:03:07AM -0800, Stephen Warren wrote:
> I see now.
> 
> I'd definitely be inclined to drop the num-pins and num-mux properties;
> The values are just len(grp-pins)/4. You can still check that
> len(grp-pins)==len(grp-mux) if you want to catch typos etc.
> 
+1

> So, this does appear to be conflating the two things: The definition of
> what pins are in a pingroup, and the mux function for a particular
> setting of that pingroup. I think you need separate nodes for this.
> 
At least for imx, we do not have mux function setting for pingroup.
Instead, it only applies to individual pin.

> Without separate nodes, there will eventually be a lot of duplication.
> A made-up example of the same uart4grp allowing either of two functions
> uart3, uart4 to be muxed out onto it:
> 
> aips-bus@02000000 { /* AIPS1 */
> 	iomuxc@020e0000 {
> 		pinctrl_uart4_3: uart4@option_3 {
> 			func-name = "uart3";
> 			grp-name = "uart4grp";

With phandle in dts reflecting the mapping, neither func-name nor
grp-name should be needed, and both can just be dropped, IMO.

> 			grp-pins = <107 108>;
> 			num-pins = <2>;
> 			grp-mux = <3 3>;
> 			num-mux = <2>;
> 		};
> 		pinctrl_uart4_4: uart4@option_4 {
> 			func-name = "uart4";
> 			grp-name = "uart4grp";
> 			grp-pins = <107 108>;
> 			num-pins = <2>;
> 			grp-mux = <3 3>;
> 			num-mux = <2>;
> 		};
> 	}
> };
> 
> Now I understand that initially you aren't going to type out the complete
> list of every available option into imx6q.dtsi because it's probably huge,
> but the binding does need to allow you to do so without duplicating a lot
> of data, because eventually you'll get boards that use a larger and larger
> subset of all the options, so the number you need to represent at once in
> imx6q.dtsi will grow.
> 
> So I think you need to model the IMX pinmux controller's bindings more on
> how the pinctrl subsystem represents objects; separate definitions of pins,
> groups of pins, functions, and board settings. Something more like:
> 
> imx6q.dtsi:
> 
> aips-bus@02000000 { /* AIPS1 */
> 	iomuxc@020e0000 {
> 		/* FIXME: Perhaps need pin nodes here to name them too */

No, it's been listed in imx pinctrl driver.

> 
> 		/* A node per group of pins. Each lists the group name, and
> 		 * the list of pins in the group */
> 		foogrp: group@100 {
> 			grp-name = "foogrp";
> 			grp-pins = <100 101>;
> 		};
> 		bargrp: group@102 {
> 			grp-name = "bargrp";
> 			grp-pins = <102 103>;
> 		};
> 		bazgrp: group@104 {
> 			grp-name = "bargrp";
> 			grp-pins = <104 105>;
> 		};

I agree that we should define pingroups in <soc>.dtsi, but the mux
setting needs to be under the pingroup node too.  See comment below ...

> 		/* A node per function that can be muxed onto pin groups,
> 		 * each listing the function name, the set of groups it can
> 		 * be muxed onto, and the mux selector value to program into
> 		 * the groups' mux control register to select it */
> 		uart3func: func@0 {
> 			func-name = "uart3";
> 			/* Length of locations and mux-value must match */
> 			locations = <&foogrp &bargrp>;
> 			mux-value = <0 4>;

This can be easily broken for imx.  As the mux setting applies to
individual pin rather than pingroup, it's very valid for foogrp to
have pin 100 muxed on mode 0 while pin 101 on mode 1.  That said,
it's not necessarily true that we always have all the pins in
particular pingroup muxed on the same setting for given function.

> 		};
> 		uart4func: func@1 {
> 			func-name = "uart4";
> 			locations = <&bargrp &bazgrp>;
> 			mux-value = <6 3>;
> 		};

I prefer to have function node defined in <board>.dtsi, since it's
all about defining phandle to the correct pingroup, which should be
decided by board design.

> 	}
> };
> 
> Or, instead of separate locations and mux-value properties with matching
> lengths, perhaps a node for each location:
> 
> 		uart3func: func@0 {
> 			func-name = "uart3";
> 			location@0 {
> 				location = <&foogrp>;
> 				mux-value = <0>;
> 			};
> 			location@1 {
> 				location = <&bargrp>;
> 				mux-value = <4>;
> 			};
> 		};
> 
> That's more long-winded, but might be more easily extensible if we need
> to add more properties later.
> 
> Now in the board's .dts file, you need to specify for each device the
> list of pinmux groups the device needs to use, and the function to
> select for each group. Perhaps something like:
> 
> board.dts:
> 
> usdhc@0219c000 { /* uSDHC4 */
>         fsl,card-wired;
>         status = "okay";
>         pinmux = <&foogrp &uart3func &bazgrp &uart4func>;
> };
> 
> I haven't convinced myself that's actually a good binding, but I think
> it does represent the data required for muxing. Some potential issues
> as before:
> 
> * Do we need to add flags to each entry in the list; GPIO/interrupt do?
> 
What's that for right now?  I guess we can add it later when we see
the need.

> * Should "pinmux" be a node, and the configuration of each group be a
> separate sub-node, so we can add more properties to each "table" entry
> in the future, e.g. pin config parameters?
> 
I do not think it's necessary. 'pinctrl' phandle works perfectly fine
to me at least for now.  How pinconf support should be added into
pinctrl subsystem is still up in the air to me.

> * For Tegra, I elected to put the definitions of pins, groups, and
> functions into the driver rather than in the device tree.

IMO, we do not want to do this for imx, as I'm scared of the size
of Tegra pinctrl patches.  If we go this way for imx, we will have
even bigger patches.

> This avoids
> parsing a heck of a lot of data from device tree. That means there isn't
> any per-function node that can be referred to by phandle. Does it make
> sense to refer to groups and functions by string name or integer ID
> instead of phandle? Perhaps:
> 
> usdhc@0219c000 { /* uSDHC4 */
> 	fsl,card-wired;
> 	status = "okay";
> 	pinmux = {
> 		group@0 {
> 			group = "foo";
> 			function = "uart3";
> 			/* You could add pin config options here too */
> 		};
> 		group@1 {
> 			group = "baz";
> 			function = "uart4";
> 		};
> 	};
> };
> 
> I guess referring to things by name isn't that idiomatic for device tree.
> Using integers here would be fine too, so long as dtc gets support for
> named constants:
> 
> imx6q.dtsi:
> 
> /define/ IMX_PINGRP_FOO 0
> /define/ IMX_PINGRP_BAR 1
> /define/ IMX_PINGRP_BAZ 2
> /define/ IMX_PINFUNC_UART3 0
> /define/ IMX_PINFUNC_UART4 1
> ...
> 
> board .dts:
> 
> usdhc@0219c000 { /* uSDHC4 */
> 	fsl,card-wired;
> 	status = "okay";
> 	pinmux = {
> 		group@0 {
> 			group = <IMX_PINGRP_FOO>;
> 			function = <IMX_PINFUNC_UART3>;
> 			/* You could add pin config options here too */
> 		};
> 		group@1 {
> 			group = <IMX_PINGRP_BAZ>;
> 			function = <IMX_PINFUNC_UART4>;
> 		};
> 	};
> };
> 
Doing this does not change the fact that this is bound with Linux
driver details.  That said, if the indexing of either pingrp array
or pinfunc array changes in the driver, the binding is broken.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-07 13:54                 ` Shawn Guo
@ 2012-01-08 12:51                   ` Richard Zhao
  2012-01-09  1:56                     ` Shawn Guo
  2012-01-11 18:28                     ` Stephen Warren
  2012-01-11 18:17                   ` Stephen Warren
  1 sibling, 2 replies; 98+ messages in thread
From: Richard Zhao @ 2012-01-08 12:51 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Stephen Warren, linus.walleij, s.hauer, linux-kernel,
	rob.herring, kernel, Simon Glass (sjg@chromium.org),
	cjb, Dong Aisheng-B29396, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

On Sat, Jan 07, 2012 at 09:54:48PM +0800, Shawn Guo wrote:
> On Fri, Jan 06, 2012 at 10:03:07AM -0800, Stephen Warren wrote:
> > I see now.
> > 
> > I'd definitely be inclined to drop the num-pins and num-mux properties;
> > The values are just len(grp-pins)/4. You can still check that
> > len(grp-pins)==len(grp-mux) if you want to catch typos etc.
Maybe add a function of_u32_array_size? There' other drivers that need
to get array size.
> > 
> +1
> 
> > So, this does appear to be conflating the two things: The definition of
> > what pins are in a pingroup, and the mux function for a particular
> > setting of that pingroup. I think you need separate nodes for this.
> > 
> At least for imx, we do not have mux function setting for pingroup.
> Instead, it only applies to individual pin.
I think it depends on function definition of pinmux driver. For the
imx example patch, it's one-to-one.
> 
> > Without separate nodes, there will eventually be a lot of duplication.
> > A made-up example of the same uart4grp allowing either of two functions
> > uart3, uart4 to be muxed out onto it:
> > 
> > aips-bus@02000000 { /* AIPS1 */
> > 	iomuxc@020e0000 {
> > 		pinctrl_uart4_3: uart4@option_3 {
> > 			func-name = "uart3";
> > 			grp-name = "uart4grp";
> 
> With phandle in dts reflecting the mapping, neither func-name nor
> grp-name should be needed, and both can just be dropped, IMO.
Maybe map-name can be dropped too if dev-name uses phandle.
> 
> > 			grp-pins = <107 108>;
> > 			num-pins = <2>;
> > 			grp-mux = <3 3>;
> > 			num-mux = <2>;
> > 		};
> > 		pinctrl_uart4_4: uart4@option_4 {
> > 			func-name = "uart4";
> > 			grp-name = "uart4grp";
> > 			grp-pins = <107 108>;
> > 			num-pins = <2>;
> > 			grp-mux = <3 3>;
> > 			num-mux = <2>;
> > 		};
> > 	}
> > };
> > 
> > Now I understand that initially you aren't going to type out the complete
> > list of every available option into imx6q.dtsi because it's probably huge,
> > but the binding does need to allow you to do so without duplicating a lot
> > of data, because eventually you'll get boards that use a larger and larger
> > subset of all the options, so the number you need to represent at once in
> > imx6q.dtsi will grow.
If we don't want to lose flexibity, the pin group number will be huge
than you think. For example, 16bit display interface, has two alternatives
for every pin. The group number will be 2^16.
> > 
> > So I think you need to model the IMX pinmux controller's bindings more on
> > how the pinctrl subsystem represents objects; separate definitions of pins,
> > groups of pins, functions, and board settings. Something more like:
> > 
> > imx6q.dtsi:
> > 
> > aips-bus@02000000 { /* AIPS1 */
> > 	iomuxc@020e0000 {
> > 		/* FIXME: Perhaps need pin nodes here to name them too */
> 
> No, it's been listed in imx pinctrl driver.
> 
> > 
> > 		/* A node per group of pins. Each lists the group name, and
> > 		 * the list of pins in the group */
> > 		foogrp: group@100 {
> > 			grp-name = "foogrp";
> > 			grp-pins = <100 101>;
> > 		};
> > 		bargrp: group@102 {
> > 			grp-name = "bargrp";
> > 			grp-pins = <102 103>;
> > 		};
> > 		bazgrp: group@104 {
> > 			grp-name = "bargrp";
> > 			grp-pins = <104 105>;
> > 		};
> 
> I agree that we should define pingroups in <soc>.dtsi, but the mux
> setting needs to be under the pingroup node too.  See comment below ...
> 
> > 		/* A node per function that can be muxed onto pin groups,
> > 		 * each listing the function name, the set of groups it can
> > 		 * be muxed onto, and the mux selector value to program into
> > 		 * the groups' mux control register to select it */
> > 		uart3func: func@0 {
> > 			func-name = "uart3";
> > 			/* Length of locations and mux-value must match */
> > 			locations = <&foogrp &bargrp>;
> > 			mux-value = <0 4>;
> 
> This can be easily broken for imx.  As the mux setting applies to
> individual pin rather than pingroup, it's very valid for foogrp to
> have pin 100 muxed on mode 0 while pin 101 on mode 1.  That said,
> it's not necessarily true that we always have all the pins in
> particular pingroup muxed on the same setting for given function.
right.
> 
> > 		};
> > 		uart4func: func@1 {
> > 			func-name = "uart4";
> > 			locations = <&bargrp &bazgrp>;
> > 			mux-value = <6 3>;
> > 		};
> 
> I prefer to have function node defined in <board>.dtsi, since it's
> all about defining phandle to the correct pingroup, which should be
> decided by board design.
group and function are one-to-one mapped for imx. So if you put function
in board dts, why not put pin group there too?
> 
> > 	}
> > };
> > 
> > Or, instead of separate locations and mux-value properties with matching
> > lengths, perhaps a node for each location:
> > 
> > 		uart3func: func@0 {
> > 			func-name = "uart3";
> > 			location@0 {
> > 				location = <&foogrp>;
> > 				mux-value = <0>;
> > 			};
> > 			location@1 {
> > 				location = <&bargrp>;
> > 				mux-value = <4>;
> > 			};
> > 		};
> > 
> > That's more long-winded, but might be more easily extensible if we need
> > to add more properties later.
> > 
> > Now in the board's .dts file, you need to specify for each device the
> > list of pinmux groups the device needs to use, and the function to
> > select for each group. Perhaps something like:
> > 
> > board.dts:
> > 
> > usdhc@0219c000 { /* uSDHC4 */
> >         fsl,card-wired;
> >         status = "okay";
> >         pinmux = <&foogrp &uart3func &bazgrp &uart4func>;
> > };
> > 
> > I haven't convinced myself that's actually a good binding, but I think
> > it does represent the data required for muxing. Some potential issues
> > as before:
> > 
> > * Do we need to add flags to each entry in the list; GPIO/interrupt do?
> > 
> What's that for right now?  I guess we can add it later when we see
> the need.
> 
> > * Should "pinmux" be a node, and the configuration of each group be a
> > separate sub-node, so we can add more properties to each "table" entry
> > in the future, e.g. pin config parameters?
> > 
> I do not think it's necessary. 'pinctrl' phandle works perfectly fine
> to me at least for now.  How pinconf support should be added into
> pinctrl subsystem is still up in the air to me.
> 
> > * For Tegra, I elected to put the definitions of pins, groups, and
> > functions into the driver rather than in the device tree.
> 
> IMO, we do not want to do this for imx, as I'm scared of the size
> of Tegra pinctrl patches.  If we go this way for imx, we will have
> even bigger patches.
> 
> > This avoids
> > parsing a heck of a lot of data from device tree. That means there isn't
> > any per-function node that can be referred to by phandle. Does it make
> > sense to refer to groups and functions by string name or integer ID
> > instead of phandle? Perhaps:
> > 
> > usdhc@0219c000 { /* uSDHC4 */
> > 	fsl,card-wired;
> > 	status = "okay";
> > 	pinmux = {
> > 		group@0 {
> > 			group = "foo";
> > 			function = "uart3";
> > 			/* You could add pin config options here too */
> > 		};
> > 		group@1 {
> > 			group = "baz";
> > 			function = "uart4";
> > 		};
> > 	};
> > };
> > 
> > I guess referring to things by name isn't that idiomatic for device tree.
> > Using integers here would be fine too, so long as dtc gets support for
> > named constants:
> > 
> > imx6q.dtsi:
> > 
> > /define/ IMX_PINGRP_FOO 0
> > /define/ IMX_PINGRP_BAR 1
> > /define/ IMX_PINGRP_BAZ 2
> > /define/ IMX_PINFUNC_UART3 0
> > /define/ IMX_PINFUNC_UART4 1
> > ...
> > 
> > board .dts:
> > 
> > usdhc@0219c000 { /* uSDHC4 */
> > 	fsl,card-wired;
> > 	status = "okay";
> > 	pinmux = {
> > 		group@0 {
> > 			group = <IMX_PINGRP_FOO>;
> > 			function = <IMX_PINFUNC_UART3>;
> > 			/* You could add pin config options here too */
> > 		};
> > 		group@1 {
> > 			group = <IMX_PINGRP_BAZ>;
> > 			function = <IMX_PINFUNC_UART4>;
> > 		};
> > 	};
> > };
> > 
> Doing this does not change the fact that this is bound with Linux
> driver details.  That said, if the indexing of either pingrp array
> or pinfunc array changes in the driver, the binding is broken.
> 
> -- 
> Regards,
> Shawn
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2011-12-20 17:40 ` [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver Dong Aisheng
  2011-12-20 19:50   ` Marek Vasut
  2012-01-01 14:02   ` Linus Walleij
@ 2012-01-08 13:05   ` Richard Zhao
  2012-01-09  2:08     ` Shawn Guo
  2 siblings, 1 reply; 98+ messages in thread
From: Richard Zhao @ 2012-01-08 13:05 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-kernel, linus.walleij, s.hauer, w.sang, rob.herring,
	grant.likely, linux-arm-kernel, kernel, cjb, devicetree-discuss,
	shawn.guo

[snip]
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-imx53.c
> @@ -0,0 +1,443 @@
> +/*
> + * imx53 pinctrl driver based on imx pinmux core
> + *
> + * Copyright (C) 2011 Freescale Semiconductor, Inc.
> + * Copyright (C) 2011 Linaro, Inc.
> + *
> + * Author: Dong Aisheng <dong.aisheng@linaro.org>
> + *
> + * 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/init.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/pinmux.h>
> +
> +#include "pinctrl-imx-core.h"
> +
> +#define IMX53_IOMUXC_MUX_OFFSET 0x20
> +#define IMX53_IOMUXC_MAXPIN	(23*23)
> +
> +enum imx_imx53_pinctrl_pads {
> +	MX53_GPIO_19 = 0,
> +	MX53_KEY_COL0 = 1,
> +	MX53_KEY_ROW0 = 2,
> +	MX53_KEY_COL1 = 3,
> +	MX53_KEY_ROW1 = 4,
> +	MX53_KEY_COL2 = 5,
> +	MX53_KEY_ROW2 = 6,
...
Why not describe it in dts and make this file generic for imx?
One node for one pad, it'll be easy to extend pad properties. You know
the pad may set pull up/down, open drain, drive strenth, daisy chain etc.
The features have to be supported, to make your model usefull.

Thanks
Richard

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-08 12:51                   ` Richard Zhao
@ 2012-01-09  1:56                     ` Shawn Guo
  2012-01-09  6:18                       ` Simon Glass
  2012-01-11 18:37                       ` Stephen Warren
  2012-01-11 18:28                     ` Stephen Warren
  1 sibling, 2 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-09  1:56 UTC (permalink / raw)
  To: Richard Zhao
  Cc: Stephen Warren, linus.walleij, s.hauer, linux-kernel,
	rob.herring, kernel, Simon Glass (sjg@chromium.org),
	cjb, Dong Aisheng-B29396, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

On Sun, Jan 08, 2012 at 08:51:59PM +0800, Richard Zhao wrote:
...
> > > So, this does appear to be conflating the two things: The definition of
> > > what pins are in a pingroup, and the mux function for a particular
> > > setting of that pingroup. I think you need separate nodes for this.
> > > 
> > At least for imx, we do not have mux function setting for pingroup.
> > Instead, it only applies to individual pin.
> I think it depends on function definition of pinmux driver. For the
> imx example patch, it's one-to-one.

It should depend on particular imx soc pinmux design rather than
pinmux driver.  If it's always one-to-one case, we do not need
pinmux at all.  Aisheng's patch just did not enumerate all the groups
for given function.  Instead, it puts a couple simple examples there
for demonstration.

...

> > > 		uart4func: func@1 {
> > > 			func-name = "uart4";
> > > 			locations = <&bargrp &bazgrp>;
> > > 			mux-value = <6 3>;
> > > 		};
> > 
> > I prefer to have function node defined in <board>.dtsi, since it's
> > all about defining phandle to the correct pingroup, which should be
> > decided by board design.
> group and function are one-to-one mapped for imx.

Again, it's not the case.

> So if you put function
> in board dts, why not put pin group there too?

If we put pingroup data in <board>.dts, the data will be likely get
duplicated a lot in different board dts files.  For example, if
imx6q-sabrelite chooses the same pingroup for usdhc3 and usdhc4 as
imx6q-arm2, the pingroup data will be duplicated between imx6q-arm2.dts
and imx6q-sabrelite.dts.

On the contrary, putting pingroup data in <soc>.dtsi and having function
node in <board>.dts with phandle pointing to the correct pingroup will
help avoid such data duplication.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2012-01-08 13:05   ` Richard Zhao
@ 2012-01-09  2:08     ` Shawn Guo
  2012-01-09  2:17       ` Richard Zhao
  0 siblings, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-09  2:08 UTC (permalink / raw)
  To: Richard Zhao
  Cc: Dong Aisheng, linux-kernel, linus.walleij, s.hauer, w.sang,
	rob.herring, grant.likely, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, shawn.guo

On Sun, Jan 08, 2012 at 09:05:44PM +0800, Richard Zhao wrote:
> > +enum imx_imx53_pinctrl_pads {
> > +	MX53_GPIO_19 = 0,
> > +	MX53_KEY_COL0 = 1,
> > +	MX53_KEY_ROW0 = 2,
> > +	MX53_KEY_COL1 = 3,
> > +	MX53_KEY_ROW1 = 4,
> > +	MX53_KEY_COL2 = 5,
> > +	MX53_KEY_ROW2 = 6,
> ...
> Why not describe it in dts and make this file generic for imx?
> One node for one pad,

Doing this will bloat the device tree dramatically.  Actually I had
a patch doing so before the pinctrl subsystem was born, but it
concerned Grant a lot for that reason and thus died.

> it'll be easy to extend pad properties. You know
> the pad may set pull up/down, open drain, drive strenth, daisy chain etc.
> The features have to be supported, to make your model usefull.
> 
As Aisheng mentioned, the pinconf support will be added later.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2012-01-09  2:08     ` Shawn Guo
@ 2012-01-09  2:17       ` Richard Zhao
  2012-01-09  6:32         ` Shawn Guo
  0 siblings, 1 reply; 98+ messages in thread
From: Richard Zhao @ 2012-01-09  2:17 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Richard Zhao, linus.walleij, s.hauer, w.sang, rob.herring,
	linux-kernel, grant.likely, shawn.guo, kernel, cjb, Dong Aisheng,
	devicetree-discuss, linux-arm-kernel

On Mon, Jan 09, 2012 at 10:08:51AM +0800, Shawn Guo wrote:
> On Sun, Jan 08, 2012 at 09:05:44PM +0800, Richard Zhao wrote:
> > > +enum imx_imx53_pinctrl_pads {
> > > +	MX53_GPIO_19 = 0,
> > > +	MX53_KEY_COL0 = 1,
> > > +	MX53_KEY_ROW0 = 2,
> > > +	MX53_KEY_COL1 = 3,
> > > +	MX53_KEY_ROW1 = 4,
> > > +	MX53_KEY_COL2 = 5,
> > > +	MX53_KEY_ROW2 = 6,
> > ...
> > Why not describe it in dts and make this file generic for imx?
> > One node for one pad,
> 
> Doing this will bloat the device tree dramatically.  Actually I had
> a patch doing so before the pinctrl subsystem was born, but it
> concerned Grant a lot for that reason and thus died.
are you against describing pad in dts or one node per pad?
one node per pad is just a tip to extend pad property, to support
other features (pinconf in your word).
> 
> > it'll be easy to extend pad properties. You know
> > the pad may set pull up/down, open drain, drive strenth, daisy chain etc.
> > The features have to be supported, to make your model usefull.
> > 
> As Aisheng mentioned, the pinconf support will be added later.
I expect pinconf come together, and get a ready-to-use patch series.

Thanks
Richard
> 
> -- 
> Regards,
> Shawn
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-09  1:56                     ` Shawn Guo
@ 2012-01-09  6:18                       ` Simon Glass
  2012-01-10 11:30                         ` Dong Aisheng-B29396
  2012-01-11 19:19                         ` Stephen Warren
  2012-01-11 18:37                       ` Stephen Warren
  1 sibling, 2 replies; 98+ messages in thread
From: Simon Glass @ 2012-01-09  6:18 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Richard Zhao, Stephen Warren, linus.walleij, s.hauer,
	linux-kernel, rob.herring, kernel, cjb, Dong Aisheng-B29396,
	devicetree-discuss, linux-arm-kernel, Dong Aisheng

Hi,

[snip lots of discussion]

Someone copied me on this so I feel I can sneak in with a response. I
have read this entire thread and implemented Tegra pinmux in U-boot,
but not much else on the topic so have limited understanding,
particular of the kernel pinmux setup, unfortunately. Sorry if I have
the wrong end of the stick on some of this, but I hope my comments are
useful.

1. Symbolic names

> Stephen said:
> It's a real pity that dtc doesn't have a way of doing named integer
> constants, so this could be re-written as e.g.:
> SoC .dtsi file:
> /define/ TEGRA_MUX_FUNC_SD4 234

IMO this is essential for pinmux. Stephen has already done a patch
which implements this feature. The alternative is bindings with lots
of arbitrary numbers - lots of errors, lots of confusion, lots of
pain. He has asked a few times on the device-tree list for this
feature to be accepted. I believe it should be, and pinmux brough in
with that in mind. Turning symbols into numbers is the role of the
device tree compiler I think.

If Stephen's proposed grammar needs tweaking that is fine, but I think
we are pushing the limits of a pure numerical representation here.


2. Stephen also said:

> We also need to consider compatibility and extensibility. A DT binding
> is an ABI between the kernel and whatever is providing it, and so we
> need to be able to maintain and extend it in a compatible fashion, just
> like the user-space syscall ABI. Now it's true that the .dts files are
> currently part of the kernel source tree and can be rev'd in sync with
> kernel changes, but that may not always be the case moving forward.
>
> In other words, taking a board with an old device tree embedded into
> Flash and running a new kernel using that device tree should work just
> like running the original kernel did.

While this is true we should remember that SOCs will change and
evolve, and we don't actually need a device tree for a Tegra 2 (say)
to be able to boot a Tegra 3 kernel. So each time we create a new SOC
in a family, we have the opportunity to update the fdt, potentially in
an incompatible way, since we know that the old boot loader and new
kernel are incompatible anyway.

Anyway we are looking at pinmux from a 2012 view of how SOCs do
things. We can't predict what things will look like in the future. The
device tree format is great for making things extensible, but there is
an efficiency cost also.

Backwards compatibility can create a lot of problems with newer
designs, so I don't think we should be slaves to it. We are backwards
compatible because it aids understanding, is necessary for kernels to
run across different boards, etc., not just for its own sake. If in
the future we decide that the approach agreed now no longer servers
the purpose and has too much baggage, we can change it. Similar things
happen in the rest of the kernel.

Also IMO updating the kernel without the device tree doesn't make a
huge amount of sense. Why not just update both? Really to me the
device tree is almost like static data for the kernel. It is a worthy
goal to keep it as static as possible, but if it changes I don' t
think it is the end of civilisation.


3. Efficiency

There has been talk about using strings to link things. IMO this is
inefficient and slow compared to integers and device trees already
have phandles. Some platforms will care more than others, but if the
reason for using strings is that the device tree format does not
support symbolic representation of integers, then see 1 above.


4. Who bears the pain?

There is a lot of complexity in pinmux - if we continue to split the
device tree into an SOC file and a board file then we should think
about which one bears the brunt of the complexity. IMO it should be
the SOC file. The SOC file is written by very clever engineers working
for the SOC vendor. They are motivated to get their SOC working
properly and for it to be easy for customers to access the glorious
ground-breaking feature therein. On the other hand, the board file (to
the extent it is not just copied from the vendor's example) is put
together by people with little knowledge of the SOC, limited time to
do the work and minimal interest in the wonders of the device tree
structure.

With this in mind I think the pinmux complexity should mostly be in
the SOC file. This includes the selection of valid pinmux options.
After all, despite the many possible ways that functions could be
brought out of the chip, only a certain few ways typically make sense.
For example, an SDMMC peripheral needs clock and command pins - unless
these are connected then nothing with work. Similarly there is no
sense in having two data[0] pins brought out for the same SDMMC port.

In fact the SOC vendor generally has a good idea about the different
options and mostly there are a small number of useful ones. So why
don't we just enumerate these in the SOC file and let the board select
what it wants in a single setting?


5. Start at the top: function mux

I propose adding a new level at the top, a function mux. This
basically routes functions to one of 2-3 predefined options. So UART1
can come out on 3 different sets of pins, SDMMC2 on two sets, etc.
These are recommended from the vendor and in common use (e.g. on
reference designs), so should be easy to use.

Below the function mux is the group mux. Here we specify a list of pin
groups and which function each group is assigned to. Together these
2-3 groups join to give us the pins that the function mux needs.

Below the pin groups are the pins. Some SOCs will have only one pin
per group, some will have a group mux that really just moves entire
functions around.

IMO the top level belongs with the board file. If the board designer
wants to depart from common options they can suffer the pain of
dropping down to the group level.

So at the board level it would be nice to do something like this:

sdhci@c8000400 {
	funcmux = <&sdmmc3-funcmux 0 0>;  /* funcmux phandle, config option, flags */
};

which means that we want this SDMMC port to use configuration 0 (out
of perhaps 2-3 recommended options the SOC provides for bringing out
this SDMMC function) and that there are no special flags required. Or:

emmc: sdhci@c8000600 {
	funcmux = <&sdmmc4-funcmux 1 OPT_SDMMC_8BIT>;
}

which means for this port we want to use configuration 1 with 8-bit wide data.

Something like this is easy for the board files to deal with. It fits
with the way reference designs are done (selecting from a few
options). It allows flags to specify different options like 4-bit or
8-bit wide SDMMC which can affect what pinmux groups are affected.

Some boot loaders might even implement things only at the funcmux
level, with hard-coded configuration of the actual pin groups in
static data in their code, without reference to the device tree. This
might allow them to operate with a vastly truncated device tree. They
might be very motivated to do this if the full device tree consists of
20KB of strings :-)


6. Groups

Already done in the discussion prior to this email:

uart4func: func@1 {
       func-name = "uart4";
       locations = <&bargrp &bazgrp>;
       mux-value = <6 3>;
};

but how above adding a flag cell and putting the locations and values
into the same property, like:

uart4func: func@1 {
       func-name = "uart4";
       locations = <&bargrp 6 0>
		<&bazgrp 3 SOME_FLAG>;
};


So the SDMMC example might have three options for SDMMC4: a 4-bit one,
and two 8-bit ones (changing 'locations' to 'groups'):

sdmmc4-funcmux : sdmmc4_funcmux@0 {
	setting@0 {
		config = <0>;
		option = <OPT_SDMMC_8BIT>;
		groups = <&pingrp-atc FUNC_SDIO4 0> /* clk, cmd, data 1, 3, 5, 7 */
			<&pingrp-atd FUNC_SDIO4 0>; /* data 0, 2, 4, 6 */
	};

	setting@1 {
		config = <1>;
		option = <0>;
		groups = <&pingrp-atb FUNC_SDIO4 0>  /* clock, command */
			<&pingrp-gma FUNC_SDIO4 0>; /* data[3:0] */
	};

	setting@2 {
		config = <1>;
		option = <OPT_SDMMC_8BIT>;
		groups = <&pingrp-atb FUNC_SDIO4 0>  /* clock, command */
			<&pingrp-gma FUNC_SDIO4 0> /* data[3:0] */
			<&pingrp-gme FUNC_SDIO4 0>; /* data [7:4] */
	};
};

The 'config' property refers to the second cell of the reference in
the funcmux. The option property refers to the third cell. Essentially
the vendor is recommending three possible options for SDMMC4 and the
board can choose which one it likes.

The disadvantage is that the last two share the pingrp-atb setting,
and the last just adds an extra group, but no matter. It is easy to
understand.

A related problem is that the options must each be enumerated. Maybe
that doesn't matter either for the moment.

Then for the groups, again already done above, but I am less clear on
the exact binding that is arrived at above. Something like this?

pingrp-atb: pingrp_atb@0 {
	locations = <&pin-i02 &pin-t07>;
	control = <&pinmux 0>;
	/* 4 options available, numbered 0 to 3 */
	functions = <FUNC_IDE   FUNC_NAND   FUNC_GMI   FUNC_SDIO4>;
	/* do we want to specify what the flags do here? I assume they are
           globally understood by the pinmux system rather than specific to
	   each group */
};

pingrp-atd: pingrp_atd@0 {
	locations = <&pin-h01 &pin-h02 &pin-h03 &pin-h04>;
	control = <&pinmux 3>;  /* 3 is the pinmux controller's ID for the atd group */
	/* 4 options available, numbered 0 to 3 */
	functions = <FUNC_IDE   FUNC_NAND   FUNC_GMI   FUNC_SDIO4>;
};


(It is probably obvious, but FUNC_SDIO4 is not just the value 3. It
might be 21 - the pinmux code searches the list of 4 options for
FUNC_SDIO4. The position it finds it in this case is 3, so that is the
value written to &pinmux)


7. Pins

At this level I'm not sure if a device tree representation adds much.
Maybe connect the GPIOs?

pin-i02: pin_i02@0 {
	name = "i02";
	gpio = <&gpio 66>;
};

pin-t07: pin_t07@0 {
	name = "t07";
	gpio = <&gpio 167>;
};


8. Flexibility

Someone asked how to deal with an LCD output with 16 bits each of
which can be on two pins. Know you of such an SOC? If so, then it is
still possible that the SOC would provide a few basic 'common' options
at the funcmux level. But board designers may have to steel themselves
and dive into the the pingroup level.

Where an SOC has no groups but only pins, then perhaps the funcmux can
still be provided, but uses a 'pins' property instead of 'groups':

sdmmc4-funcmux : sdmmc4_funcmux@0 {
        ...
	setting@2 {
		config = <1>;
		option = <OPT_SDMMC_8BIT>;
		pins = <&pin-i02 FUNC_SDIO4 0>  /* clock */
			<&pin-t07 FUNC_SDIO4 0>  /* command */
			<&pin-a00 FUNC_SDIO4 0>  /* data[0] */
			<&pin-a01 FUNC_SDIO4 0>  /* data[1] */
			<&pin-a02 FUNC_SDIO4 0>  /* data[2] */
			<&pin-a03 FUNC_SDIO4 0>;  /* data[3] */
			<&pin-a04 FUNC_SDIO4 0>;  /* data[4] */
			<&pin-a05 FUNC_SDIO4 0>;  /* data[5] */
			<&pin-a06 FUNC_SDIO4 0>;  /* data[6] */
			<&pin-a07 FUNC_SDIO4 0>;  /* data[7] */
	};
};

IMO this sort of thing makes it even more desirable to have a
high-level pinmux feature in the device tree. Again, the board
designer can dive into pins by defining his own custom funcmux-level
things, so no flexibility is lost.

Regards,
Simon

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2012-01-09  2:17       ` Richard Zhao
@ 2012-01-09  6:32         ` Shawn Guo
  2012-01-10  8:38           ` Richard Zhao
  0 siblings, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-09  6:32 UTC (permalink / raw)
  To: Richard Zhao
  Cc: Richard Zhao, linus.walleij, s.hauer, w.sang, rob.herring,
	linux-kernel, grant.likely, shawn.guo, kernel, cjb, Dong Aisheng,
	devicetree-discuss, linux-arm-kernel

On Mon, Jan 09, 2012 at 10:17:03AM +0800, Richard Zhao wrote:
> On Mon, Jan 09, 2012 at 10:08:51AM +0800, Shawn Guo wrote:
> > On Sun, Jan 08, 2012 at 09:05:44PM +0800, Richard Zhao wrote:
> > > > +enum imx_imx53_pinctrl_pads {
> > > > +	MX53_GPIO_19 = 0,
> > > > +	MX53_KEY_COL0 = 1,
> > > > +	MX53_KEY_ROW0 = 2,
> > > > +	MX53_KEY_COL1 = 3,
> > > > +	MX53_KEY_ROW1 = 4,
> > > > +	MX53_KEY_COL2 = 5,
> > > > +	MX53_KEY_ROW2 = 6,
> > > ...
> > > Why not describe it in dts and make this file generic for imx?
> > > One node for one pad,
> > 
> > Doing this will bloat the device tree dramatically.  Actually I had
> > a patch doing so before the pinctrl subsystem was born, but it
> > concerned Grant a lot for that reason and thus died.
> are you against describing pad in dts or one node per pad?
> one node per pad is just a tip to extend pad property, to support
> other features (pinconf in your word).

I definitely want to describe pinconf in device tree, though what's
the best interface for pinctrl client driver to talk to pinconf is
still vague to me.

> > 
> > > it'll be easy to extend pad properties. You know
> > > the pad may set pull up/down, open drain, drive strenth, daisy chain etc.
> > > The features have to be supported, to make your model usefull.
> > > 
> > As Aisheng mentioned, the pinconf support will be added later.
> I expect pinconf come together, and get a ready-to-use patch series.
> 
As I was educated by Linus.W, we can not drink ocean and we need to
split big chunk of work into pieces and achieve it step by step.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-06 17:23               ` Stephen Warren
@ 2012-01-10  7:02                 ` Dong Aisheng-B29396
  0 siblings, 0 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-10  7:02 UTC (permalink / raw)
  To: Stephen Warren, linux-kernel
  Cc: linus.walleij, s.hauer, rob.herring, linux-arm-kernel, kernel,
	cjb, devicetree-discuss

> -----Original Message-----
> From: Stephen Warren [mailto:swarren@nvidia.com]
> Sent: Saturday, January 07, 2012 1:24 AM
> To: Dong Aisheng-B29396; linux-kernel@vger.kernel.org
> Cc: linus.walleij@stericsson.com; s.hauer@pengutronix.de;
> rob.herring@calxeda.com; linux-arm-kernel@lists.infradead.org;
> kernel@pengutronix.de; cjb@laptop.org; devicetree-discuss@lists.ozlabs.org
> Subject: RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> Dong Aisheng-B29396 wrote at Friday, January 06, 2012 3:51 AM:
> > Stephen Warren wrote at Friday, January 06, 2012 7:38 AM:
> > > Dong Aisheng-B29396 wrote at Tuesday, December 27, 2011 7:41 AM:
> ...
> > > > But what about the pin maps without device associated?
> > >
> > > Indeed; that's why I'd tend towards defining a table of pinmux usage
> > > in the pinmux node, and having other devices refer to that table.
> >
> > Currently we still prefer to use device node relationship to reflect
> > the pinmux map if we can since as you said pinmux map is little
> > depending on the pinctrl subsystem implementation.
> > And I'm trying to do it now.
> >
> > > Still, if the pinmux definitions are in the device nodes, we could
> > > simply make the pinmux controller have such a definition itself too, for the
> "system hog"
> > > case.
> >
> > Yes, that way I think is like:
> > iomuxc@020e0000 {
> >         pinctrl_uart4: uart4 {
> >                 grp-pins = <107 108>;
> >                 grp-mux = <4 4>;
> > 		   hog_on_boot;
> >         };
> > }
> 
> If pinmux usage is defined in each individual device node,
Per my understanding a phandle to the pinmux usage defined in iomuxc node
Is also ok.
The next, you also pointed out before, we need to find a at least semi-standardized
per-device "pinmux" property which is suitable for all platforms.

> and the "hog"
> setup is included in the pinmux controller's own device node, then there's no
> need for a "hog_on_boot" property; any pinmux setup node that's inside the
> pinmux controller node would automatically be a "hog" entry, and could be
> activated as soon as the pinmux controller was probed and registered with the
> pinctrl subsystem.
> 
+1
I think this is a right solution for dt without a pinmux map.

> (as a minor nit, DT usually uses - not _ in property names, so that would be
> "hog-on-boot").
> 
> --
> nvpublic
> 



^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-06 18:03               ` Stephen Warren
  2012-01-07 13:54                 ` Shawn Guo
@ 2012-01-10  8:21                 ` Dong Aisheng-B29396
  2012-01-10 13:05                   ` Shawn Guo
  2012-01-11 20:17                   ` Stephen Warren
  1 sibling, 2 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-10  8:21 UTC (permalink / raw)
  To: Stephen Warren, Dong Aisheng
  Cc: linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org)

> -----Original Message-----
> From: Stephen Warren [mailto:swarren@nvidia.com]
> Sent: Saturday, January 07, 2012 2:03 AM
> To: Dong Aisheng-B29396; Dong Aisheng
> Cc: linux-kernel@vger.kernel.org; linus.walleij@stericsson.com;
> s.hauer@pengutronix.de; rob.herring@calxeda.com; linux-arm-
> kernel@lists.infradead.org; kernel@pengutronix.de; cjb@laptop.org; devicetree-
> discuss@lists.ozlabs.org; Simon Glass (sjg@chromium.org)
> Subject: RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> Dong Aisheng-B29396 wrote at Friday, January 06, 2012 4:34 AM:
> > Stephen Warren wrote at Friday, January 06, 2012 9:06 AM:
> > > Dong Aisheng wrote at Thursday, January 05, 2012 6:48 AM:
> > > > On Sun, Dec 25, 2011 at 11:37 AM, Stephen Warren <swarren@nvidia.com>
> wrote:
> > > > > Dong Aisheng-B29396 wrote at Thursday, December 22, 2011 1:18 AM:
> > > ...
> > > > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.txt
> > > ...
> > > > +Examples:
> > > > +soc {
> > > > +	aips-bus@02000000 { /* AIPS1 */
> > > > +		iomuxc@020e0000 {
> > > > +			pinctrl_uart4: uart4 {
> > > > +				func-name = "uart4";
> > > > +				grp-name = "uart4grp";
> > > > +				grp-pins = <107 108>;
> > > > +				num-pins = <2>;
> > > > +				grp-mux = <4 4>;
> > > > +				num-mux = <2>;
> > > > +			};
> > >
> > > Before I get too far into reviewing this path, could you explain the
> > > above node in a little more detail; what it is and what the properties
> define?
> > >
> > grp-pins is the group of pins for this function.
> > grp-mux is the corresponding mux setting of each pin in that group for
> > this specific function.
> > num-pins and num-mux are the number of pins and mux. They're mainly
> > used for sanity Checking in driver since it's easy to make a mistake
> > when write too many pins for a function. These two could be removed finally.
> 
> I see now.
> 
> I'd definitely be inclined to drop the num-pins and num-mux properties; The
> values are just len(grp-pins)/4. You can still check that
> len(grp-pins)==len(grp-mux) if you want to catch typos etc.
> 
Yes, that's right. Thanks for the suggestion.

> So, this does appear to be conflating the two things: The definition of what
> pins are in a pingroup, and the mux function for a particular setting of that
> pingroup. I think you need separate nodes for this.
> 
As shawn said, here the mux for IMX is tightly for each individuals pins rather
than groups.
Since the pins are grouped in functions, the mux for each pin is also fixed for
That function, We prefer to put mux together with pins of group.

> Without separate nodes, there will eventually be a lot of duplication.
> A made-up example of the same uart4grp allowing either of two functions uart3,
> uart4 to be muxed out onto it:
> 
> aips-bus@02000000 { /* AIPS1 */
> 	iomuxc@020e0000 {
> 		pinctrl_uart4_3: uart4@option_3 {
> 			func-name = "uart3";
> 			grp-name = "uart4grp";
> 			grp-pins = <107 108>;
> 			num-pins = <2>;
> 			grp-mux = <3 3>;
> 			num-mux = <2>;
> 		};
> 		pinctrl_uart4_4: uart4@option_4 {
> 			func-name = "uart4";
> 			grp-name = "uart4grp";
> 			grp-pins = <107 108>;
> 			num-pins = <2>;
> 			grp-mux = <3 3>;
> 			num-mux = <2>;
> 		};
> 	}
> };
> 
> Now I understand that initially you aren't going to type out the complete list
> of every available option into imx6q.dtsi because it's probably huge, but the
> binding does need to allow you to do so without duplicating a lot of data,
> because eventually you'll get boards that use a larger and larger subset of all
> the options, so the number you need to represent at once in imx6q.dtsi will grow.
> 
> So I think you need to model the IMX pinmux controller's bindings more on how
> the pinctrl subsystem represents objects; separate definitions of pins, groups
> of pins, functions, and board settings. Something more like:
> 
You're right.
To keep consistency with the current design of pinctrl subsystem,
I think we should do like that.

> imx6q.dtsi:
> 
> aips-bus@02000000 { /* AIPS1 */
> 	iomuxc@020e0000 {
> 		/* FIXME: Perhaps need pin nodes here to name them too */
> 
We did it in pinctrl driver.
I have not seen any strong reason up till now that we should put pin defines
In dts file.

> 		/* A node per group of pins. Each lists the group name, and
> 		 * the list of pins in the group */
> 		foogrp: group@100 {
> 			grp-name = "foogrp";
> 			grp-pins = <100 101>;
> 		};
> 		bargrp: group@102 {
> 			grp-name = "bargrp";
> 			grp-pins = <102 103>;
> 		};
> 		bazgrp: group@104 {
> 			grp-name = "bargrp";
> 			grp-pins = <104 105>;
> 		};
> 		/* A node per function that can be muxed onto pin groups,
> 		 * each listing the function name, the set of groups it can
> 		 * be muxed onto, and the mux selector value to program into
> 		 * the groups' mux control register to select it */
> 		uart3func: func@0 {
> 			func-name = "uart3";
> 			/* Length of locations and mux-value must match */
> 			locations = <&foogrp &bargrp>;
> 			mux-value = <0 4>;
> 		};
> 		uart4func: func@1 {
> 			func-name = "uart4";
> 			locations = <&bargrp &bazgrp>;
> 			mux-value = <6 3>;
> 		};
> 	}
> };
> 
> Or, instead of separate locations and mux-value properties with matching lengths,
> perhaps a node for each location:
> 
> 		uart3func: func@0 {
> 			func-name = "uart3";
> 			location@0 {
> 				location = <&foogrp>;
> 				mux-value = <0>;
> 			};
> 			location@1 {
> 				location = <&bargrp>;
> 				mux-value = <4>;
> 			};
> 		};
> 
> That's more long-winded, but might be more easily extensible if we need to add
> more properties later.
> 
Your example are right for us and also meet our ideas.
And I'm going to do like that.

> Now in the board's .dts file, you need to specify for each device the list of
> pinmux groups the device needs to use, and the function to select for each group.
> Perhaps something like:
> 
> board.dts:
> 
> usdhc@0219c000 { /* uSDHC4 */
>         fsl,card-wired;
>         status = "okay";
>         pinmux = <&foogrp &uart3func &bazgrp &uart4func>; };
> 
> I haven't convinced myself that's actually a good binding, but I think it does
> represent the data required for muxing. Some potential issues as before:
> 
Here is what we should discuss exactly.
Since 'pinmux' phandle will be parsed in pinctrl core, we should try to find and 
define a common and standardized pinmux property for all platforms.
>From the pinctrl subsystem point of view, specifying the function name and group
name is sufficient for construct a pinmux map for this device.
We can get the two info from the phandle.
So what you describe here seems correct for me.

Pinctrl core can get the function name from the phandle.
Here what I wonder is that do we need to allow the platform to use a func-name
property in their pinmux func node or pinmux group node to specify the name.
If it is allowed, then it could be flexible for soc to define their names.
If not there may be limitations on their node names since we can only get it from
the node name.
Another option is that we could assume each platform may have a func-name property
in their each pinmux function node. If it exists we get the name from func-name
property, if not, we get the name from the pinmux function node name.
For group name it could be in the same way.

Without the func name and group name, pinctrl do not have other special requirements
to for the func node and group node (just like what the pinctrl subsystem does now
in non-dt). It's very flexible and up to each SoC.

To keep consistency as the currently design of pinctrl subsystem and also meet
the dt design philosophy, we still do not introduce a pinmux map in dt.
Instead, we choose to scan all the device node with a 'pinmux' phandle to construct
a pinmux map table before register the pin controller device(here we may also scan
the hog_on_boot node) and I guess it's easy to do that.

After that, we have pinmux map, plus the pinmux function list and group list
(we already have function list and group list defined in the way as Stephen described).
So everything is here and it then can work exacty as the same way as non-dt pinctrl
subsystem works.
Another important thing is that we can still use the sysfs interface exported to user
space for pinctrl subsystem used via dt.
(Without scan the device node to construct the pinmux map table, we can only get the map
Information when we run the pinmux_get.
See: https://lkml.org/lkml/2012/1/5/153
So no pinmux map table exists and we surely do not want to see that the sysfs exporting
pinmux map information works in dt but unwork in non-dt)

BTW it seems you want to support multi pin groups(foogrp and bazgrp) for one device,
do we have such using case?
I guess usually one pin group already contains all the pins of device.
Anyway, just from flexibility view, it's good for me.

> * Do we need to add flags to each entry in the list; GPIO/interrupt do?
> 
We can add it when we have the real needs.

> * Should "pinmux" be a node, and the configuration of each group be a separate
> sub-node, so we can add more properties to each "table" entry in the future, e.g.
> pin config parameters?
> 
Currently no drivers are using pinctrl subsystem via dt.
So I think we can easy to make changes to improve the design if we really want to.
But before that we should get it running first.

> * For Tegra, I elected to put the definitions of pins, groups, and functions
> into the driver rather than in the device tree. This avoids parsing a heck of a
> lot of data from device tree. That means there isn't any per-function node that
> can be referred to by phandle. Does it make sense to refer to groups and
> functions by string name or integer ID instead of phandle? Perhaps:
> 
> usdhc@0219c000 { /* uSDHC4 */
> 	fsl,card-wired;
> 	status = "okay";
> 	pinmux = {
> 		group@0 {
> 			group = "foo";
> 			function = "uart3";
> 			/* You could add pin config options here too */
> 		};
> 		group@1 {
> 			group = "baz";
> 			function = "uart4";
> 		};
> 	};
> };
> 
> I guess referring to things by name isn't that idiomatic for device tree.
> Using integers here would be fine too, so long as dtc gets support for named
> constants:
> 
> imx6q.dtsi:
> 
> /define/ IMX_PINGRP_FOO 0
> /define/ IMX_PINGRP_BAR 1
> /define/ IMX_PINGRP_BAZ 2
> /define/ IMX_PINFUNC_UART3 0
> /define/ IMX_PINFUNC_UART4 1
> ...
> 
> board .dts:
> 
> usdhc@0219c000 { /* uSDHC4 */
> 	fsl,card-wired;
> 	status = "okay";
> 	pinmux = {
> 		group@0 {
> 			group = <IMX_PINGRP_FOO>;
> 			function = <IMX_PINFUNC_UART3>;
> 			/* You could add pin config options here too */
> 		};
> 		group@1 {
> 			group = <IMX_PINGRP_BAZ>;
> 			function = <IMX_PINFUNC_UART4>;
> 		};
> 	};
> };
> 
> > > I'm confused because the node has properties for function name and
> > > group name which make sense to define the mux setting for that group.
> > > However, I'm not sure what the grp-pins/num-pins/grp-mux/num-mux
> > > properties are for; if those properties define the available mux
> > > options and for the group and set of pins included in the group, I
> > > think the node is representing too many things in one place. I'd expect to
> see:
> > >
> > > a) Either data in the pinctrl driver or separate DT nodes to define
> > > each available pin group, mux function, etc.; the definition of what
> > > the SoC itself can do.
> > >
> > > b) The configuration of each pin group that's used by the particular board.
> > > All that's relevant here is the mux selection for each pin groups;
> > > things like which pins are included in each group are defined by the
> > > SoC not the board and hence wouldn't be included in a per-board node.
> >
> > We still have not started pin config work.
> > For pinmux, one way we thought is trying to define pin groups in soc
> > dts file and reference that pin group by a phandle in board dts file.
> > It could be:
> > In the soc dts file arch/arm/boot/dts/imx6q.dtsi:
> >
> > iomuxc@020e0000 {
> >         reg = <0x020e0000 0x4000>;
> >         pinmux-groups {
> >                 pingrp_uart4: uart4 {
> >                         grp-pins = <107 108>;
> >                         grp-mux = <4 4>;
> >                 };
> >
> >                 pingrp_sd4: sd4 {
> >                         grp-pins = <170 171 180 181 182 183 184 185 186 187>;
> >                         grp-mux = <0 0 1 1 1 1 1 1 1 1>;
> >                 }
> >         }
> > };
> >
> > In board dts file:
> > usdhc@0219c000 { /* uSDHC4 */
> >         fsl,card-wired;
> >         status = "okay";
> >         pinmux = <&pinctrl_sd4>;
> > };
> >
> > uart3: uart@021f0000 { /* UART4 */
> >         status = "okay";
> >         pinmux = <&pinctrl_uart4>;
> > };
> >
> > iomuxc@020e0000 {
> >         pinctrl_uart4: uart4 {
> >                 group = <&pingrp_uart4>;
> >                 pinconfig = ....;
> >         };
> >
> >         pinctrl_sd4: sd4 {
> >                 group = <&pingrp_sd4>;
> >                 pinconfig = ....;
> >         };
> > };
> >
> > Then we know the whole map information for a specific device without a pinmux
> map.
> > Do you think if it's ok?
> >
> > BTW, for imx we won't define all possible groups since most are
> > useless and It's hard to cover all cases due to the issue raised by Sascha
> before.
> > We only define what we're most using firstly.
> 
> --
> nvpublic
> 

Regards
Dong Aisheng


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2012-01-09  6:32         ` Shawn Guo
@ 2012-01-10  8:38           ` Richard Zhao
  2012-01-10 10:43             ` Linus Walleij
  0 siblings, 1 reply; 98+ messages in thread
From: Richard Zhao @ 2012-01-10  8:38 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Richard Zhao, linus.walleij, s.hauer, w.sang, rob.herring,
	linux-kernel, grant.likely, shawn.guo, kernel, cjb, Dong Aisheng,
	devicetree-discuss, linux-arm-kernel

On Mon, Jan 09, 2012 at 02:32:12PM +0800, Shawn Guo wrote:
> On Mon, Jan 09, 2012 at 10:17:03AM +0800, Richard Zhao wrote:
> > On Mon, Jan 09, 2012 at 10:08:51AM +0800, Shawn Guo wrote:
> > > On Sun, Jan 08, 2012 at 09:05:44PM +0800, Richard Zhao wrote:
> > > > > +enum imx_imx53_pinctrl_pads {
> > > > > +	MX53_GPIO_19 = 0,
> > > > > +	MX53_KEY_COL0 = 1,
> > > > > +	MX53_KEY_ROW0 = 2,
> > > > > +	MX53_KEY_COL1 = 3,
> > > > > +	MX53_KEY_ROW1 = 4,
> > > > > +	MX53_KEY_COL2 = 5,
> > > > > +	MX53_KEY_ROW2 = 6,
> > > > ...
> > > > Why not describe it in dts and make this file generic for imx?
> > > > One node for one pad,
> > > 
> > > Doing this will bloat the device tree dramatically.  Actually I had
> > > a patch doing so before the pinctrl subsystem was born, but it
> > > concerned Grant a lot for that reason and thus died.
> > are you against describing pad in dts or one node per pad?
> > one node per pad is just a tip to extend pad property, to support
> > other features (pinconf in your word).
> 
> I definitely want to describe pinconf in device tree, though what's
> the best interface for pinctrl client driver to talk to pinconf is
> still vague to me.
> 
> > > 
> > > > it'll be easy to extend pad properties. You know
> > > > the pad may set pull up/down, open drain, drive strenth, daisy chain etc.
> > > > The features have to be supported, to make your model usefull.
> > > > 
> > > As Aisheng mentioned, the pinconf support will be added later.
> > I expect pinconf come together, and get a ready-to-use patch series.
> > 
> As I was educated by Linus.W, we can not drink ocean and we need to
> split big chunk of work into pieces and achieve it step by step.
Sure, we can not drink out the ocean :). But if people can not use it
in real case, how do we verify the driver? How do we know the driver
goes in the right way?

Thanks
Richard
> 
> -- 
> Regards,
> Shawn
> 


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2012-01-10  8:38           ` Richard Zhao
@ 2012-01-10 10:43             ` Linus Walleij
  2012-01-10 10:55               ` Dong Aisheng-B29396
  2012-01-10 13:51               ` Shawn Guo
  0 siblings, 2 replies; 98+ messages in thread
From: Linus Walleij @ 2012-01-10 10:43 UTC (permalink / raw)
  To: Richard Zhao
  Cc: Shawn Guo, Richard Zhao, linus.walleij, s.hauer, w.sang,
	rob.herring, linux-kernel, grant.likely, shawn.guo, kernel, cjb,
	Dong Aisheng, devicetree-discuss, linux-arm-kernel

On Tue, Jan 10, 2012 at 9:38 AM, Richard Zhao
<richard.zhao@freescale.com> wrote:
> On Mon, Jan 09, 2012 at 02:32:12PM +0800, Shawn Guo wrote:
>> As I was educated by Linus.W, we can not drink ocean and we need to
>> split big chunk of work into pieces and achieve it step by step.
> Sure, we can not drink out the ocean :). But if people can not use it
> in real case, how do we verify the driver? How do we know the driver
> goes in the right way?

If you prefer to do a big upfront design of the entire driver then please
by all means do that.

What we need to know right now is what you need from the pin
controller core to do that. We have a (custom) pinconf API now,
does it fit the bill?

I have spent some time on generic pin config, it was not much
commented so if it helps you please ACK the patches.

Next from discussions with Stpehen I've sort of figured out that
we need a config mapping table of sorts and then a means to activate
entries of that table at runtime. I'm trying to come up with something
for this.

Yours,

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2012-01-10 10:43             ` Linus Walleij
@ 2012-01-10 10:55               ` Dong Aisheng-B29396
  2012-01-10 13:51               ` Shawn Guo
  1 sibling, 0 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-10 10:55 UTC (permalink / raw)
  To: Linus Walleij, Zhao Richard-B20223
  Cc: Shawn Guo, Richard Zhao, linus.walleij, s.hauer, w.sang,
	rob.herring, linux-kernel, grant.likely, Guo Shawn-R65073,
	kernel, cjb, devicetree-discuss, linux-arm-kernel

> Next from discussions with Stpehen I've sort of figured out that we need a
> config mapping table of sorts and then a means to activate entries of that table
> at runtime. I'm trying to come up with something for this.
> 
Good to hear this.
I did not catch up your steps before, so I did not give much comment on the pinctrl core.
I would try to do it if I can now.

Regards
Dong Aisheng


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-09  6:18                       ` Simon Glass
@ 2012-01-10 11:30                         ` Dong Aisheng-B29396
  2012-01-11 19:19                         ` Stephen Warren
  1 sibling, 0 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-10 11:30 UTC (permalink / raw)
  To: Simon Glass, Shawn Guo
  Cc: Richard Zhao, Stephen Warren, linus.walleij, s.hauer,
	linux-kernel, rob.herring, kernel, cjb, devicetree-discuss,
	linux-arm-kernel, Dong Aisheng

> -----Original Message-----
> From: sjg@google.com [mailto:sjg@google.com] On Behalf Of Simon Glass
> Sent: Monday, January 09, 2012 2:18 PM
> To: Shawn Guo
> Cc: Richard Zhao; Stephen Warren; linus.walleij@stericsson.com;
> s.hauer@pengutronix.de; linux-kernel@vger.kernel.org; rob.herring@calxeda.com;
> kernel@pengutronix.de; cjb@laptop.org; Dong Aisheng-B29396; devicetree-
> discuss@lists.ozlabs.org; linux-arm-kernel@lists.infradead.org; Dong Aisheng
> Subject: Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> Hi,
> 
> [snip lots of discussion]
> 
> Someone copied me on this so I feel I can sneak in with a response. I have read
> this entire thread and implemented Tegra pinmux in U-boot, but not much else on
> the topic so have limited understanding, particular of the kernel pinmux setup,
> unfortunately. Sorry if I have the wrong end of the stick on some of this, but I
> hope my comments are useful.
> 
Thanks a lot for such long comments and share your design. :-)
I mainly comment on pinctrl stuff.

> 1. Symbolic names
> 
> > Stephen said:
> > It's a real pity that dtc doesn't have a way of doing named integer
> > constants, so this could be re-written as e.g.:
> > SoC .dtsi file:
> > /define/ TEGRA_MUX_FUNC_SD4 234
> 
> IMO this is essential for pinmux. Stephen has already done a patch which
> implements this feature. The alternative is bindings with lots of arbitrary
> numbers - lots of errors, lots of confusion, lots of pain. He has asked a few
> times on the device-tree list for this feature to be accepted. I believe it
> should be, and pinmux brough in with that in mind. Turning symbols into numbers
> is the role of the device tree compiler I think.
> 
> If Stephen's proposed grammar needs tweaking that is fine, but I think we are
> pushing the limits of a pure numerical representation here.
> 
> 
> 2. Stephen also said:
> 
> > We also need to consider compatibility and extensibility. A DT binding
> > is an ABI between the kernel and whatever is providing it, and so we
> > need to be able to maintain and extend it in a compatible fashion,
> > just like the user-space syscall ABI. Now it's true that the .dts
> > files are currently part of the kernel source tree and can be rev'd in
> > sync with kernel changes, but that may not always be the case moving forward.
> >
> > In other words, taking a board with an old device tree embedded into
> > Flash and running a new kernel using that device tree should work just
> > like running the original kernel did.
> 
> While this is true we should remember that SOCs will change and evolve, and we
> don't actually need a device tree for a Tegra 2 (say) to be able to boot a Tegra
> 3 kernel. So each time we create a new SOC in a family, we have the opportunity
> to update the fdt, potentially in an incompatible way, since we know that the
> old boot loader and new kernel are incompatible anyway.
> 
> Anyway we are looking at pinmux from a 2012 view of how SOCs do things. We can't
> predict what things will look like in the future. The device tree format is
> great for making things extensible, but there is an efficiency cost also.
> 
> Backwards compatibility can create a lot of problems with newer designs, so I
> don't think we should be slaves to it. We are backwards compatible because it
> aids understanding, is necessary for kernels to run across different boards,
> etc., not just for its own sake. If in the future we decide that the approach
> agreed now no longer servers the purpose and has too much baggage, we can change
> it. Similar things happen in the rest of the kernel.
> 
> Also IMO updating the kernel without the device tree doesn't make a huge amount
> of sense. Why not just update both? Really to me the device tree is almost like
> static data for the kernel. It is a worthy goal to keep it as static as possible,
> but if it changes I don' t think it is the end of civilisation.
> 
> 
> 3. Efficiency
> 
> There has been talk about using strings to link things. IMO this is inefficient
> and slow compared to integers and device trees already have phandles. Some
> platforms will care more than others, but if the reason for using strings is
> that the device tree format does not support symbolic representation of integers,
> then see 1 above.
> 
> 
> 4. Who bears the pain?
> 
> There is a lot of complexity in pinmux - if we continue to split the device tree
> into an SOC file and a board file then we should think about which one bears the
> brunt of the complexity. IMO it should be the SOC file. The SOC file is written
> by very clever engineers working for the SOC vendor. They are motivated to get
> their SOC working properly and for it to be easy for customers to access the
> glorious ground-breaking feature therein. On the other hand, the board file (to
> the extent it is not just copied from the vendor's example) is put together by
> people with little knowledge of the SOC, limited time to do the work and minimal
> interest in the wonders of the device tree structure.
> 
> With this in mind I think the pinmux complexity should mostly be in the SOC file.
> This includes the selection of valid pinmux options.
> After all, despite the many possible ways that functions could be brought out of
> the chip, only a certain few ways typically make sense.
> For example, an SDMMC peripheral needs clock and command pins - unless these are
> connected then nothing with work. Similarly there is no sense in having two
> data[0] pins brought out for the same SDMMC port.
> 
> In fact the SOC vendor generally has a good idea about the different options and
> mostly there are a small number of useful ones. So why don't we just enumerate
> these in the SOC file and let the board select what it wants in a single setting?
> 
Correct for us! :)

> 
> 5. Start at the top: function mux
> 
> I propose adding a new level at the top, a function mux. This basically routes
> functions to one of 2-3 predefined options. So UART1 can come out on 3 different
> sets of pins, SDMMC2 on two sets, etc.
Yes, that's like what current pinctrl subsystem does.
And I agreed with Stephen we could define it in soc dts file.

> These are recommended from the vendor and in common use (e.g. on reference
> designs), so should be easy to use.
> 
Yes, we really do not need to define all possible ones and most of them may not
Useful.

> Below the function mux is the group mux. Here we specify a list of pin groups
> and which function each group is assigned to. Together these
> 2-3 groups join to give us the pins that the function mux needs.
> 
> Below the pin groups are the pins. Some SOCs will have only one pin per group,
> some will have a group mux that really just moves entire functions around.
> 
> IMO the top level belongs with the board file. If the board designer wants to
> depart from common options they can suffer the pain of dropping down to the
> group level.
> 
> So at the board level it would be nice to do something like this:
> 
> sdhci@c8000400 {
> 	funcmux = <&sdmmc3-funcmux 0 0>;  /* funcmux phandle, config option, flags
> */ };
> 
> which means that we want this SDMMC port to use configuration 0 (out of perhaps
> 2-3 recommended options the SOC provides for bringing out this SDMMC function)
> and that there are no special flags required. Or:
> 
> emmc: sdhci@c8000600 {
> 	funcmux = <&sdmmc4-funcmux 1 OPT_SDMMC_8BIT>; }
> 
> which means for this port we want to use configuration 1 with 8-bit wide data.
> 
In my understanding a phandle to the 8bit sdmmc pingroup already works.
Why we really need this flag?

> Something like this is easy for the board files to deal with. It fits with the
> way reference designs are done (selecting from a few options). It allows flags
> to specify different options like 4-bit or 8-bit wide SDMMC which can affect
> what pinmux groups are affected.
> 
> Some boot loaders might even implement things only at the funcmux level, with
> hard-coded configuration of the actual pin groups in static data in their code,
> without reference to the device tree. This might allow them to operate with a
> vastly truncated device tree. They might be very motivated to do this if the
> full device tree consists of 20KB of strings :-)
> 
> 
> 6. Groups
> 
> Already done in the discussion prior to this email:
> 
> uart4func: func@1 {
>        func-name = "uart4";
>        locations = <&bargrp &bazgrp>;
>        mux-value = <6 3>;
> };
> 
> but how above adding a flag cell and putting the locations and values into the
> same property, like:
> 
> uart4func: func@1 {
>        func-name = "uart4";
>        locations = <&bargrp 6 0>
> 		<&bazgrp 3 SOME_FLAG>;
> };
> 
> 
> So the SDMMC example might have three options for SDMMC4: a 4-bit one, and two
> 8-bit ones (changing 'locations' to 'groups'):
> 
> sdmmc4-funcmux : sdmmc4_funcmux@0 {
> 	setting@0 {
> 		config = <0>;
> 		option = <OPT_SDMMC_8BIT>;
> 		groups = <&pingrp-atc FUNC_SDIO4 0> /* clk, cmd, data 1, 3, 5, 7 */
> 			<&pingrp-atd FUNC_SDIO4 0>; /* data 0, 2, 4, 6 */
> 	};
> 
> 	setting@1 {
> 		config = <1>;
> 		option = <0>;
> 		groups = <&pingrp-atb FUNC_SDIO4 0>  /* clock, command */
> 			<&pingrp-gma FUNC_SDIO4 0>; /* data[3:0] */
> 	};
> 
> 	setting@2 {
> 		config = <1>;
> 		option = <OPT_SDMMC_8BIT>;
> 		groups = <&pingrp-atb FUNC_SDIO4 0>  /* clock, command */
> 			<&pingrp-gma FUNC_SDIO4 0> /* data[3:0] */
> 			<&pingrp-gme FUNC_SDIO4 0>; /* data [7:4] */
> 	};
> };
> 
> The 'config' property refers to the second cell of the reference in the funcmux.
> The option property refers to the third cell. Essentially the vendor is
> recommending three possible options for SDMMC4 and the board can choose which
> one it likes.
> 
> The disadvantage is that the last two share the pingrp-atb setting, and the last
> just adds an extra group, but no matter. It is easy to understand.
> 
> A related problem is that the options must each be enumerated. Maybe that
> doesn't matter either for the moment.
> 
> Then for the groups, again already done above, but I am less clear on the exact
> binding that is arrived at above. Something like this?
> 
> pingrp-atb: pingrp_atb@0 {
> 	locations = <&pin-i02 &pin-t07>;
> 	control = <&pinmux 0>;
If it's sub node of pin controller device, we may not need this.

> 	/* 4 options available, numbered 0 to 3 */
> 	functions = <FUNC_IDE   FUNC_NAND   FUNC_GMI   FUNC_SDIO4>;
This does not apply for IMX since the functions here are for each pin rather than
the group.

For IMX, it looks like:
iomuxc@020e0000 {
        reg = <0x020e0000 0x4000>;
        pinmux-groups {
                uart4grp: group@0 {
                        grp-name = "uart4grp";
                        grp-pins = <107 108>;
                        grp-mux = <4 4>;
                };

                sd4grp: group@1 {
                        grp-name = "sd4grp";
                        grp-pins = <170 171 180 181 182 183 184 185 186 187>;
                        grp-mux = <0 0 1 1 1 1 1 1 1 1>;
                }
        }

        pinmux-functions {
                uart4func: func@0 {
                        func-name = "uart4";
                        groups = <&uart4grp ..>;
                }

                sd4func: func@1 {
                        func-name = "sd4";
                        groups = <&sd4grp ..>;
                }
        }
};

And not the pins in 'locations' can support all functions in 'functions' Property. 
It may be less flexible.
For IMX different pins in same group may support different type of functions.

> 	/* do we want to specify what the flags do here? I assume they are
>            globally understood by the pinmux system rather than specific to
> 	   each group */
> };
>
> 
> pingrp-atd: pingrp_atd@0 {
> 	locations = <&pin-h01 &pin-h02 &pin-h03 &pin-h04>;
> 	control = <&pinmux 3>;  /* 3 is the pinmux controller's ID for the atd
> group */
> 	/* 4 options available, numbered 0 to 3 */
> 	functions = <FUNC_IDE   FUNC_NAND   FUNC_GMI   FUNC_SDIO4>;
> };
> 
> 
> (It is probably obvious, but FUNC_SDIO4 is not just the value 3. It might be 21
> - the pinmux code searches the list of 4 options for FUNC_SDIO4. The position it
> finds it in this case is 3, so that is the value written to &pinmux)
> 
> 
> 7. Pins
> 
> At this level I'm not sure if a device tree representation adds much.
> Maybe connect the GPIOs?
> 
I'm not sure if it's suitable since not all the pins of IMX are gpio pins.

> pin-i02: pin_i02@0 {
> 	name = "i02";
> 	gpio = <&gpio 66>;
> };
> 
> pin-t07: pin_t07@0 {
> 	name = "t07";
> 	gpio = <&gpio 167>;
> };
> 
> 
> 8. Flexibility
> 
> Someone asked how to deal with an LCD output with 16 bits each of which can be
> on two pins. Know you of such an SOC? If so, then it is still possible that the
> SOC would provide a few basic 'common' options at the funcmux level. But board
> designers may have to steel themselves and dive into the the pingroup level.
> 
> Where an SOC has no groups but only pins, then perhaps the funcmux can still be
> provided, but uses a 'pins' property instead of 'groups':
> 
> sdmmc4-funcmux : sdmmc4_funcmux@0 {
>         ...
> 	setting@2 {
> 		config = <1>;
> 		option = <OPT_SDMMC_8BIT>;
> 		pins = <&pin-i02 FUNC_SDIO4 0>  /* clock */
> 			<&pin-t07 FUNC_SDIO4 0>  /* command */
> 			<&pin-a00 FUNC_SDIO4 0>  /* data[0] */
> 			<&pin-a01 FUNC_SDIO4 0>  /* data[1] */
> 			<&pin-a02 FUNC_SDIO4 0>  /* data[2] */
> 			<&pin-a03 FUNC_SDIO4 0>;  /* data[3] */
> 			<&pin-a04 FUNC_SDIO4 0>;  /* data[4] */
> 			<&pin-a05 FUNC_SDIO4 0>;  /* data[5] */
> 			<&pin-a06 FUNC_SDIO4 0>;  /* data[6] */
> 			<&pin-a07 FUNC_SDIO4 0>;  /* data[7] */
> 	};
> };
> 
> IMO this sort of thing makes it even more desirable to have a high-level pinmux
> feature in the device tree. Again, the board designer can dive into pins by
> defining his own custom funcmux-level things, so no flexibility is lost.
> 
> Regards,
> Simon



^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-10  8:21                 ` Dong Aisheng-B29396
@ 2012-01-10 13:05                   ` Shawn Guo
  2012-01-11 19:41                     ` Stephen Warren
  2012-01-11 20:17                   ` Stephen Warren
  1 sibling, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-10 13:05 UTC (permalink / raw)
  To: Dong Aisheng-B29396
  Cc: Stephen Warren, Dong Aisheng, linus.walleij, s.hauer,
	linux-kernel, rob.herring, kernel, cjb, devicetree-discuss,
	linux-arm-kernel

On Tue, Jan 10, 2012 at 08:21:05AM +0000, Dong Aisheng-B29396 wrote:
> Here what I wonder is that do we need to allow the platform to use a func-name
> property in their pinmux func node or pinmux group node to specify the name.

I do not see the necessity.

> If it is allowed, then it could be flexible for soc to define their names.
> If not there may be limitations on their node names since we can only get it from
> the node name.

To me, the node name is perfectly fine to be used for that purpose.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2012-01-10 10:43             ` Linus Walleij
  2012-01-10 10:55               ` Dong Aisheng-B29396
@ 2012-01-10 13:51               ` Shawn Guo
  2012-01-11  9:28                 ` Linus Walleij
  1 sibling, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-10 13:51 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Richard Zhao, Richard Zhao, linus.walleij, s.hauer, w.sang,
	rob.herring, linux-kernel, grant.likely, shawn.guo, kernel, cjb,
	Dong Aisheng, devicetree-discuss, linux-arm-kernel

On Tue, Jan 10, 2012 at 11:43:28AM +0100, Linus Walleij wrote:
> On Tue, Jan 10, 2012 at 9:38 AM, Richard Zhao
> <richard.zhao@freescale.com> wrote:
> > On Mon, Jan 09, 2012 at 02:32:12PM +0800, Shawn Guo wrote:
> >> As I was educated by Linus.W, we can not drink ocean and we need to
> >> split big chunk of work into pieces and achieve it step by step.
> > Sure, we can not drink out the ocean :). But if people can not use it
> > in real case, how do we verify the driver? How do we know the driver
> > goes in the right way?
> 
> If you prefer to do a big upfront design of the entire driver then please
> by all means do that.
> 
> What we need to know right now is what you need from the pin
> controller core to do that. We have a (custom) pinconf API now,
> does it fit the bill?
> 
Hmm, I do not think it fits right away, as I do not think it's sensible
to have pinctrl client drivers call pin_config_set() directly.

> I have spent some time on generic pin config, it was not much
> commented so if it helps you please ACK the patches.
> 
Since the ARM community is the one who is most interested in pinctrl
subsystem so far, I guess copying LAKML will help collect more comments
and various tags.  (For example, I'm interested in pinctrl, but I do
not track LKML as close as I do for LAKML).

> Next from discussions with Stpehen I've sort of figured out that
> we need a config mapping table of sorts and then a means to activate
> entries of that table at runtime. I'm trying to come up with something
> for this.
> 
That's something we are waiting for pinconf being usable for imx.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver
  2012-01-10 13:51               ` Shawn Guo
@ 2012-01-11  9:28                 ` Linus Walleij
  0 siblings, 0 replies; 98+ messages in thread
From: Linus Walleij @ 2012-01-11  9:28 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Richard Zhao, Richard Zhao, linus.walleij, s.hauer, w.sang,
	rob.herring, linux-kernel, grant.likely, shawn.guo, kernel, cjb,
	Dong Aisheng, devicetree-discuss, linux-arm-kernel

On Tue, Jan 10, 2012 at 2:51 PM, Shawn Guo <shawn.guo@linaro.org> wrote:
> On Tue, Jan 10, 2012 at 11:43:28AM +0100, Linus Walleij wrote:
>> What we need to know right now is what you need from the pin
>> controller core to do that. We have a (custom) pinconf API now,
>> does it fit the bill?
>>
> Hmm, I do not think it fits right away, as I do not think it's sensible
> to have pinctrl client drivers call pin_config_set() directly.

OK that's more or less what Stephen said too so I'm cooking a
config table ala pinmux with string identifiers.

>> I have spent some time on generic pin config, it was not much
>> commented so if it helps you please ACK the patches.
>>
> Since the ARM community is the one who is most interested in pinctrl
> subsystem so far, I guess copying LAKML will help collect more comments
> and various tags.  (For example, I'm interested in pinctrl, but I do
> not track LKML as close as I do for LAKML).

True. I'll fix that.

>> Next from discussions with Stpehen I've sort of figured out that
>> we need a config mapping table of sorts and then a means to activate
>> entries of that table at runtime. I'm trying to come up with something
>> for this.
>>
> That's something we are waiting for pinconf being usable for imx.

I'll fix something, please review when it appears!

Thanks,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-07 13:54                 ` Shawn Guo
  2012-01-08 12:51                   ` Richard Zhao
@ 2012-01-11 18:17                   ` Stephen Warren
  2012-01-12  3:39                     ` Shawn Guo
  1 sibling, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-11 18:17 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org),
	Richard Zhao

Shawn Guo wrote at Saturday, January 07, 2012 6:55 AM:
> On Fri, Jan 06, 2012 at 10:03:07AM -0800, Stephen Warren wrote:
...
> > So, this does appear to be conflating the two things: The definition of
> > what pins are in a pingroup, and the mux function for a particular
> > setting of that pingroup. I think you need separate nodes for this.
> >
> At least for imx, we do not have mux function setting for pingroup.
> Instead, it only applies to individual pin.

Ah. There's a slight disconnect between my understanding of your HW and
how it really is then! I saw pingroup definitions on Dong's patch, and
hence I assume that your HW was like Tegra, namely that pins were grouped
together for mux control, i.e. muxing isn't a per-pin option. Given that,
some of my responses may not entirely have made sense for your HW...

Just to confirm my understanding:

IMX:

* HW has a set of pins.
* Each pin has a register/field that defines its mux function.

And contrast this to Tegra for reference:

* HW has a set of pins.
* Each pin is a member of a single mux group..
* Each mux group has a register/field that defines its mux function.
  This affects all the pins in the group at once, which are all set to
  the same logical function (e.g. UART). For that logical function, each
  pin has some specific signal muxed onto it. For example, a pin group
  "X" may have pins P1 and P2, and when function "UART" is muxed onto "X",
  P1 will be UART.RX and P2 UART.TX.
* Note that there also exist other properties that can be configured for
  each of these mux groups (e.g. pullup/down, tristate). There also exist
  other types of groups that don't align with the mux groups, and each of
  those allows various other properties (e.g. drive strength) to be
  configured. However, this bullet isn't relevant for the pin mux
  discussion, just pin config.

So, my position is that:

* Something (either the pinctrl driver, or the SoC .dtsi file) should
enumerate all available muxable entities that exist in the SoC (pins for
IMX, groups for Tegra).

* Something (either the pinctrl driver, or the SoC .dtsi file) should
enumerate all the available functions that can be assigned to a muxable
entity.

* The enumerations above should be purely at the level the HW exposes,
i.e. if a UART uses 4 signals (RX, TX, CTS, RTS), and the SoC configures
muxing at a per-pin level, and 6 pins exist which can have various UART
signals mux'd on to them, there should be a "muxable entity" enumeration
for each of the 6 pins, not an enumeration for each possible combination
of assignments of signals to pins, since in general that number could be
extremely large as Richard Zao points out in his email that was sent right
after yours.

* pinmux properties in device drivers should list the muxable entities
that they use, and the mux function for each of them.

This is the minimal data model to represent the pure HW functionality,
and is what the pinctrl subsystem uses too.

> > Without separate nodes, there will eventually be a lot of duplication.
> > A made-up example of the same uart4grp allowing either of two functions
> > uart3, uart4 to be muxed out onto it:
> >
> > aips-bus@02000000 { /* AIPS1 */
> >     iomuxc@020e0000 {
> >             pinctrl_uart4_3: uart4@option_3 {
> >                     func-name = "uart3";
> >                     grp-name = "uart4grp";
>
> With phandle in dts reflecting the mapping, neither func-name nor
> grp-name should be needed, and both can just be dropped, IMO.

I'd now argue that these nodes shouldn't even exist in the device tree;
rather the "combination" of which muxable entities are used and their
used mux function should be something in the board .dts files, since its
board-specific.

> >                     grp-pins = <107 108>;
> >                     num-pins = <2>;
> >                     grp-mux = <3 3>;
> >                     num-mux = <2>;
> >             };
> >             pinctrl_uart4_4: uart4@option_4 {
> >                     func-name = "uart4";
> >                     grp-name = "uart4grp";
> >                     grp-pins = <107 108>;
> >                     num-pins = <2>;
> >                     grp-mux = <3 3>;
> >                     num-mux = <2>;
> >             };
> >     }
> > };
> >
> > Now I understand that initially you aren't going to type out the complete
> > list of every available option into imx6q.dtsi because it's probably huge,
> > but the binding does need to allow you to do so without duplicating a lot
> > of data, because eventually you'll get boards that use a larger and larger
> > subset of all the options, so the number you need to represent at once in
> > imx6q.dtsi will grow.
> >
> > So I think you need to model the IMX pinmux controller's bindings more on
> > how the pinctrl subsystem represents objects; separate definitions of pins,
> > groups of pins, functions, and board settings. Something more like:
> >
> > imx6q.dtsi:
> >
> > aips-bus@02000000 { /* AIPS1 */
> >     iomuxc@020e0000 {
> >             /* FIXME: Perhaps need pin nodes here to name them too */
>
> No, it's been listed in imx pinctrl driver.

OK, that's fine too. I just recalled there being such a node in one of
Dong's patches.

> >             /* A node per group of pins. Each lists the group name, and
> >              * the list of pins in the group */
> >             foogrp: group@100 {
> >                     grp-name = "foogrp";
> >                     grp-pins = <100 101>;
> >             };
> >             bargrp: group@102 {
> >                     grp-name = "bargrp";
> >                     grp-pins = <102 103>;
> >             };
> >             bazgrp: group@104 {
> >                     grp-name = "bargrp";
> >                     grp-pins = <104 105>;
> >             };
>
> I agree that we should define pingroups in <soc>.dtsi, but the mux
> setting needs to be under the pingroup node too.  See comment below ...

As I mention above, I'd assert we shouldn't have any group nodes in
the .dtsi file for SoCs that don't mux pins in groups at the raw HW level.

> >             /* A node per function that can be muxed onto pin groups,
> >              * each listing the function name, the set of groups it can
> >              * be muxed onto, and the mux selector value to program into
> >              * the groups' mux control register to select it */
> >             uart3func: func@0 {
> >                     func-name = "uart3";
> >                     /* Length of locations and mux-value must match */
> >                     locations = <&foogrp &bargrp>;
> >                     mux-value = <0 4>;
>
> This can be easily broken for imx.  As the mux setting applies to
> individual pin rather than pingroup, it's very valid for foogrp to
> have pin 100 muxed on mode 0 while pin 101 on mode 1.  That said,
> it's not necessarily true that we always have all the pins in
> particular pingroup muxed on the same setting for given function.

OK, that node doesn't make sense for IMX, since muxing is at a per-pin
level. If Tegra were to enumerate the available functions in the .dtsi
file instead of in the pinctrl driver, this node would make sense for
Tegra since it does mux on a per-group basis.

> >             };
> >             uart4func: func@1 {
> >                     func-name = "uart4";
> >                     locations = <&bargrp &bazgrp>;
> >                     mux-value = <6 3>;
> >             };
>
> I prefer to have function node defined in <board>.dtsi, since it's
> all about defining phandle to the correct pingroup, which should be
> decided by board design.

Just to explicitly re-iterate, if there are no groups in HW, I don't
think the .dtsi file should attempt to represent any groups.

(I think I'll talk a little more about this in a response to Richard
Zhao's email later)

> >     }
> > };
> >
> > Or, instead of separate locations and mux-value properties with matching
> > lengths, perhaps a node for each location:
> >
> >             uart3func: func@0 {
> >                     func-name = "uart3";
> >                     location@0 {
> >                             location = <&foogrp>;
> >                             mux-value = <0>;
> >                     };
> >                     location@1 {
> >                             location = <&bargrp>;
> >                             mux-value = <4>;
> >                     };
> >             };
> >
> > That's more long-winded, but might be more easily extensible if we need
> > to add more properties later.
> >
> > Now in the board's .dts file, you need to specify for each device the
> > list of pinmux groups the device needs to use, and the function to
> > select for each group. Perhaps something like:
> >
> > board.dts:
> >
> > usdhc@0219c000 { /* uSDHC4 */
> >         fsl,card-wired;
> >         status = "okay";
> >         pinmux = <&foogrp &uart3func &bazgrp &uart4func>;
> > };
> >
> > I haven't convinced myself that's actually a good binding, but I think
> > it does represent the data required for muxing. Some potential issues
> > as before:
> >
> > * Do we need to add flags to each entry in the list; GPIO/interrupt do?
>
> What's that for right now?  I guess we can add it later when we see
> the need.

I guess as long as we have a #pinmux-cells in the pinmux controller's
node, we could write the driver to accept 2 now (phandle of muxable
entity and mux function value) but also accept 3 in the future (adding
a flags field), and hence have an upgrade path. So, yes, flags aren't
needed now.

> > * Should "pinmux" be a node, and the configuration of each group be a
> > separate sub-node, so we can add more properties to each "table" entry
> > in the future, e.g. pin config parameters?
>
> I do not think it's necessary. 'pinctrl' phandle works perfectly fine
> to me at least for now.  How pinconf support should be added into
> pinctrl subsystem is still up in the air to me.

Well, I think we definitely need to have a rough idea how to support pin
config in the future; representing the current pin mux as a node rather
than a property seems like a pretty easy way to allow this future
flexibility.

> > * For Tegra, I elected to put the definitions of pins, groups, and
> > functions into the driver rather than in the device tree.
>
> IMO, we do not want to do this for imx, as I'm scared of the size
> of Tegra pinctrl patches.  If we go this way for imx, we will have
> even bigger patches.

Now you're confusing me! In one of your answers above, you said:

  > >           /* FIXME: Perhaps need pin nodes here to name them too */
  > No, it's been listed in imx pinctrl driver.

So it sounds like the raw HW capabilities /are/ being enumerated by the
pinctrl driver and not device tree, which is exactly what I was saying
I'd chosen for Tegra. Well, with the exception that IMX's pinctrl driver
doesn't define groups, since the HW doesn't mux in groups.

Perhaps you're talking about enumerating groups of pins, which don't
really exist in HW. I wasn't.

> > This avoids
> > parsing a heck of a lot of data from device tree. That means there isn't
> > any per-function node that can be referred to by phandle. Does it make
> > sense to refer to groups and functions by string name or integer ID
> > instead of phandle? Perhaps:
> >
> > usdhc@0219c000 { /* uSDHC4 */
> >     fsl,card-wired;
> >     status = "okay";
> >     pinmux = {
> >             group@0 {
> >                     group = "foo";
> >                     function = "uart3";
> >                     /* You could add pin config options here too */
> >             };
> >             group@1 {
> >                     group = "baz";
> >                     function = "uart4";
> >             };
> >     };
> > };
> >
> > I guess referring to things by name isn't that idiomatic for device tree.
> > Using integers here would be fine too, so long as dtc gets support for
> > named constants:
> >
> > imx6q.dtsi:
> >
> > /define/ IMX_PINGRP_FOO 0
> > /define/ IMX_PINGRP_BAR 1
> > /define/ IMX_PINGRP_BAZ 2
> > /define/ IMX_PINFUNC_UART3 0
> > /define/ IMX_PINFUNC_UART4 1
> > ...
> >
> > board .dts:
> >
> > usdhc@0219c000 { /* uSDHC4 */
> >     fsl,card-wired;
> >     status = "okay";
> >     pinmux = {
> >             group@0 {
> >                     group = <IMX_PINGRP_FOO>;
> >                     function = <IMX_PINFUNC_UART3>;
> >                     /* You could add pin config options here too */
> >             };
> >             group@1 {
> >                     group = <IMX_PINGRP_BAZ>;
> >                     function = <IMX_PINFUNC_UART4>;
> >             };
> >     };
> > };

So given that IMX muxes per pin not per group of pins, that "group"
property above should really be named "pin", and the IMX_PINGRP_* values
renamed IMX_PIN_* instead.

In general, it'd be nice to come up with a binding for the users of
pinmux (i.e. the device nodes like usdhc above) that allowed them to
refer to what I've been calling "muxable entity". perhaps instead of
"pin" or "group" the property should be called "mux-point", and it's
up to the pinctrl driver to interpret that as a pin or group ID based
on what its muxable entities are.

> Doing this does not change the fact that this is bound with Linux
> driver details.  That said, if the indexing of either pingrp array
> or pinfunc array changes in the driver, the binding is broken.

I don't agree here.

Having a driver state that it wants "pin P" or "group G" to be programmed
to "mux function F" is very purely HW oriented.

The fact this so closely aligns with the data model that the pinctrl
subsystem uses is simply because I pushed for the same pure HW oriented
data model in the pinctrl subsystem; both models were derived from how
the HW works, rather than the binding being derived from the driver.

Equally, the binding for the individual pin mux HW will define what the
integer values for pin/group/function are. In practice, we will choose
the values that the Linux pinctrl driver uses to remove the need for
conversion when parsing the device tree. However, we should be very aware
that the binding is what specifies the values, not the driver, so if the
driver changes its internal representation, it must add conversion code
when parsing the device tree, not require the device tree to change.

That said, I don't see why the pinctrl driver would change its pin, group,
or mux function numbering scheme for a given SoC; the HW is fixed, right?
(Well, for shipping HW, and designs-in-progress can presumably handle some
churn in the device tree binding specification during RTL development
or layout)

If there's a bug in the list of pins/groups/functions, that's probably
also a bug in the device tree binding too, not an arbitrary change, so
it seems fine to fix that, hopefully in as backwards-compatible way as
possible though, i.e. adding missing entries to the end of the list so
there's no renumbering etc. this is unlikely to happen late in the game.

--
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-08 12:51                   ` Richard Zhao
  2012-01-09  1:56                     ` Shawn Guo
@ 2012-01-11 18:28                     ` Stephen Warren
  1 sibling, 0 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-11 18:28 UTC (permalink / raw)
  To: Richard Zhao, Shawn Guo
  Cc: linus.walleij, s.hauer, linux-kernel, rob.herring, kernel,
	Simon Glass (sjg@chromium.org),
	cjb, Dong Aisheng-B29396, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

Richard Zhao wrote at Sunday, January 08, 2012 5:52 AM:
> On Sat, Jan 07, 2012 at 09:54:48PM +0800, Shawn Guo wrote:
> > On Fri, Jan 06, 2012 at 10:03:07AM -0800, Stephen Warren wrote:
...
> > > Without separate nodes, there will eventually be a lot of duplication.
> > > A made-up example of the same uart4grp allowing either of two functions
> > > uart3, uart4 to be muxed out onto it:
> > >
> > > aips-bus@02000000 { /* AIPS1 */
> > > 	iomuxc@020e0000 {
> > > 		pinctrl_uart4_3: uart4@option_3 {
> > > 			func-name = "uart3";
> > > 			grp-name = "uart4grp";
> > > 			grp-pins = <107 108>;
> > > 			num-pins = <2>;
> > > 			grp-mux = <3 3>;
> > > 			num-mux = <2>;
> > > 		};
> > > 		pinctrl_uart4_4: uart4@option_4 {
> > > 			func-name = "uart4";
> > > 			grp-name = "uart4grp";
> > > 			grp-pins = <107 108>;
> > > 			num-pins = <2>;
> > > 			grp-mux = <3 3>;
> > > 			num-mux = <2>;
> > > 		};
> > > 	}
> > > };
> > >
> > > Now I understand that initially you aren't going to type out the complete
> > > list of every available option into imx6q.dtsi because it's probably huge,
> > > but the binding does need to allow you to do so without duplicating a lot
> > > of data, because eventually you'll get boards that use a larger and larger
> > > subset of all the options, so the number you need to represent at once in
> > > imx6q.dtsi will grow.
>
> If we don't want to lose flexibity, the pin group number will be huge
> than you think. For example, 16bit display interface, has two alternatives
> for every pin. The group number will be 2^16.

I originally misunderstood IMX HW; I though the HW muxed at a group-of-
pins level (as Tegra does), but actually it's muxing at a per-pin level,
hence some of what I wrote may have been confusing to people familiar
with how IMX HW really works.

So yes, I definitely agree that representing all possible mux combinations
(combinations of pins in use and the mux function selected for them) could
be extremely large and we don't want to enumerate /that/ list anywhere; in
.dts files or in the pinctrl driver.

So, as a result of that, and as I mentioned in my immediately previous
email, I don't think those two nodes "uart4@option_3", "uart4@option_4"
should be in the SoC .dtsi file.

Later you wrote:

> group and function are one-to-one mapped for imx. So if you put function
> in board dts, why not put pin group there too?

I agree, I think: Everything that defines the board-specific usage of
the pinmux should be part of the board's .dtsi file, not the SoC's .dtsi
file.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-09  1:56                     ` Shawn Guo
  2012-01-09  6:18                       ` Simon Glass
@ 2012-01-11 18:37                       ` Stephen Warren
  2012-01-11 23:56                         ` Shawn Guo
  1 sibling, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-11 18:37 UTC (permalink / raw)
  To: Shawn Guo, Richard Zhao
  Cc: linus.walleij, s.hauer, linux-kernel, rob.herring, kernel,
	Simon Glass (sjg@chromium.org),
	cjb, Dong Aisheng-B29396, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

Shawn Guo wrote at Sunday, January 08, 2012 6:56 PM:
> On Sun, Jan 08, 2012 at 08:51:59PM +0800, Richard Zhao wrote:
> ...
> > > > So, this does appear to be conflating the two things: The definition of
> > > > what pins are in a pingroup, and the mux function for a particular
> > > > setting of that pingroup. I think you need separate nodes for this.
> > > >
> > > At least for imx, we do not have mux function setting for pingroup.
> > > Instead, it only applies to individual pin.
> > I think it depends on function definition of pinmux driver. For the
> > imx example patch, it's one-to-one.
> 
> It should depend on particular imx soc pinmux design rather than
> pinmux driver.  If it's always one-to-one case, we do not need
> pinmux at all.  Aisheng's patch just did not enumerate all the groups
> for given function.  Instead, it puts a couple simple examples there
> for demonstration.
> 
> ...
> 
> > > > 		uart4func: func@1 {
> > > > 			func-name = "uart4";
> > > > 			locations = <&bargrp &bazgrp>;
> > > > 			mux-value = <6 3>;
> > > > 		};
> > >
> > > I prefer to have function node defined in <board>.dtsi, since it's
> > > all about defining phandle to the correct pingroup, which should be
> > > decided by board design.
> > group and function are one-to-one mapped for imx.
> 
> Again, it's not the case.
> 
> > So if you put function
> > in board dts, why not put pin group there too?
> 
> If we put pingroup data in <board>.dts, the data will be likely get
> duplicated a lot in different board dts files.  For example, if
> imx6q-sabrelite chooses the same pingroup for usdhc3 and usdhc4 as
> imx6q-arm2, the pingroup data will be duplicated between imx6q-arm2.dts
> and imx6q-sabrelite.dts.
> 
> On the contrary, putting pingroup data in <soc>.dtsi and having function
> node in <board>.dts with phandle pointing to the correct pingroup will
> help avoid such data duplication.

Oh, when I wrote in my first mail today that I'd expand on one of my
points when responding to Richard Zhao's email, I actually meant when
responding to this email. Sorry for the confusion!

So, I don't agree with putting the "combinations" in the SoC .dtsi file,
since that could grow it into a huge file that contains a lot of nodes
that are used on some board somewhere, but typically not the "current"
board that's including it.

However, I do see that there are probably lots of common combinations
that get re-used across multiple boards, and you might want a common
place to put those definitions so they don't need to be cut/paste
everywhere.

So, why not create specific include files (.dtsi files) for each of those
combinations? Each include could define one particular common combination
of pin mux usage, or perhaps even a set of them if they're commonly used
together. Each board file would include the SoC .dtsi file, the relevant
set of "pinmux config" .dtsi files, and then include anything custom to
that board. Remember, that include files simply get merged into the device
tree, so you can easily add based definitions (like) regs for e.g. an
SDHCI controller in a SoC .dtsi file, the pinmux properties in a .dtsi
file specific to SHDCI controller 3, and then e.g. CD/WP/power GPIOs in
the final board .dts file.

Following this model, we can initially just put the pinmux config into
each board file, then factor it out into new .dtsi files as/when we see
duplication. We get to start off simple, then clean up by refactoring as
we go.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-09  6:18                       ` Simon Glass
  2012-01-10 11:30                         ` Dong Aisheng-B29396
@ 2012-01-11 19:19                         ` Stephen Warren
  1 sibling, 0 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-11 19:19 UTC (permalink / raw)
  To: Simon Glass, Shawn Guo
  Cc: Richard Zhao, linus.walleij, s.hauer, linux-kernel, rob.herring,
	kernel, cjb, Dong Aisheng-B29396, devicetree-discuss,
	linux-arm-kernel, Dong Aisheng

Simon Glass wrote at Sunday, January 08, 2012 11:18 PM:
...
> 2. Stephen also said:
> 
> > We also need to consider compatibility and extensibility. A DT binding
> > is an ABI between the kernel and whatever is providing it, and so we
> > need to be able to maintain and extend it in a compatible fashion, just
> > like the user-space syscall ABI. Now it's true that the .dts files are
> > currently part of the kernel source tree and can be rev'd in sync with
> > kernel changes, but that may not always be the case moving forward.
> >
> > In other words, taking a board with an old device tree embedded into
> > Flash and running a new kernel using that device tree should work just
> > like running the original kernel did.
> 
> While this is true we should remember that SOCs will change and
> evolve, and we don't actually need a device tree for a Tegra 2 (say)
> to be able to boot a Tegra 3 kernel. So each time we create a new SOC
> in a family, we have the opportunity to update the fdt, potentially in
> an incompatible way, since we know that the old boot loader and new
> kernel are incompatible anyway.

Depending on the context, I both agree and disagree.

Take some random HW module in the SoC. If the HW changes enough to
warrant a new binding between SoC v1 and SoC v2, we can certainly revise
the binding in a non-compatible way, and hence not be shackled by
compatibility issues forever.

However, where SoC v2's HW is the same as or very similar to SoC v1's
hardware, we don't want to arbitrarily introduce a new binding if we
can instead keep it identical, or extend it in a compatible fashion.
The more we keep binding definitions stable, the easier it'll be for
people to create .dts files for the new SoC version. They can simply
copy/rename the existing SoC .dtsi file, not need to learn too much
new stuff, etc.

Finally, in the context of pinmux, we're talking about at least some
kind of common infra-structure for pinmux bindings, just like there's
a common infra-structure for registers, interrupts, GPIOs, etc. Such a
binding will hopefully apply across all SoCs, all boards, etc. Hence,
we have to be much more careful about future extensibility, and having
the binding be general enough for future scenarios.

...
> Also IMO updating the kernel without the device tree doesn't make a
> huge amount of sense. Why not just update both? Really to me the
> device tree is almost like static data for the kernel. It is a worthy
> goal to keep it as static as possible, but if it changes I don' t
> think it is the end of civilisation.

One of the goals of device tree is to have the kernel and DT file be
independent. I know this has been discussed a bit before, but can't
find it right now; previous discussions probably explain things better
than I will!

I think the main use-case here is:
* Vendor ships a system the boots with DT
* User wants to update to a newer kernel, so they build it and install
  it.
* The kernel doesn't contain the .dts file for this random board the
  mainline community hasn't even heard of, or the vendor placed the
  DT onto the device somewhere that's difficult to update. So, the user
  needs to use the old DT with the new kernel.

> 4. Who bears the pain?
> 
> There is a lot of complexity in pinmux - if we continue to split the
> device tree into an SOC file and a board file then we should think
> about which one bears the brunt of the complexity. IMO it should be
> the SOC file. The SOC file is written by very clever engineers working
> for the SOC vendor. They are motivated to get their SOC working
> properly and for it to be easy for customers to access the glorious
> ground-breaking feature therein. On the other hand, the board file (to
> the extent it is not just copied from the vendor's example) is put
> together by people with little knowledge of the SOC, limited time to
> do the work and minimal interest in the wonders of the device tree
> structure.

Yes, the board file should be as simple as is reasonable.

> With this in mind I think the pinmux complexity should mostly be in
> the SOC file. This includes the selection of valid pinmux options.

Well, either the pinctrl driver /or/ the SoC .dtsi file can enumerate
the legal set of mux options. So, I think the SoC .dtsi file could end
up without having any pinmux data if the driver contains the static
tables.

> After all, despite the many possible ways that functions could be
> brought out of the chip, only a certain few ways typically make sense.
> For example, an SDMMC peripheral needs clock and command pins - unless
> these are connected then nothing with work. Similarly there is no
> sense in having two data[0] pins brought out for the same SDMMC port.
> 
> In fact the SOC vendor generally has a good idea about the different
> options and mostly there are a small number of useful ones. So why
> don't we just enumerate these in the SOC file and let the board select
> what it wants in a single setting?

Yes, but the set of legal *combinations* of which function is selected
for each pin/group is much much larger than the individual lists of just
pins/groups and functions. Representing the entire list of combinations
often isn't practical. Instead, see my earlier response where I propose:

* All board-specific configuration go into the board .dts file.
* Where we observe there is commonality between boards, we create another
  .dtsi file just for that common part. That allows sharing between board
  files, solving the duplication problem, yet doesn't require the SoC.dtsi
  file to define a large number of combinations, most of which won't be
  useful for an individual board. The SoC vendor could supply the set of
  these pinmux .dtsi files if they want.

That said, this seems to add more complexity to me; you have to think a
little about code-sharing, search through all the definitions of the
available options to find the correct pinmux .dtsi file to use etc. I
suspect a large number of FAEs are going to find it a lot easier to just
explicitly enumerate their required pinmux settings in their one board
file and ignore any other board files. But, we can certainly do better
for boards that go upstream, and share as much as we can in the pinmux
.dtsi files.

> 5. Start at the top: function mux
> 
> I propose adding a new level at the top, a function mux. This
> basically routes functions to one of 2-3 predefined options. So UART1

As I mentioned above, the set of "predefined options" is large, and not
something we want to enumerate. Requiring enumeration of that set as a
base part of the binding is a non-starter in my opinion (and others have
mentioned this in earlier emails in this thread, and previous discussions
of the pinctrl subsystem).

> can come out on 3 different sets of pins, SDMMC2 on two sets, etc.
> These are recommended from the vendor and in common use (e.g. on
> reference designs), so should be easy to use.
> 
> Below the function mux is the group mux. Here we specify a list of pin
> groups and which function each group is assigned to. Together these
> 2-3 groups join to give us the pins that the function mux needs.

That model seems very different to how the HW works. I think the device
tree should represent the HW as closely as possible. Defining which pins
exist, and which mux option to select on a per-pin basis (or per-group
basis where the HW works that way) seems simplest and most direct, and
most familiar to board engineers and readers of the SoC documentation,
which doesn't enumerate all these "possible combinations", but instead
typically talks about which pins/groups exist, and which functions are
legal on those pins/groups.

> Below the pin groups are the pins. Some SOCs will have only one pin
> per group, some will have a group mux that really just moves entire
> functions around.
> 
> IMO the top level belongs with the board file. If the board designer
> wants to depart from common options they can suffer the pain of
> dropping down to the group level.
> 
> So at the board level it would be nice to do something like this:
> 
> sdhci@c8000400 {
> 	funcmux = <&sdmmc3-funcmux 0 0>;  /* funcmux phandle, config option, flags */
> };
> 
> which means that we want this SDMMC port to use configuration 0 (out
> of perhaps 2-3 recommended options the SOC provides for bringing out
> this SDMMC function) and that there are no special flags required. Or:
> 
> emmc: sdhci@c8000600 {
> 	funcmux = <&sdmmc4-funcmux 1 OPT_SDMMC_8BIT>;
> }
> 
> which means for this port we want to use configuration 1 with 8-bit wide data.

As I mentioned in my response to the U-Boot funcmux discussions to add
this "option" flag, it doesn't really make sense w.r.t to how the HW is
works.

If the HW has an 8-bit bus, you set up the pinmux for that 8-bit bus.

If the HW has a 4-bit bus, you set up the pinmux for that 4-bit bus.

There isn't a case where you select an "8 bit SD bus" option, for a board
where you want to use it in 4-bit mode; you'd just select a 4-bit config
instead.

Note that run-time bus width switching is orthogonal to this and subject
to negotiation between the controller and the SD card; the pinmux should
be setting up the HW for the actual bus width that's present on the board
in all cases.

> Something like this is easy for the board files to deal with. It fits
> with the way reference designs are done (selecting from a few
> options). It allows flags to specify different options like 4-bit or
> 8-bit wide SDMMC which can affect what pinmux groups are affected.

I disagree about reference designs or ease of use here. AFAIK, none of
the Tegra documentation at least talks about any set of supported sets
of pin mux usage for a given controller, but simply documents the set
of pins, groups, and legal functions for each pin/group. The documentation
I've seen for other chips is the same way. And as I mention above, I
believe FAEs and OEMs will find it easier to simply enumerate their
complete pinmux layout at a per-pin/group level, to match the docs.

> Some boot loaders might even implement things only at the funcmux
> level, with hard-coded configuration of the actual pin groups in
> static data in their code, without reference to the device tree. This
> might allow them to operate with a vastly truncated device tree. They
> might be very motivated to do this if the full device tree consists of
> 20KB of strings :-)

Uggh.

We shouldn't burden the device tree binding due to internal implementation
details of any particular software.

That said, yes, we really should avoid strings for pin/group/function/...
names in the DT if at all possible.

If U-Boot isn't going to use the device tree for some random subset of
its configuration, I'm unsure why it'd use DT at all; why not do everything
through board files?

> ...

I didn't respond to individual points in the rest of your email, since
I've basically already answered them in this and immediately previous
emails.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-10 13:05                   ` Shawn Guo
@ 2012-01-11 19:41                     ` Stephen Warren
  2012-01-11 23:01                       ` Shawn Guo
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-11 19:41 UTC (permalink / raw)
  To: Shawn Guo, Dong Aisheng-B29396
  Cc: Dong Aisheng, linus.walleij, s.hauer, linux-kernel, rob.herring,
	kernel, cjb, devicetree-discuss, linux-arm-kernel

Shawn Guo wrote at Tuesday, January 10, 2012 6:05 AM:
> On Tue, Jan 10, 2012 at 08:21:05AM +0000, Dong Aisheng-B29396 wrote:
> > Here what I wonder is that do we need to allow the platform to use a func-name
> > property in their pinmux func node or pinmux group node to specify the name.
> 
> I do not see the necessity.
> 
> > If it is allowed, then it could be flexible for soc to define their names.
> > If not there may be limitations on their node names since we can only get it from
> > the node name.
> 
> To me, the node name is perfectly fine to be used for that purpose.

I'd prefer if we could use integers over strings if at all possible, but
that does have a dependency on dtc getting a syntax to define named
constants, or the kernel pre-processing the .dts files before passing
them to dtc.

But if we have to use strings, I will point out that the pin names I
chose for Tegra may not be suitable as DT node names; I don't /think/
the DT node names can contain spaces, but I chose to name the Tegra
pinctrl pins after both their pin name and GPIO name so that it's
easier to correlate the two:

        PINCTRL_PIN(TEGRA_PIN_SDIO3_CLK_PA6, "SDIO3_CLK PA6"),

Now, I could change that, but I'd prefer not to.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-10  8:21                 ` Dong Aisheng-B29396
  2012-01-10 13:05                   ` Shawn Guo
@ 2012-01-11 20:17                   ` Stephen Warren
  2012-01-11 23:21                     ` Shawn Guo
                                       ` (2 more replies)
  1 sibling, 3 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-11 20:17 UTC (permalink / raw)
  To: Dong Aisheng-B29396, Dong Aisheng
  Cc: linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org)

Dong Aisheng wrote at Tuesday, January 10, 2012 1:21 AM:
> Stephen Warren wrote at Saturday, January 07, 2012 2:03 AM:
...
> > Now in the board's .dts file, you need to specify for each device the list of
> > pinmux groups the device needs to use, and the function to select for each group.
> > Perhaps something like:
> >
> > board.dts:
> >
> > usdhc@0219c000 { /* uSDHC4 */
> >         fsl,card-wired;
> >         status = "okay";
> >         pinmux = <&foogrp &uart3func &bazgrp &uart4func>; };
> >
> > I haven't convinced myself that's actually a good binding, but I think it does
> > represent the data required for muxing. Some potential issues as before:
>
> Here is what we should discuss exactly.
> Since 'pinmux' phandle will be parsed in pinctrl core, we should try to find and
> define a common and standardized pinmux property for all platforms.

Yes.

...
> To keep consistency as the currently design of pinctrl subsystem and also meet
> the dt design philosophy, we still do not introduce a pinmux map in dt.
> Instead, we choose to scan all the device node with a 'pinmux' phandle to construct
> a pinmux map table before register the pin controller device(here we may also scan
> the hog_on_boot node) and I guess it's easy to do that.
...
> (Without scan the device node to construct the pinmux map table, we can only get the map
> Information when we run the pinmux_get.
> See: https://lkml.org/lkml/2012/1/5/153
> So no pinmux map table exists and we surely do not want to see that the sysfs exporting
> pinmux map information works in dt but unwork in non-dt)

Hmmm. I'm not sure that the pinctrl code should actively scan all nodes
in the device tree for pin mux properties. That seems a little invasive;
how does pinctrl know which nodes it really should be looking at, and
which nodes are random internal parts of some device's custom binding?

Personally, I think I'd be OK with the sysfs pinctrl map file only
containing the map entries for devices that had used the pinctrl API,
and hence only parsing the pinmux properties in pinmux_get().

However, we could perhaps do better by registering a bus notifier, and
pro-actively parsing the top-level DT node (if there is one) for every
device that is created. That way, the mapping would be parsed as soon
as the device was created (or perhaps after probe?). The only case this
might not cover is DT nodes for which the kernel doesn't actually have
a driver, and hence no device is created.

> BTW it seems you want to support multi pin groups(foogrp and bazgrp) for one device,
> do we have such using case?
> I guess usually one pin group already contains all the pins of device.
> Anyway, just from flexibility view, it's good for me.

Yes.

Recall that I believe that pin group definitions should only exist where
the HW itself muxes pins on a per-group basis rather than a per-pin basis.
This may be a bit different to what you mean by a group. Anyway...

As an example on Tegra, we have:

* SD controller 4 HW block
* Pin group ATB contains two pins, which are the CLK and CMD signals
  when the SDIO4 function is muxed onto the group.
* Pin group GMA contains four pins, which are DATA[3:0] when the SDIO4
  function is muxed onto the group.
* Pin group GME contains four pins, which are DATA[7:4] when the SDIO4
  function is muxed onto the group.

Hence, a board that uses this SD controller in that configuration would
need 3 entries in its pinmux property/node.

In general, I think all SoCs are likely to be the same way, except that
you'd need n pins in the list instead of n groups, again recalling that
I'm talking about HW-level pins/groups, not entries in a "supported
configuration" list.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-11 23:01                       ` Shawn Guo
@ 2012-01-11 22:58                         ` Stephen Warren
  0 siblings, 0 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-11 22:58 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Dong Aisheng-B29396, Dong Aisheng, linus.walleij, s.hauer,
	linux-kernel, rob.herring, kernel, cjb, devicetree-discuss,
	linux-arm-kernel

Shawn Guo wrote at Wednesday, January 11, 2012 4:01 PM:
> On Wed, Jan 11, 2012 at 11:41:56AM -0800, Stephen Warren wrote:
> > Shawn Guo wrote at Tuesday, January 10, 2012 6:05 AM:
> > > On Tue, Jan 10, 2012 at 08:21:05AM +0000, Dong Aisheng-B29396 wrote:
> > > > Here what I wonder is that do we need to allow the platform to use a func-name
> > > > property in their pinmux func node or pinmux group node to specify the name.
> > >
> > > I do not see the necessity.
> > >
> > > > If it is allowed, then it could be flexible for soc to define their names.
> > > > If not there may be limitations on their node names since we can only get it from
> > > > the node name.
> > >
> > > To me, the node name is perfectly fine to be used for that purpose.
> >
> > I'd prefer if we could use integers over strings if at all possible, but
> > that does have a dependency on dtc getting a syntax to define named
> > constants, or the kernel pre-processing the .dts files before passing
> > them to dtc.
> >
> > But if we have to use strings, I will point out that the pin names I
> > chose for Tegra may not be suitable as DT node names; I don't /think/
> > the DT node names can contain spaces, but I chose to name the Tegra
> > pinctrl pins after both their pin name and GPIO name so that it's
> > easier to correlate the two:
> >
> >         PINCTRL_PIN(TEGRA_PIN_SDIO3_CLK_PA6, "SDIO3_CLK PA6"),
> >
> > Now, I could change that, but I'd prefer not to.
>
> Hmm, we are talking about function name and pingroup name instead of
> individual pin name. In your pinctrl-tegra20.c, they are .name and
> .groups as below.

OK, I guess that's true; my function and group names are just [a-z0-9].

> #define FUNCTION(fname)                                \
>        {                                               \
>                .name = #fname,                         \
>                .groups = fname##_groups,               \
>                .ngroups = ARRAY_SIZE(fname##_groups),  \
>        }

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-11 19:41                     ` Stephen Warren
@ 2012-01-11 23:01                       ` Shawn Guo
  2012-01-11 22:58                         ` Stephen Warren
  0 siblings, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-11 23:01 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, Dong Aisheng, linus.walleij, s.hauer,
	linux-kernel, rob.herring, kernel, cjb, devicetree-discuss,
	linux-arm-kernel

On Wed, Jan 11, 2012 at 11:41:56AM -0800, Stephen Warren wrote:
> Shawn Guo wrote at Tuesday, January 10, 2012 6:05 AM:
> > On Tue, Jan 10, 2012 at 08:21:05AM +0000, Dong Aisheng-B29396 wrote:
> > > Here what I wonder is that do we need to allow the platform to use a func-name
> > > property in their pinmux func node or pinmux group node to specify the name.
> > 
> > I do not see the necessity.
> > 
> > > If it is allowed, then it could be flexible for soc to define their names.
> > > If not there may be limitations on their node names since we can only get it from
> > > the node name.
> > 
> > To me, the node name is perfectly fine to be used for that purpose.
> 
> I'd prefer if we could use integers over strings if at all possible, but
> that does have a dependency on dtc getting a syntax to define named
> constants, or the kernel pre-processing the .dts files before passing
> them to dtc.
> 
> But if we have to use strings, I will point out that the pin names I
> chose for Tegra may not be suitable as DT node names; I don't /think/
> the DT node names can contain spaces, but I chose to name the Tegra
> pinctrl pins after both their pin name and GPIO name so that it's
> easier to correlate the two:
> 
>         PINCTRL_PIN(TEGRA_PIN_SDIO3_CLK_PA6, "SDIO3_CLK PA6"),
> 
> Now, I could change that, but I'd prefer not to.
> 
Hmm, we are talking about function name and pingroup name instead of
individual pin name. In your pinctrl-tegra20.c, they are .name and
.groups as below.

#define FUNCTION(fname)                                \
       {                                               \
               .name = #fname,                         \
               .groups = fname##_groups,               \
               .ngroups = ARRAY_SIZE(fname##_groups),  \
       }

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-11 20:17                   ` Stephen Warren
@ 2012-01-11 23:21                     ` Shawn Guo
  2012-01-12  8:36                     ` Dong Aisheng-B29396
  2012-01-13 17:11                     ` Dong Aisheng
  2 siblings, 0 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-11 23:21 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org)

On Wed, Jan 11, 2012 at 12:17:51PM -0800, Stephen Warren wrote:
> ...
> > To keep consistency as the currently design of pinctrl subsystem and also meet
> > the dt design philosophy, we still do not introduce a pinmux map in dt.
> > Instead, we choose to scan all the device node with a 'pinmux' phandle to construct
> > a pinmux map table before register the pin controller device(here we may also scan
> > the hog_on_boot node) and I guess it's easy to do that.
> ...
> > (Without scan the device node to construct the pinmux map table, we can only get the map
> > Information when we run the pinmux_get.
> > See: https://lkml.org/lkml/2012/1/5/153
> > So no pinmux map table exists and we surely do not want to see that the sysfs exporting
> > pinmux map information works in dt but unwork in non-dt)
> 
> Hmmm. I'm not sure that the pinctrl code should actively scan all nodes
> in the device tree for pin mux properties. That seems a little invasive;
> how does pinctrl know which nodes it really should be looking at, and
> which nodes are random internal parts of some device's custom binding?
> 
> Personally, I think I'd be OK with the sysfs pinctrl map file only
> containing the map entries for devices that had used the pinctrl API,
> and hence only parsing the pinmux properties in pinmux_get().
> 
During the discussion with Aisheng, I also inclined to go this way.
But it seems that he really cares about aligning dt support and
non-dt code path in pinctrl core level, which does not really matter
to me.  So if we vote, I'd vote this way.

If we go this way, all the hog_on_boot nodes need to be under particular
parent node, and get parsed and handled by pinctrl core at probe phase.

Regards,
Shawn

> However, we could perhaps do better by registering a bus notifier, and
> pro-actively parsing the top-level DT node (if there is one) for every
> device that is created. That way, the mapping would be parsed as soon
> as the device was created (or perhaps after probe?). The only case this
> might not cover is DT nodes for which the kernel doesn't actually have
> a driver, and hence no device is created.
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-11 18:37                       ` Stephen Warren
@ 2012-01-11 23:56                         ` Shawn Guo
  2012-01-11 23:59                           ` Stephen Warren
  0 siblings, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-11 23:56 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Richard Zhao, linus.walleij, s.hauer, linux-kernel, rob.herring,
	kernel, Simon Glass (sjg@chromium.org),
	cjb, Dong Aisheng-B29396, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

On Wed, Jan 11, 2012 at 10:37:36AM -0800, Stephen Warren wrote:
> Shawn Guo wrote at Sunday, January 08, 2012 6:56 PM:
> > On Sun, Jan 08, 2012 at 08:51:59PM +0800, Richard Zhao wrote:
> > ...
> > > > > So, this does appear to be conflating the two things: The definition of
> > > > > what pins are in a pingroup, and the mux function for a particular
> > > > > setting of that pingroup. I think you need separate nodes for this.
> > > > >
> > > > At least for imx, we do not have mux function setting for pingroup.
> > > > Instead, it only applies to individual pin.
> > > I think it depends on function definition of pinmux driver. For the
> > > imx example patch, it's one-to-one.
> > 
> > It should depend on particular imx soc pinmux design rather than
> > pinmux driver.  If it's always one-to-one case, we do not need
> > pinmux at all.  Aisheng's patch just did not enumerate all the groups
> > for given function.  Instead, it puts a couple simple examples there
> > for demonstration.
> > 
> > ...
> > 
> > > > > 		uart4func: func@1 {
> > > > > 			func-name = "uart4";
> > > > > 			locations = <&bargrp &bazgrp>;
> > > > > 			mux-value = <6 3>;
> > > > > 		};
> > > >
> > > > I prefer to have function node defined in <board>.dtsi, since it's
> > > > all about defining phandle to the correct pingroup, which should be
> > > > decided by board design.
> > > group and function are one-to-one mapped for imx.
> > 
> > Again, it's not the case.
> > 
> > > So if you put function
> > > in board dts, why not put pin group there too?
> > 
> > If we put pingroup data in <board>.dts, the data will be likely get
> > duplicated a lot in different board dts files.  For example, if
> > imx6q-sabrelite chooses the same pingroup for usdhc3 and usdhc4 as
> > imx6q-arm2, the pingroup data will be duplicated between imx6q-arm2.dts
> > and imx6q-sabrelite.dts.
> > 
> > On the contrary, putting pingroup data in <soc>.dtsi and having function
> > node in <board>.dts with phandle pointing to the correct pingroup will
> > help avoid such data duplication.
> 
> Oh, when I wrote in my first mail today that I'd expand on one of my
> points when responding to Richard Zhao's email, I actually meant when
> responding to this email. Sorry for the confusion!
> 
> So, I don't agree with putting the "combinations" in the SoC .dtsi file,
> since that could grow it into a huge file that contains a lot of nodes
> that are used on some board somewhere, but typically not the "current"
> board that's including it.
> 
> However, I do see that there are probably lots of common combinations
> that get re-used across multiple boards, and you might want a common
> place to put those definitions so they don't need to be cut/paste
> everywhere.
> 
> So, why not create specific include files (.dtsi files) for each of those
> combinations? Each include could define one particular common combination
> of pin mux usage, or perhaps even a set of them if they're commonly used
> together. Each board file would include the SoC .dtsi file, the relevant
> set of "pinmux config" .dtsi files, and then include anything custom to
> that board.

This is somehow overkilled to me.  Doing this will create a big mount
of .dtsi files to bloat folder arch/arm/boot/dts.  Putting the
'combinations' in <soc>.dtsi seems perfect fine to me.

Regards,
Shawn

> Remember, that include files simply get merged into the device
> tree, so you can easily add based definitions (like) regs for e.g. an
> SDHCI controller in a SoC .dtsi file, the pinmux properties in a .dtsi
> file specific to SHDCI controller 3, and then e.g. CD/WP/power GPIOs in
> the final board .dts file.
> 
> Following this model, we can initially just put the pinmux config into
> each board file, then factor it out into new .dtsi files as/when we see
> duplication. We get to start off simple, then clean up by refactoring as
> we go.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-11 23:56                         ` Shawn Guo
@ 2012-01-11 23:59                           ` Stephen Warren
  2012-01-12  4:03                             ` Shawn Guo
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-11 23:59 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Richard Zhao, linus.walleij, s.hauer, linux-kernel, rob.herring,
	kernel, Simon Glass (sjg@chromium.org),
	cjb, Dong Aisheng-B29396, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

Shawn Guo wrote at Wednesday, January 11, 2012 4:57 PM:
> On Wed, Jan 11, 2012 at 10:37:36AM -0800, Stephen Warren wrote:
> > Shawn Guo wrote at Sunday, January 08, 2012 6:56 PM:
> > > On Sun, Jan 08, 2012 at 08:51:59PM +0800, Richard Zhao wrote:
> > > ...
> > > > > > So, this does appear to be conflating the two things: The definition of
> > > > > > what pins are in a pingroup, and the mux function for a particular
> > > > > > setting of that pingroup. I think you need separate nodes for this.
> > > > > >
> > > > > At least for imx, we do not have mux function setting for pingroup.
> > > > > Instead, it only applies to individual pin.
> > > > I think it depends on function definition of pinmux driver. For the
> > > > imx example patch, it's one-to-one.
> > >
> > > It should depend on particular imx soc pinmux design rather than
> > > pinmux driver.  If it's always one-to-one case, we do not need
> > > pinmux at all.  Aisheng's patch just did not enumerate all the groups
> > > for given function.  Instead, it puts a couple simple examples there
> > > for demonstration.
> > >
> > > ...
> > >
> > > > > > 		uart4func: func@1 {
> > > > > > 			func-name = "uart4";
> > > > > > 			locations = <&bargrp &bazgrp>;
> > > > > > 			mux-value = <6 3>;
> > > > > > 		};
> > > > >
> > > > > I prefer to have function node defined in <board>.dtsi, since it's
> > > > > all about defining phandle to the correct pingroup, which should be
> > > > > decided by board design.
> > > > group and function are one-to-one mapped for imx.
> > >
> > > Again, it's not the case.
> > >
> > > > So if you put function
> > > > in board dts, why not put pin group there too?
> > >
> > > If we put pingroup data in <board>.dts, the data will be likely get
> > > duplicated a lot in different board dts files.  For example, if
> > > imx6q-sabrelite chooses the same pingroup for usdhc3 and usdhc4 as
> > > imx6q-arm2, the pingroup data will be duplicated between imx6q-arm2.dts
> > > and imx6q-sabrelite.dts.
> > >
> > > On the contrary, putting pingroup data in <soc>.dtsi and having function
> > > node in <board>.dts with phandle pointing to the correct pingroup will
> > > help avoid such data duplication.
> >
> > Oh, when I wrote in my first mail today that I'd expand on one of my
> > points when responding to Richard Zhao's email, I actually meant when
> > responding to this email. Sorry for the confusion!
> >
> > So, I don't agree with putting the "combinations" in the SoC .dtsi file,
> > since that could grow it into a huge file that contains a lot of nodes
> > that are used on some board somewhere, but typically not the "current"
> > board that's including it.
> >
> > However, I do see that there are probably lots of common combinations
> > that get re-used across multiple boards, and you might want a common
> > place to put those definitions so they don't need to be cut/paste
> > everywhere.
> >
> > So, why not create specific include files (.dtsi files) for each of those
> > combinations? Each include could define one particular common combination
> > of pin mux usage, or perhaps even a set of them if they're commonly used
> > together. Each board file would include the SoC .dtsi file, the relevant
> > set of "pinmux config" .dtsi files, and then include anything custom to
> > that board.
> 
> This is somehow overkilled to me.  Doing this will create a big mount
> of .dtsi files to bloat folder arch/arm/boot/dts.  Putting the
> 'combinations' in <soc>.dtsi seems perfect fine to me.

I see a couple problems with that approach:

1) <soc>.dtsi gets very bloated, and wastes space containing board-
specific data for boards other than the "current" one.

2) We need to invent some more complex DT format so you can reference
these canned combinations from the device drivers, rather than simply
enumerating the mux value for each pin/group.

You could put the combination .dtsi files in arch/arm/boot/dts/<soc> to
maintain some extra order.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-11 18:17                   ` Stephen Warren
@ 2012-01-12  3:39                     ` Shawn Guo
  2012-01-12  7:40                       ` Dong Aisheng-B29396
  2012-01-12 20:46                       ` Stephen Warren
  0 siblings, 2 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-12  3:39 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org),
	Richard Zhao

On Wed, Jan 11, 2012 at 10:17:40AM -0800, Stephen Warren wrote:
> Shawn Guo wrote at Saturday, January 07, 2012 6:55 AM:
> > On Fri, Jan 06, 2012 at 10:03:07AM -0800, Stephen Warren wrote:
> ...
> > > So, this does appear to be conflating the two things: The definition of
> > > what pins are in a pingroup, and the mux function for a particular
> > > setting of that pingroup. I think you need separate nodes for this.
> > >
> > At least for imx, we do not have mux function setting for pingroup.
> > Instead, it only applies to individual pin.
> 
> Ah. There's a slight disconnect between my understanding of your HW and
> how it really is then! I saw pingroup definitions on Dong's patch, and
> hence I assume that your HW was like Tegra, namely that pins were grouped
> together for mux control, i.e. muxing isn't a per-pin option. Given that,
> some of my responses may not entirely have made sense for your HW...
> 
> Just to confirm my understanding:
> 
> IMX:
> 
> * HW has a set of pins.
> * Each pin has a register/field that defines its mux function.
> 
Correct.

> And contrast this to Tegra for reference:
> 
> * HW has a set of pins.
> * Each pin is a member of a single mux group..
> * Each mux group has a register/field that defines its mux function.
>   This affects all the pins in the group at once, which are all set to
>   the same logical function (e.g. UART). For that logical function, each
>   pin has some specific signal muxed onto it. For example, a pin group
>   "X" may have pins P1 and P2, and when function "UART" is muxed onto "X",
>   P1 will be UART.RX and P2 UART.TX.

Understood.

> * Note that there also exist other properties that can be configured for
>   each of these mux groups (e.g. pullup/down, tristate). There also exist
>   other types of groups that don't align with the mux groups, and each of
>   those allows various other properties (e.g. drive strength) to be
>   configured. However, this bullet isn't relevant for the pin mux
>   discussion, just pin config.
> 
Same as pinmux, the pinconf applies to individual pin as well.

> So, my position is that:
> 
> * Something (either the pinctrl driver, or the SoC .dtsi file) should
> enumerate all available muxable entities that exist in the SoC (pins for
> IMX, groups for Tegra).
> 
Yes, we enumerate all available pins in pinctrl driver for imx.

> * Something (either the pinctrl driver, or the SoC .dtsi file) should
> enumerate all the available functions that can be assigned to a muxable
> entity.
> 
In theory, yes.  But I hope you would agree we do not need to
necessarily do this for case like imx.

For imx6q example, we have 193 pins as the muxable entities, and for
each of those pin, there are 8 alternative functions.  Let's see what
we will have if we enumerate all the available functions for each pin.

enum imx6q_pads {
        IMX6Q_SD2_DAT1 = 0,
        IMX6Q_SD2_DAT2 = 1,
        ...
        IMX6Q_NANDF_D7 = 192,
};

enum imx6q_pad_sd2_dat1 {
        IMX6Q_PAD_SD2_DAT1__USDHC2_DAT1			= 0,
        IMX6Q_PAD_SD2_DAT1__ECSPI5_SS0			= 1,
        IMX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2		= 2,
        IMX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS		= 3,
        IMX6Q_PAD_SD2_DAT1__KPP_COL_7			= 4,
        IMX6Q_PAD_SD2_DAT1__GPIO_1_14			= 5,
        IMX6Q_PAD_SD2_DAT1__CCM_WAIT			= 6,
        IMX6Q_PAD_SD2_DAT1__ANATOP_ANATOP_TESTO_0	= 7,
};

enum imx6q_pad_sd2_dat2 {
        IMX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
        IMX6Q_PAD_SD2_DAT2__ECSPI5_SS1,
        IMX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3,
        IMX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD,
        IMX6Q_PAD_SD2_DAT2__KPP_ROW_6,
        IMX6Q_PAD_SD2_DAT2__GPIO_1_13,
        IMX6Q_PAD_SD2_DAT2__CCM_STOP,
        IMX6Q_PAD_SD2_DAT2__ANATOP_ANATOP_TESTO_1,
};

...

enum imx6q_pad_nandf_d7 {
        IMX6Q_PAD_NANDF_D7__RAWNAND_D7,
        IMX6Q_PAD_NANDF_D7__USDHC2_DAT7,
        IMX6Q_PAD_NANDF_D7__GPU3D_GPU_DEBUG_OUT_7,
        IMX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT_23,
        IMX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT_23,
        IMX6Q_PAD_NANDF_D7__GPIO_2_7,
        IMX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7,
        IMX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7,
};

We simply do not want to over bloat imx6q pinctrl driver with such
enumeration.  You may want to suggest we put enumeration of both pins
and their functions into dts, so that the pinctrl driver can be clean.
I'm not sure how that will look like in your mind, but it's something
like below in mine.

        sd2_dat1: pin@0 {
                alt-functions = < "USDHC2_DAT1"
                                  "ECSPI5_SS0"
                                  "WEIM_WEIM_CS_2"
                                  "AUDMUX_AUD4_TXFS"
                                  "KPP_COL_7"
                                  "GPIO_1_14"
                                  "CCM_WAIT"
                                  "ANATOP_ANATOP_TESTO_0" >;
        };

        sd2_dat2: pin@1 {
                alt-functions = < "USDHC2_DAT2"
                                  "ECSPI5_SS1"
                                  "WEIM_WEIM_CS_3"
                                  "AUDMUX_AUD4_TXD"
                                  "KPP_ROW_6"
                                  "GPIO_1_13"
                                  "CCM_STOP"
                                  "ANATOP_ANATOP_TESTO_1" >;
        };

We will end up with having 193 such nodes in device tree.  I had one
patch trying to add pinmux support for imx5 with enumerating every
single pin in device tree (That's before pinctrl subsystem is born).
The patch concerned Grant a lot with that many nodes in device tree
and thus died.

Besides the above concern, what's the point of enumerating all
available functions for each pin at all?  The client device will still
choose desired function with index/number.  See example below ...

> * The enumerations above should be purely at the level the HW exposes,
> i.e. if a UART uses 4 signals (RX, TX, CTS, RTS), and the SoC configures
> muxing at a per-pin level, and 6 pins exist which can have various UART
> signals mux'd on to them, there should be a "muxable entity" enumeration
> for each of the 6 pins, not an enumeration for each possible combination
> of assignments of signals to pins, since in general that number could be
> extremely large as Richard Zao points out in his email that was sent right
> after yours.
> 
Speaking of the model, yes, it's true.  But coming to the practical
implementation, we may need compromise on whether we need to do a full
enumeration.

> * pinmux properties in device drivers should list the muxable entities
> that they use, and the mux function for each of them.
> 
Following on the example above, we will need something below in SD node
to specify each pin and corresponding function selection.

        usdhc@02194000 { /* uSDHC2 */
                #pinmux-cells = <2>;
                // The second cell specify the index of the desired function of given pin
                pinmux = < &sd2_dat1 0
                           &sd2_dat2 0
                           ...        >;
                status = "okay";
        };

IMO, it's not nice for pinctrl client devices.  Though it's true that
the muxable entity is pin, what the client device really cares is its
pingroup.  We should define the pingroup rather than pin for client
device to refer to with a phandle.  This is just like that pinctrl
subsystem api pinmux_get/enable operate on a pingroup as an interface
to client device driver, no matter the muxable entity at HW level is
a pin or a group.

> This is the minimal data model to represent the pure HW functionality,
> and is what the pinctrl subsystem uses too.
> 
I fully agree on this model in theory.  But again we may need compromise
on some particular implementation.

> > > Without separate nodes, there will eventually be a lot of duplication.
> > > A made-up example of the same uart4grp allowing either of two functions
> > > uart3, uart4 to be muxed out onto it:
> > >
> > > aips-bus@02000000 { /* AIPS1 */
> > >     iomuxc@020e0000 {
> > >             pinctrl_uart4_3: uart4@option_3 {
> > >                     func-name = "uart3";
> > >                     grp-name = "uart4grp";
> >
> > With phandle in dts reflecting the mapping, neither func-name nor
> > grp-name should be needed, and both can just be dropped, IMO.
> 
> I'd now argue that these nodes shouldn't even exist in the device tree;
> rather the "combination" of which muxable entities are used and their
> used mux function should be something in the board .dts files, since its
> board-specific.
> 
Again, it's a compromise.  Though the muxable entity at HW level is
individual pin, we are trying to provide a pingroup for client devices
to refer to, since that's what they are really interested in.

...

> > >             /* A node per group of pins. Each lists the group name, and
> > >              * the list of pins in the group */
> > >             foogrp: group@100 {
> > >                     grp-name = "foogrp";
> > >                     grp-pins = <100 101>;
> > >             };
> > >             bargrp: group@102 {
> > >                     grp-name = "bargrp";
> > >                     grp-pins = <102 103>;
> > >             };
> > >             bazgrp: group@104 {
> > >                     grp-name = "bargrp";
> > >                     grp-pins = <104 105>;
> > >             };
> >
> > I agree that we should define pingroups in <soc>.dtsi, but the mux
> > setting needs to be under the pingroup node too.  See comment below ...
> 
> As I mention above, I'd assert we shouldn't have any group nodes in
> the .dtsi file for SoCs that don't mux pins in groups at the raw HW level.
> 
I admit it's not a pingroup defined by raw HW.  We chose to create it
to ease users/client devices and avoid data duplication.

...

> > >             };
> > >             uart4func: func@1 {
> > >                     func-name = "uart4";
> > >                     locations = <&bargrp &bazgrp>;
> > >                     mux-value = <6 3>;
> > >             };
> >
> > I prefer to have function node defined in <board>.dtsi, since it's
> > all about defining phandle to the correct pingroup, which should be
> > decided by board design.
> 
> Just to explicitly re-iterate, if there are no groups in HW, I don't
> think the .dtsi file should attempt to represent any groups.
> 
Again, this is a compromise.  The groups represented here are meant to
helper users and save data duplication.

> (I think I'll talk a little more about this in a response to Richard
> Zhao's email later)

...

> > > * Should "pinmux" be a node, and the configuration of each group be a
> > > separate sub-node, so we can add more properties to each "table" entry
> > > in the future, e.g. pin config parameters?
> >
> > I do not think it's necessary. 'pinctrl' phandle works perfectly fine
> > to me at least for now.  How pinconf support should be added into
> > pinctrl subsystem is still up in the air to me.
> 
> Well, I think we definitely need to have a rough idea how to support pin
> config in the future; representing the current pin mux as a node rather
> than a property seems like a pretty easy way to allow this future
> flexibility.
> 
I guess, one benefit with representing pingroup anyway no matter the
muxable entity at HW level is pin or pingroup is we can always have
a pingroup node, thus the pinconf data can be represented there.  All
we need under client device node is a phandle to the correct pingroup
node.  Both pinmux and pinconf data can be found in that pingroup node.

> > > * For Tegra, I elected to put the definitions of pins, groups, and
> > > functions into the driver rather than in the device tree.
> >
> > IMO, we do not want to do this for imx, as I'm scared of the size
> > of Tegra pinctrl patches.  If we go this way for imx, we will have
> > even bigger patches.
> 
> Now you're confusing me! In one of your answers above, you said:
> 
>   > >           /* FIXME: Perhaps need pin nodes here to name them too */
>   > No, it's been listed in imx pinctrl driver.
> 
> So it sounds like the raw HW capabilities /are/ being enumerated by the
> pinctrl driver and not device tree, which is exactly what I was saying
> I'd chosen for Tegra. Well, with the exception that IMX's pinctrl driver
> doesn't define groups, since the HW doesn't mux in groups.
> 
> Perhaps you're talking about enumerating groups of pins, which don't
> really exist in HW. I wasn't.
> 
I meant we have the following defined in imx pinctrl driver.

enum imx6q_pads {
	IMX6Q_SD2_DAT1 = 0,
	IMX6Q_SD2_DAT2 = 1,
	...
};

#define IMX_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin)

static const struct pinctrl_pin_desc imx6q_pinctrl_pads[] = {
	IMX_PINCTRL_PIN(MX6Q_SD2_DAT1),
	IMX_PINCTRL_PIN(MX6Q_SD2_DAT2),
	...
};

It's all about defining pin number and pin name.  All the HW
capabilities, pin mux, pin config, will be defined in device tree.

> > > This avoids
> > > parsing a heck of a lot of data from device tree. That means there isn't
> > > any per-function node that can be referred to by phandle. Does it make
> > > sense to refer to groups and functions by string name or integer ID
> > > instead of phandle? Perhaps:
> > >
> > > usdhc@0219c000 { /* uSDHC4 */
> > >     fsl,card-wired;
> > >     status = "okay";
> > >     pinmux = {
> > >             group@0 {
> > >                     group = "foo";
> > >                     function = "uart3";
> > >                     /* You could add pin config options here too */
> > >             };
> > >             group@1 {
> > >                     group = "baz";
> > >                     function = "uart4";
> > >             };
> > >     };
> > > };
> > >
> > > I guess referring to things by name isn't that idiomatic for device tree.
> > > Using integers here would be fine too, so long as dtc gets support for
> > > named constants:
> > >
> > > imx6q.dtsi:
> > >
> > > /define/ IMX_PINGRP_FOO 0
> > > /define/ IMX_PINGRP_BAR 1
> > > /define/ IMX_PINGRP_BAZ 2
> > > /define/ IMX_PINFUNC_UART3 0
> > > /define/ IMX_PINFUNC_UART4 1
> > > ...
> > >
> > > board .dts:
> > >
> > > usdhc@0219c000 { /* uSDHC4 */
> > >     fsl,card-wired;
> > >     status = "okay";
> > >     pinmux = {
> > >             group@0 {
> > >                     group = <IMX_PINGRP_FOO>;
> > >                     function = <IMX_PINFUNC_UART3>;
> > >                     /* You could add pin config options here too */
> > >             };
> > >             group@1 {
> > >                     group = <IMX_PINGRP_BAZ>;
> > >                     function = <IMX_PINFUNC_UART4>;
> > >             };
> > >     };
> > > };
> 
> So given that IMX muxes per pin not per group of pins, that "group"
> property above should really be named "pin", and the IMX_PINGRP_* values
> renamed IMX_PIN_* instead.
> 
> In general, it'd be nice to come up with a binding for the users of
> pinmux (i.e. the device nodes like usdhc above) that allowed them to
> refer to what I've been calling "muxable entity". perhaps instead of
> "pin" or "group" the property should be called "mux-point", and it's
> up to the pinctrl driver to interpret that as a pin or group ID based
> on what its muxable entities are.
> 
See, this can be easily standardised if we allow pingroup represented
in device tree even though the muxable entity at HW level is pin.
That said, we can always have 'pinctrl' property under client device
node as the phandle to the pingroup that the device uses.

> > Doing this does not change the fact that this is bound with Linux
> > driver details.  That said, if the indexing of either pingrp array
> > or pinfunc array changes in the driver, the binding is broken.
> 
> I don't agree here.
> 
> Having a driver state that it wants "pin P" or "group G" to be programmed
> to "mux function F" is very purely HW oriented.
> 
> The fact this so closely aligns with the data model that the pinctrl
> subsystem uses is simply because I pushed for the same pure HW oriented
> data model in the pinctrl subsystem; both models were derived from how
> the HW works, rather than the binding being derived from the driver.
> 
> Equally, the binding for the individual pin mux HW will define what the
> integer values for pin/group/function are. In practice, we will choose
> the values that the Linux pinctrl driver uses to remove the need for
> conversion when parsing the device tree. However, we should be very aware
> that the binding is what specifies the values, not the driver, so if the
> driver changes its internal representation, it must add conversion code
> when parsing the device tree, not require the device tree to change.
> 
> That said, I don't see why the pinctrl driver would change its pin, group,
> or mux function numbering scheme for a given SoC; the HW is fixed, right?

It's right for case like Tegra where the group is defined by HW, but
it's not for case like imx, where there is no group defined at HW
level.  For imx non-dt case, the pingroup is defined by pinctrl driver,
thus the indexing of pingroup array can really be random.

Regards,
Shawn

> (Well, for shipping HW, and designs-in-progress can presumably handle some
> churn in the device tree binding specification during RTL development
> or layout)
> 
> If there's a bug in the list of pins/groups/functions, that's probably
> also a bug in the device tree binding too, not an arbitrary change, so
> it seems fine to fix that, hopefully in as backwards-compatible way as
> possible though, i.e. adding missing entries to the end of the list so
> there's no renumbering etc. this is unlikely to happen late in the game.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-11 23:59                           ` Stephen Warren
@ 2012-01-12  4:03                             ` Shawn Guo
  2012-01-12  7:45                               ` Dong Aisheng-B29396
  0 siblings, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-12  4:03 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Richard Zhao, linus.walleij, s.hauer, linux-kernel, rob.herring,
	kernel, Simon Glass (sjg@chromium.org),
	cjb, Dong Aisheng-B29396, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

On Wed, Jan 11, 2012 at 03:59:26PM -0800, Stephen Warren wrote:
> Shawn Guo wrote at Wednesday, January 11, 2012 4:57 PM:
> > This is somehow overkilled to me.  Doing this will create a big mount
> > of .dtsi files to bloat folder arch/arm/boot/dts.  Putting the
> > 'combinations' in <soc>.dtsi seems perfect fine to me.
> 
> I see a couple problems with that approach:
> 
> 1) <soc>.dtsi gets very bloated,

In theory, it's possible.  But in the real world, I do not think this
will be an issue.  From the experience from working on previous imx
platforms, the mux chosen on Freescale reference design board will
likely be reused on custom boards much.

> and wastes space containing board-
> specific data for boards other than the "current" one.

Technically, it's not the board specific data, because what pins can
be put together consisting of a function is really soc specific.

> 
> 2) We need to invent some more complex DT format so you can reference
> these canned combinations from the device drivers, rather than simply
> enumerating the mux value for each pin/group.

Sorry, I do not get that.

Regards,
Shawn

> 
> You could put the combination .dtsi files in arch/arm/boot/dts/<soc> to
> maintain some extra order.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-12  3:39                     ` Shawn Guo
@ 2012-01-12  7:40                       ` Dong Aisheng-B29396
  2012-01-12 20:46                       ` Stephen Warren
  1 sibling, 0 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-12  7:40 UTC (permalink / raw)
  To: Shawn Guo, Stephen Warren
  Cc: Dong Aisheng, linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org),
	Richard Zhao

...
> > * The enumerations above should be purely at the level the HW exposes,
> > i.e. if a UART uses 4 signals (RX, TX, CTS, RTS), and the SoC
> > configures muxing at a per-pin level, and 6 pins exist which can have
> > various UART signals mux'd on to them, there should be a "muxable
> > entity" enumeration for each of the 6 pins, not an enumeration for
> > each possible combination of assignments of signals to pins, since in
> > general that number could be extremely large as Richard Zao points out
> > in his email that was sent right after yours.
> >
> Speaking of the model, yes, it's true.  But coming to the practical
> implementation, we may need compromise on whether we need to do a full
> enumeration.
> 
> > * pinmux properties in device drivers should list the muxable entities
> > that they use, and the mux function for each of them.
> >
> Following on the example above, we will need something below in SD node to
> specify each pin and corresponding function selection.
> 
>         usdhc@02194000 { /* uSDHC2 */
>                 #pinmux-cells = <2>;
>                 // The second cell specify the index of the desired function of
> given pin
>                 pinmux = < &sd2_dat1 0
>                            &sd2_dat2 0
>                            ...        >;
>                 status = "okay";
>         };
> 
> IMO, it's not nice for pinctrl client devices.  Though it's true that the
> muxable entity is pin, what the client device really cares is its pingroup.  We
> should define the pingroup rather than pin for client device to refer to with a
> phandle.  This is just like that pinctrl subsystem api pinmux_get/enable operate
> on a pingroup as an interface to client device driver, no matter the muxable
> entity at HW level is a pin or a group.
> 
+1
It's just like what the current pinctrl subsystem does:
the device says "I'm using this function and this pin group, please enable!"
But no pins are specified.

Regards
Dong Aisheng


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-12  4:03                             ` Shawn Guo
@ 2012-01-12  7:45                               ` Dong Aisheng-B29396
  0 siblings, 0 replies; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-12  7:45 UTC (permalink / raw)
  To: Shawn Guo, Stephen Warren
  Cc: Richard Zhao, linus.walleij, s.hauer, linux-kernel, rob.herring,
	kernel, Simon Glass (sjg@chromium.org),
	cjb, devicetree-discuss, linux-arm-kernel, Dong Aisheng

> -----Original Message-----
> From: Shawn Guo [mailto:shawn.guo@linaro.org]
> Sent: Thursday, January 12, 2012 12:04 PM
> To: Stephen Warren
> Cc: Richard Zhao; linus.walleij@stericsson.com; s.hauer@pengutronix.de; linux-
> kernel@vger.kernel.org; rob.herring@calxeda.com; kernel@pengutronix.de; Simon
> Glass (sjg@chromium.org); cjb@laptop.org; Dong Aisheng-B29396; devicetree-
> discuss@lists.ozlabs.org; linux-arm-kernel@lists.infradead.org; Dong Aisheng
> Subject: Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> On Wed, Jan 11, 2012 at 03:59:26PM -0800, Stephen Warren wrote:
> > Shawn Guo wrote at Wednesday, January 11, 2012 4:57 PM:
> > > This is somehow overkilled to me.  Doing this will create a big
> > > mount of .dtsi files to bloat folder arch/arm/boot/dts.  Putting the
> > > 'combinations' in <soc>.dtsi seems perfect fine to me.
> >
> > I see a couple problems with that approach:
> >
> > 1) <soc>.dtsi gets very bloated,
> 
> In theory, it's possible.  But in the real world, I do not think this will be an
> issue.  From the experience from working on previous imx platforms, the mux
> chosen on Freescale reference design board will likely be reused on custom
> boards much.
> 
I'm don't think it's a big issue.
If we really find it getting very bloated, we will refine it later.

> > and wastes space containing board-
> > specific data for boards other than the "current" one.
> 
> Technically, it's not the board specific data, because what pins can be put
> together consisting of a function is really soc specific.
> 
Yes, it's true.

> >
> > 2) We need to invent some more complex DT format so you can reference
> > these canned combinations from the device drivers, rather than simply
> > enumerating the mux value for each pin/group.
> 
> Sorry, I do not get that.
> 
> Regards,
> Shawn
> 
> >
> > You could put the combination .dtsi files in arch/arm/boot/dts/<soc>
> > to maintain some extra order.



^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-11 20:17                   ` Stephen Warren
  2012-01-11 23:21                     ` Shawn Guo
@ 2012-01-12  8:36                     ` Dong Aisheng-B29396
  2012-01-12 20:56                       ` Stephen Warren
  2012-01-13 17:11                     ` Dong Aisheng
  2 siblings, 1 reply; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-12  8:36 UTC (permalink / raw)
  To: Stephen Warren, Dong Aisheng
  Cc: linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org)

> -----Original Message-----
> From: Stephen Warren [mailto:swarren@nvidia.com]
> Sent: Thursday, January 12, 2012 4:18 AM
> To: Dong Aisheng-B29396; Dong Aisheng
> Cc: linux-kernel@vger.kernel.org; linus.walleij@stericsson.com;
> s.hauer@pengutronix.de; rob.herring@calxeda.com; linux-arm-
> kernel@lists.infradead.org; kernel@pengutronix.de; cjb@laptop.org; devicetree-
> discuss@lists.ozlabs.org; Simon Glass (sjg@chromium.org)
> Subject: RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> Dong Aisheng wrote at Tuesday, January 10, 2012 1:21 AM:
> > Stephen Warren wrote at Saturday, January 07, 2012 2:03 AM:
> ...
> > > Now in the board's .dts file, you need to specify for each device
> > > the list of pinmux groups the device needs to use, and the function to
> select for each group.
> > > Perhaps something like:
> > >
> > > board.dts:
> > >
> > > usdhc@0219c000 { /* uSDHC4 */
> > >         fsl,card-wired;
> > >         status = "okay";
> > >         pinmux = <&foogrp &uart3func &bazgrp &uart4func>; };
> > >
> > > I haven't convinced myself that's actually a good binding, but I
> > > think it does represent the data required for muxing. Some potential issues
> as before:
> >
> > Here is what we should discuss exactly.
> > Since 'pinmux' phandle will be parsed in pinctrl core, we should try
> > to find and define a common and standardized pinmux property for all platforms.
> 
> Yes.
> 
> ...
> > To keep consistency as the currently design of pinctrl subsystem and
> > also meet the dt design philosophy, we still do not introduce a pinmux map in
> dt.
> > Instead, we choose to scan all the device node with a 'pinmux' phandle
> > to construct a pinmux map table before register the pin controller
> > device(here we may also scan the hog_on_boot node) and I guess it's easy to do
> that.
> ...
> > (Without scan the device node to construct the pinmux map table, we
> > can only get the map Information when we run the pinmux_get.
> > See: https://lkml.org/lkml/2012/1/5/153
> > So no pinmux map table exists and we surely do not want to see that
> > the sysfs exporting pinmux map information works in dt but unwork in
> > non-dt)
> 
> Hmmm. I'm not sure that the pinctrl code should actively scan all nodes in the
> device tree for pin mux properties. That seems a little invasive; how does
It's one solution although not good.

> pinctrl know which nodes it really should be looking at, and which nodes are
> random internal parts of some device's custom binding?
> 
Looking at all device nodes with 'pinmux' property which should not be used by
Others.

> Personally, I think I'd be OK with the sysfs pinctrl map file only containing
> the map entries for devices that had used the pinctrl API, and hence only
> parsing the pinmux properties in pinmux_get().
> 
Actually I already did it like that in the patch I sent:
https://lkml.org/lkml/2012/1/5/153

Originally I'd like to do like that but I found an inconsistent issue that
the sysfs pinctrl map file will behave differently between dt and non-dt
Platform. For non-dt, it means showing all exist map entries. For dt, it means
Only used pinmux map entries.

And in current design when device calls pinmux_get, it will search a predefined
pinmux_maps array to find which function and group it is binded to.
If switch to the new way, we only dynamically create pinmux map and dynamically 
register it when pinmux_get is called, first we need to change the code path in
pinmux_get in a totally different way, second for support that we may also better
to change pinmux_maps array to a list.
But after changing the pinmux_maps to a list, what about using in non-dt?

So without any strong reason i still think it would be better to keep consistency
With the non-dt pinctrl subsystem.
And the effort would be minimum since besides constructing the map by parsing
Device tree, everyting is the same as before in pinmux map and we could re-use
the current code.

> However, we could perhaps do better by registering a bus notifier, and pro-
> actively parsing the top-level DT node (if there is one) for every device that
> is created. That way, the mapping would be parsed as soon as the device was
> created (or perhaps after probe?). The only case this might not cover is DT
> nodes for which the kernel doesn't actually have a driver, and hence no device
> is created.
> 
> > BTW it seems you want to support multi pin groups(foogrp and bazgrp)
> > for one device, do we have such using case?
> > I guess usually one pin group already contains all the pins of device.
> > Anyway, just from flexibility view, it's good for me.
> 
> Yes.
> 
> Recall that I believe that pin group definitions should only exist where the HW
> itself muxes pins on a per-group basis rather than a per-pin basis.
> This may be a bit different to what you mean by a group. Anyway...
> 
> As an example on Tegra, we have:
> 
> * SD controller 4 HW block
> * Pin group ATB contains two pins, which are the CLK and CMD signals
>   when the SDIO4 function is muxed onto the group.
> * Pin group GMA contains four pins, which are DATA[3:0] when the SDIO4
>   function is muxed onto the group.
> * Pin group GME contains four pins, which are DATA[7:4] when the SDIO4
>   function is muxed onto the group.
> 
> Hence, a board that uses this SD controller in that configuration would need 3
> entries in its pinmux property/node.
> 
Unsertood.

> In general, I think all SoCs are likely to be the same way, except that you'd
> need n pins in the list instead of n groups, again recalling that I'm talking
> about HW-level pins/groups, not entries in a "supported configuration" list.
> 
> --
> nvpublic
> 

Regards
Dong Aisheng


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-12  3:39                     ` Shawn Guo
  2012-01-12  7:40                       ` Dong Aisheng-B29396
@ 2012-01-12 20:46                       ` Stephen Warren
  2012-01-12 21:10                         ` Stephen Warren
  2012-01-13  3:46                         ` Shawn Guo
  1 sibling, 2 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-12 20:46 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org),
	Richard Zhao

Shawn Guo wrote at Wednesday, January 11, 2012 8:40 PM:
> On Wed, Jan 11, 2012 at 10:17:40AM -0800, Stephen Warren wrote:
...
> > So, my position is that:
> >
> > * Something (either the pinctrl driver, or the SoC .dtsi file) should
> > enumerate all available muxable entities that exist in the SoC (pins for
> > IMX, groups for Tegra).
>
> Yes, we enumerate all available pins in pinctrl driver for imx.
>
> > * Something (either the pinctrl driver, or the SoC .dtsi file) should
> > enumerate all the available functions that can be assigned to a muxable
> > entity.
>
> In theory, yes.  But I hope you would agree we do not need to
> necessarily do this for case like imx.

Discussing just the Linux driver internals right now; ignoring device
tree:

Pinctrl won't let you use a function on a pin/group if that function
isn't enumerated and doesn't list that pin/group as a valid location
for that function. Given that, I'm not sure how you can avoid enumerating
all functions and their legal locations?

> For imx6q example, we have 193 pins as the muxable entities, and for
> each of those pin, there are 8 alternative functions.  Let's see what
> we will have if we enumerate all the available functions for each pin.
>
> enum imx6q_pads {
>         IMX6Q_SD2_DAT1 = 0,
>         IMX6Q_SD2_DAT2 = 1,
>         ...
>         IMX6Q_NANDF_D7 = 192,
> };
>
> enum imx6q_pad_sd2_dat1 {
>         IMX6Q_PAD_SD2_DAT1__USDHC2_DAT1                       = 0,
>         IMX6Q_PAD_SD2_DAT1__ECSPI5_SS0                        = 1,
>         IMX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2            = 2,
>         IMX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS          = 3,
>         IMX6Q_PAD_SD2_DAT1__KPP_COL_7                 = 4,
>         IMX6Q_PAD_SD2_DAT1__GPIO_1_14                 = 5,
>         IMX6Q_PAD_SD2_DAT1__CCM_WAIT                  = 6,
>         IMX6Q_PAD_SD2_DAT1__ANATOP_ANATOP_TESTO_0     = 7,
> };
>
> enum imx6q_pad_sd2_dat2 {
>         IMX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
>         IMX6Q_PAD_SD2_DAT2__ECSPI5_SS1,
>         IMX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3,
>         IMX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD,
>         IMX6Q_PAD_SD2_DAT2__KPP_ROW_6,
>         IMX6Q_PAD_SD2_DAT2__GPIO_1_13,
>         IMX6Q_PAD_SD2_DAT2__CCM_STOP,
>         IMX6Q_PAD_SD2_DAT2__ANATOP_ANATOP_TESTO_1,
> };
>
> ...
>
> enum imx6q_pad_nandf_d7 {
>         IMX6Q_PAD_NANDF_D7__RAWNAND_D7,
>         IMX6Q_PAD_NANDF_D7__USDHC2_DAT7,
>         IMX6Q_PAD_NANDF_D7__GPU3D_GPU_DEBUG_OUT_7,
>         IMX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT_23,
>         IMX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT_23,
>         IMX6Q_PAD_NANDF_D7__GPIO_2_7,
>         IMX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7,
>         IMX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7,
> };
>
> We simply do not want to over bloat imx6q pinctrl driver with such
> enumeration.

Yes, I see you'd end up with a huge number of function definitions here.

You may be able to avoid this by changing the way you name/number the
functions though.

The example above has a unique function name for every individual signal.
instead, can you name functions based on the controller they connect to?

So, instead of having:

IMX6Q_PAD_SD2_DAT1__USDHC2_DAT1
IMX6Q_PAD_SD2_DAT2__USDHC2_DAT2
IMX6Q_PAD_SD2_DAT3__USDHC2_DAT3
IMX6Q_PAD_SD2_DAT4__USDHC2_DAT4

Can you replace this with a single:

IMX_FUNC_USDHC2

Where the precise meaning of that function would vary slightly from pad
to pad; it'd mean "whatever signal from the USDHC2 controller can be
routed to this pad".

If a given pad could be mux'd to either of 2 (or n) signals from the same
controller, you may need both IMX_FUNC_USDHC2 and IMX_FUNC_USDHC2_ALT to
represent this.

Now, you'd also need a table that mapped from (pad, function) to
mux register value, but at least this would avoid avoid having so many
function names.

Does this help?

In the Tegra pinctrl patches I posted, I did exactly this.

I guess there is irony here, since I'm arguing elsewhere to make the
data model as close to the HW as possible, whereas here I'm arguing to
use a slightly abstract representation for function number rather than
the raw register mux values.

> You may want to suggest we put enumeration of both pins
> and their functions into dts, so that the pinctrl driver can be clean.

Personally, I'd actually tend to shy away from that; I see little point
putting this basic essentially static data into the .dts file just to
parse it back out at boot time into what'll end up being the same tables.

> I'm not sure how that will look like in your mind, but it's something
> like below in mine.
>
>         sd2_dat1: pin@0 {
>                 alt-functions = < "USDHC2_DAT1"
>                                   "ECSPI5_SS0"
>                                   "WEIM_WEIM_CS_2"
>                                   "AUDMUX_AUD4_TXFS"
>                                   "KPP_COL_7"
>                                   "GPIO_1_14"
>                                   "CCM_WAIT"
>                                   "ANATOP_ANATOP_TESTO_0" >;
>         };
>
>         sd2_dat2: pin@1 {
>                 alt-functions = < "USDHC2_DAT2"
>                                   "ECSPI5_SS1"
>                                   "WEIM_WEIM_CS_3"
>                                   "AUDMUX_AUD4_TXD"
>                                   "KPP_ROW_6"
>                                   "GPIO_1_13"
>                                   "CCM_STOP"
>                                   "ANATOP_ANATOP_TESTO_1" >;
>         };
>
> We will end up with having 193 such nodes in device tree.  I had one
> patch trying to add pinmux support for imx5 with enumerating every
> single pin in device tree (That's before pinctrl subsystem is born).
> The patch concerned Grant a lot with that many nodes in device tree
> and thus died.

Indeed.

> Besides the above concern, what's the point of enumerating all
> available functions for each pin at all?  The client device will still
> choose desired function with index/number.  See example below ...

As I mentioned above, the pinctrl subsystem currently requires it, since
the mapping table contains the function name, which it must then convert
to a function number, and then pass to the pinctrl driver.

As you point out though, this is just error-checking, and if the DT
were to contain the function number directly (rather than the name),
the pinctrl subsystem wouldn't have to convert name to number, but
could just pass the number through to the pinctrl driver. So, in that
scenario, the complete enumeration is only required for error-checking
(did someone put something bogus in the DT?). As such, it would be
technically possible to remove it. What does Linusw think about that?
Personally, it seems like a bad idea to remove the error checking.

Removing the error-checking would also require that the DT use the
raw register mux values, rather than the abstraction I mentioned above.
Doing anything else would require the table to map from function+pin to
mux value, i.e. require enumerating all functions.

> > * pinmux properties in device drivers should list the muxable entities
> > that they use, and the mux function for each of them.

(sorry, s/device drivers/device DT nodes/)

> Following on the example above, we will need something below in SD node
> to specify each pin and corresponding function selection.
>
>         usdhc@02194000 { /* uSDHC2 */
>                 #pinmux-cells = <2>;
>                 // The second cell specify the index of the desired function of given pin
>                 pinmux = < &sd2_dat1 0
>                            &sd2_dat2 0
>                            ...        >;
>                 status = "okay";
>         };
>
> IMO, it's not nice for pinctrl client devices.

What exactly is it not convenient for?

That DT example seems convenient enough for the person writing the DT
node for the device; it's a pretty direct representation of how to set
up the HW. If we allow "virtual" pin groups to be defined by the SoC
.dtsi file, and have the device DT nodes refer to those by phandle, then
the content of the referenced DT nodes is going to be roughly exactly
that same pinmux property, so there's no difference in DT content, just
the extra complexity of having to look something up by phandle.

That said, as you pointed out, the referenced DT node could be written
by a SoC vendor, hence perhaps simplifying life for the OEM writing the
usdhc DT node.

Perhaps what we need is to run cpp on the DT before dtc, so that the
SoC .dtsi file can define these "predefined" pinmux configurations, and
device DT nodes can reference them simply, but we don't bloat the .dtb
with unused "predefined" pinmux nodes, or require phandle parsing:

soc.dtsi:

#define IMX_PMX_USDHC2_A pinmux = < SD2_DAT1 SD2_DAT2 0>;
#define IMX_PMX_USDHC2_B pinmux = < PINX 4 PINY 7>;

board.dts:

usdhc@02194000 { /* uSDHC2 */
    IMX_PMX_USDHC2_A
};

That seems to solve all the problems except that we'd need to work out
how to integrate cpp into dtc.

As far as the device driver goes, I think it's irrelevant. Do note how
I assume this would work:

The pinctrl subsystem handles all aspects of parsing the pinmux DT value,
Including converting it to the internal mapping table representation if
applicable, iterating over the N groups in the value (just like it may
iterate over n mapping table entries when not using DT) etc.

Drivers call pinmux_get()/pinmux_enable() a single time, just as if the
pinctrl mapping table were provided through a board file instead of DT.
Given this, the DT binding doesn't have any impact on how a driver uses
the pinctrl APIs.



> > > > This avoids
> > > > parsing a heck of a lot of data from device tree. That means there isn't
> > > > any per-function node that can be referred to by phandle. Does it make
> > > > sense to refer to groups and functions by string name or integer ID
> > > > instead of phandle? Perhaps:
> > > >
> > > > usdhc@0219c000 { /* uSDHC4 */
> > > >     fsl,card-wired;
> > > >     status = "okay";
> > > >     pinmux = {
> > > >             group@0 {
> > > >                     group = "foo";
> > > >                     function = "uart3";
> > > >                     /* You could add pin config options here too */
> > > >             };
> > > >             group@1 {
> > > >                     group = "baz";
> > > >                     function = "uart4";
> > > >             };
> > > >     };
> > > > };
> > > >
> > > > I guess referring to things by name isn't that idiomatic for device tree.
> > > > Using integers here would be fine too, so long as dtc gets support for
> > > > named constants:
> > > >
> > > > imx6q.dtsi:
> > > >
> > > > /define/ IMX_PINGRP_FOO 0
> > > > /define/ IMX_PINGRP_BAR 1
> > > > /define/ IMX_PINGRP_BAZ 2
> > > > /define/ IMX_PINFUNC_UART3 0
> > > > /define/ IMX_PINFUNC_UART4 1
> > > > ...
> > > >
> > > > board .dts:
> > > >
> > > > usdhc@0219c000 { /* uSDHC4 */
> > > >     fsl,card-wired;
> > > >     status = "okay";
> > > >     pinmux = {
> > > >             group@0 {
> > > >                     group = <IMX_PINGRP_FOO>;
> > > >                     function = <IMX_PINFUNC_UART3>;
> > > >                     /* You could add pin config options here too */
> > > >             };
> > > >             group@1 {
> > > >                     group = <IMX_PINGRP_BAZ>;
> > > >                     function = <IMX_PINFUNC_UART4>;
> > > >             };
> > > >     };
> > > > };
> >
> > So given that IMX muxes per pin not per group of pins, that "group"
> > property above should really be named "pin", and the IMX_PINGRP_* values
> > renamed IMX_PIN_* instead.
> >
> > In general, it'd be nice to come up with a binding for the users of
> > pinmux (i.e. the device nodes like usdhc above) that allowed them to
> > refer to what I've been calling "muxable entity". perhaps instead of
> > "pin" or "group" the property should be called "mux-point", and it's
> > up to the pinctrl driver to interpret that as a pin or group ID based
> > on what its muxable entities are.
>
> See, this can be easily standardised if we allow pingroup represented
> in device tree even though the muxable entity at HW level is pin.
> That said, we can always have 'pinctrl' property under client device
> node as the phandle to the pingroup that the device uses.

That just moves the issue.

If the pin/group/location/muxable-entity property in the device's node
is replaced with a phandle to some other "group" node, that just moves
the problem that that referenced "group" node. It still has to list the
set of pins/groups/locations/muxable-entities it uses, and you have the
same issue.

Ignoring any other arguments for reference stuff using phandles in the
device DT nodes, it seems simples to say that the pin/group/... values
use in the device DT nodes refer to either pins or groups, as determined
by the pinmux HW. That's pretty easy if the pinctrl core calls into a
function in the pinctrl driver to process each individual pin/group
value, just like the IRQ/GPIO/... subsystems defer flag parsing (and
even allow IRQ/GPIO ID mapping to be overridden, IIRC) to the individual
drivers.

> > > Doing this does not change the fact that this is bound with Linux
> > > driver details.  That said, if the indexing of either pingrp array
> > > or pinfunc array changes in the driver, the binding is broken.
> >
> > I don't agree here.
> >
> > Having a driver state that it wants "pin P" or "group G" to be programmed
> > to "mux function F" is very purely HW oriented.
> >
> > The fact this so closely aligns with the data model that the pinctrl
> > subsystem uses is simply because I pushed for the same pure HW oriented
> > data model in the pinctrl subsystem; both models were derived from how
> > the HW works, rather than the binding being derived from the driver.
> >
> > Equally, the binding for the individual pin mux HW will define what the
> > integer values for pin/group/function are. In practice, we will choose
> > the values that the Linux pinctrl driver uses to remove the need for
> > conversion when parsing the device tree. However, we should be very aware
> > that the binding is what specifies the values, not the driver, so if the
> > driver changes its internal representation, it must add conversion code
> > when parsing the device tree, not require the device tree to change.
> >
> > That said, I don't see why the pinctrl driver would change its pin, group,
> > or mux function numbering scheme for a given SoC; the HW is fixed, right?
>
> It's right for case like Tegra where the group is defined by HW, but
> it's not for case like imx, where there is no group defined at HW
> level.  For imx non-dt case, the pingroup is defined by pinctrl driver,
> thus the indexing of pingroup array can really be random.

Yes, for virtual pin groups, sure. I was talking about real HW pin numbers
or group numbers.

If you're talking about virtual groups, then they need to be referenced
by phandle rather than ID, so the issue doesn't arise.

--
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-12  8:36                     ` Dong Aisheng-B29396
@ 2012-01-12 20:56                       ` Stephen Warren
  2012-01-13  3:55                         ` Shawn Guo
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-12 20:56 UTC (permalink / raw)
  To: Dong Aisheng-B29396, Dong Aisheng
  Cc: linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org)

Dong Aisheng wrote at Thursday, January 12, 2012 1:36 AM:
> Stephen Warren wrote at Thursday, January 12, 2012 4:18 AM:
> > Dong Aisheng wrote at Tuesday, January 10, 2012 1:21 AM:
> > > Stephen Warren wrote at Saturday, January 07, 2012 2:03 AM:
...
> > Personally, I think I'd be OK with the sysfs pinctrl map file only containing
> > the map entries for devices that had used the pinctrl API, and hence only
> > parsing the pinmux properties in pinmux_get().
>
> Actually I already did it like that in the patch I sent:
> https://lkml.org/lkml/2012/1/5/153
> 
> Originally I'd like to do like that but I found an inconsistent issue that
> the sysfs pinctrl map file will behave differently between dt and non-dt
> Platform. For non-dt, it means showing all exist map entries. For dt, it means
> Only used pinmux map entries.
> 
> And in current design when device calls pinmux_get, it will search a predefined
> pinmux_maps array to find which function and group it is binded to.
> If switch to the new way, we only dynamically create pinmux map and dynamically
> register it when pinmux_get is called, first we need to change the code path in
> pinmux_get in a totally different way, second for support that we may also better
> to change pinmux_maps array to a list.
> But after changing the pinmux_maps to a list, what about using in non-dt?
> 
> So without any strong reason i still think it would be better to keep consistency
> With the non-dt pinctrl subsystem.
> And the effort would be minimum since besides constructing the map by parsing
> Device tree, everyting is the same as before in pinmux map and we could re-use
> the current code.

OK. I think this can work out pretty easily with a bus notifier as I
mentioned before.

But, one thought on doing this in pinmux_get(). I'd simply implement a
Function that read a DT node's pinmux property/node, converted it to a
pinmux mapping table, and registered it with the pinctrl core. Then,
pinmux_get() could simply call this before doing anything else at all.
I don't think you'd need to modify how pinmux_get() worked at all.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-12 20:46                       ` Stephen Warren
@ 2012-01-12 21:10                         ` Stephen Warren
  2012-01-13  3:46                         ` Shawn Guo
  1 sibling, 0 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-12 21:10 UTC (permalink / raw)
  To: Stephen Warren, Shawn Guo
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org),
	Richard Zhao

Stephen Warren wrote at Thursday, January 12, 2012 1:47 PM:
> Shawn Guo wrote at Wednesday, January 11, 2012 8:40 PM:
> > On Wed, Jan 11, 2012 at 10:17:40AM -0800, Stephen Warren wrote:
> ...
> > > So, my position is that:
> > >
> > > * Something (either the pinctrl driver, or the SoC .dtsi file) should
> > > enumerate all available muxable entities that exist in the SoC (pins for
> > > IMX, groups for Tegra).
> >
> > Yes, we enumerate all available pins in pinctrl driver for imx.
> >
> > > * Something (either the pinctrl driver, or the SoC .dtsi file) should
> > > enumerate all the available functions that can be assigned to a muxable
> > > entity.
> >
> > In theory, yes.  But I hope you would agree we do not need to
> > necessarily do this for case like imx.
> 
> Discussing just the Linux driver internals right now; ignoring device
> tree:
> 
> Pinctrl won't let you use a function on a pin/group if that function
> isn't enumerated and doesn't list that pin/group as a valid location
> for that function. Given that, I'm not sure how you can avoid enumerating
> all functions and their legal locations?

Or you can cheat a little:

Define 8 functions named func0, func1, func2, ... func7. Tell pinctrl
that each function is a legal option on every pin. That way, you've
enumerated all the valid functions, and so satisfied pinctrl's error-
checking, yet kept a tiny list of functions. That'd have the bonus side-
effect that the function IDs map very directly to what I assume is in
your HW manuals too!

I wonder if I shouldn't have done that for Tegra. The main reason I didn't
is because the old Tegra pinmux driver didn't.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-12 20:46                       ` Stephen Warren
  2012-01-12 21:10                         ` Stephen Warren
@ 2012-01-13  3:46                         ` Shawn Guo
  2012-01-13 18:16                           ` Stephen Warren
  1 sibling, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-13  3:46 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org),
	Richard Zhao

On Thu, Jan 12, 2012 at 12:46:52PM -0800, Stephen Warren wrote:
> Shawn Guo wrote at Wednesday, January 11, 2012 8:40 PM:
> > On Wed, Jan 11, 2012 at 10:17:40AM -0800, Stephen Warren wrote:
> ...
> > > So, my position is that:
> > >
> > > * Something (either the pinctrl driver, or the SoC .dtsi file) should
> > > enumerate all available muxable entities that exist in the SoC (pins for
> > > IMX, groups for Tegra).
> >
> > Yes, we enumerate all available pins in pinctrl driver for imx.
> >
> > > * Something (either the pinctrl driver, or the SoC .dtsi file) should
> > > enumerate all the available functions that can be assigned to a muxable
> > > entity.
> >
> > In theory, yes.  But I hope you would agree we do not need to
> > necessarily do this for case like imx.
> 
> Discussing just the Linux driver internals right now; ignoring device
> tree:
> 
> Pinctrl won't let you use a function on a pin/group if that function
> isn't enumerated and doesn't list that pin/group as a valid location
> for that function. Given that, I'm not sure how you can avoid enumerating
> all functions and their legal locations?
> 
I agree with you that we should enumerate all available functions in
pinctrl driver, if we want to stick to the original pinctrl subsystem
design.  But as you can see, this enumeration for case like imx is
going to be huge data.  We would rather have both pingroup and function
defined in respective board file as needed.  I know doing so actually
violates the original idea of pinctrl subsystem, and will have data
duplication among different board files.  But that's a compromise.
And even Linus.W agreed on this compromise in the thread below.

http://thread.gmane.org/gmane.linux.kernel/1223968/focus=1224470

All above is about non-dt case.  For dt case, we will have both pingroup
and function describe in dts, and that's way we are purchasing.

> > For imx6q example, we have 193 pins as the muxable entities, and for
> > each of those pin, there are 8 alternative functions.  Let's see what
> > we will have if we enumerate all the available functions for each pin.
> >
> > enum imx6q_pads {
> >         IMX6Q_SD2_DAT1 = 0,
> >         IMX6Q_SD2_DAT2 = 1,
> >         ...
> >         IMX6Q_NANDF_D7 = 192,
> > };
> >
> > enum imx6q_pad_sd2_dat1 {
> >         IMX6Q_PAD_SD2_DAT1__USDHC2_DAT1                       = 0,
> >         IMX6Q_PAD_SD2_DAT1__ECSPI5_SS0                        = 1,
> >         IMX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2            = 2,
> >         IMX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS          = 3,
> >         IMX6Q_PAD_SD2_DAT1__KPP_COL_7                 = 4,
> >         IMX6Q_PAD_SD2_DAT1__GPIO_1_14                 = 5,
> >         IMX6Q_PAD_SD2_DAT1__CCM_WAIT                  = 6,
> >         IMX6Q_PAD_SD2_DAT1__ANATOP_ANATOP_TESTO_0     = 7,
> > };
> >
> > enum imx6q_pad_sd2_dat2 {
> >         IMX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
> >         IMX6Q_PAD_SD2_DAT2__ECSPI5_SS1,
> >         IMX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3,
> >         IMX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD,
> >         IMX6Q_PAD_SD2_DAT2__KPP_ROW_6,
> >         IMX6Q_PAD_SD2_DAT2__GPIO_1_13,
> >         IMX6Q_PAD_SD2_DAT2__CCM_STOP,
> >         IMX6Q_PAD_SD2_DAT2__ANATOP_ANATOP_TESTO_1,
> > };
> >
> > ...
> >
> > enum imx6q_pad_nandf_d7 {
> >         IMX6Q_PAD_NANDF_D7__RAWNAND_D7,
> >         IMX6Q_PAD_NANDF_D7__USDHC2_DAT7,
> >         IMX6Q_PAD_NANDF_D7__GPU3D_GPU_DEBUG_OUT_7,
> >         IMX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT_23,
> >         IMX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT_23,
> >         IMX6Q_PAD_NANDF_D7__GPIO_2_7,
> >         IMX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7,
> >         IMX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7,
> > };
> >
> > We simply do not want to over bloat imx6q pinctrl driver with such
> > enumeration.
> 
> Yes, I see you'd end up with a huge number of function definitions here.
> 
> You may be able to avoid this by changing the way you name/number the
> functions though.
> 
> The example above has a unique function name for every individual signal.
> instead, can you name functions based on the controller they connect to?
> 
> So, instead of having:
> 
> IMX6Q_PAD_SD2_DAT1__USDHC2_DAT1
> IMX6Q_PAD_SD2_DAT2__USDHC2_DAT2
> IMX6Q_PAD_SD2_DAT3__USDHC2_DAT3
> IMX6Q_PAD_SD2_DAT4__USDHC2_DAT4
> 
> Can you replace this with a single:
> 
> IMX_FUNC_USDHC2
> 
So all 'enum imx6q_pad_*' goes away, and instead, we define macros
IMX_FUNC_* at controller basis, correct?

> Where the precise meaning of that function would vary slightly from pad
> to pad; it'd mean "whatever signal from the USDHC2 controller can be
> routed to this pad".
> 
> If a given pad could be mux'd to either of 2 (or n) signals from the same
> controller, you may need both IMX_FUNC_USDHC2 and IMX_FUNC_USDHC2_ALT to
> represent this.
> 
> Now, you'd also need a table that mapped from (pad, function) to
> mux register value, but at least this would avoid avoid having so many
> function names.
> 
> Does this help?
> 
Yes, it helps reduce the function names.  But I doubt the data we need
to represent will become less anyhow, since we need an extra mapping
table to find mux register value from (pad, function).

> In the Tegra pinctrl patches I posted, I did exactly this.
> 
> I guess there is irony here, since I'm arguing elsewhere to make the
> data model as close to the HW as possible, whereas here I'm arguing to
> use a slightly abstract representation for function number rather than
> the raw register mux values.
> 
Sometimes, people need compromise :)

> > You may want to suggest we put enumeration of both pins
> > and their functions into dts, so that the pinctrl driver can be clean.
> 
> Personally, I'd actually tend to shy away from that; I see little point
> putting this basic essentially static data into the .dts file just to
> parse it back out at boot time into what'll end up being the same tables.
> 
The point is that pinctrl driver will not have to accommodate all those
huge amount of data.  This is something similar to why we are pushing
common-clk frame work and moving all those clock data into device tree.

> > I'm not sure how that will look like in your mind, but it's something
> > like below in mine.
> >
> >         sd2_dat1: pin@0 {
> >                 alt-functions = < "USDHC2_DAT1"
> >                                   "ECSPI5_SS0"
> >                                   "WEIM_WEIM_CS_2"
> >                                   "AUDMUX_AUD4_TXFS"
> >                                   "KPP_COL_7"
> >                                   "GPIO_1_14"
> >                                   "CCM_WAIT"
> >                                   "ANATOP_ANATOP_TESTO_0" >;
> >         };
> >
> >         sd2_dat2: pin@1 {
> >                 alt-functions = < "USDHC2_DAT2"
> >                                   "ECSPI5_SS1"
> >                                   "WEIM_WEIM_CS_3"
> >                                   "AUDMUX_AUD4_TXD"
> >                                   "KPP_ROW_6"
> >                                   "GPIO_1_13"
> >                                   "CCM_STOP"
> >                                   "ANATOP_ANATOP_TESTO_1" >;
> >         };
> >
> > We will end up with having 193 such nodes in device tree.  I had one
> > patch trying to add pinmux support for imx5 with enumerating every
> > single pin in device tree (That's before pinctrl subsystem is born).
> > The patch concerned Grant a lot with that many nodes in device tree
> > and thus died.
> 
> Indeed.
> 
> > Besides the above concern, what's the point of enumerating all
> > available functions for each pin at all?  The client device will still
> > choose desired function with index/number.  See example below ...
> 
> As I mentioned above, the pinctrl subsystem currently requires it, since
> the mapping table contains the function name, which it must then convert
> to a function number, and then pass to the pinctrl driver.
> 
> As you point out though, this is just error-checking, and if the DT
> were to contain the function number directly (rather than the name),
> the pinctrl subsystem wouldn't have to convert name to number, but
> could just pass the number through to the pinctrl driver. So, in that
> scenario, the complete enumeration is only required for error-checking
> (did someone put something bogus in the DT?). As such, it would be
> technically possible to remove it. What does Linusw think about that?
> Personally, it seems like a bad idea to remove the error checking.
> 
I guess this checking still makes sense for non-dt case, where the
mapping table still uses name.

> Removing the error-checking would also require that the DT use the
> raw register mux values, rather than the abstraction I mentioned above.
> Doing anything else would require the table to map from function+pin to
> mux value, i.e. require enumerating all functions.
> 
Ideally, DT should just use the raw register mux values, since it's
supposed to describe the raw hardware.  But if there is a need of a
mapping between the value DT passes in and the raw hardware mux value,
it should be respective pinctrl driver's job the translate it.

> > > * pinmux properties in device drivers should list the muxable entities
> > > that they use, and the mux function for each of them.
> 
> (sorry, s/device drivers/device DT nodes/)
> 
> > Following on the example above, we will need something below in SD node
> > to specify each pin and corresponding function selection.
> >
> >         usdhc@02194000 { /* uSDHC2 */
> >                 #pinmux-cells = <2>;
> >                 // The second cell specify the index of the desired function of given pin
> >                 pinmux = < &sd2_dat1 0
> >                            &sd2_dat2 0
> >                            ...        >;
> >                 status = "okay";
> >         };
> >
> > IMO, it's not nice for pinctrl client devices.
> 
> What exactly is it not convenient for?
> 
I should have said it is not nice/convenient for people who write the
<board>.dts for their boards.

> That DT example seems convenient enough for the person writing the DT
> node for the device; it's a pretty direct representation of how to set
> up the HW. If we allow "virtual" pin groups to be defined by the SoC
> .dtsi file, and have the device DT nodes refer to those by phandle, then
> the content of the referenced DT nodes is going to be roughly exactly
> that same pinmux property, so there's no difference in DT content, just
> the extra complexity of having to look something up by phandle.
> 
> That said, as you pointed out, the referenced DT node could be written
> by a SoC vendor, hence perhaps simplifying life for the OEM writing the
> usdhc DT node.
> 
That's exactly my point.

> Perhaps what we need is to run cpp on the DT before dtc, so that the
> SoC .dtsi file can define these "predefined" pinmux configurations, and
> device DT nodes can reference them simply, but we don't bloat the .dtb
> with unused "predefined" pinmux nodes, or require phandle parsing:
> 
> soc.dtsi:
> 
> #define IMX_PMX_USDHC2_A pinmux = < SD2_DAT1 SD2_DAT2 0>;
> #define IMX_PMX_USDHC2_B pinmux = < PINX 4 PINY 7>;
> 
> board.dts:
> 
> usdhc@02194000 { /* uSDHC2 */
>     IMX_PMX_USDHC2_A
> };
> 
> That seems to solve all the problems except that we'd need to work out
> how to integrate cpp into dtc.
> 
> As far as the device driver goes, I think it's irrelevant. Do note how
> I assume this would work:
> 
> The pinctrl subsystem handles all aspects of parsing the pinmux DT value,
> Including converting it to the internal mapping table representation if
> applicable, iterating over the N groups in the value (just like it may
> iterate over n mapping table entries when not using DT) etc.
> 
> Drivers call pinmux_get()/pinmux_enable() a single time, just as if the
> pinctrl mapping table were provided through a board file instead of DT.
> Given this, the DT binding doesn't have any impact on how a driver uses
> the pinctrl APIs.
> 
The whole idea looks interesting and constructive, but IMHO, it's
unnecessarily complexer than "virtual pingroup" one.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-12 20:56                       ` Stephen Warren
@ 2012-01-13  3:55                         ` Shawn Guo
  2012-01-13  8:07                           ` Dong Aisheng-B29396
  0 siblings, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-13  3:55 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org)

On Thu, Jan 12, 2012 at 12:56:52PM -0800, Stephen Warren wrote:
> Dong Aisheng wrote at Thursday, January 12, 2012 1:36 AM:
> > Stephen Warren wrote at Thursday, January 12, 2012 4:18 AM:
> > > Dong Aisheng wrote at Tuesday, January 10, 2012 1:21 AM:
> > > > Stephen Warren wrote at Saturday, January 07, 2012 2:03 AM:
> ...
> > > Personally, I think I'd be OK with the sysfs pinctrl map file only containing
> > > the map entries for devices that had used the pinctrl API, and hence only
> > > parsing the pinmux properties in pinmux_get().
> >
> > Actually I already did it like that in the patch I sent:
> > https://lkml.org/lkml/2012/1/5/153
> > 
> > Originally I'd like to do like that but I found an inconsistent issue that
> > the sysfs pinctrl map file will behave differently between dt and non-dt
> > Platform. For non-dt, it means showing all exist map entries. For dt, it means
> > Only used pinmux map entries.
> > 
> > And in current design when device calls pinmux_get, it will search a predefined
> > pinmux_maps array to find which function and group it is binded to.
> > If switch to the new way, we only dynamically create pinmux map and dynamically
> > register it when pinmux_get is called, first we need to change the code path in
> > pinmux_get in a totally different way, second for support that we may also better
> > to change pinmux_maps array to a list.
> > But after changing the pinmux_maps to a list, what about using in non-dt?
> > 
> > So without any strong reason i still think it would be better to keep consistency
> > With the non-dt pinctrl subsystem.
> > And the effort would be minimum since besides constructing the map by parsing
> > Device tree, everyting is the same as before in pinmux map and we could re-use
> > the current code.
> 
> OK. I think this can work out pretty easily with a bus notifier as I
> mentioned before.
> 
> But, one thought on doing this in pinmux_get(). I'd simply implement a
> Function that read a DT node's pinmux property/node, converted it to a
> pinmux mapping table, and registered it with the pinctrl core. Then,
> pinmux_get() could simply call this before doing anything else at all.
> I don't think you'd need to modify how pinmux_get() worked at all.
> 
This sounds like a pretty good idea to me.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-13  3:55                         ` Shawn Guo
@ 2012-01-13  8:07                           ` Dong Aisheng-B29396
  2012-01-13 13:35                             ` Shawn Guo
  0 siblings, 1 reply; 98+ messages in thread
From: Dong Aisheng-B29396 @ 2012-01-13  8:07 UTC (permalink / raw)
  To: Shawn Guo, Stephen Warren
  Cc: Dong Aisheng, linux-kernel, linus.walleij, s.hauer, rob.herring,
	linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org)

> -----Original Message-----
> From: Shawn Guo [mailto:shawn.guo@linaro.org]
> Sent: Friday, January 13, 2012 11:55 AM
> To: Stephen Warren
> Cc: Dong Aisheng-B29396; Dong Aisheng; linux-kernel@vger.kernel.org;
> linus.walleij@stericsson.com; s.hauer@pengutronix.de; rob.herring@calxeda.com;
> linux-arm-kernel@lists.infradead.org; kernel@pengutronix.de; cjb@laptop.org;
> devicetree-discuss@lists.ozlabs.org; Simon Glass (sjg@chromium.org)
> Subject: Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux
> mappings
> Importance: High
> 
> On Thu, Jan 12, 2012 at 12:56:52PM -0800, Stephen Warren wrote:
> > Dong Aisheng wrote at Thursday, January 12, 2012 1:36 AM:
> > > Stephen Warren wrote at Thursday, January 12, 2012 4:18 AM:
> > > > Dong Aisheng wrote at Tuesday, January 10, 2012 1:21 AM:
> > > > > Stephen Warren wrote at Saturday, January 07, 2012 2:03 AM:
> > ...
> > > > Personally, I think I'd be OK with the sysfs pinctrl map file only
> > > > containing the map entries for devices that had used the pinctrl
> > > > API, and hence only parsing the pinmux properties in pinmux_get().
> > >
> > > Actually I already did it like that in the patch I sent:
> > > https://lkml.org/lkml/2012/1/5/153
> > >
> > > Originally I'd like to do like that but I found an inconsistent
> > > issue that the sysfs pinctrl map file will behave differently
> > > between dt and non-dt Platform. For non-dt, it means showing all
> > > exist map entries. For dt, it means Only used pinmux map entries.
> > >
> > > And in current design when device calls pinmux_get, it will search a
> > > predefined pinmux_maps array to find which function and group it is binded
> to.
> > > If switch to the new way, we only dynamically create pinmux map and
> > > dynamically register it when pinmux_get is called, first we need to
> > > change the code path in pinmux_get in a totally different way,
> > > second for support that we may also better to change pinmux_maps array to a
> list.
> > > But after changing the pinmux_maps to a list, what about using in non-dt?
> > >
> > > So without any strong reason i still think it would be better to
> > > keep consistency With the non-dt pinctrl subsystem.
> > > And the effort would be minimum since besides constructing the map
> > > by parsing Device tree, everyting is the same as before in pinmux
> > > map and we could re-use the current code.
> >
> > OK. I think this can work out pretty easily with a bus notifier as I
> > mentioned before.
> >
Sorry I did not catch your idea before.
I will try to see if I can find an example.

> > But, one thought on doing this in pinmux_get(). I'd simply implement a
> > Function that read a DT node's pinmux property/node, converted it to a
> > pinmux mapping table, and registered it with the pinctrl core. Then,
> > pinmux_get() could simply call this before doing anything else at all.
> > I don't think you'd need to modify how pinmux_get() worked at all.
> >
> This sounds like a pretty good idea to me.
> 
This does not fix the inconsistency issue.
Additionally as I said before, for better support dynamically register pinmux
Map, it looks we'd better change the pinmux_maps array to a list.
However this is for dt case.
But for non-dt case, the static array is just ok.
So there's conflict.
Not sure if any better idea to fix this.

Regards
Dong Aisheng


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-13  8:07                           ` Dong Aisheng-B29396
@ 2012-01-13 13:35                             ` Shawn Guo
  2012-01-13 13:48                               ` Linus Walleij
  0 siblings, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-13 13:35 UTC (permalink / raw)
  To: Dong Aisheng-B29396
  Cc: Stephen Warren, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org)

On Fri, Jan 13, 2012 at 08:07:35AM +0000, Dong Aisheng-B29396 wrote:
> > > But, one thought on doing this in pinmux_get(). I'd simply implement a
> > > Function that read a DT node's pinmux property/node, converted it to a
> > > pinmux mapping table, and registered it with the pinctrl core. Then,
> > > pinmux_get() could simply call this before doing anything else at all.
> > > I don't think you'd need to modify how pinmux_get() worked at all.
> > >
> > This sounds like a pretty good idea to me.
> > 
> This does not fix the inconsistency issue.
> Additionally as I said before, for better support dynamically register pinmux
> Map, it looks we'd better change the pinmux_maps array to a list.
> However this is for dt case.
> But for non-dt case, the static array is just ok.
> So there's conflict.
> Not sure if any better idea to fix this.
> 
My guess is that Linus.W did not get any chance to take the dt case
into account with his first design of pinctrl core.  But I guess he
is open to any reasonable change to pinctrl core for dt adoption.
Linus?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-13 13:35                             ` Shawn Guo
@ 2012-01-13 13:48                               ` Linus Walleij
  2012-01-13 14:23                                 ` Shawn Guo
  0 siblings, 1 reply; 98+ messages in thread
From: Linus Walleij @ 2012-01-13 13:48 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Dong Aisheng-B29396, Stephen Warren, Dong Aisheng, linux-kernel,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org)

On 01/13/2012 02:35 PM, Shawn Guo wrote:
> My guess is that Linus.W did not get any chance to take the dt case
> into account with his first design of pinctrl core.  But I guess he
> is open to any reasonable change to pinctrl core for dt adoption.
> Linus?

Any patches welcome.

However we cannot *require* DT for pinctrl to work, there
are archs that do not use DT and these must also be able
to use pinctrl. For example arch/blackfin have expressed
interest IIRC.

Then the question of whether to also support mixed configs
where some callers get data from DT and some from
platform data. I suspect that this is necessary for the
single kernel goal.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-13 13:48                               ` Linus Walleij
@ 2012-01-13 14:23                                 ` Shawn Guo
  0 siblings, 0 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-13 14:23 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Dong Aisheng-B29396, Stephen Warren, Dong Aisheng, linux-kernel,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org)

On Fri, Jan 13, 2012 at 02:48:29PM +0100, Linus Walleij wrote:
> On 01/13/2012 02:35 PM, Shawn Guo wrote:
> >My guess is that Linus.W did not get any chance to take the dt case
> >into account with his first design of pinctrl core.  But I guess he
> >is open to any reasonable change to pinctrl core for dt adoption.
> >Linus?
> 
> Any patches welcome.
> 
> However we cannot *require* DT for pinctrl to work, there
> are archs that do not use DT and these must also be able
> to use pinctrl. For example arch/blackfin have expressed
> interest IIRC.
> 
Definitely.

> Then the question of whether to also support mixed configs
> where some callers get data from DT and some from
> platform data. I suspect that this is necessary for the
> single kernel goal.
> 
Yes.  Right now, imx3, imx5 and imx6 have supported single kernel
image.  We probably can not convert these three platforms all over
to pinctrl subsystem at one time.  So we definitely need that
support to make the conversion/merge them one by one possible.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-11 20:17                   ` Stephen Warren
  2012-01-11 23:21                     ` Shawn Guo
  2012-01-12  8:36                     ` Dong Aisheng-B29396
@ 2012-01-13 17:11                     ` Dong Aisheng
  2012-01-13 18:33                       ` Stephen Warren
  2 siblings, 1 reply; 98+ messages in thread
From: Dong Aisheng @ 2012-01-13 17:11 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, linux-kernel, linus.walleij, s.hauer,
	rob.herring, linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org)

On Thu, Jan 12, 2012 at 4:17 AM, Stephen Warren <swarren@nvidia.com> wrote:
...
>> To keep consistency as the currently design of pinctrl subsystem and also meet
>> the dt design philosophy, we still do not introduce a pinmux map in dt.
>> Instead, we choose to scan all the device node with a 'pinmux' phandle to construct
>> a pinmux map table before register the pin controller device(here we may also scan
>> the hog_on_boot node) and I guess it's easy to do that.
> ...
>> (Without scan the device node to construct the pinmux map table, we can only get the map
>> Information when we run the pinmux_get.
>> See: https://lkml.org/lkml/2012/1/5/153
>> So no pinmux map table exists and we surely do not want to see that the sysfs exporting
>> pinmux map information works in dt but unwork in non-dt)
>
> Hmmm. I'm not sure that the pinctrl code should actively scan all nodes
> in the device tree for pin mux properties. That seems a little invasive;
> how does pinctrl know which nodes it really should be looking at, and
> which nodes are random internal parts of some device's custom binding?
>
> Personally, I think I'd be OK with the sysfs pinctrl map file only
> containing the map entries for devices that had used the pinctrl API,
> and hence only parsing the pinmux properties in pinmux_get().
>
> However, we could perhaps do better by registering a bus notifier, and
> pro-actively parsing the top-level DT node (if there is one) for every
> device that is created. That way, the mapping would be parsed as soon
> as the device was created (or perhaps after probe?).
>
After refer to usb bus notifier, usb core will register a bus notifier.
When a new usb bus is registered, it will notify the usb core for a
new bus added.

So i guess you mean pinctrl core provides a notifier to handle the map
creation when new map is found during parsing each device node, right?
But it seems parsing of device node and creation of device is at the very early
stage when call of_platform_populate in .init_machine code and pinctrl subsystem
may still have not change to run to register a bus notifier.
And i'm not sure it's the right place for of_platform.c to handle
pinmux things when create new devices.
I wonder it may not work for pinmux map case.
If pinctrl core does not provide notifier, who else can be the right
one to privide it?

> The only case this
> might not cover is DT nodes for which the kernel doesn't actually have
> a driver, and hence no device is created.
>
Per my understanding, the device creation should be independent on the driver.
I don't know why no device is created if not have a driver.
Did i miss something?

Regards
Dong Aisheng

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-13  3:46                         ` Shawn Guo
@ 2012-01-13 18:16                           ` Stephen Warren
  2012-01-14  1:22                             ` Shawn Guo
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-13 18:16 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org),
	Richard Zhao

Shawn Guo wrote at Thursday, January 12, 2012 8:46 PM:
> On Thu, Jan 12, 2012 at 12:46:52PM -0800, Stephen Warren wrote:
> > Shawn Guo wrote at Wednesday, January 11, 2012 8:40 PM:
> > > On Wed, Jan 11, 2012 at 10:17:40AM -0800, Stephen Warren wrote:
> > ...
> > > > So, my position is that:
> > > >
> > > > * Something (either the pinctrl driver, or the SoC .dtsi file) should
> > > > enumerate all available muxable entities that exist in the SoC (pins for
> > > > IMX, groups for Tegra).
> > >
> > > Yes, we enumerate all available pins in pinctrl driver for imx.
> > >
> > > > * Something (either the pinctrl driver, or the SoC .dtsi file) should
> > > > enumerate all the available functions that can be assigned to a muxable
> > > > entity.
> > >
> > > In theory, yes.  But I hope you would agree we do not need to
> > > necessarily do this for case like imx.
> >
> > Discussing just the Linux driver internals right now; ignoring device
> > tree:
> >
> > Pinctrl won't let you use a function on a pin/group if that function
> > isn't enumerated and doesn't list that pin/group as a valid location
> > for that function. Given that, I'm not sure how you can avoid enumerating
> > all functions and their legal locations?
>
> I agree with you that we should enumerate all available functions in
> pinctrl driver, if we want to stick to the original pinctrl subsystem
> design.  But as you can see, this enumeration for case like imx is
> going to be huge data.  We would rather have both pingroup and function
> defined in respective board file as needed.  I know doing so actually
> violates the original idea of pinctrl subsystem, and will have data
> duplication among different board files.  But that's a compromise.
> And even Linus.W agreed on this compromise in the thread below.
> 
> http://thread.gmane.org/gmane.linux.kernel/1223968/focus=1224470
> 
> All above is about non-dt case.  For dt case, we will have both pingroup
> and function describe in dts, and that's way we are purchasing.

For reference, that message is:

Linusw wrote:
> On Mon, Dec 5, 2011 at 3:43 AM, Dong Aisheng <dongas86 <at> gmail.com> wrote:
> > My current plan is to define all (might be frequently) used functoin
> > and groups for the exist upstreamed board like 53 Loco and etc, is
> > that ok?
>
> Yes, but do it in respective board file, so if we say, one day
> stops to support a certain board we can just delete that board
> file and be done with it.
>
> Plus this gives us a nice separation as we move toward
> device trees. (I think.)

My interpretation of what Dong wrote there is "I'm only going to define
the functions and groups that are actually in use by upstream boards,
not everything the SoC supports". However, your (Shawn's) references to
the email, it sounds like you're interpreting what Dong wrong as "I'm
going to define some virtual groups that don't exist in HW but represent
common use-cases of the HW".

Admittedly, the wording of Linusw's actually seems to agree more with how
you're interpreting what Dong said, but in that case, I don't think his
reply makes sense - the whole purpose of the mux mapping table is to
represent the board-specific configuration. If we're going to circumvent
it, we should completely remove it from the pinctrl subsystem, rather than
having some boards avoid using it by creating virtual pin groups instead.

> > > For imx6q example, we have 193 pins as the muxable entities, and for
> > > each of those pin, there are 8 alternative functions.  Let's see what
> > > we will have if we enumerate all the available functions for each pin.
...
> > > We simply do not want to over bloat imx6q pinctrl driver with such
> > > enumeration.
> >
> > Yes, I see you'd end up with a huge number of function definitions here.
> >
> > You may be able to avoid this by changing the way you name/number the
> > functions though.
> >
> > The example above has a unique function name for every individual signal.
> > instead, can you name functions based on the controller they connect to?
> >
> > So, instead of having:
> >
> > IMX6Q_PAD_SD2_DAT1__USDHC2_DAT1
> > IMX6Q_PAD_SD2_DAT2__USDHC2_DAT2
> > IMX6Q_PAD_SD2_DAT3__USDHC2_DAT3
> > IMX6Q_PAD_SD2_DAT4__USDHC2_DAT4
> >
> > Can you replace this with a single:
> >
> > IMX_FUNC_USDHC2
>
> So all 'enum imx6q_pad_*' goes away, and instead, we define macros
> IMX_FUNC_* at controller basis, correct?

Yes, something like that. The best set to choose probably differs based
on the SoC and its mux capabilities. But thinking more, if you're going
along this kind of route, I'd prefer to just define the "func0", "func1",
... "func7" functions that represent the raw HW selection instead.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-13 17:11                     ` Dong Aisheng
@ 2012-01-13 18:33                       ` Stephen Warren
  2012-01-14  1:10                         ` Shawn Guo
  2012-01-14 17:58                         ` Dong Aisheng
  0 siblings, 2 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-13 18:33 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: Dong Aisheng-B29396, linux-kernel, linus.walleij, s.hauer,
	rob.herring, linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org)

Dong Aisheng wrote at Friday, January 13, 2012 10:12 AM:
> On Thu, Jan 12, 2012 at 4:17 AM, Stephen Warren <swarren@nvidia.com> wrote:
> ...
> >> To keep consistency as the currently design of pinctrl subsystem and also meet
> >> the dt design philosophy, we still do not introduce a pinmux map in dt.
> >> Instead, we choose to scan all the device node with a 'pinmux' phandle to construct
> >> a pinmux map table before register the pin controller device(here we may also scan
> >> the hog_on_boot node) and I guess it's easy to do that.
> > ...
> >> (Without scan the device node to construct the pinmux map table, we can only get the map
> >> Information when we run the pinmux_get.
> >> See: https://lkml.org/lkml/2012/1/5/153
> >> So no pinmux map table exists and we surely do not want to see that the sysfs exporting
> >> pinmux map information works in dt but unwork in non-dt)
> >
> > Hmmm. I'm not sure that the pinctrl code should actively scan all nodes
> > in the device tree for pin mux properties. That seems a little invasive;
> > how does pinctrl know which nodes it really should be looking at, and
> > which nodes are random internal parts of some device's custom binding?
> >
> > Personally, I think I'd be OK with the sysfs pinctrl map file only
> > containing the map entries for devices that had used the pinctrl API,
> > and hence only parsing the pinmux properties in pinmux_get().
> >
> > However, we could perhaps do better by registering a bus notifier, and
> > pro-actively parsing the top-level DT node (if there is one) for every
> > device that is created. That way, the mapping would be parsed as soon
> > as the device was created (or perhaps after probe?).
>
> After refer to usb bus notifier, usb core will register a bus notifier.
> When a new usb bus is registered, it will notify the usb core for a
> new bus added.
> 
> So i guess you mean pinctrl core provides a notifier to handle the map
> creation when new map is found during parsing each device node, right?

Yes.

> But it seems parsing of device node and creation of device is at the very early
> stage when call of_platform_populate in .init_machine code and pinctrl subsystem
> may still have not change to run to register a bus notifier.

That's possible. There are some early initcalls that might work out
fine for this, but...

> And i'm not sure it's the right place for of_platform.c to handle
> pinmux things when create new devices.

So of_device_alloc(), which is called by of_platform_populate() for each
device, already parses basic DT content such as reg and interrupts, and
converts them to Linux resources. I'd consider parsing any pinmux properties
and registering them with the pinctrl subsystem to be of a similar nature,
so adding some code to of_device_alloc() that calls a core pinmux function
to parse the DT node seems reasonable to me.

> I wonder it may not work for pinmux map case.
> If pinctrl core does not provide notifier, who else can be the right
> one to privide it?
> 
> > The only case this
> > might not cover is DT nodes for which the kernel doesn't actually have
> > a driver, and hence no device is created.
>
> Per my understanding, the device creation should be independent on the driver.
> I don't know why no device is created if not have a driver.
> Did i miss something?

Yes, I think the device gets created irrespective, so this isn't actually a problem

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-13 18:33                       ` Stephen Warren
@ 2012-01-14  1:10                         ` Shawn Guo
  2012-01-17 19:35                           ` Stephen Warren
  2012-01-14 17:58                         ` Dong Aisheng
  1 sibling, 1 reply; 98+ messages in thread
From: Shawn Guo @ 2012-01-14  1:10 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng, Dong Aisheng-B29396, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org),
	Grant Likely

On Fri, Jan 13, 2012 at 10:33:21AM -0800, Stephen Warren wrote:
> So of_device_alloc(), which is called by of_platform_populate() for each
> device, already parses basic DT content such as reg and interrupts, and
> converts them to Linux resources. I'd consider parsing any pinmux properties
> and registering them with the pinctrl subsystem to be of a similar nature,
> so adding some code to of_device_alloc() that calls a core pinmux function
> to parse the DT node seems reasonable to me.
> 
I hardly believe that device tree maintainers would agree here.
Grant, Rob?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-13 18:16                           ` Stephen Warren
@ 2012-01-14  1:22                             ` Shawn Guo
  2012-01-14 18:21                               ` Dong Aisheng
  2012-01-16 16:08                               ` Linus Walleij
  0 siblings, 2 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-14  1:22 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, Dong Aisheng, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org),
	Richard Zhao

On Fri, Jan 13, 2012 at 10:16:36AM -0800, Stephen Warren wrote:
...
> For reference, that message is:
> 
> Linusw wrote:
> > On Mon, Dec 5, 2011 at 3:43 AM, Dong Aisheng <dongas86 <at> gmail.com> wrote:
> > > My current plan is to define all (might be frequently) used functoin
> > > and groups for the exist upstreamed board like 53 Loco and etc, is
> > > that ok?
> >
> > Yes, but do it in respective board file, so if we say, one day
> > stops to support a certain board we can just delete that board
> > file and be done with it.
> >
> > Plus this gives us a nice separation as we move toward
> > device trees. (I think.)
> 
> My interpretation of what Dong wrote there is "I'm only going to define
> the functions and groups that are actually in use by upstream boards,
> not everything the SoC supports". However, your (Shawn's) references to
> the email, it sounds like you're interpreting what Dong wrong as "I'm
> going to define some virtual groups that don't exist in HW but represent
> common use-cases of the HW".
> 
Then what does the word 'groups' in Dong's sentence means with your
understanding, considering there is no HW level pingroup on imx?

> Admittedly, the wording of Linusw's actually seems to agree more with how
> you're interpreting what Dong said, but in that case, I don't think his
> reply makes sense - the whole purpose of the mux mapping table is to
> represent the board-specific configuration. If we're going to circumvent
> it, we should completely remove it from the pinctrl subsystem, rather than
> having some boards avoid using it by creating virtual pin groups instead.
> 
IMO, it's a compromise.  It still makes sense to have concept of
pingroup in pinctrl subsystem, because platforms like Tegra have
the HW pingroup.

> > > > For imx6q example, we have 193 pins as the muxable entities, and for
> > > > each of those pin, there are 8 alternative functions.  Let's see what
> > > > we will have if we enumerate all the available functions for each pin.
> ...
> > > > We simply do not want to over bloat imx6q pinctrl driver with such
> > > > enumeration.
> > >
> > > Yes, I see you'd end up with a huge number of function definitions here.
> > >
> > > You may be able to avoid this by changing the way you name/number the
> > > functions though.
> > >
> > > The example above has a unique function name for every individual signal.
> > > instead, can you name functions based on the controller they connect to?
> > >
> > > So, instead of having:
> > >
> > > IMX6Q_PAD_SD2_DAT1__USDHC2_DAT1
> > > IMX6Q_PAD_SD2_DAT2__USDHC2_DAT2
> > > IMX6Q_PAD_SD2_DAT3__USDHC2_DAT3
> > > IMX6Q_PAD_SD2_DAT4__USDHC2_DAT4
> > >
> > > Can you replace this with a single:
> > >
> > > IMX_FUNC_USDHC2
> >
> > So all 'enum imx6q_pad_*' goes away, and instead, we define macros
> > IMX_FUNC_* at controller basis, correct?
> 
> Yes, something like that. The best set to choose probably differs based
> on the SoC and its mux capabilities. But thinking more, if you're going
> along this kind of route, I'd prefer to just define the "func0", "func1",
> ... "func7" functions that represent the raw HW selection instead.
> 
In this case, I do not see any point to define them, since it does not
make too much difference than integer 0, 1, ..., 7.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-13 18:33                       ` Stephen Warren
  2012-01-14  1:10                         ` Shawn Guo
@ 2012-01-14 17:58                         ` Dong Aisheng
  2012-01-17 19:44                           ` Stephen Warren
  1 sibling, 1 reply; 98+ messages in thread
From: Dong Aisheng @ 2012-01-14 17:58 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Dong Aisheng-B29396, linux-kernel, linus.walleij, s.hauer,
	rob.herring, linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org)

On Sat, Jan 14, 2012 at 2:33 AM, Stephen Warren <swarren@nvidia.com> wrote:
> Dong Aisheng wrote at Friday, January 13, 2012 10:12 AM:
>> On Thu, Jan 12, 2012 at 4:17 AM, Stephen Warren <swarren@nvidia.com> wrote:
>> ...
>> >> To keep consistency as the currently design of pinctrl subsystem and also meet
>> >> the dt design philosophy, we still do not introduce a pinmux map in dt.
>> >> Instead, we choose to scan all the device node with a 'pinmux' phandle to construct
>> >> a pinmux map table before register the pin controller device(here we may also scan
>> >> the hog_on_boot node) and I guess it's easy to do that.
>> > ...
>> >> (Without scan the device node to construct the pinmux map table, we can only get the map
>> >> Information when we run the pinmux_get.
>> >> See: https://lkml.org/lkml/2012/1/5/153
>> >> So no pinmux map table exists and we surely do not want to see that the sysfs exporting
>> >> pinmux map information works in dt but unwork in non-dt)
>> >
>> > Hmmm. I'm not sure that the pinctrl code should actively scan all nodes
>> > in the device tree for pin mux properties. That seems a little invasive;
>> > how does pinctrl know which nodes it really should be looking at, and
>> > which nodes are random internal parts of some device's custom binding?
>> >
>> > Personally, I think I'd be OK with the sysfs pinctrl map file only
>> > containing the map entries for devices that had used the pinctrl API,
>> > and hence only parsing the pinmux properties in pinmux_get().
>> >
>> > However, we could perhaps do better by registering a bus notifier, and
>> > pro-actively parsing the top-level DT node (if there is one) for every
>> > device that is created. That way, the mapping would be parsed as soon
>> > as the device was created (or perhaps after probe?).
>>
>> After refer to usb bus notifier, usb core will register a bus notifier.
>> When a new usb bus is registered, it will notify the usb core for a
>> new bus added.
>>
>> So i guess you mean pinctrl core provides a notifier to handle the map
>> creation when new map is found during parsing each device node, right?
>
> Yes.
>
>> But it seems parsing of device node and creation of device is at the very early
>> stage when call of_platform_populate in .init_machine code and pinctrl subsystem
>> may still have not change to run to register a bus notifier.
>
> That's possible. There are some early initcalls that might work out
> fine for this,
Ok, looks .init_machine is the level of ARCH_INIT, will try a earlier one.
and we may add that init function in pinctrl core if it's reasonable.

> but...
but what?

>
>> And i'm not sure it's the right place for of_platform.c to handle
>> pinmux things when create new devices.
>
> So of_device_alloc(), which is called by of_platform_populate() for each
> device, already parses basic DT content such as reg and interrupts, and
> converts them to Linux resources. I'd consider parsing any pinmux properties
> and registering them with the pinctrl subsystem to be of a similar nature,
> so adding some code to of_device_alloc() that calls a core pinmux function
> to parse the DT node seems reasonable to me.
>
It's not perfect to me since pinmux map looks not the pure hw
conception like reg/int.
but i wonder if we can find a better way, (scanning?)

>> I wonder it may not work for pinmux map case.
>> If pinctrl core does not provide notifier, who else can be the right
>> one to privide it?
>>
>> > The only case this
>> > might not cover is DT nodes for which the kernel doesn't actually have
>> > a driver, and hence no device is created.
>>
>> Per my understanding, the device creation should be independent on the driver.
>> I don't know why no device is created if not have a driver.
>> Did i miss something?
>
> Yes, I think the device gets created irrespective, so this isn't actually a problem
>
> --
> nvpublic
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-14  1:22                             ` Shawn Guo
@ 2012-01-14 18:21                               ` Dong Aisheng
  2012-01-16 16:08                               ` Linus Walleij
  1 sibling, 0 replies; 98+ messages in thread
From: Dong Aisheng @ 2012-01-14 18:21 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Stephen Warren, Dong Aisheng-B29396, linux-kernel, linus.walleij,
	s.hauer, rob.herring, linux-arm-kernel, kernel, cjb,
	devicetree-discuss, Simon Glass (sjg@chromium.org),
	Richard Zhao

On Sat, Jan 14, 2012 at 9:22 AM, Shawn Guo <shawn.guo@linaro.org> wrote:
> On Fri, Jan 13, 2012 at 10:16:36AM -0800, Stephen Warren wrote:
> ...
>> For reference, that message is:
>>
>> Linusw wrote:
>> > On Mon, Dec 5, 2011 at 3:43 AM, Dong Aisheng <dongas86 <at> gmail.com> wrote:
>> > > My current plan is to define all (might be frequently) used functoin
>> > > and groups for the exist upstreamed board like 53 Loco and etc, is
>> > > that ok?
>> >
>> > Yes, but do it in respective board file, so if we say, one day
>> > stops to support a certain board we can just delete that board
>> > file and be done with it.
>> >
>> > Plus this gives us a nice separation as we move toward
>> > device trees. (I think.)
>>
>> My interpretation of what Dong wrote there is "I'm only going to define
>> the functions and groups that are actually in use by upstream boards,
>> not everything the SoC supports". However, your (Shawn's) references to
>> the email, it sounds like you're interpreting what Dong wrong as "I'm
>> going to define some virtual groups that don't exist in HW but represent
>> common use-cases of the HW".
>>
> Then what does the word 'groups' in Dong's sentence means with your
> understanding, considering there is no HW level pingroup on imx?
>
>> Admittedly, the wording of Linusw's actually seems to agree more with how
>> you're interpreting what Dong said, but in that case, I don't think his
>> reply makes sense - the whole purpose of the mux mapping table is to
>> represent the board-specific configuration. If we're going to circumvent
>> it, we should completely remove it from the pinctrl subsystem, rather than
>> having some boards avoid using it by creating virtual pin groups instead.
>>
> IMO, it's a compromise.  It still makes sense to have concept of
> pingroup in pinctrl subsystem, because platforms like Tegra have
> the HW pingroup.
>
IMO can we the 'virtual' pin groups for IMX first in this very first step?
At least we found it works for IMX and easy to us and it's also
suitable for Tegra
, maybe others too. It also meets the design of current pinctrl subsystem.
And we can discuss and add individual pin support for dt later if really need,
that could avoid introducing much complexity for pinctrl dt support in
the first.

Beside although IMX does not group the pins together as a separate unit,
usually the pins are used in 'predefined' groups(from the meaning of pad name)
in most cases.
I think it's ok to think those pins a hw group:
like SD1_CMD, SD1_CLK, SD1_DAT0..SD1_DAT7 although those pins can also
be used as other function.

Regards
Dong Aisheng

>> > > > For imx6q example, we have 193 pins as the muxable entities, and for
>> > > > each of those pin, there are 8 alternative functions.  Let's see what
>> > > > we will have if we enumerate all the available functions for each pin.
>> ...
>> > > > We simply do not want to over bloat imx6q pinctrl driver with such
>> > > > enumeration.
>> > >
>> > > Yes, I see you'd end up with a huge number of function definitions here.
>> > >
>> > > You may be able to avoid this by changing the way you name/number the
>> > > functions though.
>> > >
>> > > The example above has a unique function name for every individual signal.
>> > > instead, can you name functions based on the controller they connect to?
>> > >
>> > > So, instead of having:
>> > >
>> > > IMX6Q_PAD_SD2_DAT1__USDHC2_DAT1
>> > > IMX6Q_PAD_SD2_DAT2__USDHC2_DAT2
>> > > IMX6Q_PAD_SD2_DAT3__USDHC2_DAT3
>> > > IMX6Q_PAD_SD2_DAT4__USDHC2_DAT4
>> > >
>> > > Can you replace this with a single:
>> > >
>> > > IMX_FUNC_USDHC2
>> >
>> > So all 'enum imx6q_pad_*' goes away, and instead, we define macros
>> > IMX_FUNC_* at controller basis, correct?
>>
>> Yes, something like that. The best set to choose probably differs based
>> on the SoC and its mux capabilities. But thinking more, if you're going
>> along this kind of route, I'd prefer to just define the "func0", "func1",
>> ... "func7" functions that represent the raw HW selection instead.
>>
> In this case, I do not see any point to define them, since it does not
> make too much difference than integer 0, 1, ..., 7.
>
> --
> Regards,
> Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-14  1:22                             ` Shawn Guo
  2012-01-14 18:21                               ` Dong Aisheng
@ 2012-01-16 16:08                               ` Linus Walleij
  2012-01-17  2:32                                 ` Shawn Guo
  2012-01-17 19:50                                 ` Stephen Warren
  1 sibling, 2 replies; 98+ messages in thread
From: Linus Walleij @ 2012-01-16 16:08 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Stephen Warren, linus.walleij, s.hauer, linux-kernel,
	rob.herring, Richard Zhao, kernel, cjb, devicetree-discuss,
	linux-arm-kernel, Dong Aisheng

On Sat, Jan 14, 2012 at 2:22 AM, Shawn Guo <shawn.guo@linaro.org> wrote:
> On Fri, Jan 13, 2012 at 10:16:36AM -0800, Stephen Warren wrote:
>> Admittedly, the wording of Linusw's actually seems to agree more with how
>> you're interpreting what Dong said, but in that case, I don't think his
>> reply makes sense - the whole purpose of the mux mapping table is to
>> represent the board-specific configuration. If we're going to circumvent
>> it, we should completely remove it from the pinctrl subsystem, rather than
>> having some boards avoid using it by creating virtual pin groups instead.
>>
> IMO, it's a compromise.  It still makes sense to have concept of
> pingroup in pinctrl subsystem, because platforms like Tegra have
> the HW pingroup.

I'm not able to follow this discussion, it's too much stuff here that I don't
quite grasp :-(

The pinctrl idea of a group is defined in Documentation/pinctrl.txt:


---------------------8<---------------------------8<-----------------------------

Pin groups
==========

Many controllers need to deal with groups of pins, so the pin controller
subsystem has a mechanism for enumerating groups of pins and retrieving the
actual enumerated pins that are part of a certain group.

For example, say that we have a group of pins dealing with an SPI interface
on { 0, 8, 16, 24 }, and a group of pins dealing with an I2C interface on pins
on { 24, 25 }.

These two groups are presented to the pin control subsystem by implementing
some generic pinctrl_ops like this:

#include <linux/pinctrl/pinctrl.h>

struct foo_group {
        const char *name;
        const unsigned int *pins;
        const unsigned num_pins;
};

static const unsigned int spi0_pins[] = { 0, 8, 16, 24 };
static const unsigned int i2c0_pins[] = { 24, 25 };

static const struct foo_group foo_groups[] = {
        {
                .name = "spi0_grp",
                .pins = spi0_pins,
                .num_pins = ARRAY_SIZE(spi0_pins),
        },
        {
                .name = "i2c0_grp",
                .pins = i2c0_pins,
                .num_pins = ARRAY_SIZE(i2c0_pins),
        },
};

static int foo_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
{
        if (selector >= ARRAY_SIZE(foo_groups))
                return -EINVAL;
        return 0;
}

static const char *foo_get_group_name(struct pinctrl_dev *pctldev,
                                       unsigned selector)
{
        return foo_groups[selector].name;
}

static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
                               unsigned ** const pins,
                               unsigned * const num_pins)
{
        *pins = (unsigned *) foo_groups[selector].pins;
        *num_pins = foo_groups[selector].num_pins;
        return 0;
}

static struct pinctrl_ops foo_pctrl_ops = {
        .list_groups = foo_list_groups,
        .get_group_name = foo_get_group_name,
        .get_group_pins = foo_get_group_pins,
};


static struct pinctrl_desc foo_desc = {
       ...
       .pctlops = &foo_pctrl_ops,
};

The pin control subsystem will call the .list_groups() function repeatedly
beginning on 0 until it returns non-zero to determine legal selectors, then
it will call the other functions to retrieve the name and pins of the group.
Maintaining the data structure of the groups is up to the driver, this is
just a simple example - in practice you may need more entries in your group
structure, for example specific register ranges associated with each group
and so on.

---------------------8<---------------------------8<-----------------------------


As you can see none of the text above claims that the group is
about hardware-defined groups or anything like that. The groups
are just that - a group of pins, an abstract concept of a group.
It could be drawn i UML even... maybe I'll do that for my
ELC presentation :-)

Then when we come to pinmux, which is slightly different
involving the definitions of a function and mappings between
functions and one or more pin groups as per above, which is
something completely different and seems to be what you're
discussing here?

For hardware that does handle pins in groups there are
special functions that can be used in the drivers like
configuring a whole group (which falls back to iterating
over pins if there is no such callback, showing again that
this is a theoretical concept) so if the hardware handles
pins in groups its a good idea to match group definitions
1-to-1 with these, but for hardware that doesn't there is
some freedom of how to use the groups.

I don't know if this helps though the discussion here seems
a bit contended :-/

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-16 16:08                               ` Linus Walleij
@ 2012-01-17  2:32                                 ` Shawn Guo
  2012-01-17 19:50                                 ` Stephen Warren
  1 sibling, 0 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-17  2:32 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Stephen Warren, linus.walleij, s.hauer, linux-kernel,
	rob.herring, Richard Zhao, kernel, cjb, devicetree-discuss,
	linux-arm-kernel, Dong Aisheng

On Mon, Jan 16, 2012 at 05:08:57PM +0100, Linus Walleij wrote:
...
> As you can see none of the text above claims that the group is
> about hardware-defined groups or anything like that. The groups
> are just that - a group of pins, an abstract concept of a group.

Ok, the thing gets clarified.  The concept of group is a abstract at
software level.  It does not necessarily require a pin group defined
by raw hardware underneath, which is basically my argument.

> It could be drawn i UML even... maybe I'll do that for my
> ELC presentation :-)
> 
> Then when we come to pinmux, which is slightly different
> involving the definitions of a function and mappings between
> functions and one or more pin groups as per above, which is
> something completely different and seems to be what you're
> discussing here?
> 
> For hardware that does handle pins in groups there are
> special functions that can be used in the drivers like
> configuring a whole group (which falls back to iterating
> over pins if there is no such callback, showing again that
> this is a theoretical concept) so if the hardware handles
> pins in groups its a good idea to match group definitions
> 1-to-1 with these, but for hardware that doesn't there is
> some freedom of how to use the groups.
> 
> I don't know if this helps though the discussion here seems
> a bit contended :-/
> 
It does help to me.  Thanks, Linus.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-14  1:10                         ` Shawn Guo
@ 2012-01-17 19:35                           ` Stephen Warren
  2012-01-17 19:48                             ` Rob Herring
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-17 19:35 UTC (permalink / raw)
  To: Grant Likely (grant.likely@secretlab.ca), rob.herring
  Cc: Dong Aisheng, Dong Aisheng-B29396, linux-kernel, linus.walleij,
	s.hauer, linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org), Shawn Guo (shawn.guo@linaro.org)

Shawn Guo wrote at Friday, January 13, 2012 6:11 PM:
> On Fri, Jan 13, 2012 at 10:33:21AM -0800, Stephen Warren wrote:
> > So of_device_alloc(), which is called by of_platform_populate() for each
> > device, already parses basic DT content such as reg and interrupts, and
> > converts them to Linux resources. I'd consider parsing any pinmux properties
> > and registering them with the pinctrl subsystem to be of a similar nature,
> > so adding some code to of_device_alloc() that calls a core pinmux function
> > to parse the DT node seems reasonable to me.
>
> I hardly believe that device tree maintainers would agree here.
> Grant, Rob?

I'm explicitly putting Grant and Rob on the To line here to make this
question stand out to them.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-14 17:58                         ` Dong Aisheng
@ 2012-01-17 19:44                           ` Stephen Warren
  0 siblings, 0 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-17 19:44 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: Dong Aisheng-B29396, linux-kernel, linus.walleij, s.hauer,
	rob.herring, linux-arm-kernel, kernel, cjb, devicetree-discuss,
	Simon Glass (sjg@chromium.org), Shawn Guo (shawn.guo@linaro.org)

Dong Aisheng wrote at Saturday, January 14, 2012 10:58 AM:
> On Sat, Jan 14, 2012 at 2:33 AM, Stephen Warren <swarren@nvidia.com> wrote:
> > Dong Aisheng wrote at Friday, January 13, 2012 10:12 AM:
> >> On Thu, Jan 12, 2012 at 4:17 AM, Stephen Warren <swarren@nvidia.com> wrote:
> >> ...
> >> >> To keep consistency as the currently design of pinctrl subsystem and also meet
> >> >> the dt design philosophy, we still do not introduce a pinmux map in dt.
> >> >> Instead, we choose to scan all the device node with a 'pinmux' phandle to construct
> >> >> a pinmux map table before register the pin controller device(here we may also scan
> >> >> the hog_on_boot node) and I guess it's easy to do that.
> >> > ...
> >> >> (Without scan the device node to construct the pinmux map table, we can only get the map
> >> >> Information when we run the pinmux_get.
> >> >> See: https://lkml.org/lkml/2012/1/5/153
> >> >> So no pinmux map table exists and we surely do not want to see that the sysfs exporting
> >> >> pinmux map information works in dt but unwork in non-dt)
...
> >> And i'm not sure it's the right place for of_platform.c to handle
> >> pinmux things when create new devices.
> >
> > So of_device_alloc(), which is called by of_platform_populate() for each
> > device, already parses basic DT content such as reg and interrupts, and
> > converts them to Linux resources. I'd consider parsing any pinmux properties
> > and registering them with the pinctrl subsystem to be of a similar nature,
> > so adding some code to of_device_alloc() that calls a core pinmux function
> > to parse the DT node seems reasonable to me.
> >
> It's not perfect to me since pinmux map looks not the pure hw
> conception like reg/int.
> but i wonder if we can find a better way, (scanning?)

I suppose up-front scanning might work. To be fully safe, I think you'd
need to:

Enumerate all nodes with a compatible property (for anything without,
it won't be a device node, so who knows what it is).

In those nodes, look for pinctrl and pinctrl-names properties. If they're
present, process them.

For each phandle, make sure the referenced "pin configuration node" has
a specific pinctrl compatible flag (just to make sure it really is pin
control data, not some random other thing that happens to be pointed at
by a property named pinctrl from some random binding developed by some
3rd-party without review.)

I propose for this:

    compatible = "pinctrl-configuration";

Now, you know the device node and the pin configuration, so you can create
the pinctrl mapping table entries.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-17 19:35                           ` Stephen Warren
@ 2012-01-17 19:48                             ` Rob Herring
  0 siblings, 0 replies; 98+ messages in thread
From: Rob Herring @ 2012-01-17 19:48 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Grant Likely (grant.likely@secretlab.ca),
	linus.walleij, s.hauer, linux-kernel, kernel, cjb,
	devicetree-discuss, linux-arm-kernel, Dong Aisheng

On 01/17/2012 01:35 PM, Stephen Warren wrote:
> Shawn Guo wrote at Friday, January 13, 2012 6:11 PM:
>> On Fri, Jan 13, 2012 at 10:33:21AM -0800, Stephen Warren wrote:
>>> So of_device_alloc(), which is called by of_platform_populate() for each
>>> device, already parses basic DT content such as reg and interrupts, and
>>> converts them to Linux resources. I'd consider parsing any pinmux properties
>>> and registering them with the pinctrl subsystem to be of a similar nature,
>>> so adding some code to of_device_alloc() that calls a core pinmux function
>>> to parse the DT node seems reasonable to me.
>>
>> I hardly believe that device tree maintainers would agree here.
>> Grant, Rob?
> 
> I'm explicitly putting Grant and Rob on the To line here to make this
> question stand out to them.
> 

But then the same could be argued for regulators, clocks and whatever
else infrastructure type bindings we have. I think the distinction here
is reg and interrupts are already standard properties of
platform_devices. As I believe Linus W said, all the pin mux/ctrl stuff
has to work for non-DT as well. So if the infrastructure is handling
this for DT, how would this work in the non-DT case?

There are already ways to hook into the device creation with bus notifiers.

Rob

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-16 16:08                               ` Linus Walleij
  2012-01-17  2:32                                 ` Shawn Guo
@ 2012-01-17 19:50                                 ` Stephen Warren
  2012-01-18  2:30                                   ` Shawn Guo
  2012-01-19 16:55                                   ` Linus Walleij
  1 sibling, 2 replies; 98+ messages in thread
From: Stephen Warren @ 2012-01-17 19:50 UTC (permalink / raw)
  To: Linus Walleij, Shawn Guo
  Cc: linus.walleij, s.hauer, linux-kernel, rob.herring, Richard Zhao,
	kernel, cjb, devicetree-discuss, linux-arm-kernel, Dong Aisheng

Linus Walleij wrote at Monday, January 16, 2012 9:09 AM:
> On Sat, Jan 14, 2012 at 2:22 AM, Shawn Guo <shawn.guo@linaro.org> wrote:
> > On Fri, Jan 13, 2012 at 10:16:36AM -0800, Stephen Warren wrote:
> >> Admittedly, the wording of Linusw's actually seems to agree more with how
> >> you're interpreting what Dong said, but in that case, I don't think his
> >> reply makes sense - the whole purpose of the mux mapping table is to
> >> represent the board-specific configuration. If we're going to circumvent
> >> it, we should completely remove it from the pinctrl subsystem, rather than
> >> having some boards avoid using it by creating virtual pin groups instead.
> >>
> > IMO, it's a compromise.  It still makes sense to have concept of
> > pingroup in pinctrl subsystem, because platforms like Tegra have
> > the HW pingroup.
> 
> I'm not able to follow this discussion, it's too much stuff here that I don't
> quite grasp :-(
> 
> The pinctrl idea of a group is defined in Documentation/pinctrl.txt:
> 
> ---------------------8<---------------------------8<-----------------------------
> 
> Pin groups
> ==========
> 
> Many controllers need to deal with groups of pins, so the pin controller
> subsystem has a mechanism for enumerating groups of pins and retrieving the
> actual enumerated pins that are part of a certain group.
> 
> For example, say that we have a group of pins dealing with an SPI interface
> on { 0, 8, 16, 24 }, and a group of pins dealing with an I2C interface on pins
> on { 24, 25 }.
...
> ---------------------8<---------------------------8<-----------------------------
> 
> 
> As you can see none of the text above claims that the group is
> about hardware-defined groups or anything like that.

Well, I guess that's true, but didn't we only add the concept of groups
to the pinctrl subsystem in order to support Tegra's HW-group-based
muxing? And irrespective of that, why would you want to define "virtual"
groups in the pinctrl driver when the whole point of the pin mux mapping
table allowing multiple entries for a device was to handle the mux-by-
pin case?

> The groups
> are just that - a group of pins, an abstract concept of a group.
> It could be drawn i UML even... maybe I'll do that for my
> ELC presentation :-)

I should ask: Who here is coming to Linaro Connect and/or ELC? I'm
Currently signed up for Linaro Connect, but not ELC. I could probably
add ELC if there was good reason.

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-17 19:50                                 ` Stephen Warren
@ 2012-01-18  2:30                                   ` Shawn Guo
  2012-01-19 16:55                                   ` Linus Walleij
  1 sibling, 0 replies; 98+ messages in thread
From: Shawn Guo @ 2012-01-18  2:30 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Linus Walleij, linus.walleij, s.hauer, linux-kernel, rob.herring,
	Richard Zhao, kernel, cjb, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

On Tue, Jan 17, 2012 at 11:50:33AM -0800, Stephen Warren wrote:
> I should ask: Who here is coming to Linaro Connect and/or ELC? I'm
> Currently signed up for Linaro Connect, but not ELC. I could probably
> add ELC if there was good reason.
> 
Aisheng and myself have signed up for both Linaro Connect and ELC.
So see you there.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-17 19:50                                 ` Stephen Warren
  2012-01-18  2:30                                   ` Shawn Guo
@ 2012-01-19 16:55                                   ` Linus Walleij
  2012-01-19 19:30                                     ` Stephen Warren
  1 sibling, 1 reply; 98+ messages in thread
From: Linus Walleij @ 2012-01-19 16:55 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Shawn Guo, linus.walleij, s.hauer, linux-kernel, rob.herring,
	Richard Zhao, kernel, cjb, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

On Tue, Jan 17, 2012 at 8:50 PM, Stephen Warren <swarren@nvidia.com> wrote:
> Linus Walleij wrote at Monday, January 16, 2012 9:09 AM:

>> As you can see none of the text above claims that the group is
>> about hardware-defined groups or anything like that.
>
> Well, I guess that's true, but didn't we only add the concept of groups
> to the pinctrl subsystem in order to support Tegra's HW-group-based
> muxing?

The groups appeared in v6 of the very first patchset, this is
from git log drivers/pinctrl

    ChangeLog v5->v6:

    - Create an abstract pin group concept that can sort pins into
      named and enumerated groups no matter what the use of these
      groups may be, one possible usecase is a group of pins being
      muxed in or so. The intention is however to also use these
      groups for other pin control activities.
    - Make it compulsory for pinmux functions to associate with
      at least one group, so the abstract pin group concept is used
      to define the groups of pins affected by a pinmux function.
      The pinmux driver interface has been altered so as to enforce
      a function to list applicable groups per function.
    - Provide an optional .group entry in the pinmux machine map
      so the map can select beteween different available groups
      to be used with a certain function.
    - Consequent changes all over the place so that e.g. debugfs
      present reasonable information about the world.
    - Drop the per-pin mux (*config) function in the pinmux_ops
      struct - I was afraid that this would start to be used for
      things totally unrelated to muxing, we can introduce that to
      the generic struct pinctrl_ops if needed. I want to keep
      muxing orthogonal to other pin control subjects and not mix
      these things up.

The first driver using the concept was the U300 driver.

> And irrespective of that, why would you want to define "virtual"
> groups in the pinctrl driver when the whole point of the pin mux mapping
> table allowing multiple entries for a device was to handle the mux-by-
> pin case?

In the U300 the driver define groups of pins like these:

static const unsigned uart0_pins[] = { 134, 135, 136, 137 };
static const unsigned mmc0_pins[] = { 166, 167, 168, 169, 170, 171, 176, 177 };
static const unsigned spi0_pins[] = { 420, 421, 422, 423, 424, 425 };

These groups are associated with muxes.

Then each such group is activated by reading masking and writing
several registers, but basically they are muxed in and out
on a per-group basis.

So yes, in this case the U300 use is consistent with a 1-1
mapping between physical handling of a group and a certain
per-group register setting.

But I also added these groups:

static const unsigned emif0_pins[] = { 355, 356, 357, 362, 363, 364, 365, 366,
        367, 368, 369, 370, 371, 376, 377, 378, 379, 380, 381, 382, 383, 384,
        385, 386, 387, 393, 394, 395, 396, 397, 398, 406, 407, 410, 411, 412,
        417, 418 };
static const unsigned emif1_pins[] = { 216, 217, 219, 220, 221, 222, 227, 228,
        229, 230, 233, 234, 235, 236, 241, 242, 243, 244, 247, 248, 249, 250,
        253, 254, 255, 260, 261, 262, 263, 266, 267, 268, 269, 272, 273, 274,
        275, 280, 281, 282, 283, 286, 287, 288, 289, 292, 293, 294, 297, 298,
        304, 305, 306, 307, 308, 313, 314, 315 };

It's not like I could remux the pins used by the external memory
interface, so these groups are not used by the mux driver at
all.

They are used to give a nice overview in debugfs, and for
blocking up these pins from other users so as not to make
mistakes. So no relation to any registers or so.

As how to use them for controllers that can support
per-pin muxing I don't know, in the gpio-nomadik.c
case (and I should hack on this driver!) pins are controlled
on a per-pin basis, but the only settings that make any
sense is to use them in certain groupings.

Example: pins {0, 1} can be used for I2C, or GPIO.
It doesn't make sense to mux in SCL on pin 0 and
have GPIO on pin 1, do defining a group of {0, 1}
and associate that with a mux setting for I2C is the
sensible thing to do IMO, even though this is in
practice achived by writing mux registers for two
different pins.

I don't know if that is what you're discussing here,
I might have missed the point :-/

>> The groups
>> are just that - a group of pins, an abstract concept of a group.
>> It could be drawn i UML even... maybe I'll do that for my
>> ELC presentation :-)
>
> I should ask: Who here is coming to Linaro Connect and/or ELC? I'm
> Currently signed up for Linaro Connect, but not ELC. I could probably
> add ELC if there was good reason.

I'm coming to both, so see you there :-)

Thanks,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-19 16:55                                   ` Linus Walleij
@ 2012-01-19 19:30                                     ` Stephen Warren
  2012-01-20 17:51                                       ` Linus Walleij
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Warren @ 2012-01-19 19:30 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Shawn Guo, linus.walleij, s.hauer, linux-kernel, rob.herring,
	Richard Zhao, kernel, cjb, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

Linus Walleij wrote at Thursday, January 19, 2012 9:56 AM:
> On Tue, Jan 17, 2012 at 8:50 PM, Stephen Warren <swarren@nvidia.com> wrote:
> > Linus Walleij wrote at Monday, January 16, 2012 9:09 AM:
> 
> >> As you can see none of the text above claims that the group is
> >> about hardware-defined groups or anything like that.
> >
> > Well, I guess that's true, but didn't we only add the concept of groups
> > to the pinctrl subsystem in order to support Tegra's HW-group-based
> > muxing?
> 
> The groups appeared in v6 of the very first patchset, this is
> from git log drivers/pinctrl
> 
>     ChangeLog v5->v6:
> 
>     - Create an abstract pin group concept that can sort pins into
>       named and enumerated groups no matter what the use of these
>       groups may be, one possible usecase is a group of pins being
>       muxed in or so. The intention is however to also use these
>       groups for other pin control activities.

To me, "activities" above reads as pin configuration, since muxing is
an activity that's covered by this patch, and pin config is an additional
one. If doesn't imply virtual groups, which are data not an activity.

I still feel that virtual groups don't have much purpose, since the
whole reason I asked that the pin mux mapping table allow multiple
entries to be allowed for each (map name, device) pair was to allow
grouping of the lowest-level muxable entity into groups that the
device used. So, defining these virtual groups is a completely
redundant way of achieving the same goal.

For DT bindings, I think we (at least myself, Shawn, and Dong) have
agreed that with my binding proposal, you can get the same effect as
virtual groups without the driver needing to define them (this is
certainly true even if I misrepresent others' understanding). For the
non-DT case, I proposed that the virtual groups could be represented
as #defines/macros that could be used while initializing the board's
mapping table, each containing n lines of entries as appropriate. Then,
non-DT and DT could have equivalent sysfs output for pinctrl.

That all said, I suppose that if the pinctrl driver were to expose some
virtual groups, there's the possibility this will reduce the size of
the device tree or static board mapping files, since they won't need
so many entries or rows.

I'd be happy if we adopted the following policy for when to define
pin groups in a pinctrl driver. This both allows virtual groups if the
SoC's vendor wants them in their pinctrl driver, yet still exposes
the raw capabilities of the SoC, in case the pre-defined virtual groups
don't cover a case that needs to be used:

pinctrl drivers MUST enumerate all pins that are affected by the muxing
or pin configuration capabilities of the pinctrl driver. Where the HW
muxes or configures pins in terms of groups, this list MUST include
ALL pins in the groups that the pinctrl driver defines. Pinctrl drivers
MAY expose a subset of pins present on the SoC, and grow this list over
time as needed, provided the previous conditions are met.

(well, that's already a requirement of the pinctrl subsystem just due
to how it works internally)

If the HW muxes and configures pins on a per-pin basis, the pinctrl
driver MUST enumerate a group for each individual pin included in the
pin enumeration above, and allow muxing and pin configuration operations
to be applied to these groups.

(that's the main point I seek)

If the HW muxes and configures pins on a per-group basis, the pinctrl
driver MUST enumerate all groups that are affected by the muxing
or pin configuration capabilities of the pinctrl driver. Pinctrl drivers
MAY need to enumerate a group for each individual pin included in the
pin enumeration above, e.g. if representing "GPIO" as a mux function.
pinctrl drivers MAY expose a subset of groups present on the SoC, and
grow this list over time as needed, provided the previous conditions
are met.

(again, that's really just how pinctrl already works)

pinctrl drivers MAY expose additional groups. This feature may be used
to represent higher-level groupings of the HW's raw muxable pins or
groups. This may be useful in order to e.g. represent all pins involved
in a single SD interface, so their muxing may be represented in a single
pin mux mapping table entry. Such groups MUST still define a valid list
of the individual pins included in the group. Individual pinctrl drivers
are responsible for any iteration required when muxing/configuration such
"virtual" groups. This feature MAY be used irrespective of whether the
underlying HW muxes or configures pins on a per-pin or per-group basis.

(this explicitly allows "virtual" groups)

Does that seem reasonable?

(is it worth adding this to the documentation of pinctrl?)

-- 
nvpublic


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings
  2012-01-19 19:30                                     ` Stephen Warren
@ 2012-01-20 17:51                                       ` Linus Walleij
  0 siblings, 0 replies; 98+ messages in thread
From: Linus Walleij @ 2012-01-20 17:51 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Shawn Guo, linus.walleij, s.hauer, linux-kernel, rob.herring,
	Richard Zhao, kernel, cjb, devicetree-discuss, linux-arm-kernel,
	Dong Aisheng

On Thu, Jan 19, 2012 at 8:30 PM, Stephen Warren <swarren@nvidia.com> wrote:
> Linus Walleij wrote at Thursday, January 19, 2012 9:56 AM:

>>     ChangeLog v5->v6:
>>
>>     - Create an abstract pin group concept that can sort pins into
>>       named and enumerated groups no matter what the use of these
>>       groups may be, one possible usecase is a group of pins being
>>       muxed in or so. The intention is however to also use these
>>       groups for other pin control activities.
>
> To me, "activities" above reads as pin configuration, since muxing is
> an activity that's covered by this patch, and pin config is an additional
> one. If doesn't imply virtual groups, which are data not an activity.

Yes, but the text also says "also". So I do not see how one of the
use cases excludes the other.

> I still feel that virtual groups don't have much purpose, since the
> whole reason I asked that the pin mux mapping table allow multiple
> entries to be allowed for each (map name, device) pair was to allow
> grouping of the lowest-level muxable entity into groups that the
> device used. So, defining these virtual groups is a completely
> redundant way of achieving the same goal.

I don't see it quite that way. I saw the support of multiple groups
per pinmux as a compromise to get code that would be useful
no matter how you chose to model it. And groups that would be
useful for other purposes than muxing alone.

It so happens that for the U300 some of the defined groups are
1-to-1 to the muxable entitity in a register, so it actually mostly
conforms to that, with the exception of the groups I created for
power pins and EMIF...

But the latter groups does indeed group things that share
something hardware-related in common, while that is not
a setting in a mux register, but something else, like being used
to transfer data to the same memory module in the EMIF
case.

> For DT bindings, I think we (at least myself, Shawn, and Dong) have
> agreed that with my binding proposal, you can get the same effect as
> virtual groups without the driver needing to define them (this is
> certainly true even if I misrepresent others' understanding). For the
> non-DT case, I proposed that the virtual groups could be represented
> as #defines/macros that could be used while initializing the board's
> mapping table, each containing n lines of entries as appropriate. Then,
> non-DT and DT could have equivalent sysfs output for pinctrl.
>
> That all said, I suppose that if the pinctrl driver were to expose some
> virtual groups, there's the possibility this will reduce the size of
> the device tree or static board mapping files, since they won't need
> so many entries or rows.

I don't understand these concepts well enough to have an opinion
on it. I will need to see the proposed code first...

> I'd be happy if we adopted the following policy
> (...)
> pinctrl drivers MUST enumerate all pins that are affected by the muxing
> or pin configuration capabilities of the pinctrl driver.

OK (split in separate clause when you write the documentation
patch for this)

> Where the HW
> muxes or configures pins in terms of groups, this list MUST include
> ALL pins in the groups that the pinctrl driver defines.

I think this requirement is to be broader:

- when your driver define pin groups, the pins in these groups need to
  be defined and registered as well.

Nothing of drivers with muxes.

I actually wanted to add code that verifies this on the existing
drivers, so they can't present groups to the subsystem if they
contain enumerated pins that does not exist.

So I'd say, isn't it better if we simply write some code that
checks this on registered groups and make sure you cannot
register groups with non-existing pin? That's 100 times
better than any written policy that would tend to be overlooked
anyway.

> Pinctrl drivers
> MAY expose a subset of pins present on the SoC, and grow this list over
> time as needed, provided the previous conditions are met.

OK (separate clause)

> (well, that's already a requirement of the pinctrl subsystem just due
> to how it works internally)

Yes. And it is better to write code than policies.

> If the HW muxes and configures pins on a per-pin basis, the pinctrl
> driver MUST enumerate a group for each individual pin included in the
> pin enumeration above, and allow muxing and pin configuration operations
> to be applied to these groups.

NACK, sorry.

Basically my argument (which was in the previous mail)
is that it doesn't make sense for the core or any policy to dictate
how a driver for a certain hardware shall present its groups; it's
up to the driver.

I already had this example in the previous mail:

----------------8<------------------------8<-----------------------
Example: pins {0, 1} can be used for I2C, or GPIO.
It doesn't make sense to mux in SCL on pin 0 and
have GPIO on pin 1, so defining a group of {0, 1}
and associate that with a mux setting for I2C is the
sensible thing to do IMO, even though this is in
practice achived by writing mux registers for two
different pins.
----------------8<------------------------8<-----------------------

I know this may be highly suitable for Tegra, so then have it as a
rule for your driver, problem solved? I don't see why this need
to be enforced across the entire subsystem.

> If the HW muxes and configures pins on a per-group basis, the pinctrl
> driver MUST enumerate all groups that are affected by the muxing
> or pin configuration capabilities of the pinctrl driver.

OK (separate clause)

> Pinctrl drivers
> MAY need to enumerate a group for each individual pin included in the

cut "need to". If the driver writer want to present each pin as
a group, s/he can go ahead and do that. But we need not impose that.
It's a fair compromise I think.

> pin enumeration above, e.g. if representing "GPIO" as a mux function.
> pinctrl drivers MAY expose a subset of groups present on the SoC, and
> grow this list over time as needed, provided the previous conditions
> are met.

Then OK (separate clause)

> (again, that's really just how pinctrl already works)

There is no driver in the kernel that define single-pin groups, so
it is not how it works. But it is possible and allowed
to do drivers like that.

> pinctrl drivers MAY expose additional groups. This feature may be used
> to represent higher-level groupings of the HW's raw muxable pins

So you are saying that a pin may be part of more than one group
and thus overlap?

This is true though.

> or groups.

Groups of groups? Never heard of that before.

In that case I think new abstractions are needed. And there is
no point in documenting groups of groups until there is code
to support it for sure.

> This may be useful in order to e.g. represent all pins involved
> in a single SD interface, so their muxing may be represented in a single
> pin mux mapping table entry. Such groups MUST still define a valid list
> of the individual pins included in the group.

I'm fine with the simple statement of allowing
a pin to be part of more than one group.

> Individual pinctrl drivers
> are responsible for any iteration required when muxing/configuration such
> "virtual" groups. This feature MAY be used irrespective of whether the
> underlying HW muxes or configures pins on a per-pin or per-group basis.
>
> (this explicitly allows "virtual" groups)

This is how I already implemented things, and I don't think of these
groups as "virtual" at all. That some certain group of pins does not
have a common register associated with it (say a mux register) does
not mean that they do not belong together anyway, like the U300
EMIF0 pins. There is nothing "virtual" about that, it's highly
physical.

So I am resisting the terminology of "virtual"

> Does that seem reasonable?

The stuff I marked OK is... forcing hardware with per-pin control
registers to present per-pin groups doesn't play well with me.

> (is it worth adding this to the documentation of pinctrl?)

For some instances it is better to write code. Like code that
(maybe optionally?) verifies that the groups registered by
a pin controller does not contain undefined pins.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

end of thread, other threads:[~2012-01-20 17:52 UTC | newest]

Thread overview: 98+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-20 17:40 [RFC PATCH v3 0/5] pinctrl: imx: add pinnmux support Dong Aisheng
2011-12-20 17:40 ` [RFC PATCH v3 1/5] dt: add of_get_child_count helper function Dong Aisheng
2011-12-20 18:35   ` Rob Herring
2011-12-21  2:56     ` Dong Aisheng-B29396
2012-01-01 13:58       ` Linus Walleij
2011-12-20 19:47   ` Marek Vasut
2011-12-21  3:27     ` Dong Aisheng-B29396
2011-12-21  6:05       ` Lothar Waßmann
2011-12-20 23:58   ` Stephen Warren
2011-12-21  3:18     ` Dong Aisheng-B29396
2011-12-20 17:40 ` [RFC PATCH v3 2/5] pinctrl: add dt binding support for pinmux mappings Dong Aisheng
2011-12-20 19:48   ` Marek Vasut
2011-12-21  0:39   ` Stephen Warren
2011-12-22  8:18     ` Dong Aisheng-B29396
2011-12-25  3:37       ` Stephen Warren
2011-12-27 14:41         ` Dong Aisheng-B29396
2011-12-29  2:46           ` Shawn Guo
2012-01-05 13:14             ` Dong Aisheng
2012-01-05 23:45             ` Stephen Warren
2012-01-06  6:21               ` Shawn Guo
2012-01-05 23:38           ` Stephen Warren
2012-01-06 10:51             ` Dong Aisheng-B29396
2012-01-06 17:23               ` Stephen Warren
2012-01-10  7:02                 ` Dong Aisheng-B29396
2012-01-05 13:47         ` Dong Aisheng
2012-01-06  1:05           ` Stephen Warren
2012-01-06  5:27             ` Shawn Guo
2012-01-06 11:33             ` Dong Aisheng-B29396
2012-01-06 13:14               ` Shawn Guo
2012-01-06 18:03               ` Stephen Warren
2012-01-07 13:54                 ` Shawn Guo
2012-01-08 12:51                   ` Richard Zhao
2012-01-09  1:56                     ` Shawn Guo
2012-01-09  6:18                       ` Simon Glass
2012-01-10 11:30                         ` Dong Aisheng-B29396
2012-01-11 19:19                         ` Stephen Warren
2012-01-11 18:37                       ` Stephen Warren
2012-01-11 23:56                         ` Shawn Guo
2012-01-11 23:59                           ` Stephen Warren
2012-01-12  4:03                             ` Shawn Guo
2012-01-12  7:45                               ` Dong Aisheng-B29396
2012-01-11 18:28                     ` Stephen Warren
2012-01-11 18:17                   ` Stephen Warren
2012-01-12  3:39                     ` Shawn Guo
2012-01-12  7:40                       ` Dong Aisheng-B29396
2012-01-12 20:46                       ` Stephen Warren
2012-01-12 21:10                         ` Stephen Warren
2012-01-13  3:46                         ` Shawn Guo
2012-01-13 18:16                           ` Stephen Warren
2012-01-14  1:22                             ` Shawn Guo
2012-01-14 18:21                               ` Dong Aisheng
2012-01-16 16:08                               ` Linus Walleij
2012-01-17  2:32                                 ` Shawn Guo
2012-01-17 19:50                                 ` Stephen Warren
2012-01-18  2:30                                   ` Shawn Guo
2012-01-19 16:55                                   ` Linus Walleij
2012-01-19 19:30                                     ` Stephen Warren
2012-01-20 17:51                                       ` Linus Walleij
2012-01-10  8:21                 ` Dong Aisheng-B29396
2012-01-10 13:05                   ` Shawn Guo
2012-01-11 19:41                     ` Stephen Warren
2012-01-11 23:01                       ` Shawn Guo
2012-01-11 22:58                         ` Stephen Warren
2012-01-11 20:17                   ` Stephen Warren
2012-01-11 23:21                     ` Shawn Guo
2012-01-12  8:36                     ` Dong Aisheng-B29396
2012-01-12 20:56                       ` Stephen Warren
2012-01-13  3:55                         ` Shawn Guo
2012-01-13  8:07                           ` Dong Aisheng-B29396
2012-01-13 13:35                             ` Shawn Guo
2012-01-13 13:48                               ` Linus Walleij
2012-01-13 14:23                                 ` Shawn Guo
2012-01-13 17:11                     ` Dong Aisheng
2012-01-13 18:33                       ` Stephen Warren
2012-01-14  1:10                         ` Shawn Guo
2012-01-17 19:35                           ` Stephen Warren
2012-01-17 19:48                             ` Rob Herring
2012-01-14 17:58                         ` Dong Aisheng
2012-01-17 19:44                           ` Stephen Warren
2012-01-01 14:07   ` Linus Walleij
2012-01-01 15:22     ` Rob Herring
2012-01-05 13:59     ` Dong Aisheng
2011-12-20 17:40 ` [RFC PATCH v3 3/5] pinctrl: imx: add pinctrl imx driver Dong Aisheng
2011-12-20 19:50   ` Marek Vasut
2011-12-21  3:09     ` Dong Aisheng-B29396
2012-01-01 14:02   ` Linus Walleij
2012-01-08 13:05   ` Richard Zhao
2012-01-09  2:08     ` Shawn Guo
2012-01-09  2:17       ` Richard Zhao
2012-01-09  6:32         ` Shawn Guo
2012-01-10  8:38           ` Richard Zhao
2012-01-10 10:43             ` Linus Walleij
2012-01-10 10:55               ` Dong Aisheng-B29396
2012-01-10 13:51               ` Shawn Guo
2012-01-11  9:28                 ` Linus Walleij
2011-12-20 17:40 ` [RFC PATCH v3 4/5] ARM: imx6q: using pinmux subsystem Dong Aisheng
2011-12-20 17:40 ` [RFC PATCH v3 5/5] mmc: sdhci-esdhc-imx: " Dong Aisheng
2012-01-01 13:54   ` Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).