Commit 0586d263 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-thermal' and 'acpi-button'

Merge ACPI thermal driver cleanups and ACPI button drivers rework for
6.5-rc1:

 - Clean up the ACPI thermal driver and drop some dead or otherwise
   unneded code from it (Rafael Wysocki).

 - Rework the handling of notifications in the ACPI button drivers so
   as to allow the common notification handling code for devices to be
   simplified (Rafael Wysocki).

* acpi-thermal:
  ACPI: thermal: Drop struct acpi_thermal_flags
  ACPI: thermal: Drop struct acpi_thermal_state
  ACPI: thermal: Eliminate struct acpi_thermal_state_flags
  ACPI: thermal: Move acpi_thermal_driver definition
  ACPI: thermal: Move symbol definitions to one place
  ACPI: thermal: Drop redundant ACPI_TRIPS_REFRESH_DEVICES symbol
  ACPI: thermal: Use BIT() macro for defining flags

* acpi-button:
  ACPI: bus: Simplify installation and removal of notify callback
  ACPI: tiny-power-button: Eliminate the driver notify callback
  ACPI: button: Use different notify handlers for lid and buttons
  ACPI: button: Eliminate the driver notify callback
Loading
Loading
Loading
Loading
+9 −44
Original line number Diff line number Diff line
@@ -530,65 +530,30 @@ static void acpi_notify_device(acpi_handle handle, u32 event, void *data)
	acpi_drv->ops.notify(device, event);
}

static void acpi_notify_device_fixed(void *data)
{
	struct acpi_device *device = data;

	/* Fixed hardware devices have no handles */
	acpi_notify_device(NULL, ACPI_FIXED_HARDWARE_EVENT, device);
}

static u32 acpi_device_fixed_event(void *data)
{
	acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_notify_device_fixed, data);
	return ACPI_INTERRUPT_HANDLED;
}

static int acpi_device_install_notify_handler(struct acpi_device *device,
					      struct acpi_driver *acpi_drv)
{
	acpi_status status;

	if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) {
		status =
		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
						     acpi_device_fixed_event,
						     device);
	} else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) {
		status =
		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
						     acpi_device_fixed_event,
						     device);
	} else {
	u32 type = acpi_drv->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS ?
				ACPI_ALL_NOTIFY : ACPI_DEVICE_NOTIFY;
	acpi_status status;

	status = acpi_install_notify_handler(device->handle, type,
						     acpi_notify_device,
						     device);
	}

					     acpi_notify_device, device);
	if (ACPI_FAILURE(status))
		return -EINVAL;

	return 0;
}

static void acpi_device_remove_notify_handler(struct acpi_device *device,
					      struct acpi_driver *acpi_drv)
{
	if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) {
		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
						acpi_device_fixed_event);
	} else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) {
		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
						acpi_device_fixed_event);
	} else {
	u32 type = acpi_drv->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS ?
				ACPI_ALL_NOTIFY : ACPI_DEVICE_NOTIFY;

	acpi_remove_notify_handler(device->handle, type,
				   acpi_notify_device);
	}

	acpi_os_wait_events_complete();
}

+111 −44
Original line number Diff line number Diff line
@@ -135,7 +135,6 @@ static const struct dmi_system_id dmi_lid_quirks[] = {

static int acpi_button_add(struct acpi_device *device);
static void acpi_button_remove(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event);

#ifdef CONFIG_PM_SLEEP
static int acpi_button_suspend(struct device *dev);
@@ -153,7 +152,6 @@ static struct acpi_driver acpi_button_driver = {
	.ops = {
		.add = acpi_button_add,
		.remove = acpi_button_remove,
		.notify = acpi_button_notify,
	},
	.drv.pm = &acpi_button_pm,
};
@@ -409,45 +407,65 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
	button->lid_state_initialized = true;
}

