Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1626533 > unrolled thread

[GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support

Started byMark Rutland <mark.rutland@arm.com>
First post2017-04-19 18:50 +0200
Last post2017-04-20 10:40 +0200
Articles 11 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support Mark Rutland <mark.rutland@arm.com> - 2017-04-19 18:50 +0200
    [PATCH 11/16] clocksource: arm_arch_timer: split MMIO timer probing. Mark Rutland <mark.rutland@arm.com> - 2017-04-19 19:00 +0200
    [PATCH 09/16] clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call Mark Rutland <mark.rutland@arm.com> - 2017-04-19 19:00 +0200
    [PATCH 08/16] clocksource: arm_arch_timer: refactor arch_timer_needs_probing Mark Rutland <mark.rutland@arm.com> - 2017-04-19 19:20 +0200
    [PATCH 04/16] clocksource: arm_arch_timer: move enums and defines to header file Mark Rutland <mark.rutland@arm.com> - 2017-04-19 19:20 +0200
    [PATCH 03/16] clocksource: arm_arch_timer: rename the PPI enum Mark Rutland <mark.rutland@arm.com> - 2017-04-19 19:20 +0200
    [PATCH 06/16] clocksource: arm_arch_timer: rework PPI selection Mark Rutland <mark.rutland@arm.com> - 2017-04-19 19:20 +0200
    [PATCH 05/16] clocksource: arm_arch_timer: add a new enum for spi type Mark Rutland <mark.rutland@arm.com> - 2017-04-19 19:20 +0200
    Re: [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO  timer support Daniel Lezcano <daniel.lezcano@linaro.org> - 2017-04-19 23:40 +0200
      Re: [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO  timer support Mark Rutland <mark.rutland@arm.com> - 2017-04-20 10:30 +0200
        Re: [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO  timer support Fu Wei <fu.wei@linaro.org> - 2017-04-20 10:40 +0200

#1626533 — [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support

FromMark Rutland <mark.rutland@arm.com>
Date2017-04-19 18:50 +0200
Subject[GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support
Message-ID<ty0XM-5M7-13@gated-at.bofh.it>
Hi Daniel,

The series enables support for the MMIO architected timers (useful for
system-level idle), which need to be probed via the GTDT when using ACPI. 

I realise this is a little late, but I would very much appreciate if you could
pull these arch timer GTDT patches for v4.12. The series has been largely fine
for a while now, and the major hold-ups were edge cases in error handling which
have now been addressed.

The bulk of the series is a refactoring to cleanly separate the core driver, DT
probe path, and ACPI probe path. The final patch of the series adds GTDT-based
probing of the SBSA watchdog, using the new GTDT probing infrastructure. I've
tested the patches on arm and arm64 platforms.

The ACPI parts have all been appropriately acked, and it's preferred that these
all go through the clocksource tree.

The series is based on Marc's arch-timer-errata tag, which is alread in
tip/timers/core.

Thanks,
Mark.

The following changes since commit d003d029cea8a28139b4f9b88a36b8fac864f45b:

  arm64: arch_timer: Add HISILICON_ERRATUM_161010101 ACPI matching data (2017-04-07 11:22:10 +0100)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git tags/arch-timer-gtdt

for you to fetch changes up to ca9ae5ec4ef0ed13833b03297ab319676965492c:

  acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver (2017-04-19 17:00:15 +0100)

----------------------------------------------------------------
arch timer GTDT patches

- arch_timer cleanups and refactoring
- new common GTDT parser
- GTDT-based MMIO arch_timer support
- GTDT-based SBSA watchdog support

----------------------------------------------------------------
Fu Wei (16):
      clocksource: arm_arch_timer: clean up printk usage
      clocksource: arm_arch_timer: rename type macros
      clocksource: arm_arch_timer: rename the PPI enum
      clocksource: arm_arch_timer: move enums and defines to header file
      clocksource: arm_arch_timer: add a new enum for spi type
      clocksource: arm_arch_timer: rework PPI selection
      clocksource: arm_arch_timer: split dt-only rate handling
      clocksource: arm_arch_timer: refactor arch_timer_needs_probing
      clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call
      clocksource: arm_arch_timer: add structs to describe MMIO timer
      clocksource: arm_arch_timer: split MMIO timer probing.
      acpi/arm64: Add GTDT table parse driver
      clocksource: arm_arch_timer: simplify ACPI support code.
      acpi/arm64: Add memory-mapped timer support in GTDT driver
      clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
      acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver

 arch/arm64/Kconfig                   |   1 +
 drivers/acpi/arm64/Kconfig           |   3 +
 drivers/acpi/arm64/Makefile          |   1 +
 drivers/acpi/arm64/gtdt.c            | 417 +++++++++++++++++++++++++
 drivers/clocksource/arm_arch_timer.c | 573 +++++++++++++++++++++++------------
 include/clocksource/arm_arch_timer.h |  34 +++
 include/linux/acpi.h                 |   7 +
 7 files changed, 834 insertions(+), 202 deletions(-)
 create mode 100644 drivers/acpi/arm64/gtdt.c

[toc] | [next] | [standalone]


#1626540 — [PATCH 11/16] clocksource: arm_arch_timer: split MMIO timer probing.

FromMark Rutland <mark.rutland@arm.com>
Date2017-04-19 19:00 +0200
Subject[PATCH 11/16] clocksource: arm_arch_timer: split MMIO timer probing.
Message-ID<ty17r-5PA-13@gated-at.bofh.it>
In reply to#1626533
From: Fu Wei <fu.wei@linaro.org>

Currently the code to probe MMIO architected timers mixes DT parsing with
actual poking of hardware. This makes the code harder than necessary to
understand, and makes it difficult to add support for probing via ACPI.

This patch splits the DT parsing from HW probing. The DT parsing now
lives in arch_timer_mem_of_init(), which fills in an arch_timer_mem
structure that it hands to probing functions that can be reused for ACPI
support.

Since the rate detection logic will be slight different when using ACPI,
the probing is performed as a number of steps. This results in more code
for the moment, and some arguably redundant work, but simplifies matters
considerably when ACPI support is added.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
[Mark: refactor the probing split]
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 189 +++++++++++++++++++++++++++--------
 1 file changed, 145 insertions(+), 44 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index ac6fd00..d87c403 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1158,7 +1158,7 @@ static int __init arch_timer_of_init(struct device_node *np)
 
 	arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI];
 
-	rate = arch_timer_get_cntfrq;
+	rate = arch_timer_get_cntfrq();
 	arch_timer_of_configure_rate(rate, np);
 
 	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
@@ -1197,18 +1197,38 @@ static int __init arch_timer_of_init(struct device_node *np)
 CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
 CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init);
 
-static int __init arch_timer_mem_init(struct device_node *np)
+static u32 __init
+arch_timer_mem_frame_get_cntfrq(struct arch_timer_mem_frame *frame)
 {
-	struct device_node *frame, *best_frame = NULL;
-	void __iomem *cntctlbase, *base;
-	unsigned int irq, ret = -EINVAL;
-	u32 cnttidr, rate;
+	void __iomem *base;
+	u32 rate;
 
-	arch_timers_present |= ARCH_TIMER_TYPE_MEM;
-	cntctlbase = of_iomap(np, 0);
+	base = ioremap(frame->cntbase, frame->size);
+	if (!base) {
+		pr_err("Unable to map frame @ %pa\n", &frame->cntbase);
+		return 0;
+	}
+
+	rate = readl_relaxed(frame + CNTFRQ);
+
+	iounmap(frame);
+
+	return rate;
+}
+
+static struct arch_timer_mem_frame * __init
+arch_timer_mem_find_best_frame(struct arch_timer_mem *timer_mem)
+{
+	struct arch_timer_mem_frame *frame, *best_frame = NULL;
+	void __iomem *cntctlbase;
+	u32 cnttidr;
+	int i;
+
+	cntctlbase = ioremap(timer_mem->cntctlbase, timer_mem->size);
 	if (!cntctlbase) {
-		pr_err("Can't find CNTCTLBase\n");
-		return -ENXIO;
+		pr_err("Can't map CNTCTLBase @ %pa\n",
+			&timer_mem->cntctlbase);
+		return NULL;
 	}
 
 	cnttidr = readl_relaxed(cntctlbase + CNTTIDR);
@@ -1217,25 +1237,20 @@ static int __init arch_timer_mem_init(struct device_node *np)
 	 * Try to find a virtual capable frame. Otherwise fall back to a
 	 * physical capable frame.
 	 */
-	for_each_available_child_of_node(np, frame) {
-		int n;
-		u32 cntacr;
+	for (i = 0; i < ARCH_TIMER_MEM_MAX_FRAMES; i++) {
+		u32 cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT |
+			     CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT;
 
-		if (of_property_read_u32(frame, "frame-number", &n)) {
-			pr_err("Missing frame-number\n");
-			of_node_put(frame);
-			goto out;
-		}
+		frame = &timer_mem->frame[i];
+		if (!frame->valid)
+			continue;
 
 		/* Try enabling everything, and see what sticks */
-		cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT |
-			 CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT;
-		writel_relaxed(cntacr, cntctlbase + CNTACR(n));
-		cntacr = readl_relaxed(cntctlbase + CNTACR(n));
+		writel_relaxed(cntacr, cntctlbase + CNTACR(i));
+		cntacr = readl_relaxed(cntctlbase + CNTACR(i));
 
-		if ((cnttidr & CNTTIDR_VIRT(n)) &&
+		if ((cnttidr & CNTTIDR_VIRT(i)) &&
 		    !(~cntacr & (CNTACR_RWVT | CNTACR_RVCT))) {
-			of_node_put(best_frame);
 			best_frame = frame;
 			arch_timer_mem_use_virtual = true;
 			break;
@@ -1244,45 +1259,131 @@ static int __init arch_timer_mem_init(struct device_node *np)
 		if (~cntacr & (CNTACR_RWPT | CNTACR_RPCT))
 			continue;
 
-		of_node_put(best_frame);
-		best_frame = of_node_get(frame);
+		best_frame = frame;
 	}
 
-	ret= -ENXIO;
-	base = arch_counter_base = of_io_request_and_map(best_frame, 0,
-							 "arch_mem_timer");
-	if (IS_ERR(base)) {
-		pr_err("Can't map frame's registers\n");
-		goto out;
-	}
+	iounmap(cntctlbase);
+
+	if (!best_frame)
+		pr_err("Unable to find a suitable frame in timer @ %pa\n",
+			&timer_mem->cntctlbase);
+
+	return frame;
+}
+
+static int __init
+arch_timer_mem_frame_register(struct arch_timer_mem_frame *frame)
+{
+	void __iomem *base;
+	int ret, irq = 0;
 
 	if (arch_timer_mem_use_virtual)
-		irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_VIRT_SPI);
+		irq = frame->virt_irq;
 	else
-		irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_PHYS_SPI);
+		irq = frame->phys_irq;
 
-	ret = -EINVAL;
 	if (!irq) {
 		pr_err("Frame missing %s irq.\n",
 		       arch_timer_mem_use_virtual ? "virt" : "phys");
-		goto out;
+		return -EINVAL;
+	}
+
+	if (!request_mem_region(frame->cntbase, frame->size,
+				"arch_mem_timer"))
+		return -EBUSY;
+
+	base = ioremap(frame->cntbase, frame->size);
+	if (!base) {
+		pr_err("Can't map frame's registers\n");
+		return -ENXIO;
 	}
 
-	rate = readl(base + CNTFRQ);
-	arch_timer_of_configure_rate(rate, np);
 	ret = arch_timer_mem_register(base, irq);
-	if (ret)
+	if (ret) {
+		iounmap(base);
+		return ret;
+	}
+
+	arch_counter_base = base;
+	arch_timers_present |= ARCH_TIMER_TYPE_MEM;
+
+	return 0;
+}
+
+static int __init arch_timer_mem_of_init(struct device_node *np)
+{
+	struct arch_timer_mem *timer_mem;
+	struct arch_timer_mem_frame *frame;
+	struct device_node *frame_node;
+	struct resource res;
+	int ret = -EINVAL;
+	u32 rate;
+
+	timer_mem = kzalloc(sizeof(*timer_mem), GFP_KERNEL);
+	if (!timer_mem)
+		return -ENOMEM;
+
+	if (of_address_to_resource(np, 0, &res))
 		goto out;
+	timer_mem->cntctlbase = res.start;
+	timer_mem->size = resource_size(&res);
 
-	if (!arch_timer_needs_of_probing())
+	for_each_available_child_of_node(np, frame_node) {
+		u32 n;
+		struct arch_timer_mem_frame *frame;
+
+		if (of_property_read_u32(frame_node, "frame-number", &n)) {
+			pr_err(FW_BUG "Missing frame-number.\n");
+			of_node_put(frame_node);
+			goto out;
+		}
+		if (n >= ARCH_TIMER_MEM_MAX_FRAMES) {
+			pr_err(FW_BUG "Wrong frame-number, only 0-%u are permitted.\n",
+			       ARCH_TIMER_MEM_MAX_FRAMES - 1);
+			of_node_put(frame_node);
+			goto out;
+		}
+		frame = &timer_mem->frame[n];
+
+		if (frame->valid) {
+			pr_err(FW_BUG "Duplicated frame-number.\n");
+			of_node_put(frame_node);
+			goto out;
+		}
+
+		if (of_address_to_resource(frame_node, 0, &res)) {
+			of_node_put(frame_node);
+			goto out;
+		}
+		frame->cntbase = res.start;
+		frame->size = resource_size(&res);
+
+		frame->virt_irq = irq_of_parse_and_map(frame_node,
+						       ARCH_TIMER_VIRT_SPI);
+		frame->phys_irq = irq_of_parse_and_map(frame_node,
+						       ARCH_TIMER_PHYS_SPI);
+
+		frame->valid = true;
+	}
+
+	frame = arch_timer_mem_find_best_frame(timer_mem);
+	if (!frame) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	rate = arch_timer_mem_frame_get_cntfrq(frame);
+	arch_timer_of_configure_rate(rate, np);
+
+	ret = arch_timer_mem_frame_register(frame);
+	if (!ret && !arch_timer_needs_of_probing())
 		ret = arch_timer_common_init();
 out:
-	iounmap(cntctlbase);
-	of_node_put(best_frame);
+	kfree(timer_mem);
 	return ret;
 }
 CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
-		       arch_timer_mem_init);
+		       arch_timer_mem_of_init);
 
 #ifdef CONFIG_ACPI
 static int __init map_generic_timer_interrupt(u32 interrupt, u32 flags)
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1626548 — [PATCH 09/16] clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call

FromMark Rutland <mark.rutland@arm.com>
Date2017-04-19 19:00 +0200
Subject[PATCH 09/16] clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call
Message-ID<ty17s-5PA-27@gated-at.bofh.it>
In reply to#1626533
From: Fu Wei <fu.wei@linaro.org>

To cleanly split code paths specific to ACPI or DT at a higher level,
this patch removes arch_timer_init(), folding the relevant
parts of its logic into existing callers.

This pathes the way for further rework, and saves a few lines.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
[Mark: reword commit message]
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 46 ++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index e38f4d4..ac6fd00 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1105,9 +1105,6 @@ static bool __init arch_timer_needs_of_probing(void)
 
 static int __init arch_timer_common_init(void)
 {
-	if (acpi_disabled && arch_timer_needs_of_probing())
-		return 0;
-
 	arch_timer_banner(arch_timers_present);
 	arch_counter_register(arch_timers_present);
 	return arch_timer_arch_init();
@@ -1145,26 +1142,9 @@ static enum arch_timer_ppi_nr __init arch_timer_select_ppi(void)
 	return ARCH_TIMER_PHYS_SECURE_PPI;
 }
 
-static int __init arch_timer_init(void)
-{
-	int ret;
-
-	ret = arch_timer_register();
-	if (ret)
-		return ret;
-
-	ret = arch_timer_common_init();
-	if (ret)
-		return ret;
-
-	arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI];
-
-	return 0;
-}
-
 static int __init arch_timer_of_init(struct device_node *np)
 {
-	int i;
+	int i, ret;
 	u32 rate;
 
 	if (arch_timers_present & ARCH_TIMER_TYPE_CP15) {
@@ -1176,6 +1156,8 @@ static int __init arch_timer_of_init(struct device_node *np)
 	for (i = ARCH_TIMER_PHYS_SECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++)
 		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
 
+	arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI];
+
 	rate = arch_timer_get_cntfrq;
 	arch_timer_of_configure_rate(rate, np);
 
@@ -1203,7 +1185,14 @@ static int __init arch_timer_of_init(struct device_node *np)
 	arch_counter_suspend_stop = of_property_read_bool(np,
 							 "arm,no-tick-in-suspend");
 
-	return arch_timer_init();
+	ret = arch_timer_register();
+	if (ret)
+		return ret;
+
+	if (arch_timer_needs_of_probing())
+		return 0;
+
+	return arch_timer_common_init();
 }
 CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
 CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init);
