diff --git a/[refs] b/[refs] index 6df2dd36d275..2b0e2d862cf8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3344203948f40521c35a0a52e3f1bd9fbb7a1118 +refs/heads/master: d95cbe6158a679d50e03787bb1dc21ff73dac372 diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 4cd1a5da80a4..508e2a2c9864 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -170,6 +170,11 @@ and is between 256 and 4096 characters. It is defined in the file acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA Format: ,... + acpi_new_pts_ordering [HW,ACPI] + Enforce the ACPI 2.0 ordering of the _PTS control + method wrt putting devices into low power states + default: pre ACPI 2.0 ordering of _PTS + acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS diff --git a/trunk/drivers/acpi/sleep/main.c b/trunk/drivers/acpi/sleep/main.c index 71183eea7906..d2f71a54726c 100644 --- a/trunk/drivers/acpi/sleep/main.c +++ b/trunk/drivers/acpi/sleep/main.c @@ -26,6 +26,21 @@ u8 sleep_states[ACPI_S_STATE_COUNT]; #ifdef CONFIG_PM_SLEEP static u32 acpi_target_sleep_state = ACPI_STATE_S0; +static bool acpi_sleep_finish_wake_up; + +/* + * ACPI 2.0 and later want us to execute _PTS after suspending devices, so we + * allow the user to request that behavior by using the 'acpi_new_pts_ordering' + * kernel command line option that causes the following variable to be set. + */ +static bool new_pts_ordering; + +static int __init acpi_new_pts_ordering(char *str) +{ + new_pts_ordering = true; + return 1; +} +__setup("acpi_new_pts_ordering", acpi_new_pts_ordering); #endif static int acpi_sleep_prepare(u32 acpi_state) @@ -76,6 +91,14 @@ static int acpi_pm_begin(suspend_state_t pm_state) if (sleep_states[acpi_state]) { acpi_target_sleep_state = acpi_state; + if (new_pts_ordering) + return 0; + + error = acpi_sleep_prepare(acpi_state); + if (error) + acpi_target_sleep_state = ACPI_STATE_S0; + else + acpi_sleep_finish_wake_up = true; } else { printk(KERN_ERR "ACPI does not support this state: %d\n", pm_state); @@ -93,11 +116,14 @@ static int acpi_pm_begin(suspend_state_t pm_state) static int acpi_pm_prepare(void) { - int error = acpi_sleep_prepare(acpi_target_sleep_state); + if (new_pts_ordering) { + int error = acpi_sleep_prepare(acpi_target_sleep_state); - if (error) { - acpi_target_sleep_state = ACPI_STATE_S0; - return error; + if (error) { + acpi_target_sleep_state = ACPI_STATE_S0; + return error; + } + acpi_sleep_finish_wake_up = true; } return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; @@ -186,6 +212,7 @@ static void acpi_pm_finish(void) acpi_set_firmware_waking_vector((acpi_physical_address) 0); acpi_target_sleep_state = ACPI_STATE_S0; + acpi_sleep_finish_wake_up = false; #ifdef CONFIG_X86 if (init_8259A_after_S1) { @@ -202,10 +229,11 @@ static void acpi_pm_finish(void) static void acpi_pm_end(void) { /* - * This is necessary in case acpi_pm_finish() is not called during a - * failing transition to a sleep state. + * This is necessary in case acpi_pm_finish() is not called directly + * during a failing transition to a sleep state. */ - acpi_target_sleep_state = ACPI_STATE_S0; + if (acpi_sleep_finish_wake_up) + acpi_pm_finish(); } static int acpi_pm_state_valid(suspend_state_t pm_state) @@ -257,18 +285,31 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { #ifdef CONFIG_HIBERNATION static int acpi_hibernation_begin(void) { + int error; + acpi_target_sleep_state = ACPI_STATE_S4; + if (new_pts_ordering) + return 0; - return 0; + error = acpi_sleep_prepare(ACPI_STATE_S4); + if (error) + acpi_target_sleep_state = ACPI_STATE_S0; + else + acpi_sleep_finish_wake_up = true; + + return error; } static int acpi_hibernation_prepare(void) { - int error = acpi_sleep_prepare(ACPI_STATE_S4); + if (new_pts_ordering) { + int error = acpi_sleep_prepare(ACPI_STATE_S4); - if (error) { - acpi_target_sleep_state = ACPI_STATE_S0; - return error; + if (error) { + acpi_target_sleep_state = ACPI_STATE_S0; + return error; + } + acpi_sleep_finish_wake_up = true; } return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; @@ -312,15 +353,17 @@ static void acpi_hibernation_finish(void) acpi_set_firmware_waking_vector((acpi_physical_address) 0); acpi_target_sleep_state = ACPI_STATE_S0; + acpi_sleep_finish_wake_up = false; } static void acpi_hibernation_end(void) { /* * This is necessary in case acpi_hibernation_finish() is not called - * during a failing transition to the sleep state. + * directly during a failing transition to the sleep state. */ - acpi_target_sleep_state = ACPI_STATE_S0; + if (acpi_sleep_finish_wake_up) + acpi_hibernation_finish(); } static int acpi_hibernation_pre_restore(void) diff --git a/trunk/drivers/input/apm-power.c b/trunk/drivers/input/apm-power.c index 7d61a9660806..c36d110b349a 100644 --- a/trunk/drivers/input/apm-power.c +++ b/trunk/drivers/input/apm-power.c @@ -63,6 +63,8 @@ static int apmpower_connect(struct input_handler *handler, handle->handler = handler; handle->name = "apm-power"; + handler->private = handle; + error = input_register_handle(handle); if (error) { printk(KERN_ERR @@ -85,10 +87,11 @@ static int apmpower_connect(struct input_handler *handler, return 0; } -static void apmpower_disconnect(struct input_handle *handle) +static void apmpower_disconnect(struct input_handle *handler) { + struct input_handle *handle = handler->private; + input_close_device(handle); - input_unregister_handle(handle); kfree(handle); } diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index b32984bc516f..99562cee827e 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -124,7 +124,6 @@ static void evdev_free(struct device *dev) { struct evdev *evdev = container_of(dev, struct evdev, dev); - input_put_device(evdev->handle.dev); kfree(evdev); } @@ -854,6 +853,9 @@ static void evdev_cleanup(struct evdev *evdev) evdev_hangup(evdev); evdev_remove_chrdev(evdev); + if (evdev->grab) + evdev_ungrab(evdev, evdev->grab); + /* evdev is marked dead so no one else accesses evdev->open */ if (evdev->open) { input_flush_device(handle, NULL); @@ -894,7 +896,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, evdev->exist = 1; evdev->minor = minor; - evdev->handle.dev = input_get_device(dev); + evdev->handle.dev = dev; evdev->handle.name = evdev->name; evdev->handle.handler = handler; evdev->handle.private = evdev; diff --git a/trunk/drivers/input/joydev.c b/trunk/drivers/input/joydev.c index 65d7077a75a1..22b2789ef58a 100644 --- a/trunk/drivers/input/joydev.c +++ b/trunk/drivers/input/joydev.c @@ -171,7 +171,6 @@ static void joydev_free(struct device *dev) { struct joydev *joydev = container_of(dev, struct joydev, dev); - input_put_device(joydev->handle.dev); kfree(joydev); } @@ -751,7 +750,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, joydev->minor = minor; joydev->exist = 1; - joydev->handle.dev = input_get_device(dev); + joydev->handle.dev = dev; joydev->handle.name = joydev->name; joydev->handle.handler = handler; joydev->handle.private = joydev; diff --git a/trunk/drivers/input/keyboard/pxa27x_keypad.c b/trunk/drivers/input/keyboard/pxa27x_keypad.c index 4e651c11c1da..6224c2fb3b65 100644 --- a/trunk/drivers/input/keyboard/pxa27x_keypad.c +++ b/trunk/drivers/input/keyboard/pxa27x_keypad.c @@ -50,9 +50,9 @@ #define KPKDI 0x0048 /* bit definitions */ -#define KPC_MKRN(n) ((((n) - 1) & 0x7) << 26) /* matrix key row number */ -#define KPC_MKCN(n) ((((n) - 1) & 0x7) << 23) /* matrix key column number */ -#define KPC_DKN(n) ((((n) - 1) & 0x7) << 6) /* direct key number */ +#define KPC_MKRN(n) ((((n) & 0x7) - 1) << 26) /* matrix key row number */ +#define KPC_MKCN(n) ((((n) & 0x7) - 1) << 23) /* matrix key column number */ +#define KPC_DKN(n) ((((n) & 0x7) - 1) << 6) /* direct key number */ #define KPC_AS (0x1 << 30) /* Automatic Scan bit */ #define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ diff --git a/trunk/drivers/input/mousedev.c b/trunk/drivers/input/mousedev.c index b989748598ae..bbbe5e81adc1 100644 --- a/trunk/drivers/input/mousedev.c +++ b/trunk/drivers/input/mousedev.c @@ -414,7 +414,6 @@ static void mousedev_free(struct device *dev) { struct mousedev *mousedev = container_of(dev, struct mousedev, dev); - input_put_device(mousedev->handle.dev); kfree(mousedev); } @@ -866,7 +865,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, mousedev->minor = minor; mousedev->exist = 1; - mousedev->handle.dev = input_get_device(dev); + mousedev->handle.dev = dev; mousedev->handle.name = mousedev->name; mousedev->handle.handler = handler; mousedev->handle.private = mousedev; diff --git a/trunk/drivers/leds/leds-gpio.c b/trunk/drivers/leds/leds-gpio.c index 6c0a9c4761ee..d13b622419df 100644 --- a/trunk/drivers/leds/leds-gpio.c +++ b/trunk/drivers/leds/leds-gpio.c @@ -79,6 +79,10 @@ static int gpio_led_probe(struct platform_device *pdev) cur_led = &pdata->leds[i]; led_dat = &leds_data[i]; + ret = gpio_request(cur_led->gpio, cur_led->name); + if (ret < 0) + goto err; + led_dat->cdev.name = cur_led->name; led_dat->cdev.default_trigger = cur_led->default_trigger; led_dat->gpio = cur_led->gpio; @@ -87,10 +91,6 @@ static int gpio_led_probe(struct platform_device *pdev) led_dat->cdev.brightness_set = gpio_led_set; led_dat->cdev.brightness = LED_OFF; - ret = gpio_request(led_dat->gpio, led_dat->cdev.name); - if (ret < 0) - goto err; - gpio_direction_output(led_dat->gpio, led_dat->active_low); INIT_WORK(&led_dat->work, gpio_led_work); diff --git a/trunk/drivers/net/plip.c b/trunk/drivers/net/plip.c index 1e965427b0e9..fee3d7b1feba 100644 --- a/trunk/drivers/net/plip.c +++ b/trunk/drivers/net/plip.c @@ -903,18 +903,17 @@ plip_interrupt(void *dev_id) struct net_local *nl; struct plip_local *rcv; unsigned char c0; - unsigned long flags; nl = netdev_priv(dev); rcv = &nl->rcv_data; - spin_lock_irqsave (&nl->lock, flags); + spin_lock_irq (&nl->lock); c0 = read_status(dev); if ((c0 & 0xf8) != 0xc0) { if ((dev->irq != -1) && (net_debug > 1)) printk(KERN_DEBUG "%s: spurious interrupt\n", dev->name); - spin_unlock_irqrestore (&nl->lock, flags); + spin_unlock_irq (&nl->lock); return; } @@ -943,7 +942,7 @@ plip_interrupt(void *dev_id) break; } - spin_unlock_irqrestore(&nl->lock, flags); + spin_unlock_irq(&nl->lock); } static int diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index cae2c35d1206..1bdc39a8c76c 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -1227,13 +1227,12 @@ void input_free_device(struct input_dev *dev); static inline struct input_dev *input_get_device(struct input_dev *dev) { - return dev ? to_input_dev(get_device(&dev->dev)) : NULL; + return to_input_dev(get_device(&dev->dev)); } static inline void input_put_device(struct input_dev *dev) { - if (dev) - put_device(&dev->dev); + put_device(&dev->dev); } static inline void *input_get_drvdata(struct input_dev *dev)