linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Frank Bodammer <frank.bodammer@hs.gcd-erlangen.de>
To: Linuxppc-Embedded <linuxppc-embedded@ozlabs.org>
Subject: Re: AW: MPC5200,PSC in uart mode, receiving problem
Date: Thu, 02 Feb 2006 19:22:47 +0100	[thread overview]
Message-ID: <43E24DF7.5010304@hs.gcd-erlangen.de> (raw)
In-Reply-To: <002001c5ce3b$3972bbe0$34f1ff0a@beint.local>

[-- Attachment #1: Type: text/plain, Size: 1145 bytes --]

Achim Machura wrote:
> Here the patch
>  
> 
>>Even better, post a patch here on the list so we all can benefit.

I experienced similar problems with the serial ports on mpc5200 PSCs
and so i was happy to find your patch, which solved some problem, but
not all. The overrun flag still wasn´t reset after an input overrun
error, so this error was reported persistent for each received character.
I fixed this by adding an command to reset the psc error flags in
receive_char() where the overrun flag is checked. Maybe this isn't
the best solution, but it seems to work.

To reset the overrun error flag, i tried the following statement:

	out_8(&psc->command, MPC5xxx_PSC_RST_ERR_STAT);

but i got unpredictable behaviour in some cases ending in a reset.
Doing the same this way:

	psc->command = MPC5xxx_PSC_RST_ERR_STAT;

always worked as expected. Does someone know what may be wrong with
'out_8' on mpc5200 with kernel 2.4.25 or is that a configuration problem.

By the way, i improved some other parts of the code, especially the
/proc output and the portconfig stuff, so i also attach a patch here,
even not all of it may be useful.

Frank

[-- Attachment #2: patch_linuxppc_2_4_psc-060202.diff --]
[-- Type: text/plain, Size: 18129 bytes --]

--- psc-orig.c	2006-02-02 10:41:45.000000000 +0100
+++ psc.c	2006-02-02 17:30:59.000000000 +0100
@@ -29,6 +29,7 @@
 #include <linux/serial.h>
 #include <linux/serialP.h>
 #include <linux/generic_serial.h>
+#include <linux/proc_fs.h>
 #ifdef CONFIG_UBOOT
 #include <asm/ppcboot.h>
 #endif
@@ -37,7 +38,8 @@
  * This driver can spew a whole lot of debugging output at you. If you
  * need maximum performance, you should disable the DEBUG define.
  */
-#undef MPC5xxx_PSC_DEBUG 
+#undef MPC5xxx_PSC_DEBUG
+//#define MPC5xxx_PSC_DEBUG		1
 
 #ifdef MPC5xxx_PSC_DEBUG
 #define MPC5xxx_PSC_DEBUG_OPEN		0x00000001
@@ -55,6 +57,7 @@
 #define MPC5xxx_PSC_DEBUG_FIRMWARE	0x00001000
 #define MPC5xxx_PSC_DEBUG_MEMTEST	0x00002000
 #define MPC5xxx_PSC_DEBUG_THROTTLE	0x00004000
+#define MPC5xxx_PSC_DEBUG_CLEARERR	0x00008000
 #define MPC5xxx_PSC_DEBUG_ALL		0xffffffff
 
 int rs_debug = MPC5xxx_PSC_DEBUG_ALL & ~MPC5xxx_PSC_DEBUG_TRANSMIT;
@@ -73,7 +76,7 @@
 /*
  * Number of serial ports
  */
-#define MPC5xxx_PSC_NPORTS	3
+#define MPC5xxx_PSC_NPORTS	4
 
 #ifdef CONFIG_PPC_5xxx_PSC_CONSOLE
 #ifndef CONFIG_PPC_5xxx_PSC_CONSOLE_PORT
@@ -89,7 +92,7 @@
 /*
  * Hardware specific serial port structure
  */
-struct rs_port { 	
+struct rs_port {
 	struct gs_port		gs;		/* Must be first field! */
 
 	struct mpc5xxx_psc	*psc;
@@ -121,7 +124,7 @@
 /*
  * Used by generic serial driver to access hardware
  */
-static struct real_driver rs_real_driver = { 
+static struct real_driver rs_real_driver = {
 	.disable_tx_interrupts	= rs_disable_tx_interrupts, 
 	.enable_tx_interrupts	= rs_enable_tx_interrupts, 
 	.disable_rx_interrupts	= rs_disable_rx_interrupts, 
@@ -134,9 +137,15 @@
 	.hungup			= rs_hungup,
 }; 
 
+#ifdef CONFIG_PS2MULT
+struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+#else
 static struct serial_state rs_table[RS_TABLE_SIZE] = {
 	SERIAL_PORT_DFNS	/* Defined in serial.h */
 };
+#endif
 
 /*
  * Structures and such for TTY sessions and usage counts
@@ -151,6 +160,14 @@
 int rs_initialized = 0;
 
 /*
+ * proc stuff
+ */
+static int sio_read_info(char * buf, char ** start, off_t offset, int count, int  *eof, void * data);
+
+static struct proc_dir_entry 	*proc_psc_dir,
+				*proc_psc[MPC5xxx_PSC_NPORTS];
+
+/*
  * ----------------------------------------------------------------------
  *
  * Here starts the interrupt handling routines.  All of the following
@@ -180,11 +197,11 @@
 
 	/* While there are characters, get them ... */
 	while (--count >= 0) {
-		status = in_be16(&psc->mpc5xxx_psc_status);
+		status = psc->mpc5xxx_psc_status;
 		if (!(status & MPC5xxx_PSC_SR_RXRDY))
 			break;
 
-		ch = in_8(&psc->mpc5xxx_psc_buffer_8);
+		ch = psc->mpc5xxx_psc_buffer_8;
 
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
 			continue;
@@ -215,6 +232,9 @@
 					tty->flip.count++;
 				}
 				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+				rs_dprintk(MPC5xxx_PSC_DEBUG_RECEIVE, "reset psc overrun error status: 0x%04x\n", status);
+				/* Reset PSC error status */
+				psc->command = MPC5xxx_PSC_RST_ERR_STAT;
 			}
 		}
 
@@ -234,7 +254,7 @@
 
 	/* While I'm able to transmit ... */
 	while (--count >= 0) {
-		status = in_be16(&psc->mpc5xxx_psc_status);
+		status = psc->mpc5xxx_psc_status;
 		/*
 		 * XXX -df
 		 * check_modem_status(status);
@@ -243,7 +263,7 @@
 			break;
 
 		if (port->x_char) {
-			out_8(&psc->mpc5xxx_psc_buffer_8, port->x_char);
+			psc->mpc5xxx_psc_buffer_8 = port->x_char;
 			port->icount.tx++;
 			port->x_char = 0;
 		}
@@ -252,8 +272,7 @@
 			break;
 		}
 		else {
-			out_8(&psc->mpc5xxx_psc_buffer_8,
-				port->gs.xmit_buf[port->gs.xmit_tail++]);
+			psc->mpc5xxx_psc_buffer_8 = port->gs.xmit_buf[port->gs.xmit_tail++];
 			port->icount.tx++;
 			port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
 			if (--port->gs.xmit_cnt <= 0) {
@@ -266,7 +285,7 @@
 			 port->gs.tty->hw_stopped) {
 		rs_disable_tx_interrupts(port);
 	}
-	
+
 	if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
 		if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 				port->gs.tty->ldisc.write_wakeup)
@@ -275,7 +294,7 @@
 				"Waking up.... ldisc (%d)....\n",
 				port->gs.wakeup_chars); 
 		wake_up_interruptible(&port->gs.tty->write_wait);
-	}	
+	}
 }
 
 
@@ -294,19 +313,35 @@
 
 static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
-	struct rs_port * port;
+	struct rs_port * port = (struct rs_port *)dev_id;
+	struct mpc5xxx_psc *psc = port->psc;
 	unsigned long flags;
+	u16 status;
 
 	spin_lock_irqsave(&mpc5xxx_serial_lock, flags);
 
-	port = (struct rs_port *)dev_id;
 	rs_dprintk(MPC5xxx_PSC_DEBUG_INTERRUPTS,
 			"rs_interrupt (port %p)...", port);
 
+	if (!port || !port->gs.tty) {
+		printk( KERN_DEBUG"%s(%d): port=%p tty=%p\n", __FUNCTION__, __LINE__,
+				port, port?port->gs.tty:NULL );
+		goto out;
+	}
+
+	status = psc->mpc5xxx_psc_status;
+	/* RB-Bit is set ?  */
+	if (status & MPC5xxx_PSC_SR_RB)
+	{
+		rs_dprintk(MPC5xxx_PSC_DEBUG_INTERRUPTS, "reset psc error status: 0x%04x\n", status);
+		psc->command = MPC5xxx_PSC_RST_ERR_STAT;
+		goto out;
+	}
+
 	receive_char(port);
 
 	transmit_char(port);
-
+out:
 	spin_unlock_irqrestore(&mpc5xxx_serial_lock, flags);
 
 	rs_dprintk(MPC5xxx_PSC_DEBUG_INTERRUPTS, "end.\n");
@@ -318,7 +353,7 @@
  *		interface with the generic_serial driver		*
  ************************************************************************
  */
-static void rs_disable_tx_interrupts(void * ptr) 
+static void rs_disable_tx_interrupts(void *ptr)
 {
 	struct rs_port *port = ptr; 
 	struct mpc5xxx_psc *psc = port->psc;
@@ -328,7 +363,7 @@
 	port->gs.flags &= ~GS_TX_INTEN;
 
 	port->imr &= ~MPC5xxx_PSC_IMR_TXRDY;
-	out_be16(&psc->mpc5xxx_psc_imr, port->imr);
+	psc->mpc5xxx_psc_imr = port->imr;
 
 	spin_unlock_irqrestore(&mpc5xxx_serial_lock, flags);
 }
@@ -342,7 +377,7 @@
 	spin_lock_irqsave(&mpc5xxx_serial_lock, flags);
 
 	port->imr |= MPC5xxx_PSC_IMR_TXRDY;
-	out_be16(&psc->mpc5xxx_psc_imr, port->imr);
+	psc->mpc5xxx_psc_imr = port->imr;
 
 	/* Send a char to start TX interrupts happening */
 	transmit_char(port);
@@ -359,7 +394,8 @@
 	spin_lock_irqsave(&mpc5xxx_serial_lock, flags);
 
 	port->imr &= ~MPC5xxx_PSC_IMR_RXRDY;
-	out_be16(&psc->mpc5xxx_psc_imr, port->imr);
+	psc->mpc5xxx_psc_imr = port->imr;
+	rs_dprintk(MPC5xxx_PSC_DEBUG_RECEIVE,"disable RxInt\n");
 
 	spin_unlock_irqrestore(&mpc5xxx_serial_lock, flags);
 }
@@ -373,18 +409,10 @@
 	spin_lock_irqsave(&mpc5xxx_serial_lock, flags);
 
 	port->imr |= MPC5xxx_PSC_IMR_RXRDY;
-	out_be16(&psc->mpc5xxx_psc_imr, port->imr);
-
-	/* Empty the input buffer - apparently this is *vital* */
-	/*
-	 * XXXX add this back in if needed, -df
-	 *
-	 * while (in_be16(&psc->mpc5xxx_psc_status) & MPC5xxx_PSC_SR_RXRDY)
-	 *	in_8(&psc->mpc5xxx_psc_buffer_8);
-	 */
+	psc->mpc5xxx_psc_imr = port->imr;
+	rs_dprintk(MPC5xxx_PSC_DEBUG_RECEIVE,"enable RxInt\n");
 
 	spin_unlock_irqrestore(&mpc5xxx_serial_lock, flags);
-
 }
 
 static int rs_get_CD(void * ptr) 
@@ -394,7 +422,7 @@
 	func_enter();
 
 	func_exit();
-	return (in_8(&port->psc->mpc5xxx_psc_ipcr) & MPC5xxx_PSC_DCD) != 0;
+	return (port->psc->mpc5xxx_psc_ipcr & MPC5xxx_PSC_DCD) != 0;
 }
 
 static void rs_shutdown_port(void * ptr) 
@@ -432,34 +460,67 @@
 
 	divisor = ((port->gs.baud_base / (port->gs.baud * 16)) + 1) >> 1;
 	if (port->gs.baud < 50 || divisor == 0) {
-		printk(KERN_NOTICE "MPC5xxx PSC: Bad speed requested, %d\n",
-				port->gs.baud);
+		printk(KERN_NOTICE "MPC5xxx PSC: Bad speed requested, %d, %d\n",
+				port->gs.baud, divisor);
 		return 0;
 	}
 	/* Configure the PSC for UART mode */
 	line = minor(port->gs.tty->device) - port->gs.tty->driver.minor_start;
+
+#if 0
+	/* This works only for PSC1..PSC3 and assumes that the ports are assigned  */
+	/* in this order. In other configurations it affects functions like usb    */
+	/* or ethernet. It isn't needed, when portconfig is done by the bootloader */
 	val32 = in_be32(&gpio->port_config);
 	val32 |= (MPC5xxx_GPIO_PSC_CONFIG_UART_WITHOUT_CD << (4*line));
 	out_be32(&gpio->port_config, val32);
+#else
+	switch ((int) port->psc) {
+		case MPC5xxx_PSC1: {
+			rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS, "Setup portconfig for PSC1\n");
+			gpio->port_config |= MPC5xxx_GPIO_PSC_CONFIG_UART_WITHOUT_CD;
+			break;
+		}
+		case MPC5xxx_PSC2: {
+			rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS, "Setup portconfig for PSC2\n");
+			gpio->port_config |= (MPC5xxx_GPIO_PSC_CONFIG_UART_WITHOUT_CD << 4);
+			break;
+		}
+		case MPC5xxx_PSC3: {
+			rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS, "Setup portconfig for PSC3\n");
+			gpio->port_config |= (MPC5xxx_GPIO_PSC_CONFIG_UART_WITHOUT_CD << 8);
+			break;
+		}
+		case MPC5xxx_PSC4: {
+			rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS, "Setup portconfig for PSC4\n");
+			break;
+		}
+		case MPC5xxx_PSC5: {
+			rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS, "Setup portconfig for PSC5\n");
+			break;
+		}
+		case MPC5xxx_PSC6: {
+			rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS, "Setup portconfig for PSC6\n");
+			break;
+		}
+	}
+#endif
+
 	/* reset and enable PSC */
-	out_8(&psc->command, MPC5xxx_PSC_RST_TX
-		  | MPC5xxx_PSC_RX_DISABLE | MPC5xxx_PSC_TX_ENABLE);
-	out_8(&psc->command, MPC5xxx_PSC_RST_RX);
+	psc->command = MPC5xxx_PSC_RST_TX | MPC5xxx_PSC_TX_ENABLE;
+
 	/* Set PSC operation mode as 'UART, DCD ignored' */
-	out_be32(&psc->sicr, 0x0);
+	psc->sicr = 0x0;
 	/* Set clocking */
-	out_be16(&psc->mpc5xxx_psc_clock_select, 0xdd00);
+	psc->mpc5xxx_psc_clock_select = 0xdd00;
 	/* Set tx FIFO alarm level */
-	out_be16(&psc->tfalarm, 0xf8);
+	psc->tfalarm = 0xf8;
 	/* Put PSC into the operation */
-	out_8(&psc->command, MPC5xxx_PSC_SEL_MODE_REG_1
-		  | MPC5xxx_PSC_RX_ENABLE
-		  | MPC5xxx_PSC_TX_ENABLE);
-
-	rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS, "calculated divisor: %d\n",
-			divisor);
-	out_8(&psc->ctur, divisor>>8);
-	out_8(&psc->ctlr, divisor);
+	psc->command = MPC5xxx_PSC_SEL_MODE_REG_1 | MPC5xxx_PSC_RX_ENABLE | MPC5xxx_PSC_TX_ENABLE;
+
+	rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS, "calculated divisor: %d\n", divisor);
+	psc->ctur = divisor >> 8;
+	psc->ctlr = divisor;
 
 	/* Program hardware for parity, data bits, stop bits */
 	if ((CFLAG & CSIZE)==CS5)
