Commit 37577505 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'please-pull-root_bus_hotplug' of...

Merge tag 'please-pull-root_bus_hotplug' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux

Pull ia64 IOH hotplug fixes from Tony Luck:
 "Series to fix IOH hotplug in ia64"

* tag 'please-pull-root_bus_hotplug' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux:
  PCI: Replace printks with appropriate pr_*()
  PCI/IA64: introduce probe_pci_root_info() to manage _CRS resource
  PCI/IA64: Add host bridge resource release for _CRS path
  PCI/IA64: fix memleak for create pci root bus fail
  PCI/IA64: Allocate pci_root_info instead of using stack
  PCI/IA64: embed pci hostbridge resources into pci_root_info
  PCI/IA64: SN: use normal resource instead of pci_window
  PCI/IA64: SN: remove sn_pci_window_fixup()
parents 04bbc8e1 c4cbf6b9
...@@ -89,9 +89,9 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus, ...@@ -89,9 +89,9 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
#define pci_legacy_read platform_pci_legacy_read #define pci_legacy_read platform_pci_legacy_read
#define pci_legacy_write platform_pci_legacy_write #define pci_legacy_write platform_pci_legacy_write
struct pci_window { struct iospace_resource {
struct resource resource; struct list_head list;
u64 offset; struct resource res;
}; };
struct pci_controller { struct pci_controller {
...@@ -100,12 +100,10 @@ struct pci_controller { ...@@ -100,12 +100,10 @@ struct pci_controller {
int segment; int segment;
int node; /* nearest node with memory or -1 for global allocation */ int node; /* nearest node with memory or -1 for global allocation */
unsigned int windows;
struct pci_window *window;
void *platform_data; void *platform_data;
}; };
#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata) #define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment) #define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment)
......
This diff is collapsed.
...@@ -118,76 +118,26 @@ static void __init sn_fixup_ionodes(void) ...@@ -118,76 +118,26 @@ static void __init sn_fixup_ionodes(void)
} }
/* /*
* sn_pci_legacy_window_fixup - Create PCI controller windows for * sn_pci_legacy_window_fixup - Setup PCI resources for
* legacy IO and MEM space. This needs to * legacy IO and MEM space. This needs to
* be done here, as the PROM does not have * be done here, as the PROM does not have
* ACPI support defining the root buses * ACPI support defining the root buses
* and their resources (_CRS), * and their resources (_CRS),
*/ */
static void static void
sn_legacy_pci_window_fixup(struct pci_controller *controller, sn_legacy_pci_window_fixup(struct resource *res,
u64 legacy_io, u64 legacy_mem) u64 legacy_io, u64 legacy_mem)
{ {
controller->window = kcalloc(2, sizeof(struct pci_window), res[0].name = "legacy_io";
GFP_KERNEL); res[0].flags = IORESOURCE_IO;
BUG_ON(controller->window == NULL); res[0].start = legacy_io;
controller->window[0].offset = legacy_io; res[0].end = res[0].start + 0xffff;
controller->window[0].resource.name = "legacy_io"; res[0].parent = &ioport_resource;
controller->window[0].resource.flags = IORESOURCE_IO; res[1].name = "legacy_mem";
controller->window[0].resource.start = legacy_io; res[1].flags = IORESOURCE_MEM;
controller->window[0].resource.end = res[1].start = legacy_mem;
controller->window[0].resource.start + 0xffff; res[1].end = res[1].start + (1024 * 1024) - 1;
controller->window[0].resource.parent = &ioport_resource; res[1].parent = &iomem_resource;
controller->window[1].offset = legacy_mem;
controller->window[1].resource.name = "legacy_mem";
controller->window[1].resource.flags = IORESOURCE_MEM;
controller->window[1].resource.start = legacy_mem;
controller->window[1].resource.end =
controller->window[1].resource.start + (1024 * 1024) - 1;
controller->window[1].resource.parent = &iomem_resource;
controller->windows = 2;
}
/*
* sn_pci_window_fixup() - Create a pci_window for each device resource.
* It will setup pci_windows for use by
* pcibios_bus_to_resource(), pcibios_resource_to_bus(),
* etc.
*/
static void
sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
s64 * pci_addrs)
{
struct pci_controller *controller = PCI_CONTROLLER(dev->bus);
unsigned int i;
unsigned int idx;
unsigned int new_count;
struct pci_window *new_window;
if (count == 0)
return;
idx = controller->windows;
new_count = controller->windows + count;
new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL);
BUG_ON(new_window == NULL);
if (controller->window) {
memcpy(new_window, controller->window,
sizeof(struct pci_window) * controller->windows);
kfree(controller->window);
}
/* Setup a pci_window for each device resource. */
for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
if (pci_addrs[i] == -1)
continue;
new_window[idx].offset = dev->resource[i].start - pci_addrs[i];
new_window[idx].resource = dev->resource[i];
idx++;
}
controller->windows = new_count;
controller->window = new_window;
} }
/* /*
...@@ -199,9 +149,7 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, ...@@ -199,9 +149,7 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
void void
sn_io_slot_fixup(struct pci_dev *dev) sn_io_slot_fixup(struct pci_dev *dev)
{ {
unsigned int count = 0;
int idx; int idx;
s64 pci_addrs[PCI_ROM_RESOURCE + 1];
unsigned long addr, end, size, start; unsigned long addr, end, size, start;
struct pcidev_info *pcidev_info; struct pcidev_info *pcidev_info;
struct sn_irq_info *sn_irq_info; struct sn_irq_info *sn_irq_info;
...@@ -229,7 +177,6 @@ sn_io_slot_fixup(struct pci_dev *dev) ...@@ -229,7 +177,6 @@ sn_io_slot_fixup(struct pci_dev *dev)
for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
if (!pcidev_info->pdi_pio_mapped_addr[idx]) { if (!pcidev_info->pdi_pio_mapped_addr[idx]) {
pci_addrs[idx] = -1;
continue; continue;
} }
...@@ -237,11 +184,8 @@ sn_io_slot_fixup(struct pci_dev *dev) ...@@ -237,11 +184,8 @@ sn_io_slot_fixup(struct pci_dev *dev)
end = dev->resource[idx].end; end = dev->resource[idx].end;
size = end - start; size = end - start;
if (size == 0) { if (size == 0) {
pci_addrs[idx] = -1;
continue; continue;
} }
pci_addrs[idx] = start;
count++;
addr = pcidev_info->pdi_pio_mapped_addr[idx]; addr = pcidev_info->pdi_pio_mapped_addr[idx];
addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET;
dev->resource[idx].start = addr; dev->resource[idx].start = addr;
...@@ -276,11 +220,6 @@ sn_io_slot_fixup(struct pci_dev *dev) ...@@ -276,11 +220,6 @@ sn_io_slot_fixup(struct pci_dev *dev)
IORESOURCE_ROM_BIOS_COPY; IORESOURCE_ROM_BIOS_COPY;
} }
} }
/* Create a pci_window in the pci_controller struct for
* each device resource.
*/
if (count > 0)
sn_pci_window_fixup(dev, count, pci_addrs);
sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
} }
...@@ -297,8 +236,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) ...@@ -297,8 +236,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
s64 status = 0; s64 status = 0;
struct pci_controller *controller; struct pci_controller *controller;
struct pcibus_bussoft *prom_bussoft_ptr; struct pcibus_bussoft *prom_bussoft_ptr;
struct resource *res;
LIST_HEAD(resources); LIST_HEAD(resources);
int i;
status = sal_get_pcibus_info((u64) segment, (u64) busnum, status = sal_get_pcibus_info((u64) segment, (u64) busnum,
(u64) ia64_tpa(&prom_bussoft_ptr)); (u64) ia64_tpa(&prom_bussoft_ptr));
...@@ -310,19 +249,23 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) ...@@ -310,19 +249,23 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
BUG_ON(!controller); BUG_ON(!controller);
controller->segment = segment; controller->segment = segment;
res = kcalloc(2, sizeof(struct resource), GFP_KERNEL);
BUG_ON(!res);
/* /*
* Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup(). * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup().
* (platform_data will be overwritten later in sn_common_bus_fixup()) * (platform_data will be overwritten later in sn_common_bus_fixup())
*/ */
controller->platform_data = prom_bussoft_ptr; controller->platform_data = prom_bussoft_ptr;
sn_legacy_pci_window_fixup(controller, sn_legacy_pci_window_fixup(res,
prom_bussoft_ptr->bs_legacy_io, prom_bussoft_ptr->bs_legacy_io,
prom_bussoft_ptr->bs_legacy_mem); prom_bussoft_ptr->bs_legacy_mem);
for (i = 0; i < controller->windows; i++) pci_add_resource_offset(&resources, &res[0],
pci_add_resource_offset(&resources, prom_bussoft_ptr->bs_legacy_io);
&controller->window[i].resource, pci_add_resource_offset(&resources, &res[1],
controller->window[i].offset); prom_bussoft_ptr->bs_legacy_mem);
bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
&resources); &resources);
if (bus == NULL) if (bus == NULL)
...@@ -333,7 +276,7 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) ...@@ -333,7 +276,7 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
return; return;
error_return: error_return:
kfree(res);
kfree(controller); kfree(controller);
return; return;
} }
......
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