Skip to contentSkip to conversation

: pinctrl-single support DT

PATCH Superseded Haojian Zhuang 4 participants 18 messages Oct 31, 2012 – Nov 7, 2012

Subsystems (8)

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v3 cover : pinctrl-single support DT

Changelog:
v3:
1. Add more comments in document.
2. Replace pcs_readl() & pcs_writel() by pcs->read() & pcs->write().
3. Clean code.

v2:
1. Remove "pinctrl-single,gpio-mask". Since GPIO function is one of the mux function in the pinmux register of both OMAP and PXA/MMP silicons. Use "pinctrl-single,function-mask" instead.
2. Remove "pinctrl-single,gpio-enable" & "pinctrl-single,gpio-disable". Use "pinctrl-single,gpio-func" instead. Because GPIO mode is only one of the mux functions in the pinmux register. Defining "gpio-enable" & "gpio-disable" are redundant.
3. Define register with __iomem, not u32 type.
4. Remove "pinctrl-single,input-schmit-shift", "pinctrl-single,power-source-shift", "pinctrl-single,bias-shift". All these properties could be calculated by mask fields.
5. Return -EPROBE_DEFER if pinmux could be got in device driver. And the device driver would be probed again deferred.

#1 lore raw

PATCH v3 1/9 ARM: mmp: select pinctrl driver

Pinctrl driver is necessary for MMP DT & MMP2 DT platforms.

---
 arch/arm/mach-mmp/Kconfig |    4 ++++
 1 file changed, 4 insertions(+)
arch/arm/mach-mmp/Kconfig +4 -0
index 178d4da..ebdda83 100644
@@ -89,6 +89,8 @@ config MACH_MMP_DT
 	select CPU_PXA168
 	select CPU_PXA910
 	select USE_OF
+	select PINCTRL
+	select PINCTRL_SINGLE
 	help
 	  Include support for Marvell MMP2 based platforms using
 	  the device tree. Needn't select any other machine while
@@ -99,6 +101,8 @@ config MACH_MMP2_DT
 	depends on !CPU_MOHAWK
 	select CPU_MMP2
 	select USE_OF
+	select PINCTRL
+	select PINCTRL_SINGLE
 	help
 	  Include support for Marvell MMP2 based platforms using
 	  the device tree.
Signature · 1 line
1.7.10.4
#2 lore raw

PATCH v3 2/9 pinctrl: single: support gpio request and free

In reply to Haojian Zhuang

Marvell's PXA/MMP silicon also match the behavior of pinctrl-single. Each pin binds to one register. A lot of pins could be configured as gpio.

Now add these properties in below.
<gpio range phandle>:
include "pinctrl-single,gpio" & "pinctrl,gpio-func" properties.

pinctrl-single,gpio: <gpio base, npins in range, register offset>

pinctrl-single,gpio-func: <gpio function value in mux>

pinctrl-single,gpio-ranges: phandle list of gpio range array

---
 drivers/pinctrl/pinctrl-single.c |  100 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 98 insertions(+), 2 deletions(-)
drivers/pinctrl/pinctrl-single.c +98 -2
index 726a729..a7c5fdd 100644
@@ -30,6 +30,7 @@
 #define PCS_MUX_BITS_NAME		"pinctrl-single,bits"
 #define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 1)
 #define PCS_OFF_DISABLED		~0U
