GICv3: Allow either G1S or G0 interrupts to be configured
authorYatharth Kochar <[email protected]>
Tue, 6 Sep 2016 10:48:05 +0000 (11:48 +0100)
committerYatharth Kochar <[email protected]>
Mon, 12 Sep 2016 15:19:08 +0000 (16:19 +0100)
Currently the GICv3 driver mandates that platform populate
both G1S and G0 interrupts. However, it is possible that a
given platform is not interested in both the groups and
just needs to specify either one of them.

This patch modifies the `gicv3_rdistif_init()` & `gicv3_distif_init()`
functions to allow either G1S or G0 interrupts to be configured.

Fixes ARM-software/tf-issues#400

Change-Id: I43572b0e08ae30bed5af9334f25d35bf439b0d2b

drivers/arm/gic/v3/gicv3_main.c

index d13e2c9c07a3c4630646178f8f4722f86ea59996..ac433725f71026400adb5df45a9750a5fbd78f78 100644 (file)
@@ -120,10 +120,12 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data)
  ******************************************************************************/
 void gicv3_distif_init(void)
 {
+       unsigned int bitmap = 0;
+
        assert(driver_data);
        assert(driver_data->gicd_base);
-       assert(driver_data->g1s_interrupt_array);
-       assert(driver_data->g0_interrupt_array);
+       assert(driver_data->g1s_interrupt_array ||
+              driver_data->g0_interrupt_array);
 
        assert(IS_IN_EL3());
 
@@ -146,21 +148,25 @@ void gicv3_distif_init(void)
        gicv3_spis_configure_defaults(driver_data->gicd_base);
 
        /* Configure the G1S SPIs */
-       gicv3_secure_spis_configure(driver_data->gicd_base,
+       if (driver_data->g1s_interrupt_array) {
+               gicv3_secure_spis_configure(driver_data->gicd_base,
                                        driver_data->g1s_interrupt_num,
                                        driver_data->g1s_interrupt_array,
                                        INTR_GROUP1S);
+               bitmap |= CTLR_ENABLE_G1S_BIT;
+       }
 
        /* Configure the G0 SPIs */
-       gicv3_secure_spis_configure(driver_data->gicd_base,
+       if (driver_data->g0_interrupt_array) {
+               gicv3_secure_spis_configure(driver_data->gicd_base,
                                        driver_data->g0_interrupt_num,
                                        driver_data->g0_interrupt_array,
                                        INTR_GROUP0);
+               bitmap |= CTLR_ENABLE_G0_BIT;
+       }
 
        /* Enable the secure SPIs now that they have been configured */
-       gicd_set_ctlr(driver_data->gicd_base,
-                     CTLR_ENABLE_G1S_BIT | CTLR_ENABLE_G0_BIT,
-                     RWP_TRUE);
+       gicd_set_ctlr(driver_data->gicd_base, bitmap, RWP_TRUE);
 }
 
 /*******************************************************************************
@@ -177,8 +183,8 @@ void gicv3_rdistif_init(unsigned int proc_num)
        assert(driver_data->rdistif_base_addrs);
        assert(driver_data->gicd_base);
        assert(gicd_read_ctlr(driver_data->gicd_base) & CTLR_ARE_S_BIT);
-       assert(driver_data->g1s_interrupt_array);
-       assert(driver_data->g0_interrupt_array);
+       assert(driver_data->g1s_interrupt_array ||
+              driver_data->g0_interrupt_array);
 
        assert(IS_IN_EL3());
 
@@ -188,16 +194,20 @@ void gicv3_rdistif_init(unsigned int proc_num)
        gicv3_ppi_sgi_configure_defaults(gicr_base);
 
        /* Configure the G1S SGIs/PPIs */
-       gicv3_secure_ppi_sgi_configure(gicr_base,
-                                          driver_data->g1s_interrupt_num,
-                                          driver_data->g1s_interrupt_array,
-                                          INTR_GROUP1S);
+       if (driver_data->g1s_interrupt_array) {
+               gicv3_secure_ppi_sgi_configure(gicr_base,
+                                       driver_data->g1s_interrupt_num,
+                                       driver_data->g1s_interrupt_array,
+                                       INTR_GROUP1S);
+       }
 
        /* Configure the G0 SGIs/PPIs */
-       gicv3_secure_ppi_sgi_configure(gicr_base,
-                                          driver_data->g0_interrupt_num,
-                                          driver_data->g0_interrupt_array,
-                                          INTR_GROUP0);
+       if (driver_data->g0_interrupt_array) {
+               gicv3_secure_ppi_sgi_configure(gicr_base,
+                                       driver_data->g0_interrupt_num,
+                                       driver_data->g0_interrupt_array,
+                                       INTR_GROUP0);
+       }
 }
 
 /*******************************************************************************