All of lore.kernel.org
 help / color / mirror / Atom feed
* ACPI patches for 2.6.23-rc1
@ 2007-07-25  5:51 Len Brown
  2007-07-25  5:51   ` Len Brown
  2007-07-25  9:49 ` ACPI patches for 2.6.23-rc1 Richard Hughes
  0 siblings, 2 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi

I wish this batch did not miss the -rc1 deadline.
Some of them must go into -rc2, bug some of them are
probably bigger than should really go in post -rc1 --
lets see how good a mood Linus is in tomorrow:-)

As usual, please squawk if you see any problems.

thanks,
-Len

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 01/16] ACPI: Implement the set_target() callback from pm_ops
@ 2007-07-25  5:51   ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Rafael J. Wysocki, Len Brown

From: Rafael J. Wysocki <rjw@sisk.pl>

In the future some drivers may need to use ACPI to determine the low power
states in which to place their devices, but to provide the drivers with this
information the ACPI core needs to know what sleep state the system is going to
enter.  Namely, the device's state should not be too high power for given system
sleep state and, if the device is supposed to be able to wake up the system, its
state should not be too low power for the wake up to be possible).  For this
purpose, the ACPI core needs to implement the set_target() method in 'struct
pm_ops' and store the target system sleep state passed by the PM core in a
variable.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Acked-by: David Brownell <david-b@pacbell.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/sleep/main.c |   84 ++++++++++++++++++++++++++++-----------------
 1 files changed, 52 insertions(+), 32 deletions(-)

diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 42127c0..19f8557 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -34,34 +34,54 @@ static u32 acpi_suspend_states[] = {
 
 static int init_8259A_after_S1;
 
+extern int acpi_sleep_prepare(u32 acpi_state);
+extern void acpi_power_off(void);
+
+static u32 acpi_target_sleep_state = ACPI_STATE_S0;
+
+/**
+ *	acpi_pm_set_target - Set the target system sleep state to the state
+ *		associated with given @pm_state, if supported.
+ */
+
+static int acpi_pm_set_target(suspend_state_t pm_state)
+{
+	u32 acpi_state = acpi_suspend_states[pm_state];
+	int error = 0;
+
+	if (sleep_states[acpi_state]) {
+		acpi_target_sleep_state = acpi_state;
+	} else {
+		printk(KERN_ERR "ACPI does not support this state: %d\n",
+			pm_state);
+		error = -ENOSYS;
+	}
+	return error;
+}
+
 /**
  *	acpi_pm_prepare - Do preliminary suspend work.
- *	@pm_state:		suspend state we're entering.
+ *	@pm_state: ignored
  *
- *	Make sure we support the state. If we do, and we need it, set the
- *	firmware waking vector and do arch-specific nastiness to get the 
- *	wakeup code to the waking vector. 
+ *	If necessary, set the firmware waking vector and do arch-specific
+ *	nastiness to get the wakeup code to the waking vector.
  */
 
-extern int acpi_sleep_prepare(u32 acpi_state);
-extern void acpi_power_off(void);
-
 static int acpi_pm_prepare(suspend_state_t pm_state)
 {
-	u32 acpi_state = acpi_suspend_states[pm_state];
+	int error = acpi_sleep_prepare(acpi_target_sleep_state);
 
-	if (!sleep_states[acpi_state]) {
-		printk("acpi_pm_prepare does not support %d \n", pm_state);
-		return -EPERM;
-	}
-	return acpi_sleep_prepare(acpi_state);
+	if (error)
+		acpi_target_sleep_state = ACPI_STATE_S0;
+
+	return error;
 }
 
 /**
  *	acpi_pm_enter - Actually enter a sleep state.
- *	@pm_state:		State we're entering.
+ *	@pm_state: ignored
  *
- *	Flush caches and go to sleep. For STR or STD, we have to call 
+ *	Flush caches and go to sleep. For STR or S2, we have to call
  *	arch-specific assembly, which in turn call acpi_enter_sleep_state().
  *	It's unfortunate, but it works. Please fix if you're feeling frisky.
  */
@@ -70,31 +90,32 @@ static int acpi_pm_enter(suspend_state_t pm_state)
 {
 	acpi_status status = AE_OK;
 	unsigned long flags = 0;
-	u32 acpi_state = acpi_suspend_states[pm_state];
+	u32 acpi_state = acpi_target_sleep_state;
 
 	ACPI_FLUSH_CPU_CACHE();
 
 	/* Do arch specific saving of state. */
-	if (pm_state > PM_SUSPEND_STANDBY) {
+	if (acpi_state == ACPI_STATE_S2 || acpi_state == ACPI_STATE_S3) {
 		int error = acpi_save_state_mem();
-		if (error)
+
+		if (error) {
+			acpi_target_sleep_state = ACPI_STATE_S0;
 			return error;
+		}
 	}
 
 	local_irq_save(flags);
 	acpi_enable_wakeup_device(acpi_state);
-	switch (pm_state) {
-	case PM_SUSPEND_STANDBY:
+	switch (acpi_state) {
+	case ACPI_STATE_S1:
 		barrier();
 		status = acpi_enter_sleep_state(acpi_state);
 		break;
 
-	case PM_SUSPEND_MEM:
+	case ACPI_STATE_S2:
+	case ACPI_STATE_S3:
 		do_suspend_lowlevel();
 		break;
-
-	default:
-		return -EINVAL;
 	}
 
 	/* ACPI 3.0 specs (P62) says that it's the responsabilty
@@ -107,12 +128,8 @@ static int acpi_pm_enter(suspend_state_t pm_state)
 	local_irq_restore(flags);
 	printk(KERN_DEBUG "Back to C!\n");
 
-	/* restore processor state
-	 * We should only be here if we're coming back from STR or STD.
-	 * And, in the case of the latter, the memory image should have already
-	 * been loaded from disk.
-	 */
-	if (pm_state > PM_SUSPEND_STANDBY)
+	/* restore processor state */
+	if (acpi_state == ACPI_STATE_S2 || acpi_state == ACPI_STATE_S3)
 		acpi_restore_state_mem();
 
 	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
@@ -120,7 +137,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
 
 /**
  *	acpi_pm_finish - Finish up suspend sequence.
- *	@pm_state:		State we're coming out of.
+ *	@pm_state: ignored
  *
  *	This is called after we wake back up (or if entering the sleep state
  *	failed). 
@@ -128,7 +145,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
 
 static int acpi_pm_finish(suspend_state_t pm_state)
 {
-	u32 acpi_state = acpi_suspend_states[pm_state];
+	u32 acpi_state = acpi_target_sleep_state;
 
 	acpi_leave_sleep_state(acpi_state);
 	acpi_disable_wakeup_device(acpi_state);
@@ -136,6 +153,8 @@ static int acpi_pm_finish(suspend_state_t pm_state)
 	/* reset firmware waking vector */
 	acpi_set_firmware_waking_vector((acpi_physical_address) 0);
 
+	acpi_target_sleep_state = ACPI_STATE_S0;
+
 	if (init_8259A_after_S1) {
 		printk("Broken toshiba laptop -> kicking interrupts\n");
 		init_8259A(0);
@@ -176,6 +195,7 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
 
 static struct pm_ops acpi_pm_ops = {
 	.valid = acpi_pm_state_valid,
+	.set_target = acpi_pm_set_target,
 	.prepare = acpi_pm_prepare,
 	.enter = acpi_pm_enter,
 	.finish = acpi_pm_finish,
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 02/16] ACPI: Add acpi_pm_device_sleep_state helper routine
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Shaohua Li, Rafael J. Wysocki, Len Brown

From: Shaohua Li <shaohua.li@intel.com>

Based on the David Brownell's patch at
http://marc.info/?l=linux-acpi&m=117873972806360&w=2
updated by: Rafael J. Wysocki <rjw@sisk.pl>

Add a helper routine returning the lowest power (highest number) ACPI device
power state that given device can be in while the system is in the sleep state
indicated by acpi_target_sleep_state .

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/sleep/main.c |   75 +++++++++++++++++++++++++++++++++++++++++++++
 include/acpi/acpi_bus.h   |    2 +
 2 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 19f8557..55eca6e 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -260,6 +260,81 @@ static struct hibernation_ops acpi_hibernation_ops = {
 };
 #endif				/* CONFIG_SOFTWARE_SUSPEND */
 
+/**
+ *	acpi_pm_device_sleep_state - return preferred power state of ACPI device
+ *		in the system sleep state given by %acpi_target_sleep_state
+ *	@dev: device to examine
+ *	@wake: if set, the device should be able to wake up the system
+ *	@d_min_p: used to store the upper limit of allowed states range
+ *	Return value: preferred power state of the device on success, -ENODEV on
+ *		failure (ie. if there's no 'struct acpi_device' for @dev)
+ *
+ *	Find the lowest power (highest number) ACPI device power state that
+ *	device @dev can be in while the system is in the sleep state represented
+ *	by %acpi_target_sleep_state.  If @wake is nonzero, the device should be
+ *	able to wake up the system from this sleep state.  If @d_min_p is set,
+ *	the highest power (lowest number) device power state of @dev allowed
+ *	in this system sleep state is stored at the location pointed to by it.
+ *
+ *	The caller must ensure that @dev is valid before using this function.
+ *	The caller is also responsible for figuring out if the device is
+ *	supposed to be able to wake up the system and passing this information
+ *	via @wake.
+ */
+
+int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
+{
+	acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
+	struct acpi_device *adev;
+	char acpi_method[] = "_SxD";
+	unsigned long d_min, d_max;
+
+	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
+		printk(KERN_ERR "ACPI handle has no context!\n");
+		return -ENODEV;
+	}
+
+	acpi_method[2] = '0' + acpi_target_sleep_state;
+	/*
+	 * If the sleep state is S0, we will return D3, but if the device has
+	 * _S0W, we will use the value from _S0W
+	 */
+	d_min = ACPI_STATE_D0;
+	d_max = ACPI_STATE_D3;
+
+	/*
+	 * If present, _SxD methods return the minimum D-state (highest power
+	 * state) we can use for the corresponding S-states.  Otherwise, the
+	 * minimum D-state is D0 (ACPI 3.x).
+	 *
+	 * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer
+	 * provided -- that's our fault recovery, we ignore retval.
+	 */
+	if (acpi_target_sleep_state > ACPI_STATE_S0)
+		acpi_evaluate_integer(handle, acpi_method, NULL, &d_min);
+
+	/*
+	 * If _PRW says we can wake up the system from the target sleep state,
+	 * the D-state returned by _SxD is sufficient for that (we assume a
+	 * wakeup-aware driver if wake is set).  Still, if _SxW exists
+	 * (ACPI 3.x), it should return the maximum (lowest power) D-state that
+	 * can wake the system.  _S0W may be valid, too.
+	 */
+	if (acpi_target_sleep_state == ACPI_STATE_S0 ||
+	    (wake && adev->wakeup.state.enabled &&
+	     adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
+		acpi_method[3] = 'W';
+		acpi_evaluate_integer(handle, acpi_method, NULL, &d_max);
+		/* Sanity check */
+		if (d_max < d_min)
+			d_min = d_max;
+	}
+
+	if (d_min_p)
+		*d_min_p = d_min;
+	return d_max;
+}
+
 /*
  * Toshiba fails to preserve interrupts over S1, reinitialization
  * of 8259 is needed after S1 resume.
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c6fa5e0..529d035 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -364,6 +364,8 @@ acpi_handle acpi_get_child(acpi_handle, acpi_integer);
 acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
 #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
 
+int acpi_pm_device_sleep_state(struct device *, int, int *);
+
 #endif				/* CONFIG_ACPI */
 
 #endif /*__ACPI_BUS_H__*/
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 03/16] ACPI, PNP: hook ACPI D-state to PNP suspend/resume
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Shaohua Li, Len Brown

From: Shaohua Li <shaohua.li@intel.com>

applied after Rafel's 'PM: Update global suspend and hibernation operations framework' patch set

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/pnp/driver.c       |    5 +++++
 drivers/pnp/pnpacpi/core.c |   14 ++++++++++++++
 include/linux/pnp.h        |    4 ++++
 3 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index e161423..1432806 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -167,6 +167,8 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state)
 	    		return error;
 	}
 
+	if (pnp_dev->protocol && pnp_dev->protocol->suspend)
+		pnp_dev->protocol->suspend(pnp_dev, state);
 	return 0;
 }
 
@@ -179,6 +181,9 @@ static int pnp_bus_resume(struct device *dev)
 	if (!pnp_drv)
 		return 0;
 
+	if (pnp_dev->protocol && pnp_dev->protocol->resume)
+		pnp_dev->protocol->resume(pnp_dev);
+
 	if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) {
 		error = pnp_start_dev(pnp_dev);
 		if (error)
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index a005487..c37a558 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -119,11 +119,25 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
 	return ACPI_FAILURE(status) ? -ENODEV : 0;
 }
 
+static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
+{
+	return acpi_bus_set_power((acpi_handle)dev->data,
+		acpi_pm_device_sleep_state(&dev->dev,
+		device_may_wakeup(&dev->dev), NULL));
+}
+
+static int pnpacpi_resume(struct pnp_dev *dev)
+{
+	return acpi_bus_set_power((acpi_handle)dev->data, ACPI_STATE_D0);
+}
+
 static struct pnp_protocol pnpacpi_protocol = {
 	.name	= "Plug and Play ACPI",
 	.get	= pnpacpi_get_resources,
 	.set	= pnpacpi_set_resources,
 	.disable = pnpacpi_disable_resources,
+	.suspend = pnpacpi_suspend,
+	.resume = pnpacpi_resume,
 };
 
 static int __init pnpacpi_add_device(struct acpi_device *device)
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 2a1897e..66edb22 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -335,6 +335,10 @@ struct pnp_protocol {
 	int (*set)(struct pnp_dev *dev, struct pnp_resource_table *res);
 	int (*disable)(struct pnp_dev *dev);
 
+	/* protocol specific suspend/resume */
+	int (*suspend)(struct pnp_dev *dev, pm_message_t state);
+	int (*resume)(struct pnp_dev *dev);
+
 	/* used by pnp layer only (look but don't touch) */
 	unsigned char		number;		/* protocol number*/
 	struct device		dev;		/* link to driver model */
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 04/16] ACPI: Use ACPI methods to select PCI device suspend state
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Shaohua Li, Len Brown

From: Shaohua Li <shaohua.li@intel.com>

applied after Rafel's 'PM: Update global suspend and hibernation
operations framework' patch set

Signed-off-by: Shaohua Li<shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/pci/pci-acpi.c |   24 ++++++++++++++++++++----
 drivers/pci/pci.c      |    8 ++++----
 drivers/pci/pci.h      |    2 +-
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index c806249..5e866b9 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -245,11 +245,27 @@ EXPORT_SYMBOL(pci_osc_control_set);
  * currently we simply return _SxD, if present.
  */
 
-static int acpi_pci_choose_state(struct pci_dev *pdev, pm_message_t state)
+static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev,
+	pm_message_t state)
 {
-	/* TBD */
-
-	return -ENODEV;
+	int acpi_state;
+
+	acpi_state = acpi_pm_device_sleep_state(&pdev->dev,
+		device_may_wakeup(&pdev->dev), NULL);
+	if (acpi_state < 0)
+		return PCI_POWER_ERROR;
+
+	switch (acpi_state) {
+	case ACPI_STATE_D0:
+		return PCI_D0;
+	case ACPI_STATE_D1:
+		return PCI_D1;
+	case ACPI_STATE_D2:
+		return PCI_D2;
+	case ACPI_STATE_D3:
+		return PCI_D3hot;
+	}
+	return PCI_POWER_ERROR;
 }
 
 static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 03fd59e..1458fd6 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -499,7 +499,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 	return 0;
 }
 
-int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
+pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
  
 /**
  * pci_choose_state - Choose the power state of a PCI device
@@ -513,15 +513,15 @@ int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
 
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
 {
-	int ret;
+	pci_power_t ret;
 
 	if (!pci_find_capability(dev, PCI_CAP_ID_PM))
 		return PCI_D0;
 
 	if (platform_pci_choose_state) {
 		ret = platform_pci_choose_state(dev, state);
-		if (ret >= 0)
-			state.event = ret;
+		if (ret != PCI_POWER_ERROR)
+			return ret;
 	}
 
 	switch (state.event) {
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 3fec13d..c293ba1 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -13,7 +13,7 @@ extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
 					      resource_size_t, resource_size_t),
 				  void *alignf_data);
 /* Firmware callbacks */
-extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
+extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
 extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state);
 
 extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 05/16] ACPI: ignore _PSx method for hotplugable PCI devices
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Shaohua Li, Len Brown

From: Shaohua Li <shaohua.li@intel.com>

If the ACPI device has _EJ0, ignore the device.
_PSx will set power for the slot,
and the hotplug driver will take care of _PSx.

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/pci/pci-acpi.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 5e866b9..67c63d1 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -271,6 +271,7 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev,
 static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
 	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
+	acpi_handle tmp;
 	static int state_conv[] = {
 		[0] = 0,
 		[1] = 1,
@@ -282,6 +283,9 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 
 	if (!handle)
 		return -ENODEV;
+	/* If the ACPI device has _EJ0, ignore the device */
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp)))
+		return 0;
 	return acpi_bus_set_power(handle, acpi_state);
 }
 
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 06/16] ACPI: fix oops due to typo in new throttling code
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Luming Yu, Andrew Morton, Len Brown

From: Luming Yu <luming.yu@gmail.com>

Signed-off-by: Luming Yu <luming.yu@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/processor_throttling.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 3f55d1f..dc5b859 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -658,18 +658,20 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq,
 		   pr->throttling.state_count - 1);
 
 	seq_puts(seq, "states:\n");
-	if (acpi_processor_get_throttling == acpi_processor_get_throttling_fadt)
+	if (pr->throttling.acpi_processor_get_throttling ==
+			acpi_processor_get_throttling_fadt) {
 		for (i = 0; i < pr->throttling.state_count; i++)
 			seq_printf(seq, "   %cT%d:                  %02d%%\n",
 				   (i == pr->throttling.state ? '*' : ' '), i,
 				   (pr->throttling.states[i].performance ? pr->
 				    throttling.states[i].performance / 10 : 0));
-	else
+	} else {
 		for (i = 0; i < pr->throttling.state_count; i++)
 			seq_printf(seq, "   %cT%d:                  %02d%%\n",
 				   (i == pr->throttling.state ? '*' : ' '), i,
 				   (int)pr->throttling.states_tss[i].
 				   freqpercentage);
+	}
 
       end:
 	return 0;
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 07/16] ACPI: asus-laptop: Fix failure exits
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Al Viro, Al Viro, Len Brown

From: Al Viro <viro@ftp.linux.org.uk>

> Subject         : drivers/misc/asus-laptop.c:*: error: 'struct led_classdev' has no member named 'class_dev'
> References      : http://lkml.org/lkml/2007/7/22/299
> Submitter       : Gabriel C <nix.or.die@googlemail.com>

Fallout from f8a7c6fe14f556ca8eeddce258cb21392d0c3a2f.  However, looking
at it shows that checks done in ASUS_LED_UNREGISTER() can't trigger
at all (we never get to asus_led_exit() if registration fails) and
if that registration fails, we actually leak stuff.  IOW, it's worse
than just replacing class_dev with dev in there - the tests themselves
had been papering over the lousy cleanup logics.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/asus-laptop.c |   32 +++++++++++++++++++++-----------
 1 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index f753060..6b89854 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -1067,19 +1067,16 @@ static void asus_backlight_exit(void)
 }
 
 #define  ASUS_LED_UNREGISTER(object)				\
