1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * acpi_fan.c - ACPI Fan Driver ($Revision: 29 $)
5 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
6 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/types.h>
13 #include <linux/uaccess.h>
14 #include <linux/thermal.h>
15 #include <linux/acpi.h>
16 #include <linux/platform_device.h>
17 #include <linux/sort.h>
21 MODULE_AUTHOR("Paul Diefenbaugh");
22 MODULE_DESCRIPTION("ACPI Fan Driver");
23 MODULE_LICENSE("GPL");
25 static int acpi_fan_probe(struct platform_device
*pdev
);
26 static int acpi_fan_remove(struct platform_device
*pdev
);
28 static const struct acpi_device_id fan_device_ids
[] = {
32 MODULE_DEVICE_TABLE(acpi
, fan_device_ids
);
34 #ifdef CONFIG_PM_SLEEP
35 static int acpi_fan_suspend(struct device
*dev
);
36 static int acpi_fan_resume(struct device
*dev
);
37 static const struct dev_pm_ops acpi_fan_pm
= {
38 .resume
= acpi_fan_resume
,
39 .freeze
= acpi_fan_suspend
,
40 .thaw
= acpi_fan_resume
,
41 .restore
= acpi_fan_resume
,
43 #define FAN_PM_OPS_PTR (&acpi_fan_pm)
45 #define FAN_PM_OPS_PTR NULL
48 #define ACPI_FPS_NAME_LEN 20
56 char name
[ACPI_FPS_NAME_LEN
];
57 struct device_attribute dev_attr
;
64 u64 low_speed_notification
;
69 struct acpi_fan_fif fif
;
70 struct acpi_fan_fps
*fps
;
72 struct thermal_cooling_device
*cdev
;
75 static struct platform_driver acpi_fan_driver
= {
76 .probe
= acpi_fan_probe
,
77 .remove
= acpi_fan_remove
,
80 .acpi_match_table
= fan_device_ids
,
85 /* thermal cooling device callbacks */
86 static int fan_get_max_state(struct thermal_cooling_device
*cdev
, unsigned long
89 struct acpi_device
*device
= cdev
->devdata
;
90 struct acpi_fan
*fan
= acpi_driver_data(device
);
93 *state
= fan
->fps_count
- 1;
99 static int fan_get_state_acpi4(struct acpi_device
*device
, unsigned long *state
)
101 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
102 struct acpi_fan
*fan
= acpi_driver_data(device
);
103 union acpi_object
*obj
;
107 status
= acpi_evaluate_object(device
->handle
, "_FST", NULL
, &buffer
);
108 if (ACPI_FAILURE(status
)) {
109 dev_err(&device
->dev
, "Get fan state failed\n");
113 obj
= buffer
.pointer
;
114 if (!obj
|| obj
->type
!= ACPI_TYPE_PACKAGE
||
115 obj
->package
.count
!= 3 ||
116 obj
->package
.elements
[1].type
!= ACPI_TYPE_INTEGER
) {
117 dev_err(&device
->dev
, "Invalid _FST data\n");
122 control
= obj
->package
.elements
[1].integer
.value
;
123 for (i
= 0; i
< fan
->fps_count
; i
++) {
125 * When Fine Grain Control is set, return the state
126 * corresponding to maximum fan->fps[i].control
127 * value compared to the current speed. Here the
128 * fan->fps[] is sorted array with increasing speed.
130 if (fan
->fif
.fine_grain_ctrl
&& control
< fan
->fps
[i
].control
) {
131 i
= (i
> 0) ? i
- 1 : 0;
133 } else if (control
== fan
->fps
[i
].control
) {
137 if (i
== fan
->fps_count
) {
138 dev_dbg(&device
->dev
, "Invalid control value returned\n");
150 static int fan_get_state(struct acpi_device
*device
, unsigned long *state
)
153 int acpi_state
= ACPI_STATE_D0
;
155 result
= acpi_device_update_power(device
, &acpi_state
);
159 *state
= acpi_state
== ACPI_STATE_D3_COLD
160 || acpi_state
== ACPI_STATE_D3_HOT
?
161 0 : (acpi_state
== ACPI_STATE_D0
? 1 : -1);
165 static int fan_get_cur_state(struct thermal_cooling_device
*cdev
, unsigned long
168 struct acpi_device
*device
= cdev
->devdata
;
169 struct acpi_fan
*fan
= acpi_driver_data(device
);
172 return fan_get_state_acpi4(device
, state
);
174 return fan_get_state(device
, state
);
177 static int fan_set_state(struct acpi_device
*device
, unsigned long state
)
179 if (state
!= 0 && state
!= 1)
182 return acpi_device_set_power(device
,
183 state
? ACPI_STATE_D0
: ACPI_STATE_D3_COLD
);
186 static int fan_set_state_acpi4(struct acpi_device
*device
, unsigned long state
)
188 struct acpi_fan
*fan
= acpi_driver_data(device
);
191 if (state
>= fan
->fps_count
)
194 status
= acpi_execute_simple_method(device
->handle
, "_FSL",
195 fan
->fps
[state
].control
);
196 if (ACPI_FAILURE(status
)) {
197 dev_dbg(&device
->dev
, "Failed to set state by _FSL\n");
205 fan_set_cur_state(struct thermal_cooling_device
*cdev
, unsigned long state
)
207 struct acpi_device
*device
= cdev
->devdata
;
208 struct acpi_fan
*fan
= acpi_driver_data(device
);
211 return fan_set_state_acpi4(device
, state
);
213 return fan_set_state(device
, state
);
216 static const struct thermal_cooling_device_ops fan_cooling_ops
= {
217 .get_max_state
= fan_get_max_state
,
218 .get_cur_state
= fan_get_cur_state
,
219 .set_cur_state
= fan_set_cur_state
,
222 /* --------------------------------------------------------------------------
224 * --------------------------------------------------------------------------
227 static bool acpi_fan_is_acpi4(struct acpi_device
*device
)
229 return acpi_has_method(device
->handle
, "_FIF") &&
230 acpi_has_method(device
->handle
, "_FPS") &&
231 acpi_has_method(device
->handle
, "_FSL") &&
232 acpi_has_method(device
->handle
, "_FST");
235 static int acpi_fan_get_fif(struct acpi_device
*device
)
237 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
238 struct acpi_fan
*fan
= acpi_driver_data(device
);
239 struct acpi_buffer format
= { sizeof("NNNN"), "NNNN" };
240 struct acpi_buffer fif
= { sizeof(fan
->fif
), &fan
->fif
};
241 union acpi_object
*obj
;
244 status
= acpi_evaluate_object(device
->handle
, "_FIF", NULL
, &buffer
);
245 if (ACPI_FAILURE(status
))
248 obj
= buffer
.pointer
;
249 if (!obj
|| obj
->type
!= ACPI_TYPE_PACKAGE
) {
250 dev_err(&device
->dev
, "Invalid _FIF data\n");
255 status
= acpi_extract_package(obj
, &format
, &fif
);
256 if (ACPI_FAILURE(status
)) {
257 dev_err(&device
->dev
, "Invalid _FIF element\n");
266 static int acpi_fan_speed_cmp(const void *a
, const void *b
)
268 const struct acpi_fan_fps
*fps1
= a
;
269 const struct acpi_fan_fps
*fps2
= b
;
270 return fps1
->speed
- fps2
->speed
;
273 static ssize_t
show_state(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
275 struct acpi_fan_fps
*fps
= container_of(attr
, struct acpi_fan_fps
, dev_attr
);
278 if (fps
->control
== 0xFFFFFFFF || fps
->control
> 100)
279 count
= scnprintf(buf
, PAGE_SIZE
, "not-defined:");
281 count
= scnprintf(buf
, PAGE_SIZE
, "%lld:", fps
->control
);
283 if (fps
->trip_point
== 0xFFFFFFFF || fps
->trip_point
> 9)
284 count
+= scnprintf(&buf
[count
], PAGE_SIZE
- count
, "not-defined:");
286 count
+= scnprintf(&buf
[count
], PAGE_SIZE
- count
, "%lld:", fps
->trip_point
);
288 if (fps
->speed
== 0xFFFFFFFF)
289 count
+= scnprintf(&buf
[count
], PAGE_SIZE
- count
, "not-defined:");
291 count
+= scnprintf(&buf
[count
], PAGE_SIZE
- count
, "%lld:", fps
->speed
);
293 if (fps
->noise_level
== 0xFFFFFFFF)
294 count
+= scnprintf(&buf
[count
], PAGE_SIZE
- count
, "not-defined:");
296 count
+= scnprintf(&buf
[count
], PAGE_SIZE
- count
, "%lld:", fps
->noise_level
* 100);
298 if (fps
->power
== 0xFFFFFFFF)
299 count
+= scnprintf(&buf
[count
], PAGE_SIZE
- count
, "not-defined\n");
301 count
+= scnprintf(&buf
[count
], PAGE_SIZE
- count
, "%lld\n", fps
->power
);
306 static int acpi_fan_get_fps(struct acpi_device
*device
)
308 struct acpi_fan
*fan
= acpi_driver_data(device
);
309 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
310 union acpi_object
*obj
;
314 status
= acpi_evaluate_object(device
->handle
, "_FPS", NULL
, &buffer
);
315 if (ACPI_FAILURE(status
))
318 obj
= buffer
.pointer
;
319 if (!obj
|| obj
->type
!= ACPI_TYPE_PACKAGE
|| obj
->package
.count
< 2) {
320 dev_err(&device
->dev
, "Invalid _FPS data\n");
325 fan
->fps_count
= obj
->package
.count
- 1; /* minus revision field */
326 fan
->fps
= devm_kcalloc(&device
->dev
,
327 fan
->fps_count
, sizeof(struct acpi_fan_fps
),
330 dev_err(&device
->dev
, "Not enough memory\n");
334 for (i
= 0; i
< fan
->fps_count
; i
++) {
335 struct acpi_buffer format
= { sizeof("NNNNN"), "NNNNN" };
336 struct acpi_buffer fps
= { offsetof(struct acpi_fan_fps
, name
),
338 status
= acpi_extract_package(&obj
->package
.elements
[i
+ 1],
340 if (ACPI_FAILURE(status
)) {
341 dev_err(&device
->dev
, "Invalid _FPS element\n");
346 /* sort the state array according to fan speed in increase order */
347 sort(fan
->fps
, fan
->fps_count
, sizeof(*fan
->fps
),
348 acpi_fan_speed_cmp
, NULL
);
350 for (i
= 0; i
< fan
->fps_count
; ++i
) {
351 struct acpi_fan_fps
*fps
= &fan
->fps
[i
];
353 snprintf(fps
->name
, ACPI_FPS_NAME_LEN
, "state%d", i
);
354 sysfs_attr_init(&fps
->dev_attr
.attr
);
355 fps
->dev_attr
.show
= show_state
;
356 fps
->dev_attr
.store
= NULL
;
357 fps
->dev_attr
.attr
.name
= fps
->name
;
358 fps
->dev_attr
.attr
.mode
= 0444;
359 status
= sysfs_create_file(&device
->dev
.kobj
, &fps
->dev_attr
.attr
);
363 for (j
= 0; j
< i
; ++j
)
364 sysfs_remove_file(&device
->dev
.kobj
, &fan
->fps
[j
].dev_attr
.attr
);
374 static int acpi_fan_probe(struct platform_device
*pdev
)
377 struct thermal_cooling_device
*cdev
;
378 struct acpi_fan
*fan
;
379 struct acpi_device
*device
= ACPI_COMPANION(&pdev
->dev
);
382 fan
= devm_kzalloc(&pdev
->dev
, sizeof(*fan
), GFP_KERNEL
);
384 dev_err(&device
->dev
, "No memory for fan\n");
387 device
->driver_data
= fan
;
388 platform_set_drvdata(pdev
, fan
);
390 if (acpi_fan_is_acpi4(device
)) {
391 result
= acpi_fan_get_fif(device
);
395 result
= acpi_fan_get_fps(device
);
401 result
= acpi_device_update_power(device
, NULL
);
403 dev_err(&device
->dev
, "Failed to set initial power state\n");
408 if (!strncmp(pdev
->name
, "PNP0C0B", strlen("PNP0C0B")))
411 name
= acpi_device_bid(device
);
413 cdev
= thermal_cooling_device_register(name
, device
,
416 result
= PTR_ERR(cdev
);
420 dev_dbg(&pdev
->dev
, "registered as cooling_device%d\n", cdev
->id
);
423 result
= sysfs_create_link(&pdev
->dev
.kobj
,
427 dev_err(&pdev
->dev
, "Failed to create sysfs link 'thermal_cooling'\n");
429 result
= sysfs_create_link(&cdev
->device
.kobj
,
433 dev_err(&pdev
->dev
, "Failed to create sysfs link 'device'\n");
443 for (i
= 0; i
< fan
->fps_count
; ++i
)
444 sysfs_remove_file(&device
->dev
.kobj
, &fan
->fps
[i
].dev_attr
.attr
);
450 static int acpi_fan_remove(struct platform_device
*pdev
)
452 struct acpi_fan
*fan
= platform_get_drvdata(pdev
);
455 struct acpi_device
*device
= ACPI_COMPANION(&pdev
->dev
);
458 for (i
= 0; i
< fan
->fps_count
; ++i
)
459 sysfs_remove_file(&device
->dev
.kobj
, &fan
->fps
[i
].dev_attr
.attr
);
461 sysfs_remove_link(&pdev
->dev
.kobj
, "thermal_cooling");
462 sysfs_remove_link(&fan
->cdev
->device
.kobj
, "device");
463 thermal_cooling_device_unregister(fan
->cdev
);
468 #ifdef CONFIG_PM_SLEEP
469 static int acpi_fan_suspend(struct device
*dev
)
471 struct acpi_fan
*fan
= dev_get_drvdata(dev
);
475 acpi_device_set_power(ACPI_COMPANION(dev
), ACPI_STATE_D0
);
480 static int acpi_fan_resume(struct device
*dev
)
483 struct acpi_fan
*fan
= dev_get_drvdata(dev
);
488 result
= acpi_device_update_power(ACPI_COMPANION(dev
), NULL
);
490 dev_err(dev
, "Error updating fan power state\n");
496 module_platform_driver(acpi_fan_driver
);