debuggers.hg

changeset 21031:82661c9ad896

ACPI S3: fix S3 resume fail on system w/ msi capable hpet

Don't re-allocate memory for irq_channel which will cause a BUG_ON in
hpet_msi_write, and make sure hpet_setup_msi_irq() executed during S3
resuming.

Signed-off-by: Wei Gang <gang.wei@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Feb 26 14:05:32 2010 +0000 (2010-02-26)
parents bb7164fc680a
children 6aa9fb913044
files xen/arch/x86/hpet.c
line diff
     1.1 --- a/xen/arch/x86/hpet.c	Fri Feb 26 08:13:02 2010 +0000
     1.2 +++ b/xen/arch/x86/hpet.c	Fri Feb 26 14:05:32 2010 +0000
     1.3 @@ -39,11 +39,12 @@ struct hpet_event_channel
     1.4  
     1.5      unsigned int idx;   /* physical channel idx */
     1.6      int cpu;            /* msi target */
     1.7 -    unsigned int irq;/* msi irq */
     1.8 +    int irq;            /* msi irq */
     1.9      unsigned int flags; /* HPET_EVT_x */
    1.10  } __cacheline_aligned;
    1.11  static struct hpet_event_channel legacy_hpet_event;
    1.12 -static struct hpet_event_channel hpet_events[MAX_HPET_NUM];
    1.13 +static struct hpet_event_channel hpet_events[MAX_HPET_NUM] = 
    1.14 +    { [0 ... MAX_HPET_NUM-1].irq = -1 };
    1.15  static unsigned int num_hpets_used; /* msi hpet channels used for broadcast */
    1.16  
    1.17  DEFINE_PER_CPU(struct hpet_event_channel *, cpu_bc_channel);
    1.18 @@ -353,24 +354,26 @@ static int hpet_setup_msi_irq(unsigned i
    1.19  
    1.20  static int hpet_assign_irq(struct hpet_event_channel *ch)
    1.21  {
    1.22 -    int irq;
    1.23 -
    1.24 -    if ( ch->irq )
    1.25 -        return 0;
    1.26 +    int irq = ch->irq;
    1.27  
    1.28 -    if ( (irq = create_irq()) < 0 )
    1.29 -        return irq;
    1.30 +    if ( irq < 0 )
    1.31 +    {
    1.32 +        if ( (irq = create_irq()) < 0 )
    1.33 +            return irq;
    1.34  
    1.35 -    irq_channel[irq] = ch - &hpet_events[0];
    1.36 +        irq_channel[irq] = ch - &hpet_events[0];
    1.37 +        ch->irq = irq;
    1.38 +    }
    1.39  
    1.40 +    /* hpet_setup_msi_irq should also be called for S3 resuming */
    1.41      if ( hpet_setup_msi_irq(irq) )
    1.42      {
    1.43          destroy_irq(irq);
    1.44          irq_channel[irq] = -1;
    1.45 +        ch->irq = -1;
    1.46          return -EINVAL;
    1.47      }
    1.48  
    1.49 -    ch->irq = irq;
    1.50      return 0;
    1.51  }
    1.52  
    1.53 @@ -532,10 +535,13 @@ void hpet_broadcast_init(void)
    1.54      u32 hpet_id, cfg;
    1.55      int i;
    1.56  
    1.57 -    irq_channel= xmalloc_array(int, nr_irqs);
    1.58 -    BUG_ON(!irq_channel);
    1.59 -    for (i = 0; i < nr_irqs ; i++)
    1.60 -        irq_channel[i] = -1;
    1.61 +    if ( irq_channel == NULL )
    1.62 +    {
    1.63 +        irq_channel = xmalloc_array(int, nr_irqs);
    1.64 +        BUG_ON(irq_channel == NULL);
    1.65 +        for ( i = 0; i < nr_irqs; i++ )
    1.66 +            irq_channel[i] = -1;
    1.67 +    }
    1.68  
    1.69      hpet_rate = hpet_setup();
    1.70      if ( hpet_rate == 0 )