diff options
Diffstat (limited to 'drivers/clocksource')
-rw-r--r-- | drivers/clocksource/Kconfig | 3 | ||||
-rw-r--r-- | drivers/clocksource/Makefile | 2 | ||||
-rw-r--r-- | drivers/clocksource/cyclone.c | 113 | ||||
-rw-r--r-- | drivers/clocksource/dummy_timer.c | 11 | ||||
-rw-r--r-- | drivers/clocksource/exynos_mct.c | 2 | ||||
-rw-r--r-- | drivers/clocksource/qcom-timer.c | 330 | ||||
-rw-r--r-- | drivers/clocksource/timer-marco.c | 13 | ||||
-rw-r--r-- | drivers/clocksource/timer-prima2.c | 16 | ||||
-rw-r--r-- | drivers/clocksource/timer-u300.c | 2 |
9 files changed, 360 insertions, 132 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 52e9329e3c51..96918e1f26a3 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -188,3 +188,6 @@ config EM_TIMER_STI This enables build of a clocksource and clockevent driver for the 48-bit System Timer (STI) hardware available on a SoCs such as EMEV2 from former NEC Electronics. + +config CLKSRC_QCOM + bool diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index aed3488d9426..98cb6c51aa87 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -1,6 +1,5 @@ obj-$(CONFIG_CLKSRC_OF) += clksrc-of.o obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o -obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o @@ -33,6 +32,7 @@ obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o +obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o diff --git a/drivers/clocksource/cyclone.c b/drivers/clocksource/cyclone.c deleted file mode 100644 index 9e0998f22885..000000000000 --- a/drivers/clocksource/cyclone.c +++ /dev/null @@ -1,113 +0,0 @@ -#include <linux/clocksource.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/timex.h> -#include <linux/init.h> - -#include <asm/pgtable.h> -#include <asm/io.h> - -#include <asm/mach_timer.h> - -#define CYCLONE_CBAR_ADDR 0xFEB00CD0 /* base address ptr */ -#define CYCLONE_PMCC_OFFSET 0x51A0 /* offset to control register */ -#define CYCLONE_MPCS_OFFSET 0x51A8 /* offset to select register */ -#define CYCLONE_MPMC_OFFSET 0x51D0 /* offset to count register */ -#define CYCLONE_TIMER_FREQ 99780000 /* 100Mhz, but not really */ -#define CYCLONE_TIMER_MASK CLOCKSOURCE_MASK(32) /* 32 bit mask */ - -int use_cyclone = 0; -static void __iomem *cyclone_ptr; - -static cycle_t read_cyclone(struct clocksource *cs) -{ - return (cycle_t)readl(cyclone_ptr); -} - -static struct clocksource clocksource_cyclone = { - .name = "cyclone", - .rating = 250, - .read = read_cyclone, - .mask = CYCLONE_TIMER_MASK, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init init_cyclone_clocksource(void) -{ - unsigned long base; /* saved value from CBAR */ - unsigned long offset; - u32 __iomem* volatile cyclone_timer; /* Cyclone MPMC0 register */ - u32 __iomem* reg; - int i; - - /* make sure we're on a summit box: */ - if (!use_cyclone) - return -ENODEV; - - printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n"); - - /* find base address: */ - offset = CYCLONE_CBAR_ADDR; - reg = ioremap_nocache(offset, sizeof(reg)); - if (!reg) { - printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n"); - return -ENODEV; - } - /* even on 64bit systems, this is only 32bits: */ - base = readl(reg); - iounmap(reg); - if (!base) { - printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n"); - return -ENODEV; - } - - /* setup PMCC: */ - offset = base + CYCLONE_PMCC_OFFSET; - reg = ioremap_nocache(offset, sizeof(reg)); - if (!reg) { - printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n"); - return -ENODEV; - } - writel(0x00000001,reg); - iounmap(reg); - - /* setup MPCS: */ - offset = base + CYCLONE_MPCS_OFFSET; - reg = ioremap_nocache(offset, sizeof(reg)); - if (!reg) { - printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n"); - return -ENODEV; - } - writel(0x00000001,reg); - iounmap(reg); - - /* map in cyclone_timer: */ - offset = base + CYCLONE_MPMC_OFFSET; - cyclone_timer = ioremap_nocache(offset, sizeof(u64)); - if (!cyclone_timer) { - printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n"); - return -ENODEV; - } - - /* quick test to make sure its ticking: */ - for (i = 0; i < 3; i++){ - u32 old = readl(cyclone_timer); - int stall = 100; - - while (stall--) - barrier(); - - if (readl(cyclone_timer) == old) { - printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n"); - iounmap(cyclone_timer); - cyclone_timer = NULL; - return -ENODEV; - } - } - cyclone_ptr = cyclone_timer; - - return clocksource_register_hz(&clocksource_cyclone, - CYCLONE_TIMER_FREQ); -} - -arch_initcall(init_cyclone_clocksource); diff --git a/drivers/clocksource/dummy_timer.c b/drivers/clocksource/dummy_timer.c index b3eb582d6a6f..ad3572541728 100644 --- a/drivers/clocksource/dummy_timer.c +++ b/drivers/clocksource/dummy_timer.c @@ -56,14 +56,19 @@ static struct notifier_block dummy_timer_cpu_nb = { static int __init dummy_timer_register(void) { - int err = register_cpu_notifier(&dummy_timer_cpu_nb); + int err = 0; + + cpu_notifier_register_begin(); + err = __register_cpu_notifier(&dummy_timer_cpu_nb); if (err) - return err; + goto out; /* We won't get a call on the boot CPU, so register immediately */ if (num_possible_cpus() > 1) dummy_timer_setup(); - return 0; +out: + cpu_notifier_register_done(); + return err; } early_initcall(dummy_timer_register); diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index c2e390efbdca..a6ee6d7cd63f 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -25,8 +25,6 @@ #include <linux/of_address.h> #include <linux/clocksource.h> -#include <asm/mach/time.h> - #define EXYNOS4_MCTREG(x) (x) #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100) #define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104) diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c new file mode 100644 index 000000000000..e807acf4c665 --- /dev/null +++ b/drivers/clocksource/qcom-timer.c @@ -0,0 +1,330 @@ +/* + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/clocksource.h> +#include <linux/clockchips.h> +#include <linux/cpu.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/sched_clock.h> + +#define TIMER_MATCH_VAL 0x0000 +#define TIMER_COUNT_VAL 0x0004 +#define TIMER_ENABLE 0x0008 +#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1) +#define TIMER_ENABLE_EN BIT(0) +#define TIMER_CLEAR 0x000C +#define DGT_CLK_CTL 0x10 +#define DGT_CLK_CTL_DIV_4 0x3 +#define TIMER_STS_GPT0_CLR_PEND BIT(10) + +#define GPT_HZ 32768 + +#define MSM_DGT_SHIFT 5 + +static void __iomem *event_base; +static void __iomem *sts_base; + +static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + /* Stop the timer tick */ + if (evt->mode == CLOCK_EVT_MODE_ONESHOT) { + u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); + ctrl &= ~TIMER_ENABLE_EN; + writel_relaxed(ctrl, event_base + TIMER_ENABLE); + } + evt->event_handler(evt); + return IRQ_HANDLED; +} + +static int msm_timer_set_next_event(unsigned long cycles, + struct clock_event_device *evt) +{ + u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); + + ctrl &= ~TIMER_ENABLE_EN; + writel_relaxed(ctrl, event_base + TIMER_ENABLE); + + writel_relaxed(ctrl, event_base + TIMER_CLEAR); + writel_relaxed(cycles, event_base + TIMER_MATCH_VAL); + + if (sts_base) + while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND) + cpu_relax(); + + writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE); + return 0; +} + +static void msm_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + u32 ctrl; + + ctrl = readl_relaxed(event_base + TIMER_ENABLE); + ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN); + + switch (mode) { + case CLOCK_EVT_MODE_RESUME: + case CLOCK_EVT_MODE_PERIODIC: + break; + case CLOCK_EVT_MODE_ONESHOT: + /* Timer is enabled in set_next_event */ + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + break; + } + writel_relaxed(ctrl, event_base + TIMER_ENABLE); +} + +static struct clock_event_device __percpu *msm_evt; + +static void __iomem *source_base; + +static notrace cycle_t msm_read_timer_count(struct clocksource *cs) +{ + return readl_relaxed(source_base + TIMER_COUNT_VAL); +} + +static struct clocksource msm_clocksource = { + .name = "dg_timer", + .rating = 300, + .read = msm_read_timer_count, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int msm_timer_irq; +static int msm_timer_has_ppi; + +static int msm_local_timer_setup(struct clock_event_device *evt) +{ + int cpu = smp_processor_id(); + int err; + + evt->irq = msm_timer_irq; + evt->name = "msm_timer"; + evt->features = CLOCK_EVT_FEAT_ONESHOT; + evt->rating = 200; + evt->set_mode = msm_timer_set_mode; + evt->set_next_event = msm_timer_set_next_event; + evt->cpumask = cpumask_of(cpu); + + clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff); + + if (msm_timer_has_ppi) { + enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING); + } else { + err = request_irq(evt->irq, msm_timer_interrupt, + IRQF_TIMER | IRQF_NOBALANCING | + IRQF_TRIGGER_RISING, "gp_timer", evt); + if (err) + pr_err("request_irq failed\n"); + } + + return 0; +} + +static void msm_local_timer_stop(struct clock_event_device *evt) +{ + evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); + disable_percpu_irq(evt->irq); +} + +static int msm_timer_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + /* + * Grab cpu pointer in each case to avoid spurious + * preemptible warnings + */ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + msm_local_timer_setup(this_cpu_ptr(msm_evt)); + break; + case CPU_DYING: + msm_local_timer_stop(this_cpu_ptr(msm_evt)); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block msm_timer_cpu_nb = { + .notifier_call = msm_timer_cpu_notify, +}; + +static u64 notrace msm_sched_clock_read(void) +{ + return msm_clocksource.read(&msm_clocksource); +} + +static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, + bool percpu) +{ + struct clocksource *cs = &msm_clocksource; + int res = 0; + + msm_timer_irq = irq; + msm_timer_has_ppi = percpu; + + msm_evt = alloc_percpu(struct clock_event_device); + if (!msm_evt) { + pr_err("memory allocation failed for clockevents\n"); + goto err; + } + + if (percpu) + res = request_percpu_irq(irq, msm_timer_interrupt, + "gp_timer", msm_evt); + + if (res) { + pr_err("request_percpu_irq failed\n"); + } else { + res = register_cpu_notifier(&msm_timer_cpu_nb); + if (res) { + free_percpu_irq(irq, msm_evt); + goto err; + } + + /* Immediately configure the timer on the boot CPU */ + msm_local_timer_setup(__this_cpu_ptr(msm_evt)); + } + +err: + writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); + res = clocksource_register_hz(cs, dgt_hz); + if (res) + pr_err("clocksource_register failed\n"); + sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); +} + +#ifdef CONFIG_ARCH_QCOM +static void __init msm_dt_timer_init(struct device_node *np) +{ + u32 freq; + int irq; + struct resource res; + u32 percpu_offset; + void __iomem *base; + void __iomem *cpu0_base; + + base = of_iomap(np, 0); + if (!base) { + pr_err("Failed to map event base\n"); + return; + } + + /* We use GPT0 for the clockevent */ + irq = irq_of_parse_and_map(np, 1); + if (irq <= 0) { + pr_err("Can't get irq\n"); + return; + } + + /* We use CPU0's DGT for the clocksource */ + if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) + percpu_offset = 0; + + if (of_address_to_resource(np, 0, &res)) { + pr_err("Failed to parse DGT resource\n"); + return; + } + + cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res)); + if (!cpu0_base) { + pr_err("Failed to map source base\n"); + return; + } + + if (of_property_read_u32(np, "clock-frequency", &freq)) { + pr_err("Unknown frequency\n"); + return; + } + + event_base = base + 0x4; + sts_base = base + 0x88; + source_base = cpu0_base + 0x24; + freq /= 4; + writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); + + msm_timer_init(freq, 32, irq, !!percpu_offset); +} +CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); +CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); +#else + +static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source, + u32 sts) +{ + void __iomem *base; + + base = ioremap(addr, SZ_256); + if (!base) { + pr_err("Failed to map timer base\n"); + return -ENOMEM; + } + event_base = base + event; + source_base = base + source; + if (sts) + sts_base = base + sts; + + return 0; +} + +static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs) +{ + /* + * Shift timer count down by a constant due to unreliable lower bits + * on some targets. + */ + return msm_read_timer_count(cs) >> MSM_DGT_SHIFT; +} + +void __init msm7x01_timer_init(void) +{ + struct clocksource *cs = &msm_clocksource; + + if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0)) + return; + cs->read = msm_read_timer_count_shift; + cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)); + /* 600 KHz */ + msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7, + false); +} + +void __init msm7x30_timer_init(void) +{ + if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80)) + return; + msm_timer_init(24576000 / 4, 32, 1, false); +} + +void __init qsd8x50_timer_init(void) +{ + if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34)) + return; + msm_timer_init(19200000 / 4, 32, 7, false); +} +#endif diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-marco.c index 09a17d9a6594..b52e1c078b99 100644 --- a/drivers/clocksource/timer-marco.c +++ b/drivers/clocksource/timer-marco.c @@ -19,7 +19,8 @@ #include <linux/of_irq.h> #include <linux/of_address.h> #include <linux/sched_clock.h> -#include <asm/mach/time.h> + +#define MARCO_CLOCK_FREQ 1000000 #define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000 #define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004 @@ -191,7 +192,7 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce) ce->rating = 200; ce->set_mode = sirfsoc_timer_set_mode; ce->set_next_event = sirfsoc_timer_set_next_event; - clockevents_calc_mult_shift(ce, CLOCK_TICK_RATE, 60); + clockevents_calc_mult_shift(ce, MARCO_CLOCK_FREQ, 60); ce->max_delta_ns = clockevent_delta2ns(-2, ce); ce->min_delta_ns = clockevent_delta2ns(2, ce); ce->cpumask = cpumask_of(cpu); @@ -263,11 +264,11 @@ static void __init sirfsoc_marco_timer_init(void) BUG_ON(IS_ERR(clk)); rate = clk_get_rate(clk); - BUG_ON(rate < CLOCK_TICK_RATE); - BUG_ON(rate % CLOCK_TICK_RATE); + BUG_ON(rate < MARCO_CLOCK_FREQ); + BUG_ON(rate % MARCO_CLOCK_FREQ); /* Initialize the timer dividers */ - timer_div = rate / CLOCK_TICK_RATE - 1; + timer_div = rate / MARCO_CLOCK_FREQ - 1; writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL); writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL); @@ -283,7 +284,7 @@ static void __init sirfsoc_marco_timer_init(void) /* Clear all interrupts */ writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); - BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); + BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, MARCO_CLOCK_FREQ)); sirfsoc_clockevent_init(); } diff --git a/drivers/clocksource/timer-prima2.c b/drivers/clocksource/timer-prima2.c index 8a492d34ff9f..1a6b2d6356d6 100644 --- a/drivers/clocksource/timer-prima2.c +++ b/drivers/clocksource/timer-prima2.c @@ -21,6 +21,8 @@ #include <linux/sched_clock.h> #include <asm/mach/time.h> +#define PRIMA2_CLOCK_FREQ 1000000 + #define SIRFSOC_TIMER_COUNTER_LO 0x0000 #define SIRFSOC_TIMER_COUNTER_HI 0x0004 #define SIRFSOC_TIMER_MATCH_0 0x0008 @@ -173,7 +175,7 @@ static u64 notrace sirfsoc_read_sched_clock(void) static void __init sirfsoc_clockevent_init(void) { sirfsoc_clockevent.cpumask = cpumask_of(0); - clockevents_config_and_register(&sirfsoc_clockevent, CLOCK_TICK_RATE, + clockevents_config_and_register(&sirfsoc_clockevent, PRIMA2_CLOCK_FREQ, 2, -2); } @@ -190,8 +192,8 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np) rate = clk_get_rate(clk); - BUG_ON(rate < CLOCK_TICK_RATE); - BUG_ON(rate % CLOCK_TICK_RATE); + BUG_ON(rate < PRIMA2_CLOCK_FREQ); + BUG_ON(rate % PRIMA2_CLOCK_FREQ); sirfsoc_timer_base = of_iomap(np, 0); if (!sirfsoc_timer_base) @@ -199,14 +201,16 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np) sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); - writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV); + writel_relaxed(rate / PRIMA2_CLOCK_FREQ / 2 - 1, + sirfsoc_timer_base + SIRFSOC_TIMER_DIV); writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); - BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); + BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, + PRIMA2_CLOCK_FREQ)); - sched_clock_register(sirfsoc_read_sched_clock, 64, CLOCK_TICK_RATE); + sched_clock_register(sirfsoc_read_sched_clock, 64, PRIMA2_CLOCK_FREQ); BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); diff --git a/drivers/clocksource/timer-u300.c b/drivers/clocksource/timer-u300.c index e63d469661fd..5dcf756970e7 100644 --- a/drivers/clocksource/timer-u300.c +++ b/drivers/clocksource/timer-u300.c @@ -333,7 +333,7 @@ static irqreturn_t u300_timer_interrupt(int irq, void *dev_id) static struct irqaction u300_timer_irq = { .name = "U300 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = u300_timer_interrupt, }; |