Skip to content

Commit

Permalink
Add drivers/base/ modifications
Browse files Browse the repository at this point in the history
Signed-off-by: ShivamKumarJha <[email protected]>
  • Loading branch information
ShivamKumarJha committed Mar 30, 2021
1 parent 41ece96 commit b199795
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 19 deletions.
4 changes: 3 additions & 1 deletion drivers/base/firmware_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* firmware_class.c - Multi purpose firmware loading support
*
* Copyright (c) 2003 Manuel Estrada Sainz
* Copyright (C) 2021 XiaoMi, Inc.
*
* Please see Documentation/firmware_class/ for more information.
*
Expand Down Expand Up @@ -379,9 +380,10 @@ static void fw_free_buf(struct firmware_buf *buf)
}

/* direct firmware loading support */
static char fw_path_para[256];
static char fw_path_para[256] = "/vendor/firmware";
static const char * const fw_path[] = {
fw_path_para,
"/vendor/firmware/awinic",
"/lib/firmware/updates/" UTS_RELEASE,
"/lib/firmware/updates",
"/lib/firmware/" UTS_RELEASE,
Expand Down
97 changes: 80 additions & 17 deletions drivers/base/power/wakeup.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* drivers/base/power/wakeup.c - System wakeup events framework
*
* Copyright (c) 2010 Rafael J. Wysocki <[email protected]>, Novell Inc.
* Copyright (C) 2021 XiaoMi, Inc.
*
* This file is released under the GPLv2.
*/
Expand All @@ -22,7 +23,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/irqdesc.h>

#include <linux/wakeup_reason.h>
#include "power.h"

#ifndef CONFIG_SUSPEND
Expand All @@ -38,10 +39,11 @@ bool events_check_enabled __read_mostly;

/* First wakeup IRQ seen by the kernel in the last cycle. */
unsigned int pm_wakeup_irq __read_mostly;
extern void system_sleep_status_print_enabled(void);

/* If greater than 0 and the system is suspending, terminate the suspend. */
static atomic_t pm_abort_suspend __read_mostly;

static struct delayed_work wakelock_work;
/*
* Combined counters of registered wakeup events and wakeup events in progress.
* They need to be modified together atomically, so it's better to use one
Expand Down Expand Up @@ -902,7 +904,7 @@ void pm_print_active_wakeup_sources(void)
srcuidx = srcu_read_lock(&wakeup_srcu);
list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
if (ws->active) {
pr_debug("active wakeup source: %s\n", ws->name);
pr_info("active wakeup source: %s\n", ws->name);
active = 1;
} else if (!active &&
(!last_activity_ws ||
Expand All @@ -913,7 +915,7 @@ void pm_print_active_wakeup_sources(void)
}

if (!active && last_activity_ws)
pr_debug("last active wakeup source: %s\n",
pr_info("last active wakeup source: %s\n",
last_activity_ws->name);
srcu_read_unlock(&wakeup_srcu, srcuidx);
}
Expand All @@ -927,6 +929,7 @@ EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources);
* since the old value was stored. Also return true if the current number of
* wakeup events being processed is different from zero.
*/
bool wakeup_irq_abort_suspend;
bool pm_wakeup_pending(void)
{
unsigned long flags;
Expand Down Expand Up @@ -956,6 +959,7 @@ bool pm_wakeup_pending(void)
void pm_system_wakeup(void)
{
atomic_inc(&pm_abort_suspend);
wakeup_irq_abort_suspend = true;
s2idle_wake();
}
EXPORT_SYMBOL_GPL(pm_system_wakeup);
Expand All @@ -968,6 +972,7 @@ void pm_system_cancel_wakeup(void)
void pm_wakeup_clear(bool reset)
{
pm_wakeup_irq = 0;
wakeup_irq_abort_suspend = false;
if (reset)
atomic_set(&pm_abort_suspend, 0);
}
Expand All @@ -991,6 +996,7 @@ void pm_system_irq_wakeup(unsigned int irq_number)
}
pm_wakeup_irq = irq_number;
pm_system_wakeup();
log_irq_wakeup_reason(irq_number);
}
}

Expand Down Expand Up @@ -1135,46 +1141,103 @@ static int print_wakeup_source_stats(struct seq_file *m,
return 0;
}

