diff --git a/arch/h8300/mm/memory.c b/arch/h8300/mm/memory.c index ccd6ade816dd..40d8aa811e4e 100644 --- a/arch/h8300/mm/memory.c +++ b/arch/h8300/mm/memory.c @@ -44,8 +44,8 @@ void cache_push_v (unsigned long vaddr, int len) { } -/* Map some physical address range into the kernel address space. The - * code is copied and adapted from map_chunk(). +/* + * Map some physical address range into the kernel address space. */ unsigned long kernel_map(unsigned long paddr, unsigned long size, diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index ecdc19a299b2..b5da298ba61d 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -536,10 +536,6 @@ config GVPIOEXT_PLIP Say Y to enable doing IP over the parallel port on your GVP IO-Extender card, N otherwise. -config MAC_SCC - tristate "Macintosh serial support" - depends on MAC - config MAC_HID bool depends on INPUT_ADBHID @@ -595,7 +591,7 @@ config DN_SERIAL config SERIAL_CONSOLE bool "Support for serial port console" - depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL) + depends on (AMIGA || ATARI || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL) ---help--- If you say Y here, it will be possible to use a serial port as the system console (the system console is the device which receives all diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 6c74751c7b82..d2cc35d98532 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -480,7 +480,7 @@ static void __init amiga_sched_init(irq_handler_t timer_routine) static struct resource sched_res = { .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, }; - jiffy_ticks = (amiga_eclock+HZ/2)/HZ; + jiffy_ticks = DIV_ROUND_CLOSEST(amiga_eclock, HZ); if (request_resource(&mb_resources._ciab, &sched_res)) printk("Cannot allocate ciab.ta{lo,hi}\n"); diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 9991b64fea57..c5f3232ff916 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -701,6 +701,11 @@ CONFIG_VT_HW_CONSOLE_BINDING=y # # Non-8250 serial port support # +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_PMACZILOG=y +CONFIG_SERIAL_PMACZILOG_TTYS=y +CONFIG_SERIAL_PMACZILOG_CONSOLE=y CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -834,9 +839,7 @@ CONFIG_HIDRAW=y # # Character devices # -CONFIG_MAC_SCC=y CONFIG_MAC_HID=y -CONFIG_SERIAL_CONSOLE=y # # File systems diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index 69c43e2d8b45..a8bfa3fa71cf 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -822,6 +822,11 @@ CONFIG_A2232=y # # Non-8250 serial port support # +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_PMACZILOG=y +CONFIG_SERIAL_PMACZILOG_TTYS=y +CONFIG_SERIAL_PMACZILOG_CONSOLE=y CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -982,7 +987,6 @@ CONFIG_ATARI_MIDI=y CONFIG_ATARI_DSP56K=m CONFIG_AMIGA_BUILTIN_SERIAL=y CONFIG_MULTIFACE_III_TTY=m -CONFIG_MAC_SCC=y CONFIG_MAC_HID=y CONFIG_MVME147_SCC=y CONFIG_SERIAL167=y diff --git a/arch/m68k/include/asm/machw.h b/arch/m68k/include/asm/machw.h index 2b4de0c2ce4a..a22095164927 100644 --- a/arch/m68k/include/asm/machw.h +++ b/arch/m68k/include/asm/machw.h @@ -21,29 +21,4 @@ #define VIDEOMEMSIZE (4096*1024) #define VIDEOMEMMASK (-4096*1024) -#ifndef __ASSEMBLY__ - -#include - -#if 0 -/* -** SCC Z8530 -*/ - -#define MAC_SCC_BAS (0x50F04000) -struct MAC_SCC - { - u_char cha_a_ctrl; - u_char char_dummy1; - u_char cha_a_data; - u_char char_dummy2; - u_char cha_b_ctrl; - u_char char_dummy3; - u_char cha_b_data; - }; -# define mac_scc ((*(volatile struct SCC*)MAC_SCC_BAS)) -#endif - -#endif /* __ASSEMBLY__ */ - #endif /* linux/machw.h */ diff --git a/arch/m68k/include/asm/macints.h b/arch/m68k/include/asm/macints.h index 679c48ab4407..ebe1b70fe90c 100644 --- a/arch/m68k/include/asm/macints.h +++ b/arch/m68k/include/asm/macints.h @@ -37,7 +37,6 @@ #define VIA1_SOURCE_BASE 8 #define VIA2_SOURCE_BASE 16 -#define MAC_SCC_SOURCE_BASE 24 #define PSC3_SOURCE_BASE 24 #define PSC4_SOURCE_BASE 32 #define PSC5_SOURCE_BASE 40 @@ -96,26 +95,12 @@ #define IRQ_PSC3_2 (26) #define IRQ_PSC3_3 (27) -/* Level 4 (SCC) interrupts */ -#define IRQ_SCC (32) -#define IRQ_SCCA (33) -#define IRQ_SCCB (34) -#if 0 /* FIXME: are there multiple interrupt conditions on the SCC ?? */ -/* SCC interrupts */ -#define IRQ_SCCB_TX (32) -#define IRQ_SCCB_STAT (33) -#define IRQ_SCCB_RX (34) -#define IRQ_SCCB_SPCOND (35) -#define IRQ_SCCA_TX (36) -#define IRQ_SCCA_STAT (37) -#define IRQ_SCCA_RX (38) -#define IRQ_SCCA_SPCOND (39) -#endif - /* Level 4 (PSC, AV Macs only) interrupts */ #define IRQ_PSC4_0 (32) #define IRQ_PSC4_1 (33) +#define IRQ_MAC_SCC_A IRQ_PSC4_1 #define IRQ_PSC4_2 (34) +#define IRQ_MAC_SCC_B IRQ_PSC4_2 #define IRQ_PSC4_3 (35) #define IRQ_MAC_MACE_DMA IRQ_PSC4_3 @@ -146,6 +131,9 @@ #define IRQ_BABOON_2 (66) #define IRQ_BABOON_3 (67) +/* On non-PSC machines, the serial ports share an IRQ */ +#define IRQ_MAC_SCC IRQ_AUTO_4 + #define SLOT2IRQ(x) (x + 47) #define IRQ2SLOT(x) (x - 47) diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h index ee4011c23281..21605c736f69 100644 --- a/arch/m68k/include/asm/ptrace.h +++ b/arch/m68k/include/asm/ptrace.h @@ -71,6 +71,8 @@ struct switch_stack { #define PTRACE_GETFPREGS 14 #define PTRACE_SETFPREGS 15 +#define PTRACE_GET_THREAD_AREA 25 + #define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ #ifdef __KERNEL__ diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/asm/sigcontext.h index 523db2a51cf3..1320eaa4cc2a 100644 --- a/arch/m68k/include/asm/sigcontext.h +++ b/arch/m68k/include/asm/sigcontext.h @@ -15,9 +15,15 @@ struct sigcontext { unsigned long sc_pc; unsigned short sc_formatvec; #ifndef __uClinux__ +# ifdef __mcoldfire__ + unsigned long sc_fpregs[2][2]; /* room for two fp registers */ + unsigned long sc_fpcntl[3]; + unsigned char sc_fpstate[16+6*8]; +# else unsigned long sc_fpregs[2*3]; /* room for two fp registers */ unsigned long sc_fpcntl[3]; unsigned char sc_fpstate[216]; +# endif #endif }; diff --git a/arch/m68k/include/asm/siginfo.h b/arch/m68k/include/asm/siginfo.h index ca7dde8fd223..851d3d784b53 100644 --- a/arch/m68k/include/asm/siginfo.h +++ b/arch/m68k/include/asm/siginfo.h @@ -1,97 +1,6 @@ #ifndef _M68K_SIGINFO_H #define _M68K_SIGINFO_H -#ifndef __uClinux__ -#define HAVE_ARCH_SIGINFO_T -#define HAVE_ARCH_COPY_SIGINFO -#endif - #include -#ifndef __uClinux__ - -typedef struct siginfo { - int si_signo; - int si_errno; - int si_code; - - union { - int _pad[SI_PAD_SIZE]; - - /* kill() */ - struct { - __kernel_pid_t _pid; /* sender's pid */ - __kernel_uid_t _uid; /* backwards compatibility */ - __kernel_uid32_t _uid32; /* sender's uid */ - } _kill; - - /* POSIX.1b timers */ - struct { - timer_t _tid; /* timer id */ - int _overrun; /* overrun count */ - char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; - sigval_t _sigval; /* same as below */ - int _sys_private; /* not to be passed to user */ - } _timer; - - /* POSIX.1b signals */ - struct { - __kernel_pid_t _pid; /* sender's pid */ - __kernel_uid_t _uid; /* backwards compatibility */ - sigval_t _sigval; - __kernel_uid32_t _uid32; /* sender's uid */ - } _rt; - - /* SIGCHLD */ - struct { - __kernel_pid_t _pid; /* which child */ - __kernel_uid_t _uid; /* backwards compatibility */ - int _status; /* exit code */ - clock_t _utime; - clock_t _stime; - __kernel_uid32_t _uid32; /* sender's uid */ - } _sigchld; - - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ - struct { - void *_addr; /* faulting insn/memory ref. */ - } _sigfault; - - /* SIGPOLL */ - struct { - int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ - int _fd; - } _sigpoll; - } _sifields; -} siginfo_t; - -#define UID16_SIGINFO_COMPAT_NEEDED - -/* - * How these fields are to be accessed. - */ -#undef si_uid -#ifdef __KERNEL__ -#define si_uid _sifields._kill._uid32 -#define si_uid16 _sifields._kill._uid -#else -#define si_uid _sifields._kill._uid -#endif - -#ifdef __KERNEL__ - -#include - -static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) -{ - if (from->si_code < 0) - memcpy(to, from, sizeof(*to)); - else - /* _sigchld is currently the largest know union member */ - memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); -} - -#endif /* __KERNEL__ */ -#endif /* !__uClinux__ */ - #endif diff --git a/arch/m68k/include/asm/swab.h b/arch/m68k/include/asm/swab.h index 5b754aace744..b7b37a40defc 100644 --- a/arch/m68k/include/asm/swab.h +++ b/arch/m68k/include/asm/swab.h @@ -14,7 +14,7 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 val) } #define __arch_swab32 __arch_swab32 -#elif !defined(__uClinux__) +#elif !defined(__mcoldfire__) static inline __attribute_const__ __u32 __arch_swab32(__u32 val) { diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h index 167e518db41b..67266c683453 100644 --- a/arch/m68k/include/asm/thread_info_mm.h +++ b/arch/m68k/include/asm/thread_info_mm.h @@ -16,6 +16,7 @@ struct thread_info { struct exec_domain *exec_domain; /* execution domain */ int preempt_count; /* 0 => preemptable, <0 => BUG */ __u32 cpu; /* should always be 0 on m68k */ + unsigned long tp_value; /* thread pointer */ struct restart_block restart_block; }; #endif /* __ASSEMBLY__ */ diff --git a/arch/m68k/include/asm/thread_info_no.h b/arch/m68k/include/asm/thread_info_no.h index a6512bfdd01d..884776f686ca 100644 --- a/arch/m68k/include/asm/thread_info_no.h +++ b/arch/m68k/include/asm/thread_info_no.h @@ -37,6 +37,7 @@ struct thread_info { unsigned long flags; /* low level flags */ int cpu; /* cpu we're on */ int preempt_count; /* 0 => preemptable, <0 => BUG */ + unsigned long tp_value; /* thread pointer */ struct restart_block restart_block; }; diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/asm/ucontext.h index e4e22669edc0..00dcc5176c57 100644 --- a/arch/m68k/include/asm/ucontext.h +++ b/arch/m68k/include/asm/ucontext.h @@ -7,7 +7,11 @@ typedef greg_t gregset_t[NGREG]; typedef struct fpregset { int f_fpcntl[3]; +#ifdef __mcoldfire__ + int f_fpregs[8][2]; +#else int f_fpregs[8*3]; +#endif } fpregset_t; struct mcontext { diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 48b87f5ced50..d72a71dabecb 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -336,10 +336,14 @@ #define __NR_pwritev 330 #define __NR_rt_tgsigqueueinfo 331 #define __NR_perf_event_open 332 +#define __NR_get_thread_area 333 +#define __NR_set_thread_area 334 +#define __NR_atomic_cmpxchg_32 335 +#define __NR_atomic_barrier 336 #ifdef __KERNEL__ -#define NR_syscalls 333 +#define NR_syscalls 337 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/arch/m68k/include/asm/virtconvert.h b/arch/m68k/include/asm/virtconvert.h index 3f834b3ab5bd..f35229b8651d 100644 --- a/arch/m68k/include/asm/virtconvert.h +++ b/arch/m68k/include/asm/virtconvert.h @@ -31,12 +31,7 @@ static inline void *phys_to_virt(unsigned long address) #define page_to_phys(page) \ __pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT)) #else -#define page_to_phys(_page) ({ \ - struct page *__page = _page; \ - struct pglist_data *pgdat; \ - pgdat = pg_data_table[page_to_nid(__page)]; \ - page_to_pfn(__page) << PAGE_SHIFT; \ -}) +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) #endif #else #define page_to_phys(page) (((page) - mem_map) << PAGE_SHIFT) diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 77fc7c16bf48..e136b8cbe9b9 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -761,4 +761,8 @@ sys_call_table: .long sys_pwritev /* 330 */ .long sys_rt_tgsigqueueinfo .long sys_perf_event_open + .long sys_get_thread_area + .long sys_set_thread_area + .long sys_atomic_cmpxchg_32 /* 335 */ + .long sys_atomic_barrier diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 05296593e718..17c3f325255d 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -251,6 +251,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.usp = usp; p->thread.ksp = (unsigned long)childstack; + + if (clone_flags & CLONE_SETTLS) + task_thread_info(p)->tp_value = regs->d5; + /* * Must save the current SFC/DFC value, NOT the value when * the parent was last descheduled - RGH 10-08-96 diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c index 1fc217e5f06b..616e59752c29 100644 --- a/arch/m68k/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace.c @@ -245,6 +245,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = -EFAULT; break; + case PTRACE_GET_THREAD_AREA: + ret = put_user(task_thread_info(child)->tp_value, + (unsigned long __user *)data); + break; + default: ret = ptrace_request(child, request, addr, data); break; diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index de2d05ddd86d..4b387538706f 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -897,10 +897,17 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up to return from userspace. */ err |= __put_user(frame->retcode, &frame->pretcode); +#ifdef __mcoldfire__ + /* movel #__NR_rt_sigreturn,d0; trap #0 */ + err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0)); + err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16), + (long __user *)(frame->retcode + 4)); +#else /* moveq #,d0; notb d0; trap #0 */ err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), (long __user *)(frame->retcode + 0)); err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); +#endif if (err) goto give_sigsegv; diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 218f441de667..e3ad2d671973 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -28,6 +28,11 @@ #include #include #include +#include +#include + +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code); asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, @@ -595,3 +600,79 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) : "d" (__a), "d" (__b), "d" (__c)); return __res; } + +asmlinkage unsigned long sys_get_thread_area(void) +{ + return current_thread_info()->tp_value; +} + +asmlinkage int sys_set_thread_area(unsigned long tp) +{ + current_thread_info()->tp_value = tp; + return 0; +} + +/* This syscall gets its arguments in A0 (mem), D2 (oldval) and + D1 (newval). */ +asmlinkage int +sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, + unsigned long __user * mem) +{ + /* This was borrowed from ARM's implementation. */ + for (;;) { + struct mm_struct *mm = current->mm; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + spinlock_t *ptl; + unsigned long mem_value; + + down_read(&mm->mmap_sem); + pgd = pgd_offset(mm, (unsigned long)mem); + if (!pgd_present(*pgd)) + goto bad_access; + pmd = pmd_offset(pgd, (unsigned long)mem); + if (!pmd_present(*pmd)) + goto bad_access; + pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); + if (!pte_present(*pte) || !pte_dirty(*pte) + || !pte_write(*pte)) { + pte_unmap_unlock(pte, ptl); + goto bad_access; + } + + mem_value = *mem; + if (mem_value == oldval) + *mem = newval; + + pte_unmap_unlock(pte, ptl); + up_read(&mm->mmap_sem); + return mem_value; + + bad_access: + up_read(&mm->mmap_sem); + /* This is not necessarily a bad access, we can get here if + a memory we're trying to write to should be copied-on-write. + Make the kernel do the necessary page stuff, then re-iterate. + Simulate a write access fault to do that. */ + { + /* The first argument of the function corresponds to + D1, which is the first field of struct pt_regs. */ + struct pt_regs *fp = (struct pt_regs *)&newval; + + /* '3' is an RMW flag. */ + if (do_page_fault(fp, (unsigned long)mem, 3)) + /* If the do_page_fault() failed, we don't + have anything meaningful to return. + There should be a SIGSEGV pending for + the process. */ + return 0xdeadbeef; + } + } +} + +asmlinkage int sys_atomic_barrier(void) +{ + /* no code needed for uniprocs */ + return 0; +} diff --git a/arch/m68k/mac/Makefile b/arch/m68k/mac/Makefile index daebd80bdef0..b8d4c835f9a2 100644 --- a/arch/m68k/mac/Makefile +++ b/arch/m68k/mac/Makefile @@ -3,4 +3,4 @@ # obj-y := config.o macints.o iop.o via.o oss.o psc.o \ - baboon.o macboing.o debug.o misc.o + baboon.o macboing.o misc.o diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index be017984a456..0356da9bf763 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #define BOOTINFO_COMPAT_1_0 #include @@ -44,12 +46,7 @@ #include #include -/* platform device info */ - -#define SWIM_IO_SIZE 0x2000 /* SWIM IO resource size */ - /* Mac bootinfo struct */ - struct mac_booter_data mac_bi_data; /* The phys. video addr. - might be bogus on some machines */ @@ -70,8 +67,6 @@ extern void baboon_init(void); extern void mac_mksound(unsigned int, unsigned int); -extern void nubus_sweep_video(void); - static void mac_get_model(char *str); static void mac_identify(void); static void mac_report_hardware(void); @@ -167,12 +162,6 @@ void __init config_mac(void) mach_max_dma_address = 0xffffffff; #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) mach_beep = mac_mksound; -#endif -#ifdef CONFIG_HEARTBEAT -#if 0 - mach_heartbeat = mac_heartbeat; - mach_heartbeat_irq = IRQ_MAC_TIMER; -#endif #endif /* @@ -191,27 +180,19 @@ void __init config_mac(void) if (macintosh_config->ident == MAC_MODEL_IICI || macintosh_config->ident == MAC_MODEL_IIFX) mach_l2_flush = mac_cache_card_flush; - - /* - * Check for machine specific fixups. - */ - -#ifdef OLD_NUBUS_CODE - nubus_sweep_video(); -#endif } /* - * Macintosh Table: hardcoded model configuration data. + * Macintosh Table: hardcoded model configuration data. * - * Much of this was defined by Alan, based on who knows what docs. - * I've added a lot more, and some of that was pure guesswork based - * on hardware pages present on the Mac web site. Possibly wildly - * inaccurate, so look here if a new Mac model won't run. Example: if - * a Mac crashes immediately after the VIA1 registers have been dumped - * to the screen, it probably died attempting to read DirB on a RBV. - * Meaning it should have MAC_VIA_IIci here :-) + * Much of this was defined by Alan, based on who knows what docs. + * I've added a lot more, and some of that was pure guesswork based + * on hardware pages present on the Mac web site. Possibly wildly + * inaccurate, so look here if a new Mac model won't run. Example: if + * a Mac crashes immediately after the VIA1 registers have been dumped + * to the screen, it probably died attempting to read DirB on a RBV. + * Meaning it should have MAC_VIA_IIci here :-) */ struct mac_model *macintosh_config; @@ -219,7 +200,7 @@ EXPORT_SYMBOL(macintosh_config); static struct mac_model mac_data_table[] = { /* - * We'll pretend to be a Macintosh II, that's pretty safe. + * We'll pretend to be a Macintosh II, that's pretty safe. */ { @@ -230,12 +211,11 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_IWM + .floppy_type = MAC_FLOPPY_IWM, }, /* - * Original MacII hardware - * + * Original Mac II hardware */ { @@ -246,7 +226,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_IWM + .floppy_type = MAC_FLOPPY_IWM, }, { .ident = MAC_MODEL_IIX, .name = "IIx", @@ -255,7 +235,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_IICX, .name = "IIcx", @@ -264,7 +244,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_SE30, .name = "SE/30", @@ -273,13 +253,13 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, /* - * Weirdified MacII hardware - all subtly different. Gee thanks - * Apple. All these boxes seem to have VIA2 in a different place to - * the MacII (+1A000 rather than +4000) + * Weirdified Mac II hardware - all subtly different. Gee thanks + * Apple. All these boxes seem to have VIA2 in a different place to + * the Mac II (+1A000 rather than +4000) * CSA: see http://developer.apple.com/technotes/hw/hw_09.html */ @@ -291,7 +271,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_IIFX, .name = "IIfx", @@ -300,7 +280,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_IOP, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_IOP + .floppy_type = MAC_FLOPPY_SWIM_IOP, }, { .ident = MAC_MODEL_IISI, .name = "IIsi", @@ -309,7 +289,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_IIVI, .name = "IIvi", @@ -318,7 +298,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_IIVX, .name = "IIvx", @@ -327,11 +307,11 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, /* - * Classic models (guessing: similar to SE/30 ?? Nope, similar to LC ...) + * Classic models (guessing: similar to SE/30? Nope, similar to LC...) */ { @@ -342,7 +322,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_CCL, .name = "Color Classic", @@ -351,11 +331,11 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, /* - * Some Mac LC machines. Basically the same as the IIci, ADB like IIsi + * Some Mac LC machines. Basically the same as the IIci, ADB like IIsi */ { @@ -366,7 +346,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_LCII, .name = "LC II", @@ -375,7 +355,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_LCIII, .name = "LC III", @@ -384,17 +364,17 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, /* - * Quadra. Video is at 0xF9000000, via is like a MacII. We label it differently - * as some of the stuff connected to VIA2 seems different. Better SCSI chip and - * onboard ethernet using a NatSemi SONIC except the 660AV and 840AV which use an - * AMD 79C940 (MACE). - * The 700, 900 and 950 have some I/O chips in the wrong place to - * confuse us. The 840AV has a SCSI location of its own (same as - * the 660AV). + * Quadra. Video is at 0xF9000000, via is like a MacII. We label it + * differently as some of the stuff connected to VIA2 seems different. + * Better SCSI chip and onboard ethernet using a NatSemi SONIC except + * the 660AV and 840AV which use an AMD 79C940 (MACE). + * The 700, 900 and 950 have some I/O chips in the wrong place to + * confuse us. The 840AV has a SCSI location of its own (same as + * the 660AV). */ { @@ -405,7 +385,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_QUADRA, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_Q605_ACC, .name = "Quadra 605", @@ -414,7 +394,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_QUADRA, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_Q610, .name = "Quadra 610", @@ -424,7 +404,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_QUADRA, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_Q630, .name = "Quadra 630", @@ -435,7 +415,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_QUADRA, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_Q650, .name = "Quadra 650", @@ -445,9 +425,9 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_QUADRA, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, - /* The Q700 does have a NS Sonic */ + /* The Q700 does have a NS Sonic */ { .ident = MAC_MODEL_Q700, .name = "Quadra 700", @@ -457,7 +437,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_QUADRA, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_Q800, .name = "Quadra 800", @@ -467,7 +447,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_QUADRA, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_Q840, .name = "Quadra 840AV", @@ -477,7 +457,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_PSC, .ether_type = MAC_ETHER_MACE, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_AV + .floppy_type = MAC_FLOPPY_AV, }, { .ident = MAC_MODEL_Q900, .name = "Quadra 900", @@ -487,7 +467,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_IOP, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_IOP + .floppy_type = MAC_FLOPPY_SWIM_IOP, }, { .ident = MAC_MODEL_Q950, .name = "Quadra 950", @@ -497,60 +477,60 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_IOP, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_IOP + .floppy_type = MAC_FLOPPY_SWIM_IOP, }, /* - * Performa - more LC type machines + * Performa - more LC type machines */ { .ident = MAC_MODEL_P460, - .name = "Performa 460", + .name = "Performa 460", .adb_type = MAC_ADB_IISI, .via_type = MAC_VIA_IIci, .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_P475, - .name = "Performa 475", + .name = "Performa 475", .adb_type = MAC_ADB_CUDA, .via_type = MAC_VIA_QUADRA, .scsi_type = MAC_SCSI_QUADRA, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_P475F, - .name = "Performa 475", + .name = "Performa 475", .adb_type = MAC_ADB_CUDA, .via_type = MAC_VIA_QUADRA, .scsi_type = MAC_SCSI_QUADRA, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_P520, - .name = "Performa 520", + .name = "Performa 520", .adb_type = MAC_ADB_CUDA, .via_type = MAC_VIA_IIci, .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_P550, - .name = "Performa 550", + .name = "Performa 550", .adb_type = MAC_ADB_CUDA, .via_type = MAC_VIA_IIci, .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, - /* These have the comm slot, and therefore the possibility of SONIC ethernet */ + /* These have the comm slot, and therefore possibly SONIC ethernet */ { .ident = MAC_MODEL_P575, .name = "Performa 575", @@ -560,7 +540,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_II, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_P588, .name = "Performa 588", @@ -571,7 +551,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_II, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_TV, .name = "TV", @@ -580,7 +560,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_P600, .name = "Performa 600", @@ -589,14 +569,14 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, /* - * Centris - just guessing again; maybe like Quadra + * Centris - just guessing again; maybe like Quadra. + * The C610 may or may not have SONIC. We probe to make sure. */ - /* The C610 may or may not have SONIC. We probe to make sure */ { .ident = MAC_MODEL_C610, .name = "Centris 610", @@ -606,7 +586,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_QUADRA, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_C650, .name = "Centris 650", @@ -616,7 +596,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_QUADRA, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR1 + .floppy_type = MAC_FLOPPY_SWIM_ADDR1, }, { .ident = MAC_MODEL_C660, .name = "Centris 660AV", @@ -626,7 +606,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_PSC, .ether_type = MAC_ETHER_MACE, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_AV + .floppy_type = MAC_FLOPPY_AV, }, /* @@ -643,7 +623,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB145, .name = "PowerBook 145", @@ -652,7 +632,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB150, .name = "PowerBook 150", @@ -662,7 +642,7 @@ static struct mac_model mac_data_table[] = { .ide_type = MAC_IDE_PB, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB160, .name = "PowerBook 160", @@ -671,7 +651,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB165, .name = "PowerBook 165", @@ -680,7 +660,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB165C, .name = "PowerBook 165c", @@ -689,7 +669,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB170, .name = "PowerBook 170", @@ -698,7 +678,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB180, .name = "PowerBook 180", @@ -707,7 +687,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB180C, .name = "PowerBook 180c", @@ -716,7 +696,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB190, .name = "PowerBook 190", @@ -726,7 +706,7 @@ static struct mac_model mac_data_table[] = { .ide_type = MAC_IDE_BABOON, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB520, .name = "PowerBook 520", @@ -736,7 +716,7 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_QUADRA, .ether_type = MAC_ETHER_SONIC, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, /* @@ -757,7 +737,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB230, .name = "PowerBook Duo 230", @@ -766,7 +746,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB250, .name = "PowerBook Duo 250", @@ -775,7 +755,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB270C, .name = "PowerBook Duo 270c", @@ -784,7 +764,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB280, .name = "PowerBook Duo 280", @@ -793,7 +773,7 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, { .ident = MAC_MODEL_PB280C, .name = "PowerBook Duo 280c", @@ -802,17 +782,44 @@ static struct mac_model mac_data_table[] = { .scsi_type = MAC_SCSI_OLD, .scc_type = MAC_SCC_QUADRA, .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2 + .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, /* - * Other stuff ?? + * Other stuff? */ + { .ident = -1 } }; +static struct resource scc_a_rsrcs[] = { + { .flags = IORESOURCE_MEM }, + { .flags = IORESOURCE_IRQ }, +}; + +static struct resource scc_b_rsrcs[] = { + { .flags = IORESOURCE_MEM }, + { .flags = IORESOURCE_IRQ }, +}; + +struct platform_device scc_a_pdev = { + .name = "scc", + .id = 0, + .num_resources = ARRAY_SIZE(scc_a_rsrcs), + .resource = scc_a_rsrcs, +}; +EXPORT_SYMBOL(scc_a_pdev); + +struct platform_device scc_b_pdev = { + .name = "scc", + .id = 1, + .num_resources = ARRAY_SIZE(scc_b_rsrcs), + .resource = scc_b_rsrcs, +}; +EXPORT_SYMBOL(scc_b_pdev); + static void __init mac_identify(void) { struct mac_model *m; @@ -823,7 +830,8 @@ static void __init mac_identify(void) /* no bootinfo model id -> NetBSD booter was used! */ /* XXX FIXME: breaks for model > 31 */ model = (mac_bi_data.cpuid >> 2) & 63; - printk(KERN_WARNING "No bootinfo model ID, using cpuid instead (hey, use Penguin!)\n"); + printk(KERN_WARNING "No bootinfo model ID, using cpuid instead " + "(obsolete bootloader?)\n"); } macintosh_config = mac_data_table; @@ -834,10 +842,29 @@ static void __init mac_identify(void) } } - /* We need to pre-init the IOPs, if any. Otherwise */ - /* the serial console won't work if the user had */ - /* the serial ports set to "Faster" mode in MacOS. */ + /* Set up serial port resources for the console initcall. */ + scc_a_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase + 2; + scc_a_rsrcs[0].end = scc_a_rsrcs[0].start; + scc_b_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase; + scc_b_rsrcs[0].end = scc_b_rsrcs[0].start; + + switch (macintosh_config->scc_type) { + case MAC_SCC_PSC: + scc_a_rsrcs[1].start = scc_a_rsrcs[1].end = IRQ_MAC_SCC_A; + scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_MAC_SCC_B; + break; + default: + scc_a_rsrcs[1].start = scc_a_rsrcs[1].end = IRQ_MAC_SCC; + scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_MAC_SCC; + break; + } + + /* + * We need to pre-init the IOPs, if any. Otherwise + * the serial console won't work if the user had + * the serial ports set to "Faster" mode in MacOS. + */ iop_preinit(); printk(KERN_INFO "Detected Macintosh model: %d \n", model); @@ -846,7 +873,8 @@ static void __init mac_identify(void) * Report booter data: */ printk(KERN_DEBUG " Penguin bootinfo data:\n"); - printk(KERN_DEBUG " Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n", + printk(KERN_DEBUG " Video: addr 0x%lx " + "row 0x%lx depth %lx dimensions %ld x %ld\n", mac_bi_data.videoaddr, mac_bi_data.videorow, mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF, mac_bi_data.dimensions >> 16); @@ -863,6 +891,10 @@ static void __init mac_identify(void) oss_init(); psc_init(); baboon_init(); + +#ifdef CONFIG_ADB_CUDA + find_via_cuda(); +#endif } static void __init mac_report_hardware(void) @@ -876,23 +908,50 @@ static void mac_get_model(char *str) strcat(str, macintosh_config->name); } -static struct resource swim_resources[1]; +static struct resource swim_rsrc = { .flags = IORESOURCE_MEM }; -static struct platform_device swim_device = { +static struct platform_device swim_pdev = { .name = "swim", .id = -1, - .num_resources = ARRAY_SIZE(swim_resources), - .resource = swim_resources, + .num_resources = 1, + .resource = &swim_rsrc, }; -static struct platform_device *mac_platform_devices[] __initdata = { - &swim_device +static struct platform_device esp_0_pdev = { + .name = "mac_esp", + .id = 0, +}; + +static struct platform_device esp_1_pdev = { + .name = "mac_esp", + .id = 1, +}; + +static struct platform_device sonic_pdev = { + .name = "macsonic", + .id = -1, +}; + +static struct platform_device mace_pdev = { + .name = "macmace", + .id = -1, }; int __init mac_platform_init(void) { u8 *swim_base; + /* + * Serial devices + */ + + platform_device_register(&scc_a_pdev); + platform_device_register(&scc_b_pdev); + + /* + * Floppy device + */ + switch (macintosh_config->floppy_type) { case MAC_FLOPPY_SWIM_ADDR1: swim_base = (u8 *)(VIA1_BASE + 0x1E000); @@ -901,16 +960,47 @@ int __init mac_platform_init(void) swim_base = (u8 *)(VIA1_BASE + 0x16000); break; default: - return 0; + swim_base = NULL; + break; } - swim_resources[0].name = "swim-regs"; - swim_resources[0].start = (resource_size_t)swim_base; - swim_resources[0].end = (resource_size_t)(swim_base + SWIM_IO_SIZE); - swim_resources[0].flags = IORESOURCE_MEM; + if (swim_base) { + swim_rsrc.start = (resource_size_t) swim_base, + swim_rsrc.end = (resource_size_t) swim_base + 0x2000, + platform_device_register(&swim_pdev); + } - return platform_add_devices(mac_platform_devices, - ARRAY_SIZE(mac_platform_devices)); + /* + * SCSI device(s) + */ + + switch (macintosh_config->scsi_type) { + case MAC_SCSI_QUADRA: + case MAC_SCSI_QUADRA3: + platform_device_register(&esp_0_pdev); + break; + case MAC_SCSI_QUADRA2: + platform_device_register(&esp_0_pdev); + if ((macintosh_config->ident == MAC_MODEL_Q900) || + (macintosh_config->ident == MAC_MODEL_Q950)) + platform_device_register(&esp_1_pdev); + break; + } + + /* + * Ethernet device + */ + + switch (macintosh_config->ether_type) { + case MAC_ETHER_SONIC: + platform_device_register(&sonic_pdev); + break; + case MAC_ETHER_MACE: + platform_device_register(&mace_pdev); + break; + } + + return 0; } arch_initcall(mac_platform_init); diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c deleted file mode 100644 index bce074ceb768..000000000000 --- a/arch/m68k/mac/debug.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * linux/arch/m68k/mac/debug.c - * - * Shamelessly stolen (SCC code and general framework) from: - * - * linux/arch/m68k/atari/debug.c - * - * Atari debugging and serial console stuff - * - * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#include -#include -#include -#include -#include -#include - -#define BOOTINFO_COMPAT_1_0 -#include -#include -#include - -extern unsigned long mac_videobase; -extern unsigned long mac_rowbytes; - -extern void mac_serial_print(const char *); - -#define DEBUG_HEADS -#undef DEBUG_SCREEN -#define DEBUG_SERIAL - -/* - * These two auxiliary debug functions should go away ASAP. Only usage: - * before the console output is up (after head.S come some other crucial - * setup routines :-) it permits writing 'data' to the screen as bit patterns - * (good luck reading those). Helped to figure that the bootinfo contained - * garbage data on the amount and size of memory chunks ... - * - * The 'pos' argument now simply means 'linefeed after print' ... - */ - -#ifdef DEBUG_SCREEN -static int peng, line; -#endif - -#if 0 - -void mac_debugging_short(int pos, short num) -{ -#ifdef DEBUG_SCREEN - unsigned char *pengoffset; - unsigned char *pptr; - int i; -#endif - -#ifdef DEBUG_SERIAL - printk("debug: %d !\n", num); -#endif - -#ifdef DEBUG_SCREEN - if (!MACH_IS_MAC) { - /* printk("debug: %d !\n", num); */ - return; - } - - /* calculate current offset */ - pengoffset = (unsigned char *)mac_videobase + - (150+line*2) * mac_rowbytes + 80 * peng; - - pptr = pengoffset; - - for (i = 0; i < 8 * sizeof(short); i++) { /* # of bits */ - /* value mask for bit i, reverse order */ - *pptr++ = (num & (1 << (8*sizeof(short)-i-1)) ? 0xFF : 0x00); - } - - peng++; - - if (pos) { - line++; - peng = 0; - } -#endif -} - -void mac_debugging_long(int pos, long addr) -{ -#ifdef DEBUG_SCREEN - unsigned char *pengoffset; - unsigned char *pptr; - int i; -#endif - -#ifdef DEBUG_SERIAL - printk("debug: #%ld !\n", addr); -#endif - -#ifdef DEBUG_SCREEN - if (!MACH_IS_MAC) { - /* printk("debug: #%ld !\n", addr); */ - return; - } - - pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes) - +80*peng; - - pptr = pengoffset; - - for (i = 0; i < 8 * sizeof(long); i++) { /* # of bits */ - *pptr++ = (addr & (1 << (8*sizeof(long)-i-1)) ? 0xFF : 0x00); - } - - peng++; - - if (pos) { - line++; - peng = 0; - } -#endif -} - -#endif /* 0 */ - -#ifdef DEBUG_SERIAL -/* - * TODO: serial debug code - */ - -struct mac_SCC { - u_char cha_b_ctrl; - u_char char_dummy1; - u_char cha_a_ctrl; - u_char char_dummy2; - u_char cha_b_data; - u_char char_dummy3; - u_char cha_a_data; -}; - -# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase)) - -static int scc_port = -1; - -static struct console mac_console_driver = { - .name = "debug", - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -/* - * Crude hack to get console output to the screen before the framebuffer - * is initialized (happens a lot later in 2.1!). - * We just use the console routines declared in head.S, this will interfere - * with regular framebuffer console output and should be used exclusively - * to debug kernel problems manifesting before framebuffer init (aka WSOD) - * - * To keep this hack from interfering with the regular console driver, either - * deregister this driver before/on framebuffer console init, or silence this - * function after the fbcon driver is running (will lose console messages!?). - * To debug real early bugs, need to write a 'mac_register_console_hack()' - * that is called from start_kernel() before setup_arch() and just registers - * this driver if Mac. - */ - -static void mac_debug_console_write(struct console *co, const char *str, - unsigned int count) -{ - mac_serial_print(str); -} - - - -/* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/ - -#define uSEC 1 - -static inline void mac_sccb_out(char c) -{ - int i; - - do { - for (i = uSEC; i > 0; --i) - barrier(); - } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ - for (i = uSEC; i > 0; --i) - barrier(); - scc.cha_b_data = c; -} - -static inline void mac_scca_out(char c) -{ - int i; - - do { - for (i = uSEC; i > 0; --i) - barrier(); - } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ - for (i = uSEC; i > 0; --i) - barrier(); - scc.cha_a_data = c; -} - -static void mac_sccb_console_write(struct console *co, const char *str, - unsigned int count) -{ - while (count--) { - if (*str == '\n') - mac_sccb_out('\r'); - mac_sccb_out(*str++); - } -} - -static void mac_scca_console_write(struct console *co, const char *str, - unsigned int count) -{ - while (count--) { - if (*str == '\n') - mac_scca_out('\r'); - mac_scca_out(*str++); - } -} - - -/* The following two functions do a quick'n'dirty initialization of the MFP or - * SCC serial ports. They're used by the debugging interface, kgdb, and the - * serial console code. */ -#define SCCB_WRITE(reg,val) \ - do { \ - int i; \ - scc.cha_b_ctrl = (reg); \ - for (i = uSEC; i > 0; --i) \ - barrier(); \ - scc.cha_b_ctrl = (val); \ - for (i = uSEC; i > 0; --i) \ - barrier(); \ - } while(0) - -#define SCCA_WRITE(reg,val) \ - do { \ - int i; \ - scc.cha_a_ctrl = (reg); \ - for (i = uSEC; i > 0; --i) \ - barrier(); \ - scc.cha_a_ctrl = (val); \ - for (i = uSEC; i > 0; --i) \ - barrier(); \ - } while(0) - -/* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a - * delay of ~ 60us. */ -/* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/ -#define LONG_DELAY() \ - do { \ - int i; \ - for (i = 60*uSEC; i > 0; --i) \ - barrier(); \ - } while(0) - -static void __init mac_init_scc_port(int cflag, int port) -{ - /* - * baud rates: 1200, 1800, 2400, 4800, 9600, 19.2k, 38.4k, 57.6k, 115.2k - */ - - static int clksrc_table[9] = - /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ - { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; - static int clkmode_table[9] = - /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ - { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; - static int div_table[9] = - /* reg12 (BRG low) */ - { 94, 62, 46, 22, 10, 4, 1, 0, 0 }; - - int baud = cflag & CBAUD; - int clksrc, clkmode, div, reg3, reg5; - - if (cflag & CBAUDEX) - baud += B38400; - if (baud < B1200 || baud > B38400+2) - baud = B9600; /* use default 9600bps for non-implemented rates */ - baud -= B1200; /* tables starts at 1200bps */ - - clksrc = clksrc_table[baud]; - clkmode = clkmode_table[baud]; - div = div_table[baud]; - - reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40); - reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */; - - if (port == 1) { - (void)scc.cha_b_ctrl; /* reset reg pointer */ - SCCB_WRITE(9, 0xc0); /* reset */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCB_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | - 0x04 /* 1 stopbit */ | - clkmode); - SCCB_WRITE(3, reg3); - SCCB_WRITE(5, reg5); - SCCB_WRITE(9, 0); /* no interrupts */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCB_WRITE(10, 0); /* NRZ mode */ - SCCB_WRITE(11, clksrc); /* main clock source */ - SCCB_WRITE(12, div); /* BRG value */ - SCCB_WRITE(13, 0); /* BRG high byte */ - SCCB_WRITE(14, 1); - SCCB_WRITE(3, reg3 | 1); - SCCB_WRITE(5, reg5 | 8); - } else if (port == 0) { - (void)scc.cha_a_ctrl; /* reset reg pointer */ - SCCA_WRITE(9, 0xc0); /* reset */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCA_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | - 0x04 /* 1 stopbit */ | - clkmode); - SCCA_WRITE(3, reg3); - SCCA_WRITE(5, reg5); - SCCA_WRITE(9, 0); /* no interrupts */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCA_WRITE(10, 0); /* NRZ mode */ - SCCA_WRITE(11, clksrc); /* main clock source */ - SCCA_WRITE(12, div); /* BRG value */ - SCCA_WRITE(13, 0); /* BRG high byte */ - SCCA_WRITE(14, 1); - SCCA_WRITE(3, reg3 | 1); - SCCA_WRITE(5, reg5 | 8); - } -} -#endif /* DEBUG_SERIAL */ - -static int __init mac_debug_setup(char *arg) -{ - if (!MACH_IS_MAC) - return 0; - -#ifdef DEBUG_SERIAL - if (!strcmp(arg, "ser") || !strcmp(arg, "ser1")) { - /* Mac modem port */ - mac_init_scc_port(B9600|CS8, 0); - mac_console_driver.write = mac_scca_console_write; - scc_port = 0; - } else if (!strcmp(arg, "ser2")) { - /* Mac printer port */ - mac_init_scc_port(B9600|CS8, 1); - mac_console_driver.write = mac_sccb_console_write; - scc_port = 1; - } -#endif -#ifdef DEBUG_HEADS - if (!strcmp(arg, "scn") || !strcmp(arg, "con")) { - /* display, using head.S console routines */ - mac_console_driver.write = mac_debug_console_write; - } -#endif - if (mac_console_driver.write) - register_console(&mac_console_driver); - return 0; -} - -early_param("debug", mac_debug_setup); diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index 23711074e0e2..900d899f3323 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c @@ -34,9 +34,7 @@ * * 3 - unused (?) * - * 4 - SCC (slot number determined by reading RR3 on the SSC itself) - * - slot 1: SCC channel A - * - slot 2: SCC channel B + * 4 - SCC * * 5 - unused (?) * [serial errors or special conditions seem to raise level 6 @@ -55,8 +53,6 @@ * - slot 5: Slot $E * * 4 - SCC IOP - * - slot 1: SCC channel A - * - slot 2: SCC channel B * * 5 - ISM IOP (ADB?) * @@ -136,13 +132,8 @@ #include #include -#define DEBUG_SPURIOUS #define SHUTUP_SONIC -/* SCC interrupt mask */ - -static int scc_mask; - /* * VIA/RBV hooks */ @@ -190,13 +181,6 @@ extern void baboon_irq_enable(int); extern void baboon_irq_disable(int); extern void baboon_irq_clear(int); -/* - * SCC interrupt routines - */ - -static void scc_irq_enable(unsigned int); -static void scc_irq_disable(unsigned int); - /* * console_loglevel determines NMI handler function */ @@ -221,8 +205,6 @@ void __init mac_init_IRQ(void) #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Setting things up...\n"); #endif - scc_mask = 0; - m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, NUM_MAC_SOURCES - IRQ_USER); /* Make sure the SONIC interrupt is cleared or things get ugly */ @@ -283,15 +265,16 @@ void mac_enable_irq(unsigned int irq) via_irq_enable(irq); break; case 3: - case 4: case 5: case 6: if (psc_present) psc_irq_enable(irq); else if (oss_present) oss_irq_enable(irq); - else if (irq_src == 4) - scc_irq_enable(irq); + break; + case 4: + if (psc_present) + psc_irq_enable(irq); break; case 8: if (baboon_present) @@ -316,15 +299,16 @@ void mac_disable_irq(unsigned int irq) via_irq_disable(irq); break; case 3: - case 4: case 5: case 6: if (psc_present) psc_irq_disable(irq); else if (oss_present) oss_irq_disable(irq); - else if (irq_src == 4) - scc_irq_disable(irq); + break; + case 4: + if (psc_present) + psc_irq_disable(irq); break; case 8: if (baboon_present) @@ -347,7 +331,6 @@ void mac_clear_irq(unsigned int irq) via_irq_clear(irq); break; case 3: - case 4: case 5: case 6: if (psc_present) @@ -355,6 +338,10 @@ void mac_clear_irq(unsigned int irq) else if (oss_present) oss_irq_clear(irq); break; + case 4: + if (psc_present) + psc_irq_clear(irq); + break; case 8: if (baboon_present) baboon_irq_clear(irq); @@ -374,13 +361,17 @@ int mac_irq_pending(unsigned int irq) else return via_irq_pending(irq); case 3: - case 4: case 5: case 6: if (psc_present) return psc_irq_pending(irq); else if (oss_present) return oss_irq_pending(irq); + break; + case 4: + if (psc_present) + psc_irq_pending(irq); + break; } return 0; } @@ -448,59 +439,3 @@ irqreturn_t mac_nmi_handler(int irq, void *dev_id) in_nmi--; return IRQ_HANDLED; } - -/* - * Simple routines for masking and unmasking - * SCC interrupts in cases where this can't be - * done in hardware (only the PSC can do that.) - */ - -static void scc_irq_enable(unsigned int irq) -{ - int irq_idx = IRQ_IDX(irq); - - scc_mask |= (1 << irq_idx); -} - -static void scc_irq_disable(unsigned int irq) -{ - int irq_idx = IRQ_IDX(irq); - - scc_mask &= ~(1 << irq_idx); -} - -/* - * SCC master interrupt handler. We have to do a bit of magic here - * to figure out what channel gave us the interrupt; putting this - * here is cleaner than hacking it into drivers/char/macserial.c. - */ - -void mac_scc_dispatch(int irq, void *dev_id) -{ - volatile unsigned char *scc = (unsigned char *) mac_bi_data.sccbase + 2; - unsigned char reg; - unsigned long flags; - - /* Read RR3 from the chip. Always do this on channel A */ - /* This must be an atomic operation so disable irqs. */ - - local_irq_save(flags); - *scc = 3; - reg = *scc; - local_irq_restore(flags); - - /* Now dispatch. Bits 0-2 are for channel B and */ - /* bits 3-5 are for channel A. We can safely */ - /* ignore the remaining bits here. */ - /* */ - /* Note that we're ignoring scc_mask for now. */ - /* If we actually mask the ints then we tend to */ - /* get hammered by very persistent SCC irqs, */ - /* and since they're autovector interrupts they */ - /* pretty much kill the system. */ - - if (reg & 0x38) - m68k_handle_int(IRQ_SCCA); - if (reg & 0x07) - m68k_handle_int(IRQ_SCCB); -} diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index f3d23d6ebcf8..a9c0f5ab4cc0 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -33,7 +33,6 @@ static irqreturn_t oss_irq(int, void *); static irqreturn_t oss_nubus_irq(int, void *); extern irqreturn_t via1_irq(int, void *); -extern irqreturn_t mac_scc_dispatch(int, void *); /* * Initialize the OSS @@ -69,9 +68,6 @@ void __init oss_register_interrupts(void) if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, "scsi", (void *) oss)) pr_err("Couldn't register %s interrupt\n", "scsi"); - if (request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, - "scc", mac_scc_dispatch)) - pr_err("Couldn't register %s interrupt\n", "scc"); if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, "nubus", (void *) oss)) pr_err("Couldn't register %s interrupt\n", "nubus"); @@ -172,9 +168,7 @@ void oss_irq_enable(int irq) { printk("oss_irq_enable(%d)\n", irq); #endif switch(irq) { - case IRQ_SCC: - case IRQ_SCCA: - case IRQ_SCCB: + case IRQ_MAC_SCC: oss->irq_level[OSS_IOPSCC] = OSS_IRQLEV_IOPSCC; break; case IRQ_MAC_ADB: @@ -212,9 +206,7 @@ void oss_irq_disable(int irq) { printk("oss_irq_disable(%d)\n", irq); #endif switch(irq) { - case IRQ_SCC: - case IRQ_SCCA: - case IRQ_SCCB: + case IRQ_MAC_SCC: oss->irq_level[OSS_IOPSCC] = OSS_IRQLEV_DISABLED; break; case IRQ_MAC_ADB: @@ -250,9 +242,7 @@ void oss_irq_disable(int irq) { void oss_irq_clear(int irq) { /* FIXME: how to do this on OSS? */ switch(irq) { - case IRQ_SCC: - case IRQ_SCCA: - case IRQ_SCCB: + case IRQ_MAC_SCC: oss->irq_pending &= ~OSS_IP_IOPSCC; break; case IRQ_MAC_ADB: @@ -280,9 +270,7 @@ void oss_irq_clear(int irq) { int oss_irq_pending(int irq) { switch(irq) { - case IRQ_SCC: - case IRQ_SCCA: - case IRQ_SCCB: + case IRQ_MAC_SCC: return oss->irq_pending & OSS_IP_IOPSCC; break; case IRQ_MAC_ADB: diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index 11bce3cb6482..e71166daec6a 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -84,8 +84,6 @@ void via_irq_enable(int irq); void via_irq_disable(int irq); void via_irq_clear(int irq); -extern irqreturn_t mac_scc_dispatch(int, void *); - /* * Initialize the VIAs * @@ -311,11 +309,6 @@ void __init via_register_interrupts(void) if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, "via2", (void *) via2)) pr_err("Couldn't register %s interrupt\n", "via2"); - if (!psc_present) { - if (request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK, - "scc", mac_scc_dispatch)) - pr_err("Couldn't register %s interrupt\n", "scc"); - } if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2)) pr_err("Couldn't register %s interrupt\n", "nubus"); diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c index df620ac2a296..69345849454b 100644 --- a/arch/m68k/mm/kmap.c +++ b/arch/m68k/mm/kmap.c @@ -99,8 +99,7 @@ static inline void free_io_area(void *addr) #endif /* - * Map some physical address range into the kernel address space. The - * code is copied and adapted from map_chunk(). + * Map some physical address range into the kernel address space. */ /* Rewritten by Andreas Schwab to remove all races. */ @@ -116,7 +115,7 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla /* * Don't allow mappings that wrap.. */ - if (!size || size > physaddr + size) + if (!size || physaddr > (unsigned long)(-size)) return NULL; #ifdef CONFIG_AMIGA diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 5c9ecd427090..959cb249c759 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c @@ -221,6 +221,10 @@ int copy_thread(unsigned long clone_flags, p->thread.usp = usp; p->thread.ksp = (unsigned long)childstack; + + if (clone_flags & CLONE_SETTLS) + task_thread_info(p)->tp_value = regs->d5; + /* * Must save the current SFC/DFC value, NOT the value when * the parent was last descheduled - RGH 10-08-96 diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c index 4d3828959fb0..85ed2f988f98 100644 --- a/arch/m68knommu/kernel/ptrace.c +++ b/arch/m68knommu/kernel/ptrace.c @@ -319,6 +319,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } #endif + case PTRACE_GET_THREAD_AREA: + ret = put_user(task_thread_info(child)->tp_value, + (unsigned long __user *)data); + break; + default: ret = -EIO; break; diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c index b67cbc735a9b..923dd4aab875 100644 --- a/arch/m68knommu/kernel/sys_m68k.c +++ b/arch/m68knommu/kernel/sys_m68k.c @@ -190,3 +190,39 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) : "d" (__a), "d" (__b), "d" (__c)); return __res; } + +asmlinkage unsigned long sys_get_thread_area(void) +{ + return current_thread_info()->tp_value; +} + +asmlinkage int sys_set_thread_area(unsigned long tp) +{ + current_thread_info()->tp_value = tp; + return 0; +} + +/* This syscall gets its arguments in A0 (mem), D2 (oldval) and + D1 (newval). */ +asmlinkage int +sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, + unsigned long __user * mem) +{ + struct mm_struct *mm = current->mm; + unsigned long mem_value; + + down_read(&mm->mmap_sem); + + mem_value = *mem; + if (mem_value == oldval) + *mem = newval; + + up_read(&mm->mmap_sem); + return mem_value; +} + +asmlinkage int sys_atomic_barrier(void) +{ + /* no code needed for uniprocs */ + return 0; +} diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S index 486837efa3d7..56dd01ded148 100644 --- a/arch/m68knommu/kernel/syscalltable.S +++ b/arch/m68knommu/kernel/syscalltable.S @@ -351,6 +351,10 @@ ENTRY(sys_call_table) .long sys_pwritev /* 330 */ .long sys_rt_tgsigqueueinfo .long sys_perf_event_open + .long sys_get_thread_area + .long sys_set_thread_area + .long sys_atomic_cmpxchg_32 /* 335 */ + .long sys_atomic_barrier .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall diff --git a/arch/m68knommu/mm/memory.c b/arch/m68knommu/mm/memory.c index f93b88b51f9f..d5b9e1357808 100644 --- a/arch/m68knommu/mm/memory.c +++ b/arch/m68knommu/mm/memory.c @@ -24,7 +24,6 @@ /* * Map some physical address range into the kernel address space. - * The code is copied and adapted from map_chunk(). */ unsigned long kernel_map(unsigned long paddr, unsigned long size, diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index a5af1d6dda8b..e35cf59cbfde 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -1470,8 +1470,6 @@ repeat: void do_fd_request(struct request_queue * q) { - unsigned long flags; - DPRINT(("do_fd_request for pid %d\n",current->pid)); while( fdc_busy ) sleep_on( &fdc_wait ); fdc_busy = 1; diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 8f569e3df890..821c2833f9cf 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -864,7 +864,7 @@ static int __devinit swim_probe(struct platform_device *dev) struct swim_priv *swd; int ret; - res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs"); + res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) { ret = -ENODEV; goto out; @@ -942,7 +942,7 @@ static int __devexit swim_remove(struct platform_device *dev) iounmap(swd->base); - res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs"); + res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (res) release_mem_region(res->start, resource_size(res)); diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index 994e1a58b987..8b24729fec89 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c @@ -136,7 +136,7 @@ static const struct tty_port_operations scc_port_ops = { * vme_scc_init() and support functions *---------------------------------------------------------------------------*/ -static int scc_init_drivers(void) +static int __init scc_init_drivers(void) { int error; @@ -172,7 +172,7 @@ static int scc_init_drivers(void) /* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1). */ -static void scc_init_portstructs(void) +static void __init scc_init_portstructs(void) { struct scc_port *port; int i; @@ -195,7 +195,7 @@ static void scc_init_portstructs(void) #ifdef CONFIG_MVME147_SCC -static int mvme147_scc_init(void) +static int __init mvme147_scc_init(void) { struct scc_port *port; int error; @@ -298,7 +298,7 @@ fail: #ifdef CONFIG_MVME162_SCC -static int mvme162_scc_init(void) +static int __init mvme162_scc_init(void) { struct scc_port *port; int error; @@ -404,7 +404,7 @@ fail: #ifdef CONFIG_BVME6000_SCC -static int bvme6000_scc_init(void) +static int __init bvme6000_scc_init(void) { struct scc_port *port; int error; @@ -503,7 +503,7 @@ fail_free_b_rx: #endif -static int vme_scc_init(void) +static int __init vme_scc_init(void) { int res = -ENODEV; diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index d840a109f833..1c4ee6e77937 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -317,9 +317,11 @@ static int __init adb_init(void) break; } } - if ((adb_controller == NULL) || adb_controller->init()) { - printk(KERN_WARNING "Warning: no ADB interface detected\n"); + if (adb_controller != NULL && adb_controller->init && + adb_controller->init()) adb_controller = NULL; + if (adb_controller == NULL) { + printk(KERN_WARNING "Warning: no ADB interface detected\n"); } else { #ifdef CONFIG_PPC if (of_machine_is_compatible("AAPL,PowerBook1998") || diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index 62dd1fdafecf..971bc9582a5f 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c @@ -89,7 +89,6 @@ static int cuda_fully_inited; #ifdef CONFIG_ADB static int cuda_probe(void); -static int cuda_init(void); static int cuda_send_request(struct adb_request *req, int sync); static int cuda_adb_autopoll(int devs); static int cuda_reset_adb_bus(void); @@ -107,17 +106,42 @@ int cuda_request(struct adb_request *req, #ifdef CONFIG_ADB struct adb_driver via_cuda_driver = { - "CUDA", - cuda_probe, - cuda_init, - cuda_send_request, - cuda_adb_autopoll, - cuda_poll, - cuda_reset_adb_bus + .name = "CUDA", + .probe = cuda_probe, + .send_request = cuda_send_request, + .autopoll = cuda_adb_autopoll, + .poll = cuda_poll, + .reset_bus = cuda_reset_adb_bus, }; #endif /* CONFIG_ADB */ -#ifdef CONFIG_PPC +#ifdef CONFIG_MAC +int __init find_via_cuda(void) +{ + struct adb_request req; + int err; + + if (macintosh_config->adb_type != MAC_ADB_CUDA) + return 0; + + via = via1; + cuda_state = idle; + + err = cuda_init_via(); + if (err) { + printk(KERN_ERR "cuda_init_via() failed\n"); + via = NULL; + return 0; + } + + /* enable autopoll */ + cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1); + while (!req.complete) + cuda_poll(); + + return 1; +} +#else int __init find_via_cuda(void) { struct adb_request req; @@ -175,7 +199,7 @@ int __init find_via_cuda(void) vias = NULL; return 0; } -#endif /* CONFIG_PPC */ +#endif /* !defined CONFIG_MAC */ static int __init via_cuda_start(void) { @@ -184,14 +208,14 @@ static int __init via_cuda_start(void) #ifdef CONFIG_MAC cuda_irq = IRQ_MAC_ADB; -#else /* CONFIG_MAC */ +#else cuda_irq = irq_of_parse_and_map(vias, 0); if (cuda_irq == NO_IRQ) { printk(KERN_ERR "via-cuda: can't map interrupts for %s\n", vias->full_name); return -ENODEV; } -#endif /* CONFIG_MAC */ +#endif if (request_irq(cuda_irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) { printk(KERN_ERR "via-cuda: can't request irq %d\n", cuda_irq); @@ -216,28 +240,10 @@ cuda_probe(void) #else if (macintosh_config->adb_type != MAC_ADB_CUDA) return -ENODEV; - via = via1; #endif - return 0; -} - -static int __init -cuda_init(void) -{ -#ifdef CONFIG_PPC if (via == NULL) return -ENODEV; return 0; -#else - int err = cuda_init_via(); - if (err) { - printk(KERN_ERR "cuda_init_via() failed\n"); - return -ENODEV; - } - out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */ - - return via_cuda_start(); -#endif } #endif /* CONFIG_ADB */ @@ -430,9 +436,11 @@ cuda_poll(void) /* cuda_interrupt only takes a normal lock, we disable * interrupts here to avoid re-entering and thus deadlocking. */ - disable_irq(cuda_irq); + if (cuda_irq) + disable_irq(cuda_irq); cuda_interrupt(0, NULL); - enable_irq(cuda_irq); + if (cuda_irq) + enable_irq(cuda_irq); } static irqreturn_t @@ -446,7 +454,7 @@ cuda_interrupt(int irq, void *arg) spin_lock(&cuda_lock); - /* On powermacs, this handler is registered for the VIA IRQ. But it uses + /* On powermacs, this handler is registered for the VIA IRQ. But they use * just the shift register IRQ -- other VIA interrupt sources are disabled. * On m68k macs, the VIA IRQ sources are dispatched individually. Unless * we are polling, the shift register IRQ flag has already been cleared. diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index 44f3c2896f20..79408c377875 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c @@ -39,7 +39,6 @@ #include "mace.h" static char mac_mace_string[] = "macmace"; -static struct platform_device *mac_mace_device; #define N_TX_BUFF_ORDER 0 #define N_TX_RING (1 << N_TX_BUFF_ORDER) @@ -752,6 +751,7 @@ static irqreturn_t mace_dma_intr(int irq, void *dev_id) MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Macintosh MACE ethernet driver"); +MODULE_ALIAS("platform:macmace"); static int __devexit mac_mace_device_remove (struct platform_device *pdev) { @@ -777,47 +777,22 @@ static struct platform_driver mac_mace_driver = { .probe = mace_probe, .remove = __devexit_p(mac_mace_device_remove), .driver = { - .name = mac_mace_string, + .name = mac_mace_string, + .owner = THIS_MODULE, }, }; static int __init mac_mace_init_module(void) { - int err; - if (!MACH_IS_MAC) return -ENODEV; - if ((err = platform_driver_register(&mac_mace_driver))) { - printk(KERN_ERR "Driver registration failed\n"); - return err; - } - - mac_mace_device = platform_device_alloc(mac_mace_string, 0); - if (!mac_mace_device) - goto out_unregister; - - if (platform_device_add(mac_mace_device)) { - platform_device_put(mac_mace_device); - mac_mace_device = NULL; - } - - return 0; - -out_unregister: - platform_driver_unregister(&mac_mace_driver); - - return -ENOMEM; + return platform_driver_register(&mac_mace_driver); } static void __exit mac_mace_cleanup_module(void) { platform_driver_unregister(&mac_mace_driver); - - if (mac_mace_device) { - platform_device_unregister(mac_mace_device); - mac_mace_device = NULL; - } } module_init(mac_mace_init_module); diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 875d361fb79d..24109c288108 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c @@ -62,7 +62,6 @@ #include static char mac_sonic_string[] = "macsonic"; -static struct platform_device *mac_sonic_device; #include "sonic.h" @@ -607,6 +606,7 @@ out: MODULE_DESCRIPTION("Macintosh SONIC ethernet driver"); module_param(sonic_debug, int, 0); MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)"); +MODULE_ALIAS("platform:macsonic"); #include "sonic.c" @@ -627,44 +627,19 @@ static struct platform_driver mac_sonic_driver = { .probe = mac_sonic_probe, .remove = __devexit_p(mac_sonic_device_remove), .driver = { - .name = mac_sonic_string, + .name = mac_sonic_string, + .owner = THIS_MODULE, }, }; static int __init mac_sonic_init_module(void) { - int err; - - if ((err = platform_driver_register(&mac_sonic_driver))) { - printk(KERN_ERR "Driver registration failed\n"); - return err; - } - - mac_sonic_device = platform_device_alloc(mac_sonic_string, 0); - if (!mac_sonic_device) - goto out_unregister; - - if (platform_device_add(mac_sonic_device)) { - platform_device_put(mac_sonic_device); - mac_sonic_device = NULL; - } - - return 0; - -out_unregister: - platform_driver_unregister(&mac_sonic_driver); - - return -ENOMEM; + return platform_driver_register(&mac_sonic_driver); } static void __exit mac_sonic_cleanup_module(void) { platform_driver_unregister(&mac_sonic_driver); - - if (mac_sonic_device) { - platform_device_unregister(mac_sonic_device); - mac_sonic_device = NULL; - } } module_init(mac_sonic_init_module); diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index dd808ae942a1..4a90eaf7cb63 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c @@ -52,7 +52,6 @@ struct mac_esp_priv { void __iomem *pdma_io; int error; }; -static struct platform_device *internal_pdev, *external_pdev; static struct esp *esp_chips[2]; #define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \ @@ -495,29 +494,12 @@ static int __devinit esp_mac_probe(struct platform_device *dev) struct Scsi_Host *host; struct esp *esp; int err; - int chips_present; struct mac_esp_priv *mep; if (!MACH_IS_MAC) return -ENODEV; - switch (macintosh_config->scsi_type) { - case MAC_SCSI_QUADRA: - case MAC_SCSI_QUADRA3: - chips_present = 1; - break; - case MAC_SCSI_QUADRA2: - if ((macintosh_config->ident == MAC_MODEL_Q900) || - (macintosh_config->ident == MAC_MODEL_Q950)) - chips_present = 2; - else - chips_present = 1; - break; - default: - chips_present = 0; - } - - if (dev->id + 1 > chips_present) + if (dev->id > 1) return -ENODEV; host = scsi_host_alloc(tpnt, sizeof(struct esp)); @@ -642,55 +624,26 @@ static struct platform_driver esp_mac_driver = { .probe = esp_mac_probe, .remove = __devexit_p(esp_mac_remove), .driver = { - .name = DRV_MODULE_NAME, + .name = DRV_MODULE_NAME, + .owner = THIS_MODULE, }, }; static int __init mac_esp_init(void) { - int err; - - err = platform_driver_register(&esp_mac_driver); - if (err) - return err; - - internal_pdev = platform_device_alloc(DRV_MODULE_NAME, 0); - if (internal_pdev && platform_device_add(internal_pdev)) { - platform_device_put(internal_pdev); - internal_pdev = NULL; - } - external_pdev = platform_device_alloc(DRV_MODULE_NAME, 1); - if (external_pdev && platform_device_add(external_pdev)) { - platform_device_put(external_pdev); - external_pdev = NULL; - } - - if (internal_pdev || external_pdev) { - return 0; - } else { - platform_driver_unregister(&esp_mac_driver); - return -ENOMEM; - } + return platform_driver_register(&esp_mac_driver); } static void __exit mac_esp_exit(void) { platform_driver_unregister(&esp_mac_driver); - - if (internal_pdev) { - platform_device_unregister(internal_pdev); - internal_pdev = NULL; - } - if (external_pdev) { - platform_device_unregister(external_pdev); - external_pdev = NULL; - } } MODULE_DESCRIPTION("Mac ESP SCSI driver"); MODULE_AUTHOR("Finn Thain "); MODULE_LICENSE("GPL v2"); MODULE_VERSION(DRV_VERSION); +MODULE_ALIAS("platform:" DRV_MODULE_NAME); module_init(mac_esp_init); module_exit(mac_esp_exit); diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 9ff47db0b2ce..888a0ce91c4b 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -1086,12 +1086,12 @@ config SERIAL_68360 default y config SERIAL_PMACZILOG - tristate "PowerMac z85c30 ESCC support" - depends on PPC_OF && PPC_PMAC + tristate "Mac or PowerMac z85c30 ESCC support" + depends on (M68K && MAC) || (PPC_OF && PPC_PMAC) select SERIAL_CORE help This driver supports the Zilog z85C30 serial ports found on - PowerMac machines. + (Power)Mac machines. Say Y or M if you want to be able to these serial ports. config SERIAL_PMACZILOG_TTYS @@ -1116,16 +1116,16 @@ config SERIAL_PMACZILOG_TTYS unable to use the 8250 module for PCMCIA or other 16C550-style UARTs. - Say N unless you need the z85c30 ports on your powermac + Say N unless you need the z85c30 ports on your (Power)Mac to appear as /dev/ttySn. config SERIAL_PMACZILOG_CONSOLE - bool "Console on PowerMac z85c30 serial port" + bool "Console on Mac or PowerMac z85c30 serial port" depends on SERIAL_PMACZILOG=y select SERIAL_CORE_CONSOLE help If you would like to be able to use the z85c30 serial port - on your PowerMac as the console, you can do so by answering + on your (Power)Mac as the console, you can do so by answering Y to this option. config SERIAL_LH7A40X diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 3e2ae4807ae2..f020de1cdd50 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -63,11 +63,17 @@ #include #include #include + +#ifdef CONFIG_PPC_PMAC #include #include #include #include #include +#else +#include +#define of_machine_is_compatible(x) (0) +#endif #if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ @@ -83,11 +89,9 @@ static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt )"; MODULE_AUTHOR("Benjamin Herrenschmidt "); -MODULE_DESCRIPTION("Driver for the PowerMac serial ports."); +MODULE_DESCRIPTION("Driver for the Mac and PowerMac serial ports."); MODULE_LICENSE("GPL"); -#define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg) - #ifdef CONFIG_SERIAL_PMACZILOG_TTYS #define PMACZILOG_MAJOR TTY_MAJOR #define PMACZILOG_MINOR 64 @@ -153,8 +157,8 @@ static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs) write_zsreg(uap, R10, regs[R10]); /* Set TX/RX controls sans the enable bits. */ - write_zsreg(uap, R3, regs[R3] & ~RxENABLE); - write_zsreg(uap, R5, regs[R5] & ~TxENABLE); + write_zsreg(uap, R3, regs[R3] & ~RxENABLE); + write_zsreg(uap, R5, regs[R5] & ~TxENABLE); /* now set R7 "prime" on ESCC */ write_zsreg(uap, R15, regs[R15] | EN85C30); @@ -205,7 +209,7 @@ static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs) */ static void pmz_maybe_update_regs(struct uart_pmac_port *uap) { - if (!ZS_REGS_HELD(uap)) { + if (!ZS_REGS_HELD(uap)) { if (ZS_TX_ACTIVE(uap)) { uap->flags |= PMACZILOG_FLAG_REGS_HELD; } else { @@ -281,7 +285,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) spin_lock(&uap->port.lock); if (swallow) goto next_char; - } + } #endif /* CONFIG_MAGIC_SYSRQ && CONFIG_SERIAL_CORE_CONSOLE */ /* A real serial line, record the character and status. */ @@ -317,7 +321,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) if (uap->port.ignore_status_mask == 0xff || (r1 & uap->port.ignore_status_mask) == 0) { - tty_insert_flip_char(tty, ch, flag); + tty_insert_flip_char(tty, ch, flag); } if (r1 & Rx_OVR) tty_insert_flip_char(tty, 0, TTY_OVERRUN); @@ -341,7 +345,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); write_zsreg(uap, R1, uap->curregs[R1]); zssync(uap); - dev_err(&uap->dev->ofdev.dev, "pmz: rx irq flood !\n"); + pmz_error("pmz: rx irq flood !\n"); return tty; } @@ -470,47 +474,47 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) uap_a = pmz_get_port_A(uap); uap_b = uap_a->mate; - - spin_lock(&uap_a->port.lock); + + spin_lock(&uap_a->port.lock); r3 = read_zsreg(uap_a, R3); #ifdef DEBUG_HARD pmz_debug("irq, r3: %x\n", r3); #endif - /* Channel A */ + /* Channel A */ tty = NULL; - if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { + if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { write_zsreg(uap_a, R0, RES_H_IUS); zssync(uap_a); - if (r3 & CHAEXT) - pmz_status_handle(uap_a); + if (r3 & CHAEXT) + pmz_status_handle(uap_a); if (r3 & CHARxIP) tty = pmz_receive_chars(uap_a); - if (r3 & CHATxIP) - pmz_transmit_chars(uap_a); - rc = IRQ_HANDLED; - } - spin_unlock(&uap_a->port.lock); + if (r3 & CHATxIP) + pmz_transmit_chars(uap_a); + rc = IRQ_HANDLED; + } + spin_unlock(&uap_a->port.lock); if (tty != NULL) tty_flip_buffer_push(tty); if (uap_b->node == NULL) goto out; - spin_lock(&uap_b->port.lock); + spin_lock(&uap_b->port.lock); tty = NULL; if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { write_zsreg(uap_b, R0, RES_H_IUS); zssync(uap_b); - if (r3 & CHBEXT) - pmz_status_handle(uap_b); - if (r3 & CHBRxIP) - tty = pmz_receive_chars(uap_b); - if (r3 & CHBTxIP) - pmz_transmit_chars(uap_b); - rc = IRQ_HANDLED; - } - spin_unlock(&uap_b->port.lock); + if (r3 & CHBEXT) + pmz_status_handle(uap_b); + if (r3 & CHBRxIP) + tty = pmz_receive_chars(uap_b); + if (r3 & CHBTxIP) + pmz_transmit_chars(uap_b); + rc = IRQ_HANDLED; + } + spin_unlock(&uap_b->port.lock); if (tty != NULL) tty_flip_buffer_push(tty); @@ -718,7 +722,7 @@ static void pmz_enable_ms(struct uart_port *port) if (ZS_IS_ASLEEP(uap)) return; - /* NOTE: Not subject to 'transmitter active' rule. */ + /* NOTE: Not subject to 'transmitter active' rule. */ write_zsreg(uap, R15, uap->curregs[R15]); } } @@ -748,7 +752,7 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) if (new_reg != uap->curregs[R5]) { uap->curregs[R5] = new_reg; - /* NOTE: Not subject to 'transmitter active' rule. */ + /* NOTE: Not subject to 'transmitter active' rule. */ if (ZS_IS_ASLEEP(uap)) return; write_zsreg(uap, R5, uap->curregs[R5]); @@ -757,6 +761,8 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&port->lock, flags); } +#ifdef CONFIG_PPC_PMAC + /* * Turn power on or off to the SCC and associated stuff * (port drivers, modem, IR port, etc.) @@ -792,6 +798,15 @@ static int pmz_set_scc_power(struct uart_pmac_port *uap, int state) return delay; } +#else + +static int pmz_set_scc_power(struct uart_pmac_port *uap, int state) +{ + return 0; +} + +#endif /* !CONFIG_PPC_PMAC */ + /* * FixZeroBug....Works around a bug in the SCC receving channel. * Inspired from Darwin code, 15 Sept. 2000 -DanM @@ -908,7 +923,6 @@ static int __pmz_startup(struct uart_pmac_port *uap) /* Remember status for DCD/CTS changes */ uap->prev_status = read_zsreg(uap, R0); - return pwr_delay; } @@ -955,9 +969,9 @@ static int pmz_startup(struct uart_port *port) } pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON; - if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, "PowerMac Zilog", uap)) { - dev_err(&uap->dev->ofdev.dev, - "Unable to register zs interrupt handler.\n"); + if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, + "SCC", uap)) { + pmz_error("Unable to register zs interrupt handler.\n"); pmz_set_scc_power(uap, 0); mutex_unlock(&pmz_irq_mutex); return -ENXIO; @@ -983,7 +997,7 @@ static int pmz_startup(struct uart_port *port) if (!ZS_IS_EXTCLK(uap)) uap->curregs[R1] |= EXT_INT_ENAB; write_zsreg(uap, R1, uap->curregs[R1]); - spin_unlock_irqrestore(&port->lock, flags); + spin_unlock_irqrestore(&port->lock, flags); pmz_debug("pmz: startup() done.\n"); @@ -1003,7 +1017,7 @@ static void pmz_shutdown(struct uart_port *port) mutex_lock(&pmz_irq_mutex); /* Release interrupt handler */ - free_irq(uap->port.irq, uap); + free_irq(uap->port.irq, uap); spin_lock_irqsave(&port->lock, flags); @@ -1051,7 +1065,6 @@ static void pmz_convert_to_zs(struct uart_pmac_port *uap, unsigned int cflag, { int brg; - /* Switch to external clocking for IrDA high clock rates. That * code could be re-used for Midi interfaces with different * multipliers @@ -1198,7 +1211,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0 || (read_zsreg(uap, R1) & ALL_SNT) == 0) { if (--t <= 0) { - dev_err(&uap->dev->ofdev.dev, "transmitter didn't drain\n"); + pmz_error("transmitter didn't drain\n"); return; } udelay(10); @@ -1214,7 +1227,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) read_zsdata(uap); mdelay(10); if (--t <= 0) { - dev_err(&uap->dev->ofdev.dev, "receiver didn't drain\n"); + pmz_error("receiver didn't drain\n"); return; } } @@ -1223,20 +1236,19 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) uap->curregs[R5] |= DTR; write_zsreg(uap, R5, uap->curregs[R5]); zssync(uap); - mdelay(1); + mdelay(1); /* Switch SCC to 19200 */ pmz_convert_to_zs(uap, CS8, 0, 19200); pmz_load_zsregs(uap, uap->curregs); - mdelay(1); + mdelay(1); /* Write get_version command byte */ write_zsdata(uap, 1); t = 5000; while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { if (--t <= 0) { - dev_err(&uap->dev->ofdev.dev, - "irda_setup timed out on get_version byte\n"); + pmz_error("irda_setup timed out on get_version byte\n"); goto out; } udelay(10); @@ -1244,8 +1256,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) version = read_zsdata(uap); if (version < 4) { - dev_info(&uap->dev->ofdev.dev, "IrDA: dongle version %d not supported\n", - version); + pmz_info("IrDA: dongle version %d not supported\n", version); goto out; } @@ -1254,18 +1265,16 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) t = 5000; while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { if (--t <= 0) { - dev_err(&uap->dev->ofdev.dev, - "irda_setup timed out on speed mode byte\n"); + pmz_error("irda_setup timed out on speed mode byte\n"); goto out; } udelay(10); } t = read_zsdata(uap); if (t != cmdbyte) - dev_err(&uap->dev->ofdev.dev, - "irda_setup speed mode byte = %x (%x)\n", t, cmdbyte); + pmz_error("irda_setup speed mode byte = %x (%x)\n", t, cmdbyte); - dev_info(&uap->dev->ofdev.dev, "IrDA setup for %ld bps, dongle version: %d\n", + pmz_info("IrDA setup for %ld bps, dongle version: %d\n", *baud, version); (void)read_zsdata(uap); @@ -1415,7 +1424,7 @@ static void pmz_poll_put_char(struct uart_port *port, unsigned char c) write_zsdata(uap, c); } -#endif +#endif /* CONFIG_CONSOLE_POLL */ static struct uart_ops pmz_pops = { .tx_empty = pmz_tx_empty, @@ -1440,6 +1449,8 @@ static struct uart_ops pmz_pops = { #endif }; +#ifdef CONFIG_PPC_PMAC + /* * Setup one port structure after probing, HW is down at this point, * Unlike sunzilog, we don't need to pre-init the spinlock as we don't @@ -1463,7 +1474,7 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) return -ENODEV; uap->port.mapbase = r_ports.start; uap->port.membase = ioremap(uap->port.mapbase, 0x1000); - + uap->control_reg = uap->port.membase; uap->data_reg = uap->control_reg + 0x10; @@ -1590,7 +1601,7 @@ static void pmz_dispose_port(struct uart_pmac_port *uap) } /* - * Called upon match with an escc node in the devive-tree. + * Called upon match with an escc node in the device-tree. */ static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) { @@ -1812,7 +1823,7 @@ static int __init pmz_probe(void) pmz_ports[count].node = node_a; pmz_ports[count+1].node = node_b; pmz_ports[count].port.line = count; - pmz_ports[count+1].port.line = count+1; + pmz_ports[count+1].port.line = count+1; /* * Setup the ports for real @@ -1836,6 +1847,88 @@ next: return 0; } +#else + +extern struct platform_device scc_a_pdev, scc_b_pdev; + +static int __init pmz_init_port(struct uart_pmac_port *uap) +{ + struct resource *r_ports; + int irq; + + r_ports = platform_get_resource(uap->node, IORESOURCE_MEM, 0); + irq = platform_get_irq(uap->node, 0); + if (!r_ports || !irq) + return -ENODEV; + + uap->port.mapbase = r_ports->start; + uap->port.membase = (unsigned char __iomem *) r_ports->start; + uap->port.iotype = UPIO_MEM; + uap->port.irq = irq; + uap->port.uartclk = ZS_CLOCK; + uap->port.fifosize = 1; + uap->port.ops = &pmz_pops; + uap->port.type = PORT_PMAC_ZILOG; + uap->port.flags = 0; + + uap->control_reg = uap->port.membase; + uap->data_reg = uap->control_reg + 4; + uap->port_type = 0; + + pmz_convert_to_zs(uap, CS8, 0, 9600); + + return 0; +} + +static int __init pmz_probe(void) +{ + int err; + + pmz_ports_count = 0; + + pmz_ports[0].mate = &pmz_ports[1]; + pmz_ports[0].port.line = 0; + pmz_ports[0].flags = PMACZILOG_FLAG_IS_CHANNEL_A; + pmz_ports[0].node = &scc_a_pdev; + err = pmz_init_port(&pmz_ports[0]); + if (err) + return err; + pmz_ports_count++; + + pmz_ports[1].mate = &pmz_ports[0]; + pmz_ports[1].port.line = 1; + pmz_ports[1].flags = 0; + pmz_ports[1].node = &scc_b_pdev; + err = pmz_init_port(&pmz_ports[1]); + if (err) + return err; + pmz_ports_count++; + + return 0; +} + +static void pmz_dispose_port(struct uart_pmac_port *uap) +{ + memset(uap, 0, sizeof(struct uart_pmac_port)); +} + +static int __init pmz_attach(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < pmz_ports_count; i++) + if (pmz_ports[i].node == pdev) + return 0; + return -ENODEV; +} + +static int __exit pmz_detach(struct platform_device *pdev) +{ + return 0; +} + +#endif /* !CONFIG_PPC_PMAC */ + #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE static void pmz_console_write(struct console *con, const char *s, unsigned int count); @@ -1896,28 +1989,41 @@ err_out: return rc; } +#ifdef CONFIG_PPC_PMAC + static struct of_device_id pmz_match[] = { { - .name = "ch-a", + .name = "ch-a", }, { - .name = "ch-b", + .name = "ch-b", }, {}, }; MODULE_DEVICE_TABLE (of, pmz_match); -static struct macio_driver pmz_driver = -{ +static struct macio_driver pmz_driver = { .name = "pmac_zilog", .match_table = pmz_match, .probe = pmz_attach, .remove = pmz_detach, .suspend = pmz_suspend, - .resume = pmz_resume, + .resume = pmz_resume, }; +#else + +static struct platform_driver pmz_driver = { + .remove = __exit_p(pmz_detach), + .driver = { + .name = "scc", + .owner = THIS_MODULE, + }, +}; + +#endif /* !CONFIG_PPC_PMAC */ + static int __init init_pmz(void) { int rc, i; @@ -1952,19 +2058,27 @@ static int __init init_pmz(void) pmz_dispose_port(&pmz_ports[i]); return rc; } - + /* * Then we register the macio driver itself */ +#ifdef CONFIG_PPC_PMAC return macio_register_driver(&pmz_driver); +#else + return platform_driver_probe(&pmz_driver, pmz_attach); +#endif } static void __exit exit_pmz(void) { int i; +#ifdef CONFIG_PPC_PMAC /* Get rid of macio-driver (detach from macio) */ macio_unregister_driver(&pmz_driver); +#else + platform_driver_unregister(&pmz_driver); +#endif for (i = 0; i < pmz_ports_count; i++) { struct uart_pmac_port *uport = &pmz_ports[i]; @@ -2034,7 +2148,7 @@ static int __init pmz_console_setup(struct console *co, char *options) if (of_machine_is_compatible("RackMac1,1") || of_machine_is_compatible("RackMac1,2") || of_machine_is_compatible("MacRISC4")) - baud = 57600; + baud = 57600; /* * Check whether an invalid uart number has been specified, and diff --git a/drivers/serial/pmac_zilog.h b/drivers/serial/pmac_zilog.h index f6e77f12acd5..cbc34fbb1b20 100644 --- a/drivers/serial/pmac_zilog.h +++ b/drivers/serial/pmac_zilog.h @@ -1,7 +1,15 @@ #ifndef __PMAC_ZILOG_H__ #define __PMAC_ZILOG_H__ -#define pmz_debug(fmt,arg...) dev_dbg(&uap->dev->ofdev.dev, fmt, ## arg) +#ifdef CONFIG_PPC_PMAC +#define pmz_debug(fmt, arg...) dev_dbg(&uap->dev->ofdev.dev, fmt, ## arg) +#define pmz_error(fmt, arg...) dev_err(&uap->dev->ofdev.dev, fmt, ## arg) +#define pmz_info(fmt, arg...) dev_info(&uap->dev->ofdev.dev, fmt, ## arg) +#else +#define pmz_debug(fmt, arg...) dev_dbg(&uap->node->dev, fmt, ## arg) +#define pmz_error(fmt, arg...) dev_err(&uap->node->dev, fmt, ## arg) +#define pmz_info(fmt, arg...) dev_info(&uap->node->dev, fmt, ## arg) +#endif /* * At most 2 ESCCs with 2 ports each @@ -17,6 +25,7 @@ struct uart_pmac_port { struct uart_port port; struct uart_pmac_port *mate; +#ifdef CONFIG_PPC_PMAC /* macio_dev for the escc holding this port (maybe be null on * early inited port) */ @@ -25,6 +34,9 @@ struct uart_pmac_port { * of "escc" node (ie. ch-a or ch-b) */ struct device_node *node; +#else + struct platform_device *node; +#endif /* Port type as obtained from device tree (IRDA, modem, ...) */ int port_type; @@ -55,10 +67,12 @@ struct uart_pmac_port { volatile u8 __iomem *control_reg; volatile u8 __iomem *data_reg; +#ifdef CONFIG_PPC_PMAC unsigned int tx_dma_irq; unsigned int rx_dma_irq; volatile struct dbdma_regs __iomem *tx_dma_regs; volatile struct dbdma_regs __iomem *rx_dma_regs; +#endif struct ktermios termios_cache; }; @@ -113,7 +127,7 @@ static inline void zssync(struct uart_pmac_port *port) #define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2)) #define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) -#define ZS_CLOCK 3686400 /* Z8530 RTxC input clock rate */ +#define ZS_CLOCK 3686400 /* Z8530 RTxC input clock rate */ /* The Zilog register set */ @@ -171,7 +185,7 @@ static inline void zssync(struct uart_pmac_port *port) /* Write Register 3 */ -#define RxENABLE 0x1 /* Rx Enable */ +#define RxENABLE 0x1 /* Rx Enable */ #define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ #define ADD_SM 0x4 /* Address Search Mode (SDLC) */ #define RxCRC_ENAB 0x8 /* Rx CRC Enable */ @@ -185,7 +199,7 @@ static inline void zssync(struct uart_pmac_port *port) /* Write Register 4 */ -#define PAR_ENAB 0x1 /* Parity Enable */ +#define PAR_ENAB 0x1 /* Parity Enable */ #define PAR_EVEN 0x2 /* Parity Even/Odd* */ #define SYNC_ENAB 0 /* Sync Modes Enable */ @@ -210,7 +224,7 @@ static inline void zssync(struct uart_pmac_port *port) #define TxCRC_ENAB 0x1 /* Tx CRC Enable */ #define RTS 0x2 /* RTS */ #define SDLC_CRC 0x4 /* SDLC/CRC-16 */ -#define TxENABLE 0x8 /* Tx Enable */ +#define TxENABLE 0x8 /* Tx Enable */ #define SND_BRK 0x10 /* Send Break */ #define Tx5 0x0 /* Tx 5 bits (or less)/character */ #define Tx7 0x20 /* Tx 7 bits/character */ @@ -372,11 +386,11 @@ static inline void zssync(struct uart_pmac_port *port) #define ZS_TX_ACTIVE(UP) ((UP)->flags & PMACZILOG_FLAG_TX_ACTIVE) #define ZS_WANTS_MODEM_STATUS(UP) ((UP)->flags & PMACZILOG_FLAG_MODEM_STATUS) #define ZS_IS_IRDA(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRDA) -#define ZS_IS_INTMODEM(UP) ((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM) +#define ZS_IS_INTMODEM(UP) ((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM) #define ZS_HAS_DMA(UP) ((UP)->flags & PMACZILOG_FLAG_HAS_DMA) -#define ZS_IS_ASLEEP(UP) ((UP)->flags & PMACZILOG_FLAG_IS_ASLEEP) -#define ZS_IS_OPEN(UP) ((UP)->flags & PMACZILOG_FLAG_IS_OPEN) -#define ZS_IS_IRQ_ON(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRQ_ON) -#define ZS_IS_EXTCLK(UP) ((UP)->flags & PMACZILOG_FLAG_IS_EXTCLK) +#define ZS_IS_ASLEEP(UP) ((UP)->flags & PMACZILOG_FLAG_IS_ASLEEP) +#define ZS_IS_OPEN(UP) ((UP)->flags & PMACZILOG_FLAG_IS_OPEN) +#define ZS_IS_IRQ_ON(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRQ_ON) +#define ZS_IS_EXTCLK(UP) ((UP)->flags & PMACZILOG_FLAG_IS_EXTCLK) #endif /* __PMAC_ZILOG_H__ */ diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c index d66887e8cbb1..43207cc6cc19 100644 --- a/drivers/video/macfb.c +++ b/drivers/video/macfb.c @@ -1,29 +1,33 @@ -/* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we - don't know how to set */ - -/* (c) 1999 David Huggins-Daines - - Primarily based on vesafb.c, by Gerd Knorr - (c) 1998 Gerd Knorr - - Also uses information and code from: - - The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen - Mellinger, Mikael Forselius, Michael Schmitz, and others. - - valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan - Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven. - - This code is free software. You may copy, modify, and distribute - it subject to the terms and conditions of the GNU General Public - License, version 2, or any later version, at your convenience. */ +/* + * macfb.c: Generic framebuffer for Macs whose colourmaps/modes we + * don't know how to set. + * + * (c) 1999 David Huggins-Daines + * + * Primarily based on vesafb.c, by Gerd Knorr + * (c) 1998 Gerd Knorr + * + * Also uses information and code from: + * + * The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen + * Mellinger, Mikael Forselius, Michael Schmitz, and others. + * + * valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan + * Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven. + * + * The VideoToolbox "Bugs" web page at + * http://rajsky.psych.nyu.edu/Tips/VideoBugs.html + * + * This code is free software. You may copy, modify, and distribute + * it subject to the terms and conditions of the GNU General Public + * License, version 2, or any later version, at your convenience. + */ #include #include #include #include #include -#include #include #include #include @@ -31,9 +35,6 @@ #include #include -#include -#include -#include #include #include @@ -44,7 +45,7 @@ #define DAFB_BASE 0xf9800200 /* Address for the built-in Civic framebuffer in Quadra AVs */ -#define CIVIC_BASE 0x50f30800 /* Only tested on 660AV! */ +#define CIVIC_BASE 0x50f30800 /* GSC (Gray Scale Controller) base address */ #define GSC_BASE 0x50F20000 @@ -52,37 +53,9 @@ /* CSC (Color Screen Controller) base address */ #define CSC_BASE 0x50F20000 -static int (*macfb_setpalette) (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *info) = NULL; -static int valkyrie_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *info); -static int dafb_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *fb_info); -static int rbv_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *fb_info); -static int mdc_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *fb_info); -static int toby_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *fb_info); -static int civic_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *fb_info); -static int csc_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *fb_info); - -static struct { - unsigned char addr; - /* Note: word-aligned */ - char pad[3]; - unsigned char lut; -} __iomem *valkyrie_cmap_regs; +static int (*macfb_setpalette)(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + struct fb_info *info); static struct { unsigned char addr; @@ -116,15 +89,15 @@ static struct { } __iomem *civic_cmap_regs; static struct { - char pad1[0x40]; - unsigned char clut_waddr; /* 0x40 */ - char pad2; - unsigned char clut_data; /* 0x42 */ - char pad3[0x3]; - unsigned char clut_raddr; /* 0x46 */ + char pad1[0x40]; + unsigned char clut_waddr; /* 0x40 */ + char pad2; + unsigned char clut_data; /* 0x42 */ + char pad3[0x3]; + unsigned char clut_raddr; /* 0x46 */ } __iomem *csc_cmap_regs; -/* We will leave these the way they are for the time being */ +/* The registers in these structs are in NuBus slot space */ struct mdc_cmap_regs { char pad1[0x200200]; unsigned char addr; @@ -145,13 +118,10 @@ struct jet_cmap_regs { unsigned char lut; }; -#define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */ - -/* mode */ -static int video_slot = 0; +#define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */ static struct fb_var_screeninfo macfb_defined = { - .bits_per_pixel = 8, + .bits_per_pixel = 8, .activate = FB_ACTIVATE_NOW, .width = -1, .height = -1, @@ -167,181 +137,152 @@ static struct fb_fix_screeninfo macfb_fix = { .accel = FB_ACCEL_NONE, }; +static void *slot_addr; static struct fb_info fb_info; static u32 pseudo_palette[16]; -static int inverse = 0; -static int vidtest = 0; +static int inverse; +static int vidtest; -static int valkyrie_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *info) +/* + * Unlike the Valkyrie, the DAFB cannot set individual colormap + * registers. Therefore, we do what the MacOS driver does (no + * kidding!) and simply set them one by one until we hit the one we + * want. + */ +static int dafb_setpalette(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + struct fb_info *info) { - unsigned long flags; - - red >>= 8; - green >>= 8; - blue >>= 8; - - local_irq_save(flags); - - /* tell clut which address to fill */ - nubus_writeb(regno, &valkyrie_cmap_regs->addr); - nop(); - - /* send one color channel at a time */ - nubus_writeb(red, &valkyrie_cmap_regs->lut); - nop(); - nubus_writeb(green, &valkyrie_cmap_regs->lut); - nop(); - nubus_writeb(blue, &valkyrie_cmap_regs->lut); - - local_irq_restore(flags); - return 0; -} - -/* Unlike the Valkyrie, the DAFB cannot set individual colormap - registers. Therefore, we do what the MacOS driver does (no - kidding!) and simply set them one by one until we hit the one we - want. */ -static int dafb_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *info) -{ - /* FIXME: really, really need to use ioremap() here, - phys_to_virt() doesn't work anymore */ static int lastreg = -1; unsigned long flags; - - red >>= 8; - green >>= 8; - blue >>= 8; local_irq_save(flags); - - /* fbdev will set an entire colourmap, but X won't. Hopefully - this should accommodate both of them */ - if (regno != lastreg+1) { + + /* + * fbdev will set an entire colourmap, but X won't. Hopefully + * this should accommodate both of them + */ + if (regno != lastreg + 1) { int i; - + /* Stab in the dark trying to reset the CLUT pointer */ nubus_writel(0, &dafb_cmap_regs->reset); nop(); - + /* Loop until we get to the register we want */ for (i = 0; i < regno; i++) { - nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut); + nubus_writeb(info->cmap.red[i] >> 8, + &dafb_cmap_regs->lut); nop(); - nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut); + nubus_writeb(info->cmap.green[i] >> 8, + &dafb_cmap_regs->lut); nop(); - nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut); + nubus_writeb(info->cmap.blue[i] >> 8, + &dafb_cmap_regs->lut); nop(); } } - + nubus_writeb(red, &dafb_cmap_regs->lut); nop(); nubus_writeb(green, &dafb_cmap_regs->lut); nop(); nubus_writeb(blue, &dafb_cmap_regs->lut); - + local_irq_restore(flags); lastreg = regno; return 0; } /* V8 and Brazil seem to use the same DAC. Sonora does as well. */ -static int v8_brazil_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *info) +static int v8_brazil_setpalette(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + struct fb_info *info) { unsigned int bpp = info->var.bits_per_pixel; - unsigned char _red =red>>8; - unsigned char _green=green>>8; - unsigned char _blue =blue>>8; - unsigned char _regno; unsigned long flags; - if (bpp > 8) return 1; /* failsafe */ + if (bpp > 8) + return 1; /* failsafe */ local_irq_save(flags); /* On these chips, the CLUT register numbers are spread out - across the register space. Thus: - - In 8bpp, all regnos are valid. - - In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc - - In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */ - _regno = (regno << (8 - bpp)) | (0xFF >> bpp); - nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop(); + * across the register space. Thus: + * In 8bpp, all regnos are valid. + * In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc + * In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff + */ + regno = (regno << (8 - bpp)) | (0xFF >> bpp); + nubus_writeb(regno, &v8_brazil_cmap_regs->addr); + nop(); /* send one color channel at a time */ - nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop(); - nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop(); - nubus_writeb(_blue, &v8_brazil_cmap_regs->lut); + nubus_writeb(red, &v8_brazil_cmap_regs->lut); + nop(); + nubus_writeb(green, &v8_brazil_cmap_regs->lut); + nop(); + nubus_writeb(blue, &v8_brazil_cmap_regs->lut); - local_irq_restore(flags); + local_irq_restore(flags); return 0; } -static int rbv_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *info) +/* RAM-Based Video */ +static int rbv_setpalette(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + struct fb_info *info) { - /* use MSBs */ - unsigned char _red =red>>8; - unsigned char _green=green>>8; - unsigned char _blue =blue>>8; - unsigned char _regno; unsigned long flags; - if (info->var.bits_per_pixel > 8) return 1; /* failsafe */ + if (info->var.bits_per_pixel > 8) + return 1; /* failsafe */ local_irq_save(flags); - + /* From the VideoToolbox driver. Seems to be saying that * regno #254 and #255 are the important ones for 1-bit color, * regno #252-255 are the important ones for 2-bit color, etc. */ - _regno = regno + (256-(1 << info->var.bits_per_pixel)); + regno += 256 - (1 << info->var.bits_per_pixel); /* reset clut? (VideoToolbox sez "not necessary") */ - nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop(); - + nubus_writeb(0xFF, &rbv_cmap_regs->cntl); + nop(); + /* tell clut which address to use. */ - nubus_writeb(_regno, &rbv_cmap_regs->addr); nop(); - + nubus_writeb(regno, &rbv_cmap_regs->addr); + nop(); + /* send one color channel at a time. */ - nubus_writeb(_red, &rbv_cmap_regs->lut); nop(); - nubus_writeb(_green, &rbv_cmap_regs->lut); nop(); - nubus_writeb(_blue, &rbv_cmap_regs->lut); - - local_irq_restore(flags); /* done. */ + nubus_writeb(red, &rbv_cmap_regs->lut); + nop(); + nubus_writeb(green, &rbv_cmap_regs->lut); + nop(); + nubus_writeb(blue, &rbv_cmap_regs->lut); + + local_irq_restore(flags); return 0; } -/* Macintosh Display Card (8x24) */ +/* Macintosh Display Card (8*24) */ static int mdc_setpalette(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, struct fb_info *info) { - volatile struct mdc_cmap_regs *cmap_regs = - nubus_slot_addr(video_slot); - /* use MSBs */ - unsigned char _red =red>>8; - unsigned char _green=green>>8; - unsigned char _blue =blue>>8; - unsigned char _regno=regno; + struct mdc_cmap_regs *cmap_regs = slot_addr; unsigned long flags; local_irq_save(flags); - + /* the nop's are there to order writes. */ - nubus_writeb(_regno, &cmap_regs->addr); nop(); - nubus_writeb(_red, &cmap_regs->lut); nop(); - nubus_writeb(_green, &cmap_regs->lut); nop(); - nubus_writeb(_blue, &cmap_regs->lut); + nubus_writeb(regno, &cmap_regs->addr); + nop(); + nubus_writeb(red, &cmap_regs->lut); + nop(); + nubus_writeb(green, &cmap_regs->lut); + nop(); + nubus_writeb(blue, &cmap_regs->lut); local_irq_restore(flags); return 0; @@ -350,24 +291,26 @@ static int mdc_setpalette(unsigned int regno, unsigned int red, /* Toby frame buffer */ static int toby_setpalette(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, - struct fb_info *info) + struct fb_info *info) { - volatile struct toby_cmap_regs *cmap_regs = - nubus_slot_addr(video_slot); + struct toby_cmap_regs *cmap_regs = slot_addr; unsigned int bpp = info->var.bits_per_pixel; - /* use MSBs */ - unsigned char _red =~(red>>8); - unsigned char _green=~(green>>8); - unsigned char _blue =~(blue>>8); - unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp); unsigned long flags; + red = ~red; + green = ~green; + blue = ~blue; + regno = (regno << (8 - bpp)) | (0xFF >> bpp); + local_irq_save(flags); - - nubus_writeb(_regno, &cmap_regs->addr); nop(); - nubus_writeb(_red, &cmap_regs->lut); nop(); - nubus_writeb(_green, &cmap_regs->lut); nop(); - nubus_writeb(_blue, &cmap_regs->lut); + + nubus_writeb(regno, &cmap_regs->addr); + nop(); + nubus_writeb(red, &cmap_regs->lut); + nop(); + nubus_writeb(green, &cmap_regs->lut); + nop(); + nubus_writeb(blue, &cmap_regs->lut); local_irq_restore(flags); return 0; @@ -378,20 +321,18 @@ static int jet_setpalette(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, struct fb_info *info) { - volatile struct jet_cmap_regs *cmap_regs = - nubus_slot_addr(video_slot); - /* use MSBs */ - unsigned char _red = (red>>8); - unsigned char _green = (green>>8); - unsigned char _blue = (blue>>8); + struct jet_cmap_regs *cmap_regs = slot_addr; unsigned long flags; local_irq_save(flags); - - nubus_writeb(regno, &cmap_regs->addr); nop(); - nubus_writeb(_red, &cmap_regs->lut); nop(); - nubus_writeb(_green, &cmap_regs->lut); nop(); - nubus_writeb(_blue, &cmap_regs->lut); + + nubus_writeb(regno, &cmap_regs->addr); + nop(); + nubus_writeb(red, &cmap_regs->lut); + nop(); + nubus_writeb(green, &cmap_regs->lut); + nop(); + nubus_writeb(blue, &cmap_regs->lut); local_irq_restore(flags); return 0; @@ -400,53 +341,27 @@ static int jet_setpalette(unsigned int regno, unsigned int red, /* * Civic framebuffer -- Quadra AV built-in video. A chip * called Sebastian holds the actual color palettes, and - * apparently, there are two different banks of 512K RAM + * apparently, there are two different banks of 512K RAM * which can act as separate framebuffers for doing video * input and viewing the screen at the same time! The 840AV - * Can add another 1MB RAM to give the two framebuffers + * Can add another 1MB RAM to give the two framebuffers * 1MB RAM apiece. - * - * FIXME: this doesn't seem to work anymore. */ -static int civic_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *info) +static int civic_setpalette(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + struct fb_info *info) { - static int lastreg = -1; unsigned long flags; int clut_status; - if (info->var.bits_per_pixel > 8) return 1; /* failsafe */ - - red >>= 8; - green >>= 8; - blue >>= 8; + if (info->var.bits_per_pixel > 8) + return 1; /* failsafe */ local_irq_save(flags); - - /* - * Set the register address - */ - nubus_writeb(regno, &civic_cmap_regs->addr); nop(); - /* - * Wait for VBL interrupt here; - * They're usually not enabled from Penguin, so we won't check - */ -#if 0 - { -#define CIVIC_VBL_OFFSET 0x120 - volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET); - /* do interrupt setup stuff here? */ - *vbl = 0L; nop(); /* clear */ - *vbl = 1L; nop(); /* set */ - while (*vbl != 0L) /* wait for next vbl */ - { - usleep(10); /* needed? */ - } - /* do interrupt shutdown stuff here? */ - } -#endif + /* Set the register address */ + nubus_writeb(regno, &civic_cmap_regs->addr); + nop(); /* * Grab a status word and do some checking; @@ -459,39 +374,52 @@ static int civic_setpalette (unsigned int regno, unsigned int red, #if 0 if ((clut_status & 0x000D) != 0) { - nubus_writeb(0x00, &civic_cmap_regs->lut); nop(); - nubus_writeb(0x00, &civic_cmap_regs->lut); nop(); + nubus_writeb(0x00, &civic_cmap_regs->lut); + nop(); + nubus_writeb(0x00, &civic_cmap_regs->lut); + nop(); } #endif - nubus_writeb( red, &civic_cmap_regs->lut); nop(); - nubus_writeb(green, &civic_cmap_regs->lut); nop(); - nubus_writeb( blue, &civic_cmap_regs->lut); nop(); - nubus_writeb( 0x00, &civic_cmap_regs->lut); nop(); + nubus_writeb(red, &civic_cmap_regs->lut); + nop(); + nubus_writeb(green, &civic_cmap_regs->lut); + nop(); + nubus_writeb(blue, &civic_cmap_regs->lut); + nop(); + nubus_writeb(0x00, &civic_cmap_regs->lut); } else { unsigned char junk; - junk = nubus_readb(&civic_cmap_regs->lut); nop(); - junk = nubus_readb(&civic_cmap_regs->lut); nop(); - junk = nubus_readb(&civic_cmap_regs->lut); nop(); - junk = nubus_readb(&civic_cmap_regs->lut); nop(); + junk = nubus_readb(&civic_cmap_regs->lut); + nop(); + junk = nubus_readb(&civic_cmap_regs->lut); + nop(); + junk = nubus_readb(&civic_cmap_regs->lut); + nop(); + junk = nubus_readb(&civic_cmap_regs->lut); + nop(); if ((clut_status & 0x000D) != 0) { - nubus_writeb(0x00, &civic_cmap_regs->lut); nop(); - nubus_writeb(0x00, &civic_cmap_regs->lut); nop(); + nubus_writeb(0x00, &civic_cmap_regs->lut); + nop(); + nubus_writeb(0x00, &civic_cmap_regs->lut); + nop(); } - nubus_writeb( red, &civic_cmap_regs->lut); nop(); - nubus_writeb(green, &civic_cmap_regs->lut); nop(); - nubus_writeb( blue, &civic_cmap_regs->lut); nop(); - nubus_writeb( junk, &civic_cmap_regs->lut); nop(); + nubus_writeb(red, &civic_cmap_regs->lut); + nop(); + nubus_writeb(green, &civic_cmap_regs->lut); + nop(); + nubus_writeb(blue, &civic_cmap_regs->lut); + nop(); + nubus_writeb(junk, &civic_cmap_regs->lut); } local_irq_restore(flags); - lastreg = regno; return 0; } @@ -500,16 +428,21 @@ static int civic_setpalette (unsigned int regno, unsigned int red, * (and the 5300 too, but that's a PowerMac). This function * brought to you in part by the ECSC driver for MkLinux. */ - -static int csc_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - struct fb_info *info) +static int csc_setpalette(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + struct fb_info *info) { - mdelay(1); + unsigned long flags; + + local_irq_save(flags); + + udelay(1); /* mklinux on PB 5300 waits for 260 ns */ nubus_writeb(regno, &csc_cmap_regs->clut_waddr); - nubus_writeb(red, &csc_cmap_regs->clut_data); + nubus_writeb(red, &csc_cmap_regs->clut_data); nubus_writeb(green, &csc_cmap_regs->clut_data); - nubus_writeb(blue, &csc_cmap_regs->clut_data); + nubus_writeb(blue, &csc_cmap_regs->clut_data); + + local_irq_restore(flags); return 0; } @@ -518,10 +451,10 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green, struct fb_info *fb_info) { /* - * Set a single color register. The values supplied are - * already rounded down to the hardware's capabilities - * (according to the entries in the `var' structure). Return - * != 0 for invalid regno. + * Set a single color register. The values supplied are + * already rounded down to the hardware's capabilities + * (according to the entries in the `var' structure). + * Return non-zero for invalid regno. */ if (regno >= fb_info->cmap.len) @@ -536,8 +469,8 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green, case 4: case 8: if (macfb_setpalette) - macfb_setpalette(regno, red, green, blue, - fb_info); + macfb_setpalette(regno, red >> 8, green >> 8, + blue >> 8, fb_info); else return 1; break; @@ -555,28 +488,22 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green, } else { /* 0:5:6:5 */ ((u32*) (fb_info->pseudo_palette))[regno] = - ((red & 0xf800) ) | + ((red & 0xf800) >> 0) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); } break; - /* I'm pretty sure that one or the other of these - doesn't exist on 68k Macs */ + /* + * 24-bit colour almost doesn't exist on 68k Macs -- + * http://support.apple.com/kb/TA28634 (Old Article: 10992) + */ case 24: - red >>= 8; - green >>= 8; - blue >>= 8; - ((u32 *)(fb_info->pseudo_palette))[regno] = - (red << fb_info->var.red.offset) | - (green << fb_info->var.green.offset) | - (blue << fb_info->var.blue.offset); - break; case 32: red >>= 8; green >>= 8; blue >>= 8; ((u32 *)(fb_info->pseudo_palette))[regno] = - (red << fb_info->var.red.offset) | + (red << fb_info->var.red.offset) | (green << fb_info->var.green.offset) | (blue << fb_info->var.blue.offset); break; @@ -597,25 +524,24 @@ static struct fb_ops macfb_ops = { static void __init macfb_setup(char *options) { char *this_opt; - + if (!options || !*options) return; - + while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) continue; - - if (! strcmp(this_opt, "inverse")) - inverse=1; - /* This means "turn on experimental CLUT code" */ - else if (!strcmp(this_opt, "vidtest")) - vidtest=1; + if (!*this_opt) + continue; + + if (!strcmp(this_opt, "inverse")) + inverse = 1; + else + if (!strcmp(this_opt, "vidtest")) + vidtest = 1; /* enable experimental CLUT code */ } } static void __init iounmap_macfb(void) { - if (valkyrie_cmap_regs) - iounmap(valkyrie_cmap_regs); if (dafb_cmap_regs) iounmap(dafb_cmap_regs); if (v8_brazil_cmap_regs) @@ -642,48 +568,55 @@ static int __init macfb_init(void) if (!MACH_IS_MAC) return -ENODEV; - /* There can only be one internal video controller anyway so - we're not too worried about this */ + if (mac_bi_data.id == MAC_MODEL_Q630 || + mac_bi_data.id == MAC_MODEL_P588) + return -ENODEV; /* See valkyriefb.c */ + macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF; macfb_defined.yres = mac_bi_data.dimensions >> 16; macfb_defined.bits_per_pixel = mac_bi_data.videodepth; + macfb_fix.line_length = mac_bi_data.videorow; - macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres; + macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres; /* Note: physical address (since 2.1.127) */ - macfb_fix.smem_start = mac_bi_data.videoaddr; - /* This is actually redundant with the initial mappings. - However, there are some non-obvious aspects to the way - those mappings are set up, so this is in fact the safest - way to ensure that this driver will work on every possible - Mac */ - fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len); - - printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n", - macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024); - printk("macfb: mode is %dx%dx%d, linelength=%d\n", - macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length); - + macfb_fix.smem_start = mac_bi_data.videoaddr; + /* - * Fill in the available video resolution + * This is actually redundant with the initial mappings. + * However, there are some non-obvious aspects to the way + * those mappings are set up, so this is in fact the safest + * way to ensure that this driver will work on every possible Mac */ - - macfb_defined.xres_virtual = macfb_defined.xres; - macfb_defined.yres_virtual = macfb_defined.yres; - macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres); - macfb_defined.width = PIXEL_TO_MM(macfb_defined.xres); + fb_info.screen_base = ioremap(mac_bi_data.videoaddr, + macfb_fix.smem_len); + if (!fb_info.screen_base) + return -ENODEV; - printk("macfb: scrolling: redraw\n"); + printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n", + macfb_fix.smem_start, fb_info.screen_base, + macfb_fix.smem_len / 1024); + printk("macfb: mode is %dx%dx%d, linelength=%d\n", + macfb_defined.xres, macfb_defined.yres, + macfb_defined.bits_per_pixel, macfb_fix.line_length); + + /* Fill in the available video resolution */ + macfb_defined.xres_virtual = macfb_defined.xres; macfb_defined.yres_virtual = macfb_defined.yres; + macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres); + macfb_defined.width = PIXEL_TO_MM(macfb_defined.xres); - /* some dummy values for timing to make fbset happy */ - macfb_defined.pixclock = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres; + /* Some dummy values for timing to make fbset happy */ + macfb_defined.pixclock = 10000000 / macfb_defined.xres * + 1000 / macfb_defined.yres; macfb_defined.left_margin = (macfb_defined.xres / 8) & 0xf8; macfb_defined.hsync_len = (macfb_defined.xres / 8) & 0xf8; switch (macfb_defined.bits_per_pixel) { case 1: - /* XXX: I think this will catch any program that tries - to do FBIO_PUTCMAP when the visual is monochrome */ + /* + * XXX: I think this will catch any program that tries + * to do FBIO_PUTCMAP when the visual is monochrome. + */ macfb_defined.red.length = macfb_defined.bits_per_pixel; macfb_defined.green.length = macfb_defined.bits_per_pixel; macfb_defined.blue.length = macfb_defined.bits_per_pixel; @@ -708,53 +641,52 @@ static int __init macfb_init(void) macfb_defined.green.length = 5; macfb_defined.blue.offset = 0; macfb_defined.blue.length = 5; - printk("macfb: directcolor: " - "size=1:5:5:5, shift=15:10:5:0\n"); video_cmap_len = 16; - /* Should actually be FB_VISUAL_DIRECTCOLOR, but this - works too */ + /* + * Should actually be FB_VISUAL_DIRECTCOLOR, but this + * works too + */ macfb_fix.visual = FB_VISUAL_TRUECOLOR; break; case 24: case 32: - /* XXX: have to test these... can any 68k Macs - actually do this on internal video? */ macfb_defined.red.offset = 16; macfb_defined.red.length = 8; macfb_defined.green.offset = 8; macfb_defined.green.length = 8; macfb_defined.blue.offset = 0; macfb_defined.blue.length = 8; - printk("macfb: truecolor: " - "size=0:8:8:8, shift=0:16:8:0\n"); video_cmap_len = 16; macfb_fix.visual = FB_VISUAL_TRUECOLOR; + break; default: video_cmap_len = 0; macfb_fix.visual = FB_VISUAL_MONO01; - printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel); + printk("macfb: unknown or unsupported bit depth: %d\n", + macfb_defined.bits_per_pixel); break; } - /* Hardware dependent stuff */ - /* We take a wild guess that if the video physical address is - * in nubus slot space, that the nubus card is driving video. - * Penguin really ought to tell us whether we are using internal - * video or not. + /* + * We take a wild guess that if the video physical address is + * in nubus slot space, that the nubus card is driving video. + * Penguin really ought to tell us whether we are using internal + * video or not. + * Hopefully we only find one of them. Otherwise our NuBus + * code is really broken :-) */ - /* Hopefully we only find one of them. Otherwise our NuBus - code is really broken :-) */ - while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev)) - != NULL) + while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, + NUBUS_TYPE_VIDEO, ndev))) { - if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr - && (mac_bi_data.videoaddr < - (unsigned long)nubus_slot_addr(ndev->board->slot+1)))) + unsigned long base = ndev->board->slot_addr; + + if (mac_bi_data.videoaddr < base || + mac_bi_data.videoaddr - base > 0xFFFFFF) continue; + video_is_nubus = 1; - /* We should probably just use the slot address... */ - video_slot = ndev->board->slot; + slot_addr = (unsigned char *)base; switch(ndev->dr_hw) { case NUBUS_DRHW_APPLE_MDC: @@ -771,7 +703,7 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "Jet"); macfb_setpalette = jet_setpalette; macfb_defined.activate = FB_ACTIVATE_NOW; - break; + break; default: strcpy(macfb_fix.id, "Generic NuBus"); break; @@ -779,30 +711,19 @@ static int __init macfb_init(void) } /* If it's not a NuBus card, it must be internal video */ - /* FIXME: this function is getting way too big. (this driver - is too...) */ if (!video_is_nubus) - switch( mac_bi_data.id ) - { - /* Valkyrie Quadras */ - case MAC_MODEL_Q630: - /* I'm not sure about this one */ - case MAC_MODEL_P588: - strcpy(macfb_fix.id, "Valkyrie"); - macfb_setpalette = valkyrie_setpalette; - macfb_defined.activate = FB_ACTIVATE_NOW; - valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000); - break; - - /* DAFB Quadras */ - /* Note: these first four have the v7 DAFB, which is - known to be rather unlike the ones used in the - other models */ + switch (mac_bi_data.id) { + /* + * DAFB Quadras + * Note: these first four have the v7 DAFB, which is + * known to be rather unlike the ones used in the + * other models + */ case MAC_MODEL_P475: case MAC_MODEL_P475F: case MAC_MODEL_P575: case MAC_MODEL_Q605: - + case MAC_MODEL_Q800: case MAC_MODEL_Q650: case MAC_MODEL_Q610: @@ -817,17 +738,21 @@ static int __init macfb_init(void) dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); break; - /* LC II uses the V8 framebuffer */ + /* + * LC II uses the V8 framebuffer + */ case MAC_MODEL_LCII: strcpy(macfb_fix.id, "V8"); macfb_setpalette = v8_brazil_setpalette; macfb_defined.activate = FB_ACTIVATE_NOW; v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); break; - - /* IIvi, IIvx use the "Brazil" framebuffer (which is - very much like the V8, it seems, and probably uses - the same DAC) */ + + /* + * IIvi, IIvx use the "Brazil" framebuffer (which is + * very much like the V8, it seems, and probably uses + * the same DAC) + */ case MAC_MODEL_IIVI: case MAC_MODEL_IIVX: case MAC_MODEL_P600: @@ -836,12 +761,14 @@ static int __init macfb_init(void) macfb_defined.activate = FB_ACTIVATE_NOW; v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); break; - - /* LC III (and friends) use the Sonora framebuffer */ - /* Incidentally this is also used in the non-AV models - of the x100 PowerMacs */ - /* These do in fact seem to use the same DAC interface - as the LC II. */ + + /* + * LC III (and friends) use the Sonora framebuffer + * Incidentally this is also used in the non-AV models + * of the x100 PowerMacs + * These do in fact seem to use the same DAC interface + * as the LC II. + */ case MAC_MODEL_LCIII: case MAC_MODEL_P520: case MAC_MODEL_P550: @@ -852,9 +779,11 @@ static int __init macfb_init(void) v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); break; - /* IIci and IIsi use the infamous RBV chip - (the IIsi is just a rebadged and crippled - IIci in a different case, BTW) */ + /* + * IIci and IIsi use the infamous RBV chip + * (the IIsi is just a rebadged and crippled + * IIci in a different case, BTW) + */ case MAC_MODEL_IICI: case MAC_MODEL_IISI: macfb_setpalette = rbv_setpalette; @@ -863,7 +792,9 @@ static int __init macfb_init(void) rbv_cmap_regs = ioremap(DAC_BASE, 0x1000); break; - /* AVs use the Civic framebuffer */ + /* + * AVs use the Civic framebuffer + */ case MAC_MODEL_Q840: case MAC_MODEL_C660: macfb_setpalette = civic_setpalette; @@ -873,15 +804,10 @@ static int __init macfb_init(void) break; - /* Write a setpalette function for your machine, then - you can add something similar here. These are - grouped by classes of video chipsets. Some of this - information is from the VideoToolbox "Bugs" web - page at - http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */ - - /* Assorted weirdos */ - /* We think this may be like the LC II */ + /* + * Assorted weirdos + * We think this may be like the LC II + */ case MAC_MODEL_LC: if (vidtest) { macfb_setpalette = v8_brazil_setpalette; @@ -891,7 +817,10 @@ static int __init macfb_init(void) } strcpy(macfb_fix.id, "LC"); break; - /* We think this may be like the LC II */ + + /* + * We think this may be like the LC II + */ case MAC_MODEL_CCL: if (vidtest) { macfb_setpalette = v8_brazil_setpalette; @@ -902,31 +831,42 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "Color Classic"); break; - /* And we *do* mean "weirdos" */ + /* + * And we *do* mean "weirdos" + */ case MAC_MODEL_TV: strcpy(macfb_fix.id, "Mac TV"); break; - /* These don't have colour, so no need to worry */ + /* + * These don't have colour, so no need to worry + */ case MAC_MODEL_SE30: case MAC_MODEL_CLII: strcpy(macfb_fix.id, "Monochrome"); break; - /* Powerbooks are particularly difficult. Many of - them have separate framebuffers for external and - internal video, which is admittedly pretty cool, - but will be a bit of a headache to support here. - Also, many of them are grayscale, and we don't - really support that. */ + /* + * Powerbooks are particularly difficult. Many of + * them have separate framebuffers for external and + * internal video, which is admittedly pretty cool, + * but will be a bit of a headache to support here. + * Also, many of them are grayscale, and we don't + * really support that. + */ + /* + * Slot 0 ROM says TIM. No external video. B&W. + */ case MAC_MODEL_PB140: case MAC_MODEL_PB145: case MAC_MODEL_PB170: strcpy(macfb_fix.id, "DDC"); break; - /* Internal is GSC, External (if present) is ViSC */ + /* + * Internal is GSC, External (if present) is ViSC + */ case MAC_MODEL_PB150: /* no external video */ case MAC_MODEL_PB160: case MAC_MODEL_PB165: @@ -936,13 +876,17 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "GSC"); break; - /* Internal is TIM, External is ViSC */ + /* + * Internal is TIM, External is ViSC + */ case MAC_MODEL_PB165C: case MAC_MODEL_PB180C: strcpy(macfb_fix.id, "TIM"); break; - /* Internal is CSC, External is Keystone+Ariel. */ + /* + * Internal is CSC, External is Keystone+Ariel. + */ case MAC_MODEL_PB190: /* external video is optional */ case MAC_MODEL_PB520: case MAC_MODEL_PB250: @@ -954,7 +898,7 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "CSC"); csc_cmap_regs = ioremap(CSC_BASE, 0x1000); break; - + default: strcpy(macfb_fix.id, "Unknown"); break; @@ -969,7 +913,7 @@ static int __init macfb_init(void) err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0); if (err) goto fail_unmap; - + err = register_framebuffer(&fb_info); if (err) goto fail_dealloc; diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c index 083f60321ed8..af86c081d2be 100644 --- a/drivers/video/macmodes.c +++ b/drivers/video/macmodes.c @@ -33,6 +33,10 @@ static const struct fb_videomode mac_modedb[] = { { + /* 512x384, 60Hz, Non-Interlaced (15.67 MHz dot clock) */ + "mac2", 60, 512, 384, 63828, 80, 16, 19, 1, 32, 3, + 0, FB_VMODE_NONINTERLACED + }, { /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ "mac5", 60, 640, 480, 39722, 32, 32, 33, 10, 96, 2, 0, FB_VMODE_NONINTERLACED @@ -40,6 +44,10 @@ static const struct fb_videomode mac_modedb[] = { /* 640x480, 67Hz, Non-Interlaced (30.0 MHz dotclock) */ "mac6", 67, 640, 480, 33334, 80, 80, 39, 3, 64, 3, 0, FB_VMODE_NONINTERLACED + }, { + /* 640x870, 75Hz (portrait), Non-Interlaced (57.28 MHz dot clock) */ + "mac7", 75, 640, 870, 17457, 80, 32, 42, 3, 80, 3, + 0, FB_VMODE_NONINTERLACED }, { /* 800x600, 56 Hz, Non-Interlaced (36.00 MHz dotclock) */ "mac9", 56, 800, 600, 27778, 112, 40, 22, 1, 72, 2, @@ -104,10 +112,6 @@ static const struct fb_videomode mac_modedb[] = { /* VMODE_512_384_60I: 512x384, 60Hz, Interlaced (NTSC) */ "mac1", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen, sync, FB_VMODE_INTERLACED - }, { - /* VMODE_512_384_60: 512x384, 60Hz, Non-Interlaced */ - "mac2", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen, - sync, FB_VMODE_NONINTERLACED }, { /* VMODE_640_480_50I: 640x480, 50Hz, Interlaced (PAL) */ "mac3", 50, 640, 480, pixclock, left, right, upper, lower, hslen, vslen, @@ -116,10 +120,6 @@ static const struct fb_videomode mac_modedb[] = { /* VMODE_640_480_60I: 640x480, 60Hz, Interlaced (NTSC) */ "mac4", 60, 640, 480, pixclock, left, right, upper, lower, hslen, vslen, sync, FB_VMODE_INTERLACED - }, { - /* VMODE_640_870_75P: 640x870, 75Hz (portrait), Non-Interlaced */ - "mac7", 75, 640, 870, pixclock, left, right, upper, lower, hslen, vslen, - sync, FB_VMODE_NONINTERLACED }, { /* VMODE_768_576_50I: 768x576, 50Hz (PAL full frame), Interlaced */ "mac8", 50, 768, 576, pixclock, left, right, upper, lower, hslen, vslen, @@ -134,38 +134,42 @@ static const struct fb_videomode mac_modedb[] = { * * These MUST be ordered in * - increasing resolution - * - decreasing refresh rate + * - decreasing pixel clock period */ static const struct mode_map { int vmode; const struct fb_videomode *mode; } mac_modes[] = { + /* 512x384 */ + { VMODE_512_384_60, &mac_modedb[0] }, /* 640x480 */ - { VMODE_640_480_67, &mac_modedb[1] }, - { VMODE_640_480_60, &mac_modedb[0] }, + { VMODE_640_480_60, &mac_modedb[1] }, + { VMODE_640_480_67, &mac_modedb[2] }, + /* 640x870 */ + { VMODE_640_870_75P, &mac_modedb[3] }, /* 800x600 */ - { VMODE_800_600_75, &mac_modedb[5] }, - { VMODE_800_600_72, &mac_modedb[4] }, - { VMODE_800_600_60, &mac_modedb[3] }, - { VMODE_800_600_56, &mac_modedb[2] }, + { VMODE_800_600_56, &mac_modedb[4] }, + { VMODE_800_600_60, &mac_modedb[5] }, + { VMODE_800_600_75, &mac_modedb[7] }, + { VMODE_800_600_72, &mac_modedb[6] }, /* 832x624 */ - { VMODE_832_624_75, &mac_modedb[6] }, + { VMODE_832_624_75, &mac_modedb[8] }, /* 1024x768 */ - { VMODE_1024_768_75, &mac_modedb[10] }, - { VMODE_1024_768_75V, &mac_modedb[9] }, - { VMODE_1024_768_70, &mac_modedb[8] }, - { VMODE_1024_768_60, &mac_modedb[7] }, + { VMODE_1024_768_60, &mac_modedb[9] }, + { VMODE_1024_768_70, &mac_modedb[10] }, + { VMODE_1024_768_75V, &mac_modedb[11] }, + { VMODE_1024_768_75, &mac_modedb[12] }, /* 1152x768 */ - { VMODE_1152_768_60, &mac_modedb[14] }, + { VMODE_1152_768_60, &mac_modedb[16] }, /* 1152x870 */ - { VMODE_1152_870_75, &mac_modedb[11] }, + { VMODE_1152_870_75, &mac_modedb[13] }, /* 1280x960 */ - { VMODE_1280_960_75, &mac_modedb[12] }, + { VMODE_1280_960_75, &mac_modedb[14] }, /* 1280x1024 */ - { VMODE_1280_1024_75, &mac_modedb[13] }, + { VMODE_1280_1024_75, &mac_modedb[15] }, /* 1600x1024 */ - { VMODE_1600_1024_60, &mac_modedb[15] }, + { VMODE_1600_1024_60, &mac_modedb[17] }, { -1, NULL } }; @@ -299,7 +303,6 @@ EXPORT_SYMBOL(mac_vmode_to_var); int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, int *cmode) { - const struct fb_videomode *mode = NULL; const struct mode_map *map; if (var->bits_per_pixel <= 8) @@ -311,8 +314,13 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, else return -EINVAL; + /* + * Find the mac_mode with a matching resolution or failing that, the + * closest larger resolution. Skip modes with a shorter pixel clock period. + */ for (map = mac_modes; map->vmode != -1; map++) { - mode = map->mode; + const struct fb_videomode *mode = map->mode; + if (var->xres > mode->xres || var->yres > mode->yres) continue; if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres) @@ -322,6 +330,24 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, if ((var->vmode & FB_VMODE_MASK) != mode->vmode) continue; *vmode = map->vmode; + + /* + * Having found a good resolution, find the matching pixel clock + * or failing that, the closest longer pixel clock period. + */ + map++; + while (map->vmode != -1) { + const struct fb_videomode *clk_mode = map->mode; + + if (mode->xres != clk_mode->xres || mode->yres != clk_mode->yres) + break; + if (var->pixclock > mode->pixclock) + break; + if (mode->vmode != clk_mode->vmode) + continue; + *vmode = map->vmode; + map++; + } return 0; } return -EINVAL; diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c index 4bb9a0b18950..6b52bf65f0b5 100644 --- a/drivers/video/valkyriefb.c +++ b/drivers/video/valkyriefb.c @@ -69,7 +69,7 @@ #ifdef CONFIG_MAC /* We don't yet have functions to read the PRAM... perhaps we can adapt them from the PPC code? */ -static int default_vmode = VMODE_640_480_67; +static int default_vmode = VMODE_CHOOSE; static int default_cmode = CMODE_8; #else static int default_vmode = VMODE_NVRAM; @@ -326,11 +326,11 @@ int __init valkyriefb_init(void) #ifdef CONFIG_MAC if (!MACH_IS_MAC) - return 0; + return -ENODEV; if (!(mac_bi_data.id == MAC_MODEL_Q630 /* I'm not sure about this one */ || mac_bi_data.id == MAC_MODEL_P588)) - return 0; + return -ENODEV; /* Hardcoded addresses... welcome to 68k Macintosh country :-) */ frame_buffer_phys = 0xf9000000; diff --git a/drivers/video/valkyriefb.h b/drivers/video/valkyriefb.h index 97aaf7bb6417..d787441e5a42 100644 --- a/drivers/video/valkyriefb.h +++ b/drivers/video/valkyriefb.h @@ -134,15 +134,7 @@ static struct valkyrie_regvals valkyrie_reg_init_14 = { { 1024, 0 }, 1024, 768 }; - -/* Register values for 800x600, 72Hz mode (11) */ -static struct valkyrie_regvals valkyrie_reg_init_11 = { - 13, - { 17, 27, 3 }, /* pixel clock = 49.63MHz for V=71.66Hz */ - { 800, 0 }, - 800, 600 -}; -#endif /* CONFIG_MAC */ +#endif /* !defined CONFIG_MAC */ /* Register values for 832x624, 75Hz mode (13) */ static struct valkyrie_regvals valkyrie_reg_init_13 = { @@ -152,6 +144,14 @@ static struct valkyrie_regvals valkyrie_reg_init_13 = { 832, 624 }; +/* Register values for 800x600, 72Hz mode (11) */ +static struct valkyrie_regvals valkyrie_reg_init_11 = { + 13, + { 17, 27, 3 }, /* pixel clock = 49.63MHz for V=71.66Hz */ + { 800, 0 }, + 800, 600 +}; + /* Register values for 800x600, 60Hz mode (10) */ static struct valkyrie_regvals valkyrie_reg_init_10 = { 12, @@ -188,24 +188,13 @@ static struct valkyrie_regvals *valkyrie_reg_init[VMODE_MAX] = { NULL, NULL, &valkyrie_reg_init_10, -#ifdef CONFIG_MAC - NULL, - NULL, - &valkyrie_reg_init_13, - NULL, - NULL, - NULL, - NULL, -#else &valkyrie_reg_init_11, NULL, &valkyrie_reg_init_13, +#ifndef CONFIG_MAC &valkyrie_reg_init_14, &valkyrie_reg_init_15, NULL, &valkyrie_reg_init_17, #endif - NULL, - NULL, - NULL };