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