lkml.org 
[lkml]   [2001]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectRe: Kernel booting on serial console ... crawling
Date
Hi Robert,

Am Freitag, 9. November 2001 13:27 schrieben Sie:
> On Fri, 9 Nov 2001, Robert Kaiser wrote:
> > Is this an AMD Elan's built-in serial port, perchance ?
>
> I got a patch for the Elan's serial port from Jason Sodergren some days
> ago, but it's not clear to me what exactly the problem is with this port.
> I'm using the serial console on a DIL/Net-PC without any problems so far.
> Perhaps it might be a good idea to join forces and try to get a patch for
> the Elan series into the main kernel?
>
> However, my current affords can be found on
>
> http://www.schwebel.de/software/dnp/index_en.html
>
> This currently implements a new CPU configuration parameter and a fix for
> the clock on the Elan CPUs.

This is interesting, I was not aware of the different clock frequency issue.

Anyway, the patch I am using to fix the crawling console output symptom on
the Elan is entirely different (see attachment). It was originally posted by
Anders Larsen <a.larsen@identecsolutions.de> and we have been using
it with good success in our embedded Linux product for quite a while now.
The comments in the source describe the problem. Interestingly, even the
latest AMD Elan product (SC520) seems to have this problem too.

Rob

----------------------------------------------------------------
Robert Kaiser email: rkaiser@sysgo.de
SYSGO RTS GmbH
Am Pfaffenstein 14 phone: (49) 6136 9948-762
D-55270 Klein-Winternheim / Germany fax: (49) 6136 9948-10
Index: sysgo/elinos/linux/drivers/char/serial.c
diff -c sysgo/elinos/linux/drivers/char/serial.c:1.2 sysgo/elinos/linux/drivers/char/serial.c:1.3
*** sysgo/elinos/linux/drivers/char/serial.c:1.2 Wed May 17 14:07:00 2000
--- sysgo/elinos/linux/drivers/char/serial.c Wed Jun 7 15:19:53 2000
***************
*** 607,612 ****
--- 607,613 ----
int status;
struct async_struct * info;
int pass_counter = 0;
+ int iir;
struct async_struct *end_mark = 0;
#ifdef CONFIG_SERIAL_MULTIPORT
int first_multi = 0;
***************
*** 627,635 ****
first_multi = inb(multi->port_monitor);
#endif

do {
if (!info->tty ||
! (serial_in(info, UART_IIR) & UART_IIR_NO_INT)) {
if (!end_mark)
end_mark = info;
goto next;
--- 628,637 ----
first_multi = inb(multi->port_monitor);
#endif

+ iir = serial_in(info, UART_IIR);
do {
if (!info->tty ||
! ((iir = serial_in(info, UART_IIR)) & UART_IIR_NO_INT)) {
if (!end_mark)
end_mark = info;
goto next;
***************
*** 645,650 ****
--- 647,663 ----
if (status & UART_LSR_DR)
receive_chars(info, &status);
check_modem_status(info);
+ #ifdef CONFIG_AMD_ELAN
+ /*
+ ** There is a bug (misfeature?) in the UART on the AMD Elan
+ ** SC4x0 and SC520 embedded processor series; the THRE bit of
+ ** the line status register seems to be delayed one bit
+ ** clock after the interrupt is generated, so kludge this
+ ** if the IIR indicates a Transmit Holding Register Interrupt
+ */
+ if ((iir & UART_IIR_ID) == UART_IIR_THRI)
+ status |= UART_LSR_THRE;
+ #endif
if (status & UART_LSR_THRE)
transmit_chars(info, 0);

***************
*** 679,685 ****
*/
static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
{
! int status;
int pass_counter = 0;
struct async_struct * info;
#ifdef CONFIG_SERIAL_MULTIPORT
--- 692,698 ----
*/
static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
{
! int status, iir;
int pass_counter = 0;
struct async_struct * info;
#ifdef CONFIG_SERIAL_MULTIPORT
***************
*** 701,706 ****
--- 714,720 ----
first_multi = inb(multi->port_monitor);
#endif

+ iir = serial_in(info, UART_IIR);
do {
status = serial_inp(info, UART_LSR);
#ifdef SERIAL_DEBUG_INTR
***************
*** 709,714 ****
--- 723,739 ----
if (status & UART_LSR_DR)
receive_chars(info, &status);
check_modem_status(info);
+ #ifdef CONFIG_AMD_ELAN
+ /*
+ ** There is a bug (misfeature?) in the UART on the AMD Elan
+ ** SC4x0 and SC520 embedded processor series; the THRE bit of
+ ** the line status register seems to be delayed one bit
+ ** clock after the interrupt is generated, so kludge this
+ ** if the IIR indicates a Transmit Holding Register Interrupt
+ */
+ if ((iir & UART_IIR_ID) == UART_IIR_THRI)
+ status |= UART_LSR_THRE;
+ #endif
if (status & UART_LSR_THRE)
transmit_chars(info, 0);
if (pass_counter++ > RS_ISR_PASS_LIMIT) {
***************
*** 717,723 ****
#endif
break;
}
! } while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT));
info->last_active = jiffies;
#ifdef CONFIG_SERIAL_MULTIPORT
if (multi->port_monitor)
--- 742,748 ----
#endif
break;
}
! } while (!((iir = serial_in(info, UART_IIR)) & UART_IIR_NO_INT));
info->last_active = jiffies;
#ifdef CONFIG_SERIAL_MULTIPORT
if (multi->port_monitor)
\
 
 \ /
  Last update: 2005-03-22 13:13    [W:0.041 / U:0.600 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site