// SPDX-License-Identifier: GPL-2.0 /* * System Control and Management Interface (SCMI) Message Protocol bus layer * * Copyright (C) 2018-2021 ARM Ltd. */ #define pr_fmt(fmt) … #include <linux/atomic.h> #include <linux/types.h> #include <linux/module.h> #include <linux/of.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/device.h> #include "common.h" BLOCKING_NOTIFIER_HEAD(…) …; EXPORT_SYMBOL_GPL(…); static DEFINE_IDA(scmi_bus_id); static DEFINE_IDR(scmi_requested_devices); /* Protect access to scmi_requested_devices */ static DEFINE_MUTEX(scmi_requested_devices_mtx); struct scmi_requested_dev { … }; /* Track globally the creation of SCMI SystemPower related devices */ static atomic_t scmi_syspower_registered = …; /** * scmi_protocol_device_request - Helper to request a device * * @id_table: A protocol/name pair descriptor for the device to be created. * * This helper let an SCMI driver request specific devices identified by the * @id_table to be created for each active SCMI instance. * * The requested device name MUST NOT be already existent for any protocol; * at first the freshly requested @id_table is annotated in the IDR table * @scmi_requested_devices and then the requested device is advertised to any * registered party via the @scmi_requested_devices_nh notification chain. * * Return: 0 on Success */ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) { … } static int scmi_protocol_table_register(const struct scmi_device_id *id_table) { … } /** * scmi_protocol_device_unrequest - Helper to unrequest a device * * @id_table: A protocol/name pair descriptor for the device to be unrequested. * * The unrequested device, described by the provided id_table, is at first * removed from the IDR @scmi_requested_devices and then the removal is * advertised to any registered party via the @scmi_requested_devices_nh * notification chain. */ static void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table) { … } static void scmi_protocol_table_unregister(const struct scmi_device_id *id_table) { … } static const struct scmi_device_id * scmi_dev_match_id(struct scmi_device *scmi_dev, const struct scmi_driver *scmi_drv) { … } static int scmi_dev_match(struct device *dev, const struct device_driver *drv) { … } static int scmi_match_by_id_table(struct device *dev, void *data) { … } static struct scmi_device *scmi_child_dev_find(struct device *parent, int prot_id, const char *name) { … } static int scmi_dev_probe(struct device *dev) { … } static void scmi_dev_remove(struct device *dev) { … } const struct bus_type scmi_bus_type = …; EXPORT_SYMBOL_GPL(…); int scmi_driver_register(struct scmi_driver *driver, struct module *owner, const char *mod_name) { … } EXPORT_SYMBOL_GPL(…); void scmi_driver_unregister(struct scmi_driver *driver) { … } EXPORT_SYMBOL_GPL(…); static void scmi_device_release(struct device *dev) { … } static void __scmi_device_destroy(struct scmi_device *scmi_dev) { … } static struct scmi_device * __scmi_device_create(struct device_node *np, struct device *parent, int protocol, const char *name) { … } /** * scmi_device_create - A method to create one or more SCMI devices * * @np: A reference to the device node to use for the new device(s) * @parent: The parent device to use identifying a specific SCMI instance * @protocol: The SCMI protocol to be associated with this device * @name: The requested-name of the device to be created; this is optional * and if no @name is provided, all the devices currently known to * be requested on the SCMI bus for @protocol will be created. * * This method can be invoked to create a single well-defined device (like * a transport device or a device requested by an SCMI driver loaded after * the core SCMI stack has been probed), or to create all the devices currently * known to have been requested by the loaded SCMI drivers for a specific * protocol (typically during SCMI core protocol enumeration at probe time). * * Return: The created device (or one of them if @name was NOT provided and * multiple devices were created) or NULL if no device was created; * note that NULL indicates an error ONLY in case a specific @name * was provided: when @name param was not provided, a number of devices * could have been potentially created for a whole protocol, unless no * device was found to have been requested for that specific protocol. */ struct scmi_device *scmi_device_create(struct device_node *np, struct device *parent, int protocol, const char *name) { … } EXPORT_SYMBOL_GPL(…); void scmi_device_destroy(struct device *parent, int protocol, const char *name) { … } EXPORT_SYMBOL_GPL(…); static int __scmi_devices_unregister(struct device *dev, void *data) { … } static void scmi_devices_unregister(void) { … } static int __init scmi_bus_init(void) { … } subsys_initcall(scmi_bus_init); static void __exit scmi_bus_exit(void) { … } module_exit(scmi_bus_exit); MODULE_ALIAS(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;