pci-bridge.h 5.0 KB
Newer Older
1 2
#ifndef _ASM_POWERPC_PCI_BRIDGE_H
#define _ASM_POWERPC_PCI_BRIDGE_H
3
#ifdef __KERNEL__
4 5 6 7

#ifndef CONFIG_PPC64
#include <asm-ppc/pci-bridge.h>
#else
L
Linus Torvalds 已提交
8 9

#include <linux/pci.h>
10
#include <linux/list.h>
L
Linus Torvalds 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

/*
 * Structure of a PCI controller (host bridge)
 */
struct pci_controller {
	struct pci_bus *bus;
	char is_dynamic;
	void *arch_data;
	struct list_head list_node;

	int first_busno;
	int last_busno;

	void __iomem *io_base_virt;
	unsigned long io_base_phys;

	/* Some machines have a non 1:1 mapping of
	 * the PCI memory space in the CPU bus space
	 */
	unsigned long pci_mem_offset;
	unsigned long pci_io_size;

	struct pci_ops *ops;
	volatile unsigned int __iomem *cfg_addr;
42
	volatile void __iomem *cfg_data;
L
Linus Torvalds 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55

	/* Currently, we limit ourselves to 1 IO range and 3 mem
	 * ranges since the common pci_bus structure can't handle more
	 */
	struct resource io_resource;
	struct resource mem_resources[3];
	int global_number;		
	int local_number;		
	unsigned long buid;
	unsigned long dma_window_base_cur;
	unsigned long dma_window_size;
};

56 57 58 59 60 61 62 63
/*
 * PCI stuff, for nodes representing PCI devices, pointed to
 * by device_node->data.
 */
struct pci_controller;
struct iommu_table;

struct pci_dn {
64 65 66 67
	int	busno;			/* pci bus number */
	int	bussubno;		/* pci subordinate bus number */
	int	devfn;			/* pci device and function number */
	int	class_code;		/* pci device class */
68 69

#ifdef CONFIG_PPC_PSERIES
70 71
	int	eeh_mode;		/* See eeh.h for possible EEH_MODEs */
	int	eeh_config_addr;
72
	int	eeh_pe_config_addr; /* new-style partition endpoint address */
73 74
	int 	eeh_check_count;	/* # times driver ignored error */
	int 	eeh_freeze_count;	/* # times this device froze up. */
75
#endif
76 77 78 79 80
	int	pci_ext_config_space;	/* for pci devices */
	struct  pci_controller *phb;	/* for pci devices */
	struct	iommu_table *iommu_table;	/* for phb's or bridges */
	struct	pci_dev *pcidev;	/* back-pointer to the pci device */
	struct	device_node *node;	/* back-pointer to the device_node */
81
#ifdef CONFIG_PPC_ISERIES
82 83
	int	Flags;			/* Possible flags(disable/bist)*/
	u8	LogicalSlot;		/* Hv Slot Index for Tces */
84
#endif
85 86 87 88 89 90
	u32	config_space[16];	/* saved PCI config space */
};

/* Get the pointer to a device_node's pci_dn */
#define PCI_DN(dn)	((struct pci_dn *) (dn)->data)

L
Linus Torvalds 已提交
91 92
struct device_node *fetch_dev_dn(struct pci_dev *dev);

93 94 95 96 97 98
/* Get a device_node from a pci_dev.  This code must be fast except
 * in the case where the sysdata is incorrect and needs to be fixed
 * up (this will only happen once).
 * In this case the sysdata will have been inherited from a PCI host
 * bridge or a PCI-PCI bridge further up the tree, so it will point
 * to a valid struct pci_dn, just not the one we want.
L
Linus Torvalds 已提交
99 100 101 102
 */
static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
{
	struct device_node *dn = dev->sysdata;
103
	struct pci_dn *pdn = dn->data;
L
Linus Torvalds 已提交
104

105
	if (pdn && pdn->devfn == dev->devfn && pdn->busno == dev->bus->number)
L
Linus Torvalds 已提交
106
		return dn;	/* fast path.  sysdata is good */
107
	return fetch_dev_dn(dev);
L
Linus Torvalds 已提交
108 109
}

110 111 112 113 114 115 116 117 118 119
static inline int pci_device_from_OF_node(struct device_node *np,
					  u8 *bus, u8 *devfn)
{
	if (!PCI_DN(np))
		return -ENODEV;
	*bus = PCI_DN(np)->busno;
	*devfn = PCI_DN(np)->devfn;
	return 0;
}

L
Linus Torvalds 已提交
120 121 122 123 124 125 126 127
static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
{
	if (bus->self)
		return pci_device_to_OF_node(bus->self);
	else
		return bus->sysdata; /* Must be root bus (PHB) */
}

128 129 130
/** Find the bus corresponding to the indicated device node */
struct pci_bus * pcibios_find_pci_bus(struct device_node *dn);

L
Linus Torvalds 已提交
131
extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
132
					 struct device_node *dev, int primary);
L
Linus Torvalds 已提交
133

134 135 136 137 138
/** Remove all of the PCI devices under this bus */
void pcibios_remove_pci_devices(struct pci_bus *bus);

/** Discover new pci devices under this bus, and add them */
void pcibios_add_pci_devices(struct pci_bus * bus);
139
void pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus);
140

L
Linus Torvalds 已提交
141 142 143 144 145 146 147
extern int pcibios_remove_root_bus(struct pci_controller *phb);

static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
{
	struct device_node *busdn = bus->sysdata;

	BUG_ON(busdn == NULL);
148
	return PCI_DN(busdn)->phb;
L
Linus Torvalds 已提交
149 150
}

151 152 153
extern struct pci_controller*
pci_find_hose_for_OF_device(struct device_node* node);

154 155 156 157
extern struct pci_controller *
pcibios_alloc_controller(struct device_node *dev);
extern void pcibios_free_controller(struct pci_controller *phb);

158
#ifdef CONFIG_PCI
159
extern unsigned long pci_address_to_pio(phys_addr_t address);
160
#else
161
static inline unsigned long pci_address_to_pio(phys_addr_t address)
162
{
163
	return (unsigned long)-1;
164 165 166
}
#endif

167 168 169 170 171
/* Return values for ppc_md.pci_probe_mode function */
#define PCI_PROBE_NONE		-1	/* Don't look at this bus at all */
#define PCI_PROBE_NORMAL	0	/* Do normal PCI probing */
#define PCI_PROBE_DEVTREE	1	/* Instantiate from device tree */

172
#endif /* CONFIG_PPC64 */
173
#endif /* __KERNEL__ */
L
Linus Torvalds 已提交
174
#endif