static void acpi_button_notify(struct acpi_device *device, u32 event)
static void acpi_lid_notify(acpi_handle handle, u32 event, void *data)
{
	struct acpi_button *button = acpi_driver_data(device);
	struct input_dev *input;
	struct acpi_device *device = data;
	struct acpi_button *button;

	if (event != ACPI_BUTTON_NOTIFY_STATUS) {
		acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
				  event);
		return;
	}

	button = acpi_driver_data(device);
	if (!button->lid_state_initialized)
		return;

	switch (event) {
	case ACPI_FIXED_HARDWARE_EVENT:
		event = ACPI_BUTTON_NOTIFY_STATUS;
		fallthrough;
	case ACPI_BUTTON_NOTIFY_STATUS:
		input = button->input;
		if (button->type == ACPI_BUTTON_TYPE_LID) {
			if (button->lid_state_initialized)
	acpi_lid_update_state(device, true);
		} else {
}

static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
{
	struct acpi_device *device = data;
	struct acpi_button *button;
	struct input_dev *input;
	int keycode;

	if (event != ACPI_BUTTON_NOTIFY_STATUS) {
		acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
				  event);
		return;
	}

	acpi_pm_wakeup_event(&device->dev);

	button = acpi_driver_data(device);
	if (button->suspended)
				break;
		return;

	input = button->input;
	keycode = test_bit(KEY_SLEEP, input->keybit) ? KEY_SLEEP : KEY_POWER;

			keycode = test_bit(KEY_SLEEP, input->keybit) ?
						KEY_SLEEP : KEY_POWER;
	input_report_key(input, keycode, 1);
	input_sync(input);
	input_report_key(input, keycode, 0);
	input_sync(input);

			acpi_bus_generate_netlink_event(
					device->pnp.device_class,
	acpi_bus_generate_netlink_event(device->pnp.device_class,
					dev_name(&device->dev),
					event, ++button->pushed);
}
		break;
	default:
		acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
				  event);
		break;

static void acpi_button_notify_run(void *data)
{
	acpi_button_notify(NULL, ACPI_BUTTON_NOTIFY_STATUS, data);
}

static u32 acpi_button_event(void *data)
{
	acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_button_notify_run, data);
	return ACPI_INTERRUPT_HANDLED;
}

#ifdef CONFIG_PM_SLEEP
@@ -489,11 +507,13 @@ static int acpi_lid_input_open(struct input_dev *input)

