Merge branch 'pci/hotplug-vga' into for-linus
* pci/hotplug-vga: ACPIPHP / radeon / nouveau: Remove acpi_bus_no_hotplug() PCI: Add pci_ignore_hotplug() to ignore hotplug events for a device
This commit is contained in:
commit
6de8eee17a
@ -177,16 +177,6 @@ void acpi_bus_detach_private_data(acpi_handle handle)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(acpi_bus_detach_private_data);
|
EXPORT_SYMBOL_GPL(acpi_bus_detach_private_data);
|
||||||
|
|
||||||
void acpi_bus_no_hotplug(acpi_handle handle)
|
|
||||||
{
|
|
||||||
struct acpi_device *adev = NULL;
|
|
||||||
|
|
||||||
acpi_bus_get_device(handle, &adev);
|
|
||||||
if (adev)
|
|
||||||
adev->flags.no_hotplug = true;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(acpi_bus_no_hotplug);
|
|
||||||
|
|
||||||
static void acpi_print_osc_error(acpi_handle handle,
|
static void acpi_print_osc_error(acpi_handle handle,
|
||||||
struct acpi_osc_context *context, char *error)
|
struct acpi_osc_context *context, char *error)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,6 @@ static struct nouveau_dsm_priv {
|
|||||||
bool dsm_detected;
|
bool dsm_detected;
|
||||||
bool optimus_detected;
|
bool optimus_detected;
|
||||||
acpi_handle dhandle;
|
acpi_handle dhandle;
|
||||||
acpi_handle other_handle;
|
|
||||||
acpi_handle rom_handle;
|
acpi_handle rom_handle;
|
||||||
} nouveau_dsm_priv;
|
} nouveau_dsm_priv;
|
||||||
|
|
||||||
@ -222,10 +221,9 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
|
|||||||
if (!dhandle)
|
if (!dhandle)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!acpi_has_method(dhandle, "_DSM")) {
|
if (!acpi_has_method(dhandle, "_DSM"))
|
||||||
nouveau_dsm_priv.other_handle = dhandle;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
if (acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102,
|
if (acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102,
|
||||||
1 << NOUVEAU_DSM_POWER))
|
1 << NOUVEAU_DSM_POWER))
|
||||||
retval |= NOUVEAU_DSM_HAS_MUX;
|
retval |= NOUVEAU_DSM_HAS_MUX;
|
||||||
@ -301,16 +299,6 @@ static bool nouveau_dsm_detect(void)
|
|||||||
printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
|
printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
|
||||||
acpi_method_name);
|
acpi_method_name);
|
||||||
nouveau_dsm_priv.dsm_detected = true;
|
nouveau_dsm_priv.dsm_detected = true;
|
||||||
/*
|
|
||||||
* On some systems hotplug events are generated for the device
|
|
||||||
* being switched off when _DSM is executed. They cause ACPI
|
|
||||||
* hotplug to trigger and attempt to remove the device from
|
|
||||||
* the system, which causes it to break down. Prevent that from
|
|
||||||
* happening by setting the no_hotplug flag for the involved
|
|
||||||
* ACPI device objects.
|
|
||||||
*/
|
|
||||||
acpi_bus_no_hotplug(nouveau_dsm_priv.dhandle);
|
|
||||||
acpi_bus_no_hotplug(nouveau_dsm_priv.other_handle);
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,6 +627,7 @@ int nouveau_pmops_suspend(struct device *dev)
|
|||||||
|
|
||||||
pci_save_state(pdev);
|
pci_save_state(pdev);
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
|
pci_ignore_hotplug(pdev);
|
||||||
pci_set_power_state(pdev, PCI_D3hot);
|
pci_set_power_state(pdev, PCI_D3hot);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ static struct radeon_atpx_priv {
|
|||||||
bool atpx_detected;
|
bool atpx_detected;
|
||||||
/* handle for device - and atpx */
|
/* handle for device - and atpx */
|
||||||
acpi_handle dhandle;
|
acpi_handle dhandle;
|
||||||
acpi_handle other_handle;
|
|
||||||
struct radeon_atpx atpx;
|
struct radeon_atpx atpx;
|
||||||
} radeon_atpx_priv;
|
} radeon_atpx_priv;
|
||||||
|
|
||||||
@ -453,10 +452,9 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
|
status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status))
|
||||||
radeon_atpx_priv.other_handle = dhandle;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
radeon_atpx_priv.dhandle = dhandle;
|
radeon_atpx_priv.dhandle = dhandle;
|
||||||
radeon_atpx_priv.atpx.handle = atpx_handle;
|
radeon_atpx_priv.atpx.handle = atpx_handle;
|
||||||
return true;
|
return true;
|
||||||
@ -540,16 +538,6 @@ static bool radeon_atpx_detect(void)
|
|||||||
printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
|
printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
|
||||||
acpi_method_name);
|
acpi_method_name);
|
||||||
radeon_atpx_priv.atpx_detected = true;
|
radeon_atpx_priv.atpx_detected = true;
|
||||||
/*
|
|
||||||
* On some systems hotplug events are generated for the device
|
|
||||||
* being switched off when ATPX is executed. They cause ACPI
|
|
||||||
* hotplug to trigger and attempt to remove the device from
|
|
||||||
* the system, which causes it to break down. Prevent that from
|
|
||||||
* happening by setting the no_hotplug flag for the involved
|
|
||||||
* ACPI device objects.
|
|
||||||
*/
|
|
||||||
acpi_bus_no_hotplug(radeon_atpx_priv.dhandle);
|
|
||||||
acpi_bus_no_hotplug(radeon_atpx_priv.other_handle);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -440,6 +440,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev)
|
|||||||
ret = radeon_suspend_kms(drm_dev, false, false);
|
ret = radeon_suspend_kms(drm_dev, false, false);
|
||||||
pci_save_state(pdev);
|
pci_save_state(pdev);
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
|
pci_ignore_hotplug(pdev);
|
||||||
pci_set_power_state(pdev, PCI_D3cold);
|
pci_set_power_state(pdev, PCI_D3cold);
|
||||||
drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
|
drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
|
||||||
|
|
||||||
|
@ -560,19 +560,15 @@ static void disable_slot(struct acpiphp_slot *slot)
|
|||||||
slot->flags &= (~SLOT_ENABLED);
|
slot->flags &= (~SLOT_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool acpiphp_no_hotplug(struct acpi_device *adev)
|
|
||||||
{
|
|
||||||
return adev && adev->flags.no_hotplug;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool slot_no_hotplug(struct acpiphp_slot *slot)
|
static bool slot_no_hotplug(struct acpiphp_slot *slot)
|
||||||
{
|
{
|
||||||
struct acpiphp_func *func;
|
struct pci_bus *bus = slot->bus;
|
||||||
|
struct pci_dev *dev;
|
||||||
|
|
||||||
list_for_each_entry(func, &slot->funcs, sibling)
|
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||||
if (acpiphp_no_hotplug(func_to_acpi_device(func)))
|
if (PCI_SLOT(dev->devfn) == slot->device && dev->ignore_hotplug)
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,7 +641,7 @@ static void trim_stale_devices(struct pci_dev *dev)
|
|||||||
|
|
||||||
status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
|
status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
|
||||||
alive = (ACPI_SUCCESS(status) && device_status_valid(sta))
|
alive = (ACPI_SUCCESS(status) && device_status_valid(sta))
|
||||||
|| acpiphp_no_hotplug(adev);
|
|| dev->ignore_hotplug;
|
||||||
}
|
}
|
||||||
if (!alive)
|
if (!alive)
|
||||||
alive = pci_device_is_present(dev);
|
alive = pci_device_is_present(dev);
|
||||||
|
@ -506,6 +506,8 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
|
|||||||
{
|
{
|
||||||
struct controller *ctrl = (struct controller *)dev_id;
|
struct controller *ctrl = (struct controller *)dev_id;
|
||||||
struct pci_dev *pdev = ctrl_dev(ctrl);
|
struct pci_dev *pdev = ctrl_dev(ctrl);
|
||||||
|
struct pci_bus *subordinate = pdev->subordinate;
|
||||||
|
struct pci_dev *dev;
|
||||||
struct slot *slot = ctrl->slot;
|
struct slot *slot = ctrl->slot;
|
||||||
u16 detected, intr_loc;
|
u16 detected, intr_loc;
|
||||||
|
|
||||||
@ -539,6 +541,16 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
|
|||||||
wake_up(&ctrl->queue);
|
wake_up(&ctrl->queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subordinate) {
|
||||||
|
list_for_each_entry(dev, &subordinate->devices, bus_list) {
|
||||||
|
if (dev->ignore_hotplug) {
|
||||||
|
ctrl_dbg(ctrl, "ignoring hotplug event %#06x (%s requested no hotplug)\n",
|
||||||
|
intr_loc, pci_name(dev));
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(intr_loc & ~PCI_EXP_SLTSTA_CC))
|
if (!(intr_loc & ~PCI_EXP_SLTSTA_CC))
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
|
||||||
|
@ -204,10 +204,9 @@ struct acpi_device_flags {
|
|||||||
u32 match_driver:1;
|
u32 match_driver:1;
|
||||||
u32 initialized:1;
|
u32 initialized:1;
|
||||||
u32 visited:1;
|
u32 visited:1;
|
||||||
u32 no_hotplug:1;
|
|
||||||
u32 hotplug_notify:1;
|
u32 hotplug_notify:1;
|
||||||
u32 is_dock_station:1;
|
u32 is_dock_station:1;
|
||||||
u32 reserved:22;
|
u32 reserved:23;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* File System */
|
/* File System */
|
||||||
@ -412,7 +411,6 @@ void acpi_bus_private_data_handler(acpi_handle, void *);
|
|||||||
int acpi_bus_get_private_data(acpi_handle, void **);
|
int acpi_bus_get_private_data(acpi_handle, void **);
|
||||||
int acpi_bus_attach_private_data(acpi_handle, void *);
|
int acpi_bus_attach_private_data(acpi_handle, void *);
|
||||||
void acpi_bus_detach_private_data(acpi_handle);
|
void acpi_bus_detach_private_data(acpi_handle);
|
||||||
void acpi_bus_no_hotplug(acpi_handle handle);
|
|
||||||
extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
|
extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
|
||||||
extern int register_acpi_notifier(struct notifier_block *);
|
extern int register_acpi_notifier(struct notifier_block *);
|
||||||
extern int unregister_acpi_notifier(struct notifier_block *);
|
extern int unregister_acpi_notifier(struct notifier_block *);
|
||||||
|
@ -303,6 +303,7 @@ struct pci_dev {
|
|||||||
D3cold, not set for devices
|
D3cold, not set for devices
|
||||||
powered on/off by the
|
powered on/off by the
|
||||||
corresponding bridge */
|
corresponding bridge */
|
||||||
|
unsigned int ignore_hotplug:1; /* Ignore hotplug events */
|
||||||
unsigned int d3_delay; /* D3->D0 transition time in ms */
|
unsigned int d3_delay; /* D3->D0 transition time in ms */
|
||||||
unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */
|
unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */
|
||||||
|
|
||||||
@ -1021,6 +1022,11 @@ bool pci_dev_run_wake(struct pci_dev *dev);
|
|||||||
bool pci_check_pme_status(struct pci_dev *dev);
|
bool pci_check_pme_status(struct pci_dev *dev);
|
||||||
void pci_pme_wakeup_bus(struct pci_bus *bus);
|
void pci_pme_wakeup_bus(struct pci_bus *bus);
|
||||||
|
|
||||||
|
static inline void pci_ignore_hotplug(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
dev->ignore_hotplug = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,
|
static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,
|
||||||
bool enable)
|
bool enable)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user