+#define PCS_MAX_GPIO_VALUES		3
 
 /**
  * struct pcs_pingroup - pingroups for a function
@@ -77,6 +78,18 @@ struct pcs_function {
 };
 
 /**
+ * struct pcs_gpio_range - pinctrl gpio range
+ * @range:	subrange of the GPIO number space
+ * @gpio_func:	gpio function value in the pinmux register
+ * @func_en:	need to handle gpio function in the pinmux register
+ */
+struct pcs_gpio_range {
+	struct pinctrl_gpio_range range;
+	int gpio_func;
+	unsigned func_en:1;
+};
+
+/**
  * struct pcs_data - wrapper for data needed by pinctrl framework
  * @pa:		pindesc array
  * @cur:	index to current element
@@ -123,8 +136,10 @@ struct pcs_name {
  * @ftree:	function index radix tree
  * @pingroups:	list of pingroups
  * @functions:	list of functions
+ * @ranges:	list of gpio ranges
  * @ngroups:	number of pingroups
  * @nfuncs:	number of functions
+ * @nranges:	number of gpio ranges
  * @desc:	pin controller descriptor
  * @read:	register read function to use
  * @write:	register write function to use
@@ -148,8 +163,10 @@ struct pcs_device {
 	struct radix_tree_root ftree;
 	struct list_head pingroups;
 	struct list_head functions;
+	struct list_head ranges;
 	unsigned ngroups;
 	unsigned nfuncs;
+	unsigned nranges;
 	struct pinctrl_desc desc;
 	unsigned (*read)(void __iomem *reg);
 	void (*write)(unsigned val, void __iomem *reg);
@@ -403,9 +420,27 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
 }
 
 static int pcs_request_gpio(struct pinctrl_dev *pctldev,
-			struct pinctrl_gpio_range *range, unsigned offset)
+			    struct pinctrl_gpio_range *range, unsigned pin)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	struct pcs_gpio_range *gpio = NULL;
+	int end, mux_bytes;
+	unsigned data;
+
+	gpio = container_of(range, struct pcs_gpio_range, range);
+	if (!gpio->func_en)
+		return -ENOTSUPP;
+	end = range->pin_base + range->npins - 1;
+	if (pin < range->pin_base || pin > end) {
+		dev_err(pctldev->dev, "pin %d isn't in the range of "
+			"%d to %d\n", pin, range->pin_base, end);
+		return -EINVAL;
+	}
+	mux_bytes = pcs->width / BITS_PER_BYTE;
+	data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask;
+	data |= gpio->gpio_func;
+	pcs->write(data, pcs->base + pin * mux_bytes);
+	return 0;
 }
 
 static struct pinmux_ops pcs_pinmux_ops = {
@@ -879,6 +914,62 @@ static void pcs_free_resources(struct pcs_device *pcs)
 
 static struct of_device_id pcs_of_match[];
 
+static int __devinit pcs_add_gpio_range(struct device_node *node,
+					struct pcs_device *pcs)
+{
+	struct pcs_gpio_range *gpio;
+	struct device_node *np;
+	const __be32 *list;
+	const char list_name[] = "pinctrl-single,gpio-ranges";
+	const char name[] = "pinctrl-single";
+	u32 gpiores[PCS_MAX_GPIO_VALUES];
+	int ret, size, i, mux_bytes = 0;
+
+	list = of_get_property(node, list_name, &size);
+	if (!list)
+		return 0;
+	size = size / sizeof(*list);
+	for (i = 0; i < size; i++) {
+		np = of_parse_phandle(node, list_name, i);
+		memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
+		ret = of_property_read_u32_array(np, "pinctrl-single,gpio",
+						 gpiores, PCS_MAX_GPIO_VALUES);
+		if (ret < 0)
+			return -ENOENT;
+		gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL);
+		if (!gpio) {
+			dev_err(pcs->dev, "failed to allocate pcs gpio\n");
+			return -ENOMEM;
+		}
+		gpio->range.id = i;
+		gpio->range.base = gpiores[0];
+		gpio->range.npins = gpiores[1];
+		gpio->range.name = devm_kzalloc(pcs->dev, sizeof(name),
+						GFP_KERNEL);
+		if (!gpio->range.name) {
+			dev_err(pcs->dev, "failed to allocate range name\n");
+			return -ENOMEM;
+		}
+		memcpy(&gpio->range.name, name, sizeof(name));
+		mux_bytes = pcs->width / BITS_PER_BYTE;
+		gpio->range.pin_base = gpiores[2] / mux_bytes;
+		memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
+		ret = of_property_read_u32(np, "pinctrl-single,gpio-func",
+					   &gpio->gpio_func);
+		if (ret < 0)
+			return -ENOENT;
+		gpio->func_en = 1;
+
+		mutex_lock(&pcs->mutex);
+		list_add_tail(&gpio->range.node, &pcs->ranges);
+		pcs->nranges++;
+		mutex_unlock(&pcs->mutex);
+
+		pinctrl_add_gpio_range(pcs->pctl, &gpio->range);
+	}
+	return 0;
+}
+
 static int __devinit pcs_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -900,6 +991,7 @@ static int __devinit pcs_probe(struct platform_device *pdev)
 	mutex_init(&pcs->mutex);
 	INIT_LIST_HEAD(&pcs->pingroups);
 	INIT_LIST_HEAD(&pcs->functions);
+	INIT_LIST_HEAD(&pcs->ranges);
 
 	PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width,
 			 "register width not specified\n");
@@ -975,6 +1067,10 @@ static int __devinit pcs_probe(struct platform_device *pdev)
 		goto free;
 	}
 
+	ret = pcs_add_gpio_range(np, pcs);
+	if (ret < 0)
+		goto free;
+
 	dev_info(pcs->dev, "%i pins at pa %p size %u\n",
 		 pcs->desc.npins, pcs->base, pcs->size);
 
Signature · 1 line
1.7.10.4
#3 lore raw

PATCH v3 3/9 pinctrl: single: support pinconf generic

In reply to Haojian Zhuang

Add pinconf generic support with POWER SOURCE, BIAS PULL.

---
 drivers/pinctrl/Kconfig          |    1 +
 drivers/pinctrl/pinctrl-single.c |  276 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 266 insertions(+), 11 deletions(-)
drivers/pinctrl/Kconfig +1 -0
index 7bf914d..e9f2d2d 100644
@@ -139,6 +139,7 @@ config PINCTRL_SINGLE
 	depends on OF
 	select PINMUX
 	select PINCONF
+	select GENERIC_PINCONF
 	help
 	  This selects the device tree based generic pinctrl driver.
 
drivers/pinctrl/pinctrl-single.c +265 -11

394 lines not on this page · raw message

Signature · 1 line
1.7.10.4
maintainer
#4 lore raw

PATCH v3 3/9 pinctrl: single: support pinconf generic

Quoted 11 lines
drivers/pinctrl/pinctrl-single.c +1 -0
@@ -20,6 +20,7 @@
 #include <linux/of_device.h>
 #include <linux/of_address.h>
 
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 

drivers/pinctrl/pinctrl-single.c line 37

Quoted 9 lines
drivers/pinctrl/pinctrl-single.c +3 -0
@@ -28,6 +29,9 @@
 #define DRIVER_NAME			"pinctrl-single"
 #define PCS_MUX_PINS_NAME		"pinctrl-single,pins"
 #define PCS_MUX_BITS_NAME		"pinctrl-single,bits"
+#define PCS_BIAS_NAME			"pinctrl-single,bias"
+#define PCS_POWER_SOURCE_NAME		"pinctrl-single,power-source"
+#define PCS_SCHMITT_NAME		"pinctrl-single,input-schmitt"
 #define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 1)
 #define PCS_OFF_DISABLED		~0U
 #define PCS_MAX_GPIO_VALUES		3

Here too you can remove the new defines.

drivers/pinctrl/pinctrl-single.c static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset) · line 868

Quoted 6 lines

static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,

drivers/pinctrl/pinctrl-single.c +1 -0
 						struct device_node *np,
 						struct pinctrl_map **map,
+						unsigned num_configs,
 						const char **pgnames)
 {

...

Then I suggest you add a generic pinconf-generic property to indicate the controller supports pinconf. At least for omaps, only some register ranges support pinconf. And by adding pinconf-generic, you can parse it once during the probe of pinctrl-single.c, and set pcs->pinconf flag.

Then you can use here and avoid calling of_property_read_u32 for about 600 times unnecessarily for omap4:

if (pcs->pinconf) {

Quoted 12 lines
drivers/pinctrl/pinctrl-single.c +12 -0
+	if (!num_configs)
+		return 0;
+	config = devm_kzalloc(pcs->dev, sizeof(*config) * num_configs,
+			      GFP_KERNEL);
+	if (!config) {
+		res = -ENOMEM;
+		goto free_pingroup;
+	}
+	index = 0;
+
+	if (!of_property_read_u32(np, PCS_SCHMITT_NAME, &value))
+		config[index++] =

drivers/pinctrl/pinctrl-single.c

Quoted 10 lines
drivers/pinctrl/pinctrl-single.c +10 -0
+			pinconf_to_config_packed(PIN_CONFIG_INPUT_SCHMITT,
+						 value & 0xffff);
+	if (!of_property_read_u32(np, PCS_BIAS_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_BIAS_DISABLE,
+						 value & 0xffff);
+	if (!of_property_read_u32(np, PCS_POWER_SOURCE_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_POWER_SOURCE,
+						 value & 0xffff);

}

Quoted 27 lines
drivers/pinctrl/pinctrl-single.c +23 -0
+static int pcs_dt_check_maps(struct device_node *np, unsigned *num_maps,
+			     unsigned *num_configs)
+{
+	unsigned size;
+
+	*num_maps = 0;
+	*num_configs = 0;
+	if (of_get_property(np, PCS_MUX_PINS_NAME, &size)
+		|| of_get_property(np, PCS_MUX_BITS_NAME, &size))
+		(*num_maps)++;
+	if (of_get_property(np, PCS_SCHMITT_NAME, &size))
+		(*num_configs)++;
+	if (of_get_property(np, PCS_BIAS_NAME, &size))
+		(*num_configs)++;
+	if (of_get_property(np, PCS_POWER_SOURCE_NAME, &size))
+		(*num_configs)++;
+	if (*num_configs)
+		(*num_maps)++;
+	if (!(*num_maps))
+		return -EINVAL;
+	return 0;
+}
+
 /**
  * pcs_dt_node_to_map() - allocates and parses pinctrl maps
  * @pctldev: pinctrl instance

drivers/pinctrl/pinctrl-single.c static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, · line 1025

Quoted 7 lines
drivers/pinctrl/pinctrl-single.c +1 -0
@@ -802,29 +1019,32 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
 {
 	struct pcs_device *pcs;
 	const char **pgnames;
+	unsigned num_configs;
 	int ret;
 
 	pcs = pinctrl_dev_get_drvdata(pctldev);

Here too:

if (pcs->pinconf) {

drivers/pinctrl/pinctrl-single.c static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, · line 1033

Quoted 8 lines
drivers/pinctrl/pinctrl-single.c +5 -1
-	*map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL);
+	ret = pcs_dt_check_maps(np_config, num_maps, &num_configs);
+	if (ret)
+		return ret;
+
+	*map = devm_kzalloc(pcs->dev, sizeof(**map) * (*num_maps), GFP_KERNEL);
 	if (!map)
 		return -ENOMEM;

} else {

drivers/pinctrl/pinctrl-single.c static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, · line 814

Quoted 2 lines
drivers/pinctrl/pinctrl-single.c +0 -2
-	*num_maps = 0;
-

}

Regards,

Tony

#5 lore raw

PATCH 8/10 pinctrl: single: support pinconf generic

Quoted 32 lines · Tony Lindgren
Quoted 12 lines
drivers/pinctrl/pinctrl-single.c +1 -0
@@ -20,6 +20,7 @@
 #include <linux/of_device.h>
 #include <linux/of_address.h>
 
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 

drivers/pinctrl/pinctrl-single.c line 37

Quoted 9 lines
drivers/pinctrl/pinctrl-single.c +3 -0
@@ -28,6 +29,9 @@
 #define DRIVER_NAME                  "pinctrl-single"
 #define PCS_MUX_PINS_NAME            "pinctrl-single,pins"
 #define PCS_MUX_BITS_NAME            "pinctrl-single,bits"
+#define PCS_BIAS_NAME                        "pinctrl-single,bias"
+#define PCS_POWER_SOURCE_NAME                "pinctrl-single,power-source"
+#define PCS_SCHMITT_NAME             "pinctrl-single,input-schmitt"
 #define PCS_REG_NAME_LEN             ((sizeof(unsigned long) * 2) + 1)
 #define PCS_OFF_DISABLED             ~0U
 #define PCS_MAX_GPIO_VALUES          3

Here too you can remove the new defines.

Quoted 6 lines

static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
struct device_node *np, struct pinctrl_map **map,
+ unsigned num_configs,
const char **pgnames)
{

...

Quoted 9 lines

Then I suggest you add a generic pinconf-generic property to indicate the controller supports pinconf. At least for omaps, only some register ranges support pinconf. And by adding pinconf-generic, you can parse it once during the probe of pinctrl-single.c, and set pcs->pinconf flag.

Then you can use here and avoid calling of_property_read_u32 for about 600 times unnecessarily for omap4:

I don't want to add new property for this. I think that we can use compatible name instead.

"pinctrl-single" is only for pinmux & gpio range. "pinconf-single" is for pinmux & gpio range & generic pinconf.

#6 lore raw

PATCH v3 4/9 ARM: dts: support pinctrl single in pxa910

In reply to Haojian Zhuang

Add pinctrl-single support with device tree in pxa910 dkb platform.

---
 arch/arm/boot/dts/pxa910-dkb.dts |  187 +++++++++++++++++++++++++++++++++++++-
 arch/arm/boot/dts/pxa910.dtsi    |   77 ++++++++++++++++
 2 files changed, 263 insertions(+), 1 deletion(-)
arch/arm/boot/dts/pxa910-dkb.dts +186 -1
index 595492a..394396a 100644
@@ -24,10 +24,195 @@
 
 	soc {
 		apb at d4000000 {
-			uart1: uart at d4017000 {
+			pmx: pinmux at d401e000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&board_pins>;
+
+				board_pins: pinmux_board_pins {
+					/* pins not owned by device driver */
+				};
+				uart1_pins: pinmux_uart1_pins {
+					pinctrl-single,pins = <
+						0x198 0x6	/* GPIO47_UART1_RXD */
+						0x19c 0x6	/* GPIO48_UART1_TXD */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0x6>;
+				};
+				uart2_pins: pinmux_uart2_pins {
+					pinctrl-single,pins = <
+						0x150 0x4	/* GPIO29_UART2_CTS */
+						0x154 0x4	/* GPIO30_UART2_RTS */
+						0x158 0x4	/* GPIO31_UART2_TXD */
+						0x15c 0x4	/* GPIO32_UART2_RXD */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				uart3_pins: pinmux_uart3_pins {
+					pinctrl-single,pins = <
+						0x188 0x7	/* GPIO43_UART3_RXD */
+						0x18c 0x7	/* GPIO44_UART3_TXD */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				twsi1_pins: pinmux_twsi1_pins {
+					pinctrl-single,pins = <
+						0x1b0 0x2	/* GPIO53_TWSI_SCL */
+						0x1b4 0x2	/* GPIO54_TWSI_SDA */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				nand_pins: pinmux_nand_pins {
+					pinctrl-single,pins = <
+						0x040 0x0	/* ND_IO0 */
+						0x03c 0x0	/* ND_IO1 */
+						0x038 0x0	/* ND_IO2 */
+						0x034 0x0	/* ND_IO3 */
+						0x030 0x0	/* ND_IO4 */
+						0x02c 0x0	/* ND_IO5 */
+						0x028 0x0	/* ND_IO6 */
+						0x024 0x0	/* ND_IO7 */
+						0x020 0x0	/* ND_IO8 */
+						0x01c 0x0	/* ND_IO9 */
+						0x018 0x0	/* ND_IO10 */
+						0x014 0x0	/* ND_IO11 */
+						0x010 0x0	/* ND_IO12 */
+						0x00c 0x0	/* ND_IO13 */
+						0x008 0x0	/* ND_IO14 */
+						0x004 0x0	/* ND_IO15 */
+						0x044 0x0	/* ND_nCS0 */
+						0x060 0x1	/* ND_ALE */
+						0x05c 0x0	/* ND_CLE */
+						0x054 0x1	/* ND_nWE */
+						0x058 0x1	/* ND_nRE */
+						0x068 0x0	/* ND_RDY0 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc1_ldata_pins: pinmux_mmc1_ldata_pins {
+					pinctrl-single,pins = <
+						0x0a0 0x0	/* MMC1_DATA0 */
+						0x09c 0x0	/* MMC1_DATA1 */
+						0x098 0x0	/* MMC1_DATA2 */
+						0x094 0x0	/* MMC1_DATA3 */
+					>;
+					pinctrl-single,power-source = <0x3>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc1_hdata_pins: pinmux_mmc1_hdata_pins {
+					pinctrl-single,pins = <
+						0x090 0x0	/* MMC1_DATA4 */
+						0x08c 0x0	/* MMC1_DATA5 */
+						0x088 0x0	/* MMC1_DATA6 */
+						0x084 0x0	/* MMC1_DATA7 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc1_clk_pins: pinmux_mmc1_clk_pins {
+					pinctrl-single,pins = <
+						0x0a4 0x0	/* MMC1_CMD */
+						0x0a8 0x0	/* MMC1_CLK */
+					>;
+					pinctrl-single,power-source = <0x3>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc1_cd_pins: pinmux_mmc1_cd_pins {
+					pinctrl-single,pins = <
+						0x0ac 0x0	/* MMC1_CD */
+						0x0b0 0x0	/* MMC1_WP */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc2_pins: pinmux_mmc2_pins {
+					pinctrl-single,pins = <
+						0x180 0x1	/* MMC2_CMD */
+						0x184 0x1	/* MMC2_CLK */
+						0x17c 0x1	/* MMC2_DATA0 */
+						0x178 0x1	/* MMC2_DATA1 */
+						0x174 0x1	/* MMC2_DATA2 */
+						0x170 0x1	/* MMC2_DATA3 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				w1_pins: pinmux_w1_pins {
+					pinctrl-single,pins = <
+						0x0cc 0x2	/* CLK_REQ_W1 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				ssp1_pins: pinmux_ssp1_pins {
+					pinctrl-single,pins = <
+						0x130 0x1	/* GPIO21_SSP1_SCLK */
+						0x134 0x1	/* GPIO22_SSP1_FRM */
+						0x138 0x1	/* GPIO23_SSP1_TXD */
+						0x13c 0x1	/* GPIO24_SSP1_RXD */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				keypad_pins: pinmux_keypad_pins {
+					pinctrl-single,pins = <
+						0x0dc 0x1	/* GPIO0_MKIN0 */
+						0x0e0 0x1	/* GPIO1_MKOUT0 */
+						0x0e4 0x1	/* GPIO2_MKIN1 */
+						0x0e8 0x1	/* GPIO3_MKOUT1 */
+						0x0ec 0x1	/* GPIO4_MKIN2 */
+						0x0f0 0x1	/* GPIO5_MKOUT2 */
+						0x0f4 0x1	/* GPIO6_MKIN3 */
+						0x0f8 0x1	/* GPIO7_MKOUT3 */
+						0x0fc 0x1	/* GPIO8_MKIN4 */
+						0x100 0x1	/* GPIO9_MKOUT4 */
+						0x10c 0x1	/* GPIO12_MKIN6 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				nfc_pins: pinmux_nfc_pins {
+					pinctrl-single,pins = <
+						0x120 0x0	/* GPIO17 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				wlan_pins: pinmux_wlan_pins {
+					pinctrl-single,pins = <
+						0x114 0x0	/* GPIO14 */
+						0x12c 0x0	/* GPIO20 */
+						0x160 0x0	/* GPIO33 */
+						0x164 0x0	/* GPIO34 */
+						0x168 0x0	/* GPIO35 */
+						0x16c 0x0	/* GPIO36 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+			};
+			uart1: uart at d4017000 {	/* FFUART */
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart1_pins>;
+				status = "okay";
+			};
+			uart2: uart at d4018000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart2_pins>;
+				status = "okay";
+			};
+			uart3: uart at d4036000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart3_pins>;
 				status = "okay";
 			};
 			twsi1: i2c at d4011000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&twsi1_pins>;
 				status = "okay";
 
 				pmic: 88pm860x at 34 {
arch/arm/boot/dts/pxa910.dtsi +77 -0

83 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#7 lore raw

PATCH v3 5/9 document: devicetree: bind pinconf with pin-single

In reply to Haojian Zhuang

Add comments with pinconf & gpio range in the document of pinctrl-single.

---
 .../devicetree/bindings/pinctrl/pinctrl-single.txt |   66 ++++++++++++++++++++
 1 file changed, 66 insertions(+)
Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +66 -0
index 2c81e45..15f4dae 100644
@@ -17,6 +17,41 @@ Optional properties:
 - pinctrl-single,bit-per-mux : boolean to indicate that one register controls
   more than one pin
 
+- pinctrl-single,gpio-ranges : gpio range list of phandles.
+  Must be present if gpio range phandle is specified.
+  This property should be existing in .dtsi files for those silicons.
+
+- pinctrl-single,gpio : array with gpio range start, size & register
+  offset. Must be present if gpio range phandle is specified.
+  This property should be existing in .dts files for those boards.
+
+- pinctrl-single,gpio-func : gpio function value in the pinmux register.
+  Must be present if gpio range phandle is specified.
+  This property should be existing in .dts files for those boards.
+
+- pinctrl-single,power-source-mask : mask of setting power source in
+  the pinmux register
+
+- pinctrl-single,power-source : value of setting power source field
+  in the pinmux register
+
+- pinctrl-single,bias-mask : mask of setting bias value in the pinmux
+  register
+
+- pinctrl-single,bias-disable : value of disabling bias in the pinmux
+  register
+
+- pinctrl-single,bias-pull-down : value of setting bias pull down in
+  the pinmux register
+
+- pinctrl-single,bias-pull-up : value of setting bias pull up in the
+  pinmux register
+
+- pinctrl-single,bias : value of setting bias in the pinmux register
+
+- pinctrl-single,input-schmitt-mask : mask of setting input schmitt
+  in the pinmux register
+
 This driver assumes that there is only one register for each pin (unless the
 pinctrl-single,bit-per-mux is set), and uses the common pinctrl bindings as
 specified in the pinctrl-bindings.txt document in this directory.
@@ -42,6 +77,15 @@ Where 0xdc is the offset from the pinctrl register base address for the
 device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to
 be used when applying this change to the register.
 
+In case pinctrl device supports gpio function, it needs to define gpio range.
+All the phandles of gpio range list should be set in below:
+
+	pinctrl-single,gpio-ranges = <[phandle of gpio range]>;
+
+	[phandle of gpio range]: {
+		pinctrl-single,gpio = <0 55 0x0dc>;
+		pinctrl-single,gpio-func = <0>;
+	};
 Example:
 
 /* SoC common file */
@@ -76,6 +120,28 @@ control_devconf0: pinmux at 48002274 {
 	pinctrl-single,function-mask = <0x5F>;
 };
 
+/* third controller instance for pins in gpio domain */
+pmx_gpio: pinmux at d401e000 {
+	compatible = "pinctrl-single";
+	reg = <0xd401e000 0x0330>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-single,register-width = <32>;
+	pinctrl-single,function-mask = <7>;
+	pinctrl-single,gpio-ranges = <&gpiorange0 &gpiorange1>;
+};
+
+gpiorange0: gpiorange at d401e0dc {
+	pinctrl-single,gpio = <0 55 0x0dc>;
+	pinctrl-single,gpio-func = <0>;
+};
+
+gpiorange1: gpiorange at d401e2f0 {
+	pinctrl-single,gpio = <55 5 0x2f0>;
+	pinctrl-single,gpio-func = <1>;
+};
+
+
 /* board specific .dts file */
 
 &pmx_core {
Signature · 1 line
1.7.10.4
#8 lore raw

PATCH v3 5/9 document: devicetree: bind pinconf with pin-single

Quoted 2 lines · Haojian Zhuang

Add comments with pinconf & gpio range in the document of pinctrl-single.

I'd tend to suggest separating the series to add GPIO range support and pinconf support, especially since didn't Tony suggest a separate driver for pinconf? Perhaps that was just for non-generic properties.

Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt Optional properties: · line 30

Quoted 13 lines

+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt

+- pinctrl-single,gpio-ranges : gpio range list of phandles.

Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +10 -0
+  Must be present if gpio range phandle is specified.
+  This property should be existing in .dtsi files for those silicons.
+
+- pinctrl-single,gpio : array with gpio range start, size & register
+  offset. Must be present if gpio range phandle is specified.
+  This property should be existing in .dts files for those boards.
+
+- pinctrl-single,gpio-func : gpio function value in the pinmux register.
+  Must be present if gpio range phandle is specified.
+  This property should be existing in .dts files for those boards.

I don't see any reason why pinctrl-single,gpio or pinctrl-single,gpio-func are board-specific rather than SoC-specific. Surely it's the Soc HW construction that defines how the pinctrl and GPIO modules relate to each-other? I would simply remove the last sentence from each of the three descriptions above.

Also, isn't this list a list of properties for the main pinctrl-single node itself? I think you should split the list up as follows:

1) A description of the main node
2) A list of required and optional properties for the main node
3) A description of what a GPIO range node is
4) A list of required and optional properties for a GPIO range node.

I think that would explain the whole structure a lot more clearly.

Oh, and why not just get rid of the pinctrl-single,gpio-ranges property entirely, and simply make the GPIO range definitions be child nodes of the pinctrl-single node? That would require them to either be named according to some scheme or have some compatible property to differentiate them from any other nodes, but I think that's workable.

Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt Where 0xdc is the offset from the pinctrl register base address for the · line 85

Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +6 -0
@@ -42,6 +77,15 @@ Where 0xdc is the offset from the pinctrl register base address for the
 device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to
 be used when applying this change to the register.
 
+In case pinctrl device supports gpio function, it needs to define gpio range.
+All the phandles of gpio range list should be set in below:
+
+	pinctrl-single,gpio-ranges = <[phandle of gpio range]>;
+
+	[phandle of gpio range]: {

That's a label, not a phandle. The reference to the label gets compiled to a phandle in the DTB. The node name is missing. you should probably just use an example label and re-write the last 3 lines as:

	pinctrl-single,gpio-ranges = <&range0>;

	range0: range0 {
maintainer
#9 lore raw

PATCH v3 5/9 document: devicetree: bind pinconf with pin-single

Quoted 7 lines · Stephen Warren
Quoted 2 lines · Haojian Zhuang

Add comments with pinconf & gpio range in the document of pinctrl-single.

I'd tend to suggest separating the series to add GPIO range support and pinconf support, especially since didn't Tony suggest a separate driver for pinconf? Perhaps that was just for non-generic properties.

Well I was just thinking setting them up as separate driver instances for the register ranges supporting pinconf and not supporting pinconf. This combined with some pinconf property parsed during pinctrl-single.c probe time allows saving lots of unnecessary parsing of properties for register ranges that don't support pinconf. At least for omaps we have few hundred registers that don't support pinconf, and then some separate random register that do.

Regards,

TOny

#10 lore raw

PATCH v3 5/9 document: devicetree: bind pinconf with pin-single

In reply to Stephen Warren
Quoted 10 lines · Stephen Warren
Quoted 2 lines · Haojian Zhuang

Add comments with pinconf & gpio range in the document of pinctrl-single.

I'd tend to suggest separating the series to add GPIO range support and pinconf support, especially since didn't Tony suggest a separate driver for pinconf? Perhaps that was just for non-generic properties.

Quoted 1 line

+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt

Quoted 14 lines

Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt Optional properties: · line 30

Quoted 11 lines

+- pinctrl-single,gpio-ranges : gpio range list of phandles.

Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +10 -0
+  Must be present if gpio range phandle is specified.
+  This property should be existing in .dtsi files for those silicons.
+
+- pinctrl-single,gpio : array with gpio range start, size & register
+  offset. Must be present if gpio range phandle is specified.
+  This property should be existing in .dts files for those boards.
+
+- pinctrl-single,gpio-func : gpio function value in the pinmux register.
+  Must be present if gpio range phandle is specified.
+  This property should be existing in .dts files for those boards.

I don't see any reason why pinctrl-single,gpio or pinctrl-single,gpio-func are board-specific rather than SoC-specific.

Oh, I wrote it with error. It should be SoC-specific.

Quoted 12 lines

Surely it's the Soc HW construction that defines how the pinctrl and GPIO modules relate to each-other? I would simply remove the last sentence from each of the three descriptions above.

Also, isn't this list a list of properties for the main pinctrl-single node itself? I think you should split the list up as follows:

1) A description of the main node
2) A list of required and optional properties for the main node
3) A description of what a GPIO range node is
4) A list of required and optional properties for a GPIO range node.

Quoted 8 lines

I think that would explain the whole structure a lot more clearly.

Oh, and why not just get rid of the pinctrl-single,gpio-ranges property entirely, and simply make the GPIO range definitions be child nodes of the pinctrl-single node? That would require them to either be named according to some scheme or have some compatible property to differentiate them from any other nodes, but I think that's workable.

Em. Removing pinctrl-single,gpio-ranges should be better. Now I define range as sub node. There're two properties in this sub-node: reg & pinctrl-single,gpio.

Quoted 15 lines

Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt Where 0xdc is the offset from the pinctrl register base address for the · line 85

Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +6 -0
@@ -42,6 +77,15 @@ Where 0xdc is the offset from the pinctrl register base address for the
 device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to
 be used when applying this change to the register.
 
+In case pinctrl device supports gpio function, it needs to define gpio range.
+All the phandles of gpio range list should be set in below:
+
+     pinctrl-single,gpio-ranges = <[phandle of gpio range]>;
+
+     [phandle of gpio range]: {

That's a label, not a phandle. The reference to the label gets compiled to a phandle in the DTB. The node name is missing. you should probably just use an example label and re-write the last 3 lines as:

Quoted 4 lines
        pinctrl-single,gpio-ranges = <&range0>;

        range0: range0 {

Updated.

#11 lore raw

PATCH v3 6/9 tty: pxa: configure pin

In reply to Haojian Zhuang

Configure pins by pinctrl driver.

---
 drivers/tty/serial/pxa.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/tty/serial/pxa.c +7 -1
index 9033fc6..02dc771 100644
@@ -37,6 +37,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -809,6 +810,7 @@ static int serial_pxa_probe_dt(struct platform_device *pdev,
 			       struct uart_pxa_port *sport)
 {
 	struct device_node *np = pdev->dev.of_node;
+	struct pinctrl *pinctrl;
 	int ret;
 
 	if (!np)
@@ -819,6 +821,10 @@ static int serial_pxa_probe_dt(struct platform_device *pdev,
 		dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
 		return ret;
 	}
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl))
+		return -EPROBE_DEFER;
+
 	sport->port.line = ret;
 	return 0;
 }
@@ -857,7 +863,7 @@ static int serial_pxa_probe(struct platform_device *dev)
 	ret = serial_pxa_probe_dt(dev, sport);
 	if (ret > 0)
 		sport->port.line = dev->id;
-	else if (ret < 0)
+	if (ret < 0)
 		goto err_clk;
 	snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1);
 
