mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-27 06:22:03 +02:00
387 lines
9.1 KiB
Diff
387 lines
9.1 KiB
Diff
|
From 95b8e195427ce0c6b495925813d7e10949af8ce3 Mon Sep 17 00:00:00 2001
|
||
|
From: Andy Green <andy@openmoko.com>
|
||
|
Date: Fri, 25 Jul 2008 23:06:10 +0100
|
||
|
Subject: [PATCH] add-resume-reason-sysfs.patch
|
||
|
|
||
|
If you have U-Boot with uboot-add-find-wake-reason.patch, this
|
||
|
patch will get you a wake reason report from
|
||
|
|
||
|
cat /sys/devices/platform/neo1973-resume.0/resume_reason
|
||
|
|
||
|
it looks like this:
|
||
|
|
||
|
EINT00_ACCEL1
|
||
|
EINT01_GSM
|
||
|
EINT02_BLUETOOTH
|
||
|
EINT03_DEBUGBRD
|
||
|
EINT04_JACK
|
||
|
EINT05_WLAN
|
||
|
EINT06_AUXKEY
|
||
|
EINT07_HOLDKEY
|
||
|
EINT08_ACCEL2
|
||
|
* EINT09_PMU
|
||
|
adpins
|
||
|
adprem
|
||
|
usbins
|
||
|
usbrem
|
||
|
rtcalarm
|
||
|
second
|
||
|
onkeyr
|
||
|
onkeyf
|
||
|
exton1r
|
||
|
exton1f
|
||
|
exton2r
|
||
|
exton2f
|
||
|
exton3r
|
||
|
exton3f
|
||
|
* batfull
|
||
|
chghalt
|
||
|
thlimon
|
||
|
thlimoff
|
||
|
usblimon
|
||
|
usblimoff
|
||
|
adcrdy
|
||
|
onkey1s
|
||
|
lowsys
|
||
|
lowbat
|
||
|
hightmp
|
||
|
autopwrfail
|
||
|
dwn1pwrfail
|
||
|
dwn2pwrfail
|
||
|
ledpwrfail
|
||
|
ledovp
|
||
|
ldo1pwrfail
|
||
|
ldo2pwrfail
|
||
|
ldo3pwrfail
|
||
|
ldo4pwrfail
|
||
|
ldo5pwrfail
|
||
|
ldo6pwrfail
|
||
|
hcidopwrfail
|
||
|
hcidoovl
|
||
|
EINT10_NULL
|
||
|
EINT11_NULL
|
||
|
EINT12_GLAMO
|
||
|
EINT13_NULL
|
||
|
EINT14_NULL
|
||
|
EINT15_NULL
|
||
|
|
||
|
This shows a problem, false wake from suspend due to battery full
|
||
|
|
||
|
Signed-off-by: Andy Green <andy@openmoko.com>
|
||
|
---
|
||
|
arch/arm/mach-s3c2440/mach-gta02.c | 5 +
|
||
|
arch/arm/plat-s3c24xx/Makefile | 4 +-
|
||
|
arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c | 134 ++++++++++++++++++++++
|
||
|
drivers/i2c/chips/pcf50633.c | 80 +++++++++++++
|
||
|
include/linux/pcf50633.h | 6 +
|
||
|
5 files changed, 227 insertions(+), 2 deletions(-)
|
||
|
create mode 100644 arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
|
||
|
|
||
|
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||
|
index 9e8fae7..90b62c1 100644
|
||
|
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||
|
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||
|
@@ -378,6 +378,10 @@ struct platform_device gta02_version_device = {
|
||
|
.num_resources = 0,
|
||
|
};
|
||
|
|
||
|
+struct platform_device gta02_resume_reason_device = {
|
||
|
+ .name = "neo1973-resume",
|
||
|
+ .num_resources = 0,
|
||
|
+};
|
||
|
|
||
|
static struct map_desc gta02_iodesc[] __initdata = {
|
||
|
{
|
||
|
@@ -737,6 +741,7 @@ static struct platform_device *gta02_devices[] __initdata = {
|
||
|
>a02_nor_flash,
|
||
|
&sc32440_fiq_device,
|
||
|
>a02_version_device,
|
||
|
+ >a02_resume_reason_device,
|
||
|
&s3c24xx_pwm_device,
|
||
|
};
|
||
|
|
||
|
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
|
||
|
index c173f7b..f60dc5f 100644
|
||
|
--- a/arch/arm/plat-s3c24xx/Makefile
|
||
|
+++ b/arch/arm/plat-s3c24xx/Makefile
|
||
|
@@ -34,5 +34,5 @@ obj-$(CONFIG_MACH_NEO1973) += neo1973_version.o \
|
||
|
neo1973_pm_gsm.o \
|
||
|
neo1973_pm_gps.o \
|
||
|
neo1973_pm_bt.o \
|
||
|
- neo1973_shadow.o
|
||
|
-
|
||
|
+ neo1973_shadow.o \
|
||
|
+ neo1973_pm_resume_reason.o
|
||
|
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c b/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
|
||
|
new file mode 100644
|
||
|
index 0000000..cca42dc
|
||
|
--- /dev/null
|
||
|
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
|
||
|
@@ -0,0 +1,134 @@
|
||
|
+/*
|
||
|
+ * Resume reason sysfs for the FIC Neo1973 GSM Phone
|
||
|
+ *
|
||
|
+ * (C) 2008 by Openmoko Inc.
|
||
|
+ * Author: Andy Green <andy@openmoko.com>
|
||
|
+ * All rights reserved.
|
||
|
+ *
|
||
|
+ * This program is free software; you can redistribute it and/or modify
|
||
|
+ * it under the terms of the GNU General Public License resume_reason 2 as
|
||
|
+ * published by the Free Software Foundation
|
||
|
+ *
|
||
|
+ */
|
||
|
+
|
||
|
+#include <linux/module.h>
|
||
|
+#include <linux/init.h>
|
||
|
+#include <linux/kernel.h>
|
||
|
+#include <linux/platform_device.h>
|
||
|
+#include <linux/io.h>
|
||
|
+
|
||
|
+#include <asm/hardware.h>
|
||
|
+#include <asm/mach-types.h>
|
||
|
+
|
||
|
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||
|
+#include <asm/arch/gta02.h>
|
||
|
+#include <linux/pcf50633.h>
|
||
|
+
|
||
|
+
|
||
|
+static unsigned int *gstatus4_mapped;
|
||
|
+static char *resume_reasons[] = {
|
||
|
+ "EINT00_ACCEL1",
|
||
|
+ "EINT01_GSM",
|
||
|
+ "EINT02_BLUETOOTH",
|
||
|
+ "EINT03_DEBUGBRD",
|
||
|
+ "EINT04_JACK",
|
||
|
+ "EINT05_WLAN",
|
||
|
+ "EINT06_AUXKEY",
|
||
|
+ "EINT07_HOLDKEY",
|
||
|
+ "EINT08_ACCEL2",
|
||
|
+ "EINT09_PMU",
|
||
|
+ "EINT10_NULL",
|
||
|
+ "EINT11_NULL",
|
||
|
+ "EINT12_GLAMO",
|
||
|
+ "EINT13_NULL",
|
||
|
+ "EINT14_NULL",
|
||
|
+ "EINT15_NULL",
|
||
|
+ NULL
|
||
|
+};
|
||
|
+
|
||
|
+static ssize_t resume_reason_read(struct device *dev,
|
||
|
+ struct device_attribute *attr,
|
||
|
+ char *buf)
|
||
|
+{
|
||
|
+ int bit = 0;
|
||
|
+ char *end = buf;
|
||
|
+
|
||
|
+ for (bit = 0; resume_reasons[bit]; bit++) {
|
||
|
+ if ((*gstatus4_mapped) & (1 << bit))
|
||
|
+ end += sprintf(end, "* %s\n", resume_reasons[bit]);
|
||
|
+ else
|
||
|
+ end += sprintf(end, " %s\n", resume_reasons[bit]);
|
||
|
+
|
||
|
+ if (bit == 9) /* PMU */
|
||
|
+ end += pcf50633_report_resumers(pcf50633_global, end);
|
||
|
+ }
|
||
|
+
|
||
|
+ return end - buf;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static DEVICE_ATTR(resume_reason, 0644, resume_reason_read, NULL);
|
||
|
+
|
||
|
+static struct attribute *neo1973_resume_reason_sysfs_entries[] = {
|
||
|
+ &dev_attr_resume_reason.attr,
|
||
|
+ NULL
|
||
|
+};
|
||
|
+
|
||
|
+static struct attribute_group neo1973_resume_reason_attr_group = {
|
||
|
+ .name = NULL,
|
||
|
+ .attrs = neo1973_resume_reason_sysfs_entries,
|
||
|
+};
|
||
|
+
|
||
|
+static int __init neo1973_resume_reason_probe(struct platform_device *pdev)
|
||
|
+{
|
||
|
+ dev_info(&pdev->dev, "starting\n");
|
||
|
+
|
||
|
+ switch (machine_arch_type) {
|
||
|
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||
|
+ case MACH_TYPE_NEO1973_GTA01:
|
||
|
+ return -EINVAL;
|
||
|
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||
|
+ default:
|
||
|
+ gstatus4_mapped = ioremap(0x560000BC, 0x4);
|
||
|
+ if (!gstatus4_mapped) {
|
||
|
+ dev_err(&pdev->dev, "failed to ioremap() memory region\n");
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ return sysfs_create_group(&pdev->dev.kobj, &neo1973_resume_reason_attr_group);
|
||
|
+}
|
||
|
+
|
||
|
+static int neo1973_resume_reason_remove(struct platform_device *pdev)
|
||
|
+{
|
||
|
+ sysfs_remove_group(&pdev->dev.kobj, &neo1973_resume_reason_attr_group);
|
||
|
+ iounmap(gstatus4_mapped);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static struct platform_driver neo1973_resume_reason_driver = {
|
||
|
+ .probe = neo1973_resume_reason_probe,
|
||
|
+ .remove = neo1973_resume_reason_remove,
|
||
|
+ .driver = {
|
||
|
+ .name = "neo1973-resume",
|
||
|
+ },
|
||
|
+};
|
||
|
+
|
||
|
+static int __devinit neo1973_resume_reason_init(void)
|
||
|
+{
|
||
|
+ return platform_driver_register(&neo1973_resume_reason_driver);
|
||
|
+}
|
||
|
+
|
||
|
+static void neo1973_resume_reason_exit(void)
|
||
|
+{
|
||
|
+ platform_driver_unregister(&neo1973_resume_reason_driver);
|
||
|
+}
|
||
|
+
|
||
|
+module_init(neo1973_resume_reason_init);
|
||
|
+module_exit(neo1973_resume_reason_exit);
|
||
|
+
|
||
|
+MODULE_LICENSE("GPL");
|
||
|
+MODULE_AUTHOR("Andy Green <andy@openmoko.com>");
|
||
|
+MODULE_DESCRIPTION("Neo1973 resume_reason");
|
||
|
+#endif
|
||
|
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
|
||
|
index da58aa3..d2ff2c1 100644
|
||
|
--- a/drivers/i2c/chips/pcf50633.c
|
||
|
+++ b/drivers/i2c/chips/pcf50633.c
|
||
|
@@ -120,6 +120,8 @@ struct pcf50633_data {
|
||
|
int allow_close;
|
||
|
int onkey_seconds;
|
||
|
int irq;
|
||
|
+ int have_been_suspended;
|
||
|
+ unsigned char pcfirq_resume[5];
|
||
|
|
||
|
int coldplug_done; /* cleared by probe, set by first work service */
|
||
|
int flag_bat_voltage_read; /* ipc to /sys batt voltage read func */
|
||
|
@@ -597,6 +599,17 @@ static void pcf50633_work(struct work_struct *work)
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+ /* hey did we just resume? */
|
||
|
+
|
||
|
+ if (pcf->have_been_suspended) {
|
||
|
+ pcf->have_been_suspended = 0;
|
||
|
+ /*
|
||
|
+ * grab a copy of resume interrupt reasons
|
||
|
+ * from pcf50633 POV
|
||
|
+ */
|
||
|
+ memcpy(pcf->pcfirq_resume, pcfirq, sizeof(pcf->pcfirq_resume));
|
||
|
+ }
|
||
|
+
|
||
|
if (!pcf->coldplug_done) {
|
||
|
DEBUGP("PMU Coldplug init\n");
|
||
|
|
||
|
@@ -1856,6 +1869,71 @@ static int pcf50633_detach_client(struct i2c_client *client)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+/* you're going to need >300 bytes in buf */
|
||
|
+
|
||
|
+int pcf50633_report_resumers(struct pcf50633_data *pcf, char *buf)
|
||
|
+{
|
||
|
+ static char *int_names[] = {
|
||
|
+ "adpins",
|
||
|
+ "adprem",
|
||
|
+ "usbins",
|
||
|
+ "usbrem",
|
||
|
+ NULL,
|
||
|
+ NULL,
|
||
|
+ "rtcalarm",
|
||
|
+ "second",
|
||
|
+
|
||
|
+ "onkeyr",
|
||
|
+ "onkeyf",
|
||
|
+ "exton1r",
|
||
|
+ "exton1f",
|
||
|
+ "exton2r",
|
||
|
+ "exton2f",
|
||
|
+ "exton3r",
|
||
|
+ "exton3f",
|
||
|
+
|
||
|
+ "batfull",
|
||
|
+ "chghalt",
|
||
|
+ "thlimon",
|
||
|
+ "thlimoff",
|
||
|
+ "usblimon",
|
||
|
+ "usblimoff",
|
||
|
+ "adcrdy",
|
||
|
+ "onkey1s",
|
||
|
+
|
||
|
+ "lowsys",
|
||
|
+ "lowbat",
|
||
|
+ "hightmp",
|
||
|
+ "autopwrfail",
|
||
|
+ "dwn1pwrfail",
|
||
|
+ "dwn2pwrfail",
|
||
|
+ "ledpwrfail",
|
||
|
+ "ledovp",
|
||
|
+
|
||
|
+ "ldo1pwrfail",
|
||
|
+ "ldo2pwrfail",
|
||
|
+ "ldo3pwrfail",
|
||
|
+ "ldo4pwrfail",
|
||
|
+ "ldo5pwrfail",
|
||
|
+ "ldo6pwrfail",
|
||
|
+ "hcidopwrfail",
|
||
|
+ "hcidoovl"
|
||
|
+ };
|
||
|
+ char *end = buf;
|
||
|
+ int n;
|
||
|
+
|
||
|
+ for (n = 0; n < 40; n++)
|
||
|
+ if (int_names[n]) {
|
||
|
+ if (pcf->pcfirq_resume[n >> 3] & (1 >> (n & 7)))
|
||
|
+ end += sprintf(end, " * %s\n", int_names[n]);
|
||
|
+ else
|
||
|
+ end += sprintf(end, " %s\n", int_names[n]);
|
||
|
+ }
|
||
|
+
|
||
|
+ return end - buf;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
#ifdef CONFIG_PM
|
||
|
#define INT1M_RESUMERS (PCF50633_INT1_ADPINS | \
|
||
|
PCF50633_INT1_ADPREM | \
|
||
|
@@ -1938,6 +2016,8 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
|
||
|
__reg_write(pcf, PCF50633_REG_INT4M, ~INT4M_RESUMERS & 0xff);
|
||
|
__reg_write(pcf, PCF50633_REG_INT5M, ~INT5M_RESUMERS & 0xff);
|
||
|
|
||
|
+ pcf->have_been_suspended = 1;
|
||
|
+
|
||
|
mutex_unlock(&pcf->lock);
|
||
|
|
||
|
return 0;
|
||
|
diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h
|
||
|
index f427985..39d919d 100644
|
||
|
--- a/include/linux/pcf50633.h
|
||
|
+++ b/include/linux/pcf50633.h
|
||
|
@@ -64,6 +64,12 @@ pcf50633_charge_enable(struct pcf50633_data *pcf, int on);
|
||
|
extern void
|
||
|
pcf50633_backlight_resume(struct pcf50633_data *pcf);
|
||
|
|
||
|
+extern u_int16_t
|
||
|
+pcf50633_battvolt(struct pcf50633_data *pcf);
|
||
|
+
|
||
|
+extern int
|
||
|
+pcf50633_report_resumers(struct pcf50633_data *pcf, char *buf);
|
||
|
+
|
||
|
#define PCF50633_FEAT_EXTON 0x00000001 /* not yet supported */
|
||
|
#define PCF50633_FEAT_MBC 0x00000002
|
||
|
#define PCF50633_FEAT_BBC 0x00000004 /* not yet supported */
|
||
|
--
|
||
|
1.5.6.3
|
||
|
|