Commit ec7de656 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-v3.18-rc' of git://git.infradead.org/battery-2.6

Pull power supply updates from Sebastian Reichel:
 "Power supply and reset changes for the v3.18-rc:

   - misc. charger-manager fixes
   - year 2038 fix in ab8500_fg
   - fix error handling of bq2415x_charger"

* tag 'for-v3.18-rc' of git://git.infradead.org/battery-2.6:
  power: charger-manager: Fix accessing invalidated power supply after charger unbind
  power: charger-manager: Fix accessing invalidated power supply after fuel gauge unbind
  power: charger-manager: Avoid recursive thermal get_temp call
  power_supply: Add no_thermal property to prevent recursive get_temp calls
  power: bq2415x_charger: Fix memory leak on DTS parsing error
  power: bq2415x_charger: Properly handle ENODEV from power_supply_get_by_phandle
  power: ab8500_fg.c: use 64-bit time types
parents e0611671 cdaf3e15
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/time64.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
...@@ -108,7 +109,7 @@ enum ab8500_fg_calibration_state { ...@@ -108,7 +109,7 @@ enum ab8500_fg_calibration_state {
struct ab8500_fg_avg_cap { struct ab8500_fg_avg_cap {
int avg; int avg;
int samples[NBR_AVG_SAMPLES]; int samples[NBR_AVG_SAMPLES];
__kernel_time_t time_stamps[NBR_AVG_SAMPLES]; time64_t time_stamps[NBR_AVG_SAMPLES];
int pos; int pos;
int nbr_samples; int nbr_samples;
int sum; int sum;
...@@ -386,15 +387,15 @@ static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr) ...@@ -386,15 +387,15 @@ static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr)
*/ */
static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample) static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample)
{ {
struct timespec ts; struct timespec64 ts64;
struct ab8500_fg_avg_cap *avg = &di->avg_cap; struct ab8500_fg_avg_cap *avg = &di->avg_cap;
getnstimeofday(&ts); getnstimeofday64(&ts64);
do { do {
avg->sum += sample - avg->samples[avg->pos]; avg->sum += sample - avg->samples[avg->pos];
avg->samples[avg->pos] = sample; avg->samples[avg->pos] = sample;
avg->time_stamps[avg->pos] = ts.tv_sec; avg->time_stamps[avg->pos] = ts64.tv_sec;
avg->pos++; avg->pos++;
if (avg->pos == NBR_AVG_SAMPLES) if (avg->pos == NBR_AVG_SAMPLES)
...@@ -407,7 +408,7 @@ static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample) ...@@ -407,7 +408,7 @@ static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample)
* Check the time stamp for each sample. If too old, * Check the time stamp for each sample. If too old,
* replace with latest sample * replace with latest sample
*/ */
} while (ts.tv_sec - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]); } while (ts64.tv_sec - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]);
avg->avg = avg->sum / avg->nbr_samples; avg->avg = avg->sum / avg->nbr_samples;
...@@ -446,14 +447,14 @@ static void ab8500_fg_clear_cap_samples(struct ab8500_fg *di) ...@@ -446,14 +447,14 @@ static void ab8500_fg_clear_cap_samples(struct ab8500_fg *di)
static void ab8500_fg_fill_cap_sample(struct ab8500_fg *di, int sample) static void ab8500_fg_fill_cap_sample(struct ab8500_fg *di, int sample)
{ {
int i; int i;
struct timespec ts; struct timespec64 ts64;
struct ab8500_fg_avg_cap *avg = &di->avg_cap; struct ab8500_fg_avg_cap *avg = &di->avg_cap;
getnstimeofday(&ts); getnstimeofday64(&ts64);
for (i = 0; i < NBR_AVG_SAMPLES; i++) { for (i = 0; i < NBR_AVG_SAMPLES; i++) {
avg->samples[i] = sample; avg->samples[i] = sample;
avg->time_stamps[i] = ts.tv_sec; avg->time_stamps[i] = ts64.tv_sec;
} }
avg->pos = 0; avg->pos = 0;
......
...@@ -1579,8 +1579,15 @@ static int bq2415x_probe(struct i2c_client *client, ...@@ -1579,8 +1579,15 @@ static int bq2415x_probe(struct i2c_client *client,
if (np) { if (np) {
bq->notify_psy = power_supply_get_by_phandle(np, "ti,usb-charger-detection"); bq->notify_psy = power_supply_get_by_phandle(np, "ti,usb-charger-detection");
if (!bq->notify_psy) if (IS_ERR(bq->notify_psy)) {
return -EPROBE_DEFER; dev_info(&client->dev,
"no 'ti,usb-charger-detection' property (err=%ld)\n",
PTR_ERR(bq->notify_psy));
bq->notify_psy = NULL;
} else if (!bq->notify_psy) {
ret = -EPROBE_DEFER;
goto error_2;
}
} }
else if (pdata->notify_device) else if (pdata->notify_device)
bq->notify_psy = power_supply_get_by_name(pdata->notify_device); bq->notify_psy = power_supply_get_by_name(pdata->notify_device);
...@@ -1602,27 +1609,27 @@ static int bq2415x_probe(struct i2c_client *client, ...@@ -1602,27 +1609,27 @@ static int bq2415x_probe(struct i2c_client *client,
ret = of_property_read_u32(np, "ti,current-limit", ret = of_property_read_u32(np, "ti,current-limit",
&bq->init_data.current_limit); &bq->init_data.current_limit);
if (ret) if (ret)
return ret; goto error_2;
ret = of_property_read_u32(np, "ti,weak-battery-voltage", ret = of_property_read_u32(np, "ti,weak-battery-voltage",
&bq->init_data.weak_battery_voltage); &bq->init_data.weak_battery_voltage);
if (ret) if (ret)
return ret; goto error_2;
ret = of_property_read_u32(np, "ti,battery-regulation-voltage", ret = of_property_read_u32(np, "ti,battery-regulation-voltage",
&bq->init_data.battery_regulation_voltage); &bq->init_data.battery_regulation_voltage);
if (ret) if (ret)
return ret; goto error_2;
ret = of_property_read_u32(np, "ti,charge-current", ret = of_property_read_u32(np, "ti,charge-current",
&bq->init_data.charge_current); &bq->init_data.charge_current);
if (ret) if (ret)
return ret; goto error_2;
ret = of_property_read_u32(np, "ti,termination-current", ret = of_property_read_u32(np, "ti,termination-current",
&bq->init_data.termination_current); &bq->init_data.termination_current);
if (ret) if (ret)
return ret; goto error_2;
ret = of_property_read_u32(np, "ti,resistor-sense", ret = of_property_read_u32(np, "ti,resistor-sense",
&bq->init_data.resistor_sense); &bq->init_data.resistor_sense);
if (ret) if (ret)
return ret; goto error_2;
} else { } else {
memcpy(&bq->init_data, pdata, sizeof(bq->init_data)); memcpy(&bq->init_data, pdata, sizeof(bq->init_data));
} }
......
This diff is collapsed.
...@@ -417,6 +417,9 @@ static int psy_register_thermal(struct power_supply *psy) ...@@ -417,6 +417,9 @@ static int psy_register_thermal(struct power_supply *psy)
{ {
int i; int i;
if (psy->no_thermal)
return 0;
/* Register battery zone device psy reports temperature */ /* Register battery zone device psy reports temperature */
for (i = 0; i < psy->num_properties; i++) { for (i = 0; i < psy->num_properties; i++) {
if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) { if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
......
...@@ -253,9 +253,6 @@ struct charger_manager { ...@@ -253,9 +253,6 @@ struct charger_manager {
struct device *dev; struct device *dev;
struct charger_desc *desc; struct charger_desc *desc;
struct power_supply *fuel_gauge;
struct power_supply **charger_stat;
#ifdef CONFIG_THERMAL #ifdef CONFIG_THERMAL
struct thermal_zone_device *tzd_batt; struct thermal_zone_device *tzd_batt;
#endif #endif
......
...@@ -200,6 +200,12 @@ struct power_supply { ...@@ -200,6 +200,12 @@ struct power_supply {
void (*external_power_changed)(struct power_supply *psy); void (*external_power_changed)(struct power_supply *psy);
void (*set_charged)(struct power_supply *psy); void (*set_charged)(struct power_supply *psy);
/*
* Set if thermal zone should not be created for this power supply.
* For example for virtual supplies forwarding calls to actual
* sensors or other supplies.
*/
bool no_thermal;
/* For APM emulation, think legacy userspace. */ /* For APM emulation, think legacy userspace. */
int use_for_apm; int use_for_apm;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment