diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-03 18:33:15 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-03 18:33:15 -0800 | 
| commit | d2bea739f8b41d620c235d81e00289d01169dc3c (patch) | |
| tree | 1a56f84a34a9642e19cc01caa34d343691f34f3e /drivers/clocksource | |
| parent | 53528695ff6d8b77011bc818407c13e30914a946 (diff) | |
| parent | 4faefda97bc1be6ca909ba0fd0927ea78f37f67e (diff) | |
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 apic changes from Ingo Molnar:
 "The main changes in this cycle were:
   - Numachip updates: new hardware support, fixes and cleanups.
     (Daniel J Blueman)
   - misc smaller cleanups and fixlets"
* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/io_apic: Make eoi_ioapic_pin() static
  x86/irq: Drop unlikely before IS_ERR_OR_NULL
  x86/x2apic: Make stub functions available even if !CONFIG_X86_LOCAL_APIC
  x86/apic: Deinline various functions
  x86/numachip: Fix timer build conflict
  x86/numachip: Introduce Numachip2 timer mechanisms
  x86/numachip: Add Numachip IPI optimisations
  x86/numachip: Add Numachip2 APIC support
  x86/numachip: Cleanup Numachip support
Diffstat (limited to 'drivers/clocksource')
| -rw-r--r-- | drivers/clocksource/Makefile | 1 | ||||
| -rw-r--r-- | drivers/clocksource/numachip.c | 95 | 
2 files changed, 96 insertions, 0 deletions
| diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index fc9348dc4f92..67bc996ca909 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -63,3 +63,4 @@ obj-$(CONFIG_H8300)			+= h8300_timer8.o  obj-$(CONFIG_H8300_TMR16)		+= h8300_timer16.o  obj-$(CONFIG_H8300_TPU)			+= h8300_tpu.o  obj-$(CONFIG_CLKSRC_ST_LPC)		+= clksrc_st_lpc.o +obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o diff --git a/drivers/clocksource/numachip.c b/drivers/clocksource/numachip.c new file mode 100644 index 000000000000..4e0f11fd2617 --- /dev/null +++ b/drivers/clocksource/numachip.c @@ -0,0 +1,95 @@ +/* + * + * Copyright (C) 2015 Numascale AS. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + */ + +#include <linux/clockchips.h> + +#include <asm/irq.h> +#include <asm/numachip/numachip.h> +#include <asm/numachip/numachip_csr.h> + +static DEFINE_PER_CPU(struct clock_event_device, numachip2_ced); + +static cycles_t numachip2_timer_read(struct clocksource *cs) +{ +	return numachip2_read64_lcsr(NUMACHIP2_TIMER_NOW); +} + +static struct clocksource numachip2_clocksource = { +	.name            = "numachip2", +	.rating          = 295, +	.read            = numachip2_timer_read, +	.mask            = CLOCKSOURCE_MASK(64), +	.flags           = CLOCK_SOURCE_IS_CONTINUOUS, +	.mult            = 1, +	.shift           = 0, +}; + +static int numachip2_set_next_event(unsigned long delta, struct clock_event_device *ced) +{ +	numachip2_write64_lcsr(NUMACHIP2_TIMER_DEADLINE + numachip2_timer(), +		delta); +	return 0; +} + +static struct clock_event_device numachip2_clockevent = { +	.name            = "numachip2", +	.rating          = 400, +	.set_next_event  = numachip2_set_next_event, +	.features        = CLOCK_EVT_FEAT_ONESHOT, +	.mult            = 1, +	.shift           = 0, +	.min_delta_ns    = 1250, +	.max_delta_ns    = LONG_MAX, +}; + +static void numachip_timer_interrupt(void) +{ +	struct clock_event_device *ced = this_cpu_ptr(&numachip2_ced); + +	ced->event_handler(ced); +} + +static __init void numachip_timer_each(struct work_struct *work) +{ +	unsigned local_apicid = __this_cpu_read(x86_cpu_to_apicid) & 0xff; +	struct clock_event_device *ced = this_cpu_ptr(&numachip2_ced); + +	/* Setup IPI vector to local core and relative timing mode */ +	numachip2_write64_lcsr(NUMACHIP2_TIMER_INT + numachip2_timer(), +		(3 << 22) | (X86_PLATFORM_IPI_VECTOR << 14) | +		(local_apicid << 6)); + +	*ced = numachip2_clockevent; +	ced->cpumask = cpumask_of(smp_processor_id()); +	clockevents_register_device(ced); +} + +static int __init numachip_timer_init(void) +{ +	if (numachip_system != 2) +		return -ENODEV; + +	/* Reset timer */ +	numachip2_write64_lcsr(NUMACHIP2_TIMER_RESET, 0); +	clocksource_register_hz(&numachip2_clocksource, NSEC_PER_SEC); + +	/* Setup per-cpu clockevents */ +	x86_platform_ipi_callback = numachip_timer_interrupt; +	schedule_on_each_cpu(&numachip_timer_each); + +	return 0; +} + +arch_initcall(numachip_timer_init); | 
