forked from Minki/linux
MIPS: Refactor GIC clocksource code.
Reorganize some of the GIC clocksource driver code. Below is a list of the various changes. * No longer select CSRC_GIC by default for Malta platform. * Limit choice for either the GIC or R4K clocksource, not both. * Change location in Makefile. * Created new 'gic_read_count' function in common 'irq-gic.c' file. * Change 'git_hpt_read' function in 'csrc-gic.c' to use new function. * Surround GIC specific code in Malta platform code with #ifdef's. * Only initialize the GIC clocksource if it was selected. Original code called it unconditionally if a GIC was found. Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
This commit is contained in:
parent
28ea215186
commit
dfa762e1c3
@ -337,6 +337,7 @@ config MIPS_SEAD3
|
|||||||
select BOOT_RAW
|
select BOOT_RAW
|
||||||
select CEVT_R4K
|
select CEVT_R4K
|
||||||
select CSRC_R4K
|
select CSRC_R4K
|
||||||
|
select CSRC_GIC
|
||||||
select CPU_MIPSR2_IRQ_VI
|
select CPU_MIPSR2_IRQ_VI
|
||||||
select CPU_MIPSR2_IRQ_EI
|
select CPU_MIPSR2_IRQ_EI
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
|
@ -359,6 +359,9 @@ struct gic_shared_intr_map {
|
|||||||
/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
|
/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
|
||||||
#define GIC_PIN_TO_VEC_OFFSET (1)
|
#define GIC_PIN_TO_VEC_OFFSET (1)
|
||||||
|
|
||||||
|
#include <linux/clocksource.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
|
||||||
extern unsigned int gic_present;
|
extern unsigned int gic_present;
|
||||||
extern unsigned int gic_frequency;
|
extern unsigned int gic_frequency;
|
||||||
extern unsigned long _gic_base;
|
extern unsigned long _gic_base;
|
||||||
@ -372,6 +375,7 @@ extern void gic_init(unsigned long gic_base_addr,
|
|||||||
|
|
||||||
extern void gic_clocksource_init(unsigned int);
|
extern void gic_clocksource_init(unsigned int);
|
||||||
extern unsigned int gic_get_int(void);
|
extern unsigned int gic_get_int(void);
|
||||||
|
extern cycle_t gic_read_count(void);
|
||||||
extern void gic_send_ipi(unsigned int intr);
|
extern void gic_send_ipi(unsigned int intr);
|
||||||
extern unsigned int plat_ipi_call_int_xlate(unsigned int);
|
extern unsigned int plat_ipi_call_int_xlate(unsigned int);
|
||||||
extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
|
extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
|
||||||
|
@ -23,11 +23,11 @@ obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
|
|||||||
obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
|
obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
|
||||||
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
|
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
|
||||||
obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
|
obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
|
||||||
|
obj-$(CONFIG_CSRC_GIC) += csrc-gic.o
|
||||||
obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
|
obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
|
||||||
obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o
|
obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o
|
||||||
obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
|
obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
|
||||||
obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
|
obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
|
||||||
obj-$(CONFIG_CSRC_GIC) += csrc-gic.o
|
|
||||||
obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
|
obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
|
||||||
|
|
||||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||||
|
@ -5,23 +5,14 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#include <linux/clocksource.h>
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/time.h>
|
||||||
|
|
||||||
#include <asm/time.h>
|
|
||||||
#include <asm/gic.h>
|
#include <asm/gic.h>
|
||||||
|
|
||||||
static cycle_t gic_hpt_read(struct clocksource *cs)
|
static cycle_t gic_hpt_read(struct clocksource *cs)
|
||||||
{
|
{
|
||||||
unsigned int hi, hi2, lo;
|
return gic_read_count();
|
||||||
|
|
||||||
do {
|
|
||||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi);
|
|
||||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo);
|
|
||||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2);
|
|
||||||
} while (hi2 != hi);
|
|
||||||
|
|
||||||
return (((cycle_t) hi) << 32) + lo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct clocksource gic_clocksource = {
|
static struct clocksource gic_clocksource = {
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
#include <linux/clocksource.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/gic.h>
|
#include <asm/gic.h>
|
||||||
@ -32,6 +33,21 @@ static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
|
|||||||
static struct gic_pending_regs pending_regs[NR_CPUS];
|
static struct gic_pending_regs pending_regs[NR_CPUS];
|
||||||
static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
|
static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
|
||||||
|
|
||||||
|
#ifdef CONFIG_CSRC_GIC
|
||||||
|
cycle_t gic_read_count(void)
|
||||||
|
{
|
||||||
|
unsigned int hi, hi2, lo;
|
||||||
|
|
||||||
|
do {
|
||||||
|
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi);
|
||||||
|
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo);
|
||||||
|
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2);
|
||||||
|
} while (hi2 != hi);
|
||||||
|
|
||||||
|
return (((cycle_t) hi) << 32) + lo;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned int gic_get_timer_pending(void)
|
unsigned int gic_get_timer_pending(void)
|
||||||
{
|
{
|
||||||
unsigned int vpe_pending;
|
unsigned int vpe_pending;
|
||||||
|
@ -71,7 +71,9 @@ static void __init estimate_frequencies(void)
|
|||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int count, start;
|
unsigned int count, start;
|
||||||
|
#ifdef CONFIG_IRQ_GIC
|
||||||
unsigned int giccount = 0, gicstart = 0;
|
unsigned int giccount = 0, gicstart = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
|
||||||
@ -81,26 +83,32 @@ static void __init estimate_frequencies(void)
|
|||||||
|
|
||||||
/* Initialize counters. */
|
/* Initialize counters. */
|
||||||
start = read_c0_count();
|
start = read_c0_count();
|
||||||
|
#ifdef CONFIG_IRQ_GIC
|
||||||
if (gic_present)
|
if (gic_present)
|
||||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart);
|
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Read counter exactly on falling edge of update flag. */
|
/* Read counter exactly on falling edge of update flag. */
|
||||||
while (CMOS_READ(RTC_REG_A) & RTC_UIP);
|
while (CMOS_READ(RTC_REG_A) & RTC_UIP);
|
||||||
while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
|
while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
|
||||||
|
|
||||||
count = read_c0_count();
|
count = read_c0_count();
|
||||||
|
#ifdef CONFIG_IRQ_GIC
|
||||||
if (gic_present)
|
if (gic_present)
|
||||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount);
|
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount);
|
||||||
|
#endif
|
||||||
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
count -= start;
|
count -= start;
|
||||||
if (gic_present)
|
|
||||||
giccount -= gicstart;
|
|
||||||
|
|
||||||
mips_hpt_frequency = count;
|
mips_hpt_frequency = count;
|
||||||
if (gic_present)
|
|
||||||
|
#ifdef CONFIG_IRQ_GIC
|
||||||
|
if (gic_present) {
|
||||||
|
giccount -= gicstart;
|
||||||
gic_frequency = giccount;
|
gic_frequency = giccount;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_persistent_clock(struct timespec *ts)
|
void read_persistent_clock(struct timespec *ts)
|
||||||
@ -156,24 +164,27 @@ void __init plat_time_init(void)
|
|||||||
(prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
|
(prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
|
||||||
freq *= 2;
|
freq *= 2;
|
||||||
freq = freqround(freq, 5000);
|
freq = freqround(freq, 5000);
|
||||||
pr_debug("CPU frequency %d.%02d MHz\n", freq/1000000,
|
printk("CPU frequency %d.%02d MHz\n", freq/1000000,
|
||||||
(freq%1000000)*100/1000000);
|
(freq%1000000)*100/1000000);
|
||||||
cpu_khz = freq / 1000;
|
cpu_khz = freq / 1000;
|
||||||
|
|
||||||
if (gic_present) {
|
mips_scroll_message();
|
||||||
freq = freqround(gic_frequency, 5000);
|
|
||||||
pr_debug("GIC frequency %d.%02d MHz\n", freq/1000000,
|
|
||||||
(freq%1000000)*100/1000000);
|
|
||||||
gic_clocksource_init(gic_frequency);
|
|
||||||
} else
|
|
||||||
init_r4k_clocksource();
|
|
||||||
|
|
||||||
#ifdef CONFIG_I8253
|
#ifdef CONFIG_I8253
|
||||||
/* Only Malta has a PIT. */
|
/* Only Malta has a PIT. */
|
||||||
setup_pit_timer();
|
setup_pit_timer();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mips_scroll_message();
|
#ifdef CONFIG_IRQ_GIC
|
||||||
|
if (gic_present) {
|
||||||
|
freq = freqround(gic_frequency, 5000);
|
||||||
|
printk("GIC frequency %d.%02d MHz\n", freq/1000000,
|
||||||
|
(freq%1000000)*100/1000000);
|
||||||
|
#ifdef CONFIG_CSRC_GIC
|
||||||
|
gic_clocksource_init(gic_frequency);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
plat_perf_setup();
|
plat_perf_setup();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user