All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] pinctrl: enable pxa pinmux
@ 2011-11-25 23:08 Haojian Zhuang
  2011-11-25 23:08 ` [PATCH 1/7] pinctrl: enable pxa3xx pinmux Haojian Zhuang
                   ` (6 more replies)
  0 siblings, 7 replies; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-25 23:08 UTC (permalink / raw)
  To: linux-arm-kernel

Re-send these patches.

Replace mfpr driver with pinmux driver in arch-pxa & arch-mmp.

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-25 23:08 [PATCH 0/7] pinctrl: enable pxa pinmux Haojian Zhuang
@ 2011-11-25 23:08 ` Haojian Zhuang
  2011-11-28  9:08   ` Linus Walleij
                     ` (2 more replies)
  2011-11-25 23:08 ` [PATCH 2/7] gpio: make pxa gpio depend on pinmux Haojian Zhuang
                   ` (5 subsequent siblings)
  6 siblings, 3 replies; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-25 23:08 UTC (permalink / raw)
  To: linux-arm-kernel

Support PXA300/PXA310/PXA320/PXA910 pinmux.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
---
 drivers/pinctrl/Kconfig         |    5 +
 drivers/pinctrl/Makefile        |    1 +
 drivers/pinctrl/pinmux-pxa3xx.c |  931 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 937 insertions(+), 0 deletions(-)
 create mode 100644 drivers/pinctrl/pinmux-pxa3xx.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index e17e2f8..582f72d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -20,6 +20,11 @@ config DEBUG_PINCTRL
 	help
 	  Say Y here to add some extra checks and diagnostics to PINCTRL calls.
 
+config PINMUX_PXA3xx
+	bool "PXA pinmux driver"
+	default y if ARCH_PXA || ARCH_MMP
+	select PINMUX
+
 config PINMUX_SIRF
 	bool "CSR SiRFprimaII pinmux driver"
 	depends on ARCH_PRIMA2
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index bdc548a..a364787 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -4,5 +4,6 @@ ccflags-$(CONFIG_DEBUG_PINMUX)	+= -DDEBUG
 
 obj-$(CONFIG_PINCTRL)		+= core.o
 obj-$(CONFIG_PINMUX)		+= pinmux.o
+obj-$(CONFIG_PINMUX_PXA3xx)	+= pinmux-pxa3xx.o
 obj-$(CONFIG_PINMUX_SIRF)	+= pinmux-sirf.o
 obj-$(CONFIG_PINMUX_U300)	+= pinmux-u300.o
diff --git a/drivers/pinctrl/pinmux-pxa3xx.c b/drivers/pinctrl/pinmux-pxa3xx.c
new file mode 100644
index 0000000..e4386fa
--- /dev/null
+++ b/drivers/pinctrl/pinmux-pxa3xx.c
@@ -0,0 +1,931 @@
+/*
+ *  linux/drivers/pinctrl/pinmux-pxa3xx.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+
+#define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
+#define MFPR_FUNC		7
+#define MFPR_FUNC_MASK		(~MFPR_FUNC)
+
+
+enum {
+	PINMUX_PXA300 = 0,
+	PINMUX_PXA310,
+	PINMUX_PXA320,
+	PINMUX_PXA910,
+	PINMUX_MAX,
+};
+
+struct pxa3xx_pin_group {
+	const char *name;
+	const unsigned int *func;
+	const unsigned int *pins;
+	const unsigned int num_pins;
+};
+
+struct pxa3xx_pmx_func {
+	const char *name;
+	const char * const * groups;
+	const unsigned num_groups;
+};
+
+struct pxa3xx_pinmux_info {
+	struct device *dev;
+	struct pinctrl_dev *pctl;
+	unsigned int phy_base;
+	unsigned int phy_size;
+	void __iomem *virt_base;
+	unsigned int cpuid;
+	struct pxa3xx_pin_group *grp;
+	unsigned int num_grps;
+	struct pxa3xx_pmx_func *func;
+	unsigned int num_funcs;
+};
+
+/* These 135 pins exists in PXA300, PXA310 & PXA320 */
+#define PXA3XX_COMMON_PINS()						\
+	PINCTRL_PIN(0, "GPIO0"), 	PINCTRL_PIN(1, "GPIO1"),	\
+	PINCTRL_PIN(2, "GPIO2"),	PINCTRL_PIN(3, "GPIO3"),	\
+	PINCTRL_PIN(4, "GPIO4"),	PINCTRL_PIN(5, "GPIO5"),	\
+	PINCTRL_PIN(6, "GPIO6"),	PINCTRL_PIN(7, "GPIO7"),	\
+	PINCTRL_PIN(8, "GPIO8"),	PINCTRL_PIN(9, "GPIO9"),	\
+	PINCTRL_PIN(10, "GPIO10"),	PINCTRL_PIN(11, "GPIO11"),	\
+	PINCTRL_PIN(12, "GPIO12"),	PINCTRL_PIN(13, "GPIO13"),	\
+	PINCTRL_PIN(14, "GPIO14"),	PINCTRL_PIN(15, "GPIO15"),	\
+	PINCTRL_PIN(16, "GPIO16"),	PINCTRL_PIN(17, "GPIO17"),	\
+	PINCTRL_PIN(18, "GPIO18"),	PINCTRL_PIN(19, "GPIO19"),	\
+	PINCTRL_PIN(20, "GPIO20"),	PINCTRL_PIN(21, "GPIO21"),	\
+	PINCTRL_PIN(22, "GPIO22"),	PINCTRL_PIN(23, "GPIO23"),	\
+	PINCTRL_PIN(24, "GPIO24"),	PINCTRL_PIN(25, "GPIO25"),	\
+	PINCTRL_PIN(26, "GPIO26"),	PINCTRL_PIN(27, "GPIO27"),	\
+	PINCTRL_PIN(28, "GPIO28"),	PINCTRL_PIN(29, "GPIO29"),	\
+	PINCTRL_PIN(30, "GPIO30"),	PINCTRL_PIN(31, "GPIO31"),	\
+	PINCTRL_PIN(32, "GPIO32"),	PINCTRL_PIN(33, "GPIO33"),	\
+	PINCTRL_PIN(34, "GPIO34"),	PINCTRL_PIN(35, "GPIO35"),	\
+	PINCTRL_PIN(36, "GPIO36"),	PINCTRL_PIN(37, "GPIO37"),	\
+	PINCTRL_PIN(38, "GPIO38"),	PINCTRL_PIN(39, "GPIO39"),	\
+	PINCTRL_PIN(40, "GPIO40"),	PINCTRL_PIN(41, "GPIO41"),	\
+	PINCTRL_PIN(42, "GPIO42"),	PINCTRL_PIN(43, "GPIO43"),	\
+	PINCTRL_PIN(44, "GPIO44"),	PINCTRL_PIN(45, "GPIO45"),	\
+	PINCTRL_PIN(46, "GPIO46"),	PINCTRL_PIN(47, "GPIO47"),	\
+	PINCTRL_PIN(48, "GPIO48"),	PINCTRL_PIN(49, "GPIO49"),	\
+	PINCTRL_PIN(50, "GPIO50"),	PINCTRL_PIN(51, "GPIO51"),	\
+	PINCTRL_PIN(52, "GPIO52"),	PINCTRL_PIN(53, "GPIO53"),	\
+	PINCTRL_PIN(54, "GPIO54"),	PINCTRL_PIN(55, "GPIO55"),	\
+	PINCTRL_PIN(56, "GPIO56"),	PINCTRL_PIN(57, "GPIO57"),	\
+	PINCTRL_PIN(58, "GPIO58"),	PINCTRL_PIN(59, "GPIO59"),	\
+	PINCTRL_PIN(60, "GPIO60"),	PINCTRL_PIN(61, "GPIO61"),	\
+	PINCTRL_PIN(62, "GPIO62"),	PINCTRL_PIN(63, "GPIO63"),	\
+	PINCTRL_PIN(64, "GPIO64"),	PINCTRL_PIN(65, "GPIO65"),	\
+	PINCTRL_PIN(66, "GPIO66"),	PINCTRL_PIN(67, "GPIO67"),	\
+	PINCTRL_PIN(68, "GPIO68"),	PINCTRL_PIN(69, "GPIO69"),	\
+	PINCTRL_PIN(70, "GPIO70"),	PINCTRL_PIN(71, "GPIO71"),	\
+	PINCTRL_PIN(72, "GPIO72"),	PINCTRL_PIN(73, "GPIO73"),	\
+	PINCTRL_PIN(74, "GPIO74"),	PINCTRL_PIN(75, "GPIO75"),	\
+	PINCTRL_PIN(76, "GPIO76"),	PINCTRL_PIN(77, "GPIO77"),	\
+	PINCTRL_PIN(78, "GPIO78"),	PINCTRL_PIN(79, "GPIO79"),	\
+	PINCTRL_PIN(80, "GPIO80"),	PINCTRL_PIN(81, "GPIO81"),	\
+	PINCTRL_PIN(82, "GPIO82"),	PINCTRL_PIN(83, "GPIO83"),	\
+	PINCTRL_PIN(84, "GPIO84"),	PINCTRL_PIN(85, "GPIO85"),	\
+	PINCTRL_PIN(86, "GPIO86"),	PINCTRL_PIN(87, "GPIO87"),	\
+	PINCTRL_PIN(88, "GPIO88"),	PINCTRL_PIN(89, "GPIO89"),	\
+	PINCTRL_PIN(90, "GPIO90"),	PINCTRL_PIN(91, "GPIO91"),	\
+	PINCTRL_PIN(92, "GPIO92"),	PINCTRL_PIN(93, "GPIO93"),	\
+	PINCTRL_PIN(94, "GPIO94"),	PINCTRL_PIN(95, "GPIO95"),	\
+	PINCTRL_PIN(96, "GPIO96"),	PINCTRL_PIN(97, "GPIO97"),	\
+	PINCTRL_PIN(98, "GPIO98"),	PINCTRL_PIN(99, "GPIO99"),	\
+	PINCTRL_PIN(100, "GPIO100"),	PINCTRL_PIN(101, "GPIO101"),	\
+	PINCTRL_PIN(102, "GPIO102"),	PINCTRL_PIN(103, "GPIO103"),	\
+	PINCTRL_PIN(104, "GPIO104"),	PINCTRL_PIN(105, "GPIO105"),	\
+	PINCTRL_PIN(106, "GPIO106"),	PINCTRL_PIN(107, "GPIO107"),	\
+	PINCTRL_PIN(108, "GPIO108"),	PINCTRL_PIN(109, "GPIO109"),	\
+	PINCTRL_PIN(110, "GPIO110"),	PINCTRL_PIN(111, "GPIO111"),	\
+	PINCTRL_PIN(112, "GPIO112"),	PINCTRL_PIN(113, "GPIO113"),	\
+	PINCTRL_PIN(114, "GPIO114"),	PINCTRL_PIN(115, "GPIO115"),	\
+	PINCTRL_PIN(116, "GPIO116"),	PINCTRL_PIN(117, "GPIO117"),	\
+	PINCTRL_PIN(118, "GPIO118"),	PINCTRL_PIN(119, "GPIO119"),	\
+	PINCTRL_PIN(120, "GPIO120"),	PINCTRL_PIN(121, "GPIO121"),	\
+	PINCTRL_PIN(122, "GPIO122"),	PINCTRL_PIN(123, "GPIO123"),	\
+	PINCTRL_PIN(124, "GPIO124"),	PINCTRL_PIN(125, "GPIO125"),	\
+	PINCTRL_PIN(126, "GPIO126"),	PINCTRL_PIN(127, "GPIO127")
+
+#ifdef CONFIG_ARCH_PXA
+static struct pinctrl_pin_desc pxa300_pads[] = {
+	PXA3XX_COMMON_PINS(),
+	PINCTRL_PIN(128, "GPIO0_2"),	PINCTRL_PIN(129, "GPIO1_2"),
+	PINCTRL_PIN(130, "GPIO2_2"),	PINCTRL_PIN(131, "GPIO3_2"),
+	PINCTRL_PIN(132, "GPIO4_2"),	PINCTRL_PIN(133, "GPIO5_2"),
+	PINCTRL_PIN(134, "GPIO6_2"),
+};
+
+static struct pinctrl_pin_desc pxa310_pads[] = {
+	PXA3XX_COMMON_PINS(),
+	PINCTRL_PIN(128, "GPIO0_2"),	PINCTRL_PIN(129, "GPIO1_2"),
+	PINCTRL_PIN(130, "GPIO2_2"),	PINCTRL_PIN(131, "GPIO3_2"),
+	PINCTRL_PIN(132, "GPIO4_2"),	PINCTRL_PIN(133, "GPIO5_2"),
+	PINCTRL_PIN(134, "GPIO6_2"),	PINCTRL_PIN(135, "GPIO7_2"),
+	PINCTRL_PIN(136, "GPIO8_2"),	PINCTRL_PIN(137, "GPIO9_2"),
+	PINCTRL_PIN(138, "GPIO10_2"),
+};
+
+static struct pinctrl_pin_desc pxa320_pads[] = {
+	PXA3XX_COMMON_PINS(),
+	PINCTRL_PIN(128, "GPIO0_2"),	PINCTRL_PIN(129, "GPIO1_2"),
+	PINCTRL_PIN(130, "GPIO2_2"),	PINCTRL_PIN(131, "GPIO3_2"),
+	PINCTRL_PIN(132, "GPIO4_2"),	PINCTRL_PIN(133, "GPIO5_2"),
+	PINCTRL_PIN(134, "GPIO6_2"),	PINCTRL_PIN(135, "GPIO7_2"),
+	PINCTRL_PIN(136, "GPIO8_2"),	PINCTRL_PIN(137, "GPIO9_2"),
+	PINCTRL_PIN(138, "GPIO10_2"),	PINCTRL_PIN(139, "GPIO11_2"),
+	PINCTRL_PIN(140, "GPIO12_2"),	PINCTRL_PIN(141, "GPIO13_2"),
+	PINCTRL_PIN(142, "GPIO14_2"),	PINCTRL_PIN(143, "GPIO15_2"),
+	PINCTRL_PIN(144, "GPIO16_2"),	PINCTRL_PIN(145, "GPIO17_2"),
+};
+
+/* the sequence follows pxa300_pads[] */
+const static unsigned pxa300_mfpr[] = {
+	0x0B4, 0x0B8, 0x0BC, 0x27C, 0x280, 0x284, 0x288, 0x28C, 0x290, 0x294,
+	0x298, 0x29C, 0x2A0, 0x2A4, 0x2A8, 0x2AC, 0x2B0, 0x2B4, 0x2B8, 0x2BC,
+	0x2C0, 0x2C4, 0x2C8, 0x2CC, 0x2D0, 0x2D4, 0x2D8, 0x400, 0x404, 0x408,
+	0x40C, 0x410, 0x414, 0x418, 0x41C, 0x420, 0x424, 0x428, 0x42C, 0x430,
+	0x434, 0x438, 0x43C, 0x440, 0x444, 0x448, 0x44C, 0x450, 0x454, 0x458,
+	0x45C, 0x460, 0x464, 0x468, 0x46C, 0x470, 0x474, 0x478, 0x47C, 0x480,
+	0x484, 0x488, 0x48C, 0x490, 0x494, 0x498, 0x49C, 0x4A0, 0x4A4, 0x4A8,
+	0x4AC, 0x4B0, 0x4B4, 0x4B8, 0x4BC, 0x4C0, 0x4C4, 0x4C8, 0x4CC, 0x4D0,
+	0x4D4, 0x4D8, 0x4DC, 0x4E0, 0x4E4, 0x4E8, 0x4EC, 0x4F0, 0x4F4, 0x4F8,
+	0x4FC, 0x500, 0x504, 0x508, 0x50C, 0x510, 0x514, 0x518, 0x51C, 0x600,
+	0x604, 0x608, 0x60C, 0x610, 0x614, 0x618, 0x61C, 0x620, 0x624, 0x628,
+	0x62C, 0x630, 0x634, 0x638, 0x63C, 0x640, 0x644, 0x648, 0x64C, 0x650,
+	0x654, 0x658, 0x65C, 0x660, 0x664, 0x668, 0x66C, 0x670,
+	/* the below pins can also be configured as GPIO[6:0] */
+	0x674, 0x678, 0x2DC, 0x2E0, 0x2E4, 0x2E8, 0x2EC,
+};
+
+/* the sequence follows pxa310_pads[] */
+const static unsigned pxa310_mfpr[] = {
+	0x0B4, 0x0B8, 0x0BC, 0x27C, 0x280, 0x284, 0x288, 0x28C, 0x290, 0x294,
+	0x298, 0x29C, 0x2A0, 0x2A4, 0x2A8, 0x2AC, 0x2B0, 0x2B4, 0x2B8, 0x2BC,
+	0x2C0, 0x2C4, 0x2C8, 0x2CC, 0x2D0, 0x2D4, 0x2D8, 0x400, 0x404, 0x408,
+	0x418, 0x41C, 0x420, 0x424, 0x428, 0x42C, 0x430, 0x434, 0x438, 0x43C,
+	0x440, 0x444, 0x448, 0x44C, 0x450, 0x454, 0x458, 0x45C, 0x460, 0x464,
+	0x468, 0x46C, 0x470, 0x474, 0x478, 0x47C, 0x480, 0x484, 0x488, 0x48C,
+	0x490, 0x494, 0x498, 0x49C, 0x4A0, 0x4A4, 0x4A8, 0x4AC, 0x4B0, 0x4B4,
+	0x4B8, 0x4BC, 0x4C0, 0x4C4, 0x4C8, 0x4CC, 0x4D0, 0x4D4, 0x4D8, 0x4DC,
+	0x4E0, 0x4E4, 0x4E8, 0x4EC, 0x4F0, 0x4F4, 0x4F8, 0x4FC, 0x500, 0x504,
+	0x508, 0x50C, 0x510, 0x514, 0x518, 0x51C, 0x520, 0x524, 0x528, 0x600,
+	0x604, 0x608, 0x60C, 0x610, 0x614, 0x618, 0x61C, 0x620, 0x624, 0x628,
+	0x62C, 0x630, 0x634, 0x638, 0x63C, 0x640, 0x644, 0x648, 0x64C, 0x650,
+	0x654, 0x658, 0x65C, 0x660, 0x664, 0x668, 0x66C, 0x670,
+	/* the below pins can also be configured as GPIO[10:0] */
+	0x674, 0x678, 0x2DC, 0x2E0, 0x2E4, 0x2E8, 0x2EC, 0x52C, 0x530, 0x534,
+	0x538,
+};
+
+/* the sequence follows pxa320_pads[] */
+const static unsigned pxa320_mfpr[] = {
+	0x124, 0x128, 0x12C, 0x130, 0x134, 0x28C, 0x290, 0x294, 0x298, 0x29C,
+	0x458, 0x2A0, 0x2A4, 0x2A8, 0x2AC, 0x2B0, 0x2B4, 0x2B8, 0x2BC, 0x2C0,
+	0x2C4, 0x2C8, 0x2CC, 0x2D0, 0x2D4, 0x2D8, 0x2DC, 0x400, 0x404, 0x408,
+	0x40C, 0x410, 0x414, 0x418, 0x41C, 0x420, 0x424, 0x428, 0x42C, 0x430,
+	0x434, 0x438, 0x43C, 0x440, 0x444, 0x448, 0x44C, 0x450, 0x454, 0x45C,
+	0x460, 0x464, 0x468, 0x46C, 0x470, 0x474, 0x478, 0x47C, 0x480, 0x484,
+	0x488, 0x48C, 0x490, 0x4B4, 0x4B8, 0x4BC, 0x4C0, 0x4C4, 0x4C8, 0x4CC,
+	0x4D0, 0x4D4, 0x4D8, 0x4DC, 0x4F0, 0x4F4, 0x4F8, 0x4FC, 0x500, 0x504,
+	0x508, 0x50C, 0x510, 0x514, 0x518, 0x51C, 0x520, 0x524, 0x528, 0x52C,
+	0x530, 0x534, 0x538, 0x53C, 0x540, 0x544, 0x548, 0x54C, 0x550, 0x600,
+	0x604, 0x608, 0x60C, 0x610, 0x614, 0x618, 0x61C, 0x620, 0x624, 0x628,
+	0x62C, 0x630, 0x634, 0x638, 0x63C, 0x640, 0x644, 0x648, 0x64C, 0x650,
+	0x654, 0x658, 0x65C, 0x660, 0x664, 0x668, 0x66C, 0x670,
+	/* the below pins can also be configured as GPIO[17:0] */
+	0x674, 0x678, 0x67C, 0x680, 0x684, 0x688, 0x494, 0x498, 0x49C, 0x4A0,
+	0x4A4, 0x4A8, 0x4AC, 0x4B0, 0x4E0, 0x4E4, 0x4E8, 0x4EC,
+};
+
+/*
+ * pxa300_xxx_pins and pxa300_xxx_func are pairs.
+ * One is pin number, the other is function number.
+ */
+static const unsigned pxa300_uart1_0_pins[] = {30, 31, 32, 33, 34, 35, 36, 37};
+static const unsigned pxa300_uart1_0_func[] = {2, 2, 2, 2, 2, 2, 2, 2};
+static const unsigned pxa300_uart1_1_pins[] = {77, 78, 79, 81, 83, 84};
+static const unsigned pxa300_uart1_1_func[] = {1, 1, 1, 1, 1, 1};
+static const unsigned pxa300_uart2_pins[] = {111, 112, 113, 114};
+static const unsigned pxa300_uart2_func[] = {1, 1, 1, 1};
+static const unsigned pxa300_uart3_0_pins[] = {107, 108, 109, 110};
+static const unsigned pxa300_uart3_0_func[] = {1, 1, 1, 1};
+static const unsigned pxa300_uart3_1_pins[] = {109, 110};
+static const unsigned pxa300_uart3_1_func[] = {1, 1};
+static const unsigned pxa300_lcd0_pins[] = {54, 55, 56, 57, 58, 59, 60, 61, 62,
+		63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 127};
+static const unsigned pxa300_lcd0_func[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1};
+/* not include LCD_CS */
+static const unsigned pxa300_lcd1_pins[] = {54, 55, 56, 57, 58, 59, 60, 61, 62,
+		63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76};
+static const unsigned pxa300_lcd1_func[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2};
+/* pxa300_ac97[] not include SDATA_IN_1 pin */
+static const unsigned pxa300_ac97_pins[] = {23, 24, 25, 27, 28, 29};
+static const unsigned pxa300_ac97_func[] = {1, 1, 1, 1, 1, 1};
+static const unsigned pxa300_ssp1_pins[] = {85, 56, 87, 88, 89, 90};
+static const unsigned pxa300_ssp1_func[] = {1, 1, 1, 1, 1, 1};
+/* SSPSCLK2 & SSPTXD2 */
+static const unsigned pxa300_ssp2_0_pins[] = {25, 27};
+static const unsigned pxa300_ssp2_0_func[] = {2, 2};
+/* SSPSCLK2, SSPSFRM2, SSPTXD2 & SSPEXTCLK2 */
+static const unsigned pxa300_ssp2_1_pins[] = {25, 26, 27, 29};
+static const unsigned pxa300_ssp2_1_func[] = {2, 2, 2, 2};
+static const unsigned pxa300_ssp3_pins[] = {91, 92, 93, 94};
+static const unsigned pxa300_ssp3_func[] = {1, 1, 1, 1};
+/* DKIN[1:0], MKIN[7:0] & MKOUT[7:0] */
+static const unsigned pxa300_key0_pins[] = {107, 108, 115, 116, 117, 118,
+		119, 120, 130, 131, 121, 122, 123, 124, 125, 132, 133, 134};
+static const unsigned pxa300_key0_func[] = {2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+		1, 1, 1, 1, 1, 1, 1, 1};
+/* DKIN[1:0], MKIN[5:0] & MKOUT[4:0] */
+static const unsigned pxa300_key1_pins[] = {107, 108, 115, 116, 117, 118,
+		119, 120, 121, 122, 123, 124, 125};
+static const unsigned pxa300_key1_func[] = {2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+		1, 1, 1};
+/* MKIN[7:0] & MKOUT[5:0] */
+static const unsigned pxa300_key2_pins[] = {115, 116, 117, 118, 119, 120, 130,
+		131, 121, 122, 123, 124, 125, 132};
+static const unsigned pxa300_key2_func[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+		1, 1, 1};
+static const unsigned pxa300_mmc1_0_pins[] = {3, 4, 5, 6, 7, 8};
+static const unsigned pxa300_mmc1_0_func[] = {4, 4, 4, 4, 4, 4};
+static const unsigned pxa300_mmc1_1_pins[] = {3, 4, 5, 6, 7, 14};
+static const unsigned pxa300_mmc1_1_func[] = {4, 4, 4, 4, 4, 5};
+static const unsigned pxa300_mmc2_pins[] = {9, 10, 11, 12, 13, 14};
+static const unsigned pxa300_mmc2_func[] = {4, 4, 4, 4, 4, 4};
+static const unsigned pxa300_usbh_pins[] = {128, 129};
+static const unsigned pxa300_usbh_func[] = {1, 1};
+static const unsigned pxa300_usbp3_pins[] = {77, 78, 79, 80, 81, 82};
+static const unsigned pxa300_usbp3_func[] = {2, 2, 2, 2, 2, 2};
+static const unsigned pxa300_i2c_pins[] = {21, 22};
+static const unsigned pxa300_i2c_func[] = {1, 1};
+static const unsigned pxa300_smc_pins[] = {2};
+static const unsigned pxa300_smc_func[] = {1};
+static const unsigned pxa300_pwm3_pins[] = {20};
+static const unsigned pxa300_pwm3_func[] = {1};
+
+static struct pxa3xx_pin_group pxa300_pin_groups[] = {
+	{"ffuart0", pxa300_uart1_0_func, ARRAY_AND_SIZE(pxa300_uart1_0_pins)},
+	{"ffuart1", pxa300_uart1_0_func, ARRAY_AND_SIZE(pxa300_uart1_1_pins)},
+	{"btuart", pxa300_uart2_func, ARRAY_AND_SIZE(pxa300_uart2_pins)},
+	{"stuart0", pxa300_uart3_0_func, ARRAY_AND_SIZE(pxa300_uart3_0_pins)},
+	{"stuart1", pxa300_uart3_1_func, ARRAY_AND_SIZE(pxa300_uart3_1_pins)},
+	{"lcd0", pxa300_lcd0_func, ARRAY_AND_SIZE(pxa300_lcd0_pins)},
+	{"lcd1", pxa300_lcd1_func, ARRAY_AND_SIZE(pxa300_lcd1_pins)},
+	{"ac97", pxa300_ac97_func, ARRAY_AND_SIZE(pxa300_ac97_pins)},
+	{"ssp2_0", pxa300_ssp2_0_func, ARRAY_AND_SIZE(pxa300_ssp2_0_pins)},
+	{"ssp2_1", pxa300_ssp2_1_func, ARRAY_AND_SIZE(pxa300_ssp2_1_pins)},
+	{"ssp3", pxa300_ssp3_func, ARRAY_AND_SIZE(pxa300_ssp3_pins)},
+	{"key0", pxa300_key0_func, ARRAY_AND_SIZE(pxa300_key0_pins)},
+	{"key1", pxa300_key1_func, ARRAY_AND_SIZE(pxa300_key1_pins)},
+	{"key2", pxa300_key2_func, ARRAY_AND_SIZE(pxa300_key2_pins)},
+	{"mmc1_0", pxa300_mmc1_0_func, ARRAY_AND_SIZE(pxa300_mmc1_0_pins)},
+	{"mmc1_1", pxa300_mmc1_1_func, ARRAY_AND_SIZE(pxa300_mmc1_1_pins)},
+	{"mmc2", pxa300_mmc2_func, ARRAY_AND_SIZE(pxa300_mmc2_pins)},
+	{"usbh", pxa300_usbh_func, ARRAY_AND_SIZE(pxa300_usbh_pins)},
+	{"usbp3", pxa300_usbp3_func, ARRAY_AND_SIZE(pxa300_usbp3_pins)},
+	{"i2c", pxa300_i2c_func, ARRAY_AND_SIZE(pxa300_i2c_pins)},
+	{"smc", pxa300_smc_func, ARRAY_AND_SIZE(pxa300_smc_pins)},
+	{"pwm3", pxa300_pwm3_func, ARRAY_AND_SIZE(pxa300_pwm3_pins)},
+};
+
+static const char * const pxa300_uart0_grps[] = {"ffuart0", "ffuart1"};
+static const char * const pxa300_uart1_grps[] = {"btuart"};
+static const char * const pxa300_uart2_grps[] = {"stuart0", "stuart1"};
+static const char * const pxa300_lcd_grps[] = {"lcd0", "lcd1"};
+static const char * const pxa300_ac97_grps[] = {"ac97"};
+static const char * const pxa300_ssp2_grps[] = {"ssp2_0", "ssp2_1"};
+static const char * const pxa300_ssp3_grps[] = {"ssp3"};
+static const char * const pxa300_key_grps[] = {"key0", "key1", "key2"};
+static const char * const pxa300_mmc1_grps[] = {"mmc1_0", "mmc1_1"};
+static const char * const pxa300_mmc2_grps[] = {"mmc2"};
+static const char * const pxa300_usbh_grps[] = {"usbh"};
+static const char * const pxa300_usbp3_grps[] = {"usbp3"};
+static const char * const pxa300_i2c_grps[] = {"i2c"};
+static const char * const pxa300_smc_grps[] = {"smc"};
+static const char * const pxa300_pwm3_grps[] = {"pwm3"};
+
+static struct pxa3xx_pmx_func pxa300_pmx_functions[] = {
+	{"uart0",	ARRAY_AND_SIZE(pxa300_uart0_grps)},
+	{"uart1",	ARRAY_AND_SIZE(pxa300_uart1_grps)},
+	{"uart2",	ARRAY_AND_SIZE(pxa300_uart2_grps)},
+	{"lcd",		ARRAY_AND_SIZE(pxa300_lcd_grps)},
+	{"ac97",	ARRAY_AND_SIZE(pxa300_ac97_grps)},
+	{"ssp2",	ARRAY_AND_SIZE(pxa300_ssp2_grps)},
+	{"ssp3",	ARRAY_AND_SIZE(pxa300_ssp3_grps)},
+	{"key",		ARRAY_AND_SIZE(pxa300_key_grps)},
+	{"mmc1",	ARRAY_AND_SIZE(pxa300_mmc1_grps)},
+	{"mmc2",	ARRAY_AND_SIZE(pxa300_mmc2_grps)},
+	{"usbh",	ARRAY_AND_SIZE(pxa300_usbh_grps)},
+	{"usbp3",	ARRAY_AND_SIZE(pxa300_usbp3_grps)},
+	{"i2c",		ARRAY_AND_SIZE(pxa300_i2c_grps)},
+	{"smc",		ARRAY_AND_SIZE(pxa300_smc_grps)},
+	{"pwm3",	ARRAY_AND_SIZE(pxa300_pwm3_grps)},
+};
+
+/* RxD, TxD, CTS, RTS of UART1 */
+static const unsigned pxa310_uart1_2_pins[] = {99, 100, 101, 106};
+static const unsigned pxa310_uart1_2_func[] = {1, 1, 1, 1};
+static const unsigned pxa310_mmc3_pins[] = {135, 136, 137, 138, 103, 105};
+static const unsigned pxa310_mmc3_func[] = {1, 1, 1, 1, 2, 2};
+static const unsigned pxa310_ulpi_pins[] = {30, 31, 32, 33, 34, 35, 36,
+		37, 38};
+static const unsigned pxa310_ulpi_func[] = {3, 3, 3, 3, 3, 3, 3, 3, 1};
+
+static struct pxa3xx_pin_group pxa310_pin_groups[] = {
+	{"ffuart2", pxa310_uart1_2_func, ARRAY_AND_SIZE(pxa310_uart1_2_pins)},
+	{"btuart", pxa300_uart2_func, ARRAY_AND_SIZE(pxa300_uart2_pins)},
+	{"stuart0", pxa300_uart3_0_func, ARRAY_AND_SIZE(pxa300_uart3_0_pins)},
+	{"stuart1", pxa300_uart3_1_func, ARRAY_AND_SIZE(pxa300_uart3_1_pins)},
+	{"lcd0", pxa300_lcd0_func, ARRAY_AND_SIZE(pxa300_lcd0_pins)},
+	{"lcd1", pxa300_lcd1_func, ARRAY_AND_SIZE(pxa300_lcd1_pins)},
+	{"ac97", pxa300_ac97_func, ARRAY_AND_SIZE(pxa300_ac97_pins)},
+	{"ssp2", pxa300_ssp2_0_func, ARRAY_AND_SIZE(pxa300_ssp2_0_pins)},
+	{"ssp3", pxa300_ssp3_func, ARRAY_AND_SIZE(pxa300_ssp3_pins)},
+	{"key0", pxa300_key0_func, ARRAY_AND_SIZE(pxa300_key0_pins)},
+	{"key1", pxa300_key1_func, ARRAY_AND_SIZE(pxa300_key1_pins)},
+	{"key2", pxa300_key2_func, ARRAY_AND_SIZE(pxa300_key2_pins)},
+	{"mmc1_0", pxa300_mmc1_0_func, ARRAY_AND_SIZE(pxa300_mmc1_0_pins)},
+	{"mmc1_1", pxa300_mmc1_1_func, ARRAY_AND_SIZE(pxa300_mmc1_1_pins)},
+	{"mmc2", pxa300_mmc2_func, ARRAY_AND_SIZE(pxa300_mmc2_pins)},
+	{"mmc3", pxa310_mmc3_func, ARRAY_AND_SIZE(pxa310_mmc3_pins)},
+	{"usbh", pxa300_usbh_func, ARRAY_AND_SIZE(pxa300_usbh_pins)},
+	{"ulpi", pxa310_ulpi_func, ARRAY_AND_SIZE(pxa310_ulpi_pins)},
+	{"usbp3", pxa300_usbp3_func, ARRAY_AND_SIZE(pxa300_usbp3_pins)},
+	{"i2c", pxa300_i2c_func, ARRAY_AND_SIZE(pxa300_i2c_pins)},
+	{"smc", pxa300_smc_func, ARRAY_AND_SIZE(pxa300_smc_pins)},
+	{"pwm3", pxa300_pwm3_func, ARRAY_AND_SIZE(pxa300_pwm3_pins)},
+};
+
+static const char * const pxa310_uart0_grps[] = {"ffuart2"};
+static const char * const pxa310_mmc3_grps[] = {"mmc3"};
+static const char * const pxa310_ulpi_grps[] = {"ulpi"};
+
+static struct pxa3xx_pmx_func pxa310_pmx_functions[] = {
+	{"uart1",	ARRAY_AND_SIZE(pxa300_uart1_grps)},
+	{"uart2",	ARRAY_AND_SIZE(pxa300_uart2_grps)},
+	{"lcd",		ARRAY_AND_SIZE(pxa300_lcd_grps)},
+	{"ac97",	ARRAY_AND_SIZE(pxa300_ac97_grps)},
+	{"ssp3",	ARRAY_AND_SIZE(pxa300_ssp3_grps)},
+	{"key",		ARRAY_AND_SIZE(pxa300_key_grps)},
+	{"mmc1",	ARRAY_AND_SIZE(pxa300_mmc1_grps)},
+	{"mmc2",	ARRAY_AND_SIZE(pxa300_mmc2_grps)},
+	{"usbh",	ARRAY_AND_SIZE(pxa300_usbh_grps)},
+	{"usbp3",	ARRAY_AND_SIZE(pxa300_usbp3_grps)},
+	{"i2c",		ARRAY_AND_SIZE(pxa300_i2c_grps)},
+	{"smc",		ARRAY_AND_SIZE(pxa300_smc_grps)},
+	{"pwm3",	ARRAY_AND_SIZE(pxa300_pwm3_grps)},
+	/* new in PXA310 */
+	{"uart0",	ARRAY_AND_SIZE(pxa310_uart0_grps)},
+	{"mmc3",	ARRAY_AND_SIZE(pxa310_mmc3_grps)},
+	{"ulpi",	ARRAY_AND_SIZE(pxa310_ulpi_grps)},
+};
+
+static const unsigned pxa320_lcd_pins[] = {134, 135, 136, 137, 138, 139,
+		140, 141, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+		142, 143, 144, 145};
+static const unsigned pxa320_lcd_func[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+		1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1};
+static const unsigned pxa320_uart0_pins[] = {41, 42, 43, 44, 45, 46, 47, 48};
+static const unsigned pxa320_uart0_func[] = {2, 2, 2, 2, 2, 2, 2, 2};
+/* not include SDATA_IN_1 */
+static const unsigned pxa320_ac97_pins[] = {34, 35, 37, 38, 39, 40};
+static const unsigned pxa320_ac97_func[] = {1, 1, 1, 1, 1, 1};
+static const unsigned pxa320_ssp3_pins[] = {89, 90, 91, 92};
+static const unsigned pxa320_ssp3_func[] = {1, 1, 1, 1};
+static const unsigned pxa320_i2c_pins[] = {32, 33};
+static const unsigned pxa320_i2c_func[] = {1, 1};
+/* DKIN[1:0], MKIN[7:0] & MKOUT[7:0] */
+static const unsigned pxa320_key_pins[] = {105, 106, 113, 114, 115, 116, 117,
+		118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 133};
+static const unsigned pxa320_key_func[] = {2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+		1, 1, 1, 1, 1, 1, 1, 1};
+static const unsigned pxa320_smc_pins[] = {4};
+static const unsigned pxa320_smc_func[] = {1};
+static const unsigned pxa320_mmc1_pins[] = {18, 19, 20, 21, 22, 23};
+static const unsigned pxa320_mmc1_func[] = {4, 4, 4, 4, 4, 4};
+static const unsigned pxa320_mmc2_pins[] = {24, 25, 26, 27, 28, 29};
+static const unsigned pxa320_mmc2_func[] = {4, 4, 4, 4, 4, 4};
+static const unsigned pxa320_usbh_pins[] = {130, 131};
+static const unsigned pxa320_usbh_func[] = {1, 1};
+static const unsigned pxa320_pwm3_pins[] = {14};
+static const unsigned pxa320_pwm3_func[] = {1};
+static const unsigned pxa320_usim_pins[] = {15, 17};
+static const unsigned pxa320_usim_func[] = {1};
+
+static struct pxa3xx_pin_group pxa320_pin_groups[] = {
+	{"lcd", pxa320_lcd_func, ARRAY_AND_SIZE(pxa320_lcd_pins)},
+	{"ffuart", pxa320_uart0_func, ARRAY_AND_SIZE(pxa320_uart0_pins)},
+	{"ac97", pxa320_ac97_func, ARRAY_AND_SIZE(pxa320_ac97_pins)},
+	{"ssp3", pxa320_ssp3_func, ARRAY_AND_SIZE(pxa320_ssp3_pins)},
+	{"i2c", pxa320_i2c_func, ARRAY_AND_SIZE(pxa320_i2c_pins)},
+	{"key", pxa320_key_func, ARRAY_AND_SIZE(pxa320_key_pins)},
+	{"smc", pxa320_smc_func, ARRAY_AND_SIZE(pxa320_smc_pins)},
+	{"mmc1", pxa320_mmc1_func, ARRAY_AND_SIZE(pxa320_mmc1_pins)},
+	{"mmc2", pxa320_mmc2_func, ARRAY_AND_SIZE(pxa320_mmc2_pins)},
+	{"usbh", pxa320_usbh_func, ARRAY_AND_SIZE(pxa320_usbh_pins)},
+	{"pwm3", pxa320_pwm3_func, ARRAY_AND_SIZE(pxa320_pwm3_pins)},
+	{"usim", pxa320_usim_func, ARRAY_AND_SIZE(pxa320_usim_pins)},
+};
+
+static const char * const pxa320_lcd_grps[] = {"lcd"};
+static const char * const pxa320_uart0_grps[] = {"ffuart"};
+static const char * const pxa320_ac97_grps[] = {"ac97"};
+static const char * const pxa320_ssp3_grps[] = {"ssp3"};
+static const char * const pxa320_i2c_grps[] = {"i2c"};
+static const char * const pxa320_key_grps[] = {"key"};
+static const char * const pxa320_smc_grps[] = {"smc"};
+static const char * const pxa320_mmc1_grps[] = {"mmc1"};
+static const char * const pxa320_mmc2_grps[] = {"mmc2"};
+static const char * const pxa320_usbh_grps[] = {"usbh"};
+static const char * const pxa320_pwm3_grps[] = {"pwm3"};
+static const char * const pxa320_usim_grps[] = {"usim"};
+
+static struct pxa3xx_pmx_func pxa320_pmx_functions[] = {
+	{"lcd",		ARRAY_AND_SIZE(pxa320_lcd_grps)},
+	{"uart0",	ARRAY_AND_SIZE(pxa320_uart0_grps)},
+	{"ac97",	ARRAY_AND_SIZE(pxa320_ac97_grps)},
+	{"ssp3",	ARRAY_AND_SIZE(pxa320_ssp3_grps)},
+	{"i2c",		ARRAY_AND_SIZE(pxa320_i2c_grps)},
+	{"key",		ARRAY_AND_SIZE(pxa320_key_grps)},
+	{"smc",		ARRAY_AND_SIZE(pxa320_smc_grps)},
+	{"mmc1",	ARRAY_AND_SIZE(pxa320_mmc1_grps)},
+	{"mmc2",	ARRAY_AND_SIZE(pxa320_mmc2_grps)},
+	{"usbh",	ARRAY_AND_SIZE(pxa320_usbh_grps)},
+	{"pwm3",	ARRAY_AND_SIZE(pxa320_pwm3_grps)},
+	{"usim",	ARRAY_AND_SIZE(pxa320_usim_grps)},
+};
+#endif
+
+#ifdef CONFIG_ARCH_MMP
+static struct pinctrl_pin_desc pxa910_pads[] = {
+	PXA3XX_COMMON_PINS(),
+};
+
+const static unsigned pxa910_mfpr[] = {
+	0x0DC, 0x0E0, 0x0E4, 0x0E8, 0x0EC, 0x0F0, 0x0F4, 0x0F8, 0x0FC, 0x100,
+	0x104, 0x108, 0x10C, 0x110, 0x114, 0x118, 0x11C, 0x120, 0x124, 0x128,
+	0x12C, 0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C, 0x150,
+	0x154, 0x158, 0x15C, 0x160, 0x164, 0x168, 0x16C, 0x170, 0x174, 0x178,
+	0x17C, 0x180, 0x184, 0x188, 0x18C, 0x190, 0x194, 0x198, 0x19C, 0x1A0,
+	0x1A4, 0x1A8, 0x1AC, 0x1B0, 0x1B4, 0x2F0, 0x2F4, 0x2F8, 0x2FC, 0x300,
+	0x304, 0x308, 0x30C, 0x310, 0x314, 0x318, 0x31C, 0x1B8, 0x1BC, 0x1C0,
+	0x1C4, 0x1C8, 0x1CC, 0x1D0, 0x1D4, 0x1D8, 0x1DC, 0x1E0, 0x1E4, 0x1E8,
+	0x1EC, 0x1F0, 0x1F4, 0x1F8, 0x1FC, 0x200, 0x204, 0x208, 0x20C, 0x210,
+	0x214, 0x218, 0x21C, 0x220, 0x224, 0x228, 0x22C, 0x230, 0x234, 0x0B0,
+	0x238, 0x23C, 0x240, 0x244, 0x248, 0x24C, 0x250, 0x254, 0x258, 0x25C,
+	0x298, 0x29C, 0x2A0, 0x2A4, 0x2A8, 0x2AC, 0x2B0, 0x0B4, 0x0B8, 0x0BC,
+	0x0C0, 0x32C, 0x0C8, 0x0CC, 0x0D0, 0x0D4, 0x06C, 0x070,
+};
+
+static const unsigned pxa910_uart2_pins[] = {47, 48};
+static const unsigned pxa910_uart2_func[] = {6, 6};
+
+static struct pxa3xx_pin_group pxa910_pin_groups[] = {
+	{"uart2", pxa910_uart2_func, ARRAY_AND_SIZE(pxa910_uart2_pins)},
+};
+
+static const char * const pxa910_uart2_grps[] = {"uart2"};
+
+static struct pxa3xx_pmx_func pxa910_pmx_functions[] = {
+	{"uart2",	ARRAY_AND_SIZE(pxa910_uart2_grps)},
+};
+#endif
+
+static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (selector > info->num_grps)
+		return -EINVAL;
+	return 0;
+}
+
+static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
+					 unsigned selector)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (selector >= info->num_grps)
+		return NULL;
+	return info->grp[selector].name;
+}
+
+static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev,
+				 unsigned selector,
+				 const unsigned **pins,
+				 unsigned *num_pins)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (selector > info->num_grps)
+		return -EINVAL;
+	*pins = info->grp[selector].pins;
+	*num_pins = info->grp[selector].num_pins;
+	return 0;
+}
+
+static struct pinctrl_ops pxa3xx_pctrl_ops = {
+	.list_groups	= pxa3xx_list_groups,
+	.get_group_name	= pxa3xx_get_group_name,
+	.get_group_pins	= pxa3xx_get_group_pins,
+};
+
+static int pxa3xx_get_gpio_func(unsigned int cpuid, unsigned int gpio)
+{
+	int ret = 0;
+
+	switch (cpuid) {
+#ifdef CONFIG_ARCH_PXA
+	case PINMUX_PXA300:
+	case PINMUX_PXA310:
+		if (gpio == 50)
+			ret = 2;
+		else if (gpio == 49 || gpio == 51 || gpio == 53)
+			ret = 3;
+		break;
+	case PINMUX_PXA320:
+		if (gpio == 56 || (gpio > 58 && gpio < 63))
+			goto out;
+		break;
+#endif
+#ifdef CONFIG_ARCH_MMP
+	case PINMUX_PXA910:
+		if ((gpio > 116 && gpio < 121) || gpio == 122 || gpio == 123 ||
+			gpio == 125 || gpio == 99 || gpio == 58 || gpio == 59)
+			ret = 1;
+		break;
+#endif
+	default:
+		goto out;
+	}
+	return ret & MFPR_FUNC;
+out:
+	return -1;
+}
+
+static int pxa3xx_get_mfpr(unsigned int cpuid, unsigned int pin)
+{
+	int ret;
+	switch (cpuid) {
+#ifdef CONFIG_ARCH_PXA
+	case PINMUX_PXA300:
+		if (pin > ARRAY_SIZE(pxa300_mfpr))
+			goto out;
+		ret = pxa300_mfpr[pin];
+		break;
+	case PINMUX_PXA310:
+		if (pin > ARRAY_SIZE(pxa310_mfpr))
+			goto out;
+		ret = pxa310_mfpr[pin];
+		break;
+	case PINMUX_PXA320:
+		if (pin > ARRAY_SIZE(pxa320_mfpr))
+			goto out;
+		ret = pxa320_mfpr[pin];
+		break;
+#endif
+#ifdef CONFIG_ARCH_MMP
+	case PINMUX_PXA910:
+		if (pin > ARRAY_SIZE(pxa910_mfpr))
+			goto out;
+		ret = pxa910_mfpr[pin];
+#endif
+	default:
+		goto out;
+	}
+	return ret;
+out:
+	return -EINVAL;
+}
+
+static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
+			       struct pinctrl_gpio_range *range,
+			       unsigned pin)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	unsigned int data;
+	int mfpr, pin_func, gpio;
+
+	/* convert pin to gpio */
+	gpio = pin - range->pin_base + range->base;
+	pin_func = pxa3xx_get_gpio_func(info->cpuid, gpio);
+	if (pin_func < 0)
+		goto out;
+	mfpr = pxa3xx_get_mfpr(info->cpuid, pin);
+	if (mfpr < 0)
+		goto out;
+
+	/* write gpio function into mfpr register */
+	data = readl_relaxed(info->virt_base + mfpr) & MFPR_FUNC_MASK;
+	data |= pin_func;
+	writel_relaxed(data, info->virt_base + mfpr);
+	return 0;
+out:
+	return -EINVAL;
+}
+
+static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func,
+			     unsigned group)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	struct pxa3xx_pin_group *pin_grp = &info->grp[group];
+	unsigned int data, pin_func;
+	int i, mfpr;
+
+	for (i = 0; i < pin_grp->num_pins; i++) {
+		mfpr = pxa3xx_get_mfpr(info->cpuid, pin_grp->pins[i]);
+		if (mfpr < 0) {
+			dev_err(info->dev, "error pin:%d mfpr offset:%x\n",
+				pin_grp->pins[i], mfpr);
+			goto out;
+		}
+		pin_func = pin_grp->func[i];
+		data = readl_relaxed(info->virt_base + mfpr);
+	        data &= MFPR_FUNC_MASK;
+		data |= pin_func;
+		writel_relaxed(data, info->virt_base + mfpr);
+	}
+	return 0;
+out:
+	return -EINVAL;
+}
+
+static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func,
+			       unsigned group)
+{
+}
+
+static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (func > info->num_funcs)
+		return -EINVAL;
+	return 0;
+}
+
+static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
+					    unsigned func)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	return info->func[func].name;
+}
+
+static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func,
+				 const char * const **groups,
+				 unsigned * const num_groups)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	*groups = info->func[func].groups;
+	*num_groups = info->func[func].num_groups;
+	return 0;
+}
+
+static struct pinmux_ops pxa3xx_pmx_ops = {
+	.list_functions		= pxa3xx_pmx_list_func,
+	.get_function_name	= pxa3xx_pmx_get_func_name,
+	.get_function_groups	= pxa3xx_pmx_get_groups,
+	.enable			= pxa3xx_pmx_enable,
+	.disable		= pxa3xx_pmx_disable,
+	.gpio_request_enable	= pxa3xx_pmx_request_gpio,
+};
+
+#ifdef CONFIG_ARCH_PXA
+static struct pinctrl_desc pxa300_pctrl_desc = {
+	.name		= "pxa300-pinctrl",
+	.pins		= pxa300_pads,
+	.npins		= ARRAY_SIZE(pxa300_pads),
+	.maxpin		= 260,
+	.pctlops	= &pxa3xx_pctrl_ops,
+	.pmxops		= &pxa3xx_pmx_ops,
+	.owner		= THIS_MODULE,
+};
+
+static struct pinctrl_desc pxa310_pctrl_desc = {
+	.name		= "pxa310-pinctrl",
+	.pins		= pxa310_pads,
+	.npins		= ARRAY_SIZE(pxa310_pads),
+	.maxpin		= 260,
+	.pctlops	= &pxa3xx_pctrl_ops,
+	.pmxops		= &pxa3xx_pmx_ops,
+	.owner		= THIS_MODULE,
+};
+
+static struct pinctrl_desc pxa320_pctrl_desc = {
+	.name		= "pxa320-pinctrl",
+	.pins		= pxa320_pads,
+	.npins		= ARRAY_SIZE(pxa320_pads),
+	.maxpin		= 260,
+	.pctlops	= &pxa3xx_pctrl_ops,
+	.pmxops		= &pxa3xx_pmx_ops,
+	.owner		= THIS_MODULE,
+};
+
+static struct pinctrl_gpio_range pxa300_gpio_ranges[] = {
+	{
+		.name		= "gpio",
+		.id		= 0,
+		.base		= 0,
+		.pin_base	= 0,
+		.npins		= 128,
+	}, {
+		.name		= "gpio",
+		.id		= 1,
+		.base		= 0,
+		.pin_base	= 128,
+		.npins		= 7,
+	},
+};
+
+static struct pinctrl_gpio_range pxa310_gpio_ranges[] = {
+	{
+		.name		= "gpio",
+		.id		= 0,
+		.base		= 0,
+		.pin_base	= 0,
+		.npins		= 128,
+	}, {
+		.name		= "gpio",
+		.id		= 1,
+		.base		= 0,
+		.pin_base	= 128,
+		.npins		= 11,
+	},
+};
+
+static struct pinctrl_gpio_range pxa320_gpio_ranges[] = {
+	{
+		.name		= "gpio",
+		.id		= 0,
+		.base		= 0,
+		.pin_base	= 0,
+		.npins		= 128,
+	}, {
+		.name		= "gpio",
+		.id		= 1,
+		.base		= 0,
+		.pin_base	= 128,
+		.npins		= 18,
+	},
+};
+#endif
+
+#ifdef CONFIG_ARCH_MMP
+static struct pinctrl_desc pxa910_pctrl_desc = {
+	.name		= "pxa910-pinctrl",
+	.pins		= pxa910_pads,
+	.npins		= ARRAY_SIZE(pxa910_pads),
+	.maxpin		= 260,
+	.pctlops	= &pxa3xx_pctrl_ops,
+	.pmxops		= &pxa3xx_pmx_ops,
+	.owner		= THIS_MODULE,
+};
+
+static struct pinctrl_gpio_range pxa910_gpio_ranges[] = {
+	{
+		.name		= "gpio",
+		.id		= 0,
+		.base		= 0,
+		.pin_base	= 0,
+		.npins		= 128,
+	},
+};
+#endif
+
+static int __devinit pxa3xx_pinmux_probe(struct platform_device *pdev)
+{
+	struct pxa3xx_pinmux_info *info;
+	struct pinctrl_gpio_range *range = NULL;
+	struct resource *res;
+	int ret, i, range_num;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		return -ENOENT;
+	}
+	info = devm_kzalloc(&pdev->dev, sizeof(struct pxa3xx_pinmux_info),
+			GFP_KERNEL);
+	if (!info) {
+		return -ENOMEM;
+	}
+	info->phy_base = res->start;
+	info->phy_size = resource_size(res);
+	info->virt_base = ioremap(info->phy_base, info->phy_size);
+	if (!info->virt_base) {
+		ret = -ENOMEM;
+		goto out_remap;
+	}
+#ifdef CONFIG_ARCH_PXA
+	if (cpu_is_pxa300()) {
+		info->cpuid = PINMUX_PXA300;
+		info->grp = pxa300_pin_groups;
+		info->func = pxa300_pmx_functions;
+		info->num_grps = ARRAY_SIZE(pxa300_pin_groups);
+		info->num_funcs = ARRAY_SIZE(pxa300_pmx_functions);
+		info->pctl = pinctrl_register(&pxa300_pctrl_desc, &pdev->dev,
+				info);
+		range = pxa300_gpio_ranges;
+		range_num = ARRAY_SIZE(pxa300_gpio_ranges);
+	} else if (cpu_is_pxa310()) {
+		info->cpuid = PINMUX_PXA310;
+		info->grp = pxa310_pin_groups;
+		info->func = pxa310_pmx_functions;
+		info->num_grps = ARRAY_SIZE(pxa310_pin_groups);
+		info->num_funcs = ARRAY_SIZE(pxa310_pmx_functions);
+		info->pctl = pinctrl_register(&pxa310_pctrl_desc, &pdev->dev,
+				info);
+		range = pxa310_gpio_ranges;
+		range_num = ARRAY_SIZE(pxa310_gpio_ranges);
+	} else if (cpu_is_pxa320()) {
+		info->cpuid = PINMUX_PXA320;
+		info->grp = pxa320_pin_groups;
+		info->func = pxa320_pmx_functions;
+		info->num_grps = ARRAY_SIZE(pxa320_pin_groups);
+		info->num_funcs = ARRAY_SIZE(pxa320_pmx_functions);
+		info->pctl = pinctrl_register(&pxa320_pctrl_desc, &pdev->dev,
+				info);
+		range = pxa320_gpio_ranges;
+		range_num = ARRAY_SIZE(pxa320_gpio_ranges);
+	}
+#endif
+#ifdef CONFIG_ARCH_MMP
+	if (cpu_is_pxa910()) {
+		info->cpuid = PINMUX_PXA910;
+		info->grp = pxa910_pin_groups;
+		info->func = pxa910_pmx_functions;
+		info->num_grps = ARRAY_SIZE(pxa910_pin_groups);
+		info->num_funcs = ARRAY_SIZE(pxa910_pmx_functions);
+		info->pctl = pinctrl_register(&pxa910_pctrl_desc, &pdev->dev,
+				info);
+		range = pxa910_gpio_ranges;
+		range_num = ARRAY_SIZE(pxa910_gpio_ranges);
+	}
+#endif
+	if (!info->pctl) {
+		dev_err(&pdev->dev, "failed to register PXA pinmux driver\n");
+		ret = -EINVAL;
+		goto out_pctrl;
+	}
+	for (i = 0; i < range_num; i++)
+		pinctrl_add_gpio_range(info->pctl, &range[0]);
+	platform_set_drvdata(pdev, info);
+	return 0;
+out_pctrl:
+	release_mem_region(info->phy_base, info->phy_size);
+out_remap:
+	devm_kfree(&pdev->dev, info);
+	return ret;
+}
+
+static int __devexit pxa3xx_pinmux_remove(struct platform_device *pdev)
+{
+	struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(info->pctl);
+	iounmap(info->virt_base);
+	platform_set_drvdata(pdev, NULL);
+	devm_kfree(&pdev->dev, info);
+	return 0;
+}
+
+static struct platform_driver pxa3xx_pinmux_driver = {
+	.driver = {
+		.name = "pxa3xx-pinmux",
+		.owner = THIS_MODULE,
+	},
+	.probe = pxa3xx_pinmux_probe,
+	.remove = __devexit_p(pxa3xx_pinmux_remove),
+};
+
+static int __init pxa3xx_pinmux_init(void)
+{
+	return platform_driver_register(&pxa3xx_pinmux_driver);
+}
+postcore_initcall(pxa3xx_pinmux_init);
+
+static void __exit pxa3xx_pinmux_exit(void)
+{
+	platform_driver_unregister(&pxa3xx_pinmux_driver);
+}
+module_exit(pxa3xx_pinmux_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("PXA pin control driver");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4

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

* [PATCH 2/7] gpio: make pxa gpio depend on pinmux
  2011-11-25 23:08 [PATCH 0/7] pinctrl: enable pxa pinmux Haojian Zhuang
  2011-11-25 23:08 ` [PATCH 1/7] pinctrl: enable pxa3xx pinmux Haojian Zhuang
