All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] add pinmux and gpio for CSR SiRFprimaII
@ 2011-07-26  8:13 Barry Song
  2011-07-26  8:13 ` [RFC PATCH 1/2] ARM: CSR: Add pinmux support for SiRFprimaII Barry Song
  2011-07-26  8:13 ` [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller Barry Song
  0 siblings, 2 replies; 19+ messages in thread
From: Barry Song @ 2011-07-26  8:13 UTC (permalink / raw)
  To: linux-arm-kernel

The following two patches add pinmux and gpio support for CSR SiRFprimaII.

Now the pinmux subsystem of Linus Walleij, so patch 1 isn't based on it yet.
But it is easy to move that to use new framework once pinmux subsystem is merged.

Rongjun Ying (1):
  ARM: CSR: Add pinmux support for SiRFprimaII

Yuping Luo (1):
  GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller

 arch/arm/boot/dts/prima2-cb.dts               |    2 +-
 arch/arm/mach-prima2/Makefile                 |    1 +
 arch/arm/mach-prima2/include/mach/gpio.h      |   34 +
 arch/arm/mach-prima2/include/mach/irqs.h      |   11 +
 arch/arm/mach-prima2/include/mach/regs-gpio.h |   30 +
 arch/arm/mach-prima2/pinmux.c                 |  824 +++++++++++++++++++++++++
 drivers/gpio/Kconfig                          |    6 +
 drivers/gpio/Makefile                         |    1 +
 drivers/gpio/gpio-sirf.c                      |  529 ++++++++++++++++
 9 files changed, 1437 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-prima2/include/mach/gpio.h
 create mode 100644 arch/arm/mach-prima2/include/mach/regs-gpio.h
 create mode 100644 arch/arm/mach-prima2/pinmux.c
 create mode 100644 drivers/gpio/gpio-sirf.c



Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog

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

* [RFC PATCH 1/2] ARM: CSR: Add pinmux support for SiRFprimaII
  2011-07-26  8:13 [RFC PATCH 0/2] add pinmux and gpio for CSR SiRFprimaII Barry Song
@ 2011-07-26  8:13 ` Barry Song
  2011-07-26  8:13 ` [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller Barry Song
  1 sibling, 0 replies; 19+ messages in thread
From: Barry Song @ 2011-07-26  8:13 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rongjun Ying <rongjun.ying@csr.com>

Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
Signed-off-by: Barry Song <baohua.song@csr.com>
---
 arch/arm/boot/dts/prima2-cb.dts               |    2 +-
 arch/arm/mach-prima2/Makefile                 |    1 +
 arch/arm/mach-prima2/include/mach/irqs.h      |   11 +
 arch/arm/mach-prima2/include/mach/regs-gpio.h |   30 +
 arch/arm/mach-prima2/pinmux.c                 |  824 +++++++++++++++++++++++++
 5 files changed, 867 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-prima2/include/mach/regs-gpio.h
 create mode 100644 arch/arm/mach-prima2/pinmux.c

diff --git a/arch/arm/boot/dts/prima2-cb.dts b/arch/arm/boot/dts/prima2-cb.dts
index 6fecc88..07249c2 100644
--- a/arch/arm/boot/dts/prima2-cb.dts
+++ b/arch/arm/boot/dts/prima2-cb.dts
@@ -274,7 +274,7 @@
 			gpio: gpio-controller at b0120000 {
 				#gpio-cells = <2>;
 				#interrupt-cells = <2>;
-				compatible = "sirf,prima2-gpio";
+				compatible = "sirf,prima2-gpio", "sirf,prima2-pinmux";
 				reg = <0xb0120000 0x10000>;
 				gpio-controller;
 				interrupt-controller;
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
index 7af7fc0..efb8489 100644
--- a/arch/arm/mach-prima2/Makefile
+++ b/arch/arm/mach-prima2/Makefile
@@ -3,5 +3,6 @@ obj-y += irq.o
 obj-y += clock.o
 obj-y += rstc.o
 obj-y += prima2.o
+obj-y += pinmux.o
 obj-$(CONFIG_DEBUG_LL) += lluart.o
 obj-$(CONFIG_CACHE_L2X0) += l2x0.o
diff --git a/arch/arm/mach-prima2/include/mach/irqs.h b/arch/arm/mach-prima2/include/mach/irqs.h
index bb354f9..06fe4e0 100644
--- a/arch/arm/mach-prima2/include/mach/irqs.h
+++ b/arch/arm/mach-prima2/include/mach/irqs.h
@@ -12,6 +12,17 @@
 #define SIRFSOC_INTENAL_IRQ_START  0
 #define SIRFSOC_INTENAL_IRQ_END    59
 
+#define SIRFSOC_GPIO_IO_CPLD_SIZE	(5 * 8)
+#define SIRFSOC_GPIO_HS_CPLD_SIZE	(16 * 8)
+
+#define SIRFSOC_GPIO_IRQ_START     (SIRFSOC_INTENAL_IRQ_END + 1)
+
+#define SIRFSOC_GPIO_NO_OF_BANKS        5
+#define SIRFSOC_GPIO_BANK_SIZE          32
+
+#define SIRFSOC_GPIO_IRQ_END       (SIRFSOC_GPIO_IRQ_START + \
+		SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE)
+
 #define NR_IRQS	220
 
 #endif
diff --git a/arch/arm/mach-prima2/include/mach/regs-gpio.h b/arch/arm/mach-prima2/include/mach/regs-gpio.h
new file mode 100644
index 0000000..e3489eb
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/regs-gpio.h
@@ -0,0 +1,30 @@
+/*
+ * arch/arm/mach-prima2/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __REGS_GPIO_H_
+#define __REGS_GPIO_H_
+
+#define SIRFSOC_GPIO_CTRL(g, i)			((g)*0x100 + (i)*4)
+#define SIRFSOC_GPIO_DSP_EN0			(0x80)
+#define SIRFSOC_GPIO_PAD_EN(g)			((g)*0x100 + 0x84)
+#define SIRFSOC_GPIO_INT_STATUS(g) 		((g)*0x100 + 0x8C)
+
+#define SIRFSOC_GPIO_CTL_INTR_LOW_MASK		0x1
+#define SIRFSOC_GPIO_CTL_INTR_HIGH_MASK		0x2
+#define SIRFSOC_GPIO_CTL_INTR_TYPE_MASK		0x4
+#define SIRFSOC_GPIO_CTL_INTR_EN_MASK		0x8
+#define SIRFSOC_GPIO_CTL_INTR_STS_MASK		0x10
+#define SIRFSOC_GPIO_CTL_OUT_EN_MASK		0x20
+#define SIRFSOC_GPIO_CTL_DATAOUT_MASK		0x40
+#define SIRFSOC_GPIO_CTL_DATAIN_MASK		0x80
+#define SIRFSOC_GPIO_CTL_PULL_MASK		0x100
+#define SIRFSOC_GPIO_CTL_PULL_HIGH      	0x200
+#define SIRFSOC_GPIO_CTL_DSP_INT		0x400
+
+#define SIRFSOC_GPIO_NUM(bank, index)	(((bank)*(32)) + (index))
+#endif
diff --git a/arch/arm/mach-prima2/pinmux.c b/arch/arm/mach-prima2/pinmux.c
new file mode 100644
index 0000000..37873fb
--- /dev/null
+++ b/arch/arm/mach-prima2/pinmux.c
@@ -0,0 +1,824 @@
+/*
+ * pinmux for CSR SiRF prima2
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <asm/mach/irq.h>
+#include <mach/pinmux.h>
+#include <mach/regs-gpio.h>
+#include "common.h"
+
+#define SIRFSOC_RSC_PIN_MUX        0x0004
+
+struct muxmask {
+	unsigned long group;
+	unsigned long mask;
+};
+
+struct padmux {
+	char *name;
+	unsigned long muxmask_counts;
+	struct muxmask *pad_muxmask;
+	unsigned long funcmask;
+	unsigned long funcval;
+};
+
+void __iomem *sirfsoc_gpio_pinmux_base;
+
+static unsigned long pad_gpio_used_map[SIRFSOC_GPIO_NO_OF_BANKS];
+static unsigned long pad_module_used_map[SIRFSOC_GPIO_NO_OF_BANKS];
+
+static DEFINE_SPINLOCK(pad_lock);
+
+void sirfsoc_put_gpios(int group, u32 bitmask)
+{
+	if (group >= SIRFSOC_GPIO_NO_OF_BANKS) {
+		pr_err("%d th group is not valid. Only %d groups are available\n",
+			group, SIRFSOC_GPIO_NO_OF_BANKS);
+	} else {
+		int muxval;
+		unsigned long flags;
+		spin_lock_irqsave(&pad_lock, flags);
+		if (pad_module_used_map[group] & bitmask) {
+			pr_warning("%d th group is used by other modules\n", group);
+		}
+		pad_gpio_used_map[group] &= (~bitmask);
+		muxval = readl(sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_PAD_EN(group));
+		muxval = muxval & (~bitmask);
+		writel(muxval, sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_PAD_EN(group));
+		spin_unlock_irqrestore(&pad_lock, flags);
+	}
+}
+EXPORT_SYMBOL(sirfsoc_put_gpios);
+
+void sirfsoc_put_gpio(int group, int bitno)
+{
+	sirfsoc_put_gpios(group, 1 << bitno);
+}
+EXPORT_SYMBOL(sirfsoc_put_gpio);
+
+void sirfsoc_get_gpios(int group, u32 bitmask)
+{
+	if (group >= SIRFSOC_GPIO_NO_OF_BANKS) {
+		pr_err("%d th group is not valid. Only %d groups are available\n",
+			group, SIRFSOC_GPIO_NO_OF_BANKS);
+	} else {
+		int muxval;
+		unsigned long flags;
+		spin_lock_irqsave(&pad_lock, flags);
+		if (pad_module_used_map[group] & bitmask) {
+			pr_err("%d th group is used by other modules\n", group);
+			spin_unlock_irqrestore(&pad_lock, flags);
+			return;
+		}
+		pad_gpio_used_map[group] |= bitmask;
+		muxval = readl(sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_PAD_EN(group));
+		muxval = muxval | (bitmask);
+		writel(muxval, sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_PAD_EN(group));
+		spin_unlock_irqrestore(&pad_lock, flags);
+	}
+}
+EXPORT_SYMBOL(sirfsoc_get_gpios);
+
+void sirfsoc_get_gpio(int group, int bitno)
+{
+	sirfsoc_get_gpios(group, 1 << bitno);
+}
+EXPORT_SYMBOL(sirfsoc_get_gpio);
+
+static struct muxmask lcd_16bits_muxmask[] = {
+	{
+		.group = 3,
+		.mask =
+			~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) |
+				(1 << 6) | (1 << 7)
+				| (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13)
+				| (1 << 14) | (1 << 15)
+				| (1 << 16) | (1 << 17) | (1 << 18)),
+	}, {
+		.group = 2,
+		.mask = ~(1 << 31),
+	},
+};
+
+static struct padmux lcd_16bits_padmux = {
+	.name = "lcd_16bits",
+	.muxmask_counts = ARRAY_SIZE(lcd_16bits_muxmask),
+	.pad_muxmask = lcd_16bits_muxmask,
+	.funcmask = (1 << 4),
+	.funcval = (0 << 4),
+};
+
+static struct muxmask lcd_18bits_muxmask[] = {
+	{
+		.group = 3,
+		.mask =
+			~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) |
+				(1 << 6) | (1 << 7)
+				| (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13)
+				| (1 << 14) | (1 << 15)
+				| (1 << 16) | (1 << 17) | (1 << 18)),
+	}, {
+		.group = 2,
+		.mask = ~(1 << 31),
+	}, {
+		.group = 0,
+		.mask = ~((1 << 16) | (1 << 17)),
+	},
+};
+
+static struct padmux lcd_18bits_padmux = {
+	.name = "lcd_18bits",
+	.muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask),
+	.pad_muxmask = lcd_18bits_muxmask,
+	.funcmask = (1 << 4),
+	.funcval = (0 << 4),
+};
+
+static struct muxmask lcd_24bits_muxmask[] = {
+	{
+		.group = 3,
+		.mask =
+			~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) |
+				(1 << 6) | (1 << 7)
+				| (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13)
+				| (1 << 14) | (1 << 15)
+				| (1 << 16) | (1 << 17) | (1 << 18)),
+	}, {
+		.group = 2,
+		.mask = ~(1 << 31),
+	}, {
+		.group = 0,
+		.mask =
+			~((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20) |
+				(1 << 21) | (1 << 22) | (1 << 23)),
+	},
+};
+
+static struct padmux lcd_24bits_padmux = {
+	.name = "lcd_24bits",
+	.muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask),
+	.pad_muxmask = lcd_24bits_muxmask,
+	.funcmask = (1 << 4),
+	.funcval = (0 << 4),
+};
+
+static struct muxmask lcdrom_muxmask[] = {
+	{
+		.group = 3,
+		.mask =
+			~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) |
+				(1 << 6) | (1 << 7)
+				| (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13)
+				| (1 << 14) | (1 << 15)
+				| (1 << 16) | (1 << 17) | (1 << 18)),
+	}, {
+		.group = 2,
+		.mask = ~(1 << 31),
+	}, {
+		.group = 0,
+		.mask = ~((1 << 23)),
+	},
+};
+
+static struct padmux lcdrom_padmux = {
+	.name = "lcdrom",
+	.muxmask_counts = ARRAY_SIZE(lcdrom_muxmask),
+	.pad_muxmask = lcdrom_muxmask,
+	.funcmask = (1 << 4),
+	.funcval = (1 << 4),
+};
+
+static struct muxmask sdmmc3_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~((1 << 30) | (1 << 31)),
+	}, {
+		.group = 1,
+		.mask = ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)),
+	},
+};
+
+static struct padmux sdmmc3_padmux = {
+	.name = "sdmmc3",
+	.muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask),
+	.pad_muxmask = sdmmc3_muxmask,
+	.funcmask = (1 << 7),
+	.funcval = (0 << 7),
+};
+
+static struct muxmask spi0_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)),
+	},
+};
+
+static struct padmux spi0_padmux = {
+	.name = "spi0",
+	.muxmask_counts = ARRAY_SIZE(spi0_muxmask),
+	.pad_muxmask = spi0_muxmask,
+	.funcmask = (1 << 7),
+	.funcval = (1 << 7),
+};
+
+static struct muxmask sdmmc4_muxmask[] = {
+	{
+		.group = 1,
+		.mask =
+			~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9)),
+	},
+};
+
+static struct padmux sdmmc4_padmux = {
+	.name = "sdmmc4",
+	.muxmask_counts = ARRAY_SIZE(sdmmc4_muxmask),
+	.pad_muxmask = sdmmc4_muxmask,
+};
+
+static struct muxmask cko1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~(1 << 10),
+	},
+};
+
+static struct padmux cko1_padmux = {
+	.name = "cko1",
+	.muxmask_counts = ARRAY_SIZE(cko1_muxmask),
+	.pad_muxmask = cko1_muxmask,
+	.funcmask = (1 << 3),
+	.funcval = (0 << 3),
+};
+
+static struct muxmask i2s_muxmask[] = {
+	{
+		.group = 1,
+		.mask =
+			~((1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 19)
+				| (1 << 23) | (1 << 28)),
+	},
+};
+
+static struct padmux i2s_padmux = {
+	.name = "i2s",
+	.muxmask_counts = ARRAY_SIZE(i2s_muxmask),
+	.pad_muxmask = i2s_muxmask,
+	.funcmask = (1 << 3) | (1 << 9),
+	.funcval = (1 << 3) | (0 << 9),
+};
+
+static struct muxmask ac97_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~((1 << 11) | (1 << 12) | (1 << 13) | (1 << 14)),
+	},
+};
+
+static struct padmux ac97_padmux = {
+	.name = "ac97",
+	.muxmask_counts = ARRAY_SIZE(ac97_muxmask),
+	.pad_muxmask = ac97_muxmask,
+	.funcmask = (1 << 8),
+	.funcval = (0 << 8),
+};
+
+static struct muxmask spi1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~((1 << 11) | (1 << 12) | (1 << 13) | (1 << 14)),
+	},
+};
+
+static struct padmux spi1_padmux = {
+	.name = "spi1",
+	.muxmask_counts = ARRAY_SIZE(spi1_muxmask),
+	.pad_muxmask = spi1_muxmask,
+	.funcmask = (1 << 8),
+	.funcval = (1 << 8),
+};
+
+static struct muxmask sdmmc1_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~((1 << 27) | (1 << 28) | (1 << 29)),
+	},
+};
+
+static struct padmux sdmmc1_padmux = {
+	.name = "sdmmc1",
+	.muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask),
+	.pad_muxmask = sdmmc1_muxmask,
+};
+
+static struct muxmask gps_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~((1 << 24) | (1 << 25) | (1 << 26) | (1 << 4)),
+	},
+};
+
+static struct padmux gps_padmux = {
+	.name = "gps",
+	.muxmask_counts = ARRAY_SIZE(gps_muxmask),
+	.pad_muxmask = gps_muxmask,
+	.funcmask = (1 << 12) | (1 << 13) | (1 << 14),
+	.funcval = (1 << 12) | (0 << 13) | (0 << 14),
+};
+
+static struct muxmask sdmmc5_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~((1 << 24) | (1 << 25) | (1 << 26)),
+	}, {
+		.group = 1,
+		.mask = ~(1 << 29),
+	}, {
+		.group = 2,
+		.mask = ~((1 << 0) | (1 << 1)),
+	},
+};
+
+static struct padmux sdmmc5_padmux = {
+	.name = "sdmmc5",
+	.muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask),
+	.pad_muxmask = sdmmc5_muxmask,
+	.funcmask = (1 << 13) | (1 << 14),
+	.funcval = (1 << 13) | (1 << 14),
+};
+
+static struct muxmask uart1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~((1 << 15) | (1 << 17)),
+	},
+};
+
+static struct padmux uart1_padmux = {
+	.name = "uart1",
+	.muxmask_counts = ARRAY_SIZE(uart1_muxmask),
+	.pad_muxmask = uart1_muxmask,
+};
+
+static struct muxmask uart2_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~((1 << 16) | (1 << 18) | (1 << 24) | (1 << 27)),
+	},
+};
+
+static struct padmux uart2_padmux = {
+	.name = "uart2",
+	.muxmask_counts = ARRAY_SIZE(uart2_muxmask),
+	.pad_muxmask = uart2_muxmask,
+	.funcmask = (1 << 10),
+	.funcval = (1 << 10),
+};
+
+static struct muxmask uart2_nostreamctrl_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~((1 << 16) | (1 << 18)),
+	},
+};
+
+static struct padmux uart2_nostreamctrl_padmux = {
+	.name = "uart2_nostreamctrl",
+	.muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask),
+	.pad_muxmask = uart2_nostreamctrl_muxmask,
+};
+
+static struct muxmask usp0_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~((1 << 19) | (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23)),
+	},
+};
+
+static struct padmux usp0_padmux = {
+	.name = "usp0",
+	.muxmask_counts = ARRAY_SIZE(usp0_muxmask),
+	.pad_muxmask = usp0_muxmask,
+	.funcmask = (1 << 1) | (1 << 2) | (1 << 6) | (1 << 9),
+	.funcval = (0 << 1) | (0 << 2) | (0 << 6) | (0 << 9),
+};
+
+static struct muxmask usp1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~((1 << 24) | (1 << 25) | (1 << 26) | (1 << 27) | (1 << 28)),
+	},
+};
+
+static struct padmux usp1_padmux = {
+	.name = "usp1",
+	.muxmask_counts = ARRAY_SIZE(usp1_muxmask),
+	.pad_muxmask = usp1_muxmask,
+	.funcmask = (1 << 1) | (1 << 9) | (1 << 10) | (1 << 11),
+	.funcval = (0 << 1) | (0 << 9) | (0 << 10) | (0 << 11),
+};
+
+static struct muxmask usp2_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~((1 << 29) | (1 << 30) | (1 << 31)),
+	}, {
+		.group = 2,
+		.mask = ~((1 << 0) | (1 << 1)),
+	},
+};
+
+static struct padmux usp2_padmux = {
+	.name = "usp2",
+	.muxmask_counts = ARRAY_SIZE(usp2_muxmask),
+	.pad_muxmask = usp2_muxmask,
+	.funcmask = (1 << 13) | (1 << 14),
+	.funcval = (0 << 13) | (0 << 14),
+};
+
+static struct muxmask nand_muxmask[] = {
+	{
+		.group = 2,
+		.mask = ~((1 << 2) | (1 << 3) | (1 << 28) | (1 << 29) | (1 << 30)),
+	},
+};
+
+static struct padmux nand_padmux = {
+	.name = "nand",
+	.muxmask_counts = ARRAY_SIZE(nand_muxmask),
+	.pad_muxmask = nand_muxmask,
+	.funcmask = (1 << 5),
+	.funcval = (0 << 5),
+};
+
+static struct padmux sdmmc0_padmux = {
+	.name = "sdmmc0",
+	.muxmask_counts = 0,
+	.funcmask = (1 << 5),
+	.funcval = (0 << 5),
+};
+
+static struct muxmask sdmmc2_muxmask[] = {
+	{
+		.group = 2,
+		.mask = ~((1 << 2) | (1 << 3)),
+	},
+};
+
+static struct padmux sdmmc2_padmux = {
+	.name = "sdmmc2",
+	.muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask),
+	.pad_muxmask = nand_muxmask,
+	.funcmask = (1 << 5),
+	.funcval = (1 << 5),
+};
+
+static struct muxmask uart0_muxmask[] = {
+	{
+		.group = 2,
+		.mask = ~((1 << 4) | (1 << 5)),
+	}, {
+		.group = 1,
+		.mask = ~((1 << 23) | (1 << 28)),
+	},
+};
+
+static struct padmux uart0_padmux = {
+	.name = "uart0",
+	.muxmask_counts = ARRAY_SIZE(uart0_muxmask),
+	.pad_muxmask = uart0_muxmask,
+	.funcmask = (1 << 9),
+	.funcval = (1 << 9),
+};
+
+static struct muxmask uart0_nostreamctrl_muxmask[] = {
+	{
+		.group = 2,
+		.mask = ~((1 << 4) | (1 << 5)),
+	},
+};
+
+static struct padmux uart0_nostreamctrl_padmux = {
+	.name = "uart0_nostreamctrl",
+	.muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask),
+	.pad_muxmask = uart0_nostreamctrl_muxmask,
+};
+
+static struct muxmask cko0_muxmask[] = {
+	{
+		.group = 2,
+		.mask = ~((1 << 14)),
+	},
+};
+
+static struct padmux cko0_padmux = {
+	.name = "cko0",
+	.muxmask_counts = ARRAY_SIZE(cko0_muxmask),
+	.pad_muxmask = cko0_muxmask,
+};
+
+static struct muxmask vip_muxmask[] = {
+	{
+		.group = 2,
+		.mask = ~((1 << 15) | (1 << 16) | (1 << 17) | (1 << 18) | (1 << 19)
+			| (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23) | (1 << 24) |
+			(1 << 25)),
+	},
+};
+
+static struct padmux vip_padmux = {
+	.name = "vip",
+	.muxmask_counts = ARRAY_SIZE(vip_muxmask),
+	.pad_muxmask = vip_muxmask,
+	.funcmask = (1 << 0),
+	.funcval = (0 << 0),
+};
+
+static struct muxmask i2c0_muxmask[] = {
+	{
+		.group = 2,
+		.mask = ~((1 << 26) | (1 << 27)),
+	},
+};
+
+static struct padmux i2c0_padmux = {
+	.name = "i2c0",
+	.muxmask_counts = ARRAY_SIZE(i2c0_muxmask),
+	.pad_muxmask = i2c0_muxmask,
+};
+
+static struct muxmask i2c1_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~((1 << 13) | (1 << 15)),
+	},
+};
+
+static struct padmux i2c1_padmux = {
+	.name = "i2c1",
+	.muxmask_counts = ARRAY_SIZE(i2c1_muxmask),
+	.pad_muxmask = i2c1_muxmask,
+};
+
+static struct muxmask viprom_muxmask[] = {
+	{
+		.group = 2,
+		.mask = ~((1 << 15) | (1 << 16) | (1 << 17) | (1 << 18) | (1 << 19)
+			| (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23) | (1 << 24) |
+			(1 << 25)),
+	}, {
+		.group = 0,
+		.mask = ~(1 << 12),
+	},
+};
+
+static struct padmux viprom_padmux = {
+	.name = "viprom",
+	.muxmask_counts = ARRAY_SIZE(viprom_muxmask),
+	.pad_muxmask = viprom_muxmask,
+	.funcmask = (1 << 0),
+	.funcval = (1 << 0),
+};
+
+static struct muxmask pwm0_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~(1 << 4),
+	},
+};
+
+static struct padmux pwm0_padmux = {
+	.name = "pwm0",
+	.muxmask_counts = ARRAY_SIZE(pwm0_muxmask),
+	.pad_muxmask = pwm0_muxmask,
+	.funcmask = (1 << 12),
+	.funcval = (0 << 12),
+};
+
+static struct muxmask pwm1_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~(1 << 5),
+	},
+};
+
+static struct padmux pwm1_padmux = {
+	.name = "pwm1",
+	.muxmask_counts = ARRAY_SIZE(pwm1_muxmask),
+	.pad_muxmask = pwm1_muxmask,
+};
+
+static struct muxmask pwm2_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~(1 << 6),
+	},
+};
+
+static struct padmux pwm2_padmux = {
+	.name = "pwm2",
+	.muxmask_counts = ARRAY_SIZE(pwm2_muxmask),
+	.pad_muxmask = pwm2_muxmask,
+};
+
+static struct muxmask pwm3_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~(1 << 7),
+	},
+};
+
+static struct padmux pwm3_padmux = {
+	.name = "pwm3",
+	.muxmask_counts = ARRAY_SIZE(pwm3_muxmask),
+	.pad_muxmask = pwm3_muxmask,
+};
+
+static struct muxmask warm_rst_muxmask[] = {
+	{
+		.group = 0,
+		.mask = ~(1 << 8),
+	},
+};
+
+static struct padmux warm_rst_padmux = {
+	.name = "warm_rst",
+	.muxmask_counts = ARRAY_SIZE(warm_rst_muxmask),
+	.pad_muxmask = warm_rst_muxmask,
+};
+
+static struct muxmask usb0_utmi_drvbus_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~(1 << 22),
+	},
+};
+static struct padmux usb0_utmi_drvbus_padmux = {
+	.name = "usb0_utmi",
+	.muxmask_counts = ARRAY_SIZE(usb0_utmi_drvbus_muxmask),
+	.pad_muxmask = usb0_utmi_drvbus_muxmask,
+	.funcmask = (1 << 6),
+	.funcval = (1 << 6), /* refer to PAD_UTMI_DRVVBUS0_ENABLE */
+};
+
+static struct muxmask usb1_utmi_drvbus_muxmask[] = {
+	{
+		.group = 1,
+		.mask = ~(1 << 27),
+	},
+};
+static struct padmux usb1_utmi_drvbus_padmux = {
+	.name = "usb1_utmi",
+	.muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask),
+	.pad_muxmask = usb1_utmi_drvbus_muxmask,
+	.funcmask = (1 << 11),
+	.funcval = (1 << 11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */
+};
+
+static struct padmux *prima2_all_padmux[] = {
+	&lcd_16bits_padmux,
+	&lcd_18bits_padmux,
+	&lcd_24bits_padmux,
+	&lcdrom_padmux,
+	&sdmmc3_padmux,
+	&spi0_padmux,
+	&sdmmc4_padmux,
+	&cko1_padmux,
+	&i2s_padmux,
+	&ac97_padmux,
+	&spi1_padmux,
+	&sdmmc1_padmux,
+	&gps_padmux,
+	&sdmmc5_padmux,
+	&uart1_padmux,
+	&uart2_padmux,
+	&uart2_nostreamctrl_padmux,
+	&usp0_padmux,
+	&usp1_padmux,
+	&usp2_padmux,
+	&nand_padmux,
+	&sdmmc0_padmux,
+	&sdmmc2_padmux,
+	&uart0_padmux,
+	&uart0_nostreamctrl_padmux,
+	&cko0_padmux,
+	&vip_padmux,
+	&i2c0_padmux,
+	&i2c1_padmux,
+	&viprom_padmux,
+	&pwm0_padmux,
+	&pwm1_padmux,
+	&pwm2_padmux,
+	&pwm3_padmux,
+	&warm_rst_padmux,
+	&usb0_utmi_drvbus_padmux,
+	&usb1_utmi_drvbus_padmux,
+};
+
+void sirfsoc_pad_get(const char *name)
+{
+	int i, j;
+	for (i = 0; i < ARRAY_SIZE(prima2_all_padmux); i++) {
+		struct padmux *mux = prima2_all_padmux[i];
+		struct muxmask *mask = mux->pad_muxmask;
+		unsigned long flags;
+
+		if (strcmp(mux->name, name))
+			continue;
+
+		spin_lock_irqsave(&pad_lock, flags);
+		for (j = 0; j < mux->muxmask_counts; j++) {
+			int muxval;
+			if (pad_gpio_used_map[mask[j].group] &
+				(~(mask[j].mask))) {
+				pr_err(
+					"This pad is used by gpio\n");
+				spin_unlock_irqrestore(&pad_lock,
+					flags);
+				return;
+			}
+			pad_module_used_map[mask[j].group] |=
+				(~(mask[j].mask));
+			muxval =
+				readl(sirfsoc_gpio_pinmux_base +
+					SIRFSOC_GPIO_PAD_EN(mask[j].group));
+			muxval = muxval & (mask[j].mask);
+			writel(muxval,
+				sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_PAD_EN(mask[j].group));
+		}
+		if (mux->funcmask) {
+			unsigned long func_en_val;
+			func_en_val =
+				readl(sirfsoc_rstc_base + SIRFSOC_RSC_PIN_MUX);
+			func_en_val =
+				(func_en_val & (~(mux->funcmask))) | (mux->
+					funcval);
+			writel(func_en_val,
+				sirfsoc_rstc_base + SIRFSOC_RSC_PIN_MUX);
+		}
+		spin_unlock_irqrestore(&pad_lock, flags);
+	}
+}
+EXPORT_SYMBOL(sirfsoc_pad_get);
+
+void sirfsoc_pad_put(const char *name)
+{
+	int i, j;
+	for (i = 0; i < ARRAY_SIZE(prima2_all_padmux); i++) {
+		struct padmux *mux = prima2_all_padmux[i];
+		struct muxmask *mask = mux->pad_muxmask;
+		unsigned long flags;
+
+		if (strcmp(mux->name, name))
+			continue;
+
+		spin_lock_irqsave(&pad_lock, flags);
+		for (j = 0; j < mux->muxmask_counts; j++) {
+			int muxval;
+			if (pad_gpio_used_map[mask[j].group] &
+				(~(mask[j].mask)))
+				pr_warning("This pad is used by gpio\n");
+			pad_module_used_map[mask[j].group] &=
+				mask[j].mask;
+			muxval =
+				readl(sirfsoc_gpio_pinmux_base +
+					SIRFSOC_GPIO_PAD_EN(mask[j].group));
+			muxval = muxval | (~(mask[j].mask));
+			writel(muxval,
+				sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_PAD_EN(mask[j].group));
+		}
+		spin_unlock_irqrestore(&pad_lock, flags);
+	}
+}
+EXPORT_SYMBOL(sirfsoc_pad_put);
+
+static struct of_device_id pinmux_ids[]  = {
+	{ .compatible = "sirf,prima2-pinmux" },
+};
+
+static int __init sirfsoc_of_pinmux_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_matching_node(NULL, pinmux_ids);
+	if (!np)
+		panic("unable to find compatible pinmux node in dtb\n");
+
+	sirfsoc_gpio_pinmux_base = of_iomap(np, 0);
+	if (!sirfsoc_gpio_pinmux_base)
+		panic("unable to map gpio/pinmux cpu registers\n");
+
+	of_node_put(np);
+
+	return 0;
+}
+early_initcall(sirfsoc_of_pinmux_init);
+
-- 
1.7.1



Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog

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

