#define DBG(x...)
#endif
-extern int pci_probe_only;
-extern int pci_read_irq_line(struct pci_dev *pci_dev);
-
/* XXX Could be per-controller, but I don't think we risk anything by
* assuming we won't have both UniNorth and Bandit */
static int has_uninorth;
static struct pci_controller *u3_agp;
-u8 pci_cache_line_size;
-struct pci_dev *k2_skiplist[2];
+struct device_node *k2_skiplist[2];
static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
{
int offset, int len, u32 *val)
{
struct pci_controller *hose;
- struct device_node *busdn;
unsigned long addr;
- if (bus->self)
- busdn = pci_device_to_OF_node(bus->self);
- else
- busdn = bus->sysdata; /* must be a phb */
- if (busdn == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- hose = busdn->phb;
+ hose = pci_bus_to_host(bus);
if (hose == NULL)
return PCIBIOS_DEVICE_NOT_FOUND;
int offset, int len, u32 val)
{
struct pci_controller *hose;
- struct device_node *busdn;
unsigned long addr;
- if (bus->self)
- busdn = pci_device_to_OF_node(bus->self);
- else
- busdn = bus->sysdata; /* must be a phb */
- if (busdn == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- hose = busdn->phb;
+ hose = pci_bus_to_host(bus);
if (hose == NULL)
return PCIBIOS_DEVICE_NOT_FOUND;
* implement self-view of the HT host yet
*/
-static int skip_k2_device(struct pci_bus *bus, unsigned int devfn)
+/*
+ * This function deals with some "special cases" devices.
+ *
+ * 0 -> No special case
+ * 1 -> Skip the device but act as if the access was successfull
+ * (return 0xff's on reads, eventually, cache config space
+ * accesses in a later version)
+ * -1 -> Hide the device (unsuccessful acess)
+ */
+static int u3_ht_skip_device(struct pci_controller *hose,
+ struct pci_bus *bus, unsigned int devfn)
{
+ struct device_node *busdn, *dn;
int i;
+ /* We only allow config cycles to devices that are in OF device-tree
+ * as we are apparently having some weird things going on with some
+ * revs of K2 on recent G5s
+ */
+ if (bus->self)
+ busdn = pci_device_to_OF_node(bus->self);
+ else
+ busdn = hose->arch_data;
+ for (dn = busdn->child; dn; dn = dn->sibling)
+ if (dn->devfn == devfn)
+ break;
+ if (dn == NULL)
+ return -1;
+
+ /*
+ * When a device in K2 is powered down, we die on config
+ * cycle accesses. Fix that here.
+ */
for (i=0; i<2; i++)
- if (k2_skiplist[i] && k2_skiplist[i]->bus == bus &&
- k2_skiplist[i]->devfn == devfn)
+ if (k2_skiplist[i] == dn)
return 1;
+
return 0;
}
{
if (bus == hose->first_busno) {
/* For now, we don't self probe U3 HT bridge */
- if (PCI_FUNC(devfn) != 0 || PCI_SLOT(devfn) > 7 ||
- PCI_SLOT(devfn) < 1)
+ if (PCI_SLOT(devfn) == 0)
return 0;
return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
} else
int offset, int len, u32 *val)
{
struct pci_controller *hose;
- struct device_node *busdn;
unsigned long addr;
- if (bus->self)
- busdn = pci_device_to_OF_node(bus->self);
- else
- busdn = bus->sysdata; /* must be a phb */
- if (busdn == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- hose = busdn->phb;
+
+ hose = pci_bus_to_host(bus);
if (hose == NULL)
return PCIBIOS_DEVICE_NOT_FOUND;
addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
if (!addr)
return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * When a device in K2 is powered down, we die on config
- * cycle accesses. Fix that here. We may ultimately want
- * to cache the config space for those instead of returning
- * 0xffffffff's to make life easier to HW detection tools
- */
- if (skip_k2_device(bus, devfn)) {
+
+ switch (u3_ht_skip_device(hose, bus, devfn)) {
+ case 0:
+ break;
+ case 1:
switch (len) {
case 1:
*val = 0xff; break;
*val = 0xfffffffful; break;
}
return PCIBIOS_SUCCESSFUL;
+ default:
+ return PCIBIOS_DEVICE_NOT_FOUND;
}
/*
int offset, int len, u32 val)
{
struct pci_controller *hose;
- struct device_node *busdn;
unsigned long addr;
- if (bus->self)
- busdn = pci_device_to_OF_node(bus->self);
- else
- busdn = bus->sysdata; /* must be a phb */
- if (busdn == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- hose = busdn->phb;
+ hose = pci_bus_to_host(bus);
if (hose == NULL)
return PCIBIOS_DEVICE_NOT_FOUND;
addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
if (!addr)
return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * When a device in K2 is powered down, we die on config
- * cycle accesses. Fix that here.
- */
- if (skip_k2_device(bus, devfn))
+
+ switch (u3_ht_skip_device(hose, bus, devfn)) {
+ case 0:
+ break;
+ case 1:
return PCIBIOS_SUCCESSFUL;
+ default:
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
/*
* Note: the caller has already checked that offset is
* properties or figuring out the U3 address space decoding logic and
* then read it's configuration register (if any).
*/
- hose->io_base_phys = 0xf4000000 + 0x00400000;
+ hose->io_base_phys = 0xf4000000;
hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);
isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt;
hose->io_resource.name = np->full_name;
dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
if (!dt_ranges)
return;
- /* lc_ranges = (unsigned int *) alloc_bootmem(rlen);*/
+ /* lc_ranges = alloc_bootmem(rlen);*/
lc_ranges = static_lc_ranges;
if (!lc_ranges)
return; /* what can we do here ? */
dev->full_name);
}
- hose = pci_alloc_pci_controller(phb_type_apple);
- if (!hose)
- return -ENOMEM;
+ hose = alloc_bootmem(sizeof(struct pci_controller));
+ if (hose == NULL)
+ return -ENOMEM;
+ pci_setup_pci_controller(hose);
+
hose->arch_data = dev;
hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;
- of_prop = (struct property *)alloc_bootmem(sizeof(struct property) +
- sizeof(hose->global_number));
+ of_prop = alloc_bootmem(sizeof(struct property) +
+ sizeof(hose->global_number));
if (of_prop) {
memset(of_prop, 0, sizeof(struct property));
of_prop->name = "linux,pci-domain";
{
struct pci_dev *dev = NULL;
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+ for_each_pci_dev(dev)
pci_read_irq_line(dev);
-
- pci_fix_bus_sysdata();
-
-#ifdef CONFIG_PMAC_DART
- iommu_setup_pmac();
-#endif /* CONFIG_PMAC_DART */
-
}
static void __init pmac_fixup_phb_resources(void)
{
- struct pci_controller *hose;
+ struct pci_controller *hose, *tmp;
- for (hose = hose_head; hose; hose = hose->next) {
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
hose->io_resource.start += offset;
hose->io_resource.end += offset;
pmac_check_ht_link();
- /* Tell pci.c to use the common resource allocation mecanism */
- pci_probe_only = 0;
+ /* Tell pci.c to not use the common resource allocation mecanism */
+ pci_probe_only = 1;
- /* HT don't do more than 64 bytes transfers. FIXME: Deal with
- * the exception of U3/AGP (hook into pci_set_mwi)
- */
- pci_cache_line_size = 16; /* 64 bytes */
+ /* Allow all IO */
+ io_page_mask = -1;
}
/*
* Disable second function on K2-SATA, it's broken
* and disable IO BARs on first one
*/
-void fixup_k2_sata(struct pci_dev* dev)
+static void fixup_k2_sata(struct pci_dev* dev)
{
int i;
u16 cmd;
}
}
}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);