diff options
Diffstat (limited to 'include/linux/pci.h')
-rw-r--r-- | include/linux/pci.h | 98 |
1 files changed, 86 insertions, 12 deletions
diff --git a/include/linux/pci.h b/include/linux/pci.h index d92d70b6bd..f6511e0095 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + /* * pci.h * @@ -23,14 +25,20 @@ #include <linux/ioport.h> #include <linux/list.h> #include <linux/compiler.h> +#include <linux/resource_ext.h> #include <driver.h> #include <errno.h> #include <io.h> #include <linux/pci_ids.h> +/* Include architecture-dependent settings and functions */ + +#include <asm/pci.h> #define PCI_ANY_ID (~0) +#define PCI_FIND_CAP_TTL 48 + /* * The PCI interface treats multi-function devices as independent * devices. The slot/function address of each device is encoded @@ -95,7 +103,7 @@ struct pci_dev { struct pci_slot *slot; /* Physical slot this device is in */ const struct pci_device_id *id; /* the id this device matches */ - struct device_d dev; + struct device dev; unsigned int devfn; /* encoded device & function index */ unsigned short vendor; @@ -115,20 +123,31 @@ struct pci_dev { }; #define to_pci_dev(d) container_of(d, struct pci_dev, dev) +#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) +#define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end) +#define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags) +#define pci_resource_len(dev,bar) \ + ((pci_resource_start((dev), (bar)) == 0 && \ + pci_resource_end((dev), (bar)) == \ + pci_resource_start((dev), (bar))) ? 0 : \ + \ + (pci_resource_end((dev), (bar)) - \ + pci_resource_start((dev), (bar)) + 1)) + enum { PCI_BUS_RESOURCE_IO = 0, PCI_BUS_RESOURCE_MEM = 1, PCI_BUS_RESOURCE_MEM_PREF = 2, PCI_BUS_RESOURCE_BUSN = 3, }; + struct pci_bus { struct pci_controller *host; /* associated host controller */ - struct device_d *parent; - struct pci_bus *parent_bus; /* parent bus */ + struct pci_dev *self; + struct pci_bus *parent; /* Parent bus this bridge is on */ struct list_head node; /* node in list of buses */ struct list_head children; /* list of child buses */ struct list_head devices; /* list of devices on this bus */ - struct resource *resource[PCI_BRIDGE_RESOURCE_NUM]; unsigned char number; /* bus number */ unsigned char primary; /* number of primary bridge */ @@ -155,7 +174,7 @@ extern struct pci_ops *pci_ops; */ struct pci_controller { struct pci_controller *next; - struct device_d *parent; + struct device *parent; struct pci_bus *bus; const struct pci_ops *pci_ops; @@ -166,6 +185,8 @@ struct pci_controller { unsigned long io_offset; unsigned long io_map_base; + struct list_head windows; /* resource_entry */ + unsigned int index; /* Optional access method for writing the bus number */ @@ -178,15 +199,11 @@ struct pci_driver { const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */ int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ - struct driver_d driver; + struct driver driver; }; #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) -/* these helpers provide future and backwards compatibility - * for accessing popular PCI BAR info */ -#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) - /** * DEFINE_PCI_DEVICE_TABLE - macro used to describe a pci device table * @_table: device table name @@ -211,6 +228,20 @@ struct pci_driver { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID /** + * PCI_DEVICE_SUB - macro used to describe a specific PCI device with subsystem + * @vend: the 16 bit PCI Vendor ID + * @dev: the 16 bit PCI Device ID + * @subvend: the 16 bit PCI Subvendor ID + * @subdev: the 16 bit PCI Subdevice ID + * + * This macro is used to create a struct pci_device_id that matches a + * specific device with subsystem information. + */ +#define PCI_DEVICE_SUB(vend, dev, subvend, subdev) \ + .vendor = (vend), .device = (dev), \ + .subvendor = (subvend), .subdevice = (subdev) + +/** * PCI_DEVICE_CLASS - macro used to describe a specific pci device class * @dev_class: the class, subclass, prog-if triple for this device * @dev_class_mask: the class mask for this device @@ -249,6 +280,7 @@ int pci_register_device(struct pci_dev *pdev); extern struct list_head pci_root_buses; /* list of all known PCI buses */ +extern void pci_controller_init(struct pci_controller *hose); extern void register_pci_controller(struct pci_controller *hose); int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, @@ -294,9 +326,15 @@ static inline int pci_write_config_dword(const struct pci_dev *dev, int where, void pci_set_master(struct pci_dev *dev); void pci_clear_master(struct pci_dev *dev); int pci_enable_device(struct pci_dev *dev); +int pci_select_bars(struct pci_dev *dev, unsigned long flags); + +u8 pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap); +u8 pci_find_capability(struct pci_dev *dev, int cap); extern void __iomem *pci_iomap(struct pci_dev *dev, int bar); +int pci_flr(struct pci_dev *pdev); + /* * The world is not perfect and supplies us with broken PCI devices. * For at least a part of these bugs we need a work-around, so both @@ -321,8 +359,8 @@ enum pci_fixup_pass { /* Anonymous variables would be nice... */ #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \ class_shift, hook) \ - static const struct pci_fixup __PASTE(__pci_fixup_##name,__LINE__) __used \ - __attribute__((__section__(#section), aligned((sizeof(void *))))) \ + static const struct pci_fixup __PASTE(__pci_fixup_##name,__LINE__) \ + __ll_elem(section) __aligned(sizeof(void *)) \ = { vendor, device, class, class_shift, hook }; #define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class, \ @@ -350,4 +388,40 @@ enum pci_fixup_pass { void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); +#ifdef CONFIG_PCI +const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, + struct pci_dev *dev); +#else +static inline const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, + struct pci_dev *dev) +{ return NULL; } +#endif + +/* drivers/pci/bus.c */ +void pci_add_resource_offset(struct list_head *resources, struct resource *res, + resource_size_t offset); +void pci_add_resource(struct list_head *resources, struct resource *res); + +struct pci_controller *pci_find_host_bridge(struct pci_bus *bus); + +struct pci_bus_region { + u64 start; + u64 end; +}; + +void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, + struct resource *res); +void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res, + struct pci_bus_region *region); + +/* drivers/pci/of.c */ +#ifdef CONFIG_OFDEVICE +int of_pci_bridge_init(struct device *dev, struct pci_controller *bridge); +#else +static inline int of_pci_bridge_init(struct device *dev, struct pci_controller *bridge) +{ + return 0; +} +#endif + #endif /* LINUX_PCI_H */ |