linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] irqchip/gicv3: use readl_poll_timeout_relaxed()
@ 2018-04-06 16:26 Mark Rutland
  2018-04-06 16:26 ` [PATCH 1/2] irqchip/gic-v3-its: " Mark Rutland
  2018-04-06 16:26 ` [PATCH 2/2] irqchip/gic-v3: " Mark Rutland
  0 siblings, 2 replies; 3+ messages in thread
From: Mark Rutland @ 2018-04-06 16:26 UTC (permalink / raw)
  To: linux-arm-kernel

The GICv3 code open-codes some IO polling loops, which a delay constructed as a
series of udelay(1) calls. We can make this simpler and more consistent by
using the readl_relaxed_poll_timeout() helper, so lets do so.

Thanks,
Mark.

Mark Rutland (2):
  irqchip/gic-v3-its: use readl_poll_timeout_relaxed()
  irqchip/gic-v3: use readl_poll_timeout_relaxed()

 drivers/irqchip/irq-gic-v3-its.c | 59 +++++++++++++++++-----------------------
 drivers/irqchip/irq-gic-v3.c     | 31 ++++++++-------------
 2 files changed, 37 insertions(+), 53 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] irqchip/gic-v3-its: use readl_poll_timeout_relaxed()
  2018-04-06 16:26 [PATCH 0/2] irqchip/gicv3: use readl_poll_timeout_relaxed() Mark Rutland
@ 2018-04-06 16:26 ` Mark Rutland
  2018-04-06 16:26 ` [PATCH 2/2] irqchip/gic-v3: " Mark Rutland
  1 sibling, 0 replies; 3+ messages in thread
From: Mark Rutland @ 2018-04-06 16:26 UTC (permalink / raw)
  To: linux-arm-kernel

The GICv3 ITS driver open-codes IO polling loops. Let's use the standard
iopoll helpers to make things more consistent. At the same time, let's
use the USEC_PER_SEC mnemonic to make the timeout behaviour clearer.

This change means that we return -ETIMEDOUT rather than 1 or -EBUSY, but
in all cases the caller only cares as to whether the return value is
non-zero, so this should not be problematic.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 59 +++++++++++++++++-----------------------
 1 file changed, 25 insertions(+), 34 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 2cbb19cddbf8..ca45fec77be1 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -23,6 +23,7 @@
 #include <linux/dma-iommu.h>
 #include <linux/interrupt.h>
 #include <linux/irqdomain.h>
+#include <linux/iopoll.h>
 #include <linux/log2.h>
 #include <linux/mm.h>
 #include <linux/msi.h>
@@ -33,6 +34,7 @@
 #include <linux/of_platform.h>
 #include <linux/percpu.h>
 #include <linux/slab.h>
+#include <linux/time64.h>
 
 #include <linux/irqchip.h>
 #include <linux/irqchip/arm-gic-v3.h>
@@ -711,38 +713,37 @@ static void its_flush_cmd(struct its_node *its, struct its_cmd_block *cmd)
 		dsb(ishst);
 }
 
