blob: 18b73341fafbc4082799cb55785529e36bd41e00 [file] [log] [blame]
Ankur Nandwanie258cf02011-08-19 10:16:38 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/reboot.h>
16#include <linux/workqueue.h>
17#include <linux/io.h>
18#include <linux/delay.h>
19#include <linux/module.h>
20#include <mach/irqs.h>
21#include <mach/scm.h>
22#include <mach/subsystem_restart.h>
23#include <mach/subsystem_notif.h>
Sameer Thalappil74743382011-11-10 16:38:58 -080024#include <mach/peripheral-loader.h>
Ankur Nandwanie258cf02011-08-19 10:16:38 -070025#include "smd_private.h"
26#include "ramdump.h"
27
28#define MODULE_NAME "wcnss_8960"
29
30static void riva_smsm_cb_fn(struct work_struct *);
31static DECLARE_WORK(riva_smsm_cb_work, riva_smsm_cb_fn);
32
33static void riva_fatal_fn(struct work_struct *);
34static DECLARE_WORK(riva_fatal_work, riva_fatal_fn);
35
36static void *riva_ramdump_dev;
37static int riva_crash;
38static int ss_restart_inprogress;
Sameer Thalappil74743382011-11-10 16:38:58 -080039static int enable_riva_ssr;
Ankur Nandwanie258cf02011-08-19 10:16:38 -070040
41static void riva_smsm_cb_fn(struct work_struct *work)
42{
Sameer Thalappil74743382011-11-10 16:38:58 -080043 if (!enable_riva_ssr)
44 panic(MODULE_NAME ": SMSM reset request received from Riva");
45 else
46 subsystem_restart("riva");
Ankur Nandwanie258cf02011-08-19 10:16:38 -070047}
48
49static void smsm_state_cb_hdlr(void *data, uint32_t old_state,
50 uint32_t new_state)
51{
52 riva_crash = true;
53 pr_err("%s: smsm state changed to smsm reset\n", MODULE_NAME);
54
55 if (ss_restart_inprogress) {
56 pr_err("%s: Ignoring smsm reset req, restart in progress\n",
57 MODULE_NAME);
58 return;
59 }
60 if (new_state & SMSM_RESET)
61 schedule_work(&riva_smsm_cb_work);
62}
63
64static void riva_fatal_fn(struct work_struct *work)
65{
Ankur Nandwanie258cf02011-08-19 10:16:38 -070066 if (!ss_restart_inprogress)
Sameer Thalappil1806ae12011-10-20 12:45:41 -070067 panic(MODULE_NAME ": Watchdog bite received from Riva");
Ankur Nandwanie258cf02011-08-19 10:16:38 -070068}
69
Ankur Nandwanie258cf02011-08-19 10:16:38 -070070/* SMSM reset Riva */
71static void smsm_riva_reset(void)
72{
73 /* per SS reset request bit is not available now,
74 * all SS host modules are setting this bit
75 * This is still under discussion*/
76 smsm_change_state(SMSM_APPS_STATE, SMSM_RESET, SMSM_RESET);
77}
78
79/* Subsystem handlers */
80static int riva_shutdown(const struct subsys_data *subsys)
81{
Sameer Thalappil74743382011-11-10 16:38:58 -080082 pil_force_shutdown("wcnss");
Ankur Nandwanie258cf02011-08-19 10:16:38 -070083 return 0;
84}
85
86static int riva_powerup(const struct subsys_data *subsys)
87{
Sameer Thalappil74743382011-11-10 16:38:58 -080088 pil_force_boot("wcnss");
Ankur Nandwanie258cf02011-08-19 10:16:38 -070089 return 0;
90}
91
92/* RAM segments for Riva SS;
93 * We don't specify the full 5MB allocated for Riva. Only 3MB is specified */
94static struct ramdump_segment riva_segments[] = {{0x8f200000,
95 0x8f500000 - 0x8f200000} };
96
97static int riva_ramdump(int enable, const struct subsys_data *subsys)
98{
99 pr_debug("%s: enable[%d]\n", MODULE_NAME, enable);
100 if (enable)
101 return do_ramdump(riva_ramdump_dev,
102 riva_segments,
103 ARRAY_SIZE(riva_segments));
104 else
105 return 0;
106}
107
108/* Riva crash handler */
109static void riva_crash_shutdown(const struct subsys_data *subsys)
110{
111 ss_restart_inprogress = true;
112
113 pr_err("%s: crash shutdown : %d\n", MODULE_NAME, riva_crash);
114 if (riva_crash != true)
115 smsm_riva_reset();
116}
117
118static struct subsys_data riva_8960 = {
119 .name = "riva",
120 .shutdown = riva_shutdown,
121 .powerup = riva_powerup,
122 .ramdump = riva_ramdump,
123 .crash_shutdown = riva_crash_shutdown
124};
125
Sameer Thalappil74743382011-11-10 16:38:58 -0800126static int enable_riva_ssr_set(const char *val, struct kernel_param *kp)
127{
128 int ret;
129
130 ret = param_set_int(val, kp);
131 if (ret)
132 return ret;
133
134 if (enable_riva_ssr)
135 pr_info(MODULE_NAME ": Subsystem restart activated for riva.\n");
136
137 return 0;
138}
139
140module_param_call(enable_riva_ssr, enable_riva_ssr_set, param_get_int,
141 &enable_riva_ssr, S_IRUGO | S_IWUSR);
142
Ankur Nandwanie258cf02011-08-19 10:16:38 -0700143static int __init riva_restart_init(void)
144{
145 return ssr_register_subsystem(&riva_8960);
146}
147
148static int __init riva_ssr_module_init(void)
149{
150 int ret;
151
152 ret = smsm_state_cb_register(SMSM_WCNSS_STATE, SMSM_RESET,
153 smsm_state_cb_hdlr, 0);
154 if (ret < 0) {
155 pr_err("%s: Unable to register smsm callback for Riva Reset!"
156 " (%d)\n", MODULE_NAME, ret);
157 goto out;
158 }
Ankur Nandwanie258cf02011-08-19 10:16:38 -0700159 ret = riva_restart_init();
160 if (ret < 0) {
161 pr_err("%s: Unable to register with ssr. (%d)\n",
162 MODULE_NAME, ret);
163 goto out;
164 }
165 riva_ramdump_dev = create_ramdump_device("riva");
166 if (!riva_ramdump_dev) {
167 pr_err("%s: Unable to create ramdump device.\n",
168 MODULE_NAME);
169 ret = -ENOMEM;
170 goto out;
171 }
172 pr_info("%s: module initialized\n", MODULE_NAME);
173out:
174 return ret;
175}
176
177static void __exit riva_ssr_module_exit(void)
178{
179 free_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ, NULL);
180}
181
182module_init(riva_ssr_module_init);
183module_exit(riva_ssr_module_exit);
184
185MODULE_LICENSE("GPL v2");