Signature · 1 line
1.7.10.4
#12 lore raw

PATCH v3 7/9 i2c: pxa: use devm_kzalloc

In reply to Haojian Zhuang

Use devm_kzalloc & add checking in probe() function.

---
 drivers/i2c/busses/i2c-pxa.c |   26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)
drivers/i2c/busses/i2c-pxa.c +10 -16
index 1034d93..7c8b5d0 100644
@@ -1078,6 +1078,8 @@ static int i2c_pxa_probe_pdata(struct platform_device *pdev,
 	struct i2c_pxa_platform_data *plat = pdev->dev.platform_data;
 	const struct platform_device_id *id = platform_get_device_id(pdev);
 
+	if (!id)
+		return -EINVAL;
 	*i2c_types = id->driver_data;
 	if (plat) {
 		i2c->use_pio = plat->use_pio;
@@ -1094,29 +1096,23 @@ static int i2c_pxa_probe(struct platform_device *dev)
 	struct resource *res = NULL;
 	int ret, irq;
 
-	i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
-	if (!i2c) {
-		ret = -ENOMEM;
-		goto emalloc;
-	}
+	i2c = devm_kzalloc(&dev->dev, sizeof(struct pxa_i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
 
 	ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type);
 	if (ret > 0)
 		ret = i2c_pxa_probe_pdata(dev, i2c, &i2c_type);
 	if (ret < 0)
-		goto eclk;
+		return ret;
 
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(dev, 0);
-	if (res == NULL || irq < 0) {
-		ret = -ENODEV;
-		goto eclk;
-	}
+	if (res == NULL || irq < 0)
+		return -ENODEV;
 
-	if (!request_mem_region(res->start, resource_size(res), res->name)) {
-		ret = -ENOMEM;
-		goto eclk;
-	}
+	if (!request_mem_region(res->start, resource_size(res), res->name))
+		return -ENOMEM;
 
 	i2c->adap.owner   = THIS_MODULE;
 	i2c->adap.retries = 5;
@@ -1209,8 +1205,6 @@ ereqirq:
 eremap:
 	clk_put(i2c->clk);
 eclk:
-	kfree(i2c);
-emalloc:
 	release_mem_region(res->start, resource_size(res));
 	return ret;
 }
Signature · 1 line
1.7.10.4
#13 lore raw

PATCH v3 8/9 i2c: pxa: configure pinmux

In reply to Haojian Zhuang

Configure pins by pinctrl driver.

---
 drivers/i2c/busses/i2c-pxa.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/i2c/busses/i2c-pxa.c +5 -0
index 7c8b5d0..11e4a30 100644
@@ -32,6 +32,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_i2c.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/clk.h>
@@ -1051,6 +1052,7 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
 			    enum pxa_i2c_types *i2c_types)
 {
 	struct device_node *np = pdev->dev.of_node;
+	struct pinctrl *pinctrl;
 	const struct of_device_id *of_id =
 			of_match_device(i2c_pxa_dt_ids, &pdev->dev);
 	int ret;
@@ -1063,6 +1065,9 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
 		return ret;
 	}
 	pdev->id = ret;
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl))
+		return -EPROBE_DEFER;
 	if (of_get_property(np, "mrvl,i2c-polling", NULL))
 		i2c->use_pio = 1;
 	if (of_get_property(np, "mrvl,i2c-fast-mode", NULL))
