Commit de68aa5a authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-acpi.bkbits.net/linux-acpi

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 7878b8fe 4257def7
......@@ -144,8 +144,8 @@ EXPORT_SYMBOL(acpi_bus_unregister_driver);
#include <linux/pci.h>
extern int acpi_pci_irq_enable(struct pci_dev *dev);
EXPORT_SYMBOL(acpi_pci_irq_enable);
extern int acpi_pci_irq_lookup (int segment, int bus, int device, int pin);
EXPORT_SYMBOL(acpi_pci_irq_lookup);
EXPORT_SYMBOL(acpi_pci_register_driver);
EXPORT_SYMBOL(acpi_pci_unregister_driver);
#endif /*CONFIG_ACPI_PCI */
#ifdef CONFIG_ACPI_EC
......
......@@ -38,6 +38,7 @@
#include <acpi/acpi.h>
#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>
#ifdef CONFIG_ACPI_EFI
#include <linux/efi.h>
......@@ -948,19 +949,22 @@ acpi_os_get_line(char *buffer)
return 0;
}
/*
* We just have to assume we're dealing with valid memory
*/
/* Assumes no unreadable holes inbetween */
BOOLEAN
acpi_os_readable(void *ptr, u32 len)
{
#if defined(__i386__) || defined(__x86_64__)
char tmp;
return !__get_user(tmp, (char *)ptr) && !__get_user(tmp, (char *)ptr + len - 1);
#endif
return 1;
}
BOOLEAN
acpi_os_writable(void *ptr, u32 len)
{
/* could do dummy write (racy) or a kernel page table lookup.
The later may be difficult at early boot when kmap doesn't work yet. */
return 1;
}
......
......@@ -229,22 +229,20 @@ acpi_pci_irq_add_prt (
PCI Interrupt Routing Support
-------------------------------------------------------------------------- */
int
acpi_pci_irq_lookup (
int segment,
int bus,
int device,
int pin)
static int
acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin)
{
struct acpi_prt_entry *entry = NULL;
int segment = pci_domain_nr(bus);
int bus_nr = bus->number;
ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Searching for PRT entry for %02x:%02x:%02x[%c]\n",
segment, bus, device, ('A' + pin)));
segment, bus_nr, device, ('A' + pin)));
entry = acpi_pci_irq_find_prt_entry(segment, bus, device, pin);
entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin);
if (!entry) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n"));
return_VALUE(0);
......@@ -288,7 +286,8 @@ acpi_pci_irq_derive (
while (!irq && bridge->bus->self) {
pin = (pin + PCI_SLOT(bridge->devfn)) % 4;
bridge = bridge->bus->self;
irq = acpi_pci_irq_lookup(0, bridge->bus->number, PCI_SLOT(bridge->devfn), pin);
irq = acpi_pci_irq_lookup(bridge->bus,
PCI_SLOT(bridge->devfn), pin);
}
if (!irq) {
......@@ -331,7 +330,7 @@ acpi_pci_irq_enable (
* First we check the PCI IRQ routing table (PRT) for an IRQ. PRT
* values override any BIOS-assigned IRQs set during boot.
*/
irq = acpi_pci_irq_lookup(0, dev->bus->number, PCI_SLOT(dev->devfn), pin);
irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin);
/*
* If no PRT entry was found, we'll try to derive an IRQ from the
......
......@@ -59,17 +59,63 @@ static struct acpi_driver acpi_pci_root_driver = {
},
};
struct acpi_pci_root {
struct acpi_pci_root {
struct list_head node;
acpi_handle handle;
struct acpi_pci_id id;
struct pci_bus *bus;
acpi_handle handle;
struct acpi_pci_id id;
struct pci_bus *bus;
u64 mem_tra;
u64 io_tra;
};
};
struct list_head acpi_pci_roots;
static struct acpi_pci_driver *sub_driver;
int acpi_pci_register_driver(struct acpi_pci_driver *driver)
{
int n = 0;
struct list_head *entry;
struct acpi_pci_driver **pptr = &sub_driver;
while (*pptr)
pptr = &(*pptr)->next;
*pptr = driver;
if (!driver->add)
return 0;
list_for_each(entry, &acpi_pci_roots) {
struct acpi_pci_root *root;
root = list_entry(entry, struct acpi_pci_root, node);
driver->add(root->handle);
n++;
}
return n;
}
void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
{
struct list_head *entry;
struct acpi_pci_driver **pptr = &sub_driver;
while (*pptr) {
if (*pptr != driver)
continue;
*pptr = (*pptr)->next;
break;
}
if (!driver->remove)
return;
list_for_each(entry, &acpi_pci_roots) {
struct acpi_pci_root *root;
root = list_entry(entry, struct acpi_pci_root, node);
driver->remove(root->handle);
}
}
void
acpi_pci_get_translations (
......
......@@ -214,6 +214,10 @@ acpi_suspend (
{
acpi_status status;
/* Suspend is hard to get right on SMP. */
if (num_online_cpus() != 1)
return AE_ERROR;
/* get out if state is invalid */
if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
return AE_ERROR;
......@@ -226,7 +230,10 @@ acpi_suspend (
* TBD: S1 can be done without device_suspend. Make a CONFIG_XX
* to handle however when S1 failed without device_suspend.
*/
freeze_processes(); /* device_suspend needs processes to be stopped */
if (freeze_processes()) {
thaw_processes();
return AE_ERROR; /* device_suspend needs processes to be stopped */
}
/* do we have a wakeup address for S2 and S3? */
/* Here, we support only S4BIOS, those we set the wakeup address */
......
......@@ -56,7 +56,7 @@ static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
[ACPI_SRAT] = "SRAT",
[ACPI_SSDT] = "SSDT",
[ACPI_SPMI] = "SPMI",
[ACPI_HPET] = "HPET"
[ACPI_HPET] = "HPET",
};
/* System Description Table (RSDT/XSDT) */
......
......@@ -430,7 +430,7 @@ acpi_thermal_call_usermode (
ACPI_FUNCTION_TRACE("acpi_thermal_call_usermode");
if (!path)
return_VALUE(-EINVAL);;
return_VALUE(-EINVAL);
argv[0] = path;
......
......@@ -401,6 +401,15 @@ struct pci_dev;
int acpi_pci_irq_enable (struct pci_dev *dev);
int acpi_pci_irq_init (void);
struct acpi_pci_driver {
struct acpi_pci_driver *next;
int (*add)(acpi_handle *handle);
void (*remove)(acpi_handle *handle);
};
int acpi_pci_register_driver(struct acpi_pci_driver *driver);
void acpi_pci_unregister_driver(struct acpi_pci_driver *driver);
#endif /*CONFIG_ACPI_PCI*/
#ifdef CONFIG_ACPI_EC
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment