blob: 6ffc797a0dc1c9a25004be6b0da94727a4956aba [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 * Purpose: PCI Express Port Bus Driver's Internal Data Structures
4 *
5 * Copyright (C) 2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */
8
9#ifndef _PORTDRV_H_
10#define _PORTDRV_H_
11
Andrew Morton3ec6a8d2006-09-25 16:52:20 -070012#include <linux/compiler.h>
13
Bjorn Helgaasef794262018-03-09 11:42:01 -060014/* Service Type */
15#define PCIE_PORT_SERVICE_PME_SHIFT 0 /* Power Management Event */
16#define PCIE_PORT_SERVICE_PME (1 << PCIE_PORT_SERVICE_PME_SHIFT)
17#define PCIE_PORT_SERVICE_AER_SHIFT 1 /* Advanced Error Reporting */
18#define PCIE_PORT_SERVICE_AER (1 << PCIE_PORT_SERVICE_AER_SHIFT)
19#define PCIE_PORT_SERVICE_HP_SHIFT 2 /* Native Hotplug */
20#define PCIE_PORT_SERVICE_HP (1 << PCIE_PORT_SERVICE_HP_SHIFT)
Bjorn Helgaas168f3ae2018-03-09 11:21:24 -060021#define PCIE_PORT_SERVICE_DPC_SHIFT 3 /* Downstream Port Containment */
Bjorn Helgaasef794262018-03-09 11:42:01 -060022#define PCIE_PORT_SERVICE_DPC (1 << PCIE_PORT_SERVICE_DPC_SHIFT)
23
Bjorn Helgaas168f3ae2018-03-09 11:21:24 -060024#define PCIE_PORT_DEVICE_MAXSERVICES 4
Bjorn Helgaasef794262018-03-09 11:42:01 -060025
26/* Port Type */
27#define PCIE_ANY_PORT (~0)
28
29struct pcie_device {
30 int irq; /* Service IRQ/MSI/MSI-X Vector */
31 struct pci_dev *port; /* Root/Upstream/Downstream Port */
32 u32 service; /* Port service this device represents */
33 void *priv_data; /* Service Private Data */
34 struct device device; /* Generic Device Interface */
35};
36#define to_pcie_device(d) container_of(d, struct pcie_device, device)
37
38static inline void set_service_data(struct pcie_device *dev, void *data)
39{
40 dev->priv_data = data;
41}
42
43static inline void *get_service_data(struct pcie_device *dev)
44{
45 return dev->priv_data;
46}
47
48struct pcie_port_service_driver {
49 const char *name;
50 int (*probe) (struct pcie_device *dev);
51 void (*remove) (struct pcie_device *dev);
52 int (*suspend) (struct pcie_device *dev);
53 int (*resume) (struct pcie_device *dev);
54
55 /* Device driver may resume normal operations */
56 void (*error_resume)(struct pci_dev *dev);
57
58 /* Link Reset Capability - AER service driver specific */
59 pci_ers_result_t (*reset_link) (struct pci_dev *dev);
60
61 int port_type; /* Type of the port this driver can handle */
62 u32 service; /* Port service this device represents */
63
64 struct device_driver driver;
65};
66#define to_service_driver(d) \
67 container_of(d, struct pcie_port_service_driver, driver)
68
69int pcie_port_service_register(struct pcie_port_service_driver *new);
70void pcie_port_service_unregister(struct pcie_port_service_driver *new);
71
Rafael J. Wysockib43d4512009-01-24 00:23:22 +010072/*
Gabriele Paolonia1d5f182017-05-23 15:23:58 +010073 * The PCIe Capability Interrupt Message Number (PCIe r3.1, sec 7.8.2) must
74 * be one of the first 32 MSI-X entries. Per PCI r3.0, sec 6.8.3.1, MSI
75 * supports a maximum of 32 vectors per function.
Rafael J. Wysockib43d4512009-01-24 00:23:22 +010076 */
Gabriele Paolonia1d5f182017-05-23 15:23:58 +010077#define PCIE_PORT_MAX_MSI_ENTRIES 32
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
Keith Busch6d814172016-05-03 09:58:11 -050079#define get_descriptor_id(type, service) (((type - 4) << 8) | service)
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
81extern struct bus_type pcie_port_bus_type;
Bjorn Helgaasf39d5b72013-04-12 12:02:59 -060082int pcie_port_device_register(struct pci_dev *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070083#ifdef CONFIG_PM
Bjorn Helgaasf39d5b72013-04-12 12:02:59 -060084int pcie_port_device_suspend(struct device *dev);
85int pcie_port_device_resume(struct device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086#endif
Bjorn Helgaasf39d5b72013-04-12 12:02:59 -060087void pcie_port_device_remove(struct pci_dev *dev);
88int __must_check pcie_port_bus_register(void);
89void pcie_port_bus_unregister(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Rafael J. Wysocki28eb5f22010-08-21 22:02:38 +020091struct pci_dev;
92
Rafael J. Wysockic39fae12010-02-17 23:40:07 +010093#ifdef CONFIG_PCIE_PME
94extern bool pcie_pme_msi_disabled;
95
96static inline void pcie_pme_disable_msi(void)
97{
98 pcie_pme_msi_disabled = true;
99}
100
101static inline bool pcie_pme_no_msi(void)
102{
103 return pcie_pme_msi_disabled;
104}
Rafael J. Wysocki28eb5f22010-08-21 22:02:38 +0200105
Bjorn Helgaasf39d5b72013-04-12 12:02:59 -0600106void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable);
Rafael J. Wysockic39fae12010-02-17 23:40:07 +0100107#else /* !CONFIG_PCIE_PME */
108static inline void pcie_pme_disable_msi(void) {}
109static inline bool pcie_pme_no_msi(void) { return false; }
Rafael J. Wysocki28eb5f22010-08-21 22:02:38 +0200110static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {}
Rafael J. Wysockic39fae12010-02-17 23:40:07 +0100111#endif /* !CONFIG_PCIE_PME */
112
Bjorn Helgaas0544b042018-06-08 08:40:16 -0500113#ifdef CONFIG_ACPI_APEI
114int pcie_aer_get_firmware_first(struct pci_dev *pci_dev);
115#else
116static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
117{
118 if (pci_dev->__aer_firmware_first_valid)
119 return pci_dev->__aer_firmware_first;
120 return 0;
121}
122#endif
123
Bjorn Helgaasf53e7412018-06-08 08:40:25 -0500124#ifdef CONFIG_PCIEAER
125irqreturn_t aer_irq(int irq, void *context);
126#endif
127
Oza Pawandeepf252d062018-05-17 16:44:16 -0500128struct pcie_port_service_driver *pcie_port_find_service(struct pci_dev *dev,
129 u32 service);
Oza Pawandeepe76d5962018-05-17 16:44:17 -0500130struct device *pcie_port_find_device(struct pci_dev *dev, u32 service);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131#endif /* _PORTDRV_H_ */