summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/gpio/gpio-mxc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/gpio/gpio-mxc.c')
-rw-r--r--kernel/drivers/gpio/gpio-mxc.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/kernel/drivers/gpio/gpio-mxc.c b/kernel/drivers/gpio/gpio-mxc.c
index 9f7446a7a..6ea8df6c7 100644
--- a/kernel/drivers/gpio/gpio-mxc.c
+++ b/kernel/drivers/gpio/gpio-mxc.c
@@ -33,7 +33,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/module.h>
-#include <asm-generic/bug.h>
+#include <linux/bug.h>
enum mxc_gpio_hwtype {
IMX1_GPIO, /* runs on i.mx1 */
@@ -131,7 +131,7 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
#define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge)
#define GPIO_INT_BOTH_EDGES 0x4
-static struct platform_device_id mxc_gpio_devtype[] = {
+static const struct platform_device_id mxc_gpio_devtype[] = {
{
.name = "imx1-gpio",
.driver_data = IMX1_GPIO,
@@ -272,11 +272,11 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
}
/* MX1 and MX3 has one interrupt *per* gpio port */
-static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+static void mx3_gpio_irq_handler(struct irq_desc *desc)
{
u32 irq_stat;
- struct mxc_gpio_port *port = irq_get_handler_data(irq);
- struct irq_chip *chip = irq_get_chip(irq);
+ struct mxc_gpio_port *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
chained_irq_enter(chip, desc);
@@ -288,11 +288,11 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
}
/* MX2 has one interrupt *for all* gpio ports */
-static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+static void mx2_gpio_irq_handler(struct irq_desc *desc)
{
u32 irq_msk, irq_stat;
struct mxc_gpio_port *port;
- struct irq_chip *chip = irq_get_chip(irq);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
chained_irq_enter(chip, desc);
@@ -339,13 +339,15 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
return 0;
}
-static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
+static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
gc = irq_alloc_generic_chip("gpio-mxc", 1, irq_base,
port->base, handle_level_irq);
+ if (!gc)
+ return -ENOMEM;
gc->private = port;
ct = gc->chip_types;
@@ -354,11 +356,14 @@ static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
ct->chip.irq_unmask = irq_gc_mask_set_bit;
ct->chip.irq_set_type = gpio_set_irq_type;
ct->chip.irq_set_wake = gpio_set_wake_irq;
+ ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND;
ct->regs.ack = GPIO_ISR;
ct->regs.mask = GPIO_IMR;
irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
IRQ_NOREQUEST, 0);
+
+ return 0;
}
static void mxc_gpio_get_hw(struct platform_device *pdev)
@@ -437,20 +442,20 @@ static int mxc_gpio_probe(struct platform_device *pdev)
irq_set_chained_handler(port->irq, mx2_gpio_irq_handler);
} else {
/* setup one handler for each entry */
- irq_set_chained_handler(port->irq, mx3_gpio_irq_handler);
- irq_set_handler_data(port->irq, port);
- if (port->irq_high > 0) {
+ irq_set_chained_handler_and_data(port->irq,
+ mx3_gpio_irq_handler, port);
+ if (port->irq_high > 0)
/* setup handler for GPIO 16 to 31 */
- irq_set_chained_handler(port->irq_high,
- mx3_gpio_irq_handler);
- irq_set_handler_data(port->irq_high, port);
- }
+ irq_set_chained_handler_and_data(port->irq_high,
+ mx3_gpio_irq_handler,
+ port);
}
err = bgpio_init(&port->bgc, &pdev->dev, 4,
port->base + GPIO_PSR,
port->base + GPIO_DR, NULL,
- port->base + GPIO_GDIR, NULL, 0);
+ port->base + GPIO_GDIR, NULL,
+ BGPIOF_READ_OUTPUT_REG_SET);
if (err)
goto out_bgio;
@@ -476,12 +481,16 @@ static int mxc_gpio_probe(struct platform_device *pdev)
}
/* gpio-mxc can be a generic irq chip */
- mxc_gpio_init_gc(port, irq_base);
+ err = mxc_gpio_init_gc(port, irq_base);
+ if (err < 0)
+ goto out_irqdomain_remove;
list_add_tail(&port->node, &mxc_gpio_ports);
return 0;
+out_irqdomain_remove:
+ irq_domain_remove(port->domain);
out_irqdesc_free:
irq_free_descs(irq_base, 32);
out_gpiochip_remove: