Commit 5a120391 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull battery updates from Anton Vorontsov:
 "Four new drivers:

   - goldfish_battery:

     This is Android Emulator battery driver.  Originally from Google,
     but Intel folks reshaped it for mainline

   - pm2301_charger:

     A new driver for ST-Ericsson 2301 Power Management chip, uses
     AB8500 battery management core

   - qnap-poweroff:

     The driver adds poweroff functionality for QNAP NAS boxes

   - restart-poweroff:

     A generic driver that implements 'power off by restarting'.  The
     actual poweroff functionality is implemented through a bootloader,
     so Linux' task is just to restart the box.  The driver is useful on
     Buffalo Linkstation LS-XHL and LS-CHLv2 boards.  Andrew Lunn worked
     on submitting the driver (as well as qnap-poweroff above).

  Additionally:

   - A lot of fixes for ab8500 drivers.  This is a part of efforts of
     syncing internal ST-Ericsson development tree with the mainline.
     Lee Jones @ Linaro worked on compilation and reshaping these
     series.

   - New health properties for the power supplies: "Watchdog timer
     expire" and "Safety timer expire"

   - As usual, a bunch of fixes/cleanups here and there"

* tag 'for-v3.9' of git://git.infradead.org/battery-2.6: (81 commits)
  bq2415x_charger: Add support for offline and 100mA mode
  generic-adc-battery: Fix forever loop in gab_remove()
  goldfish_battery: Add missing GENERIC_HARDIRQS dependency
  da9030_battery: Include notifier.h
  bq27x00_battery: Fix reporting battery temperature
  power/reset: Remove newly introduced __dev* annotations
  lp8727_charger: Small cleanup in naming
  ab8500_btemp: Demote initcall sequence
  ds2782_battery: Add power_supply_changed() calls for proper uevent support
  power: Add battery driver for goldfish emulator
  u8500-charger: Delay for USB enumeration
  ab8500-bm: Remove individual [charger|btemp|fg|chargalg] pdata structures
  ab8500-charger: Do not touch VBUSOVV bits
  ab8500-fg: Use correct battery charge full design
  pm2301: LPN mode control support
  pm2301: Enable vbat low monitoring
  ab8500-bm: Flush all work queues before suspending
  ab8500-fg: Go to INIT_RECOVERY when charger removed
  ab8500-charger: Add support for autopower on AB8505 and AB9540
  abx500-chargalg: Add new sysfs interface to get current charge status
  ...