* [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller
  2011-07-26  8:13 [RFC PATCH 0/2] add pinmux and gpio for CSR SiRFprimaII Barry Song
  2011-07-26  8:13 ` [RFC PATCH 1/2] ARM: CSR: Add pinmux support for SiRFprimaII Barry Song
@ 2011-07-26  8:13 ` Barry Song
  2011-07-26 10:09   ` Russell King - ARM Linux
  1 sibling, 1 reply; 19+ messages in thread
From: Barry Song @ 2011-07-26  8:13 UTC (permalink / raw)
  To: linux-arm-kernel

From: Yuping Luo <yuping.luo@csr.com>

Signed-off-by: Yuping Luo <yuping.luo@csr.com>
Signed-off-by: Barry Song <baohua.song@csr.com>
---
 arch/arm/mach-prima2/include/mach/gpio.h |   34 ++
 drivers/gpio/Kconfig                     |    6 +
 drivers/gpio/Makefile                    |    1 +
 drivers/gpio/gpio-sirf.c                 |  529 ++++++++++++++++++++++++++++++
 4 files changed, 570 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-prima2/include/mach/gpio.h
 create mode 100644 drivers/gpio/gpio-sirf.c

diff --git a/arch/arm/mach-prima2/include/mach/gpio.h b/arch/arm/mach-prima2/include/mach/gpio.h
new file mode 100644
index 0000000..25673b1
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/gpio.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-prima2/include/mach/gpio.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_GPIO_H
+#define __MACH_GPIO_H
+
+#include <mach/irqs.h>
+
+#ifndef CONFIG_GPIO_SIRFCPLD
+#define ARCH_NR_GPIOS	(SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS)
+#else
+#define ARCH_NR_GPIOS	(SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS + \
+	SIRFSOC_GPIO_CPLD_SIZE + SIRFSOC_GPIO_IO_CPLD_SIZE + \
+	SIRFSOC_GPIO_HS_CPLD_SIZE)
+#endif
+
+#include <linux/errno.h>
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define gpio_to_irq	__gpio_to_irq
+
+void gpio_set_pull(unsigned gpio, int enable);
+void gpio_pull_down(unsigned gpio);
+void gpio_pull_up(unsigned gpio);
+
+#endif
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3634986..c5da284 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -162,6 +162,12 @@ config GPIO_SCH
 	  The Intel Tunnel Creek processor has 5 GPIOs powered by the
 	  core power rail and 9 from suspend power supply.
 
+config GPIO_SIRF
+	bool "CSR SiRFprimaII GPIO"
+	default y
+	help
+	  Say yes here to support GPIO interface on CSR SiRFprimaII.
+
 config GPIO_VX855
 	tristate "VIA VX855/VX875 GPIO"
 	depends on MFD_SUPPORT && PCI
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 7207112..f4ffd0e 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GPIO_S5PC100)	+= gpio-s5pc100.o
 obj-$(CONFIG_GPIO_S5PV210)	+= gpio-s5pv210.o
 
 obj-$(CONFIG_GPIO_SCH)		+= gpio-sch.o
+obj-$(CONFIG_GPIO_SIRF)		+= gpio-sirf.o
 obj-$(CONFIG_GPIO_STMPE)	+= gpio-stmpe.o
 obj-$(CONFIG_GPIO_SX150X)	+= gpio-sx150x.o
 obj-$(CONFIG_GPIO_TC3589X)	+= gpio-tc3589x.o
diff --git a/drivers/gpio/gpio-sirf.c b/drivers/gpio/gpio-sirf.c
new file mode 100644
index 0000000..34b5820
--- /dev/null
+++ b/drivers/gpio/gpio-sirf.c
@@ -0,0 +1,529 @@
+/*
+ * GPIO controller driver for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+#include <mach/pinmux.h>
+
+#define SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP0         43
+#define SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP1         44
+#define SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP2         45
+#define SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP3         46
+#define SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP4         47
+
+struct gpio_bank {
+	u8 group;
+	u16 irq;
+	u32 paden_bk_map;
+	u8 wake_mask;
+
+	spinlock_t lock;
+	struct gpio_chip chip;
+};
+
+static struct gpio_bank sirfsoc_gpio_bank[SIRFSOC_GPIO_NO_OF_BANKS] = {
+	{.group = 0, .irq = SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP0,},
+	{.group = 1, .irq = SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP1,},
+	{.group = 2, .irq = SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP2,},
+	{.group = 3, .irq = SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP3,},
+	{.group = 4, .irq = SIRFSOC_IRQ_SIRFSOC_GPIO_GROUP4,}
+};
+
+static DEFINE_SPINLOCK(gpio_lock);
+
+static struct gpio_bank *sirfsoc_irq_to_bank(unsigned int irq)
+{
+	int bk;
+
+	if ((irq < SIRFSOC_GPIO_IRQ_START) || (irq >= SIRFSOC_GPIO_IRQ_END)) {
+		printk(KERN_ALERT " Invalid GPIO IRQ/Bank: %d\n", irq);
+		return NULL;
+	}
+
+	bk = (irq - SIRFSOC_GPIO_IRQ_START) / SIRFSOC_GPIO_BANK_SIZE;
+	return &sirfsoc_gpio_bank[bk];
+}
+
+static int sirfsoc_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	return SIRFSOC_GPIO_IRQ_START + (chip->base + offset);
+}
+
+static int sirfsoc_irq_to_indx(unsigned int irq)
+{
+	return (irq - SIRFSOC_GPIO_IRQ_START) % SIRFSOC_GPIO_BANK_SIZE;
+}
+
+static struct gpio_bank *sirfsoc_gpio_to_bank(unsigned int gpio)
+{
+	unsigned int bk = gpio / SIRFSOC_GPIO_BANK_SIZE;
+
+	if (bk >= SIRFSOC_GPIO_NO_OF_BANKS) {
+		printk(KERN_ALERT "Invalid GPIO Number: %d\n", gpio);
+		return NULL;
+	} else {
+		return &sirfsoc_gpio_bank[bk];
+	}
+}
+
+static int sirfsoc_gpio_to_indx(unsigned int gpio)
+{
+	return gpio % SIRFSOC_GPIO_BANK_SIZE;
+}
+
+static void sirfsoc_gpio_irq_ack(struct irq_data *d)
+{
+	struct gpio_bank *bank = sirfsoc_irq_to_bank(d->irq);
+	int index = sirfsoc_irq_to_indx(d->irq);
+	u32 status, offset;
+	unsigned long flags;
+
+	if (bank != NULL) {
+		offset = SIRFSOC_GPIO_CTRL(bank->group, index);
+		spin_lock_irqsave(&gpio_lock, flags);
+
+		status = readl(sirfsoc_gpio_pinmux_base + offset);
+
+		writel(status, sirfsoc_gpio_pinmux_base + offset);
+		pr_debug("%s: ack gpio group %d index %d, status %#x\n",
+			__func__, bank->group, index,
+			readl(sirfsoc_gpio_pinmux_base + offset));
+		spin_unlock_irqrestore(&gpio_lock, flags);
+	}
+
+}
+
+static void _sirfsoc_gpio_irq_mask(unsigned int irq)
+{
+	struct gpio_bank *bank = sirfsoc_irq_to_bank(irq);
+	int index = sirfsoc_irq_to_indx(irq);
+	u32 status, offset;
+	unsigned long flags;
+
+	if (bank != NULL) {
+		pr_debug("%s: unmask gpio group %d index %d\n", __func__,
+			bank->group, index);
+		offset = SIRFSOC_GPIO_CTRL(bank->group, index);
+		spin_lock_irqsave(&gpio_lock, flags);
+		status = readl(sirfsoc_gpio_pinmux_base + offset);
+
+		status &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK;
+		status &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
+
+		writel(status, sirfsoc_gpio_pinmux_base + offset);
+
+		spin_unlock_irqrestore(&gpio_lock, flags);
+	}
+}
+
+
+static void sirfsoc_gpio_irq_mask(struct irq_data *d)
+{
+	_sirfsoc_gpio_irq_mask(d->irq);
+}
+
+static void sirfsoc_gpio_irq_unmask(struct irq_data *d)
+{
+	struct gpio_bank *bank = sirfsoc_irq_to_bank(d->irq);
+	int index = sirfsoc_irq_to_indx(d->irq);
+	u32 status, offset;
+	unsigned long flags;
+
+	if (bank != NULL) {
+		pr_debug("%s: unmask gpio group %d index %d\n", __func__,
+			bank->group, index);
+		offset = SIRFSOC_GPIO_CTRL(bank->group, index);
+
+		spin_lock_irqsave(&gpio_lock, flags);
+		status = readl(sirfsoc_gpio_pinmux_base + offset);
+
+		status &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
+		status |= SIRFSOC_GPIO_CTL_INTR_EN_MASK;
+
+		writel(status, sirfsoc_gpio_pinmux_base + offset);
+		spin_unlock_irqrestore(&gpio_lock, flags);
+	}
+}
+
+static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type)
+{
+	struct gpio_bank *bank = sirfsoc_irq_to_bank(d->irq);
+	int index = sirfsoc_irq_to_indx(d->irq);
+	u32 status, offset;
+	unsigned long flags;
+
+	if (bank == NULL)
+		return -EINVAL;
+
+	offset = SIRFSOC_GPIO_CTRL(bank->group, index);
+	spin_lock_irqsave(&gpio_lock, flags);
+	status = readl(sirfsoc_gpio_pinmux_base + offset);
+	status &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		status |= (SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
+		status &= ~SIRFSOC_GPIO_CTL_INTR_LOW_MASK;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		status &= ~SIRFSOC_GPIO_CTL_INTR_HIGH_MASK;
+		status |= (SIRFSOC_GPIO_CTL_INTR_LOW_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		status |=
+			(SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | SIRFSOC_GPIO_CTL_INTR_LOW_MASK |
+			 SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		status &= ~(SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
+		status |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		status |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK;
+		status &= ~(SIRFSOC_GPIO_CTL_INTR_LOW_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
+		break;
+	}
+
+	writel(status, sirfsoc_gpio_pinmux_base + offset);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	return 0;
+}
+
+static struct irq_chip sirfsoc_irq_chip = {
+	.name = "SiRF SoC GPIO IRQ",
+	.irq_ack = sirfsoc_gpio_irq_ack,
+	.irq_mask = sirfsoc_gpio_irq_mask,
+	.irq_unmask = sirfsoc_gpio_irq_unmask,
+	.irq_set_type = sirfsoc_gpio_irq_type,
+};
+
+static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc)
+{
+	struct gpio_bank *bank = NULL;
+	u32 status, ctrl;
+	int i, index = 0;
+
+	pr_debug("%s: irq %d\n", __func__, irq);
+
+	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
+		if (sirfsoc_gpio_bank[i].irq == irq) {
+			bank = &sirfsoc_gpio_bank[i];
+			break;
+		}
+	}
+
+	if (bank == NULL) {
+		printk(KERN_ALERT " Invalid GPIO IRQ/Bank: %d\n", irq);
+		handle_bad_irq(irq, desc);
+		return;
+	}
+
+	status = readl(sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_INT_STATUS(bank->group));
+	if (!status) {
+		printk(KERN_WARNING
+			"%s: gpio group %d status %#x no interrupt is flaged\n",
+			__func__, bank->group, status);
+		handle_bad_irq(irq, desc);
+		return;
+	}
+
+	while (status) {
+		ctrl = readl(sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_CTRL(bank->group, index));
+
+		/*
+		 * Here we must check whether the corresponding GPIO's interrupt
+		 * has been enabled, otherwise just skip it
+		 */
+		if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) {
+			pr_debug("%s: gpio group %d index %d happens\n",
+				__func__, bank->group, index);
+			irq =
+				(SIRFSOC_GPIO_IRQ_START +
+				 (bank->group * SIRFSOC_GPIO_BANK_SIZE)) + index;
+			generic_handle_irq(irq);
+		}
+
+		index++;
+		status = status >> 1;
+	}
+
+	return;
+}
+
+static inline void sirfsoc_gpio_set_input(struct gpio_bank *bank, unsigned ctrl_offset)
+{
+	u32 status;
+	status = readl(sirfsoc_gpio_pinmux_base + ctrl_offset);
+	status &= ~SIRFSOC_GPIO_CTL_OUT_EN_MASK;
+	writel(status, sirfsoc_gpio_pinmux_base + ctrl_offset);
+}
+
+static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	/*set direction as input and disable/mask irq */
+	sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->group, offset));
+	_sirfsoc_gpio_irq_mask(sirfsoc_gpio_to_irq(chip, offset));
+	sirfsoc_get_gpio(bank->group, offset);
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+	return 0;
+}
+
+static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	/*disable irq */
+	_sirfsoc_gpio_irq_mask(sirfsoc_gpio_to_irq(chip, offset));
+
+	/*set gpio to input */
+	sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->group, offset));
+
+	if (bank->paden_bk_map & (1 << offset))
+		sirfsoc_get_gpio(bank->group, offset);
+	else
+		sirfsoc_put_gpio(bank->group, offset);
+}
+
+static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+	int index = sirfsoc_gpio_to_indx(gpio);
+	unsigned long flags;
+	unsigned offset;
+
+	offset = SIRFSOC_GPIO_CTRL(bank->group, index);
+	spin_lock_irqsave(&bank->lock, flags);
+	sirfsoc_gpio_set_input(bank, offset);
+	spin_unlock_irqrestore(&bank->lock, flags);
+	return 0;
+}
+
+static inline void sirfsoc_gpio_set_output(struct gpio_bank *bank, unsigned offset,
+	int value)
+{
+	u32 status;
+
+	status = readl(sirfsoc_gpio_pinmux_base + offset);
+	if (value)
+		status |= SIRFSOC_GPIO_CTL_DATAOUT_MASK;
+	else
+		status &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK;
+
+	status &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK;
+	status |= SIRFSOC_GPIO_CTL_OUT_EN_MASK;
+
+	writel(status, sirfsoc_gpio_pinmux_base + offset);
+}
+
+static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value)
+{
+	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+	int index = sirfsoc_gpio_to_indx(gpio);
+	u32 offset;
+	unsigned long flags;
+
+	offset = SIRFSOC_GPIO_CTRL(bank->group, index);
+	spin_lock_irqsave(&gpio_lock, flags);
+	sirfsoc_gpio_set_output(bank, offset, value);
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	return 0;
+}
+
+void gpio_set_pull(unsigned gpio, int enable)
+{
+	struct gpio_bank *bank = sirfsoc_gpio_to_bank(gpio);
+	int index = sirfsoc_gpio_to_indx(gpio);
+	u32 status, offset;
+	unsigned long flags;
+
+	BUG_ON(!bank);
+
+	offset = SIRFSOC_GPIO_CTRL(bank->group, index);
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	status = readl(sirfsoc_gpio_pinmux_base + offset);
+
+	if (enable)
+		status |= SIRFSOC_GPIO_CTL_PULL_MASK;
+	else
+		status &= ~SIRFSOC_GPIO_CTL_PULL_MASK;
+
+	writel(status, sirfsoc_gpio_pinmux_base + offset);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(gpio_set_pull);
+
+void gpio_pull_up(unsigned int gpio)
+{
+	struct gpio_bank *bank = sirfsoc_gpio_to_bank(gpio);
+	int index = sirfsoc_gpio_to_indx(gpio);
+	u32 status, offset;
+	unsigned long flags;
+
+	BUG_ON(!bank);
+
+	gpio_set_pull(gpio, 1);
+
+	offset = SIRFSOC_GPIO_CTRL(bank->group, index);
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	status = readl(sirfsoc_gpio_pinmux_base + offset);
+	status |= SIRFSOC_GPIO_CTL_PULL_HIGH;
+	writel(status, sirfsoc_gpio_pinmux_base + offset);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(gpio_pull_up);
+
+void gpio_pull_down(unsigned int gpio)
+{
+	struct gpio_bank *bank = sirfsoc_gpio_to_bank(gpio);
+	int index = sirfsoc_gpio_to_indx(gpio);
+	u32 status, offset;
+	unsigned long flags;
+
+	BUG_ON(!bank);
+
+	gpio_set_pull(gpio, 1);
+
+	offset = SIRFSOC_GPIO_CTRL(bank->group, index);
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	status = readl(sirfsoc_gpio_pinmux_base + offset);
+	status &= ~SIRFSOC_GPIO_CTL_PULL_HIGH;
+	writel(status, sirfsoc_gpio_pinmux_base + offset);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(gpio_pull_down);
+
+static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+	u32 status;
+
+	status = readl(sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_CTRL(bank->group, offset));
+
+	return !!(status & SIRFSOC_GPIO_CTL_DATAIN_MASK);
+}
+
+static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset,
+	int value)
+{
+	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+	u32 status;
+
+	status = readl(sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_CTRL(bank->group, offset));
+	if (value)
+		status |= SIRFSOC_GPIO_CTL_DATAOUT_MASK;
+	else
+		status &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK;
+	writel(status, sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_CTRL(bank->group, offset));
+}
+
+static int sirfsoc_gpio_probe(struct platform_device *pdev)
+{
+	int i;
+
+	struct gpio_bank *bank;
+	int gpio = 0;
+
+	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
+		bank = &sirfsoc_gpio_bank[i];
+		spin_lock_init(&bank->lock);
+		bank->paden_bk_map = readl(sirfsoc_gpio_pinmux_base + SIRFSOC_GPIO_PAD_EN(i));
+		irq_set_chained_handler(bank->irq, sirfsoc_gpio_handle_irq);
+
+		bank->chip.request = sirfsoc_gpio_request;
+		bank->chip.free = sirfsoc_gpio_free;
+		bank->chip.direction_input = sirfsoc_gpio_direction_input;
+		bank->chip.get = sirfsoc_gpio_get_value;
+		bank->chip.direction_output = sirfsoc_gpio_direction_output;
+		bank->chip.set = sirfsoc_gpio_set_value;
+		bank->chip.to_irq = sirfsoc_gpio_to_irq;
+
+		bank->chip.label = "gpio";
+		bank->chip.base = gpio;
+
+		gpio += SIRFSOC_GPIO_BANK_SIZE;
+		bank->chip.ngpio = SIRFSOC_GPIO_BANK_SIZE;
+		gpiochip_add(&bank->chip);
+	}
+
+	for (i = SIRFSOC_GPIO_IRQ_START; i < SIRFSOC_GPIO_IRQ_END; i++) {
+		irq_set_chip(i, &sirfsoc_irq_chip);
+		irq_set_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+	}
+
+	return 0;
+}
+
+static int sirfsoc_gpio_remove(struct platform_device *dev)
+{
+	return 0;
+}
+
+static const struct of_device_id sirf_gpio_of_match[] = {
+	{.compatible = "sirf,prima2-gpio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sirf_gpio_of_match);
+
+static struct platform_driver sirfsoc_gpio_driver = {
+	.driver		= {
+		.name	= "sirfsoc_gpio",
+		.of_match_table = sirf_gpio_of_match,
+	},
+	.probe		= sirfsoc_gpio_probe,
+	.remove		= sirfsoc_gpio_remove,
+};
+
+static int __init sirfsoc_gpio_init(void)
+{
+	return platform_driver_register(&sirfsoc_gpio_driver);
+}
+core_initcall(sirfsoc_gpio_init);
+
+static void __exit sirfsoc_gpio_exit(void)
+{
+	platform_driver_unregister(&sirfsoc_gpio_driver);
+}
+module_exit(sirfsoc_gpio_exit);
+
+MODULE_DESCRIPTION("SiRFSoC gpio driver");
+MODULE_AUTHOR("Yuping Luo <yuping.luo@csr.com>, Barry Song <baohua.song@csr.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.1



Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog

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

* [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller
  2011-07-26  8:13 ` [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller Barry Song
@ 2011-07-26 10:09   ` Russell King - ARM Linux
  2011-07-26 10:46     ` PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller) Russell King - ARM Linux
                       ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Russell King - ARM Linux @ 2011-07-26 10:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 26, 2011 at 01:13:13AM -0700, Barry Song wrote:
> diff --git a/arch/arm/mach-prima2/include/mach/gpio.h b/arch/arm/mach-prima2/include/mach/gpio.h
> new file mode 100644
> index 0000000..25673b1
> --- /dev/null
> +++ b/arch/arm/mach-prima2/include/mach/gpio.h
> @@ -0,0 +1,34 @@
> +/*
> + * arch/arm/mach-prima2/include/mach/gpio.h
> + *
> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
> + *
> + * Licensed under GPLv2 or later.
> + */
> +
> +#ifndef __MACH_GPIO_H
> +#define __MACH_GPIO_H
> +
> +#include <mach/irqs.h>
> +
> +#ifndef CONFIG_GPIO_SIRFCPLD
> +#define ARCH_NR_GPIOS	(SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS)
> +#else
> +#define ARCH_NR_GPIOS	(SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS + \
> +	SIRFSOC_GPIO_CPLD_SIZE + SIRFSOC_GPIO_IO_CPLD_SIZE + \
> +	SIRFSOC_GPIO_HS_CPLD_SIZE)
> +#endif
> +
> +#include <linux/errno.h>

