aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib-acpi.c
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2014-03-10 08:54:51 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-03-13 10:14:16 -0400
commitaa92b6f689acf159120ce0753f36100c3b190b4d (patch)
treec6cc39b0910489fb023d9bfeef6fa42d0d63faa5 /drivers/gpio/gpiolib-acpi.c
parent77c2d7929d7d7f0e391b17f85d2d954912ed0590 (diff)
gpio / ACPI: Allocate ACPI specific data directly in acpi_gpiochip_add()
We are going to add more ACPI specific data to accompany GPIO chip so instead of allocating it per each use-case we allocate it once when acpi_gpiochip_add() is called and release it when acpi_gpiochip_remove() is called. Doing this allows us to add more ACPI specific data by merely adding new fields to struct acpi_gpio_chip. In addition we embed evt_pins member directly to the structure instead of having it as a pointer. This simplifies the code a bit since we don't need to check against NULL. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib-acpi.c')
-rw-r--r--drivers/gpio/gpiolib-acpi.c106
1 files changed, 64 insertions, 42 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index b7db098ba060..5c0cf1d76c8b 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -26,6 +26,11 @@ struct acpi_gpio_evt_pin {
26 unsigned int irq; 26 unsigned int irq;
27}; 27};
28 28
29struct acpi_gpio_chip {
30 struct gpio_chip *chip;
31 struct list_head evt_pins;
32};
33
29static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) 34static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
30{ 35{
31 if (!gc->dev) 36 if (!gc->dev)
@@ -81,14 +86,14 @@ static irqreturn_t acpi_gpio_irq_handler_evt(int irq, void *data)
81 return IRQ_HANDLED; 86 return IRQ_HANDLED;
82} 87}
83 88
84static void acpi_gpio_evt_dh(acpi_handle handle, void *data) 89static void acpi_gpio_chip_dh(acpi_handle handle, void *data)
85{ 90{
86 /* The address of this function is used as a key. */ 91 /* The address of this function is used as a key. */
87} 92}
88 93
89/** 94/**
90 * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events 95 * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events
91 * @chip: gpio chip 96 * @acpi_gpio: ACPI GPIO chip
92 * 97 *
93 * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are 98 * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are
94 * handled by ACPI event methods which need to be called from the GPIO 99 * handled by ACPI event methods which need to be called from the GPIO
@@ -96,12 +101,12 @@ static void acpi_gpio_evt_dh(acpi_handle handle, void *data)
96 * 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
97 * the acpi event methods for those pins. 102 * the acpi event methods for those pins.
98 */ 103 */
99static void acpi_gpiochip_request_interrupts(struct gpio_chip *chip) 104static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
100{ 105{
101 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; 106 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
107 struct gpio_chip *chip = acpi_gpio->chip;
102 struct acpi_resource *res; 108 struct acpi_resource *res;
103 acpi_handle handle, evt_handle; 109 acpi_handle handle, evt_handle;
104 struct list_head *evt_pins = NULL;
105 acpi_status status; 110 acpi_status status;
106 unsigned int pin; 111 unsigned int pin;
107 int irq, ret; 112 int irq, ret;
@@ -114,23 +119,7 @@ static void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
114 if (!handle) 119 if (!handle)
115 return; 120 return;
116 121
117 status = acpi_get_event_resources(handle, &buf); 122 INIT_LIST_HEAD(&acpi_gpio->evt_pins);
118 if (ACPI_FAILURE(status))
119 return;
120
121 status = acpi_get_handle(handle, "_EVT", &evt_handle);
122 if (ACPI_SUCCESS(status)) {
123 evt_pins = kzalloc(sizeof(*evt_pins), GFP_KERNEL);
124 if (evt_pins) {
125 INIT_LIST_HEAD(evt_pins);
126 status = acpi_attach_data(handle, acpi_gpio_evt_dh,
127 evt_pins);
128 if (ACPI_FAILURE(status)) {
129 kfree(evt_pins);
130 evt_pins = NULL;
131 }
132 }
133 }
134 123
135 /* 124 /*
136 * If a GPIO interrupt has an ACPI event handler method, or _EVT is 125 * If a GPIO interrupt has an ACPI event handler method, or _EVT is
@@ -167,14 +156,18 @@ static void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
167 data = ev_handle; 156 data = ev_handle;
168 } 157 }
169 } 158 }
170 if (!handler && evt_pins) { 159 if (!handler) {
171 struct acpi_gpio_evt_pin *evt_pin; 160 struct acpi_gpio_evt_pin *evt_pin;
172 161
162 status = acpi_get_handle(handle, "_EVT", &evt_handle);
163 if (ACPI_FAILURE(status))
164 continue
165
173 evt_pin = kzalloc(sizeof(*evt_pin), GFP_KERNEL); 166 evt_pin = kzalloc(sizeof(*evt_pin), GFP_KERNEL);
174 if (!evt_pin) 167 if (!evt_pin)
175 continue; 168 continue;
176 169
177 list_add_tail(&evt_pin->node, evt_pins); 170 list_add_tail(&evt_pin->node, &acpi_gpio->evt_pins);
178 evt_pin->evt_handle = evt_handle; 171 evt_pin->evt_handle = evt_handle;
179 evt_pin->pin = pin; 172 evt_pin->pin = pin;
180 evt_pin->irq = irq; 173 evt_pin->irq = irq;
@@ -197,39 +190,27 @@ static void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
197 190
198/** 191/**
199 * acpi_gpiochip_free_interrupts() - Free GPIO _EVT ACPI event interrupts. 192 * acpi_gpiochip_free_interrupts() - Free GPIO _EVT ACPI event interrupts.
200 * @chip: gpio chip 193 * @acpi_gpio: ACPI GPIO chip
201 * 194 *
202 * Free interrupts associated with the _EVT method for the given GPIO chip. 195 * Free interrupts associated with the _EVT method for the given GPIO chip.
203 * 196 *
204 * The remaining ACPI event interrupts associated with the chip are freed 197 * The remaining ACPI event interrupts associated with the chip are freed
205 * automatically. 198 * automatically.
206 */ 199 */
207static void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) 200static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
208{ 201{
209 acpi_handle handle;
210 acpi_status status;
211 struct list_head *evt_pins;
212 struct acpi_gpio_evt_pin *evt_pin, *ep; 202 struct acpi_gpio_evt_pin *evt_pin, *ep;
203 struct gpio_chip *chip = acpi_gpio->chip;
213 204
214 if (!chip->dev || !chip->to_irq) 205 if (!chip->dev || !chip->to_irq)
215 return; 206 return;
216 207
217 handle = ACPI_HANDLE(chip->dev); 208 list_for_each_entry_safe_reverse(evt_pin, ep, &acpi_gpio->evt_pins,
218 if (!handle) 209 node) {
219 return;
220
221 status = acpi_get_data(handle, acpi_gpio_evt_dh, (void **)&evt_pins);
222 if (ACPI_FAILURE(status))
223 return;
224
225 list_for_each_entry_safe_reverse(evt_pin, ep, evt_pins, node) {
226 devm_free_irq(chip->dev, evt_pin->irq, evt_pin); 210 devm_free_irq(chip->dev, evt_pin->irq, evt_pin);
227 list_del(&evt_pin->node); 211 list_del(&evt_pin->node);
228 kfree(evt_pin); 212 kfree(evt_pin);
229 } 213 }
230
231 acpi_detach_data(handle, acpi_gpio_evt_dh);
232 kfree(evt_pins);
233} 214}
234 215
235struct acpi_gpio_lookup { 216struct acpi_gpio_lookup {
@@ -312,10 +293,51 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
312 293
313void acpi_gpiochip_add(struct gpio_chip *chip) 294void acpi_gpiochip_add(struct gpio_chip *chip)
314{ 295{
315 acpi_gpiochip_request_interrupts(chip); 296 struct acpi_gpio_chip *acpi_gpio;
297 acpi_handle handle;
298 acpi_status status;
299
300 handle = ACPI_HANDLE(chip->dev);
301 if (!handle)
302 return;
303
304 acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL);
305 if (!acpi_gpio) {
306 dev_err(chip->dev,
307 "Failed to allocate memory for ACPI GPIO chip\n");
308 return;
309 }
310
311 acpi_gpio->chip = chip;
312
313 status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
314 if (ACPI_FAILURE(status)) {
315 dev_err(chip->dev, "Failed to attach ACPI GPIO chip\n");
316 kfree(acpi_gpio);
317 return;
318 }
319
320 acpi_gpiochip_request_interrupts(acpi_gpio);
316} 321}
317 322
318void acpi_gpiochip_remove(struct gpio_chip *chip) 323void acpi_gpiochip_remove(struct gpio_chip *chip)
319{ 324{
320 acpi_gpiochip_free_interrupts(chip); 325 struct acpi_gpio_chip *acpi_gpio;
326 acpi_handle handle;
327 acpi_status status;
328
329 handle = ACPI_HANDLE(chip->dev);
330 if (!handle)
331 return;
332
333 status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
334 if (ACPI_FAILURE(status)) {
335 dev_warn(chip->dev, "Failed to retrieve ACPI GPIO chip\n");
336 return;
337 }
338
339 acpi_gpiochip_free_interrupts(acpi_gpio);
340
341 acpi_detach_data(handle, acpi_gpio_chip_dh);
342 kfree(acpi_gpio);
321} 343}