root/drivers/firmware/arm_scmi/bus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. scmi_dev_match_id
  2. scmi_dev_match
  3. scmi_protocol_init
  4. scmi_dev_probe
  5. scmi_dev_remove
  6. scmi_driver_register
  7. scmi_driver_unregister
  8. scmi_device_release
  9. scmi_device_create
  10. scmi_device_destroy
  11. scmi_set_handle
  12. scmi_protocol_register
  13. scmi_protocol_unregister
  14. __scmi_devices_unregister
  15. scmi_devices_unregister
  16. scmi_bus_init
  17. scmi_bus_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * System Control and Management Interface (SCMI) Message Protocol bus layer
   4  *
   5  * Copyright (C) 2018 ARM Ltd.
   6  */
   7 
   8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9 
  10 #include <linux/types.h>
  11 #include <linux/module.h>
  12 #include <linux/kernel.h>
  13 #include <linux/slab.h>
  14 #include <linux/device.h>
  15 
  16 #include "common.h"
  17 
  18 static DEFINE_IDA(scmi_bus_id);
  19 static DEFINE_IDR(scmi_protocols);
  20 static DEFINE_SPINLOCK(protocol_lock);
  21 
  22 static const struct scmi_device_id *
  23 scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv)
  24 {
  25         const struct scmi_device_id *id = scmi_drv->id_table;
  26 
  27         if (!id)
  28                 return NULL;
  29 
  30         for (; id->protocol_id; id++)
  31                 if (id->protocol_id == scmi_dev->protocol_id)
  32                         return id;
  33 
  34         return NULL;
  35 }
  36 
  37 static int scmi_dev_match(struct device *dev, struct device_driver *drv)
  38 {
  39         struct scmi_driver *scmi_drv = to_scmi_driver(drv);
  40         struct scmi_device *scmi_dev = to_scmi_dev(dev);
  41         const struct scmi_device_id *id;
  42 
  43         id = scmi_dev_match_id(scmi_dev, scmi_drv);
  44         if (id)
  45                 return 1;
  46 
  47         return 0;
  48 }
  49 
  50 static int scmi_protocol_init(int protocol_id, struct scmi_handle *handle)
  51 {
  52         scmi_prot_init_fn_t fn = idr_find(&scmi_protocols, protocol_id);
  53 
  54         if (unlikely(!fn))
  55                 return -EINVAL;
  56         return fn(handle);
  57 }
  58 
  59 static int scmi_dev_probe(struct device *dev)
  60 {
  61         struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
  62         struct scmi_device *scmi_dev = to_scmi_dev(dev);
  63         const struct scmi_device_id *id;
  64         int ret;
  65 
  66         id = scmi_dev_match_id(scmi_dev, scmi_drv);
  67         if (!id)
  68                 return -ENODEV;
  69 
  70         if (!scmi_dev->handle)
  71                 return -EPROBE_DEFER;
  72 
  73         ret = scmi_protocol_init(scmi_dev->protocol_id, scmi_dev->handle);
  74         if (ret)
  75                 return ret;
  76 
  77         return scmi_drv->probe(scmi_dev);
  78 }
  79 
  80 static int scmi_dev_remove(struct device *dev)
  81 {
  82         struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
  83         struct scmi_device *scmi_dev = to_scmi_dev(dev);
  84 
  85         if (scmi_drv->remove)
  86                 scmi_drv->remove(scmi_dev);
  87 
  88         return 0;
  89 }
  90 
  91 static struct bus_type scmi_bus_type = {
  92         .name = "scmi_protocol",
  93         .match = scmi_dev_match,
  94         .probe = scmi_dev_probe,
  95         .remove = scmi_dev_remove,
  96 };
  97 
  98 int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
  99                          const char *mod_name)
 100 {
 101         int retval;
 102 
 103         driver->driver.bus = &scmi_bus_type;
 104         driver->driver.name = driver->name;
 105         driver->driver.owner = owner;
 106         driver->driver.mod_name = mod_name;
 107 
 108         retval = driver_register(&driver->driver);
 109         if (!retval)
 110                 pr_debug("registered new scmi driver %s\n", driver->name);
 111 
 112         return retval;
 113 }
 114 EXPORT_SYMBOL_GPL(scmi_driver_register);
 115 
 116 void scmi_driver_unregister(struct scmi_driver *driver)
 117 {
 118         driver_unregister(&driver->driver);
 119 }
 120 EXPORT_SYMBOL_GPL(scmi_driver_unregister);
 121 
 122 static void scmi_device_release(struct device *dev)
 123 {
 124         kfree(to_scmi_dev(dev));
 125 }
 126 
 127 struct scmi_device *
 128 scmi_device_create(struct device_node *np, struct device *parent, int protocol)
 129 {
 130         int id, retval;
 131         struct scmi_device *scmi_dev;
 132 
 133         scmi_dev = kzalloc(sizeof(*scmi_dev), GFP_KERNEL);
 134         if (!scmi_dev)
 135                 return NULL;
 136 
 137         id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
 138         if (id < 0) {
 139                 kfree(scmi_dev);
 140                 return NULL;
 141         }
 142 
 143         scmi_dev->id = id;
 144         scmi_dev->protocol_id = protocol;
 145         scmi_dev->dev.parent = parent;
 146         scmi_dev->dev.of_node = np;
 147         scmi_dev->dev.bus = &scmi_bus_type;
 148         scmi_dev->dev.release = scmi_device_release;
 149         dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
 150 
 151         retval = device_register(&scmi_dev->dev);
 152         if (retval)
 153                 goto put_dev;
 154 
 155         return scmi_dev;
 156 put_dev:
 157         put_device(&scmi_dev->dev);
 158         ida_simple_remove(&scmi_bus_id, id);
 159         return NULL;
 160 }
 161 
 162 void scmi_device_destroy(struct scmi_device *scmi_dev)
 163 {
 164         scmi_handle_put(scmi_dev->handle);
 165         ida_simple_remove(&scmi_bus_id, scmi_dev->id);
 166         device_unregister(&scmi_dev->dev);
 167 }
 168 
 169 void scmi_set_handle(struct scmi_device *scmi_dev)
 170 {
 171         scmi_dev->handle = scmi_handle_get(&scmi_dev->dev);
 172 }
 173 
 174 int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn)
 175 {
 176         int ret;
 177 
 178         spin_lock(&protocol_lock);
 179         ret = idr_alloc(&scmi_protocols, fn, protocol_id, protocol_id + 1,
 180                         GFP_ATOMIC);
 181         spin_unlock(&protocol_lock);
 182         if (ret != protocol_id)
 183                 pr_err("unable to allocate SCMI idr slot, err %d\n", ret);
 184 
 185         return ret;
 186 }
 187 EXPORT_SYMBOL_GPL(scmi_protocol_register);
 188 
 189 void scmi_protocol_unregister(int protocol_id)
 190 {
 191         spin_lock(&protocol_lock);
 192         idr_remove(&scmi_protocols, protocol_id);
 193         spin_unlock(&protocol_lock);
 194 }
 195 EXPORT_SYMBOL_GPL(scmi_protocol_unregister);
 196 
 197 static int __scmi_devices_unregister(struct device *dev, void *data)
 198 {
 199         struct scmi_device *scmi_dev = to_scmi_dev(dev);
 200 
 201         scmi_device_destroy(scmi_dev);
 202         return 0;
 203 }
 204 
 205 static void scmi_devices_unregister(void)
 206 {
 207         bus_for_each_dev(&scmi_bus_type, NULL, NULL, __scmi_devices_unregister);
 208 }
 209 
 210 static int __init scmi_bus_init(void)
 211 {
 212         int retval;
 213 
 214         retval = bus_register(&scmi_bus_type);
 215         if (retval)
 216                 pr_err("scmi protocol bus register failed (%d)\n", retval);
 217 
 218         return retval;
 219 }
 220 subsys_initcall(scmi_bus_init);
 221 
 222 static void __exit scmi_bus_exit(void)
 223 {
 224         scmi_devices_unregister();
 225         bus_unregister(&scmi_bus_type);
 226         ida_destroy(&scmi_bus_id);
 227 }
 228 module_exit(scmi_bus_exit);

/* [<][>][^][v][top][bottom][index][help] */