Commit 847f9c60 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k: (24 commits)
  m68k: Define sigcontext ABI of ColdFire
  m68knommu: NPTL support for uClinux
  m68k: Add NPTL support
  m68k: Eliminate unused variable in page_to_phys()
  m68k: Switch to generic siginfo layout
  macfb: fix 24-bit visual and stuff
  macfb: cleanup
  fbdev: add some missing mac modes
  mac68k: start CUDA early
  valkyriefb: various fixes
  fbdev: mac_var_to_mode() fix
  mac68k: move macsonic and macmace platform devices
  mac68k: move mac_esp platform device
  mac68k: replace mac68k SCC code with platform device
  pmac-zilog: add platform driver
  pmac-zilog: cleanup
  mac68k: rework SWIM platform device
  mac68k: cleanup
  ataflop: Killl warning about unused variable flags
  m68k: Use DIV_ROUND_CLOSEST
  ...
parents 79811647 00ebfe58
......@@ -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,
......
......@@ -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
......
......@@ -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");
......
......@@ -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
......
......@@ -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
......
......@@ -21,29 +21,4 @@
#define VIDEOMEMSIZE (4096*1024)
#define VIDEOMEMMASK (-4096*1024)
#ifndef __ASSEMBLY__
#include <linux/types.h>
#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 */
......@@ -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)
......
......@@ -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__
......
......@@ -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
};
......
#ifndef _M68K_SIGINFO_H
#define _M68K_SIGINFO_H
#ifndef __uClinux__
#define HAVE_ARCH_SIGINFO_T
#define HAVE_ARCH_COPY_SIGINFO
#endif
#include <asm-generic/siginfo.h>
#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 <linux/string.h>
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
......@@ -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)
{
......
......@@ -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__ */
......
......@@ -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;
};
......
......@@ -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 {
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
......@@ -28,6 +28,11 @@
#include <asm/traps.h>
#include <asm/page.h>
#include <asm/unistd.h>
#include <linux/elf.h>
#include <asm/tlb.h>
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;
}
......@@ -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
......@@ -23,6 +23,8 @@
#include <linux/init.h>
#include <linux/vt_kern.h>
#include <linux/platform_device.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#define BOOTINFO_COMPAT_1_0
#include <asm/setup.h>
......@@ -44,12 +46,7 @@
#include <asm/mac_oss.h>
#include <asm/mac_psc.h>
/* 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);
}
/*
* 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 platform_add_devices(mac_platform_devices,
ARRAY_SIZE(mac_platform_devices));
return 0;
}
arch_initcall(mac_platform_init);
/*
* 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 <linux/types.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/delay.h>
#define BOOTINFO_COMPAT_1_0
#include <asm/setup.h>
#include <asm/bootinfo.h>
#include <asm/macints.h>
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);
......@@ -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 <asm/irq_regs.h>
#include <asm/mac_oss.h>
#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);
}
......@@ -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:
......
......@@ -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");
......
......@@ -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
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
}
......@@ -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
......
......@@ -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,
......
......@@ -1470,8 +1470,6 @@ static void redo_fd_request(void)
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;
......
......@@ -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));
......
......@@ -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 @@ static int mvme147_scc_init(void)
#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 @@ static int mvme162_scc_init(void)
#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 @@ static int bvme6000_scc_init(void)
#endif
static int vme_scc_init(void)
static int __init vme_scc_init(void)
{
int res = -ENODEV;
......
......@@ -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") ||
......
......@@ -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.
......
......@@ -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);
......
......@@ -62,7 +62,6 @@
#include <asm/mac_via.h>
static char mac_sonic_string[] = "macsonic";
static struct platform_device *mac_sonic_device;
#include "sonic.h"
......@@ -607,6 +606,7 @@ static int __devinit mac_sonic_probe(struct platform_device *pdev)
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);
......
......@@ -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 <fthain@telegraphics.com.au>");
MODULE_LICENSE("GPL v2");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:" DRV_MODULE_NAME);
module_init(mac_esp_init);
module_exit(mac_esp_exit);
......@@ -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
......
......@@ -63,11 +63,17 @@
#include <asm/sections.h>
#include <asm/io.h>
#include <asm/irq.h>
#ifdef CONFIG_PPC_PMAC
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/dbdma.h>
#include <asm/macio.h>
#else
#include <linux/platform_device.h>
#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 <benh@kernel.crashing.org>)";
MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
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 @@ static int __init pmz_probe(void)
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 @@ static int __init pmz_register(void)
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
......
#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__ */
/* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
don't know how to set */
/* (c) 1999 David Huggins-Daines <dhd@debian.org>
Primarily based on vesafb.c, by Gerd Knorr
(c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
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 <dhd@debian.org>
*
* Primarily based on vesafb.c, by Gerd Knorr
* (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
*
* 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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/nubus.h>
#include <linux/init.h>
......@@ -31,9 +35,6 @@
#include <asm/setup.h>
#include <asm/bootinfo.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/macintosh.h>
#include <asm/io.h>
......@@ -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)
{
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)
/*
* 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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment