linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Steffen Rumler <Steffen.Rumler@siemens.com>
To: linuxppc <linuxppc-embedded@ozlabs.org>
Subject: uart.c: avoid changing parameter RAM on-the-fly for the console
Date: Thu, 03 Feb 2005 16:17:30 +0100	[thread overview]
Message-ID: <4202408A.7050200@siemens.com> (raw)

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

Hi,

We are using the 2.4.20 PPC kernel running on the TQM859T module.

A lot of this kind of modules always hangs during the boot,
something like this:

      Linux version 2.4.20-rthal5 (ru@styx) (gcc version 2.95.3 20010111 (prerelease/franzo/20010111))
      #31 Thu Feb 3 15:07:0
      1 CET 2005
      On node 0 totalpages: 8128
      zone(0): 8128 pages.
      zone(1): 0 pages.
      zone(2): 0 pages.
      ...
      CPM UART driver version 0.03+
      ttyS00 at 0x0280 is a SMC
                           ^^^^^
                             THE SYSTEM HANGS HERE :-(

Deeper inspecting the uart.c, we recognized that the SMC (or SCC)
hardware related to the console will be (re-)configured multiple times in:

    (1) serial_console_setup():  early setup with small BD tables

    (2) rs_8xx_init(): bigger BD tables; without interrupts

    (3) startup(): with interrupts

The re-configuring (1->2, 2->3) will be performed on-the-fly,
without disabling the hardware.

According to Motorola this is _NOT_ allowed and dangerous.

For the SMC, it is suggested to run a 'STOP TX' CPCR command followed
by disabling RX/TX in SMCMR (TEN/REN), in order to stop the controller
correctly.

I suggest to do this inside rs_8xx_init() and startup() as shown
in the patch below.
The SCC is not addressed by the patch.

With this fix, the modules hanging before can boot now.


Steffen

--







[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 2472 bytes --]

diff -Naur old/arch/ppc/8xx_io/uart.c new/arch/ppc/8xx_io/uart.c
--- old/arch/ppc/8xx_io/uart.c	Thu Feb  3 15:54:21 2005
+++ new/arch/ppc/8xx_io/uart.c	Thu Feb  3 15:52:44 2005
@@ -119,6 +119,10 @@
 static int  uart_buf_read_proc    (char *, char **, off_t, int, int *, void *);
 #endif
 
+#ifdef CONFIG_SERIAL_CONSOLE
+static void full_seq_smc_stop (int port);
+#endif
+
 /*
  * Serial driver configuration section.  Here are the various options:
  */
@@ -831,10 +835,17 @@
 	else {
 		smcp = &cpmp->cp_smc[idx];
 
+#ifdef CONFIG_SERIAL_CONSOLE
+                /*  stop SMC in the correct way, before re-configuring it
+                 */
+		if (((state - rs_table) == CONFIG_SERIAL_CONSOLE_PORT)){
+                    full_seq_smc_stop(PORT_NUM(info->state->smc_scc_num));
+                }
+#endif
+
 		/* Enable interrupts and I/O.
 		*/
 		smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
-		smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
 
 		/* We can tune the buffer length and idle characters
 		 * to take advantage of the entire incoming buffer size.
@@ -848,6 +859,8 @@
 		up->smc_mrblr = RX_BUF_SIZE;
 		up->smc_maxidl = RX_BUF_SIZE;
 		up->smc_brkcr = 1;	/* number of break chars */
+
+		smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
 	}
 
 	info->flags |= ASYNC_INITIALIZED;
@@ -2694,6 +2707,30 @@
   
 } /* end uart_removeProcEntries() */
 
+
+#ifdef CONFIG_SERIAL_CONSOLE
+static void full_seq_smc_stop (int port)
+{
+    volatile cpm8xx_t *cp=cpmp;
+    volatile smc_t *sp;
+    ushort chan;
+    unsigned long flags;
+
+    sp   = &cp->cp_smc[port];
+    chan = smc_chan_map[port];
+
+    local_irq_save(flags);
+
+    while (cp->cp_cpcr & CPM_CR_FLG);
+    cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG;
+    while (cp->cp_cpcr & CPM_CR_FLG);
+    sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+    local_irq_restore(flags);
+
+}  /* full_seq_smc_stop */ 
+#endif  /* CONFIG_SERIAL_CONSOLE */
+
 /*
  * The serial driver boot-time initialization code!
  */
@@ -2905,6 +2942,15 @@
 			}
 			else {
 				sp = &cp->cp_smc[idx];
+
+#ifdef CONFIG_SERIAL_CONSOLE
+                                /*  stop SMC in the correct way, before re-configuring it
+                                 */
+                                if (i == CONFIG_SERIAL_CONSOLE_PORT){
+                                    full_seq_smc_stop(idx);
+                                }
+#endif
+
 				up = (smc_uart_t *)&cp->cp_dparam[state->port];
 				up->smc_rbase = dp_addr;
 			}

             reply	other threads:[~2005-02-03 15:17 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-03 15:17 Steffen Rumler [this message]
2005-02-03 15:43 ` uart.c: avoid changing parameter RAM on-the-fly for the console Dan Malek
2005-02-04  8:55   ` Steffen Rumler
2005-02-16  9:56   ` Steffen Rumler

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=4202408A.7050200@siemens.com \
    --to=steffen.rumler@siemens.com \
    --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).