All of lore.kernel.org
 help / color / mirror / Atom feed
From: b_lkasam@codeaurora.org
To: broonie@kernel.org, gregkh@linuxfoundation.org, rafael@kernel.org
Cc: linux-kernel@vger.kernel.org, srinivas.kandagatla@linaro.org
Subject: [PATCH v2] regmap: irq: Add support to clear ack registers
Date: Mon, 05 Oct 2020 17:55:27 +0530	[thread overview]
Message-ID: <0f3da3b378ee9af7030d8bafa30b8dfd@codeaurora.org> (raw)
In-Reply-To: <1601896560-27938-1-git-send-email-lkasam@codeaurora.org>

[-- Attachment #1: Type: text/plain, Size: 3509 bytes --]

<diff in v1 to v2 , addressed formatting and simplified logic >

For particular codec HWs have requirement to
toggle interrupt clear register twice 0->1->0.
To accommodate it, need to add one more field
(clear_ack) in the regmap_irq struct and update
regmap-irq driver to support it.

Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
---
  drivers/base/regmap/regmap-irq.c | 33 ++++++++++++++++++++++++++++++++-
  include/linux/regmap.h           |  2 ++
  2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/base/regmap/regmap-irq.c 
b/drivers/base/regmap/regmap-irq.c
index 369a57e..ad5c2de 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -168,6 +168,14 @@ static void regmap_irq_sync_unlock(struct irq_data 
*data)
  				ret = regmap_write(map, reg, ~d->mask_buf[i]);
  			else
  				ret = regmap_write(map, reg, d->mask_buf[i]);
+			if (d->chip->clear_ack) {
+				if (d->chip->ack_invert && !ret)
+					ret = regmap_write(map, reg,
+							   d->mask_buf[i]);
+				else if (!ret)
+					ret = regmap_write(map, reg,
+							   ~d->mask_buf[i]);
+			}
  			if (ret != 0)
  				dev_err(d->map->dev, "Failed to ack 0x%x: %d\n",
  					reg, ret);
@@ -493,7 +501,20 @@ static irqreturn_t regmap_irq_thread(int irq, void 
*d)
  		if (data->status_buf[i] && (chip->ack_base || chip->use_ack)) {
  			reg = chip->ack_base +
  				(i * map->reg_stride * data->irq_reg_stride);
-			ret = regmap_write(map, reg, data->status_buf[i]);
+			if (chip->ack_invert)
+				ret = regmap_write(map, reg,
+						~data->status_buf[i]);
+			else
+				ret = regmap_write(map, reg,
+						data->status_buf[i]);
+			if (chip->clear_ack) {
+				if (chip->ack_invert && !ret)
+					ret = regmap_write(map, reg,
+							data->status_buf[i]);
+				else if (!ret)
+					ret = regmap_write(map, reg,
+							~data->status_buf[i]);
+			}
  			if (ret != 0)
  				dev_err(map->dev, "Failed to ack 0x%x: %d\n",
  					reg, ret);
@@ -722,6 +743,16 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle 
*fwnode,
  			else
  				ret = regmap_write(map, reg,
  					d->status_buf[i] & d->mask_buf[i]);
+			if (chip->clear_ack) {
+				if (chip->ack_invert && !ret)
+					ret = regmap_write(map, reg,
+						(d->status_buf[i] &
+						 d->mask_buf[i]));
+				else if (!ret)
+					ret = regmap_write(map, reg,
+						~(d->status_buf[i] &
+						  d->mask_buf[i]));
+			}
  			if (ret != 0) {
  				dev_err(map->dev, "Failed to ack 0x%x: %d\n",
  					reg, ret);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 1970ed5..0701671 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -1305,6 +1305,7 @@ struct regmap_irq_sub_irq_map {
   * @mask_invert: Inverted mask register: cleared bits are masked out.
   * @use_ack:     Use @ack register even if it is zero.
   * @ack_invert:  Inverted ack register: cleared bits for ack.
+ * @clear_ack:  Use this to set 1 and 0 or vice-versa to clear 
interrupts.
   * @wake_invert: Inverted wake register: cleared bits are wake enabled.
   * @type_invert: Invert the type flags.
   * @type_in_mask: Use the mask registers for controlling irq type. For
@@ -1353,6 +1354,7 @@ struct regmap_irq_chip {
  	bool mask_invert:1;
  	bool use_ack:1;
  	bool ack_invert:1;
+	bool clear_ack:1;
  	bool wake_invert:1;
  	bool runtime_pm:1;
  	bool type_invert:1;
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, 
Inc.,
is a member of Code Aurora Forum, a Linux Foundation Collaborative 
Project.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v2-0001-regmap-irq-Add-support-to-clear-ack-registers.patch --]
[-- Type: text/x-diff; name=v2-0001-regmap-irq-Add-support-to-clear-ack-registers.patch, Size: 3631 bytes --]

From 822d819c8d538b0323709eefc41e88d062b349ee Mon Sep 17 00:00:00 2001
From: Laxminath Kasam <lkasam@codeaurora.org>
Date: Wed, 23 Sep 2020 18:42:36 +0530
Subject: [PATCH v2] regmap: irq: Add support to clear ack registers

For particular codec HWs have requirement to
toggle interrupt clear register twice 0->1->0.
To accommodate it, need to add one more field
(clear_ack) in the regmap_irq struct and update
regmap-irq driver to support it.

Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
---
 drivers/base/regmap/regmap-irq.c | 33 ++++++++++++++++++++++++++++++++-
 include/linux/regmap.h           |  2 ++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 369a57e..ad5c2de 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -168,6 +168,14 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
 				ret = regmap_write(map, reg, ~d->mask_buf[i]);
 			else
 				ret = regmap_write(map, reg, d->mask_buf[i]);
+			if (d->chip->clear_ack) {
+				if (d->chip->ack_invert && !ret)
+					ret = regmap_write(map, reg,
+							   d->mask_buf[i]);
+				else if (!ret)
+					ret = regmap_write(map, reg,
+							   ~d->mask_buf[i]);
+			}
 			if (ret != 0)
 				dev_err(d->map->dev, "Failed to ack 0x%x: %d\n",
 					reg, ret);
@@ -493,7 +501,20 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
 		if (data->status_buf[i] && (chip->ack_base || chip->use_ack)) {
 			reg = chip->ack_base +
 				(i * map->reg_stride * data->irq_reg_stride);
-			ret = regmap_write(map, reg, data->status_buf[i]);
+			if (chip->ack_invert)
+				ret = regmap_write(map, reg,
+						~data->status_buf[i]);
+			else
+				ret = regmap_write(map, reg,
+						data->status_buf[i]);
+			if (chip->clear_ack) {
+				if (chip->ack_invert && !ret)
+					ret = regmap_write(map, reg,
+							data->status_buf[i]);
+				else if (!ret)
+					ret = regmap_write(map, reg,
+							~data->status_buf[i]);
+			}
 			if (ret != 0)
 				dev_err(map->dev, "Failed to ack 0x%x: %d\n",
 					reg, ret);
@@ -722,6 +743,16 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 			else
 				ret = regmap_write(map, reg,
 					d->status_buf[i] & d->mask_buf[i]);
+			if (chip->clear_ack) {
+				if (chip->ack_invert && !ret)
+					ret = regmap_write(map, reg,
+						(d->status_buf[i] &
+						 d->mask_buf[i]));
+				else if (!ret)
+					ret = regmap_write(map, reg,
+						~(d->status_buf[i] &
+						  d->mask_buf[i]));
+			}
 			if (ret != 0) {
 				dev_err(map->dev, "Failed to ack 0x%x: %d\n",
 					reg, ret);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 1970ed5..0701671 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -1305,6 +1305,7 @@ struct regmap_irq_sub_irq_map {
  * @mask_invert: Inverted mask register: cleared bits are masked out.
  * @use_ack:     Use @ack register even if it is zero.
  * @ack_invert:  Inverted ack register: cleared bits for ack.
+ * @clear_ack:  Use this to set 1 and 0 or vice-versa to clear interrupts.
  * @wake_invert: Inverted wake register: cleared bits are wake enabled.
  * @type_invert: Invert the type flags.
  * @type_in_mask: Use the mask registers for controlling irq type. For
@@ -1353,6 +1354,7 @@ struct regmap_irq_chip {
 	bool mask_invert:1;
 	bool use_ack:1;
 	bool ack_invert:1;
+	bool clear_ack:1;
 	bool wake_invert:1;
 	bool runtime_pm:1;
 	bool type_invert:1;
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc.,
is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.


       reply	other threads:[~2020-10-05 12:25 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Re: [PATCH] regmap: irq: Add support to clear ack registers>
     [not found] ` <1601896560-27938-1-git-send-email-lkasam@codeaurora.org>
2020-10-05 12:25   ` b_lkasam [this message]
2020-10-05 12:41     ` [PATCH v2] regmap: irq: Add support to clear ack registers Greg KH
2020-10-05 14:02       ` b_lkasam

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0f3da3b378ee9af7030d8bafa30b8dfd@codeaurora.org \
    --to=b_lkasam@codeaurora.org \
    --cc=broonie@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rafael@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.