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