Why do you need linux/errno.h?  asm-generic/gpio.h already includes this.

> +#include <asm-generic/gpio.h>
> +
> +#define gpio_get_value	__gpio_get_value
> +#define gpio_set_value	__gpio_set_value
> +#define gpio_cansleep	__gpio_cansleep

Hmm, yet another trivial gpio implementation.  We have 24 others just like
this.  Well, mainline does... I have just one.  Patches after the merge
window closes.

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-07-26 10:09   ` Russell King - ARM Linux
@ 2011-07-26 10:46     ` Russell King - ARM Linux
  2011-07-26 18:32       ` Colin Cross
  2011-08-08  9:09     ` [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller Barry Song
  2011-08-08  9:32     ` Linus Walleij
  2 siblings, 1 reply; 19+ messages in thread
From: Russell King - ARM Linux @ 2011-07-26 10:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 26, 2011 at 11:09:28AM +0100, Russell King - ARM Linux wrote:
> Hmm, yet another trivial gpio implementation.  We have 24 others just like
> this.  Well, mainline does... I have just one.  Patches after the merge
> window closes.

As an additional note to this: we _really_ need to get on top of the
includes of mach/gpio.h rather than linux/gpio.h - there are around 139
files in mainline (this morning) which include mach/gpio.h directly.

There's one which includes both asm/gpio.h and mach/gpio.h, which is
silly when you look at what asm/gpio.h contains - maybe one attempt
to include mach/gpio.h wasn't enough!

These includes get in the way of consolidating stuff out of mach/gpio.h
into asm/gpio.h - moving stuff out of mach/gpio.h could take it out of
view of these files, thereby causing build errors.

What is even less clear is whether changing these mach/gpio.h includes
to linux/gpio.h is correct or not.

So, what I'd like all platform and all soc maintainers to do is to:

	grep -rl '<mach/gpio.h>' arch/arm drivers

and investigate their files from that list which they're responsible for,
and submit patches to _me_ to fix these includes up (preferably to use
linux/gpio.h).  I'd also like them to do a better job at spotting these
while reviewing patches on the list to help reduce new occurances of
this.

Thanks.

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-07-26 10:46     ` PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller) Russell King - ARM Linux
@ 2011-07-26 18:32       ` Colin Cross
  2011-07-26 18:39         ` Russell King - ARM Linux
  0 siblings, 1 reply; 19+ messages in thread
From: Colin Cross @ 2011-07-26 18:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 26, 2011 at 3:46 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Jul 26, 2011 at 11:09:28AM +0100, Russell King - ARM Linux wrote:
>> Hmm, yet another trivial gpio implementation. ?We have 24 others just like
>> this. ?Well, mainline does... I have just one. ?Patches after the merge
>> window closes.
>
> As an additional note to this: we _really_ need to get on top of the
> includes of mach/gpio.h rather than linux/gpio.h - there are around 139
> files in mainline (this morning) which include mach/gpio.h directly.
>
> There's one which includes both asm/gpio.h and mach/gpio.h, which is
> silly when you look at what asm/gpio.h contains - maybe one attempt
> to include mach/gpio.h wasn't enough!
>
> These includes get in the way of consolidating stuff out of mach/gpio.h
> into asm/gpio.h - moving stuff out of mach/gpio.h could take it out of
> view of these files, thereby causing build errors.
>
> What is even less clear is whether changing these mach/gpio.h includes
> to linux/gpio.h is correct or not.
>
> So, what I'd like all platform and all soc maintainers to do is to:
>
> ? ? ? ?grep -rl '<mach/gpio.h>' arch/arm drivers
>
> and investigate their files from that list which they're responsible for,
> and submit patches to _me_ to fix these includes up (preferably to use
> linux/gpio.h). ?I'd also like them to do a better job at spotting these
> while reviewing patches on the list to help reduce new occurances of
> this.
>
> Thanks.

