Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5325225 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'timers-fixes-for-linus' of...

Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  clocksource, acpi_pm.c: check for monotonicity
  clocksource, acpi_pm.c: use proper read function also in errata mode
  ntp: fix calculation of the next jiffie to trigger RTC sync
  x86: HPET: read back compare register before reading counter
  x86: HPET fix moronic 32/64bit thinko
  clockevents: broadcast fixup possible waiters
  HPET: make minimum reprogramming delta useful
  clockevents: prevent endless loop lockup
  clockevents: prevent multiple init/shutdown
  clockevents: enforce reprogram in oneshot setup
  clockevents: prevent endless loop in periodic broadcast handler
  clockevents: prevent clockevent event_handler ending up handler_noop
parents 4747832b 4ab6a219
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -210,8 +210,8 @@ static void hpet_legacy_clockevent_register(void)
	/* Calculate the min / max delta */
	hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
							   &hpet_clockevent);
	hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
							   &hpet_clockevent);
	/* 5 usec minimum reprogramming delta. */
	hpet_clockevent.min_delta_ns = 5000;

	/*
	 * Start hpet with the boot cpu mask and make it
@@ -272,13 +272,20 @@ static void hpet_legacy_set_mode(enum clock_event_mode mode,
static int hpet_legacy_next_event(unsigned long delta,
				  struct clock_event_device *evt)
{
	unsigned long cnt;
	u32 cnt;

	cnt = hpet_readl(HPET_COUNTER);
	cnt += delta;
	cnt += (u32) delta;
	hpet_writel(cnt, HPET_T0_CMP);

	return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0;
	/*
	 * We need to read back the CMP register to make sure that
	 * what we wrote hit the chip before we compare it to the
	 * counter.
	 */
	WARN_ON((u32)hpet_readl(HPET_T0_CMP) != cnt);

	return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
}

/*
+33 −21
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <asm/io.h>

/*
@@ -151,13 +152,13 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
 */
static int verify_pmtmr_rate(void)
{
	u32 value1, value2;
	cycle_t value1, value2;
	unsigned long count, delta;

	mach_prepare_counter();
	value1 = read_pmtmr();
	value1 = clocksource_acpi_pm.read();
	mach_countup(&count);
	value2 = read_pmtmr();
	value2 = clocksource_acpi_pm.read();
	delta = (value2 - value1) & ACPI_PM_MASK;

	/* Check that the PMTMR delta is within 5% of what we expect */
@@ -175,10 +176,13 @@ static int verify_pmtmr_rate(void)
#define verify_pmtmr_rate() (0)
#endif

/* Number of monotonicity checks to perform during initialization */
#define ACPI_PM_MONOTONICITY_CHECKS 10

static int __init init_acpi_pm_clocksource(void)
{
	u32 value1, value2;
	unsigned int i;
	cycle_t value1, value2;
	unsigned int i, j, good = 0;

	if (!pmtmr_ioport)
		return -ENODEV;
@@ -187,24 +191,32 @@ static int __init init_acpi_pm_clocksource(void)
						clocksource_acpi_pm.shift);

	/* "verify" this timing source: */
	value1 = read_pmtmr();
	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
		value1 = clocksource_acpi_pm.read();
		for (i = 0; i < 10000; i++) {
		value2 = read_pmtmr();
			value2 = clocksource_acpi_pm.read();
			if (value2 == value1)
				continue;
			if (value2 > value1)
			goto pm_good;
				good++;
				break;
			if ((value2 < value1) && ((value2) < 0xFFF))
			goto pm_good;
				good++;
				break;
			printk(KERN_INFO "PM-Timer had inconsistent results:"
			" 0x%#x, 0x%#x - aborting.\n", value1, value2);
			       " 0x%#llx, 0x%#llx - aborting.\n",
			       value1, value2);
			return -EINVAL;
		}
	printk(KERN_INFO "PM-Timer had no reasonable result:"
			" 0x%#x - aborting.\n", value1);
		udelay(300 * i);
	}

	if (good != ACPI_PM_MONOTONICITY_CHECKS) {
		printk(KERN_INFO "PM-Timer failed consistency check "
		       " (0x%#llx) - aborting.\n", value1);
		return -ENODEV;
	}

pm_good:
	if (verify_pmtmr_rate() != 0)
		return -ENODEV;

+2 −0
Original line number Diff line number Diff line
@@ -127,6 +127,8 @@ extern int clockevents_register_notifier(struct notifier_block *nb);
extern int clockevents_program_event(struct clock_event_device *dev,
				     ktime_t expires, ktime_t now);

extern void clockevents_handle_noop(struct clock_event_device *dev);

#ifdef CONFIG_GENERIC_CLOCKEVENTS
extern void clockevents_notify(unsigned long reason, void *arg);
#else
+1 −2
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ void clockevents_register_device(struct clock_event_device *dev)
/*
 * Noop handler when we shut down an event device
 */
static void clockevents_handle_noop(struct clock_event_device *dev)
void clockevents_handle_noop(struct clock_event_device *dev)
{
}

@@ -199,7 +199,6 @@ void clockevents_exchange_device(struct clock_event_device *old,
	 * released list and do a notify add later.
	 */
	if (old) {
		old->event_handler = clockevents_handle_noop;
		clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED);
		list_del(&old->list);
		list_add(&old->list, &clockevents_released);
+1 −1
Original line number Diff line number Diff line
@@ -245,7 +245,7 @@ static void sync_cmos_clock(unsigned long dummy)
	if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
		fail = update_persistent_clock(now);

	next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec;
	next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2);
	if (next.tv_nsec <= 0)
		next.tv_nsec += NSEC_PER_SEC;

Loading