Pull SoC fixes from Arnd Bergmann: "A couple of fixes for firmware drivers have come up, addressing kernel side bugs in op-tee and ff-a code, as well as compatibility issues with exynos-acpm and ff-a protocols. The only devicetree fixes are for the Apple platform, addressing issues with conformance to the bindings for the wlan, spi and mipi nodes" * tag 'soc-fixes-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: arm64: dts: apple: Move touchbar mipi {address,size}-cells from dtsi to dts arm64: dts: apple: Drop {address,size}-cells from SPI NOR arm64: dts: apple: t8103: Fix PCIe BCM4377 nodename optee: ffa: fix sleep in atomic context firmware: exynos-acpm: fix timeouts on xfers handling arm64: defconfig: update renamed PHY_SNPS_EUSB2 firmware: arm_ffa: Fix the missing entry in struct ffa_indirect_msg_hdr firmware: arm_ffa: Replace mutex with rwlock to avoid sleep in atomic context firmware: arm_ffa: Move memory allocation outside the mutex locking firmware: arm_ffa: Fix memory leak by freeing notifier callback node
Unified · Split
| @@ -20,8 +20,6 @@ · 19 unmodified lines | |||
| 20 | compatible = "jedec,spi-nor"; | 20 | compatible = "jedec,spi-nor"; |
| 21 | reg = <0x0>; | 21 | reg = <0x0>; |
| 22 | spi-max-frequency = <25000000>; | 22 | spi-max-frequency = <25000000>; |
| 23 | #address-cells = <1>; | ||
| 24 | #size-cells = <1>; | ||
| 25 | 23 | ||
| 26 | partitions { | 24 | partitions { |
| 27 | compatible = "fixed-partitions"; | 25 | compatible = "fixed-partitions"; |
| @@ -100,6 +100,8 @@ · 99 unmodified lines | |||
| 100 | 100 | ||
| 101 | &displaydfr_mipi { | 101 | &displaydfr_mipi { |
| 102 | status = "okay"; | 102 | status = "okay"; |
| 103 | #address-cells = <1>; | ||
| 104 | #size-cells = <0>; | ||
| 103 | 105 | ||
| 104 | dfr_panel: panel@0 { | 106 | dfr_panel: panel@0 { |
| 105 | compatible = "apple,j293-summit", "apple,summit"; | 107 | compatible = "apple,j293-summit", "apple,summit"; |
| @@ -71,7 +71,7 @@ · 70 unmodified lines | |||
| 71 | */ | 71 | */ |
| 72 | &port00 { | 72 | &port00 { |
| 73 | bus-range = <1 1>; | 73 | bus-range = <1 1>; |
| 74 | wifi0: network@0,0 { | 74 | wifi0: wifi@0,0 { |
| 75 | compatible = "pci14e4,4425"; | 75 | compatible = "pci14e4,4425"; |
| 76 | reg = <0x10000 0x0 0x0 0x0 0x0>; | 76 | reg = <0x10000 0x0 0x0 0x0 0x0>; |
| 77 | /* To be filled by the loader */ | 77 | /* To be filled by the loader */ |
| @@ -405,8 +405,6 @@ · 404 unmodified lines | |||
| 405 | compatible = "apple,t8103-display-pipe-mipi", "apple,h7-display-pipe-mipi"; | 405 | compatible = "apple,t8103-display-pipe-mipi", "apple,h7-display-pipe-mipi"; |
| 406 | reg = <0x2 0x28600000 0x0 0x100000>; | 406 | reg = <0x2 0x28600000 0x0 0x100000>; |
| 407 | power-domains = <&ps_mipi_dsi>; | 407 | power-domains = <&ps_mipi_dsi>; |
| 408 | #address-cells = <1>; | ||
| 409 | #size-cells = <0>; | ||
| 410 | status = "disabled"; | 408 | status = "disabled"; |
| 411 | 409 | ||
| 412 | ports { | 410 | ports { |
| @@ -63,6 +63,8 @@ · 62 unmodified lines | |||
| 63 | 63 | ||
| 64 | &displaydfr_mipi { | 64 | &displaydfr_mipi { |
| 65 | status = "okay"; | 65 | status = "okay"; |
| 66 | #address-cells = <1>; | ||
| 67 | #size-cells = <0>; | ||
| 66 | 68 | ||
| 67 | dfr_panel: panel@0 { | 69 | dfr_panel: panel@0 { |
| 68 | compatible = "apple,j493-summit", "apple,summit"; | 70 | compatible = "apple,j493-summit", "apple,summit"; |
| @@ -420,8 +420,6 @@ · 419 unmodified lines | |||
| 420 | compatible = "apple,t8112-display-pipe-mipi", "apple,h7-display-pipe-mipi"; | 420 | compatible = "apple,t8112-display-pipe-mipi", "apple,h7-display-pipe-mipi"; |
| 421 | reg = <0x2 0x28600000 0x0 0x100000>; | 421 | reg = <0x2 0x28600000 0x0 0x100000>; |
| 422 | power-domains = <&ps_mipi_dsi>; | 422 | power-domains = <&ps_mipi_dsi>; |
| 423 | #address-cells = <1>; | ||
| 424 | #size-cells = <0>; | ||
| 425 | status = "disabled"; | 423 | status = "disabled"; |
| 426 | 424 | ||
| 427 | ports { | 425 | ports { |
| @@ -1573,6 +1573,7 @@ CONFIG_RESET_QCOM_AOSS=y · 1572 unmodified lines | |||
| 1573 | CONFIG_RESET_QCOM_PDC=m | 1573 | CONFIG_RESET_QCOM_PDC=m |
| 1574 | CONFIG_RESET_RZG2L_USBPHY_CTRL=y | 1574 | CONFIG_RESET_RZG2L_USBPHY_CTRL=y |
| 1575 | CONFIG_RESET_TI_SCI=y | 1575 | CONFIG_RESET_TI_SCI=y |
| 1576 | CONFIG_PHY_SNPS_EUSB2=m | ||
| 1576 | CONFIG_PHY_XGENE=y | 1577 | CONFIG_PHY_XGENE=y |
| 1577 | CONFIG_PHY_CAN_TRANSCEIVER=m | 1578 | CONFIG_PHY_CAN_TRANSCEIVER=m |
| 1578 | CONFIG_PHY_NXP_PTN3222=m | 1579 | CONFIG_PHY_NXP_PTN3222=m |
| @@ -1597,7 +1598,6 @@ CONFIG_PHY_QCOM_EDP=m · 18 unmodified lines | |||
| 1597 | CONFIG_PHY_QCOM_PCIE2=m | 1598 | CONFIG_PHY_QCOM_PCIE2=m |
| 1598 | CONFIG_PHY_QCOM_QMP=m | 1599 | CONFIG_PHY_QCOM_QMP=m |
| 1599 | CONFIG_PHY_QCOM_QUSB2=m | 1600 | CONFIG_PHY_QCOM_QUSB2=m |
| 1600 | CONFIG_PHY_QCOM_SNPS_EUSB2=m | ||
| 1601 | CONFIG_PHY_QCOM_EUSB2_REPEATER=m | 1601 | CONFIG_PHY_QCOM_EUSB2_REPEATER=m |
| 1602 | CONFIG_PHY_QCOM_M31_USB=m | 1602 | CONFIG_PHY_QCOM_M31_USB=m |
| 1603 | CONFIG_PHY_QCOM_USB_HS=m | 1603 | CONFIG_PHY_QCOM_USB_HS=m |
| @@ -110,7 +110,7 @@ struct ffa_drv_info { · 109 unmodified lines | |||
| 110 | struct work_struct sched_recv_irq_work; | 110 | struct work_struct sched_recv_irq_work; |
| 111 | struct xarray partition_info; | 111 | struct xarray partition_info; |
| 112 | DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS)); | 112 | DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS)); |
| 113 | struct mutex notify_lock; /* lock to protect notifier hashtable */ | 113 | rwlock_t notify_lock; /* lock to protect notifier hashtable */ |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | static struct ffa_drv_info *drv_info; | 116 | static struct ffa_drv_info *drv_info; |
| @@ -1250,13 +1250,12 @@ notifier_hnode_get_by_type(u16 notify_id, enum notify_type type) · 1133 unmodified lines | |||
| 1250 | return NULL; | 1250 | return NULL; |
| 1251 | } | 1251 | } |
| 1252 | 1252 | ||
| 1253 | static int | 1253 | static int update_notifier_cb(struct ffa_device *dev, int notify_id, |
| 1254 | update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb, | 1254 | struct notifier_cb_info *cb, bool is_framework) |
| 1255 | void *cb_data, bool is_registration, bool is_framework) | ||
| 1256 | { | 1255 | { |
| 1257 | struct notifier_cb_info *cb_info = NULL; | 1256 | struct notifier_cb_info *cb_info = NULL; |
| 1258 | enum notify_type type = ffa_notify_type_get(dev->vm_id); | 1257 | enum notify_type type = ffa_notify_type_get(dev->vm_id); |
| 1259 | bool cb_found; | 1258 | bool cb_found, is_registration = !!cb; |
| 1260 | 1259 | ||
| 1261 | if (is_framework) | 1260 | if (is_framework) |
| 1262 | cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, dev->vm_id, | 1261 | cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, dev->vm_id, |
| @@ -1270,20 +1269,10 @@ update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb, · 7 unmodified lines | |||
| 1270 | return -EINVAL; | 1269 | return -EINVAL; |
| 1271 | 1270 | ||
| 1272 | if (is_registration) { | 1271 | if (is_registration) { |
| 1273 | cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL); | 1272 | hash_add(drv_info->notifier_hash, &cb->hnode, notify_id); |
| 1274 | if (!cb_info) | ||
| 1275 | return -ENOMEM; | ||
| 1276 | |||
| 1277 | cb_info->dev = dev; | ||
| 1278 | cb_info->cb_data = cb_data; | ||
| 1279 | if (is_framework) | ||
| 1280 | cb_info->fwk_cb = cb; | ||
| 1281 | else | ||
| 1282 | cb_info->cb = cb; | ||
| 1283 | |||
| 1284 | hash_add(drv_info->notifier_hash, &cb_info->hnode, notify_id); | ||
| 1285 | } else { | 1273 | } else { |
| 1286 | hash_del(&cb_info->hnode); | 1274 | hash_del(&cb_info->hnode); |
| 1275 | kfree(cb_info); | ||
| 1287 | } | 1276 | } |
| 1288 | 1277 | ||
| 1289 | return 0; | 1278 | return 0; |
| @@ -1300,20 +1289,19 @@ static int __ffa_notify_relinquish(struct ffa_device *dev, int notify_id, · 10 unmodified lines | |||
| 1300 | if (notify_id >= FFA_MAX_NOTIFICATIONS) | 1289 | if (notify_id >= FFA_MAX_NOTIFICATIONS) |
| 1301 | return -EINVAL; | 1290 | return -EINVAL; |
| 1302 | 1291 | ||
| 1303 | mutex_lock(&drv_info->notify_lock); | 1292 | write_lock(&drv_info->notify_lock); |
| 1304 | 1293 | ||
| 1305 | rc = update_notifier_cb(dev, notify_id, NULL, NULL, false, | 1294 | rc = update_notifier_cb(dev, notify_id, NULL, is_framework); |
| 1306 | is_framework); | ||
| 1307 | if (rc) { | 1295 | if (rc) { |
| 1308 | pr_err("Could not unregister notification callback\n"); | 1296 | pr_err("Could not unregister notification callback\n"); |
| 1309 | mutex_unlock(&drv_info->notify_lock); | 1297 | write_unlock(&drv_info->notify_lock); |
| 1310 | return rc; | 1298 | return rc; |
| 1311 | } | 1299 | } |
| 1312 | 1300 | ||
| 1313 | if (!is_framework) | 1301 | if (!is_framework) |
| 1314 | rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id)); | 1302 | rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id)); |
| 1315 | 1303 | ||
| 1316 | mutex_unlock(&drv_info->notify_lock); | 1304 | write_unlock(&drv_info->notify_lock); |
| 1317 | 1305 | ||
| 1318 | return rc; | 1306 | return rc; |
| 1319 | } | 1307 | } |
| @@ -1334,6 +1322,7 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu, · 14 unmodified lines | |||
| 1334 | { | 1322 | { |
| 1335 | int rc; | 1323 | int rc; |
| 1336 | u32 flags = 0; | 1324 | u32 flags = 0; |
| 1325 | struct notifier_cb_info *cb_info = NULL; | ||
| 1337 | 1326 | ||
| 1338 | if (ffa_notifications_disabled()) | 1327 | if (ffa_notifications_disabled()) |
| 1339 | return -EOPNOTSUPP; | 1328 | return -EOPNOTSUPP; |
| @@ -1341,28 +1330,40 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu, · 1 unmodified line | |||
| 1341 | if (notify_id >= FFA_MAX_NOTIFICATIONS) | 1330 | if (notify_id >= FFA_MAX_NOTIFICATIONS) |
| 1342 | return -EINVAL; | 1331 | return -EINVAL; |
| 1343 | 1332 | ||
| 1344 | mutex_lock(&drv_info->notify_lock); | 1333 | cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL); |
| 1334 | if (!cb_info) | ||
| 1335 | return -ENOMEM; | ||
| 1336 | |||
| 1337 | cb_info->dev = dev; | ||
| 1338 | cb_info->cb_data = cb_data; | ||
| 1339 | if (is_framework) | ||
| 1340 | cb_info->fwk_cb = cb; | ||
| 1341 | else | ||
| 1342 | cb_info->cb = cb; | ||
| 1343 | |||
| 1344 | write_lock(&drv_info->notify_lock); | ||
| 1345 | 1345 | ||
| 1346 | if (!is_framework) { | 1346 | if (!is_framework) { |
| 1347 | if (is_per_vcpu) | 1347 | if (is_per_vcpu) |
| 1348 | flags = PER_VCPU_NOTIFICATION_FLAG; | 1348 | flags = PER_VCPU_NOTIFICATION_FLAG; |
| 1349 | 1349 | ||
| 1350 | rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags); | 1350 | rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags); |
| 1351 | if (rc) { | 1351 | if (rc) |
| 1352 | mutex_unlock(&drv_info->notify_lock); | 1352 | goto out_unlock_free; |
| 1353 | return rc; | ||
| 1354 | } | ||
| 1355 | } | 1353 | } |
| 1356 | 1354 | ||
| 1357 | rc = update_notifier_cb(dev, notify_id, cb, cb_data, true, | 1355 | rc = update_notifier_cb(dev, notify_id, cb_info, is_framework); |
| 1358 | is_framework); | ||
| 1359 | if (rc) { | 1356 | if (rc) { |
| 1360 | pr_err("Failed to register callback for %d - %d\n", | 1357 | pr_err("Failed to register callback for %d - %d\n", |
| 1361 | notify_id, rc); | 1358 | notify_id, rc); |
| 1362 | if (!is_framework) | 1359 | if (!is_framework) |
| 1363 | ffa_notification_unbind(dev->vm_id, BIT(notify_id)); | 1360 | ffa_notification_unbind(dev->vm_id, BIT(notify_id)); |
| 1364 | } | 1361 | } |
| 1365 | mutex_unlock(&drv_info->notify_lock); | 1362 | |
| 1363 | out_unlock_free: | ||
| 1364 | write_unlock(&drv_info->notify_lock); | ||
| 1365 | if (rc) | ||
| 1366 | kfree(cb_info); | ||
| 1366 | 1367 | ||
| 1367 | return rc; | 1368 | return rc; |
| 1368 | } | 1369 | } |
| @@ -1406,9 +1407,9 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type) · 37 unmodified lines | |||
| 1406 | if (!(bitmap & 1)) | 1407 | if (!(bitmap & 1)) |
| 1407 | continue; | 1408 | continue; |
| 1408 | 1409 | ||
| 1409 | mutex_lock(&drv_info->notify_lock); | 1410 | read_lock(&drv_info->notify_lock); |
| 1410 | cb_info = notifier_hnode_get_by_type(notify_id, type); | 1411 | cb_info = notifier_hnode_get_by_type(notify_id, type); |
| 1411 | mutex_unlock(&drv_info->notify_lock); | 1412 | read_unlock(&drv_info->notify_lock); |
| 1412 | 1413 | ||
| 1413 | if (cb_info && cb_info->cb) | 1414 | if (cb_info && cb_info->cb) |
| 1414 | cb_info->cb(notify_id, cb_info->cb_data); | 1415 | cb_info->cb(notify_id, cb_info->cb_data); |
| @@ -1446,9 +1447,9 @@ static void handle_fwk_notif_callbacks(u32 bitmap) · 31 unmodified lines | |||
| 1446 | 1447 | ||
| 1447 | ffa_rx_release(); | 1448 | ffa_rx_release(); |
| 1448 | 1449 | ||
| 1449 | mutex_lock(&drv_info->notify_lock); | 1450 | read_lock(&drv_info->notify_lock); |
| 1450 | cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, target, &uuid); | 1451 | cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, target, &uuid); |
| 1451 | mutex_unlock(&drv_info->notify_lock); | 1452 | read_unlock(&drv_info->notify_lock); |
| 1452 | 1453 | ||
| 1453 | if (cb_info && cb_info->fwk_cb) | 1454 | if (cb_info && cb_info->fwk_cb) |
| 1454 | cb_info->fwk_cb(notify_id, cb_info->cb_data, buf); | 1455 | cb_info->fwk_cb(notify_id, cb_info->cb_data, buf); |
| @@ -1973,7 +1974,7 @@ static void ffa_notifications_setup(void) · 518 unmodified lines | |||
| 1973 | goto cleanup; | 1974 | goto cleanup; |
| 1974 | 1975 | ||
| 1975 | hash_init(drv_info->notifier_hash); | 1976 | hash_init(drv_info->notifier_hash); |
| 1976 | mutex_init(&drv_info->notify_lock); | 1977 | rwlock_init(&drv_info->notify_lock); |
| 1977 | 1978 | ||
| 1978 | drv_info->notif_enabled = true; | 1979 | drv_info->notif_enabled = true; |
| 1979 | return; | 1980 | return; |
| @@ -430,6 +430,9 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer) · 429 unmodified lines | |||
| 430 | return -EOPNOTSUPP; | 430 | return -EOPNOTSUPP; |
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | msg.chan_id = xfer->acpm_chan_id; | ||
| 434 | msg.chan_type = EXYNOS_MBOX_CHAN_TYPE_DOORBELL; | ||
| 435 | |||
| 433 | scoped_guard(mutex, &achan->tx_lock) { | 436 | scoped_guard(mutex, &achan->tx_lock) { |
| 434 | tx_front = readl(achan->tx.front); | 437 | tx_front = readl(achan->tx.front); |
| 435 | idx = (tx_front + 1) % achan->qlen; | 438 | idx = (tx_front + 1) % achan->qlen; |
| @@ -446,25 +449,15 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer) · 10 unmodified lines | |||
| 446 | 449 | ||
| 447 | /* Advance TX front. */ | 450 | /* Advance TX front. */ |
| 448 | writel(idx, achan->tx.front); | 451 | writel(idx, achan->tx.front); |
| 449 | } | ||
| 450 | 452 | ||
| 451 | msg.chan_id = xfer->acpm_chan_id; | 453 | ret = mbox_send_message(achan->chan, (void *)&msg); |
| 452 | msg.chan_type = EXYNOS_MBOX_CHAN_TYPE_DOORBELL; | 454 | if (ret < 0) |
| 453 | ret = mbox_send_message(achan->chan, (void *)&msg); | 455 | return ret; |
| 454 | if (ret < 0) | ||
| 455 | return ret; | ||
| 456 | |||
| 457 | ret = acpm_wait_for_message_response(achan, xfer); | ||
| 458 | 456 | ||
| 459 | /* | 457 | mbox_client_txdone(achan->chan, 0); |
| 460 | * NOTE: we might prefer not to need the mailbox ticker to manage the | 458 | } |
| 461 | * transfer queueing since the protocol layer queues things by itself. | ||
| 462 | * Unfortunately, we have to kick the mailbox framework after we have | ||
| 463 | * received our message. | ||
| 464 | */ | ||
| 465 | mbox_client_txdone(achan->chan, ret); | ||
| 466 | 459 | ||
| 467 | return ret; | 460 | return acpm_wait_for_message_response(achan, xfer); |
| 468 | } | 461 | } |
| 469 | 462 | ||
| 470 | /** | 463 | /** |
| @@ -728,12 +728,21 @@ static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev, · 727 unmodified lines | |||
| 728 | return true; | 728 | return true; |
| 729 | } | 729 | } |
| 730 | 730 | ||
| 731 | static void notif_work_fn(struct work_struct *work) | ||
| 732 | { | ||
| 733 | struct optee_ffa *optee_ffa = container_of(work, struct optee_ffa, | ||
| 734 | notif_work); | ||
| 735 | struct optee *optee = container_of(optee_ffa, struct optee, ffa); | ||
| 736 | |||
| 737 | optee_do_bottom_half(optee->ctx); | ||
| 738 | } | ||
| 739 | |||
| 731 | static void notif_callback(int notify_id, void *cb_data) | 740 | static void notif_callback(int notify_id, void *cb_data) |
| 732 | { | 741 | { |
| 733 | struct optee *optee = cb_data; | 742 | struct optee *optee = cb_data; |
| 734 | 743 | ||
| 735 | if (notify_id == optee->ffa.bottom_half_value) | 744 | if (notify_id == optee->ffa.bottom_half_value) |
| 736 | optee_do_bottom_half(optee->ctx); | 745 | queue_work(optee->ffa.notif_wq, &optee->ffa.notif_work); |
| 737 | else | 746 | else |
| 738 | optee_notif_send(optee, notify_id); | 747 | optee_notif_send(optee, notify_id); |
| 739 | } | 748 | } |
| @@ -817,9 +826,11 @@ static void optee_ffa_remove(struct ffa_device *ffa_dev) · 77 unmodified lines | |||
| 817 | struct optee *optee = ffa_dev_get_drvdata(ffa_dev); | 826 | struct optee *optee = ffa_dev_get_drvdata(ffa_dev); |
| 818 | u32 bottom_half_id = optee->ffa.bottom_half_value; | 827 | u32 bottom_half_id = optee->ffa.bottom_half_value; |
| 819 | 828 | ||
| 820 | if (bottom_half_id != U32_MAX) | 829 | if (bottom_half_id != U32_MAX) { |
| 821 | ffa_dev->ops->notifier_ops->notify_relinquish(ffa_dev, | 830 | ffa_dev->ops->notifier_ops->notify_relinquish(ffa_dev, |
| 822 | bottom_half_id); | 831 | bottom_half_id); |
| 832 | destroy_workqueue(optee->ffa.notif_wq); | ||
| 833 | } | ||
| 823 | optee_remove_common(optee); | 834 | optee_remove_common(optee); |
| 824 | 835 | ||
| 825 | mutex_destroy(&optee->ffa.mutex); | 836 | mutex_destroy(&optee->ffa.mutex); |
| @@ -835,6 +846,13 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev, · 9 unmodified lines | |||
| 835 | u32 notif_id = 0; | 846 | u32 notif_id = 0; |
| 836 | int rc; | 847 | int rc; |
| 837 | 848 | ||
| 849 | INIT_WORK(&optee->ffa.notif_work, notif_work_fn); | ||
| 850 | optee->ffa.notif_wq = create_workqueue("optee_notification"); | ||
| 851 | if (!optee->ffa.notif_wq) { | ||
| 852 | rc = -EINVAL; | ||
| 853 | goto err; | ||
| 854 | } | ||
| 855 | |||
| 838 | while (true) { | 856 | while (true) { |
| 839 | rc = ffa_dev->ops->notifier_ops->notify_request(ffa_dev, | 857 | rc = ffa_dev->ops->notifier_ops->notify_request(ffa_dev, |
| 840 | is_per_vcpu, | 858 | is_per_vcpu, |
| @@ -851,19 +869,24 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev, · 10 unmodified lines | |||
| 851 | * notifications in that case. | 869 | * notifications in that case. |
| 852 | */ | 870 | */ |
| 853 | if (rc != -EACCES) | 871 | if (rc != -EACCES) |
| 854 | return rc; | 872 | goto err_wq; |
| 855 | notif_id++; | 873 | notif_id++; |
| 856 | if (notif_id >= OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE) | 874 | if (notif_id >= OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE) |
| 857 | return rc; | 875 | goto err_wq; |
| 858 | } | 876 | } |
| 859 | optee->ffa.bottom_half_value = notif_id; | 877 | optee->ffa.bottom_half_value = notif_id; |
| 860 | 878 | ||
| 861 | rc = enable_async_notif(optee); | 879 | rc = enable_async_notif(optee); |
| 862 | if (rc < 0) { | 880 | if (rc < 0) |
| 863 | ffa_dev->ops->notifier_ops->notify_relinquish(ffa_dev, | 881 | goto err_rel; |
| 864 | notif_id); | 882 | |
| 865 | optee->ffa.bottom_half_value = U32_MAX; | 883 | return 0; |
| 866 | } | 884 | err_rel: |
| 885 | ffa_dev->ops->notifier_ops->notify_relinquish(ffa_dev, notif_id); | ||
| 886 | err_wq: | ||
| 887 | destroy_workqueue(optee->ffa.notif_wq); | ||
| 888 | err: | ||
| 889 | optee->ffa.bottom_half_value = U32_MAX; | ||
| 867 | 890 | ||
| 868 | return rc; | 891 | return rc; |
| 869 | } | 892 | } |
| @@ -165,6 +165,8 @@ struct optee_ffa { · 164 unmodified lines | |||
| 165 | /* Serializes access to @global_ids */ | 165 | /* Serializes access to @global_ids */ |
| 166 | struct mutex mutex; | 166 | struct mutex mutex; |
| 167 | struct rhashtable global_ids; | 167 | struct rhashtable global_ids; |
| 168 | struct workqueue_struct *notif_wq; | ||
| 169 | struct work_struct notif_work; | ||
| 168 | }; | 170 | }; |
| 169 | 171 | ||
| 170 | struct optee; | 172 | struct optee; |
| @@ -283,6 +283,7 @@ struct ffa_indirect_msg_hdr { · 282 unmodified lines | |||
| 283 | u32 offset; | 283 | u32 offset; |
| 284 | u32 send_recv_id; | 284 | u32 send_recv_id; |
| 285 | u32 size; | 285 | u32 size; |
| 286 | u32 res1; | ||
| 286 | uuid_t uuid; | 287 | uuid_t uuid; |
| 287 | }; | 288 | }; |
| 288 | 289 | ||