xref: /linux/drivers/firmware/arm_ffa/bus.c (revision 3bbfe9871005f38df2955b2e125933edf1d2feef)
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