Changeset 4057


Ignore:
Timestamp:
02/13/08 02:29:25 (5 years ago)
Author:
werner
Message:

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@…>

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(-)

Location:
branches/src/target/kernel/2.6.24.x/patches
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/src/target/kernel/2.6.24.x/patches/gta01-pcf50606.patch

    r4056 r4057  
    99--- /dev/null 
    1010+++ linux-2.6.24/drivers/i2c/chips/pcf50606.c 
    11 @@ -0,0 +1,1933 @@ 
     11@@ -0,0 +1,1941 @@ 
    1212+/* Philips/NXP PCF50606 Power Management Unit (PMU) driver 
    1313+ * 
     
    567567+       struct pcf50606_data *pcf = 
    568568+                       container_of(work, struct pcf50606_data, work); 
    569 +       u_int8_t int1, int2, int3; 
     569+       u_int8_t pcfirq[3]; 
     570+       int ret; 
    570571+ 
    571572+       mutex_lock(&pcf->working_lock); 
    572573+       pcf->working = 1; 
    573 + 
    574 +       int1 = __reg_read(pcf, PCF50606_REG_INT1); 
    575 +       int2 = __reg_read(pcf, PCF50606_REG_INT2); 
    576 +       int3 = __reg_read(pcf, PCF50606_REG_INT3); 
     574+       /* 
     575+        * p35 pcf50606 datasheet rev 2.2: 
     576+        * ''The system controller shall read all interrupt registers in 
     577+        *   one I2C read action'' 
     578+        * because if you don't INT# gets stuck asserted forever after a 
     579+        * while 
     580+        */ 
     581+       ret = i2c_smbus_read_i2c_block_data(&pcf->client, PCF50606_REG_INT1, 3, 
     582+                                           pcfirq); 
     583+       if (ret != 3) 
     584+               DEBUGPC("Oh crap PMU IRQ register read failed %d\n", ret); 
    577585+ 
    578586+       dev_dbg(&pcf->client.dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x:", 
    579 +               int1, int2, int3); 
    580 + 
    581 +       if (int1 & PCF50606_INT1_ONKEYF) { 
     587+               pcfirq[0], pcfirq[1], pcfirq[2]); 
     588+ 
     589+       if (pcfirq[0] & PCF50606_INT1_ONKEYF) { 
    582590+               /* ONKEY falling edge (start of button press) */ 
    583591+               DEBUGPC("ONKEYF "); 
     
    585593+               input_report_key(pcf->input_dev, KEY_POWER, 1); 
    586594+       } 
    587 +       if (int1 & PCF50606_INT1_ONKEY1S) { 
     595+       if (pcfirq[0] & PCF50606_INT1_ONKEY1S) { 
    588596+               /* ONKEY pressed for more than 1 second */ 
    589597+               pcf->onkey_seconds = 0; 
     
    596604+               reg_clear_bits(pcf, PCF50606_REG_INT1M, PCF50606_INT1_SECOND); 
    597605+       } 
    598 +       if (int1 & PCF50606_INT1_ONKEYR) { 
     606+       if (pcfirq[0] & PCF50606_INT1_ONKEYR) { 
    599607+               /* ONKEY rising edge (end of button press) */ 
    600608+               DEBUGPC("ONKEYR "); 
     
    609617+                                        PCF50606_INT1_SECOND); 
    610618+       } 
    611 +       if (int1 & PCF50606_INT1_EXTONR) { 
     619+       if (pcfirq[0] & PCF50606_INT1_EXTONR) { 
    612620+               DEBUGPC("EXTONR "); 
    613621+               input_report_key(pcf->input_dev, KEY_POWER2, 1); 
    614622+       } 
    615 +       if (int1 & PCF50606_INT1_EXTONF) { 
     623+       if (pcfirq[0] & PCF50606_INT1_EXTONF) { 
    616624+               DEBUGPC("EXTONF "); 
    617625+               input_report_key(pcf->input_dev, KEY_POWER2, 0); 
    618626+       } 
    619 +       if (int1 & PCF50606_INT1_SECOND) { 
     627+       if (pcfirq[0] & PCF50606_INT1_SECOND) { 
    620628+               DEBUGPC("SECOND "); 
    621629+               if (pcf->flags & PCF50606_F_RTC_SECOND) 
     
    639647+               } 
    640648+       } 
    641 +       if (int1 & PCF50606_INT1_ALARM) { 
     649+       if (pcfirq[0] & PCF50606_INT1_ALARM) { 
    642650+               DEBUGPC("ALARM "); 
    643651+               if (pcf->pdata->used_features & PCF50606_FEAT_RTC) 
     
    646654+       } 
    647655+ 
    648 +       if (int2 & PCF50606_INT2_CHGINS) { 
     656+       if (pcfirq[1] & PCF50606_INT2_CHGINS) { 
    649657+               /* Charger inserted */ 
    650658+               DEBUGPC("CHGINS "); 
     
    657665+               /* FIXME: how to signal this to userspace */ 
    658666+       } 
    659 +       if (int2 & PCF50606_INT2_CHGRM) { 
     667+       if (pcfirq[1] & PCF50606_INT2_CHGRM) { 
    660668+               /* Charger removed */ 
    661669+               DEBUGPC("CHGRM "); 
     
    668676+               /* FIXME: how signal this to userspace */ 
    669677+       } 
    670 +       if (int2 & PCF50606_INT2_CHGFOK) { 
     678+       if (pcfirq[1] & PCF50606_INT2_CHGFOK) { 
    671679+               /* Battery ready for fast charging */ 
    672680+               DEBUGPC("CHGFOK "); 
     
    674682+               /* FIXME: how to signal this to userspace */ 
    675683+       } 
    676 +       if (int2 & PCF50606_INT2_CHGERR) { 
     684+       if (pcfirq[1] & PCF50606_INT2_CHGERR) { 
    677685+               /* Error in charge mode */ 
    678686+               DEBUGPC("CHGERR "); 
     
    681689+               /* FIXME: how to signal this to userspace */ 
    682690+       } 
    683 +       if (int2 & PCF50606_INT2_CHGFRDY) { 
     691+       if (pcfirq[1] & PCF50606_INT2_CHGFRDY) { 
    684692+               /* Fast charge completed */ 
    685693+               DEBUGPC("CHGFRDY "); 
     
    688696+               /* FIXME: how to signal this to userspace */ 
    689697+       } 
    690 +       if (int2 & PCF50606_INT2_CHGPROT) { 
     698+       if (pcfirq[1] & PCF50606_INT2_CHGPROT) { 
    691699+               /* Charging protection interrupt */ 
    692700+               DEBUGPC("CHGPROT "); 
     
    694702+               /* FIXME: signal this to userspace */ 
    695703+       } 
    696 +       if (int2 & PCF50606_INT2_CHGWD10S) { 
     704+       if (pcfirq[1] & PCF50606_INT2_CHGWD10S) { 
    697705+               /* Charger watchdog will expire in 10 seconds */ 
    698706+               DEBUGPC("CHGWD10S "); 
     
    701709+                                PCF50606_OOCC1_WDTRST); 
    702710+       } 
    703 +       if (int2 & PCF50606_INT2_CHGWDEXP) { 
     711+       if (pcfirq[1] & PCF50606_INT2_CHGWDEXP) { 
    704712+               /* Charger watchdog expires */ 
    705713+               DEBUGPC("CHGWDEXP "); 
     
    707715+       } 
    708716+ 
    709 +       if (int3 & PCF50606_INT3_ADCRDY) { 
     717+       if (pcfirq[2] & PCF50606_INT3_ADCRDY) { 
    710718+               /* ADC result ready */ 
    711719+               DEBUGPC("ADCRDY "); 
    712720+       } 
    713 +       if (int3 & PCF50606_INT3_ACDINS) { 
     721+       if (pcfirq[2] & PCF50606_INT3_ACDINS) { 
    714722+               /* Accessory insertion detected */ 
    715723+               DEBUGPC("ACDINS "); 
     
    718726+                                      PCF50606_FEAT_ACD, PMU_EVT_INSERT); 
    719727+       } 
    720 +       if (int3 & PCF50606_INT3_ACDREM) { 
     728+       if (pcfirq[2] & PCF50606_INT3_ACDREM) { 
    721729+               /* Accessory removal detected */ 
    722730+               DEBUGPC("ACDREM "); 
     
    726734+       } 
    727735+       /* FIXME: TSCPRES */ 
    728 +       if (int3 & PCF50606_INT3_LOWBAT) { 
     736+       if (pcfirq[2] & PCF50606_INT3_LOWBAT) { 
    729737+               /* Really low battery voltage, we have 8 seconds left */ 
    730738+               DEBUGPC("LOWBAT "); 
     
    737745+                                PCF50606_OOCC1_TOTRST); 
    738746+       } 
    739 +       if (int3 & PCF50606_INT3_HIGHTMP) { 
     747+       if (pcfirq[2] & PCF50606_INT3_HIGHTMP) { 
    740748+               /* High temperature */ 
    741749+               DEBUGPC("HIGHTMP "); 
  • branches/src/target/kernel/2.6.24.x/patches/pcf50633.patch

    r4056 r4057  
    3535--- /dev/null 
    3636+++ linux-2.6.24/drivers/i2c/chips/pcf50633.c 
    37 @@ -0,0 +1,1789 @@ 
     37@@ -0,0 +1,1791 @@ 
    3838+/* Philips PCF50633 Power Management Unit (PMU) driver 
    3939+ * 
     
    527527+       struct pcf50633_data *pcf = 
    528528+                       container_of(work, struct pcf50633_data, work); 
    529 +       u_int8_t int1, int2, int3, int4, int5; 
     529+       u_int8_t pcfirq[5]; 
     530+       int ret; 
    530531+ 
    531532+       mutex_lock(&pcf->working_lock); 
    532533+       pcf->working = 1; 
    533 + 
    534 +       /* FIXME: read in one i2c transaction */ 
    535 +       int1 = __reg_read(pcf, PCF50633_REG_INT1); 
    536 +       int2 = __reg_read(pcf, PCF50633_REG_INT2); 
    537 +       int3 = __reg_read(pcf, PCF50633_REG_INT3); 
    538 +       int4 = __reg_read(pcf, PCF50633_REG_INT4); 
    539 +       int5 = __reg_read(pcf, PCF50633_REG_INT5); 
     534+       /* 
     535+        * datasheet says we have to read the five IRQ 
     536+        * status regs in one transaction 
     537+        */ 
     538+       ret = i2c_smbus_read_i2c_block_data(&pcf->client, PCF50633_REG_INT1, 5, 
     539+                                           pcfirq); 
     540+       if (ret != 5) 
     541+               DEBUGP("Oh crap PMU IRQ register read failed %d\n", ret); 
    540542+ 
    541543+       DEBUGP("INT1=0x%02x INT2=0x%02x INT3=0x%02x INT4=0x%02x INT5=0x%02x\n", 
    542 +               int1, int2, int3, int4, int5); 
    543 + 
    544 +       if (int1 & PCF50633_INT1_ADPINS) { 
     544+               pcfirq[0], pcfirq[1], pcfirq[2], pcfirq[3], pcfirq[4]); 
     545+ 
     546+       if (pcfirq[0] & PCF50633_INT1_ADPINS) { 
    545547+               /* Charger inserted */ 
    546548+               DEBUGPC("ADPINS "); 
     
    554556+               //kobject_uevent( ,KOBJ_ADD); 
    555557+       } 
    556 +       if (int1 & PCF50633_INT1_ADPREM) { 
     558+       if (pcfirq[0] & PCF50633_INT1_ADPREM) { 
    557559+               /* Charger removed */ 
    558560+               DEBUGPC("ADPREM "); 
     
    566568+               //kobject_uevent( ,KOBJ_ADD); 
    567569+       } 
    568 +       if (int1 & PCF50633_INT1_USBINS) { 
     570+       if (pcfirq[0] & PCF50633_INT1_USBINS) { 
    569571+               DEBUGPC("USBINS "); 
    570572+               input_report_key(pcf->input_dev, KEY_POWER2, 1); 
     
    576578+ 
    577579+       } 
    578 +       if (int1 & PCF50633_INT1_USBREM) { 
     580+       if (pcfirq[0] & PCF50633_INT1_USBREM) { 
    579581+               DEBUGPC("USBREM "); 
    580582+               input_report_key(pcf->input_dev, KEY_POWER2, 0); 
     
    585587+                                      PCF50633_FEAT_MBC, PMU_EVT_USB_REMOVE); 
    586588+       } 
    587 +       if (int1 & PCF50633_INT1_ALARM) { 
     589+       if (pcfirq[0] & PCF50633_INT1_ALARM) { 
    588590+               DEBUGPC("ALARM "); 
    589591+               if (pcf->pdata->used_features & PCF50633_FEAT_RTC) 
     
    591593+                                      RTC_AF | RTC_IRQF); 
    592594+       } 
    593 +       if (int1 & PCF50633_INT1_SECOND) { 
     595+       if (pcfirq[0] & PCF50633_INT1_SECOND) { 
    594596+               DEBUGPC("SECOND "); 
    595597+               if (pcf->flags & PCF50633_F_RTC_SECOND) 
     
    613615+       } 
    614616+ 
    615 +       if (int2 & PCF50633_INT2_ONKEYF) { 
     617+       if (pcfirq[1] & PCF50633_INT2_ONKEYF) { 
    616618+               /* ONKEY falling edge (start of button press) */ 
    617619+               DEBUGPC("ONKEYF "); 
     
    619621+               input_report_key(pcf->input_dev, KEY_POWER, 1); 
    620622+       } 
    621 +       if (int2 & PCF50633_INT2_ONKEYR) { 
     623+       if (pcfirq[1] & PCF50633_INT2_ONKEYR) { 
    622624+               /* ONKEY rising edge (end of button press) */ 
    623625+               DEBUGPC("ONKEYR "); 
     
    634636+       /* FIXME: we don't use EXTON1/2/3. thats why we skip it */ 
    635637+ 
    636 +       if (int3 & PCF50633_INT3_BATFULL) { 
     638+       if (pcfirq[2] & PCF50633_INT3_BATFULL) { 
    637639+               DEBUGPC("BATFULL "); 
    638640+               /* FIXME: signal this to userspace */ 
    639641+       } 
    640 +       if (int3 & PCF50633_INT3_CHGHALT) { 
     642+       if (pcfirq[2] & PCF50633_INT3_CHGHALT) { 
    641643+               DEBUGPC("CHGHALT "); 
    642644+               /* FIXME: signal this to userspace */ 
    643645+       } 
    644 +       if (int3 & PCF50633_INT3_THLIMON) { 
     646+       if (pcfirq[2] & PCF50633_INT3_THLIMON) { 
    645647+               DEBUGPC("THLIMON "); 
    646648+               pcf->flags |= PCF50633_F_CHG_PROT; 
    647649+               /* FIXME: signal this to userspace */ 
    648650+       } 
    649 +       if (int3 & PCF50633_INT3_THLIMOFF) { 
     651+       if (pcfirq[2] & PCF50633_INT3_THLIMOFF) { 
    650652+               DEBUGPC("THLIMOFF "); 
    651653+               pcf->flags &= ~PCF50633_F_CHG_PROT; 
    652654+               /* FIXME: signal this to userspace */ 
    653655+       } 
    654 +       if (int3 & PCF50633_INT3_USBLIMON) { 
     656+       if (pcfirq[2] & PCF50633_INT3_USBLIMON) { 
    655657+               DEBUGPC("USBLIMON "); 
    656658+               /* FIXME: signal this to userspace */ 
    657659+       } 
    658 +       if (int3 & PCF50633_INT3_USBLIMOFF) { 
     660+       if (pcfirq[2] & PCF50633_INT3_USBLIMOFF) { 
    659661+               DEBUGPC("USBLIMOFF "); 
    660662+               /* FIXME: signal this to userspace */ 
    661663+       } 
    662 +       if (int3 & PCF50633_INT3_ADCRDY) { 
     664+       if (pcfirq[2] & PCF50633_INT3_ADCRDY) { 
    663665+               /* ADC result ready */ 
    664666+               DEBUGPC("ADCRDY "); 
    665667+       } 
    666 +       if (int3 & PCF50633_INT3_ONKEY1S) { 
     668+       if (pcfirq[2] & PCF50633_INT3_ONKEY1S) { 
    667669+               /* ONKEY pressed for more than 1 second */ 
    668670+               pcf->onkey_seconds = 0; 
     
    676678+       } 
    677679+ 
    678 +       if (int4 & (PCF50633_INT4_LOWBAT|PCF50633_INT4_LOWSYS)) { 
     680+       if (pcfirq[3] & (PCF50633_INT4_LOWBAT|PCF50633_INT4_LOWSYS)) { 
    679681+               /* Really low battery voltage, we have 8 seconds left */ 
    680682+               DEBUGPC("LOWBAT "); 
     
    687689+                                PCF50633_OOCSHDWN_TOTRST); 
    688690+       } 
    689 +       if (int4 & PCF50633_INT4_HIGHTMP) { 
     691+       if (pcfirq[3] & PCF50633_INT4_HIGHTMP) { 
    690692+               /* High temperature */ 
    691693+               DEBUGPC("HIGHTMP "); 
    692694+               apm_queue_event(APM_CRITICAL_SUSPEND); 
    693695+       } 
    694 +       if (int4 & (PCF50633_INT4_AUTOPWRFAIL|PCF50633_INT4_DWN1PWRFAIL| 
     696+       if (pcfirq[3] & (PCF50633_INT4_AUTOPWRFAIL|PCF50633_INT4_DWN1PWRFAIL| 
    695697+                  PCF50633_INT4_DWN2PWRFAIL|PCF50633_INT4_LEDPWRFAIL| 
    696698+                  PCF50633_INT4_LEDOVP)) { 
  • branches/src/target/kernel/2.6.24.x/patches/series

    r4054 r4057  
    9696 
    9797# this may not be the last word on this issue, but the patch certainly helps 
    98 fix-pcf50633-LOWBAT-kill-init.patch 
     98# backed out temporarily since the patch fails and there's a new version of 
     99# this just around the corner anyway 
     100##fix-pcf50633-LOWBAT-kill-init.patch 
    99101 
    100102# temporary work-around. awaiting decision on correct fix from upstream. 
Note: See TracChangeset for help on using the changeset viewer.