static int acpi_button_add(struct acpi_device *device)
{
	acpi_notify_handler handler;
	struct acpi_button *button;
	struct input_dev *input;
	const char *hid = acpi_device_hid(device);
	acpi_status status;
	char *name, *class;
	int error;
	int error = 0;

	if (!strcmp(hid, ACPI_BUTTON_HID_LID) &&
	     lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED)
@@ -517,17 +537,20 @@ static int acpi_button_add(struct acpi_device *device)
	if (!strcmp(hid, ACPI_BUTTON_HID_POWER) ||
	    !strcmp(hid, ACPI_BUTTON_HID_POWERF)) {
		button->type = ACPI_BUTTON_TYPE_POWER;
		handler = acpi_button_notify;
		strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER);
		sprintf(class, "%s/%s",
			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
	} else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) ||
		   !strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) {
		button->type = ACPI_BUTTON_TYPE_SLEEP;
		handler = acpi_button_notify;
		strcpy(name, ACPI_BUTTON_DEVICE_NAME_SLEEP);
		sprintf(class, "%s/%s",
			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
	} else if (!strcmp(hid, ACPI_BUTTON_HID_LID)) {
		button->type = ACPI_BUTTON_TYPE_LID;
		handler = acpi_lid_notify;
		strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
		sprintf(class, "%s/%s",
			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
@@ -535,12 +558,15 @@ static int acpi_button_add(struct acpi_device *device)
	} else {
		pr_info("Unsupported hid [%s]\n", hid);
		error = -ENODEV;
		goto err_free_input;
	}

	if (!error)
		error = acpi_button_add_fs(device);
	if (error)
		goto err_free_input;

	if (error) {
		input_free_device(input);
		goto err_free_button;
	}

	snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);

@@ -568,6 +594,29 @@ static int acpi_button_add(struct acpi_device *device)
	error = input_register_device(input);
	if (error)
		goto err_remove_fs;

	switch (device->device_type) {
	case ACPI_BUS_TYPE_POWER_BUTTON:
		status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
							  acpi_button_event,
							  device);
		break;
	case ACPI_BUS_TYPE_SLEEP_BUTTON:
		status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
							  acpi_button_event,
							  device);
		break;
	default:
		status = acpi_install_notify_handler(device->handle,
						     ACPI_DEVICE_NOTIFY, handler,
						     device);
		break;
	}
	if (ACPI_FAILURE(status)) {
		error = -ENODEV;
		goto err_input_unregister;
	}

	if (button->type == ACPI_BUTTON_TYPE_LID) {
		/*
		 * This assumes there's only one lid device, or if there are
@@ -580,10 +629,10 @@ static int acpi_button_add(struct acpi_device *device)
	pr_info("%s [%s]\n", name, acpi_device_bid(device));
	return 0;

err_input_unregister:
	input_unregister_device(input);
err_remove_fs:
	acpi_button_remove_fs(device);
 err_free_input:
	input_free_device(input);
err_free_button:
	kfree(button);
	return error;
@@ -593,6 +642,24 @@ static void acpi_button_remove(struct acpi_device *device)
{
	struct acpi_button *button = acpi_driver_data(device);

	switch (device->device_type) {
	case ACPI_BUS_TYPE_POWER_BUTTON:
		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
						acpi_button_event);
		break;
	case ACPI_BUS_TYPE_SLEEP_BUTTON:
		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
						acpi_button_event);
		break;
	default:
		acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
					   button->type == ACPI_BUTTON_TYPE_LID ?
						acpi_lid_notify :
						acpi_button_notify);
		break;
	}
	acpi_os_wait_events_complete();

	acpi_button_remove_fs(device);
	input_unregister_device(button->input);
	kfree(button);
+121 −166
Original line number Diff line number Diff line
@@ -43,9 +43,32 @@
#define ACPI_THERMAL_MAX_ACTIVE		10
#define ACPI_THERMAL_MAX_LIMIT_STR_LEN	65

MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
MODULE_LICENSE("GPL");
#define ACPI_TRIPS_CRITICAL	BIT(0)
#define ACPI_TRIPS_HOT		BIT(1)
#define ACPI_TRIPS_PASSIVE	BIT(2)
#define ACPI_TRIPS_ACTIVE	BIT(3)
#define ACPI_TRIPS_DEVICES	BIT(4)

#define ACPI_TRIPS_THRESHOLDS	(ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE)

#define ACPI_TRIPS_INIT		(ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT | \
				 ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE | \
				 ACPI_TRIPS_DEVICES)

/*
 * This exception is thrown out in two cases:
 * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid
 *   when re-evaluating the AML code.
 * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change.
 *   We need to re-bind the cooling devices of a thermal zone when this occurs.
 */
#define ACPI_THERMAL_TRIPS_EXCEPTION(flags, tz, str) \
do { \
	if (flags != ACPI_TRIPS_INIT) \
		acpi_handle_info(tz->device->handle, \
			"ACPI thermal trip point %s changed\n" \
			"Please report to linux-acpi@vger.kernel.org\n", str); \
} while (0)

static int act;
module_param(act, int, 0644);
@@ -73,75 +96,30 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");

static struct workqueue_struct *acpi_thermal_pm_queue;

static int acpi_thermal_add(struct acpi_device *device);
static void acpi_thermal_remove(struct acpi_device *device);
static void acpi_thermal_notify(struct acpi_device *device, u32 event);

static const struct acpi_device_id  thermal_device_ids[] = {
	{ACPI_THERMAL_HID, 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, thermal_device_ids);

#ifdef CONFIG_PM_SLEEP
static int acpi_thermal_suspend(struct device *dev);
static int acpi_thermal_resume(struct device *dev);
#else
#define acpi_thermal_suspend NULL
#define acpi_thermal_resume NULL
#endif
static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume);

static struct acpi_driver acpi_thermal_driver = {
	.name = "thermal",
	.class = ACPI_THERMAL_CLASS,
	.ids = thermal_device_ids,
	.ops = {
		.add = acpi_thermal_add,
		.remove = acpi_thermal_remove,
		.notify = acpi_thermal_notify,
		},
	.drv.pm = &acpi_thermal_pm,
};

struct acpi_thermal_state {
	u8 critical:1;
	u8 hot:1;
	u8 passive:1;
	u8 active:1;
	u8 reserved:4;
	int active_index;
};

struct acpi_thermal_state_flags {
	u8 valid:1;
	u8 enabled:1;
	u8 reserved:6;
};

struct acpi_thermal_critical {
	struct acpi_thermal_state_flags flags;
	unsigned long temperature;
	bool valid;
};

struct acpi_thermal_hot {
	struct acpi_thermal_state_flags flags;
	unsigned long temperature;
	bool valid;
};

struct acpi_thermal_passive {
	struct acpi_thermal_state_flags flags;
	struct acpi_handle_list devices;
	unsigned long temperature;
	unsigned long tc1;
	unsigned long tc2;
	unsigned long tsp;
	struct acpi_handle_list devices;
	bool valid;
};

struct acpi_thermal_active {
	struct acpi_thermal_state_flags flags;
	unsigned long temperature;
	struct acpi_handle_list devices;
	unsigned long temperature;
	bool valid;
	bool enabled;
};

struct acpi_thermal_trips {
@@ -151,12 +129,6 @@ struct acpi_thermal_trips {
	struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
};

struct acpi_thermal_flags {
	u8 cooling_mode:1;	/* _SCP */
	u8 devices:1;		/* _TZD */
	u8 reserved:6;
};

struct acpi_thermal {
	struct acpi_device *device;
	acpi_bus_id name;
@@ -164,8 +136,6 @@ struct acpi_thermal {
	unsigned long last_temperature;
	unsigned long polling_frequency;
	volatile u8 zombie;
	struct acpi_thermal_flags flags;
	struct acpi_thermal_state state;
	struct acpi_thermal_trips trips;
	struct acpi_handle_list devices;
	struct thermal_zone_device *thermal_zone;
@@ -220,52 +190,12 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
	return 0;
}

static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
{
	if (!tz)
		return -EINVAL;

	if (ACPI_FAILURE(acpi_execute_simple_method(tz->device->handle,
						    "_SCP", mode)))
		return -ENODEV;

	return 0;
}

#define ACPI_TRIPS_CRITICAL	0x01
#define ACPI_TRIPS_HOT		0x02
#define ACPI_TRIPS_PASSIVE	0x04
#define ACPI_TRIPS_ACTIVE	0x08
#define ACPI_TRIPS_DEVICES	0x10

#define ACPI_TRIPS_REFRESH_THRESHOLDS	(ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE)
#define ACPI_TRIPS_REFRESH_DEVICES	ACPI_TRIPS_DEVICES

#define ACPI_TRIPS_INIT      (ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT |	\
			      ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE |	\
			      ACPI_TRIPS_DEVICES)

/*
 * This exception is thrown out in two cases:
 * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid
 *   when re-evaluating the AML code.
 * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change.
 *   We need to re-bind the cooling devices of a thermal zone when this occurs.
 */
#define ACPI_THERMAL_TRIPS_EXCEPTION(flags, tz, str)	\
do {	\
	if (flags != ACPI_TRIPS_INIT)	\
		acpi_handle_info(tz->device->handle,	\
		"ACPI thermal trip point %s changed\n"	\
		"Please report to linux-acpi@vger.kernel.org\n", str); \
} while (0)

static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
{
	acpi_status status;
	unsigned long long tmp;
	struct acpi_handle_list devices;
	int valid = 0;
	bool valid = false;
	int i;

	/* Critical Shutdown */
@@ -279,21 +209,21 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
		 * ... so lets discard those as invalid.
		 */
		if (ACPI_FAILURE(status)) {
			tz->trips.critical.flags.valid = 0;
			tz->trips.critical.valid = false;
			acpi_handle_debug(tz->device->handle,
					  "No critical threshold\n");
		} else if (tmp <= 2732) {
			pr_info(FW_BUG "Invalid critical threshold (%llu)\n", tmp);
			tz->trips.critical.flags.valid = 0;
			tz->trips.critical.valid = false;
		} else {
			tz->trips.critical.flags.valid = 1;
			tz->trips.critical.valid = true;
			acpi_handle_debug(tz->device->handle,
					  "Found critical threshold [%lu]\n",
					  tz->trips.critical.temperature);
		}
		if (tz->trips.critical.flags.valid) {
		if (tz->trips.critical.valid) {
			if (crt == -1) {
				tz->trips.critical.flags.valid = 0;
				tz->trips.critical.valid = false;
			} else if (crt > 0) {
				unsigned long crt_k = celsius_to_deci_kelvin(crt);

@@ -312,12 +242,12 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
	if (flag & ACPI_TRIPS_HOT) {
		status = acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, &tmp);
		if (ACPI_FAILURE(status)) {
			tz->trips.hot.flags.valid = 0;
			tz->trips.hot.valid = false;
			acpi_handle_debug(tz->device->handle,
					  "No hot threshold\n");
		} else {
			tz->trips.hot.temperature = tmp;
			tz->trips.hot.flags.valid = 1;
			tz->trips.hot.valid = true;
			acpi_handle_debug(tz->device->handle,
					  "Found hot threshold [%lu]\n",
					  tz->trips.hot.temperature);
@@ -325,9 +255,9 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
	}

	/* Passive (optional) */
	if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) ||
	if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.valid) ||
	    flag == ACPI_TRIPS_INIT) {
		valid = tz->trips.passive.flags.valid;
		valid = tz->trips.passive.valid;
		if (psv == -1) {
			status = AE_SUPPORT;
		} else if (psv > 0) {
@@ -339,44 +269,44 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
		}

		if (ACPI_FAILURE(status)) {
			tz->trips.passive.flags.valid = 0;
			tz->trips.passive.valid = false;
		} else {
			tz->trips.passive.temperature = tmp;
			tz->trips.passive.flags.valid = 1;
			tz->trips.passive.valid = true;
			if (flag == ACPI_TRIPS_INIT) {
				status = acpi_evaluate_integer(tz->device->handle,
							       "_TC1", NULL, &tmp);
				if (ACPI_FAILURE(status))
					tz->trips.passive.flags.valid = 0;
					tz->trips.passive.valid = false;
				else
					tz->trips.passive.tc1 = tmp;

				status = acpi_evaluate_integer(tz->device->handle,
							       "_TC2", NULL, &tmp);
				if (ACPI_FAILURE(status))
					tz->trips.passive.flags.valid = 0;
					tz->trips.passive.valid = false;
				else
					tz->trips.passive.tc2 = tmp;

				status = acpi_evaluate_integer(tz->device->handle,
							       "_TSP", NULL, &tmp);
				if (ACPI_FAILURE(status))
					tz->trips.passive.flags.valid = 0;
					tz->trips.passive.valid = false;
				else
					tz->trips.passive.tsp = tmp;
			}
		}
	}
	if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.flags.valid) {
	if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.valid) {
		memset(&devices, 0, sizeof(struct acpi_handle_list));
		status = acpi_evaluate_reference(tz->device->handle, "_PSL",
						 NULL, &devices);
		if (ACPI_FAILURE(status)) {
			acpi_handle_info(tz->device->handle,
					 "Invalid passive threshold\n");
			tz->trips.passive.flags.valid = 0;
			tz->trips.passive.valid = false;
		} else {
			tz->trips.passive.flags.valid = 1;
			tz->trips.passive.valid = true;
		}

		if (memcmp(&tz->trips.passive.devices, &devices,
@@ -387,24 +317,24 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
		}
	}
	if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) {
		if (valid != tz->trips.passive.flags.valid)
		if (valid != tz->trips.passive.valid)
			ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state");
	}

	/* Active (optional) */
	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
		char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
		valid = tz->trips.active[i].flags.valid;
		valid = tz->trips.active[i].valid;

		if (act == -1)
			break; /* disable all active trip points */

		if (flag == ACPI_TRIPS_INIT || ((flag & ACPI_TRIPS_ACTIVE) &&
		    tz->trips.active[i].flags.valid)) {
		    tz->trips.active[i].valid)) {
			status = acpi_evaluate_integer(tz->device->handle,
						       name, NULL, &tmp);
			if (ACPI_FAILURE(status)) {
				tz->trips.active[i].flags.valid = 0;
				tz->trips.active[i].valid = false;
				if (i == 0)
					break;

@@ -426,21 +356,21 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
				break;
			} else {
				tz->trips.active[i].temperature = tmp;
				tz->trips.active[i].flags.valid = 1;
				tz->trips.active[i].valid = true;
			}
		}

		name[2] = 'L';
		if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid) {
		if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].valid) {
			memset(&devices, 0, sizeof(struct acpi_handle_list));
			status = acpi_evaluate_reference(tz->device->handle,
							 name, NULL, &devices);
			if (ACPI_FAILURE(status)) {
				acpi_handle_info(tz->device->handle,
						 "Invalid active%d threshold\n", i);
				tz->trips.active[i].flags.valid = 0;
				tz->trips.active[i].valid = false;
			} else {
				tz->trips.active[i].flags.valid = 1;
				tz->trips.active[i].valid = true;
			}

			if (memcmp(&tz->trips.active[i].devices, &devices,
@@ -451,10 +381,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
			}
		}
		if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES))
			if (valid != tz->trips.active[i].flags.valid)
			if (valid != tz->trips.active[i].valid)
				ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state");

		if (!tz->trips.active[i].flags.valid)
		if (!tz->trips.active[i].valid)
			break;
	}

