static void mpc8xxx_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); unsigned long flags; int i; raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); for (i = 0; i < gc->ngpio; i++) { if (*mask == 0) break; if (__test_and_clear_bit(i, mask)) { if (test_bit(i, bits)) mpc8xxx_gc->data |= mpc8xxx_gpio2mask(i); else mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(i); } } out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data); raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); }
static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) { struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS) return irq_create_mapping(mpc8xxx_gc->irq, offset); else return -ENXIO; }
/* 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 * is determined by reading GPDAT register. */ static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) { u32 val; struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); }
/* 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 * is determined by reading GPDAT register. */ static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) { u32 val; struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); u32 out_mask, out_shadow; out_mask = in_be32(mm->regs + GPIO_DIR); val = in_be32(mm->regs + GPIO_DAT) & ~out_mask; out_shadow = mpc8xxx_gc->data & out_mask; return (val | out_shadow) & mpc8xxx_gpio2mask(gpio); }
static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); unsigned long flags; spin_lock_irqsave(&mpc8xxx_gc->lock, flags); clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); return 0; }
static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) { struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); unsigned long flags; spin_lock_irqsave(&mpc8xxx_gc->lock, flags); if (val) mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio); else mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio); out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data); spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); }
static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) { struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); }