diff options
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/mei_wdt.c | 58 | ||||
-rw-r--r-- | drivers/watchdog/octeon-wdt-main.c | 62 | ||||
-rw-r--r-- | drivers/watchdog/sa1100_wdt.c | 24 |
3 files changed, 50 insertions, 94 deletions
diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c index 2a9d5cdedea2..b29c6fde7473 100644 --- a/drivers/watchdog/mei_wdt.c +++ b/drivers/watchdog/mei_wdt.c @@ -412,11 +412,11 @@ static void mei_wdt_unregister_work(struct work_struct *work) } /** - * mei_wdt_event_rx - callback for data receive + * mei_wdt_rx - callback for data receive * * @cldev: bus device */ -static void mei_wdt_event_rx(struct mei_cl_device *cldev) +static void mei_wdt_rx(struct mei_cl_device *cldev) { struct mei_wdt *wdt = mei_cldev_get_drvdata(cldev); struct mei_wdt_start_response res; @@ -484,11 +484,11 @@ out: } /* - * mei_wdt_notify_event - callback for event notification + * mei_wdt_notif - callback for event notification * * @cldev: bus device */ -static void mei_wdt_notify_event(struct mei_cl_device *cldev) +static void mei_wdt_notif(struct mei_cl_device *cldev) { struct mei_wdt *wdt = mei_cldev_get_drvdata(cldev); @@ -498,23 +498,6 @@ static void mei_wdt_notify_event(struct mei_cl_device *cldev) mei_wdt_register(wdt); } -/** - * mei_wdt_event - callback for event receive - * - * @cldev: bus device - * @events: event mask - * @context: callback context - */ -static void mei_wdt_event(struct mei_cl_device *cldev, - u32 events, void *context) -{ - if (events & BIT(MEI_CL_EVENT_RX)) - mei_wdt_event_rx(cldev); - - if (events & BIT(MEI_CL_EVENT_NOTIF)) - mei_wdt_notify_event(cldev); -} - #if IS_ENABLED(CONFIG_DEBUG_FS) static ssize_t mei_dbgfs_read_activation(struct file *file, char __user *ubuf, @@ -625,16 +608,17 @@ static int mei_wdt_probe(struct mei_cl_device *cldev, goto err_out; } - ret = mei_cldev_register_event_cb(wdt->cldev, - BIT(MEI_CL_EVENT_RX) | - BIT(MEI_CL_EVENT_NOTIF), - mei_wdt_event, NULL); + ret = mei_cldev_register_rx_cb(wdt->cldev, mei_wdt_rx); + if (ret) { + dev_err(&cldev->dev, "Could not reg rx event ret=%d\n", ret); + goto err_disable; + } + ret = mei_cldev_register_notif_cb(wdt->cldev, mei_wdt_notif); /* on legacy devices notification is not supported - * this doesn't fail the registration for RX event */ if (ret && ret != -EOPNOTSUPP) { - dev_err(&cldev->dev, "Could not register event ret=%d\n", ret); + dev_err(&cldev->dev, "Could not reg notif event ret=%d\n", ret); goto err_disable; } @@ -701,25 +685,7 @@ static struct mei_cl_driver mei_wdt_driver = { .remove = mei_wdt_remove, }; -static int __init mei_wdt_init(void) -{ - int ret; - - ret = mei_cldev_driver_register(&mei_wdt_driver); - if (ret) { - pr_err(KBUILD_MODNAME ": module registration failed\n"); - return ret; - } - return 0; -} - -static void __exit mei_wdt_exit(void) -{ - mei_cldev_driver_unregister(&mei_wdt_driver); -} - -module_init(mei_wdt_init); -module_exit(mei_wdt_exit); +module_mei_cl_driver(mei_wdt_driver); MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c index 8b4fa4df3fc1..b5cdceb36cff 100644 --- a/drivers/watchdog/octeon-wdt-main.c +++ b/drivers/watchdog/octeon-wdt-main.c @@ -373,7 +373,7 @@ void octeon_wdt_nmi_stage3(u64 reg[32]) octeon_wdt_write_string("*** Chip soft reset soon ***\r\n"); } -static void octeon_wdt_disable_interrupt(int cpu) +static int octeon_wdt_cpu_pre_down(unsigned int cpu) { unsigned int core; unsigned int irq; @@ -391,9 +391,10 @@ static void octeon_wdt_disable_interrupt(int cpu) cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64); free_irq(irq, octeon_wdt_poke_irq); + return 0; } -static void octeon_wdt_setup_interrupt(int cpu) +static int octeon_wdt_cpu_online(unsigned int cpu) { unsigned int core; unsigned int irq; @@ -423,25 +424,8 @@ static void octeon_wdt_setup_interrupt(int cpu) ciu_wdog.s.len = timeout_cnt; ciu_wdog.s.mode = 3; /* 3 = Interrupt + NMI + Soft-Reset */ cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64); -} -static int octeon_wdt_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_DOWN_PREPARE: - octeon_wdt_disable_interrupt(cpu); - break; - case CPU_ONLINE: - case CPU_DOWN_FAILED: - octeon_wdt_setup_interrupt(cpu); - break; - default: - break; - } - return NOTIFY_OK; + return 0; } static int octeon_wdt_ping(struct watchdog_device __always_unused *wdog) @@ -530,10 +514,6 @@ static int octeon_wdt_stop(struct watchdog_device *wdog) return 0; } -static struct notifier_block octeon_wdt_cpu_notifier = { - .notifier_call = octeon_wdt_cpu_callback, -}; - static const struct watchdog_info octeon_wdt_info = { .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, .identity = "OCTEON", @@ -552,6 +532,7 @@ static struct watchdog_device octeon_wdt = { .ops = &octeon_wdt_ops, }; +static enum cpuhp_state octeon_wdt_online; /** * Module/ driver initialization. * @@ -561,7 +542,6 @@ static int __init octeon_wdt_init(void) { int i; int ret; - int cpu; u64 *ptr; /* @@ -609,14 +589,16 @@ static int __init octeon_wdt_init(void) cpumask_clear(&irq_enabled_cpus); - cpu_notifier_register_begin(); - for_each_online_cpu(cpu) - octeon_wdt_setup_interrupt(cpu); - - __register_hotcpu_notifier(&octeon_wdt_cpu_notifier); - cpu_notifier_register_done(); - + ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "watchdog/octeon:online", + octeon_wdt_cpu_online, octeon_wdt_cpu_pre_down); + if (ret < 0) + goto err; + octeon_wdt_online = ret; return 0; +err: + cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0); + watchdog_unregister_device(&octeon_wdt); + return ret; } /** @@ -624,22 +606,8 @@ static int __init octeon_wdt_init(void) */ static void __exit octeon_wdt_cleanup(void) { - int cpu; - watchdog_unregister_device(&octeon_wdt); - - cpu_notifier_register_begin(); - __unregister_hotcpu_notifier(&octeon_wdt_cpu_notifier); - - for_each_online_cpu(cpu) { - int core = cpu2core(cpu); - /* Disable the watchdog */ - cvmx_write_csr(CVMX_CIU_WDOGX(core), 0); - /* Free the interrupt handler */ - free_irq(OCTEON_IRQ_WDOG0 + core, octeon_wdt_poke_irq); - } - - cpu_notifier_register_done(); + cpuhp_remove_state(octeon_wdt_online); /* * Disable the boot-bus memory, the code it points to is soon diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index e1d39a1e9628..8965e3f536c3 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/clk.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/fs.h> @@ -155,12 +156,27 @@ static struct miscdevice sa1100dog_miscdev = { }; static int margin __initdata = 60; /* (secs) Default is 1 minute */ +static struct clk *clk; static int __init sa1100dog_init(void) { int ret; - oscr_freq = get_clock_tick_rate(); + clk = clk_get(NULL, "OSTIMER0"); + if (IS_ERR(clk)) { + pr_err("SA1100/PXA2xx Watchdog Timer: clock not found: %d\n", + (int) PTR_ERR(clk)); + return PTR_ERR(clk); + } + + ret = clk_prepare_enable(clk); + if (ret) { + pr_err("SA1100/PXA2xx Watchdog Timer: clock failed to prepare+enable: %d\n", + ret); + goto err; + } + + oscr_freq = clk_get_rate(clk); /* * Read the reset status, and save it for later. If @@ -176,11 +192,17 @@ static int __init sa1100dog_init(void) pr_info("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", margin); return ret; +err: + clk_disable_unprepare(clk); + clk_put(clk); + return ret; } static void __exit sa1100dog_exit(void) { misc_deregister(&sa1100dog_miscdev); + clk_disable_unprepare(clk); + clk_put(clk); } module_init(sa1100dog_init); |