From bbb4ce50f3169b08764f9965fd5b9655646d545a Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Fri, 6 Apr 2012 09:59:14 +0900 Subject: serial: sh-sci: modify sci_break_ctl() SCIF modules which have SCSPTR can output the break signal. Now that we have a way of determining port features/capabilities, add trivial break control via SCSPTR support. Tested on sh7757lcr. Signed-off-by: Yoshihiro Shimoda Reviewed-by: Simon Horman Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 3158e17b665c..3e471fc12991 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1564,10 +1564,32 @@ static void sci_enable_ms(struct uart_port *port) static void sci_break_ctl(struct uart_port *port, int break_state) { - /* - * Not supported by hardware. Most parts couple break and rx - * interrupts together, with break detection always enabled. - */ + struct sci_port *s = to_sci_port(port); + unsigned short scscr, scsptr; + + switch (s->cfg->regtype) { + case SCIx_SH4_SCIF_REGTYPE: + scsptr = serial_port_in(port, SCSPTR); + scscr = serial_port_in(port, SCSCR); + + if (break_state == -1) { + scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT; + scscr &= ~SCSCR_TE; + } else { + scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO; + scscr |= SCSCR_TE; + } + + serial_port_out(port, SCSPTR, scsptr); + serial_port_out(port, SCSCR, scscr); + break; + default: + /* + * Not supported by hardware. Most parts couple break and rx + * interrupts together, with break detection always enabled. + */ + break; + } } #ifdef CONFIG_SERIAL_SH_SCI_DMA -- cgit v1.2.2 From 4d6ddb08acc48368c5b7ac431f9d00db7227d2ed Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 11 Apr 2012 12:05:50 +0900 Subject: sh: clkfwk: Support variable size accesses for MSTP clocks. The bulk of the MSTP users require 32-bit access, but this isn't the case for some of the SH-2A parts, so add in some basic infrastructure to let the CPU define its required access size in preparation. Requested-by: Phil Edworthy Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 91b6d52f74eb..6cbda4841589 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -2,6 +2,7 @@ * Helper routines for SuperH Clock Pulse Generator blocks (CPG). * * Copyright (C) 2010 Magnus Damm + * Copyright (C) 2010 - 2012 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -13,26 +14,41 @@ #include #include -static int sh_clk_mstp32_enable(struct clk *clk) +static int sh_clk_mstp_enable(struct clk *clk) { - iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit), - clk->mapped_reg); + if (clk->flags & CLK_ENABLE_REG_8BIT) + iowrite8(ioread8(clk->mapped_reg) & ~(1 << clk->enable_bit), + clk->mapped_reg); + else if (clk->flags & CLK_ENABLE_REG_16BIT) + iowrite16(ioread16(clk->mapped_reg) & ~(1 << clk->enable_bit), + clk->mapped_reg); + else + iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit), + clk->mapped_reg); + return 0; } -static void sh_clk_mstp32_disable(struct clk *clk) +static void sh_clk_mstp_disable(struct clk *clk) { - iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit), - clk->mapped_reg); + if (clk->flags & CLK_ENABLE_REG_8BIT) + iowrite8(ioread8(clk->mapped_reg) | (1 << clk->enable_bit), + clk->mapped_reg); + else if (clk->flags & CLK_ENABLE_REG_16BIT) + iowrite16(ioread16(clk->mapped_reg) | (1 << clk->enable_bit), + clk->mapped_reg); + else + iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit), + clk->mapped_reg); } -static struct sh_clk_ops sh_clk_mstp32_clk_ops = { - .enable = sh_clk_mstp32_enable, - .disable = sh_clk_mstp32_disable, +static struct sh_clk_ops sh_clk_mstp_clk_ops = { + .enable = sh_clk_mstp_enable, + .disable = sh_clk_mstp_disable, .recalc = followparent_recalc, }; -int __init sh_clk_mstp32_register(struct clk *clks, int nr) +int __init sh_clk_mstp_register(struct clk *clks, int nr) { struct clk *clkp; int ret = 0; @@ -40,7 +56,7 @@ int __init sh_clk_mstp32_register(struct clk *clks, int nr) for (k = 0; !ret && (k < nr); k++) { clkp = clks + k; - clkp->ops = &sh_clk_mstp32_clk_ops; + clkp->ops = &sh_clk_mstp_clk_ops; ret |= clk_register(clkp); } -- cgit v1.2.2 From a4e02f6d83d4fcdb13bcaba76878fc5ea0da9911 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Thu, 12 Apr 2012 19:19:21 +0900 Subject: serial: sh-sci: Update break_ctl handling for all SCSPTR-capable regtypes. This updates the earlier break_ctl support regardless of regtype so long as the requisite SCSPTR exists. This is the same approach used by sci_init_pins() for providing a generic solution now that we're able to detect register capabilities on a per-port basis. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 3e471fc12991..be31d85a50e3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1565,31 +1565,31 @@ static void sci_enable_ms(struct uart_port *port) static void sci_break_ctl(struct uart_port *port, int break_state) { struct sci_port *s = to_sci_port(port); + struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; unsigned short scscr, scsptr; - switch (s->cfg->regtype) { - case SCIx_SH4_SCIF_REGTYPE: - scsptr = serial_port_in(port, SCSPTR); - scscr = serial_port_in(port, SCSCR); - - if (break_state == -1) { - scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT; - scscr &= ~SCSCR_TE; - } else { - scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO; - scscr |= SCSCR_TE; - } - - serial_port_out(port, SCSPTR, scsptr); - serial_port_out(port, SCSCR, scscr); - break; - default: + /* check wheter the port has SCSPTR */ + if (!reg->size) { /* * Not supported by hardware. Most parts couple break and rx * interrupts together, with break detection always enabled. */ - break; + return; } + + scsptr = serial_port_in(port, SCSPTR); + scscr = serial_port_in(port, SCSCR); + + if (break_state == -1) { + scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT; + scscr &= ~SCSCR_TE; + } else { + scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO; + scscr |= SCSCR_TE; + } + + serial_port_out(port, SCSPTR, scsptr); + serial_port_out(port, SCSCR, scscr); } #ifdef CONFIG_SERIAL_SH_SCI_DMA -- cgit v1.2.2 From 104fa61a7dd83197160d5cafedc0e94ad9cd7fcc Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 12 Apr 2012 19:50:40 +0900 Subject: sh: clkfwk: Support variable size accesses for div4/div6 clocks. This follows the MSTP clock change and implements variable access size support for the rest of the CPG clocks, too. Upcoming SH-2A support has need of this for 16-bit div4 clocks, while others will follow. Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 71 +++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 6cbda4841589..f0d015dd0fef 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -14,32 +14,35 @@ #include #include -static int sh_clk_mstp_enable(struct clk *clk) +static unsigned int sh_clk_read(struct clk *clk) { if (clk->flags & CLK_ENABLE_REG_8BIT) - iowrite8(ioread8(clk->mapped_reg) & ~(1 << clk->enable_bit), - clk->mapped_reg); + return ioread8(clk->mapped_reg); else if (clk->flags & CLK_ENABLE_REG_16BIT) - iowrite16(ioread16(clk->mapped_reg) & ~(1 << clk->enable_bit), - clk->mapped_reg); - else - iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit), - clk->mapped_reg); + return ioread16(clk->mapped_reg); - return 0; + return ioread32(clk->mapped_reg); } -static void sh_clk_mstp_disable(struct clk *clk) +static void sh_clk_write(int value, struct clk *clk) { if (clk->flags & CLK_ENABLE_REG_8BIT) - iowrite8(ioread8(clk->mapped_reg) | (1 << clk->enable_bit), - clk->mapped_reg); + iowrite8(value, clk->mapped_reg); else if (clk->flags & CLK_ENABLE_REG_16BIT) - iowrite16(ioread16(clk->mapped_reg) | (1 << clk->enable_bit), - clk->mapped_reg); + iowrite16(value, clk->mapped_reg); else - iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit), - clk->mapped_reg); + iowrite32(value, clk->mapped_reg); +} + +static int sh_clk_mstp_enable(struct clk *clk) +{ + sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk); + return 0; +} + +static void sh_clk_mstp_disable(struct clk *clk) +{ + sh_clk_write(sh_clk_read(clk) | (1 << clk->enable_bit), clk); } static struct sh_clk_ops sh_clk_mstp_clk_ops = { @@ -88,7 +91,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk) clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, table, NULL); - idx = ioread32(clk->mapped_reg) & 0x003f; + idx = sh_clk_read(clk) & 0x003f; return clk->freq_table[idx].frequency; } @@ -114,10 +117,10 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) if (ret < 0) return ret; - value = ioread32(clk->mapped_reg) & + value = sh_clk_read(clk) & ~(((1 << clk->src_width) - 1) << clk->src_shift); - iowrite32(value | (i << clk->src_shift), clk->mapped_reg); + sh_clk_write(value | (i << clk->src_shift), clk); /* Rebuild the frequency table */ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, @@ -135,10 +138,10 @@ static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate) if (idx < 0) return idx; - value = ioread32(clk->mapped_reg); + value = sh_clk_read(clk); value &= ~0x3f; value |= idx; - iowrite32(value, clk->mapped_reg); + sh_clk_write(value, clk); return 0; } @@ -149,9 +152,9 @@ static int sh_clk_div6_enable(struct clk *clk) ret = sh_clk_div6_set_rate(clk, clk->rate); if (ret == 0) { - value = ioread32(clk->mapped_reg); + value = sh_clk_read(clk); value &= ~0x100; /* clear stop bit to enable clock */ - iowrite32(value, clk->mapped_reg); + sh_clk_write(value, clk); } return ret; } @@ -160,10 +163,10 @@ static void sh_clk_div6_disable(struct clk *clk) { unsigned long value; - value = ioread32(clk->mapped_reg); + value = sh_clk_read(clk); value |= 0x100; /* stop clock */ value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ - iowrite32(value, clk->mapped_reg); + sh_clk_write(value, clk); } static struct sh_clk_ops sh_clk_div6_clk_ops = { @@ -198,7 +201,7 @@ static int __init sh_clk_init_parent(struct clk *clk) return -EINVAL; } - val = (ioread32(clk->mapped_reg) >> clk->src_shift); + val = (sh_clk_read(clk) >> clk->src_shift); val &= (1 << clk->src_width) - 1; if (val >= clk->parent_num) { @@ -268,7 +271,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk) clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, table, &clk->arch_flags); - idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f; + idx = (sh_clk_read(clk) >> clk->enable_bit) & 0x000f; return clk->freq_table[idx].frequency; } @@ -286,15 +289,15 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) */ if (parent->flags & CLK_ENABLE_ON_INIT) - value = ioread32(clk->mapped_reg) & ~(1 << 7); + value = sh_clk_read(clk) & ~(1 << 7); else - value = ioread32(clk->mapped_reg) | (1 << 7); + value = sh_clk_read(clk) | (1 << 7); ret = clk_reparent(clk, parent); if (ret < 0) return ret; - iowrite32(value, clk->mapped_reg); + sh_clk_write(value, clk); /* Rebiuld the frequency table */ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, @@ -311,10 +314,10 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) if (idx < 0) return idx; - value = ioread32(clk->mapped_reg); + value = sh_clk_read(clk); value &= ~(0xf << clk->enable_bit); value |= (idx << clk->enable_bit); - iowrite32(value, clk->mapped_reg); + sh_clk_write(value, clk); if (d4t->kick) d4t->kick(clk); @@ -324,13 +327,13 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) static int sh_clk_div4_enable(struct clk *clk) { - iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg); + sh_clk_write(sh_clk_read(clk) & ~(1 << 8), clk); return 0; } static void sh_clk_div4_disable(struct clk *clk) { - iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg); + sh_clk_write(sh_clk_read(clk) | (1 << 8), clk); } static struct sh_clk_ops sh_clk_div4_clk_ops = { -- cgit v1.2.2 From 40968126366219d11201257b5006878f939c1c5c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 10 May 2012 14:21:15 +0900 Subject: watchdog: shwdt: Migrate from reboot notifier to platform shutdown. It's possible to do the same work via the platform driver shutdown method, so wire that up and dump the reboot notifier. Signed-off-by: Paul Mundt --- drivers/watchdog/shwdt.c | 43 ++++++++++++------------------------------- 1 file changed, 12 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 93958a7763e6..74a261f36702 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -3,7 +3,7 @@ * * Watchdog driver for integrated watchdog in the SuperH processors. * - * Copyright (C) 2001 - 2010 Paul Mundt + * Copyright (C) 2001 - 2012 Paul Mundt * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include @@ -293,17 +291,6 @@ static long sh_wdt_ioctl(struct file *file, unsigned int cmd, return 0; } -static int sh_wdt_notify_sys(struct notifier_block *this, - unsigned long code, void *unused) -{ - struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev); - - if (code == SYS_DOWN || code == SYS_HALT) - sh_wdt_stop(wdt); - - return NOTIFY_DONE; -} - static const struct file_operations sh_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, @@ -320,10 +307,6 @@ static const struct watchdog_info sh_wdt_info = { .identity = "SH WDT", }; -static struct notifier_block sh_wdt_notifier = { - .notifier_call = sh_wdt_notify_sys, -}; - static struct miscdevice sh_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", @@ -365,13 +348,6 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) goto out_err; } - rc = register_reboot_notifier(&sh_wdt_notifier); - if (unlikely(rc)) { - dev_err(&pdev->dev, - "Can't register reboot notifier (err=%d)\n", rc); - goto out_unmap; - } - sh_wdt_miscdev.parent = wdt->dev; rc = misc_register(&sh_wdt_miscdev); @@ -379,7 +355,7 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Can't register miscdev on minor=%d (err=%d)\n", sh_wdt_miscdev.minor, rc); - goto out_unreg; + goto out_unmap; } init_timer(&wdt->timer); @@ -394,8 +370,6 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) return 0; -out_unreg: - unregister_reboot_notifier(&sh_wdt_notifier); out_unmap: devm_iounmap(&pdev->dev, wdt->base); out_err: @@ -417,7 +391,6 @@ static int __devexit sh_wdt_remove(struct platform_device *pdev) sh_wdt_dev = NULL; - unregister_reboot_notifier(&sh_wdt_notifier); devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); devm_iounmap(&pdev->dev, wdt->base); devm_kfree(&pdev->dev, wdt); @@ -425,14 +398,22 @@ static int __devexit sh_wdt_remove(struct platform_device *pdev) return 0; } +static void sh_wdt_shutdown(struct platform_device *pdev) +{ + struct sh_wdt *wdt = platform_get_drvdata(pdev); + + sh_wdt_stop(wdt); +} + static struct platform_driver sh_wdt_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, }, - .probe = sh_wdt_probe, - .remove = __devexit_p(sh_wdt_remove), + .probe = sh_wdt_probe, + .remove = __devexit_p(sh_wdt_remove), + .shutdown = sh_wdt_shutdown, }; static int __init sh_wdt_init(void) -- cgit v1.2.2 From 1950f499df4eacb5d89cf0151f5edda139b800f4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 10 May 2012 15:07:53 +0900 Subject: watchdog: shwdt: Conversion to watchdog core. Fairly straightforward conversion to utilize watchdog core support. Signed-off-by: Paul Mundt --- drivers/watchdog/Kconfig | 1 + drivers/watchdog/shwdt.c | 198 +++++++++++------------------------------------ 2 files changed, 45 insertions(+), 154 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 37096246c937..67957393393f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1138,6 +1138,7 @@ config ZVM_WATCHDOG config SH_WDT tristate "SuperH Watchdog" depends on SUPERH && (CPU_SH3 || CPU_SH4) + select WATCHDOG_CORE help This driver adds watchdog support for the integrated watchdog in the SuperH processors. If you have one of these processors and wish diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 74a261f36702..0beabf238d4f 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -27,12 +27,10 @@ #include #include #include -#include #include #include #include #include -#include #include #define DRV_NAME "sh-wdt" @@ -67,8 +65,6 @@ static int clock_division_ratio = WTCSR_CKS_4096; #define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) -static const struct watchdog_info sh_wdt_info; -static struct platform_device *sh_wdt_dev; static DEFINE_SPINLOCK(shwdt_lock); #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ @@ -86,8 +82,9 @@ struct sh_wdt { char expect_close; }; -static void sh_wdt_start(struct sh_wdt *wdt) +static int sh_wdt_start(struct watchdog_device *wdt_dev) { + struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); unsigned long flags; u8 csr; @@ -121,10 +118,13 @@ static void sh_wdt_start(struct sh_wdt *wdt) sh_wdt_write_rstcsr(csr); #endif spin_unlock_irqrestore(&shwdt_lock, flags); + + return 0; } -static void sh_wdt_stop(struct sh_wdt *wdt) +static int sh_wdt_stop(struct watchdog_device *wdt_dev) { + struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); unsigned long flags; u8 csr; @@ -137,18 +137,22 @@ static void sh_wdt_stop(struct sh_wdt *wdt) sh_wdt_write_csr(csr); spin_unlock_irqrestore(&shwdt_lock, flags); + + return 0; } -static inline void sh_wdt_keepalive(struct sh_wdt *wdt) +static int sh_wdt_keepalive(struct watchdog_device *wdt_dev) { unsigned long flags; spin_lock_irqsave(&shwdt_lock, flags); next_heartbeat = jiffies + (heartbeat * HZ); spin_unlock_irqrestore(&shwdt_lock, flags); + + return 0; } -static int sh_wdt_set_heartbeat(int t) +static int sh_wdt_set_heartbeat(struct watchdog_device *wdt_dev, unsigned t) { unsigned long flags; @@ -157,7 +161,9 @@ static int sh_wdt_set_heartbeat(int t) spin_lock_irqsave(&shwdt_lock, flags); heartbeat = t; + wdt_dev->timeout = t; spin_unlock_irqrestore(&shwdt_lock, flags); + return 0; } @@ -183,123 +189,6 @@ static void sh_wdt_ping(unsigned long data) spin_unlock_irqrestore(&shwdt_lock, flags); } -static int sh_wdt_open(struct inode *inode, struct file *file) -{ - struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev); - - if (test_and_set_bit(0, &wdt->enabled)) - return -EBUSY; - if (nowayout) - __module_get(THIS_MODULE); - - file->private_data = wdt; - - sh_wdt_start(wdt); - - return nonseekable_open(inode, file); -} - -static int sh_wdt_close(struct inode *inode, struct file *file) -{ - struct sh_wdt *wdt = file->private_data; - - if (wdt->expect_close == 42) { - sh_wdt_stop(wdt); - } else { - dev_crit(wdt->dev, "Unexpected close, not " - "stopping watchdog!\n"); - sh_wdt_keepalive(wdt); - } - - clear_bit(0, &wdt->enabled); - wdt->expect_close = 0; - - return 0; -} - -static ssize_t sh_wdt_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct sh_wdt *wdt = file->private_data; - - if (count) { - if (!nowayout) { - size_t i; - - wdt->expect_close = 0; - - for (i = 0; i != count; i++) { - char c; - if (get_user(c, buf + i)) - return -EFAULT; - if (c == 'V') - wdt->expect_close = 42; - } - } - sh_wdt_keepalive(wdt); - } - - return count; -} - -static long sh_wdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct sh_wdt *wdt = file->private_data; - int new_heartbeat; - int options, retval = -EINVAL; - - switch (cmd) { - case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, - &sh_wdt_info, sizeof(sh_wdt_info)) ? -EFAULT : 0; - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); - case WDIOC_SETOPTIONS: - if (get_user(options, (int *)arg)) - return -EFAULT; - - if (options & WDIOS_DISABLECARD) { - sh_wdt_stop(wdt); - retval = 0; - } - - if (options & WDIOS_ENABLECARD) { - sh_wdt_start(wdt); - retval = 0; - } - - return retval; - case WDIOC_KEEPALIVE: - sh_wdt_keepalive(wdt); - return 0; - case WDIOC_SETTIMEOUT: - if (get_user(new_heartbeat, (int *)arg)) - return -EFAULT; - - if (sh_wdt_set_heartbeat(new_heartbeat)) - return -EINVAL; - - sh_wdt_keepalive(wdt); - /* Fall */ - case WDIOC_GETTIMEOUT: - return put_user(heartbeat, (int *)arg); - default: - return -ENOTTY; - } - return 0; -} - -static const struct file_operations sh_wdt_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .write = sh_wdt_write, - .unlocked_ioctl = sh_wdt_ioctl, - .open = sh_wdt_open, - .release = sh_wdt_close, -}; - static const struct watchdog_info sh_wdt_info = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, @@ -307,10 +196,17 @@ static const struct watchdog_info sh_wdt_info = { .identity = "SH WDT", }; -static struct miscdevice sh_wdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &sh_wdt_fops, +static const struct watchdog_ops sh_wdt_ops = { + .owner = THIS_MODULE, + .start = sh_wdt_start, + .stop = sh_wdt_stop, + .ping = sh_wdt_keepalive, + .set_timeout = sh_wdt_set_heartbeat, +}; + +static struct watchdog_device sh_wdt_dev = { + .info = &sh_wdt_info, + .ops = &sh_wdt_ops, }; static int __devinit sh_wdt_probe(struct platform_device *pdev) @@ -348,13 +244,25 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) goto out_err; } - sh_wdt_miscdev.parent = wdt->dev; + rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat); + if (unlikely(rc)) { + /* Default timeout if invalid */ + sh_wdt_set_heartbeat(&sh_wdt_dev, WATCHDOG_HEARTBEAT); + + dev_warn(&pdev->dev, + "heartbeat value must be 1<=x<=3600, using %d\n", + sh_wdt_dev.timeout); + } + + dev_info(&pdev->dev, "configured with heartbeat=%d sec (nowayout=%d)\n", + sh_wdt_dev.timeout, nowayout); - rc = misc_register(&sh_wdt_miscdev); + watchdog_set_nowayout(&sh_wdt_dev, nowayout); + watchdog_set_drvdata(&sh_wdt_dev, wdt); + + rc = watchdog_register_device(&sh_wdt_dev); if (unlikely(rc)) { - dev_err(&pdev->dev, - "Can't register miscdev on minor=%d (err=%d)\n", - sh_wdt_miscdev.minor, rc); + dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); goto out_unmap; } @@ -364,7 +272,6 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) wdt->timer.expires = next_ping_period(clock_division_ratio); platform_set_drvdata(pdev, wdt); - sh_wdt_dev = pdev; dev_info(&pdev->dev, "initialized.\n"); @@ -387,9 +294,7 @@ static int __devexit sh_wdt_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - misc_deregister(&sh_wdt_miscdev); - - sh_wdt_dev = NULL; + watchdog_unregister_device(&sh_wdt_dev); devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); devm_iounmap(&pdev->dev, wdt->base); @@ -400,9 +305,7 @@ static int __devexit sh_wdt_remove(struct platform_device *pdev) static void sh_wdt_shutdown(struct platform_device *pdev) { - struct sh_wdt *wdt = platform_get_drvdata(pdev); - - sh_wdt_stop(wdt); + sh_wdt_stop(&sh_wdt_dev); } static struct platform_driver sh_wdt_driver = { @@ -418,8 +321,6 @@ static struct platform_driver sh_wdt_driver = { static int __init sh_wdt_init(void) { - int rc; - if (unlikely(clock_division_ratio < 0x5 || clock_division_ratio > 0x7)) { clock_division_ratio = WTCSR_CKS_4096; @@ -428,17 +329,6 @@ static int __init sh_wdt_init(void) clock_division_ratio); } - rc = sh_wdt_set_heartbeat(heartbeat); - if (unlikely(rc)) { - heartbeat = WATCHDOG_HEARTBEAT; - - pr_info("heartbeat value must be 1<=x<=3600, using %d\n", - heartbeat); - } - - pr_info("configured with heartbeat=%d sec (nowayout=%d)\n", - heartbeat, nowayout); - return platform_driver_register(&sh_wdt_driver); } -- cgit v1.2.2 From f9fb360cb3440fb7d22ad7061de4e99235a97e1c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 10 May 2012 15:15:08 +0900 Subject: watchdog: shwdt: Migrate to per-device locking. Presently we've been using global locking for everything. Push the locking down to the per-device level in preparation for per-CPU watchdogs. Signed-off-by: Paul Mundt --- drivers/watchdog/shwdt.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 0beabf238d4f..0d734a38d29f 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -65,8 +66,6 @@ static int clock_division_ratio = WTCSR_CKS_4096; #define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) -static DEFINE_SPINLOCK(shwdt_lock); - #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ static bool nowayout = WATCHDOG_NOWAYOUT; @@ -75,6 +74,7 @@ static unsigned long next_heartbeat; struct sh_wdt { void __iomem *base; struct device *dev; + spinlock_t lock; struct timer_list timer; @@ -88,7 +88,7 @@ static int sh_wdt_start(struct watchdog_device *wdt_dev) unsigned long flags; u8 csr; - spin_lock_irqsave(&shwdt_lock, flags); + spin_lock_irqsave(&wdt->lock, flags); next_heartbeat = jiffies + (heartbeat * HZ); mod_timer(&wdt->timer, next_ping_period(clock_division_ratio)); @@ -117,7 +117,7 @@ static int sh_wdt_start(struct watchdog_device *wdt_dev) csr &= ~RSTCSR_RSTS; sh_wdt_write_rstcsr(csr); #endif - spin_unlock_irqrestore(&shwdt_lock, flags); + spin_unlock_irqrestore(&wdt->lock, flags); return 0; } @@ -128,7 +128,7 @@ static int sh_wdt_stop(struct watchdog_device *wdt_dev) unsigned long flags; u8 csr; - spin_lock_irqsave(&shwdt_lock, flags); + spin_lock_irqsave(&wdt->lock, flags); del_timer(&wdt->timer); @@ -136,33 +136,35 @@ static int sh_wdt_stop(struct watchdog_device *wdt_dev) csr &= ~WTCSR_TME; sh_wdt_write_csr(csr); - spin_unlock_irqrestore(&shwdt_lock, flags); + spin_unlock_irqrestore(&wdt->lock, flags); return 0; } static int sh_wdt_keepalive(struct watchdog_device *wdt_dev) { + struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); unsigned long flags; - spin_lock_irqsave(&shwdt_lock, flags); + spin_lock_irqsave(&wdt->lock, flags); next_heartbeat = jiffies + (heartbeat * HZ); - spin_unlock_irqrestore(&shwdt_lock, flags); + spin_unlock_irqrestore(&wdt->lock, flags); return 0; } static int sh_wdt_set_heartbeat(struct watchdog_device *wdt_dev, unsigned t) { + struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); unsigned long flags; if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */ return -EINVAL; - spin_lock_irqsave(&shwdt_lock, flags); + spin_lock_irqsave(&wdt->lock, flags); heartbeat = t; wdt_dev->timeout = t; - spin_unlock_irqrestore(&shwdt_lock, flags); + spin_unlock_irqrestore(&wdt->lock, flags); return 0; } @@ -172,7 +174,7 @@ static void sh_wdt_ping(unsigned long data) struct sh_wdt *wdt = (struct sh_wdt *)data; unsigned long flags; - spin_lock_irqsave(&shwdt_lock, flags); + spin_lock_irqsave(&wdt->lock, flags); if (time_before(jiffies, next_heartbeat)) { u8 csr; @@ -186,7 +188,7 @@ static void sh_wdt_ping(unsigned long data) } else dev_warn(wdt->dev, "Heartbeat lost! Will not ping " "the watchdog\n"); - spin_unlock_irqrestore(&shwdt_lock, flags); + spin_unlock_irqrestore(&wdt->lock, flags); } static const struct watchdog_info sh_wdt_info = { @@ -238,12 +240,17 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) wdt->dev = &pdev->dev; + watchdog_set_nowayout(&sh_wdt_dev, nowayout); + watchdog_set_drvdata(&sh_wdt_dev, wdt); + wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (unlikely(!wdt->base)) { rc = -ENXIO; goto out_err; } + spin_lock_init(&wdt->lock); + rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat); if (unlikely(rc)) { /* Default timeout if invalid */ @@ -257,9 +264,6 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) dev_info(&pdev->dev, "configured with heartbeat=%d sec (nowayout=%d)\n", sh_wdt_dev.timeout, nowayout); - watchdog_set_nowayout(&sh_wdt_dev, nowayout); - watchdog_set_drvdata(&sh_wdt_dev, wdt); - rc = watchdog_register_device(&sh_wdt_dev); if (unlikely(rc)) { dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); -- cgit v1.2.2 From f9e2eae6c66437a414988b44e1d2b8c025134883 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 10 May 2012 15:20:18 +0900 Subject: watchdog: shwdt: Trim down private data structure. Now that we're using the generic watchdog core, kill off unused elements from the private data structure. Signed-off-by: Paul Mundt --- drivers/watchdog/shwdt.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 0d734a38d29f..de3630d6bd4d 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -77,9 +77,6 @@ struct sh_wdt { spinlock_t lock; struct timer_list timer; - - unsigned long enabled; - char expect_close; }; static int sh_wdt_start(struct watchdog_device *wdt_dev) -- cgit v1.2.2 From 9ea6404691a520f734b819cbbd4757b0ea5f99c6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 10 May 2012 15:46:48 +0900 Subject: watchdog: shwdt: Basic clock framework support. This plugs in basic clock framework support for the watchdog. As it's an optional MSTP bit, we don't particularly care if a platform has provided it or not, though a valid clock will need to be available for the more complex overflow period calculations found on newer parts -- this will be addressed later. Signed-off-by: Paul Mundt --- drivers/watchdog/shwdt.c | 50 +++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index de3630d6bd4d..380ada4e5d66 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #define DRV_NAME "sh-wdt" @@ -74,6 +75,7 @@ static unsigned long next_heartbeat; struct sh_wdt { void __iomem *base; struct device *dev; + struct clk *clk; spinlock_t lock; struct timer_list timer; @@ -225,27 +227,32 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) if (unlikely(!res)) return -EINVAL; - if (!devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), DRV_NAME)) - return -EBUSY; - wdt = devm_kzalloc(&pdev->dev, sizeof(struct sh_wdt), GFP_KERNEL); - if (unlikely(!wdt)) { - rc = -ENOMEM; - goto out_release; - } + if (unlikely(!wdt)) + return -ENOMEM; wdt->dev = &pdev->dev; - watchdog_set_nowayout(&sh_wdt_dev, nowayout); - watchdog_set_drvdata(&sh_wdt_dev, wdt); + wdt->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(wdt->clk)) { + /* + * Clock framework support is optional, continue on + * anyways if we don't find a matching clock. + */ + wdt->clk = NULL; + } - wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + clk_enable(wdt->clk); + + wdt->base = devm_request_and_ioremap(wdt->dev, res); if (unlikely(!wdt->base)) { - rc = -ENXIO; - goto out_err; + rc = -EADDRNOTAVAIL; + goto out_disable; } + watchdog_set_nowayout(&sh_wdt_dev, nowayout); + watchdog_set_drvdata(&sh_wdt_dev, wdt); + spin_lock_init(&wdt->lock); rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat); @@ -264,7 +271,7 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) rc = watchdog_register_device(&sh_wdt_dev); if (unlikely(rc)) { dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); - goto out_unmap; + goto out_disable; } init_timer(&wdt->timer); @@ -278,12 +285,9 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) return 0; -out_unmap: - devm_iounmap(&pdev->dev, wdt->base); -out_err: - devm_kfree(&pdev->dev, wdt); -out_release: - devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); +out_disable: + clk_disable(wdt->clk); + clk_put(wdt->clk); return rc; } @@ -291,15 +295,13 @@ out_release: static int __devexit sh_wdt_remove(struct platform_device *pdev) { struct sh_wdt *wdt = platform_get_drvdata(pdev); - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); platform_set_drvdata(pdev, NULL); watchdog_unregister_device(&sh_wdt_dev); - devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); - devm_iounmap(&pdev->dev, wdt->base); - devm_kfree(&pdev->dev, wdt); + clk_disable(wdt->clk); + clk_put(wdt->clk); return 0; } -- cgit v1.2.2 From 8c013d964ac32c20afe2cdeadf59926d87012b37 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 10 May 2012 16:08:35 +0900 Subject: watchdog: shwdt: Preliminary runtime PM support. This plugs in some trivial runtime PM support in the probe/remove and start/stop paths. Signed-off-by: Paul Mundt --- drivers/watchdog/shwdt.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 380ada4e5d66..b11104702d23 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +88,8 @@ static int sh_wdt_start(struct watchdog_device *wdt_dev) unsigned long flags; u8 csr; + pm_runtime_get_sync(wdt->dev); + spin_lock_irqsave(&wdt->lock, flags); next_heartbeat = jiffies + (heartbeat * HZ); @@ -137,6 +140,8 @@ static int sh_wdt_stop(struct watchdog_device *wdt_dev) spin_unlock_irqrestore(&wdt->lock, flags); + pm_runtime_put_sync(wdt->dev); + return 0; } @@ -283,6 +288,8 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) dev_info(&pdev->dev, "initialized.\n"); + pm_runtime_enable(&pdev->dev); + return 0; out_disable: @@ -300,6 +307,7 @@ static int __devexit sh_wdt_remove(struct platform_device *pdev) watchdog_unregister_device(&sh_wdt_dev); + pm_runtime_disable(&pdev->dev); clk_disable(wdt->clk); clk_put(wdt->clk); -- cgit v1.2.2 From d42c97443da5a542201f6cbaf793606877115d05 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 10 May 2012 16:14:40 +0900 Subject: watchdog: shwdt: Use finer grained clock control. The clk enable/disable pairs can be pushed down to start/stop rather than probe/remove, along with the runtime PM callsites. This will allow us to keep the block powered off until userspace comes along and decides to do something with it. Signed-off-by: Paul Mundt --- drivers/watchdog/shwdt.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index b11104702d23..e5b59bebcdb1 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -89,6 +89,7 @@ static int sh_wdt_start(struct watchdog_device *wdt_dev) u8 csr; pm_runtime_get_sync(wdt->dev); + clk_enable(wdt->clk); spin_lock_irqsave(&wdt->lock, flags); @@ -140,6 +141,7 @@ static int sh_wdt_stop(struct watchdog_device *wdt_dev) spin_unlock_irqrestore(&wdt->lock, flags); + clk_disable(wdt->clk); pm_runtime_put_sync(wdt->dev); return 0; @@ -247,12 +249,10 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) wdt->clk = NULL; } - clk_enable(wdt->clk); - wdt->base = devm_request_and_ioremap(wdt->dev, res); if (unlikely(!wdt->base)) { rc = -EADDRNOTAVAIL; - goto out_disable; + goto err; } watchdog_set_nowayout(&sh_wdt_dev, nowayout); @@ -276,7 +276,7 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) rc = watchdog_register_device(&sh_wdt_dev); if (unlikely(rc)) { dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); - goto out_disable; + goto err; } init_timer(&wdt->timer); @@ -292,8 +292,7 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) return 0; -out_disable: - clk_disable(wdt->clk); +err: clk_put(wdt->clk); return rc; @@ -308,7 +307,6 @@ static int __devexit sh_wdt_remove(struct platform_device *pdev) watchdog_unregister_device(&sh_wdt_dev); pm_runtime_disable(&pdev->dev); - clk_disable(wdt->clk); clk_put(wdt->clk); return 0; -- cgit v1.2.2 From 0e8963de1fe95e7fbc30c79c1dbc7cb1ea0cf699 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 18 May 2012 18:21:06 +0900 Subject: serial: sh-sci: Fix for port types without BRI interrupts. In doing the evt2irq() + muxed vector conversion for various port types it became apparent that some of the legacy port types will presently error out due to the irq requesting logic attempting to acquire the non-existent BRI IRQ. This adds some sanity checks to the request/free path to ensure that non-existence of a source in itself is not an error. This should restore functionality for legacy PORT_SCI ports. Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index be31d85a50e3..4604153b7954 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1052,9 +1052,17 @@ static int sci_request_irq(struct sci_port *port) if (SCIx_IRQ_IS_MUXED(port)) { i = SCIx_MUX_IRQ; irq = up->irq; - } else + } else { irq = port->cfg->irqs[i]; + /* + * Certain port types won't support all of the + * available interrupt sources. + */ + if (unlikely(!irq)) + continue; + } + desc = sci_irq_desc + i; port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s", dev_name(up->dev), desc->desc); @@ -1094,6 +1102,15 @@ static void sci_free_irq(struct sci_port *port) * IRQ first. */ for (i = 0; i < SCIx_NR_IRQS; i++) { + unsigned int irq = port->cfg->irqs[i]; + + /* + * Certain port types won't support all of the available + * interrupt sources. + */ + if (unlikely(!irq)) + continue; + free_irq(port->cfg->irqs[i], port); kfree(port->irqstr[i]); -- cgit v1.2.2 From 5f19f14fed7786652b9617c633db101d26a42251 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 22 May 2012 19:07:55 +0900 Subject: sh: intc: Kill off special reservation interface. At present reserving the IRLs in the IRQ bitmap in addition to the dropping of the legacy IRQ pre-allocation prevent IRL IRQs from being allocated for the x3proto board. The only reason to permit reservations was to lock down possible hardware vectors prior to dynamic IRQ scanning, but this doesn't matter much given that the hardware controller configuration is sorted before we get around to doing any dynamic IRQ allocation anyways. Beyond that, all of the tables are __init annotated, so quite a bit more work would need to be done to support reconfiguring things like IRL controllers on the fly, much more than would ever make it worth the hassle. Signed-off-by: Paul Mundt --- drivers/sh/intc/dynamic.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/sh/intc/dynamic.c b/drivers/sh/intc/dynamic.c index 5fea1ee8799a..14eb01ef5d72 100644 --- a/drivers/sh/intc/dynamic.c +++ b/drivers/sh/intc/dynamic.c @@ -55,11 +55,3 @@ void destroy_irq(unsigned int irq) { irq_free_desc(irq); } - -void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) -{ - int i; - - for (i = 0; i < nr_vecs; i++) - irq_reserve_irq(evt2irq(vectors[i].vect)); -} -- cgit v1.2.2