Skip to content

Commit

Permalink
Merge branches 'pci/aer', 'pci/hotplug', 'pci/misc', 'pci/msi', 'pci/…
Browse files Browse the repository at this point in the history
…resource' and 'pci/virtualization' into next

* pci/aer:
  PCI/AER: Clear error status registers during enumeration and restore

* pci/hotplug:
  PCI: pciehp: Queue power work requests in dedicated function

* pci/misc:
  PCI: Turn off Request Attributes to avoid Chelsio T5 Completion erratum
  x86/PCI: Make pci_subsys_init() static
  PCI: Add builtin_pci_driver() to avoid registration boilerplate
  PCI: Remove unnecessary "if" statement

* pci/msi:
  x86/PCI: Don't alloc pcibios-irq when MSI is enabled
  PCI/MSI: Export all remapped MSIs to sysfs attributes
  PCI: Disable MSI on SiS 761

* pci/resource:
  sparc/PCI: Add mem64 resource parsing for root bus
  PCI: Expand Enhanced Allocation BAR output
  PCI: Make Enhanced Allocation bitmasks more obvious
  PCI: Handle Enhanced Allocation capability for SR-IOV devices
  PCI: Add support for Enhanced Allocation devices
  PCI: Add Enhanced Allocation register entries
  PCI: Handle IORESOURCE_PCI_FIXED when assigning resources
  PCI: Handle IORESOURCE_PCI_FIXED when sizing resources
  PCI: Clear IORESOURCE_UNSET when reverting to firmware-assigned address

* pci/virtualization:
  PCI: Fix sriov_enable() error path for pcibios_enable_sriov() failures
  PCI: Wait 1 second between disabling VFs and clearing NumVFs
  PCI: Reorder pcibios_sriov_disable()
  PCI: Remove VFs in reverse order if virtfn_add() fails
  PCI: Remove redundant validation of SR-IOV offset/stride registers
  PCI: Set SR-IOV NumVFs to zero after enumeration
  PCI: Enable SR-IOV ARI Capable Hierarchy before reading TotalVFs
  PCI: Don't try to restore VF BARs
  • Loading branch information
bjorn-helgaas committed Nov 2, 2015
7 parents 6ff33f3 + b07461a + bee6775 + c56d445 + 8affb48 + af86fa4 + c23b613 commit 1f9a30e
Show file tree
Hide file tree
Showing 19 changed files with 556 additions and 129 deletions.
7 changes: 6 additions & 1 deletion arch/sparc/kernel/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,10 @@ static unsigned long pci_parse_of_flags(u32 addr0)

if (addr0 & 0x02000000) {
flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
if (addr0 & 0x01000000)
flags |= IORESOURCE_MEM_64
| PCI_BASE_ADDRESS_MEM_TYPE_64;
if (addr0 & 0x40000000)
flags |= IORESOURCE_PREFETCH
| PCI_BASE_ADDRESS_MEM_PREFETCH;
Expand Down Expand Up @@ -655,6 +657,9 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
pbm->io_space.start);
pci_add_resource_offset(&resources, &pbm->mem_space,
pbm->mem_space.start);
if (pbm->mem64_space.flags)
pci_add_resource_offset(&resources, &pbm->mem64_space,
pbm->mem_space.start);
pbm->busn.start = pbm->pci_first_busno;
pbm->busn.end = pbm->pci_last_busno;
pbm->busn.flags = IORESOURCE_BUS;
Expand Down
17 changes: 15 additions & 2 deletions arch/sparc/kernel/pci_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
}

num_pbm_ranges = i / sizeof(*pbm_ranges);
memset(&pbm->mem64_space, 0, sizeof(struct resource));

for (i = 0; i < num_pbm_ranges; i++) {
const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
Expand Down Expand Up @@ -451,7 +452,12 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
break;

case 3:
/* XXX 64-bit MEM handling XXX */
/* 64-bit MEM handling */
pbm->mem64_space.start = a;
pbm->mem64_space.end = a + size - 1UL;
pbm->mem64_space.flags = IORESOURCE_MEM;
saw_mem = 1;
break;

default:
break;
Expand All @@ -465,15 +471,22 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
prom_halt();
}

printk("%s: PCI IO[%llx] MEM[%llx]\n",
printk("%s: PCI IO[%llx] MEM[%llx]",
pbm->name,
pbm->io_space.start,
pbm->mem_space.start);
if (pbm->mem64_space.flags)
printk(" MEM64[%llx]",
pbm->mem64_space.start);
printk("\n");

pbm->io_space.name = pbm->mem_space.name = pbm->name;
pbm->mem64_space.name = pbm->name;

request_resource(&ioport_resource, &pbm->io_space);
request_resource(&iomem_resource, &pbm->mem_space);
if (pbm->mem64_space.flags)
request_resource(&iomem_resource, &pbm->mem64_space);

pci_register_legacy_regions(&pbm->io_space,
&pbm->mem_space);
Expand Down
1 change: 1 addition & 0 deletions arch/sparc/kernel/pci_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct pci_pbm_info {
/* PBM I/O and Memory space resources. */
struct resource io_space;
struct resource mem_space;
struct resource mem64_space;
struct resource busn;

/* Base of PCI Config space, can be per-PBM or shared. */
Expand Down
8 changes: 8 additions & 0 deletions arch/x86/pci/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,14 @@ int pcibios_add_device(struct pci_dev *dev)

int pcibios_alloc_irq(struct pci_dev *dev)
{
/*
* If the PCI device was already claimed by core code and has
* MSI enabled, probing of the pcibios IRQ will overwrite
* dev->irq. So bail out if MSI is already enabled.
*/
if (pci_dev_msi_enabled(dev))
return -EBUSY;

return pcibios_enable_irq(dev);
}

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/pci/legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void pcibios_scan_specific_bus(int busn)
}
EXPORT_SYMBOL_GPL(pcibios_scan_specific_bus);

int __init pci_subsys_init(void)
static int __init pci_subsys_init(void)
{
/*
* The init function returns an non zero value when
Expand Down
75 changes: 23 additions & 52 deletions drivers/pci/hotplug/pciehp_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,36 +204,39 @@ static void pciehp_power_thread(struct work_struct *work)
kfree(info);
}

void pciehp_queue_pushbutton_work(struct work_struct *work)
static void pciehp_queue_power_work(struct slot *p_slot, int req)
{
struct slot *p_slot = container_of(work, struct slot, work.work);
struct power_work_info *info;

p_slot->state = (req == ENABLE_REQ) ? POWERON_STATE : POWEROFF_STATE;

info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
__func__);
ctrl_err(p_slot->ctrl, "no memory to queue %s request\n",
(req == ENABLE_REQ) ? "poweron" : "poweroff");
return;
}
info->p_slot = p_slot;
INIT_WORK(&info->work, pciehp_power_thread);
info->req = req;
queue_work(p_slot->wq, &info->work);
}

void pciehp_queue_pushbutton_work(struct work_struct *work)
{
struct slot *p_slot = container_of(work, struct slot, work.work);

mutex_lock(&p_slot->lock);
switch (p_slot->state) {
case BLINKINGOFF_STATE:
p_slot->state = POWEROFF_STATE;
info->req = DISABLE_REQ;
pciehp_queue_power_work(p_slot, DISABLE_REQ);
break;
case BLINKINGON_STATE:
p_slot->state = POWERON_STATE;
info->req = ENABLE_REQ;
pciehp_queue_power_work(p_slot, ENABLE_REQ);
break;
default:
kfree(info);
goto out;
break;
}
queue_work(p_slot->wq, &info->work);
out:
mutex_unlock(&p_slot->lock);
}

Expand Down Expand Up @@ -301,27 +304,12 @@ static void handle_button_press_event(struct slot *p_slot)
static void handle_surprise_event(struct slot *p_slot)
{
u8 getstatus;
struct power_work_info *info;

info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
__func__);
return;
}
info->p_slot = p_slot;
INIT_WORK(&info->work, pciehp_power_thread);

pciehp_get_adapter_status(p_slot, &getstatus);
if (!getstatus) {
p_slot->state = POWEROFF_STATE;
info->req = DISABLE_REQ;
} else {
p_slot->state = POWERON_STATE;
info->req = ENABLE_REQ;
}

queue_work(p_slot->wq, &info->work);
if (!getstatus)
pciehp_queue_power_work(p_slot, DISABLE_REQ);
else
pciehp_queue_power_work(p_slot, ENABLE_REQ);
}

/*
Expand All @@ -330,60 +318,43 @@ static void handle_surprise_event(struct slot *p_slot)
static void handle_link_event(struct slot *p_slot, u32 event)
{
struct controller *ctrl = p_slot->ctrl;
struct power_work_info *info;

info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
__func__);
return;
}
info->p_slot = p_slot;
info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ;
INIT_WORK(&info->work, pciehp_power_thread);

switch (p_slot->state) {
case BLINKINGON_STATE:
case BLINKINGOFF_STATE:
cancel_delayed_work(&p_slot->work);
/* Fall through */
case STATIC_STATE:
p_slot->state = event == INT_LINK_UP ?
POWERON_STATE : POWEROFF_STATE;
queue_work(p_slot->wq, &info->work);
pciehp_queue_power_work(p_slot, event == INT_LINK_UP ?
ENABLE_REQ : DISABLE_REQ);
break;
case POWERON_STATE:
if (event == INT_LINK_UP) {
ctrl_info(ctrl,
"Link Up event ignored on slot(%s): already powering on\n",
slot_name(p_slot));
kfree(info);
} else {
ctrl_info(ctrl,
"Link Down event queued on slot(%s): currently getting powered on\n",
slot_name(p_slot));
p_slot->state = POWEROFF_STATE;
queue_work(p_slot->wq, &info->work);
pciehp_queue_power_work(p_slot, DISABLE_REQ);
}
break;
case POWEROFF_STATE:
if (event == INT_LINK_UP) {
ctrl_info(ctrl,
"Link Up event queued on slot(%s): currently getting powered off\n",
slot_name(p_slot));
p_slot->state = POWERON_STATE;
queue_work(p_slot->wq, &info->work);
pciehp_queue_power_work(p_slot, ENABLE_REQ);
} else {
ctrl_info(ctrl,
"Link Down event ignored on slot(%s): already powering off\n",
slot_name(p_slot));
kfree(info);
}
break;
default:
ctrl_err(ctrl, "ignoring invalid state %#x on slot(%s)\n",
p_slot->state, slot_name(p_slot));
kfree(info);
break;
}
}
Expand Down
Loading

0 comments on commit 1f9a30e

Please sign in to comment.