aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-gic-v3-its.c
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-12-12 05:51:24 -0500
committerThomas Gleixner <tglx@linutronix.de>2014-12-13 07:41:06 -0500
commitc848126734e8621e81659d819922b20d93a2aa6d (patch)
treec3c7ffded7bc94951587318dd40a19641587d47b /drivers/irqchip/irq-gic-v3-its.c
parentaca268df8a576ad11ce5ecd55d1eabe00c69e3c6 (diff)
irqchip: gicv3-its: Fix ITT allocation
When issuing a MAPD command, one of the parameters passed to the ITS is the number of EventID bits used to index the per-device Interrupt Translation Table (ITT). Crucially, this is the number of bits *minus one*. This has two consequences: - The size of the ITT has to be a strict power of two, no matter how many different events the device is actually going to generate. - It is impossible to express an ITT with a single entry, as you would have to tell the ITS to "use zero bit from the EventID", and that clashes with "minus one" above. Fix this by allocating the ITT with the number of vectors rounded up to the next power of two, with a minimum of two entries. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Cc: linux-arm-kernel@lists.infradead.org Cc: Yun Wu (Abel) <wuyun.wu@huawei.com> Cc: Robert Richter <robert.richter@caviumnetworks.com> Cc: Jason Cooper <jason@lakedaemon.net> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/irqchip/irq-gic-v3-its.c')
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 98144fde1df0..86e4684adeb1 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -228,7 +228,7 @@ static struct its_collection *its_build_mapd_cmd(struct its_cmd_block *cmd,
228 struct its_cmd_desc *desc) 228 struct its_cmd_desc *desc)
229{ 229{
230 unsigned long itt_addr; 230 unsigned long itt_addr;
231 u8 size = order_base_2(desc->its_mapd_cmd.dev->nr_ites); 231 u8 size = ilog2(desc->its_mapd_cmd.dev->nr_ites);
232 232
233 itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt); 233 itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt);
234 itt_addr = ALIGN(itt_addr, ITS_ITT_ALIGN); 234 itt_addr = ALIGN(itt_addr, ITS_ITT_ALIGN);
@@ -1043,11 +1043,18 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
1043 void *itt; 1043 void *itt;
1044 int lpi_base; 1044 int lpi_base;
1045 int nr_lpis; 1045 int nr_lpis;
1046 int nr_ites;
1046 int cpu; 1047 int cpu;
1047 int sz; 1048 int sz;
1048 1049
1049 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 1050 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1050 sz = nvecs * its->ite_size; 1051 /*
1052 * At least one bit of EventID is being used, hence a minimum
1053 * of two entries. No, the architecture doesn't let you
1054 * express an ITT with a single entry.
1055 */
1056 nr_ites = max(2, roundup_pow_of_two(nvecs));
1057 sz = nr_ites * its->ite_size;
1051 sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; 1058 sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
1052 itt = kmalloc(sz, GFP_KERNEL); 1059 itt = kmalloc(sz, GFP_KERNEL);
1053 lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis); 1060 lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
@@ -1061,7 +1068,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
1061 1068
1062 dev->its = its; 1069 dev->its = its;
1063 dev->itt = itt; 1070 dev->itt = itt;
1064 dev->nr_ites = nvecs; 1071 dev->nr_ites = nr_ites;
1065 dev->lpi_map = lpi_map; 1072 dev->lpi_map = lpi_map;
1066 dev->lpi_base = lpi_base; 1073 dev->lpi_base = lpi_base;
1067 dev->nr_lpis = nr_lpis; 1074 dev->nr_lpis = nr_lpis;