aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-04-09 09:57:25 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-04-10 17:41:17 -0400
commit7fc7acb9a0b0ff3ffdf21818fe0735ebaf4fecb8 (patch)
treeb7dcfc4ecf9a1ef1099f0f658b381139c8689746 /drivers/gpio
parentfdc7a9f85ab4c19acfc21e4da6ff8b7000bb686c (diff)
gpio / ACPI: Handle ACPI events in accordance with the spec
Commit 0d1c28a (gpiolib-acpi: Add ACPI5 event model support to gpio.) that added support for ACPI events signalled through GPIO interrupts covered only GPIO pins whose numbers are less than or equal to 255. However, there may be GPIO pins with numbers greater than 255 and the ACPI spec (ACPI 5.0, Section 5.6.5.1) requires the _EVT method to be used for handling events corresponding to those pins. Moreover, according to the spec, _EVT is the default mechanism for handling all ACPI events signalled through GPIO interrupts, so if the _Exx/_Lxx method is not present for the given pin, _EVT should be used instead. If present, though, _Exx/_Lxx take precedence over _EVT which shouldn't be executed in that case (ACPI 5.0, Section 5.6.5.3). Modify acpi_gpiochip_request_interrupts() to follow the spec as described above and add acpi_gpiochip_free_interrupts() needed to free interrupts associated with _EVT. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpiolib-acpi.c140
1 files changed, 120 insertions, 20 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index a063eb04b6ce..89336c4f82cd 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -17,6 +17,13 @@
17#include <linux/acpi.h> 17#include <linux/acpi.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19 19
20struct acpi_gpio_evt_pin {
21 struct list_head node;
22 acpi_handle *evt_handle;
23 unsigned int pin;
24 unsigned int irq;
25};
26
20static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) 27static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
21{ 28{
22 if (!gc->dev) 29 if (!gc->dev)
@@ -54,7 +61,6 @@ int acpi_get_gpio(char *path, int pin)
54} 61}
55EXPORT_SYMBOL_GPL(acpi_get_gpio); 62EXPORT_SYMBOL_GPL(acpi_get_gpio);
56 63
57
58static irqreturn_t acpi_gpio_irq_handler(int irq, void *data) 64static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
59{ 65{
60 acpi_handle handle = data; 66 acpi_handle handle = data;
@@ -64,6 +70,27 @@ static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
64 return IRQ_HANDLED; 70 return IRQ_HANDLED;
65} 71}
66 72
73static irqreturn_t acpi_gpio_irq_handler_evt(int irq, void *data)
74{
75 struct acpi_gpio_evt_pin *evt_pin = data;
76 struct acpi_object_list args;
77 union acpi_object arg;
78
79 arg.type = ACPI_TYPE_INTEGER;
80 arg.integer.value = evt_pin->pin;
81 args.count = 1;
82 args.pointer = &arg;
83
84 acpi_evaluate_object(evt_pin->evt_handle, NULL, &args, NULL);
85
86 return IRQ_HANDLED;
87}
88
89static void acpi_gpio_evt_dh(acpi_handle handle, void *data)
90{
91 /* The address of this function is used as a key. */
92}
93
67/** 94/**
68 * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events 95 * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events
69 * @chip: gpio chip 96 * @chip: gpio chip
@@ -73,15 +100,13 @@ static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
73 * chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which 100 * chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which
74 * gpio pins have acpi event methods and assigns interrupt handlers that calls 101 * gpio pins have acpi event methods and assigns interrupt handlers that calls
75 * the acpi event methods for those pins. 102 * the acpi event methods for those pins.
76 *
77 * Interrupts are automatically freed on driver detach
78 */ 103 */
79
80void acpi_gpiochip_request_interrupts(struct gpio_chip *chip) 104void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
81{ 105{
82 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; 106 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
83 struct acpi_resource *res; 107 struct acpi_resource *res;
84 acpi_handle handle, ev_handle; 108 acpi_handle handle, evt_handle;
109 struct list_head *evt_pins = NULL;
85 acpi_status status; 110 acpi_status status;
86 unsigned int pin; 111 unsigned int pin;
87 int irq, ret; 112 int irq, ret;
@@ -98,13 +123,30 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
98 if (ACPI_FAILURE(status)) 123 if (ACPI_FAILURE(status))
99 return; 124 return;
100 125
101 /* If a gpio interrupt has an acpi event handler method, then 126 status = acpi_get_handle(handle, "_EVT", &evt_handle);
102 * set up an interrupt handler that calls the acpi event handler 127 if (ACPI_SUCCESS(status)) {
103 */ 128 evt_pins = kzalloc(sizeof(*evt_pins), GFP_KERNEL);
129 if (evt_pins) {
130 INIT_LIST_HEAD(evt_pins);
131 status = acpi_attach_data(handle, acpi_gpio_evt_dh,
132 evt_pins);
133 if (ACPI_FAILURE(status)) {
134 kfree(evt_pins);
135 evt_pins = NULL;
136 }
137 }
138 }
104 139
140 /*
141 * If a GPIO interrupt has an ACPI event handler method, or _EVT is
142 * present, set up an interrupt handler that calls the ACPI event
143 * handler.
144 */
105 for (res = buf.pointer; 145 for (res = buf.pointer;
106 res && (res->type != ACPI_RESOURCE_TYPE_END_TAG); 146 res && (res->type != ACPI_RESOURCE_TYPE_END_TAG);
107 res = ACPI_NEXT_RESOURCE(res)) { 147 res = ACPI_NEXT_RESOURCE(res)) {
148 irq_handler_t handler = NULL;
149 void *data;
108 150
109 if (res->type != ACPI_RESOURCE_TYPE_GPIO || 151 if (res->type != ACPI_RESOURCE_TYPE_GPIO ||
110 res->data.gpio.connection_type != 152 res->data.gpio.connection_type !=
@@ -115,23 +157,42 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
115 if (pin > chip->ngpio) 157 if (pin > chip->ngpio)
116 continue; 158 continue;
117 159
118 sprintf(ev_name, "_%c%02X",
119 res->data.gpio.triggering ? 'E' : 'L', pin);
120
121 status = acpi_get_handle(handle, ev_name, &ev_handle);
122 if (ACPI_FAILURE(status))
123 continue;
124
125 irq = chip->to_irq(chip, pin); 160 irq = chip->to_irq(chip, pin);
126 if (irq < 0) 161 if (irq < 0)
127 continue; 162 continue;
128 163
164 if (pin <= 255) {
165 acpi_handle ev_handle;
166
167 sprintf(ev_name, "_%c%02X",
168 res->data.gpio.triggering ? 'E' : 'L', pin);
169 status = acpi_get_handle(handle, ev_name, &ev_handle);
170 if (ACPI_SUCCESS(status)) {
171 handler = acpi_gpio_irq_handler;
172 data = ev_handle;
173 }
174 }
175 if (!handler && evt_pins) {
176 struct acpi_gpio_evt_pin *evt_pin;
177
178 evt_pin = kzalloc(sizeof(*evt_pin), GFP_KERNEL);
179 if (!evt_pin)
180 continue;
181
182 list_add_tail(&evt_pin->node, evt_pins);
183 evt_pin->evt_handle = evt_handle;
184 evt_pin->pin = pin;
185 evt_pin->irq = irq;
186 handler = acpi_gpio_irq_handler_evt;
187 data = evt_pin;
188 }
189 if (!handler)
190 continue;
191
129 /* Assume BIOS sets the triggering, so no flags */ 192 /* Assume BIOS sets the triggering, so no flags */
130 ret = devm_request_threaded_irq(chip->dev, irq, NULL, 193 ret = devm_request_threaded_irq(chip->dev, irq, NULL, handler,
131 acpi_gpio_irq_handler, 194 0, "GPIO-signaled-ACPI-event",
132 0, 195 data);
133 "GPIO-signaled-ACPI-event",
134 ev_handle);
135 if (ret) 196 if (ret)
136 dev_err(chip->dev, 197 dev_err(chip->dev,
137 "Failed to request IRQ %d ACPI event handler\n", 198 "Failed to request IRQ %d ACPI event handler\n",
@@ -139,3 +200,42 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
139 } 200 }
140} 201}
141EXPORT_SYMBOL(acpi_gpiochip_request_interrupts); 202EXPORT_SYMBOL(acpi_gpiochip_request_interrupts);
203
204
205/**
206 * acpi_gpiochip_free_interrupts() - Free GPIO _EVT ACPI event interrupts.
207 * @chip: gpio chip
208 *
209 * Free interrupts associated with the _EVT method for the given GPIO chip.
210 *
211 * The remaining ACPI event interrupts associated with the chip are freed
212 * automatically.
213 */
214void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
215{
216 acpi_handle handle;
217 acpi_status status;
218 struct list_head *evt_pins;
219 struct acpi_gpio_evt_pin *evt_pin, *ep;
220
221 if (!chip->dev || !chip->to_irq)
222 return;
223
224 handle = ACPI_HANDLE(chip->dev);
225 if (!handle)
226 return;
227
228 status = acpi_get_data(handle, acpi_gpio_evt_dh, (void **)&evt_pins);
229 if (ACPI_FAILURE(status))
230 return;
231
232 list_for_each_entry_safe_reverse(evt_pin, ep, evt_pins, node) {
233 devm_free_irq(chip->dev, evt_pin->irq, evt_pin);
234 list_del(&evt_pin->node);
235 kfree(evt_pin);
236 }
237
238 acpi_detach_data(handle, acpi_gpio_evt_dh);
239 kfree(evt_pins);
240}
241EXPORT_SYMBOL(acpi_gpiochip_free_interrupts);