1b88cbaaaSBjorn Helgaas /* SPDX-License-Identifier: GPL-2.0-only */ 2b88cbaaaSBjorn Helgaas /* 3b88cbaaaSBjorn Helgaas * Copyright (C) 2024 Linaro Ltd. 4b88cbaaaSBjorn Helgaas */ 5b88cbaaaSBjorn Helgaas 6*3f925cd6SBjorn Helgaas #ifndef __PCI_PWRCTRL_H__ 7*3f925cd6SBjorn Helgaas #define __PCI_PWRCTRL_H__ 8b88cbaaaSBjorn Helgaas 9b88cbaaaSBjorn Helgaas #include <linux/notifier.h> 10b88cbaaaSBjorn Helgaas #include <linux/workqueue.h> 11b88cbaaaSBjorn Helgaas 12b88cbaaaSBjorn Helgaas struct device; 13b88cbaaaSBjorn Helgaas struct device_link; 14b88cbaaaSBjorn Helgaas 15b88cbaaaSBjorn Helgaas /* 16b88cbaaaSBjorn Helgaas * This is a simple framework for solving the issue of PCI devices that require 17b88cbaaaSBjorn Helgaas * certain resources (regulators, GPIOs, clocks) to be enabled before the 18b88cbaaaSBjorn Helgaas * device can actually be detected on the PCI bus. 19b88cbaaaSBjorn Helgaas * 20b88cbaaaSBjorn Helgaas * The idea is to reuse the platform bus to populate OF nodes describing the 21b88cbaaaSBjorn Helgaas * PCI device and its resources, let these platform devices probe and enable 22b88cbaaaSBjorn Helgaas * relevant resources and then trigger a rescan of the PCI bus allowing for the 23b88cbaaaSBjorn Helgaas * same device (with a second associated struct device) to be registered with 24b88cbaaaSBjorn Helgaas * the PCI subsystem. 25b88cbaaaSBjorn Helgaas * 26b88cbaaaSBjorn Helgaas * To preserve a correct hierarchy for PCI power management and device reset, 27b88cbaaaSBjorn Helgaas * we create a device link between the power control platform device (parent) 28b88cbaaaSBjorn Helgaas * and the supplied PCI device (child). 29b88cbaaaSBjorn Helgaas */ 30b88cbaaaSBjorn Helgaas 31b88cbaaaSBjorn Helgaas /** 32*3f925cd6SBjorn Helgaas * struct pci_pwrctrl - PCI device power control context. 33b88cbaaaSBjorn Helgaas * @dev: Address of the power controlling device. 34b88cbaaaSBjorn Helgaas * 35b88cbaaaSBjorn Helgaas * An object of this type must be allocated by the PCI power control device and 36*3f925cd6SBjorn Helgaas * passed to the pwrctrl subsystem to trigger a bus rescan and setup a device 37b88cbaaaSBjorn Helgaas * link with the device once it's up. 38b88cbaaaSBjorn Helgaas */ 39*3f925cd6SBjorn Helgaas struct pci_pwrctrl { 40b88cbaaaSBjorn Helgaas struct device *dev; 41b88cbaaaSBjorn Helgaas 42b88cbaaaSBjorn Helgaas /* Private: don't use. */ 43b88cbaaaSBjorn Helgaas struct notifier_block nb; 44b88cbaaaSBjorn Helgaas struct device_link *link; 45b88cbaaaSBjorn Helgaas struct work_struct work; 46b88cbaaaSBjorn Helgaas }; 47b88cbaaaSBjorn Helgaas 48*3f925cd6SBjorn Helgaas void pci_pwrctrl_init(struct pci_pwrctrl *pwrctrl, struct device *dev); 49*3f925cd6SBjorn Helgaas int pci_pwrctrl_device_set_ready(struct pci_pwrctrl *pwrctrl); 50*3f925cd6SBjorn Helgaas void pci_pwrctrl_device_unset_ready(struct pci_pwrctrl *pwrctrl); 51*3f925cd6SBjorn Helgaas int devm_pci_pwrctrl_device_set_ready(struct device *dev, 52*3f925cd6SBjorn Helgaas struct pci_pwrctrl *pwrctrl); 53b88cbaaaSBjorn Helgaas 54*3f925cd6SBjorn Helgaas #endif /* __PCI_PWRCTRL_H__ */ 55