diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2016-12-19 19:53:02 +0100 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2017-08-23 12:09:18 +0200 |
commit | 70cc81edc08d2ae42414d609dac87e7db8da456d (patch) | |
tree | ce105c2996d868c796394c434424df1995ef9dce /drivers/irqchip | |
parent | irqchip/gic-v3-its: Rework LPI freeing (diff) | |
download | linux-70cc81edc08d2ae42414d609dac87e7db8da456d.tar.xz linux-70cc81edc08d2ae42414d609dac87e7db8da456d.zip |
irqchip/gic-v3-its: Generalize device table allocation
As we want to use 2-level tables for VCPUs, let's hack the device
table allocator in order to make it slightly more generic. It
will get reused in subsequent patches.
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 71d71f757a17..15a007f98253 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1392,26 +1392,19 @@ static struct its_baser *its_get_baser(struct its_node *its, u32 type) return NULL; } -static bool its_alloc_device_table(struct its_node *its, u32 dev_id) +static bool its_alloc_table_entry(struct its_baser *baser, u32 id) { - struct its_baser *baser; struct page *page; u32 esz, idx; __le64 *table; - baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE); - - /* Don't allow device id that exceeds ITS hardware limit */ - if (!baser) - return (ilog2(dev_id) < its->device_ids); - /* Don't allow device id that exceeds single, flat table limit */ esz = GITS_BASER_ENTRY_SIZE(baser->val); if (!(baser->val & GITS_BASER_INDIRECT)) - return (dev_id < (PAGE_ORDER_TO_SIZE(baser->order) / esz)); + return (id < (PAGE_ORDER_TO_SIZE(baser->order) / esz)); /* Compute 1st level table index & check if that exceeds table limit */ - idx = dev_id >> ilog2(baser->psz / esz); + idx = id >> ilog2(baser->psz / esz); if (idx >= (PAGE_ORDER_TO_SIZE(baser->order) / GITS_LVL1_ENTRY_SIZE)) return false; @@ -1440,6 +1433,19 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id) return true; } +static bool its_alloc_device_table(struct its_node *its, u32 dev_id) +{ + struct its_baser *baser; + + baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE); + + /* Don't allow device id that exceeds ITS hardware limit */ + if (!baser) + return (ilog2(dev_id) < its->device_ids); + + return its_alloc_table_entry(baser, dev_id); +} + static struct its_device *its_create_device(struct its_node *its, u32 dev_id, int nvecs) { |