Tegra has four uses of mach/gpio.h:
arch/arm/mach-tegra/board-trimslice-pinmux.c
arch/arm/mach-tegra/board-paz00.c
arch/arm/mach-tegra/board-trimslice.c
drivers/mmc/host/sdhci-tegra.c

Each of these files calls tegra_gpio_enable/tegra_gpio_disable, which
flip the pin in/out of gpio mode.  Including linux/gpio.h and
mach/gpio.h was deliberate, so that when linux/gpio.h stops causing
mach/gpio.h to be included, the tegra gpio apis are still available.
Should I move the tegra gpio apis to a separate include and drop
mach/gpio.h?

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-07-26 18:32       ` Colin Cross
@ 2011-07-26 18:39         ` Russell King - ARM Linux
  2011-07-26 19:10           ` Nicolas Pitre
  0 siblings, 1 reply; 19+ messages in thread
From: Russell King - ARM Linux @ 2011-07-26 18:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 26, 2011 at 11:32:22AM -0700, Colin Cross wrote:
> On Tue, Jul 26, 2011 at 3:46 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Tue, Jul 26, 2011 at 11:09:28AM +0100, Russell King - ARM Linux wrote:
> >> Hmm, yet another trivial gpio implementation. ?We have 24 others just like
> >> this. ?Well, mainline does... I have just one. ?Patches after the merge
> >> window closes.
> >
> > As an additional note to this: we _really_ need to get on top of the
> > includes of mach/gpio.h rather than linux/gpio.h - there are around 139
> > files in mainline (this morning) which include mach/gpio.h directly.
> >
> > There's one which includes both asm/gpio.h and mach/gpio.h, which is
> > silly when you look at what asm/gpio.h contains - maybe one attempt
> > to include mach/gpio.h wasn't enough!
> >
> > These includes get in the way of consolidating stuff out of mach/gpio.h
> > into asm/gpio.h - moving stuff out of mach/gpio.h could take it out of
> > view of these files, thereby causing build errors.
> >
> > What is even less clear is whether changing these mach/gpio.h includes
> > to linux/gpio.h is correct or not.
> >
> > So, what I'd like all platform and all soc maintainers to do is to:
> >
> > ? ? ? ?grep -rl '<mach/gpio.h>' arch/arm drivers
> >
> > and investigate their files from that list which they're responsible for,
> > and submit patches to _me_ to fix these includes up (preferably to use
> > linux/gpio.h). ?I'd also like them to do a better job at spotting these
> > while reviewing patches on the list to help reduce new occurances of
> > this.
> >
> > Thanks.
> 
> Tegra has four uses of mach/gpio.h:
> arch/arm/mach-tegra/board-trimslice-pinmux.c
> arch/arm/mach-tegra/board-paz00.c
> arch/arm/mach-tegra/board-trimslice.c
> drivers/mmc/host/sdhci-tegra.c
> 
> Each of these files calls tegra_gpio_enable/tegra_gpio_disable, which
> flip the pin in/out of gpio mode.  Including linux/gpio.h and
> mach/gpio.h was deliberate, so that when linux/gpio.h stops causing
> mach/gpio.h to be included, the tegra gpio apis are still available.
> Should I move the tegra gpio apis to a separate include and drop
> mach/gpio.h?

I don't think there's any plans to break the:

linux/gpio.h -> asm/gpio.h -> mach/gpio.h

include path at the moment, as platforms do define ARCH_NR_GPIO,
which has to be done before asm-generic/gpiolib.h is included.

The problem which is there at the moment is that moving stuff out of
mach/gpio.h is *dangerous* because soo much stuff includes mach/gpio.h,
it's impossible to tell whether moving stuff like gpio_set_value,
gpio_get_value, etc into asm/gpio.h is going to break anything - and
there's no way I can get sufficient coverage to check that.

So, the only way I can think of sorting this out is to forcefully
change all mach/gpio.h to be linux/gpio.h first, before starting
to migrate stuff out of mach/gpio.h.

What we may do later is make the include of mach/gpio.h conditional,
and those platforms with their own specific stuff would continue to
include that.  Those which don't need mach/gpio.h can then live on
without it.

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-07-26 18:39         ` Russell King - ARM Linux
@ 2011-07-26 19:10           ` Nicolas Pitre
  2011-07-27  2:08             ` Barry Song
  2011-07-29 15:58             ` Linus Walleij
  0 siblings, 2 replies; 19+ messages in thread
From: Nicolas Pitre @ 2011-07-26 19:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 26 Jul 2011, Russell King - ARM Linux wrote:

> I don't think there's any plans to break the:
> 
> linux/gpio.h -> asm/gpio.h -> mach/gpio.h
> 
> include path at the moment, as platforms do define ARCH_NR_GPIO,
> which has to be done before asm-generic/gpiolib.h is included.

Well, this GPIO business is the biggest hurdle towards a single kernel 
image that can support multiple SOCs at the moment, and the only one for 
which I have no solution yet.  Anything that could help removing 
mach/gpio.h from asm/gpio.h would be welcome.


Nicolas

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-07-26 19:10           ` Nicolas Pitre
@ 2011-07-27  2:08             ` Barry Song
  2011-07-27  2:51               ` Nicolas Pitre
  2011-07-29 15:58             ` Linus Walleij
  1 sibling, 1 reply; 19+ messages in thread
From: Barry Song @ 2011-07-27  2:08 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/27 Nicolas Pitre <nicolas.pitre@linaro.org>:
> On Tue, 26 Jul 2011, Russell King - ARM Linux wrote:
>
>> I don't think there's any plans to break the:
>>
>> linux/gpio.h -> asm/gpio.h -> mach/gpio.h
>>
>> include path at the moment, as platforms do define ARCH_NR_GPIO,
>> which has to be done before asm-generic/gpiolib.h is included.
>
> Well, this GPIO business is the biggest hurdle towards a single kernel
> image that can support multiple SOCs at the moment, and the only one for
> which I have no solution yet. ?Anything that could help removing
> mach/gpio.h from asm/gpio.h would be welcome.

After reading all the following patches,

1. use CONFIG_PHYS_OFFSET to prepare for removal of a bunch of
<mach/memory.h> files

2. move from ARM_DMA_ZONE_SIZE to mdesc->dma_zone_size

3. convert boot_params to atag_offset

Have i lost anything for the work on 1 and 2? considering some
platforms need CONSISTENT_DMA_SIZE more than the default 2MB in
arch/arm/include/asm/memory.h, we can't remove all memory.h only by
defining CONFIG_PHYS_OFFSET and moving ARM_DMA_ZONE_SIZE to
mdesc->dma_zone_size. So CONSISTENT_DMA_SIZE should also be a left
issue except gpio.h.

>
>
> Nicolas
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-07-27  2:08             ` Barry Song
@ 2011-07-27  2:51               ` Nicolas Pitre
  0 siblings, 0 replies; 19+ messages in thread
From: Nicolas Pitre @ 2011-07-27  2:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 27 Jul 2011, Barry Song wrote:

> 2011/7/27 Nicolas Pitre <nicolas.pitre@linaro.org>:
> > On Tue, 26 Jul 2011, Russell King - ARM Linux wrote:
> >
> >> I don't think there's any plans to break the:
> >>
> >> linux/gpio.h -> asm/gpio.h -> mach/gpio.h
> >>
> >> include path at the moment, as platforms do define ARCH_NR_GPIO,
> >> which has to be done before asm-generic/gpiolib.h is included.
> >
> > Well, this GPIO business is the biggest hurdle towards a single kernel
> > image that can support multiple SOCs at the moment, and the only one for
> > which I have no solution yet. ?Anything that could help removing
> > mach/gpio.h from asm/gpio.h would be welcome.
> 
> After reading all the following patches,
> 
> 1. use CONFIG_PHYS_OFFSET to prepare for removal of a bunch of
> <mach/memory.h> files
> 
> 2. move from ARM_DMA_ZONE_SIZE to mdesc->dma_zone_size
> 
> 3. convert boot_params to atag_offset
> 
> Have i lost anything for the work on 1 and 2? considering some
> platforms need CONSISTENT_DMA_SIZE more than the default 2MB in
> arch/arm/include/asm/memory.h, we can't remove all memory.h only by
> defining CONFIG_PHYS_OFFSET and moving ARM_DMA_ZONE_SIZE to
> mdesc->dma_zone_size. So CONSISTENT_DMA_SIZE should also be a left
> issue except gpio.h.

CONSISTENT_DMA_SIZE can be solved the same way as ARM_DMA_ZONE_SIZE, 
plus a few changes in dma-mapping.c to dynamically allocate the 
consistent_pte array.

But that's far from the end of it.  In a nutshell:

- We have to get rid of mach/vmalloc.h (trivial)

- We have to kill every SOC specific definition for CLOCK_TICK_RATE and 
  remove mach/timex.h.

- All mach/io.h need a similar refactoring.

- asm/irq.h must stop including mach/irqs.h, and everyone should 
  initialize mdesc->nr_irqs

- mach/entry-macro.S should be translated into something that hooks to 
  mdesc->handle_irq.

- mach/system.h content needs to be moved to out-of-line indirect calls.

- A multy-SOC kernel binary might not support CONFIG_DEBUG_LL out of the 
  box.

- And there are a few odd cases we probably might not find sufficient 
  motivation to fix them and simply exclude them from a single image 
  config.

But there is mach/gpio.h which is the real bummer at the moment.


Nicolas

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-07-26 19:10           ` Nicolas Pitre
  2011-07-27  2:08             ` Barry Song
@ 2011-07-29 15:58             ` Linus Walleij
  2011-08-09  7:22               ` Barry Song
  1 sibling, 1 reply; 19+ messages in thread
From: Linus Walleij @ 2011-07-29 15:58 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/26 Nicolas Pitre <nicolas.pitre@linaro.org>:
> On Tue, 26 Jul 2011, Russell King - ARM Linux wrote:
>
>> I don't think there's any plans to break the:
>>
>> linux/gpio.h -> asm/gpio.h -> mach/gpio.h
>>
>> include path at the moment, as platforms do define ARCH_NR_GPIO,
>> which has to be done before asm-generic/gpiolib.h is included.
>
> Well, this GPIO business is the biggest hurdle towards a single kernel
> image that can support multiple SOCs at the moment, and the only one for
> which I have no solution yet. ?Anything that could help removing
> mach/gpio.h from asm/gpio.h would be welcome.

I've been trying to address it somewhat by converting existing users to
use struct gpio_chip and struct irq_chip.

However I ran into a brick wall as soon as an advanced GPIO controller
such as those in U8500 or the OMAPs needed anything custom apart
from what is done in the API in <linux/gpio.h>, such as configuring pin
bias and muxing pins.

Different alternatives have been floated to LKML, also a post
of two different approaches for patches resolving the issue
in two different ways (see subject [PATCH 0/2] RFC:
gpio: driver-local pin configuration)

Due to lack of interest i.e. no ACKing nor NACKing of the patches,
nor any approach being chosen by the subsystem maintainer, I'm
mainly resting my case, intially we (me & Grant) planned to have
a solution for this early in the 3.1 cycle but that has failed.

A third solution is to complete the pincfg subsystem that I'm
working on and which will naturally (hopefully) split off the
controversial parts of GPIO drivers. Sadly this will involve a bit of
upfront overhead work :-/

Thanks,
Linus Walleij

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

* [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller
  2011-07-26 10:09   ` Russell King - ARM Linux
  2011-07-26 10:46     ` PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller) Russell King - ARM Linux
@ 2011-08-08  9:09     ` Barry Song
  2011-08-08  9:32     ` Linus Walleij
  2 siblings, 0 replies; 19+ messages in thread
From: Barry Song @ 2011-08-08  9:09 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/26 Russell King - ARM Linux <linux@arm.linux.org.uk>:
> On Tue, Jul 26, 2011 at 01:13:13AM -0700, Barry Song wrote:
>> diff --git a/arch/arm/mach-prima2/include/mach/gpio.h b/arch/arm/mach-prima2/include/mach/gpio.h
>> new file mode 100644
>> index 0000000..25673b1
>> --- /dev/null
>> +++ b/arch/arm/mach-prima2/include/mach/gpio.h
>> @@ -0,0 +1,34 @@
>> +/*
>> + * arch/arm/mach-prima2/include/mach/gpio.h
>> + *
>> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +
>> +#ifndef __MACH_GPIO_H
>> +#define __MACH_GPIO_H
>> +
>> +#include <mach/irqs.h>
>> +
>> +#ifndef CONFIG_GPIO_SIRFCPLD
>> +#define ARCH_NR_GPIOS ? ? ? ?(SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS)
>> +#else
>> +#define ARCH_NR_GPIOS ? ? ? ?(SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS + \
>> + ? ? SIRFSOC_GPIO_CPLD_SIZE + SIRFSOC_GPIO_IO_CPLD_SIZE + \
>> + ? ? SIRFSOC_GPIO_HS_CPLD_SIZE)
>> +#endif
>> +
>> +#include <linux/errno.h>
>
> Why do you need linux/errno.h? ?asm-generic/gpio.h already includes this.
>
>> +#include <asm-generic/gpio.h>
>> +
>> +#define gpio_get_value ? ? ? __gpio_get_value
>> +#define gpio_set_value ? ? ? __gpio_set_value
>> +#define gpio_cansleep ? ? ? ?__gpio_cansleep
>
> Hmm, yet another trivial gpio implementation. ?We have 24 others just like
> this. ?Well, mainline does... I have just one.

Ok.
this gpio driver includes two parts: gpio chip and irq chip.  For gpio
chip, we could import gpio-generic and delete
sirfsoc_gpio_direction_input, sirfsoc_gpio_get_value,
sirfsoc_gpio_direction_output and so on.
For the part of irq chip, i don't see much benefit from generic-irq.
all of sirfsoc_gpio_irq_ack, sirfsoc_gpio_irq_mask and
sirfsoc_gpio_irq_unmask are CSR-specific.  irq_gc_ack_set_bit,
irq_gc_mask_clr_bit and irq_gc_mask_set_bit are not practicable to
this chip.

-barry

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

* [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller
  2011-07-26 10:09   ` Russell King - ARM Linux
  2011-07-26 10:46     ` PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller) Russell King - ARM Linux
  2011-08-08  9:09     ` [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller Barry Song
@ 2011-08-08  9:32     ` Linus Walleij
  2 siblings, 0 replies; 19+ messages in thread
From: Linus Walleij @ 2011-08-08  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/26 Russell King - ARM Linux <linux@arm.linux.org.uk>:
> [Barry]
>> +#include <asm-generic/gpio.h>
>> +
>> +#define gpio_get_value ? ? ? __gpio_get_value
>> +#define gpio_set_value ? ? ? __gpio_set_value
>> +#define gpio_cansleep ? ? ? ?__gpio_cansleep
>
> Hmm, yet another trivial gpio implementation. ?We have 24 others just like
> this. ?Well, mainline does... I have just one. ?Patches after the merge
> window closes.

Hm, that sounds very good, now the merge window is closed, can you
post them? Me and Ben have some stash of GPIO patches as well so
we may just as well base them atop of your cleanup.

Thanks,
Linus Walleij

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-07-29 15:58             ` Linus Walleij
@ 2011-08-09  7:22               ` Barry Song
  2011-08-09 13:15                 ` Arnd Bergmann
  0 siblings, 1 reply; 19+ messages in thread
From: Barry Song @ 2011-08-09  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/29 Linus Walleij <linus.ml.walleij@gmail.com>:
> 2011/7/26 Nicolas Pitre <nicolas.pitre@linaro.org>:
>> On Tue, 26 Jul 2011, Russell King - ARM Linux wrote:
>>
>>> I don't think there's any plans to break the:
>>>
>>> linux/gpio.h -> asm/gpio.h -> mach/gpio.h
>>>
>>> include path at the moment, as platforms do define ARCH_NR_GPIO,
>>> which has to be done before asm-generic/gpiolib.h is included.
>>
>> Well, this GPIO business is the biggest hurdle towards a single kernel
>> image that can support multiple SOCs at the moment, and the only one for
>> which I have no solution yet. ?Anything that could help removing
>> mach/gpio.h from asm/gpio.h would be welcome.
>
> I've been trying to address it somewhat by converting existing users to
> use struct gpio_chip and struct irq_chip.
>
> However I ran into a brick wall as soon as an advanced GPIO controller
> such as those in U8500 or the OMAPs needed anything custom apart
> from what is done in the API in <linux/gpio.h>, such as configuring pin
> bias and muxing pins.

The patch wants to eliminate the requirement of self-defined
SoC-specific gpio APIs. The intent is that you want to delete files
arch/arm/mach-xxx/include/mach/gpio.h.

I guess same issues exist for other hardwares except GPIO. For
example, almost every different SoC has different DMA API, for
example:
mach-bcmring/dma.c:EXPORT_SYMBOL(dma_alloc_descriptor_ring);
mach-davinci/dma.c:EXPORT_SYMBOL(edma_alloc_channel);
mach-davinci/dma.c:EXPORT_SYMBOL(edma_clear_event);
mach-imx/dma-v1.c:EXPORT_SYMBOL(imx_dma_setup_single);
mach-s3c64xx/dma.c:EXPORT_SYMBOL(s3c2410_dma_enqueue);

Do we also want to delete all arch/arm/mach-xxx/include/mach/dma.h?

Or do we want to delete the whole arch/arm/mach-xxx/include/mach directory?

If not, it is probably that SoC can still hold some chip-specific APIs
in arch/arm/mach-xxx/include/mach/yyy.h.

>
> Different alternatives have been floated to LKML, also a post
> of two different approaches for patches resolving the issue
> in two different ways (see subject [PATCH 0/2] RFC:
> gpio: driver-local pin configuration)
>
> Due to lack of interest i.e. no ACKing nor NACKing of the patches,
> nor any approach being chosen by the subsystem maintainer, I'm
> mainly resting my case, intially we (me & Grant) planned to have
> a solution for this early in the 3.1 cycle but that has failed.
>
> A third solution is to complete the pincfg subsystem that I'm
> working on and which will naturally (hopefully) split off the
> controversial parts of GPIO drivers. Sadly this will involve a bit of
> upfront overhead work :-/
>
> Thanks,
> Linus Walleij

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-08-09  7:22               ` Barry Song
@ 2011-08-09 13:15                 ` Arnd Bergmann
  2011-08-11  2:25                   ` Barry Song
  2011-09-19  9:10                   ` Linus Walleij
  0 siblings, 2 replies; 19+ messages in thread
From: Arnd Bergmann @ 2011-08-09 13:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 09 August 2011, Barry Song wrote:
> I guess same issues exist for other hardwares except GPIO. For
> example, almost every different SoC has different DMA API, for
> example:
> mach-bcmring/dma.c:EXPORT_SYMBOL(dma_alloc_descriptor_ring);
> mach-davinci/dma.c:EXPORT_SYMBOL(edma_alloc_channel);
> mach-davinci/dma.c:EXPORT_SYMBOL(edma_clear_event);
> mach-imx/dma-v1.c:EXPORT_SYMBOL(imx_dma_setup_single);
> mach-s3c64xx/dma.c:EXPORT_SYMBOL(s3c2410_dma_enqueue);
> 
> Do we also want to delete all arch/arm/mach-xxx/include/mach/dma.h?

We need to eliminate all header files that have conflicting names
and that are used by drivers or other header files outside of mach-*.
How we get there is very different for each of these headers.

> Or do we want to delete the whole arch/arm/mach-xxx/include/mach directory?

Ideally, yes. However, that will take a lot of time. Meanwhile, we should
rename the individual header files to have unique names for each API,
and ensure that the symbols don't clash.

> If not, it is probably that SoC can still hold some chip-specific APIs
> in arch/arm/mach-xxx/include/mach/yyy.h.

Can you name an example? Most of the ones I can think of will not work
in a multiplatform kernel.

	Arnd

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-08-09 13:15                 ` Arnd Bergmann
@ 2011-08-11  2:25                   ` Barry Song
  2011-08-11  8:30                     ` Russell King - ARM Linux
  2011-09-19  9:10                   ` Linus Walleij
  1 sibling, 1 reply; 19+ messages in thread
From: Barry Song @ 2011-08-11  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

2011/8/9 Arnd Bergmann <arnd@arndb.de>:
> On Tuesday 09 August 2011, Barry Song wrote:
>> I guess same issues exist for other hardwares except GPIO. For
>> example, almost every different SoC has different DMA API, for
>> example:
>> mach-bcmring/dma.c:EXPORT_SYMBOL(dma_alloc_descriptor_ring);
>> mach-davinci/dma.c:EXPORT_SYMBOL(edma_alloc_channel);
>> mach-davinci/dma.c:EXPORT_SYMBOL(edma_clear_event);
>> mach-imx/dma-v1.c:EXPORT_SYMBOL(imx_dma_setup_single);
>> mach-s3c64xx/dma.c:EXPORT_SYMBOL(s3c2410_dma_enqueue);
>>
>> Do we also want to delete all arch/arm/mach-xxx/include/mach/dma.h?
>
> We need to eliminate all header files that have conflicting names
> and that are used by drivers or other header files outside of mach-*.
> How we get there is very different for each of these headers.

now every SoCs have different DMA APIs due to different DMA controller:

1. Tegra(dma has a queue with enqueue and dequeue API):
int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
        struct tegra_dma_req *req);
