Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6: (28 commits) sparc32: fix build, fix missing cpu_relax declaration SCHED_TTWU_QUEUE is not longer needed since sparc32 now implements IPI sparc32,leon: Remove unnecessary page_address calls in LEON DMA API. sparc: convert old cpumask API into new one sparc32, sun4d: Implemented SMP IPIs support for SUN4D machines sparc32, sun4m: Implemented SMP IPIs support for SUN4M machines sparc32,leon: Implemented SMP IPIs for LEON CPU sparc32: implement SMP IPIs using the generic functions sparc32,leon: SMP power down implementation sparc32,leon: added some SMP comments sparc: add {read,write}*_be routines sparc32,leon: don't rely on bootloader to mask IRQs sparc32,leon: operate on boot-cpu IRQ controller registers sparc32: always define boot_cpu_id sparc32: removed unused code, implemented by generic code sparc32: avoid build warning at mm/percpu.c:1647 sparc32: always register a PROM based early console sparc32: probe for cpu info only during startup sparc: consolidate show_cpuinfo in cpu.c sparc32,leon: implement genirq CPU affinity ...
This commit is contained in:
@ -16,6 +16,10 @@ typedef struct {
|
||||
unsigned long clock_tick;
|
||||
unsigned int multiplier;
|
||||
unsigned int counter;
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned int irq_resched_count;
|
||||
unsigned int irq_call_count;
|
||||
#endif
|
||||
int prom_node;
|
||||
int mid;
|
||||
int next;
|
||||
@ -23,5 +27,6 @@ typedef struct {
|
||||
|
||||
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
|
||||
#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
|
||||
#define local_cpu_data() __get_cpu_var(__cpu_data)
|
||||
|
||||
#endif /* _SPARC_CPUDATA_H */
|
||||
|
@ -281,28 +281,27 @@ static inline void sun_fd_enable_dma(void)
|
||||
pdma_areasize = pdma_size;
|
||||
}
|
||||
|
||||
/* Our low-level entry point in arch/sparc/kernel/entry.S */
|
||||
extern int sparc_floppy_request_irq(int irq, unsigned long flags,
|
||||
irq_handler_t irq_handler);
|
||||
extern int sparc_floppy_request_irq(unsigned int irq,
|
||||
irq_handler_t irq_handler);
|
||||
|
||||
static int sun_fd_request_irq(void)
|
||||
{
|
||||
static int once = 0;
|
||||
int error;
|
||||
|
||||
if(!once) {
|
||||
if (!once) {
|
||||
once = 1;
|
||||
error = sparc_floppy_request_irq(FLOPPY_IRQ,
|
||||
IRQF_DISABLED,
|
||||
floppy_interrupt);
|
||||
return ((error == 0) ? 0 : -1);
|
||||
} else return 0;
|
||||
return sparc_floppy_request_irq(FLOPPY_IRQ, floppy_interrupt);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct linux_prom_registers fd_regs[2];
|
||||
|
||||
static int sun_floppy_init(void)
|
||||
{
|
||||
struct platform_device *op;
|
||||
struct device_node *dp;
|
||||
char state[128];
|
||||
phandle tnode, fd_node;
|
||||
int num_regs;
|
||||
@ -310,7 +309,6 @@ static int sun_floppy_init(void)
|
||||
|
||||
use_virtual_dma = 1;
|
||||
|
||||
FLOPPY_IRQ = 11;
|
||||
/* Forget it if we aren't on a machine that could possibly
|
||||
* ever have a floppy drive.
|
||||
*/
|
||||
@ -349,6 +347,26 @@ static int sun_floppy_init(void)
|
||||
sun_fdc = (struct sun_flpy_controller *)
|
||||
of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
|
||||
|
||||
/* Look up irq in platform_device.
|
||||
* We try "SUNW,fdtwo" and "fd"
|
||||
*/
|
||||
for_each_node_by_name(dp, "SUNW,fdtwo") {
|
||||
op = of_find_device_by_node(dp);
|
||||
if (op)
|
||||
break;
|
||||
}
|
||||
if (!op) {
|
||||
for_each_node_by_name(dp, "fd") {
|
||||
op = of_find_device_by_node(dp);
|
||||
if (op)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!op)
|
||||
goto no_sun_fdc;
|
||||
|
||||
FLOPPY_IRQ = op->archdata.irqs[0];
|
||||
|
||||
/* Last minute sanity check... */
|
||||
if(sun_fdc->status_82072 == 0xff) {
|
||||
sun_fdc = NULL;
|
||||
|
@ -5,4 +5,17 @@
|
||||
#else
|
||||
#include <asm/io_32.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Defines used for both SPARC32 and SPARC64
|
||||
*/
|
||||
|
||||
/* Big endian versions of memory read/write routines */
|
||||
#define readb_be(__addr) __raw_readb(__addr)
|
||||
#define readw_be(__addr) __raw_readw(__addr)
|
||||
#define readl_be(__addr) __raw_readl(__addr)
|
||||
#define writeb_be(__b, __addr) __raw_writeb(__b, __addr)
|
||||
#define writel_be(__w, __addr) __raw_writel(__w, __addr)
|
||||
#define writew_be(__l, __addr) __raw_writew(__l, __addr)
|
||||
|
||||
#endif
|
||||
|
@ -6,7 +6,11 @@
|
||||
#ifndef _SPARC_IRQ_H
|
||||
#define _SPARC_IRQ_H
|
||||
|
||||
#define NR_IRQS 16
|
||||
/* Allocated number of logical irq numbers.
|
||||
* sun4d boxes (ss2000e) should be OK with ~32.
|
||||
* Be on the safe side and make room for 64
|
||||
*/
|
||||
#define NR_IRQS 64
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
|
@ -52,29 +52,6 @@
|
||||
#define LEON_DIAGF_VALID 0x2000
|
||||
#define LEON_DIAGF_VALID_SHIFT 13
|
||||
|
||||
/*
|
||||
* Interrupt Sources
|
||||
*
|
||||
* The interrupt source numbers directly map to the trap type and to
|
||||
* the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask,
|
||||
* and the Interrupt Pending Registers.
|
||||
*/
|
||||
#define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR 1
|
||||
#define LEON_INTERRUPT_UART_1_RX_TX 2
|
||||
#define LEON_INTERRUPT_UART_0_RX_TX 3
|
||||
#define LEON_INTERRUPT_EXTERNAL_0 4
|
||||
#define LEON_INTERRUPT_EXTERNAL_1 5
|
||||
#define LEON_INTERRUPT_EXTERNAL_2 6
|
||||
#define LEON_INTERRUPT_EXTERNAL_3 7
|
||||
#define LEON_INTERRUPT_TIMER1 8
|
||||
#define LEON_INTERRUPT_TIMER2 9
|
||||
#define LEON_INTERRUPT_EMPTY1 10
|
||||
#define LEON_INTERRUPT_EMPTY2 11
|
||||
#define LEON_INTERRUPT_OPEN_ETH 12
|
||||
#define LEON_INTERRUPT_EMPTY4 13
|
||||
#define LEON_INTERRUPT_EMPTY5 14
|
||||
#define LEON_INTERRUPT_EMPTY6 15
|
||||
|
||||
/* irq masks */
|
||||
#define LEON_HARD_INT(x) (1 << (x)) /* irq 0-15 */
|
||||
#define LEON_IRQMASK_R 0x0000fffe /* bit 15- 1 of lregs.irqmask */
|
||||
@ -183,7 +160,6 @@ static inline void leon_srmmu_enabletlb(void)
|
||||
/* macro access for leon_readnobuffer_reg() */
|
||||
#define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x))
|
||||
|
||||
extern void sparc_leon_eirq_register(int eirq);
|
||||
extern void leon_init(void);
|
||||
extern void leon_switch_mm(void);
|
||||
extern void leon_init_IRQ(void);
|
||||
@ -239,8 +215,8 @@ static inline int sparc_leon3_cpuid(void)
|
||||
#endif /*!__ASSEMBLY__*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# define LEON3_IRQ_RESCHEDULE 13
|
||||
# define LEON3_IRQ_TICKER (leon_percpu_timer_dev[0].irq)
|
||||
# define LEON3_IRQ_IPI_DEFAULT 13
|
||||
# define LEON3_IRQ_TICKER (leon3_ticker_irq)
|
||||
# define LEON3_IRQ_CROSS_CALL 15
|
||||
#endif
|
||||
|
||||
@ -339,9 +315,9 @@ struct leon2_cacheregs {
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
struct device_node;
|
||||
extern int sparc_leon_eirq_get(int eirq, int cpu);
|
||||
extern irqreturn_t sparc_leon_eirq_isr(int dummy, void *dev_id);
|
||||
extern void sparc_leon_eirq_register(int eirq);
|
||||
extern unsigned int leon_build_device_irq(unsigned int real_irq,
|
||||
irq_flow_handler_t flow_handler,
|
||||
const char *name, int do_ack);
|
||||
extern void leon_clear_clock_irq(void);
|
||||
extern void leon_load_profile_irq(int cpu, unsigned int limit);
|
||||
extern void leon_init_timers(irq_handler_t counter_fn);
|
||||
@ -358,6 +334,7 @@ extern void leon3_getCacheRegs(struct leon3_cacheregs *regs);
|
||||
extern int leon_flush_needed(void);
|
||||
extern void leon_switch_mm(void);
|
||||
extern int srmmu_swprobe_trace;
|
||||
extern int leon3_ticker_irq;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern int leon_smp_nrcpus(void);
|
||||
@ -366,17 +343,19 @@ extern void leon_smp_done(void);
|
||||
extern void leon_boot_cpus(void);
|
||||
extern int leon_boot_one_cpu(int i);
|
||||
void leon_init_smp(void);
|
||||
extern void cpu_probe(void);
|
||||
extern void cpu_idle(void);
|
||||
extern void init_IRQ(void);
|
||||
extern void cpu_panic(void);
|
||||
extern int __leon_processor_id(void);
|
||||
void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu);
|
||||
extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused);
|
||||
|
||||
extern unsigned int real_irq_entry[], smpleon_ticker[];
|
||||
extern unsigned int real_irq_entry[];
|
||||
extern unsigned int smpleon_ipi[];
|
||||
extern unsigned int patchme_maybe_smp_msg[];
|
||||
extern unsigned int t_nmi[], linux_trap_ipi15_leon[];
|
||||
extern unsigned int linux_trap_ipi15_sun4m[];
|
||||
extern int leon_ipi_irq;
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
|
@ -29,11 +29,17 @@ struct linux_pcic {
|
||||
int pcic_imdim;
|
||||
};
|
||||
|
||||
extern int pcic_probe(void);
|
||||
/* Erm... MJ redefined pcibios_present() so that it does not work early. */
|
||||
#ifdef CONFIG_PCI
|
||||
extern int pcic_present(void);
|
||||
extern int pcic_probe(void);
|
||||
extern void pci_time_init(void);
|
||||
extern void sun4m_pci_init_IRQ(void);
|
||||
|
||||
#else
|
||||
static inline int pcic_present(void) { return 0; }
|
||||
static inline int pcic_probe(void) { return 0; }
|
||||
static inline void pci_time_init(void) {}
|
||||
static inline void sun4m_pci_init_IRQ(void) {}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Size of PCI I/O space which we relocate. */
|
||||
|
@ -8,6 +8,8 @@
|
||||
* Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
|
||||
*/
|
||||
|
||||
#include <linux/const.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm-generic/4level-fixup.h>
|
||||
|
||||
@ -456,9 +458,9 @@ extern int io_remap_pfn_range(struct vm_area_struct *vma,
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#define VMALLOC_START 0xfe600000
|
||||
#define VMALLOC_START _AC(0xfe600000,UL)
|
||||
/* XXX Alter this when I get around to fixing sun4c - Anton */
|
||||
#define VMALLOC_END 0xffc00000
|
||||
#define VMALLOC_END _AC(0xffc00000,UL)
|
||||
|
||||
|
||||
/* We provide our own get_unmapped_area to cope with VA holes for userland */
|
||||
|
@ -699,6 +699,9 @@ extern pmd_t swapper_low_pmd_dir[2048];
|
||||
extern void paging_init(void);
|
||||
extern unsigned long find_ecache_flush_span(unsigned long size);
|
||||
|
||||
struct seq_file;
|
||||
extern void mmu_info(struct seq_file *);
|
||||
|
||||
/* These do nothing with the way I have things setup. */
|
||||
#define mmu_lockarea(vaddr, len) (vaddr)
|
||||
#define mmu_unlockarea(vaddr, len) do { } while(0)
|
||||
|
@ -11,4 +11,16 @@
|
||||
# define COMMAND_LINE_SIZE 256
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifdef CONFIG_SPARC32
|
||||
/* The CPU that was used for booting
|
||||
* Only sun4d + leon may have boot_cpu_id != 0
|
||||
*/
|
||||
extern unsigned char boot_cpu_id;
|
||||
extern unsigned char boot_cpu_id4;
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _SPARC_SETUP_H */
|
||||
|
@ -50,42 +50,38 @@ void smp_callin(void);
|
||||
void smp_boot_cpus(void);
|
||||
void smp_store_cpu_info(int);
|
||||
|
||||
void smp_resched_interrupt(void);
|
||||
void smp_call_function_single_interrupt(void);
|
||||
void smp_call_function_interrupt(void);
|
||||
|
||||
struct seq_file;
|
||||
void smp_bogo(struct seq_file *);
|
||||
void smp_info(struct seq_file *);
|
||||
|
||||
BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long)
|
||||
BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void)
|
||||
BTFIXUPDEF_CALL(void, smp_ipi_resched, int);
|
||||
BTFIXUPDEF_CALL(void, smp_ipi_single, int);
|
||||
BTFIXUPDEF_CALL(void, smp_ipi_mask_one, int);
|
||||
BTFIXUPDEF_BLACKBOX(hard_smp_processor_id)
|
||||
BTFIXUPDEF_BLACKBOX(load_current)
|
||||
|
||||
#define smp_cross_call(func,mask,arg1,arg2,arg3,arg4) BTFIXUP_CALL(smp_cross_call)(func,mask,arg1,arg2,arg3,arg4)
|
||||
|
||||
static inline void xc0(smpfunc_t func) { smp_cross_call(func, cpu_online_map, 0, 0, 0, 0); }
|
||||
static inline void xc0(smpfunc_t func) { smp_cross_call(func, *cpu_online_mask, 0, 0, 0, 0); }
|
||||
static inline void xc1(smpfunc_t func, unsigned long arg1)
|
||||
{ smp_cross_call(func, cpu_online_map, arg1, 0, 0, 0); }
|
||||
{ smp_cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); }
|
||||
static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
|
||||
{ smp_cross_call(func, cpu_online_map, arg1, arg2, 0, 0); }
|
||||
{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); }
|
||||
static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
|
||||
unsigned long arg3)
|
||||
{ smp_cross_call(func, cpu_online_map, arg1, arg2, arg3, 0); }
|
||||
{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, 0); }
|
||||
static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
|
||||
unsigned long arg3, unsigned long arg4)
|
||||
{ smp_cross_call(func, cpu_online_map, arg1, arg2, arg3, arg4); }
|
||||
{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, arg4); }
|
||||
|
||||
static inline int smp_call_function(void (*func)(void *info), void *info, int wait)
|
||||
{
|
||||
xc1((smpfunc_t)func, (unsigned long)info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int smp_call_function_single(int cpuid, void (*func) (void *info),
|
||||
void *info, int wait)
|
||||
{
|
||||
smp_cross_call((smpfunc_t)func, cpumask_of_cpu(cpuid),
|
||||
(unsigned long) info, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
extern void arch_send_call_function_single_ipi(int cpu);
|
||||
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
|
||||
|
||||
static inline int cpu_logical_map(int cpu)
|
||||
{
|
||||
@ -135,6 +131,11 @@ static inline int hard_smp_processor_id(void)
|
||||
__asm__ __volatile__("lda [%g0] ASI_M_VIKING_TMP1, %0\n\t"
|
||||
"nop; nop" :
|
||||
"=&r" (cpuid));
|
||||
- leon
|
||||
__asm__ __volatile__( "rd %asr17, %0\n\t"
|
||||
"srl %0, 0x1c, %0\n\t"
|
||||
"nop\n\t" :
|
||||
"=&r" (cpuid));
|
||||
See btfixup.h and btfixupprep.c to understand how a blackbox works.
|
||||
*/
|
||||
__asm__ __volatile__("sethi %%hi(___b_hard_smp_processor_id), %0\n\t"
|
||||
|
@ -49,6 +49,10 @@ extern void cpu_play_dead(void);
|
||||
|
||||
extern void smp_fetch_global_regs(void);
|
||||
|
||||
struct seq_file;
|
||||
void smp_bogo(struct seq_file *);
|
||||
void smp_info(struct seq_file *);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
extern int __cpu_disable(void);
|
||||
extern void __cpu_die(unsigned int cpu);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/psr.h>
|
||||
#include <asm/processor.h> /* for cpu_relax */
|
||||
|
||||
#define arch_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
|
||||
|
||||
|
@ -15,11 +15,6 @@
|
||||
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
static inline unsigned int probe_irq_mask(unsigned long val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sparc (general) CPU types
|
||||
*/
|
||||
|
@ -29,10 +29,6 @@ enum sparc_cpu {
|
||||
/* This cannot ever be a sun4c :) That's just history. */
|
||||
#define ARCH_SUN4C 0
|
||||
|
||||
extern const char *sparc_cpu_type;
|
||||
extern const char *sparc_fpu_type;
|
||||
extern const char *sparc_pmu_type;
|
||||
|
||||
extern char reboot_command[];
|
||||
|
||||
/* These are here in an effort to more fully work around Spitfire Errata
|
||||
|
@ -103,6 +103,7 @@
|
||||
st %scratch, [%cur_reg + TI_W_SAVED];
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Results of LOAD_CURRENT() after BTFIXUP for SUN4M, SUN4D & LEON (comments) */
|
||||
#define LOAD_CURRENT4M(dest_reg, idreg) \
|
||||
rd %tbr, %idreg; \
|
||||
sethi %hi(current_set), %dest_reg; \
|
||||
@ -118,6 +119,14 @@
|
||||
or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \
|
||||
ld [%idreg + %dest_reg], %dest_reg;
|
||||
|
||||
#define LOAD_CURRENT_LEON(dest_reg, idreg) \
|
||||
rd %asr17, %idreg; \
|
||||
sethi %hi(current_set), %dest_reg; \
|
||||
srl %idreg, 0x1c, %idreg; \
|
||||
or %dest_reg, %lo(current_set), %dest_reg; \
|
||||
sll %idreg, 0x2, %idreg; \
|
||||
ld [%idreg + %dest_reg], %dest_reg;
|
||||
|
||||
/* Blackbox - take care with this... - check smp4m and smp4d before changing this. */
|
||||
#define LOAD_CURRENT(dest_reg, idreg) \
|
||||
sethi %hi(___b_load_current), %idreg; \
|
||||
|
Reference in New Issue
Block a user