Date: Wed, 10 Dec 1997 14:01:52 GMT
From: Roman Hodek <rnhodek@faui22c.informatik.uni-erlangen.de>
To: linux-m68k@lists.linux-m68k.org
In-reply-to: <199712101101.LAA03790@faui21.informatik.uni-erlangen.de>
	(message from Roman Hodek on Wed, 10 Dec 1997 11:04:15 GMT)
Subject: Re: L68K: patch for atari_MFPser.c
Sender: owner-linux-m68k@phil.uni-sb.de


Here is the patch. It first rewrites Juergen's asms to C code (which
produces nearly the same assembler code). Hope it still works (but I'm
rather confident :-) Second, it corrects clearing of pending MFP
interrupts.

Roman

------------------------------------------------------------------------------
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/drivers/char/atari_MFPser.c linux-2.1.64/drivers/char/atari_MFPser.c
--- linux-2.1.64.orig/drivers/char/atari_MFPser.c	Wed Dec 10 12:05:21 1997
+++ linux-2.1.64/drivers/char/atari_MFPser.c	Wed Dec 10 14:50:31 1997
@@ -241,28 +241,26 @@
 	return( nr > 0 ? 0 : -ENODEV );
 }
 
-static void __inline__ set_timer_D(struct MFP *thismfp, int baud, int prescale) {
+static void __inline__ set_timer_D(volatile struct MFP *thismfp,
+								   int baud, int prescale) {
 /* set timer d to given value, prescale 4
  * allow PLL-settling (3 bit-times)
  */
 
     int count;
 
-    __asm__ __volatile__ (
-	"	andb	#0xf8, 0x1c(%2)	\t\n"	/* disable timer D */
-	"	moveb	%3, 0x24(%2)	\t\n"	/* preset baudrate */
-	"	orb	%4, 0x1c(%2)	\t\n"	/* enable timer D, prescale N */
-	"1:	moveb	#0xef, 0x0c(%2)	\t\n"	/* clear pending int D */
-	"2:	btst	#4, 0x0c(%2)	\t\n"	/* pending int D? */
-	"	beq	2b		\t\n"	/*   no: wait... */
-	"	subq	#1, %0		\t\n"
-	"	bne	1b		\t\n"	
-	: "=d"(count)
-	: "0" (count=6), "a"(thismfp), "d"(baud), "d"(prescale)
-    );
+	thismfp->tim_ct_cd &= 0xf8;		/* disable timer D */
+	thismfp->tim_dt_d = baud;		/* preset baudrate */
+	thismfp->tim_ct_cd |= prescale;	/* enable timer D, prescale N */
+
+	for( count = 6; count; --count ) {
+		thismfp->int_pn_b = ~0x10;
+		while( !(thismfp->int_pn_b & 0x10) )
+			;
+	}
 }
 
-static int detect_MFP_speeder(struct MFP *currMFP) {
+static int detect_MFP_speeder(volatile struct MFP *currMFP) {
 /* try to autodetect RSVE, RSFI or similiar RS232 speeders
  *
  *  (c) Harun Scheutzow 
@@ -317,20 +315,17 @@
 	cli();
 
 	/* check for fixed speed / bad speed */
-	__asm__ __volatile__ (
-		"	moveb	#0x1, 0x2a(%2)	\t\n"	/* currMFP->rcv_stat = RSR_RX_ENAB */
-		"1:	addql	#1, %0		\t\n"	/* count++; 			*/
-		"	moveb	#0xef, 0x0c(%2)	\t\n"	/* currMFP->int_pn_b &= 0xef;	*/
-		"2:	btst	#4, 0x0c(%2)	\t\n"	/* timer D toggle? */
-		"	bne	1b		\t\n"	/*   increment timer D zero-count */
-		"	btst	#3, 0x2a(%2)	\t\n"	/* currMFP->rcv_stat & RSR_SYNC_SEARCH */
-		"	bne	3f		\t\n"	/*   finish	*/
-		"	cmp	#22, %0		\t\n"	/* max. wait (= 11 bittimes) reached? */
-		"	bcs	2b		\t\n"	/*   no - again */
-		"3:				\n\t"
-		: "=d"(count)
-		: "0"(count=-1), "a"(currMFP)	
-	);
+	currMFP->rcv_stat = RSR_RX_ENAB;
+	count = -1;
+	do {
+	  continue_outer:
+		++count;
+		currMFP->int_pn_b = ~0x10;
+		do {
+			if (currMFP->int_pn_b & 0x10)
+				goto continue_outer;
+		} while( !(currMFP->rcv_stat & RSR_SYNC_SEARCH) && count <= 22 );
+	} while(0);
 	restore_flags(flags);
 
 	/* for RSxx or standard MFP we have 8 bittimes (count=16) */
@@ -356,24 +351,26 @@
 		 * RSFI:     38400	  1.39		208us
 		 * Standard:  1720	  0.06
 		 * 
-		 */ 
-		__asm__ __volatile__ (
-			"	moveb	#0xef, 0x0c(%2)	\t\n"	/* clear IRQ pending D */
-			"9:	btst	#4, 0x0c(%2)	\t\n"	/* syncronize timer D */
-			"	beq	9b		\t\n"
-			"	moveb	#0xef, 0x0c(%2)	\t\n"	/* clear IRQ pending D */
-			"1:	moveb	#0, 0x2a(%2)	\t\n"	/* disable Rx */
-			"	addql	#1, %0		\t\n"	/* count++ */
-			"	tstb	(%2)		\t\n"	/* consume time */
-			"	moveb	#1, 0x2a(%2)	\t\n"	/* enable Rx */
-			"	nop			\t\n"
-			"2:	btst	#3, 0x2a(%2)	\t\n"	/* sync char detect? */
-			"	bne	1b		\t\n"	/*   yes: increment sync-count */
-			"	btst	#4, 0x0c(%2)	\t\n"	/* timer D expired? */
-			"	beq	2b		\t\n"	/*   no: test again */
-			: "=d"(count)
-			: "0" (count=-1), "a"(currMFP)
-		);
+		 */
+		currMFP->int_pn_b = ~0x10;
+		/* syncronize to timer D */
+		while( !(currMFP->int_pn_b & 0x10) )
+			;
+		currMFP->int_pn_b = ~0x10;
+		count = -1;
+		do {
+		  continue_outer2:
+			currMFP->rcv_stat = 0;				/* disable Rx */
+			++count;
+			(void)currMFP->par_dt_reg;			/* delay */
+			currMFP->rcv_stat = RSR_RX_ENAB;	/* enable Rx */
+			nop();
+			do {
+				/* increment counter if sync char detected */
+				if (currMFP->rcv_stat & RSR_SYNC_SEARCH)
+					goto continue_outer2;
+			} while( !(currMFP->int_pn_b & 0x10) );
+		} while(0);
 
 #ifdef RSFI_DEBUG
 		printk(KERN_INFO "    detect_MFP_speeder: count[110]=%d\n", count);
@@ -393,8 +390,8 @@
 	currMFP->int_mk_a = imra;
 	currMFP->int_mk_b = imrb;
 	currMFP->int_en_b &= 0xef;
-	currMFP->int_pn_a &= 0xe1;		/* mask off pending Rx/Tx */
-	currMFP->int_pn_b &= 0xef;		/* mask off pending Timer D */
+	currMFP->int_pn_a = 0xe1;		/* mask off pending Rx/Tx */
+	currMFP->int_pn_b = 0xef;		/* mask off pending Timer D */
 	return speeder;
 
 }
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/drivers/char/atari_SCC.c linux-2.1.64/drivers/char/atari_SCC.c
--- linux-2.1.64.orig/drivers/char/atari_SCC.c	Wed Dec  3 14:50:59 1997
+++ linux-2.1.64/drivers/char/atari_SCC.c	Wed Dec 10 12:15:42 1997
@@ -534,7 +534,7 @@
 				  scca_dma_buf[i].pbuf = (char *)VTOP((int)scca_dma_buf[i].buf);
 
 				tt_mfp.int_en_a &= ~0x20;
-				tt_mfp.int_pn_a &= ~0x20;
+				tt_mfp.int_pn_a = ~0x20;
 				tt_mfp.tim_ct_a = 0x00;
 				tt_mfp.tim_dt_a = 0x00;
 				request_irq (IRQ_TT_MFP_TIMA, SCC_timer_int, IRQ_TYPE_SLOW,
@@ -626,7 +626,7 @@
 #ifdef CONFIG_ATARI_SCC_DMA
 	if (channel == CHANNEL_A && scca_dma) {
 		tt_mfp.int_en_a &= ~0x20;
-		tt_mfp.int_pn_a &= ~0x20;
+		tt_mfp.int_pn_a = ~0x20;
 		tt_mfp.int_mk_a &= ~0x20;
 		free_irq(IRQ_TT_MFP_SCC, info);
 		free_irq(IRQ_TT_MFP_TIMA, info);
@@ -1358,7 +1358,7 @@
 		 */
 		tt_mfp.int_en_b &= ~4;
 		tt_mfp.active_edge |= 4;
-		tt_mfp.int_pn_b &= ~4;
+		tt_mfp.int_pn_b = ~4;
 		tt_mfp.int_mk_b |= 4;
 		tt_mfp.int_en_b |= 4;
 
