|
@@ -377,6 +377,10 @@ static void cpm1_set_pin16(int port, int pin, int flags)
|
|
|
setbits16(&iop->odr_sor, pin);
|
|
|
else
|
|
|
clrbits16(&iop->odr_sor, pin);
|
|
|
+ if (flags & CPM_PIN_FALLEDGE)
|
|
|
+ setbits16(&iop->intr, pin);
|
|
|
+ else
|
|
|
+ clrbits16(&iop->intr, pin);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -528,6 +532,9 @@ struct cpm1_gpio16_chip {
|
|
|
|
|
|
/* shadowed data register to clear/set bits safely */
|
|
|
u16 cpdata;
|
|
|
+
|
|
|
+ /* IRQ associated with Pins when relevant */
|
|
|
+ int irq[16];
|
|
|
};
|
|
|
|
|
|
static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc)
|
|
@@ -578,6 +585,14 @@ static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
|
|
|
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
|
|
|
}
|
|
|
|
|
|
+static int cpm1_gpio16_to_irq(struct gpio_chip *gc, unsigned int gpio)
|
|
|
+{
|
|
|
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
|
|
+ struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
|
|
|
+
|
|
|
+ return cpm1_gc->irq[gpio] ? : -ENXIO;
|
|
|
+}
|
|
|
+
|
|
|
static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
|
|
{
|
|
|
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
|
@@ -618,6 +633,7 @@ int cpm1_gpiochip_add16(struct device_node *np)
|
|
|
struct cpm1_gpio16_chip *cpm1_gc;
|
|
|
struct of_mm_gpio_chip *mm_gc;
|
|
|
struct gpio_chip *gc;
|
|
|
+ u16 mask;
|
|
|
|
|
|
cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
|
|
|
if (!cpm1_gc)
|
|
@@ -625,6 +641,14 @@ int cpm1_gpiochip_add16(struct device_node *np)
|
|
|
|
|
|
spin_lock_init(&cpm1_gc->lock);
|
|
|
|
|
|
+ if (!of_property_read_u16(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
|
|
|
+ int i, j;
|
|
|
+
|
|
|
+ for (i = 0, j = 0; i < 16; i++)
|
|
|
+ if (mask & (1 << (15 - i)))
|
|
|
+ cpm1_gc->irq[i] = irq_of_parse_and_map(np, j++);
|
|
|
+ }
|
|
|
+
|
|
|
mm_gc = &cpm1_gc->mm_gc;
|
|
|
gc = &mm_gc->gc;
|
|
|
|
|
@@ -634,6 +658,7 @@ int cpm1_gpiochip_add16(struct device_node *np)
|
|
|
gc->direction_output = cpm1_gpio16_dir_out;
|
|
|
gc->get = cpm1_gpio16_get;
|
|
|
gc->set = cpm1_gpio16_set;
|
|
|
+ gc->to_irq = cpm1_gpio16_to_irq;
|
|
|
|
|
|
return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc);
|
|
|
}
|