diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-05 09:46:26 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-05 09:46:26 -0800 |
commit | 5ecc9d15f73b82c748526350d5602c94fdd65cac (patch) | |
tree | 686ae55a0de4be8bad9e2248b019e459525cb109 /drivers | |
parent | 2f13437b8917627119d163d62f73e7a78a92303a (diff) | |
parent | f949286c668aed5aa24acdb5838be9cfd9513bd3 (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton:
"Most of the rest of MM and various other things. Some Kconfig rework
still awaits merges of dependent trees from linux-next.
Subsystems affected by this patch series: mm/hotfixes, mm/memcg,
mm/vmstat, mm/thp, procfs, sysctl, misc, notifiers, core-kernel,
bitops, lib, checkpatch, epoll, binfmt, init, rapidio, uaccess, kcov,
ubsan, ipc, bitmap, mm/pagemap"
* akpm: (86 commits)
mm: remove __ARCH_HAS_4LEVEL_HACK and include/asm-generic/4level-fixup.h
um: add support for folded p4d page tables
um: remove unused pxx_offset_proc() and addr_pte() functions
sparc32: use pgtable-nopud instead of 4level-fixup
parisc/hugetlb: use pgtable-nopXd instead of 4level-fixup
parisc: use pgtable-nopXd instead of 4level-fixup
nds32: use pgtable-nopmd instead of 4level-fixup
microblaze: use pgtable-nopmd instead of 4level-fixup
m68k: mm: use pgtable-nopXd instead of 4level-fixup
m68k: nommu: use pgtable-nopud instead of 4level-fixup
c6x: use pgtable-nopud instead of 4level-fixup
arm: nommu: use pgtable-nopud instead of 4level-fixup
alpha: use pgtable-nopud instead of 4level-fixup
gpio: pca953x: tighten up indentation
gpio: pca953x: convert to use bitmap API
gpio: pca953x: use input from regs structure in pca953x_irq_pending()
gpio: pca953x: remove redundant variable and check in IRQ handler
lib/bitmap: introduce bitmap_replace() helper
lib/test_bitmap: fix comment about this file
lib/test_bitmap: move exp1 and exp2 upper for others to use
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/auxdisplay/charlcd.c | 34 | ||||
-rw-r--r-- | drivers/base/node.c | 9 | ||||
-rw-r--r-- | drivers/gpio/gpio-104-dio-48e.c | 73 | ||||
-rw-r--r-- | drivers/gpio/gpio-104-idi-48.c | 36 | ||||
-rw-r--r-- | drivers/gpio/gpio-74x164.c | 19 | ||||
-rw-r--r-- | drivers/gpio/gpio-gpio-mm.c | 73 | ||||
-rw-r--r-- | drivers/gpio/gpio-max3191x.c | 19 | ||||
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 195 | ||||
-rw-r--r-- | drivers/gpio/gpio-pci-idio-16.c | 75 | ||||
-rw-r--r-- | drivers/gpio/gpio-pcie-idio-24.c | 109 | ||||
-rw-r--r-- | drivers/gpio/gpio-pisosr.c | 12 | ||||
-rw-r--r-- | drivers/gpio/gpio-uniphier.c | 13 | ||||
-rw-r--r-- | drivers/gpio/gpio-ws16c48.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_property.c | 2 | ||||
-rw-r--r-- | drivers/misc/sram-exec.c | 2 | ||||
-rw-r--r-- | drivers/rapidio/rio-access.c | 2 | ||||
-rw-r--r-- | drivers/rapidio/rio-driver.c | 1 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_soc_dts_iosf.c | 31 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_soc_dts_iosf.h | 2 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 5 | ||||
-rw-r--r-- | drivers/vhost/vhost.c | 6 | ||||
-rw-r--r-- | drivers/vhost/vhost.h | 1 |
22 files changed, 292 insertions, 500 deletions
diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c index bef6b85778b6..874c259a8829 100644 --- a/drivers/auxdisplay/charlcd.c +++ b/drivers/auxdisplay/charlcd.c @@ -288,31 +288,6 @@ static int charlcd_init_display(struct charlcd *lcd) } /* - * Parses an unsigned integer from a string, until a non-digit character - * is found. The empty string is not accepted. No overflow checks are done. - * - * Returns whether the parsing was successful. Only in that case - * the output parameters are written to. - * - * TODO: If the kernel adds an inplace version of kstrtoul(), this function - * could be easily replaced by that. - */ -static bool parse_n(const char *s, unsigned long *res, const char **next_s) -{ - if (!isdigit(*s)) - return false; - - *res = 0; - while (isdigit(*s)) { - *res = *res * 10 + (*s - '0'); - ++s; - } - - *next_s = s; - return true; -} - -/* * Parses a movement command of the form "(.*);", where the group can be * any number of subcommands of the form "(x|y)[0-9]+". * @@ -336,6 +311,7 @@ static bool parse_xy(const char *s, unsigned long *x, unsigned long *y) { unsigned long new_x = *x; unsigned long new_y = *y; + char *p; for (;;) { if (!*s) @@ -345,11 +321,15 @@ static bool parse_xy(const char *s, unsigned long *x, unsigned long *y) break; if (*s == 'x') { - if (!parse_n(s + 1, &new_x, &s)) + new_x = simple_strtoul(s + 1, &p, 10); + if (p == s + 1) return false; + s = p; } else if (*s == 'y') { - if (!parse_n(s + 1, &new_y, &s)) + new_y = simple_strtoul(s + 1, &p, 10); + if (p == s + 1) return false; + s = p; } else { return false; } diff --git a/drivers/base/node.c b/drivers/base/node.c index 296546ffed6c..98a31bafc8a2 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -496,20 +496,17 @@ static ssize_t node_read_vmstat(struct device *dev, int n = 0; for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) - n += sprintf(buf+n, "%s %lu\n", vmstat_text[i], + n += sprintf(buf+n, "%s %lu\n", zone_stat_name(i), sum_zone_node_page_state(nid, i)); #ifdef CONFIG_NUMA for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) - n += sprintf(buf+n, "%s %lu\n", - vmstat_text[i + NR_VM_ZONE_STAT_ITEMS], + n += sprintf(buf+n, "%s %lu\n", numa_stat_name(i), sum_zone_numa_state(nid, i)); #endif for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) - n += sprintf(buf+n, "%s %lu\n", - vmstat_text[i + NR_VM_ZONE_STAT_ITEMS + - NR_VM_NUMA_STAT_ITEMS], + n += sprintf(buf+n, "%s %lu\n", node_stat_name(i), node_page_state(pgdat, i)); return n; diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c index 400c09b905f8..1f7d9bbec0fc 100644 --- a/drivers/gpio/gpio-104-dio-48e.c +++ b/drivers/gpio/gpio-104-dio-48e.c @@ -178,46 +178,25 @@ static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset) return !!(port_state & mask); } +static const size_t ports[] = { 0, 1, 2, 4, 5, 6 }; + static int dio48e_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits) { struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); - size_t i; - static const size_t ports[] = { 0, 1, 2, 4, 5, 6 }; - const unsigned int gpio_reg_size = 8; - unsigned int bits_offset; - size_t word_index; - unsigned int word_offset; - unsigned long word_mask; - const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); + unsigned long offset; + unsigned long gpio_mask; + unsigned int port_addr; unsigned long port_state; /* clear bits array to a clean slate */ bitmap_zero(bits, chip->ngpio); - /* get bits are evaluated a gpio port register at a time */ - for (i = 0; i < ARRAY_SIZE(ports); i++) { - /* gpio offset in bits array */ - bits_offset = i * gpio_reg_size; - - /* word index for bits array */ - word_index = BIT_WORD(bits_offset); - - /* gpio offset within current word of bits array */ - word_offset = bits_offset % BITS_PER_LONG; - - /* mask of get bits for current gpio within current word */ - word_mask = mask[word_index] & (port_mask << word_offset); - if (!word_mask) { - /* no get bits in this port so skip to next one */ - continue; - } - - /* read bits from current gpio port */ - port_state = inb(dio48egpio->base + ports[i]); + for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { + port_addr = dio48egpio->base + ports[offset / 8]; + port_state = inb(port_addr) & gpio_mask; - /* store acquired bits at respective bits array offset */ - bits[word_index] |= (port_state << word_offset) & word_mask; + bitmap_set_value8(bits, port_state, offset); } return 0; @@ -247,37 +226,27 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits) { struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); - unsigned int i; - const unsigned int gpio_reg_size = 8; - unsigned int port; - unsigned int out_port; - unsigned int bitmask; + unsigned long offset; + unsigned long gpio_mask; + size_t index; + unsigned int port_addr; + unsigned long bitmask; unsigned long flags; - /* set bits are evaluated a gpio register size at a time */ - for (i = 0; i < chip->ngpio; i += gpio_reg_size) { - /* no more set bits in this mask word; skip to the next word */ - if (!mask[BIT_WORD(i)]) { - i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size; - continue; - } + for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { + index = offset / 8; + port_addr = dio48egpio->base + ports[index]; - port = i / gpio_reg_size; - out_port = (port > 2) ? port + 1 : port; - bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)]; + bitmask = bitmap_get_value8(bits, offset) & gpio_mask; raw_spin_lock_irqsave(&dio48egpio->lock, flags); /* update output state data and set device gpio register */ - dio48egpio->out_state[port] &= ~mask[BIT_WORD(i)]; - dio48egpio->out_state[port] |= bitmask; - outb(dio48egpio->out_state[port], dio48egpio->base + out_port); + dio48egpio->out_state[index] &= ~gpio_mask; + dio48egpio->out_state[index] |= bitmask; + outb(dio48egpio->out_state[index], port_addr); raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); - - /* prepare for next gpio register set */ - mask[BIT_WORD(i)] >>= gpio_reg_size; - bits[BIT_WORD(i)] >>= gpio_reg_size; } } diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c index c50329ab493a..d350ac0de06b 100644 --- a/drivers/gpio/gpio-104-idi-48.c +++ b/drivers/gpio/gpio-104-idi-48.c @@ -85,42 +85,20 @@ static int idi_48_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits) { struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip); - size_t i; + unsigned long offset; + unsigned long gpio_mask; static const size_t ports[] = { 0, 1, 2, 4, 5, 6 }; - const unsigned int gpio_reg_size = 8; - unsigned int bits_offset; - size_t word_index; - unsigned int word_offset; - unsigned long word_mask; - const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); + unsigned int port_addr; unsigned long port_state; /* clear bits array to a clean slate */ bitmap_zero(bits, chip->ngpio); - /* get bits are evaluated a gpio port register at a time */ - for (i = 0; i < ARRAY_SIZE(ports); i++) { - /* gpio offset in bits array */ - bits_offset = i * gpio_reg_size; + for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { + port_addr = idi48gpio->base + ports[offset / 8]; + port_state = inb(port_addr) & gpio_mask; - /* word index for bits array */ - word_index = BIT_WORD(bits_offset); - - /* gpio offset within current word of bits array */ - word_offset = bits_offset % BITS_PER_LONG; - - /* mask of get bits for current gpio within current word */ - word_mask = mask[word_index] & (port_mask << word_offset); - if (!word_mask) { - /* no get bits in this port so skip to next one */ - continue; - } - - /* read bits from current gpio port */ - port_state = inb(idi48gpio->base + ports[i]); - - /* store acquired bits at respective bits array offset */ - bits[word_index] |= (port_state << word_offset) & word_mask; + bitmap_set_value8(bits, port_state, offset); } return 0; diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index e81307f9754e..05637d585152 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c @@ -6,6 +6,7 @@ * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> */ +#include <linux/bitops.h> #include <linux/gpio/consumer.h> #include <linux/gpio/driver.h> #include <linux/module.h> @@ -72,20 +73,18 @@ static void gen_74x164_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { struct gen_74x164_chip *chip = gpiochip_get_data(gc); - unsigned int i, idx, shift; - u8 bank, bankmask; + unsigned long offset; + unsigned long bankmask; + size_t bank; + unsigned long bitmask; mutex_lock(&chip->lock); - for (i = 0, bank = chip->registers - 1; i < chip->registers; - i++, bank--) { - idx = i / sizeof(*mask); - shift = i % sizeof(*mask) * BITS_PER_BYTE; - bankmask = mask[idx] >> shift; - if (!bankmask) - continue; + for_each_set_clump8(offset, bankmask, mask, chip->registers * 8) { + bank = chip->registers - 1 - offset / 8; + bitmask = bitmap_get_value8(bits, offset) & bankmask; chip->buffer[bank] &= ~bankmask; - chip->buffer[bank] |= bankmask & (bits[idx] >> shift); + chip->buffer[bank] |= bitmask; } __gen_74x164_write_config(chip); mutex_unlock(&chip->lock); diff --git a/drivers/gpio/gpio-gpio-mm.c b/drivers/gpio/gpio-gpio-mm.c index c22d6f94129c..b89b8c5ff1f5 100644 --- a/drivers/gpio/gpio-gpio-mm.c +++ b/drivers/gpio/gpio-gpio-mm.c @@ -167,46 +167,25 @@ static int gpiomm_gpio_get(struct gpio_chip *chip, unsigned int offset) return !!(port_state & mask); } +static const size_t ports[] = { 0, 1, 2, 4, 5, 6 }; + static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits) { struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip); - size_t i; - static const size_t ports[] = { 0, 1, 2, 4, 5, 6 }; - const unsigned int gpio_reg_size = 8; - unsigned int bits_offset; - size_t word_index; - unsigned int word_offset; - unsigned long word_mask; - const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); + unsigned long offset; + unsigned long gpio_mask; + unsigned int port_addr; unsigned long port_state; /* clear bits array to a clean slate */ bitmap_zero(bits, chip->ngpio); - /* get bits are evaluated a gpio port register at a time */ - for (i = 0; i < ARRAY_SIZE(ports); i++) { - /* gpio offset in bits array */ - bits_offset = i * gpio_reg_size; - - /* word index for bits array */ - word_index = BIT_WORD(bits_offset); - - /* gpio offset within current word of bits array */ - word_offset = bits_offset % BITS_PER_LONG; - - /* mask of get bits for current gpio within current word */ - word_mask = mask[word_index] & (port_mask << word_offset); - if (!word_mask) { - /* no get bits in this port so skip to next one */ - continue; - } - - /* read bits from current gpio port */ - port_state = inb(gpiommgpio->base + ports[i]); + for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { + port_addr = gpiommgpio->base + ports[offset / 8]; + port_state = inb(port_addr) & gpio_mask; - /* store acquired bits at respective bits array offset */ - bits[word_index] |= (port_state << word_offset) & word_mask; + bitmap_set_value8(bits, port_state, offset); } return 0; @@ -237,37 +216,27 @@ static void gpiomm_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits) { struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip); - unsigned int i; - const unsigned int gpio_reg_size = 8; - unsigned int port; - unsigned int out_port; - unsigned int bitmask; + unsigned long offset; + unsigned long gpio_mask; + size_t index; + unsigned int port_addr; + unsigned long bitmask; unsigned long flags; - /* set bits are evaluated a gpio register size at a time */ - for (i = 0; i < chip->ngpio; i += gpio_reg_size) { - /* no more set bits in this mask word; skip to the next word */ - if (!mask[BIT_WORD(i)]) { - i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size; - continue; - } + for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { + index = offset / 8; + port_addr = gpiommgpio->base + ports[index]; - port = i / gpio_reg_size; - out_port = (port > 2) ? port + 1 : port; - bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)]; + bitmask = bitmap_get_value8(bits, offset) & gpio_mask; spin_lock_irqsave(&gpiommgpio->lock, flags); /* update output state data and set device gpio register */ - gpiommgpio->out_state[port] &= ~mask[BIT_WORD(i)]; - gpiommgpio->out_state[port] |= bitmask; - outb(gpiommgpio->out_state[port], gpiommgpio->base + out_port); + gpiommgpio->out_state[index] &= ~gpio_mask; + gpiommgpio->out_state[index] |= bitmask; + outb(gpiommgpio->out_state[index], port_addr); spin_unlock_irqrestore(&gpiommgpio->lock, flags); - - /* prepare for next gpio register set */ - mask[BIT_WORD(i)] >>= gpio_reg_size; - bits[BIT_WORD(i)] >>= gpio_reg_size; } } diff --git a/drivers/gpio/gpio-max3191x.c b/drivers/gpio/gpio-max3191x.c index 0696d5a21431..310d1a248cae 100644 --- a/drivers/gpio/gpio-max3191x.c +++ b/drivers/gpio/gpio-max3191x.c @@ -31,6 +31,7 @@ */ #include <linux/bitmap.h> +#include <linux/bitops.h> #include <linux/crc8.h> #include <linux/gpio/consumer.h> #include <linux/gpio/driver.h> @@ -232,16 +233,20 @@ static int max3191x_get_multiple(struct gpio_chip *gpio, unsigned long *mask, unsigned long *bits) { struct max3191x_chip *max3191x = gpiochip_get_data(gpio); - int ret, bit = 0, wordlen = max3191x_wordlen(max3191x); + const unsigned int wordlen = max3191x_wordlen(max3191x); + int ret; + unsigned long bit; + unsigned long gpio_mask; + unsigned long in; mutex_lock(&max3191x->lock); ret = max3191x_readout_locked(max3191x); if (ret) goto out_unlock; - while ((bit = find_next_bit(mask, gpio->ngpio, bit)) != gpio->ngpio) { + bitmap_zero(bits, gpio->ngpio); + for_each_set_clump8(bit, gpio_mask, mask, gpio->ngpio) { unsigned int chipnum = bit / MAX3191X_NGPIO; - unsigned long in, shift, index; if (max3191x_chip_is_faulting(max3191x, chipnum)) { ret = -EIO; @@ -249,12 +254,8 @@ static int max3191x_get_multiple(struct gpio_chip *gpio, unsigned long *mask, } in = ((u8 *)max3191x->xfer.rx_buf)[chipnum * wordlen]; - shift = round_down(bit % BITS_PER_LONG, MAX3191X_NGPIO); - index = bit / BITS_PER_LONG; - bits[index] &= ~(mask[index] & (0xff << shift)); - bits[index] |= mask[index] & (in << shift); /* copy bits */ - - bit = (chipnum + 1) * MAX3191X_NGPIO; /* go to next chip */ + in &= gpio_mask; + bitmap_set_value8(bits, in, bit); } out_unlock: diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 82122c3c688a..6652bee01966 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -9,7 +9,7 @@ */ #include <linux/acpi.h> -#include <linux/bits.h> +#include <linux/bitmap.h> #include <linux/gpio/driver.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> @@ -115,6 +115,7 @@ MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids); #define MAX_BANK 5 #define BANK_SZ 8 +#define MAX_LINE (MAX_BANK * BANK_SZ) #define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ) @@ -146,10 +147,10 @@ struct pca953x_chip { #ifdef CONFIG_GPIO_PCA953X_IRQ struct mutex irq_lock; - u8 irq_mask[MAX_BANK]; - u8 irq_stat[MAX_BANK]; - u8 irq_trig_raise[MAX_BANK]; - u8 irq_trig_fall[MAX_BANK]; + DECLARE_BITMAP(irq_mask, MAX_LINE); + DECLARE_BITMAP(irq_stat, MAX_LINE); + DECLARE_BITMAP(irq_trig_raise, MAX_LINE); + DECLARE_BITMAP(irq_trig_fall, MAX_LINE); struct irq_chip irq_chip; #endif atomic_t wakeup_path; @@ -333,12 +334,16 @@ static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off, return regaddr; } -static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val) +static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long *val) { u8 regaddr = pca953x_recalc_addr(chip, reg, 0, true, true); - int ret; + u8 value[MAX_BANK]; + int i, ret; + + for (i = 0; i < NBANK(chip); i++) + value[i] = bitmap_get_value8(val, i * BANK_SZ); - ret = regmap_bulk_write(chip->regmap, regaddr, val, NBANK(chip)); + ret = regmap_bulk_write(chip->regmap, regaddr, value, NBANK(chip)); if (ret < 0) { dev_err(&chip->client->dev, "failed writing register\n"); return ret; @@ -347,17 +352,21 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val) return 0; } -static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val) +static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long *val) { u8 regaddr = pca953x_recalc_addr(chip, reg, 0, false, true); - int ret; + u8 value[MAX_BANK]; + int i, ret; - ret = regmap_bulk_read(chip->regmap, regaddr, val, NBANK(chip)); + ret = regmap_bulk_read(chip->regmap, regaddr, value, NBANK(chip)); if (ret < 0) { dev_err(&chip->client->dev, "failed reading register\n"); return ret; } + for (i = 0; i < NBANK(chip); i++) + bitmap_set_value8(val, value[i], i * BANK_SZ); + return 0; } @@ -412,7 +421,9 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) ret = regmap_read(chip->regmap, inreg, ®_val); mutex_unlock(&chip->i2c_lock); if (ret < 0) { - /* NOTE: diagnostic already emitted; that's all we should + /* + * NOTE: + * diagnostic already emitted; that's all we should * do unless gpio_*_value_cansleep() calls become different * from their nonsleeping siblings (and report faults). */ @@ -459,9 +470,7 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { struct pca953x_chip *chip = gpiochip_get_data(gc); - unsigned int bank_mask, bank_val; - int bank; - u8 reg_val[MAX_BANK]; + DECLARE_BITMAP(reg_val, MAX_LINE); int ret; mutex_lock(&chip->i2c_lock); @@ -469,16 +478,7 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc, if (ret) goto exit; - for (bank = 0; bank < NBANK(chip); bank++) { - bank_mask = mask[bank / sizeof(*mask)] >> - ((bank % sizeof(*mask)) * 8); - if (bank_mask) { - bank_val = bits[bank / sizeof(*bits)] >> - ((bank % sizeof(*bits)) * 8); - bank_val &= bank_mask; - reg_val[bank] = (reg_val[bank] & ~bank_mask) | bank_val; - } - } + bitmap_replace(reg_val, reg_val, bits, mask, gc->ngpio); pca953x_write_regs(chip, chip->regs->output, reg_val); exit: @@ -605,10 +605,9 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 new_irqs; - int level, i; - u8 invert_irq_mask[MAX_BANK]; - u8 reg_direction[MAX_BANK]; + DECLARE_BITMAP(irq_mask, MAX_LINE); + DECLARE_BITMAP(reg_direction, MAX_LINE); + int level; pca953x_read_regs(chip, chip->regs->direction, reg_direction); @@ -616,25 +615,18 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) /* Enable latch on interrupt-enabled inputs */ pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask); - for (i = 0; i < NBANK(chip); i++) - invert_irq_mask[i] = ~chip->irq_mask[i]; + bitmap_complement(irq_mask, chip->irq_mask, gc->ngpio); /* Unmask enabled interrupts */ - pca953x_write_regs(chip, PCAL953X_INT_MASK, invert_irq_mask); + pca953x_write_regs(chip, PCAL953X_INT_MASK, irq_mask); } + bitmap_or(irq_mask, chip->irq_trig_fall, chip->irq_trig_raise, gc->ngpio); + bitmap_and(irq_mask, irq_mask, reg_direction, gc->ngpio); + /* Look for any newly setup interrupt */ - for (i = 0; i < NBANK(chip); i++) { - new_irqs = chip->irq_trig_fall[i] | chip->irq_trig_raise[i]; - new_irqs &= reg_direction[i]; - - while (new_irqs) { - level = __ffs(new_irqs); - pca953x_gpio_direction_input(&chip->gpio_chip, - level + (BANK_SZ * i)); - new_irqs &= ~(1 << level); - } - } + for_each_set_bit(level, irq_mask, gc->ngpio) + pca953x_gpio_direction_input(&chip->gpio_chip, level); mutex_unlock(&chip->irq_lock); } @@ -675,15 +667,15 @@ static void pca953x_irq_shutdown(struct irq_data *d) chip->irq_trig_fall[d->hwirq / BANK_SZ] &= ~mask; } -static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending) +static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pending) { - u8 cur_stat[MAX_BANK]; - u8 old_stat[MAX_BANK]; - bool pending_seen = false; - bool trigger_seen = false; - u8 trigger[MAX_BANK]; - u8 reg_direction[MAX_BANK]; - int ret, i; + struct gpio_chip *gc = &chip->gpio_chip; + DECLARE_BITMAP(reg_direction, MAX_LINE); + DECLARE_BITMAP(old_stat, MAX_LINE); + DECLARE_BITMAP(cur_stat, MAX_LINE); + DECLARE_BITMAP(new_stat, MAX_LINE); + DECLARE_BITMAP(trigger, MAX_LINE); + int ret; if (chip->driver_data & PCA_PCAL) { /* Read the current interrupt status from the device */ @@ -692,20 +684,16 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending) return false; /* Check latched inputs and clear interrupt status */ - ret = pca953x_read_regs(chip, PCA953X_INPUT, cur_stat); + ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); if (ret) return false; - for (i = 0; i < NBANK(chip); i++) { - /* Apply filter for rising/falling edge selection */ - pending[i] = (~cur_stat[i] & chip->irq_trig_fall[i]) | - (cur_stat[i] & chip->irq_trig_raise[i]); - pending[i] &= trigger[i]; - if (pending[i]) - pending_seen = true; - } + /* Apply filter for rising/falling edge selection */ + bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise, cur_stat, gc->ngpio); + + bitmap_and(pending, new_stat, trigger, gc->ngpio); - return pending_seen; + return !bitmap_empty(pending, gc->ngpio); } ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); @@ -714,64 +702,49 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending) /* Remove output pins from the equation */ pca953x_read_regs(chip, chip->regs->direction, reg_direction); - for (i = 0; i < NBANK(chip); i++) - cur_stat[i] &= reg_direction[i]; - memcpy(old_stat, chip->irq_stat, NBANK(chip)); + bitmap_copy(old_stat, chip->irq_stat, gc->ngpio); - for (i = 0; i < NBANK(chip); i++) { - trigger[i] = (cur_stat[i] ^ old_stat[i]) & chip->irq_mask[i]; - if (trigger[i]) - trigger_seen = true; - } + bitmap_and(new_stat, cur_stat, reg_direction, gc->ngpio); + bitmap_xor(cur_stat, new_stat, old_stat, gc->ngpio); + bitmap_and(trigger, cur_stat, chip->irq_mask, gc->ngpio); - if (!trigger_seen) + if (bitmap_empty(trigger, gc->ngpio)) return false; - memcpy(chip->irq_stat, cur_stat, NBANK(chip)); + bitmap_copy(chip->irq_stat, new_stat, gc->ngpio); - for (i = 0; i < NBANK(chip); i++) { - pending[i] = (old_stat[i] & chip->irq_trig_fall[i]) | - (cur_stat[i] & chip->irq_trig_raise[i]); - pending[i] &= trigger[i]; - if (pending[i]) - pending_seen = true; - } + bitmap_and(cur_stat, chip->irq_trig_fall, old_stat, gc->ngpio); + bitmap_and(old_stat, chip->irq_trig_raise, new_stat, gc->ngpio); + bitmap_or(new_stat, old_stat, cur_stat, gc->ngpio); + bitmap_and(pending, new_stat, trigger, gc->ngpio); - return pending_seen; + return !bitmap_empty(pending, gc->ngpio); } static irqreturn_t pca953x_irq_handler(int irq, void *devid) { struct pca953x_chip *chip = devid; - u8 pending[MAX_BANK]; - u8 level; - unsigned nhandled = 0; - int i; + struct gpio_chip *gc = &chip->gpio_chip; + DECLARE_BITMAP(pending, MAX_LINE); + int level; if (!pca953x_irq_pending(chip, pending)) return IRQ_NONE; - for (i = 0; i < NBANK(chip); i++) { - while (pending[i]) { - level = __ffs(pending[i]); - handle_nested_irq(irq_find_mapping(chip->gpio_chip.irq.domain, - level + (BANK_SZ * i))); - pending[i] &= ~(1 << level); - nhandled++; - } - } + for_each_set_bit(level, pending, gc->ngpio) + handle_nested_irq(irq_find_mapping(gc->irq.domain, level)); - return (nhandled > 0) ? IRQ_HANDLED : IRQ_NONE; + return IRQ_HANDLED; } -static int pca953x_irq_setup(struct pca953x_chip *chip, - int irq_base) +static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base) { struct i2c_client *client = chip->client; struct irq_chip *irq_chip = &chip->irq_chip; - u8 reg_direction[MAX_BANK]; - int ret, i; + DECLARE_BITMAP(reg_direction, MAX_LINE); + DECLARE_BITMAP(irq_stat, MAX_LINE); + int ret; if (!client->irq) return 0; @@ -782,7 +755,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, if (!(chip->driver_data & PCA_INT)) return 0; - ret = pca953x_read_regs(chip, chip->regs->input, chip->irq_stat); + ret = pca953x_read_regs(chip, chip->regs->input, irq_stat); if (ret) return ret; @@ -792,8 +765,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, * this purpose. */ pca953x_read_regs(chip, chip->regs->direction, reg_direction); - for (i = 0; i < NBANK(chip); i++) - chip->irq_stat[i] &= reg_direction[i]; + bitmap_and(chip->irq_stat, irq_stat, reg_direction, chip->gpio_chip.ngpio); mutex_init(&chip->irq_lock); ret = devm_request_threaded_irq(&client->dev, client->irq, @@ -816,9 +788,9 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, irq_chip->irq_set_type = pca953x_irq_set_type; irq_chip->irq_shutdown = pca953x_irq_shutdown; - ret = gpiochip_irqchip_add_nested(&chip->gpio_chip, irq_chip, - irq_base, handle_simple_irq, - IRQ_TYPE_NONE); + ret = gpiochip_irqchip_add_nested(&chip->gpio_chip, irq_chip, + irq_base, handle_simple_irq, + IRQ_TYPE_NONE); if (ret) { dev_err(&client->dev, "could not connect irqchip to gpiochip\n"); @@ -845,8 +817,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert) { + DECLARE_BITMAP(val, MAX_LINE); int ret; - u8 val[MAX_BANK]; ret = regcache_sync_region(chip->regmap, chip->regs->output, chip->regs->output + NBANK(chip)); @@ -860,9 +832,9 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert) /* set platform specific polarity inversion */ if (invert) - memset(val, 0xFF, NBANK(chip)); + bitmap_fill(val, MAX_LINE); else - memset(val, 0, NBANK(chip)); + bitmap_zero(val, MAX_LINE); ret = pca953x_write_regs(chip, chip->regs->invert, val); out: @@ -871,8 +843,8 @@ out: static int device_pca957x_init(struct pca953x_chip *chip, u32 invert) { + DECLARE_BITMAP(val, MAX_LINE); int ret; - u8 val[MAX_BANK]; ret = device_pca95xx_init(chip, invert); if (ret) @@ -892,7 +864,7 @@ out: static const struct of_device_id pca953x_dt_ids[]; static int pca953x_probe(struct i2c_client *client, - const struct i2c_device_id *i2c_id) |