|
@@ -210,7 +210,7 @@ struct bus_type of_bus_type = {
|
|
};
|
|
};
|
|
EXPORT_SYMBOL(of_bus_type);
|
|
EXPORT_SYMBOL(of_bus_type);
|
|
|
|
|
|
-static inline u64 of_read_addr(u32 *cell, int size)
|
|
|
|
|
|
+static inline u64 of_read_addr(const u32 *cell, int size)
|
|
{
|
|
{
|
|
u64 r = 0;
|
|
u64 r = 0;
|
|
while (size--)
|
|
while (size--)
|
|
@@ -236,8 +236,8 @@ struct of_bus {
|
|
int (*match)(struct device_node *parent);
|
|
int (*match)(struct device_node *parent);
|
|
void (*count_cells)(struct device_node *child,
|
|
void (*count_cells)(struct device_node *child,
|
|
int *addrc, int *sizec);
|
|
int *addrc, int *sizec);
|
|
- u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
|
|
|
|
- int (*translate)(u32 *addr, u64 offset, int na);
|
|
|
|
|
|
+ int (*map)(u32 *addr, const u32 *range,
|
|
|
|
+ int na, int ns, int pna);
|
|
unsigned int (*get_flags)(u32 *addr);
|
|
unsigned int (*get_flags)(u32 *addr);
|
|
};
|
|
};
|
|
|
|
|
|
@@ -251,27 +251,49 @@ static void of_bus_default_count_cells(struct device_node *dev,
|
|
get_cells(dev, addrc, sizec);
|
|
get_cells(dev, addrc, sizec);
|
|
}
|
|
}
|
|
|
|
|
|
-static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
|
|
|
|
|
|
+/* Make sure the least significant 64-bits are in-range. Even
|
|
|
|
+ * for 3 or 4 cell values it is a good enough approximation.
|
|
|
|
+ */
|
|
|
|
+static int of_out_of_range(const u32 *addr, const u32 *base,
|
|
|
|
+ const u32 *size, int na, int ns)
|
|
{
|
|
{
|
|
- u64 cp, s, da;
|
|
|
|
|
|
+ u64 a = of_read_addr(addr, na);
|
|
|
|
+ u64 b = of_read_addr(base, na);
|
|
|
|
|
|
- cp = of_read_addr(range, na);
|
|
|
|
- s = of_read_addr(range + na + pna, ns);
|
|
|
|
- da = of_read_addr(addr, na);
|
|
|
|
|
|
+ if (a < b)
|
|
|
|
+ return 1;
|
|
|
|
|
|
- if (da < cp || da >= (cp + s))
|
|
|
|
- return OF_BAD_ADDR;
|
|
|
|
- return da - cp;
|
|
|
|
|
|
+ b += of_read_addr(size, ns);
|
|
|
|
+ if (a >= b)
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int of_bus_default_translate(u32 *addr, u64 offset, int na)
|
|
|
|
|
|
+static int of_bus_default_map(u32 *addr, const u32 *range,
|
|
|
|
+ int na, int ns, int pna)
|
|
{
|
|
{
|
|
- u64 a = of_read_addr(addr, na);
|
|
|
|
- memset(addr, 0, na * 4);
|
|
|
|
- a += offset;
|
|
|
|
- if (na > 1)
|
|
|
|
- addr[na - 2] = a >> 32;
|
|
|
|
- addr[na - 1] = a & 0xffffffffu;
|
|
|
|
|
|
+ u32 result[OF_MAX_ADDR_CELLS];
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ if (ns > 2) {
|
|
|
|
+ printk("of_device: Cannot handle size cells (%d) > 2.", ns);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (of_out_of_range(addr, range, range + na + pna, na, ns))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ /* Start with the parent range base. */
|
|
|
|
+ memcpy(result, range + na, pna * 4);
|
|
|
|
+
|
|
|
|
+ /* Add in the child address offset. */
|
|
|
|
+ for (i = 0; i < na; i++)
|
|
|
|
+ result[pna - 1 - i] +=
|
|
|
|
+ (addr[na - 1 - i] -
|
|
|
|
+ range[na - 1 - i]);
|
|
|
|
+
|
|
|
|
+ memcpy(addr, result, pna * 4);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -287,7 +309,20 @@ static unsigned int of_bus_default_get_flags(u32 *addr)
|
|
|
|
|
|
static int of_bus_pci_match(struct device_node *np)
|
|
static int of_bus_pci_match(struct device_node *np)
|
|
{
|
|
{
|
|
- return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex");
|
|
|
|
|
|
+ if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
|
|
|
|
+ /* Do not do PCI specific frobbing if the
|
|
|
|
+ * PCI bridge lacks a ranges property. We
|
|
|
|
+ * want to pass it through up to the next
|
|
|
|
+ * parent as-is, not with the PCI translate
|
|
|
|
+ * method which chops off the top address cell.
|
|
|
|
+ */
|
|
|
|
+ if (!of_find_property(np, "ranges", NULL))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static void of_bus_pci_count_cells(struct device_node *np,
|
|
static void of_bus_pci_count_cells(struct device_node *np,
|
|
@@ -299,27 +334,32 @@ static void of_bus_pci_count_cells(struct device_node *np,
|
|
*sizec = 2;
|
|
*sizec = 2;
|
|
}
|
|
}
|
|
|
|
|
|
-static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
|
|
|
|
|
|
+static int of_bus_pci_map(u32 *addr, const u32 *range,
|
|
|
|
+ int na, int ns, int pna)
|
|
{
|
|
{
|
|
- u64 cp, s, da;
|
|
|
|
|
|
+ u32 result[OF_MAX_ADDR_CELLS];
|
|
|
|
+ int i;
|
|
|
|
|
|
/* Check address type match */
|
|
/* Check address type match */
|
|
if ((addr[0] ^ range[0]) & 0x03000000)
|
|
if ((addr[0] ^ range[0]) & 0x03000000)
|
|
- return OF_BAD_ADDR;
|
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
- /* Read address values, skipping high cell */
|
|
|
|
- cp = of_read_addr(range + 1, na - 1);
|
|
|
|
- s = of_read_addr(range + na + pna, ns);
|
|
|
|
- da = of_read_addr(addr + 1, na - 1);
|
|
|
|
|
|
+ if (of_out_of_range(addr + 1, range + 1, range + na + pna,
|
|
|
|
+ na - 1, ns))
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
- if (da < cp || da >= (cp + s))
|
|
|
|
- return OF_BAD_ADDR;
|
|
|
|
- return da - cp;
|
|
|
|
-}
|
|
|
|
|
|
+ /* Start with the parent range base. */
|
|
|
|
+ memcpy(result, range + na, pna * 4);
|
|
|
|
|
|
-static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
|
|
|
|
-{
|
|
|
|
- return of_bus_default_translate(addr + 1, offset, na - 1);
|
|
|
|
|
|
+ /* Add in the child address offset, skipping high cell. */
|
|
|
|
+ for (i = 0; i < na - 1; i++)
|
|
|
|
+ result[pna - 1 - i] +=
|
|
|
|
+ (addr[na - 1 - i] -
|
|
|
|
+ range[na - 1 - i]);
|
|
|
|
+
|
|
|
|
+ memcpy(addr, result, pna * 4);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static unsigned int of_bus_pci_get_flags(u32 *addr)
|
|
static unsigned int of_bus_pci_get_flags(u32 *addr)
|
|
@@ -339,59 +379,6 @@ static unsigned int of_bus_pci_get_flags(u32 *addr)
|
|
return flags;
|
|
return flags;
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * ISA bus specific translator
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-static int of_bus_isa_match(struct device_node *np)
|
|
|
|
-{
|
|
|
|
- return !strcmp(np->name, "isa");
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void of_bus_isa_count_cells(struct device_node *child,
|
|
|
|
- int *addrc, int *sizec)
|
|
|
|
-{
|
|
|
|
- if (addrc)
|
|
|
|
- *addrc = 2;
|
|
|
|
- if (sizec)
|
|
|
|
- *sizec = 1;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
|
|
|
|
-{
|
|
|
|
- u64 cp, s, da;
|
|
|
|
-
|
|
|
|
- /* Check address type match */
|
|
|
|
- if ((addr[0] ^ range[0]) & 0x00000001)
|
|
|
|
- return OF_BAD_ADDR;
|
|
|
|
-
|
|
|
|
- /* Read address values, skipping high cell */
|
|
|
|
- cp = of_read_addr(range + 1, na - 1);
|
|
|
|
- s = of_read_addr(range + na + pna, ns);
|
|
|
|
- da = of_read_addr(addr + 1, na - 1);
|
|
|
|
-
|
|
|
|
- if (da < cp || da >= (cp + s))
|
|
|
|
- return OF_BAD_ADDR;
|
|
|
|
- return da - cp;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
|
|
|
|
-{
|
|
|
|
- return of_bus_default_translate(addr + 1, offset, na - 1);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static unsigned int of_bus_isa_get_flags(u32 *addr)
|
|
|
|
-{
|
|
|
|
- unsigned int flags = 0;
|
|
|
|
- u32 w = addr[0];
|
|
|
|
-
|
|
|
|
- if (w & 1)
|
|
|
|
- flags |= IORESOURCE_IO;
|
|
|
|
- else
|
|
|
|
- flags |= IORESOURCE_MEM;
|
|
|
|
- return flags;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* SBUS bus specific translator
|
|
* SBUS bus specific translator
|
|
*/
|
|
*/
|
|
@@ -411,16 +398,11 @@ static void of_bus_sbus_count_cells(struct device_node *child,
|
|
*sizec = 1;
|
|
*sizec = 1;
|
|
}
|
|
}
|
|
|
|
|
|
-static u64 of_bus_sbus_map(u32 *addr, u32 *range, int na, int ns, int pna)
|
|
|
|
|
|
+static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna)
|
|
{
|
|
{
|
|
return of_bus_default_map(addr, range, na, ns, pna);
|
|
return of_bus_default_map(addr, range, na, ns, pna);
|
|
}
|
|
}
|
|
|
|
|
|
-static int of_bus_sbus_translate(u32 *addr, u64 offset, int na)
|
|
|
|
-{
|
|
|
|
- return of_bus_default_translate(addr, offset, na);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static unsigned int of_bus_sbus_get_flags(u32 *addr)
|
|
static unsigned int of_bus_sbus_get_flags(u32 *addr)
|
|
{
|
|
{
|
|
return IORESOURCE_MEM;
|
|
return IORESOURCE_MEM;
|
|
@@ -439,19 +421,8 @@ static struct of_bus of_busses[] = {
|
|
.match = of_bus_pci_match,
|
|
.match = of_bus_pci_match,
|
|
.count_cells = of_bus_pci_count_cells,
|
|
.count_cells = of_bus_pci_count_cells,
|
|
.map = of_bus_pci_map,
|
|
.map = of_bus_pci_map,
|
|
- .translate = of_bus_pci_translate,
|
|
|
|
.get_flags = of_bus_pci_get_flags,
|
|
.get_flags = of_bus_pci_get_flags,
|
|
},
|
|
},
|
|
- /* ISA */
|
|
|
|
- {
|
|
|
|
- .name = "isa",
|
|
|
|
- .addr_prop_name = "reg",
|
|
|
|
- .match = of_bus_isa_match,
|
|
|
|
- .count_cells = of_bus_isa_count_cells,
|
|
|
|
- .map = of_bus_isa_map,
|
|
|
|
- .translate = of_bus_isa_translate,
|
|
|
|
- .get_flags = of_bus_isa_get_flags,
|
|
|
|
- },
|
|
|
|
/* SBUS */
|
|
/* SBUS */
|
|
{
|
|
{
|
|
.name = "sbus",
|
|
.name = "sbus",
|
|
@@ -459,7 +430,6 @@ static struct of_bus of_busses[] = {
|
|
.match = of_bus_sbus_match,
|
|
.match = of_bus_sbus_match,
|
|
.count_cells = of_bus_sbus_count_cells,
|
|
.count_cells = of_bus_sbus_count_cells,
|
|
.map = of_bus_sbus_map,
|
|
.map = of_bus_sbus_map,
|
|
- .translate = of_bus_sbus_translate,
|
|
|
|
.get_flags = of_bus_sbus_get_flags,
|
|
.get_flags = of_bus_sbus_get_flags,
|
|
},
|
|
},
|
|
/* Default */
|
|
/* Default */
|
|
@@ -469,7 +439,6 @@ static struct of_bus of_busses[] = {
|
|
.match = NULL,
|
|
.match = NULL,
|
|
.count_cells = of_bus_default_count_cells,
|
|
.count_cells = of_bus_default_count_cells,
|
|
.map = of_bus_default_map,
|
|
.map = of_bus_default_map,
|
|
- .translate = of_bus_default_translate,
|
|
|
|
.get_flags = of_bus_default_get_flags,
|
|
.get_flags = of_bus_default_get_flags,
|
|
},
|
|
},
|
|
};
|
|
};
|
|
@@ -494,33 +463,62 @@ static int __init build_one_resource(struct device_node *parent,
|
|
u32 *ranges;
|
|
u32 *ranges;
|
|
unsigned int rlen;
|
|
unsigned int rlen;
|
|
int rone;
|
|
int rone;
|
|
- u64 offset = OF_BAD_ADDR;
|
|
|
|
|
|
|
|
ranges = of_get_property(parent, "ranges", &rlen);
|
|
ranges = of_get_property(parent, "ranges", &rlen);
|
|
if (ranges == NULL || rlen == 0) {
|
|
if (ranges == NULL || rlen == 0) {
|
|
- offset = of_read_addr(addr, na);
|
|
|
|
- memset(addr, 0, pna * 4);
|
|
|
|
- goto finish;
|
|
|
|
|
|
+ u32 result[OF_MAX_ADDR_CELLS];
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ memset(result, 0, pna * 4);
|
|
|
|
+ for (i = 0; i < na; i++)
|
|
|
|
+ result[pna - 1 - i] =
|
|
|
|
+ addr[na - 1 - i];
|
|
|
|
+
|
|
|
|
+ memcpy(addr, result, pna * 4);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* Now walk through the ranges */
|
|
/* Now walk through the ranges */
|
|
rlen /= 4;
|
|
rlen /= 4;
|
|
rone = na + pna + ns;
|
|
rone = na + pna + ns;
|
|
for (; rlen >= rone; rlen -= rone, ranges += rone) {
|
|
for (; rlen >= rone; rlen -= rone, ranges += rone) {
|
|
- offset = bus->map(addr, ranges, na, ns, pna);
|
|
|
|
- if (offset != OF_BAD_ADDR)
|
|
|
|
- break;
|
|
|
|
|
|
+ if (!bus->map(addr, ranges, na, ns, pna))
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
- if (offset == OF_BAD_ADDR)
|
|
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int __init use_1to1_mapping(struct device_node *pp)
|
|
|
|
+{
|
|
|
|
+ char *model;
|
|
|
|
+
|
|
|
|
+ /* If this is on the PMU bus, don't try to translate it even
|
|
|
|
+ * if a ranges property exists.
|
|
|
|
+ */
|
|
|
|
+ if (!strcmp(pp->name, "pmu"))
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
- memcpy(addr, ranges + na, 4 * pna);
|
|
|
|
|
|
+ /* If we have a ranges property in the parent, use it. */
|
|
|
|
+ if (of_find_property(pp, "ranges", NULL) != NULL)
|
|
|
|
+ return 0;
|
|
|
|
|
|
-finish:
|
|
|
|
- /* Translate it into parent bus space */
|
|
|
|
- return pbus->translate(addr, offset, pna);
|
|
|
|
|
|
+ /* If the parent is the dma node of an ISA bus, pass
|
|
|
|
+ * the translation up to the root.
|
|
|
|
+ */
|
|
|
|
+ if (!strcmp(pp->name, "dma"))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ /* Similarly for Simba PCI bridges. */
|
|
|
|
+ model = of_get_property(pp, "model", NULL);
|
|
|
|
+ if (model && !strcmp(model, "SUNW,simba"))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int of_resource_verbose;
|
|
|
|
+
|
|
static void __init build_device_resources(struct of_device *op,
|
|
static void __init build_device_resources(struct of_device *op,
|
|
struct device *parent)
|
|
struct device *parent)
|
|
{
|
|
{
|
|
@@ -564,15 +562,7 @@ static void __init build_device_resources(struct of_device *op,
|
|
|
|
|
|
memcpy(addr, reg, na * 4);
|
|
memcpy(addr, reg, na * 4);
|
|
|
|
|
|
- /* If the immediate parent has no ranges property to apply,
|
|
|
|
- * just use a 1<->1 mapping. Unless it is the 'dma' child
|
|
|
|
- * of an isa bus, which must be passed up towards the root.
|
|
|
|
- *
|
|
|
|
- * Also, don't try to translate PMU bus device registers.
|
|
|
|
- */
|
|
|
|
- if ((of_find_property(pp, "ranges", NULL) == NULL &&
|
|
|
|
- strcmp(pp->name, "dma") != 0) ||
|
|
|
|
- !strcmp(pp->name, "pmu")) {
|
|
|
|
|
|
+ if (use_1to1_mapping(pp)) {
|
|
result = of_read_addr(addr, na);
|
|
result = of_read_addr(addr, na);
|
|
goto build_res;
|
|
goto build_res;
|
|
}
|
|
}
|
|
@@ -591,7 +581,8 @@ static void __init build_device_resources(struct of_device *op,
|
|
pbus = of_match_bus(pp);
|
|
pbus = of_match_bus(pp);
|
|
pbus->count_cells(dp, &pna, &pns);
|
|
pbus->count_cells(dp, &pna, &pns);
|
|
|
|
|
|
- if (build_one_resource(dp, bus, pbus, addr, dna, dns, pna))
|
|
|
|
|
|
+ if (build_one_resource(dp, bus, pbus, addr,
|
|
|
|
+ dna, dns, pna))
|
|
break;
|
|
break;
|
|
|
|
|
|
dna = pna;
|
|
dna = pna;
|
|
@@ -601,6 +592,12 @@ static void __init build_device_resources(struct of_device *op,
|
|
|
|
|
|
build_res:
|
|
build_res:
|
|
memset(r, 0, sizeof(*r));
|
|
memset(r, 0, sizeof(*r));
|
|
|
|
+
|
|
|
|
+ if (of_resource_verbose)
|
|
|
|
+ printk("%s reg[%d] -> %lx\n",
|
|
|
|
+ op->node->full_name, index,
|
|
|
|
+ result);
|
|
|
|
+
|
|
if (result != OF_BAD_ADDR) {
|
|
if (result != OF_BAD_ADDR) {
|
|
if (tlb_type == hypervisor)
|
|
if (tlb_type == hypervisor)
|
|
result &= 0x0fffffffffffffffUL;
|
|
result &= 0x0fffffffffffffffUL;
|
|
@@ -684,6 +681,8 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int of_irq_verbose;
|
|
|
|
+
|
|
static unsigned int __init build_one_device_irq(struct of_device *op,
|
|
static unsigned int __init build_one_device_irq(struct of_device *op,
|
|
struct device *parent,
|
|
struct device *parent,
|
|
unsigned int irq)
|
|
unsigned int irq)
|
|
@@ -698,10 +697,11 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
|
|
if (dp->irq_trans) {
|
|
if (dp->irq_trans) {
|
|
irq = dp->irq_trans->irq_build(dp, irq,
|
|
irq = dp->irq_trans->irq_build(dp, irq,
|
|
dp->irq_trans->data);
|
|
dp->irq_trans->data);
|
|
-#if 1
|
|
|
|
- printk("%s: direct translate %x --> %x\n",
|
|
|
|
- dp->full_name, orig_irq, irq);
|
|
|
|
-#endif
|
|
|
|
|
|
+
|
|
|
|
+ if (of_irq_verbose)
|
|
|
|
+ printk("%s: direct translate %x --> %x\n",
|
|
|
|
+ dp->full_name, orig_irq, irq);
|
|
|
|
+
|
|
return irq;
|
|
return irq;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -728,12 +728,13 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
|
|
iret = apply_interrupt_map(dp, pp,
|
|
iret = apply_interrupt_map(dp, pp,
|
|
imap, imlen, imsk,
|
|
imap, imlen, imsk,
|
|
&irq);
|
|
&irq);
|
|
-#if 1
|
|
|
|
- printk("%s: Apply [%s:%x] imap --> [%s:%x]\n",
|
|
|
|
- op->node->full_name,
|
|
|
|
- pp->full_name, this_orig_irq,
|
|
|
|
- (iret ? iret->full_name : "NULL"), irq);
|
|
|
|
-#endif
|
|
|
|
|
|
+
|
|
|
|
+ if (of_irq_verbose)
|
|
|
|
+ printk("%s: Apply [%s:%x] imap --> [%s:%x]\n",
|
|
|
|
+ op->node->full_name,
|
|
|
|
+ pp->full_name, this_orig_irq,
|
|
|
|
+ (iret ? iret->full_name : "NULL"), irq);
|
|
|
|
+
|
|
if (!iret)
|
|
if (!iret)
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -747,11 +748,13 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
|
|
unsigned int this_orig_irq = irq;
|
|
unsigned int this_orig_irq = irq;
|
|
|
|
|
|
irq = pci_irq_swizzle(dp, pp, irq);
|
|
irq = pci_irq_swizzle(dp, pp, irq);
|
|
-#if 1
|
|
|
|
- printk("%s: PCI swizzle [%s] %x --> %x\n",
|
|
|
|
- op->node->full_name,
|
|
|
|
- pp->full_name, this_orig_irq, irq);
|
|
|
|
-#endif
|
|
|
|
|
|
+ if (of_irq_verbose)
|
|
|
|
+ printk("%s: PCI swizzle [%s] "
|
|
|
|
+ "%x --> %x\n",
|
|
|
|
+ op->node->full_name,
|
|
|
|
+ pp->full_name, this_orig_irq,
|
|
|
|
+ irq);
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
if (pp->irq_trans) {
|
|
if (pp->irq_trans) {
|
|
@@ -767,10 +770,9 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
|
|
|
|
|
|
irq = ip->irq_trans->irq_build(op->node, irq,
|
|
irq = ip->irq_trans->irq_build(op->node, irq,
|
|
ip->irq_trans->data);
|
|
ip->irq_trans->data);
|
|
-#if 1
|
|
|
|
- printk("%s: Apply IRQ trans [%s] %x --> %x\n",
|
|
|
|
- op->node->full_name, ip->full_name, orig_irq, irq);
|
|
|
|
-#endif
|
|
|
|
|
|
+ if (of_irq_verbose)
|
|
|
|
+ printk("%s: Apply IRQ trans [%s] %x --> %x\n",
|
|
|
|
+ op->node->full_name, ip->full_name, orig_irq, irq);
|
|
|
|
|
|
return irq;
|
|
return irq;
|
|
}
|
|
}
|
|
@@ -870,6 +872,20 @@ static int __init of_bus_driver_init(void)
|
|
|
|
|
|
postcore_initcall(of_bus_driver_init);
|
|
postcore_initcall(of_bus_driver_init);
|
|
|
|
|
|
|
|
+static int __init of_debug(char *str)
|
|
|
|
+{
|
|
|
|
+ int val = 0;
|
|
|
|
+
|
|
|
|
+ get_option(&str, &val);
|
|
|
|
+ if (val & 1)
|
|
|
|
+ of_resource_verbose = 1;
|
|
|
|
+ if (val & 2)
|
|
|
|
+ of_irq_verbose = 1;
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+__setup("of_debug=", of_debug);
|
|
|
|
+
|
|
int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
|
|
int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
|
|
{
|
|
{
|
|
/* initialize common driver fields */
|
|
/* initialize common driver fields */
|