Signature · 1 line
1.7.10.4
#14 lore raw

PATCH v3 9/9 pinctrl: single: dump pinmux register value

In reply to Haojian Zhuang

Dump pinmux register value, not only function part in the pinmux register.

Also fix the issue on caluclating pin offset. The last parameter should be pin number, not register offset.

---
 drivers/pinctrl/pinctrl-single.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/pinctrl/pinctrl-single.c +4 -4
index 3b97b65..72017e7 100644
@@ -283,15 +283,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
 
 static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
 					struct seq_file *s,
-					unsigned offset)
+					unsigned pin)
 {
 	struct pcs_device *pcs;
-	unsigned val;
+	unsigned val, mux_bytes;
 
 	pcs = pinctrl_dev_get_drvdata(pctldev);
 
-	val = pcs->read(pcs->base + offset);
-	val &= pcs->fmask;
+	mux_bytes = pcs->width / BITS_PER_BYTE;
+	val = pcs->read(pcs->base + pin * mux_bytes);
 
 	seq_printf(s, "%08x %s " , val, DRIVER_NAME);
 }
Signature · 1 line
1.7.10.4
maintainer
#15 lore raw

PATCH v3 9/9 pinctrl: single: dump pinmux register value

Quoted 5 lines · Haojian Zhuang

