Skip to content

Commit 35d13d9

Browse files
andy-shevtorvalds
authored andcommitted
gpio: pca953x: convert to use bitmap API
Instead of customized approach convert the driver to use bitmap API. [[email protected]: reduce stack usage in couple of functions] Link: http://lkml.kernel.org/r/[email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Andy Shevchenko <[email protected]> Acked-by: Linus Walleij <[email protected]> Cc: William Breathitt Gray <[email protected]> Cc: Thomas Petazzoni <[email protected]> Cc: Marek Vasut <[email protected]> Cc: Bartosz Golaszewski <[email protected]> Cc: Geert Uytterhoeven <[email protected]> Cc: Rasmus Villemoes <[email protected]> Cc: Yury Norov <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 0a0a021 commit 35d13d9

File tree

1 file changed

+70
-94
lines changed

1 file changed

+70
-94
lines changed

drivers/gpio/gpio-pca953x.c

Lines changed: 70 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
*/
1010

1111
#include <linux/acpi.h>
12-
#include <linux/bits.h>
13-
#include <linux/bitops.h>
12+
#include <linux/bitmap.h>
1413
#include <linux/gpio/driver.h>
1514
#include <linux/gpio/consumer.h>
1615
#include <linux/i2c.h>
@@ -116,6 +115,7 @@ MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
116115

117116
#define MAX_BANK 5
118117
#define BANK_SZ 8
118+
#define MAX_LINE (MAX_BANK * BANK_SZ)
119119

120120
#define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ)
121121

@@ -147,10 +147,10 @@ struct pca953x_chip {
147147

148148
#ifdef CONFIG_GPIO_PCA953X_IRQ
149149
struct mutex irq_lock;
150-
u8 irq_mask[MAX_BANK];
151-
u8 irq_stat[MAX_BANK];
152-
u8 irq_trig_raise[MAX_BANK];
153-
u8 irq_trig_fall[MAX_BANK];
150+
DECLARE_BITMAP(irq_mask, MAX_LINE);
151+
DECLARE_BITMAP(irq_stat, MAX_LINE);
152+
DECLARE_BITMAP(irq_trig_raise, MAX_LINE);
153+
DECLARE_BITMAP(irq_trig_fall, MAX_LINE);
154154
struct irq_chip irq_chip;
155155
#endif
156156
atomic_t wakeup_path;
@@ -334,12 +334,16 @@ static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off,
334334
return regaddr;
335335
}
336336

337-
static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val)
337+
static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long *val)
338338
{
339339
u8 regaddr = pca953x_recalc_addr(chip, reg, 0, true, true);
340-
int ret;
340+
u8 value[MAX_BANK];
341+
int i, ret;
342+
343+
for (i = 0; i < NBANK(chip); i++)
344+
value[i] = bitmap_get_value8(val, i * BANK_SZ);
341345

342-
ret = regmap_bulk_write(chip->regmap, regaddr, val, NBANK(chip));
346+
ret = regmap_bulk_write(chip->regmap, regaddr, value, NBANK(chip));
343347
if (ret < 0) {
344348
dev_err(&chip->client->dev, "failed writing register\n");
345349
return ret;
@@ -348,17 +352,21 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val)
348352
return 0;
349353
}
350354

351-
static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val)
355+
static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long *val)
352356
{
353357
u8 regaddr = pca953x_recalc_addr(chip, reg, 0, false, true);
354-
int ret;
358+
u8 value[MAX_BANK];
359+
int i, ret;
355360

356-
ret = regmap_bulk_read(chip->regmap, regaddr, val, NBANK(chip));
361+
ret = regmap_bulk_read(chip->regmap, regaddr, value, NBANK(chip));
357362
if (ret < 0) {
358363
dev_err(&chip->client->dev, "failed reading register\n");
359364
return ret;
360365
}
361366

367+
for (i = 0; i < NBANK(chip); i++)
368+
bitmap_set_value8(val, value[i], i * BANK_SZ);
369+
362370
return 0;
363371
}
364372

