All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.