public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: fabrizio.gennari@philips.com
To: <linux-kernel@vger.kernel.org>
Subject: Patch for supporting CPR register in 16C950 UART
Date: Fri, 18 May 2001 18:14:23 +0200	[thread overview]
Message-ID: <0056900018047773000002L032*@MHS> (raw)

[-- Attachment #1: MEMO 05/18/01 18:00:46 --]
[-- Type: text/plain, Size: 909 bytes --]

Hello.

Here is a patch (tested on kernels 2.4.3 and 2.4.4) that adds 2 ioctl's in serial.c. One, TCSSERCPR, sets the CPR register in 16C950 UARTs. This register is a pre-scaler (that is, a divisor) for the clock. If the value is N, the clock is divided by N/8. 
If N<8, pre-scaling is disabled by setting bit 7 of MCR to 0. The other one, TCGSERCPR,, reads the value of CPR. If pre-scaling is disabled, it returns 8 (i.e., the clock frequency is left intact).

The patch also disables resetting the UART via the CSR register every time the serial device is opened (in the startup() function). This would reset the content of CPR.
---------------------------------------------------------
Fabrizio Gennari          tel. +39 039 203 7816
Philips Research Monza    fax. +39 039 203 7800
via G. Casati 23          fabrizio.gennari@philips.com
20052 Monza (MI) Italy    http://www.research.philips.com

[-- Attachment #2: serial-patch --]
[-- Type: application/octet-stream, Size: 3666 bytes --]

diff -ruN linux-2.4.3/drivers/char/serial.c linux-2.4.3-patched/drivers/char/serial.c
--- linux-2.4.3/drivers/char/serial.c	Wed Mar  7 05:13:51 2001
+++ linux-2.4.3-patched/drivers/char/serial.c	Fri May 18 16:28:30 2001
@@ -1259,7 +1259,7 @@
 		serial_outp(info, UART_EFR, UART_EFR_ECB);
 		serial_outp(info, UART_IER, 0);
 		serial_outp(info, UART_LCR, 0);
-		serial_icr_write(info, UART_CSR, 0); /* Reset the UART */
+		/*		serial_icr_write(info, UART_CSR, 0); */ /* Reset the UART */
 		serial_outp(info, UART_LCR, 0xBF);
 		serial_outp(info, UART_EFR, UART_EFR_ECB);
 		serial_outp(info, UART_LCR, 0);
@@ -1364,9 +1364,12 @@
 	 */
 	serial_outp(info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
 
-	info->MCR = 0;
+	if (state->type == PORT_16C950)
+		info->MCR &= UART_MCR_PRESCALER;
+	else
+		info->MCR = 0;
 	if (info->tty->termios->c_cflag & CBAUD)
-		info->MCR = UART_MCR_DTR | UART_MCR_RTS;
+		info->MCR |= UART_MCR_DTR | UART_MCR_RTS;
 #ifdef CONFIG_SERIAL_MANY_PORTS
 	if (info->flags & ASYNC_FOURPORT) {
 		if (state->irq == 0)
@@ -2514,6 +2517,41 @@
 }
 #endif
 
+static int get_clock_prescaler(struct async_struct * info, unsigned char *value)
+{
+	unsigned char cpr;
+
+	if (!(serial_in(info, UART_MCR) & UART_MCR_PRESCALER))
+		cpr = 8;
+	else
+		cpr = serial_icr_read(info, UART_CPR);
+
+	if (copy_to_user(value,&cpr,sizeof(unsigned char)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int set_clock_prescaler(struct async_struct * info, unsigned char *value)
+{
+	unsigned char cpr;
+	
+	if (copy_from_user(&cpr,value,sizeof(unsigned char)))
+		return -EFAULT;
+
+	if (cpr < 8){
+		info->MCR &= ~UART_MCR_PRESCALER;
+	}
+	else{
+		info->MCR |= UART_MCR_PRESCALER;
+	}
+	
+	serial_out(info, UART_MCR, info->MCR);
+	serial_icr_write(info, UART_CPR, cpr);
+
+	return 0;
+}
+
 static int rs_ioctl(struct tty_struct *tty, struct file * file,
 		    unsigned int cmd, unsigned long arg)
 {
@@ -2668,6 +2706,14 @@
 			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
 				return -EFAULT;
 			return 0;
+		case TIOCGSERCPR: /* Get serial clock prescaler */
+			if (info->state->type == PORT_16C950)
+				return get_clock_prescaler(info, (unsigned char *) arg);
+			return -ENXIO;
+		case TIOCSSERCPR: /* Set serial clock prescaler */
+			if (info->state->type == PORT_16C950)
+				return set_clock_prescaler(info, (unsigned char *) arg);
+			return -ENXIO;
 		case TIOCSERGWILD:
 		case TIOCSERSWILD:
 			/* "setserial -W" is called in Debian boot */
diff -ruN linux-2.4.3/include/asm-i386/ioctls.h linux-2.4.3-patched/include/asm-i386/ioctls.h
--- linux-2.4.3/include/asm-i386/ioctls.h	Fri Jul 24 20:10:16 1998
+++ linux-2.4.3-patched/include/asm-i386/ioctls.h	Thu May 17 16:34:08 2001
@@ -67,6 +67,8 @@
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 #define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+#define TIOCGSERCPR   0x5460  /* Get serial clock prescaler*/
+#define TIOCSSERCPR   0x5461  /* Set serial clock prescaler*/
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -ruN linux-2.4.3/include/linux/serial_reg.h linux-2.4.3-patched/include/linux/serial_reg.h
--- linux-2.4.3/include/linux/serial_reg.h	Wed Mar  7 04:28:35 2001
+++ linux-2.4.3-patched/include/linux/serial_reg.h	Thu May 17 16:23:32 2001
@@ -121,6 +121,7 @@
 /*
  * These are the definitions for the Modem Control Register
  */
+#define UART_MCR_PRESCALER	0x80	/* Enable clock prescaler */
 #define UART_MCR_LOOP	0x10	/* Enable loopback test mode */
 #define UART_MCR_OUT2	0x08	/* Out2 complement */
 #define UART_MCR_OUT1	0x04	/* Out1 complement */

                 reply	other threads:[~2001-05-18 16:02 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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='0056900018047773000002L032*@MHS' \
    --to=fabrizio.gennari@philips.com \
    --cc=linux-kernel@vger.kernel.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