@@ -1285,7 +1274,8 @@ static int __init arch_timer_mem_init(struct device_node *np)
 	if (ret)
 		goto out;
 
-	return arch_timer_common_init();
+	if (!arch_timer_needs_of_probing())
+		ret = arch_timer_common_init();
 out:
 	iounmap(cntctlbase);
 	of_node_put(best_frame);
@@ -1314,6 +1304,7 @@ static int __init map_generic_timer_interrupt(u32 interrupt, u32 flags)
 /* Initialize per-processor generic timer */
 static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 {
+	int ret;
 	struct acpi_table_gtdt *gtdt;
 
 	if (arch_timers_present & ARCH_TIMER_TYPE_CP15) {
@@ -1341,6 +1332,8 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 		map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt,
 		gtdt->non_secure_el2_flags);
 
+	arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI];
+
 	/*
 	 * When probing via ACPI, we have no mechanism to override the sysreg
 	 * CNTFRQ value. This *must* be correct.
@@ -1363,8 +1356,11 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 	/* Check for globally applicable workarounds */
 	arch_timer_check_ool_workaround(ate_match_acpi_oem_info, table);
 
-	arch_timer_init();
-	return 0;
+	ret = arch_timer_register();
+	if (ret)
+		return ret;
+
+	return arch_timer_common_init();
 }
 CLOCKSOURCE_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init);
 #endif
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1626607 — [PATCH 08/16] clocksource: arm_arch_timer: refactor arch_timer_needs_probing

