diff options
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.24/1198-fix-pcf50633-suspend-state-as-enum.patch.patch')
-rw-r--r-- | target/linux/s3c24xx/patches-2.6.24/1198-fix-pcf50633-suspend-state-as-enum.patch.patch | 197 |
1 files changed, 0 insertions, 197 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.24/1198-fix-pcf50633-suspend-state-as-enum.patch.patch b/target/linux/s3c24xx/patches-2.6.24/1198-fix-pcf50633-suspend-state-as-enum.patch.patch deleted file mode 100644 index 9bae4491fb..0000000000 --- a/target/linux/s3c24xx/patches-2.6.24/1198-fix-pcf50633-suspend-state-as-enum.patch.patch +++ /dev/null @@ -1,197 +0,0 @@ -From dd7ff306b150c36950fa0f9dd718a1745a984d38 Mon Sep 17 00:00:00 2001 -From: Andy Green <andy@openmoko.com> -Date: Wed, 2 Jul 2008 22:41:38 +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 2e5981d..c014384 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 -@@ -1155,8 +1181,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)) -@@ -2322,8 +2349,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 -@@ -2387,7 +2415,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); - -@@ -2400,7 +2428,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; -@@ -2435,10 +2464,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 */ - -@@ -2471,7 +2500,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); - -@@ -2505,6 +2534,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) - { -@@ -2526,6 +2570,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.5 - |