diff options
-rw-r--r-- | drivers/gpio/Kconfig | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-lynxpoint.c | 93 |
2 files changed, 26 insertions, 69 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 345da63fb0ad..255e8f00910f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -430,7 +430,7 @@ config GPIO_GE_FPGA | |||
430 | config GPIO_LYNXPOINT | 430 | config GPIO_LYNXPOINT |
431 | tristate "Intel Lynxpoint GPIO support" | 431 | tristate "Intel Lynxpoint GPIO support" |
432 | depends on ACPI && X86 | 432 | depends on ACPI && X86 |
433 | select IRQ_DOMAIN | 433 | select GPIOLIB_IRQCHIP |
434 | help | 434 | help |
435 | driver for GPIO functionality on Intel Lynxpoint PCH chipset | 435 | driver for GPIO functionality on Intel Lynxpoint PCH chipset |
436 | Requires ACPI device enumeration code to set up a platform device. | 436 | Requires ACPI device enumeration code to set up a platform device. |
diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index 7c141dd850a1..ff9eb911b5e4 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c | |||
@@ -25,9 +25,7 @@ | |||
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/irq.h> | ||
29 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
30 | #include <linux/irqdomain.h> | ||
31 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
32 | #include <linux/acpi.h> | 30 | #include <linux/acpi.h> |
33 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
@@ -62,7 +60,6 @@ | |||
62 | 60 | ||
63 | struct lp_gpio { | 61 | struct lp_gpio { |
64 | struct gpio_chip chip; | 62 | struct gpio_chip chip; |
65 | struct irq_domain *domain; | ||
66 | struct platform_device *pdev; | 63 | struct platform_device *pdev; |
67 | spinlock_t lock; | 64 | spinlock_t lock; |
68 | unsigned long reg_base; | 65 | unsigned long reg_base; |
@@ -151,7 +148,8 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned offset) | |||
151 | 148 | ||
152 | static int lp_irq_type(struct irq_data *d, unsigned type) | 149 | static int lp_irq_type(struct irq_data *d, unsigned type) |
153 | { | 150 | { |
154 | struct lp_gpio *lg = irq_data_get_irq_chip_data(d); | 151 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
152 | struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip); | ||
155 | u32 hwirq = irqd_to_hwirq(d); | 153 | u32 hwirq = irqd_to_hwirq(d); |
156 | unsigned long flags; | 154 | unsigned long flags; |
157 | u32 value; | 155 | u32 value; |
@@ -236,16 +234,11 @@ static int lp_gpio_direction_output(struct gpio_chip *chip, | |||
236 | return 0; | 234 | return 0; |
237 | } | 235 | } |
238 | 236 | ||
239 | static int lp_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
240 | { | ||
241 | struct lp_gpio *lg = container_of(chip, struct lp_gpio, chip); | ||
242 | return irq_create_mapping(lg->domain, offset); | ||
243 | } | ||
244 | |||
245 | static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc) | 237 | static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc) |
246 | { | 238 | { |
247 | struct irq_data *data = irq_desc_get_irq_data(desc); | 239 | struct irq_data *data = irq_desc_get_irq_data(desc); |
248 | struct lp_gpio *lg = irq_data_get_irq_handler_data(data); | 240 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
241 | struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip); | ||
249 | struct irq_chip *chip = irq_data_get_irq_chip(data); | 242 | struct irq_chip *chip = irq_data_get_irq_chip(data); |
250 | u32 base, pin, mask; | 243 | u32 base, pin, mask; |
251 | unsigned long reg, ena, pending; | 244 | unsigned long reg, ena, pending; |
@@ -262,7 +255,7 @@ static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc) | |||
262 | mask = BIT(pin); | 255 | mask = BIT(pin); |
263 | /* Clear before handling so we don't lose an edge */ | 256 | /* Clear before handling so we don't lose an edge */ |
264 | outl(mask, reg); | 257 | outl(mask, reg); |
265 | irq = irq_find_mapping(lg->domain, base + pin); | 258 | irq = irq_find_mapping(lg->chip.irqdomain, base + pin); |
266 | generic_handle_irq(irq); | 259 | generic_handle_irq(irq); |
267 | } | 260 | } |
268 | } | 261 | } |
@@ -279,7 +272,8 @@ static void lp_irq_mask(struct irq_data *d) | |||
279 | 272 | ||
280 | static void lp_irq_enable(struct irq_data *d) | 273 | static void lp_irq_enable(struct irq_data *d) |
281 | { | 274 | { |
282 | struct lp_gpio *lg = irq_data_get_irq_chip_data(d); | 275 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
276 | struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip); | ||
283 | u32 hwirq = irqd_to_hwirq(d); | 277 | u32 hwirq = irqd_to_hwirq(d); |
284 | unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); | 278 | unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); |
285 | unsigned long flags; | 279 | unsigned long flags; |
@@ -291,7 +285,8 @@ static void lp_irq_enable(struct irq_data *d) | |||
291 | 285 | ||
292 | static void lp_irq_disable(struct irq_data *d) | 286 | static void lp_irq_disable(struct irq_data *d) |
293 | { | 287 | { |
294 | struct lp_gpio *lg = irq_data_get_irq_chip_data(d); | 288 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
289 | struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip); | ||
295 | u32 hwirq = irqd_to_hwirq(d); | 290 | u32 hwirq = irqd_to_hwirq(d); |
296 | unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); | 291 | unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); |
297 | unsigned long flags; | 292 | unsigned long flags; |
@@ -301,26 +296,6 @@ static void lp_irq_disable(struct irq_data *d) | |||
301 | spin_unlock_irqrestore(&lg->lock, flags); | 296 | spin_unlock_irqrestore(&lg->lock, flags); |
302 | } | 297 | } |
303 | 298 | ||
304 | static int lp_irq_reqres(struct irq_data *d) | ||
305 | { | ||
306 | struct lp_gpio *lg = irq_data_get_irq_chip_data(d); | ||
307 | |||
308 | if (gpio_lock_as_irq(&lg->chip, irqd_to_hwirq(d))) { | ||
309 | dev_err(lg->chip.dev, | ||
310 | "unable to lock HW IRQ %lu for IRQ\n", | ||
311 | irqd_to_hwirq(d)); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static void lp_irq_relres(struct irq_data *d) | ||
318 | { | ||
319 | struct lp_gpio *lg = irq_data_get_irq_chip_data(d); | ||
320 | |||
321 | gpio_unlock_as_irq(&lg->chip, irqd_to_hwirq(d)); | ||
322 | } | ||
323 | |||
324 | static struct irq_chip lp_irqchip = { | 299 | static struct irq_chip lp_irqchip = { |
325 | .name = "LP-GPIO", | 300 | .name = "LP-GPIO", |
326 | .irq_mask = lp_irq_mask, | 301 | .irq_mask = lp_irq_mask, |
@@ -328,8 +303,6 @@ static struct irq_chip lp_irqchip = { | |||
328 | .irq_enable = lp_irq_enable, | 303 | .irq_enable = lp_irq_enable, |
329 | .irq_disable = lp_irq_disable, | 304 | .irq_disable = lp_irq_disable, |
330 | .irq_set_type = lp_irq_type, | 305 | .irq_set_type = lp_irq_type, |
331 | .irq_request_resources = lp_irq_reqres, | ||
332 | .irq_release_resources = lp_irq_relres, | ||
333 | .flags = IRQCHIP_SKIP_SET_WAKE, | 306 | .flags = IRQCHIP_SKIP_SET_WAKE, |
334 | }; | 307 | }; |
335 | 308 | ||
@@ -348,22 +321,6 @@ static void lp_gpio_irq_init_hw(struct lp_gpio *lg) | |||
348 | } | 321 | } |
349 | } | 322 | } |
350 | 323 | ||
351 | static int lp_gpio_irq_map(struct irq_domain *d, unsigned int irq, | ||
352 | irq_hw_number_t hwirq) | ||
353 | { | ||
354 | struct lp_gpio *lg = d->host_data; | ||
355 | |||
356 | irq_set_chip_and_handler(irq, &lp_irqchip, handle_simple_irq); | ||
357 | irq_set_chip_data(irq, lg); | ||
358 | irq_set_irq_type(irq, IRQ_TYPE_NONE); | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static const struct irq_domain_ops lp_gpio_irq_ops = { | ||
364 | .map = lp_gpio_irq_map, | ||
365 | }; | ||
366 | |||
367 | static int lp_gpio_probe(struct platform_device *pdev) | 324 | static int lp_gpio_probe(struct platform_device *pdev) |
368 | { | 325 | { |
369 | struct lp_gpio *lg; | 326 | struct lp_gpio *lg; |
@@ -371,7 +328,6 @@ static int lp_gpio_probe(struct platform_device *pdev) | |||
371 | struct resource *io_rc, *irq_rc; | 328 | struct resource *io_rc, *irq_rc; |
372 | struct device *dev = &pdev->dev; | 329 | struct device *dev = &pdev->dev; |
373 | unsigned long reg_len; | 330 | unsigned long reg_len; |
374 | unsigned hwirq; | ||
375 | int ret = -ENODEV; | 331 | int ret = -ENODEV; |
376 | 332 | ||
377 | lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL); | 333 | lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL); |
@@ -414,27 +370,28 @@ static int lp_gpio_probe(struct platform_device *pdev) | |||
414 | gc->can_sleep = false; | 370 | gc->can_sleep = false; |
415 | gc->dev = dev; | 371 | gc->dev = dev; |
416 | 372 | ||
373 | ret = gpiochip_add(gc); | ||
374 | if (ret) { | ||
375 | dev_err(dev, "failed adding lp-gpio chip\n"); | ||
376 | return ret; | ||
377 | } | ||
378 | |||
417 | /* set up interrupts */ | 379 | /* set up interrupts */ |
418 | if (irq_rc && irq_rc->start) { | 380 | if (irq_rc && irq_rc->start) { |
419 | hwirq = irq_rc->start; | ||
420 | gc->to_irq = lp_gpio_to_irq; | ||
421 | |||
422 | lg->domain = irq_domain_add_linear(NULL, LP_NUM_GPIO, | ||
423 | &lp_gpio_irq_ops, lg); | ||
424 | if (!lg->domain) | ||
425 | return -ENXIO; | ||
426 | |||
427 | lp_gpio_irq_init_hw(lg); | 381 | lp_gpio_irq_init_hw(lg); |
382 | ret = gpiochip_irqchip_add(gc, &lp_irqchip, 0, | ||
383 | handle_simple_irq, IRQ_TYPE_NONE); | ||
384 | if (ret) { | ||
385 | dev_err(dev, "failed to add irqchip\n"); | ||
386 | gpiochip_remove(gc); | ||
387 | return ret; | ||
388 | } | ||
428 | 389 | ||
429 | irq_set_handler_data(hwirq, lg); | 390 | gpiochip_set_chained_irqchip(gc, &lp_irqchip, |
430 | irq_set_chained_handler(hwirq, lp_gpio_irq_handler); | 391 | (unsigned)irq_rc->start, |
392 | lp_gpio_irq_handler); | ||
431 | } | 393 | } |
432 | 394 | ||
433 | ret = gpiochip_add(gc); | ||
434 | if (ret) { | ||
435 | dev_err(dev, "failed adding lp-gpio chip\n"); | ||
436 | return ret; | ||
437 | } | ||
438 | pm_runtime_enable(dev); | 395 | pm_runtime_enable(dev); |
439 | 396 | ||
440 | return 0; | 397 | return 0; |