Dump pinmux register value, not only function part in the pinmux register.

Also fix the issue on caluclating pin offset. The last parameter should be pin number, not register offset.

You have a minor typo ^^^^^^^^^^^ should be calculating
instead.

Is there a bug that should be fixed for the -rc cycle here? That's the impression I get from the description. Or is it just a cosmetic fix to rename offset to pin?

Regards,

Tony

Quoted 32 lines
---
 drivers/pinctrl/pinctrl-single.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/pinctrl/pinctrl-single.c +4 -4
index 3b97b65..72017e7 100644
@@ -283,15 +283,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
 
 static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
 					struct seq_file *s,
-					unsigned offset)
+					unsigned pin)
 {
 	struct pcs_device *pcs;
-	unsigned val;
+	unsigned val, mux_bytes;
 
 	pcs = pinctrl_dev_get_drvdata(pctldev);
 
-	val = pcs->read(pcs->base + offset);
-	val &= pcs->fmask;
+	mux_bytes = pcs->width / BITS_PER_BYTE;
+	val = pcs->read(pcs->base + pin * mux_bytes);
 
 	seq_printf(s, "%08x %s " , val, DRIVER_NAME);
 }
Signature · 1 line
1.7.10.4
#16 lore raw

PATCH v3 9/9 pinctrl: single: dump pinmux register value