int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
        struct tegra_dma_req *req);
void tegra_dma_dequeue(struct tegra_dma_channel *ch);
void tegra_dma_flush(struct tegra_dma_channel *ch);

bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch,
        struct tegra_dma_req *req);
bool tegra_dma_is_empty(struct tegra_dma_channel *ch);

struct tegra_dma_channel *tegra_dma_allocate_channel(int mode);
void tegra_dma_free_channel(struct tegra_dma_channel *ch);


2. samsung(with queue and request/free, ctrl):
/* s3c2410_dma_request
 *
 * request a dma channel exclusivley
*/

extern int s3c2410_dma_request(enum dma_ch channel,
                               struct s3c2410_dma_client *, void *dev);


/* s3c2410_dma_ctrl
 *
 * change the state of the dma channel
*/

extern int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op);

/* s3c2410_dma_setflags
 *
 * set the channel's flags to a given state
*/

extern int s3c2410_dma_setflags(enum dma_ch channel,
                                unsigned int flags);

/* s3c2410_dma_free
 *
 * free the dma channel (will also abort any outstanding operations)
*/

extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *);

/* s3c2410_dma_enqueue
 *
 * place the given buffer onto the queue of operations for the channel.
 * The buffer must be allocated from dma coherent memory, or the Dcache/WB
 * drained before the buffer is given to the DMA system.

*/

