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 static int ffa_device_match(struct device *dev, struct device_driver *drv)
20 const struct ffa_device_id *id_table;
21 struct ffa_device *ffa_dev;
23 id_table = to_ffa_driver(drv)->id_table;
24 ffa_dev = to_ffa_dev(dev);
26 while (!uuid_is_null(&id_table->uuid)) {
28 * FF-A v1.0 doesn't provide discovery of UUIDs, just the
29 * partition IDs, so fetch the partitions IDs for this
30 * id_table UUID and assign the UUID to the device if the
31 * partition ID matches
33 if (uuid_is_null(&ffa_dev->uuid))
34 ffa_device_match_uuid(ffa_dev, &id_table->uuid);
36 if (uuid_equal(&ffa_dev->uuid, &id_table->uuid))
44 static int ffa_device_probe(struct device *dev)
46 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
47 struct ffa_device *ffa_dev = to_ffa_dev(dev);
49 if (!ffa_device_match(dev, dev->driver))
52 return ffa_drv->probe(ffa_dev);
55 static int ffa_device_uevent(struct device *dev, struct kobj_uevent_env *env)
57 struct ffa_device *ffa_dev = to_ffa_dev(dev);
59 return add_uevent_var(env, "MODALIAS=arm_ffa:%04x:%pUb",
60 ffa_dev->vm_id, &ffa_dev->uuid);
63 static ssize_t partition_id_show(struct device *dev,
64 struct device_attribute *attr, char *buf)
66 struct ffa_device *ffa_dev = to_ffa_dev(dev);
68 return sprintf(buf, "0x%04x\n", ffa_dev->vm_id);
70 static DEVICE_ATTR_RO(partition_id);
72 static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
75 struct ffa_device *ffa_dev = to_ffa_dev(dev);
77 return sprintf(buf, "%pUb\n", &ffa_dev->uuid);
79 static DEVICE_ATTR_RO(uuid);
81 static struct attribute *ffa_device_attributes_attrs[] = {
82 &dev_attr_partition_id.attr,
86 ATTRIBUTE_GROUPS(ffa_device_attributes);
88 struct bus_type ffa_bus_type = {
90 .match = ffa_device_match,
91 .probe = ffa_device_probe,
92 .uevent = ffa_device_uevent,
93 .dev_groups = ffa_device_attributes_groups,
95 EXPORT_SYMBOL_GPL(ffa_bus_type);
97 int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
102 driver->driver.bus = &ffa_bus_type;
103 driver->driver.name = driver->name;
104 driver->driver.owner = owner;
105 driver->driver.mod_name = mod_name;
107 ret = driver_register(&driver->driver);
109 pr_debug("registered new ffa driver %s\n", driver->name);
113 EXPORT_SYMBOL_GPL(ffa_driver_register);
115 void ffa_driver_unregister(struct ffa_driver *driver)
117 driver_unregister(&driver->driver);
119 EXPORT_SYMBOL_GPL(ffa_driver_unregister);
121 static void ffa_release_device(struct device *dev)
123 struct ffa_device *ffa_dev = to_ffa_dev(dev);
128 static int __ffa_devices_unregister(struct device *dev, void *data)
130 ffa_release_device(dev);
135 static void ffa_devices_unregister(void)
137 bus_for_each_dev(&ffa_bus_type, NULL, NULL,
138 __ffa_devices_unregister);
141 bool ffa_device_is_valid(struct ffa_device *ffa_dev)
144 struct device *dev = NULL;
145 struct ffa_device *tmp_dev;
148 dev = bus_find_next_device(&ffa_bus_type, dev);
149 tmp_dev = to_ffa_dev(dev);
150 if (tmp_dev == ffa_dev) {
162 struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id)
166 struct ffa_device *ffa_dev;
168 ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL);
173 dev->bus = &ffa_bus_type;
174 dev->release = ffa_release_device;
175 dev_set_name(&ffa_dev->dev, "arm-ffa-%04x", vm_id);
177 ffa_dev->vm_id = vm_id;
178 uuid_copy(&ffa_dev->uuid, uuid);
180 ret = device_register(&ffa_dev->dev);
182 dev_err(dev, "unable to register device %s err=%d\n",
190 EXPORT_SYMBOL_GPL(ffa_device_register);
192 void ffa_device_unregister(struct ffa_device *ffa_dev)
197 device_unregister(&ffa_dev->dev);
199 EXPORT_SYMBOL_GPL(ffa_device_unregister);
201 int arm_ffa_bus_init(void)
203 return bus_register(&ffa_bus_type);
206 void arm_ffa_bus_exit(void)
208 ffa_devices_unregister();
209 bus_unregister(&ffa_bus_type);