Commit 021723e6 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull power supply and reset updates from Sebastian Reichel:
 - move power supply drivers to drivers/power/supply
 - unify location of power supply DT documentation
 - tps65217-charger: IRQ support
 - act8945a-charger: misc. cleanups & improvements
 - sbs-battery cleanup
 - fix users of deprecated create_singlethread_workqueue()
 - misc fixes.

* tag 'for-v4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (46 commits)
  power: supply: bq27xxx_battery: allow kernel poll_interval parameter runtime update
  power: supply: sbs-battery: Cleanup removal of chip->pdata
  power: reset: st: Remove obsolete platforms from dt doc
  power: reset: st-poweroff: Remove obsolete platforms.
  power: reset: zx-reboot: Unmap region obtained by of_iomap
  power: reset: xgene-reboot: Unmap region obtained by of_iomap
  power: supply: ab8500: cleanup with list_first_entry_or_null()
  power: reset: add in missing white space in error message text
  sbs-battery: make writes to ManufacturerAccess optional
  power: bq24257: Fix use of uninitialized pointer bq->charger
  power: supply: sbs-battery: simplify DT parsing
  power: supply: bq24735-charger: Request status GPIO with initial input setup
  power: supply: sbs-battery: Use gpio_desc and sleeping calls for battery detect
  power: supply: act8945a_charger: Add max current property
  power: supply: act8945a_charger: Add capacity level property
  doc: bindings: power: act8945a-charger: Update properties.
  power: supply: act8945a_charger: Fix the power supply type
  power: supply: act8945a_charger: Add status change update support
  power: supply: act8945a_charger: Improve state handling
  power: supply: act8945a_charger: Remove "battery_temperature"
  ...
parents c6594fc6 1d72706f
...@@ -1090,6 +1090,10 @@ S: 6350 Stoneridge Mall Road ...@@ -1090,6 +1090,10 @@ S: 6350 Stoneridge Mall Road
S: Pleasanton, CA 94588 S: Pleasanton, CA 94588
S: USA S: USA
N: Dmitry Eremin-Solenikov
E: dbaryshkov@gmail.com
D: Power Supply Maintainer from v3.14 - v3.15
N: Doug Evans N: Doug Evans
E: dje@cygnus.com E: dje@cygnus.com
D: Wrote Xenix FS (part of standard kernel since 0.99.15) D: Wrote Xenix FS (part of standard kernel since 0.99.15)
......
...@@ -22,7 +22,7 @@ Description: ...@@ -22,7 +22,7 @@ Description:
What: /sys/class/power_supply/max14577-charger/device/fast_charge_timer What: /sys/class/power_supply/max14577-charger/device/fast_charge_timer
Date: October 2014 Date: October 2014
KernelVersion: 3.18.0 KernelVersion: 3.18.0
Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com> Contact: Krzysztof Kozlowski <krzk@kernel.org>
Description: Description:
This entry shows and sets the maximum time the max14577 This entry shows and sets the maximum time the max14577
charger operates in fast-charge mode. When the timer expires charger operates in fast-charge mode. When the timer expires
...@@ -36,7 +36,7 @@ Description: ...@@ -36,7 +36,7 @@ Description:
What: /sys/class/power_supply/max77693-charger/device/fast_charge_timer What: /sys/class/power_supply/max77693-charger/device/fast_charge_timer
Date: January 2015 Date: January 2015
KernelVersion: 3.19.0 KernelVersion: 3.19.0
Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com> Contact: Krzysztof Kozlowski <krzk@kernel.org>
Description: Description:
This entry shows and sets the maximum time the max77693 This entry shows and sets the maximum time the max77693
charger operates in fast-charge mode. When the timer expires charger operates in fast-charge mode. When the timer expires
...@@ -50,7 +50,7 @@ Description: ...@@ -50,7 +50,7 @@ Description:
What: /sys/class/power_supply/max77693-charger/device/top_off_threshold_current What: /sys/class/power_supply/max77693-charger/device/top_off_threshold_current
Date: January 2015 Date: January 2015
KernelVersion: 3.19.0 KernelVersion: 3.19.0
Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com> Contact: Krzysztof Kozlowski <krzk@kernel.org>
Description: Description:
This entry shows and sets the charging current threshold for This entry shows and sets the charging current threshold for
entering top-off charging mode. When charging current in fast entering top-off charging mode. When charging current in fast
...@@ -65,7 +65,7 @@ Description: ...@@ -65,7 +65,7 @@ Description:
What: /sys/class/power_supply/max77693-charger/device/top_off_timer What: /sys/class/power_supply/max77693-charger/device/top_off_timer
Date: January 2015 Date: January 2015
KernelVersion: 3.19.0 KernelVersion: 3.19.0
Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com> Contact: Krzysztof Kozlowski <krzk@kernel.org>
Description: Description:
This entry shows and sets the maximum time the max77693 This entry shows and sets the maximum time the max77693
charger operates in top-off charge mode. When the timer expires charger operates in top-off charge mode. When the timer expires
......
*Device-Tree bindings for ST SW reset functionality *Device-Tree bindings for ST SW reset functionality
Required properties: Required properties:
- compatible: should be "st,<chip>-restart". - compatible: should be "stih407-restart".
- st,syscfg: should be a phandle of the syscfg node. - st,syscfg: should be a phandle of the syscfg node.
Example node: Example node:
restart { restart {
compatible = "st,stih416-restart"; compatible = "st,stih407-restart";
st,syscfg = <&syscfg_sbc>; st,syscfg = <&syscfg_sbc_reg>;
status = "okay";
}; };
Device-Tree bindings for charger of Active-semi ACT8945A Multi-Function Device Device-Tree bindings for charger of Active-semi ACT8945A Multi-Function Device
Required properties: Required properties:
- compatible: "active-semi,act8945a", please refer to ../mfd/act8945a.txt. - compatible: "active-semi,act8945a-charger".
- active-semi,chglev-gpios: charge current level phandle with args - active-semi,chglev-gpios: charge current level phandle with args
as described in ../gpio/gpio.txt. as described in ../gpio/gpio.txt.
- active-semi,lbo-gpios: specify the low battery voltage detect phandle
with args as as described in ../gpio/gpio.txt.
- interrupts: <a b> where a is the interrupt number and b is a
field that represents an encoding of the sense and level
information for the interrupt.
- interrupt-parent: the phandle for the interrupt controller that
services interrupts for this device.
Optional properties: Optional properties:
- active-semi,check-battery-temperature: boolean to check the battery
temperature or not.
- active-semi,input-voltage-threshold-microvolt: unit: mV; - active-semi,input-voltage-threshold-microvolt: unit: mV;
Specifies the charger's input over-voltage threshold value; Specifies the charger's input over-voltage threshold value;
The value can be: 6600, 7000, 7500, 8000; default: 6600 The value can be: 6600, 7000, 7500, 8000; default: 6600
...@@ -26,10 +31,18 @@ Example: ...@@ -26,10 +31,18 @@ Example:
reg = <0x5b>; reg = <0x5b>;
status = "okay"; status = "okay";
charger {
compatible = "active-semi,act8945a-charger";
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_charger_chglev>; pinctrl-0 = <&pinctrl_charger_chglev &pinctrl_charger_lbo &pinctrl_charger_irq>;
interrupt-parent = <&pioA>;
interrupts = <45 GPIO_ACTIVE_LOW>;
active-semi,chglev-gpios = <&pioA 12 GPIO_ACTIVE_HIGH>; active-semi,chglev-gpios = <&pioA 12 GPIO_ACTIVE_HIGH>;
active-semi,lbo-gpios = <&pioA 72 GPIO_ACTIVE_LOW>;
active-semi,input-voltage-threshold-microvolt = <6600>; active-semi,input-voltage-threshold-microvolt = <6600>;
active-semi,precondition-timeout = <40>; active-semi,precondition-timeout = <40>;
active-semi,total-timeout = <3>; active-semi,total-timeout = <3>;
status = "okay";
};
}; };
...@@ -346,6 +346,10 @@ PINCTRL ...@@ -346,6 +346,10 @@ PINCTRL
devm_pinctrl_register() devm_pinctrl_register()
devm_pinctrl_unregister() devm_pinctrl_unregister()
POWER
devm_reboot_mode_register()
devm_reboot_mode_unregister()
PWM PWM
devm_pwm_get() devm_pwm_get()
devm_pwm_put() devm_pwm_put()
......
...@@ -39,8 +39,8 @@ kind of power supply, and can process/present them to a user in consistent ...@@ -39,8 +39,8 @@ kind of power supply, and can process/present them to a user in consistent
manner. Results for different power supplies and machines are also directly manner. Results for different power supplies and machines are also directly
comparable. comparable.
See drivers/power/ds2760_battery.c and drivers/power/pda_power.c for the See drivers/power/supply/ds2760_battery.c and drivers/power/supply/pda_power.c
example how to declare and handle attributes. for the example how to declare and handle attributes.
Units Units
......
...@@ -3784,8 +3784,8 @@ F: drivers/leds/leds-da90??.c ...@@ -3784,8 +3784,8 @@ F: drivers/leds/leds-da90??.c
F: drivers/mfd/da903x.c F: drivers/mfd/da903x.c
F: drivers/mfd/da90??-*.c F: drivers/mfd/da90??-*.c
F: drivers/mfd/da91??-*.c F: drivers/mfd/da91??-*.c
F: drivers/power/da9052-battery.c F: drivers/power/supply/da9052-battery.c
F: drivers/power/da91??-*.c F: drivers/power/supply/da91??-*.c
F: drivers/regulator/da903x.c F: drivers/regulator/da903x.c
F: drivers/regulator/da9???-regulator.[ch] F: drivers/regulator/da9???-regulator.[ch]
F: drivers/rtc/rtc-da90??.c F: drivers/rtc/rtc-da90??.c
...@@ -7579,8 +7579,8 @@ M: Krzysztof Kozlowski <krzk@kernel.org> ...@@ -7579,8 +7579,8 @@ M: Krzysztof Kozlowski <krzk@kernel.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-pm@vger.kernel.org L: linux-pm@vger.kernel.org
S: Supported S: Supported
F: drivers/power/max14577_charger.c F: drivers/power/supply/max14577_charger.c
F: drivers/power/max77693_charger.c F: drivers/power/supply/max77693_charger.c
MAXIM MAX77802 MULTIFUNCTION PMIC DEVICE DRIVERS MAXIM MAX77802 MULTIFUNCTION PMIC DEVICE DRIVERS
M: Javier Martinez Canillas <javier@osg.samsung.com> M: Javier Martinez Canillas <javier@osg.samsung.com>
...@@ -8486,11 +8486,11 @@ R: Pali Rohár <pali.rohar@gmail.com> ...@@ -8486,11 +8486,11 @@ R: Pali Rohár <pali.rohar@gmail.com>
F: include/linux/power/bq2415x_charger.h F: include/linux/power/bq2415x_charger.h
F: include/linux/power/bq27xxx_battery.h F: include/linux/power/bq27xxx_battery.h
F: include/linux/power/isp1704_charger.h F: include/linux/power/isp1704_charger.h
F: drivers/power/bq2415x_charger.c F: drivers/power/supply/bq2415x_charger.c
F: drivers/power/bq27xxx_battery.c F: drivers/power/supply/bq27xxx_battery.c
F: drivers/power/bq27xxx_battery_i2c.c F: drivers/power/supply/bq27xxx_battery_i2c.c
F: drivers/power/isp1704_charger.c F: drivers/power/supply/isp1704_charger.c
F: drivers/power/rx51_battery.c F: drivers/power/supply/rx51_battery.c
NTB DRIVER CORE NTB DRIVER CORE
M: Jon Mason <jdmason@kudzu.us> M: Jon Mason <jdmason@kudzu.us>
...@@ -9490,16 +9490,12 @@ F: drivers/powercap/ ...@@ -9490,16 +9490,12 @@ F: drivers/powercap/
POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
M: Sebastian Reichel <sre@kernel.org> M: Sebastian Reichel <sre@kernel.org>
M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
M: David Woodhouse <dwmw2@infradead.org>
L: linux-pm@vger.kernel.org L: linux-pm@vger.kernel.org
T: git git://git.infradead.org/battery-2.6.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/power/ F: Documentation/devicetree/bindings/power/supply/
F: Documentation/devicetree/bindings/power_supply/
F: include/linux/power_supply.h F: include/linux/power_supply.h
F: drivers/power/ F: drivers/power/supply/
X: drivers/power/avs/
POWER STATE COORDINATION INTERFACE (PSCI) POWER STATE COORDINATION INTERFACE (PSCI)
M: Mark Rutland <mark.rutland@arm.com> M: Mark Rutland <mark.rutland@arm.com>
...@@ -10514,8 +10510,8 @@ F: drivers/thunderbolt/ ...@@ -10514,8 +10510,8 @@ F: drivers/thunderbolt/
TI BQ27XXX POWER SUPPLY DRIVER TI BQ27XXX POWER SUPPLY DRIVER
R: Andrew F. Davis <afd@ti.com> R: Andrew F. Davis <afd@ti.com>
F: include/linux/power/bq27xxx_battery.h F: include/linux/power/bq27xxx_battery.h
F: drivers/power/bq27xxx_battery.c F: drivers/power/supply/bq27xxx_battery.c
F: drivers/power/bq27xxx_battery_i2c.c F: drivers/power/supply/bq27xxx_battery_i2c.c
TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
M: John Stultz <john.stultz@linaro.org> M: John Stultz <john.stultz@linaro.org>
...@@ -11512,6 +11508,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git ...@@ -11512,6 +11508,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
S: Supported S: Supported
F: drivers/mfd/syscon.c F: drivers/mfd/syscon.c
SYSTEM RESET/SHUTDOWN DRIVERS
M: Sebastian Reichel <sre@kernel.org>
L: linux-pm@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git
S: Maintained
F: Documentation/devicetree/bindings/power/reset/
F: drivers/power/reset/
SYSV FILESYSTEM SYSV FILESYSTEM
M: Christoph Hellwig <hch@infradead.org> M: Christoph Hellwig <hch@infradead.org>
S: Maintained S: Maintained
...@@ -11860,7 +11864,7 @@ F: include/linux/platform_data/lp855x.h ...@@ -11860,7 +11864,7 @@ F: include/linux/platform_data/lp855x.h
TI LP8727 CHARGER DRIVER TI LP8727 CHARGER DRIVER
M: Milo Kim <milo.kim@ti.com> M: Milo Kim <milo.kim@ti.com>
S: Maintained S: Maintained
F: drivers/power/lp8727_charger.c F: drivers/power/supply/lp8727_charger.c
F: include/linux/platform_data/lp8727.h F: include/linux/platform_data/lp8727.h
TI LP8788 MFD DRIVER TI LP8788 MFD DRIVER
...@@ -11869,7 +11873,7 @@ S: Maintained ...@@ -11869,7 +11873,7 @@ S: Maintained
F: drivers/iio/adc/lp8788_adc.c F: drivers/iio/adc/lp8788_adc.c
F: drivers/leds/leds-lp8788.c F: drivers/leds/leds-lp8788.c
F: drivers/mfd/lp8788*.c F: drivers/mfd/lp8788*.c
F: drivers/power/lp8788-charger.c F: drivers/power/supply/lp8788-charger.c
F: drivers/regulator/lp8788-*.c F: drivers/regulator/lp8788-*.c
F: include/linux/mfd/lp8788*.h F: include/linux/mfd/lp8788*.h
...@@ -12946,7 +12950,7 @@ F: drivers/input/touchscreen/wm97*.c ...@@ -12946,7 +12950,7 @@ F: drivers/input/touchscreen/wm97*.c
F: drivers/mfd/arizona* F: drivers/mfd/arizona*
F: drivers/mfd/wm*.c F: drivers/mfd/wm*.c
F: drivers/mfd/cs47l24* F: drivers/mfd/cs47l24*
F: drivers/power/wm83*.c F: drivers/power/supply/wm83*.c
F: drivers/rtc/rtc-wm83*.c F: drivers/rtc/rtc-wm83*.c
F: drivers/regulator/wm8*.c F: drivers/regulator/wm8*.c
F: drivers/video/backlight/wm83*_bl.c F: drivers/video/backlight/wm83*_bl.c
......
menuconfig POWER_SUPPLY
bool "Power supply class support"
help
Say Y here to enable power supply class support. This allows
power supply (batteries, AC, USB) monitoring by userspace
via sysfs and uevent (if available) and/or APM kernel interface
(if selected below).
if POWER_SUPPLY
config POWER_SUPPLY_DEBUG
bool "Power supply debug"
help
Say Y here to enable debugging messages for power supply class
and drivers.
config PDA_POWER
tristate "Generic PDA/phone power driver"
depends on !S390
help
Say Y here to enable generic power driver for PDAs and phones with
one or two external power supplies (AC/USB) connected to main and
backup batteries, and optional builtin charger.
config APM_POWER
tristate "APM emulation for class batteries"
depends on APM_EMULATION
help
Say Y here to enable support APM status emulation using
battery class devices.
config GENERIC_ADC_BATTERY
tristate "Generic battery support using IIO"
depends on IIO
help
Say Y here to enable support for the generic battery driver
which uses IIO framework to read adc.
config MAX8925_POWER
tristate "MAX8925 battery charger support"
depends on MFD_MAX8925
help
Say Y here to enable support for the battery charger in the Maxim
MAX8925 PMIC.
config WM831X_BACKUP
tristate "WM831X backup battery charger support"
depends on MFD_WM831X
help
Say Y here to enable support for the backup battery charger
in the Wolfson Microelectronics WM831x PMICs.
config WM831X_POWER
tristate "WM831X PMU support"
depends on MFD_WM831X
help
Say Y here to enable support for the power management unit
provided by Wolfson Microelectronics WM831x PMICs.
config WM8350_POWER
tristate "WM8350 PMU support"
depends on MFD_WM8350
help
Say Y here to enable support for the power management unit
provided by the Wolfson Microelectronics WM8350 PMIC.
config TEST_POWER
tristate "Test power driver"
help
This driver is used for testing. It's safe to say M here.
config BATTERY_88PM860X
tristate "Marvell 88PM860x battery driver"
depends on MFD_88PM860X
help
Say Y here to enable battery monitor for Marvell 88PM860x chip.
config BATTERY_ACT8945A
tristate "Active-semi ACT8945A charger driver"
depends on MFD_ACT8945A || COMPILE_TEST
help
Say Y here to enable support for power supply provided by
Active-semi ActivePath ACT8945A charger.
config BATTERY_DS2760
tristate "DS2760 battery driver (HP iPAQ & others)"
depends on W1 && W1_SLAVE_DS2760
help
Say Y here to enable support for batteries with ds2760 chip.
config BATTERY_DS2780
tristate "DS2780 battery driver"
depends on HAS_IOMEM
select W1
select W1_SLAVE_DS2780
help
Say Y here to enable support for batteries with ds2780 chip.
config BATTERY_DS2781
tristate "DS2781 battery driver"
depends on HAS_IOMEM
select W1
select W1_SLAVE_DS2781
help
If you enable this you will have the DS2781 battery driver support.
The battery monitor chip is used in many batteries/devices
as the one who is responsible for charging/discharging/monitoring
Li+ batteries.
If you are unsure, say N.
config BATTERY_DS2782
tristate "DS2782/DS2786 standalone gas-gauge"
depends on I2C
help
Say Y here to enable support for the DS2782/DS2786 standalone battery
gas-gauge.
config BATTERY_PMU
tristate "Apple PMU battery"
depends on PPC32 && ADB_PMU
help
Say Y here to expose battery information on Apple machines
through the generic battery class.
config BATTERY_OLPC
tristate "One Laptop Per Child battery"
depends on X86_32 && OLPC
help
Say Y to enable support for the battery on the OLPC laptop.
config BATTERY_TOSA
tristate "Sharp SL-6000 (tosa) battery"
depends on MACH_TOSA && MFD_TC6393XB && TOUCHSCREEN_WM97XX
help
Say Y to enable support for the battery on the Sharp Zaurus
SL-6000 (tosa) models.
config BATTERY_COLLIE
tristate "Sharp SL-5500 (collie) battery"
depends on SA1100_COLLIE && MCP_UCB1200
help
Say Y to enable support for the battery on the Sharp Zaurus
SL-5500 (collie) models.
config BATTERY_IPAQ_MICRO
tristate "iPAQ Atmel Micro ASIC battery driver"
depends on MFD_IPAQ_MICRO
help
Choose this option if you want to monitor battery status on
Compaq/HP iPAQ h3100 and h3600.
config BATTERY_WM97XX
bool "WM97xx generic battery driver"
depends on TOUCHSCREEN_WM97XX=y
help
Say Y to enable support for battery measured by WM97xx aux port.
config BATTERY_SBS
tristate "SBS Compliant gas gauge"
depends on I2C
help
Say Y to include support for SBS battery driver for SBS-compliant
gas gauges.
config BATTERY_BQ27XXX
tristate "BQ27xxx battery driver"
help
Say Y here to enable support for batteries with BQ27xxx chips.
config BATTERY_BQ27XXX_I2C
tristate "BQ27xxx I2C support"
depends on BATTERY_BQ27XXX
depends on I2C
default y
help
Say Y here to enable support for batteries with BQ27xxx chips
connected over an I2C bus.
config BATTERY_DA9030
tristate "DA9030 battery driver"
depends on PMIC_DA903X
help
Say Y here to enable support for batteries charger integrated into
DA9030 PMIC.
config BATTERY_DA9052
tristate "Dialog DA9052 Battery"
depends on PMIC_DA9052
help
Say Y here to enable support for batteries charger integrated into
DA9052 PMIC.
config CHARGER_DA9150
tristate "Dialog Semiconductor DA9150 Charger support"
depends on MFD_DA9150
depends on DA9150_GPADC
depends on IIO
help
Say Y here to enable support for charger unit of the DA9150
Integrated Charger & Fuel-Gauge IC.
This driver can also be built as a module. If so, the module will be
called da9150-charger.
config BATTERY_DA9150
tristate "Dialog Semiconductor DA9150 Fuel Gauge support"
depends on MFD_DA9150
help
Say Y here to enable support for the Fuel-Gauge unit of the DA9150
Integrated Charger & Fuel-Gauge IC
This driver can also be built as a module. If so, the module will be
called da9150-fg.
config AXP288_CHARGER
tristate "X-Powers AXP288 Charger"
depends on MFD_AXP20X && EXTCON_AXP288
help
Say yes here to have support X-Power AXP288 power management IC (PMIC)
integrated charger.
config AXP288_FUEL_GAUGE
tristate "X-Powers AXP288 Fuel Gauge"
depends on MFD_AXP20X && IIO
help
Say yes here to have support for X-Power power management IC (PMIC)
Fuel Gauge. The device provides battery statistics and status
monitoring as well as alerts for battery over/under voltage and
over/under temperature.
config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
help
MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
in handheld and portable equipment. The MAX17040 is configured
to operate with a single lithium cell
config BATTERY_MAX17042
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
depends on I2C
select REGMAP_I2C
help
MAX17042 is fuel-gauge systems for lithium-ion (Li+) batteries
in handheld and portable equipment. The MAX17042 is configured
to operate with a single lithium cell. MAX8997 and MAX8966 are
multi-function devices that include fuel gauages that are compatible
with MAX17042. This driver also supports max17047/50 chips which are
improved version of max17042.
config BATTERY_Z2
tristate "Z2 battery driver"
depends on I2C && MACH_ZIPIT2
help
Say Y to include support for the battery on the Zipit Z2.
config BATTERY_S3C_ADC
tristate "Battery driver for Samsung ADC based monitoring"
depends on S3C_ADC
help
Say Y here to enable support for iPAQ h1930/h1940/rx1950 battery
config BATTERY_TWL4030_MADC
tristate "TWL4030 MADC battery driver"
depends on TWL4030_MADC
help
Say Y here to enable this dumb driver for batteries managed
through the TWL4030 MADC.
config CHARGER_88PM860X
tristate "Marvell 88PM860x Charger driver"
depends on MFD_88PM860X && BATTERY_88PM860X
help
Say Y here to enable charger for Marvell 88PM860x chip.
config CHARGER_PCF50633
tristate "NXP PCF50633 MBC"
depends on MFD_PCF50633
help
Say Y to include support for NXP PCF50633 Main Battery Charger.
config BATTERY_JZ4740
tristate "Ingenic JZ4740 battery"
depends on MACH_JZ4740
depends on MFD_JZ4740_ADC
help
Say Y to enable support for the battery on Ingenic JZ4740 based
boards.
This driver can be build as a module. If so, the module will be
called jz4740-battery.
config BATTERY_INTEL_MID
tristate "Battery driver for Intel MID platforms"
depends on INTEL_SCU_IPC && SPI
help
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_PHY
depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y'
help
Say Y to enable support for USB Charger Detection with
ISP1707/ISP1704 USB transceivers.
config CHARGER_MAX8903
tristate "MAX8903 Battery DC-DC Charger for USB and Adapter Power"
help
Say Y to enable support for the MAX8903 DC-DC charger and sysfs.
The driver supports controlling charger-enable and current-limit
pins based on the status of charger connections with interrupt
handlers.
config CHARGER_TWL4030
tristate "OMAP TWL4030 BCI charger driver"
depends on IIO && TWL4030_CORE
help
Say Y here to enable support for TWL4030 Battery Charge Interface.
config CHARGER_LP8727
tristate "TI/National Semiconductor LP8727 charger driver"
depends on I2C
help
Say Y here to enable support for LP8727 Charger Driver.
config CHARGER_LP8788
tristate "TI LP8788 charger driver"
depends on MFD_LP8788
depends on LP8788_ADC
depends on IIO
help
Say Y to enable support for the LP8788 linear charger.
config CHARGER_GPIO
tristate "GPIO charger"
depends on GPIOLIB || COMPILE_TEST
help
Say Y to include support for chargers which report their online status
through a GPIO pin.
This driver can be build as a module. If so, the module will be
called gpio-charger.
config CHARGER_MANAGER
bool "Battery charger manager for multiple chargers"
depends on REGULATOR
select EXTCON
help
Say Y to enable charger-manager support, which allows multiple
chargers attached to a battery and multiple batteries attached to a
system. The charger-manager also can monitor charging status in
runtime and in suspend-to-RAM by waking up the system periodically
with help of suspend_again support.
config CHARGER_MAX14577
tristate "Maxim MAX14577/77836 battery charger driver"
depends on MFD_MAX14577
help
Say Y to enable support for the battery charger control sysfs and
platform data of MAX14577/77836 MUICs.
config CHARGER_MAX77693
tristate "Maxim MAX77693 battery charger driver"
depends on MFD_MAX77693
help
Say Y to enable support for the Maxim MAX77693 battery charger.
config CHARGER_MAX8997
tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
depends on MFD_MAX8997 && REGULATOR_MAX8997
help
Say Y to enable support for the battery charger control sysfs and
platform data of MAX8997/LP3974 PMICs.
config CHARGER_MAX8998
tristate "Maxim MAX8998/LP3974 PMIC battery charger driver"
depends on MFD_MAX8998 && REGULATOR_MAX8998
help
Say Y to enable support for the battery charger control sysfs and
platform data of MAX8998/LP3974 PMICs.
config CHARGER_QCOM_SMBB
tristate "Qualcomm Switch-Mode Battery Charger and Boost"
depends on MFD_SPMI_PMIC || COMPILE_TEST
depends on OF
depends on EXTCON
help
Say Y to include support for the Switch-Mode Battery Charger and
Boost (SMBB) hardware found in Qualcomm PM8941 PMICs. The charger
is an integrated, single-cell lithium-ion battery charger. DT
configuration is required for loading, see the devicetree
documentation for more detail. The base name for this driver is
'pm8941_charger'.
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_BQ24190
tristate "TI BQ24190 battery charger driver"
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 BQ24250/24251/24257 battery charger driver"
depends on I2C
depends on GPIOLIB || COMPILE_TEST
depends on REGMAP_I2C
help
Say Y to enable support for the TI BQ24250, BQ24251, and BQ24257 battery
chargers.
config CHARGER_BQ24735
tristate "TI BQ24735 battery charger support"
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
depends on GPIOLIB || COMPILE_TEST
select REGMAP_I2C
help
Say Y to enable support for the TI BQ25890 battery charger.
config CHARGER_SMB347
tristate "Summit Microelectronics SMB347 Battery Charger"
depends on I2C
select REGMAP_I2C
help
Say Y to include support for Summit Microelectronics SMB347
Battery Charger.
config CHARGER_TPS65090
tristate "TPS65090 battery charger driver"
depends on MFD_TPS65090
help
Say Y here to enable support for battery charging with TPS65090
PMIC chips.
config CHARGER_TPS65217
tristate "TPS65217 battery charger driver"
depends on MFD_TPS65217
help
Say Y here to enable support for battery charging with TPS65217
PMIC chips.
config BATTERY_GAUGE_LTC2941
tristate "LTC2941/LTC2943 Battery Gauge Driver"
depends on I2C
help
Say Y here to include support for LTC2941 and LTC2943 Battery
Gauge IC. The driver reports the charge count continuously, and
measures the voltage and temperature every 10 seconds.
config AB8500_BM
bool "AB8500 Battery Management Driver"
depends on AB8500_CORE && AB8500_GPADC
help
Say Y to include support for AB8500 battery management.
config BATTERY_GOLDFISH
tristate "Goldfish battery driver"
depends on GOLDFISH || COMPILE_TEST
depends on HAS_IOMEM
help
Say Y to enable support for the battery and AC power in the
Goldfish emulator.
config BATTERY_RT5033
tristate "RT5033 fuel gauge support"
depends on MFD_RT5033
help
This adds support for battery fuel gauge in Richtek RT5033 PMIC.
The fuelgauge calculates and determines the battery state of charge
according to battery open circuit voltage.
config CHARGER_RT9455
tristate "Richtek RT9455 battery charger driver"
depends on I2C
depends on GPIOLIB || COMPILE_TEST
select REGMAP_I2C
help
Say Y to enable support for Richtek RT9455 battery charger.
config AXP20X_POWER
tristate "AXP20x power supply driver"
depends on MFD_AXP20X
help
This driver provides support for the power supply features of
AXP20x PMIC.
endif # POWER_SUPPLY
source "drivers/power/reset/Kconfig"
source "drivers/power/avs/Kconfig" source "drivers/power/avs/Kconfig"
source "drivers/power/reset/Kconfig"
source "drivers/power/supply/Kconfig"
subdir-ccflags-$(CONFIG_POWER_SUPPLY_DEBUG) := -DDEBUG
power_supply-y := power_supply_core.o
power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o
power_supply-$(CONFIG_LEDS_TRIGGERS) += power_supply_leds.o
obj-$(CONFIG_POWER_SUPPLY) += power_supply.o
obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o
obj-$(CONFIG_PDA_POWER) += pda_power.o
obj-$(CONFIG_APM_POWER) += apm_power.o
obj-$(CONFIG_AXP20X_POWER) += axp20x_usb_power.o
obj-$(CONFIG_MAX8925_POWER) += max8925_power.o
obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o
obj-$(CONFIG_WM831X_POWER) += wm831x_power.o
obj-$(CONFIG_WM8350_POWER) += wm8350_power.o
obj-$(CONFIG_TEST_POWER) += test_power.o
obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o
obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o
obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o
obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o
obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o
obj-$(CONFIG_BATTERY_GAUGE_LTC2941) += ltc2941-battery-gauge.o
obj-$(CONFIG_BATTERY_GOLDFISH) += goldfish_battery.o
obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o
obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o
obj-$(CONFIG_BATTERY_BQ27XXX) += bq27xxx_battery.o
obj-$(CONFIG_BATTERY_BQ27XXX_I2C) += bq27xxx_battery_i2c.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o
obj-$(CONFIG_BATTERY_DA9150) += da9150-fg.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
obj-$(CONFIG_BATTERY_RT5033) += rt5033_battery.o
obj-$(CONFIG_CHARGER_RT9455) += rt9455_charger.o
obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o
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_BATTERY_RX51) += rx51_battery.o
obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o pm2301_charger.o
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
obj-$(CONFIG_CHARGER_MAX14577) += max14577_charger.o
obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
obj-$(CONFIG_CHARGER_QCOM_SMBB) += qcom_smbb.o
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o
obj-$(CONFIG_CHARGER_BQ24257) += bq24257_charger.o
obj-$(CONFIG_CHARGER_BQ24735) += bq24735-charger.o
obj-$(CONFIG_CHARGER_BQ25890) += bq25890_charger.o
obj-$(CONFIG_POWER_AVS) += avs/ obj-$(CONFIG_POWER_AVS) += avs/
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o
obj-$(CONFIG_POWER_RESET) += reset/ obj-$(CONFIG_POWER_RESET) += reset/
obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o obj-$(CONFIG_POWER_SUPPLY) += supply/
obj-$(CONFIG_AXP288_CHARGER) += axp288_charger.o
...@@ -139,7 +139,7 @@ static int rsctrl_probe(struct platform_device *pdev) ...@@ -139,7 +139,7 @@ static int rsctrl_probe(struct platform_device *pdev)
} }
if (val >= WDT_MUX_NUMBER) { if (val >= WDT_MUX_NUMBER) {
dev_err(dev, "ti,wdt-list property can contain" dev_err(dev, "ti,wdt-list property can contain "
"only numbers < 4\n"); "only numbers < 4\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -135,6 +135,65 @@ int reboot_mode_unregister(struct reboot_mode_driver *reboot) ...@@ -135,6 +135,65 @@ int reboot_mode_unregister(struct reboot_mode_driver *reboot)
} }
EXPORT_SYMBOL_GPL(reboot_mode_unregister); EXPORT_SYMBOL_GPL(reboot_mode_unregister);
static void devm_reboot_mode_release(struct device *dev, void *res)
{
reboot_mode_unregister(*(struct reboot_mode_driver **)res);
}
/**
* devm_reboot_mode_register() - resource managed reboot_mode_register()
* @dev: device to associate this resource with
* @reboot: reboot mode driver
*
* Returns: 0 on success or a negative error code on failure.
*/
int devm_reboot_mode_register(struct device *dev,
struct reboot_mode_driver *reboot)
{
struct reboot_mode_driver **dr;
int rc;
dr = devres_alloc(devm_reboot_mode_release, sizeof(*dr), GFP_KERNEL);
if (!dr)
return -ENOMEM;
rc = reboot_mode_register(reboot);
if (rc) {
devres_free(dr);
return rc;
}
*dr = reboot;
devres_add(dev, dr);
return 0;
}
EXPORT_SYMBOL_GPL(devm_reboot_mode_register);
static int devm_reboot_mode_match(struct device *dev, void *res, void *data)
{
struct reboot_mode_driver **p = res;
if (WARN_ON(!p || !*p))
return 0;
return *p == data;
}
/**
* devm_reboot_mode_unregister() - resource managed reboot_mode_unregister()
* @dev: device to associate this resource with
* @reboot: reboot mode driver
*/
void devm_reboot_mode_unregister(struct device *dev,
struct reboot_mode_driver *reboot)
{
WARN_ON(devres_release(dev,
devm_reboot_mode_release,
devm_reboot_mode_match, reboot));
}
EXPORT_SYMBOL_GPL(devm_reboot_mode_unregister);
MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com"); MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com");
MODULE_DESCRIPTION("System reboot mode core library"); MODULE_DESCRIPTION("System reboot mode core library");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -10,5 +10,9 @@ struct reboot_mode_driver { ...@@ -10,5 +10,9 @@ struct reboot_mode_driver {
int reboot_mode_register(struct reboot_mode_driver *reboot); int reboot_mode_register(struct reboot_mode_driver *reboot);
int reboot_mode_unregister(struct reboot_mode_driver *reboot); int reboot_mode_unregister(struct reboot_mode_driver *reboot);
int devm_reboot_mode_register(struct device *dev,
struct reboot_mode_driver *reboot);
void devm_reboot_mode_unregister(struct device *dev,
struct reboot_mode_driver *reboot);
#endif #endif
...@@ -28,28 +28,6 @@ struct reset_syscfg { ...@@ -28,28 +28,6 @@ struct reset_syscfg {
unsigned int mask_rst_msk; unsigned int mask_rst_msk;
}; };
/* STiH415 */
#define STIH415_SYSCFG_11 0x2c
#define STIH415_SYSCFG_15 0x3c
static struct reset_syscfg stih415_reset = {
.offset_rst = STIH415_SYSCFG_11,
.mask_rst = BIT(0),
.offset_rst_msk = STIH415_SYSCFG_15,
.mask_rst_msk = BIT(0)
};
/* STiH416 */
#define STIH416_SYSCFG_500 0x7d0
#define STIH416_SYSCFG_504 0x7e0
static struct reset_syscfg stih416_reset = {
.offset_rst = STIH416_SYSCFG_500,
.mask_rst = BIT(0),
.offset_rst_msk = STIH416_SYSCFG_504,
.mask_rst_msk = BIT(0)
};
/* STiH407 */ /* STiH407 */
#define STIH407_SYSCFG_4000 0x0 #define STIH407_SYSCFG_4000 0x0
#define STIH407_SYSCFG_4008 0x20 #define STIH407_SYSCFG_4008 0x20
...@@ -61,16 +39,6 @@ static struct reset_syscfg stih407_reset = { ...@@ -61,16 +39,6 @@ static struct reset_syscfg stih407_reset = {
.mask_rst_msk = BIT(0) .mask_rst_msk = BIT(0)
}; };
/* STiD127 */
#define STID127_SYSCFG_700 0x0
#define STID127_SYSCFG_773 0x124
static struct reset_syscfg stid127_reset = {
.offset_rst = STID127_SYSCFG_773,
.mask_rst = BIT(0),
.offset_rst_msk = STID127_SYSCFG_700,
.mask_rst_msk = BIT(8)
};
static struct reset_syscfg *st_restart_syscfg; static struct reset_syscfg *st_restart_syscfg;
...@@ -99,17 +67,8 @@ static struct notifier_block st_restart_nb = { ...@@ -99,17 +67,8 @@ static struct notifier_block st_restart_nb = {
static const struct of_device_id st_reset_of_match[] = { static const struct of_device_id st_reset_of_match[] = {
{ {
.compatible = "st,stih415-restart",
.data = (void *)&stih415_reset,
}, {
.compatible = "st,stih416-restart",
.data = (void *)&stih416_reset,
}, {
.compatible = "st,stih407-restart", .compatible = "st,stih407-restart",
.data = (void *)&stih407_reset, .data = (void *)&stih407_reset,
}, {
.compatible = "st,stid127-restart",
.data = (void *)&stid127_reset,
}, },
{} {}
}; };
......
...@@ -53,8 +53,6 @@ static int syscon_reboot_mode_probe(struct platform_device *pdev) ...@@ -53,8 +53,6 @@ static int syscon_reboot_mode_probe(struct platform_device *pdev)
syscon_rbm->reboot.write = syscon_reboot_mode_write; syscon_rbm->reboot.write = syscon_reboot_mode_write;
syscon_rbm->mask = 0xffffffff; syscon_rbm->mask = 0xffffffff;
dev_set_drvdata(&pdev->dev, syscon_rbm);
syscon_rbm->map = syscon_node_to_regmap(pdev->dev.parent->of_node); syscon_rbm->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
if (IS_ERR(syscon_rbm->map)) if (IS_ERR(syscon_rbm->map))
return PTR_ERR(syscon_rbm->map); return PTR_ERR(syscon_rbm->map);
...@@ -65,20 +63,13 @@ static int syscon_reboot_mode_probe(struct platform_device *pdev) ...@@ -65,20 +63,13 @@ static int syscon_reboot_mode_probe(struct platform_device *pdev)
of_property_read_u32(pdev->dev.of_node, "mask", &syscon_rbm->mask); of_property_read_u32(pdev->dev.of_node, "mask", &syscon_rbm->mask);
ret = reboot_mode_register(&syscon_rbm->reboot); ret = devm_reboot_mode_register(&pdev->dev, &syscon_rbm->reboot);
if (ret) if (ret)
dev_err(&pdev->dev, "can't register reboot mode\n"); dev_err(&pdev->dev, "can't register reboot mode\n");
return ret; return ret;
} }
static int syscon_reboot_mode_remove(struct platform_device *pdev)
{
struct syscon_reboot_mode *syscon_rbm = dev_get_drvdata(&pdev->dev);
return reboot_mode_unregister(&syscon_rbm->reboot);
}
static const struct of_device_id syscon_reboot_mode_of_match[] = { static const struct of_device_id syscon_reboot_mode_of_match[] = {
{ .compatible = "syscon-reboot-mode" }, { .compatible = "syscon-reboot-mode" },
{} {}
...@@ -86,7 +77,6 @@ static const struct of_device_id syscon_reboot_mode_of_match[] = { ...@@ -86,7 +77,6 @@ static const struct of_device_id syscon_reboot_mode_of_match[] = {
static struct platform_driver syscon_reboot_mode_driver = { static struct platform_driver syscon_reboot_mode_driver = {
.probe = syscon_reboot_mode_probe, .probe = syscon_reboot_mode_probe,
.remove = syscon_reboot_mode_remove,
.driver = { .driver = {
.name = "syscon-reboot-mode", .name = "syscon-reboot-mode",
.of_match_table = syscon_reboot_mode_of_match, .of_match_table = syscon_reboot_mode_of_match,
......
...@@ -81,8 +81,10 @@ static int xgene_reboot_probe(struct platform_device *pdev) ...@@ -81,8 +81,10 @@ static int xgene_reboot_probe(struct platform_device *pdev)
ctx->restart_handler.notifier_call = xgene_restart_handler; ctx->restart_handler.notifier_call = xgene_restart_handler;
ctx->restart_handler.priority = 128; ctx->restart_handler.priority = 128;
err = register_restart_handler(&ctx->restart_handler); err = register_restart_handler(&ctx->restart_handler);
if (err) if (err) {
iounmap(ctx->csr);
dev_err(dev, "cannot register restart handler (err=%d)\n", err); dev_err(dev, "cannot register restart handler (err=%d)\n", err);
}
return err; return err;
} }
......
...@@ -58,9 +58,12 @@ static int zx_reboot_probe(struct platform_device *pdev) ...@@ -58,9 +58,12 @@ static int zx_reboot_probe(struct platform_device *pdev)
} }
err = register_restart_handler(&zx_restart_nb); err = register_restart_handler(&zx_restart_nb);
if (err) if (err) {
iounmap(base);
iounmap(pcu_base);
dev_err(&pdev->dev, "Register restart handler failed(err=%d)\n", dev_err(&pdev->dev, "Register restart handler failed(err=%d)\n",
err); err);
}
return err; return err;
} }
......
menuconfig POWER_SUPPLY
bool "Power supply class support"
help
Say Y here to enable power supply class support. This allows
power supply (batteries, AC, USB) monitoring by userspace
via sysfs and uevent (if available) and/or APM kernel interface
(if selected below).
if POWER_SUPPLY
config POWER_SUPPLY_DEBUG
bool "Power supply debug"
help
Say Y here to enable debugging messages for power supply class
and drivers.
config PDA_POWER
tristate "Generic PDA/phone power driver"
depends on !S390
help
Say Y here to enable generic power driver for PDAs and phones with
one or two external power supplies (AC/USB) connected to main and
backup batteries, and optional builtin charger.
config APM_POWER
tristate "APM emulation for class batteries"
depends on APM_EMULATION
help
Say Y here to enable support APM status emulation using
battery class devices.
config GENERIC_ADC_BATTERY
tristate "Generic battery support using IIO"
depends on IIO
help
Say Y here to enable support for the generic battery driver
which uses IIO framework to read adc.
config MAX8925_POWER
tristate "MAX8925 battery charger support"
depends on MFD_MAX8925
help
Say Y here to enable support for the battery charger in the Maxim
MAX8925 PMIC.
config WM831X_BACKUP
tristate "WM831X backup battery charger support"
depends on MFD_WM831X
help
Say Y here to enable support for the backup battery charger
in the Wolfson Microelectronics WM831x PMICs.
config WM831X_POWER
tristate "WM831X PMU support"
depends on MFD_WM831X
help
Say Y here to enable support for the power management unit
provided by Wolfson Microelectronics WM831x PMICs.
config WM8350_POWER
tristate "WM8350 PMU support"
depends on MFD_WM8350
help
Say Y here to enable support for the power management unit
provided by the Wolfson Microelectronics WM8350 PMIC.
config TEST_POWER
tristate "Test power driver"
help
This driver is used for testing. It's safe to say M here.
config BATTERY_88PM860X
tristate "Marvell 88PM860x battery driver"
depends on MFD_88PM860X
help
Say Y here to enable battery monitor for Marvell 88PM860x chip.
config BATTERY_ACT8945A
tristate "Active-semi ACT8945A charger driver"
depends on MFD_ACT8945A || COMPILE_TEST
help
Say Y here to enable support for power supply provided by
Active-semi ActivePath ACT8945A charger.
config BATTERY_DS2760
tristate "DS2760 battery driver (HP iPAQ & others)"
depends on W1 && W1_SLAVE_DS2760
help
Say Y here to enable support for batteries with ds2760 chip.
config BATTERY_DS2780
tristate "DS2780 battery driver"
depends on HAS_IOMEM
select W1
select W1_SLAVE_DS2780
help
Say Y here to enable support for batteries with ds2780 chip.
config BATTERY_DS2781
tristate "DS2781 battery driver"
depends on HAS_IOMEM
select W1
select W1_SLAVE_DS2781
help
If you enable this you will have the DS2781 battery driver support.
The battery monitor chip is used in many batteries/devices
as the one who is responsible for charging/discharging/monitoring
Li+ batteries.
If you are unsure, say N.
config BATTERY_DS2782
tristate "DS2782/DS2786 standalone gas-gauge"
depends on I2C
help
Say Y here to enable support for the DS2782/DS2786 standalone battery
gas-gauge.
config BATTERY_PMU
tristate "Apple PMU battery"
depends on PPC32 && ADB_PMU
help
Say Y here to expose battery information on Apple machines
through the generic battery class.
config BATTERY_OLPC
tristate "One Laptop Per Child battery"
depends on X86_32 && OLPC
help
Say Y to enable support for the battery on the OLPC laptop.
config BATTERY_TOSA
tristate "Sharp SL-6000 (tosa) battery"
depends on MACH_TOSA && MFD_TC6393XB && TOUCHSCREEN_WM97XX
help
Say Y to enable support for the battery on the Sharp Zaurus
SL-6000 (tosa) models.
config BATTERY_COLLIE
tristate "Sharp SL-5500 (collie) battery"
depends on SA1100_COLLIE && MCP_UCB1200
help
Say Y to enable support for the battery on the Sharp Zaurus
SL-5500 (collie) models.
config BATTERY_IPAQ_MICRO
tristate "iPAQ Atmel Micro ASIC battery driver"
depends on MFD_IPAQ_MICRO
help
Choose this option if you want to monitor battery status on
Compaq/HP iPAQ h3100 and h3600.
config BATTERY_WM97XX
bool "WM97xx generic battery driver"
depends on TOUCHSCREEN_WM97XX=y
help
Say Y to enable support for battery measured by WM97xx aux port.
config BATTERY_SBS
tristate "SBS Compliant gas gauge"
depends on I2C
help
Say Y to include support for SBS battery driver for SBS-compliant
gas gauges.
config BATTERY_BQ27XXX
tristate "BQ27xxx battery driver"
help
Say Y here to enable support for batteries with BQ27xxx chips.
config BATTERY_BQ27XXX_I2C
tristate "BQ27xxx I2C support"
depends on BATTERY_BQ27XXX
depends on I2C
default y
help
Say Y here to enable support for batteries with BQ27xxx chips
connected over an I2C bus.
config BATTERY_DA9030
tristate "DA9030 battery driver"
depends on PMIC_DA903X
help
Say Y here to enable support for batteries charger integrated into
DA9030 PMIC.
config BATTERY_DA9052
tristate "Dialog DA9052 Battery"
depends on PMIC_DA9052
help
Say Y here to enable support for batteries charger integrated into
DA9052 PMIC.
config CHARGER_DA9150
tristate "Dialog Semiconductor DA9150 Charger support"
depends on MFD_DA9150
depends on DA9150_GPADC
depends on IIO
help
Say Y here to enable support for charger unit of the DA9150
Integrated Charger & Fuel-Gauge IC.
This driver can also be built as a module. If so, the module will be
called da9150-charger.
config BATTERY_DA9150
tristate "Dialog Semiconductor DA9150 Fuel Gauge support"
depends on MFD_DA9150
help
Say Y here to enable support for the Fuel-Gauge unit of the DA9150
Integrated Charger & Fuel-Gauge IC
This driver can also be built as a module. If so, the module will be
called da9150-fg.
config AXP288_CHARGER
tristate "X-Powers AXP288 Charger"
depends on MFD_AXP20X && EXTCON_AXP288
help
Say yes here to have support X-Power AXP288 power management IC (PMIC)
integrated charger.
config AXP288_FUEL_GAUGE
tristate "X-Powers AXP288 Fuel Gauge"
depends on MFD_AXP20X && IIO
help
Say yes here to have support for X-Power power management IC (PMIC)
Fuel Gauge. The device provides battery statistics and status
monitoring as well as alerts for battery over/under voltage and
over/under temperature.
config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
help
MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
in handheld and portable equipment. The MAX17040 is configured
to operate with a single lithium cell
config BATTERY_MAX17042
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
depends on I2C
select REGMAP_I2C
help
MAX17042 is fuel-gauge systems for lithium-ion (Li+) batteries
in handheld and portable equipment. The MAX17042 is configured
to operate with a single lithium cell. MAX8997 and MAX8966 are
multi-function devices that include fuel gauages that are compatible
with MAX17042. This driver also supports max17047/50 chips which are
improved version of max17042.
config BATTERY_Z2
tristate "Z2 battery driver"
depends on I2C && MACH_ZIPIT2
help
Say Y to include support for the battery on the Zipit Z2.
config BATTERY_S3C_ADC
tristate "Battery driver for Samsung ADC based monitoring"
depends on S3C_ADC
help
Say Y here to enable support for iPAQ h1930/h1940/rx1950 battery
config BATTERY_TWL4030_MADC
tristate "TWL4030 MADC battery driver"
depends on TWL4030_MADC
help
Say Y here to enable this dumb driver for batteries managed
through the TWL4030 MADC.
config CHARGER_88PM860X
tristate "Marvell 88PM860x Charger driver"
depends on MFD_88PM860X && BATTERY_88PM860X
help
Say Y here to enable charger for Marvell 88PM860x chip.
config CHARGER_PCF50633
tristate "NXP PCF50633 MBC"
depends on MFD_PCF50633
help
Say Y to include support for NXP PCF50633 Main Battery Charger.
config BATTERY_JZ4740
tristate "Ingenic JZ4740 battery"
depends on MACH_JZ4740
depends on MFD_JZ4740_ADC
help
Say Y to enable support for the battery on Ingenic JZ4740 based
boards.
This driver can be build as a module. If so, the module will be
called jz4740-battery.
config BATTERY_INTEL_MID
tristate "Battery driver for Intel MID platforms"
depends on INTEL_SCU_IPC && SPI
help
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_PHY
depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y'
help
Say Y to enable support for USB Charger Detection with
ISP1707/ISP1704 USB transceivers.
config CHARGER_MAX8903
tristate "MAX8903 Battery DC-DC Charger for USB and Adapter Power"
help
Say Y to enable support for the MAX8903 DC-DC charger and sysfs.
The driver supports controlling charger-enable and current-limit
pins based on the status of charger connections with interrupt
handlers.
config CHARGER_TWL4030
tristate "OMAP TWL4030 BCI charger driver"
depends on IIO && TWL4030_CORE
help
Say Y here to enable support for TWL4030 Battery Charge Interface.
config CHARGER_LP8727
tristate "TI/National Semiconductor LP8727 charger driver"
depends on I2C
help
Say Y here to enable support for LP8727 Charger Driver.
config CHARGER_LP8788
tristate "TI LP8788 charger driver"
depends on MFD_LP8788
depends on LP8788_ADC
depends on IIO
help
Say Y to enable support for the LP8788 linear charger.
config CHARGER_GPIO
tristate "GPIO charger"
depends on GPIOLIB || COMPILE_TEST
help
Say Y to include support for chargers which report their online status
through a GPIO pin.
This driver can be build as a module. If so, the module will be
called gpio-charger.
config CHARGER_MANAGER
bool "Battery charger manager for multiple chargers"
depends on REGULATOR
select EXTCON
help
Say Y to enable charger-manager support, which allows multiple
chargers attached to a battery and multiple batteries attached to a
system. The charger-manager also can monitor charging status in
runtime and in suspend-to-RAM by waking up the system periodically
with help of suspend_again support.
config CHARGER_MAX14577
tristate "Maxim MAX14577/77836 battery charger driver"
depends on MFD_MAX14577
help
Say Y to enable support for the battery charger control sysfs and
platform data of MAX14577/77836 MUICs.
config CHARGER_MAX77693
tristate "Maxim MAX77693 battery charger driver"
depends on MFD_MAX77693
help
Say Y to enable support for the Maxim MAX77693 battery charger.
config CHARGER_MAX8997
tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
depends on MFD_MAX8997 && REGULATOR_MAX8997
help
Say Y to enable support for the battery charger control sysfs and
platform data of MAX8997/LP3974 PMICs.
config CHARGER_MAX8998
tristate "Maxim MAX8998/LP3974 PMIC battery charger driver"
depends on MFD_MAX8998 && REGULATOR_MAX8998
help
Say Y to enable support for the battery charger control sysfs and
platform data of MAX8998/LP3974 PMICs.
config CHARGER_QCOM_SMBB
tristate "Qualcomm Switch-Mode Battery Charger and Boost"
depends on MFD_SPMI_PMIC || COMPILE_TEST
depends on OF
depends on EXTCON
help
Say Y to include support for the Switch-Mode Battery Charger and
Boost (SMBB) hardware found in Qualcomm PM8941 PMICs. The charger
is an integrated, single-cell lithium-ion battery charger. DT
configuration is required for loading, see the devicetree
documentation for more detail. The base name for this driver is
'pm8941_charger'.
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_BQ24190
tristate "TI BQ24190 battery charger driver"
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 BQ24250/24251/24257 battery charger driver"
depends on I2C
depends on GPIOLIB || COMPILE_TEST
depends on REGMAP_I2C
help
Say Y to enable support for the TI BQ24250, BQ24251, and BQ24257 battery
chargers.
config CHARGER_BQ24735
tristate "TI BQ24735 battery charger support"
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
depends on GPIOLIB || COMPILE_TEST
select REGMAP_I2C
help
Say Y to enable support for the TI BQ25890 battery charger.
config CHARGER_SMB347
tristate "Summit Microelectronics SMB347 Battery Charger"
depends on I2C
select REGMAP_I2C
help
Say Y to include support for Summit Microelectronics SMB347
Battery Charger.
config CHARGER_TPS65090
tristate "TPS65090 battery charger driver"
depends on MFD_TPS65090
help
Say Y here to enable support for battery charging with TPS65090
PMIC chips.
config CHARGER_TPS65217
tristate "TPS65217 battery charger driver"
depends on MFD_TPS65217
help
Say Y here to enable support for battery charging with TPS65217
PMIC chips.
config BATTERY_GAUGE_LTC2941
tristate "LTC2941/LTC2943 Battery Gauge Driver"
depends on I2C
help
Say Y here to include support for LTC2941 and LTC2943 Battery
Gauge IC. The driver reports the charge count continuously, and
measures the voltage and temperature every 10 seconds.
config AB8500_BM
bool "AB8500 Battery Management Driver"
depends on AB8500_CORE && AB8500_GPADC
help
Say Y to include support for AB8500 battery management.
config BATTERY_GOLDFISH
tristate "Goldfish battery driver"
depends on GOLDFISH || COMPILE_TEST
depends on HAS_IOMEM
help
Say Y to enable support for the battery and AC power in the
Goldfish emulator.
config BATTERY_RT5033
tristate "RT5033 fuel gauge support"
depends on MFD_RT5033
help
This adds support for battery fuel gauge in Richtek RT5033 PMIC.
The fuelgauge calculates and determines the battery state of charge
according to battery open circuit voltage.
config CHARGER_RT9455
tristate "Richtek RT9455 battery charger driver"
depends on I2C
depends on GPIOLIB || COMPILE_TEST
select REGMAP_I2C
help
Say Y to enable support for Richtek RT9455 battery charger.
config AXP20X_POWER
tristate "AXP20x power supply driver"
depends on MFD_AXP20X
help
This driver provides support for the power supply features of
AXP20x PMIC.
endif # POWER_SUPPLY
subdir-ccflags-$(CONFIG_POWER_SUPPLY_DEBUG) := -DDEBUG
power_supply-y := power_supply_core.o
power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o
power_supply-$(CONFIG_LEDS_TRIGGERS) += power_supply_leds.o
obj-$(CONFIG_POWER_SUPPLY) += power_supply.o
obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o
obj-$(CONFIG_PDA_POWER) += pda_power.o
obj-$(CONFIG_APM_POWER) += apm_power.o
obj-$(CONFIG_AXP20X_POWER) += axp20x_usb_power.o
obj-$(CONFIG_MAX8925_POWER) += max8925_power.o
obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o
obj-$(CONFIG_WM831X_POWER) += wm831x_power.o
obj-$(CONFIG_WM8350_POWER) += wm8350_power.o
obj-$(CONFIG_TEST_POWER) += test_power.o
obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o
obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o
obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o
obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o
obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o
obj-$(CONFIG_BATTERY_GAUGE_LTC2941) += ltc2941-battery-gauge.o
obj-$(CONFIG_BATTERY_GOLDFISH) += goldfish_battery.o
obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o
obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o
obj-$(CONFIG_BATTERY_BQ27XXX) += bq27xxx_battery.o
obj-$(CONFIG_BATTERY_BQ27XXX_I2C) += bq27xxx_battery_i2c.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o
obj-$(CONFIG_BATTERY_DA9150) += da9150-fg.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
obj-$(CONFIG_BATTERY_RT5033) += rt5033_battery.o
obj-$(CONFIG_CHARGER_RT9455) += rt9455_charger.o
obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o
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_BATTERY_RX51) += rx51_battery.o
obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o pm2301_charger.o
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
obj-$(CONFIG_CHARGER_MAX14577) += max14577_charger.o
obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
obj-$(CONFIG_CHARGER_QCOM_SMBB) += qcom_smbb.o
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o
obj-$(CONFIG_CHARGER_BQ24257) += bq24257_charger.o
obj-$(CONFIG_CHARGER_BQ24735) += bq24735-charger.o
obj-$(CONFIG_CHARGER_BQ25890) += bq25890_charger.o
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o
obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o
obj-$(CONFIG_AXP288_CHARGER) += axp288_charger.o
...@@ -1095,7 +1095,7 @@ static int ab8500_btemp_probe(struct platform_device *pdev) ...@@ -1095,7 +1095,7 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
/* Create a work queue for the btemp */ /* Create a work queue for the btemp */
di->btemp_wq = di->btemp_wq =
create_singlethread_workqueue("ab8500_btemp_wq"); alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0);
if (di->btemp_wq == NULL) { if (di->btemp_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n"); dev_err(di->dev, "failed to create work queue\n");
return -ENOMEM; return -ENOMEM;
......
...@@ -3540,8 +3540,8 @@ static int ab8500_charger_probe(struct platform_device *pdev) ...@@ -3540,8 +3540,8 @@ static int ab8500_charger_probe(struct platform_device *pdev)
di->usb_state.usb_current = -1; di->usb_state.usb_current = -1;
/* Create a work queue for the charger */ /* Create a work queue for the charger */
di->charger_wq = di->charger_wq = alloc_ordered_workqueue("ab8500_charger_wq",
create_singlethread_workqueue("ab8500_charger_wq"); WQ_MEM_RECLAIM);
if (di->charger_wq == NULL) { if (di->charger_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n"); dev_err(di->dev, "failed to create work queue\n");
return -ENOMEM; return -ENOMEM;
......
...@@ -245,13 +245,8 @@ static LIST_HEAD(ab8500_fg_list); ...@@ -245,13 +245,8 @@ static LIST_HEAD(ab8500_fg_list);
*/ */
struct ab8500_fg *ab8500_fg_get(void) struct ab8500_fg *ab8500_fg_get(void)
{ {
struct ab8500_fg *fg; return list_first_entry_or_null(&ab8500_fg_list, struct ab8500_fg,
node);
if (list_empty(&ab8500_fg_list))
return NULL;
fg = list_first_entry(&ab8500_fg_list, struct ab8500_fg, node);
return fg;
} }
/* Main battery properties */ /* Main battery properties */
...@@ -3096,7 +3091,7 @@ static int ab8500_fg_probe(struct platform_device *pdev) ...@@ -3096,7 +3091,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
ab8500_fg_discharge_state_to(di, AB8500_FG_DISCHARGE_INIT); ab8500_fg_discharge_state_to(di, AB8500_FG_DISCHARGE_INIT);
/* Create a work queue for running the FG algorithm */ /* Create a work queue for running the FG algorithm */
di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq"); di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM);
if (di->fg_wq == NULL) { if (di->fg_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n"); dev_err(di->dev, "failed to create work queue\n");
return -ENOMEM; return -ENOMEM;
......
...@@ -2091,8 +2091,8 @@ static int abx500_chargalg_probe(struct platform_device *pdev) ...@@ -2091,8 +2091,8 @@ static int abx500_chargalg_probe(struct platform_device *pdev)
abx500_chargalg_maintenance_timer_expired; abx500_chargalg_maintenance_timer_expired;
/* Create a work queue for the chargalg */ /* Create a work queue for the chargalg */
di->chargalg_wq = di->chargalg_wq = alloc_ordered_workqueue("abx500_chargalg_wq",
create_singlethread_workqueue("abx500_chargalg_wq"); WQ_MEM_RECLAIM);
if (di->chargalg_wq == NULL) { if (di->chargalg_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n"); dev_err(di->dev, "failed to create work queue\n");
return -ENOMEM; return -ENOMEM;
......
...@@ -10,12 +10,14 @@ ...@@ -10,12 +10,14 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
*/ */
#include <linux/interrupt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h> #include <linux/of_irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/gpio/consumer.h>
static const char *act8945a_charger_model = "ACT8945A"; static const char *act8945a_charger_model = "ACT8945A";
static const char *act8945a_charger_manufacturer = "Active-semi"; static const char *act8945a_charger_manufacturer = "Active-semi";
...@@ -75,8 +77,14 @@ static const char *act8945a_charger_manufacturer = "Active-semi"; ...@@ -75,8 +77,14 @@ static const char *act8945a_charger_manufacturer = "Active-semi";
#define APCH_STATE_CSTATE_PRE 0x03 #define APCH_STATE_CSTATE_PRE 0x03
struct act8945a_charger { struct act8945a_charger {
struct power_supply *psy;
struct power_supply_desc desc;
struct regmap *regmap; struct regmap *regmap;
bool battery_temperature; struct work_struct work;
bool init_done;
struct gpio_desc *lbo_gpio;
struct gpio_desc *chglev_gpio;
}; };
static int act8945a_get_charger_state(struct regmap *regmap, int *val) static int act8945a_get_charger_state(struct regmap *regmap, int *val)
...@@ -95,16 +103,24 @@ static int act8945a_get_charger_state(struct regmap *regmap, int *val) ...@@ -95,16 +103,24 @@ static int act8945a_get_charger_state(struct regmap *regmap, int *val)
state &= APCH_STATE_CSTATE; state &= APCH_STATE_CSTATE;
state >>= APCH_STATE_CSTATE_SHIFT; state >>= APCH_STATE_CSTATE_SHIFT;
if (state == APCH_STATE_CSTATE_EOC) { switch (state) {
case APCH_STATE_CSTATE_PRE:
case APCH_STATE_CSTATE_FAST:
*val = POWER_SUPPLY_STATUS_CHARGING;
break;
case APCH_STATE_CSTATE_EOC:
if (status & APCH_STATUS_CHGDAT) if (status & APCH_STATUS_CHGDAT)
*val = POWER_SUPPLY_STATUS_FULL; *val = POWER_SUPPLY_STATUS_FULL;
else else
*val = POWER_SUPPLY_STATUS_NOT_CHARGING;
} else if ((state == APCH_STATE_CSTATE_FAST) ||
(state == APCH_STATE_CSTATE_PRE)) {
*val = POWER_SUPPLY_STATUS_CHARGING; *val = POWER_SUPPLY_STATUS_CHARGING;
} else { break;
case APCH_STATE_CSTATE_DISABLED:
default:
if (!(status & APCH_STATUS_INDAT))
*val = POWER_SUPPLY_STATUS_DISCHARGING;
else
*val = POWER_SUPPLY_STATUS_NOT_CHARGING; *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
break;
} }
return 0; return 0;
...@@ -113,7 +129,11 @@ static int act8945a_get_charger_state(struct regmap *regmap, int *val) ...@@ -113,7 +129,11 @@ static int act8945a_get_charger_state(struct regmap *regmap, int *val)
static int act8945a_get_charge_type(struct regmap *regmap, int *val) static int act8945a_get_charge_type(struct regmap *regmap, int *val)
{ {
int ret; int ret;
unsigned int state; unsigned int status, state;
ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
if (ret < 0)
return ret;
ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state); ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
if (ret < 0) if (ret < 0)
...@@ -130,32 +150,184 @@ static int act8945a_get_charge_type(struct regmap *regmap, int *val) ...@@ -130,32 +150,184 @@ static int act8945a_get_charge_type(struct regmap *regmap, int *val)
*val = POWER_SUPPLY_CHARGE_TYPE_FAST; *val = POWER_SUPPLY_CHARGE_TYPE_FAST;
break; break;
case APCH_STATE_CSTATE_EOC: case APCH_STATE_CSTATE_EOC:
*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
break;
case APCH_STATE_CSTATE_DISABLED: case APCH_STATE_CSTATE_DISABLED:
default: default:
if (!(status & APCH_STATUS_INDAT))
*val = POWER_SUPPLY_CHARGE_TYPE_NONE; *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
else
*val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
break;
} }
return 0; return 0;
} }
static int act8945a_get_battery_health(struct act8945a_charger *charger, static int act8945a_get_battery_health(struct regmap *regmap, int *val)
struct regmap *regmap, int *val)
{ {
int ret; int ret;
unsigned int status; unsigned int status, state, config;
ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status); ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (charger->battery_temperature && !(status & APCH_STATUS_TEMPDAT)) ret = regmap_read(regmap, ACT8945A_APCH_CFG, &config);
if (ret < 0)
return ret;
ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
if (ret < 0)
return ret;
state &= APCH_STATE_CSTATE;
state >>= APCH_STATE_CSTATE_SHIFT;
switch (state) {
case APCH_STATE_CSTATE_DISABLED:
if (config & APCH_CFG_SUSCHG) {
*val = POWER_SUPPLY_HEALTH_UNKNOWN;
} else if (status & APCH_STATUS_INDAT) {
if (!(status & APCH_STATUS_TEMPDAT))
*val = POWER_SUPPLY_HEALTH_OVERHEAT; *val = POWER_SUPPLY_HEALTH_OVERHEAT;
else if (!(status & APCH_STATUS_INDAT))
*val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
else if (status & APCH_STATUS_TIMRDAT) else if (status & APCH_STATUS_TIMRDAT)
*val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
else else
*val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
} else {
*val = POWER_SUPPLY_HEALTH_GOOD;
}
break;
case APCH_STATE_CSTATE_PRE:
case APCH_STATE_CSTATE_FAST:
case APCH_STATE_CSTATE_EOC:
default:
*val = POWER_SUPPLY_HEALTH_GOOD; *val = POWER_SUPPLY_HEALTH_GOOD;
break;
}
return 0;
}
static int act8945a_get_capacity_level(struct act8945a_charger *charger,
struct regmap *regmap, int *val)
{
int ret;
unsigned int status, state, config;
int lbo_level = gpiod_get_value(charger->lbo_gpio);
ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
if (ret < 0)
return ret;
ret = regmap_read(regmap, ACT8945A_APCH_CFG, &config);
if (ret < 0)
return ret;
ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
if (ret < 0)
return ret;
state &= APCH_STATE_CSTATE;
state >>= APCH_STATE_CSTATE_SHIFT;
switch (state) {
case APCH_STATE_CSTATE_PRE:
*val = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
break;
case APCH_STATE_CSTATE_FAST:
if (lbo_level)
*val = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
else
*val = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
break;
case APCH_STATE_CSTATE_EOC:
if (status & APCH_STATUS_CHGDAT)
*val = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
else
*val = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
break;
case APCH_STATE_CSTATE_DISABLED:
default:
if (config & APCH_CFG_SUSCHG) {
*val = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
} else {
*val = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
if (!(status & APCH_STATUS_INDAT)) {
if (!lbo_level)
*val = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
}
}
break;
}
return 0;
}
#define MAX_CURRENT_USB_HIGH 450000
#define MAX_CURRENT_USB_LOW 90000
#define MAX_CURRENT_USB_PRE 45000
/*
* Riset(K) = 2336 * (1V/Ichg(mA)) - 0.205
* Riset = 2.43K
*/
#define MAX_CURRENT_AC_HIGH 886527
#define MAX_CURRENT_AC_LOW 117305
#define MAX_CURRENT_AC_HIGH_PRE 88653
#define MAX_CURRENT_AC_LOW_PRE 11731
static int act8945a_get_current_max(struct act8945a_charger *charger,
struct regmap *regmap, int *val)
{
int ret;
unsigned int status, state;
unsigned int acin_state;
int chgin_level = gpiod_get_value(charger->chglev_gpio);
ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
if (ret < 0)
return ret;
ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
if (ret < 0)
return ret;
acin_state = (state & APCH_STATE_ACINSTAT) >> 1;
state &= APCH_STATE_CSTATE;
state >>= APCH_STATE_CSTATE_SHIFT;
switch (state) {
case APCH_STATE_CSTATE_PRE:
if (acin_state) {
if (chgin_level)
*val = MAX_CURRENT_AC_HIGH_PRE;
else
*val = MAX_CURRENT_AC_LOW_PRE;
} else {
*val = MAX_CURRENT_USB_PRE;
}
break;
case APCH_STATE_CSTATE_FAST:
if (acin_state) {
if (chgin_level)
*val = MAX_CURRENT_AC_HIGH;
else
*val = MAX_CURRENT_AC_LOW;
} else {
if (chgin_level)
*val = MAX_CURRENT_USB_HIGH;
else
*val = MAX_CURRENT_USB_LOW;
}
break;
case APCH_STATE_CSTATE_EOC:
case APCH_STATE_CSTATE_DISABLED:
default:
*val = 0;
break;
}
return 0; return 0;
} }
...@@ -165,6 +337,8 @@ static enum power_supply_property act8945a_charger_props[] = { ...@@ -165,6 +337,8 @@ static enum power_supply_property act8945a_charger_props[] = {
POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_CHARGE_TYPE,
POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER POWER_SUPPLY_PROP_MANUFACTURER
}; };
...@@ -188,7 +362,14 @@ static int act8945a_charger_get_property(struct power_supply *psy, ...@@ -188,7 +362,14 @@ static int act8945a_charger_get_property(struct power_supply *psy,
val->intval = POWER_SUPPLY_TECHNOLOGY_LION; val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break; break;
case POWER_SUPPLY_PROP_HEALTH: case POWER_SUPPLY_PROP_HEALTH:
ret = act8945a_get_battery_health(charger, ret = act8945a_get_battery_health(regmap, &val->intval);
break;
case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
ret = act8945a_get_capacity_level(charger,
regmap, &val->intval);
break;
case POWER_SUPPLY_PROP_CURRENT_MAX:
ret = act8945a_get_current_max(charger,
regmap, &val->intval); regmap, &val->intval);
break; break;
case POWER_SUPPLY_PROP_MODEL_NAME: case POWER_SUPPLY_PROP_MODEL_NAME:
...@@ -204,13 +385,74 @@ static int act8945a_charger_get_property(struct power_supply *psy, ...@@ -204,13 +385,74 @@ static int act8945a_charger_get_property(struct power_supply *psy,
return ret; return ret;
} }
static const struct power_supply_desc act8945a_charger_desc = { static int act8945a_enable_interrupt(struct act8945a_charger *charger)
.name = "act8945a-charger", {
.type = POWER_SUPPLY_TYPE_BATTERY, struct regmap *regmap = charger->regmap;
.get_property = act8945a_charger_get_property, unsigned char ctrl;
.properties = act8945a_charger_props, int ret;
.num_properties = ARRAY_SIZE(act8945a_charger_props),
}; ctrl = APCH_CTRL_CHGEOCOUT | APCH_CTRL_CHGEOCIN |
APCH_CTRL_INDIS | APCH_CTRL_INCON |
APCH_CTRL_TEMPOUT | APCH_CTRL_TEMPIN |
APCH_CTRL_TIMRPRE | APCH_CTRL_TIMRTOT;
ret = regmap_write(regmap, ACT8945A_APCH_CTRL, ctrl);
if (ret)
return ret;
ctrl = APCH_STATUS_CHGSTAT | APCH_STATUS_INSTAT |
APCH_STATUS_TEMPSTAT | APCH_STATUS_TIMRSTAT;
ret = regmap_write(regmap, ACT8945A_APCH_STATUS, ctrl);
if (ret)
return ret;
return 0;
}
static unsigned int act8945a_set_supply_type(struct act8945a_charger *charger,
unsigned int *type)
{
unsigned int status, state;
int ret;
ret = regmap_read(charger->regmap, ACT8945A_APCH_STATUS, &status);
if (ret < 0)
return ret;
ret = regmap_read(charger->regmap, ACT8945A_APCH_STATE, &state);
if (ret < 0)
return ret;
if (status & APCH_STATUS_INDAT) {
if (state & APCH_STATE_ACINSTAT)
*type = POWER_SUPPLY_TYPE_MAINS;
else
*type = POWER_SUPPLY_TYPE_USB;
} else {
*type = POWER_SUPPLY_TYPE_BATTERY;
}
return 0;
}
static void act8945a_work(struct work_struct *work)
{
struct act8945a_charger *charger =
container_of(work, struct act8945a_charger, work);
act8945a_set_supply_type(charger, &charger->desc.type);
power_supply_changed(charger->psy);
}
static irqreturn_t act8945a_status_changed(int irq, void *dev_id)
{
struct act8945a_charger *charger = dev_id;
if (charger->init_done)
schedule_work(&charger->work);
return IRQ_HANDLED;
}
#define DEFAULT_TOTAL_TIME_OUT 3 #define DEFAULT_TOTAL_TIME_OUT 3
#define DEFAULT_PRE_TIME_OUT 40 #define DEFAULT_PRE_TIME_OUT 40
...@@ -220,14 +462,14 @@ static int act8945a_charger_config(struct device *dev, ...@@ -220,14 +462,14 @@ static int act8945a_charger_config(struct device *dev,
struct act8945a_charger *charger) struct act8945a_charger *charger)
{ {
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
enum of_gpio_flags flags;
struct regmap *regmap = charger->regmap; struct regmap *regmap = charger->regmap;
u32 total_time_out; u32 total_time_out;
u32 pre_time_out; u32 pre_time_out;
u32 input_voltage_threshold; u32 input_voltage_threshold;
int chglev_pin; int err, ret;
unsigned int tmp;
unsigned int value = 0; unsigned int value = 0;
if (!np) { if (!np) {
...@@ -235,15 +477,37 @@ static int act8945a_charger_config(struct device *dev, ...@@ -235,15 +477,37 @@ static int act8945a_charger_config(struct device *dev,
return -EINVAL; return -EINVAL;
} }
charger->battery_temperature = of_property_read_bool(np, ret = regmap_read(regmap, ACT8945A_APCH_CFG, &tmp);
"active-semi,check-battery-temperature"); if (ret)
return ret;
if (tmp & APCH_CFG_SUSCHG) {
value |= APCH_CFG_SUSCHG;
dev_info(dev, "have been suspended\n");
}
chglev_pin = of_get_named_gpio_flags(np, charger->lbo_gpio = devm_gpiod_get_optional(dev, "active-semi,lbo",
"active-semi,chglev-gpios", 0, &flags); GPIOD_IN);
if (IS_ERR(charger->lbo_gpio)) {
err = PTR_ERR(charger->lbo_gpio);
dev_err(dev, "unable to claim gpio \"lbo\": %d\n", err);
return err;
}
if (gpio_is_valid(chglev_pin)) { ret = devm_request_irq(dev, gpiod_to_irq(charger->lbo_gpio),
gpio_set_value(chglev_pin, act8945a_status_changed,
((flags == OF_GPIO_ACTIVE_LOW) ? 0 : 1)); (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING),
"act8945a_lbo_detect", charger);
if (ret)
dev_info(dev, "failed to request gpio \"lbo\" IRQ\n");
charger->chglev_gpio = devm_gpiod_get_optional(dev,
"active-semi,chglev",
GPIOD_IN);
if (IS_ERR(charger->chglev_gpio)) {
err = PTR_ERR(charger->chglev_gpio);
dev_err(dev, "unable to claim gpio \"chglev\": %d\n", err);
return err;
} }
if (of_property_read_u32(np, if (of_property_read_u32(np,
...@@ -314,9 +578,8 @@ static int act8945a_charger_config(struct device *dev, ...@@ -314,9 +578,8 @@ static int act8945a_charger_config(struct device *dev,
static int act8945a_charger_probe(struct platform_device *pdev) static int act8945a_charger_probe(struct platform_device *pdev)
{ {
struct act8945a_charger *charger; struct act8945a_charger *charger;
struct power_supply *psy;
struct power_supply_config psy_cfg = {}; struct power_supply_config psy_cfg = {};
int ret; int irq, ret;
charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
if (!charger) if (!charger)
...@@ -328,21 +591,64 @@ static int act8945a_charger_probe(struct platform_device *pdev) ...@@ -328,21 +591,64 @@ static int act8945a_charger_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
ret = act8945a_charger_config(pdev->dev.parent, charger); ret = act8945a_charger_config(&pdev->dev, charger);
if (ret) if (ret)
return ret; return ret;
psy_cfg.of_node = pdev->dev.parent->of_node; irq = of_irq_get(pdev->dev.of_node, 0);
if (irq == -EPROBE_DEFER) {
dev_err(&pdev->dev, "failed to find IRQ number\n");
return -EPROBE_DEFER;
}
ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
IRQF_TRIGGER_FALLING, "act8945a_interrupt",
charger);
if (ret) {
dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
return ret;
}
charger->desc.name = "act8945a-charger";
charger->desc.get_property = act8945a_charger_get_property;
charger->desc.properties = act8945a_charger_props;
charger->desc.num_properties = ARRAY_SIZE(act8945a_charger_props);
ret = act8945a_set_supply_type(charger, &charger->desc.type);
if (ret)
return -EINVAL;
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.drv_data = charger; psy_cfg.drv_data = charger;
psy = devm_power_supply_register(&pdev->dev, charger->psy = devm_power_supply_register(&pdev->dev,
&act8945a_charger_desc, &charger->desc,
&psy_cfg); &psy_cfg);
if (IS_ERR(psy)) { if (IS_ERR(charger->psy)) {
dev_err(&pdev->dev, "failed to register power supply\n"); dev_err(&pdev->dev, "failed to register power supply\n");
return PTR_ERR(psy); return PTR_ERR(charger->psy);
} }
platform_set_drvdata(pdev, charger);
INIT_WORK(&charger->work, act8945a_work);
ret = act8945a_enable_interrupt(charger);
if (ret)
return -EIO;
charger->init_done = true;
return 0;
}
static int act8945a_charger_remove(struct platform_device *pdev)
{
struct act8945a_charger *charger = platform_get_drvdata(pdev);
charger->init_done = false;
cancel_work_sync(&charger->work);
return 0; return 0;
} }
...@@ -351,6 +657,7 @@ static struct platform_driver act8945a_charger_driver = { ...@@ -351,6 +657,7 @@ static struct platform_driver act8945a_charger_driver = {
.name = "act8945a-charger", .name = "act8945a-charger",
}, },
.probe = act8945a_charger_probe, .probe = act8945a_charger_probe,
.remove = act8945a_charger_remove,
}; };
module_platform_driver(act8945a_charger_driver); module_platform_driver(act8945a_charger_driver);
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/usb/otg.h> #include <linux/usb/otg.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/notifier.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/mfd/axp20x.h> #include <linux/mfd/axp20x.h>
#include <linux/extcon.h> #include <linux/extcon.h>
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/mfd/axp20x.h> #include <linux/mfd/axp20x.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
......
...@@ -1068,6 +1068,12 @@ static int bq24257_probe(struct i2c_client *client, ...@@ -1068,6 +1068,12 @@ static int bq24257_probe(struct i2c_client *client,
return ret; return ret;
} }
ret = bq24257_power_supply_init(bq);
if (ret < 0) {
dev_err(dev, "Failed to register power supply\n");
return ret;
}
ret = devm_request_threaded_irq(dev, client->irq, NULL, ret = devm_request_threaded_irq(dev, client->irq, NULL,
bq24257_irq_handler_thread, bq24257_irq_handler_thread,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_FALLING |
...@@ -1078,12 +1084,6 @@ static int bq24257_probe(struct i2c_client *client, ...@@ -1078,12 +1084,6 @@ static int bq24257_probe(struct i2c_client *client,
return ret; return ret;
} }
ret = bq24257_power_supply_init(bq);
if (ret < 0) {
dev_err(dev, "Failed to register power supply\n");
return ret;
}
ret = sysfs_create_group(&bq->charger->dev.kobj, &bq24257_attr_group); ret = sysfs_create_group(&bq->charger->dev.kobj, &bq24257_attr_group);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Can't create sysfs entries\n"); dev_err(dev, "Can't create sysfs entries\n");
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h> #include <linux/gpio/consumer.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -49,6 +49,7 @@ struct bq24735 { ...@@ -49,6 +49,7 @@ struct bq24735 {
struct i2c_client *client; struct i2c_client *client;
struct bq24735_platform *pdata; struct bq24735_platform *pdata;
struct mutex lock; struct mutex lock;
struct gpio_desc *status_gpio;
bool charging; bool charging;
}; };
...@@ -177,12 +178,8 @@ static int bq24735_config_charger(struct bq24735 *charger) ...@@ -177,12 +178,8 @@ static int bq24735_config_charger(struct bq24735 *charger)
static bool bq24735_charger_is_present(struct bq24735 *charger) static bool bq24735_charger_is_present(struct bq24735 *charger)
{ {
struct bq24735_platform *pdata = charger->pdata; if (charger->status_gpio) {
int ret; return !gpiod_get_value_cansleep(charger->status_gpio);
if (pdata->status_gpio_valid) {
ret = gpio_get_value_cansleep(pdata->status_gpio);
return ret ^= pdata->status_gpio_active_low == 0;
} else { } else {
int ac = 0; int ac = 0;
...@@ -201,8 +198,12 @@ static bool bq24735_charger_is_present(struct bq24735 *charger) ...@@ -201,8 +198,12 @@ static bool bq24735_charger_is_present(struct bq24735 *charger)
static int bq24735_charger_is_charging(struct bq24735 *charger) static int bq24735_charger_is_charging(struct bq24735 *charger)
{ {
int ret = bq24735_read_word(charger->client, BQ24735_CHG_OPT); int ret;
if (!bq24735_charger_is_present(charger))
return 0;
ret = bq24735_read_word(charger->client, BQ24735_CHG_OPT);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -304,7 +305,6 @@ static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client) ...@@ -304,7 +305,6 @@ static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
struct device_node *np = client->dev.of_node; struct device_node *np = client->dev.of_node;
u32 val; u32 val;
int ret; int ret;
enum of_gpio_flags flags;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) { if (!pdata) {
...@@ -313,12 +313,6 @@ static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client) ...@@ -313,12 +313,6 @@ static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
return NULL; return NULL;
} }
pdata->status_gpio = of_get_named_gpio_flags(np, "ti,ac-detect-gpios",
0, &flags);
if (flags & OF_GPIO_ACTIVE_LOW)
pdata->status_gpio_active_low = 1;
ret = of_property_read_u32(np, "ti,charge-current", &val); ret = of_property_read_u32(np, "ti,charge-current", &val);
if (!ret) if (!ret)
pdata->charge_current = val; pdata->charge_current = val;
...@@ -392,21 +386,16 @@ static int bq24735_charger_probe(struct i2c_client *client, ...@@ -392,21 +386,16 @@ static int bq24735_charger_probe(struct i2c_client *client,
i2c_set_clientdata(client, charger); i2c_set_clientdata(client, charger);
if (gpio_is_valid(charger->pdata->status_gpio)) { charger->status_gpio = devm_gpiod_get_optional(&client->dev,
ret = devm_gpio_request(&client->dev, "ti,ac-detect",
charger->pdata->status_gpio, GPIOD_IN);
name); if (IS_ERR(charger->status_gpio)) {
if (ret) { ret = PTR_ERR(charger->status_gpio);
dev_err(&client->dev, dev_err(&client->dev, "Getting gpio failed: %d\n", ret);
"Failed GPIO request for GPIO %d: %d\n", return ret;
charger->pdata->status_gpio, ret);
}
charger->pdata->status_gpio_valid = !ret;
} }
if (!charger->pdata->status_gpio_valid if (!charger->status_gpio || bq24735_charger_is_present(charger)) {
|| bq24735_charger_is_present(charger)) {
ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID); ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "Failed to read manufacturer id : %d\n", dev_err(&client->dev, "Failed to read manufacturer id : %d\n",
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h>
#include <linux/param.h> #include <linux/param.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -390,8 +391,35 @@ static struct { ...@@ -390,8 +391,35 @@ static struct {
BQ27XXX_PROP(BQ27421, bq27421_battery_props), BQ27XXX_PROP(BQ27421, bq27421_battery_props),
}; };
static DEFINE_MUTEX(bq27xxx_list_lock);
static LIST_HEAD(bq27xxx_battery_devices);
static int poll_interval_param_set(const char *val, const struct kernel_param *kp)
{
struct bq27xxx_device_info *di;
int ret;
ret = param_set_uint(val, kp);
if (ret < 0)
return ret;
mutex_lock(&bq27xxx_list_lock);
list_for_each_entry(di, &bq27xxx_battery_devices, list) {
cancel_delayed_work_sync(&di->work);
schedule_delayed_work(&di->work, 0);
}
mutex_unlock(&bq27xxx_list_lock);
return ret;
}
static const struct kernel_param_ops param_ops_poll_interval = {
.get = param_get_uint,
.set = poll_interval_param_set,
};
static unsigned int poll_interval = 360; static unsigned int poll_interval = 360;
module_param(poll_interval, uint, 0644); module_param_cb(poll_interval, &param_ops_poll_interval, &poll_interval, 0644);
MODULE_PARM_DESC(poll_interval, MODULE_PARM_DESC(poll_interval,
"battery poll interval in seconds - 0 disables polling"); "battery poll interval in seconds - 0 disables polling");
...@@ -644,8 +672,9 @@ static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags) ...@@ -644,8 +672,9 @@ static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di) static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
{ {
int flags; int flags;
bool has_singe_flag = di->chip == BQ27000 || di->chip == BQ27010;
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false); flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
if (flags < 0) { if (flags < 0) {
dev_err(di->dev, "error reading flag register:%d\n", flags); dev_err(di->dev, "error reading flag register:%d\n", flags);
return flags; return flags;
...@@ -745,7 +774,7 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di, ...@@ -745,7 +774,7 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
} }
if (di->chip == BQ27000 || di->chip == BQ27010) { if (di->chip == BQ27000 || di->chip == BQ27010) {
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false); flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
if (flags & BQ27000_FLAG_CHGS) { if (flags & BQ27000_FLAG_CHGS) {
dev_dbg(di->dev, "negative current!\n"); dev_dbg(di->dev, "negative current!\n");
curr = -curr; curr = -curr;
...@@ -971,6 +1000,10 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di) ...@@ -971,6 +1000,10 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
bq27xxx_battery_update(di); bq27xxx_battery_update(di);
mutex_lock(&bq27xxx_list_lock);
list_add(&di->list, &bq27xxx_battery_devices);
mutex_unlock(&bq27xxx_list_lock);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(bq27xxx_battery_setup); EXPORT_SYMBOL_GPL(bq27xxx_battery_setup);
...@@ -989,6 +1022,10 @@ void bq27xxx_battery_teardown(struct bq27xxx_device_info *di) ...@@ -989,6 +1022,10 @@ void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
power_supply_unregister(di->bat); power_supply_unregister(di->bat);
mutex_lock(&bq27xxx_list_lock);
list_del(&di->list);
mutex_unlock(&bq27xxx_list_lock);
mutex_destroy(&di->lock); mutex_destroy(&di->lock);
} }
EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown); EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include "../w1/w1.h" #include "../../w1/w1.h"
#include "../w1/slaves/w1_ds2760.h" #include "../../w1/slaves/w1_ds2760.h"
struct ds2760_device_info { struct ds2760_device_info {
struct device *dev; struct device *dev;
...@@ -566,7 +566,8 @@ static int ds2760_battery_probe(struct platform_device *pdev) ...@@ -566,7 +566,8 @@ static int ds2760_battery_probe(struct platform_device *pdev)
INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work);
INIT_DELAYED_WORK(&di->set_charged_work, INIT_DELAYED_WORK(&di->set_charged_work,
ds2760_battery_set_charged_work); ds2760_battery_set_charged_work);
di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); di->monitor_wqueue = alloc_ordered_workqueue(dev_name(&pdev->dev),
WQ_MEM_RECLAIM);
if (!di->monitor_wqueue) { if (!di->monitor_wqueue) {
retval = -ESRCH; retval = -ESRCH;
goto workqueue_failed; goto workqueue_failed;
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/idr.h> #include <linux/idr.h>
#include "../w1/w1.h" #include "../../w1/w1.h"
#include "../w1/slaves/w1_ds2780.h" #include "../../w1/slaves/w1_ds2780.h"
/* Current unit measurement in uA for a 1 milli-ohm sense resistor */ /* Current unit measurement in uA for a 1 milli-ohm sense resistor */
#define DS2780_CURRENT_UNITS 1563 #define DS2780_CURRENT_UNITS 1563
......
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/idr.h> #include <linux/idr.h>
#include "../w1/w1.h" #include "../../w1/w1.h"
#include "../w1/slaves/w1_ds2781.h" #include "../../w1/slaves/w1_ds2781.h"
/* Current unit measurement in uA for a 1 milli-ohm sense resistor */ /* Current unit measurement in uA for a 1 milli-ohm sense resistor */
#define DS2781_CURRENT_UNITS 1563 #define DS2781_CURRENT_UNITS 1563
......
...@@ -689,8 +689,7 @@ static int probe(int irq, struct device *dev) ...@@ -689,8 +689,7 @@ static int probe(int irq, struct device *dev)
/* initialize all required framework before enabling interrupts */ /* initialize all required framework before enabling interrupts */
INIT_WORK(&pbi->handler, pmic_battery_handle_intrpt); INIT_WORK(&pbi->handler, pmic_battery_handle_intrpt);
INIT_DELAYED_WORK(&pbi->monitor_battery, pmic_battery_monitor); INIT_DELAYED_WORK(&pbi->monitor_battery, pmic_battery_monitor);
pbi->monitor_wqueue = pbi->monitor_wqueue = alloc_workqueue(dev_name(dev), WQ_MEM_RECLAIM, 0);
create_singlethread_workqueue(dev_name(dev));
if (!pbi->monitor_wqueue) { if (!pbi->monitor_wqueue) {
dev_err(dev, "%s(): wqueue init failed\n", __func__); dev_err(dev, "%s(): wqueue init failed\n", __func__);
retval = -ESRCH; retval = -ESRCH;
......
...@@ -235,7 +235,7 @@ static int micro_batt_probe(struct platform_device *pdev) ...@@ -235,7 +235,7 @@ static int micro_batt_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
mb->micro = dev_get_drvdata(pdev->dev.parent); mb->micro = dev_get_drvdata(pdev->dev.parent);
mb->wq = create_singlethread_workqueue("ipaq-battery-wq"); mb->wq = alloc_workqueue("ipaq-battery-wq", WQ_MEM_RECLAIM, 0);
if (!mb->wq) if (!mb->wq)
return -ENOMEM; return -ENOMEM;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* max14577_charger.c - Battery charger driver for the Maxim 14577/77836 * max14577_charger.c - Battery charger driver for the Maxim 14577/77836
* *
* Copyright (C) 2013,2014 Samsung Electronics * Copyright (C) 2013,2014 Samsung Electronics
* Krzysztof Kozlowski <k.kozlowski@samsung.com> * Krzysztof Kozlowski <krzk@kernel.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -643,6 +643,6 @@ static struct platform_driver max14577_charger_driver = { ...@@ -643,6 +643,6 @@ static struct platform_driver max14577_charger_driver = {
}; };
module_platform_driver(max14577_charger_driver); module_platform_driver(max14577_charger_driver);
MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski@samsung.com>"); MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
MODULE_DESCRIPTION("Maxim 14577/77836 charger driver"); MODULE_DESCRIPTION("Maxim 14577/77836 charger driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* max77693_charger.c - Battery charger driver for the Maxim 77693 * max77693_charger.c - Battery charger driver for the Maxim 77693
* *
* Copyright (C) 2014 Samsung Electronics * Copyright (C) 2014 Samsung Electronics
* Krzysztof Kozlowski <k.kozlowski@samsung.com> * Krzysztof Kozlowski <krzk@kernel.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -766,6 +766,6 @@ static struct platform_driver max77693_charger_driver = { ...@@ -766,6 +766,6 @@ static struct platform_driver max77693_charger_driver = {
}; };
module_platform_driver(max77693_charger_driver); module_platform_driver(max77693_charger_driver);
MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski@samsung.com>"); MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
MODULE_DESCRIPTION("Maxim 77693 charger driver"); MODULE_DESCRIPTION("Maxim 77693 charger driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -1054,7 +1054,8 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, ...@@ -1054,7 +1054,8 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
pm2->ac_chg.external = true; pm2->ac_chg.external = true;
/* Create a work queue for the charger */ /* Create a work queue for the charger */
pm2->charger_wq = create_singlethread_workqueue("pm2xxx_charger_wq"); pm2->charger_wq = alloc_ordered_workqueue("pm2xxx_charger_wq",
WQ_MEM_RECLAIM);
if (pm2->charger_wq == NULL) { if (pm2->charger_wq == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
dev_err(pm2->dev, "failed to create work queue\n"); dev_err(pm2->dev, "failed to create work queue\n");
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/stat.h> #include <linux/stat.h>
...@@ -41,6 +41,7 @@ enum { ...@@ -41,6 +41,7 @@ enum {
REG_TIME_TO_EMPTY, REG_TIME_TO_EMPTY,
REG_TIME_TO_FULL, REG_TIME_TO_FULL,
REG_STATUS, REG_STATUS,
REG_CAPACITY_LEVEL,
REG_CYCLE_COUNT, REG_CYCLE_COUNT,
REG_SERIAL_NUMBER, REG_SERIAL_NUMBER,
REG_REMAINING_CAPACITY, REG_REMAINING_CAPACITY,
...@@ -68,6 +69,7 @@ enum sbs_battery_mode { ...@@ -68,6 +69,7 @@ enum sbs_battery_mode {
#define MANUFACTURER_ACCESS_SLEEP 0x0011 #define MANUFACTURER_ACCESS_SLEEP 0x0011
/* battery status value bits */ /* battery status value bits */
#define BATTERY_INITIALIZED 0x80
#define BATTERY_DISCHARGING 0x40 #define BATTERY_DISCHARGING 0x40
#define BATTERY_FULL_CHARGED 0x20 #define BATTERY_FULL_CHARGED 0x20
#define BATTERY_FULL_DISCHARGED 0x10 #define BATTERY_FULL_DISCHARGED 0x10
...@@ -110,6 +112,8 @@ static const struct chip_data { ...@@ -110,6 +112,8 @@ static const struct chip_data {
SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0, 65535), SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0, 65535),
[REG_STATUS] = [REG_STATUS] =
SBS_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535), SBS_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535),
[REG_CAPACITY_LEVEL] =
SBS_DATA(POWER_SUPPLY_PROP_CAPACITY_LEVEL, 0x16, 0, 65535),
[REG_CYCLE_COUNT] = [REG_CYCLE_COUNT] =
SBS_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535), SBS_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535),
[REG_DESIGN_CAPACITY] = [REG_DESIGN_CAPACITY] =
...@@ -131,6 +135,7 @@ static const struct chip_data { ...@@ -131,6 +135,7 @@ static const struct chip_data {
static enum power_supply_property sbs_properties[] = { static enum power_supply_property sbs_properties[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_TECHNOLOGY,
...@@ -158,13 +163,13 @@ static enum power_supply_property sbs_properties[] = { ...@@ -158,13 +163,13 @@ static enum power_supply_property sbs_properties[] = {
struct sbs_info { struct sbs_info {
struct i2c_client *client; struct i2c_client *client;
struct power_supply *power_supply; struct power_supply *power_supply;
struct sbs_platform_data *pdata;
bool is_present; bool is_present;
bool gpio_detect; struct gpio_desc *gpio_detect;
bool enable_detection; bool enable_detection;
int irq;
int last_state; int last_state;
int poll_time; int poll_time;
u32 i2c_retry_count;
u32 poll_retry_count;
struct delayed_work work; struct delayed_work work;
int ignore_changes; int ignore_changes;
}; };
...@@ -179,8 +184,7 @@ static int sbs_read_word_data(struct i2c_client *client, u8 address) ...@@ -179,8 +184,7 @@ static int sbs_read_word_data(struct i2c_client *client, u8 address)
s32 ret = 0; s32 ret = 0;
int retries = 1; int retries = 1;
if (chip->pdata) retries = chip->i2c_retry_count;
retries = max(chip->pdata->i2c_retry_count + 1, 1);
while (retries > 0) { while (retries > 0) {
ret = i2c_smbus_read_word_data(client, address); ret = i2c_smbus_read_word_data(client, address);
...@@ -207,10 +211,8 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address, ...@@ -207,10 +211,8 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
int retries_length = 1, retries_block = 1; int retries_length = 1, retries_block = 1;
u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
if (chip->pdata) { retries_length = chip->i2c_retry_count;
retries_length = max(chip->pdata->i2c_retry_count + 1, 1); retries_block = chip->i2c_retry_count;
retries_block = max(chip->pdata->i2c_retry_count + 1, 1);
}
/* Adapter needs to support these two functions */ /* Adapter needs to support these two functions */
if (!i2c_check_functionality(client->adapter, if (!i2c_check_functionality(client->adapter,
...@@ -274,8 +276,7 @@ static int sbs_write_word_data(struct i2c_client *client, u8 address, ...@@ -274,8 +276,7 @@ static int sbs_write_word_data(struct i2c_client *client, u8 address,
s32 ret = 0; s32 ret = 0;
int retries = 1; int retries = 1;
if (chip->pdata) retries = chip->i2c_retry_count;
retries = max(chip->pdata->i2c_retry_count + 1, 1);
while (retries > 0) { while (retries > 0) {
ret = i2c_smbus_write_word_data(client, address, ret = i2c_smbus_write_word_data(client, address,
...@@ -302,32 +303,31 @@ static int sbs_get_battery_presence_and_health( ...@@ -302,32 +303,31 @@ static int sbs_get_battery_presence_and_health(
s32 ret; s32 ret;
struct sbs_info *chip = i2c_get_clientdata(client); struct sbs_info *chip = i2c_get_clientdata(client);
if (psp == POWER_SUPPLY_PROP_PRESENT && if (psp == POWER_SUPPLY_PROP_PRESENT && chip->gpio_detect) {
chip->gpio_detect) { ret = gpiod_get_value_cansleep(chip->gpio_detect);
ret = gpio_get_value(chip->pdata->battery_detect); if (ret < 0)
if (ret == chip->pdata->battery_detect_present) return ret;
val->intval = 1; val->intval = ret;
else
val->intval = 0;
chip->is_present = val->intval; chip->is_present = val->intval;
return ret; return ret;
} }
/* Write to ManufacturerAccess with /*
* ManufacturerAccess command and then * Write to ManufacturerAccess with ManufacturerAccess command
* read the status */ * and then read the status. Do not check for error on the write
ret = sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr, * since not all batteries implement write access to this command,
* while others mandate it.
*/
sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
MANUFACTURER_ACCESS_STATUS); MANUFACTURER_ACCESS_STATUS);
ret = sbs_read_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr);
if (ret < 0) { if (ret < 0) {
if (psp == POWER_SUPPLY_PROP_PRESENT) if (psp == POWER_SUPPLY_PROP_PRESENT)
val->intval = 0; /* battery removed */ val->intval = 0; /* battery removed */
return ret; return ret;
} }
ret = sbs_read_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr);
if (ret < 0)
return ret;
if (ret < sbs_data[REG_MANUFACTURER_DATA].min_value || if (ret < sbs_data[REG_MANUFACTURER_DATA].min_value ||
ret > sbs_data[REG_MANUFACTURER_DATA].max_value) { ret > sbs_data[REG_MANUFACTURER_DATA].max_value) {
val->intval = 0; val->intval = 0;
...@@ -377,8 +377,23 @@ static int sbs_get_battery_property(struct i2c_client *client, ...@@ -377,8 +377,23 @@ static int sbs_get_battery_property(struct i2c_client *client,
if (ret >= sbs_data[reg_offset].min_value && if (ret >= sbs_data[reg_offset].min_value &&
ret <= sbs_data[reg_offset].max_value) { ret <= sbs_data[reg_offset].max_value) {
val->intval = ret; val->intval = ret;
if (psp != POWER_SUPPLY_PROP_STATUS) if (psp == POWER_SUPPLY_PROP_CAPACITY_LEVEL) {
if (!(ret & BATTERY_INITIALIZED))
val->intval =
POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
else if (ret & BATTERY_FULL_CHARGED)
val->intval =
POWER_SUPPLY_CAPACITY_LEVEL_FULL;
else if (ret & BATTERY_FULL_DISCHARGED)
val->intval =
POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
else
val->intval =
POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
return 0;
} else if (psp != POWER_SUPPLY_PROP_STATUS) {
return 0; return 0;
}
if (ret & BATTERY_FULL_CHARGED) if (ret & BATTERY_FULL_CHARGED)
val->intval = POWER_SUPPLY_STATUS_FULL; val->intval = POWER_SUPPLY_STATUS_FULL;
...@@ -590,6 +605,7 @@ static int sbs_get_property(struct power_supply *psy, ...@@ -590,6 +605,7 @@ static int sbs_get_property(struct power_supply *psy,
break; break;
case POWER_SUPPLY_PROP_STATUS: case POWER_SUPPLY_PROP_STATUS:
case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
case POWER_SUPPLY_PROP_CYCLE_COUNT: case POWER_SUPPLY_PROP_CYCLE_COUNT:
case POWER_SUPPLY_PROP_VOLTAGE_NOW: case POWER_SUPPLY_PROP_VOLTAGE_NOW:
case POWER_SUPPLY_PROP_CURRENT_NOW: case POWER_SUPPLY_PROP_CURRENT_NOW:
...@@ -661,8 +677,14 @@ static int sbs_get_property(struct power_supply *psy, ...@@ -661,8 +677,14 @@ static int sbs_get_property(struct power_supply *psy,
static irqreturn_t sbs_irq(int irq, void *devid) static irqreturn_t sbs_irq(int irq, void *devid)
{ {
struct power_supply *battery = devid; struct sbs_info *chip = devid;
struct power_supply *battery = chip->power_supply;
int ret;
ret = gpiod_get_value_cansleep(chip->gpio_detect);
if (ret < 0)
return ret;
chip->is_present = ret;
power_supply_changed(battery); power_supply_changed(battery);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -681,7 +703,7 @@ static void sbs_external_power_changed(struct power_supply *psy) ...@@ -681,7 +703,7 @@ static void sbs_external_power_changed(struct power_supply *psy)
cancel_delayed_work_sync(&chip->work); cancel_delayed_work_sync(&chip->work);
schedule_delayed_work(&chip->work, HZ); schedule_delayed_work(&chip->work, HZ);
chip->poll_time = chip->pdata->poll_retry_count; chip->poll_time = chip->poll_retry_count;
} }
static void sbs_delayed_work(struct work_struct *work) static void sbs_delayed_work(struct work_struct *work)
...@@ -717,80 +739,6 @@ static void sbs_delayed_work(struct work_struct *work) ...@@ -717,80 +739,6 @@ static void sbs_delayed_work(struct work_struct *work)
} }
} }
#if defined(CONFIG_OF)
#include <linux/of_device.h>
#include <linux/of_gpio.h>
static const struct of_device_id sbs_dt_ids[] = {
{ .compatible = "sbs,sbs-battery" },
{ .compatible = "ti,bq20z75" },
{ }
};
MODULE_DEVICE_TABLE(of, sbs_dt_ids);
static struct sbs_platform_data *sbs_of_populate_pdata(
struct i2c_client *client)
{
struct device_node *of_node = client->dev.of_node;
struct sbs_platform_data *pdata = client->dev.platform_data;
enum of_gpio_flags gpio_flags;
int rc;
u32 prop;
/* verify this driver matches this device */
if (!of_node)
return NULL;
/* if platform data is set, honor it */
if (pdata)
return pdata;
/* first make sure at least one property is set, otherwise
* it won't change behavior from running without pdata.
*/
if (!of_get_property(of_node, "sbs,i2c-retry-count", NULL) &&
!of_get_property(of_node, "sbs,poll-retry-count", NULL) &&
!of_get_property(of_node, "sbs,battery-detect-gpios", NULL))
goto of_out;
pdata = devm_kzalloc(&client->dev, sizeof(struct sbs_platform_data),
GFP_KERNEL);
if (!pdata)
goto of_out;
rc = of_property_read_u32(of_node, "sbs,i2c-retry-count", &prop);
if (!rc)
pdata->i2c_retry_count = prop;
rc = of_property_read_u32(of_node, "sbs,poll-retry-count", &prop);
if (!rc)
pdata->poll_retry_count = prop;
if (!of_get_property(of_node, "sbs,battery-detect-gpios", NULL)) {
pdata->battery_detect = -1;
goto of_out;
}
pdata->battery_detect = of_get_named_gpio_flags(of_node,
"sbs,battery-detect-gpios", 0, &gpio_flags);
if (gpio_flags & OF_GPIO_ACTIVE_LOW)
pdata->battery_detect_present = 0;
else
pdata->battery_detect_present = 1;
of_out:
return pdata;
}
#else
static struct sbs_platform_data *sbs_of_populate_pdata(
struct i2c_client *client)
{
return client->dev.platform_data;
}
#endif
static const struct power_supply_desc sbs_default_desc = { static const struct power_supply_desc sbs_default_desc = {
.type = POWER_SUPPLY_TYPE_BATTERY, .type = POWER_SUPPLY_TYPE_BATTERY,
.properties = sbs_properties, .properties = sbs_properties,
...@@ -819,13 +767,12 @@ static int sbs_probe(struct i2c_client *client, ...@@ -819,13 +767,12 @@ static int sbs_probe(struct i2c_client *client,
if (!sbs_desc->name) if (!sbs_desc->name)
return -ENOMEM; return -ENOMEM;
chip = kzalloc(sizeof(struct sbs_info), GFP_KERNEL); chip = devm_kzalloc(&client->dev, sizeof(struct sbs_info), GFP_KERNEL);
if (!chip) if (!chip)
return -ENOMEM; return -ENOMEM;
chip->client = client; chip->client = client;
chip->enable_detection = false; chip->enable_detection = false;
chip->gpio_detect = false;
psy_cfg.of_node = client->dev.of_node; psy_cfg.of_node = client->dev.of_node;
psy_cfg.drv_data = chip; psy_cfg.drv_data = chip;
/* ignore first notification of external change, it is generated /* ignore first notification of external change, it is generated
...@@ -834,11 +781,31 @@ static int sbs_probe(struct i2c_client *client, ...@@ -834,11 +781,31 @@ static int sbs_probe(struct i2c_client *client,
chip->ignore_changes = 1; chip->ignore_changes = 1;
chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN; chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
pdata = sbs_of_populate_pdata(client); /* use pdata if available, fall back to DT properties,
* or hardcoded defaults if not
*/
rc = of_property_read_u32(client->dev.of_node, "sbs,i2c-retry-count",
&chip->i2c_retry_count);
if (rc)
chip->i2c_retry_count = 0;
rc = of_property_read_u32(client->dev.of_node, "sbs,poll-retry-count",
&chip->poll_retry_count);
if (rc)
chip->poll_retry_count = 0;
if (pdata) { if (pdata) {
chip->gpio_detect = gpio_is_valid(pdata->battery_detect); chip->poll_retry_count = pdata->poll_retry_count;
chip->pdata = pdata; chip->i2c_retry_count = pdata->i2c_retry_count;
}
chip->i2c_retry_count = chip->i2c_retry_count + 1;
chip->gpio_detect = devm_gpiod_get_optional(&client->dev,
"sbs,battery-detect", GPIOD_IN);
if (IS_ERR(chip->gpio_detect)) {
dev_err(&client->dev, "Failed to get gpio: %ld\n",
PTR_ERR(chip->gpio_detect));
return PTR_ERR(chip->gpio_detect);
} }
i2c_set_clientdata(client, chip); i2c_set_clientdata(client, chip);
...@@ -846,47 +813,26 @@ static int sbs_probe(struct i2c_client *client, ...@@ -846,47 +813,26 @@ static int sbs_probe(struct i2c_client *client,
if (!chip->gpio_detect) if (!chip->gpio_detect)
goto skip_gpio; goto skip_gpio;
rc = gpio_request(pdata->battery_detect, dev_name(&client->dev)); irq = gpiod_to_irq(chip->gpio_detect);
if (rc) {
dev_warn(&client->dev, "Failed to request gpio: %d\n", rc);
chip->gpio_detect = false;
goto skip_gpio;
}
rc = gpio_direction_input(pdata->battery_detect);
if (rc) {
dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc);
gpio_free(pdata->battery_detect);
chip->gpio_detect = false;
goto skip_gpio;
}
irq = gpio_to_irq(pdata->battery_detect);
if (irq <= 0) { if (irq <= 0) {
dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq); dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
gpio_free(pdata->battery_detect);
chip->gpio_detect = false;
goto skip_gpio; goto skip_gpio;
} }
rc = request_irq(irq, sbs_irq, rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
dev_name(&client->dev), chip->power_supply); dev_name(&client->dev), chip);
if (rc) { if (rc) {
dev_warn(&client->dev, "Failed to request irq: %d\n", rc); dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
gpio_free(pdata->battery_detect);
chip->gpio_detect = false;
goto skip_gpio; goto skip_gpio;
} }
chip->irq = irq;
skip_gpio: skip_gpio:
/* /*
* Before we register, we might need to make sure we can actually talk * Before we register, we might need to make sure we can actually talk
* to the battery. * to the battery.
*/ */
if (!force_load) { if (!(force_load || chip->gpio_detect)) {
rc = sbs_read_word_data(client, sbs_data[REG_STATUS].addr); rc = sbs_read_word_data(client, sbs_data[REG_STATUS].addr);
if (rc < 0) { if (rc < 0) {
...@@ -896,7 +842,7 @@ static int sbs_probe(struct i2c_client *client, ...@@ -896,7 +842,7 @@ static int sbs_probe(struct i2c_client *client,
} }
} }
chip->power_supply = power_supply_register(&client->dev, sbs_desc, chip->power_supply = devm_power_supply_register(&client->dev, sbs_desc,
&psy_cfg); &psy_cfg);
if (IS_ERR(chip->power_supply)) { if (IS_ERR(chip->power_supply)) {
dev_err(&client->dev, dev_err(&client->dev,
...@@ -915,13 +861,6 @@ static int sbs_probe(struct i2c_client *client, ...@@ -915,13 +861,6 @@ static int sbs_probe(struct i2c_client *client,
return 0; return 0;
exit_psupply: exit_psupply:
if (chip->irq)
free_irq(chip->irq, chip->power_supply);
if (chip->gpio_detect)
gpio_free(pdata->battery_detect);
kfree(chip);
return rc; return rc;
} }
...@@ -929,18 +868,8 @@ static int sbs_remove(struct i2c_client *client) ...@@ -929,18 +868,8 @@ static int sbs_remove(struct i2c_client *client)
{ {
struct sbs_info *chip = i2c_get_clientdata(client); struct sbs_info *chip = i2c_get_clientdata(client);
if (chip->irq)
free_irq(chip->irq, chip->power_supply);
if (chip->gpio_detect)
gpio_free(chip->pdata->battery_detect);
power_supply_unregister(chip->power_supply);
cancel_delayed_work_sync(&chip->work); cancel_delayed_work_sync(&chip->work);
kfree(chip);
chip = NULL;
return 0; return 0;
} }
...@@ -950,16 +879,16 @@ static int sbs_suspend(struct device *dev) ...@@ -950,16 +879,16 @@ static int sbs_suspend(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct sbs_info *chip = i2c_get_clientdata(client); struct sbs_info *chip = i2c_get_clientdata(client);
s32 ret;
if (chip->poll_time > 0) if (chip->poll_time > 0)
cancel_delayed_work_sync(&chip->work); cancel_delayed_work_sync(&chip->work);
/* write to manufacturer access with sleep command */ /*
ret = sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr, * Write to manufacturer access with sleep command.
* Support is manufacturer dependend, so ignore errors.
*/
sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
MANUFACTURER_ACCESS_SLEEP); MANUFACTURER_ACCESS_SLEEP);
if (chip->is_present && ret < 0)
return ret;
return 0; return 0;
} }
...@@ -978,13 +907,20 @@ static const struct i2c_device_id sbs_id[] = { ...@@ -978,13 +907,20 @@ static const struct i2c_device_id sbs_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, sbs_id); MODULE_DEVICE_TABLE(i2c, sbs_id);
static const struct of_device_id sbs_dt_ids[] = {
{ .compatible = "sbs,sbs-battery" },
{ .compatible = "ti,bq20z75" },
{ }
};
MODULE_DEVICE_TABLE(of, sbs_dt_ids);
static struct i2c_driver sbs_battery_driver = { static struct i2c_driver sbs_battery_driver = {
.probe = sbs_probe, .probe = sbs_probe,
.remove = sbs_remove, .remove = sbs_remove,
.id_table = sbs_id, .id_table = sbs_id,
.driver = { .driver = {
.name = "sbs-battery", .name = "sbs-battery",
.of_match_table = of_match_ptr(sbs_dt_ids), .of_match_table = sbs_dt_ids,
.pm = SBS_PM_OPS, .pm = SBS_PM_OPS,
}, },
}; };
......
...@@ -46,6 +46,8 @@ struct tps65217_charger { ...@@ -46,6 +46,8 @@ struct tps65217_charger {
int prev_ac_online; int prev_ac_online;
struct task_struct *poll_task; struct task_struct *poll_task;
int irq;
}; };
static enum power_supply_property tps65217_ac_props[] = { static enum power_supply_property tps65217_ac_props[] = {
...@@ -198,6 +200,7 @@ static int tps65217_charger_probe(struct platform_device *pdev) ...@@ -198,6 +200,7 @@ static int tps65217_charger_probe(struct platform_device *pdev)
struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
struct tps65217_charger *charger; struct tps65217_charger *charger;
struct power_supply_config cfg = {}; struct power_supply_config cfg = {};
int irq;
int ret; int ret;
dev_dbg(&pdev->dev, "%s\n", __func__); dev_dbg(&pdev->dev, "%s\n", __func__);
...@@ -221,19 +224,41 @@ static int tps65217_charger_probe(struct platform_device *pdev) ...@@ -221,19 +224,41 @@ static int tps65217_charger_probe(struct platform_device *pdev)
return PTR_ERR(charger->ac); return PTR_ERR(charger->ac);
} }
irq = platform_get_irq_byname(pdev, "AC");
if (irq < 0)
irq = -ENXIO;
charger->irq = irq;
ret = tps65217_config_charger(charger); ret = tps65217_config_charger(charger);
if (ret < 0) { if (ret < 0) {
dev_err(charger->dev, "charger config failed, err %d\n", ret); dev_err(charger->dev, "charger config failed, err %d\n", ret);
return ret; return ret;
} }
if (irq != -ENXIO) {
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
tps65217_charger_irq,
0, "tps65217-charger",
charger);
if (ret) {
dev_err(charger->dev,
"Unable to register irq %d err %d\n", irq,
ret);
return ret;
}
/* Check current state */
tps65217_charger_irq(irq, charger);
} else {
charger->poll_task = kthread_run(tps65217_charger_poll_task, charger->poll_task = kthread_run(tps65217_charger_poll_task,
charger, "ktps65217charger"); charger, "ktps65217charger");
if (IS_ERR(charger->poll_task)) { if (IS_ERR(charger->poll_task)) {
ret = PTR_ERR(charger->poll_task); ret = PTR_ERR(charger->poll_task);
dev_err(charger->dev, "Unable to run kthread err %d\n", ret); dev_err(charger->dev,
"Unable to run kthread err %d\n", ret);
return ret; return ret;
} }
}
return 0; return 0;
} }
...@@ -242,6 +267,7 @@ static int tps65217_charger_remove(struct platform_device *pdev) ...@@ -242,6 +267,7 @@ static int tps65217_charger_remove(struct platform_device *pdev)
{ {
struct tps65217_charger *charger = platform_get_drvdata(pdev); struct tps65217_charger *charger = platform_get_drvdata(pdev);
if (charger->irq == -ENXIO)
kthread_stop(charger->poll_task); kthread_stop(charger->poll_task);
return 0; return 0;
......
/* /*
* linux/drivers/power/wm97xx_battery.c
*
* Battery measurement code for WM97xx * Battery measurement code for WM97xx
* *
* based on tosa_battery.c * based on tosa_battery.c
......
...@@ -317,7 +317,6 @@ MODULE_DEVICE_TABLE(i2c, z2_batt_id); ...@@ -317,7 +317,6 @@ MODULE_DEVICE_TABLE(i2c, z2_batt_id);
static struct i2c_driver z2_batt_driver = { static struct i2c_driver z2_batt_driver = {
.driver = { .driver = {
.name = "z2-battery", .name = "z2-battery",
.owner = THIS_MODULE,
.pm = Z2_BATTERY_PM_OPS .pm = Z2_BATTERY_PM_OPS
}, },
.probe = z2_batt_probe, .probe = z2_batt_probe,
......
...@@ -28,10 +28,6 @@ struct bq24735_platform { ...@@ -28,10 +28,6 @@ struct bq24735_platform {
const char *name; const char *name;
int status_gpio;
int status_gpio_active_low;
bool status_gpio_valid;
bool ext_control; bool ext_control;
char **supplied_to; char **supplied_to;
......
...@@ -58,6 +58,7 @@ struct bq27xxx_device_info { ...@@ -58,6 +58,7 @@ struct bq27xxx_device_info {
unsigned long last_update; unsigned long last_update;
struct delayed_work work; struct delayed_work work;
struct power_supply *bat; struct power_supply *bat;
struct list_head list;
struct mutex lock; struct mutex lock;
u8 *regs; u8 *regs;
}; };
......
...@@ -26,17 +26,13 @@ ...@@ -26,17 +26,13 @@
/** /**
* struct sbs_platform_data - platform data for sbs devices * struct sbs_platform_data - platform data for sbs devices
* @battery_detect: GPIO which is used to detect battery presence
* @battery_detect_present: gpio state when battery is present (0 / 1)
* @i2c_retry_count: # of times to retry on i2c IO failure * @i2c_retry_count: # of times to retry on i2c IO failure
* @poll_retry_count: # of times to retry looking for new status after * @poll_retry_count: # of times to retry looking for new status after
* external change notification * external change notification
*/ */
struct sbs_platform_data { struct sbs_platform_data {
int battery_detect; u32 i2c_retry_count;
int battery_detect_present; u32 poll_retry_count;
int i2c_retry_count;
int poll_retry_count;
}; };
#endif #endif
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