You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'for-v3.8-merged' of git://git.infradead.org/battery-2.6
Pull battery subsystem updates from Anton Vorontsov:
"Highlights:
- Two new drivers from Pali Rohár and N900 hackers: rx51_battery and
bq2415x_charger. The drivers are a part of a solution to replace
the proprietary Nokia BME stack
- Power supply core now registers devices with a thermal cooling
subsystem, so we can now automatically throttle charging. Thanks
to Ramakrishna Pallala!
- Device tree support for ab8500 and max8925_power drivers
- Random fixups and enhancements for a bunch of drivers."
* tag 'for-v3.8-merged' of git://git.infradead.org/battery-2.6: (22 commits)
max8925_power: Add support for device-tree initialization
ab8500: Add devicetree support for chargalg
ab8500: Add devicetree support for charger
ab8500: Add devicetree support for btemp
ab8500: Add devicetree support for fuelgauge
twl4030_charger: Change TWL4030_MODULE_* ids to TWL_MODULE_*
jz4740-battery: Use devm_request_and_ioremap
jz4740-battery: Use devm_kzalloc
bq27x00_battery: Fixup nominal available capacity reporting
bq2415x_charger: Fix style issues
bq2415x_charger: Add Kconfig/Makefile entries
power_supply: Add bq2415x charger driver
power_supply: Add new Nokia RX-51 (N900) power supply battery driver
max17042_battery: Fix missing verify_model_lock() return value check
ds2782_battery: Fix signedness bug in ds278x_read_reg16()
lp8788-charger: Fix ADC channel names
lp8788-charger: Fix wrong ADC conversion
lp8788-charger: Use consumer device name on setting IIO channels
power_supply: Register power supply for thermal cooling device
power_supply: Add support for CHARGE_CONTROL_* attributes
...
This commit is contained in:
@@ -24,7 +24,32 @@ ab8500-bm : : : Battery Manager
|
||||
ab8500-btemp : : : Battery Temperature
|
||||
ab8500-charger : : : Battery Charger
|
||||
ab8500-codec : : : Audio Codec
|
||||
ab8500-fg : : : Fuel Gauge
|
||||
ab8500-fg : : vddadc : Fuel Gauge
|
||||
: NCONV_ACCU : : Accumulate N Sample Conversion
|
||||
: BATT_OVV : : Battery Over Voltage
|
||||
: LOW_BAT_F : : LOW threshold battery voltage
|
||||
: CC_INT_CALIB : : Coulomb Counter Internal Calibration
|
||||
: CCEOC : : Coulomb Counter End of Conversion
|
||||
ab8500-btemp : : vtvout : Battery Temperature
|
||||
: BAT_CTRL_INDB : : Battery Removal Indicator
|
||||
: BTEMP_LOW : : Btemp < BtempLow, if battery temperature is lower than -10°C
|
||||
: BTEMP_LOW_MEDIUM : : BtempLow < Btemp < BtempMedium,if battery temperature is between -10 and 0°C
|
||||
: BTEMP_MEDIUM_HIGH : : BtempMedium < Btemp < BtempHigh,if battery temperature is between 0°C and“MaxTemp
|
||||
: BTEMP_HIGH : : Btemp > BtempHigh, if battery temperature is higher than “MaxTemp
|
||||
ab8500-charger : : vddadc : Charger interface
|
||||
: MAIN_CH_UNPLUG_DET : : main charger unplug detection management (not in 8505)
|
||||
: MAIN_CHARGE_PLUG_DET : : main charger plug detection management (not in 8505)
|
||||
: MAIN_EXT_CH_NOT_OK : : main charger not OK
|
||||
: MAIN_CH_TH_PROT_R : : Die temp is above main charger
|
||||
: MAIN_CH_TH_PROT_F : : Die temp is below main charger
|
||||
: VBUS_DET_F : : VBUS falling detected
|
||||
: VBUS_DET_R : : VBUS rising detected
|
||||
: USB_LINK_STATUS : : USB link status has changed
|
||||
: USB_CH_TH_PROT_R : : Die temp is above usb charger
|
||||
: USB_CH_TH_PROT_F : : Die temp is below usb charger
|
||||
: USB_CHARGER_NOT_OKR : : allowed USB charger not ok detection
|
||||
: VBUS_OVV : : Overvoltage on Vbus ball detected (USB charge is stopped)
|
||||
: CH_WD_EXP : : Charger watchdog detected
|
||||
ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter
|
||||
SW_CONV_END : :
|
||||
ab8500-gpio : : : GPIO Controller
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
=== AB8500 Battery Temperature Monitor Driver ===
|
||||
|
||||
The properties below describes the node for btemp driver.
|
||||
|
||||
Required Properties:
|
||||
- compatible = Shall be: "stericsson,ab8500-btemp"
|
||||
- battery = Shall be battery specific information
|
||||
|
||||
Example:
|
||||
ab8500_btemp {
|
||||
compatible = "stericsson,ab8500-btemp";
|
||||
battery = <&ab8500_battery>;
|
||||
};
|
||||
|
||||
For information on battery specific node, Ref:
|
||||
Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
|
||||
@@ -0,0 +1,16 @@
|
||||
=== AB8500 Charging Algorithm Driver ===
|
||||
|
||||
The properties below describes the node for chargalg driver.
|
||||
|
||||
Required Properties:
|
||||
- compatible = Shall be: "stericsson,ab8500-chargalg"
|
||||
- battery = Shall be battery specific information
|
||||
|
||||
Example:
|
||||
ab8500_chargalg {
|
||||
compatible = "stericsson,ab8500-chargalg";
|
||||
battery = <&ab8500_battery>;
|
||||
};
|
||||
|
||||
For information on battery specific node, Ref:
|
||||
Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
|
||||
@@ -0,0 +1,25 @@
|
||||
=== AB8500 Charger Driver ===
|
||||
|
||||
Required Properties:
|
||||
- compatible = Shall be "stericsson,ab8500-charger"
|
||||
- battery = Shall be battery specific information
|
||||
Example:
|
||||
ab8500_charger {
|
||||
compatible = "stericsson,ab8500-charger";
|
||||
battery = <&ab8500_battery>;
|
||||
};
|
||||
|
||||
- vddadc-supply: Supply for USB and Main charger
|
||||
Example:
|
||||
ab8500-charger {
|
||||
vddadc-supply = <&ab8500_ldo_tvout_reg>;
|
||||
}
|
||||
- autopower_cfg:
|
||||
Boolean value depicting the presence of 'automatic poweron after powerloss'
|
||||
Example:
|
||||
ab8500-charger {
|
||||
autopower_cfg;
|
||||
};
|
||||
|
||||
For information on battery specific node, Ref:
|
||||
Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
|
||||
@@ -0,0 +1,58 @@
|
||||
=== AB8500 Fuel Gauge Driver ===
|
||||
|
||||
AB8500 is a mixed signal multimedia and power management
|
||||
device comprising: power and energy-management-module,
|
||||
wall-charger, usb-charger, audio codec, general purpose adc,
|
||||
tvout, clock management and sim card interface.
|
||||
|
||||
Fuelgauge support is part of energy-management-modules, other
|
||||
components of this module are:
|
||||
main-charger, usb-combo-charger and battery-temperature-monitoring.
|
||||
|
||||
The properties below describes the node for fuelgauge driver.
|
||||
|
||||
Required Properties:
|
||||
- compatible = This shall be: "stericsson,ab8500-fg"
|
||||
- battery = Shall be battery specific information
|
||||
Example:
|
||||
ab8500_fg {
|
||||
compatible = "stericsson,ab8500-fg";
|
||||
battery = <&ab8500_battery>;
|
||||
};
|
||||
|
||||
dependent node:
|
||||
ab8500_battery: ab8500_battery {
|
||||
};
|
||||
This node will provide information on 'thermistor interface' and
|
||||
'battery technology type' used.
|
||||
|
||||
Properties of this node are:
|
||||
thermistor-on-batctrl:
|
||||
A boolean value indicating thermistor interface to battery
|
||||
|
||||
Note:
|
||||
'btemp' and 'batctrl' are the pins interfaced for battery temperature
|
||||
measurement, 'btemp' signal is used when NTC(negative temperature
|
||||
coefficient) resister is interfaced external to battery whereas
|
||||
'batctrl' pin is used when NTC resister is internal to battery.
|
||||
|
||||
Example:
|
||||
ab8500_battery: ab8500_battery {
|
||||
thermistor-on-batctrl;
|
||||
};
|
||||
indicates: NTC resister is internal to battery, 'batctrl' is used
|
||||
for thermal measurement.
|
||||
|
||||
The absence of property 'thermal-on-batctrl' indicates
|
||||
NTC resister is external to battery and 'btemp' signal is used
|
||||
for thermal measurement.
|
||||
|
||||
battery-type:
|
||||
This shall be the battery manufacturing technology type,
|
||||
allowed types are:
|
||||
"UNKNOWN" "NiMH" "LION" "LIPO" "LiFe" "NiCd" "LiMn"
|
||||
Example:
|
||||
ab8500_battery: ab8500_battery {
|
||||
stericsson,battery-type = "LIPO";
|
||||
}
|
||||
|
||||
@@ -123,6 +123,9 @@ CONSTANT_CHARGE_VOLTAGE - constant charge voltage programmed by charger.
|
||||
CONSTANT_CHARGE_VOLTAGE_MAX - maximum charge voltage supported by the
|
||||
power supply object.
|
||||
|
||||
CHARGE_CONTROL_LIMIT - current charge control limit setting
|
||||
CHARGE_CONTROL_LIMIT_MAX - maximum charge control limit setting
|
||||
|
||||
ENERGY_FULL, ENERGY_EMPTY - same as above but for energy.
|
||||
|
||||
CAPACITY - capacity in percents.
|
||||
|
||||
@@ -340,7 +340,33 @@
|
||||
vddadc-supply = <&ab8500_ldo_tvout_reg>;
|
||||
};
|
||||
|
||||
ab8500-usb {
|
||||
ab8500_battery: ab8500_battery {
|
||||
stericsson,battery-type = "LIPO";
|
||||
thermistor-on-batctrl;
|
||||
};
|
||||
|
||||
ab8500_fg {
|
||||
compatible = "stericsson,ab8500-fg";
|
||||
battery = <&ab8500_battery>;
|
||||
};
|
||||
|
||||
ab8500_btemp {
|
||||
compatible = "stericsson,ab8500-btemp";
|
||||
battery = <&ab8500_battery>;
|
||||
};
|
||||
|
||||
ab8500_charger {
|
||||
compatible = "stericsson,ab8500-charger";
|
||||
battery = <&ab8500_battery>;
|
||||
vddadc-supply = <&ab8500_ldo_tvout_reg>;
|
||||
};
|
||||
|
||||
ab8500_chargalg {
|
||||
compatible = "stericsson,ab8500-chargalg";
|
||||
battery = <&ab8500_battery>;
|
||||
};
|
||||
|
||||
ab8500_usb {
|
||||
compatible = "stericsson,ab8500-usb";
|
||||
interrupts = < 90 0x4
|
||||
96 0x4
|
||||
|
||||
@@ -1036,23 +1036,43 @@ static struct mfd_cell abx500_common_devs[] = {
|
||||
static struct mfd_cell ab8500_bm_devs[] = {
|
||||
{
|
||||
.name = "ab8500-charger",
|
||||
.of_compatible = "stericsson,ab8500-charger",
|
||||
.num_resources = ARRAY_SIZE(ab8500_charger_resources),
|
||||
.resources = ab8500_charger_resources,
|
||||
#ifndef CONFIG_OF
|
||||
.platform_data = &ab8500_bm_data,
|
||||
.pdata_size = sizeof(ab8500_bm_data),
|
||||
#endif
|
||||
},
|
||||
{
|
||||
.name = "ab8500-btemp",
|
||||
.of_compatible = "stericsson,ab8500-btemp",
|
||||
.num_resources = ARRAY_SIZE(ab8500_btemp_resources),
|
||||
.resources = ab8500_btemp_resources,
|
||||
#ifndef CONFIG_OF
|
||||
.platform_data = &ab8500_bm_data,
|
||||
.pdata_size = sizeof(ab8500_bm_data),
|
||||
#endif
|
||||
},
|
||||
{
|
||||
.name = "ab8500-fg",
|
||||
.of_compatible = "stericsson,ab8500-fg",
|
||||
.num_resources = ARRAY_SIZE(ab8500_fg_resources),
|
||||
.resources = ab8500_fg_resources,
|
||||
#ifndef CONFIG_OF
|
||||
.platform_data = &ab8500_bm_data,
|
||||
.pdata_size = sizeof(ab8500_bm_data),
|
||||
#endif
|
||||
},
|
||||
{
|
||||
.name = "ab8500-chargalg",
|
||||
.of_compatible = "stericsson,ab8500-chargalg",
|
||||
.num_resources = ARRAY_SIZE(ab8500_chargalg_resources),
|
||||
.resources = ab8500_chargalg_resources,
|
||||
#ifndef CONFIG_OF
|
||||
.platform_data = &ab8500_bm_data,
|
||||
.pdata_size = sizeof(ab8500_bm_data),
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+17
-7
@@ -245,6 +245,13 @@ config BATTERY_INTEL_MID
|
||||
Say Y here to enable the battery driver on Intel MID
|
||||
platforms.
|
||||
|
||||
config BATTERY_RX51
|
||||
tristate "Nokia RX-51 (N900) battery driver"
|
||||
depends on TWL4030_MADC
|
||||
help
|
||||
Say Y here to enable support for battery information on Nokia
|
||||
RX-51, also known as N900 tablet.
|
||||
|
||||
config CHARGER_ISP1704
|
||||
tristate "ISP1704 USB Charger Detection"
|
||||
depends on USB_OTG_UTILS
|
||||
@@ -315,6 +322,16 @@ config CHARGER_MAX8998
|
||||
Say Y to enable support for the battery charger control sysfs and
|
||||
platform data of MAX8998/LP3974 PMICs.
|
||||
|
||||
config CHARGER_BQ2415X
|
||||
tristate "TI BQ2415x battery charger driver"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y to enable support for the TI BQ2415x battery charger
|
||||
PMICs.
|
||||
|
||||
You'll need this driver to charge batteries on e.g. Nokia
|
||||
RX-51/N900.
|
||||
|
||||
config CHARGER_SMB347
|
||||
tristate "Summit Microelectronics SMB347 Battery Charger"
|
||||
depends on I2C
|
||||
@@ -329,13 +346,6 @@ config AB8500_BM
|
||||
help
|
||||
Say Y to include support for AB8500 battery management.
|
||||
|
||||
config AB8500_BATTERY_THERM_ON_BATCTRL
|
||||
bool "Thermistor connected on BATCTRL ADC"
|
||||
depends on AB8500_BM
|
||||
help
|
||||
Say Y to enable battery temperature measurements using
|
||||
thermistor connected on BATCTRL ADC.
|
||||
|
||||
source "drivers/power/reset/Kconfig"
|
||||
|
||||
endif # POWER_SUPPLY
|
||||
|
||||
@@ -37,7 +37,8 @@ obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o
|
||||
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
|
||||
obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
|
||||
obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
|
||||
obj-$(CONFIG_AB8500_BM) += ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o
|
||||
obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o
|
||||
obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o
|
||||
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
|
||||
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
|
||||
@@ -47,6 +48,7 @@ obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
|
||||
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
|
||||
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
|
||||
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
|
||||
obj-$(CONFIG_POWER_AVS) += avs/
|
||||
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
|
||||
obj-$(CONFIG_POWER_RESET) += reset/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,11 +20,13 @@
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mfd/abx500/ab8500.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/abx500.h>
|
||||
#include <linux/mfd/abx500/ab8500.h>
|
||||
#include <linux/mfd/abx500/ab8500-bm.h>
|
||||
#include <linux/mfd/abx500/ab8500-gpadc.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#define VTVOUT_V 1800
|
||||
|
||||
@@ -76,7 +78,6 @@ struct ab8500_btemp_ranges {
|
||||
* @parent: Pointer to the struct ab8500
|
||||
* @gpadc: Pointer to the struct gpadc
|
||||
* @fg: Pointer to the struct fg
|
||||
* @pdata: Pointer to the abx500_btemp platform data
|
||||
* @bat: Pointer to the abx500_bm platform data
|
||||
* @btemp_psy: Structure for BTEMP specific battery properties
|
||||
* @events: Structure for information about events triggered
|
||||
@@ -93,7 +94,6 @@ struct ab8500_btemp {
|
||||
struct ab8500 *parent;
|
||||
struct ab8500_gpadc *gpadc;
|
||||
struct ab8500_fg *fg;
|
||||
struct abx500_btemp_platform_data *pdata;
|
||||
struct abx500_bm_data *bat;
|
||||
struct power_supply btemp_psy;
|
||||
struct ab8500_btemp_events events;
|
||||
@@ -955,56 +955,57 @@ static int ab8500_btemp_remove(struct platform_device *pdev)
|
||||
flush_scheduled_work();
|
||||
power_supply_unregister(&di->btemp_psy);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(di);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *supply_interface[] = {
|
||||
"ab8500_chargalg",
|
||||
"ab8500_fg",
|
||||
};
|
||||
|
||||
static int ab8500_btemp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct ab8500_btemp *di;
|
||||
int irq, i, ret = 0;
|
||||
u8 val;
|
||||
struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
|
||||
struct ab8500_btemp *di;
|
||||
|
||||
if (!plat_data) {
|
||||
dev_err(&pdev->dev, "No platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
di = kzalloc(sizeof(*di), GFP_KERNEL);
|
||||
if (!di)
|
||||
di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
|
||||
if (!di) {
|
||||
dev_err(&pdev->dev, "%s no mem for ab8500_btemp\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
di->bat = pdev->mfd_cell->platform_data;
|
||||
if (!di->bat) {
|
||||
if (np) {
|
||||
ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to get battery information\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
dev_err(&pdev->dev, "missing dt node for ab8500_btemp\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
dev_info(&pdev->dev, "falling back to legacy platform data\n");
|
||||
}
|
||||
|
||||
/* get parent data */
|
||||
di->dev = &pdev->dev;
|
||||
di->parent = dev_get_drvdata(pdev->dev.parent);
|
||||
di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
|
||||
|
||||
/* get btemp specific platform data */
|
||||
di->pdata = plat_data->btemp;
|
||||
if (!di->pdata) {
|
||||
dev_err(di->dev, "no btemp platform data supplied\n");
|
||||
ret = -EINVAL;
|
||||
goto free_device_info;
|
||||
}
|
||||
|
||||
/* get battery specific platform data */
|
||||
di->bat = plat_data->battery;
|
||||
if (!di->bat) {
|
||||
dev_err(di->dev, "no battery platform data supplied\n");
|
||||
ret = -EINVAL;
|
||||
goto free_device_info;
|
||||
}
|
||||
|
||||
/* BTEMP supply */
|
||||
di->btemp_psy.name = "ab8500_btemp";
|
||||
di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
di->btemp_psy.properties = ab8500_btemp_props;
|
||||
di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props);
|
||||
di->btemp_psy.get_property = ab8500_btemp_get_property;
|
||||
di->btemp_psy.supplied_to = di->pdata->supplied_to;
|
||||
di->btemp_psy.num_supplicants = di->pdata->num_supplicants;
|
||||
di->btemp_psy.supplied_to = supply_interface;
|
||||
di->btemp_psy.num_supplicants = ARRAY_SIZE(supply_interface);
|
||||
di->btemp_psy.external_power_changed =
|
||||
ab8500_btemp_external_power_changed;
|
||||
|
||||
@@ -1014,8 +1015,7 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
|
||||
create_singlethread_workqueue("ab8500_btemp_wq");
|
||||
if (di->btemp_wq == NULL) {
|
||||
dev_err(di->dev, "failed to create work queue\n");
|
||||
ret = -ENOMEM;
|
||||
goto free_device_info;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Init work for measuring temperature periodically */
|
||||
@@ -1093,12 +1093,14 @@ free_irq:
|
||||
}
|
||||
free_btemp_wq:
|
||||
destroy_workqueue(di->btemp_wq);
|
||||
free_device_info:
|
||||
kfree(di);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id ab8500_btemp_match[] = {
|
||||
{ .compatible = "stericsson,ab8500-btemp", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_driver ab8500_btemp_driver = {
|
||||
.probe = ab8500_btemp_probe,
|
||||
.remove = ab8500_btemp_remove,
|
||||
@@ -1107,6 +1109,7 @@ static struct platform_driver ab8500_btemp_driver = {
|
||||
.driver = {
|
||||
.name = "ab8500-btemp",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ab8500_btemp_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/abx500/ab8500.h>
|
||||
#include <linux/mfd/abx500.h>
|
||||
#include <linux/mfd/abx500/ab8500-bm.h>
|
||||
@@ -181,9 +183,9 @@ struct ab8500_charger_usb_state {
|
||||
* @vbat Battery voltage
|
||||
* @old_vbat Previously measured battery voltage
|
||||
* @autopower Indicate if we should have automatic pwron after pwrloss
|
||||
* @autopower_cfg platform specific power config support for "pwron after pwrloss"
|
||||
* @parent: Pointer to the struct ab8500
|
||||
* @gpadc: Pointer to the struct gpadc
|
||||
* @pdata: Pointer to the abx500_charger platform data
|
||||
* @bat: Pointer to the abx500_bm platform data
|
||||
* @flags: Structure for information about events triggered
|
||||
* @usb_state: Structure for usb stack information
|
||||
@@ -218,9 +220,9 @@ struct ab8500_charger {
|
||||
int vbat;
|
||||
int old_vbat;
|
||||
bool autopower;
|
||||
bool autopower_cfg;
|
||||
struct ab8500 *parent;
|
||||
struct ab8500_gpadc *gpadc;
|
||||
struct abx500_charger_platform_data *pdata;
|
||||
struct abx500_bm_data *bat;
|
||||
struct ab8500_charger_event_flags flags;
|
||||
struct ab8500_charger_usb_state usb_state;
|
||||
@@ -322,7 +324,7 @@ static void ab8500_power_loss_handling(struct ab8500_charger *di)
|
||||
static void ab8500_power_supply_changed(struct ab8500_charger *di,
|
||||
struct power_supply *psy)
|
||||
{
|
||||
if (di->pdata->autopower_cfg) {
|
||||
if (di->autopower_cfg) {
|
||||
if (!di->usb.charger_connected &&
|
||||
!di->ac.charger_connected &&
|
||||
di->autopower) {
|
||||
@@ -2526,25 +2528,45 @@ static int ab8500_charger_remove(struct platform_device *pdev)
|
||||
power_supply_unregister(&di->usb_chg.psy);
|
||||
power_supply_unregister(&di->ac_chg.psy);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(di);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *supply_interface[] = {
|
||||
"ab8500_chargalg",
|
||||
"ab8500_fg",
|
||||
"ab8500_btemp",
|
||||
};
|
||||
|
||||
static int ab8500_charger_probe(struct platform_device *pdev)
|
||||
{
|
||||
int irq, i, charger_status, ret = 0;
|
||||
struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct ab8500_charger *di;
|
||||
int irq, i, charger_status, ret = 0;
|
||||
|
||||
if (!plat_data) {
|
||||
dev_err(&pdev->dev, "No platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
di = kzalloc(sizeof(*di), GFP_KERNEL);
|
||||
if (!di)
|
||||
di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
|
||||
if (!di) {
|
||||
dev_err(&pdev->dev, "%s no mem for ab8500_charger\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
di->bat = pdev->mfd_cell->platform_data;
|
||||
if (!di->bat) {
|
||||
if (np) {
|
||||
ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to get battery information\n");
|
||||
return ret;
|
||||
}
|
||||
di->autopower_cfg = of_property_read_bool(np, "autopower_cfg");
|
||||
} else {
|
||||
dev_err(&pdev->dev, "missing dt node for ab8500_charger\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
dev_info(&pdev->dev, "falling back to legacy platform data\n");
|
||||
di->autopower_cfg = false;
|
||||
}
|
||||
|
||||
/* get parent data */
|
||||
di->dev = &pdev->dev;
|
||||
@@ -2554,22 +2576,6 @@ static int ab8500_charger_probe(struct platform_device *pdev)
|
||||
/* initialize lock */
|
||||
spin_lock_init(&di->usb_state.usb_lock);
|
||||
|
||||
/* get charger specific platform data */
|
||||
di->pdata = plat_data->charger;
|
||||
if (!di->pdata) {
|
||||
dev_err(di->dev, "no charger platform data supplied\n");
|
||||
ret = -EINVAL;
|
||||
goto free_device_info;
|
||||
}
|
||||
|
||||
/* get battery specific platform data */
|
||||
di->bat = plat_data->battery;
|
||||
if (!di->bat) {
|
||||
dev_err(di->dev, "no battery platform data supplied\n");
|
||||
ret = -EINVAL;
|
||||
goto free_device_info;
|
||||
}
|
||||
|
||||
di->autopower = false;
|
||||
|
||||
/* AC supply */
|
||||
@@ -2579,8 +2585,8 @@ static int ab8500_charger_probe(struct platform_device *pdev)
|
||||
di->ac_chg.psy.properties = ab8500_charger_ac_props;
|
||||
di->ac_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_ac_props);
|
||||
di->ac_chg.psy.get_property = ab8500_charger_ac_get_property;
|
||||
di->ac_chg.psy.supplied_to = di->pdata->supplied_to;
|
||||
di->ac_chg.psy.num_supplicants = di->pdata->num_supplicants;
|
||||
di->ac_chg.psy.supplied_to = supply_interface;
|
||||
di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface),
|
||||
/* ux500_charger sub-class */
|
||||
di->ac_chg.ops.enable = &ab8500_charger_ac_en;
|
||||
di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
|
||||
@@ -2597,8 +2603,8 @@ static int ab8500_charger_probe(struct platform_device *pdev)
|
||||
di->usb_chg.psy.properties = ab8500_charger_usb_props;
|
||||
di->usb_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_usb_props);
|
||||
di->usb_chg.psy.get_property = ab8500_charger_usb_get_property;
|
||||
di->usb_chg.psy.supplied_to = di->pdata->supplied_to;
|
||||
di->usb_chg.psy.num_supplicants = di->pdata->num_supplicants;
|
||||
di->usb_chg.psy.supplied_to = supply_interface;
|
||||
di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface),
|
||||
/* ux500_charger sub-class */
|
||||
di->usb_chg.ops.enable = &ab8500_charger_usb_en;
|
||||
di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
|
||||
@@ -2614,8 +2620,7 @@ static int ab8500_charger_probe(struct platform_device *pdev)
|
||||
create_singlethread_workqueue("ab8500_charger_wq");
|
||||
if (di->charger_wq == NULL) {
|
||||
dev_err(di->dev, "failed to create work queue\n");
|
||||
ret = -ENOMEM;
|
||||
goto free_device_info;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Init work for HW failure check */
|
||||
@@ -2757,12 +2762,14 @@ free_regulator:
|
||||
regulator_put(di->regu);
|
||||
free_charger_wq:
|
||||
destroy_workqueue(di->charger_wq);
|
||||
free_device_info:
|
||||
kfree(di);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id ab8500_charger_match[] = {
|
||||
{ .compatible = "stericsson,ab8500-charger", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_driver ab8500_charger_driver = {
|
||||
.probe = ab8500_charger_probe,
|
||||
.remove = ab8500_charger_remove,
|
||||
@@ -2771,6 +2778,7 @@ static struct platform_driver ab8500_charger_driver = {
|
||||
.driver = {
|
||||
.name = "ab8500-charger",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ab8500_charger_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+42
-40
@@ -22,15 +22,16 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/mfd/abx500/ab8500.h>
|
||||
#include <linux/mfd/abx500.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mfd/abx500/ab8500-bm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mfd/abx500/ab8500-gpadc.h>
|
||||
#include <linux/mfd/abx500.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/abx500.h>
|
||||
#include <linux/mfd/abx500/ab8500.h>
|
||||
#include <linux/mfd/abx500/ab8500-bm.h>
|
||||
#include <linux/mfd/abx500/ab8500-gpadc.h>
|
||||
|
||||
#define MILLI_TO_MICRO 1000
|
||||
#define FG_LSB_IN_MA 1627
|
||||
@@ -172,7 +173,6 @@ struct inst_curr_result_list {
|
||||
* @avg_cap: Average capacity filter
|
||||
* @parent: Pointer to the struct ab8500
|
||||
* @gpadc: Pointer to the struct gpadc
|
||||
* @pdata: Pointer to the abx500_fg platform data
|
||||
* @bat: Pointer to the abx500_bm platform data
|
||||
* @fg_psy: Structure that holds the FG specific battery properties
|
||||
* @fg_wq: Work queue for running the FG algorithm
|
||||
@@ -212,7 +212,6 @@ struct ab8500_fg {
|
||||
struct ab8500_fg_avg_cap avg_cap;
|
||||
struct ab8500 *parent;
|
||||
struct ab8500_gpadc *gpadc;
|
||||
struct abx500_fg_platform_data *pdata;
|
||||
struct abx500_bm_data *bat;
|
||||
struct power_supply fg_psy;
|
||||
struct workqueue_struct *fg_wq;
|
||||
@@ -2429,7 +2428,6 @@ static int ab8500_fg_remove(struct platform_device *pdev)
|
||||
flush_scheduled_work();
|
||||
power_supply_unregister(&di->fg_psy);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(di);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2442,21 +2440,39 @@ static struct ab8500_fg_interrupts ab8500_fg_irq[] = {
|
||||
{"CCEOC", ab8500_fg_cc_data_end_handler},
|
||||
};
|
||||
|
||||
static char *supply_interface[] = {
|
||||
"ab8500_chargalg",
|
||||
"ab8500_usb",
|
||||
};
|
||||
|
||||
static int ab8500_fg_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct ab8500_fg *di;
|
||||
int i, irq;
|
||||
int ret = 0;
|
||||
struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
|
||||
struct ab8500_fg *di;
|
||||
|
||||
if (!plat_data) {
|
||||
dev_err(&pdev->dev, "No platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
di = kzalloc(sizeof(*di), GFP_KERNEL);
|
||||
if (!di)
|
||||
di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
|
||||
if (!di) {
|
||||
dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
di->bat = pdev->mfd_cell->platform_data;
|
||||
if (!di->bat) {
|
||||
if (np) {
|
||||
ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to get battery information\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
dev_err(&pdev->dev, "missing dt node for ab8500_fg\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
dev_info(&pdev->dev, "falling back to legacy platform data\n");
|
||||
}
|
||||
|
||||
mutex_init(&di->cc_lock);
|
||||
|
||||
@@ -2465,29 +2481,13 @@ static int ab8500_fg_probe(struct platform_device *pdev)
|
||||
di->parent = dev_get_drvdata(pdev->dev.parent);
|
||||
di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
|
||||
|
||||
/* get fg specific platform data */
|
||||
di->pdata = plat_data->fg;
|
||||
if (!di->pdata) {
|
||||
dev_err(di->dev, "no fg platform data supplied\n");
|
||||
ret = -EINVAL;
|
||||
goto free_device_info;
|
||||
}
|
||||
|
||||
/* get battery specific platform data */
|
||||
di->bat = plat_data->battery;
|
||||
if (!di->bat) {
|
||||
dev_err(di->dev, "no battery platform data supplied\n");
|
||||
ret = -EINVAL;
|
||||
goto free_device_info;
|
||||
}
|
||||
|
||||
di->fg_psy.name = "ab8500_fg";
|
||||
di->fg_psy.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
di->fg_psy.properties = ab8500_fg_props;
|
||||
di->fg_psy.num_properties = ARRAY_SIZE(ab8500_fg_props);
|
||||
di->fg_psy.get_property = ab8500_fg_get_property;
|
||||
di->fg_psy.supplied_to = di->pdata->supplied_to;
|
||||
di->fg_psy.num_supplicants = di->pdata->num_supplicants;
|
||||
di->fg_psy.supplied_to = supply_interface;
|
||||
di->fg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
|
||||
di->fg_psy.external_power_changed = ab8500_fg_external_power_changed;
|
||||
|
||||
di->bat_cap.max_mah_design = MILLI_TO_MICRO *
|
||||
@@ -2506,8 +2506,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
|
||||
di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq");
|
||||
if (di->fg_wq == NULL) {
|
||||
dev_err(di->dev, "failed to create work queue\n");
|
||||
ret = -ENOMEM;
|
||||
goto free_device_info;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Init work for running the fg algorithm instantly */
|
||||
@@ -2606,12 +2605,14 @@ free_irq:
|
||||
}
|
||||
free_inst_curr_wq:
|
||||
destroy_workqueue(di->fg_wq);
|
||||
free_device_info:
|
||||
kfree(di);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id ab8500_fg_match[] = {
|
||||
{ .compatible = "stericsson,ab8500-fg", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_driver ab8500_fg_driver = {
|
||||
.probe = ab8500_fg_probe,
|
||||
.remove = ab8500_fg_remove,
|
||||
@@ -2620,6 +2621,7 @@ static struct platform_driver ab8500_fg_driver = {
|
||||
.driver = {
|
||||
.name = "ab8500-fg",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ab8500_fg_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <linux/completion.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/abx500.h>
|
||||
#include <linux/mfd/abx500/ux500_chargalg.h>
|
||||
#include <linux/mfd/abx500/ab8500-bm.h>
|
||||
@@ -205,7 +207,6 @@ enum maxim_ret {
|
||||
* @chg_info: information about connected charger types
|
||||
* @batt_data: data of the battery
|
||||
* @susp_status: current charger suspension status
|
||||
* @pdata: pointer to the abx500_chargalg platform data
|
||||
* @bat: pointer to the abx500_bm platform data
|
||||
* @chargalg_psy: structure that holds the battery properties exposed by
|
||||
* the charging algorithm
|
||||
@@ -231,7 +232,6 @@ struct abx500_chargalg {
|
||||
struct abx500_chargalg_charger_info chg_info;
|
||||
struct abx500_chargalg_battery_data batt_data;
|
||||
struct abx500_chargalg_suspension_status susp_status;
|
||||
struct abx500_chargalg_platform_data *pdata;
|
||||
struct abx500_bm_data *bat;
|
||||
struct power_supply chargalg_psy;
|
||||
struct ux500_charger *ac_chg;
|
||||
@@ -1795,36 +1795,53 @@ static int abx500_chargalg_remove(struct platform_device *pdev)
|
||||
flush_scheduled_work();
|
||||
power_supply_unregister(&di->chargalg_psy);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(di);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *supply_interface[] = {
|
||||
"ab8500_fg",
|
||||
};
|
||||
|
||||
static int abx500_chargalg_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct abx500_bm_plat_data *plat_data;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct abx500_chargalg *di;
|
||||
int ret = 0;
|
||||
|
||||
struct abx500_chargalg *di =
|
||||
kzalloc(sizeof(struct abx500_chargalg), GFP_KERNEL);
|
||||
if (!di)
|
||||
di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
|
||||
if (!di) {
|
||||
dev_err(&pdev->dev, "%s no mem for ab8500_chargalg\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
di->bat = pdev->mfd_cell->platform_data;
|
||||
if (!di->bat) {
|
||||
if (np) {
|
||||
ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to get battery information\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
dev_err(&pdev->dev, "missing dt node for ab8500_chargalg\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
dev_info(&pdev->dev, "falling back to legacy platform data\n");
|
||||
}
|
||||
|
||||
/* get device struct */
|
||||
di->dev = &pdev->dev;
|
||||
|
||||
plat_data = pdev->dev.platform_data;
|
||||
di->pdata = plat_data->chargalg;
|
||||
di->bat = plat_data->battery;
|
||||
|
||||
/* chargalg supply */
|
||||
di->chargalg_psy.name = "abx500_chargalg";
|
||||
di->chargalg_psy.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
di->chargalg_psy.properties = abx500_chargalg_props;
|
||||
di->chargalg_psy.num_properties = ARRAY_SIZE(abx500_chargalg_props);
|
||||
di->chargalg_psy.get_property = abx500_chargalg_get_property;
|
||||
di->chargalg_psy.supplied_to = di->pdata->supplied_to;
|
||||
di->chargalg_psy.num_supplicants = di->pdata->num_supplicants;
|
||||
di->chargalg_psy.supplied_to = supply_interface;
|
||||
di->chargalg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
|
||||
di->chargalg_psy.external_power_changed =
|
||||
abx500_chargalg_external_power_changed;
|
||||
|
||||
@@ -1844,7 +1861,7 @@ static int abx500_chargalg_probe(struct platform_device *pdev)
|
||||
create_singlethread_workqueue("abx500_chargalg_wq");
|
||||
if (di->chargalg_wq == NULL) {
|
||||
dev_err(di->dev, "failed to create work queue\n");
|
||||
goto free_device_info;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Init work for chargalg */
|
||||
@@ -1885,20 +1902,23 @@ free_psy:
|
||||
power_supply_unregister(&di->chargalg_psy);
|
||||
free_chargalg_wq:
|
||||
destroy_workqueue(di->chargalg_wq);
|
||||
free_device_info:
|
||||
kfree(di);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id ab8500_chargalg_match[] = {
|
||||
{ .compatible = "stericsson,ab8500-chargalg", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_driver abx500_chargalg_driver = {
|
||||
.probe = abx500_chargalg_probe,
|
||||
.remove = abx500_chargalg_remove,
|
||||
.suspend = abx500_chargalg_suspend,
|
||||
.resume = abx500_chargalg_resume,
|
||||
.driver = {
|
||||
.name = "abx500-chargalg",
|
||||
.name = "ab8500-chargalg",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ab8500_chargalg_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -230,6 +230,14 @@ static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)
|
||||
*/
|
||||
static inline int bq27x00_battery_read_nac(struct bq27x00_device_info *di)
|
||||
{
|
||||
int flags;
|
||||
bool is_bq27500 = di->chip == BQ27500;
|
||||
bool is_higher = bq27xxx_is_chip_version_higher(di);
|
||||
|
||||
flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500);
|
||||
if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI))
|
||||
return -ENODATA;
|
||||
|
||||
return bq27x00_battery_read_charge(di, BQ27x00_REG_NAC);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,13 +80,13 @@ static inline int ds278x_read_reg16(struct ds278x_info *info, int reg_msb,
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = swab16(i2c_smbus_read_word_data(info->client, reg_msb));
|
||||
ret = i2c_smbus_read_word_data(info->client, reg_msb);
|
||||
if (ret < 0) {
|
||||
dev_err(&info->client->dev, "register read failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*val = ret;
|
||||
*val = swab16(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +279,8 @@ static int gab_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
memcpy(psy->properties, gab_props, sizeof(gab_props));
|
||||
properties = psy->properties + sizeof(gab_props);
|
||||
properties = (enum power_supply_property *)
|
||||
((char *)psy->properties + sizeof(gab_props));
|
||||
|
||||
/*
|
||||
* getting channel from iio and copying the battery properties
|
||||
@@ -327,7 +328,7 @@ static int gab_probe(struct platform_device *pdev)
|
||||
ret = request_any_context_irq(irq, gab_charged,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||
"battery charged", adc_bat);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto err_gpio;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ struct jz_battery {
|
||||
struct jz_battery_platform_data *pdata;
|
||||
struct platform_device *pdev;
|
||||
|
||||
struct resource *mem;
|
||||
void __iomem *base;
|
||||
|
||||
int irq;
|
||||
@@ -244,13 +243,14 @@ static int jz_battery_probe(struct platform_device *pdev)
|
||||
struct jz_battery_platform_data *pdata = pdev->dev.parent->platform_data;
|
||||
struct jz_battery *jz_battery;
|
||||
struct power_supply *battery;
|
||||
struct resource *mem;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "No platform_data supplied\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL);
|
||||
jz_battery = devm_kzalloc(&pdev->dev, sizeof(*jz_battery), GFP_KERNEL);
|
||||
if (!jz_battery) {
|
||||
dev_err(&pdev->dev, "Failed to allocate driver structure\n");
|
||||
return -ENOMEM;
|
||||
@@ -260,33 +260,15 @@ static int jz_battery_probe(struct platform_device *pdev)
|
||||
|
||||
jz_battery->irq = platform_get_irq(pdev, 0);
|
||||
if (jz_battery->irq < 0) {
|
||||
ret = jz_battery->irq;
|
||||
dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
|
||||
goto err_free;
|
||||
return jz_battery->irq;
|
||||
}
|
||||
|
||||
jz_battery->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!jz_battery->mem) {
|
||||
ret = -ENOENT;
|
||||
dev_err(&pdev->dev, "Failed to get platform mmio resource\n");
|
||||
goto err_free;
|
||||
}
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
jz_battery->mem = request_mem_region(jz_battery->mem->start,
|
||||
resource_size(jz_battery->mem), pdev->name);
|
||||
if (!jz_battery->mem) {
|
||||
ret = -EBUSY;
|
||||
dev_err(&pdev->dev, "Failed to request mmio memory region\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
jz_battery->base = ioremap_nocache(jz_battery->mem->start,
|
||||
resource_size(jz_battery->mem));
|
||||
if (!jz_battery->base) {
|
||||
ret = -EBUSY;
|
||||
dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
|
||||
goto err_release_mem_region;
|
||||
}
|
||||
jz_battery->base = devm_request_and_ioremap(&pdev->dev, mem);
|
||||
if (!jz_battery->base)
|
||||
return -EBUSY;
|
||||
|
||||
battery = &jz_battery->battery;
|
||||
battery->name = pdata->info.name;
|
||||
@@ -309,7 +291,7 @@ static int jz_battery_probe(struct platform_device *pdev)
|
||||
jz_battery);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to request irq %d\n", ret);
|
||||
goto err_iounmap;
|
||||
goto err;
|
||||
}
|
||||
disable_irq(jz_battery->irq);
|
||||
|
||||
@@ -366,13 +348,8 @@ err_free_gpio:
|
||||
gpio_free(jz_battery->pdata->gpio_charge);
|
||||
err_free_irq:
|
||||
free_irq(jz_battery->irq, jz_battery);
|
||||
err_iounmap:
|
||||
err:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
iounmap(jz_battery->base);
|
||||
err_release_mem_region:
|
||||
release_mem_region(jz_battery->mem->start, resource_size(jz_battery->mem));
|
||||
err_free:
|
||||
kfree(jz_battery);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -392,10 +369,6 @@ static int jz_battery_remove(struct platform_device *pdev)
|
||||
|
||||
free_irq(jz_battery->irq, jz_battery);
|
||||
|
||||
iounmap(jz_battery->base);
|
||||
release_mem_region(jz_battery->mem->start, resource_size(jz_battery->mem));
|
||||
kfree(jz_battery);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user