@@ -460,22 +468,15 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
460468
unsigned long *mask, unsigned long *bits)
461469
{
462470
struct pca953x_chip *chip = gpiochip_get_data(gc);
463-
unsigned long offset;
464-
unsigned long bank_mask;
465-
int bank;
466-
u8 reg_val[MAX_BANK];
471+
DECLARE_BITMAP(reg_val, MAX_LINE);
467472
int ret;
468473

469474
mutex_lock(&chip->i2c_lock);
470475
ret = pca953x_read_regs(chip, chip->regs->output, reg_val);
471476
if (ret)
472477
goto exit;
473478

474-
for_each_set_clump8(offset, bank_mask, mask, gc->ngpio) {
475-
bank = offset / 8;
476-
reg_val[bank] &= ~bank_mask;
477-
reg_val[bank] |= bitmap_get_value8(bits, offset) & bank_mask;
478-
}
479+
bitmap_replace(reg_val, reg_val, bits, mask, gc->ngpio);
479480

480481
pca953x_write_regs(chip, chip->regs->output, reg_val);
481482
exit:
@@ -602,36 +603,28 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
602603
{
603604
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
604605
struct pca953x_chip *chip = gpiochip_get_data(gc);
605-
u8 new_irqs;
606-
int level, i;
607-
u8 invert_irq_mask[MAX_BANK];
608-
u8 reg_direction[MAX_BANK];
606+
DECLARE_BITMAP(irq_mask, MAX_LINE);
607+
DECLARE_BITMAP(reg_direction, MAX_LINE);
608+
int level;
609609

610610
pca953x_read_regs(chip, chip->regs->direction, reg_direction);
611611

612612
if (chip->driver_data & PCA_PCAL) {
613613
/* Enable latch on interrupt-enabled inputs */
614614
pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask);
615615

616-
for (i = 0; i < NBANK(chip); i++)
617-
invert_irq_mask[i] = ~chip->irq_mask[i];
616+
bitmap_complement(irq_mask, chip->irq_mask, gc->ngpio);
618617

619618
/* Unmask enabled interrupts */
620-
pca953x_write_regs(chip, PCAL953X_INT_MASK, invert_irq_mask);
619+
pca953x_write_regs(chip, PCAL953X_INT_MASK, irq_mask);
621620
}
622621

622+
bitmap_or(irq_mask, chip->irq_trig_fall, chip->irq_trig_raise, gc->ngpio);
623+
bitmap_and(irq_mask, irq_mask, reg_direction, gc->ngpio);
624+
623625
/* Look for any newly setup interrupt */
624-
for (i = 0; i < NBANK(chip); i++) {
625-
new_irqs = chip->irq_trig_fall[i] | chip->irq_trig_raise[i];
626-
new_irqs &= reg_direction[i];
627-
628-
while (new_irqs) {
629-
level = __ffs(new_irqs);
630-
pca953x_gpio_direction_input(&chip->gpio_chip,
631-
level + (BANK_SZ * i));
632-
new_irqs &= ~(1 << level);
633-
}
634-
}
626+
for_each_set_bit(level, irq_mask, gc->ngpio)
627+
pca953x_gpio_direction_input(&chip->gpio_chip, level);
635628

636629
mutex_unlock(&chip->irq_lock);
637630
}
@@ -672,15 +665,15 @@ static void pca953x_irq_shutdown(struct irq_data *d)
672665
chip->irq_trig_fall[d->hwirq / BANK_SZ] &= ~mask;
673666
}
674667

675-
static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
668+
static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pending)
676669
{
677-
u8 cur_stat[MAX_BANK];
678-
u8 old_stat[MAX_BANK];
679-
bool pending_seen = false;
680-
bool trigger_seen = false;
681-
u8 trigger[MAX_BANK];
682-
u8 reg_direction[MAX_BANK];
683-
int ret, i;
670+
struct gpio_chip *gc = &chip->gpio_chip;
671+
DECLARE_BITMAP(reg_direction, MAX_LINE);
672+
DECLARE_BITMAP(old_stat, MAX_LINE);
673+
DECLARE_BITMAP(cur_stat, MAX_LINE);
674+
DECLARE_BITMAP(new_stat, MAX_LINE);
675+
DECLARE_BITMAP(trigger, MAX_LINE);
676+
int ret;
684677

685678
if (chip->driver_data & PCA_PCAL) {
686679
/* Read the current interrupt status from the device */
@@ -693,16 +686,12 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
693686
if (ret)
694687
return false;
695688

696-
for (i = 0; i < NBANK(chip); i++) {
697-
/* Apply filter for rising/falling edge selection */
698-
pending[i] = (~cur_stat[i] & chip->irq_trig_fall[i]) |
699-
(cur_stat[i] & chip->irq_trig_raise[i]);
700-
pending[i] &= trigger[i];
701-
if (pending[i])
702-
pending_seen = true;
703-
}
689+
/* Apply filter for rising/falling edge selection */
690+
bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise, cur_stat, gc->ngpio);
691+
692+
bitmap_and(pending, new_stat, trigger, gc->ngpio);
704693

705-
return pending_seen;
694+
return !bitmap_empty(pending, gc->ngpio);
706695
}
707696

708697
ret = pca953x_read_regs(chip, chip->regs->input, cur_stat);
@@ -711,51 +700,38 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
711700

712701
/* Remove output pins from the equation */
713702
pca953x_read_regs(chip, chip->regs->direction, reg_direction);
714-
for (i = 0; i < NBANK(chip); i++)
715-
cur_stat[i] &= reg_direction[i];
716703

717-
memcpy(old_stat, chip->irq_stat, NBANK(chip));
704+
bitmap_copy(old_stat, chip->irq_stat, gc->ngpio);
718705

