@@ -1496,6 +1496,10 @@ int __init its_init(struct rdist_prop *rdists)
its_alloc_lpi_tables();
its_lpi_init(rdists->id_bits);
+ /* Allocate irq descriptors for LPIs */
+ if ( init_lpi() )
+ return -ENOMEM;
+
its = list_first_entry(&its_nodes, struct its_node, entry);
/*
* As per vITS design spec, Xen exposes only one virtual ITS per domain.
@@ -31,6 +31,8 @@
static unsigned int local_irqs_type[NR_LOCAL_IRQS];
static DEFINE_SPINLOCK(local_irqs_type_lock);
+static irq_desc_t *irq_desc_lpi;
+
/* Describe an IRQ assigned to a guest */
struct irq_guest
{
@@ -61,7 +63,15 @@ static DEFINE_PER_CPU(irq_desc_t[NR_LOCAL_IRQS], local_irq_desc);
irq_desc_t *__irq_to_desc(int irq)
{
if (irq < NR_LOCAL_IRQS) return &this_cpu(local_irq_desc)[irq];
- return &irq_desc[irq-NR_LOCAL_IRQS];
+ else if ( gic_is_lpi(irq) )
+ {
+ ASSERT(irq_desc_lpi != NULL);
+ return &irq_desc_lpi[irq - FIRST_GIC_LPI];
+ }
+ else
+ return &irq_desc[irq - NR_LOCAL_IRQS];
+
+ return NULL;
}
int __init arch_init_one_irq_desc(struct irq_desc *desc)
@@ -111,6 +121,31 @@ static int init_local_irq_data(void)
return 0;
}
+int init_lpi(void)
+{
+ struct irq_desc *desc;
+ unsigned int i, nr_lpis;
+
+ nr_lpis = gic_nr_irq_ids() - FIRST_GIC_LPI;
+ ASSERT(nr_lpis >= 0);
+
+ /* Allocate LPI irq descriptors */
+ irq_desc_lpi = xzalloc_array(struct irq_desc, nr_lpis);
+ if ( !irq_desc_lpi )
+ return -ENOMEM;
+
+ for ( i = 0; i < nr_lpis; i++ )
+ {
+ desc = &irq_desc_lpi[i];
+ init_one_irq_desc(desc);
+ desc->irq = FIRST_GIC_LPI + i;
+ desc->arch.type = DT_IRQ_TYPE_EDGE_BOTH;
+ desc->action = NULL;
+ }
+
+ return 0;
+}
+
void __init init_IRQ(void)
{
int irq;
@@ -65,6 +65,7 @@ int platform_get_irq(const struct dt_device_node *device, int index);
void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask);
void irq_set_msi_desc(struct irq_desc *desc, struct msi_desc *msi);
struct msi_desc *irq_get_msi_desc(struct irq_desc *desc);
+int init_lpi(void);
#endif /* _ASM_HW_IRQ_H */
/*