-	if(object##_led.class_dev				\
-	   && !IS_ERR(object##_led.class_dev))			\
-		led_classdev_unregister(&object##_led)
+	led_classdev_unregister(&object##_led)
 
 static void asus_led_exit(void)
 {
+	destroy_workqueue(led_workqueue);
 	ASUS_LED_UNREGISTER(mled);
 	ASUS_LED_UNREGISTER(tled);
 	ASUS_LED_UNREGISTER(pled);
 	ASUS_LED_UNREGISTER(rled);
 	ASUS_LED_UNREGISTER(gled);
-
-	destroy_workqueue(led_workqueue);
 }
 
 static void __exit asus_laptop_exit(void)
@@ -1135,29 +1132,42 @@ static int asus_led_init(struct device *dev)
 
 	rv = ASUS_LED_REGISTER(mled, dev);
 	if (rv)
-		return rv;
+		goto out;
 
 	rv = ASUS_LED_REGISTER(tled, dev);
 	if (rv)
-		return rv;
+		goto out1;
 
 	rv = ASUS_LED_REGISTER(rled, dev);
 	if (rv)
-		return rv;
+		goto out2;
 
 	rv = ASUS_LED_REGISTER(pled, dev);
 	if (rv)
-		return rv;
+		goto out3;
 
 	rv = ASUS_LED_REGISTER(gled, dev);
 	if (rv)
-		return rv;
+		goto out4;
 
 	led_workqueue = create_singlethread_workqueue("led_workqueue");
 	if (!led_workqueue)
-		return -ENOMEM;
+		goto out5;
 
 	return 0;
+out5:
+	rv = -ENOMEM;
+	ASUS_LED_UNREGISTER(gled);
+out4:
+	ASUS_LED_UNREGISTER(pled);
+out3:
+	ASUS_LED_UNREGISTER(rled);
+out2:
+	ASUS_LED_UNREGISTER(tled);
+out1:
+	ASUS_LED_UNREGISTER(mled);
+out:
+	return rv;
 }
 
 static int __init asus_laptop_init(void)
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 08/16] ACPI: autoload modules - ACPICA modifications
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Thomas Renninger, Len Brown

From: Thomas Renninger <trenn@suse.de>

Define standardized HIDs - Rename current acpi_device_id to acpica_device_id

Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/events/evrgnini.c    |    2 +-
 drivers/acpi/namespace/nsxfeval.c |    2 +-
 drivers/acpi/utilities/uteval.c   |    4 ++--
 include/acpi/acpi_bus.h           |    5 +++--
 include/acpi/acpi_drivers.h       |   21 +++++++++++++--------
 include/acpi/actypes.h            |    6 +++---
 include/acpi/acutils.h            |    4 ++--
 7 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 23ee7bc..b1aaa0e 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -378,7 +378,7 @@ static u8 acpi_ev_match_pci_root_bridge(char *id)
 static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
 {
 	acpi_status status;
-	struct acpi_device_id hid;
+	struct acpica_device_id hid;
 	struct acpi_compatible_id_list *cid;
 	acpi_native_uint i;
 
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index be4f289..ab65b2c 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -440,7 +440,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
 	acpi_status status;
 	struct acpi_namespace_node *node;
 	u32 flags;
-	struct acpi_device_id hid;
+	struct acpica_device_id hid;
 	struct acpi_compatible_id_list *cid;
 	acpi_native_uint i;
 
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index f112af4..0042b7e 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -407,7 +407,7 @@ acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
 
 acpi_status
 acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
-		    struct acpi_device_id *hid)
+		    struct acpica_device_id *hid)
 {
 	union acpi_operand_object *obj_desc;
 	acpi_status status;
@@ -609,7 +609,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
 
 acpi_status
 acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
-		    struct acpi_device_id *uid)
+		    struct acpica_device_id *uid)
 {
 	union acpi_operand_object *obj_desc;
 	acpi_status status;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 5e3dcf3..3f2a22b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -131,7 +131,7 @@ struct acpi_device_ops {
 struct acpi_driver {
 	char name[80];
 	char class[80];
-	char *ids;		/* Supported Hardware IDs */
+	const struct acpi_device_id *ids; /* Supported Hardware IDs */
 	struct acpi_device_ops ops;
 	struct device_driver drv;
 	struct module *owner;
@@ -341,7 +341,8 @@ int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
 int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 int acpi_bus_start(struct acpi_device *device);
 acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
-int acpi_match_ids(struct acpi_device *device, char *ids);
+int acpi_match_device_ids(struct acpi_device *device,
+			  const struct acpi_device_id *ids);
 int acpi_create_dir(struct acpi_device *);
 void acpi_remove_dir(struct acpi_device *);
 
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 5535159..c348ff4 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -34,16 +34,21 @@
 #define ACPI_BUS_COMPONENT		0x00010000
 #define ACPI_SYSTEM_COMPONENT		0x02000000
 
-/* _HID definitions */
+/*
+ * _HID definitions
+ * HIDs must conform to ACPI spec(6.1.4)
+ * Linux specific HIDs do not apply to this and begin with LNX:
+ */
 
-#define ACPI_POWER_HID			"power_resource"
+#define ACPI_POWER_HID			"LNXPOWER"
 #define ACPI_PROCESSOR_HID		"ACPI0007"
-#define ACPI_SYSTEM_HID			"acpi_system"
-#define ACPI_THERMAL_HID		"thermal"
-#define ACPI_BUTTON_HID_POWERF		"button_power"
-#define ACPI_BUTTON_HID_SLEEPF		"button_sleep"
-#define ACPI_VIDEO_HID			"video"
-#define ACPI_BAY_HID			"bay"
+#define ACPI_SYSTEM_HID			"LNXSYSTM"
+#define ACPI_THERMAL_HID		"LNXTHERM"
+#define ACPI_BUTTON_HID_POWERF		"LNXPWRBN"
+#define ACPI_BUTTON_HID_SLEEPF		"LNXSLPBN"
+#define ACPI_VIDEO_HID			"LNXVIDEO"
+#define ACPI_BAY_HID			"LNXIOBAY"
+
 /* --------------------------------------------------------------------------
                                        PCI
    -------------------------------------------------------------------------- */
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index fe8abc2..e73a389 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -809,7 +809,7 @@ acpi_status(*acpi_walk_callback) (acpi_handle obj_handle,
 
 /* Common string version of device HIDs and UIDs */
 
-struct acpi_device_id {
+struct acpica_device_id {
 	char value[ACPI_DEVICE_ID_LENGTH];
 };
 
@@ -859,8 +859,8 @@ struct acpi_device_info {
 	u32 valid;		/* Indicates which fields below are valid */
 	u32 current_status;	/* _STA value */
 	acpi_integer address;	/* _ADR value if any */
-	struct acpi_device_id hardware_id;	/* _HID value if any */
-	struct acpi_device_id unique_id;	/* _UID value if any */
+	struct acpica_device_id hardware_id;	/* _HID value if any */
+	struct acpica_device_id unique_id;	/* _UID value if any */
 	u8 highest_dstates[4];	/* _sx_d values: 0xFF indicates not valid */
 	struct acpi_compatible_id_list compatibility_id;	/* List of _CIDs if any */
 };
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h
index a87ef1c..a291854 100644
--- a/include/acpi/acutils.h
+++ b/include/acpi/acutils.h
@@ -354,7 +354,7 @@ acpi_ut_evaluate_numeric_object(char *object_name,
 
 acpi_status
 acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
-		    struct acpi_device_id *hid);
+		    struct acpica_device_id *hid);
 
 acpi_status
 acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
@@ -366,7 +366,7 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node,
 
 acpi_status
 acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
-		    struct acpi_device_id *uid);
+		    struct acpica_device_id *uid);
 
 acpi_status
 acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 09/16] ACPI: autoload modules - Create ACPI alias interface
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Thomas Renninger, Kay Sievers, Len Brown

From: Thomas Renninger <trenn@suse.de>

Modify modpost (file2alias.c) to add acpi*:XYZ0001: alias in modules.alias
like:
grep acpi /lib/modules/2.6.22-rc4-default/modules.alias
alias acpi*:SNY5001:* sony_laptop
alias acpi*:SNY6001:* sony_laptop
for e.g. the sony_laptop module.
This module matches against all ACPI devices with a HID or CID of SNY5001
or SNY6001

Export an uevent and modalias sysfs file containing the string:
[MODALIAS=]acpi:PNP0C0C:
additional CIDs are concatenated at the end.

Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/scan.c             |  156 +++++++++++++++++++++++++++-----------
 drivers/pnp/pnpacpi/core.c      |   19 +++--
 include/linux/acpi.h            |    1 +
 include/linux/mod_devicetable.h |    6 ++
 scripts/mod/file2alias.c        |   12 +++
 5 files changed, 142 insertions(+), 52 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 6b3b8a5..be74347 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -16,7 +16,7 @@ ACPI_MODULE_NAME("scan");
 extern struct acpi_device *acpi_root;
 
 #define ACPI_BUS_CLASS			"system_bus"
-#define ACPI_BUS_HID			"ACPI_BUS"
+#define ACPI_BUS_HID			"LNXSYBUS"
 #define ACPI_BUS_DEVICE_NAME		"System Bus"
 
 static LIST_HEAD(acpi_device_list);
@@ -29,6 +29,62 @@ struct acpi_device_bus_id{
 	unsigned int instance_no;
 	struct list_head node;
 };
+
+/*
+ * Creates hid/cid(s) string needed for modalias and uevent
+ * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
+ * char *modalias: "acpi:IBM0001:ACPI0001"
+*/
+int create_modalias(struct acpi_device *acpi_dev, char *modalias, int size){
+
+	int len;
+
+	if (!acpi_dev->flags.hardware_id)
+		return -ENODEV;
+
+	len = snprintf(modalias, size, "acpi:%s:",
+		       acpi_dev->pnp.hardware_id);
+	if (len < 0 || len >= size)
+		return -EINVAL;
+	size -= len;
+
+	if (acpi_dev->flags.compatible_ids) {
+		struct acpi_compatible_id_list *cid_list;
+		int i;
+		int count;
+
+		cid_list = acpi_dev->pnp.cid_list;
+		for (i = 0; i < cid_list->count; i++) {
+			count = snprintf(&modalias[len], size, "%s:",
+					 cid_list->id[i].value);
+			if (count < 0 || count >= size) {
+				printk(KERN_ERR "acpi: %s cid[%i] exceeds event buffer size",
+				       acpi_dev->pnp.device_name, i);
+				break;
+			}
+			len += count;
+			size -= count;
+		}
+	}
+
+	modalias[len] = '\0';
+	return len;
+}
+
+static ssize_t
+acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) {
+	struct acpi_device *acpi_dev = to_acpi_device(dev);
+	int len;
+
+	/* Device has no HID and no CID or string is >1024 */
+	len = create_modalias(acpi_dev, buf, 1024);
+	if (len <= 0)
+		return 0;
+	buf[len++] = '\n';
+	return len;
+}
+static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
+
 static int acpi_eject_operation(acpi_handle handle, int lockable)
 {
 	struct acpi_object_list arg_list;
@@ -154,6 +210,12 @@ static int acpi_device_setup_files(struct acpi_device *dev)
 			goto end;
 	}
 
+	if (dev->flags.hardware_id || dev->flags.compatible_ids){
+		result = device_create_file(&dev->dev, &dev_attr_modalias);
+		if(result)
+			goto end;
+	}
+
         /*
          * If device has _EJ0, 'eject' file is created that is used to trigger
          * hot-removal function from userland.
@@ -178,6 +240,9 @@ static void acpi_device_remove_files(struct acpi_device *dev)
 	if (ACPI_SUCCESS(status))
 		device_remove_file(&dev->dev, &dev_attr_eject);
 
+	if (dev->flags.hardware_id || dev->flags.compatible_ids)
+		device_remove_file(&dev->dev, &dev_attr_modalias);
+
 	if(dev->flags.hardware_id)
 		device_remove_file(&dev->dev, &dev_attr_hid);
 	if(dev->handle)
@@ -186,6 +251,37 @@ static void acpi_device_remove_files(struct acpi_device *dev)
 /* --------------------------------------------------------------------------
 			ACPI Bus operations
    -------------------------------------------------------------------------- */
+
+int acpi_match_device_ids(struct acpi_device *device,
+			  const struct acpi_device_id *ids)
+{
+	const struct acpi_device_id *id;
+
+	if (device->flags.hardware_id) {
+		for (id = ids; id->id[0]; id++) {
+			if (!strcmp((char*)id->id, device->pnp.hardware_id))
+				return 0;
+		}
+	}
+
+	if (device->flags.compatible_ids) {
+		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
+		int i;
+
+		for (id = ids; id->id[0]; id++) {
+			/* compare multiple _CID entries against driver ids */
+			for (i = 0; i < cid_list->count; i++) {
+				if (!strcmp((char*)id->id,
+					    cid_list->id[i].value))
+					return 0;
+			}
+		}
+	}
+
+	return -ENOENT;
+}
+EXPORT_SYMBOL(acpi_match_device_ids);
+
 static void acpi_device_release(struct device *dev)
 {
 	struct acpi_device *acpi_dev = to_acpi_device(dev);
@@ -219,37 +315,19 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
 	struct acpi_device *acpi_dev = to_acpi_device(dev);
 	struct acpi_driver *acpi_drv = to_acpi_driver(drv);
 
-	return !acpi_match_ids(acpi_dev, acpi_drv->ids);
+	return !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
 }
 
 static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
-	char *buffer, int buffer_size)
+			      char *buffer, int buffer_size)
 {
 	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	int i = 0, length = 0, ret = 0;
-
-	if (acpi_dev->flags.hardware_id)
-		ret = add_uevent_var(envp, num_envp, &i,
-			buffer, buffer_size, &length,
-			"HWID=%s", acpi_dev->pnp.hardware_id);
-	if (ret)
-		return -ENOMEM;
-	if (acpi_dev->flags.compatible_ids) {
-		int j;
-		struct acpi_compatible_id_list *cid_list;
 
-		cid_list = acpi_dev->pnp.cid_list;
-
-		for (j = 0; j < cid_list->count; j++) {
-			ret = add_uevent_var(envp, num_envp, &i, buffer,
-				buffer_size, &length, "COMPTID=%s",
-				cid_list->id[j].value);
-			if (ret)
-				return -ENOMEM;
-		}
+	strcpy(buffer, "MODALIAS=");
+	if (create_modalias(acpi_dev, buffer + 9, buffer_size - 9) > 0) {
+		envp[0] = buffer;
+		envp[1] = NULL;
 	}
-
-	envp[i] = NULL;
 	return 0;
 }
 
@@ -543,25 +621,6 @@ void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
 	return;
 }
 