@ 2011-11-25 23:08 ` Haojian Zhuang
  2011-11-28  9:09   ` Linus Walleij
  2011-11-25 23:09 ` [PATCH 3/7] ARM: pxa: enable pinmux in pxa pwm Haojian Zhuang
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-25 23:08 UTC (permalink / raw)
  To: linux-arm-kernel

From: Haojian Zhuang <hzhuang1@hexinfolabs.org>

While gpio_request() is called, pinmux_request_gpio() would be called
too. Then alternate function of pin can be changed to gpio directly.

Signed-off-by: Haojian Zhuang <hzhuang1@hexinfolabs.org>
---
 drivers/gpio/gpio-pxa.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index b2d3ee1..8808004 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -19,6 +19,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/pinctrl/pinmux.h>
 #include <linux/syscore_ops.h>
 #include <linux/slab.h>
 
@@ -267,6 +268,16 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 				(value ? GPSR_OFFSET : GPCR_OFFSET));
 }
 
+static int pxa_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	return pinmux_request_gpio(chip->base + offset);
+}
+
+static void pxa_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pinmux_free_gpio(chip->base + offset);
+}
+
 static int __devinit pxa_init_gpio_chip(int gpio_end)
 {
 	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
@@ -292,6 +303,8 @@ static int __devinit pxa_init_gpio_chip(int gpio_end)
 		c->get = pxa_gpio_get;
 		c->set = pxa_gpio_set;
 		c->to_irq = pxa_gpio_to_irq;
+		c->request = pxa_gpio_request;
+		c->free = pxa_gpio_free;
 
 		/* number of GPIOs on last bank may be less than 32 */
 		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
@@ -612,4 +625,4 @@ static int __init pxa_gpio_sysinit(void)
 	register_syscore_ops(&pxa_gpio_syscore_ops);
 	return 0;
 }
-postcore_initcall(pxa_gpio_sysinit);
+postcore_initcall_sync(pxa_gpio_sysinit);
-- 
1.7.0.4

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

* [PATCH 3/7] ARM: pxa: enable pinmux in pxa pwm
  2011-11-25 23:08 [PATCH 0/7] pinctrl: enable pxa pinmux Haojian Zhuang
  2011-11-25 23:08 ` [PATCH 1/7] pinctrl: enable pxa3xx pinmux Haojian Zhuang
  2011-11-25 23:08 ` [PATCH 2/7] gpio: make pxa gpio depend on pinmux Haojian Zhuang
@ 2011-11-25 23:09 ` Haojian Zhuang
  2011-11-28  9:18   ` Linus Walleij
  2011-11-25 23:09 ` [PATCH 4/7] tty: serial: support pinmux in pxa serial Haojian Zhuang
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-25 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Haojian Zhuang <hzhuang1@hexinfolabs.org>

