c62d86ecb8
This watchdog driver should work with SoC having a PMU. This fixes #11720. SVN-Revision: 34323
123 lines
3.3 KiB
Diff
123 lines
3.3 KiB
Diff
--- 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. */
|