aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm47xx/patches-3.6/554-ssb-register-watchdog-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm47xx/patches-3.6/554-ssb-register-watchdog-driver.patch')
-rw-r--r--target/linux/brcm47xx/patches-3.6/554-ssb-register-watchdog-driver.patch122
1 files changed, 122 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-3.6/554-ssb-register-watchdog-driver.patch b/target/linux/brcm47xx/patches-3.6/554-ssb-register-watchdog-driver.patch
new file mode 100644
index 0000000000..c814c54ac4
--- /dev/null
+++ b/target/linux/brcm47xx/patches-3.6/554-ssb-register-watchdog-driver.patch
@@ -0,0 +1,122 @@
+--- 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_bu
+ }
+ 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;
+--- 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>
+@@ -434,6 +435,11 @@ static void ssb_devices_unregister(struc
+ 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)
+@@ -579,6 +585,8 @@ static int __devinit ssb_attach_queued_b
+ 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);
+--- a/drivers/ssb/ssb_private.h
++++ b/drivers/ssb/ssb_private.h
+@@ -246,4 +246,14 @@ static inline u32 ssb_extif_watchdog_tim
+ 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_ */
+--- 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. */