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 | 20 | compatible = "jedec,spi-nor"; |
| 21 | 21 | reg = <0x0>; |
| 22 | 22 | spi-max-frequency = <25000000>; |
| 23 | − #address-cells = <1>; | |
| 24 | − #size-cells = <1>; | |
| 25 | 23 | |
| 26 | 24 | partitions { |
| 27 | 25 | compatible = "fixed-partitions"; |
| @@ -100,6 +100,8 @@ · 99 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | &displaydfr_mipi { |
| 102 | 102 | status = "okay"; |
| 103 | + #address-cells = <1>; | |
| 104 | + #size-cells = <0>; | |
| 103 | 105 | |
| 104 | 106 | dfr_panel: panel@0 { |
| 105 | 107 | compatible = "apple,j293-summit", "apple,summit"; |
| @@ -71,7 +71,7 @@ · 70 unmodified lines | ||
| 71 | 71 | */ |
| 72 | 72 | &port00 { |
| 73 | 73 | bus-range = <1 1>; |
| 74 | − wifi0: network@0,0 { | |
| 74 | + wifi0: wifi@0,0 { | |
| 75 | 75 | compatible = "pci14e4,4425"; |
| 76 | 76 | reg = <0x10000 0x0 0x0 0x0 0x0>; |
| 77 | 77 | /* To be filled by the loader */ |
| @@ -405,8 +405,6 @@ · 404 unmodified lines | ||
| 405 | 405 | compatible = "apple,t8103-display-pipe-mipi", "apple,h7-display-pipe-mipi"; |
| 406 | 406 | reg = <0x2 0x28600000 0x0 0x100000>; |
| 407 | 407 | power-domains = <&ps_mipi_dsi>; |
| 408 | − #address-cells = <1>; | |
| 409 | − #size-cells = <0>; | |
| 410 | 408 | status = "disabled"; |
| 411 | 409 | |
| 412 | 410 | ports { |
| @@ -63,6 +63,8 @@ · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | &displaydfr_mipi { |
| 65 | 65 | status = "okay"; |
| 66 | + #address-cells = <1>; | |
| 67 | + #size-cells = <0>; | |
| 66 | 68 | |
| 67 | 69 | dfr_panel: panel@0 { |
| 68 | 70 | compatible = "apple,j493-summit", "apple,summit"; |
| @@ -420,8 +420,6 @@ · 419 unmodified lines | ||
| 420 | 420 | compatible = "apple,t8112-display-pipe-mipi", "apple,h7-display-pipe-mipi"; |
| 421 | 421 | reg = <0x2 0x28600000 0x0 0x100000>; |
| 422 | 422 | power-domains = <&ps_mipi_dsi>; |
| 423 | − #address-cells = <1>; | |
| 424 | − #size-cells = <0>; | |
| 425 | 423 | status = "disabled"; |
| 426 | 424 | |
| 427 | 425 | ports { |
| @@ -1573,6 +1573,7 @@ CONFIG_RESET_QCOM_AOSS=y · 1572 unmodified lines | ||
| 1573 | 1573 | CONFIG_RESET_QCOM_PDC=m |
| 1574 | 1574 | CONFIG_RESET_RZG2L_USBPHY_CTRL=y |
| 1575 | 1575 | CONFIG_RESET_TI_SCI=y |
| 1576 | +CONFIG_PHY_SNPS_EUSB2=m | |
| 1576 | 1577 | CONFIG_PHY_XGENE=y |
| 1577 | 1578 | CONFIG_PHY_CAN_TRANSCEIVER=m |
| 1578 | 1579 | CONFIG_PHY_NXP_PTN3222=m |
| @@ -1597,7 +1598,6 @@ CONFIG_PHY_QCOM_EDP=m · 18 unmodified lines | ||
| 1597 | 1598 | CONFIG_PHY_QCOM_PCIE2=m |
| 1598 | 1599 | CONFIG_PHY_QCOM_QMP=m |
| 1599 | 1600 | CONFIG_PHY_QCOM_QUSB2=m |
| 1600 | −CONFIG_PHY_QCOM_SNPS_EUSB2=m | |
| 1601 | 1601 | CONFIG_PHY_QCOM_EUSB2_REPEATER=m |
| 1602 | 1602 | CONFIG_PHY_QCOM_M31_USB=m |
| 1603 | 1603 | CONFIG_PHY_QCOM_USB_HS=m |
| @@ -110,7 +110,7 @@ struct ffa_drv_info { · 109 unmodified lines | ||
| 110 | 110 | struct work_struct sched_recv_irq_work; |
| 111 | 111 | struct xarray partition_info; |
| 112 | 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 | 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 | 1250 | return NULL; |
| 1251 | 1251 | } |
| 1252 | 1252 | |
| 1253 | −static int | |
| 1254 | −update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb, | |
| 1255 | − void *cb_data, bool is_registration, bool is_framework) | |
| 1253 | +static int update_notifier_cb(struct ffa_device *dev, int notify_id, | |
| 1254 | + struct notifier_cb_info *cb, bool is_framework) | |
| 1256 | 1255 | { |
| 1257 | 1256 | struct notifier_cb_info *cb_info = NULL; |
| 1258 | 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 | 1260 | if (is_framework) |
| 1262 | 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 | 1269 | return -EINVAL; |
| 1271 | 1270 | |
| 1272 | 1271 | if (is_registration) { |
| 1273 | − cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL); | |
| 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); | |
| 1272 | + hash_add(drv_info->notifier_hash, &cb->hnode, notify_id); | |
| 1285 | 1273 | } else { |
| 1286 | 1274 | hash_del(&cb_info->hnode); |
| 1275 | + kfree(cb_info); | |
| 1287 | 1276 | } |
| 1288 | 1277 | |
| 1289 | 1278 | return 0; |
| @@ -1300,20 +1289,19 @@ static int __ffa_notify_relinquish(struct ffa_device *dev, int notify_id, · 10 unmodified lines | ||
| 1300 | 1289 | if (notify_id >= FFA_MAX_NOTIFICATIONS) |
| 1301 | 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, | |
| 1306 | − is_framework); | |
| 1294 | + rc = update_notifier_cb(dev, notify_id, NULL, is_framework); | |
| 1307 | 1295 | if (rc) { |
| 1308 | 1296 | pr_err("Could not unregister notification callback\n"); |
| 1309 | − mutex_unlock(&drv_info->notify_lock); | |
| 1297 | + write_unlock(&drv_info->notify_lock); | |
| 1310 | 1298 | return rc; |
| 1311 | 1299 | } |
| 1312 | 1300 | |
| 1313 | 1301 | if (!is_framework) |
| 1314 | 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 | 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 | 1323 | int rc; |
| 1336 | 1324 | u32 flags = 0; |
| 1325 | + struct notifier_cb_info *cb_info = NULL; | |
| 1337 | 1326 | |
| 1338 | 1327 | if (ffa_notifications_disabled()) |
| 1339 | 1328 | return -EOPNOTSUPP; |
| @@ -1341,28 +1330,40 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu, · 1 unmodified line | ||
| 1341 | 1330 | if (notify_id >= FFA_MAX_NOTIFICATIONS) |
| 1342 | 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 | 1346 | if (!is_framework) { |
| 1347 | 1347 | if (is_per_vcpu) |
| 1348 | 1348 | flags = PER_VCPU_NOTIFICATION_FLAG; |
| 1349 | 1349 | |
| 1350 | 1350 | rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags); |
| 1351 | − if (rc) { | |
| 1352 | − mutex_unlock(&drv_info->notify_lock); | |
| 1353 | − return rc; | |
| 1354 | − } | |
| 1351 | + if (rc) | |
| 1352 | + goto out_unlock_free; | |
| 1355 | 1353 | } |
| 1356 | 1354 | |
| 1357 | − rc = update_notifier_cb(dev, notify_id, cb, cb_data, true, | |
| 1358 | − is_framework); | |
| 1355 | + rc = update_notifier_cb(dev, notify_id, cb_info, is_framework); | |
| 1359 | 1356 | if (rc) { |
| 1360 | 1357 | pr_err("Failed to register callback for %d - %d\n", |
| 1361 | 1358 | notify_id, rc); |
| 1362 | 1359 | if (!is_framework) |
| 1363 | 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 | 1368 | return rc; |
| 1368 | 1369 | } |
| @@ -1406,9 +1407,9 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type) · 37 unmodified lines | ||
| 1406 | 1407 | if (!(bitmap & 1)) |
| 1407 | 1408 | continue; |
| 1408 | 1409 | |
| 1409 | − mutex_lock(&drv_info->notify_lock); | |
| 1410 | + read_lock(&drv_info->notify_lock); | |
| 1410 | 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 | 1414 | if (cb_info && cb_info->cb) |
| 1414 | 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 | 1448 | ffa_rx_release(); |
| 1448 | 1449 | |
| 1449 | − mutex_lock(&drv_info->notify_lock); | |
| 1450 | + read_lock(&drv_info->notify_lock); | |
| 1450 | 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 | 1454 | if (cb_info && cb_info->fwk_cb) |
| 1454 | 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 | 1974 | goto cleanup; |
| 1974 | 1975 | |
| 1975 | 1976 | hash_init(drv_info->notifier_hash); |
| 1976 | − mutex_init(&drv_info->notify_lock); | |
| 1977 | + rwlock_init(&drv_info->notify_lock); | |
| 1977 | 1978 | |
| 1978 | 1979 | drv_info->notif_enabled = true; |
| 1979 | 1980 | return; |
| @@ -430,6 +430,9 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer) · 429 unmodified lines | ||
| 430 | 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 | 436 | scoped_guard(mutex, &achan->tx_lock) { |
| 434 | 437 | tx_front = readl(achan->tx.front); |
| 435 | 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 | 450 | /* Advance TX front. */ |
| 448 | 451 | writel(idx, achan->tx.front); |
| 449 | − } | |
| 450 | 452 | |
| 451 | − msg.chan_id = xfer->acpm_chan_id; | |
| 452 | − msg.chan_type = EXYNOS_MBOX_CHAN_TYPE_DOORBELL; | |
| 453 | − ret = mbox_send_message(achan->chan, (void *)&msg); | |
| 454 | − if (ret < 0) | |
| 455 | − return ret; | |
| 456 | − | |
| 457 | − ret = acpm_wait_for_message_response(achan, xfer); | |
| 453 | + ret = mbox_send_message(achan->chan, (void *)&msg); | |
| 454 | + if (ret < 0) | |
| 455 | + return ret; | |
| 458 | 456 | |
| 459 | − /* | |
| 460 | − * NOTE: we might prefer not to need the mailbox ticker to manage the | |
| 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); | |
| 457 | + mbox_client_txdone(achan->chan, 0); | |
| 458 | + } | |
| 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 | 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 | 740 | static void notif_callback(int notify_id, void *cb_data) |
| 732 | 741 | { |
| 733 | 742 | struct optee *optee = cb_data; |
| 734 | 743 | |
| 735 | 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 | 746 | else |
| 738 | 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 | 826 | struct optee *optee = ffa_dev_get_drvdata(ffa_dev); |
| 818 | 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 | 830 | ffa_dev->ops->notifier_ops->notify_relinquish(ffa_dev, |
| 822 | 831 | bottom_half_id); |
| 832 | + destroy_workqueue(optee->ffa.notif_wq); | |
| 833 | + } | |
| 823 | 834 | optee_remove_common(optee); |
| 824 | 835 | |
| 825 | 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 | 846 | u32 notif_id = 0; |
| 836 | 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 | 856 | while (true) { |
| 839 | 857 | rc = ffa_dev->ops->notifier_ops->notify_request(ffa_dev, |
| 840 | 858 | is_per_vcpu, |
| @@ -851,19 +869,24 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev, · 10 unmodified lines | ||
| 851 | 869 | * notifications in that case. |
| 852 | 870 | */ |
| 853 | 871 | if (rc != -EACCES) |
| 854 | − return rc; | |
| 872 | + goto err_wq; | |
| 855 | 873 | notif_id++; |
| 856 | 874 | if (notif_id >= OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE) |
| 857 | − return rc; | |
| 875 | + goto err_wq; | |
| 858 | 876 | } |
| 859 | 877 | optee->ffa.bottom_half_value = notif_id; |
| 860 | 878 | |
| 861 | 879 | rc = enable_async_notif(optee); |
| 862 | − if (rc < 0) { | |
| 863 | − ffa_dev->ops->notifier_ops->notify_relinquish(ffa_dev, | |
| 864 | − notif_id); | |
| 865 | − optee->ffa.bottom_half_value = U32_MAX; | |
| 866 | − } | |
| 880 | + if (rc < 0) | |
| 881 | + goto err_rel; | |
| 882 | + | |
| 883 | + return 0; | |
| 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 | 891 | return rc; |
| 869 | 892 | } |
| @@ -165,6 +165,8 @@ struct optee_ffa { · 164 unmodified lines | ||
| 165 | 165 | /* Serializes access to @global_ids */ |
| 166 | 166 | struct mutex mutex; |
| 167 | 167 | struct rhashtable global_ids; |
| 168 | + struct workqueue_struct *notif_wq; | |
| 169 | + struct work_struct notif_work; | |
| 168 | 170 | }; |
| 169 | 171 | |
| 170 | 172 | struct optee; |
| @@ -283,6 +283,7 @@ struct ffa_indirect_msg_hdr { · 282 unmodified lines | ||
| 283 | 283 | u32 offset; |
| 284 | 284 | u32 send_recv_id; |
| 285 | 285 | u32 size; |
| 286 | + u32 res1; | |
| 286 | 287 | uuid_t uuid; |
| 287 | 288 | }; |
| 288 | 289 | |