Skip to content

Commit a321db0

Browse files
committed
firmware: arm_ffa: Refactor SRI handling in prepartion to add NPI support
JIRA: https://issues.redhat.com/browse/RHEL-102691 commit f936c24 Author: Sudeep Holla <sudeep.holla@arm.com> Date: Thu, 11 Apr 2024 13:57:33 +0100 In preparation to support handling of Notification Pending Interrupt(NPI) in addition to the existing support for Schedule Receiver Interrupt(SRI), refactor the code around SRI handling so that NPI support can reuse some of it. This change shouldn't have any functionality impact. It neither adds the support for NPIs nor changes any SRI support. Tested-by: Jens Wiklander <jens.wiklander@linaro.org> Link: https://lore.kernel.org/r/20240411-ffa_npi_support-v2-2-927a670254e6@arm.com Signed-off-by: Sudeep Holla <sudeep.holla@arm.com> Signed-off-by: Marcin Juszkiewicz <mjuszkiewicz@redhat.com>
1 parent 12cfeb6 commit a321db0

File tree

1 file changed

+28
-19
lines changed

1 file changed

+28
-19
lines changed

drivers/firmware/arm_ffa/driver.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ struct ffa_drv_info {
105105
struct ffa_pcpu_irq __percpu *irq_pcpu;
106106
struct workqueue_struct *notif_pcpu_wq;
107107
struct work_struct notif_pcpu_work;
108-
struct work_struct irq_work;
108+
struct work_struct sched_recv_irq_work;
109109
struct xarray partition_info;
110110
DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS));
111111
struct mutex notify_lock; /* lock to protect notifier hashtable */
@@ -1291,12 +1291,12 @@ static void ffa_partitions_cleanup(void)
12911291
#define FFA_FEAT_SCHEDULE_RECEIVER_INT (2)
12921292
#define FFA_FEAT_MANAGED_EXIT_INT (3)
12931293

1294-
static irqreturn_t irq_handler(int irq, void *irq_data)
1294+
static irqreturn_t ffa_sched_recv_irq_handler(int irq, void *irq_data)
12951295
{
12961296
struct ffa_pcpu_irq *pcpu = irq_data;
12971297
struct ffa_drv_info *info = pcpu->info;
12981298

1299-
queue_work(info->notif_pcpu_wq, &info->irq_work);
1299+
queue_work(info->notif_pcpu_wq, &info->sched_recv_irq_work);
13001300

13011301
return IRQ_HANDLED;
13021302
}
@@ -1306,15 +1306,23 @@ static void ffa_sched_recv_irq_work_fn(struct work_struct *work)
13061306
ffa_notification_info_get();
13071307
}
13081308

1309-
static int ffa_sched_recv_irq_map(void)
1309+
static int ffa_irq_map(u32 id)
13101310
{
1311-
int ret, irq, sr_intid;
1311+
char *err_str;
1312+
int ret, irq, intid;
13121313

1313-
/* The returned sr_intid is assumed to be SGI donated to NS world */
1314-
ret = ffa_features(FFA_FEAT_SCHEDULE_RECEIVER_INT, 0, &sr_intid, NULL);
1314+
if (id == FFA_FEAT_NOTIFICATION_PENDING_INT)
1315+
err_str = "Notification Pending Interrupt";
1316+
else if (id == FFA_FEAT_SCHEDULE_RECEIVER_INT)
1317+
err_str = "Schedule Receiver Interrupt";
1318+
else
1319+
err_str = "Unknown ID";
1320+
1321+
/* The returned intid is assumed to be SGI donated to NS world */
1322+
ret = ffa_features(id, 0, &intid, NULL);
13151323
if (ret < 0) {
13161324
if (ret != -EOPNOTSUPP)
1317-
pr_err("Failed to retrieve scheduler Rx interrupt\n");
1325+
pr_err("Failed to retrieve FF-A %s %u\n", err_str, id);
13181326
return ret;
13191327
}
13201328

@@ -1329,12 +1337,12 @@ static int ffa_sched_recv_irq_map(void)
13291337

13301338
oirq.np = gic;
13311339
oirq.args_count = 1;
1332-
oirq.args[0] = sr_intid;
1340+
oirq.args[0] = intid;
13331341
irq = irq_create_of_mapping(&oirq);
13341342
of_node_put(gic);
13351343
#ifdef CONFIG_ACPI
13361344
} else {
1337-
irq = acpi_register_gsi(NULL, sr_intid, ACPI_EDGE_SENSITIVE,
1345+
irq = acpi_register_gsi(NULL, intid, ACPI_EDGE_SENSITIVE,
13381346
ACPI_ACTIVE_HIGH);
13391347
#endif
13401348
}
@@ -1347,12 +1355,11 @@ static int ffa_sched_recv_irq_map(void)
13471355
return irq;
13481356
}
13491357

1350-
static void ffa_sched_recv_irq_unmap(void)
1358+
static void ffa_irq_unmap(unsigned int irq)
13511359
{
1352-
if (drv_info->sched_recv_irq) {
1353-
irq_dispose_mapping(drv_info->sched_recv_irq);
1354-
drv_info->sched_recv_irq = 0;
1355-
}
1360+
if (!irq)
1361+
return;
1362+
irq_dispose_mapping(irq);
13561363
}
13571364

13581365
static int ffa_cpuhp_pcpu_irq_enable(unsigned int cpu)
@@ -1402,13 +1409,14 @@ static int ffa_init_pcpu_irq(unsigned int irq)
14021409

14031410
drv_info->irq_pcpu = irq_pcpu;
14041411

1405-
ret = request_percpu_irq(irq, irq_handler, "ARM-FFA", irq_pcpu);
1412+
ret = request_percpu_irq(irq, ffa_sched_recv_irq_handler, "ARM-FFA-SRI",
1413+
irq_pcpu);
14061414
if (ret) {
14071415
pr_err("Error registering notification IRQ %d: %d\n", irq, ret);
14081416
return ret;
14091417
}
14101418

1411-
INIT_WORK(&drv_info->irq_work, ffa_sched_recv_irq_work_fn);
1419+
INIT_WORK(&drv_info->sched_recv_irq_work, ffa_sched_recv_irq_work_fn);
14121420
INIT_WORK(&drv_info->notif_pcpu_work, notif_pcpu_irq_work_fn);
14131421
drv_info->notif_pcpu_wq = create_workqueue("ffa_pcpu_irq_notification");
14141422
if (!drv_info->notif_pcpu_wq)
@@ -1428,7 +1436,8 @@ static int ffa_init_pcpu_irq(unsigned int irq)
14281436
static void ffa_notifications_cleanup(void)
14291437
{
14301438
ffa_uninit_pcpu_irq();
1431-
ffa_sched_recv_irq_unmap();
1439+
ffa_irq_unmap(drv_info->sched_recv_irq);
1440+
drv_info->sched_recv_irq = 0;
14321441

14331442
if (drv_info->bitmap_created) {
14341443
ffa_notification_bitmap_destroy();
@@ -1452,7 +1461,7 @@ static void ffa_notifications_setup(void)
14521461
drv_info->bitmap_created = true;
14531462
}
14541463

1455-
irq = ffa_sched_recv_irq_map();
1464+
irq = ffa_irq_map(FFA_FEAT_SCHEDULE_RECEIVER_INT);
14561465
if (irq <= 0) {
14571466
ret = irq;
14581467
goto cleanup;

0 commit comments

Comments
 (0)