[PATCH v22 06/11] clocksource: arm_arch_timer: refactor MMIO timer probing.

2017-03-21 Thread fu . wei
From: Fu Wei 

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 factors all the DT-specific logic out of arch_timer_mem_init(),
into a new function arch_timer_mem_of_init().
The former pokes the hardware and determines the suitablility of frames
based on a datastructure populated by the latter.

This cleanly separates the two and will make it possible to add probing
using the ACPI GTDT in subsequent patches.

Signed-off-by: Fu Wei 
Reviewed-by: Hanjun Guo 
---
 drivers/clocksource/arm_arch_timer.c | 158 +--
 1 file changed, 112 insertions(+), 46 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c 
b/drivers/clocksource/arm_arch_timer.c
index 4b29a6d..3ada5dc 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -977,17 +977,21 @@ 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 int __init arch_timer_mem_init(struct arch_timer_mem *timer_mem)
 {
-   struct device_node *frame, *best_frame = NULL;
void __iomem *cntctlbase, *base;
-   unsigned int irq, ret = -EINVAL;
+   struct arch_timer_mem_frame *best_frame = NULL;
+   u32 arch_timer_mem_freq;
+   unsigned int irq;
u32 cnttidr;
+   int i, ret;
 
-   arch_timers_present |= ARCH_TIMER_TYPE_MEM;
-   cntctlbase = of_iomap(np, 0);
+   if (!timer_mem->num_frames)
+   return -ENODEV;
+
+   cntctlbase = ioremap(timer_mem->cntctlbase, timer_mem->size);
if (!cntctlbase) {
-   pr_err("Can't find CNTCTLBase\n");
+   pr_err("Can't map CNTCTLBase.\n");
return -ENXIO;
}
 
@@ -997,26 +1001,18 @@ 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;
-
-   if (of_property_read_u32(frame, "frame-number", )) {
-   pr_err("Missing frame-number\n");
-   of_node_put(frame);
-   goto out;
-   }
+   for (i = 0; i < timer_mem->num_frames; i++) {
+   u32 cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT |
+CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT;
+   int n = timer_mem->frame[i].frame_nr;
 
/* 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));
 
if ((cnttidr & CNTTIDR_VIRT(n)) &&
!(~cntacr & (CNTACR_RWVT | CNTACR_RVCT))) {
-   of_node_put(best_frame);
-   best_frame = frame;
+   best_frame = _mem->frame[i];
arch_timer_mem_use_virtual = true;
break;
}
@@ -1024,56 +1020,126 @@ 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 = _mem->frame[i];
}
+   iounmap(cntctlbase);
 
-   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;
+   if (!best_frame) {
+   pr_err("Can't find frame for register\n");
+   return -EINVAL;
}
 
if (arch_timer_mem_use_virtual)
-   irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_VIRT_SPI);
+   irq = best_frame->virt_irq;
else
-   irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_PHYS_SPI);
+   irq = best_frame->phys_irq;
 
-   ret = -EINVAL;
if (!irq) {
pr_err("Frame missing %s irq.\n",
   arch_timer_mem_use_virtual ? "virt" : "phys");
+   return -EINVAL;
+   }
+
+   if (!request_mem_region(best_frame->cntbase, best_frame->size,
+   

[PATCH v22 06/11] clocksource: arm_arch_timer: refactor MMIO timer probing.

2017-03-21 Thread fu . wei
From: Fu Wei 

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 factors all the DT-specific logic out of arch_timer_mem_init(),
into a new function arch_timer_mem_of_init().
The former pokes the hardware and determines the suitablility of frames
based on a datastructure populated by the latter.

This cleanly separates the two and will make it possible to add probing
using the ACPI GTDT in subsequent patches.

Signed-off-by: Fu Wei 
Reviewed-by: Hanjun Guo 
---
 drivers/clocksource/arm_arch_timer.c | 158 +--
 1 file changed, 112 insertions(+), 46 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c 
b/drivers/clocksource/arm_arch_timer.c
index 4b29a6d..3ada5dc 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -977,17 +977,21 @@ 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 int __init arch_timer_mem_init(struct arch_timer_mem *timer_mem)
 {
-   struct device_node *frame, *best_frame = NULL;
void __iomem *cntctlbase, *base;
-   unsigned int irq, ret = -EINVAL;
+   struct arch_timer_mem_frame *best_frame = NULL;
+   u32 arch_timer_mem_freq;
+   unsigned int irq;
u32 cnttidr;
+   int i, ret;
 
-   arch_timers_present |= ARCH_TIMER_TYPE_MEM;
-   cntctlbase = of_iomap(np, 0);
+   if (!timer_mem->num_frames)
+   return -ENODEV;
+
+   cntctlbase = ioremap(timer_mem->cntctlbase, timer_mem->size);
if (!cntctlbase) {
-   pr_err("Can't find CNTCTLBase\n");
+   pr_err("Can't map CNTCTLBase.\n");
return -ENXIO;
}
 
@@ -997,26 +1001,18 @@ 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;
-
-   if (of_property_read_u32(frame, "frame-number", )) {
-   pr_err("Missing frame-number\n");
-   of_node_put(frame);
-   goto out;
-   }
+   for (i = 0; i < timer_mem->num_frames; i++) {
+   u32 cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT |
+CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT;
+   int n = timer_mem->frame[i].frame_nr;
 
/* 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));
 
if ((cnttidr & CNTTIDR_VIRT(n)) &&
!(~cntacr & (CNTACR_RWVT | CNTACR_RVCT))) {
-   of_node_put(best_frame);
-   best_frame = frame;
+   best_frame = _mem->frame[i];
arch_timer_mem_use_virtual = true;
break;
}
@@ -1024,56 +1020,126 @@ 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 = _mem->frame[i];
}
+   iounmap(cntctlbase);
 
-   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;
+   if (!best_frame) {
+   pr_err("Can't find frame for register\n");
+   return -EINVAL;
}
 
if (arch_timer_mem_use_virtual)
-   irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_VIRT_SPI);
+   irq = best_frame->virt_irq;
else
-   irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_PHYS_SPI);
+   irq = best_frame->phys_irq;
 
-   ret = -EINVAL;
if (!irq) {
pr_err("Frame missing %s irq.\n",
   arch_timer_mem_use_virtual ? "virt" : "phys");
+   return -EINVAL;
+   }
+
+   if (!request_mem_region(best_frame->cntbase, best_frame->size,
+   "arch_mem_timer"))
+   return -EBUSY;
+
+