diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-06 23:05:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-06 23:05:34 -0400 |
commit | 0498cf8429011ec968870b3fee7570a751575a35 (patch) | |
tree | 1e0cd91db7a780c323fb97b0fbae8a9da51cae03 | |
parent | 85417aef44fc58b08773117ceb1bc6ca5684e973 (diff) | |
parent | 5e37195f30cc31e6a1052cbc282254e127c1b8c7 (diff) |
Merge tag 'for-v3.17' of git://git.infradead.org/battery-2.6
Pull power supply changes from Sebastian Reichel:
- Added iPaq h3xxx battery driver
- Added Broadcom STB reset driver
- DT support for rx51-battery
- misc. fixes
* tag 'for-v3.17' of git://git.infradead.org/battery-2.6:
ipaq_micro_battery: fix sparse non static symbol warning
power: add driver for battery reading on iPaq h3xxx
power: twl4030_charger: detect battery presence prior to enabling charger
power: reset: Add reboot driver for brcmstb
power_supply: Fix sparse non static symbol warning
power_supply: Add inlmt,iterm, min/max temp props
charger: tps65090: Allow charger module to be used when no irq
power/reset: Fix GPL v2 license string typo
power: poweroff: gpio: convert to use descriptors
bq27000: report missing device better.
bq27x00_battery: Introduce the use of the managed version of kzalloc
Documentation: DT: Document rx51-battery binding
rx51_battery: convert to iio consumer
bq2415x_charger: Fix Atomic Sleep Bug
-rw-r--r-- | Documentation/devicetree/bindings/power/rx51-battery.txt | 25 | ||||
-rw-r--r-- | Documentation/power/power_supply_class.txt | 6 | ||||
-rw-r--r-- | drivers/power/Kconfig | 7 | ||||
-rw-r--r-- | drivers/power/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/bq2415x_charger.c | 8 | ||||
-rw-r--r-- | drivers/power/bq27x00_battery.c | 28 | ||||
-rw-r--r-- | drivers/power/ipaq_micro_battery.c | 290 | ||||
-rw-r--r-- | drivers/power/power_supply_core.c | 3 | ||||
-rw-r--r-- | drivers/power/power_supply_sysfs.c | 4 | ||||
-rw-r--r-- | drivers/power/reset/Kconfig | 11 | ||||
-rw-r--r-- | drivers/power/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/reset/brcmstb-reboot.c | 120 | ||||
-rw-r--r-- | drivers/power/reset/gpio-poweroff.c | 52 | ||||
-rw-r--r-- | drivers/power/reset/restart-poweroff.c | 2 | ||||
-rw-r--r-- | drivers/power/rx51_battery.c | 90 | ||||
-rw-r--r-- | drivers/power/tps65090-charger.c | 76 | ||||
-rw-r--r-- | drivers/power/twl4030_charger.c | 44 | ||||
-rw-r--r-- | include/linux/power_supply.h | 4 |
18 files changed, 673 insertions, 99 deletions
diff --git a/Documentation/devicetree/bindings/power/rx51-battery.txt b/Documentation/devicetree/bindings/power/rx51-battery.txt new file mode 100644 index 000000000000..90438453db58 --- /dev/null +++ b/Documentation/devicetree/bindings/power/rx51-battery.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | Binding for Nokia N900 battery | ||
2 | |||
3 | The Nokia N900 battery status can be read via the TWL4030's A/D converter. | ||
4 | |||
5 | Required properties: | ||
6 | - compatible: Should contain one of the following: | ||
7 | * "nokia,n900-battery" | ||
8 | - io-channels: Should contain IIO channel specifiers | ||
9 | for each element in io-channel-names. | ||
10 | - io-channel-names: Should contain the following values: | ||
11 | * "temp" - The ADC channel for temperature reading | ||
12 | * "bsi" - The ADC channel for battery size identification | ||
13 | * "vbat" - The ADC channel to measure the battery voltage | ||
14 | |||
15 | Example from Nokia N900: | ||
16 | |||
17 | battery: n900-battery { | ||
18 | compatible = "nokia,n900-battery"; | ||
19 | io-channels = <&twl4030_madc 0>, | ||
20 | <&twl4030_madc 4>, | ||
21 | <&twl4030_madc 12>; | ||
22 | io-channel-names = "temp", | ||
23 | "bsi", | ||
24 | "vbat"; | ||
25 | }; | ||
diff --git a/Documentation/power/power_supply_class.txt b/Documentation/power/power_supply_class.txt index 89a8816990ff..48cff881cb8a 100644 --- a/Documentation/power/power_supply_class.txt +++ b/Documentation/power/power_supply_class.txt | |||
@@ -118,6 +118,10 @@ relative, time-based measurements. | |||
118 | CONSTANT_CHARGE_CURRENT - constant charge current programmed by charger. | 118 | CONSTANT_CHARGE_CURRENT - constant charge current programmed by charger. |
119 | CONSTANT_CHARGE_CURRENT_MAX - maximum charge current supported by the | 119 | CONSTANT_CHARGE_CURRENT_MAX - maximum charge current supported by the |
120 | power supply object. | 120 | power supply object. |
121 | INPUT_CURRENT_LIMIT - input current limit programmed by charger. Indicates | ||
122 | the current drawn from a charging source. | ||
123 | CHARGE_TERM_CURRENT - Charge termination current used to detect the end of charge | ||
124 | condition. | ||
121 | 125 | ||
122 | CONSTANT_CHARGE_VOLTAGE - constant charge voltage programmed by charger. | 126 | CONSTANT_CHARGE_VOLTAGE - constant charge voltage programmed by charger. |
123 | CONSTANT_CHARGE_VOLTAGE_MAX - maximum charge voltage supported by the | 127 | CONSTANT_CHARGE_VOLTAGE_MAX - maximum charge voltage supported by the |
@@ -140,6 +144,8 @@ TEMP_ALERT_MAX - maximum battery temperature alert. | |||
140 | TEMP_AMBIENT - ambient temperature. | 144 | TEMP_AMBIENT - ambient temperature. |
141 | TEMP_AMBIENT_ALERT_MIN - minimum ambient temperature alert. | 145 | TEMP_AMBIENT_ALERT_MIN - minimum ambient temperature alert. |
142 | TEMP_AMBIENT_ALERT_MAX - maximum ambient temperature alert. | 146 | TEMP_AMBIENT_ALERT_MAX - maximum ambient temperature alert. |
147 | TEMP_MIN - minimum operatable temperature | ||
148 | TEMP_MAX - maximum operatable temperature | ||
143 | 149 | ||
144 | TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e. | 150 | TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e. |
145 | while battery powers a load) | 151 | while battery powers a load) |
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index ba6975123071..73cfcdf28a36 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
@@ -137,6 +137,13 @@ config BATTERY_COLLIE | |||
137 | Say Y to enable support for the battery on the Sharp Zaurus | 137 | Say Y to enable support for the battery on the Sharp Zaurus |
138 | SL-5500 (collie) models. | 138 | SL-5500 (collie) models. |
139 | 139 | ||
140 | config BATTERY_IPAQ_MICRO | ||
141 | tristate "iPAQ Atmel Micro ASIC battery driver" | ||
142 | depends on MFD_IPAQ_MICRO | ||
143 | help | ||
144 | Choose this option if you want to monitor battery status on | ||
145 | Compaq/HP iPAQ h3100 and h3600. | ||
146 | |||
140 | config BATTERY_WM97XX | 147 | config BATTERY_WM97XX |
141 | bool "WM97xx generic battery driver" | 148 | bool "WM97xx generic battery driver" |
142 | depends on TOUCHSCREEN_WM97XX=y | 149 | depends on TOUCHSCREEN_WM97XX=y |
diff --git a/drivers/power/Makefile b/drivers/power/Makefile index ee54a3e4c90a..dfa894273926 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o | |||
25 | obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o | 25 | obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o |
26 | obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o | 26 | obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o |
27 | obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o | 27 | obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o |
28 | obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o | ||
28 | obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o | 29 | obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o |
29 | obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o | 30 | obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o |
30 | obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o | 31 | obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o |
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c index 79a37f6d3307..e384844a1ae1 100644 --- a/drivers/power/bq2415x_charger.c +++ b/drivers/power/bq2415x_charger.c | |||
@@ -840,8 +840,7 @@ static int bq2415x_notifier_call(struct notifier_block *nb, | |||
840 | if (bq->automode < 1) | 840 | if (bq->automode < 1) |
841 | return NOTIFY_OK; | 841 | return NOTIFY_OK; |
842 | 842 | ||
843 | sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode"); | 843 | schedule_delayed_work(&bq->work, 0); |
844 | bq2415x_set_mode(bq, bq->reported_mode); | ||
845 | 844 | ||
846 | return NOTIFY_OK; | 845 | return NOTIFY_OK; |
847 | } | 846 | } |
@@ -892,6 +891,11 @@ static void bq2415x_timer_work(struct work_struct *work) | |||
892 | int error; | 891 | int error; |
893 | int boost; | 892 | int boost; |
894 | 893 | ||
894 | if (bq->automode > 0 && (bq->reported_mode != bq->mode)) { | ||
895 | sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode"); | ||
896 | bq2415x_set_mode(bq, bq->reported_mode); | ||
897 | } | ||
898 | |||
895 | if (!bq->autotimer) | 899 | if (!bq->autotimer) |
896 | return; | 900 | return; |
897 | 901 | ||
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index b309713b63bc..e10763e3a1d5 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * http://www.ti.com/product/bq27425-g1 | 25 | * http://www.ti.com/product/bq27425-g1 |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/device.h> | ||
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
29 | #include <linux/param.h> | 30 | #include <linux/param.h> |
30 | #include <linux/jiffies.h> | 31 | #include <linux/jiffies.h> |
@@ -415,6 +416,9 @@ static void bq27x00_update(struct bq27x00_device_info *di) | |||
415 | bool is_bq27425 = di->chip == BQ27425; | 416 | bool is_bq27425 = di->chip == BQ27425; |
416 | 417 | ||
417 | cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500); | 418 | cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500); |
419 | if ((cache.flags & 0xff) == 0xff) | ||
420 | /* read error */ | ||
421 | cache.flags = -1; | ||
418 | if (cache.flags >= 0) { | 422 | if (cache.flags >= 0) { |
419 | if (!is_bq27500 && !is_bq27425 | 423 | if (!is_bq27500 && !is_bq27425 |
420 | && (cache.flags & BQ27000_FLAG_CI)) { | 424 | && (cache.flags & BQ27000_FLAG_CI)) { |
@@ -804,7 +808,7 @@ static int bq27x00_battery_probe(struct i2c_client *client, | |||
804 | goto batt_failed_1; | 808 | goto batt_failed_1; |
805 | } | 809 | } |
806 | 810 | ||
807 | di = kzalloc(sizeof(*di), GFP_KERNEL); | 811 | di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); |
808 | if (!di) { | 812 | if (!di) { |
809 | dev_err(&client->dev, "failed to allocate device info data\n"); | 813 | dev_err(&client->dev, "failed to allocate device info data\n"); |
810 | retval = -ENOMEM; | 814 | retval = -ENOMEM; |
@@ -819,14 +823,12 @@ static int bq27x00_battery_probe(struct i2c_client *client, | |||
819 | 823 | ||
820 | retval = bq27x00_powersupply_init(di); | 824 | retval = bq27x00_powersupply_init(di); |
821 | if (retval) | 825 | if (retval) |
822 | goto batt_failed_3; | 826 | goto batt_failed_2; |
823 | 827 | ||
824 | i2c_set_clientdata(client, di); | 828 | i2c_set_clientdata(client, di); |
825 | 829 | ||
826 | return 0; | 830 | return 0; |
827 | 831 | ||
828 | batt_failed_3: | ||
829 | kfree(di); | ||
830 | batt_failed_2: | 832 | batt_failed_2: |
831 | kfree(name); | 833 | kfree(name); |
832 | batt_failed_1: | 834 | batt_failed_1: |
@@ -849,8 +851,6 @@ static int bq27x00_battery_remove(struct i2c_client *client) | |||
849 | idr_remove(&battery_id, di->id); | 851 | idr_remove(&battery_id, di->id); |
850 | mutex_unlock(&battery_mutex); | 852 | mutex_unlock(&battery_mutex); |
851 | 853 | ||
852 | kfree(di); | ||
853 | |||
854 | return 0; | 854 | return 0; |
855 | } | 855 | } |
856 | 856 | ||
@@ -933,7 +933,6 @@ static int bq27000_battery_probe(struct platform_device *pdev) | |||
933 | { | 933 | { |
934 | struct bq27x00_device_info *di; | 934 | struct bq27x00_device_info *di; |
935 | struct bq27000_platform_data *pdata = pdev->dev.platform_data; | 935 | struct bq27000_platform_data *pdata = pdev->dev.platform_data; |
936 | int ret; | ||
937 | 936 | ||
938 | if (!pdata) { | 937 | if (!pdata) { |
939 | dev_err(&pdev->dev, "no platform_data supplied\n"); | 938 | dev_err(&pdev->dev, "no platform_data supplied\n"); |
@@ -945,7 +944,7 @@ static int bq27000_battery_probe(struct platform_device *pdev) | |||
945 | return -EINVAL; | 944 | return -EINVAL; |
946 | } | 945 | } |
947 | 946 | ||
948 | di = kzalloc(sizeof(*di), GFP_KERNEL); | 947 | di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); |
949 | if (!di) { | 948 | if (!di) { |
950 | dev_err(&pdev->dev, "failed to allocate device info data\n"); | 949 | dev_err(&pdev->dev, "failed to allocate device info data\n"); |
951 | return -ENOMEM; | 950 | return -ENOMEM; |
@@ -959,16 +958,7 @@ static int bq27000_battery_probe(struct platform_device *pdev) | |||
959 | di->bat.name = pdata->name ?: dev_name(&pdev->dev); | 958 | di->bat.name = pdata->name ?: dev_name(&pdev->dev); |
960 | di->bus.read = &bq27000_read_platform; | 959 | di->bus.read = &bq27000_read_platform; |
961 | 960 | ||
962 | ret = bq27x00_powersupply_init(di); | 961 | return bq27x00_powersupply_init(di); |
963 | if (ret) | ||
964 | goto err_free; | ||
965 | |||
966 | return 0; | ||
967 | |||
968 | err_free: | ||
969 | kfree(di); | ||
970 | |||
971 | return ret; | ||
972 | } | 962 | } |
973 | 963 | ||
974 | static int bq27000_battery_remove(struct platform_device *pdev) | 964 | static int bq27000_battery_remove(struct platform_device *pdev) |
@@ -977,8 +967,6 @@ static int bq27000_battery_remove(struct platform_device *pdev) | |||
977 | 967 | ||
978 | bq27x00_powersupply_unregister(di); | 968 | bq27x00_powersupply_unregister(di); |
979 | 969 | ||
980 | kfree(di); | ||
981 | |||
982 | return 0; | 970 | return 0; |
983 | } | 971 | } |
984 | 972 | ||
diff --git a/drivers/power/ipaq_micro_battery.c b/drivers/power/ipaq_micro_battery.c new file mode 100644 index 000000000000..9d694605cdb7 --- /dev/null +++ b/drivers/power/ipaq_micro_battery.c | |||
@@ -0,0 +1,290 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * h3xxx atmel micro companion support, battery subdevice | ||
7 | * based on previous kernel 2.4 version | ||
8 | * Author : Alessandro Gardich <gremlin@gremlin.it> | ||
9 | * Author : Linus Walleij <linus.walleij@linaro.org> | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/mfd/ipaq-micro.h> | ||
17 | #include <linux/power_supply.h> | ||
18 | #include <linux/workqueue.h> | ||
19 | |||
20 | #define BATT_PERIOD 100000 /* 100 seconds in milliseconds */ | ||
21 | |||
22 | #define MICRO_BATT_CHEM_ALKALINE 0x01 | ||
23 | #define MICRO_BATT_CHEM_NICD 0x02 | ||
24 | #define MICRO_BATT_CHEM_NIMH 0x03 | ||
25 | #define MICRO_BATT_CHEM_LION 0x04 | ||
26 | #define MICRO_BATT_CHEM_LIPOLY 0x05 | ||
27 | #define MICRO_BATT_CHEM_NOT_INSTALLED 0x06 | ||
28 | #define MICRO_BATT_CHEM_UNKNOWN 0xff | ||
29 | |||
30 | #define MICRO_BATT_STATUS_HIGH 0x01 | ||
31 | #define MICRO_BATT_STATUS_LOW 0x02 | ||
32 | #define MICRO_BATT_STATUS_CRITICAL 0x04 | ||
33 | #define MICRO_BATT_STATUS_CHARGING 0x08 | ||
34 | #define MICRO_BATT_STATUS_CHARGEMAIN 0x10 | ||
35 | #define MICRO_BATT_STATUS_DEAD 0x20 /* Battery will not charge */ | ||
36 | #define MICRO_BATT_STATUS_NOTINSTALLED 0x20 /* For expansion pack batteries */ | ||
37 | #define MICRO_BATT_STATUS_FULL 0x40 /* Battery fully charged */ | ||
38 | #define MICRO_BATT_STATUS_NOBATTERY 0x80 | ||
39 | #define MICRO_BATT_STATUS_UNKNOWN 0xff | ||
40 | |||
41 | struct micro_battery { | ||
42 | struct ipaq_micro *micro; | ||
43 | struct workqueue_struct *wq; | ||
44 | struct delayed_work update; | ||
45 | u8 ac; | ||
46 | u8 chemistry; | ||
47 | unsigned int voltage; | ||
48 | u16 temperature; | ||
49 | u8 flag; | ||
50 | }; | ||
51 | |||
52 | static void micro_battery_work(struct work_struct *work) | ||
53 | { | ||
54 | struct micro_battery *mb = container_of(work, | ||
55 | struct micro_battery, update.work); | ||
56 | struct ipaq_micro_msg msg_battery = { | ||
57 | .id = MSG_BATTERY, | ||
58 | }; | ||
59 | struct ipaq_micro_msg msg_sensor = { | ||
60 | .id = MSG_THERMAL_SENSOR, | ||
61 | }; | ||
62 | |||
63 | /* First send battery message */ | ||
64 | ipaq_micro_tx_msg_sync(mb->micro, &msg_battery); | ||
65 | if (msg_battery.rx_len < 4) | ||
66 | pr_info("ERROR"); | ||
67 | |||
68 | /* | ||
69 | * Returned message format: | ||
70 | * byte 0: 0x00 = Not plugged in | ||
71 | * 0x01 = AC adapter plugged in | ||
72 | * byte 1: chemistry | ||
73 | * byte 2: voltage LSB | ||
74 | * byte 3: voltage MSB | ||
75 | * byte 4: flags | ||
76 | * byte 5-9: same for battery 2 | ||
77 | */ | ||
78 | mb->ac = msg_battery.rx_data[0]; | ||
79 | mb->chemistry = msg_battery.rx_data[1]; | ||
80 | mb->voltage = ((((unsigned short)msg_battery.rx_data[3] << 8) + | ||
81 | msg_battery.rx_data[2]) * 5000L) * 1000 / 1024; | ||
82 | mb->flag = msg_battery.rx_data[4]; | ||
83 | |||
84 | if (msg_battery.rx_len == 9) | ||
85 | pr_debug("second battery ignored\n"); | ||
86 | |||
87 | /* Then read the sensor */ | ||
88 | ipaq_micro_tx_msg_sync(mb->micro, &msg_sensor); | ||
89 | mb->temperature = msg_sensor.rx_data[1] << 8 | msg_sensor.rx_data[0]; | ||
90 | |||
91 | queue_delayed_work(mb->wq, &mb->update, msecs_to_jiffies(BATT_PERIOD)); | ||
92 | } | ||
93 | |||
94 | static int get_capacity(struct power_supply *b) | ||
95 | { | ||
96 | struct micro_battery *mb = dev_get_drvdata(b->dev->parent); | ||
97 | |||
98 | switch (mb->flag & 0x07) { | ||
99 | case MICRO_BATT_STATUS_HIGH: | ||
100 | return 100; | ||
101 | break; | ||
102 | case MICRO_BATT_STATUS_LOW: | ||
103 | return 50; | ||
104 | break; | ||
105 | case MICRO_BATT_STATUS_CRITICAL: | ||
106 | return 5; | ||
107 | break; | ||
108 | default: | ||
109 | break; | ||
110 | } | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int get_status(struct power_supply *b) | ||
115 | { | ||
116 | struct micro_battery *mb = dev_get_drvdata(b->dev->parent); | ||
117 | |||
118 | if (mb->flag == MICRO_BATT_STATUS_UNKNOWN) | ||
119 | return POWER_SUPPLY_STATUS_UNKNOWN; | ||
120 | |||
121 | if (mb->flag & MICRO_BATT_STATUS_FULL) | ||
122 | return POWER_SUPPLY_STATUS_FULL; | ||
123 | |||
124 | if ((mb->flag & MICRO_BATT_STATUS_CHARGING) || | ||
125 | (mb->flag & MICRO_BATT_STATUS_CHARGEMAIN)) | ||
126 | return POWER_SUPPLY_STATUS_CHARGING; | ||
127 | |||
128 | return POWER_SUPPLY_STATUS_DISCHARGING; | ||
129 | } | ||
130 | |||
131 | static int micro_batt_get_property(struct power_supply *b, | ||
132 | enum power_supply_property psp, | ||
133 | union power_supply_propval *val) | ||
134 | { | ||
135 | struct micro_battery *mb = dev_get_drvdata(b->dev->parent); | ||
136 | |||
137 | switch (psp) { | ||
138 | case POWER_SUPPLY_PROP_TECHNOLOGY: | ||
139 | switch (mb->chemistry) { | ||
140 | case MICRO_BATT_CHEM_NICD: | ||
141 | val->intval = POWER_SUPPLY_TECHNOLOGY_NiCd; | ||
142 | break; | ||
143 | case MICRO_BATT_CHEM_NIMH: | ||
144 | val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH; | ||
145 | break; | ||
146 | case MICRO_BATT_CHEM_LION: | ||
147 | val->intval = POWER_SUPPLY_TECHNOLOGY_LION; | ||
148 | break; | ||
149 | case MICRO_BATT_CHEM_LIPOLY: | ||
150 | val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; | ||
151 | break; | ||
152 | default: | ||
153 | val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; | ||
154 | break; | ||
155 | }; | ||
156 | break; | ||
157 | case POWER_SUPPLY_PROP_STATUS: | ||
158 | val->intval = get_status(b); | ||
159 | break; | ||
160 | case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: | ||
161 | val->intval = 4700000; | ||
162 | break; | ||
163 | case POWER_SUPPLY_PROP_CAPACITY: | ||
164 | val->intval = get_capacity(b); | ||
165 | break; | ||
166 | case POWER_SUPPLY_PROP_TEMP: | ||
167 | val->intval = mb->temperature; | ||
168 | break; | ||
169 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
170 | val->intval = mb->voltage; | ||
171 | break; | ||
172 | default: | ||
173 | return -EINVAL; | ||
174 | }; | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int micro_ac_get_property(struct power_supply *b, | ||
180 | enum power_supply_property psp, | ||
181 | union power_supply_propval *val) | ||
182 | { | ||
183 | struct micro_battery *mb = dev_get_drvdata(b->dev->parent); | ||
184 | |||
185 | switch (psp) { | ||
186 | case POWER_SUPPLY_PROP_ONLINE: | ||
187 | val->intval = mb->ac; | ||
188 | break; | ||
189 | default: | ||
190 | return -EINVAL; | ||
191 | }; | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static enum power_supply_property micro_batt_power_props[] = { | ||
197 | POWER_SUPPLY_PROP_TECHNOLOGY, | ||
198 | POWER_SUPPLY_PROP_STATUS, | ||
199 | POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, | ||
200 | POWER_SUPPLY_PROP_CAPACITY, | ||
201 | POWER_SUPPLY_PROP_TEMP, | ||
202 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
203 | }; | ||
204 | |||
205 | static struct power_supply micro_batt_power = { | ||
206 | .name = "main-battery", | ||
207 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
208 | .properties = micro_batt_power_props, | ||
209 | .num_properties = ARRAY_SIZE(micro_batt_power_props), | ||
210 | .get_property = micro_batt_get_property, | ||
211 | .use_for_apm = 1, | ||
212 | }; | ||
213 | |||
214 | static enum power_supply_property micro_ac_power_props[] = { | ||
215 | POWER_SUPPLY_PROP_ONLINE, | ||
216 | }; | ||
217 | |||
218 | static struct power_supply micro_ac_power = { | ||
219 | .name = "ac", | ||
220 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
221 | .properties = micro_ac_power_props, | ||
222 | .num_properties = ARRAY_SIZE(micro_ac_power_props), | ||
223 | .get_property = micro_ac_get_property, | ||
224 | }; | ||
225 | |||
226 | static int micro_batt_probe(struct platform_device *pdev) | ||
227 | { | ||
228 | struct micro_battery *mb; | ||
229 | |||
230 | mb = devm_kzalloc(&pdev->dev, sizeof(*mb), GFP_KERNEL); | ||
231 | if (!mb) | ||
232 | return -ENOMEM; | ||
233 | |||
234 | mb->micro = dev_get_drvdata(pdev->dev.parent); | ||
235 | mb->wq = create_singlethread_workqueue("ipaq-battery-wq"); | ||
236 | INIT_DELAYED_WORK(&mb->update, micro_battery_work); | ||
237 | platform_set_drvdata(pdev, mb); | ||
238 | queue_delayed_work(mb->wq, &mb->update, 1); | ||
239 | power_supply_register(&pdev->dev, µ_batt_power); | ||
240 | power_supply_register(&pdev->dev, µ_ac_power); | ||
241 | |||
242 | dev_info(&pdev->dev, "iPAQ micro battery driver\n"); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int micro_batt_remove(struct platform_device *pdev) | ||
247 | |||
248 | { | ||
249 | struct micro_battery *mb = platform_get_drvdata(pdev); | ||
250 | |||
251 | power_supply_unregister(µ_ac_power); | ||
252 | power_supply_unregister(µ_batt_power); | ||
253 | cancel_delayed_work_sync(&mb->update); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int micro_batt_suspend(struct device *dev) | ||
259 | { | ||
260 | struct micro_battery *mb = dev_get_drvdata(dev); | ||
261 | |||
262 | cancel_delayed_work_sync(&mb->update); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int micro_batt_resume(struct device *dev) | ||
267 | { | ||
268 | struct micro_battery *mb = dev_get_drvdata(dev); | ||
269 | |||
270 | queue_delayed_work(mb->wq, &mb->update, msecs_to_jiffies(BATT_PERIOD)); | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static const struct dev_pm_ops micro_batt_dev_pm_ops = { | ||
275 | SET_SYSTEM_SLEEP_PM_OPS(micro_batt_suspend, micro_batt_resume) | ||
276 | }; | ||
277 | |||
278 | static struct platform_driver micro_batt_device_driver = { | ||
279 | .driver = { | ||
280 | .name = "ipaq-micro-battery", | ||
281 | .pm = µ_batt_dev_pm_ops, | ||
282 | }, | ||
283 | .probe = micro_batt_probe, | ||
284 | .remove = micro_batt_remove, | ||
285 | }; | ||
286 | module_platform_driver(micro_batt_device_driver); | ||
287 | |||
288 | MODULE_LICENSE("GPL"); | ||
289 | MODULE_DESCRIPTION("driver for iPAQ Atmel micro battery"); | ||
290 | MODULE_ALIAS("platform:battery-ipaq-micro"); | ||
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 5a5a24e7d43c..078afd61490d 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c | |||
@@ -537,7 +537,8 @@ static void psy_unregister_cooler(struct power_supply *psy) | |||
537 | } | 537 | } |
538 | #endif | 538 | #endif |
539 | 539 | ||
540 | int __power_supply_register(struct device *parent, struct power_supply *psy, bool ws) | 540 | static int __power_supply_register(struct device *parent, |
541 | struct power_supply *psy, bool ws) | ||
541 | { | 542 | { |
542 | struct device *dev; | 543 | struct device *dev; |
543 | int rc; | 544 | int rc; |
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 44420d1e9094..750a20275664 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c | |||
@@ -167,6 +167,7 @@ static struct device_attribute power_supply_attrs[] = { | |||
167 | POWER_SUPPLY_ATTR(constant_charge_voltage_max), | 167 | POWER_SUPPLY_ATTR(constant_charge_voltage_max), |
168 | POWER_SUPPLY_ATTR(charge_control_limit), | 168 | POWER_SUPPLY_ATTR(charge_control_limit), |
169 | POWER_SUPPLY_ATTR(charge_control_limit_max), | 169 | POWER_SUPPLY_ATTR(charge_control_limit_max), |
170 | POWER_SUPPLY_ATTR(input_current_limit), | ||
170 | POWER_SUPPLY_ATTR(energy_full_design), | 171 | POWER_SUPPLY_ATTR(energy_full_design), |
171 | POWER_SUPPLY_ATTR(energy_empty_design), | 172 | POWER_SUPPLY_ATTR(energy_empty_design), |
172 | POWER_SUPPLY_ATTR(energy_full), | 173 | POWER_SUPPLY_ATTR(energy_full), |
@@ -178,6 +179,8 @@ static struct device_attribute power_supply_attrs[] = { | |||
178 | POWER_SUPPLY_ATTR(capacity_alert_max), | 179 | POWER_SUPPLY_ATTR(capacity_alert_max), |
179 | POWER_SUPPLY_ATTR(capacity_level), | 180 | POWER_SUPPLY_ATTR(capacity_level), |
180 | POWER_SUPPLY_ATTR(temp), | 181 | POWER_SUPPLY_ATTR(temp), |
182 | POWER_SUPPLY_ATTR(temp_max), | ||
183 | POWER_SUPPLY_ATTR(temp_min), | ||
181 | POWER_SUPPLY_ATTR(temp_alert_min), | 184 | POWER_SUPPLY_ATTR(temp_alert_min), |
182 | POWER_SUPPLY_ATTR(temp_alert_max), | 185 | POWER_SUPPLY_ATTR(temp_alert_max), |
183 | POWER_SUPPLY_ATTR(temp_ambient), | 186 | POWER_SUPPLY_ATTR(temp_ambient), |
@@ -189,6 +192,7 @@ static struct device_attribute power_supply_attrs[] = { | |||
189 | POWER_SUPPLY_ATTR(time_to_full_avg), | 192 | POWER_SUPPLY_ATTR(time_to_full_avg), |
190 | POWER_SUPPLY_ATTR(type), | 193 | POWER_SUPPLY_ATTR(type), |
191 | POWER_SUPPLY_ATTR(scope), | 194 | POWER_SUPPLY_ATTR(scope), |
195 | POWER_SUPPLY_ATTR(charge_term_current), | ||
192 | /* Properties of type `const char *' */ | 196 | /* Properties of type `const char *' */ |
193 | POWER_SUPPLY_ATTR(model_name), | 197 | POWER_SUPPLY_ATTR(model_name), |
194 | POWER_SUPPLY_ATTR(manufacturer), | 198 | POWER_SUPPLY_ATTR(manufacturer), |
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index bdcf5173e377..f2ac54df496f 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig | |||
@@ -20,6 +20,17 @@ config POWER_RESET_AXXIA | |||
20 | 20 | ||
21 | Say Y if you have an Axxia family SoC. | 21 | Say Y if you have an Axxia family SoC. |
22 | 22 | ||
23 | config POWER_RESET_BRCMSTB | ||
24 | bool "Broadcom STB reset driver" if COMPILE_TEST | ||
25 | depends on POWER_RESET && ARM | ||
26 | default ARCH_BRCMSTB | ||
27 | help | ||
28 | This driver provides restart support for ARM-based Broadcom STB | ||
29 | boards. | ||
30 | |||
31 | Say Y here if you have an ARM-based Broadcom STB board and you wish | ||
32 | to have restart support. | ||
33 | |||
23 | config POWER_RESET_GPIO | 34 | config POWER_RESET_GPIO |
24 | bool "GPIO power-off driver" | 35 | bool "GPIO power-off driver" |
25 | depends on OF_GPIO && POWER_RESET | 36 | depends on OF_GPIO && POWER_RESET |
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index dde2e8bbac53..7379818ca69d 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o | 1 | obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o |
2 | obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o | 2 | obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o |
3 | obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o | ||
3 | obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o | 4 | obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o |
4 | obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o | 5 | obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o |
5 | obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o | 6 | obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o |
diff --git a/drivers/power/reset/brcmstb-reboot.c b/drivers/power/reset/brcmstb-reboot.c new file mode 100644 index 000000000000..3f236924742a --- /dev/null +++ b/drivers/power/reset/brcmstb-reboot.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/device.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/jiffies.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/of_irq.h> | ||
21 | #include <linux/of_platform.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/printk.h> | ||
24 | #include <linux/reboot.h> | ||
25 | #include <linux/regmap.h> | ||
26 | #include <linux/smp.h> | ||
27 | #include <linux/mfd/syscon.h> | ||
28 | |||
29 | #include <asm/system_misc.h> | ||
30 | |||
31 | #define RESET_SOURCE_ENABLE_REG 1 | ||
32 | #define SW_MASTER_RESET_REG 2 | ||
33 | |||
34 | static struct regmap *regmap; | ||
35 | static u32 rst_src_en; | ||
36 | static u32 sw_mstr_rst; | ||
37 | |||
38 | static void brcmstb_reboot(enum reboot_mode mode, const char *cmd) | ||
39 | { | ||
40 | int rc; | ||
41 | u32 tmp; | ||
42 | |||
43 | rc = regmap_write(regmap, rst_src_en, 1); | ||
44 | if (rc) { | ||
45 | pr_err("failed to write rst_src_en (%d)\n", rc); | ||
46 | return; | ||
47 | } | ||
48 | |||
49 | rc = regmap_read(regmap, rst_src_en, &tmp); | ||
50 | if (rc) { | ||
51 | pr_err("failed to read rst_src_en (%d)\n", rc); | ||
52 | return; | ||
53 | } | ||
54 | |||
55 | rc = regmap_write(regmap, sw_mstr_rst, 1); | ||
56 | if (rc) { | ||
57 | pr_err("failed to write sw_mstr_rst (%d)\n", rc); | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | rc = regmap_read(regmap, sw_mstr_rst, &tmp); | ||
62 | if (rc) { | ||
63 | pr_err("failed to read sw_mstr_rst (%d)\n", rc); | ||
64 | return; | ||
65 | } | ||
66 | |||
67 | while (1) | ||
68 | ; | ||
69 | } | ||
70 | |||
71 | static int brcmstb_reboot_probe(struct platform_device *pdev) | ||
72 | { | ||
73 | int rc; | ||
74 | struct device_node *np = pdev->dev.of_node; | ||
75 | |||
76 | regmap = syscon_regmap_lookup_by_phandle(np, "syscon"); | ||
77 | if (IS_ERR(regmap)) { | ||
78 | pr_err("failed to get syscon phandle\n"); | ||
79 | return -EINVAL; | ||
80 | } | ||
81 | |||
82 | rc = of_property_read_u32_index(np, "syscon", RESET_SOURCE_ENABLE_REG, | ||
83 | &rst_src_en); | ||
84 | if (rc) { | ||
85 | pr_err("can't get rst_src_en offset (%d)\n", rc); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | rc = of_property_read_u32_index(np, "syscon", SW_MASTER_RESET_REG, | ||
90 | &sw_mstr_rst); | ||
91 | if (rc) { | ||
92 | pr_err("can't get sw_mstr_rst offset (%d)\n", rc); | ||
93 | return -EINVAL; | ||
94 | } | ||
95 | |||
96 | arm_pm_restart = brcmstb_reboot; | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static const struct of_device_id of_match[] = { | ||
102 | { .compatible = "brcm,brcmstb-reboot", }, | ||
103 | {}, | ||
104 | }; | ||
105 | |||
106 | static struct platform_driver brcmstb_reboot_driver = { | ||
107 | .probe = brcmstb_reboot_probe, | ||
108 | .driver = { | ||
109 | .name = "brcmstb-reboot", | ||
110 | .owner = THIS_MODULE, | ||
111 | .of_match_table = of_match, | ||
112 | }, | ||
113 | }; | ||
114 | |||
115 | static int __init brcmstb_reboot_init(void) | ||
116 | { | ||
117 | return platform_driver_probe(&brcmstb_reboot_driver, | ||
118 | brcmstb_reboot_probe); | ||
119 | } | ||
120 | subsys_initcall(brcmstb_reboot_init); | ||
diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c index e290d48ddd99..ce849bc9b269 100644 --- a/drivers/power/reset/gpio-poweroff.c +++ b/drivers/power/reset/gpio-poweroff.c | |||
@@ -15,31 +15,29 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/gpio.h> | 18 | #include <linux/gpio/consumer.h> |
19 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
20 | #include <linux/of_gpio.h> | ||
21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
22 | 21 | ||
23 | /* | 22 | /* |
24 | * Hold configuration here, cannot be more than one instance of the driver | 23 | * Hold configuration here, cannot be more than one instance of the driver |
25 | * since pm_power_off itself is global. | 24 | * since pm_power_off itself is global. |
26 | */ | 25 | */ |
27 | static int gpio_num = -1; | 26 | static struct gpio_desc *reset_gpio; |
28 | static int gpio_active_low; | ||
29 | 27 | ||
30 | static void gpio_poweroff_do_poweroff(void) | 28 | static void gpio_poweroff_do_poweroff(void) |
31 | { | 29 | { |
32 | BUG_ON(!gpio_is_valid(gpio_num)); | 30 | BUG_ON(!reset_gpio); |
33 | 31 | ||
34 | /* drive it active, also inactive->active edge */ | 32 | /* drive it active, also inactive->active edge */ |
35 | gpio_direction_output(gpio_num, !gpio_active_low); | 33 | gpiod_direction_output(reset_gpio, 1); |
36 | mdelay(100); | 34 | mdelay(100); |
37 | /* drive inactive, also active->inactive edge */ | 35 | /* drive inactive, also active->inactive edge */ |
38 | gpio_set_value(gpio_num, gpio_active_low); | 36 | gpiod_set_value(reset_gpio, 0); |
39 | mdelay(100); | 37 | mdelay(100); |
40 | 38 | ||
41 | /* drive it active, also inactive->active edge */ | 39 | /* drive it active, also inactive->active edge */ |
42 | gpio_set_value(gpio_num, !gpio_active_low); | 40 | gpiod_set_value(reset_gpio, 1); |
43 | 41 | ||
44 | /* give it some time */ | 42 | /* give it some time */ |
45 | mdelay(3000); | 43 | mdelay(3000); |
@@ -49,54 +47,42 @@ static void gpio_poweroff_do_poweroff(void) | |||
49 | 47 | ||
50 | static int gpio_poweroff_probe(struct platform_device *pdev) | 48 | static int gpio_poweroff_probe(struct platform_device *pdev) |
51 | { | 49 | { |
52 | enum of_gpio_flags flags; | ||
53 | bool input = false; | 50 | bool input = false; |
54 | int ret; | ||
55 | 51 | ||
56 | /* If a pm_power_off function has already been added, leave it alone */ | 52 | /* If a pm_power_off function has already been added, leave it alone */ |
57 | if (pm_power_off != NULL) { | 53 | if (pm_power_off != NULL) { |
58 | pr_err("%s: pm_power_off function already registered", | 54 | dev_err(&pdev->dev, |
55 | "%s: pm_power_off function already registered", | ||
59 | __func__); | 56 | __func__); |
60 | return -EBUSY; | 57 | return -EBUSY; |
61 | } | 58 | } |
62 | 59 | ||
63 | gpio_num = of_get_gpio_flags(pdev->dev.of_node, 0, &flags); | 60 | reset_gpio = devm_gpiod_get(&pdev->dev, NULL); |
64 | if (!gpio_is_valid(gpio_num)) | 61 | if (IS_ERR(reset_gpio)) |
65 | return gpio_num; | 62 | return PTR_ERR(reset_gpio); |
66 | |||
67 | gpio_active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
68 | 63 | ||
69 | input = of_property_read_bool(pdev->dev.of_node, "input"); | 64 | input = of_property_read_bool(pdev->dev.of_node, "input"); |
70 | 65 | ||
71 | ret = gpio_request(gpio_num, "poweroff-gpio"); | ||
72 | if (ret) { | ||
73 | pr_err("%s: Could not get GPIO %d", __func__, gpio_num); | ||
74 | return ret; | ||
75 | } | ||
76 | if (input) { | 66 | if (input) { |
77 | if (gpio_direction_input(gpio_num)) { | 67 | if (gpiod_direction_input(reset_gpio)) { |
78 | pr_err("Could not set direction of GPIO %d to input", | 68 | dev_err(&pdev->dev, |
79 | gpio_num); | 69 | "Could not set direction of reset GPIO to input\n"); |
80 | goto err; | 70 | return -ENODEV; |
81 | } | 71 | } |
82 | } else { | 72 | } else { |
83 | if (gpio_direction_output(gpio_num, gpio_active_low)) { | 73 | if (gpiod_direction_output(reset_gpio, 0)) { |
84 | pr_err("Could not set direction of GPIO %d", gpio_num); | 74 | dev_err(&pdev->dev, |
85 | goto err; | 75 | "Could not set direction of reset GPIO\n"); |
76 | return -ENODEV; | ||
86 | } | 77 | } |
87 | } | 78 | } |
88 | 79 | ||
89 | pm_power_off = &gpio_poweroff_do_poweroff; | 80 | pm_power_off = &gpio_poweroff_do_poweroff; |
90 | return 0; | 81 | return 0; |
91 | |||
92 | err: | ||
93 | gpio_free(gpio_num); | ||
94 | return -ENODEV; | ||
95 | } | 82 | } |
96 | 83 | ||
97 | static int gpio_poweroff_remove(struct platform_device *pdev) | 84 | static int gpio_poweroff_remove(struct platform_device *pdev) |
98 | { | 85 | { |
99 | gpio_free(gpio_num); | ||
100 | if (pm_power_off == &gpio_poweroff_do_poweroff) | 86 | if (pm_power_off == &gpio_poweroff_do_poweroff) |
101 | pm_power_off = NULL; | 87 | pm_power_off = NULL; |
102 | 88 | ||
diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c index 5758033e0c16..3e51f8d29bfe 100644 --- a/drivers/power/reset/restart-poweroff.c +++ b/drivers/power/reset/restart-poweroff.c | |||
@@ -62,5 +62,5 @@ module_platform_driver(restart_poweroff_driver); | |||
62 | 62 | ||
63 | MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch"); | 63 | MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch"); |
64 | MODULE_DESCRIPTION("restart poweroff driver"); | 64 | MODULE_DESCRIPTION("restart poweroff driver"); |
65 | MODULE_LICENSE("GPLv2"); | 65 | MODULE_LICENSE("GPL v2"); |
66 | MODULE_ALIAS("platform:poweroff-restart"); | 66 | MODULE_ALIAS("platform:poweroff-restart"); |
diff --git a/drivers/power/rx51_battery.c b/drivers/power/rx51_battery.c index 1bc5857b8bd5..d5a2acfb8821 100644 --- a/drivers/power/rx51_battery.c +++ b/drivers/power/rx51_battery.c | |||
@@ -24,34 +24,27 @@ | |||
24 | #include <linux/power_supply.h> | 24 | #include <linux/power_supply.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/i2c/twl4030-madc.h> | 26 | #include <linux/i2c/twl4030-madc.h> |
27 | 27 | #include <linux/iio/consumer.h> | |
28 | /* RX51 specific channels */ | 28 | #include <linux/of.h> |
29 | #define TWL4030_MADC_BTEMP_RX51 TWL4030_MADC_ADCIN0 | ||
30 | #define TWL4030_MADC_BCI_RX51 TWL4030_MADC_ADCIN4 | ||
31 | 29 | ||
32 | struct rx51_device_info { | 30 | struct rx51_device_info { |
33 | struct device *dev; | 31 | struct device *dev; |
34 | struct power_supply bat; | 32 | struct power_supply bat; |
33 | struct iio_channel *channel_temp; | ||
34 | struct iio_channel *channel_bsi; | ||
35 | struct iio_channel *channel_vbat; | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Read ADCIN channel value, code copied from maemo kernel | 39 | * Read ADCIN channel value, code copied from maemo kernel |
39 | */ | 40 | */ |
40 | static int rx51_battery_read_adc(int channel) | 41 | static int rx51_battery_read_adc(struct iio_channel *channel) |
41 | { | 42 | { |
42 | struct twl4030_madc_request req; | 43 | int val, err; |
43 | 44 | err = iio_read_channel_average_raw(channel, &val); | |
44 | req.channels = channel; | 45 | if (err < 0) |
45 | req.do_avg = 1; | 46 | return err; |
46 | req.method = TWL4030_MADC_SW1; | 47 | return val; |
47 | req.func_cb = NULL; | ||
48 | req.type = TWL4030_MADC_WAIT; | ||
49 | req.raw = true; | ||
50 | |||
51 | if (twl4030_madc_conversion(&req) <= 0) | ||
52 | return -ENODATA; | ||
53 | |||
54 | return req.rbuf[ffs(channel) - 1]; | ||
55 | } | 48 | } |
56 | 49 | ||
57 | /* | 50 | /* |
@@ -60,10 +53,12 @@ static int rx51_battery_read_adc(int channel) | |||
60 | */ | 53 | */ |
61 | static int rx51_battery_read_voltage(struct rx51_device_info *di) | 54 | static int rx51_battery_read_voltage(struct rx51_device_info *di) |
62 | { | 55 | { |
63 | int voltage = rx51_battery_read_adc(TWL4030_MADC_VBAT); | 56 | int voltage = rx51_battery_read_adc(di->channel_vbat); |
64 | 57 | ||
65 | if (voltage < 0) | 58 | if (voltage < 0) { |
59 | dev_err(di->dev, "Could not read ADC: %d\n", voltage); | ||
66 | return voltage; | 60 | return voltage; |
61 | } | ||
67 | 62 | ||
68 | return 1000 * (10000 * voltage / 1705); | 63 | return 1000 * (10000 * voltage / 1705); |
69 | } | 64 | } |
@@ -112,7 +107,10 @@ static int rx51_battery_read_temperature(struct rx51_device_info *di) | |||
112 | { | 107 | { |
113 | int min = 0; | 108 | int min = 0; |
114 | int max = ARRAY_SIZE(rx51_temp_table2) - 1; | 109 | int max = ARRAY_SIZE(rx51_temp_table2) - 1; |
115 | int raw = rx51_battery_read_adc(TWL4030_MADC_BTEMP_RX51); | 110 | int raw = rx51_battery_read_adc(di->channel_temp); |
111 | |||
112 | if (raw < 0) | ||
113 | dev_err(di->dev, "Could not read ADC: %d\n", raw); | ||
116 | 114 | ||
117 | /* Zero and negative values are undefined */ | 115 | /* Zero and negative values are undefined */ |
118 | if (raw <= 0) | 116 | if (raw <= 0) |
@@ -146,10 +144,12 @@ static int rx51_battery_read_temperature(struct rx51_device_info *di) | |||
146 | */ | 144 | */ |
147 | static int rx51_battery_read_capacity(struct rx51_device_info *di) | 145 | static int rx51_battery_read_capacity(struct rx51_device_info *di) |
148 | { | 146 | { |
149 | int capacity = rx51_battery_read_adc(TWL4030_MADC_BCI_RX51); | 147 | int capacity = rx51_battery_read_adc(di->channel_bsi); |
150 | 148 | ||
151 | if (capacity < 0) | 149 | if (capacity < 0) { |
150 | dev_err(di->dev, "Could not read ADC: %d\n", capacity); | ||
152 | return capacity; | 151 | return capacity; |
152 | } | ||
153 | 153 | ||
154 | return 1280 * (1200 * capacity)/(1024 - capacity); | 154 | return 1280 * (1200 * capacity)/(1024 - capacity); |
155 | } | 155 | } |
@@ -213,17 +213,46 @@ static int rx51_battery_probe(struct platform_device *pdev) | |||
213 | 213 | ||
214 | platform_set_drvdata(pdev, di); | 214 | platform_set_drvdata(pdev, di); |
215 | 215 | ||
216 | di->dev = &pdev->dev; | ||
216 | di->bat.name = dev_name(&pdev->dev); | 217 | di->bat.name = dev_name(&pdev->dev); |
217 | di->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 218 | di->bat.type = POWER_SUPPLY_TYPE_BATTERY; |
218 | di->bat.properties = rx51_battery_props; | 219 | di->bat.properties = rx51_battery_props; |
219 | di->bat.num_properties = ARRAY_SIZE(rx51_battery_props); | 220 | di->bat.num_properties = ARRAY_SIZE(rx51_battery_props); |
220 | di->bat.get_property = rx51_battery_get_property; | 221 | di->bat.get_property = rx51_battery_get_property; |
221 | 222 | ||
223 | di->channel_temp = iio_channel_get(di->dev, "temp"); | ||
224 | if (IS_ERR(di->channel_temp)) { | ||
225 | ret = PTR_ERR(di->channel_temp); | ||
226 | goto error; | ||
227 | } | ||
228 | |||
229 | di->channel_bsi = iio_channel_get(di->dev, "bsi"); | ||
230 | if (IS_ERR(di->channel_bsi)) { | ||
231 | ret = PTR_ERR(di->channel_bsi); | ||
232 | goto error_channel_temp; | ||
233 | } | ||
234 | |||
235 | di->channel_vbat = iio_channel_get(di->dev, "vbat"); | ||
236 | if (IS_ERR(di->channel_vbat)) { | ||
237 | ret = PTR_ERR(di->channel_vbat); | ||
238 | goto error_channel_bsi; | ||
239 | } | ||
240 | |||
222 | ret = power_supply_register(di->dev, &di->bat); | 241 | ret = power_supply_register(di->dev, &di->bat); |
223 | if (ret) | 242 | if (ret) |
224 | return ret; | 243 | goto error_channel_vbat; |
225 | 244 | ||
226 | return 0; | 245 | return 0; |
246 | |||
247 | error_channel_vbat: | ||
248 | iio_channel_release(di->channel_vbat); | ||
249 | error_channel_bsi: | ||
250 | iio_channel_release(di->channel_bsi); | ||
251 | error_channel_temp: | ||
252 | iio_channel_release(di->channel_temp); | ||
253 | error: | ||
254 | |||
255 | return ret; | ||
227 | } | 256 | } |
228 | 257 | ||
229 | static int rx51_battery_remove(struct platform_device *pdev) | 258 | static int rx51_battery_remove(struct platform_device *pdev) |
@@ -232,15 +261,28 @@ static int rx51_battery_remove(struct platform_device *pdev) | |||
232 | 261 | ||
233 | power_supply_unregister(&di->bat); | 262 | power_supply_unregister(&di->bat); |
234 | 263 | ||
264 | iio_channel_release(di->channel_vbat); | ||
265 | iio_channel_release(di->channel_bsi); | ||
266 | iio_channel_release(di->channel_temp); | ||
267 | |||
235 | return 0; | 268 | return 0; |
236 | } | 269 | } |
237 | 270 | ||
271 | #ifdef CONFIG_OF | ||
272 | static const struct of_device_id n900_battery_of_match[] = { | ||
273 | {.compatible = "nokia,n900-battery", }, | ||
274 | { }, | ||
275 | }; | ||
276 | MODULE_DEVICE_TABLE(of, n900_battery_of_match); | ||
277 | #endif | ||
278 | |||
238 | static struct platform_driver rx51_battery_driver = { | 279 | static struct platform_driver rx51_battery_driver = { |
239 | .probe = rx51_battery_probe, | 280 | .probe = rx51_battery_probe, |
240 | .remove = rx51_battery_remove, | 281 | .remove = rx51_battery_remove, |
241 | .driver = { | 282 | .driver = { |
242 | .name = "rx51-battery", | 283 | .name = "rx51-battery", |
243 | .owner = THIS_MODULE, | 284 | .owner = THIS_MODULE, |
285 | .of_match_table = of_match_ptr(n900_battery_of_match), | ||
244 | }, | 286 | }, |
245 | }; | 287 | }; |
246 | module_platform_driver(rx51_battery_driver); | 288 | module_platform_driver(rx51_battery_driver); |
diff --git a/drivers/power/tps65090-charger.c b/drivers/power/tps65090-charger.c index 1685f63b9e5d..3e8ba97c8169 100644 --- a/drivers/power/tps65090-charger.c +++ b/drivers/power/tps65090-charger.c | |||
@@ -17,9 +17,11 @@ | |||
17 | */ | 17 | */ |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <linux/freezer.h> | ||
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/kthread.h> | ||
23 | #include <linux/module.h> | 25 | #include <linux/module.h> |
24 | #include <linux/of_device.h> | 26 | #include <linux/of_device.h> |
25 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
@@ -32,11 +34,15 @@ | |||
32 | #define TPS65090_VACG BIT(1) | 34 | #define TPS65090_VACG BIT(1) |
33 | #define TPS65090_NOITERM BIT(5) | 35 | #define TPS65090_NOITERM BIT(5) |
34 | 36 | ||
37 | #define POLL_INTERVAL (HZ * 2) /* Used when no irq */ | ||
38 | |||
35 | struct tps65090_charger { | 39 | struct tps65090_charger { |
36 | struct device *dev; | 40 | struct device *dev; |
37 | int ac_online; | 41 | int ac_online; |
38 | int prev_ac_online; | 42 | int prev_ac_online; |
39 | int irq; | 43 | int irq; |
44 | struct task_struct *poll_task; | ||
45 | bool passive_mode; | ||
40 | struct power_supply ac; | 46 | struct power_supply ac; |
41 | struct tps65090_platform_data *pdata; | 47 | struct tps65090_platform_data *pdata; |
42 | }; | 48 | }; |
@@ -49,6 +55,9 @@ static int tps65090_low_chrg_current(struct tps65090_charger *charger) | |||
49 | { | 55 | { |
50 | int ret; | 56 | int ret; |
51 | 57 | ||
58 | if (charger->passive_mode) | ||
59 | return 0; | ||
60 | |||
52 | ret = tps65090_write(charger->dev->parent, TPS65090_REG_CG_CTRL5, | 61 | ret = tps65090_write(charger->dev->parent, TPS65090_REG_CG_CTRL5, |
53 | TPS65090_NOITERM); | 62 | TPS65090_NOITERM); |
54 | if (ret < 0) { | 63 | if (ret < 0) { |
@@ -64,6 +73,9 @@ static int tps65090_enable_charging(struct tps65090_charger *charger) | |||
64 | int ret; | 73 | int ret; |
65 | uint8_t ctrl0 = 0; | 74 | uint8_t ctrl0 = 0; |
66 | 75 | ||
76 | if (charger->passive_mode) | ||
77 | return 0; | ||
78 | |||
67 | ret = tps65090_read(charger->dev->parent, TPS65090_REG_CG_CTRL0, | 79 | ret = tps65090_read(charger->dev->parent, TPS65090_REG_CG_CTRL0, |
68 | &ctrl0); | 80 | &ctrl0); |
69 | if (ret < 0) { | 81 | if (ret < 0) { |
@@ -87,6 +99,9 @@ static int tps65090_config_charger(struct tps65090_charger *charger) | |||
87 | uint8_t intrmask = 0; | 99 | uint8_t intrmask = 0; |
88 | int ret; | 100 | int ret; |
89 | 101 | ||
102 | if (charger->passive_mode) | ||
103 | return 0; | ||
104 | |||
90 | if (charger->pdata->enable_low_current_chrg) { | 105 | if (charger->pdata->enable_low_current_chrg) { |
91 | ret = tps65090_low_chrg_current(charger); | 106 | ret = tps65090_low_chrg_current(charger); |
92 | if (ret < 0) { | 107 | if (ret < 0) { |
@@ -164,10 +179,14 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id) | |||
164 | } | 179 | } |
165 | 180 | ||
166 | /* Clear interrupts. */ | 181 | /* Clear interrupts. */ |
167 | ret = tps65090_write(charger->dev->parent, TPS65090_REG_INTR_STS, 0x00); | 182 | if (!charger->passive_mode) { |
168 | if (ret < 0) { | 183 | ret = tps65090_write(charger->dev->parent, |
169 | dev_err(charger->dev, "%s(): Error in writing reg 0x%x\n", | 184 | TPS65090_REG_INTR_STS, 0x00); |
185 | if (ret < 0) { | ||
186 | dev_err(charger->dev, | ||
187 | "%s(): Error in writing reg 0x%x\n", | ||
170 | __func__, TPS65090_REG_INTR_STS); | 188 | __func__, TPS65090_REG_INTR_STS); |
189 | } | ||
171 | } | 190 | } |
172 | 191 | ||
173 | if (charger->prev_ac_online != charger->ac_online) | 192 | if (charger->prev_ac_online != charger->ac_online) |
@@ -198,6 +217,18 @@ static struct tps65090_platform_data * | |||
198 | 217 | ||
199 | } | 218 | } |
200 | 219 | ||
220 | static int tps65090_charger_poll_task(void *data) | ||
221 | { | ||
222 | set_freezable(); | ||
223 | |||
224 | while (!kthread_should_stop()) { | ||
225 | schedule_timeout_interruptible(POLL_INTERVAL); | ||
226 | try_to_freeze(); | ||
227 | tps65090_charger_isr(-1, data); | ||
228 | } | ||
229 | return 0; | ||
230 | } | ||
231 | |||
201 | static int tps65090_charger_probe(struct platform_device *pdev) | 232 | static int tps65090_charger_probe(struct platform_device *pdev) |
202 | { | 233 | { |
203 | struct tps65090_charger *cdata; | 234 | struct tps65090_charger *cdata; |
@@ -244,22 +275,10 @@ static int tps65090_charger_probe(struct platform_device *pdev) | |||
244 | } | 275 | } |
245 | 276 | ||
246 | irq = platform_get_irq(pdev, 0); | 277 | irq = platform_get_irq(pdev, 0); |
247 | if (irq <= 0) { | 278 | if (irq < 0) |
248 | dev_warn(&pdev->dev, "Unable to get charger irq = %d\n", irq); | 279 | irq = -ENXIO; |
249 | ret = irq; | ||
250 | goto fail_unregister_supply; | ||
251 | } | ||
252 | |||
253 | cdata->irq = irq; | 280 | cdata->irq = irq; |
254 | 281 | ||
255 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
256 | tps65090_charger_isr, 0, "tps65090-charger", cdata); | ||
257 | if (ret) { | ||
258 | dev_err(cdata->dev, "Unable to register irq %d err %d\n", irq, | ||
259 | ret); | ||
260 | goto fail_unregister_supply; | ||
261 | } | ||
262 | |||
263 | ret = tps65090_config_charger(cdata); | 282 | ret = tps65090_config_charger(cdata); |
264 | if (ret < 0) { | 283 | if (ret < 0) { |
265 | dev_err(&pdev->dev, "charger config failed, err %d\n", ret); | 284 | dev_err(&pdev->dev, "charger config failed, err %d\n", ret); |
@@ -285,6 +304,27 @@ static int tps65090_charger_probe(struct platform_device *pdev) | |||
285 | power_supply_changed(&cdata->ac); | 304 | power_supply_changed(&cdata->ac); |
286 | } | 305 | } |
287 | 306 | ||
307 | if (irq != -ENXIO) { | ||
308 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
309 | tps65090_charger_isr, 0, "tps65090-charger", cdata); | ||
310 | if (ret) { | ||
311 | dev_err(cdata->dev, | ||
312 | "Unable to register irq %d err %d\n", irq, | ||
313 | ret); | ||
314 | goto fail_unregister_supply; | ||
315 | } | ||
316 | } else { | ||
317 | cdata->poll_task = kthread_run(tps65090_charger_poll_task, | ||
318 | cdata, "ktps65090charger"); | ||
319 | cdata->passive_mode = true; | ||
320 | if (IS_ERR(cdata->poll_task)) { | ||
321 | ret = PTR_ERR(cdata->poll_task); | ||
322 | dev_err(cdata->dev, | ||
323 | "Unable to run kthread err %d\n", ret); | ||
324 | goto fail_unregister_supply; | ||
325 | } | ||
326 | } | ||
327 | |||
288 | return 0; | 328 | return 0; |
289 | 329 | ||
290 | fail_unregister_supply: | 330 | fail_unregister_supply: |
@@ -297,6 +337,8 @@ static int tps65090_charger_remove(struct platform_device *pdev) | |||
297 | { | 337 | { |
298 | struct tps65090_charger *cdata = platform_get_drvdata(pdev); | 338 | struct tps65090_charger *cdata = platform_get_drvdata(pdev); |
299 | 339 | ||
340 | if (cdata->irq == -ENXIO) | ||
341 | kthread_stop(cdata->poll_task); | ||
300 | power_supply_unregister(&cdata->ac); | 342 | power_supply_unregister(&cdata->ac); |
301 | 343 | ||
302 | return 0; | 344 | return 0; |
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index f14108844e1a..2598c588006e 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c | |||
@@ -28,10 +28,13 @@ | |||
28 | #define TWL4030_BCIICHG 0x08 | 28 | #define TWL4030_BCIICHG 0x08 |
29 | #define TWL4030_BCIVAC 0x0a | 29 | #define TWL4030_BCIVAC 0x0a |
30 | #define TWL4030_BCIVBUS 0x0c | 30 | #define TWL4030_BCIVBUS 0x0c |
31 | #define TWL4030_BCIMFSTS3 0x0F | ||
31 | #define TWL4030_BCIMFSTS4 0x10 | 32 | #define TWL4030_BCIMFSTS4 0x10 |
32 | #define TWL4030_BCICTL1 0x23 | 33 | #define TWL4030_BCICTL1 0x23 |
33 | #define TWL4030_BB_CFG 0x12 | 34 | #define TWL4030_BB_CFG 0x12 |
34 | 35 | ||
36 | #define TWL4030_BCIMFSTS1 0x01 | ||
37 | |||
35 | #define TWL4030_BCIAUTOWEN BIT(5) | 38 | #define TWL4030_BCIAUTOWEN BIT(5) |
36 | #define TWL4030_CONFIG_DONE BIT(4) | 39 | #define TWL4030_CONFIG_DONE BIT(4) |
37 | #define TWL4030_BCIAUTOUSB BIT(1) | 40 | #define TWL4030_BCIAUTOUSB BIT(1) |
@@ -52,6 +55,9 @@ | |||
52 | #define TWL4030_BBISEL_500uA 0x02 | 55 | #define TWL4030_BBISEL_500uA 0x02 |
53 | #define TWL4030_BBISEL_1000uA 0x03 | 56 | #define TWL4030_BBISEL_1000uA 0x03 |
54 | 57 | ||
58 | #define TWL4030_BATSTSPCHG BIT(2) | ||
59 | #define TWL4030_BATSTSMCHG BIT(6) | ||
60 | |||
55 | /* BCI interrupts */ | 61 | /* BCI interrupts */ |
56 | #define TWL4030_WOVF BIT(0) /* Watchdog overflow */ | 62 | #define TWL4030_WOVF BIT(0) /* Watchdog overflow */ |
57 | #define TWL4030_TMOVF BIT(1) /* Timer overflow */ | 63 | #define TWL4030_TMOVF BIT(1) /* Timer overflow */ |
@@ -145,6 +151,35 @@ static int twl4030bci_read_adc_val(u8 reg) | |||
145 | } | 151 | } |
146 | 152 | ||
147 | /* | 153 | /* |
154 | * Check if Battery Pack was present | ||
155 | */ | ||
156 | static int twl4030_is_battery_present(struct twl4030_bci *bci) | ||
157 | { | ||
158 | int ret; | ||
159 | u8 val = 0; | ||
160 | |||
161 | /* Battery presence in Main charge? */ | ||
162 | ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val, TWL4030_BCIMFSTS3); | ||
163 | if (ret) | ||
164 | return ret; | ||
165 | if (val & TWL4030_BATSTSMCHG) | ||
166 | return 0; | ||
167 | |||
168 | /* | ||
169 | * OK, It could be that bootloader did not enable main charger, | ||
170 | * pre-charge is h/w auto. So, Battery presence in Pre-charge? | ||
171 | */ | ||
172 | ret = twl_i2c_read_u8(TWL4030_MODULE_PRECHARGE, &val, | ||
173 | TWL4030_BCIMFSTS1); | ||
174 | if (ret) | ||
175 | return ret; | ||
176 | if (val & TWL4030_BATSTSPCHG) | ||
177 | return 0; | ||
178 | |||
179 | return -ENODEV; | ||
180 | } | ||
181 | |||
182 | /* | ||
148 | * Check if VBUS power is present | 183 | * Check if VBUS power is present |
149 | */ | 184 | */ |
150 | static int twl4030_bci_have_vbus(struct twl4030_bci *bci) | 185 | static int twl4030_bci_have_vbus(struct twl4030_bci *bci) |
@@ -541,8 +576,14 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
541 | bci->irq_chg = platform_get_irq(pdev, 0); | 576 | bci->irq_chg = platform_get_irq(pdev, 0); |
542 | bci->irq_bci = platform_get_irq(pdev, 1); | 577 | bci->irq_bci = platform_get_irq(pdev, 1); |
543 | 578 | ||
544 | platform_set_drvdata(pdev, bci); | 579 | /* Only proceed further *IF* battery is physically present */ |
580 | ret = twl4030_is_battery_present(bci); | ||
581 | if (ret) { | ||
582 | dev_crit(&pdev->dev, "Battery was not detected:%d\n", ret); | ||
583 | goto fail_no_battery; | ||
584 | } | ||
545 | 585 | ||
586 | platform_set_drvdata(pdev, bci); | ||
546 | bci->ac.name = "twl4030_ac"; | 587 | bci->ac.name = "twl4030_ac"; |
547 | bci->ac.type = POWER_SUPPLY_TYPE_MAINS; | 588 | bci->ac.type = POWER_SUPPLY_TYPE_MAINS; |
548 | bci->ac.properties = twl4030_charger_props; | 589 | bci->ac.properties = twl4030_charger_props; |
@@ -633,6 +674,7 @@ fail_chg_irq: | |||
633 | fail_register_usb: | 674 | fail_register_usb: |
634 | power_supply_unregister(&bci->ac); | 675 | power_supply_unregister(&bci->ac); |
635 | fail_register_ac: | 676 | fail_register_ac: |
677 | fail_no_battery: | ||
636 | kfree(bci); | 678 | kfree(bci); |
637 | 679 | ||
638 | return ret; | 680 | return ret; |
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index f2b76aeaf4e4..f3dea41dbcd2 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h | |||
@@ -120,6 +120,7 @@ enum power_supply_property { | |||
120 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, | 120 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, |
121 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, | 121 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, |
122 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, | 122 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, |
123 | POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, | ||
123 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, | 124 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, |
124 | POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN, | 125 | POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN, |
125 | POWER_SUPPLY_PROP_ENERGY_FULL, | 126 | POWER_SUPPLY_PROP_ENERGY_FULL, |
@@ -131,6 +132,8 @@ enum power_supply_property { | |||
131 | POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX, /* in percents! */ | 132 | POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX, /* in percents! */ |
132 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, | 133 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, |
133 | POWER_SUPPLY_PROP_TEMP, | 134 | POWER_SUPPLY_PROP_TEMP, |
135 | POWER_SUPPLY_PROP_TEMP_MAX, | ||
136 | POWER_SUPPLY_PROP_TEMP_MIN, | ||
134 | POWER_SUPPLY_PROP_TEMP_ALERT_MIN, | 137 | POWER_SUPPLY_PROP_TEMP_ALERT_MIN, |
135 | POWER_SUPPLY_PROP_TEMP_ALERT_MAX, | 138 | POWER_SUPPLY_PROP_TEMP_ALERT_MAX, |
136 | POWER_SUPPLY_PROP_TEMP_AMBIENT, | 139 | POWER_SUPPLY_PROP_TEMP_AMBIENT, |
@@ -142,6 +145,7 @@ enum power_supply_property { | |||
142 | POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, | 145 | POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, |
143 | POWER_SUPPLY_PROP_TYPE, /* use power_supply.type instead */ | 146 | POWER_SUPPLY_PROP_TYPE, /* use power_supply.type instead */ |
144 | POWER_SUPPLY_PROP_SCOPE, | 147 | POWER_SUPPLY_PROP_SCOPE, |
148 | POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, | ||
145 | /* Properties of type `const char *' */ | 149 | /* Properties of type `const char *' */ |
146 | POWER_SUPPLY_PROP_MODEL_NAME, | 150 | POWER_SUPPLY_PROP_MODEL_NAME, |
147 | POWER_SUPPLY_PROP_MANUFACTURER, | 151 | POWER_SUPPLY_PROP_MANUFACTURER, |