Skip to content

Commit 46cc7c2

Browse files
committed
firmware: arm_scmi: Add receive channel support for notifications
With scmi_mbox_chan_setup enabled to identify and setup both Tx and Rx, let's consolidate setting up of both the channels under the function scmi_mbox_txrx_setup. Since some platforms may opt not to support notifications or delayed response, they may not need support for Rx. Hence Rx is optional and failure of setting one up is not considered fatal. Signed-off-by: Sudeep Holla <[email protected]>
1 parent 3748daf commit 46cc7c2

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

drivers/firmware/arm_scmi/driver.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ struct scmi_chan_info {
113113
* implementation version and (sub-)vendor identification.
114114
* @minfo: Message info
115115
* @tx_idr: IDR object to map protocol id to Tx channel info pointer
116+
* @rx_idr: IDR object to map protocol id to Rx channel info pointer
116117
* @protocols_imp: List of protocols implemented, currently maximum of
117118
* MAX_PROTOCOLS_IMP elements allocated by the base protocol
118119
* @node: List head
@@ -125,6 +126,7 @@ struct scmi_info {
125126
struct scmi_handle handle;
126127
struct scmi_xfers_info minfo;
127128
struct idr tx_idr;
129+
struct idr rx_idr;
128130
u8 *protocols_imp;
129131
struct list_head node;
130132
int users;
@@ -655,13 +657,17 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
655657
struct device_node *shmem, *np = dev->of_node;
656658
struct scmi_chan_info *cinfo;
657659
struct mbox_client *cl;
660+
struct idr *idr;
658661
const char *desc = tx ? "Tx" : "Rx";
659662

660663
/* Transmit channel is first entry i.e. index 0 */
661664
idx = tx ? 0 : 1;
665+
idr = tx ? &info->tx_idr : &info->rx_idr;
662666

663667
if (scmi_mailbox_check(np, idx)) {
664-
cinfo = idr_find(&info->tx_idr, SCMI_PROTOCOL_BASE);
668+
cinfo = idr_find(idr, SCMI_PROTOCOL_BASE);
669+
if (unlikely(!cinfo)) /* Possible only if platform has no Rx */
670+
return -EINVAL;
665671
goto idr_alloc;
666672
}
667673

@@ -703,7 +709,7 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
703709
}
704710

705711
idr_alloc:
706-
ret = idr_alloc(&info->tx_idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
712+
ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
707713
if (ret != prot_id) {
708714
dev_err(dev, "unable to allocate SCMI idr slot err %d\n", ret);
709715
return ret;
@@ -713,6 +719,17 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
713719
return 0;
714720
}
715721

722+
static inline int
723+
scmi_mbox_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
724+
{
725+
int ret = scmi_mbox_chan_setup(info, dev, prot_id, true);
726+
727+
if (!ret) /* Rx is optional, hence no error check */
728+
scmi_mbox_chan_setup(info, dev, prot_id, false);
729+
730+
return ret;
731+
}
732+
716733
static inline void
717734
scmi_create_protocol_device(struct device_node *np, struct scmi_info *info,
718735
int prot_id)
@@ -726,7 +743,7 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info,
726743
return;
727744
}
728745

729-
if (scmi_mbox_chan_setup(info, &sdev->dev, prot_id, true)) {
746+
if (scmi_mbox_txrx_setup(info, &sdev->dev, prot_id)) {
730747
dev_err(&sdev->dev, "failed to setup transport\n");
731748
scmi_device_destroy(sdev);
732749
return;
@@ -769,12 +786,13 @@ static int scmi_probe(struct platform_device *pdev)
769786

770787
platform_set_drvdata(pdev, info);
771788
idr_init(&info->tx_idr);
789+
idr_init(&info->rx_idr);
772790

773791
handle = &info->handle;
774792
handle->dev = info->dev;
775793
handle->version = &info->version;
776794

777-
ret = scmi_mbox_chan_setup(info, dev, SCMI_PROTOCOL_BASE, true);
795+
ret = scmi_mbox_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
778796
if (ret)
779797
return ret;
780798

@@ -844,6 +862,10 @@ static int scmi_remove(struct platform_device *pdev)
844862
ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
845863
idr_destroy(&info->tx_idr);
846864

865+
idr = &info->rx_idr;
866+
ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
867+
idr_destroy(&info->rx_idr);
868+
847869
return ret;
848870
}
849871

0 commit comments

Comments
 (0)