Commit 081f3698 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pci-v4.4-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull PCI fixes from Bjorn Helgaas:
 "Here are a few fixes I'd like to have in v4.4: a generic one for sysfs
  and three for HiSilicon and DesignWare host controllers.

  Summary:

  NUMA:
   - Prevent out of bounds access in numa_node override (Mathias Krause)

  HiSilicon host bridge driver:
   - Fix deferred probing (Arnd Bergmann)

  Synopsys DesignWare host bridge driver:
   - Remove incorrect io_base assignment (Stanimir Varbanov)
   - Move align_resource function pointer to pci_host_bridge structure
     (Gabriele Paoloni)"

* tag 'pci-v4.4-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
  ARM/PCI: Move align_resource function pointer to pci_host_bridge structure
  PCI: hisi: Fix deferred probing
  PCI: designware: Remove incorrect io_base assignment
  PCI: Prevent out of bounds access in numa_node override
parents 8003a573 7c7a0e94
...@@ -17,11 +17,6 @@ ...@@ -17,11 +17,6 @@
#include <asm/mach/pci.h> #include <asm/mach/pci.h>
static int debug_pci; static int debug_pci;
static resource_size_t (*align_resource)(struct pci_dev *dev,
const struct resource *res,
resource_size_t start,
resource_size_t size,
resource_size_t align) = NULL;
/* /*
* We can't use pci_get_device() here since we are * We can't use pci_get_device() here since we are
...@@ -461,7 +456,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, ...@@ -461,7 +456,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
sys->busnr = busnr; sys->busnr = busnr;
sys->swizzle = hw->swizzle; sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq; sys->map_irq = hw->map_irq;
align_resource = hw->align_resource;
INIT_LIST_HEAD(&sys->resources); INIT_LIST_HEAD(&sys->resources);
if (hw->private_data) if (hw->private_data)
...@@ -470,6 +464,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, ...@@ -470,6 +464,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
ret = hw->setup(nr, sys); ret = hw->setup(nr, sys);
if (ret > 0) { if (ret > 0) {
struct pci_host_bridge *host_bridge;
ret = pcibios_init_resources(nr, sys); ret = pcibios_init_resources(nr, sys);
if (ret) { if (ret) {
kfree(sys); kfree(sys);
...@@ -491,6 +487,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, ...@@ -491,6 +487,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
busnr = sys->bus->busn_res.end + 1; busnr = sys->bus->busn_res.end + 1;
list_add(&sys->node, head); list_add(&sys->node, head);
host_bridge = pci_find_host_bridge(sys->bus);
host_bridge->align_resource = hw->align_resource;
} else { } else {
kfree(sys); kfree(sys);
if (ret < 0) if (ret < 0)
...@@ -578,14 +577,18 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, ...@@ -578,14 +577,18 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
{ {
struct pci_dev *dev = data; struct pci_dev *dev = data;
resource_size_t start = res->start; resource_size_t start = res->start;
struct pci_host_bridge *host_bridge;
if (res->flags & IORESOURCE_IO && start & 0x300) if (res->flags & IORESOURCE_IO && start & 0x300)
start = (start + 0x3ff) & ~0x3ff; start = (start + 0x3ff) & ~0x3ff;
start = (start + align - 1) & ~(align - 1); start = (start + align - 1) & ~(align - 1);
if (align_resource) host_bridge = pci_find_host_bridge(dev->bus);
return align_resource(dev, res, start, size, align);
if (host_bridge->align_resource)
return host_bridge->align_resource(dev, res,
start, size, align);
return start; return start;
} }
......
...@@ -440,7 +440,6 @@ int dw_pcie_host_init(struct pcie_port *pp) ...@@ -440,7 +440,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
ret, pp->io); ret, pp->io);
continue; continue;
} }
pp->io_base = pp->io->start;
break; break;
case IORESOURCE_MEM: case IORESOURCE_MEM:
pp->mem = win->res; pp->mem = win->res;
......
...@@ -111,7 +111,7 @@ static struct pcie_host_ops hisi_pcie_host_ops = { ...@@ -111,7 +111,7 @@ static struct pcie_host_ops hisi_pcie_host_ops = {
.link_up = hisi_pcie_link_up, .link_up = hisi_pcie_link_up,
}; };
static int __init hisi_add_pcie_port(struct pcie_port *pp, static int hisi_add_pcie_port(struct pcie_port *pp,
struct platform_device *pdev) struct platform_device *pdev)
{ {
int ret; int ret;
...@@ -139,7 +139,7 @@ static int __init hisi_add_pcie_port(struct pcie_port *pp, ...@@ -139,7 +139,7 @@ static int __init hisi_add_pcie_port(struct pcie_port *pp,
return 0; return 0;
} }
static int __init hisi_pcie_probe(struct platform_device *pdev) static int hisi_pcie_probe(struct platform_device *pdev)
{ {
struct hisi_pcie *hisi_pcie; struct hisi_pcie *hisi_pcie;
struct pcie_port *pp; struct pcie_port *pp;
......
...@@ -216,7 +216,10 @@ static ssize_t numa_node_store(struct device *dev, ...@@ -216,7 +216,10 @@ static ssize_t numa_node_store(struct device *dev,
if (ret) if (ret)
return ret; return ret;
if (node >= MAX_NUMNODES || !node_online(node)) if ((node < 0 && node != NUMA_NO_NODE) || node >= MAX_NUMNODES)
return -EINVAL;
if (node != NUMA_NO_NODE && !node_online(node))
return -EINVAL; return -EINVAL;
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
......
...@@ -337,6 +337,4 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) ...@@ -337,6 +337,4 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
} }
#endif #endif
struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
#endif /* DRIVERS_PCI_H */ #endif /* DRIVERS_PCI_H */
...@@ -412,9 +412,18 @@ struct pci_host_bridge { ...@@ -412,9 +412,18 @@ struct pci_host_bridge {
void (*release_fn)(struct pci_host_bridge *); void (*release_fn)(struct pci_host_bridge *);
void *release_data; void *release_data;
unsigned int ignore_reset_delay:1; /* for entire hierarchy */ unsigned int ignore_reset_delay:1; /* for entire hierarchy */
/* Resource alignment requirements */
resource_size_t (*align_resource)(struct pci_dev *dev,
const struct resource *res,
resource_size_t start,
resource_size_t size,
resource_size_t align);
}; };
#define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev) #define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev)
struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
void pci_set_host_bridge_release(struct pci_host_bridge *bridge, void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
void (*release_fn)(struct pci_host_bridge *), void (*release_fn)(struct pci_host_bridge *),
void *release_data); void *release_data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment