Add support to notify the EPF device about the Device State (D_STATE) event received by the EPC device from the Root complex. Usage: ====== EPC --- ``` static irqreturn_t pcie_ep_irq(int irq, void *data) { ... case PCIE_EP_INT_D_STATE: dstate = dw_pcie_readl_dbi(pci, DBI_CON_STATUS) & 0x3; pci_epc_d_state_notify(epc, dstate); break; ... } ``` EPF --- ``` static int pci_epf_notifier(struct notifier_block *nb, unsigned long val, void *data) { ... case D_STATE: dstate = data; if (dstate == PCIE_EP_D0) /* Handle D0 event */ else if (dstate == PCIE_EP_D3) /* Handle D3 event */ break; ... } ``` Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> --- drivers/pci/endpoint/pci-epc-core.c | 18 ++++++++++++++++++ include/linux/pci-epc.h | 1 + include/linux/pci-epf.h | 1 + 3 files changed, 20 insertions(+) diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index 63fe90dbbba2..b4a7bb3caa97 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -710,6 +710,24 @@ void pci_epc_pme_notify(struct pci_epc *epc, void *data) } EXPORT_SYMBOL_GPL(pci_epc_pme_notify); +/** + * pci_epc_d_state_notify() - Notify the EPF device that the EPC device has + * received the Device State event from Root complex + * @epc: the EPC device that received the Device State event + * @data: Data for the D_STATE notifier + * + * Invoke to notify the EPF device that the EPC device has received the Device + * State (D_STATE) event from the Root complex + */ +void pci_epc_d_state_notify(struct pci_epc *epc, void *data) +{ + if (!epc || IS_ERR(epc)) + return; + + atomic_notifier_call_chain(&epc->notifier, D_STATE, data); +} +EXPORT_SYMBOL_GPL(pci_epc_d_state_notify); + /** * pci_epc_destroy() - destroy the EPC device * @epc: the EPC device that has to be destroyed diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index 37dbcade1780..94c66fae8a88 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h @@ -206,6 +206,7 @@ void pci_epc_linkdown(struct pci_epc *epc); void pci_epc_init_notify(struct pci_epc *epc); void pci_epc_bme_notify(struct pci_epc *epc); void pci_epc_pme_notify(struct pci_epc *epc, void *data); +void pci_epc_d_state_notify(struct pci_epc *epc, void *data); void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf, enum pci_epc_interface_type type); int pci_epc_write_header(struct pci_epc *epc, u8 func_no, diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index c162a73eb836..ca020c080431 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h @@ -23,6 +23,7 @@ enum pci_notify_event { LINK_DOWN, BME, PME, + D_STATE, }; enum pci_barno { -- 2.25.1