On Fri, 13 May 2011 16:22:18 +0800 <[email protected]> wrote: > If over battery charge current is detected, Renesas PMIC will trigger > an interrupt and reduce charger current automatically. > Do nothing when this interrupt is triggered, and log once in > pmic_battery_read_status(). > There is a new bug report shows over current interrupt storm. https://bugzilla.otcshare.org/show_bug.cgi?id=9887 Put the hw side of the cause aside, I think we should make battery charging event log a debug feature only. e.g. add a module parameters to turn it on if needed, otherwise it should be masked off. There is nothing OS can do to prevent charging over current. As you mentioned, PMIC HW does current and thermal overload protection.
> Adapter detection will be done in adapter detection interrupt handler, > and will also be checked in pmic_battery_read_status(). > Add adapter detection in pmic_battery_read_status(). > > Signed-off-by: Major Lee <[email protected]> > --- > > --- linux-2.6.37.bak/drivers/power/intel_mid_battery.c > 2011-05-12 11:57:59.840232580 +0800 > +++ linux-2.6.37/drivers/power/intel_mid_battery.c 2011-05-13 > 15:50:52.421875000 +0800 > @@ -97,6 +97,8 @@ struct pmic_power_module_info { > unsigned int batt_prev_charge_full; /* in mAS */ > unsigned int batt_charge_rate; /* in units > per second */ > > + bool dclmt_excpt_log_flag; > + > struct power_supply usb; > struct power_supply batt; > int irq; /* GPE_ID or IRQ# */ > @@ -291,10 +293,13 @@ static void pmic_battery_read_status(str > pmic_battery_log_event(BATT_EVENT_BATOVP_EXCPT); > batt_exception = 1; > } else if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) { > - pbi->batt_health = > POWER_SUPPLY_HEALTH_OVERVOLTAGE; > - pbi->batt_status = > POWER_SUPPLY_STATUS_NOT_CHARGING; > - > pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT); > - batt_exception = 1; > + pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD; > + if (!pbi->dclmt_excpt_log_flag) { > + /* if over current is detected, log > once */ > + > pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT); > + pbi->dclmt_excpt_log_flag = 1; > + } > + batt_exception = 0; > } else if (r8 & PMIC_BATT_CHR_STEMP_MASK) { > pbi->batt_health = > POWER_SUPPLY_HEALTH_OVERHEAT; pbi->batt_status = > POWER_SUPPLY_STATUS_NOT_CHARGING; > @@ -306,7 +311,7 @@ static void pmic_battery_read_status(str > } > > /* set usb_is_present */ > - if (r8 & PMIC_BATT_CHR_SUSBDET_MASK) { > + if ((r8 & PMIC_BATT_CHR_SUSBDET_MASK) || > gpio_get_value(PMIC_GPIO_0)) { > pbi->usb_is_present = PMIC_USB_PRESENT; > usb_present = 1; > } else { > @@ -509,6 +514,7 @@ static void pmic_adaptor_handle_intrpt(s > > if (val) { > pbi->usb_is_present = PMIC_USB_PRESENT; > + pbi->dclmt_excpt_log_flag = 0; > } else { > pbi->usb_is_present = PMIC_USB_NOT_PRESENT; > pbi->usb_health = POWER_SUPPLY_HEALTH_UNKNOWN; > @@ -553,6 +559,12 @@ static void pmic_battery_handle_intrpt(s > > __func__); > return; > } > + > + if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) { > + /* PMIC will reduce charger current automatically */ > + return; > + } > + > /* find the cause of the interrupt */ > if (r8 & PMIC_BATT_CHR_SBATDET_MASK) { > pbi->batt_is_present = PMIC_BATT_PRESENT; > --- linux-2.6.37.bak/drivers/power/intel_pmic_battery.c > 2011-05-12 11:57:59.850223025 +0800 > +++ linux-2.6.37/drivers/power/intel_pmic_battery.c 2011-05-13 > 15:51:08.937500000 +0800 > @@ -30,7 +30,7 @@ > #include <asm/intel_scu_ipc.h> > > #define DRIVER_NAME "pmic_battery" > -#define DRIVER_VERSION "Version 0.2.0" > +#define DRIVER_VERSION "Version 0.2.1" > > /********************************************************************* > * Generic defines > @@ -110,6 +110,8 @@ struct pmic_power_info { > unsigned int batt_charge_rate; /* in units > per second */ > unsigned int batt_charge_full_des; /* in mAS */ > > + bool dclmt_excpt_log_flag; > + > struct power_supply adap; > struct power_supply batt; > int irq; > @@ -598,10 +600,13 @@ static void pmic_battery_read_status(str > pmic_battery_log_event(pbi, > BATT_EVENT_BATOVP_EXCPT); > batt_exception = 1; > } else if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) { > - pbi->batt_health = > POWER_SUPPLY_HEALTH_OVERVOLTAGE; > - pbi->batt_status = > POWER_SUPPLY_STATUS_NOT_CHARGING; > - pmic_battery_log_event(pbi, > BATT_EVENT_DCLMT_EXCPT); > - batt_exception = 1; > + pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD; > + if (!pbi->dclmt_excpt_log_flag) { > + /* if over current is detected, log > once */ > + pmic_battery_log_event(pbi, > BATT_EVENT_DCLMT_EXCPT); > + pbi->dclmt_excpt_log_flag = 1; > + } > + batt_exception = 0; > } else if (r8 & PMIC_BATT_CHR_STEMP_MASK) { > pbi->batt_health = > POWER_SUPPLY_HEALTH_OVERHEAT; pbi->batt_status = > POWER_SUPPLY_STATUS_NOT_CHARGING; > @@ -613,7 +618,7 @@ static void pmic_battery_read_status(str > } > > /* set adap_is_present */ > - if (r8 & PMIC_BATT_CHR_SUSBDET_MASK) { > + if (gpio_get_value(PMIC_GPIO_0)) { > pbi->adap_is_present = PMIC_ADAP_PRESENT; > adap_present = 1; > } else { > @@ -841,6 +846,7 @@ static void pmic_adaptor_handle_intrpt(s > > if (val) { > pbi->adap_is_present = PMIC_ADAP_PRESENT; > + pbi->dclmt_excpt_log_flag = 0; > } else { > pbi->adap_is_present = PMIC_ADAP_NOT_PRESENT; > pbi->adap_health = POWER_SUPPLY_HEALTH_UNKNOWN; > @@ -867,6 +873,11 @@ static void pmic_battery_handle_intrpt(s > if (pmic_scu_ipc_ioread8(pbi, PMIC_BATT_CHR_SCHRGINT_ADDR, > &r8)) return; > > + if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) { > + /* PMIC will reduce charger current automatically */ > + return; > + } > + > /* find the cause of the interrupt */ > if (r8 & PMIC_BATT_CHR_SBATDET_MASK) { > pbi->batt_is_present = PMIC_BATT_PRESENT; > _______________________________________________ > MeeGo-kernel mailing list > [email protected] > http://lists.meego.com/listinfo/meego-kernel [jacob pan] -- Thanks Jacob _______________________________________________ MeeGo-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