Fix up fairly straightforward conflicts in the ab8500 driver.  But since
it seems to be ARM-specific, I can't even compile-test the result..
parents c560dc87 ac6324e7
* QNAP Power Off
QNAP NAS devices have a microcontroller controlling the main power
supply. This microcontroller is connected to UART1 of the Kirkwood and
Orion5x SoCs. Sending the charactor 'A', at 19200 baud, tells the
microcontroller to turn the power off. This driver adds a handler to
pm_power_off which is called to turn the power off.
Required Properties:
- compatible: Should be "qnap,power-off"
- reg: Address and length of the register set for UART1
- clocks: tclk clock
* Restart Power Off
Buffalo Linkstation LS-XHL and LS-CHLv2, and other devices power off
by restarting and letting u-boot keep hold of the machine until the
user presses a button.
Required Properties:
- compatible: Should be "restart-poweroff"
...@@ -7612,6 +7612,22 @@ F: Documentation/backlight/lp855x-driver.txt ...@@ -7612,6 +7612,22 @@ F: Documentation/backlight/lp855x-driver.txt
F: drivers/video/backlight/lp855x_bl.c F: drivers/video/backlight/lp855x_bl.c
F: include/linux/platform_data/lp855x.h F: include/linux/platform_data/lp855x.h
TI LP8727 CHARGER DRIVER
M: Milo Kim <milo.kim@ti.com>
S: Maintained
F: drivers/power/lp8727_charger.c
F: include/linux/platform_data/lp8727.h
TI LP8788 MFD DRIVER
M: Milo Kim <milo.kim@ti.com>
S: Maintained
F: drivers/iio/adc/lp8788_adc.c
F: drivers/leds/leds-lp8788.c
F: drivers/mfd/lp8788*.c
F: drivers/power/lp8788-charger.c
F: drivers/regulator/lp8788-*.c
F: include/linux/mfd/lp8788*.h
TI TWL4030 SERIES SOC CODEC DRIVER TI TWL4030 SERIES SOC CODEC DRIVER
M: Peter Ujfalusi <peter.ujfalusi@ti.com> M: Peter Ujfalusi <peter.ujfalusi@ti.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: alsa-devel@alsa-project.org (moderated for non-subscribers)
......
...@@ -750,6 +750,12 @@ static struct resource ab8500_charger_resources[] = { ...@@ -750,6 +750,12 @@ static struct resource ab8500_charger_resources[] = {
.end = AB8500_INT_CH_WD_EXP, .end = AB8500_INT_CH_WD_EXP,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
}, },
{
.name = "VBUS_CH_DROP_END",
.start = AB8500_INT_VBUS_CH_DROP_END,
.end = AB8500_INT_VBUS_CH_DROP_END,
.flags = IORESOURCE_IRQ,
},
}; };
static struct resource ab8500_btemp_resources[] = { static struct resource ab8500_btemp_resources[] = {
...@@ -1012,40 +1018,32 @@ static struct mfd_cell ab8500_bm_devs[] = { ...@@ -1012,40 +1018,32 @@ static struct mfd_cell ab8500_bm_devs[] = {
.of_compatible = "stericsson,ab8500-charger", .of_compatible = "stericsson,ab8500-charger",
.num_resources = ARRAY_SIZE(ab8500_charger_resources), .num_resources = ARRAY_SIZE(ab8500_charger_resources),
.resources = ab8500_charger_resources, .resources = ab8500_charger_resources,
#ifndef CONFIG_OF
.platform_data = &ab8500_bm_data, .platform_data = &ab8500_bm_data,
.pdata_size = sizeof(ab8500_bm_data), .pdata_size = sizeof(ab8500_bm_data),
#endif
}, },
{ {
.name = "ab8500-btemp", .name = "ab8500-btemp",
.of_compatible = "stericsson,ab8500-btemp", .of_compatible = "stericsson,ab8500-btemp",
.num_resources = ARRAY_SIZE(ab8500_btemp_resources), .num_resources = ARRAY_SIZE(ab8500_btemp_resources),
.resources = ab8500_btemp_resources, .resources = ab8500_btemp_resources,
#ifndef CONFIG_OF
.platform_data = &ab8500_bm_data, .platform_data = &ab8500_bm_data,
.pdata_size = sizeof(ab8500_bm_data), .pdata_size = sizeof(ab8500_bm_data),
#endif
}, },
{ {
.name = "ab8500-fg", .name = "ab8500-fg",
.of_compatible = "stericsson,ab8500-fg", .of_compatible = "stericsson,ab8500-fg",
.num_resources = ARRAY_SIZE(ab8500_fg_resources), .num_resources = ARRAY_SIZE(ab8500_fg_resources),
.resources = ab8500_fg_resources, .resources = ab8500_fg_resources,
#ifndef CONFIG_OF
.platform_data = &ab8500_bm_data, .platform_data = &ab8500_bm_data,
.pdata_size = sizeof(ab8500_bm_data), .pdata_size = sizeof(ab8500_bm_data),
#endif
}, },
{ {
.name = "ab8500-chargalg", .name = "ab8500-chargalg",
.of_compatible = "stericsson,ab8500-chargalg", .of_compatible = "stericsson,ab8500-chargalg",
.num_resources = ARRAY_SIZE(ab8500_chargalg_resources), .num_resources = ARRAY_SIZE(ab8500_chargalg_resources),
.resources = ab8500_chargalg_resources, .resources = ab8500_chargalg_resources,
#ifndef CONFIG_OF
.platform_data = &ab8500_bm_data, .platform_data = &ab8500_bm_data,
.pdata_size = sizeof(ab8500_bm_data), .pdata_size = sizeof(ab8500_bm_data),
#endif
}, },
}; };
......
...@@ -915,15 +915,13 @@ static int pm860x_battery_probe(struct platform_device *pdev) ...@@ -915,15 +915,13 @@ static int pm860x_battery_probe(struct platform_device *pdev)
info->irq_cc = platform_get_irq(pdev, 0); info->irq_cc = platform_get_irq(pdev, 0);
if (info->irq_cc <= 0) { if (info->irq_cc <= 0) {
dev_err(&pdev->dev, "No IRQ resource!\n"); dev_err(&pdev->dev, "No IRQ resource!\n");
ret = -EINVAL; return -EINVAL;
goto out;
} }
info->irq_batt = platform_get_irq(pdev, 1); info->irq_batt = platform_get_irq(pdev, 1);
if (info->irq_batt <= 0) { if (info->irq_batt <= 0) {
dev_err(&pdev->dev, "No IRQ resource!\n"); dev_err(&pdev->dev, "No IRQ resource!\n");
ret = -EINVAL; return -EINVAL;
goto out;
} }
info->chip = chip; info->chip = chip;
...@@ -957,7 +955,7 @@ static int pm860x_battery_probe(struct platform_device *pdev) ...@@ -957,7 +955,7 @@ static int pm860x_battery_probe(struct platform_device *pdev)
ret = power_supply_register(&pdev->dev, &info->battery); ret = power_supply_register(&pdev->dev, &info->battery);
if (ret) if (ret)
goto out; return ret;
info->battery.dev->parent = &pdev->dev; info->battery.dev->parent = &pdev->dev;
ret = request_threaded_irq(info->irq_cc, NULL, ret = request_threaded_irq(info->irq_cc, NULL,
...@@ -984,8 +982,6 @@ static int pm860x_battery_probe(struct platform_device *pdev) ...@@ -984,8 +982,6 @@ static int pm860x_battery_probe(struct platform_device *pdev)
free_irq(info->irq_cc, info); free_irq(info->irq_cc, info);
out_reg: out_reg:
power_supply_unregister(&info->battery); power_supply_unregister(&info->battery);
out:
kfree(info);
return ret; return ret;
} }
...@@ -993,10 +989,9 @@ static int pm860x_battery_remove(struct platform_device *pdev) ...@@ -993,10 +989,9 @@ static int pm860x_battery_remove(struct platform_device *pdev)
{ {
struct pm860x_battery_info *info = platform_get_drvdata(pdev); struct pm860x_battery_info *info = platform_get_drvdata(pdev);
power_supply_unregister(&info->battery);
free_irq(info->irq_batt, info); free_irq(info->irq_batt, info);
free_irq(info->irq_cc, info); free_irq(info->irq_cc, info);
kfree(info); power_supply_unregister(&info->battery);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
...@@ -346,6 +346,20 @@ config AB8500_BM ...@@ -346,6 +346,20 @@ config AB8500_BM
help help
Say Y to include support for AB8500 battery management. Say Y to include support for AB8500 battery management.
config BATTERY_GOLDFISH
tristate "Goldfish battery driver"
depends on GENERIC_HARDIRQS
help
Say Y to enable support for the battery and AC power in the
Goldfish emulator.
config CHARGER_PM2301
bool "PM2301 Battery Charger Driver"
depends on AB8500_BM
help
Say Y to include support for PM2301 charger driver.
Depends on AB8500 battery management core.
source "drivers/power/reset/Kconfig" source "drivers/power/reset/Kconfig"
endif # POWER_SUPPLY endif # POWER_SUPPLY
......
...@@ -20,6 +20,7 @@ obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o ...@@ -20,6 +20,7 @@ obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o
obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o
obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o
obj-$(CONFIG_BATTERY_GOLDFISH) += goldfish_battery.o
obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
...@@ -38,7 +39,7 @@ obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o ...@@ -38,7 +39,7 @@ obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o
obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
...@@ -46,6 +47,7 @@ obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o ...@@ -46,6 +47,7 @@ obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
obj-$(CONFIG_CHARGER_PM2301) += pm2301_charger.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
......
...@@ -182,7 +182,7 @@ static struct batres_vs_temp temp_to_batres_tbl_9100[] = { ...@@ -182,7 +182,7 @@ static struct batres_vs_temp temp_to_batres_tbl_9100[] = {
}; };
static struct abx500_battery_type bat_type_thermistor[] = { static struct abx500_battery_type bat_type_thermistor[] = {
[BATTERY_UNKNOWN] = { [BATTERY_UNKNOWN] = {
/* First element always represent the UNKNOWN battery */ /* First element always represent the UNKNOWN battery */
.name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
.resis_high = 0, .resis_high = 0,
...@@ -192,7 +192,7 @@ static struct abx500_battery_type bat_type_thermistor[] = { ...@@ -192,7 +192,7 @@ static struct abx500_battery_type bat_type_thermistor[] = {
.nominal_voltage = 3700, .nominal_voltage = 3700,
.termination_vol = 4050, .termination_vol = 4050,
.termination_curr = 200, .termination_curr = 200,
.recharge_vol = 3990, .recharge_cap = 95,
.normal_cur_lvl = 400, .normal_cur_lvl = 400,
.normal_vol_lvl = 4100, .normal_vol_lvl = 4100,
.maint_a_cur_lvl = 400, .maint_a_cur_lvl = 400,
...@@ -209,8 +209,8 @@ static struct abx500_battery_type bat_type_thermistor[] = { ...@@ -209,8 +209,8 @@ static struct abx500_battery_type bat_type_thermistor[] = {
.v_to_cap_tbl = cap_tbl, .v_to_cap_tbl = cap_tbl,
.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
.batres_tbl = temp_to_batres_tbl_thermistor, .batres_tbl = temp_to_batres_tbl_thermistor,
}, },
{ {
.name = POWER_SUPPLY_TECHNOLOGY_LIPO, .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
.resis_high = 53407, .resis_high = 53407,
.resis_low = 12500, .resis_low = 12500,
...@@ -219,7 +219,7 @@ static struct abx500_battery_type bat_type_thermistor[] = { ...@@ -219,7 +219,7 @@ static struct abx500_battery_type bat_type_thermistor[] = {
.nominal_voltage = 3600, .nominal_voltage = 3600,
.termination_vol = 4150, .termination_vol = 4150,
.termination_curr = 80, .termination_curr = 80,
.recharge_vol = 4130, .recharge_cap = 95,
.normal_cur_lvl = 700, .normal_cur_lvl = 700,
.normal_vol_lvl = 4200, .normal_vol_lvl = 4200,
.maint_a_cur_lvl = 600, .maint_a_cur_lvl = 600,
...@@ -237,8 +237,8 @@ static struct abx500_battery_type bat_type_thermistor[] = { ...@@ -237,8 +237,8 @@ static struct abx500_battery_type bat_type_thermistor[] = {
.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
.batres_tbl = temp_to_batres_tbl_thermistor, .batres_tbl = temp_to_batres_tbl_thermistor,
}, },
{ {
.name = POWER_SUPPLY_TECHNOLOGY_LIPO, .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
.resis_high = 200000, .resis_high = 200000,
.resis_low = 82869, .resis_low = 82869,
...@@ -247,7 +247,7 @@ static struct abx500_battery_type bat_type_thermistor[] = { ...@@ -247,7 +247,7 @@ static struct abx500_battery_type bat_type_thermistor[] = {
.nominal_voltage = 3600, .nominal_voltage = 3600,
.termination_vol = 4150, .termination_vol = 4150,
.termination_curr = 80, .termination_curr = 80,
.recharge_vol = 4130, .recharge_cap = 95,
.normal_cur_lvl = 700, .normal_cur_lvl = 700,
.normal_vol_lvl = 4200, .normal_vol_lvl = 4200,
.maint_a_cur_lvl = 600, .maint_a_cur_lvl = 600,
...@@ -264,11 +264,11 @@ static struct abx500_battery_type bat_type_thermistor[] = { ...@@ -264,11 +264,11 @@ static struct abx500_battery_type bat_type_thermistor[] = {
.v_to_cap_tbl = cap_tbl_B_thermistor, .v_to_cap_tbl = cap_tbl_B_thermistor,
.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
.batres_tbl = temp_to_batres_tbl_thermistor, .batres_tbl = temp_to_batres_tbl_thermistor,
}, },
}; };
static struct abx500_battery_type bat_type_ext_thermistor[] = { static struct abx500_battery_type bat_type_ext_thermistor[] = {
[BATTERY_UNKNOWN] = { [BATTERY_UNKNOWN] = {
/* First element always represent the UNKNOWN battery */ /* First element always represent the UNKNOWN battery */
.name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
.resis_high = 0, .resis_high = 0,
...@@ -278,7 +278,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = { ...@@ -278,7 +278,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = {
.nominal_voltage = 3700, .nominal_voltage = 3700,
.termination_vol = 4050, .termination_vol = 4050,
.termination_curr = 200, .termination_curr = 200,
.recharge_vol = 3990, .recharge_cap = 95,
.normal_cur_lvl = 400, .normal_cur_lvl = 400,
.normal_vol_lvl = 4100, .normal_vol_lvl = 4100,
.maint_a_cur_lvl = 400, .maint_a_cur_lvl = 400,
...@@ -295,13 +295,13 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = { ...@@ -295,13 +295,13 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = {
.v_to_cap_tbl = cap_tbl, .v_to_cap_tbl = cap_tbl,
.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
.batres_tbl = temp_to_batres_tbl_thermistor, .batres_tbl = temp_to_batres_tbl_thermistor,
}, },
/* /*
* These are the batteries that doesn't have an internal NTC resistor to measure * These are the batteries that doesn't have an internal NTC resistor to measure
* its temperature. The temperature in this case is measure with a NTC placed * its temperature. The temperature in this case is measure with a NTC placed
* near the battery but on the PCB. * near the battery but on the PCB.
*/ */
{ {
.name = POWER_SUPPLY_TECHNOLOGY_LIPO, .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
.resis_high = 76000, .resis_high = 76000,
.resis_low = 53000, .resis_low = 53000,
...@@ -310,7 +310,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = { ...@@ -310,7 +310,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = {
.nominal_voltage = 3700, .nominal_voltage = 3700,
.termination_vol = 4150, .termination_vol = 4150,
.termination_curr = 100, .termination_curr = 100,
.recharge_vol = 4130, .recharge_cap = 95,
.normal_cur_lvl = 700, .normal_cur_lvl = 700,
.normal_vol_lvl = 4200, .normal_vol_lvl = 4200,
.maint_a_cur_lvl = 600, .maint_a_cur_lvl = 600,
...@@ -327,8 +327,8 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = { ...@@ -327,8 +327,8 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = {
.v_to_cap_tbl = cap_tbl, .v_to_cap_tbl = cap_tbl,
.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
.batres_tbl = temp_to_batres_tbl_thermistor, .batres_tbl = temp_to_batres_tbl_thermistor,
}, },
{ {
.name = POWER_SUPPLY_TECHNOLOGY_LION, .name = POWER_SUPPLY_TECHNOLOGY_LION,
.resis_high = 30000, .resis_high = 30000,
.resis_low = 10000, .resis_low = 10000,
...@@ -337,7 +337,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = { ...@@ -337,7 +337,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = {
.nominal_voltage = 3700, .nominal_voltage = 3700,
.termination_vol = 4150, .termination_vol = 4150,
.termination_curr = 100, .termination_curr = 100,
.recharge_vol = 4130, .recharge_cap = 95,
.normal_cur_lvl = 700, .normal_cur_lvl = 700,
.normal_vol_lvl = 4200, .normal_vol_lvl = 4200,
.maint_a_cur_lvl = 600, .maint_a_cur_lvl = 600,
...@@ -354,8 +354,8 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = { ...@@ -354,8 +354,8 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = {
.v_to_cap_tbl = cap_tbl, .v_to_cap_tbl = cap_tbl,
.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
.batres_tbl = temp_to_batres_tbl_thermistor, .batres_tbl = temp_to_batres_tbl_thermistor,
}, },
{ {
.name = POWER_SUPPLY_TECHNOLOGY_LION, .name = POWER_SUPPLY_TECHNOLOGY_LION,
.resis_high = 95000, .resis_high = 95000,
.resis_low = 76001, .resis_low = 76001,
...@@ -364,7 +364,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = { ...@@ -364,7 +364,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = {
.nominal_voltage = 3700, .nominal_voltage = 3700,
.termination_vol = 4150, .termination_vol = 4150,
.termination_curr = 100, .termination_curr = 100,
.recharge_vol = 4130, .recharge_cap = 95,
.normal_cur_lvl = 700, .normal_cur_lvl = 700,
.normal_vol_lvl = 4200, .normal_vol_lvl = 4200,
.maint_a_cur_lvl = 600, .maint_a_cur_lvl = 600,
...@@ -381,7 +381,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = { ...@@ -381,7 +381,7 @@ static struct abx500_battery_type bat_type_ext_thermistor[] = {
.v_to_cap_tbl = cap_tbl, .v_to_cap_tbl = cap_tbl,
.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
.batres_tbl = temp_to_batres_tbl_thermistor, .batres_tbl = temp_to_batres_tbl_thermistor,
}, },
}; };
static const struct abx500_bm_capacity_levels cap_levels = { static const struct abx500_bm_capacity_levels cap_levels = {
...@@ -405,8 +405,8 @@ static const struct abx500_fg_parameters fg = { ...@@ -405,8 +405,8 @@ static const struct abx500_fg_parameters fg = {
.lowbat_threshold = 3100, .lowbat_threshold = 3100,
.battok_falling_th_sel0 = 2860, .battok_falling_th_sel0 = 2860,
.battok_raising_th_sel1 = 2860, .battok_raising_th_sel1 = 2860,
.maint_thres = 95,
.user_cap_limit = 15, .user_cap_limit = 15,
.maint_thres = 97,
}; };
static const struct abx500_maxim_parameters maxi_params = { static const struct abx500_maxim_parameters maxi_params = {
...@@ -435,6 +435,7 @@ struct abx500_bm_data ab8500_bm_data = { ...@@ -435,6 +435,7 @@ struct abx500_bm_data ab8500_bm_data = {
.bkup_bat_v = BUP_VCH_SEL_2P6V, .bkup_bat_v = BUP_VCH_SEL_2P6V,
.bkup_bat_i = BUP_ICH_SEL_150UA, .bkup_bat_i = BUP_ICH_SEL_150UA,
.no_maintenance = false, .no_maintenance = false,
.capacity_scaling = false,
.adc_therm = ABx500_ADC_THERM_BATCTRL, .adc_therm = ABx500_ADC_THERM_BATCTRL,
.chg_unknown_bat = false, .chg_unknown_bat = false,
.enable_overshoot = false, .enable_overshoot = false,
...@@ -452,68 +453,55 @@ struct abx500_bm_data ab8500_bm_data = { ...@@ -452,68 +453,55 @@ struct abx500_bm_data ab8500_bm_data = {
.fg_params = &fg, .fg_params = &fg,
}; };
int bmdevs_of_probe(struct device *dev, struct device_node *np, int ab8500_bm_of_probe(struct device *dev,
struct abx500_bm_data **battery) struct device_node *np,
struct abx500_bm_data *bm)
{ {
struct abx500_battery_type *btype; struct batres_vs_temp *tmp_batres_tbl;
struct device_node *np_bat_supply; struct device_node *battery_node;
struct abx500_bm_data *bat;
const char *btech; const char *btech;
char bat_tech[8]; int i;
int i, thermistor;
*battery = &ab8500_bm_data;
/* get phandle to 'battery-info' node */ /* get phandle to 'battery-info' node */
np_bat_supply = of_parse_phandle(np, "battery", 0); battery_node = of_parse_phandle(np, "battery", 0);
if (!np_bat_supply) { if (!battery_node) {
dev_err(dev, "missing property battery\n"); dev_err(dev, "battery node or reference missing\n");
return -EINVAL; return -EINVAL;
} }
if (of_property_read_bool(np_bat_supply,
"thermistor-on-batctrl"))
thermistor = NTC_INTERNAL;
else
thermistor = NTC_EXTERNAL;
bat = *battery; btech = of_get_property(battery_node, "stericsson,battery-type", NULL);
if (thermistor == NTC_EXTERNAL) {
bat->n_btypes = 4;
bat->bat_type = bat_type_ext_thermistor;
bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
}
btech = of_get_property(np_bat_supply,
"stericsson,battery-type", NULL);
if (!btech) { if (!btech) {
dev_warn(dev, "missing property battery-name/type\n"); dev_warn(dev, "missing property battery-name/type\n");
strcpy(bat_tech, "UNKNOWN"); return -EINVAL;
} else {
strcpy(bat_tech, btech);
} }
if (strncmp(bat_tech, "LION", 4) == 0) { if (strncmp(btech, "LION", 4) == 0) {
bat->no_maintenance = true; bm->no_maintenance = true;
bat->chg_unknown_bat = true; bm->chg_unknown_bat = true;
bat->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600; bm->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600;
bat->bat_type[BATTERY_UNKNOWN].termination_vol = 4150; bm->bat_type[BATTERY_UNKNOWN].termination_vol = 4150;
bat->bat_type[BATTERY_UNKNOWN].recharge_vol = 4130; bm->bat_type[BATTERY_UNKNOWN].recharge_cap = 95;
bat->bat_type[BATTERY_UNKNOWN].normal_cur_lvl = 520; bm->bat_type[BATTERY_UNKNOWN].normal_cur_lvl = 520;
bat->bat_type[BATTERY_UNKNOWN].normal_vol_lvl = 4200; bm->bat_type[BATTERY_UNKNOWN].normal_vol_lvl = 4200;
} }
/* select the battery resolution table */
for (i = 0; i < bat->n_btypes; ++i) { if (of_property_read_bool(battery_node, "thermistor-on-batctrl")) {
btype = (bat->bat_type + i); if (strncmp(btech, "LION", 4) == 0)
if (thermistor == NTC_EXTERNAL) { tmp_batres_tbl = temp_to_batres_tbl_9100;
btype->batres_tbl = else
temp_to_batres_tbl_ext_thermistor; tmp_batres_tbl = temp_to_batres_tbl_thermistor;
} else if (strncmp(bat_tech, "LION", 4) == 0) {
btype->batres_tbl =
temp_to_batres_tbl_9100;
} else { } else {
btype->batres_tbl = bm->n_btypes = 4;
temp_to_batres_tbl_thermistor; bm->bat_type = bat_type_ext_thermistor;
} bm->adc_therm = ABx500_ADC_THERM_BATTEMP;
tmp_batres_tbl = temp_to_batres_tbl_ext_thermistor;
} }
of_node_put(np_bat_supply);
/* select the battery resolution table */
for (i = 0; i < bm->n_btypes; ++i)
bm->bat_type[i].batres_tbl = tmp_batres_tbl;
of_node_put(battery_node);
return 0; return 0;
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
* http://www.ti.com/product/bq24155 * http://www.ti.com/product/bq24155
*/ */
#include <linux/version.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/param.h> #include <linux/param.h>
...@@ -734,12 +733,10 @@ static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode) ...@@ -734,12 +733,10 @@ static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode)
int charger = 0; int charger = 0;
int boost = 0; int boost = 0;
if (mode == BQ2415X_MODE_HOST_CHARGER ||
mode == BQ2415X_MODE_DEDICATED_CHARGER)
charger = 1;
if (mode == BQ2415X_MODE_BOOST) if (mode == BQ2415X_MODE_BOOST)
boost = 1; boost = 1;
else if (mode != BQ2415X_MODE_OFF)
charger = 1;
if (!charger) if (!charger)
ret = bq2415x_exec_command(bq, BQ2415X_CHARGER_DISABLE); ret = bq2415x_exec_command(bq, BQ2415X_CHARGER_DISABLE);
...@@ -751,6 +748,10 @@ static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode) ...@@ -751,6 +748,10 @@ static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode)
return ret; return ret;
switch (mode) { switch (mode) {
case BQ2415X_MODE_OFF:
dev_dbg(bq->dev, "changing mode to: Offline\n");
ret = bq2415x_set_current_limit(bq, 100);
break;
case BQ2415X_MODE_NONE: case BQ2415X_MODE_NONE:
dev_dbg(bq->dev, "changing mode to: N/A\n"); dev_dbg(bq->dev, "changing mode to: N/A\n");
ret = bq2415x_set_current_limit(bq, 100); ret = bq2415x_set_current_limit(bq, 100);
...@@ -843,7 +844,7 @@ static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg) ...@@ -843,7 +844,7 @@ static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg)
dev_err(bq->dev, "%s\n", msg); dev_err(bq->dev, "%s\n", msg);
if (bq->automode > 0) if (bq->automode > 0)
bq->automode = 0; bq->automode = 0;
bq2415x_set_mode(bq, BQ2415X_MODE_NONE); bq2415x_set_mode(bq, BQ2415X_MODE_OFF);
bq2415x_set_autotimer(bq, 0); bq2415x_set_autotimer(bq, 0);
} }
...@@ -1136,6 +1137,10 @@ static ssize_t bq2415x_sysfs_set_mode(struct device *dev, ...@@ -1136,6 +1137,10 @@ static ssize_t bq2415x_sysfs_set_mode(struct device *dev,
return -ENOSYS; return -ENOSYS;
bq->automode = 1; bq->automode = 1;
mode = bq->reported_mode; mode = bq->reported_mode;
} else if (strncmp(buf, "off", 3) == 0) {
if (bq->automode > 0)
bq->automode = 0;
mode = BQ2415X_MODE_OFF;
} else if (strncmp(buf, "none", 4) == 0) { } else if (strncmp(buf, "none", 4) == 0) {
if (bq->automode > 0) if (bq->automode > 0)
bq->automode = 0; bq->automode = 0;
...@@ -1183,6 +1188,9 @@ static ssize_t bq2415x_sysfs_show_mode(struct device *dev, ...@@ -1183,6 +1188,9 @@ static ssize_t bq2415x_sysfs_show_mode(struct device *dev,
ret += sprintf(buf+ret, "auto ("); ret += sprintf(buf+ret, "auto (");
switch (bq->mode) { switch (bq->mode) {
case BQ2415X_MODE_OFF:
ret += sprintf(buf+ret, "off");
break;
case BQ2415X_MODE_NONE: case BQ2415X_MODE_NONE:
ret += sprintf(buf+ret, "none"); ret += sprintf(buf+ret, "none");
break; break;
...@@ -1217,6 +1225,8 @@ static ssize_t bq2415x_sysfs_show_reported_mode(struct device *dev, ...@@ -1217,6 +1225,8 @@ static ssize_t bq2415x_sysfs_show_reported_mode(struct device *dev,
return -EINVAL; return -EINVAL;
switch (bq->reported_mode) { switch (bq->reported_mode) {
case BQ2415X_MODE_OFF:
return sprintf(buf, "off\n");
case BQ2415X_MODE_NONE: case BQ2415X_MODE_NONE:
return sprintf(buf, "none\n"); return sprintf(buf, "none\n");
case BQ2415X_MODE_HOST_CHARGER: case BQ2415X_MODE_HOST_CHARGER:
...@@ -1523,7 +1533,7 @@ static int bq2415x_probe(struct i2c_client *client, ...@@ -1523,7 +1533,7 @@ static int bq2415x_probe(struct i2c_client *client,
goto error_1; goto error_1;
} }
bq = kzalloc(sizeof(*bq), GFP_KERNEL); bq = devm_kzalloc(&client->dev, sizeof(*bq), GFP_KERNEL);
if (!bq) { if (!bq) {
dev_err(&client->dev, "failed to allocate device data\n"); dev_err(&client->dev, "failed to allocate device data\n");
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1536,8 +1546,8 @@ static int bq2415x_probe(struct i2c_client *client, ...@@ -1536,8 +1546,8 @@ static int bq2415x_probe(struct i2c_client *client,
bq->dev = &client->dev; bq->dev = &client->dev;
bq->chip = id->driver_data; bq->chip = id->driver_data;
bq->name = name; bq->name = name;
bq->mode = BQ2415X_MODE_NONE; bq->mode = BQ2415X_MODE_OFF;
bq->reported_mode = BQ2415X_MODE_NONE; bq->reported_mode = BQ2415X_MODE_OFF;
bq->autotimer = 0; bq->autotimer = 0;
bq->automode = 0; bq->automode = 0;
...@@ -1549,19 +1559,19 @@ static int bq2415x_probe(struct i2c_client *client, ...@@ -1549,19 +1559,19 @@ static int bq2415x_probe(struct i2c_client *client,
ret = bq2415x_power_supply_init(bq); ret = bq2415x_power_supply_init(bq);
if (ret) { if (ret) {
dev_err(bq->dev, "failed to register power supply: %d\n", ret); dev_err(bq->dev, "failed to register power supply: %d\n", ret);
goto error_3; goto error_2;
} }
ret = bq2415x_sysfs_init(bq); ret = bq2415x_sysfs_init(bq);
if (ret) { if (ret) {
dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret); dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret);
goto error_4; goto error_3;
} }
ret = bq2415x_set_defaults(bq); ret = bq2415x_set_defaults(bq);
if (ret) { if (ret) {
dev_err(bq->dev, "failed to set default values: %d\n", ret); dev_err(bq->dev, "failed to set default values: %d\n", ret);
goto error_5; goto error_4;
} }
if (bq->init_data.set_mode_hook) { if (bq->init_data.set_mode_hook) {
...@@ -1585,12 +1595,10 @@ static int bq2415x_probe(struct i2c_client *client, ...@@ -1585,12 +1595,10 @@ static int bq2415x_probe(struct i2c_client *client,
dev_info(bq->dev, "driver registered\n"); dev_info(bq->dev, "driver registered\n");
return 0; return 0;
error_5:
bq2415x_sysfs_exit(bq);
error_4: error_4:
bq2415x_power_supply_exit(bq); bq2415x_sysfs_exit(bq);
error_3: error_3:
kfree(bq); bq2415x_power_supply_exit(bq);
error_2: error_2:
kfree(name); kfree(name);
error_1: error_1:
...@@ -1622,7 +1630,6 @@ static int bq2415x_remove(struct i2c_client *client) ...@@ -1622,7 +1630,6 @@ static int bq2415x_remove(struct i2c_client *client)
dev_info(bq->dev, "driver unregistered\n"); dev_info(bq->dev, "driver unregistered\n");
kfree(bq->name); kfree(bq->name);
kfree(bq);
return 0; return 0;
} }
...@@ -1652,18 +1659,7 @@ static struct i2c_driver bq2415x_driver = { ...@@ -1652,18 +1659,7 @@ static struct i2c_driver bq2415x_driver = {
.remove = bq2415x_remove, .remove = bq2415x_remove,
.id_table = bq2415x_i2c_id_table, .id_table = bq2415x_i2c_id_table,
}; };
module_i2c_driver(bq2415x_driver);
static int __init bq2415x_init(void)
{
return i2c_add_driver(&bq2415x_driver);
}
module_init(bq2415x_init);
static void __exit bq2415x_exit(void)
{
i2c_del_driver(&bq2415x_driver);
}
module_exit(bq2415x_exit);
MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
MODULE_DESCRIPTION("bq2415x charger driver"); MODULE_DESCRIPTION("bq2415x charger driver");
......
...@@ -299,7 +299,7 @@ static int bq27x00_battery_read_energy(struct bq27x00_device_info *di) ...@@ -299,7 +299,7 @@ static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
} }
/* /*
* Return the battery temperature in tenths of degree Celsius * Return the battery temperature in tenths of degree Kelvin
* Or < 0 if something fails. * Or < 0 if something fails.
*/ */
static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di) static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
...@@ -312,10 +312,8 @@ static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di) ...@@ -312,10 +312,8 @@ static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
return temp; return temp;
} }
if (bq27xxx_is_chip_version_higher(di)) if (!bq27xxx_is_chip_version_higher(di))
temp -= 2731; temp = 5 * temp / 2;
else
temp = ((temp * 5) - 5463) / 2;
return temp; return temp;
} }
...@@ -448,7 +446,6 @@ static void bq27x00_update(struct bq27x00_device_info *di) ...@@ -448,7 +446,6 @@ static void bq27x00_update(struct bq27x00_device_info *di)
cache.temperature = bq27x00_battery_read_temperature(di); cache.temperature = bq27x00_battery_read_temperature(di);
if (!is_bq27425) if (!is_bq27425)
cache.cycle_count = bq27x00_battery_read_cyct(di); cache.cycle_count = bq27x00_battery_read_cyct(di);
cache.cycle_count = bq27x00_battery_read_cyct(di);
cache.power_avg = cache.power_avg =
bq27x00_battery_read_pwr_avg(di, BQ27x00_POWER_AVG); bq27x00_battery_read_pwr_avg(di, BQ27x00_POWER_AVG);
...@@ -642,6 +639,8 @@ static int bq27x00_battery_get_property(struct power_supply *psy, ...@@ -642,6 +639,8 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
break; break;
case POWER_SUPPLY_PROP_TEMP: case POWER_SUPPLY_PROP_TEMP:
ret = bq27x00_simple_value(di->cache.temperature, val); ret = bq27x00_simple_value(di->cache.temperature, val);
if (ret == 0)
val->intval -= 2731;
break; break;
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
ret = bq27x00_simple_value(di->cache.time_to_empty, val); ret = bq27x00_simple_value(di->cache.time_to_empty, val);
...@@ -696,7 +695,6 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di) ...@@ -696,7 +695,6 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di)
int ret; int ret;
di->bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
di->chip = BQ27425;
if (di->chip == BQ27425) { if (di->chip == BQ27425) {
di->bat.properties = bq27425_battery_props; di->bat.properties = bq27425_battery_props;
di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props); di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props);
......
This diff is collapsed.
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/notifier.h>
#define DA9030_FAULT_LOG 0x0a #define DA9030_FAULT_LOG 0x0a
#define DA9030_FAULT_LOG_OVER_TEMP (1 << 7) #define DA9030_FAULT_LOG_OVER_TEMP (1 << 7)
......
...@@ -337,7 +337,7 @@ static unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp) ...@@ -337,7 +337,7 @@ static unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp)
if (adc_temp > vc_tbl_ref[DA9052_VC_TBL_REF_SZ - 1]) if (adc_temp > vc_tbl_ref[DA9052_VC_TBL_REF_SZ - 1])
return DA9052_VC_TBL_REF_SZ - 1; return DA9052_VC_TBL_REF_SZ - 1;
for (i = 0; i < DA9052_VC_TBL_REF_SZ; i++) { for (i = 0; i < DA9052_VC_TBL_REF_SZ - 1; i++) {
if ((adc_temp > vc_tbl_ref[i]) && if ((adc_temp > vc_tbl_ref[i]) &&
(adc_temp <= DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1]))) (adc_temp <= DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1])))
return i; return i;
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
* *
* DS2786 added by Yulia Vilensky <vilensky@compulab.co.il> * DS2786 added by Yulia Vilensky <vilensky@compulab.co.il>
* *
* UEvent sending added by Evgeny Romanov <romanov@neurosoft.ru>
*
* 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 version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
...@@ -19,6 +21,7 @@ ...@@ -19,6 +21,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/swab.h> #include <linux/swab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -40,6 +43,8 @@ ...@@ -40,6 +43,8 @@
#define DS2786_CURRENT_UNITS 25 #define DS2786_CURRENT_UNITS 25
#define DS278x_DELAY 1000
struct ds278x_info; struct ds278x_info;
struct ds278x_battery_ops { struct ds278x_battery_ops {
...@@ -54,8 +59,11 @@ struct ds278x_info { ...@@ -54,8 +59,11 @@ struct ds278x_info {
struct i2c_client *client; struct i2c_client *client;
struct power_supply battery; struct power_supply battery;
struct ds278x_battery_ops *ops; struct ds278x_battery_ops *ops;
struct delayed_work bat_work;
int id; int id;
int rsns; int rsns;
int capacity;
int status; /* State Of Charge */
}; };
static DEFINE_IDR(battery_id); static DEFINE_IDR(battery_id);
...@@ -220,6 +228,8 @@ static int ds278x_get_status(struct ds278x_info *info, int *status) ...@@ -220,6 +228,8 @@ static int ds278x_get_status(struct ds278x_info *info, int *status)
if (err) if (err)
return err; return err;
info->capacity = capacity;
if (capacity == 100) if (capacity == 100)
*status = POWER_SUPPLY_STATUS_FULL; *status = POWER_SUPPLY_STATUS_FULL;
else if (current_uA == 0) else if (current_uA == 0)
...@@ -267,6 +277,27 @@ static int ds278x_battery_get_property(struct power_supply *psy, ...@@ -267,6 +277,27 @@ static int ds278x_battery_get_property(struct power_supply *psy,
return ret; return ret;
} }
static void ds278x_bat_update(struct ds278x_info *info)
{
int old_status = info->status;
int old_capacity = info->capacity;
ds278x_get_status(info, &info->status);
if ((old_status != info->status) || (old_capacity != info->capacity))
power_supply_changed(&info->battery);
}
static void ds278x_bat_work(struct work_struct *work)
{
struct ds278x_info *info;
info = container_of(work, struct ds278x_info, bat_work.work);
ds278x_bat_update(info);
schedule_delayed_work(&info->bat_work, DS278x_DELAY);
}
static enum power_supply_property ds278x_battery_props[] = { static enum power_supply_property ds278x_battery_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CAPACITY,
...@@ -295,10 +326,39 @@ static int ds278x_battery_remove(struct i2c_client *client) ...@@ -295,10 +326,39 @@ static int ds278x_battery_remove(struct i2c_client *client)
idr_remove(&battery_id, info->id); idr_remove(&battery_id, info->id);
mutex_unlock(&battery_lock); mutex_unlock(&battery_lock);
cancel_delayed_work(&info->bat_work);
kfree(info); kfree(info);
return 0; return 0;
} }
#ifdef CONFIG_PM
static int ds278x_suspend(struct i2c_client *client,
pm_message_t state)
{
struct ds278x_info *info = i2c_get_clientdata(client);
cancel_delayed_work(&info->bat_work);
return 0;
}
static int ds278x_resume(struct i2c_client *client)
{
struct ds278x_info *info = i2c_get_clientdata(client);
schedule_delayed_work(&info->bat_work, DS278x_DELAY);
return 0;
}
#else
#define ds278x_suspend NULL
#define ds278x_resume NULL
#endif /* CONFIG_PM */
enum ds278x_num_id { enum ds278x_num_id {
DS2782 = 0, DS2782 = 0,
DS2786, DS2786,
...@@ -368,10 +428,17 @@ static int ds278x_battery_probe(struct i2c_client *client, ...@@ -368,10 +428,17 @@ static int ds278x_battery_probe(struct i2c_client *client,
info->ops = &ds278x_ops[id->driver_data]; info->ops = &ds278x_ops[id->driver_data];
ds278x_power_supply_init(&info->battery); ds278x_power_supply_init(&info->battery);
info->capacity = 100;
info->status = POWER_SUPPLY_STATUS_FULL;
INIT_DELAYED_WORK(&info->bat_work, ds278x_bat_work);
ret = power_supply_register(&client->dev, &info->battery); ret = power_supply_register(&client->dev, &info->battery);
if (ret) { if (ret) {
dev_err(&client->dev, "failed to register battery\n"); dev_err(&client->dev, "failed to register battery\n");
goto fail_register; goto fail_register;
} else {
schedule_delayed_work(&info->bat_work, DS278x_DELAY);
} }
return 0; return 0;
...@@ -401,6 +468,8 @@ static struct i2c_driver ds278x_battery_driver = { ...@@ -401,6 +468,8 @@ static struct i2c_driver ds278x_battery_driver = {
}, },
.probe = ds278x_battery_probe, .probe = ds278x_battery_probe,
.remove = ds278x_battery_remove, .remove = ds278x_battery_remove,
.suspend = ds278x_suspend,
.resume = ds278x_resume,
.id_table = ds278x_id, .id_table = ds278x_id,
}; };
module_i2c_driver(ds278x_battery_driver); module_i2c_driver(ds278x_battery_driver);
......
...@@ -263,9 +263,6 @@ static int gab_probe(struct platform_device *pdev) ...@@ -263,9 +263,6 @@ static int gab_probe(struct platform_device *pdev)
psy->external_power_changed = gab_ext_power_changed; psy->external_power_changed = gab_ext_power_changed;
adc_bat->pdata = pdata; adc_bat->pdata = pdata;
/* calculate the total number of channels */
chan = ARRAY_SIZE(gab_chan_name);
/* /*
* copying the static properties and allocating extra memory for holding * copying the static properties and allocating extra memory for holding
* the extra configurable properties received from platform data. * the extra configurable properties received from platform data.
...@@ -291,6 +288,7 @@ static int gab_probe(struct platform_device *pdev) ...@@ -291,6 +288,7 @@ static int gab_probe(struct platform_device *pdev)
gab_chan_name[chan]); gab_chan_name[chan]);
if (IS_ERR(adc_bat->channel[chan])) { if (IS_ERR(adc_bat->channel[chan])) {
ret = PTR_ERR(adc_bat->channel[chan]); ret = PTR_ERR(adc_bat->channel[chan]);
adc_bat->channel[chan] = NULL;
} else { } else {
/* copying properties for supported channels only */ /* copying properties for supported channels only */
memcpy(properties + sizeof(*(psy->properties)) * index, memcpy(properties + sizeof(*(psy->properties)) * index,
...@@ -344,8 +342,10 @@ static int gab_probe(struct platform_device *pdev) ...@@ -344,8 +342,10 @@ static int gab_probe(struct platform_device *pdev)
gpio_req_fail: gpio_req_fail:
power_supply_unregister(psy); power_supply_unregister(psy);
err_reg_fail: err_reg_fail:
for (chan = 0; ARRAY_SIZE(gab_chan_name); chan++) for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) {
if (adc_bat->channel[chan])
iio_channel_release(adc_bat->channel[chan]); iio_channel_release(adc_bat->channel[chan]);
}
second_mem_fail: second_mem_fail:
kfree(psy->properties); kfree(psy->properties);
first_mem_fail: first_mem_fail:
...@@ -365,8 +365,10 @@ static int gab_remove(struct platform_device *pdev) ...@@ -365,8 +365,10 @@ static int gab_remove(struct platform_device *pdev)
gpio_free(pdata->gpio_charge_finished); gpio_free(pdata->gpio_charge_finished);
} }
for (chan = 0; ARRAY_SIZE(gab_chan_name); chan++) for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) {
if (adc_bat->channel[chan])
iio_channel_release(adc_bat->channel[chan]); iio_channel_release(adc_bat->channel[chan]);
}
kfree(adc_bat->psy.properties); kfree(adc_bat->psy.properties);
cancel_delayed_work(&adc_bat->bat_work); cancel_delayed_work(&adc_bat->bat_work);
......
/*
* Power supply driver for the goldfish emulator
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2012 Intel, Inc.
* Copyright (C) 2013 Intel, Inc.
* Author: Mike Lockwood <lockwood@android.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/io.h>
struct goldfish_battery_data {
void __iomem *reg_base;
int irq;
spinlock_t lock;
struct power_supply battery;
struct power_supply ac;
};
#define GOLDFISH_BATTERY_READ(data, addr) \
(readl(data->reg_base + addr))
#define GOLDFISH_BATTERY_WRITE(data, addr, x) \
(writel(x, data->reg_base + addr))
/*
* Temporary variable used between goldfish_battery_probe() and
* goldfish_battery_open().
*/
static struct goldfish_battery_data *battery_data;
enum {
/* status register */
BATTERY_INT_STATUS = 0x00,
/* set this to enable IRQ */
BATTERY_INT_ENABLE = 0x04,
BATTERY_AC_ONLINE = 0x08,
BATTERY_STATUS = 0x0C,
BATTERY_HEALTH = 0x10,
BATTERY_PRESENT = 0x14,
BATTERY_CAPACITY = 0x18,
BATTERY_STATUS_CHANGED = 1U << 0,
AC_STATUS_CHANGED = 1U << 1,
BATTERY_INT_MASK = BATTERY_STATUS_CHANGED | AC_STATUS_CHANGED,
};
static int goldfish_ac_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct goldfish_battery_data *data = container_of(psy,
struct goldfish_battery_data, ac);
int ret = 0;
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_AC_ONLINE);
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static int goldfish_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct goldfish_battery_data *data = container_of(psy,
struct goldfish_battery_data, battery);
int ret = 0;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_STATUS);
break;
case POWER_SUPPLY_PROP_HEALTH:
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_HEALTH);
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_PRESENT);
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_CAPACITY);
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static enum power_supply_property goldfish_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_CAPACITY,
};
static enum power_supply_property goldfish_ac_props[] = {
POWER_SUPPLY_PROP_ONLINE,
};
static irqreturn_t goldfish_battery_interrupt(int irq, void *dev_id)
{
unsigned long irq_flags;
struct goldfish_battery_data *data = dev_id;
uint32_t status;
spin_lock_irqsave(&data->lock, irq_flags);
/* read status flags, which will clear the interrupt */
status = GOLDFISH_BATTERY_READ(data, BATTERY_INT_STATUS);
status &= BATTERY_INT_MASK;
if (status & BATTERY_STATUS_CHANGED)
power_supply_changed(&data->battery);
if (status & AC_STATUS_CHANGED)
power_supply_changed(&data->ac);
spin_unlock_irqrestore(&data->lock, irq_flags);
return status ? IRQ_HANDLED : IRQ_NONE;
}
static int goldfish_battery_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
struct goldfish_battery_data *data;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
spin_lock_init(&data->lock);
data->battery.properties = goldfish_battery_props;
data->battery.num_properties = ARRAY_SIZE(goldfish_battery_props);
data->battery.get_property = goldfish_battery_get_property;
data->battery.name = "battery";
data->battery.type = POWER_SUPPLY_TYPE_BATTERY;
data->ac.properties = goldfish_ac_props;
data->ac.num_properties = ARRAY_SIZE(goldfish_ac_props);
data->ac.get_property = goldfish_ac_get_property;
data->ac.name = "ac";
data->ac.type = POWER_SUPPLY_TYPE_MAINS;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&pdev->dev, "platform_get_resource failed\n");
return -ENODEV;
}
data->reg_base = devm_ioremap(&pdev->dev, r->start, r->end - r->start + 1);
if (data->reg_base == NULL) {
dev_err(&pdev->dev, "unable to remap MMIO\n");
return -ENOMEM;
}
data->irq = platform_get_irq(pdev, 0);
if (data->irq < 0) {
dev_err(&pdev->dev, "platform_get_irq failed\n");
return -ENODEV;
}
ret = devm_request_irq(&pdev->dev, data->irq, goldfish_battery_interrupt,
IRQF_SHARED, pdev->name, data);
if (ret)
return ret;
ret = power_supply_register(&pdev->dev, &data->ac);
if (ret)
return ret;
ret = power_supply_register(&pdev->dev, &data->battery);
if (ret) {
power_supply_unregister(&data->ac);
return ret;
}
platform_set_drvdata(pdev, data);
battery_data = data;
GOLDFISH_BATTERY_WRITE(data, BATTERY_INT_ENABLE, BATTERY_INT_MASK);
return 0;
}
static int goldfish_battery_remove(struct platform_device *pdev)
{
struct goldfish_battery_data *data = platform_get_drvdata(pdev);
power_supply_unregister(&data->battery);
power_supply_unregister(&data->ac);
battery_data = NULL;
return 0;
}
static struct platform_driver goldfish_battery_device = {
.probe = goldfish_battery_probe,
.remove = goldfish_battery_remove,
.driver = {
.name = "goldfish-battery"
}
};
module_platform_driver(goldfish_battery_device);
MODULE_AUTHOR("Mike Lockwood lockwood@android.com");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Battery driver for the Goldfish emulator");
...@@ -367,28 +367,28 @@ static int lp8727_battery_get_property(struct power_supply *psy, ...@@ -367,28 +367,28 @@ static int lp8727_battery_get_property(struct power_supply *psy,
return -EINVAL; return -EINVAL;
if (pdata->get_batt_present) if (pdata->get_batt_present)
val->intval = pchg->pdata->get_batt_present(); val->intval = pdata->get_batt_present();
break; break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW: case POWER_SUPPLY_PROP_VOLTAGE_NOW:
if (!pdata) if (!pdata)
return -EINVAL; return -EINVAL;
if (pdata->get_batt_level) if (pdata->get_batt_level)
val->intval = pchg->pdata->get_batt_level(); val->intval = pdata->get_batt_level();
break; break;
case POWER_SUPPLY_PROP_CAPACITY: case POWER_SUPPLY_PROP_CAPACITY:
if (!pdata) if (!pdata)
return -EINVAL; return -EINVAL;
if (pdata->get_batt_capacity) if (pdata->get_batt_capacity)
val->intval = pchg->pdata->get_batt_capacity(); val->intval = pdata->get_batt_capacity();
break; break;
case POWER_SUPPLY_PROP_TEMP: case POWER_SUPPLY_PROP_TEMP:
if (!pdata) if (!pdata)
return -EINVAL; return -EINVAL;
if (pdata->get_batt_temp) if (pdata->get_batt_temp)
val->intval = pchg->pdata->get_batt_temp(); val->intval = pdata->get_batt_temp();
break; break;
default: default:
break; break;
......
...@@ -367,7 +367,8 @@ static inline bool lp8788_is_valid_charger_register(u8 addr) ...@@ -367,7 +367,8 @@ static inline bool lp8788_is_valid_charger_register(u8 addr)
return addr >= LP8788_CHG_START && addr <= LP8788_CHG_END; return addr >= LP8788_CHG_START && addr <= LP8788_CHG_END;
} }
static int lp8788_update_charger_params(struct lp8788_charger *pchg) static int lp8788_update_charger_params(struct platform_device *pdev,
struct lp8788_charger *pchg)
{ {
struct lp8788 *lp = pchg->lp; struct lp8788 *lp = pchg->lp;
struct lp8788_charger_platform_data *pdata = pchg->pdata; struct lp8788_charger_platform_data *pdata = pchg->pdata;
...@@ -376,7 +377,7 @@ static int lp8788_update_charger_params(struct lp8788_charger *pchg) ...@@ -376,7 +377,7 @@ static int lp8788_update_charger_params(struct lp8788_charger *pchg)
int ret; int ret;
if (!pdata || !pdata->chg_params) { if (!pdata || !pdata->chg_params) {
dev_info(lp->dev, "skip updating charger parameters\n"); dev_info(&pdev->dev, "skip updating charger parameters\n");
return 0; return 0;
} }
...@@ -537,7 +538,6 @@ static int lp8788_set_irqs(struct platform_device *pdev, ...@@ -537,7 +538,6 @@ static int lp8788_set_irqs(struct platform_device *pdev,
static int lp8788_irq_register(struct platform_device *pdev, static int lp8788_irq_register(struct platform_device *pdev,
struct lp8788_charger *pchg) struct lp8788_charger *pchg)
{ {
struct lp8788 *lp = pchg->lp;
const char *name[] = { const char *name[] = {
LP8788_CHG_IRQ, LP8788_PRSW_IRQ, LP8788_BATT_IRQ LP8788_CHG_IRQ, LP8788_PRSW_IRQ, LP8788_BATT_IRQ
}; };
...@@ -550,13 +550,13 @@ static int lp8788_irq_register(struct platform_device *pdev, ...@@ -550,13 +550,13 @@ static int lp8788_irq_register(struct platform_device *pdev,
for (i = 0; i < ARRAY_SIZE(name); i++) { for (i = 0; i < ARRAY_SIZE(name); i++) {
ret = lp8788_set_irqs(pdev, pchg, name[i]); ret = lp8788_set_irqs(pdev, pchg, name[i]);
if (ret) { if (ret) {
dev_warn(lp->dev, "irq setup failed: %s\n", name[i]); dev_warn(&pdev->dev, "irq setup failed: %s\n", name[i]);
return ret; return ret;
} }
} }
if (pchg->num_irqs > LP8788_MAX_CHG_IRQS) { if (pchg->num_irqs > LP8788_MAX_CHG_IRQS) {
dev_err(lp->dev, "invalid total number of irqs: %d\n", dev_err(&pdev->dev, "invalid total number of irqs: %d\n",
pchg->num_irqs); pchg->num_irqs);
return -EINVAL; return -EINVAL;
} }
...@@ -690,9 +690,10 @@ static int lp8788_charger_probe(struct platform_device *pdev) ...@@ -690,9 +690,10 @@ static int lp8788_charger_probe(struct platform_device *pdev)
{ {
struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
struct lp8788_charger *pchg; struct lp8788_charger *pchg;
struct device *dev = &pdev->dev;
int ret; int ret;
pchg = devm_kzalloc(lp->dev, sizeof(struct lp8788_charger), GFP_KERNEL); pchg = devm_kzalloc(dev, sizeof(struct lp8788_charger), GFP_KERNEL);
if (!pchg) if (!pchg)
return -ENOMEM; return -ENOMEM;
...@@ -700,7 +701,7 @@ static int lp8788_charger_probe(struct platform_device *pdev) ...@@ -700,7 +701,7 @@ static int lp8788_charger_probe(struct platform_device *pdev)
pchg->pdata = lp->pdata ? lp->pdata->chg_pdata : NULL; pchg->pdata = lp->pdata ? lp->pdata->chg_pdata : NULL;
platform_set_drvdata(pdev, pchg); platform_set_drvdata(pdev, pchg);
ret = lp8788_update_charger_params(pchg); ret = lp8788_update_charger_params(pdev, pchg);
if (ret) if (ret)
return ret; return ret;
...@@ -718,7 +719,7 @@ static int lp8788_charger_probe(struct platform_device *pdev) ...@@ -718,7 +719,7 @@ static int lp8788_charger_probe(struct platform_device *pdev)
ret = lp8788_irq_register(pdev, pchg); ret = lp8788_irq_register(pdev, pchg);
if (ret) if (ret)
dev_warn(lp->dev, "failed to register charger irq: %d\n", ret); dev_warn(dev, "failed to register charger irq: %d\n", ret);
return 0; return 0;
} }
......
...@@ -207,7 +207,7 @@ static int max17040_probe(struct i2c_client *client, ...@@ -207,7 +207,7 @@ static int max17040_probe(struct i2c_client *client,
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
return -EIO; return -EIO;
chip = kzalloc(sizeof(*chip), GFP_KERNEL); chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip) if (!chip)
return -ENOMEM; return -ENOMEM;
...@@ -225,7 +225,6 @@ static int max17040_probe(struct i2c_client *client, ...@@ -225,7 +225,6 @@ static int max17040_probe(struct i2c_client *client,
ret = power_supply_register(&client->dev, &chip->battery); ret = power_supply_register(&client->dev, &chip->battery);
if (ret) { if (ret) {
dev_err(&client->dev, "failed: power supply register\n"); dev_err(&client->dev, "failed: power supply register\n");
kfree(chip);
return ret; return ret;
} }
...@@ -244,7 +243,6 @@ static int max17040_remove(struct i2c_client *client) ...@@ -244,7 +243,6 @@ static int max17040_remove(struct i2c_client *client)
power_supply_unregister(&chip->battery); power_supply_unregister(&chip->battery);
cancel_delayed_work(&chip->work); cancel_delayed_work(&chip->work);
kfree(chip);
return 0; return 0;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -55,7 +55,8 @@ static ssize_t power_supply_show_property(struct device *dev, ...@@ -55,7 +55,8 @@ static ssize_t power_supply_show_property(struct device *dev,
}; };
static char *health_text[] = { static char *health_text[] = {
"Unknown", "Good", "Overheat", "Dead", "Over voltage", "Unknown", "Good", "Overheat", "Dead", "Over voltage",
"Unspecified failure", "Cold", "Unspecified failure", "Cold", "Watchdog timer expire",
"Safety timer expire"
}; };
static char *technology_text[] = { static char *technology_text[] = {
"Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd", "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd",
......
...@@ -13,3 +13,20 @@ config POWER_RESET_GPIO ...@@ -13,3 +13,20 @@ config POWER_RESET_GPIO
This driver supports turning off your board via a GPIO line. This driver supports turning off your board via a GPIO line.
If your board needs a GPIO high/low to power down, say Y and If your board needs a GPIO high/low to power down, say Y and
create a binding in your devicetree. create a binding in your devicetree.
config POWER_RESET_QNAP
bool "QNAP power-off driver"
depends on OF_GPIO && POWER_RESET && PLAT_ORION
help
This driver supports turning off QNAP NAS devices by sending
commands to the microcontroller which controls the main power.
Say Y if you have a QNAP NAS.
config POWER_RESET_RESTART
bool "Restart power-off driver"
depends on ARM
help
Some boards don't actually have the ability to power off.
Instead they restart, and u-boot holds the SoC until the
user presses a key. u-boot then boots into Linux.
obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment