aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/mac
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-05-07 23:37:51 -0400
committerPaul Mackerras <paulus@samba.org>2007-05-07 23:37:51 -0400
commit02bbc0f09c90cefdb2837605c96a66c5ce4ba2e1 (patch)
tree04ef573cd4de095c500c9fc3477f4278c0b36300 /arch/m68k/mac
parent7487a2245b8841c77ba9db406cf99a483b9334e9 (diff)
parent5b94f675f57e4ff16c8fda09088d7480a84dcd91 (diff)
Merge branch 'linux-2.6'
Diffstat (limited to 'arch/m68k/mac')
-rw-r--r--arch/m68k/mac/baboon.c32
-rw-r--r--arch/m68k/mac/config.c167
-rw-r--r--arch/m68k/mac/debug.c331
-rw-r--r--arch/m68k/mac/macints.c2
-rw-r--r--arch/m68k/mac/oss.c18
-rw-r--r--arch/m68k/mac/psc.c21
-rw-r--r--arch/m68k/mac/via.c284
7 files changed, 442 insertions, 413 deletions
diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c
index a1c7ec706741..673a1085984d 100644
--- a/arch/m68k/mac/baboon.c
+++ b/arch/m68k/mac/baboon.c
@@ -22,7 +22,7 @@
22/* #define DEBUG_BABOON */ 22/* #define DEBUG_BABOON */
23/* #define DEBUG_IRQS */ 23/* #define DEBUG_IRQS */
24 24
25int baboon_present,baboon_active; 25int baboon_present;
26volatile struct baboon *baboon; 26volatile struct baboon *baboon;
27 27
28irqreturn_t baboon_irq(int, void *); 28irqreturn_t baboon_irq(int, void *);
@@ -45,7 +45,6 @@ void __init baboon_init(void)
45 45
46 baboon = (struct baboon *) BABOON_BASE; 46 baboon = (struct baboon *) BABOON_BASE;
47 baboon_present = 1; 47 baboon_present = 1;
48 baboon_active = 0;
49 48
50 printk("Baboon detected at %p\n", baboon); 49 printk("Baboon detected at %p\n", baboon);
51} 50}
@@ -66,26 +65,28 @@ void __init baboon_register_interrupts(void)
66 65
67irqreturn_t baboon_irq(int irq, void *dev_id) 66irqreturn_t baboon_irq(int irq, void *dev_id)
68{ 67{
69 int irq_bit,i; 68 int irq_bit, irq_num;
70 unsigned char events; 69 unsigned char events;
71 70
72#ifdef DEBUG_IRQS 71#ifdef DEBUG_IRQS
73 printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X active %02X\n", 72 printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n",
74 (uint) baboon->mb_control, (uint) baboon->mb_ifr, 73 (uint) baboon->mb_control, (uint) baboon->mb_ifr,
75 (uint) baboon->mb_status, baboon_active); 74 (uint) baboon->mb_status);
76#endif 75#endif
77 76
78 if (!(events = baboon->mb_ifr & 0x07)) 77 if (!(events = baboon->mb_ifr & 0x07))
79 return IRQ_NONE; 78 return IRQ_NONE;
80 79
81 for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { 80 irq_num = IRQ_BABOON_0;
82 if (events & irq_bit/* & baboon_active*/) { 81 irq_bit = 1;
83 baboon_active &= ~irq_bit; 82 do {
84 m68k_handle_int(IRQ_BABOON_0 + i); 83 if (events & irq_bit) {
85 baboon_active |= irq_bit;
86 baboon->mb_ifr &= ~irq_bit; 84 baboon->mb_ifr &= ~irq_bit;
85 m68k_handle_int(irq_num);
87 } 86 }
88 } 87 irq_bit <<= 1;
88 irq_num++;
89 } while(events >= irq_bit);
89#if 0 90#if 0
90 if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL); 91 if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL);
91 /* for now we need to smash all interrupts */ 92 /* for now we need to smash all interrupts */
@@ -95,21 +96,18 @@ irqreturn_t baboon_irq(int irq, void *dev_id)
95} 96}
96 97
97void baboon_irq_enable(int irq) { 98void baboon_irq_enable(int irq) {
98 int irq_idx = IRQ_IDX(irq);
99
100#ifdef DEBUG_IRQUSE 99#ifdef DEBUG_IRQUSE
101 printk("baboon_irq_enable(%d)\n", irq); 100 printk("baboon_irq_enable(%d)\n", irq);
102#endif 101#endif
103 baboon_active |= (1 << irq_idx); 102 /* FIXME: figure out how to mask and unmask baboon interrupt sources */
103 enable_irq(IRQ_NUBUS_C);
104} 104}
105 105
106void baboon_irq_disable(int irq) { 106void baboon_irq_disable(int irq) {
107 int irq_idx = IRQ_IDX(irq);
108
109#ifdef DEBUG_IRQUSE 107#ifdef DEBUG_IRQUSE
110 printk("baboon_irq_disable(%d)\n", irq); 108 printk("baboon_irq_disable(%d)\n", irq);
111#endif 109#endif
112 baboon_active &= ~(1 << irq_idx); 110 disable_irq(IRQ_NUBUS_C);
113} 111}
114 112
115void baboon_irq_clear(int irq) { 113void baboon_irq_clear(int irq) {
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 562b38d00180..5fd413246f89 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -59,15 +59,15 @@ extern struct mem_info m68k_ramdisk;
59 59
60extern char m68k_command_line[CL_SIZE]; 60extern char m68k_command_line[CL_SIZE];
61 61
62void *mac_env; /* Loaded by the boot asm */ 62void *mac_env; /* Loaded by the boot asm */
63 63
64/* The phys. video addr. - might be bogus on some machines */ 64/* The phys. video addr. - might be bogus on some machines */
65unsigned long mac_orig_videoaddr; 65unsigned long mac_orig_videoaddr;
66 66
67/* Mac specific timer functions */ 67/* Mac specific timer functions */
68extern unsigned long mac_gettimeoffset (void); 68extern unsigned long mac_gettimeoffset(void);
69extern int mac_hwclk (int, struct rtc_time *); 69extern int mac_hwclk(int, struct rtc_time *);
70extern int mac_set_clock_mmss (unsigned long); 70extern int mac_set_clock_mmss(unsigned long);
71extern int show_mac_interrupts(struct seq_file *, void *); 71extern int show_mac_interrupts(struct seq_file *, void *);
72extern void iop_preinit(void); 72extern void iop_preinit(void);
73extern void iop_init(void); 73extern void iop_init(void);
@@ -82,10 +82,6 @@ extern void mac_mksound(unsigned int, unsigned int);
82 82
83extern void nubus_sweep_video(void); 83extern void nubus_sweep_video(void);
84 84
85/* Mac specific debug functions (in debug.c) */
86extern void mac_debug_init(void);
87extern void mac_debugging_long(int, long);
88
89static void mac_get_model(char *str); 85static void mac_get_model(char *str);
90 86
91static void mac_sched_init(irq_handler_t vector) 87static void mac_sched_init(irq_handler_t vector)
@@ -99,51 +95,52 @@ static void mac_sched_init(irq_handler_t vector)
99 95
100int __init mac_parse_bootinfo(const struct bi_record *record) 96int __init mac_parse_bootinfo(const struct bi_record *record)
101{ 97{
102 int unknown = 0; 98 int unknown = 0;
103 const u_long *data = record->data; 99 const u_long *data = record->data;
104 100
105 switch (record->tag) { 101 switch (record->tag) {
106 case BI_MAC_MODEL: 102 case BI_MAC_MODEL:
107 mac_bi_data.id = *data; 103 mac_bi_data.id = *data;
108 break; 104 break;
109 case BI_MAC_VADDR: 105 case BI_MAC_VADDR:
110 mac_bi_data.videoaddr = *data; 106 mac_bi_data.videoaddr = *data;
111 break; 107 break;
112 case BI_MAC_VDEPTH: 108 case BI_MAC_VDEPTH:
113 mac_bi_data.videodepth = *data; 109 mac_bi_data.videodepth = *data;
114 break; 110 break;
115 case BI_MAC_VROW: 111 case BI_MAC_VROW:
116 mac_bi_data.videorow = *data; 112 mac_bi_data.videorow = *data;
117 break; 113 break;
118 case BI_MAC_VDIM: 114 case BI_MAC_VDIM:
119 mac_bi_data.dimensions = *data; 115 mac_bi_data.dimensions = *data;
120 break; 116 break;
121 case BI_MAC_VLOGICAL: 117 case BI_MAC_VLOGICAL:
122 mac_bi_data.videological = VIDEOMEMBASE + (*data & ~VIDEOMEMMASK); 118 mac_bi_data.videological = VIDEOMEMBASE + (*data & ~VIDEOMEMMASK);
123 mac_orig_videoaddr = *data; 119 mac_orig_videoaddr = *data;
124 break; 120 break;
125 case BI_MAC_SCCBASE: 121 case BI_MAC_SCCBASE:
126 mac_bi_data.sccbase = *data; 122 mac_bi_data.sccbase = *data;
127 break; 123 break;
128 case BI_MAC_BTIME: 124 case BI_MAC_BTIME:
129 mac_bi_data.boottime = *data; 125 mac_bi_data.boottime = *data;
130 break; 126 break;
131 case BI_MAC_GMTBIAS: 127 case BI_MAC_GMTBIAS:
132 mac_bi_data.gmtbias = *data; 128 mac_bi_data.gmtbias = *data;
133 break; 129 break;
134 case BI_MAC_MEMSIZE: 130 case BI_MAC_MEMSIZE:
135 mac_bi_data.memsize = *data; 131 mac_bi_data.memsize = *data;
136 break; 132 break;
137 case BI_MAC_CPUID: 133 case BI_MAC_CPUID:
138 mac_bi_data.cpuid = *data; 134 mac_bi_data.cpuid = *data;
139 break; 135 break;
140 case BI_MAC_ROMBASE: 136 case BI_MAC_ROMBASE:
141 mac_bi_data.rombase = *data; 137 mac_bi_data.rombase = *data;
142 break; 138 break;
143 default: 139 default:
144 unknown = 1; 140 unknown = 1;
145 } 141 break;
146 return(unknown); 142 }
143 return unknown;
147} 144}
148 145
149/* 146/*
@@ -155,6 +152,7 @@ int __init mac_parse_bootinfo(const struct bi_record *record)
155static void mac_cache_card_flush(int writeback) 152static void mac_cache_card_flush(int writeback)
156{ 153{
157 unsigned long flags; 154 unsigned long flags;
155
158 local_irq_save(flags); 156 local_irq_save(flags);
159 via_flush_cache(); 157 via_flush_cache();
160 local_irq_restore(flags); 158 local_irq_restore(flags);
@@ -162,28 +160,24 @@ static void mac_cache_card_flush(int writeback)
162 160
163void __init config_mac(void) 161void __init config_mac(void)
164{ 162{
165 if (!MACH_IS_MAC) { 163 if (!MACH_IS_MAC)
166 printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n"); 164 printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n");
167 }
168 165
169 mach_sched_init = mac_sched_init; 166 mach_sched_init = mac_sched_init;
170 mach_init_IRQ = mac_init_IRQ; 167 mach_init_IRQ = mac_init_IRQ;
171 mach_get_model = mac_get_model; 168 mach_get_model = mac_get_model;
172 mach_gettimeoffset = mac_gettimeoffset; 169 mach_gettimeoffset = mac_gettimeoffset;
173#warning move to adb/via init 170#warning move to adb/via init
174#if 0 171#if 0
175 mach_hwclk = mac_hwclk; 172 mach_hwclk = mac_hwclk;
176#endif 173#endif
177 mach_set_clock_mmss = mac_set_clock_mmss; 174 mach_set_clock_mmss = mac_set_clock_mmss;
178 mach_reset = mac_reset; 175 mach_reset = mac_reset;
179 mach_halt = mac_poweroff; 176 mach_halt = mac_poweroff;
180 mach_power_off = mac_poweroff; 177 mach_power_off = mac_poweroff;
181 mach_max_dma_address = 0xffffffff; 178 mach_max_dma_address = 0xffffffff;
182#if 0
183 mach_debug_init = mac_debug_init;
184#endif
185#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) 179#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
186 mach_beep = mac_mksound; 180 mach_beep = mac_mksound;
187#endif 181#endif
188#ifdef CONFIG_HEARTBEAT 182#ifdef CONFIG_HEARTBEAT
189#if 0 183#if 0
@@ -199,21 +193,22 @@ void __init config_mac(void)
199 mac_identify(); 193 mac_identify();
200 mac_report_hardware(); 194 mac_report_hardware();
201 195
202 /* AFAIK only the IIci takes a cache card. The IIfx has onboard 196 /*
203 cache ... someone needs to figure out how to tell if it's on or 197 * AFAIK only the IIci takes a cache card. The IIfx has onboard
204 not. */ 198 * cache ... someone needs to figure out how to tell if it's on or
199 * not.
200 */
205 201
206 if (macintosh_config->ident == MAC_MODEL_IICI 202 if (macintosh_config->ident == MAC_MODEL_IICI
207 || macintosh_config->ident == MAC_MODEL_IIFX) { 203 || macintosh_config->ident == MAC_MODEL_IIFX)
208 mach_l2_flush = mac_cache_card_flush; 204 mach_l2_flush = mac_cache_card_flush;
209 }
210 205
211 /* 206 /*
212 * Check for machine specific fixups. 207 * Check for machine specific fixups.
213 */ 208 */
214 209
215#ifdef OLD_NUBUS_CODE 210#ifdef OLD_NUBUS_CODE
216 nubus_sweep_video(); 211 nubus_sweep_video();
217#endif 212#endif
218} 213}
219 214
@@ -233,8 +228,7 @@ void __init config_mac(void)
233struct mac_model *macintosh_config; 228struct mac_model *macintosh_config;
234EXPORT_SYMBOL(macintosh_config); 229EXPORT_SYMBOL(macintosh_config);
235 230
236static struct mac_model mac_data_table[]= 231static struct mac_model mac_data_table[] = {
237{
238 /* 232 /*
239 * We'll pretend to be a Macintosh II, that's pretty safe. 233 * We'll pretend to be a Macintosh II, that's pretty safe.
240 */ 234 */
@@ -784,12 +778,12 @@ void mac_identify(void)
784 if (!model) { 778 if (!model) {
785 /* no bootinfo model id -> NetBSD booter was used! */ 779 /* no bootinfo model id -> NetBSD booter was used! */
786 /* XXX FIXME: breaks for model > 31 */ 780 /* XXX FIXME: breaks for model > 31 */
787 model=(mac_bi_data.cpuid>>2)&63; 781 model = (mac_bi_data.cpuid >> 2) & 63;
788 printk (KERN_WARNING "No bootinfo model ID, using cpuid instead (hey, use Penguin!)\n"); 782 printk(KERN_WARNING "No bootinfo model ID, using cpuid instead (hey, use Penguin!)\n");
789 } 783 }
790 784
791 macintosh_config = mac_data_table; 785 macintosh_config = mac_data_table;
792 for (m = macintosh_config ; m->ident != -1 ; m++) { 786 for (m = macintosh_config; m->ident != -1; m++) {
793 if (m->ident == model) { 787 if (m->ident == model) {
794 macintosh_config = m; 788 macintosh_config = m;
795 break; 789 break;
@@ -801,27 +795,26 @@ void mac_identify(void)
801 /* the serial ports set to "Faster" mode in MacOS. */ 795 /* the serial ports set to "Faster" mode in MacOS. */
802 796
803 iop_preinit(); 797 iop_preinit();
804 mac_debug_init();
805 798
806 printk (KERN_INFO "Detected Macintosh model: %d \n", model); 799 printk(KERN_INFO "Detected Macintosh model: %d \n", model);
807 800
808 /* 801 /*
809 * Report booter data: 802 * Report booter data:
810 */ 803 */
811 printk (KERN_DEBUG " Penguin bootinfo data:\n"); 804 printk(KERN_DEBUG " Penguin bootinfo data:\n");
812 printk (KERN_DEBUG " Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n", 805 printk(KERN_DEBUG " Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n",
813 mac_bi_data.videoaddr, mac_bi_data.videorow, 806 mac_bi_data.videoaddr, mac_bi_data.videorow,
814 mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF, 807 mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF,
815 mac_bi_data.dimensions >> 16); 808 mac_bi_data.dimensions >> 16);
816 printk (KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n", 809 printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n",
817 mac_bi_data.videological, mac_orig_videoaddr, 810 mac_bi_data.videological, mac_orig_videoaddr,
818 mac_bi_data.sccbase); 811 mac_bi_data.sccbase);
819 printk (KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n", 812 printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n",
820 mac_bi_data.boottime, mac_bi_data.gmtbias); 813 mac_bi_data.boottime, mac_bi_data.gmtbias);
821 printk (KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n", 814 printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n",
822 mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize); 815 mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize);
823#if 0 816#if 0
824 printk ("Ramdisk: addr 0x%lx size 0x%lx\n", 817 printk("Ramdisk: addr 0x%lx size 0x%lx\n",
825 m68k_ramdisk.addr, m68k_ramdisk.size); 818 m68k_ramdisk.addr, m68k_ramdisk.size);
826#endif 819#endif
827 820
@@ -830,22 +823,22 @@ void mac_identify(void)
830 */ 823 */
831 switch (macintosh_config->scsi_type) { 824 switch (macintosh_config->scsi_type) {
832 case MAC_SCSI_OLD: 825 case MAC_SCSI_OLD:
833 MACHW_SET(MAC_SCSI_80); 826 MACHW_SET(MAC_SCSI_80);
834 break; 827 break;
835 case MAC_SCSI_QUADRA: 828 case MAC_SCSI_QUADRA:
836 case MAC_SCSI_QUADRA2: 829 case MAC_SCSI_QUADRA2:
837 case MAC_SCSI_QUADRA3: 830 case MAC_SCSI_QUADRA3:
838 MACHW_SET(MAC_SCSI_96); 831 MACHW_SET(MAC_SCSI_96);
839 if ((macintosh_config->ident == MAC_MODEL_Q900) || 832 if ((macintosh_config->ident == MAC_MODEL_Q900) ||
840 (macintosh_config->ident == MAC_MODEL_Q950)) 833 (macintosh_config->ident == MAC_MODEL_Q950))
841 MACHW_SET(MAC_SCSI_96_2); 834 MACHW_SET(MAC_SCSI_96_2);
842 break; 835 break;
843 default: 836 default:
844 printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n"); 837 printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n");
845 MACHW_SET(MAC_SCSI_80); 838 MACHW_SET(MAC_SCSI_80);
846 break; 839 break;
847
848 } 840 }
841
849 iop_init(); 842 iop_init();
850 via_init(); 843 via_init();
851 oss_init(); 844 oss_init();
@@ -860,6 +853,6 @@ void mac_report_hardware(void)
860 853
861static void mac_get_model(char *str) 854static void mac_get_model(char *str)
862{ 855{
863 strcpy(str,"Macintosh "); 856 strcpy(str, "Macintosh ");
864 strcat(str, macintosh_config->name); 857 strcat(str, macintosh_config->name);
865} 858}
diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c
index 4eeb09dc0e8f..7a5bed5bdc57 100644
--- a/arch/m68k/mac/debug.c
+++ b/arch/m68k/mac/debug.c
@@ -27,10 +27,6 @@
27#include <asm/machw.h> 27#include <asm/machw.h>
28#include <asm/macints.h> 28#include <asm/macints.h>
29 29
30extern char m68k_debug_device[];
31
32extern struct compat_bootinfo compat_boot_info;
33
34extern unsigned long mac_videobase; 30extern unsigned long mac_videobase;
35extern unsigned long mac_videodepth; 31extern unsigned long mac_videodepth;
36extern unsigned long mac_rowbytes; 32extern unsigned long mac_rowbytes;
@@ -52,7 +48,7 @@ extern void mac_serial_print(const char *);
52 */ 48 */
53 49
54#ifdef DEBUG_SCREEN 50#ifdef DEBUG_SCREEN
55static int peng=0, line=0; 51static int peng, line;
56#endif 52#endif
57 53
58void mac_debugging_short(int pos, short num) 54void mac_debugging_short(int pos, short num)
@@ -74,15 +70,14 @@ void mac_debugging_short(int pos, short num)
74 } 70 }
75 71
76 /* calculate current offset */ 72 /* calculate current offset */
77 pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes) 73 pengoffset = (unsigned char *)mac_videobase +
78 +80*peng; 74 (150+line*2) * mac_rowbytes) + 80 * peng;
79 75
80 pptr=pengoffset; 76 pptr = pengoffset;
81 77
82 for(i=0;i<8*sizeof(short);i++) /* # of bits */ 78 for (i = 0; i < 8 * sizeof(short); i++) { /* # of bits */
83 {
84 /* value mask for bit i, reverse order */ 79 /* value mask for bit i, reverse order */
85 *pptr++ = (num & ( 1 << (8*sizeof(short)-i-1) ) ? 0xFF : 0x00); 80 *pptr++ = (num & (1 << (8*sizeof(short)-i-1)) ? 0xFF : 0x00);
86 } 81 }
87 82
88 peng++; 83 peng++;
@@ -115,11 +110,10 @@ void mac_debugging_long(int pos, long addr)
115 pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes) 110 pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes)
116 +80*peng; 111 +80*peng;
117 112
118 pptr=pengoffset; 113 pptr = pengoffset;
119 114
120 for(i=0;i<8*sizeof(long);i++) /* # of bits */ 115 for (i = 0; i < 8 * sizeof(long); i++) { /* # of bits */
121 { 116 *pptr++ = (addr & (1 << (8*sizeof(long)-i-1)) ? 0xFF : 0x00);
122 *pptr++ = (addr & ( 1 << (8*sizeof(long)-i-1) ) ? 0xFF : 0x00);
123 } 117 }
124 118
125 peng++; 119 peng++;
@@ -136,16 +130,15 @@ void mac_debugging_long(int pos, long addr)
136 * TODO: serial debug code 130 * TODO: serial debug code
137 */ 131 */
138 132
139struct mac_SCC 133struct mac_SCC {
140 { 134 u_char cha_b_ctrl;
141 u_char cha_b_ctrl; 135 u_char char_dummy1;
142 u_char char_dummy1; 136 u_char cha_a_ctrl;
143 u_char cha_a_ctrl; 137 u_char char_dummy2;
144 u_char char_dummy2; 138 u_char cha_b_data;
145 u_char cha_b_data; 139 u_char char_dummy3;
146 u_char char_dummy3; 140 u_char cha_a_data;
147 u_char cha_a_data; 141};
148 };
149 142
150# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase)) 143# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase))
151 144
@@ -158,9 +151,9 @@ int mac_SCC_reset_done;
158static int scc_port = -1; 151static int scc_port = -1;
159 152
160static struct console mac_console_driver = { 153static struct console mac_console_driver = {
161 .name = "debug", 154 .name = "debug",
162 .flags = CON_PRINTBUFFER, 155 .flags = CON_PRINTBUFFER,
163 .index = -1, 156 .index = -1,
164}; 157};
165 158
166/* 159/*
@@ -178,8 +171,8 @@ static struct console mac_console_driver = {
178 * this driver if Mac. 171 * this driver if Mac.
179 */ 172 */
180 173
181void mac_debug_console_write (struct console *co, const char *str, 174void mac_debug_console_write(struct console *co, const char *str,
182 unsigned int count) 175 unsigned int count)
183{ 176{
184 mac_serial_print(str); 177 mac_serial_print(str);
185} 178}
@@ -190,48 +183,50 @@ void mac_debug_console_write (struct console *co, const char *str,
190 183
191#define uSEC 1 184#define uSEC 1
192 185
193static inline void mac_sccb_out (char c) 186static inline void mac_sccb_out(char c)
194{ 187{
195 int i; 188 int i;
196 do { 189
197 for( i = uSEC; i > 0; --i ) 190 do {
191 for (i = uSEC; i > 0; --i)
192 barrier();
193 } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
194 for (i = uSEC; i > 0; --i)
198 barrier(); 195 barrier();
199 } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ 196 scc.cha_b_data = c;
200 for( i = uSEC; i > 0; --i )
201 barrier();
202 scc.cha_b_data = c;
203} 197}
204 198
205static inline void mac_scca_out (char c) 199static inline void mac_scca_out(char c)
206{ 200{
207 int i; 201 int i;
208 do { 202
209 for( i = uSEC; i > 0; --i ) 203 do {
204 for (i = uSEC; i > 0; --i)
205 barrier();
206 } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */
207 for (i = uSEC; i > 0; --i)
210 barrier(); 208 barrier();
211 } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ 209 scc.cha_a_data = c;
212 for( i = uSEC; i > 0; --i )
213 barrier();
214 scc.cha_a_data = c;
215} 210}
216 211
217void mac_sccb_console_write (struct console *co, const char *str, 212void mac_sccb_console_write(struct console *co, const char *str,
218 unsigned int count) 213 unsigned int count)
219{ 214{
220 while (count--) { 215 while (count--) {
221 if (*str == '\n') 216 if (*str == '\n')
222 mac_sccb_out( '\r' ); 217 mac_sccb_out('\r');
223 mac_sccb_out( *str++ ); 218 mac_sccb_out(*str++);
224 } 219 }
225} 220}
226 221
227void mac_scca_console_write (struct console *co, const char *str, 222void mac_scca_console_write(struct console *co, const char *str,
228 unsigned int count) 223 unsigned int count)
229{ 224{
230 while (count--) { 225 while (count--) {
231 if (*str == '\n') 226 if (*str == '\n')
232 mac_scca_out( '\r' ); 227 mac_scca_out('\r');
233 mac_scca_out( *str++ ); 228 mac_scca_out(*str++);
234 } 229 }
235} 230}
236 231
237 232
@@ -239,41 +234,41 @@ void mac_scca_console_write (struct console *co, const char *str,
239 * SCC serial ports. They're used by the debugging interface, kgdb, and the 234 * SCC serial ports. They're used by the debugging interface, kgdb, and the
240 * serial console code. */ 235 * serial console code. */
241#define SCCB_WRITE(reg,val) \ 236#define SCCB_WRITE(reg,val) \
242 do { \ 237 do { \
243 int i; \ 238 int i; \
244 scc.cha_b_ctrl = (reg); \ 239 scc.cha_b_ctrl = (reg); \
245 for( i = uSEC; i > 0; --i ) \ 240 for (i = uSEC; i > 0; --i) \
246 barrier(); \ 241 barrier(); \
247 scc.cha_b_ctrl = (val); \ 242 scc.cha_b_ctrl = (val); \
248 for( i = uSEC; i > 0; --i ) \ 243 for (i = uSEC; i > 0; --i) \
249 barrier(); \ 244 barrier(); \
250 } while(0) 245 } while(0)
251 246
252#define SCCA_WRITE(reg,val) \ 247#define SCCA_WRITE(reg,val) \
253 do { \ 248 do { \
254 int i; \ 249 int i; \
255 scc.cha_a_ctrl = (reg); \ 250 scc.cha_a_ctrl = (reg); \
256 for( i = uSEC; i > 0; --i ) \ 251 for (i = uSEC; i > 0; --i) \
257 barrier(); \ 252 barrier(); \
258 scc.cha_a_ctrl = (val); \ 253 scc.cha_a_ctrl = (val); \
259 for( i = uSEC; i > 0; --i ) \ 254 for (i = uSEC; i > 0; --i) \
260 barrier(); \ 255 barrier(); \
261 } while(0) 256 } while(0)
262 257
263/* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a 258/* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a
264 * delay of ~ 60us. */ 259 * delay of ~ 60us. */
265/* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/ 260/* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/
266#define LONG_DELAY() \ 261#define LONG_DELAY() \
267 do { \ 262 do { \
268 int i; \ 263 int i; \
269 for( i = 60*uSEC; i > 0; --i ) \ 264 for (i = 60*uSEC; i > 0; --i) \
270 barrier(); \ 265 barrier(); \
271 } while(0) 266 } while(0)
272 267
273#ifndef CONFIG_SERIAL_CONSOLE 268#ifndef CONFIG_SERIAL_CONSOLE
274static void __init mac_init_scc_port( int cflag, int port ) 269static void __init mac_init_scc_port(int cflag, int port)
275#else 270#else
276void mac_init_scc_port( int cflag, int port ) 271void mac_init_scc_port(int cflag, int port)
277#endif 272#endif
278{ 273{
279 extern int mac_SCC_reset_done; 274 extern int mac_SCC_reset_done;
@@ -292,106 +287,102 @@ void mac_init_scc_port( int cflag, int port )
292 /* reg12 (BRG low) */ 287 /* reg12 (BRG low) */
293 { 94, 62, 46, 22, 10, 4, 1, 0, 0 }; 288 { 94, 62, 46, 22, 10, 4, 1, 0, 0 };
294 289
295 int baud = cflag & CBAUD; 290 int baud = cflag & CBAUD;
296 int clksrc, clkmode, div, reg3, reg5; 291 int clksrc, clkmode, div, reg3, reg5;
297 292
298 if (cflag & CBAUDEX) 293 if (cflag & CBAUDEX)
299 baud += B38400; 294 baud += B38400;
300 if (baud < B1200 || baud > B38400+2) 295 if (baud < B1200 || baud > B38400+2)
301 baud = B9600; /* use default 9600bps for non-implemented rates */ 296 baud = B9600; /* use default 9600bps for non-implemented rates */
302 baud -= B1200; /* tables starts at 1200bps */ 297 baud -= B1200; /* tables starts at 1200bps */
303 298
304 clksrc = clksrc_table[baud]; 299 clksrc = clksrc_table[baud];
305 clkmode = clkmode_table[baud]; 300 clkmode = clkmode_table[baud];
306 div = div_table[baud]; 301 div = div_table[baud];
307 302
308 reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40); 303 reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40);
309 reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */; 304 reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */;
310 305
311 if (port == 1) { 306 if (port == 1) {
312 (void)scc.cha_b_ctrl; /* reset reg pointer */ 307 (void)scc.cha_b_ctrl; /* reset reg pointer */
313 SCCB_WRITE( 9, 0xc0 ); /* reset */ 308 SCCB_WRITE(9, 0xc0); /* reset */
314 LONG_DELAY(); /* extra delay after WR9 access */ 309 LONG_DELAY(); /* extra delay after WR9 access */
315 SCCB_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | 310 SCCB_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 |
311 0x04 /* 1 stopbit */ |
312 clkmode);
313 SCCB_WRITE(3, reg3);
314 SCCB_WRITE(5, reg5);
315 SCCB_WRITE(9, 0); /* no interrupts */
316 LONG_DELAY(); /* extra delay after WR9 access */
317 SCCB_WRITE(10, 0); /* NRZ mode */
318 SCCB_WRITE(11, clksrc); /* main clock source */
319 SCCB_WRITE(12, div); /* BRG value */
320 SCCB_WRITE(13, 0); /* BRG high byte */
321 SCCB_WRITE(14, 1);
322 SCCB_WRITE(3, reg3 | 1);
323 SCCB_WRITE(5, reg5 | 8);
324 } else if (port == 0) {
325 (void)scc.cha_a_ctrl; /* reset reg pointer */
326 SCCA_WRITE(9, 0xc0); /* reset */
327 LONG_DELAY(); /* extra delay after WR9 access */
328 SCCA_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 |
316 0x04 /* 1 stopbit */ | 329 0x04 /* 1 stopbit */ |
317 clkmode ); 330 clkmode);
318 SCCB_WRITE( 3, reg3 ); 331 SCCA_WRITE(3, reg3);
319 SCCB_WRITE( 5, reg5 ); 332 SCCA_WRITE(5, reg5);
320 SCCB_WRITE( 9, 0 ); /* no interrupts */ 333 SCCA_WRITE(9, 0); /* no interrupts */
321 LONG_DELAY(); /* extra delay after WR9 access */ 334 LONG_DELAY(); /* extra delay after WR9 access */
322 SCCB_WRITE( 10, 0 ); /* NRZ mode */ 335 SCCA_WRITE(10, 0); /* NRZ mode */
323 SCCB_WRITE( 11, clksrc ); /* main clock source */ 336 SCCA_WRITE(11, clksrc); /* main clock source */
324 SCCB_WRITE( 12, div ); /* BRG value */ 337 SCCA_WRITE(12, div); /* BRG value */
325 SCCB_WRITE( 13, 0 ); /* BRG high byte */ 338 SCCA_WRITE(13, 0); /* BRG high byte */
326 SCCB_WRITE( 14, 1 ); 339 SCCA_WRITE(14, 1);
327 SCCB_WRITE( 3, reg3 | 1 ); 340 SCCA_WRITE(3, reg3 | 1);
328 SCCB_WRITE( 5, reg5 | 8 ); 341 SCCA_WRITE(5, reg5 | 8);
329 } else if (port == 0) { 342 }
330 (void)scc.cha_a_ctrl; /* reset reg pointer */ 343
331 SCCA_WRITE( 9, 0xc0 ); /* reset */ 344 mac_SCC_reset_done = 1;
332 LONG_DELAY(); /* extra delay after WR9 access */ 345 mac_SCC_init_done = 1;
333 SCCA_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 |
334 0x04 /* 1 stopbit */ |
335 clkmode );
336 SCCA_WRITE( 3, reg3 );
337 SCCA_WRITE( 5, reg5 );
338 SCCA_WRITE( 9, 0 ); /* no interrupts */
339 LONG_DELAY(); /* extra delay after WR9 access */
340 SCCA_WRITE( 10, 0 ); /* NRZ mode */
341 SCCA_WRITE( 11, clksrc ); /* main clock source */
342 SCCA_WRITE( 12, div ); /* BRG value */
343 SCCA_WRITE( 13, 0 ); /* BRG high byte */
344 SCCA_WRITE( 14, 1 );
345 SCCA_WRITE( 3, reg3 | 1 );
346 SCCA_WRITE( 5, reg5 | 8 );
347 }
348
349 mac_SCC_reset_done = 1;
350 mac_SCC_init_done = 1;
351} 346}
352#endif /* DEBUG_SERIAL */ 347#endif /* DEBUG_SERIAL */
353 348
354void mac_init_scca_port( int cflag ) 349void mac_init_scca_port(int cflag)
355{ 350{
356 mac_init_scc_port(cflag, 0); 351 mac_init_scc_port(cflag, 0);
357} 352}
358 353
359void mac_init_sccb_port( int cflag ) 354void mac_init_sccb_port(int cflag)
360{ 355{
361 mac_init_scc_port(cflag, 1); 356 mac_init_scc_port(cflag, 1);
362} 357}
363 358
364void __init mac_debug_init(void) 359static int __init mac_debug_setup(char *arg)
365{ 360{
361 if (!MACH_IS_MAC)
362 return 0;
363
366#ifdef DEBUG_SERIAL 364#ifdef DEBUG_SERIAL
367 if ( !strcmp( m68k_debug_device, "ser" ) 365 if (!strcmp(arg, "ser") || !strcmp(arg, "ser1")) {
368 || !strcmp( m68k_debug_device, "ser1" )) { 366 /* Mac modem port */
369 /* Mac modem port */ 367 mac_init_scc_port(B9600|CS8, 0);
370 mac_init_scc_port( B9600|CS8, 0 ); 368 mac_console_driver.write = mac_scca_console_write;
371 mac_console_driver.write = mac_scca_console_write; 369 scc_port = 0;
372 scc_port = 0; 370 } else if (!strcmp(arg, "ser2")) {
373 } 371 /* Mac printer port */
374 else if (!strcmp( m68k_debug_device, "ser2" )) { 372 mac_init_scc_port(B9600|CS8, 1);
375 /* Mac printer port */ 373 mac_console_driver.write = mac_sccb_console_write;
376 mac_init_scc_port( B9600|CS8, 1 ); 374 scc_port = 1;
377 mac_console_driver.write = mac_sccb_console_write; 375 }
378 scc_port = 1;
379 }
380#endif 376#endif
381#ifdef DEBUG_HEADS 377#ifdef DEBUG_HEADS
382 if ( !strcmp( m68k_debug_device, "scn" ) 378 if (!strcmp(arg, "scn") || !strcmp(arg, "con")) {
383 || !strcmp( m68k_debug_device, "con" )) { 379 /* display, using head.S console routines */
384 /* display, using head.S console routines */ 380 mac_console_driver.write = mac_debug_console_write;
385 mac_console_driver.write = mac_debug_console_write; 381 }
386 }
387#endif 382#endif
388 if (mac_console_driver.write) 383 if (mac_console_driver.write)
389 register_console(&mac_console_driver); 384 register_console(&mac_console_driver);
385 return 0;
390} 386}
391 387
392/* 388early_param("debug", mac_debug_setup);
393 * Local variables:
394 * c-indent-level: 4
395 * tab-width: 8
396 * End:
397 */
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index f6fcd754d8f6..0fc72d8f786e 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -219,7 +219,7 @@ static void mac_disable_irq(unsigned int irq);
219 219
220static struct irq_controller mac_irq_controller = { 220static struct irq_controller mac_irq_controller = {
221 .name = "mac", 221 .name = "mac",
222 .lock = SPIN_LOCK_UNLOCKED, 222 .lock = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock),
223 .enable = mac_enable_irq, 223 .enable = mac_enable_irq,
224 .disable = mac_disable_irq, 224 .disable = mac_disable_irq,
225}; 225};
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c
index 63690819565a..d7be16917efd 100644
--- a/arch/m68k/mac/oss.c
+++ b/arch/m68k/mac/oss.c
@@ -109,13 +109,11 @@ irqreturn_t oss_irq(int irq, void *dev_id)
109 /* FIXME: how do you clear a pending IRQ? */ 109 /* FIXME: how do you clear a pending IRQ? */
110 110
111 if (events & OSS_IP_SOUND) { 111 if (events & OSS_IP_SOUND) {
112 /* FIXME: call sound handler */
113 oss->irq_pending &= ~OSS_IP_SOUND; 112 oss->irq_pending &= ~OSS_IP_SOUND;
113 /* FIXME: call sound handler */
114 } else if (events & OSS_IP_SCSI) { 114 } else if (events & OSS_IP_SCSI) {
115 oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED;
116 m68k_handle_int(IRQ_MAC_SCSI);
117 oss->irq_pending &= ~OSS_IP_SCSI; 115 oss->irq_pending &= ~OSS_IP_SCSI;
118 oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; 116 m68k_handle_int(IRQ_MAC_SCSI);
119 } else { 117 } else {
120 /* FIXME: error check here? */ 118 /* FIXME: error check here? */
121 } 119 }
@@ -143,14 +141,16 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id)
143#endif 141#endif
144 /* There are only six slots on the OSS, not seven */ 142 /* There are only six slots on the OSS, not seven */
145 143
146 for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { 144 i = 6;
145 irq_bit = 0x40;
146 do {
147 --i;
148 irq_bit >>= 1;
147 if (events & irq_bit) { 149 if (events & irq_bit) {
148 oss->irq_level[i] = OSS_IRQLEV_DISABLED;
149 m68k_handle_int(NUBUS_SOURCE_BASE + i);
150 oss->irq_pending &= ~irq_bit; 150 oss->irq_pending &= ~irq_bit;
151 oss->irq_level[i] = OSS_IRQLEV_NUBUS; 151 m68k_handle_int(NUBUS_SOURCE_BASE + i);
152 } 152 }
153 } 153 } while(events & (irq_bit - 1));
154 return IRQ_HANDLED; 154 return IRQ_HANDLED;
155} 155}
156 156
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index 15378a5878c9..d66f723b17c3 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -131,11 +131,8 @@ irqreturn_t psc_irq(int irq, void *dev_id)
131{ 131{
132 int pIFR = pIFRbase + ((int) dev_id); 132 int pIFR = pIFRbase + ((int) dev_id);
133 int pIER = pIERbase + ((int) dev_id); 133 int pIER = pIERbase + ((int) dev_id);
134 int base_irq; 134 int irq_num;
135 int irq_bit,i; 135 unsigned char irq_bit, events;
136 unsigned char events;
137
138 base_irq = irq << 3;
139 136
140#ifdef DEBUG_IRQS 137#ifdef DEBUG_IRQS
141 printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n", 138 printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n",
@@ -146,14 +143,16 @@ irqreturn_t psc_irq(int irq, void *dev_id)
146 if (!events) 143 if (!events)
147 return IRQ_NONE; 144 return IRQ_NONE;
148 145
149 for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) { 146 irq_num = irq << 3;
150 if (events & irq_bit) { 147 irq_bit = 1;
151 psc_write_byte(pIER, irq_bit); 148 do {
152 m68k_handle_int(base_irq + i); 149 if (events & irq_bit) {
153 psc_write_byte(pIFR, irq_bit); 150 psc_write_byte(pIFR, irq_bit);
154 psc_write_byte(pIER, irq_bit | 0x80); 151 m68k_handle_int(irq_num);
155 } 152 }
156 } 153 irq_num++;
154 irq_bit <<= 1;
155 } while (events >= irq_bit);
157 return IRQ_HANDLED; 156 return IRQ_HANDLED;
158} 157}
159 158
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index e27735be2924..d5cac72eb3db 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -13,6 +13,10 @@
13 * for info. A full-text web search on 6522 AND VIA will probably also 13 * for info. A full-text web search on 6522 AND VIA will probably also
14 * net some usefulness. <cananian@alumni.princeton.edu> 20apr1999 14 * net some usefulness. <cananian@alumni.princeton.edu> 20apr1999
15 * 15 *
16 * Additional data is here (the SY6522 was used in the Mac II etc):
17 * http://www.6502.org/documents/datasheets/synertek/synertek_sy6522.pdf
18 * http://www.6502.org/documents/datasheets/synertek/synertek_sy6522_programming_reference.pdf
19 *
16 * PRAM/RTC access algorithms are from the NetBSD RTC toolkit version 1.08b 20 * PRAM/RTC access algorithms are from the NetBSD RTC toolkit version 1.08b
17 * by Erik Vogan and adapted to Linux by Joshua M. Thompson (funaho@jurai.org) 21 * by Erik Vogan and adapted to Linux by Joshua M. Thompson (funaho@jurai.org)
18 * 22 *
@@ -37,7 +41,7 @@ volatile __u8 *via1, *via2;
37/* See note in mac_via.h about how this is possibly not useful */ 41/* See note in mac_via.h about how this is possibly not useful */
38volatile long *via_memory_bogon=(long *)&via_memory_bogon; 42volatile long *via_memory_bogon=(long *)&via_memory_bogon;
39#endif 43#endif
40int rbv_present,via_alt_mapping; 44int rbv_present, via_alt_mapping;
41__u8 rbv_clear; 45__u8 rbv_clear;
42 46
43/* 47/*
@@ -60,7 +64,19 @@ static int gIER,gIFR,gBufA,gBufB;
60#define MAC_CLOCK_LOW (MAC_CLOCK_TICK&0xFF) 64#define MAC_CLOCK_LOW (MAC_CLOCK_TICK&0xFF)
61#define MAC_CLOCK_HIGH (MAC_CLOCK_TICK>>8) 65#define MAC_CLOCK_HIGH (MAC_CLOCK_TICK>>8)
62 66
63static int nubus_active; 67/* To disable a NuBus slot on Quadras we make the slot IRQ lines outputs, set
68 * high. On RBV we just use the slot interrupt enable register. On Macs with
69 * genuine VIA chips we must use nubus_disabled to keep track of disabled slot
70 * interrupts. When any slot IRQ is disabled we mask the (edge triggered) CA1
71 * or "SLOTS" interrupt. When no slot is disabled, we unmask the CA1 interrupt.
72 * So, on genuine VIAs, having more than one NuBus IRQ can mean trouble,
73 * because closing one of those drivers can mask all of the NuBus interrupts.
74 * Also, since we can't mask the unregistered slot IRQs on genuine VIAs, it's
75 * possible to get interrupts from cards that MacOS or the ROM has configured
76 * but we have not. FWIW, "Designing Cards and Drivers for Macintosh II and
77 * Macintosh SE", page 9-8, says, a slot IRQ with no driver would crash MacOS.
78 */
79static u8 nubus_disabled;
64 80
65void via_debug_dump(void); 81void via_debug_dump(void);
66irqreturn_t via1_irq(int, void *); 82irqreturn_t via1_irq(int, void *);
@@ -138,11 +154,11 @@ void __init via_init(void)
138 154
139 printk(KERN_INFO "VIA2 at %p is ", via2); 155 printk(KERN_INFO "VIA2 at %p is ", via2);
140 if (rbv_present) { 156 if (rbv_present) {
141 printk(KERN_INFO "an RBV\n"); 157 printk("an RBV\n");
142 } else if (oss_present) { 158 } else if (oss_present) {
143 printk(KERN_INFO "an OSS\n"); 159 printk("an OSS\n");
144 } else { 160 } else {
145 printk(KERN_INFO "a 6522 or clone\n"); 161 printk("a 6522 or clone\n");
146 } 162 }
147 163
148#ifdef DEBUG_VIA 164#ifdef DEBUG_VIA
@@ -163,6 +179,7 @@ void __init via_init(void)
163 via1[vT2CL] = 0; 179 via1[vT2CL] = 0;
164 via1[vT2CH] = 0; 180 via1[vT2CH] = 0;
165 via1[vACR] &= 0x3F; 181 via1[vACR] &= 0x3F;
182 via1[vACR] &= ~0x03; /* disable port A & B latches */
166 183
167 /* 184 /*
168 * SE/30: disable video IRQ 185 * SE/30: disable video IRQ
@@ -193,8 +210,14 @@ void __init via_init(void)
193 /* that the IIfx emulates this alternate mapping using the OSS. */ 210 /* that the IIfx emulates this alternate mapping using the OSS. */
194 211
195 switch(macintosh_config->ident) { 212 switch(macintosh_config->ident) {
213 case MAC_MODEL_P475:
214 case MAC_MODEL_P475F:
215 case MAC_MODEL_P575:
216 case MAC_MODEL_Q605:
217 case MAC_MODEL_Q605_ACC:
196 case MAC_MODEL_C610: 218 case MAC_MODEL_C610:
197 case MAC_MODEL_Q610: 219 case MAC_MODEL_Q610:
220 case MAC_MODEL_Q630:
198 case MAC_MODEL_C650: 221 case MAC_MODEL_C650:
199 case MAC_MODEL_Q650: 222 case MAC_MODEL_Q650:
200 case MAC_MODEL_Q700: 223 case MAC_MODEL_Q700:
@@ -228,6 +251,22 @@ void __init via_init(void)
228 via2[vT2CL] = 0; 251 via2[vT2CL] = 0;
229 via2[vT2CH] = 0; 252 via2[vT2CH] = 0;
230 via2[vACR] &= 0x3F; 253 via2[vACR] &= 0x3F;
254 via2[vACR] &= ~0x03; /* disable port A & B latches */
255 }
256
257 /*
258 * Set vPCR for SCSI interrupts (but not on RBV)
259 */
260 if (!rbv_present) {
261 if (macintosh_config->scsi_type == MAC_SCSI_OLD) {
262 /* CB2 (IRQ) indep. input, positive edge */
263 /* CA2 (DRQ) indep. input, positive edge */
264 via2[vPCR] = 0x66;
265 } else {
266 /* CB2 (IRQ) indep. input, negative edge */
267 /* CA2 (DRQ) indep. input, negative edge */
268 via2[vPCR] = 0x22;
269 }
231 } 270 }
232} 271}
233 272
@@ -356,78 +395,75 @@ int via_get_cache_disable(void)
356 395
357void __init via_nubus_init(void) 396void __init via_nubus_init(void)
358{ 397{
359 /* don't set nubus_active = 0 here, it kills the Baboon */
360 /* interrupt that we've already registered. */
361
362 /* unlock nubus transactions */ 398 /* unlock nubus transactions */
363 399
364 if (!rbv_present) { 400 if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
401 (macintosh_config->adb_type != MAC_ADB_PB2)) {
365 /* set the line to be an output on non-RBV machines */ 402 /* set the line to be an output on non-RBV machines */
366 if ((macintosh_config->adb_type != MAC_ADB_PB1) && 403 if (!rbv_present)
367 (macintosh_config->adb_type != MAC_ADB_PB2)) {
368 via2[vDirB] |= 0x02; 404 via2[vDirB] |= 0x02;
369 }
370 }
371 405
372 /* this seems to be an ADB bit on PMU machines */ 406 /* this seems to be an ADB bit on PMU machines */
373 /* according to MkLinux. -- jmt */ 407 /* according to MkLinux. -- jmt */
374
375 if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
376 (macintosh_config->adb_type != MAC_ADB_PB2)) {
377 via2[gBufB] |= 0x02; 408 via2[gBufB] |= 0x02;
378 } 409 }
379 410
380 /* disable nubus slot interrupts. */ 411 /* Disable all the slot interrupts (where possible). */
381 if (rbv_present) { 412
413 switch (macintosh_config->via_type) {
414 case MAC_VIA_II:
415 /* Just make the port A lines inputs. */
416 switch(macintosh_config->ident) {
417 case MAC_MODEL_II:
418 case MAC_MODEL_IIX:
419 case MAC_MODEL_IICX:
420 case MAC_MODEL_SE30:
421 /* The top two bits are RAM size outputs. */
422 via2[vDirA] &= 0xC0;
423 break;
424 default:
425 via2[vDirA] &= 0x80;
426 }
427 break;
428 case MAC_VIA_IIci:
429 /* RBV. Disable all the slot interrupts. SIER works like IER. */
382 via2[rSIER] = 0x7F; 430 via2[rSIER] = 0x7F;
383 via2[rSIER] = nubus_active | 0x80; 431 break;
384 } else { 432 case MAC_VIA_QUADRA:
385 /* These are ADB bits on PMU */ 433 /* Disable the inactive slot interrupts by making those lines outputs. */
386 if ((macintosh_config->adb_type != MAC_ADB_PB1) && 434 if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
387 (macintosh_config->adb_type != MAC_ADB_PB2)) { 435 (macintosh_config->adb_type != MAC_ADB_PB2)) {
388 switch(macintosh_config->ident) 436 via2[vBufA] |= 0x7F;
389 { 437 via2[vDirA] |= 0x7F;
390 case MAC_MODEL_II:
391 case MAC_MODEL_IIX:
392 case MAC_MODEL_IICX:
393 case MAC_MODEL_SE30:
394 via2[vBufA] |= 0x3F;
395 via2[vDirA] = ~nubus_active | 0xc0;
396 break;
397 default:
398 via2[vBufA] = 0xFF;
399 via2[vDirA] = ~nubus_active;
400 }
401 } 438 }
439 break;
402 } 440 }
403} 441}
404 442
405/* 443/*
406 * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's 444 * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's
407 * via6522.c :-), disable/pending masks added. 445 * via6522.c :-), disable/pending masks added.
408 *
409 * The new interrupt architecture in macints.c takes care of a lot of the
410 * gruntwork for us, including tallying the interrupts and calling the
411 * handlers on the linked list. All we need to do here is basically generate
412 * the machspec interrupt number after clearing the interrupt.
413 */ 446 */
414 447
415irqreturn_t via1_irq(int irq, void *dev_id) 448irqreturn_t via1_irq(int irq, void *dev_id)
416{ 449{
417 int irq_bit, i; 450 int irq_num;
418 unsigned char events, mask; 451 unsigned char irq_bit, events;
419 452
420 mask = via1[vIER] & 0x7F; 453 events = via1[vIFR] & via1[vIER] & 0x7F;
421 if (!(events = via1[vIFR] & mask)) 454 if (!events)
422 return IRQ_NONE; 455 return IRQ_NONE;
423 456
424 for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) 457 irq_num = VIA1_SOURCE_BASE;
458 irq_bit = 1;
459 do {
425 if (events & irq_bit) { 460 if (events & irq_bit) {
426 via1[vIER] = irq_bit;
427 m68k_handle_int(VIA1_SOURCE_BASE + i);
428 via1[vIFR] = irq_bit; 461 via1[vIFR] = irq_bit;
429 via1[vIER] = irq_bit | 0x80; 462 m68k_handle_int(irq_num);
430 } 463 }
464 ++irq_num;
465 irq_bit <<= 1;
466 } while (events >= irq_bit);
431 467
432#if 0 /* freakin' pmu is doing weird stuff */ 468#if 0 /* freakin' pmu is doing weird stuff */
433 if (!oss_present) { 469 if (!oss_present) {
@@ -448,20 +484,23 @@ irqreturn_t via1_irq(int irq, void *dev_id)
448 484
449irqreturn_t via2_irq(int irq, void *dev_id) 485irqreturn_t via2_irq(int irq, void *dev_id)
450{ 486{
451 int irq_bit, i; 487 int irq_num;
452 unsigned char events, mask; 488 unsigned char irq_bit, events;
453 489
454 mask = via2[gIER] & 0x7F; 490 events = via2[gIFR] & via2[gIER] & 0x7F;
455 if (!(events = via2[gIFR] & mask)) 491 if (!events)
456 return IRQ_NONE; 492 return IRQ_NONE;
457 493
458 for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) 494 irq_num = VIA2_SOURCE_BASE;
495 irq_bit = 1;
496 do {
459 if (events & irq_bit) { 497 if (events & irq_bit) {
460 via2[gIER] = irq_bit;
461 via2[gIFR] = irq_bit | rbv_clear; 498 via2[gIFR] = irq_bit | rbv_clear;
462 m68k_handle_int(VIA2_SOURCE_BASE + i); 499 m68k_handle_int(irq_num);
463 via2[gIER] = irq_bit | 0x80;
464 } 500 }
501 ++irq_num;
502 irq_bit <<= 1;
503 } while (events >= irq_bit);
465 return IRQ_HANDLED; 504 return IRQ_HANDLED;
466} 505}
467 506
@@ -472,71 +511,75 @@ irqreturn_t via2_irq(int irq, void *dev_id)
472 511
473irqreturn_t via_nubus_irq(int irq, void *dev_id) 512irqreturn_t via_nubus_irq(int irq, void *dev_id)
474{ 513{
475 int irq_bit, i; 514 int slot_irq;
476 unsigned char events; 515 unsigned char slot_bit, events;
477 516
478 if (!(events = ~via2[gBufA] & nubus_active)) 517 events = ~via2[gBufA] & 0x7F;
518 if (rbv_present)
519 events &= via2[rSIER];
520 else
521 events &= ~via2[vDirA];
522 if (!events)
479 return IRQ_NONE; 523 return IRQ_NONE;
480 524
481 for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) { 525 do {
482 if (events & irq_bit) { 526 slot_irq = IRQ_NUBUS_F;
483 via_irq_disable(NUBUS_SOURCE_BASE + i); 527 slot_bit = 0x40;
484 m68k_handle_int(NUBUS_SOURCE_BASE + i); 528 do {
485 via_irq_enable(NUBUS_SOURCE_BASE + i); 529 if (events & slot_bit) {
486 } 530 events &= ~slot_bit;
487 } 531 m68k_handle_int(slot_irq);
532 }
533 --slot_irq;
534 slot_bit >>= 1;
535 } while (events);
536
537 /* clear the CA1 interrupt and make certain there's no more. */
538 via2[gIFR] = 0x02 | rbv_clear;
539 events = ~via2[gBufA] & 0x7F;
540 if (rbv_present)
541 events &= via2[rSIER];
542 else
543 events &= ~via2[vDirA];
544 } while (events);
488 return IRQ_HANDLED; 545 return IRQ_HANDLED;
489} 546}
490 547
491void via_irq_enable(int irq) { 548void via_irq_enable(int irq) {
492 int irq_src = IRQ_SRC(irq); 549 int irq_src = IRQ_SRC(irq);
493 int irq_idx = IRQ_IDX(irq); 550 int irq_idx = IRQ_IDX(irq);
494 int irq_bit = 1 << irq_idx;
495 551
496#ifdef DEBUG_IRQUSE 552#ifdef DEBUG_IRQUSE
497 printk(KERN_DEBUG "via_irq_enable(%d)\n", irq); 553 printk(KERN_DEBUG "via_irq_enable(%d)\n", irq);
498#endif 554#endif
499 555
500 if (irq_src == 1) { 556 if (irq_src == 1) {
501 via1[vIER] = irq_bit | 0x80; 557 via1[vIER] = IER_SET_BIT(irq_idx);
502 } else if (irq_src == 2) { 558 } else if (irq_src == 2) {
503 /* 559 if (irq != IRQ_MAC_NUBUS || nubus_disabled == 0)
504 * Set vPCR for SCSI interrupts (but not on RBV) 560 via2[gIER] = IER_SET_BIT(irq_idx);
505 */
506 if ((irq_idx == 0) && !rbv_present) {
507 if (macintosh_config->scsi_type == MAC_SCSI_OLD) {
508 /* CB2 (IRQ) indep. input, positive edge */
509 /* CA2 (DRQ) indep. input, positive edge */
510 via2[vPCR] = 0x66;
511 } else {
512 /* CB2 (IRQ) indep. input, negative edge */
513 /* CA2 (DRQ) indep. input, negative edge */
514 via2[vPCR] = 0x22;
515 }
516 }
517 via2[gIER] = irq_bit | 0x80;
518 } else if (irq_src == 7) { 561 } else if (irq_src == 7) {
519 nubus_active |= irq_bit; 562 switch (macintosh_config->via_type) {
520 if (rbv_present) { 563 case MAC_VIA_II:
521 /* enable the slot interrupt. SIER works like IER. */ 564 nubus_disabled &= ~(1 << irq_idx);
565 /* Enable the CA1 interrupt when no slot is disabled. */
566 if (!nubus_disabled)
567 via2[gIER] = IER_SET_BIT(1);
568 break;
569 case MAC_VIA_IIci:
570 /* On RBV, enable the slot interrupt.
571 * SIER works like IER.
572 */
522 via2[rSIER] = IER_SET_BIT(irq_idx); 573 via2[rSIER] = IER_SET_BIT(irq_idx);
523 } else { 574 break;
524 /* Make sure the bit is an input, to enable the irq */ 575 case MAC_VIA_QUADRA:
525 /* But not on PowerBooks, that's ADB... */ 576 /* Make the port A line an input to enable the slot irq.
577 * But not on PowerBooks, that's ADB.
578 */
526 if ((macintosh_config->adb_type != MAC_ADB_PB1) && 579 if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
527 (macintosh_config->adb_type != MAC_ADB_PB2)) { 580 (macintosh_config->adb_type != MAC_ADB_PB2))
528 switch(macintosh_config->ident) 581 via2[vDirA] &= ~(1 << irq_idx);
529 { 582 break;
530 case MAC_MODEL_II:
531 case MAC_MODEL_IIX:
532 case MAC_MODEL_IICX:
533 case MAC_MODEL_SE30:
534 via2[vDirA] &= (~irq_bit | 0xc0);
535 break;
536 default:
537 via2[vDirA] &= ~irq_bit;
538 }
539 }
540 } 583 }
541 } 584 }
542} 585}
@@ -544,29 +587,31 @@ void via_irq_enable(int irq) {
544void via_irq_disable(int irq) { 587void via_irq_disable(int irq) {
545 int irq_src = IRQ_SRC(irq); 588 int irq_src = IRQ_SRC(irq);
546 int irq_idx = IRQ_IDX(irq); 589 int irq_idx = IRQ_IDX(irq);
547 int irq_bit = 1 << irq_idx;
548 590
549#ifdef DEBUG_IRQUSE 591#ifdef DEBUG_IRQUSE
550 printk(KERN_DEBUG "via_irq_disable(%d)\n", irq); 592 printk(KERN_DEBUG "via_irq_disable(%d)\n", irq);
551#endif 593#endif
552 594
553 if (irq_src == 1) { 595 if (irq_src == 1) {
554 via1[vIER] = irq_bit; 596 via1[vIER] = IER_CLR_BIT(irq_idx);
555 } else if (irq_src == 2) { 597 } else if (irq_src == 2) {
556 via2[gIER] = irq_bit; 598 via2[gIER] = IER_CLR_BIT(irq_idx);
557 } else if (irq_src == 7) { 599 } else if (irq_src == 7) {
558 if (rbv_present) { 600 switch (macintosh_config->via_type) {
559 /* disable the slot interrupt. SIER works like IER. */ 601 case MAC_VIA_II:
602 nubus_disabled |= 1 << irq_idx;
603 if (nubus_disabled)
604 via2[gIER] = IER_CLR_BIT(1);
605 break;
606 case MAC_VIA_IIci:
560 via2[rSIER] = IER_CLR_BIT(irq_idx); 607 via2[rSIER] = IER_CLR_BIT(irq_idx);
561 } else { 608 break;
562 /* disable the nubus irq by changing dir to output */ 609 case MAC_VIA_QUADRA:
563 /* except on PMU */
564 if ((macintosh_config->adb_type != MAC_ADB_PB1) && 610 if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
565 (macintosh_config->adb_type != MAC_ADB_PB2)) { 611 (macintosh_config->adb_type != MAC_ADB_PB2))
566 via2[vDirA] |= irq_bit; 612 via2[vDirA] |= 1 << irq_idx;
567 } 613 break;
568 } 614 }
569 nubus_active &= ~irq_bit;
570 } 615 }
571} 616}
572 617
@@ -580,7 +625,9 @@ void via_irq_clear(int irq) {
580 } else if (irq_src == 2) { 625 } else if (irq_src == 2) {
581 via2[gIFR] = irq_bit | rbv_clear; 626 via2[gIFR] = irq_bit | rbv_clear;
582 } else if (irq_src == 7) { 627 } else if (irq_src == 7) {
583 /* FIXME: hmm.. */ 628 /* FIXME: There is no way to clear an individual nubus slot
629 * IRQ flag, other than getting the device to do it.
630 */
584 } 631 }
585} 632}
586 633
@@ -600,6 +647,7 @@ int via_irq_pending(int irq)
600 } else if (irq_src == 2) { 647 } else if (irq_src == 2) {
601 return via2[gIFR] & irq_bit; 648 return via2[gIFR] & irq_bit;
602 } else if (irq_src == 7) { 649 } else if (irq_src == 7) {
650 /* Always 0 for MAC_VIA_QUADRA if the slot irq is disabled. */
603 return ~via2[gBufA] & irq_bit; 651 return ~via2[gBufA] & irq_bit;
604 } 652 }
605 return 0; 653 return 0;