You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branches 'acerhdf', 'acpi-pci-bind', 'bjorn-pci-root', 'bugzilla-12904', 'bugzilla-13121', 'bugzilla-13396', 'bugzilla-13533', 'bugzilla-13612', 'c3_lock', 'hid-cleanups', 'misc-2.6.31', 'pdc-leak-fix', 'pnpacpi', 'power_nocheck', 'thinkpad_acpi', 'video' and 'wmi' into release
This commit is contained in:
@@ -229,14 +229,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
to assume that this machine's pmtimer latches its value
|
||||
and always returns good values.
|
||||
|
||||
acpi.power_nocheck= [HW,ACPI]
|
||||
Format: 1/0 enable/disable the check of power state.
|
||||
On some bogus BIOS the _PSC object/_STA object of
|
||||
power resource can't return the correct device power
|
||||
state. In such case it is unneccessary to check its
|
||||
power state again in power transition.
|
||||
1 : disable the power state check
|
||||
|
||||
acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode
|
||||
Format: { level | edge | high | low }
|
||||
|
||||
|
||||
@@ -920,7 +920,7 @@ The available commands are:
|
||||
echo '<LED number> off' >/proc/acpi/ibm/led
|
||||
echo '<LED number> blink' >/proc/acpi/ibm/led
|
||||
|
||||
The <LED number> range is 0 to 7. The set of LEDs that can be
|
||||
The <LED number> range is 0 to 15. The set of LEDs that can be
|
||||
controlled varies from model to model. Here is the common ThinkPad
|
||||
mapping:
|
||||
|
||||
@@ -932,6 +932,11 @@ mapping:
|
||||
5 - UltraBase battery slot
|
||||
6 - (unknown)
|
||||
7 - standby
|
||||
8 - dock status 1
|
||||
9 - dock status 2
|
||||
10, 11 - (unknown)
|
||||
12 - thinkvantage
|
||||
13, 14, 15 - (unknown)
|
||||
|
||||
All of the above can be turned on and off and can be made to blink.
|
||||
|
||||
@@ -940,10 +945,12 @@ sysfs notes:
|
||||
The ThinkPad LED sysfs interface is described in detail by the LED class
|
||||
documentation, in Documentation/leds-class.txt.
|
||||
|
||||
The leds are named (in LED ID order, from 0 to 7):
|
||||
The LEDs are named (in LED ID order, from 0 to 12):
|
||||
"tpacpi::power", "tpacpi:orange:batt", "tpacpi:green:batt",
|
||||
"tpacpi::dock_active", "tpacpi::bay_active", "tpacpi::dock_batt",
|
||||
"tpacpi::unknown_led", "tpacpi::standby".
|
||||
"tpacpi::unknown_led", "tpacpi::standby", "tpacpi::dock_status1",
|
||||
"tpacpi::dock_status2", "tpacpi::unknown_led2", "tpacpi::unknown_led3",
|
||||
"tpacpi::thinkvantage".
|
||||
|
||||
Due to limitations in the sysfs LED class, if the status of the LED
|
||||
indicators cannot be read due to an error, thinkpad-acpi will report it as
|
||||
@@ -958,6 +965,12 @@ ThinkPad indicator LED should blink in hardware accelerated mode, use the
|
||||
"timer" trigger, and leave the delay_on and delay_off parameters set to
|
||||
zero (to request hardware acceleration autodetection).
|
||||
|
||||
LEDs that are known not to exist in a given ThinkPad model are not
|
||||
made available through the sysfs interface. If you have a dock and you
|
||||
notice there are LEDs listed for your ThinkPad that do not exist (and
|
||||
are not in the dock), or if you notice that there are missing LEDs,
|
||||
a report to ibm-acpi-devel@lists.sourceforge.net is appreciated.
|
||||
|
||||
|
||||
ACPI sounds -- /proc/acpi/ibm/beep
|
||||
----------------------------------
|
||||
@@ -1156,17 +1169,19 @@ may not be distinct. Later Lenovo models that implement the ACPI
|
||||
display backlight brightness control methods have 16 levels, ranging
|
||||
from 0 to 15.
|
||||
|
||||
There are two interfaces to the firmware for direct brightness control,
|
||||
EC and UCMS (or CMOS). To select which one should be used, use the
|
||||
brightness_mode module parameter: brightness_mode=1 selects EC mode,
|
||||
brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC
|
||||
mode with NVRAM backing (so that brightness changes are remembered
|
||||
across shutdown/reboot).
|
||||
For IBM ThinkPads, there are two interfaces to the firmware for direct
|
||||
brightness control, EC and UCMS (or CMOS). To select which one should be
|
||||
used, use the brightness_mode module parameter: brightness_mode=1 selects
|
||||
EC mode, brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC
|
||||
mode with NVRAM backing (so that brightness changes are remembered across
|
||||
shutdown/reboot).
|
||||
|
||||
The driver tries to select which interface to use from a table of
|
||||
defaults for each ThinkPad model. If it makes a wrong choice, please
|
||||
report this as a bug, so that we can fix it.
|
||||
|
||||
Lenovo ThinkPads only support brightness_mode=2 (UCMS).
|
||||
|
||||
When display backlight brightness controls are available through the
|
||||
standard ACPI interface, it is best to use it instead of this direct
|
||||
ThinkPad-specific interface. The driver will disable its native
|
||||
@@ -1254,7 +1269,7 @@ Fan control and monitoring: fan speed, fan enable/disable
|
||||
|
||||
procfs: /proc/acpi/ibm/fan
|
||||
sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1,
|
||||
pwm1_enable
|
||||
pwm1_enable, fan2_input
|
||||
sysfs hwmon driver attributes: fan_watchdog
|
||||
|
||||
NOTE NOTE NOTE: fan control operations are disabled by default for
|
||||
@@ -1267,6 +1282,9 @@ from the hardware registers of the embedded controller. This is known
|
||||
to work on later R, T, X and Z series ThinkPads but may show a bogus
|
||||
value on other models.
|
||||
|
||||
Some Lenovo ThinkPads support a secondary fan. This fan cannot be
|
||||
controlled separately, it shares the main fan control.
|
||||
|
||||
Fan levels:
|
||||
|
||||
Most ThinkPad fans work in "levels" at the firmware interface. Level 0
|
||||
@@ -1397,6 +1415,11 @@ hwmon device attribute fan1_input:
|
||||
which can take up to two minutes. May return rubbish on older
|
||||
ThinkPads.
|
||||
|
||||
hwmon device attribute fan2_input:
|
||||
Fan tachometer reading, in RPM, for the secondary fan.
|
||||
Available only on some ThinkPads. If the secondary fan is
|
||||
not installed, will always read 0.
|
||||
|
||||
hwmon driver attribute fan_watchdog:
|
||||
Fan safety watchdog timer interval, in seconds. Minimum is
|
||||
1 second, maximum is 120 seconds. 0 disables the watchdog.
|
||||
@@ -1555,3 +1578,7 @@ Sysfs interface changelog:
|
||||
0x020300: hotkey enable/disable support removed, attributes
|
||||
hotkey_bios_enabled and hotkey_enable deprecated and
|
||||
marked for removal.
|
||||
|
||||
0x020400: Marker for 16 LEDs support. Also, LEDs that are known
|
||||
to not exist in a given model are not registered with
|
||||
the LED sysfs class anymore.
|
||||
|
||||
@@ -230,6 +230,13 @@ L: linux-acenic@sunsite.dk
|
||||
S: Maintained
|
||||
F: drivers/net/acenic*
|
||||
|
||||
ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER
|
||||
P: Peter Feuerer
|
||||
M: peter@piie.net
|
||||
W: http://piie.net/?section=acerhdf
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/acerhdf.c
|
||||
|
||||
ACER WMI LAPTOP EXTRAS
|
||||
P: Carlos Corbacho
|
||||
M: carlos@strangeworlds.co.uk
|
||||
|
||||
@@ -71,3 +71,15 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
|
||||
|
||||
void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr)
|
||||
{
|
||||
if (pr->pdc) {
|
||||
kfree(pr->pdc->pointer->buffer.pointer);
|
||||
kfree(pr->pdc->pointer);
|
||||
kfree(pr->pdc);
|
||||
pr->pdc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(arch_acpi_processor_cleanup_pdc);
|
||||
|
||||
@@ -144,6 +144,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
|
||||
|
||||
#else /* !CONFIG_ACPI */
|
||||
|
||||
#define acpi_disabled 1
|
||||
#define acpi_lapic 0
|
||||
#define acpi_ioapic 0
|
||||
static inline void acpi_noirq_set(void) { }
|
||||
|
||||
@@ -121,6 +121,9 @@ extern int __init pcibios_init(void);
|
||||
extern int __init pci_mmcfg_arch_init(void);
|
||||
extern void __init pci_mmcfg_arch_free(void);
|
||||
|
||||
extern struct acpi_mcfg_allocation *pci_mmcfg_config;
|
||||
extern int pci_mmcfg_config_num;
|
||||
|
||||
/*
|
||||
* AMD Fam10h CPUs are buggy, and cannot access MMIO config space
|
||||
* on their northbrige except through the * %eax register. As such, you MUST
|
||||
|
||||
@@ -44,11 +44,7 @@
|
||||
|
||||
static int __initdata acpi_force = 0;
|
||||
u32 acpi_rsdt_forced;
|
||||
#ifdef CONFIG_ACPI
|
||||
int acpi_disabled = 0;
|
||||
#else
|
||||
int acpi_disabled = 1;
|
||||
#endif
|
||||
int acpi_disabled;
|
||||
EXPORT_SYMBOL(acpi_disabled);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
@@ -122,72 +118,6 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
|
||||
early_iounmap(map, size);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_MMCONFIG
|
||||
|
||||
static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
|
||||
|
||||
/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
|
||||
struct acpi_mcfg_allocation *pci_mmcfg_config;
|
||||
int pci_mmcfg_config_num;
|
||||
|
||||
static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
|
||||
{
|
||||
if (!strcmp(mcfg->header.oem_id, "SGI"))
|
||||
acpi_mcfg_64bit_base_addr = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init acpi_parse_mcfg(struct acpi_table_header *header)
|
||||
{
|
||||
struct acpi_table_mcfg *mcfg;
|
||||
unsigned long i;
|
||||
int config_size;
|
||||
|
||||
if (!header)
|
||||
return -EINVAL;
|
||||
|
||||
mcfg = (struct acpi_table_mcfg *)header;
|
||||
|
||||
/* how many config structures do we have */
|
||||
pci_mmcfg_config_num = 0;
|
||||
i = header->length - sizeof(struct acpi_table_mcfg);
|
||||
while (i >= sizeof(struct acpi_mcfg_allocation)) {
|
||||
++pci_mmcfg_config_num;
|
||||
i -= sizeof(struct acpi_mcfg_allocation);
|
||||
};
|
||||
if (pci_mmcfg_config_num == 0) {
|
||||
printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
|
||||
pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
|
||||
if (!pci_mmcfg_config) {
|
||||
printk(KERN_WARNING PREFIX
|
||||
"No memory for MCFG config tables\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(pci_mmcfg_config, &mcfg[1], config_size);
|
||||
|
||||
acpi_mcfg_oem_check(mcfg);
|
||||
|
||||
for (i = 0; i < pci_mmcfg_config_num; ++i) {
|
||||
if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) &&
|
||||
!acpi_mcfg_64bit_base_addr) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"MMCONFIG not in low 4GB of memory\n");
|
||||
kfree(pci_mmcfg_config);
|
||||
pci_mmcfg_config_num = 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PCI_MMCONFIG */
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
static int __init acpi_parse_madt(struct acpi_table_header *table)
|
||||
{
|
||||
@@ -1517,14 +1447,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = force_acpi_ht,
|
||||
.ident = "ASUS P4B266",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = force_acpi_ht,
|
||||
.ident = "ASUS P2B-DS",
|
||||
|
||||
@@ -34,12 +34,22 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
|
||||
flags->bm_check = 1;
|
||||
else if (c->x86_vendor == X86_VENDOR_INTEL) {
|
||||
/*
|
||||
* Today all CPUs that support C3 share cache.
|
||||
* TBD: This needs to look at cache shared map, once
|
||||
* multi-core detection patch makes to the base.
|
||||
* Today all MP CPUs that support C3 share cache.
|
||||
* And caches should not be flushed by software while
|
||||
* entering C3 type state.
|
||||
*/
|
||||
flags->bm_check = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* On all recent Intel platforms, ARB_DISABLE is a nop.
|
||||
* So, set bm_control to zero to indicate that ARB_DISABLE
|
||||
* is not required while entering C3 type state on
|
||||
* P4, Core and beyond CPUs
|
||||
*/
|
||||
if (c->x86_vendor == X86_VENDOR_INTEL &&
|
||||
(c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 14)))
|
||||
flags->bm_control = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_processor_power_init_bm_check);
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize _PDC data based on the CPU vendor */
|
||||
void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
|
||||
{
|
||||
@@ -85,3 +86,15 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
|
||||
|
||||
void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr)
|
||||
{
|
||||
if (pr->pdc) {
|
||||
kfree(pr->pdc->pointer->buffer.pointer);
|
||||
kfree(pr->pdc->pointer);
|
||||
kfree(pr->pdc);
|
||||
pr->pdc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(arch_acpi_processor_cleanup_pdc);
|
||||
|
||||
@@ -523,6 +523,69 @@ reject:
|
||||
|
||||
static int __initdata known_bridge;
|
||||
|
||||
static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
|
||||
|
||||
/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
|
||||
struct acpi_mcfg_allocation *pci_mmcfg_config;
|
||||
int pci_mmcfg_config_num;
|
||||
|
||||
static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
|
||||
{
|
||||
if (!strcmp(mcfg->header.oem_id, "SGI"))
|
||||
acpi_mcfg_64bit_base_addr = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init pci_parse_mcfg(struct acpi_table_header *header)
|
||||
{
|
||||
struct acpi_table_mcfg *mcfg;
|
||||
unsigned long i;
|
||||
int config_size;
|
||||
|
||||
if (!header)
|
||||
return -EINVAL;
|
||||
|
||||
mcfg = (struct acpi_table_mcfg *)header;
|
||||
|
||||
/* how many config structures do we have */
|
||||
pci_mmcfg_config_num = 0;
|
||||
i = header->length - sizeof(struct acpi_table_mcfg);
|
||||
while (i >= sizeof(struct acpi_mcfg_allocation)) {
|
||||
++pci_mmcfg_config_num;
|
||||
i -= sizeof(struct acpi_mcfg_allocation);
|
||||
};
|
||||
if (pci_mmcfg_config_num == 0) {
|
||||
printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
|
||||
pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
|
||||
if (!pci_mmcfg_config) {
|
||||
printk(KERN_WARNING PREFIX
|
||||
"No memory for MCFG config tables\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(pci_mmcfg_config, &mcfg[1], config_size);
|
||||
|
||||
acpi_mcfg_oem_check(mcfg);
|
||||
|
||||
for (i = 0; i < pci_mmcfg_config_num; ++i) {
|
||||
if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) &&
|
||||
!acpi_mcfg_64bit_base_addr) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"MMCONFIG not in low 4GB of memory\n");
|
||||
kfree(pci_mmcfg_config);
|
||||
pci_mmcfg_config_num = 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init __pci_mmcfg_init(int early)
|
||||
{
|
||||
/* MMCONFIG disabled */
|
||||
@@ -543,7 +606,7 @@ static void __init __pci_mmcfg_init(int early)
|
||||
}
|
||||
|
||||
if (!known_bridge)
|
||||
acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
|
||||
acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
|
||||
|
||||
pci_mmcfg_reject_broken(early);
|
||||
|
||||
|
||||
@@ -192,6 +192,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = dmi_disable_osi_vista,
|
||||
.ident = "Sony VGN-NS10J_S",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = dmi_disable_osi_vista,
|
||||
.ident = "Sony VGN-SR290J",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
|
||||
|
||||
@@ -140,46 +140,6 @@ struct device *acpi_get_physical_device(acpi_handle handle)
|
||||
|
||||
EXPORT_SYMBOL(acpi_get_physical_device);
|
||||
|
||||
/* ToDo: When a PCI bridge is found, return the PCI device behind the bridge
|
||||
* This should work in general, but did not on a Lenovo T61 for the
|
||||
* graphics card. But this must be fixed when the PCI device is
|
||||
* bound and the kernel device struct is attached to the acpi device
|
||||
* Note: A success call will increase reference count by one
|
||||
* Do call put_device(dev) on the returned device then
|
||||
*/
|
||||
struct device *acpi_get_physical_pci_device(acpi_handle handle)
|
||||
{
|
||||
struct device *dev;
|
||||
long long device_id;
|
||||
acpi_status status;
|
||||
|
||||
status =
|
||||
acpi_evaluate_integer(handle, "_ADR", NULL, &device_id);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
return NULL;
|
||||
|
||||
/* We need to attempt to determine whether the _ADR refers to a
|
||||
PCI device or not. There's no terribly good way to do this,
|
||||
so the best we can hope for is to assume that there'll never
|
||||
be a device in the host bridge */
|
||||
if (device_id >= 0x10000) {
|
||||
/* It looks like a PCI device. Does it exist? */
|
||||
dev = acpi_get_physical_device(handle);
|
||||
} else {
|
||||
/* It doesn't look like a PCI device. Does its parent
|
||||
exist? */
|
||||
acpi_handle phandle;
|
||||
if (acpi_get_parent(handle, &phandle))
|
||||
return NULL;
|
||||
dev = acpi_get_physical_device(phandle);
|
||||
}
|
||||
if (!dev)
|
||||
return NULL;
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_get_physical_pci_device);
|
||||
|
||||
static int acpi_bind_one(struct device *dev, acpi_handle handle)
|
||||
{
|
||||
struct acpi_device *acpi_dev;
|
||||
|
||||
+16
-9
@@ -79,6 +79,7 @@ static acpi_osd_handler acpi_irq_handler;
|
||||
static void *acpi_irq_context;
|
||||
static struct workqueue_struct *kacpid_wq;
|
||||
static struct workqueue_struct *kacpi_notify_wq;
|
||||
static struct workqueue_struct *kacpi_hotplug_wq;
|
||||
|
||||
struct acpi_res_list {
|
||||
resource_size_t start;
|
||||
@@ -192,8 +193,10 @@ acpi_status acpi_os_initialize1(void)
|
||||
{
|
||||
kacpid_wq = create_singlethread_workqueue("kacpid");
|
||||
kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
|
||||
kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug");
|
||||
BUG_ON(!kacpid_wq);
|
||||
BUG_ON(!kacpi_notify_wq);
|
||||
BUG_ON(!kacpi_hotplug_wq);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
@@ -206,6 +209,7 @@ acpi_status acpi_os_terminate(void)
|
||||
|
||||
destroy_workqueue(kacpid_wq);
|
||||
destroy_workqueue(kacpi_notify_wq);
|
||||
destroy_workqueue(kacpi_hotplug_wq);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
@@ -716,6 +720,7 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_os_dpc *dpc;
|
||||
struct workqueue_struct *queue;
|
||||
work_func_t func;
|
||||
int ret;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"Scheduling function [%p(%p)] for deferred execution.\n",
|
||||
@@ -740,15 +745,17 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
|
||||
dpc->function = function;
|
||||
dpc->context = context;
|
||||
|
||||
if (!hp) {
|
||||
INIT_WORK(&dpc->work, acpi_os_execute_deferred);
|
||||
queue = (type == OSL_NOTIFY_HANDLER) ?
|
||||
kacpi_notify_wq : kacpid_wq;
|
||||
ret = queue_work(queue, &dpc->work);
|
||||
} else {
|
||||
INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred);
|
||||
ret = schedule_work(&dpc->work);
|
||||
}
|
||||
/*
|
||||
* We can't run hotplug code in keventd_wq/kacpid_wq/kacpid_notify_wq
|
||||
* because the hotplug code may call driver .remove() functions,
|
||||
* which invoke flush_scheduled_work/acpi_os_wait_events_complete
|
||||
* to flush these workqueues.
|
||||
*/
|
||||
queue = hp ? kacpi_hotplug_wq :
|
||||
(type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
|
||||
func = hp ? acpi_os_execute_hp_deferred : acpi_os_execute_deferred;
|
||||
INIT_WORK(&dpc->work, func);
|
||||
ret = queue_work(queue, &dpc->work);
|
||||
|
||||
if (!ret) {
|
||||
printk(KERN_ERR PREFIX
|
||||
|
||||
+45
-284
@@ -24,12 +24,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
@@ -38,310 +33,76 @@
|
||||
#define _COMPONENT ACPI_PCI_COMPONENT
|
||||
ACPI_MODULE_NAME("pci_bind");
|
||||
|
||||
struct acpi_pci_data {
|
||||
struct acpi_pci_id id;
|
||||
static int acpi_pci_unbind(struct acpi_device *device)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
dev = acpi_get_pci_dev(device->handle);
|
||||
if (!dev || !dev->subordinate)
|
||||
goto out;
|
||||
|
||||
acpi_pci_irq_del_prt(dev->subordinate);
|
||||
|
||||
device->ops.bind = NULL;
|
||||
device->ops.unbind = NULL;
|
||||
|
||||
out:
|
||||
pci_dev_put(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_pci_bind(struct acpi_device *device)
|
||||
{
|
||||
acpi_status status;
|
||||
acpi_handle handle;
|
||||
struct pci_bus *bus;
|
||||
struct pci_dev *dev;
|
||||
};
|
||||
|
||||
static int acpi_pci_unbind(struct acpi_device *device);
|
||||
|
||||
static void acpi_pci_data_handler(acpi_handle handle, u32 function,
|
||||
void *context)
|
||||
{
|
||||
|
||||
/* TBD: Anything we need to do here? */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_get_pci_id
|
||||
* ------------------
|
||||
* This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
|
||||
* to resolve PCI information for ACPI-PCI devices defined in the namespace.
|
||||
* This typically occurs when resolving PCI operation region information.
|
||||
*/
|
||||
acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id)
|
||||
{
|
||||
int result = 0;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_device *device = NULL;
|
||||
struct acpi_pci_data *data = NULL;
|
||||
|
||||
|
||||
if (!id)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
result = acpi_bus_get_device(handle, &device);
|
||||
if (result) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"Invalid ACPI Bus context for device %s\n",
|
||||
acpi_device_bid(device));
|
||||
return AE_NOT_EXIST;
|
||||
}
|
||||
|
||||
status = acpi_get_data(handle, acpi_pci_data_handler, (void **)&data);
|
||||
if (ACPI_FAILURE(status) || !data) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Invalid ACPI-PCI context for device %s",
|
||||
acpi_device_bid(device)));
|
||||
return status;
|
||||
}
|
||||
|
||||
*id = data->id;
|
||||
dev = acpi_get_pci_dev(device->handle);
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
id->segment = data->id.segment;
|
||||
id->bus = data->id.bus;
|
||||
id->device = data->id.device;
|
||||
id->function = data->id.function;
|
||||
* Install the 'bind' function to facilitate callbacks for
|
||||
* children of the P2P bridge.
|
||||
*/
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Device %s has PCI address %04x:%02x:%02x.%d\n",
|
||||
acpi_device_bid(device), id->segment, id->bus,
|
||||
id->device, id->function));
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_get_pci_id);
|
||||
|
||||
int acpi_pci_bind(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
acpi_status status;
|
||||
struct acpi_pci_data *data;
|
||||
struct acpi_pci_data *pdata;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
acpi_handle handle;
|
||||
|
||||
if (!device || !device->parent)
|
||||
return -EINVAL;
|
||||
|
||||
data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
kfree(data);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n",
|
||||
(char *)buffer.pointer));
|
||||
|
||||
/*
|
||||
* Segment & Bus
|
||||
* -------------
|
||||
* These are obtained via the parent device's ACPI-PCI context.
|
||||
*/
|
||||
status = acpi_get_data(device->parent->handle, acpi_pci_data_handler,
|
||||
(void **)&pdata);
|
||||
if (ACPI_FAILURE(status) || !pdata || !pdata->bus) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Invalid ACPI-PCI context for parent device %s",
|
||||
acpi_device_bid(device->parent)));
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
data->id.segment = pdata->id.segment;
|
||||
data->id.bus = pdata->bus->number;
|
||||
|
||||
/*
|
||||
* Device & Function
|
||||
* -----------------
|
||||
* These are simply obtained from the device's _ADR method. Note
|
||||
* that a value of zero is valid.
|
||||
*/
|
||||
data->id.device = device->pnp.bus_address >> 16;
|
||||
data->id.function = device->pnp.bus_address & 0xFFFF;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %04x:%02x:%02x.%d\n",
|
||||
data->id.segment, data->id.bus, data->id.device,
|
||||
data->id.function));
|
||||
|
||||
/*
|
||||
* TBD: Support slot devices (e.g. function=0xFFFF).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Locate PCI Device
|
||||
* -----------------
|
||||
* Locate matching device in PCI namespace. If it doesn't exist
|
||||
* this typically means that the device isn't currently inserted
|
||||
* (e.g. docking station, port replicator, etc.).
|
||||
*/
|
||||
data->dev = pci_get_slot(pdata->bus,
|
||||
PCI_DEVFN(data->id.device, data->id.function));
|
||||
if (!data->dev) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Device %04x:%02x:%02x.%d not present in PCI namespace\n",
|
||||
data->id.segment, data->id.bus,
|
||||
data->id.device, data->id.function));
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
if (!data->dev->bus) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"Device %04x:%02x:%02x.%d has invalid 'bus' field\n",
|
||||
data->id.segment, data->id.bus,
|
||||
data->id.device, data->id.function);
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* PCI Bridge?
|
||||
* -----------
|
||||
* If so, set the 'bus' field and install the 'bind' function to
|
||||
* facilitate callbacks for all of its children.
|
||||
*/
|
||||
if (data->dev->subordinate) {
|
||||
if (dev->subordinate) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Device %04x:%02x:%02x.%d is a PCI bridge\n",
|
||||
data->id.segment, data->id.bus,
|
||||
data->id.device, data->id.function));
|
||||
data->bus = data->dev->subordinate;
|
||||
pci_domain_nr(dev->bus), dev->bus->number,
|
||||
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)));
|
||||
device->ops.bind = acpi_pci_bind;
|
||||
device->ops.unbind = acpi_pci_unbind;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach ACPI-PCI Context
|
||||
* -----------------------
|
||||
* Thus binding the ACPI and PCI devices.
|
||||
*/
|
||||
status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Unable to attach ACPI-PCI context to device %s",
|
||||
acpi_device_bid(device)));
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* PCI Routing Table
|
||||
* -----------------
|
||||
* Evaluate and parse _PRT, if exists. This code is independent of
|
||||
* PCI bridges (above) to allow parsing of _PRT objects within the
|
||||
* scope of non-bridge devices. Note that _PRTs within the scope of
|
||||
* a PCI bridge assume the bridge's subordinate bus number.
|
||||
* Evaluate and parse _PRT, if exists. This code allows parsing of
|
||||
* _PRT objects within the scope of non-bridge devices. Note that
|
||||
* _PRTs within the scope of a PCI bridge assume the bridge's
|
||||
* subordinate bus number.
|
||||
*
|
||||
* TBD: Can _PRTs exist within the scope of non-bridge PCI devices?
|
||||
*/
|
||||
status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
if (data->bus) /* PCI-PCI bridge */
|
||||
acpi_pci_irq_add_prt(device->handle, data->id.segment,
|
||||
data->bus->number);
|
||||
else /* non-bridge PCI device */
|
||||
acpi_pci_irq_add_prt(device->handle, data->id.segment,
|
||||
data->id.bus);
|
||||
}
|
||||
|
||||
end:
|
||||
kfree(buffer.pointer);
|
||||
if (result) {
|
||||
pci_dev_put(data->dev);
|
||||
kfree(data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_pci_unbind(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
acpi_status status;
|
||||
struct acpi_pci_data *data;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
||||
|
||||
if (!device || !device->parent)
|
||||
return -EINVAL;
|
||||
|
||||
status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
goto out;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n",
|
||||
(char *) buffer.pointer));
|
||||
kfree(buffer.pointer);
|
||||
if (dev->subordinate)
|
||||
bus = dev->subordinate;
|
||||
else
|
||||
bus = dev->bus;
|
||||
|
||||
status =
|
||||
acpi_get_data(device->handle, acpi_pci_data_handler,
|
||||
(void **)&data);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
acpi_pci_irq_add_prt(device->handle, bus);
|
||||
|
||||
status = acpi_detach_data(device->handle, acpi_pci_data_handler);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Unable to detach data from device %s",
|
||||
acpi_device_bid(device)));
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
if (data->dev->subordinate) {
|
||||
acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
|
||||
}
|
||||
pci_dev_put(data->dev);
|
||||
kfree(data);
|
||||
|
||||
end:
|
||||
return result;
|
||||
out:
|
||||
pci_dev_put(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
acpi_pci_bind_root(struct acpi_device *device,
|
||||
struct acpi_pci_id *id, struct pci_bus *bus)
|
||||
int acpi_pci_bind_root(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
acpi_status status;
|
||||
struct acpi_pci_data *data = NULL;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
||||
if (!device || !id || !bus) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->id = *id;
|
||||
data->bus = bus;
|
||||
device->ops.bind = acpi_pci_bind;
|
||||
device->ops.unbind = acpi_pci_unbind;
|
||||
|
||||
status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
kfree (data);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to "
|
||||
"%04x:%02x\n", (char *)buffer.pointer,
|
||||
id->segment, id->bus));
|
||||
|
||||
status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Unable to attach ACPI-PCI context to device %s",
|
||||
(char *)buffer.pointer));
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
kfree(buffer.pointer);
|
||||
if (result != 0)
|
||||
kfree(data);
|
||||
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ static void do_prt_fixups(struct acpi_prt_entry *entry,
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus,
|
||||
static int acpi_pci_irq_add_entry(acpi_handle handle, struct pci_bus *bus,
|
||||
struct acpi_pci_routing_table *prt)
|
||||
{
|
||||
struct acpi_prt_entry *entry;
|
||||
@@ -196,8 +196,8 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus,
|
||||
* 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert
|
||||
* it here.
|
||||
*/
|
||||
entry->id.segment = segment;
|
||||
entry->id.bus = bus;
|
||||
entry->id.segment = pci_domain_nr(bus);
|
||||
entry->id.bus = bus->number;
|
||||
entry->id.device = (prt->address >> 16) & 0xFFFF;
|
||||
entry->pin = prt->pin + 1;
|
||||
|
||||
@@ -242,7 +242,7 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
|
||||
int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
@@ -271,7 +271,7 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
|
||||
|
||||
entry = buffer.pointer;
|
||||
while (entry && (entry->length > 0)) {
|
||||
acpi_pci_irq_add_entry(handle, segment, bus, entry);
|
||||
acpi_pci_irq_add_entry(handle, bus, entry);
|
||||
entry = (struct acpi_pci_routing_table *)
|
||||
((unsigned long)entry + entry->length);
|
||||
}
|
||||
@@ -280,16 +280,17 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void acpi_pci_irq_del_prt(int segment, int bus)
|
||||
void acpi_pci_irq_del_prt(struct pci_bus *bus)
|
||||
{
|
||||
struct acpi_prt_entry *entry, *tmp;
|
||||
|
||||
printk(KERN_DEBUG
|
||||
"ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n",
|
||||
segment, bus);
|
||||
pci_domain_nr(bus), bus->number);
|
||||
spin_lock(&acpi_prt_lock);
|
||||
list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) {
|
||||
if (segment == entry->id.segment && bus == entry->id.bus) {
|
||||
if (pci_domain_nr(bus) == entry->id.segment
|
||||
&& bus->number == entry->id.bus) {
|
||||
list_del(&entry->list);
|
||||
kfree(entry);
|
||||
}
|
||||
|
||||
+164
-133
@@ -63,9 +63,10 @@ static struct acpi_driver acpi_pci_root_driver = {
|
||||
|
||||
struct acpi_pci_root {
|
||||
struct list_head node;
|
||||
struct acpi_device * device;
|
||||
struct acpi_pci_id id;
|
||||
struct acpi_device *device;
|
||||
struct pci_bus *bus;
|
||||
u16 segment;
|
||||
u8 bus_nr;
|
||||
|
||||
u32 osc_support_set; /* _OSC state of support bits */
|
||||
u32 osc_control_set; /* _OSC state of control bits */
|
||||
@@ -82,7 +83,7 @@ static DEFINE_MUTEX(osc_lock);
|
||||
int acpi_pci_register_driver(struct acpi_pci_driver *driver)
|
||||
{
|
||||
int n = 0;
|
||||
struct list_head *entry;
|
||||
struct acpi_pci_root *root;
|
||||
|
||||
struct acpi_pci_driver **pptr = &sub_driver;
|
||||
while (*pptr)
|
||||
@@ -92,9 +93,7 @@ int acpi_pci_register_driver(struct acpi_pci_driver *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);
|
||||
list_for_each_entry(root, &acpi_pci_roots, node) {
|
||||
driver->add(root->device->handle);
|
||||
n++;
|
||||
}
|
||||
@@ -106,7 +105,7 @@ EXPORT_SYMBOL(acpi_pci_register_driver);
|
||||
|
||||
void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
|
||||
{
|
||||
struct list_head *entry;
|
||||
struct acpi_pci_root *root;
|
||||
|
||||
struct acpi_pci_driver **pptr = &sub_driver;
|
||||
while (*pptr) {
|
||||
@@ -120,28 +119,48 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
|
||||
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);
|
||||
list_for_each_entry(root, &acpi_pci_roots, node)
|
||||
driver->remove(root->device->handle);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_pci_unregister_driver);
|
||||
|
||||
acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
|
||||
{
|
||||
struct acpi_pci_root *tmp;
|
||||
struct acpi_pci_root *root;
|
||||
|
||||
list_for_each_entry(tmp, &acpi_pci_roots, node) {
|
||||
if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus))
|
||||
return tmp->device->handle;
|
||||
}
|
||||
list_for_each_entry(root, &acpi_pci_roots, node)
|
||||
if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus))
|
||||
return root->device->handle;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
|
||||
|
||||
/**
|
||||
* acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
|
||||
* @handle - the ACPI CA node in question.
|
||||
*
|
||||
* Note: we could make this API take a struct acpi_device * instead, but
|
||||
* for now, it's more convenient to operate on an acpi_handle.
|
||||
*/
|
||||
int acpi_is_root_bridge(acpi_handle handle)
|
||||
{
|
||||
int ret;
|
||||
struct acpi_device *device;
|
||||
|
||||
ret = acpi_bus_get_device(handle, &device);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
ret = acpi_match_device_ids(device, root_device_ids);
|
||||
if (ret)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_is_root_bridge);
|
||||
|
||||
static acpi_status
|
||||
get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
|
||||
{
|
||||
@@ -161,19 +180,22 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
|
||||
static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
|
||||
unsigned long long *bus)
|
||||
{
|
||||
acpi_status status;
|
||||
int busnum;
|
||||
|
||||
*busnum = -1;
|
||||
busnum = -1;
|
||||
status =
|
||||
acpi_walk_resources(handle, METHOD_NAME__CRS,
|
||||
get_root_bridge_busnr_callback, busnum);
|
||||
get_root_bridge_busnr_callback, &busnum);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
/* Check if we really get a bus number from _CRS */
|
||||
if (*busnum == -1)
|
||||
if (busnum == -1)
|
||||
return AE_ERROR;
|
||||
*bus = busnum;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
@@ -298,6 +320,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
|
||||
static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
|
||||
{
|
||||
struct acpi_pci_root *root;
|
||||
|
||||
list_for_each_entry(root, &acpi_pci_roots, node) {
|
||||
if (root->device->handle == handle)
|
||||
return root;
|
||||
@@ -305,6 +328,87 @@ static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct acpi_handle_node {
|
||||
struct list_head node;
|
||||
acpi_handle handle;
|
||||
};
|
||||
|
||||
/**
|
||||
* acpi_get_pci_dev - convert ACPI CA handle to struct pci_dev
|
||||
* @handle: the handle in question
|
||||
*
|
||||
* Given an ACPI CA handle, the desired PCI device is located in the
|
||||
* list of PCI devices.
|
||||
*
|
||||
* If the device is found, its reference count is increased and this
|
||||
* function returns a pointer to its data structure. The caller must
|
||||
* decrement the reference count by calling pci_dev_put().
|
||||
* If no device is found, %NULL is returned.
|
||||
*/
|
||||
struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
|
||||
{
|
||||
int dev, fn;
|
||||
unsigned long long adr;
|
||||
acpi_status status;
|
||||
acpi_handle phandle;
|
||||
struct pci_bus *pbus;
|
||||
struct pci_dev *pdev = NULL;
|
||||
struct acpi_handle_node *node, *tmp;
|
||||
struct acpi_pci_root *root;
|
||||
LIST_HEAD(device_list);
|
||||
|
||||
/*
|
||||
* Walk up the ACPI CA namespace until we reach a PCI root bridge.
|
||||
*/
|
||||
phandle = handle;
|
||||
while (!acpi_is_root_bridge(phandle)) {
|
||||
node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL);
|
||||
if (!node)
|
||||
goto out;
|
||||
|
||||
INIT_LIST_HEAD(&node->node);
|
||||
node->handle = phandle;
|
||||
list_add(&node->node, &device_list);
|
||||
|
||||
status = acpi_get_parent(phandle, &phandle);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto out;
|
||||
}
|
||||
|
||||
root = acpi_pci_find_root(phandle);
|
||||
if (!root)
|
||||
goto out;
|
||||
|
||||
pbus = root->bus;
|
||||
|
||||
/*
|
||||
* Now, walk back down the PCI device tree until we return to our
|
||||
* original handle. Assumes that everything between the PCI root
|
||||
* bridge and the device we're looking for must be a P2P bridge.
|
||||
*/
|
||||
list_for_each_entry(node, &device_list, node) {
|
||||
acpi_handle hnd = node->handle;
|
||||
status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto out;
|
||||
dev = (adr >> 16) & 0xffff;
|
||||
fn = adr & 0xffff;
|
||||
|
||||
pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn));
|
||||
if (hnd == handle)
|
||||
break;
|
||||
|
||||
pbus = pdev->subordinate;
|
||||
pci_dev_put(pdev);
|
||||
}
|
||||
out:
|
||||
list_for_each_entry_safe(node, tmp, &device_list, node)
|
||||
kfree(node);
|
||||
|
||||
return pdev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
|
||||
|
||||
/**
|
||||
* acpi_pci_osc_control_set - commit requested control to Firmware
|
||||
* @handle: acpi_handle for the target ACPI object
|
||||
@@ -363,31 +467,46 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set);
|
||||
|
||||
static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
struct acpi_pci_root *root = NULL;
|
||||
struct acpi_pci_root *tmp;
|
||||
acpi_status status = AE_OK;
|
||||
unsigned long long value = 0;
|
||||
acpi_handle handle = NULL;
|
||||
unsigned long long segment, bus;
|
||||
acpi_status status;
|
||||
int result;
|
||||
struct acpi_pci_root *root;
|
||||
acpi_handle handle;
|
||||
struct acpi_device *child;
|
||||
u32 flags, base_flags;
|
||||
|
||||
segment = 0;
|
||||
status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
|
||||
&segment);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
/* Check _CRS first, then _BBN. If no _BBN, default to zero. */
|
||||
bus = 0;
|
||||
status = try_get_root_bridge_busnr(device->handle, &bus);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"no bus number in _CRS and can't evaluate _BBN\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
|
||||
if (!root)
|
||||
return -ENOMEM;
|
||||
INIT_LIST_HEAD(&root->node);
|
||||
|
||||
INIT_LIST_HEAD(&root->node);
|
||||
root->device = device;
|
||||
root->segment = segment & 0xFFFF;
|
||||
root->bus_nr = bus & 0xFF;
|
||||
strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
|
||||
device->driver_data = root;
|
||||
|
||||
device->ops.bind = acpi_pci_bind;
|
||||
|
||||
/*
|
||||
* All supported architectures that use ACPI have support for
|
||||
* PCI domains, so we indicate this in _OSC support capabilities.
|
||||
@@ -395,79 +514,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
|
||||
acpi_pci_osc_support(root, flags);
|
||||
|
||||
/*
|
||||
* Segment
|
||||
* -------
|
||||
* Obtained via _SEG, if exists, otherwise assumed to be zero (0).
|
||||
*/
|
||||
status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
|
||||
&value);
|
||||
switch (status) {
|
||||
case AE_OK:
|
||||
root->id.segment = (u16) value;
|
||||
break;
|
||||
case AE_NOT_FOUND:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Assuming segment 0 (no _SEG)\n"));
|
||||
root->id.segment = 0;
|
||||
break;
|
||||
default:
|
||||
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SEG"));
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bus
|
||||
* ---
|
||||
* Obtained via _BBN, if exists, otherwise assumed to be zero (0).
|
||||
*/
|
||||
status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL,
|
||||
&value);
|
||||
switch (status) {
|
||||
case AE_OK:
|
||||
root->id.bus = (u16) value;
|
||||
break;
|
||||
case AE_NOT_FOUND:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Assuming bus 0 (no _BBN)\n"));
|
||||
root->id.bus = 0;
|
||||
break;
|
||||
default:
|
||||
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BBN"));
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Some systems have wrong _BBN */
|
||||
list_for_each_entry(tmp, &acpi_pci_roots, node) {
|
||||
if ((tmp->id.segment == root->id.segment)
|
||||
&& (tmp->id.bus == root->id.bus)) {
|
||||
int bus = 0;
|
||||
acpi_status status;
|
||||
|
||||
printk(KERN_ERR PREFIX
|
||||
"Wrong _BBN value, reboot"
|
||||
" and use option 'pci=noacpi'\n");
|
||||
|
||||
status = try_get_root_bridge_busnr(device->handle, &bus);
|
||||
if (ACPI_FAILURE(status))
|
||||
break;
|
||||
if (bus != root->id.bus) {
|
||||
printk(KERN_INFO PREFIX
|
||||
"PCI _CRS %d overrides _BBN 0\n", bus);
|
||||
root->id.bus = bus;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Device & Function
|
||||
* -----------------
|
||||
* Obtained from _ADR (which has already been evaluated for us).
|
||||
*/
|
||||
root->id.device = device->pnp.bus_address >> 16;
|
||||
root->id.function = device->pnp.bus_address & 0xFFFF;
|
||||
|
||||
/*
|
||||
* TBD: Need PCI interface for enumeration/configuration of roots.
|
||||
*/
|
||||
@@ -477,7 +523,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n",
|
||||
acpi_device_name(device), acpi_device_bid(device),
|
||||
root->id.segment, root->id.bus);
|
||||
root->segment, root->bus_nr);
|
||||
|
||||
/*
|
||||
* Scan the Root Bridge
|
||||
@@ -486,11 +532,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
* PCI namespace does not get created until this call is made (and
|
||||
* thus the root bridge's pci_dev does not exist).
|
||||
*/
|
||||
root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus);
|
||||
root->bus = pci_acpi_scan_root(device, segment, bus);
|
||||
if (!root->bus) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"Bus %04x:%02x not present in PCI namespace\n",
|
||||
root->id.segment, root->id.bus);
|
||||
root->segment, root->bus_nr);
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
@@ -500,7 +546,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
* -----------------------
|
||||
* Thus binding the ACPI and PCI devices.
|
||||
*/
|
||||
result = acpi_pci_bind_root(device, &root->id, root->bus);
|
||||
result = acpi_pci_bind_root(device);
|
||||
if (result)
|
||||
goto end;
|
||||
|
||||
@@ -511,8 +557,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
*/
|
||||
status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
|
||||
if (ACPI_SUCCESS(status))
|
||||
result = acpi_pci_irq_add_prt(device->handle, root->id.segment,
|
||||
root->id.bus);
|
||||
result = acpi_pci_irq_add_prt(device->handle, root->bus);
|
||||
|
||||
/*
|
||||
* Scan and bind all _ADR-Based Devices
|
||||
@@ -531,42 +576,28 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
if (flags != base_flags)
|
||||
acpi_pci_osc_support(root, flags);
|
||||
|
||||
end:
|
||||
if (result) {
|
||||
if (!list_empty(&root->node))
|
||||
list_del(&root->node);
|
||||
kfree(root);
|
||||
}
|
||||
return 0;
|
||||
|
||||
end:
|
||||
if (!list_empty(&root->node))
|
||||
list_del(&root->node);
|
||||
kfree(root);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_pci_root_start(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_pci_root *root;
|
||||
struct acpi_pci_root *root = acpi_driver_data(device);
|
||||
|
||||
|
||||
list_for_each_entry(root, &acpi_pci_roots, node) {
|
||||
if (root->device == device) {
|
||||
pci_bus_add_devices(root->bus);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -ENODEV;
|
||||
pci_bus_add_devices(root->bus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_pci_root_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
struct acpi_pci_root *root = NULL;
|
||||
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
|
||||
root = acpi_driver_data(device);
|
||||
struct acpi_pci_root *root = acpi_driver_data(device);
|
||||
|
||||
kfree(root);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+2
-26
@@ -194,7 +194,7 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
|
||||
|
||||
static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
|
||||
{
|
||||
int result = 0, state;
|
||||
int result = 0;
|
||||
int found = 0;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
@@ -236,18 +236,6 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
if (!acpi_power_nocheck) {
|
||||
/*
|
||||
* If acpi_power_nocheck is set, it is unnecessary to check
|
||||
* the power state after power transition.
|
||||
*/
|
||||
result = acpi_power_get_state(resource->device->handle,
|
||||
&state);
|
||||
if (result)
|
||||
return result;
|
||||
if (state != ACPI_POWER_RESOURCE_STATE_ON)
|
||||
return -ENOEXEC;
|
||||
}
|
||||
/* Update the power resource's _device_ power state */
|
||||
resource->device->power.state = ACPI_STATE_D0;
|
||||
|
||||
@@ -258,7 +246,7 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
|
||||
|
||||
static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
|
||||
{
|
||||
int result = 0, state;
|
||||
int result = 0;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct list_head *node, *next;
|
||||
@@ -293,18 +281,6 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
if (!acpi_power_nocheck) {
|
||||
/*
|
||||
* If acpi_power_nocheck is set, it is unnecessary to check
|
||||
* the power state after power transition.
|
||||
*/
|
||||
result = acpi_power_get_state(handle, &state);
|
||||
if (result)
|
||||
return result;
|
||||
if (state != ACPI_POWER_RESOURCE_STATE_OFF)
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* Update the power resource's _device_ power state */
|
||||
resource->device->power.state = ACPI_STATE_D3;
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr);
|
||||
|
||||
static const struct acpi_device_id processor_device_ids[] = {
|
||||
{ACPI_PROCESSOR_OBJECT_HID, 0},
|
||||
{ACPI_PROCESSOR_HID, 0},
|
||||
{"ACPI0007", 0},
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, processor_device_ids);
|
||||
@@ -596,7 +596,21 @@ static int acpi_processor_get_info(struct acpi_device *device)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"No bus mastering arbitration control\n"));
|
||||
|
||||
if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) {
|
||||
if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
|
||||
/* Declared with "Processor" statement; match ProcessorID */
|
||||
status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
printk(KERN_ERR PREFIX "Evaluating processor object\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
|
||||
* >>> 'acpi_get_processor_id(acpi_id, &id)' in
|
||||
* arch/xxx/acpi.c
|
||||
*/
|
||||
pr->acpi_id = object.processor.proc_id;
|
||||
} else {
|
||||
/*
|
||||
* Declared with "Device" statement; match _UID.
|
||||
* Note that we don't handle string _UIDs yet.
|
||||
@@ -611,20 +625,6 @@ static int acpi_processor_get_info(struct acpi_device *device)
|
||||
}
|
||||
device_declaration = 1;
|
||||
pr->acpi_id = value;
|
||||
} else {
|
||||
/* Declared with "Processor" statement; match ProcessorID */
|
||||
status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
printk(KERN_ERR PREFIX "Evaluating processor object\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
|
||||
* >>> 'acpi_get_processor_id(acpi_id, &id)' in
|
||||
* arch/xxx/acpi.c
|
||||
*/
|
||||
pr->acpi_id = object.processor.proc_id;
|
||||
}
|
||||
cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id);
|
||||
|
||||
@@ -649,7 +649,16 @@ static int acpi_processor_get_info(struct acpi_device *device)
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* On some boxes several processors use the same processor bus id.
|
||||
* But they are located in different scope. For example:
|
||||
* \_SB.SCK0.CPU0
|
||||
* \_SB.SCK1.CPU0
|
||||
* Rename the processor device bus id. And the new bus id will be
|
||||
* generated as the following format:
|
||||
* CPU+CPU ID.
|
||||
*/
|
||||
sprintf(acpi_device_bid(device), "CPU%X", pr->id);
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
|
||||
pr->acpi_id));
|
||||
|
||||
@@ -731,6 +740,8 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
|
||||
/* _PDC call should be done before doing anything else (if reqd.). */
|
||||
arch_acpi_processor_init_pdc(pr);
|
||||
acpi_processor_set_pdc(pr);
|
||||
arch_acpi_processor_cleanup_pdc(pr);
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
acpi_processor_ppc_has_changed(pr);
|
||||
#endif
|
||||
|
||||
@@ -139,7 +139,7 @@ static void acpi_safe_halt(void)
|
||||
* are affected too. We pick the most conservative approach: we assume
|
||||
* that the local APIC stops in both C2 and C3.
|
||||
*/
|
||||
static void acpi_timer_check_state(int state, struct acpi_processor *pr,
|
||||
static void lapic_timer_check_state(int state, struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx)
|
||||
{
|
||||
struct acpi_processor_power *pwr = &pr->power;
|
||||
@@ -162,7 +162,7 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
|
||||
pr->power.timer_broadcast_on_state = state;
|
||||
}
|
||||
|
||||
static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
|
||||
static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)
|
||||
{
|
||||
unsigned long reason;
|
||||
|
||||
@@ -173,7 +173,7 @@ static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
|
||||
}
|
||||
|
||||
/* Power(C) State timer broadcast control */
|
||||
static void acpi_state_timer_broadcast(struct acpi_processor *pr,
|
||||
static void lapic_timer_state_broadcast(struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx,
|
||||
int broadcast)
|
||||
{
|
||||
@@ -190,10 +190,10 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr,
|
||||
|
||||
#else
|
||||
|
||||
static void acpi_timer_check_state(int state, struct acpi_processor *pr,
|
||||
static void lapic_timer_check_state(int state, struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cstate) { }
|
||||
static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { }
|
||||
static void acpi_state_timer_broadcast(struct acpi_processor *pr,
|
||||
static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { }
|
||||
static void lapic_timer_state_broadcast(struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx,
|
||||
int broadcast)
|
||||
{
|
||||
@@ -515,7 +515,8 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
|
||||
static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx)
|
||||
{
|
||||
static int bm_check_flag;
|
||||
static int bm_check_flag = -1;
|
||||
static int bm_control_flag = -1;
|
||||
|
||||
|
||||
if (!cx->address)
|
||||
@@ -545,12 +546,14 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
|
||||
}
|
||||
|
||||
/* All the logic here assumes flags.bm_check is same across all CPUs */
|
||||
if (!bm_check_flag) {
|
||||
if (bm_check_flag == -1) {
|
||||
/* Determine whether bm_check is needed based on CPU */
|
||||
acpi_processor_power_init_bm_check(&(pr->flags), pr->id);
|
||||
bm_check_flag = pr->flags.bm_check;
|
||||
bm_control_flag = pr->flags.bm_control;
|
||||
} else {
|
||||
pr->flags.bm_check = bm_check_flag;
|
||||
pr->flags.bm_control = bm_control_flag;
|
||||
}
|
||||
|
||||
if (pr->flags.bm_check) {
|
||||
@@ -614,29 +617,25 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
|
||||
switch (cx->type) {
|
||||
case ACPI_STATE_C1:
|
||||
cx->valid = 1;
|
||||
acpi_timer_check_state(i, pr, cx);
|
||||
break;
|
||||
|
||||
case ACPI_STATE_C2:
|
||||
acpi_processor_power_verify_c2(cx);
|
||||
if (cx->valid)
|
||||
acpi_timer_check_state(i, pr, cx);
|
||||
break;
|
||||
|
||||
case ACPI_STATE_C3:
|
||||
acpi_processor_power_verify_c3(pr, cx);
|
||||
if (cx->valid)
|
||||
acpi_timer_check_state(i, pr, cx);
|
||||
break;
|
||||
}
|
||||
if (cx->valid)
|
||||
tsc_check_state(cx->type);
|
||||
if (!cx->valid)
|
||||
continue;
|
||||
|
||||
if (cx->valid)
|
||||
working++;
|
||||
lapic_timer_check_state(i, pr, cx);
|
||||
tsc_check_state(cx->type);
|
||||
working++;
|
||||
}
|
||||
|
||||
acpi_propagate_timer_broadcast(pr);
|
||||
lapic_timer_propagate_broadcast(pr);
|
||||
|
||||
return (working);
|
||||
}
|
||||
@@ -839,7 +838,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
acpi_state_timer_broadcast(pr, cx, 1);
|
||||
lapic_timer_state_broadcast(pr, cx, 1);
|
||||
kt1 = ktime_get_real();
|
||||
acpi_idle_do_entry(cx);
|
||||
kt2 = ktime_get_real();
|
||||
@@ -847,7 +846,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
|
||||
|
||||
local_irq_enable();
|
||||
cx->usage++;
|
||||
acpi_state_timer_broadcast(pr, cx, 0);
|
||||
lapic_timer_state_broadcast(pr, cx, 0);
|
||||
|
||||
return idle_time;
|
||||
}
|
||||
@@ -892,7 +891,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
|
||||
* Must be done before busmaster disable as we might need to
|
||||
* access HPET !
|
||||
*/
|
||||
acpi_state_timer_broadcast(pr, cx, 1);
|
||||
lapic_timer_state_broadcast(pr, cx, 1);
|
||||
|
||||
if (cx->type == ACPI_STATE_C3)
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
@@ -914,7 +913,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
|
||||
|
||||
cx->usage++;
|
||||
|
||||
acpi_state_timer_broadcast(pr, cx, 0);
|
||||
lapic_timer_state_broadcast(pr, cx, 0);
|
||||
cx->time += sleep_ticks;
|
||||
return idle_time;
|
||||
}
|
||||
@@ -981,7 +980,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
||||
* Must be done before busmaster disable as we might need to
|
||||
* access HPET !
|
||||
*/
|
||||
acpi_state_timer_broadcast(pr, cx, 1);
|
||||
lapic_timer_state_broadcast(pr, cx, 1);
|
||||
|
||||
kt1 = ktime_get_real();
|
||||
/*
|
||||
@@ -1026,7 +1025,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
||||
|
||||
cx->usage++;
|
||||
|
||||
acpi_state_timer_broadcast(pr, cx, 0);
|
||||
lapic_timer_state_broadcast(pr, cx, 0);
|
||||
cx->time += sleep_ticks;
|
||||
return idle_time;
|
||||
}
|
||||
|
||||
+30
-39
@@ -95,7 +95,7 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha
|
||||
}
|
||||
static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
|
||||
|
||||
static int acpi_bus_hot_remove_device(void *context)
|
||||
static void acpi_bus_hot_remove_device(void *context)
|
||||
{
|
||||
struct acpi_device *device;
|
||||
acpi_handle handle = context;
|
||||
@@ -104,10 +104,10 @@ static int acpi_bus_hot_remove_device(void *context)
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
if (acpi_bus_get_device(handle, &device))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Hot-removing device %s...\n", dev_name(&device->dev)));
|
||||
@@ -115,7 +115,7 @@ static int acpi_bus_hot_remove_device(void *context)
|
||||
if (acpi_bus_trim(device, 1)) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"Removing device failed\n");
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* power off device */
|
||||
@@ -142,9 +142,10 @@ static int acpi_bus_hot_remove_device(void *context)
|
||||
*/
|
||||
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
printk(KERN_WARNING PREFIX
|
||||
"Eject device failed\n");
|
||||
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@@ -155,7 +156,6 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
|
||||
acpi_status status;
|
||||
acpi_object_type type = 0;
|
||||
struct acpi_device *acpi_device = to_acpi_device(d);
|
||||
struct task_struct *task;
|
||||
|
||||
if ((!count) || (buf[0] != '1')) {
|
||||
return -EINVAL;
|
||||
@@ -172,11 +172,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* remove the device in another thread to fix the deadlock issue */
|
||||
task = kthread_run(acpi_bus_hot_remove_device,
|
||||
acpi_device->handle, "acpi_hot_remove_device");
|
||||
if (IS_ERR(task))
|
||||
ret = PTR_ERR(task);
|
||||
acpi_os_hotplug_execute(acpi_bus_hot_remove_device, acpi_device->handle);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
@@ -198,12 +194,12 @@ acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *b
|
||||
int result;
|
||||
|
||||
result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
|
||||
if(result)
|
||||
if (result)
|
||||
goto end;
|
||||
|
||||
result = sprintf(buf, "%s\n", (char*)path.pointer);
|
||||
kfree(path.pointer);
|
||||
end:
|
||||
end:
|
||||
return result;
|
||||
}
|
||||
static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
|
||||
@@ -217,21 +213,21 @@ static int acpi_device_setup_files(struct acpi_device *dev)
|
||||
/*
|
||||
* Devices gotten from FADT don't have a "path" attribute
|
||||
*/
|
||||
if(dev->handle) {
|
||||
if (dev->handle) {
|
||||
result = device_create_file(&dev->dev, &dev_attr_path);
|
||||
if(result)
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(dev->flags.hardware_id) {
|
||||
if (dev->flags.hardware_id) {
|
||||
result = device_create_file(&dev->dev, &dev_attr_hid);
|
||||
if(result)
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (dev->flags.hardware_id || dev->flags.compatible_ids){
|
||||
if (dev->flags.hardware_id || dev->flags.compatible_ids) {
|
||||
result = device_create_file(&dev->dev, &dev_attr_modalias);
|
||||
if(result)
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -242,7 +238,7 @@ static int acpi_device_setup_files(struct acpi_device *dev)
|
||||
status = acpi_get_handle(dev->handle, "_EJ0", &temp);
|
||||
if (ACPI_SUCCESS(status))
|
||||
result = device_create_file(&dev->dev, &dev_attr_eject);
|
||||
end:
|
||||
end:
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -262,9 +258,9 @@ static void acpi_device_remove_files(struct acpi_device *dev)
|
||||
if (dev->flags.hardware_id || dev->flags.compatible_ids)
|
||||
device_remove_file(&dev->dev, &dev_attr_modalias);
|
||||
|
||||
if(dev->flags.hardware_id)
|
||||
if (dev->flags.hardware_id)
|
||||
device_remove_file(&dev->dev, &dev_attr_hid);
|
||||
if(dev->handle)
|
||||
if (dev->handle)
|
||||
device_remove_file(&dev->dev, &dev_attr_path);
|
||||
}
|
||||
/* --------------------------------------------------------------------------
|
||||
@@ -512,7 +508,7 @@ static int acpi_device_register(struct acpi_device *device,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
if (!found) {
|
||||
acpi_device_bus_id = new_bus_id;
|
||||
strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device");
|
||||
acpi_device_bus_id->instance_no = 0;
|
||||
@@ -530,22 +526,21 @@ static int acpi_device_register(struct acpi_device *device,
|
||||
if (device->parent)
|
||||
device->dev.parent = &parent->dev;
|
||||
device->dev.bus = &acpi_bus_type;
|
||||
device_initialize(&device->dev);
|
||||
device->dev.release = &acpi_device_release;
|
||||
result = device_add(&device->dev);
|
||||
if(result) {
|
||||
dev_err(&device->dev, "Error adding device\n");
|
||||
result = device_register(&device->dev);
|
||||
if (result) {
|
||||
dev_err(&device->dev, "Error registering device\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
result = acpi_device_setup_files(device);
|
||||
if(result)
|
||||
if (result)
|
||||
printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n",
|
||||
dev_name(&device->dev));
|
||||
|
||||
device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
|
||||
return 0;
|
||||
end:
|
||||
end:
|
||||
mutex_lock(&acpi_device_lock);
|
||||
if (device->parent)
|
||||
list_del(&device->node);
|
||||
@@ -577,7 +572,7 @@ static void acpi_device_unregister(struct acpi_device *device, int type)
|
||||
* @device: the device to add and initialize
|
||||
* @driver: driver for the device
|
||||
*
|
||||
* Used to initialize a device via its device driver. Called whenever a
|
||||
* Used to initialize a device via its device driver. Called whenever a
|
||||
* driver is bound to a device. Invokes the driver's add() ops.
|
||||
*/
|
||||
static int
|
||||
@@ -585,7 +580,6 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
|
||||
if (!device || !driver)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -802,7 +796,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
|
||||
if (!acpi_match_device_ids(device, button_device_ids))
|
||||
device->wakeup.flags.run_wake = 1;
|
||||
|
||||
end:
|
||||
end:
|
||||
if (ACPI_FAILURE(status))
|
||||
device->flags.wake_capable = 0;
|
||||
return 0;
|
||||
@@ -1070,7 +1064,7 @@ static void acpi_device_set_id(struct acpi_device *device,
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* \_SB
|
||||
* ----
|
||||
* Fix for the system root bus device -- the only root-level device.
|
||||
@@ -1320,7 +1314,7 @@ acpi_add_single_object(struct acpi_device **child,
|
||||
device->parent->ops.bind(device);
|
||||
}
|
||||
|
||||
end:
|
||||
end:
|
||||
if (!result)
|
||||
*child = device;
|
||||
else {
|
||||
@@ -1464,7 +1458,6 @@ acpi_bus_add(struct acpi_device **child,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_bus_add);
|
||||
|
||||
int acpi_bus_start(struct acpi_device *device)
|
||||
@@ -1484,7 +1477,6 @@ int acpi_bus_start(struct acpi_device *device)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_bus_start);
|
||||
|
||||
int acpi_bus_trim(struct acpi_device *start, int rmdevice)
|
||||
@@ -1542,7 +1534,6 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_bus_trim);
|
||||
|
||||
|
||||
static int acpi_bus_scan_fixed(struct acpi_device *root)
|
||||
{
|
||||
int result = 0;
|
||||
@@ -1610,6 +1601,6 @@ int __init acpi_scan_init(void)
|
||||
if (result)
|
||||
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
|
||||
|
||||
Done:
|
||||
Done:
|
||||
return result;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user