diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2012-12-05 18:46:08 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-12-06 14:58:58 -0500 |
commit | bde327eff8a722df1198df9b14464f84f1adfb65 (patch) | |
tree | dde6282acfa1957a4fa310540a9206aeba277d57 | |
parent | 9f640a6376e54fa9ae834c32cbe92cefeec970dc (diff) | |
download | linux-bde327eff8a722df1198df9b14464f84f1adfb65.tar.gz linux-bde327eff8a722df1198df9b14464f84f1adfb65.tar.bz2 linux-bde327eff8a722df1198df9b14464f84f1adfb65.zip |
ssb: register watchdog driver
Register the watchdog driver to the system if it is a SoC. Using the
watchdog on a non SoC device, like a PCI card, will make the PCI
card die when the timeout expired, but starting it again is not
supported by ssb.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/ssb/embedded.c | 35 | ||||
-rw-r--r-- | drivers/ssb/main.c | 8 | ||||
-rw-r--r-- | drivers/ssb/ssb_private.h | 10 | ||||
-rw-r--r-- | include/linux/ssb/ssb.h | 2 |
4 files changed, 55 insertions, 0 deletions
diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c index 9ef124f9ee2d..bb18d76f9f2c 100644 --- a/drivers/ssb/embedded.c +++ b/drivers/ssb/embedded.c @@ -4,11 +4,13 @@ * * Copyright 2005-2008, Broadcom Corporation * Copyright 2006-2008, Michael Buesch <m@bues.ch> + * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de> * * Licensed under the GNU/GPL. See COPYING for details. */ #include <linux/export.h> +#include <linux/platform_device.h> #include <linux/ssb/ssb.h> #include <linux/ssb/ssb_embedded.h> #include <linux/ssb/ssb_driver_pci.h> @@ -32,6 +34,39 @@ int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks) } EXPORT_SYMBOL(ssb_watchdog_timer_set); +int ssb_watchdog_register(struct ssb_bus *bus) +{ + struct bcm47xx_wdt wdt = {}; + struct platform_device *pdev; + + if (ssb_chipco_available(&bus->chipco)) { + wdt.driver_data = &bus->chipco; + wdt.timer_set = ssb_chipco_watchdog_timer_set_wdt; + wdt.timer_set_ms = ssb_chipco_watchdog_timer_set_ms; + wdt.max_timer_ms = bus->chipco.max_timer_ms; + } else if (ssb_extif_available(&bus->extif)) { + wdt.driver_data = &bus->extif; + wdt.timer_set = ssb_extif_watchdog_timer_set_wdt; + wdt.timer_set_ms = ssb_extif_watchdog_timer_set_ms; + wdt.max_timer_ms = SSB_EXTIF_WATCHDOG_MAX_TIMER_MS; + } else { + return -ENODEV; + } + + pdev = platform_device_register_data(NULL, "bcm47xx-wdt", + bus->busnumber, &wdt, + sizeof(wdt)); + if (IS_ERR(pdev)) { + ssb_dprintk(KERN_INFO PFX + "can not register watchdog device, err: %li\n", + PTR_ERR(pdev)); + return PTR_ERR(pdev); + } + + bus->watchdog = pdev; + return 0; +} + u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask) { unsigned long flags; diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index df0f145c22fc..58c7da29a37c 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -13,6 +13,7 @@ #include <linux/delay.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/ssb/ssb.h> #include <linux/ssb/ssb_regs.h> #include <linux/ssb/ssb_driver_gige.h> @@ -433,6 +434,11 @@ static void ssb_devices_unregister(struct ssb_bus *bus) if (sdev->dev) device_unregister(sdev->dev); } + +#ifdef CONFIG_SSB_EMBEDDED + if (bus->bustype == SSB_BUSTYPE_SSB) + platform_device_unregister(bus->watchdog); +#endif } void ssb_bus_unregister(struct ssb_bus *bus) @@ -561,6 +567,8 @@ static int __devinit ssb_attach_queued_buses(void) if (err) goto error; ssb_pcicore_init(&bus->pcicore); + if (bus->bustype == SSB_BUSTYPE_SSB) + ssb_watchdog_register(bus); ssb_bus_may_powerdown(bus); err = ssb_devices_register(bus); diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index 50ea02877777..8942db1d855a 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h @@ -232,4 +232,14 @@ static inline u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, return 0; } #endif + +#ifdef CONFIG_SSB_EMBEDDED +extern int ssb_watchdog_register(struct ssb_bus *bus); +#else /* CONFIG_SSB_EMBEDDED */ +static inline int ssb_watchdog_register(struct ssb_bus *bus) +{ + return 0; +} +#endif /* CONFIG_SSB_EMBEDDED */ + #endif /* LINUX_SSB_PRIVATE_H_ */ diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index bb674c02f306..1f64e3f1f22b 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -8,6 +8,7 @@ #include <linux/pci.h> #include <linux/mod_devicetable.h> #include <linux/dma-mapping.h> +#include <linux/platform_device.h> #include <linux/ssb/ssb_regs.h> @@ -432,6 +433,7 @@ struct ssb_bus { #ifdef CONFIG_SSB_EMBEDDED /* Lock for GPIO register access. */ spinlock_t gpio_lock; + struct platform_device *watchdog; #endif /* EMBEDDED */ /* Internal-only stuff follows. Do not touch. */ |