mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-23 12:43:55 +08:00
62f082830d
The kernel uses l14 timers as clockevents. l10 timer is used as clocksource if platform master_l10_counter isn't constantly zero. The clocksource is continuous, so it's possible to use high resolution timers. l10 timer is also used as clockevent on UP configurations. This realization is for sun4m, sun4d, sun4c, microsparc-IIep and LEON platforms. The appropriate LEON changes was made by Konrad Eisele. In case of sun4m's oneshot mode, profile irq is zeroed in smp4m_percpu_timer_interrupt(). It is maybe needless (double, triple etc overflow does nothing). sun4d is able to have oneshot mode too, but I haven't any way to test it. So code of its percpu timer handler is made as much equal to the current code as possible. The patch is tested on sun4m box in SMP mode by me, and tested by Konrad on leon in up mode (leon smp is broken atm - due to other reasons). Signed-off-by: Tkhai Kirill <tkhai@yandex.ru> Tested-by: Konrad Eisele <konrad@gaisler.com> [leon up] [sam: revised patch to provide generic support for leon] Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
114 lines
3.2 KiB
C
114 lines
3.2 KiB
C
#include <linux/platform_device.h>
|
|
|
|
#include <asm/btfixup.h>
|
|
#include <asm/cpu_type.h>
|
|
|
|
struct irq_bucket {
|
|
struct irq_bucket *next;
|
|
unsigned int real_irq;
|
|
unsigned int irq;
|
|
unsigned int pil;
|
|
};
|
|
|
|
#define SUN4D_MAX_BOARD 10
|
|
#define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5)
|
|
|
|
/* Map between the irq identifier used in hw to the
|
|
* irq_bucket. The map is sufficient large to hold
|
|
* the sun4d hw identifiers.
|
|
*/
|
|
extern struct irq_bucket *irq_map[SUN4D_MAX_IRQ];
|
|
|
|
|
|
/* sun4m specific type definitions */
|
|
|
|
/* This maps direct to CPU specific interrupt registers */
|
|
struct sun4m_irq_percpu {
|
|
u32 pending;
|
|
u32 clear;
|
|
u32 set;
|
|
};
|
|
|
|
/* This maps direct to global interrupt registers */
|
|
struct sun4m_irq_global {
|
|
u32 pending;
|
|
u32 mask;
|
|
u32 mask_clear;
|
|
u32 mask_set;
|
|
u32 interrupt_target;
|
|
};
|
|
|
|
extern struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
|
|
extern struct sun4m_irq_global __iomem *sun4m_irq_global;
|
|
|
|
/* The following definitions describe the individual platform features: */
|
|
#define FEAT_L10_CLOCKSOURCE (1 << 0) /* L10 timer is used as a clocksource */
|
|
#define FEAT_L10_CLOCKEVENT (1 << 1) /* L10 timer is used as a clockevent */
|
|
#define FEAT_L14_ONESHOT (1 << 2) /* L14 timer clockevent can oneshot */
|
|
|
|
/*
|
|
* Platform specific configuration
|
|
* The individual platforms assign their platform
|
|
* specifics in their init functions.
|
|
*/
|
|
struct sparc_config {
|
|
void (*init_timers)(void);
|
|
unsigned int (*build_device_irq)(struct platform_device *op,
|
|
unsigned int real_irq);
|
|
|
|
/* generic clockevent features - see FEAT_* above */
|
|
int features;
|
|
|
|
/* clock rate used for clock event timer */
|
|
int clock_rate;
|
|
|
|
/* one period for clock source timer */
|
|
unsigned int cs_period;
|
|
|
|
/* function to obtain offsett for cs period */
|
|
unsigned int (*get_cycles_offset)(void);
|
|
};
|
|
extern struct sparc_config sparc_config;
|
|
|
|
unsigned int irq_alloc(unsigned int real_irq, unsigned int pil);
|
|
void irq_link(unsigned int irq);
|
|
void irq_unlink(unsigned int irq);
|
|
void handler_irq(unsigned int pil, struct pt_regs *regs);
|
|
|
|
/* Dave Redman (djhr@tadpole.co.uk)
|
|
* changed these to function pointers.. it saves cycles and will allow
|
|
* the irq dependencies to be split into different files at a later date
|
|
* sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size.
|
|
* Jakub Jelinek (jj@sunsite.mff.cuni.cz)
|
|
* Changed these to btfixup entities... It saves cycles :)
|
|
*/
|
|
|
|
BTFIXUPDEF_CALL(void, clear_clock_irq, void)
|
|
BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int)
|
|
|
|
static inline void clear_clock_irq(void)
|
|
{
|
|
BTFIXUP_CALL(clear_clock_irq)();
|
|
}
|
|
|
|
static inline void load_profile_irq(int cpu, int limit)
|
|
{
|
|
BTFIXUP_CALL(load_profile_irq)(cpu, limit);
|
|
}
|
|
|
|
#ifdef CONFIG_SMP
|
|
BTFIXUPDEF_CALL(void, set_cpu_int, int, int)
|
|
BTFIXUPDEF_CALL(void, clear_cpu_int, int, int)
|
|
BTFIXUPDEF_CALL(void, set_irq_udt, int)
|
|
|
|
#define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level)
|
|
#define clear_cpu_int(cpu,level) BTFIXUP_CALL(clear_cpu_int)(cpu,level)
|
|
#define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu)
|
|
|
|
/* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
|
|
#define SUN4D_IPI_IRQ 13
|
|
|
|
extern void sun4d_ipi_interrupt(void);
|
|
|
|
#endif
|