summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaran Jhavar <kjhavar@nvidia.com>2011-05-02 13:32:57 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-05-17 11:52:43 -0700
commit99f755b0c92dc8b4eaf9c235b3527220c95af236 (patch)
tree3f2f5b414199237b441d32630a83a8453b68f819
parentde4c80095b759924d0b8867918daa3dbc884c222 (diff)
ARM: tegra: power LP0/LP1 selection via sysfs
Select LP0/LP1 on runtime using sysfs node /sys/power/suspend/type. Valid selctions/commands are: 1. lp0 2. lp1 3. lp2 Change-Id: I335a8845dbfed7539ae4bf8aee3ba3b97ecb3db3 Reviewed-on: http://git-master/r/30081 Reviewed-by: Karan Jhavar <kjhavar@nvidia.com> Reviewed-by: Aleksandr Frid <afrid@nvidia.com> Tested-by: Karan Jhavar <kjhavar@nvidia.com> Reviewed-by: Scott Williams <scwilliams@nvidia.com> Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/gpio.c7
-rw-r--r--arch/arm/mach-tegra/irq.c5
-rw-r--r--arch/arm/mach-tegra/suspend.c75
3 files changed, 68 insertions, 19 deletions
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
index 66f37f9b4d65..25d1eaa31de1 100644
--- a/arch/arm/mach-tegra/gpio.c
+++ b/arch/arm/mach-tegra/gpio.c
@@ -240,8 +240,7 @@ static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type)
else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
__set_irq_handler_unlocked(irq, handle_edge_irq);
- if (tegra_get_suspend_mode() == TEGRA_SUSPEND_LP0)
- tegra_set_lp0_wake_type(irq, type);
+ tegra_set_lp0_wake_type(irq, type);
return 0;
}
@@ -363,12 +362,10 @@ static int tegra_gpio_wake_enable(unsigned int irq, unsigned int enable)
struct tegra_gpio_bank *bank = get_irq_chip_data(irq);
ret = tegra_set_lp1_wake(bank->irq, enable);
+ ret |= tegra_set_lp0_wake(irq, enable);
if (ret)
return ret;
- if (tegra_get_suspend_mode() == TEGRA_SUSPEND_LP0)
- return tegra_set_lp0_wake(irq, enable);
-
return 0;
}
#endif
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index e9e51ba47575..3abc6da46167 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -270,10 +270,7 @@ static int tegra_set_wake(unsigned int irq, unsigned int enable)
static int tegra_set_type(unsigned int irq, unsigned int flow_type)
{
- if (tegra_get_suspend_mode() == TEGRA_SUSPEND_LP0)
- return tegra_set_lp0_wake_type(irq, flow_type);
-
- return 0;
+ return tegra_set_lp0_wake_type(irq, flow_type);
}
static void tegra_ack(unsigned int irq)
diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c
index dc8ff5699849..80269b5f7c59 100644
--- a/arch/arm/mach-tegra/suspend.c
+++ b/arch/arm/mach-tegra/suspend.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/cpumask.h>
+#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/sched.h>
@@ -181,6 +182,15 @@ static enum tegra_suspend_mode current_suspend_mode;
static unsigned int tegra_time_in_suspend[32];
+struct kobject *suspend_kobj;
+
+static const char *tegra_suspend_name[TEGRA_MAX_SUSPEND_MODE] = {
+ [TEGRA_SUSPEND_NONE] = "none",
+ [TEGRA_SUSPEND_LP2] = "lp2",
+ [TEGRA_SUSPEND_LP1] = "lp1",
+ [TEGRA_SUSPEND_LP0] = "lp0",
+};
+
#if INSTRUMENT_CLUSTER_SWITCH
enum tegra_cluster_switch_time_id
{
@@ -213,6 +223,49 @@ static unsigned long tegra_cluster_switch_times[tegra_cluster_switch_time_id_max
#define cpu_number() 0
#endif
+static ssize_t suspend_mode_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ char *start = buf;
+ char *end = buf + PAGE_SIZE;
+
+ start += scnprintf(start, end - start, "%s ", \
+ tegra_suspend_name[current_suspend_mode]);
+ start += scnprintf(start, end - start, "\n");
+
+ return start - buf;
+}
+
+static ssize_t suspend_mode_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ int len;
+ const char *name_ptr;
+ enum tegra_suspend_mode new_mode;
+
+ name_ptr = buf;
+ while (*name_ptr && !isspace(*name_ptr))
+ name_ptr++;
+ len = name_ptr - buf;
+ if (!len)
+ goto bad_name;
+
+ for (new_mode = TEGRA_SUSPEND_NONE; \
+ new_mode < TEGRA_MAX_SUSPEND_MODE; ++new_mode) {
+ if (!strncmp(buf, tegra_suspend_name[new_mode], len)) {
+ current_suspend_mode = new_mode;
+ break;
+ }
+ }
+
+bad_name:
+ return n;
+}
+
+static struct kobj_attribute suspend_mode_attribute =
+ __ATTR(mode, 0666, suspend_mode_show, suspend_mode_store);
+
static inline unsigned int time_to_bin(unsigned int time)
{
return fls(time);
@@ -247,7 +300,7 @@ enum tegra_suspend_mode tegra_get_suspend_mode(void)
if (!pdata)
return TEGRA_SUSPEND_NONE;
- return pdata->suspend_mode;
+ return current_suspend_mode;
}
#if defined(CONFIG_PM) || defined(CONFIG_CPU_IDLE) || !defined(CONFIG_ARCH_TEGRA_2x_SOC)
@@ -678,8 +731,7 @@ void tegra_suspend_dram(bool do_lp0)
pr_err_ratelimited("WFI for LP1 failed for CPU %d: count %lu\n",
cpu, tegra_wfi_fail_count[cpu]);
}
- }
- else {
+ } else {
tegra_cpu_reset_handler_enable();
tegra_cpu_reset_handler_restore();
tegra_lp0_resume_mc();
@@ -1018,16 +1070,19 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
#endif
current_suspend_mode = plat->suspend_mode;
+
+ /* Create /sys/power/suspend/type */
+ suspend_kobj = kobject_create_and_add("suspend", power_kobj);
+ if (suspend_kobj) {
+ if (sysfs_create_file(suspend_kobj, \
+ &suspend_mode_attribute.attr))
+ pr_err("%s: sysfs_create_file suspend type failed!", \
+ __func__);
+ }
}
-#ifdef CONFIG_DEBUG_FS
-static const char *tegra_suspend_name[TEGRA_MAX_SUSPEND_MODE] = {
- [TEGRA_SUSPEND_NONE] = "none",
- [TEGRA_SUSPEND_LP2] = "lp2",
- [TEGRA_SUSPEND_LP1] = "lp1",
- [TEGRA_SUSPEND_LP0] = "lp0",
-};
+#ifdef CONFIG_DEBUG_FS
static int tegra_suspend_debug_show(struct seq_file *s, void *data)
{
seq_printf(s, "%s\n", tegra_suspend_name[*(int *)s->private]);