Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 29551
b: refs/heads/master
c: e87dc35
h: refs/heads/master
i:
  29549: 322bf50
  29547: cbe2d7d
  29543: 836ff4e
  29535: 04bf44d
v: v3
  • Loading branch information
David S. Miller committed Jun 24, 2006
1 parent 7fc55b4 commit c4bedd4
Show file tree
Hide file tree
Showing 8 changed files with 313 additions and 386 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: aaf7cec2769942035985716452107fc5ba0b11f6
refs/heads/master: e87dc35020bc555969810452f44bceaf8394eafa
53 changes: 25 additions & 28 deletions trunk/arch/sparc64/kernel/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <asm/irq.h>
#include <asm/ebus.h>
#include <asm/isa.h>
#include <asm/prom.h>

unsigned long pci_memspace_mask = 0xffffffffUL;

Expand Down Expand Up @@ -177,16 +178,16 @@ void pci_config_write32(u32 *addr, u32 val)
}

/* Probe for all PCI controllers in the system. */
extern void sabre_init(int, char *);
extern void psycho_init(int, char *);
extern void schizo_init(int, char *);
extern void schizo_plus_init(int, char *);
extern void tomatillo_init(int, char *);
extern void sun4v_pci_init(int, char *);
extern void sabre_init(struct device_node *, const char *);
extern void psycho_init(struct device_node *, const char *);
extern void schizo_init(struct device_node *, const char *);
extern void schizo_plus_init(struct device_node *, const char *);
extern void tomatillo_init(struct device_node *, const char *);
extern void sun4v_pci_init(struct device_node *, const char *);

static struct {
char *model_name;
void (*init)(int, char *);
void (*init)(struct device_node *, const char *);
} pci_controller_table[] __initdata = {
{ "SUNW,sabre", sabre_init },
{ "pci108e,a000", sabre_init },
Expand All @@ -204,26 +205,23 @@ static struct {
#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \
sizeof(pci_controller_table[0]))

static int __init pci_controller_init(char *model_name, int namelen, int node)
static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp)
{
int i;

for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) {
if (!strncmp(model_name,
pci_controller_table[i].model_name,
namelen)) {
pci_controller_table[i].init(node, model_name);
pci_controller_table[i].init(dp, model_name);
return 1;
}
}
printk("PCI: Warning unknown controller, model name [%s]\n",
model_name);
printk("PCI: Ignoring controller...\n");

return 0;
}

static int __init pci_is_controller(char *model_name, int namelen, int node)
static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp)
{
int i;

Expand All @@ -237,36 +235,35 @@ static int __init pci_is_controller(char *model_name, int namelen, int node)
return 0;
}

static int __init pci_controller_scan(int (*handler)(char *, int, int))
static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *))
{
char namebuf[64];
int node;
struct device_node *dp;
int count = 0;

node = prom_getchild(prom_root_node);
while ((node = prom_searchsiblings(node, "pci")) != 0) {
for_each_node_by_name(dp, "pci") {
struct property *prop;
int len;

if ((len = prom_getproperty(node, "model", namebuf, sizeof(namebuf))) > 0 ||
(len = prom_getproperty(node, "compatible", namebuf, sizeof(namebuf))) > 0) {
prop = of_find_property(dp, "model", &len);
if (!prop)
prop = of_find_property(dp, "compatible", &len);

if (prop) {
const char *model = prop->value;
int item_len = 0;

/* Our value may be a multi-valued string in the
* case of some compatible properties. For sanity,
* only try the first one. */

while (namebuf[item_len] && len) {
* only try the first one.
*/
while (model[item_len] && len) {
len--;
item_len++;
}

if (handler(namebuf, item_len, node))
if (handler(model, item_len, dp))
count++;
}

node = prom_getsibling(node);
if (!node)
break;
}

return count;
Expand Down
15 changes: 8 additions & 7 deletions trunk/arch/sparc64/kernel/pci_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm,
}
pdev = pbus;

if (cnode == pbm->prom_node)
if (cnode == pbm->prom_node->node)
break;
}

Expand All @@ -680,7 +680,7 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
int i, cnode, plen;

cnode = pci_intmap_match_to_root(pbm, pdev, interrupt);
if (cnode == pbm->prom_node)
if (cnode == pbm->prom_node->node)
goto success;

plen = prom_getproperty(cnode, "reg", (char *) reg, sizeof(reg));
Expand All @@ -691,10 +691,10 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
goto fail;
}

hi = reg[0].phys_hi & pbm->pbm_intmask.phys_hi;
mid = reg[0].phys_mid & pbm->pbm_intmask.phys_mid;
lo = reg[0].phys_lo & pbm->pbm_intmask.phys_lo;
irq = *interrupt & pbm->pbm_intmask.interrupt;
hi = reg[0].phys_hi & pbm->pbm_intmask->phys_hi;
mid = reg[0].phys_mid & pbm->pbm_intmask->phys_mid;
lo = reg[0].phys_lo & pbm->pbm_intmask->phys_lo;
irq = *interrupt & pbm->pbm_intmask->interrupt;

for (i = 0; i < pbm->num_pbm_intmap; i++) {
struct linux_prom_pci_intmap *intmap;
Expand All @@ -714,7 +714,8 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
return 0;

success:
printk("PCI-IRQ: Routing bus[%2x] slot[%2x] to INO[%02x]\n",
printk("%s: Routing bus[%2x] slot[%2x] to INO[%02x]\n",
pbm->name,
pdev->bus->number, PCI_SLOT(pdev->devfn),
*interrupt);
return 1;
Expand Down
108 changes: 50 additions & 58 deletions trunk/arch/sparc64/kernel/pci_psycho.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <asm/iommu.h>
#include <asm/irq.h>
#include <asm/starfire.h>
#include <asm/prom.h>

#include "pci_impl.h"
#include "iommu_common.h"
Expand Down Expand Up @@ -1103,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);
pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node->node);
pci_record_assignments(pbm, pbm->pci_bus);
pci_assign_unassigned(pbm, pbm->pci_bus);
pci_fixup_irq(pbm, pbm->pci_bus);
Expand Down Expand Up @@ -1291,11 +1292,12 @@ static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL

static void psycho_pbm_init(struct pci_controller_info *p,
int prom_node, int is_pbm_a)
struct device_node *dp, int is_pbm_a)
{
unsigned int busrange[2];
unsigned int *busrange;
struct property *prop;
struct pci_pbm_info *pbm;
int err;
int len;

if (is_pbm_a) {
pbm = &p->pbm_A;
Expand All @@ -1310,10 +1312,14 @@ static void psycho_pbm_init(struct pci_controller_info *p,
}

pbm->chip_type = PBM_CHIP_TYPE_PSYCHO;
pbm->chip_version =
prom_getintdefault(prom_node, "version#", 0);
pbm->chip_revision =
prom_getintdefault(prom_node, "module-revision#", 0);
pbm->chip_version = 0;
prop = of_find_property(dp, "version#", NULL);
if (prop)
pbm->chip_version = *(int *) prop->value;
pbm->chip_revision = 0;
prop = of_find_property(dp, "module-revision#", NULL);
if (prop)
pbm->chip_revision = *(int *) prop->value;

pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE;
pbm->io_space.flags = IORESOURCE_IO;
Expand All @@ -1322,45 +1328,36 @@ static void psycho_pbm_init(struct pci_controller_info *p,
pbm_register_toplevel_resources(p, pbm);

pbm->parent = p;
pbm->prom_node = prom_node;
prom_getstring(prom_node, "name",
pbm->prom_name,
sizeof(pbm->prom_name));

err = prom_getproperty(prom_node, "ranges",
(char *)pbm->pbm_ranges,
sizeof(pbm->pbm_ranges));
if (err != -1)
pbm->prom_node = dp;
pbm->name = dp->full_name;

printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n",
pbm->name,
pbm->chip_version, pbm->chip_revision);

prop = of_find_property(dp, "ranges", &len);
if (prop) {
pbm->pbm_ranges = prop->value;
pbm->num_pbm_ranges =
(err / sizeof(struct linux_prom_pci_ranges));
else
(len / sizeof(struct linux_prom_pci_ranges));
} else {
pbm->num_pbm_ranges = 0;
}

err = prom_getproperty(prom_node, "interrupt-map",
(char *)pbm->pbm_intmap,
sizeof(pbm->pbm_intmap));
if (err != -1) {
pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap));
err = prom_getproperty(prom_node, "interrupt-map-mask",
(char *)&pbm->pbm_intmask,
sizeof(pbm->pbm_intmask));
if (err == -1) {
prom_printf("PSYCHO-PBM: Fatal error, no "
"interrupt-map-mask.\n");
prom_halt();
}
prop = of_find_property(dp, "interrupt-map", &len);
if (prop) {
pbm->pbm_intmap = prop->value;
pbm->num_pbm_intmap =
(len / sizeof(struct linux_prom_pci_intmap));

prop = of_find_property(dp, "interrupt-map-mask", NULL);
pbm->pbm_intmask = prop->value;
} else {
pbm->num_pbm_intmap = 0;
memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
}

err = prom_getproperty(prom_node, "bus-range",
(char *)&busrange[0],
sizeof(busrange));
if (err == 0 || err == -1) {
prom_printf("PSYCHO-PBM: Fatal error, no bus-range.\n");
prom_halt();
}
prop = of_find_property(dp, "bus-range", NULL);
busrange = prop->value;
pbm->pci_first_busno = busrange[0];
pbm->pci_last_busno = busrange[1];

Expand All @@ -1369,20 +1366,24 @@ static void psycho_pbm_init(struct pci_controller_info *p,

#define PSYCHO_CONFIGSPACE 0x001000000UL

void psycho_init(int node, char *model_name)
void psycho_init(struct device_node *dp, char *model_name)
{
struct linux_prom64_registers pr_regs[3];
struct linux_prom64_registers *pr_regs;
struct pci_controller_info *p;
struct pci_iommu *iommu;
struct property *prop;
u32 upa_portid;
int is_pbm_a, err;
int is_pbm_a;

upa_portid = prom_getintdefault(node, "upa-portid", 0xff);
upa_portid = 0xff;
prop = of_find_property(dp, "upa-portid", NULL);
if (prop)
upa_portid = *(u32 *) prop->value;

for(p = pci_controller_root; p; p = p->next) {
if (p->pbm_A.portid == upa_portid) {
is_pbm_a = (p->pbm_A.prom_node == 0);
psycho_pbm_init(p, node, is_pbm_a);
is_pbm_a = (p->pbm_A.prom_node == NULL);
psycho_pbm_init(p, dp, is_pbm_a);
return;
}
}
Expand Down Expand Up @@ -1412,23 +1413,14 @@ void psycho_init(int node, char *model_name)
p->resource_adjust = psycho_resource_adjust;
p->pci_ops = &psycho_ops;

err = prom_getproperty(node, "reg",
(char *)&pr_regs[0],
sizeof(pr_regs));
if (err == 0 || err == -1) {
prom_printf("PSYCHO: Fatal error, no reg property.\n");
prom_halt();
}
prop = of_find_property(dp, "reg", NULL);
pr_regs = prop->value;

p->pbm_A.controller_regs = pr_regs[2].phys_addr;
p->pbm_B.controller_regs = pr_regs[2].phys_addr;
printk("PCI: Found PSYCHO, control regs at %016lx\n",
p->pbm_A.controller_regs);

p->pbm_A.config_space = p->pbm_B.config_space =
(pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE);
printk("PSYCHO: Shared PCI config space at %016lx\n",
p->pbm_A.config_space);

/*
* Psycho's PCI MEM space is mapped to a 2GB aligned area, so
Expand All @@ -1441,5 +1433,5 @@ void psycho_init(int node, char *model_name)
psycho_iommu_init(p);

is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000);
psycho_pbm_init(p, node, is_pbm_a);
psycho_pbm_init(p, dp, is_pbm_a);
}
Loading

0 comments on commit c4bedd4

Please sign in to comment.