Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 42226
b: refs/heads/master
c: 4c9d280
h: refs/heads/master
v: v3
  • Loading branch information
Benjamin Herrenschmidt authored and Paul Mackerras committed Dec 4, 2006
1 parent 3e93126 commit e212694
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 11 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: 803d4573e60bc890d7fbc040ad1c18c2dc7f8279
refs/heads/master: 4c9d2800be5dfabf26acdeb401cbabe9edc1dcf2
6 changes: 6 additions & 0 deletions trunk/arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ config PPC_DCR
depends on PPC_DCR_NATIVE || PPC_DCR_MMIO
default y

config PPC_OF_PLATFORM_PCI
bool
depends on PPC64 # not supported on 32 bits yet
default n

config BOOKE
bool
depends on E200 || E500
Expand Down Expand Up @@ -469,6 +474,7 @@ config PPC_CELL_NATIVE
bool
select PPC_CELL
select PPC_DCR_MMIO
select PPC_OF_PLATFORM_PCI
select MPIC
default n

Expand Down
103 changes: 103 additions & 0 deletions trunk/arch/powerpc/kernel/of_platform.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
* <benh@kernel.crashing.org>
* and Arnd Bergmann, IBM Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
Expand All @@ -17,12 +18,15 @@
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
#include <linux/pci.h>

#include <asm/errno.h>
#include <asm/dcr.h>
#include <asm/of_device.h>
#include <asm/of_platform.h>
#include <asm/topology.h>
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>

/*
* The list of OF IDs below is used for matching bus types in the
Expand Down Expand Up @@ -377,3 +381,102 @@ struct of_device *of_find_device_by_phandle(phandle ph)
return NULL;
}
EXPORT_SYMBOL(of_find_device_by_phandle);


#ifdef CONFIG_PPC_OF_PLATFORM_PCI

/* The probing of PCI controllers from of_platform is currently
* 64 bits only, mostly due to gratuitous differences between
* the 32 and 64 bits PCI code on PowerPC and the 32 bits one
* lacking some bits needed here.
*/

static int __devinit of_pci_phb_probe(struct of_device *dev,
const struct of_device_id *match)
{
struct pci_controller *phb;

/* Check if we can do that ... */
if (ppc_md.pci_setup_phb == NULL)
return -ENODEV;

printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name);

/* Alloc and setup PHB data structure */
phb = pcibios_alloc_controller(dev->node);
if (!phb)
return -ENODEV;

/* Setup parent in sysfs */
phb->parent = &dev->dev;

/* Setup the PHB using arch provided callback */
if (ppc_md.pci_setup_phb(phb)) {
pcibios_free_controller(phb);
return -ENODEV;
}

/* Process "ranges" property */
pci_process_bridge_OF_ranges(phb, dev->node, 0);

/* Setup IO space.
* This will not work properly for ISA IOs, something needs to be done
* about it if we ever generalize that way of probing PCI brigdes
*/
pci_setup_phb_io_dynamic(phb, 0);

/* Init pci_dn data structures */
pci_devs_phb_init_dynamic(phb);

/* Register devices with EEH */
#ifdef CONFIG_EEH
if (dev->node->child)
eeh_add_device_tree_early(dev->node);
#endif /* CONFIG_EEH */

/* Scan the bus */
scan_phb(phb);

/* Claim resources. This might need some rework as well depending
* wether we are doing probe-only or not, like assigning unassigned
* resources etc...
*/
pcibios_claim_one_bus(phb->bus);

/* Finish EEH setup */
#ifdef CONFIG_EEH
eeh_add_device_tree_late(phb->bus);
#endif

/* Add probed PCI devices to the device model */
pci_bus_add_devices(phb->bus);

return 0;
}

static struct of_device_id of_pci_phb_ids[] = {
{ .type = "pci", },
{ .type = "pcix", },
{ .type = "pcie", },
{ .type = "pciex", },
{ .type = "ht", },
{}
};

static struct of_platform_driver of_pci_phb_driver = {
.name = "of-pci",
.match_table = of_pci_phb_ids,
.probe = of_pci_phb_probe,
.driver = {
.multithread_probe = 1,
},
};

static __init int of_pci_phb_init(void)
{
return of_register_platform_driver(&of_pci_phb_driver);
}

