Skip to content

Commit

Permalink
[POWERPC] pci32: Add flags modifying the PCI code behaviour
Browse files Browse the repository at this point in the history
This adds to the 32 bits PCI code some flags, replacing the old
pci_assign_all_busses global, that allow us to control various
aspects of the PCI probing, such as whether to re-assign all
resources or not, or to not try to assign anything at all.

This also adds the flag x86 already has to avoid ISA alignment
on bridges that don't have ISA forwarding enabled (no legacy
devices on the top level bus) and sets it for PowerMacs.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Benjamin Herrenschmidt authored and Paul Mackerras committed Dec 20, 2007
1 parent b9baa20 commit fc3fb71
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 22 deletions.
42 changes: 34 additions & 8 deletions arch/powerpc/kernel/pci_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ unsigned long isa_io_base = 0;
unsigned long pci_dram_offset = 0;
int pcibios_assign_bus_offset = 1;

/* Default PCI flags is 0 */
unsigned int ppc_pci_flags;

void pcibios_make_OF_bus_map(void);

static void pcibios_fixup_resources(struct pci_dev* dev);
Expand All @@ -48,7 +51,7 @@ static u8* pci_to_OF_bus_map;
/* By default, we don't re-assign bus numbers. We do this only on
* some pmacs
*/
int pci_assign_all_buses;
static int pci_assign_all_buses;

LIST_HEAD(hose_list);

Expand Down Expand Up @@ -174,6 +177,14 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
}
EXPORT_SYMBOL(pcibios_bus_to_resource);

static int skip_isa_ioresource_align(struct pci_dev *dev)
{
if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
!(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
return 1;
return 0;
}

/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
Expand All @@ -195,6 +206,8 @@ void pcibios_align_resource(void *data, struct resource *res,
if (res->flags & IORESOURCE_IO) {
resource_size_t start = res->start;

if (skip_isa_ioresource_align(dev))
return;
if (start & 0x300) {
start = (start + 0x3ff) & ~0x3ff;
res->start = start;
Expand Down Expand Up @@ -251,8 +264,13 @@ pcibios_allocate_bus_resources(struct list_head *bus_list)
continue;
if (bus->parent == NULL)
pr = (res->flags & IORESOURCE_IO)?
&ioport_resource: &iomem_resource;
&ioport_resource : &iomem_resource;
else {
/* Don't bother with non-root busses when
* re-assigning all resources.
*/
if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
continue;
pr = pci_find_parent_resource(bus->self, res);
if (pr == res) {
/* this happens when the generic PCI
Expand Down Expand Up @@ -720,6 +738,9 @@ pcibios_init(void)

printk(KERN_INFO "PCI: Probing PCI hardware\n");

if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
pci_assign_all_buses = 1;

/* Scan all of the recorded PCI controllers. */
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
if (pci_assign_all_buses)
Expand All @@ -746,13 +767,18 @@ pcibios_init(void)
if (ppc_md.pcibios_fixup)
ppc_md.pcibios_fixup();

/* Allocate and assign resources */
/* Allocate and assign resources. If we re-assign everything, then
* we skip the allocate phase
*/
pcibios_allocate_bus_resources(&pci_root_buses);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);

DBG("PCI: Assigning unassigned resouces...\n");
pci_assign_unassigned_resources();
if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
}
if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
DBG("PCI: Assigning unassigned resouces...\n");
pci_assign_unassigned_resources();
}

/* Call machine dependent post-init code */
if (ppc_md.pcibios_after_init)
Expand Down
1 change: 0 additions & 1 deletion arch/powerpc/kernel/pci_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
#endif

unsigned long pci_probe_only = 1;
int pci_assign_all_buses = 0;

static void fixup_resource(struct resource *res, struct pci_dev *dev);
static void do_bus_setup(struct pci_bus *bus);
Expand Down
6 changes: 4 additions & 2 deletions arch/powerpc/kernel/rtas_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,12 @@ void __init find_and_init_phbs(void)
if (prop)
pci_probe_only = *prop;

#ifdef CONFIG_PPC32 /* Will be made generic soon */
prop = of_get_property(of_chosen,
"linux,pci-assign-all-buses", NULL);
if (prop)
pci_assign_all_buses = *prop;
if (prop && *prop)
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
#endif /* CONFIG_PPC32 */
}
}

Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/52xx/mpc52xx_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ mpc52xx_add_bridge(struct device_node *node)

pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);

