1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2021 ARM Ltd.
6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8 #include <linux/arm_ffa.h>
9 #include <linux/device.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/types.h>
18 #define SCMI_UEVENT_MODALIAS_FMT "arm_ffa:%04x:%pUb"
20 static DEFINE_IDA(ffa_bus_id);
22 static int ffa_device_match(struct device *dev, struct device_driver *drv)
24 const struct ffa_device_id *id_table;
25 struct ffa_device *ffa_dev;
27 id_table = to_ffa_driver(drv)->id_table;
28 ffa_dev = to_ffa_dev(dev);
30 while (!uuid_is_null(&id_table->uuid)) {
32 * FF-A v1.0 doesn't provide discovery of UUIDs, just the
33 * partition IDs, so fetch the partitions IDs for this
34 * id_table UUID and assign the UUID to the device if the
35 * partition ID matches
37 if (uuid_is_null(&ffa_dev->uuid))
38 ffa_device_match_uuid(ffa_dev, &id_table->uuid);
40 if (uuid_equal(&ffa_dev->uuid, &id_table->uuid))
48 static int ffa_device_probe(struct device *dev)
50 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
51 struct ffa_device *ffa_dev = to_ffa_dev(dev);
53 return ffa_drv->probe(ffa_dev);
56 static void ffa_device_remove(struct device *dev)
58 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
61 ffa_drv->remove(to_ffa_dev(dev));
64 static int ffa_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
66 const struct ffa_device *ffa_dev = to_ffa_dev(dev);
68 return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT,
69 ffa_dev->vm_id, &ffa_dev->uuid);
72 static ssize_t modalias_show(struct device *dev,
73 struct device_attribute *attr, char *buf)
75 struct ffa_device *ffa_dev = to_ffa_dev(dev);
77 return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT, ffa_dev->vm_id,
80 static DEVICE_ATTR_RO(modalias);
82 static ssize_t partition_id_show(struct device *dev,
83 struct device_attribute *attr, char *buf)
85 struct ffa_device *ffa_dev = to_ffa_dev(dev);
87 return sprintf(buf, "0x%04x\n", ffa_dev->vm_id);
89 static DEVICE_ATTR_RO(partition_id);
91 static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
94 struct ffa_device *ffa_dev = to_ffa_dev(dev);
96 return sprintf(buf, "%pUb\n", &ffa_dev->uuid);
98 static DEVICE_ATTR_RO(uuid);
100 static struct attribute *ffa_device_attributes_attrs[] = {
101 &dev_attr_partition_id.attr,
103 &dev_attr_modalias.attr,
106 ATTRIBUTE_GROUPS(ffa_device_attributes);
108 struct bus_type ffa_bus_type = {
110 .match = ffa_device_match,
111 .probe = ffa_device_probe,
112 .remove = ffa_device_remove,
113 .uevent = ffa_device_uevent,
114 .dev_groups = ffa_device_attributes_groups,
116 EXPORT_SYMBOL_GPL(ffa_bus_type);
118 int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
119 const char *mod_name)
126 driver->driver.bus = &ffa_bus_type;
127 driver->driver.name = driver->name;
128 driver->driver.owner = owner;
129 driver->driver.mod_name = mod_name;
131 ret = driver_register(&driver->driver);
133 pr_debug("registered new ffa driver %s\n", driver->name);
137 EXPORT_SYMBOL_GPL(ffa_driver_register);
139 void ffa_driver_unregister(struct ffa_driver *driver)
141 driver_unregister(&driver->driver);
143 EXPORT_SYMBOL_GPL(ffa_driver_unregister);
145 static void ffa_release_device(struct device *dev)
147 struct ffa_device *ffa_dev = to_ffa_dev(dev);
149 ida_free(&ffa_bus_id, ffa_dev->id);
153 static int __ffa_devices_unregister(struct device *dev, void *data)
155 device_unregister(dev);
160 static void ffa_devices_unregister(void)
162 bus_for_each_dev(&ffa_bus_type, NULL, NULL,
163 __ffa_devices_unregister);
166 bool ffa_device_is_valid(struct ffa_device *ffa_dev)
169 struct device *dev = NULL;
170 struct ffa_device *tmp_dev;
173 dev = bus_find_next_device(&ffa_bus_type, dev);
174 tmp_dev = to_ffa_dev(dev);
175 if (tmp_dev == ffa_dev) {
187 struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
188 const struct ffa_ops *ops)
192 struct ffa_device *ffa_dev;
194 id = ida_alloc_min(&ffa_bus_id, 1, GFP_KERNEL);
198 ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL);
200 ida_free(&ffa_bus_id, id);
205 dev->bus = &ffa_bus_type;
206 dev->release = ffa_release_device;
207 dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id);
210 ffa_dev->vm_id = vm_id;
212 uuid_copy(&ffa_dev->uuid, uuid);
214 ret = device_register(&ffa_dev->dev);
216 dev_err(dev, "unable to register device %s err=%d\n",
224 EXPORT_SYMBOL_GPL(ffa_device_register);
226 void ffa_device_unregister(struct ffa_device *ffa_dev)
231 device_unregister(&ffa_dev->dev);
233 EXPORT_SYMBOL_GPL(ffa_device_unregister);
235 int arm_ffa_bus_init(void)
237 return bus_register(&ffa_bus_type);
240 void arm_ffa_bus_exit(void)
242 ffa_devices_unregister();
243 bus_unregister(&ffa_bus_type);
244 ida_destroy(&ffa_bus_id);