diff options
24 files changed, 295 insertions, 47 deletions
diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt new file mode 100644 index 000000000000..7c26154b8bbb --- /dev/null +++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | Allwinner SoCs High Speed Timer Controller | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible : should be "allwinner,sun5i-a13-hstimer" or | ||
| 6 | "allwinner,sun7i-a20-hstimer" | ||
| 7 | - reg : Specifies base physical address and size of the registers. | ||
| 8 | - interrupts : The interrupts of these timers (2 for the sun5i IP, 4 for the sun7i | ||
| 9 | one) | ||
| 10 | - clocks: phandle to the source clock (usually the AHB clock) | ||
| 11 | |||
| 12 | Example: | ||
| 13 | |||
| 14 | timer@01c60000 { | ||
| 15 | compatible = "allwinner,sun7i-a20-hstimer"; | ||
| 16 | reg = <0x01c60000 0x1000>; | ||
| 17 | interrupts = <0 51 1>, | ||
| 18 | <0 52 1>, | ||
| 19 | <0 53 1>, | ||
| 20 | <0 54 1>; | ||
| 21 | clocks = <&ahb1_gates 19>; | ||
| 22 | }; | ||
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 52476742a104..e674c94c7206 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi | |||
| @@ -332,5 +332,12 @@ | |||
| 332 | clock-frequency = <100000>; | 332 | clock-frequency = <100000>; |
| 333 | status = "disabled"; | 333 | status = "disabled"; |
| 334 | }; | 334 | }; |
| 335 | |||
| 336 | timer@01c60000 { | ||
| 337 | compatible = "allwinner,sun5i-a13-hstimer"; | ||
| 338 | reg = <0x01c60000 0x1000>; | ||
| 339 | interrupts = <82>, <83>; | ||
| 340 | clocks = <&ahb_gates 28>; | ||
| 341 | }; | ||
| 335 | }; | 342 | }; |
| 336 | }; | 343 | }; |
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index ce8ef2a45be0..1ccd75d37f49 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi | |||
| @@ -273,5 +273,12 @@ | |||
| 273 | clock-frequency = <100000>; | 273 | clock-frequency = <100000>; |
| 274 | status = "disabled"; | 274 | status = "disabled"; |
| 275 | }; | 275 | }; |
| 276 | |||
| 277 | timer@01c60000 { | ||
| 278 | compatible = "allwinner,sun5i-a13-hstimer"; | ||
| 279 | reg = <0x01c60000 0x1000>; | ||
| 280 | interrupts = <82>, <83>; | ||
| 281 | clocks = <&ahb_gates 28>; | ||
| 282 | }; | ||
| 276 | }; | 283 | }; |
| 277 | }; | 284 | }; |
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 367611a0730b..0135039eff96 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi | |||
| @@ -395,6 +395,16 @@ | |||
| 395 | status = "disabled"; | 395 | status = "disabled"; |
| 396 | }; | 396 | }; |
| 397 | 397 | ||
| 398 | hstimer@01c60000 { | ||
| 399 | compatible = "allwinner,sun7i-a20-hstimer"; | ||
| 400 | reg = <0x01c60000 0x1000>; | ||
| 401 | interrupts = <0 81 1>, | ||
| 402 | <0 82 1>, | ||
| 403 | <0 83 1>, | ||
| 404 | <0 84 1>; | ||
| 405 | clocks = <&ahb_gates 28>; | ||
| 406 | }; | ||
| 407 | |||
| 398 | gic: interrupt-controller@01c81000 { | 408 | gic: interrupt-controller@01c81000 { |
| 399 | compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; | 409 | compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; |
| 400 | reg = <0x01c81000 0x1000>, | 410 | reg = <0x01c81000 0x1000>, |
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index c9e72c89066a..bce0d4277f71 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig | |||
| @@ -12,3 +12,4 @@ config ARCH_SUNXI | |||
| 12 | select PINCTRL_SUNXI | 12 | select PINCTRL_SUNXI |
| 13 | select SPARSE_IRQ | 13 | select SPARSE_IRQ |
| 14 | select SUN4I_TIMER | 14 | select SUN4I_TIMER |
| 15 | select SUN5I_HSTIMER | ||
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 634c4d6dd45a..cd6950fd8caf 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
| @@ -37,6 +37,10 @@ config SUN4I_TIMER | |||
| 37 | select CLKSRC_MMIO | 37 | select CLKSRC_MMIO |
| 38 | bool | 38 | bool |
| 39 | 39 | ||
| 40 | config SUN5I_HSTIMER | ||
| 41 | select CLKSRC_MMIO | ||
| 42 | bool | ||
| 43 | |||
| 40 | config VT8500_TIMER | 44 | config VT8500_TIMER |
| 41 | bool | 45 | bool |
| 42 | 46 | ||
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 33621efb9148..358358d87b6d 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
| @@ -22,6 +22,7 @@ obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o | |||
| 22 | obj-$(CONFIG_ARCH_MXS) += mxs_timer.o | 22 | obj-$(CONFIG_ARCH_MXS) += mxs_timer.o |
| 23 | obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o | 23 | obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o |
| 24 | obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o | 24 | obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o |
| 25 | obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o | ||
| 25 | obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o | 26 | obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o |
| 26 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o | 27 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o |
| 27 | obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o | 28 | obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o |
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index c639b1a9e996..0fc31d029e52 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c | |||
| @@ -202,7 +202,7 @@ static struct clocksource gt_clocksource = { | |||
| 202 | }; | 202 | }; |
| 203 | 203 | ||
| 204 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK | 204 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK |
| 205 | static u32 notrace gt_sched_clock_read(void) | 205 | static u64 notrace gt_sched_clock_read(void) |
| 206 | { | 206 | { |
| 207 | return gt_counter_read(); | 207 | return gt_counter_read(); |
| 208 | } | 208 | } |
| @@ -217,7 +217,7 @@ static void __init gt_clocksource_init(void) | |||
| 217 | writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL); | 217 | writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL); |
| 218 | 218 | ||
| 219 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK | 219 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK |
| 220 | setup_sched_clock(gt_sched_clock_read, 32, gt_clk_rate); | 220 | sched_clock_register(gt_sched_clock_read, 64, gt_clk_rate); |
| 221 | #endif | 221 | #endif |
| 222 | clocksource_register_hz(>_clocksource, gt_clk_rate); | 222 | clocksource_register_hz(>_clocksource, gt_clk_rate); |
| 223 | } | 223 | } |
diff --git a/drivers/clocksource/bcm_kona_timer.c b/drivers/clocksource/bcm_kona_timer.c index 0d7d8c3ed6b2..5176e761166b 100644 --- a/drivers/clocksource/bcm_kona_timer.c +++ b/drivers/clocksource/bcm_kona_timer.c | |||
| @@ -98,12 +98,6 @@ kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw) | |||
| 98 | return; | 98 | return; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static const struct of_device_id bcm_timer_ids[] __initconst = { | ||
| 102 | {.compatible = "brcm,kona-timer"}, | ||
| 103 | {.compatible = "bcm,kona-timer"}, /* deprecated name */ | ||
| 104 | {}, | ||
| 105 | }; | ||
| 106 | |||
| 107 | static void __init kona_timers_init(struct device_node *node) | 101 | static void __init kona_timers_init(struct device_node *node) |
| 108 | { | 102 | { |
| 109 | u32 freq; | 103 | u32 freq; |
diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c index b2bb3a4bc205..8c7382bf260c 100644 --- a/drivers/clocksource/cadence_ttc_timer.c +++ b/drivers/clocksource/cadence_ttc_timer.c | |||
| @@ -158,7 +158,7 @@ static cycle_t __ttc_clocksource_read(struct clocksource *cs) | |||
| 158 | TTC_COUNT_VAL_OFFSET); | 158 | TTC_COUNT_VAL_OFFSET); |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | static u32 notrace ttc_sched_clock_read(void) | 161 | static u64 notrace ttc_sched_clock_read(void) |
| 162 | { | 162 | { |
| 163 | return __raw_readl(ttc_sched_clock_val_reg); | 163 | return __raw_readl(ttc_sched_clock_val_reg); |
| 164 | } | 164 | } |
| @@ -306,7 +306,7 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base) | |||
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; | 308 | ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; |
| 309 | setup_sched_clock(ttc_sched_clock_read, 16, | 309 | sched_clock_register(ttc_sched_clock_read, 16, |
| 310 | clk_get_rate(ttccs->ttc.clk) / PRESCALE); | 310 | clk_get_rate(ttccs->ttc.clk) / PRESCALE); |
| 311 | } | 311 | } |
| 312 | 312 | ||
| @@ -388,8 +388,7 @@ static void __init ttc_setup_clockevent(struct clk *clk, | |||
| 388 | __raw_writel(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET); | 388 | __raw_writel(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET); |
| 389 | 389 | ||
| 390 | err = request_irq(irq, ttc_clock_event_interrupt, | 390 | err = request_irq(irq, ttc_clock_event_interrupt, |
| 391 | IRQF_DISABLED | IRQF_TIMER, | 391 | IRQF_TIMER, ttcce->ce.name, ttcce); |
| 392 | ttcce->ce.name, ttcce); | ||
| 393 | if (WARN_ON(err)) { | 392 | if (WARN_ON(err)) { |
| 394 | kfree(ttcce); | 393 | kfree(ttcce); |
| 395 | return; | 394 | return; |
diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c index b9ddd9e3a2f5..ae2e4278c42a 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-of.c | |||
| @@ -28,6 +28,7 @@ void __init clocksource_of_init(void) | |||
| 28 | struct device_node *np; | 28 | struct device_node *np; |
| 29 | const struct of_device_id *match; | 29 | const struct of_device_id *match; |
| 30 | clocksource_of_init_fn init_func; | 30 | clocksource_of_init_fn init_func; |
| 31 | unsigned clocksources = 0; | ||
| 31 | 32 | ||
| 32 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { | 33 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { |
| 33 | if (!of_device_is_available(np)) | 34 | if (!of_device_is_available(np)) |
| @@ -35,5 +36,8 @@ void __init clocksource_of_init(void) | |||
| 35 | 36 | ||
| 36 | init_func = match->data; | 37 | init_func = match->data; |
| 37 | init_func(np); | 38 | init_func(np); |
| 39 | clocksources++; | ||
| 38 | } | 40 | } |
| 41 | if (!clocksources) | ||
| 42 | pr_crit("%s: no matching clocksources found\n", __func__); | ||
| 39 | } | 43 | } |
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c index ea210482dd20..db2105290898 100644 --- a/drivers/clocksource/cs5535-clockevt.c +++ b/drivers/clocksource/cs5535-clockevt.c | |||
| @@ -131,7 +131,7 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) | |||
| 131 | 131 | ||
| 132 | static struct irqaction mfgptirq = { | 132 | static struct irqaction mfgptirq = { |
| 133 | .handler = mfgpt_tick, | 133 | .handler = mfgpt_tick, |
| 134 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER | IRQF_SHARED, | 134 | .flags = IRQF_NOBALANCING | IRQF_TIMER | IRQF_SHARED, |
| 135 | .name = DRV_NAME, | 135 | .name = DRV_NAME, |
| 136 | }; | 136 | }; |
| 137 | 137 | ||
diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c index e54ca1062d8e..f3656a6b0382 100644 --- a/drivers/clocksource/dw_apb_timer.c +++ b/drivers/clocksource/dw_apb_timer.c | |||
| @@ -243,8 +243,7 @@ dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, | |||
| 243 | dw_ced->irqaction.dev_id = &dw_ced->ced; | 243 | dw_ced->irqaction.dev_id = &dw_ced->ced; |
| 244 | dw_ced->irqaction.irq = irq; | 244 | dw_ced->irqaction.irq = irq; |
| 245 | dw_ced->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | | 245 | dw_ced->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | |
| 246 | IRQF_NOBALANCING | | 246 | IRQF_NOBALANCING; |
| 247 | IRQF_DISABLED; | ||
| 248 | 247 | ||
| 249 | dw_ced->eoi = apbt_eoi; | 248 | dw_ced->eoi = apbt_eoi; |
| 250 | err = setup_irq(irq, &dw_ced->irqaction); | 249 | err = setup_irq(irq, &dw_ced->irqaction); |
diff --git a/drivers/clocksource/nomadik-mtu.c b/drivers/clocksource/nomadik-mtu.c index ed7b73b508e0..152a3f3875ee 100644 --- a/drivers/clocksource/nomadik-mtu.c +++ b/drivers/clocksource/nomadik-mtu.c | |||
| @@ -187,7 +187,7 @@ static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id) | |||
| 187 | 187 | ||
| 188 | static struct irqaction nmdk_timer_irq = { | 188 | static struct irqaction nmdk_timer_irq = { |
| 189 | .name = "Nomadik Timer Tick", | 189 | .name = "Nomadik Timer Tick", |
| 190 | .flags = IRQF_DISABLED | IRQF_TIMER, | 190 | .flags = IRQF_TIMER, |
| 191 | .handler = nmdk_timer_interrupt, | 191 | .handler = nmdk_timer_interrupt, |
| 192 | .dev_id = &nmdk_clkevt, | 192 | .dev_id = &nmdk_clkevt, |
| 193 | }; | 193 | }; |
diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c index 85082e8d3052..5645cfc90c41 100644 --- a/drivers/clocksource/samsung_pwm_timer.c +++ b/drivers/clocksource/samsung_pwm_timer.c | |||
| @@ -264,7 +264,7 @@ static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id) | |||
| 264 | 264 | ||
| 265 | static struct irqaction samsung_clock_event_irq = { | 265 | static struct irqaction samsung_clock_event_irq = { |
| 266 | .name = "samsung_time_irq", | 266 | .name = "samsung_time_irq", |
| 267 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 267 | .flags = IRQF_TIMER | IRQF_IRQPOLL, |
| 268 | .handler = samsung_clock_event_isr, | 268 | .handler = samsung_clock_event_isr, |
| 269 | .dev_id = &time_event_device, | 269 | .dev_id = &time_event_device, |
| 270 | }; | 270 | }; |
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 0965e9848b3d..0b1836a6c539 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
| @@ -634,12 +634,18 @@ static int sh_cmt_clock_event_next(unsigned long delta, | |||
| 634 | 634 | ||
| 635 | static void sh_cmt_clock_event_suspend(struct clock_event_device *ced) | 635 | static void sh_cmt_clock_event_suspend(struct clock_event_device *ced) |
| 636 | { | 636 | { |
| 637 | pm_genpd_syscore_poweroff(&ced_to_sh_cmt(ced)->pdev->dev); | 637 | struct sh_cmt_priv *p = ced_to_sh_cmt(ced); |
| 638 | |||
| 639 | pm_genpd_syscore_poweroff(&p->pdev->dev); | ||
| 640 | clk_unprepare(p->clk); | ||
| 638 | } | 641 | } |
| 639 | 642 | ||
| 640 | static void sh_cmt_clock_event_resume(struct clock_event_device *ced) | 643 | static void sh_cmt_clock_event_resume(struct clock_event_device *ced) |
| 641 | { | 644 | { |
| 642 | pm_genpd_syscore_poweron(&ced_to_sh_cmt(ced)->pdev->dev); | 645 | struct sh_cmt_priv *p = ced_to_sh_cmt(ced); |
| 646 | |||
| 647 | clk_prepare(p->clk); | ||
| 648 | pm_genpd_syscore_poweron(&p->pdev->dev); | ||
| 643 | } | 649 | } |
| 644 | 650 | ||
| 645 | static void sh_cmt_register_clockevent(struct sh_cmt_priv *p, | 651 | static void sh_cmt_register_clockevent(struct sh_cmt_priv *p, |
| @@ -726,8 +732,7 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | |||
| 726 | p->irqaction.name = dev_name(&p->pdev->dev); | 732 | p->irqaction.name = dev_name(&p->pdev->dev); |
| 727 | p->irqaction.handler = sh_cmt_interrupt; | 733 | p->irqaction.handler = sh_cmt_interrupt; |
| 728 | p->irqaction.dev_id = p; | 734 | p->irqaction.dev_id = p; |
| 729 | p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \ | 735 | p->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING; |
| 730 | IRQF_IRQPOLL | IRQF_NOBALANCING; | ||
| 731 | 736 | ||
| 732 | /* get hold of clock */ | 737 | /* get hold of clock */ |
| 733 | p->clk = clk_get(&p->pdev->dev, "cmt_fck"); | 738 | p->clk = clk_get(&p->pdev->dev, "cmt_fck"); |
| @@ -737,6 +742,10 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | |||
| 737 | goto err2; | 742 | goto err2; |
| 738 | } | 743 | } |
| 739 | 744 | ||
| 745 | ret = clk_prepare(p->clk); | ||
| 746 | if (ret < 0) | ||
| 747 | goto err3; | ||
| 748 | |||
| 740 | if (res2 && (resource_size(res2) == 4)) { | 749 | if (res2 && (resource_size(res2) == 4)) { |
| 741 | /* assume both CMSTR and CMCSR to be 32-bit */ | 750 | /* assume both CMSTR and CMCSR to be 32-bit */ |
| 742 | p->read_control = sh_cmt_read32; | 751 | p->read_control = sh_cmt_read32; |
| @@ -773,19 +782,21 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | |||
| 773 | cfg->clocksource_rating); | 782 | cfg->clocksource_rating); |
| 774 | if (ret) { | 783 | if (ret) { |
| 775 | dev_err(&p->pdev->dev, "registration failed\n"); | 784 | dev_err(&p->pdev->dev, "registration failed\n"); |
| 776 | goto err3; | 785 | goto err4; |
| 777 | } | 786 | } |
| 778 | p->cs_enabled = false; | 787 | p->cs_enabled = false; |
| 779 | 788 | ||
| 780 | ret = setup_irq(irq, &p->irqaction); | 789 | ret = setup_irq(irq, &p->irqaction); |
| 781 | if (ret) { | 790 | if (ret) { |
| 782 | dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); | 791 | dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); |
| 783 | goto err3; | 792 | goto err4; |
| 784 | } | 793 | } |
| 785 | 794 | ||
| 786 | platform_set_drvdata(pdev, p); | 795 | platform_set_drvdata(pdev, p); |
| 787 | 796 | ||
| 788 | return 0; | 797 | return 0; |
| 798 | err4: | ||
| 799 | clk_unprepare(p->clk); | ||
| 789 | err3: | 800 | err3: |
| 790 | clk_put(p->clk); | 801 | clk_put(p->clk); |
| 791 | err2: | 802 | err2: |
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 3cf12834681e..e30d76e0a6fa 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c | |||
| @@ -302,8 +302,7 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) | |||
| 302 | p->irqaction.handler = sh_mtu2_interrupt; | 302 | p->irqaction.handler = sh_mtu2_interrupt; |
| 303 | p->irqaction.dev_id = p; | 303 | p->irqaction.dev_id = p; |
| 304 | p->irqaction.irq = irq; | 304 | p->irqaction.irq = irq; |
| 305 | p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \ | 305 | p->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING; |
| 306 | IRQF_IRQPOLL | IRQF_NOBALANCING; | ||
| 307 | 306 | ||
| 308 | /* get hold of clock */ | 307 | /* get hold of clock */ |
| 309 | p->clk = clk_get(&p->pdev->dev, "mtu2_fck"); | 308 | p->clk = clk_get(&p->pdev->dev, "mtu2_fck"); |
| @@ -358,7 +357,6 @@ static int sh_mtu2_probe(struct platform_device *pdev) | |||
| 358 | ret = sh_mtu2_setup(p, pdev); | 357 | ret = sh_mtu2_setup(p, pdev); |
| 359 | if (ret) { | 358 | if (ret) { |
| 360 | kfree(p); | 359 | kfree(p); |
| 361 | platform_set_drvdata(pdev, NULL); | ||
| 362 | pm_runtime_idle(&pdev->dev); | 360 | pm_runtime_idle(&pdev->dev); |
| 363 | return ret; | 361 | return ret; |
| 364 | } | 362 | } |
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 63557cda0a7d..ecd7b60bfdfa 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c | |||
| @@ -462,8 +462,7 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) | |||
| 462 | p->irqaction.handler = sh_tmu_interrupt; | 462 | p->irqaction.handler = sh_tmu_interrupt; |
| 463 | p->irqaction.dev_id = p; | 463 | p->irqaction.dev_id = p; |
| 464 | p->irqaction.irq = irq; | 464 | p->irqaction.irq = irq; |
| 465 | p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \ | 465 | p->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING; |
| 466 | IRQF_IRQPOLL | IRQF_NOBALANCING; | ||
| 467 | 466 | ||
| 468 | /* get hold of clock */ | 467 | /* get hold of clock */ |
| 469 | p->clk = clk_get(&p->pdev->dev, "tmu_fck"); | 468 | p->clk = clk_get(&p->pdev->dev, "tmu_fck"); |
| @@ -523,7 +522,6 @@ static int sh_tmu_probe(struct platform_device *pdev) | |||
| 523 | ret = sh_tmu_setup(p, pdev); | 522 | ret = sh_tmu_setup(p, pdev); |
| 524 | if (ret) { | 523 | if (ret) { |
| 525 | kfree(p); | 524 | kfree(p); |
| 526 | platform_set_drvdata(pdev, NULL); | ||
| 527 | pm_runtime_idle(&pdev->dev); | 525 | pm_runtime_idle(&pdev->dev); |
| 528 | return ret; | 526 | return ret; |
| 529 | } | 527 | } |
diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c index a4f6119aafd8..bf497afba9ad 100644 --- a/drivers/clocksource/sun4i_timer.c +++ b/drivers/clocksource/sun4i_timer.c | |||
| @@ -114,7 +114,7 @@ static int sun4i_clkevt_next_event(unsigned long evt, | |||
| 114 | 114 | ||
| 115 | static struct clock_event_device sun4i_clockevent = { | 115 | static struct clock_event_device sun4i_clockevent = { |
| 116 | .name = "sun4i_tick", | 116 | .name = "sun4i_tick", |
| 117 | .rating = 300, | 117 | .rating = 350, |
| 118 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 118 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
| 119 | .set_mode = sun4i_clkevt_mode, | 119 | .set_mode = sun4i_clkevt_mode, |
| 120 | .set_next_event = sun4i_clkevt_next_event, | 120 | .set_next_event = sun4i_clkevt_next_event, |
| @@ -138,7 +138,7 @@ static struct irqaction sun4i_timer_irq = { | |||
| 138 | .dev_id = &sun4i_clockevent, | 138 | .dev_id = &sun4i_clockevent, |
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | static u32 sun4i_timer_sched_read(void) | 141 | static u64 notrace sun4i_timer_sched_read(void) |
| 142 | { | 142 | { |
| 143 | return ~readl(timer_base + TIMER_CNTVAL_REG(1)); | 143 | return ~readl(timer_base + TIMER_CNTVAL_REG(1)); |
| 144 | } | 144 | } |
| @@ -170,9 +170,9 @@ static void __init sun4i_timer_init(struct device_node *node) | |||
| 170 | TIMER_CTL_CLK_SRC(TIMER_CTL_CLK_SRC_OSC24M), | 170 | TIMER_CTL_CLK_SRC(TIMER_CTL_CLK_SRC_OSC24M), |
| 171 | timer_base + TIMER_CTL_REG(1)); | 171 | timer_base + TIMER_CTL_REG(1)); |
| 172 | 172 | ||
| 173 | setup_sched_clock(sun4i_timer_sched_read, 32, rate); | 173 | sched_clock_register(sun4i_timer_sched_read, 32, rate); |
| 174 | clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name, | 174 | clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name, |
| 175 | rate, 300, 32, clocksource_mmio_readl_down); | 175 | rate, 350, 32, clocksource_mmio_readl_down); |
| 176 | 176 | ||
| 177 | ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); | 177 | ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); |
| 178 | 178 | ||
| @@ -190,7 +190,8 @@ static void __init sun4i_timer_init(struct device_node *node) | |||
| 190 | val = readl(timer_base + TIMER_IRQ_EN_REG); | 190 | val = readl(timer_base + TIMER_IRQ_EN_REG); |
| 191 | writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); | 191 | writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); |
| 192 | 192 | ||
| 193 | sun4i_clockevent.cpumask = cpumask_of(0); | 193 | sun4i_clockevent.cpumask = cpu_possible_mask; |
| 194 | sun4i_clockevent.irq = irq; | ||
| 194 | 195 | ||
| 195 | clockevents_config_and_register(&sun4i_clockevent, rate, | 196 | clockevents_config_and_register(&sun4i_clockevent, rate, |
| 196 | TIMER_SYNC_TICKS, 0xffffffff); | 197 | TIMER_SYNC_TICKS, 0xffffffff); |
diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c index 642849256d82..d1869f02051c 100644 --- a/drivers/clocksource/tegra20_timer.c +++ b/drivers/clocksource/tegra20_timer.c | |||
| @@ -149,7 +149,7 @@ static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id) | |||
| 149 | 149 | ||
| 150 | static struct irqaction tegra_timer_irq = { | 150 | static struct irqaction tegra_timer_irq = { |
| 151 | .name = "timer0", | 151 | .name = "timer0", |
| 152 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH, | 152 | .flags = IRQF_TIMER | IRQF_TRIGGER_HIGH, |
| 153 | .handler = tegra_timer_interrupt, | 153 | .handler = tegra_timer_interrupt, |
| 154 | .dev_id = &tegra_clockevent, | 154 | .dev_id = &tegra_clockevent, |
| 155 | }; | 155 | }; |
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index 4e7f6802e840..ee8691b89944 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c | |||
| @@ -76,6 +76,7 @@ | |||
| 76 | static void __iomem *timer_base, *local_base; | 76 | static void __iomem *timer_base, *local_base; |
| 77 | static unsigned int timer_clk; | 77 | static unsigned int timer_clk; |
| 78 | static bool timer25Mhz = true; | 78 | static bool timer25Mhz = true; |
| 79 | static u32 enable_mask; | ||
| 79 | 80 | ||
| 80 | /* | 81 | /* |
| 81 | * Number of timer ticks per jiffy. | 82 | * Number of timer ticks per jiffy. |
| @@ -121,8 +122,7 @@ armada_370_xp_clkevt_next_event(unsigned long delta, | |||
| 121 | /* | 122 | /* |
| 122 | * Enable the timer. | 123 | * Enable the timer. |
| 123 | */ | 124 | */ |
| 124 | local_timer_ctrl_clrset(TIMER0_RELOAD_EN, | 125 | local_timer_ctrl_clrset(TIMER0_RELOAD_EN, enable_mask); |
| 125 | TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); | ||
| 126 | return 0; | 126 | return 0; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| @@ -141,9 +141,7 @@ armada_370_xp_clkevt_mode(enum clock_event_mode mode, | |||
| 141 | /* | 141 | /* |
| 142 | * Enable timer. | 142 | * Enable timer. |
| 143 | */ | 143 | */ |
| 144 | local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | | 144 | local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | enable_mask); |
| 145 | TIMER0_EN | | ||
| 146 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); | ||
| 147 | } else { | 145 | } else { |
| 148 | /* | 146 | /* |
| 149 | * Disable timer. | 147 | * Disable timer. |
| @@ -240,10 +238,13 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np) | |||
| 240 | WARN_ON(!timer_base); | 238 | WARN_ON(!timer_base); |
| 241 | local_base = of_iomap(np, 1); | 239 | local_base = of_iomap(np, 1); |
| 242 | 240 | ||
| 243 | if (timer25Mhz) | 241 | if (timer25Mhz) { |
| 244 | set = TIMER0_25MHZ; | 242 | set = TIMER0_25MHZ; |
| 245 | else | 243 | enable_mask = TIMER0_EN; |
| 244 | } else { | ||
| 246 | clr = TIMER0_25MHZ; | 245 | clr = TIMER0_25MHZ; |
| 246 | enable_mask = TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT); | ||
| 247 | } | ||
| 247 | timer_ctrl_clrset(clr, set); | 248 | timer_ctrl_clrset(clr, set); |
| 248 | local_timer_ctrl_clrset(clr, set); | 249 | local_timer_ctrl_clrset(clr, set); |
| 249 | 250 | ||
| @@ -262,8 +263,7 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np) | |||
| 262 | writel(0xffffffff, timer_base + TIMER0_VAL_OFF); | 263 | writel(0xffffffff, timer_base + TIMER0_VAL_OFF); |
| 263 | writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); | 264 | writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); |
| 264 | 265 | ||
| 265 | timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN | | 266 | timer_ctrl_clrset(0, TIMER0_RELOAD_EN | enable_mask); |
| 266 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); | ||
| 267 | 267 | ||
| 268 | /* | 268 | /* |
| 269 | * Set scale and timer for sched_clock. | 269 | * Set scale and timer for sched_clock. |
diff --git a/drivers/clocksource/time-orion.c b/drivers/clocksource/time-orion.c index 9c7f018a67ca..20066222f3f2 100644 --- a/drivers/clocksource/time-orion.c +++ b/drivers/clocksource/time-orion.c | |||
| @@ -53,7 +53,7 @@ EXPORT_SYMBOL(orion_timer_ctrl_clrset); | |||
| 53 | /* | 53 | /* |
| 54 | * Free-running clocksource handling. | 54 | * Free-running clocksource handling. |
| 55 | */ | 55 | */ |
| 56 | static u32 notrace orion_read_sched_clock(void) | 56 | static u64 notrace orion_read_sched_clock(void) |
| 57 | { | 57 | { |
| 58 | return ~readl(timer_base + TIMER0_VAL); | 58 | return ~readl(timer_base + TIMER0_VAL); |
| 59 | } | 59 | } |
| @@ -135,7 +135,7 @@ static void __init orion_timer_init(struct device_node *np) | |||
| 135 | clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource", | 135 | clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource", |
| 136 | clk_get_rate(clk), 300, 32, | 136 | clk_get_rate(clk), 300, 32, |
| 137 | clocksource_mmio_readl_down); | 137 | clocksource_mmio_readl_down); |
| 138 | setup_sched_clock(orion_read_sched_clock, 32, clk_get_rate(clk)); | 138 | sched_clock_register(orion_read_sched_clock, 32, clk_get_rate(clk)); |
| 139 | 139 | ||
| 140 | /* setup timer1 as clockevent timer */ | 140 | /* setup timer1 as clockevent timer */ |
| 141 | if (setup_irq(irq, &orion_clkevt_irq)) | 141 | if (setup_irq(irq, &orion_clkevt_irq)) |
diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c new file mode 100644 index 000000000000..bddc52233d2a --- /dev/null +++ b/drivers/clocksource/timer-sun5i.c | |||
| @@ -0,0 +1,192 @@ | |||
| 1 | /* | ||
| 2 | * Allwinner SoCs hstimer driver. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013 Maxime Ripard | ||
| 5 | * | ||
| 6 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
| 7 | * | ||
| 8 | * This file is licensed under the terms of the GNU General Public | ||
| 9 | * License version 2. This program is licensed "as is" without any | ||
| 10 | * warranty of any kind, whether express or implied. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/clk.h> | ||
| 14 | #include <linux/clockchips.h> | ||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/irq.h> | ||
| 18 | #include <linux/irqreturn.h> | ||
| 19 | #include <linux/sched_clock.h> | ||
| 20 | #include <linux/of.h> | ||
| 21 | #include <linux/of_address.h> | ||
| 22 | #include <linux/of_irq.h> | ||
| 23 | |||
| 24 | #define TIMER_IRQ_EN_REG 0x00 | ||
| 25 | #define TIMER_IRQ_EN(val) BIT(val) | ||
| 26 | #define TIMER_IRQ_ST_REG 0x04 | ||
| 27 | #define TIMER_CTL_REG(val) (0x20 * (val) + 0x10) | ||
| 28 | #define TIMER_CTL_ENABLE BIT(0) | ||
| 29 | #define TIMER_CTL_RELOAD BIT(1) | ||
| 30 | #define TIMER_CTL_CLK_PRES(val) (((val) & 0x7) << 4) | ||
| 31 | #define TIMER_CTL_ONESHOT BIT(7) | ||
| 32 | #define TIMER_INTVAL_LO_REG(val) (0x20 * (val) + 0x14) | ||
| 33 | #define TIMER_INTVAL_HI_REG(val) (0x20 * (val) + 0x18) | ||
| 34 | #define TIMER_CNTVAL_LO_REG(val) (0x20 * (val) + 0x1c) | ||
| 35 | #define TIMER_CNTVAL_HI_REG(val) (0x20 * (val) + 0x20) | ||
| 36 | |||
| 37 | #define TIMER_SYNC_TICKS 3 | ||
| 38 | |||
| 39 | static void __iomem *timer_base; | ||
| 40 | static u32 ticks_per_jiffy; | ||
| 41 | |||
| 42 | /* | ||
| 43 | * When we disable a timer, we need to wait at least for 2 cycles of | ||
| 44 | * the timer source clock. We will use for that the clocksource timer | ||
| 45 | * that is already setup and runs at the same frequency than the other | ||
| 46 | * timers, and we never will be disabled. | ||
| 47 | */ | ||
| 48 | static void sun5i_clkevt_sync(void) | ||
| 49 | { | ||
| 50 | u32 old = readl(timer_base + TIMER_CNTVAL_LO_REG(1)); | ||
| 51 | |||
| 52 | while ((old - readl(timer_base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS) | ||
| 53 | cpu_relax(); | ||
| 54 | } | ||
| 55 | |||
| 56 | static void sun5i_clkevt_time_stop(u8 timer) | ||
| 57 | { | ||
| 58 | u32 val = readl(timer_base + TIMER_CTL_REG(timer)); | ||
| 59 | writel(val & ~TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG(timer)); | ||
| 60 | |||
| 61 | sun5i_clkevt_sync(); | ||
| 62 | } | ||
| 63 | |||
| 64 | static void sun5i_clkevt_time_setup(u8 timer, u32 delay) | ||
| 65 | { | ||
| 66 | writel(delay, timer_base + TIMER_INTVAL_LO_REG(timer)); | ||
| 67 | } | ||
| 68 | |||
| 69 | static void sun5i_clkevt_time_start(u8 timer, bool periodic) | ||
| 70 | { | ||
| 71 | u32 val = readl(timer_base + TIMER_CTL_REG(timer)); | ||
| 72 | |||
| 73 | if (periodic) | ||
| 74 | val &= ~TIMER_CTL_ONESHOT; | ||
| 75 | else | ||
| 76 | val |= TIMER_CTL_ONESHOT; | ||
| 77 | |||
| 78 | writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD, | ||
| 79 | timer_base + TIMER_CTL_REG(timer)); | ||
| 80 | } | ||
| 81 | |||
| 82 | static void sun5i_clkevt_mode(enum clock_event_mode mode, | ||
| 83 | struct clock_event_device *clk) | ||
| 84 | { | ||
| 85 | switch (mode) { | ||
| 86 | case CLOCK_EVT_MODE_PERIODIC: | ||
| 87 | sun5i_clkevt_time_stop(0); | ||
| 88 | sun5i_clkevt_time_setup(0, ticks_per_jiffy); | ||
| 89 | sun5i_clkevt_time_start(0, true); | ||
| 90 | break; | ||
| 91 | case CLOCK_EVT_MODE_ONESHOT: | ||
| 92 | sun5i_clkevt_time_stop(0); | ||
| 93 | sun5i_clkevt_time_start(0, false); | ||
| 94 | break; | ||
| 95 | case CLOCK_EVT_MODE_UNUSED: | ||
| 96 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
| 97 | default: | ||
| 98 | sun5i_clkevt_time_stop(0); | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | static int sun5i_clkevt_next_event(unsigned long evt, | ||
| 104 | struct clock_event_device *unused) | ||
| 105 | { | ||
| 106 | sun5i_clkevt_time_stop(0); | ||
| 107 | sun5i_clkevt_time_setup(0, evt - TIMER_SYNC_TICKS); | ||
| 108 | sun5i_clkevt_time_start(0, false); | ||
| 109 | |||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | static struct clock_event_device sun5i_clockevent = { | ||
| 114 | .name = "sun5i_tick", | ||
| 115 | .rating = 340, | ||
| 116 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
| 117 | .set_mode = sun5i_clkevt_mode, | ||
| 118 | .set_next_event = sun5i_clkevt_next_event, | ||
| 119 | }; | ||
| 120 | |||
| 121 | |||
| 122 | static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id) | ||
| 123 | { | ||
| 124 | struct clock_event_device *evt = (struct clock_event_device *)dev_id; | ||
| 125 | |||
| 126 | writel(0x1, timer_base + TIMER_IRQ_ST_REG); | ||
| 127 | evt->event_handler(evt); | ||
| 128 | |||
| 129 | return IRQ_HANDLED; | ||
| 130 | } | ||
| 131 | |||
| 132 | static struct irqaction sun5i_timer_irq = { | ||
| 133 | .name = "sun5i_timer0", | ||
| 134 | .flags = IRQF_TIMER | IRQF_IRQPOLL, | ||
| 135 | .handler = sun5i_timer_interrupt, | ||
| 136 | .dev_id = &sun5i_clockevent, | ||
| 137 | }; | ||
| 138 | |||
| 139 | static u32 sun5i_timer_sched_read(void) | ||
| 140 | { | ||
| 141 | return ~readl(timer_base + TIMER_CNTVAL_LO_REG(1)); | ||
| 142 | } | ||
| 143 | |||
| 144 | static void __init sun5i_timer_init(struct device_node *node) | ||
| 145 | { | ||
| 146 | unsigned long rate; | ||
| 147 | struct clk *clk; | ||
| 148 | int ret, irq; | ||
| 149 | u32 val; | ||
| 150 | |||
| 151 | timer_base = of_iomap(node, 0); | ||
| 152 | if (!timer_base) | ||
| 153 | panic("Can't map registers"); | ||
| 154 | |||
| 155 | irq = irq_of_parse_and_map(node, 0); | ||
| 156 | if (irq <= 0) | ||
| 157 | panic("Can't parse IRQ"); | ||
| 158 | |||
| 159 | clk = of_clk_get(node, 0); | ||
| 160 | if (IS_ERR(clk)) | ||
| 161 | panic("Can't get timer clock"); | ||
| 162 | clk_prepare_enable(clk); | ||
| 163 | rate = clk_get_rate(clk); | ||
| 164 | |||
| 165 | writel(~0, timer_base + TIMER_INTVAL_LO_REG(1)); | ||
| 166 | writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD, | ||
| 167 | timer_base + TIMER_CTL_REG(1)); | ||
| 168 | |||
| 169 | setup_sched_clock(sun5i_timer_sched_read, 32, rate); | ||
| 170 | clocksource_mmio_init(timer_base + TIMER_CNTVAL_LO_REG(1), node->name, | ||
| 171 | rate, 340, 32, clocksource_mmio_readl_down); | ||
| 172 | |||
| 173 | ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); | ||
| 174 | |||
| 175 | ret = setup_irq(irq, &sun5i_timer_irq); | ||
| 176 | if (ret) | ||
| 177 | pr_warn("failed to setup irq %d\n", irq); | ||
| 178 | |||
| 179 | /* Enable timer0 interrupt */ | ||
| 180 | val = readl(timer_base + TIMER_IRQ_EN_REG); | ||
| 181 | writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); | ||
| 182 | |||
| 183 | sun5i_clockevent.cpumask = cpu_possible_mask; | ||
| 184 | sun5i_clockevent.irq = irq; | ||
| 185 | |||
| 186 | clockevents_config_and_register(&sun5i_clockevent, rate, | ||
| 187 | TIMER_SYNC_TICKS, 0xffffffff); | ||
| 188 | } | ||
| 189 | CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer", | ||
| 190 | sun5i_timer_init); | ||
| 191 | CLOCKSOURCE_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer", | ||
| 192 | sun5i_timer_init); | ||
diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c index ad3c0e83a779..1098ed3b9b89 100644 --- a/drivers/clocksource/vt8500_timer.c +++ b/drivers/clocksource/vt8500_timer.c | |||
| @@ -124,7 +124,7 @@ static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id) | |||
| 124 | 124 | ||
| 125 | static struct irqaction irq = { | 125 | static struct irqaction irq = { |
| 126 | .name = "vt8500_timer", | 126 | .name = "vt8500_timer", |
| 127 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 127 | .flags = IRQF_TIMER | IRQF_IRQPOLL, |
| 128 | .handler = vt8500_timer_interrupt, | 128 | .handler = vt8500_timer_interrupt, |
| 129 | .dev_id = &clockevent, | 129 | .dev_id = &clockevent, |
| 130 | }; | 130 | }; |
