Skip to content

Commit 84a6a2e

Browse files
Marc ZyngierJason Cooper
authored andcommitted
irqchip: GICv3: ITS: device allocation and configuration
The ITS has a notion of "device" that can write to it in order to generate an interrupt. Conversly, the driver maintains a per-ITS list of devices, together with their configuration information, and uses this to configure the HW. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Link: https://lkml.kernel.org/r/1416839720-18400-9-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
1 parent 1ac19ca commit 84a6a2e

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,3 +981,77 @@ static void its_cpu_init_collection(void)
981981

982982
spin_unlock(&its_lock);
983983
}
984+
985+
static struct its_device *its_find_device(struct its_node *its, u32 dev_id)
986+
{
987+
struct its_device *its_dev = NULL, *tmp;
988+
989+
raw_spin_lock(&its->lock);
990+
991+
list_for_each_entry(tmp, &its->its_device_list, entry) {
992+
if (tmp->device_id == dev_id) {
993+
its_dev = tmp;
994+
break;
995+
}
996+
}
997+
998+
raw_spin_unlock(&its->lock);
999+
1000+
return its_dev;
1001+
}
1002+
1003+
static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
1004+
int nvecs)
1005+
{
1006+
struct its_device *dev;
1007+
unsigned long *lpi_map;
1008+
void *itt;
1009+
int lpi_base;
1010+
int nr_lpis;
1011+
int cpu;
1012+
int sz;
1013+
1014+
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1015+
sz = nvecs * its->ite_size;
1016+
sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
1017+
itt = kmalloc(sz, GFP_KERNEL);
1018+
lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
1019+
1020+
if (!dev || !itt || !lpi_map) {
1021+
kfree(dev);
1022+
kfree(itt);
1023+
kfree(lpi_map);
1024+
return NULL;
1025+
}
1026+
1027+
dev->its = its;
1028+
dev->itt = itt;
1029+
dev->nr_ites = nvecs;
1030+
dev->lpi_map = lpi_map;
1031+
dev->lpi_base = lpi_base;
1032+
dev->nr_lpis = nr_lpis;
1033+
dev->device_id = dev_id;
1034+
INIT_LIST_HEAD(&dev->entry);
1035+
1036+
raw_spin_lock(&its->lock);
1037+
list_add(&dev->entry, &its->its_device_list);
1038+
raw_spin_unlock(&its->lock);
1039+
1040+
/* Bind the device to the first possible CPU */
1041+
cpu = cpumask_first(cpu_online_mask);
1042+
dev->collection = &its->collections[cpu];
1043+
1044+
/* Map device to its ITT */
1045+
its_send_mapd(dev, 1);
1046+
1047+
return dev;
1048+
}
1049+
1050+
static void its_free_device(struct its_device *its_dev)
1051+
{
1052+
raw_spin_lock(&its_dev->its->lock);
1053+
list_del(&its_dev->entry);
1054+
raw_spin_unlock(&its_dev->its->lock);
1055+
kfree(its_dev->itt);
1056+
kfree(its_dev);
1057+
}

0 commit comments

Comments
 (0)