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