aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/mpc8xxx_gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/mpc8xxx_gpio.c')
-rw-r--r--arch/powerpc/sysdev/mpc8xxx_gpio.c122
1 files changed, 91 insertions, 31 deletions
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
index 2b69084d0f0c..fb4963abdf55 100644
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * GPIOs on MPC8349/8572/8610 and compatible 2 * GPIOs on MPC512x/8349/8572/8610 and compatible
3 * 3 *
4 * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk> 4 * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
5 * 5 *
@@ -26,6 +26,7 @@
26#define GPIO_IER 0x0c 26#define GPIO_IER 0x0c
27#define GPIO_IMR 0x10 27#define GPIO_IMR 0x10
28#define GPIO_ICR 0x14 28#define GPIO_ICR 0x14
29#define GPIO_ICR2 0x18
29 30
30struct mpc8xxx_gpio_chip { 31struct mpc8xxx_gpio_chip {
31 struct of_mm_gpio_chip mm_gc; 32 struct of_mm_gpio_chip mm_gc;
@@ -37,6 +38,7 @@ struct mpc8xxx_gpio_chip {
37 */ 38 */
38 u32 data; 39 u32 data;
39 struct irq_host *irq; 40 struct irq_host *irq;
41 void *of_dev_id_data;
40}; 42};
41 43
42static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) 44static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
@@ -143,7 +145,7 @@ static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
143 145
144static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) 146static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
145{ 147{
146 struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_desc_data(desc); 148 struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
147 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; 149 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
148 unsigned int mask; 150 unsigned int mask;
149 151
@@ -153,43 +155,43 @@ static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
153 32 - ffs(mask))); 155 32 - ffs(mask)));
154} 156}
155 157
156static void mpc8xxx_irq_unmask(unsigned int virq) 158static void mpc8xxx_irq_unmask(struct irq_data *d)
157{ 159{
158 struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); 160 struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
159 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; 161 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
160 unsigned long flags; 162 unsigned long flags;
161 163
162 spin_lock_irqsave(&mpc8xxx_gc->lock, flags); 164 spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
163 165
164 setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq))); 166 setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
165 167
166 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 168 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
167} 169}
168 170
169static void mpc8xxx_irq_mask(unsigned int virq) 171static void mpc8xxx_irq_mask(struct irq_data *d)
170{ 172{
171 struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); 173 struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
172 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; 174 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
173 unsigned long flags; 175 unsigned long flags;
174 176
175 spin_lock_irqsave(&mpc8xxx_gc->lock, flags); 177 spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
176 178
177 clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq))); 179 clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
178 180
179 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 181 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
180} 182}
181 183
182static void mpc8xxx_irq_ack(unsigned int virq) 184static void mpc8xxx_irq_ack(struct irq_data *d)
183{ 185{
184 struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); 186 struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
185 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; 187 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
186 188
187 out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(virq))); 189 out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
188} 190}
189 191
190static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type) 192static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
191{ 193{
192 struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); 194 struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
193 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; 195 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
194 unsigned long flags; 196 unsigned long flags;
195 197
@@ -197,14 +199,59 @@ static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
197 case IRQ_TYPE_EDGE_FALLING: 199 case IRQ_TYPE_EDGE_FALLING:
198 spin_lock_irqsave(&mpc8xxx_gc->lock, flags); 200 spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
199 setbits32(mm->regs + GPIO_ICR, 201 setbits32(mm->regs + GPIO_ICR,
200 mpc8xxx_gpio2mask(virq_to_hw(virq))); 202 mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
201 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 203 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
202 break; 204 break;
203 205
204 case IRQ_TYPE_EDGE_BOTH: 206 case IRQ_TYPE_EDGE_BOTH:
205 spin_lock_irqsave(&mpc8xxx_gc->lock, flags); 207 spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
206 clrbits32(mm->regs + GPIO_ICR, 208 clrbits32(mm->regs + GPIO_ICR,
207 mpc8xxx_gpio2mask(virq_to_hw(virq))); 209 mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
210 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
211 break;
212
213 default:
214 return -EINVAL;
215 }
216
217 return 0;
218}
219
220static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
221{
222 struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
223 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
224 unsigned long gpio = irqd_to_hwirq(d);
225 void __iomem *reg;
226 unsigned int shift;
227 unsigned long flags;
228
229 if (gpio < 16) {
230 reg = mm->regs + GPIO_ICR;
231 shift = (15 - gpio) * 2;
232 } else {
233 reg = mm->regs + GPIO_ICR2;
234 shift = (15 - (gpio % 16)) * 2;
235 }
236
237 switch (flow_type) {
238 case IRQ_TYPE_EDGE_FALLING:
239 case IRQ_TYPE_LEVEL_LOW:
240 spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
241 clrsetbits_be32(reg, 3 << shift, 2 << shift);
242 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
243 break;
244
245 case IRQ_TYPE_EDGE_RISING:
246 case IRQ_TYPE_LEVEL_HIGH:
247 spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
248 clrsetbits_be32(reg, 3 << shift, 1 << shift);
249 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
250 break;
251
252 case IRQ_TYPE_EDGE_BOTH:
253 spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
254 clrbits32(reg, 3 << shift);
208 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 255 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
209 break; 256 break;
210 257
@@ -217,18 +264,23 @@ static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
217 264
218static struct irq_chip mpc8xxx_irq_chip = { 265static struct irq_chip mpc8xxx_irq_chip = {
219 .name = "mpc8xxx-gpio", 266 .name = "mpc8xxx-gpio",
220 .unmask = mpc8xxx_irq_unmask, 267 .irq_unmask = mpc8xxx_irq_unmask,
221 .mask = mpc8xxx_irq_mask, 268 .irq_mask = mpc8xxx_irq_mask,
222 .ack = mpc8xxx_irq_ack, 269 .irq_ack = mpc8xxx_irq_ack,
223 .set_type = mpc8xxx_irq_set_type, 270 .irq_set_type = mpc8xxx_irq_set_type,
224}; 271};
225 272
226static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, 273static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
227 irq_hw_number_t hw) 274 irq_hw_number_t hw)
228{ 275{
229 set_irq_chip_data(virq, h->host_data); 276 struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
230 set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); 277
231 set_irq_type(virq, IRQ_TYPE_NONE); 278 if (mpc8xxx_gc->of_dev_id_data)
279 mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
280
281 irq_set_chip_data(virq, h->host_data);
282 irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
283 irq_set_irq_type(virq, IRQ_TYPE_NONE);
232 284
233 return 0; 285 return 0;
234} 286}
@@ -253,11 +305,21 @@ static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
253 .xlate = mpc8xxx_gpio_irq_xlate, 305 .xlate = mpc8xxx_gpio_irq_xlate,
254}; 306};
255 307
308static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
309 { .compatible = "fsl,mpc8349-gpio", },
310 { .compatible = "fsl,mpc8572-gpio", },
311 { .compatible = "fsl,mpc8610-gpio", },
312 { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
313 { .compatible = "fsl,qoriq-gpio", },
314 {}
315};
316
256static void __init mpc8xxx_add_controller(struct device_node *np) 317static void __init mpc8xxx_add_controller(struct device_node *np)
257{ 318{
258 struct mpc8xxx_gpio_chip *mpc8xxx_gc; 319 struct mpc8xxx_gpio_chip *mpc8xxx_gc;
259 struct of_mm_gpio_chip *mm_gc; 320 struct of_mm_gpio_chip *mm_gc;
260 struct gpio_chip *gc; 321 struct gpio_chip *gc;
322 const struct of_device_id *id;
261 unsigned hwirq; 323 unsigned hwirq;
262 int ret; 324 int ret;
263 325
@@ -297,14 +359,18 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
297 if (!mpc8xxx_gc->irq) 359 if (!mpc8xxx_gc->irq)
298 goto skip_irq; 360 goto skip_irq;
299 361
362 id = of_match_node(mpc8xxx_gpio_ids, np);
363 if (id)
364 mpc8xxx_gc->of_dev_id_data = id->data;
365
300 mpc8xxx_gc->irq->host_data = mpc8xxx_gc; 366 mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
301 367
302 /* ack and mask all irqs */ 368 /* ack and mask all irqs */
303 out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); 369 out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
304 out_be32(mm_gc->regs + GPIO_IMR, 0); 370 out_be32(mm_gc->regs + GPIO_IMR, 0);
305 371
306 set_irq_data(hwirq, mpc8xxx_gc); 372 irq_set_handler_data(hwirq, mpc8xxx_gc);
307 set_irq_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); 373 irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
308 374
309skip_irq: 375skip_irq:
310 return; 376 return;
@@ -321,13 +387,7 @@ static int __init mpc8xxx_add_gpiochips(void)
321{ 387{
322 struct device_node *np; 388 struct device_node *np;
323 389
324 for_each_compatible_node(np, NULL, "fsl,mpc8349-gpio") 390 for_each_matching_node(np, mpc8xxx_gpio_ids)
325 mpc8xxx_add_controller(np);
326
327 for_each_compatible_node(np, NULL, "fsl,mpc8572-gpio")
328 mpc8xxx_add_controller(np);
329
330 for_each_compatible_node(np, NULL, "fsl,mpc8610-gpio")
331 mpc8xxx_add_controller(np); 391 mpc8xxx_add_controller(np);
332 392
333 return 0; 393 return 0;