Quoted 45 lines · Tony Lindgren
Quoted 5 lines · Haojian Zhuang

Dump pinmux register value, not only function part in the pinmux register.

Also fix the issue on caluclating pin offset. The last parameter should be pin number, not register offset.

You have a minor typo ^^^^^^^^^^^ should be calculating
instead.

Is there a bug that should be fixed for the -rc cycle here? That's the impression I get from the description. Or is it just a cosmetic fix to rename offset to pin?

Regards,

Tony

Quoted 27 lines
---
 drivers/pinctrl/pinctrl-single.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/pinctrl/pinctrl-single.c +4 -4
index 3b97b65..72017e7 100644
@@ -283,15 +283,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
 
 static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
                                      struct seq_file *s,
-                                     unsigned offset)
+                                     unsigned pin)
 {
      struct pcs_device *pcs;
-     unsigned val;
+     unsigned val, mux_bytes;
 
      pcs = pinctrl_dev_get_drvdata(pctldev);
 
-     val = pcs->read(pcs->base + offset);
-     val &= pcs->fmask;
+     mux_bytes = pcs->width / BITS_PER_BYTE;
+     val = pcs->read(pcs->base + pin * mux_bytes);
 
Quoted 5 lines
Quoted 5 lines
drivers/pinctrl/pinctrl-single.c +0 -1
      seq_printf(s, "%08x %s " , val, DRIVER_NAME);
 }
--

1.7.10.4

There's also include a bug fix. I'm OK that this patch could be included in -rc cycle.

#17 lore raw

PATCH v3 9/9 pinctrl: single: dump pinmux register value

Quoted 18 lines · Haojian Zhuang
Quoted 16 lines · Tony Lindgren
Quoted 16 lines

static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s,

drivers/pinctrl/pinctrl-single.c +4 -4
-                                     unsigned offset)
+                                     unsigned pin)
 {
      struct pcs_device *pcs;
-     unsigned val;
+     unsigned val, mux_bytes;
 
      pcs = pinctrl_dev_get_drvdata(pctldev);
 
-     val = pcs->read(pcs->base + offset);
-     val &= pcs->fmask;
+     mux_bytes = pcs->width / BITS_PER_BYTE;
+     val = pcs->read(pcs->base + pin * mux_bytes);
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
      seq_printf(s, "%08x %s " , val, DRIVER_NAME);

}
--
1.7.10.4

There's also include a bug fix. I'm OK that this patch could be included in -rc cycle.

A debug print can by definition not be a regression, it should not have a specific use other than debugging.

And those debugging can use linux-next or separate patches or whatever ... better keep this series together.

Yours,
Linus Walleij