Message ID | 20170118132541.8989-9-fu.wei@linaro.org (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Hi Fuwei, One comments below. On 2017/1/18 21:25, fu.wei@linaro.org wrote: > From: Fu Wei <fu.wei@linaro.org> > > The counter frequency detection call(arch_timer_detect_rate) combines two > ways to get counter frequency: system coprocessor register and MMIO timer. > But in a specific timer init code, we only need one way to try: > getting frequency from MMIO timer register will be needed only when we > init MMIO timer; getting frequency from system coprocessor register will > be needed only when we init arch timer. > > This patch separates paths to determine frequency: > Separate out the MMIO frequency and the sysreg frequency detection call, > and use the appropriate one for the counter. > > Signed-off-by: Fu Wei <fu.wei@linaro.org> > --- > drivers/clocksource/arm_arch_timer.c | 40 ++++++++++++++++++++++-------------- > 1 file changed, 25 insertions(+), 15 deletions(-) > > diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c > index 6484f84..9482481 100644 > --- a/drivers/clocksource/arm_arch_timer.c > +++ b/drivers/clocksource/arm_arch_timer.c > @@ -488,23 +488,33 @@ static int arch_timer_starting_cpu(unsigned int cpu) > return 0; > } > > -static void arch_timer_detect_rate(void __iomem *cntbase) > +static void __arch_timer_determine_rate(u32 rate) > { > - /* Who has more than one independent system counter? */ > - if (arch_timer_rate) > - return; > + /* Check the timer frequency. */ > + if (!arch_timer_rate) { > + if (rate) > + arch_timer_rate = rate; > + else > + pr_warn("frequency not available\n"); > + } else if (rate && arch_timer_rate != rate) { ^ Typo? I think it's "&" here. Thanks Hanjun -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Hanjun, On 19 January 2017 at 16:02, Hanjun Guo <hanjun.guo@linaro.org> wrote: > Hi Fuwei, > > One comments below. > > > On 2017/1/18 21:25, fu.wei@linaro.org wrote: >> >> From: Fu Wei <fu.wei@linaro.org> >> >> The counter frequency detection call(arch_timer_detect_rate) combines two >> ways to get counter frequency: system coprocessor register and MMIO timer. >> But in a specific timer init code, we only need one way to try: >> getting frequency from MMIO timer register will be needed only when we >> init MMIO timer; getting frequency from system coprocessor register will >> be needed only when we init arch timer. >> >> This patch separates paths to determine frequency: >> Separate out the MMIO frequency and the sysreg frequency detection call, >> and use the appropriate one for the counter. >> >> Signed-off-by: Fu Wei <fu.wei@linaro.org> >> --- >> drivers/clocksource/arm_arch_timer.c | 40 >> ++++++++++++++++++++++-------------- >> 1 file changed, 25 insertions(+), 15 deletions(-) >> >> diff --git a/drivers/clocksource/arm_arch_timer.c >> b/drivers/clocksource/arm_arch_timer.c >> index 6484f84..9482481 100644 >> --- a/drivers/clocksource/arm_arch_timer.c >> +++ b/drivers/clocksource/arm_arch_timer.c >> @@ -488,23 +488,33 @@ static int arch_timer_starting_cpu(unsigned int cpu) >> return 0; >> } >> >> -static void arch_timer_detect_rate(void __iomem *cntbase) >> +static void __arch_timer_determine_rate(u32 rate) >> { >> - /* Who has more than one independent system counter? */ >> - if (arch_timer_rate) >> - return; >> + /* Check the timer frequency. */ >> + if (!arch_timer_rate) { >> + if (rate) >> + arch_timer_rate = rate; >> + else >> + pr_warn("frequency not available\n"); >> + } else if (rate && arch_timer_rate != rate) { > > ^ > Typo? I think it's "&" here. Not a typo, It's definitely a “&&” :-) Here arch_timer_rate is not zero. If rate is not zero(that means we got a valid rate), and arch_timer_rate != rate , we will print warning message. > > Thanks > Hanjun
On 2017/1/19 17:44, Fu Wei wrote: > Hi Hanjun, > > On 19 January 2017 at 16:02, Hanjun Guo <hanjun.guo@linaro.org> wrote: >> Hi Fuwei, >> >> One comments below. >> >> >> On 2017/1/18 21:25, fu.wei@linaro.org wrote: >>> >>> From: Fu Wei <fu.wei@linaro.org> >>> >>> The counter frequency detection call(arch_timer_detect_rate) combines two >>> ways to get counter frequency: system coprocessor register and MMIO timer. >>> But in a specific timer init code, we only need one way to try: >>> getting frequency from MMIO timer register will be needed only when we >>> init MMIO timer; getting frequency from system coprocessor register will >>> be needed only when we init arch timer. >>> >>> This patch separates paths to determine frequency: >>> Separate out the MMIO frequency and the sysreg frequency detection call, >>> and use the appropriate one for the counter. >>> >>> Signed-off-by: Fu Wei <fu.wei@linaro.org> >>> --- >>> drivers/clocksource/arm_arch_timer.c | 40 >>> ++++++++++++++++++++++-------------- >>> 1 file changed, 25 insertions(+), 15 deletions(-) >>> >>> diff --git a/drivers/clocksource/arm_arch_timer.c >>> b/drivers/clocksource/arm_arch_timer.c >>> index 6484f84..9482481 100644 >>> --- a/drivers/clocksource/arm_arch_timer.c >>> +++ b/drivers/clocksource/arm_arch_timer.c >>> @@ -488,23 +488,33 @@ static int arch_timer_starting_cpu(unsigned int cpu) >>> return 0; >>> } >>> >>> -static void arch_timer_detect_rate(void __iomem *cntbase) >>> +static void __arch_timer_determine_rate(u32 rate) >>> { >>> - /* Who has more than one independent system counter? */ >>> - if (arch_timer_rate) >>> - return; >>> + /* Check the timer frequency. */ >>> + if (!arch_timer_rate) { >>> + if (rate) >>> + arch_timer_rate = rate; >>> + else >>> + pr_warn("frequency not available\n"); >>> + } else if (rate && arch_timer_rate != rate) { >> >> ^ >> Typo? I think it's "&" here. > > Not a typo, It's definitely a “&&” :-) > > Here arch_timer_rate is not zero. > > If rate is not zero(that means we got a valid rate), and > arch_timer_rate != rate , > we will print warning message. Ah, misreading the code, thanks for clarify :) Hanjun -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Jan 18, 2017 at 09:25:32PM +0800, fu.wei@linaro.org wrote: > From: Fu Wei <fu.wei@linaro.org> > > The counter frequency detection call(arch_timer_detect_rate) combines two > ways to get counter frequency: system coprocessor register and MMIO timer. > But in a specific timer init code, we only need one way to try: > getting frequency from MMIO timer register will be needed only when we > init MMIO timer; getting frequency from system coprocessor register will > be needed only when we init arch timer. When I mentioned this splitting before, I had mean that we'd completely separate the two, with separate mmio_rate and sysreg_rate variables. The probing logic relying on this is complicated and fragile, and I think these patches are complicating that further (though I appreciate that's far from the intent). I believe we need to split the MMIO and sysreg timer code apart entirely. I've had a look at that today, though it's been fairly painful so far. It appears some platforms may inadvertently be relying on the order and manner in which the rates are probed, which is a major headache. I will try to attack that some more tomorrow. > This patch separates paths to determine frequency: > Separate out the MMIO frequency and the sysreg frequency detection call, > and use the appropriate one for the counter. > > Signed-off-by: Fu Wei <fu.wei@linaro.org> > --- > drivers/clocksource/arm_arch_timer.c | 40 ++++++++++++++++++++++-------------- > 1 file changed, 25 insertions(+), 15 deletions(-) > > diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c > index 6484f84..9482481 100644 > --- a/drivers/clocksource/arm_arch_timer.c > +++ b/drivers/clocksource/arm_arch_timer.c > @@ -488,23 +488,33 @@ static int arch_timer_starting_cpu(unsigned int cpu) > return 0; > } > > -static void arch_timer_detect_rate(void __iomem *cntbase) > +static void __arch_timer_determine_rate(u32 rate) > { > - /* Who has more than one independent system counter? */ > - if (arch_timer_rate) > - return; > + /* Check the timer frequency. */ > + if (!arch_timer_rate) { > + if (rate) > + arch_timer_rate = rate; > + else > + pr_warn("frequency not available\n"); > + } else if (rate && arch_timer_rate != rate) { > + pr_warn("got different frequency, keep original.\n"); > + } > +} This function should be killed off entirely. We need to be able to fail the probe if we cannot determine the rate, and that means we need error handling in the ACPI and DT cases anyway. Thanks, Mark. -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 6484f84..9482481 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -488,23 +488,33 @@ static int arch_timer_starting_cpu(unsigned int cpu) return 0; } -static void arch_timer_detect_rate(void __iomem *cntbase) +static void __arch_timer_determine_rate(u32 rate) { - /* Who has more than one independent system counter? */ - if (arch_timer_rate) - return; + /* Check the timer frequency. */ + if (!arch_timer_rate) { + if (rate) + arch_timer_rate = rate; + else + pr_warn("frequency not available\n"); + } else if (rate && arch_timer_rate != rate) { + pr_warn("got different frequency, keep original.\n"); + } +} +static void arch_timer_detect_rate(void) +{ /* - * Try to determine the frequency from the MMIO timer or the sysreg. + * Try to get the timer frequency from the sysreg CNTFRQ. */ - if (cntbase) - arch_timer_rate = readl_relaxed(cntbase + CNTFRQ); - else - arch_timer_rate = arch_timer_get_cntfrq(); + __arch_timer_determine_rate(arch_timer_get_cntfrq()); +} - /* Check the timer frequency. */ - if (arch_timer_rate == 0) - pr_warn("frequency not available\n"); +static void arch_timer_mem_detect_rate(void __iomem *cntbase) +{ + /* + * Try to get the timer frequency from the CNTFRQ reg of MMIO timer. + */ + __arch_timer_determine_rate(readl_relaxed(cntbase + CNTFRQ)); } static void arch_timer_banner(unsigned type) @@ -887,7 +897,7 @@ static int __init arch_timer_of_init(struct device_node *np) */ if (!arch_timer_rate && of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) - arch_timer_detect_rate(NULL); + arch_timer_detect_rate(); arch_timer_c3stop = !of_property_read_bool(np, "always-on"); @@ -1001,7 +1011,7 @@ static int __init arch_timer_mem_init(struct device_node *np) */ if (!arch_timer_rate && of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) - arch_timer_detect_rate(base); + arch_timer_mem_detect_rate(base); ret = arch_timer_mem_register(base, irq); if (ret) @@ -1064,7 +1074,7 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) gtdt->non_secure_el2_flags); /* Get the frequency from the sysreg CNTFRQ */ - arch_timer_detect_rate(NULL); + arch_timer_detect_rate(); arch_timer_uses_ppi = arch_timer_select_ppi(); if (!arch_timer_ppi[arch_timer_uses_ppi]) {