aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-mpc8xxx.c
diff options
context:
space:
mode:
authorRojhalat Ibrahim <imr@rtschenk.de>2014-11-04 11:12:09 -0500
committerLinus Walleij <linus.walleij@linaro.org>2014-11-27 09:01:18 -0500
commite5db3b338aae35fbdd8b33cef6e2510f42ea4640 (patch)
tree025dabed161e36892e1eaffff199cdbf83bc6de4 /drivers/gpio/gpio-mpc8xxx.c
parent5f42424354f5b0ca5413b4fb8528d150692c85b7 (diff)
gpio-mpc8xxx: add mpc8xxx_gpio_set_multiple function
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. Change log: v6: - rebase on current linux-gpio devel branch v5: - no change 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) Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-mpc8xxx.c')
-rw-r--r--drivers/gpio/gpio-mpc8xxx.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index d7d6d72eba33..d1ff879e6ff2 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)
105 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 105 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
106} 106}
107 107
108static void mpc8xxx_gpio_set_multiple(struct gpio_chip *gc,
109 unsigned long *mask, unsigned long *bits)
110{
111 struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
112 struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
113 unsigned long flags;
114 int i;
115
116 spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
117
118 for (i = 0; i < gc->ngpio; i++) {
119 if (*mask == 0)
120 break;
121 if (__test_and_clear_bit(i, mask)) {
122 if (test_bit(i, bits))
123 mpc8xxx_gc->data |= mpc8xxx_gpio2mask(i);
124 else
125 mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(i);
126 }
127 }
128
129 out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
130
131 spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
132}
133
108static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 134static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
109{ 135{
110 struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); 136 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)
344 gc->get = of_device_is_compatible(np, "fsl,mpc8572-gpio") ? 370 gc->get = of_device_is_compatible(np, "fsl,mpc8572-gpio") ?
345 mpc8572_gpio_get : mpc8xxx_gpio_get; 371 mpc8572_gpio_get : mpc8xxx_gpio_get;
346 gc->set = mpc8xxx_gpio_set; 372 gc->set = mpc8xxx_gpio_set;
373 gc->set_multiple = mpc8xxx_gpio_set_multiple;
347 gc->to_irq = mpc8xxx_gpio_to_irq; 374 gc->to_irq = mpc8xxx_gpio_to_irq;
348 375
349 ret = of_mm_gpiochip_add(np, mm_gc); 376 ret = of_mm_gpiochip_add(np, mm_gc);