Root/target/linux/cns3xxx/patches-2.6.39/104-cns3xxx_gpio.patch

1--- a/arch/arm/mach-cns3xxx/cns3420vb.c
2+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
3@@ -191,7 +191,7 @@ static struct map_desc cns3420_io_desc[]
4 
5 static void __init cns3420_map_io(void)
6 {
7- cns3xxx_map_io();
8+ cns3xxx_common_init();
9     iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc));
10 
11     cns3420_early_serial_setup();
12--- a/arch/arm/mach-cns3xxx/core.c
13+++ b/arch/arm/mach-cns3xxx/core.c
14@@ -18,6 +18,7 @@
15 #include <asm/hardware/cache-l2x0.h>
16 #include <asm/hardware/gic.h>
17 #include <asm/smp_twd.h>
18+#include <asm/gpio.h>
19 #include <mach/cns3xxx.h>
20 #include "core.h"
21 
22@@ -80,7 +81,89 @@ static struct map_desc cns3xxx_io_desc[]
23     },
24 };
25 
26-void __init cns3xxx_map_io(void)
27+int gpio_to_irq(int gpio)
28+{
29+ if (gpio > 63)
30+ return -EINVAL;
31+
32+ if (gpio < 32)
33+ return IRQ_CNS3XXX_GPIOA;
34+ else
35+ return IRQ_CNS3XXX_GPIOB;
36+}
37+EXPORT_SYMBOL(gpio_to_irq);
38+
39+int irq2gpio(int irq)
40+{
41+ if (irq == IRQ_CNS3XXX_GPIOA)
42+ return 0;
43+ else if (irq == IRQ_CNS3XXX_GPIOB)
44+ return 32;
45+ else
46+ return -EINVAL;
47+}
48+EXPORT_SYMBOL(irq2gpio);
49+
50+static inline void gpio_line_config(u8 line, u32 direction)
51+{
52+ u32 reg;
53+ if (direction) {
54+ if (line < 32) {
55+ reg = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_DIR);
56+ reg |= (1 << line);
57+ __raw_writel(reg, CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_DIR);
58+ } else {
59+ reg = __raw_readl(CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_DIR);
60+ reg |= (1 << (line - 32));
61+ __raw_writel(reg, CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_DIR);
62+ }
63+ } else {
64+ if (line < 32) {
65+ reg = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_DIR);
66+ reg &= ~(1 << line);
67+ __raw_writel(reg, CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_DIR);
68+ } else {
69+ reg = __raw_readl(CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_DIR);
70+ reg &= ~(1 << (line - 32));
71+ __raw_writel(reg, CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_DIR);
72+ }
73+ }
74+}
75+
76+static int cns3xxx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
77+{
78+ gpio_line_config(gpio, CNS3XXX_GPIO_IN);
79+ return 0;
80+}
81+
82+static int cns3xxx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
83+{
84+ gpio_line_set(gpio, level);
85+ gpio_line_config(gpio, CNS3XXX_GPIO_OUT);
86+ return 0;
87+}
88+
89+static int cns3xxx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
90+{
91+ return gpio_get_value(gpio);
92+}
93+
94+static void cns3xxx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
95+{
96+ gpio_set_value(gpio, value);
97+}
98+
99+static struct gpio_chip cns3xxx_gpio_chip = {
100+ .label = "CNS3XXX_GPIO_CHIP",
101+ .direction_input = cns3xxx_gpio_direction_input,
102+ .direction_output = cns3xxx_gpio_direction_output,
103+ .get = cns3xxx_gpio_get_value,
104+ .set = cns3xxx_gpio_set_value,
105+ .base = 0,
106+ .ngpio = 64,
107+};
108+
109+void __init cns3xxx_common_init(void)
110 {
111     iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
112 #ifdef CONFIG_CACHE_L2X0
113@@ -95,6 +178,7 @@ void __init cns3xxx_map_io(void)
114 #ifdef CONFIG_LOCAL_TIMERS
115     twd_base = (void __iomem *) CNS3XXX_TC11MP_TWD_BASE_VIRT;
116 #endif
117+ gpiochip_add(&cns3xxx_gpio_chip);
118 }
119 
120 /* used by entry-macro.S */
121--- a/arch/arm/mach-cns3xxx/core.h
122+++ b/arch/arm/mach-cns3xxx/core.h
123@@ -13,7 +13,7 @@
124 
125 extern struct sys_timer cns3xxx_timer;
126 
127-void __init cns3xxx_map_io(void);
128+void __init cns3xxx_common_init(void);
129 void __init cns3xxx_init_irq(void);
130 void cns3xxx_power_off(void);
131 
132--- a/arch/arm/mach-cns3xxx/laguna.c
133+++ b/arch/arm/mach-cns3xxx/laguna.c
134@@ -520,7 +520,7 @@ static struct map_desc laguna_io_desc[]
135 
136 static void __init laguna_map_io(void)
137 {
138- cns3xxx_map_io();
139+ cns3xxx_common_init();
140     iotable_init(laguna_io_desc, ARRAY_SIZE(laguna_io_desc));
141 
142     laguna_early_serial_setup();
143

Archive Download this file



interactive