summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch155
1 files changed, 155 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch
new file mode 100644
index 0000000000..b513ba1466
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch
@@ -0,0 +1,155 @@
1
2From: Petr Vandrovec <vandrove@vc.cvut.cz>
3
4Patch below adds support for using different prescaler than 16 for 16c950
5chips. This is needed for using Fujitsu-Siemens Connect2Air compact-flash
6card, which comes (apparently) with 806kHz clocks, and so you have to
7program prescaler for division by 7, and DLAB to 1, to get 115200Bd.
8
9To get card properly running you also have to add lines below to
10/etc/pcmcia/serial.opts so kernel knows that base speed is not 115200 but
1150400 (50400 * 16 = 806400; 806400 / 7 = 115200). As I've found no code
12specifying baud_rate in serial_cs, I assume that specifying it in
13serial.opts is right way to do this type of things.
14
15Patch also fixes problem that for UPF_MAGIC_MULTIPLIER maximum possible
16baud rate passed to uart code was uartclk / 16 while correct value for
17these devices (and for 16c950) is uartclk / 4.
18
19Patch also fixes problem that for UPF_MAGIC_MULTIPLIER devices with
20baud_rate 19200 or 9600 spd_cust did not work correctly. Not that such
21devices exist, but we should not ignore spd_cust, user probably knows why
22he asked for spd_cust.
23
24serial.opts:
25
26case "$MANFID-$FUNCID-$PRODID_1-$PRODID_2-$PRODID_3-$PRODID_4" in
27'0279,950b-2-GPRS Modem---')
28 SERIAL_OPTS="baud_base 50400"
29 ;;
30esac
31
32Cc: David Woodhouse <dwmw2@infradead.org>
33Signed-off-by: Andrew Morton <akpm@osdl.org>
34---
35
36 drivers/serial/8250.c | 82 +++++++++++++++++++++++++++++++++++++++-----------
37 1 file changed, 64 insertions(+), 18 deletions(-)
38
39Index: linux-2.6.21/drivers/serial/8250.c
40===================================================================
41--- linux-2.6.21.orig/drivers/serial/8250.c 2007-07-01 16:59:52.000000000 +0100
42+++ linux-2.6.21/drivers/serial/8250.c 2007-07-01 17:01:21.000000000 +0100
43@@ -1964,24 +1964,58 @@ static void serial8250_shutdown(struct u
44 serial_unlink_irq_chain(up);
45 }
46
47-static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
48+static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud,
49+ unsigned int *prescaler)
50 {
51- unsigned int quot;
52-
53- /*
54- * Handle magic divisors for baud rates above baud_base on
55- * SMSC SuperIO chips.
56+ /*
57+ * Use special handling only if user did not supply its own divider.
58+ * spd_cust is defined in terms of baud_base, so always use default
59+ * prescaler when spd_cust is requested.
60 */
61- if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
62- baud == (port->uartclk/4))
63- quot = 0x8001;
64- else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
65- baud == (port->uartclk/8))
66- quot = 0x8002;
67- else
68- quot = uart_get_divisor(port, baud);
69
70- return quot;
71+ *prescaler = 16;
72+ if (baud != 38400 || (port->flags & UPF_SPD_MASK) != UPF_SPD_CUST) {
73+ unsigned int quot = port->uartclk / baud;
74+
75+ /*
76+ * Handle magic divisors for baud rates above baud_base on
77+ * SMSC SuperIO chips.
78+ */
79+ if (port->flags & UPF_MAGIC_MULTIPLIER) {
80+ if (quot == 4) {
81+ return 0x8001;
82+ } else if (quot == 8) {
83+ return 0x8002;
84+ }
85+ }
86+ if (port->type == PORT_16C950) {
87+ /*
88+ * This computes TCR value (4 to 16), not CPR value (which can
89+ * be between 1.000 and 31.875) - chip I have uses XTAL of
90+ * 806400Hz, and so a division by 7 is required to get 115200Bd.
91+ * I'm leaving CPR disabled for now, until someone will
92+ * hit even more exotic XTAL (it is needed to get 500kbps
93+ * or 1000kbps from 18.432MHz XTAL, but I have no device
94+ * which would benefit from doing that).
95+ *
96+ * If we can use divide by 16, use it. Otherwise look for
97+ * better prescaler, from 15 to 4. If quotient cannot
98+ * be divided by any integer value between 4 and 15, use 4.
99+ */
100+ if (quot & 0x0F) {
101+ unsigned int div;
102+
103+ for (div = 15; div > 4; div--) {
104+ if (quot % div == 0) {
105+ break;
106+ }
107+ }
108+ *prescaler = div;
109+ return quot / div;
110+ }
111+ }
112+ }
113+ return uart_get_divisor(port, baud);
114 }
115
116 static void
117@@ -1991,7 +2025,7 @@ serial8250_set_termios(struct uart_port
118 struct uart_8250_port *up = (struct uart_8250_port *)port;
119 unsigned char cval, fcr = 0;
120 unsigned long flags;
121- unsigned int baud, quot;
122+ unsigned int baud, quot, prescaler;
123
124 switch (termios->c_cflag & CSIZE) {
125 case CS5:
126@@ -2023,8 +2057,13 @@ serial8250_set_termios(struct uart_port
127 /*
128 * Ask the core to calculate the divisor for us.
129 */
130- baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
131- quot = serial8250_get_divisor(port, baud);
132+ if (port->type == PORT_16C950 || (port->flags & UPF_MAGIC_MULTIPLIER)) {
133+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/4);
134+ } else {
135+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
136+ }
137+ quot = serial8250_get_divisor(port, baud, &prescaler);
138+
139
140 /*
141 * Oxford Semi 952 rev B workaround
142@@ -2139,6 +2178,13 @@ serial8250_set_termios(struct uart_port
143 serial_dl_write(up, quot);
144
145 /*
146+ * Program prescaler for 16C950 chips.
147+ */
148+ if (up->port.type == PORT_16C950) {
149+ serial_icr_write(up, UART_TCR, prescaler == 16 ? 0 : prescaler);
150+ }
151+
152+ /*
153 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
154 * is written without DLAB set, this mode will be disabled.
155 */