[PATCH] m8xx_wdt: software watchdog reset/interrupt select
Kumar Gala
galak at kernel.crashing.org
Tue Nov 15 07:55:24 EST 2005
Can we put the WDT for 8xx in drivers/char/watchdog/?
- kumar
On Nov 14, 2005, at 8:38 AM, Marcelo Tosatti wrote:
> Hi,
>
> Currently the mpc8xx_wdt driver installs an IRQ handler for
> PIT_INTERRUPT (SIU_LEVEL0, irq 1) to service the WDT until a userspace
> watchdog daemon takes over after boot.
>
> However, if the "software watchdog reset/interrupt select" (SWRI)
> bit of
> SYPCR register is set, no interrupt is generated. In that
> configuration
> (the default) HRESET signal is generated if the WDT timeout expires,
> without kernel notification.
>
> The following patch creates a kernel timer to service the WDT and
> rearm
> itself in case this configuration is detected, making it possible to
> boot the system with the watchdog turned on. The timer is shutdown
> once the userspace daemon open's the device.
>
> Note: From my reading of the documentation, even if the SWRI bit is
> unset (interrupt select mode), an NMI at IRQ0 should cause the
> system to
> jump to exception vector 0x100, resetting the system.
>
> So I'm wondering if the interrupt mode ever worked?
>
>
> --- ../git/linux-2.6/arch/ppc/syslib/m8xx_wdt.c 2005-11-08
> 11:38:39.000000000 -0600
> +++ linux-2.6-git-wednov02/arch/ppc/syslib/m8xx_wdt.c 2005-11-14
> 10:36:53.000000000 -0600
> @@ -45,35 +45,18 @@
> return IRQ_HANDLED;
> }
>
> -void __init m8xx_wdt_handler_install(bd_t * binfo)
> +#define SYPCR_SWP 0x1
> +#define SYPCR_SWRI 0x2
> +#define SYPCR_SWE 0x4
> +
> +/* software watchdog reset/interrupt select */
> +int m8xx_wdt_keepalive_mode = 0;
> +
> +void __init m8xx_wdt_install_irq(volatile immap_t *imap, bd_t *binfo)
> {
> - volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
> u32 pitc;
> - u32 sypcr;
> u32 pitrtclk;
>
> - sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
> -
> - if (!(sypcr & 0x04)) {
> - printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
> - sypcr);
> - return;
> - }
> -
> - m8xx_wdt_reset();
> -
> - printk(KERN_NOTICE
> - "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n",
> - (sypcr >> 16), sypcr & 0x01);
> -
> - wdt_timeout = (sypcr >> 16) & 0xFFFF;
> -
> - if (!wdt_timeout)
> - wdt_timeout = 0xFFFF;
> -
> - if (sypcr & 0x01)
> - wdt_timeout *= 2048;
> -
> /*
> * Fire trigger if half of the wdt ticked down
> */
> @@ -98,6 +81,66 @@
> printk(KERN_NOTICE
> "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n",
> pitc);
>
> +}
> +
> +static void m8xx_wdt_timer_func(unsigned long data);
> +
> +static struct timer_list m8xx_wdt_timer =
> + TIMER_INITIALIZER(m8xx_wdt_timer_func, 0, 0);
> +
> +void m8xx_wdt_stop_timer(void)
> +{
> + del_timer(&m8xx_wdt_timer);
> +}
> +
> +static void m8xx_wdt_timer_func(unsigned long data)
> +{
> + m8xx_wdt_reset();
> + m8xx_wdt_timer.expires = jiffies + 25;
> + add_timer(&m8xx_wdt_timer);
> +}
> +
> +void m8xx_wdt_install_timer(volatile immap_t *imap)
> +{
> + m8xx_wdt_timer.expires = jiffies + 25;
> + add_timer(&m8xx_wdt_timer);
> +}
> +
> +void __init m8xx_wdt_handler_install(bd_t * binfo)
> +{
> + volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
> + u32 sypcr;
> +
> + sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
> +
> + printk(KERN_NOTICE "m8xx_wdt SYPCR: 0x%08X)\n", sypcr);
> +
> + if (!(sypcr & SYPCR_SWE)) {
> + printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
> + sypcr);
> + return;
> + }
> +
> + m8xx_wdt_reset();
> +
> + printk(KERN_NOTICE
> + "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n",
> + (sypcr >> 16), sypcr & SYPCR_SWP);
> +
> + wdt_timeout = (sypcr >> 16) & 0xFFFF;
> +
> + if (!wdt_timeout)
> + wdt_timeout = 0xFFFF;
> +
> + if (sypcr & SYPCR_SWP)
> + wdt_timeout *= 2048;
> +
> + m8xx_wdt_keepalive_mode = sypcr & SYPCR_SWRI;
> + if (m8xx_wdt_keepalive_mode)
> + m8xx_wdt_install_timer(imap);
> + else
> + m8xx_wdt_install_irq(imap, binfo);
> +
> wdt_timeout /= binfo->bi_intfreq;
> }
>
> --- ../git/linux-2.6/arch/ppc/syslib/m8xx_wdt.h 2005-10-10
> 18:06:12.000000000 -0500
> +++ linux-2.6-git-wednov02/arch/ppc/syslib/m8xx_wdt.h 2005-11-14
> 10:37:39.000000000 -0600
> @@ -9,8 +9,12 @@
> #ifndef _PPC_SYSLIB_M8XX_WDT_H
> #define _PPC_SYSLIB_M8XX_WDT_H
>
> +extern int m8xx_wdt_keepalive_mode;
> +
> extern void m8xx_wdt_handler_install(bd_t * binfo);
> extern int m8xx_wdt_get_timeout(void);
> extern void m8xx_wdt_reset(void);
> +extern void m8xx_wdt_install_timer(volatile immap_t *imap);
> +extern void m8xx_wdt_stop_timer(void);
>
> #endif /* _PPC_SYSLIB_M8XX_WDT_H */
> --- ../git/linux-2.6/drivers/char/watchdog/mpc8xx_wdt.c 2005-10-10
> 18:06:15.000000000 -0500
> +++ linux-2.6-git-wednov02/drivers/char/watchdog/mpc8xx_wdt.c
> 2005-11-14 10:37:15.000000000 -0600
> @@ -27,7 +27,10 @@
> {
> volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
>
> - imap->im_sit.sit_piscr &= ~(PISCR_PIE | PISCR_PTE);
> + if (m8xx_wdt_keepalive_mode)
> + m8xx_wdt_stop_timer();
> + else
> + imap->im_sit.sit_piscr &= ~(PISCR_PIE | PISCR_PTE);
>
> printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n");
> }
> @@ -36,7 +39,10 @@
> {
> volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
>
> - imap->im_sit.sit_piscr |= PISCR_PIE | PISCR_PTE;
> + if (m8xx_wdt_keepalive_mode)
> + m8xx_wdt_install_timer(imap);
> + else
> + imap->im_sit.sit_piscr |= PISCR_PIE | PISCR_PTE;
>
> printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n");
> }
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
More information about the Linuxppc-embedded
mailing list