On Tuesday 20 March 2007 05:21, Zhang Rui wrote: > From: Zhang Rui <rui.zhang@xxxxxxxxx> > > Add ACPI thermal_zone sysfs interface. > > Required attributes: > Attribute Mode Description > state RO state of the current thermal zone > (ok/passive/active[x]/hot/critical) > cooling_mode RW the cooling policy of the current thermal zone. > 0x00 = active, 0x01 = passive, 0xff = critical. > polling_freq RW > temperature RO temperature of the current thermal zone.(celsius) > critical_temp RW critical trip point where OSPM must perform a > critical shutdown > > Optional attributes: > Attribute Mode Description > hot_temp RW critical trip point where OSPM may choose to > transition the system into S4 > passive_temp RW the passive cooling policy threshold value > passive_tc1 RO thermal constant for passive cooling > passive_tc2 RO thermal constant for passive cooling > passive_tsp RO thermal sampling period for passive cooling > active0_temp RW active cooling policy threshold value > ... > active9_temp RW active cooling policy threshold value > > Syslinks to cooling devices(dynamic, optional): > passive_cooling_device0 > ... > passive_cooling_device9 > > active0_cooling_device0 > ... > active0_cooling_device9 > ... > ... > active9_cooling_device0 > ... > active9_cooling_device9 > I think this is an improvement over the procfs thermal_zone/*/trip_points file, which confuses a lot of people with its format. -Len > Signed-off-by: Zhang Rui <rui.zhang@xxxxxxxxx> > --- > drivers/acpi/thermal.c | 713 ++++++++++++++++++++++++++++++++++++++++++------- > 1 files changed, 622 insertions(+), 91 deletions(-) > > Index: linux-2.6.21-rc4-mm1/drivers/acpi/thermal.c > =================================================================== > --- linux-2.6.21-rc4-mm1.orig/drivers/acpi/thermal.c 2007-03-20 16:16:23.000000000 +0800 > +++ linux-2.6.21-rc4-mm1/drivers/acpi/thermal.c 2007-03-20 16:30:21.000000000 +0800 > @@ -83,19 +83,6 @@ MODULE_PARM_DESC(tzp, "Thermal zone poll > static int acpi_thermal_add(struct acpi_device *device); > static int acpi_thermal_remove(struct acpi_device *device, int type); > static int acpi_thermal_resume(struct acpi_device *device); > -static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); > -static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); > -static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); > -static ssize_t acpi_thermal_write_trip_points(struct file *, > - const char __user *, size_t, > - loff_t *); > -static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); > -static ssize_t acpi_thermal_write_cooling_mode(struct file *, > - const char __user *, size_t, > - loff_t *); > -static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); > -static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, > - size_t, loff_t *); > > static struct acpi_driver acpi_thermal_driver = { > .name = "thermal", > @@ -176,44 +163,6 @@ struct acpi_thermal { > struct timer_list timer; > }; > > -static const struct file_operations acpi_thermal_state_fops = { > - .open = acpi_thermal_state_open_fs, > - .read = seq_read, > - .llseek = seq_lseek, > - .release = single_release, > -}; > - > -static const struct file_operations acpi_thermal_temp_fops = { > - .open = acpi_thermal_temp_open_fs, > - .read = seq_read, > - .llseek = seq_lseek, > - .release = single_release, > -}; > - > -static const struct file_operations acpi_thermal_trip_fops = { > - .open = acpi_thermal_trip_open_fs, > - .read = seq_read, > - .write = acpi_thermal_write_trip_points, > - .llseek = seq_lseek, > - .release = single_release, > -}; > - > -static const struct file_operations acpi_thermal_cooling_fops = { > - .open = acpi_thermal_cooling_open_fs, > - .read = seq_read, > - .write = acpi_thermal_write_cooling_mode, > - .llseek = seq_lseek, > - .release = single_release, > -}; > - > -static const struct file_operations acpi_thermal_polling_fops = { > - .open = acpi_thermal_polling_open_fs, > - .read = seq_read, > - .write = acpi_thermal_write_polling, > - .llseek = seq_lseek, > - .release = single_release, > -}; > - > /* -------------------------------------------------------------------------- > Thermal Zone Management > -------------------------------------------------------------------------- */ > @@ -305,15 +254,25 @@ static int acpi_thermal_set_cooling_mode > return 0; > } > > +static int acpi_thermal_cooling_device_update(struct acpi_thermal *thermal, int state, > + struct acpi_handle_list *new_devices); > +static int acpi_thermal_sysfs_update(struct acpi_thermal *thermal, struct acpi_thermal_state *old_state); > static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) > { > acpi_status status = AE_OK; > int i = 0; > + struct acpi_handle_list devices; > + struct acpi_thermal_state state; > > > if (!tz) > return -EINVAL; > > + state.hot = tz->trips.hot.flags.valid; > + state.passive= tz->trips.passive.flags.valid; > + for (state.active_index = 0; state.active_index < ACPI_THERMAL_MAX_ACTIVE && > + tz->trips.active[state.active_index].flags.valid; state.active_index ++); > + > /* Critical Shutdown (required) */ > > status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, > @@ -374,7 +333,7 @@ static int acpi_thermal_get_trip_points( > > status = > acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, > - &tz->trips.passive.devices); > + &devices); > if (ACPI_FAILURE(status)) > tz->trips.passive.flags.valid = 0; > > @@ -386,6 +345,13 @@ static int acpi_thermal_get_trip_points( > tz->trips.passive.temperature)); > } > > + if (!tz->trips.passive.flags.valid) > + devices.count = 0; > + status = acpi_thermal_cooling_device_update(tz, -1, &devices); > + if (status) > + ACPI_DEBUG_PRINT((ACPI_DB_WARN, > + "Passive cooling device update failed!\n")); > + > /* Active: Fans, etc. (optional) */ > > for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { > @@ -396,22 +362,35 @@ static int acpi_thermal_get_trip_points( > acpi_evaluate_integer(tz->device->handle, name, NULL, > &tz->trips.active[i].temperature); > if (ACPI_FAILURE(status)) > - break; > - > - name[2] = 'L'; > - status = > - acpi_evaluate_reference(tz->device->handle, name, NULL, > - &tz->trips.active[i].devices); > - if (ACPI_SUCCESS(status)) { > - tz->trips.active[i].flags.valid = 1; > - ACPI_DEBUG_PRINT((ACPI_DB_INFO, > - "Found active threshold [%d]:[%lu]\n", > - i, tz->trips.active[i].temperature)); > - } else > - ACPI_EXCEPTION((AE_INFO, status, > - "Invalid active threshold [%d]", i)); > + tz->trips.active[i].flags.valid = 0; > + else { > + name[2] = 'L'; > + status = > + acpi_evaluate_reference(tz->device->handle, name, NULL, > + &devices); > + if (ACPI_SUCCESS(status)) { > + tz->trips.active[i].flags.valid = 1; > + ACPI_DEBUG_PRINT((ACPI_DB_INFO, > + "Found active threshold [%d]:[%lu]\n", > + i, tz->trips.active[i].temperature)); > + } else { > + tz->trips.active[i].flags.valid = 0; > + ACPI_EXCEPTION((AE_INFO, status, > + "Invalid active threshold [%d]", i)); > + } > + } > + if (!tz->trips.active[i].flags.valid) > + devices.count = 0; > + status = acpi_thermal_cooling_device_update(tz, i, &devices); > + if (status) > + ACPI_DEBUG_PRINT((ACPI_DB_WARN, > + "Active[%d] cooling device update failed!\n", i)); > } > > + if(acpi_thermal_sysfs_update(tz, &state)) > + ACPI_DEBUG_PRINT((ACPI_DB_WARN, > + "Trip point sysfs update failed!\n")); > + > return 0; > } > > @@ -771,9 +750,495 @@ static void acpi_thermal_check(void *dat > } > > /* -------------------------------------------------------------------------- > - FS Interface (/proc) > + FS Interface (/sys) > -------------------------------------------------------------------------- */ > +static ssize_t > +acpi_thermal_state_show(struct acpi_device *dev, char *buf) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(dev); > + int result = 0; > + > + if (!thermal->state.critical && !thermal->state.hot && !thermal->state.passive > + && !thermal->state.active) > + result = sprintf(buf, "ok\n"); > + else { > + if (thermal->state.critical) > + result += sprintf(buf, "critical "); > + if (thermal->state.hot) > + result += sprintf(buf, "hot "); > + if (thermal->state.passive) > + result += sprintf(buf, "passive "); > + if (thermal->state.active) > + result += sprintf(buf, "active[%d]", thermal->state.active_index); > + sprintf(buf, "\n"); > + } > + return result; > +} > +static ACPI_DEVICE_ATTR(state, 0444, acpi_thermal_state_show, NULL); > + > +static ssize_t > +acpi_thermal_temperature_show(struct acpi_device *dev, char *buf) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(dev); > + int result = 0; > + > + result = acpi_thermal_get_temperature(thermal); > + if (!result) > + return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(thermal->temperature)); > + else > + return result; > +} > +static ACPI_DEVICE_ATTR(temperature, 0444, acpi_thermal_temperature_show, NULL); > + > +static ssize_t > +acpi_thermal_cooling_mode_show(struct acpi_device *dev, char *buf) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(dev); > + > + if (!thermal) > + return -EINVAL; > + > + if (thermal->flags.cooling_mode) > + return sprintf(buf, "0x%02x\n", thermal->cooling_mode); > + > + return 0; > +} > + > +static ssize_t > +acpi_thermal_cooling_mode_store(struct acpi_device *dev, const char *buf, size_t count) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(dev); > + u32 mode; > + char *end; > + int ret = 0; > + > + mode = simple_strtoul(buf, &end, 0); > + if (*end == '\0') > + return -EINVAL; > + > + if (thermal->flags.cooling_mode){ > + ret = acpi_thermal_set_cooling_mode(thermal, mode); > + if (ret) > + return ret; > + acpi_thermal_check(thermal); > + return count; > + } > + else > + return -ENODEV; > +} > +static ACPI_DEVICE_ATTR(cooling_mode, 0644, acpi_thermal_cooling_mode_show, acpi_thermal_cooling_mode_store); > + > +static ssize_t > +acpi_thermal_polling_freq_show(struct acpi_device *dev, char *buf) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(dev); > + > + if (thermal->polling_frequency) > + return sprintf(buf, "%lu\n", (thermal->polling_frequency / 10)); > + > + return 0; > +} > + > +static ssize_t > +acpi_thermal_polling_freq_store(struct acpi_device *dev, const char *buf, size_t count) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(dev); > + unsigned long freq; > + char * end; > + int ret = 0; > + > + freq = simple_strtoul(buf, &end, 0); > + if (*end == '\0') > + return -EINVAL; > + > + ret = acpi_thermal_set_polling(thermal, freq); > + if (ret) > + return ret; > + > + acpi_thermal_check(thermal); > + return count; > +} > +static ACPI_DEVICE_ATTR(polling_freq, 0644, acpi_thermal_polling_freq_show, acpi_thermal_polling_freq_store); > + > +static ssize_t > +acpi_thermal_passive_tc1_show(struct acpi_device *dev, char *buf) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(dev); > + > + if (!thermal) > + return -EINVAL; > + > + if (thermal->trips.passive.flags.valid) > + return sprintf(buf, "%ld\n", thermal->trips.passive.tc1); > + else > + return -ENODEV; > +} > +static ACPI_DEVICE_ATTR(passive_tc1, 0444, acpi_thermal_passive_tc1_show, NULL); > + > +static ssize_t > +acpi_thermal_passive_tc2_show(struct acpi_device *dev, char *buf) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(dev); > + > + if (!thermal) > + return -EINVAL; > + > + if (thermal->trips.passive.flags.valid) > + return sprintf(buf, "%ld\n", thermal->trips.passive.tc2); > + else > + return -ENODEV; > +} > +static ACPI_DEVICE_ATTR(passive_tc2, 0444, acpi_thermal_passive_tc2_show, NULL); > + > +static ssize_t > +acpi_thermal_passive_tsp_show(struct acpi_device *dev, char *buf) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(dev); > + > + if (!thermal) > + return -EINVAL; > + > + if (thermal->trips.passive.flags.valid) > + return sprintf(buf, "%ld\n", thermal->trips.passive.tsp); > + else > + return -ENODEV; > +} > +static ACPI_DEVICE_ATTR(passive_tsp, 0444, acpi_thermal_passive_tsp_show, NULL); > + > +typedef ssize_t (*trip_point_show)(struct acpi_thermal *thermal, > + int type, int state, char*buf); > +typedef ssize_t (*trip_point_store)(struct acpi_thermal *thermal, int type, > + int state, const char *buf, size_t count); > + > +struct acpi_thermal_trip_point_attr { > + struct device_attribute attr; > + int type; > + int state; > + trip_point_show show; > + trip_point_store store; > +}; > + > +#define ACPI_THERMAL_TRIP_POINT_CRITICAL 0 > +#define ACPI_THERMAL_TRIP_POINT_HOT 1 > +#define ACPI_THERMAL_TRIP_POINT_PASSIVE 2 > +#define ACPI_THERMAL_TRIP_POINT_ACTIVE 3 > + > +static ssize_t > +acpi_thermal_trip_point_show(struct acpi_thermal *thermal, > + int type, int state, char*buf) > +{ > + ssize_t result = -ENODEV; > + > + switch(type) { > + case ACPI_THERMAL_TRIP_POINT_CRITICAL: > + if (thermal->trips.critical.flags.valid) > + result = sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(thermal->trips.critical.temperature)); > + break; > + case ACPI_THERMAL_TRIP_POINT_HOT: > + if (thermal->trips.hot.flags.valid) > + result = sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(thermal->trips.hot.temperature)); > + break; > + case ACPI_THERMAL_TRIP_POINT_PASSIVE: > + if (thermal->trips.passive.flags.valid) > + result = sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(thermal->trips.passive.temperature)); > + break; > + case ACPI_THERMAL_TRIP_POINT_ACTIVE: > + if (thermal->trips.active[state].flags.valid) { > + if (state >= 0 && state < ACPI_THERMAL_MAX_ACTIVE) > + result = sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(thermal->trips.active[state].temperature)); > + else > + result = -EINVAL; > + } > + break; > + default: > + result = -EINVAL; > + } > + > + return result; > +} > + > +static ssize_t > +acpi_thermal_trip_point_store(struct acpi_thermal *thermal, int type, > + int state, const char *buf, size_t count) > +{ > + char *end; > + u32 val; > + ssize_t result = -ENODEV; > + > + val = simple_strtol(buf, &end, 0); > + if (*end == '\0') > + return -EINVAL; > + > + switch(type) { > + case ACPI_THERMAL_TRIP_POINT_CRITICAL: > + if (thermal->trips.critical.flags.valid){ > + thermal->trips.critical.temperature = CELSIUS_TO_KELVIN(val); > + result = count; > + } > + break; > + case ACPI_THERMAL_TRIP_POINT_HOT: > + if (thermal->trips.hot.flags.valid){ > + thermal->trips.hot.temperature = CELSIUS_TO_KELVIN(val); > + result = count; > + } > + break; > + case ACPI_THERMAL_TRIP_POINT_PASSIVE: > + if (thermal->trips.passive.flags.valid){ > + thermal->trips.passive.temperature = CELSIUS_TO_KELVIN(val); > + result = count; > + } > + break; > + case ACPI_THERMAL_TRIP_POINT_ACTIVE: > + if (thermal->trips.active[state].flags.valid){ > + if (state >= 0 && state < ACPI_THERMAL_MAX_ACTIVE) { > + thermal->trips.active[state].temperature = CELSIUS_TO_KELVIN(val); > + result = count; > + } > + else > + result = -EINVAL; > + } > + break; > + default: > + result = -EINVAL; > + } > > + return result; > +} > + > +static ssize_t _trip_point_show(struct device *dev, struct device_attribute *attr, > + char *buf) > +{ > + struct acpi_thermal_trip_point_attr *thermal_attr = container_of(attr, struct acpi_thermal_trip_point_attr, attr); > + struct acpi_device *acpi_dev = to_acpi_device(dev); > + struct acpi_thermal *thermal = acpi_driver_data(acpi_dev); > + > + if (!thermal_attr->store) > + return -EINVAL; > + > + return thermal_attr->show(thermal, thermal_attr->type, thermal_attr->state, buf); > +} > +static ssize_t _trip_point_store(struct device *dev, struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + struct acpi_thermal_trip_point_attr *thermal_attr = container_of(attr, struct acpi_thermal_trip_point_attr, attr); > + struct acpi_device *acpi_dev = to_acpi_device(dev); > + struct acpi_thermal *thermal = acpi_driver_data(acpi_dev); > + > + if (!thermal_attr->store) > + return -EINVAL; > + > + return thermal_attr->store(thermal, thermal_attr->type, thermal_attr->state, buf, count); > +} > + > +#define ACPI_THERMAL_TRIP_POINT(_name, _type, _state) \ > +struct acpi_thermal_trip_point_attr _name##_attr = \ > +{ \ > + .attr = __ATTR(_name, 0644, _trip_point_show, _trip_point_store), \ > + .type = _type, \ > + .state = _state, \ > + .show = acpi_thermal_trip_point_show, \ > + .store = acpi_thermal_trip_point_store, \ > +} > + > + > +static ACPI_THERMAL_TRIP_POINT(critical_temp, ACPI_THERMAL_TRIP_POINT_CRITICAL, 0); > +static ACPI_THERMAL_TRIP_POINT(hot_temp, ACPI_THERMAL_TRIP_POINT_HOT, 0); > +static ACPI_THERMAL_TRIP_POINT(passive_temp, ACPI_THERMAL_TRIP_POINT_PASSIVE, 0); > +static ACPI_THERMAL_TRIP_POINT(active0_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 0); > +static ACPI_THERMAL_TRIP_POINT(active1_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 1); > +static ACPI_THERMAL_TRIP_POINT(active2_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 2); > +static ACPI_THERMAL_TRIP_POINT(active3_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 3); > +static ACPI_THERMAL_TRIP_POINT(active4_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 4); > +static ACPI_THERMAL_TRIP_POINT(active5_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 5); > +static ACPI_THERMAL_TRIP_POINT(active6_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 6); > +static ACPI_THERMAL_TRIP_POINT(active7_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 7); > +static ACPI_THERMAL_TRIP_POINT(active8_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 8); > +static ACPI_THERMAL_TRIP_POINT(active9_temp, ACPI_THERMAL_TRIP_POINT_ACTIVE, 9); > + > +static struct device_attribute *thermal_default_attr[] = > +{ > + GET_DEV_ATTR(state), > + GET_DEV_ATTR(temperature), > + GET_DEV_ATTR(cooling_mode), > + GET_DEV_ATTR(polling_freq), > + GET_DEV_ATTR(critical_temp), > + NULL, > +}; > + > +static struct device_attribute *thermal_optional_attr[] = > +{ > + GET_DEV_ATTR(hot_temp), > + GET_DEV_ATTR(passive_temp), > + GET_DEV_ATTR(passive_tc1), > + GET_DEV_ATTR(passive_tc2), > + GET_DEV_ATTR(passive_tsp), > + GET_DEV_ATTR(active0_temp), > + GET_DEV_ATTR(active1_temp), > + GET_DEV_ATTR(active2_temp), > + GET_DEV_ATTR(active3_temp), > + GET_DEV_ATTR(active4_temp), > + GET_DEV_ATTR(active5_temp), > + GET_DEV_ATTR(active6_temp), > + GET_DEV_ATTR(active7_temp), > + GET_DEV_ATTR(active8_temp), > + GET_DEV_ATTR(active9_temp), > +}; > + > +static int acpi_thermal_add_sysfs(struct acpi_device* device) > +{ > + int result = 0; > + > + result = acpi_device_add_sysfs(device, thermal_default_attr); > + > + /* > + * optional trip point attributes (hot/passive/active) > + * and syslinks to cooling devices both are dynamic > + */ > + > + return result; > +} > + > +static void acpi_thermal_remove_sysfs(struct acpi_device* device) > +{ > + struct acpi_thermal *thermal = acpi_driver_data(device); > + struct acpi_handle_list new_devices; > + int i = 0; > + > + acpi_device_remove_sysfs(device, thermal_default_attr); > + > + /* > + * remove syslinks to cooling devices > + */ > + new_devices.count = 0; > + > + if (thermal->trips.passive.flags.valid) > + acpi_thermal_cooling_device_update(thermal, -1, &new_devices); > + > + > + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) > + if (thermal->trips.active[i].flags.valid) > + acpi_thermal_cooling_device_update(thermal, i, &new_devices); > + > + /* > + * remove optional trip point attributes > + */ > + if (thermal->trips.hot.flags.valid ) > + device_remove_file(&device->dev, thermal_optional_attr[0]); > + > + if (thermal->trips.passive.flags.valid) > + for (i = 0; i < 4; i++) > + device_remove_file(&device->dev, thermal_optional_attr[1+i]); > + > + > + for(i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) > + if ((thermal->trips.active[i].flags.valid)) > + device_remove_file(&device->dev, thermal_optional_attr[5+i]); > + > + return ; > +} > + > +static int acpi_thermal_cooling_device_update(struct acpi_thermal* thermal, int state, > + struct acpi_handle_list *new_devices) > +{ > + struct acpi_device *device = thermal->device; > + struct acpi_handle_list *old_devices; > + struct acpi_device *cooling_device; > + char buf[24]; > + int i = 0; > + int result = 0; > + > + if (!device || !new_devices) > + return -EINVAL; > + > + if (state == -1) { > + sprintf(buf, "passive_cooling_device0"); > + old_devices = &thermal->trips.passive.devices; > + } > + else > + if (state >= 0 && state < ACPI_THERMAL_MAX_ACTIVE) { > + sprintf(buf, "active%d_cooling_device0", state); > + old_devices = &thermal->trips.active[state].devices; > + } > + else > + return -EINVAL; > + > + for (i = 0; i < old_devices->count || i < new_devices->count; i++) { > + if (i >= old_devices->count) > + old_devices->handles[i] = NULL; > + if (i >= new_devices->count) > + new_devices->handles[i] = NULL; > + if (new_devices->handles[i] != old_devices->handles[i]) { > + buf[22] = '0'+i; > + > + if (i < old_devices->count && old_devices->handles[i]) > + sysfs_remove_link(&device->dev.kobj, buf); > + > + if (i < new_devices->count && new_devices->handles[i]) { > + acpi_bus_get_device(new_devices->handles[i], &cooling_device); > + result = sysfs_create_link(&device->dev.kobj, &cooling_device->dev.kobj, buf); > + if (result) > + return result; > + } > + old_devices->handles[i] = new_devices->handles[i]; > + } > + } > + old_devices->count = new_devices->count; > + > + return result; > +} > + > +static int acpi_thermal_trip_point_update(struct device *dev, struct device_attribute *attr, int type) > +{ > + int result =0; > + > + if (type) > + result = device_create_file(dev, attr); > + else > + device_remove_file(dev, attr); > + > + return result; > +} > + > +static int acpi_thermal_sysfs_update(struct acpi_thermal *thermal, struct acpi_thermal_state *old_state) > +{ > + struct acpi_device *device = thermal->device; > + int result = 0; > + int i = 0; > + > + if (thermal->trips.hot.flags.valid != old_state->hot) { > + result = acpi_thermal_trip_point_update(&device->dev, thermal_optional_attr[0], > + thermal->trips.hot.flags.valid); > + if (result) > + goto done; > + } > + > + if (thermal->trips.passive.flags.valid != old_state->passive) > + for (i = 0; i < 4; i++) { > + result = acpi_thermal_trip_point_update(&device->dev, thermal_optional_attr[1+i], > + thermal->trips.passive.flags.valid); > + if (result) > + goto done; > + } > + > + for(i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) > + { > + if ((thermal->trips.active[i].flags.valid && i >= old_state->active_index) || > + (!thermal->trips.active[i].flags.valid && i < old_state->active_index)) { > + result = acpi_thermal_trip_point_update(&device->dev, thermal_optional_attr[5+i], > + thermal->trips.active[i].flags.valid); > + if (result) > + goto done; > + } > + } > + > + done: > + return result; > +} > + > +/* -------------------------------------------------------------------------- > + FS Interface (/proc) > + -------------------------------------------------------------------------- */ > +#ifdef CONFIG_ACPI_PROCFS > static struct proc_dir_entry *acpi_thermal_dir; > > static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) > @@ -838,6 +1303,7 @@ static int acpi_thermal_temp_open_fs(str > static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) > { > struct acpi_thermal *tz = seq->private; > + struct acpi_device *device; > int i = 0; > int j = 0; > > @@ -860,9 +1326,8 @@ static int acpi_thermal_trip_seq_show(st > tz->trips.passive.tc1, tz->trips.passive.tc2, > tz->trips.passive.tsp); > for (j = 0; j < tz->trips.passive.devices.count; j++) { > - > - seq_printf(seq, "0x%p ", > - tz->trips.passive.devices.handles[j]); > + acpi_bus_get_device(tz->trips.passive.devices.handles[j], &device); > + seq_printf(seq, "%4.4s ", acpi_device_bid(device)); > } > seq_puts(seq, "\n"); > } > @@ -873,9 +1338,10 @@ static int acpi_thermal_trip_seq_show(st > seq_printf(seq, "active[%d]: %ld C: devices=", > i, > KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); > - for (j = 0; j < tz->trips.active[i].devices.count; j++) > - seq_printf(seq, "0x%p ", > - tz->trips.active[i].devices.handles[j]); > + for (j = 0; j < tz->trips.active[i].devices.count; j++) { > + acpi_bus_get_device(tz->trips.active[i].devices.handles[j], &device); > + seq_printf(seq, "%4.4s ", acpi_device_bid(device)); > + } > seq_puts(seq, "\n"); > } > > @@ -1067,7 +1533,45 @@ acpi_thermal_write_polling(struct file * > return count; > } > > -static int acpi_thermal_add_fs(struct acpi_device *device) > +static const struct file_operations acpi_thermal_state_fops = { > + .open = acpi_thermal_state_open_fs, > + .read = seq_read, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > +static const struct file_operations acpi_thermal_temp_fops = { > + .open = acpi_thermal_temp_open_fs, > + .read = seq_read, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > +static const struct file_operations acpi_thermal_trip_fops = { > + .open = acpi_thermal_trip_open_fs, > + .read = seq_read, > + .write = acpi_thermal_write_trip_points, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > +static const struct file_operations acpi_thermal_cooling_fops = { > + .open = acpi_thermal_cooling_open_fs, > + .read = seq_read, > + .write = acpi_thermal_write_cooling_mode, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > +static const struct file_operations acpi_thermal_polling_fops = { > + .open = acpi_thermal_polling_open_fs, > + .read = seq_read, > + .write = acpi_thermal_write_polling, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > +static int acpi_thermal_add_procfs(struct acpi_device *device) > { > struct proc_dir_entry *entry = NULL; > > @@ -1141,7 +1645,7 @@ static int acpi_thermal_add_fs(struct ac > return 0; > } > > -static int acpi_thermal_remove_fs(struct acpi_device *device) > +static int acpi_thermal_remove_procfs(struct acpi_device *device) > { > > if (acpi_device_dir(device)) { > @@ -1162,6 +1666,26 @@ static int acpi_thermal_remove_fs(struct > return 0; > } > > +static int acpi_thermal_procfs_init(void) > +{ > + acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); > + if (!acpi_thermal_dir) > + return -ENODEV; > + acpi_thermal_dir->owner = THIS_MODULE; > + > + return 0; > +} > + > +static int acpi_thermal_procfs_exit(void) > +{ > + remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); > + > + return 0; > +} > +#else > +declare_acpi_device_procfs(thermal); > +#endif > + > /* -------------------------------------------------------------------------- > Driver Interface > -------------------------------------------------------------------------- */ > @@ -1283,10 +1807,14 @@ static int acpi_thermal_add(struct acpi_ > if (result) > goto end; > > - result = acpi_thermal_add_fs(device); > + result = acpi_thermal_add_sysfs(device); > if (result) > goto end; > > + result = acpi_thermal_add_procfs(device); > + if (result) > + goto procfs_error; > + > init_timer(&tz->timer); > > acpi_thermal_check(tz); > @@ -1296,19 +1824,22 @@ static int acpi_thermal_add(struct acpi_ > acpi_thermal_notify, tz); > if (ACPI_FAILURE(status)) { > result = -ENODEV; > - goto end; > + goto notify_error; > } > > printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", > acpi_device_name(device), acpi_device_bid(device), > KELVIN_TO_CELSIUS(tz->temperature)); > > - end: > - if (result) { > - acpi_thermal_remove_fs(device); > - kfree(tz); > - } > + goto end; > > + notify_error: > + acpi_thermal_remove_procfs(device); > + procfs_error: > + acpi_thermal_remove_sysfs(device); > + end: > + if (result) > + kfree(tz); > return result; > } > > @@ -1347,7 +1878,9 @@ static int acpi_thermal_remove(struct ac > acpi_thermal_active(tz); > } > > - acpi_thermal_remove_fs(device); > + acpi_thermal_remove_procfs(device); > + > + acpi_thermal_remove_sysfs(device); > > kfree(tz); > return 0; > @@ -1390,15 +1923,14 @@ static int __init acpi_thermal_init(void > { > int result = 0; > > + result = acpi_thermal_procfs_init(); > + if (result) > + return result; > > - acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); > - if (!acpi_thermal_dir) > - return -ENODEV; > - acpi_thermal_dir->owner = THIS_MODULE; > - > + acpi_thermal_driver.owner = THIS_MODULE; > result = acpi_bus_register_driver(&acpi_thermal_driver); > if (result < 0) { > - remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); > + acpi_thermal_procfs_exit(); > return -ENODEV; > } > > @@ -1407,10 +1939,9 @@ static int __init acpi_thermal_init(void > > static void __exit acpi_thermal_exit(void) > { > - > acpi_bus_unregister_driver(&acpi_thermal_driver); > > - remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); > + acpi_thermal_procfs_exit(); > > return; > } > - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html