summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpi_video.c43
-rw-r--r--drivers/acpi/acpica/dsfield.c3
-rw-r--r--drivers/acpi/acpica/exfield.c11
-rw-r--r--drivers/acpi/fan.h2
-rw-r--r--drivers/acpi/fan_core.c147
-rw-r--r--drivers/acpi/fan_hwmon.c2
-rw-r--r--drivers/acpi/processor_driver.c6
-rw-r--r--drivers/acpi/processor_thermal.c80
-rw-r--r--drivers/acpi/thermal.c19
-rw-r--r--drivers/thermal/thermal_core.c28
-rw-r--r--drivers/thermal/thermal_core.h3
-rw-r--r--drivers/thermal/thermal_of.c2
-rw-r--r--include/acpi/actbl2.h7
-rw-r--r--include/acpi/processor.h6
-rw-r--r--include/linux/acpi.h2
-rw-r--r--include/linux/thermal.h19
16 files changed, 150 insertions, 230 deletions
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 4d6fd9f6e9ad..2a2822516665 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -1700,9 +1700,9 @@ static int acpi_video_resume(struct notifier_block *nb,
static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
{
+ struct device *phys_dev, *parent = NULL;
struct backlight_properties props;
struct pci_dev *pdev;
- struct device *parent = NULL;
int result;
static int count;
char *name;
@@ -1729,11 +1729,10 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
device,
&acpi_backlight_ops,
&props);
- put_device(parent);
kfree(name);
if (IS_ERR(device->backlight)) {
device->backlight = NULL;
- return;
+ goto put_parent;
}
/*
@@ -1743,8 +1742,12 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
device->backlight->props.brightness =
acpi_video_get_brightness(device->backlight);
- device->cooling_dev = thermal_cooling_device_register("LCD", device,
- &video_cooling_ops);
+ phys_dev = acpi_bus_get_primary_device(device->dev);
+ if (!phys_dev)
+ phys_dev = get_device(parent);
+
+ device->cooling_dev = thermal_cooling_device_create(phys_dev, "LCD", device,
+ &video_cooling_ops);
if (IS_ERR(device->cooling_dev)) {
/*
* Set cooling_dev to NULL so we don't crash trying to free it.
@@ -1753,21 +1756,17 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
* -- dtor
*/
device->cooling_dev = NULL;
- return;
+ goto put_phys_dev;
}
- dev_info(&device->dev->dev, "registered as cooling_device%d\n",
- device->cooling_dev->id);
- result = sysfs_create_link(&device->dev->dev.kobj,
- &device->cooling_dev->device.kobj,
- "thermal_cooling");
- if (result)
- pr_info("sysfs link creation failed\n");
+ dev_info(&device->cooling_dev->device, "Using ACPI device %s\n",
+ acpi_dev_name(device->dev));
- result = sysfs_create_link(&device->cooling_dev->device.kobj,
- &device->dev->dev.kobj, "device");
- if (result)
- pr_info("Reverse sysfs link creation failed\n");
+put_phys_dev:
+ put_device(phys_dev);
+
+put_parent:
+ put_device(parent);
}
static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video)
@@ -1825,6 +1824,10 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video)
static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device)
{
+ if (device->cooling_dev) {
+ thermal_cooling_device_unregister(device->cooling_dev);
+ device->cooling_dev = NULL;
+ }
if (device->backlight) {
backlight_device_unregister(device->backlight);
device->backlight = NULL;
@@ -1834,12 +1837,6 @@ static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device
kfree(device->brightness);
device->brightness = NULL;
}
- if (device->cooling_dev) {
- sysfs_remove_link(&device->dev->dev.kobj, "thermal_cooling");
- sysfs_remove_link(&device->cooling_dev->device.kobj, "device");
- thermal_cooling_device_unregister(device->cooling_dev);
- device->cooling_dev = NULL;
- }
}
static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video)
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c
index d7d56cc600d3..f7e503bf57c8 100644
--- a/drivers/acpi/acpica/dsfield.c
+++ b/drivers/acpi/acpica/dsfield.c
@@ -522,7 +522,8 @@ acpi_ds_create_field(union acpi_parse_object *op,
}
if (info.region_node->object->region.space_id ==
- ACPI_ADR_SPACE_PLATFORM_COMM) {
+ ACPI_ADR_SPACE_PLATFORM_COMM &&
+ !region_node->object->field.internal_pcc_buffer) {
region_node->object->field.internal_pcc_buffer =
ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
length);
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index 9a55524ed8f4..50317fe0cbd5 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -45,12 +45,13 @@ static const u8 acpi_protocol_lengths[] = {
/*
* The following macros determine a given offset is a COMD field.
- * According to the specification, generic subspaces (types 0-2) contains a
- * 2-byte COMD field at offset 4 and master subspaces (type 3) contains a 4-byte
- * COMD field starting at offset 12.
+ * According to the specification, the PCC OperationRegion begins after
+ * the PCC signature. The raw shared memory COMD offsets of 4 for generic
+ * subspaces (types 0-2) and 12 for master subspaces (type 3) therefore
+ * appear at OperationRegion offsets 0 and 8.
*/
-#define GENERIC_SUBSPACE_COMMAND(a) (4 == a || a == 5)
-#define MASTER_SUBSPACE_COMMAND(a) (12 <= a && a <= 15)
+#define GENERIC_SUBSPACE_COMMAND(a) (0 == a || a == 1)
+#define MASTER_SUBSPACE_COMMAND(a) (8 <= a && a <= 11)
/*******************************************************************************
*
diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h
index e20d6ad9df80..3faa247af514 100644
--- a/drivers/acpi/fan.h
+++ b/drivers/acpi/fan.h
@@ -52,7 +52,7 @@ struct acpi_fan_fst {
};
struct acpi_fan {
- acpi_handle handle;
+ struct acpi_device *adev;
bool acpi4;
bool has_fst;
struct acpi_fan_fif fif;
diff --git a/drivers/acpi/fan_core.c b/drivers/acpi/fan_core.c
index 624d0736b581..3674f9613d40 100644
--- a/drivers/acpi/fan_core.c
+++ b/drivers/acpi/fan_core.c
@@ -54,8 +54,7 @@ MODULE_DEVICE_TABLE(acpi, fan_device_ids);
static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
*state)
{
- struct acpi_device *device = cdev->devdata;
- struct acpi_fan *fan = acpi_driver_data(device);
+ struct acpi_fan *fan = cdev->devdata;
if (fan->acpi4) {
if (fan->fif.fine_grain_ctrl)
@@ -72,42 +71,34 @@ static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
acpi_status status;
- int ret = 0;
status = acpi_evaluate_object(handle, "_FST", NULL, &buffer);
if (ACPI_FAILURE(status))
- return -EIO;
+ return -ENXIO;
- obj = buffer.pointer;
+ union acpi_object *obj __free(acpi_object_free) = buffer.pointer;
if (!obj)
return -ENODATA;
- if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3) {
- ret = -EPROTO;
- goto err;
- }
+ if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3)
+ return -EPROTO;
if (obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
obj->package.elements[1].type != ACPI_TYPE_INTEGER ||
- obj->package.elements[2].type != ACPI_TYPE_INTEGER) {
- ret = -EPROTO;
- goto err;
- }
+ obj->package.elements[2].type != ACPI_TYPE_INTEGER)
+ return -EPROTO;
fst->revision = obj->package.elements[0].integer.value;
fst->control = obj->package.elements[1].integer.value;
fst->speed = obj->package.elements[2].integer.value;
-err:
- kfree(obj);
- return ret;
+ return 0;
}
-static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
+static int fan_get_state_acpi4(struct acpi_fan *fan, unsigned long *state)
{
- struct acpi_fan *fan = acpi_driver_data(device);
+ struct acpi_device *device = fan->adev;
struct acpi_fan_fst fst;
int status, i;
@@ -159,13 +150,12 @@ static int fan_get_state(struct acpi_device *device, unsigned long *state)
static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
*state)
{
- struct acpi_device *device = cdev->devdata;
- struct acpi_fan *fan = acpi_driver_data(device);
+ struct acpi_fan *fan = cdev->devdata;
if (fan->acpi4)
- return fan_get_state_acpi4(device, state);
+ return fan_get_state_acpi4(fan, state);
else
- return fan_get_state(device, state);
+ return fan_get_state(fan->adev, state);
}
static int fan_set_state(struct acpi_device *device, unsigned long state)
@@ -177,9 +167,9 @@ static int fan_set_state(struct acpi_device *device, unsigned long state)
state ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD);
}
-static int fan_set_state_acpi4(struct acpi_device *device, unsigned long state)
+static int fan_set_state_acpi4(struct acpi_fan *fan, unsigned long state)
{
- struct acpi_fan *fan = acpi_driver_data(device);
+ struct acpi_device *device = fan->adev;
acpi_status status;
u64 value = state;
int max_state;
@@ -213,13 +203,12 @@ static int fan_set_state_acpi4(struct acpi_device *device, unsigned long state)
static int
fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
- struct acpi_device *device = cdev->devdata;
- struct acpi_fan *fan = acpi_driver_data(device);
+ struct acpi_fan *fan = cdev->devdata;
if (fan->acpi4)
- return fan_set_state_acpi4(device, state);
+ return fan_set_state_acpi4(fan, state);
else
- return fan_set_state(device, state);
+ return fan_set_state(fan->adev, state);
}
static const struct thermal_cooling_device_ops fan_cooling_ops = {
@@ -240,25 +229,22 @@ static int acpi_fan_get_fif(struct acpi_device *device)
struct acpi_buffer format = { sizeof("NNNN"), "NNNN" };
u64 fields[4];
struct acpi_buffer fif = { sizeof(fields), fields };
- union acpi_object *obj;
acpi_status status;
status = acpi_evaluate_object(device->handle, "_FIF", NULL, &buffer);
if (ACPI_FAILURE(status))
- return status;
+ return -ENXIO;
- obj = buffer.pointer;
+ union acpi_object *obj __free(acpi_object_free) = buffer.pointer;
if (!obj || obj->type != ACPI_TYPE_PACKAGE) {
dev_err(&device->dev, "Invalid _FIF data\n");
- status = -EINVAL;
- goto err;
+ return -ENODATA;
}
status = acpi_extract_package(obj, &format, &fif);
if (ACPI_FAILURE(status)) {
dev_err(&device->dev, "Invalid _FIF element\n");
- status = -EINVAL;
- goto err;
+ return -ENODATA;
}
fan->fif.revision = fields[0];
@@ -272,9 +258,8 @@ static int acpi_fan_get_fif(struct acpi_device *device)
/* If step size > 9, change to 9 (by spec valid values 1-9) */
else if (fan->fif.step_size > 9)
fan->fif.step_size = 9;
-err:
- kfree(obj);
- return status;
+
+ return 0;
}
static int acpi_fan_speed_cmp(const void *a, const void *b)
@@ -284,34 +269,28 @@ static int acpi_fan_speed_cmp(const void *a, const void *b)
return fps1->speed - fps2->speed;
}
-static int acpi_fan_get_fps(struct acpi_device *device)
+static int acpi_fan_get_fps(struct device *dev, struct acpi_device *device)
{
struct acpi_fan *fan = acpi_driver_data(device);
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
acpi_status status;
int i;
status = acpi_evaluate_object(device->handle, "_FPS", NULL, &buffer);
if (ACPI_FAILURE(status))
- return status;
+ return -ENXIO;
- obj = buffer.pointer;
+ union acpi_object *obj __free(acpi_object_free) = buffer.pointer;
if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count < 2) {
dev_err(&device->dev, "Invalid _FPS data\n");
- status = -EINVAL;
- goto err;
+ return -ENODATA;
}
fan->fps_count = obj->package.count - 1; /* minus revision field */
- fan->fps = devm_kcalloc(&device->dev,
- fan->fps_count, sizeof(struct acpi_fan_fps),
- GFP_KERNEL);
- if (!fan->fps) {
- dev_err(&device->dev, "Not enough memory\n");
- status = -ENOMEM;
- goto err;
- }
+ fan->fps = devm_kcalloc(dev, fan->fps_count, sizeof(*fan->fps), GFP_KERNEL);
+ if (!fan->fps)
+ return -ENOMEM;
+
for (i = 0; i < fan->fps_count; i++) {
struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" };
struct acpi_buffer fps = { offsetof(struct acpi_fan_fps, name),
@@ -320,7 +299,7 @@ static int acpi_fan_get_fps(struct acpi_device *device)
&format, &fps);
if (ACPI_FAILURE(status)) {
dev_err(&device->dev, "Invalid _FPS element\n");
- goto err;
+ return -ENODATA;
}
}
@@ -328,9 +307,7 @@ static int acpi_fan_get_fps(struct acpi_device *device)
sort(fan->fps, fan->fps_count, sizeof(*fan->fps),
acpi_fan_speed_cmp, NULL);
-err:
- kfree(obj);
- return status;
+ return 0;
}
static int acpi_fan_dsm_init(struct device *dev)
@@ -343,30 +320,28 @@ static int acpi_fan_dsm_init(struct device *dev)
},
};
struct acpi_fan *fan = dev_get_drvdata(dev);
- union acpi_object *obj;
- int ret = 0;
+ acpi_handle fan_handle = fan->adev->handle;
- if (!acpi_check_dsm(fan->handle, &acpi_fan_microsoft_guid, 0,
+ if (!acpi_check_dsm(fan_handle, &acpi_fan_microsoft_guid, 0,
BIT(ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY) |
BIT(ACPI_FAN_DSM_SET_TRIP_POINTS)))
return 0;
dev_info(dev, "Using Microsoft fan extensions\n");
- obj = acpi_evaluate_dsm_typed(fan->handle, &acpi_fan_microsoft_guid, 0,
- ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY, &dummy,
- ACPI_TYPE_INTEGER);
+ union acpi_object *obj __free(acpi_object_free) =
+ acpi_evaluate_dsm_typed(fan_handle, &acpi_fan_microsoft_guid, 0,
+ ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY,
+ &dummy, ACPI_TYPE_INTEGER);
if (!obj)
- return -EIO;
+ return -ENXIO;
if (obj->integer.value > U32_MAX)
- ret = -EOVERFLOW;
- else
- fan->fan_trip_granularity = obj->integer.value;
+ return -EOVERFLOW;
- kfree(obj);
+ fan->fan_trip_granularity = obj->integer.value;
- return ret;
+ return 0;
}
static int acpi_fan_dsm_set_trip_points(struct device *dev, u64 upper, u64 lower)
@@ -395,9 +370,9 @@ static int acpi_fan_dsm_set_trip_points(struct device *dev, u64 upper, u64 lower
};
union acpi_object *obj;
- obj = acpi_evaluate_dsm(fan->handle, &acpi_fan_microsoft_guid, 0,
- ACPI_FAN_DSM_SET_TRIP_POINTS, &in);
- kfree(obj);
+ obj = acpi_evaluate_dsm(fan->adev->handle, &acpi_fan_microsoft_guid,
+ 0, ACPI_FAN_DSM_SET_TRIP_POINTS, &in);
+ ACPI_FREE(obj);
return 0;
}
@@ -506,7 +481,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
return -ENOMEM;
}
- fan->handle = device->handle;
+ fan->adev = device;
device->driver_data = fan;
platform_set_drvdata(pdev, fan);
@@ -522,7 +497,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
if (result)
return result;
- result = acpi_fan_get_fps(device);
+ result = acpi_fan_get_fps(&pdev->dev, device);
if (result)
return result;
}
@@ -567,8 +542,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
else
name = acpi_device_bid(device);
- cdev = thermal_cooling_device_register(name, device,
- &fan_cooling_ops);
+ cdev = thermal_cooling_device_create(&pdev->dev, name, fan, &fan_cooling_ops);
if (IS_ERR(cdev)) {
result = PTR_ERR(cdev);
goto err_end;
@@ -577,28 +551,9 @@ static int acpi_fan_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "registered as cooling_device%d\n", cdev->id);
fan->cdev = cdev;
- result = sysfs_create_link(&pdev->dev.kobj,
- &cdev->device.kobj,
- "thermal_cooling");
- if (result) {
- dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n");
- goto err_unregister;
- }
-
- result = sysfs_create_link(&cdev->device.kobj,
- &pdev->dev.kobj,
- "device");
- if (result) {
- dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n");
- goto err_remove_link;
- }
return 0;
-err_remove_link:
- sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
-err_unregister:
- thermal_cooling_device_unregister(cdev);
err_end:
if (fan->has_fst)
acpi_fan_delete_attributes(device);
@@ -615,8 +570,6 @@ static void acpi_fan_remove(struct platform_device *pdev)
acpi_fan_delete_attributes(device);
}
- sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
- sysfs_remove_link(&fan->cdev->device.kobj, "device");
thermal_cooling_device_unregister(fan->cdev);
}
diff --git a/drivers/acpi/fan_hwmon.c b/drivers/acpi/fan_hwmon.c
index d3374f8f524b..c5d8419f41c5 100644
--- a/drivers/acpi/fan_hwmon.c
+++ b/drivers/acpi/fan_hwmon.c
@@ -94,7 +94,7 @@ static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
struct acpi_fan_fst fst;
int ret;
- ret = acpi_fan_get_fst(fan->handle, &fst);
+ ret = acpi_fan_get_fst(fan->adev->handle, &fst);
if (ret < 0)
return ret;
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index cdc2ae1632b2..bdd1529d79f0 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -164,7 +164,7 @@ static int __acpi_processor_start(struct acpi_device *device)
acpi_pss_perf_init(pr);
- result = acpi_processor_thermal_init(pr, device);
+ result = acpi_processor_thermal_init(pr);
if (result)
goto err_power_exit;
@@ -179,7 +179,7 @@ static int __acpi_processor_start(struct acpi_device *device)
return 0;
err_thermal_exit:
- acpi_processor_thermal_exit(pr, device);
+ acpi_processor_thermal_exit(pr);
err_power_exit:
acpi_processor_power_exit(pr);
return result;
@@ -203,7 +203,7 @@ static int acpi_processor_stop(struct device *dev)
acpi_cppc_processor_exit(pr);
- acpi_processor_thermal_exit(pr, device);
+ acpi_processor_thermal_exit(pr);
return 0;
}
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index c7b1dc5687ec..11036f0d2b94 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -235,15 +235,7 @@ static int
processor_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
- struct acpi_device *device = cdev->devdata;
- struct acpi_processor *pr;
-
- if (!device)
- return -EINVAL;
-
- pr = acpi_driver_data(device);
- if (!pr)
- return -EINVAL;
+ struct acpi_processor *pr = cdev->devdata;
*state = acpi_processor_max_state(pr);
return 0;
@@ -253,15 +245,7 @@ static int
processor_get_cur_state(struct thermal_cooling_device *cdev,
unsigned long *cur_state)
{
- struct acpi_device *device = cdev->devdata;
- struct acpi_processor *pr;
-
- if (!device)
- return -EINVAL;
-
- pr = acpi_driver_data(device);
- if (!pr)
- return -EINVAL;
+ struct acpi_processor *pr = cdev->devdata;
*cur_state = cpufreq_get_cur_state(pr->id);
if (pr->flags.throttling)
@@ -273,18 +257,10 @@ static int
processor_set_cur_state(struct thermal_cooling_device *cdev,
unsigned long state)
{
- struct acpi_device *device = cdev->devdata;
- struct acpi_processor *pr;
+ struct acpi_processor *pr = cdev->devdata;
int result = 0;
int max_pstate;
- if (!device)
- return -EINVAL;
-
- pr = acpi_driver_data(device);
- if (!pr)
- return -EINVAL;
-
max_pstate = cpufreq_get_max_state(pr->id);
if (state > acpi_processor_max_state(pr))
@@ -308,55 +284,21 @@ const struct thermal_cooling_device_ops processor_cooling_ops = {
.set_cur_state = processor_set_cur_state,
};
-int acpi_processor_thermal_init(struct acpi_processor *pr,
- struct acpi_device *device)
+int acpi_processor_thermal_init(struct acpi_processor *pr)
{
- int result = 0;
-
- pr->cdev = thermal_cooling_device_register("Processor", device,
- &processor_cooling_ops);
- if (IS_ERR(pr->cdev)) {
- result = PTR_ERR(pr->cdev);
- return result;
- }
-
- dev_dbg(&device->dev, "registered as cooling_device%d\n",
- pr->cdev->id);
+ pr->cdev = thermal_cooling_device_create(pr->dev, "Processor", pr,
+ &processor_cooling_ops);
+ if (IS_ERR(pr->cdev))
+ return PTR_ERR(pr->cdev);
- result = sysfs_create_link(&device->dev.kobj,
- &pr->cdev->device.kobj,
- "thermal_cooling");
- if (result) {
- dev_err(&device->dev,
- "Failed to create sysfs link 'thermal_cooling'\n");
- goto err_thermal_unregister;
- }
-
- result = sysfs_create_link(&pr->cdev->device.kobj,
- &device->dev.kobj,
- "device");
- if (result) {
- dev_err(&pr->cdev->device,
- "Failed to create sysfs link 'device'\n");
- goto err_remove_sysfs_thermal;
- }
+ dev_dbg(pr->dev, "registered as cooling_device%d\n", pr->cdev->id);
return 0;
-
-err_remove_sysfs_thermal:
- sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
-err_thermal_unregister:
- thermal_cooling_device_unregister(pr->cdev);
-
- return result;
}
-void acpi_processor_thermal_exit(struct acpi_processor *pr,
- struct acpi_device *device)
+void acpi_processor_thermal_exit(struct acpi_processor *pr)
{
- if (pr->cdev) {
- sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
- sysfs_remove_link(&pr->cdev->device.kobj, "device");
+ if (!IS_ERR_OR_NULL(pr->cdev)) {
thermal_cooling_device_unregister(pr->cdev);
pr->cdev = NULL;
}
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index dd7666c176a0..13e9a3a79d92 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -564,17 +564,20 @@ static bool acpi_thermal_should_bind_cdev(struct thermal_zone_device *thermal,
struct cooling_spec *c)
{
struct acpi_thermal_trip *acpi_trip = trip->priv;
- struct acpi_device *cdev_adev = cdev->devdata;
+ struct device *parent = cdev->device.parent;
+ acpi_handle parent_handle;
int i;
- /* Skip critical and hot trips. */
- if (!acpi_trip)
+ /* Skip critical and hot trips and parentless cooling devices. */
+ if (!acpi_trip || !parent)
return false;
- for (i = 0; i < acpi_trip->devices.count; i++) {
- acpi_handle handle = acpi_trip->devices.handles[i];
+ parent_handle = ACPI_HANDLE(parent);
+ if (!parent_handle)
+ return false;
- if (acpi_fetch_acpi_dev(handle) == cdev_adev)
+ for (i = 0; i < acpi_trip->devices.count; i++) {
+ if (acpi_trip->devices.handles[i] == parent_handle)
return true;
}
@@ -738,7 +741,9 @@ static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz)
*/
static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp)
{
- if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1)
+ if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 0)
+ tz->kelvin_offset = 273000;
+ else if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1)
tz->kelvin_offset = 273100;
else
tz->kelvin_offset = 273200;
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 82e2f0d8a26d..ac928c199829 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1005,7 +1005,8 @@ out_kfree_cdev:
return ERR_PTR(ret);
}
-int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdata)
+int thermal_cooling_device_add(struct thermal_cooling_device *cdev,
+ struct device *parent, void *devdata)
{
unsigned long current_state;
int ret;
@@ -1013,6 +1014,7 @@ int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdat
mutex_init(&cdev->lock);
INIT_LIST_HEAD(&cdev->thermal_instances);
cdev->updated = false;
+ cdev->device.parent = parent;
cdev->device.class = &thermal_class;
cdev->device.release = thermal_cdev_release;
device_initialize(&cdev->device);
@@ -1062,21 +1064,23 @@ out_put_device:
}
/**
- * thermal_cooling_device_register() - register a new thermal cooling device
+ * thermal_cooling_device_create() - register a new thermal cooling device
+ * @parent: parent device (optional).
* @type: the thermal cooling device type.
* @devdata: device private data.
* @ops: standard thermal cooling devices callbacks.
*
- * This interface function adds a new thermal cooling device (fan/processor/...)
- * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
- * to all the thermal zone devices registered at the same time.
+ * Allocate and register a new thermal cooling device under the given parent (if
+ * not NULL) and with the given type, device data, and operations. During the
+ * registration, it will be matched against all of the registered thermal zones
+ * and it will be bound to the matching ones.
*
- * Return: a pointer to the created struct thermal_cooling_device or an
- * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
+ * Return: A pointer to the created struct thermal_cooling_device or an ERR_PTR.
+ * Callers must use IS_ERR*() helpers to check the return value.
*/
-struct thermal_cooling_device *
-thermal_cooling_device_register(const char *type, void *devdata,
- const struct thermal_cooling_device_ops *ops)
+struct thermal_cooling_device *thermal_cooling_device_create(
+ struct device *parent, const char *type, void *devdata,
+ const struct thermal_cooling_device_ops *ops)
{
struct thermal_cooling_device *cdev;
int ret;
@@ -1085,13 +1089,13 @@ thermal_cooling_device_register(const char *type, void *devdata,
if (IS_ERR(cdev))
return cdev;
- ret = thermal_cooling_device_add(cdev, devdata);
+ ret = thermal_cooling_device_add(cdev, parent, devdata);
if (ret)
return ERR_PTR(ret);
return cdev;
}
-EXPORT_SYMBOL_GPL(thermal_cooling_device_register);
+EXPORT_SYMBOL_GPL(thermal_cooling_device_create);
static void thermal_cooling_device_release(void *data)
{
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index e98b0aa5aacc..7ef7c6cab437 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -270,7 +270,8 @@ void thermal_governor_update_tz(struct thermal_zone_device *tz,
struct thermal_cooling_device *
thermal_cooling_device_alloc(const char *type, const struct thermal_cooling_device_ops *ops);
-int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdata);
+int thermal_cooling_device_add(struct thermal_cooling_device *cdev,
+ struct device *parent, void *devdata);
/* Helpers */
#define for_each_trip_desc(__tz, __td) \
diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index 0217a49b08ae..14dfac9359b8 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -561,7 +561,7 @@ thermal_of_cooling_device_register(struct device_node *np, u32 cdev_id,
cdev->np = np;
cdev->cdev_id = cdev_id;
- ret = thermal_cooling_device_add(cdev, devdata);
+ ret = thermal_cooling_device_add(cdev, NULL, devdata);
if (ret)
return ERR_PTR(ret);
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index baef525367b5..76e4a5bc79b4 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -919,6 +919,13 @@ struct acpi_iovt_iommu {
u32 device_entry_offset;
};
+/* Masks for Flags field above */
+#define ACPI_IOVT_IOMMU_PCI_DEVICE (1<<0)
+#define ACPI_IOVT_IOMMU_PXM_VALID (1<<1)
+#define ACPI_IOVT_IOMMU_MAGAGE_BY_SEGMENT (1<<2)
+#define ACPI_IOVT_IOMMU_HW_CAP_SUPPORT (1<<3)
+#define ACPI_IOVT_IOMMU_MSI_INT_BYPASS (1<<4)
+
struct acpi_iovt_device_entry {
u8 type;
u8 length;
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 554be224ce76..b5447af4d40b 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -427,10 +427,8 @@ int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi);
#endif /* CONFIG_ACPI_PROCESSOR_IDLE */
/* in processor_thermal.c */
-int acpi_processor_thermal_init(struct acpi_processor *pr,
- struct acpi_device *device);
-void acpi_processor_thermal_exit(struct acpi_processor *pr,
- struct acpi_device *device);
+int acpi_processor_thermal_init(struct acpi_processor *pr);
+void acpi_processor_thermal_exit(struct acpi_processor *pr);
extern const struct thermal_cooling_device_ops processor_cooling_ops;
#ifdef CONFIG_CPU_FREQ
void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index f7e3efd328f7..8dbc4e8bf227 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -29,6 +29,8 @@ struct irq_domain_ops;
#ifdef CONFIG_ACPI
+DEFINE_FREE(acpi_object_free, union acpi_object *, if (_T) ACPI_FREE(_T));
+
#include <linux/list.h>
#include <linux/dynamic_debug.h>
#include <linux/module.h>
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 083b4f533933..306ad17aed89 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -293,8 +293,9 @@ struct device *thermal_zone_device(struct thermal_zone_device *tzd);
void thermal_zone_device_update(struct thermal_zone_device *,
enum thermal_notify_event);
-struct thermal_cooling_device *thermal_cooling_device_register(const char *,
- void *, const struct thermal_cooling_device_ops *);
+struct thermal_cooling_device *thermal_cooling_device_create(
+ struct device *parent, const char *type, void *devdata,
+ const struct thermal_cooling_device_ops *ops);
struct thermal_cooling_device *
devm_thermal_cooling_device_register(struct device *dev, const char *type, void *devdata,
@@ -340,9 +341,9 @@ static inline void thermal_zone_device_update(struct thermal_zone_device *tz,
enum thermal_notify_event event)
{ }
-static inline struct thermal_cooling_device *
-thermal_cooling_device_register(const char *type, void *devdata,
- const struct thermal_cooling_device_ops *ops)
+static inline struct thermal_cooling_device *thermal_cooling_device_create(
+ struct device *parent, const char *type, void *devdata,
+ const struct thermal_cooling_device_ops *ops)
{ return ERR_PTR(-ENODEV); }
static inline struct thermal_cooling_device *
@@ -391,4 +392,12 @@ static inline void thermal_pm_prepare(void) {}
static inline void thermal_pm_complete(void) {}
#endif /* CONFIG_THERMAL */
+static inline struct thermal_cooling_device *thermal_cooling_device_register(
+ const char *type, void *devdata,
+ const struct thermal_cooling_device_ops *ops)
+{
+ return thermal_cooling_device_create(NULL, type, devdata, ops);
+}
+
+
#endif /* __THERMAL_H__ */