Skip to content

Commit aa92b6f

Browse files
westeriLinus Walleij
authored andcommitted
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 <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent 77c2d79 commit aa92b6f

File tree

1 file changed

+64
-42
lines changed

1 file changed

+64
-42
lines changed

drivers/gpio/gpiolib-acpi.c

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ struct acpi_gpio_evt_pin {
2626
unsigned int irq;
2727
};
2828

29+
struct acpi_gpio_chip {
30+
struct gpio_chip *chip;
31+
struct list_head evt_pins;
32+
};
33+
2934
static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
3035
{
3136
if (!gc->dev)
@@ -81,27 +86,27 @@ static irqreturn_t acpi_gpio_irq_handler_evt(int irq, void *data)
8186
return IRQ_HANDLED;
8287
}
8388

84-
static void acpi_gpio_evt_dh(acpi_handle handle, void *data)
89+
static void acpi_gpio_chip_dh(acpi_handle handle, void *data)
8590
{
8691
/* The address of this function is used as a key. */
8792
}
8893

8994
/**
9095
* acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events
91-
* @chip: gpio chip
96+
* @acpi_gpio: ACPI GPIO chip
9297
*
9398
* ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are
9499
* handled by ACPI event methods which need to be called from the GPIO
95100
* chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which
96101
* gpio pins have acpi event methods and assigns interrupt handlers that calls
97102
* the acpi event methods for those pins.
98103
*/
99-
static void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
104+
static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
100105
{
101106
struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
107+
struct gpio_chip *chip = acpi_gpio->chip;
102108
struct acpi_resource *res;
103109
acpi_handle handle, evt_handle;
104-
struct list_head *evt_pins = NULL;
105110
acpi_status status;
106111
unsigned int pin;
107112
int irq, ret;
@@ -114,23 +119,7 @@ static void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
114119
if (!handle)
115120
return;
116121

117-
status = acpi_get_event_resources(handle, &buf);
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-
}
122+
INIT_LIST_HEAD(&acpi_gpio->evt_pins);
134123

135124
/*
136125
* 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)
167156
data = ev_handle;
168157
}
169158
}
170-
if (!handler && evt_pins) {
159+
if (!handler) {
171160
struct acpi_gpio_evt_pin *evt_pin;
172161

162+
status = acpi_get_handle(handle, "_EVT", &evt_handle);
163+
if (ACPI_FAILURE(status))
164+
continue
165+
173166
evt_pin = kzalloc(sizeof(*evt_pin), GFP_KERNEL);
174167
if (!evt_pin)
175168
continue;
176169

177-
list_add_tail(&evt_pin->node, evt_pins);
170+
list_add_tail(&evt_pin->node, &acpi_gpio->evt_pins);
178171
evt_pin->evt_handle = evt_handle;
179172
evt_pin->pin = pin;
180173
evt_pin->irq = irq;
@@ -197,39 +190,27 @@ static void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
197190

198191
/**
199192
* acpi_gpiochip_free_interrupts() - Free GPIO _EVT ACPI event interrupts.
200-
* @chip: gpio chip
193+
* @acpi_gpio: ACPI GPIO chip
201194
*
202195
* Free interrupts associated with the _EVT method for the given GPIO chip.
203196
*
204197
* The remaining ACPI event interrupts associated with the chip are freed
205198
* automatically.
206199
*/
207-
static void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
200+
static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
208201
{
209-
acpi_handle handle;
210-
acpi_status status;
211-
struct list_head *evt_pins;
212202
struct acpi_gpio_evt_pin *evt_pin, *ep;
203+
struct gpio_chip *chip = acpi_gpio->chip;
213204

214205
if (!chip->dev || !chip->to_irq)
215206
return;
216207

217-
handle = ACPI_HANDLE(chip->dev);
218-
if (!handle)
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) {
208+
list_for_each_entry_safe_reverse(evt_pin, ep, &acpi_gpio->evt_pins,
209+
node) {
226210
devm_free_irq(chip->dev, evt_pin->irq, evt_pin);
227211
list_del(&evt_pin->node);
228212
kfree(evt_pin);
229213
}
230-
231-
acpi_detach_data(handle, acpi_gpio_evt_dh);
232-
kfree(evt_pins);
233214
}
234215

235216
struct acpi_gpio_lookup {
@@ -312,10 +293,51 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
312293

313294
void acpi_gpiochip_add(struct gpio_chip *chip)
314295
{
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);
316321
}
317322

318323
void acpi_gpiochip_remove(struct gpio_chip *chip)
319324
{
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);
321343
}

0 commit comments

Comments
 (0)