Skip to content

Commit 9ef08d7

Browse files
committed
Thermal: int3406_thermal: fix thermal sysfs I/F
there are three concepts represent backlight in int3406_thermal driver. 1. the raw brightness value from native graphics driver. 2. the percentage numbers from ACPI _BCL control method. 3. the consecutive numbers represent cooling states. int3406_thermal driver 1. uses value from DDDL/DDPC as the lower/upper limit, which is consistent with ACPI _BCL control methods. 2. reads current and maximum brightness from the native graphics driver. 3. expose them to thermal sysfs I/F This patch fixes the code that switches between the raw brightness value and the cooling state, which results in bogus value in thermal sysfs I/F. Signed-off-by: Zhang Rui <[email protected]>
1 parent 595536e commit 9ef08d7

File tree

1 file changed

+37
-59
lines changed

1 file changed

+37
-59
lines changed

drivers/thermal/int340x_thermal/int3406_thermal.c

Lines changed: 37 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -21,39 +21,33 @@
2121

2222
struct int3406_thermal_data {
2323
int upper_limit;
24-
int upper_limit_index;
2524
int lower_limit;
26-
int lower_limit_index;
2725
acpi_handle handle;
2826
struct acpi_video_device_brightness *br;
2927
struct backlight_device *raw_bd;
3028
struct thermal_cooling_device *cooling_dev;
3129
};
3230

33-
static int int3406_thermal_to_raw(int level, struct int3406_thermal_data *d)
34-
{
35-
int max_level = d->br->levels[d->br->count - 1];
36-
int raw_max = d->raw_bd->props.max_brightness;
37-
38-
return level * raw_max / max_level;
39-
}
40-
41-
static int int3406_thermal_to_acpi(int level, struct int3406_thermal_data *d)
42-
{
43-
int raw_max = d->raw_bd->props.max_brightness;
44-
int max_level = d->br->levels[d->br->count - 1];
45-
46-
return level * max_level / raw_max;
47-
}
31+
/*
32+
* According to the ACPI spec,
33+
* "Each brightness level is represented by a number between 0 and 100,
34+
* and can be thought of as a percentage. For example, 50 can be 50%
35+
* power consumption or 50% brightness, as defined by the OEM."
36+
*
37+
* As int3406 device uses this value to communicate with the native
38+
* graphics driver, we make the assumption that it represents
39+
* the percentage of brightness only
40+
*/
41+
#define ACPI_TO_RAW(v, d) (d->raw_bd->props.max_brightness * v / 100)
42+
#define RAW_TO_ACPI(v, d) (v * 100 / d->raw_bd->props.max_brightness)
4843

4944
static int
5045
int3406_thermal_get_max_state(struct thermal_cooling_device *cooling_dev,
5146
unsigned long *state)
5247
{
5348
struct int3406_thermal_data *d = cooling_dev->devdata;
54-
int index = d->lower_limit_index ? d->lower_limit_index : 2;
5549

56-
*state = d->br->count - 1 - index;
50+
*state = d->upper_limit - d->lower_limit;
5751
return 0;
5852
}
5953

@@ -62,19 +56,15 @@ int3406_thermal_set_cur_state(struct thermal_cooling_device *cooling_dev,
6256
unsigned long state)
6357
{
6458
struct int3406_thermal_data *d = cooling_dev->devdata;
65-
int level, raw_level;
59+
int acpi_level, raw_level;
6660

67-
if (state > d->br->count - 3)
61+
if (state > d->upper_limit - d->lower_limit)
6862
return -EINVAL;
6963

70-
state = d->br->count - 1 - state;
71-
level = d->br->levels[state];
64+
acpi_level = d->br->levels[d->upper_limit - state];
7265

73-
if ((d->upper_limit && level > d->upper_limit) ||
74-
(d->lower_limit && level < d->lower_limit))
75-
return -EINVAL;
66+
raw_level = ACPI_TO_RAW(acpi_level, d);
7667

77-
raw_level = int3406_thermal_to_raw(level, d);
7868
return backlight_device_set_brightness(d->raw_bd, raw_level);
7969
}
8070

@@ -83,27 +73,22 @@ int3406_thermal_get_cur_state(struct thermal_cooling_device *cooling_dev,
8373
unsigned long *state)
8474
{
8575
struct int3406_thermal_data *d = cooling_dev->devdata;
86-
int raw_level, level, i;
87-
int *levels = d->br->levels;
76+
int acpi_level;
77+
int index;
8878

89-
raw_level = d->raw_bd->props.brightness;
90-
level = int3406_thermal_to_acpi(raw_level, d);
79+
acpi_level = RAW_TO_ACPI(d->raw_bd->props.brightness, d);
9180

9281
/*
93-
* There is no 1:1 mapping between the firmware interface level with the
94-
* raw interface level, we will have to find one that is close enough.
82+
* There is no 1:1 mapping between the firmware interface level
83+
* with the raw interface level, we will have to find one that is
84+
* right above it.
9585
*/
96-
for (i = 2; i < d->br->count; i++) {
97-
if (level < levels[i]) {
98-
if (i == 2)
99-
break;
100-
if ((level - levels[i - 1]) < (levels[i] - level))
101-
i--;
86+
for (index = d->lower_limit; index < d->upper_limit; index++) {
87+
if (acpi_level <= d->br->levels[index])
10288
break;
103-
}
10489
}
10590

106-
*state = d->br->count - 1 - i;
91+
*state = d->upper_limit - index;
10792
return 0;
10893
}
10994

@@ -117,7 +102,7 @@ static int int3406_thermal_get_index(int *array, int nr, int value)
117102
{
118103
int i;
119104

120-
for (i = 0; i < nr; i++) {
105+
for (i = 2; i < nr; i++) {
121106
if (array[i] == value)
122107
break;
123108
}
@@ -128,27 +113,20 @@ static void int3406_thermal_get_limit(struct int3406_thermal_data *d)
128113
{
129114
acpi_status status;
130115
unsigned long long lower_limit, upper_limit;
131-
int index;
132116

133117
status = acpi_evaluate_integer(d->handle, "DDDL", NULL, &lower_limit);
134-
if (ACPI_SUCCESS(status)) {
135-
index = int3406_thermal_get_index(d->br->levels, d->br->count,
136-
lower_limit);
137-
if (index > 0) {
138-
d->lower_limit = (int)lower_limit;
139-
d->lower_limit_index = index;
140-
}
141-
}
118+
if (ACPI_SUCCESS(status))
119+
d->lower_limit = int3406_thermal_get_index(d->br->levels,
120+
d->br->count, lower_limit);
142121

143122
status = acpi_evaluate_integer(d->handle, "DDPC", NULL, &upper_limit);
144-
if (ACPI_SUCCESS(status)) {
145-
index = int3406_thermal_get_index(d->br->levels, d->br->count,
146-
upper_limit);
147-
if (index > 0) {
148-
d->upper_limit = (int)upper_limit;
149-
d->upper_limit_index = index;
150-
}
151-
}
123+
if (ACPI_SUCCESS(status))
124+
d->upper_limit = int3406_thermal_get_index(d->br->levels,
125+
d->br->count, upper_limit);
126+
127+
/* lower_limit and upper_limit should be always set */
128+
d->lower_limit = d->lower_limit > 0 ? d->lower_limit : 2;
129+
d->upper_limit = d->upper_limit > 0 ? d->upper_limit : d->br->count - 1;
152130
}
153131

154132
static void int3406_notify(acpi_handle handle, u32 event, void *data)

0 commit comments

Comments
 (0)