diff options
Diffstat (limited to 'arch/ppc/syslib/m8xx_wdt.c')
-rw-r--r-- | arch/ppc/syslib/m8xx_wdt.c | 92 |
1 files changed, 67 insertions, 25 deletions
diff --git a/arch/ppc/syslib/m8xx_wdt.c b/arch/ppc/syslib/m8xx_wdt.c index a21632d37e5a..df6c9557b86a 100644 --- a/arch/ppc/syslib/m8xx_wdt.c +++ b/arch/ppc/syslib/m8xx_wdt.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <syslib/m8xx_wdt.h> | 19 | #include <syslib/m8xx_wdt.h> |
20 | 20 | ||
21 | static int wdt_timeout; | 21 | static int wdt_timeout; |
22 | int m8xx_has_internal_rtc = 0; | ||
22 | 23 | ||
23 | static irqreturn_t m8xx_wdt_interrupt(int, void *, struct pt_regs *); | 24 | static irqreturn_t m8xx_wdt_interrupt(int, void *, struct pt_regs *); |
24 | static struct irqaction m8xx_wdt_irqaction = { | 25 | static struct irqaction m8xx_wdt_irqaction = { |
@@ -45,35 +46,15 @@ static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs) | |||
45 | return IRQ_HANDLED; | 46 | return IRQ_HANDLED; |
46 | } | 47 | } |
47 | 48 | ||
48 | void __init m8xx_wdt_handler_install(bd_t * binfo) | 49 | #define SYPCR_SWP 0x1 |
50 | #define SYPCR_SWE 0x4 | ||
51 | |||
52 | |||
53 | void __init m8xx_wdt_install_irq(volatile immap_t *imap, bd_t *binfo) | ||
49 | { | 54 | { |
50 | volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; | ||
51 | u32 pitc; | 55 | u32 pitc; |
52 | u32 sypcr; | ||
53 | u32 pitrtclk; | 56 | u32 pitrtclk; |
54 | 57 | ||
55 | sypcr = in_be32(&imap->im_siu_conf.sc_sypcr); | ||
56 | |||
57 | if (!(sypcr & 0x04)) { | ||
58 | printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n", | ||
59 | sypcr); | ||
60 | return; | ||
61 | } | ||
62 | |||
63 | m8xx_wdt_reset(); | ||
64 | |||
65 | printk(KERN_NOTICE | ||
66 | "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n", | ||
67 | (sypcr >> 16), sypcr & 0x01); | ||
68 | |||
69 | wdt_timeout = (sypcr >> 16) & 0xFFFF; | ||
70 | |||
71 | if (!wdt_timeout) | ||
72 | wdt_timeout = 0xFFFF; | ||
73 | |||
74 | if (sypcr & 0x01) | ||
75 | wdt_timeout *= 2048; | ||
76 | |||
77 | /* | 58 | /* |
78 | * Fire trigger if half of the wdt ticked down | 59 | * Fire trigger if half of the wdt ticked down |
79 | */ | 60 | */ |
@@ -98,6 +79,67 @@ void __init m8xx_wdt_handler_install(bd_t * binfo) | |||
98 | printk(KERN_NOTICE | 79 | printk(KERN_NOTICE |
99 | "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n", pitc); | 80 | "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n", pitc); |
100 | 81 | ||
82 | } | ||
83 | |||
84 | static void m8xx_wdt_timer_func(unsigned long data); | ||
85 | |||
86 | static struct timer_list m8xx_wdt_timer = | ||
87 | TIMER_INITIALIZER(m8xx_wdt_timer_func, 0, 0); | ||
88 | |||
89 | void m8xx_wdt_stop_timer(void) | ||
90 | { | ||
91 | del_timer(&m8xx_wdt_timer); | ||
92 | } | ||
93 | |||
94 | void m8xx_wdt_install_timer(void) | ||
95 | { | ||
96 | m8xx_wdt_timer.expires = jiffies + (HZ/2); | ||
97 | add_timer(&m8xx_wdt_timer); | ||
98 | } | ||
99 | |||
100 | static void m8xx_wdt_timer_func(unsigned long data) | ||
101 | { | ||
102 | m8xx_wdt_reset(); | ||
103 | m8xx_wdt_install_timer(); | ||
104 | } | ||
105 | |||
106 | void __init m8xx_wdt_handler_install(bd_t * binfo) | ||
107 | { | ||
108 | volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; | ||
109 | u32 sypcr; | ||
110 | |||
111 | sypcr = in_be32(&imap->im_siu_conf.sc_sypcr); | ||
112 | |||
113 | if (!(sypcr & SYPCR_SWE)) { | ||
114 | printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n", | ||
115 | sypcr); | ||
116 | return; | ||
117 | } | ||
118 | |||
119 | m8xx_wdt_reset(); | ||
120 | |||
121 | printk(KERN_NOTICE | ||
122 | "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n", | ||
123 | (sypcr >> 16), sypcr & SYPCR_SWP); | ||
124 | |||
125 | wdt_timeout = (sypcr >> 16) & 0xFFFF; | ||
126 | |||
127 | if (!wdt_timeout) | ||
128 | wdt_timeout = 0xFFFF; | ||
129 | |||
130 | if (sypcr & SYPCR_SWP) | ||
131 | wdt_timeout *= 2048; | ||
132 | |||
133 | m8xx_has_internal_rtc = in_be16(&imap->im_sit.sit_rtcsc) & RTCSC_RTE; | ||
134 | |||
135 | /* if the internal RTC is off use a kernel timer */ | ||
136 | if (!m8xx_has_internal_rtc) { | ||
137 | if (wdt_timeout < (binfo->bi_intfreq/HZ)) | ||
138 | printk(KERN_ERR "m8xx_wdt: timeout too short for ktimer!\n"); | ||
139 | m8xx_wdt_install_timer(); | ||
140 | } else | ||
141 | m8xx_wdt_install_irq(imap, binfo); | ||
142 | |||
101 | wdt_timeout /= binfo->bi_intfreq; | 143 | wdt_timeout /= binfo->bi_intfreq; |
102 | } | 144 | } |
103 | 145 | ||