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

Commit a44eb870 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'clockevents/3.13' of git://git.linaro.org/people/dlezcano/linux into timers/core



Pull ARM clocksource/clockevents updates from Daniel Lezcano:

  * Will Deacon and Sudeep KarkadaNagesha implemented the event stream
    for architected timer. The event streams can be used to impose a
    timeout on a wfe, to safeguard against any programming error in case
    an expected event is not generated or even to implement wfe-based
    timeouts for userspace locking implementations. Some files fall
    under the arm maintainers' umbrella but those changes have been
    reviewed and acked by the relevant people (Catalin Marinas and Olof
    Johansson).

  * Boris Brezillon improved the tcb_clksrc driver by removing a
    deprecated flag, checking return code values and using functions
    from the common clock framework.

Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 68e90740 f51380a7
Loading
Loading
Loading
Loading
+31 −5
Original line number Diff line number Diff line
@@ -87,17 +87,43 @@ static inline u64 arch_counter_get_cntvct(void)
	return cval;
}

static inline void arch_counter_set_user_access(void)
static inline u32 arch_timer_get_cntkctl(void)
{
	u32 cntkctl;

	asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl));
	return cntkctl;
}

	/* disable user access to everything */
	cntkctl &= ~((3 << 8) | (7 << 0));

static inline void arch_timer_set_cntkctl(u32 cntkctl)
{
	asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
}

static inline void arch_counter_set_user_access(void)
{
	u32 cntkctl = arch_timer_get_cntkctl();

	/* Disable user access to both physical/virtual counters/timers */
	/* Also disable virtual event stream */
	cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
			| ARCH_TIMER_USR_VT_ACCESS_EN
			| ARCH_TIMER_VIRT_EVT_EN
			| ARCH_TIMER_USR_VCT_ACCESS_EN
			| ARCH_TIMER_USR_PCT_ACCESS_EN);
	arch_timer_set_cntkctl(cntkctl);
}

static inline void arch_timer_evtstrm_enable(int divider)
{
	u32 cntkctl = arch_timer_get_cntkctl();
	cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
	/* Set the divider and enable virtual event stream */
	cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
			| ARCH_TIMER_VIRT_EVT_EN;
	arch_timer_set_cntkctl(cntkctl);
	elf_hwcap |= HWCAP_EVTSTRM;
}

#endif

#endif
+1 −0
Original line number Diff line number Diff line
@@ -26,5 +26,6 @@
#define HWCAP_VFPD32	(1 << 19)	/* set if VFP has 32 regs (not 16) */
#define HWCAP_IDIV	(HWCAP_IDIVA | HWCAP_IDIVT)
#define HWCAP_LPAE	(1 << 20)
#define HWCAP_EVTSTRM	(1 << 21)

#endif /* _UAPI__ASMARM_HWCAP_H */
+1 −0
Original line number Diff line number Diff line
@@ -975,6 +975,7 @@ static const char *hwcap_str[] = {
	"idivt",
	"vfpd32",
	"lpae",
	"evtstrm",
	NULL
};

+36 −6
Original line number Diff line number Diff line
@@ -92,19 +92,49 @@ static inline u32 arch_timer_get_cntfrq(void)
	return val;
}

static inline void arch_counter_set_user_access(void)
static inline u32 arch_timer_get_cntkctl(void)
{
	u32 cntkctl;

	/* Disable user access to the timers and the physical counter. */
	asm volatile("mrs	%0, cntkctl_el1" : "=r" (cntkctl));
	cntkctl &= ~((3 << 8) | (1 << 0));
	return cntkctl;
}

	/* Enable user access to the virtual counter and frequency. */
	cntkctl |= (1 << 1);
static inline void arch_timer_set_cntkctl(u32 cntkctl)
{
	asm volatile("msr	cntkctl_el1, %0" : : "r" (cntkctl));
}

static inline void arch_counter_set_user_access(void)
{
	u32 cntkctl = arch_timer_get_cntkctl();

	/* Disable user access to the timers and the physical counter */
	/* Also disable virtual event stream */
	cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
			| ARCH_TIMER_USR_VT_ACCESS_EN
			| ARCH_TIMER_VIRT_EVT_EN
			| ARCH_TIMER_USR_PCT_ACCESS_EN);

	/* Enable user access to the virtual counter */
	cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;

	arch_timer_set_cntkctl(cntkctl);
}

static inline void arch_timer_evtstrm_enable(int divider)
{
	u32 cntkctl = arch_timer_get_cntkctl();
	cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
	/* Set the divider and enable virtual event stream */
	cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
			| ARCH_TIMER_VIRT_EVT_EN;
	arch_timer_set_cntkctl(cntkctl);
	elf_hwcap |= HWCAP_EVTSTRM;
#ifdef CONFIG_COMPAT
	compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
#endif
}

static inline u64 arch_counter_get_cntvct(void)
{
	u64 cval;
+6 −5
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#define COMPAT_HWCAP_IDIVA	(1 << 17)
#define COMPAT_HWCAP_IDIVT	(1 << 18)
#define COMPAT_HWCAP_IDIV	(COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT)
#define COMPAT_HWCAP_EVTSTRM	(1 << 21)

#ifndef __ASSEMBLY__
/*
@@ -37,11 +38,11 @@
 * instruction set this cpu supports.
 */
#define ELF_HWCAP		(elf_hwcap)
#define COMPAT_ELF_HWCAP	(COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\
				 COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\
				 COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\
				 COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
				 COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV)

#ifdef CONFIG_COMPAT
#define COMPAT_ELF_HWCAP	(compat_elf_hwcap)
extern unsigned int compat_elf_hwcap;
#endif

extern unsigned long elf_hwcap;
#endif
Loading