aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim, Milo <Milo.Kim@ti.com>2012-08-31 05:23:12 -0400
committerAnton Vorontsov <anton.vorontsov@linaro.org>2012-09-20 20:56:49 -0400
commit318cb389d020e3107979d7d794ab992e4bcd6665 (patch)
treea1d4c51931e22d78abcf5a7b0217e6b5a73c589d
parentfb9adc5190d7605506ebc0e05351baa57365cc90 (diff)
lp8727_charger: Fix buggy code of NULL pdata
LP8727 platform data is optional, so the driver should work even the platform data is NULL. To check the platform data, charging parameter data should be changed to the pointer type. Fix NULL point access problem when getting the battery properties. When the data is NULL, just return as invalid value. Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com> Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
-rw-r--r--drivers/power/lp8727_charger.c28
-rw-r--r--include/linux/platform_data/lp8727.h7
2 files changed, 25 insertions, 10 deletions
diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c
index b2df11458d98..7c19c0927f3a 100644
--- a/drivers/power/lp8727_charger.c
+++ b/drivers/power/lp8727_charger.c
@@ -170,20 +170,21 @@ static void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw)
170 170
171static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin) 171static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin)
172{ 172{
173 struct lp8727_platform_data *pdata = pchg->pdata;
173 u8 devid = ID_NONE; 174 u8 devid = ID_NONE;
174 u8 swctrl = SW_DM1_HiZ | SW_DP2_HiZ; 175 u8 swctrl = SW_DM1_HiZ | SW_DP2_HiZ;
175 176
176 switch (id) { 177 switch (id) {
177 case 0x5: 178 case 0x5:
178 devid = ID_TA; 179 devid = ID_TA;
179 pchg->chg_parm = &pchg->pdata->ac; 180 pchg->chg_parm = pdata ? pdata->ac : NULL;
180 break; 181 break;
181 case 0xB: 182 case 0xB:
182 if (lp8727_is_dedicated_charger(pchg)) { 183 if (lp8727_is_dedicated_charger(pchg)) {
183 pchg->chg_parm = &pchg->pdata->ac; 184 pchg->chg_parm = pdata ? pdata->ac : NULL;
184 devid = ID_DEDICATED_CHG; 185 devid = ID_DEDICATED_CHG;
185 } else if (lp8727_is_usb_charger(pchg)) { 186 } else if (lp8727_is_usb_charger(pchg)) {
186 pchg->chg_parm = &pchg->pdata->usb; 187 pchg->chg_parm = pdata ? pdata->usb : NULL;
187 devid = ID_USB_CHG; 188 devid = ID_USB_CHG;
188 swctrl = SW_DM1_DM | SW_DP2_DP; 189 swctrl = SW_DM1_DM | SW_DP2_DP;
189 } else if (vbusin) { 190 } else if (vbusin) {
@@ -295,6 +296,7 @@ static int lp8727_battery_get_property(struct power_supply *psy,
295 union power_supply_propval *val) 296 union power_supply_propval *val)
296{ 297{
297 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 298 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
299 struct lp8727_platform_data *pdata = pchg->pdata;
298 u8 read; 300 u8 read;
299 301
300 switch (psp) { 302 switch (psp) {
@@ -318,19 +320,31 @@ static int lp8727_battery_get_property(struct power_supply *psy,
318 val->intval = POWER_SUPPLY_HEALTH_GOOD; 320 val->intval = POWER_SUPPLY_HEALTH_GOOD;
319 break; 321 break;
320 case POWER_SUPPLY_PROP_PRESENT: 322 case POWER_SUPPLY_PROP_PRESENT:
321 if (pchg->pdata->get_batt_present) 323 if (!pdata)
324 return -EINVAL;
325
326 if (pdata->get_batt_present)
322 val->intval = pchg->pdata->get_batt_present(); 327 val->intval = pchg->pdata->get_batt_present();
323 break; 328 break;
324 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 329 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
325 if (pchg->pdata->get_batt_level) 330 if (!pdata)
331 return -EINVAL;
332
333 if (pdata->get_batt_level)
326 val->intval = pchg->pdata->get_batt_level(); 334 val->intval = pchg->pdata->get_batt_level();
327 break; 335 break;
328 case POWER_SUPPLY_PROP_CAPACITY: 336 case POWER_SUPPLY_PROP_CAPACITY:
329 if (pchg->pdata->get_batt_capacity) 337 if (!pdata)
338 return -EINVAL;
339
340 if (pdata->get_batt_capacity)
330 val->intval = pchg->pdata->get_batt_capacity(); 341 val->intval = pchg->pdata->get_batt_capacity();
331 break; 342 break;
332 case POWER_SUPPLY_PROP_TEMP: 343 case POWER_SUPPLY_PROP_TEMP:
333 if (pchg->pdata->get_batt_temp) 344 if (!pdata)
345 return -EINVAL;
346
347 if (pdata->get_batt_temp)
334 val->intval = pchg->pdata->get_batt_temp(); 348 val->intval = pchg->pdata->get_batt_temp();
335 break; 349 break;
336 default: 350 default:
diff --git a/include/linux/platform_data/lp8727.h b/include/linux/platform_data/lp8727.h
index ea98c6133d32..f4bcdd5f20a4 100644
--- a/include/linux/platform_data/lp8727.h
+++ b/include/linux/platform_data/lp8727.h
@@ -51,15 +51,16 @@ struct lp8727_chg_param {
51 * @get_batt_level : get battery voltage (mV) 51 * @get_batt_level : get battery voltage (mV)
52 * @get_batt_capacity : get battery capacity (%) 52 * @get_batt_capacity : get battery capacity (%)
53 * @get_batt_temp : get battery temperature 53 * @get_batt_temp : get battery temperature
54 * @ac, @usb : charging parameters each charger type 54 * @ac : charging parameters for AC type charger
55 * @usb : charging parameters for USB type charger
55 */ 56 */
56struct lp8727_platform_data { 57struct lp8727_platform_data {
57 u8 (*get_batt_present)(void); 58 u8 (*get_batt_present)(void);
58 u16 (*get_batt_level)(void); 59 u16 (*get_batt_level)(void);
59 u8 (*get_batt_capacity)(void); 60 u8 (*get_batt_capacity)(void);
60 u8 (*get_batt_temp)(void); 61 u8 (*get_batt_temp)(void);
61 struct lp8727_chg_param ac; 62 struct lp8727_chg_param *ac;
62 struct lp8727_chg_param usb; 63 struct lp8727_chg_param *usb;
63}; 64};
64 65
65#endif 66#endif