Add pinmux operations in pxa pwm driver.

Signed-off-by: Haojian Zhuang <hzhuang1@hexinfolabs.org>
---
 arch/arm/plat-pxa/pwm.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c
index ef32686..93c0986 100644
--- a/arch/arm/plat-pxa/pwm.c
+++ b/arch/arm/plat-pxa/pwm.c
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/pinctrl/pinmux.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
@@ -47,6 +48,7 @@ struct pwm_device {
 	struct list_head	node;
 	struct pwm_device	*secondary;
 	struct platform_device	*pdev;
+	struct pinmux		*pmx;
 
 	const char	*label;
 	struct clk	*clk;
@@ -187,10 +189,16 @@ static int __devinit pwm_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	pwm->pmx = pinmux_get(&pdev->dev, NULL);
+	if (IS_ERR(pwm->pmx)) {
+		ret = PTR_ERR(pwm->pmx);
+		goto err_free;
+	}
+	pinmux_enable(pwm->pmx);
 	pwm->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(pwm->clk)) {
 		ret = PTR_ERR(pwm->clk);
-		goto err_free;
+		goto err_free_pwm;
 	}
 	pwm->clk_enabled = 0;
 
@@ -245,6 +253,9 @@ err_free_mem:
 	release_mem_region(r->start, resource_size(r));
 err_free_clk:
 	clk_put(pwm->clk);