device_initcall(of_pci_phb_init);

#endif /* CONFIG_PPC_OF_PLATFORM_PCI */
9 changes: 9 additions & 0 deletions trunk/arch/powerpc/kernel/pci_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)

void pcibios_free_controller(struct pci_controller *phb)
{
spin_lock(&hose_spinlock);
list_del(&phb->list_node);
spin_unlock(&hose_spinlock);

if (phb->is_dynamic)
kfree(phb);
}
Expand Down Expand Up @@ -1242,6 +1246,11 @@ static void __devinit do_bus_setup(struct pci_bus *bus)
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_dev *dev = bus->self;
struct device_node *np;

np = pci_bus_to_OF_node(bus);

DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : "<???>");

if (dev && pci_probe_only &&
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
Expand Down
7 changes: 4 additions & 3 deletions trunk/arch/powerpc/kernel/rtas_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,10 @@ static int phb_set_bus_ranges(struct device_node *dev,
return 0;
}

int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb)
int __devinit rtas_setup_phb(struct pci_controller *phb)
{
struct device_node *dev = phb->arch_data;

if (is_python(dev))
python_countermeasures(dev);

Expand Down Expand Up @@ -290,7 +292,7 @@ unsigned long __init find_and_init_phbs(void)
phb = pcibios_alloc_controller(node);
if (!phb)
continue;
setup_phb(node, phb);
rtas_setup_phb(phb);
pci_process_bridge_OF_ranges(phb, node, 0);
pci_setup_phb_io(phb, index == 0);
index++;
Expand Down Expand Up @@ -362,7 +364,6 @@ int pcibios_remove_root_bus(struct pci_controller *phb)
}
}

list_del(&phb->list_node);
pcibios_free_controller(phb);

return 0;
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/platforms/cell/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ define_machine(cell) {
.check_legacy_ioport = cell_check_legacy_ioport,
.progress = cell_progress,
.init_IRQ = cell_init_irq,
.pci_setup_phb = rtas_setup_phb,
#ifdef CONFIG_KEXEC
.machine_kexec = default_machine_kexec,
.machine_kexec_prepare = default_machine_kexec_prepare,
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/platforms/pseries/pci_dlpar.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
phb = pcibios_alloc_controller(dn);
if (!phb)
return NULL;
setup_phb(dn, phb);
rtas_setup_phb(phb);
pci_process_bridge_OF_ranges(phb, dn, 0);

pci_setup_phb_io_dynamic(phb, primary);
Expand Down
4 changes: 4 additions & 0 deletions trunk/include/asm-powerpc/machdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct device_node;
struct iommu_table;
struct rtc_time;
struct file;
struct pci_controller;
#ifdef CONFIG_KEXEC
struct kimage;
#endif
Expand Down Expand Up @@ -107,6 +108,9 @@ struct machdep_calls {
int (*pci_probe_mode)(struct pci_bus *);
void (*pci_irq_fixup)(struct pci_dev *dev);

/* To setup PHBs when using automatic OF platform driver for PCI */
int (*pci_setup_phb)(struct pci_controller *host);

void (*restart)(char *cmd);
void (*power_off)(void);
void (*halt)(void);
Expand Down
12 changes: 6 additions & 6 deletions trunk/include/asm-powerpc/ppc-pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ typedef void *(*traverse_func)(struct device_node *me, void *data);
void *traverse_pci_devices(struct device_node *start, traverse_func pre,
void *data);

void pci_devs_phb_init(void);
void pci_devs_phb_init_dynamic(struct pci_controller *phb);
int setup_phb(struct device_node *dev, struct pci_controller *phb);
void __devinit scan_phb(struct pci_controller *hose);
extern void pci_devs_phb_init(void);
extern void pci_devs_phb_init_dynamic(struct pci_controller *phb);
extern void scan_phb(struct pci_controller *hose);

/* From rtas_pci.h */
void init_pci_config_tokens (void);
unsigned long get_phb_buid (struct device_node *);
extern void init_pci_config_tokens (void);
extern unsigned long get_phb_buid (struct device_node *);
extern int rtas_setup_phb(struct pci_controller *phb);

/* From pSeries_pci.h */
extern void pSeries_final_fixup(void);
Expand Down

0 comments on commit e212694

Please sign in to comment.