@@ -474,17 +404,18 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)

static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
{
	int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
	int i, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
	bool valid;

	if (ret)
		return ret;

	valid = tz->trips.critical.flags.valid |
		tz->trips.hot.flags.valid |
		tz->trips.passive.flags.valid;
	valid = tz->trips.critical.valid |
		tz->trips.hot.valid |
		tz->trips.passive.valid;

	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
		valid |= tz->trips.active[i].flags.valid;
		valid = valid || tz->trips.active[i].valid;

	if (!valid) {
		pr_warn(FW_BUG "No valid trip found\n");
@@ -521,7 +452,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
	if (!tz || trip < 0)
		return -EINVAL;

	if (tz->trips.critical.flags.valid) {
	if (tz->trips.critical.valid) {
		if (!trip) {
			*type = THERMAL_TRIP_CRITICAL;
			return 0;
@@ -529,7 +460,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
		trip--;
	}

	if (tz->trips.hot.flags.valid) {
	if (tz->trips.hot.valid) {
		if (!trip) {
			*type = THERMAL_TRIP_HOT;
			return 0;
@@ -537,7 +468,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
		trip--;
	}

	if (tz->trips.passive.flags.valid) {
	if (tz->trips.passive.valid) {
		if (!trip) {
			*type = THERMAL_TRIP_PASSIVE;
			return 0;
@@ -545,7 +476,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
		trip--;
	}

	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid; i++) {
	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].valid; i++) {
		if (!trip) {
			*type = THERMAL_TRIP_ACTIVE;
			return 0;
@@ -565,7 +496,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
	if (!tz || trip < 0)
		return -EINVAL;

	if (tz->trips.critical.flags.valid) {
	if (tz->trips.critical.valid) {
		if (!trip) {
			*temp = deci_kelvin_to_millicelsius_with_offset(
					tz->trips.critical.temperature,
@@ -575,7 +506,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
		trip--;
	}

	if (tz->trips.hot.flags.valid) {
	if (tz->trips.hot.valid) {
		if (!trip) {
			*temp = deci_kelvin_to_millicelsius_with_offset(
					tz->trips.hot.temperature,
@@ -585,7 +516,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
		trip--;
	}

	if (tz->trips.passive.flags.valid) {
	if (tz->trips.passive.valid) {
		if (!trip) {
			*temp = deci_kelvin_to_millicelsius_with_offset(
					tz->trips.passive.temperature,
@@ -596,7 +527,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
	}

	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
		tz->trips.active[i].flags.valid; i++) {
		tz->trips.active[i].valid; i++) {
		if (!trip) {
			*temp = deci_kelvin_to_millicelsius_with_offset(
					tz->trips.active[i].temperature,
@@ -614,7 +545,7 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
{
	struct acpi_thermal *tz = thermal_zone_device_priv(thermal);

	if (tz->trips.critical.flags.valid) {
	if (tz->trips.critical.valid) {
		*temperature = deci_kelvin_to_millicelsius_with_offset(
					tz->trips.critical.temperature,
					tz->kelvin_offset);
@@ -700,13 +631,13 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
	int trip = -1;
	int result = 0;

	if (tz->trips.critical.flags.valid)
	if (tz->trips.critical.valid)
		trip++;

	if (tz->trips.hot.flags.valid)
	if (tz->trips.hot.valid)
		trip++;

	if (tz->trips.passive.flags.valid) {
	if (tz->trips.passive.valid) {
		trip++;
		for (i = 0; i < tz->trips.passive.devices.count; i++) {
			handle = tz->trips.passive.devices.handles[i];
@@ -731,7 +662,7 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
	}

	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
		if (!tz->trips.active[i].flags.valid)
		if (!tz->trips.active[i].valid)
			break;

		trip++;
@@ -819,19 +750,19 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
	acpi_status status;
	int i;

	if (tz->trips.critical.flags.valid)
	if (tz->trips.critical.valid)
		trips++;

	if (tz->trips.hot.flags.valid)
	if (tz->trips.hot.valid)
		trips++;

	if (tz->trips.passive.flags.valid)
	if (tz->trips.passive.valid)
		trips++;

	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid;
	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].valid;
	     i++, trips++);

	if (tz->trips.passive.flags.valid)
	if (tz->trips.passive.valid)
		tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz,
								&acpi_thermal_zone_ops, NULL,
								tz->trips.passive.tsp * 100,
@@ -906,13 +837,13 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event)
		acpi_queue_thermal_check(tz);
		break;
	case ACPI_THERMAL_NOTIFY_THRESHOLDS:
		acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS);
		acpi_thermal_trips_update(tz, ACPI_TRIPS_THRESHOLDS);
		acpi_queue_thermal_check(tz);
		acpi_bus_generate_netlink_event(device->pnp.device_class,
						dev_name(&device->dev), event, 0);
		break;
	case ACPI_THERMAL_NOTIFY_DEVICES:
		acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
		acpi_thermal_trips_update(tz, ACPI_TRIPS_DEVICES);
		acpi_queue_thermal_check(tz);
		acpi_bus_generate_netlink_event(device->pnp.device_class,
						dev_name(&device->dev), event, 0);
@@ -976,9 +907,8 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)
		return result;

	/* Set the cooling mode [_SCP] to active cooling (default) */
	result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
	if (!result)
		tz->flags.cooling_mode = 1;
	acpi_execute_simple_method(tz->device->handle, "_SCP",
				   ACPI_THERMAL_MODE_ACTIVE);

	/* Get default polling frequency [_TZP] (optional) */
	if (tzp)
@@ -1001,7 +931,7 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)
 */
static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
{
	if (tz->trips.critical.flags.valid &&
	if (tz->trips.critical.valid &&
	    (tz->trips.critical.temperature % 5) == 1)
		tz->kelvin_offset = 273100;
	else
@@ -1110,27 +1040,48 @@ static int acpi_thermal_resume(struct device *dev)
		return -EINVAL;

	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
		if (!tz->trips.active[i].flags.valid)
		if (!tz->trips.active[i].valid)
			break;

		tz->trips.active[i].flags.enabled = 1;
		tz->trips.active[i].enabled = true;
		for (j = 0; j < tz->trips.active[i].devices.count; j++) {
			result = acpi_bus_update_power(
					tz->trips.active[i].devices.handles[j],
					&power_state);
			if (result || (power_state != ACPI_STATE_D0)) {
				tz->trips.active[i].flags.enabled = 0;
				tz->trips.active[i].enabled = false;
				break;
			}
		}
		tz->state.active |= tz->trips.active[i].flags.enabled;
	}

	acpi_queue_thermal_check(tz);

	return AE_OK;
}
#else
#define acpi_thermal_suspend	NULL
#define acpi_thermal_resume	NULL
#endif
static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume);

static const struct acpi_device_id  thermal_device_ids[] = {
	{ACPI_THERMAL_HID, 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, thermal_device_ids);

static struct acpi_driver acpi_thermal_driver = {
	.name = "thermal",
	.class = ACPI_THERMAL_CLASS,
	.ids = thermal_device_ids,
	.ops = {
		.add = acpi_thermal_add,
		.remove = acpi_thermal_remove,
		.notify = acpi_thermal_notify,
		},
	.drv.pm = &acpi_thermal_pm,
};

static int thermal_act(const struct dmi_system_id *d) {
	if (act == 0) {
@@ -1236,3 +1187,7 @@ static void __exit acpi_thermal_exit(void)

module_init(acpi_thermal_init);
module_exit(acpi_thermal_exit);

MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
MODULE_LICENSE("GPL");
+41 −8

File changed.

Preview size limit exceeded, changes collapsed.