719-
for (i = 0; i < NBANK(chip); i++) {
720-
trigger[i] = (cur_stat[i] ^ old_stat[i]) & chip->irq_mask[i];
721-
if (trigger[i])
722-
trigger_seen = true;
723-
}
706+
bitmap_and(new_stat, cur_stat, reg_direction, gc->ngpio);
707+
bitmap_xor(cur_stat, new_stat, old_stat, gc->ngpio);
708+
bitmap_and(trigger, cur_stat, chip->irq_mask, gc->ngpio);
724709

725-
if (!trigger_seen)
710+
if (bitmap_empty(trigger, gc->ngpio))
726711
return false;
727712

728-
memcpy(chip->irq_stat, cur_stat, NBANK(chip));
713+
bitmap_copy(chip->irq_stat, new_stat, gc->ngpio);
729714

730-
for (i = 0; i < NBANK(chip); i++) {
731-
pending[i] = (old_stat[i] & chip->irq_trig_fall[i]) |
732-
(cur_stat[i] & chip->irq_trig_raise[i]);
733-
pending[i] &= trigger[i];
734-
if (pending[i])
735-
pending_seen = true;
736-
}
715+
bitmap_and(cur_stat, chip->irq_trig_fall, old_stat, gc->ngpio);
716+
bitmap_and(old_stat, chip->irq_trig_raise, new_stat, gc->ngpio);
717+
bitmap_or(new_stat, old_stat, cur_stat, gc->ngpio);
718+
bitmap_and(pending, new_stat, trigger, gc->ngpio);
737719

738-
return pending_seen;
720+
return !bitmap_empty(pending, gc->ngpio);
739721
}
740722

741723
static irqreturn_t pca953x_irq_handler(int irq, void *devid)
742724
{
743725
struct pca953x_chip *chip = devid;
744-
u8 pending[MAX_BANK];
745-
u8 level;
746-
int i;
726+
struct gpio_chip *gc = &chip->gpio_chip;
727+
DECLARE_BITMAP(pending, MAX_LINE);
728+
int level;
747729

748730
if (!pca953x_irq_pending(chip, pending))
749731
return IRQ_NONE;
750732

751-
for (i = 0; i < NBANK(chip); i++) {
752-
while (pending[i]) {
753-
level = __ffs(pending[i]);
754-
handle_nested_irq(irq_find_mapping(chip->gpio_chip.irq.domain,
755-
level + (BANK_SZ * i)));
756-
pending[i] &= ~(1 << level);
757-
}
758-
}
733+
for_each_set_bit(level, pending, gc->ngpio)
734+
handle_nested_irq(irq_find_mapping(gc->irq.domain, level));
759735

760736
return IRQ_HANDLED;
761737
}
@@ -765,8 +741,9 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
765741
{
766742
struct i2c_client *client = chip->client;
767743
struct irq_chip *irq_chip = &chip->irq_chip;
768-
u8 reg_direction[MAX_BANK];
769-
int ret, i;
744+
DECLARE_BITMAP(reg_direction, MAX_LINE);
745+
DECLARE_BITMAP(irq_stat, MAX_LINE);
746+
int ret;
770747

771748
if (!client->irq)
772749
return 0;
@@ -777,7 +754,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
777754
if (!(chip->driver_data & PCA_INT))
778755
return 0;
779756

780-
ret = pca953x_read_regs(chip, chip->regs->input, chip->irq_stat);
757+
ret = pca953x_read_regs(chip, chip->regs->input, irq_stat);
781758
if (ret)
782759
return ret;
783760

@@ -787,8 +764,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
787764
* this purpose.
788765
*/
789766
pca953x_read_regs(chip, chip->regs->direction, reg_direction);
790-
for (i = 0; i < NBANK(chip); i++)
791-
chip->irq_stat[i] &= reg_direction[i];
767+
bitmap_and(chip->irq_stat, irq_stat, reg_direction, chip->gpio_chip.ngpio);
792768
mutex_init(&chip->irq_lock);
793769

794770
ret = devm_request_threaded_irq(&client->dev, client->irq,
@@ -840,8 +816,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
840816

841817
static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
842818
{
819+
DECLARE_BITMAP(val, MAX_LINE);
843820
int ret;
844-
u8 val[MAX_BANK];
845821

846822
ret = regcache_sync_region(chip->regmap, chip->regs->output,
847823
chip->regs->output + NBANK(chip));
@@ -855,9 +831,9 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
855831

856832
/* set platform specific polarity inversion */
857833
if (invert)
858-
memset(val, 0xFF, NBANK(chip));
834+
bitmap_fill(val, MAX_LINE);
859835
else
860-
memset(val, 0, NBANK(chip));
836+
bitmap_zero(val, MAX_LINE);
861837

862838
ret = pca953x_write_regs(chip, chip->regs->invert, val);
863839
out:
@@ -866,8 +842,8 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
866842

867843
static int device_pca957x_init(struct pca953x_chip *chip, u32 invert)
868844
{
845+
DECLARE_BITMAP(val, MAX_LINE);
869846
int ret;
870-
u8 val[MAX_BANK];
871847

872848
ret = device_pca95xx_init(chip, invert);
873849
if (ret)

0 commit comments

Comments
 (0)