Subject: [PATCH] [acpi thermal] Add support for trip points - Implement thermal_get_trips() - Fill out struct acpi_thermal with necessary structures for trip info. - Call thermal_get_trips() on device init. - Add err() macro for reporting badness. Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/thermal/device.c | 111 ++++++++++++++++++++++++++++++++ drivers/acpi/drivers/thermal/driver.c | 8 ++ drivers/acpi/drivers/thermal/thermal.h | 46 +++++++++++++ 3 files changed, 163 insertions(+), 2 deletions(-) applies-to: 3cdc681baceee2fffacaede4c63b3129ccfb03f7 290aed845e7b59afd0bf22277aefecff60f77011 diff --git a/drivers/acpi/drivers/thermal/device.c b/drivers/acpi/drivers/thermal/device.c index 87db2ba..c7e2b53 100644 --- a/drivers/acpi/drivers/thermal/device.c +++ b/drivers/acpi/drivers/thermal/device.c @@ -24,6 +24,17 @@ static int get_int(struct acpi_thermal * } +static int get_devices(struct acpi_thermal * at, char * obj, + struct acpi_handle_list * list) +{ + acpi_status status; + + status = acpi_evaluate_reference(at->t_ad->acpi_device->handle, + obj, NULL, list); + return ACPI_SUCCESS(status) ? 0 : -ENODEV; +} + + long thermal_temp_c(long tempk) { if (tempk - 2732 >= 0) @@ -45,3 +56,103 @@ int thermal_get_temp(struct acpi_thermal } return ret; } + +static int get_crit_trip(struct acpi_thermal * at) +{ + int ret; + + ret = get_int(at, "_CRT", &at->t_trips.crit_temp); + if (!ret) { + at->t_trips.crit_val = 1; + dbg("Found critical threshold [%lu]", + at->t_trips.crit_temp); + } else + dbg("No critical threshold"); + return ret; +} + + +static int get_hot_trip(struct acpi_thermal * at) +{ + int ret; + + ret = get_int(at, "_HOT", &at->t_trips.hot_temp); + if (!ret) { + at->t_trips.hot_val = 1; + dbg("Found hot threshold [%lu]", + at->t_trips.hot_temp); + } else + dbg("No hot threshold: %d / %d", + at->t_trips.hot_val, at->t_trips.hot_en); + return ret; +} + + + +static int get_passive_trips(struct acpi_thermal * at) +{ + int ret; + + ret = get_int(at, "_PSV", &at->t_trips.psv_temp); + if (!ret) { + at->t_trips.psv_val = 1; + + ret += get_int(at, "_TC1", &at->t_trips.psv_tc1); + ret += get_int(at, "_TC2", &at->t_trips.psv_tc1); + ret += get_int(at, "_TSP", &at->t_trips.psv_tc1); + ret += get_devices(at, "_PSL", &at->t_trips.psv_devices); + + if (!ret) + dbg("Found passive threshold [%lu]", + at->t_trips.psv_temp); + else { + at->t_trips.psv_val = 0; + err("Invalid passive threshold"); + } + } else + dbg("No passive threshold"); + return ret; +} + +static int get_active_trips(struct acpi_thermal * at) +{ + struct thermal_active * ta; + char obj_name[5] = "_AC?"; + char obj_list[5] = "_AL?"; + int ret = 0; + int i; + + for (i = 0; i < THERMAL_MAX_ACTIVE; i++) { + ta = at->t_trips.act + i; + obj_name[3] = '0' + i; + + ret = get_int(at, obj_name, &ta->temp); + if (ret) + break; + + obj_list[3] = '0' + i; + ret = get_devices(at, obj_list, &ta->devices); + if (!ret) { + ta->val = 1; + dbg("Found active threshold [%d]:[%lu]", + i, ta->temp); + } else + err("Invalid active threshold [%d]", i); + } + return ret; +} + +int thermal_get_trips(struct acpi_thermal * at) +{ + int ret; + + ret = get_crit_trip(at); + if (ret) + return ret; + + get_hot_trip(at); + get_passive_trips(at); + get_active_trips(at); + return 0; +} + diff --git a/drivers/acpi/drivers/thermal/driver.c b/drivers/acpi/drivers/thermal/driver.c index d19c8a6..350dc0d 100644 --- a/drivers/acpi/drivers/thermal/driver.c +++ b/drivers/acpi/drivers/thermal/driver.c @@ -13,7 +13,6 @@ #include "thermal.h" - static int thermal_init(struct acpi_thermal * at) { int ret; @@ -25,6 +24,13 @@ static int thermal_init(struct acpi_ther if (ret) return ret; + /* + * Get trip points + */ + ret = thermal_get_trips(at); + if (ret) + return ret; + return 0; } diff --git a/drivers/acpi/drivers/thermal/thermal.h b/drivers/acpi/drivers/thermal/thermal.h index 758d7e6..e3dc2c4 100644 --- a/drivers/acpi/drivers/thermal/thermal.h +++ b/drivers/acpi/drivers/thermal/thermal.h @@ -7,19 +7,63 @@ #define dbg(fmt, ...) #endif +#define err(fmt, ...) printk(KERN_ERR PREFIX "thermal: " fmt "\n", ## __VA_ARGS__) + #define _COMPONENT ACPI_THERMAL_COMPONENT ACPI_MODULE_NAME("acpi_thermal"); - #define ACPI_THERMAL_HID "ACPI_THM" +#define THERMAL_MAX_ACTIVE 10 + +#define THERMAL_MODE_ACT 0 +#define THERMAL_MODE_PSV 1 +#define THERMAL_MODE_CRIT 0xff + +#define THERMAL_STATE_CRIT 0x00000001 +#define THERMAL_STATE_HOT 0x00000002 +#define THERMAL_STATE_PSV 0x00000004 +#define THERMAL_STATE_ACT 0x00000008 + + +struct thermal_active { + u32 val; + u32 en; + unsigned long temp; + struct acpi_handle_list devices; +}; + +struct thermal_trips { + u32 crit_val; + u32 crit_en; + unsigned long crit_temp; + + u32 hot_val; + u32 hot_en; + unsigned long hot_temp; + + u32 psv_val; + u32 psv_en; + unsigned long psv_temp; + unsigned long psv_tc1; + unsigned long psv_tc2; + unsigned long psv_tsp; + struct acpi_handle_list psv_devices; + + u32 act_index; + struct thermal_active act[THERMAL_MAX_ACTIVE]; +}; + struct acpi_thermal { struct acpi_dev * t_ad; long t_temp; long t_last_temp; + + struct thermal_trips t_trips; }; extern int thermal_get_temp(struct acpi_thermal *); +extern int thermal_get_trips(struct acpi_thermal * at); extern long thermal_temp_c(long tempk); --- 0.99.9.GIT