extern int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
                               dma_addr_t data, int size);

/* s3c2410_dma_config
 *
 * configure the dma channel
*/

extern int s3c2410_dma_config(enum dma_ch channel, int xferunit);


3. PXA(pretty simple)
int __init pxa_init_dma(int irq, int num_ch);

int pxa_request_dma (char *name,
                         pxa_dma_prio prio,
                         void (*irq_handler)(int, void *),
                         void *data);

void pxa_free_dma (int dma_ch);


4. qualcomm msm(with queue cmd and exec cmd):
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);

5. TI omap(with request/free/enable/param config/mode set....)
extern void omap_set_dma_priority(int lch, int dst_port, int priority);
extern int omap_request_dma(int dev_id, const char *dev_name,
                        void (*callback)(int lch, u16 ch_status, void *data),
                        void *data, int *dma_ch);
extern void omap_enable_dma_irq(int ch, u16 irq_bits);
extern void omap_disable_dma_irq(int ch, u16 irq_bits);
extern void omap_free_dma(int ch);
extern void omap_start_dma(int lch);
extern void omap_stop_dma(int lch);
extern void omap_set_dma_transfer_params(int lch, int data_type,
                                         int elem_count, int frame_count,
                                         int sync_mode,
                                         int dma_trigger, int src_or_dst_synch);
extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
                                    u32 color);
extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);

extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
                                    unsigned long src_start,
                                    int src_ei, int src_fi);
extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
extern void omap_set_dma_src_data_pack(int lch, int enable);
extern void omap_set_dma_src_burst_mode(int lch,
                                        enum omap_dma_burst_mode burst_mode);

extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
                                     unsigned long dest_start,
                                     int dst_ei, int dst_fi);
extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
extern void omap_set_dma_dest_data_pack(int lch, int enable);
extern void omap_set_dma_dest_burst_mode(int lch,


we might figure out some common DMA API framework so that all SoCs can
use. i think:

group1 : request/free/enable/disable/set_mode/set_priority are common
to all, but set_mode/set_priority can be empty.
group2:  enqueue/dequeue  are common to DMAC with queues
group3:  many param configurations.
group4:  other DMA controller with special work mode which can't be
covered by group1-3.
for example, prima2 has a 2D dma controller,  In 2-D DMA, the system
memory space is interpreted as a 2-D layout instead of a linear 1-D
layout. More specifically, the system memory can be considered as
multiple data lines. The length of the data line is determined by the
user-selected DMA_WIDTH register. The user can specify a data window
that the user wants to access using four parameters:
? Start address
? X length
? Y length
? Width

we might also want a dma_chip with many callbacks like gpio and irq,
then move all dma drivers to drivers/dma just like Linus W is moving
all gpio drivers to drivers/gpio. How do you think?

>
>> Or do we want to delete the whole arch/arm/mach-xxx/include/mach directory?
>
> Ideally, yes. However, that will take a lot of time. Meanwhile, we should
> rename the individual header files to have unique names for each API,
> and ensure that the symbols don't clash.
>
>> If not, it is probably that SoC can still hold some chip-specific APIs
>> in arch/arm/mach-xxx/include/mach/yyy.h.
>
> Can you name an example? Most of the ones I can think of will not work
> in a multiplatform kernel.

as i have posted the sirfsoc rtciobrg, we can't read rtc and pm
controller directly since they are not in memory space and any one of
i2c/spi/usb/pci busses, and we are reading them by the following
strange APIs indirectly:
extern void sirfsoc_rtc_iobrg_besyncing(void);
extern u32 sirfsoc_rtc_iobrg_readl(u32 addr);
extern void sirfsoc_rtc_iobrg_writel(u32 val, u32 addr);
now i have placed these APIs in a head file
include/linux/rtc/sirfsoc_rtciobrg.h not in
arch/arm/mach-prima2/include/mach considering we are tending to delete
the dir.

>
> ? ? ? ?Arnd
>

-barry

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-08-11  2:25                   ` Barry Song
@ 2011-08-11  8:30                     ` Russell King - ARM Linux
  0 siblings, 0 replies; 19+ messages in thread
From: Russell King - ARM Linux @ 2011-08-11  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Aug 11, 2011 at 10:25:58AM +0800, Barry Song wrote:
> now every SoCs have different DMA APIs due to different DMA controller:

We already have a solution to this.  It's called dmaengine.  See
drivers/dma, include/linux/dmaengine.h and Documentation/dmaengine.txt
There is work going on at present to convert the OMAP and Samsung SoC
specific DMA support to dmaengine.

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-08-09 13:15                 ` Arnd Bergmann
  2011-08-11  2:25                   ` Barry Song
@ 2011-09-19  9:10                   ` Linus Walleij
  2011-09-19 15:53                     ` Arnd Bergmann
  1 sibling, 1 reply; 19+ messages in thread
From: Linus Walleij @ 2011-09-19  9:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 09 August 2011, Barry Song wrote:

> Or do we want to delete the whole arch/arm/mach-xxx/include/mach directory?
>
> If not, it is probably that SoC can still hold some chip-specific APIs
> in arch/arm/mach-xxx/include/mach/yyy.h.

I was actually proposing patches that moved GPIO headers from
<mach/foo-gpio> to <linux/gpio/foo.h> but they were NAK:ed or
frowned upon, so I guess we're keeping the <mach/*> include
union namespace for machine/SoC-specific headers.

Now we just try to make files in this namespace have unqiue
names.

Yours,
Linus Walleij

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

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
  2011-09-19  9:10                   ` Linus Walleij
@ 2011-09-19 15:53                     ` Arnd Bergmann
  0 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2011-09-19 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 19 September 2011, Linus Walleij wrote:
> On Tuesday 09 August 2011, Barry Song wrote:
> 
> > Or do we want to delete the whole arch/arm/mach-xxx/include/mach directory?
> >
> > If not, it is probably that SoC can still hold some chip-specific APIs
> > in arch/arm/mach-xxx/include/mach/yyy.h.
> 
> I was actually proposing patches that moved GPIO headers from
> <mach/foo-gpio> to <linux/gpio/foo.h> but they were NAK:ed or
> frowned upon, so I guess we're keeping the <mach/*> include
> union namespace for machine/SoC-specific headers.
> 
> Now we just try to make files in this namespace have unqiue
> names.

That doesn't really sound like a long-term solution. I think the idea
for the single-zimage work is to eventually make the mach/ headers
local to the mach-* directory so they cannot be included from any
device drivers at all.

For any constants in those headers, they should be communicated
to the drivers using the platform data or (better) device tree
information.

The platform specific APIs that you mentioned are a bigger problem,
and I think the focus for those should be on avoiding them with
proper generic infrastructure and having only selected interfaces
exported through asm/*.h or linux/*.h where that is not an option.

	Arnd

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

end of thread, other threads:[~2011-09-19 15:53 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-26  8:13 [RFC PATCH 0/2] add pinmux and gpio for CSR SiRFprimaII Barry Song
2011-07-26  8:13 ` [RFC PATCH 1/2] ARM: CSR: Add pinmux support for SiRFprimaII Barry Song
2011-07-26  8:13 ` [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller Barry Song
2011-07-26 10:09   ` Russell King - ARM Linux
2011-07-26 10:46     ` PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller) Russell King - ARM Linux
2011-07-26 18:32       ` Colin Cross
2011-07-26 18:39         ` Russell King - ARM Linux
2011-07-26 19:10           ` Nicolas Pitre
2011-07-27  2:08             ` Barry Song
2011-07-27  2:51               ` Nicolas Pitre
2011-07-29 15:58             ` Linus Walleij
2011-08-09  7:22               ` Barry Song
2011-08-09 13:15                 ` Arnd Bergmann
2011-08-11  2:25                   ` Barry Song
2011-08-11  8:30                     ` Russell King - ARM Linux
2011-09-19  9:10                   ` Linus Walleij
2011-09-19 15:53                     ` Arnd Bergmann
2011-08-08  9:09     ` [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller Barry Song
2011-08-08  9:32     ` 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.