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