static void *wakeup_sources_stats_seq_start(struct seq_file *m, loff_t *pos)
{
struct wakeup_source *ws;
loff_t n = *pos;
int *srcuidx = m->private;

if (n == 0) {
seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
"expire_count\tactive_since\ttotal_time\tmax_time\t"
"last_change\tprevent_suspend_time\n");
}

*srcuidx = srcu_read_lock(&wakeup_srcu);
list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
if (n-- <= 0)
return ws;
}

return NULL;
}

static void *wakeup_sources_stats_seq_next(struct seq_file *m, void *v, loff_t *pos)
{
struct wakeup_source *ws = v;
struct wakeup_source *next_ws = NULL;

++(*pos);

list_for_each_entry_continue_rcu(ws, &wakeup_sources, entry) {
next_ws = ws;
break;
}

return next_ws;
}

static void wakeup_sources_stats_seq_stop(struct seq_file *m, void *v)
{
int *srcuidx = m->private;

srcu_read_unlock(&wakeup_srcu, *srcuidx);
}

/**
* wakeup_sources_stats_show - Print wakeup sources statistics information.
* @m: seq_file to print the statistics into.
* @v: wakeup_source of each iteration
*/
static int wakeup_sources_stats_show(struct seq_file *m, void *unused)
static int wakeup_sources_stats_seq_show(struct seq_file *m, void *v)
{
struct wakeup_source *ws;
int srcuidx;

seq_puts(m, "name\t\t\t\t\tactive_count\tevent_count\twakeup_count\t"
"expire_count\tactive_since\ttotal_time\tmax_time\t"
"last_change\tprevent_suspend_time\n");
struct wakeup_source *ws = v;

srcuidx = srcu_read_lock(&wakeup_srcu);
list_for_each_entry_rcu(ws, &wakeup_sources, entry)
print_wakeup_source_stats(m, ws);
srcu_read_unlock(&wakeup_srcu, srcuidx);
print_wakeup_source_stats(m, ws);

print_wakeup_source_stats(m, &deleted_ws);

return 0;
}

void print_active_wakelock(struct work_struct *work)

{

pm_print_active_wakeup_sources();
#ifdef CONFIG_DEBUG_FS
system_sleep_status_print_enabled();
#endif
schedule_delayed_work(&wakelock_work, 18000);

}

static const struct seq_operations wakeup_sources_stats_seq_ops = {
.start = wakeup_sources_stats_seq_start,
.next = wakeup_sources_stats_seq_next,
.stop = wakeup_sources_stats_seq_stop,
.show = wakeup_sources_stats_seq_show,
};

static int wakeup_sources_stats_open(struct inode *inode, struct file *file)
{
return single_open(file, wakeup_sources_stats_show, NULL);
return seq_open_private(file, &wakeup_sources_stats_seq_ops, sizeof(int));
}

static const struct file_operations wakeup_sources_stats_fops = {
.owner = THIS_MODULE,
.open = wakeup_sources_stats_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.release = seq_release_private,
};

static int __init wakeup_sources_debugfs_init(void)
{
wakeup_sources_stats_dentry = debugfs_create_file("wakeup_sources",
S_IRUGO, NULL, NULL, &wakeup_sources_stats_fops);
INIT_DELAYED_WORK(&wakelock_work, print_active_wakelock);
schedule_delayed_work(&wakelock_work, 1);
return 0;
}

Expand Down
10 changes: 9 additions & 1 deletion drivers/base/syscore.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,25 @@ EXPORT_SYMBOL_GPL(unregister_syscore_ops);
*
* This function is executed with one CPU on-line and disabled interrupts.
*/
extern bool wakeup_irq_abort_suspend;
int syscore_suspend(void)
{
struct syscore_ops *ops;
int ret = 0;
char suspend_abort[MAX_SUSPEND_ABORT_LEN];

trace_suspend_resume(TPS("syscore_suspend"), 0, true);
pr_debug("Checking wakeup interrupts\n");

/* Return error code if there are any wakeup interrupts pending. */
if (pm_wakeup_pending())
if (pm_wakeup_pending()) {
if (wakeup_irq_abort_suspend == false) {
pm_get_active_wakeup_sources(suspend_abort, MAX_SUSPEND_ABORT_LEN);
log_suspend_abort_reason(suspend_abort);
}
pr_err("PM: Abort system core suspend, wakeup interrupt or wakeup source detected");
return -EBUSY;
}

WARN_ONCE(!irqs_disabled(),
"Interrupts enabled before system core suspend.\n");
Expand Down

0 comments on commit b199795

Please sign in to comment.