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