ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / nvdumper.c
1 /*
2  * arch/arm/mach-tegra/nvdumper.c
3  *
4  * Copyright (C) 2011 NVIDIA Corporation
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/errno.h>
18 #include <linux/init.h>
19 #include <linux/io.h>
20 #include <linux/module.h>
21 #include <linux/reboot.h>
22 #include "board.h"
23
24 #define NVDUMPER_CLEAN 0xf000caf3U
25 #define NVDUMPER_DIRTY 0xdeadbeefU
26
27 static uint32_t *nvdumper_ptr;
28
29 static int get_dirty_state(void)
30 {
31         uint32_t val;
32
33         val = ioread32(nvdumper_ptr);
34         if (val == NVDUMPER_DIRTY)
35                 return 1;
36         else if (val == NVDUMPER_CLEAN)
37                 return 0;
38         else
39                 return -1;
40 }
41
42 static void set_dirty_state(int dirty)
43 {
44         if (dirty)
45                 iowrite32(NVDUMPER_DIRTY, nvdumper_ptr);
46         else
47                 iowrite32(NVDUMPER_CLEAN, nvdumper_ptr);
48 }
49
50 static int nvdumper_reboot_cb(struct notifier_block *nb,
51                 unsigned long event, void *unused)
52 {
53         printk(KERN_INFO "nvdumper: rebooting cleanly.\n");
54         set_dirty_state(0);
55         return NOTIFY_DONE;
56 }
57
58 struct notifier_block nvdumper_reboot_notifier = {
59         .notifier_call = nvdumper_reboot_cb,
60 };
61
62 static int __init nvdumper_init(void)
63 {
64         int ret, dirty;
65
66         if (!nvdumper_reserved) {
67                 printk(KERN_INFO "nvdumper: not configured\n");
68                 return -ENOTSUPP;
69         }
70         nvdumper_ptr = ioremap_nocache(nvdumper_reserved,
71                         NVDUMPER_RESERVED_SIZE);
72         if (!nvdumper_ptr) {
73                 printk(KERN_INFO "nvdumper: failed to ioremap memory "
74                         "at 0x%08lx\n", nvdumper_reserved);
75                 return -EIO;
76         }
77         ret = register_reboot_notifier(&nvdumper_reboot_notifier);
78         if (ret)
79                 return ret;
80         dirty = get_dirty_state();
81         switch (dirty) {
82         case 0:
83                 printk(KERN_INFO "nvdumper: last reboot was clean\n");
84                 break;
85         case 1:
86                 printk(KERN_INFO "nvdumper: last reboot was dirty\n");
87                 break;
88         default:
89                 printk(KERN_INFO "nvdumper: last reboot was unknown\n");
90                 break;
91         }
92         set_dirty_state(1);
93         return 0;
94 }
95
96 static void __exit nvdumper_exit(void)
97 {
98         unregister_reboot_notifier(&nvdumper_reboot_notifier);
99         set_dirty_state(0);
100         iounmap(nvdumper_ptr);
101 }
102
103 module_init(nvdumper_init);
104 module_exit(nvdumper_exit);
105
106 MODULE_LICENSE("GPL");