blob: 2ef5c61f82cd805fc3b6895ef70ba2054e42b305 [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>
24#include "smd_private.h"
25#include "ramdump.h"
26
27#define MODULE_NAME "wcnss_8960"
28
29static void riva_smsm_cb_fn(struct work_struct *);
30static DECLARE_WORK(riva_smsm_cb_work, riva_smsm_cb_fn);
31
32static void riva_fatal_fn(struct work_struct *);
33static DECLARE_WORK(riva_fatal_work, riva_fatal_fn);
34
35static void *riva_ramdump_dev;
36static int riva_crash;
37static int ss_restart_inprogress;
38
39static void riva_smsm_cb_fn(struct work_struct *work)
40{
Sameer Thalappil1806ae12011-10-20 12:45:41 -070041 panic(MODULE_NAME ": SMSM reset request received from Riva");
Ankur Nandwanie258cf02011-08-19 10:16:38 -070042}
43
44static void smsm_state_cb_hdlr(void *data, uint32_t old_state,
45 uint32_t new_state)
46{
47 riva_crash = true;
48 pr_err("%s: smsm state changed to smsm reset\n", MODULE_NAME);
49
50 if (ss_restart_inprogress) {
51 pr_err("%s: Ignoring smsm reset req, restart in progress\n",
52 MODULE_NAME);
53 return;
54 }
55 if (new_state & SMSM_RESET)
56 schedule_work(&riva_smsm_cb_work);
57}
58
59static void riva_fatal_fn(struct work_struct *work)
60{
Ankur Nandwanie258cf02011-08-19 10:16:38 -070061 if (!ss_restart_inprogress)
Sameer Thalappil1806ae12011-10-20 12:45:41 -070062 panic(MODULE_NAME ": Watchdog bite received from Riva");
Ankur Nandwanie258cf02011-08-19 10:16:38 -070063}
64
Ankur Nandwanie258cf02011-08-19 10:16:38 -070065/* SMSM reset Riva */
66static void smsm_riva_reset(void)
67{
68 /* per SS reset request bit is not available now,
69 * all SS host modules are setting this bit
70 * This is still under discussion*/
71 smsm_change_state(SMSM_APPS_STATE, SMSM_RESET, SMSM_RESET);
72}
73
74/* Subsystem handlers */
75static int riva_shutdown(const struct subsys_data *subsys)
76{
77 /* TODO for phase 3 */
78 return 0;
79}
80
81static int riva_powerup(const struct subsys_data *subsys)
82{
83 /* TODO for phase 3 */
84 return 0;
85}
86
87/* RAM segments for Riva SS;
88 * We don't specify the full 5MB allocated for Riva. Only 3MB is specified */
89static struct ramdump_segment riva_segments[] = {{0x8f200000,
90 0x8f500000 - 0x8f200000} };
91
92static int riva_ramdump(int enable, const struct subsys_data *subsys)
93{
94 pr_debug("%s: enable[%d]\n", MODULE_NAME, enable);
95 if (enable)
96 return do_ramdump(riva_ramdump_dev,
97 riva_segments,
98 ARRAY_SIZE(riva_segments));
99 else
100 return 0;
101}
102
103/* Riva crash handler */
104static void riva_crash_shutdown(const struct subsys_data *subsys)
105{
106 ss_restart_inprogress = true;
107
108 pr_err("%s: crash shutdown : %d\n", MODULE_NAME, riva_crash);
109 if (riva_crash != true)
110 smsm_riva_reset();
111}
112
113static struct subsys_data riva_8960 = {
114 .name = "riva",
115 .shutdown = riva_shutdown,
116 .powerup = riva_powerup,
117 .ramdump = riva_ramdump,
118 .crash_shutdown = riva_crash_shutdown
119};
120
121static int __init riva_restart_init(void)
122{
123 return ssr_register_subsystem(&riva_8960);
124}
125
126static int __init riva_ssr_module_init(void)
127{
128 int ret;
129
130 ret = smsm_state_cb_register(SMSM_WCNSS_STATE, SMSM_RESET,
131 smsm_state_cb_hdlr, 0);
132 if (ret < 0) {
133 pr_err("%s: Unable to register smsm callback for Riva Reset!"
134 " (%d)\n", MODULE_NAME, ret);
135 goto out;
136 }
Ankur Nandwanie258cf02011-08-19 10:16:38 -0700137 ret = riva_restart_init();
138 if (ret < 0) {
139 pr_err("%s: Unable to register with ssr. (%d)\n",
140 MODULE_NAME, ret);
141 goto out;
142 }
143 riva_ramdump_dev = create_ramdump_device("riva");
144 if (!riva_ramdump_dev) {
145 pr_err("%s: Unable to create ramdump device.\n",
146 MODULE_NAME);
147 ret = -ENOMEM;
148 goto out;
149 }
150 pr_info("%s: module initialized\n", MODULE_NAME);
151out:
152 return ret;
153}
154
155static void __exit riva_ssr_module_exit(void)
156{
157 free_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ, NULL);
158}
159
160module_init(riva_ssr_module_init);
161module_exit(riva_ssr_module_exit);
162
163MODULE_LICENSE("GPL v2");