hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/acpi/dptf/dptf_power.c
....@@ -1,16 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * dptf_power: DPTF platform power driver
34 * Copyright (c) 2016, Intel Corporation.
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
- * more details.
13
- *
145 */
156
167 #include <linux/kernel.h>
....@@ -19,20 +10,26 @@
1910 #include <linux/platform_device.h>
2011
2112 /*
22
- * Presentation of attributes which are defined for INT3407. They are:
13
+ * Presentation of attributes which are defined for INT3407 and INT3532.
14
+ * They are:
2315 * PMAX : Maximum platform powe
2416 * PSRC : Platform power source
2517 * ARTG : Adapter rating
2618 * CTYP : Charger type
2719 * PBSS : Battery steady power
20
+ * PROP : Rest of worst case platform Power
21
+ * PBSS : Power Battery Steady State
22
+ * PBSS : Power Battery Steady State
23
+ * RBHF : High Frequency Impedance
24
+ * VBNL : Instantaneous No-Load Voltage
25
+ * CMPP : Current Discharge Capability
2826 */
2927 #define DPTF_POWER_SHOW(name, object) \
3028 static ssize_t name##_show(struct device *dev,\
3129 struct device_attribute *attr,\
3230 char *buf)\
3331 {\
34
- struct platform_device *pdev = to_platform_device(dev);\
35
- struct acpi_device *acpi_dev = platform_get_drvdata(pdev);\
32
+ struct acpi_device *acpi_dev = dev_get_drvdata(dev);\
3633 unsigned long long val;\
3734 acpi_status status;\
3835 \
....@@ -49,12 +46,42 @@
4946 DPTF_POWER_SHOW(adapter_rating_mw, ARTG)
5047 DPTF_POWER_SHOW(battery_steady_power_mw, PBSS)
5148 DPTF_POWER_SHOW(charger_type, CTYP)
49
+DPTF_POWER_SHOW(rest_of_platform_power_mw, PROP)
50
+DPTF_POWER_SHOW(max_steady_state_power_mw, PBSS)
51
+DPTF_POWER_SHOW(high_freq_impedance_mohm, RBHF)
52
+DPTF_POWER_SHOW(no_load_voltage_mv, VBNL)
53
+DPTF_POWER_SHOW(current_discharge_capbility_ma, CMPP);
5254
5355 static DEVICE_ATTR_RO(max_platform_power_mw);
5456 static DEVICE_ATTR_RO(platform_power_source);
5557 static DEVICE_ATTR_RO(adapter_rating_mw);
5658 static DEVICE_ATTR_RO(battery_steady_power_mw);
5759 static DEVICE_ATTR_RO(charger_type);
60
+static DEVICE_ATTR_RO(rest_of_platform_power_mw);
61
+static DEVICE_ATTR_RO(max_steady_state_power_mw);
62
+static DEVICE_ATTR_RO(high_freq_impedance_mohm);
63
+static DEVICE_ATTR_RO(no_load_voltage_mv);
64
+static DEVICE_ATTR_RO(current_discharge_capbility_ma);
65
+
66
+static ssize_t prochot_confirm_store(struct device *dev,
67
+ struct device_attribute *attr,
68
+ const char *buf, size_t count)
69
+{
70
+ struct acpi_device *acpi_dev = dev_get_drvdata(dev);
71
+ acpi_status status;
72
+ int seq_no;
73
+
74
+ if (kstrtouint(buf, 0, &seq_no) < 0)
75
+ return -EINVAL;
76
+
77
+ status = acpi_execute_simple_method(acpi_dev->handle, "PBOK", seq_no);
78
+ if (ACPI_SUCCESS(status))
79
+ return count;
80
+
81
+ return -EINVAL;
82
+}
83
+
84
+static DEVICE_ATTR_WO(prochot_confirm);
5885
5986 static struct attribute *dptf_power_attrs[] = {
6087 &dev_attr_max_platform_power_mw.attr,
....@@ -62,6 +89,8 @@
6289 &dev_attr_adapter_rating_mw.attr,
6390 &dev_attr_battery_steady_power_mw.attr,
6491 &dev_attr_charger_type.attr,
92
+ &dev_attr_rest_of_platform_power_mw.attr,
93
+ &dev_attr_prochot_confirm.attr,
6594 NULL
6695 };
6796
....@@ -70,10 +99,79 @@
7099 .name = "dptf_power"
71100 };
72101
102
+static struct attribute *dptf_battery_attrs[] = {
103
+ &dev_attr_max_platform_power_mw.attr,
104
+ &dev_attr_max_steady_state_power_mw.attr,
105
+ &dev_attr_high_freq_impedance_mohm.attr,
106
+ &dev_attr_no_load_voltage_mv.attr,
107
+ &dev_attr_current_discharge_capbility_ma.attr,
108
+ NULL
109
+};
110
+
111
+static const struct attribute_group dptf_battery_attribute_group = {
112
+ .attrs = dptf_battery_attrs,
113
+ .name = "dptf_battery"
114
+};
115
+
116
+#define MAX_POWER_CHANGED 0x80
117
+#define POWER_STATE_CHANGED 0x81
118
+#define STEADY_STATE_POWER_CHANGED 0x83
119
+#define POWER_PROP_CHANGE_EVENT 0x84
120
+#define IMPEDANCED_CHNGED 0x85
121
+#define VOLTAGE_CURRENT_CHANGED 0x86
122
+
123
+static long long dptf_participant_type(acpi_handle handle)
124
+{
125
+ unsigned long long ptype;
126
+ acpi_status status;
127
+
128
+ status = acpi_evaluate_integer(handle, "PTYP", NULL, &ptype);
129
+ if (ACPI_FAILURE(status))
130
+ return -ENODEV;
131
+
132
+ return ptype;
133
+}
134
+
135
+static void dptf_power_notify(acpi_handle handle, u32 event, void *data)
136
+{
137
+ struct platform_device *pdev = data;
138
+ char *attr;
139
+
140
+ switch (event) {
141
+ case POWER_STATE_CHANGED:
142
+ attr = "platform_power_source";
143
+ break;
144
+ case POWER_PROP_CHANGE_EVENT:
145
+ attr = "rest_of_platform_power_mw";
146
+ break;
147
+ case MAX_POWER_CHANGED:
148
+ attr = "max_platform_power_mw";
149
+ break;
150
+ case STEADY_STATE_POWER_CHANGED:
151
+ attr = "max_steady_state_power_mw";
152
+ break;
153
+ case VOLTAGE_CURRENT_CHANGED:
154
+ attr = "no_load_voltage_mv";
155
+ break;
156
+ default:
157
+ dev_err(&pdev->dev, "Unsupported event [0x%x]\n", event);
158
+ return;
159
+ }
160
+
161
+ /*
162
+ * Notify that an attribute is changed, so that user space can read
163
+ * again.
164
+ */
165
+ if (dptf_participant_type(handle) == 0x0CULL)
166
+ sysfs_notify(&pdev->dev.kobj, "dptf_battery", attr);
167
+ else
168
+ sysfs_notify(&pdev->dev.kobj, "dptf_power", attr);
169
+}
170
+
73171 static int dptf_power_add(struct platform_device *pdev)
74172 {
173
+ const struct attribute_group *attr_group;
75174 struct acpi_device *acpi_dev;
76
- acpi_status status;
77175 unsigned long long ptype;
78176 int result;
79177
....@@ -81,17 +179,29 @@
81179 if (!acpi_dev)
82180 return -ENODEV;
83181
84
- status = acpi_evaluate_integer(acpi_dev->handle, "PTYP", NULL, &ptype);
85
- if (ACPI_FAILURE(status))
182
+ ptype = dptf_participant_type(acpi_dev->handle);
183
+ if (ptype == 0x11)
184
+ attr_group = &dptf_power_attribute_group;
185
+ else if (ptype == 0x0C)
186
+ attr_group = &dptf_battery_attribute_group;
187
+ else
86188 return -ENODEV;
87189
88
- if (ptype != 0x11)
89
- return -ENODEV;
90
-
91
- result = sysfs_create_group(&pdev->dev.kobj,
92
- &dptf_power_attribute_group);
190
+ result = acpi_install_notify_handler(acpi_dev->handle,
191
+ ACPI_DEVICE_NOTIFY,
192
+ dptf_power_notify,
193
+ (void *)pdev);
93194 if (result)
94195 return result;
196
+
197
+ result = sysfs_create_group(&pdev->dev.kobj,
198
+ attr_group);
199
+ if (result) {
200
+ acpi_remove_notify_handler(acpi_dev->handle,
201
+ ACPI_DEVICE_NOTIFY,
202
+ dptf_power_notify);
203
+ return result;
204
+ }
95205
96206 platform_set_drvdata(pdev, acpi_dev);
97207
....@@ -100,14 +210,27 @@
100210
101211 static int dptf_power_remove(struct platform_device *pdev)
102212 {
213
+ struct acpi_device *acpi_dev = platform_get_drvdata(pdev);
103214
104
- sysfs_remove_group(&pdev->dev.kobj, &dptf_power_attribute_group);
215
+ acpi_remove_notify_handler(acpi_dev->handle,
216
+ ACPI_DEVICE_NOTIFY,
217
+ dptf_power_notify);
218
+
219
+ if (dptf_participant_type(acpi_dev->handle) == 0x0CULL)
220
+ sysfs_remove_group(&pdev->dev.kobj, &dptf_battery_attribute_group);
221
+ else
222
+ sysfs_remove_group(&pdev->dev.kobj, &dptf_power_attribute_group);
105223
106224 return 0;
107225 }
108226
109227 static const struct acpi_device_id int3407_device_ids[] = {
110228 {"INT3407", 0},
229
+ {"INT3532", 0},
230
+ {"INTC1047", 0},
231
+ {"INTC1050", 0},
232
+ {"INTC1060", 0},
233
+ {"INTC1061", 0},
111234 {"", 0},
112235 };
113236 MODULE_DEVICE_TABLE(acpi, int3407_device_ids);
....@@ -116,7 +239,7 @@
116239 .probe = dptf_power_add,
117240 .remove = dptf_power_remove,
118241 .driver = {
119
- .name = "DPTF Platform Power",
242
+ .name = "dptf_power",
120243 .acpi_match_table = int3407_device_ids,
121244 },
122245 };