pci_assign_all_buses = 1;
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;

if (of_address_to_resource(node, 0, &rsrc) != 0) {
printk(KERN_ERR "Can't get %s resources\n", node->full_name);
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/82xx/pq2.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static void __init pq2_pci_add_bridge(struct device_node *np)
if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
goto err;

pci_assign_all_buses = 1;
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;

hose = pcibios_alloc_controller(np);
if (!hose)
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/83xx/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
" bus 0\n", dev->full_name);
}

pci_assign_all_buses = 1;
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
hose = pcibios_alloc_controller(dev);
if (!hose)
return -ENOMEM;
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/chrp/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
printk ("RTAS supporting Pegasos OF not found, please upgrade"
" your firmware\n");
}
pci_assign_all_buses = 1;
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
/* keep the reference to the root node */
}

Expand Down
7 changes: 5 additions & 2 deletions arch/powerpc/platforms/powermac/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ static void __init setup_bandit(struct pci_controller *hose,
static int __init setup_uninorth(struct pci_controller *hose,
struct resource *addr)
{
pci_assign_all_buses = 1;
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
has_uninorth = 1;
hose->ops = &macrisc_pci_ops;
hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
Expand Down Expand Up @@ -994,6 +994,9 @@ void __init pmac_pci_init(void)
struct device_node *np, *root;
struct device_node *ht = NULL;

#ifdef CONFIG_PPC32
ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN;
#endif
root = of_find_node_by_path("/");
if (root == NULL) {
printk(KERN_CRIT "pmac_pci_init: can't find root "
Expand Down Expand Up @@ -1051,7 +1054,7 @@ void __init pmac_pci_init(void)
* some offset between bus number and domains for now when we
* assign all busses should help for now
*/
if (pci_assign_all_buses)
if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
pcibios_assign_bus_offset = 0x10;
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/sysdev/fsl_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
printk(KERN_WARNING "Can't get bus-range for %s, assume"
" bus 0\n", dev->full_name);

pci_assign_all_buses = 1;
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
hose = pcibios_alloc_controller(dev);
if (!hose)
return -ENOMEM;
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/sysdev/grackle.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_controller *hose)
{
setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
if (machine_is_compatible("PowerMac1,1"))
pci_assign_all_buses = 1;
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
if (machine_is_compatible("AAPL,PowerBook1998"))
grackle_set_loop_snoop(hose, 1);
#if 0 /* Disabled for now, HW problems ??? */
Expand Down
20 changes: 20 additions & 0 deletions include/asm-powerpc/pci-bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@

struct device_node;

extern unsigned int ppc_pci_flags;
enum {
/* Force re-assigning all resources (ignore firmware
* setup completely)
*/
PPC_PCI_REASSIGN_ALL_RSRC = 0x00000001,

/* Re-assign all bus numbers */
PPC_PCI_REASSIGN_ALL_BUS = 0x00000002,

/* Do not try to assign, just use existing setup */
PPC_PCI_PROBE_ONLY = 0x00000004,

/* Don't bother with ISA alignment unless the bridge has
* ISA forwarding enabled
*/
PPC_PCI_CAN_SKIP_ISA_ALIGN = 0x00000008,
};


/*
* Structure of a PCI controller (host bridge)
*/
Expand Down
9 changes: 6 additions & 3 deletions include/asm-powerpc/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ struct pci_dev;
* Set this to 1 if you want the kernel to re-assign all PCI
* bus numbers
*/
extern int pci_assign_all_buses;
#define pcibios_assign_all_busses() (pci_assign_all_buses)

#ifdef CONFIG_PPC64
#define pcibios_assign_all_busses() 0
#else
#define pcibios_assign_all_busses() (ppc_pci_flags & \
PPC_PCI_REASSIGN_ALL_BUS)
#endif
#define pcibios_scan_all_fns(a, b) 0

static inline void pcibios_set_master(struct pci_dev *dev)
Expand Down

0 comments on commit fc3fb71

Please sign in to comment.