@@ -98,6 +98,7 @@ enum ab8500_gpio_action {
struct ab8500_gpio_irq_cluster {
int start;
int end;
+ int offset;
};
struct ab8500_gpio {
@@ -155,10 +156,12 @@ static struct ab8500_gpio_irq_cluster ab8505_irq_clusters[] = {
/*
* For AB8540 Only some GPIOs are interrupt capable:
+ * GPIO43 to GPIO44
* GPIO51 to GPIO54
*/
static struct ab8500_gpio_irq_cluster ab8540_irq_clusters[] = {
- {.start = 50, .end = 53}, /* GPIO numbers start from 1 */
+ {.start = 42, .end = 43, .offset = 2}, /* GPIO numbers start from 1 */
+ {.start = 50, .end = 53},
};
@@ -253,7 +256,7 @@ static int ab8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
return base + offset - cluster->start;
/* Advance by the number of gpios in this cluster */
- base += cluster->end - cluster->start + 1;
+ base += cluster->end + cluster->offset - cluster->start + 1;
}
return -EINVAL;
@@ -273,7 +276,12 @@ static unsigned int irq_to_rising(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = irq_get_chip_data(irq);
int offset = irq - ab8500_gpio->irq_base;
- int new_irq = offset + AB8500_INT_GPIO6R
+ int new_irq;
+ if (is_ab8540(ab8500_gpio->parent)) {
+ new_irq = offset * 2 + AB8540_INT_GPIO43R
+ + ab8500_gpio->parent->irq_base;
+ } else
+ new_irq = offset + AB8500_INT_GPIO6R
+ ab8500_gpio->parent->irq_base;
return new_irq;
}
@@ -282,8 +290,13 @@ static unsigned int irq_to_falling(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = irq_get_chip_data(irq);
int offset = irq - ab8500_gpio->irq_base;
- int new_irq = offset + AB8500_INT_GPIO6F
- + ab8500_gpio->parent->irq_base;
+ int new_irq;
+ if (is_ab8540(ab8500_gpio->parent)) {
+ new_irq = offset * 2 + AB8540_INT_GPIO43F
+ + ab8500_gpio->parent->irq_base;
+ } else
+ new_irq = offset + AB8500_INT_GPIO6F
+ + ab8500_gpio->parent->irq_base;
return new_irq;
}
@@ -291,20 +304,33 @@ static unsigned int irq_to_falling(unsigned int irq)
static unsigned int rising_to_irq(unsigned int irq, void *dev)
{
struct ab8500_gpio *ab8500_gpio = dev;
- int offset = irq - AB8500_INT_GPIO6R
- - ab8500_gpio->parent->irq_base ;
- int new_irq = offset + ab8500_gpio->irq_base;
+ int offset, new_irq;
+ if (is_ab8540(ab8500_gpio->parent)) {
+ offset = irq - AB8540_INT_GPIO43R
+ - ab8500_gpio->parent->irq_base;
+ new_irq = (offset >> 1) + ab8500_gpio->irq_base;
+ } else {
+ offset = irq - AB8500_INT_GPIO6R
+ - ab8500_gpio->parent->irq_base;
+ new_irq = offset + ab8500_gpio->irq_base;
+ }
return new_irq;
}
static unsigned int falling_to_irq(unsigned int irq, void *dev)
{
struct ab8500_gpio *ab8500_gpio = dev;
- int offset = irq - AB8500_INT_GPIO6F
- - ab8500_gpio->parent->irq_base ;
- int new_irq = offset + ab8500_gpio->irq_base;
+ int offset, new_irq;
+ if (is_ab8540(ab8500_gpio->parent)) {
+ offset = irq - AB8540_INT_GPIO43F
+ - ab8500_gpio->parent->irq_base;
+ new_irq = (offset >> 1) + ab8500_gpio->irq_base;
+ } else {
+ offset = irq - AB8500_INT_GPIO6F
+ - ab8500_gpio->parent->irq_base;
+ new_irq = offset + ab8500_gpio->irq_base;
+ }
return new_irq;
-
}
/*