Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'ffa-updates-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into soc/drivers

Arm FF-A driver updates for v6.11

The main addition is the split of bus and driver into distinct modules
The FF-A bus module is initialized at subsys_initcall level when builtin.

FF-A drivers initialization is now changed to module_init level so that
pKVM ffa proxy is all setup and running in case pKVM hypervisor needs to
trap and handle FF-A calls.

One of the reason for not having this split from the beginning is the
need to workaround the FF-A v1.0 NULL UUID. The FF-A bus layer called
into FF-A driver and populated the device UUID if it matches with the
driver attempting to match. Moving the workaround away from the FF-A
bus layer to the FF-A core driver as a bus notifier will help to remove
the dependency.

* tag 'ffa-updates-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
firmware: arm_ffa: Split bus and driver into distinct modules
firmware: arm_ffa: Move the FF-A v1.0 NULL UUID workaround to bus notifier

Link: https://lore.kernel.org/r/20240624103451.2870146-1-sudeep.holla@arm.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+58 -29
+4 -2
drivers/firmware/arm_ffa/Makefile
··· 2 2 ffa-bus-y = bus.o 3 3 ffa-driver-y = driver.o 4 4 ffa-transport-$(CONFIG_ARM_FFA_SMCCC) += smccc.o 5 - ffa-module-objs := $(ffa-bus-y) $(ffa-driver-y) $(ffa-transport-y) 6 - obj-$(CONFIG_ARM_FFA_TRANSPORT) = ffa-module.o 5 + ffa-core-objs := $(ffa-bus-y) 6 + ffa-module-objs := $(ffa-driver-y) $(ffa-transport-y) 7 + obj-$(CONFIG_ARM_FFA_TRANSPORT) = ffa-core.o 8 + obj-$(CONFIG_ARM_FFA_TRANSPORT) += ffa-module.o
+16 -6
drivers/firmware/arm_ffa/bus.c
··· 30 30 while (!uuid_is_null(&id_table->uuid)) { 31 31 /* 32 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 33 + * partition IDs, so match it unconditionally here and handle 34 + * it via the installed bus notifier during driver binding. 36 35 */ 37 36 if (uuid_is_null(&ffa_dev->uuid)) 38 - ffa_device_match_uuid(ffa_dev, &id_table->uuid); 37 + return 1; 39 38 40 39 if (uuid_equal(&ffa_dev->uuid, &id_table->uuid)) 41 40 return 1; ··· 48 49 { 49 50 struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver); 50 51 struct ffa_device *ffa_dev = to_ffa_dev(dev); 52 + 53 + /* UUID can be still NULL with FF-A v1.0, so just skip probing them */ 54 + if (uuid_is_null(&ffa_dev->uuid)) 55 + return -ENODEV; 51 56 52 57 return ffa_drv->probe(ffa_dev); 53 58 } ··· 235 232 } 236 233 EXPORT_SYMBOL_GPL(ffa_device_unregister); 237 234 238 - int arm_ffa_bus_init(void) 235 + static int __init arm_ffa_bus_init(void) 239 236 { 240 237 return bus_register(&ffa_bus_type); 241 238 } 239 + subsys_initcall(arm_ffa_bus_init); 242 240 243 - void arm_ffa_bus_exit(void) 241 + static void __exit arm_ffa_bus_exit(void) 244 242 { 245 243 ffa_devices_unregister(); 246 244 bus_unregister(&ffa_bus_type); 247 245 ida_destroy(&ffa_bus_id); 248 246 } 247 + module_exit(arm_ffa_bus_exit); 248 + 249 + MODULE_ALIAS("ffa-core"); 250 + MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>"); 251 + MODULE_DESCRIPTION("ARM FF-A bus"); 252 + MODULE_LICENSE("GPL");
-2
drivers/firmware/arm_ffa/common.h
··· 14 14 15 15 typedef void (ffa_fn)(ffa_value_t, ffa_value_t *); 16 16 17 - int arm_ffa_bus_init(void); 18 - void arm_ffa_bus_exit(void); 19 17 bool ffa_device_is_valid(struct ffa_device *ffa_dev); 20 18 void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid); 21 19
+38 -19
drivers/firmware/arm_ffa/driver.c
··· 1224 1224 int count, idx; 1225 1225 struct ffa_partition_info *pbuf, *tpbuf; 1226 1226 1227 - /* 1228 - * FF-A v1.1 provides UUID for each partition as part of the discovery 1229 - * API, the discovered UUID must be populated in the device's UUID and 1230 - * there is no need to copy the same from the driver table. 1231 - */ 1232 - if (drv_info->version > FFA_VERSION_1_0) 1233 - return; 1234 - 1235 1227 count = ffa_partition_probe(uuid, &pbuf); 1236 1228 if (count <= 0) 1237 1229 return; ··· 1234 1242 kfree(pbuf); 1235 1243 } 1236 1244 1245 + static int 1246 + ffa_bus_notifier(struct notifier_block *nb, unsigned long action, void *data) 1247 + { 1248 + struct device *dev = data; 1249 + struct ffa_device *fdev = to_ffa_dev(dev); 1250 + 1251 + if (action == BUS_NOTIFY_BIND_DRIVER) { 1252 + struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver); 1253 + const struct ffa_device_id *id_table= ffa_drv->id_table; 1254 + 1255 + /* 1256 + * FF-A v1.1 provides UUID for each partition as part of the 1257 + * discovery API, the discovered UUID must be populated in the 1258 + * device's UUID and there is no need to workaround by copying 1259 + * the same from the driver table. 1260 + */ 1261 + if (uuid_is_null(&fdev->uuid)) 1262 + ffa_device_match_uuid(fdev, &id_table->uuid); 1263 + 1264 + return NOTIFY_OK; 1265 + } 1266 + 1267 + return NOTIFY_DONE; 1268 + } 1269 + 1270 + static struct notifier_block ffa_bus_nb = { 1271 + .notifier_call = ffa_bus_notifier, 1272 + }; 1273 + 1237 1274 static int ffa_setup_partitions(void) 1238 1275 { 1239 1276 int count, idx, ret; ··· 1270 1249 struct ffa_device *ffa_dev; 1271 1250 struct ffa_dev_part_info *info; 1272 1251 struct ffa_partition_info *pbuf, *tpbuf; 1252 + 1253 + if (drv_info->version == FFA_VERSION_1_0) { 1254 + ret = bus_register_notifier(&ffa_bus_type, &ffa_bus_nb); 1255 + if (ret) 1256 + pr_err("Failed to register FF-A bus notifiers\n"); 1257 + } 1273 1258 1274 1259 count = ffa_partition_probe(&uuid_null, &pbuf); 1275 1260 if (count <= 0) { ··· 1288 1261 import_uuid(&uuid, (u8 *)tpbuf->uuid); 1289 1262 1290 1263 /* Note that if the UUID will be uuid_null, that will require 1291 - * ffa_device_match() to find the UUID of this partition id 1264 + * ffa_bus_notifier() to find the UUID of this partition id 1292 1265 * with help of ffa_device_match_uuid(). FF-A v1.1 and above 1293 1266 * provides UUID here for each partition as part of the 1294 1267 * discovery API and the same is passed. ··· 1608 1581 if (ret) 1609 1582 return ret; 1610 1583 1611 - ret = arm_ffa_bus_init(); 1612 - if (ret) 1613 - return ret; 1614 - 1615 1584 drv_info = kzalloc(sizeof(*drv_info), GFP_KERNEL); 1616 1585 if (!drv_info) { 1617 - ret = -ENOMEM; 1618 - goto ffa_bus_exit; 1586 + return -ENOMEM; 1619 1587 } 1620 1588 1621 1589 ret = ffa_version_check(&drv_info->version); ··· 1671 1649 free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE); 1672 1650 free_drv_info: 1673 1651 kfree(drv_info); 1674 - ffa_bus_exit: 1675 - arm_ffa_bus_exit(); 1676 1652 return ret; 1677 1653 } 1678 - subsys_initcall(ffa_init); 1654 + module_init(ffa_init); 1679 1655 1680 1656 static void __exit ffa_exit(void) 1681 1657 { ··· 1683 1663 free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE); 1684 1664 free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE); 1685 1665 kfree(drv_info); 1686 - arm_ffa_bus_exit(); 1687 1666 } 1688 1667 module_exit(ffa_exit); 1689 1668