Commit 601917b5 authored by Anton Blanchard's avatar Anton Blanchard

ppc64: Rework pci probe to be like alpha.

parent 748a82b2
......@@ -71,9 +71,6 @@ extern void openpic_init_IRQ(void);
extern void init_ras_IRQ(void);
extern void find_and_init_phbs(void);
extern void pSeries_pcibios_fixup(void);
extern void pSeries_pcibios_fixup_bus(struct pci_bus *bus);
extern void iSeries_pcibios_fixup(void);
extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
extern int pSeries_set_rtc_time(struct rtc_time *rtc_time);
......@@ -201,7 +198,6 @@ void __init pSeries_init_early(void)
hpte_init_pSeries();
tce_init_pSeries();
pSeries_pcibios_init_early();
#ifdef CONFIG_SMP
smp_init_pSeries();
......@@ -244,15 +240,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
}
ppc_md.init_ras_IRQ = init_ras_IRQ;
#ifndef CONFIG_PPC_ISERIES
ppc_md.pcibios_fixup = pSeries_pcibios_fixup;
ppc_md.pcibios_fixup_bus = pSeries_pcibios_fixup_bus;
#else
ppc_md.pcibios_fixup = NULL;
// ppc_md.pcibios_fixup = iSeries_pcibios_fixup;
#endif
ppc_md.init = chrp_init2;
ppc_md.restart = rtas_restart;
......
......@@ -84,8 +84,6 @@ struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev);
struct iSeries_Device_Node* get_Device_Node(struct pci_dev* PciDev);
unsigned long find_and_init_phbs(void);
void fixup_resources(struct pci_dev *dev);
void iSeries_pcibios_fixup(void);
struct pci_controller* alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words) ;
void iSeries_Scan_PHBs_Slots(struct pci_controller* Phb);
......@@ -275,7 +273,7 @@ unsigned long __init find_and_init_phbs(void)
return 0;
}
/***********************************************************************
* ppc64_pcibios_init
* iSeries_pcibios_init
*
* Chance to initialize and structures or variable before PCI Bus walk.
*
......@@ -302,9 +300,9 @@ void iSeries_pcibios_init(void)
PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_init Exit.\n");
}
/***********************************************************************
* iSeries_pcibios_fixup(void)
* pcibios_final_fixup(void)
***********************************************************************/
void __init iSeries_pcibios_fixup(void)
void __init pcibios_final_fixup(void)
{
struct pci_dev* PciDev;
struct iSeries_Device_Node* DeviceNode;
......@@ -328,8 +326,6 @@ void __init iSeries_pcibios_fixup(void)
iSeries_allocateDeviceBars(PciDev);
PPCDBGCALL(PPCDBG_BUSWALK,dumpPci_Dev(PciDev) );
iSeries_Device_Information(PciDev,Buffer, sizeof(Buffer) );
printk("%d. %s\n",DeviceCount,Buffer);
......@@ -345,11 +341,7 @@ void __init iSeries_pcibios_fixup(void)
mf_displaySrc(0xC9000200);
}
/***********************************************************************
* iSeries_pcibios_fixup_bus(int Bus)
*
***********************************************************************/
void iSeries_pcibios_fixup_bus(struct pci_bus* PciBus)
void pcibios_fixup_bus(struct pci_bus* PciBus)
{
PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",PciBus->number);
......@@ -357,12 +349,12 @@ void iSeries_pcibios_fixup_bus(struct pci_bus* PciBus)
/***********************************************************************
* fixup_resources(struct pci_dev *dev)
* pcibios_fixup_resources(struct pci_dev *dev)
*
***********************************************************************/
void fixup_resources(struct pci_dev *PciDev)
void pcibios_fixup_resources(struct pci_dev *PciDev)
{
PPCDBG(PPCDBG_BUSWALK,"fixup_resources PciDev %p\n",PciDev);
PPCDBG(PPCDBG_BUSWALK,"pcibios_fixup_resources PciDev %p\n",PciDev);
}
......@@ -910,18 +902,3 @@ void iSeries_Write_Long(u32 Data, void* IoAddress)
} while (CheckReturnCode("WWL",DevNode, Return.rc) != 0);
if(Pci_Trace_Flag == 1) PCIFR("WWL: IoAddress 0x%p = 0x%08X",IoAddress, Data);
}
/*
* This is called very early before the page table is setup.
* There are warnings here because of type mismatches.. Okay for now. AHT
*/
void
iSeries_pcibios_init_early(void)
{
//ppc_md.pcibios_read_config_byte = iSeries_Node_read_config_byte;
//ppc_md.pcibios_read_config_word = iSeries_Node_read_config_word;
//ppc_md.pcibios_read_config_dword = iSeries_Node_read_config_dword;
//ppc_md.pcibios_write_config_byte = iSeries_Node_write_config_byte;
//ppc_md.pcibios_write_config_word = iSeries_Node_write_config_word;
//ppc_md.pcibios_write_config_dword = iSeries_Node_write_config_dword;
}
......@@ -62,8 +62,6 @@ void build_valid_hpte( unsigned long vsid, unsigned long ea, unsigned long pa,
pte_t * ptep, unsigned hpteflags, unsigned bolted );
extern void ppcdbg_initialize(void);
extern void iSeries_pcibios_init(void);
extern void iSeries_pcibios_fixup(void);
extern void iSeries_pcibios_fixup_bus(int);
static void iSeries_setup_dprofile(void);
/* Global Variables */
......@@ -317,9 +315,6 @@ iSeries_init_early(void)
ppc_md.get_irq = iSeries_get_irq;
ppc_md.init = NULL;
ppc_md.pcibios_fixup = iSeries_pcibios_fixup;
ppc_md.pcibios_fixup_bus = iSeries_pcibios_fixup_bus;
ppc_md.restart = iSeries_restart;
ppc_md.power_off = iSeries_power_off;
ppc_md.halt = iSeries_halt;
......
......@@ -320,7 +320,6 @@ void pSeriesLP_init_early(void)
#ifdef CONFIG_SMP
smp_init_pSeries();
#endif
pSeries_pcibios_init_early();
/* The keyboard is not useful in the LPAR environment.
* Leave all the interfaces NULL.
......
......@@ -2,6 +2,7 @@
* pSeries_pci.c
*
* Copyright (C) 2001 Dave Engebretsen, IBM Corporation
* Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
*
* pSeries specific routines for PCI.
*
......@@ -51,6 +52,8 @@ static int ibm_write_pci_config;
static int s7a_workaround;
extern unsigned long pci_probe_only;
static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
{
unsigned long returnval = ~0L;
......@@ -371,9 +374,6 @@ struct pci_controller *alloc_phb(struct device_node *dev,
phb->last_busno += (phb->global_number << 8);
}
/* Dump PHB information for Debug */
PPCDBGCALL(PPCDBG_PHBINIT, dumpPci_Controller(phb));
return phb;
}
......@@ -423,129 +423,96 @@ unsigned long __init find_and_init_phbs(void)
return 0;
}
void
fixup_resources(struct pci_dev *dev)
void pcibios_name_device(struct pci_dev *dev)
{
int i;
struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
struct device_node *dn;
/* Add IBM loc code (slot) as a prefix to the device names for service */
/*
* Add IBM loc code (slot) as a prefix to the device names for service
*/
dn = pci_device_to_OF_node(dev);
if (dn) {
char *loc_code = get_property(dn, "ibm,loc-code", 0);
if (loc_code) {
int loc_len = strlen(loc_code);
if (loc_len < sizeof(dev->dev.name)) {
memmove(dev->dev.name+loc_len+1, dev->dev.name, sizeof(dev->dev.name)-loc_len-1);
memmove(dev->dev.name+loc_len+1, dev->dev.name,
sizeof(dev->dev.name)-loc_len-1);
memcpy(dev->dev.name, loc_code, loc_len);
dev->dev.name[loc_len] = ' ';
dev->dev.name[sizeof(dev->dev.name)-1] = '\0';
}
}
}
}
PPCDBG(PPCDBG_PHBINIT, "fixup_resources:\n");
PPCDBG(PPCDBG_PHBINIT, "\tphb = 0x%016LX\n", phb);
PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_io_offset = 0x%016LX\n", phb->pci_io_offset);
PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_mem_offset = 0x%016LX\n", phb->pci_mem_offset);
PPCDBG(PPCDBG_PHBINIT, "\tdev->dev.name = %s\n", dev->dev.name);
PPCDBG(PPCDBG_PHBINIT, "\tdev->vendor:device = 0x%04X : 0x%04X\n", dev->vendor, dev->device);
if (phb == NULL)
return;
for (i = 0; i < DEVICE_COUNT_RESOURCE; ++i) {
PPCDBG(PPCDBG_PHBINIT, "\tdevice %x.%x[%d] (flags %x) [%lx..%lx]\n",
dev->bus->number, dev->devfn, i,
dev->resource[i].flags,
dev->resource[i].start,
dev->resource[i].end);
if ((dev->resource[i].start == 0) && (dev->resource[i].end == 0)) {
continue;
}
if (dev->resource[i].start > dev->resource[i].end) {
/* Bogus resource. Just clear it out. */
dev->resource[i].start = dev->resource[i].end = 0;
continue;
}
void __init pcibios_fixup_device_resources(struct pci_dev *dev,
struct pci_bus *bus)
{
/* Update device resources. */
struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
if (dev->resource[i].flags & IORESOURCE_IO) {
unsigned long offset = (unsigned long)phb->io_base_virt - pci_io_base;
unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
dev->resource[i].start += offset;
dev->resource[i].end += offset;
PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx .. %lx]\n",
dev->resource[i].start, dev->resource[i].end);
} else if (dev->resource[i].flags & IORESOURCE_MEM) {
if (dev->resource[i].start == 0) {
/* Bogus. Probably an unused bridge. */
dev->resource[i].end = 0;
} else {
dev->resource[i].start += phb->pci_mem_offset;
dev->resource[i].end += phb->pci_mem_offset;
}
PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx..%lx]\n",
dev->resource[i].start, dev->resource[i].end);
} else {
continue;
else if (dev->resource[i].flags & IORESOURCE_MEM) {
dev->resource[i].start += hose->pci_mem_offset;
dev->resource[i].end += hose->pci_mem_offset;
}
/* zap the 2nd function of the winbond chip */
if (dev->resource[i].flags & IORESOURCE_IO
&& dev->bus->number == 0 && dev->devfn == 0x81)
dev->resource[i].flags &= ~IORESOURCE_IO;
}
}
void __init pSeries_pcibios_fixup_bus(struct pci_bus *bus)
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_controller *phb = PCI_GET_PHB_PTR(bus);
struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
struct list_head *ln;
/* XXX or bus->parent? */
struct pci_dev *dev = bus->self;
struct resource *res;
int i;
if (bus->parent == NULL) {
/* This is a host bridge - fill in its resources */
phb->bus = bus;
bus->resource[0] = res = &phb->io_resource;
if (!dev) {
/* Root bus. */
hose->bus = bus;
bus->resource[0] = res = &hose->io_resource;
if (!res->flags)
BUG(); /* No I/O resource for this PHB? */
if (request_resource(&ioport_resource, res))
printk(KERN_ERR "Failed to request IO"
"on hose %d\n", 0 /* FIXME */);
for (i = 0; i < 3; ++i) {
res = &phb->mem_resources[i];
if (!res->flags) {
if (i == 0)
res = &hose->mem_resources[i];
if (!res->flags && i == 0)
BUG(); /* No memory resource for this PHB? */
}
bus->resource[i+1] = res;
if (res->flags && request_resource(&iomem_resource, res))
printk(KERN_ERR "Failed to request MEM"
"on hose %d\n", 0 /* FIXME */);
}
} else {
} else if (pci_probe_only &&
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
/* This is a subordinate bridge */
pci_read_bridge_bases(bus);
for (i = 0; i < 4; ++i) {
if ((res = bus->resource[i]) == NULL)
continue;
if (!res->flags)
continue;
if (res == pci_find_parent_resource(bus->self, res)) {
/* Transparent resource -- don't try to "fix" it. */
continue;
}
if (res->flags & IORESOURCE_IO) {
unsigned long offset = (unsigned long)phb->io_base_virt - pci_io_base;
res->start += offset;
res->end += offset;
} else if (phb->pci_mem_offset
&& (res->flags & IORESOURCE_MEM)) {
if (res->start < phb->pci_mem_offset) {
res->start += phb->pci_mem_offset;
res->end += phb->pci_mem_offset;
}
}
pci_read_bridge_bases(bus);
pcibios_fixup_device_resources(dev, bus);
}
/* XXX Need to check why Alpha doesnt do this - Anton */
if (!pci_probe_only)
return;
for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
struct pci_dev *dev = pci_dev_b(ln);
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
pcibios_fixup_device_resources(dev, bus);
}
}
......@@ -562,19 +529,20 @@ static void check_s7a(void)
}
}
void __init
pSeries_pcibios_fixup(void)
extern void chrp_request_regions(void);
void __init pcibios_final_fixup(void)
{
struct pci_dev *dev;
PPCDBG(PPCDBG_PHBINIT, "pSeries_pcibios_fixup: start\n");
check_s7a();
pci_for_each_dev(dev) {
pci_for_each_dev(dev)
pci_read_irq_line(dev);
PPCDBGCALL(PPCDBG_PHBINIT, dumpPci_Dev(dev) );
}
chrp_request_regions();
pci_fix_bus_sysdata();
create_tce_tables();
}
/***********************************************************************
......@@ -596,13 +564,3 @@ pci_find_hose_for_OF_device(struct device_node *node)
}
return NULL;
}
/*
* This is called very early before the page table is setup.
*/
void
pSeries_pcibios_init_early(void)
{
ppc_md.pcibios_read_config = rtas_read_config;
ppc_md.pcibios_write_config = rtas_write_config;
}
This diff is collapsed.
......@@ -19,18 +19,14 @@ extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* no
extern struct pci_controller* hose_head;
extern struct pci_controller** hose_tail;
/* PHB's are also in a table. */
#define PCI_MAX_PHB 64
extern int global_phb_number;
extern struct pci_controller *phbtab[];
/*******************************************************************
* Platform functions that are brand specific implementation.
*******************************************************************/
extern unsigned long find_and_init_phbs(void);
extern void ppc64_pcibios_init(void);
extern struct pci_dev *ppc64_isabridge_dev; /* may be NULL if no ISA bus */
/*******************************************************************
......@@ -46,10 +42,6 @@ void pci_devs_phb_init(void);
void pci_fix_bus_sysdata(void);
struct device_node *fetch_dev_dn(struct pci_dev *dev);
void iSeries_pcibios_init_early(void);
void pSeries_pcibios_init_early(void);
void pSeries_pcibios_init(void);
/*******************************************************************
* Helper macros for extracting data from pci structures.
* PCI_GET_PHB_PTR(struct pci_dev*) returns the Phb pointer.
......@@ -60,12 +52,4 @@ void pSeries_pcibios_init(void);
#define PCI_GET_PHB_NUMBER(dev) (((dev)->bus->number&0x00FFFF00)>>8)
#define PCI_GET_BUS_NUMBER(dev) ((dev)->bus->number&0x0000FF)
/*******************************************************************
* Debugging Routines.
*******************************************************************/
extern void dumpResources(struct resource* Resource);
extern void dumpPci_Controller(struct pci_controller* phb);
extern void dumpPci_Bus(struct pci_bus* Pci_Bus);
extern void dumpPci_Dev(struct pci_dev* Pci_Dev);
#endif /* __PPC_KERNEL_PCI_H__ */
......@@ -90,22 +90,6 @@ struct machdep_calls {
unsigned char (*udbg_getc)(void);
int (*udbg_getc_poll)(void);
/* PCI interfaces */
int (*pcibios_read_config)(struct device_node *dn, int where, int size,
u32 *val);
int (*pcibios_write_config)(struct device_node *dn, int where,
int size, u32 val);
/* Called after scanning the bus, before allocating
* resources
*/
void (*pcibios_fixup)(void);
/* Called for each PCI bus in the system
* when it's probed
*/
void (*pcibios_fixup_bus)(struct pci_bus *);
#ifdef CONFIG_SMP
/* functions for dealing with other cpus */
struct smp_ops_t smp_ops;
......
......@@ -40,7 +40,7 @@ struct pci_controller {
void *io_base_virt;
unsigned long io_base_phys;
/* Some machines (PReP) have a non 1:1 mapping of
/* Some machines have a non 1:1 mapping of
* the PCI memory space in the CPU bus space
*/
unsigned long pci_mem_offset;
......
......@@ -16,11 +16,6 @@
#include <asm/io.h>
#include <asm/prom.h>
static inline int pcibios_assign_all_busses(void)
{
return 0;
}
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0x10000000
......@@ -36,7 +31,18 @@ static inline void pcibios_penalize_isa_irq(int irq)
struct pci_dev;
extern char* pci_card_location(struct pci_dev*);
#define HAVE_ARCH_PCI_MWI 1
static inline int pcibios_prep_mwi(struct pci_dev *dev)
{
/*
* pSeries firmware sets cacheline size and hardware treats
* MWI the same as memory write, so we dont change cacheline size
* or the MWI bit.
*/
return 1;
}
extern unsigned int pcibios_assign_all_busses(void);
extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle);
......@@ -52,8 +58,6 @@ extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction);
extern void pSeries_pcibios_init_early(void);
static inline void pci_dma_sync_single(struct pci_dev *hwdev,
dma_addr_t dma_handle,
size_t size, int direction)
......@@ -122,9 +126,10 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
*/
#define PCI_DMA_BUS_IS_PHYS (0)
#endif /* __KERNEL__ */
extern void
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
struct resource *res);
/* generic pci stuff */
#include <asm-generic/pci.h>
#endif /* __KERNEL__ */
#endif /* __PPC64_PCI_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment