Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 241693
b: refs/heads/master
c: 05534c9
h: refs/heads/master
i:
  241691: 7f1a364
v: v3
  • Loading branch information
Len Brown committed Mar 18, 2011
1 parent 36f4663 commit 0438740
Show file tree
Hide file tree
Showing 18 changed files with 194 additions and 155 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 589c7a39ae2f2b74fd13ae344ca1dcca61da6bca
refs/heads/master: 05534c9ffc9d5d950b14de8ba49a7609dc59b0b8
6 changes: 3 additions & 3 deletions trunk/arch/ia64/include/asm/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ static inline 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);
/* Low-level suspend routine. */
extern int acpi_suspend_lowlevel(void);

extern unsigned long acpi_wakeup_address;

/*
Expand Down
14 changes: 2 additions & 12 deletions trunk/arch/ia64/kernel/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1034,18 +1034,8 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
EXPORT_SYMBOL(acpi_unregister_ioapic);

/*
* acpi_save_state_mem() - save kernel state
* acpi_suspend_lowlevel() - save kernel state and suspend.
*
* 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) {}
int acpi_suspend_lowlevel(void) { return 0; }
5 changes: 2 additions & 3 deletions trunk/arch/x86/include/asm/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,8 @@ static inline void acpi_disable_pci(void)
acpi_noirq_set();
}

/* routines for saving/restoring kernel state */
extern int acpi_save_state_mem(void);
extern void acpi_restore_state_mem(void);
/* Low-level suspend routine. */
extern int acpi_suspend_lowlevel(void);

extern unsigned long acpi_wakeup_address;

Expand Down
13 changes: 3 additions & 10 deletions trunk/arch/x86/kernel/acpi/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ static char temp_stack[4096];
#endif

/**
* acpi_save_state_mem - save kernel state
* acpi_suspend_lowlevel - save kernel state
*
* Create an identity mapped page table and copy the wakeup routine to
* low memory.
*
* Note that this is too late to change acpi_wakeup_address.
*/
int acpi_save_state_mem(void)
int acpi_suspend_lowlevel(void)
{
struct wakeup_header *header;

Expand Down Expand Up @@ -107,17 +107,10 @@ int acpi_save_state_mem(void)
saved_magic = 0x123456789abcdef0L;
#endif /* CONFIG_64BIT */

do_suspend_lowlevel();
return 0;
}

/*
* acpi_restore_state - undo effects of acpi_save_state_mem
*/
void acpi_restore_state_mem(void)
{
}


/**
* acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation
*
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/x86/kernel/acpi/sleep.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ extern char swsusp_pg_dir[PAGE_SIZE];

extern unsigned long acpi_copy_wakeup_routine(unsigned long);
extern void wakeup_long64(void);

extern void do_suspend_lowlevel(void);
7 changes: 6 additions & 1 deletion trunk/drivers/acpi/acpica/aclocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,10 +397,15 @@ struct acpi_gpe_handler_info {
u8 originally_enabled; /* True if GPE was originally enabled */
};

struct acpi_gpe_notify_object {
struct acpi_namespace_node *node;
struct acpi_gpe_notify_object *next;
};

union acpi_gpe_dispatch_info {
struct acpi_namespace_node *method_node; /* Method node for this GPE level */
struct acpi_gpe_handler_info *handler; /* Installed GPE handler */
struct acpi_namespace_node *device_node; /* Parent _PRW device for implicit notify */
struct acpi_gpe_notify_object device; /* List of _PRW devices for implicit notify */
};

/*
Expand Down
17 changes: 13 additions & 4 deletions trunk/drivers/acpi/acpica/evgpe.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
acpi_status status;
struct acpi_gpe_event_info *local_gpe_event_info;
struct acpi_evaluate_info *info;
struct acpi_gpe_notify_object *notify_object;

ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);

Expand Down Expand Up @@ -517,10 +518,18 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
* from this thread -- because handlers may in turn run other
* control methods.
*/
status =
acpi_ev_queue_notify_request(local_gpe_event_info->dispatch.
device_node,
ACPI_NOTIFY_DEVICE_WAKE);
status = acpi_ev_queue_notify_request(
local_gpe_event_info->dispatch.device.node,
ACPI_NOTIFY_DEVICE_WAKE);

notify_object = local_gpe_event_info->dispatch.device.next;
while (ACPI_SUCCESS(status) && notify_object) {
status = acpi_ev_queue_notify_request(
notify_object->node,
ACPI_NOTIFY_DEVICE_WAKE);
notify_object = notify_object->next;
}

break;

case ACPI_GPE_DISPATCH_METHOD:
Expand Down
42 changes: 33 additions & 9 deletions trunk/drivers/acpi/acpica/evxfgpe.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,9 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
acpi_status status = AE_BAD_PARAMETER;
struct acpi_gpe_event_info *gpe_event_info;
struct acpi_namespace_node *device_node;
struct acpi_gpe_notify_object *notify_object;
acpi_cpu_flags flags;
u8 gpe_dispatch_mask;

ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);

Expand All @@ -221,27 +223,49 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
goto unlock_and_exit;
}

if (wake_device == ACPI_ROOT_OBJECT) {
goto out;
}

