summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-mpc8xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-mpc8xxx.c')
-rw-r--r--drivers/gpio/gpio-mpc8xxx.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 8c93dec498fa..c8673a5d9412 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/gpio/driver.h>
+#include <linux/bitops.h>
#define MPC8XXX_GPIO_PINS 32
@@ -44,6 +45,16 @@ struct mpc8xxx_gpio_chip {
unsigned int irqn;
};
+/*
+ * This hardware has a big endian bit assignment such that GPIO line 0 is
+ * connected to bit 31, line 1 to bit 30 ... line 31 to bit 0.
+ * This inline helper give the right bitmask for a certain line.
+ */
+static inline u32 mpc_pin2mask(unsigned int offset)
+{
+ return BIT(31 - offset);
+}
+
/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
* defined as output cannot be determined by reading GPDAT register,
* so we use shadow data register instead. The status of input pins
@@ -59,7 +70,7 @@ static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
val = gc->read_reg(mpc8xxx_gc->regs + GPIO_DAT) & ~out_mask;
out_shadow = gc->bgpio_data & out_mask;
- return !!((val | out_shadow) & gc->pin2mask(gc, gpio));
+ return !!((val | out_shadow) & mpc_pin2mask(gpio));
}
static int mpc5121_gpio_dir_out(struct gpio_chip *gc,
@@ -120,7 +131,7 @@ static void mpc8xxx_irq_unmask(struct irq_data *d)
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR)
- | gc->pin2mask(gc, irqd_to_hwirq(d)));
+ | mpc_pin2mask(irqd_to_hwirq(d)));
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
}
@@ -135,7 +146,7 @@ static void mpc8xxx_irq_mask(struct irq_data *d)
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR)
- & ~(gc->pin2mask(gc, irqd_to_hwirq(d))));
+ & ~mpc_pin2mask(irqd_to_hwirq(d)));
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
}
@@ -146,7 +157,7 @@ static void mpc8xxx_irq_ack(struct irq_data *d)
struct gpio_chip *gc = &mpc8xxx_gc->gc;
gc->write_reg(mpc8xxx_gc->regs + GPIO_IER,
- gc->pin2mask(gc, irqd_to_hwirq(d)));
+ mpc_pin2mask(irqd_to_hwirq(d)));
}
static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
@@ -160,7 +171,7 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR)
- | gc->pin2mask(gc, irqd_to_hwirq(d)));
+ | mpc_pin2mask(irqd_to_hwirq(d)));
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
break;
@@ -168,7 +179,7 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR)
- & ~(gc->pin2mask(gc, irqd_to_hwirq(d))));
+ & ~mpc_pin2mask(irqd_to_hwirq(d)));
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
break;