Re: Click source driver
On Saturday 11 June 2016 01:12 AM, Noam Camus wrote: > > Hi Vineet, > > I am updating my clocksource driver to include support of timer0 for > clockevents. > > My current version uses arc-timer driver for clockevents. > > I noticed that arc-timer driver appears twice in DTS file so first one will > invoke initialization of clockevent and second the clocksource. Please note > that > both update same global variable arc_timer_freq and you can end up with > different value from clocksource used by clockevent for secondaries CPUs. > Can you please elaborate this a bit more - where/how exactly is timer freq different for NPS ? > So my updated driver will like today will use arc-timer clickevent for > simulator > and for real chip it will be used for both clocksource and clockevent. > Again I'm not sure if I understand this - why do u need to make this distinctions for sim vs. real chip ! > How do you suggest to achieve that? > > Using arc-timer technique of double nodes at DTS or just single node to init > both of them > the current arc timer driver expects to be called twice - i.e. 2 DT nodes for "snps,arc-timer" - for first it processes clockevent, for second it does clocksource. If u instantiate it only once, only clockevent will be called. I'm sorry but I don't understand the issue here ! -Vineet ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
RE: Click source driver
>From: Vineet Gupta [mailto:vineet.gup...@synopsys.com] >Sent: Tuesday, June 28, 2016 11:32 AM >> I noticed that arc-timer driver appears twice in DTS file so first one >> will invoke initialization of clockevent and second the clocksource. >> Please note that both update same global variable arc_timer_freq and >> you can end up with different value from clocksource used by clockevent for >> secondaries CPUs. >> >Can you please elaborate this a bit more - where/how exactly is timer freq >different for NPS ? In NPS chip the timer0 is shared among all HW threads from the same core. There is also dedicated design for choosing which threads will get the timer interrupt when it arrives. This is different from ARC700. In simulator we use regular ARC700 cores without simulating this HW behavior so generic ARC driver is good for us when working with simulator. See below link for patch I use and going to upstream: https://github.com/Mellanox/linux/commit/94f1b4d7b28634ce579101aa79e9853566883536 >> So my updated driver will like today will use arc-timer clickevent for >> simulator and for real chip it will be used for both clocksource and >> clockevent. >> >Again I'm not sure if I understand this - why do u need to make this >distinctions for sim vs. real chip ! I hope above clarifying things >> How do you suggest to achieve that? >> >> Using arc-timer technique of double nodes at DTS or just single node >> to init both of them >> >the current arc timer driver expects to be called twice - i.e. 2 DT nodes for >"snps,arc-timer" - for first it processes clockevent, for second it does >clocksource. If u instantiate it only once, only clockevent will be called. >I'm sorry but I don't understand the issue here ! >From above link to my patch you can see that I choose to have 2 separate >"compatiable" implementations one for timer0 and another for timer1. This way >I can separate the origin clock each one uses. In your case (I believe so) the order of " snps,arc-timer" at DTS files is important and since for both you call arc_get_timer_clk() which in turn update same global variable called arc_timer_freq. So if in your DTS file each node got different clocks=, then second node will override this value set by first node. -Noam ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH 70/92] clocksource/drivers/arc: Convert init function to return error
The init functions do not return any error. They behave as the following: - panic, thus leading to a kernel crash while another timer may work and make the system boot up correctly or - print an error and let the caller unaware if the state of the system Change that by converting the init functions to return an error conforming to the CLOCKSOURCE_OF_RET prototype. Proper error handling (rollback, errno value) will be changed later case by case, thus this change just return back an error or success in the init function. Signed-off-by: Daniel Lezcano --- arch/arc/kernel/time.c | 69 ++ 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 4549ab2..09de669 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -116,21 +116,21 @@ static struct clocksource arc_counter_gfrc = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init arc_cs_setup_gfrc(struct device_node *node) +static int __init arc_cs_setup_gfrc(struct device_node *node) { int exists = cpuinfo_arc700[0].extn.gfrc; int ret; if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected")) - return; + return -ENXIO; ret = arc_get_timer_clk(node); if (ret) - return; + return ret; - clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); + return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); } -CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); +CLOCKSOURCE_OF_DECLARE_RET(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); #endif @@ -172,27 +172,27 @@ static struct clocksource arc_counter_rtc = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init arc_cs_setup_rtc(struct device_node *node) +static int __init arc_cs_setup_rtc(struct device_node *node) { int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc; int ret; if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected")) - return; + return -ENXIO; /* Local to CPU hence not usable in SMP */ if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP")) - return; + return -EINVAL; ret = arc_get_timer_clk(node); if (ret) - return; + return ret; write_aux_reg(AUX_RTC_CTRL, 1); - clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); + return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); } -CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); +CLOCKSOURCE_OF_DECLARE_RET(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); #endif @@ -213,23 +213,23 @@ static struct clocksource arc_counter_timer1 = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init arc_cs_setup_timer1(struct device_node *node) +static int __init arc_cs_setup_timer1(struct device_node *node) { int ret; /* Local to CPU hence not usable in SMP */ if (IS_ENABLED(CONFIG_SMP)) - return; + return -EINVAL; ret = arc_get_timer_clk(node); if (ret) - return; + return ret; write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); write_aux_reg(ARC_REG_TIMER1_CNT, 0); write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); - clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); + return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); } /** Clock Event Device */ @@ -324,20 +324,28 @@ static struct notifier_block arc_timer_cpu_nb = { /* * clockevent setup for boot CPU */ -static void __init arc_clockevent_setup(struct device_node *node) +static int __init arc_clockevent_setup(struct device_node *node) { struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); int ret; - register_cpu_notifier(&arc_timer_cpu_nb); + ret = register_cpu_notifier(&arc_timer_cpu_nb); + if (ret) { + pr_err("Failed to register cpu notifier"); + return ret; + } arc_timer_irq = irq_of_parse_and_map(node, 0); - if (arc_timer_irq <= 0) - panic("clockevent: missing irq"); + if (arc_timer_irq <= 0) { + pr_err("clockevent: missing irq"); + return -EINVAL; + } ret = arc_get_timer_clk(node); - if (ret) - panic("clockevent: missing clk"); + if (ret) { + pr_err("clockevent: missing clk"); + return ret; + } evt->irq = arc_timer_irq; evt->cpumask = cpumask_of(smp_processor_id()); @@ -347,24 +355,31 @@ static void __init arc_clockevent_setup(struct device_node *node) /* Needs
[PATCH 72/92] clocksources: Switch back to the clksrc table
All the clocksource drivers's init function are now converted to return an error code. CLOCKSOURCE_OF_DECLARE is no longer used as well as the clksrc-of table. Let's convert back the names: - CLOCKSOURCE_OF_DECLARE_RET => CLOCKSOURCE_OF_DECLARE - clksrc-of-ret => clksrc-of Signed-off-by: Daniel Lezcano For exynos_mct and samsung_pwm_timer: Acked-by: Krzysztof Kozlowski For arch/arc: Acked-by: Vineet Gupta For mediatek driver: Acked-by: Matthias Brugger For the Rockchip-part Acked-by: Heiko Stuebner For STi : Acked-by: Patrice Chotard For the mps2-timer.c and versatile.c changes: Acked-by: Liviu Dudau For the OXNAS part : Acked-by: Neil Armstrong For LPC32xx driver: Acked-by: Sylvain Lemieux For Broadcom Kona timer change: Acked-by: Ray Jui For Sun4i and Sun5i: Acked-by: Chen-Yu Tsai For Meson6: Acked-by: Carlo Caione For Keystone: Acked-by: Santosh Shilimkar For NPS: Acked-by: Noam Camus For bcm2835: Acked-by: Eric Anholt --- arch/arc/kernel/time.c| 6 +++--- arch/arm/kernel/smp_twd.c | 6 +++--- arch/microblaze/kernel/timer.c| 2 +- arch/mips/ralink/cevt-rt3352.c| 2 +- arch/nios2/kernel/time.c | 2 +- drivers/clocksource/arm_arch_timer.c | 6 +++--- drivers/clocksource/arm_global_timer.c| 2 +- drivers/clocksource/armv7m_systick.c | 2 +- drivers/clocksource/asm9260_timer.c | 2 +- drivers/clocksource/bcm2835_timer.c | 2 +- drivers/clocksource/bcm_kona_timer.c | 4 ++-- drivers/clocksource/cadence_ttc_timer.c | 2 +- drivers/clocksource/clksrc-dbx500-prcmu.c | 2 +- drivers/clocksource/clksrc-probe.c| 14 -- drivers/clocksource/clksrc_st_lpc.c | 2 +- drivers/clocksource/clps711x-timer.c | 2 +- drivers/clocksource/dw_apb_timer_of.c | 8 drivers/clocksource/exynos_mct.c | 4 ++-- drivers/clocksource/fsl_ftm_timer.c | 2 +- drivers/clocksource/h8300_timer16.c | 2 +- drivers/clocksource/h8300_timer8.c| 2 +- drivers/clocksource/h8300_tpu.c | 2 +- drivers/clocksource/meson6_timer.c| 2 +- drivers/clocksource/mips-gic-timer.c | 2 +- drivers/clocksource/moxart_timer.c| 2 +- drivers/clocksource/mps2-timer.c | 2 +- drivers/clocksource/mtk_timer.c | 2 +- drivers/clocksource/mxs_timer.c | 2 +- drivers/clocksource/nomadik-mtu.c | 2 +- drivers/clocksource/pxa_timer.c | 2 +- drivers/clocksource/qcom-timer.c | 4 ++-- drivers/clocksource/rockchip_timer.c | 8 drivers/clocksource/samsung_pwm_timer.c | 8 drivers/clocksource/sun4i_timer.c | 2 +- drivers/clocksource/tango_xtal.c | 2 +- drivers/clocksource/tegra20_timer.c | 4 ++-- drivers/clocksource/time-armada-370-xp.c | 6 +++--- drivers/clocksource/time-efm32.c | 4 ++-- drivers/clocksource/time-lpc32xx.c| 2 +- drivers/clocksource/time-orion.c | 2 +- drivers/clocksource/time-pistachio.c | 2 +- drivers/clocksource/timer-atlas7.c| 2 +- drivers/clocksource/timer-atmel-pit.c | 2 +- drivers/clocksource/timer-atmel-st.c | 2 +- drivers/clocksource/timer-digicolor.c | 2 +- drivers/clocksource/timer-imx-gpt.c | 24 drivers/clocksource/timer-integrator-ap.c | 2 +- drivers/clocksource/timer-keystone.c | 2 +- drivers/clocksource/timer-nps.c | 4 ++-- drivers/clocksource/timer-oxnas-rps.c | 4 ++-- drivers/clocksource/timer-prima2.c| 2 +- drivers/clocksource/timer-sp804.c | 4 ++-- drivers/clocksource/timer-stm32.c | 2 +- drivers/clocksource/timer-sun5i.c | 4 ++-- drivers/clocksource/timer-ti-32k.c| 2 +- drivers/clocksource/timer-u300.c | 2 +- drivers/clocksource/versatile.c | 4 ++-- drivers/clocksource/vf_pit_timer.c| 2 +- drivers/clocksource/vt8500_timer.c| 2 +- drivers/clocksource/zevio-timer.c | 2 +- include/asm-generic/vmlinux.lds.h | 2 -- include/linux/clocksource.h | 5 + 62 files changed, 98 insertions(+), 117 deletions(-) diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 09de669..98f22d2 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -130,7 +130,7 @@ static int __init arc_cs_setup_gfrc(struct device_node *node) return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); } -CLOCKSOURCE_OF_DECLARE_RET(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); +CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); #endif @@ -192,7 +192,7 @@ static int __init arc_cs_setup_rtc(struct device_node *node) return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); } -CLOCKSOURCE_OF_DECLARE_RET(arc_rtc, "snps,archs-timer-rtc