FromMark Rutland <mark.rutland@arm.com>
Date2017-04-19 19:20 +0200
Subject[PATCH 08/16] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
Message-ID<ty1qN-6bq-3@gated-at.bofh.it>
In reply to#1626533
From: Fu Wei <fu.wei@linaro.org>

When booting with DT, it's possible for timer nodes to be probed in any
order. Some common initialisation needs to occur after all nodes have
been probed, and arch_timer_common_init() has code to detect when this
has happened.

This logic is DT-specific, and it would be best to factor it out of the
common code that will be shared with ACPI.

This patch folds this into the existing arch_timer_needs_probing(),
which is renamed to arch_timer_needs_of_probing(), and no longer takes
any arguments. This is only called when using DT, and not when using
ACPI, which will have a deterministic probe order.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
[Mark: reword commit message]
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 02c5cb8..e38f4d4 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1076,15 +1076,28 @@ static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq)
 	{},
 };
 
-static bool __init
-arch_timer_needs_probing(int type, const struct of_device_id *matches)
+static bool __init arch_timer_needs_of_probing(void)
 {
 	struct device_node *dn;
 	bool needs_probing = false;
+	unsigned int mask = ARCH_TIMER_TYPE_CP15 | ARCH_TIMER_TYPE_MEM;
 
-	dn = of_find_matching_node(NULL, matches);
-	if (dn && of_device_is_available(dn) && !(arch_timers_present & type))
+	/* We have two timers, and both device-tree nodes are probed. */
+	if ((arch_timers_present & mask) == mask)
+		return false;
+
+	/*
+	 * Only one type of timer is probed,
+	 * check if we have another type of timer node in device-tree.
+	 */
+	if (arch_timers_present & ARCH_TIMER_TYPE_CP15)
+		dn = of_find_matching_node(NULL, arch_timer_mem_of_match);
+	else
+		dn = of_find_matching_node(NULL, arch_timer_of_match);
+
+	if (dn && of_device_is_available(dn))
 		needs_probing = true;
+
 	of_node_put(dn);
 
 	return needs_probing;
@@ -1092,17 +1105,8 @@ static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq)
 
 static int __init arch_timer_common_init(void)
 {
-	unsigned mask = ARCH_TIMER_TYPE_CP15 | ARCH_TIMER_TYPE_MEM;
-
-	/* Wait until both nodes are probed if we have two timers */
-	if ((arch_timers_present & mask) != mask) {
-		if (arch_timer_needs_probing(ARCH_TIMER_TYPE_MEM,
-					     arch_timer_mem_of_match))
-			return 0;
-		if (arch_timer_needs_probing(ARCH_TIMER_TYPE_CP15,
-					     arch_timer_of_match))
-			return 0;
-	}
+	if (acpi_disabled && arch_timer_needs_of_probing())
+		return 0;
 
 	arch_timer_banner(arch_timers_present);
 	arch_counter_register(arch_timers_present);
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1626608 — [PATCH 04/16] clocksource: arm_arch_timer: move enums and defines to header file

FromMark Rutland <mark.rutland@arm.com>
Date2017-04-19 19:20 +0200
Subject[PATCH 04/16] clocksource: arm_arch_timer: move enums and defines to header file
Message-ID<ty1qO-6bq-17@gated-at.bofh.it>
In reply to#1626533
From: Fu Wei <fu.wei@linaro.org>

To support the arm_arch_timer via ACPI we need to share defines and enums
between the driver and the ACPI parser code.
So we split out the relevant defines and enums into arm_arch_timer.h.

No functional change.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 11 -----------
 include/clocksource/arm_arch_timer.h | 12 ++++++++++++
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 94e355b..04218c1 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -55,8 +55,6 @@
 #define CNTV_TVAL	0x38
 #define CNTV_CTL	0x3c
 
-#define ARCH_TIMER_TYPE_CP15		BIT(0)
-#define ARCH_TIMER_TYPE_MEM		BIT(1)
 static unsigned arch_timers_present __initdata;
 
 static void __iomem *arch_counter_base;
@@ -69,15 +67,6 @@ struct arch_timer {
 #define to_arch_timer(e) container_of(e, struct arch_timer, evt)
 
 static u32 arch_timer_rate;
-
-enum arch_timer_ppi_nr {
-	ARCH_TIMER_PHYS_SECURE_PPI,
-	ARCH_TIMER_PHYS_NONSECURE_PPI,
-	ARCH_TIMER_VIRT_PPI,
-	ARCH_TIMER_HYP_PPI,
-	ARCH_TIMER_MAX_TIMER_PPI
-};
-
 static int arch_timer_ppi[ARCH_TIMER_MAX_TIMER_PPI];
 
 static struct clock_event_device __percpu *arch_timer_evt;
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index caedb74..b898637 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -16,9 +16,13 @@
 #ifndef __CLKSOURCE_ARM_ARCH_TIMER_H
 #define __CLKSOURCE_ARM_ARCH_TIMER_H
 
+#include <linux/bitops.h>
 #include <linux/timecounter.h>
 #include <linux/types.h>
 
+#define ARCH_TIMER_TYPE_CP15		BIT(0)
+#define ARCH_TIMER_TYPE_MEM		BIT(1)
+
 #define ARCH_TIMER_CTRL_ENABLE		(1 << 0)
 #define ARCH_TIMER_CTRL_IT_MASK		(1 << 1)
 #define ARCH_TIMER_CTRL_IT_STAT		(1 << 2)
@@ -34,6 +38,14 @@ enum arch_timer_reg {
 	ARCH_TIMER_REG_TVAL,
 };
 
+enum arch_timer_ppi_nr {
+	ARCH_TIMER_PHYS_SECURE_PPI,
+	ARCH_TIMER_PHYS_NONSECURE_PPI,
+	ARCH_TIMER_VIRT_PPI,
+	ARCH_TIMER_HYP_PPI,
+	ARCH_TIMER_MAX_TIMER_PPI
+};
+
 #define ARCH_TIMER_PHYS_ACCESS		0
 #define ARCH_TIMER_VIRT_ACCESS		1
 #define ARCH_TIMER_MEM_PHYS_ACCESS	2
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1626611 — [PATCH 03/16] clocksource: arm_arch_timer: rename the PPI enum

FromMark Rutland <mark.rutland@arm.com>
Date2017-04-19 19:20 +0200
Subject[PATCH 03/16] clocksource: arm_arch_timer: rename the PPI enum
Message-ID<ty1qO-6bq-15@gated-at.bofh.it>
In reply to#1626533
From: Fu Wei <fu.wei@linaro.org>

In preparation for moving the PPI enum out into a header, rename the
enum and its constituent values these so they are namespaced w.r.t. the
arch timer. This will aid consistency and avoid potential name clashes
when this move occurs.

No functional change.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
[Mark: reword commit message]
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 82 ++++++++++++++++++------------------
 1 file changed, 42 insertions(+), 40 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 38bddb9..94e355b 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -70,19 +70,19 @@ struct arch_timer {
 
 static u32 arch_timer_rate;
 
-enum ppi_nr {
-	PHYS_SECURE_PPI,
-	PHYS_NONSECURE_PPI,
-	VIRT_PPI,
-	HYP_PPI,
-	MAX_TIMER_PPI
+enum arch_timer_ppi_nr {
+	ARCH_TIMER_PHYS_SECURE_PPI,
+	ARCH_TIMER_PHYS_NONSECURE_PPI,
+	ARCH_TIMER_VIRT_PPI,
+	ARCH_TIMER_HYP_PPI,
+	ARCH_TIMER_MAX_TIMER_PPI
 };
 
-static int arch_timer_ppi[MAX_TIMER_PPI];
+static int arch_timer_ppi[ARCH_TIMER_MAX_TIMER_PPI];
 
 static struct clock_event_device __percpu *arch_timer_evt;
 
-static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI;
+static enum arch_timer_ppi_nr arch_timer_uses_ppi = ARCH_TIMER_VIRT_PPI;
 static bool arch_timer_c3stop;
 static bool arch_timer_mem_use_virtual;
 static bool arch_counter_suspend_stop;
@@ -694,14 +694,14 @@ static void __arch_timer_setup(unsigned type,
 		clk->cpumask = cpumask_of(smp_processor_id());
 		clk->irq = arch_timer_ppi[arch_timer_uses_ppi];
 		switch (arch_timer_uses_ppi) {
-		case VIRT_PPI:
+		case ARCH_TIMER_VIRT_PPI:
 			clk->set_state_shutdown = arch_timer_shutdown_virt;
 			clk->set_state_oneshot_stopped = arch_timer_shutdown_virt;
 			clk->set_next_event = arch_timer_set_next_event_virt;
 			break;
-		case PHYS_SECURE_PPI:
-		case PHYS_NONSECURE_PPI:
-		case HYP_PPI:
+		case ARCH_TIMER_PHYS_SECURE_PPI:
+		case ARCH_TIMER_PHYS_NONSECURE_PPI:
+		case ARCH_TIMER_HYP_PPI:
 			clk->set_state_shutdown = arch_timer_shutdown_phys;
 			clk->set_state_oneshot_stopped = arch_timer_shutdown_phys;
 			clk->set_next_event = arch_timer_set_next_event_phys;
@@ -789,8 +789,8 @@ static void arch_counter_set_user_access(void)
 
 static bool arch_timer_has_nonsecure_ppi(void)
 {
-	return (arch_timer_uses_ppi == PHYS_SECURE_PPI &&
-		arch_timer_ppi[PHYS_NONSECURE_PPI]);
+	return (arch_timer_uses_ppi == ARCH_TIMER_PHYS_SECURE_PPI &&
+		arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
 }
 
 static u32 check_ppi_trigger(int irq)
@@ -817,8 +817,9 @@ static int arch_timer_starting_cpu(unsigned int cpu)
 	enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], flags);
 
 	if (arch_timer_has_nonsecure_ppi()) {
-		flags = check_ppi_trigger(arch_timer_ppi[PHYS_NONSECURE_PPI]);
-		enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], flags);
+		flags = check_ppi_trigger(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
+		enable_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI],
+				  flags);
 	}
 
 	arch_counter_set_user_access();
@@ -862,7 +863,7 @@ static void arch_timer_banner(unsigned type)
 		(unsigned long)arch_timer_rate / 1000000,
 		(unsigned long)(arch_timer_rate / 10000) % 100,
 		type & ARCH_TIMER_TYPE_CP15 ?
-			(arch_timer_uses_ppi == VIRT_PPI) ? "virt" : "phys" :
+			(arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) ? "virt" : "phys" :
 			"",
 		type == (ARCH_TIMER_TYPE_CP15 | ARCH_TIMER_TYPE_MEM) ? "/" : "",
 		type & ARCH_TIMER_TYPE_MEM ?
@@ -901,7 +902,8 @@ static void __init arch_counter_register(unsigned type)
 
 	/* Register the CP15 based counter if we have one */
 	if (type & ARCH_TIMER_TYPE_CP15) {
-		if (IS_ENABLED(CONFIG_ARM64) || arch_timer_uses_ppi == VIRT_PPI)
+		if (IS_ENABLED(CONFIG_ARM64) ||
+		    arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI)
 			arch_timer_read_counter = arch_counter_get_cntvct;
 		else
 			arch_timer_read_counter = arch_counter_get_cntpct;
@@ -930,7 +932,7 @@ static void arch_timer_stop(struct clock_event_device *clk)
 
 	disable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi]);
 	if (arch_timer_has_nonsecure_ppi())
-		disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]);
+		disable_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
 
 	clk->set_state_shutdown(clk);
 }