@@ -496,19 +557,20 @@
 	rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS,
 			"baud_base: %d\n", port->gs.baud_base);
 #ifdef MPC5xxx_PSC_DEBUG
-	if (rs_debug & MPC5xxx_PSC_DEBUG_TERMIOS)
-		out_8(&psc->command, MPC5xxx_PSC_SEL_MODE_REG_1);
+	if (rs_debug & MPC5xxx_PSC_DEBUG_TERMIOS) {
+		psc->command = MPC5xxx_PSC_SEL_MODE_REG_1;
+	}
 #endif
 	rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS,
 			"mode 1 register was: %08x, now: %08x\n",
-			in_8(&psc->mode), mode1);
+			psc->mode, mode1);
 	rs_dprintk(MPC5xxx_PSC_DEBUG_TERMIOS,
 			"mode 2 register was: %08x, now: %08x\n",
-			in_8(&psc->mode), mode2);
+			psc->mode, mode2);
 
-	out_8(&psc->command, MPC5xxx_PSC_SEL_MODE_REG_1);
-	out_8(&psc->mode, mode1);
-	out_8(&psc->mode, mode2);
+	psc->command = MPC5xxx_PSC_SEL_MODE_REG_1;
+	psc->mode = mode1;
+	psc->mode = mode2;
 
 	func_exit();
 	return 0;
