[lantiq] update 3.2 patches
[openwrt.git] / target / linux / lantiq / patches-3.2 / 0055-MIPS-lantiq-make-GPIO3-work-on-AR9.patch
1 From bc45b5c61ffb156eb01515bf56efc5ae8d2bc3b2 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Sat, 13 Aug 2011 13:59:50 +0200
4 Subject: [PATCH 55/73] MIPS: lantiq: make GPIO3 work on AR9
5
6 There are 3 16bit and 1 8bit gpio ports on AR9. The gpio driver needs a hack
7 at 2 places to make the different register layout of the GPIO3 work properly
8 with the driver. Before only GPIO0-2 were supported. As the GPIO number scheme
9 clashes with the new size, we also move the other gpio chips to new offsets.
10
11 Signed-off-by: John Crispin <blogic@openwrt.org>
12 Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
13 ---
14  .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |    2 +
15  arch/mips/lantiq/xway/devices.c                    |    3 +
16  arch/mips/lantiq/xway/gpio.c                       |   84 ++++++++++++++++----
17  arch/mips/lantiq/xway/gpio_ebu.c                   |    3 +-
18  arch/mips/lantiq/xway/gpio_stp.c                   |    3 +-
19  5 files changed, 75 insertions(+), 20 deletions(-)
20
21 diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
22 index d1b8cc8..bfdeb16 100644
23 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
24 +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
25 @@ -126,7 +126,9 @@
26  #define LTQ_GPIO0_BASE_ADDR    0x1E100B10
27  #define LTQ_GPIO1_BASE_ADDR    0x1E100B40
28  #define LTQ_GPIO2_BASE_ADDR    0x1E100B70
29 +#define LTQ_GPIO3_BASE_ADDR    0x1E100BA0
30  #define LTQ_GPIO_SIZE          0x30
31 +#define LTQ_GPIO3_SIZE         0x10
32  
33  /* SSC */
34  #define LTQ_SSC_BASE_ADDR      0x1e100800
35 diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
36 index 5efa4f3..e6d45bc 100644
37 --- a/arch/mips/lantiq/xway/devices.c
38 +++ b/arch/mips/lantiq/xway/devices.c
39 @@ -34,6 +34,7 @@ static struct resource ltq_gpio_resource[] = {
40         MEM_RES("gpio0", LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE),
41         MEM_RES("gpio1", LTQ_GPIO1_BASE_ADDR, LTQ_GPIO_SIZE),
42         MEM_RES("gpio2", LTQ_GPIO2_BASE_ADDR, LTQ_GPIO_SIZE),
43 +       MEM_RES("gpio3", LTQ_GPIO3_BASE_ADDR, LTQ_GPIO3_SIZE),
44  };
45  
46  void __init ltq_register_gpio(void)
47 @@ -47,6 +48,8 @@ void __init ltq_register_gpio(void)
48         if (ltq_is_ar9() || ltq_is_vr9()) {
49                 platform_device_register_simple("ltq_gpio", 2,
50                         &ltq_gpio_resource[2], 1);
51 +               platform_device_register_simple("ltq_gpio", 3,
52 +                       &ltq_gpio_resource[3], 1);
53         }
54  }
55  
56 diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
57 index 54ec6c9..375329b 100644
58 --- a/arch/mips/lantiq/xway/gpio.c
59 +++ b/arch/mips/lantiq/xway/gpio.c
60 @@ -23,9 +23,17 @@
61  #define LTQ_GPIO_OD            0x14
62  #define LTQ_GPIO_PUDSEL                0x1C
63  #define LTQ_GPIO_PUDEN         0x20
64 +#define LTQ_GPIO3_OD           0x24
65 +#define LTQ_GPIO3_ALTSEL1      0x24
66 +#define LTQ_GPIO3_PUDSEL       0x28
67 +#define LTQ_GPIO3_PUDEN                0x2C
68  
69 +/* PORT3 only has 8 pins and its register layout
70 +   is slightly different */
71  #define PINS_PER_PORT          16
72 -#define MAX_PORTS              3
73 +#define PINS_PORT3             8
74 +#define MAX_PORTS              4
75 +#define MAX_PIN                        56
76  
77  #define ltq_gpio_getbit(m, r, p)       (!!(ltq_r32(m + r) & (1 << p)))
78  #define ltq_gpio_setbit(m, r, p)       ltq_w32_mask(0, (1 << p), m + r)
79 @@ -55,7 +63,7 @@ int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
80  {
81         int id = 0;
82  
83 -       if (pin >= (MAX_PORTS * PINS_PER_PORT))
84 +       if (pin >= MAX_PIN)
85                 return -EINVAL;
86         if (devm_gpio_request(dev, pin, name)) {
87                 pr_err("failed to setup lantiq gpio: %s\n", name);
88 @@ -75,12 +83,21 @@ int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
89         else
90                 ltq_gpio_clearbit(ltq_gpio_port[id].membase,
91                         LTQ_GPIO_ALTSEL0, pin);
92 -       if (mux & 0x1)
93 -               ltq_gpio_setbit(ltq_gpio_port[id].membase,
94 -                       LTQ_GPIO_ALTSEL1, pin);
95 -       else
96 -               ltq_gpio_clearbit(ltq_gpio_port[id].membase,
97 -                       LTQ_GPIO_ALTSEL1, pin);
98 +       if (id == 3) {
99 +               if (mux & 0x1)
100 +                       ltq_gpio_setbit(ltq_gpio_port[1].membase,
101 +                               LTQ_GPIO3_ALTSEL1, pin);
102 +               else
103 +                       ltq_gpio_clearbit(ltq_gpio_port[1].membase,
104 +                               LTQ_GPIO3_ALTSEL1, pin);
105 +       } else {
106 +               if (mux & 0x1)
107 +                       ltq_gpio_setbit(ltq_gpio_port[id].membase,
108 +                               LTQ_GPIO_ALTSEL1, pin);
109 +               else
110 +                       ltq_gpio_clearbit(ltq_gpio_port[id].membase,
111 +                               LTQ_GPIO_ALTSEL1, pin);
112 +       }
113         return 0;
114  }
115  EXPORT_SYMBOL(ltq_gpio_request);
116 @@ -106,10 +123,19 @@ static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
117  {
118         struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
119  
120 -       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
121 +       if (chip->ngpio == PINS_PORT3) {
122 +               ltq_gpio_clearbit(ltq_gpio_port[0].membase,
123 +                               LTQ_GPIO3_OD, offset);
124 +               ltq_gpio_setbit(ltq_gpio_port[0].membase,
125 +                               LTQ_GPIO3_PUDSEL, offset);
126 +               ltq_gpio_setbit(ltq_gpio_port[0].membase,
127 +                               LTQ_GPIO3_PUDEN, offset);
128 +       } else {
129 +               ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
130 +               ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
131 +               ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
132 +       }
133         ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
134 -       ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
135 -       ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
136  
137         return 0;
138  }
139 @@ -119,10 +145,19 @@ static int ltq_gpio_direction_output(struct gpio_chip *chip,
140  {
141         struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
142  
143 -       ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
144 +       if (chip->ngpio == PINS_PORT3) {
145 +               ltq_gpio_setbit(ltq_gpio_port[0].membase,
146 +                               LTQ_GPIO3_OD, offset);
147 +               ltq_gpio_clearbit(ltq_gpio_port[0].membase,
148 +                               LTQ_GPIO3_PUDSEL, offset);
149 +               ltq_gpio_clearbit(ltq_gpio_port[0].membase,
150 +                               LTQ_GPIO3_PUDEN, offset);
151 +       } else {
152 +               ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
153 +               ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
154 +               ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
155 +       }
156         ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
157 -       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
158 -       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
159         ltq_gpio_set(chip, offset, value);
160  
161         return 0;
162 @@ -133,7 +168,11 @@ static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
163         struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
164  
165         ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
166 -       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
167 +       if (chip->ngpio == PINS_PORT3)
168 +               ltq_gpio_clearbit(ltq_gpio_port[1].membase,
169 +                               LTQ_GPIO3_ALTSEL1, offset);
170 +       else
171 +               ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
172         return 0;
173  }
174  
175 @@ -146,6 +185,16 @@ static int ltq_gpio_probe(struct platform_device *pdev)
176                         pdev->id);
177                 return -EINVAL;
178         }
179 +
180 +       /* dirty hack - The registers of port3 are not mapped linearly.
181 +          Port 3 may only load if Port 1/2 are mapped */
182 +       if ((pdev->id == 3) && (!ltq_gpio_port[1].membase
183 +                                       || !ltq_gpio_port[2].membase)) {
184 +               dev_err(&pdev->dev,
185 +                       "ports 1/2 need to be loaded before port 3 works\n");
186 +               return -ENOMEM;
187 +       }
188 +
189         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
190         if (!res) {
191                 dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
192 @@ -175,7 +224,10 @@ static int ltq_gpio_probe(struct platform_device *pdev)
193         ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
194         ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
195         ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
196 -       ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
197 +       if (pdev->id == 3)
198 +               ltq_gpio_port[pdev->id].chip.ngpio = PINS_PORT3;
199 +       else
200 +               ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
201         platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
202         return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
203  }
204 diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c
205 index b91c7f1..bc5696b 100644
206 --- a/arch/mips/lantiq/xway/gpio_ebu.c
207 +++ b/arch/mips/lantiq/xway/gpio_ebu.c
208 @@ -61,9 +61,8 @@ static struct gpio_chip ltq_ebu_chip = {
209         .label = "ltq_ebu",
210         .direction_output = ltq_ebu_direction_output,
211         .set = ltq_ebu_set,
212 -       .base = 72,
213 +       .base = 100,
214         .ngpio = 16,
215 -       .can_sleep = 1,
216         .owner = THIS_MODULE,
217  };
218  
219 diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c
220 index da91c5e..9610c10 100644
221 --- a/arch/mips/lantiq/xway/gpio_stp.c
222 +++ b/arch/mips/lantiq/xway/gpio_stp.c
223 @@ -74,9 +74,8 @@ static struct gpio_chip ltq_stp_chip = {
224         .label = "ltq_stp",
225         .direction_output = ltq_stp_direction_output,
226         .set = ltq_stp_set,
227 -       .base = 48,
228 +       .base = 200,
229         .ngpio = 24,
230 -       .can_sleep = 1,
231         .owner = THIS_MODULE,
232  };
233  
234 -- 
235 1.7.9.1
236