@@ -993,24 +995,24 @@ static int __init arch_timer_register(void)
 
 	ppi = arch_timer_ppi[arch_timer_uses_ppi];
 	switch (arch_timer_uses_ppi) {
-	case VIRT_PPI:
+	case ARCH_TIMER_VIRT_PPI:
 		err = request_percpu_irq(ppi, arch_timer_handler_virt,
 					 "arch_timer", arch_timer_evt);
 		break;
-	case PHYS_SECURE_PPI:
-	case PHYS_NONSECURE_PPI:
+	case ARCH_TIMER_PHYS_SECURE_PPI:
+	case ARCH_TIMER_PHYS_NONSECURE_PPI:
 		err = request_percpu_irq(ppi, arch_timer_handler_phys,
 					 "arch_timer", arch_timer_evt);
-		if (!err && arch_timer_ppi[PHYS_NONSECURE_PPI]) {
-			ppi = arch_timer_ppi[PHYS_NONSECURE_PPI];
+		if (!err && arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]) {
+			ppi = arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI];
 			err = request_percpu_irq(ppi, arch_timer_handler_phys,
 						 "arch_timer", arch_timer_evt);
 			if (err)
-				free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
+				free_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI],
 						arch_timer_evt);
 		}
 		break;
-	case HYP_PPI:
+	case ARCH_TIMER_HYP_PPI:
 		err = request_percpu_irq(ppi, arch_timer_handler_phys,
 					 "arch_timer", arch_timer_evt);
 		break;
@@ -1042,7 +1044,7 @@ static int __init arch_timer_register(void)
 out_unreg_notify:
 	free_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], arch_timer_evt);
 	if (arch_timer_has_nonsecure_ppi())
-		free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI],
+		free_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI],
 				arch_timer_evt);
 
 out_free:
@@ -1139,16 +1141,16 @@ static int __init arch_timer_init(void)
 	 * their CNTHP_*_EL2 counterparts, and use a different PPI
 	 * number.
 	 */
-	if (is_hyp_mode_available() || !arch_timer_ppi[VIRT_PPI]) {
+	if (is_hyp_mode_available() || !arch_timer_ppi[ARCH_TIMER_VIRT_PPI]) {
 		bool has_ppi;
 
 		if (is_kernel_in_hyp_mode()) {
-			arch_timer_uses_ppi = HYP_PPI;
-			has_ppi = !!arch_timer_ppi[HYP_PPI];
+			arch_timer_uses_ppi = ARCH_TIMER_HYP_PPI;
+			has_ppi = !!arch_timer_ppi[ARCH_TIMER_HYP_PPI];
 		} else {
-			arch_timer_uses_ppi = PHYS_SECURE_PPI;
-			has_ppi = (!!arch_timer_ppi[PHYS_SECURE_PPI] ||
-				   !!arch_timer_ppi[PHYS_NONSECURE_PPI]);
+			arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
+			has_ppi = (!!arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] ||
+				   !!arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
 		}
 
 		if (!has_ppi) {
@@ -1165,7 +1167,7 @@ static int __init arch_timer_init(void)
 	if (ret)
 		return ret;
 
-	arch_timer_kvm_info.virtual_irq = arch_timer_ppi[VIRT_PPI];
+	arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI];
 
 	return 0;
 }
@@ -1180,7 +1182,7 @@ static int __init arch_timer_of_init(struct device_node *np)
 	}
 
 	arch_timers_present |= ARCH_TIMER_TYPE_CP15;
