aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource
diff options
context:
space:
mode:
authorFu Wei <fu.wei@linaro.org>2017-03-21 12:31:13 -0400
committerMark Rutland <mark.rutland@arm.com>2017-04-19 11:11:37 -0400
commit5d3dfa96c7a202f3a70ebeb6f8bb5005c1547250 (patch)
tree7f39f9203a83ad19916378ef7775c64aa4af6622 /drivers/clocksource
parent4502b6bb720d7a519c4cea76cf68a2425b481a45 (diff)
clocksource: arm_arch_timer: split dt-only rate handling
For historical reasons, rate detection when probing via DT is somewhat convoluted. We tried to package this up in arch_timer_detect_rate(), but with the addition of ACPI worse, and gets in the way of stringent rate checking when ACPI is used. This patch makes arch_timer_detect_rate() specific to DT, ripping out ACPI logic. In preparation for rework of the MMIO timer probing, the reading of the relevant CNTFRQ register is factored out to callers. The function is then renamed to arch_timer_of_configure_rate(), which better represents its new place in the world. Comments are added in the DT and ACPI probe paths to explain this. Signed-off-by: Fu Wei <fu.wei@linaro.org> [Mark: reword commit message] Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/arm_arch_timer.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 94de018c65d0..02c5cb86ca83 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -818,24 +818,19 @@ static int arch_timer_starting_cpu(unsigned int cpu)
818 return 0; 818 return 0;
819} 819}
820 820
821static void 821/*
822arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np) 822 * For historical reasons, when probing with DT we use whichever (non-zero)
823 * rate was probed first, and don't verify that others match. If the first node
824 * probed has a clock-frequency property, this overrides the HW register.
825 */
826static void arch_timer_of_configure_rate(u32 rate, struct device_node *np)
823{ 827{
824 /* Who has more than one independent system counter? */ 828 /* Who has more than one independent system counter? */
825 if (arch_timer_rate) 829 if (arch_timer_rate)
826 return; 830 return;
827 831
828 /* 832 if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
829 * Try to determine the frequency from the device tree or CNTFRQ, 833 arch_timer_rate = rate;
830 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
831 */
832 if (!acpi_disabled ||
833 of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
834 if (cntbase)
835 arch_timer_rate = readl_relaxed(cntbase + CNTFRQ);
836 else
837 arch_timer_rate = arch_timer_get_cntfrq();
838 }
839 834
840 /* Check the timer frequency. */ 835 /* Check the timer frequency. */
841 if (arch_timer_rate == 0) 836 if (arch_timer_rate == 0)
@@ -1166,6 +1161,7 @@ static int __init arch_timer_init(void)
1166static int __init arch_timer_of_init(struct device_node *np) 1161static int __init arch_timer_of_init(struct device_node *np)
1167{ 1162{
1168 int i; 1163 int i;
1164 u32 rate;
1169 1165
1170 if (arch_timers_present & ARCH_TIMER_TYPE_CP15) { 1166 if (arch_timers_present & ARCH_TIMER_TYPE_CP15) {
1171 pr_warn("multiple nodes in dt, skipping\n"); 1167 pr_warn("multiple nodes in dt, skipping\n");
@@ -1176,7 +1172,8 @@ static int __init arch_timer_of_init(struct device_node *np)
1176 for (i = ARCH_TIMER_PHYS_SECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++) 1172 for (i = ARCH_TIMER_PHYS_SECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++)
1177 arch_timer_ppi[i] = irq_of_parse_and_map(np, i); 1173 arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
1178 1174
1179 arch_timer_detect_rate(NULL, np); 1175 rate = arch_timer_get_cntfrq;
1176 arch_timer_of_configure_rate(rate, np);
1180 1177
1181 arch_timer_c3stop = !of_property_read_bool(np, "always-on"); 1178 arch_timer_c3stop = !of_property_read_bool(np, "always-on");
1182 1179
@@ -1212,7 +1209,7 @@ static int __init arch_timer_mem_init(struct device_node *np)
1212 struct device_node *frame, *best_frame = NULL; 1209 struct device_node *frame, *best_frame = NULL;
1213 void __iomem *cntctlbase, *base; 1210 void __iomem *cntctlbase, *base;
1214 unsigned int irq, ret = -EINVAL; 1211 unsigned int irq, ret = -EINVAL;
1215 u32 cnttidr; 1212 u32 cnttidr, rate;
1216 1213
1217 arch_timers_present |= ARCH_TIMER_TYPE_MEM; 1214 arch_timers_present |= ARCH_TIMER_TYPE_MEM;
1218 cntctlbase = of_iomap(np, 0); 1215 cntctlbase = of_iomap(np, 0);
@@ -1278,7 +1275,8 @@ static int __init arch_timer_mem_init(struct device_node *np)
1278 goto out; 1275 goto out;
1279 } 1276 }
1280 1277
1281 arch_timer_detect_rate(base, np); 1278 rate = readl(base + CNTFRQ);
1279 arch_timer_of_configure_rate(rate, np);
1282 ret = arch_timer_mem_register(base, irq); 1280 ret = arch_timer_mem_register(base, irq);
1283 if (ret) 1281 if (ret)
1284 goto out; 1282 goto out;
@@ -1339,8 +1337,15 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
1339 map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt, 1337 map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt,
1340 gtdt->non_secure_el2_flags); 1338 gtdt->non_secure_el2_flags);
1341 1339
1342 /* Get the frequency from CNTFRQ */ 1340 /*
1343 arch_timer_detect_rate(NULL, NULL); 1341 * When probing via ACPI, we have no mechanism to override the sysreg
1342 * CNTFRQ value. This *must* be correct.
1343 */
1344 arch_timer_rate = arch_timer_get_cntfrq();
1345 if (!arch_timer_rate) {
1346 pr_err(FW_BUG "frequency not available.\n");
1347 return -EINVAL;
1348 }
1344 1349
1345 arch_timer_uses_ppi = arch_timer_select_ppi(); 1350 arch_timer_uses_ppi = arch_timer_select_ppi();
1346 if (!arch_timer_ppi[arch_timer_uses_ppi]) { 1351 if (!arch_timer_ppi[arch_timer_uses_ppi]) {