@@ -539,7 +601,7 @@
 
 	line = minor(tty->device) - tty->driver.minor_start;
 	rs_dprintk(MPC5xxx_PSC_DEBUG_OPEN,
-			"%d: opening line %d. tty=%p ctty=%p)\n", 
+			"%d: opening line %d. tty=%p ctty=%p)\n",
 			(int) current->pid, line, tty, current->tty);
 
 	if ((line < 0) || (line >= RS_TABLE_SIZE))
@@ -728,7 +790,7 @@
 #endif
 
 	func_enter();
-	
+
 	if (I_IXOFF(tty)) {
 		if (port->x_char)
 			port->x_char = 0;
@@ -763,6 +825,7 @@
 static int rs_init_portstructs(void)
 {
 	struct rs_port *port;
+	struct mpc5xxx_psc *psc;
 	int i;
 #ifdef CONFIG_UBOOT
 	extern unsigned char __res[];
@@ -789,7 +852,7 @@
 	rs_driver.termios_locked = rs_termios_locked;
 
 	port = rs_ports;
-	for (i=0; i < MPC5xxx_PSC_NPORTS;i++) {
+	for (i = 0; i < MPC5xxx_PSC_NPORTS; i++) {
 		rs_dprintk(MPC5xxx_PSC_DEBUG_INIT, "initing port %d\n", i);
 		port->gs.callout_termios = tty_std_termios;
 		port->gs.normal_termios	= tty_std_termios;
@@ -813,6 +876,8 @@
 #endif
 		rs_dprintk(MPC5xxx_PSC_DEBUG_INIT, "psc base 0x%08lx\n",
 				(unsigned long)port->psc);
+		psc = port->psc;
+		psc->command = MPC5xxx_PSC_RST_ERR_STAT;
 		port++;
 	}
 
@@ -822,7 +887,9 @@
 
 static int rs_init_drivers(void)
 {
-	int error;
+	struct rs_port *port;
+	char proc_psc_name[8];
+	int i, error;
 
 	func_enter();
 
@@ -878,6 +945,19 @@
 		return 1;
 	}
 
+	/* Create /proc entries */
+	proc_psc_dir = proc_mkdir("driver/psc_mpc52xx", NULL);
+	if (proc_psc_dir != NULL) {
+		for (i=0; i < MPC5xxx_PSC_NPORTS; i++) {
+			sprintf(proc_psc_name, "ttyS%1d", i);
+			proc_psc[i] = create_proc_entry(proc_psc_name, 0444, proc_psc_dir);
+			proc_psc[i]->read_proc = sio_read_info;
+			proc_psc[i]->write_proc = NULL;
+			proc_psc[i]->data = &rs_ports[i];
+			proc_psc[i]->owner = THIS_MODULE;
+		}
+	}
+
 	func_exit();
 	return 0;
 }
@@ -888,6 +968,7 @@
 	int rc;
 	int i;
 	struct rs_port *port;
+	char name[6];
 
 	func_enter();
 	rs_dprintk(MPC5xxx_PSC_DEBUG_INIT,
@@ -896,20 +977,29 @@
 	rc = rs_init_portstructs();
 	rs_init_drivers();
 	port = rs_ports;
-	for (i=0; i < MPC5xxx_PSC_NPORTS;i++) {
-		rs_disable_rx_interrupts(port); 
-		rs_disable_tx_interrupts(port); 
+	for (i=0; i < MPC5xxx_PSC_NPORTS; i++) {
+		rs_disable_rx_interrupts(port);
+		rs_disable_tx_interrupts(port);
+		switch ((int) port->psc) {
+			case MPC5xxx_PSC1: { sprintf(name, "PSC1"); break; }
+			case MPC5xxx_PSC2: { sprintf(name, "PSC2"); break; }
+			case MPC5xxx_PSC3: { sprintf(name, "PSC3"); break; }
+			case MPC5xxx_PSC4: { sprintf(name, "PSC4"); break; }
+			case MPC5xxx_PSC5: { sprintf(name, "PSC5"); break; }
+			case MPC5xxx_PSC6: { sprintf(name, "PSC6"); break; }
+			default: { sprintf(name, "PSC?"); break; }
+		}
+
 		if (request_irq(port->irq, rs_interrupt,
 			SA_SHIRQ | SA_INTERRUPT, "serial", port)) {
-			printk(KERN_ERR
-				"rs: Cannot allocate irq for PSC%d.\n", i+1);
+			printk(KERN_ERR "rs: Cannot allocate irq for %s (ttyS%d).\n", name, i);
 			rc = 0;
 			continue;
 		}
 		rs_dprintk(MPC5xxx_PSC_DEBUG_INIT,
 				"requested irq for port[%d] = %08x\n",
 				i, (u32)port);
-		printk(KERN_INFO "ttyS%d on PSC%d\n", i, i+1);
+		printk(KERN_INFO "ttyS%d on %s\n", i, name);
 		port++;
 	}
 
@@ -940,25 +1030,27 @@
 	/*
 	 * Turn PSC interrupts off
 	 */
-	out_be16(&psc->mpc5xxx_psc_imr, 0);
+	psc->mpc5xxx_psc_imr = 0;
 
 	/*
 	 * Wait for the Tx register to become empty
 	 */
 	i = BUSY_WAIT;
-	while (!(in_be16(&psc->mpc5xxx_psc_status) & MPC5xxx_PSC_SR_TXEMP) &&
-			i--)
+	while (!(psc->mpc5xxx_psc_status & MPC5xxx_PSC_SR_TXEMP) && i--) {
 		udelay(1);
-	out_8(&psc->mpc5xxx_psc_buffer_8, c);
+	}
+
+	psc->mpc5xxx_psc_buffer_8 = c;
+
 	i = BUSY_WAIT;
-	while (!(in_be16(&psc->mpc5xxx_psc_status) & MPC5xxx_PSC_SR_TXEMP) &&
-			i--)
+	while (!(psc->mpc5xxx_psc_status & MPC5xxx_PSC_SR_TXEMP) && i--) {
 		udelay(1);
+	}
 
 	/*
 	 * Turn PSC interrupts back on
 	 */
-	out_be16(&psc->mpc5xxx_psc_imr, port->imr);
+	psc->mpc5xxx_psc_imr = port->imr;
 }
 
 static void serial_console_write(struct console *co, const char *s,
@@ -1050,17 +1142,14 @@
 		break;
 	}
 
-	out_8(&psc->command, MPC5xxx_PSC_RST_TX
-			| MPC5xxx_PSC_RX_DISABLE | MPC5xxx_PSC_TX_ENABLE);
-	out_8(&psc->command, MPC5xxx_PSC_RST_RX);
-
-	out_be32(&psc->sicr, 0x0);
-	out_be16(&psc->mpc5xxx_psc_clock_select, 0xdd00);
-	out_be16(&psc->tfalarm, 0xf8);
-
-	out_8(&psc->command, MPC5xxx_PSC_SEL_MODE_REG_1
-			| MPC5xxx_PSC_RX_ENABLE
-			| MPC5xxx_PSC_TX_ENABLE);
+	psc->command = MPC5xxx_PSC_RST_TX | MPC5xxx_PSC_RX_DISABLE | MPC5xxx_PSC_TX_ENABLE;
+	psc->command = MPC5xxx_PSC_RST_RX;
+
+	psc->sicr = 0x0;
+	psc->mpc5xxx_psc_clock_select = 0xdd00;
+	psc->tfalarm = 0xf8;
+
+	psc->command = MPC5xxx_PSC_SEL_MODE_REG_1 | MPC5xxx_PSC_RX_ENABLE | MPC5xxx_PSC_TX_ENABLE;
 
 #ifdef CONFIG_UBOOT
 	divisor = ((bd->bi_ipbfreq / (baud * 16)) + 1) >> 1;	/* round up */
@@ -1071,11 +1160,11 @@
 	mode1 = bits | parity | MPC5xxx_PSC_MODE_ERR;
 	mode2 = MPC5xxx_PSC_MODE_ONE_STOP;
 
-	out_8(&psc->ctur, divisor>>8);
-	out_8(&psc->ctlr, divisor);
-	out_8(&psc->command, MPC5xxx_PSC_SEL_MODE_REG_1);
-	out_8(&psc->mode, mode1);
-	out_8(&psc->mode, mode2);
+	psc->ctur = divisor >> 8;
+	psc->ctlr = divisor;
+	psc->command = MPC5xxx_PSC_SEL_MODE_REG_1;
+	psc->mode = mode1;
+	psc->mode = mode2;
 
 	return 0;
 }
@@ -1095,3 +1184,51 @@
 }
 
 #endif
+
+static int sio_read_info(char *buf, char **start, off_t offset, int count, int  *eof, void *data)
+{
+	struct rs_port *port;
+	struct mpc5xxx_psc *psc;
+	u16 nStat;
+	int len = 0;
+
+	port = (struct rs_port *) data;
+	psc = port->psc;
+	nStat = psc->mpc5xxx_psc_status;
+
+	switch ((int) psc) {
+		case MPC5xxx_PSC1: { len += sprintf(buf+len, "PSC1: "); break; }
+		case MPC5xxx_PSC2: { len += sprintf(buf+len, "PSC2: "); break; }
+		case MPC5xxx_PSC3: { len += sprintf(buf+len, "PSC3: "); break; }
+		case MPC5xxx_PSC4: { len += sprintf(buf+len, "PSC4: "); break; }
+		case MPC5xxx_PSC5: { len += sprintf(buf+len, "PSC5: "); break; }
+		case MPC5xxx_PSC6: { len += sprintf(buf+len, "PSC6: "); break; }
+		default: { len += sprintf(buf+len, "PSC?: "); break; }
+	}
+	len += sprintf(buf+len, "Baudrate=%d, ", port->baud);
+	len += sprintf(buf+len, "Flags=0x%04x, ", port->cflag);
+	len += sprintf(buf+len, "Status=0x%04x ", nStat);
+	len += sprintf(buf+len, "Irq=%d, ", port->irq);
+	len += sprintf(buf+len, "Base=0x%08x\n      ", port->psc);
+	len += sprintf(buf+len, "RB:%d, ",(nStat & MPC5xxx_PSC_SR_RB) ? 1 : 0);
+	len += sprintf(buf+len, "FE:%d, ",(nStat & MPC5xxx_PSC_SR_FE) ? 1 : 0);
+	len += sprintf(buf+len, "PE:%d, ",(nStat & MPC5xxx_PSC_SR_PE) ? 1 : 0);
+	len += sprintf(buf+len, "OR:%d, ",(nStat & MPC5xxx_PSC_SR_OE) ? 1 : 0);
+	len += sprintf(buf+len, "TxEMP:%d, ",(nStat & MPC5xxx_PSC_SR_TXEMP) ? 1 : 0);
+	len += sprintf(buf+len, "TxRDY:%d, ",(nStat & MPC5xxx_PSC_SR_TXRDY) ? 1 : 0);
+	len += sprintf(buf+len, "RXFULL:%d, ",(nStat & MPC5xxx_PSC_SR_RXFULL) ? 1 : 0);
+	len += sprintf(buf+len, "RxRDY:%d, ",(nStat & MPC5xxx_PSC_SR_RXRDY) ? 1 : 0);
+	len += sprintf(buf+len, "CDE:%d\n",(nStat & MPC5xxx_PSC_SR_CDE) ? 1 : 0);
+
+	if (len <= offset + count)
+		*eof = 1;
+	*start = buf + offset;
+	len -= offset;
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+

  reply	other threads:[~2006-02-02 18:43 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-10-11  6:55 MPC5200,PSC in uart mode, receiving problem Derycke, Johan
2005-10-11  7:18 ` Wolfgang Denk
2005-10-11  8:10   ` AW: " Achim Machura
2006-02-02 18:22     ` Frank Bodammer [this message]
  -- strict thread matches above, loose matches on Subject: below --
2005-10-10 11:37 Tomasz Prochownik
2005-10-10 13:13 ` AW: " Achim Machura

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=43E24DF7.5010304@hs.gcd-erlangen.de \
    --to=frank.bodammer@hs.gcd-erlangen.de \
    --cc=linuxppc-embedded@ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).