-	for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
+	for (i = ARCH_TIMER_PHYS_SECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++)
 		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
 
 	arch_timer_detect_rate(NULL, np);
@@ -1196,7 +1198,7 @@ static int __init arch_timer_of_init(struct device_node *np)
 	 */
 	if (IS_ENABLED(CONFIG_ARM) &&
 	    of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
-		arch_timer_uses_ppi = PHYS_SECURE_PPI;
+		arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
 
 	/* On some systems, the counter stops ticking when in suspend. */
 	arch_counter_suspend_stop = of_property_read_bool(np,
@@ -1323,19 +1325,19 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 
 	arch_timers_present |= ARCH_TIMER_TYPE_CP15;
 
-	arch_timer_ppi[PHYS_SECURE_PPI] =
+	arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] =
 		map_generic_timer_interrupt(gtdt->secure_el1_interrupt,
 		gtdt->secure_el1_flags);
 
-	arch_timer_ppi[PHYS_NONSECURE_PPI] =
+	arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI] =
 		map_generic_timer_interrupt(gtdt->non_secure_el1_interrupt,
 		gtdt->non_secure_el1_flags);
 
-	arch_timer_ppi[VIRT_PPI] =
+	arch_timer_ppi[ARCH_TIMER_VIRT_PPI] =
 		map_generic_timer_interrupt(gtdt->virtual_timer_interrupt,
 		gtdt->virtual_timer_flags);
 
-	arch_timer_ppi[HYP_PPI] =
+	arch_timer_ppi[ARCH_TIMER_HYP_PPI] =
 		map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt,
 		gtdt->non_secure_el2_flags);
 
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1626617 — [PATCH 06/16] clocksource: arm_arch_timer: rework PPI selection

FromMark Rutland <mark.rutland@arm.com>
Date2017-04-19 19:20 +0200
Subject[PATCH 06/16] clocksource: arm_arch_timer: rework PPI selection
Message-ID<ty1qO-6bq-25@gated-at.bofh.it>
In reply to#1626533
From: Fu Wei <fu.wei@linaro.org>

Currently, the arch timer driver uses ARCH_TIMER_PHYS_SECURE_PPI to mean
the driver will use the secure PPI *and* potentially also use the
non-secure PPI. This is somewhat confusing.

For arm64 it never makes sense to use the secure PPI, but we do anyway,
inheriting this behaviour from 32-bit arm. For ACPI, we may not even
have a valid secure PPI, so we need to be able to only request the
non-secure PPI.

To that end, this patch reworks the timer driver so that we can request
the non-secure PPI alone. The PPI selection is split out into a new
function, arch_timer_select_ppi(), and verification of the selected PPI
is shifted out to callers (as DT may select the PPI by other means and
must handle this anyway).

