if ( hpet_assign_irq(ch) )
continue;
- /* set default irq affinity */
- ch->cpu = num_chs_used;
- per_cpu(cpu_bc_channel, ch->cpu) = ch;
- irq_desc[ch->irq].handler->
- set_affinity(ch->irq, cpumask_of_cpu(ch->cpu));
-
num_chs_used++;
-
- if ( num_chs_used == num_possible_cpus() )
- break;
}
printk(XENLOG_INFO
int next;
struct hpet_event_channel *ch;
+ if ( num_hpets_used == 0 )
+ return &legacy_hpet_event;
+
spin_lock(&next_lock);
next = next_channel = (next_channel + 1) % num_hpets_used;
spin_unlock(&next_lock);
return ch;
}
-static void hpet_attach_channel_share(int cpu, struct hpet_event_channel *ch)
+static void hpet_attach_channel(int cpu, struct hpet_event_channel *ch)
{
+ ASSERT(spin_is_locked(&ch->lock));
+
per_cpu(cpu_bc_channel, cpu) = ch;
/* try to be the channel owner again while holding the lock */
set_affinity(ch->irq, cpumask_of_cpu(ch->cpu));
}
-static void hpet_detach_channel_share(int cpu)
+static void hpet_detach_channel(int cpu, struct hpet_event_channel *ch)
{
- struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
+ ASSERT(spin_is_locked(&ch->lock));
+ ASSERT(ch == per_cpu(cpu_bc_channel, cpu));
per_cpu(cpu_bc_channel, cpu) = NULL;
set_affinity(ch->irq, cpumask_of_cpu(ch->cpu));
}
-static void (*hpet_attach_channel)(int cpu, struct hpet_event_channel *ch);
-static void (*hpet_detach_channel)(int cpu);
-
#include <asm/mc146818rtc.h>
void (*pv_rtc_handler)(unsigned int port, uint8_t value);
spin_lock_init(&hpet_events[i].lock);
}
- if ( num_hpets_used < num_possible_cpus() )
- {
- hpet_attach_channel = hpet_attach_channel_share;
- hpet_detach_channel = hpet_detach_channel_share;
- }
-
return;
}
legacy_hpet_event.flags = 0;
spin_lock_init(&legacy_hpet_event.lock);
- for_each_possible_cpu(i)
- per_cpu(cpu_bc_channel, i) = &legacy_hpet_event;
-
if ( !force_hpet_broadcast )
pv_rtc_handler = handle_rtc_once;
}
if ( !ch )
ch = hpet_get_channel(cpu);
- BUG_ON( !ch );
ASSERT(!local_irq_is_enabled());
- if ( hpet_attach_channel )
+ if ( ch != &legacy_hpet_event )
{
spin_lock(&ch->lock);
-
hpet_attach_channel(cpu, ch);
-
spin_unlock(&ch->lock);
}
if ( this_cpu(timer_deadline_start) == 0 )
return;
- BUG_ON( !ch );
-
/* Reprogram the deadline; trigger timer work now if it has passed. */
enable_APIC_timer();
if ( !reprogram_timer(this_cpu(timer_deadline_start)) )
spin_unlock_irq(&ch->lock);
-
- if ( hpet_detach_channel )
+ if ( ch != &legacy_hpet_event )
{
spin_lock_irq(&ch->lock);
-
- hpet_detach_channel(cpu);
-
+ hpet_detach_channel(cpu, ch);
spin_unlock_irq(&ch->lock);
}
}