+err_free_pwm:
+	pinmux_disable(pwm->pmx);
+	pinmux_put(pwm->pmx);
 err_free:
 	kfree(pwm);
 	return ret;
@@ -275,6 +286,8 @@ static int __devexit pwm_remove(struct platform_device *pdev)
 	release_mem_region(r->start, resource_size(r));
 
 	clk_put(pwm->clk);
+	pinmux_disable(pwm->pmx);
+	pinmux_put(pwm->pmx);
 	kfree(pwm);
 	return 0;
 }
-- 
1.7.0.4

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

* [PATCH 4/7] tty: serial: support pinmux in pxa serial
  2011-11-25 23:08 [PATCH 0/7] pinctrl: enable pxa pinmux Haojian Zhuang
                   ` (2 preceding siblings ...)
  2011-11-25 23:09 ` [PATCH 3/7] ARM: pxa: enable pinmux in pxa pwm Haojian Zhuang
@ 2011-11-25 23:09 ` Haojian Zhuang
  2011-11-28  9:15   ` Linus Walleij
  2011-11-25 23:09 ` [PATCH 5/7] fb: pxa: support pinmux operation Haojian Zhuang
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-25 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Haojian Zhuang <hzhuang1@hexinfolabs.org>

PXA serial driver can configure pin directly.

Signed-off-by: Haojian Zhuang <hzhuang1@hexinfolabs.org>
---
 drivers/tty/serial/pxa.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c
index 5c8e3bb..98df48d 100644
--- a/drivers/tty/serial/pxa.c
+++ b/drivers/tty/serial/pxa.c
@@ -37,6 +37,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/pinctrl/pinmux.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
@@ -51,6 +52,7 @@ struct uart_pxa_port {
 	unsigned char           mcr;
 	unsigned int            lsr_break_flag;
 	struct clk		*clk;
+	struct pinmux		*pmx;
 	char			*name;
 };
 
@@ -802,6 +804,13 @@ static int serial_pxa_probe(struct platform_device *dev)
 		goto err_free;
 	}
 
+	sport->pmx = pinmux_get(&dev->dev, NULL);
+	if (IS_ERR(sport->pmx)) {
+		ret = PTR_ERR(sport->pmx);
+		goto err_clk;
+	}
+	pinmux_enable(sport->pmx);
+
 	sport->port.type = PORT_PXA;
 	sport->port.iotype = UPIO_MEM;
 	sport->port.mapbase = mmres->start;
@@ -826,7 +835,7 @@ static int serial_pxa_probe(struct platform_device *dev)
 	sport->port.membase = ioremap(mmres->start, resource_size(mmres));
 	if (!sport->port.membase) {
 		ret = -ENOMEM;
-		goto err_clk;
+		goto err_pmx;
 	}
 
 	serial_pxa_ports[dev->id] = sport;
@@ -836,6 +845,9 @@ static int serial_pxa_probe(struct platform_device *dev)
 
 	return 0;
 
+ err_pmx:
+	pinmux_disable(sport->pmx);
+	pinmux_put(sport->pmx);
  err_clk:
 	clk_put(sport->clk);
  err_free:
@@ -851,6 +863,8 @@ static int serial_pxa_remove(struct platform_device *dev)
 
 	uart_remove_one_port(&serial_pxa_reg, &sport->port);
 	clk_put(sport->clk);
+	pinmux_disable(sport->pmx);
+	pinmux_put(sport->pmx);
 	kfree(sport);
 
 	return 0;
-- 
1.7.0.4

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

* [PATCH 5/7] fb: pxa: support pinmux operation
  2011-11-25 23:08 [PATCH 0/7] pinctrl: enable pxa pinmux Haojian Zhuang
                   ` (3 preceding siblings ...)
  2011-11-25 23:09 ` [PATCH 4/7] tty: serial: support pinmux in pxa serial Haojian Zhuang
@ 2011-11-25 23:09 ` Haojian Zhuang
  2011-11-28  9:19   ` Linus Walleij
  2011-11-25 23:09 ` [PATCH 6/7] ARM: pxa: enable pinmux mapping in zylonite Haojian Zhuang
  2011-11-25 23:09 ` [PATCH 7/7] ARM: mmp: enable pinmux on ttc dkb Haojian Zhuang
  6 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-25 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
---
 drivers/video/pxafb.c |   10 ++++++++++
 drivers/video/pxafb.h |    1 +
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 1d1e4f1..af5f618 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -47,6 +47,7 @@
 #include <linux/ioport.h>
 #include <linux/cpufreq.h>
 #include <linux/platform_device.h>
+#include <linux/pinctrl/pinmux.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -1799,11 +1800,18 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
 	memset(fbi, 0, sizeof(struct pxafb_info));
 	fbi->dev = dev;
 
+	fbi->pmx = pinmux_get(dev, NULL);
+	if (IS_ERR(fbi->pmx)) {
+		kfree(fbi);
+		return NULL;
+	}
 	fbi->clk = clk_get(dev, NULL);
 	if (IS_ERR(fbi->clk)) {
+		pinmux_put(fbi->pmx);
 		kfree(fbi);
 		return NULL;
 	}
+	pinmux_enable(fbi->pmx);
 
 	strcpy(fbi->fb.fix.id, PXA_NAME);
 
@@ -2293,6 +2301,8 @@ static int __devexit pxafb_remove(struct platform_device *dev)
 	release_mem_region(r->start, resource_size(r));
 
 	clk_put(fbi->clk);
+	pinmux_disable(fbi->pmx);
+	pinmux_put(fbi->pmx);
 	kfree(fbi);
 
 	return 0;
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index 26ba9fa..d232816 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -110,6 +110,7 @@ struct pxafb_info {
 	struct fb_info		fb;
 	struct device		*dev;
 	struct clk		*clk;
+	struct pinmux		*pmx;
 
 	void __iomem		*mmio_base;
 
-- 
1.7.0.4

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

* [PATCH 6/7] ARM: pxa: enable pinmux mapping in zylonite
  2011-11-25 23:08 [PATCH 0/7] pinctrl: enable pxa pinmux Haojian Zhuang
                   ` (4 preceding siblings ...)
  2011-11-25 23:09 ` [PATCH 5/7] fb: pxa: support pinmux operation Haojian Zhuang
@ 2011-11-25 23:09 ` Haojian Zhuang
  2011-11-26  3:53   ` Arnd Bergmann
  2011-11-25 23:09 ` [PATCH 7/7] ARM: mmp: enable pinmux on ttc dkb Haojian Zhuang
  6 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-25 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

Remove MFP operation in zylonite. Use pinmux mapping instead.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
---
 arch/arm/mach-pxa/Kconfig                 |    1 +
 arch/arm/mach-pxa/devices.c               |   15 ++
 arch/arm/mach-pxa/devices.h               |    1 +
 arch/arm/mach-pxa/include/mach/zylonite.h |    2 +
 arch/arm/mach-pxa/pxa3xx.c                |    1 +
 arch/arm/mach-pxa/zylonite.c              |    6 +
 arch/arm/mach-pxa/zylonite_pxa300.c       |  298 +++++++++++------------------
 arch/arm/mach-pxa/zylonite_pxa320.c       |  211 +++++----------------
 8 files changed, 183 insertions(+), 352 deletions(-)

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 61d3c72..ea569ff 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -39,6 +39,7 @@ config MACH_ZYLONITE
 	bool
 	select PXA3xx
 	select HAVE_PWM
+	select PINCTRL
 
 config MACH_ZYLONITE300
 	bool "PXA3xx Development Platform (aka Zylonite) PXA300/310"
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 5bc1312..3302bed 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -946,6 +946,21 @@ struct platform_device pxa3xx_device_gcu = {
 	},
 };
 
+static struct resource pxa3xx_resources_pinmux[] = {
+	{
+		.start	= 0x40e10000,
+		.end	= 0x40e10fff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device pxa3xx_device_pinmux = {
+	.name		= "pxa3xx-pinmux",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(pxa3xx_resources_pinmux),
+	.resource	= pxa3xx_resources_pinmux,
+};
+
 #endif /* CONFIG_PXA3xx */
 
 #if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x)
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 1475db1..d440fbb 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -39,6 +39,7 @@ extern struct platform_device pxa3xx_device_nand;
 extern struct platform_device pxa3xx_device_i2c_power;
 
 extern struct platform_device pxa3xx_device_gcu;
+extern struct platform_device pxa3xx_device_pinmux;
 
 extern struct platform_device pxa_device_asoc_platform;
 extern struct platform_device pxa_device_asoc_ssp1;
diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h
index ecca976..70e5017 100644
--- a/arch/arm/mach-pxa/include/mach/zylonite.h
+++ b/arch/arm/mach-pxa/include/mach/zylonite.h
@@ -15,6 +15,8 @@ extern int gpio_debug_led1;
 extern int gpio_debug_led2;
 
 extern int wm9713_irq;
+extern int ac97_sdata1;
+extern int mmc1_cmd1;
 
 extern int lcd_id;
 extern int lcd_orientation;
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 4f402af..eea2cb6 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -435,6 +435,7 @@ static struct platform_device *devices[] __initdata = {
 	&pxa3xx_device_ssp4,
 	&pxa27x_device_pwm0,
 	&pxa27x_device_pwm1,
+	&pxa3xx_device_pinmux,
 };
 
 static int __init pxa3xx_init(void)
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 98eec80..13ddba0 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -41,6 +41,8 @@ int gpio_debug_led1;
 int gpio_debug_led2;
 
 int wm9713_irq;
+int ac97_sdata1;
+int mmc1_cmd1;
 
 int lcd_id;
 int lcd_orientation;
@@ -52,6 +54,7 @@ struct platform_device pxa_device_wm9713_audio = {
 
 static void __init zylonite_init_wm9713_audio(void)
 {
+	gpio_request_one(wm9713_irq, GPIOF_DIR_IN, "wm9713 irq");
 	platform_device_register(&pxa_device_wm9713_audio);
 }
 
@@ -253,6 +256,7 @@ static struct pxamci_platform_data zylonite_mci3_platform_data = {
 
 static void __init zylonite_init_mmc(void)
 {
+	gpio_request_one(mmc1_cmd1, GPIOF_DIR_IN, "mmc1 CDM1");
 	pxa_set_mci_info(&zylonite_mci_platform_data);
 	pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
 	if (cpu_is_pxa310())
@@ -408,10 +412,12 @@ static void __init zylonite_init(void)
 	 * Note: We depend that the bootloader set
 	 * the correct value to MSC register for SMC91x.
 	 */
+	gpio_request_one(gpio_eth_irq, GPIOF_DIR_IN, "eth irq");
 	smc91x_resources[1].start = PXA_GPIO_TO_IRQ(gpio_eth_irq);
 	smc91x_resources[1].end   = PXA_GPIO_TO_IRQ(gpio_eth_irq);
 	platform_device_register(&smc91x_device);
 
+	gpio_request_one(ac97_sdata1, GPIOF_DIR_IN, "SDATA_IN_1 not used");
 	pxa_set_ac97_info(NULL);
 	zylonite_init_lcd();
 	zylonite_init_mmc();
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index 86e59c0..02ccf35 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -20,202 +20,107 @@
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/gpio.h>
+#include <linux/pinctrl/machine.h>
 
 #include <mach/pxa300.h>
 #include <mach/zylonite.h>
 
 #include "generic.h"
 
-/* PXA300/PXA310 common configurations */
-static mfp_cfg_t common_mfp_cfg[] __initdata = {
-	/* LCD */
-	GPIO54_LCD_LDD_0,
-	GPIO55_LCD_LDD_1,
-	GPIO56_LCD_LDD_2,
-	GPIO57_LCD_LDD_3,
-	GPIO58_LCD_LDD_4,
-	GPIO59_LCD_LDD_5,
-	GPIO60_LCD_LDD_6,
-	GPIO61_LCD_LDD_7,
-	GPIO62_LCD_LDD_8,
-	GPIO63_LCD_LDD_9,
-	GPIO64_LCD_LDD_10,
-	GPIO65_LCD_LDD_11,
-	GPIO66_LCD_LDD_12,
-	GPIO67_LCD_LDD_13,
-	GPIO68_LCD_LDD_14,
-	GPIO69_LCD_LDD_15,
-	GPIO70_LCD_LDD_16,
-	GPIO71_LCD_LDD_17,
-	GPIO72_LCD_FCLK,
-	GPIO73_LCD_LCLK,
-	GPIO74_LCD_PCLK,
-	GPIO75_LCD_BIAS,
-	GPIO76_LCD_VSYNC,
-	GPIO127_LCD_CS_N,
-	GPIO20_PWM3_OUT,	/* backlight */
-
-	/* BTUART */
-	GPIO111_UART2_RTS,
-	GPIO112_UART2_RXD | MFP_LPM_EDGE_FALL,
-	GPIO113_UART2_TXD,
-	GPIO114_UART2_CTS | MFP_LPM_EDGE_BOTH,
-
-	/* STUART */
-	GPIO109_UART3_TXD,
-	GPIO110_UART3_RXD | MFP_LPM_EDGE_FALL,
-
-	/* AC97 */
-	GPIO23_AC97_nACRESET,
-	GPIO24_AC97_SYSCLK,
-	GPIO29_AC97_BITCLK,
-	GPIO25_AC97_SDATA_IN_0,
-	GPIO27_AC97_SDATA_OUT,
-	GPIO28_AC97_SYNC,
-	GPIO17_GPIO,	/* SDATA_IN_1 but unused - configure to GPIO */
-
-	/* SSP3 */
-	GPIO91_SSP3_SCLK,
-	GPIO92_SSP3_FRM,
-	GPIO93_SSP3_TXD,
-	GPIO94_SSP3_RXD,
-
-	/* WM9713 IRQ */
-	GPIO26_GPIO,
-
-	/* Keypad */
-	GPIO107_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
-	GPIO108_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
-	GPIO115_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
-	GPIO116_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
-	GPIO117_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
-	GPIO118_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
-	GPIO119_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
-	GPIO120_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
-	GPIO2_2_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
-	GPIO3_2_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
-	GPIO121_KP_MKOUT_0,
-	GPIO122_KP_MKOUT_1,
-	GPIO123_KP_MKOUT_2,
-	GPIO124_KP_MKOUT_3,
-	GPIO125_KP_MKOUT_4,
-	GPIO4_2_KP_MKOUT_5,
-	GPIO5_2_KP_MKOUT_6,
-	GPIO6_2_KP_MKOUT_7,
-
-	/* MMC1 */
-	GPIO3_MMC1_DAT0,
-	GPIO4_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
-	GPIO5_MMC1_DAT2,
-	GPIO6_MMC1_DAT3,
-	GPIO7_MMC1_CLK,
-	GPIO8_MMC1_CMD,	/* CMD0 for slot 0 */
-	GPIO15_GPIO,	/* CMD1 default as GPIO for slot 0 */
-
-	/* MMC2 */
-	GPIO9_MMC2_DAT0,
-	GPIO10_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
-	GPIO11_MMC2_DAT2,
-	GPIO12_MMC2_DAT3,
-	GPIO13_MMC2_CLK,
-	GPIO14_MMC2_CMD,
-
-	/* USB Host */
-	GPIO0_2_USBH_PEN,
-	GPIO1_2_USBH_PWR,
-
-	/* Standard I2C */
-	GPIO21_I2C_SCL,
-	GPIO22_I2C_SDA,
-
-	/* GPIO */
-	GPIO18_GPIO | MFP_PULL_HIGH,	/* GPIO Expander #0 INT_N */
-	GPIO19_GPIO | MFP_PULL_HIGH,	/* GPIO Expander #1 INT_N */
-};
-
-static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
-	/* FFUART */
-	GPIO30_UART1_RXD | MFP_LPM_EDGE_FALL,
-	GPIO31_UART1_TXD,
-	GPIO32_UART1_CTS,
-	GPIO37_UART1_RTS,
-	GPIO33_UART1_DCD,
-	GPIO34_UART1_DSR | MFP_LPM_EDGE_FALL,
-	GPIO35_UART1_RI,
-	GPIO36_UART1_DTR,
-
-	/* Ethernet */
-	GPIO2_nCS3,
-	GPIO99_GPIO,
+#define COMMON_PINMUX_MAP()					\
+	{							\
+		.name = "uart2",				\
+		.ctrl_dev_name = "pinctrl.0",			\
+		.function = "uart2",				\
+		.dev_name = "pxa2xx-uart.2",			\
+		.group = "stuart1",				\
+		.hog_on_boot = true,				\
+	}, {							\
+		.name = "key",					\
+		.ctrl_dev_name = "pinctrl.0",			\
+		.function = "key",				\
+		.dev_name = "pxa27x-keyboard",			\
+		.group = "key0",				\
+		.hog_on_boot = true,				\
+	}, {							\
+		.name = "mmc1",					\
+		.ctrl_dev_name = "pinctrl.0",			\
+		.function = "mmc1",				\
+		.group = "mmc1_0",				\
+		.hog_on_boot = true,				\
+	},							\
+	PINMUX_MAP_PRIMARY_SYS_HOG("mmc2", "mmc2"),		\
+	PINMUX_MAP_PRIMARY_SYS_HOG("usbh", "usbh"),		\
+	PINMUX_MAP_PRIMARY_SYS_HOG("ac97", "ac97"),		\
+	PINMUX_MAP_PRIMARY_SYS_HOG("smc", "smc"),		\
+	PINMUX_MAP_PRIMARY("pwm3", "pwm3", "pxa27x-pwm.1"),	\
+	PINMUX_MAP_PRIMARY("uart1", "uart1", "pxa2xx-uart.1"),	\
+	PINMUX_MAP_PRIMARY("ssp3", "ssp3", "pxa27x-ssp.2"),	\
+	PINMUX_MAP_PRIMARY("lcd", "lcd", "pxa2xx-fb"),		\
+	PINMUX_MAP_PRIMARY("i2c", "i2c", "pxa2xx-i2c.0")
+
+static struct pinmux_map pxa300_pmx_map[] = {
+	COMMON_PINMUX_MAP(),
+	{
+		.name = "uart0",
+		.ctrl_dev_name = "pinctrl.0",
+		.function = "uart0",
+		.dev_name = "pxa2xx-uart.0",
+		.group = "ffuart0",
+	},
 };
 
-static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
-	/* FFUART */
-	GPIO99_UART1_RXD | MFP_LPM_EDGE_FALL,
-	GPIO100_UART1_TXD,
-	GPIO101_UART1_CTS,
-	GPIO106_UART1_RTS,
-
-	/* Ethernet */
-	GPIO2_nCS3,
-	GPIO102_GPIO,
-
-	/* MMC3 */
-	GPIO7_2_MMC3_DAT0,
-	GPIO8_2_MMC3_DAT1 | MFP_LPM_EDGE_BOTH,
-	GPIO9_2_MMC3_DAT2,
-	GPIO10_2_MMC3_DAT3,
-	GPIO103_MMC3_CLK,
-	GPIO105_MMC3_CMD,
+static struct pinmux_map pxa310_pmx_map[] = {
+	COMMON_PINMUX_MAP(),
+	{
+		.name = "uart0",
+		.ctrl_dev_name = "pinctrl.0",
+		.function = "uart0",
+		.dev_name = "pxa2xx-uart.0",
+		.group = "ffuart2",
+	}, {
+		.name = "mmc3",
+		.ctrl_dev_name = "pinctrl.0",
+		.function = "mmc3",
+		.group = "mmc3",
+	},
 };
 
-#define NUM_LCD_DETECT_PINS	7
-
-static int lcd_detect_pins[] __initdata = {
-	MFP_PIN_GPIO71,	/* LCD_LDD_17 - ORIENT */
-	MFP_PIN_GPIO70, /* LCD_LDD_16 - LCDID[5] */
-	MFP_PIN_GPIO75, /* LCD_BIAS   - LCDID[4] */
-	MFP_PIN_GPIO73, /* LCD_LCLK   - LCDID[3] */
-	MFP_PIN_GPIO72, /* LCD_FCLK   - LCDID[2] */
-	MFP_PIN_GPIO127,/* LCD_CS_N   - LCDID[1] */
-	MFP_PIN_GPIO76, /* LCD_VSYNC  - LCDID[0] */
+static struct gpio detect_lcd_gpios[] = {
+	{71,  GPIOF_DIR_IN, "ORIENT"},
+	{70,  GPIOF_DIR_IN, "LCDID[5]"},
+	{75,  GPIOF_DIR_IN, "LCDID[4]"},
+	{73,  GPIOF_DIR_IN, "LCDID[3]"},
+	{72,  GPIOF_DIR_IN, "LCDID[2]"},
+	{127, GPIOF_DIR_IN, "LCDID[1]"},
+	{76,  GPIOF_DIR_IN, "LCDID[0]"},
 };
 
-static void __init zylonite_detect_lcd_panel(void)
+static int __init zylonite_detect_lcd_panel(void)
 {
-	unsigned long mfpr_save[NUM_LCD_DETECT_PINS];
-	int i, gpio, id = 0;
-
-	/* save the original MFP settings of these pins and configure
-	 * them as GPIO Input, DS01X, Pull Neither, Edge Clear
-	 */
-	for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
-		mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
-		pxa3xx_mfp_write(lcd_detect_pins[i], 0x8440);
-	}
-
-	for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
-		id = id << 1;
-		gpio = mfp_to_gpio(lcd_detect_pins[i]);
-		gpio_request(gpio, "LCD_ID_PINS");
-		gpio_direction_input(gpio);
-
-		if (gpio_get_value(gpio))
-			id = id | 0x1;
-		gpio_free(gpio);
+	int i, ret = 0, size, id = 0;
+
+	size = ARRAY_SIZE(detect_lcd_gpios);
+	ret = gpio_request_array(detect_lcd_gpios, size);
+	if (ret < 0)
+		goto out;
+	for (i = 0; i < size; i++) {
+		id <<= 1;
+		if (gpio_get_value(detect_lcd_gpios[i].gpio))
+			id |= 1;
 	}
+	gpio_free_array(detect_lcd_gpios, size);
 
 	/* lcd id, flush out bit 1 */
 	lcd_id = id & 0x3d;
 
 	/* lcd orientation, portrait or landscape */
 	lcd_orientation = (id >> 6) & 0x1;
-
-	/* restore the original MFP settings */
-	for (i = 0; i < NUM_LCD_DETECT_PINS; i++)
-		pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
+out:
+	return ret;
 }
 
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static struct pca953x_platform_data gpio_exp[] = {
 	[0] = {
@@ -240,8 +145,14 @@ static struct i2c_board_info zylonite_i2c_board_info[] = {
 	},
 };
 
+static struct gpio gpio_exp_pins[] = {
+	{18, GPIOF_DIR_IN, "gpio ex0"},
+	{19, GPIOF_DIR_IN, "gpio ex1"},
+};
+
 static void __init zylonite_init_i2c(void)
 {
+	gpio_request_array(ARRAY_AND_SIZE(gpio_exp_pins));
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(zylonite_i2c_board_info));
 }
@@ -251,30 +162,37 @@ static inline void zylonite_init_i2c(void) {}
 
 void __init zylonite_pxa300_init(void)
 {
-	if (cpu_is_pxa300() || cpu_is_pxa310()) {
-		/* initialize MFP */
-		pxa3xx_mfp_config(ARRAY_AND_SIZE(common_mfp_cfg));
+	int ret;
+	if (cpu_is_pxa300()) {
+		ret = pinmux_register_mappings(ARRAY_AND_SIZE(pxa300_pmx_map));
+		if (ret < 0)
+			goto out;
+		gpio_eth_irq = 99;
+	}
 
-		/* detect LCD panel */
-		zylonite_detect_lcd_panel();
+	if (cpu_is_pxa310()) {
+		ret = pinmux_register_mappings(ARRAY_AND_SIZE(pxa310_pmx_map));
+		if (ret < 0)
+			goto out;
+		gpio_eth_irq = 102;
+	}
 
+	if (cpu_is_pxa300() || cpu_is_pxa310()) {
+		ret = zylonite_detect_lcd_panel();
+		if (ret < 0)
+			goto out;
 		/* WM9713 IRQ */
-		wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO26);
+		wm9713_irq = 26;
+		ac97_sdata1 = 17;
+		mmc1_cmd1 = 15;
 
 		zylonite_init_i2c();
 	}
 
-	if (cpu_is_pxa300()) {
-		pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa300_mfp_cfg));
-		gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO99);
-	}
-
-	if (cpu_is_pxa310()) {
-		pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg));
-		gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102);
-	}
-
 	/* GPIOs for Debug LEDs */
 	gpio_debug_led1 = EXT_GPIO(25);
 	gpio_debug_led2 = EXT_GPIO(26);
