On Mon, May 23, 2011 at 11:25:30AM +0200, Anatolij Gustschin wrote: > The mpc52xx_gpio driver currently supports 8 wakeup GPIOs and 32 > simple GPIOs. Extend it to also support GPIO function of 8 simple > interrupt GPIOs controlled in the standard GPIO register module. > > Signed-off-by: Anatolij Gustschin <ag...@denx.de> > --- > arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 117 > ++++++++++++++++++++++++++++
I don't want to merge more open coded MMIO gpio driver code. This whole driver really needs to be converted to use GENERIC_GPIO. g. > 1 files changed, 117 insertions(+), 0 deletions(-) > > diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c > b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c > index 1757d1d..42a0759 100644 > --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c > +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c > @@ -35,6 +35,9 @@ struct mpc52xx_gpiochip { > unsigned int shadow_dvo; > unsigned int shadow_gpioe; > unsigned int shadow_ddr; > + unsigned char sint_shadow_dvo; > + unsigned char sint_shadow_gpioe; > + unsigned char sint_shadow_ddr; > }; > > /* > @@ -309,6 +312,100 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, > unsigned int gpio, int val) > return 0; > } > > +static int mpc52xx_sint_gpio_get(struct gpio_chip *gc, unsigned int gpio) > +{ > + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); > + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; > + unsigned int ret; > + > + ret = (in_8(®s->sint_ival) >> (7 - gpio)) & 1; > + > + pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret); > + > + return ret; > +} > + > +static inline void > +__mpc52xx_sint_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) > +{ > + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); > + struct mpc52xx_gpiochip *chip = container_of(mm_gc, > + struct mpc52xx_gpiochip, mmchip); > + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; > + > + if (val) > + chip->sint_shadow_dvo |= 1 << (7 - gpio); > + else > + chip->sint_shadow_dvo &= ~(1 << (7 - gpio)); > + > + out_8(®s->sint_dvo, chip->sint_shadow_dvo); > +} > + > +static void > +mpc52xx_sint_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) > +{ > + unsigned long flags; > + > + spin_lock_irqsave(&gpio_lock, flags); > + > + __mpc52xx_sint_gpio_set(gc, gpio, val); > + > + spin_unlock_irqrestore(&gpio_lock, flags); > + > + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); > +} > + > +static int mpc52xx_sint_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) > +{ > + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); > + struct mpc52xx_gpiochip *chip = container_of(mm_gc, > + struct mpc52xx_gpiochip, mmchip); > + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; > + unsigned long flags; > + > + spin_lock_irqsave(&gpio_lock, flags); > + > + /* set the direction */ > + chip->sint_shadow_ddr &= ~(1 << (7 - gpio)); > + out_8(®s->sint_ddr, chip->sint_shadow_ddr); > + > + /* and enable the pin */ > + chip->sint_shadow_gpioe |= 1 << (7 - gpio); > + out_8(®s->sint_gpioe, chip->sint_shadow_gpioe); > + > + spin_unlock_irqrestore(&gpio_lock, flags); > + > + return 0; > +} > + > +static int > +mpc52xx_sint_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) > +{ > + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); > + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; > + struct mpc52xx_gpiochip *chip = container_of(mm_gc, > + struct mpc52xx_gpiochip, mmchip); > + unsigned long flags; > + > + spin_lock_irqsave(&gpio_lock, flags); > + > + __mpc52xx_sint_gpio_set(gc, gpio, val); > + > + /* Then set direction */ > + chip->sint_shadow_ddr |= 1 << (7 - gpio); > + out_8(®s->sint_ddr, chip->sint_shadow_ddr); > + > + /* Finally enable the pin */ > + chip->sint_shadow_gpioe |= 1 << (7 - gpio); > + out_8(®s->sint_gpioe, chip->sint_shadow_gpioe); > + > + spin_unlock_irqrestore(&gpio_lock, flags); > + > + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); > + > + return 0; > +} > + > static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device > *ofdev) > { > struct mpc52xx_gpiochip *chip; > @@ -337,6 +434,26 @@ static int __devinit > mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev > chip->shadow_ddr = in_be32(®s->simple_ddr); > chip->shadow_dvo = in_be32(®s->simple_dvo); > > + chip = kzalloc(sizeof(*chip), GFP_KERNEL); > + if (!chip) > + return -ENOMEM; > + > + gc = &chip->mmchip.gc; > + > + gc->ngpio = 8; > + gc->direction_input = mpc52xx_sint_gpio_dir_in; > + gc->direction_output = mpc52xx_sint_gpio_dir_out; > + gc->get = mpc52xx_sint_gpio_get; > + gc->set = mpc52xx_sint_gpio_set; > + > + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); > + if (ret) > + return ret; > + > + regs = chip->mmchip.regs; > + chip->sint_shadow_gpioe = in_8(®s->sint_gpioe); > + chip->sint_shadow_ddr = in_8(®s->sint_ddr); > + chip->sint_shadow_dvo = in_8(®s->sint_dvo); > return 0; > } > > -- > 1.7.1 > _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev