Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 245927
Collapse All | Expand All

(-)linux-2.6.25-gentoo-r9.orig/kernel/time/tick-broadcast.c (-48 / +7 lines)
Lines 209-215 Link Here
209
	struct clock_event_device *bc, *dev;
209
	struct clock_event_device *bc, *dev;
210
	struct tick_device *td;
210
	struct tick_device *td;
211
	unsigned long flags, *reason = why;
211
	unsigned long flags, *reason = why;
212
	int cpu, bc_stopped;
212
	int cpu;
213
213
214
	spin_lock_irqsave(&tick_broadcast_lock, flags);
214
	spin_lock_irqsave(&tick_broadcast_lock, flags);
215
215
Lines 227-234 Link Here
227
	if (!tick_device_is_functional(dev))
227
	if (!tick_device_is_functional(dev))
228
		goto out;
228
		goto out;
229
229
230
	bc_stopped = cpus_empty(tick_broadcast_mask);
231
232
	switch (*reason) {
230
	switch (*reason) {
233
	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
231
	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
234
	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
232
	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
Lines 250-259 Link Here
250
		break;
248
		break;
251
	}
249
	}
252
250
253
	if (cpus_empty(tick_broadcast_mask)) {
251
	if (cpus_empty(tick_broadcast_mask))
254
		if (!bc_stopped)
252
		clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
255
			clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
253
	else {
256
	} else if (bc_stopped) {
257
		if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
254
		if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
258
			tick_broadcast_start_periodic(bc);
255
			tick_broadcast_start_periodic(bc);
259
		else
256
		else
Lines 490-541 Link Here
490
	cpu_clear(cpu, tick_broadcast_oneshot_mask);
487
	cpu_clear(cpu, tick_broadcast_oneshot_mask);
491
}
488
}
492
489
493
static void tick_broadcast_init_next_event(cpumask_t *mask, ktime_t expires)
494
{
495
	struct tick_device *td;
496
	int cpu;
497
498
	for_each_cpu_mask(cpu, *mask) {
499
		td = &per_cpu(tick_cpu_device, cpu);
500
		if (td->evtdev)
501
			td->evtdev->next_event = expires;
502
	}
503
}
504
505
/**
490
/**
506
 * tick_broadcast_setup_oneshot - setup the broadcast device
491
 * tick_broadcast_setup_oneshot - setup the broadcast device
507
 */
492
 */
508
void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
493
void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
509
{
494
{
510
	/* Set it up only once ! */
495
	bc->event_handler = tick_handle_oneshot_broadcast;
511
	if (bc->event_handler != tick_handle_oneshot_broadcast) {
496
	clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
512
		int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC;
497
	bc->next_event.tv64 = KTIME_MAX;
513
		int cpu = smp_processor_id();
514
		cpumask_t mask;
515
516
		bc->event_handler = tick_handle_oneshot_broadcast;
517
		clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
518
519
		/* Take the do_timer update */
520
		tick_do_timer_cpu = cpu;
521
522
		/*
523
		 * We must be careful here. There might be other CPUs
524
		 * waiting for periodic broadcast. We need to set the
525
		 * oneshot_mask bits for those and program the
526
		 * broadcast device to fire.
527
		 */
528
		mask = tick_broadcast_mask;
529
		cpu_clear(cpu, mask);
530
		cpus_or(tick_broadcast_oneshot_mask,
531
			tick_broadcast_oneshot_mask, mask);
532
533
		if (was_periodic && !cpus_empty(mask)) {
534
			tick_broadcast_init_next_event(&mask, tick_next_period);
535
			tick_broadcast_set_event(tick_next_period, 1);
536
		} else
537
			bc->next_event.tv64 = KTIME_MAX;
538
	}
539
}
498
}
540
499
541
/*
500
/*

Return to bug 245927