On Tue, Jun 3, 2014 at 12:29 AM, Rojhalat Ibrahim <[email protected]> wrote:
> Add a set_multiple function to the MPC8xxx GPIO chip driver and thereby allow
> for actual performance improvements when setting multiple outputs
> simultaneously. In my case the time needed to configure an FPGA goes down from
> 48 s to 20 s.
>
> Signed-off-by: Rojhalat Ibrahim <[email protected]>
> ---
> This patch depends on my previous patch "gpiolib: allow simultaneous setting
> of multiple GPIO outputs".
>
> Change log:
> v4: - change interface of the set_multiple driver function to use
> unsigned long as type for the bit fields
> - use generic bitops (which also use unsigned long for bit fields)
> v3: - change commit message
> v2: - add this patch (v1 included only changes to gpiolib)
>
> drivers/gpio/gpio-mpc8xxx.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
> index d7d6d72..d1ff879 100644
> --- a/drivers/gpio/gpio-mpc8xxx.c
> +++ b/drivers/gpio/gpio-mpc8xxx.c
> @@ -105,6 +105,32 @@ static void mpc8xxx_gpio_set(struct gpio_chip *gc,
> unsigned int gpio, int val)
> spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> }
>
> +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;
> +
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> +
> + for (i = 0; i < gc->ngpio; i++) {
> + if (*mask == 0)
> + break;
Ok, so this works because presentely you can only have 32 GPIOs max on
this chip. But you cannot be sure that future revisions won't extend
that number ; and if this happens this function won't work as-is
anymore. I won't take much more code to make it more generic, so
please do it now to avoid hours of horrendous debugging to your future
self.
> + 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);
> +
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> +}
> +
> 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);
> @@ -344,6 +370,7 @@ static void __init mpc8xxx_add_controller(struct
> device_node *np)
> gc->get = of_device_is_compatible(np, "fsl,mpc8572-gpio") ?
> mpc8572_gpio_get : mpc8xxx_gpio_get;
> gc->set = mpc8xxx_gpio_set;
> + gc->set_multiple = mpc8xxx_gpio_set_multiple;
> gc->to_irq = mpc8xxx_gpio_to_irq;
>
> ret = of_mm_gpiochip_add(np, mm_gc);
>
> --
> 1.8.5.5
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html