r4057 - branches/src/target/kernel/2.6.24.x/patches
werner at sita.openmoko.org
werner at sita.openmoko.org
Wed Feb 13 02:29:30 CET 2008
Author: werner
Date: 2008-02-13 02:29:25 +0100 (Wed, 13 Feb 2008)
New Revision: 4057
Modified:
branches/src/target/kernel/2.6.24.x/patches/gta01-pcf50606.patch
branches/src/target/kernel/2.6.24.x/patches/pcf50633.patch
branches/src/target/kernel/2.6.24.x/patches/series
Log:
fix-pcf50606-atomic-i2c-int-read.patch
fix-pcf50633-atomic-i2c-int-read.patch
Datasheet says reading the interrupt source regs (and thereby
clearing them) must be done in a single i2c read transaction
Signed-off-by: Andy Green <andy at openmoko.com>
series: temporarily backed out fix-pcf50633-LOWBAT-kill-init.patch, since it
conflicts with these patches, and since there's a new version of it in the
queue already, there's no point in fixing it now
---
drivers/i2c/chips/pcf50606.c | 60 ++++++++++++++++++++++++------------------
1 files changed, 34 insertions(+), 26 deletions(-)
drivers/i2c/chips/pcf50633.c | 58 ++++++++++++++++++++++--------------------
1 files changed, 30 insertions(+), 28 deletions(-)
Modified: branches/src/target/kernel/2.6.24.x/patches/gta01-pcf50606.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/gta01-pcf50606.patch 2008-02-13 01:18:47 UTC (rev 4056)
+++ branches/src/target/kernel/2.6.24.x/patches/gta01-pcf50606.patch 2008-02-13 01:29:25 UTC (rev 4057)
@@ -8,7 +8,7 @@
===================================================================
--- /dev/null
+++ linux-2.6.24/drivers/i2c/chips/pcf50606.c
-@@ -0,0 +1,1933 @@
+@@ -0,0 +1,1941 @@
+/* Philips/NXP PCF50606 Power Management Unit (PMU) driver
+ *
+ * (C) 2006-2007 by OpenMoko, Inc.
@@ -566,25 +566,33 @@
+{
+ struct pcf50606_data *pcf =
+ container_of(work, struct pcf50606_data, work);
-+ u_int8_t int1, int2, int3;
++ u_int8_t pcfirq[3];
++ int ret;
+
+ mutex_lock(&pcf->working_lock);
+ pcf->working = 1;
++ /*
++ * p35 pcf50606 datasheet rev 2.2:
++ * ''The system controller shall read all interrupt registers in
++ * one I2C read action''
++ * because if you don't INT# gets stuck asserted forever after a
++ * while
++ */
++ ret = i2c_smbus_read_i2c_block_data(&pcf->client, PCF50606_REG_INT1, 3,
++ pcfirq);
++ if (ret != 3)
++ DEBUGPC("Oh crap PMU IRQ register read failed %d\n", ret);
+
-+ int1 = __reg_read(pcf, PCF50606_REG_INT1);
-+ int2 = __reg_read(pcf, PCF50606_REG_INT2);
-+ int3 = __reg_read(pcf, PCF50606_REG_INT3);
-+
+ dev_dbg(&pcf->client.dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x:",
-+ int1, int2, int3);
++ pcfirq[0], pcfirq[1], pcfirq[2]);
+
-+ if (int1 & PCF50606_INT1_ONKEYF) {
++ if (pcfirq[0] & PCF50606_INT1_ONKEYF) {
+ /* ONKEY falling edge (start of button press) */
+ DEBUGPC("ONKEYF ");
+ pcf->flags |= PCF50606_F_PWR_PRESSED;
+ input_report_key(pcf->input_dev, KEY_POWER, 1);
+ }
-+ if (int1 & PCF50606_INT1_ONKEY1S) {
++ if (pcfirq[0] & PCF50606_INT1_ONKEY1S) {
+ /* ONKEY pressed for more than 1 second */
+ pcf->onkey_seconds = 0;
+ DEBUGPC("ONKEY1S ");
@@ -595,7 +603,7 @@
+ /* enable SECOND interrupt (hz tick) */
+ reg_clear_bits(pcf, PCF50606_REG_INT1M, PCF50606_INT1_SECOND);
+ }
-+ if (int1 & PCF50606_INT1_ONKEYR) {
++ if (pcfirq[0] & PCF50606_INT1_ONKEYR) {
+ /* ONKEY rising edge (end of button press) */
+ DEBUGPC("ONKEYR ");
+ pcf->flags &= ~PCF50606_F_PWR_PRESSED;
@@ -608,15 +616,15 @@
+ PCF50606_INT1_SECOND,
+ PCF50606_INT1_SECOND);
+ }
-+ if (int1 & PCF50606_INT1_EXTONR) {
++ if (pcfirq[0] & PCF50606_INT1_EXTONR) {
+ DEBUGPC("EXTONR ");
+ input_report_key(pcf->input_dev, KEY_POWER2, 1);
+ }
-+ if (int1 & PCF50606_INT1_EXTONF) {
++ if (pcfirq[0] & PCF50606_INT1_EXTONF) {
+ DEBUGPC("EXTONF ");
+ input_report_key(pcf->input_dev, KEY_POWER2, 0);
+ }
-+ if (int1 & PCF50606_INT1_SECOND) {
++ if (pcfirq[0] & PCF50606_INT1_SECOND) {
+ DEBUGPC("SECOND ");
+ if (pcf->flags & PCF50606_F_RTC_SECOND)
+ rtc_update_irq(pcf->rtc, 1,
@@ -638,14 +646,14 @@
+ }
+ }
+ }
-+ if (int1 & PCF50606_INT1_ALARM) {
++ if (pcfirq[0] & PCF50606_INT1_ALARM) {
+ DEBUGPC("ALARM ");
+ if (pcf->pdata->used_features & PCF50606_FEAT_RTC)
+ rtc_update_irq(pcf->rtc, 1,
+ RTC_AF | RTC_IRQF);
+ }
+
-+ if (int2 & PCF50606_INT2_CHGINS) {
++ if (pcfirq[1] & PCF50606_INT2_CHGINS) {
+ /* Charger inserted */
+ DEBUGPC("CHGINS ");
+ input_report_key(pcf->input_dev, KEY_BATTERY, 1);
@@ -656,7 +664,7 @@
+ PCF50606_FEAT_MBC, PMU_EVT_INSERT);
+ /* FIXME: how to signal this to userspace */
+ }
-+ if (int2 & PCF50606_INT2_CHGRM) {
++ if (pcfirq[1] & PCF50606_INT2_CHGRM) {
+ /* Charger removed */
+ DEBUGPC("CHGRM ");
+ input_report_key(pcf->input_dev, KEY_BATTERY, 0);
@@ -667,57 +675,57 @@
+ PCF50606_FEAT_MBC, PMU_EVT_INSERT);
+ /* FIXME: how signal this to userspace */
+ }
-+ if (int2 & PCF50606_INT2_CHGFOK) {
++ if (pcfirq[1] & PCF50606_INT2_CHGFOK) {
+ /* Battery ready for fast charging */
+ DEBUGPC("CHGFOK ");
+ pcf->flags |= PCF50606_F_CHG_FOK;
+ /* FIXME: how to signal this to userspace */
+ }
-+ if (int2 & PCF50606_INT2_CHGERR) {
++ if (pcfirq[1] & PCF50606_INT2_CHGERR) {
+ /* Error in charge mode */
+ DEBUGPC("CHGERR ");
+ pcf->flags |= PCF50606_F_CHG_ERR;
+ pcf->flags &= ~(PCF50606_F_CHG_FOK|PCF50606_F_CHG_READY);
+ /* FIXME: how to signal this to userspace */
+ }
-+ if (int2 & PCF50606_INT2_CHGFRDY) {
++ if (pcfirq[1] & PCF50606_INT2_CHGFRDY) {
+ /* Fast charge completed */
+ DEBUGPC("CHGFRDY ");
+ pcf->flags |= PCF50606_F_CHG_READY;
+ pcf->flags &= ~PCF50606_F_CHG_FOK;
+ /* FIXME: how to signal this to userspace */
+ }
-+ if (int2 & PCF50606_INT2_CHGPROT) {
++ if (pcfirq[1] & PCF50606_INT2_CHGPROT) {
+ /* Charging protection interrupt */
+ DEBUGPC("CHGPROT ");
+ pcf->flags &= ~(PCF50606_F_CHG_FOK|PCF50606_F_CHG_READY);
+ /* FIXME: signal this to userspace */
+ }
-+ if (int2 & PCF50606_INT2_CHGWD10S) {
++ if (pcfirq[1] & PCF50606_INT2_CHGWD10S) {
+ /* Charger watchdog will expire in 10 seconds */
+ DEBUGPC("CHGWD10S ");
+ reg_set_bit_mask(pcf, PCF50606_REG_OOCC1,
+ PCF50606_OOCC1_WDTRST,
+ PCF50606_OOCC1_WDTRST);
+ }
-+ if (int2 & PCF50606_INT2_CHGWDEXP) {
++ if (pcfirq[1] & PCF50606_INT2_CHGWDEXP) {
+ /* Charger watchdog expires */
+ DEBUGPC("CHGWDEXP ");
+ /* FIXME: how to signal this to userspace */
+ }
+
-+ if (int3 & PCF50606_INT3_ADCRDY) {
++ if (pcfirq[2] & PCF50606_INT3_ADCRDY) {
+ /* ADC result ready */
+ DEBUGPC("ADCRDY ");
+ }
-+ if (int3 & PCF50606_INT3_ACDINS) {
++ if (pcfirq[2] & PCF50606_INT3_ACDINS) {
+ /* Accessory insertion detected */
+ DEBUGPC("ACDINS ");
+ if (pcf->pdata->cb)
+ pcf->pdata->cb(&pcf->client.dev,
+ PCF50606_FEAT_ACD, PMU_EVT_INSERT);
+ }
-+ if (int3 & PCF50606_INT3_ACDREM) {
++ if (pcfirq[2] & PCF50606_INT3_ACDREM) {
+ /* Accessory removal detected */
+ DEBUGPC("ACDREM ");
+ if (pcf->pdata->cb)
@@ -725,7 +733,7 @@
+ PCF50606_FEAT_ACD, PMU_EVT_REMOVE);
+ }
+ /* FIXME: TSCPRES */
-+ if (int3 & PCF50606_INT3_LOWBAT) {
++ if (pcfirq[2] & PCF50606_INT3_LOWBAT) {
+ /* Really low battery voltage, we have 8 seconds left */
+ DEBUGPC("LOWBAT ");
+ apm_queue_event(APM_LOW_BATTERY);
@@ -736,7 +744,7 @@
+ PCF50606_OOCC1_TOTRST,
+ PCF50606_OOCC1_TOTRST);
+ }
-+ if (int3 & PCF50606_INT3_HIGHTMP) {
++ if (pcfirq[2] & PCF50606_INT3_HIGHTMP) {
+ /* High temperature */
+ DEBUGPC("HIGHTMP ");
+ apm_queue_event(APM_CRITICAL_SUSPEND);
Modified: branches/src/target/kernel/2.6.24.x/patches/pcf50633.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/pcf50633.patch 2008-02-13 01:18:47 UTC (rev 4056)
+++ branches/src/target/kernel/2.6.24.x/patches/pcf50633.patch 2008-02-13 01:29:25 UTC (rev 4057)
@@ -34,7 +34,7 @@
===================================================================
--- /dev/null
+++ linux-2.6.24/drivers/i2c/chips/pcf50633.c
-@@ -0,0 +1,1789 @@
+@@ -0,0 +1,1791 @@
+/* Philips PCF50633 Power Management Unit (PMU) driver
+ *
+ * (C) 2006-2007 by OpenMoko, Inc.
@@ -526,22 +526,24 @@
+{
+ struct pcf50633_data *pcf =
+ container_of(work, struct pcf50633_data, work);
-+ u_int8_t int1, int2, int3, int4, int5;
++ u_int8_t pcfirq[5];
++ int ret;
+
+ mutex_lock(&pcf->working_lock);
+ pcf->working = 1;
++ /*
++ * datasheet says we have to read the five IRQ
++ * status regs in one transaction
++ */
++ ret = i2c_smbus_read_i2c_block_data(&pcf->client, PCF50633_REG_INT1, 5,
++ pcfirq);
++ if (ret != 5)
++ DEBUGP("Oh crap PMU IRQ register read failed %d\n", ret);
+
-+ /* FIXME: read in one i2c transaction */
-+ int1 = __reg_read(pcf, PCF50633_REG_INT1);
-+ int2 = __reg_read(pcf, PCF50633_REG_INT2);
-+ int3 = __reg_read(pcf, PCF50633_REG_INT3);
-+ int4 = __reg_read(pcf, PCF50633_REG_INT4);
-+ int5 = __reg_read(pcf, PCF50633_REG_INT5);
-+
+ DEBUGP("INT1=0x%02x INT2=0x%02x INT3=0x%02x INT4=0x%02x INT5=0x%02x\n",
-+ int1, int2, int3, int4, int5);
++ pcfirq[0], pcfirq[1], pcfirq[2], pcfirq[3], pcfirq[4]);
+
-+ if (int1 & PCF50633_INT1_ADPINS) {
++ if (pcfirq[0] & PCF50633_INT1_ADPINS) {
+ /* Charger inserted */
+ DEBUGPC("ADPINS ");
+ input_report_key(pcf->input_dev, KEY_BATTERY, 1);
@@ -553,7 +555,7 @@
+ /* FIXME: signal this to userspace */
+ //kobject_uevent( ,KOBJ_ADD);
+ }
-+ if (int1 & PCF50633_INT1_ADPREM) {
++ if (pcfirq[0] & PCF50633_INT1_ADPREM) {
+ /* Charger removed */
+ DEBUGPC("ADPREM ");
+ input_report_key(pcf->input_dev, KEY_BATTERY, 0);
@@ -565,7 +567,7 @@
+ /* FIXME: signal this to userspace */
+ //kobject_uevent( ,KOBJ_ADD);
+ }
-+ if (int1 & PCF50633_INT1_USBINS) {
++ if (pcfirq[0] & PCF50633_INT1_USBINS) {
+ DEBUGPC("USBINS ");
+ input_report_key(pcf->input_dev, KEY_POWER2, 1);
+ apm_queue_event(APM_POWER_STATUS_CHANGE);
@@ -575,7 +577,7 @@
+ PCF50633_FEAT_MBC, PMU_EVT_USB_INSERT);
+
+ }
-+ if (int1 & PCF50633_INT1_USBREM) {
++ if (pcfirq[0] & PCF50633_INT1_USBREM) {
+ DEBUGPC("USBREM ");
+ input_report_key(pcf->input_dev, KEY_POWER2, 0);
+ apm_queue_event(APM_POWER_STATUS_CHANGE);
@@ -584,13 +586,13 @@
+ pcf->pdata->cb(&pcf->client.dev,
+ PCF50633_FEAT_MBC, PMU_EVT_USB_REMOVE);
+ }
-+ if (int1 & PCF50633_INT1_ALARM) {
++ if (pcfirq[0] & PCF50633_INT1_ALARM) {
+ DEBUGPC("ALARM ");
+ if (pcf->pdata->used_features & PCF50633_FEAT_RTC)
+ rtc_update_irq(pcf->rtc, 1,
+ RTC_AF | RTC_IRQF);
+ }
-+ if (int1 & PCF50633_INT1_SECOND) {
++ if (pcfirq[0] & PCF50633_INT1_SECOND) {
+ DEBUGPC("SECOND ");
+ if (pcf->flags & PCF50633_F_RTC_SECOND)
+ rtc_update_irq(pcf->rtc, 1,
@@ -612,13 +614,13 @@
+ }
+ }
+
-+ if (int2 & PCF50633_INT2_ONKEYF) {
++ if (pcfirq[1] & PCF50633_INT2_ONKEYF) {
+ /* ONKEY falling edge (start of button press) */
+ DEBUGPC("ONKEYF ");
+ pcf->flags |= PCF50633_F_PWR_PRESSED;
+ input_report_key(pcf->input_dev, KEY_POWER, 1);
+ }
-+ if (int2 & PCF50633_INT2_ONKEYR) {
++ if (pcfirq[1] & PCF50633_INT2_ONKEYR) {
+ /* ONKEY rising edge (end of button press) */
+ DEBUGPC("ONKEYR ");
+ pcf->flags &= ~PCF50633_F_PWR_PRESSED;
@@ -633,37 +635,37 @@
+ }
+ /* FIXME: we don't use EXTON1/2/3. thats why we skip it */
+
-+ if (int3 & PCF50633_INT3_BATFULL) {
++ if (pcfirq[2] & PCF50633_INT3_BATFULL) {
+ DEBUGPC("BATFULL ");
+ /* FIXME: signal this to userspace */
+ }
-+ if (int3 & PCF50633_INT3_CHGHALT) {
++ if (pcfirq[2] & PCF50633_INT3_CHGHALT) {
+ DEBUGPC("CHGHALT ");
+ /* FIXME: signal this to userspace */
+ }
-+ if (int3 & PCF50633_INT3_THLIMON) {
++ if (pcfirq[2] & PCF50633_INT3_THLIMON) {
+ DEBUGPC("THLIMON ");
+ pcf->flags |= PCF50633_F_CHG_PROT;
+ /* FIXME: signal this to userspace */
+ }
-+ if (int3 & PCF50633_INT3_THLIMOFF) {
++ if (pcfirq[2] & PCF50633_INT3_THLIMOFF) {
+ DEBUGPC("THLIMOFF ");
+ pcf->flags &= ~PCF50633_F_CHG_PROT;
+ /* FIXME: signal this to userspace */
+ }
-+ if (int3 & PCF50633_INT3_USBLIMON) {
++ if (pcfirq[2] & PCF50633_INT3_USBLIMON) {
+ DEBUGPC("USBLIMON ");
+ /* FIXME: signal this to userspace */
+ }
-+ if (int3 & PCF50633_INT3_USBLIMOFF) {
++ if (pcfirq[2] & PCF50633_INT3_USBLIMOFF) {
+ DEBUGPC("USBLIMOFF ");
+ /* FIXME: signal this to userspace */
+ }
-+ if (int3 & PCF50633_INT3_ADCRDY) {
++ if (pcfirq[2] & PCF50633_INT3_ADCRDY) {
+ /* ADC result ready */
+ DEBUGPC("ADCRDY ");
+ }
-+ if (int3 & PCF50633_INT3_ONKEY1S) {
++ if (pcfirq[2] & PCF50633_INT3_ONKEY1S) {
+ /* ONKEY pressed for more than 1 second */
+ pcf->onkey_seconds = 0;
+ DEBUGPC("ONKEY1S ");
@@ -675,7 +677,7 @@
+ reg_clear_bits(pcf, PCF50633_REG_INT1M, PCF50633_INT1_SECOND);
+ }
+
-+ if (int4 & (PCF50633_INT4_LOWBAT|PCF50633_INT4_LOWSYS)) {
++ if (pcfirq[3] & (PCF50633_INT4_LOWBAT|PCF50633_INT4_LOWSYS)) {
+ /* Really low battery voltage, we have 8 seconds left */
+ DEBUGPC("LOWBAT ");
+ apm_queue_event(APM_LOW_BATTERY);
@@ -686,12 +688,12 @@
+ PCF50633_OOCSHDWN_TOTRST,
+ PCF50633_OOCSHDWN_TOTRST);
+ }
-+ if (int4 & PCF50633_INT4_HIGHTMP) {
++ if (pcfirq[3] & PCF50633_INT4_HIGHTMP) {
+ /* High temperature */
+ DEBUGPC("HIGHTMP ");
+ apm_queue_event(APM_CRITICAL_SUSPEND);
+ }
-+ if (int4 & (PCF50633_INT4_AUTOPWRFAIL|PCF50633_INT4_DWN1PWRFAIL|
++ if (pcfirq[3] & (PCF50633_INT4_AUTOPWRFAIL|PCF50633_INT4_DWN1PWRFAIL|
+ PCF50633_INT4_DWN2PWRFAIL|PCF50633_INT4_LEDPWRFAIL|
+ PCF50633_INT4_LEDOVP)) {
+ /* Some regulator failed */
Modified: branches/src/target/kernel/2.6.24.x/patches/series
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/series 2008-02-13 01:18:47 UTC (rev 4056)
+++ branches/src/target/kernel/2.6.24.x/patches/series 2008-02-13 01:29:25 UTC (rev 4057)
@@ -95,7 +95,9 @@
fix-hwecc-2410.patch
# this may not be the last word on this issue, but the patch certainly helps
-fix-pcf50633-LOWBAT-kill-init.patch
+# backed out temporarily since the patch fails and there's a new version of
+# this just around the corner anyway
+##fix-pcf50633-LOWBAT-kill-init.patch
# temporary work-around. awaiting decision on correct fix from upstream.
gta01-dehang-printk.patch
More information about the commitlog
mailing list