blob: fb9d52a57d78286d3bc74263db11720583b9100c [file] [log] [blame]
Dmitry Baryshkov45528e32008-04-10 13:31:47 +01001/*
2 * linux/arch/arm/mach-sa1100/gpio.c
3 *
4 * Generic SA-1100 GPIO handling
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
Russell King2f8163b2011-07-26 10:53:52 +010010#include <linux/gpio.h>
Dmitry Baryshkov45528e32008-04-10 13:31:47 +010011#include <linux/init.h>
12#include <linux/module.h>
Linus Walleij40ca0612013-09-25 13:33:55 +010013#include <linux/io.h>
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +010014#include <linux/syscore_ops.h>
Russell King9dd48192016-08-31 08:49:44 +010015#include <soc/sa1100/pwer.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010016#include <mach/hardware.h>
Rob Herringf314f332012-02-24 00:06:51 +010017#include <mach/irqs.h>
Dmitry Baryshkov45528e32008-04-10 13:31:47 +010018
19static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
20{
Linus Walleij6a681b62015-12-21 11:36:28 +010021 return !!(GPLR & GPIO_GPIO(offset));
Dmitry Baryshkov45528e32008-04-10 13:31:47 +010022}
23
24static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
25{
26 if (value)
27 GPSR = GPIO_GPIO(offset);
28 else
29 GPCR = GPIO_GPIO(offset);
30}
31
32static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset)
33{
34 unsigned long flags;
35
36 local_irq_save(flags);
37 GPDR &= ~GPIO_GPIO(offset);
38 local_irq_restore(flags);
39 return 0;
40}
41
42static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int value)
43{
44 unsigned long flags;
45
46 local_irq_save(flags);
47 sa1100_gpio_set(chip, offset, value);
48 GPDR |= GPIO_GPIO(offset);
49 local_irq_restore(flags);
50 return 0;
51}
52
Russell Kingf408c982011-12-18 18:24:57 +000053static int sa1100_to_irq(struct gpio_chip *chip, unsigned offset)
54{
Dmitry Eremin-Solenikov83508092015-01-15 02:29:16 +010055 return IRQ_GPIO0 + offset;
Russell Kingf408c982011-12-18 18:24:57 +000056}
57
Dmitry Baryshkov45528e32008-04-10 13:31:47 +010058static struct gpio_chip sa1100_gpio_chip = {
59 .label = "gpio",
60 .direction_input = sa1100_direction_input,
61 .direction_output = sa1100_direction_output,
62 .set = sa1100_gpio_set,
63 .get = sa1100_gpio_get,
Russell Kingf408c982011-12-18 18:24:57 +000064 .to_irq = sa1100_to_irq,
Dmitry Baryshkov45528e32008-04-10 13:31:47 +010065 .base = 0,
66 .ngpio = GPIO_MAX + 1,
67};
68
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +010069/*
70 * SA1100 GPIO edge detection for IRQs:
71 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
72 * Use this instead of directly setting GRER/GFER.
73 */
74static int GPIO_IRQ_rising_edge;
75static int GPIO_IRQ_falling_edge;
76static int GPIO_IRQ_mask;
Russell King9dd48192016-08-31 08:49:44 +010077static int GPIO_IRQ_wake;
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +010078
79static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
80{
81 unsigned int mask;
82
83 mask = BIT(d->hwirq);
84
85 if (type == IRQ_TYPE_PROBE) {
86 if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
87 return 0;
88 type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
89 }
90
91 if (type & IRQ_TYPE_EDGE_RISING)
92 GPIO_IRQ_rising_edge |= mask;
93 else
94 GPIO_IRQ_rising_edge &= ~mask;
95 if (type & IRQ_TYPE_EDGE_FALLING)
96 GPIO_IRQ_falling_edge |= mask;
97 else
98 GPIO_IRQ_falling_edge &= ~mask;
99
100 GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
101 GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
102
103 return 0;
104}
105
106/*
107 * GPIO IRQs must be acknowledged.
108 */
109static void sa1100_gpio_ack(struct irq_data *d)
110{
111 GEDR = BIT(d->hwirq);
112}
113
114static void sa1100_gpio_mask(struct irq_data *d)
115{
116 unsigned int mask = BIT(d->hwirq);
117
118 GPIO_IRQ_mask &= ~mask;
119
120 GRER &= ~mask;
121 GFER &= ~mask;
122}
123
124static void sa1100_gpio_unmask(struct irq_data *d)
125{
126 unsigned int mask = BIT(d->hwirq);
127
128 GPIO_IRQ_mask |= mask;
129
130 GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
131 GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
132}
133
134static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
135{
Russell King9dd48192016-08-31 08:49:44 +0100136 int ret = sa11x0_gpio_set_wake(d->hwirq, on);
137 if (!ret) {
138 if (on)
139 GPIO_IRQ_wake |= BIT(d->hwirq);
140 else
141 GPIO_IRQ_wake &= ~BIT(d->hwirq);
142 }
143 return ret;
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +0100144}
145
146/*
147 * This is for GPIO IRQs
148 */
149static struct irq_chip sa1100_gpio_irq_chip = {
150 .name = "GPIO",
151 .irq_ack = sa1100_gpio_ack,
152 .irq_mask = sa1100_gpio_mask,
153 .irq_unmask = sa1100_gpio_unmask,
154 .irq_set_type = sa1100_gpio_type,
155 .irq_set_wake = sa1100_gpio_wake,
156};
157
158static int sa1100_gpio_irqdomain_map(struct irq_domain *d,
159 unsigned int irq, irq_hw_number_t hwirq)
160{
161 irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip,
162 handle_edge_irq);
Russell King56beac92016-08-29 11:24:10 +0100163 irq_set_probe(irq);
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +0100164
165 return 0;
166}
167
Krzysztof Kozlowski0b354dc2015-04-27 21:54:07 +0900168static const struct irq_domain_ops sa1100_gpio_irqdomain_ops = {
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +0100169 .map = sa1100_gpio_irqdomain_map,
170 .xlate = irq_domain_xlate_onetwocell,
171};
172
173static struct irq_domain *sa1100_gpio_irqdomain;
174
175/*
176 * IRQ 0-11 (GPIO) handler. We enter here with the
177 * irq_controller_lock held, and IRQs disabled. Decode the IRQ
178 * and call the handler.
179 */
Thomas Gleixnerbd0b9ac2015-09-14 10:42:37 +0200180static void sa1100_gpio_handler(struct irq_desc *desc)
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +0100181{
Thomas Gleixner2951a792015-07-13 00:11:27 +0200182 unsigned int irq, mask;
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +0100183
184 mask = GEDR;
185 do {
186 /*
187 * clear down all currently active IRQ sources.
188 * We will be processing them all.
189 */
190 GEDR = mask;
191
192 irq = IRQ_GPIO0;
193 do {
194 if (mask & 1)
195 generic_handle_irq(irq);
196 mask >>= 1;
197 irq++;
198 } while (mask);
199
200 mask = GEDR;
201 } while (mask);
202}
203
204static int sa1100_gpio_suspend(void)
205{
206 /*
207 * Set the appropriate edges for wakeup.
208 */
Russell King9dd48192016-08-31 08:49:44 +0100209 GRER = GPIO_IRQ_wake & GPIO_IRQ_rising_edge;
210 GFER = GPIO_IRQ_wake & GPIO_IRQ_falling_edge;
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +0100211
212 /*
213 * Clear any pending GPIO interrupts.
214 */
215 GEDR = GEDR;
216
217 return 0;
218}
219
220static void sa1100_gpio_resume(void)
221{
222 GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
223 GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
224}
225
226static struct syscore_ops sa1100_gpio_syscore_ops = {
227 .suspend = sa1100_gpio_suspend,
228 .resume = sa1100_gpio_resume,
229};
230
231static int __init sa1100_gpio_init_devicefs(void)
232{
233 register_syscore_ops(&sa1100_gpio_syscore_ops);
234 return 0;
235}
236
237device_initcall(sa1100_gpio_init_devicefs);
238
Dmitry Baryshkov45528e32008-04-10 13:31:47 +0100239void __init sa1100_init_gpio(void)
240{
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +0100241 /* clear all GPIO edge detects */
242 GFER = 0;
243 GRER = 0;
244 GEDR = -1;
245
Linus Walleij4eab22e2015-12-08 10:41:44 +0100246 gpiochip_add_data(&sa1100_gpio_chip, NULL);
Dmitry Eremin-Solenikova0ea298d32015-01-15 02:32:26 +0100247
248 sa1100_gpio_irqdomain = irq_domain_add_simple(NULL,
249 28, IRQ_GPIO0,
250 &sa1100_gpio_irqdomain_ops, NULL);
251
252 /*
253 * Install handlers for GPIO 0-10 edge detect interrupts
254 */
255 irq_set_chained_handler(IRQ_GPIO0_SC, sa1100_gpio_handler);
256 irq_set_chained_handler(IRQ_GPIO1_SC, sa1100_gpio_handler);
257 irq_set_chained_handler(IRQ_GPIO2_SC, sa1100_gpio_handler);
258 irq_set_chained_handler(IRQ_GPIO3_SC, sa1100_gpio_handler);
259 irq_set_chained_handler(IRQ_GPIO4_SC, sa1100_gpio_handler);
260 irq_set_chained_handler(IRQ_GPIO5_SC, sa1100_gpio_handler);
261 irq_set_chained_handler(IRQ_GPIO6_SC, sa1100_gpio_handler);
262 irq_set_chained_handler(IRQ_GPIO7_SC, sa1100_gpio_handler);
263 irq_set_chained_handler(IRQ_GPIO8_SC, sa1100_gpio_handler);
264 irq_set_chained_handler(IRQ_GPIO9_SC, sa1100_gpio_handler);
265 irq_set_chained_handler(IRQ_GPIO10_SC, sa1100_gpio_handler);
266 /*
267 * Install handler for GPIO 11-27 edge detect interrupts
268 */
269 irq_set_chained_handler(IRQ_GPIO11_27, sa1100_gpio_handler);
270
Dmitry Baryshkov45528e32008-04-10 13:31:47 +0100271}