Commit c8192ba4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply

Pull power supply and reset changes from Sebastian Reichel:
 - new reset driver for ZTE SoCs
 - add support for sama5d3 reset handling
 - overhaul of twl4030 charger driver
 - misc fixes and cleanups

* tag 'for-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (35 commits)
  bq2415x_charger: Allow to load and use driver even if notify device is not registered yet
  twl4030_charger: fix compile error when TWL4030_MADC not available.
  power: bq24190_charger: Fix charge type sysfs property
  power: Allow compile test of GPIO consumers if !GPIOLIB
  power: Export I2C module alias information in missing drivers
  twl4030_charger: Increase current carefully while watching voltage.
  twl4030_charger: add ac/mode to match usb/mode
  twl4030_charger: add software controlled linear charging mode.
  twl4030_charger: enable manual enable/disable of usb charging.
  twl4030_charger: allow max_current to be managed via sysfs.
  twl4030_charger: distinguish between USB current and 'AC' current
  twl4030_charger: allow fine control of charger current.
  twl4030_charger: split uA calculation into a function.
  twl4030_charger: trust phy to determine when USB power is available.
  twl4030_charger: correctly handle -EPROBE_DEFER from devm_usb_get_phy_by_node
  twl4030_charger: convert to module_platform_driver instead of ..._probe.
  twl4030_charger: use runtime_pm to keep usb phy active while charging.
  rx51-battery: Set name to rx51-battery
  MAINTAINERS: AVS is not maintained via power supply tree
  power: olpc_battery: clean up eeprom read function
  ...
parents 9c6a019c b68c3161
What: /sys/class/power_supply/twl4030_ac/max_current
/sys/class/power_supply/twl4030_usb/max_current
Description:
Read/Write limit on current which may
be drawn from the ac (Accessory Charger) or
USB port.
Value is in micro-Amps.
Value is set automatically to an appropriate
value when a cable is plugged or unplugged.
Value can the set by writing to the attribute.
The change will only persist until the next
plug event. These event are reported via udev.
What: /sys/class/power_supply/twl4030_usb/mode
Description:
Changing mode for USB port.
Writing to this can disable charging.
Possible values are:
"auto" - draw power as appropriate for detected
power source and battery status.
"off" - do not draw any power.
"continuous"
- activate mode described as "linear" in
TWL data sheets. This uses whatever
current is available and doesn't switch off
when voltage drops.
This is useful for unstable power sources
such as bicycle dynamo, but care should
be taken that battery is not over-charged.
What: /sys/class/power_supply/twl4030_ac/mode
Description:
Changing mode for 'ac' port.
Writing to this can disable charging.
Possible values are:
"auto" - draw power as appropriate for detected
power source and battery status.
"off" - do not draw any power.
......@@ -87,7 +87,7 @@ One interrupt per TC channel in a TC block:
RSTC Reset Controller required properties:
- compatible: Should be "atmel,<chip>-rstc".
<chip> can be "at91sam9260" or "at91sam9g45"
<chip> can be "at91sam9260" or "at91sam9g45" or "sama5d3"
- reg: Should contain registers location and length
Example:
......
......@@ -8093,6 +8093,7 @@ T: git git://git.infradead.org/battery-2.6.git
S: Maintained
F: include/linux/power_supply.h
F: drivers/power/
X: drivers/power/avs/
PNP SUPPORT
M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
......
......@@ -788,9 +788,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
static struct regulator_consumer_supply usb1v8 = {
.supply = "usb1v8",
};
static struct regulator_consumer_supply usb3v1[] = {
{ .supply = "usb3v1" },
{ .supply = "bci3v1" },
static struct regulator_consumer_supply usb3v1 = {
.supply = "usb3v1",
};
/* First add the regulators so that they can be used by transceiver */
......@@ -818,7 +817,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
return PTR_ERR(child);
child = add_regulator_linked(TWL4030_REG_VUSB3V1,
&usb_fixed, usb3v1, 2,
&usb_fixed, &usb3v1, 1,
features);
if (IS_ERR(child))
return PTR_ERR(child);
......@@ -838,7 +837,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child) {
usb1v5.dev_name = dev_name(child);
usb1v8.dev_name = dev_name(child);
usb3v1[0].dev_name = dev_name(child);
usb3v1.dev_name = dev_name(child);
}
}
......
......@@ -333,7 +333,7 @@ config CHARGER_LP8788
config CHARGER_GPIO
tristate "GPIO charger"
depends on GPIOLIB
depends on GPIOLIB || COMPILE_TEST
help
Say Y to include support for chargers which report their online status
through a GPIO pin.
......@@ -391,26 +391,30 @@ config CHARGER_BQ2415X
config CHARGER_BQ24190
tristate "TI BQ24190 battery charger driver"
depends on I2C && GPIOLIB
depends on I2C
depends on GPIOLIB || COMPILE_TEST
help
Say Y to enable support for the TI BQ24190 battery charger.
config CHARGER_BQ24257
tristate "TI BQ24257 battery charger driver"
depends on I2C && GPIOLIB
depends on I2C
depends on GPIOLIB || COMPILE_TEST
depends on REGMAP_I2C
help
Say Y to enable support for the TI BQ24257 battery charger.
config CHARGER_BQ24735
tristate "TI BQ24735 battery charger support"
depends on I2C && GPIOLIB
depends on I2C
depends on GPIOLIB || COMPILE_TEST
help
Say Y to enable support for the TI BQ24735 battery charger.
config CHARGER_BQ25890
tristate "TI BQ25890 battery charger driver"
depends on I2C && GPIOLIB
depends on I2C
depends on GPIOLIB || COMPILE_TEST
select REGMAP_I2C
help
Say Y to enable support for the TI BQ25890 battery charger.
......@@ -462,7 +466,8 @@ config BATTERY_RT5033
config CHARGER_RT9455
tristate "Richtek RT9455 battery charger driver"
depends on I2C && GPIOLIB
depends on I2C
depends on GPIOLIB || COMPILE_TEST
select REGMAP_I2C
help
Say Y to enable support for Richtek RT9455 battery charger.
......
......@@ -170,7 +170,7 @@ struct bq2415x_device {
struct power_supply *charger;
struct power_supply_desc charger_desc;
struct delayed_work work;
struct power_supply *notify_psy;
struct device_node *notify_node;
struct notifier_block nb;
enum bq2415x_mode reported_mode;/* mode reported by hook function */
enum bq2415x_mode mode; /* currently configured mode */
......@@ -792,22 +792,47 @@ static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode)
}
static bool bq2415x_update_reported_mode(struct bq2415x_device *bq, int mA)
{
enum bq2415x_mode mode;
if (mA == 0)
mode = BQ2415X_MODE_OFF;
else if (mA < 500)
mode = BQ2415X_MODE_NONE;
else if (mA < 1800)
mode = BQ2415X_MODE_HOST_CHARGER;
else
mode = BQ2415X_MODE_DEDICATED_CHARGER;
if (bq->reported_mode == mode)
return false;
bq->reported_mode = mode;
return true;
}
static int bq2415x_notifier_call(struct notifier_block *nb,
unsigned long val, void *v)
{
struct bq2415x_device *bq =
container_of(nb, struct bq2415x_device, nb);
struct power_supply *psy = v;
enum bq2415x_mode mode;
union power_supply_propval prop;
int ret;
int mA;
if (val != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
if (psy != bq->notify_psy)
return NOTIFY_OK;
/* Ignore event if it was not send by notify_node/notify_device */
if (bq->notify_node) {
if (!psy->dev.parent ||
psy->dev.parent->of_node != bq->notify_node)
return NOTIFY_OK;
} else if (bq->init_data.notify_device) {
if (strcmp(psy->desc->name, bq->init_data.notify_device) != 0)
return NOTIFY_OK;
}
dev_dbg(bq->dev, "notifier call was called\n");
......@@ -816,22 +841,9 @@ static int bq2415x_notifier_call(struct notifier_block *nb,
if (ret != 0)
return NOTIFY_OK;
mA = prop.intval;
if (mA == 0)
mode = BQ2415X_MODE_OFF;
else if (mA < 500)
mode = BQ2415X_MODE_NONE;
else if (mA < 1800)
mode = BQ2415X_MODE_HOST_CHARGER;
else
mode = BQ2415X_MODE_DEDICATED_CHARGER;
if (bq->reported_mode == mode)
if (!bq2415x_update_reported_mode(bq, prop.intval))
return NOTIFY_OK;
bq->reported_mode = mode;
/* if automode is not enabled do not tell about reported_mode */
if (bq->automode < 1)
return NOTIFY_OK;
......@@ -1536,6 +1548,8 @@ static int bq2415x_probe(struct i2c_client *client,
struct device_node *np = client->dev.of_node;
struct bq2415x_platform_data *pdata = client->dev.platform_data;
const struct acpi_device_id *acpi_id = NULL;
struct power_supply *notify_psy = NULL;
union power_supply_propval prop;
if (!np && !pdata && !ACPI_HANDLE(&client->dev)) {
dev_err(&client->dev, "Neither devicetree, nor platform data, nor ACPI support\n");
......@@ -1569,25 +1583,6 @@ static int bq2415x_probe(struct i2c_client *client,
goto error_2;
}
if (np) {
bq->notify_psy = power_supply_get_by_phandle(np,
"ti,usb-charger-detection");
if (IS_ERR(bq->notify_psy)) {
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 && pdata->notify_device) {
bq->notify_psy = power_supply_get_by_name(pdata->notify_device);
} else {
bq->notify_psy = NULL;
}
i2c_set_clientdata(client, bq);
bq->id = num;
......@@ -1607,32 +1602,35 @@ static int bq2415x_probe(struct i2c_client *client,
"ti,current-limit",
&bq->init_data.current_limit);
if (ret)
goto error_3;
goto error_2;
ret = device_property_read_u32(bq->dev,
"ti,weak-battery-voltage",
&bq->init_data.weak_battery_voltage);
if (ret)
goto error_3;
goto error_2;
ret = device_property_read_u32(bq->dev,
"ti,battery-regulation-voltage",
&bq->init_data.battery_regulation_voltage);
if (ret)
goto error_3;
goto error_2;
ret = device_property_read_u32(bq->dev,
"ti,charge-current",
&bq->init_data.charge_current);
if (ret)
goto error_3;
goto error_2;
ret = device_property_read_u32(bq->dev,
"ti,termination-current",
&bq->init_data.termination_current);
if (ret)
goto error_3;
goto error_2;
ret = device_property_read_u32(bq->dev,
"ti,resistor-sense",
&bq->init_data.resistor_sense);
if (ret)
goto error_3;
goto error_2;
if (np)
bq->notify_node = of_parse_phandle(np,
"ti,usb-charger-detection", 0);
} else {
memcpy(&bq->init_data, pdata, sizeof(bq->init_data));
}
......@@ -1642,56 +1640,72 @@ static int bq2415x_probe(struct i2c_client *client,
ret = bq2415x_power_supply_init(bq);
if (ret) {
dev_err(bq->dev, "failed to register power supply: %d\n", ret);
goto error_3;
goto error_2;
}
ret = bq2415x_sysfs_init(bq);
if (ret) {
dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret);
goto error_4;
goto error_3;
}
ret = bq2415x_set_defaults(bq);
if (ret) {
dev_err(bq->dev, "failed to set default values: %d\n", ret);
goto error_5;
goto error_4;
}
if (bq->notify_psy) {
if (bq->notify_node || bq->init_data.notify_device) {
bq->nb.notifier_call = bq2415x_notifier_call;
ret = power_supply_reg_notifier(&bq->nb);
if (ret) {
dev_err(bq->dev, "failed to reg notifier: %d\n", ret);
goto error_6;
goto error_4;
}
/* Query for initial reported_mode and set it */
bq2415x_notifier_call(&bq->nb, PSY_EVENT_PROP_CHANGED,
bq->notify_psy);
bq2415x_set_mode(bq, bq->reported_mode);
bq->automode = 1;
dev_info(bq->dev, "automode enabled\n");
dev_info(bq->dev, "automode supported, waiting for events\n");
} else {
bq->automode = -1;
dev_info(bq->dev, "automode not supported\n");
}
/* Query for initial reported_mode and set it */
if (bq->nb.notifier_call) {
if (np) {
notify_psy = power_supply_get_by_phandle(np,
"ti,usb-charger-detection");
if (IS_ERR(notify_psy))
notify_psy = NULL;
} else if (bq->init_data.notify_device) {
notify_psy = power_supply_get_by_name(
bq->init_data.notify_device);
}
}
if (notify_psy) {
ret = power_supply_get_property(notify_psy,
POWER_SUPPLY_PROP_CURRENT_MAX, &prop);
power_supply_put(notify_psy);
if (ret == 0) {
bq2415x_update_reported_mode(bq, prop.intval);
bq2415x_set_mode(bq, bq->reported_mode);
}
}
INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work);
bq2415x_set_autotimer(bq, 1);
dev_info(bq->dev, "driver registered\n");
return 0;
error_6:
error_5:
bq2415x_sysfs_exit(bq);
error_4:
bq2415x_power_supply_exit(bq);
bq2415x_sysfs_exit(bq);
error_3:
if (bq->notify_psy)
power_supply_put(bq->notify_psy);
bq2415x_power_supply_exit(bq);
error_2:
if (bq->notify_node)
of_node_put(bq->notify_node);
kfree(name);
error_1:
mutex_lock(&bq2415x_id_mutex);
......@@ -1707,10 +1721,11 @@ static int bq2415x_remove(struct i2c_client *client)
{
struct bq2415x_device *bq = i2c_get_clientdata(client);
if (bq->notify_psy) {
if (bq->nb.notifier_call)
power_supply_unreg_notifier(&bq->nb);
power_supply_put(bq->notify_psy);
}
if (bq->notify_node)
of_node_put(bq->notify_node);
bq2415x_sysfs_exit(bq);
bq2415x_power_supply_exit(bq);
......
......@@ -902,7 +902,7 @@ static int bq24190_charger_property_is_writeable(struct power_supply *psy,
}
static enum power_supply_property bq24190_charger_properties[] = {
POWER_SUPPLY_PROP_TYPE,
POWER_SUPPLY_PROP_CHARGE_TYPE,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
......@@ -1515,6 +1515,7 @@ static const struct i2c_device_id bq24190_i2c_ids[] = {
{ "bq24190", BQ24190_REG_VPRS_PN_24190 },
{ },
};
MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
#ifdef CONFIG_OF
static const struct of_device_id bq24190_of_match[] = {
......@@ -1534,7 +1535,6 @@ static struct i2c_driver bq24190_driver = {
.id_table = bq24190_i2c_ids,
.driver = {
.name = "bq24190-charger",
.owner = THIS_MODULE,
.pm = &bq24190_pm_ops,
.of_match_table = of_match_ptr(bq24190_of_match),
},
......
......@@ -267,8 +267,9 @@ static int bq24735_charger_probe(struct i2c_client *client,
name = (char *)charger->pdata->name;
if (!name) {
name = kasprintf(GFP_KERNEL, "bq24735@%s",
dev_name(&client->dev));
name = devm_kasprintf(&client->dev, GFP_KERNEL,
"bq24735@%s",
dev_name(&client->dev));
if (!name) {
dev_err(&client->dev, "Failed to alloc device name\n");
return -ENOMEM;
......@@ -296,23 +297,21 @@ static int bq24735_charger_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(&client->dev, "Failed to read manufacturer id : %d\n",
ret);
goto err_free_name;
return ret;
} else if (ret != 0x0040) {
dev_err(&client->dev,
"manufacturer id mismatch. 0x0040 != 0x%04x\n", ret);
ret = -ENODEV;
goto err_free_name;
return -ENODEV;
}
ret = bq24735_read_word(client, BQ24735_DEVICE_ID);
if (ret < 0) {
dev_err(&client->dev, "Failed to read device id : %d\n", ret);
goto err_free_name;
return ret;
} else if (ret != 0x000B) {
dev_err(&client->dev,
"device id mismatch. 0x000b != 0x%04x\n", ret);
ret = -ENODEV;
goto err_free_name;
return -ENODEV;
}
if (gpio_is_valid(charger->pdata->status_gpio)) {
......@@ -331,7 +330,7 @@ static int bq24735_charger_probe(struct i2c_client *client,
ret = bq24735_config_charger(charger);
if (ret < 0) {
dev_err(&client->dev, "failed in configuring charger");
goto err_free_name;
return ret;
}
/* check for AC adapter presence */
......@@ -339,17 +338,17 @@ static int bq24735_charger_probe(struct i2c_client *client,
ret = bq24735_enable_charging(charger);
if (ret < 0) {
dev_err(&client->dev, "Failed to enable charging\n");
goto err_free_name;
return ret;
}
}
charger->charger = power_supply_register(&client->dev, supply_desc,
&psy_cfg);
charger->charger = devm_power_supply_register(&client->dev, supply_desc,
&psy_cfg);
if (IS_ERR(charger->charger)) {
ret = PTR_ERR(charger->charger);
dev_err(&client->dev, "Failed to register power supply: %d\n",
ret);
goto err_free_name;
return ret;
}
if (client->irq) {
......@@ -364,33 +363,10 @@ static int bq24735_charger_probe(struct i2c_client *client,
dev_err(&client->dev,
"Unable to register IRQ %d err %d\n",
client->irq, ret);
goto err_unregister_supply;
return ret;
}
}
return 0;
err_unregister_supply:
power_supply_unregister(charger->charger);
err_free_name:
if (name != charger->pdata->name)
kfree(name);
return ret;
}
static int bq24735_charger_remove(struct i2c_client *client)
{
struct bq24735 *charger = i2c_get_clientdata(client);
if (charger->client->irq)
devm_free_irq(&charger->client->dev, charger->client->irq,
&charger->charger);
power_supply_unregister(charger->charger);
if (charger->charger_desc.name != charger->pdata->name)
kfree(charger->charger_desc.name);
return 0;
}
......@@ -409,11 +385,9 @@ MODULE_DEVICE_TABLE(of, bq24735_match_ids);
static struct i2c_driver bq24735_charger_driver = {
.driver = {
.name = "bq24735-charger",
.owner = THIS_MODULE,
.of_match_table = bq24735_match_ids,
},
.probe = bq24735_charger_probe,
.remove = bq24735_charger_remove,
.id_table = bq24735_charger_id,
};
......
......@@ -39,47 +39,49 @@
#include <linux/power/bq27x00_battery.h>
#define DRIVER_VERSION "1.2.0"
#define BQ27x00_REG_TEMP 0x06
#define BQ27x00_REG_VOLT 0x08
#define BQ27x00_REG_AI 0x14
#define BQ27x00_REG_FLAGS 0x0A
#define BQ27x00_REG_TTE 0x16
#define BQ27x00_REG_TTF 0x18
#define BQ27x00_REG_TTECP 0x26
#define BQ27x00_REG_NAC 0x0C /* Nominal available capacity */
#define BQ27x00_REG_LMD 0x12 /* Last measured discharge */
#define BQ27x00_REG_CYCT 0x2A /* Cycle count total */
#define BQ27x00_REG_AE 0x22 /* Available energy */
#define BQ27x00_POWER_AVG 0x24
#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */
#define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */
#define BQ27000_FLAG_EDVF BIT(0) /* Final End-of-Discharge-Voltage flag */
#define BQ27000_FLAG_EDV1 BIT(1) /* First End-of-Discharge-Voltage flag */
#define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */
#define BQ27000_FLAG_FC BIT(5)
#define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */
#define BQ27500_REG_SOC 0x2C
#define BQ27500_REG_DCAP 0x3C /* Design capacity */
#define BQ27500_FLAG_DSC BIT(0)
#define BQ27500_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */
#define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */
#define BQ27500_FLAG_FC BIT(9)
#define BQ27500_FLAG_OTC BIT(15)
#define BQ27742_POWER_AVG 0x76
#define BQ27510_REG_SOC 0x20
#define BQ27510_REG_DCAP 0x2E /* Design capacity */
#define BQ27510_REG_CYCT 0x1E /* Cycle count total */
#define DRIVER_VERSION "1.2.0"
#define BQ27XXX_MANUFACTURER "Texas Instruments"
#define BQ27x00_REG_TEMP 0x06
#define BQ27x00_REG_VOLT 0x08
#define BQ27x00_REG_AI 0x14
#define BQ27x00_REG_FLAGS 0x0A
#define BQ27x00_REG_TTE 0x16
#define BQ27x00_REG_TTF 0x18
#define BQ27x00_REG_TTECP 0x26
#define BQ27x00_REG_NAC 0x0C /* Nominal available capacity */
#define BQ27x00_REG_LMD 0x12 /* Last measured discharge */
#define BQ27x00_REG_CYCT 0x2A /* Cycle count total */
#define BQ27x00_REG_AE 0x22 /* Available energy */
#define BQ27x00_POWER_AVG 0x24
#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */
#define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */
#define BQ27000_FLAG_EDVF BIT(0) /* Final End-of-Discharge-Voltage flag */
#define BQ27000_FLAG_EDV1 BIT(1) /* First End-of-Discharge-Voltage flag */
#define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */
#define BQ27000_FLAG_FC BIT(5)
#define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */
#define BQ27500_REG_SOC 0x2C
#define BQ27500_REG_DCAP 0x3C /* Design capacity */
#define BQ27500_FLAG_DSC BIT(0)
#define BQ27500_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */
#define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */
#define BQ27500_FLAG_FC BIT(9)
#define BQ27500_FLAG_OTC BIT(15)
#define BQ27742_POWER_AVG 0x76
#define BQ27510_REG_SOC 0x20
#define BQ27510_REG_DCAP 0x2E /* Design capacity */
#define BQ27510_REG_CYCT 0x1E /* Cycle count total */
/* bq27425 register addresses are same as bq27x00 addresses minus 4 */
#define BQ27425_REG_OFFSET 0x04
#define BQ27425_REG_OFFSET 0x04
#define BQ27425_REG_SOC (0x1C + BQ27425_REG_OFFSET)
#define BQ27425_REG_DCAP (0x3C + BQ27425_REG_OFFSET)
#define BQ27425_REG_DCAP (0x3C + BQ27425_REG_OFFSET)
#define BQ27000_RS 20 /* Resistor sense */
#define BQ27x00_POWER_CONSTANT (256 * 29200 / 1000)
......@@ -106,7 +108,7 @@ struct bq27x00_reg_cache {
};
struct bq27x00_device_info {
struct device *dev;
struct device *dev;
int id;
enum bq27x00_chip chip;
......@@ -142,6 +144,7 @@ static enum power_supply_property bq27x00_battery_props[] = {
POWER_SUPPLY_PROP_ENERGY_NOW,
POWER_SUPPLY_PROP_POWER_AVG,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_MANUFACTURER,
};
static enum power_supply_property bq27425_battery_props[] = {
......@@ -156,6 +159,7 @@ static enum power_supply_property bq27425_battery_props[] = {
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_MANUFACTURER,
};
static enum power_supply_property bq27742_battery_props[] = {
......@@ -174,6 +178,7 @@ static enum power_supply_property bq27742_battery_props[] = {
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_POWER_AVG,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_MANUFACTURER,
};
static enum power_supply_property bq27510_battery_props[] = {
......@@ -192,19 +197,20 @@ static enum power_supply_property bq27510_battery_props[] = {
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_POWER_AVG,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_MANUFACTURER,
};
static unsigned int poll_interval = 360;
module_param(poll_interval, uint, 0644);
MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \
"0 disables polling");
MODULE_PARM_DESC(poll_interval,
"battery poll interval in seconds - 0 disables polling");
/*
* Common code for BQ27x00 devices
*/
static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,
bool single)
bool single)
{
if (di->chip == BQ27425)
return di->bus.read(di, reg - BQ27425_REG_OFFSET, single);
......@@ -313,8 +319,9 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
ilmd = bq27x00_read(di, BQ27510_REG_DCAP, false);
else
ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false);
} else
} else {
ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true);
}
if (ilmd < 0) {
dev_dbg(di->dev, "error reading initial last measured discharge\n");
......@@ -445,7 +452,7 @@ static int bq27x00_battery_read_health(struct bq27x00_device_info *di)
return tval;
}
if ((di->chip == BQ27500)) {
if (di->chip == BQ27500) {
if (tval & BQ27500_FLAG_SOCF)
tval = POWER_SUPPLY_HEALTH_DEAD;
else if (tval & BQ27500_FLAG_OTC)
......@@ -559,7 +566,7 @@ static void bq27x00_battery_poll(struct work_struct *work)
* Or 0 if something fails.
*/
static int bq27x00_battery_current(struct bq27x00_device_info *di,
union power_supply_propval *val)
union power_supply_propval *val)
{
int curr;
int flags;
......@@ -587,7 +594,7 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di,
}
static int bq27x00_battery_status(struct bq27x00_device_info *di,
union power_supply_propval *val)
union power_supply_propval *val)
{
int status;
......@@ -615,7 +622,7 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di,
}
static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
union power_supply_propval *val)
union power_supply_propval *val)
{
int level;
......@@ -649,7 +656,7 @@ static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
* Or < 0 if something fails.
*/
static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
union power_supply_propval *val)
union power_supply_propval *val)
{
int volt;
......@@ -665,7 +672,7 @@ static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
}
static int bq27x00_simple_value(int value,
union power_supply_propval *val)
union power_supply_propval *val)
{
if (value < 0)
return value;
......@@ -749,6 +756,9 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_HEALTH:
ret = bq27x00_simple_value(di->cache.health, val);
break;
case POWER_SUPPLY_PROP_MANUFACTURER:
val->strval = BQ27XXX_MANUFACTURER;
break;
default:
return -EINVAL;
}
......@@ -827,7 +837,6 @@ static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
mutex_destroy(&di->lock);
}
/* i2c specific code */
#ifdef CONFIG_BATTERY_BQ27X00_I2C
......@@ -888,14 +897,12 @@ static int bq27x00_battery_probe(struct i2c_client *client,
name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num);
if (!name) {
dev_err(&client->dev, "failed to allocate device name\n");
retval = -ENOMEM;
goto batt_failed;
}
di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL);
if (!di) {
dev_err(&client->dev, "failed to allocate device info data\n");
retval = -ENOMEM;
goto batt_failed;
}
......@@ -956,8 +963,9 @@ static struct i2c_driver bq27x00_battery_driver = {
static inline int bq27x00_battery_i2c_init(void)
{
int ret = i2c_add_driver(&bq27x00_battery_driver);
if (ret)
printk(KERN_ERR "Unable to register BQ27x00 i2c driver\n");
pr_err("Unable to register BQ27x00 i2c driver\n");
return ret;
}
......@@ -978,7 +986,7 @@ static inline void bq27x00_battery_i2c_exit(void) {};
#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM
static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg,
bool single)
bool single)
{
struct device *dev = di->dev;
struct bq27000_platform_data *pdata = dev->platform_data;
......@@ -1028,10 +1036,8 @@ static int bq27000_battery_probe(struct platform_device *pdev)
}
di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
if (!di) {
dev_err(&pdev->dev, "failed to allocate device info data\n");
if (!di)
return -ENOMEM;
}
platform_set_drvdata(pdev, di);
......@@ -1064,8 +1070,9 @@ static struct platform_driver bq27000_battery_driver = {
static inline int bq27x00_battery_platform_init(void)
{
int ret = platform_driver_register(&bq27000_battery_driver);
if (ret)
printk(KERN_ERR "Unable to register BQ27000 platform driver\n");
pr_err("Unable to register BQ27000 platform driver\n");
return ret;
}
......
......@@ -637,10 +637,6 @@ static ssize_t ds2780_read_param_eeprom_bin(struct file *filp,
struct power_supply *psy = to_power_supply(dev);
struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
count = min_t(loff_t, count,
DS2780_EEPROM_BLOCK1_END -
DS2780_EEPROM_BLOCK1_START + 1 - off);
return ds2780_read_block(dev_info, buf,
DS2780_EEPROM_BLOCK1_START + off, count);
}
......@@ -655,10 +651,6 @@ static ssize_t ds2780_write_param_eeprom_bin(struct file *filp,
struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
int ret;
count = min_t(loff_t, count,
DS2780_EEPROM_BLOCK1_END -
DS2780_EEPROM_BLOCK1_START + 1 - off);
ret = ds2780_write(dev_info, buf,
DS2780_EEPROM_BLOCK1_START + off, count);
if (ret < 0)
......@@ -676,7 +668,7 @@ static struct bin_attribute ds2780_param_eeprom_bin_attr = {
.name = "param_eeprom",
.mode = S_IRUGO | S_IWUSR,
},
.size = DS2780_EEPROM_BLOCK1_END - DS2780_EEPROM_BLOCK1_START + 1,
.size = DS2780_PARAM_EEPROM_SIZE,
.read = ds2780_read_param_eeprom_bin,
.write = ds2780_write_param_eeprom_bin,
};
......@@ -690,10 +682,6 @@ static ssize_t ds2780_read_user_eeprom_bin(struct file *filp,
struct power_supply *psy = to_power_supply(dev);
struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
count = min_t(loff_t, count,
DS2780_EEPROM_BLOCK0_END -
DS2780_EEPROM_BLOCK0_START + 1 - off);
return ds2780_read_block(dev_info, buf,
DS2780_EEPROM_BLOCK0_START + off, count);
}
......@@ -708,10 +696,6 @@ static ssize_t ds2780_write_user_eeprom_bin(struct file *filp,
struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
int ret;
count = min_t(loff_t, count,
DS2780_EEPROM_BLOCK0_END -
DS2780_EEPROM_BLOCK0_START + 1 - off);
ret = ds2780_write(dev_info, buf,
DS2780_EEPROM_BLOCK0_START + off, count);
if (ret < 0)
......@@ -729,7 +713,7 @@ static struct bin_attribute ds2780_user_eeprom_bin_attr = {
.name = "user_eeprom",
.mode = S_IRUGO | S_IWUSR,
},
.size = DS2780_EEPROM_BLOCK0_END - DS2780_EEPROM_BLOCK0_START + 1,
.size = DS2780_USER_EEPROM_SIZE,
.read = ds2780_read_user_eeprom_bin,
.write = ds2780_write_user_eeprom_bin,
};
......
......@@ -639,8 +639,6 @@ static ssize_t ds2781_read_param_eeprom_bin(struct file *filp,
struct power_supply *psy = to_power_supply(dev);
struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
count = min_t(loff_t, count, DS2781_PARAM_EEPROM_SIZE - off);
return ds2781_read_block(dev_info, buf,
DS2781_EEPROM_BLOCK1_START + off, count);
}
......@@ -655,8 +653,6 @@ static ssize_t ds2781_write_param_eeprom_bin(struct file *filp,
struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
int ret;
count = min_t(loff_t, count, DS2781_PARAM_EEPROM_SIZE - off);
ret = ds2781_write(dev_info, buf,
DS2781_EEPROM_BLOCK1_START + off, count);
if (ret < 0)
......@@ -688,8 +684,6 @@ static ssize_t ds2781_read_user_eeprom_bin(struct file *filp,
struct power_supply *psy = to_power_supply(dev);
struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
count = min_t(loff_t, count, DS2781_USER_EEPROM_SIZE - off);
return ds2781_read_block(dev_info, buf,
DS2781_EEPROM_BLOCK0_START + off, count);
......@@ -705,8 +699,6 @@ static ssize_t ds2781_write_user_eeprom_bin(struct file *filp,
struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
int ret;
count = min_t(loff_t, count, DS2781_USER_EEPROM_SIZE - off);
ret = ds2781_write(dev_info, buf,
DS2781_EEPROM_BLOCK0_START + off, count);
if (ret < 0)
......
......@@ -14,7 +14,6 @@
#include <linux/swab.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/idr.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
......@@ -63,15 +62,11 @@ struct ltc294x_info {
struct power_supply_desc supply_desc; /* Supply description */
struct delayed_work work; /* Work scheduler */
int num_regs; /* Number of registers (chip type) */
int id; /* Identifier of ltc294x chip */
int charge; /* Last charge register content */
int r_sense; /* mOhm */
int Qlsb; /* nAh */
};
static DEFINE_IDR(ltc294x_id);
static DEFINE_MUTEX(ltc294x_lock);
static inline int convert_bin_to_uAh(
const struct ltc294x_info *info, int Q)
{
......@@ -371,10 +366,6 @@ static int ltc294x_i2c_remove(struct i2c_client *client)
cancel_delayed_work(&info->work);
power_supply_unregister(info->supply);
kfree(info->supply_desc.name);
mutex_lock(&ltc294x_lock);
idr_remove(&ltc294x_id, info->id);
mutex_unlock(&ltc294x_lock);
return 0;
}
......@@ -384,44 +375,28 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
struct power_supply_config psy_cfg = {};
struct ltc294x_info *info;
int ret;
int num;
u32 prescaler_exp;
s32 r_sense;
struct device_node *np;
mutex_lock(&ltc294x_lock);
ret = idr_alloc(&ltc294x_id, client, 0, 0, GFP_KERNEL);
mutex_unlock(&ltc294x_lock);
if (ret < 0)
goto fail_id;
num = ret;
info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
if (info == NULL) {
ret = -ENOMEM;
goto fail_info;
}
if (info == NULL)
return -ENOMEM;
i2c_set_clientdata(client, info);
info->num_regs = id->driver_data;
info->supply_desc.name = kasprintf(GFP_KERNEL, "%s-%d", client->name,
num);
if (!info->supply_desc.name) {
ret = -ENOMEM;
goto fail_name;
}
np = of_node_get(client->dev.of_node);
info->num_regs = id->driver_data;
info->supply_desc.name = np->name;
/* r_sense can be negative, when sense+ is connected to the battery
* instead of the sense-. This results in reversed measurements. */
ret = of_property_read_u32(np, "lltc,resistor-sense", &r_sense);
if (ret < 0) {
dev_err(&client->dev,
"Could not find lltc,resistor-sense in devicetree\n");
goto fail_name;
return ret;
}
info->r_sense = r_sense;
......@@ -446,7 +421,6 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
}
info->client = client;
info->id = num;
info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
info->supply_desc.properties = ltc294x_properties;
if (info->num_regs >= LTC294X_REG_TEMPERATURE_LSB)
......@@ -473,31 +447,19 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
ret = ltc294x_reset(info, prescaler_exp);
if (ret < 0) {
dev_err(&client->dev, "Communication with chip failed\n");
goto fail_comm;
return ret;
}
info->supply = power_supply_register(&client->dev, &info->supply_desc,
&psy_cfg);
if (IS_ERR(info->supply)) {
dev_err(&client->dev, "failed to register ltc2941\n");
ret = PTR_ERR(info->supply);
goto fail_register;
return PTR_ERR(info->supply);
} else {
schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ);
}
return 0;
fail_register:
kfree(info->supply_desc.name);
fail_comm:
fail_name:
fail_info:
mutex_lock(&ltc294x_lock);
idr_remove(&ltc294x_id, num);
mutex_unlock(&ltc294x_lock);
fail_id:
return ret;
}
#ifdef CONFIG_PM_SLEEP
......
......@@ -521,11 +521,6 @@ static ssize_t olpc_bat_eeprom_read(struct file *filp, struct kobject *kobj,
int ret;
int i;
if (off >= EEPROM_SIZE)
return 0;
if (off + count > EEPROM_SIZE)
count = EEPROM_SIZE - off;
for (i = 0; i < count; i++) {
ec_byte = EEPROM_START + off + i;
ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &buf[i], 1);
......@@ -545,7 +540,7 @@ static struct bin_attribute olpc_bat_eeprom = {
.name = "eeprom",
.mode = S_IRUGO,
},
.size = 0,
.size = EEPROM_SIZE,
.read = olpc_bat_eeprom_read,
};
......
......@@ -1244,7 +1244,6 @@ static struct i2c_driver pm2xxx_charger_driver = {
.remove = pm2xxx_wall_charger_remove,
.driver = {
.name = "pm2xxx-wall_charger",
.owner = THIS_MODULE,
.pm = PM2XXX_PM_OPS,
},
.id_table = pm2xxx_id,
......
......@@ -166,5 +166,12 @@ config POWER_RESET_RMOBILE
help
Reboot support for Renesas R-Mobile and SH-Mobile SoCs.
config POWER_RESET_ZX
tristate "ZTE SoCs reset driver"
depends on ARCH_ZX || COMPILE_TEST
depends on HAS_IOMEM
help
Reboot support for ZTE SoCs.
endif
......@@ -19,3 +19,4 @@ obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o
obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o
obj-$(CONFIG_POWER_RESET_SYSCON_POWEROFF) += syscon-poweroff.o
obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o
obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
......@@ -123,6 +123,15 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode,
return NOTIFY_DONE;
}
static int sama5d3_restart(struct notifier_block *this, unsigned long mode,
void *cmd)
{
writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST),
at91_rstc_base);
return NOTIFY_DONE;
}
static void __init at91_reset_status(struct platform_device *pdev)
{
u32 reg = readl(at91_rstc_base + AT91_RSTC_SR);
......@@ -155,13 +164,13 @@ static void __init at91_reset_status(struct platform_device *pdev)
static const struct of_device_id at91_ramc_of_match[] = {
{ .compatible = "atmel,at91sam9260-sdramc", },
{ .compatible = "atmel,at91sam9g45-ddramc", },
{ .compatible = "atmel,sama5d3-ddramc", },
{ /* sentinel */ }
};
static const struct of_device_id at91_reset_of_match[] = {
{ .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart },
{ .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
{ .compatible = "atmel,sama5d3-rstc", .data = sama5d3_restart },
{ /* sentinel */ }
};
......@@ -181,13 +190,16 @@ static int at91_reset_of_probe(struct platform_device *pdev)
return -ENODEV;
}
for_each_matching_node(np, at91_ramc_of_match) {
at91_ramc_base[idx] = of_iomap(np, 0);
if (!at91_ramc_base[idx]) {
dev_err(&pdev->dev, "Could not map ram controller address\n");
return -ENODEV;
if (!of_device_is_compatible(pdev->dev.of_node, "atmel,sama5d3-rstc")) {
/* we need to shutdown the ddr controller, so get ramc base */
for_each_matching_node(np, at91_ramc_of_match) {
at91_ramc_base[idx] = of_iomap(np, 0);
if (!at91_ramc_base[idx]) {
dev_err(&pdev->dev, "Could not map ram controller address\n");
return -ENODEV;
}
idx++;
}
idx++;
}
match = of_match_node(at91_reset_of_match, pdev->dev.of_node);
......
/*
* ZTE zx296702 SoC reset code
*
* Copyright (c) 2015 Linaro Ltd.
*
* Author: Jun Nie <jun.nie@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
static void __iomem *base;
static void __iomem *pcu_base;
static int zx_restart_handler(struct notifier_block *this,
unsigned long mode, void *cmd)
{
writel_relaxed(1, base + 0xb0);
writel_relaxed(1, pcu_base + 0x34);
mdelay(50);
pr_emerg("Unable to restart system\n");
return NOTIFY_DONE;
}
static struct notifier_block zx_restart_nb = {
.notifier_call = zx_restart_handler,
.priority = 128,
};
static int zx_reboot_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
int err;
base = of_iomap(np, 0);
if (!base) {
WARN(1, "failed to map base address");
return -ENODEV;
}
np = of_find_compatible_node(NULL, NULL, "zte,zx296702-pcu");
pcu_base = of_iomap(np, 0);
if (!pcu_base) {
iounmap(base);
WARN(1, "failed to map pcu_base address");
return -ENODEV;
}
err = register_restart_handler(&zx_restart_nb);
if (err)
dev_err(&pdev->dev, "Register restart handler failed(err=%d)\n",
err);
return err;
}
static const struct of_device_id zx_reboot_of_match[] = {
{ .compatible = "zte,sysctrl" },
{}
};
static struct platform_driver zx_reboot_driver = {
.probe = zx_reboot_probe,
.driver = {
.name = "zx-reboot",
.of_match_table = zx_reboot_of_match,
},
};
module_platform_driver(zx_reboot_driver);
......@@ -165,7 +165,7 @@ static const struct i2c_device_id rt5033_battery_id[] = {
{ "rt5033-battery", },
{ }
};
MODULE_DEVICE_TABLE(platform, rt5033_battery_id);
MODULE_DEVICE_TABLE(i2c, rt5033_battery_id);
static struct i2c_driver rt5033_battery_driver = {
.driver = {
......
......@@ -973,7 +973,6 @@ static int rt9455_irq_handler_check_irq2_register(struct rt9455_info *info,
if (irq2 & GET_MASK(F_CHRVPI)) {
dev_dbg(dev, "Charger fault occurred\n");
alert_userspace = true;
/*
* CHRVPI bit is set in 2 cases:
* 1. when the power source is connected to the charger.
......@@ -981,6 +980,9 @@ static int rt9455_irq_handler_check_irq2_register(struct rt9455_info *info,
* To identify the case, PWR_RDY bit is checked. Because
* PWR_RDY bit is set / cleared after CHRVPI interrupt is
* triggered, it is used delayed_work to later read PWR_RDY bit.
* Also, do not set to true alert_userspace, because there is no
* need to notify userspace when CHRVPI interrupt has occurred.
* Userspace will be notified after PWR_RDY bit is read.
*/
queue_delayed_work(system_power_efficient_wq,
&info->pwr_rdy_work,
......@@ -1178,7 +1180,7 @@ static irqreturn_t rt9455_irq_handler_thread(int irq, void *data)
/*
* Sometimes, an interrupt occurs while rt9455_probe() function
* is executing and power_supply_register() is not yet called.
* Do not call power_supply_charged() in this case.
* Do not call power_supply_changed() in this case.
*/
if (info->charger)
power_supply_changed(info->charger);
......@@ -1478,6 +1480,11 @@ static void rt9455_pwr_rdy_work_callback(struct work_struct *work)
RT9455_MAX_CHARGING_TIME * HZ);
break;
}
/*
* Notify userspace that the charger has been either connected to or
* disconnected from the power source.
*/
power_supply_changed(info->charger);
}
static void rt9455_max_charging_time_work_callback(struct work_struct *work)
......@@ -1533,6 +1540,11 @@ static void rt9455_batt_presence_work_callback(struct work_struct *work)
if (ret)
dev_err(dev, "Failed to unmask BATAB interrupt\n");
}
/*
* Notify userspace that the battery is now connected to the
* charger.
*/
power_supply_changed(info->charger);
}
}
......
......@@ -215,7 +215,7 @@ static int rx51_battery_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, di);
di->dev = &pdev->dev;
di->bat_desc.name = dev_name(&pdev->dev);
di->bat_desc.name = "rx51-battery";
di->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
di->bat_desc.properties = rx51_battery_props;
di->bat_desc.num_properties = ARRAY_SIZE(rx51_battery_props);
......
This diff is collapsed.
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