Commit 48f2fa20 authored by David S. Miller's avatar David S. Miller

Hand merge one-liner.

parents 22101408 c02fb92a
......@@ -57,25 +57,24 @@ unsigned int fsr_storage;
void __init cpu_probe(void)
{
int manuf, impl;
unsigned i, cpuid;
long ver, fpu_vers;
long fprs;
unsigned long ver, fpu_vers, manuf, impl, fprs;
int i, cpuid;
cpuid = hard_smp_processor_id();
fprs = fprs_read ();
fprs_write (FPRS_FEF);
fprs = fprs_read();
fprs_write(FPRS_FEF);
__asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]"
: "=&r" (ver)
: "r" (&fpu_vers));
fprs_write (fprs);
fprs_write(fprs);
manuf = ((ver >> 48) & 0xffff);
impl = ((ver >> 32) & 0xffff);
fpu_vers = ((fpu_vers >> 17) & 0x7);
retry:
for (i = 0; i < NSPARCCHIPS; i++) {
if (linux_sparc_chips[i].manuf == manuf) {
if (linux_sparc_chips[i].impl == impl) {
......@@ -87,8 +86,17 @@ void __init cpu_probe(void)
}
if (i == NSPARCCHIPS) {
printk("DEBUG: manuf = 0x%x impl = 0x%x\n",
manuf, impl);
/* Maybe it is a cheetah+ derivative, report it as cheetah+
* in that case until we learn the real names.
*/
if (manuf == 0x3e &&
impl > 0x15) {
impl = 0x15;
goto retry;
} else {
printk("DEBUG: manuf[%lx] impl[%lx]\n",
manuf, impl);
}
sparc_cpu_type[cpuid] = "Unknown CPU";
}
......@@ -104,9 +112,8 @@ void __init cpu_probe(void)
}
if (i == NSPARCFPU) {
printk("DEBUG: manuf = 0x%x impl = 0x%x fsr.vers = 0x%x\n",
manuf, impl,
(unsigned int) fpu_vers);
printk("DEBUG: manuf[%lx] impl[%lx] fsr.vers[%lx]\n",
manuf, impl, fpu_vers);
sparc_fpu_type[cpuid] = "Unknown FPU";
}
}
......@@ -1820,23 +1820,13 @@ do_gettimeofday: /* %o0 = timevalp */
ldx [%g3 + %lo(timer_tick_offset)], %g3
or %g2, %lo(xtime), %g2
or %g1, %lo(timer_tick_compare), %g1
1: rdpr %ver, %o2
sethi %hi(CHEETAH_ID), %o1
srlx %o2, 32, %o2
or %o1, %lo(CHEETAH_ID), %o1
membar #Sync
1: membar #Sync
ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o4
cmp %o2, %o1
be,a,pn %xcc, 3f
rd %asr24, %o1
sethi %hi(CHEETAH_PLUS_ID), %o1
or %o1, %lo(CHEETAH_PLUS_ID), %o1
cmp %o2, %o1
bne,pt %xcc, 2f
nop
BRANCH_IF_ANY_CHEETAH(o2,o1,2f)
ba,pt %xcc, 3f
rd %tick, %o1
2: ba,pt %xcc, 3f
rd %asr24, %o1
2: rd %tick, %o1
3: ldx [%g1], %g7
membar #Sync
ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o2
......
......@@ -115,11 +115,12 @@ etraptl1: /* Save tstate/tpc/tnpc of TL 1-->4 and the tl register itself.
* 0x00 TL1's TSTATE
* 0x08 TL1's TPC
* 0x10 TL1's TNPC
* 0x18 TL1's TT
* ...
* 0x58 TL4's TNPC
* 0x58 TL4's TT
* 0x60 TL
*/
sub %sp, (24 * 8) + 8, %g2
sub %sp, ((4 * 8) * 4) + 8, %g2
rdpr %tl, %g1
wrpr %g0, 1, %tl
......@@ -129,33 +130,41 @@ etraptl1: /* Save tstate/tpc/tnpc of TL 1-->4 and the tl register itself.
stx %g3, [%g2 + STACK_BIAS + 0x08]
rdpr %tnpc, %g3
stx %g3, [%g2 + STACK_BIAS + 0x10]
rdpr %tt, %g3
stx %g3, [%g2 + STACK_BIAS + 0x18]
wrpr %g0, 2, %tl
rdpr %tstate, %g3
stx %g3, [%g2 + STACK_BIAS + 0x18]
rdpr %tpc, %g3
stx %g3, [%g2 + STACK_BIAS + 0x20]
rdpr %tnpc, %g3
rdpr %tpc, %g3
stx %g3, [%g2 + STACK_BIAS + 0x28]
rdpr %tnpc, %g3
stx %g3, [%g2 + STACK_BIAS + 0x30]
rdpr %tt, %g3
stx %g3, [%g2 + STACK_BIAS + 0x38]
wrpr %g0, 3, %tl
rdpr %tstate, %g3
stx %g3, [%g2 + STACK_BIAS + 0x30]
stx %g3, [%g2 + STACK_BIAS + 0x40]
rdpr %tpc, %g3
stx %g3, [%g2 + STACK_BIAS + 0x38]
stx %g3, [%g2 + STACK_BIAS + 0x48]
rdpr %tnpc, %g3
stx %g3, [%g2 + STACK_BIAS + 0x40]
stx %g3, [%g2 + STACK_BIAS + 0x50]
rdpr %tt, %g3
stx %g3, [%g2 + STACK_BIAS + 0x58]
wrpr %g0, 4, %tl
rdpr %tstate, %g3
stx %g3, [%g2 + STACK_BIAS + 0x48]
stx %g3, [%g2 + STACK_BIAS + 0x60]
rdpr %tpc, %g3
stx %g3, [%g2 + STACK_BIAS + 0x50]
stx %g3, [%g2 + STACK_BIAS + 0x68]
rdpr %tnpc, %g3
stx %g3, [%g2 + STACK_BIAS + 0x58]
stx %g3, [%g2 + STACK_BIAS + 0x70]
rdpr %tt, %g3
stx %g3, [%g2 + STACK_BIAS + 0x78]
wrpr %g1, %tl
stx %g1, [%g2 + STACK_BIAS + 0x60]
stx %g1, [%g2 + STACK_BIAS + 0x80]
rdpr %tstate, %g1 ! Single Group+4bubbles
sub %g2, REGWIN_SZ + TRACEREG_SZ - STACK_BIAS, %g2 ! IEU1
......
......@@ -78,16 +78,9 @@ sparc_ramdisk_size:
* PROM entry point is on %o4
*/
sparc64_boot:
rdpr %ver, %g1
sethi %hi(CHEETAH_ID), %g5
srlx %g1, 32, %g1
or %g5, %lo(CHEETAH_ID), %g5
cmp %g1, %g5
be,pn %icc, cheetah_boot
sethi %hi(CHEETAH_PLUS_ID), %g5
or %g5, %lo(CHEETAH_PLUS_ID), %g5
cmp %g1, %g5
bne,pt %icc, spitfire_boot
BRANCH_IF_CHEETAH_BASE(g1,g5,cheetah_boot)
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g5,cheetah_plus_boot)
ba,pt %xcc, spitfire_boot
nop
cheetah_plus_boot:
......@@ -212,15 +205,11 @@ cheetah_got_tlbentry:
add %l0, (1 << 3), %l0
/* On Cheetah+, have to check second DTLB. */
rdpr %ver, %g1
srlx %g1, 32, %g1
sethi %hi(CHEETAH_PLUS_ID), %l0
or %l0, %lo(CHEETAH_PLUS_ID), %l0
cmp %g1, %l0
bne,pt %icc, 9f
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,l0,2f)
ba,pt %xcc, 9f
nop
set 3 << 16, %l0
2: set 3 << 16, %l0
1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1
membar #Sync
andn %g1, %l2, %g1
......@@ -469,16 +458,9 @@ sun4u_init:
stxa %g3, [%g2] ASI_DMMU
membar #Sync
rdpr %ver, %g1
sethi %hi(CHEETAH_ID), %g5
srlx %g1, 32, %g1
or %g5, %lo(CHEETAH_ID), %g5
cmp %g1, %g5
be,pn %icc, cheetah_tlb_fixup
sethi %hi(CHEETAH_PLUS_ID), %g5
or %g5, %lo(CHEETAH_PLUS_ID), %g5
cmp %g1, %g5
bne,pt %icc, spitfire_tlb_fixup
BRANCH_IF_ANY_CHEETAH(g1,g5,cheetah_tlb_fixup)
ba,pt %xcc, spitfire_tlb_fixup
nop
cheetah_tlb_fixup:
......@@ -499,15 +481,10 @@ cheetah_tlb_fixup:
flush %g3
membar #Sync
sethi %hi(CHEETAH_PLUS_ID), %g5
or %g5, %lo(CHEETAH_PLUS_ID), %g5
rdpr %ver, %g2
srlx %g2, 32, %g2
cmp %g2, %g5
bne,a,pt %icc, 1f
mov 1, %g2 /* Set TLB type to cheetah. */
mov 2, %g2 /* Set TLB type to cheetah+. */
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g5,g2,1f)
mov 1, %g2 /* Set TLB type to cheetah. */
1: sethi %hi(tlb_type), %g5
stw %g2, [%g5 + %lo(tlb_type)]
......@@ -631,16 +608,8 @@ setup_tba: /* i0 = is_starfire */
sllx %g2, 32, %g2
or %g2, KERN_LOWBITS, %g2
rdpr %ver, %g3
sethi %hi(CHEETAH_ID), %g7
srlx %g3, 32, %g3
or %g7, %lo(CHEETAH_ID), %g7
cmp %g3, %g7
be,pn %icc, cheetah_vpte_base
sethi %hi(CHEETAH_PLUS_ID), %g7
or %g7, %lo(CHEETAH_PLUS_ID), %g7
cmp %g3, %g7
bne,pt %icc, spitfire_vpte_base
BRANCH_IF_ANY_CHEETAH(g3,g7,cheetah_vpte_base)
ba,pt %xcc, spitfire_vpte_base
nop
cheetah_vpte_base:
......@@ -648,6 +617,7 @@ cheetah_vpte_base:
or %g3, %ulo(VPTE_BASE_CHEETAH), %g3
ba,pt %xcc, 2f
sllx %g3, 32, %g3
spitfire_vpte_base:
sethi %uhi(VPTE_BASE_SPITFIRE), %g3
or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3
......@@ -675,16 +645,9 @@ spitfire_vpte_base:
nop
not_starfire:
rdpr %ver, %g1
sethi %hi(CHEETAH_ID), %g5
srlx %g1, 32, %g1
or %g5, %lo(CHEETAH_ID), %g5
cmp %g1, %g5
be,pn %icc, is_cheetah
sethi %hi(CHEETAH_PLUS_ID), %g5
or %g5, %lo(CHEETAH_PLUS_ID), %g5
cmp %g1, %g5
bne,pt %icc, not_cheetah
BRANCH_IF_ANY_CHEETAH(g1,g5,is_cheetah)
ba,pt %xcc, not_cheetah
nop
is_cheetah:
......@@ -710,23 +673,16 @@ set_worklist:
/* Kill PROM timer */
wr %g0, 0, %tick_cmpr
rdpr %ver, %g1
sethi %hi(CHEETAH_ID), %g5
srlx %g1, 32, %g1
or %g5, %lo(CHEETAH_ID), %g5
cmp %g1, %g5
be,pn %icc, 1f
sethi %hi(CHEETAH_PLUS_ID), %g5
or %g5, %lo(CHEETAH_PLUS_ID), %g5
cmp %g1, %g5
bne,pt %icc, 2f
BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
ba,pt %xcc, 2f
nop
/* Disable STICK_INT interrupts. */
1:
sethi %hi(0x80000000), %g1
sllx %g1, 32, %g1
wr %g1, %asr25
sethi %hi(0x80000000), %g1
sllx %g1, 32, %g1
wr %g1, %asr25
/* Ok, we're done setting up all the state our trap mechanims needs,
* now get back into normal globals and let the PROM know what is up.
......
......@@ -20,7 +20,6 @@
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/kbd_ll.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
......
......@@ -705,19 +705,5 @@ void sun_do_break(void)
prom_cmdline();
}
#ifdef CONFIG_MAGIC_SYSRQ
/* Because we use the generic input layer keyboard drivers for
* everything, this PC sysrq translation table is all we need.
*/
unsigned char kbd_sysrq_xlate[128] =
"\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
"dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
"bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
"\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
"\r\000/"; /* 0x60 - 0x6f */
#endif
int serial_console;
int stop_a_enabled = 1;
......@@ -33,16 +33,10 @@ dtlb_load:
sparc64_cpu_startup:
flushw
rdpr %ver, %g1
sethi %hi(CHEETAH_ID), %g5
srlx %g1, 32, %g1
or %g5, %lo(CHEETAH_ID), %g5
cmp %g1, %g5
be,pn %icc, cheetah_startup
sethi %hi(CHEETAH_PLUS_ID), %g5
or %g5, %lo(CHEETAH_PLUS_ID), %g5
cmp %g1, %g5
bne,pt %icc, spitfire_startup
BRANCH_IF_CHEETAH_BASE(g1,g5,cheetah_startup)
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g5,cheetah_plus_startup)
ba,pt %xcc, spitfire_startup
nop
cheetah_plus_startup:
......@@ -51,15 +45,15 @@ cheetah_plus_startup:
nop
cheetah_startup:
mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
wr %g1, %asr18
sethi %uhi(DCU_ME | DCU_RE | /*DCU_PE |*/ DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5
or %g5, %ulo(DCU_ME | DCU_RE | /*DCU_PE |*/ DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5
sllx %g5, 32, %g5
or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
stxa %g5, [%g0] ASI_DCU_CONTROL_REG
membar #Sync
mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
wr %g1, %asr18
sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
or %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
sllx %g5, 32, %g5
or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
stxa %g5, [%g0] ASI_DCU_CONTROL_REG
membar #Sync
cheetah_generic_startup:
mov TSB_EXTENSION_P, %g3
......@@ -127,19 +121,10 @@ startup_continue:
ldx [%g2 + %lo(kern_locked_tte_data)], %g2
stx %g2, [%sp + 2047 + 128 + 0x30]
rdpr %ver, %g1
sethi %hi(CHEETAH_ID), %g5
srlx %g1, 32, %g1
or %g5, %lo(CHEETAH_ID), %g5
cmp %g1, %g5
be,a,pn %icc, 1f
mov 15, %g2
sethi %hi(CHEETAH_PLUS_ID), %g5
or %g5, %lo(CHEETAH_PLUS_ID), %g5
cmp %g1, %g5
bne,a,pt %icc, 1f
mov 63, %g2
mov 15, %g2
BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
mov 63, %g2
1:
stx %g2, [%sp + 2047 + 128 + 0x38]
sethi %hi(p1275buf), %g2
......@@ -167,19 +152,10 @@ startup_continue:
ldx [%g2 + %lo(kern_locked_tte_data)], %g2
stx %g2, [%sp + 2047 + 128 + 0x30]
rdpr %ver, %g1
sethi %hi(CHEETAH_ID), %g5
srlx %g1, 32, %g1
or %g5, %lo(CHEETAH_ID), %g5
cmp %g1, %g5
be,a,pn %icc, 1f
mov 15, %g2
sethi %hi(CHEETAH_PLUS_ID), %g5
or %g5, %lo(CHEETAH_PLUS_ID), %g5
cmp %g1, %g5
bne,a,pt %icc, 1f
mov 63, %g2
mov 15, %g2
BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
mov 63, %g2
1:
stx %g2, [%sp + 2047 + 128 + 0x38]
......@@ -244,16 +220,9 @@ startup_continue:
sllx %g2, 32, %g2
or %g2, KERN_LOWBITS, %g2
rdpr %ver, %g3
sethi %hi(CHEETAH_ID), %g7
srlx %g3, 32, %g3
or %g7, %lo(CHEETAH_ID), %g7
cmp %g3, %g7
be,pn %icc, 9f
sethi %hi(CHEETAH_PLUS_ID), %g7
or %g7, %lo(CHEETAH_PLUS_ID), %g7
cmp %g3, %g7
bne,pt %icc, 1f
BRANCH_IF_ANY_CHEETAH(g3,g7,9f)
ba,pt %xcc, 1f
nop
9:
......
......@@ -47,6 +47,7 @@ struct tl1_traplog {
unsigned long tstate;
unsigned long tpc;
unsigned long tnpc;
unsigned long tt;
} trapstack[4];
unsigned long tl;
};
......@@ -58,9 +59,12 @@ static void dump_tl1_traplog(struct tl1_traplog *p)
printk("TRAPLOG: Error at trap level 0x%lx, dumping track stack.\n",
p->tl);
for (i = 0; i < 4; i++) {
printk("TRAPLOG: Trap level %d TSTATE[%016lx] TPC[%016lx] TNPC[%016lx]\n",
printk(KERN_CRIT
"TRAPLOG: Trap level %d TSTATE[%016lx] TPC[%016lx] "
"TNPC[%016lx] TT[%lx]\n",
i + 1,
p->trapstack[i].tstate, p->trapstack[i].tpc, p->trapstack[i].tnpc);
p->trapstack[i].tstate, p->trapstack[i].tpc,
p->trapstack[i].tnpc, p->trapstack[i].tt);
}
}
......@@ -182,43 +186,36 @@ extern volatile int pci_poke_faulted;
#endif
/* When access exceptions happen, we must do this. */
static void clean_and_reenable_l1_caches(void)
static void spitfire_clean_and_reenable_l1_caches(void)
{
unsigned long va;
if (tlb_type == spitfire) {
/* Clean 'em. */
for (va = 0; va < (PAGE_SIZE << 1); va += 32) {
spitfire_put_icache_tag(va, 0x0);
spitfire_put_dcache_tag(va, 0x0);
}
if (tlb_type != spitfire)
BUG();
/* Re-enable in LSU. */
__asm__ __volatile__("flush %%g6\n\t"
"membar #Sync\n\t"
"stxa %0, [%%g0] %1\n\t"
"membar #Sync"
: /* no outputs */
: "r" (LSU_CONTROL_IC | LSU_CONTROL_DC |
LSU_CONTROL_IM | LSU_CONTROL_DM),
"i" (ASI_LSU_CONTROL)
: "memory");
} else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
/* Flush D-cache */
for (va = 0; va < (1 << 16); va += (1 << 5)) {
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* no outputs */
: "r" (va), "i" (ASI_DCACHE_TAG));
}
/* Clean 'em. */
for (va = 0; va < (PAGE_SIZE << 1); va += 32) {
spitfire_put_icache_tag(va, 0x0);
spitfire_put_dcache_tag(va, 0x0);
}
/* Re-enable in LSU. */
__asm__ __volatile__("flush %%g6\n\t"
"membar #Sync\n\t"
"stxa %0, [%%g0] %1\n\t"
"membar #Sync"
: /* no outputs */
: "r" (LSU_CONTROL_IC | LSU_CONTROL_DC |
LSU_CONTROL_IM | LSU_CONTROL_DM),
"i" (ASI_LSU_CONTROL)
: "memory");
}
void do_iae(struct pt_regs *regs)
{
siginfo_t info;
clean_and_reenable_l1_caches();
spitfire_clean_and_reenable_l1_caches();
info.si_signo = SIGBUS;
info.si_errno = 0;
......@@ -232,7 +229,7 @@ void do_dae(struct pt_regs *regs)
{
#ifdef CONFIG_PCI
if (pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) {
clean_and_reenable_l1_caches();
spitfire_clean_and_reenable_l1_caches();
pci_poke_faulted = 1;
......
......@@ -106,13 +106,8 @@ cheetah_patch_1:
bne,pn %xcc, copy_page_using_blkcommit
nop
rdpr %ver, %g3
sllx %g3, 16, %g3
srlx %g3, 32 + 16, %g3
cmp %g3, 0x14 ! CHEETAH_ID
be,pn %icc, cheetah_copy_user_page
cmp %g3, 0x15 ! CHEETAH_PLUS_ID
bne,pt %icc, spitfire_copy_user_page
BRANCH_IF_ANY_CHEETAH(g3,o2,cheetah_copy_user_page)
ba,pt %xcc, spitfire_copy_user_page
nop
cheetah_copy_user_page:
......
......@@ -906,7 +906,7 @@ static void kbd_bh(unsigned long dummy)
DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC)
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
static unsigned short x86_keycodes[256] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
......@@ -929,6 +929,11 @@ static unsigned short x86_keycodes[256] =
extern int mac_hid_mouse_emulate_buttons(int, int, int);
#endif /* CONFIG_MAC_EMUMOUSEBTN */
#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
static int sparc_l1_a_state = 0;
extern void sun_do_break(void);
#endif
static int emulate_raw(struct vc_data *vc, unsigned int keycode,
unsigned char up_flag)
{
......@@ -1001,6 +1006,10 @@ void kbd_keycode(unsigned int keycode, int down)
if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
sysrq_alt = down;
#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
if (keycode == KEY_STOP)
sparc_l1_a_state = down;
#endif
rep = (down == 2);
......@@ -1018,6 +1027,12 @@ void kbd_keycode(unsigned int keycode, int down)
return;
}
#endif
#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
if (keycode == KEY_A && sparc_l1_a_state) {
sparc_l1_a_state = 0;
sun_do_break();
}
#endif
if (kbd->kbdmode == VC_MEDIUMRAW) {
/*
......
......@@ -17,6 +17,17 @@ CONFIG_INPUT_PCSPKR
The module will be called pcspkr.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
CONFIG_INPUT_SPARCSPKR
Say Y here if you want the standard Speaker on Sparc PCI systems
to be used for bells and whistles.
If unsure, say Y.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called pcspkr.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
CONFIG_INPUT_UINPUT
Say Y here if you want to support user level drivers for input
......
......@@ -5,4 +5,7 @@
bool 'Misc' CONFIG_INPUT_MISC
dep_tristate ' PC Speaker support' CONFIG_INPUT_PCSPKR $CONFIG_INPUT $CONFIG_INPUT_MISC
if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
dep_tristate ' SPARC Speaker support' CONFIG_INPUT_SPARCSPKR $CONFIG_INPUT $CONFIG_INPUT_MISC
fi
dep_tristate ' User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT $CONFIG_INPUT_MISC
......@@ -4,6 +4,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
......
/*
* Driver for PC-speaker like devices found on various Sparc systems.
*
* Copyright (c) 2002 Vojtech Pavlik
* Copyright (c) 2002 David S. Miller (davem@redhat.com)
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <asm/io.h>
#include <asm/ebus.h>
#ifdef CONFIG_SPARC64
#include <asm/isa.h>
#endif
MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
MODULE_DESCRIPTION("PC Speaker beeper driver");
MODULE_LICENSE("GPL");
static unsigned long beep_iobase;
static char *sparcspkr_isa_name = "Sparc ISA Speaker";
static char *sparcspkr_ebus_name = "Sparc EBUS Speaker";
static char *sparcspkr_phys = "sparc/input0";
static struct input_dev sparcspkr_dev;
spinlock_t beep_lock = SPIN_LOCK_UNLOCKED;
static void __init init_sparcspkr_struct(void)
{
sparcspkr_dev.evbit[0] = BIT(EV_SND);
sparcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
sparcspkr_dev.phys = sparcspkr_phys;
sparcspkr_dev.id.bustype = BUS_ISA;
sparcspkr_dev.id.vendor = 0x001f;
sparcspkr_dev.id.product = 0x0001;
sparcspkr_dev.id.version = 0x0100;
}
static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
unsigned int count = 0;
unsigned long flags;
if (type != EV_SND)
return -1;
switch (code) {
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
}
if (value > 20 && value < 32767)
count = 1193182 / value;
spin_lock_irqsave(&beep_lock, flags);
/* EBUS speaker only has on/off state, the frequency does not
* appear to be programmable.
*/
if (count) {
if (beep_iobase & 0x2UL)
outb(1, beep_iobase);
else
outl(1, beep_iobase);
} else {
if (beep_iobase & 0x2UL)
outb(0, beep_iobase);
else
outl(0, beep_iobase);
}
spin_unlock_irqrestore(&beep_lock, flags);
return 0;
}
static int __init init_ebus_beep(struct linux_ebus_device *edev)
{
beep_iobase = edev->resource[0].start;
init_sparcspkr_struct();
sparcspkr_dev.name = sparcspkr_ebus_name;
sparcspkr_dev.event = ebus_spkr_event;
input_register_device(&sparcspkr_dev);
printk(KERN_INFO "input: %s\n", sparcspkr_ebus_name);
return 0;
}
#ifdef CONFIG_SPARC64
static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
unsigned int count = 0;
unsigned long flags;
if (type != EV_SND)
return -1;
switch (code) {
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
}
if (value > 20 && value < 32767)
count = 1193182 / value;
spin_lock_irqsave(&beep_lock, flags);
if (count) {
/* enable counter 2 */
outb(inb(beep_iobase + 0x61) | 3, beep_iobase + 0x61);
/* set command for counter 2, 2 byte write */
outb(0xB6, beep_iobase + 0x43);
/* select desired HZ */
outb(count & 0xff, beep_iobase + 0x42);
outb((count >> 8) & 0xff, beep_iobase + 0x42);
} else {
/* disable counter 2 */
outb(inb_p(beep_iobase + 0x61) & 0xFC, beep_iobase + 0x61);
}
spin_unlock_irqrestore(&beep_lock, flags);
return 0;
}
static int __init init_isa_beep(struct isa_device *isa_dev)
{
beep_iobase = isa_dev->resource.start;
init_sparcspkr_struct();
sparcspkr_dev.name = sparcspkr_isa_name;
sparcspkr_dev.event = isa_spkr_event;
sparcspkr_dev.id.bustype = BUS_ISA;
input_register_device(&sparcspkr_dev);
printk(KERN_INFO "input: %s\n", sparcspkr_isa_name);
return 0;
}
#endif
static int __init sparcspkr_init(void)
{
struct linux_ebus *ebus;
struct linux_ebus_device *edev = NULL;
#ifdef CONFIG_SPARC64
struct isa_bridge *isa_br;
struct isa_device *isa_dev;
#endif
for_each_ebus(ebus) {
for_each_ebusdev(edev, ebus) {
if (!strcmp(edev->prom_name, "beep"))
return init_ebus_beep(edev);
}
}
#ifdef CONFIG_SPARC64
for_each_isa(isa_br) {
for_each_isadev(isa_dev, isa_br) {
/* A hack, the beep device's base lives in
* the DMA isa node.
*/
if (!strcmp(isa_dev->prom_name, "dma"))
return init_isa_beep(isa_dev);
}
}
#endif
return -ENODEV;
}
static void __exit sparcspkr_exit(void)
{
input_unregister_device(&sparcspkr_dev);
}
module_init(sparcspkr_init);
module_exit(sparcspkr_exit);
......@@ -68,7 +68,7 @@ static int options_node = 0;
*/
static int copyin(struct openpromio *info, struct openpromio **opp_p)
{
int bufsize;
unsigned int bufsize;
if (!info || !opp_p)
return -EFAULT;
......
......@@ -51,7 +51,7 @@ if [ "$CONFIG_ARM" = "y" ]; then
dep_bool ' Console on SA1100 serial port' CONFIG_SERIAL_SA1100_CONSOLE $CONFIG_SERIAL_SA1100
fi
if [ "$CONFIG_SPARC" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
define_bool CONFIG_SERIAL_SUNCORE y
define_bool CONFIG_SERIAL_CORE_CONSOLE y
tristate 'Sun Zilog8530 serial support' CONFIG_SERIAL_SUNZILOG
......
......@@ -77,7 +77,8 @@ static ssize_t nodenum_read(struct file *file, char *buf,
return 0;
if (count > 9 - file->f_pos)
count = 9 - file->f_pos;
copy_to_user(buf, buffer + file->f_pos, count);
if (copy_to_user(buf, buffer + file->f_pos, count))
return -EFAULT;
file->f_pos += count;
return count;
}
......@@ -93,7 +94,7 @@ static ssize_t property_read(struct file *filp, char *buf,
openprom_property *op;
char buffer[64];
if (filp->f_pos >= 0xffffff)
if (filp->f_pos >= 0xffffff || count >= 0xffffff)
return -EINVAL;
if (!filp->private_data) {
node = nodes[(u16)((long)inode->u.generic_ip)].node;
......@@ -184,7 +185,8 @@ static ssize_t property_read(struct file *filp, char *buf,
if (count > i - k) count = i - k;
if (op->flag & OPP_STRING) {
if (!k) {
__put_user('\'', buf);
if (put_user('\'', buf))
return -EFAULT;
k++;
count--;
}
......@@ -195,17 +197,21 @@ static ssize_t property_read(struct file *filp, char *buf,
j = count;
if (j >= 0) {
copy_to_user(buf + k - filp->f_pos,
op->value + k - 1, j);
if (copy_to_user(buf + k - filp->f_pos,
op->value + k - 1, j))
return -EFAULT;
count -= j;
k += j;
}
if (count)
__put_user('\'', &buf [k++ - filp->f_pos]);
if (count > 1)
__put_user('\n', &buf [k++ - filp->f_pos]);
if (count) {
if (put_user('\'', &buf [k++ - filp->f_pos]))
return -EFAULT;
}
if (count > 1) {
if (put_user('\n', &buf [k++ - filp->f_pos]))
return -EFAULT;
}
} else if (op->flag & OPP_STRINGLIST) {
char *tmp;
......@@ -225,7 +231,8 @@ static ssize_t property_read(struct file *filp, char *buf,
}
strcpy(s, "'\n");
copy_to_user(buf, tmp + k, count);
if (copy_to_user(buf, tmp + k, count))
return -EFAULT;
kfree(tmp);
k += count;
......@@ -243,53 +250,68 @@ static ssize_t property_read(struct file *filp, char *buf,
if (first == last) {
sprintf (buffer, "%08x.", *first);
copy_to_user (buf, buffer + first_off, last_cnt - first_off);
if (copy_to_user(buf, buffer + first_off,
last_cnt - first_off))
return -EFAULT;
buf += last_cnt - first_off;
} else {
for (q = first; q <= last; q++) {
sprintf (buffer, "%08x.", *q);
if (q == first) {
copy_to_user (buf, buffer + first_off,
9 - first_off);
if (copy_to_user(buf, buffer + first_off,
9 - first_off))
return -EFAULT;
buf += 9 - first_off;
} else if (q == last) {
copy_to_user (buf, buffer, last_cnt);
if (copy_to_user(buf, buffer, last_cnt))
return -EFAULT;
buf += last_cnt;
} else {
copy_to_user (buf, buffer, 9);
if (copy_to_user(buf, buffer, 9))
return -EFAULT;
buf += 9;
}
}
}
if (last == (u32 *)(op->value + op->len - 4) && last_cnt == 9)
__put_user('\n', (buf - 1));
if (last == (u32 *)(op->value + op->len - 4) && last_cnt == 9) {
if (put_user('\n', (buf - 1)))
return -EFAULT;
}
k += count;
} else if (op->flag & OPP_HEXSTRING) {
char buffer[2];
char buffer[3];
if ((k < i - 1) && (k & 1)) {
sprintf (buffer, "%02x", *(op->value + (k >> 1)));
__put_user(buffer[1], &buf[k++ - filp->f_pos]);
sprintf (buffer, "%02x",
(unsigned char) *(op->value + (k >> 1)) & 0xff);
if (put_user(buffer[1], &buf[k++ - filp->f_pos]))
return -EFAULT;
count--;
}
for (; (count > 1) && (k < i - 1); k += 2) {
sprintf (buffer, "%02x", *(op->value + (k >> 1)));
copy_to_user (buf + k - filp->f_pos, buffer, 2);
sprintf (buffer, "%02x",
(unsigned char) *(op->value + (k >> 1)) & 0xff);
if (copy_to_user(buf + k - filp->f_pos, buffer, 2))
return -EFAULT;
count -= 2;
}
if (count && (k < i - 1)) {
sprintf (buffer, "%02x", *(op->value + (k >> 1)));
__put_user(buffer[0], &buf[k++ - filp->f_pos]);
sprintf (buffer, "%02x",
(unsigned char) *(op->value + (k >> 1)) & 0xff);
if (put_user(buffer[0], &buf[k++ - filp->f_pos]))
return -EFAULT;
count--;
}
if (count)
__put_user('\n', &buf [k++ - filp->f_pos]);
if (count) {
if (put_user('\n', &buf [k++ - filp->f_pos]))
return -EFAULT;
}
}
count = k - filp->f_pos;
filp->f_pos = k;
......@@ -305,7 +327,7 @@ static ssize_t property_write(struct file *filp, const char *buf,
void *b;
openprom_property *op;
if (filp->f_pos >= 0xffffff)
if (filp->f_pos >= 0xffffff || count >= 0xffffff)
return -EINVAL;
if (!filp->private_data) {
i = property_read (filp, NULL, 0, 0);
......@@ -326,7 +348,8 @@ static ssize_t property_write(struct file *filp, const char *buf,
if (j == 9) j = 0;
if (!j) {
char ctmp;
__get_user(ctmp, &buf[i]);
if (get_user(ctmp, &buf[i]))
return -EFAULT;
if (ctmp != '.') {
if (ctmp != '\n') {
if (op->flag & OPP_BINARY)
......@@ -341,7 +364,8 @@ static ssize_t property_write(struct file *filp, const char *buf,
}
} else {
char ctmp;
__get_user(ctmp, &buf[i]);
if (get_user(ctmp, &buf[i]))
return -EFAULT;
if (ctmp < '0' ||
(ctmp > '9' && ctmp < 'A') ||
(ctmp > 'F' && ctmp < 'a') ||
......@@ -379,8 +403,10 @@ static ssize_t property_write(struct file *filp, const char *buf,
last_cnt = (k + count) % 9;
if (first + 1 == last) {
memset (tmp, '0', 8);
copy_from_user (tmp + first_off, buf,
(count + first_off > 8) ? 8 - first_off : count);
if (copy_from_user(tmp + first_off, buf,
(count + first_off > 8) ?
8 - first_off : count))
return -EFAULT;
mask = 0xffffffff;
mask2 = 0xffffffff;
for (j = 0; j < first_off; j++)
......@@ -399,8 +425,10 @@ static ssize_t property_write(struct file *filp, const char *buf,
if (q == first) {
if (first_off < 8) {
memset (tmp, '0', 8);
copy_from_user (tmp + first_off, buf,
8 - first_off);
if (copy_from_user(tmp + first_off,
buf,
8 - first_off))
return -EFAULT;
mask = 0xffffffff;
for (j = 0; j < first_off; j++)
mask >>= 1;
......@@ -411,7 +439,8 @@ static ssize_t property_write(struct file *filp, const char *buf,
} else if ((q == last - 1) && last_cnt
&& (last_cnt < 8)) {
memset (tmp, '0', 8);
copy_from_user (tmp, buf, last_cnt);
if (copy_from_user(tmp, buf, last_cnt))
return -EFAULT;
mask = 0xffffffff;
for (j = 0; j < 8 - last_cnt; j++)
mask <<= 1;
......@@ -421,7 +450,8 @@ static ssize_t property_write(struct file *filp, const char *buf,
} else {
char tchars[17]; /* XXX yuck... */
copy_from_user(tchars, buf, 16);
if (copy_from_user(tchars, buf, 16))
return -EFAULT;
*q = simple_strtoul (tchars, 0, 16);
buf += 9;
}
......@@ -444,7 +474,8 @@ static ssize_t property_write(struct file *filp, const char *buf,
*/
if (k > 0)
return -EINVAL;
__get_user(ctmp, buf);
if (get_user(ctmp, buf))
return -EFAULT;
if (ctmp == '\'') {
op->flag |= OPP_QUOTED;
buf++;
......@@ -476,7 +507,8 @@ static ssize_t property_write(struct file *filp, const char *buf,
kfree (b);
}
p = op->value + filp->f_pos - ((op->flag & OPP_QUOTED) ? 1 : 0);
copy_from_user (p, buf, count);
if (copy_from_user(p, buf, count))
return -EFAULT;
op->flag |= OPP_DIRTY;
for (i = 0; i < count; i++, p++)
if (*p == '\n') {
......
......@@ -8,7 +8,41 @@
#define PTREGS_OFF (STACK_BIAS + REGWIN_SZ)
#define CHEETAH_ID 0x003e0014
#define CHEETAH_PLUS_ID 0x003e0015
#define __CHEETAH_ID 0x003e0014
#define CHEETAH_MANUF 0x003e
#define CHEETAH_IMPL 0x0014
#define CHEETAH_PLUS_IMPL 0x0015
#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label) \
rdpr %ver, %tmp1; \
sethi %hi(__CHEETAH_ID), %tmp2; \
srlx %tmp1, 32, %tmp1; \
or %tmp2, %lo(__CHEETAH_ID), %tmp2;\
cmp %tmp1, %tmp2; \
be,pn %icc, label; \
nop;
#define BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(tmp1,tmp2,label) \
rdpr %ver, %tmp1; \
srlx %tmp1, (32 + 16), %tmp2; \
cmp %tmp2, CHEETAH_MANUF; \
bne,pt %xcc, 99f; \
sllx %tmp1, 16, %tmp1; \
srlx %tmp1, (32 + 16), %tmp2; \
cmp %tmp2, CHEETAH_PLUS_IMPL; \
bgeu,pt %xcc, label; \
99: nop;
#define BRANCH_IF_ANY_CHEETAH(tmp1,tmp2,label) \
rdpr %ver, %tmp1; \
srlx %tmp1, (32 + 16), %tmp2; \
cmp %tmp2, CHEETAH_MANUF; \
bne,pt %xcc, 99f; \
sllx %tmp1, 16, %tmp1; \
srlx %tmp1, (32 + 16), %tmp2; \
cmp %tmp2, CHEETAH_IMPL; \
bgeu,pt %xcc, label; \
99: nop;
#endif /* !(_SPARC64_HEAD_H) */
......@@ -5,6 +5,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/page.h>
#include <asm/spitfire.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment