All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support
@ 2015-11-21 18:04 ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-gpio, linux-kernel, linux-arm-kernel

Hi Linus,

I've been working on this for some time now, it's time pxa archtecture gets a
proper pin control support.

This serie provides support for pxa27x architecture, and paves the way to pxa2xx
one. I've tested this on my pxa27x board, in both device-tree and non
device-tree builds.

It's time to have more eyes on this code, so let's begin the review.

Cheers.

Robert Jarzmik (6):
  MAINTAINERS: add to pxa files pinctrl
  pinctrl: pxa: pxa2xx: add pin control skeleton
  pinctrl: pxa: pxa2xx: add pin muxing
  pinctrl: pxa: pxa2xx: add pin configuration support
  pinctrl: pxa: add pxa27x architecture
  pinctrl: activate pxa architecture

 MAINTAINERS                          |   1 +
 drivers/pinctrl/Kconfig              |   1 +
 drivers/pinctrl/Makefile             |   1 +
 drivers/pinctrl/pxa/Kconfig          |  17 ++
 drivers/pinctrl/pxa/Makefile         |   2 +
 drivers/pinctrl/pxa/pinctrl-pxa27x.c | 566 +++++++++++++++++++++++++++++++++++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 436 +++++++++++++++++++++++++++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.h |  92 ++++++
 8 files changed, 1116 insertions(+)
 create mode 100644 drivers/pinctrl/pxa/Kconfig
 create mode 100644 drivers/pinctrl/pxa/Makefile
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa27x.c
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.c
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.h

-- 
2.1.4

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

* [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support
@ 2015-11-21 18:04 ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-kernel, linux-gpio, linux-arm-kernel

Hi Linus,

I've been working on this for some time now, it's time pxa archtecture gets a
proper pin control support.

This serie provides support for pxa27x architecture, and paves the way to pxa2xx
one. I've tested this on my pxa27x board, in both device-tree and non
device-tree builds.

It's time to have more eyes on this code, so let's begin the review.

Cheers.

Robert Jarzmik (6):
  MAINTAINERS: add to pxa files pinctrl
  pinctrl: pxa: pxa2xx: add pin control skeleton
  pinctrl: pxa: pxa2xx: add pin muxing
  pinctrl: pxa: pxa2xx: add pin configuration support
  pinctrl: pxa: add pxa27x architecture
  pinctrl: activate pxa architecture

 MAINTAINERS                          |   1 +
 drivers/pinctrl/Kconfig              |   1 +
 drivers/pinctrl/Makefile             |   1 +
 drivers/pinctrl/pxa/Kconfig          |  17 ++
 drivers/pinctrl/pxa/Makefile         |   2 +
 drivers/pinctrl/pxa/pinctrl-pxa27x.c | 566 +++++++++++++++++++++++++++++++++++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 436 +++++++++++++++++++++++++++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.h |  92 ++++++
 8 files changed, 1116 insertions(+)
 create mode 100644 drivers/pinctrl/pxa/Kconfig
 create mode 100644 drivers/pinctrl/pxa/Makefile
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa27x.c
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.c
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.h

-- 
2.1.4


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

* [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support
@ 2015-11-21 18:04 ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

I've been working on this for some time now, it's time pxa archtecture gets a
proper pin control support.

This serie provides support for pxa27x architecture, and paves the way to pxa2xx
one. I've tested this on my pxa27x board, in both device-tree and non
device-tree builds.

It's time to have more eyes on this code, so let's begin the review.

Cheers.

Robert Jarzmik (6):
  MAINTAINERS: add to pxa files pinctrl
  pinctrl: pxa: pxa2xx: add pin control skeleton
  pinctrl: pxa: pxa2xx: add pin muxing
  pinctrl: pxa: pxa2xx: add pin configuration support
  pinctrl: pxa: add pxa27x architecture
  pinctrl: activate pxa architecture

 MAINTAINERS                          |   1 +
 drivers/pinctrl/Kconfig              |   1 +
 drivers/pinctrl/Makefile             |   1 +
 drivers/pinctrl/pxa/Kconfig          |  17 ++
 drivers/pinctrl/pxa/Makefile         |   2 +
 drivers/pinctrl/pxa/pinctrl-pxa27x.c | 566 +++++++++++++++++++++++++++++++++++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 436 +++++++++++++++++++++++++++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.h |  92 ++++++
 8 files changed, 1116 insertions(+)
 create mode 100644 drivers/pinctrl/pxa/Kconfig
 create mode 100644 drivers/pinctrl/pxa/Makefile
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa27x.c
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.c
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.h

-- 
2.1.4

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

* [PATCH 1/6] MAINTAINERS: add to pxa files pinctrl
  2015-11-21 18:04 ` Robert Jarzmik
  (?)
@ 2015-11-21 18:04   ` Robert Jarzmik
  -1 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-gpio, linux-kernel, linux-arm-kernel

Add the pinctrl pxa drivers to the pxa maintained files.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e9caa4b28828..9bca217c655e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8613,6 +8613,7 @@ S:	Maintained
 F:	arch/arm/mach-pxa/
 F:	drivers/dma/pxa*
 F:	drivers/pcmcia/pxa2xx*
+F:	drivers/pinctrl/pxa/
 F:	drivers/spi/spi-pxa2xx*
 F:	drivers/usb/gadget/udc/pxa2*
 F:	include/sound/pxa2xx-lib.h
-- 
2.1.4

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

* [PATCH 1/6] MAINTAINERS: add to pxa files pinctrl
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-kernel, linux-gpio, linux-arm-kernel

Add the pinctrl pxa drivers to the pxa maintained files.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e9caa4b28828..9bca217c655e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8613,6 +8613,7 @@ S:	Maintained
 F:	arch/arm/mach-pxa/
 F:	drivers/dma/pxa*
 F:	drivers/pcmcia/pxa2xx*
+F:	drivers/pinctrl/pxa/
 F:	drivers/spi/spi-pxa2xx*
 F:	drivers/usb/gadget/udc/pxa2*
 F:	include/sound/pxa2xx-lib.h
-- 
2.1.4


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

* [PATCH 1/6] MAINTAINERS: add to pxa files pinctrl
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add the pinctrl pxa drivers to the pxa maintained files.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e9caa4b28828..9bca217c655e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8613,6 +8613,7 @@ S:	Maintained
 F:	arch/arm/mach-pxa/
 F:	drivers/dma/pxa*
 F:	drivers/pcmcia/pxa2xx*
+F:	drivers/pinctrl/pxa/
 F:	drivers/spi/spi-pxa2xx*
 F:	drivers/usb/gadget/udc/pxa2*
 F:	include/sound/pxa2xx-lib.h
-- 
2.1.4

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

* [PATCH 2/6] pinctrl: pxa: pxa2xx: add pin control skeleton
  2015-11-21 18:04 ` Robert Jarzmik
  (?)
@ 2015-11-21 18:04   ` Robert Jarzmik
  -1 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-gpio, linux-kernel, linux-arm-kernel

Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.

One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.

The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
 - a pin is obviously a pin
 - a group is also a pin, ie. group P101 is the pin 101
 - a mux function is an alternate function
   (ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)

The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/Kconfig          |   9 ++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 252 +++++++++++++++++++++++++++++++++++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.h |  92 +++++++++++++
 3 files changed, 353 insertions(+)
 create mode 100644 drivers/pinctrl/pxa/Kconfig
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.c
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.h

diff --git a/drivers/pinctrl/pxa/Kconfig b/drivers/pinctrl/pxa/Kconfig
new file mode 100644
index 000000000000..13e24d7c45c7
--- /dev/null
+++ b/drivers/pinctrl/pxa/Kconfig
@@ -0,0 +1,9 @@
+if (ARCH_PXA || COMPILE_TEST)
+
+config PINCTRL_PXA
+	bool
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+
+endif
diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
new file mode 100644
index 000000000000..baded1a8745b
--- /dev/null
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -0,0 +1,252 @@
+/*
+ * Marvell PXA2xx family pin control
+ *
+ * Copyright (C) 2015 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "../pinctrl-utils.h"
+#include "pinctrl-pxa2xx.h"
+
+static int pxa2xx_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->ngroups;
+}
+
+static const char *pxa2xx_pctrl_get_group_name(struct pinctrl_dev *pctldev,
+					       unsigned tgroup)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *group = pctl->groups + tgroup;
+
+	return group->name;
+}
+
+static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
+				       unsigned tgroup,
+				       const unsigned **pins,
+				       unsigned *num_pins)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *group = pctl->groups + tgroup;
+
+	*pins = (unsigned *)&group->pin;
+	*num_pins = 1;
+
+	return 0;
+}
+
+static const struct pinctrl_ops pxa2xx_pctl_ops = {
+#ifdef CONFIG_OF
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_all,
+	.dt_free_map		= pinctrl_utils_dt_free_map,
+#endif
+	.get_groups_count	= pxa2xx_pctrl_get_groups_count,
+	.get_group_name		= pxa2xx_pctrl_get_group_name,
+	.get_group_pins		= pxa2xx_pctrl_get_group_pins,
+};
+
+static struct pinctrl_desc pxa2xx_pinctrl_desc = {
+	.pctlops	= &pxa2xx_pctl_ops,
+};
+
+static const struct pxa_pinctrl_function *
+pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname,
+		     const struct pxa_pinctrl_function *functions)
+{
+	const struct pxa_pinctrl_function *func;
+
+	for (func = functions; func->name; func++)
+		if (!strcmp(fname, func->name))
+			return func;
+
+	return NULL;
+}
+
+static int pxa2xx_build_functions(struct pxa_pinctrl *pctl)
+{
+	int i;
+	struct pxa_pinctrl_function *functions;
+	struct pxa_desc_function *df;
+
+	/*
+	 * Each pin can have at most 6 alternate functions, and 2 gpio functions
+	 * which are common to each pin. As there are more than 2 pins without
+	 * alternate function, 6 * npins is an absolute high limit of the number
+	 * of functions.
+	 */
+	functions = devm_kcalloc(pctl->dev, pctl->npins * 6,
+				 sizeof(*functions), GFP_KERNEL);
+	if (!functions)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl->npins; i++)
+		for (df = pctl->ppins[i].functions; df->name; df++)
+			if (!pxa2xx_find_function(pctl, df->name, functions))
+				(functions + pctl->nfuncs++)->name = df->name;
+	pctl->functions = devm_kmemdup(pctl->dev, functions,
+				       pctl->nfuncs * sizeof(*functions),
+				       GFP_KERNEL);
+	if (!pctl->functions)
+		return -ENOMEM;
+
+	kfree(functions);
+	return 0;
+}
+
+static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
+{
+	int i, j, ngroups;
+	struct pxa_pinctrl_function *func;
+	struct pxa_desc_function *df;
+	char **gtmp;
+
+	gtmp = devm_kmalloc_array(pctl->dev, pctl->npins, sizeof(*gtmp),
+				  GFP_KERNEL);
+	if (!gtmp)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl->nfuncs; i++) {
+		ngroups = 0;
+		for (j = 0; j < pctl->npins; j++)
+			for (df = pctl->ppins[j].functions; df->name;
+			     df++)
+				if (!strcmp(pctl->functions[i].name,
+					    df->name))
+					gtmp[ngroups++] = (char *)
+						pctl->ppins[j].pin.name;
+		func = pctl->functions + i;
+		func->ngroups = ngroups;
+		func->groups =
+			devm_kmalloc_array(pctl->dev, ngroups,
+					   sizeof(char *), GFP_KERNEL);
+		if (!func->groups)
+			return -ENOMEM;
+
+		memcpy(func->groups, gtmp, ngroups * sizeof(*gtmp));
+	}
+
+	kfree(gtmp);
+	return 0;
+}
+
+static int pxa2xx_build_state(struct pxa_pinctrl *pctl,
+			      const struct pxa_desc_pin *ppins, int npins)
+{
+	struct pxa_pinctrl_group *group;
+	struct pinctrl_pin_desc *pins;
+	int ret, i;
+
+	pctl->npins = npins;
+	pctl->ppins = ppins;
+	pctl->ngroups = npins;
+
+	pctl->desc.npins = npins;
+	pins = devm_kcalloc(pctl->dev, npins, sizeof(*pins), GFP_KERNEL);
+	if (!pins)
+		return -ENOMEM;
+
+	pctl->desc.pins = pins;
+	for (i = 0; i < npins; i++)
+		pins[i] = ppins[i].pin;
+
+	pctl->groups = devm_kmalloc_array(pctl->dev, pctl->ngroups,
+					  sizeof(*pctl->groups), GFP_KERNEL);
+	if (!pctl->groups)
+		return -ENOMEM;
+
+	for (i = 0; i < npins; i++) {
+		group = pctl->groups + i;
+		group->name = ppins[i].pin.name;
+		group->pin = ppins[i].pin.number;
+	}
+
+	ret = pxa2xx_build_functions(pctl);
+	if (ret)
+		return ret;
+
+	ret = pxa2xx_build_groups(pctl);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int pxa2xx_pinctrl_init(struct platform_device *pdev,
+			const struct pxa_desc_pin *ppins, int npins,
+			void __iomem *base_gafr[], void __iomem *base_gpdr[],
+			void __iomem *base_pgsr[])
+{
+	struct pxa_pinctrl *pctl;
+	int ret, i, maxpin = 0;
+
+	for (i = 0; i < npins; i++)
+		maxpin = max_t(int, ppins[i].pin.number, maxpin);
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+	pctl->base_gafr = devm_kcalloc(&pdev->dev, roundup(maxpin, 16),
+				       sizeof(*pctl->base_gafr), GFP_KERNEL);
+	pctl->base_gpdr = devm_kcalloc(&pdev->dev, roundup(maxpin, 32),
+				       sizeof(*pctl->base_gpdr), GFP_KERNEL);
+	pctl->base_pgsr = devm_kcalloc(&pdev->dev, roundup(maxpin, 32),
+				       sizeof(*pctl->base_pgsr), GFP_KERNEL);
+	if (!pctl->base_gafr || !pctl->base_gpdr || !pctl->base_pgsr)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pctl);
+	spin_lock_init(&pctl->lock);
+
+	pctl->dev = &pdev->dev;
+	pctl->desc = pxa2xx_pinctrl_desc;
+	pctl->desc.name = dev_name(&pdev->dev);
+	pctl->desc.owner = THIS_MODULE;
+
+	for (i = 0; i < roundup(maxpin, 16); i += 16)
+		pctl->base_gafr[i / 16] = base_gafr[i / 16];
+	for (i = 0; i < roundup(maxpin, 32); i += 32) {
+		pctl->base_gpdr[i / 32] = base_gpdr[i / 32];
+		pctl->base_pgsr[i / 32] = base_pgsr[i / 32];
+	}
+
+	ret = pxa2xx_build_state(pctl, ppins, npins);
+	if (ret)
+		return ret;
+
+	pctl->pctl_dev = pinctrl_register(&pctl->desc, &pdev->dev, pctl);
+	if (IS_ERR(pctl->pctl_dev)) {
+		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
+		return PTR_ERR(pctl->pctl_dev);
+	}
+
+	dev_info(&pdev->dev, "initialized pxa2xx pinctrl driver\n");
+
+	return 0;
+}
+
+int pxa2xx_pinctrl_exit(struct platform_device *pdev)
+{
+	struct pxa_pinctrl *pctl = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(pctl->pctl_dev);
+	return 0;
+}
diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.h b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h
new file mode 100644
index 000000000000..8be1e0b79751
--- /dev/null
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h
@@ -0,0 +1,92 @@
+/*
+ * Marvell PXA2xx family pin control
+ *
+ * Copyright (C) 2015 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ */
+
+#ifndef __PINCTRL_PXA_H
+#define __PINCTRL_PXA_H
+
+#define PXA_FUNCTION(_dir, _af, _name)				\
+	{							\
+		.name = _name,					\
+		.muxval = (_dir | (_af << 1)),			\
+	}
+
+#define PXA_PIN(_pin, funcs...)					\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct pxa_desc_function[]){	\
+			funcs, { } },				\
+	}
+
+#define PXA_GPIO_PIN(_pin, funcs...)				\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct pxa_desc_function[]){	\
+			PXA_FUNCTION(0, 0, "gpio_in"),		\
+			PXA_FUNCTION(1, 0, "gpio_out"),		\
+			funcs, { } },				\
+	}
+
+#define PXA_GPIO_ONLY_PIN(_pin)					\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct pxa_desc_function[]){	\
+			PXA_FUNCTION(0, 0, "gpio_in"),		\
+			PXA_FUNCTION(1, 0, "gpio_out"),		\
+			{ } },					\
+	}
+
+#define PXA_PINCTRL_PIN(pin)		\
+	PINCTRL_PIN(pin, "P" #pin)
+
+struct pxa_desc_function {
+	const char	*name;
+	u8		muxval;
+};
+
+struct pxa_desc_pin {
+	struct pinctrl_pin_desc		pin;
+	struct pxa_desc_function	*functions;
+};
+
+struct pxa_pinctrl_group {
+	const char	*name;
+	unsigned	pin;
+};
+
+struct pxa_pinctrl_function {
+	const char	*name;
+	const char	**groups;
+	unsigned	ngroups;
+};
+
+struct pxa_pinctrl {
+	spinlock_t			lock;
+	void __iomem			**base_gafr;
+	void __iomem			**base_gpdr;
+	void __iomem			**base_pgsr;
+	struct device			*dev;
+	struct pinctrl_desc		desc;
+	struct pinctrl_dev		*pctl_dev;
+	unsigned			npins;
+	const struct pxa_desc_pin	*ppins;
+	unsigned			ngroups;
+	struct pxa_pinctrl_group	*groups;
+	unsigned			nfuncs;
+	struct pxa_pinctrl_function	*functions;
+	char				*name;
+};
+
+int pxa2xx_pinctrl_init(struct platform_device *pdev,
+			const struct pxa_desc_pin *ppins, int npins,
+			void __iomem *base_gafr[], void __iomem *base_gpdr[],
+			void __iomem *base_gpsr[]);
+
+#endif /* __PINCTRL_PXA_H */
-- 
2.1.4

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

* [PATCH 2/6] pinctrl: pxa: pxa2xx: add pin control skeleton
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-kernel, linux-gpio, linux-arm-kernel

Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.

One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.

The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
 - a pin is obviously a pin
 - a group is also a pin, ie. group P101 is the pin 101
 - a mux function is an alternate function
   (ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)

The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/Kconfig          |   9 ++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 252 +++++++++++++++++++++++++++++++++++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.h |  92 +++++++++++++
 3 files changed, 353 insertions(+)
 create mode 100644 drivers/pinctrl/pxa/Kconfig
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.c
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.h

diff --git a/drivers/pinctrl/pxa/Kconfig b/drivers/pinctrl/pxa/Kconfig
new file mode 100644
index 000000000000..13e24d7c45c7
--- /dev/null
+++ b/drivers/pinctrl/pxa/Kconfig
@@ -0,0 +1,9 @@
+if (ARCH_PXA || COMPILE_TEST)
+
+config PINCTRL_PXA
+	bool
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+
+endif
diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
new file mode 100644
index 000000000000..baded1a8745b
--- /dev/null
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -0,0 +1,252 @@
+/*
+ * Marvell PXA2xx family pin control
+ *
+ * Copyright (C) 2015 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "../pinctrl-utils.h"
+#include "pinctrl-pxa2xx.h"
+
+static int pxa2xx_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->ngroups;
+}
+
+static const char *pxa2xx_pctrl_get_group_name(struct pinctrl_dev *pctldev,
+					       unsigned tgroup)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *group = pctl->groups + tgroup;
+
+	return group->name;
+}
+
+static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
+				       unsigned tgroup,
+				       const unsigned **pins,
+				       unsigned *num_pins)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *group = pctl->groups + tgroup;
+
+	*pins = (unsigned *)&group->pin;
+	*num_pins = 1;
+
+	return 0;
+}
+
+static const struct pinctrl_ops pxa2xx_pctl_ops = {
+#ifdef CONFIG_OF
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_all,
+	.dt_free_map		= pinctrl_utils_dt_free_map,
+#endif
+	.get_groups_count	= pxa2xx_pctrl_get_groups_count,
+	.get_group_name		= pxa2xx_pctrl_get_group_name,
+	.get_group_pins		= pxa2xx_pctrl_get_group_pins,
+};
+
+static struct pinctrl_desc pxa2xx_pinctrl_desc = {
+	.pctlops	= &pxa2xx_pctl_ops,
+};
+
+static const struct pxa_pinctrl_function *
+pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname,
+		     const struct pxa_pinctrl_function *functions)
+{
+	const struct pxa_pinctrl_function *func;
+
+	for (func = functions; func->name; func++)
+		if (!strcmp(fname, func->name))
+			return func;
+
+	return NULL;
+}
+
+static int pxa2xx_build_functions(struct pxa_pinctrl *pctl)
+{
+	int i;
+	struct pxa_pinctrl_function *functions;
+	struct pxa_desc_function *df;
+
+	/*
+	 * Each pin can have at most 6 alternate functions, and 2 gpio functions
+	 * which are common to each pin. As there are more than 2 pins without
+	 * alternate function, 6 * npins is an absolute high limit of the number
+	 * of functions.
+	 */
+	functions = devm_kcalloc(pctl->dev, pctl->npins * 6,
+				 sizeof(*functions), GFP_KERNEL);
+	if (!functions)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl->npins; i++)
+		for (df = pctl->ppins[i].functions; df->name; df++)
+			if (!pxa2xx_find_function(pctl, df->name, functions))
+				(functions + pctl->nfuncs++)->name = df->name;
+	pctl->functions = devm_kmemdup(pctl->dev, functions,
+				       pctl->nfuncs * sizeof(*functions),
+				       GFP_KERNEL);
+	if (!pctl->functions)
+		return -ENOMEM;
+
+	kfree(functions);
+	return 0;
+}
+
+static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
+{
+	int i, j, ngroups;
+	struct pxa_pinctrl_function *func;
+	struct pxa_desc_function *df;
+	char **gtmp;
+
+	gtmp = devm_kmalloc_array(pctl->dev, pctl->npins, sizeof(*gtmp),
+				  GFP_KERNEL);
+	if (!gtmp)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl->nfuncs; i++) {
+		ngroups = 0;
+		for (j = 0; j < pctl->npins; j++)
+			for (df = pctl->ppins[j].functions; df->name;
+			     df++)
+				if (!strcmp(pctl->functions[i].name,
+					    df->name))
+					gtmp[ngroups++] = (char *)
+						pctl->ppins[j].pin.name;
+		func = pctl->functions + i;
+		func->ngroups = ngroups;
+		func->groups =
+			devm_kmalloc_array(pctl->dev, ngroups,
+					   sizeof(char *), GFP_KERNEL);
+		if (!func->groups)
+			return -ENOMEM;
+
+		memcpy(func->groups, gtmp, ngroups * sizeof(*gtmp));
+	}
+
+	kfree(gtmp);
+	return 0;
+}
+
+static int pxa2xx_build_state(struct pxa_pinctrl *pctl,
+			      const struct pxa_desc_pin *ppins, int npins)
+{
+	struct pxa_pinctrl_group *group;
+	struct pinctrl_pin_desc *pins;
+	int ret, i;
+
+	pctl->npins = npins;
+	pctl->ppins = ppins;
+	pctl->ngroups = npins;
+
+	pctl->desc.npins = npins;
+	pins = devm_kcalloc(pctl->dev, npins, sizeof(*pins), GFP_KERNEL);
+	if (!pins)
+		return -ENOMEM;
+
+	pctl->desc.pins = pins;
+	for (i = 0; i < npins; i++)
+		pins[i] = ppins[i].pin;
+
+	pctl->groups = devm_kmalloc_array(pctl->dev, pctl->ngroups,
+					  sizeof(*pctl->groups), GFP_KERNEL);
+	if (!pctl->groups)
+		return -ENOMEM;
+
+	for (i = 0; i < npins; i++) {
+		group = pctl->groups + i;
+		group->name = ppins[i].pin.name;
+		group->pin = ppins[i].pin.number;
+	}
+
+	ret = pxa2xx_build_functions(pctl);
+	if (ret)
+		return ret;
+
+	ret = pxa2xx_build_groups(pctl);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int pxa2xx_pinctrl_init(struct platform_device *pdev,
+			const struct pxa_desc_pin *ppins, int npins,
+			void __iomem *base_gafr[], void __iomem *base_gpdr[],
+			void __iomem *base_pgsr[])
+{
+	struct pxa_pinctrl *pctl;
+	int ret, i, maxpin = 0;
+
+	for (i = 0; i < npins; i++)
+		maxpin = max_t(int, ppins[i].pin.number, maxpin);
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+	pctl->base_gafr = devm_kcalloc(&pdev->dev, roundup(maxpin, 16),
+				       sizeof(*pctl->base_gafr), GFP_KERNEL);
+	pctl->base_gpdr = devm_kcalloc(&pdev->dev, roundup(maxpin, 32),
+				       sizeof(*pctl->base_gpdr), GFP_KERNEL);
+	pctl->base_pgsr = devm_kcalloc(&pdev->dev, roundup(maxpin, 32),
+				       sizeof(*pctl->base_pgsr), GFP_KERNEL);
+	if (!pctl->base_gafr || !pctl->base_gpdr || !pctl->base_pgsr)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pctl);
+	spin_lock_init(&pctl->lock);
+
+	pctl->dev = &pdev->dev;
+	pctl->desc = pxa2xx_pinctrl_desc;
+	pctl->desc.name = dev_name(&pdev->dev);
+	pctl->desc.owner = THIS_MODULE;
+
+	for (i = 0; i < roundup(maxpin, 16); i += 16)
+		pctl->base_gafr[i / 16] = base_gafr[i / 16];
+	for (i = 0; i < roundup(maxpin, 32); i += 32) {
+		pctl->base_gpdr[i / 32] = base_gpdr[i / 32];
+		pctl->base_pgsr[i / 32] = base_pgsr[i / 32];
+	}
+
+	ret = pxa2xx_build_state(pctl, ppins, npins);
+	if (ret)
+		return ret;
+
+	pctl->pctl_dev = pinctrl_register(&pctl->desc, &pdev->dev, pctl);
+	if (IS_ERR(pctl->pctl_dev)) {
+		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
+		return PTR_ERR(pctl->pctl_dev);
+	}
+
+	dev_info(&pdev->dev, "initialized pxa2xx pinctrl driver\n");
+
+	return 0;
+}
+
+int pxa2xx_pinctrl_exit(struct platform_device *pdev)
+{
+	struct pxa_pinctrl *pctl = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(pctl->pctl_dev);
+	return 0;
+}
diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.h b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h
new file mode 100644
index 000000000000..8be1e0b79751
--- /dev/null
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h
@@ -0,0 +1,92 @@
+/*
+ * Marvell PXA2xx family pin control
+ *
+ * Copyright (C) 2015 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ */
+
+#ifndef __PINCTRL_PXA_H
+#define __PINCTRL_PXA_H
+
+#define PXA_FUNCTION(_dir, _af, _name)				\
+	{							\
+		.name = _name,					\
+		.muxval = (_dir | (_af << 1)),			\
+	}
+
+#define PXA_PIN(_pin, funcs...)					\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct pxa_desc_function[]){	\
+			funcs, { } },				\
+	}
+
+#define PXA_GPIO_PIN(_pin, funcs...)				\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct pxa_desc_function[]){	\
+			PXA_FUNCTION(0, 0, "gpio_in"),		\
+			PXA_FUNCTION(1, 0, "gpio_out"),		\
+			funcs, { } },				\
+	}
+
+#define PXA_GPIO_ONLY_PIN(_pin)					\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct pxa_desc_function[]){	\
+			PXA_FUNCTION(0, 0, "gpio_in"),		\
+			PXA_FUNCTION(1, 0, "gpio_out"),		\
+			{ } },					\
+	}
+
+#define PXA_PINCTRL_PIN(pin)		\
+	PINCTRL_PIN(pin, "P" #pin)
+
+struct pxa_desc_function {
+	const char	*name;
+	u8		muxval;
+};
+
+struct pxa_desc_pin {
+	struct pinctrl_pin_desc		pin;
+	struct pxa_desc_function	*functions;
+};
+
+struct pxa_pinctrl_group {
+	const char	*name;
+	unsigned	pin;
+};
+
+struct pxa_pinctrl_function {
+	const char	*name;
+	const char	**groups;
+	unsigned	ngroups;
+};
+
+struct pxa_pinctrl {
+	spinlock_t			lock;
+	void __iomem			**base_gafr;
+	void __iomem			**base_gpdr;
+	void __iomem			**base_pgsr;
+	struct device			*dev;
+	struct pinctrl_desc		desc;
+	struct pinctrl_dev		*pctl_dev;
+	unsigned			npins;
+	const struct pxa_desc_pin	*ppins;
+	unsigned			ngroups;
+	struct pxa_pinctrl_group	*groups;
+	unsigned			nfuncs;
+	struct pxa_pinctrl_function	*functions;
+	char				*name;
+};
+
+int pxa2xx_pinctrl_init(struct platform_device *pdev,
+			const struct pxa_desc_pin *ppins, int npins,
+			void __iomem *base_gafr[], void __iomem *base_gpdr[],
+			void __iomem *base_gpsr[]);
+
+#endif /* __PINCTRL_PXA_H */
-- 
2.1.4


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

* [PATCH 2/6] pinctrl: pxa: pxa2xx: add pin control skeleton
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.

One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.

The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
 - a pin is obviously a pin
 - a group is also a pin, ie. group P101 is the pin 101
 - a mux function is an alternate function
   (ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)

The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/Kconfig          |   9 ++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 252 +++++++++++++++++++++++++++++++++++
 drivers/pinctrl/pxa/pinctrl-pxa2xx.h |  92 +++++++++++++
 3 files changed, 353 insertions(+)
 create mode 100644 drivers/pinctrl/pxa/Kconfig
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.c
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa2xx.h

diff --git a/drivers/pinctrl/pxa/Kconfig b/drivers/pinctrl/pxa/Kconfig
new file mode 100644
index 000000000000..13e24d7c45c7
--- /dev/null
+++ b/drivers/pinctrl/pxa/Kconfig
@@ -0,0 +1,9 @@
+if (ARCH_PXA || COMPILE_TEST)
+
+config PINCTRL_PXA
+	bool
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+
+endif
diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
new file mode 100644
index 000000000000..baded1a8745b
--- /dev/null
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -0,0 +1,252 @@
+/*
+ * Marvell PXA2xx family pin control
+ *
+ * Copyright (C) 2015 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "../pinctrl-utils.h"
+#include "pinctrl-pxa2xx.h"
+
+static int pxa2xx_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->ngroups;
+}
+
+static const char *pxa2xx_pctrl_get_group_name(struct pinctrl_dev *pctldev,
+					       unsigned tgroup)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *group = pctl->groups + tgroup;
+
+	return group->name;
+}
+
+static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
+				       unsigned tgroup,
+				       const unsigned **pins,
+				       unsigned *num_pins)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *group = pctl->groups + tgroup;
+
+	*pins = (unsigned *)&group->pin;
+	*num_pins = 1;
+
+	return 0;
+}
+
+static const struct pinctrl_ops pxa2xx_pctl_ops = {
+#ifdef CONFIG_OF
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_all,
+	.dt_free_map		= pinctrl_utils_dt_free_map,
+#endif
+	.get_groups_count	= pxa2xx_pctrl_get_groups_count,
+	.get_group_name		= pxa2xx_pctrl_get_group_name,
+	.get_group_pins		= pxa2xx_pctrl_get_group_pins,
+};
+
+static struct pinctrl_desc pxa2xx_pinctrl_desc = {
+	.pctlops	= &pxa2xx_pctl_ops,
+};
+
+static const struct pxa_pinctrl_function *
+pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname,
+		     const struct pxa_pinctrl_function *functions)
+{
+	const struct pxa_pinctrl_function *func;
+
+	for (func = functions; func->name; func++)
+		if (!strcmp(fname, func->name))
+			return func;
+
+	return NULL;
+}
+
+static int pxa2xx_build_functions(struct pxa_pinctrl *pctl)
+{
+	int i;
+	struct pxa_pinctrl_function *functions;
+	struct pxa_desc_function *df;
+
+	/*
+	 * Each pin can have at most 6 alternate functions, and 2 gpio functions
+	 * which are common to each pin. As there are more than 2 pins without
+	 * alternate function, 6 * npins is an absolute high limit of the number
+	 * of functions.
+	 */
+	functions = devm_kcalloc(pctl->dev, pctl->npins * 6,
+				 sizeof(*functions), GFP_KERNEL);
+	if (!functions)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl->npins; i++)
+		for (df = pctl->ppins[i].functions; df->name; df++)
+			if (!pxa2xx_find_function(pctl, df->name, functions))
+				(functions + pctl->nfuncs++)->name = df->name;
+	pctl->functions = devm_kmemdup(pctl->dev, functions,
+				       pctl->nfuncs * sizeof(*functions),
+				       GFP_KERNEL);
+	if (!pctl->functions)
+		return -ENOMEM;
+
+	kfree(functions);
+	return 0;
+}
+
+static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
+{
+	int i, j, ngroups;
+	struct pxa_pinctrl_function *func;
+	struct pxa_desc_function *df;
+	char **gtmp;
+
+	gtmp = devm_kmalloc_array(pctl->dev, pctl->npins, sizeof(*gtmp),
+				  GFP_KERNEL);
+	if (!gtmp)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl->nfuncs; i++) {
+		ngroups = 0;
+		for (j = 0; j < pctl->npins; j++)
+			for (df = pctl->ppins[j].functions; df->name;
+			     df++)
+				if (!strcmp(pctl->functions[i].name,
+					    df->name))
+					gtmp[ngroups++] = (char *)
+						pctl->ppins[j].pin.name;
+		func = pctl->functions + i;
+		func->ngroups = ngroups;
+		func->groups =
+			devm_kmalloc_array(pctl->dev, ngroups,
+					   sizeof(char *), GFP_KERNEL);
+		if (!func->groups)
+			return -ENOMEM;
+
+		memcpy(func->groups, gtmp, ngroups * sizeof(*gtmp));
+	}
+
+	kfree(gtmp);
+	return 0;
+}
+
+static int pxa2xx_build_state(struct pxa_pinctrl *pctl,
+			      const struct pxa_desc_pin *ppins, int npins)
+{
+	struct pxa_pinctrl_group *group;
+	struct pinctrl_pin_desc *pins;
+	int ret, i;
+
+	pctl->npins = npins;
+	pctl->ppins = ppins;
+	pctl->ngroups = npins;
+
+	pctl->desc.npins = npins;
+	pins = devm_kcalloc(pctl->dev, npins, sizeof(*pins), GFP_KERNEL);
+	if (!pins)
+		return -ENOMEM;
+
+	pctl->desc.pins = pins;
+	for (i = 0; i < npins; i++)
+		pins[i] = ppins[i].pin;
+
+	pctl->groups = devm_kmalloc_array(pctl->dev, pctl->ngroups,
+					  sizeof(*pctl->groups), GFP_KERNEL);
+	if (!pctl->groups)
+		return -ENOMEM;
+
+	for (i = 0; i < npins; i++) {
+		group = pctl->groups + i;
+		group->name = ppins[i].pin.name;
+		group->pin = ppins[i].pin.number;
+	}
+
+	ret = pxa2xx_build_functions(pctl);
+	if (ret)
+		return ret;
+
+	ret = pxa2xx_build_groups(pctl);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int pxa2xx_pinctrl_init(struct platform_device *pdev,
+			const struct pxa_desc_pin *ppins, int npins,
+			void __iomem *base_gafr[], void __iomem *base_gpdr[],
+			void __iomem *base_pgsr[])
+{
+	struct pxa_pinctrl *pctl;
+	int ret, i, maxpin = 0;
+
+	for (i = 0; i < npins; i++)
+		maxpin = max_t(int, ppins[i].pin.number, maxpin);
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+	pctl->base_gafr = devm_kcalloc(&pdev->dev, roundup(maxpin, 16),
+				       sizeof(*pctl->base_gafr), GFP_KERNEL);
+	pctl->base_gpdr = devm_kcalloc(&pdev->dev, roundup(maxpin, 32),
+				       sizeof(*pctl->base_gpdr), GFP_KERNEL);
+	pctl->base_pgsr = devm_kcalloc(&pdev->dev, roundup(maxpin, 32),
+				       sizeof(*pctl->base_pgsr), GFP_KERNEL);
+	if (!pctl->base_gafr || !pctl->base_gpdr || !pctl->base_pgsr)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pctl);
+	spin_lock_init(&pctl->lock);
+
+	pctl->dev = &pdev->dev;
+	pctl->desc = pxa2xx_pinctrl_desc;
+	pctl->desc.name = dev_name(&pdev->dev);
+	pctl->desc.owner = THIS_MODULE;
+
+	for (i = 0; i < roundup(maxpin, 16); i += 16)
+		pctl->base_gafr[i / 16] = base_gafr[i / 16];
+	for (i = 0; i < roundup(maxpin, 32); i += 32) {
+		pctl->base_gpdr[i / 32] = base_gpdr[i / 32];
+		pctl->base_pgsr[i / 32] = base_pgsr[i / 32];
+	}
+
+	ret = pxa2xx_build_state(pctl, ppins, npins);
+	if (ret)
+		return ret;
+
+	pctl->pctl_dev = pinctrl_register(&pctl->desc, &pdev->dev, pctl);
+	if (IS_ERR(pctl->pctl_dev)) {
+		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
+		return PTR_ERR(pctl->pctl_dev);
+	}
+
+	dev_info(&pdev->dev, "initialized pxa2xx pinctrl driver\n");
+
+	return 0;
+}
+
+int pxa2xx_pinctrl_exit(struct platform_device *pdev)
+{
+	struct pxa_pinctrl *pctl = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(pctl->pctl_dev);
+	return 0;
+}
diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.h b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h
new file mode 100644
index 000000000000..8be1e0b79751
--- /dev/null
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h
@@ -0,0 +1,92 @@
+/*
+ * Marvell PXA2xx family pin control
+ *
+ * Copyright (C) 2015 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ */
+
+#ifndef __PINCTRL_PXA_H
+#define __PINCTRL_PXA_H
+
+#define PXA_FUNCTION(_dir, _af, _name)				\
+	{							\
+		.name = _name,					\
+		.muxval = (_dir | (_af << 1)),			\
+	}
+
+#define PXA_PIN(_pin, funcs...)					\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct pxa_desc_function[]){	\
+			funcs, { } },				\
+	}
+
+#define PXA_GPIO_PIN(_pin, funcs...)				\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct pxa_desc_function[]){	\
+			PXA_FUNCTION(0, 0, "gpio_in"),		\
+			PXA_FUNCTION(1, 0, "gpio_out"),		\
+			funcs, { } },				\
+	}
+
+#define PXA_GPIO_ONLY_PIN(_pin)					\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct pxa_desc_function[]){	\
+			PXA_FUNCTION(0, 0, "gpio_in"),		\
+			PXA_FUNCTION(1, 0, "gpio_out"),		\
+			{ } },					\
+	}
+
+#define PXA_PINCTRL_PIN(pin)		\
+	PINCTRL_PIN(pin, "P" #pin)
+
+struct pxa_desc_function {
+	const char	*name;
+	u8		muxval;
+};
+
+struct pxa_desc_pin {
+	struct pinctrl_pin_desc		pin;
+	struct pxa_desc_function	*functions;
+};
+
+struct pxa_pinctrl_group {
+	const char	*name;
+	unsigned	pin;
+};
+
+struct pxa_pinctrl_function {
+	const char	*name;
+	const char	**groups;
+	unsigned	ngroups;
+};
+
+struct pxa_pinctrl {
+	spinlock_t			lock;
+	void __iomem			**base_gafr;
+	void __iomem			**base_gpdr;
+	void __iomem			**base_pgsr;
+	struct device			*dev;
+	struct pinctrl_desc		desc;
+	struct pinctrl_dev		*pctl_dev;
+	unsigned			npins;
+	const struct pxa_desc_pin	*ppins;
+	unsigned			ngroups;
+	struct pxa_pinctrl_group	*groups;
+	unsigned			nfuncs;
+	struct pxa_pinctrl_function	*functions;
+	char				*name;
+};
+
+int pxa2xx_pinctrl_init(struct platform_device *pdev,
+			const struct pxa_desc_pin *ppins, int npins,
+			void __iomem *base_gafr[], void __iomem *base_gpdr[],
+			void __iomem *base_gpsr[]);
+
+#endif /* __PINCTRL_PXA_H */
-- 
2.1.4

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

* [PATCH 3/6] pinctrl: pxa: pxa2xx: add pin muxing
  2015-11-21 18:04 ` Robert Jarzmik
  (?)
@ 2015-11-21 18:04   ` Robert Jarzmik
  -1 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-gpio, linux-kernel, linux-arm-kernel

The driver is inspired from the sunxi driver. The pxa architecture
specificities leading to the driver are :
 - each pin has 8 possible alternate functions
 - 4 of these are output kind
 - 4 of these are input kind
 - there is always a "gpio input" and "gpio output" function
 - the function matrix is very scattered :
   - some functions can be found on 5 different pads
   - the number of functions is greater than the number of pins
   - there is no "topology" grouping of pins (such as all SPI in one
     corner of the die)

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 121 +++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
index baded1a8745b..a4ba82459af8 100644
--- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -64,8 +64,129 @@ static const struct pinctrl_ops pxa2xx_pctl_ops = {
 	.get_group_pins		= pxa2xx_pctrl_get_group_pins,
 };
 
+static struct pxa_desc_function *
+pxa_desc_by_func_group(struct pxa_pinctrl *pctl, const char *pin_name,
+		       const char *func_name)
+{
+	int i;
+	struct pxa_desc_function *df;
+
+	for (i = 0; i < pctl->npins; i++) {
+		const struct pxa_desc_pin *pin = pctl->ppins + i;
+
+		if (!strcmp(pin->pin.name, pin_name))
+			for (df = pin->functions; df->name; df++)
+				if (!strcmp(df->name, func_name))
+					return df;
+	}
+
+	return NULL;
+}
+
+static int pxa2xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+					 struct pinctrl_gpio_range *range,
+					 unsigned pin,
+					 bool input)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long flags;
+	uint32_t val;
+	void __iomem *gpdr;
+
+	gpdr = pctl->base_gpdr[pin / 32];
+	dev_dbg(pctl->dev, "set_direction(pin=%d): dir=%d\n",
+		pin, !input);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	val = readl_relaxed(gpdr);
+	val = (val & ~BIT(pin % 32)) | (input ? 0 : BIT(pin % 32));
+	writel_relaxed(val, gpdr);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+
+static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev,
+					    unsigned function)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_function *pf = pctl->functions + function;
+
+	return pf->name;
+}
+
+static int pxa2xx_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->nfuncs;
+}
+
+static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev,
+				      unsigned function,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_function *pf = pctl->functions + function;
+
+	*groups = pf->groups;
+	*num_groups = pf->ngroups;
+
+	return 0;
+}
+
+static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function,
+			      unsigned tgroup)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *group = pctl->groups + tgroup;
+	struct pxa_desc_function *df;
+	int pin, shift;
+	unsigned long flags;
+	void __iomem *gafr, *gpdr;
+	u32 val;
+
+
+	df = pxa_desc_by_func_group(pctl, group->name,
+				    (pctl->functions + function)->name);
+	if (!df)
+		return -EINVAL;
+
+	pin = group->pin;
+	gafr = pctl->base_gafr[pin / 16];
+	gpdr = pctl->base_gpdr[pin / 32];
+	shift = (pin % 16) << 1;
+	dev_dbg(pctl->dev, "set_mux(pin=%d): af=%d dir=%d\n",
+		pin, df->muxval >> 1, df->muxval & 0x1);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	val = readl_relaxed(gafr);
+	val = (val & ~(0x3 << shift)) | ((df->muxval >> 1) << shift);
+	writel_relaxed(val, gafr);
+
+	val = readl_relaxed(gpdr);
+	val = (val & ~BIT(pin % 32)) | ((df->muxval & 1) ? BIT(pin % 32) : 0);
+	writel_relaxed(val, gpdr);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+static const struct pinmux_ops pxa2xx_pinmux_ops = {
+	.get_functions_count = pxa2xx_get_functions_count,
+	.get_function_name = pxa2xx_pmx_get_func_name,
+	.get_function_groups = pxa2xx_pmx_get_func_groups,
+	.set_mux = pxa2xx_pmx_set_mux,
+	.gpio_set_direction = pxa2xx_pmx_gpio_set_direction,
+};
+
 static struct pinctrl_desc pxa2xx_pinctrl_desc = {
 	.pctlops	= &pxa2xx_pctl_ops,
+	.pmxops		= &pxa2xx_pinmux_ops,
 };
 
 static const struct pxa_pinctrl_function *
-- 
2.1.4

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

* [PATCH 3/6] pinctrl: pxa: pxa2xx: add pin muxing
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-kernel, linux-gpio, linux-arm-kernel

The driver is inspired from the sunxi driver. The pxa architecture
specificities leading to the driver are :
 - each pin has 8 possible alternate functions
 - 4 of these are output kind
 - 4 of these are input kind
 - there is always a "gpio input" and "gpio output" function
 - the function matrix is very scattered :
   - some functions can be found on 5 different pads
   - the number of functions is greater than the number of pins
   - there is no "topology" grouping of pins (such as all SPI in one
     corner of the die)

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 121 +++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
index baded1a8745b..a4ba82459af8 100644
--- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -64,8 +64,129 @@ static const struct pinctrl_ops pxa2xx_pctl_ops = {
 	.get_group_pins		= pxa2xx_pctrl_get_group_pins,
 };
 
+static struct pxa_desc_function *
+pxa_desc_by_func_group(struct pxa_pinctrl *pctl, const char *pin_name,
+		       const char *func_name)
+{
+	int i;
+	struct pxa_desc_function *df;
+
+	for (i = 0; i < pctl->npins; i++) {
+		const struct pxa_desc_pin *pin = pctl->ppins + i;
+
+		if (!strcmp(pin->pin.name, pin_name))
+			for (df = pin->functions; df->name; df++)
+				if (!strcmp(df->name, func_name))
+					return df;
+	}
+
+	return NULL;
+}
+
+static int pxa2xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+					 struct pinctrl_gpio_range *range,
+					 unsigned pin,
+					 bool input)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long flags;
+	uint32_t val;
+	void __iomem *gpdr;
+
+	gpdr = pctl->base_gpdr[pin / 32];
+	dev_dbg(pctl->dev, "set_direction(pin=%d): dir=%d\n",
+		pin, !input);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	val = readl_relaxed(gpdr);
+	val = (val & ~BIT(pin % 32)) | (input ? 0 : BIT(pin % 32));
+	writel_relaxed(val, gpdr);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+
+static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev,
+					    unsigned function)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_function *pf = pctl->functions + function;
+
+	return pf->name;
+}
+
+static int pxa2xx_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->nfuncs;
+}
+
+static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev,
+				      unsigned function,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_function *pf = pctl->functions + function;
+
+	*groups = pf->groups;
+	*num_groups = pf->ngroups;
+
+	return 0;
+}
+
+static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function,
+			      unsigned tgroup)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *group = pctl->groups + tgroup;
+	struct pxa_desc_function *df;
+	int pin, shift;
+	unsigned long flags;
+	void __iomem *gafr, *gpdr;
+	u32 val;
+
+
+	df = pxa_desc_by_func_group(pctl, group->name,
+				    (pctl->functions + function)->name);
+	if (!df)
+		return -EINVAL;
+
+	pin = group->pin;
+	gafr = pctl->base_gafr[pin / 16];
+	gpdr = pctl->base_gpdr[pin / 32];
+	shift = (pin % 16) << 1;
+	dev_dbg(pctl->dev, "set_mux(pin=%d): af=%d dir=%d\n",
+		pin, df->muxval >> 1, df->muxval & 0x1);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	val = readl_relaxed(gafr);
+	val = (val & ~(0x3 << shift)) | ((df->muxval >> 1) << shift);
+	writel_relaxed(val, gafr);
+
+	val = readl_relaxed(gpdr);
+	val = (val & ~BIT(pin % 32)) | ((df->muxval & 1) ? BIT(pin % 32) : 0);
+	writel_relaxed(val, gpdr);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+static const struct pinmux_ops pxa2xx_pinmux_ops = {
+	.get_functions_count = pxa2xx_get_functions_count,
+	.get_function_name = pxa2xx_pmx_get_func_name,
+	.get_function_groups = pxa2xx_pmx_get_func_groups,
+	.set_mux = pxa2xx_pmx_set_mux,
+	.gpio_set_direction = pxa2xx_pmx_gpio_set_direction,
+};
+
 static struct pinctrl_desc pxa2xx_pinctrl_desc = {
 	.pctlops	= &pxa2xx_pctl_ops,
+	.pmxops		= &pxa2xx_pinmux_ops,
 };
 
 static const struct pxa_pinctrl_function *
-- 
2.1.4


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

* [PATCH 3/6] pinctrl: pxa: pxa2xx: add pin muxing
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

The driver is inspired from the sunxi driver. The pxa architecture
specificities leading to the driver are :
 - each pin has 8 possible alternate functions
 - 4 of these are output kind
 - 4 of these are input kind
 - there is always a "gpio input" and "gpio output" function
 - the function matrix is very scattered :
   - some functions can be found on 5 different pads
   - the number of functions is greater than the number of pins
   - there is no "topology" grouping of pins (such as all SPI in one
     corner of the die)

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 121 +++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
index baded1a8745b..a4ba82459af8 100644
--- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -64,8 +64,129 @@ static const struct pinctrl_ops pxa2xx_pctl_ops = {
 	.get_group_pins		= pxa2xx_pctrl_get_group_pins,
 };
 
+static struct pxa_desc_function *
+pxa_desc_by_func_group(struct pxa_pinctrl *pctl, const char *pin_name,
+		       const char *func_name)
+{
+	int i;
+	struct pxa_desc_function *df;
+
+	for (i = 0; i < pctl->npins; i++) {
+		const struct pxa_desc_pin *pin = pctl->ppins + i;
+
+		if (!strcmp(pin->pin.name, pin_name))
+			for (df = pin->functions; df->name; df++)
+				if (!strcmp(df->name, func_name))
+					return df;
+	}
+
+	return NULL;
+}
+
+static int pxa2xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+					 struct pinctrl_gpio_range *range,
+					 unsigned pin,
+					 bool input)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long flags;
+	uint32_t val;
+	void __iomem *gpdr;
+
+	gpdr = pctl->base_gpdr[pin / 32];
+	dev_dbg(pctl->dev, "set_direction(pin=%d): dir=%d\n",
+		pin, !input);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	val = readl_relaxed(gpdr);
+	val = (val & ~BIT(pin % 32)) | (input ? 0 : BIT(pin % 32));
+	writel_relaxed(val, gpdr);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+
+static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev,
+					    unsigned function)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_function *pf = pctl->functions + function;
+
+	return pf->name;
+}
+
+static int pxa2xx_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->nfuncs;
+}
+
+static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev,
+				      unsigned function,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_function *pf = pctl->functions + function;
+
+	*groups = pf->groups;
+	*num_groups = pf->ngroups;
+
+	return 0;
+}
+
+static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function,
+			      unsigned tgroup)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *group = pctl->groups + tgroup;
+	struct pxa_desc_function *df;
+	int pin, shift;
+	unsigned long flags;
+	void __iomem *gafr, *gpdr;
+	u32 val;
+
+
+	df = pxa_desc_by_func_group(pctl, group->name,
+				    (pctl->functions + function)->name);
+	if (!df)
+		return -EINVAL;
+
+	pin = group->pin;
+	gafr = pctl->base_gafr[pin / 16];
+	gpdr = pctl->base_gpdr[pin / 32];
+	shift = (pin % 16) << 1;
+	dev_dbg(pctl->dev, "set_mux(pin=%d): af=%d dir=%d\n",
+		pin, df->muxval >> 1, df->muxval & 0x1);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	val = readl_relaxed(gafr);
+	val = (val & ~(0x3 << shift)) | ((df->muxval >> 1) << shift);
+	writel_relaxed(val, gafr);
+
+	val = readl_relaxed(gpdr);
+	val = (val & ~BIT(pin % 32)) | ((df->muxval & 1) ? BIT(pin % 32) : 0);
+	writel_relaxed(val, gpdr);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+static const struct pinmux_ops pxa2xx_pinmux_ops = {
+	.get_functions_count = pxa2xx_get_functions_count,
+	.get_function_name = pxa2xx_pmx_get_func_name,
+	.get_function_groups = pxa2xx_pmx_get_func_groups,
+	.set_mux = pxa2xx_pmx_set_mux,
+	.gpio_set_direction = pxa2xx_pmx_gpio_set_direction,
+};
+
 static struct pinctrl_desc pxa2xx_pinctrl_desc = {
 	.pctlops	= &pxa2xx_pctl_ops,
+	.pmxops		= &pxa2xx_pinmux_ops,
 };
 
 static const struct pxa_pinctrl_function *
-- 
2.1.4

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

* [PATCH 4/6] pinctrl: pxa: pxa2xx: add pin configuration support
  2015-11-21 18:04 ` Robert Jarzmik
  (?)
@ 2015-11-21 18:04   ` Robert Jarzmik
  -1 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-gpio, linux-kernel, linux-arm-kernel

Add pin configuration for pxa2xx architectures. PXA doesn't provide any
bias, push, pull capabilities. The only capability is to set a state for
the pins when the platform enter sleep or deep sleep mode.

The state of a pin is set by :
 - whether the GPIO direction was input or output
 - if it is output, a register set programs whether the pin should be
   held to ground or VccIO

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 63 ++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
index a4ba82459af8..e01914460219 100644
--- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -184,7 +184,70 @@ static const struct pinmux_ops pxa2xx_pinmux_ops = {
 	.gpio_set_direction = pxa2xx_pmx_gpio_set_direction,
 };
 
+static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev,
+				  unsigned group,
+				  unsigned long *config)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *g = pctl->groups + group;
+	unsigned long flags;
+	unsigned pin = g->pin;
+	void __iomem *pgsr = pctl->base_pgsr[pin / 32];
+	u32 val;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	val = readl_relaxed(pgsr) & BIT(pin % 32);
+	*config = val ? PIN_CONFIG_LOW_POWER_MODE : 0;
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	dev_dbg(pctl->dev, "get sleep gpio state(pin=%d) %d\n",
+		pin, !!val);
+	return 0;
+}
+
+static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev,
+				  unsigned group,
+				  unsigned long *configs,
+				  unsigned num_configs)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *g = pctl->groups + group;
+	unsigned long flags;
+	unsigned pin = g->pin;
+	void __iomem *pgsr = pctl->base_pgsr[pin / 32];
+	int i, is_set = 0;
+	u32 val;
+
+	for (i = 0; i < num_configs; i++) {
+		switch (pinconf_to_config_param(configs[i])) {
+		case PIN_CONFIG_LOW_POWER_MODE:
+			is_set = pinconf_to_config_argument(configs[i]);
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	dev_dbg(pctl->dev, "set sleep gpio state(pin=%d) %d\n",
+		pin, is_set);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	val = readl_relaxed(pgsr);
+	val = (val & ~BIT(pin % 32)) | (is_set ? BIT(pin % 32) : 0);
+	writel_relaxed(val, pgsr);
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+
+static const struct pinconf_ops pxa2xx_pconf_ops = {
+	.pin_config_group_get	= pxa2xx_pconf_group_get,
+	.pin_config_group_set	= pxa2xx_pconf_group_set,
+	.is_generic		= true,
+};
+
 static struct pinctrl_desc pxa2xx_pinctrl_desc = {
+	.confops	= &pxa2xx_pconf_ops,
 	.pctlops	= &pxa2xx_pctl_ops,
 	.pmxops		= &pxa2xx_pinmux_ops,
 };
-- 
2.1.4

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

* [PATCH 4/6] pinctrl: pxa: pxa2xx: add pin configuration support
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-kernel, linux-gpio, linux-arm-kernel

Add pin configuration for pxa2xx architectures. PXA doesn't provide any
bias, push, pull capabilities. The only capability is to set a state for
the pins when the platform enter sleep or deep sleep mode.

The state of a pin is set by :
 - whether the GPIO direction was input or output
 - if it is output, a register set programs whether the pin should be
   held to ground or VccIO

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 63 ++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
index a4ba82459af8..e01914460219 100644
--- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -184,7 +184,70 @@ static const struct pinmux_ops pxa2xx_pinmux_ops = {
 	.gpio_set_direction = pxa2xx_pmx_gpio_set_direction,
 };
 
+static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev,
+				  unsigned group,
+				  unsigned long *config)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *g = pctl->groups + group;
+	unsigned long flags;
+	unsigned pin = g->pin;
+	void __iomem *pgsr = pctl->base_pgsr[pin / 32];
+	u32 val;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	val = readl_relaxed(pgsr) & BIT(pin % 32);
+	*config = val ? PIN_CONFIG_LOW_POWER_MODE : 0;
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	dev_dbg(pctl->dev, "get sleep gpio state(pin=%d) %d\n",
+		pin, !!val);
+	return 0;
+}
+
+static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev,
+				  unsigned group,
+				  unsigned long *configs,
+				  unsigned num_configs)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *g = pctl->groups + group;
+	unsigned long flags;
+	unsigned pin = g->pin;
+	void __iomem *pgsr = pctl->base_pgsr[pin / 32];
+	int i, is_set = 0;
+	u32 val;
+
+	for (i = 0; i < num_configs; i++) {
+		switch (pinconf_to_config_param(configs[i])) {
+		case PIN_CONFIG_LOW_POWER_MODE:
+			is_set = pinconf_to_config_argument(configs[i]);
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	dev_dbg(pctl->dev, "set sleep gpio state(pin=%d) %d\n",
+		pin, is_set);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	val = readl_relaxed(pgsr);
+	val = (val & ~BIT(pin % 32)) | (is_set ? BIT(pin % 32) : 0);
+	writel_relaxed(val, pgsr);
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+
+static const struct pinconf_ops pxa2xx_pconf_ops = {
+	.pin_config_group_get	= pxa2xx_pconf_group_get,
+	.pin_config_group_set	= pxa2xx_pconf_group_set,
+	.is_generic		= true,
+};
+
 static struct pinctrl_desc pxa2xx_pinctrl_desc = {
+	.confops	= &pxa2xx_pconf_ops,
 	.pctlops	= &pxa2xx_pctl_ops,
 	.pmxops		= &pxa2xx_pinmux_ops,
 };
-- 
2.1.4


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

* [PATCH 4/6] pinctrl: pxa: pxa2xx: add pin configuration support
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add pin configuration for pxa2xx architectures. PXA doesn't provide any
bias, push, pull capabilities. The only capability is to set a state for
the pins when the platform enter sleep or deep sleep mode.

The state of a pin is set by :
 - whether the GPIO direction was input or output
 - if it is output, a register set programs whether the pin should be
   held to ground or VccIO

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 63 ++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
index a4ba82459af8..e01914460219 100644
--- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -184,7 +184,70 @@ static const struct pinmux_ops pxa2xx_pinmux_ops = {
 	.gpio_set_direction = pxa2xx_pmx_gpio_set_direction,
 };
 
+static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev,
+				  unsigned group,
+				  unsigned long *config)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *g = pctl->groups + group;
+	unsigned long flags;
+	unsigned pin = g->pin;
+	void __iomem *pgsr = pctl->base_pgsr[pin / 32];
+	u32 val;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	val = readl_relaxed(pgsr) & BIT(pin % 32);
+	*config = val ? PIN_CONFIG_LOW_POWER_MODE : 0;
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	dev_dbg(pctl->dev, "get sleep gpio state(pin=%d) %d\n",
+		pin, !!val);
+	return 0;
+}
+
+static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev,
+				  unsigned group,
+				  unsigned long *configs,
+				  unsigned num_configs)
+{
+	struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pxa_pinctrl_group *g = pctl->groups + group;
+	unsigned long flags;
+	unsigned pin = g->pin;
+	void __iomem *pgsr = pctl->base_pgsr[pin / 32];
+	int i, is_set = 0;
+	u32 val;
+
+	for (i = 0; i < num_configs; i++) {
+		switch (pinconf_to_config_param(configs[i])) {
+		case PIN_CONFIG_LOW_POWER_MODE:
+			is_set = pinconf_to_config_argument(configs[i]);
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	dev_dbg(pctl->dev, "set sleep gpio state(pin=%d) %d\n",
+		pin, is_set);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	val = readl_relaxed(pgsr);
+	val = (val & ~BIT(pin % 32)) | (is_set ? BIT(pin % 32) : 0);
+	writel_relaxed(val, pgsr);
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+
+static const struct pinconf_ops pxa2xx_pconf_ops = {
+	.pin_config_group_get	= pxa2xx_pconf_group_get,
+	.pin_config_group_set	= pxa2xx_pconf_group_set,
+	.is_generic		= true,
+};
+
 static struct pinctrl_desc pxa2xx_pinctrl_desc = {
+	.confops	= &pxa2xx_pconf_ops,
 	.pctlops	= &pxa2xx_pctl_ops,
 	.pmxops		= &pxa2xx_pinmux_ops,
 };
-- 
2.1.4

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

* [PATCH 5/6] pinctrl: pxa: add pxa27x architecture
  2015-11-21 18:04 ` Robert Jarzmik
@ 2015-11-21 18:04   ` Robert Jarzmik
  -1 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-kernel, linux-gpio, linux-arm-kernel

Add the pxa27x architecture, which is a pxa2xx with 128 pins. The
registers spacing, and pins logic is common to pxa2xx, only the pins and
their alternate function are specific to pxa27x.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/Kconfig          |   8 +
 drivers/pinctrl/pxa/Makefile         |   2 +
 drivers/pinctrl/pxa/pinctrl-pxa27x.c | 566 +++++++++++++++++++++++++++++++++++
 3 files changed, 576 insertions(+)
 create mode 100644 drivers/pinctrl/pxa/Makefile
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa27x.c

diff --git a/drivers/pinctrl/pxa/Kconfig b/drivers/pinctrl/pxa/Kconfig
index 13e24d7c45c7..990667ff772c 100644
--- a/drivers/pinctrl/pxa/Kconfig
+++ b/drivers/pinctrl/pxa/Kconfig
@@ -6,4 +6,12 @@ config PINCTRL_PXA
 	select PINCONF
 	select GENERIC_PINCONF
 
+config PINCTRL_PXA27X
+	tristate "Marvell PXA27x pin controller driver"
+	select PINCTRL_PXA
+	default y if PXA27x
+	help
+	  This is the pinctrl, pinmux, pinconf driver for the Marvell
+	  PXA2xx block found in the pxa25x and pxa27x platforms.
+
 endif
diff --git a/drivers/pinctrl/pxa/Makefile b/drivers/pinctrl/pxa/Makefile
new file mode 100644
index 000000000000..f1d56af2bfc0
--- /dev/null
+++ b/drivers/pinctrl/pxa/Makefile
@@ -0,0 +1,2 @@
+# Marvell PXA pin control drivers
+obj-$(CONFIG_PINCTRL_PXA27X)	+= pinctrl-pxa2xx.o pinctrl-pxa27x.o
diff --git a/drivers/pinctrl/pxa/pinctrl-pxa27x.c b/drivers/pinctrl/pxa/pinctrl-pxa27x.c
new file mode 100644
index 000000000000..2e2c3709ef05
--- /dev/null
+++ b/drivers/pinctrl/pxa/pinctrl-pxa27x.c
@@ -0,0 +1,566 @@
+/*
+ * Marvell PXA27x family pin control
+ *
+ * Copyright (C) 2015 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-pxa2xx.h"
+
+static const struct pxa_desc_pin pxa27x_pins[] = {
+	PXA_GPIO_ONLY_PIN(PXA_PINCTRL_PIN(0)),
+	PXA_GPIO_ONLY_PIN(PXA_PINCTRL_PIN(1)),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(9),
+		     PXA_FUNCTION(0, 3, "FFCTS"),
+		     PXA_FUNCTION(1, 1, "HZ_CLK"),
+		     PXA_FUNCTION(1, 3, "CHOUT<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(10),
+		     PXA_FUNCTION(0, 1, "FFDCD"),
+		     PXA_FUNCTION(0, 3, "USB_P3_5"),
+		     PXA_FUNCTION(1, 1, "HZ_CLK"),
+		     PXA_FUNCTION(1, 3, "CHOUT<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(11),
+		     PXA_FUNCTION(0, 1, "EXT_SYNC<0>"),
+		     PXA_FUNCTION(0, 2, "SSPRXD2"),
+		     PXA_FUNCTION(0, 3, "USB_P3_1"),
+		     PXA_FUNCTION(1, 1, "CHOUT<0>"),
+		     PXA_FUNCTION(1, 1, "PWM_OUT<2>"),
+		     PXA_FUNCTION(1, 3, "48_MHz")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(12),
+		     PXA_FUNCTION(0, 1, "EXT_SYNC<1>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<7>"),
+		     PXA_FUNCTION(1, 1, "CHOUT<1>"),
+		     PXA_FUNCTION(1, 1, "PWM_OUT<3>"),
+		     PXA_FUNCTION(1, 3, "48_MHz")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(13),
+		     PXA_FUNCTION(0, 1, "CLK_EXT"),
+		     PXA_FUNCTION(0, 2, "KP_DKIN<7>"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<7>"),
+		     PXA_FUNCTION(1, 1, "SSPTXD2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(14),
+		     PXA_FUNCTION(0, 1, "L_VSYNC"),
+		     PXA_FUNCTION(0, 2, "SSPSFRM2"),
+		     PXA_FUNCTION(1, 1, "SSPSFRM2"),
+		     PXA_FUNCTION(1, 3, "UCLK")),
+	PXA_GPIO_ONLY_PIN(PXA_PINCTRL_PIN(15)),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(16),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<5>"),
+		     PXA_FUNCTION(1, 2, "PWM_OUT<0>"),
+		     PXA_FUNCTION(1, 3, "FFTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(17),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<6>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<6>"),
+		     PXA_FUNCTION(1, 2, "PWM_OUT<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(18),
+		     PXA_FUNCTION(0, 1, "RDY")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(19),
+		     PXA_FUNCTION(0, 1, "SSPSCLK2"),
+		     PXA_FUNCTION(0, 3, "FFRXD"),
+		     PXA_FUNCTION(1, 1, "SSPSCLK2"),
+		     PXA_FUNCTION(1, 2, "L_CS"),
+		     PXA_FUNCTION(1, 3, "nURST")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(20),
+		     PXA_FUNCTION(0, 1, "DREQ<0>"),
+		     PXA_FUNCTION(0, 2, "MBREQ"),
+		     PXA_FUNCTION(1, 1, "nSDCS<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(21),
+		     PXA_FUNCTION(1, 1, "nSDCS<3>"),
+		     PXA_FUNCTION(1, 2, "DVAL<0>"),
+		     PXA_FUNCTION(1, 3, "MBGNT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(22),
+		     PXA_FUNCTION(0, 1, "SSPEXTCLK2"),
+		     PXA_FUNCTION(0, 2, "SSPSCLKEN2"),
+		     PXA_FUNCTION(0, 3, "SSPSCLK2"),
+		     PXA_FUNCTION(1, 1, "KP_MKOUT<7>"),
+		     PXA_FUNCTION(1, 2, "SSPSYSCLK2"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(23),
+		     PXA_FUNCTION(0, 2, "SSPSCLK"),
+		     PXA_FUNCTION(1, 1, "CIF_MCLK"),
+		     PXA_FUNCTION(1, 1, "SSPSCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(24),
+		     PXA_FUNCTION(0, 1, "CIF_FV"),
+		     PXA_FUNCTION(0, 2, "SSPSFRM"),
+		     PXA_FUNCTION(1, 1, "CIF_FV"),
+		     PXA_FUNCTION(1, 2, "SSPSFRM")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(25),
+		     PXA_FUNCTION(0, 1, "CIF_LV"),
+		     PXA_FUNCTION(1, 1, "CIF_LV"),
+		     PXA_FUNCTION(1, 2, "SSPTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(26),
+		     PXA_FUNCTION(0, 1, "SSPRXD"),
+		     PXA_FUNCTION(0, 2, "CIF_PCLK"),
+		     PXA_FUNCTION(0, 3, "FFCTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(27),
+		     PXA_FUNCTION(0, 1, "SSPEXTCLK"),
+		     PXA_FUNCTION(0, 2, "SSPSCLKEN"),
+		     PXA_FUNCTION(0, 3, "CIF_DD<0>"),
+		     PXA_FUNCTION(1, 1, "SSPSYSCLK"),
+		     PXA_FUNCTION(1, 3, "FFRTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(28),
+		     PXA_FUNCTION(0, 1, "AC97_BITCLK"),
+		     PXA_FUNCTION(0, 2, "I2S_BITCLK"),
+		     PXA_FUNCTION(0, 3, "SSPSFRM"),
+		     PXA_FUNCTION(1, 1, "I2S_BITCLK"),
+		     PXA_FUNCTION(1, 3, "SSPSFRM")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(29),
+		     PXA_FUNCTION(0, 1, "AC97_SDATA_IN_0"),
+		     PXA_FUNCTION(0, 2, "I2S_SDATA_IN"),
+		     PXA_FUNCTION(0, 3, "SSPSCLK"),
+		     PXA_FUNCTION(1, 1, "SSPRXD2"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(30),
+		     PXA_FUNCTION(1, 1, "I2S_SDATA_OUT"),
+		     PXA_FUNCTION(1, 2, "AC97_SDATA_OUT"),
+		     PXA_FUNCTION(1, 3, "USB_P3_2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(31),
+		     PXA_FUNCTION(1, 1, "I2S_SYNC"),
+		     PXA_FUNCTION(1, 2, "AC97_SYNC"),
+		     PXA_FUNCTION(1, 3, "USB_P3_6")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(32),
+		     PXA_FUNCTION(1, 1, "MSSCLK"),
+		     PXA_FUNCTION(1, 2, "MMCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(33),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "FFDSR"),
+		     PXA_FUNCTION(1, 1, "DVAL<1>"),
+		     PXA_FUNCTION(1, 2, "nCS<5>"),
+		     PXA_FUNCTION(1, 3, "MBGNT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(34),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "KP_MKIN<3>"),
+		     PXA_FUNCTION(0, 3, "SSPSCLK3"),
+		     PXA_FUNCTION(1, 1, "USB_P2_2"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(35),
+		     PXA_FUNCTION(0, 1, "FFCTS"),
+		     PXA_FUNCTION(0, 2, "USB_P2_1"),
+		     PXA_FUNCTION(0, 3, "SSPSFRM3"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<6>"),
+		     PXA_FUNCTION(1, 3, "SSPTXD3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(36),
+		     PXA_FUNCTION(0, 1, "FFDCD"),
+		     PXA_FUNCTION(0, 2, "SSPSCLK2"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<7>"),
+		     PXA_FUNCTION(1, 1, "USB_P2_4"),
+		     PXA_FUNCTION(1, 2, "SSPSCLK2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(37),
+		     PXA_FUNCTION(0, 1, "FFDSR"),
+		     PXA_FUNCTION(0, 2, "SSPSFRM2"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<3>"),
+		     PXA_FUNCTION(1, 1, "USB_P2_8"),
+		     PXA_FUNCTION(1, 2, "SSPSFRM2"),
+		     PXA_FUNCTION(1, 3, "FFTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(38),
+		     PXA_FUNCTION(0, 1, "FFRI"),
+		     PXA_FUNCTION(0, 2, "KP_MKIN<4>"),
+		     PXA_FUNCTION(0, 3, "USB_P2_3"),
+		     PXA_FUNCTION(1, 1, "SSPTXD3"),
+		     PXA_FUNCTION(1, 2, "SSPTXD2"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(39),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<4>"),
+		     PXA_FUNCTION(0, 3, "SSPSFRM3"),
+		     PXA_FUNCTION(1, 1, "USB_P2_6"),
+		     PXA_FUNCTION(1, 2, "FFTXD"),
+		     PXA_FUNCTION(1, 3, "SSPSFRM3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(40),
+		     PXA_FUNCTION(0, 1, "SSPRXD2"),
+		     PXA_FUNCTION(0, 3, "USB_P2_5"),
+		     PXA_FUNCTION(1, 1, "KP_MKOUT<6>"),
+		     PXA_FUNCTION(1, 2, "FFDTR"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(41),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "USB_P2_7"),
+		     PXA_FUNCTION(0, 3, "SSPRXD3"),
+		     PXA_FUNCTION(1, 1, "KP_MKOUT<7>"),
+		     PXA_FUNCTION(1, 2, "FFRTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(42),
+		     PXA_FUNCTION(0, 1, "BTRXD"),
+		     PXA_FUNCTION(0, 2, "ICP_RXD"),
+		     PXA_FUNCTION(1, 3, "CIF_MCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(43),
+		     PXA_FUNCTION(0, 3, "CIF_FV"),
+		     PXA_FUNCTION(1, 1, "ICP_TXD"),
+		     PXA_FUNCTION(1, 2, "BTTXD"),
+		     PXA_FUNCTION(1, 3, "CIF_FV")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(44),
+		     PXA_FUNCTION(0, 1, "BTCTS"),
+		     PXA_FUNCTION(0, 3, "CIF_LV"),
+		     PXA_FUNCTION(1, 3, "CIF_LV")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(45),
+		     PXA_FUNCTION(0, 3, "CIF_PCLK"),
+		     PXA_FUNCTION(1, 1, "AC97_SYSCLK"),
+		     PXA_FUNCTION(1, 2, "BTRTS"),
+		     PXA_FUNCTION(1, 3, "SSPSYSCLK3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(46),
+		     PXA_FUNCTION(0, 1, "ICP_RXD"),
+		     PXA_FUNCTION(0, 2, "STD_RXD"),
+		     PXA_FUNCTION(1, 2, "PWM_OUT<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(47),
+		     PXA_FUNCTION(0, 1, "CIF_DD<0>"),
+		     PXA_FUNCTION(1, 1, "STD_TXD"),
+		     PXA_FUNCTION(1, 2, "ICP_TXD"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(48),
+		     PXA_FUNCTION(0, 1, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 1, "BB_OB_DAT<1>"),
+		     PXA_FUNCTION(1, 2, "nPOE")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(49),
+		     PXA_FUNCTION(1, 2, "nPWE")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(50),
+		     PXA_FUNCTION(0, 1, "CIF_DD<3>"),
+		     PXA_FUNCTION(0, 3, "SSPSCLK2"),
+		     PXA_FUNCTION(1, 1, "BB_OB_DAT<2>"),
+		     PXA_FUNCTION(1, 2, "nPIOR"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(51),
+		     PXA_FUNCTION(0, 1, "CIF_DD<2>"),
+		     PXA_FUNCTION(1, 1, "BB_OB_DAT<3>"),
+		     PXA_FUNCTION(1, 2, "nPIOW")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(52),
+		     PXA_FUNCTION(0, 1, "CIF_DD<4>"),
+		     PXA_FUNCTION(0, 2, "SSPSCLK3"),
+		     PXA_FUNCTION(1, 1, "BB_OB_CLK"),
+		     PXA_FUNCTION(1, 2, "SSPSCLK3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(53),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "USB_P2_3"),
+		     PXA_FUNCTION(1, 1, "BB_OB_STB"),
+		     PXA_FUNCTION(1, 2, "CIF_MCLK"),
+		     PXA_FUNCTION(1, 3, "SSPSYSCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(54),
+		     PXA_FUNCTION(0, 2, "BB_OB_WAIT"),
+		     PXA_FUNCTION(0, 3, "CIF_PCLK"),
+		     PXA_FUNCTION(1, 2, "nPCE<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(55),
+		     PXA_FUNCTION(0, 1, "CIF_DD<1>"),
+		     PXA_FUNCTION(0, 2, "BB_IB_DAT<1>"),
+		     PXA_FUNCTION(1, 2, "nPREG")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(56),
+		     PXA_FUNCTION(0, 1, "nPWAIT"),
+		     PXA_FUNCTION(0, 2, "BB_IB_DAT<2>"),
+		     PXA_FUNCTION(1, 1, "USB_P3_4")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(57),
+		     PXA_FUNCTION(0, 1, "nIOS16"),
+		     PXA_FUNCTION(0, 2, "BB_IB_DAT<3>"),
+		     PXA_FUNCTION(1, 3, "SSPTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(58),
+		     PXA_FUNCTION(0, 2, "LDD<0>"),
+		     PXA_FUNCTION(1, 2, "LDD<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(59),
+		     PXA_FUNCTION(0, 2, "LDD<1>"),
+		     PXA_FUNCTION(1, 2, "LDD<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(60),
+		     PXA_FUNCTION(0, 2, "LDD<2>"),
+		     PXA_FUNCTION(1, 2, "LDD<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(61),
+		     PXA_FUNCTION(0, 2, "LDD<3>"),
+		     PXA_FUNCTION(1, 2, "LDD<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(62),
+		     PXA_FUNCTION(0, 2, "LDD<4>"),
+		     PXA_FUNCTION(1, 2, "LDD<4>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(63),
+		     PXA_FUNCTION(0, 2, "LDD<5>"),
+		     PXA_FUNCTION(1, 2, "LDD<5>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(64),
+		     PXA_FUNCTION(0, 2, "LDD<6>"),
+		     PXA_FUNCTION(1, 2, "LDD<6>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(65),
+		     PXA_FUNCTION(0, 2, "LDD<7>"),
+		     PXA_FUNCTION(1, 2, "LDD<7>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(66),
+		     PXA_FUNCTION(0, 2, "LDD<8>"),
+		     PXA_FUNCTION(1, 2, "LDD<8>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(67),
+		     PXA_FUNCTION(0, 2, "LDD<9>"),
+		     PXA_FUNCTION(1, 2, "LDD<9>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(68),
+		     PXA_FUNCTION(0, 2, "LDD<10>"),
+		     PXA_FUNCTION(1, 2, "LDD<10>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(69),
+		     PXA_FUNCTION(0, 2, "LDD<11>"),
+		     PXA_FUNCTION(1, 2, "LDD<11>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(70),
+		     PXA_FUNCTION(0, 2, "LDD<12>"),
+		     PXA_FUNCTION(1, 2, "LDD<12>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(71),
+		     PXA_FUNCTION(0, 2, "LDD<13>"),
+		     PXA_FUNCTION(1, 2, "LDD<13>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(72),
+		     PXA_FUNCTION(0, 2, "LDD<14>"),
+		     PXA_FUNCTION(1, 2, "LDD<14>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(73),
+		     PXA_FUNCTION(0, 2, "LDD<15>"),
+		     PXA_FUNCTION(1, 2, "LDD<15>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(74),
+		     PXA_FUNCTION(1, 2, "L_FCLK_RD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(75),
+		     PXA_FUNCTION(1, 2, "L_LCLK_A0")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(76),
+		     PXA_FUNCTION(1, 2, "L_PCLK_WR")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(77),
+		     PXA_FUNCTION(1, 2, "L_BIAS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(78),
+		     PXA_FUNCTION(1, 1, "nPCE<2>"),
+		     PXA_FUNCTION(1, 2, "nCS<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(79),
+		     PXA_FUNCTION(1, 1, "PSKTSEL"),
+		     PXA_FUNCTION(1, 2, "nCS<3>"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(80),
+		     PXA_FUNCTION(0, 1, "DREQ<1>"),
+		     PXA_FUNCTION(0, 2, "MBREQ"),
+		     PXA_FUNCTION(1, 2, "nCS<4>"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(81),
+		     PXA_FUNCTION(0, 2, "CIF_DD<0>"),
+		     PXA_FUNCTION(1, 1, "SSPTXD3"),
+		     PXA_FUNCTION(1, 2, "BB_OB_DAT<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(82),
+		     PXA_FUNCTION(0, 1, "SSPRXD3"),
+		     PXA_FUNCTION(0, 2, "BB_IB_DAT<0>"),
+		     PXA_FUNCTION(0, 3, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 3, "FFDTR")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(83),
+		     PXA_FUNCTION(0, 1, "SSPSFRM3"),
+		     PXA_FUNCTION(0, 2, "BB_IB_CLK"),
+		     PXA_FUNCTION(0, 3, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 1, "SSPSFRM3"),
+		     PXA_FUNCTION(1, 2, "FFTXD"),
+		     PXA_FUNCTION(1, 3, "FFRTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(84),
+		     PXA_FUNCTION(0, 1, "SSPCLK3"),
+		     PXA_FUNCTION(0, 2, "BB_IB_STB"),
+		     PXA_FUNCTION(0, 3, "CIF_FV"),
+		     PXA_FUNCTION(1, 1, "SSPCLK3"),
+		     PXA_FUNCTION(1, 3, "CIF_FV")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(85),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "DREQ<2>"),
+		     PXA_FUNCTION(0, 3, "CIF_LV"),
+		     PXA_FUNCTION(1, 1, "nPCE<1>"),
+		     PXA_FUNCTION(1, 2, "BB_IB_WAIT"),
+		     PXA_FUNCTION(1, 3, "CIF_LV")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(86),
+		     PXA_FUNCTION(0, 1, "SSPRXD2"),
+		     PXA_FUNCTION(0, 2, "LDD<16>"),
+		     PXA_FUNCTION(0, 3, "USB_P3_5"),
+		     PXA_FUNCTION(1, 1, "nPCE<1>"),
+		     PXA_FUNCTION(1, 2, "LDD<16>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(87),
+		     PXA_FUNCTION(0, 1, "nPCE<2>"),
+		     PXA_FUNCTION(0, 2, "LDD<17>"),
+		     PXA_FUNCTION(0, 3, "USB_P3_1"),
+		     PXA_FUNCTION(1, 1, "SSPTXD2"),
+		     PXA_FUNCTION(1, 2, "LDD<17>"),
+		     PXA_FUNCTION(1, 3, "SSPSFRM2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(88),
+		     PXA_FUNCTION(0, 1, "USBHPWR<1>"),
+		     PXA_FUNCTION(0, 2, "SSPRXD2"),
+		     PXA_FUNCTION(0, 3, "SSPSFRM2"),
+		     PXA_FUNCTION(1, 2, "SSPTXD2"),
+		     PXA_FUNCTION(1, 3, "SSPSFRM2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(89),
+		     PXA_FUNCTION(0, 1, "SSPRXD3"),
+		     PXA_FUNCTION(0, 3, "FFRI"),
+		     PXA_FUNCTION(1, 1, "AC97_SYSCLK"),
+		     PXA_FUNCTION(1, 2, "USBHPEN<1>"),
+		     PXA_FUNCTION(1, 3, "SSPTXD2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(90),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<5>"),
+		     PXA_FUNCTION(0, 3, "USB_P3_5"),
+		     PXA_FUNCTION(1, 1, "CIF_DD<4>"),
+		     PXA_FUNCTION(1, 2, "nURST")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(91),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<6>"),
+		     PXA_FUNCTION(0, 3, "USB_P3_1"),
+		     PXA_FUNCTION(1, 1, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 2, "UCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(92),
+		     PXA_FUNCTION(0, 1, "MMDAT<0>"),
+		     PXA_FUNCTION(1, 1, "MMDAT<0>"),
+		     PXA_FUNCTION(1, 2, "MSBS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(93),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<0>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<6>"),
+		     PXA_FUNCTION(1, 1, "AC97_SDATA_OUT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(94),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<1>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 1, "AC97_SYNC")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(95),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<2>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<4>"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<6>"),
+		     PXA_FUNCTION(1, 1, "AC97_RESET_n")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(96),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<3>"),
+		     PXA_FUNCTION(0, 2, "MBREQ"),
+		     PXA_FUNCTION(0, 3, "FFRXD"),
+		     PXA_FUNCTION(1, 2, "DVAL<1>"),
+		     PXA_FUNCTION(1, 3, "KP_MKOUT<6>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(97),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<4>"),
+		     PXA_FUNCTION(0, 2, "DREQ<1>"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<3>"),
+		     PXA_FUNCTION(1, 2, "MBGNT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(98),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<5>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<0>"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<4>"),
+		     PXA_FUNCTION(1, 1, "AC97_SYSCLK"),
+		     PXA_FUNCTION(1, 3, "FFRTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(99),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<6>"),
+		     PXA_FUNCTION(0, 2, "AC97_SDATA_IN_1"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<5>"),
+		     PXA_FUNCTION(1, 3, "FFTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(100),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<0>"),
+		     PXA_FUNCTION(0, 2, "DREQ<2>"),
+		     PXA_FUNCTION(0, 3, "FFCTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(101),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(102),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<2>"),
+		     PXA_FUNCTION(0, 3, "FFRXD"),
+		     PXA_FUNCTION(1, 1, "nPCE<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(103),
+		     PXA_FUNCTION(0, 1, "CIF_DD<3>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(104),
+		     PXA_FUNCTION(0, 1, "CIF_DD<2>"),
+		     PXA_FUNCTION(1, 1, "PSKTSEL"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(105),
+		     PXA_FUNCTION(0, 1, "CIF_DD<1>"),
+		     PXA_FUNCTION(1, 1, "nPCE<2>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(106),
+		     PXA_FUNCTION(0, 1, "CIF_DD<9>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(107),
+		     PXA_FUNCTION(0, 1, "CIF_DD<8>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<4>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(108),
+		     PXA_FUNCTION(0, 1, "CIF_DD<7>"),
+		     PXA_FUNCTION(1, 1, "CHOUT<0>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<5>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(109),
+		     PXA_FUNCTION(0, 1, "MMDAT<1>"),
+		     PXA_FUNCTION(0, 2, "MSSDIO"),
+		     PXA_FUNCTION(1, 1, "MMDAT<1>"),
+		     PXA_FUNCTION(1, 2, "MSSDIO")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(110),
+		     PXA_FUNCTION(0, 1, "MMDAT<2>"),
+		     PXA_FUNCTION(1, 1, "MMDAT<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(111),
+		     PXA_FUNCTION(0, 1, "MMDAT<3>"),
+		     PXA_FUNCTION(1, 1, "MMDAT<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(112),
+		     PXA_FUNCTION(0, 1, "MMCMD"),
+		     PXA_FUNCTION(0, 2, "nMSINS"),
+		     PXA_FUNCTION(1, 1, "MMCMD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(113),
+		     PXA_FUNCTION(0, 3, "USB_P3_3"),
+		     PXA_FUNCTION(1, 1, "I2S_SYSCLK"),
+		     PXA_FUNCTION(1, 2, "AC97_RESET_n")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(114),
+		     PXA_FUNCTION(0, 1, "CIF_DD<1>"),
+		     PXA_FUNCTION(1, 1, "UEN"),
+		     PXA_FUNCTION(1, 2, "UVS0")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(115),
+		     PXA_FUNCTION(0, 1, "DREQ<0>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<3>"),
+		     PXA_FUNCTION(0, 3, "MBREQ"),
+		     PXA_FUNCTION(1, 1, "UEN"),
+		     PXA_FUNCTION(1, 2, "nUVS1"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(116),
+		     PXA_FUNCTION(0, 1, "CIF_DD<2>"),
+		     PXA_FUNCTION(0, 2, "AC97_SDATA_IN_0"),
+		     PXA_FUNCTION(0, 3, "UDET"),
+		     PXA_FUNCTION(1, 1, "DVAL<0>"),
+		     PXA_FUNCTION(1, 2, "nUVS2"),
+		     PXA_FUNCTION(1, 3, "MBGNT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(117),
+		     PXA_FUNCTION(0, 1, "SCL"),
+		     PXA_FUNCTION(1, 1, "SCL")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(118),
+		     PXA_FUNCTION(0, 1, "SDA"),
+		     PXA_FUNCTION(1, 1, "SDA")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(119),
+		     PXA_FUNCTION(0, 1, "USBHPWR<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(120),
+		     PXA_FUNCTION(1, 2, "USBHPEN<2>")),
+};
+
+static int pxa27x_pinctrl_probe(struct platform_device *pdev)
+{
+	int ret, i;
+	void __iomem *base_af[8];
+	void __iomem *base_dir[4];
+	void __iomem *base_sleep[4];
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base_af[0] = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base_af[0]))
+		return PTR_ERR(base_af[0]);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base_dir[0] = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base_dir[0]))
+		return PTR_ERR(base_dir[0]);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	base_dir[3] = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base_dir[3]))
+		return PTR_ERR(base_dir[3]);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+	base_sleep[0] = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base_sleep[0]))
+		return PTR_ERR(base_sleep[0]);
+
+	for (i = 0; i < ARRAY_SIZE(base_af); i++)
+		base_af[i] = base_af[0] + sizeof(base_af[0]) * i;
+	for (i = 0; i < 3; i++)
+		base_dir[i] = base_dir[0] + sizeof(base_dir[0]) * i;
+	for (i = 0; i < ARRAY_SIZE(base_sleep); i++)
+		base_sleep[i] = base_sleep[0] + sizeof(base_af[0]) * i;
+
+	ret = pxa2xx_pinctrl_init(pdev, pxa27x_pins, ARRAY_SIZE(pxa27x_pins),
+				  base_af, base_dir, base_sleep);
+	return ret;
+}
+
+static const struct of_device_id pxa27x_pinctrl_match[] = {
+	{ .compatible = "marvell,pxa27x-pinctrl", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, pxa27x_pinctrl_match);
+
+static struct platform_driver pxa27x_pinctrl_driver = {
+	.probe	= pxa27x_pinctrl_probe,
+	.driver	= {
+		.name		= "pxa27x-pinctrl",
+		.of_match_table	= pxa27x_pinctrl_match,
+	},
+};
+module_platform_driver(pxa27x_pinctrl_driver);
+
+MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
+MODULE_DESCRIPTION("Marvell PXA27x pinctrl driver");
+MODULE_LICENSE("GPL v2");
-- 
2.1.4

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

* [PATCH 5/6] pinctrl: pxa: add pxa27x architecture
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add the pxa27x architecture, which is a pxa2xx with 128 pins. The
registers spacing, and pins logic is common to pxa2xx, only the pins and
their alternate function are specific to pxa27x.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/pxa/Kconfig          |   8 +
 drivers/pinctrl/pxa/Makefile         |   2 +
 drivers/pinctrl/pxa/pinctrl-pxa27x.c | 566 +++++++++++++++++++++++++++++++++++
 3 files changed, 576 insertions(+)
 create mode 100644 drivers/pinctrl/pxa/Makefile
 create mode 100644 drivers/pinctrl/pxa/pinctrl-pxa27x.c

diff --git a/drivers/pinctrl/pxa/Kconfig b/drivers/pinctrl/pxa/Kconfig
index 13e24d7c45c7..990667ff772c 100644
--- a/drivers/pinctrl/pxa/Kconfig
+++ b/drivers/pinctrl/pxa/Kconfig
@@ -6,4 +6,12 @@ config PINCTRL_PXA
 	select PINCONF
 	select GENERIC_PINCONF
 
+config PINCTRL_PXA27X
+	tristate "Marvell PXA27x pin controller driver"
+	select PINCTRL_PXA
+	default y if PXA27x
+	help
+	  This is the pinctrl, pinmux, pinconf driver for the Marvell
+	  PXA2xx block found in the pxa25x and pxa27x platforms.
+
 endif
diff --git a/drivers/pinctrl/pxa/Makefile b/drivers/pinctrl/pxa/Makefile
new file mode 100644
index 000000000000..f1d56af2bfc0
--- /dev/null
+++ b/drivers/pinctrl/pxa/Makefile
@@ -0,0 +1,2 @@
+# Marvell PXA pin control drivers
+obj-$(CONFIG_PINCTRL_PXA27X)	+= pinctrl-pxa2xx.o pinctrl-pxa27x.o
diff --git a/drivers/pinctrl/pxa/pinctrl-pxa27x.c b/drivers/pinctrl/pxa/pinctrl-pxa27x.c
new file mode 100644
index 000000000000..2e2c3709ef05
--- /dev/null
+++ b/drivers/pinctrl/pxa/pinctrl-pxa27x.c
@@ -0,0 +1,566 @@
+/*
+ * Marvell PXA27x family pin control
+ *
+ * Copyright (C) 2015 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-pxa2xx.h"
+
+static const struct pxa_desc_pin pxa27x_pins[] = {
+	PXA_GPIO_ONLY_PIN(PXA_PINCTRL_PIN(0)),
+	PXA_GPIO_ONLY_PIN(PXA_PINCTRL_PIN(1)),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(9),
+		     PXA_FUNCTION(0, 3, "FFCTS"),
+		     PXA_FUNCTION(1, 1, "HZ_CLK"),
+		     PXA_FUNCTION(1, 3, "CHOUT<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(10),
+		     PXA_FUNCTION(0, 1, "FFDCD"),
+		     PXA_FUNCTION(0, 3, "USB_P3_5"),
+		     PXA_FUNCTION(1, 1, "HZ_CLK"),
+		     PXA_FUNCTION(1, 3, "CHOUT<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(11),
+		     PXA_FUNCTION(0, 1, "EXT_SYNC<0>"),
+		     PXA_FUNCTION(0, 2, "SSPRXD2"),
+		     PXA_FUNCTION(0, 3, "USB_P3_1"),
+		     PXA_FUNCTION(1, 1, "CHOUT<0>"),
+		     PXA_FUNCTION(1, 1, "PWM_OUT<2>"),
+		     PXA_FUNCTION(1, 3, "48_MHz")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(12),
+		     PXA_FUNCTION(0, 1, "EXT_SYNC<1>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<7>"),
+		     PXA_FUNCTION(1, 1, "CHOUT<1>"),
+		     PXA_FUNCTION(1, 1, "PWM_OUT<3>"),
+		     PXA_FUNCTION(1, 3, "48_MHz")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(13),
+		     PXA_FUNCTION(0, 1, "CLK_EXT"),
+		     PXA_FUNCTION(0, 2, "KP_DKIN<7>"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<7>"),
+		     PXA_FUNCTION(1, 1, "SSPTXD2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(14),
+		     PXA_FUNCTION(0, 1, "L_VSYNC"),
+		     PXA_FUNCTION(0, 2, "SSPSFRM2"),
+		     PXA_FUNCTION(1, 1, "SSPSFRM2"),
+		     PXA_FUNCTION(1, 3, "UCLK")),
+	PXA_GPIO_ONLY_PIN(PXA_PINCTRL_PIN(15)),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(16),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<5>"),
+		     PXA_FUNCTION(1, 2, "PWM_OUT<0>"),
+		     PXA_FUNCTION(1, 3, "FFTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(17),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<6>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<6>"),
+		     PXA_FUNCTION(1, 2, "PWM_OUT<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(18),
+		     PXA_FUNCTION(0, 1, "RDY")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(19),
+		     PXA_FUNCTION(0, 1, "SSPSCLK2"),
+		     PXA_FUNCTION(0, 3, "FFRXD"),
+		     PXA_FUNCTION(1, 1, "SSPSCLK2"),
+		     PXA_FUNCTION(1, 2, "L_CS"),
+		     PXA_FUNCTION(1, 3, "nURST")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(20),
+		     PXA_FUNCTION(0, 1, "DREQ<0>"),
+		     PXA_FUNCTION(0, 2, "MBREQ"),
+		     PXA_FUNCTION(1, 1, "nSDCS<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(21),
+		     PXA_FUNCTION(1, 1, "nSDCS<3>"),
+		     PXA_FUNCTION(1, 2, "DVAL<0>"),
+		     PXA_FUNCTION(1, 3, "MBGNT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(22),
+		     PXA_FUNCTION(0, 1, "SSPEXTCLK2"),
+		     PXA_FUNCTION(0, 2, "SSPSCLKEN2"),
+		     PXA_FUNCTION(0, 3, "SSPSCLK2"),
+		     PXA_FUNCTION(1, 1, "KP_MKOUT<7>"),
+		     PXA_FUNCTION(1, 2, "SSPSYSCLK2"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(23),
+		     PXA_FUNCTION(0, 2, "SSPSCLK"),
+		     PXA_FUNCTION(1, 1, "CIF_MCLK"),
+		     PXA_FUNCTION(1, 1, "SSPSCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(24),
+		     PXA_FUNCTION(0, 1, "CIF_FV"),
+		     PXA_FUNCTION(0, 2, "SSPSFRM"),
+		     PXA_FUNCTION(1, 1, "CIF_FV"),
+		     PXA_FUNCTION(1, 2, "SSPSFRM")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(25),
+		     PXA_FUNCTION(0, 1, "CIF_LV"),
+		     PXA_FUNCTION(1, 1, "CIF_LV"),
+		     PXA_FUNCTION(1, 2, "SSPTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(26),
+		     PXA_FUNCTION(0, 1, "SSPRXD"),
+		     PXA_FUNCTION(0, 2, "CIF_PCLK"),
+		     PXA_FUNCTION(0, 3, "FFCTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(27),
+		     PXA_FUNCTION(0, 1, "SSPEXTCLK"),
+		     PXA_FUNCTION(0, 2, "SSPSCLKEN"),
+		     PXA_FUNCTION(0, 3, "CIF_DD<0>"),
+		     PXA_FUNCTION(1, 1, "SSPSYSCLK"),
+		     PXA_FUNCTION(1, 3, "FFRTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(28),
+		     PXA_FUNCTION(0, 1, "AC97_BITCLK"),
+		     PXA_FUNCTION(0, 2, "I2S_BITCLK"),
+		     PXA_FUNCTION(0, 3, "SSPSFRM"),
+		     PXA_FUNCTION(1, 1, "I2S_BITCLK"),
+		     PXA_FUNCTION(1, 3, "SSPSFRM")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(29),
+		     PXA_FUNCTION(0, 1, "AC97_SDATA_IN_0"),
+		     PXA_FUNCTION(0, 2, "I2S_SDATA_IN"),
+		     PXA_FUNCTION(0, 3, "SSPSCLK"),
+		     PXA_FUNCTION(1, 1, "SSPRXD2"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(30),
+		     PXA_FUNCTION(1, 1, "I2S_SDATA_OUT"),
+		     PXA_FUNCTION(1, 2, "AC97_SDATA_OUT"),
+		     PXA_FUNCTION(1, 3, "USB_P3_2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(31),
+		     PXA_FUNCTION(1, 1, "I2S_SYNC"),
+		     PXA_FUNCTION(1, 2, "AC97_SYNC"),
+		     PXA_FUNCTION(1, 3, "USB_P3_6")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(32),
+		     PXA_FUNCTION(1, 1, "MSSCLK"),
+		     PXA_FUNCTION(1, 2, "MMCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(33),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "FFDSR"),
+		     PXA_FUNCTION(1, 1, "DVAL<1>"),
+		     PXA_FUNCTION(1, 2, "nCS<5>"),
+		     PXA_FUNCTION(1, 3, "MBGNT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(34),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "KP_MKIN<3>"),
+		     PXA_FUNCTION(0, 3, "SSPSCLK3"),
+		     PXA_FUNCTION(1, 1, "USB_P2_2"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(35),
+		     PXA_FUNCTION(0, 1, "FFCTS"),
+		     PXA_FUNCTION(0, 2, "USB_P2_1"),
+		     PXA_FUNCTION(0, 3, "SSPSFRM3"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<6>"),
+		     PXA_FUNCTION(1, 3, "SSPTXD3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(36),
+		     PXA_FUNCTION(0, 1, "FFDCD"),
+		     PXA_FUNCTION(0, 2, "SSPSCLK2"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<7>"),
+		     PXA_FUNCTION(1, 1, "USB_P2_4"),
+		     PXA_FUNCTION(1, 2, "SSPSCLK2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(37),
+		     PXA_FUNCTION(0, 1, "FFDSR"),
+		     PXA_FUNCTION(0, 2, "SSPSFRM2"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<3>"),
+		     PXA_FUNCTION(1, 1, "USB_P2_8"),
+		     PXA_FUNCTION(1, 2, "SSPSFRM2"),
+		     PXA_FUNCTION(1, 3, "FFTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(38),
+		     PXA_FUNCTION(0, 1, "FFRI"),
+		     PXA_FUNCTION(0, 2, "KP_MKIN<4>"),
+		     PXA_FUNCTION(0, 3, "USB_P2_3"),
+		     PXA_FUNCTION(1, 1, "SSPTXD3"),
+		     PXA_FUNCTION(1, 2, "SSPTXD2"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(39),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<4>"),
+		     PXA_FUNCTION(0, 3, "SSPSFRM3"),
+		     PXA_FUNCTION(1, 1, "USB_P2_6"),
+		     PXA_FUNCTION(1, 2, "FFTXD"),
+		     PXA_FUNCTION(1, 3, "SSPSFRM3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(40),
+		     PXA_FUNCTION(0, 1, "SSPRXD2"),
+		     PXA_FUNCTION(0, 3, "USB_P2_5"),
+		     PXA_FUNCTION(1, 1, "KP_MKOUT<6>"),
+		     PXA_FUNCTION(1, 2, "FFDTR"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(41),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "USB_P2_7"),
+		     PXA_FUNCTION(0, 3, "SSPRXD3"),
+		     PXA_FUNCTION(1, 1, "KP_MKOUT<7>"),
+		     PXA_FUNCTION(1, 2, "FFRTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(42),
+		     PXA_FUNCTION(0, 1, "BTRXD"),
+		     PXA_FUNCTION(0, 2, "ICP_RXD"),
+		     PXA_FUNCTION(1, 3, "CIF_MCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(43),
+		     PXA_FUNCTION(0, 3, "CIF_FV"),
+		     PXA_FUNCTION(1, 1, "ICP_TXD"),
+		     PXA_FUNCTION(1, 2, "BTTXD"),
+		     PXA_FUNCTION(1, 3, "CIF_FV")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(44),
+		     PXA_FUNCTION(0, 1, "BTCTS"),
+		     PXA_FUNCTION(0, 3, "CIF_LV"),
+		     PXA_FUNCTION(1, 3, "CIF_LV")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(45),
+		     PXA_FUNCTION(0, 3, "CIF_PCLK"),
+		     PXA_FUNCTION(1, 1, "AC97_SYSCLK"),
+		     PXA_FUNCTION(1, 2, "BTRTS"),
+		     PXA_FUNCTION(1, 3, "SSPSYSCLK3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(46),
+		     PXA_FUNCTION(0, 1, "ICP_RXD"),
+		     PXA_FUNCTION(0, 2, "STD_RXD"),
+		     PXA_FUNCTION(1, 2, "PWM_OUT<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(47),
+		     PXA_FUNCTION(0, 1, "CIF_DD<0>"),
+		     PXA_FUNCTION(1, 1, "STD_TXD"),
+		     PXA_FUNCTION(1, 2, "ICP_TXD"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(48),
+		     PXA_FUNCTION(0, 1, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 1, "BB_OB_DAT<1>"),
+		     PXA_FUNCTION(1, 2, "nPOE")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(49),
+		     PXA_FUNCTION(1, 2, "nPWE")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(50),
+		     PXA_FUNCTION(0, 1, "CIF_DD<3>"),
+		     PXA_FUNCTION(0, 3, "SSPSCLK2"),
+		     PXA_FUNCTION(1, 1, "BB_OB_DAT<2>"),
+		     PXA_FUNCTION(1, 2, "nPIOR"),
+		     PXA_FUNCTION(1, 3, "SSPSCLK2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(51),
+		     PXA_FUNCTION(0, 1, "CIF_DD<2>"),
+		     PXA_FUNCTION(1, 1, "BB_OB_DAT<3>"),
+		     PXA_FUNCTION(1, 2, "nPIOW")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(52),
+		     PXA_FUNCTION(0, 1, "CIF_DD<4>"),
+		     PXA_FUNCTION(0, 2, "SSPSCLK3"),
+		     PXA_FUNCTION(1, 1, "BB_OB_CLK"),
+		     PXA_FUNCTION(1, 2, "SSPSCLK3")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(53),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "USB_P2_3"),
+		     PXA_FUNCTION(1, 1, "BB_OB_STB"),
+		     PXA_FUNCTION(1, 2, "CIF_MCLK"),
+		     PXA_FUNCTION(1, 3, "SSPSYSCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(54),
+		     PXA_FUNCTION(0, 2, "BB_OB_WAIT"),
+		     PXA_FUNCTION(0, 3, "CIF_PCLK"),
+		     PXA_FUNCTION(1, 2, "nPCE<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(55),
+		     PXA_FUNCTION(0, 1, "CIF_DD<1>"),
+		     PXA_FUNCTION(0, 2, "BB_IB_DAT<1>"),
+		     PXA_FUNCTION(1, 2, "nPREG")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(56),
+		     PXA_FUNCTION(0, 1, "nPWAIT"),
+		     PXA_FUNCTION(0, 2, "BB_IB_DAT<2>"),
+		     PXA_FUNCTION(1, 1, "USB_P3_4")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(57),
+		     PXA_FUNCTION(0, 1, "nIOS16"),
+		     PXA_FUNCTION(0, 2, "BB_IB_DAT<3>"),
+		     PXA_FUNCTION(1, 3, "SSPTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(58),
+		     PXA_FUNCTION(0, 2, "LDD<0>"),
+		     PXA_FUNCTION(1, 2, "LDD<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(59),
+		     PXA_FUNCTION(0, 2, "LDD<1>"),
+		     PXA_FUNCTION(1, 2, "LDD<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(60),
+		     PXA_FUNCTION(0, 2, "LDD<2>"),
+		     PXA_FUNCTION(1, 2, "LDD<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(61),
+		     PXA_FUNCTION(0, 2, "LDD<3>"),
+		     PXA_FUNCTION(1, 2, "LDD<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(62),
+		     PXA_FUNCTION(0, 2, "LDD<4>"),
+		     PXA_FUNCTION(1, 2, "LDD<4>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(63),
+		     PXA_FUNCTION(0, 2, "LDD<5>"),
+		     PXA_FUNCTION(1, 2, "LDD<5>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(64),
+		     PXA_FUNCTION(0, 2, "LDD<6>"),
+		     PXA_FUNCTION(1, 2, "LDD<6>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(65),
+		     PXA_FUNCTION(0, 2, "LDD<7>"),
+		     PXA_FUNCTION(1, 2, "LDD<7>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(66),
+		     PXA_FUNCTION(0, 2, "LDD<8>"),
+		     PXA_FUNCTION(1, 2, "LDD<8>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(67),
+		     PXA_FUNCTION(0, 2, "LDD<9>"),
+		     PXA_FUNCTION(1, 2, "LDD<9>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(68),
+		     PXA_FUNCTION(0, 2, "LDD<10>"),
+		     PXA_FUNCTION(1, 2, "LDD<10>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(69),
+		     PXA_FUNCTION(0, 2, "LDD<11>"),
+		     PXA_FUNCTION(1, 2, "LDD<11>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(70),
+		     PXA_FUNCTION(0, 2, "LDD<12>"),
+		     PXA_FUNCTION(1, 2, "LDD<12>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(71),
+		     PXA_FUNCTION(0, 2, "LDD<13>"),
+		     PXA_FUNCTION(1, 2, "LDD<13>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(72),
+		     PXA_FUNCTION(0, 2, "LDD<14>"),
+		     PXA_FUNCTION(1, 2, "LDD<14>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(73),
+		     PXA_FUNCTION(0, 2, "LDD<15>"),
+		     PXA_FUNCTION(1, 2, "LDD<15>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(74),
+		     PXA_FUNCTION(1, 2, "L_FCLK_RD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(75),
+		     PXA_FUNCTION(1, 2, "L_LCLK_A0")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(76),
+		     PXA_FUNCTION(1, 2, "L_PCLK_WR")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(77),
+		     PXA_FUNCTION(1, 2, "L_BIAS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(78),
+		     PXA_FUNCTION(1, 1, "nPCE<2>"),
+		     PXA_FUNCTION(1, 2, "nCS<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(79),
+		     PXA_FUNCTION(1, 1, "PSKTSEL"),
+		     PXA_FUNCTION(1, 2, "nCS<3>"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(80),
+		     PXA_FUNCTION(0, 1, "DREQ<1>"),
+		     PXA_FUNCTION(0, 2, "MBREQ"),
+		     PXA_FUNCTION(1, 2, "nCS<4>"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(81),
+		     PXA_FUNCTION(0, 2, "CIF_DD<0>"),
+		     PXA_FUNCTION(1, 1, "SSPTXD3"),
+		     PXA_FUNCTION(1, 2, "BB_OB_DAT<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(82),
+		     PXA_FUNCTION(0, 1, "SSPRXD3"),
+		     PXA_FUNCTION(0, 2, "BB_IB_DAT<0>"),
+		     PXA_FUNCTION(0, 3, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 3, "FFDTR")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(83),
+		     PXA_FUNCTION(0, 1, "SSPSFRM3"),
+		     PXA_FUNCTION(0, 2, "BB_IB_CLK"),
+		     PXA_FUNCTION(0, 3, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 1, "SSPSFRM3"),
+		     PXA_FUNCTION(1, 2, "FFTXD"),
+		     PXA_FUNCTION(1, 3, "FFRTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(84),
+		     PXA_FUNCTION(0, 1, "SSPCLK3"),
+		     PXA_FUNCTION(0, 2, "BB_IB_STB"),
+		     PXA_FUNCTION(0, 3, "CIF_FV"),
+		     PXA_FUNCTION(1, 1, "SSPCLK3"),
+		     PXA_FUNCTION(1, 3, "CIF_FV")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(85),
+		     PXA_FUNCTION(0, 1, "FFRXD"),
+		     PXA_FUNCTION(0, 2, "DREQ<2>"),
+		     PXA_FUNCTION(0, 3, "CIF_LV"),
+		     PXA_FUNCTION(1, 1, "nPCE<1>"),
+		     PXA_FUNCTION(1, 2, "BB_IB_WAIT"),
+		     PXA_FUNCTION(1, 3, "CIF_LV")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(86),
+		     PXA_FUNCTION(0, 1, "SSPRXD2"),
+		     PXA_FUNCTION(0, 2, "LDD<16>"),
+		     PXA_FUNCTION(0, 3, "USB_P3_5"),
+		     PXA_FUNCTION(1, 1, "nPCE<1>"),
+		     PXA_FUNCTION(1, 2, "LDD<16>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(87),
+		     PXA_FUNCTION(0, 1, "nPCE<2>"),
+		     PXA_FUNCTION(0, 2, "LDD<17>"),
+		     PXA_FUNCTION(0, 3, "USB_P3_1"),
+		     PXA_FUNCTION(1, 1, "SSPTXD2"),
+		     PXA_FUNCTION(1, 2, "LDD<17>"),
+		     PXA_FUNCTION(1, 3, "SSPSFRM2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(88),
+		     PXA_FUNCTION(0, 1, "USBHPWR<1>"),
+		     PXA_FUNCTION(0, 2, "SSPRXD2"),
+		     PXA_FUNCTION(0, 3, "SSPSFRM2"),
+		     PXA_FUNCTION(1, 2, "SSPTXD2"),
+		     PXA_FUNCTION(1, 3, "SSPSFRM2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(89),
+		     PXA_FUNCTION(0, 1, "SSPRXD3"),
+		     PXA_FUNCTION(0, 3, "FFRI"),
+		     PXA_FUNCTION(1, 1, "AC97_SYSCLK"),
+		     PXA_FUNCTION(1, 2, "USBHPEN<1>"),
+		     PXA_FUNCTION(1, 3, "SSPTXD2")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(90),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<5>"),
+		     PXA_FUNCTION(0, 3, "USB_P3_5"),
+		     PXA_FUNCTION(1, 1, "CIF_DD<4>"),
+		     PXA_FUNCTION(1, 2, "nURST")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(91),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<6>"),
+		     PXA_FUNCTION(0, 3, "USB_P3_1"),
+		     PXA_FUNCTION(1, 1, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 2, "UCLK")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(92),
+		     PXA_FUNCTION(0, 1, "MMDAT<0>"),
+		     PXA_FUNCTION(1, 1, "MMDAT<0>"),
+		     PXA_FUNCTION(1, 2, "MSBS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(93),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<0>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<6>"),
+		     PXA_FUNCTION(1, 1, "AC97_SDATA_OUT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(94),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<1>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<5>"),
+		     PXA_FUNCTION(1, 1, "AC97_SYNC")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(95),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<2>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<4>"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<6>"),
+		     PXA_FUNCTION(1, 1, "AC97_RESET_n")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(96),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<3>"),
+		     PXA_FUNCTION(0, 2, "MBREQ"),
+		     PXA_FUNCTION(0, 3, "FFRXD"),
+		     PXA_FUNCTION(1, 2, "DVAL<1>"),
+		     PXA_FUNCTION(1, 3, "KP_MKOUT<6>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(97),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<4>"),
+		     PXA_FUNCTION(0, 2, "DREQ<1>"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<3>"),
+		     PXA_FUNCTION(1, 2, "MBGNT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(98),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<5>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<0>"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<4>"),
+		     PXA_FUNCTION(1, 1, "AC97_SYSCLK"),
+		     PXA_FUNCTION(1, 3, "FFRTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(99),
+		     PXA_FUNCTION(0, 1, "KP_DKIN<6>"),
+		     PXA_FUNCTION(0, 2, "AC97_SDATA_IN_1"),
+		     PXA_FUNCTION(0, 3, "KP_MKIN<5>"),
+		     PXA_FUNCTION(1, 3, "FFTXD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(100),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<0>"),
+		     PXA_FUNCTION(0, 2, "DREQ<2>"),
+		     PXA_FUNCTION(0, 3, "FFCTS")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(101),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(102),
+		     PXA_FUNCTION(0, 1, "KP_MKIN<2>"),
+		     PXA_FUNCTION(0, 3, "FFRXD"),
+		     PXA_FUNCTION(1, 1, "nPCE<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(103),
+		     PXA_FUNCTION(0, 1, "CIF_DD<3>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<0>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(104),
+		     PXA_FUNCTION(0, 1, "CIF_DD<2>"),
+		     PXA_FUNCTION(1, 1, "PSKTSEL"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(105),
+		     PXA_FUNCTION(0, 1, "CIF_DD<1>"),
+		     PXA_FUNCTION(1, 1, "nPCE<2>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(106),
+		     PXA_FUNCTION(0, 1, "CIF_DD<9>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(107),
+		     PXA_FUNCTION(0, 1, "CIF_DD<8>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<4>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(108),
+		     PXA_FUNCTION(0, 1, "CIF_DD<7>"),
+		     PXA_FUNCTION(1, 1, "CHOUT<0>"),
+		     PXA_FUNCTION(1, 2, "KP_MKOUT<5>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(109),
+		     PXA_FUNCTION(0, 1, "MMDAT<1>"),
+		     PXA_FUNCTION(0, 2, "MSSDIO"),
+		     PXA_FUNCTION(1, 1, "MMDAT<1>"),
+		     PXA_FUNCTION(1, 2, "MSSDIO")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(110),
+		     PXA_FUNCTION(0, 1, "MMDAT<2>"),
+		     PXA_FUNCTION(1, 1, "MMDAT<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(111),
+		     PXA_FUNCTION(0, 1, "MMDAT<3>"),
+		     PXA_FUNCTION(1, 1, "MMDAT<3>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(112),
+		     PXA_FUNCTION(0, 1, "MMCMD"),
+		     PXA_FUNCTION(0, 2, "nMSINS"),
+		     PXA_FUNCTION(1, 1, "MMCMD")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(113),
+		     PXA_FUNCTION(0, 3, "USB_P3_3"),
+		     PXA_FUNCTION(1, 1, "I2S_SYSCLK"),
+		     PXA_FUNCTION(1, 2, "AC97_RESET_n")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(114),
+		     PXA_FUNCTION(0, 1, "CIF_DD<1>"),
+		     PXA_FUNCTION(1, 1, "UEN"),
+		     PXA_FUNCTION(1, 2, "UVS0")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(115),
+		     PXA_FUNCTION(0, 1, "DREQ<0>"),
+		     PXA_FUNCTION(0, 2, "CIF_DD<3>"),
+		     PXA_FUNCTION(0, 3, "MBREQ"),
+		     PXA_FUNCTION(1, 1, "UEN"),
+		     PXA_FUNCTION(1, 2, "nUVS1"),
+		     PXA_FUNCTION(1, 3, "PWM_OUT<1>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(116),
+		     PXA_FUNCTION(0, 1, "CIF_DD<2>"),
+		     PXA_FUNCTION(0, 2, "AC97_SDATA_IN_0"),
+		     PXA_FUNCTION(0, 3, "UDET"),
+		     PXA_FUNCTION(1, 1, "DVAL<0>"),
+		     PXA_FUNCTION(1, 2, "nUVS2"),
+		     PXA_FUNCTION(1, 3, "MBGNT")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(117),
+		     PXA_FUNCTION(0, 1, "SCL"),
+		     PXA_FUNCTION(1, 1, "SCL")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(118),
+		     PXA_FUNCTION(0, 1, "SDA"),
+		     PXA_FUNCTION(1, 1, "SDA")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(119),
+		     PXA_FUNCTION(0, 1, "USBHPWR<2>")),
+	PXA_GPIO_PIN(PXA_PINCTRL_PIN(120),
+		     PXA_FUNCTION(1, 2, "USBHPEN<2>")),
+};
+
+static int pxa27x_pinctrl_probe(struct platform_device *pdev)
+{
+	int ret, i;
+	void __iomem *base_af[8];
+	void __iomem *base_dir[4];
+	void __iomem *base_sleep[4];
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base_af[0] = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base_af[0]))
+		return PTR_ERR(base_af[0]);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base_dir[0] = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base_dir[0]))
+		return PTR_ERR(base_dir[0]);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	base_dir[3] = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base_dir[3]))
+		return PTR_ERR(base_dir[3]);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+	base_sleep[0] = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base_sleep[0]))
+		return PTR_ERR(base_sleep[0]);
+
+	for (i = 0; i < ARRAY_SIZE(base_af); i++)
+		base_af[i] = base_af[0] + sizeof(base_af[0]) * i;
+	for (i = 0; i < 3; i++)
+		base_dir[i] = base_dir[0] + sizeof(base_dir[0]) * i;
+	for (i = 0; i < ARRAY_SIZE(base_sleep); i++)
+		base_sleep[i] = base_sleep[0] + sizeof(base_af[0]) * i;
+
+	ret = pxa2xx_pinctrl_init(pdev, pxa27x_pins, ARRAY_SIZE(pxa27x_pins),
+				  base_af, base_dir, base_sleep);
+	return ret;
+}
+
+static const struct of_device_id pxa27x_pinctrl_match[] = {
+	{ .compatible = "marvell,pxa27x-pinctrl", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, pxa27x_pinctrl_match);
+
+static struct platform_driver pxa27x_pinctrl_driver = {
+	.probe	= pxa27x_pinctrl_probe,
+	.driver	= {
+		.name		= "pxa27x-pinctrl",
+		.of_match_table	= pxa27x_pinctrl_match,
+	},
+};
+module_platform_driver(pxa27x_pinctrl_driver);
+
+MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
+MODULE_DESCRIPTION("Marvell PXA27x pinctrl driver");
+MODULE_LICENSE("GPL v2");
-- 
2.1.4

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

* [PATCH 6/6] pinctrl: activate pxa architecture
  2015-11-21 18:04 ` Robert Jarzmik
@ 2015-11-21 18:04   ` Robert Jarzmik
  -1 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: Linus Walleij, Daniel Mack, Haojian Zhuang, Robert Jarzmik
  Cc: linux-kernel, linux-gpio, linux-arm-kernel

As the pxa architecture, at least for pxa27x, supports pin control,
activate it in the pinctrl tree.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/Kconfig  | 1 +
 drivers/pinctrl/Makefile | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index b422e4ed73f4..cab84911466a 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -254,6 +254,7 @@ source "drivers/pinctrl/freescale/Kconfig"
 source "drivers/pinctrl/intel/Kconfig"
 source "drivers/pinctrl/mvebu/Kconfig"
 source "drivers/pinctrl/nomadik/Kconfig"
+source "drivers/pinctrl/pxa/Kconfig"
 source "drivers/pinctrl/qcom/Kconfig"
 source "drivers/pinctrl/samsung/Kconfig"
 source "drivers/pinctrl/sh-pfc/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 738cb4929a49..d214ede807e0 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -46,6 +46,7 @@ obj-y				+= freescale/
 obj-$(CONFIG_X86)		+= intel/
 obj-$(CONFIG_PLAT_ORION)        += mvebu/
 obj-y				+= nomadik/
+obj-$(CONFIG_ARCH_PXA)		+= pxa/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
 obj-$(CONFIG_PINCTRL_SAMSUNG)	+= samsung/
 obj-$(CONFIG_PINCTRL_SH_PFC)	+= sh-pfc/
-- 
2.1.4

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

* [PATCH 6/6] pinctrl: activate pxa architecture
@ 2015-11-21 18:04   ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-21 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

As the pxa architecture, at least for pxa27x, supports pin control,
activate it in the pinctrl tree.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pinctrl/Kconfig  | 1 +
 drivers/pinctrl/Makefile | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index b422e4ed73f4..cab84911466a 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -254,6 +254,7 @@ source "drivers/pinctrl/freescale/Kconfig"
 source "drivers/pinctrl/intel/Kconfig"
 source "drivers/pinctrl/mvebu/Kconfig"
 source "drivers/pinctrl/nomadik/Kconfig"
+source "drivers/pinctrl/pxa/Kconfig"
 source "drivers/pinctrl/qcom/Kconfig"
 source "drivers/pinctrl/samsung/Kconfig"
 source "drivers/pinctrl/sh-pfc/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 738cb4929a49..d214ede807e0 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -46,6 +46,7 @@ obj-y				+= freescale/
 obj-$(CONFIG_X86)		+= intel/
 obj-$(CONFIG_PLAT_ORION)        += mvebu/
 obj-y				+= nomadik/
+obj-$(CONFIG_ARCH_PXA)		+= pxa/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
 obj-$(CONFIG_PINCTRL_SAMSUNG)	+= samsung/
 obj-$(CONFIG_PINCTRL_SH_PFC)	+= sh-pfc/
-- 
2.1.4

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

* Re: [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support
  2015-11-21 18:04 ` Robert Jarzmik
  (?)
@ 2015-11-30 13:05   ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-11-30 13:05 UTC (permalink / raw)
  To: Robert Jarzmik, Haojian Zhuang
  Cc: Daniel Mack, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> I've been working on this for some time now, it's time pxa archtecture gets a
> proper pin control support.
>
> This serie provides support for pxa27x architecture, and paves the way to pxa2xx
> one. I've tested this on my pxa27x board, in both device-tree and non
> device-tree builds.

So in 2013 Haojian removed PXA3xx, MMP2, PXA168 and PXA910 in favor
of using pinctrl-single.c shared with OMAP.

See
commit 62194200e5e383af2085faf35b6f009364446069
"pinctrl: remove pxa pinctrl driver"

What makes the PXA27x so different from its siblings that it still
warrants its own driver? Why can this one not use pinctrl-single
as well?

Yours,
Linus Walleij

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

* Re: [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support
@ 2015-11-30 13:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-11-30 13:05 UTC (permalink / raw)
  To: Robert Jarzmik, Haojian Zhuang
  Cc: Daniel Mack, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> I've been working on this for some time now, it's time pxa archtecture gets a
> proper pin control support.
>
> This serie provides support for pxa27x architecture, and paves the way to pxa2xx
> one. I've tested this on my pxa27x board, in both device-tree and non
> device-tree builds.

So in 2013 Haojian removed PXA3xx, MMP2, PXA168 and PXA910 in favor
of using pinctrl-single.c shared with OMAP.

See
commit 62194200e5e383af2085faf35b6f009364446069
"pinctrl: remove pxa pinctrl driver"

What makes the PXA27x so different from its siblings that it still
warrants its own driver? Why can this one not use pinctrl-single
as well?

Yours,
Linus Walleij

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

* [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support
@ 2015-11-30 13:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-11-30 13:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> I've been working on this for some time now, it's time pxa archtecture gets a
> proper pin control support.
>
> This serie provides support for pxa27x architecture, and paves the way to pxa2xx
> one. I've tested this on my pxa27x board, in both device-tree and non
> device-tree builds.

So in 2013 Haojian removed PXA3xx, MMP2, PXA168 and PXA910 in favor
of using pinctrl-single.c shared with OMAP.

See
commit 62194200e5e383af2085faf35b6f009364446069
"pinctrl: remove pxa pinctrl driver"

What makes the PXA27x so different from its siblings that it still
warrants its own driver? Why can this one not use pinctrl-single
as well?

Yours,
Linus Walleij

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

* Re: [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support
  2015-11-30 13:05   ` Linus Walleij
  (?)
@ 2015-11-30 21:06     ` Robert Jarzmik
  -1 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-30 21:06 UTC (permalink / raw)
  To: Linus Walleij, Haojian Zhuang
  Cc: Daniel Mack, linux-kernel, linux-gpio, linux-arm-kernel

Linus Walleij <linus.walleij@linaro.org> writes:

> On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
>
>> I've been working on this for some time now, it's time pxa archtecture gets a
>> proper pin control support.
>>
>> This serie provides support for pxa27x architecture, and paves the way to pxa2xx
>> one. I've tested this on my pxa27x board, in both device-tree and non
>> device-tree builds.
>
> So in 2013 Haojian removed PXA3xx, MMP2, PXA168 and PXA910 in favor
> of using pinctrl-single.c shared with OMAP.
>
> See
> commit 62194200e5e383af2085faf35b6f009364446069
> "pinctrl: remove pxa pinctrl driver"
Yes, for MMP2, PXA168 and PXA910. Up to my best understanding this didn't cover
pxa3xx, but I might be wrong.

> What makes the PXA27x so different from its siblings that it still
> warrants its own driver? Why can this one not use pinctrl-single
> as well?
There are several factors I considered, which apply for both pxa25x and pxa27x :
 - pinmuxing
   - the "alternate" function is not dictated by a single register for a given
     pin. The function is dictated by 2 registers : the gpio direction register
     and the alternate function register.
     That means that setting alternate function "MMCLK" for examples implies
     writing to the gpio direction register (GPDR) "output", and writing to the
     alternate function register (GAFR) the function.
     I don't think pinctrl-single can handle this complexity, correct me if I'm
     wrong.

   - MMP2, PXA168 and PXA910 are "post-multi platform" kernel. That means there
     is not "machine code", and that all their boards are described in
     devicetree (correct me Haojian if I'm wrong).
     On the other hand, pxa25x, pxa27x and pxa3xx platform have still a lot of
     machine files (arch/arm/mach-pxa/*.c). The goal of this serie is to remove
     arch/arm/mach-pxa/mfp-*.c files, which predate pin control API, by
     converting these machine files to pin control.
     The long term goal is to have only one code maintained for pxa pinmuxing,
     for both devicetree and platform_data board, and I'd rather have it in
     pinctrl rather than arch/arm/mach-pxa.

   - gpio direction register sharing
     As GPDR is needed for both gpio driver and pinctrl, I'd like to have a
     single point where GPDR is manipulated. As pincontrol cannot be configured
     without it, I was thinking have a pinctrl driver driving GPDR, and
     gpio-pxa.c using it.
     I don't see pinctrl-single enabling that either.

   - non contiguous register ranges
     GPDR and GAFR are not contiguous, ie. you don't have the guarantee that
     GPDR(pin(x+1)) is either GPDR(pin(x)) or GPDR(pin(x)) + 4.
     Or said differently the register sets are sparse, and I don't know if
     pinctrl-single can handle that.

 - pinconf
   - nothing special here, only a register set (sparse AFAIR).
     I don't know if pinctrl-single can handle non contiguous MMIO ranges.

Now for pxa3xx, I think pinctrl-single might be usable, as this architecture has
a proper pincontrol register set. This is something I will look into next, as
long as the legacy platform can use pinctrl-single too (ie. from machine code).

I might remember other reasons in the next days, these ones are the most obvious
which came to my mind.

If you think of another way, I'm all for it, my personal objectives are :
 - removing mfp* files
 - having the same code handle devicetree and platform_data boards
 - having consistency in gpio direction handling
 - having pinctrl debug facilities (I love /sys/kernel/debug/pinctrl**)
 - having pin function names consistency across the boards if possible (ie. if
   MMCLK is used on boardX, then MMCLK must be used in boardY, and not MMCCLK)

Cheers.

-- 
Robert

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

* Re: [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support
@ 2015-11-30 21:06     ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-30 21:06 UTC (permalink / raw)
  To: Linus Walleij, Haojian Zhuang
  Cc: Daniel Mack, linux-kernel, linux-gpio, linux-arm-kernel

Linus Walleij <linus.walleij@linaro.org> writes:

> On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
>
>> I've been working on this for some time now, it's time pxa archtecture gets a
>> proper pin control support.
>>
>> This serie provides support for pxa27x architecture, and paves the way to pxa2xx
>> one. I've tested this on my pxa27x board, in both device-tree and non
>> device-tree builds.
>
> So in 2013 Haojian removed PXA3xx, MMP2, PXA168 and PXA910 in favor
> of using pinctrl-single.c shared with OMAP.
>
> See
> commit 62194200e5e383af2085faf35b6f009364446069
> "pinctrl: remove pxa pinctrl driver"
Yes, for MMP2, PXA168 and PXA910. Up to my best understanding this didn't cover
pxa3xx, but I might be wrong.

> What makes the PXA27x so different from its siblings that it still
> warrants its own driver? Why can this one not use pinctrl-single
> as well?
There are several factors I considered, which apply for both pxa25x and pxa27x :
 - pinmuxing
   - the "alternate" function is not dictated by a single register for a given
     pin. The function is dictated by 2 registers : the gpio direction register
     and the alternate function register.
     That means that setting alternate function "MMCLK" for examples implies
     writing to the gpio direction register (GPDR) "output", and writing to the
     alternate function register (GAFR) the function.
     I don't think pinctrl-single can handle this complexity, correct me if I'm
     wrong.

   - MMP2, PXA168 and PXA910 are "post-multi platform" kernel. That means there
     is not "machine code", and that all their boards are described in
     devicetree (correct me Haojian if I'm wrong).
     On the other hand, pxa25x, pxa27x and pxa3xx platform have still a lot of
     machine files (arch/arm/mach-pxa/*.c). The goal of this serie is to remove
     arch/arm/mach-pxa/mfp-*.c files, which predate pin control API, by
     converting these machine files to pin control.
     The long term goal is to have only one code maintained for pxa pinmuxing,
     for both devicetree and platform_data board, and I'd rather have it in
     pinctrl rather than arch/arm/mach-pxa.

   - gpio direction register sharing
     As GPDR is needed for both gpio driver and pinctrl, I'd like to have a
     single point where GPDR is manipulated. As pincontrol cannot be configured
     without it, I was thinking have a pinctrl driver driving GPDR, and
     gpio-pxa.c using it.
     I don't see pinctrl-single enabling that either.

   - non contiguous register ranges
     GPDR and GAFR are not contiguous, ie. you don't have the guarantee that
     GPDR(pin(x+1)) is either GPDR(pin(x)) or GPDR(pin(x)) + 4.
     Or said differently the register sets are sparse, and I don't know if
     pinctrl-single can handle that.

 - pinconf
   - nothing special here, only a register set (sparse AFAIR).
     I don't know if pinctrl-single can handle non contiguous MMIO ranges.

Now for pxa3xx, I think pinctrl-single might be usable, as this architecture has
a proper pincontrol register set. This is something I will look into next, as
long as the legacy platform can use pinctrl-single too (ie. from machine code).

I might remember other reasons in the next days, these ones are the most obvious
which came to my mind.

If you think of another way, I'm all for it, my personal objectives are :
 - removing mfp* files
 - having the same code handle devicetree and platform_data boards
 - having consistency in gpio direction handling
 - having pinctrl debug facilities (I love /sys/kernel/debug/pinctrl**)
 - having pin function names consistency across the boards if possible (ie. if
   MMCLK is used on boardX, then MMCLK must be used in boardY, and not MMCCLK)

Cheers.

-- 
Robert

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

* [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support
@ 2015-11-30 21:06     ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-11-30 21:06 UTC (permalink / raw)
  To: linux-arm-kernel

Linus Walleij <linus.walleij@linaro.org> writes:

> On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
>
>> I've been working on this for some time now, it's time pxa archtecture gets a
>> proper pin control support.
>>
>> This serie provides support for pxa27x architecture, and paves the way to pxa2xx
>> one. I've tested this on my pxa27x board, in both device-tree and non
>> device-tree builds.
>
> So in 2013 Haojian removed PXA3xx, MMP2, PXA168 and PXA910 in favor
> of using pinctrl-single.c shared with OMAP.
>
> See
> commit 62194200e5e383af2085faf35b6f009364446069
> "pinctrl: remove pxa pinctrl driver"
Yes, for MMP2, PXA168 and PXA910. Up to my best understanding this didn't cover
pxa3xx, but I might be wrong.

> What makes the PXA27x so different from its siblings that it still
> warrants its own driver? Why can this one not use pinctrl-single
> as well?
There are several factors I considered, which apply for both pxa25x and pxa27x :
 - pinmuxing
   - the "alternate" function is not dictated by a single register for a given
     pin. The function is dictated by 2 registers : the gpio direction register
     and the alternate function register.
     That means that setting alternate function "MMCLK" for examples implies
     writing to the gpio direction register (GPDR) "output", and writing to the
     alternate function register (GAFR) the function.
     I don't think pinctrl-single can handle this complexity, correct me if I'm
     wrong.

   - MMP2, PXA168 and PXA910 are "post-multi platform" kernel. That means there
     is not "machine code", and that all their boards are described in
     devicetree (correct me Haojian if I'm wrong).
     On the other hand, pxa25x, pxa27x and pxa3xx platform have still a lot of
     machine files (arch/arm/mach-pxa/*.c). The goal of this serie is to remove
     arch/arm/mach-pxa/mfp-*.c files, which predate pin control API, by
     converting these machine files to pin control.
     The long term goal is to have only one code maintained for pxa pinmuxing,
     for both devicetree and platform_data board, and I'd rather have it in
     pinctrl rather than arch/arm/mach-pxa.

   - gpio direction register sharing
     As GPDR is needed for both gpio driver and pinctrl, I'd like to have a
     single point where GPDR is manipulated. As pincontrol cannot be configured
     without it, I was thinking have a pinctrl driver driving GPDR, and
     gpio-pxa.c using it.
     I don't see pinctrl-single enabling that either.

   - non contiguous register ranges
     GPDR and GAFR are not contiguous, ie. you don't have the guarantee that
     GPDR(pin(x+1)) is either GPDR(pin(x)) or GPDR(pin(x)) + 4.
     Or said differently the register sets are sparse, and I don't know if
     pinctrl-single can handle that.

 - pinconf
   - nothing special here, only a register set (sparse AFAIR).
     I don't know if pinctrl-single can handle non contiguous MMIO ranges.

Now for pxa3xx, I think pinctrl-single might be usable, as this architecture has
a proper pincontrol register set. This is something I will look into next, as
long as the legacy platform can use pinctrl-single too (ie. from machine code).

I might remember other reasons in the next days, these ones are the most obvious
which came to my mind.

If you think of another way, I'm all for it, my personal objectives are :
 - removing mfp* files
 - having the same code handle devicetree and platform_data boards
 - having consistency in gpio direction handling
 - having pinctrl debug facilities (I love /sys/kernel/debug/pinctrl**)
 - having pin function names consistency across the boards if possible (ie. if
   MMCLK is used on boardX, then MMCLK must be used in boardY, and not MMCCLK)

Cheers.

-- 
Robert

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

* Re: [PATCH 1/6] MAINTAINERS: add to pxa files pinctrl
  2015-11-21 18:04   ` Robert Jarzmik
  (?)
@ 2015-12-10 15:09     ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:09 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> Add the pinctrl pxa drivers to the pxa maintained files.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

Patch applied.

Yours,
Linus Walleij

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

* Re: [PATCH 1/6] MAINTAINERS: add to pxa files pinctrl
@ 2015-12-10 15:09     ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:09 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> Add the pinctrl pxa drivers to the pxa maintained files.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

Patch applied.

Yours,
Linus Walleij

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

* [PATCH 1/6] MAINTAINERS: add to pxa files pinctrl
@ 2015-12-10 15:09     ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> Add the pinctrl pxa drivers to the pxa maintained files.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

Patch applied.

Yours,
Linus Walleij

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

* Re: [PATCH 2/6] pinctrl: pxa: pxa2xx: add pin control skeleton
  2015-11-21 18:04   ` Robert Jarzmik
  (?)
@ 2015-12-10 15:10     ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:10 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
> and pxa27x variants. This is only the pin muxing part of the driver.
>
> One specific consideration is also the memory space (MMIO), which is
> intertwined with the GPIO registers. To make things worse, the GPIO
> direction register also affect pin muxing, as it chooses the "kind" of
> pin, ie. the 4 output functions or 4 input functions.
>
> The mapping between pinctrl notions and PXA Technical Reference Manual
> is as follows :
>  - a pin is obviously a pin
>  - a group is also a pin, ie. group P101 is the pin 101
>  - a mux function is an alternate function
>    (ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
>
> The individual architecture (pxa27x, pxa25x) instantiate a pin control
> by providing a table of pins, each pin being provided a list of
> PXA_FUNCTION (alternate functions).
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

Patch applied.

Yours,
Linus Walleij

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

* Re: [PATCH 2/6] pinctrl: pxa: pxa2xx: add pin control skeleton
@ 2015-12-10 15:10     ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:10 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
> and pxa27x variants. This is only the pin muxing part of the driver.
>
> One specific consideration is also the memory space (MMIO), which is
> intertwined with the GPIO registers. To make things worse, the GPIO
> direction register also affect pin muxing, as it chooses the "kind" of
> pin, ie. the 4 output functions or 4 input functions.
>
> The mapping between pinctrl notions and PXA Technical Reference Manual
> is as follows :
>  - a pin is obviously a pin
>  - a group is also a pin, ie. group P101 is the pin 101
>  - a mux function is an alternate function
>    (ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
>
> The individual architecture (pxa27x, pxa25x) instantiate a pin control
> by providing a table of pins, each pin being provided a list of
> PXA_FUNCTION (alternate functions).
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

Patch applied.

Yours,
Linus Walleij

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

* [PATCH 2/6] pinctrl: pxa: pxa2xx: add pin control skeleton
@ 2015-12-10 15:10     ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
> and pxa27x variants. This is only the pin muxing part of the driver.
>
> One specific consideration is also the memory space (MMIO), which is
> intertwined with the GPIO registers. To make things worse, the GPIO
> direction register also affect pin muxing, as it chooses the "kind" of
> pin, ie. the 4 output functions or 4 input functions.
>
> The mapping between pinctrl notions and PXA Technical Reference Manual
> is as follows :
>  - a pin is obviously a pin
>  - a group is also a pin, ie. group P101 is the pin 101
>  - a mux function is an alternate function
>    (ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
>
> The individual architecture (pxa27x, pxa25x) instantiate a pin control
> by providing a table of pins, each pin being provided a list of
> PXA_FUNCTION (alternate functions).
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

Patch applied.

Yours,
Linus Walleij

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

* Re: [PATCH 3/6] pinctrl: pxa: pxa2xx: add pin muxing
  2015-11-21 18:04   ` Robert Jarzmik
  (?)
@ 2015-12-10 15:12     ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:12 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> The driver is inspired from the sunxi driver. The pxa architecture
> specificities leading to the driver are :
>  - each pin has 8 possible alternate functions
>  - 4 of these are output kind
>  - 4 of these are input kind
>  - there is always a "gpio input" and "gpio output" function
>  - the function matrix is very scattered :
>    - some functions can be found on 5 different pads
>    - the number of functions is greater than the number of pins
>    - there is no "topology" grouping of pins (such as all SPI in one
>      corner of the die)
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

Patch applied.

Yours,
Linus Walleij

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

* Re: [PATCH 3/6] pinctrl: pxa: pxa2xx: add pin muxing
@ 2015-12-10 15:12     ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:12 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> The driver is inspired from the sunxi driver. The pxa architecture
> specificities leading to the driver are :
>  - each pin has 8 possible alternate functions
>  - 4 of these are output kind
>  - 4 of these are input kind
>  - there is always a "gpio input" and "gpio output" function
>  - the function matrix is very scattered :
>    - some functions can be found on 5 different pads
>    - the number of functions is greater than the number of pins
>    - there is no "topology" grouping of pins (such as all SPI in one
>      corner of the die)
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

Patch applied.

Yours,
Linus Walleij

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

* [PATCH 3/6] pinctrl: pxa: pxa2xx: add pin muxing
@ 2015-12-10 15:12     ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> The driver is inspired from the sunxi driver. The pxa architecture
> specificities leading to the driver are :
>  - each pin has 8 possible alternate functions
>  - 4 of these are output kind
>  - 4 of these are input kind
>  - there is always a "gpio input" and "gpio output" function
>  - the function matrix is very scattered :
>    - some functions can be found on 5 different pads
>    - the number of functions is greater than the number of pins
>    - there is no "topology" grouping of pins (such as all SPI in one
>      corner of the die)
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

Patch applied.

Yours,
Linus Walleij

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

* Re: [PATCH 6/6] pinctrl: activate pxa architecture
  2015-11-21 18:04   ` Robert Jarzmik
  (?)
@ 2015-12-10 15:14     ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:14 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> As the pxa architecture, at least for pxa27x, supports pin control,
> activate it in the pinctrl tree.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

All 6 patches applied. I can see that you know what you're doing
so let's go ahead with this driver. Any issues can be patched
up later.

Yours,
Linus Walleij

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

* Re: [PATCH 6/6] pinctrl: activate pxa architecture
@ 2015-12-10 15:14     ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:14 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> As the pxa architecture, at least for pxa27x, supports pin control,
> activate it in the pinctrl tree.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

All 6 patches applied. I can see that you know what you're doing
so let's go ahead with this driver. Any issues can be patched
up later.

Yours,
Linus Walleij

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

* [PATCH 6/6] pinctrl: activate pxa architecture
@ 2015-12-10 15:14     ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2015-12-10 15:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> As the pxa architecture, at least for pxa27x, supports pin control,
> activate it in the pinctrl tree.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

All 6 patches applied. I can see that you know what you're doing
so let's go ahead with this driver. Any issues can be patched
up later.

Yours,
Linus Walleij

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

* Re: [PATCH 6/6] pinctrl: activate pxa architecture
  2015-12-10 15:14     ` Linus Walleij
  (?)
@ 2015-12-10 18:59       ` Robert Jarzmik
  -1 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-12-10 18:59 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

Linus Walleij <linus.walleij@linaro.org> writes:

> On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
>
>> As the pxa architecture, at least for pxa27x, supports pin control,
>> activate it in the pinctrl tree.
>>
>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>
> All 6 patches applied. I can see that you know what you're doing
> so let's go ahead with this driver. Any issues can be patched
> up later.
Thanks Linus. Let's hope I live up to your expectations :)

Cheers.

-- 
Robert

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

* Re: [PATCH 6/6] pinctrl: activate pxa architecture
@ 2015-12-10 18:59       ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-12-10 18:59 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Daniel Mack, Haojian Zhuang, linux-kernel, linux-gpio, linux-arm-kernel

Linus Walleij <linus.walleij@linaro.org> writes:

> On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
>
>> As the pxa architecture, at least for pxa27x, supports pin control,
>> activate it in the pinctrl tree.
>>
>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>
> All 6 patches applied. I can see that you know what you're doing
> so let's go ahead with this driver. Any issues can be patched
> up later.
Thanks Linus. Let's hope I live up to your expectations :)

Cheers.

-- 
Robert

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

* [PATCH 6/6] pinctrl: activate pxa architecture
@ 2015-12-10 18:59       ` Robert Jarzmik
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Jarzmik @ 2015-12-10 18:59 UTC (permalink / raw)
  To: linux-arm-kernel

Linus Walleij <linus.walleij@linaro.org> writes:

> On Sat, Nov 21, 2015 at 7:04 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
>
>> As the pxa architecture, at least for pxa27x, supports pin control,
>> activate it in the pinctrl tree.
>>
>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>
> All 6 patches applied. I can see that you know what you're doing
> so let's go ahead with this driver. Any issues can be patched
> up later.
Thanks Linus. Let's hope I live up to your expectations :)

Cheers.

-- 
Robert

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

end of thread, other threads:[~2015-12-10 18:59 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-21 18:04 [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support Robert Jarzmik
2015-11-21 18:04 ` Robert Jarzmik
2015-11-21 18:04 ` Robert Jarzmik
2015-11-21 18:04 ` [PATCH 1/6] MAINTAINERS: add to pxa files pinctrl Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-12-10 15:09   ` Linus Walleij
2015-12-10 15:09     ` Linus Walleij
2015-12-10 15:09     ` Linus Walleij
2015-11-21 18:04 ` [PATCH 2/6] pinctrl: pxa: pxa2xx: add pin control skeleton Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-12-10 15:10   ` Linus Walleij
2015-12-10 15:10     ` Linus Walleij
2015-12-10 15:10     ` Linus Walleij
2015-11-21 18:04 ` [PATCH 3/6] pinctrl: pxa: pxa2xx: add pin muxing Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-12-10 15:12   ` Linus Walleij
2015-12-10 15:12     ` Linus Walleij
2015-12-10 15:12     ` Linus Walleij
2015-11-21 18:04 ` [PATCH 4/6] pinctrl: pxa: pxa2xx: add pin configuration support Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-11-21 18:04 ` [PATCH 5/6] pinctrl: pxa: add pxa27x architecture Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-11-21 18:04 ` [PATCH 6/6] pinctrl: activate pxa architecture Robert Jarzmik
2015-11-21 18:04   ` Robert Jarzmik
2015-12-10 15:14   ` Linus Walleij
2015-12-10 15:14     ` Linus Walleij
2015-12-10 15:14     ` Linus Walleij
2015-12-10 18:59     ` Robert Jarzmik
2015-12-10 18:59       ` Robert Jarzmik
2015-12-10 18:59       ` Robert Jarzmik
2015-11-30 13:05 ` [PATCH 0/6] pinctrl: pxa: add pxa27x pin control support Linus Walleij
2015-11-30 13:05   ` Linus Walleij
2015-11-30 13:05   ` Linus Walleij
2015-11-30 21:06   ` Robert Jarzmik
2015-11-30 21:06     ` Robert Jarzmik
2015-11-30 21:06     ` Robert Jarzmik

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.