diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-09 12:11:09 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-09 12:11:09 -0700 |
commit | a16afaf7928b74c30a4727cdcaa67bd10675a55d (patch) | |
tree | ab6c4835991ac397d3c6eb1934ec5ea94e2098c0 /drivers | |
parent | 2a70ea5cda00214a1d573acf19fa0cd06d947e38 (diff) | |
parent | c42812da1395bf57a6f7b5934b5339a3a42c2c7d (diff) | |
download | linux-a16afaf7928b74c30a4727cdcaa67bd10675a55d.tar.bz2 |
Merge tag 'for-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset updates from Sebastian Reichel:
- bq27xxx: Add BQ27426 support
- ab8500: Drop AB8540/9540 support
- Introduced new usb_type property
- Properly document the power-supply ABI
- misc. cleanups and fixes
* tag 'for-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply:
MAINTAINERS: add entry for LEGO MINDSTORMS EV3
power: supply: ab8500_charger: fix spelling mistake: "faile" -> "failed"
power: supply: axp288_fuel_gauge: Remove polling from the driver
power: supply: axp288_fuelguage: Do not bind when the fg function is not used
power: supply: axp288_charger: Do not bind when the charge function is not used
power: supply: axp288_charger: Support 3500 and 4000 mA input current limit
power: supply: s3c-adc-battery: fix driver data initialization
power: supply: charger-manager: Verify polling interval only when polling requested
power: supply: sysfs: Use enum to specify property
power: supply: ab8500: Drop AB8540/9540 support
power: supply: ab8500_fg: fix spelling mistake: "Disharge" -> "Discharge"
power: supply: simplify getting .drvdata
power: supply: bq27xxx: Add support for BQ27426
gpio-poweroff: Use gpiod_set_value_cansleep
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/power/reset/gpio-poweroff.c | 4 | ||||
-rw-r--r-- | drivers/power/supply/ab8500_bmdata.c | 63 | ||||
-rw-r--r-- | drivers/power/supply/ab8500_btemp.c | 93 | ||||
-rw-r--r-- | drivers/power/supply/ab8500_charger.c | 133 | ||||
-rw-r--r-- | drivers/power/supply/ab8500_fg.c | 14 | ||||
-rw-r--r-- | drivers/power/supply/abx500_chargalg.c | 62 | ||||
-rw-r--r-- | drivers/power/supply/axp288_charger.c | 26 | ||||
-rw-r--r-- | drivers/power/supply/axp288_fuel_gauge.c | 27 | ||||
-rw-r--r-- | drivers/power/supply/bq27xxx_battery.c | 9 | ||||
-rw-r--r-- | drivers/power/supply/bq27xxx_battery_i2c.c | 2 | ||||
-rw-r--r-- | drivers/power/supply/charger-manager.c | 5 | ||||
-rw-r--r-- | drivers/power/supply/gpio-charger.c | 3 | ||||
-rw-r--r-- | drivers/power/supply/power_supply_sysfs.c | 86 | ||||
-rw-r--r-- | drivers/power/supply/s3c_adc_battery.c | 8 |
14 files changed, 137 insertions, 398 deletions
diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c index 6273ad3b411d..38206c39b3bf 100644 --- a/drivers/power/reset/gpio-poweroff.c +++ b/drivers/power/reset/gpio-poweroff.c @@ -35,11 +35,11 @@ static void gpio_poweroff_do_poweroff(void) gpiod_direction_output(reset_gpio, 1); mdelay(100); /* drive inactive, also active->inactive edge */ - gpiod_set_value(reset_gpio, 0); + gpiod_set_value_cansleep(reset_gpio, 0); mdelay(100); /* drive it active, also inactive->active edge */ - gpiod_set_value(reset_gpio, 1); + gpiod_set_value_cansleep(reset_gpio, 1); /* give it some time */ mdelay(timeout); diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index 4a7ed50d1dc5..7b2b69916f48 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -430,13 +430,6 @@ static const struct abx500_maxim_parameters ab8500_maxi_params = { .charger_curr_step = 100, }; -static const struct abx500_maxim_parameters abx540_maxi_params = { - .ena_maxi = true, - .chg_curr = 3000, - .wait_cycles = 10, - .charger_curr_step = 200, -}; - static const struct abx500_bm_charger_parameters chg = { .usb_volt_max = 5500, .usb_curr_max = 1500, @@ -453,17 +446,6 @@ static int ab8500_charge_output_curr_map[] = { 900, 1000, 1100, 1200, 1300, 1400, 1500, 1500, }; -static int ab8540_charge_output_curr_map[] = { - 0, 0, 0, 75, 100, 125, 150, 175, - 200, 225, 250, 275, 300, 325, 350, 375, - 400, 425, 450, 475, 500, 525, 550, 575, - 600, 625, 650, 675, 700, 725, 750, 775, - 800, 825, 850, 875, 900, 925, 950, 975, - 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, - 1200, 1225, 1250, 1275, 1300, 1325, 1350, 1375, - 1400, 1425, 1450, 1500, 1600, 1700, 1900, 2000, -}; - /* * This array maps the raw hex value to charger input current used by the * AB8500 values @@ -473,17 +455,6 @@ static int ab8500_charge_input_curr_map[] = { 700, 800, 900, 1000, 1100, 1300, 1400, 1500, }; -static int ab8540_charge_input_curr_map[] = { - 25, 50, 75, 100, 125, 150, 175, 200, - 225, 250, 275, 300, 325, 350, 375, 400, - 425, 450, 475, 500, 525, 550, 575, 600, - 625, 650, 675, 700, 725, 750, 775, 800, - 825, 850, 875, 900, 925, 950, 975, 1000, - 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, - 1225, 1250, 1275, 1300, 1325, 1350, 1375, 1400, - 1425, 1450, 1475, 1500, 1500, 1500, 1500, 1500, -}; - struct abx500_bm_data ab8500_bm_data = { .temp_under = 3, .temp_low = 8, @@ -518,40 +489,6 @@ struct abx500_bm_data ab8500_bm_data = { .n_chg_in_curr = ARRAY_SIZE(ab8500_charge_input_curr_map), }; -struct abx500_bm_data ab8540_bm_data = { - .temp_under = 3, - .temp_low = 8, - .temp_high = 43, - .temp_over = 48, - .main_safety_tmr_h = 4, - .temp_interval_chg = 20, - .temp_interval_nochg = 120, - .usb_safety_tmr_h = 4, - .bkup_bat_v = BUP_VCH_SEL_2P6V, - .bkup_bat_i = BUP_ICH_SEL_150UA, - .no_maintenance = false, - .capacity_scaling = false, - .adc_therm = ABx500_ADC_THERM_BATCTRL, - .chg_unknown_bat = false, - .enable_overshoot = false, - .fg_res = 100, - .cap_levels = &cap_levels, - .bat_type = bat_type_thermistor, - .n_btypes = ARRAY_SIZE(bat_type_thermistor), - .batt_id = 0, - .interval_charging = 5, - .interval_not_charging = 120, - .temp_hysteresis = 3, - .gnd_lift_resistance = 0, - .maxi = &abx540_maxi_params, - .chg_params = &chg, - .fg_params = &fg, - .chg_output_curr = ab8540_charge_output_curr_map, - .n_chg_out_curr = ARRAY_SIZE(ab8540_charge_output_curr_map), - .chg_input_curr = ab8540_charge_input_curr_map, - .n_chg_in_curr = ARRAY_SIZE(ab8540_charge_input_curr_map), -}; - int ab8500_bm_of_probe(struct device *dev, struct device_node *np, struct abx500_bm_data *bm) diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c index f7a35ebfbab2..708fd58cd62b 100644 --- a/drivers/power/supply/ab8500_btemp.c +++ b/drivers/power/supply/ab8500_btemp.c @@ -214,22 +214,10 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, /* Only do this for batteries with internal NTC */ if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) { - if (is_ab8540(di->parent)) { - if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_60UA) - curr = BAT_CTRL_60U_ENA; - else - curr = BAT_CTRL_120U_ENA; - } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { - if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_16UA) - curr = BAT_CTRL_16U_ENA; - else - curr = BAT_CTRL_18U_ENA; - } else { - if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_7UA) - curr = BAT_CTRL_7U_ENA; - else - curr = BAT_CTRL_20U_ENA; - } + if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_7UA) + curr = BAT_CTRL_7U_ENA; + else + curr = BAT_CTRL_20U_ENA; dev_dbg(di->dev, "Set BATCTRL %duA\n", di->curr_source); @@ -260,28 +248,12 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) { dev_dbg(di->dev, "Disable BATCTRL curr source\n"); - if (is_ab8540(di->parent)) { - /* Write 0 to the curr bits */ - ret = abx500_mask_and_set_register_interruptible( - di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA, - ~(BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA)); - } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { - /* Write 0 to the curr bits */ - ret = abx500_mask_and_set_register_interruptible( - di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_16U_ENA | BAT_CTRL_18U_ENA, - ~(BAT_CTRL_16U_ENA | BAT_CTRL_18U_ENA)); - } else { - /* Write 0 to the curr bits */ - ret = abx500_mask_and_set_register_interruptible( - di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, - ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); - } + /* Write 0 to the curr bits */ + ret = abx500_mask_and_set_register_interruptible( + di->dev, + AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, + BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, + ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); if (ret) { dev_err(di->dev, "%s failed disabling current source\n", @@ -324,25 +296,11 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, * if we got an error above */ disable_curr_source: - if (is_ab8540(di->parent)) { - /* Write 0 to the curr bits */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA, - ~(BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA)); - } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { - /* Write 0 to the curr bits */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_16U_ENA | BAT_CTRL_18U_ENA, - ~(BAT_CTRL_16U_ENA | BAT_CTRL_18U_ENA)); - } else { - /* Write 0 to the curr bits */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, - ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); - } + /* Write 0 to the curr bits */ + ret = abx500_mask_and_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, + BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, + ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); if (ret) { dev_err(di->dev, "%s failed disabling current source\n", @@ -556,13 +514,8 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) { int res; u8 i; - if (is_ab8540(di->parent)) - di->curr_source = BTEMP_BATCTRL_CURR_SRC_60UA; - else if (is_ab9540(di->parent) || is_ab8505(di->parent)) - di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; - else - di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; + di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; di->bm->batt_id = BATTERY_UNKNOWN; res = ab8500_btemp_get_batctrl_res(di); @@ -600,18 +553,8 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) */ if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && di->bm->batt_id == 1) { - if (is_ab8540(di->parent)) { - dev_dbg(di->dev, - "Set BATCTRL current source to 60uA\n"); - di->curr_source = BTEMP_BATCTRL_CURR_SRC_60UA; - } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { - dev_dbg(di->dev, - "Set BATCTRL current source to 16uA\n"); - di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; - } else { - dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); - di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA; - } + dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); + di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA; } return di->bm->batt_id; diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index 5a76c6d343de..98b335042ba6 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -58,9 +58,7 @@ #define MAIN_CH_INPUT_CURR_SHIFT 4 #define VBUS_IN_CURR_LIM_SHIFT 4 -#define AB8540_VBUS_IN_CURR_LIM_SHIFT 2 #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 -#define AB8540_AUTO_VBUS_IN_CURR_MASK 0x3F #define VBUS_IN_CURR_LIM_RETRY_SET_TIME 30 /* seconds */ #define LED_INDICATOR_PWM_ENA 0x01 @@ -1138,10 +1136,7 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, no_stepping = true; break; case AB8500_USBCH_IPT_CRNTLVL_REG: - if (is_ab8540(di->parent)) - shift_value = AB8540_VBUS_IN_CURR_LIM_SHIFT; - else - shift_value = VBUS_IN_CURR_LIM_SHIFT; + shift_value = VBUS_IN_CURR_LIM_SHIFT; prev_curr_index = (reg_value >> shift_value); curr_index = ab8500_vbus_in_curr_to_regval(di, ich); step_udelay = STEP_UDELAY * 100; @@ -1865,67 +1860,6 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger, return ret; } -/** - * ab8540_charger_power_path_enable() - enable usb power path mode - * @charger: pointer to the ux500_charger structure - * @enable: enable/disable flag - * - * Enable or disable the power path for usb mode - * Returns error code in case of failure else 0(on success) - */ -static int ab8540_charger_power_path_enable(struct ux500_charger *charger, - bool enable) -{ - int ret; - struct ab8500_charger *di; - - if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB) - di = to_ab8500_charger_usb_device_info(charger); - else - return -ENXIO; - - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8540_USB_PP_MODE_REG, - BUS_POWER_PATH_MODE_ENA, enable); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - - return ret; -} - - -/** - * ab8540_charger_usb_pre_chg_enable() - enable usb pre change - * @charger: pointer to the ux500_charger structure - * @enable: enable/disable flag - * - * Enable or disable the pre-chage for usb mode - * Returns error code in case of failure else 0(on success) - */ -static int ab8540_charger_usb_pre_chg_enable(struct ux500_charger *charger, - bool enable) -{ - int ret; - struct ab8500_charger *di; - - if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB) - di = to_ab8500_charger_usb_device_info(charger); - else - return -ENXIO; - - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8540_USB_PP_CHR_REG, - BUS_POWER_PATH_PRECHG_ENA, enable); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - - return ret; -} - static int ab8500_charger_get_ext_psy_data(struct device *dev, void *data) { struct power_supply *psy; @@ -2704,23 +2638,15 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) abx500_set_register_interruptible(di->dev, AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); - if (is_ab8540(di->parent)) - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, - AB8540_CH_USBCH_STAT3_REG, ®_value); - else - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_USBCH_STAT2_REG, ®_value); + ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, + AB8500_CH_USBCH_STAT2_REG, ®_value); if (ret < 0) { dev_err(di->dev, "%s read failed\n", __func__); return; } - if (is_ab8540(di->parent)) - curr = di->bm->chg_input_curr[ - reg_value & AB8540_AUTO_VBUS_IN_CURR_MASK]; - else - curr = di->bm->chg_input_curr[ - reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; + curr = di->bm->chg_input_curr[ + reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; if (di->max_usb_in_curr.calculated_max != curr) { /* USB source is collapsing */ @@ -3097,14 +3023,9 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) goto out; } - if (is_ab8540(di->parent)) - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG, - CH_OP_CUR_LVL_2P); - else - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG, - CH_OP_CUR_LVL_1P6); + ret = abx500_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG, + CH_OP_CUR_LVL_1P6); if (ret) { dev_err(di->dev, "failed to set CH_OPT_CRNTLVL_MAX_REG\n"); @@ -3112,8 +3033,7 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) } } - if (is_ab9540_2p0(di->parent) || is_ab9540_3p0(di->parent) - || is_ab8505_2p0(di->parent) || is_ab8540(di->parent)) + if (is_ab8505_2p0(di->parent)) ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_CHARGER, AB8500_USBCH_CTRL2_REG, @@ -3146,7 +3066,7 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) AB8500_SYS_CTRL2_BLOCK, AB8500_MAIN_WDOG_CTRL_REG, MAIN_WDOG_ENA); if (ret) { - dev_err(di->dev, "faile to enable main watchdog\n"); + dev_err(di->dev, "failed to enable main watchdog\n"); goto out; } @@ -3205,17 +3125,6 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) dev_err(di->dev, "failed to setup backup battery charging\n"); goto out; } - if (is_ab8540(di->parent)) { - ret = abx500_set_register_interruptible(di->dev, - AB8500_RTC, - AB8500_RTC_CTRL1_REG, - bup_vch_range | vbup33_vrtcn); - if (ret) { - dev_err(di->dev, - "failed to setup backup battery charging\n"); - goto out; - } - } /* Enable backup battery charging */ ret = abx500_mask_and_set_register_interruptible(di->dev, @@ -3226,25 +3135,6 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) goto out; } - if (is_ab8540(di->parent)) { - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8540_USB_PP_MODE_REG, - BUS_VSYS_VOL_SELECT_MASK, BUS_VSYS_VOL_SELECT_3P6V); - if (ret) { - dev_err(di->dev, - "failed to setup usb power path vsys voltage\n"); - goto out; - } - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8540_USB_PP_CHR_REG, - BUS_PP_PRECHG_CURRENT_MASK, 0); - if (ret) { - dev_err(di->dev, - "failed to setup usb power path precharge current\n"); - goto out; - } - } - out: return ret; } @@ -3529,8 +3419,6 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.ops.check_enable = &ab8500_charger_usb_check_enable; di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current; - di->usb_chg.ops.pp_enable = &ab8540_charger_power_path_enable; - di->usb_chg.ops.pre_chg_enable = &ab8540_charger_usb_pre_chg_enable; di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; di->usb_chg.max_out_curr = @@ -3538,7 +3426,6 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; di->usb_chg.enabled = di->bm->usb_enabled; di->usb_chg.external = false; - di->usb_chg.power_path = di->bm->usb_power_path; di->usb_state.usb_current = -1; /* Create a work queue for the charger */ diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index c569f82a0071..d9c6c7bedd85 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -1408,7 +1408,7 @@ static void ab8500_fg_charge_state_to(struct ab8500_fg *di, static void ab8500_fg_discharge_state_to(struct ab8500_fg *di, enum ab8500_fg_discharge_state new_state) { - dev_dbg(di->dev, "Disharge state from %d [%s] to %d [%s]\n", + dev_dbg(di->dev, "Discharge state from %d [%s] to %d [%s]\n", di->discharge_state, discharge_state[di->discharge_state], new_state, @@ -2326,9 +2326,7 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di) goto out; } - if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && - abx500_get_chip_id(di->dev) >= AB8500_CUT2P0) - || is_ab8540(di->parent)) { + if (is_ab8505(di->parent)) { ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, AB8505_RTC_PCUT_MAX_TIME_REG, di->bm->fg_params->pcut_max_time); @@ -2915,9 +2913,7 @@ static int ab8500_fg_sysfs_psy_create_attrs(struct ab8500_fg *di) { unsigned int i; - if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && - abx500_get_chip_id(di->dev) >= AB8500_CUT2P0) - || is_ab8540(di->parent)) { + if (is_ab8505(di->parent)) { for (i = 0; i < ARRAY_SIZE(ab8505_fg_sysfs_psy_attrs); i++) if (device_create_file(&di->fg_psy->dev, &ab8505_fg_sysfs_psy_attrs[i])) @@ -2937,9 +2933,7 @@ static void ab8500_fg_sysfs_psy_remove_attrs(struct ab8500_fg *di) { unsigned int i; - if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && - abx500_get_chip_id(di->dev) >= AB8500_CUT2P0) - || is_ab8540(di->parent)) { + if (is_ab8505(di->parent)) { for (i = 0; i < ARRAY_SIZE(ab8505_fg_sysfs_psy_attrs); i++) (void)device_remove_file(&di->fg_psy->dev, &ab8505_fg_sysfs_psy_attrs[i]); diff --git a/drivers/power/supply/abx500_chargalg.c b/drivers/power/supply/abx500_chargalg.c index a4411d6bbc96..947709cdd14e 100644 --- a/drivers/power/supply/abx500_chargalg.c +++ b/drivers/power/supply/abx500_chargalg.c @@ -44,9 +44,6 @@ /* Five minutes expressed in seconds */ #define FIVE_MINUTES_IN_SECONDS 300 -/* Plus margin for the low battery threshold */ -#define BAT_PLUS_MARGIN (100) - #define CHARGALG_CURR_STEP_LOW 0 #define CHARGALG_CURR_STEP_HIGH 100 @@ -101,7 +98,6 @@ enum abx500_chargalg_states { STATE_HW_TEMP_PROTECT_INIT, STATE_HW_TEMP_PROTECT, STATE_NORMAL_INIT, - STATE_USB_PP_PRE_CHARGE, STATE_NORMAL, STATE_WAIT_FOR_RECHARGE_INIT, STATE_WAIT_FOR_RECHARGE, @@ -133,7 +129,6 @@ static const char *states[] = { "HW_TEMP_PROTECT_INIT", "HW_TEMP_PROTECT", "NORMAL_INIT", - "USB_PP_PRE_CHARGE", "NORMAL", "WAIT_FOR_RECHARGE_INIT", "WAIT_FOR_RECHARGE", @@ -603,37 +598,6 @@ static int abx500_chargalg_usb_en(struct abx500_chargalg *di, int enable, return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset); } - /** - * ab8540_chargalg_usb_pp_en() - Enable/ disable USB power path - * @di: pointer to the abx500_chargalg structure - * @enable: power path enable/disable - * - * The USB power path will be enable/ disable - */ -static int ab8540_chargalg_usb_pp_en(struct abx500_chargalg *di, bool enable) -{ - if (!di->usb_chg || !di->usb_chg->ops.pp_enable) - return -ENXIO; - - return di->usb_chg->ops.pp_enable(di->usb_chg, enable); -} - -/** - * ab8540_chargalg_usb_pre_chg_en() - Enable/ disable USB pre-charge - * @di: pointer to the abx500_chargalg structure - * @enable: USB pre-charge enable/disable - * - * The USB USB pre-charge will be enable/ disable - */ -static int ab8540_chargalg_usb_pre_chg_en(struct abx500_chargalg *di, - bool enable) -{ - if (!di->usb_chg || !di->usb_chg->ops.pre_chg_enable) - return -ENXIO; - - return di->usb_chg->ops.pre_chg_enable(di->usb_chg, enable); -} - /** * abx500_chargalg_update_chg_curr() - Update charger current * @di: pointer to the abx500_chargalg structure @@ -833,9 +797,6 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di) di->batt_data.avg_curr > 0) { if (++di->eoc_cnt >= EOC_COND_CNT) { di->eoc_cnt = 0; - if ((di->chg_info.charger_type & USB_CHG) && - (di->usb_chg->power_path)) - ab8540_chargalg_usb_pp_en(di, true); di->charge_status = POWER_SUPPLY_STATUS_FULL; di->maintenance_chg = true; dev_dbg(di->dev, "EOC reached!\n"); @@ -1536,22 +1497,6 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) break; case STATE_NORMAL_INIT: - if ((di->chg_info.charger_type & USB_CHG) && - di->usb_chg->power_path) { - if (di->batt_data.volt > - (di->bm->fg_params->lowbat_threshold + - BAT_PLUS_MARGIN)) { - ab8540_chargalg_usb_pre_chg_en(di, false); - ab8540_chargalg_usb_pp_en(di, false); - } else { - ab8540_chargalg_usb_pp_en(di, true); - ab8540_chargalg_usb_pre_chg_en(di, true); - abx500_chargalg_state_to(di, - STATE_USB_PP_PRE_CHARGE); - break; - } - } - if (di->curr_status.curr_step == CHARGALG_CURR_STEP_LOW) abx500_chargalg_stop_charging(di); else { @@ -1575,13 +1520,6 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) break; - case STATE_USB_PP_PRE_CHARGE: - if (di->batt_data.volt > - (di->bm->fg_params->lowbat_threshold + - BAT_PLUS_MARGIN)) - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - break; - case STATE_NORMAL: handle_maxim_chg_curr(di); if (di->charge_status == POWER_SUPPLY_STATUS_FULL && diff --git a/drivers/power/supply/axp288_charger.c b/drivers/power/supply/axp288_charger.c index 9bfbde15b07d..6e1bc14c3304 100644 --- a/drivers/power/supply/axp288_charger.c +++ b/drivers/power/supply/axp288_charger.c @@ -88,6 +88,8 @@ #define CHRG_VBUS_ILIM_2000MA 0x4 /* 2000mA */ #define CHRG_VBUS_ILIM_2500MA 0x5 /* 2500mA */ #define CHRG_VBUS_ILIM_3000MA 0x6 /* 3000mA */ +#define CHRG_VBUS_ILIM_3500MA 0x7 /* 3500mA */ +#define CHRG_VBUS_ILIM_4000MA 0x8 /* 4000mA */ #define CHRG_VLTFC_0C 0xA5 /* 0 DegC */ #define CHRG_VHTFC_45C 0x1F /* 45 DegC */ @@ -223,9 +225,11 @@ static int axp288_charger_get_vbus_inlmt(struct axp288_chrg_info *info) return 2500000; case CHRG_VBUS_ILIM_3000MA: return 3000000; + case CHRG_VBUS_ILIM_3500MA: + return 3500000; default: - dev_warn(&info->pdev->dev, "Unknown ilim reg val: %d\n", val); - return 0; + /* All b1xxx values map to 4000 mA */ + return 4000000; } } @@ -235,7 +239,11 @@ static inline int axp288_charger_set_vbus_inlmt(struct axp288_chrg_info *info, int ret; u8 reg_val; - if (inlmt >= 3000000) + if (inlmt >= 4000000) + reg_val = CHRG_VBUS_ILIM_4000MA << CHRG_VBUS_ILIM_BIT_POS; + else if (inlmt >= 3500000) + reg_val = CHRG_VBUS_ILIM_3500MA << CHRG_VBUS_ILIM_BIT_POS; + else if (inlmt >= 3000000) reg_val = CHRG_VBUS_ILIM_3000MA << CHRG_VBUS_ILIM_BIT_POS; else if (inlmt >= 2500000) reg_val = CHRG_VBUS_ILIM_2500MA << CHRG_VBUS_ILIM_BIT_POS; @@ -739,6 +747,18 @@ static int axp288_charger_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); struct power_supply_config charger_cfg = {}; + unsigned int val; + + /* + * On some devices the fuelgauge and charger parts of the axp288 are + * not used, check that the fuelgauge is enabled (CC_CTRL != 0). + */ + ret = regmap_read(axp20x->regmap, AXP20X_CC_CTRL, &val); + if (ret < 0) + return ret; + if (val == 0) + return -ENODEV; + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c index fd8f0b2210bc..084c8ba9749d 100644 --- a/drivers/power/supply/axp288_fuel_gauge.c +++ b/drivers/power/supply/axp288_fuel_gauge.c @@ -24,7 +24,6 @@ #include <linux/regmap.h> #include <linux/jiffies.h> #include <linux/interrupt.h> -#include <linux/workqueue.h> #include <linux/mfd/axp20x.h> #include <linux/platform_device.h> #include <linux/power_supply.h> @@ -88,7 +87,6 @@ #define FG_LOW_CAP_CRIT_THR 4 /* 4 perc */ #define FG_LOW_CAP_SHDN_THR 0 /* 0 perc */ -#define STATUS_MON_DELAY_JIFFIES (HZ * 60) /*60 sec */ #define NR_RETRY_CNT 3 #define DEV_NAME "axp288_fuel_gauge" @@ -128,7 +126,6 @@ struct axp288_fg_info { struct mutex lock; int status; int max_volt; - struct delayed_work status_monitor; struct dentry *debug_file; }; @@ -592,16 +589,6 @@ static int fuel_gauge_property_is_writeable(struct power_supply *psy, return ret; } -static void fuel_gauge_status_monitor(struct work_struct *work) -{ - struct axp288_fg_info *info = container_of(work, - struct axp288_fg_info, status_monitor.work); - - fuel_gauge_get_status(info); - power_supply_changed(info->bat); - schedule_delayed_work(&info->status_monitor, STATUS_MON_DELAY_JIFFIES); -} - static irqreturn_t fuel_gauge_thread_handler(int irq, void *dev) { struct axp288_fg_info *info = dev; @@ -754,10 +741,21 @@ static int axp288_fuel_gauge_probe(struct platform_device *pdev) [BAT_D_CURR] = "axp288-chrg-d-curr", [BAT_VOLT] = "axp288-batt-volt", }; + unsigned int val; if (dmi_check_system(axp288_fuel_gauge_blacklist)) return -ENODEV; + /* + * On some devices the fuelgauge and charger parts of the axp288 are + * not used, check that the fuelgauge is enabled (CC_CTRL != 0). + */ + ret = regmap_read(axp20x->regmap, AXP20X_CC_CTRL, &val); + if (ret < 0) + return ret; + if (val == 0) + return -ENODEV; + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; @@ -770,7 +768,6 @@ static int axp288_fuel_gauge_probe(struct platform_device *pdev) platform_set_drvdata(pdev, info); mutex_init(&info->lock); - INIT_DELAYED_WORK(&info->status_monitor, fuel_gauge_status_monitor); for (i = 0; i < IIO_CHANNEL_NUM; i++) { /* @@ -830,7 +827,6 @@ static int axp288_fuel_gauge_probe(struct platform_device *pdev) fuel_gauge_create_debugfs(info); fuel_gauge_init_irq(info); - schedule_delayed_work(&info->status_monitor, STATUS_MON_DELAY_JIFFIES); return 0; @@ -853,7 +849,6 @@ static int axp288_fuel_gauge_remove(struct platform_device *pdev) struct axp288_fg_info *info = platform_get_drvdata(pdev); int i; - cancel_delayed_work_sync(&info->status_monitor); power_supply_unregister(info->bat); fuel_gauge_remove_debugfs(info); diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 7ce60519b1bc..d44ed8e17c47 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -432,6 +432,7 @@ static u8 BQ27XXX_DM_REG_ROWS, }; #define bq27425_regs bq27421_regs +#define bq27426_regs bq27421_regs #define bq27441_regs bq27421_regs #define bq27621_regs bq27421_regs @@ -664,6 +665,7 @@ static enum power_supply_property bq27421_props[] = { POWER_SUPPLY_PROP_MANUFACTURER, }; #define bq27425_props bq27421_props +#define bq27426_props bq27421_props #define bq27441_props bq27421_props #define bq27621_props bq27421_props @@ -734,6 +736,12 @@ static struct bq27xxx_dm_reg bq27425_dm_regs[] = { [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 18, 2, 2800, 3700 }, }; +static struct bq27xxx_dm_reg bq27426_dm_regs[] = { + [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 6, 2, 0, 8000 }, + [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 8, 2, 0, 32767 }, + [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 10, 2, 2500, 3700 }, +}; + #if 0 /* not yet tested */ #define bq27441_dm_regs bq27421_dm_regs #else @@ -795,6 +803,7 @@ static struct { [BQ27545] = BQ27XXX_DATA(bq27545, 0x04143672, BQ27XXX_O_OTDC), [BQ27421] = BQ27XXX_DATA(bq27421, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM), [BQ27425] = BQ27XXX_DATA(bq27425, 0x04143672, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP), + [BQ27426] = BQ27XXX_DATA(bq27426, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM), [BQ27441] = BQ27XXX_DATA(bq27441, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM), [BQ27621] = BQ27XXX_DATA(bq27621, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM), }; diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c index 6b25e5f2337e..40069128ad44 100644 --- a/drivers/power/supply/bq27xxx_battery_i2c.c +++ b/drivers/power/supply/bq27xxx_battery_i2c.c @@ -249,6 +249,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = { { "bq27545", BQ27545 }, { "bq27421", BQ27421 }, { "bq27425", BQ27425 }, + { "bq27426", BQ27426 }, { "bq27441", BQ27441 }, { "bq27621", BQ27621 }, {}, @@ -280,6 +281,7 @@ static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = { { .compatible = "ti,bq27545" }, { .compatible = "ti,bq27421" }, { .compatible = "ti,bq27425" }, + { .compatible = "ti,bq27426" }, { .compatible = "ti,bq27441" }, { .compatible = "ti,bq27621" }, {}, diff --git a/drivers/power/supply/charger-manager.c b/drivers/power/supply/charger-manager.c index 1de4b4493824..2a50b4654793 100644 --- a/drivers/power/supply/charger-manager.c +++ b/drivers/power/supply/charger-manager.c @@ -1700,8 +1700,9 @@ static int charger_manager_probe(struct platform_device *pdev) power_supply_put(psy); } - if (desc->polling_interval_ms == 0 || - msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL) { + if (cm->desc->polling_mode != CM_POLL_DISABLE && + (desc->polling_interval_ms == 0 || + msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL)) { dev_err(&pdev->dev, "polling_interval_ms is too small\n"); return -EINVAL; } diff --git a/drivers/power/supply/gpio-charger.c b/drivers/power/supply/gpio-charger.c index bd2468ca6b63..c3f2a9479468 100644 --- a/drivers/power/supply/gpio-charger.c +++ b/drivers/power/supply/gpio-charger.c @@ -212,8 +212,7 @@ static int gpio_charger_suspend(struct device *dev) static int gpio_charger_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); + struct gpio_charger *gpio_charger = dev_get_drvdata(dev); if (device_may_wakeup(dev) && gpio_charger->wakeup_enabled) disable_irq_wake(gpio_charger->irq); diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 1350068c401a..6170ed8b6854 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -116,15 +116,15 @@ static ssize_t power_supply_show_usb_type(struct device *dev, static ssize_t power_supply_show_property(struct device *dev, struct device_attribute *attr, char *buf) { - ssize_t ret = 0; + ssize_t ret; struct power_supply *psy = dev_get_drvdata(dev); - const ptrdiff_t off = attr - power_supply_attrs; + enum power_supply_property psp = attr - power_supply_attrs; union power_supply_propval value; - if (off == POWER_SUPPLY_PROP_TYPE) { + if (psp == POWER_SUPPLY_PROP_TYPE) { value.intval = psy->desc->type; } else { - ret = power_supply_get_property(psy, off, &value); + ret = power_supply_get_property(psy, psp, &value); if (ret < 0) { if (ret == -ENODATA) @@ -137,35 +137,48 @@ static ssize_t power_supply_show_property(struct device *dev, } } - if (off == POWER_SUPPLY_PROP_STATUS) - return sprintf(buf, "%s\n", - power_supply_status_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_CHARGE_TYPE) - return sprintf(buf, "%s\n", - power_supply_charge_type_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_HEALTH) - return sprintf(buf, "%s\n", - power_supply_health_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_TECHNOLOGY) - return sprintf(buf, "%s\n", - power_supply_technology_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_CAPACITY_LEVEL) - return sprintf(buf, "%s\n", - power_supply_capacity_level_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_TYPE) - return sprintf(buf, "%s\n", - power_supply_type_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_USB_TYPE) - return power_supply_show_usb_type(dev, psy->desc->usb_types, - psy->desc->num_usb_types, - &value, buf); - else if (off == POWER_SUPPLY_PROP_SCOPE) - return sprintf(buf, "%s\n", - power_supply_scope_text[value.intval]); - else if (off >= POWER_SUPPLY_PROP_MODEL_NAME) - return sprintf(buf, "%s\n", value.strval); - - return sprintf(buf, "%d\n", value.intval); + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + ret = sprintf(buf, "%s\n", + power_supply_status_text[value.intval]); + break; + case POWER_SUPPLY_PROP_CHARGE_TYPE: + ret = sprintf(buf, "%s\n", + power_supply_charge_type_text[value.intval]); + break; + case POWER_SUPPLY_PROP_HEALTH: + ret = sprintf(buf, "%s\n", + power_supply_health_text[value.intval]); + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + ret = sprintf(buf, "%s\n", + power_supply_technology_text[value.intval]); + break; + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + ret = sprintf(buf, "%s\n", + power_supply_capacity_level_text[value.intval]); + break; + case POWER_SUPPLY_PROP_TYPE: + ret = sprintf(buf, "%s\n", + power_supply_type_text[value.intval]); + break; + case POWER_SUPPLY_PROP_USB_TYPE: + ret = power_supply_show_usb_type(dev, psy->desc->usb_types, + psy->desc->num_usb_types, + &value, buf); + break; + case POWER_SUPPLY_PROP_SCOPE: + ret = sprintf(buf, "%s\n", + power_supply_scope_text[value.intval]); + break; + case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER: + ret = sprintf(buf, "%s\n", value.strval); + break; + default: + ret = sprintf(buf, "%d\n", value.intval); + } + + return ret; } static ssize_t power_supply_store_property(struct device *dev, @@ -173,11 +186,10 @@ static ssize_t power_supply_store_property(struct device *dev, const char *buf, size_t count) { ssize_t ret; struct power_supply *psy = dev_get_drvdata(dev); - const ptrdiff_t off = attr - power_supply_attrs; + enum power_supply_property psp = attr - power_supply_attrs; union power_supply_propval value; - /* maybe it is a enum property? */ - switch (off) { + switch (psp) { case POWER_SUPPLY_PROP_STATUS: ret = sysfs_match_string(power_supply_status_text, buf); break; @@ -216,7 +228,7 @@ static ssize_t power_supply_store_property(struct device *dev, value.intval = ret; - ret = power_supply_set_property(psy, off, &value); + ret = power_supply_set_property(psy, psp, &value); if (ret < 0) return ret; diff --git a/drivers/power/supply/s3c_adc_battery.c b/drivers/power/supply/s3c_adc_battery.c index 0ffe5cd3abf6..3d00b35cafc9 100644 --- a/drivers/power/supply/s3c_adc_battery.c +++ b/drivers/power/supply/s3c_adc_battery.c @@ -293,6 +293,7 @@ static int s3c_adc_bat_probe(struct platform_device *pdev) { struct s3c_adc_client *client; struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; + struct power_supply_config psy_cfg = {}; int ret; client = s3c_adc_register(pdev, NULL, NULL, 0); @@ -309,14 +310,15 @@ static int s3c_adc_bat_probe(struct platform_device *pdev) main_bat.cur_value = -1; main_bat.cable_plugged = 0; main_bat.status = POWER_SUPPLY_STATUS_DISCHARGING; + psy_cfg.drv_data = &main_bat; - main_bat.psy = power_supply_register(&pdev->dev, &main_bat_desc, NULL); + main_bat.psy = power_supply_register(&pdev->dev, &main_bat_desc, &psy_cfg); if (IS_ERR(main_bat.psy)) { ret = PTR_ERR(main_bat.psy); goto err_reg_main; } if (pdata->backup_volt_mult) { - const struct power_supply_config psy_cfg + const struct power_supply_config backup_psy_cfg = { .drv_data = &backup_bat, }; backup_bat.client = client; @@ -324,7 +326,7 @@ static int s3c_adc_bat_probe(struct platform_device *pdev) backup_bat.volt_value = -1; backup_bat.psy = power_supply_register(&pdev->dev, &backup_bat_desc, - &psy_cfg); + &backup_psy_cfg); if (IS_ERR(backup_bat.psy)) { ret = PTR_ERR(backup_bat.psy); goto err_reg_backup; |