-int acpi_match_ids(struct acpi_device *device, char *ids)
-{
-	if (device->flags.hardware_id)
-		if (strstr(ids, device->pnp.hardware_id))
-			return 0;
-
-	if (device->flags.compatible_ids) {
-		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
-		int i;
-
-		/* compare multiple _CID entries against driver ids */
-		for (i = 0; i < cid_list->count; i++) {
-			if (strstr(ids, cid_list->id[i].value))
-				return 0;
-		}
-	}
-	return -ENOENT;
-}
-
 static int acpi_bus_get_perf_flags(struct acpi_device *device)
 {
 	device->performance.state = ACPI_STATE_UNKNOWN;
@@ -624,6 +683,13 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	union acpi_object *package = NULL;
 
+	struct acpi_device_id button_device_ids[] = {
+		{"PNP0C0D", 0},
+		{"PNP0C0C", 0},
+		{"PNP0C0E", 0},
+		{"", 0},
+	};
+
 
 	/* _PRW */
 	status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
@@ -643,7 +709,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
 
 	device->wakeup.flags.valid = 1;
 	/* Power button, Lid switch always enable wakeup */
-	if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
+	if (!acpi_match_device_ids(device, button_device_ids))
 		device->wakeup.flags.run_wake = 1;
 
       end:
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index a005487..0bc8891 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -21,7 +21,10 @@
 
 #include <linux/acpi.h>
 #include <linux/pnp.h>
+#include <linux/mod_devicetable.h>
 #include <acpi/acpi_bus.h>
+#include <acpi/actypes.h>
+
 #include "pnpacpi.h"
 
 static int num = 0;
@@ -33,15 +36,17 @@ static int num = 0;
  * have irqs (PIC, Timer) because we call acpi_register_gsi.
  * Finaly only devices that have a CRS method need to be in this list.
  */
-static char __initdata excluded_id_list[] =
-	"PNP0C09," /* EC */
-	"PNP0C0F," /* Link device */
-	"PNP0000," /* PIC */
-	"PNP0100," /* Timer */
-	;
+static __initdata struct acpi_device_id excluded_id_list[] ={
+	{"PNP0C09", 0}, /* EC */
+	{"PNP0C0F", 0}, /* Link device */
+	{"PNP0000", 0}, /* PIC */
+	{"PNP0100", 0}, /* Timer */
+	{"", 0},
+};
+
 static inline int is_exclusive_device(struct acpi_device *dev)
 {
-	return (!acpi_match_ids(dev, excluded_id_list));
+	return (!acpi_match_device_ids(dev, excluded_id_list));
 }
 
 /*
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d5680cd..bf5e000 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -33,6 +33,7 @@
 #endif
 
 #include <linux/list.h>
+#include <linux/mod_devicetable.h>
 
 #include <acpi/acpi.h>
 #include <acpi/acpi_bus.h>
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index af04a55..2ada8ee 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -159,6 +159,12 @@ struct ap_device_id {
 
 #define AP_DEVICE_ID_MATCH_DEVICE_TYPE		0x01
 
+#define ACPI_ID_LEN	9
+
+struct acpi_device_id {
+	__u8 id[ACPI_ID_LEN];
+	kernel_ulong_t driver_data;
+};
 
 #define PNP_ID_LEN	8
 #define PNP_MAX_DEVICES	8
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index f646381..8a09021 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -290,6 +290,14 @@ static int do_serio_entry(const char *filename,
 	return 1;
 }
 
+/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
+static int do_acpi_entry(const char *filename,
+			struct acpi_device_id *id, char *alias)
+{
+	sprintf(alias, "acpi*:%s:", id->id);
+	return 1;
+}
+
 /* looks like: "pnp:dD" */
 static int do_pnp_entry(const char *filename,
 			struct pnp_device_id *id, char *alias)
@@ -551,6 +559,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 		do_table(symval, sym->st_size,
 			 sizeof(struct serio_device_id), "serio",
 			 do_serio_entry, mod);
+	else if (sym_is(symname, "__mod_acpi_device_table"))
+		do_table(symval, sym->st_size,
+			 sizeof(struct acpi_device_id), "acpi",
+			 do_acpi_entry, mod);
 	else if (sym_is(symname, "__mod_pnp_device_table"))
 		do_table(symval, sym->st_size,
 			 sizeof(struct pnp_device_id), "pnp",
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 10/16] ACPI: autoload modules - Create __mod_acpi_device_table symbol for all ACPI drivers
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Thomas Renninger, Len Brown

From: Thomas Renninger <trenn@suse.de>

modpost is going to use these to create e.g. acpi:ACPI0001
in modules.alias.

Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ac.c               |    9 +++++++--
 drivers/acpi/acpi_memhotplug.c  |    8 +++++++-
 drivers/acpi/asus_acpi.c        |   11 ++++++++---
 drivers/acpi/battery.c          |    9 +++++++--
 drivers/acpi/button.c           |   12 +++++++++++-
 drivers/acpi/container.c        |   10 +++++++++-
 drivers/acpi/ec.c               |    8 ++++++--
 drivers/acpi/fan.c              |    8 +++++++-
 drivers/acpi/pci_link.c         |    9 +++++++--
 drivers/acpi/pci_root.c         |    9 +++++++--
 drivers/acpi/power.c            |    8 +++++++-
 drivers/acpi/processor_core.c   |    8 +++++++-
 drivers/acpi/sbs.c              |   10 ++++++++--
 drivers/acpi/thermal.c          |    8 +++++++-
 drivers/acpi/video.c            |    8 +++++++-
 drivers/char/hpet.c             |    8 +++++++-
 drivers/input/misc/atlas_btns.c |    9 +++++++--
 drivers/misc/asus-laptop.c      |    9 +++++++--
 drivers/misc/sony-laptop.c      |   21 +++++++++++++++++++--
 drivers/misc/thinkpad_acpi.c    |   20 ++++++++++++++++----
 drivers/misc/thinkpad_acpi.h    |    2 +-
 21 files changed, 169 insertions(+), 35 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 37c7dc4..d8b3509 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -34,7 +34,6 @@
 
 #define ACPI_AC_COMPONENT		0x00020000
 #define ACPI_AC_CLASS			"ac_adapter"
-#define ACPI_AC_HID 			"ACPI0003"
 #define ACPI_AC_DEVICE_NAME		"AC Adapter"
 #define ACPI_AC_FILE_STATE		"state"
 #define ACPI_AC_NOTIFY_STATUS		0x80
@@ -56,10 +55,16 @@ static int acpi_ac_add(struct acpi_device *device);
 static int acpi_ac_remove(struct acpi_device *device, int type);
 static int acpi_ac_open_fs(struct inode *inode, struct file *file);
 
+const static struct acpi_device_id ac_device_ids[] = {
+	{"ACPI0003", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, ac_device_ids);
+
 static struct acpi_driver acpi_ac_driver = {
 	.name = "ac",
 	.class = ACPI_AC_CLASS,
-	.ids = ACPI_AC_HID,
+	.ids = ac_device_ids,
 	.ops = {
 		.add = acpi_ac_add,
 		.remove = acpi_ac_remove,
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index e65628a..5f1127a 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -53,10 +53,16 @@ static int acpi_memory_device_add(struct acpi_device *device);
 static int acpi_memory_device_remove(struct acpi_device *device, int type);
 static int acpi_memory_device_start(struct acpi_device *device);
 
+static const struct acpi_device_id memory_device_ids[] = {
+	{ACPI_MEMORY_DEVICE_HID, 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, memory_device_ids);
+
 static struct acpi_driver acpi_memory_device_driver = {
 	.name = "acpi_memhotplug",
 	.class = ACPI_MEMORY_DEVICE_CLASS,
-	.ids = ACPI_MEMORY_DEVICE_HID,
+	.ids = memory_device_ids,
 	.ops = {
 		.add = acpi_memory_device_add,
 		.remove = acpi_memory_device_remove,
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 3cd79ca..9c4bd22 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -56,7 +56,6 @@
 #define ACPI_HOTK_NAME          "Asus Laptop ACPI Extras Driver"
 #define ACPI_HOTK_CLASS         "hotkey"
 #define ACPI_HOTK_DEVICE_NAME   "Hotkey"
-#define ACPI_HOTK_HID           "ATK0100"
 
 /*
  * Some events we use, same for all Asus
@@ -426,14 +425,20 @@ static struct acpi_table_header *asus_info;
 static struct asus_hotk *hotk;
 
 /*
- * The hotkey driver declaration
+ * The hotkey driver and autoloading declaration
  */
 static int asus_hotk_add(struct acpi_device *device);
 static int asus_hotk_remove(struct acpi_device *device, int type);
+static const struct acpi_device_id asus_device_ids[] = {
+	{"ATK0100", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, asus_device_ids);
+
 static struct acpi_driver asus_hotk_driver = {
 	.name = "asus_acpi",
 	.class = ACPI_HOTK_CLASS,
-	.ids = ACPI_HOTK_HID,
+	.ids = asus_device_ids,
 	.ops = {
 		.add = asus_hotk_add,
 		.remove = asus_hotk_remove,
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index cad932d..8165103 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -41,7 +41,6 @@
 
 #define ACPI_BATTERY_COMPONENT		0x00040000
 #define ACPI_BATTERY_CLASS		"battery"
-#define ACPI_BATTERY_HID		"PNP0C0A"
 #define ACPI_BATTERY_DEVICE_NAME	"Battery"
 #define ACPI_BATTERY_NOTIFY_STATUS	0x80
 #define ACPI_BATTERY_NOTIFY_INFO	0x81
@@ -74,10 +73,16 @@ static int acpi_battery_add(struct acpi_device *device);
 static int acpi_battery_remove(struct acpi_device *device, int type);
 static int acpi_battery_resume(struct acpi_device *device);
 
+static const struct acpi_device_id battery_device_ids[] = {
+	{"PNP0C0A", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, battery_device_ids);
+
 static struct acpi_driver acpi_battery_driver = {
 	.name = "battery",
 	.class = ACPI_BATTERY_CLASS,
-	.ids = ACPI_BATTERY_HID,
+	.ids = battery_device_ids,
 	.ops = {
 		.add = acpi_battery_add,
 		.resume = acpi_battery_resume,
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index cb4110b..5405813 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -66,6 +66,16 @@ MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION("ACPI Button Driver");
 MODULE_LICENSE("GPL");
 
+static const struct acpi_device_id button_device_ids[] = {
+	{ACPI_BUTTON_HID_LID,    0},
+	{ACPI_BUTTON_HID_SLEEP,  0},
+	{ACPI_BUTTON_HID_SLEEPF, 0},
+	{ACPI_BUTTON_HID_POWER,  0},
+	{ACPI_BUTTON_HID_POWERF, 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, button_device_ids);
+
 static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device, int type);
 static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
@@ -74,7 +84,7 @@ static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 static struct acpi_driver acpi_button_driver = {
 	.name = "button",
 	.class = ACPI_BUTTON_CLASS,
-	.ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
+	.ids = button_device_ids,
 	.ops = {
 		.add = acpi_button_add,
 		.remove = acpi_button_remove,
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 0dd3bf7..3c25ec7 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -52,10 +52,18 @@ MODULE_LICENSE("GPL");
 static int acpi_container_add(struct acpi_device *device);
 static int acpi_container_remove(struct acpi_device *device, int type);
 
+static const struct acpi_device_id container_device_ids[] = {
+	{"ACPI0004", 0},
+	{"PNP0A05", 0},
+	{"PNP0A06", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, container_device_ids);
+
 static struct acpi_driver acpi_container_driver = {
 	.name = "container",
 	.class = ACPI_CONTAINER_CLASS,
-	.ids = "ACPI0004,PNP0A05,PNP0A06",
+	.ids = container_device_ids,
 	.ops = {
 		.add = acpi_container_add,
 		.remove = acpi_container_remove,
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 10e8510..469f3f5 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -41,7 +41,6 @@
 #include <acpi/actypes.h>
 
 #define ACPI_EC_CLASS			"embedded_controller"
-#define ACPI_EC_HID			"PNP0C09"
 #define ACPI_EC_DEVICE_NAME		"Embedded Controller"
 #define ACPI_EC_FILE_INFO		"info"
 
@@ -82,10 +81,15 @@ static int acpi_ec_start(struct acpi_device *device);
 static int acpi_ec_stop(struct acpi_device *device, int type);
 static int acpi_ec_add(struct acpi_device *device);
 
+static const struct acpi_device_id ec_device_ids[] = {
+	{"PNP0C09", 0},
+	{"", 0},
+};
+
 static struct acpi_driver acpi_ec_driver = {
 	.name = "ec",
 	.class = ACPI_EC_CLASS,
-	.ids = ACPI_EC_HID,
+	.ids = ec_device_ids,
 	.ops = {
 		.add = acpi_ec_add,
 		.remove = acpi_ec_remove,
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index ec655c5..c81f6bd 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -50,10 +50,16 @@ static int acpi_fan_remove(struct acpi_device *device, int type);
 static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
 static int acpi_fan_resume(struct acpi_device *device);
 
+static const struct acpi_device_id fan_device_ids[] = {
+	{"PNP0C0B", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, fan_device_ids);
+
 static struct acpi_driver acpi_fan_driver = {
 	.name = "fan",
 	.class = ACPI_FAN_CLASS,
-	.ids = "PNP0C0B",
+	.ids = fan_device_ids,
 	.ops = {
 		.add = acpi_fan_add,
 		.remove = acpi_fan_remove,
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 3448edd..c9f526e 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -46,7 +46,6 @@
 #define _COMPONENT		ACPI_PCI_COMPONENT
 ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_CLASS		"pci_irq_routing"
-#define ACPI_PCI_LINK_HID		"PNP0C0F"
 #define ACPI_PCI_LINK_DEVICE_NAME	"PCI Interrupt Link"
 #define ACPI_PCI_LINK_FILE_INFO		"info"
 #define ACPI_PCI_LINK_FILE_STATUS	"state"
@@ -54,10 +53,16 @@ ACPI_MODULE_NAME("pci_link");
 static int acpi_pci_link_add(struct acpi_device *device);
 static int acpi_pci_link_remove(struct acpi_device *device, int type);
 
+static struct acpi_device_id link_device_ids[] = {
+	{"PNP0C0F", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, link_device_ids);
+
 static struct acpi_driver acpi_pci_link_driver = {
 	.name = "pci_link",
 	.class = ACPI_PCI_LINK_CLASS,
-	.ids = ACPI_PCI_LINK_HID,
+	.ids = link_device_ids,
 	.ops = {
 		.add = acpi_pci_link_add,
 		.remove = acpi_pci_link_remove,
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index ad4145a..f14ff1f 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -38,16 +38,21 @@
 #define _COMPONENT		ACPI_PCI_COMPONENT
 ACPI_MODULE_NAME("pci_root");
 #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
-#define ACPI_PCI_ROOT_HID		"PNP0A03"
 #define ACPI_PCI_ROOT_DEVICE_NAME	"PCI Root Bridge"
 static int acpi_pci_root_add(struct acpi_device *device);
 static int acpi_pci_root_remove(struct acpi_device *device, int type);
 static int acpi_pci_root_start(struct acpi_device *device);
 
+static struct acpi_device_id root_device_ids[] = {
+	{"PNP0A03", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, root_device_ids);
+
 static struct acpi_driver acpi_pci_root_driver = {
 	.name = "pci_root",
 	.class = ACPI_PCI_ROOT_CLASS,
-	.ids = ACPI_PCI_ROOT_HID,
+	.ids = root_device_ids,
 	.ops = {
 		.add = acpi_pci_root_add,
 		.remove = acpi_pci_root_remove,
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 4ffecd1..57b9a29 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -59,10 +59,16 @@ static int acpi_power_remove(struct acpi_device *device, int type);
 static int acpi_power_resume(struct acpi_device *device);
 static int acpi_power_open_fs(struct inode *inode, struct file *file);
 
+static struct acpi_device_id power_device_ids[] = {
+	{ACPI_POWER_HID, 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, power_device_ids);
+
 static struct acpi_driver acpi_power_driver = {
 	.name = "power",
 	.class = ACPI_POWER_CLASS,
-	.ids = ACPI_POWER_HID,
+	.ids = power_device_ids,
 	.ops = {
 		.add = acpi_power_add,
 		.remove = acpi_power_remove,
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 81aceb5..4984223 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -88,10 +88,16 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr);
 extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
 
 
+static const struct acpi_device_id processor_device_ids[] = {
+	{ACPI_PROCESSOR_HID, 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, processor_device_ids);
+
 static struct acpi_driver acpi_processor_driver = {
 	.name = "processor",
 	.class = ACPI_PROCESSOR_CLASS,
-	.ids = ACPI_PROCESSOR_HID,
+	.ids = processor_device_ids,
 	.ops = {
 		.add = acpi_processor_add,
 		.remove = acpi_processor_remove,
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 974d00c..7d8e78e 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -38,7 +38,6 @@
 #define ACPI_SBS_CLASS			"sbs"
 #define ACPI_AC_CLASS			"ac_adapter"
 #define ACPI_BATTERY_CLASS		"battery"
-#define ACPI_SBS_HID			"ACPI0002"
 #define ACPI_SBS_DEVICE_NAME		"Smart Battery System"
 #define ACPI_SBS_FILE_INFO		"info"
 #define ACPI_SBS_FILE_STATE		"state"
@@ -124,10 +123,17 @@ static int acpi_sbs_add(struct acpi_device *device);
 static int acpi_sbs_remove(struct acpi_device *device, int type);
 static int acpi_sbs_resume(struct acpi_device *device);
 
+static const struct acpi_device_id sbs_device_ids[] = {
+	{"ACPI0001", 0},
+	{"ACPI0005", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
+
 static struct acpi_driver acpi_sbs_driver = {
 	.name = "sbs",
 	.class = ACPI_SBS_CLASS,
-	.ids = "ACPI0001,ACPI0005",
+	.ids = sbs_device_ids,
 	.ops = {
 		.add = acpi_sbs_add,
 		.remove = acpi_sbs_remove,
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 58f1338..5a62de1 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -92,10 +92,16 @@ 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 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 = ACPI_THERMAL_HID,
+	.ids = thermal_device_ids,
 	.ops = {
 		.add = acpi_thermal_add,
 		.remove = acpi_thermal_remove,
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 04ea697..d987019 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -74,10 +74,16 @@ MODULE_LICENSE("GPL");
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
 
+static const struct acpi_device_id video_device_ids[] = {
+	{ACPI_VIDEO_HID, 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, video_device_ids);
+
 static struct acpi_driver acpi_video_bus = {
 	.name = "video",
 	.class = ACPI_VIDEO_CLASS,
-	.ids = ACPI_VIDEO_HID,
+	.ids = video_device_ids,
 	.ops = {
 		.add = acpi_video_bus_add,
 		.remove = acpi_video_bus_remove,
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index ba0e74a..9a2694e 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -1007,9 +1007,15 @@ static int hpet_acpi_remove(struct acpi_device *device, int type)
 	return -EINVAL;
 }
 
+static const struct acpi_device_id hpet_device_ids[] = {
+	{"PNP0103", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, hpet_device_ids);
+
 static struct acpi_driver hpet_acpi_driver = {
 	.name = "hpet",
-	.ids = "PNP0103",
+	.ids = hpet_device_ids,
 	.ops = {
 		.add = hpet_acpi_add,
 		.remove = hpet_acpi_remove,
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index 0acc3a1..e43e92f 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -31,7 +31,6 @@
 
 #define ACPI_ATLAS_NAME			"Atlas ACPI"
 #define ACPI_ATLAS_CLASS		"Atlas"
-#define ACPI_ATLAS_BUTTON_HID		"ASIM0000"
 
 static struct input_dev *input_dev;
 
@@ -130,10 +129,16 @@ static int atlas_acpi_button_remove(struct acpi_device *device, int type)
 	return status;
 }
 
+static const struct acpi_device_id atlas_device_ids[] = {
+	{"ASIM0000", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, atlas_device_ids);
+
 static struct acpi_driver atlas_acpi_driver = {
 	.name	= ACPI_ATLAS_NAME,
 	.class	= ACPI_ATLAS_CLASS,
-	.ids	= ACPI_ATLAS_BUTTON_HID,
+	.ids	= atlas_device_ids,
 	.ops	= {
 		.add	= atlas_acpi_button_add,
 		.remove	= atlas_acpi_button_remove,
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index f753060..63953fe 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -53,7 +53,6 @@
 #define ASUS_HOTK_NAME          "Asus Laptop Support"
 #define ASUS_HOTK_CLASS         "hotkey"
 #define ASUS_HOTK_DEVICE_NAME   "Hotkey"
-#define ASUS_HOTK_HID           "ATK0100"
 #define ASUS_HOTK_FILE          "asus-laptop"
 #define ASUS_HOTK_PREFIX        "\\_SB.ATKD."
 
@@ -197,12 +196,18 @@ static struct asus_hotk *hotk;
 /*
  * The hotkey driver declaration
  */
+static const struct acpi_device_id asus_device_ids[] = {
+	{"ATK0100", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, asus_device_ids);
+
 static int asus_hotk_add(struct acpi_device *device);
 static int asus_hotk_remove(struct acpi_device *device, int type);
 static struct acpi_driver asus_hotk_driver = {
 	.name = ASUS_HOTK_NAME,
 	.class = ASUS_HOTK_CLASS,
-	.ids = ASUS_HOTK_HID,
+	.ids = asus_device_ids,
 	.ops = {
 		.add = asus_hotk_add,
 		.remove = asus_hotk_remove,
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 303e48c..14ee06c 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -1124,10 +1124,22 @@ static int sony_nc_remove(struct acpi_device *device, int type)
 	return 0;
 }
 
+static const struct acpi_device_id sony_device_ids[] = {
+	{SONY_NC_HID, 0},
+	{SONY_PIC_HID, 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, sony_device_ids);
+
+static const struct acpi_device_id sony_nc_device_ids[] = {
+	{SONY_NC_HID, 0},
+	{"", 0},
+};
+
 static struct acpi_driver sony_nc_driver = {
 	.name = SONY_NC_DRIVER_NAME,
 	.class = SONY_NC_CLASS,
-	.ids = SONY_NC_HID,
+	.ids = sony_nc_device_ids,
 	.owner = THIS_MODULE,
 	.ops = {
 		.add = sony_nc_add,
@@ -2470,10 +2482,15 @@ static int sony_pic_resume(struct acpi_device *device)
 	return 0;
 }
 
+static const struct acpi_device_id sony_pic_device_ids[] = {
+	{SONY_PIC_HID, 0},
+	{"", 0},
+};
+
 static struct acpi_driver sony_pic_driver = {
 	.name = SONY_PIC_DRIVER_NAME,
 	.class = SONY_PIC_CLASS,
-	.ids = SONY_PIC_HID,
+	.ids = sony_pic_device_ids,
 	.owner = THIS_MODULE,
 	.ops = {
 		.add = sony_pic_add,
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index f15a58f..fa80f35 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -411,12 +411,13 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 
 	sprintf(ibm->acpi->driver->name, "%s_%s", IBM_NAME, ibm->name);
 	ibm->acpi->driver->ids = ibm->acpi->hid;
+
 	ibm->acpi->driver->ops.add = &tpacpi_device_add;
 
 	rc = acpi_bus_register_driver(ibm->acpi->driver);
 	if (rc < 0) {
 		printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n",
-		       ibm->acpi->hid, rc);
+		       ibm->name, rc);
 		kfree(ibm->acpi->driver);
 		ibm->acpi->driver = NULL;
 	} else if (!rc)
@@ -1316,8 +1317,13 @@ errexit:
 	return res;
 }
 
+static const struct acpi_device_id ibm_htk_device_ids[] = {
+	{IBM_HKEY_HID, 0},
+	{"", 0},
+};
+
 static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
-	.hid = IBM_HKEY_HID,
+	.hid = ibm_htk_device_ids,
 	.notify = hotkey_notify,
 	.handle = &hkey_handle,
 	.type = ACPI_DEVICE_NOTIFY,
@@ -2080,6 +2086,11 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
 /* don't list other alternatives as we install a notify handler on the 570 */
 IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
 
+static const struct acpi_device_id ibm_pci_device_ids[] = {
+	{PCI_ROOT_HID_STRING, 0},
+	{"", 0},
+};
+
 static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
 	{
 	 .notify = dock_notify,
@@ -2090,7 +2101,7 @@ static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
 	/* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING.
 	 * We just use it to get notifications of dock hotplug
 	 * in very old thinkpads */
-	 .hid = PCI_ROOT_HID_STRING,
+	 .hid = ibm_pci_device_ids,
 	 .notify = dock_notify,
 	 .handle = &pci_handle,
 	 .type = ACPI_SYSTEM_NOTIFY,
@@ -2149,7 +2160,8 @@ static int __init dock_init2(struct ibm_init_struct *iibm)
 static void dock_notify(struct ibm_struct *ibm, u32 event)
 {
 	int docked = dock_docked();
-	int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, PCI_ROOT_HID_STRING);
+	int pci = ibm->acpi->hid && ibm->acpi->device &&
+		acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids);
 
 	if (event == 1 && !pci)	/* 570 */
 		acpi_bus_generate_event(ibm->acpi->device, event, 1);	/* button */
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index b7a4a88..88af089 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -193,7 +193,7 @@ static void thinkpad_acpi_module_exit(void);
 struct ibm_struct;
 
 struct tp_acpi_drv_struct {
-	char *hid;
+	const struct acpi_device_id *hid;
 	struct acpi_driver *driver;
 
 	void (*notify) (struct ibm_struct *, u32);
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 11/16] ACPI: Kconfig: CONFIG_ACPI_PROCFS now defaults to N
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Len Brown

delete "default y" from CONFIG_ACPI_PROCFS
(effectively making the default 'N')

List exactly what /proc files this option controls,
and clarify that it doesn't change non-deprecated files.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/Kconfig |   27 +++++++++++++++++----------
 1 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 408b451..8e42977 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -76,17 +76,24 @@ config ACPI_SLEEP_PROC_SLEEP
 	  Deprecated by /sys/power/state
 
 config ACPI_PROCFS
-	bool "Procfs interface (deprecated)"
-	default y
+	bool "Deprecated /proc/acpi files"
+	depends on PROC_FS
 	---help---
-	  The Procfs interface for ACPI is made optional for backward compatibility.
-	  As the same functions are duplicated in the sysfs interface
-	  and this proc interface will be removed some time later,
-	  it's marked as deprecated.
-	  ( /proc/acpi/debug_layer && debug_level are deprecated by
-	    /sys/module/acpi/parameters/debug_layer && debug_level.
-	    /proc/acpi/info is deprecated by
-	    /sys/module/acpi/parameters/acpica_version )
+	  For backwards compatibility, this option allows
+	  depricated /proc/acpi/ files to exist, even when
+	  they have been replaced by functions in /sys.
+	  The deprecated files (and their replacements) include:
+
+	  /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
+	  /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
+	  /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
+	  /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
+	  /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level)
+
+	  This option has no effect on /proc/acpi/ files
+	  and functions which do not yet exist in /sys.
+
+	  Say N to delete /proc/acpi/ files that have moved to /sys/
 
 config ACPI_AC
 	tristate "AC Adapter"
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 12/16] ACPI: Kconfig: fold /proc/acpi/sleep under CONFIG_ACPI_PROCFS
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Len Brown

/proc/acpi/sleep has had its own "default n" option,
ACPI_SLEEP_PROC_SLEEP, for many months.
Time to delete ACPI_SLEEP_PROC_SLEEP.

Users that still need /proc/acpi/sleep can still get it
along with the other deprecated /proc/acpi files
by enabling CONFIG_ACPI_PROCFS.

Also delete ACPI_SLEEP_PROC_FS, which was an umbrella
for /proc/acpi/sleep, wakeup, alarm, because it was
effectively just a synonym for ACPI_SLEEP.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/Kconfig        |   14 +-------------
 drivers/acpi/sleep/Makefile |    2 +-
 drivers/acpi/sleep/proc.c   |   20 ++++++++++++++------
 3 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 8e42977..efd47ee 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -62,19 +62,6 @@ config ACPI_SLEEP
 	  This option is not recommended for anyone except those doing driver
 	  power management development.
 
-config ACPI_SLEEP_PROC_FS
-	bool
-	depends on ACPI_SLEEP && PROC_FS
-	default y
-
-config ACPI_SLEEP_PROC_SLEEP
-	bool "/proc/acpi/sleep (deprecated)"
-	depends on ACPI_SLEEP_PROC_FS
-	default n
-	---help---
-	  Create /proc/acpi/sleep
-	  Deprecated by /sys/power/state
-
 config ACPI_PROCFS
 	bool "Deprecated /proc/acpi files"
 	depends on PROC_FS
@@ -84,6 +71,7 @@ config ACPI_PROCFS
 	  they have been replaced by functions in /sys.
 	  The deprecated files (and their replacements) include:
 
+	  /proc/acpi/sleep (/sys/power/state)
 	  /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
 	  /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
 	  /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
diff --git a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile
index d6c0177..195a4f6 100644
--- a/drivers/acpi/sleep/Makefile
+++ b/drivers/acpi/sleep/Makefile
@@ -1,5 +1,5 @@
 obj-y					:= poweroff.o wakeup.o
 obj-$(CONFIG_ACPI_SLEEP)		+= main.o
-obj-$(CONFIG_ACPI_SLEEP_PROC_FS)	+= proc.o
+obj-$(CONFIG_ACPI_SLEEP)		+= proc.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 61f1822..ed58e11 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -14,8 +14,16 @@
 #include "sleep.h"
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
+
+/*
+ * this file provides support for:
+ * /proc/acpi/sleep
+ * /proc/acpi/alarm
+ * /proc/acpi/wakeup
+ */
+
 ACPI_MODULE_NAME("sleep")
-#ifdef	CONFIG_ACPI_SLEEP_PROC_SLEEP
+#ifdef	CONFIG_ACPI_PROCFS
 static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
 {
 	int i;
@@ -68,7 +76,7 @@ acpi_system_write_sleep(struct file *file,
       Done:
 	return error ? error : count;
 }
-#endif				/* CONFIG_ACPI_SLEEP_PROC_SLEEP */
+#endif				/* CONFIG_ACPI_PROCFS */
 
 #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
 /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */
@@ -463,7 +471,7 @@ static const struct file_operations acpi_system_wakeup_device_fops = {
 	.release = single_release,
 };
 
-#ifdef	CONFIG_ACPI_SLEEP_PROC_SLEEP
+#ifdef	CONFIG_ACPI_PROCFS
 static const struct file_operations acpi_system_sleep_fops = {
 	.open = acpi_system_sleep_open_fs,
 	.read = seq_read,
@@ -471,7 +479,7 @@ static const struct file_operations acpi_system_sleep_fops = {
 	.llseek = seq_lseek,
 	.release = single_release,
 };
-#endif				/* CONFIG_ACPI_SLEEP_PROC_SLEEP */
+#endif				/* CONFIG_ACPI_PROCFS */
 
 #ifdef	HAVE_ACPI_LEGACY_ALARM
 static const struct file_operations acpi_system_alarm_fops = {
@@ -498,14 +506,14 @@ static int __init acpi_sleep_proc_init(void)
 	if (acpi_disabled)
 		return 0;
 
-#ifdef	CONFIG_ACPI_SLEEP_PROC_SLEEP
+#ifdef	CONFIG_ACPI_PROCFS
 	/* 'sleep' [R/W] */
 	entry =
 	    create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR,
 			      acpi_root_dir);
 	if (entry)
 		entry->proc_fops = &acpi_system_sleep_fops;
-#endif
+#endif				/* CONFIG_ACPI_PROCFS */
 
 #ifdef	HAVE_ACPI_LEGACY_ALARM
 	/* 'alarm' [R/W] */
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 13/16] ACPI: Kconfig: always enable CONFIG_ACPI_SLEEP on X86
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Len Brown

The SMP dependency on HOTPLUG_CPU and SUSPEND_SMP
caused more harm than good -- making ACPI sleep
support vanish for configs missing those options.
So simply select them on the (ACPI && SMP && X86) systems
that need them.

Also, remove the prompt for ACPI_SLEEP,
virtually nobody (intentionally) enables ACPI without it.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/Kconfig |   21 ++++-----------------
 1 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index efd47ee..524cbf1 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -43,24 +43,11 @@ menuconfig ACPI
 if ACPI
 
 config ACPI_SLEEP
-	bool "Sleep States"
-	depends on X86 && (!SMP || SUSPEND_SMP)
+	bool
+	depends on X86
+	select HOTPLUG_CPU if SMP
+	select SUSPEND_SMP if SMP
 	default y
-	---help---
-	  This option adds support for ACPI suspend states. 
-
-	  With this option, you will be able to put the system "to sleep". 
-	  Sleep states are low power states for the system and devices. All
-	  of the system operating state is saved to either memory or disk
-	  (depending on the state), to allow the system to resume operation
-	  quickly at your request.
-
-	  Although this option sounds really nifty, barely any of the device
-	  drivers have been converted to the new driver model and hence few
-	  have proper power management support. 
-
-	  This option is not recommended for anyone except those doing driver
-	  power management development.
 
 config ACPI_PROCFS
 	bool "Deprecated /proc/acpi files"
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 14/16] ACPI: Remove references to ACPI_STATE_S2 from acpi_pm_enter
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Rafael J. Wysocki, Len Brown

From: Rafael J. Wysocki <rjw@sisk.pl>

Remove references to ACPI_STATE_S2, introduced by
acpi-implement-the-set_target-callback-from-pm_ops.patch, from acpi_pm_enter().

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/sleep/main.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 55eca6e..29bdb01 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -81,8 +81,8 @@ static int acpi_pm_prepare(suspend_state_t pm_state)
  *	acpi_pm_enter - Actually enter a sleep state.
  *	@pm_state: ignored
  *
- *	Flush caches and go to sleep. For STR or S2, we have to call
- *	arch-specific assembly, which in turn call acpi_enter_sleep_state().
+ *	Flush caches and go to sleep. For STR we have to call arch-specific
+ *	assembly, which in turn call acpi_enter_sleep_state().
  *	It's unfortunate, but it works. Please fix if you're feeling frisky.
  */
 
@@ -95,7 +95,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
 	ACPI_FLUSH_CPU_CACHE();
 
 	/* Do arch specific saving of state. */
-	if (acpi_state == ACPI_STATE_S2 || acpi_state == ACPI_STATE_S3) {
+	if (acpi_state == ACPI_STATE_S3) {
 		int error = acpi_save_state_mem();
 
 		if (error) {
@@ -112,7 +112,6 @@ static int acpi_pm_enter(suspend_state_t pm_state)
 		status = acpi_enter_sleep_state(acpi_state);
 		break;
 
-	case ACPI_STATE_S2:
 	case ACPI_STATE_S3:
 		do_suspend_lowlevel();
 		break;
@@ -129,7 +128,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
 	printk(KERN_DEBUG "Back to C!\n");
 
 	/* restore processor state */
-	if (acpi_state == ACPI_STATE_S2 || acpi_state == ACPI_STATE_S3)
+	if (acpi_state == ACPI_STATE_S3)
 		acpi_restore_state_mem();
 
 	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 15/16] ACPI: quiet ACPI Exceptions due to no _PTC or _TSS
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Len Brown

ACPI Exception (processor_throttling-0084): AE_NOT_FOUND, Evaluating _PTC [20070126]
ACPI Exception (processor_throttling-0147): AE_NOT_FOUND, Evaluating _TSS [20070126]

These methods are optional, so Linux should not
alarm users when they are not found.

http://bugzilla.kernel.org/show_bug.cgi?id=8802

Signed-off-by: Len Brown <len.brown@intel.com>
Acked-by: Luming Yu <luming.yu@intel.com>
---
 drivers/acpi/processor_throttling.c |   53 ++++++++++++++++++++++++----------
 1 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index dc5b859..0b8204e 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -47,6 +47,9 @@ ACPI_MODULE_NAME("processor_throttling");
 static int acpi_processor_get_throttling(struct acpi_processor *pr);
 int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
 
+/*
+ * _TPC - Throttling Present Capabilities
+ */
 static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
 {
 	acpi_status status = 0;
@@ -55,8 +58,10 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
 	if (!pr)
 		return -EINVAL;
 	status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc);
-	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TPC"));
+	if (ACPI_FAILURE(status)) {
+		if (status != AE_NOT_FOUND) {
+			ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TPC"));
+		}
 		return -ENODEV;
 	}
 	pr->throttling_platform_limit = (int)tpc;
@@ -68,9 +73,9 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
 	return acpi_processor_get_platform_limit(pr);
 }
 
-/* --------------------------------------------------------------------------
-                             _PTC, _TSS, _TSD support 
-   -------------------------------------------------------------------------- */
+/*
+ * _PTC - Processor Throttling Control (and status) register location
+ */
 static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
 {
 	int result = 0;
@@ -81,7 +86,9 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
 
 	status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer);
 	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTC"));
+		if (status != AE_NOT_FOUND) {
+			ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTC"));
+		}
 		return -ENODEV;
 	}
 
@@ -132,6 +139,10 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
 
 	return result;
 }
+
+/*
+ * _TSS - Throttling Supported States
+ */
 static int acpi_processor_get_throttling_states(struct acpi_processor *pr)
 {
 	int result = 0;
@@ -144,7 +155,9 @@ static int acpi_processor_get_throttling_states(struct acpi_processor *pr)
 
 	status = acpi_evaluate_object(pr->handle, "_TSS", NULL, &buffer);
 	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TSS"));
+		if (status != AE_NOT_FOUND) {
+			ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TSS"));
+		}
 		return -ENODEV;
 	}
 
@@ -201,6 +214,10 @@ static int acpi_processor_get_throttling_states(struct acpi_processor *pr)
 
 	return result;
 }
+
+/*
+ * _TSD - T-State Dependencies
+ */
 static int acpi_processor_get_tsd(struct acpi_processor *pr)
 {
 	int result = 0;
@@ -213,6 +230,9 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr)
 
 	status = acpi_evaluate_object(pr->handle, "_TSD", NULL, &buffer);
 	if (ACPI_FAILURE(status)) {
+		if (status != AE_NOT_FOUND) {
+			ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TSD"));
+		}
 		return -ENODEV;
 	}
 
@@ -525,9 +545,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 	int result = 0;
 	int step = 0;
 	int i = 0;
-	int no_ptc = 0;
-	int no_tss = 0;
-	int no_tsd = 0;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
@@ -538,12 +555,14 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 	if (!pr)
 		return -EINVAL;
 
-	/* TBD: Support ACPI 2.0 objects */
-	no_ptc = acpi_processor_get_throttling_control(pr);
-	no_tss = acpi_processor_get_throttling_states(pr);
-	no_tsd = acpi_processor_get_tsd(pr);
-
-	if (no_ptc || no_tss) {
+	/*
+	 * Evaluate _PTC, _TSS and _TPC
+	 * They must all be present or none of them can be used.
+	 */
+	if (acpi_processor_get_throttling_control(pr) ||
+		acpi_processor_get_throttling_states(pr) ||
+		acpi_processor_get_platform_limit(pr))
+	{
 		pr->throttling.acpi_processor_get_throttling =
 		    &acpi_processor_get_throttling_fadt;
 		pr->throttling.acpi_processor_set_throttling =
@@ -555,6 +574,8 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 		    &acpi_processor_set_throttling_ptc;
 	}
 
+	acpi_processor_get_tsd(pr);
+
 	if (!pr->throttling.address) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
 		return 0;
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 16/16] ACPI: Kconfig: remove CONFIG_ACPI_SLEEP from source
@ 2007-07-25  5:51     ` Len Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2007-07-25  5:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Len Brown

As it was a synonym for (CONFIG_ACPI && CONFIG_X86),
the ifdefs for it were more clutter than they were worth.

For ia64, just add a few stubs in anticipation of future
S3 or S4 support.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/i386/kernel/acpi/Makefile   |    2 +-
 arch/i386/kernel/setup.c         |    2 +-
 arch/i386/mm/init.c              |    2 +-
 arch/ia64/kernel/acpi.c          |   19 +++++++++++++++++++
 arch/x86_64/kernel/acpi/Makefile |    2 +-
 arch/x86_64/kernel/acpi/sleep.c  |    4 ----
 arch/x86_64/kernel/head.S        |    2 +-
 arch/x86_64/kernel/setup.c       |    2 +-
 drivers/acpi/Kconfig             |   10 +++-------
 drivers/acpi/sleep/Makefile      |    4 ++--
 drivers/acpi/sleep/main.c        |    2 ++
 drivers/acpi/sleep/poweroff.c    |    2 --
 drivers/acpi/sleep/wakeup.c      |    2 --
 include/acpi/acpi_drivers.h      |    4 ----
 include/asm-i386/acpi.h          |   23 +++++++++--------------
 include/asm-i386/suspend.h       |    2 +-
 include/asm-ia64/acpi.h          |    5 +++++
 include/asm-x86_64/acpi.h        |   22 +++++++++-------------
 include/asm-x86_64/suspend.h     |    2 --
 kernel/sysctl.c                  |    2 +-
 20 files changed, 57 insertions(+), 58 deletions(-)

diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile
index 7f7be01..223f58f 100644
--- a/arch/i386/kernel/acpi/Makefile
+++ b/arch/i386/kernel/acpi/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_ACPI)		+= boot.o
 ifneq ($(CONFIG_PCI),)
 obj-$(CONFIG_X86_IO_APIC)	+= earlyquirk.o
 endif
-obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup.o
+obj-$(CONFIG_ACPI)		+= sleep.o wakeup.o
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y				+= cstate.o processor.o
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index d474cd6..7fe5da3 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -422,7 +422,7 @@ void __init setup_bootmem_allocator(void)
 	 */
 	reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
 #endif
-#ifdef CONFIG_ACPI_SLEEP
+#ifdef CONFIG_ACPI
 	/*
 	 * Reserve low memory region for sleep support.
 	 */
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index c3b9905..1b1a1e6 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -432,7 +432,7 @@ static void __init pagetable_init (void)
 	paravirt_pagetable_setup_done(pgd_base);
 }
 
-#if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP)
+#if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI)
 /*
  * Swap suspend & friends need this for resume because things like the intel-agp
  * driver might have split up a kernel 4MB mapping.
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 103dd8e..c6ede87 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -67,6 +67,8 @@ EXPORT_SYMBOL(pm_power_off);
 unsigned int acpi_cpei_override;
 unsigned int acpi_cpei_phys_cpuid;
 
+unsigned long acpi_wakeup_address = 0;
+
 const char __init *
 acpi_get_sysname(void)
 {
@@ -986,4 +988,21 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
 
 EXPORT_SYMBOL(acpi_unregister_ioapic);
 
+/*
+ * acpi_save_state_mem() - save kernel state
+ *
+ * TBD when when IA64 starts to support suspend...
+ */
+int acpi_save_state_mem(void) { return 0; } 
+
+/*
+ * acpi_restore_state()
+ */
+void acpi_restore_state_mem(void) {}
+
+/*
+ * do_suspend_lowlevel()
+ */
+void do_suspend_lowlevel(void) {}
+
 #endif				/* CONFIG_ACPI */
diff --git a/arch/x86_64/kernel/acpi/Makefile b/arch/x86_64/kernel/acpi/Makefile
index 080b996..17595d2 100644
--- a/arch/x86_64/kernel/acpi/Makefile
+++ b/arch/x86_64/kernel/acpi/Makefile
@@ -1,6 +1,6 @@
 obj-y			:= boot.o
 boot-y			:= ../../../i386/kernel/acpi/boot.o
-obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup.o
+obj-y			+= sleep.o wakeup.o
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y			+= processor.o
diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c
index 4277f2b..79475d2 100644
--- a/arch/x86_64/kernel/acpi/sleep.c
+++ b/arch/x86_64/kernel/acpi/sleep.c
@@ -51,8 +51,6 @@
                               Low-Level Sleep Support
    -------------------------------------------------------------------------- */
 
-#ifdef CONFIG_ACPI_SLEEP
-
 /* address in low memory of the wakeup routine. */
 unsigned long acpi_wakeup_address = 0;
 unsigned long acpi_realmode_flags;
@@ -117,8 +115,6 @@ static int __init acpi_sleep_setup(char *str)
 
 __setup("acpi_sleep=", acpi_sleep_setup);
 
-#endif				/*CONFIG_ACPI_SLEEP */
-
 void acpi_pci_link_exit(void)
 {
 }
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
index e89abcd..3a16e41 100644
--- a/arch/x86_64/kernel/head.S
+++ b/arch/x86_64/kernel/head.S
@@ -120,7 +120,7 @@ ident_complete:
 	addq	%rbp, trampoline_level4_pgt + 0(%rip)
 	addq	%rbp, trampoline_level4_pgt + (511*8)(%rip)
 #endif
-#ifdef CONFIG_ACPI_SLEEP
+#ifdef CONFIG_ACPI
 	addq	%rbp, wakeup_level4_pgt + 0(%rip)
 	addq	%rbp, wakeup_level4_pgt + (511*8)(%rip)
 #endif
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index af838f6..0f400f3 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -333,7 +333,7 @@ void __init setup_arch(char **cmdline_p)
 	reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE);
 #endif
 
-#ifdef CONFIG_ACPI_SLEEP
+#ifdef CONFIG_ACPI
        /*
         * Reserve low memory region for sleep support.
         */
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 524cbf1..251344c 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -11,6 +11,9 @@ menuconfig ACPI
 	depends on PCI
 	depends on PM
 	select PNP
+	# for sleep
+	select HOTPLUG_CPU if X86 && SMP
+	select SUSPEND_SMP if X86 && SMP
 	default y
 	---help---
 	  Advanced Configuration and Power Interface (ACPI) support for 
@@ -42,13 +45,6 @@ menuconfig ACPI
 
 if ACPI
 
-config ACPI_SLEEP
-	bool
-	depends on X86
-	select HOTPLUG_CPU if SMP
-	select SUSPEND_SMP if SMP
-	default y
-
 config ACPI_PROCFS
 	bool "Deprecated /proc/acpi files"
 	depends on PROC_FS
diff --git a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile
index 195a4f6..01a993a 100644
--- a/drivers/acpi/sleep/Makefile
+++ b/drivers/acpi/sleep/Makefile
@@ -1,5 +1,5 @@
 obj-y					:= poweroff.o wakeup.o
-obj-$(CONFIG_ACPI_SLEEP)		+= main.o
-obj-$(CONFIG_ACPI_SLEEP)		+= proc.o
+obj-y					+= main.o
+obj-$(CONFIG_X86)			+= proc.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 3279e72..54c2dfc 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -136,10 +136,12 @@ static int acpi_pm_finish(suspend_state_t pm_state)
 	/* reset firmware waking vector */
 	acpi_set_firmware_waking_vector((acpi_physical_address) 0);
 
+#ifdef CONFIG_X86
 	if (init_8259A_after_S1) {
 		printk("Broken toshiba laptop -> kicking interrupts\n");
 		init_8259A(0);
 	}
+#endif
 	return 0;
 }
 
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
index 39e40d5..b3f68ef 100644
--- a/drivers/acpi/sleep/poweroff.c
+++ b/drivers/acpi/sleep/poweroff.c
@@ -18,7 +18,6 @@
 
 int acpi_sleep_prepare(u32 acpi_state)
 {
-#ifdef CONFIG_ACPI_SLEEP
 	/* do we have a wakeup address for S2 and S3? */
 	if (acpi_state == ACPI_STATE_S3) {
 		if (!acpi_wakeup_address) {
@@ -31,7 +30,6 @@ int acpi_sleep_prepare(u32 acpi_state)
 	}
 	ACPI_FLUSH_CPU_CACHE();
 	acpi_enable_wakeup_device_prep(acpi_state);
-#endif
 	acpi_gpe_sleep_prepare(acpi_state);
 	acpi_enter_sleep_state_prep(acpi_state);
 	return 0;
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index fab8f26..97c27dd 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -17,7 +17,6 @@ ACPI_MODULE_NAME("wakeup_devices")
 extern struct list_head acpi_wakeup_device_list;
 extern spinlock_t acpi_device_lock;
 
-#ifdef CONFIG_ACPI_SLEEP
 /**
  * acpi_enable_wakeup_device_prep - prepare wakeup devices
  *	@sleep_state:	ACPI state
@@ -180,7 +179,6 @@ static int __init acpi_wakeup_device_init(void)
 }
 
 late_initcall(acpi_wakeup_device_init);
-#endif
 
 /*
  * Disable all wakeup GPEs before entering requested sleep state.
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 5535159..07b5d76 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -142,10 +142,6 @@ static inline void unregister_hotplug_dock_device(acpi_handle handle)
 /*--------------------------------------------------------------------------
                                   Suspend/Resume
   -------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_SLEEP
 extern int acpi_sleep_init(void);
-#else
-#define acpi_sleep_init() do {} while (0)
-#endif
 
 #endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index 449f3f2..125179a 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -121,19 +121,6 @@ static inline void acpi_disable_pci(void)
 }
 extern int acpi_irq_balance_set(char *str);
 
-#else	/* !CONFIG_ACPI */
-
-#define acpi_lapic 0
-#define acpi_ioapic 0
-static inline void acpi_noirq_set(void) { }
-static inline void acpi_disable_pci(void) { }
-static inline void disable_acpi(void) { }
-
-#endif	/* !CONFIG_ACPI */
-
-
-#ifdef CONFIG_ACPI_SLEEP
-
 /* routines for saving/restoring kernel state */
 extern int acpi_save_state_mem(void);
 extern void acpi_restore_state_mem(void);
@@ -143,7 +130,15 @@ extern unsigned long acpi_wakeup_address;
 /* early initialization routine */
 extern void acpi_reserve_bootmem(void);
 
-#endif /*CONFIG_ACPI_SLEEP*/
+#else	/* !CONFIG_ACPI */
+
+#define acpi_lapic 0
+#define acpi_ioapic 0
+static inline void acpi_noirq_set(void) { }
+static inline void acpi_disable_pci(void) { }
+static inline void disable_acpi(void) { }
+
+#endif	/* !CONFIG_ACPI */
 
 #define ARCH_HAS_POWER_INIT	1
 
diff --git a/include/asm-i386/suspend.h b/include/asm-i386/suspend.h
index 8dbaafe..a252073 100644
--- a/include/asm-i386/suspend.h
+++ b/include/asm-i386/suspend.h
@@ -21,7 +21,7 @@ struct saved_context {
 	unsigned long return_address;
 } __attribute__((packed));
 
-#ifdef CONFIG_ACPI_SLEEP
+#ifdef CONFIG_ACPI
 extern unsigned long saved_eip;
 extern unsigned long saved_esp;
 extern unsigned long saved_ebp;
diff --git a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h
index 5b52635..49730ff 100644
--- a/include/asm-ia64/acpi.h
+++ b/include/asm-ia64/acpi.h
@@ -100,6 +100,11 @@ const char *acpi_get_sysname (void);
 int acpi_request_vector (u32 int_type);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
+/* routines for saving/restoring kernel state */
+extern int acpi_save_state_mem(void);
+extern void acpi_restore_state_mem(void);
+extern unsigned long acpi_wakeup_address;
+
 /*
  * Record the cpei override flag and current logical cpu. This is
  * useful for CPU removal.
diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
index 1da8f49..9817335 100644
--- a/include/asm-x86_64/acpi.h
+++ b/include/asm-x86_64/acpi.h
@@ -108,6 +108,15 @@ static inline void acpi_disable_pci(void)
 }
 extern int acpi_irq_balance_set(char *str);
 
+/* routines for saving/restoring kernel state */
+extern int acpi_save_state_mem(void);
+extern void acpi_restore_state_mem(void);
+
+extern unsigned long acpi_wakeup_address;
+
+/* early initialization routine */
+extern void acpi_reserve_bootmem(void);
+
 #else	/* !CONFIG_ACPI */
 
 #define acpi_lapic 0
@@ -121,19 +130,6 @@ extern int acpi_numa;
 extern int acpi_scan_nodes(unsigned long start, unsigned long end);
 #define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
 
-#ifdef CONFIG_ACPI_SLEEP
-
-/* routines for saving/restoring kernel state */
-extern int acpi_save_state_mem(void);
-extern void acpi_restore_state_mem(void);
-
-extern unsigned long acpi_wakeup_address;
-
-/* early initialization routine */
-extern void acpi_reserve_bootmem(void);
-
-#endif /*CONFIG_ACPI_SLEEP*/
-
 extern int acpi_disabled;
 extern int acpi_pci_disabled;
 
diff --git a/include/asm-x86_64/suspend.h b/include/asm-x86_64/suspend.h
index 9c3f8de..b897e8c 100644
--- a/include/asm-x86_64/suspend.h
+++ b/include/asm-x86_64/suspend.h
@@ -44,7 +44,6 @@ extern unsigned long saved_context_eflags;
 
 extern void fix_processor_context(void);
 
-#ifdef CONFIG_ACPI_SLEEP
 extern unsigned long saved_rip;
 extern unsigned long saved_rsp;
 extern unsigned long saved_rbp;
@@ -54,4 +53,3 @@ extern unsigned long saved_rdi;
 
 /* routines for saving/restoring kernel state */
 extern int acpi_save_state_mem(void);
-#endif
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index ddebf3f..eb26f2b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -689,7 +689,7 @@ static ctl_table kern_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 #endif
-#ifdef CONFIG_ACPI_SLEEP
+#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
 	{
 		.ctl_name	= KERN_ACPI_VIDEO_FLAGS,
 		.procname	= "acpi_video_flags",
-- 
1.5.3.rc2.22.g69a9b

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: ACPI patches for 2.6.23-rc1
  2007-07-25  5:51 ACPI patches for 2.6.23-rc1 Len Brown
  2007-07-25  5:51   ` Len Brown
@ 2007-07-25  9:49 ` Richard Hughes
  1 sibling, 0 replies; 18+ messages in thread
From: Richard Hughes @ 2007-07-25  9:49 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi, kay.sievers, Matthias Clasen, Zack Cerza

[-- Attachment #1: Type: text/plain, Size: 2630 bytes --]

On Wed, 2007-07-25 at 01:51 -0400, Len Brown wrote:
> I wish this batch did not miss the -rc1 deadline.
> Some of them must go into -rc2, bug some of them are
> probably bigger than should really go in post -rc1 --
> lets see how good a mood Linus is in tomorrow:-)

Len, the attached patch has been ignored two or three times now.
I've been getting about 2-3 duplicate bugs a week about this.

Please apply,

Richard.

From: Richard Hughes <richard@hughsie.com>
Date: Fri, 15 Jun 2007 15:53:11 +0100
Subject: No Subject
Message-Id: <1181919191.2681.5.camel@work>
Mime-Version: 1.0
Content-Transfer-Encoding: 7bit

On resume we need to refresh the lid status as we will not get an event if
the lid opening was what triggered the suspend.
This manifests itself in users never getting a "lid open" event when a
suspend happens because of lid close on hardware that supports wake on
lid open. This makes userspace gets very confused indeed.
Patch attached forces a check of the lid status in the resume handler.

Signed-off-by: Richard Hughes <richard@hughsie.com>
---

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index cb4110b..fd3473b 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -68,6 +68,7 @@ MODULE_LICENSE("GPL");
 
 static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device, int type);
+static int acpi_button_resume(struct acpi_device *device);
 static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
@@ -77,6 +78,7 @@ static struct acpi_driver acpi_button_driver = {
 	.ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
 	.ops = {
 		.add = acpi_button_add,
+		.resume = acpi_button_resume,
 		.remove = acpi_button_remove,
 	},
 };
@@ -487,6 +489,29 @@ static int acpi_button_remove(struct acpi_device *device, int type)
 	return 0;
 }
 
+/* this is needed to learn about changes made in suspended state */
+static int acpi_button_resume(struct acpi_device *device)
+{
+	struct acpi_button *button;
+	struct acpi_handle *handle;
+	struct input_dev *input;
+	unsigned long state;
+
+	button = device->driver_data;
+	handle = button->device->handle;
+	input = button->input;
+
+	/*
+	 * On resume we send the state; if it matches to what input layer
+	 * thinks then the event will not even reach userspace.
+	 */
+	if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
+						NULL, &state)))
+		input_report_switch(input, SW_LID, !state);
+
+	return 0;
+}
+
 static int __init acpi_button_init(void)
 {
 	int result;


[-- Attachment #2: button-resume.patch --]
[-- Type: message/rfc822, Size: 2209 bytes --]

From: Richard Hughes <richard@hughsie.com>
Subject: No Subject
Date: Fri, 15 Jun 2007 15:53:11 +0100
Message-ID: <1181919191.2681.5.camel@work>

On resume we need to refresh the lid status as we will not get an event if
the lid opening was what triggered the suspend.
This manifests itself in users never getting a "lid open" event when a
suspend happens because of lid close on hardware that supports wake on
lid open. This makes userspace gets very confused indeed.
Patch attached forces a check of the lid status in the resume handler.

Signed-off-by: Richard Hughes <richard@hughsie.com>
---

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index cb4110b..fd3473b 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -68,6 +68,7 @@ MODULE_LICENSE("GPL");
 
 static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device, int type);
+static int acpi_button_resume(struct acpi_device *device);
 static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
@@ -77,6 +78,7 @@ static struct acpi_driver acpi_button_driver = {
 	.ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
 	.ops = {
 		.add = acpi_button_add,
+		.resume = acpi_button_resume,
 		.remove = acpi_button_remove,
 	},
 };
@@ -487,6 +489,29 @@ static int acpi_button_remove(struct acpi_device *device, int type)
 	return 0;
 }
 
+/* this is needed to learn about changes made in suspended state */
+static int acpi_button_resume(struct acpi_device *device)
+{
+	struct acpi_button *button;
+	struct acpi_handle *handle;
+	struct input_dev *input;
+	unsigned long state;
+
+	button = device->driver_data;
+	handle = button->device->handle;
+	input = button->input;
+
+	/*
+	 * On resume we send the state; if it matches to what input layer
+	 * thinks then the event will not even reach userspace.
+	 */
+	if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
+						NULL, &state)))
+		input_report_switch(input, SW_LID, !state);
+
+	return 0;
+}
+
 static int __init acpi_button_init(void)
 {
 	int result;

^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2007-07-25  9:54 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-25  5:51 ACPI patches for 2.6.23-rc1 Len Brown
2007-07-25  5:51 ` [PATCH 01/16] ACPI: Implement the set_target() callback from pm_ops Len Brown
2007-07-25  5:51   ` Len Brown
2007-07-25  5:51   ` [PATCH 02/16] ACPI: Add acpi_pm_device_sleep_state helper routine Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 03/16] ACPI, PNP: hook ACPI D-state to PNP suspend/resume Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 04/16] ACPI: Use ACPI methods to select PCI device suspend state Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 05/16] ACPI: ignore _PSx method for hotplugable PCI devices Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 06/16] ACPI: fix oops due to typo in new throttling code Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 07/16] ACPI: asus-laptop: Fix failure exits Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 08/16] ACPI: autoload modules - ACPICA modifications Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 09/16] ACPI: autoload modules - Create ACPI alias interface Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 10/16] ACPI: autoload modules - Create __mod_acpi_device_table symbol for all ACPI drivers Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 11/16] ACPI: Kconfig: CONFIG_ACPI_PROCFS now defaults to N Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 12/16] ACPI: Kconfig: fold /proc/acpi/sleep under CONFIG_ACPI_PROCFS Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 13/16] ACPI: Kconfig: always enable CONFIG_ACPI_SLEEP on X86 Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 14/16] ACPI: Remove references to ACPI_STATE_S2 from acpi_pm_enter Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 15/16] ACPI: quiet ACPI Exceptions due to no _PTC or _TSS Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  5:51   ` [PATCH 16/16] ACPI: Kconfig: remove CONFIG_ACPI_SLEEP from source Len Brown
2007-07-25  5:51     ` Len Brown
2007-07-25  9:49 ` ACPI patches for 2.6.23-rc1 Richard Hughes

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.