]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/watchdog/tegra_wdt.c
59a4100385699650d85bd8aa6fa08255111b45bc
[sojka/nv-tegra/linux-3.10.git] / drivers / watchdog / tegra_wdt.c
1 /*
2  * drivers/watchdog/tegra_wdt.c
3  *
4  * watchdog driver for NVIDIA tegra internal watchdog
5  *
6  * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved.
7  *
8  * based on drivers/watchdog/softdog.c and drivers/watchdog/omap_wdt.c
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18  * more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23  */
24
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/fs.h>
28 #include <linux/interrupt.h>
29 #include <linux/io.h>
30 #include <linux/kernel.h>
31 #include <linux/miscdevice.h>
32 #include <linux/notifier.h>
33 #include <linux/platform_device.h>
34 #include <linux/reboot.h>
35 #include <linux/slab.h>
36 #include <linux/spinlock.h>
37 #include <linux/uaccess.h>
38 #include <linux/watchdog.h>
39 #include <linux/nmi.h>
40 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
41 #include <mach/irqs.h>
42 #endif
43
44 /* minimum and maximum watchdog trigger periods, in seconds */
45 #define MIN_WDT_PERIOD  5
46 #define MAX_WDT_PERIOD  1000
47 /* Assign Timer 7 to Timer 10 for WDT0 to WDT3, respectively */
48 #define TMR_SRC_START   7
49
50 enum tegra_wdt_status {
51         WDT_DISABLED = 1 << 0,
52         WDT_ENABLED = 1 << 1,
53         WDT_ENABLED_AT_PROBE = 1 << 2,
54 };
55
56 struct tegra_wdt {
57         struct miscdevice       miscdev;
58         struct notifier_block   notifier;
59         struct resource         *res_src;
60         struct resource         *res_wdt;
61         struct resource         *res_int_base;
62         struct resource         *res_pmc;
63         unsigned long           users;
64         void __iomem            *wdt_source;
65         void __iomem            *wdt_timer;
66         void __iomem            *int_base;
67         void __iomem            *pmc_base;
68         int                     irq;
69         int                     tmrsrc;
70         int                     timeout;
71         int                     status;
72 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
73         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
74         struct resource         *res_avp_src;
75         void __iomem            *wdt_avp_source;
76 #endif
77
78 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
79         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
80         struct resource         *res_avp_src;
81         void __iomem            *wdt_avp_source;
82 #endif
83 };
84
85 /*
86  * For spinlock lockup detection to work, the heartbeat should be 2*lockup
87  * for cases where the spinlock disabled irqs.
88  */
89 static int heartbeat = 80; /* must be greater than MIN_WDT_PERIOD and lower than MAX_WDT_PERIOD */
90
91 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
92
93 #define TIMER_PTV               0x0
94  #define TIMER_EN               (1 << 31)
95  #define TIMER_PERIODIC         (1 << 30)
96 #define TIMER_PCR               0x4
97  #define TIMER_PCR_INTR         (1 << 30)
98 #define WDT_EN                  (1 << 5)
99 #define WDT_SEL_TMR1            (0 << 4)
100 #define WDT_SYS_RST             (1 << 2)
101
102 static void tegra_wdt_enable(struct tegra_wdt *wdt)
103 {
104         u32 val;
105
106         /* since the watchdog reset occurs when a second interrupt
107          * is asserted before the first is processed, program the
108          * timer period to one-half of the watchdog period */
109         val = wdt->timeout * 1000000ul / 2;
110         val |= (TIMER_EN | TIMER_PERIODIC);
111         writel(val, wdt->wdt_timer + TIMER_PTV);
112
113         val = WDT_EN | WDT_SEL_TMR1 | WDT_SYS_RST;
114         writel(val, wdt->wdt_source);
115 }
116
117 static void tegra_wdt_disable(struct tegra_wdt *wdt)
118 {
119         writel(0, wdt->wdt_source);
120         writel(0, wdt->wdt_timer + TIMER_PTV);
121 }
122
123 static inline void tegra_wdt_ping(struct tegra_wdt *wdt)
124 {
125         return;
126 }
127
128 static irqreturn_t tegra_wdt_interrupt(int irq, void *dev_id)
129 {
130         struct tegra_wdt *wdt = dev_id;
131
132         writel(TIMER_PCR_INTR, wdt->wdt_timer + TIMER_PCR);
133         return IRQ_HANDLED;
134 }
135 #elif defined(CONFIG_ARCH_TEGRA_3x_SOC) || defined(CONFIG_ARCH_TEGRA_12x_SOC)
136
137 #define TIMER_PTV                       0
138  #define TIMER_EN                       (1 << 31)
139  #define TIMER_PERIODIC                 (1 << 30)
140 #define TIMER_PCR                       0x4
141  #define TIMER_PCR_INTR                 (1 << 30)
142 #define WDT_CFG                         (0)
143  #define WDT_CFG_PERIOD                 (1 << 4)
144  #define WDT_CFG_INT_EN                 (1 << 12)
145  #define WDT_CFG_FIQ_INT_EN             (1 << 13)
146  #define WDT_CFG_SYS_RST_EN             (1 << 14)
147  #define WDT_CFG_PMC2CAR_RST_EN         (1 << 15)
148 #define WDT_STATUS                      (4)
149  #define WDT_INTR_STAT                  (1 << 1)
150 #define WDT_CMD                         (8)
151  #define WDT_CMD_START_COUNTER          (1 << 0)
152  #define WDT_CMD_DISABLE_COUNTER        (1 << 1)
153 #define WDT_UNLOCK                      (0xC)
154  #define WDT_UNLOCK_PATTERN             (0xC45A << 0)
155 #define ICTLR_IEP_CLASS                 0x2C
156 #define MAX_NR_CPU_WDT                  0x4
157 #define PMC_RST_STATUS                  0x1b4
158
159 struct tegra_wdt *tegra_wdt[MAX_NR_CPU_WDT];
160 /*
161  * In order to generate the stack dump for the CPU which has IRQ off, we must
162  * use the FIQ. TEGRA WDT can generate the FIQ if we do not ACK the IRQ.
163  */
164 bool wdt_nmi_ack_off;
165
166 static inline void tegra_wdt_ping(struct tegra_wdt *wdt)
167 {
168         writel(WDT_CMD_START_COUNTER, wdt->wdt_source + WDT_CMD);
169 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
170         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
171         /* Comment out to test FIQ debugger */
172         if (!watchdog_get_lockup_state())
173                 writel(WDT_CMD_START_COUNTER, wdt->wdt_avp_source + WDT_CMD);
174 #endif
175
176 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
177         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
178         if (wdt_nmi_ack_off == false)
179                 writel(WDT_CMD_START_COUNTER, wdt->wdt_avp_source + WDT_CMD);
180 #endif
181
182 }
183
184 #if !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
185 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
186 static void tegra_wdt_int_priority(struct tegra_wdt *wdt)
187 {
188         unsigned val = 0;
189
190         if (!wdt->int_base)
191                 return;
192         val = readl(wdt->int_base + ICTLR_IEP_CLASS);
193         val &= ~(1 << (INT_WDT_CPU & 31));
194         writel(val, wdt->int_base + ICTLR_IEP_CLASS);
195 }
196 #endif
197 #endif
198
199 #if defined(CONFIG_TRUSTED_FOUNDATIONS) || \
200         !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
201 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
202 static void tegra_wdt_int_priority(struct tegra_wdt *wdt)
203 {
204         unsigned val = 0;
205
206         if (!wdt->int_base)
207                 return;
208         val = readl(wdt->int_base + ICTLR_IEP_CLASS);
209         val &= ~(1 << (INT_WDT_CPU & 31));
210         writel(val, wdt->int_base + ICTLR_IEP_CLASS);
211 }
212 #endif
213 #endif
214
215 static void tegra_wdt_enable(struct tegra_wdt *wdt)
216 {
217         u32 val;
218
219         writel(TIMER_PCR_INTR, wdt->wdt_timer + TIMER_PCR);
220         val = (wdt->timeout * 1000000ul) / 4;
221         val |= (TIMER_EN | TIMER_PERIODIC);
222         writel(val, wdt->wdt_timer + TIMER_PTV);
223
224         /* Interrupt handler is not required for user space
225          * WDT accesses, since the caller is responsible to ping the
226          * WDT to reset the counter before expiration, through ioctls.
227          * SYS_RST_EN doesnt work as there is no external reset
228          * from Tegra.
229          */
230         val = wdt->tmrsrc | WDT_CFG_PERIOD | /*WDT_CFG_INT_EN |*/
231                 /*WDT_CFG_SYS_RST_EN |*/ WDT_CFG_PMC2CAR_RST_EN;
232
233 #if !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
234 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
235         val |= WDT_CFG_FIQ_INT_EN;
236 #endif
237 #endif
238
239 #if defined(CONFIG_TRUSTED_FOUNDATIONS) || \
240         !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
241 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
242         val |= WDT_CFG_FIQ_INT_EN;
243 #endif
244 #endif
245
246         writel(val, wdt->wdt_source + WDT_CFG);
247         writel(WDT_CMD_START_COUNTER, wdt->wdt_source + WDT_CMD);
248
249 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
250         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
251         val = wdt->tmrsrc | (WDT_CFG_PERIOD << 1) | /*WDT_CFG_INT_EN |*/
252                 /*WDT_CFG_SYS_RST_EN |*/ WDT_CFG_PMC2CAR_RST_EN;
253         writel(val, wdt->wdt_avp_source + WDT_CFG);
254         writel(WDT_CMD_START_COUNTER, wdt->wdt_avp_source + WDT_CMD);
255
256 #endif
257
258 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
259         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
260         val = wdt->tmrsrc | (WDT_CFG_PERIOD << 1) | /*WDT_CFG_INT_EN |*/
261                 /*WDT_CFG_SYS_RST_EN |*/ WDT_CFG_PMC2CAR_RST_EN;
262         writel(val, wdt->wdt_avp_source + WDT_CFG);
263         writel(WDT_CMD_START_COUNTER, wdt->wdt_avp_source + WDT_CMD);
264
265 #endif
266 }
267
268 static void tegra_wdt_disable(struct tegra_wdt *wdt)
269 {
270         writel(WDT_UNLOCK_PATTERN, wdt->wdt_source + WDT_UNLOCK);
271         writel(WDT_CMD_DISABLE_COUNTER, wdt->wdt_source + WDT_CMD);
272
273 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
274         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
275         writel(WDT_UNLOCK_PATTERN, wdt->wdt_avp_source + WDT_UNLOCK);
276         writel(WDT_CMD_DISABLE_COUNTER, wdt->wdt_avp_source + WDT_CMD);
277 #endif
278
279 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
280         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
281         writel(WDT_UNLOCK_PATTERN, wdt->wdt_avp_source + WDT_UNLOCK);
282         writel(WDT_CMD_DISABLE_COUNTER, wdt->wdt_avp_source + WDT_CMD);
283 #endif
284         writel(0, wdt->wdt_timer + TIMER_PTV);
285 }
286
287 static irqreturn_t tegra_wdt_interrupt(int irq, void *dev_id)
288 {
289         unsigned i, status;
290
291         for (i = 0; i < MAX_NR_CPU_WDT; i++) {
292                 if (tegra_wdt[i] == NULL)
293                         continue;
294                 status = readl(tegra_wdt[i]->wdt_source + WDT_STATUS);
295                 if ((tegra_wdt[i]->status & WDT_ENABLED) &&
296                     (status & WDT_INTR_STAT))
297                         tegra_wdt_ping(tegra_wdt[i]);
298         }
299
300         return IRQ_HANDLED;
301 }
302
303 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
304         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
305 static irqreturn_t tegra_wdt_avp_interrupt(int irq, void *dev_id)
306 {
307         return IRQ_HANDLED;
308 }
309 #endif
310
311 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
312         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
313 static irqreturn_t tegra_wdt_avp_interrupt(int irq, void *dev_id)
314 {
315         return IRQ_HANDLED;
316 }
317 #endif
318
319
320 #endif
321
322 static int tegra_wdt_notify(struct notifier_block *this,
323                             unsigned long code, void *dev)
324 {
325         struct tegra_wdt *wdt = container_of(this, struct tegra_wdt, notifier);
326
327         if (code == SYS_DOWN || code == SYS_HALT)
328                 tegra_wdt_disable(wdt);
329         return NOTIFY_DONE;
330 }
331
332 static int tegra_wdt_open(struct inode *inode, struct file *file)
333 {
334         struct miscdevice *mdev = file->private_data;
335         struct tegra_wdt *wdt = container_of(mdev, struct tegra_wdt,
336                                              miscdev);
337
338         if (test_and_set_bit(1, &wdt->users))
339                 return -EBUSY;
340
341         wdt->status |= WDT_ENABLED;
342         wdt->timeout = heartbeat;
343         tegra_wdt_enable(wdt);
344         file->private_data = wdt;
345         return nonseekable_open(inode, file);
346 }
347
348 static int tegra_wdt_release(struct inode *inode, struct file *file)
349 {
350         struct tegra_wdt *wdt = file->private_data;
351
352         if (wdt->status & WDT_ENABLED) {
353 #ifndef CONFIG_WATCHDOG_NOWAYOUT
354                 tegra_wdt_disable(wdt);
355                 wdt->status = WDT_DISABLED;
356 #endif
357         }
358         wdt->users = 0;
359         return 0;
360 }
361
362 static long tegra_wdt_ioctl(struct file *file, unsigned int cmd,
363                             unsigned long arg)
364 {
365         struct tegra_wdt *wdt = file->private_data;
366         static DEFINE_SPINLOCK(lock);
367         int new_timeout;
368 #ifndef CONFIG_WATCHDOG_NOWAYOUT
369         int option;
370 #endif
371         static const struct watchdog_info ident = {
372                 .identity = "Tegra Watchdog",
373                 .options = WDIOF_SETTIMEOUT,
374                 .firmware_version = 0,
375         };
376
377         switch (cmd) {
378         case WDIOC_GETSUPPORT:
379                 return copy_to_user((struct watchdog_info __user *)arg, &ident,
380                                     sizeof(ident));
381         case WDIOC_GETSTATUS:
382         case WDIOC_GETBOOTSTATUS:
383                 return put_user(0, (int __user *)arg);
384
385         case WDIOC_KEEPALIVE:
386                 spin_lock(&lock);
387                 tegra_wdt_ping(wdt);
388                 spin_unlock(&lock);
389                 return 0;
390
391         case WDIOC_SETTIMEOUT:
392                 if (get_user(new_timeout, (int __user *)arg))
393                         return -EFAULT;
394                 spin_lock(&lock);
395                 tegra_wdt_disable(wdt);
396                 wdt->timeout = clamp(new_timeout, MIN_WDT_PERIOD, MAX_WDT_PERIOD);
397                 tegra_wdt_enable(wdt);
398                 spin_unlock(&lock);
399         case WDIOC_GETTIMEOUT:
400                 return put_user(wdt->timeout, (int __user *)arg);
401
402         case WDIOC_SETOPTIONS:
403 #ifndef CONFIG_WATCHDOG_NOWAYOUT
404                 if (get_user(option, (int __user *)arg))
405                         return -EFAULT;
406                 spin_lock(&lock);
407                 if (option & WDIOS_DISABLECARD) {
408                         wdt->status &= ~WDT_ENABLED;
409                         wdt->status |= WDT_DISABLED;
410                         tegra_wdt_disable(wdt);
411                 } else if (option & WDIOS_ENABLECARD) {
412                         tegra_wdt_enable(wdt);
413                         wdt->status |= WDT_ENABLED;
414                         wdt->status &= ~WDT_DISABLED;
415                 } else {
416                         spin_unlock(&lock);
417                         return -EINVAL;
418                 }
419                 spin_unlock(&lock);
420                 return 0;
421 #else
422                 return -EINVAL;
423 #endif
424         }
425         return -ENOTTY;
426 }
427
428 static ssize_t tegra_wdt_write(struct file *file, const char __user *data,
429                                size_t len, loff_t *ppos)
430 {
431         return len;
432 }
433
434 static void tegra_wdt_log_reset_reason(struct platform_device *pdev,
435                 struct tegra_wdt *wdt)
436 {
437
438 #if defined(CONFIG_ARCH_TEGRA_3x_SOC) || defined(CONFIG_ARCH_TEGRA_12x_SOC)
439         /*
440          * There are two pathes to make the WDT reset:
441          *  (a) WDT -> PMC -> CAR
442          *              ^
443          *              |
444          *              v
445          *             PMIC
446          *
447          *  (b) WDT -> CAR
448          *
449          *  Path (a) is enabled by WDT_CFG_PMC2CAR_RST_EN bit in the WDT
450          *  configuration register, as it will reset the CAR module, and we
451          *  cannot read back the reset reason from the CAR module. However, we
452          *  can read back the reaset reason from the PMC module.
453          *
454          *  Path (b) is enabled by the WDT_CFG_SYS_RST_EN bit, and we can
455          *  read back the reset reason from the CAR moudle. However, this reset
456          *  path will not reset the peripherals which might be the hard hang
457          *  source. We will not use this path.
458          */
459         u32 val;
460 #define RESET_STR(REASON) "last reset is due to "#REASON"\n"
461         char *reset_reason[] = {
462                 RESET_STR(power on reset),
463                 RESET_STR(watchdog timeout),
464                 RESET_STR(sensor),
465                 RESET_STR(software reset),
466                 RESET_STR(deep sleep reset),
467         };
468
469         /* report reset reason only once */
470         if (pdev->id > 0)
471                 return;
472
473         val = readl(wdt->pmc_base + PMC_RST_STATUS) & 0x7;
474         if (val >= ARRAY_SIZE(reset_reason))
475                 dev_info(&pdev->dev, "last reset value is invalid 0x%x\n", val);
476         else
477                 dev_info(&pdev->dev, reset_reason[val]);
478
479 #else
480         u32 val;
481
482         val = readl(wdt->wdt_source);
483         if (val & BIT(12))
484                 dev_info(&pdev->dev, "last reset due to watchdog timeout\n");
485 #endif
486 }
487
488 static const struct file_operations tegra_wdt_fops = {
489         .owner          = THIS_MODULE,
490         .llseek         = no_llseek,
491         .write          = tegra_wdt_write,
492         .unlocked_ioctl = tegra_wdt_ioctl,
493         .open           = tegra_wdt_open,
494         .release        = tegra_wdt_release,
495 };
496
497 static int tegra_wdt_probe(struct platform_device *pdev)
498 {
499         struct resource *res_src, *res_wdt, *res_irq, *res_pmc;
500 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
501         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
502         struct resource *res_avp_src, *res_avp_irq;
503 #endif
504
505 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
506         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
507         struct resource *res_avp_src, *res_avp_irq;
508 #endif
509
510         struct resource *res_int_base = NULL;
511         struct tegra_wdt *wdt;
512         int ret = 0;
513
514         if ((pdev->id < -1) || (pdev->id > 0)) {
515                 dev_err(&pdev->dev, "Only support IDs -1 and 0\n");
516                 return -ENODEV;
517         }
518
519         res_src = platform_get_resource(pdev, IORESOURCE_MEM, 0);
520         res_wdt = platform_get_resource(pdev, IORESOURCE_MEM, 1);
521         res_pmc = platform_get_resource(pdev, IORESOURCE_MEM, 2);
522         res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
523
524 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
525         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
526         res_avp_src = platform_get_resource(pdev, IORESOURCE_MEM, 4);
527         res_avp_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
528 #endif
529
530 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
531         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
532         res_avp_src = platform_get_resource(pdev, IORESOURCE_MEM, 4);
533         res_avp_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
534 #endif
535
536
537 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
538         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
539         if (!res_src || !res_wdt || !res_avp_src || (!pdev->id && !res_irq) ||
540             !res_pmc) {
541 #else
542
543 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
544         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
545         if (!res_src || !res_wdt || !res_avp_src || (!pdev->id && !res_irq)) {
546 #else
547         if (!res_src || !res_wdt || (!pdev->id && !res_irq) || !res_pmc) {
548 #endif
549
550 #endif
551                 dev_err(&pdev->dev, "incorrect resources\n");
552                 return -ENOENT;
553         }
554
555 #if !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
556 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
557         res_int_base = platform_get_resource(pdev, IORESOURCE_MEM, 3);
558         if (!pdev->id && !res_int_base) {
559                 dev_err(&pdev->dev, "FIQ_DBG: INT base not defined\n");
560                 return -ENOENT;
561         }
562 #endif
563 #endif
564
565 #if defined(CONFIG_TRUSTED_FOUNDATIONS) || \
566         !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
567 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
568         res_int_base = platform_get_resource(pdev, IORESOURCE_MEM, 3);
569         if (!pdev->id && !res_int_base) {
570                 dev_err(&pdev->dev, "FIQ_DBG: INT base not defined\n");
571                 return -ENOENT;
572         }
573 #endif
574 #endif
575
576
577         if (pdev->id == -1 && !res_irq) {
578                 dev_err(&pdev->dev, "incorrect irq\n");
579                 return -ENOENT;
580         }
581
582         wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
583         if (!wdt) {
584                 dev_err(&pdev->dev, "out of memory\n");
585                 return -ENOMEM;
586         }
587
588         wdt->irq = -1;
589         wdt->miscdev.parent = &pdev->dev;
590         if (pdev->id == -1) {
591                 wdt->miscdev.minor = WATCHDOG_MINOR;
592                 wdt->miscdev.name = "watchdog";
593         } else {
594                 wdt->miscdev.minor = MISC_DYNAMIC_MINOR;
595                 if (pdev->id == 0)
596                         wdt->miscdev.name = "watchdog0";
597                 else if (pdev->id == 1)
598                         wdt->miscdev.name = "watchdog1";
599                 else if (pdev->id == 2)
600                         wdt->miscdev.name = "watchdog2";
601                 else if (pdev->id == 3)
602                         wdt->miscdev.name = "watchdog3";
603         }
604         wdt->miscdev.fops = &tegra_wdt_fops;
605
606         wdt->notifier.notifier_call = tegra_wdt_notify;
607
608         res_src = request_mem_region(res_src->start, resource_size(res_src),
609                                      pdev->name);
610         res_wdt = request_mem_region(res_wdt->start, resource_size(res_wdt),
611                                      pdev->name);
612         res_pmc = request_mem_region(res_pmc->start, resource_size(res_pmc),
613                                      pdev->name);
614
615 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
616         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
617         res_avp_src = request_mem_region(res_avp_src->start,
618                                          resource_size(res_avp_src),
619                                          pdev->name);
620 #endif
621
622 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
623         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
624         res_avp_src = request_mem_region(res_avp_src->start,
625                                          resource_size(res_avp_src),
626                                          pdev->name);
627 #endif
628
629 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
630         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
631         if (!res_src || !res_wdt || !res_avp_src || !res_pmc) {
632 #else
633
634 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
635         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
636         if (!res_src || !res_wdt || !res_avp_src || !res_pmc) {
637 #else
638         if (!res_src || !res_wdt || !res_pmc) {
639 #endif
640
641 #endif
642                 dev_err(&pdev->dev, "unable to request memory resources\n");
643                 ret = -EBUSY;
644                 goto fail;
645         }
646
647         wdt->wdt_source = ioremap(res_src->start, resource_size(res_src));
648         wdt->wdt_timer = ioremap(res_wdt->start, resource_size(res_wdt));
649         wdt->pmc_base = ioremap(res_pmc->start, resource_size(res_pmc));
650
651 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
652         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
653         wdt->wdt_avp_source = ioremap(res_avp_src->start,
654                                       resource_size(res_avp_src));
655 #endif
656
657 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
658         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
659         wdt->wdt_avp_source = ioremap(res_avp_src->start,
660                                       resource_size(res_avp_src));
661 #endif
662
663         /* tmrsrc will be used to set WDT_CFG */
664         wdt->tmrsrc = (TMR_SRC_START + pdev->id) % 10;
665
666 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
667         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
668         if (!wdt->wdt_source || !wdt->wdt_timer || !wdt->wdt_avp_source ||
669             !wdt->pmc_base) {
670 #else
671 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
672         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
673         if (!wdt->wdt_source || !wdt->wdt_timer || !wdt->wdt_avp_source ||
674             !wdt->pmc_base) {
675 #else
676         if (!wdt->wdt_source || !wdt->wdt_timer || !wdt->pmc_base) {
677 #endif
678
679 #endif
680                 dev_err(&pdev->dev, "unable to map registers\n");
681                 ret = -ENOMEM;
682                 goto fail;
683         }
684
685         tegra_wdt_log_reset_reason(pdev, wdt);
686
687         tegra_wdt_disable(wdt);
688         writel(TIMER_PCR_INTR, wdt->wdt_timer + TIMER_PCR);
689
690         if (res_irq != NULL) {
691 #if !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
692 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
693                 /* FIQ debugger enables FIQ priority for INT_WDT_CPU.
694                  * But that will disable IRQ on WDT expiration.
695                  * Reset the priority back to IRQ on INT_WDT_CPU so
696                  * that tegra_wdt_interrupt gets its chance to restart the
697                  * counter before expiration.
698                  */
699                 res_int_base = request_mem_region(res_int_base->start,
700                                                   resource_size(res_int_base),
701                                                   pdev->name);
702                 if (!res_int_base)
703                         goto fail;
704                 wdt->int_base = ioremap(res_int_base->start,
705                                         resource_size(res_int_base));
706                 if (!wdt->int_base)
707                         goto fail;
708                 tegra_wdt_int_priority(wdt);
709 #endif
710 #endif
711
712 #if defined(CONFIG_TRUSTED_FOUNDATIONS) || \
713         !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
714 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
715                 /* FIQ debugger enables FIQ priority for INT_WDT_CPU.
716                  * But that will disable IRQ on WDT expiration.
717                  * Reset the priority back to IRQ on INT_WDT_CPU so
718                  * that tegra_wdt_interrupt gets its chance to restart the
719                  * counter before expiration.
720                  */
721                 res_int_base = request_mem_region(res_int_base->start,
722                                                   resource_size(res_int_base),
723                                                   pdev->name);
724                 if (!res_int_base)
725                         goto fail;
726                 wdt->int_base = ioremap(res_int_base->start,
727                                         resource_size(res_int_base));
728                 if (!wdt->int_base)
729                         goto fail;
730                 tegra_wdt_int_priority(wdt);
731 #endif
732 #endif
733                 ret = request_irq(res_irq->start, tegra_wdt_interrupt,
734                                   IRQF_DISABLED, dev_name(&pdev->dev), wdt);
735                 if (ret) {
736                         dev_err(&pdev->dev, "unable to configure IRQ\n");
737                         goto fail;
738                 }
739
740 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
741         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
742                 ret = request_irq(res_avp_irq->start, tegra_wdt_avp_interrupt,
743                                 IRQF_DISABLED, "avp_wdt", wdt);
744                 if (ret) {
745                         dev_err(&pdev->dev, "unable to configure WDT AVP IRQ\n");
746                         goto fail;
747                 }
748 #endif
749
750 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
751         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
752                 ret = request_irq(res_avp_irq->start, tegra_wdt_avp_interrupt,
753                                 IRQF_DISABLED, "avp_wdt", wdt);
754                 if (ret) {
755                         dev_err(&pdev->dev, "unable to configure WDT AVP IRQ\n");
756                         goto fail;
757                 }
758 #endif
759                 wdt->irq = res_irq->start;
760         }
761
762         wdt->res_src = res_src;
763
764 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
765         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
766         wdt->res_avp_src = res_avp_src;
767 #endif
768 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
769         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
770         wdt->res_avp_src = res_avp_src;
771 #endif
772
773         wdt->res_wdt = res_wdt;
774         wdt->res_int_base = res_int_base;
775         wdt->res_pmc = res_pmc;
776         wdt->status = WDT_DISABLED;
777
778         ret = register_reboot_notifier(&wdt->notifier);
779         if (ret) {
780                 dev_err(&pdev->dev, "cannot register reboot notifier\n");
781                 goto fail;
782         }
783
784         ret = misc_register(&wdt->miscdev);
785         if (ret) {
786                 dev_err(&pdev->dev, "failed to register misc device\n");
787                 unregister_reboot_notifier(&wdt->notifier);
788                 goto fail;
789         }
790
791         platform_set_drvdata(pdev, wdt);
792
793 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
794 #ifdef CONFIG_TEGRA_WATCHDOG_ENABLE_ON_PROBE
795         /* Init and enable watchdog on WDT0 with timer 8 during probe */
796         if (!(pdev->id)) {
797                 u32 val = 0;
798                 wdt->status = WDT_ENABLED | WDT_ENABLED_AT_PROBE;
799                 wdt->timeout = heartbeat;
800                 tegra_wdt_enable(wdt);
801                 val = readl(wdt->wdt_source + WDT_CFG);
802                 val |= WDT_CFG_INT_EN;
803                 writel(val, wdt->wdt_source + WDT_CFG);
804
805 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
806         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
807                 val = readl(wdt->wdt_avp_source + WDT_CFG);
808                 val |= WDT_CFG_INT_EN;
809                 writel(val, wdt->wdt_avp_source + WDT_CFG);
810
811 #endif
812
813 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
814         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
815                 val = readl(wdt->wdt_avp_source + WDT_CFG);
816                 val |= WDT_CFG_INT_EN;
817                 writel(val, wdt->wdt_avp_source + WDT_CFG);
818
819 #endif
820
821                 pr_info("WDT heartbeat enabled on probe\n");
822         }
823 #endif
824         tegra_wdt[pdev->id] = wdt;
825 #endif
826         pr_info("%s done\n", __func__);
827         return 0;
828 fail:
829         if (wdt->irq != -1)
830                 free_irq(wdt->irq, wdt);
831         if (wdt->wdt_source)
832                 iounmap(wdt->wdt_source);
833         if (wdt->wdt_timer)
834                 iounmap(wdt->wdt_timer);
835         if (wdt->int_base)
836                 iounmap(wdt->int_base);
837         if (wdt->pmc_base)
838                 iounmap(wdt->pmc_base);
839         if (res_src)
840                 release_mem_region(res_src->start, resource_size(res_src));
841         if (res_wdt)
842                 release_mem_region(res_wdt->start, resource_size(res_wdt));
843         if (res_int_base)
844                 release_mem_region(res_int_base->start,
845                                         resource_size(res_int_base));
846         if (res_pmc)
847                 release_mem_region(res_pmc->start, resource_size(res_pmc));
848
849 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
850         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
851         if (wdt->wdt_avp_source)
852                 iounmap(wdt->wdt_avp_source);
853         if (res_avp_src)
854                 release_mem_region(res_avp_src->start,
855                                    resource_size(res_avp_src));
856 #endif
857
858 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
859         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
860         if (wdt->wdt_avp_source)
861                 iounmap(wdt->wdt_avp_source);
862         if (res_avp_src)
863                 release_mem_region(res_avp_src->start,
864                                    resource_size(res_avp_src));
865 #endif
866         kfree(wdt);
867         return ret;
868 }
869
870 static int tegra_wdt_remove(struct platform_device *pdev)
871 {
872         struct tegra_wdt *wdt = platform_get_drvdata(pdev);
873
874         tegra_wdt_disable(wdt);
875
876         unregister_reboot_notifier(&wdt->notifier);
877         misc_deregister(&wdt->miscdev);
878         if (wdt->irq != -1)
879                 free_irq(wdt->irq, wdt);
880         iounmap(wdt->wdt_source);
881
882 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
883         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
884         iounmap(wdt->wdt_avp_source);
885 #endif
886
887 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
888         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
889         iounmap(wdt->wdt_avp_source);
890 #endif
891         iounmap(wdt->wdt_timer);
892         if (wdt->int_base)
893                 iounmap(wdt->int_base);
894         if (wdt->pmc_base)
895                 iounmap(wdt->pmc_base);
896         release_mem_region(wdt->res_src->start, resource_size(wdt->res_src));
897
898 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
899         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
900         release_mem_region(wdt->res_avp_src->start,
901                            resource_size(wdt->res_avp_src));
902 #endif
903
904 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
905         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
906         release_mem_region(wdt->res_avp_src->start,
907                            resource_size(wdt->res_avp_src));
908 #endif
909
910         release_mem_region(wdt->res_wdt->start, resource_size(wdt->res_wdt));
911         if (wdt->res_int_base)
912                 release_mem_region(wdt->res_int_base->start,
913                                         resource_size(wdt->res_int_base));
914         if (wdt->res_pmc)
915                 release_mem_region(wdt->res_pmc->start,
916                                         resource_size(wdt->res_pmc));
917         kfree(wdt);
918         platform_set_drvdata(pdev, NULL);
919         return 0;
920 }
921
922 #ifdef CONFIG_PM
923 static int tegra_wdt_suspend(struct platform_device *pdev, pm_message_t state)
924 {
925         struct tegra_wdt *wdt = platform_get_drvdata(pdev);
926
927         tegra_wdt_disable(wdt);
928         return 0;
929 }
930
931 static int tegra_wdt_resume(struct platform_device *pdev)
932 {
933         struct tegra_wdt *wdt = platform_get_drvdata(pdev);
934
935         if (wdt->status & WDT_ENABLED)
936                 tegra_wdt_enable(wdt);
937
938 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
939         /* Enable interrupt for WDT3 heartbeat watchdog */
940         if (wdt->status & WDT_ENABLED_AT_PROBE) {
941                 u32 val = 0;
942                 val = readl(wdt->wdt_source + WDT_CFG);
943                 val |= WDT_CFG_INT_EN;
944                 writel(val, wdt->wdt_source + WDT_CFG);
945
946 #if defined(CONFIG_TRUSTED_LITTLE_KERNEL) && \
947         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
948                 val = readl(wdt->wdt_avp_source + WDT_CFG);
949                 val |= WDT_CFG_INT_EN;
950                 writel(val, wdt->wdt_avp_source + WDT_CFG);
951 #endif
952
953 #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \
954         defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
955                 val = readl(wdt->wdt_avp_source + WDT_CFG);
956                 val |= WDT_CFG_INT_EN;
957                 writel(val, wdt->wdt_avp_source + WDT_CFG);
958 #endif
959
960                 pr_info("WDT heartbeat enabled on probe\n");
961         }
962 #endif
963         return 0;
964 }
965 #endif
966
967 static struct platform_driver tegra_wdt_driver = {
968         .probe          = tegra_wdt_probe,
969         .remove         = tegra_wdt_remove,
970 #ifdef CONFIG_PM
971         .suspend        = tegra_wdt_suspend,
972         .resume         = tegra_wdt_resume,
973 #endif
974         .driver         = {
975                 .owner  = THIS_MODULE,
976                 .name   = "tegra_wdt",
977         },
978 };
979
980 static int __init tegra_wdt_init(void)
981 {
982         return platform_driver_register(&tegra_wdt_driver);
983 }
984
985 static void __exit tegra_wdt_exit(void)
986 {
987         platform_driver_unregister(&tegra_wdt_driver);
988 }
989
990 module_init(tegra_wdt_init);
991 module_exit(tegra_wdt_exit);
992
993 MODULE_AUTHOR("NVIDIA Corporation");
994 MODULE_DESCRIPTION("Tegra Watchdog Driver");
995
996 module_param(heartbeat, int, 0);
997 MODULE_PARM_DESC(heartbeat,
998                  "Watchdog heartbeat period in seconds");
999
1000 MODULE_LICENSE("GPL");
1001 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
1002 MODULE_ALIAS("platform:tegra_wdt");