[SPARC64]: Convert sparc64 PCI layer to in-kernel device tree.
One thing this change pointed out was that we really should pull the "get 'local-mac-address' property" logic into a helper function all the network drivers can call. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
765b5f3273
Коммит
de8d28b16f
|
@ -553,7 +553,7 @@ void __init ebus_init(void)
|
|||
}
|
||||
|
||||
cookie = pdev->sysdata;
|
||||
ebusnd = cookie->prom_node;
|
||||
ebusnd = cookie->prom_node->node;
|
||||
|
||||
ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
|
||||
ebus->next = NULL;
|
||||
|
@ -578,7 +578,7 @@ void __init ebus_init(void)
|
|||
}
|
||||
ebus->is_rio = is_rio;
|
||||
cookie = pdev->sysdata;
|
||||
ebusnd = cookie->prom_node;
|
||||
ebusnd = cookie->prom_node->node;
|
||||
continue;
|
||||
}
|
||||
printk("ebus%d:", num_ebus);
|
||||
|
@ -622,7 +622,7 @@ void __init ebus_init(void)
|
|||
break;
|
||||
|
||||
cookie = pdev->sysdata;
|
||||
ebusnd = cookie->prom_node;
|
||||
ebusnd = cookie->prom_node->node;
|
||||
|
||||
ebus->next = ebus_alloc(sizeof(struct linux_ebus));
|
||||
ebus = ebus->next;
|
||||
|
|
|
@ -291,8 +291,8 @@ void __init isa_init(void)
|
|||
isa_br->parent = pbm;
|
||||
isa_br->self = pdev;
|
||||
isa_br->index = index++;
|
||||
isa_br->prom_node = pdev_cookie->prom_node;
|
||||
strncpy(isa_br->prom_name, pdev_cookie->prom_name,
|
||||
isa_br->prom_node = pdev_cookie->prom_node->node;
|
||||
strncpy(isa_br->prom_name, pdev_cookie->prom_node->name,
|
||||
sizeof(isa_br->prom_name));
|
||||
|
||||
prop_len = prom_getproperty(isa_br->prom_node,
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#include <linux/init.h>
|
||||
|
||||
#include <asm/pbm.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
#include "pci_impl.h"
|
||||
|
||||
/* Pass "pci=irq_verbose" on the kernel command line to enable this. */
|
||||
int pci_irq_verbose;
|
||||
|
@ -31,16 +34,14 @@ void __init pci_fixup_host_bridge_self(struct pci_bus *pbus)
|
|||
prom_halt();
|
||||
}
|
||||
|
||||
/* Find the OBP PROM device tree node for a PCI device.
|
||||
* Return zero if not found.
|
||||
*/
|
||||
static int __init find_device_prom_node(struct pci_pbm_info *pbm,
|
||||
struct pci_dev *pdev,
|
||||
int bus_prom_node,
|
||||
struct linux_prom_pci_registers *pregs,
|
||||
int *nregs)
|
||||
/* Find the OBP PROM device tree node for a PCI device. */
|
||||
static struct device_node * __init
|
||||
find_device_prom_node(struct pci_pbm_info *pbm, struct pci_dev *pdev,
|
||||
struct device_node *bus_node,
|
||||
struct linux_prom_pci_registers **pregs,
|
||||
int *nregs)
|
||||
{
|
||||
int node;
|
||||
struct device_node *dp;
|
||||
|
||||
*nregs = 0;
|
||||
|
||||
|
@ -57,24 +58,30 @@ static int __init find_device_prom_node(struct pci_pbm_info *pbm,
|
|||
pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO ||
|
||||
pdev->device == PCI_DEVICE_ID_SUN_SABRE ||
|
||||
pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD))
|
||||
return bus_prom_node;
|
||||
return bus_node;
|
||||
|
||||
node = prom_getchild(bus_prom_node);
|
||||
while (node != 0) {
|
||||
int err = prom_getproperty(node, "reg",
|
||||
(char *)pregs,
|
||||
sizeof(*pregs) * PROMREG_MAX);
|
||||
if (err == 0 || err == -1)
|
||||
dp = bus_node->child;
|
||||
while (dp) {
|
||||
struct linux_prom_pci_registers *regs;
|
||||
struct property *prop;
|
||||
int len;
|
||||
|
||||
prop = of_find_property(dp, "reg", &len);
|
||||
if (!prop)
|
||||
goto do_next_sibling;
|
||||
if (((pregs[0].phys_hi >> 8) & 0xff) == pdev->devfn) {
|
||||
*nregs = err / sizeof(*pregs);
|
||||
return node;
|
||||
|
||||
regs = prop->value;
|
||||
if (((regs[0].phys_hi >> 8) & 0xff) == pdev->devfn) {
|
||||
*pregs = regs;
|
||||
*nregs = len / sizeof(struct linux_prom_pci_registers);
|
||||
return dp;
|
||||
}
|
||||
|
||||
do_next_sibling:
|
||||
node = prom_getsibling(node);
|
||||
dp = dp->sibling;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Older versions of OBP on PCI systems encode 64-bit MEM
|
||||
|
@ -131,15 +138,17 @@ static void __init fixup_obp_assignments(struct pci_dev *pdev,
|
|||
*/
|
||||
static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
|
||||
struct pci_dev *pdev,
|
||||
int bus_prom_node)
|
||||
struct device_node *bus_node)
|
||||
{
|
||||
struct linux_prom_pci_registers pregs[PROMREG_MAX];
|
||||
struct linux_prom_pci_registers *pregs = NULL;
|
||||
struct pcidev_cookie *pcp;
|
||||
int device_prom_node, nregs, err;
|
||||
struct device_node *dp;
|
||||
struct property *prop;
|
||||
int nregs, len;
|
||||
|
||||
device_prom_node = find_device_prom_node(pbm, pdev, bus_prom_node,
|
||||
pregs, &nregs);
|
||||
if (device_prom_node == 0) {
|
||||
dp = find_device_prom_node(pbm, pdev, bus_node,
|
||||
&pregs, &nregs);
|
||||
if (!dp) {
|
||||
/* If it is not in the OBP device tree then
|
||||
* there must be a damn good reason for it.
|
||||
*
|
||||
|
@ -153,45 +162,43 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
|
|||
return;
|
||||
}
|
||||
|
||||
pcp = kmalloc(sizeof(*pcp), GFP_ATOMIC);
|
||||
pcp = kzalloc(sizeof(*pcp), GFP_ATOMIC);
|
||||
if (pcp == NULL) {
|
||||
prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n");
|
||||
prom_halt();
|
||||
}
|
||||
pcp->pbm = pbm;
|
||||
pcp->prom_node = device_prom_node;
|
||||
memcpy(pcp->prom_regs, pregs, sizeof(pcp->prom_regs));
|
||||
pcp->prom_node = dp;
|
||||
memcpy(pcp->prom_regs, pregs,
|
||||
nregs * sizeof(struct linux_prom_pci_registers));
|
||||
pcp->num_prom_regs = nregs;
|
||||
err = prom_getproperty(device_prom_node, "name",
|
||||
pcp->prom_name, sizeof(pcp->prom_name));
|
||||
if (err > 0)
|
||||
pcp->prom_name[err] = 0;
|
||||
else
|
||||
pcp->prom_name[0] = 0;
|
||||
|
||||
err = prom_getproperty(device_prom_node,
|
||||
"assigned-addresses",
|
||||
(char *)pcp->prom_assignments,
|
||||
sizeof(pcp->prom_assignments));
|
||||
if (err == 0 || err == -1)
|
||||
/* We can't have the pcidev_cookie assignments be just
|
||||
* direct pointers into the property value, since they
|
||||
* are potentially modified by the probing process.
|
||||
*/
|
||||
prop = of_find_property(dp, "assigned-addresses", &len);
|
||||
if (!prop) {
|
||||
pcp->num_prom_assignments = 0;
|
||||
else
|
||||
} else {
|
||||
memcpy(pcp->prom_assignments, prop->value, len);
|
||||
pcp->num_prom_assignments =
|
||||
(err / sizeof(pcp->prom_assignments[0]));
|
||||
(len / sizeof(pcp->prom_assignments[0]));
|
||||
}
|
||||
|
||||
if (strcmp(pcp->prom_name, "ebus") == 0) {
|
||||
struct linux_prom_ebus_ranges erng[PROM_PCIRNG_MAX];
|
||||
if (strcmp(dp->name, "ebus") == 0) {
|
||||
struct linux_prom_ebus_ranges *erng;
|
||||
int iter;
|
||||
|
||||
/* EBUS is special... */
|
||||
err = prom_getproperty(device_prom_node, "ranges",
|
||||
(char *)&erng[0], sizeof(erng));
|
||||
if (err == 0 || err == -1) {
|
||||
prop = of_find_property(dp, "ranges", &len);
|
||||
if (!prop) {
|
||||
prom_printf("EBUS: Fatal error, no range property\n");
|
||||
prom_halt();
|
||||
}
|
||||
err = (err / sizeof(erng[0]));
|
||||
for(iter = 0; iter < err; iter++) {
|
||||
erng = prop->value;
|
||||
len = (len / sizeof(erng[0]));
|
||||
for (iter = 0; iter < len; iter++) {
|
||||
struct linux_prom_ebus_ranges *ep = &erng[iter];
|
||||
struct linux_prom_pci_registers *ap;
|
||||
|
||||
|
@ -203,7 +210,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
|
|||
ap->size_hi = 0;
|
||||
ap->size_lo = ep->size;
|
||||
}
|
||||
pcp->num_prom_assignments = err;
|
||||
pcp->num_prom_assignments = len;
|
||||
}
|
||||
|
||||
fixup_obp_assignments(pdev, pcp);
|
||||
|
@ -213,7 +220,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
|
|||
|
||||
void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
|
||||
struct pci_pbm_info *pbm,
|
||||
int prom_node)
|
||||
struct device_node *dp)
|
||||
{
|
||||
struct pci_dev *pdev, *pdev_next;
|
||||
struct pci_bus *this_pbus, *pbus_next;
|
||||
|
@ -221,7 +228,7 @@ void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
|
|||
/* This must be _safe because the cookie fillin
|
||||
routine can delete devices from the tree. */
|
||||
list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list)
|
||||
pdev_cookie_fillin(pbm, pdev, prom_node);
|
||||
pdev_cookie_fillin(pbm, pdev, dp);
|
||||
|
||||
list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) {
|
||||
struct pcidev_cookie *pcp = this_pbus->self->sysdata;
|
||||
|
@ -244,7 +251,6 @@ static void __init bad_assignment(struct pci_dev *pdev,
|
|||
if (res)
|
||||
prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n",
|
||||
res->start, res->end, res->flags);
|
||||
prom_printf("Please email this information to davem@redhat.com\n");
|
||||
if (do_prom_halt)
|
||||
prom_halt();
|
||||
}
|
||||
|
@ -276,8 +282,7 @@ __init get_root_resource(struct linux_prom_pci_registers *ap,
|
|||
return &pbm->mem_space;
|
||||
|
||||
default:
|
||||
printk("PCI: What is resource space %x? "
|
||||
"Tell davem@redhat.com about it!\n", space);
|
||||
printk("PCI: What is resource space %x?\n", space);
|
||||
return NULL;
|
||||
};
|
||||
}
|
||||
|
@ -572,50 +577,51 @@ static inline unsigned int pci_apply_intmap(struct pci_pbm_info *pbm,
|
|||
struct pci_dev *pbus,
|
||||
struct pci_dev *pdev,
|
||||
unsigned int interrupt,
|
||||
unsigned int *cnode)
|
||||
struct device_node **cnode)
|
||||
{
|
||||
struct linux_prom_pci_intmap imap[PROM_PCIIMAP_MAX];
|
||||
struct linux_prom_pci_intmask imask;
|
||||
struct linux_prom_pci_intmap *imap;
|
||||
struct linux_prom_pci_intmask *imask;
|
||||
struct pcidev_cookie *pbus_pcp = pbus->sysdata;
|
||||
struct pcidev_cookie *pdev_pcp = pdev->sysdata;
|
||||
struct linux_prom_pci_registers *pregs = pdev_pcp->prom_regs;
|
||||
struct property *prop;
|
||||
int plen, num_imap, i;
|
||||
unsigned int hi, mid, lo, irq, orig_interrupt;
|
||||
|
||||
*cnode = pbus_pcp->prom_node;
|
||||
|
||||
plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map",
|
||||
(char *) &imap[0], sizeof(imap));
|
||||
if (plen <= 0 ||
|
||||
prop = of_find_property(pbus_pcp->prom_node, "interrupt-map", &plen);
|
||||
if (!prop ||
|
||||
(plen % sizeof(struct linux_prom_pci_intmap)) != 0) {
|
||||
printk("%s: Device %s interrupt-map has bad len %d\n",
|
||||
pbm->name, pci_name(pbus), plen);
|
||||
goto no_intmap;
|
||||
}
|
||||
imap = prop->value;
|
||||
num_imap = plen / sizeof(struct linux_prom_pci_intmap);
|
||||
|
||||
plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map-mask",
|
||||
(char *) &imask, sizeof(imask));
|
||||
if (plen <= 0 ||
|
||||
prop = of_find_property(pbus_pcp->prom_node, "interrupt-map-mask", &plen);
|
||||
if (!prop ||
|
||||
(plen % sizeof(struct linux_prom_pci_intmask)) != 0) {
|
||||
printk("%s: Device %s interrupt-map-mask has bad len %d\n",
|
||||
pbm->name, pci_name(pbus), plen);
|
||||
goto no_intmap;
|
||||
}
|
||||
imask = prop->value;
|
||||
|
||||
orig_interrupt = interrupt;
|
||||
|
||||
hi = pregs->phys_hi & imask.phys_hi;
|
||||
mid = pregs->phys_mid & imask.phys_mid;
|
||||
lo = pregs->phys_lo & imask.phys_lo;
|
||||
irq = interrupt & imask.interrupt;
|
||||
hi = pregs->phys_hi & imask->phys_hi;
|
||||
mid = pregs->phys_mid & imask->phys_mid;
|
||||
lo = pregs->phys_lo & imask->phys_lo;
|
||||
irq = interrupt & imask->interrupt;
|
||||
|
||||
for (i = 0; i < num_imap; i++) {
|
||||
if (imap[i].phys_hi == hi &&
|
||||
imap[i].phys_mid == mid &&
|
||||
imap[i].phys_lo == lo &&
|
||||
imap[i].interrupt == irq) {
|
||||
*cnode = imap[i].cnode;
|
||||
*cnode = of_find_node_by_phandle(imap[i].cnode);
|
||||
interrupt = imap[i].cinterrupt;
|
||||
}
|
||||
}
|
||||
|
@ -638,21 +644,22 @@ no_intmap:
|
|||
* all interrupt translations are complete, else we should use that node's
|
||||
* "reg" property to apply the PBM's "interrupt-{map,mask}" to the interrupt.
|
||||
*/
|
||||
static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm,
|
||||
struct pci_dev *pdev,
|
||||
unsigned int *interrupt)
|
||||
static struct device_node * __init
|
||||
pci_intmap_match_to_root(struct pci_pbm_info *pbm,
|
||||
struct pci_dev *pdev,
|
||||
unsigned int *interrupt)
|
||||
{
|
||||
struct pci_dev *toplevel_pdev = pdev;
|
||||
struct pcidev_cookie *toplevel_pcp = toplevel_pdev->sysdata;
|
||||
unsigned int cnode = toplevel_pcp->prom_node;
|
||||
struct device_node *cnode = toplevel_pcp->prom_node;
|
||||
|
||||
while (pdev->bus->number != pbm->pci_first_busno) {
|
||||
struct pci_dev *pbus = pdev->bus->self;
|
||||
struct pcidev_cookie *pcp = pbus->sysdata;
|
||||
int plen;
|
||||
struct property *prop;
|
||||
|
||||
plen = prom_getproplen(pcp->prom_node, "interrupt-map");
|
||||
if (plen <= 0) {
|
||||
prop = of_find_property(pcp->prom_node, "interrupt-map", NULL);
|
||||
if (!prop) {
|
||||
*interrupt = pci_slot_swivel(pbm, toplevel_pdev,
|
||||
pdev, *interrupt);
|
||||
cnode = pcp->prom_node;
|
||||
|
@ -669,7 +676,7 @@ static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm,
|
|||
}
|
||||
pdev = pbus;
|
||||
|
||||
if (cnode == pbm->prom_node->node)
|
||||
if (cnode == pbm->prom_node)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -680,21 +687,24 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
|
|||
{
|
||||
struct pcidev_cookie *dev_pcp = pdev->sysdata;
|
||||
struct pci_pbm_info *pbm = dev_pcp->pbm;
|
||||
struct linux_prom_pci_registers reg[PROMREG_MAX];
|
||||
struct linux_prom_pci_registers *reg;
|
||||
struct device_node *cnode;
|
||||
struct property *prop;
|
||||
unsigned int hi, mid, lo, irq;
|
||||
int i, cnode, plen;
|
||||
int i, plen;
|
||||
|
||||
cnode = pci_intmap_match_to_root(pbm, pdev, interrupt);
|
||||
if (cnode == pbm->prom_node->node)
|
||||
if (cnode == pbm->prom_node)
|
||||
goto success;
|
||||
|
||||
plen = prom_getproperty(cnode, "reg", (char *) reg, sizeof(reg));
|
||||
if (plen <= 0 ||
|
||||
prop = of_find_property(cnode, "reg", &plen);
|
||||
if (!prop ||
|
||||
(plen % sizeof(struct linux_prom_pci_registers)) != 0) {
|
||||
printk("%s: OBP node %x reg property has bad len %d\n",
|
||||
pbm->name, cnode, plen);
|
||||
printk("%s: OBP node %s reg property has bad len %d\n",
|
||||
pbm->name, cnode->full_name, plen);
|
||||
goto fail;
|
||||
}
|
||||
reg = prop->value;
|
||||
|
||||
hi = reg[0].phys_hi & pbm->pbm_intmask->phys_hi;
|
||||
mid = reg[0].phys_mid & pbm->pbm_intmask->phys_mid;
|
||||
|
@ -734,8 +744,8 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
|
|||
struct pci_controller_info *p = pbm->parent;
|
||||
unsigned int portid = pbm->portid;
|
||||
unsigned int prom_irq;
|
||||
int prom_node = pcp->prom_node;
|
||||
int err;
|
||||
struct device_node *dp = pcp->prom_node;
|
||||
struct property *prop;
|
||||
|
||||
/* If this is an empty EBUS device, sometimes OBP fails to
|
||||
* give it a valid fully specified interrupts property.
|
||||
|
@ -746,17 +756,17 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
|
|||
*/
|
||||
if (pdev->vendor == PCI_VENDOR_ID_SUN &&
|
||||
pdev->device == PCI_DEVICE_ID_SUN_EBUS &&
|
||||
!prom_getchild(prom_node)) {
|
||||
!dp->child) {
|
||||
pdev->irq = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
err = prom_getproperty(prom_node, "interrupts",
|
||||
(char *)&prom_irq, sizeof(prom_irq));
|
||||
if (err == 0 || err == -1) {
|
||||
prop = of_find_property(dp, "interrupts", NULL);
|
||||
if (!prop) {
|
||||
pdev->irq = 0;
|
||||
return;
|
||||
}
|
||||
prom_irq = *(unsigned int *) prop->value;
|
||||
|
||||
if (tlb_type != hypervisor) {
|
||||
/* Fully specified already? */
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
extern struct pci_controller_info *pci_controller_root;
|
||||
|
||||
|
@ -19,7 +20,7 @@ extern int pci_num_controllers;
|
|||
extern void pci_fixup_host_bridge_self(struct pci_bus *pbus);
|
||||
extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus,
|
||||
struct pci_pbm_info *pbm,
|
||||
int prom_node);
|
||||
struct device_node *prom_node);
|
||||
extern void pci_record_assignments(struct pci_pbm_info *pbm,
|
||||
struct pci_bus *pbus);
|
||||
extern void pci_assign_unassigned(struct pci_pbm_info *pbm,
|
||||
|
|
|
@ -1104,7 +1104,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
|
|||
pci_fixup_host_bridge_self(pbm->pci_bus);
|
||||
pbm->pci_bus->self->sysdata = cookie;
|
||||
|
||||
pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node->node);
|
||||
pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
|
||||
pci_record_assignments(pbm, pbm->pci_bus);
|
||||
pci_assign_unassigned(pbm, pbm->pci_bus);
|
||||
pci_fixup_irq(pbm, pbm->pci_bus);
|
||||
|
|
|
@ -1161,7 +1161,7 @@ static void sabre_scan_bus(struct pci_controller_info *p)
|
|||
|
||||
pbus->sysdata = pbm;
|
||||
pbm->pci_bus = pbus;
|
||||
pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node->node);
|
||||
pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node);
|
||||
pci_record_assignments(pbm, pbus);
|
||||
pci_assign_unassigned(pbm, pbus);
|
||||
pci_fixup_irq(pbm, pbus);
|
||||
|
@ -1174,7 +1174,7 @@ static void sabre_scan_bus(struct pci_controller_info *p)
|
|||
pbm = &p->pbm_A;
|
||||
sabre_bus->sysdata = pbm;
|
||||
pbm->pci_bus = sabre_bus;
|
||||
pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node->node);
|
||||
pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node);
|
||||
pci_record_assignments(pbm, sabre_bus);
|
||||
pci_assign_unassigned(pbm, sabre_bus);
|
||||
pci_fixup_irq(pbm, sabre_bus);
|
||||
|
|
|
@ -1438,7 +1438,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
|
|||
pci_fixup_host_bridge_self(pbm->pci_bus);
|
||||
pbm->pci_bus->self->sysdata = cookie;
|
||||
|
||||
pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node->node);
|
||||
pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
|
||||
pci_record_assignments(pbm, pbm->pci_bus);
|
||||
pci_assign_unassigned(pbm, pbm->pci_bus);
|
||||
pci_fixup_irq(pbm, pbm->pci_bus);
|
||||
|
|
|
@ -814,8 +814,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
|
|||
pci_fixup_host_bridge_self(pbm->pci_bus);
|
||||
pbm->pci_bus->self->sysdata = cookie;
|
||||
#endif
|
||||
pci_fill_in_pbm_cookies(pbm->pci_bus, pbm,
|
||||
pbm->prom_node->node);
|
||||
pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
|
||||
pci_record_assignments(pbm, pbm->pci_bus);
|
||||
pci_assign_unassigned(pbm, pbm->pci_bus);
|
||||
pci_fixup_irq(pbm, pbm->pci_bus);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
#include <asm/oplib.h>
|
||||
|
@ -63,6 +64,17 @@ struct device_node *of_find_node_by_path(const char *path)
|
|||
return np;
|
||||
}
|
||||
|
||||
struct device_node *of_find_node_by_phandle(phandle handle)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
for (np = allnodes; np != 0; np = np->allnext)
|
||||
if (np->node == handle)
|
||||
break;
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name)
|
||||
{
|
||||
|
@ -103,6 +115,18 @@ struct property *of_find_property(struct device_node *np, const char *name,
|
|||
}
|
||||
return pp;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_property);
|
||||
|
||||
/*
|
||||
* Find a property with a given name for a given node
|
||||
* and return the value.
|
||||
*/
|
||||
void *of_get_property(struct device_node *np, const char *name, int *lenp)
|
||||
{
|
||||
struct property *pp = of_find_property(np,name,lenp);
|
||||
return pp ? pp->value : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_property);
|
||||
|
||||
int of_getintprop_default(struct device_node *np, const char *name, int def)
|
||||
{
|
||||
|
@ -115,6 +139,7 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
|
|||
|
||||
return *(int *) prop->value;
|
||||
}
|
||||
EXPORT_SYMBOL(of_getintprop_default);
|
||||
|
||||
static unsigned int prom_early_allocated;
|
||||
|
||||
|
|
|
@ -2880,17 +2880,20 @@ static int __devinit gem_get_device_address(struct gem *gp)
|
|||
#if defined(__sparc__)
|
||||
struct pci_dev *pdev = gp->pdev;
|
||||
struct pcidev_cookie *pcp = pdev->sysdata;
|
||||
int node = -1;
|
||||
int use_idprom = 1;
|
||||
|
||||
if (pcp != NULL) {
|
||||
node = pcp->prom_node;
|
||||
if (prom_getproplen(node, "local-mac-address") == 6)
|
||||
prom_getproperty(node, "local-mac-address",
|
||||
dev->dev_addr, 6);
|
||||
else
|
||||
node = -1;
|
||||
unsigned char *addr;
|
||||
int len;
|
||||
|
||||
addr = of_get_property(pcp->prom_node, "local-mac-address",
|
||||
&len);
|
||||
if (addr && len == 6) {
|
||||
use_idprom = 0;
|
||||
memcpy(dev->dev_addr, addr, 6);
|
||||
}
|
||||
}
|
||||
if (node == -1)
|
||||
if (use_idprom)
|
||||
memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
|
||||
#elif defined(CONFIG_PPC_PMAC)
|
||||
unsigned char *addr;
|
||||
|
|
|
@ -3013,7 +3013,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
|
|||
struct quattro *qp = NULL;
|
||||
#ifdef __sparc__
|
||||
struct pcidev_cookie *pcp;
|
||||
int node;
|
||||
#endif
|
||||
struct happy_meal *hp;
|
||||
struct net_device *dev;
|
||||
|
@ -3026,13 +3025,12 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
|
|||
/* Now make sure pci_dev cookie is there. */
|
||||
#ifdef __sparc__
|
||||
pcp = pdev->sysdata;
|
||||
if (pcp == NULL || pcp->prom_node == -1) {
|
||||
if (pcp == NULL) {
|
||||
printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
node = pcp->prom_node;
|
||||
|
||||
prom_getstring(node, "name", prom_name, sizeof(prom_name));
|
||||
strcpy(prom_name, pcp->prom_node->name);
|
||||
#else
|
||||
if (is_quattro_p(pdev))
|
||||
strcpy(prom_name, "SUNW,qfe");
|
||||
|
@ -3104,10 +3102,14 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
|
|||
macaddr[5]++;
|
||||
} else {
|
||||
#ifdef __sparc__
|
||||
unsigned char *addr;
|
||||
int len;
|
||||
|
||||
if (qfe_slot != -1 &&
|
||||
prom_getproplen(node, "local-mac-address") == 6) {
|
||||
prom_getproperty(node, "local-mac-address",
|
||||
dev->dev_addr, 6);
|
||||
(addr = of_get_property(pcp->prom_node,
|
||||
"local-mac-address", &len)) != NULL
|
||||
&& len == 6) {
|
||||
memcpy(dev->dev_addr, addr, 6);
|
||||
} else {
|
||||
memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
|
||||
}
|
||||
|
@ -3124,7 +3126,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
|
|||
hp->tcvregs = (hpreg_base + 0x7000UL);
|
||||
|
||||
#ifdef __sparc__
|
||||
hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff);
|
||||
hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff);
|
||||
if (hp->hm_revision == 0xff) {
|
||||
unsigned char prev;
|
||||
|
||||
|
|
|
@ -10549,11 +10549,13 @@ static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp)
|
|||
struct pcidev_cookie *pcp = pdev->sysdata;
|
||||
|
||||
if (pcp != NULL) {
|
||||
int node = pcp->prom_node;
|
||||
unsigned char *addr;
|
||||
int len;
|
||||
|
||||
if (prom_getproplen(node, "local-mac-address") == 6) {
|
||||
prom_getproperty(node, "local-mac-address",
|
||||
dev->dev_addr, 6);
|
||||
addr = of_get_property(pcp->prom_node, "local-mac-address",
|
||||
&len);
|
||||
if (addr && len == 6) {
|
||||
memcpy(dev->dev_addr, addr, 6);
|
||||
memcpy(dev->perm_addr, dev->dev_addr, 6);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1550,10 +1550,14 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
|
|||
dev->dev_addr[i] = last_phys_addr[i];
|
||||
dev->dev_addr[i] = last_phys_addr[i] + 1;
|
||||
#if defined(__sparc__)
|
||||
if ((pcp != NULL) && prom_getproplen(pcp->prom_node,
|
||||
"local-mac-address") == 6) {
|
||||
prom_getproperty(pcp->prom_node, "local-mac-address",
|
||||
dev->dev_addr, 6);
|
||||
if (pcp) {
|
||||
unsigned char *addr;
|
||||
int len;
|
||||
|
||||
addr = of_get_property(pcp->prom_node,
|
||||
"local-mac-address", &len);
|
||||
if (addr && len == 6)
|
||||
memcpy(dev->dev_addr, addr, 6);
|
||||
}
|
||||
#endif
|
||||
#if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */
|
||||
|
|
|
@ -243,8 +243,8 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
|
|||
((int *) opp->oprom_array)[1]);
|
||||
|
||||
pcp = pdev->sysdata;
|
||||
if (pcp != NULL && pcp->prom_node != -1 && pcp->prom_node) {
|
||||
node = pcp->prom_node;
|
||||
if (pcp != NULL) {
|
||||
node = pcp->prom_node->node;
|
||||
data->current_node = node;
|
||||
*((int *)opp->oprom_array) = node;
|
||||
opp->oprom_size = sizeof(int);
|
||||
|
|
|
@ -2966,7 +2966,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
pcp = pdev->sysdata;
|
||||
if (node == pcp->prom_node) {
|
||||
if (node == pcp->prom_node->node) {
|
||||
struct fb_var_screeninfo *var = &default_var;
|
||||
unsigned int N, P, Q, M, T, R;
|
||||
u32 v_total, h_total;
|
||||
|
|
|
@ -227,8 +227,7 @@ struct pci_controller_info {
|
|||
*/
|
||||
struct pcidev_cookie {
|
||||
struct pci_pbm_info *pbm;
|
||||
char prom_name[64];
|
||||
int prom_node;
|
||||
struct device_node *prom_node;
|
||||
struct linux_prom_pci_registers prom_regs[PROMREG_MAX];
|
||||
int num_prom_regs;
|
||||
struct linux_prom_pci_registers prom_assignments[PROMREG_MAX];
|
||||
|
|
|
@ -76,12 +76,15 @@ extern struct device_node *of_find_node_by_type(struct device_node *from,
|
|||
for (dn = of_find_node_by_type(NULL, type); dn; \
|
||||
dn = of_find_node_by_type(dn, type))
|
||||
extern struct device_node *of_find_node_by_path(const char *path);
|
||||
extern struct device_node *of_find_node_by_phandle(phandle handle);
|
||||
extern struct device_node *of_get_parent(const struct device_node *node);
|
||||
extern struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev);
|
||||
extern struct property *of_find_property(struct device_node *np,
|
||||
const char *name,
|
||||
int *lenp);
|
||||
extern void *of_get_property(struct device_node *node, const char *name,
|
||||
int *lenp);
|
||||
extern int of_getintprop_default(struct device_node *np,
|
||||
const char *name,
|
||||
int def);
|
||||
|
|
Загрузка…
Ссылка в новой задаче