aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib-acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpiolib-acpi.c')
-rw-r--r--drivers/gpio/gpiolib-acpi.c214
1 files changed, 129 insertions, 85 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index be09e7526890..092ea4e5c9a8 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -70,9 +70,9 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
70 70
71static irqreturn_t acpi_gpio_irq_handler(int irq, void *data) 71static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
72{ 72{
73 acpi_handle handle = data; 73 struct acpi_gpio_event *event = data;
74 74
75 acpi_evaluate_object(handle, NULL, NULL, NULL); 75 acpi_evaluate_object(event->handle, NULL, NULL, NULL);
76 76
77 return IRQ_HANDLED; 77 return IRQ_HANDLED;
78} 78}
@@ -91,111 +91,148 @@ static void acpi_gpio_chip_dh(acpi_handle handle, void *data)
91 /* The address of this function is used as a key. */ 91 /* The address of this function is used as a key. */
92} 92}
93 93
94/** 94static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
95 * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events 95 void *context)
96 * @acpi_gpio: ACPI GPIO chip
97 *
98 * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are
99 * handled by ACPI event methods which need to be called from the GPIO
100 * chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which
101 * gpio pins have acpi event methods and assigns interrupt handlers that calls
102 * the acpi event methods for those pins.
103 */
104static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
105{ 96{
106 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; 97 struct acpi_gpio_chip *acpi_gpio = context;
107 struct gpio_chip *chip = acpi_gpio->chip; 98 struct gpio_chip *chip = acpi_gpio->chip;
108 struct acpi_resource *res; 99 struct acpi_resource_gpio *agpio;
109 acpi_handle handle, evt_handle; 100 acpi_handle handle, evt_handle;
110 acpi_status status; 101 struct acpi_gpio_event *event;
111 unsigned int pin; 102 irq_handler_t handler = NULL;
112 int irq, ret; 103 struct gpio_desc *desc;
113 char ev_name[5]; 104 unsigned long irqflags;
105 int ret, pin, irq;
114 106
115 if (!chip->dev || !chip->to_irq) 107 if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
116 return; 108 return AE_OK;
109
110 agpio = &ares->data.gpio;
111 if (agpio->connection_type != ACPI_RESOURCE_GPIO_TYPE_INT)
112 return AE_OK;
117 113
118 handle = ACPI_HANDLE(chip->dev); 114 handle = ACPI_HANDLE(chip->dev);
119 if (!handle) 115 pin = agpio->pin_table[0];
120 return; 116
117 if (pin <= 255) {
118 char ev_name[5];
119 sprintf(ev_name, "_%c%02X",
120 agpio->triggering == ACPI_EDGE_SENSITIVE ? 'E' : 'L',
121 pin);
122 if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle)))
123 handler = acpi_gpio_irq_handler;
124 }
125 if (!handler) {
126 if (ACPI_SUCCESS(acpi_get_handle(handle, "_EVT", &evt_handle)))
127 handler = acpi_gpio_irq_handler_evt;
128 }
129 if (!handler)
130 return AE_BAD_PARAMETER;
121 131
122 INIT_LIST_HEAD(&acpi_gpio->events); 132 desc = gpiochip_get_desc(chip, pin);
133 if (IS_ERR(desc)) {
134 dev_err(chip->dev, "Failed to get GPIO descriptor\n");
135 return AE_ERROR;
136 }
123 137
124 /* 138 ret = gpiochip_request_own_desc(desc, "ACPI:Event");
125 * If a GPIO interrupt has an ACPI event handler method, or _EVT is 139 if (ret) {
126 * present, set up an interrupt handler that calls the ACPI event 140 dev_err(chip->dev, "Failed to request GPIO\n");
127 * handler. 141 return AE_ERROR;
128 */ 142 }
129 for (res = buf.pointer;
130 res && (res->type != ACPI_RESOURCE_TYPE_END_TAG);
131 res = ACPI_NEXT_RESOURCE(res)) {
132 irq_handler_t handler = NULL;
133 void *data;
134
135 if (res->type != ACPI_RESOURCE_TYPE_GPIO ||
136 res->data.gpio.connection_type !=
137 ACPI_RESOURCE_GPIO_TYPE_INT)
138 continue;
139 143
140 pin = res->data.gpio.pin_table[0]; 144 gpiod_direction_input(desc);
141 if (pin > chip->ngpio)
142 continue;
143 145
144 irq = chip->to_irq(chip, pin); 146 ret = gpiod_lock_as_irq(desc);
145 if (irq < 0) 147 if (ret) {
146 continue; 148 dev_err(chip->dev, "Failed to lock GPIO as interrupt\n");
149 goto fail_free_desc;
150 }
147 151
148 if (pin <= 255) { 152 irq = gpiod_to_irq(desc);
149 acpi_handle ev_handle; 153 if (irq < 0) {
154 dev_err(chip->dev, "Failed to translate GPIO to IRQ\n");
155 goto fail_unlock_irq;
156 }
150 157
151 sprintf(ev_name, "_%c%02X", 158 irqflags = IRQF_ONESHOT;
152 res->data.gpio.triggering ? 'E' : 'L', pin); 159 if (agpio->triggering == ACPI_LEVEL_SENSITIVE) {
153 status = acpi_get_handle(handle, ev_name, &ev_handle); 160 if (agpio->polarity == ACPI_ACTIVE_HIGH)
154 if (ACPI_SUCCESS(status)) { 161 irqflags |= IRQF_TRIGGER_HIGH;
155 handler = acpi_gpio_irq_handler; 162 else
156 data = ev_handle; 163 irqflags |= IRQF_TRIGGER_LOW;
157 } 164 } else {
165 switch (agpio->polarity) {
166 case ACPI_ACTIVE_HIGH:
167 irqflags |= IRQF_TRIGGER_RISING;
168 break;
169 case ACPI_ACTIVE_LOW:
170 irqflags |= IRQF_TRIGGER_FALLING;
171 break;
172 default:
173 irqflags |= IRQF_TRIGGER_RISING |
174 IRQF_TRIGGER_FALLING;
175 break;
158 } 176 }
159 if (!handler) { 177 }
160 struct acpi_gpio_event *event;
161
162 status = acpi_get_handle(handle, "_EVT", &evt_handle);
163 if (ACPI_FAILURE(status))
164 continue
165 178
166 event = kzalloc(sizeof(*event), GFP_KERNEL); 179 event = kzalloc(sizeof(*event), GFP_KERNEL);
167 if (!event) 180 if (!event)
168 continue; 181 goto fail_unlock_irq;
169 182
170 list_add_tail(&event->node, &acpi_gpio->events); 183 event->handle = evt_handle;
171 event->handle = evt_handle; 184 event->irq = irq;
172 event->pin = pin; 185 event->pin = pin;
173 event->irq = irq;
174 handler = acpi_gpio_irq_handler_evt;
175 data = event;
176 }
177 if (!handler)
178 continue;
179 186
180 /* Assume BIOS sets the triggering, so no flags */ 187 ret = request_threaded_irq(event->irq, NULL, handler, irqflags,
181 ret = devm_request_threaded_irq(chip->dev, irq, NULL, handler, 188 "ACPI:Event", event);
182 0, "GPIO-signaled-ACPI-event", 189 if (ret) {
183 data); 190 dev_err(chip->dev, "Failed to setup interrupt handler for %d\n",
184 if (ret) 191 event->irq);
185 dev_err(chip->dev, 192 goto fail_free_event;
186 "Failed to request IRQ %d ACPI event handler\n",
187 irq);
188 } 193 }
194
195 list_add_tail(&event->node, &acpi_gpio->events);
196 return AE_OK;
197
198fail_free_event:
199 kfree(event);
200fail_unlock_irq:
201 gpiod_unlock_as_irq(desc);
202fail_free_desc:
203 gpiochip_free_own_desc(desc);
204
205 return AE_ERROR;
189} 206}
190 207
191/** 208/**
192 * acpi_gpiochip_free_interrupts() - Free GPIO _EVT ACPI event interrupts. 209 * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events
193 * @acpi_gpio: ACPI GPIO chip 210 * @acpi_gpio: ACPI GPIO chip
194 * 211 *
195 * Free interrupts associated with the _EVT method for the given GPIO chip. 212 * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are
213 * handled by ACPI event methods which need to be called from the GPIO
214 * chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which
215 * gpio pins have acpi event methods and assigns interrupt handlers that calls
216 * the acpi event methods for those pins.
217 */
218static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
219{
220 struct gpio_chip *chip = acpi_gpio->chip;
221
222 if (!chip->dev || !chip->to_irq)
223 return;
224
225 INIT_LIST_HEAD(&acpi_gpio->events);
226 acpi_walk_resources(ACPI_HANDLE(chip->dev), "_AEI",
227 acpi_gpiochip_request_interrupt, acpi_gpio);
228}
229
230/**
231 * acpi_gpiochip_free_interrupts() - Free GPIO ACPI event interrupts.
232 * @acpi_gpio: ACPI GPIO chip
196 * 233 *
197 * The remaining ACPI event interrupts associated with the chip are freed 234 * Free interrupts associated with GPIO ACPI event method for the given
198 * automatically. 235 * GPIO chip.
199 */ 236 */
200static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio) 237static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
201{ 238{
@@ -206,7 +243,14 @@ static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
206 return; 243 return;
207 244
208 list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) { 245 list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
209 devm_free_irq(chip->dev, event->irq, event); 246 struct gpio_desc *desc;
247
248 free_irq(event->irq, event);
249 desc = gpiochip_get_desc(chip, event->pin);
250 if (WARN_ON(IS_ERR(desc)))
251 continue;
252 gpiod_unlock_as_irq(desc);
253 gpiochip_free_own_desc(desc);
210 list_del(&event->node); 254 list_del(&event->node);
211 kfree(event); 255 kfree(event);
212 } 256 }