+static bool __its_range_complete(u64 rd_idx, u64 from_idx, u64 to_idx)
+{
+	/* direct case */
+	if (from_idx < to_idx && rd_idx >= to_idx)
+		return true;
+
+	/* Wrapped case */
+	if (from_idx >= to_idx && rd_idx >= to_idx && rd_idx < from_idx)
+		return true;
+
+	return false;
+}
+
 static int its_wait_for_range_completion(struct its_node *its,
 					 struct its_cmd_block *from,
 					 struct its_cmd_block *to)
 {
 	u64 rd_idx, from_idx, to_idx;
-	u32 count = 1000000;	/* 1s! */
+	int ret;
 
 	from_idx = its_cmd_ptr_to_offset(its, from);
 	to_idx = its_cmd_ptr_to_offset(its, to);
 
-	while (1) {
-		rd_idx = readl_relaxed(its->base + GITS_CREADR);
-
-		/* Direct case */
-		if (from_idx < to_idx && rd_idx >= to_idx)
-			break;
-
-		/* Wrapped case */
-		if (from_idx >= to_idx && rd_idx >= to_idx && rd_idx < from_idx)
-			break;
-
-		count--;
-		if (!count) {
-			pr_err_ratelimited("ITS queue timeout (%llu %llu %llu)\n",
+	ret = readl_relaxed_poll_timeout(its->base + GITS_CREADR, rd_idx,
+					 __its_range_complete(rd_idx, from_idx, to_idx),
+					 1, USEC_PER_SEC);
+	if (ret)
+		pr_err_ratelimited("ITS queue timeout (%llu %llu %llu)\n",
 					   from_idx, to_idx, rd_idx);
-			return -1;
-		}
-		cpu_relax();
-		udelay(1);
-	}
 
-	return 0;
+	return ret;
 }
 
 /* Warning, macro hell follows */
@@ -2872,7 +2873,6 @@ static const struct irq_domain_ops its_vpe_domain_ops = {
 
 static int its_force_quiescent(void __iomem *base)
 {
-	u32 count = 1000000;	/* 1s */
 	u32 val;
 
 	val = readl_relaxed(base + GITS_CTLR);
@@ -2889,18 +2889,9 @@ static int its_force_quiescent(void __iomem *base)
 	writel_relaxed(val, base + GITS_CTLR);
 
 	/* Poll GITS_CTLR and wait until ITS becomes quiescent */
-	while (1) {
-		val = readl_relaxed(base + GITS_CTLR);
-		if (val & GITS_CTLR_QUIESCENT)
-			return 0;
-
-		count--;
-		if (!count)
-			return -EBUSY;
-
-		cpu_relax();
-		udelay(1);
-	}
+	return readl_relaxed_poll_timeout(base + GITS_CTLR, val,
+					  val & GITS_CTLR_QUIESCENT, 1,
+					  USEC_PER_SEC);
 }
 
 static bool __maybe_unused its_enable_quirk_cavium_22375(void *data)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] irqchip/gic-v3: use readl_poll_timeout_relaxed()
  2018-04-06 16:26 [PATCH 0/2] irqchip/gicv3: use readl_poll_timeout_relaxed() Mark Rutland
  2018-04-06 16:26 ` [PATCH 1/2] irqchip/gic-v3-its: " Mark Rutland
@ 2018-04-06 16:26 ` Mark Rutland
  1 sibling, 0 replies; 3+ messages in thread
From: Mark Rutland @ 2018-04-06 16:26 UTC (permalink / raw)
  To: linux-arm-kernel

The GICv3 driver open-codes IO polling loops. Let's use the standard
iopoll helpers to make things more consistent. At the same time, let's
use the USEC_PER_SEC mnemonic to make the timeout behaviour clearer.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3.c | 31 ++++++++++++-------------------
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index d99cc07903ec..9fd777a8398f 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -23,11 +23,13 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/irqdomain.h>
+#include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/percpu.h>
 #include <linux/slab.h>
+#include <linux/time64.h>
 
 #include <linux/irqchip.h>
 #include <linux/irqchip/arm-gic-common.h>
@@ -97,17 +99,13 @@ static inline void __iomem *gic_dist_base(struct irq_data *d)
 
 static void gic_do_wait_for_rwp(void __iomem *base)
 {
-	u32 count = 1000000;	/* 1s! */
+	u32 val;
 
-	while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) {
-		count--;
-		if (!count) {
-			pr_err_ratelimited("RWP timeout, gone fishing\n");
-			return;
-		}
-		cpu_relax();
-		udelay(1);
-	};
+	if (readl_relaxed_poll_timeout(base + GICD_CTLR, val,
+				       !(val & GICD_CTLR_RWP), 1,
+				       USEC_PER_SEC)) {
+		pr_err_ratelimited("RWP timeout, gone fishing\n");
+	}
 }
 
 /* Wait for completion of a distributor change */
@@ -136,7 +134,6 @@ static u64 __maybe_unused gic_read_iar(void)
 static void gic_enable_redist(bool enable)
 {
 	void __iomem *rbase;
-	u32 count = 1000000;	/* 1s! */
 	u32 val;
 
 	rbase = gic_data_rdist_rd_base();
@@ -155,16 +152,12 @@ static void gic_enable_redist(bool enable)
 			return;	/* No PM support in this redistributor */
 	}
 
-	while (--count) {
-		val = readl_relaxed(rbase + GICR_WAKER);
-		if (enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep))
-			break;
-		cpu_relax();
-		udelay(1);
-	};
-	if (!count)
+	if (readl_relaxed_poll_timeout(rbase + GICR_WAKER, val,
+				       enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep),
+				       1, USEC_PER_SEC)) {
 		pr_err_ratelimited("redistributor failed to %s...\n",
 				   enable ? "wakeup" : "sleep");
+	}
 }
 
 /*
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-04-06 16:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-04-06 16:26 [PATCH 0/2] irqchip/gicv3: use readl_poll_timeout_relaxed() Mark Rutland
2018-04-06 16:26 ` [PATCH 1/2] irqchip/gic-v3-its: " Mark Rutland
2018-04-06 16:26 ` [PATCH 2/2] irqchip/gic-v3: " Mark Rutland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).