blob: 55cb604fd215e28ea1f5434c1dfb05ff6364dba1 [file] [log] [blame]
Kyle Yanc836d052017-01-05 15:04:34 -08001/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
Kyle Yane45fa022016-08-29 11:40:26 -07002 *
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#define pr_fmt(fmt) "subsys-restart: %s(): " fmt, __func__
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/uaccess.h>
18#include <linux/module.h>
19#include <linux/fs.h>
20#include <linux/delay.h>
21#include <linux/list.h>
22#include <linux/io.h>
23#include <linux/kthread.h>
24#include <linux/time.h>
25#include <linux/suspend.h>
26#include <linux/mutex.h>
27#include <linux/slab.h>
28#include <linux/spinlock.h>
29#include <linux/device.h>
30#include <linux/idr.h>
Kyle Yane45fa022016-08-29 11:40:26 -070031#include <linux/interrupt.h>
32#include <linux/of_gpio.h>
33#include <linux/cdev.h>
34#include <linux/platform_device.h>
35#include <soc/qcom/subsystem_restart.h>
36#include <soc/qcom/subsystem_notif.h>
37#include <soc/qcom/sysmon.h>
Gaurav Kohli2da45012017-05-08 15:21:43 +053038#include <trace/events/trace_msm_pil_event.h>
Kyle Yane45fa022016-08-29 11:40:26 -070039
40#include <asm/current.h>
41
42#include "peripheral-loader.h"
43
44#define DISABLE_SSR 0x9889deed
45/* If set to 0x9889deed, call to subsystem_restart_dev() returns immediately */
46static uint disable_restart_work;
47module_param(disable_restart_work, uint, 0644);
48
49static int enable_debug;
50module_param(enable_debug, int, 0644);
51
52/* The maximum shutdown timeout is the product of MAX_LOOPS and DELAY_MS. */
53#define SHUTDOWN_ACK_MAX_LOOPS 100
54#define SHUTDOWN_ACK_DELAY_MS 100
55
56/**
57 * enum p_subsys_state - state of a subsystem (private)
58 * @SUBSYS_NORMAL: subsystem is operating normally
59 * @SUBSYS_CRASHED: subsystem has crashed and hasn't been shutdown
60 * @SUBSYS_RESTARTING: subsystem has been shutdown and is now restarting
61 *
62 * The 'private' side of the subsytem state used to determine where in the
63 * restart process the subsystem is.
64 */
65enum p_subsys_state {
66 SUBSYS_NORMAL,
67 SUBSYS_CRASHED,
68 SUBSYS_RESTARTING,
69};
70
71/**
72 * enum subsys_state - state of a subsystem (public)
73 * @SUBSYS_OFFLINING: subsystem is offlining
74 * @SUBSYS_OFFLINE: subsystem is offline
75 * @SUBSYS_ONLINE: subsystem is online
76 *
77 * The 'public' side of the subsytem state, exposed to userspace.
78 */
79enum subsys_state {
80 SUBSYS_OFFLINING,
81 SUBSYS_OFFLINE,
82 SUBSYS_ONLINE,
83};
84
85static const char * const subsys_states[] = {
86 [SUBSYS_OFFLINING] = "OFFLINING",
87 [SUBSYS_OFFLINE] = "OFFLINE",
88 [SUBSYS_ONLINE] = "ONLINE",
89};
90
91static const char * const restart_levels[] = {
92 [RESET_SOC] = "SYSTEM",
93 [RESET_SUBSYS_COUPLED] = "RELATED",
94};
95
96/**
97 * struct subsys_tracking - track state of a subsystem or restart order
98 * @p_state: private state of subsystem/order
99 * @state: public state of subsystem/order
100 * @s_lock: protects p_state
101 * @lock: protects subsystem/order callbacks and state
102 *
103 * Tracks the state of a subsystem or a set of subsystems (restart order).
104 * Doing this avoids the need to grab each subsystem's lock and update
105 * each subsystems state when restarting an order.
106 */
107struct subsys_tracking {
108 enum p_subsys_state p_state;
109 spinlock_t s_lock;
110 enum subsys_state state;
111 struct mutex lock;
112};
113
114/**
115 * struct subsys_soc_restart_order - subsystem restart order
116 * @subsystem_list: names of subsystems in this restart order
117 * @count: number of subsystems in order
118 * @track: state tracking and locking
119 * @subsys_ptrs: pointers to subsystems in this restart order
120 */
121struct subsys_soc_restart_order {
122 struct device_node **device_ptrs;
123 int count;
124
125 struct subsys_tracking track;
126 struct subsys_device **subsys_ptrs;
127 struct list_head list;
128};
129
130struct restart_log {
131 struct timeval time;
132 struct subsys_device *dev;
133 struct list_head list;
134};
135
136/**
137 * struct subsys_device - subsystem device
138 * @desc: subsystem descriptor
139 * @work: context for subsystem_restart_wq_func() for this device
140 * @ssr_wlock: prevents suspend during subsystem_restart()
141 * @wlname: name of wakeup source
142 * @device_restart_work: work struct for device restart
143 * @track: state tracking and locking
144 * @notify: subsys notify handle
145 * @dev: device
146 * @owner: module that provides @desc
147 * @count: reference count of subsystem_get()/subsystem_put()
148 * @id: ida
149 * @restart_level: restart level (0 - panic, 1 - related, 2 - independent, etc.)
150 * @restart_order: order of other devices this devices restarts with
151 * @crash_count: number of times the device has crashed
Kyle Yane45fa022016-08-29 11:40:26 -0700152 * @do_ramdump_on_put: ramdump on subsystem_put() if true
153 * @err_ready: completion variable to record error ready from subsystem
154 * @crashed: indicates if subsystem has crashed
155 * @notif_state: current state of subsystem in terms of subsys notifications
156 */
157struct subsys_device {
158 struct subsys_desc *desc;
159 struct work_struct work;
160 struct wakeup_source ssr_wlock;
161 char wlname[64];
162 struct work_struct device_restart_work;
163 struct subsys_tracking track;
164
165 void *notify;
166 struct device dev;
167 struct module *owner;
168 int count;
169 int id;
170 int restart_level;
171 int crash_count;
172 struct subsys_soc_restart_order *restart_order;
Kyle Yane45fa022016-08-29 11:40:26 -0700173 bool do_ramdump_on_put;
174 struct cdev char_dev;
175 dev_t dev_no;
176 struct completion err_ready;
Satya Durga Srinivasu Prabhala30af7d02016-12-15 13:33:39 -0800177 enum crash_status crashed;
Kyle Yane45fa022016-08-29 11:40:26 -0700178 int notif_state;
179 struct list_head list;
180};
181
182static struct subsys_device *to_subsys(struct device *d)
183{
184 return container_of(d, struct subsys_device, dev);
185}
186
187void complete_err_ready(struct subsys_device *subsys)
188{
189 complete(&subsys->err_ready);
190}
191
192static struct subsys_tracking *subsys_get_track(struct subsys_device *subsys)
193{
194 struct subsys_soc_restart_order *order = subsys->restart_order;
195
196 if (order)
197 return &order->track;
198 else
199 return &subsys->track;
200}
201
202static ssize_t name_show(struct device *dev, struct device_attribute *attr,
203 char *buf)
204{
205 return snprintf(buf, PAGE_SIZE, "%s\n", to_subsys(dev)->desc->name);
206}
207
208static ssize_t state_show(struct device *dev, struct device_attribute *attr,
209 char *buf)
210{
211 enum subsys_state state = to_subsys(dev)->track.state;
212
213 return snprintf(buf, PAGE_SIZE, "%s\n", subsys_states[state]);
214}
215
216static ssize_t crash_count_show(struct device *dev,
217 struct device_attribute *attr, char *buf)
218{
219 return snprintf(buf, PAGE_SIZE, "%d\n", to_subsys(dev)->crash_count);
220}
221
222static ssize_t
223restart_level_show(struct device *dev, struct device_attribute *attr, char *buf)
224{
225 int level = to_subsys(dev)->restart_level;
226
227 return snprintf(buf, PAGE_SIZE, "%s\n", restart_levels[level]);
228}
229
230static ssize_t restart_level_store(struct device *dev,
231 struct device_attribute *attr, const char *buf, size_t count)
232{
233 struct subsys_device *subsys = to_subsys(dev);
234 const char *p;
235 int i, orig_count = count;
236
237 p = memchr(buf, '\n', count);
238 if (p)
239 count = p - buf;
240
241 for (i = 0; i < ARRAY_SIZE(restart_levels); i++)
242 if (!strncasecmp(buf, restart_levels[i], count)) {
243 subsys->restart_level = i;
244 return orig_count;
245 }
246 return -EPERM;
247}
248
249static ssize_t firmware_name_show(struct device *dev,
250 struct device_attribute *attr, char *buf)
251{
252 return snprintf(buf, PAGE_SIZE, "%s\n", to_subsys(dev)->desc->fw_name);
253}
254
255static ssize_t firmware_name_store(struct device *dev,
256 struct device_attribute *attr, const char *buf, size_t count)
257{
258 struct subsys_device *subsys = to_subsys(dev);
259 struct subsys_tracking *track = subsys_get_track(subsys);
260 const char *p;
261 int orig_count = count;
262
263 p = memchr(buf, '\n', count);
264 if (p)
265 count = p - buf;
266
267 pr_info("Changing subsys fw_name to %s\n", buf);
268 mutex_lock(&track->lock);
269 strlcpy(subsys->desc->fw_name, buf,
270 min(count + 1, sizeof(subsys->desc->fw_name)));
271 mutex_unlock(&track->lock);
272 return orig_count;
273}
274
275static ssize_t system_debug_show(struct device *dev,
276 struct device_attribute *attr, char *buf)
277{
278 struct subsys_device *subsys = to_subsys(dev);
279 char p[6] = "set";
280
281 if (!subsys->desc->system_debug)
282 strlcpy(p, "reset", sizeof(p));
283
284 return snprintf(buf, PAGE_SIZE, "%s\n", p);
285}
286
287static ssize_t system_debug_store(struct device *dev,
288 struct device_attribute *attr, const char *buf,
289 size_t count)
290{
291 struct subsys_device *subsys = to_subsys(dev);
292 const char *p;
293 int orig_count = count;
294
295 p = memchr(buf, '\n', count);
296 if (p)
297 count = p - buf;
298
299 if (!strncasecmp(buf, "set", count))
300 subsys->desc->system_debug = true;
301 else if (!strncasecmp(buf, "reset", count))
302 subsys->desc->system_debug = false;
303 else
304 return -EPERM;
305 return orig_count;
306}
307
308int subsys_get_restart_level(struct subsys_device *dev)
309{
310 return dev->restart_level;
311}
312EXPORT_SYMBOL(subsys_get_restart_level);
313
314static void subsys_set_state(struct subsys_device *subsys,
315 enum subsys_state state)
316{
317 unsigned long flags;
318
319 spin_lock_irqsave(&subsys->track.s_lock, flags);
320 if (subsys->track.state != state) {
321 subsys->track.state = state;
322 spin_unlock_irqrestore(&subsys->track.s_lock, flags);
323 sysfs_notify(&subsys->dev.kobj, NULL, "state");
324 return;
325 }
326 spin_unlock_irqrestore(&subsys->track.s_lock, flags);
327}
328
329/**
330 * subsytem_default_online() - Mark a subsystem as online by default
331 * @dev: subsystem to mark as online
332 *
333 * Marks a subsystem as "online" without increasing the reference count
334 * on the subsystem. This is typically used by subsystems that are already
335 * online when the kernel boots up.
336 */
337void subsys_default_online(struct subsys_device *dev)
338{
339 subsys_set_state(dev, SUBSYS_ONLINE);
340}
341EXPORT_SYMBOL(subsys_default_online);
342
343static struct device_attribute subsys_attrs[] = {
344 __ATTR_RO(name),
345 __ATTR_RO(state),
346 __ATTR_RO(crash_count),
347 __ATTR(restart_level, 0644, restart_level_show, restart_level_store),
348 __ATTR(firmware_name, 0644, firmware_name_show, firmware_name_store),
349 __ATTR(system_debug, 0644, system_debug_show, system_debug_store),
350 __ATTR_NULL,
351};
352
Satya Durga Srinivasu Prabhalac6c96c62017-04-17 10:41:24 -0700353struct bus_type subsys_bus_type = {
Kyle Yane45fa022016-08-29 11:40:26 -0700354 .name = "msm_subsys",
355 .dev_attrs = subsys_attrs,
356};
Satya Durga Srinivasu Prabhalac6c96c62017-04-17 10:41:24 -0700357EXPORT_SYMBOL(subsys_bus_type);
Kyle Yane45fa022016-08-29 11:40:26 -0700358
359static DEFINE_IDA(subsys_ida);
360
361static int enable_ramdumps;
362module_param(enable_ramdumps, int, 0644);
363
364static int enable_mini_ramdumps;
365module_param(enable_mini_ramdumps, int, 0644);
366
367struct workqueue_struct *ssr_wq;
368static struct class *char_class;
369
370static LIST_HEAD(restart_log_list);
371static LIST_HEAD(subsys_list);
372static LIST_HEAD(ssr_order_list);
373static DEFINE_MUTEX(soc_order_reg_lock);
374static DEFINE_MUTEX(restart_log_mutex);
375static DEFINE_MUTEX(subsys_list_lock);
376static DEFINE_MUTEX(char_device_lock);
377static DEFINE_MUTEX(ssr_order_mutex);
378
379static struct subsys_soc_restart_order *
380update_restart_order(struct subsys_device *dev)
381{
382 int i;
383 struct subsys_soc_restart_order *order;
384 struct device_node *device = dev->desc->dev->of_node;
385
386 mutex_lock(&soc_order_reg_lock);
387 list_for_each_entry(order, &ssr_order_list, list) {
388 for (i = 0; i < order->count; i++) {
389 if (order->device_ptrs[i] == device) {
390 order->subsys_ptrs[i] = dev;
391 goto found;
392 }
393 }
394 }
395 order = NULL;
396found:
397 mutex_unlock(&soc_order_reg_lock);
398
399 return order;
400}
401
402static int max_restarts;
403module_param(max_restarts, int, 0644);
404
405static long max_history_time = 3600;
406module_param(max_history_time, long, 0644);
407
408static void do_epoch_check(struct subsys_device *dev)
409{
410 int n = 0;
411 struct timeval *time_first = NULL, *curr_time;
412 struct restart_log *r_log, *temp;
413 static int max_restarts_check;
414 static long max_history_time_check;
415
416 mutex_lock(&restart_log_mutex);
417
418 max_restarts_check = max_restarts;
419 max_history_time_check = max_history_time;
420
421 /* Check if epoch checking is enabled */
422 if (!max_restarts_check)
423 goto out;
424
425 r_log = kmalloc(sizeof(struct restart_log), GFP_KERNEL);
426 if (!r_log)
427 goto out;
428 r_log->dev = dev;
429 do_gettimeofday(&r_log->time);
430 curr_time = &r_log->time;
431 INIT_LIST_HEAD(&r_log->list);
432
433 list_add_tail(&r_log->list, &restart_log_list);
434
435 list_for_each_entry_safe(r_log, temp, &restart_log_list, list) {
436
437 if ((curr_time->tv_sec - r_log->time.tv_sec) >
438 max_history_time_check) {
439
440 pr_debug("Deleted node with restart_time = %ld\n",
441 r_log->time.tv_sec);
442 list_del(&r_log->list);
443 kfree(r_log);
444 continue;
445 }
446 if (!n) {
447 time_first = &r_log->time;
448 pr_debug("Time_first: %ld\n", time_first->tv_sec);
449 }
450 n++;
451 pr_debug("Restart_time: %ld\n", r_log->time.tv_sec);
452 }
453
454 if (time_first && n >= max_restarts_check) {
455 if ((curr_time->tv_sec - time_first->tv_sec) <
456 max_history_time_check)
457 panic("Subsystems have crashed %d times in less than %ld seconds!",
458 max_restarts_check, max_history_time_check);
459 }
460
461out:
462 mutex_unlock(&restart_log_mutex);
463}
464
465static int is_ramdump_enabled(struct subsys_device *dev)
466{
467 if (dev->desc->ramdump_disable_gpio)
468 return !dev->desc->ramdump_disable;
469
470 return enable_ramdumps;
471}
472
473static void send_sysmon_notif(struct subsys_device *dev)
474{
475 struct subsys_device *subsys;
476
477 mutex_lock(&subsys_list_lock);
478 list_for_each_entry(subsys, &subsys_list, list)
479 if ((subsys->notif_state > 0) && (subsys != dev))
480 sysmon_send_event(dev->desc, subsys->desc,
481 subsys->notif_state);
482 mutex_unlock(&subsys_list_lock);
483}
484
Arun KSc992cf62017-03-06 13:21:45 +0530485static int for_each_subsys_device(struct subsys_device **list,
Kyle Yane45fa022016-08-29 11:40:26 -0700486 unsigned int count, void *data,
Arun KSc992cf62017-03-06 13:21:45 +0530487 int (*fn)(struct subsys_device *, void *))
Kyle Yane45fa022016-08-29 11:40:26 -0700488{
Arun KSc992cf62017-03-06 13:21:45 +0530489 int ret;
Kyle Yane45fa022016-08-29 11:40:26 -0700490 while (count--) {
491 struct subsys_device *dev = *list++;
492
493 if (!dev)
494 continue;
Arun KSc992cf62017-03-06 13:21:45 +0530495 ret = fn(dev, data);
496 if (ret)
497 return ret;
Kyle Yane45fa022016-08-29 11:40:26 -0700498 }
Arun KSc992cf62017-03-06 13:21:45 +0530499 return 0;
Kyle Yane45fa022016-08-29 11:40:26 -0700500}
501
502static void notify_each_subsys_device(struct subsys_device **list,
503 unsigned int count,
504 enum subsys_notif_type notif, void *data)
505{
506 struct subsys_device *subsys;
507
508 while (count--) {
509 struct subsys_device *dev = *list++;
510 struct notif_data notif_data;
511 struct platform_device *pdev;
512
513 if (!dev)
514 continue;
515
516 pdev = container_of(dev->desc->dev, struct platform_device,
517 dev);
518 dev->notif_state = notif;
519
520 mutex_lock(&subsys_list_lock);
521 list_for_each_entry(subsys, &subsys_list, list)
522 if (dev != subsys &&
523 subsys->track.state == SUBSYS_ONLINE)
524 sysmon_send_event(subsys->desc, dev->desc,
525 notif);
526 mutex_unlock(&subsys_list_lock);
527
528 if (notif == SUBSYS_AFTER_POWERUP &&
529 dev->track.state == SUBSYS_ONLINE)
530 send_sysmon_notif(dev);
531
532 notif_data.crashed = subsys_get_crash_status(dev);
533 notif_data.enable_ramdump = is_ramdump_enabled(dev);
534 notif_data.enable_mini_ramdumps = enable_mini_ramdumps;
535 notif_data.no_auth = dev->desc->no_auth;
536 notif_data.pdev = pdev;
537
Gaurav Kohli2da45012017-05-08 15:21:43 +0530538 trace_pil_notif("before_send_notif", notif, dev->desc->fw_name);
Kyle Yane45fa022016-08-29 11:40:26 -0700539 subsys_notif_queue_notification(dev->notify, notif,
540 &notif_data);
Gaurav Kohli2da45012017-05-08 15:21:43 +0530541 trace_pil_notif("after_send_notif", notif, dev->desc->fw_name);
Kyle Yane45fa022016-08-29 11:40:26 -0700542 }
543}
544
545static void enable_all_irqs(struct subsys_device *dev)
546{
547 if (dev->desc->err_ready_irq)
548 enable_irq(dev->desc->err_ready_irq);
549 if (dev->desc->wdog_bite_irq && dev->desc->wdog_bite_handler) {
550 enable_irq(dev->desc->wdog_bite_irq);
551 irq_set_irq_wake(dev->desc->wdog_bite_irq, 1);
552 }
553 if (dev->desc->err_fatal_irq && dev->desc->err_fatal_handler)
554 enable_irq(dev->desc->err_fatal_irq);
555 if (dev->desc->stop_ack_irq && dev->desc->stop_ack_handler)
556 enable_irq(dev->desc->stop_ack_irq);
557 if (dev->desc->generic_irq && dev->desc->generic_handler) {
558 enable_irq(dev->desc->generic_irq);
559 irq_set_irq_wake(dev->desc->generic_irq, 1);
560 }
561}
562
563static void disable_all_irqs(struct subsys_device *dev)
564{
565 if (dev->desc->err_ready_irq)
566 disable_irq(dev->desc->err_ready_irq);
567 if (dev->desc->wdog_bite_irq && dev->desc->wdog_bite_handler) {
568 disable_irq(dev->desc->wdog_bite_irq);
569 irq_set_irq_wake(dev->desc->wdog_bite_irq, 0);
570 }
571 if (dev->desc->err_fatal_irq && dev->desc->err_fatal_handler)
572 disable_irq(dev->desc->err_fatal_irq);
573 if (dev->desc->stop_ack_irq && dev->desc->stop_ack_handler)
574 disable_irq(dev->desc->stop_ack_irq);
575 if (dev->desc->generic_irq && dev->desc->generic_handler) {
576 disable_irq(dev->desc->generic_irq);
577 irq_set_irq_wake(dev->desc->generic_irq, 0);
578 }
579}
580
581static int wait_for_err_ready(struct subsys_device *subsys)
582{
583 int ret;
584
585 /*
586 * If subsys is using generic_irq in which case err_ready_irq will be 0,
587 * don't return.
588 */
589 if ((subsys->desc->generic_irq <= 0 && !subsys->desc->err_ready_irq) ||
590 enable_debug == 1 || is_timeout_disabled())
591 return 0;
592
593 ret = wait_for_completion_timeout(&subsys->err_ready,
594 msecs_to_jiffies(10000));
595 if (!ret) {
596 pr_err("[%s]: Error ready timed out\n", subsys->desc->name);
597 return -ETIMEDOUT;
598 }
599
600 return 0;
601}
602
Arun KSc992cf62017-03-06 13:21:45 +0530603static int subsystem_shutdown(struct subsys_device *dev, void *data)
Kyle Yane45fa022016-08-29 11:40:26 -0700604{
605 const char *name = dev->desc->name;
Arun KSc992cf62017-03-06 13:21:45 +0530606 int ret;
Kyle Yane45fa022016-08-29 11:40:26 -0700607
Satya Durga Srinivasu Prabhala2d3f4802016-12-16 10:01:58 -0800608 pr_info("[%s:%d]: Shutting down %s\n",
609 current->comm, current->pid, name);
Arun KSc992cf62017-03-06 13:21:45 +0530610 ret = dev->desc->shutdown(dev->desc, true);
611 if (ret < 0) {
612 if (!dev->desc->ignore_ssr_failure) {
613 panic("subsys-restart: [%s:%d]: Failed to shutdown %s!",
614 current->comm, current->pid, name);
615 } else {
616 pr_err("Shutdown failure on %s\n", name);
617 return ret;
618 }
619 }
Kyle Yane45fa022016-08-29 11:40:26 -0700620 dev->crash_count++;
621 subsys_set_state(dev, SUBSYS_OFFLINE);
622 disable_all_irqs(dev);
Arun KSc992cf62017-03-06 13:21:45 +0530623
624 return 0;
Kyle Yane45fa022016-08-29 11:40:26 -0700625}
626
Arun KSc992cf62017-03-06 13:21:45 +0530627static int subsystem_ramdump(struct subsys_device *dev, void *data)
Kyle Yane45fa022016-08-29 11:40:26 -0700628{
629 const char *name = dev->desc->name;
630
631 if (dev->desc->ramdump)
632 if (dev->desc->ramdump(is_ramdump_enabled(dev), dev->desc) < 0)
Satya Durga Srinivasu Prabhala2d3f4802016-12-16 10:01:58 -0800633 pr_warn("%s[%s:%d]: Ramdump failed.\n",
634 name, current->comm, current->pid);
Kyle Yane45fa022016-08-29 11:40:26 -0700635 dev->do_ramdump_on_put = false;
Arun KSc992cf62017-03-06 13:21:45 +0530636 return 0;
Kyle Yane45fa022016-08-29 11:40:26 -0700637}
638
Arun KSc992cf62017-03-06 13:21:45 +0530639static int subsystem_free_memory(struct subsys_device *dev, void *data)
Kyle Yane45fa022016-08-29 11:40:26 -0700640{
641 if (dev->desc->free_memory)
642 dev->desc->free_memory(dev->desc);
Arun KSc992cf62017-03-06 13:21:45 +0530643 return 0;
Kyle Yane45fa022016-08-29 11:40:26 -0700644}
645
Arun KSc992cf62017-03-06 13:21:45 +0530646static int subsystem_powerup(struct subsys_device *dev, void *data)
Kyle Yane45fa022016-08-29 11:40:26 -0700647{
648 const char *name = dev->desc->name;
649 int ret;
650
Satya Durga Srinivasu Prabhala2d3f4802016-12-16 10:01:58 -0800651 pr_info("[%s:%d]: Powering up %s\n", current->comm, current->pid, name);
Kyle Yane45fa022016-08-29 11:40:26 -0700652 init_completion(&dev->err_ready);
653
Arun KSc992cf62017-03-06 13:21:45 +0530654 ret = dev->desc->powerup(dev->desc);
655 if (ret < 0) {
Kyle Yane45fa022016-08-29 11:40:26 -0700656 notify_each_subsys_device(&dev, 1, SUBSYS_POWERUP_FAILURE,
657 NULL);
Arun KSc992cf62017-03-06 13:21:45 +0530658 if (!dev->desc->ignore_ssr_failure) {
659 panic("[%s:%d]: Powerup error: %s!",
660 current->comm, current->pid, name);
661 } else {
662 pr_err("Powerup failure on %s\n", name);
663 return ret;
664 }
Kyle Yane45fa022016-08-29 11:40:26 -0700665 }
666 enable_all_irqs(dev);
667
668 ret = wait_for_err_ready(dev);
669 if (ret) {
670 notify_each_subsys_device(&dev, 1, SUBSYS_POWERUP_FAILURE,
671 NULL);
Arun KSc992cf62017-03-06 13:21:45 +0530672 if (!dev->desc->ignore_ssr_failure)
673 panic("[%s:%d]: Timed out waiting for error ready: %s!",
674 current->comm, current->pid, name);
675 else
676 return ret;
Kyle Yane45fa022016-08-29 11:40:26 -0700677 }
678 subsys_set_state(dev, SUBSYS_ONLINE);
Satya Durga Srinivasu Prabhala30af7d02016-12-15 13:33:39 -0800679 subsys_set_crash_status(dev, CRASH_STATUS_NO_CRASH);
Arun KSc992cf62017-03-06 13:21:45 +0530680
681 return 0;
Kyle Yane45fa022016-08-29 11:40:26 -0700682}
683
684static int __find_subsys(struct device *dev, void *data)
685{
686 struct subsys_device *subsys = to_subsys(dev);
687
688 return !strcmp(subsys->desc->name, data);
689}
690
691static struct subsys_device *find_subsys(const char *str)
692{
693 struct device *dev;
694
695 if (!str)
696 return NULL;
697
698 dev = bus_find_device(&subsys_bus_type, NULL, (void *)str,
699 __find_subsys);
700 return dev ? to_subsys(dev) : NULL;
701}
702
703static int subsys_start(struct subsys_device *subsys)
704{
705 int ret;
706
707 notify_each_subsys_device(&subsys, 1, SUBSYS_BEFORE_POWERUP,
708 NULL);
709
710 init_completion(&subsys->err_ready);
711 ret = subsys->desc->powerup(subsys->desc);
712 if (ret) {
713 notify_each_subsys_device(&subsys, 1, SUBSYS_POWERUP_FAILURE,
714 NULL);
715 return ret;
716 }
717 enable_all_irqs(subsys);
718
719 if (subsys->desc->is_not_loadable) {
720 subsys_set_state(subsys, SUBSYS_ONLINE);
721 return 0;
722 }
723
724 ret = wait_for_err_ready(subsys);
725 if (ret) {
726 /* pil-boot succeeded but we need to shutdown
727 * the device because error ready timed out.
728 */
729 notify_each_subsys_device(&subsys, 1, SUBSYS_POWERUP_FAILURE,
730 NULL);
731 subsys->desc->shutdown(subsys->desc, false);
732 disable_all_irqs(subsys);
733 return ret;
734 }
735 subsys_set_state(subsys, SUBSYS_ONLINE);
736
737 notify_each_subsys_device(&subsys, 1, SUBSYS_AFTER_POWERUP,
738 NULL);
739 return ret;
740}
741
742static void subsys_stop(struct subsys_device *subsys)
743{
744 const char *name = subsys->desc->name;
745
746 notify_each_subsys_device(&subsys, 1, SUBSYS_BEFORE_SHUTDOWN, NULL);
747 if (!of_property_read_bool(subsys->desc->dev->of_node,
748 "qcom,pil-force-shutdown")) {
749 subsys_set_state(subsys, SUBSYS_OFFLINING);
750 subsys->desc->sysmon_shutdown_ret =
751 sysmon_send_shutdown(subsys->desc);
752 if (subsys->desc->sysmon_shutdown_ret)
753 pr_debug("Graceful shutdown failed for %s\n", name);
754 }
755
756 subsys->desc->shutdown(subsys->desc, false);
757 subsys_set_state(subsys, SUBSYS_OFFLINE);
758 disable_all_irqs(subsys);
759 notify_each_subsys_device(&subsys, 1, SUBSYS_AFTER_SHUTDOWN, NULL);
760}
761
762int subsystem_set_fwname(const char *name, const char *fw_name)
763{
764 struct subsys_device *subsys;
765
766 if (!name)
767 return -EINVAL;
768
769 if (!fw_name)
770 return -EINVAL;
771
772 subsys = find_subsys(name);
773 if (!subsys)
774 return -EINVAL;
775
776 pr_debug("Changing subsys [%s] fw_name to [%s]\n", name, fw_name);
777 strlcpy(subsys->desc->fw_name, fw_name,
778 sizeof(subsys->desc->fw_name));
779
780 return 0;
781}
782EXPORT_SYMBOL(subsystem_set_fwname);
783
784int wait_for_shutdown_ack(struct subsys_desc *desc)
785{
786 int count;
787 struct subsys_device *dev;
788
789 if (!desc || !desc->shutdown_ack_gpio)
790 return 0;
791
792 dev = find_subsys(desc->name);
793 if (!dev)
794 return 0;
795
796 for (count = SHUTDOWN_ACK_MAX_LOOPS; count > 0; count--) {
797 if (gpio_get_value(desc->shutdown_ack_gpio))
798 return count;
799 else if (subsys_get_crash_status(dev))
800 break;
801 msleep(SHUTDOWN_ACK_DELAY_MS);
802 }
803
804 pr_err("[%s]: Timed out waiting for shutdown ack\n", desc->name);
805 return -ETIMEDOUT;
806}
807EXPORT_SYMBOL(wait_for_shutdown_ack);
808
809void *__subsystem_get(const char *name, const char *fw_name)
810{
811 struct subsys_device *subsys;
812 struct subsys_device *subsys_d;
813 int ret;
814 void *retval;
815 struct subsys_tracking *track;
816
817 if (!name)
818 return NULL;
819
820 subsys = retval = find_subsys(name);
821 if (!subsys)
822 return ERR_PTR(-ENODEV);
823 if (!try_module_get(subsys->owner)) {
824 retval = ERR_PTR(-ENODEV);
825 goto err_module;
826 }
827
828 subsys_d = subsystem_get(subsys->desc->depends_on);
829 if (IS_ERR(subsys_d)) {
830 retval = subsys_d;
831 goto err_depends;
832 }
833
834 track = subsys_get_track(subsys);
835 mutex_lock(&track->lock);
836 if (!subsys->count) {
837 if (fw_name) {
838 pr_info("Changing subsys fw_name to %s\n", fw_name);
839 strlcpy(subsys->desc->fw_name, fw_name,
840 sizeof(subsys->desc->fw_name));
841 }
842 ret = subsys_start(subsys);
843 if (ret) {
844 retval = ERR_PTR(ret);
845 goto err_start;
846 }
847 }
848 subsys->count++;
849 mutex_unlock(&track->lock);
850 return retval;
851err_start:
852 mutex_unlock(&track->lock);
853 subsystem_put(subsys_d);
854err_depends:
855 module_put(subsys->owner);
856err_module:
857 put_device(&subsys->dev);
858 return retval;
859}
860
861/**
862 * subsytem_get() - Boot a subsystem
863 * @name: pointer to a string containing the name of the subsystem to boot
864 *
865 * This function returns a pointer if it succeeds. If an error occurs an
866 * ERR_PTR is returned.
867 *
868 * If this feature is disable, the value %NULL will be returned.
869 */
870void *subsystem_get(const char *name)
871{
872 return __subsystem_get(name, NULL);
873}
874EXPORT_SYMBOL(subsystem_get);
875
876/**
877 * subsystem_get_with_fwname() - Boot a subsystem using the firmware name passed
878 * @name: pointer to a string containing the name of the subsystem to boot
879 * @fw_name: pointer to a string containing the subsystem firmware image name
880 *
881 * This function returns a pointer if it succeeds. If an error occurs an
882 * ERR_PTR is returned.
883 *
884 * If this feature is disable, the value %NULL will be returned.
885 */
886void *subsystem_get_with_fwname(const char *name, const char *fw_name)
887{
888 return __subsystem_get(name, fw_name);
889}
890EXPORT_SYMBOL(subsystem_get_with_fwname);
891
892/**
893 * subsystem_put() - Shutdown a subsystem
894 * @peripheral_handle: pointer from a previous call to subsystem_get()
895 *
896 * This doesn't imply that a subsystem is shutdown until all callers of
897 * subsystem_get() have called subsystem_put().
898 */
899void subsystem_put(void *subsystem)
900{
901 struct subsys_device *subsys_d, *subsys = subsystem;
902 struct subsys_tracking *track;
903
904 if (IS_ERR_OR_NULL(subsys))
905 return;
906
907 track = subsys_get_track(subsys);
908 mutex_lock(&track->lock);
909 if (WARN(!subsys->count, "%s: %s: Reference count mismatch\n",
910 subsys->desc->name, __func__))
911 goto err_out;
912 if (!--subsys->count) {
913 subsys_stop(subsys);
914 if (subsys->do_ramdump_on_put)
915 subsystem_ramdump(subsys, NULL);
916 subsystem_free_memory(subsys, NULL);
917 }
918 mutex_unlock(&track->lock);
919
920 subsys_d = find_subsys(subsys->desc->depends_on);
921 if (subsys_d) {
922 subsystem_put(subsys_d);
923 put_device(&subsys_d->dev);
924 }
925 module_put(subsys->owner);
926 put_device(&subsys->dev);
927 return;
928err_out:
929 mutex_unlock(&track->lock);
930}
931EXPORT_SYMBOL(subsystem_put);
932
933static void subsystem_restart_wq_func(struct work_struct *work)
934{
935 struct subsys_device *dev = container_of(work,
936 struct subsys_device, work);
937 struct subsys_device **list;
938 struct subsys_desc *desc = dev->desc;
939 struct subsys_soc_restart_order *order = dev->restart_order;
940 struct subsys_tracking *track;
941 unsigned int count;
942 unsigned long flags;
Arun KSc992cf62017-03-06 13:21:45 +0530943 int ret;
Kyle Yane45fa022016-08-29 11:40:26 -0700944
945 /*
946 * It's OK to not take the registration lock at this point.
947 * This is because the subsystem list inside the relevant
948 * restart order is not being traversed.
949 */
950 if (order) {
951 list = order->subsys_ptrs;
952 count = order->count;
953 track = &order->track;
954 } else {
955 list = &dev;
956 count = 1;
957 track = &dev->track;
958 }
959
960 /*
961 * If a system reboot/shutdown is under way, ignore subsystem errors.
962 * However, print a message so that we know that a subsystem behaved
963 * unexpectedly here.
964 */
965 if (system_state == SYSTEM_RESTART
966 || system_state == SYSTEM_POWER_OFF) {
967 WARN(1, "SSR aborted: %s, system reboot/shutdown is under way\n",
968 desc->name);
969 return;
970 }
971
972 mutex_lock(&track->lock);
973 do_epoch_check(dev);
974
975 if (dev->track.state == SUBSYS_OFFLINE) {
976 mutex_unlock(&track->lock);
977 WARN(1, "SSR aborted: %s subsystem not online\n", desc->name);
978 return;
979 }
980
981 /*
982 * It's necessary to take the registration lock because the subsystem
983 * list in the SoC restart order will be traversed and it shouldn't be
984 * changed until _this_ restart sequence completes.
985 */
986 mutex_lock(&soc_order_reg_lock);
987
Satya Durga Srinivasu Prabhala2d3f4802016-12-16 10:01:58 -0800988 pr_debug("[%s:%d]: Starting restart sequence for %s\n",
989 current->comm, current->pid, desc->name);
Kyle Yane45fa022016-08-29 11:40:26 -0700990 notify_each_subsys_device(list, count, SUBSYS_BEFORE_SHUTDOWN, NULL);
Arun KSc992cf62017-03-06 13:21:45 +0530991 ret = for_each_subsys_device(list, count, NULL, subsystem_shutdown);
992 if (ret)
993 goto err;
Kyle Yane45fa022016-08-29 11:40:26 -0700994 notify_each_subsys_device(list, count, SUBSYS_AFTER_SHUTDOWN, NULL);
995
996 notify_each_subsys_device(list, count, SUBSYS_RAMDUMP_NOTIFICATION,
997 NULL);
998
999 spin_lock_irqsave(&track->s_lock, flags);
1000 track->p_state = SUBSYS_RESTARTING;
1001 spin_unlock_irqrestore(&track->s_lock, flags);
1002
1003 /* Collect ram dumps for all subsystems in order here */
1004 for_each_subsys_device(list, count, NULL, subsystem_ramdump);
1005
1006 for_each_subsys_device(list, count, NULL, subsystem_free_memory);
1007
1008 notify_each_subsys_device(list, count, SUBSYS_BEFORE_POWERUP, NULL);
Arun KSc992cf62017-03-06 13:21:45 +05301009 ret = for_each_subsys_device(list, count, NULL, subsystem_powerup);
1010 if (ret)
1011 goto err;
Kyle Yane45fa022016-08-29 11:40:26 -07001012 notify_each_subsys_device(list, count, SUBSYS_AFTER_POWERUP, NULL);
1013
Satya Durga Srinivasu Prabhala2d3f4802016-12-16 10:01:58 -08001014 pr_info("[%s:%d]: Restart sequence for %s completed.\n",
1015 current->comm, current->pid, desc->name);
Kyle Yane45fa022016-08-29 11:40:26 -07001016
Arun KSc992cf62017-03-06 13:21:45 +05301017err:
1018 /* Reset subsys count */
1019 if (ret)
1020 dev->count = 0;
1021
Kyle Yane45fa022016-08-29 11:40:26 -07001022 mutex_unlock(&soc_order_reg_lock);
1023 mutex_unlock(&track->lock);
1024
1025 spin_lock_irqsave(&track->s_lock, flags);
1026 track->p_state = SUBSYS_NORMAL;
1027 __pm_relax(&dev->ssr_wlock);
1028 spin_unlock_irqrestore(&track->s_lock, flags);
1029}
1030
1031static void __subsystem_restart_dev(struct subsys_device *dev)
1032{
1033 struct subsys_desc *desc = dev->desc;
1034 const char *name = dev->desc->name;
1035 struct subsys_tracking *track;
1036 unsigned long flags;
1037
1038 pr_debug("Restarting %s [level=%s]!\n", desc->name,
1039 restart_levels[dev->restart_level]);
1040
1041 track = subsys_get_track(dev);
1042 /*
1043 * Allow drivers to call subsystem_restart{_dev}() as many times as
1044 * they want up until the point where the subsystem is shutdown.
1045 */
1046 spin_lock_irqsave(&track->s_lock, flags);
1047 if (track->p_state != SUBSYS_CRASHED &&
1048 dev->track.state == SUBSYS_ONLINE) {
1049 if (track->p_state != SUBSYS_RESTARTING) {
1050 track->p_state = SUBSYS_CRASHED;
1051 __pm_stay_awake(&dev->ssr_wlock);
1052 queue_work(ssr_wq, &dev->work);
1053 } else {
1054 panic("Subsystem %s crashed during SSR!", name);
1055 }
1056 } else
1057 WARN(dev->track.state == SUBSYS_OFFLINE,
1058 "SSR aborted: %s subsystem not online\n", name);
1059 spin_unlock_irqrestore(&track->s_lock, flags);
1060}
1061
1062static void device_restart_work_hdlr(struct work_struct *work)
1063{
1064 struct subsys_device *dev = container_of(work, struct subsys_device,
1065 device_restart_work);
1066
1067 notify_each_subsys_device(&dev, 1, SUBSYS_SOC_RESET, NULL);
1068 /*
1069 * Temporary workaround until ramdump userspace application calls
1070 * sync() and fclose() on attempting the dump.
1071 */
1072 msleep(100);
1073 panic("subsys-restart: Resetting the SoC - %s crashed.",
1074 dev->desc->name);
1075}
1076
1077int subsystem_restart_dev(struct subsys_device *dev)
1078{
1079 const char *name;
1080
1081 if (!get_device(&dev->dev))
1082 return -ENODEV;
1083
1084 if (!try_module_get(dev->owner)) {
1085 put_device(&dev->dev);
1086 return -ENODEV;
1087 }
1088
1089 name = dev->desc->name;
1090
1091 /*
1092 * If a system reboot/shutdown is underway, ignore subsystem errors.
1093 * However, print a message so that we know that a subsystem behaved
1094 * unexpectedly here.
1095 */
1096 if (system_state == SYSTEM_RESTART
1097 || system_state == SYSTEM_POWER_OFF) {
1098 pr_err("%s crashed during a system poweroff/shutdown.\n", name);
1099 return -EBUSY;
1100 }
1101
1102 pr_info("Restart sequence requested for %s, restart_level = %s.\n",
1103 name, restart_levels[dev->restart_level]);
1104
Puja Gupta9b318dd2017-01-16 15:56:27 -08001105 if (disable_restart_work == DISABLE_SSR) {
1106 pr_warn("subsys-restart: Ignoring restart request for %s\n",
1107 name);
Kyle Yane45fa022016-08-29 11:40:26 -07001108 return 0;
1109 }
1110
1111 switch (dev->restart_level) {
1112
1113 case RESET_SUBSYS_COUPLED:
1114 __subsystem_restart_dev(dev);
1115 break;
1116 case RESET_SOC:
1117 __pm_stay_awake(&dev->ssr_wlock);
1118 schedule_work(&dev->device_restart_work);
1119 return 0;
1120 default:
1121 panic("subsys-restart: Unknown restart level!\n");
1122 break;
1123 }
1124 module_put(dev->owner);
1125 put_device(&dev->dev);
1126
1127 return 0;
1128}
1129EXPORT_SYMBOL(subsystem_restart_dev);
1130
1131int subsystem_restart(const char *name)
1132{
1133 int ret;
1134 struct subsys_device *dev = find_subsys(name);
1135
1136 if (!dev)
1137 return -ENODEV;
1138
1139 ret = subsystem_restart_dev(dev);
1140 put_device(&dev->dev);
1141 return ret;
1142}
1143EXPORT_SYMBOL(subsystem_restart);
1144
1145int subsystem_crashed(const char *name)
1146{
1147 struct subsys_device *dev = find_subsys(name);
1148 struct subsys_tracking *track;
1149
1150 if (!dev)
1151 return -ENODEV;
1152
1153 if (!get_device(&dev->dev))
1154 return -ENODEV;
1155
1156 track = subsys_get_track(dev);
1157
1158 mutex_lock(&track->lock);
1159 dev->do_ramdump_on_put = true;
1160 /*
1161 * TODO: Make this work with multiple consumers where one is calling
1162 * subsystem_restart() and another is calling this function. To do
1163 * so would require updating private state, etc.
1164 */
1165 mutex_unlock(&track->lock);
1166
1167 put_device(&dev->dev);
1168 return 0;
1169}
1170EXPORT_SYMBOL(subsystem_crashed);
1171
Satya Durga Srinivasu Prabhala30af7d02016-12-15 13:33:39 -08001172void subsys_set_crash_status(struct subsys_device *dev,
1173 enum crash_status crashed)
Kyle Yane45fa022016-08-29 11:40:26 -07001174{
1175 dev->crashed = crashed;
1176}
1177
Satya Durga Srinivasu Prabhala30af7d02016-12-15 13:33:39 -08001178enum crash_status subsys_get_crash_status(struct subsys_device *dev)
Kyle Yane45fa022016-08-29 11:40:26 -07001179{
1180 return dev->crashed;
1181}
1182
1183static struct subsys_device *desc_to_subsys(struct device *d)
1184{
1185 struct subsys_device *device, *subsys_dev = 0;
1186
1187 mutex_lock(&subsys_list_lock);
1188 list_for_each_entry(device, &subsys_list, list)
1189 if (device->desc->dev == d)
1190 subsys_dev = device;
1191 mutex_unlock(&subsys_list_lock);
1192 return subsys_dev;
1193}
1194
1195void notify_proxy_vote(struct device *device)
1196{
1197 struct subsys_device *dev = desc_to_subsys(device);
1198
1199 if (dev)
1200 notify_each_subsys_device(&dev, 1, SUBSYS_PROXY_VOTE, NULL);
1201}
1202
1203void notify_proxy_unvote(struct device *device)
1204{
1205 struct subsys_device *dev = desc_to_subsys(device);
1206
1207 if (dev)
1208 notify_each_subsys_device(&dev, 1, SUBSYS_PROXY_UNVOTE, NULL);
1209}
1210
Kyle Yane45fa022016-08-29 11:40:26 -07001211static int subsys_device_open(struct inode *inode, struct file *file)
1212{
1213 struct subsys_device *device, *subsys_dev = 0;
1214 void *retval;
1215
1216 mutex_lock(&subsys_list_lock);
1217 list_for_each_entry(device, &subsys_list, list)
1218 if (MINOR(device->dev_no) == iminor(inode))
1219 subsys_dev = device;
1220 mutex_unlock(&subsys_list_lock);
1221
1222 if (!subsys_dev)
1223 return -EINVAL;
1224
1225 retval = subsystem_get_with_fwname(subsys_dev->desc->name,
1226 subsys_dev->desc->fw_name);
1227 if (IS_ERR(retval))
1228 return PTR_ERR(retval);
1229
1230 return 0;
1231}
1232
1233static int subsys_device_close(struct inode *inode, struct file *file)
1234{
1235 struct subsys_device *device, *subsys_dev = 0;
1236
1237 mutex_lock(&subsys_list_lock);
1238 list_for_each_entry(device, &subsys_list, list)
1239 if (MINOR(device->dev_no) == iminor(inode))
1240 subsys_dev = device;
1241 mutex_unlock(&subsys_list_lock);
1242
1243 if (!subsys_dev)
1244 return -EINVAL;
1245
1246 subsystem_put(subsys_dev);
1247 return 0;
1248}
1249
1250static const struct file_operations subsys_device_fops = {
1251 .owner = THIS_MODULE,
1252 .open = subsys_device_open,
1253 .release = subsys_device_close,
1254};
1255
1256static void subsys_device_release(struct device *dev)
1257{
1258 struct subsys_device *subsys = to_subsys(dev);
1259
1260 wakeup_source_trash(&subsys->ssr_wlock);
1261 mutex_destroy(&subsys->track.lock);
1262 ida_simple_remove(&subsys_ida, subsys->id);
1263 kfree(subsys);
1264}
1265static irqreturn_t subsys_err_ready_intr_handler(int irq, void *subsys)
1266{
1267 struct subsys_device *subsys_dev = subsys;
1268
1269 dev_info(subsys_dev->desc->dev,
1270 "Subsystem error monitoring/handling services are up\n");
1271
1272 if (subsys_dev->desc->is_not_loadable)
1273 return IRQ_HANDLED;
1274
1275 complete(&subsys_dev->err_ready);
1276 return IRQ_HANDLED;
1277}
1278
1279static int subsys_char_device_add(struct subsys_device *subsys_dev)
1280{
1281 int ret = 0;
1282 static int major, minor;
1283 dev_t dev_no;
1284
1285 mutex_lock(&char_device_lock);
1286 if (!major) {
1287 ret = alloc_chrdev_region(&dev_no, 0, 4, "subsys");
1288 if (ret < 0) {
1289 pr_err("Failed to alloc subsys_dev region, err %d\n",
1290 ret);
1291 goto fail;
1292 }
1293 major = MAJOR(dev_no);
1294 minor = MINOR(dev_no);
1295 } else
1296 dev_no = MKDEV(major, minor);
1297
1298 if (!device_create(char_class, subsys_dev->desc->dev, dev_no,
1299 NULL, "subsys_%s", subsys_dev->desc->name)) {
1300 pr_err("Failed to create subsys_%s device\n",
1301 subsys_dev->desc->name);
1302 goto fail_unregister_cdev_region;
1303 }
1304
1305 cdev_init(&subsys_dev->char_dev, &subsys_device_fops);
1306 subsys_dev->char_dev.owner = THIS_MODULE;
1307 ret = cdev_add(&subsys_dev->char_dev, dev_no, 1);
1308 if (ret < 0)
1309 goto fail_destroy_device;
1310
1311 subsys_dev->dev_no = dev_no;
1312 minor++;
1313 mutex_unlock(&char_device_lock);
1314
1315 return 0;
1316
1317fail_destroy_device:
1318 device_destroy(char_class, dev_no);
1319fail_unregister_cdev_region:
1320 unregister_chrdev_region(dev_no, 1);
1321fail:
1322 mutex_unlock(&char_device_lock);
1323 return ret;
1324}
1325
1326static void subsys_char_device_remove(struct subsys_device *subsys_dev)
1327{
1328 cdev_del(&subsys_dev->char_dev);
1329 device_destroy(char_class, subsys_dev->dev_no);
1330 unregister_chrdev_region(subsys_dev->dev_no, 1);
1331}
1332
1333static void subsys_remove_restart_order(struct device_node *device)
1334{
1335 struct subsys_soc_restart_order *order;
1336 int i;
1337
1338 mutex_lock(&ssr_order_mutex);
1339 list_for_each_entry(order, &ssr_order_list, list)
1340 for (i = 0; i < order->count; i++)
1341 if (order->device_ptrs[i] == device)
1342 order->subsys_ptrs[i] = NULL;
1343 mutex_unlock(&ssr_order_mutex);
1344}
1345
1346static struct subsys_soc_restart_order *ssr_parse_restart_orders(struct
1347 subsys_desc * desc)
1348{
1349 int i, j, count, num = 0;
1350 struct subsys_soc_restart_order *order, *tmp;
1351 struct device *dev = desc->dev;
1352 struct device_node *ssr_node;
1353 uint32_t len;
1354
1355 if (!of_get_property(dev->of_node, "qcom,restart-group", &len))
1356 return NULL;
1357
1358 count = len/sizeof(uint32_t);
1359
1360 order = devm_kzalloc(dev, sizeof(*order), GFP_KERNEL);
1361 if (!order)
1362 return ERR_PTR(-ENOMEM);
1363
1364 order->subsys_ptrs = devm_kzalloc(dev,
1365 count * sizeof(struct subsys_device *),
1366 GFP_KERNEL);
1367 if (!order->subsys_ptrs)
1368 return ERR_PTR(-ENOMEM);
1369
1370 order->device_ptrs = devm_kzalloc(dev,
1371 count * sizeof(struct device_node *),
1372 GFP_KERNEL);
1373 if (!order->device_ptrs)
1374 return ERR_PTR(-ENOMEM);
1375
1376 for (i = 0; i < count; i++) {
1377 ssr_node = of_parse_phandle(dev->of_node,
1378 "qcom,restart-group", i);
1379 if (!ssr_node)
1380 return ERR_PTR(-ENXIO);
1381 of_node_put(ssr_node);
1382 pr_info("%s device has been added to %s's restart group\n",
1383 ssr_node->name, desc->name);
1384 order->device_ptrs[i] = ssr_node;
1385 }
1386
1387 /*
1388 * Check for similar restart groups. If found, return
1389 * without adding the new group to the ssr_order_list.
1390 */
1391 mutex_lock(&ssr_order_mutex);
1392 list_for_each_entry(tmp, &ssr_order_list, list) {
1393 for (i = 0; i < count; i++) {
1394 for (j = 0; j < count; j++) {
1395 if (order->device_ptrs[j] !=
1396 tmp->device_ptrs[i])
1397 continue;
1398 else
1399 num++;
1400 }
1401 }
1402
1403 if (num == count && tmp->count == count)
1404 goto err;
1405 else if (num) {
1406 tmp = ERR_PTR(-EINVAL);
1407 goto err;
1408 }
1409 }
1410
1411 order->count = count;
1412 mutex_init(&order->track.lock);
1413 spin_lock_init(&order->track.s_lock);
1414
1415 INIT_LIST_HEAD(&order->list);
1416 list_add_tail(&order->list, &ssr_order_list);
1417 mutex_unlock(&ssr_order_mutex);
1418
1419 return order;
1420err:
1421 mutex_unlock(&ssr_order_mutex);
1422 return tmp;
1423}
1424
1425static int __get_gpio(struct subsys_desc *desc, const char *prop,
1426 int *gpio)
1427{
1428 struct device_node *dnode = desc->dev->of_node;
1429 int ret = -ENOENT;
1430
1431 if (of_find_property(dnode, prop, NULL)) {
1432 *gpio = of_get_named_gpio(dnode, prop, 0);
1433 ret = *gpio < 0 ? *gpio : 0;
1434 }
1435
1436 return ret;
1437}
1438
1439static int __get_irq(struct subsys_desc *desc, const char *prop,
1440 unsigned int *irq, int *gpio)
1441{
1442 int ret, gpiol, irql;
1443
1444 ret = __get_gpio(desc, prop, &gpiol);
1445 if (ret)
1446 return ret;
1447
1448 irql = gpio_to_irq(gpiol);
1449
1450 if (irql == -ENOENT)
1451 irql = -ENXIO;
1452
1453 if (irql < 0) {
1454 pr_err("[%s]: Error getting IRQ \"%s\"\n", desc->name,
1455 prop);
1456 return irql;
1457 }
1458
1459 if (gpio)
1460 *gpio = gpiol;
1461 *irq = irql;
1462
1463 return 0;
1464}
1465
1466static int subsys_parse_devicetree(struct subsys_desc *desc)
1467{
1468 struct subsys_soc_restart_order *order;
1469 int ret;
1470
1471 struct platform_device *pdev = container_of(desc->dev,
1472 struct platform_device, dev);
1473
1474 ret = __get_irq(desc, "qcom,gpio-err-fatal", &desc->err_fatal_irq,
1475 &desc->err_fatal_gpio);
1476 if (ret && ret != -ENOENT)
1477 return ret;
1478
1479 ret = __get_irq(desc, "qcom,gpio-err-ready", &desc->err_ready_irq,
1480 NULL);
1481 if (ret && ret != -ENOENT)
1482 return ret;
1483
1484 ret = __get_irq(desc, "qcom,gpio-stop-ack", &desc->stop_ack_irq, NULL);
1485 if (ret && ret != -ENOENT)
1486 return ret;
1487
1488 ret = __get_gpio(desc, "qcom,gpio-force-stop", &desc->force_stop_gpio);
1489 if (ret && ret != -ENOENT)
1490 return ret;
1491
1492 ret = __get_gpio(desc, "qcom,gpio-ramdump-disable",
1493 &desc->ramdump_disable_gpio);
1494 if (ret && ret != -ENOENT)
1495 return ret;
1496
1497 ret = __get_gpio(desc, "qcom,gpio-shutdown-ack",
1498 &desc->shutdown_ack_gpio);
1499 if (ret && ret != -ENOENT)
1500 return ret;
1501
1502 ret = platform_get_irq(pdev, 0);
1503 if (ret > 0)
1504 desc->wdog_bite_irq = ret;
1505
1506 if (of_property_read_bool(pdev->dev.of_node,
1507 "qcom,pil-generic-irq-handler")) {
1508 ret = platform_get_irq(pdev, 0);
1509 if (ret > 0)
1510 desc->generic_irq = ret;
1511 }
1512
Arun KSc992cf62017-03-06 13:21:45 +05301513 desc->ignore_ssr_failure = of_property_read_bool(pdev->dev.of_node,
1514 "qcom,ignore-ssr-failure");
1515
Kyle Yane45fa022016-08-29 11:40:26 -07001516 order = ssr_parse_restart_orders(desc);
1517 if (IS_ERR(order)) {
1518 pr_err("Could not initialize SSR restart order, err = %ld\n",
1519 PTR_ERR(order));
1520 return PTR_ERR(order);
1521 }
1522
1523 return 0;
1524}
1525
1526static int subsys_setup_irqs(struct subsys_device *subsys)
1527{
1528 struct subsys_desc *desc = subsys->desc;
1529 int ret;
1530
1531 if (desc->err_fatal_irq && desc->err_fatal_handler) {
1532 ret = devm_request_irq(desc->dev, desc->err_fatal_irq,
1533 desc->err_fatal_handler,
1534 IRQF_TRIGGER_RISING, desc->name, desc);
1535 if (ret < 0) {
1536 dev_err(desc->dev, "[%s]: Unable to register error fatal IRQ handler!: %d\n",
1537 desc->name, ret);
1538 return ret;
1539 }
1540 disable_irq(desc->err_fatal_irq);
1541 }
1542
1543 if (desc->stop_ack_irq && desc->stop_ack_handler) {
1544 ret = devm_request_irq(desc->dev, desc->stop_ack_irq,
1545 desc->stop_ack_handler,
1546 IRQF_TRIGGER_RISING, desc->name, desc);
1547 if (ret < 0) {
1548 dev_err(desc->dev, "[%s]: Unable to register stop ack handler!: %d\n",
1549 desc->name, ret);
1550 return ret;
1551 }
1552 disable_irq(desc->stop_ack_irq);
1553 }
1554
1555 if (desc->wdog_bite_irq && desc->wdog_bite_handler) {
1556 ret = devm_request_irq(desc->dev, desc->wdog_bite_irq,
1557 desc->wdog_bite_handler,
1558 IRQF_TRIGGER_RISING, desc->name, desc);
1559 if (ret < 0) {
1560 dev_err(desc->dev, "[%s]: Unable to register wdog bite handler!: %d\n",
1561 desc->name, ret);
1562 return ret;
1563 }
1564 disable_irq(desc->wdog_bite_irq);
1565 }
1566
1567 if (desc->generic_irq && desc->generic_handler) {
1568 ret = devm_request_irq(desc->dev, desc->generic_irq,
1569 desc->generic_handler,
1570 IRQF_TRIGGER_HIGH, desc->name, desc);
1571 if (ret < 0) {
1572 dev_err(desc->dev, "[%s]: Unable to register generic irq handler!: %d\n",
1573 desc->name, ret);
1574 return ret;
1575 }
1576 disable_irq(desc->generic_irq);
1577 }
1578
1579 if (desc->err_ready_irq) {
1580 ret = devm_request_irq(desc->dev,
1581 desc->err_ready_irq,
1582 subsys_err_ready_intr_handler,
1583 IRQF_TRIGGER_RISING,
1584 "error_ready_interrupt", subsys);
1585 if (ret < 0) {
1586 dev_err(desc->dev,
1587 "[%s]: Unable to register err ready handler\n",
1588 desc->name);
1589 return ret;
1590 }
1591 disable_irq(desc->err_ready_irq);
1592 }
1593
1594 return 0;
1595}
1596
1597static void subsys_free_irqs(struct subsys_device *subsys)
1598{
1599 struct subsys_desc *desc = subsys->desc;
1600
1601 if (desc->err_fatal_irq && desc->err_fatal_handler)
1602 devm_free_irq(desc->dev, desc->err_fatal_irq, desc);
1603 if (desc->stop_ack_irq && desc->stop_ack_handler)
1604 devm_free_irq(desc->dev, desc->stop_ack_irq, desc);
1605 if (desc->wdog_bite_irq && desc->wdog_bite_handler)
1606 devm_free_irq(desc->dev, desc->wdog_bite_irq, desc);
1607 if (desc->err_ready_irq)
1608 devm_free_irq(desc->dev, desc->err_ready_irq, subsys);
1609}
1610
1611struct subsys_device *subsys_register(struct subsys_desc *desc)
1612{
1613 struct subsys_device *subsys;
1614 struct device_node *ofnode = desc->dev->of_node;
1615 int ret;
1616
1617 subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);
1618 if (!subsys)
1619 return ERR_PTR(-ENOMEM);
1620
1621 subsys->desc = desc;
1622 subsys->owner = desc->owner;
1623 subsys->dev.parent = desc->dev;
1624 subsys->dev.bus = &subsys_bus_type;
1625 subsys->dev.release = subsys_device_release;
1626 subsys->notif_state = -1;
1627 subsys->desc->sysmon_pid = -1;
1628 strlcpy(subsys->desc->fw_name, desc->name,
1629 sizeof(subsys->desc->fw_name));
1630
1631 subsys->notify = subsys_notif_add_subsys(desc->name);
1632
1633 snprintf(subsys->wlname, sizeof(subsys->wlname), "ssr(%s)", desc->name);
1634 wakeup_source_init(&subsys->ssr_wlock, subsys->wlname);
1635 INIT_WORK(&subsys->work, subsystem_restart_wq_func);
1636 INIT_WORK(&subsys->device_restart_work, device_restart_work_hdlr);
1637 spin_lock_init(&subsys->track.s_lock);
1638
1639 subsys->id = ida_simple_get(&subsys_ida, 0, 0, GFP_KERNEL);
1640 if (subsys->id < 0) {
1641 wakeup_source_trash(&subsys->ssr_wlock);
1642 ret = subsys->id;
1643 kfree(subsys);
1644 return ERR_PTR(ret);
1645 }
1646
1647 dev_set_name(&subsys->dev, "subsys%d", subsys->id);
1648
1649 mutex_init(&subsys->track.lock);
1650
Kyle Yane45fa022016-08-29 11:40:26 -07001651 ret = device_register(&subsys->dev);
1652 if (ret) {
Kyle Yane45fa022016-08-29 11:40:26 -07001653 put_device(&subsys->dev);
Kyle Yane45fa022016-08-29 11:40:26 -07001654 return ERR_PTR(ret);
1655 }
1656
1657 ret = subsys_char_device_add(subsys);
1658 if (ret)
1659 goto err_register;
1660
1661 if (ofnode) {
1662 ret = subsys_parse_devicetree(desc);
1663 if (ret)
1664 goto err_register;
1665
1666 subsys->restart_order = update_restart_order(subsys);
1667
1668 ret = subsys_setup_irqs(subsys);
1669 if (ret < 0)
1670 goto err_setup_irqs;
1671
1672 if (of_property_read_u32(ofnode, "qcom,ssctl-instance-id",
1673 &desc->ssctl_instance_id))
1674 pr_debug("Reading instance-id for %s failed\n",
1675 desc->name);
1676
1677 if (of_property_read_u32(ofnode, "qcom,sysmon-id",
1678 &subsys->desc->sysmon_pid))
1679 pr_debug("Reading sysmon-id for %s failed\n",
1680 desc->name);
1681
1682 subsys->desc->edge = of_get_property(ofnode, "qcom,edge",
1683 NULL);
1684 if (!subsys->desc->edge)
1685 pr_debug("Reading qcom,edge for %s failed\n",
1686 desc->name);
1687 }
1688
1689 ret = sysmon_notifier_register(desc);
1690 if (ret < 0)
1691 goto err_sysmon_notifier;
1692
1693 if (subsys->desc->edge) {
1694 ret = sysmon_glink_register(desc);
1695 if (ret < 0)
1696 goto err_sysmon_glink_register;
1697 }
1698 mutex_lock(&subsys_list_lock);
1699 INIT_LIST_HEAD(&subsys->list);
1700 list_add_tail(&subsys->list, &subsys_list);
1701 mutex_unlock(&subsys_list_lock);
1702
1703 return subsys;
1704err_sysmon_glink_register:
1705 sysmon_notifier_unregister(subsys->desc);
1706err_sysmon_notifier:
1707 if (ofnode)
1708 subsys_free_irqs(subsys);
1709err_setup_irqs:
1710 if (ofnode)
1711 subsys_remove_restart_order(ofnode);
1712err_register:
Kyle Yane45fa022016-08-29 11:40:26 -07001713 device_unregister(&subsys->dev);
Kyle Yane45fa022016-08-29 11:40:26 -07001714 return ERR_PTR(ret);
1715}
1716EXPORT_SYMBOL(subsys_register);
1717
1718void subsys_unregister(struct subsys_device *subsys)
1719{
1720 struct subsys_device *subsys_dev, *tmp;
1721 struct device_node *device = subsys->desc->dev->of_node;
1722
1723 if (IS_ERR_OR_NULL(subsys))
1724 return;
1725
1726 if (get_device(&subsys->dev)) {
1727 mutex_lock(&subsys_list_lock);
1728 list_for_each_entry_safe(subsys_dev, tmp, &subsys_list, list)
1729 if (subsys_dev == subsys)
1730 list_del(&subsys->list);
1731 mutex_unlock(&subsys_list_lock);
1732
1733 if (device) {
1734 subsys_free_irqs(subsys);
1735 subsys_remove_restart_order(device);
1736 }
1737 mutex_lock(&subsys->track.lock);
1738 WARN_ON(subsys->count);
1739 device_unregister(&subsys->dev);
1740 mutex_unlock(&subsys->track.lock);
Kyle Yane45fa022016-08-29 11:40:26 -07001741 subsys_char_device_remove(subsys);
1742 sysmon_notifier_unregister(subsys->desc);
1743 if (subsys->desc->edge)
1744 sysmon_glink_unregister(subsys->desc);
1745 put_device(&subsys->dev);
1746 }
1747}
1748EXPORT_SYMBOL(subsys_unregister);
1749
1750static int subsys_panic(struct device *dev, void *data)
1751{
1752 struct subsys_device *subsys = to_subsys(dev);
1753
1754 if (subsys->desc->crash_shutdown)
1755 subsys->desc->crash_shutdown(subsys->desc);
1756 return 0;
1757}
1758
1759static int ssr_panic_handler(struct notifier_block *this,
1760 unsigned long event, void *ptr)
1761{
1762 bus_for_each_dev(&subsys_bus_type, NULL, NULL, subsys_panic);
1763 return NOTIFY_DONE;
1764}
1765
1766static struct notifier_block panic_nb = {
1767 .notifier_call = ssr_panic_handler,
1768};
1769
1770static int __init subsys_restart_init(void)
1771{
1772 int ret;
1773
1774 ssr_wq = alloc_workqueue("ssr_wq", WQ_CPU_INTENSIVE, 0);
1775 BUG_ON(!ssr_wq);
1776
1777 ret = bus_register(&subsys_bus_type);
1778 if (ret)
1779 goto err_bus;
Kyle Yane45fa022016-08-29 11:40:26 -07001780
1781 char_class = class_create(THIS_MODULE, "subsys");
1782 if (IS_ERR(char_class)) {
1783 ret = -ENOMEM;
1784 pr_err("Failed to create subsys_dev class\n");
1785 goto err_class;
1786 }
1787
1788 ret = atomic_notifier_chain_register(&panic_notifier_list,
1789 &panic_nb);
1790 if (ret)
1791 goto err_soc;
1792
1793 return 0;
1794
1795err_soc:
1796 class_destroy(char_class);
1797err_class:
Kyle Yane45fa022016-08-29 11:40:26 -07001798 bus_unregister(&subsys_bus_type);
1799err_bus:
1800 destroy_workqueue(ssr_wq);
1801 return ret;
1802}
1803arch_initcall(subsys_restart_init);
1804
1805MODULE_DESCRIPTION("Subsystem Restart Driver");
1806MODULE_LICENSE("GPL v2");