Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb4af417 authored by Len Brown's avatar Len Brown
Browse files

Merge branch 'wakeup-etc-rafael' into release

parents 07bf2805 7b330707
Loading
Loading
Loading
Loading
+55 −39
Original line number Diff line number Diff line
@@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
 * RETURN:      ACPI_INTERRUPT_HANDLED
 *
 * DESCRIPTION: Invoked directly from the SCI handler when a global lock
 *              release interrupt occurs. Attempt to acquire the global lock,
 *              if successful, signal the thread waiting for the lock.
 *              release interrupt occurs.  If there's a thread waiting for
 *              the global lock, signal it.
 *
 * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
 * this is not possible for some reason, a separate thread will have to be
 * scheduled to do this.
 *
 ******************************************************************************/
static u8 acpi_ev_global_lock_pending;
static spinlock_t _acpi_ev_global_lock_pending_lock;
#define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock

static u32 acpi_ev_global_lock_handler(void *context)
{
	u8 acquired = FALSE;
	acpi_status status;
	acpi_cpu_flags flags;

	/*
	 * Attempt to get the lock.
	 *
	 * If we don't get it now, it will be marked pending and we will
	 * take another interrupt when it becomes free.
	 */
	ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
	if (acquired) {
	flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);

		/* Got the lock, now wake all threads waiting for it */
	if (!acpi_ev_global_lock_pending) {
		goto out;
	}

		acpi_gbl_global_lock_acquired = TRUE;
	/* Send a unit to the semaphore */

		if (ACPI_FAILURE
		    (acpi_os_signal_semaphore
		     (acpi_gbl_global_lock_semaphore, 1))) {
			ACPI_ERROR((AE_INFO,
				    "Could not signal Global Lock semaphore"));
		}
	status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
	if (ACPI_FAILURE(status)) {
		ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
	}

	acpi_ev_global_lock_pending = FALSE;

 out:
	acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);

	return (ACPI_INTERRUPT_HANDLED);
}

@@ -415,6 +415,7 @@ static int acpi_ev_global_lock_acquired;

acpi_status acpi_ev_acquire_global_lock(u16 timeout)
{
	acpi_cpu_flags flags;
	acpi_status status = AE_OK;
	u8 acquired = FALSE;

@@ -467,33 +468,48 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
		return_ACPI_STATUS(AE_OK);
	}

	flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);

	do {

		/* Attempt to acquire the actual hardware lock */

		ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
		if (acquired) {

		/* We got the lock */
			acpi_gbl_global_lock_acquired = TRUE;

			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
					  "Acquired hardware Global Lock\n"));

		acpi_gbl_global_lock_acquired = TRUE;
		return_ACPI_STATUS(AE_OK);
			break;
		}

		acpi_ev_global_lock_pending = TRUE;

		acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);

		/*
	 * Did not get the lock. The pending bit was set above, and we must now
	 * wait until we get the global lock released interrupt.
		 * Did not get the lock. The pending bit was set above, and we
		 * must wait until we get the global lock released interrupt.
		 */
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
				  "Waiting for hardware Global Lock\n"));

		/*
		 * Wait for handshake with the global lock interrupt handler.
		 * This interface releases the interpreter if we must wait.
		 */
	status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
		status = acpi_ex_system_wait_semaphore(
						acpi_gbl_global_lock_semaphore,
						ACPI_WAIT_FOREVER);

		flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);

	} while (ACPI_SUCCESS(status));

	acpi_ev_global_lock_pending = FALSE;

	acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);

	return_ACPI_STATUS(status);
}

+7 −2
Original line number Diff line number Diff line
@@ -279,6 +279,9 @@ static int acpi_lid_send_state(struct acpi_device *device)
	input_report_switch(button->input, SW_LID, !state);
	input_sync(button->input);

	if (state)
		pm_wakeup_event(&device->dev, 0);

	ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
	if (ret == NOTIFY_DONE)
		ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
@@ -314,6 +317,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
			input_sync(input);
			input_report_key(input, keycode, 0);
			input_sync(input);

			pm_wakeup_event(&device->dev, 0);
		}

		acpi_bus_generate_proc_event(device, event, ++button->pushed);
