Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932087AbbGCPej (ORCPT ); Fri, 3 Jul 2015 11:34:39 -0400 Received: from mail-wg0-f47.google.com ([74.125.82.47]:34504 "EHLO mail-wg0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755231AbbGCPe3 (ORCPT ); Fri, 3 Jul 2015 11:34:29 -0400 From: David Dueck To: linux-kernel@vger.kernel.org Cc: bigeasy@linutronix.de, nicolas.ferre@atmel.com, alexandre.belloni@free-electrons.com, ludovic.desroches@atmel.com, boris.brezillon@free-electrons.com, maxime.ripard@free-electrons.com, wsteinwender@pcs.com, antoine.tenart@free-electrons.com, mail@jann.io, c.emde@osadl.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/2] at91: use request_irq/free_irq instead of setup_irq/remove_irq Date: Fri, 3 Jul 2015 17:33:29 +0200 Message-Id: <1435937609-18623-2-git-send-email-davidcdueck@googlemail.com> X-Mailer: git-send-email 2.4.4 In-Reply-To: <1435937609-18623-1-git-send-email-davidcdueck@googlemail.com> References: <1435937609-18623-1-git-send-email-davidcdueck@googlemail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5002 Lines: 144 This fixes a warning when using RT-Preempt. WARNING: CPU: 0 PID: 0 at kernel/irq/manage.c:1406 __free_irq+0xa4/0x210() Trying to free already-free IRQ 0 Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 4.0.0-rt4+ #198 Hardware name: Atmel SAMA5 [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (warn_slowpath_common+0x80/0xac) [] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x30/0x40) [] (warn_slowpath_fmt) from [] (__free_irq+0xa4/0x210) [] (__free_irq) from [] (clockevents_set_mode+0x28/0x5c) [] (clockevents_set_mode) from [] (clockevents_exchange_device+0x84/0x9c) [] (clockevents_exchange_device) from [] (tick_check_new_device+0x8c/0xac) [] (tick_check_new_device) from [] (clockevents_register_device+0x5c/0x118) [] (clockevents_register_device) from [] (clocksource_of_init+0x4c/0x8c) [] (clocksource_of_init) from [] (start_kernel+0x268/0x3c0) [] (start_kernel) from [<20008070>] (0x20008070) ---[ end trace 0000000000000001 ]--- Signed-off-by: David Dueck --- drivers/clocksource/timer-atmel-pit.c | 76 ++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c index d9c0b72..1de1ac8 100644 --- a/drivers/clocksource/timer-atmel-pit.c +++ b/drivers/clocksource/timer-atmel-pit.c @@ -90,7 +90,38 @@ static cycle_t read_pit_clk(struct clocksource *cs) return elapsed; } -static struct irqaction at91sam926x_pit_irq; +/* + * IRQ handler for the timer. + */ +static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) +{ + struct pit_data *data = dev_id; + + /* + * irqs should be disabled here, but as the irq is shared they are only + * guaranteed to be off if the timer irq is registered first. + */ + WARN_ON_ONCE(!irqs_disabled()); + + /* The PIT interrupt may be disabled, and is shared */ + if ((data->clkevt.mode == CLOCK_EVT_MODE_PERIODIC) && + (pit_read(data->base, AT91_PIT_SR) & AT91_PIT_PITS)) { + unsigned nr_ticks; + + /* Get number of ticks performed before irq, and ack it */ + nr_ticks = PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR)); + do { + data->cnt += data->cycle; + data->clkevt.event_handler(&data->clkevt); + nr_ticks--; + } while (nr_ticks); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + /* * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16) */ @@ -98,11 +129,16 @@ static void pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) { struct pit_data *data = clkevt_to_pit_data(dev); + int ret; switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - /* Set up irq handler */ - setup_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq); + ret = request_irq(data->irq, at91sam926x_pit_interrupt, + IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, + "at91_tick", data); + if (ret) + pr_warn("Unable to request PIT irq!\n"); + /* update clocksource counter */ data->cnt += data->cycle * PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR)); pit_write(data->base, AT91_PIT_MR, @@ -116,7 +152,7 @@ pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) /* disable irq, leaving the clocksource active */ pit_write(data->base, AT91_PIT_MR, (data->cycle - 1) | AT91_PIT_PITEN); - remove_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq); + free_irq(data->irq, data); break; case CLOCK_EVT_MODE_RESUME: break; @@ -153,38 +189,6 @@ static void at91sam926x_pit_resume(struct clock_event_device *cedev) } /* - * IRQ handler for the timer. - */ -static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) -{ - struct pit_data *data = dev_id; - - /* - * irqs should be disabled here, but as the irq is shared they are only - * guaranteed to be off if the timer irq is registered first. - */ - WARN_ON_ONCE(!irqs_disabled()); - - /* The PIT interrupt may be disabled, and is shared */ - if ((data->clkevt.mode == CLOCK_EVT_MODE_PERIODIC) && - (pit_read(data->base, AT91_PIT_SR) & AT91_PIT_PITS)) { - unsigned nr_ticks; - - /* Get number of ticks performed before irq, and ack it */ - nr_ticks = PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR)); - do { - data->cnt += data->cycle; - data->clkevt.event_handler(&data->clkevt); - nr_ticks--; - } while (nr_ticks); - - return IRQ_HANDLED; - } - - return IRQ_NONE; -} - -/* * Set up both clocksource and clockevent support. */ static void __init at91sam926x_pit_common_init(struct pit_data *data) -- 2.4.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/