/*
* If there is no method or handler for this GPE, then the
* wake_device will be notified whenever this GPE fires (aka
* "implicit notify") Note: The GPE is assumed to be
* level-triggered (for windows compatibility).
*/
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) {
gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK;
if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE
&& gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) {
goto out;
}

/* Validate wake_device is of type Device */
/* Validate wake_device is of type Device */

device_node = ACPI_CAST_PTR(struct acpi_namespace_node,
wake_device);
if (device_node->type != ACPI_TYPE_DEVICE) {
goto unlock_and_exit;
}
device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
if (device_node->type != ACPI_TYPE_DEVICE) {
goto unlock_and_exit;
}

if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) {
gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY |
ACPI_GPE_LEVEL_TRIGGERED);
gpe_event_info->dispatch.device_node = device_node;
gpe_event_info->dispatch.device.node = device_node;
gpe_event_info->dispatch.device.next = NULL;
} else {
/* There are multiple devices to notify implicitly. */

notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object));
if (!notify_object) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
}

notify_object->node = device_node;
notify_object->next = gpe_event_info->dispatch.device.next;
gpe_event_info->dispatch.device.next = notify_object;
}

out:
gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
status = AE_OK;

Expand Down
11 changes: 7 additions & 4 deletions trunk/drivers/acpi/button.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct acpi_button {
struct input_dev *input;
char phys[32]; /* for input device */
unsigned long pushed;
bool wakeup_enabled;
};

static const struct file_operations acpi_button_info_fops = {
Expand Down Expand Up @@ -430,8 +431,10 @@ static int acpi_button_add(struct acpi_device *device)
/* Button's GPE is run-wake GPE */
acpi_enable_gpe(device->wakeup.gpe_device,
device->wakeup.gpe_number);
device->wakeup.run_wake_count++;
device_set_wakeup_enable(&device->dev, true);
if (!device_may_wakeup(&device->dev)) {
device_set_wakeup_enable(&device->dev, true);
button->wakeup_enabled = true;
}
}

printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
Expand All @@ -453,8 +456,8 @@ static int acpi_button_remove(struct acpi_device *device, int type)
if (device->wakeup.flags.valid) {
acpi_disable_gpe(device->wakeup.gpe_device,
device->wakeup.gpe_number);
device->wakeup.run_wake_count--;
device_set_wakeup_enable(&device->dev, false);
if (button->wakeup_enabled)
device_set_wakeup_enable(&device->dev, false);
}

acpi_button_remove_fs(device);
Expand Down
20 changes: 14 additions & 6 deletions trunk/drivers/acpi/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
size_t count, loff_t *ppos)
{
static char *buf;
static int uncopied_bytes;
static u32 max_size;
static u32 uncopied_bytes;

struct acpi_table_header table;
acpi_status status;

Expand All @@ -37,19 +39,24 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
if (copy_from_user(&table, user_buf,
sizeof(struct acpi_table_header)))
return -EFAULT;
uncopied_bytes = table.length;
buf = kzalloc(uncopied_bytes, GFP_KERNEL);
uncopied_bytes = max_size = table.length;
buf = kzalloc(max_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
}

if (uncopied_bytes < count) {
kfree(buf);
if (buf == NULL)
return -EINVAL;

if ((*ppos > max_size) ||
(*ppos + count > max_size) ||
(*ppos + count < count) ||
(count > uncopied_bytes))
return -EINVAL;
}

if (copy_from_user(buf + (*ppos), user_buf, count)) {
kfree(buf);
buf = NULL;
return -EFAULT;
}

Expand All @@ -59,6 +66,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
if (!uncopied_bytes) {
status = acpi_install_method(buf);
kfree(buf);
buf = NULL;
if (ACPI_FAILURE(status))
return -EINVAL;
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
Expand Down
22 changes: 19 additions & 3 deletions trunk/drivers/acpi/nvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct nvs_page {
unsigned int size;
void *kaddr;
void *data;
bool unmap;
struct list_head node;
};

Expand All @@ -44,6 +45,9 @@ int suspend_nvs_register(unsigned long start, unsigned long size)
{
struct nvs_page *entry, *next;

pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n",
start, size);

while (size > 0) {
unsigned int nr_bytes;

Expand Down Expand Up @@ -81,7 +85,13 @@ void suspend_nvs_free(void)
free_page((unsigned long)entry->data);
entry->data = NULL;
if (entry->kaddr) {
iounmap(entry->kaddr);
if (entry->unmap) {
iounmap(entry->kaddr);
entry->unmap = false;
} else {
acpi_os_unmap_memory(entry->kaddr,
entry->size);
}
entry->kaddr = NULL;
}
}
Expand Down Expand Up @@ -115,8 +125,14 @@ int suspend_nvs_save(void)

list_for_each_entry(entry, &nvs_list, node)
if (entry->data) {
entry->kaddr = acpi_os_ioremap(entry->phys_start,
entry->size);
unsigned long phys = entry->phys_start;
unsigned int size = entry->size;

entry->kaddr = acpi_os_get_iomem(phys, size);
if (!entry->kaddr) {
entry->kaddr = acpi_os_ioremap(phys, size);
entry->unmap = !!entry->kaddr;
}
if (!entry->kaddr) {
suspend_nvs_free();
return -ENOMEM;
Expand Down
Loading

0 comments on commit 0438740

Please sign in to comment.