mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-06 05:06:29 +00:00
firmware: arm_ffa: Add support for FFA_YIELD in direct messaging
Successful completion of both direct messaging function can be indicated through an invocation of FFA_YIELD or GGA_INTERRUPT by the callee. FFA_INTERRUPT indicates that the direct request was interrupted and must be resumed through the FFA_RUN interface which is already done in the driver. FFA_YIELD indicates that the receiver endpoint has transitioned to the blocked runtime state and must be resumed through the FFA_RUN interface. However, the way receiver endpoint gets unblocked is implementation defined. So, the driver just sleeps for 1 - 2ms and issues FFA_RUN. It can return to the caller with FFA_YIELD is the receiver endpoint is still blocked. Message-Id: <20240820-ffa_v1-2-v2-6-18c0c5f3c65e@arm.com> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
This commit is contained in:
parent
aaef3bc981
commit
eaca7ef8f3
@ -26,6 +26,7 @@
|
||||
#include <linux/arm_ffa.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/hashtable.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -397,6 +398,18 @@ static int ffa_id_get(u16 *vm_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ffa_msg_send_wait_for_completion(ffa_value_t *ret)
|
||||
{
|
||||
while (ret->a0 == FFA_INTERRUPT || ret->a0 == FFA_YIELD) {
|
||||
if (ret->a0 == FFA_YIELD)
|
||||
fsleep(1000);
|
||||
|
||||
invoke_ffa_fn((ffa_value_t){
|
||||
.a0 = FFA_RUN, .a1 = ret->a1,
|
||||
}, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static int ffa_msg_send_direct_req(u16 src_id, u16 dst_id, bool mode_32bit,
|
||||
struct ffa_send_direct_data *data)
|
||||
{
|
||||
@ -417,10 +430,7 @@ static int ffa_msg_send_direct_req(u16 src_id, u16 dst_id, bool mode_32bit,
|
||||
.a6 = data->data3, .a7 = data->data4,
|
||||
}, &ret);
|
||||
|
||||
while (ret.a0 == FFA_INTERRUPT)
|
||||
invoke_ffa_fn((ffa_value_t){
|
||||
.a0 = FFA_RUN, .a1 = ret.a1,
|
||||
}, &ret);
|
||||
ffa_msg_send_wait_for_completion(&ret);
|
||||
|
||||
if (ret.a0 == FFA_ERROR)
|
||||
return ffa_to_linux_errno((int)ret.a2);
|
||||
@ -482,10 +492,7 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
|
||||
|
||||
invoke_ffa_fn(args, &ret);
|
||||
|
||||
while (ret.a0 == FFA_INTERRUPT)
|
||||
invoke_ffa_fn((ffa_value_t){
|
||||
.a0 = FFA_RUN, .a1 = ret.a1,
|
||||
}, &ret);
|
||||
ffa_msg_send_wait_for_completion(&ret);
|
||||
|
||||
if (ret.a0 == FFA_ERROR)
|
||||
return ffa_to_linux_errno((int)ret.a2);
|
||||
|
Loading…
Reference in New Issue
Block a user