+	return;
+out:
+	BUG();
 }
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
index 9942bac..61a47cd 100644
--- a/arch/arm/mach-pxa/zylonite_pxa320.c
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -17,199 +17,86 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
+#include <linux/pinctrl/machine.h>
 
 #include <mach/pxa320.h>
 #include <mach/zylonite.h>
 
 #include "generic.h"
 
-static mfp_cfg_t mfp_cfg[] __initdata = {
-	/* LCD */
-	GPIO6_2_LCD_LDD_0,
-	GPIO7_2_LCD_LDD_1,
-	GPIO8_2_LCD_LDD_2,
-	GPIO9_2_LCD_LDD_3,
-	GPIO10_2_LCD_LDD_4,
-	GPIO11_2_LCD_LDD_5,
-	GPIO12_2_LCD_LDD_6,
-	GPIO13_2_LCD_LDD_7,
-	GPIO63_LCD_LDD_8,
-	GPIO64_LCD_LDD_9,
-	GPIO65_LCD_LDD_10,
-	GPIO66_LCD_LDD_11,
-	GPIO67_LCD_LDD_12,
-	GPIO68_LCD_LDD_13,
-	GPIO69_LCD_LDD_14,
-	GPIO70_LCD_LDD_15,
-	GPIO71_LCD_LDD_16,
-	GPIO72_LCD_LDD_17,
-	GPIO73_LCD_CS_N,
-	GPIO74_LCD_VSYNC,
-	GPIO14_2_LCD_FCLK,
-	GPIO15_2_LCD_LCLK,
-	GPIO16_2_LCD_PCLK,
-	GPIO17_2_LCD_BIAS,
-	GPIO14_PWM3_OUT,	/* backlight */
-
-	/* FFUART */
-	GPIO41_UART1_RXD | MFP_LPM_EDGE_FALL,
-	GPIO42_UART1_TXD,
-	GPIO43_UART1_CTS,
-	GPIO44_UART1_DCD,
-	GPIO45_UART1_DSR | MFP_LPM_EDGE_FALL,
-	GPIO46_UART1_RI,
-	GPIO47_UART1_DTR,
-	GPIO48_UART1_RTS,
-
-	/* AC97 */
-	GPIO34_AC97_SYSCLK,
-	GPIO35_AC97_SDATA_IN_0,
-	GPIO37_AC97_SDATA_OUT,
-	GPIO38_AC97_SYNC,
-	GPIO39_AC97_BITCLK,
-	GPIO40_AC97_nACRESET,
-	GPIO36_GPIO,	/* SDATA_IN_1 but unused - configure to GPIO */
-
-	/* SSP3 */
-	GPIO89_SSP3_SCLK,
-	GPIO90_SSP3_FRM,
-	GPIO91_SSP3_TXD,
-	GPIO92_SSP3_RXD,
-
-	/* WM9713 IRQ */
-	GPIO15_GPIO,
-
-	/* I2C */
-	GPIO32_I2C_SCL,
-	GPIO33_I2C_SDA,
-
-	/* Keypad */
-	GPIO105_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
-	GPIO106_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
-	GPIO113_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
-	GPIO114_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
-	GPIO115_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
-	GPIO116_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
-	GPIO117_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
-	GPIO118_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
-	GPIO119_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
-	GPIO120_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
-	GPIO121_KP_MKOUT_0,
-	GPIO122_KP_MKOUT_1,
-	GPIO123_KP_MKOUT_2,
-	GPIO124_KP_MKOUT_3,
-	GPIO125_KP_MKOUT_4,
-	GPIO126_KP_MKOUT_5,
-	GPIO127_KP_MKOUT_6,
-	GPIO5_2_KP_MKOUT_7,
-
-	/* Ethernet */
-	GPIO4_nCS3,
-	GPIO90_GPIO,
-
-	/* MMC1 */
-	GPIO18_MMC1_DAT0,
-	GPIO19_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
-	GPIO20_MMC1_DAT2,
-	GPIO21_MMC1_DAT3,
-	GPIO22_MMC1_CLK,
-	GPIO23_MMC1_CMD,/* CMD0 for slot 0 */
-	GPIO31_GPIO,	/* CMD1 default as GPIO for slot 0 */
-
-	/* MMC2 */
-	GPIO24_MMC2_DAT0,
-	GPIO25_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
-	GPIO26_MMC2_DAT2,
-	GPIO27_MMC2_DAT3,
-	GPIO28_MMC2_CLK,
-	GPIO29_MMC2_CMD,
-
-	/* USB Host */
-	GPIO2_2_USBH_PEN,
-	GPIO3_2_USBH_PWR,
-
-	/* Debug LEDs */
-	GPIO1_2_GPIO | MFP_LPM_DRIVE_HIGH,
-	GPIO4_2_GPIO | MFP_LPM_DRIVE_HIGH,
+static struct pinmux_map pxa320_pmx_map[] = {
+	PINMUX_MAP_PRIMARY_SYS_HOG("mmc1", "mmc1"),
+	PINMUX_MAP_PRIMARY_SYS_HOG("mmc2", "mmc2"),
+	PINMUX_MAP_PRIMARY_SYS_HOG("usbh", "usbh"),
+	PINMUX_MAP_PRIMARY_SYS_HOG("ac97", "ac97"),
+	PINMUX_MAP_PRIMARY_SYS_HOG("smc", "smc"),
+	PINMUX_MAP_PRIMARY_SYS_HOG("usim", "usim"),
+	PINMUX_MAP_PRIMARY("lcd", "lcd", "pxa2xx-fb"),
+	PINMUX_MAP_PRIMARY("uart0", "uart0", "pxa27x-uart.0"),
+	PINMUX_MAP_PRIMARY("pwm3", "pwm3", "pxa27x-pwm.1"),
+	PINMUX_MAP_PRIMARY("ssp3", "ssp3", "pxa27x-ssp.2"),
+	PINMUX_MAP_PRIMARY("i2c", "i2c", "pxa2xx-i2c.0"),
 };
 
-#define NUM_LCD_DETECT_PINS	7
-
-static int lcd_detect_pins[] __initdata = {
-	MFP_PIN_GPIO72,   /* LCD_LDD_17 - ORIENT */
-	MFP_PIN_GPIO71,   /* LCD_LDD_16 - LCDID[5] */
-	MFP_PIN_GPIO17_2, /* LCD_BIAS   - LCDID[4] */
-	MFP_PIN_GPIO15_2, /* LCD_LCLK   - LCDID[3] */
-	MFP_PIN_GPIO14_2, /* LCD_FCLK   - LCDID[2] */
-	MFP_PIN_GPIO73,   /* LCD_CS_N   - LCDID[1] */
-	MFP_PIN_GPIO74,   /* LCD_VSYNC  - LCDID[0] */
-	/*
-	 * set the MFP_PIN_GPIO 14/15/17 to alternate function other than
-	 * GPIO to avoid input level confliction with 14_2, 15_2, 17_2
-	 */
-	MFP_PIN_GPIO14,
-	MFP_PIN_GPIO15,
-	MFP_PIN_GPIO17,
+static struct gpio detect_lcd_gpios[] = {
+	{72,  GPIOF_DIR_IN, "ORIENT"},
+	{71,  GPIOF_DIR_IN, "LCDID[5]"},
+	{145, GPIOF_DIR_IN, "LCDID[4]"},
+	{143, GPIOF_DIR_IN, "LCDID[3]"},
+	{142, GPIOF_DIR_IN, "LCDID[2]"},
+	{73,  GPIOF_DIR_IN, "LCDID[1]"},
+	{74,  GPIOF_DIR_IN, "LCDID[0]"},
 };
 
-static int lcd_detect_mfpr[] __initdata = {
-	/* AF0, DS 1X, Pull Neither, Edge Clear */
-	0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440,
-	0xc442, /* Backlight, Pull-Up, AF2 */
-	0x8445, /* AF5 */
-	0x8445, /* AF5 */
-};
-
-static void __init zylonite_detect_lcd_panel(void)
+static int __init zylonite_detect_lcd_panel(void)
 {
-	unsigned long mfpr_save[ARRAY_SIZE(lcd_detect_pins)];
-	int i, gpio, id = 0;
-
-	/* save the original MFP settings of these pins and configure them
-	 * as GPIO Input, DS01X, Pull Neither, Edge Clear
-	 */
-	for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++) {
-		mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
-		pxa3xx_mfp_write(lcd_detect_pins[i], lcd_detect_mfpr[i]);
-	}
-
-	for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
-		id = id << 1;
-		gpio = mfp_to_gpio(lcd_detect_pins[i]);
-		gpio_request(gpio, "LCD_ID_PINS");
-		gpio_direction_input(gpio);
-
-		if (gpio_get_value(gpio))
-			id = id | 0x1;
-		gpio_free(gpio);
+	int i, ret = 0, size, id = 0;
+
+	size = ARRAY_SIZE(detect_lcd_gpios);
+	ret = gpio_request_array(detect_lcd_gpios, size);
+	if (ret < 0)
+		goto out;
+	for (i = 0; i < size; i++) {
+		id <<= 1;
+		if (gpio_get_value(detect_lcd_gpios[i].gpio))
+			id |= 1;
 	}
+	gpio_free_array(detect_lcd_gpios, size);
 
 	/* lcd id, flush out bit 1 */
 	lcd_id = id & 0x3d;
 
 	/* lcd orientation, portrait or landscape */
 	lcd_orientation = (id >> 6) & 0x1;
-
-	/* restore the original MFP settings */
-	for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++)
-		pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
+out:
+	return ret;
 }
 
 void __init zylonite_pxa320_init(void)
 {
+	int ret;
 	if (cpu_is_pxa320()) {
-		/* initialize MFP */
-		pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg));
+		ret = pinmux_register_mappings(ARRAY_AND_SIZE(pxa320_pmx_map));
+		if (ret < 0)
+			goto out;
 
 		/* detect LCD panel */
 		zylonite_detect_lcd_panel();
 
 		/* GPIO pin assignment */
-		gpio_eth_irq	= mfp_to_gpio(MFP_PIN_GPIO9);
+		gpio_eth_irq	= 90;
+#if 0
+		/* FIXME: can't support additional gpio pins */
 		gpio_debug_led1	= mfp_to_gpio(MFP_PIN_GPIO1_2);
 		gpio_debug_led2	= mfp_to_gpio(MFP_PIN_GPIO4_2);
+#endif
 
 		/* WM9713 IRQ */
-		wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO15);
+		wm9713_irq = 15;
+		ac97_sdata1 = 36;
+		mmc1_cmd1 = 31;
 	}
+	return;
+out:
+	BUG();
 }
-- 
1.7.0.4

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

* [PATCH 7/7] ARM: mmp: enable pinmux on ttc dkb
  2011-11-25 23:08 [PATCH 0/7] pinctrl: enable pxa pinmux Haojian Zhuang
                   ` (5 preceding siblings ...)
  2011-11-25 23:09 ` [PATCH 6/7] ARM: pxa: enable pinmux mapping in zylonite Haojian Zhuang
@ 2011-11-25 23:09 ` Haojian Zhuang
  2011-11-28  9:22   ` Linus Walleij
  6 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-25 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

Remove MFP operation. Use pinmux mapping instead.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
---
 arch/arm/mach-mmp/Kconfig   |    1 +
 arch/arm/mach-mmp/ttc_dkb.c |   40 ++++++++++------------------------------
 2 files changed, 11 insertions(+), 30 deletions(-)

diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 323d4c9..bd67c38 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -33,6 +33,7 @@ config MACH_TAVOREVB
 config MACH_TTC_DKB
 	bool "Marvell's PXA910 TavorEVB Development Board"
 	select CPU_PXA910
+	select PINCTRL
 	help
 	  Say 'Y' here if you want to support the Marvell PXA910-based
 	  TTC_DKB Development Board.
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 5ac5d58..28d3cc8 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/pinctrl/machine.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/onenand.h>
@@ -22,7 +23,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <mach/addr-map.h>
-#include <mach/mfp-pxa910.h>
 #include <mach/pxa910.h>
 #include <mach/irqs.h>
 
@@ -40,34 +40,8 @@
  */
 #define TTCDKB_NR_IRQS		(IRQ_BOARD_START + 16 + 16 + 24)
 
-static unsigned long ttc_dkb_pin_config[] __initdata = {
-	/* UART2 */
-	GPIO47_UART2_RXD,
-	GPIO48_UART2_TXD,
-
-	/* DFI */
-	DF_IO0_ND_IO0,
-	DF_IO1_ND_IO1,
-	DF_IO2_ND_IO2,
-	DF_IO3_ND_IO3,
-	DF_IO4_ND_IO4,
-	DF_IO5_ND_IO5,
-	DF_IO6_ND_IO6,
-	DF_IO7_ND_IO7,
-	DF_IO8_ND_IO8,
-	DF_IO9_ND_IO9,
-	DF_IO10_ND_IO10,
-	DF_IO11_ND_IO11,
-	DF_IO12_ND_IO12,
-	DF_IO13_ND_IO13,
-	DF_IO14_ND_IO14,
-	DF_IO15_ND_IO15,
-	DF_nCS0_SM_nCS2_nCS0,
-	DF_ALE_SM_WEn_ND_ALE,
-	DF_CLE_SM_OEn_ND_CLE,
-	DF_WEn_DF_WEn,
-	DF_REn_DF_REn,
-	DF_RDY0_DF_RDY0,
+static struct pinmux_map ttc_dkb_pmx_map[] = {
+	PINMUX_MAP_PRIMARY("uart2", "uart2", "pxa2xx-uart.1"),
 };
 
 static struct mtd_partition ttc_dkb_onenand_partitions[] = {
@@ -145,14 +119,20 @@ static struct i2c_board_info ttc_dkb_i2c_info[] = {
 
 static void __init ttc_dkb_init(void)
 {
-	mfp_config(ARRAY_AND_SIZE(ttc_dkb_pin_config));
+	int ret;
 
+	ret = pinmux_register_mappings(ARRAY_AND_SIZE(ttc_dkb_pmx_map));
+	if (ret < 0)
+		goto out;
 	/* on-chip devices */
 	pxa910_add_uart(1);
 
 	/* off-chip devices */
 	pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info));
 	platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));
+	return;
+out:
+	BUG();
 }
 
 MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform")
-- 
1.7.0.4

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

* [PATCH 6/7] ARM: pxa: enable pinmux mapping in zylonite
  2011-11-25 23:09 ` [PATCH 6/7] ARM: pxa: enable pinmux mapping in zylonite Haojian Zhuang
@ 2011-11-26  3:53   ` Arnd Bergmann
  2011-11-26  4:45     ` Haojian Zhuang
  2011-11-28  9:32     ` Linus Walleij
  0 siblings, 2 replies; 32+ messages in thread
From: Arnd Bergmann @ 2011-11-26  3:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 25 November 2011, Haojian Zhuang wrote:
> Remove MFP operation in zylonite. Use pinmux mapping instead.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
> ---
>  arch/arm/mach-pxa/Kconfig                 |    1 +
>  arch/arm/mach-pxa/devices.c               |   15 ++
>  arch/arm/mach-pxa/devices.h               |    1 +
>  arch/arm/mach-pxa/include/mach/zylonite.h |    2 +
>  arch/arm/mach-pxa/pxa3xx.c                |    1 +
>  arch/arm/mach-pxa/zylonite.c              |    6 +
>  arch/arm/mach-pxa/zylonite_pxa300.c       |  298 +++++++++++------------------
>  arch/arm/mach-pxa/zylonite_pxa320.c       |  211 +++++----------------
>  8 files changed, 183 insertions(+), 352 deletions(-)

This looks quite nice overall, but there is one thing that made me wonder if there
should be a better way to express it:

> +#define COMMON_PINMUX_MAP()					\
> +	{							\
> +		.name = "uart2",				\
> +		.ctrl_dev_name = "pinctrl.0",			\
> +		.function = "uart2",				\
> +		.dev_name = "pxa2xx-uart.2",			\
> +		.group = "stuart1",				\
> +		.hog_on_boot = true,				\
> +	}, {							\
> +		.name = "key",					\
> +		.ctrl_dev_name = "pinctrl.0",			\
> +		.function = "key",				\
> +		.dev_name = "pxa27x-keyboard",			\
> +		.group = "key0",				\
> +		.hog_on_boot = true,				\
> +	}, {							\
> +		.name = "mmc1",					\
> +		.ctrl_dev_name = "pinctrl.0",			\
> +		.function = "mmc1",				\
> +		.group = "mmc1_0",				\
> +		.hog_on_boot = true,				\
> +	},							\
> +	PINMUX_MAP_PRIMARY_SYS_HOG("mmc2", "mmc2"),		\
> +	PINMUX_MAP_PRIMARY_SYS_HOG("usbh", "usbh"),		\
> +	PINMUX_MAP_PRIMARY_SYS_HOG("ac97", "ac97"),		\
> +	PINMUX_MAP_PRIMARY_SYS_HOG("smc", "smc"),		\
> +	PINMUX_MAP_PRIMARY("pwm3", "pwm3", "pxa27x-pwm.1"),	\
> +	PINMUX_MAP_PRIMARY("uart1", "uart1", "pxa2xx-uart.1"),	\
> +	PINMUX_MAP_PRIMARY("ssp3", "ssp3", "pxa27x-ssp.2"),	\
> +	PINMUX_MAP_PRIMARY("lcd", "lcd", "pxa2xx-fb"),		\
> +	PINMUX_MAP_PRIMARY("i2c", "i2c", "pxa2xx-i2c.0")
> +
> +static struct pinmux_map pxa300_pmx_map[] = {
> +	COMMON_PINMUX_MAP(),
> +	{
> +		.name = "uart0",
> +		.ctrl_dev_name = "pinctrl.0",
> +		.function = "uart0",
> +		.dev_name = "pxa2xx-uart.0",
> +		.group = "ffuart0",
> +	},
>  };

I think we should not be forced to use macros like this in order to extend a common
pinmux mapping. Unfortunately, I can't see an easy way to do it differently
with the pinmux core, but it might not be too late to extend the interfaces now.

I also noticed that the pinmux_map arrays are not marked __initdata, because
it gets referenced later. This means that in a kernel that supports many machines,
we also have to keep all pinmux configurations around at runtime.

Linus, what do you think about changing the pinmux_register_mappings function
to make a copy of the data in order to let the platform code mark the data as
__initdata, and to allow appending the maps at boot time so that the above
can become two arrays that are registered individually?

>  		/* GPIO pin assignment */
> -		gpio_eth_irq	= mfp_to_gpio(MFP_PIN_GPIO9);
> +		gpio_eth_irq	= 90;
> +#if 0
> +		/* FIXME: can't support additional gpio pins */
>  		gpio_debug_led1	= mfp_to_gpio(MFP_PIN_GPIO1_2);
>  		gpio_debug_led2	= mfp_to_gpio(MFP_PIN_GPIO4_2);
> +#endif

If I read this correctly, your comment here refers to a different aspect of the
same problem, not being able to amend the mapping at a later point.

	Arnd

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

* [PATCH 6/7] ARM: pxa: enable pinmux mapping in zylonite
  2011-11-26  3:53   ` Arnd Bergmann
@ 2011-11-26  4:45     ` Haojian Zhuang
  2011-11-28  9:32     ` Linus Walleij
  1 sibling, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-26  4:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 26, 2011 at 11:53 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 25 November 2011, Haojian Zhuang wrote:
>> Remove MFP operation in zylonite. Use pinmux mapping instead.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
>> ---
>> ?arch/arm/mach-pxa/Kconfig ? ? ? ? ? ? ? ? | ? ?1 +
>> ?arch/arm/mach-pxa/devices.c ? ? ? ? ? ? ? | ? 15 ++
>> ?arch/arm/mach-pxa/devices.h ? ? ? ? ? ? ? | ? ?1 +
>> ?arch/arm/mach-pxa/include/mach/zylonite.h | ? ?2 +
>> ?arch/arm/mach-pxa/pxa3xx.c ? ? ? ? ? ? ? ?| ? ?1 +
>> ?arch/arm/mach-pxa/zylonite.c ? ? ? ? ? ? ?| ? ?6 +
>> ?arch/arm/mach-pxa/zylonite_pxa300.c ? ? ? | ?298 +++++++++++------------------
>> ?arch/arm/mach-pxa/zylonite_pxa320.c ? ? ? | ?211 +++++----------------
>> ?8 files changed, 183 insertions(+), 352 deletions(-)
>
>
>> ? ? ? ? ? ? ? /* GPIO pin assignment */
>> - ? ? ? ? ? ? gpio_eth_irq ? ?= mfp_to_gpio(MFP_PIN_GPIO9);
>> + ? ? ? ? ? ? gpio_eth_irq ? ?= 90;
>> +#if 0
>> + ? ? ? ? ? ? /* FIXME: can't support additional gpio pins */
>> ? ? ? ? ? ? ? gpio_debug_led1 = mfp_to_gpio(MFP_PIN_GPIO1_2);
>> ? ? ? ? ? ? ? gpio_debug_led2 = mfp_to_gpio(MFP_PIN_GPIO4_2);
>> +#endif
>
> If I read this correctly, your comment here refers to a different aspect of the
> same problem, not being able to amend the mapping at a later point.
>
GPIO1, GPIO4, GPIO1_2, GPIO4_2 are four pads. Both GPIO1 and GPIO1_2
can be configured as GPIO1. It's same on GPIO4/GPIO4/2.

At here, we need to configure GPIO1_2 as GPIO1. It also means that we
need set GPIO1 as not gpio function automatically. In current pinmux
driver, one GPIO can only be routed to one pad. Now I don't have good
ideas on how to resolve this. Any comments are welcome.

Best Regards
Haojian

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-25 23:08 ` [PATCH 1/7] pinctrl: enable pxa3xx pinmux Haojian Zhuang
@ 2011-11-28  9:08   ` Linus Walleij
  2011-11-28  9:50     ` Haojian Zhuang
  2011-11-28 20:21   ` Stephen Warren
  2011-11-30 12:00   ` Linus Walleij
  2 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2011-11-28  9:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 26, 2011 at 12:08 AM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:

> Support PXA300/PXA310/PXA320/PXA910 pinmux.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>

Cool!

