* Please pull 'next' branch of 4xx tree
From: Josh Boyer @ 2010-02-12 13:02 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
Hi Ben,
Some updates for various boards from Stefan. I don't have anything else at
the moment, so I thought I'd get this rolled into your tree now.
josh
The following changes since commit b919ee827e048826786fd7e889a2b04f63382fe6:
Anton Blanchard (1):
powerpc: Only print clockevent settings once
are available in the git repository at:
ssh://master.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git next
Stefan Roese (6):
powerpc/44x: Fix L2-cache support for 460GT
powerpc/44x: Add MTD support (NOR FLASH) to Katmai dts
powerpc/44x: Update Arches dts
powerpc/44x: Update Glacier dts
powerpc/44x: Add MTD support to katmai defconfig
powerpc/40x: Add support for PPC40x boards with > 512MB SDRAM
arch/powerpc/boot/dts/arches.dts | 12 ++++
arch/powerpc/boot/dts/glacier.dts | 76 ++++++++++++++++++++---
arch/powerpc/boot/dts/katmai.dts | 71 ++++++++++++++++------
arch/powerpc/configs/44x/katmai_defconfig | 94 +++++++++++++++++++++++++++--
arch/powerpc/mm/40x_mmu.c | 4 +-
arch/powerpc/sysdev/ppc4xx_soc.c | 3 +-
6 files changed, 224 insertions(+), 36 deletions(-)
^ permalink raw reply
* [PATCH v3 1/7] PCI: split up pci_read_bridge_bases()
From: Bjorn Helgaas @ 2010-02-12 16:59 UTC (permalink / raw)
To: Jesse Barnes
Cc: Matthew Garrett, Tony Luck, linuxppc-dev, linux-pci, Peter Haight,
Gary Hade, linux-kernel, Linus Torvalds, linux-acpi,
linux-am33-list, linux-alpha, Ingo Molnar, Yinghai Lu,
Larry Finger
In-Reply-To: <20100212165532.19522.47240.stgit@bob.kio>
No functional change; this breaks up pci_read_bridge_bases() into separate
pieces for the I/O, memory, and prefetchable memory windows, similar to how
Yinghai recently split up pci_setup_bridge() in 68e84ff3bdc.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
drivers/pci/probe.c | 54 +++++++++++++++++++++++++++++++++++++--------------
1 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index d300943..3d305c1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -281,26 +281,12 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
}
}
-void __devinit pci_read_bridge_bases(struct pci_bus *child)
+static void __devinit pci_read_bridge_io(struct pci_bus *child)
{
struct pci_dev *dev = child->self;
u8 io_base_lo, io_limit_lo;
- u16 mem_base_lo, mem_limit_lo;
unsigned long base, limit;
struct resource *res;
- int i;
-
- if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */
- return;
-
- dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n",
- child->secondary, child->subordinate,
- dev->transparent ? " (subtractive decode)": "");
-
- if (dev->transparent) {
- for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
- child->resource[i] = child->parent->resource[i - 3];
- }
res = child->resource[0];
pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
@@ -328,6 +314,14 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
" bridge window [io %04lx - %04lx] reg reading\n",
base, limit);
}
+}
+
+static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
+{
+ struct pci_dev *dev = child->self;
+ u16 mem_base_lo, mem_limit_lo;
+ unsigned long base, limit;
+ struct resource *res;
res = child->resource[1];
pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
@@ -344,6 +338,14 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
" bridge window [mem 0x%08lx - 0x%08lx] reg reading\n",
base, limit + 0xfffff);
}
+}
+
+static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
+{
+ struct pci_dev *dev = child->self;
+ u16 mem_base_lo, mem_limit_lo;
+ unsigned long base, limit;
+ struct resource *res;
res = child->resource[2];
pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
@@ -389,6 +391,28 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
}
}
+void __devinit pci_read_bridge_bases(struct pci_bus *child)
+{
+ struct pci_dev *dev = child->self;
+ int i;
+
+ if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */
+ return;
+
+ dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n",
+ child->secondary, child->subordinate,
+ dev->transparent ? " (subtractive decode)": "");
+
+ if (dev->transparent) {
+ for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
+ child->resource[i] = child->parent->resource[i - 3];
+ }
+
+ pci_read_bridge_io(child);
+ pci_read_bridge_mmio(child);
+ pci_read_bridge_mmio_pref(child);
+}
+
static struct pci_bus * pci_alloc_bus(void)
{
struct pci_bus *b;
^ permalink raw reply related
* [PATCH v3 3/7] PCI: replace bus resource table with a list
From: Bjorn Helgaas @ 2010-02-12 17:00 UTC (permalink / raw)
To: Jesse Barnes
Cc: Matthew Garrett, Tony Luck, linuxppc-dev, linux-pci, Peter Haight,
Gary Hade, linux-kernel, Linus Torvalds, linux-acpi,
linux-am33-list, linux-alpha, Ingo Molnar, Yinghai Lu,
Larry Finger
In-Reply-To: <20100212165532.19522.47240.stgit@bob.kio>
Previously we used a table of size PCI_BUS_NUM_RESOURCES for resources
forwarded to a bus by its upstream bridge. We've increased this size
several times when the table overflowed.
But there's no good limit on the number of resources for a bus because
host bridges can forward any number of ranges to their secondary buses
(i.e., PCI root buses).
This patch replaces the fixed-size table with a list.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
arch/alpha/kernel/pci.c | 5 +-
arch/ia64/pci/pci.c | 20 ++----
arch/mn10300/unit-asb2305/pci.c | 7 +-
arch/powerpc/kernel/pci-common.c | 26 +++++---
arch/powerpc/kernel/pci_64.c | 18 +++---
arch/powerpc/kernel/pci_of_scan.c | 7 +-
arch/powerpc/platforms/fsl_uli1575.c | 15 +++--
arch/x86/pci/acpi.c | 33 +---------
arch/x86/pci/bus_numa.c | 9 ++-
arch/x86/pci/bus_numa.h | 3 -
drivers/eisa/pci_eisa.c | 4 +
drivers/pci/bus.c | 50 ++++++++++++++-
drivers/pci/hotplug/shpchp_sysfs.c | 15 ++---
drivers/pci/pci.c | 6 +-
drivers/pci/probe.c | 35 ++++++-----
drivers/pci/setup-bus.c | 111 ++++++++++++++++------------------
drivers/pcmcia/rsrc_nonstatic.c | 7 +-
drivers/pcmcia/yenta_socket.c | 7 +-
include/linux/pci.h | 16 +++--
19 files changed, 219 insertions(+), 175 deletions(-)
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index c9ab94e..e4bb1f3 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -292,8 +292,9 @@ pcibios_fixup_bus(struct pci_bus *bus)
u32 sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0;
unsigned long end;
- bus->resource[0] = hose->io_space;
- bus->resource[1] = hose->mem_space;
+ pci_bus_remove_resources(bus);
+ pci_bus_add_resource(bus, hose->io_space, 0);
+ pci_bus_add_resource(bus, hose->mem_space, 0);
/* Adjust hose mem_space limit to prevent PCI allocations
in the iommu windows. */
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 783c83b..ad64554 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -320,9 +320,9 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
static void __devinit
pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
{
- int i, j;
+ int i;
- j = 0;
+ pci_bus_remove_resources(bus);
for (i = 0; i < ctrl->windows; i++) {
struct resource *res = &ctrl->window[i].resource;
/* HP's firmware has a hack to work around a Windows bug.
@@ -330,13 +330,7 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
if ((res->flags & IORESOURCE_MEM) &&
(res->end - res->start < 16))
continue;
- if (j >= PCI_BUS_NUM_RESOURCES) {
- dev_warn(&bus->dev,
- "ignoring host bridge window %pR (no space)\n",
- res);
- continue;
- }
- bus->resource[j++] = res;
+ pci_bus_add_resource(bus, res, 0);
}
}
@@ -451,13 +445,15 @@ EXPORT_SYMBOL(pcibios_bus_to_resource);
static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
{
- unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+ unsigned int type_mask = IORESOURCE_IO | IORESOURCE_MEM;
struct resource *devr = &dev->resource[idx];
+ struct pci_bus_resource *bus_res;
if (!dev->bus)
return 0;
- for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
- struct resource *busr = dev->bus->resource[i];
+
+ list_for_each_entry(bus_res, &dev->bus->resources, list) {
+ struct resource *busr = bus_res->res;
if (!busr || ((busr->flags ^ devr->flags) & type_mask))
continue;
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
index 2cb7e75..187adcc 100644
--- a/arch/mn10300/unit-asb2305/pci.c
+++ b/arch/mn10300/unit-asb2305/pci.c
@@ -332,12 +332,13 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
{
unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
struct resource *devr = &dev->resource[idx];
+ struct pci_bus_resource *bus_res;
if (dev->bus) {
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- struct resource *busr = dev->bus->resource[i];
+ list_for_each_entry(bus_res, &dev->bus->resources, list) {
+ struct resource *busr = bus_res->res;
- if (!busr || (busr->flags ^ devr->flags) & type_mask)
+ if ((busr->flags ^ devr->flags) & type_mask)
continue;
if (devr->start &&
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index e640810..d75546e 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1042,14 +1042,15 @@ static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
/* Fixup resources of a PCI<->PCI bridge */
static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
{
+ struct pci_bus_resource *bus_res;
struct resource *res;
- int i;
+ int i = -1;
struct pci_dev *dev = bus->self;
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
- if ((res = bus->resource[i]) == NULL)
- continue;
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ i++;
+ res = bus_res->res;
if (!res->flags)
continue;
if (i >= 3 && bus->self->transparent)
@@ -1271,15 +1272,17 @@ static int reparent_resources(struct resource *parent,
void pcibios_allocate_bus_resources(struct pci_bus *bus)
{
struct pci_bus *b;
- int i;
+ int i = -1;
+ struct pci_bus_resource *bus_res;
struct resource *res, *pr;
pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
pci_domain_nr(bus), bus->number);
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
- if ((res = bus->resource[i]) == NULL || !res->flags
- || res->start > res->end || res->parent)
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ i++;
+ res = bus_res->res;
+ if (!res->flags || res->start > res->end || res->parent)
continue;
if (bus->parent == NULL)
pr = (res->flags & IORESOURCE_IO) ?
@@ -1579,8 +1582,11 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
struct resource *res;
int i;
+ pci_bus_remove_resources(bus);
+
/* Hookup PHB IO resource */
- bus->resource[0] = res = &hose->io_resource;
+ res = &hose->io_resource;
+ pci_bus_add_resource(bus, res, 0);
if (!res->flags) {
printk(KERN_WARNING "PCI: I/O resource not set for host"
@@ -1615,7 +1621,7 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
res->flags = IORESOURCE_MEM;
#endif /* CONFIG_PPC32 */
}
- bus->resource[i+1] = res;
+ pci_bus_add_resource(bus, res, 0);
pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i,
(unsigned long long)res->start,
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index ccf56ac..155a2bf 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -82,6 +82,7 @@ subsys_initcall(pcibios_init);
int pcibios_unmap_io_space(struct pci_bus *bus)
{
+ struct pci_dev *bridge = bus->self;
struct pci_controller *hose;
WARN_ON(bus == NULL);
@@ -96,13 +97,13 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
* Note: If we ever support P2P hotplug on Book3E, we'll have
* to do an appropriate TLB flush here too
*/
- if (bus->self) {
+ if (bridge) {
#ifdef CONFIG_PPC_STD_MMU_64
- struct resource *res = bus->resource[0];
+ struct resource *res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
#endif
pr_debug("IO unmapping for PCI-PCI bridge %s\n",
- pci_name(bus->self));
+ pci_name(bridge));
#ifdef CONFIG_PPC_STD_MMU_64
__flush_hash_table_range(&init_mm, res->start + _IO_BASE,
@@ -132,6 +133,7 @@ EXPORT_SYMBOL_GPL(pcibios_unmap_io_space);
int __devinit pcibios_map_io_space(struct pci_bus *bus)
{
+ struct pci_dev *bridge = bus->self;
struct vm_struct *area;
unsigned long phys_page;
unsigned long size_page;
@@ -143,12 +145,14 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
/* If this not a PHB, nothing to do, page tables still exist and
* thus HPTEs will be faulted in when needed
*/
- if (bus->self) {
+ if (bridge) {
+ struct resource *res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
+
pr_debug("IO mapping for PCI-PCI bridge %s\n",
- pci_name(bus->self));
+ pci_name(bridge));
pr_debug(" virt=0x%016llx...0x%016llx\n",
- bus->resource[0]->start + _IO_BASE,
- bus->resource[0]->end + _IO_BASE);
+ res->start + _IO_BASE,
+ res->end + _IO_BASE);
return 0;
}
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 4aa1740..521ad52 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -242,10 +242,11 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
/* parse ranges property */
/* PCI #address-cells == 3 and #size-cells == 2 always */
+ pci_bus_remove_resources(bus);
res = &dev->resource[PCI_BRIDGE_RESOURCES];
for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
res->flags = 0;
- bus->resource[i] = res;
+ pci_bus_add_resource(bus, res, PCI_POSITIVE_DECODE);
++res;
}
i = 1;
@@ -255,7 +256,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
if (flags == 0 || size == 0)
continue;
if (flags & IORESOURCE_IO) {
- res = bus->resource[0];
+ res = &dev->resource[PCI_BRIDGE_RESOURCES + 0];
if (res->flags) {
printk(KERN_ERR "PCI: ignoring extra I/O range"
" for bridge %s\n", node->full_name);
@@ -267,7 +268,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
" for bridge %s\n", node->full_name);
continue;
}
- res = bus->resource[i];
+ res = &dev->resource[PCI_BRIDGE_RESOURCES + i];
++i;
}
res->start = of_read_number(&ranges[1], 2);
diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c
index fd23a1d..04c546f 100644
--- a/arch/powerpc/platforms/fsl_uli1575.c
+++ b/arch/powerpc/platforms/fsl_uli1575.c
@@ -222,6 +222,8 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev)
int i;
u8 *dummy;
struct pci_bus *bus = dev->bus;
+ struct pci_bus_resource *bus_res;
+ struct resource *res;
resource_size_t end = 0;
for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCES+3; i++) {
@@ -230,13 +232,14 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev)
end = pci_resource_end(dev, i);
}
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- if ((bus->resource[i]) &&
- (bus->resource[i]->flags & IORESOURCE_MEM)) {
- if (bus->resource[i]->end == end)
- dummy = ioremap(bus->resource[i]->start, 0x4);
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ res = bus_res->res;
+
+ if (res->flags & IORESOURCE_MEM) {
+ if (res->end == end)
+ dummy = ioremap(res->start, 0x4);
else
- dummy = ioremap(bus->resource[i]->end - 3, 0x4);
+ dummy = ioremap(res->end - 3, 0x4);
if (dummy) {
in_8(dummy);
iounmap(dummy);
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 959e548..a2f8cdb 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -45,20 +45,6 @@ count_resource(struct acpi_resource *acpi_res, void *data)
return AE_OK;
}
-static int
-bus_has_transparent_bridge(struct pci_bus *bus)
-{
- struct pci_dev *dev;
-
- list_for_each_entry(dev, &bus->devices, bus_list) {
- u16 class = dev->class >> 8;
-
- if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent)
- return true;
- }
- return false;
-}
-
static void
align_resource(struct acpi_device *bridge, struct resource *res)
{
@@ -92,12 +78,8 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
acpi_status status;
unsigned long flags;
struct resource *root;
- int max_root_bus_resources = PCI_BUS_NUM_RESOURCES;
u64 start, end;
- if (bus_has_transparent_bridge(info->bus))
- max_root_bus_resources -= 3;
-
status = resource_to_addr(acpi_res, &addr);
if (!ACPI_SUCCESS(status))
return AE_OK;
@@ -115,15 +97,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
start = addr.minimum + addr.translation_offset;
end = start + addr.address_length - 1;
- if (info->res_num >= max_root_bus_resources) {
- if (pci_probe & PCI_USE__CRS)
- printk(KERN_WARNING "PCI: Failed to allocate "
- "0x%lx-0x%lx from %s for %s due to _CRS "
- "returning more than %d resource descriptors\n",
- (unsigned long) start, (unsigned long) end,
- root->name, info->name, max_root_bus_resources);
- return AE_OK;
- }
res = &info->res[info->res_num];
res->name = info->name;
@@ -143,7 +116,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
dev_err(&info->bridge->dev,
"can't allocate host bridge window %pR\n", res);
} else {
- info->bus->resource[info->res_num] = res;
+ pci_bus_add_resource(info->bus, res, 0);
info->res_num++;
if (addr.translation_offset)
dev_info(&info->bridge->dev, "host bridge window %pR "
@@ -164,7 +137,9 @@ get_current_resources(struct acpi_device *device, int busnum,
struct pci_root_info info;
size_t size;
- if (!(pci_probe & PCI_USE__CRS))
+ if (pci_probe & PCI_USE__CRS)
+ pci_bus_remove_resources(bus);
+ else
dev_info(&device->dev,
"ignoring host bridge windows from ACPI; "
"boot with \"pci=use_crs\" to use them\n");
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c
index f939d60..6999970 100644
--- a/arch/x86/pci/bus_numa.c
+++ b/arch/x86/pci/bus_numa.c
@@ -12,10 +12,12 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b)
int i;
int j;
struct pci_root_info *info;
+ struct pci_bus_resource *bus_res;
/* don't go for it if _CRS is used already */
- if (b->resource[0] != &ioport_resource ||
- b->resource[1] != &iomem_resource)
+ bus_res = list_first_entry(&b->resources, struct pci_bus_resource,
+ list);
+ if (bus_res->res != &ioport_resource)
return;
if (!pci_root_num)
@@ -36,13 +38,14 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b)
printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
b->number);
+ pci_bus_remove_resources(b);
info = &pci_root_info[i];
for (j = 0; j < info->res_num; j++) {
struct resource *res;
struct resource *root;
res = &info->res[j];
- b->resource[j] = res;
+ pci_bus_add_resource(b, res, 0);
if (res->flags & IORESOURCE_IO)
root = &ioport_resource;
else
diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h
index adbc23f..731b64e 100644
--- a/arch/x86/pci/bus_numa.h
+++ b/arch/x86/pci/bus_numa.h
@@ -2,8 +2,7 @@
/*
* sub bus (transparent) will use entres from 3 to store extra from
- * root, so need to make sure we have enough slot there, Should we
- * increase PCI_BUS_NUM_RESOURCES?
+ * root, so need to make sure we have enough slot there.
*/
#define RES_NUM 16
struct pci_root_info {
diff --git a/drivers/eisa/pci_eisa.c b/drivers/eisa/pci_eisa.c
index 0dd0f63..562eaa4 100644
--- a/drivers/eisa/pci_eisa.c
+++ b/drivers/eisa/pci_eisa.c
@@ -31,8 +31,8 @@ static int __init pci_eisa_init(struct pci_dev *pdev,
}
pci_eisa_root.dev = &pdev->dev;
- pci_eisa_root.res = pdev->bus->resource[0];
- pci_eisa_root.bus_base_addr = pdev->bus->resource[0]->start;
+ pci_eisa_root.res = &pdev->resource[PCI_BRIDGE_RESOURCES + 0];
+ pci_eisa_root.bus_base_addr = pdev->resource[PCI_BRIDGE_RESOURCES + 0].start;
pci_eisa_root.slots = EISA_MAX_SLOTS;
pci_eisa_root.dma_mask = pdev->dma_mask;
dev_set_drvdata(pci_eisa_root.dev, &pci_eisa_root);
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index a26135b..9725846 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -17,6 +17,49 @@
#include "pci.h"
+void pci_bus_add_resource(struct pci_bus *bus, struct resource *res,
+ unsigned int flags)
+{
+ struct pci_bus_resource *bus_res;
+
+ bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL);
+ if (!bus_res) {
+ dev_err(&bus->dev, "can't add %pR resource\n", res);
+ return;
+ }
+
+ bus_res->res = res;
+ bus_res->flags = flags;
+ list_add_tail(&bus_res->list, &bus->resources);
+}
+
+struct resource *pci_bus_get_resource(struct pci_bus *bus, unsigned long flags,
+ int num)
+{
+ struct pci_bus_resource *bus_res;
+ struct resource *res;
+
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ if (!(bus_res->flags & PCI_POSITIVE_DECODE))
+ continue;
+
+ res = bus_res->res;
+ if (((res->flags & flags) == flags) && num-- == 0)
+ return res;
+ }
+ return NULL;
+}
+
+void pci_bus_remove_resources(struct pci_bus *bus)
+{
+ struct pci_bus_resource *bus_res, *tmp;
+
+ list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) {
+ list_del(&bus_res->list);
+ kfree(bus_res);
+ }
+}
+
/**
* pci_bus_alloc_resource - allocate a resource from a parent bus
* @bus: PCI bus
@@ -42,7 +85,8 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
resource_size_t),
void *alignf_data)
{
- int i, ret = -ENOMEM;
+ int ret = -ENOMEM;
+ struct pci_bus_resource *bus_res;
resource_size_t max = -1;
type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
@@ -51,8 +95,8 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
if (!(res->flags & IORESOURCE_MEM_64))
max = PCIBIOS_MAX_MEM_32;
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- struct resource *r = bus->resource[i];
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ struct resource *r = bus_res->res;
if (!r)
continue;
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
index 29fa9d2..e1a9d6a 100644
--- a/drivers/pci/hotplug/shpchp_sysfs.c
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -39,16 +39,17 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha
{
struct pci_dev *pdev;
char * out = buf;
- int index, busnr;
+ int busnr;
struct resource *res;
struct pci_bus *bus;
+ struct pci_bus_resource *bus_res;
pdev = container_of (dev, struct pci_dev, dev);
bus = pdev->subordinate;
out += sprintf(buf, "Free resources: memory\n");
- for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
- res = bus->resource[index];
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ res = bus_res->res;
if (res && (res->flags & IORESOURCE_MEM) &&
!(res->flags & IORESOURCE_PREFETCH)) {
out += sprintf(out, "start = %8.8llx, "
@@ -58,8 +59,8 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha
}
}
out += sprintf(out, "Free resources: prefetchable memory\n");
- for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
- res = bus->resource[index];
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ res = bus_res->res;
if (res && (res->flags & IORESOURCE_MEM) &&
(res->flags & IORESOURCE_PREFETCH)) {
out += sprintf(out, "start = %8.8llx, "
@@ -69,8 +70,8 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha
}
}
out += sprintf(out, "Free resources: IO\n");
- for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
- res = bus->resource[index];
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ res = bus_res->res;
if (res && (res->flags & IORESOURCE_IO)) {
out += sprintf(out, "start = %8.8llx, "
"length = %8.8llx\n",
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d62a5de..60a6a88 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -385,11 +385,11 @@ struct resource *
pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
{
const struct pci_bus *bus = dev->bus;
- int i;
+ struct pci_bus_resource *bus_res;
struct resource *best = NULL;
- for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- struct resource *r = bus->resource[i];
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ struct resource *r = bus_res->res;
if (!r)
continue;
if (res->start && !(res->start >= r->start && res->end <= r->end))
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 06ff76d..c5ecd3c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -89,6 +89,7 @@ static void release_pcibus_dev(struct device *dev)
if (pci_bus->bridge)
put_device(pci_bus->bridge);
+ pci_bus_remove_resources(pci_bus);
kfree(pci_bus);
}
@@ -288,7 +289,8 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
unsigned long base, limit;
struct resource *res;
- res = child->resource[0];
+ res = &dev->resource[PCI_BRIDGE_RESOURCES + 0];
+
pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
base = (io_base_lo & PCI_IO_RANGE_MASK) << 8;
@@ -323,7 +325,8 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
unsigned long base, limit;
struct resource *res;
- res = child->resource[1];
+ res = &dev->resource[PCI_BRIDGE_RESOURCES + 1];
+
pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
@@ -347,7 +350,8 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
unsigned long base, limit;
struct resource *res;
- res = child->resource[2];
+ res = &dev->resource[PCI_BRIDGE_RESOURCES + 2];
+
pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
@@ -394,7 +398,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
void __devinit pci_read_bridge_bases(struct pci_bus *child)
{
struct pci_dev *dev = child->self;
- int i;
+ struct pci_bus_resource *bus_res;
if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */
return;
@@ -408,12 +412,11 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
pci_read_bridge_mmio_pref(child);
if (dev->transparent) {
- for (i = 3; i < PCI_BUS_NUM_RESOURCES; i++) {
- child->resource[i] = child->parent->resource[i - 3];
- if (child->resource[i])
- dev_printk(KERN_DEBUG, &dev->dev,
- " bridge window %pR (subtractive decode)\n",
- child->resource[i]);
+ list_for_each_entry(bus_res, &child->parent->resources, list) {
+ pci_bus_add_resource(child, bus_res->res, 0);
+ dev_printk(KERN_DEBUG, &dev->dev,
+ " bridge window %pR (subtractive decode)\n",
+ bus_res->res);
}
}
}
@@ -428,6 +431,7 @@ static struct pci_bus * pci_alloc_bus(void)
INIT_LIST_HEAD(&b->children);
INIT_LIST_HEAD(&b->devices);
INIT_LIST_HEAD(&b->slots);
+ INIT_LIST_HEAD(&b->resources);
b->max_bus_speed = PCI_SPEED_UNKNOWN;
b->cur_bus_speed = PCI_SPEED_UNKNOWN;
}
@@ -573,6 +577,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
{
struct pci_bus *child;
int i;
+ struct resource *res;
/*
* Allocate a new bus, and inherit stuff from the parent..
@@ -611,9 +616,11 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
/* Set up default resource pointers and names.. */
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
- child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];
- child->resource[i]->name = child->name;
+ res = &bridge->resource[PCI_BRIDGE_RESOURCES + i];
+ res->name = child->name;
+ pci_bus_add_resource(child, res, PCI_POSITIVE_DECODE);
}
+
bridge->subordinate = child;
return child;
@@ -1445,8 +1452,8 @@ struct pci_bus * pci_create_bus(struct device *parent,
pci_create_legacy_files(b);
b->number = b->secondary = bus;
- b->resource[0] = &ioport_resource;
- b->resource[1] = &iomem_resource;
+ pci_bus_add_resource(b, &ioport_resource, 0);
+ pci_bus_add_resource(b, &iomem_resource, 0);
return b;
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 743ed8c..8a3b512 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -138,58 +138,53 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus,
__assign_resources_sorted(&head, fail_head);
}
-void pci_setup_cardbus(struct pci_bus *bus)
+static void pci_setup_cardbus_window(struct pci_dev *bridge, char *type, int n,
+ struct resource *res, int base_reg, int limit_reg)
{
- struct pci_dev *bridge = bus->self;
- struct resource *res;
struct pci_bus_region region;
+ u32 base, limit;
- dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
- bus->secondary, bus->subordinate);
-
- res = bus->resource[0];
- pcibios_resource_to_bus(bridge, ®ion, res);
- if (res->flags & IORESOURCE_IO) {
+ if (!res) {
/*
- * The IO resource is allocated a range twice as large as it
- * would normally need. This allows us to set both IO regs.
+ * Maybe we should disable the window, but the previous
+ * code left it alone.
*/
- dev_info(&bridge->dev, " bridge window %pR\n", res);
- pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
- region.start);
- pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
- region.end);
+ pci_read_config_dword(bridge, base_reg, &base);
+ pci_read_config_dword(bridge, limit_reg, &limit);
+ dev_info(&bridge->dev, " no %s%d resource, leaving bridge programmed with base %#08x limit %#08x\n",
+ type, n, base, limit);
+ return;
}
- res = bus->resource[1];
pcibios_resource_to_bus(bridge, ®ion, res);
- if (res->flags & IORESOURCE_IO) {
- dev_info(&bridge->dev, " bridge window %pR\n", res);
- pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
- region.start);
- pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
- region.end);
- }
+ pci_write_config_dword(bridge, base_reg, region.start);
+ pci_write_config_dword(bridge, limit_reg, region.end);
+ dev_info(&bridge->dev, " bridge window %pR\n", res);
+}
- res = bus->resource[2];
- pcibios_resource_to_bus(bridge, ®ion, res);
- if (res->flags & IORESOURCE_MEM) {
- dev_info(&bridge->dev, " bridge window %pR\n", res);
- pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
- region.start);
- pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
- region.end);
- }
+void pci_setup_cardbus(struct pci_bus *bus)
+{
+ struct pci_dev *bridge = bus->self;
- res = bus->resource[3];
- pcibios_resource_to_bus(bridge, ®ion, res);
- if (res->flags & IORESOURCE_MEM) {
- dev_info(&bridge->dev, " bridge window %pR\n", res);
- pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
- region.start);
- pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
- region.end);
- }
+ dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
+ bus->secondary, bus->subordinate);
+
+ /*
+ * The IO resource is allocated a range twice as large as it
+ * would normally need. This allows us to set both IO regs.
+ */
+ pci_setup_cardbus_window(bridge, "io", 0,
+ pci_bus_get_resource(bus, IORESOURCE_IO, 0),
+ PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
+ pci_setup_cardbus_window(bridge, "io", 1,
+ pci_bus_get_resource(bus, IORESOURCE_IO, 1),
+ PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
+ pci_setup_cardbus_window(bridge, "mem", 0,
+ pci_bus_get_resource(bus, IORESOURCE_MEM, 0),
+ PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
+ pci_setup_cardbus_window(bridge, "mem", 1,
+ pci_bus_get_resource(bus, IORESOURCE_MEM, 1),
+ PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
}
EXPORT_SYMBOL(pci_setup_cardbus);
@@ -212,9 +207,9 @@ static void pci_setup_bridge_io(struct pci_bus *bus)
u32 l, io_upper16;
/* Set up the top and bottom of the PCI I/O segment for this bus. */
- res = bus->resource[0];
- pcibios_resource_to_bus(bridge, ®ion, res);
- if (res->flags & IORESOURCE_IO) {
+ res = pci_bus_get_resource(bus, IORESOURCE_IO, 0);
+ if (res) {
+ pcibios_resource_to_bus(bridge, ®ion, res);
pci_read_config_dword(bridge, PCI_IO_BASE, &l);
l &= 0xffff0000;
l |= (region.start >> 8) & 0x00f0;
@@ -244,9 +239,9 @@ static void pci_setup_bridge_mmio(struct pci_bus *bus)
u32 l;
/* Set up the top and bottom of the PCI Memory segment for this bus. */
- res = bus->resource[1];
- pcibios_resource_to_bus(bridge, ®ion, res);
- if (res->flags & IORESOURCE_MEM) {
+ res = pci_bus_get_resource(bus, IORESOURCE_MEM, 0);
+ if (res) {
+ pcibios_resource_to_bus(bridge, ®ion, res);
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
dev_info(&bridge->dev, " bridge window %pR\n", res);
@@ -271,9 +266,9 @@ static void pci_setup_bridge_mmio_pref(struct pci_bus *bus)
/* Set up PREF base/limit. */
bu = lu = 0;
- res = bus->resource[2];
- pcibios_resource_to_bus(bridge, ®ion, res);
- if (res->flags & IORESOURCE_PREFETCH) {
+ res = pci_bus_get_resource(bus, IORESOURCE_MEM | IORESOURCE_PREFETCH, 0);
+ if (res) {
+ pcibios_resource_to_bus(bridge, ®ion, res);
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
if (res->flags & IORESOURCE_MEM_64) {
@@ -382,13 +377,13 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
have non-NULL parent resource). */
static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type)
{
- int i;
+ struct pci_bus_resource *bus_res;
struct resource *r;
unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_PREFETCH;
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- r = bus->resource[i];
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ r = bus_res->res;
if (r == &ioport_resource || r == &iomem_resource)
continue;
if (r && (r->flags & type_mask) == type && !r->parent)
@@ -803,15 +798,15 @@ static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus,
static void pci_bus_dump_res(struct pci_bus *bus)
{
- int i;
+ struct pci_bus_resource *bus_res;
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- struct resource *res = bus->resource[i];
+ list_for_each_entry(bus_res, &bus->resources, list) {
+ struct resource *res = bus_res->res;
if (!res || !res->end || !res->flags)
continue;
- dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res);
+ dev_printk(KERN_DEBUG, &bus->dev, "resource %pR\n", res);
}
}
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 45d75dc..cd15c51 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -786,8 +786,9 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
#ifdef CONFIG_PCI
static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
{
+ struct pci_bus_resource *bus_res;
struct resource *res;
- int i, done = 0;
+ int done = 0;
if (!s->cb_dev || !s->cb_dev->bus)
return -ENODEV;
@@ -803,8 +804,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
return -EINVAL;
#endif
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- res = s->cb_dev->bus->resource[i];
+ list_for_each_entry(bus_res, &s->cb_dev->bus->resources, list) {
+ res = bus_res->res;
if (!res)
continue;
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index e4d12ac..9c5a80e 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -649,9 +649,10 @@ static int yenta_search_one_res(struct resource *root, struct resource *res,
static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
u32 min)
{
- int i;
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- struct resource *root = socket->dev->bus->resource[i];
+ struct pci_bus_resource *bus_res;
+
+ list_for_each_entry(bus_res, &socket->dev->bus->resources, list) {
+ struct resource *root = bus_res->res;
if (!root)
continue;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index df2a12f..44e2f0e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -363,9 +363,13 @@ static inline void pci_add_saved_cap(struct pci_dev *pci_dev,
hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
}
-#ifndef PCI_BUS_NUM_RESOURCES
-#define PCI_BUS_NUM_RESOURCES 16
-#endif
+#define PCI_POSITIVE_DECODE 1
+
+struct pci_bus_resource {
+ struct list_head list;
+ struct resource *res;
+ unsigned int flags;
+};
#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
@@ -376,8 +380,7 @@ struct pci_bus {
struct list_head devices; /* list of devices on this bus */
struct pci_dev *self; /* bridge device as seen by parent */
struct list_head slots; /* list of slots on this bus */
- struct resource *resource[PCI_BUS_NUM_RESOURCES];
- /* address space routed to this bus */
+ struct list_head resources; /* address space routed to this bus */
struct pci_ops *ops; /* configuration access functions */
void *sysdata; /* hook for sys-specific extension */
@@ -828,6 +831,9 @@ int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *);
void pci_release_selected_regions(struct pci_dev *, int);
/* drivers/pci/bus.c */
+void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags);
+struct resource *pci_bus_get_resource(struct pci_bus *bus, unsigned long flags, int num);
+void pci_bus_remove_resources(struct pci_bus *bus);
int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
struct resource *res, resource_size_t size,
resource_size_t align, resource_size_t min,
^ permalink raw reply related
* [PATCH v3 5/7] PCI: make disabled window printk style match the enabled ones
From: Bjorn Helgaas @ 2010-02-12 17:00 UTC (permalink / raw)
To: Jesse Barnes
Cc: Matthew Garrett, Tony Luck, linuxppc-dev, linux-pci, Peter Haight,
Gary Hade, linux-kernel, Linus Torvalds, linux-acpi,
linux-am33-list, linux-alpha, Ingo Molnar, Yinghai Lu,
Larry Finger
In-Reply-To: <20100212165532.19522.47240.stgit@bob.kio>
No functional change; this just tweaks the changes from 349e1823a405
so the new printks for disabled PCI-to-PCI bridge windows match the
ones for the enabled windows.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
drivers/pci/probe.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c5ecd3c..dacdeae 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -313,7 +313,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
} else {
dev_printk(KERN_DEBUG, &dev->dev,
- " bridge window [io %04lx - %04lx] reg reading\n",
+ " bridge window [io %#06lx-%#06lx] (disabled)\n",
base, limit);
}
}
@@ -338,7 +338,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
} else {
dev_printk(KERN_DEBUG, &dev->dev,
- " bridge window [mem 0x%08lx - 0x%08lx] reg reading\n",
+ " bridge window [mem %#010lx-%#010lx] (disabled)\n",
base, limit + 0xfffff);
}
}
@@ -390,7 +390,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
} else {
dev_printk(KERN_DEBUG, &dev->dev,
- " bridge window [mem 0x%08lx - %08lx pref] reg reading\n",
+ " bridge window [mem %#010lx-%#010lx pref] (disabled)\n",
base, limit + 0xfffff);
}
}
^ permalink raw reply related
* [PATCH v3 7/7] PCI: reference bridge window resources explicitly
From: Bjorn Helgaas @ 2010-02-12 17:00 UTC (permalink / raw)
To: Jesse Barnes
Cc: Matthew Garrett, Tony Luck, linuxppc-dev, linux-pci, Peter Haight,
Gary Hade, linux-kernel, Linus Torvalds, linux-acpi,
linux-am33-list, linux-alpha, Ingo Molnar, Yinghai Lu,
Larry Finger
In-Reply-To: <20100212165532.19522.47240.stgit@bob.kio>
No functional change; just be more explicit about this mapping for
bridge resources:
bridge->res[PCI_BRIDGE_RESOURCES+0]: I/O window (or CB I/O 0 window)
bridge->res[PCI_BRIDGE_RESOURCES+1]: mem window (or CB I/O 1 window)
bridge->res[PCI_BRIDGE_RESOURCES+2]: pref mem window (or CB mem 0 window)
bridge->res[PCI_BRIDGE_RESOURCES+3]: CB mem 1 window
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
arch/powerpc/kernel/pci_64.c | 4 +--
arch/powerpc/kernel/pci_of_scan.c | 9 ++++--
drivers/pci/probe.c | 6 ++--
drivers/pci/quirks.c | 4 +--
drivers/pci/setup-bus.c | 57 +++++++++++++++++++++----------------
drivers/pcmcia/yenta_socket.c | 39 +++++++++++++++----------
include/linux/pci.h | 11 ++++++-
7 files changed, 78 insertions(+), 52 deletions(-)
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 155a2bf..044a4bd 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -99,7 +99,7 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
*/
if (bridge) {
#ifdef CONFIG_PPC_STD_MMU_64
- struct resource *res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
+ struct resource *res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
#endif
pr_debug("IO unmapping for PCI-PCI bridge %s\n",
@@ -146,7 +146,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
* thus HPTEs will be faulted in when needed
*/
if (bridge) {
- struct resource *res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
+ struct resource *res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
pr_debug("IO mapping for PCI-PCI bridge %s\n",
pci_name(bridge));
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 521ad52..39487c3 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -256,19 +256,22 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
if (flags == 0 || size == 0)
continue;
if (flags & IORESOURCE_IO) {
- res = &dev->resource[PCI_BRIDGE_RESOURCES + 0];
+ res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
if (res->flags) {
printk(KERN_ERR "PCI: ignoring extra I/O range"
" for bridge %s\n", node->full_name);
continue;
}
} else {
- if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
+ if (i == 1)
+ res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
+ else if (i == 2)
+ res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
+ else {
printk(KERN_ERR "PCI: too many memory ranges"
" for bridge %s\n", node->full_name);
continue;
}
- res = &dev->resource[PCI_BRIDGE_RESOURCES + i];
++i;
}
res->start = of_read_number(&ranges[1], 2);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 04e7e97..6d693fb 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -289,7 +289,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
unsigned long base, limit;
struct resource *res;
- res = &dev->resource[PCI_BRIDGE_RESOURCES + 0];
+ res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
@@ -325,7 +325,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
unsigned long base, limit;
struct resource *res;
- res = &dev->resource[PCI_BRIDGE_RESOURCES + 1];
+ res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
@@ -350,7 +350,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
unsigned long base, limit;
struct resource *res;
- res = &dev->resource[PCI_BRIDGE_RESOURCES + 2];
+ res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 790eb69..197c6c6 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1907,7 +1907,7 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
u16 en1k;
u8 io_base_lo, io_limit_lo;
unsigned long base, limit;
- struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES;
+ struct resource *res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
pci_read_config_word(dev, 0x40, &en1k);
@@ -1934,7 +1934,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io);
static void __devinit quirk_p64h2_1k_io_fix_iobl(struct pci_dev *dev)
{
u16 en1k, iobl_adr, iobl_adr_1k;
- struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES;
+ struct resource *res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
pci_read_config_word(dev, 0x40, &en1k);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 8a3b512..182fe54 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -324,8 +324,7 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
struct pci_dev *bridge = bus->self;
struct resource *b_res;
- b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
- b_res[1].flags |= IORESOURCE_MEM;
+ bridge->resource[PCI_BRIDGE_MEM_WINDOW].flags |= IORESOURCE_MEM;
pci_read_config_word(bridge, PCI_IO_BASE, &io);
if (!io) {
@@ -334,12 +333,15 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
}
if (io)
- b_res[0].flags |= IORESOURCE_IO;
+ bridge->resource[PCI_BRIDGE_IO_WINDOW].flags |= IORESOURCE_IO;
+
/* DECchip 21050 pass 2 errata: the bridge may miss an address
disconnect boundary by one PCI data phase.
Workaround: do not use prefetching on this device. */
if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001)
return;
+
+ b_res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
if (!pmem) {
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE,
@@ -348,16 +350,16 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
}
if (pmem) {
- b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ b_res->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
PCI_PREF_RANGE_TYPE_64) {
- b_res[2].flags |= IORESOURCE_MEM_64;
- b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
+ b_res->flags |= IORESOURCE_MEM_64;
+ b_res->flags |= PCI_PREF_RANGE_TYPE_64;
}
}
/* double check if bridge does support 64 bit pref */
- if (b_res[2].flags & IORESOURCE_MEM_64) {
+ if (b_res->flags & IORESOURCE_MEM_64) {
u32 mem_base_hi, tmp;
pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32,
&mem_base_hi);
@@ -365,7 +367,7 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
0xffffffff);
pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
if (!tmp)
- b_res[2].flags &= ~IORESOURCE_MEM_64;
+ b_res->flags &= ~IORESOURCE_MEM_64;
pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
mem_base_hi);
}
@@ -544,20 +546,22 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
static void pci_bus_size_cardbus(struct pci_bus *bus)
{
struct pci_dev *bridge = bus->self;
- struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
+ struct resource *b_res;
u16 ctrl;
/*
* Reserve some resources for CardBus. We reserve
* a fixed amount of bus space for CardBus bridges.
*/
- b_res[0].start = 0;
- b_res[0].end = pci_cardbus_io_size - 1;
- b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
+ b_res = &bridge->resource[PCI_CB_BRIDGE_IO_0_WINDOW];
+ b_res->start = 0;
+ b_res->end = pci_cardbus_io_size - 1;
+ b_res->flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
- b_res[1].start = 0;
- b_res[1].end = pci_cardbus_io_size - 1;
- b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
+ b_res = &bridge->resource[PCI_CB_BRIDGE_IO_1_WINDOW];
+ b_res->start = 0;
+ b_res->end = pci_cardbus_io_size - 1;
+ b_res->flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
/*
* Check whether prefetchable memory is supported
@@ -576,17 +580,20 @@ static void pci_bus_size_cardbus(struct pci_bus *bus)
* twice the size.
*/
if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
- b_res[2].start = 0;
- b_res[2].end = pci_cardbus_mem_size - 1;
- b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN;
-
- b_res[3].start = 0;
- b_res[3].end = pci_cardbus_mem_size - 1;
- b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
+ b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_0_WINDOW];
+ b_res->start = 0;
+ b_res->end = pci_cardbus_mem_size - 1;
+ b_res->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN;
+
+ b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_1_WINDOW];
+ b_res->start = 0;
+ b_res->end = pci_cardbus_mem_size - 1;
+ b_res->flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
} else {
- b_res[3].start = 0;
- b_res[3].end = pci_cardbus_mem_size * 2 - 1;
- b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
+ b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_1_WINDOW];
+ b_res->start = 0;
+ b_res->end = pci_cardbus_mem_size * 2 - 1;
+ b_res->flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
}
}
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 9c5a80e..dc55592 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -673,7 +673,7 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
struct pci_bus_region region;
unsigned mask;
- res = dev->resource + PCI_BRIDGE_RESOURCES + nr;
+ res = &dev->resource[nr];
/* Already allocated? */
if (res->parent)
return 0;
@@ -690,7 +690,7 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
region.end = config_readl(socket, addr_end) | ~mask;
if (region.start && region.end > region.start && !override_bios) {
pcibios_bus_to_resource(dev, res, ®ion);
- if (pci_claim_resource(dev, PCI_BRIDGE_RESOURCES + nr) == 0)
+ if (pci_claim_resource(dev, nr) == 0)
return 0;
dev_printk(KERN_INFO, &dev->dev,
"Preassigned resource %d busy or not available, "
@@ -731,32 +731,39 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
static void yenta_allocate_resources(struct yenta_socket *socket)
{
int program = 0;
- program += yenta_allocate_res(socket, 0, IORESOURCE_IO,
- PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
- program += yenta_allocate_res(socket, 1, IORESOURCE_IO,
- PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
- program += yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
+ program += yenta_allocate_res(socket, PCI_CB_BRIDGE_IO_0_WINDOW,
+ IORESOURCE_IO, PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
+ program += yenta_allocate_res(socket, PCI_CB_BRIDGE_IO_1_WINDOW,
+ IORESOURCE_IO, PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
+ program += yenta_allocate_res(socket, PCI_CB_BRIDGE_MEM_0_WINDOW,
+ IORESOURCE_MEM|IORESOURCE_PREFETCH,
PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
- program += yenta_allocate_res(socket, 3, IORESOURCE_MEM,
+ program += yenta_allocate_res(socket, PCI_CB_BRIDGE_MEM_1_WINDOW,
+ IORESOURCE_MEM,
PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
if (program)
pci_setup_cardbus(socket->dev->subordinate);
}
+static void yenta_free_resource(struct yenta_socket *socket, int nr)
+{
+ struct resource *res;
+
+ res = &socket->dev->resource[nr];
+ if (res->start != 0 && res->end != 0)
+ release_resource(res);
+ res->start = res->end = res->flags = 0;
+}
/*
* Free the bridge mappings for the device..
*/
static void yenta_free_resources(struct yenta_socket *socket)
{
- int i;
- for (i = 0; i < 4; i++) {
- struct resource *res;
- res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
- if (res->start != 0 && res->end != 0)
- release_resource(res);
- res->start = res->end = res->flags = 0;
- }
+ yenta_free_resource(socket, PCI_CB_BRIDGE_IO_0_WINDOW);
+ yenta_free_resource(socket, PCI_CB_BRIDGE_IO_1_WINDOW);
+ yenta_free_resource(socket, PCI_CB_BRIDGE_MEM_0_WINDOW);
+ yenta_free_resource(socket, PCI_CB_BRIDGE_MEM_1_WINDOW);
}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 44e2f0e..edcabd6 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -101,7 +101,16 @@ enum {
#endif
/* resources assigned to buses behind the bridge */
-#define PCI_BRIDGE_RESOURCE_NUM 4
+#define PCI_BRIDGE_IO_WINDOW (PCI_BRIDGE_RESOURCES + 0)
+#define PCI_BRIDGE_MEM_WINDOW (PCI_BRIDGE_RESOURCES + 1)
+#define PCI_BRIDGE_PREF_MEM_WINDOW (PCI_BRIDGE_RESOURCES + 2)
+
+#define PCI_CB_BRIDGE_IO_0_WINDOW (PCI_BRIDGE_RESOURCES + 0)
+#define PCI_CB_BRIDGE_IO_1_WINDOW (PCI_BRIDGE_RESOURCES + 1)
+#define PCI_CB_BRIDGE_MEM_0_WINDOW (PCI_BRIDGE_RESOURCES + 2)
+#define PCI_CB_BRIDGE_MEM_1_WINDOW (PCI_BRIDGE_RESOURCES + 3)
+
+#define PCI_BRIDGE_RESOURCE_NUM 4 /* max of P2P, cardbus */
PCI_BRIDGE_RESOURCES,
PCI_BRIDGE_RESOURCE_END = PCI_BRIDGE_RESOURCES +
^ permalink raw reply related
* [PATCH v3 2/7] PCI: read bridge windows before filling in subtractive decode resources
From: Bjorn Helgaas @ 2010-02-12 16:59 UTC (permalink / raw)
To: Jesse Barnes
Cc: Matthew Garrett, Tony Luck, linuxppc-dev, linux-pci, Peter Haight,
Gary Hade, linux-kernel, Linus Torvalds, linux-acpi,
linux-am33-list, linux-alpha, Ingo Molnar, Yinghai Lu,
Larry Finger
In-Reply-To: <20100212165532.19522.47240.stgit@bob.kio>
No functional change; this fills in the bus subtractive decode resources
after reading the bridge window information rather than before. Also,
print out the subtractive decode resources as we already do for the
positive decode windows.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
drivers/pci/probe.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 3d305c1..06ff76d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -403,14 +403,19 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
child->secondary, child->subordinate,
dev->transparent ? " (subtractive decode)": "");
- if (dev->transparent) {
- for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
- child->resource[i] = child->parent->resource[i - 3];
- }
-
pci_read_bridge_io(child);
pci_read_bridge_mmio(child);
pci_read_bridge_mmio_pref(child);
+
+ if (dev->transparent) {
+ for (i = 3; i < PCI_BUS_NUM_RESOURCES; i++) {
+ child->resource[i] = child->parent->resource[i - 3];
+ if (child->resource[i])
+ dev_printk(KERN_DEBUG, &dev->dev,
+ " bridge window %pR (subtractive decode)\n",
+ child->resource[i]);
+ }
+ }
}
static struct pci_bus * pci_alloc_bus(void)
^ permalink raw reply related
* [PATCH v3 6/7] PCI: break out primary/secondary/subordinate for readability
From: Bjorn Helgaas @ 2010-02-12 17:00 UTC (permalink / raw)
To: Jesse Barnes
Cc: Matthew Garrett, Tony Luck, linuxppc-dev, linux-pci, Peter Haight,
Gary Hade, linux-kernel, Linus Torvalds, linux-acpi,
linux-am33-list, linux-alpha, Ingo Molnar, Yinghai Lu,
Larry Finger
In-Reply-To: <20100212165532.19522.47240.stgit@bob.kio>
No functional change; just add names for the primary/secondary/subordinate
bus numbers read from config space rather than repeatedly masking/shifting.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
drivers/pci/probe.c | 24 ++++++++++++++----------
1 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dacdeae..04e7e97 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -671,16 +671,20 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
u32 buses, i, j = 0;
u16 bctl;
+ u8 primary, secondary, subordinate;
int broken = 0;
pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
+ primary = buses & 0xFF;
+ secondary = (buses >> 8) & 0xFF;
+ subordinate = (buses >> 16) & 0xFF;
- dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n",
- buses & 0xffffff, pass);
+ dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
+ secondary, subordinate, pass);
/* Check if setup is sensible at all */
if (!pass &&
- ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) {
+ (primary != bus->number || secondary <= bus->number)) {
dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n");
broken = 1;
}
@@ -691,15 +695,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
- if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) {
- unsigned int cmax, busnr;
+ if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
+ !is_cardbus && !broken) {
+ unsigned int cmax;
/*
* Bus already configured by firmware, process it in the first
* pass and just note the configuration.
*/
if (pass)
goto out;
- busnr = (buses >> 8) & 0xFF;
/*
* If we already got to this bus through a different bridge,
@@ -708,13 +712,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
* However, we continue to descend down the hierarchy and
* scan remaining child buses.
*/
- child = pci_find_bus(pci_domain_nr(bus), busnr);
+ child = pci_find_bus(pci_domain_nr(bus), secondary);
if (!child) {
- child = pci_add_new_bus(bus, dev, busnr);
+ child = pci_add_new_bus(bus, dev, secondary);
if (!child)
goto out;
- child->primary = buses & 0xFF;
- child->subordinate = (buses >> 16) & 0xFF;
+ child->primary = primary;
+ child->subordinate = subordinate;
child->bridge_ctl = bctl;
}
^ permalink raw reply related
* [PATCH v3 0/7] PCI: try "pci=use_crs" again
From: Bjorn Helgaas @ 2010-02-12 16:59 UTC (permalink / raw)
To: Jesse Barnes
Cc: Matthew Garrett, Tony Luck, linuxppc-dev, linux-pci, Peter Haight,
Gary Hade, linux-kernel, Linus Torvalds, linux-acpi,
linux-am33-list, linux-alpha, Ingo Molnar, Yinghai Lu,
Larry Finger
Historically, Linux has assumed a single PCI host bridge, with that bridge
claiming all the address space left after RAM and legacy devices are taken out.
If the system contains multiple host bridges, we can no longer operate under
that assumption. We have to know what parts of the address space are claimed
by each bridge so that when we assign resources to a PCI device, we take them
from a range claimed by the upstream host bridge.
On x86 and ia64, we use ACPI to enumerate all the PCI host bridges in the
system, and part of the host bridge description is the "_CRS" (current resource
settings" property, which lists the address space used by the bridge. On x86,
we currently ignore most of the _CRS information. This patch series changes
this, so we will use _CRS to learn about the host bridge windows.
Since most x86 machines with multiple host bridges are relatively new, this
series only turns this on for machines with BIOS dates of 2008 or newer.
Changes from v2 to v3:
- Fix alpha, powerpc, and mn10300 references to pci_bus resource table
- Turn on "pci=use_crs" for 2008 and newer, not 2010 and newer
- Remove Toshiba A355 quirk (BIOS date is 2009, so automatically included)
- Remove IBM x3850 and x3950 quirks (BIOS dates in 2008, so automatically
included)
- Leave IBM x3800 quirk (pre-2008 BIOS)
- Use "bool" for pci_use_crs (new to me, but I see akpm suggesting it)
- Reorder so the important patches are first
Changes from v1 to v2:
- Rebase to be6e9f7853e
- Add patch to clean up "disabled window" printk
- Add bugzilla reference comment in use_crs DMI quirk
---
Bjorn Helgaas (7):
PCI: split up pci_read_bridge_bases()
PCI: read bridge windows before filling in subtractive decode resources
PCI: replace bus resource table with a list
x86/PCI: use host bridge _CRS info by default on 2008 and newer machines
PCI: make disabled window printk style match the enabled ones
PCI: break out primary/secondary/subordinate for readability
PCI: reference bridge window resources explicitly
Documentation/kernel-parameters.txt | 8 +-
arch/alpha/kernel/pci.c | 5 +
arch/ia64/include/asm/acpi.h | 1
arch/ia64/pci/pci.c | 20 ++--
arch/mn10300/unit-asb2305/pci.c | 7 +
arch/powerpc/kernel/pci-common.c | 26 +++--
arch/powerpc/kernel/pci_64.c | 18 ++--
arch/powerpc/kernel/pci_of_scan.c | 12 ++
arch/powerpc/platforms/fsl_uli1575.c | 15 ++-
arch/x86/include/asm/pci_x86.h | 1
arch/x86/pci/acpi.c | 82 ++++++++++-------
arch/x86/pci/bus_numa.c | 9 +-
arch/x86/pci/bus_numa.h | 3 -
arch/x86/pci/common.c | 3 +
drivers/acpi/pci_root.c | 1
drivers/eisa/pci_eisa.c | 4 -
drivers/pci/bus.c | 50 ++++++++++
drivers/pci/hotplug/shpchp_sysfs.c | 15 ++-
drivers/pci/pci.c | 6 +
drivers/pci/probe.c | 108 +++++++++++++++-------
drivers/pci/quirks.c | 4 -
drivers/pci/setup-bus.c | 168 +++++++++++++++++-----------------
drivers/pcmcia/rsrc_nonstatic.c | 7 +
drivers/pcmcia/yenta_socket.c | 46 +++++----
include/acpi/acpi_drivers.h | 1
include/linux/pci.h | 27 ++++-
26 files changed, 401 insertions(+), 246 deletions(-)
^ permalink raw reply
* [PATCH v3 4/7] x86/PCI: use host bridge _CRS info by default on 2008 and newer machines
From: Bjorn Helgaas @ 2010-02-12 17:00 UTC (permalink / raw)
To: Jesse Barnes
Cc: Matthew Garrett, Tony Luck, linuxppc-dev, linux-pci, Peter Haight,
Gary Hade, linux-kernel, Linus Torvalds, linux-acpi,
linux-am33-list, linux-alpha, Ingo Molnar, Yinghai Lu,
Larry Finger
In-Reply-To: <20100212165532.19522.47240.stgit@bob.kio>
The main benefit of using ACPI host bridge window information is that
we can do better resource allocation in systems with multiple host bridges,
e.g., http://bugzilla.kernel.org/show_bug.cgi?id=14183
Sometimes we need _CRS information even if we only have one host bridge,
e.g., https://bugs.launchpad.net/ubuntu/+source/linux/+bug/341681
Most of these systems are relatively new, so this patch turns on
"pci=use_crs" only on machines with a BIOS date of 2008 or newer.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
Documentation/kernel-parameters.txt | 8 ++++-
arch/ia64/include/asm/acpi.h | 1 +
arch/x86/include/asm/pci_x86.h | 1 +
arch/x86/pci/acpi.c | 53 +++++++++++++++++++++++++++++++----
arch/x86/pci/common.c | 3 ++
drivers/acpi/pci_root.c | 1 +
include/acpi/acpi_drivers.h | 1 +
7 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 01e2a98..6913e9a 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1939,8 +1939,12 @@ and is between 256 and 4096 characters. It is defined in the file
IRQ routing is enabled.
noacpi [X86] Do not use ACPI for IRQ routing
or for PCI scanning.
- use_crs [X86] Use _CRS for PCI resource
- allocation.
+ use_crs [X86] Use PCI host bridge window information
+ from ACPI. On BIOSes from 2008 or later, this
+ is enabled by default. If you need to use this,
+ please report a bug.
+ nocrs [X86] Ignore PCI host bridge windows from ACPI.
+ If you need to use this, please report a bug.
routeirq Do IRQ routing for all PCI devices.
This is normally done in pci_enable_device(),
so this option is a temporary workaround
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h
index 7ae5889..7f2d7f2 100644
--- a/arch/ia64/include/asm/acpi.h
+++ b/arch/ia64/include/asm/acpi.h
@@ -97,6 +97,7 @@ ia64_acpi_release_global_lock (unsigned int *lock)
#endif
#define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
static inline void disable_acpi(void) { }
+static inline void pci_acpi_crs_quirks(void) { }
const char *acpi_get_sysname (void);
int acpi_request_vector (u32 int_type);
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index b4bf9a9..05b58cc 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -29,6 +29,7 @@
#define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000
#define PCI_HAS_IO_ECS 0x40000
#define PCI_NOASSIGN_ROMS 0x80000
+#define PCI_ROOT_NO_CRS 0x100000
extern unsigned int pci_probe;
extern unsigned long pirq_table_addr;
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index a2f8cdb..5f11ff6 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -15,6 +15,51 @@ struct pci_root_info {
int busnum;
};
+static bool pci_use_crs = true;
+
+static int __init set_use_crs(const struct dmi_system_id *id)
+{
+ pci_use_crs = true;
+ return 0;
+}
+
+static const struct dmi_system_id pci_use_crs_table[] __initconst = {
+ /* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
+ {
+ .callback = set_use_crs,
+ .ident = "IBM System x3800",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
+ },
+ },
+ {}
+};
+
+void __init pci_acpi_crs_quirks(void)
+{
+ int year;
+
+ if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008)
+ pci_use_crs = false;
+
+ dmi_check_system(pci_use_crs_table);
+
+ /*
+ * If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that
+ * takes precedence over anything we figured out above.
+ */
+ if (pci_probe & PCI_ROOT_NO_CRS)
+ pci_use_crs = false;
+ else if (pci_probe & PCI_USE__CRS)
+ pci_use_crs = true;
+
+ printk(KERN_INFO "PCI: %s host bridge windows from ACPI; "
+ "if necessary, use \"pci=%s\" and report a bug\n",
+ pci_use_crs ? "Using" : "Ignoring",
+ pci_use_crs ? "nocrs" : "use_crs");
+}
+
static acpi_status
resource_to_addr(struct acpi_resource *resource,
struct acpi_resource_address64 *addr)
@@ -106,7 +151,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
res->child = NULL;
align_resource(info->bridge, res);
- if (!(pci_probe & PCI_USE__CRS)) {
+ if (!pci_use_crs) {
dev_printk(KERN_DEBUG, &info->bridge->dev,
"host bridge window %pR (ignored)\n", res);
return AE_OK;
@@ -137,12 +182,8 @@ get_current_resources(struct acpi_device *device, int busnum,
struct pci_root_info info;
size_t size;
- if (pci_probe & PCI_USE__CRS)
+ if (pci_use_crs)
pci_bus_remove_resources(bus);
- else
- dev_info(&device->dev,
- "ignoring host bridge windows from ACPI; "
- "boot with \"pci=use_crs\" to use them\n");
info.bridge = device;
info.bus = bus;
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index d2552c6..3736176 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -520,6 +520,9 @@ char * __devinit pcibios_setup(char *str)
} else if (!strcmp(str, "use_crs")) {
pci_probe |= PCI_USE__CRS;
return NULL;
+ } else if (!strcmp(str, "nocrs")) {
+ pci_probe |= PCI_ROOT_NO_CRS;
+ return NULL;
} else if (!strcmp(str, "earlydump")) {
pci_early_dump_regs = 1;
return NULL;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 64ae2f2..4a46051 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -566,6 +566,7 @@ static int __init acpi_pci_root_init(void)
if (acpi_pci_disabled)
return 0;
+ pci_acpi_crs_quirks();
if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
return -ENODEV;
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index f4906f6..3a4767c 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -104,6 +104,7 @@ int acpi_pci_bind_root(struct acpi_device *device);
struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain,
int bus);
+void pci_acpi_crs_quirks(void);
/* --------------------------------------------------------------------------
Processor
^ permalink raw reply related
* Re: [PATCH v3 1/7] PCI: split up pci_read_bridge_bases()
From: Jesse Barnes @ 2010-02-12 21:26 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Matthew Garrett, Tony Luck, linuxppc-dev, linux-pci, Peter Haight,
Gary Hade, linux-kernel, Linus Torvalds, linux-acpi,
linux-am33-list, linux-alpha, Ingo Molnar, Yinghai Lu,
Larry Finger
In-Reply-To: <20100212165952.19522.19555.stgit@bob.kio>
On Fri, 12 Feb 2010 09:59:52 -0700
Bjorn Helgaas <bjorn.helgaas@hp.com> wrote:
>
> No functional change; this breaks up pci_read_bridge_bases() into
> separate pieces for the I/O, memory, and prefetchable memory windows,
> similar to how Yinghai recently split up pci_setup_bridge() in
> 68e84ff3bdc.
>
> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
> ---
Applied to my linux-next branch replacing the old ones, thanks Bjorn.
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply
* [PATCH] RapidIO: add support for mapping outbound memory
From: Micha Nelissen @ 2010-02-12 22:01 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Micha Nelissen
Signed-off-by: Micha Nelissen <micha.nelissen@prodrive.nl>
---
arch/powerpc/sysdev/fsl_rio.c | 175 ++++++++++++++++++++++++++++++++++++++++-
drivers/rapidio/rio-scan.c | 3 +-
drivers/rapidio/rio.c | 121 ++++++++++++++++++++++++++++-
include/linux/rio.h | 20 ++++-
include/linux/rio_drv.h | 5 +-
5 files changed, 315 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 757a83f..3290971 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -26,6 +26,8 @@
#include <asm/io.h>
+#define DRVNAME "fsl_rio"
+
/* RapidIO definition irq, which read from OF-tree */
#define IRQ_RIO_BELL(m) (((struct rio_priv *)(m->priv))->bellirq)
#define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq)
@@ -61,6 +63,49 @@
#define RIO_MIN_RX_RING_SIZE 2
#define RIO_MAX_RX_RING_SIZE 2048
+#define RIO_OUTB_ATMU_COUNT 9
+#define RIO_INB_ATMU_COUNT 4
+
+#define ROWTAR_LTGTID_MASK 0xC0000000
+#define ROWTAR_TREXAD_TID_MASK 0x3FC00000
+#define ROWTAR_TRAD_MASK 0x003FFFFF
+#define ROWTAR_LTGTID_SHIFT 30
+#define ROWTAR_TREXAD_TID_SHIFT 22
+#define ROWTAR_TRAD_HOP_SHIFT 12
+#define ROWTAR_LTGTID_VAL_SHIFT 8
+#define ROWTAR_LTGTID_VAL_MASK 3
+#define ROWTAR_TREXAD_TID_VAL_MASK 0xFF
+#define ROWTAR_TRAD_VAL_SHIFT 12
+#define ROWTAR_TRAD_MAINT_SHIFT 22
+#define ROWTEAR_LTGTID_VAL_SHIFT 10
+#define ROWBAR_BADD_VAL_SHIFT 12
+#define ROWBAR_BADD_MASK 0x000FFFFF
+#define ROWAR_TFLOWLVL_HIGHEST 0x08000000
+#define ROWAR_TFLOWLVL_HIGH 0x04000000
+#define ROWAR_NSEG_MASK 0x00C00000
+#define ROWAR_NSSEG_MASK 0x00300000
+#define ROWAR_SIZE_MASK 0x0000003F
+#define ROWAR_NSEG_SHIFT 22
+#define ROWAR_NSSEG_SHIFT 20
+#define ROWAR_SIZE_SHIFT 0
+#define ROWAR_ENABLE 0x80000000
+#define ROWAR_PCI 0x02000000
+#define ROWAR_NSEG_FOUR 0x00800000
+#define ROWAR_NSSEG_EIGHT 0x00300000
+#define ROWAR_RDTYP_NREAD 0x00040000
+#define ROWAR_RDTYP_MAINT_READ 0x00070000
+#define ROWAR_WRTYP_DOORBELL 0x00002000 /* parallel PHY only */
+#define ROWAR_WRTYP_NWRITE 0x00004000
+#define ROWAR_WRTYP_MAINT_WRITE 0x00007000
+#define ROWAR_SIZE_4KB 0x0000000B
+#define ROWAR_SIZE_4MB 0x00000015
+#define ROWAR_MAX_SEGS 4 /* must be power of 2 */
+#define ROWAR_MAX_SSEGS 8 /* idem */
+#define ROWAR_SIZE_MIN 4096
+#define ROWSAR_SGTGTDID_MASK 0x000000FF
+#define ROWSAR_RDTYP_NREAD 0x00400000
+#define ROWSAR_WRTYP_NWRITE 0x00040000
+
#define DOORBELL_DMR_DI 0x00000002
#define DOORBELL_DSR_TE 0x00000080
#define DOORBELL_DSR_QFI 0x00000010
@@ -80,7 +125,7 @@ struct rio_atmu_regs {
u32 rowbar;
u32 pad2;
u32 rowar;
- u32 pad3[3];
+ u32 rowsar[3];
};
struct rio_msg_regs {
@@ -171,6 +216,9 @@ struct rio_priv {
struct rio_dbell_ring dbell_ring;
struct rio_msg_tx_ring msg_tx_ring;
struct rio_msg_rx_ring msg_rx_ring;
+ int mem_atmu_segs[RIO_OUTB_ATMU_COUNT];
+ unsigned long law_start_free;
+ unsigned long law_end;
int bellirq;
int txirq;
int rxirq;
@@ -870,6 +918,129 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
return IRQ_HANDLED;
}
+int rio_open_outb_mem(struct rio_dev *rdev, int region, struct resource *res)
+{
+ struct rio_dev_mem *rmem;
+ resource_size_t start, len;
+ unsigned int seg, num_seg, num_sseg, used_segs, win_size_log;
+ unsigned long trad_start, sseg_len, win_start, win_size;
+ struct rio_mport *port = rdev->net->hport;
+ struct rio_priv *priv = port->priv;
+ u32 rowar, rowtar, rowsar;
+ u16 dev_destid, destid;
+ int i;
+
+ rmem = rio_find_dev_mem(rdev->vid, rdev->did, region);
+ if (!rmem)
+ return -ENODEV;
+
+ start = rmem->start;
+ len = rmem->len;
+ dev_destid = rdev->destid;
+ for (i = 0; i < RIO_OUTB_ATMU_COUNT; i++) {
+ rowar = in_be32(&priv->atmu_regs[i].rowar);
+ if (!(rowar & ROWAR_ENABLE))
+ continue;
+
+ rowtar = in_be32(&priv->atmu_regs[i].rowtar);
+ num_seg = 1 << ((rowar & ROWAR_NSEG_MASK) >> ROWAR_NSEG_SHIFT);
+ num_sseg = 1 << ((rowar & ROWAR_NSSEG_MASK) >> ROWAR_NSSEG_SHIFT);
+ sseg_len = (1 << ((rowar & ROWAR_SIZE_MASK) + 1)) / (num_seg * num_sseg);
+ /* trad_start is to be 33..2 */
+ trad_start = (rowtar & ROWTAR_TRAD_MASK) << (ROWTAR_TRAD_VAL_SHIFT - 2);
+ if (start < trad_start || start + (len >> 2) > trad_start + (sseg_len >> 2))
+ continue;
+
+ destid = (rowtar & ROWTAR_TREXAD_TID_MASK) >> ROWTAR_TREXAD_TID_SHIFT;
+ if (port->sys_size)
+ destid |= (((rowtar & ROWTAR_LTGTID_MASK) >> ROWTAR_LTGTID_SHIFT)
+ << ROWTAR_LTGTID_VAL_SHIFT) |
+ (in_be32(&priv->atmu_regs[i].rowtear)
+ << ROWTEAR_LTGTID_VAL_SHIFT);
+
+ seg = 0;
+ if (destid <= dev_destid && dev_destid < destid + num_sseg)
+ goto atmu_found;
+ used_segs = priv->mem_atmu_segs[i];
+ for (; seg < used_segs; seg++) {
+ rowsar = in_be32(&priv->atmu_regs[i].rowsar[seg]);
+ destid = rowsar & ROWSAR_SGTGTDID_MASK;
+ if (destid <= dev_destid && dev_destid < destid + num_sseg) {
+ /* seg = 0 <=> second segment in ATMU */
+ seg++;
+ goto atmu_found;
+ }
+ }
+ if (seg < ROWAR_MAX_SEGS) {
+ /* use segment for this destid range */
+ out_be32(&priv->atmu_regs[i].rowsar[seg], ROWSAR_RDTYP_NREAD |
+ ROWSAR_WRTYP_NWRITE | (dev_destid &
+ (ROWSAR_SGTGTDID_MASK & ~(ROWAR_MAX_SSEGS-1))));
+ seg++;
+ /* seg = number of extra segments = segment number */
+ priv->mem_atmu_segs[i] = seg;
+ goto atmu_found;
+ }
+ }
+
+ /* try to find a new ATMU to configure */
+ for (i = 0; i < RIO_OUTB_ATMU_COUNT; i++)
+ if (!(in_be32(&priv->atmu_regs[i].rowar) & ROWAR_ENABLE))
+ break;
+
+ if (i == RIO_OUTB_ATMU_COUNT)
+ return -EBUSY;
+
+ sseg_len = rio_find_largest_dev_mem(start);
+ if (sseg_len < ROWAR_SIZE_MIN)
+ sseg_len = ROWAR_SIZE_MIN;
+ num_seg = ROWAR_MAX_SEGS;
+ num_sseg = ROWAR_MAX_SSEGS;
+ win_size = sseg_len * num_seg * num_sseg;
+ /* align win_size to next power of 2 */
+ win_size_log = __ilog2(win_size) + ((win_size & (win_size - 1)) != 0);
+ win_size = 1 << win_size_log;
+ /* align base address to next multiple of win_size */
+ win_start = (priv->law_start_free + win_size - 1) & ~(win_size - 1);
+ /* check if enough outbound memory */
+ if (priv->law_end - win_start < win_size)
+ return -EBUSY;
+
+ pr_debug(DRVNAME ": opening new window %d at 0x%08lx, size 0x%08lx (log %u)\n",
+ i, win_start, win_size, win_size_log);
+ rowtar = ((dev_destid & (ROWTAR_TREXAD_TID_VAL_MASK & ~(ROWAR_MAX_SSEGS-1)))
+ << ROWTAR_TREXAD_TID_SHIFT) | (start >> (ROWTAR_TRAD_VAL_SHIFT - 2));
+ if (port->sys_size) {
+ rowtar |= (((dev_destid >> ROWTAR_LTGTID_VAL_SHIFT)
+ & ROWTAR_LTGTID_VAL_MASK) << ROWTAR_LTGTID_SHIFT);
+ out_be32(&priv->atmu_regs[i].rowtear,
+ dev_destid >> ROWTEAR_LTGTID_VAL_SHIFT);
+ }
+ out_be32(&priv->atmu_regs[i].rowtar, rowtar);
+ out_be32(&priv->atmu_regs[i].rowbar, win_start >> ROWBAR_BADD_VAL_SHIFT);
+ out_be32(&priv->atmu_regs[i].rowar, ROWAR_ENABLE | ROWAR_PCI |
+ ROWAR_NSEG_FOUR | ROWAR_NSSEG_EIGHT | ROWAR_RDTYP_NREAD |
+ ROWAR_WRTYP_NWRITE | (win_size_log - 1));
+ priv->law_start_free = win_start + win_size;
+ res->start = win_start;
+ seg = 0;
+ goto res_start_found;
+atmu_found:
+ res->start = start - trad_start +
+ ((priv->atmu_regs[i].rowbar & ROWBAR_BADD_MASK) << ROWBAR_BADD_VAL_SHIFT);
+res_start_found:
+ res->start += (seg * num_sseg + (dev_destid & (ROWAR_MAX_SSEGS-1))) * sseg_len;
+ res->end = res->start + len - 1;
+ pr_debug(DRVNAME ": device destid %d mapped to 0x%08x-0x%08x (seg %d)\n",
+ dev_destid, res->start, res->end, seg);
+ return 0;
+}
+
+void rio_close_outb_mem(struct rio_dev *rdev, int window)
+{
+ /* TODO, keep track of window usage */
+}
+
/**
* fsl_rio_doorbell_init - MPC85xx doorbell interface init
* @mport: Master port implementing the inbound doorbell unit
@@ -1168,6 +1339,8 @@ int fsl_rio_setup(struct of_device *dev)
out_be32(&priv->maint_atmu_regs->rowar, 0x80077015); /* 4M */
priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE);
+ priv->law_start_free = law_start + RIO_MAINT_WIN_SIZE;
+ priv->law_end = law_start + law_size;
/* Configure outbound doorbell window */
out_be32(&priv->dbell_atmu_regs->rowbar,
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 4541509..3389fa5 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -387,8 +387,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
(rdev->dst_ops & RIO_DST_OPS_DOORBELL))
- rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
- 0, 0xffff);
+ rio_init_dbell_res(&rdev->doorbell_res, 0, 0xffff);
ret = rio_add_device(rdev);
if (ret)
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 6395c78..68eade9 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -28,6 +28,7 @@
#include "rio.h"
static LIST_HEAD(rio_mports);
+static LIST_HEAD(rio_dev_mem_list);
/**
* rio_local_get_device_id - Get the base/extended device id for a port
@@ -305,8 +306,7 @@ struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start,
rio_init_dbell_res(res, start, end);
/* Make sure these doorbells aren't in use */
- if (request_resource(&rdev->riores[RIO_DOORBELL_RESOURCE], res)
- < 0) {
+ if (request_resource(&rdev->doorbell_res, res) < 0) {
kfree(res);
res = NULL;
}
@@ -388,6 +388,74 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
return 0;
}
+int rio_claim_resource(u16 vid, u16 did, u32 start, u32 len)
+{
+ struct rio_dev_mem *rmem;
+
+ rmem = rio_find_dev_mem_by_addr(vid, did, start);
+ if (rmem != NULL) {
+ rmem->len = len;
+ return 0;
+ }
+
+ rmem = kzalloc(sizeof(*rmem), GFP_KERNEL);
+ if (rmem == NULL)
+ return -ENOMEM;
+
+ rmem->vendor_id = vid;
+ rmem->device_id = did;
+ rmem->start = start;
+ rmem->len = len;
+ spin_lock(&rio_global_list_lock);
+ list_add_tail(&rmem->node, &rio_dev_mem_list);
+ spin_unlock(&rio_global_list_lock);
+ return 0;
+}
+
+int rio_request_region(struct rio_dev *rdev, int region, char *res_name)
+{
+ struct resource *res;
+ int rc;
+
+ if (region >= RIO_MAX_REGIONS)
+ return -EINVAL;
+
+ if (rdev->mem_res[region] != NULL)
+ return -EBUSY;
+
+ res = kzalloc (sizeof(struct resource), GFP_KERNEL);
+ if (res == NULL)
+ return -ENOMEM;
+
+ rc = rio_open_outb_mem(rdev, region, res);
+ if (rc < 0)
+ goto err_res;
+
+ res->name = res_name;
+ rc = request_resource(&rdev->net->hport->iores, res);
+ if (rc < 0)
+ goto err_res;
+
+ rdev->mem_res[region] = res;
+ goto out;
+err_res:
+ kfree(res);
+ res = NULL;
+out:
+ return rc;
+}
+
+void rio_release_region(struct rio_dev *rdev, int region)
+{
+ if (region >= RIO_MAX_REGIONS)
+ return;
+
+ rio_close_outb_mem(rdev, region);
+ release_resource(rdev->mem_res[region]);
+ kfree(rdev->mem_res[region]);
+ rdev->mem_res[region] = NULL;
+}
+
/**
* rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
* @vid: RIO vid to match or %RIO_ANY_ID to match all vids
@@ -451,6 +519,52 @@ struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
}
+static struct rio_dev_mem *rio_get_dev_mem(u16 vid, u16 did, int region, u32 start)
+{
+ struct rio_dev_mem *rmem;
+
+ spin_lock(&rio_global_list_lock);
+ list_for_each_entry(rmem, &rio_dev_mem_list, node) {
+ if (vid == rmem->vendor_id && did == rmem->device_id) {
+ if (region <= 0 && (start == RIO_ANY_ADDR || start == rmem->start))
+ goto out;
+ else
+ region--;
+ }
+ }
+
+ rmem = NULL;
+out:
+ spin_unlock(&rio_global_list_lock);
+ return rmem;
+}
+
+struct rio_dev_mem *rio_find_dev_mem(u16 vid, u16 did, int region)
+{
+ return rio_get_dev_mem(vid, did, region, RIO_ANY_ADDR);
+}
+
+struct rio_dev_mem *rio_find_dev_mem_by_addr(u16 vid, u16 did, u32 start)
+{
+ return rio_get_dev_mem(vid, did, -1, start);
+}
+
+u32 rio_find_largest_dev_mem(u32 start)
+{
+ struct rio_dev_mem *rmem;
+ u32 len;
+
+ len = 0;
+ spin_lock(&rio_global_list_lock);
+ list_for_each_entry(rmem, &rio_dev_mem_list, node) {
+ if (rmem->start == start && rmem->len > len)
+ len = rmem->len;
+ }
+ spin_unlock(&rio_global_list_lock);
+
+ return len;
+}
+
static void rio_fixup_device(struct rio_dev *dev)
{
}
@@ -509,3 +623,6 @@ EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
+EXPORT_SYMBOL_GPL(rio_claim_resource);
+EXPORT_SYMBOL_GPL(rio_request_region);
+EXPORT_SYMBOL_GPL(rio_release_region);
diff --git a/include/linux/rio.h b/include/linux/rio.h
index dc0c755..343d714 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -25,7 +25,7 @@
#define RIO_INVALID_DESTID 0xffff
#define RIO_MAX_MPORT_RESOURCES 16
-#define RIO_MAX_DEV_RESOURCES 16
+#define RIO_MAX_REGIONS 16
#define RIO_GLOBAL_TABLE 0xff /* Indicates access of a switch's
global routing table if it
@@ -36,6 +36,8 @@
entry is invalid (no route
exists for the device ID) */
+#define RIO_ANY_ADDR 0xffffffff
+
#define RIO_MAX_ROUTE_ENTRIES(size) (size ? (1 << 16) : (1 << 8))
#define RIO_ANY_DESTID(size) (size ? 0xffff : 0xff)
@@ -69,6 +71,14 @@ extern struct list_head rio_devices; /* list of all devices */
struct rio_mport;
+struct rio_dev_mem {
+ struct list_head node;
+ unsigned short vendor_id;
+ unsigned short device_id;
+ u32 start; /* bits 33..2 */
+ u32 len;
+};
+
/**
* struct rio_dev - RIO device info
* @global_list: Node in list of all RIO devices
@@ -89,7 +99,8 @@ struct rio_mport;
* @rswitch: Pointer to &struct rio_switch if valid for this device
* @driver: Driver claiming this device
* @dev: Device model device
- * @riores: RIO resources this device owns
+ * @mem_res: RIO resources this device owns
+ * @doorbell_res: Outbound doorbell ranges in use by drivers/users
* @destid: Network destination ID
*/
struct rio_dev {
@@ -111,7 +122,8 @@ struct rio_dev {
struct rio_switch *rswitch; /* RIO switch info */
struct rio_driver *driver; /* RIO driver claiming this device */
struct device dev; /* LDM device structure */
- struct resource riores[RIO_MAX_DEV_RESOURCES];
+ struct resource *mem_res[RIO_MAX_REGIONS];
+ struct resource doorbell_res;
u16 destid;
};
@@ -330,5 +342,7 @@ extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
extern void rio_close_inb_mbox(struct rio_mport *, int);
extern int rio_open_outb_mbox(struct rio_mport *, void *, int, int);
extern void rio_close_outb_mbox(struct rio_mport *, int);
+extern int rio_open_outb_mem(struct rio_dev *, int, struct resource *res);
+extern void rio_close_outb_mem(struct rio_dev *, int);
#endif /* LINUX_RIO_H */
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index c93a58a..cbcd68d 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -407,7 +407,7 @@ extern struct resource *rio_request_outb_dbell(struct rio_dev *, u16, u16);
extern int rio_release_outb_dbell(struct rio_dev *, struct resource *);
/* Memory region management */
-int rio_claim_resource(struct rio_dev *, int);
+int rio_claim_resource(u16 vid, u16 did, u32 start, u32 len);
int rio_request_regions(struct rio_dev *, char *);
void rio_release_regions(struct rio_dev *);
int rio_request_region(struct rio_dev *, int, char *);
@@ -461,5 +461,8 @@ extern u16 rio_local_get_device_id(struct rio_mport *port);
extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from);
extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did,
struct rio_dev *from);
+extern struct rio_dev_mem *rio_find_dev_mem(u16 vid, u16 did, int region);
+extern struct rio_dev_mem *rio_find_dev_mem_by_addr(u16 vid, u16 did, u32 start);
+extern u32 rio_find_largest_dev_mem(u32 start);
#endif /* LINUX_RIO_DRV_H */
--
1.6.5.7
^ permalink raw reply related
* [PATCH 1/9] of: Remove old and misplaced function declarations
From: Grant Likely @ 2010-02-13 16:02 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
In-Reply-To: <20100213154838.4767.83881.stgit@angua>
The following functions don't exist:
finish_device_tree()
print_properties()
prom_n_intr_cells()
prom_get_irq_senses()
The following functions are in drivers/of/base.c, so the declaration
belongs in of.h instead of of_fdt.h
of_machine_is_compatible()
prom_add_property()
prom_remove_property()
prom_update_property()
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
include/linux/of.h | 8 ++++++++
include/linux/of_fdt.h | 10 ----------
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/include/linux/of.h b/include/linux/of.h
index fa5571b..5c7b6a6 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -180,6 +180,14 @@ extern int of_parse_phandles_with_args(struct device_node *np,
const char *list_name, const char *cells_name, int index,
struct device_node **out_node, const void **out_args);
+extern int of_machine_is_compatible(const char *compat);
+
+extern int prom_add_property(struct device_node* np, struct property* prop);
+extern int prom_remove_property(struct device_node *np, struct property *prop);
+extern int prom_update_property(struct device_node *np,
+ struct property *newprop,
+ struct property *oldprop);
+
#if defined(CONFIG_OF_DYNAMIC)
/* For updating the device tree at runtime */
extern void of_attach_node(struct device_node *);
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 0007187..c9cb8a7 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -95,18 +95,8 @@ extern int early_init_dt_scan_root(unsigned long node, const char *uname,
int depth, void *data);
/* Other Prototypes */
-extern void finish_device_tree(void);
extern void unflatten_device_tree(void);
extern void early_init_devtree(void *);
-extern int of_machine_is_compatible(const char *compat);
-extern void print_properties(struct device_node *node);
-extern int prom_n_intr_cells(struct device_node* np);
-extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
-extern int prom_add_property(struct device_node* np, struct property* prop);
-extern int prom_remove_property(struct device_node *np, struct property *prop);
-extern int prom_update_property(struct device_node *np,
- struct property *newprop,
- struct property *oldprop);
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_OF_FDT_H */
^ permalink raw reply related
* [PATCH 0/9] Random OF cleanups and merges
From: Grant Likely @ 2010-02-13 16:02 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
Here's another batch of cleanup patches from my test-devicetree branch.
A number of cleanups, corrections and minor merges of common code.
Also a patch from Jeremy to make the flat tree work on architectures
without LMB (arm).
Once I've collected acks on these, I'll move them over to my
next-devicetree branch on git://git.secretlab.ca/git/linux-2.6
Cheers,
g.
---
Grant Likely (6):
of: remove undefined request_OF_resource & release_OF_resource
of/sparc: Remove sparc-local declaration of allnodes and devtree_lock
of: move definition of of_chosen into common code.
of: remove unused extern reference to devtree_lock
of: put default string compare and #a/s-cell values into common header
of: Remove old and misplaced function declarations
Jeremy Kerr (3):
of/flattree: Don't assume HAVE_LMB
of: protect linux/of.h with CONFIG_OF
proc_devtree: fix THIS_MODULE without module.h
arch/microblaze/include/asm/prom.h | 15 ---------------
arch/microblaze/kernel/prom.c | 8 +++++---
arch/powerpc/include/asm/prom.h | 14 --------------
arch/powerpc/kernel/prom.c | 10 +++++-----
arch/sparc/kernel/prom.h | 3 ---
drivers/of/base.c | 1 +
drivers/of/fdt.c | 9 ++++++---
fs/proc/proc_devtree.c | 1 +
include/linux/of.h | 27 +++++++++++++++++++++++++++
include/linux/of_fdt.h | 11 +----------
10 files changed, 46 insertions(+), 53 deletions(-)
^ permalink raw reply
* [PATCH 2/9] proc_devtree: fix THIS_MODULE without module.h
From: Grant Likely @ 2010-02-13 16:02 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
In-Reply-To: <20100213154838.4767.83881.stgit@angua>
From: Jeremy Kerr <jeremy.kerr@canonical.com>
Commit e22f628395432b967f2f505858c64450f7835365 introduced a build
breakage for ARM devtree work: the THIS_MODULE macro was added, but we
don't have module.h
This change adds the necessary #include to get THIS_MODULE defined.
While we could just replace it with NULL (PROC_FS is a bool, not a
tristate), using THIS_MODULE will prevent unexpected breakage if we
ever do compile this as a module.
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
fs/proc/proc_devtree.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 0ec4511..f8650dc 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -11,6 +11,7 @@
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/of.h>
+#include <linux/module.h>
#include <asm/prom.h>
#include <asm/uaccess.h>
#include "internal.h"
^ permalink raw reply related
* [PATCH 3/9] of: protect linux/of.h with CONFIG_OF
From: Grant Likely @ 2010-02-13 16:02 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
In-Reply-To: <20100213154838.4767.83881.stgit@angua>
From: Jeremy Kerr <jeremy.kerr@canonical.com>
For platforms that have CONFIG_OF optional, we need to make the contents
of linux/of.h conditional on CONFIG_OF.
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
include/linux/of.h | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/include/linux/of.h b/include/linux/of.h
index 5c7b6a6..48b0ee6 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -22,6 +22,8 @@
#include <asm/byteorder.h>
+#ifdef CONFIG_OF
+
typedef u32 phandle;
typedef u32 ihandle;
@@ -194,4 +196,5 @@ extern void of_attach_node(struct device_node *);
extern void of_detach_node(struct device_node *);
#endif
+#endif /* CONFIG_OF */
#endif /* _LINUX_OF_H */
^ permalink raw reply related
* [PATCH 4/9] of/flattree: Don't assume HAVE_LMB
From: Grant Likely @ 2010-02-13 16:02 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
In-Reply-To: <20100213154838.4767.83881.stgit@angua>
From: Jeremy Kerr <jeremy.kerr@canonical.com>
We don't always have lmb available, so make arches provide an
early_init_dt_alloc_memory_arch() to handle the allocation of
memory in the fdt code.
When we don't have lmb.h included, we need asm/page.h for __va.
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/microblaze/kernel/prom.c | 5 +++++
arch/powerpc/kernel/prom.c | 5 +++++
drivers/of/fdt.c | 9 ++++++---
include/linux/of_fdt.h | 1 +
4 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 050b799..a7dcaf0 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -55,6 +55,11 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
lmb_add(base, size);
}
+u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+ return lmb_alloc(size, align);
+}
+
#ifdef CONFIG_EARLY_PRINTK
/* MS this is Microblaze specifig function */
static int __init early_init_dt_scan_serial(unsigned long node,
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 43c78d7..5bbbdb2 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -510,6 +510,11 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
memstart_addr = min((u64)memstart_addr, base);
}
+u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+ return lmb_alloc(size, align);
+}
+
#ifdef CONFIG_BLK_DEV_INITRD
void __init early_init_dt_setup_initrd_arch(unsigned long start,
unsigned long end)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index b51f797..406757a 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -10,16 +10,18 @@
*/
#include <linux/kernel.h>
-#include <linux/lmb.h>
#include <linux/initrd.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
-
+#include <linux/string.h>
+#include <linux/errno.h>
#ifdef CONFIG_PPC
#include <asm/machdep.h>
#endif /* CONFIG_PPC */
+#include <asm/page.h>
+
int __initdata dt_root_addr_cells;
int __initdata dt_root_size_cells;
@@ -560,7 +562,8 @@ void __init unflatten_device_tree(void)
pr_debug(" size is %lx, allocating...\n", size);
/* Allocate memory for the expanded device tree */
- mem = lmb_alloc(size + 4, __alignof__(struct device_node));
+ mem = early_init_dt_alloc_memory_arch(size + 4,
+ __alignof__(struct device_node));
mem = (unsigned long) __va(mem);
((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index c9cb8a7..a1ca92c 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -78,6 +78,7 @@ extern void early_init_dt_check_for_initrd(unsigned long node);
extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
int depth, void *data);
extern void early_init_dt_add_memory_arch(u64 base, u64 size);
+extern u64 early_init_dt_alloc_memory_arch(u64 size, u64 align);
extern u64 dt_mem_next_cell(int s, __be32 **cellp);
/*
^ permalink raw reply related
* [PATCH 5/9] of: put default string compare and #a/s-cell values into common header
From: Grant Likely @ 2010-02-13 16:02 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
In-Reply-To: <20100213154838.4767.83881.stgit@angua>
Most architectures don't need to change these. Put them into common
code to eliminate some duplication
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/microblaze/include/asm/prom.h | 7 -------
arch/powerpc/include/asm/prom.h | 7 -------
include/linux/of.h | 13 +++++++++++++
3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 6c6b386..ddc5c57 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -26,13 +26,6 @@
#include <asm/irq.h>
#include <asm/atomic.h>
-#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
-#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
-
-#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
-#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
-#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
-
extern struct device_node *of_chosen;
#define HAVE_ARCH_DEVTREE_FIXUPS
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index f384db8..4a5070e 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -23,13 +23,6 @@
#include <asm/irq.h>
#include <asm/atomic.h>
-#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
-#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
-
-#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
-#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
-#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
-
extern struct device_node *of_chosen;
#define HAVE_ARCH_DEVTREE_FIXUPS
diff --git a/include/linux/of.h b/include/linux/of.h
index 48b0ee6..5cd2840 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -116,6 +116,19 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
#include <asm/prom.h>
+/* Default #address and #size cells. Allow arch asm/prom.h to override */
+#if !defined(OF_ROOT_NODE_ADDR_CELLS_DEFAULT)
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+#endif
+
+/* Default string compare functions, Allow arch asm/prom.h to override */
+#if !defined(of_compat_cmp)
+#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
+#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
+#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
+#endif
+
/* flag descriptions */
#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
#define OF_DETACHED 2 /* node has been detached from the device tree */
^ permalink raw reply related
* [PATCH 6/9] of: remove unused extern reference to devtree_lock
From: Grant Likely @ 2010-02-13 16:02 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
In-Reply-To: <20100213154838.4767.83881.stgit@angua>
Neither the powerpc nor the microblaze code use devtree_lock anymore.
Remove the extern reference.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/microblaze/include/asm/prom.h | 2 --
arch/powerpc/kernel/prom.c | 2 --
2 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index ddc5c57..8b1ebd3 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -30,8 +30,6 @@ extern struct device_node *of_chosen;
#define HAVE_ARCH_DEVTREE_FIXUPS
-extern rwlock_t devtree_lock; /* temporary while merging */
-
/* Other Prototypes */
extern int early_uartlite_console(void);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 5bbbdb2..4869c93 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -67,8 +67,6 @@ int __initdata iommu_force_on;
unsigned long tce_alloc_start, tce_alloc_end;
#endif
-extern rwlock_t devtree_lock; /* temporary while merging */
-
/* export that to outside world */
struct device_node *of_chosen;
^ permalink raw reply related
* [PATCH 7/9] of: move definition of of_chosen into common code.
From: Grant Likely @ 2010-02-13 16:03 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
In-Reply-To: <20100213154838.4767.83881.stgit@angua>
Rather than defining of_chosen in each arch, it can be defined for all
in driver/of/base.c
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/microblaze/include/asm/prom.h | 2 --
arch/microblaze/kernel/prom.c | 3 ---
arch/powerpc/include/asm/prom.h | 2 --
arch/powerpc/kernel/prom.c | 3 ---
drivers/of/base.c | 1 +
include/linux/of.h | 1 +
6 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 8b1ebd3..aa1a437 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -26,8 +26,6 @@
#include <asm/irq.h>
#include <asm/atomic.h>
-extern struct device_node *of_chosen;
-
#define HAVE_ARCH_DEVTREE_FIXUPS
/* Other Prototypes */
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index a7dcaf0..a15ef6d 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -42,9 +42,6 @@
#include <asm/sections.h>
#include <asm/pci-bridge.h>
-/* export that to outside world */
-struct device_node *of_chosen;
-
void __init early_init_dt_scan_chosen_arch(unsigned long node)
{
/* No Microblaze specific code here */
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 4a5070e..7f9a50a 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -23,8 +23,6 @@
#include <asm/irq.h>
#include <asm/atomic.h>
-extern struct device_node *of_chosen;
-
#define HAVE_ARCH_DEVTREE_FIXUPS
#ifdef CONFIG_PPC32
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 4869c93..43238b2 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -67,9 +67,6 @@ int __initdata iommu_force_on;
unsigned long tce_alloc_start, tce_alloc_end;
#endif
-/* export that to outside world */
-struct device_node *of_chosen;
-
static int __init early_parse_mem(char *p)
{
if (!p)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 873479a..cb96888 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -23,6 +23,7 @@
#include <linux/proc_fs.h>
struct device_node *allnodes;
+struct device_node *of_chosen;
/* use when traversing tree through the allnext, child, sibling,
* or parent members of struct device_node.
diff --git a/include/linux/of.h b/include/linux/of.h
index 5cd2840..d34cc5d 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -66,6 +66,7 @@ struct device_node {
/* Pointer for first entry in chain of all nodes. */
extern struct device_node *allnodes;
+extern struct device_node *of_chosen;
static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
{
^ permalink raw reply related
* [PATCH 8/9] of/sparc: Remove sparc-local declaration of allnodes and devtree_lock
From: Grant Likely @ 2010-02-13 16:03 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
In-Reply-To: <20100213154838.4767.83881.stgit@angua>
Both allnodes and devtree_lock are defined in common code. The
extern declaration should be in the common header too so that the
compiler can type check. allnodes is already in of.h, but
devtree_lock should be declared there too.
This patch removes the SPARC declarations and uses decls in of.h instead.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/sparc/kernel/prom.h | 3 ---
include/linux/of.h | 2 ++
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/sparc/kernel/prom.h b/arch/sparc/kernel/prom.h
index 453397f..a8591ef 100644
--- a/arch/sparc/kernel/prom.h
+++ b/arch/sparc/kernel/prom.h
@@ -4,9 +4,6 @@
#include <linux/spinlock.h>
#include <asm/prom.h>
-extern struct device_node *allnodes; /* temporary while merging */
-extern rwlock_t devtree_lock; /* temporary while merging */
-
extern void * prom_early_alloc(unsigned long size);
extern void irq_trans_init(struct device_node *dp);
diff --git a/include/linux/of.h b/include/linux/of.h
index d34cc5d..f6d9cbc 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -19,6 +19,7 @@
#include <linux/bitops.h>
#include <linux/kref.h>
#include <linux/mod_devicetable.h>
+#include <linux/spinlock.h>
#include <asm/byteorder.h>
@@ -67,6 +68,7 @@ struct device_node {
/* Pointer for first entry in chain of all nodes. */
extern struct device_node *allnodes;
extern struct device_node *of_chosen;
+extern rwlock_t devtree_lock;
static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
{
^ permalink raw reply related
* [PATCH 9/9] of: remove undefined request_OF_resource & release_OF_resource
From: Grant Likely @ 2010-02-13 16:03 UTC (permalink / raw)
To: monstr, sfr, benh, jeremy.kerr, davem, microblaze-uclinux,
linuxppc-dev, sparclinux, devicetree-discuss, linux-kernel
In-Reply-To: <20100213154838.4767.83881.stgit@angua>
Neither request_OF_resource or release_OF_resource are defined
anywhere. Remove the declarations.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/microblaze/include/asm/prom.h | 4 ----
arch/powerpc/include/asm/prom.h | 5 -----
2 files changed, 0 insertions(+), 9 deletions(-)
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index aa1a437..03f45a9 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -31,10 +31,6 @@
/* Other Prototypes */
extern int early_uartlite_console(void);
-extern struct resource *request_OF_resource(struct device_node *node,
- int index, const char *name_postfix);
-extern int release_OF_resource(struct device_node *node, int index);
-
/*
* OF address retreival & translation
*/
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 7f9a50a..ddd408a 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -39,11 +39,6 @@ extern struct device_node* pci_device_to_OF_node(struct pci_dev *);
extern void pci_create_OF_bus_map(void);
#endif
-extern struct resource *request_OF_resource(struct device_node* node,
- int index, const char* name_postfix);
-extern int release_OF_resource(struct device_node* node, int index);
-
-
/*
* OF address retreival & translation
*/
^ permalink raw reply related
* Re: [PATCH 1/9] of: Remove old and misplaced function declarations
From: Benjamin Herrenschmidt @ 2010-02-14 6:09 UTC (permalink / raw)
To: Grant Likely
Cc: sfr, monstr, microblaze-uclinux, devicetree-discuss, linux-kernel,
linuxppc-dev, sparclinux, jeremy.kerr, davem
In-Reply-To: <20100213160231.4767.23831.stgit@angua>
On Sat, 2010-02-13 at 09:02 -0700, Grant Likely wrote:
> The following functions don't exist:
> finish_device_tree()
> print_properties()
> prom_n_intr_cells()
> prom_get_irq_senses()
>
> The following functions are in drivers/of/base.c, so the declaration
> belongs in of.h instead of of_fdt.h
> of_machine_is_compatible()
> prom_add_property()
> prom_remove_property()
> prom_update_property()
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> include/linux/of.h | 8 ++++++++
> include/linux/of_fdt.h | 10 ----------
> 2 files changed, 8 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/of.h b/include/linux/of.h
> index fa5571b..5c7b6a6 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -180,6 +180,14 @@ extern int of_parse_phandles_with_args(struct device_node *np,
> const char *list_name, const char *cells_name, int index,
> struct device_node **out_node, const void **out_args);
>
> +extern int of_machine_is_compatible(const char *compat);
> +
> +extern int prom_add_property(struct device_node* np, struct property* prop);
> +extern int prom_remove_property(struct device_node *np, struct property *prop);
> +extern int prom_update_property(struct device_node *np,
> + struct property *newprop,
> + struct property *oldprop);
> +
> #if defined(CONFIG_OF_DYNAMIC)
> /* For updating the device tree at runtime */
> extern void of_attach_node(struct device_node *);
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 0007187..c9cb8a7 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -95,18 +95,8 @@ extern int early_init_dt_scan_root(unsigned long node, const char *uname,
> int depth, void *data);
>
> /* Other Prototypes */
> -extern void finish_device_tree(void);
> extern void unflatten_device_tree(void);
> extern void early_init_devtree(void *);
> -extern int of_machine_is_compatible(const char *compat);
> -extern void print_properties(struct device_node *node);
> -extern int prom_n_intr_cells(struct device_node* np);
> -extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
> -extern int prom_add_property(struct device_node* np, struct property* prop);
> -extern int prom_remove_property(struct device_node *np, struct property *prop);
> -extern int prom_update_property(struct device_node *np,
> - struct property *newprop,
> - struct property *oldprop);
>
> #endif /* __ASSEMBLY__ */
> #endif /* _LINUX_OF_FDT_H */
^ permalink raw reply
* Re: [PATCH 2/9] proc_devtree: fix THIS_MODULE without module.h
From: Benjamin Herrenschmidt @ 2010-02-14 6:09 UTC (permalink / raw)
To: Grant Likely
Cc: sfr, monstr, microblaze-uclinux, devicetree-discuss, linux-kernel,
linuxppc-dev, sparclinux, jeremy.kerr, davem
In-Reply-To: <20100213160236.4767.48310.stgit@angua>
On Sat, 2010-02-13 at 09:02 -0700, Grant Likely wrote:
> From: Jeremy Kerr <jeremy.kerr@canonical.com>
>
> Commit e22f628395432b967f2f505858c64450f7835365 introduced a build
> breakage for ARM devtree work: the THIS_MODULE macro was added, but we
> don't have module.h
>
> This change adds the necessary #include to get THIS_MODULE defined.
> While we could just replace it with NULL (PROC_FS is a bool, not a
> tristate), using THIS_MODULE will prevent unexpected breakage if we
> ever do compile this as a module.
>
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> fs/proc/proc_devtree.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
> index 0ec4511..f8650dc 100644
> --- a/fs/proc/proc_devtree.c
> +++ b/fs/proc/proc_devtree.c
> @@ -11,6 +11,7 @@
> #include <linux/stat.h>
> #include <linux/string.h>
> #include <linux/of.h>
> +#include <linux/module.h>
> #include <asm/prom.h>
> #include <asm/uaccess.h>
> #include "internal.h"
^ permalink raw reply
* Re: [PATCH 4/9] of/flattree: Don't assume HAVE_LMB
From: Benjamin Herrenschmidt @ 2010-02-14 6:11 UTC (permalink / raw)
To: Grant Likely
Cc: sfr, monstr, microblaze-uclinux, devicetree-discuss, linux-kernel,
linuxppc-dev, sparclinux, jeremy.kerr, davem
In-Reply-To: <20100213160247.4767.74578.stgit@angua>
On Sat, 2010-02-13 at 09:02 -0700, Grant Likely wrote:
> From: Jeremy Kerr <jeremy.kerr@canonical.com>
>
> We don't always have lmb available, so make arches provide an
> early_init_dt_alloc_memory_arch() to handle the allocation of
> memory in the fdt code.
>
> When we don't have lmb.h included, we need asm/page.h for __va.
>
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> arch/microblaze/kernel/prom.c | 5 +++++
> arch/powerpc/kernel/prom.c | 5 +++++
> drivers/of/fdt.c | 9 ++++++---
> include/linux/of_fdt.h | 1 +
> 4 files changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
> index 050b799..a7dcaf0 100644
> --- a/arch/microblaze/kernel/prom.c
> +++ b/arch/microblaze/kernel/prom.c
> @@ -55,6 +55,11 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
> lmb_add(base, size);
> }
>
> +u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
> +{
> + return lmb_alloc(size, align);
> +}
> +
> #ifdef CONFIG_EARLY_PRINTK
> /* MS this is Microblaze specifig function */
> static int __init early_init_dt_scan_serial(unsigned long node,
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 43c78d7..5bbbdb2 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -510,6 +510,11 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
> memstart_addr = min((u64)memstart_addr, base);
> }
>
> +u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
> +{
> + return lmb_alloc(size, align);
> +}
> +
> #ifdef CONFIG_BLK_DEV_INITRD
> void __init early_init_dt_setup_initrd_arch(unsigned long start,
> unsigned long end)
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index b51f797..406757a 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -10,16 +10,18 @@
> */
>
> #include <linux/kernel.h>
> -#include <linux/lmb.h>
> #include <linux/initrd.h>
> #include <linux/of.h>
> #include <linux/of_fdt.h>
> -
> +#include <linux/string.h>
> +#include <linux/errno.h>
>
> #ifdef CONFIG_PPC
> #include <asm/machdep.h>
> #endif /* CONFIG_PPC */
>
> +#include <asm/page.h>
> +
> int __initdata dt_root_addr_cells;
> int __initdata dt_root_size_cells;
>
> @@ -560,7 +562,8 @@ void __init unflatten_device_tree(void)
> pr_debug(" size is %lx, allocating...\n", size);
>
> /* Allocate memory for the expanded device tree */
> - mem = lmb_alloc(size + 4, __alignof__(struct device_node));
> + mem = early_init_dt_alloc_memory_arch(size + 4,
> + __alignof__(struct device_node));
> mem = (unsigned long) __va(mem);
>
> ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index c9cb8a7..a1ca92c 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -78,6 +78,7 @@ extern void early_init_dt_check_for_initrd(unsigned long node);
> extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
> int depth, void *data);
> extern void early_init_dt_add_memory_arch(u64 base, u64 size);
> +extern u64 early_init_dt_alloc_memory_arch(u64 size, u64 align);
> extern u64 dt_mem_next_cell(int s, __be32 **cellp);
>
> /*
^ permalink raw reply
* Re: [PATCH 5/9] of: put default string compare and #a/s-cell values into common header
From: Benjamin Herrenschmidt @ 2010-02-14 6:11 UTC (permalink / raw)
To: Grant Likely
Cc: sfr, monstr, microblaze-uclinux, devicetree-discuss, linux-kernel,
linuxppc-dev, sparclinux, jeremy.kerr, davem
In-Reply-To: <20100213160252.4767.94582.stgit@angua>
On Sat, 2010-02-13 at 09:02 -0700, Grant Likely wrote:
> Most architectures don't need to change these. Put them into common
> code to eliminate some duplication
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>
> arch/microblaze/include/asm/prom.h | 7 -------
> arch/powerpc/include/asm/prom.h | 7 -------
> include/linux/of.h | 13 +++++++++++++
> 3 files changed, 13 insertions(+), 14 deletions(-)
>
> diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
> index 6c6b386..ddc5c57 100644
> --- a/arch/microblaze/include/asm/prom.h
> +++ b/arch/microblaze/include/asm/prom.h
> @@ -26,13 +26,6 @@
> #include <asm/irq.h>
> #include <asm/atomic.h>
>
> -#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
> -#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
> -
> -#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
> -#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
> -#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
> -
> extern struct device_node *of_chosen;
>
> #define HAVE_ARCH_DEVTREE_FIXUPS
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index f384db8..4a5070e 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -23,13 +23,6 @@
> #include <asm/irq.h>
> #include <asm/atomic.h>
>
> -#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
> -#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
> -
> -#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
> -#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
> -#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
> -
> extern struct device_node *of_chosen;
>
> #define HAVE_ARCH_DEVTREE_FIXUPS
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 48b0ee6..5cd2840 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -116,6 +116,19 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
>
> #include <asm/prom.h>
>
> +/* Default #address and #size cells. Allow arch asm/prom.h to override */
> +#if !defined(OF_ROOT_NODE_ADDR_CELLS_DEFAULT)
> +#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
> +#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
> +#endif
> +
> +/* Default string compare functions, Allow arch asm/prom.h to override */
> +#if !defined(of_compat_cmp)
> +#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
> +#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
> +#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
> +#endif
> +
> /* flag descriptions */
> #define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
> #define OF_DETACHED 2 /* node has been detached from the device tree */
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox