From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751745AbdF1TYv (ORCPT ); Wed, 28 Jun 2017 15:24:51 -0400 Received: from mezzanine.sirena.org.uk ([106.187.55.193]:46858 "EHLO mezzanine.sirena.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751612AbdF1TYp (ORCPT ); Wed, 28 Jun 2017 15:24:45 -0400 From: Mark Brown To: Michael Grzeschik Cc: Mark Brown , broonie@kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, linux-kernel@vger.kernel.org In-Reply-To: <20170623123509.30442-1-m.grzeschik@pengutronix.de> Message-Id: Date: Wed, 28 Jun 2017 20:24:28 +0100 X-SA-Exim-Connect-IP: 176.12.107.140 X-SA-Exim-Mail-From: broonie@sirena.org.uk Subject: Applied "regmap: irq: add chip option mask_writeonly" to the regmap tree X-SA-Exim-Version: 4.2.1 (built Tue, 02 Aug 2016 21:08:31 +0000) X-SA-Exim-Scanned: No (on mezzanine.sirena.org.uk); Unknown failure Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The patch regmap: irq: add chip option mask_writeonly has been applied to the regmap tree at git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >>From a71411dbf6c82ba2eb2519717c04ffb19bc4dda5 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Fri, 23 Jun 2017 14:35:09 +0200 Subject: [PATCH] regmap: irq: add chip option mask_writeonly Some irq controllers have writeonly/multipurpose register layouts. In those cases we read invalid data back. Here we add the option mask_writeonly as masking option. Signed-off-by: Michael Grzeschik Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-irq.c | 40 +++++++++++++++++++++++++--------------- include/linux/regmap.h | 2 ++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index c4a1eadb093f..429ca8ed7e51 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -60,6 +60,16 @@ static void regmap_irq_lock(struct irq_data *data) mutex_lock(&d->lock); } +static int regmap_irq_update_bits(struct regmap_irq_chip_data *d, + unsigned int reg, unsigned int mask, + unsigned int val) +{ + if (d->chip->mask_writeonly) + return regmap_write_bits(d->map, reg, mask, val); + else + return regmap_update_bits(d->map, reg, mask, val); +} + static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); @@ -84,11 +94,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->mask_base + (i * map->reg_stride * d->irq_reg_stride); if (d->chip->mask_invert) { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); } else if (d->chip->unmask_base) { /* set mask with mask_base register */ - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); if (ret < 0) dev_err(d->map->dev, @@ -97,12 +107,12 @@ static void regmap_irq_sync_unlock(struct irq_data *data) unmask_offset = d->chip->unmask_base - d->chip->mask_base; /* clear mask with unmask_base register */ - ret = regmap_update_bits(d->map, + ret = regmap_irq_update_bits(d, reg + unmask_offset, d->mask_buf_def[i], d->mask_buf[i]); } else { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->mask_buf[i]); } if (ret != 0) @@ -113,11 +123,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data) (i * map->reg_stride * d->irq_reg_stride); if (d->wake_buf) { if (d->chip->wake_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->wake_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) @@ -153,10 +163,10 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->type_base + (i * map->reg_stride * d->type_reg_stride); if (d->chip->type_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], ~d->type_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], d->type_buf[i]); if (ret != 0) dev_err(d->map->dev, "Failed to sync type in %x\n", @@ -519,17 +529,17 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, reg = chip->mask_base + (i * map->reg_stride * d->irq_reg_stride); if (chip->mask_invert) - ret = regmap_update_bits(map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf[i], ~d->mask_buf[i]); else if (d->chip->unmask_base) { unmask_offset = d->chip->unmask_base - d->chip->mask_base; - ret = regmap_update_bits(d->map, + ret = regmap_irq_update_bits(d, reg + unmask_offset, d->mask_buf[i], d->mask_buf[i]); } else - ret = regmap_update_bits(map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf[i], d->mask_buf[i]); if (ret != 0) { dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", @@ -575,11 +585,11 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, (i * map->reg_stride * d->irq_reg_stride); if (chip->wake_invert) - ret = regmap_update_bits(map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], 0); else - ret = regmap_update_bits(map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) { @@ -603,10 +613,10 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, reg = chip->type_base + (i * map->reg_stride * d->type_reg_stride); if (chip->type_invert) - ret = regmap_update_bits(map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], 0xFF); else - ret = regmap_update_bits(map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], 0x0); if (ret != 0) { dev_err(map->dev, diff --git a/include/linux/regmap.h b/include/linux/regmap.h index e88649225a60..400172b59f24 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -884,6 +884,7 @@ struct regmap_irq { * * @status_base: Base status register address. * @mask_base: Base mask register address. + * @mask_writeonly: Base mask register is write only. * @unmask_base: Base unmask register address. for chips who have * separate mask and unmask registers * @ack_base: Base ack address. If zero then the chip is clear on read. @@ -927,6 +928,7 @@ struct regmap_irq_chip { unsigned int wake_base; unsigned int type_base; unsigned int irq_reg_stride; + bool mask_writeonly:1; bool init_ack_masked:1; bool mask_invert:1; bool use_ack:1; -- 2.13.2