All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Cercueil <paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
To: Linus Walleij
	<linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>,
	Ralf Baechle <ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>,
	Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Boris Brezillon
	<boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Thierry Reding
	<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Bartlomiej Zolnierkiewicz
	<b.zolnierkie-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	Maarten ter Huurne
	<maarten-Ph2Y2OKCxY1M656bX5wj8A@public.gmane.org>,
	Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>,
	Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org,
	Paul Cercueil <paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
Subject: [PATCH v2 03/14] pinctrl-ingenic: add a pinctrl driver for the Ingenic jz47xx SoCs
Date: Sun, 22 Jan 2017 15:49:36 +0100	[thread overview]
Message-ID: <20170122144947.16158-4-paul@crapouillou.net> (raw)
In-Reply-To: <20170122144947.16158-1-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>

This driver handles pin configuration and pin muxing for the
JZ4740 and JZ4780 SoCs from Ingenic.

Signed-off-by: Paul Cercueil <paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
---
 drivers/pinctrl/Kconfig           |   8 +
 drivers/pinctrl/Makefile          |   1 +
 drivers/pinctrl/pinctrl-ingenic.c | 488 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 497 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-ingenic.c

v2: Consider it's a new patch. Completely rewritten from v1.

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8f8c2af45781..2312e21ca48d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -285,6 +285,14 @@ config PINCTRL_ZYNQ
 	help
 	  This selects the pinctrl driver for Xilinx Zynq.
 
+config PINCTRL_INGENIC
+	bool "Pinctrl driver for the Ingenic JZ47xx SoCs"
+	default y
+	depends on MACH_INGENIC || COMPILE_TEST
+	select GENERIC_PINCONF
+	select GENERIC_PINCTRL_GROUPS
+	select GENERIC_PINMUX_FUNCTIONS
+
 source "drivers/pinctrl/aspeed/Kconfig"
 source "drivers/pinctrl/bcm/Kconfig"
 source "drivers/pinctrl/berlin/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a251f439626f..80f327239d4b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_LPC18XX)	+= pinctrl-lpc18xx.o
 obj-$(CONFIG_PINCTRL_TB10X)	+= pinctrl-tb10x.o
 obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
 obj-$(CONFIG_PINCTRL_ZYNQ)	+= pinctrl-zynq.o
+obj-$(CONFIG_PINCTRL_INGENIC)	+= pinctrl-ingenic.o
 
 obj-$(CONFIG_ARCH_ASPEED)	+= aspeed/
 obj-y				+= bcm/
diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
new file mode 100644
index 000000000000..ce36cf509eb1
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ingenic.c
@@ -0,0 +1,488 @@
+/*
+ * Ingenic SoCs pinctrl driver
+ *
+ * Copyright (c) 2017 Paul Cercueil <paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/compiler.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "core.h"
+#include "pinconf.h"
+#include "pinmux.h"
+
+#define JZ4740_GPIO_DATA	0x10
+#define JZ4740_GPIO_PULL_DIS	0x30
+#define JZ4740_GPIO_FUNC	0x40
+#define JZ4740_GPIO_SELECT	0x50
+#define JZ4740_GPIO_DIR		0x60
+#define JZ4740_GPIO_TRIG	0x70
+#define JZ4740_GPIO_FLAG	0x80
+
+#define JZ4780_GPIO_INT		0x10
+#define JZ4780_GPIO_MSK		0x20
+#define JZ4780_GPIO_PAT1	0x30
+#define JZ4780_GPIO_PAT0	0x40
+#define JZ4780_GPIO_FLAG	0x50
+#define JZ4780_GPIO_PEN		0x70
+
+#define REG_SET(x) ((x) + 0x4)
+#define REG_CLEAR(x) ((x) + 0x8)
+
+#define PINS_PER_GPIO_CHIP 32
+#define NUM_MAX_GPIO_CHIPS 6
+
+enum jz_version {
+	ID_JZ4740,
+	ID_JZ4780,
+};
+
+struct ingenic_pinctrl {
+	struct device *dev;
+	void __iomem *base;
+	struct pinctrl_dev *pctl;
+	struct pinctrl_pin_desc *pdesc;
+	enum jz_version version;
+
+	u32 pull_ups[NUM_MAX_GPIO_CHIPS];
+	u32 pull_downs[NUM_MAX_GPIO_CHIPS];
+};
+
+static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
+		unsigned int pin, u8 reg, bool set)
+{
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	writel(BIT(idx), jzpc->base + offt * 0x100 +
+			(set ? REG_SET(reg) : REG_CLEAR(reg)));
+}
+
+static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
+		unsigned int pin, u8 reg)
+{
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	return readl(jzpc->base + offt * 0x100 + reg) & BIT(idx);
+}
+
+static struct pinctrl_ops ingenic_pctlops = {
+	.get_groups_count = pinctrl_generic_get_group_count,
+	.get_group_name = pinctrl_generic_get_group_name,
+	.get_group_pins = pinctrl_generic_get_group_pins,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+	.dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
+		int pin, int func)
+{
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	dev_dbg(jzpc->dev, "set pin P%c%u to function %u\n",
+			'A' + offt, idx, func);
+
+	if (jzpc->version >= ID_JZ4780) {
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_INT, false);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_MSK, false);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PAT1, func & 0x2);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PAT0, func & 0x1);
+	} else {
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
+	}
+
+	return 0;
+}
+
+static int ingenic_pinmux_set_mux(struct pinctrl_dev *pctldev,
+		unsigned int selector, unsigned int group)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	struct function_desc *func;
+	struct group_desc *grp;
+	unsigned int i;
+
+	func = pinmux_generic_get_function(pctldev, selector);
+	if (!func)
+		return -EINVAL;
+
+	grp = pinctrl_generic_get_group(pctldev, group);
+	if (!grp)
+		return -EINVAL;
+
+	dev_dbg(pctldev->dev, "enable function %s group %s\n",
+		func->name, grp->name);
+
+	for (i = 0; i < grp->num_pins; i++) {
+		int *pin_modes = grp->data;
+
+		ingenic_pinmux_set_pin_fn(jzpc, grp->pins[i], pin_modes[i]);
+	}
+
+	return 0;
+}
+
+static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
+		struct pinctrl_gpio_range *range,
+		unsigned int pin, bool input)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	dev_dbg(pctldev->dev, "set pin P%c%u to %sput\n",
+			'A' + offt, idx, input ? "in" : "out");
+
+	if (jzpc->version >= ID_JZ4780) {
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_INT, false);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_MSK, true);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PAT1, input);
+	} else {
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, input);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false);
+	}
+
+	return 0;
+}
+
+static struct pinmux_ops ingenic_pmxops = {
+	.get_functions_count = pinmux_generic_get_function_count,
+	.get_function_name = pinmux_generic_get_function_name,
+	.get_function_groups = pinmux_generic_get_function_groups,
+	.set_mux = ingenic_pinmux_set_mux,
+	.gpio_set_direction = ingenic_pinmux_gpio_set_direction,
+};
+
+static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
+		unsigned int pin, unsigned long *config)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+	bool pull;
+
+	if (jzpc->version >= ID_JZ4780)
+		pull = !ingenic_get_pin_config(jzpc, pin, JZ4780_GPIO_PEN);
+	else
+		pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pull)
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (!pull || !(jzpc->pull_ups[offt] & BIT(idx)))
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (!pull || !(jzpc->pull_downs[offt] & BIT(idx)))
+			return -EINVAL;
+		break;
+
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, 1);
+	return 0;
+}
+
+static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
+		unsigned int pin, bool enabled)
+{
+	if (jzpc->version >= ID_JZ4780)
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PEN, !enabled);
+	else
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled);
+}
+
+static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+		unsigned long *configs, unsigned int num_configs)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+	unsigned int cfg;
+
+	for (cfg = 0; cfg < num_configs; cfg++) {
+		switch (pinconf_to_config_param(configs[cfg])) {
+		case PIN_CONFIG_BIAS_DISABLE:
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			continue;
+		default:
+			return -ENOTSUPP;
+		}
+	}
+
+	for (cfg = 0; cfg < num_configs; cfg++) {
+		switch (pinconf_to_config_param(configs[cfg])) {
+		case PIN_CONFIG_BIAS_DISABLE:
+			dev_dbg(jzpc->dev, "disable pull-over for pin P%c%u\n",
+					'A' + offt, idx);
+			ingenic_set_bias(jzpc, pin, false);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_UP:
+			if (!(jzpc->pull_ups[offt] & BIT(idx)))
+				return -EINVAL;
+			dev_dbg(jzpc->dev, "set pull-up for pin P%c%u\n",
+					'A' + offt, idx);
+			ingenic_set_bias(jzpc, pin, true);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			if (!(jzpc->pull_downs[offt] & BIT(idx)))
+				return -EINVAL;
+			dev_dbg(jzpc->dev, "set pull-down for pin P%c%u\n",
+					'A' + offt, idx);
+			ingenic_set_bias(jzpc, pin, true);
+			break;
+
+		default:
+			unreachable();
+		}
+	}
+
+	return 0;
+}
+
+static int ingenic_pinconf_group_get(struct pinctrl_dev *pctldev,
+		unsigned int group, unsigned long *config)
+{
+	const unsigned *pins;
+	unsigned int i, npins, old = 0;
+	int ret;
+
+	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < npins; i++) {
+		if (ingenic_pinconf_get(pctldev, pins[i], config))
+			return -ENOTSUPP;
+
+		/* configs do not match between two pins */
+		if (i && (old != *config))
+			return -ENOTSUPP;
+
+		old = *config;
+	}
+
+	return 0;
+}
+
+static int ingenic_pinconf_group_set(struct pinctrl_dev *pctldev,
+		unsigned int group, unsigned long *configs,
+		unsigned int num_configs)
+{
+	const unsigned *pins;
+	unsigned int i, npins;
+	int ret;
+
+	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < npins; i++) {
+		ret = ingenic_pinconf_set(pctldev,
+				pins[i], configs, num_configs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static struct pinconf_ops ingenic_confops = {
+	.is_generic = true,
+	.pin_config_get = ingenic_pinconf_get,
+	.pin_config_set = ingenic_pinconf_set,
+	.pin_config_group_get = ingenic_pinconf_group_get,
+	.pin_config_group_set = ingenic_pinconf_group_set,
+};
+
+static int ingenic_pinctrl_parse_dt_func(struct ingenic_pinctrl *jzpc,
+		struct device_node *np)
+{
+	unsigned int num_groups;
+	struct device_node *group_node;
+	unsigned int i, j;
+	int err, npins, *pins, *confs;
+	const char **groups;
+
+	num_groups = of_get_child_count(np);
+	groups = devm_kzalloc(jzpc->dev,
+			sizeof(*groups) * num_groups, GFP_KERNEL);
+	if (!groups)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node(np, group_node) {
+		groups[i++] = group_node->name;
+
+		npins = of_property_count_elems_of_size(group_node,
+				"ingenic,pins", 8);
+		if (npins < 0)
+			return npins;
+
+		pins = devm_kzalloc(jzpc->dev,
+				sizeof(*pins) * npins, GFP_KERNEL);
+		confs = devm_kzalloc(jzpc->dev,
+				sizeof(*confs) * npins, GFP_KERNEL);
+		if (!pins || !confs)
+			return -ENOMEM;
+
+		for (j = 0; j < npins; j++) {
+			of_property_read_u32_index(group_node,
+					"ingenic,pins", j * 2, &pins[j]);
+
+			of_property_read_u32_index(group_node,
+					"ingenic,pins", j * 2 + 1, &confs[j]);
+		}
+
+		err = pinctrl_generic_add_group(jzpc->pctl, group_node->name,
+				pins, npins, confs);
+		if (err)
+			return err;
+	}
+
+	return pinmux_generic_add_function(jzpc->pctl, np->name,
+			groups, num_groups, NULL);
+}
+
+static const struct of_device_id ingenic_pinctrl_of_match[] = {
+	{ .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
+	{ .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
+	{},
+};
+
+int ingenic_pinctrl_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ingenic_pinctrl *jzpc;
+	struct pinctrl_desc *pctl_desc;
+	struct device_node *np, *functions_node;
+	const struct of_device_id *of_id = of_match_device(
+			ingenic_pinctrl_of_match, dev);
+	unsigned int i, num_chips;
+	int err;
+
+	jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL);
+	if (!jzpc)
+		return -ENOMEM;
+
+	jzpc->base = of_iomap(dev->of_node, 0);
+	if (!jzpc->base) {
+		dev_err(dev, "failed to map IO memory\n");
+		return -ENXIO;
+	}
+
+	jzpc->dev = dev;
+	dev_set_drvdata(dev, jzpc);
+
+	jzpc->version = (enum jz_version)of_id->data;
+
+	if (jzpc->version >= ID_JZ4780)
+		num_chips = 6;
+	else
+		num_chips = 4;
+
+	/*
+	 * Read the ingenic,pull-ups and ingenic,pull-downs arrays if present in
+	 * the devicetree. Otherwise set all bits to 0xff to consider that
+	 * pull-over resistors are available on all pins.
+	 */
+	err = of_property_read_u32_array(dev->of_node, "ingenic,pull-ups",
+			jzpc->pull_ups, num_chips);
+	if (err)
+		memset(jzpc->pull_ups, 0xff, sizeof(jzpc->pull_ups));
+
+	err = of_property_read_u32_array(dev->of_node, "ingenic,pull-downs",
+			jzpc->pull_downs, num_chips);
+	if (err)
+		memset(jzpc->pull_downs, 0xff, sizeof(jzpc->pull_downs));
+
+	functions_node = of_find_node_by_name(dev->of_node, "functions");
+	if (!functions_node) {
+		dev_err(dev, "Missing \"functions\" devicetree node\n");
+		return -EINVAL;
+	}
+
+	pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
+	if (!pctl_desc)
+		return -ENOMEM;
+
+	/* fill in pinctrl_desc structure */
+	pctl_desc->name = dev_name(dev);
+	pctl_desc->owner = THIS_MODULE;
+	pctl_desc->pctlops = &ingenic_pctlops;
+	pctl_desc->pmxops = &ingenic_pmxops;
+	pctl_desc->confops = &ingenic_confops;
+	pctl_desc->npins = num_chips * PINS_PER_GPIO_CHIP;
+	pctl_desc->pins = jzpc->pdesc = devm_kzalloc(&pdev->dev,
+			sizeof(*jzpc->pdesc) * pctl_desc->npins, GFP_KERNEL);
+	if (!jzpc->pdesc)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl_desc->npins; i++) {
+		jzpc->pdesc[i].number = i;
+		jzpc->pdesc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
+						'A' + (i / PINS_PER_GPIO_CHIP),
+						i % PINS_PER_GPIO_CHIP);
+	}
+
+	jzpc->pctl = devm_pinctrl_register(dev, pctl_desc, jzpc);
+	if (!jzpc->pctl) {
+		dev_err(dev, "Failed pinctrl registration\n");
+		return -EINVAL;
+	}
+
+	for_each_child_of_node(functions_node, np) {
+		err = ingenic_pinctrl_parse_dt_func(jzpc, np);
+		if (err) {
+			dev_err(dev, "failed to parse function %s\n",
+					np->full_name);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+static struct platform_driver ingenic_pinctrl_driver = {
+	.driver = {
+		.name = "pinctrl-ingenic",
+		.of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
+		.suppress_bind_attrs = true,
+	},
+	.probe = ingenic_pinctrl_probe,
+};
+
+static int __init ingenic_pinctrl_drv_register(void)
+{
+	return platform_driver_register(&ingenic_pinctrl_driver);
+}
+postcore_initcall(ingenic_pinctrl_drv_register);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: Paul Cercueil <paul@crapouillou.net>
To: Linus Walleij <linus.walleij@linaro.org>,
	Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Ralf Baechle <ralf@linux-mips.org>,
	Ulf Hansson <ulf.hansson@linaro.org>
Cc: Boris Brezillon <boris.brezillon@free-electrons.com>,
	Thierry Reding <thierry.reding@gmail.com>,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	Maarten ter Huurne <maarten@treewalker.org>,
	Lars-Peter Clausen <lars@metafoo.de>,
	Paul Burton <paul.burton@imgtec.com>,
	linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mips@linux-mips.org,
	linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org,
	linux-pwm@vger.kernel.org, linux-fbdev@vger.kernel.org,
	james.hogan@imgtec.com, Paul Cercueil <paul@crapouillou.net>
Subject: [PATCH v2 03/14] pinctrl-ingenic: add a pinctrl driver for the Ingenic jz47xx SoCs
Date: Sun, 22 Jan 2017 15:49:36 +0100	[thread overview]
Message-ID: <20170122144947.16158-4-paul@crapouillou.net> (raw)
In-Reply-To: <20170122144947.16158-1-paul@crapouillou.net>

This driver handles pin configuration and pin muxing for the
JZ4740 and JZ4780 SoCs from Ingenic.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/pinctrl/Kconfig           |   8 +
 drivers/pinctrl/Makefile          |   1 +
 drivers/pinctrl/pinctrl-ingenic.c | 488 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 497 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-ingenic.c

v2: Consider it's a new patch. Completely rewritten from v1.

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8f8c2af45781..2312e21ca48d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -285,6 +285,14 @@ config PINCTRL_ZYNQ
 	help
 	  This selects the pinctrl driver for Xilinx Zynq.
 
+config PINCTRL_INGENIC
+	bool "Pinctrl driver for the Ingenic JZ47xx SoCs"
+	default y
+	depends on MACH_INGENIC || COMPILE_TEST
+	select GENERIC_PINCONF
+	select GENERIC_PINCTRL_GROUPS
+	select GENERIC_PINMUX_FUNCTIONS
+
 source "drivers/pinctrl/aspeed/Kconfig"
 source "drivers/pinctrl/bcm/Kconfig"
 source "drivers/pinctrl/berlin/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a251f439626f..80f327239d4b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_LPC18XX)	+= pinctrl-lpc18xx.o
 obj-$(CONFIG_PINCTRL_TB10X)	+= pinctrl-tb10x.o
 obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
 obj-$(CONFIG_PINCTRL_ZYNQ)	+= pinctrl-zynq.o
+obj-$(CONFIG_PINCTRL_INGENIC)	+= pinctrl-ingenic.o
 
 obj-$(CONFIG_ARCH_ASPEED)	+= aspeed/
 obj-y				+= bcm/
diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
new file mode 100644
index 000000000000..ce36cf509eb1
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ingenic.c
@@ -0,0 +1,488 @@
+/*
+ * Ingenic SoCs pinctrl driver
+ *
+ * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/compiler.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "core.h"
+#include "pinconf.h"
+#include "pinmux.h"
+
+#define JZ4740_GPIO_DATA	0x10
+#define JZ4740_GPIO_PULL_DIS	0x30
+#define JZ4740_GPIO_FUNC	0x40
+#define JZ4740_GPIO_SELECT	0x50
+#define JZ4740_GPIO_DIR		0x60
+#define JZ4740_GPIO_TRIG	0x70
+#define JZ4740_GPIO_FLAG	0x80
+
+#define JZ4780_GPIO_INT		0x10
+#define JZ4780_GPIO_MSK		0x20
+#define JZ4780_GPIO_PAT1	0x30
+#define JZ4780_GPIO_PAT0	0x40
+#define JZ4780_GPIO_FLAG	0x50
+#define JZ4780_GPIO_PEN		0x70
+
+#define REG_SET(x) ((x) + 0x4)
+#define REG_CLEAR(x) ((x) + 0x8)
+
+#define PINS_PER_GPIO_CHIP 32
+#define NUM_MAX_GPIO_CHIPS 6
+
+enum jz_version {
+	ID_JZ4740,
+	ID_JZ4780,
+};
+
+struct ingenic_pinctrl {
+	struct device *dev;
+	void __iomem *base;
+	struct pinctrl_dev *pctl;
+	struct pinctrl_pin_desc *pdesc;
+	enum jz_version version;
+
+	u32 pull_ups[NUM_MAX_GPIO_CHIPS];
+	u32 pull_downs[NUM_MAX_GPIO_CHIPS];
+};
+
+static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
+		unsigned int pin, u8 reg, bool set)
+{
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	writel(BIT(idx), jzpc->base + offt * 0x100 +
+			(set ? REG_SET(reg) : REG_CLEAR(reg)));
+}
+
+static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
+		unsigned int pin, u8 reg)
+{
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	return readl(jzpc->base + offt * 0x100 + reg) & BIT(idx);
+}
+
+static struct pinctrl_ops ingenic_pctlops = {
+	.get_groups_count = pinctrl_generic_get_group_count,
+	.get_group_name = pinctrl_generic_get_group_name,
+	.get_group_pins = pinctrl_generic_get_group_pins,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+	.dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
+		int pin, int func)
+{
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	dev_dbg(jzpc->dev, "set pin P%c%u to function %u\n",
+			'A' + offt, idx, func);
+
+	if (jzpc->version >= ID_JZ4780) {
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_INT, false);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_MSK, false);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PAT1, func & 0x2);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PAT0, func & 0x1);
+	} else {
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
+	}
+
+	return 0;
+}
+
+static int ingenic_pinmux_set_mux(struct pinctrl_dev *pctldev,
+		unsigned int selector, unsigned int group)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	struct function_desc *func;
+	struct group_desc *grp;
+	unsigned int i;
+
+	func = pinmux_generic_get_function(pctldev, selector);
+	if (!func)
+		return -EINVAL;
+
+	grp = pinctrl_generic_get_group(pctldev, group);
+	if (!grp)
+		return -EINVAL;
+
+	dev_dbg(pctldev->dev, "enable function %s group %s\n",
+		func->name, grp->name);
+
+	for (i = 0; i < grp->num_pins; i++) {
+		int *pin_modes = grp->data;
+
+		ingenic_pinmux_set_pin_fn(jzpc, grp->pins[i], pin_modes[i]);
+	}
+
+	return 0;
+}
+
+static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
+		struct pinctrl_gpio_range *range,
+		unsigned int pin, bool input)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	dev_dbg(pctldev->dev, "set pin P%c%u to %sput\n",
+			'A' + offt, idx, input ? "in" : "out");
+
+	if (jzpc->version >= ID_JZ4780) {
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_INT, false);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_MSK, true);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PAT1, input);
+	} else {
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, input);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false);
+	}
+
+	return 0;
+}
+
+static struct pinmux_ops ingenic_pmxops = {
+	.get_functions_count = pinmux_generic_get_function_count,
+	.get_function_name = pinmux_generic_get_function_name,
+	.get_function_groups = pinmux_generic_get_function_groups,
+	.set_mux = ingenic_pinmux_set_mux,
+	.gpio_set_direction = ingenic_pinmux_gpio_set_direction,
+};
+
+static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
+		unsigned int pin, unsigned long *config)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+	bool pull;
+
+	if (jzpc->version >= ID_JZ4780)
+		pull = !ingenic_get_pin_config(jzpc, pin, JZ4780_GPIO_PEN);
+	else
+		pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pull)
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (!pull || !(jzpc->pull_ups[offt] & BIT(idx)))
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (!pull || !(jzpc->pull_downs[offt] & BIT(idx)))
+			return -EINVAL;
+		break;
+
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, 1);
+	return 0;
+}
+
+static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
+		unsigned int pin, bool enabled)
+{
+	if (jzpc->version >= ID_JZ4780)
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PEN, !enabled);
+	else
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled);
+}
+
+static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+		unsigned long *configs, unsigned int num_configs)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+	unsigned int cfg;
+
+	for (cfg = 0; cfg < num_configs; cfg++) {
+		switch (pinconf_to_config_param(configs[cfg])) {
+		case PIN_CONFIG_BIAS_DISABLE:
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			continue;
+		default:
+			return -ENOTSUPP;
+		}
+	}
+
+	for (cfg = 0; cfg < num_configs; cfg++) {
+		switch (pinconf_to_config_param(configs[cfg])) {
+		case PIN_CONFIG_BIAS_DISABLE:
+			dev_dbg(jzpc->dev, "disable pull-over for pin P%c%u\n",
+					'A' + offt, idx);
+			ingenic_set_bias(jzpc, pin, false);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_UP:
+			if (!(jzpc->pull_ups[offt] & BIT(idx)))
+				return -EINVAL;
+			dev_dbg(jzpc->dev, "set pull-up for pin P%c%u\n",
+					'A' + offt, idx);
+			ingenic_set_bias(jzpc, pin, true);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			if (!(jzpc->pull_downs[offt] & BIT(idx)))
+				return -EINVAL;
+			dev_dbg(jzpc->dev, "set pull-down for pin P%c%u\n",
+					'A' + offt, idx);
+			ingenic_set_bias(jzpc, pin, true);
+			break;
+
+		default:
+			unreachable();
+		}
+	}
+
+	return 0;
+}
+
+static int ingenic_pinconf_group_get(struct pinctrl_dev *pctldev,
+		unsigned int group, unsigned long *config)
+{
+	const unsigned *pins;
+	unsigned int i, npins, old = 0;
+	int ret;
+
+	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < npins; i++) {
+		if (ingenic_pinconf_get(pctldev, pins[i], config))
+			return -ENOTSUPP;
+
+		/* configs do not match between two pins */
+		if (i && (old != *config))
+			return -ENOTSUPP;
+
+		old = *config;
+	}
+
+	return 0;
+}
+
+static int ingenic_pinconf_group_set(struct pinctrl_dev *pctldev,
+		unsigned int group, unsigned long *configs,
+		unsigned int num_configs)
+{
+	const unsigned *pins;
+	unsigned int i, npins;
+	int ret;
+
+	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < npins; i++) {
+		ret = ingenic_pinconf_set(pctldev,
+				pins[i], configs, num_configs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static struct pinconf_ops ingenic_confops = {
+	.is_generic = true,
+	.pin_config_get = ingenic_pinconf_get,
+	.pin_config_set = ingenic_pinconf_set,
+	.pin_config_group_get = ingenic_pinconf_group_get,
+	.pin_config_group_set = ingenic_pinconf_group_set,
+};
+
+static int ingenic_pinctrl_parse_dt_func(struct ingenic_pinctrl *jzpc,
+		struct device_node *np)
+{
+	unsigned int num_groups;
+	struct device_node *group_node;
+	unsigned int i, j;
+	int err, npins, *pins, *confs;
+	const char **groups;
+
+	num_groups = of_get_child_count(np);
+	groups = devm_kzalloc(jzpc->dev,
+			sizeof(*groups) * num_groups, GFP_KERNEL);
+	if (!groups)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node(np, group_node) {
+		groups[i++] = group_node->name;
+
+		npins = of_property_count_elems_of_size(group_node,
+				"ingenic,pins", 8);
+		if (npins < 0)
+			return npins;
+
+		pins = devm_kzalloc(jzpc->dev,
+				sizeof(*pins) * npins, GFP_KERNEL);
+		confs = devm_kzalloc(jzpc->dev,
+				sizeof(*confs) * npins, GFP_KERNEL);
+		if (!pins || !confs)
+			return -ENOMEM;
+
+		for (j = 0; j < npins; j++) {
+			of_property_read_u32_index(group_node,
+					"ingenic,pins", j * 2, &pins[j]);
+
+			of_property_read_u32_index(group_node,
+					"ingenic,pins", j * 2 + 1, &confs[j]);
+		}
+
+		err = pinctrl_generic_add_group(jzpc->pctl, group_node->name,
+				pins, npins, confs);
+		if (err)
+			return err;
+	}
+
+	return pinmux_generic_add_function(jzpc->pctl, np->name,
+			groups, num_groups, NULL);
+}
+
+static const struct of_device_id ingenic_pinctrl_of_match[] = {
+	{ .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
+	{ .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
+	{},
+};
+
+int ingenic_pinctrl_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ingenic_pinctrl *jzpc;
+	struct pinctrl_desc *pctl_desc;
+	struct device_node *np, *functions_node;
+	const struct of_device_id *of_id = of_match_device(
+			ingenic_pinctrl_of_match, dev);
+	unsigned int i, num_chips;
+	int err;
+
+	jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL);
+	if (!jzpc)
+		return -ENOMEM;
+
+	jzpc->base = of_iomap(dev->of_node, 0);
+	if (!jzpc->base) {
+		dev_err(dev, "failed to map IO memory\n");
+		return -ENXIO;
+	}
+
+	jzpc->dev = dev;
+	dev_set_drvdata(dev, jzpc);
+
+	jzpc->version = (enum jz_version)of_id->data;
+
+	if (jzpc->version >= ID_JZ4780)
+		num_chips = 6;
+	else
+		num_chips = 4;
+
+	/*
+	 * Read the ingenic,pull-ups and ingenic,pull-downs arrays if present in
+	 * the devicetree. Otherwise set all bits to 0xff to consider that
+	 * pull-over resistors are available on all pins.
+	 */
+	err = of_property_read_u32_array(dev->of_node, "ingenic,pull-ups",
+			jzpc->pull_ups, num_chips);
+	if (err)
+		memset(jzpc->pull_ups, 0xff, sizeof(jzpc->pull_ups));
+
+	err = of_property_read_u32_array(dev->of_node, "ingenic,pull-downs",
+			jzpc->pull_downs, num_chips);
+	if (err)
+		memset(jzpc->pull_downs, 0xff, sizeof(jzpc->pull_downs));
+
+	functions_node = of_find_node_by_name(dev->of_node, "functions");
+	if (!functions_node) {
+		dev_err(dev, "Missing \"functions\" devicetree node\n");
+		return -EINVAL;
+	}
+
+	pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
+	if (!pctl_desc)
+		return -ENOMEM;
+
+	/* fill in pinctrl_desc structure */
+	pctl_desc->name = dev_name(dev);
+	pctl_desc->owner = THIS_MODULE;
+	pctl_desc->pctlops = &ingenic_pctlops;
+	pctl_desc->pmxops = &ingenic_pmxops;
+	pctl_desc->confops = &ingenic_confops;
+	pctl_desc->npins = num_chips * PINS_PER_GPIO_CHIP;
+	pctl_desc->pins = jzpc->pdesc = devm_kzalloc(&pdev->dev,
+			sizeof(*jzpc->pdesc) * pctl_desc->npins, GFP_KERNEL);
+	if (!jzpc->pdesc)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl_desc->npins; i++) {
+		jzpc->pdesc[i].number = i;
+		jzpc->pdesc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
+						'A' + (i / PINS_PER_GPIO_CHIP),
+						i % PINS_PER_GPIO_CHIP);
+	}
+
+	jzpc->pctl = devm_pinctrl_register(dev, pctl_desc, jzpc);
+	if (!jzpc->pctl) {
+		dev_err(dev, "Failed pinctrl registration\n");
+		return -EINVAL;
+	}
+
+	for_each_child_of_node(functions_node, np) {
+		err = ingenic_pinctrl_parse_dt_func(jzpc, np);
+		if (err) {
+			dev_err(dev, "failed to parse function %s\n",
+					np->full_name);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+static struct platform_driver ingenic_pinctrl_driver = {
+	.driver = {
+		.name = "pinctrl-ingenic",
+		.of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
+		.suppress_bind_attrs = true,
+	},
+	.probe = ingenic_pinctrl_probe,
+};
+
+static int __init ingenic_pinctrl_drv_register(void)
+{
+	return platform_driver_register(&ingenic_pinctrl_driver);
+}
+postcore_initcall(ingenic_pinctrl_drv_register);
-- 
2.11.0

WARNING: multiple messages have this Message-ID (diff)
From: Paul Cercueil <paul@crapouillou.net>
To: Linus Walleij
	<linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>,
	Ralf Baechle <ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>,
	Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Boris Brezillon
	<boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Thierry Reding
	<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Bartlomiej Zolnierkiewicz
	<b.zolnierkie-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	Maarten ter Huurne
	<maarten-Ph2Y2OKCxY1M656bX5wj8A@public.gmane.org>,
	Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>,
	Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org,
	Paul Cercueil <paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
Subject: [PATCH v2 03/14] pinctrl-ingenic: add a pinctrl driver for the Ingenic jz47xx SoCs
Date: Sun, 22 Jan 2017 14:49:36 +0000	[thread overview]
Message-ID: <20170122144947.16158-4-paul@crapouillou.net> (raw)
In-Reply-To: <20170122144947.16158-1-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>

This driver handles pin configuration and pin muxing for the
JZ4740 and JZ4780 SoCs from Ingenic.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/pinctrl/Kconfig           |   8 +
 drivers/pinctrl/Makefile          |   1 +
 drivers/pinctrl/pinctrl-ingenic.c | 488 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 497 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-ingenic.c

v2: Consider it's a new patch. Completely rewritten from v1.

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8f8c2af45781..2312e21ca48d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -285,6 +285,14 @@ config PINCTRL_ZYNQ
 	help
 	  This selects the pinctrl driver for Xilinx Zynq.
 
+config PINCTRL_INGENIC
+	bool "Pinctrl driver for the Ingenic JZ47xx SoCs"
+	default y
+	depends on MACH_INGENIC || COMPILE_TEST
+	select GENERIC_PINCONF
+	select GENERIC_PINCTRL_GROUPS
+	select GENERIC_PINMUX_FUNCTIONS
+
 source "drivers/pinctrl/aspeed/Kconfig"
 source "drivers/pinctrl/bcm/Kconfig"
 source "drivers/pinctrl/berlin/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a251f439626f..80f327239d4b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_LPC18XX)	+= pinctrl-lpc18xx.o
 obj-$(CONFIG_PINCTRL_TB10X)	+= pinctrl-tb10x.o
 obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
 obj-$(CONFIG_PINCTRL_ZYNQ)	+= pinctrl-zynq.o
+obj-$(CONFIG_PINCTRL_INGENIC)	+= pinctrl-ingenic.o
 
 obj-$(CONFIG_ARCH_ASPEED)	+= aspeed/
 obj-y				+= bcm/
diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
new file mode 100644
index 000000000000..ce36cf509eb1
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ingenic.c
@@ -0,0 +1,488 @@
+/*
+ * Ingenic SoCs pinctrl driver
+ *
+ * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/compiler.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "core.h"
+#include "pinconf.h"
+#include "pinmux.h"
+
+#define JZ4740_GPIO_DATA	0x10
+#define JZ4740_GPIO_PULL_DIS	0x30
+#define JZ4740_GPIO_FUNC	0x40
+#define JZ4740_GPIO_SELECT	0x50
+#define JZ4740_GPIO_DIR		0x60
+#define JZ4740_GPIO_TRIG	0x70
+#define JZ4740_GPIO_FLAG	0x80
+
+#define JZ4780_GPIO_INT		0x10
+#define JZ4780_GPIO_MSK		0x20
+#define JZ4780_GPIO_PAT1	0x30
+#define JZ4780_GPIO_PAT0	0x40
+#define JZ4780_GPIO_FLAG	0x50
+#define JZ4780_GPIO_PEN		0x70
+
+#define REG_SET(x) ((x) + 0x4)
+#define REG_CLEAR(x) ((x) + 0x8)
+
+#define PINS_PER_GPIO_CHIP 32
+#define NUM_MAX_GPIO_CHIPS 6
+
+enum jz_version {
+	ID_JZ4740,
+	ID_JZ4780,
+};
+
+struct ingenic_pinctrl {
+	struct device *dev;
+	void __iomem *base;
+	struct pinctrl_dev *pctl;
+	struct pinctrl_pin_desc *pdesc;
+	enum jz_version version;
+
+	u32 pull_ups[NUM_MAX_GPIO_CHIPS];
+	u32 pull_downs[NUM_MAX_GPIO_CHIPS];
+};
+
+static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
+		unsigned int pin, u8 reg, bool set)
+{
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	writel(BIT(idx), jzpc->base + offt * 0x100 +
+			(set ? REG_SET(reg) : REG_CLEAR(reg)));
+}
+
+static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
+		unsigned int pin, u8 reg)
+{
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	return readl(jzpc->base + offt * 0x100 + reg) & BIT(idx);
+}
+
+static struct pinctrl_ops ingenic_pctlops = {
+	.get_groups_count = pinctrl_generic_get_group_count,
+	.get_group_name = pinctrl_generic_get_group_name,
+	.get_group_pins = pinctrl_generic_get_group_pins,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+	.dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
+		int pin, int func)
+{
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	dev_dbg(jzpc->dev, "set pin P%c%u to function %u\n",
+			'A' + offt, idx, func);
+
+	if (jzpc->version >= ID_JZ4780) {
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_INT, false);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_MSK, false);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PAT1, func & 0x2);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PAT0, func & 0x1);
+	} else {
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
+	}
+
+	return 0;
+}
+
+static int ingenic_pinmux_set_mux(struct pinctrl_dev *pctldev,
+		unsigned int selector, unsigned int group)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	struct function_desc *func;
+	struct group_desc *grp;
+	unsigned int i;
+
+	func = pinmux_generic_get_function(pctldev, selector);
+	if (!func)
+		return -EINVAL;
+
+	grp = pinctrl_generic_get_group(pctldev, group);
+	if (!grp)
+		return -EINVAL;
+
+	dev_dbg(pctldev->dev, "enable function %s group %s\n",
+		func->name, grp->name);
+
+	for (i = 0; i < grp->num_pins; i++) {
+		int *pin_modes = grp->data;
+
+		ingenic_pinmux_set_pin_fn(jzpc, grp->pins[i], pin_modes[i]);
+	}
+
+	return 0;
+}
+
+static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
+		struct pinctrl_gpio_range *range,
+		unsigned int pin, bool input)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+	dev_dbg(pctldev->dev, "set pin P%c%u to %sput\n",
+			'A' + offt, idx, input ? "in" : "out");
+
+	if (jzpc->version >= ID_JZ4780) {
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_INT, false);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_MSK, true);
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PAT1, input);
+	} else {
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, input);
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false);
+	}
+
+	return 0;
+}
+
+static struct pinmux_ops ingenic_pmxops = {
+	.get_functions_count = pinmux_generic_get_function_count,
+	.get_function_name = pinmux_generic_get_function_name,
+	.get_function_groups = pinmux_generic_get_function_groups,
+	.set_mux = ingenic_pinmux_set_mux,
+	.gpio_set_direction = ingenic_pinmux_gpio_set_direction,
+};
+
+static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
+		unsigned int pin, unsigned long *config)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+	bool pull;
+
+	if (jzpc->version >= ID_JZ4780)
+		pull = !ingenic_get_pin_config(jzpc, pin, JZ4780_GPIO_PEN);
+	else
+		pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pull)
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (!pull || !(jzpc->pull_ups[offt] & BIT(idx)))
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (!pull || !(jzpc->pull_downs[offt] & BIT(idx)))
+			return -EINVAL;
+		break;
+
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, 1);
+	return 0;
+}
+
+static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
+		unsigned int pin, bool enabled)
+{
+	if (jzpc->version >= ID_JZ4780)
+		ingenic_config_pin(jzpc, pin, JZ4780_GPIO_PEN, !enabled);
+	else
+		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled);
+}
+
+static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+		unsigned long *configs, unsigned int num_configs)
+{
+	struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+	unsigned int cfg;
+
+	for (cfg = 0; cfg < num_configs; cfg++) {
+		switch (pinconf_to_config_param(configs[cfg])) {
+		case PIN_CONFIG_BIAS_DISABLE:
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			continue;
+		default:
+			return -ENOTSUPP;
+		}
+	}
+
+	for (cfg = 0; cfg < num_configs; cfg++) {
+		switch (pinconf_to_config_param(configs[cfg])) {
+		case PIN_CONFIG_BIAS_DISABLE:
+			dev_dbg(jzpc->dev, "disable pull-over for pin P%c%u\n",
+					'A' + offt, idx);
+			ingenic_set_bias(jzpc, pin, false);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_UP:
+			if (!(jzpc->pull_ups[offt] & BIT(idx)))
+				return -EINVAL;
+			dev_dbg(jzpc->dev, "set pull-up for pin P%c%u\n",
+					'A' + offt, idx);
+			ingenic_set_bias(jzpc, pin, true);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			if (!(jzpc->pull_downs[offt] & BIT(idx)))
+				return -EINVAL;
+			dev_dbg(jzpc->dev, "set pull-down for pin P%c%u\n",
+					'A' + offt, idx);
+			ingenic_set_bias(jzpc, pin, true);
+			break;
+
+		default:
+			unreachable();
+		}
+	}
+
+	return 0;
+}
+
+static int ingenic_pinconf_group_get(struct pinctrl_dev *pctldev,
+		unsigned int group, unsigned long *config)
+{
+	const unsigned *pins;
+	unsigned int i, npins, old = 0;
+	int ret;
+
+	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < npins; i++) {
+		if (ingenic_pinconf_get(pctldev, pins[i], config))
+			return -ENOTSUPP;
+
+		/* configs do not match between two pins */
+		if (i && (old != *config))
+			return -ENOTSUPP;
+
+		old = *config;
+	}
+
+	return 0;
+}
+
+static int ingenic_pinconf_group_set(struct pinctrl_dev *pctldev,
+		unsigned int group, unsigned long *configs,
+		unsigned int num_configs)
+{
+	const unsigned *pins;
+	unsigned int i, npins;
+	int ret;
+
+	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < npins; i++) {
+		ret = ingenic_pinconf_set(pctldev,
+				pins[i], configs, num_configs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static struct pinconf_ops ingenic_confops = {
+	.is_generic = true,
+	.pin_config_get = ingenic_pinconf_get,
+	.pin_config_set = ingenic_pinconf_set,
+	.pin_config_group_get = ingenic_pinconf_group_get,
+	.pin_config_group_set = ingenic_pinconf_group_set,
+};
+
+static int ingenic_pinctrl_parse_dt_func(struct ingenic_pinctrl *jzpc,
+		struct device_node *np)
+{
+	unsigned int num_groups;
+	struct device_node *group_node;
+	unsigned int i, j;
+	int err, npins, *pins, *confs;
+	const char **groups;
+
+	num_groups = of_get_child_count(np);
+	groups = devm_kzalloc(jzpc->dev,
+			sizeof(*groups) * num_groups, GFP_KERNEL);
+	if (!groups)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node(np, group_node) {
+		groups[i++] = group_node->name;
+
+		npins = of_property_count_elems_of_size(group_node,
+				"ingenic,pins", 8);
+		if (npins < 0)
+			return npins;
+
+		pins = devm_kzalloc(jzpc->dev,
+				sizeof(*pins) * npins, GFP_KERNEL);
+		confs = devm_kzalloc(jzpc->dev,
+				sizeof(*confs) * npins, GFP_KERNEL);
+		if (!pins || !confs)
+			return -ENOMEM;
+
+		for (j = 0; j < npins; j++) {
+			of_property_read_u32_index(group_node,
+					"ingenic,pins", j * 2, &pins[j]);
+
+			of_property_read_u32_index(group_node,
+					"ingenic,pins", j * 2 + 1, &confs[j]);
+		}
+
+		err = pinctrl_generic_add_group(jzpc->pctl, group_node->name,
+				pins, npins, confs);
+		if (err)
+			return err;
+	}
+
+	return pinmux_generic_add_function(jzpc->pctl, np->name,
+			groups, num_groups, NULL);
+}
+
+static const struct of_device_id ingenic_pinctrl_of_match[] = {
+	{ .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
+	{ .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
+	{},
+};
+
+int ingenic_pinctrl_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ingenic_pinctrl *jzpc;
+	struct pinctrl_desc *pctl_desc;
+	struct device_node *np, *functions_node;
+	const struct of_device_id *of_id = of_match_device(
+			ingenic_pinctrl_of_match, dev);
+	unsigned int i, num_chips;
+	int err;
+
+	jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL);
+	if (!jzpc)
+		return -ENOMEM;
+
+	jzpc->base = of_iomap(dev->of_node, 0);
+	if (!jzpc->base) {
+		dev_err(dev, "failed to map IO memory\n");
+		return -ENXIO;
+	}
+
+	jzpc->dev = dev;
+	dev_set_drvdata(dev, jzpc);
+
+	jzpc->version = (enum jz_version)of_id->data;
+
+	if (jzpc->version >= ID_JZ4780)
+		num_chips = 6;
+	else
+		num_chips = 4;
+
+	/*
+	 * Read the ingenic,pull-ups and ingenic,pull-downs arrays if present in
+	 * the devicetree. Otherwise set all bits to 0xff to consider that
+	 * pull-over resistors are available on all pins.
+	 */
+	err = of_property_read_u32_array(dev->of_node, "ingenic,pull-ups",
+			jzpc->pull_ups, num_chips);
+	if (err)
+		memset(jzpc->pull_ups, 0xff, sizeof(jzpc->pull_ups));
+
+	err = of_property_read_u32_array(dev->of_node, "ingenic,pull-downs",
+			jzpc->pull_downs, num_chips);
+	if (err)
+		memset(jzpc->pull_downs, 0xff, sizeof(jzpc->pull_downs));
+
+	functions_node = of_find_node_by_name(dev->of_node, "functions");
+	if (!functions_node) {
+		dev_err(dev, "Missing \"functions\" devicetree node\n");
+		return -EINVAL;
+	}
+
+	pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
+	if (!pctl_desc)
+		return -ENOMEM;
+
+	/* fill in pinctrl_desc structure */
+	pctl_desc->name = dev_name(dev);
+	pctl_desc->owner = THIS_MODULE;
+	pctl_desc->pctlops = &ingenic_pctlops;
+	pctl_desc->pmxops = &ingenic_pmxops;
+	pctl_desc->confops = &ingenic_confops;
+	pctl_desc->npins = num_chips * PINS_PER_GPIO_CHIP;
+	pctl_desc->pins = jzpc->pdesc = devm_kzalloc(&pdev->dev,
+			sizeof(*jzpc->pdesc) * pctl_desc->npins, GFP_KERNEL);
+	if (!jzpc->pdesc)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl_desc->npins; i++) {
+		jzpc->pdesc[i].number = i;
+		jzpc->pdesc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
+						'A' + (i / PINS_PER_GPIO_CHIP),
+						i % PINS_PER_GPIO_CHIP);
+	}
+
+	jzpc->pctl = devm_pinctrl_register(dev, pctl_desc, jzpc);
+	if (!jzpc->pctl) {
+		dev_err(dev, "Failed pinctrl registration\n");
+		return -EINVAL;
+	}
+
+	for_each_child_of_node(functions_node, np) {
+		err = ingenic_pinctrl_parse_dt_func(jzpc, np);
+		if (err) {
+			dev_err(dev, "failed to parse function %s\n",
+					np->full_name);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+static struct platform_driver ingenic_pinctrl_driver = {
+	.driver = {
+		.name = "pinctrl-ingenic",
+		.of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
+		.suppress_bind_attrs = true,
+	},
+	.probe = ingenic_pinctrl_probe,
+};
+
+static int __init ingenic_pinctrl_drv_register(void)
+{
+	return platform_driver_register(&ingenic_pinctrl_driver);
+}
+postcore_initcall(ingenic_pinctrl_drv_register);
-- 
2.11.0


  parent reply	other threads:[~2017-01-22 14:49 UTC|newest]

Thread overview: 359+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-17 23:14 [PATCH 00/13] Ingenic JZ4740 / JZ4780 pinctrl driver Paul Cercueil
2017-01-17 23:14 ` Paul Cercueil
2017-01-17 23:14 ` [PATCH 01/13] Documentation: dt/bindings: Document pinctrl-ingenic Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-18 23:45   ` Linus Walleij
2017-01-18 23:45     ` Linus Walleij
2017-01-18 23:45     ` Linus Walleij
2017-01-17 23:14 ` [PATCH 02/13] pinctrl-jz4740: add a pinctrl driver for the Ingenic jz4740 SoC Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-18 10:16   ` Linus Walleij
2017-01-18 10:16     ` Linus Walleij
2017-01-18 10:16     ` Linus Walleij
2017-01-17 23:14 ` [PATCH 03/13] pinctrl-jz4780: add a pinctrl driver for the Ingenic jz4780 SoC Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-17 23:14 ` [PATCH 04/13] MIPS: ingenic: Enable pinctrl for all ingenic SoCs Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-17 23:14 ` [PATCH 05/13] MIPS: jz4740: DTS: Add node for the jz4740-pinctrl driver Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-18 23:50   ` Linus Walleij
2017-01-18 23:50     ` Linus Walleij
2017-01-18 23:50     ` Linus Walleij
2017-01-17 23:14 ` [PATCH 06/13] MIPS: jz4780: DTS: Add node for the jz4780-pinctrl driver Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-17 23:14 ` [PATCH 07/13] MIPS: JZ4740: Qi LB60: Add pinctrl configuration for several drivers Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-17 23:14 ` [PATCH 08/13] MIPS: JZ4780: CI20: " Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-17 23:14 ` [PATCH 09/13] mmc: jz4740: Let the pinctrl driver configure the pins Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-19 10:55   ` Ulf Hansson
2017-01-19 10:55     ` Ulf Hansson
2017-01-19 10:55     ` Ulf Hansson
     [not found]     ` <CAPDyKFp4idZx+ynQByz22zwsiK+reBcvt3OdHm1kR2QUy+sUhw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-01-20 11:59       ` Paul Cercueil
2017-01-20 11:59         ` Paul Cercueil
2017-01-20 11:59         ` Paul Cercueil
2017-01-17 23:14 ` [PATCH 10/13] mtd: nand: " Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-27 17:33   ` Boris Brezillon
2017-01-27 17:33     ` Boris Brezillon
2017-01-17 23:14 ` [PATCH 11/13] fbdev: jz4740-fb: " Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-17 23:14 ` [PATCH 12/13] pwm: jz4740: " Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-18  7:20   ` Thierry Reding
2017-01-18  7:20     ` Thierry Reding
2017-01-17 23:14 ` [PATCH 13/13] MIPS: jz4740: Remove custom GPIO code Paul Cercueil
2017-01-17 23:14   ` Paul Cercueil
2017-01-18  7:27   ` Thierry Reding
2017-01-18  7:27     ` Thierry Reding
2017-01-18  7:27     ` Thierry Reding
2017-01-19 11:24     ` Paul Cercueil
2017-01-19 11:24       ` Paul Cercueil
2017-01-19  9:07   ` Linus Walleij
2017-01-19  9:07     ` Linus Walleij
2017-01-19  9:07     ` Linus Walleij
2017-01-20 10:01     ` Paul Cercueil
2017-01-20 10:01       ` Paul Cercueil
2017-01-18  7:15 ` [PATCH 00/13] Ingenic JZ4740 / JZ4780 pinctrl driver Thierry Reding
2017-01-18  7:15   ` Thierry Reding
2017-01-19 11:19   ` Paul Cercueil
2017-01-19 11:19     ` Paul Cercueil
2017-01-20  8:40     ` Linus Walleij
2017-01-20  8:40       ` Linus Walleij
2017-01-20  8:40       ` Linus Walleij
2017-01-20 10:17       ` Paul Cercueil
2017-01-20 10:17         ` Paul Cercueil
2017-01-22 14:49     ` [PATCH v2 00/14] " Paul Cercueil
2017-01-22 14:49       ` Paul Cercueil
2017-01-22 14:49       ` [PATCH v2 01/14] Documentation: dt/bindings: Document pinctrl-ingenic Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
2017-01-27 11:18         ` Linus Walleij
2017-01-27 11:18           ` Linus Walleij
2017-01-27 11:18           ` Linus Walleij
2017-01-27 15:27           ` Paul Cercueil
2017-01-27 15:27             ` Paul Cercueil
     [not found]             ` <08e9505d2d366557950f8e6a4e81f57a-p8hskv8pF7lEPksTRSfcJOTW4wlIGRCZ@public.gmane.org>
2017-01-31 12:59               ` Linus Walleij
2017-01-31 12:59                 ` Linus Walleij
2017-01-31 12:59                 ` Linus Walleij
2017-01-22 14:49       ` [PATCH v2 02/14] Documentation: dt/bindings: Document pinctrl-gpio Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
     [not found]       ` <20170122144947.16158-1-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
2017-01-22 14:49         ` Paul Cercueil [this message]
2017-01-22 14:49           ` [PATCH v2 03/14] pinctrl-ingenic: add a pinctrl driver for the Ingenic jz47xx SoCs Paul Cercueil
2017-01-22 14:49           ` Paul Cercueil
2017-01-22 14:49         ` [PATCH v2 08/14] MIPS: JZ4740: Qi LB60: Add pinctrl configuration for several drivers Paul Cercueil
2017-01-22 14:49           ` Paul Cercueil
2017-01-22 14:49           ` Paul Cercueil
2017-01-22 14:49         ` [PATCH v2 11/14] mtd: nand: jz4740: Let the pinctrl driver configure the pins Paul Cercueil
2017-01-22 14:49           ` Paul Cercueil
2017-01-22 14:49           ` Paul Cercueil
2017-01-22 14:49       ` [PATCH v2 04/14] GPIO: Add gpio-ingenic driver Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
     [not found]         ` <20170122144947.16158-5-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
2017-01-22 16:21           ` kbuild test robot
2017-01-22 16:21             ` kbuild test robot
2017-01-22 16:21             ` kbuild test robot
2017-01-22 16:21             ` kbuild test robot
2017-01-22 17:49         ` kbuild test robot
2017-01-22 17:49           ` kbuild test robot
2017-01-22 17:49           ` kbuild test robot
2017-01-22 17:49           ` kbuild test robot
2017-01-22 17:49         ` [PATCH] GPIO: fix semicolon.cocci warnings kbuild test robot
2017-01-22 17:49           ` kbuild test robot
2017-01-22 17:49           ` kbuild test robot
2017-01-22 17:49           ` kbuild test robot
2017-01-22 14:49       ` [PATCH v2 05/14] MIPS: ingenic: Enable pinctrl for all ingenic SoCs Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
2017-01-22 14:49       ` [PATCH v2 06/14] MIPS: jz4740: DTS: Add nodes for ingenic pinctrl and gpio drivers Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
2017-01-22 14:49       ` [PATCH v2 07/14] MIPS: jz4780: " Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
2017-01-22 14:49       ` [PATCH v2 09/14] MIPS: JZ4780: CI20: Add pinctrl configuration for several drivers Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
2017-01-22 14:49       ` [PATCH v2 10/14] mmc: jz4740: Let the pinctrl driver configure the pins Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
2017-01-23 10:40         ` Ulf Hansson
2017-01-23 10:40           ` Ulf Hansson
2017-01-23 10:40           ` Ulf Hansson
2017-01-22 14:49       ` [PATCH v2 12/14] fbdev: jz4740-fb: " Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
2017-01-22 14:49       ` [PATCH v2 13/14] pwm: jz4740: " Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
2017-01-22 14:49       ` [PATCH v2 14/14] MIPS: jz4740: Remove custom GPIO code Paul Cercueil
2017-01-22 14:49         ` Paul Cercueil
2017-01-25 18:51     ` [PATCH v3 00/14] Ingenic JZ4740 / JZ4780 pinctrl driver Paul Cercueil
2017-01-25 18:51       ` Paul Cercueil
2017-01-25 18:51       ` [PATCH v3 01/14] Documentation: dt/bindings: Document pinctrl-ingenic Paul Cercueil
2017-01-25 18:51         ` Paul Cercueil
2017-01-30 20:36         ` Rob Herring
2017-01-30 20:36           ` Rob Herring
2017-01-30 20:36           ` Rob Herring
2017-01-30 20:36           ` Rob Herring
2017-01-31 10:31           ` Paul Cercueil
2017-01-31 10:31             ` Paul Cercueil
     [not found]             ` <12dc62a7255bd453ff4e5e89f93ebc58-p8hskv8pF7lEPksTRSfcJOTW4wlIGRCZ@public.gmane.org>
2017-01-31 13:09               ` Linus Walleij
2017-01-31 13:09                 ` Linus Walleij
2017-01-31 13:09                 ` Linus Walleij
2017-02-09 17:28                 ` Paul Cercueil
2017-02-09 17:28                   ` Paul Cercueil
     [not found]                   ` <fd3c507484a9ee34a08c9f92e60624db-p8hskv8pF7lEPksTRSfcJOTW4wlIGRCZ@public.gmane.org>
2017-02-20 13:56                     ` Linus Walleij
2017-02-20 13:56                       ` Linus Walleij
2017-02-20 13:56                       ` Linus Walleij
2017-02-21 11:20                       ` Paul Cercueil
2017-02-21 11:20                         ` Paul Cercueil
2017-02-23  9:59                         ` Linus Walleij
2017-02-23  9:59                           ` Linus Walleij
2017-02-23  9:59                           ` Linus Walleij
2017-04-02 20:42         ` [PATCH v4 00/14] Ingenic JZ4740 / JZ4780 pinctrl driver Paul Cercueil
2017-04-02 20:42           ` Paul Cercueil
2017-04-02 20:42           ` [PATCH v4 01/14] dt/bindings: Document pinctrl-ingenic Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-04 14:48             ` Rob Herring
2017-04-04 14:48               ` Rob Herring
2017-04-28 20:08             ` [PATCH v4 00/14] Ingenic JZ4740 / JZ4780 pinctrl driver Paul Cercueil
2017-04-28 20:08               ` Paul Cercueil
2017-04-28 20:08               ` [PATCH v5 02/14] dt/bindings: Document gpio-ingenic Paul Cercueil
2017-04-28 20:08                 ` Paul Cercueil
2017-05-05 19:57                 ` Rob Herring
2017-05-05 19:57                   ` Rob Herring
2017-04-28 20:08               ` [PATCH v5 07/14] MIPS: jz4780: DTS: Add nodes for ingenic pinctrl and gpio drivers Paul Cercueil
2017-04-28 20:08                 ` Paul Cercueil
2017-04-28 20:08               ` [PATCH v5 08/14] MIPS: JZ4740: Qi LB60: Add pinctrl configuration for several drivers Paul Cercueil
2017-04-28 20:08                 ` Paul Cercueil
     [not found]               ` <20170428200824.10906-1-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
2017-04-28 20:08                 ` [PATCH v5 01/14] dt/bindings: Document pinctrl-ingenic Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
     [not found]                   ` <20170428200824.10906-2-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
2017-05-12 16:52                     ` [PATCH v6 " Paul Cercueil
2017-05-12 16:52                       ` Paul Cercueil
2017-05-12 16:52                       ` [PATCH v6 02/14] dt/bindings: Document gpio-ingenic Paul Cercueil
2017-05-12 16:52                       ` [PATCH v6 03/14] pinctrl: add a pinctrl driver for the Ingenic jz47xx SoCs Paul Cercueil
     [not found]                       ` <20170512165307.31369-1-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
2017-05-12 16:52                         ` [PATCH v6 04/14] GPIO: Add gpio-ingenic driver Paul Cercueil
2017-05-12 16:52                           ` Paul Cercueil
2017-05-12 16:52                       ` [PATCH v6 05/14] MIPS: ingenic: Enable pinctrl for all ingenic SoCs Paul Cercueil
2017-05-12 16:52                       ` [PATCH v6 06/14] MIPS: jz4740: DTS: Add nodes for ingenic pinctrl and gpio drivers Paul Cercueil
2017-05-12 16:53                       ` [PATCH v6 07/14] MIPS: jz4780: " Paul Cercueil
2017-05-12 16:53                       ` [PATCH v6 08/14] MIPS: JZ4740: Qi LB60: Add pinctrl configuration for several drivers Paul Cercueil
2017-05-12 16:53                       ` [PATCH v6 09/14] MIPS: JZ4780: CI20: " Paul Cercueil
2017-05-12 16:53                       ` [PATCH v6 10/14] mmc: jz4740: Let the pinctrl driver configure the pins Paul Cercueil
2017-05-12 16:53                       ` [PATCH v6 11/14] mtd: nand: " Paul Cercueil
2017-05-12 16:53                       ` [PATCH v6 12/14] fbdev: jz4740-fb: " Paul Cercueil
2017-05-12 16:53                       ` [PATCH v6 13/14] pwm: jz4740: " Paul Cercueil
2017-05-12 16:53                       ` [PATCH v6 14/14] MIPS: jz4740: Remove custom GPIO code Paul Cercueil
2017-04-28 20:08                 ` [PATCH v5 03/14] pinctrl: add a pinctrl driver for the Ingenic jz47xx SoCs Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-05-03  9:12                   ` Paul Cercueil
2017-05-03  9:12                     ` Paul Cercueil
2017-05-11 11:01                     ` Linus Walleij
2017-05-11 11:01                       ` Linus Walleij
2017-05-11 11:01                       ` Linus Walleij
2017-04-28 20:08                 ` [PATCH v5 04/14] GPIO: Add gpio-ingenic driver Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-05-07 22:05                   ` Paul Cercueil
2017-05-07 22:05                     ` Paul Cercueil
2017-05-11 11:06                     ` Linus Walleij
2017-05-11 11:06                       ` Linus Walleij
2017-05-11 11:06                       ` Linus Walleij
2017-04-28 20:08                 ` [PATCH v5 05/14] MIPS: ingenic: Enable pinctrl for all ingenic SoCs Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-05-11 11:08                   ` Linus Walleij
2017-05-11 11:08                     ` Linus Walleij
2017-05-11 11:08                     ` Linus Walleij
2017-05-12 17:00                     ` Paul Cercueil
2017-05-12 17:00                       ` Paul Cercueil
2017-05-12 17:00                       ` Paul Cercueil
2017-05-22 15:31                   ` Linus Walleij
2017-05-22 15:31                     ` Linus Walleij
2017-05-22 15:31                     ` Linus Walleij
     [not found]                     ` <CACRpkdauf5c2i4o5i8QY8YHPNjizkvTu6kAbnquWiP_=v2=KdQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-07-02 16:35                       ` Paul Cercueil
2017-07-02 16:35                         ` Paul Cercueil
2017-07-02 16:35                         ` Paul Cercueil
2017-07-03  9:07                         ` Linus Walleij
2017-07-03  9:07                           ` Linus Walleij
2017-07-03  9:07                           ` Linus Walleij
2017-07-03 13:55                           ` Ralf Baechle
2017-07-03 13:55                             ` Ralf Baechle
2017-07-03 13:55                             ` Ralf Baechle
2017-07-31 13:29                             ` Linus Walleij
2017-07-31 13:29                               ` Linus Walleij
2017-07-31 13:29                               ` Linus Walleij
2017-04-28 20:08                 ` [PATCH v5 06/14] MIPS: jz4740: DTS: Add nodes for ingenic pinctrl and gpio drivers Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08                 ` [PATCH v5 09/14] MIPS: JZ4780: CI20: Add pinctrl configuration for several drivers Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08                 ` [PATCH v5 11/14] mtd: nand: jz4740: Let the pinctrl driver configure the pins Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08                   ` Paul Cercueil
2017-04-28 20:08               ` [PATCH v5 10/14] mmc: " Paul Cercueil
2017-04-28 20:08                 ` Paul Cercueil
2017-04-28 20:08               ` [PATCH v5 12/14] fbdev: jz4740-fb: " Paul Cercueil
2017-04-28 20:08                 ` Paul Cercueil
2017-04-28 20:08               ` [PATCH v5 13/14] pwm: jz4740: " Paul Cercueil
2017-04-28 20:08                 ` Paul Cercueil
2017-04-28 20:08               ` [PATCH v5 14/14] MIPS: jz4740: Remove custom GPIO code Paul Cercueil
2017-04-28 20:08                 ` Paul Cercueil
2017-04-02 20:42           ` [PATCH v4 02/14] dt/bindings: Document gpio-ingenic Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-04 14:52             ` Rob Herring
2017-04-04 14:52               ` Rob Herring
2017-04-02 20:42           ` [PATCH v4 03/14] pinctrl-ingenic: add a pinctrl driver for the Ingenic jz47xx SoCs Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-07  9:41             ` Linus Walleij
2017-04-07  9:41               ` Linus Walleij
2017-04-07  9:41               ` Linus Walleij
2017-04-07 10:56               ` Lee Jones
2017-04-07 10:56                 ` Lee Jones
2017-04-07 10:56                 ` Lee Jones
2017-04-02 20:42           ` [PATCH v4 04/14] GPIO: Add gpio-ingenic driver Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-03 14:15             ` kbuild test robot
2017-04-03 14:15               ` kbuild test robot
2017-04-03 14:15               ` kbuild test robot
2017-04-03 14:15               ` kbuild test robot
     [not found]             ` <20170402204244.14216-5-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
2017-04-07  9:34               ` Linus Walleij
2017-04-07  9:34                 ` Linus Walleij
2017-04-07  9:34                 ` Linus Walleij
2017-04-02 20:42           ` [PATCH v4 05/14] MIPS: ingenic: Enable pinctrl for all ingenic SoCs Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-02 20:42           ` [PATCH v4 06/14] MIPS: jz4740: DTS: Add nodes for ingenic pinctrl and gpio drivers Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-03  9:57             ` Sergei Shtylyov
2017-04-03  9:57               ` Sergei Shtylyov
     [not found]               ` <48f7f4ee-b8e3-0096-ddea-2fbe0b399b40-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
2017-04-03 10:20                 ` Paul Cercueil
2017-04-03 10:20                   ` Paul Cercueil
2017-04-03 10:20                   ` Paul Cercueil
2017-04-03 10:32                   ` Sergei Shtylyov
2017-04-03 10:32                     ` Sergei Shtylyov
     [not found]             ` <20170402204244.14216-7-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
2017-04-07  9:44               ` Linus Walleij
2017-04-07  9:44                 ` Linus Walleij
2017-04-07  9:44                 ` Linus Walleij
2017-04-07 13:57                 ` Paul Cercueil
2017-04-07 13:57                   ` Paul Cercueil
2017-04-24 12:58                   ` Linus Walleij
2017-04-24 12:58                     ` Linus Walleij
2017-04-24 12:58                     ` Linus Walleij
2017-04-02 20:42           ` [PATCH v4 07/14] MIPS: jz4780: " Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-02 20:42           ` [PATCH v4 08/14] MIPS: JZ4740: Qi LB60: Add pinctrl configuration for several drivers Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-02 20:42           ` [PATCH v4 09/14] MIPS: JZ4780: CI20: " Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-02 20:42           ` [PATCH v4 10/14] mmc: jz4740: Let the pinctrl driver configure the pins Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-02 20:42           ` [PATCH v4 11/14] mtd: nand: " Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-02 20:42           ` [PATCH v4 12/14] fbdev: jz4740-fb: " Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-04-02 20:42           ` [PATCH v4 13/14] pwm: jz4740: " Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
     [not found]             ` <20170402204244.14216-14-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
2017-04-06 14:40               ` Thierry Reding
2017-04-06 14:40                 ` Thierry Reding
2017-04-06 14:40                 ` Thierry Reding
2017-04-02 20:42           ` [PATCH v4 14/14] MIPS: jz4740: Remove custom GPIO code Paul Cercueil
2017-04-02 20:42             ` Paul Cercueil
2017-01-25 18:51       ` [PATCH v3 02/14] Documentation: dt/bindings: Document pinctrl-gpio Paul Cercueil
2017-01-25 18:51         ` Paul Cercueil
2017-01-30 20:33         ` Rob Herring
2017-01-30 20:33           ` Rob Herring
2017-01-25 18:51       ` [PATCH v3 03/14] pinctrl-ingenic: add a pinctrl driver for the Ingenic jz47xx SoCs Paul Cercueil
2017-01-25 18:51         ` Paul Cercueil
2017-01-31 14:05         ` Linus Walleij
2017-01-31 14:05           ` Linus Walleij
2017-01-31 14:05           ` Linus Walleij
2017-01-31 14:12           ` Paul Cercueil
2017-01-31 14:12             ` Paul Cercueil
2017-01-25 18:51       ` [PATCH v3 04/14] GPIO: Add gpio-ingenic driver Paul Cercueil
2017-01-25 18:51         ` Paul Cercueil
2017-01-31 14:13         ` Linus Walleij
2017-01-31 14:13           ` Linus Walleij
2017-01-31 14:13           ` Linus Walleij
2017-02-09 17:14           ` Paul Cercueil
2017-02-09 17:14             ` Paul Cercueil
2017-02-12 20:48             ` Linus Walleij
2017-02-12 20:48               ` Linus Walleij
2017-02-12 20:48               ` Linus Walleij
2017-01-31 14:20         ` Linus Walleij
2017-01-31 14:20           ` Linus Walleij
2017-01-31 14:20           ` Linus Walleij
2017-01-31 15:29           ` Paul Cercueil
2017-01-31 15:29             ` Paul Cercueil
     [not found]             ` <699f0c63e95ecdafe6946fdcdbb97a37-p8hskv8pF7lEPksTRSfcJOTW4wlIGRCZ@public.gmane.org>
2017-02-03 13:58               ` Linus Walleij
2017-02-03 13:58                 ` Linus Walleij
2017-02-03 13:58                 ` Linus Walleij
2017-01-25 18:51       ` [PATCH v3 05/14] MIPS: ingenic: Enable pinctrl for all ingenic SoCs Paul Cercueil
2017-01-25 18:51         ` Paul Cercueil
2017-01-25 18:51       ` [PATCH v3 06/14] MIPS: jz4740: DTS: Add nodes for ingenic pinctrl and gpio drivers Paul Cercueil
2017-01-25 18:51         ` Paul Cercueil
2017-01-31 14:16         ` Linus Walleij
2017-01-31 14:16           ` Linus Walleij
2017-01-31 14:16           ` Linus Walleij
2017-01-25 18:52       ` [PATCH v3 07/14] MIPS: jz4780: " Paul Cercueil
2017-01-25 18:52         ` Paul Cercueil
2017-01-25 18:52       ` [PATCH v3 08/14] MIPS: JZ4740: Qi LB60: Add pinctrl configuration for several drivers Paul Cercueil
2017-01-25 18:52         ` Paul Cercueil
2017-01-25 18:52       ` [PATCH v3 09/14] MIPS: JZ4780: CI20: " Paul Cercueil
2017-01-25 18:52         ` Paul Cercueil
2017-01-25 18:52       ` [PATCH v3 10/14] mmc: jz4740: Let the pinctrl driver configure the pins Paul Cercueil
2017-01-25 18:52         ` Paul Cercueil
2017-01-26  6:11         ` kbuild test robot
2017-01-26  6:11           ` kbuild test robot
2017-01-26  6:11           ` kbuild test robot
2017-01-26  6:11           ` kbuild test robot
2017-01-26 10:10           ` Paul Cercueil
2017-01-26 10:10             ` Paul Cercueil
2017-01-25 18:52       ` [PATCH v3 11/14] mtd: nand: " Paul Cercueil
2017-01-25 18:52         ` Paul Cercueil
2017-01-25 18:52       ` [PATCH v3 12/14] fbdev: jz4740-fb: " Paul Cercueil
2017-01-25 18:52         ` Paul Cercueil
2017-01-30 16:10         ` Bartlomiej Zolnierkiewicz
2017-01-30 16:10           ` Bartlomiej Zolnierkiewicz
2017-01-25 18:52       ` [PATCH v3 13/14] pwm: jz4740: " Paul Cercueil
2017-01-25 18:52         ` Paul Cercueil
2017-01-25 18:52       ` [PATCH v3 14/14] MIPS: jz4740: Remove custom GPIO code Paul Cercueil
2017-01-25 18:52         ` Paul Cercueil
2017-01-19  6:38 ` [PATCH 00/13] Ingenic JZ4740 / JZ4780 pinctrl driver Linus Walleij
2017-01-19  6:38   ` Linus Walleij
2017-01-19  6:38   ` Linus Walleij

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170122144947.16158-4-paul@crapouillou.net \
    --to=paul-ictto2rgo2otusrc4mpeew@public.gmane.org \
    --cc=b.zolnierkie-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org \
    --cc=boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org \
    --cc=lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org \
    --cc=linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org \
    --cc=linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-pwm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=maarten-Ph2Y2OKCxY1M656bX5wj8A@public.gmane.org \
    --cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
    --cc=paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org \
    --cc=ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org \
    --cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.