Skip to content

Commit

Permalink
powerpc/pci: Pull ppc32 PCI features into common
Browse files Browse the repository at this point in the history
Some of the PCI features we have in ppc32 we will need on ppc64
platforms in the future.  These include support for:

* ppc_md.pci_exclude_device
* indirect config cycles
* early config cycles

We also simplified the logic in fake_pci_bus() to assume it will always
get a valid pci_controller.  Since all current callers seem to pass it
one.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Kumar Gala authored and Benjamin Herrenschmidt committed Aug 28, 2009
1 parent fbe6544 commit 89c2dd6
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 93 deletions.
6 changes: 3 additions & 3 deletions arch/powerpc/include/asm/machdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,14 @@ struct machdep_calls {
/*
* optional PCI "hooks"
*/
/* Called in indirect_* to avoid touching devices */
int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);

/* Called at then very end of pcibios_init() */
void (*pcibios_after_init)(void);

#endif /* CONFIG_PPC32 */

/* Called in indirect_* to avoid touching devices */
int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);

/* Called after PPC generic resource fixup to perform
machine specific fixups */
void (*pcibios_fixup_resources)(struct pci_dev *);
Expand Down
35 changes: 16 additions & 19 deletions arch/powerpc/include/asm/pci-bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ struct pci_controller {

int first_busno;
int last_busno;
#ifndef CONFIG_PPC64
int self_busno;
#endif

void __iomem *io_base_virt;
#ifdef CONFIG_PPC64
Expand All @@ -104,7 +102,6 @@ struct pci_controller {
unsigned int __iomem *cfg_addr;
void __iomem *cfg_data;

#ifndef CONFIG_PPC64
/*
* Used for variants of PCI indirect handling and possible quirks:
* SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
Expand All @@ -128,7 +125,6 @@ struct pci_controller {
#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010
#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020
u32 indirect_type;
#endif /* !CONFIG_PPC64 */
/* Currently, we limit ourselves to 1 IO range and 3 mem
* ranges since the common pci_bus structure can't handle more
*/
Expand All @@ -146,21 +142,6 @@ struct pci_controller {
#endif /* CONFIG_PPC64 */
};

#ifndef CONFIG_PPC64

static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
{
return bus->sysdata;
}

static inline int isa_vaddr_is_ioport(void __iomem *address)
{
/* No specific ISA handling on ppc32 at this stage, it
* all goes through PCI
*/
return 0;
}

/* These are used for config access before all the PCI probing
has been done. */
extern int early_read_config_byte(struct pci_controller *hose, int bus,
Expand All @@ -182,6 +163,22 @@ extern int early_find_capability(struct pci_controller *hose, int bus,
extern void setup_indirect_pci(struct pci_controller* hose,
resource_size_t cfg_addr,
resource_size_t cfg_data, u32 flags);

#ifndef CONFIG_PPC64

static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
{
return bus->sysdata;
}

static inline int isa_vaddr_is_ioport(void __iomem *address)
{
/* No specific ISA handling on ppc32 at this stage, it
* all goes through PCI
*/
return 0;
}

#else /* CONFIG_PPC64 */

/*
Expand Down
71 changes: 71 additions & 0 deletions arch/powerpc/kernel/pci-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1617,3 +1617,74 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
(unsigned long)hose->io_base_virt - _IO_BASE);

}

/*
* Null PCI config access functions, for the case when we can't
* find a hose.
*/
#define NULL_PCI_OP(rw, size, type) \
static int \
null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
{ \
return PCIBIOS_DEVICE_NOT_FOUND; \
}

static int
null_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
return PCIBIOS_DEVICE_NOT_FOUND;
}

static int
null_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
return PCIBIOS_DEVICE_NOT_FOUND;
}

static struct pci_ops null_pci_ops =
{
.read = null_read_config,
.write = null_write_config,
};

/*
* These functions are used early on before PCI scanning is done
* and all of the pci_dev and pci_bus structures have been created.
*/
static struct pci_bus *
fake_pci_bus(struct pci_controller *hose, int busnr)
{
static struct pci_bus bus;

if (hose == 0) {
printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
}
bus.number = busnr;
bus.sysdata = hose;
bus.ops = hose? hose->ops: &null_pci_ops;
return &bus;
}

#define EARLY_PCI_OP(rw, size, type) \
int early_##rw##_config_##size(struct pci_controller *hose, int bus, \
int devfn, int offset, type value) \
{ \
return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus), \
devfn, offset, value); \
}

EARLY_PCI_OP(read, byte, u8 *)
EARLY_PCI_OP(read, word, u16 *)
EARLY_PCI_OP(read, dword, u32 *)
EARLY_PCI_OP(write, byte, u8)
EARLY_PCI_OP(write, word, u16)
EARLY_PCI_OP(write, dword, u32)

extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
int early_find_capability(struct pci_controller *hose, int bus, int devfn,
int cap)
{
return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
}
71 changes: 0 additions & 71 deletions arch/powerpc/kernel/pci_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,75 +469,4 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
return result;
}

/*
* Null PCI config access functions, for the case when we can't
* find a hose.
*/
#define NULL_PCI_OP(rw, size, type) \
static int \
null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
{ \
return PCIBIOS_DEVICE_NOT_FOUND; \
}

static int
null_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
return PCIBIOS_DEVICE_NOT_FOUND;
}

static int
null_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
return PCIBIOS_DEVICE_NOT_FOUND;
}

static struct pci_ops null_pci_ops =
{
.read = null_read_config,
.write = null_write_config,
};

/*
* These functions are used early on before PCI scanning is done
* and all of the pci_dev and pci_bus structures have been created.
*/
static struct pci_bus *
fake_pci_bus(struct pci_controller *hose, int busnr)
{
static struct pci_bus bus;

if (hose == 0) {
hose = pci_bus_to_hose(busnr);
if (hose == 0)
printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
}
bus.number = busnr;
bus.sysdata = hose;
bus.ops = hose? hose->ops: &null_pci_ops;
return &bus;
}

#define EARLY_PCI_OP(rw, size, type) \
int early_##rw##_config_##size(struct pci_controller *hose, int bus, \
int devfn, int offset, type value) \
{ \
return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus), \
devfn, offset, value); \
}

EARLY_PCI_OP(read, byte, u8 *)
EARLY_PCI_OP(read, word, u16 *)
EARLY_PCI_OP(read, dword, u32 *)
EARLY_PCI_OP(write, byte, u8)
EARLY_PCI_OP(write, word, u16)
EARLY_PCI_OP(write, dword, u32)

extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
int early_find_capability(struct pci_controller *hose, int bus, int devfn,
int cap)
{
return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
}

0 comments on commit 89c2dd6

Please sign in to comment.