[PATCH v6 05/19] watchdog: orion: Make sure the watchdog is initially stopped
linux at roeck-us.net
linux at roeck-us.net
Mon Feb 10 11:48:50 EST 2014
Quoting Ezequiel Garcia <ezequiel.garcia at free-electrons.com>:
> On Fri, Feb 07, 2014 at 10:43:14AM -0700, Jason Gunthorpe wrote:
>> On Fri, Feb 07, 2014 at 07:40:45AM -0300, Ezequiel Garcia wrote:
>>
>> > Well, this is related to the discussion about the bootloader not
>> > reseting the watchdog properly, provoking spurious watchdog triggering.
>> >
>> > Jason Gunthorpe explained [1] that we needed a particular sequence:
>> >
>> > 1. Disable WDT
>> > 2. Clear bridge
>> > 3. Enable WDT
>> >
>> > We added the irq handling to satisfy (2), and the watchdog stop for (1).
>>
>> The issue here is the driver configures two 'machine kill' elements:
>> the PANIC IRQ and the RstOut setup.
>>
>> Before configuring either of those the driver needs to ensure that any
>> old watchdog events are cleared out of the HW. We must not get a
>> spurious event.
>>
>> I agree not disabling an already functional and properly configured
>> counter from the bootloader is desirable.
>>
>> So lets break it down a bit..
>>
>> 1) The IRQ:
>> It looks like the cause bit latches high on watchdog timer
>> expiration but has no side effect unless it is unmasked.
>>
>> The new IRQ flow code ensures the bit is cleared during request_irq
>> so no old events can trigger the IRQ. Thus it is solved now.
>>
>
> Agreed.
>
>> 3) The timer itself:
>> The WDT is just a general timer with an optional hookup to the
>> rst control. If it is harmlessly counting but not resetting we need
>> to stop that before enabling rst out.
>>
>
> Actually, the current flow is to:
>
> 1. Disable rst out and then disable the counter, in probe().
>
> 2. Enable the counter, and then enable rst out, in start().
>
>> So, how about this for psuedo-code in probe:
>>
>> if (readl(RSTOUTn) & WDRstOutEn)
>> {
>> /* Watchdog is configured and may be down counting,
>> don't touch it */
>> request_irq(..);
>> }
>> else
>> {
>> /* Watchdog is not configured, fully disable the timer
>> and configure for watchdog operation. */
>> disable_watchdog();
>> request_irq();
>> writel(RSTOUTn), .. WDRstOutEn);
>> }
>>
>
> Sounds good, although it seems to me it's actually simpler:
>
> /* Let's make sure the watchdog is fully stopped, unless
> * it's explicitly enabled and running
> */
> if ( !(wdt_rst_out_en && wdt_timer_enabled) ) {
> watchdog_stop();
> }
>
if (!wdt_rst_out_en || !wdt_timer_enabled)
watchdog_stop();
seems to be a bit easier to understand.
Also watch out for coding style issues. Above code
snippet has multiple violations ;-).
Guenter
More information about the linux-arm-kernel
mailing list