> +#ifdef CONFIG_ARCH_PXA
> +static struct pinctrl_pin_desc pxa300_pads[] = {
(...)

Ick, per-arch #ifdefs in the driver/ directory is not good. Can you arrange
for this to be #ifdef:ed up in your board file and passed in as platform
data instead of being defined here?

I know that the U300 driver defines all it's pins in the driver file,
but it only supports one single board on one single chipset and
is thus pretty fixed, nominally this kind of stuff should come from
the board file(s) or the device tree.

> +static int pxa3xx_get_gpio_func(unsigned int cpuid, unsigned int gpio)
> +{
> + ? ? ? int ret = 0;
> +
> + ? ? ? switch (cpuid) {
> +#ifdef CONFIG_ARCH_PXA
> + ? ? ? case PINMUX_PXA300:
> + ? ? ? case PINMUX_PXA310:
> + ? ? ? ? ? ? ? if (gpio == 50)
> + ? ? ? ? ? ? ? ? ? ? ? ret = 2;
> + ? ? ? ? ? ? ? else if (gpio == 49 || gpio == 51 || gpio == 53)
> + ? ? ? ? ? ? ? ? ? ? ? ret = 3;
> + ? ? ? ? ? ? ? break;
> + ? ? ? case PINMUX_PXA320:
> + ? ? ? ? ? ? ? if (gpio == 56 || (gpio > 58 && gpio < 63))
> + ? ? ? ? ? ? ? ? ? ? ? goto out;
> + ? ? ? ? ? ? ? break;
> +#endif
> +#ifdef CONFIG_ARCH_MMP
> + ? ? ? case PINMUX_PXA910:
> + ? ? ? ? ? ? ? if ((gpio > 116 && gpio < 121) || gpio == 122 || gpio == 123 ||
> + ? ? ? ? ? ? ? ? ? ? ? gpio == 125 || gpio == 99 || gpio == 58 || gpio == 59)
> + ? ? ? ? ? ? ? ? ? ? ? ret = 1;
> + ? ? ? ? ? ? ? break;
> +#endif

Do you need these #ifdef:s?

They need to go, one way or another.

Switching on cpuid is excellent, provided it's passed in from
the outside, the definitons of these cases should be available
anyway should they not.

#ifdef:in out for footprint or unused code paths on some platforms
should *not* be done, it creates more trouble than it solves, see
Documentation/SubmittingPatches section 2) #ifdefs are ugly.

> +static int pxa3xx_get_mfpr(unsigned int cpuid, unsigned int pin)
> +{
> + ? ? ? int ret;
> + ? ? ? switch (cpuid) {
> +#ifdef CONFIG_ARCH_PXA

Dito. Etc.

> +#ifdef CONFIG_ARCH_MMP
> +static struct pinctrl_desc pxa910_pctrl_desc = {
> +       .name           = "pxa910-pinctrl",
> +       .pins           = pxa910_pads,
> +       .npins          = ARRAY_SIZE(pxa910_pads),
> +       .maxpin         = 260,
> +       .pctlops        = &pxa3xx_pctrl_ops,
> +       .pmxops         = &pxa3xx_pmx_ops,
> +       .owner          = THIS_MODULE,
> +};

This is not good either. Get rid of all #ifdef

> +#ifdef CONFIG_ARCH_PXA
> + ? ? ? if (cpu_is_pxa300()) {
> + ? ? ? ? ? ? ? info->cpuid = PINMUX_PXA300;
> + ? ? ? ? ? ? ? info->grp = pxa300_pin_groups;
> + ? ? ? ? ? ? ? info->func = pxa300_pmx_functions;
> + ? ? ? ? ? ? ? info->num_grps = ARRAY_SIZE(pxa300_pin_groups);
> + ? ? ? ? ? ? ? info->num_funcs = ARRAY_SIZE(pxa300_pmx_functions);
> + ? ? ? ? ? ? ? info->pctl = pinctrl_register(&pxa300_pctrl_desc, &pdev->dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info);
> + ? ? ? ? ? ? ? range = pxa300_gpio_ranges;
> + ? ? ? ? ? ? ? range_num = ARRAY_SIZE(pxa300_gpio_ranges);
> + ? ? ? } else if (cpu_is_pxa310()) {
> + ? ? ? ? ? ? ? info->cpuid = PINMUX_PXA310;
> + ? ? ? ? ? ? ? info->grp = pxa310_pin_groups;
> + ? ? ? ? ? ? ? info->func = pxa310_pmx_functions;
> + ? ? ? ? ? ? ? info->num_grps = ARRAY_SIZE(pxa310_pin_groups);
> + ? ? ? ? ? ? ? info->num_funcs = ARRAY_SIZE(pxa310_pmx_functions);
> + ? ? ? ? ? ? ? info->pctl = pinctrl_register(&pxa310_pctrl_desc, &pdev->dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info);
> + ? ? ? ? ? ? ? range = pxa310_gpio_ranges;
> + ? ? ? ? ? ? ? range_num = ARRAY_SIZE(pxa310_gpio_ranges);
> + ? ? ? } else if (cpu_is_pxa320()) {
> + ? ? ? ? ? ? ? info->cpuid = PINMUX_PXA320;
> + ? ? ? ? ? ? ? info->grp = pxa320_pin_groups;
> + ? ? ? ? ? ? ? info->func = pxa320_pmx_functions;
> + ? ? ? ? ? ? ? info->num_grps = ARRAY_SIZE(pxa320_pin_groups);
> + ? ? ? ? ? ? ? info->num_funcs = ARRAY_SIZE(pxa320_pmx_functions);
> + ? ? ? ? ? ? ? info->pctl = pinctrl_register(&pxa320_pctrl_desc, &pdev->dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info);
> + ? ? ? ? ? ? ? range = pxa320_gpio_ranges;
> + ? ? ? ? ? ? ? range_num = ARRAY_SIZE(pxa320_gpio_ranges);
> + ? ? ? }
> +#endif
> +#ifdef CONFIG_ARCH_MMP
> + ? ? ? if (cpu_is_pxa910()) {
> + ? ? ? ? ? ? ? info->cpuid = PINMUX_PXA910;
> + ? ? ? ? ? ? ? info->grp = pxa910_pin_groups;
> + ? ? ? ? ? ? ? info->func = pxa910_pmx_functions;
> + ? ? ? ? ? ? ? info->num_grps = ARRAY_SIZE(pxa910_pin_groups);
> + ? ? ? ? ? ? ? info->num_funcs = ARRAY_SIZE(pxa910_pmx_functions);
> + ? ? ? ? ? ? ? info->pctl = pinctrl_register(&pxa910_pctrl_desc, &pdev->dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info);
> + ? ? ? ? ? ? ? range = pxa910_gpio_ranges;
> + ? ? ? ? ? ? ? range_num = ARRAY_SIZE(pxa910_gpio_ranges);
> + ? ? ? }
> +#endif

Same here.

But *apart* from the #ifdef stuff it looks very good!
So if you can get rid of that, I'll be very happy!

Yours,
Linus Walleij

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

* [PATCH 2/7] gpio: make pxa gpio depend on pinmux
  2011-11-25 23:08 ` [PATCH 2/7] gpio: make pxa gpio depend on pinmux Haojian Zhuang
@ 2011-11-28  9:09   ` Linus Walleij
  0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2011-11-28  9:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 26, 2011 at 12:08 AM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:

> From: Haojian Zhuang <hzhuang1@hexinfolabs.org>
>
> While gpio_request() is called, pinmux_request_gpio() would be called
> too. Then alternate function of pin can be changed to gpio directly.
>
> Signed-off-by: Haojian Zhuang <hzhuang1@hexinfolabs.org>

Looks good,
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Thanks,
Linus Walleij

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

* [PATCH 4/7] tty: serial: support pinmux in pxa serial
  2011-11-25 23:09 ` [PATCH 4/7] tty: serial: support pinmux in pxa serial Haojian Zhuang
@ 2011-11-28  9:15   ` Linus Walleij
  2011-11-30 11:04     ` Greg KH
  0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2011-11-28  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 26, 2011 at 12:09 AM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:

> From: Haojian Zhuang <hzhuang1@hexinfolabs.org>
>
> PXA serial driver can configure pin directly.
>
> Signed-off-by: Haojian Zhuang <hzhuang1@hexinfolabs.org>
(...)
> + err_pmx:
> + ? ? ? pinmux_disable(sport->pmx);
> + ? ? ? pinmux_put(sport->pmx);

There is this little discussion whether each individual driver should access
it's pins or whether it should be done all centrally.

After some thinking and resoning I actually think this may be best
to have in each driver in most cases. The reason is that while it is
possible to standardize for simple usecases (like this one, just activate
it at probe() and deactivate it at remove()) it gets really complicated
and hairy to have it in central places when we come to things like
suspend()/resume(), idling and sometimes even
runtime_[suspend|resume].

So unless someone else disagrees or talks agains me, and
provided this is how you want to do it for all PXA drivers:
Acked-by: Linus Walleij <linus.walleij@linaro.org>

I need Gregs ACK if you want it to go iin through the pinctrl
tree.

Thanks,
Linus Walleij

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

* [PATCH 3/7] ARM: pxa: enable pinmux in pxa pwm
  2011-11-25 23:09 ` [PATCH 3/7] ARM: pxa: enable pinmux in pxa pwm Haojian Zhuang
@ 2011-11-28  9:18   ` Linus Walleij
  2011-11-28 12:49     ` Russell King - ARM Linux
  0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2011-11-28  9:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 26, 2011 at 12:09 AM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:

> From: Haojian Zhuang <hzhuang1@hexinfolabs.org>
>
> Add pinmux operations in pxa pwm driver.
>
> Signed-off-by: Haojian Zhuang <hzhuang1@hexinfolabs.org>

Same comment as for the serial driver,
Acked-by: Linus Walleij <linus.walleij@linaro.org>

I need one of the PXA maintainers (Eric, Russell) ACK to merge
it through the pinctrl tree.

Thanks,
Linus Walleij

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

* [PATCH 5/7] fb: pxa: support pinmux operation
  2011-11-25 23:09 ` [PATCH 5/7] fb: pxa: support pinmux operation Haojian Zhuang
@ 2011-11-28  9:19   ` Linus Walleij
  2011-12-02 21:53     ` Florian Tobias Schandinat
  0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2011-11-28  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 26, 2011 at 12:09 AM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:

More verbose commit log please.

> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>

Apart from that, same comment as for the serial driver,
Acked-by: Linus Walleij <linus.walleij@linaro.org>

I need the framebuffer maintainers ACK to merge this through the pinctrl
tree.

Thanks,
Linus Walleij

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

* [PATCH 7/7] ARM: mmp: enable pinmux on ttc dkb
  2011-11-25 23:09 ` [PATCH 7/7] ARM: mmp: enable pinmux on ttc dkb Haojian Zhuang
@ 2011-11-28  9:22   ` Linus Walleij
  0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2011-11-28  9:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 26, 2011 at 12:09 AM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:

> Remove MFP operation. Use pinmux mapping instead.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>

As stated earlier, I think the new pinctrl platform data should be
passed in from
here, apart from that:

Acked-by: Linus Walleij <linus.walleij@linaro.org>

SInce you're the (co-)subarch maintainer for MMP I will merge this to pinctrl
as soon as the core driver is OK and you tell me to merge the rest of the
(ACK:ed) series.

Thanks,
Linus Walleij

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

* [PATCH 6/7] ARM: pxa: enable pinmux mapping in zylonite
  2011-11-26  3:53   ` Arnd Bergmann
  2011-11-26  4:45     ` Haojian Zhuang
@ 2011-11-28  9:32     ` Linus Walleij
  1 sibling, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2011-11-28  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Nov 26, 2011 at 4:53 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 25 November 2011, Haojian Zhuang wrote:
>> Remove MFP operation in zylonite. Use pinmux mapping instead.
>>
>> +#define COMMON_PINMUX_MAP() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? .name = "uart2", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .ctrl_dev_name = "pinctrl.0", ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? .function = "uart2", ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .dev_name = "pxa2xx-uart.2", ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .group = "stuart1", ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? .hog_on_boot = true, ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? }, { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .name = "key", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .ctrl_dev_name = "pinctrl.0", ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? .function = "key", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .dev_name = "pxa27x-keyboard", ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .group = "key0", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .hog_on_boot = true, ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? }, { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .name = "mmc1", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? .ctrl_dev_name = "pinctrl.0", ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? .function = "mmc1", ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? .group = "mmc1_0", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .hog_on_boot = true, ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? }, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? PINMUX_MAP_PRIMARY_SYS_HOG("mmc2", "mmc2"), ? ? ? ? ? ? \
>> + ? ? PINMUX_MAP_PRIMARY_SYS_HOG("usbh", "usbh"), ? ? ? ? ? ? \
>> + ? ? PINMUX_MAP_PRIMARY_SYS_HOG("ac97", "ac97"), ? ? ? ? ? ? \
>> + ? ? PINMUX_MAP_PRIMARY_SYS_HOG("smc", "smc"), ? ? ? ? ? ? ? \
>> + ? ? PINMUX_MAP_PRIMARY("pwm3", "pwm3", "pxa27x-pwm.1"), ? ? \
>> + ? ? PINMUX_MAP_PRIMARY("uart1", "uart1", "pxa2xx-uart.1"), ?\
>> + ? ? PINMUX_MAP_PRIMARY("ssp3", "ssp3", "pxa27x-ssp.2"), ? ? \
>> + ? ? PINMUX_MAP_PRIMARY("lcd", "lcd", "pxa2xx-fb"), ? ? ? ? ?\
>> + ? ? PINMUX_MAP_PRIMARY("i2c", "i2c", "pxa2xx-i2c.0")
>> +
>> +static struct pinmux_map pxa300_pmx_map[] = {
>> + ? ? COMMON_PINMUX_MAP(),
>> + ? ? {
>> + ? ? ? ? ? ? .name = "uart0",
>> + ? ? ? ? ? ? .ctrl_dev_name = "pinctrl.0",
>> + ? ? ? ? ? ? .function = "uart0",
>> + ? ? ? ? ? ? .dev_name = "pxa2xx-uart.0",
>> + ? ? ? ? ? ? .group = "ffuart0",
>> + ? ? },
>> ?};
>
> I think we should not be forced to use macros like this in order to extend a common
> pinmux mapping. Unfortunately, I can't see an easy way to do it differently
> with the pinmux core, but it might not be too late to extend the interfaces now.

No problem at all, if I just get a patch to extend the mapping with whatever
is needed to use large common subsets I'll review/merge, it looks pretty
useful for PXA.

> I also noticed that the pinmux_map arrays are not marked __initdata, because
> it gets referenced later. This means that in a kernel that supports many machines,
> we also have to keep all pinmux configurations around at runtime.
>
> Linus, what do you think about changing the pinmux_register_mappings function
> to make a copy of the data in order to let the platform code mark the data as
> __initdata, and to allow appending the maps at boot time so that the above
> can become two arrays that are registered individually?

It's a bit costly since it involves making deep copies of structs
that in turn contain a few strings each, leading to a lot of kstrdup()
happening for a large map, but I'll propose something for the single
in-kernel user so we can see how it looks.

Yours,
Linus Walleij

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-28  9:08   ` Linus Walleij
@ 2011-11-28  9:50     ` Haojian Zhuang
  2011-11-28 13:17       ` Linus Walleij
  0 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-28  9:50 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Linus Walleij [mailto:linus.walleij at linaro.org]
>Sent: 2011?11?28? 5:08 PM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org; swarren at nvidia.com;
>linux at arm.linux.org.uk; eric.y.miao at gmail.com; grant.likely at secretlab.ca;
>arnd at arndb.de
>Subject: Re: [PATCH 1/7] pinctrl: enable pxa3xx pinmux
>
>On Sat, Nov 26, 2011 at 12:08 AM, Haojian Zhuang
><haojian.zhuang@marvell.com> wrote:
>
>> Support PXA300/PXA310/PXA320/PXA910 pinmux.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
>
>Cool!
>
>> +#ifdef CONFIG_ARCH_PXA
>> +static struct pinctrl_pin_desc pxa300_pads[] = {
>(...)
>
>Ick, per-arch #ifdefs in the driver/ directory is not good. Can you
>arrange
>for this to be #ifdef:ed up in your board file and passed in as platform
>data instead of being defined here?
>
>I know that the U300 driver defines all it's pins in the driver file,
>but it only supports one single board on one single chipset and
>is thus pretty fixed, nominally this kind of stuff should come from
>the board file(s) or the device tree.
>
>> +static int pxa3xx_get_gpio_func(unsigned int cpuid, unsigned int gpio)
>> +{
>> + ? ? ? int ret = 0;
>> +
>> + ? ? ? switch (cpuid) {
>> +#ifdef CONFIG_ARCH_PXA
>> + ? ? ? case PINMUX_PXA300:
>> + ? ? ? case PINMUX_PXA310:
>> + ? ? ? ? ? ? ? if (gpio == 50)
>> + ? ? ? ? ? ? ? ? ? ? ? ret = 2;
>> + ? ? ? ? ? ? ? else if (gpio == 49 || gpio == 51 || gpio == 53)
>> + ? ? ? ? ? ? ? ? ? ? ? ret = 3;
>> + ? ? ? ? ? ? ? break;
>> + ? ? ? case PINMUX_PXA320:
>> + ? ? ? ? ? ? ? if (gpio == 56 || (gpio > 58 && gpio < 63))
>> + ? ? ? ? ? ? ? ? ? ? ? goto out;
>> + ? ? ? ? ? ? ? break;
>> +#endif
>> +#ifdef CONFIG_ARCH_MMP
>> + ? ? ? case PINMUX_PXA910:
>> + ? ? ? ? ? ? ? if ((gpio > 116 && gpio < 121) || gpio == 122 || gpio
>== 123 ||
>> + ? ? ? ? ? ? ? ? ? ? ? gpio == 125 || gpio == 99 || gpio == 58 ||
>gpio == 59)
>> + ? ? ? ? ? ? ? ? ? ? ? ret = 1;
>> + ? ? ? ? ? ? ? break;
>> +#endif
>
>Do you need these #ifdef:s?

I can remove this #ifdef.

>
>They need to go, one way or another.
>
>Switching on cpuid is excellent, provided it's passed in from
>the outside, the definitons of these cases should be available
>anyway should they not.
>
>#ifdef:in out for footprint or unused code paths on some platforms
>should *not* be done, it creates more trouble than it solves, see
>Documentation/SubmittingPatches section 2) #ifdefs are ugly.
>
>> +static int pxa3xx_get_mfpr(unsigned int cpuid, unsigned int pin)
>> +{
>> + ? ? ? int ret;
>> + ? ? ? switch (cpuid) {
>> +#ifdef CONFIG_ARCH_PXA
>
>Dito. Etc.
I can remove this too.

>
>> +#ifdef CONFIG_ARCH_MMP
>> +static struct pinctrl_desc pxa910_pctrl_desc = {
>> +       .name           = "pxa910-pinctrl",
>> +       .pins           = pxa910_pads,
>> +       .npins          = ARRAY_SIZE(pxa910_pads),
>> +       .maxpin         = 260,
>> +       .pctlops        = &pxa3xx_pctrl_ops,
>> +       .pmxops         = &pxa3xx_pmx_ops,
>> +       .owner          = THIS_MODULE,
>> +};
>
>This is not good either. Get rid of all #ifdef
I can remove this too.
>
>> +#ifdef CONFIG_ARCH_PXA
>> + ? ? ? if (cpu_is_pxa300()) {
>> + ? ? ? ? ? ? ? info->cpuid = PINMUX_PXA300;
>> + ? ? ? ? ? ? ? info->grp = pxa300_pin_groups;
>> + ? ? ? ? ? ? ? info->func = pxa300_pmx_functions;
>> + ? ? ? ? ? ? ? info->num_grps = ARRAY_SIZE(pxa300_pin_groups);
>> + ? ? ? ? ? ? ? info->num_funcs = ARRAY_SIZE(pxa300_pmx_functions);
>> + ? ? ? ? ? ? ? info->pctl = pinctrl_register(&pxa300_pctrl_desc,
>&pdev->dev,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info);
>> + ? ? ? ? ? ? ? range = pxa300_gpio_ranges;
>> + ? ? ? ? ? ? ? range_num = ARRAY_SIZE(pxa300_gpio_ranges);
>> + ? ? ? } else if (cpu_is_pxa310()) {
>> + ? ? ? ? ? ? ? info->cpuid = PINMUX_PXA310;
>> + ? ? ? ? ? ? ? info->grp = pxa310_pin_groups;
>> + ? ? ? ? ? ? ? info->func = pxa310_pmx_functions;
>> + ? ? ? ? ? ? ? info->num_grps = ARRAY_SIZE(pxa310_pin_groups);
>> + ? ? ? ? ? ? ? info->num_funcs = ARRAY_SIZE(pxa310_pmx_functions);
>> + ? ? ? ? ? ? ? info->pctl = pinctrl_register(&pxa310_pctrl_desc,
>&pdev->dev,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info);
>> + ? ? ? ? ? ? ? range = pxa310_gpio_ranges;
>> + ? ? ? ? ? ? ? range_num = ARRAY_SIZE(pxa310_gpio_ranges);
>> + ? ? ? } else if (cpu_is_pxa320()) {
>> + ? ? ? ? ? ? ? info->cpuid = PINMUX_PXA320;
>> + ? ? ? ? ? ? ? info->grp = pxa320_pin_groups;
>> + ? ? ? ? ? ? ? info->func = pxa320_pmx_functions;
>> + ? ? ? ? ? ? ? info->num_grps = ARRAY_SIZE(pxa320_pin_groups);
>> + ? ? ? ? ? ? ? info->num_funcs = ARRAY_SIZE(pxa320_pmx_functions);
>> + ? ? ? ? ? ? ? info->pctl = pinctrl_register(&pxa320_pctrl_desc,
>&pdev->dev,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info);
>> + ? ? ? ? ? ? ? range = pxa320_gpio_ranges;
>> + ? ? ? ? ? ? ? range_num = ARRAY_SIZE(pxa320_gpio_ranges);
>> + ? ? ? }
>> +#endif
>> +#ifdef CONFIG_ARCH_MMP
>> + ? ? ? if (cpu_is_pxa910()) {
>> + ? ? ? ? ? ? ? info->cpuid = PINMUX_PXA910;
>> + ? ? ? ? ? ? ? info->grp = pxa910_pin_groups;
>> + ? ? ? ? ? ? ? info->func = pxa910_pmx_functions;
>> + ? ? ? ? ? ? ? info->num_grps = ARRAY_SIZE(pxa910_pin_groups);
>> + ? ? ? ? ? ? ? info->num_funcs = ARRAY_SIZE(pxa910_pmx_functions);
>> + ? ? ? ? ? ? ? info->pctl = pinctrl_register(&pxa910_pctrl_desc,
>&pdev->dev,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info);
>> + ? ? ? ? ? ? ? range = pxa910_gpio_ranges;
>> + ? ? ? ? ? ? ? range_num = ARRAY_SIZE(pxa910_gpio_ranges);
>> + ? ? ? }
>> +#endif
>
>Same here.
>
>But *apart* from the #ifdef stuff it looks very good!
>So if you can get rid of that, I'll be very happy!
The only block issue at here is that cpu_is_pxa3xx() is defined in arch-pxa and cpu_is_pxa910() is defined in arch-mmp. If I only enable arch-pxa, I would meet build error for undefined cpu_is_pxa910().

>
>Yours,
>Linus Walleij

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

* [PATCH 3/7] ARM: pxa: enable pinmux in pxa pwm
  2011-11-28  9:18   ` Linus Walleij
@ 2011-11-28 12:49     ` Russell King - ARM Linux
  0 siblings, 0 replies; 32+ messages in thread
From: Russell King - ARM Linux @ 2011-11-28 12:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 28, 2011 at 10:18:25AM +0100, Linus Walleij wrote:
> On Sat, Nov 26, 2011 at 12:09 AM, Haojian Zhuang
> <haojian.zhuang@marvell.com> wrote:
> 
> > From: Haojian Zhuang <hzhuang1@hexinfolabs.org>
> >
> > Add pinmux operations in pxa pwm driver.
> >
> > Signed-off-by: Haojian Zhuang <hzhuang1@hexinfolabs.org>
> 
> Same comment as for the serial driver,
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> 
> I need one of the PXA maintainers (Eric, Russell) ACK to merge
> it through the pinctrl tree.

Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-28  9:50     ` Haojian Zhuang
@ 2011-11-28 13:17       ` Linus Walleij
  2011-11-28 13:23         ` Haojian Zhuang
  0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2011-11-28 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 28, 2011 at 10:50 AM, Haojian Zhuang <hzhuang1@marvell.com> wrote:

> The only block issue at here is that cpu_is_pxa3xx() is defined in arch-pxa and cpu_is_pxa910()
> is defined in arch-mmp. If I only enable arch-pxa, I would meet build error for undefined
> cpu_is_pxa910().

Please #ifdef and cpu_is_* in arch/arm/mach-* then pass a flag or enumerator
with the platform data to the driver. This way the platform data uniformly
tells the driver what machine/cpu it is, and the driver need not hold any
knowledge of the system or use machine-specific functions.

I don't understand where your cpu_is* functions come from anyway,
which of these includes:

+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>

Actually provides it?

Please include that file explicitly and I'll tell you to
not include it :-D

Since this driver will be used by multiple platforms, why not
create
include/linux/pinctrl/pxa3xx.h and define your platform data
struct there like:

#include <linux/pinctrl/machine.h>

/* Unless an enumerator or defines like this exist already */
enum pxa_cpu_type {
   PXA_FOO,
   PXA_BAR,
   PXA_FNORD,
};

struct pxa3xx_pinmux_plat {
    enum pxa_cpu_type cputype;
    ...other interesting stuff ...
};

Fill it in in your machine and pick it up in your
driver.

Yours,
Linus Walleij

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-28 13:17       ` Linus Walleij
@ 2011-11-28 13:23         ` Haojian Zhuang
  2011-11-29 14:46           ` Arnd Bergmann
  0 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-28 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 28, 2011 at 9:17 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Mon, Nov 28, 2011 at 10:50 AM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>
>> The only block issue at here is that cpu_is_pxa3xx() is defined in arch-pxa and cpu_is_pxa910()
>> is defined in arch-mmp. If I only enable arch-pxa, I would meet build error for undefined
>> cpu_is_pxa910().
>
> Please #ifdef and cpu_is_* in arch/arm/mach-* then pass a flag or enumerator
> with the platform data to the driver. This way the platform data uniformly
> tells the driver what machine/cpu it is, and the driver need not hold any
> knowledge of the system or use machine-specific functions.
>
> I don't understand where your cpu_is* functions come from anyway,
> which of these includes:
>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/gpio.h>
> +#include <linux/io.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/pinmux.h>
> +#include <linux/platform_device.h>
>
> Actually provides it?
>
> Please include that file explicitly and I'll tell you to
> not include it :-D
>
> Since this driver will be used by multiple platforms, why not
> create
> include/linux/pinctrl/pxa3xx.h and define your platform data
> struct there like:
>
> #include <linux/pinctrl/machine.h>
>
> /* Unless an enumerator or defines like this exist already */
> enum pxa_cpu_type {
> ? PXA_FOO,
> ? PXA_BAR,
> ? PXA_FNORD,
> };
>
> struct pxa3xx_pinmux_plat {
> ? ?enum pxa_cpu_type cputype;
> ? ?...other interesting stuff ...
> };
>
> Fill it in in your machine and pick it up in your
> driver.
>
> Yours,
> Linus Walleij
>

How about define cpu_is_pxa3xx() in both arch-pxa and arch-mmp? Maybe
it could be simpler. Since we have similar issue in gpio driver too.

Thanks
Haojian

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-25 23:08 ` [PATCH 1/7] pinctrl: enable pxa3xx pinmux Haojian Zhuang
  2011-11-28  9:08   ` Linus Walleij
@ 2011-11-28 20:21   ` Stephen Warren
  2011-11-29  2:31     ` Eric Miao
  2011-11-29  8:39     ` Linus Walleij
  2011-11-30 12:00   ` Linus Walleij
  2 siblings, 2 replies; 32+ messages in thread
From: Stephen Warren @ 2011-11-28 20:21 UTC (permalink / raw)
  To: linux-arm-kernel

Haojian Zhuang wrote at Friday, November 25, 2011 4:09 PM:
...
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
...
> +config PINMUX_PXA3xx
> +	bool "PXA pinmux driver"
> +	default y if ARCH_PXA || ARCH_MMP
> +	select PINMUX
> +

I thought the plan here was for e.g. ARCH_PXA to "select PINMUX_PXA3xxx",
since it's presumably mandatory?

-- 
nvpublic

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-28 20:21   ` Stephen Warren
@ 2011-11-29  2:31     ` Eric Miao
  2011-11-29  8:39     ` Linus Walleij
  1 sibling, 0 replies; 32+ messages in thread
From: Eric Miao @ 2011-11-29  2:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 29, 2011 at 4:21 AM, Stephen Warren <swarren@nvidia.com> wrote:
> Haojian Zhuang wrote at Friday, November 25, 2011 4:09 PM:
> ...
>> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> ...
>> +config PINMUX_PXA3xx
>> + ? ? bool "PXA pinmux driver"
>> + ? ? default y if ARCH_PXA || ARCH_MMP
>> + ? ? select PINMUX
>> +
>
> I thought the plan here was for e.g. ARCH_PXA to "select PINMUX_PXA3xxx",
> since it's presumably mandatory?

Can we pass the SoC type by platform data, instead of calling cpu_is_*()?

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-28 20:21   ` Stephen Warren
  2011-11-29  2:31     ` Eric Miao
@ 2011-11-29  8:39     ` Linus Walleij
  2011-11-29  8:56       ` Haojian Zhuang
  1 sibling, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2011-11-29  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 28, 2011 at 9:21 PM, Stephen Warren <swarren@nvidia.com> wrote:
> Haojian Zhuang wrote at Friday, November 25, 2011 4:09 PM:
> ...
>> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> ...
>> +config PINMUX_PXA3xx
>> + ? ? bool "PXA pinmux driver"
>> + ? ? default y if ARCH_PXA || ARCH_MMP

So drop that line.

The rest is correct.

>> + ? ? select PINMUX
>> +
>
> I thought the plan here was for e.g. ARCH_PXA to "select PINMUX_PXA3xxx",
> since it's presumably mandatory?

Yes that is correct.

Haojian can you alter the patch so that arch/arm/mach*/Kconfig does

select PINCTRL
select PINMUX_PXA3XX

(Both are needed.)

And

Yours,
Linus Walleij

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-29  8:39     ` Linus Walleij
@ 2011-11-29  8:56       ` Haojian Zhuang
  0 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-29  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 29, 2011 at 4:39 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Mon, Nov 28, 2011 at 9:21 PM, Stephen Warren <swarren@nvidia.com> wrote:
>> Haojian Zhuang wrote at Friday, November 25, 2011 4:09 PM:
>> ...
>>> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
>> ...
>>> +config PINMUX_PXA3xx
>>> + ? ? bool "PXA pinmux driver"
>>> + ? ? default y if ARCH_PXA || ARCH_MMP
>
> So drop that line.
>
> The rest is correct.
>
>>> + ? ? select PINMUX
>>> +
>>
>> I thought the plan here was for e.g. ARCH_PXA to "select PINMUX_PXA3xxx",
>> since it's presumably mandatory?
>
> Yes that is correct.
>
> Haojian can you alter the patch so that arch/arm/mach*/Kconfig does
>
> select PINCTRL
> select PINMUX_PXA3XX
>
> (Both are needed.)
>
I'll change it.

Thanks
Haojian

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-28 13:23         ` Haojian Zhuang
@ 2011-11-29 14:46           ` Arnd Bergmann
  2011-11-29 15:36             ` Haojian Zhuang
  0 siblings, 1 reply; 32+ messages in thread
From: Arnd Bergmann @ 2011-11-29 14:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 28 November 2011, Haojian Zhuang wrote:
> 
> How about define cpu_is_pxa3xx() in both arch-pxa and arch-mmp? Maybe
> it could be simpler. Since we have similar issue in gpio driver too.

That would work, but I think the solution that Linus suggested is cleaner.

My preferred solution would be to make the detection data driven instead
of coded into the probe function. What I mean with this is to have
the four versions use a fixed data structure like this:

static const struct pxa3xx_pinmux_info pxa300_pinmux = {
       .cpuid = PINMUX_PXA300,
       .grp = pxa300_pin_groups,
       .func = pxa300_pmx_functions,
       .num_grps = ARRAY_SIZE(pxa300_pin_groups),
       .num_funcs = ARRAY_SIZE(pxa300_pmx_functions),
       .desc = &pxa300_pctrl_desc,
       .range = pxa300_gpio_ranges,
       .range_num = ARRAY_SIZE(pxa300_gpio_ranges),
};

static const struct pxa3xx_pinmux_info pxa310_pinmux = {
       .cpuid = PINMUX_PXA320,
       .grp = pxa310_pin_groups,
       .func = pxa310_pmx_functions,
       .num_grps = ARRAY_SIZE(pxa310_pin_groups),
       .num_funcs = ARRAY_SIZE(pxa310_pmx_functions),
       .desc = &pxa310_pctrl_desc,
       .range = pxa310_gpio_ranges,
       .range_num = ARRAY_SIZE(pxa310_gpio_ranges),
};

static const struct pxa3xx_pinmux_info pxa320_pinmux = {
	...
};

static struct platform_device_id pxa3xx_pinmux_ids = {
	{ .name = "pxa300-pinmux", .id = (unsigned long)&pxa300_pinmux, },
	{ .name = "pxa310-pinmux", .id = (unsigned long)&pxa310_pinmux, },
	{ .name = "pxa320-pinmux", .id = (unsigned long)&pxa320_pinmux, },
	{ .name = "pxa910-pinmux", .id = (unsigned long)&pxa910_pinmux, },
};

static struct platform_driver pxa3xx_pinmux_driver = {
       .driver = {
               .owner = THIS_MODULE,
       },
       .id_entry = pxa3xx_pinmux_ids,
       .probe = pxa3xx_pinmux_probe,
       .remove = __devexit_p(pxa3xx_pinmux_remove),
};

Then you can look at the pxa3xx_pinmux_info pointer in the probe function
and do whatever else is necessary.

Another entirely different approach would be to split the driver into
multiple files, one for each soc plus one for the common parts, so you
just build the parts you need for the configuration.

	Arnd

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-29 14:46           ` Arnd Bergmann
@ 2011-11-29 15:36             ` Haojian Zhuang
  2011-11-29 16:04               ` Arnd Bergmann
  0 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2011-11-29 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 29, 2011 at 10:46 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Monday 28 November 2011, Haojian Zhuang wrote:
>>
>> How about define cpu_is_pxa3xx() in both arch-pxa and arch-mmp? Maybe
>> it could be simpler. Since we have similar issue in gpio driver too.
>
> That would work, but I think the solution that Linus suggested is cleaner.
>
Yes, I'm moving to his solution now.

> My preferred solution would be to make the detection data driven instead
> of coded into the probe function. What I mean with this is to have
> the four versions use a fixed data structure like this:
>
> static const struct pxa3xx_pinmux_info pxa300_pinmux = {
> ? ? ? .cpuid = PINMUX_PXA300,
> ? ? ? .grp = pxa300_pin_groups,
> ? ? ? .func = pxa300_pmx_functions,
> ? ? ? .num_grps = ARRAY_SIZE(pxa300_pin_groups),
> ? ? ? .num_funcs = ARRAY_SIZE(pxa300_pmx_functions),
> ? ? ? .desc = &pxa300_pctrl_desc,
> ? ? ? .range = pxa300_gpio_ranges,
> ? ? ? .range_num = ARRAY_SIZE(pxa300_gpio_ranges),
> };
>
> static const struct pxa3xx_pinmux_info pxa310_pinmux = {
> ? ? ? .cpuid = PINMUX_PXA320,
> ? ? ? .grp = pxa310_pin_groups,
> ? ? ? .func = pxa310_pmx_functions,
> ? ? ? .num_grps = ARRAY_SIZE(pxa310_pin_groups),
> ? ? ? .num_funcs = ARRAY_SIZE(pxa310_pmx_functions),
> ? ? ? .desc = &pxa310_pctrl_desc,
> ? ? ? .range = pxa310_gpio_ranges,
> ? ? ? .range_num = ARRAY_SIZE(pxa310_gpio_ranges),
> };
>
> static const struct pxa3xx_pinmux_info pxa320_pinmux = {
> ? ? ? ?...
> };
>
> static struct platform_device_id pxa3xx_pinmux_ids = {
> ? ? ? ?{ .name = "pxa300-pinmux", .id = (unsigned long)&pxa300_pinmux, },
> ? ? ? ?{ .name = "pxa310-pinmux", .id = (unsigned long)&pxa310_pinmux, },
> ? ? ? ?{ .name = "pxa320-pinmux", .id = (unsigned long)&pxa320_pinmux, },
> ? ? ? ?{ .name = "pxa910-pinmux", .id = (unsigned long)&pxa910_pinmux, },
> };
It's cleaner. And I'm considering to extend pxa3xx_pinmux_info. I'll
also add pointers to pads[] and mfpr[]. Since pads[] and mfpr[] are
large, more silicons are supported and more memory space is occupied.
So I'll define pads[] and mfpr[] as __initdata and copy them into
pxa3xx_pinmux_info structure. So I'll use both your solution and
memcopy in probe().
>
> static struct platform_driver pxa3xx_pinmux_driver = {
> ? ? ? .driver = {
> ? ? ? ? ? ? ? .owner = THIS_MODULE,
> ? ? ? },
> ? ? ? .id_entry = pxa3xx_pinmux_ids,
> ? ? ? .probe = pxa3xx_pinmux_probe,
> ? ? ? .remove = __devexit_p(pxa3xx_pinmux_remove),
> };
>
> Then you can look at the pxa3xx_pinmux_info pointer in the probe function
> and do whatever else is necessary.
>
> Another entirely different approach would be to split the driver into
> multiple files, one for each soc plus one for the common parts, so you
> just build the parts you need for the configuration.
>
Is it OK to define pinmux-pxa3xx.c, pinmux-pxa300.c, ...? I'll append
8 files since I have 7 silicons.

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-29 15:36             ` Haojian Zhuang
@ 2011-11-29 16:04               ` Arnd Bergmann
  0 siblings, 0 replies; 32+ messages in thread
From: Arnd Bergmann @ 2011-11-29 16:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 29 November 2011, Haojian Zhuang wrote:
> > static struct platform_device_id pxa3xx_pinmux_ids = {
> >        { .name = "pxa300-pinmux", .id = (unsigned long)&pxa300_pinmux, },
> >        { .name = "pxa310-pinmux", .id = (unsigned long)&pxa310_pinmux, },
> >        { .name = "pxa320-pinmux", .id = (unsigned long)&pxa320_pinmux, },
> >        { .name = "pxa910-pinmux", .id = (unsigned long)&pxa910_pinmux, },
> > };
> It's cleaner. And I'm considering to extend pxa3xx_pinmux_info. I'll
> also add pointers to pads[] and mfpr[]. Since pads[] and mfpr[] are
> large, more silicons are supported and more memory space is occupied.
> So I'll define pads[] and mfpr[] as __initdata and copy them into
> pxa3xx_pinmux_info structure. So I'll use both your solution and
> memcopy in probe().

Ok. However, I think it needs to be __devinitdata if the platform
device might be added after the pinmux driver is added.

> > static struct platform_driver pxa3xx_pinmux_driver = {
> >       .driver = {
> >               .owner = THIS_MODULE,
> >       },
> >       .id_entry = pxa3xx_pinmux_ids,
> >       .probe = pxa3xx_pinmux_probe,
> >       .remove = __devexit_p(pxa3xx_pinmux_remove),
> > };
> >
> > Then you can look at the pxa3xx_pinmux_info pointer in the probe function
> > and do whatever else is necessary.
> >
> > Another entirely different approach would be to split the driver into
> > multiple files, one for each soc plus one for the common parts, so you
> > just build the parts you need for the configuration.
> >
> Is it OK to define pinmux-pxa3xx.c, pinmux-pxa300.c, ...? I'll append
> 8 files since I have 7 silicons.

I think it's ok, but it's your decision if you think it's too much.
You could also end up with fewer than 8 files if you group a few
socs together in case they are almost identical, but keep them
apart from the somewhat more different ones.

I would not recommend having one file per soc if that ends up duplicating
a lot of code that would otherwise be shared, but I think separate
modules would be preferred if you can make all the shared code end
up in the shared file and each individual driver get linked in only
when the configuration for that soc is enabled.

One more clarification: The idea here was to have each file as a separate
module with its own platform driver registration and one private
pinmux_info structure calling functions from the common module, but
never have common code call out to the individual drivers.

	Arnd

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

* [PATCH 4/7] tty: serial: support pinmux in pxa serial
  2011-11-28  9:15   ` Linus Walleij
@ 2011-11-30 11:04     ` Greg KH
  0 siblings, 0 replies; 32+ messages in thread
From: Greg KH @ 2011-11-30 11:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 28, 2011 at 10:15:34AM +0100, Linus Walleij wrote:
> On Sat, Nov 26, 2011 at 12:09 AM, Haojian Zhuang
> <haojian.zhuang@marvell.com> wrote:
> 
> > From: Haojian Zhuang <hzhuang1@hexinfolabs.org>
> >
> > PXA serial driver can configure pin directly.
> >
> > Signed-off-by: Haojian Zhuang <hzhuang1@hexinfolabs.org>
> (...)
> > + err_pmx:
> > + ? ? ? pinmux_disable(sport->pmx);
> > + ? ? ? pinmux_put(sport->pmx);
> 
> There is this little discussion whether each individual driver should access
> it's pins or whether it should be done all centrally.
> 
> After some thinking and resoning I actually think this may be best
> to have in each driver in most cases. The reason is that while it is
> possible to standardize for simple usecases (like this one, just activate
> it at probe() and deactivate it at remove()) it gets really complicated
> and hairy to have it in central places when we come to things like
> suspend()/resume(), idling and sometimes even
> runtime_[suspend|resume].
> 
> So unless someone else disagrees or talks agains me, and
> provided this is how you want to do it for all PXA drivers:
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> 
> I need Gregs ACK if you want it to go iin through the pinctrl
> tree.

Acked-by: Greg Kroah-Hartman <gregkh@suse.de>

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

* [PATCH 1/7] pinctrl: enable pxa3xx pinmux
  2011-11-25 23:08 ` [PATCH 1/7] pinctrl: enable pxa3xx pinmux Haojian Zhuang
  2011-11-28  9:08   ` Linus Walleij
  2011-11-28 20:21   ` Stephen Warren
@ 2011-11-30 12:00   ` Linus Walleij
  2 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2011-11-30 12:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Haojian,

I thought about this last night:

On Sat, Nov 26, 2011 at 12:08 AM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:

> +/* These 135 pins exists in PXA300, PXA310 & PXA320 */
> +#define PXA3XX_COMMON_PINS() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? PINCTRL_PIN(0, "GPIO0"), ? ? ? ?PINCTRL_PIN(1, "GPIO1"), ? ? ? ?\
(...)
+#ifdef CONFIG_ARCH_PXA
+static struct pinctrl_pin_desc pxa300_pads[] = {
+       PXA3XX_COMMON_PINS(),
+       PINCTRL_PIN(128, "GPIO0_2"),    PINCTRL_PIN(129, "GPIO1_2"),

Defining a huge macro like PXA3XX_COMMON_PINS() and reusing
all over the place doesn't scale.

The real fix is that I fix so that you can call
pinmux_register_mappings() more than one time.

So it will look like this or similar:

pinmux_register_mappings(common_pins);
if (plat->is_pxa)
  pinmux_register_mappings(pxa_pins);
if (plat->is_mmp)
  pinmux_register_mappings(mmp_pins);

etc.

Since I'm anyway fixing up this function I'll see if
I can simply fit this in as patch 2/2 and send out
ASAP.

Yours,
Linus Walleij

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

* [PATCH 5/7] fb: pxa: support pinmux operation
  2011-11-28  9:19   ` Linus Walleij
@ 2011-12-02 21:53     ` Florian Tobias Schandinat
  2011-12-05 13:07       ` Linus Walleij
  0 siblings, 1 reply; 32+ messages in thread
From: Florian Tobias Schandinat @ 2011-12-02 21:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

On 11/28/2011 09:19 AM, Linus Walleij wrote:
> On Sat, Nov 26, 2011 at 12:09 AM, Haojian Zhuang
> <haojian.zhuang@marvell.com> wrote:
> 
> More verbose commit log please.
> 
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
> 
> Apart from that, same comment as for the serial driver,
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> 
> I need the framebuffer maintainers ACK to merge this through the pinctrl
> tree.

You could have made my life easier by quoting the patch. Anyway, after I found
it in an archive, you may add

Acked-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>


Best regards,

Florian Tobias Schandinat

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

* [PATCH 5/7] fb: pxa: support pinmux operation
  2011-12-02 21:53     ` Florian Tobias Schandinat
@ 2011-12-05 13:07       ` Linus Walleij
  0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2011-12-05 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 2, 2011 at 10:53 PM, Florian Tobias Schandinat
<FlorianSchandinat@gmx.de> wrote:

> You could have made my life easier by quoting the patch. Anyway, after I found
> it in an archive, you may add
>
> Acked-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>

Ah. sorry, I compulsory cut down my reply quotes after being yelled at
to stop quoting too much, in this case I didn't think long enough...

Yours,
Linus Walleij

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

end of thread, other threads:[~2011-12-05 13:07 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-25 23:08 [PATCH 0/7] pinctrl: enable pxa pinmux Haojian Zhuang
2011-11-25 23:08 ` [PATCH 1/7] pinctrl: enable pxa3xx pinmux Haojian Zhuang
2011-11-28  9:08   ` Linus Walleij
2011-11-28  9:50     ` Haojian Zhuang
2011-11-28 13:17       ` Linus Walleij
2011-11-28 13:23         ` Haojian Zhuang
2011-11-29 14:46           ` Arnd Bergmann
2011-11-29 15:36             ` Haojian Zhuang
2011-11-29 16:04               ` Arnd Bergmann
2011-11-28 20:21   ` Stephen Warren
2011-11-29  2:31     ` Eric Miao
2011-11-29  8:39     ` Linus Walleij
2011-11-29  8:56       ` Haojian Zhuang
2011-11-30 12:00   ` Linus Walleij
2011-11-25 23:08 ` [PATCH 2/7] gpio: make pxa gpio depend on pinmux Haojian Zhuang
2011-11-28  9:09   ` Linus Walleij
2011-11-25 23:09 ` [PATCH 3/7] ARM: pxa: enable pinmux in pxa pwm Haojian Zhuang
2011-11-28  9:18   ` Linus Walleij
2011-11-28 12:49     ` Russell King - ARM Linux
2011-11-25 23:09 ` [PATCH 4/7] tty: serial: support pinmux in pxa serial Haojian Zhuang
2011-11-28  9:15   ` Linus Walleij
2011-11-30 11:04     ` Greg KH
2011-11-25 23:09 ` [PATCH 5/7] fb: pxa: support pinmux operation Haojian Zhuang
2011-11-28  9:19   ` Linus Walleij
2011-12-02 21:53     ` Florian Tobias Schandinat
2011-12-05 13:07       ` Linus Walleij
2011-11-25 23:09 ` [PATCH 6/7] ARM: pxa: enable pinmux mapping in zylonite Haojian Zhuang
2011-11-26  3:53   ` Arnd Bergmann
2011-11-26  4:45     ` Haojian Zhuang
2011-11-28  9:32     ` Linus Walleij
2011-11-25 23:09 ` [PATCH 7/7] ARM: mmp: enable pinmux on ttc dkb Haojian Zhuang
2011-11-28  9:22   ` Linus Walleij

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.