Merge branch 'pci/hotplug'
- Fix infinite loop in pciehp IRQ handler on power fault (Lukas Wunner) - Removed commented-out ibmphp functions (Vihas Mak) - Fix pciehp lockdep errors on Thunderbolt undock (Hans de Goede) * pci/hotplug: PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors PCI: ibmphp: Remove commented-out functions PCI: pciehp: Fix infinite loop in IRQ handler upon power fault
This commit is contained in:
Коммит
7475f9319a
|
@ -30,11 +30,6 @@ ibmphp:
|
|||
or ibmphp should store a pointer to its bus in struct slot. Probably the
|
||||
former.
|
||||
|
||||
* The functions get_max_adapter_speed() and get_bus_name() are commented out.
|
||||
Can they be deleted? There are also forward declarations at the top of
|
||||
ibmphp_core.c as well as pointers in ibmphp_hotplug_slot_ops, likewise
|
||||
commented out.
|
||||
|
||||
* ibmphp_init_devno() takes a struct slot **, it could instead take a
|
||||
struct slot *.
|
||||
|
||||
|
|
|
@ -50,14 +50,6 @@ static int irqs[16]; /* PIC mode IRQs we're using so far (in case MPS
|
|||
|
||||
static int init_flag;
|
||||
|
||||
/*
|
||||
static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
|
||||
|
||||
static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
|
||||
{
|
||||
return get_max_adapter_speed_1 (hs, value, 1);
|
||||
}
|
||||
*/
|
||||
static inline int get_cur_bus_info(struct slot **sl)
|
||||
{
|
||||
int rc = 1;
|
||||
|
@ -401,69 +393,6 @@ static int get_max_bus_speed(struct slot *slot)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 *value, u8 flag)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
struct slot *pslot;
|
||||
struct slot myslot;
|
||||
|
||||
debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",
|
||||
(ulong)hotplug_slot, (ulong) value);
|
||||
|
||||
if (flag)
|
||||
ibmphp_lock_operations();
|
||||
|
||||
if (hotplug_slot && value) {
|
||||
pslot = hotplug_slot->private;
|
||||
if (pslot) {
|
||||
memcpy(&myslot, pslot, sizeof(struct slot));
|
||||
rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
|
||||
&(myslot.status));
|
||||
|
||||
if (!(SLOT_LATCH (myslot.status)) &&
|
||||
(SLOT_PRESENT (myslot.status))) {
|
||||
rc = ibmphp_hpc_readslot(pslot,
|
||||
READ_EXTSLOTSTATUS,
|
||||
&(myslot.ext_status));
|
||||
if (!rc)
|
||||
*value = SLOT_SPEED(myslot.ext_status);
|
||||
} else
|
||||
*value = MAX_ADAPTER_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
ibmphp_unlock_operations();
|
||||
|
||||
debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int get_bus_name(struct hotplug_slot *hotplug_slot, char *value)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
struct slot *pslot = NULL;
|
||||
|
||||
debug("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
|
||||
|
||||
ibmphp_lock_operations();
|
||||
|
||||
if (hotplug_slot) {
|
||||
pslot = hotplug_slot->private;
|
||||
if (pslot) {
|
||||
rc = 0;
|
||||
snprintf(value, 100, "Bus %x", pslot->bus);
|
||||
}
|
||||
} else
|
||||
rc = -ENODEV;
|
||||
|
||||
ibmphp_unlock_operations();
|
||||
debug("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
|
||||
return rc;
|
||||
}
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* This routine will initialize the ops data structure used in the validate
|
||||
* function. It will also power off empty slots that are powered on since BIOS
|
||||
|
@ -1231,9 +1160,6 @@ const struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
|
|||
.get_attention_status = get_attention_status,
|
||||
.get_latch_status = get_latch_status,
|
||||
.get_adapter_status = get_adapter_present,
|
||||
/* .get_max_adapter_speed = get_max_adapter_speed,
|
||||
.get_bus_name_status = get_bus_name,
|
||||
*/
|
||||
};
|
||||
|
||||
static void ibmphp_unload(void)
|
||||
|
|
|
@ -75,6 +75,8 @@ extern int pciehp_poll_time;
|
|||
* @reset_lock: prevents access to the Data Link Layer Link Active bit in the
|
||||
* Link Status register and to the Presence Detect State bit in the Slot
|
||||
* Status register during a slot reset which may cause them to flap
|
||||
* @depth: Number of additional hotplug ports in the path to the root bus,
|
||||
* used as lock subclass for @reset_lock
|
||||
* @ist_running: flag to keep user request waiting while IRQ thread is running
|
||||
* @request_result: result of last user request submitted to the IRQ thread
|
||||
* @requester: wait queue to wake up on completion of user request,
|
||||
|
@ -106,6 +108,7 @@ struct controller {
|
|||
|
||||
struct hotplug_slot hotplug_slot; /* hotplug core interface */
|
||||
struct rw_semaphore reset_lock;
|
||||
unsigned int depth;
|
||||
unsigned int ist_running;
|
||||
int request_result;
|
||||
wait_queue_head_t requester;
|
||||
|
|
|
@ -166,7 +166,7 @@ static void pciehp_check_presence(struct controller *ctrl)
|
|||
{
|
||||
int occupied;
|
||||
|
||||
down_read(&ctrl->reset_lock);
|
||||
down_read_nested(&ctrl->reset_lock, ctrl->depth);
|
||||
mutex_lock(&ctrl->state_lock);
|
||||
|
||||
occupied = pciehp_card_present_or_link_active(ctrl);
|
||||
|
|
|
@ -583,7 +583,7 @@ static void pciehp_ignore_dpc_link_change(struct controller *ctrl,
|
|||
* the corresponding link change may have been ignored above.
|
||||
* Synthesize it to ensure that it is acted on.
|
||||
*/
|
||||
down_read(&ctrl->reset_lock);
|
||||
down_read_nested(&ctrl->reset_lock, ctrl->depth);
|
||||
if (!pciehp_check_link_active(ctrl))
|
||||
pciehp_request(ctrl, PCI_EXP_SLTSTA_DLLSC);
|
||||
up_read(&ctrl->reset_lock);
|
||||
|
@ -642,6 +642,8 @@ read_status:
|
|||
*/
|
||||
if (ctrl->power_fault_detected)
|
||||
status &= ~PCI_EXP_SLTSTA_PFD;
|
||||
else if (status & PCI_EXP_SLTSTA_PFD)
|
||||
ctrl->power_fault_detected = true;
|
||||
|
||||
events |= status;
|
||||
if (!events) {
|
||||
|
@ -651,7 +653,7 @@ read_status:
|
|||
}
|
||||
|
||||
if (status) {
|
||||
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events);
|
||||
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, status);
|
||||
|
||||
/*
|
||||
* In MSI mode, all event bits must be zero before the port
|
||||
|
@ -725,8 +727,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
/* Check Power Fault Detected */
|
||||
if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
|
||||
ctrl->power_fault_detected = 1;
|
||||
if (events & PCI_EXP_SLTSTA_PFD) {
|
||||
ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl));
|
||||
pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
|
||||
PCI_EXP_SLTCTL_ATTN_IND_ON);
|
||||
|
@ -746,7 +747,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
|
|||
* Disable requests have higher priority than Presence Detect Changed
|
||||
* or Data Link Layer State Changed events.
|
||||
*/
|
||||
down_read(&ctrl->reset_lock);
|
||||
down_read_nested(&ctrl->reset_lock, ctrl->depth);
|
||||
if (events & DISABLE_SLOT)
|
||||
pciehp_handle_disable_request(ctrl);
|
||||
else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC))
|
||||
|
@ -906,7 +907,7 @@ int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, bool probe)
|
|||
if (probe)
|
||||
return 0;
|
||||
|
||||
down_write(&ctrl->reset_lock);
|
||||
down_write_nested(&ctrl->reset_lock, ctrl->depth);
|
||||
|
||||
if (!ATTN_BUTTN(ctrl)) {
|
||||
ctrl_mask |= PCI_EXP_SLTCTL_PDCE;
|
||||
|
@ -962,6 +963,20 @@ static inline void dbg_ctrl(struct controller *ctrl)
|
|||
|
||||
#define FLAG(x, y) (((x) & (y)) ? '+' : '-')
|
||||
|
||||
static inline int pcie_hotplug_depth(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_bus *bus = dev->bus;
|
||||
int depth = 0;
|
||||
|
||||
while (bus->parent) {
|
||||
bus = bus->parent;
|
||||
if (bus->self && bus->self->is_hotplug_bridge)
|
||||
depth++;
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
struct controller *pcie_init(struct pcie_device *dev)
|
||||
{
|
||||
struct controller *ctrl;
|
||||
|
@ -975,6 +990,7 @@ struct controller *pcie_init(struct pcie_device *dev)
|
|||
return NULL;
|
||||
|
||||
ctrl->pcie = dev;
|
||||
ctrl->depth = pcie_hotplug_depth(dev->port);
|
||||
pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
|
||||
|
||||
if (pdev->hotplug_user_indicators)
|
||||
|
|
Загрузка…
Ссылка в новой задаче