Frediano, Zoltan,

On Thu, 2015-03-19 at 19:29 +0000, Julien Grall wrote:
>     Note that the HIP04 GIC driver has not been modified because I don't
>     have a platform where I can test my changes. Although, the code is
>     still building.
> 
>     I let the Hisilicon guys (Frediano and Zoltan) providing a suitable
>     patch for there platform.

Are you going to provide an update for the hip04 driver for this change?

>     Meanwhile, I think it can go upstream as it has been acked by both
>     Ian and Stefano.
> 
>     Changes in v4:
>         - Rebase on the latest staging (no functional changes)
>         - Add Ian and Stefano's ack
>         - Typo in the commit message
> 
>     Changes in v3:
>         - Patch was previously sent in a separate series [1]
>         - Reorder the function to avoid forward declaration
>         - Make gic-v3 driver compliant to the new interface
>         - Remove spurious field addition in gicv2 structure
> 
>     Changelog based on the separate series:
> 
>     Changes in v3:
>         - Patch added.
> 
>     [1] https://patches.linaro.org/33313/
> ---
>  xen/arch/arm/gic-v2.c     | 70 ++++++++++++++++++++++---------------------
>  xen/arch/arm/gic-v3.c     | 75 
> ++++++++++++++++++++++++-----------------------
>  xen/arch/arm/gic.c        | 16 ++++++++--
>  xen/arch/arm/setup.c      |  3 +-
>  xen/include/asm-arm/gic.h |  8 +++++
>  5 files changed, 100 insertions(+), 72 deletions(-)
> 
> diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
> index 20cdbc9..3be4ad6 100644
> --- a/xen/arch/arm/gic-v2.c
> +++ b/xen/arch/arm/gic-v2.c
> @@ -674,37 +674,10 @@ static hw_irq_controller gicv2_guest_irq_type = {
>      .set_affinity = gicv2_irq_set_affinity,
>  };
>  
> -const static struct gic_hw_operations gicv2_ops = {
> -    .info                = &gicv2_info,
> -    .secondary_init      = gicv2_secondary_cpu_init,
> -    .save_state          = gicv2_save_state,
> -    .restore_state       = gicv2_restore_state,
> -    .dump_state          = gicv2_dump_state,
> -    .gicv_setup          = gicv2v_setup,
> -    .gic_host_irq_type   = &gicv2_host_irq_type,
> -    .gic_guest_irq_type  = &gicv2_guest_irq_type,
> -    .eoi_irq             = gicv2_eoi_irq,
> -    .deactivate_irq      = gicv2_dir_irq,
> -    .read_irq            = gicv2_read_irq,
> -    .set_irq_properties  = gicv2_set_irq_properties,
> -    .send_SGI            = gicv2_send_SGI,
> -    .disable_interface   = gicv2_disable_interface,
> -    .update_lr           = gicv2_update_lr,
> -    .update_hcr_status   = gicv2_hcr_status,
> -    .clear_lr            = gicv2_clear_lr,
> -    .read_lr             = gicv2_read_lr,
> -    .write_lr            = gicv2_write_lr,
> -    .read_vmcr_priority  = gicv2_read_vmcr_priority,
> -    .read_apr            = gicv2_read_apr,
> -    .make_dt_node        = gicv2_make_dt_node,
> -};
> -
> -/* Set up the GIC */
> -static int __init gicv2_init(struct dt_device_node *node, const void *data)
> +static int __init gicv2_init(void)
>  {
>      int res;
> -
> -    dt_device_set_used_by(node, DOMID_XEN);
> +    const struct dt_device_node *node = gicv2_info.node;
>  
>      res = dt_device_get_address(node, 0, &gicv2.dbase, NULL);
>      if ( res || !gicv2.dbase || (gicv2.dbase & ~PAGE_MASK) )
> @@ -727,9 +700,6 @@ static int __init gicv2_init(struct dt_device_node *node, 
> const void *data)
>          panic("GICv2: Cannot find the maintenance IRQ");
>      gicv2_info.maintenance_irq = res;
>  
> -    /* Set the GIC as the primary interrupt controller */
> -    dt_interrupt_controller = node;
> -
>      /* TODO: Add check on distributor, cpu size */
>  
>      printk("GICv2 initialization:\n"
> @@ -774,8 +744,42 @@ static int __init gicv2_init(struct dt_device_node 
> *node, const void *data)
>  
>      spin_unlock(&gicv2.lock);
>  
> +    return 0;
> +}
> +
> +const static struct gic_hw_operations gicv2_ops = {
> +    .info                = &gicv2_info,
> +    .init                = gicv2_init,
> +    .secondary_init      = gicv2_secondary_cpu_init,
> +    .save_state          = gicv2_save_state,
> +    .restore_state       = gicv2_restore_state,
> +    .dump_state          = gicv2_dump_state,
> +    .gicv_setup          = gicv2v_setup,
> +    .gic_host_irq_type   = &gicv2_host_irq_type,
> +    .gic_guest_irq_type  = &gicv2_guest_irq_type,
> +    .eoi_irq             = gicv2_eoi_irq,
> +    .deactivate_irq      = gicv2_dir_irq,
> +    .read_irq            = gicv2_read_irq,
> +    .set_irq_properties  = gicv2_set_irq_properties,
> +    .send_SGI            = gicv2_send_SGI,
> +    .disable_interface   = gicv2_disable_interface,
> +    .update_lr           = gicv2_update_lr,
> +    .update_hcr_status   = gicv2_hcr_status,
> +    .clear_lr            = gicv2_clear_lr,
> +    .read_lr             = gicv2_read_lr,
> +    .write_lr            = gicv2_write_lr,
> +    .read_vmcr_priority  = gicv2_read_vmcr_priority,
> +    .read_apr            = gicv2_read_apr,
> +    .make_dt_node        = gicv2_make_dt_node,
> +};
> +
> +/* Set up the GIC */
> +static int __init gicv2_preinit(struct dt_device_node *node, const void 
> *data)
> +{
>      gicv2_info.hw_version = GIC_V2;
> +    gicv2_info.node = node;
>      register_gic_ops(&gicv2_ops);
> +    dt_irq_xlate = gic_irq_xlate;
>  
>      return 0;
>  }
> @@ -788,7 +792,7 @@ static const struct dt_device_match gicv2_dt_match[] 
> __initconst =
>  
>  DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
>          .dt_match = gicv2_dt_match,
> -        .init = gicv2_init,
> +        .init = gicv2_preinit,
>  DT_DEVICE_END
>  
>  /*
> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
> index ab80670..48772f1 100644
> --- a/xen/arch/arm/gic-v3.c
> +++ b/xen/arch/arm/gic-v3.c
> @@ -1173,31 +1173,6 @@ static const hw_irq_controller gicv3_guest_irq_type = {
>      .set_affinity = gicv3_irq_set_affinity,
>  };
>  
> -static const struct gic_hw_operations gicv3_ops = {
> -    .info                = &gicv3_info,
> -    .save_state          = gicv3_save_state,
> -    .restore_state       = gicv3_restore_state,
> -    .dump_state          = gicv3_dump_state,
> -    .gicv_setup          = gicv_v3_init,
> -    .gic_host_irq_type   = &gicv3_host_irq_type,
> -    .gic_guest_irq_type  = &gicv3_guest_irq_type,
> -    .eoi_irq             = gicv3_eoi_irq,
> -    .deactivate_irq      = gicv3_dir_irq,
> -    .read_irq            = gicv3_read_irq,
> -    .set_irq_properties  = gicv3_set_irq_properties,
> -    .send_SGI            = gicv3_send_sgi,
> -    .disable_interface   = gicv3_disable_interface,
> -    .update_lr           = gicv3_update_lr,
> -    .update_hcr_status   = gicv3_hcr_status,
> -    .clear_lr            = gicv3_clear_lr,
> -    .read_lr             = gicv3_read_lr,
> -    .write_lr            = gicv3_write_lr,
> -    .read_vmcr_priority  = gicv3_read_vmcr_priority,
> -    .read_apr            = gicv3_read_apr,
> -    .secondary_init      = gicv3_secondary_cpu_init,
> -    .make_dt_node        = gicv3_make_dt_node,
> -};
> -
>  static int __init cmp_rdist(const void *a, const void *b)
>  {
>      const struct rdist_region *l = a, *r = a;
> @@ -1207,11 +1182,12 @@ static int __init cmp_rdist(const void *a, const void 
> *b)
>  }
>  
>  /* Set up the GIC */
> -static int __init gicv3_init(struct dt_device_node *node, const void *data)
> +static int __init gicv3_init(void)
>  {
>      struct rdist_region *rdist_regs;
>      int res, i;
>      uint32_t reg;
> +    const struct dt_device_node *node = gicv3_info.node;
>  
>      if ( !cpu_has_gicv3 )
>      {
> @@ -1219,8 +1195,6 @@ static int __init gicv3_init(struct dt_device_node 
> *node, const void *data)
>          return -ENODEV;
>      }
>  
> -    dt_device_set_used_by(node, DOMID_XEN);
> -
>      res = dt_device_get_address(node, 0, &gicv3.dbase, &gicv3.dbase_size);
>      if ( res || !gicv3.dbase )
>          panic("GICv3: Cannot find a valid distributor address");
> @@ -1274,9 +1248,6 @@ static int __init gicv3_init(struct dt_device_node 
> *node, const void *data)
>          panic("GICv3: Cannot find the maintenance IRQ");
>      gicv3_info.maintenance_irq = res;
>  
> -    /* Set the GIC as the primary interrupt controller */
> -    dt_interrupt_controller = node;
> -
>      for ( i = 0; i < gicv3.rdist_count; i++ )
>      {
>          /* map dbase & rdist regions */
> @@ -1311,15 +1282,47 @@ static int __init gicv3_init(struct dt_device_node 
> *node, const void *data)
>      res = gicv3_cpu_init();
>      gicv3_hyp_init();
>  
> -    gicv3_info.hw_version = GIC_V3;
> -    /* Register hw ops*/
> -    register_gic_ops(&gicv3_ops);
> -
>      spin_unlock(&gicv3.lock);
>  
>      return res;
>  }
>  
> +static const struct gic_hw_operations gicv3_ops = {
> +    .info                = &gicv3_info,
> +    .init                = gicv3_init,
> +    .save_state          = gicv3_save_state,
> +    .restore_state       = gicv3_restore_state,
> +    .dump_state          = gicv3_dump_state,
> +    .gicv_setup          = gicv_v3_init,
> +    .gic_host_irq_type   = &gicv3_host_irq_type,
> +    .gic_guest_irq_type  = &gicv3_guest_irq_type,
> +    .eoi_irq             = gicv3_eoi_irq,
> +    .deactivate_irq      = gicv3_dir_irq,
> +    .read_irq            = gicv3_read_irq,
> +    .set_irq_properties  = gicv3_set_irq_properties,
> +    .send_SGI            = gicv3_send_sgi,
> +    .disable_interface   = gicv3_disable_interface,
> +    .update_lr           = gicv3_update_lr,
> +    .update_hcr_status   = gicv3_hcr_status,
> +    .clear_lr            = gicv3_clear_lr,
> +    .read_lr             = gicv3_read_lr,
> +    .write_lr            = gicv3_write_lr,
> +    .read_vmcr_priority  = gicv3_read_vmcr_priority,
> +    .read_apr            = gicv3_read_apr,
> +    .secondary_init      = gicv3_secondary_cpu_init,
> +    .make_dt_node        = gicv3_make_dt_node,
> +};
> +
> +static int __init gicv3_preinit(struct dt_device_node *node, const void 
> *data)
> +{
> +    gicv3_info.hw_version = GIC_V3;
> +    gicv3_info.node = node;
> +    register_gic_ops(&gicv3_ops);
> +    dt_irq_xlate = gic_irq_xlate;
> +
> +    return 0;
> +}
> +
>  static const struct dt_device_match gicv3_dt_match[] __initconst =
>  {
>      DT_MATCH_GIC_V3,
> @@ -1328,7 +1331,7 @@ static const struct dt_device_match gicv3_dt_match[] 
> __initconst =
>  
>  DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
>          .dt_match = gicv3_dt_match,
> -        .init = gicv3_init,
> +        .init = gicv3_preinit,
>  DT_DEVICE_END
>  
>  /*
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 940fb8e..8e7f24b 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -163,8 +163,10 @@ int gic_irq_xlate(const u32 *intspec, unsigned int 
> intsize,
>      return 0;
>  }
>  
> -/* Set up the GIC */
> -void __init gic_init(void)
> +/* Find the interrupt controller and set up the callback to translate
> + * device tree IRQ.
> + */
> +void __init gic_preinit(void)
>  {
>      int rc;
>      struct dt_device_node *node;
> @@ -189,6 +191,16 @@ void __init gic_init(void)
>      if ( !num_gics )
>          panic("Unable to find compatible GIC in the device tree");
>  
> +    /* Set the GIC as the primary interrupt controller */
> +    dt_interrupt_controller = node;
> +    dt_device_set_used_by(node, DOMID_XEN);
> +}
> +
> +/* Set up the GIC */
> +void __init gic_init(void)
> +{
> +    if ( gic_hw_ops->init() )
> +        panic("Failed to initialize the GIC drivers");
>      /* Clear LR mask for cpu0 */
>      clear_cpu_lr_mask();
>  }
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index b905c9f..4f05f57 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -752,7 +752,6 @@ void __init start_xen(unsigned long boot_phys_offset,
>  
>      vm_init();
>      dt_unflatten_host_device_tree();
> -    dt_irq_xlate = gic_irq_xlate;
>  
>      init_IRQ();
>  
> @@ -760,6 +759,8 @@ void __init start_xen(unsigned long boot_phys_offset,
>  
>      preinit_xen_time();
>  
> +    gic_preinit();
> +
>      dt_uart_init();
>      console_init_preirq();
>      console_init_ring();
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index 89a9b6f..b16f98e 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -232,6 +232,10 @@ extern void gic_remove_from_queues(struct vcpu *v, 
> unsigned int virtual_irq);
>  
>  /* Accept an interrupt from the GIC and dispatch its handler */
>  extern void gic_interrupt(struct cpu_user_regs *regs, int is_fiq);
> +/* Find the interrupt controller and set up the callback to translate
> + * device tree IRQ.
> + */
> +extern void gic_preinit(void);
>  /* Bring up the interrupt controller, and report # cpus attached */
>  extern void gic_init(void);
>  /* Bring up a secondary CPU's per-CPU GIC interface */
> @@ -284,11 +288,15 @@ struct gic_info {
>      uint8_t nr_lrs;
>      /* Maintenance irq number */
>      unsigned int maintenance_irq;
> +    /* Pointer to the device tree node representing the interrupt controller 
> */
> +    const struct dt_device_node *node;
>  };
>  
>  struct gic_hw_operations {
>      /* Hold GIC HW information */
>      const struct gic_info *info;
> +    /* Initialize the GIC and the boot CPU */
> +    int (*init)(void);
>      /* Save GIC registers */
>      void (*save_state)(struct vcpu *);
>      /* Restore GIC registers */



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

Reply via email to