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 #define SCMI_UEVENT_MODALIAS_FMT "arm_ffa:%04x:%pUb" 19 20 static DEFINE_IDA(ffa_bus_id); 21 22 static int ffa_device_match(struct device *dev, struct device_driver *drv) 23 { 24 const struct ffa_device_id *id_table; 25 struct ffa_device *ffa_dev; 26 27 id_table = to_ffa_driver(drv)->id_table; 28 ffa_dev = to_ffa_dev(dev); 29 30 while (!uuid_is_null(&id_table->uuid)) { 31 /* 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 36 */ 37 if (uuid_is_null(&ffa_dev->uuid)) 38 ffa_device_match_uuid(ffa_dev, &id_table->uuid); 39 40 if (uuid_equal(&ffa_dev->uuid, &id_table->uuid)) 41 return 1; 42 id_table++; 43 } 44 45 return 0; 46 } 47 48 static int ffa_device_probe(struct device *dev) 49 { 50 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver); 51 struct ffa_device *ffa_dev = to_ffa_dev(dev); 52 53 return ffa_drv->probe(ffa_dev); 54 } 55 56 static void ffa_device_remove(struct device *dev) 57 { 58 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver); 59 60 if (ffa_drv->remove) 61 ffa_drv->remove(to_ffa_dev(dev)); 62 } 63 64 static int ffa_device_uevent(const struct device *dev, struct kobj_uevent_env *env) 65 { 66 const struct ffa_device *ffa_dev = to_ffa_dev(dev); 67 68 return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT, 69 ffa_dev->vm_id, &ffa_dev->uuid); 70 } 71 72 static ssize_t modalias_show(struct device *dev, 73 struct device_attribute *attr, char *buf) 74 { 75 struct ffa_device *ffa_dev = to_ffa_dev(dev); 76 77 return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT, ffa_dev->vm_id, 78 &ffa_dev->uuid); 79 } 80 static DEVICE_ATTR_RO(modalias); 81 82 static ssize_t partition_id_show(struct device *dev, 83 struct device_attribute *attr, char *buf) 84 { 85 struct ffa_device *ffa_dev = to_ffa_dev(dev); 86 87 return sprintf(buf, "0x%04x\n", ffa_dev->vm_id); 88 } 89 static DEVICE_ATTR_RO(partition_id); 90 91 static ssize_t uuid_show(struct device *dev, struct device_attribute *attr, 92 char *buf) 93 { 94 struct ffa_device *ffa_dev = to_ffa_dev(dev); 95 96 return sprintf(buf, "%pUb\n", &ffa_dev->uuid); 97 } 98 static DEVICE_ATTR_RO(uuid); 99 100 static struct attribute *ffa_device_attributes_attrs[] = { 101 &dev_attr_partition_id.attr, 102 &dev_attr_uuid.attr, 103 &dev_attr_modalias.attr, 104 NULL, 105 }; 106 ATTRIBUTE_GROUPS(ffa_device_attributes); 107 108 const struct bus_type ffa_bus_type = { 109 .name = "arm_ffa", 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, 115 }; 116 EXPORT_SYMBOL_GPL(ffa_bus_type); 117 118 int ffa_driver_register(struct ffa_driver *driver, struct module *owner, 119 const char *mod_name) 120 { 121 int ret; 122 123 if (!driver->probe) 124 return -EINVAL; 125 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; 130 131 ret = driver_register(&driver->driver); 132 if (!ret) 133 pr_debug("registered new ffa driver %s\n", driver->name); 134 135 return ret; 136 } 137 EXPORT_SYMBOL_GPL(ffa_driver_register); 138 139 void ffa_driver_unregister(struct ffa_driver *driver) 140 { 141 driver_unregister(&driver->driver); 142 } 143 EXPORT_SYMBOL_GPL(ffa_driver_unregister); 144 145 static void ffa_release_device(struct device *dev) 146 { 147 struct ffa_device *ffa_dev = to_ffa_dev(dev); 148 149 ida_free(&ffa_bus_id, ffa_dev->id); 150 kfree(ffa_dev); 151 } 152 153 static int __ffa_devices_unregister(struct device *dev, void *data) 154 { 155 device_unregister(dev); 156 157 return 0; 158 } 159 160 static void ffa_devices_unregister(void) 161 { 162 bus_for_each_dev(&ffa_bus_type, NULL, NULL, 163 __ffa_devices_unregister); 164 } 165 166 bool ffa_device_is_valid(struct ffa_device *ffa_dev) 167 { 168 bool valid = false; 169 struct device *dev = NULL; 170 struct ffa_device *tmp_dev; 171 172 do { 173 dev = bus_find_next_device(&ffa_bus_type, dev); 174 tmp_dev = to_ffa_dev(dev); 175 if (tmp_dev == ffa_dev) { 176 valid = true; 177 break; 178 } 179 put_device(dev); 180 } while (dev); 181 182 put_device(dev); 183 184 return valid; 185 } 186 187 struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, 188 const struct ffa_ops *ops) 189 { 190 int id, ret; 191 struct device *dev; 192 struct ffa_device *ffa_dev; 193 194 id = ida_alloc_min(&ffa_bus_id, 1, GFP_KERNEL); 195 if (id < 0) 196 return NULL; 197 198 ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL); 199 if (!ffa_dev) { 200 ida_free(&ffa_bus_id, id); 201 return NULL; 202 } 203 204 dev = &ffa_dev->dev; 205 dev->bus = &ffa_bus_type; 206 dev->release = ffa_release_device; 207 dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id); 208 209 ffa_dev->id = id; 210 ffa_dev->vm_id = vm_id; 211 ffa_dev->ops = ops; 212 uuid_copy(&ffa_dev->uuid, uuid); 213 214 ret = device_register(&ffa_dev->dev); 215 if (ret) { 216 dev_err(dev, "unable to register device %s err=%d\n", 217 dev_name(dev), ret); 218 put_device(dev); 219 return NULL; 220 } 221 222 return ffa_dev; 223 } 224 EXPORT_SYMBOL_GPL(ffa_device_register); 225 226 void ffa_device_unregister(struct ffa_device *ffa_dev) 227 { 228 if (!ffa_dev) 229 return; 230 231 device_unregister(&ffa_dev->dev); 232 } 233 EXPORT_SYMBOL_GPL(ffa_device_unregister); 234 235 int arm_ffa_bus_init(void) 236 { 237 return bus_register(&ffa_bus_type); 238 } 239 240 void arm_ffa_bus_exit(void) 241 { 242 ffa_devices_unregister(); 243 bus_unregister(&ffa_bus_type); 244 ida_destroy(&ffa_bus_id); 245 } 246