@@ -426,7 +431,7 @@ static int acpi_button_add(struct acpi_device *device)
		acpi_enable_gpe(device->wakeup.gpe_device,
				device->wakeup.gpe_number);
		device->wakeup.run_wake_count++;
		device->wakeup.state.enabled = 1;
		device_set_wakeup_enable(&device->dev, true);
	}

	printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
@@ -449,7 +454,7 @@ static int acpi_button_remove(struct acpi_device *device, int type)
		acpi_disable_gpe(device->wakeup.gpe_device,
				device->wakeup.gpe_number);
		device->wakeup.run_wake_count--;
		device->wakeup.state.enabled = 0;
		device_set_wakeup_enable(&device->dev, false);
	}

	acpi_button_remove_fs(device);
+1 −4
Original line number Diff line number Diff line
@@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
				"firmware_node");
		ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
				"physical_node");
		if (acpi_dev->wakeup.flags.valid) {
		if (acpi_dev->wakeup.flags.valid)
			device_set_wakeup_capable(dev, true);
			device_set_wakeup_enable(dev,
						acpi_dev->wakeup.state.enabled);
		}
	}

	return 0;
+12 −29
Original line number Diff line number Diff line
@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
			   dev->pnp.bus_id,
			   (u32) dev->wakeup.sleep_state,
			   dev->wakeup.flags.run_wake ? '*' : ' ',
			   dev->wakeup.state.enabled ? "enabled" : "disabled");
			   (device_may_wakeup(&dev->dev)
			     || (ldev && device_may_wakeup(ldev))) ?
			       "enabled" : "disabled");
		if (ldev)
			seq_printf(seq, "%s:%s",
				   ldev->bus ? ldev->bus->name : "no-bus",
@@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev)
{
	struct device *dev = acpi_get_physical_device(adev->handle);

	if (dev && device_can_wakeup(dev))
		device_set_wakeup_enable(dev, adev->wakeup.state.enabled);
	if (dev && device_can_wakeup(dev)) {
		bool enable = !device_may_wakeup(dev);
		device_set_wakeup_enable(dev, enable);
	}
}

static ssize_t
@@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file,
	char strbuf[5];
	char str[5] = "";
	unsigned int len = count;
	struct acpi_device *found_dev = NULL;

	if (len > 4)
		len = 4;
@@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file,
			continue;

		if (!strncmp(dev->pnp.bus_id, str, 4)) {
			dev->wakeup.state.enabled =
			    dev->wakeup.state.enabled ? 0 : 1;
			found_dev = dev;
			break;
		}
	}
	if (found_dev) {
		physical_device_enable_wakeup(found_dev);
		list_for_each_safe(node, next, &acpi_wakeup_device_list) {
			struct acpi_device *dev = container_of(node,
							       struct
							       acpi_device,
							       wakeup_list);

			if ((dev != found_dev) &&
			    (dev->wakeup.gpe_number ==
			     found_dev->wakeup.gpe_number)
			    && (dev->wakeup.gpe_device ==
				found_dev->wakeup.gpe_device)) {
				printk(KERN_WARNING
				       "ACPI: '%s' and '%s' have the same GPE, "
				       "can't disable/enable one separately\n",
				       dev->pnp.bus_id, found_dev->pnp.bus_id);
				dev->wakeup.state.enabled =
				    found_dev->wakeup.state.enabled;
			if (device_can_wakeup(&dev->dev)) {
				bool enable = !device_may_wakeup(&dev->dev);
				device_set_wakeup_enable(&dev->dev, enable);
			} else {
				physical_device_enable_wakeup(dev);
			}
			break;
		}
	}
	mutex_unlock(&acpi_device_lock);
+1 −1
Original line number Diff line number Diff line
@@ -803,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
	/* Power button, Lid switch always enable wakeup */
	if (!acpi_match_device_ids(device, button_device_ids)) {
		device->wakeup.flags.run_wake = 1;
		device->wakeup.flags.always_enabled = 1;
		device_set_wakeup_capable(&device->dev, true);
		return;
	}

Loading