0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007
0008 #include <linux/arm_ffa.h>
0009 #include <linux/device.h>
0010 #include <linux/fs.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/types.h>
0015
0016 #include "common.h"
0017
0018 static int ffa_device_match(struct device *dev, struct device_driver *drv)
0019 {
0020 const struct ffa_device_id *id_table;
0021 struct ffa_device *ffa_dev;
0022
0023 id_table = to_ffa_driver(drv)->id_table;
0024 ffa_dev = to_ffa_dev(dev);
0025
0026 while (!uuid_is_null(&id_table->uuid)) {
0027
0028
0029
0030
0031
0032
0033 if (uuid_is_null(&ffa_dev->uuid))
0034 ffa_device_match_uuid(ffa_dev, &id_table->uuid);
0035
0036 if (uuid_equal(&ffa_dev->uuid, &id_table->uuid))
0037 return 1;
0038 id_table++;
0039 }
0040
0041 return 0;
0042 }
0043
0044 static int ffa_device_probe(struct device *dev)
0045 {
0046 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
0047 struct ffa_device *ffa_dev = to_ffa_dev(dev);
0048
0049 return ffa_drv->probe(ffa_dev);
0050 }
0051
0052 static void ffa_device_remove(struct device *dev)
0053 {
0054 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
0055
0056 ffa_drv->remove(to_ffa_dev(dev));
0057 }
0058
0059 static int ffa_device_uevent(struct device *dev, struct kobj_uevent_env *env)
0060 {
0061 struct ffa_device *ffa_dev = to_ffa_dev(dev);
0062
0063 return add_uevent_var(env, "MODALIAS=arm_ffa:%04x:%pUb",
0064 ffa_dev->vm_id, &ffa_dev->uuid);
0065 }
0066
0067 static ssize_t partition_id_show(struct device *dev,
0068 struct device_attribute *attr, char *buf)
0069 {
0070 struct ffa_device *ffa_dev = to_ffa_dev(dev);
0071
0072 return sprintf(buf, "0x%04x\n", ffa_dev->vm_id);
0073 }
0074 static DEVICE_ATTR_RO(partition_id);
0075
0076 static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
0077 char *buf)
0078 {
0079 struct ffa_device *ffa_dev = to_ffa_dev(dev);
0080
0081 return sprintf(buf, "%pUb\n", &ffa_dev->uuid);
0082 }
0083 static DEVICE_ATTR_RO(uuid);
0084
0085 static struct attribute *ffa_device_attributes_attrs[] = {
0086 &dev_attr_partition_id.attr,
0087 &dev_attr_uuid.attr,
0088 NULL,
0089 };
0090 ATTRIBUTE_GROUPS(ffa_device_attributes);
0091
0092 struct bus_type ffa_bus_type = {
0093 .name = "arm_ffa",
0094 .match = ffa_device_match,
0095 .probe = ffa_device_probe,
0096 .remove = ffa_device_remove,
0097 .uevent = ffa_device_uevent,
0098 .dev_groups = ffa_device_attributes_groups,
0099 };
0100 EXPORT_SYMBOL_GPL(ffa_bus_type);
0101
0102 int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
0103 const char *mod_name)
0104 {
0105 int ret;
0106
0107 if (!driver->probe)
0108 return -EINVAL;
0109
0110 driver->driver.bus = &ffa_bus_type;
0111 driver->driver.name = driver->name;
0112 driver->driver.owner = owner;
0113 driver->driver.mod_name = mod_name;
0114
0115 ret = driver_register(&driver->driver);
0116 if (!ret)
0117 pr_debug("registered new ffa driver %s\n", driver->name);
0118
0119 return ret;
0120 }
0121 EXPORT_SYMBOL_GPL(ffa_driver_register);
0122
0123 void ffa_driver_unregister(struct ffa_driver *driver)
0124 {
0125 driver_unregister(&driver->driver);
0126 }
0127 EXPORT_SYMBOL_GPL(ffa_driver_unregister);
0128
0129 static void ffa_release_device(struct device *dev)
0130 {
0131 struct ffa_device *ffa_dev = to_ffa_dev(dev);
0132
0133 kfree(ffa_dev);
0134 }
0135
0136 static int __ffa_devices_unregister(struct device *dev, void *data)
0137 {
0138 device_unregister(dev);
0139
0140 return 0;
0141 }
0142
0143 static void ffa_devices_unregister(void)
0144 {
0145 bus_for_each_dev(&ffa_bus_type, NULL, NULL,
0146 __ffa_devices_unregister);
0147 }
0148
0149 bool ffa_device_is_valid(struct ffa_device *ffa_dev)
0150 {
0151 bool valid = false;
0152 struct device *dev = NULL;
0153 struct ffa_device *tmp_dev;
0154
0155 do {
0156 dev = bus_find_next_device(&ffa_bus_type, dev);
0157 tmp_dev = to_ffa_dev(dev);
0158 if (tmp_dev == ffa_dev) {
0159 valid = true;
0160 break;
0161 }
0162 put_device(dev);
0163 } while (dev);
0164
0165 put_device(dev);
0166
0167 return valid;
0168 }
0169
0170 struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id)
0171 {
0172 int ret;
0173 struct device *dev;
0174 struct ffa_device *ffa_dev;
0175
0176 ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL);
0177 if (!ffa_dev)
0178 return NULL;
0179
0180 dev = &ffa_dev->dev;
0181 dev->bus = &ffa_bus_type;
0182 dev->release = ffa_release_device;
0183 dev_set_name(&ffa_dev->dev, "arm-ffa-%04x", vm_id);
0184
0185 ffa_dev->vm_id = vm_id;
0186 uuid_copy(&ffa_dev->uuid, uuid);
0187
0188 ret = device_register(&ffa_dev->dev);
0189 if (ret) {
0190 dev_err(dev, "unable to register device %s err=%d\n",
0191 dev_name(dev), ret);
0192 put_device(dev);
0193 return NULL;
0194 }
0195
0196 return ffa_dev;
0197 }
0198 EXPORT_SYMBOL_GPL(ffa_device_register);
0199
0200 void ffa_device_unregister(struct ffa_device *ffa_dev)
0201 {
0202 if (!ffa_dev)
0203 return;
0204
0205 device_unregister(&ffa_dev->dev);
0206 }
0207 EXPORT_SYMBOL_GPL(ffa_device_unregister);
0208
0209 int arm_ffa_bus_init(void)
0210 {
0211 return bus_register(&ffa_bus_type);
0212 }
0213
0214 void arm_ffa_bus_exit(void)
0215 {
0216 ffa_devices_unregister();
0217 bus_unregister(&ffa_bus_type);
0218 }