summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>2023-03-22 19:46:14 +0300
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>2023-03-22 19:46:14 +0300
commitae5ae35467d5c04e5453218a927d86a5e9a78340 (patch)
treef8b81187575e694202b4749342c68c6e8a67ad9e
parenta7400a48160dc6a00ff93c40ba25d04a8e49f1f4 (diff)
parent4d60cac951fd2dfbf261b83abb805748abc8b995 (diff)
downloadlinux-ae5ae35467d5c04e5453218a927d86a5e9a78340.tar.xz
Merge tag 'regmap-no-status' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap into gpio/for-next
regmap: Add no_status support This patch adds support for devices which don't support readback of individual interrupt statuses, we report all interrupts as firing and hope the consumers do the right thing.
-rw-r--r--drivers/base/regmap/regmap-irq.c22
-rw-r--r--include/linux/regmap.h2
2 files changed, 17 insertions, 7 deletions
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 8c903b8c9714..f4d544ee7c30 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -433,7 +433,10 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
* possible in order to reduce the I/O overheads.
*/
- if (chip->num_main_regs) {
+ if (chip->no_status) {
+ /* no status register so default to all active */
+ memset32(data->status_buf, GENMASK(31, 0), chip->num_regs);
+ } else if (chip->num_main_regs) {
unsigned int max_main_bits;
unsigned long size;
@@ -949,12 +952,17 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
continue;
/* Ack masked but set interrupts */
- reg = d->get_irq_reg(d, d->chip->status_base, i);
- ret = regmap_read(map, reg, &d->status_buf[i]);
- if (ret != 0) {
- dev_err(map->dev, "Failed to read IRQ status: %d\n",
- ret);
- goto err_alloc;
+ if (d->chip->no_status) {
+ /* no status register so default to all active */
+ d->status_buf[i] = GENMASK(31, 0);
+ } else {
+ reg = d->get_irq_reg(d, d->chip->status_base, i);
+ ret = regmap_read(map, reg, &d->status_buf[i]);
+ if (ret != 0) {
+ dev_err(map->dev, "Failed to read IRQ status: %d\n",
+ ret);
+ goto err_alloc;
+ }
}
if (chip->status_invert)
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 4d10790adeb0..301286149643 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -1567,6 +1567,7 @@ struct regmap_irq_chip_data;
* the need for a @sub_reg_offsets table.
* @status_invert: Inverted status register: cleared bits are active interrupts.
* @runtime_pm: Hold a runtime PM lock on the device when accessing it.
+ * @no_status: No status register: all interrupts assumed generated by device.
*
* @num_regs: Number of registers in each control bank.
* @irqs: Descriptors for individual IRQs. Interrupt numbers are
@@ -1631,6 +1632,7 @@ struct regmap_irq_chip {
unsigned int clear_on_unmask:1;
unsigned int not_fixed_stride:1;
unsigned int status_invert:1;
+ unsigned int no_status:1;
int num_regs;