mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2025-04-21 12:27:27 +03:00
change prefix for kernelpatchbase 2.6.26
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@13619 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
From 591a5d7e8da059de812d315b865fd5c0fa89071e Mon Sep 17 00:00:00 2001
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:15 +0100
|
||||
Subject: [PATCH] fix-pcf50633-suspend-state-as-enum.patch
|
||||
|
||||
Use an enum to define pcf50633 suspend / resume state.
|
||||
Add PCF50633_SS_RESUMING_BUT_NOT_US_YET to be the state
|
||||
early in resume: add platform driver resume function just
|
||||
to set this state so we can differentiate between early
|
||||
resume and late suspend.
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
drivers/i2c/chips/pcf50633.c | 73 ++++++++++++++++++++++++++++++++++--------
|
||||
1 files changed, 59 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
|
||||
index 37dfca6..87a3003 100644
|
||||
--- a/drivers/i2c/chips/pcf50633.c
|
||||
+++ b/drivers/i2c/chips/pcf50633.c
|
||||
@@ -108,6 +108,16 @@ enum charger_type {
|
||||
|
||||
#define MAX_ADC_FIFO_DEPTH 8
|
||||
|
||||
+enum pcf50633_suspend_states {
|
||||
+ PCF50633_SS_RUNNING,
|
||||
+ PCF50633_SS_STARTING_SUSPEND,
|
||||
+ PCF50633_SS_COMPLETED_SUSPEND,
|
||||
+ PCF50633_SS_RESUMING_BUT_NOT_US_YET,
|
||||
+ PCF50633_SS_STARTING_RESUME,
|
||||
+ PCF50633_SS_COMPLETED_RESUME,
|
||||
+};
|
||||
+
|
||||
+
|
||||
struct pcf50633_data {
|
||||
struct i2c_client client;
|
||||
struct pcf50633_platform_data *pdata;
|
||||
@@ -122,9 +132,9 @@ struct pcf50633_data {
|
||||
int allow_close;
|
||||
int onkey_seconds;
|
||||
int irq;
|
||||
- int have_been_suspended;
|
||||
+ enum pcf50633_suspend_states suspend_state;
|
||||
int usb_removal_count;
|
||||
- unsigned char pcfirq_resume[5];
|
||||
+ u8 pcfirq_resume[5];
|
||||
int probe_completed;
|
||||
|
||||
/* if he pulls battery while charging, we notice that and correctly
|
||||
@@ -191,7 +201,7 @@ static struct platform_device *pcf50633_pdev;
|
||||
|
||||
static int __reg_write(struct pcf50633_data *pcf, u_int8_t reg, u_int8_t val)
|
||||
{
|
||||
- if (pcf->have_been_suspended == 1) {
|
||||
+ if (pcf->suspend_state == PCF50633_SS_COMPLETED_SUSPEND) {
|
||||
dev_err(&pcf->client.dev, "__reg_write while suspended\n");
|
||||
dump_stack();
|
||||
}
|
||||
@@ -213,7 +223,7 @@ static int32_t __reg_read(struct pcf50633_data *pcf, u_int8_t reg)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
- if (pcf->have_been_suspended == 1) {
|
||||
+ if (pcf->suspend_state == PCF50633_SS_COMPLETED_SUSPEND) {
|
||||
dev_err(&pcf->client.dev, "__reg_read while suspended\n");
|
||||
dump_stack();
|
||||
}
|
||||
@@ -630,7 +640,8 @@ static void pcf50633_work_usbcurlim(struct work_struct *work)
|
||||
/* we got a notification from USB stack before we completed resume...
|
||||
* that can only make trouble, reschedule for a retry
|
||||
*/
|
||||
- if (pcf->have_been_suspended && (pcf->have_been_suspended < 3))
|
||||
+ if (pcf->suspend_state &&
|
||||
+ (pcf->suspend_state < PCF50633_SS_COMPLETED_RESUME))
|
||||
goto reschedule;
|
||||
|
||||
/*
|
||||
@@ -751,6 +762,21 @@ static void pcf50633_work(struct work_struct *work)
|
||||
pcf->working = 1;
|
||||
|
||||
/*
|
||||
+ * if we are presently suspending, we are not in a position to deal
|
||||
+ * with pcf50633 interrupts at all.
|
||||
+ *
|
||||
+ * Because we didn't clear the int pending registers, there will be
|
||||
+ * no edge / interrupt waiting for us when we wake. But it is OK
|
||||
+ * because at the end of our resume, we call this workqueue function
|
||||
+ * gratuitously, clearing the pending register and re-enabling
|
||||
+ * servicing this interrupt.
|
||||
+ */
|
||||
+
|
||||
+ if ((pcf->suspend_state == PCF50633_SS_STARTING_SUSPEND) ||
|
||||
+ (pcf->suspend_state == PCF50633_SS_COMPLETED_SUSPEND))
|
||||
+ goto bail;
|
||||
+
|
||||
+ /*
|
||||
* If we are inside suspend -> resume completion time we don't attempt
|
||||
* service until we have fully resumed. Although we could talk to the
|
||||
* device as soon as I2C is up, the regs in the device which we might
|
||||
@@ -1154,8 +1180,9 @@ reschedule:
|
||||
/* EXCEPTION: if we are in the middle of suspending, we don't have
|
||||
* time to hang around since we may be turned off core 1V3 already
|
||||
*/
|
||||
- if (pcf->have_been_suspended != 1) {
|
||||
- msleep(50);
|
||||
+ if ((pcf->suspend_state != PCF50633_SS_STARTING_SUSPEND) &&
|
||||
+ (pcf->suspend_state != PCF50633_SS_COMPLETED_SUSPEND)) {
|
||||
+ msleep(10);
|
||||
dev_info(&pcf->client.dev, "rescheduling interrupt service\n");
|
||||
}
|
||||
if (!schedule_work(&pcf->work))
|
||||
@@ -2315,8 +2342,9 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
|
||||
|
||||
/* we suspend once (!) as late as possible in the suspend sequencing */
|
||||
|
||||
- if ((state.event != PM_EVENT_SUSPEND) || (pcf->have_been_suspended))
|
||||
- return 0;
|
||||
+ if ((state.event != PM_EVENT_SUSPEND) ||
|
||||
+ (pcf->suspend_state != PCF50633_SS_RUNNING))
|
||||
+ return -EBUSY;
|
||||
|
||||
/* The general idea is to power down all unused power supplies,
|
||||
* and then mask all PCF50633 interrupt sources but EXTONR, ONKEYF
|
||||
@@ -2380,7 +2408,7 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to set wake masks :-( %d\n", ret);
|
||||
|
||||
- pcf->have_been_suspended = 1;
|
||||
+ pcf->suspend_state = PCF50633_SS_COMPLETED_SUSPEND;
|
||||
|
||||
mutex_unlock(&pcf->lock);
|
||||
|
||||
@@ -2393,7 +2421,8 @@ int pcf50633_ready(struct pcf50633_data *pcf)
|
||||
if (!pcf)
|
||||
return -EACCES;
|
||||
|
||||
- if (pcf->have_been_suspended && (pcf->have_been_suspended < 3))
|
||||
+ if ((pcf->suspend_state != PCF50633_SS_RUNNING) &&
|
||||
+ (pcf->suspend_state < PCF50633_SS_COMPLETED_RESUME))
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
@@ -2428,10 +2457,10 @@ static int pcf50633_resume(struct device *dev)
|
||||
u8 res[5];
|
||||
|
||||
dev_info(dev, "pcf50633_resume suspended on entry = %d\n",
|
||||
- pcf->have_been_suspended);
|
||||
+ (int)pcf->suspend_state);
|
||||
mutex_lock(&pcf->lock);
|
||||
|
||||
- pcf->have_been_suspended = 2; /* resuming */
|
||||
+ pcf->suspend_state = PCF50633_SS_STARTING_RESUME;
|
||||
|
||||
/* these guys get reset while pcf50633 is suspend state, refresh */
|
||||
|
||||
@@ -2464,7 +2493,7 @@ static int pcf50633_resume(struct device *dev)
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to set int masks :-( %d\n", ret);
|
||||
|
||||
- pcf->have_been_suspended = 3; /* resume completed */
|
||||
+ pcf->suspend_state = PCF50633_SS_COMPLETED_RESUME;
|
||||
|
||||
mutex_unlock(&pcf->lock);
|
||||
|
||||
@@ -2498,6 +2527,21 @@ static struct i2c_driver pcf50633_driver = {
|
||||
.detach_client = pcf50633_detach_client,
|
||||
};
|
||||
|
||||
+/* we have this purely to capture an early indication that we are coming out
|
||||
+ * of suspend, before our device resume got called; async interrupt service is
|
||||
+ * interested in this
|
||||
+ */
|
||||
+
|
||||
+static int pcf50633_plat_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ /* i2c_get_clientdata(to_i2c_client(&pdev->dev)) returns NULL at this
|
||||
+ * early resume time so we have to use pcf50633_global
|
||||
+ */
|
||||
+ pcf50633_global->suspend_state = PCF50633_SS_RESUMING_BUT_NOT_US_YET;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* platform driver, since i2c devices don't have platform_data */
|
||||
static int __init pcf50633_plat_probe(struct platform_device *pdev)
|
||||
{
|
||||
@@ -2519,6 +2563,7 @@ static int pcf50633_plat_remove(struct platform_device *pdev)
|
||||
static struct platform_driver pcf50633_plat_driver = {
|
||||
.probe = pcf50633_plat_probe,
|
||||
.remove = pcf50633_plat_remove,
|
||||
+ .resume_early = pcf50633_plat_resume,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pcf50633",
|
||||
--
|
||||
1.5.6.3
|
||||
|
||||
Reference in New Issue
Block a user