1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2021 ARM Ltd. 4 */ 5 6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 8 #include <linux/arm_ffa.h> 9 #include <linux/device.h> 10 #include <linux/fs.h> 11 #include <linux/kernel.h> 12 #include <linux/module.h> 13 #include <linux/slab.h> 14 #include <linux/types.h> 15 16 #include "common.h" 17 18 static DEFINE_IDA(ffa_bus_id); 19 20 static int ffa_device_match(struct device *dev, struct device_driver *drv) 21 { 22 const struct ffa_device_id *id_table; 23 struct ffa_device *ffa_dev; 24 25 id_table = to_ffa_driver(drv)->id_table; 26 ffa_dev = to_ffa_dev(dev); 27 28 while (!uuid_is_null(&id_table->uuid)) { 29 /* 30 * FF-A v1.0 doesn't provide discovery of UUIDs, just the 31 * partition IDs, so fetch the partitions IDs for this 32 * id_table UUID and assign the UUID to the device if the 33 * partition ID matches 34 */ 35 if (uuid_is_null(&ffa_dev->uuid)) 36 ffa_device_match_uuid(ffa_dev, &id_table->uuid); 37 38 if (uuid_equal(&ffa_dev->uuid, &id_table->uuid)) 39 return 1; 40 id_table++; 41 } 42 43 return 0; 44 } 45 46 static int ffa_device_probe(struct device *dev) 47 { 48 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver); 49 struct ffa_device *ffa_dev = to_ffa_dev(dev); 50 51 return ffa_drv->probe(ffa_dev); 52 } 53 54 static void ffa_device_remove(struct device *dev) 55 { 56 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver); 57 58 if (ffa_drv->remove) 59 ffa_drv->remove(to_ffa_dev(dev)); 60 } 61 62 static int ffa_device_uevent(const struct device *dev, struct kobj_uevent_env *env) 63 { 64 const struct ffa_device *ffa_dev = to_ffa_dev(dev); 65 66 return add_uevent_var(env, "MODALIAS=arm_ffa:%04x:%pUb", 67 ffa_dev->vm_id, &ffa_dev->uuid); 68 } 69 70 static ssize_t partition_id_show(struct device *dev, 71 struct device_attribute *attr, char *buf) 72 { 73 struct ffa_device *ffa_dev = to_ffa_dev(dev); 74 75 return sprintf(buf, "0x%04x\n", ffa_dev->vm_id); 76 } 77 static DEVICE_ATTR_RO(partition_id); 78 79 static ssize_t uuid_show(struct device *dev, struct device_attribute *attr, 80 char *buf) 81 { 82 struct ffa_device *ffa_dev = to_ffa_dev(dev); 83 84 return sprintf(buf, "%pUb\n", &ffa_dev->uuid); 85 } 86 static DEVICE_ATTR_RO(uuid); 87 88 static struct attribute *ffa_device_attributes_attrs[] = { 89 &dev_attr_partition_id.attr, 90 &dev_attr_uuid.attr, 91 NULL, 92 }; 93 ATTRIBUTE_GROUPS(ffa_device_attributes); 94 95 struct bus_type ffa_bus_type = { 96 .name = "arm_ffa", 97 .match = ffa_device_match, 98 .probe = ffa_device_probe, 99 .remove = ffa_device_remove, 100 .uevent = ffa_device_uevent, 101 .dev_groups = ffa_device_attributes_groups, 102 }; 103 EXPORT_SYMBOL_GPL(ffa_bus_type); 104 105 int ffa_driver_register(struct ffa_driver *driver, struct module *owner, 106 const char *mod_name) 107 { 108 int ret; 109 110 if (!driver->probe) 111 return -EINVAL; 112 113 driver->driver.bus = &ffa_bus_type; 114 driver->driver.name = driver->name; 115 driver->driver.owner = owner; 116 driver->driver.mod_name = mod_name; 117 118 ret = driver_register(&driver->driver); 119 if (!ret) 120 pr_debug("registered new ffa driver %s\n", driver->name); 121 122 return ret; 123 } 124 EXPORT_SYMBOL_GPL(ffa_driver_register); 125 126 void ffa_driver_unregister(struct ffa_driver *driver) 127 { 128 driver_unregister(&driver->driver); 129 } 130 EXPORT_SYMBOL_GPL(ffa_driver_unregister); 131 132 static void ffa_release_device(struct device *dev) 133 { 134 struct ffa_device *ffa_dev = to_ffa_dev(dev); 135 136 ida_free(&ffa_bus_id, ffa_dev->id); 137 kfree(ffa_dev); 138 } 139 140 static int __ffa_devices_unregister(struct device *dev, void *data) 141 { 142 device_unregister(dev); 143 144 return 0; 145 } 146 147 static void ffa_devices_unregister(void) 148 { 149 bus_for_each_dev(&ffa_bus_type, NULL, NULL, 150 __ffa_devices_unregister); 151 } 152 153 bool ffa_device_is_valid(struct ffa_device *ffa_dev) 154 { 155 bool valid = false; 156 struct device *dev = NULL; 157 struct ffa_device *tmp_dev; 158 159 do { 160 dev = bus_find_next_device(&ffa_bus_type, dev); 161 tmp_dev = to_ffa_dev(dev); 162 if (tmp_dev == ffa_dev) { 163 valid = true; 164 break; 165 } 166 put_device(dev); 167 } while (dev); 168 169 put_device(dev); 170 171 return valid; 172 } 173 174 struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, 175 const struct ffa_ops *ops) 176 { 177 int id, ret; 178 struct device *dev; 179 struct ffa_device *ffa_dev; 180 181 id = ida_alloc_min(&ffa_bus_id, 1, GFP_KERNEL); 182 if (id < 0) 183 return NULL; 184 185 ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL); 186 if (!ffa_dev) { 187 ida_free(&ffa_bus_id, id); 188 return NULL; 189 } 190 191 dev = &ffa_dev->dev; 192 dev->bus = &ffa_bus_type; 193 dev->release = ffa_release_device; 194 dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id); 195 196 ffa_dev->vm_id = vm_id; 197 ffa_dev->ops = ops; 198 uuid_copy(&ffa_dev->uuid, uuid); 199 200 ret = device_register(&ffa_dev->dev); 201 if (ret) { 202 dev_err(dev, "unable to register device %s err=%d\n", 203 dev_name(dev), ret); 204 put_device(dev); 205 return NULL; 206 } 207 208 return ffa_dev; 209 } 210 EXPORT_SYMBOL_GPL(ffa_device_register); 211 212 void ffa_device_unregister(struct ffa_device *ffa_dev) 213 { 214 if (!ffa_dev) 215 return; 216 217 device_unregister(&ffa_dev->dev); 218 } 219 EXPORT_SYMBOL_GPL(ffa_device_unregister); 220 221 int arm_ffa_bus_init(void) 222 { 223 return bus_register(&ffa_bus_type); 224 } 225 226 void arm_ffa_bus_exit(void) 227 { 228 ffa_devices_unregister(); 229 bus_unregister(&ffa_bus_type); 230 ida_destroy(&ffa_bus_id); 231 } 232