mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-16 03:19:00 -05:00
Merge tag 'soc-fixes-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
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
This commit is contained in:
@@ -20,8 +20,6 @@ flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0x0>;
|
||||
spi-max-frequency = <25000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
@@ -100,6 +100,8 @@ dfr_mipi_out_panel: endpoint@0 {
|
||||
|
||||
&displaydfr_mipi {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
dfr_panel: panel@0 {
|
||||
compatible = "apple,j293-summit", "apple,summit";
|
||||
|
||||
@@ -71,7 +71,7 @@ hpm1: usb-pd@3f {
|
||||
*/
|
||||
&port00 {
|
||||
bus-range = <1 1>;
|
||||
wifi0: network@0,0 {
|
||||
wifi0: wifi@0,0 {
|
||||
compatible = "pci14e4,4425";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
/* To be filled by the loader */
|
||||
|
||||
@@ -405,8 +405,6 @@ displaydfr_mipi: dsi@228600000 {
|
||||
compatible = "apple,t8103-display-pipe-mipi", "apple,h7-display-pipe-mipi";
|
||||
reg = <0x2 0x28600000 0x0 0x100000>;
|
||||
power-domains = <&ps_mipi_dsi>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
||||
ports {
|
||||
|
||||
@@ -63,6 +63,8 @@ dfr_mipi_out_panel: endpoint@0 {
|
||||
|
||||
&displaydfr_mipi {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
dfr_panel: panel@0 {
|
||||
compatible = "apple,j493-summit", "apple,summit";
|
||||
|
||||
@@ -420,8 +420,6 @@ displaydfr_mipi: dsi@228600000 {
|
||||
compatible = "apple,t8112-display-pipe-mipi", "apple,h7-display-pipe-mipi";
|
||||
reg = <0x2 0x28600000 0x0 0x100000>;
|
||||
power-domains = <&ps_mipi_dsi>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
||||
ports {
|
||||
|
||||
@@ -1573,6 +1573,7 @@ CONFIG_RESET_QCOM_AOSS=y
|
||||
CONFIG_RESET_QCOM_PDC=m
|
||||
CONFIG_RESET_RZG2L_USBPHY_CTRL=y
|
||||
CONFIG_RESET_TI_SCI=y
|
||||
CONFIG_PHY_SNPS_EUSB2=m
|
||||
CONFIG_PHY_XGENE=y
|
||||
CONFIG_PHY_CAN_TRANSCEIVER=m
|
||||
CONFIG_PHY_NXP_PTN3222=m
|
||||
@@ -1597,7 +1598,6 @@ CONFIG_PHY_QCOM_EDP=m
|
||||
CONFIG_PHY_QCOM_PCIE2=m
|
||||
CONFIG_PHY_QCOM_QMP=m
|
||||
CONFIG_PHY_QCOM_QUSB2=m
|
||||
CONFIG_PHY_QCOM_SNPS_EUSB2=m
|
||||
CONFIG_PHY_QCOM_EUSB2_REPEATER=m
|
||||
CONFIG_PHY_QCOM_M31_USB=m
|
||||
CONFIG_PHY_QCOM_USB_HS=m
|
||||
|
||||
@@ -110,7 +110,7 @@ struct ffa_drv_info {
|
||||
struct work_struct sched_recv_irq_work;
|
||||
struct xarray partition_info;
|
||||
DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS));
|
||||
struct mutex notify_lock; /* lock to protect notifier hashtable */
|
||||
rwlock_t notify_lock; /* lock to protect notifier hashtable */
|
||||
};
|
||||
|
||||
static struct ffa_drv_info *drv_info;
|
||||
@@ -1250,13 +1250,12 @@ notifier_hnode_get_by_type(u16 notify_id, enum notify_type type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb,
|
||||
void *cb_data, bool is_registration, bool is_framework)
|
||||
static int update_notifier_cb(struct ffa_device *dev, int notify_id,
|
||||
struct notifier_cb_info *cb, bool is_framework)
|
||||
{
|
||||
struct notifier_cb_info *cb_info = NULL;
|
||||
enum notify_type type = ffa_notify_type_get(dev->vm_id);
|
||||
bool cb_found;
|
||||
bool cb_found, is_registration = !!cb;
|
||||
|
||||
if (is_framework)
|
||||
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,
|
||||
return -EINVAL;
|
||||
|
||||
if (is_registration) {
|
||||
cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
|
||||
if (!cb_info)
|
||||
return -ENOMEM;
|
||||
|
||||
cb_info->dev = dev;
|
||||
cb_info->cb_data = cb_data;
|
||||
if (is_framework)
|
||||
cb_info->fwk_cb = cb;
|
||||
else
|
||||
cb_info->cb = cb;
|
||||
|
||||
hash_add(drv_info->notifier_hash, &cb_info->hnode, notify_id);
|
||||
hash_add(drv_info->notifier_hash, &cb->hnode, notify_id);
|
||||
} else {
|
||||
hash_del(&cb_info->hnode);
|
||||
kfree(cb_info);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1300,20 +1289,19 @@ static int __ffa_notify_relinquish(struct ffa_device *dev, int notify_id,
|
||||
if (notify_id >= FFA_MAX_NOTIFICATIONS)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&drv_info->notify_lock);
|
||||
write_lock(&drv_info->notify_lock);
|
||||
|
||||
rc = update_notifier_cb(dev, notify_id, NULL, NULL, false,
|
||||
is_framework);
|
||||
rc = update_notifier_cb(dev, notify_id, NULL, is_framework);
|
||||
if (rc) {
|
||||
pr_err("Could not unregister notification callback\n");
|
||||
mutex_unlock(&drv_info->notify_lock);
|
||||
write_unlock(&drv_info->notify_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!is_framework)
|
||||
rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id));
|
||||
|
||||
mutex_unlock(&drv_info->notify_lock);
|
||||
write_unlock(&drv_info->notify_lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1334,6 +1322,7 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
|
||||
{
|
||||
int rc;
|
||||
u32 flags = 0;
|
||||
struct notifier_cb_info *cb_info = NULL;
|
||||
|
||||
if (ffa_notifications_disabled())
|
||||
return -EOPNOTSUPP;
|
||||
@@ -1341,28 +1330,40 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
|
||||
if (notify_id >= FFA_MAX_NOTIFICATIONS)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&drv_info->notify_lock);
|
||||
cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
|
||||
if (!cb_info)
|
||||
return -ENOMEM;
|
||||
|
||||
cb_info->dev = dev;
|
||||
cb_info->cb_data = cb_data;
|
||||
if (is_framework)
|
||||
cb_info->fwk_cb = cb;
|
||||
else
|
||||
cb_info->cb = cb;
|
||||
|
||||
write_lock(&drv_info->notify_lock);
|
||||
|
||||
if (!is_framework) {
|
||||
if (is_per_vcpu)
|
||||
flags = PER_VCPU_NOTIFICATION_FLAG;
|
||||
|
||||
rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
|
||||
if (rc) {
|
||||
mutex_unlock(&drv_info->notify_lock);
|
||||
return rc;
|
||||
}
|
||||
if (rc)
|
||||
goto out_unlock_free;
|
||||
}
|
||||
|
||||
rc = update_notifier_cb(dev, notify_id, cb, cb_data, true,
|
||||
is_framework);
|
||||
rc = update_notifier_cb(dev, notify_id, cb_info, is_framework);
|
||||
if (rc) {
|
||||
pr_err("Failed to register callback for %d - %d\n",
|
||||
notify_id, rc);
|
||||
if (!is_framework)
|
||||
ffa_notification_unbind(dev->vm_id, BIT(notify_id));
|
||||
}
|
||||
mutex_unlock(&drv_info->notify_lock);
|
||||
|
||||
out_unlock_free:
|
||||
write_unlock(&drv_info->notify_lock);
|
||||
if (rc)
|
||||
kfree(cb_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1406,9 +1407,9 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
|
||||
if (!(bitmap & 1))
|
||||
continue;
|
||||
|
||||
mutex_lock(&drv_info->notify_lock);
|
||||
read_lock(&drv_info->notify_lock);
|
||||
cb_info = notifier_hnode_get_by_type(notify_id, type);
|
||||
mutex_unlock(&drv_info->notify_lock);
|
||||
read_unlock(&drv_info->notify_lock);
|
||||
|
||||
if (cb_info && cb_info->cb)
|
||||
cb_info->cb(notify_id, cb_info->cb_data);
|
||||
@@ -1446,9 +1447,9 @@ static void handle_fwk_notif_callbacks(u32 bitmap)
|
||||
|
||||
ffa_rx_release();
|
||||
|
||||
mutex_lock(&drv_info->notify_lock);
|
||||
read_lock(&drv_info->notify_lock);
|
||||
cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, target, &uuid);
|
||||
mutex_unlock(&drv_info->notify_lock);
|
||||
read_unlock(&drv_info->notify_lock);
|
||||
|
||||
if (cb_info && cb_info->fwk_cb)
|
||||
cb_info->fwk_cb(notify_id, cb_info->cb_data, buf);
|
||||
@@ -1973,7 +1974,7 @@ static void ffa_notifications_setup(void)
|
||||
goto cleanup;
|
||||
|
||||
hash_init(drv_info->notifier_hash);
|
||||
mutex_init(&drv_info->notify_lock);
|
||||
rwlock_init(&drv_info->notify_lock);
|
||||
|
||||
drv_info->notif_enabled = true;
|
||||
return;
|
||||
|
||||
@@ -430,6 +430,9 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
msg.chan_id = xfer->acpm_chan_id;
|
||||
msg.chan_type = EXYNOS_MBOX_CHAN_TYPE_DOORBELL;
|
||||
|
||||
scoped_guard(mutex, &achan->tx_lock) {
|
||||
tx_front = readl(achan->tx.front);
|
||||
idx = (tx_front + 1) % achan->qlen;
|
||||
@@ -446,25 +449,15 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer)
|
||||
|
||||
/* Advance TX front. */
|
||||
writel(idx, achan->tx.front);
|
||||
|
||||
ret = mbox_send_message(achan->chan, (void *)&msg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mbox_client_txdone(achan->chan, 0);
|
||||
}
|
||||
|
||||
msg.chan_id = xfer->acpm_chan_id;
|
||||
msg.chan_type = EXYNOS_MBOX_CHAN_TYPE_DOORBELL;
|
||||
ret = mbox_send_message(achan->chan, (void *)&msg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = acpm_wait_for_message_response(achan, xfer);
|
||||
|
||||
/*
|
||||
* NOTE: we might prefer not to need the mailbox ticker to manage the
|
||||
* transfer queueing since the protocol layer queues things by itself.
|
||||
* Unfortunately, we have to kick the mailbox framework after we have
|
||||
* received our message.
|
||||
*/
|
||||
mbox_client_txdone(achan->chan, ret);
|
||||
|
||||
return ret;
|
||||
return acpm_wait_for_message_response(achan, xfer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -728,12 +728,21 @@ static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void notif_work_fn(struct work_struct *work)
|
||||
{
|
||||
struct optee_ffa *optee_ffa = container_of(work, struct optee_ffa,
|
||||
notif_work);
|
||||
struct optee *optee = container_of(optee_ffa, struct optee, ffa);
|
||||
|
||||
optee_do_bottom_half(optee->ctx);
|
||||
}
|
||||
|
||||
static void notif_callback(int notify_id, void *cb_data)
|
||||
{
|
||||
struct optee *optee = cb_data;
|
||||
|
||||
if (notify_id == optee->ffa.bottom_half_value)
|
||||
optee_do_bottom_half(optee->ctx);
|
||||
queue_work(optee->ffa.notif_wq, &optee->ffa.notif_work);
|
||||
else
|
||||
optee_notif_send(optee, notify_id);
|
||||
}
|
||||
@@ -817,9 +826,11 @@ static void optee_ffa_remove(struct ffa_device *ffa_dev)
|
||||
struct optee *optee = ffa_dev_get_drvdata(ffa_dev);
|
||||
u32 bottom_half_id = optee->ffa.bottom_half_value;
|
||||
|
||||
if (bottom_half_id != U32_MAX)
|
||||
if (bottom_half_id != U32_MAX) {
|
||||
ffa_dev->ops->notifier_ops->notify_relinquish(ffa_dev,
|
||||
bottom_half_id);
|
||||
destroy_workqueue(optee->ffa.notif_wq);
|
||||
}
|
||||
optee_remove_common(optee);
|
||||
|
||||
mutex_destroy(&optee->ffa.mutex);
|
||||
@@ -835,6 +846,13 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev,
|
||||
u32 notif_id = 0;
|
||||
int rc;
|
||||
|
||||
INIT_WORK(&optee->ffa.notif_work, notif_work_fn);
|
||||
optee->ffa.notif_wq = create_workqueue("optee_notification");
|
||||
if (!optee->ffa.notif_wq) {
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
rc = ffa_dev->ops->notifier_ops->notify_request(ffa_dev,
|
||||
is_per_vcpu,
|
||||
@@ -851,19 +869,24 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev,
|
||||
* notifications in that case.
|
||||
*/
|
||||
if (rc != -EACCES)
|
||||
return rc;
|
||||
goto err_wq;
|
||||
notif_id++;
|
||||
if (notif_id >= OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE)
|
||||
return rc;
|
||||
goto err_wq;
|
||||
}
|
||||
optee->ffa.bottom_half_value = notif_id;
|
||||
|
||||
rc = enable_async_notif(optee);
|
||||
if (rc < 0) {
|
||||
ffa_dev->ops->notifier_ops->notify_relinquish(ffa_dev,
|
||||
notif_id);
|
||||
optee->ffa.bottom_half_value = U32_MAX;
|
||||
}
|
||||
if (rc < 0)
|
||||
goto err_rel;
|
||||
|
||||
return 0;
|
||||
err_rel:
|
||||
ffa_dev->ops->notifier_ops->notify_relinquish(ffa_dev, notif_id);
|
||||
err_wq:
|
||||
destroy_workqueue(optee->ffa.notif_wq);
|
||||
err:
|
||||
optee->ffa.bottom_half_value = U32_MAX;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -165,6 +165,8 @@ struct optee_ffa {
|
||||
/* Serializes access to @global_ids */
|
||||
struct mutex mutex;
|
||||
struct rhashtable global_ids;
|
||||
struct workqueue_struct *notif_wq;
|
||||
struct work_struct notif_work;
|
||||
};
|
||||
|
||||
struct optee;
|
||||
|
||||
@@ -283,6 +283,7 @@ struct ffa_indirect_msg_hdr {
|
||||
u32 offset;
|
||||
u32 send_recv_id;
|
||||
u32 size;
|
||||
u32 res1;
|
||||
uuid_t uuid;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user