Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755235AbbKDHgk (ORCPT ); Wed, 4 Nov 2015 02:36:40 -0500 Received: from mail2.asahi-net.or.jp ([202.224.39.198]:48358 "EHLO mail2.asahi-net.or.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752064AbbKDHgj (ORCPT ); Wed, 4 Nov 2015 02:36:39 -0500 From: Yoshinori Sato To: Daniel Lezcano , Thomas Gleixner Cc: Yoshinori Sato , linux-kernel@vger.kernel.org Subject: [PATCH] h8300: Initialize cleanup and remove module code Date: Wed, 4 Nov 2015 16:35:48 +0900 Message-Id: <1446622548-18248-1-git-send-email-ysato@users.sourceforge.jp> X-Mailer: git-send-email 2.6.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 16493 Lines: 619 h8300's clocksource driver cleanup. - Use CLOCKSOURCE_OF_DECLARE - Remove module exit Signed-off-by: Yoshinori Sato --- drivers/clocksource/h8300_timer16.c | 133 ++++++++++++----------------- drivers/clocksource/h8300_timer8.c | 164 ++++++++++++++---------------------- drivers/clocksource/h8300_tpu.c | 105 ++++++++--------------- 3 files changed, 151 insertions(+), 251 deletions(-) diff --git a/drivers/clocksource/h8300_timer16.c b/drivers/clocksource/h8300_timer16.c index 82941c1..e2e10cf 100644 --- a/drivers/clocksource/h8300_timer16.c +++ b/drivers/clocksource/h8300_timer16.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include @@ -47,7 +49,6 @@ #define ABSOLUTE 1 struct timer16_priv { - struct platform_device *pdev; struct clocksource cs; struct irqaction irqaction; unsigned long total_cycles; @@ -147,43 +148,58 @@ static void timer16_disable(struct clocksource *cs) #define REG_CH 0 #define REG_COMM 1 -static int timer16_setup(struct timer16_priv *p, struct platform_device *pdev) +static void __init h8300_16timer_init(struct device_node *node) { - struct resource *res[2]; + void __iomem *base[2]; int ret, irq; unsigned int ch; + struct timer16_priv *p; + struct clk *clk; + + clk = of_clk_get(node, 0); + if (IS_ERR(clk)) { + pr_err("failed to get clock for clocksource\n"); + return; + } - memset(p, 0, sizeof(*p)); - p->pdev = pdev; + base[REG_CH] = of_iomap(node, 0); + if (!base[0]) { + pr_err("failed to map registers for clocksource\n"); + goto free_clk; + } - res[REG_CH] = platform_get_resource(p->pdev, - IORESOURCE_MEM, REG_CH); - res[REG_COMM] = platform_get_resource(p->pdev, - IORESOURCE_MEM, REG_COMM); - if (!res[REG_CH] || !res[REG_COMM]) { - dev_err(&p->pdev->dev, "failed to get I/O memory\n"); - return -ENXIO; + base[REG_COMM] = of_iomap(node, 1); + if (!base[1]) { + pr_err("failed to map registers for clocksource\n"); + goto unmap_ch; } - irq = platform_get_irq(p->pdev, 0); + + irq = irq_of_parse_and_map(node, 0); if (irq < 0) { - dev_err(&p->pdev->dev, "failed to get irq\n"); - return irq; + pr_err("failed to get irq for clockevent\n"); + goto unmap_comm; } - p->clk = clk_get(&p->pdev->dev, "fck"); - if (IS_ERR(p->clk)) { - dev_err(&p->pdev->dev, "can't get clk\n"); - return PTR_ERR(p->clk); + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) { + pr_err("failed to allocate memory for clocksource\n"); + goto unmap_comm; } - of_property_read_u32(p->pdev->dev.of_node, "renesas,channel", &ch); - p->pdev = pdev; - p->mapbase = res[REG_CH]->start; - p->mapcommon = res[REG_COMM]->start; + of_property_read_u32(node, "renesas,channel", &ch); + + p->mapbase = (unsigned long)base[REG_CH]; + p->mapcommon = (unsigned long)base[REG_COMM]; p->enb = 1 << ch; p->imfa = 1 << ch; p->imiea = 1 << (4 + ch); - p->cs.name = pdev->name; + + p->irqaction.name = node->name; + p->irqaction.handler = timer16_interrupt; + p->irqaction.dev_id = p; + p->irqaction.flags = IRQF_TIMER; + + p->cs.name = node->name; p->cs.rating = 200; p->cs.read = timer16_clocksource_read; p->cs.enable = timer16_enable; @@ -191,64 +207,23 @@ static int timer16_setup(struct timer16_priv *p, struct platform_device *pdev) p->cs.mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); p->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; - ret = request_irq(irq, timer16_interrupt, - IRQF_TIMER, pdev->name, p); + ret = setup_irq(irq, &p->irqaction); if (ret < 0) { - dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); - return ret; + pr_err("failed to request irq %d of clocksource\n", irq); + goto free_priv; } clocksource_register_hz(&p->cs, clk_get_rate(p->clk) / 8); - - return 0; -} - -static int timer16_probe(struct platform_device *pdev) -{ - struct timer16_priv *p = platform_get_drvdata(pdev); - - if (p) { - dev_info(&pdev->dev, "kept as earlytimer\n"); - return 0; - } - - p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); - if (!p) - return -ENOMEM; - - return timer16_setup(p, pdev); -} - -static int timer16_remove(struct platform_device *pdev) -{ - return -EBUSY; -} - -static const struct of_device_id timer16_of_table[] = { - { .compatible = "renesas,16bit-timer" }, - { } -}; -static struct platform_driver timer16_driver = { - .probe = timer16_probe, - .remove = timer16_remove, - .driver = { - .name = "h8300h-16timer", - .of_match_table = of_match_ptr(timer16_of_table), - } -}; - -static int __init timer16_init(void) -{ - return platform_driver_register(&timer16_driver); -} - -static void __exit timer16_exit(void) -{ - platform_driver_unregister(&timer16_driver); + return; + +free_priv: + kfree(p); +unmap_comm: + iounmap(base[REG_COMM]); +unmap_ch: + iounmap(base[REG_CH]); +free_clk: + clk_put(clk); } -subsys_initcall(timer16_init); -module_exit(timer16_exit); -MODULE_AUTHOR("Yoshinori Sato"); -MODULE_DESCRIPTION("H8/300H 16bit Timer Driver"); -MODULE_LICENSE("GPL v2"); +CLOCKSOURCE_OF_DECLARE(h8300_16bit, "renesas,16bit-timer", h8300_16timer_init); diff --git a/drivers/clocksource/h8300_timer8.c b/drivers/clocksource/h8300_timer8.c index e83db7b..0a2333b 100644 --- a/drivers/clocksource/h8300_timer8.c +++ b/drivers/clocksource/h8300_timer8.c @@ -12,13 +12,14 @@ #include #include #include -#include #include #include #include #include #include #include +#include +#include #include @@ -39,8 +40,9 @@ #define RELATIVE 0 #define ABSOLUTE 1 +#define SCALE 64 + struct timer8_priv { - struct platform_device *pdev; struct clock_event_device ced; struct irqaction irqaction; unsigned long mapbase; @@ -76,8 +78,6 @@ static irqreturn_t timer8_interrupt(int irq, void *dev_id) { struct timer8_priv *p = dev_id; - ctrl_outb(ctrl_inb(p->mapbase + _8TCSR) & ~0x40, - p->mapbase + _8TCSR); p->flags |= FLAG_IRQCONTEXT; ctrl_outw(p->tcora, p->mapbase + TCORA); if (!(p->flags & FLAG_SKIPEVENT)) { @@ -85,6 +85,8 @@ static irqreturn_t timer8_interrupt(int irq, void *dev_id) ctrl_outw(0x0000, p->mapbase + _8TCR); p->ced.event_handler(&p->ced); } + ctrl_outb(ctrl_inb(p->mapbase + _8TCSR) & ~0x40, + p->mapbase + _8TCSR); p->flags &= ~(FLAG_SKIPEVENT | FLAG_IRQCONTEXT); return IRQ_HANDLED; @@ -96,23 +98,25 @@ static void timer8_set_next(struct timer8_priv *p, unsigned long delta) unsigned long now; raw_spin_lock_irqsave(&p->lock, flags); - if (delta >= 0x10000) - dev_warn(&p->pdev->dev, "delta out of range\n"); now = timer8_get_counter(p); p->tcora = delta; - ctrl_outb(ctrl_inb(p->mapbase + _8TCR) & ~0x40, p->mapbase + _8TCR); - if (delta > now) - ctrl_outw(delta, p->mapbase + TCORA); - else - ctrl_outw(now + 1, p->mapbase + TCORA); - ctrl_outb(ctrl_inb(p->mapbase + _8TCR) | 0x40, p->mapbase + _8TCR); + if (unlikely(p->flags & FLAG_IRQCONTEXT)) { + ctrl_outb(ctrl_inb(p->mapbase + _8TCR) & ~0x40, + p->mapbase + _8TCR); + if (delta > now) + ctrl_outw(delta, p->mapbase + TCORA); + else + ctrl_outw(now + 1, p->mapbase + TCORA); + ctrl_outb(ctrl_inb(p->mapbase + _8TCR) | 0x40, + p->mapbase + _8TCR); + } raw_spin_unlock_irqrestore(&p->lock, flags); } static int timer8_enable(struct timer8_priv *p) { - p->rate = clk_get_rate(p->pclk) / 64; + p->rate = clk_get_rate(p->pclk) / SCALE; ctrl_outw(0xffff, p->mapbase + TCORA); ctrl_outw(0x0000, p->mapbase + _8TCNT); ctrl_outw(0x0c02, p->mapbase + _8TCR); @@ -159,14 +163,7 @@ static inline struct timer8_priv *ced_to_priv(struct clock_event_device *ced) static void timer8_clock_event_start(struct timer8_priv *p, int periodic) { - struct clock_event_device *ced = &p->ced; - timer8_start(p); - - ced->shift = 32; - ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift); - ced->max_delta_ns = clockevent_delta2ns(0xffff, ced); - ced->min_delta_ns = clockevent_delta2ns(0x0001, ced); timer8_set_next(p, periodic?(p->rate + HZ/2) / HZ:0x10000); } @@ -180,7 +177,7 @@ static int timer8_clock_event_periodic(struct clock_event_device *ced) { struct timer8_priv *p = ced_to_priv(ced); - dev_info(&p->pdev->dev, "used for periodic clock events\n"); + pr_info("%s: used for periodic clock events\n", ced->name); timer8_stop(p); timer8_clock_event_start(p, PERIODIC); @@ -191,7 +188,7 @@ static int timer8_clock_event_oneshot(struct clock_event_device *ced) { struct timer8_priv *p = ced_to_priv(ced); - dev_info(&p->pdev->dev, "used for oneshot clock events\n"); + pr_info("%s: used for oneshot clock events\n", ced->name); timer8_stop(p); timer8_clock_event_start(p, ONESHOT); @@ -209,42 +206,48 @@ static int timer8_clock_event_next(unsigned long delta, return 0; } -static int timer8_setup(struct timer8_priv *p, - struct platform_device *pdev) +static void __init h8300_8timer_init(struct device_node *node) { - struct resource *res; + void __iomem *base; int irq; - int ret; - - memset(p, 0, sizeof(*p)); - p->pdev = pdev; + int ret = 0; + int rate; + struct timer8_priv *p; + struct clk *clk; + + clk = of_clk_get(node, 0); + if (IS_ERR(clk)) { + pr_err("failed to get clock for clockevent\n"); + return; + } - res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&p->pdev->dev, "failed to get I/O memory\n"); - return -ENXIO; + base = of_iomap(node, 0); + if (!base) { + pr_err("failed to map registers for clockevent\n"); + goto free_clk; } - irq = platform_get_irq(p->pdev, 0); + irq = irq_of_parse_and_map(node, 0); if (irq < 0) { - dev_err(&p->pdev->dev, "failed to get irq\n"); - return -ENXIO; + pr_err("failed to get irq for clockevent\n"); + goto unmap_reg; + } + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) { + pr_err("failed to allocate memory for clockevent\n"); + goto unmap_reg; } - p->mapbase = res->start; + p->mapbase = (unsigned long)base; + p->pclk = clk; - p->irqaction.name = dev_name(&p->pdev->dev); + p->irqaction.name = node->name; p->irqaction.handler = timer8_interrupt; p->irqaction.dev_id = p; p->irqaction.flags = IRQF_TIMER; - p->pclk = clk_get(&p->pdev->dev, "fck"); - if (IS_ERR(p->pclk)) { - dev_err(&p->pdev->dev, "can't get clk\n"); - return PTR_ERR(p->pclk); - } - - p->ced.name = pdev->name; + p->ced.name = node->name; p->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; p->ced.rating = 200; @@ -256,64 +259,19 @@ static int timer8_setup(struct timer8_priv *p, ret = setup_irq(irq, &p->irqaction); if (ret < 0) { - dev_err(&p->pdev->dev, - "failed to request irq %d\n", irq); - return ret; - } - clockevents_register_device(&p->ced); - platform_set_drvdata(pdev, p); - - return 0; -} - -static int timer8_probe(struct platform_device *pdev) -{ - struct timer8_priv *p = platform_get_drvdata(pdev); - - if (p) { - dev_info(&pdev->dev, "kept as earlytimer\n"); - return 0; + pr_err("failed to request irq %d for clockevent\n", irq); + goto free_priv; } - - p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); - if (!p) - return -ENOMEM; - - return timer8_setup(p, pdev); -} - -static int timer8_remove(struct platform_device *pdev) -{ - return -EBUSY; -} - -static const struct of_device_id timer8_of_table[] __maybe_unused = { - { .compatible = "renesas,8bit-timer" }, - { } -}; - -MODULE_DEVICE_TABLE(of, timer8_of_table); -static struct platform_driver timer8_driver = { - .probe = timer8_probe, - .remove = timer8_remove, - .driver = { - .name = "h8300-8timer", - .of_match_table = of_match_ptr(timer8_of_table), - } -}; - -static int __init timer8_init(void) -{ - return platform_driver_register(&timer8_driver); -} - -static void __exit timer8_exit(void) -{ - platform_driver_unregister(&timer8_driver); + rate = clk_get_rate(clk) / SCALE; + clockevents_config_and_register(&p->ced, rate, 1, 0x0000ffff); + return; + +free_priv: + kfree(p); +unmap_reg: + iounmap(base); +free_clk: + clk_put(clk); } -subsys_initcall(timer8_init); -module_exit(timer8_exit); -MODULE_AUTHOR("Yoshinori Sato"); -MODULE_DESCRIPTION("H8/300 8bit Timer Driver"); -MODULE_LICENSE("GPL v2"); +CLOCKSOURCE_OF_DECLARE(h8300_8bit, "renesas,8bit-timer", h8300_8timer_init); diff --git a/drivers/clocksource/h8300_tpu.c b/drivers/clocksource/h8300_tpu.c index 64195fd..2dd4daf 100644 --- a/drivers/clocksource/h8300_tpu.c +++ b/drivers/clocksource/h8300_tpu.c @@ -1,5 +1,5 @@ /* - * H8/300 TPU Driver + * H8S TPU Driver * * Copyright 2015 Yoshinori Sato * @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include @@ -32,7 +34,6 @@ #define TGRD 14 struct tpu_priv { - struct platform_device *pdev; struct clocksource cs; struct clk *clk; unsigned long mapbase1; @@ -119,30 +120,39 @@ static void tpu_clocksource_disable(struct clocksource *cs) #define CH_L 0 #define CH_H 1 -static int __init tpu_setup(struct tpu_priv *p, struct platform_device *pdev) +static void __init h8300_tpu_init(struct device_node *node) { - struct resource *res[2]; + void __iomem *base[2]; + struct tpu_priv *p; + struct clk *clk; - memset(p, 0, sizeof(*p)); - p->pdev = pdev; + clk = of_clk_get(node, 0); + if (IS_ERR(clk)) { + pr_err("failed to get clock for clocksource\n"); + return; + } - res[CH_L] = platform_get_resource(p->pdev, IORESOURCE_MEM, CH_L); - res[CH_H] = platform_get_resource(p->pdev, IORESOURCE_MEM, CH_H); - if (!res[CH_L] || !res[CH_H]) { - dev_err(&p->pdev->dev, "failed to get I/O memory\n"); - return -ENXIO; + base[CH_L] = of_iomap(node, CH_L); + if (!base[CH_L]) { + pr_err("failed to map registers for clocksource\n"); + goto free_clk; + } + base[CH_H] = of_iomap(node, CH_H); + if (!base[CH_H]) { + pr_err("failed to map registers for clocksource\n"); + goto unmap_L; } - p->clk = clk_get(&p->pdev->dev, "fck"); - if (IS_ERR(p->clk)) { - dev_err(&p->pdev->dev, "can't get clk\n"); - return PTR_ERR(p->clk); + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) { + pr_err("failed to allocate memory for clocksource\n"); + goto unmap_H; } - p->mapbase1 = res[CH_L]->start; - p->mapbase2 = res[CH_H]->start; + p->mapbase1 = (unsigned long)base[CH_L]; + p->mapbase2 = (unsigned long)base[CH_H]; - p->cs.name = pdev->name; + p->cs.name = node->name; p->cs.rating = 200; p->cs.read = tpu_clocksource_read; p->cs.enable = tpu_clocksource_enable; @@ -150,58 +160,15 @@ static int __init tpu_setup(struct tpu_priv *p, struct platform_device *pdev) p->cs.mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); p->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; clocksource_register_hz(&p->cs, clk_get_rate(p->clk) / 64); - platform_set_drvdata(pdev, p); - - return 0; -} - -static int tpu_probe(struct platform_device *pdev) -{ - struct tpu_priv *p = platform_get_drvdata(pdev); - - if (p) { - dev_info(&pdev->dev, "kept as earlytimer\n"); - return 0; - } - - p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); - if (!p) - return -ENOMEM; - - return tpu_setup(p, pdev); -} - -static int tpu_remove(struct platform_device *pdev) -{ - return -EBUSY; -} - -static const struct of_device_id tpu_of_table[] = { - { .compatible = "renesas,tpu" }, - { } -}; -static struct platform_driver tpu_driver = { - .probe = tpu_probe, - .remove = tpu_remove, - .driver = { - .name = "h8s-tpu", - .of_match_table = of_match_ptr(tpu_of_table), - } -}; - -static int __init tpu_init(void) -{ - return platform_driver_register(&tpu_driver); -} + return; -static void __exit tpu_exit(void) -{ - platform_driver_unregister(&tpu_driver); +unmap_H: + iounmap(base[CH_H]); +unmap_L: + iounmap(base[CH_H]); +free_clk: + clk_put(clk); } -subsys_initcall(tpu_init); -module_exit(tpu_exit); -MODULE_AUTHOR("Yoshinori Sato"); -MODULE_DESCRIPTION("H8S Timer Pulse Unit Driver"); -MODULE_LICENSE("GPL v2"); +CLOCKSOURCE_OF_DECLARE(h8300_tpu, "renesas,tpu", h8300_tpu_init); -- 2.6.1 -- 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/