We now consistently use arch_timer_has_nonsecure_ppi() to determine
whether we must manage a non-secure PPI *in addition* to a secure PPI.
When we only have a non-secure PPI, this returns false.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
[Mark: reword commit message]
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 77 +++++++++++++++++++++---------------
 1 file changed, 46 insertions(+), 31 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 15059c9..94de018 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -992,7 +992,7 @@ static int __init arch_timer_register(void)
 	case ARCH_TIMER_PHYS_NONSECURE_PPI:
 		err = request_percpu_irq(ppi, arch_timer_handler_phys,
 					 "arch_timer", arch_timer_evt);
-		if (!err && arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]) {
+		if (!err && arch_timer_has_nonsecure_ppi()) {
 			ppi = arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI];
 			err = request_percpu_irq(ppi, arch_timer_handler_phys,
 						 "arch_timer", arch_timer_evt);
@@ -1114,39 +1114,41 @@ static int __init arch_timer_common_init(void)
 	return arch_timer_arch_init();
 }
 
-static int __init arch_timer_init(void)
+/**
+ * arch_timer_select_ppi() - Select suitable PPI for the current system.
+ *
+ * If HYP mode is available, we know that the physical timer
+ * has been configured to be accessible from PL1. Use it, so
+ * that a guest can use the virtual timer instead.
+ *
+ * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE
+ * accesses to CNTP_*_EL1 registers are silently redirected to
+ * their CNTHP_*_EL2 counterparts, and use a different PPI
+ * number.
+ *
+ * If no interrupt provided for virtual timer, we'll have to
+ * stick to the physical timer. It'd better be accessible...
+ * For arm64 we never use the secure interrupt.
+ *
+ * Return: a suitable PPI type for the current system.
+ */
+static enum arch_timer_ppi_nr __init arch_timer_select_ppi(void)
 {
-	int ret;
-	/*
-	 * If HYP mode is available, we know that the physical timer
-	 * has been configured to be accessible from PL1. Use it, so
-	 * that a guest can use the virtual timer instead.
-	 *
-	 * If no interrupt provided for virtual timer, we'll have to
-	 * stick to the physical timer. It'd better be accessible...
-	 *
-	 * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE
-	 * accesses to CNTP_*_EL1 registers are silently redirected to
-	 * their CNTHP_*_EL2 counterparts, and use a different PPI
-	 * number.
-	 */
-	if (is_hyp_mode_available() || !arch_timer_ppi[ARCH_TIMER_VIRT_PPI]) {
-		bool has_ppi;
+	if (is_kernel_in_hyp_mode())
+		return ARCH_TIMER_HYP_PPI;
 
-		if (is_kernel_in_hyp_mode()) {
-			arch_timer_uses_ppi = ARCH_TIMER_HYP_PPI;
-			has_ppi = !!arch_timer_ppi[ARCH_TIMER_HYP_PPI];
-		} else {
-			arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
-			has_ppi = (!!arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] ||
-				   !!arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
-		}
+	if (!is_hyp_mode_available() && arch_timer_ppi[ARCH_TIMER_VIRT_PPI])
+		return ARCH_TIMER_VIRT_PPI;
 
-		if (!has_ppi) {
-			pr_warn("No interrupt available, giving up\n");
-			return -EINVAL;
-		}
-	}
+	if (IS_ENABLED(CONFIG_ARM64))
+		return ARCH_TIMER_PHYS_NONSECURE_PPI;
+
+	return ARCH_TIMER_PHYS_SECURE_PPI;
+}
+
+static int __init arch_timer_init(void)
+{
+	int ret;
 
 	ret = arch_timer_register();
 	if (ret)
@@ -1188,6 +1190,13 @@ static int __init arch_timer_of_init(struct device_node *np)
 	if (IS_ENABLED(CONFIG_ARM) &&
 	    of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
 		arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
+	else
+		arch_timer_uses_ppi = arch_timer_select_ppi();
+
+	if (!arch_timer_ppi[arch_timer_uses_ppi]) {
+		pr_err("No interrupt available, giving up\n");
+		return -EINVAL;
+	}
 
 	/* On some systems, the counter stops ticking when in suspend. */
 	arch_counter_suspend_stop = of_property_read_bool(np,
@@ -1333,6 +1342,12 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 	/* Get the frequency from CNTFRQ */
 	arch_timer_detect_rate(NULL, NULL);
 
+	arch_timer_uses_ppi = arch_timer_select_ppi();
+	if (!arch_timer_ppi[arch_timer_uses_ppi]) {
+		pr_err("No interrupt available, giving up\n");
+		return -EINVAL;
+	}
+
 	/* Always-on capability */
 	arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
 
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1626620 — [PATCH 05/16] clocksource: arm_arch_timer: add a new enum for spi type

FromMark Rutland <mark.rutland@arm.com>
Date2017-04-19 19:20 +0200
Subject[PATCH 05/16] clocksource: arm_arch_timer: add a new enum for spi type
Message-ID<ty1qP-6bq-41@gated-at.bofh.it>
In reply to#1626533
From: Fu Wei <fu.wei@linaro.org>

This patch add a new enum "arch_timer_spi_nr" and use it in the driver.
Just for code's readability, no functional change.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 4 ++--
 include/clocksource/arm_arch_timer.h | 6 ++++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 04218c1..15059c9 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1258,9 +1258,9 @@ static int __init arch_timer_mem_init(struct device_node *np)
 	}
 
 	if (arch_timer_mem_use_virtual)
-		irq = irq_of_parse_and_map(best_frame, 1);
+		irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_VIRT_SPI);
 	else
-		irq = irq_of_parse_and_map(best_frame, 0);
+		irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_PHYS_SPI);
 
 	ret = -EINVAL;
 	if (!irq) {
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index b898637..4a98c06 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -46,6 +46,12 @@ enum arch_timer_ppi_nr {
 	ARCH_TIMER_MAX_TIMER_PPI
 };
 
+enum arch_timer_spi_nr {
+	ARCH_TIMER_PHYS_SPI,
+	ARCH_TIMER_VIRT_SPI,
+	ARCH_TIMER_MAX_TIMER_SPI
+};
+
 #define ARCH_TIMER_PHYS_ACCESS		0
 #define ARCH_TIMER_VIRT_ACCESS		1
 #define ARCH_TIMER_MEM_PHYS_ACCESS	2
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1626814 — Re: [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2017-04-19 23:40 +0200
SubjectRe: [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support
Message-ID<ty5uq-8wq-17@gated-at.bofh.it>
In reply to#1626533
On Wed, Apr 19, 2017 at 05:44:17PM +0100, Mark Rutland wrote:
> Hi Daniel,
> 
> The series enables support for the MMIO architected timers (useful for
> system-level idle), which need to be probed via the GTDT when using ACPI. 
> 
> I realise this is a little late, but I would very much appreciate if you could
> pull these arch timer GTDT patches for v4.12. The series has been largely fine
> for a while now, and the major hold-ups were edge cases in error handling which
> have now been addressed.
> 
> The bulk of the series is a refactoring to cleanly separate the core driver, DT
> probe path, and ACPI probe path. The final patch of the series adds GTDT-based
> probing of the SBSA watchdog, using the new GTDT probing infrastructure. I've
> tested the patches on arm and arm64 platforms.
> 
> The ACPI parts have all been appropriately acked, and it's preferred that these
> all go through the clocksource tree.
> 
> The series is based on Marc's arch-timer-errata tag, which is alread in
> tip/timers/core.

Hi Thomas,

the series is ok for me. Is it possible to pull these changes directly in 
tip/timers/core?

There is a single trivial conflict with a trace.

  -- Daniel

> 
> The following changes since commit d003d029cea8a28139b4f9b88a36b8fac864f45b:
> 
>   arm64: arch_timer: Add HISILICON_ERRATUM_161010101 ACPI matching data (2017-04-07 11:22:10 +0100)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git tags/arch-timer-gtdt
> 
> for you to fetch changes up to ca9ae5ec4ef0ed13833b03297ab319676965492c:
> 
>   acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver (2017-04-19 17:00:15 +0100)
> 
> ----------------------------------------------------------------
> arch timer GTDT patches
> 
> - arch_timer cleanups and refactoring
> - new common GTDT parser
> - GTDT-based MMIO arch_timer support
> - GTDT-based SBSA watchdog support
> 
> ----------------------------------------------------------------
> Fu Wei (16):
>       clocksource: arm_arch_timer: clean up printk usage
>       clocksource: arm_arch_timer: rename type macros
>       clocksource: arm_arch_timer: rename the PPI enum
>       clocksource: arm_arch_timer: move enums and defines to header file
>       clocksource: arm_arch_timer: add a new enum for spi type
>       clocksource: arm_arch_timer: rework PPI selection
>       clocksource: arm_arch_timer: split dt-only rate handling
>       clocksource: arm_arch_timer: refactor arch_timer_needs_probing
>       clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call
>       clocksource: arm_arch_timer: add structs to describe MMIO timer
>       clocksource: arm_arch_timer: split MMIO timer probing.
>       acpi/arm64: Add GTDT table parse driver
>       clocksource: arm_arch_timer: simplify ACPI support code.
>       acpi/arm64: Add memory-mapped timer support in GTDT driver
>       clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
>       acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
> 
>  arch/arm64/Kconfig                   |   1 +
>  drivers/acpi/arm64/Kconfig           |   3 +
>  drivers/acpi/arm64/Makefile          |   1 +
>  drivers/acpi/arm64/gtdt.c            | 417 +++++++++++++++++++++++++
>  drivers/clocksource/arm_arch_timer.c | 573 +++++++++++++++++++++++------------
>  include/clocksource/arm_arch_timer.h |  34 +++
>  include/linux/acpi.h                 |   7 +
>  7 files changed, 834 insertions(+), 202 deletions(-)
>  create mode 100644 drivers/acpi/arm64/gtdt.c

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

[toc] | [prev] | [next] | [standalone]


#1627197 — Re: [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support

FromMark Rutland <mark.rutland@arm.com>
Date2017-04-20 10:30 +0200
SubjectRe: [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support
Message-ID<tyfDs-6zX-23@gated-at.bofh.it>
In reply to#1626814
On Wed, Apr 19, 2017 at 11:39:44PM +0200, Daniel Lezcano wrote:
> On Wed, Apr 19, 2017 at 05:44:17PM +0100, Mark Rutland wrote:
> > Hi Daniel,

> > I realise this is a little late, but I would very much appreciate if you could
> > pull these arch timer GTDT patches for v4.12. The series has been largely fine
> > for a while now, and the major hold-ups were edge cases in error handling which
> > have now been addressed.

> Hi Thomas,
> 
> the series is ok for me. Is it possible to pull these changes directly in 
> tip/timers/core?

The tip-bot tells me it was.

Many thanks for picking these up, it's much appreciated.

Mark.

[toc] | [prev] | [next] | [standalone]


#1627209 — Re: [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support

FromFu Wei <fu.wei@linaro.org>
Date2017-04-20 10:40 +0200
SubjectRe: [GIT PULL 00/16] clocksource: arm_arch_timer: GTDT-based MMIO timer support
Message-ID<tyfN9-6Do-25@gated-at.bofh.it>
In reply to#1627197
Hi Daniel, Lorenzo, Mark,


On 20 April 2017 at 16:26, Mark Rutland <mark.rutland@arm.com> wrote:
> On Wed, Apr 19, 2017 at 11:39:44PM +0200, Daniel Lezcano wrote:
>> On Wed, Apr 19, 2017 at 05:44:17PM +0100, Mark Rutland wrote:
>> > Hi Daniel,
>
>> > I realise this is a little late, but I would very much appreciate if you could
>> > pull these arch timer GTDT patches for v4.12. The series has been largely fine
>> > for a while now, and the major hold-ups were edge cases in error handling which
>> > have now been addressed.
>
>> Hi Thomas,
>>
>> the series is ok for me. Is it possible to pull these changes directly in
>> tip/timers/core?
>
> The tip-bot tells me it was.
>
> Many thanks for picking these up, it's much appreciated.

Great thanks to all of you, I very appreciate all the help and
suggestion from you :-)

>
> Mark.



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web