summaryrefslogtreecommitdiffstats
path: root/include/linux/pci.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/pci.h')
-rw-r--r--include/linux/pci.h98
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 */