Atheros AR531X (Generic) watchdog support code (based on ar7_wdt.c). This watchdog should work on most AR5315 / AR5312 devices. I've personally tested it on La Fonera and D-Link DWL-2100AP. Please note that the DWL-2100AP uses a slightly faster clock for its watchdog, see the source files.
Signed-off-by: Axel Gembe <[EMAIL PROTECTED]> --- target/linux/atheros/config-2.6.23 | 1 + target/linux/atheros/config-2.6.24 | 1 + target/linux/atheros/config-2.6.25 | 1 + .../files/drivers/char/watchdog/ar531x_wdt.c | 326 ++++++++++++++++++++ .../atheros/files/drivers/watchdog/ar531x_wdt.c | 326 ++++++++++++++++++++ .../include/asm-mips/mach-atheros/ar5315/ar5315.h | 1 + .../atheros/patches-2.6.23/160-watchdog.patch | 35 ++ .../atheros/patches-2.6.24/160-watchdog.patch | 35 ++ .../atheros/patches-2.6.25/160-watchdog.patch | 35 ++ 9 files changed, 761 insertions(+), 0 deletions(-) create mode 100644 target/linux/atheros/files/drivers/char/watchdog/ar531x_wdt.c create mode 100644 target/linux/atheros/files/drivers/watchdog/ar531x_wdt.c create mode 100644 target/linux/atheros/patches-2.6.23/160-watchdog.patch create mode 100644 target/linux/atheros/patches-2.6.24/160-watchdog.patch create mode 100644 target/linux/atheros/patches-2.6.25/160-watchdog.patch diff --git a/target/linux/atheros/config-2.6.23 b/target/linux/atheros/config-2.6.23 index e1694ba..4876047 100644 --- a/target/linux/atheros/config-2.6.23 +++ b/target/linux/atheros/config-2.6.23 @@ -8,6 +8,7 @@ CONFIG_AR2313=y CONFIG_ATHEROS=y CONFIG_ATHEROS_AR5312=y CONFIG_ATHEROS_AR5315=y +CONFIG_ATHEROS_WDT=y # CONFIG_ATM is not set CONFIG_BASE_SMALL=0 CONFIG_BITREVERSE=y diff --git a/target/linux/atheros/config-2.6.24 b/target/linux/atheros/config-2.6.24 index 848f459..ef34de9 100644 --- a/target/linux/atheros/config-2.6.24 +++ b/target/linux/atheros/config-2.6.24 @@ -9,6 +9,7 @@ CONFIG_ARCH_SUPPORTS_OPROFILE=y CONFIG_ATHEROS=y CONFIG_ATHEROS_AR5312=y CONFIG_ATHEROS_AR5315=y +CONFIG_ATHEROS_WDT=y # CONFIG_ATM is not set CONFIG_BASE_SMALL=0 # CONFIG_BCM47XX is not set diff --git a/target/linux/atheros/config-2.6.25 b/target/linux/atheros/config-2.6.25 index fc1cda4..39e31b2 100644 --- a/target/linux/atheros/config-2.6.25 +++ b/target/linux/atheros/config-2.6.25 @@ -10,6 +10,7 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ATHEROS=y CONFIG_ATHEROS_AR5312=y CONFIG_ATHEROS_AR5315=y +CONFIG_ATHEROS_WDT=y # CONFIG_ATM is not set CONFIG_BASE_SMALL=0 # CONFIG_BCM47XX is not set diff --git a/target/linux/atheros/files/drivers/char/watchdog/ar531x_wdt.c b/target/linux/atheros/files/drivers/char/watchdog/ar531x_wdt.c new file mode 100644 index 0000000..16c0eea --- /dev/null +++ b/target/linux/atheros/files/drivers/char/watchdog/ar531x_wdt.c @@ -0,0 +1,326 @@ +/* + * drivers/watchdog/ar531x_wdt.c + * + * Atheros 531x Watchdog Timer support + * + * Copyright (C) 2008 Axel Gembe <[EMAIL PROTECTED]> + * + * Some base code taken from: + * OpenWRT AR7 watchdog driver + * Copyright (C) 2007 Nicolas Thill <[EMAIL PROTECTED]> + * Copyright (C) 2005 Enrik Berkhan <[EMAIL PROTECTED]> + * Copyright (C) 2001, 2002 Christer Weinigel <[EMAIL PROTECTED]> + * + * 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 Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/miscdevice.h> +#include <linux/watchdog.h> +#include <linux/notifier.h> +#include <linux/reboot.h> +#include <linux/fs.h> +#include <linux/ioport.h> +#include <linux/io.h> +#include <linux/uaccess.h> +#include <linux/interrupt.h> + +#include <asm/addrspace.h> +#include <asm/mach-atheros/ar531x.h> + +#define DRVNAME "ar531x_wdt" +#define LONGNAME "Atheros 531x Watchdog Timer" + +MODULE_AUTHOR("Axel Gembe <[EMAIL PROTECTED]>"); +MODULE_DESCRIPTION(LONGNAME); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); + +static int margin = 60; +module_param(margin, int, 0); +MODULE_PARM_DESC(margin, "Watchdog margin in seconds"); + +/* + I found these clock rates so far: + 48MHz - DLink DWL-2100AP + 40MHz - Meraki +*/ + +static int wdtclock = 40000000; /* 40MHz */ +module_param(wdtclock, int, 0); +MODULE_PARM_DESC(wdtclock, "Watchdog clock in hertz"); + +static int nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); + +/* + WDC_IGNORE_EXPIRATION 0 Just interrupt gets triggered + WDC_NMI 1 Make the interrupt a NMI + WDC_RESET 2 Board gets reset + WDC_AHB 4 AHB interrupt gets triggered +*/ +static int wdflags = WDC_IGNORE_EXPIRATION; +module_param(wdflags, int, 0); +MODULE_PARM_DESC(wdflags, "Watchdog flags (0-Int., 1-NMI, 2-Reset, 4-AHB)"); + +#define WDT_FLAGS_MASK 0x7 /* Mask out all flags except the lowest 3 */ + +static u32 ar531x_wd; +static u32 ar531x_wdc; +static u32 ar531x_isr; +static u32 ar531x_isr_wd; + +static struct semaphore open_semaphore; +static int expect_close = -1; + +static void ar531x_wdt_get_regs(void) +{ + DO_AR5312( + ar531x_wd = AR531X_WD_TIMER; + ar531x_wdc = AR531X_WD_CTRL; + ar531x_isr = AR531X_ISR; + ar531x_isr_wd = AR531X_ISR_WD; + ) + + DO_AR5315( + ar531x_wd = AR5315_WD; + ar531x_wdc = AR5315_WDC; + ar531x_isr = AR5315_ISR; + ar531x_isr_wd = AR5315_ISR_WD; + ) +} + +static void ar531x_wdt_kick(void) +{ + sysRegWrite(ar531x_wd, margin * wdtclock); + sysRegWrite(ar531x_isr, sysRegRead(ar531x_isr) | ar531x_isr_wd); +} + +static void ar531x_wdt_enable_wdt(void) +{ + printk(KERN_DEBUG DRVNAME ": enabling watchdog timer\n"); + + ar531x_wdt_kick(); + sysRegWrite(ar531x_wdc, wdflags & WDT_FLAGS_MASK); +} + +static void ar531x_wdt_disable_wdt(void) +{ + printk(KERN_DEBUG DRVNAME ": disabling watchdog timer\n"); + + expect_close = -1; + sysRegWrite(ar531x_wdc, 0); + sysRegWrite(ar531x_wd, 0); +} + +static int ar531x_wdt_open(struct inode *inode, struct file *file) +{ + /* only allow one at a time */ + if (down_trylock(&open_semaphore)) + return -EBUSY; + + ar531x_wdt_enable_wdt(); + expect_close = 0; + + return nonseekable_open(inode, file); +} + +static int ar531x_wdt_release(struct inode *inode, struct file *file) +{ + if (!expect_close) + printk(KERN_WARNING DRVNAME + ": watchdog device closed unexpectedly, " + "will not disable the watchdog timer\n"); + else if (!nowayout) + ar531x_wdt_disable_wdt(); + + up(&open_semaphore); + + return 0; +} + +static int ar531x_wdt_notify_sys(struct notifier_block *this, + unsigned long code, void *unused) +{ + if (code == SYS_HALT || code == SYS_POWER_OFF) + if (!nowayout) + ar531x_wdt_disable_wdt(); + + return NOTIFY_DONE; +} + +static struct notifier_block ar531x_wdt_notifier = { + .notifier_call = ar531x_wdt_notify_sys +}; + +static ssize_t ar531x_wdt_write(struct file *file, const char *data, + size_t len, loff_t *ppos) +{ + /* check for a magic close character */ + if (len) { + size_t i; + + ar531x_wdt_kick(); + + expect_close = 0; + for (i = 0; i < len; ++i) { + char c; + if (get_user(c, data + i)) + return -EFAULT; + if (c == 'V') + expect_close = 1; + } + + } + return len; +} + +static int ar531x_wdt_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + static struct watchdog_info ident = { + .identity = LONGNAME, + .firmware_version = 1, + .options = WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE | + WDIOF_KEEPALIVEPING + }; + int new_margin; + + switch (cmd) { + default: + return -ENOTTY; + case WDIOC_GETSUPPORT: + if (copy_to_user((struct watchdog_info *)arg, &ident, + sizeof(ident))) + return -EFAULT; + return 0; + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + if (put_user(0, (int *)arg)) + return -EFAULT; + return 0; + case WDIOC_KEEPALIVE: + ar531x_wdt_kick(); + return 0; + case WDIOC_SETTIMEOUT: + if (get_user(new_margin, (int *)arg)) + return -EFAULT; + if (new_margin < 1 || new_margin > 90) + return -EINVAL; + margin = new_margin; + /* omit break */ + case WDIOC_GETTIMEOUT: + if (put_user(margin, (int *)arg)) + return -EFAULT; + return 0; + } +} + +static irqreturn_t ar531x_wdt_interrupt(int irq, void *devid) +{ + if (expect_close == 0) { + printk(KERN_CRIT DRVNAME ": expired, restarting system\n"); + machine_restart("Watchdog expired!"); + } + + sysRegWrite(ar531x_wd, 0); + sysRegWrite(ar531x_wdc, 0); + sysRegWrite(ar531x_isr, sysRegRead(ar531x_isr) | ar531x_isr_wd); + + return IRQ_HANDLED; +} + +static struct file_operations ar531x_wdt_fops = { + .owner = THIS_MODULE, + .write = ar531x_wdt_write, + .ioctl = ar531x_wdt_ioctl, + .open = ar531x_wdt_open, + .release = ar531x_wdt_release, +}; + +static struct miscdevice ar531x_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &ar531x_wdt_fops, +}; + +static int __init ar531x_wdt_init(void) +{ + int rc; + + sema_init(&open_semaphore, 1); + + ar531x_wdt_get_regs(); + + if (!request_mem_region(ar531x_wd, sizeof(u32), LONGNAME)) { + printk(KERN_WARNING DRVNAME ": watchdog I/O region busy\n"); + return -EBUSY; + } + + if (!request_mem_region(ar531x_wdc, sizeof(u32), LONGNAME)) { + printk(KERN_WARNING DRVNAME ": watchdog I/O region busy\n"); + rc = -EBUSY; + goto out_alloc; + } + + rc = register_reboot_notifier(&ar531x_wdt_notifier); + if (rc) { + printk(KERN_ERR DRVNAME + ": unable to register reboot notifier\n"); + goto out_alloc_wdc; + } + + rc = request_irq(AR531X_MISC_IRQ_WATCHDOG, ar531x_wdt_interrupt, + IRQF_DISABLED, "ar531x_wdt", NULL); + if (rc) { + printk(KERN_ERR DRVNAME ": IRQ is already in use\n"); + goto out_register; + } + + rc = misc_register(&ar531x_wdt_miscdev); + if (rc) { + printk(KERN_ERR DRVNAME ": unable to register misc device\n"); + goto out_reqirq; + } + goto out; + +out_reqirq: + free_irq(AR531X_MISC_IRQ_WATCHDOG, NULL); +out_register: + unregister_reboot_notifier(&ar531x_wdt_notifier); +out_alloc_wdc: + release_mem_region(ar531x_wdc, sizeof(u32)); +out_alloc: + release_mem_region(ar531x_wd, sizeof(u32)); +out: + return rc; +} + +static void __exit ar531x_wdt_cleanup(void) +{ + misc_deregister(&ar531x_wdt_miscdev); + free_irq(AR531X_MISC_IRQ_WATCHDOG, NULL); + unregister_reboot_notifier(&ar531x_wdt_notifier); + release_mem_region(ar531x_wdc, sizeof(u32)); + release_mem_region(ar531x_wd, sizeof(u32)); +} + +module_init(ar531x_wdt_init); +module_exit(ar531x_wdt_cleanup); diff --git a/target/linux/atheros/files/drivers/watchdog/ar531x_wdt.c b/target/linux/atheros/files/drivers/watchdog/ar531x_wdt.c new file mode 100644 index 0000000..16c0eea --- /dev/null +++ b/target/linux/atheros/files/drivers/watchdog/ar531x_wdt.c @@ -0,0 +1,326 @@ +/* + * drivers/watchdog/ar531x_wdt.c + * + * Atheros 531x Watchdog Timer support + * + * Copyright (C) 2008 Axel Gembe <[EMAIL PROTECTED]> + * + * Some base code taken from: + * OpenWRT AR7 watchdog driver + * Copyright (C) 2007 Nicolas Thill <[EMAIL PROTECTED]> + * Copyright (C) 2005 Enrik Berkhan <[EMAIL PROTECTED]> + * Copyright (C) 2001, 2002 Christer Weinigel <[EMAIL PROTECTED]> + * + * 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 Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/miscdevice.h> +#include <linux/watchdog.h> +#include <linux/notifier.h> +#include <linux/reboot.h> +#include <linux/fs.h> +#include <linux/ioport.h> +#include <linux/io.h> +#include <linux/uaccess.h> +#include <linux/interrupt.h> + +#include <asm/addrspace.h> +#include <asm/mach-atheros/ar531x.h> + +#define DRVNAME "ar531x_wdt" +#define LONGNAME "Atheros 531x Watchdog Timer" + +MODULE_AUTHOR("Axel Gembe <[EMAIL PROTECTED]>"); +MODULE_DESCRIPTION(LONGNAME); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); + +static int margin = 60; +module_param(margin, int, 0); +MODULE_PARM_DESC(margin, "Watchdog margin in seconds"); + +/* + I found these clock rates so far: + 48MHz - DLink DWL-2100AP + 40MHz - Meraki +*/ + +static int wdtclock = 40000000; /* 40MHz */ +module_param(wdtclock, int, 0); +MODULE_PARM_DESC(wdtclock, "Watchdog clock in hertz"); + +static int nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); + +/* + WDC_IGNORE_EXPIRATION 0 Just interrupt gets triggered + WDC_NMI 1 Make the interrupt a NMI + WDC_RESET 2 Board gets reset + WDC_AHB 4 AHB interrupt gets triggered +*/ +static int wdflags = WDC_IGNORE_EXPIRATION; +module_param(wdflags, int, 0); +MODULE_PARM_DESC(wdflags, "Watchdog flags (0-Int., 1-NMI, 2-Reset, 4-AHB)"); + +#define WDT_FLAGS_MASK 0x7 /* Mask out all flags except the lowest 3 */ + +static u32 ar531x_wd; +static u32 ar531x_wdc; +static u32 ar531x_isr; +static u32 ar531x_isr_wd; + +static struct semaphore open_semaphore; +static int expect_close = -1; + +static void ar531x_wdt_get_regs(void) +{ + DO_AR5312( + ar531x_wd = AR531X_WD_TIMER; + ar531x_wdc = AR531X_WD_CTRL; + ar531x_isr = AR531X_ISR; + ar531x_isr_wd = AR531X_ISR_WD; + ) + + DO_AR5315( + ar531x_wd = AR5315_WD; + ar531x_wdc = AR5315_WDC; + ar531x_isr = AR5315_ISR; + ar531x_isr_wd = AR5315_ISR_WD; + ) +} + +static void ar531x_wdt_kick(void) +{ + sysRegWrite(ar531x_wd, margin * wdtclock); + sysRegWrite(ar531x_isr, sysRegRead(ar531x_isr) | ar531x_isr_wd); +} + +static void ar531x_wdt_enable_wdt(void) +{ + printk(KERN_DEBUG DRVNAME ": enabling watchdog timer\n"); + + ar531x_wdt_kick(); + sysRegWrite(ar531x_wdc, wdflags & WDT_FLAGS_MASK); +} + +static void ar531x_wdt_disable_wdt(void) +{ + printk(KERN_DEBUG DRVNAME ": disabling watchdog timer\n"); + + expect_close = -1; + sysRegWrite(ar531x_wdc, 0); + sysRegWrite(ar531x_wd, 0); +} + +static int ar531x_wdt_open(struct inode *inode, struct file *file) +{ + /* only allow one at a time */ + if (down_trylock(&open_semaphore)) + return -EBUSY; + + ar531x_wdt_enable_wdt(); + expect_close = 0; + + return nonseekable_open(inode, file); +} + +static int ar531x_wdt_release(struct inode *inode, struct file *file) +{ + if (!expect_close) + printk(KERN_WARNING DRVNAME + ": watchdog device closed unexpectedly, " + "will not disable the watchdog timer\n"); + else if (!nowayout) + ar531x_wdt_disable_wdt(); + + up(&open_semaphore); + + return 0; +} + +static int ar531x_wdt_notify_sys(struct notifier_block *this, + unsigned long code, void *unused) +{ + if (code == SYS_HALT || code == SYS_POWER_OFF) + if (!nowayout) + ar531x_wdt_disable_wdt(); + + return NOTIFY_DONE; +} + +static struct notifier_block ar531x_wdt_notifier = { + .notifier_call = ar531x_wdt_notify_sys +}; + +static ssize_t ar531x_wdt_write(struct file *file, const char *data, + size_t len, loff_t *ppos) +{ + /* check for a magic close character */ + if (len) { + size_t i; + + ar531x_wdt_kick(); + + expect_close = 0; + for (i = 0; i < len; ++i) { + char c; + if (get_user(c, data + i)) + return -EFAULT; + if (c == 'V') + expect_close = 1; + } + + } + return len; +} + +static int ar531x_wdt_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + static struct watchdog_info ident = { + .identity = LONGNAME, + .firmware_version = 1, + .options = WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE | + WDIOF_KEEPALIVEPING + }; + int new_margin; + + switch (cmd) { + default: + return -ENOTTY; + case WDIOC_GETSUPPORT: + if (copy_to_user((struct watchdog_info *)arg, &ident, + sizeof(ident))) + return -EFAULT; + return 0; + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + if (put_user(0, (int *)arg)) + return -EFAULT; + return 0; + case WDIOC_KEEPALIVE: + ar531x_wdt_kick(); + return 0; + case WDIOC_SETTIMEOUT: + if (get_user(new_margin, (int *)arg)) + return -EFAULT; + if (new_margin < 1 || new_margin > 90) + return -EINVAL; + margin = new_margin; + /* omit break */ + case WDIOC_GETTIMEOUT: + if (put_user(margin, (int *)arg)) + return -EFAULT; + return 0; + } +} + +static irqreturn_t ar531x_wdt_interrupt(int irq, void *devid) +{ + if (expect_close == 0) { + printk(KERN_CRIT DRVNAME ": expired, restarting system\n"); + machine_restart("Watchdog expired!"); + } + + sysRegWrite(ar531x_wd, 0); + sysRegWrite(ar531x_wdc, 0); + sysRegWrite(ar531x_isr, sysRegRead(ar531x_isr) | ar531x_isr_wd); + + return IRQ_HANDLED; +} + +static struct file_operations ar531x_wdt_fops = { + .owner = THIS_MODULE, + .write = ar531x_wdt_write, + .ioctl = ar531x_wdt_ioctl, + .open = ar531x_wdt_open, + .release = ar531x_wdt_release, +}; + +static struct miscdevice ar531x_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &ar531x_wdt_fops, +}; + +static int __init ar531x_wdt_init(void) +{ + int rc; + + sema_init(&open_semaphore, 1); + + ar531x_wdt_get_regs(); + + if (!request_mem_region(ar531x_wd, sizeof(u32), LONGNAME)) { + printk(KERN_WARNING DRVNAME ": watchdog I/O region busy\n"); + return -EBUSY; + } + + if (!request_mem_region(ar531x_wdc, sizeof(u32), LONGNAME)) { + printk(KERN_WARNING DRVNAME ": watchdog I/O region busy\n"); + rc = -EBUSY; + goto out_alloc; + } + + rc = register_reboot_notifier(&ar531x_wdt_notifier); + if (rc) { + printk(KERN_ERR DRVNAME + ": unable to register reboot notifier\n"); + goto out_alloc_wdc; + } + + rc = request_irq(AR531X_MISC_IRQ_WATCHDOG, ar531x_wdt_interrupt, + IRQF_DISABLED, "ar531x_wdt", NULL); + if (rc) { + printk(KERN_ERR DRVNAME ": IRQ is already in use\n"); + goto out_register; + } + + rc = misc_register(&ar531x_wdt_miscdev); + if (rc) { + printk(KERN_ERR DRVNAME ": unable to register misc device\n"); + goto out_reqirq; + } + goto out; + +out_reqirq: + free_irq(AR531X_MISC_IRQ_WATCHDOG, NULL); +out_register: + unregister_reboot_notifier(&ar531x_wdt_notifier); +out_alloc_wdc: + release_mem_region(ar531x_wdc, sizeof(u32)); +out_alloc: + release_mem_region(ar531x_wd, sizeof(u32)); +out: + return rc; +} + +static void __exit ar531x_wdt_cleanup(void) +{ + misc_deregister(&ar531x_wdt_miscdev); + free_irq(AR531X_MISC_IRQ_WATCHDOG, NULL); + unregister_reboot_notifier(&ar531x_wdt_notifier); + release_mem_region(ar531x_wdc, sizeof(u32)); + release_mem_region(ar531x_wd, sizeof(u32)); +} + +module_init(ar531x_wdt_init); +module_exit(ar531x_wdt_cleanup); diff --git a/target/linux/atheros/files/include/asm-mips/mach-atheros/ar5315/ar5315.h b/target/linux/atheros/files/include/asm-mips/mach-atheros/ar5315/ar5315.h index 8ad8810..ff67ec5 100644 --- a/target/linux/atheros/files/include/asm-mips/mach-atheros/ar5315/ar5315.h +++ b/target/linux/atheros/files/include/asm-mips/mach-atheros/ar5315/ar5315.h @@ -198,6 +198,7 @@ #define AR5315_WD (AR5315_DSLBASE + 0x0038) #define AR5315_WDC (AR5315_DSLBASE + 0x003c) +#define WDC_AHB 0x00000004 #define WDC_RESET 0x00000002 /* reset on watchdog */ #define WDC_NMI 0x00000001 /* NMI on watchdog */ #define WDC_IGNORE_EXPIRATION 0x00000000 diff --git a/target/linux/atheros/patches-2.6.23/160-watchdog.patch b/target/linux/atheros/patches-2.6.23/160-watchdog.patch new file mode 100644 index 0000000..841c10d --- /dev/null +++ b/target/linux/atheros/patches-2.6.23/160-watchdog.patch @@ -0,0 +1,35 @@ +commit 57765d87f8b4f34c598e39a2f95b8c60359b7b3e +Author: Axel Gembe <[EMAIL PROTECTED]> +Date: Wed May 7 10:17:56 2008 +0200 + + watchdog patch + +diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig +index 37bddc1..9b1b631 100644 +--- a/drivers/char/watchdog/Kconfig ++++ b/drivers/char/watchdog/Kconfig +@@ -609,6 +609,12 @@ config WDT_RM9K_GPI + To compile this driver as a module, choose M here: the + module will be called rm9k_wdt. + ++config ATHEROS_WDT ++ tristate "Atheros hardware watchdog" ++ depends on ATHEROS ++ help ++ Hardware driver for the Atheros Watchdog Timer. ++ + # PARISC Architecture + + # POWERPC Architecture +diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile +index 389f8b1..0bafa42 100644 +--- a/drivers/char/watchdog/Makefile ++++ b/drivers/char/watchdog/Makefile +@@ -90,6 +90,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o + obj-$(CONFIG_INDYDOG) += indydog.o + obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o + obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o ++obj-$(CONFIG_ATHEROS_WDT) += ar531x_wdt.o + + # PARISC Architecture + diff --git a/target/linux/atheros/patches-2.6.24/160-watchdog.patch b/target/linux/atheros/patches-2.6.24/160-watchdog.patch new file mode 100644 index 0000000..dc9ad51 --- /dev/null +++ b/target/linux/atheros/patches-2.6.24/160-watchdog.patch @@ -0,0 +1,35 @@ +commit a9d0bee7a0891667764e4c1c0c76af5abb7ab446 +Author: Axel Gembe <[EMAIL PROTECTED]> +Date: Wed May 7 10:30:26 2008 +0200 + + watchdog patch + +diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig +index 52dff40..89f4b0a 100644 +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -639,6 +639,12 @@ config AR7_WDT + help + Hardware driver for the TI AR7 Watchdog Timer. + ++config ATHEROS_WDT ++ tristate "Atheros hardware watchdog" ++ depends on ATHEROS ++ help ++ Hardware driver for the Atheros Watchdog Timer. ++ + # PARISC Architecture + + # POWERPC Architecture +diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile +index 87483cc..9dee070 100644 +--- a/drivers/watchdog/Makefile ++++ b/drivers/watchdog/Makefile +@@ -93,6 +93,7 @@ obj-$(CONFIG_INDYDOG) += indydog.o + obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o + obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o + obj-$(CONFIG_AR7_WDT) += ar7_wdt.o ++obj-$(CONFIG_ATHEROS_WDT) += ar531x_wdt.o + + # PARISC Architecture + diff --git a/target/linux/atheros/patches-2.6.25/160-watchdog.patch b/target/linux/atheros/patches-2.6.25/160-watchdog.patch new file mode 100644 index 0000000..1273d8b --- /dev/null +++ b/target/linux/atheros/patches-2.6.25/160-watchdog.patch @@ -0,0 +1,35 @@ +commit acdf903800de2d3329c7036a43f61e9d9baf0a4b +Author: Axel Gembe <[EMAIL PROTECTED]> +Date: Tue May 6 12:46:05 2008 +0200 + + watchdog patch + +diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig +index 254d115..0162147 100644 +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -670,6 +670,12 @@ config TXX9_WDT + help + Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs. + ++config ATHEROS_WDT ++ tristate "Atheros hardware watchdog" ++ depends on ATHEROS ++ help ++ Hardware driver for the Atheros Watchdog Timer. ++ + # PARISC Architecture + + # POWERPC Architecture +diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile +index f3fb170..68b630e 100644 +--- a/drivers/watchdog/Makefile ++++ b/drivers/watchdog/Makefile +@@ -96,6 +96,7 @@ obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o + obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o + obj-$(CONFIG_AR7_WDT) += ar7_wdt.o + obj-$(CONFIG_TXX9_WDT) += txx9wdt.o ++obj-$(CONFIG_ATHEROS_WDT) += ar531x_wdt.o + + # PARISC Architecture + -- 1.5.5.1 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org http://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel