From fbuihuu@gmail.com Sat Dec  1 21:13:30 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 01 Dec 2007 21:13:38 +0000 (GMT)
Received: from nf-out-0910.google.com ([64.233.182.191]:46018 "EHLO
	nf-out-0910.google.com") by ftp.linux-mips.org with ESMTP
	id S20025949AbXLAVNa (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Sat, 1 Dec 2007 21:13:30 +0000
Received: by nf-out-0910.google.com with SMTP id c10so2240681nfd
        for <linux-mips@linux-mips.org>; Sat, 01 Dec 2007 13:13:29 -0800 (PST)
DKIM-Signature:	v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:from:to:cc:subject:date:message-id:x-mailer;
        bh=gM3lwe+Nj1yr/1VlODck0P6qaeKvLRMgCeqtuEi5tBc=;
        b=fsdiol9sKTTx5RNXDGhh3vfEDc6Tev9mfq9WCIUUwdAAMMPMcoMYZ58ApkTWPribRHJpa3eytgS7xvd/3uu+02F360+CuQo8sSBbfRi9rsKALo+LvhFqETi3cOmL5v56nESnA93Gm7QbiHeKnw0ULZlWpiAxY+8BHUEwldbMgxA=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=received:from:to:cc:subject:date:message-id:x-mailer;
        b=OfUmBMrXh5dDVlDpVWAd7p3WcN9Nljrg2y01yKqYhTJvWtOy4qN0/GGyKeH1uNEKuiSfngsMyNrISy7tH3w+9+UBCr2RzAVAdRlukyo3GZWzDtivaytbM8jXRAmHphCBkGFrsHIs4KQ4irDZU+VJGqL0qWx2QOl9jQTZbk4AND8=
Received: by 10.78.131.8 with SMTP id e8mr4514560hud.1196543609381;
        Sat, 01 Dec 2007 13:13:29 -0800 (PST)
Received: from localhost ( [82.235.205.153])
        by mx.google.com with ESMTPS id y2sm20915525mug.2007.12.01.13.13.27
        (version=TLSv1/SSLv3 cipher=OTHER);
        Sat, 01 Dec 2007 13:13:28 -0800 (PST)
From:	Franck Bui-Huu <fbuihuu@gmail.com>
To:	linux-arch@vger.kernel.org
Cc:	macro@linux-mips.org, linux-mips@linux-mips.org
Subject: [RFC] Yet another __init annotation: __initbss
Date:	Sat,  1 Dec 2007 22:13:04 +0100
Message-Id: <1196543586-6698-1-git-send-email-fbuihuu@gmail.com>
X-Mailer: git-send-email 1.5.3.5
Return-Path: <fbuihuu@gmail.com>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17652
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: fbuihuu@gmail.com
Precedence: bulk
X-list: linux-mips

Hi,

Currently, there's no way to make a data part of both the init section
and the bss section. Therefore uninitialized init data consume useless
space in the vmlinux image.

Most of these data can be listed by:

     $ git grep -E "__initdata([^=]*| ?= ?0);" -- *.c

This short patchset is an attempt to make these init data part of the
bss section (done by patch #1) and therefore decreases the size of the
vmlinux image.

For now, only MIPS architecture handles this new section, this is done
by patch #2. It's only a start and should be enough for discussion.

Please consider,

                Franck



From fbuihuu@gmail.com Sat Dec  1 21:13:59 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 01 Dec 2007 21:14:07 +0000 (GMT)
Received: from mu-out-0910.google.com ([209.85.134.185]:1449 "EHLO
	mu-out-0910.google.com") by ftp.linux-mips.org with ESMTP
	id S20025982AbXLAVNe (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Sat, 1 Dec 2007 21:13:34 +0000
Received: by mu-out-0910.google.com with SMTP id g7so1556288muf
        for <linux-mips@linux-mips.org>; Sat, 01 Dec 2007 13:13:33 -0800 (PST)
DKIM-Signature:	v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references;
        bh=xlZi7R9X35y9cLmby02SPm62fCqBFY/yrZaPe67uqzY=;
        b=uOpK7vHSaZ+FPEUTbYoIeBmOybPxl++rocEB99go1qB8rnjHnmpODY+lNzRrM5Y/lqvX9DVPstgWxwVieArlNaRM9hLEBVZ84NpxZXta0/Ijy6jEASQdEfRlNpSvP1c+jpsOpcoedq3C118j4yo8eNTYPb37EfIerAYAHQjDn8M=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references;
        b=kpVHqkRiin6wU27V1Bd/cuEqVc/RxQecahTki6sGxyjNlhu+UmnGKb95+thovVp92jwW3RhLOg1+yyD4htKdHSQ8GKY6bZIAhHAybLmUKFm9tz4NplN7kH6gWBz+t3CI4HcXt5ztPNQsVm/9ierOEylR8GaHPvBjM2xVcVLRgho=
Received: by 10.86.100.7 with SMTP id x7mr8724082fgb.1196543612441;
        Sat, 01 Dec 2007 13:13:32 -0800 (PST)
Received: from localhost ( [82.235.205.153])
        by mx.google.com with ESMTPS id p9sm11677479fkb.2007.12.01.13.13.30
        (version=TLSv1/SSLv3 cipher=OTHER);
        Sat, 01 Dec 2007 13:13:31 -0800 (PST)
From:	Franck Bui-Huu <fbuihuu@gmail.com>
To:	linux-arch@vger.kernel.org
Cc:	macro@linux-mips.org, linux-mips@linux-mips.org
Subject: [PATCH 1/2] Yet another __initxxx annotations: __initbss/__exitbss
Date:	Sat,  1 Dec 2007 22:13:05 +0100
Message-Id: <1196543586-6698-2-git-send-email-fbuihuu@gmail.com>
X-Mailer: git-send-email 1.5.3.5
In-Reply-To: <1196543586-6698-1-git-send-email-fbuihuu@gmail.com>
References: <1196543586-6698-1-git-send-email-fbuihuu@gmail.com>
Return-Path: <fbuihuu@gmail.com>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17653
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: fbuihuu@gmail.com
Precedence: bulk
X-list: linux-mips

Currently we can mark an initialized data to belong to the init.data
section, this data being discarded after the boot process and the
memory space used is taken back by the kernel. For _uninitialized_
data, we must use the same mechanism.

The main drawback of this is that these data take space in the kernel
image whereas this space is not really used. It's actually the reason
why we prefer to not initialize a normal data when its initial value
is 0.

This patch creates two new init sections called '.bss.init' and
'.bss.exit'.

These sections are similar to the .{init,exit}.data ones but doesn't
consume any space in the vmlinux image because they're part of the bss
section except that they're freed once the kernel has booted.

To select the BSS attribute for a peculiar section, the name of the
section must start with 'bss.' pattern. This is at least how GCC
3.2/4.1.2 works and it's the reason why the 2 new sections haven't
been called '.{init,exit}.bss'.

To mark a data part of one of these 2 sections, we use the 2 new
annotations: __initbss/__exitbss.

All data marked as part of this section must not be initialized,
of course.

Signed-off-by: Franck Bui-Huu <fbuihuu@gmail.com>
---
 include/linux/init.h |   25 +++++++++++++++++--------
 1 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/linux/init.h b/include/linux/init.h
index 5141381..19e04b2 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -43,6 +43,8 @@
 #define __init		__attribute__ ((__section__ (".init.text"))) __cold
 #define __initdata	__attribute__ ((__section__ (".init.data")))
 #define __exitdata	__attribute__ ((__section__(".exit.data")))
+#define __initbss	__attribute__ ((__section__ (".bss.init")))
+#define __exitbss	__attribute__ ((__section__ (".bss.exit")))
 #define __exit_call	__attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
 
 /* modpost check for section mismatches during the kernel build.
@@ -71,6 +73,7 @@
 #define __FINIT		.previous
 #define __INITDATA	.section	".init.data","aw"
 #define __INITDATA_REFOK .section	".data.init.refok","aw"
+#define __INITBSS	.section	".bss.init","aw",@nobits
 
 #ifndef __ASSEMBLY__
 /*
@@ -260,10 +263,12 @@ void __init parse_early_param(void);
 #define __devexit
 #define __devexitdata
 #else
-#define __devinit __init
-#define __devinitdata __initdata
-#define __devexit __exit
-#define __devexitdata __exitdata
+#define __devinit	__init
+#define __devinitdata	__initdata
+#define __devinitbss	__initbss
+#define __devexit	__exit
+#define __devexitdata	__exitdata
+#define __devexitbss	__exitbss
 #endif
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -273,9 +278,11 @@ void __init parse_early_param(void);
 #define __cpuexitdata
 #else
 #define __cpuinit	__init
-#define __cpuinitdata __initdata
-#define __cpuexit __exit
+#define __cpuinitdata	__initdata
+#define __cpuinitbss	__initbss
+#define __cpuexit	__exit
 #define __cpuexitdata	__exitdata
+#define __cpuexitbss	__exitbss
 #endif
 
 #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \
@@ -286,9 +293,11 @@ void __init parse_early_param(void);
 #define __memexitdata
 #else
 #define __meminit	__init
-#define __meminitdata __initdata
-#define __memexit __exit
+#define __meminitdata	__initdata
+#define __meminitbss	__meminitbss
+#define __memexit	__exit
 #define __memexitdata	__exitdata
+#define __memexitbss	__exitbss
 #endif
 
 /* Functions marked as __devexit may be discarded at kernel link time, depending
-- 
1.5.3.5


From fbuihuu@gmail.com Sat Dec  1 21:14:27 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 01 Dec 2007 21:14:37 +0000 (GMT)
Received: from mu-out-0910.google.com ([209.85.134.184]:42665 "EHLO
	mu-out-0910.google.com") by ftp.linux-mips.org with ESMTP
	id S20025999AbXLAVNh (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Sat, 1 Dec 2007 21:13:37 +0000
Received: by mu-out-0910.google.com with SMTP id g7so1556351muf
        for <linux-mips@linux-mips.org>; Sat, 01 Dec 2007 13:13:36 -0800 (PST)
DKIM-Signature:	v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references;
        bh=VoR5l8cqb6l44ze3jC00m6EsJ+7Hr4kjBiio300nvdA=;
        b=t3Y5tu+Mco9zBdrGwSLMhldk5nDZFoznR8numhYl8Ip35dGE8PIWXRg+95FMgxs2npsyQp3JLINi1xMVMt4+XrdCIWWwA9Y8QoFBBSNIvnNFPav+309gs9FjazhJCT0SklR6SFpsJSBeW8DK37shuyYY5ISpGsCY6sLcQEEwDCs=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references;
        b=dyieupMvVkLEIzG7X/PmfWslcTqjqcfdTZyecPW9OkCMbzlwZtv9GZTWlHq5ZydxWfXNxRGgkEZyJtjQ6Q725SndQ3AFJq7Hjnw+lIMNvJRapKAq4b3G9Q6V+QnMr+rWTvnYvgR1fEh7hUoU2SHZDuveGlARG0oIRtRLg8maPZo=
Received: by 10.86.1.1 with SMTP id 1mr8773799fga.1196543615833;
        Sat, 01 Dec 2007 13:13:35 -0800 (PST)
Received: from localhost ( [82.235.205.153])
        by mx.google.com with ESMTPS id l12sm5003187fgb.2007.12.01.13.13.34
        (version=TLSv1/SSLv3 cipher=OTHER);
        Sat, 01 Dec 2007 13:13:34 -0800 (PST)
From:	Franck Bui-Huu <fbuihuu@gmail.com>
To:	linux-arch@vger.kernel.org
Cc:	macro@linux-mips.org, linux-mips@linux-mips.org
Subject: [PATCH 2/2] MIPS: vmlinux.lds.S: handle .{init,exit}.bss sections
Date:	Sat,  1 Dec 2007 22:13:06 +0100
Message-Id: <1196543586-6698-3-git-send-email-fbuihuu@gmail.com>
X-Mailer: git-send-email 1.5.3.5
In-Reply-To: <1196543586-6698-1-git-send-email-fbuihuu@gmail.com>
References: <1196543586-6698-1-git-send-email-fbuihuu@gmail.com>
Return-Path: <fbuihuu@gmail.com>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17654
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: fbuihuu@gmail.com
Precedence: bulk
X-list: linux-mips

Signed-off-by: Franck Bui-Huu <fbuihuu@gmail.com>
---
 arch/mips/kernel/vmlinux.lds.S |   21 ++++++++++++++++-----
 1 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 5fc2398..8508d3c 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -110,7 +110,7 @@ SECTIONS
 	_edata =  .;			/* End of data section */
 
 	/* will be freed after init */
-	. = ALIGN(_PAGE_SIZE);		/* Init code and data */
+	. = ALIGN(_PAGE_SIZE);		/* Init code, data and bss */
 	__init_begin = .;
 	.init.text : {
 		_sinittext = .;
@@ -158,12 +158,23 @@ SECTIONS
 	}
 #endif
 	PERCPU(_PAGE_SIZE)
-	. = ALIGN(_PAGE_SIZE);
-	__init_end = .;
-	/* freed after init ends here */
 
+	/*
+	 * We keep init/exit bss sections here to have only one
+	 * segment to load. Note that .bss.exit is also discarded
+	 * at runtime for the same reason as above.
+	 */
+	.exit.bss : {
+		*(.bss.exit)
+	}
 	__bss_start = .;	/* BSS */
-	.sbss  : {
+	.init.bss : {
+		*(.bss.init)
+	}
+	. = ALIGN(_PAGE_SIZE);
+	__init_end = .;		/* freed after init ends here */
+
+	.sbss : {
 		*(.sbss)
 		*(.scommon)
 	}
-- 
1.5.3.5


From jgarzik@pobox.com Sat Dec  1 21:57:28 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 01 Dec 2007 21:57:37 +0000 (GMT)
Received: from srv5.dvmed.net ([207.36.208.214]:22407 "EHLO mail.dvmed.net")
	by ftp.linux-mips.org with ESMTP id S20026116AbXLAV5V (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Sat, 1 Dec 2007 21:57:21 +0000
Received: from cpe-069-134-071-233.nc.res.rr.com ([69.134.71.233] helo=core.yyz.us)
	by mail.dvmed.net with esmtpsa (Exim 4.63 #1 (Red Hat Linux))
	id 1IyaKm-0001AY-Q8; Sat, 01 Dec 2007 21:57:13 +0000
Message-ID: <4751D8B7.1060508@pobox.com>
Date:	Sat, 01 Dec 2007 16:57:11 -0500
From:	Jeff Garzik <jgarzik@pobox.com>
User-Agent: Thunderbird 2.0.0.9 (X11/20071115)
MIME-Version: 1.0
To:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
CC:	netdev@vger.kernel.org, linux-mips@linux-mips.org,
	ralf@linux-mips.org
Subject: Re: [PATCH] SGISEEQ: use cached memory access to make driver work
 on IP28
References: <20071126223934.84BE7C2B26@solo.franken.de>
In-Reply-To: <20071126223934.84BE7C2B26@solo.franken.de>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Return-Path: <jgarzik@pobox.com>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17655
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: jgarzik@pobox.com
Precedence: bulk
X-list: linux-mips

Thomas Bogendoerfer wrote:
> Following patch is clearly 2.6.25 material and is needed to get SGI IP28
> machines supported.
> 
> Thomas.
> 
> SGI IP28 machines would need special treatment (enable adding addtional
> wait states) when accessing memory uncached. To avoid this pain I changed
> the driver to use only cached access to memory.
> 
> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

applied.  As I have noted to you previously, /please/ put extraneous 
comments /after/ a "---" separator, so that they are not copied by 
git-am (Linus's email patch import tool) into the permanent kernel 
changelog.

The above should look like:

<snip>
SGI IP28 machines would need special treatment (enable adding addtional 
wait states) when accessing memory uncached. To avoid this pain I 
changed the driver to use only cached access to memory.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
Following patch is clearly 2.6.25 material and is needed to get SGI IP28 
machines supported.

Thomas.

  drivers/net/sgiseeq.c |  239 
++++++++++++++++++++++++++++++++++---------------
  1 files changed, 166 insertions(+), 73 deletions(-)
</snip>


See Documentation/SubmittingPatches for more details, in particular "14) 
The canonical patch format" or http://linux.yyz.us/patch-format.html

	Jeff



From rmk+linux-mips=linux-mips.org@arm.linux.org.uk Sat Dec  1 23:22:14 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 01 Dec 2007 23:22:23 +0000 (GMT)
Received: from caramon.arm.linux.org.uk ([78.32.30.218]:50665 "EHLO
	caramon.arm.linux.org.uk") by ftp.linux-mips.org with ESMTP
	id S20026751AbXLAXWO (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Sat, 1 Dec 2007 23:22:14 +0000
Received: from flint.arm.linux.org.uk ([2002:4e20:1eda:1:201:2ff:fe14:8fad])
	by caramon.arm.linux.org.uk with esmtpsa (TLSv1:AES256-SHA:256)
	(Exim 4.62)
	(envelope-from <rmk@arm.linux.org.uk>)
	id 1IybbN-0002ly-SD; Sat, 01 Dec 2007 23:18:26 +0000
Received: from rmk by flint.arm.linux.org.uk with local (Exim 4.62)
	(envelope-from <rmk@flint.arm.linux.org.uk>)
	id 1IybbL-0004Qn-QZ; Sat, 01 Dec 2007 23:18:23 +0000
Date:	Sat, 1 Dec 2007 23:18:23 +0000
From:	Russell King <rmk@arm.linux.org.uk>
To:	Franck Bui-Huu <fbuihuu@gmail.com>
Cc:	linux-arch@vger.kernel.org, macro@linux-mips.org,
	linux-mips@linux-mips.org
Subject: Re: [PATCH 1/2] Yet another __initxxx annotations: __initbss/__exitbss
Message-ID: <20071201231823.GB5411@flint.arm.linux.org.uk>
Mail-Followup-To: Franck Bui-Huu <fbuihuu@gmail.com>,
	linux-arch@vger.kernel.org, macro@linux-mips.org,
	linux-mips@linux-mips.org
References: <1196543586-6698-1-git-send-email-fbuihuu@gmail.com> <1196543586-6698-2-git-send-email-fbuihuu@gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <1196543586-6698-2-git-send-email-fbuihuu@gmail.com>
User-Agent: Mutt/1.4.2.1i
Return-Path: <rmk+linux-mips=linux-mips.org@arm.linux.org.uk>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17656
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: rmk@arm.linux.org.uk
Precedence: bulk
X-list: linux-mips

On Sat, Dec 01, 2007 at 10:13:05PM +0100, Franck Bui-Huu wrote:
> To select the BSS attribute for a peculiar section, the name of the
> section must start with 'bss.' pattern. This is at least how GCC
> 3.2/4.1.2 works and it's the reason why the 2 new sections haven't
> been called '.{init,exit}.bss'.
> 
> To mark a data part of one of these 2 sections, we use the 2 new
> annotations: __initbss/__exitbss.
> 
> All data marked as part of this section must not be initialized,
> of course.

Are you sure about this?  The gcc manual for 4.1.1 says:

     Use the `section' attribute with an _initialized_ definition of a
     _global_ variable, as shown in the example.  GCC issues a warning
     and otherwise ignores the `section' attribute in uninitialized
     variable declarations.

which has had that paragraph since at least 3.4.0.  Either the GCC
documentation is wrong or the compiler is misbehaving if what you say
works.  Either way, I'd be nervous about relying on this given that
GCC developers like to change the compiler behaviour.

Suggest getting the GCC developers nailed down to ensure we know what
the intended compiler behaviour is (and getting the docs to reflect that)
before relying on the existing behaviour.

-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:

From tsbogend@alpha.franken.de Sun Dec  2 11:13:39 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Dec 2007 11:13:47 +0000 (GMT)
Received: from elvis.franken.de ([193.175.24.41]:6113 "EHLO elvis.franken.de")
	by ftp.linux-mips.org with ESMTP id S20022282AbXLBLNj (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Sun, 2 Dec 2007 11:13:39 +0000
Received: from uucp (helo=solo.franken.de)
	by elvis.franken.de with local-bsmtp (Exim 3.36 #1)
	id 1IymiQ-0000XZ-00; Sun, 02 Dec 2007 12:10:26 +0100
Received: by solo.franken.de (Postfix, from userid 1000)
	id 6A926C2EB4; Sun,  2 Dec 2007 11:33:09 +0100 (CET)
From:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To:	linux-scsi@vger.kernel.org, linux-mips@linux-mips.org
cc:	ralf@linux-mips.org, James.Bottomley@HansenPartnership.com
Subject: [UPDATED PATCH] SGIWD93: use cached memory access to make driver work on IP28
Message-Id: <20071202103309.6A926C2EB4@solo.franken.de>
Date:	Sun,  2 Dec 2007 11:33:09 +0100 (CET)
Return-Path: <tsbogend@alpha.franken.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17657
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tsbogend@alpha.franken.de
Precedence: bulk
X-list: linux-mips

SGI IP28 machines would need special treatment (enable adding addtional
wait states) when accessing memory uncached. To avoid this pain I
changed the driver to use only cached access to memory.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

Changes to last version:

- added Kconfig change to make selection for similair SGI boxes easier

 drivers/scsi/Kconfig   |    2 +-
 drivers/scsi/sgiwd93.c |   64 +++++++++++++++++++++++++++++------------------
 2 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index a6676be..2a071b0 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -345,7 +345,7 @@ config ISCSI_TCP
 
 config SGIWD93_SCSI
 	tristate "SGI WD93C93 SCSI Driver"
-	depends on SGI_IP22 && SCSI
+	depends on SGI_HAS_WD93 && SCSI
   	help
 	  If you have a Western Digital WD93 SCSI controller on
 	  an SGI MIPS system, say Y.  Otherwise, say N.
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index eef8275..e64ddee 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -33,10 +33,9 @@
 
 struct ip22_hostdata {
 	struct WD33C93_hostdata wh;
-	struct hpc_data {
-		dma_addr_t      dma;
-		void		*cpu;
-	} hd;
+	dma_addr_t dma;
+	void *cpu;
+	void *dev;
 };
 
 #define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata))
@@ -46,6 +45,11 @@ struct hpc_chunk {
 	u32 _padding;	/* align to quadword boundary */
 };
 
+/* space for hpc dma descriptors */
+#define HPC_DMA_SIZE   PAGE_SIZE
+
+#define DMA_DIR(d)   ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE)
+
 static irqreturn_t sgiwd93_intr(int irq, void *dev_id)
 {
 	struct Scsi_Host * host = dev_id;
@@ -59,15 +63,17 @@ static irqreturn_t sgiwd93_intr(int irq, void *dev_id)
 }
 
 static inline
-void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp)
+void fill_hpc_entries(struct ip22_hostdata *hd, struct scsi_cmnd *cmd, int din)
 {
 	unsigned long len = cmd->SCp.this_residual;
 	void *addr = cmd->SCp.ptr;
 	dma_addr_t physaddr;
 	unsigned long count;
+	struct hpc_chunk *hcp;
 
-	physaddr = dma_map_single(NULL, addr, len, cmd->sc_data_direction);
+	physaddr = dma_map_single(hd->dev, addr, len, DMA_DIR(din));
 	cmd->SCp.dma_handle = physaddr;
+	hcp = hd->cpu;
 
 	while (len) {
 		/*
@@ -89,6 +95,9 @@ void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp)
 	 */
 	hcp->desc.pbuf = 0;
 	hcp->desc.cntinfo = HPCDMA_EOX;
+	dma_cache_sync(hd->dev, hd->cpu,
+		       (unsigned long)(hcp + 1) - (unsigned long)hd->cpu,
+		       DMA_TO_DEVICE);
 }
 
 static int dma_setup(struct scsi_cmnd *cmd, int datainp)
@@ -96,9 +105,8 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp)
 	struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host);
 	struct hpc3_scsiregs *hregs =
 		(struct hpc3_scsiregs *) cmd->device->host->base;
-	struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu;
 
-	pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp);
+	pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hdata->cpu);
 
 	hdata->wh.dma_dir = datainp;
 
@@ -111,12 +119,12 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp)
 	if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0)
 		return 1;
 
-	fill_hpc_entries(hcp, cmd, datainp);
+	fill_hpc_entries(hdata, cmd, datainp);
 
 	pr_debug(" HPCGO\n");
 
 	/* Start up the HPC. */
-	hregs->ndptr = hdata->hd.dma;
+	hregs->ndptr = hdata->dma;
 	if (datainp)
 		hregs->ctrl = HPC3_SCTRL_ACTIVE;
 	else
@@ -134,6 +142,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
 	if (!SCpnt)
 		return;
 
+	if (SCpnt->SCp.ptr == NULL || SCpnt->SCp.this_residual == 0)
+		return;
+
 	hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base;
 
 	pr_debug("dma_stop: status<%d> ", status);
@@ -145,8 +156,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
 			barrier();
 	}
 	hregs->ctrl = 0;
-	dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual,
-	                 SCpnt->sc_data_direction);
+	dma_unmap_single(hdata->dev, SCpnt->SCp.dma_handle,
+			 SCpnt->SCp.this_residual,
+			 DMA_DIR(hdata->wh.dma_dir));
 
 	pr_debug("\n");
 }
@@ -160,22 +172,23 @@ void sgiwd93_reset(unsigned long base)
 	hregs->ctrl = 0;
 }
 
-static inline void init_hpc_chain(struct hpc_data *hd)
+static inline void init_hpc_chain(void *dev, struct ip22_hostdata *hdata)
 {
-	struct hpc_chunk *hcp = (struct hpc_chunk *) hd->cpu;
-	struct hpc_chunk *dma = (struct hpc_chunk *) hd->dma;
+	struct hpc_chunk *hcp = (struct hpc_chunk *)hdata->cpu;
+	dma_addr_t dma = hdata->dma;
 	unsigned long start, end;
 
 	start = (unsigned long) hcp;
-	end = start + PAGE_SIZE;
+	end = start + HPC_DMA_SIZE;
 	while (start < end) {
-		hcp->desc.pnext = (u32) (dma + 1);
+		hcp->desc.pnext = (u32) (dma + sizeof(struct hpc_chunk));
 		hcp->desc.cntinfo = HPCDMA_EOX;
-		hcp++; dma++;
+		hcp++;
+		dma += sizeof(struct hpc_chunk);
 		start += sizeof(struct hpc_chunk);
 	};
 	hcp--;
-	hcp->desc.pnext = hd->dma;
+	hcp->desc.pnext = hdata->dma;
 }
 
 static int sgiwd93_bus_reset(struct scsi_cmnd *cmd)
@@ -234,16 +247,17 @@ static int __init sgiwd93_probe(struct platform_device *pdev)
 	host->irq = irq;
 
 	hdata = host_to_hostdata(host);
-	hdata->hd.cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
-	                                   &hdata->hd.dma, GFP_KERNEL);
-	if (!hdata->hd.cpu) {
+	hdata->dev = &pdev->dev;
+	hdata->cpu = dma_alloc_noncoherent(&pdev->dev, HPC_DMA_SIZE,
+					   &hdata->dma, GFP_KERNEL);
+	if (!hdata->cpu) {
 		printk(KERN_WARNING "sgiwd93: Could not allocate memory for "
 		       "host %d buffer.\n", unit);
 		err = -ENOMEM;
 		goto out_put;
 	}
 
-	init_hpc_chain(&hdata->hd);
+	init_hpc_chain(&pdev->dev, hdata);
 
 	regs.SASR = wdregs + 3;
 	regs.SCMD = wdregs + 7;
@@ -273,7 +287,7 @@ static int __init sgiwd93_probe(struct platform_device *pdev)
 out_irq:
 	free_irq(irq, host);
 out_free:
-	dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma);
+	dma_free_noncoherent(NULL, HPC_DMA_SIZE, hdata->cpu, hdata->dma);
 out_put:
 	scsi_host_put(host);
 out:
@@ -289,7 +303,7 @@ static void __exit sgiwd93_remove(struct platform_device *pdev)
 
 	scsi_remove_host(host);
 	free_irq(pd->irq, host);
-	dma_free_coherent(&pdev->dev, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma);
+	dma_free_noncoherent(&pdev->dev, HPC_DMA_SIZE, hdata->cpu, hdata->dma);
 	scsi_host_put(host);
 }
 

From tsbogend@alpha.franken.de Sun Dec  2 11:14:08 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Dec 2007 11:14:12 +0000 (GMT)
Received: from elvis.franken.de ([193.175.24.41]:7137 "EHLO elvis.franken.de")
	by ftp.linux-mips.org with ESMTP id S20022363AbXLBLNn (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Sun, 2 Dec 2007 11:13:43 +0000
Received: from uucp (helo=solo.franken.de)
	by elvis.franken.de with local-bsmtp (Exim 3.36 #1)
	id 1IymiQ-0000XZ-01; Sun, 02 Dec 2007 12:10:26 +0100
Received: by solo.franken.de (Postfix, from userid 1000)
	id 75E51C2EB5; Sun,  2 Dec 2007 11:33:12 +0100 (CET)
From:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To:	netdev@vger.kernel.org, linux-mips@linux-mips.org
cc:	ralf@linux-mips.org, jgarzik@pobox.com
Subject: [UPDATED PATCH] SGISEEQ: use cached memory access to make driver work on IP28
Message-Id: <20071202103312.75E51C2EB5@solo.franken.de>
Date:	Sun,  2 Dec 2007 11:33:12 +0100 (CET)
Return-Path: <tsbogend@alpha.franken.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17658
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tsbogend@alpha.franken.de
Precedence: bulk
X-list: linux-mips

SGI IP28 machines would need special treatment (enable adding addtional
wait states) when accessing memory uncached. To avoid this pain I changed
the driver to use only cached access to memory.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

Changes to last version:
- Use inline functions for dma_sync_* instead of macros (suggested by Ralf)
- added Kconfig change to make selection for similair SGI boxes easier


 drivers/net/Kconfig   |    2 +-
 drivers/net/sgiseeq.c |  243 ++++++++++++++++++++++++++++++++++---------------
 2 files changed, 171 insertions(+), 74 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 7a55bc1..9cbd5de 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1795,7 +1795,7 @@ config DE620
 
 config SGISEEQ
 	tristate "SGI Seeq ethernet controller support"
-	depends on SGI_IP22
+	depends on SGI_HAS_SEEQ
 	help
 	  Say Y here if you have an Seeq based Ethernet network card. This is
 	  used in many Silicon Graphics machines.
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index ff40563..c69bb8b 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -12,7 +12,6 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
@@ -53,14 +52,27 @@ static char *sgiseeqstr = "SGI Seeq8003";
 			    sp->tx_old + (SEEQ_TX_BUFFERS - 1) - sp->tx_new : \
 			    sp->tx_old - sp->tx_new - 1)
 
+#define VIRT_TO_DMA(sp, v) ((sp)->srings_dma +                                 \
+				  (dma_addr_t)((unsigned long)(v) -            \
+					       (unsigned long)((sp)->rx_desc)))
+
+/* Copy frames shorter than rx_copybreak, otherwise pass on up in
+ * a full sized sk_buff.  Value of 100 stolen from tulip.c (!alpha).
+ */
+static int rx_copybreak = 100;
+
+#define PAD_SIZE    (128 - sizeof(struct hpc_dma_desc) - sizeof(void *))
+
 struct sgiseeq_rx_desc {
 	volatile struct hpc_dma_desc rdma;
-	volatile signed int buf_vaddr;
+	u8 padding[PAD_SIZE];
+	struct sk_buff *skb;
 };
 
 struct sgiseeq_tx_desc {
 	volatile struct hpc_dma_desc tdma;
-	volatile signed int buf_vaddr;
+	u8 padding[PAD_SIZE];
+	struct sk_buff *skb;
 };
 
 /*
@@ -96,6 +108,18 @@ struct sgiseeq_private {
 	spinlock_t tx_lock;
 };
 
+static inline void dma_sync_desc_cpu(struct net_device *dev, void *addr)
+{
+	dma_cache_sync(dev->dev.parent, addr, sizeof(struct sgiseeq_rx_desc),
+		       DMA_FROM_DEVICE);
+}
+
+static inline void dma_sync_desc_dev(struct net_device *dev, void *addr)
+{
+	dma_cache_sync(dev->dev.parent, addr, sizeof(struct sgiseeq_rx_desc),
+		       DMA_TO_DEVICE);
+}
+
 static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
 {
 	hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
@@ -163,35 +187,55 @@ static int seeq_init_ring(struct net_device *dev)
 
 	/* Setup tx ring. */
 	for(i = 0; i < SEEQ_TX_BUFFERS; i++) {
-		if (!sp->tx_desc[i].tdma.pbuf) {
-			unsigned long buffer;
-
-			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
-			if (!buffer)
-				return -ENOMEM;
-			sp->tx_desc[i].buf_vaddr = CKSEG1ADDR(buffer);
-			sp->tx_desc[i].tdma.pbuf = CPHYSADDR(buffer);
-		}
 		sp->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT;
+		dma_sync_desc_dev(dev, &sp->tx_desc[i]);
 	}
 
 	/* And now the rx ring. */
 	for (i = 0; i < SEEQ_RX_BUFFERS; i++) {
 		if (!sp->rx_desc[i].rdma.pbuf) {
-			unsigned long buffer;
+			dma_addr_t dma_addr;
+			struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
 
-			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
-			if (!buffer)
+			if (skb == NULL)
 				return -ENOMEM;
-			sp->rx_desc[i].buf_vaddr = CKSEG1ADDR(buffer);
-			sp->rx_desc[i].rdma.pbuf = CPHYSADDR(buffer);
+			skb_reserve(skb, 2);
+			dma_addr = dma_map_single(dev->dev.parent,
+						  skb->data - 2,
+						  PKT_BUF_SZ, DMA_FROM_DEVICE);
+			sp->rx_desc[i].skb = skb;
+			sp->rx_desc[i].rdma.pbuf = dma_addr;
 		}
 		sp->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT;
+		dma_sync_desc_dev(dev, &sp->rx_desc[i]);
 	}
 	sp->rx_desc[i - 1].rdma.cntinfo |= HPCDMA_EOR;
+	dma_sync_desc_dev(dev, &sp->rx_desc[i - 1]);
 	return 0;
 }
 
+static void seeq_purge_ring(struct net_device *dev)
+{
+	struct sgiseeq_private *sp = netdev_priv(dev);
+	int i;
+
+	/* clear tx ring. */
+	for (i = 0; i < SEEQ_TX_BUFFERS; i++) {
+		if (sp->tx_desc[i].skb) {
+			dev_kfree_skb(sp->tx_desc[i].skb);
+			sp->tx_desc[i].skb = NULL;
+		}
+	}
+
+	/* And now the rx ring. */
+	for (i = 0; i < SEEQ_RX_BUFFERS; i++) {
+		if (sp->rx_desc[i].skb) {
+			dev_kfree_skb(sp->rx_desc[i].skb);
+			sp->rx_desc[i].skb = NULL;
+		}
+	}
+}
+
 #ifdef DEBUG
 static struct sgiseeq_private *gpriv;
 static struct net_device *gdev;
@@ -258,8 +302,8 @@ static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
 		sregs->tstat = TSTAT_INIT_SEEQ;
 	}
 
-	hregs->rx_ndptr = CPHYSADDR(sp->rx_desc);
-	hregs->tx_ndptr = CPHYSADDR(sp->tx_desc);
+	hregs->rx_ndptr = VIRT_TO_DMA(sp, sp->rx_desc);
+	hregs->tx_ndptr = VIRT_TO_DMA(sp, sp->tx_desc);
 
 	seeq_go(sp, hregs, sregs);
 	return 0;
@@ -283,69 +327,90 @@ static inline void rx_maybe_restart(struct sgiseeq_private *sp,
 				    struct sgiseeq_regs *sregs)
 {
 	if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) {
-		hregs->rx_ndptr = CPHYSADDR(sp->rx_desc + sp->rx_new);
+		hregs->rx_ndptr = VIRT_TO_DMA(sp, sp->rx_desc + sp->rx_new);
 		seeq_go(sp, hregs, sregs);
 	}
 }
 
-#define for_each_rx(rd, sp) for((rd) = &(sp)->rx_desc[(sp)->rx_new]; \
-				!((rd)->rdma.cntinfo & HPCDMA_OWN); \
-				(rd) = &(sp)->rx_desc[(sp)->rx_new])
-
 static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp,
 			      struct hpc3_ethregs *hregs,
 			      struct sgiseeq_regs *sregs)
 {
 	struct sgiseeq_rx_desc *rd;
 	struct sk_buff *skb = NULL;
+	struct sk_buff *newskb;
 	unsigned char pkt_status;
-	unsigned char *pkt_pointer = NULL;
 	int len = 0;
 	unsigned int orig_end = PREV_RX(sp->rx_new);
 
 	/* Service every received packet. */
-	for_each_rx(rd, sp) {
+	rd = &sp->rx_desc[sp->rx_new];
+	dma_sync_desc_cpu(dev, rd);
+	while (!(rd->rdma.cntinfo & HPCDMA_OWN)) {
 		len = PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3;
-		pkt_pointer = (unsigned char *)(long)rd->buf_vaddr;
-		pkt_status = pkt_pointer[len + 2];
-
+		dma_unmap_single(dev->dev.parent, rd->rdma.pbuf,
+				 PKT_BUF_SZ, DMA_FROM_DEVICE);
+		pkt_status = rd->skb->data[len];
 		if (pkt_status & SEEQ_RSTAT_FIG) {
 			/* Packet is OK. */
-			skb = dev_alloc_skb(len + 2);
-
-			if (skb) {
-				skb_reserve(skb, 2);
-				skb_put(skb, len);
-
-				/* Copy out of kseg1 to avoid silly cache flush. */
-				skb_copy_to_linear_data(skb, pkt_pointer + 2, len);
-				skb->protocol = eth_type_trans(skb, dev);
-
-				/* We don't want to receive our own packets */
-				if (memcmp(eth_hdr(skb)->h_source, dev->dev_addr, ETH_ALEN)) {
+			/* We don't want to receive our own packets */
+			if (memcmp(rd->skb->data + 6, dev->dev_addr, ETH_ALEN)) {
+				if (len > rx_copybreak) {
+					skb = rd->skb;
+					newskb = netdev_alloc_skb(dev, PKT_BUF_SZ);
+					if (!newskb) {
+						newskb = skb;
+						skb = NULL;
+						goto memory_squeeze;
+					}
+					skb_reserve(newskb, 2);
+				} else {
+					skb = netdev_alloc_skb(dev, len + 2);
+					if (skb) {
+						skb_reserve(skb, 2);
+						skb_copy_to_linear_data(skb, rd->skb->data, len);
+					}
+					newskb = rd->skb;
+				}
+memory_squeeze:
+				if (skb) {
+					skb_put(skb, len);
+					skb->protocol = eth_type_trans(skb, dev);
 					netif_rx(skb);
 					dev->last_rx = jiffies;
 					dev->stats.rx_packets++;
 					dev->stats.rx_bytes += len;
 				} else {
-					/* Silently drop my own packets */
-					dev_kfree_skb_irq(skb);
+					printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n",
+						dev->name);
+					dev->stats.rx_dropped++;
 				}
 			} else {
-				printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n",
-					dev->name);
-				dev->stats.rx_dropped++;
+				/* Silently drop my own packets */
+				newskb = rd->skb;
 			}
 		} else {
 			record_rx_errors(dev, pkt_status);
+			newskb = rd->skb;
 		}
+		rd->skb = newskb;
+		rd->rdma.pbuf = dma_map_single(dev->dev.parent,
+					       newskb->data - 2,
+					       PKT_BUF_SZ, DMA_FROM_DEVICE);
 
 		/* Return the entry to the ring pool. */
 		rd->rdma.cntinfo = RCNTINFO_INIT;
 		sp->rx_new = NEXT_RX(sp->rx_new);
+		dma_sync_desc_dev(dev, rd);
+		rd = &sp->rx_desc[sp->rx_new];
+		dma_sync_desc_cpu(dev, rd);
 	}
+	dma_sync_desc_cpu(dev, &sp->rx_desc[orig_end]);
 	sp->rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR);
+	dma_sync_desc_dev(dev, &sp->rx_desc[orig_end]);
+	dma_sync_desc_cpu(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]);
 	sp->rx_desc[PREV_RX(sp->rx_new)].rdma.cntinfo |= HPCDMA_EOR;
+	dma_sync_desc_dev(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]);
 	rx_maybe_restart(sp, hregs, sregs);
 }
 
@@ -358,20 +423,29 @@ static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp,
 	}
 }
 
-static inline void kick_tx(struct sgiseeq_tx_desc *td,
+static inline void kick_tx(struct net_device *dev,
+			   struct sgiseeq_private *sp,
 			   struct hpc3_ethregs *hregs)
 {
+	struct sgiseeq_tx_desc *td;
+	int i = sp->tx_old;
+
 	/* If the HPC aint doin nothin, and there are more packets
 	 * with ETXD cleared and XIU set we must make very certain
 	 * that we restart the HPC else we risk locking up the
 	 * adapter.  The following code is only safe iff the HPCDMA
 	 * is not active!
 	 */
+	td = &sp->tx_desc[i];
+	dma_sync_desc_cpu(dev, td);
 	while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
-	      (HPCDMA_XIU | HPCDMA_ETXD))
-		td = (struct sgiseeq_tx_desc *)(long) CKSEG1ADDR(td->tdma.pnext);
+	      (HPCDMA_XIU | HPCDMA_ETXD)) {
+		i = NEXT_TX(i);
+		td = &sp->tx_desc[i];
+		dma_sync_desc_cpu(dev, td);
+	}
 	if (td->tdma.cntinfo & HPCDMA_XIU) {
-		hregs->tx_ndptr = CPHYSADDR(td);
+		hregs->tx_ndptr = VIRT_TO_DMA(sp, td);
 		hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
 	}
 }
@@ -400,11 +474,12 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp
 	for (j = sp->tx_old; j != sp->tx_new; j = NEXT_TX(j)) {
 		td = &sp->tx_desc[j];
 
+		dma_sync_desc_cpu(dev, td);
 		if (!(td->tdma.cntinfo & (HPCDMA_XIU)))
 			break;
 		if (!(td->tdma.cntinfo & (HPCDMA_ETXD))) {
 			if (!(status & HPC3_ETXCTRL_ACTIVE)) {
-				hregs->tx_ndptr = CPHYSADDR(td);
+				hregs->tx_ndptr = VIRT_TO_DMA(sp, td);
 				hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
 			}
 			break;
@@ -413,6 +488,11 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp
 		sp->tx_old = NEXT_TX(sp->tx_old);
 		td->tdma.cntinfo &= ~(HPCDMA_XIU | HPCDMA_XIE);
 		td->tdma.cntinfo |= HPCDMA_EOX;
+		if (td->skb) {
+			dev_kfree_skb_any(td->skb);
+			td->skb = NULL;
+		}
+		dma_sync_desc_dev(dev, td);
 	}
 }
 
@@ -480,6 +560,7 @@ static int sgiseeq_close(struct net_device *dev)
 	/* Shutdown the Seeq. */
 	reset_hpc3_and_seeq(sp->hregs, sregs);
 	free_irq(irq, dev);
+	seeq_purge_ring(dev);
 
 	return 0;
 }
@@ -506,16 +587,22 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct hpc3_ethregs *hregs = sp->hregs;
 	unsigned long flags;
 	struct sgiseeq_tx_desc *td;
-	int skblen, len, entry;
+	int len, entry;
 
 	spin_lock_irqsave(&sp->tx_lock, flags);
 
 	/* Setup... */
-	skblen = skb->len;
-	len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
+	len = skb->len;
+	if (len < ETH_ZLEN) {
+		if (skb_padto(skb, ETH_ZLEN))
+			return 0;
+		len = ETH_ZLEN;
+	}
+
 	dev->stats.tx_bytes += len;
 	entry = sp->tx_new;
 	td = &sp->tx_desc[entry];
+	dma_sync_desc_cpu(dev, td);
 
 	/* Create entry.  There are so many races with adding a new
 	 * descriptor to the chain:
@@ -530,25 +617,27 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	 *    entry and the HPC got to the end of the chain before we
 	 *    added this new entry and restarted it.
 	 */
-	skb_copy_from_linear_data(skb, (char *)(long)td->buf_vaddr, skblen);
-	if (len != skblen)
-		memset((char *)(long)td->buf_vaddr + skb->len, 0, len-skblen);
+	td->skb = skb;
+	td->tdma.pbuf = dma_map_single(dev->dev.parent, skb->data,
+				       len, DMA_TO_DEVICE);
 	td->tdma.cntinfo = (len & HPCDMA_BCNT) |
 	                   HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX;
+	dma_sync_desc_dev(dev, td);
 	if (sp->tx_old != sp->tx_new) {
 		struct sgiseeq_tx_desc *backend;
 
 		backend = &sp->tx_desc[PREV_TX(sp->tx_new)];
+		dma_sync_desc_cpu(dev, backend);
 		backend->tdma.cntinfo &= ~HPCDMA_EOX;
+		dma_sync_desc_dev(dev, backend);
 	}
 	sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */
 
 	/* Maybe kick the HPC back into motion. */
 	if (!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE))
-		kick_tx(&sp->tx_desc[sp->tx_old], hregs);
+		kick_tx(dev, sp, hregs);
 
 	dev->trans_start = jiffies;
-	dev_kfree_skb(skb);
 
 	if (!TX_BUFFS_AVAIL(sp))
 		netif_stop_queue(dev);
@@ -586,33 +675,41 @@ static void sgiseeq_set_multicast(struct net_device *dev)
 		sgiseeq_reset(dev);
 }
 
-static inline void setup_tx_ring(struct sgiseeq_tx_desc *buf, int nbufs)
+static inline void setup_tx_ring(struct net_device *dev,
+				 struct sgiseeq_tx_desc *buf,
+				 int nbufs)
 {
+	struct sgiseeq_private *sp = netdev_priv(dev);
 	int i = 0;
 
 	while (i < (nbufs - 1)) {
-		buf[i].tdma.pnext = CPHYSADDR(buf + i + 1);
+		buf[i].tdma.pnext = VIRT_TO_DMA(sp, buf + i + 1);
 		buf[i].tdma.pbuf = 0;
+		dma_sync_desc_dev(dev, &buf[i]);
 		i++;
 	}
-	buf[i].tdma.pnext = CPHYSADDR(buf);
+	buf[i].tdma.pnext = VIRT_TO_DMA(sp, buf);
+	dma_sync_desc_dev(dev, &buf[i]);
 }
 
-static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs)
+static inline void setup_rx_ring(struct net_device *dev,
+				 struct sgiseeq_rx_desc *buf,
+				 int nbufs)
 {
+	struct sgiseeq_private *sp = netdev_priv(dev);
 	int i = 0;
 
 	while (i < (nbufs - 1)) {
-		buf[i].rdma.pnext = CPHYSADDR(buf + i + 1);
+		buf[i].rdma.pnext = VIRT_TO_DMA(sp, buf + i + 1);
 		buf[i].rdma.pbuf = 0;
+		dma_sync_desc_dev(dev, &buf[i]);
 		i++;
 	}
 	buf[i].rdma.pbuf = 0;
-	buf[i].rdma.pnext = CPHYSADDR(buf);
+	buf[i].rdma.pnext = VIRT_TO_DMA(sp, buf);
+	dma_sync_desc_dev(dev, &buf[i]);
 }
 
-#define ALIGNED(x)  ((((unsigned long)(x)) + 0xf) & ~(0xf))
-
 static int __init sgiseeq_probe(struct platform_device *pdev)
 {
 	struct sgiseeq_platform_data *pd = pdev->dev.platform_data;
@@ -621,7 +718,7 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
 	unsigned int irq = pd->irq;
 	struct sgiseeq_private *sp;
 	struct net_device *dev;
-	int err, i;
+	int err;
 	DECLARE_MAC_BUF(mac);
 
 	dev = alloc_etherdev(sizeof (struct sgiseeq_private));
@@ -635,7 +732,7 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
 	sp = netdev_priv(dev);
 
 	/* Make private data page aligned */
-	sr = dma_alloc_coherent(&pdev->dev, sizeof(*sp->srings),
+	sr = dma_alloc_noncoherent(&pdev->dev, sizeof(*sp->srings),
 				&sp->srings_dma, GFP_KERNEL);
 	if (!sr) {
 		printk(KERN_ERR "Sgiseeq: Page alloc failed, aborting.\n");
@@ -647,8 +744,8 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
 	sp->tx_desc = sp->srings->txvector;
 
 	/* A couple calculations now, saves many cycles later. */
-	setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS);
-	setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS);
+	setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS);
+	setup_tx_ring(dev, sp->tx_desc, SEEQ_TX_BUFFERS);
 
 	memcpy(dev->dev_addr, pd->mac, ETH_ALEN);
 
@@ -716,8 +813,8 @@ static int __exit sgiseeq_remove(struct platform_device *pdev)
 	struct sgiseeq_private *sp = netdev_priv(dev);
 
 	unregister_netdev(dev);
-	dma_free_coherent(&pdev->dev, sizeof(*sp->srings), sp->srings,
-	                  sp->srings_dma);
+	dma_free_noncoherent(&pdev->dev, sizeof(*sp->srings), sp->srings,
+			     sp->srings_dma);
 	free_netdev(dev);
 	platform_set_drvdata(pdev, NULL);
 


From tsbogend@alpha.franken.de Sun Dec  2 12:00:59 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Dec 2007 12:01:07 +0000 (GMT)
Received: from elvis.franken.de ([193.175.24.41]:18661 "EHLO elvis.franken.de")
	by ftp.linux-mips.org with ESMTP id S20023160AbXLBMA7 (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Sun, 2 Dec 2007 12:00:59 +0000
Received: from uucp (helo=solo.franken.de)
	by elvis.franken.de with local-bsmtp (Exim 3.36 #1)
	id 1IynVI-0001dY-00; Sun, 02 Dec 2007 13:00:56 +0100
Received: by solo.franken.de (Postfix, from userid 1000)
	id E7844C2EB5; Sun,  2 Dec 2007 12:54:42 +0100 (CET)
From:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To:	linux-kernel@vger.kernel.org, linux-mips@linux-mips.org
cc:	wim@iguana.be
Subject: [PATCH] WATCHDOG: Use SGI_HAS_INDYDOG for INDYDOG depends
Message-Id: <20071202115442.E7844C2EB5@solo.franken.de>
Date:	Sun,  2 Dec 2007 12:54:42 +0100 (CET)
Return-Path: <tsbogend@alpha.franken.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17659
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tsbogend@alpha.franken.de
Precedence: bulk
X-list: linux-mips

Use SGI_HAS_INDYDOG for INDYDOG depends.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

Please apply for 2.6.25.

 drivers/watchdog/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 2792bc1..1ba30cb 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -586,7 +586,7 @@ config SBC_EPX_C3_WATCHDOG
 
 config INDYDOG
 	tristate "Indy/I2 Hardware Watchdog"
-	depends on SGI_IP22
+	depends on SGI_HAS_INDYDOG
 	help
 	  Hardware driver for the Indy's/I2's watchdog. This is a
 	  watchdog timer that will reboot the machine after a 60 second

From tsbogend@alpha.franken.de Sun Dec  2 12:01:27 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Dec 2007 12:01:31 +0000 (GMT)
Received: from elvis.franken.de ([193.175.24.41]:18917 "EHLO elvis.franken.de")
	by ftp.linux-mips.org with ESMTP id S20023297AbXLBMA7 (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Sun, 2 Dec 2007 12:00:59 +0000
Received: from uucp (helo=solo.franken.de)
	by elvis.franken.de with local-bsmtp (Exim 3.36 #1)
	id 1IynVI-0001dY-01; Sun, 02 Dec 2007 13:00:56 +0100
Received: by solo.franken.de (Postfix, from userid 1000)
	id BDBEFC2EB6; Sun,  2 Dec 2007 12:54:56 +0100 (CET)
From:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To:	linux-kernel@vger.kernel.org, linux-mips@linux-mips.org
cc:	wim@iguana.be
Subject: [PATCH] PARTITION: Use DEFAULT_SGI_PARTITION for SGI_PARTION default
Message-Id: <20071202115456.BDBEFC2EB6@solo.franken.de>
Date:	Sun,  2 Dec 2007 12:54:56 +0100 (CET)
Return-Path: <tsbogend@alpha.franken.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17660
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tsbogend@alpha.franken.de
Precedence: bulk
X-list: linux-mips

Use DEFAULT_SGI_PARTITION for SGI_PARTION default

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

Please apply for 2.6.25.

 fs/partitions/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig
index a99acd8..cb5f0a3 100644
--- a/fs/partitions/Kconfig
+++ b/fs/partitions/Kconfig
@@ -198,7 +198,7 @@ config LDM_DEBUG
 
 config SGI_PARTITION
 	bool "SGI partition support" if PARTITION_ADVANCED
-	default y if (SGI_IP22 || SGI_IP27 || ((MACH_JAZZ || SNI_RM) && !CPU_LITTLE_ENDIAN))
+	default y if DEFAULT_SGI_PARTITION
 	help
 	  Say Y here if you would like to be able to read the hard disk
 	  partition table format used by SGI machines.

From tsbogend@alpha.franken.de Sun Dec  2 12:01:52 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Dec 2007 12:02:01 +0000 (GMT)
Received: from elvis.franken.de ([193.175.24.41]:19941 "EHLO elvis.franken.de")
	by ftp.linux-mips.org with ESMTP id S20023370AbXLBMBB (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Sun, 2 Dec 2007 12:01:01 +0000
Received: from uucp (helo=solo.franken.de)
	by elvis.franken.de with local-bsmtp (Exim 3.36 #1)
	id 1IynVI-0001dY-02; Sun, 02 Dec 2007 13:00:56 +0100
Received: by solo.franken.de (Postfix, from userid 1000)
	id 85F91C2EB6; Sun,  2 Dec 2007 12:55:19 +0100 (CET)
From:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To:	linux-input@vger.kernel.org, linux-mips@linux-mips.org
cc:	dmitry.torokhov@gmail.com
Subject: [PATCH] I8042: Use SGI_HAS_I8042 to select SGI i8042 handlinig
Message-Id: <20071202115519.85F91C2EB6@solo.franken.de>
Date:	Sun,  2 Dec 2007 12:55:19 +0100 (CET)
Return-Path: <tsbogend@alpha.franken.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17661
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tsbogend@alpha.franken.de
Precedence: bulk
X-list: linux-mips

Use SGI_HAS_I8042 to select SGI i8042 handling

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

Please apply for 2.6.25.

 drivers/input/serio/i8042.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index dd22d91..c972e5d 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -16,7 +16,7 @@
 
 #if defined(CONFIG_MACH_JAZZ)
 #include "i8042-jazzio.h"
-#elif defined(CONFIG_SGI_IP22)
+#elif defined(CONFIG_SGI_HAS_I8042)
 #include "i8042-ip22io.h"
 #elif defined(CONFIG_PPC)
 #include "i8042-ppcio.h"

From tsbogend@alpha.franken.de Sun Dec  2 12:02:21 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Dec 2007 12:02:31 +0000 (GMT)
Received: from elvis.franken.de ([193.175.24.41]:20453 "EHLO elvis.franken.de")
	by ftp.linux-mips.org with ESMTP id S20023380AbXLBMBB (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Sun, 2 Dec 2007 12:01:01 +0000
Received: from uucp (helo=solo.franken.de)
	by elvis.franken.de with local-bsmtp (Exim 3.36 #1)
	id 1IynVJ-0001dY-01; Sun, 02 Dec 2007 13:00:57 +0100
Received: by solo.franken.de (Postfix, from userid 1000)
	id 2A477C2EB6; Sun,  2 Dec 2007 13:00:32 +0100 (CET)
From:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Subject: [UPDATED PATCH] IP28 support
To:	linux-mips@linux-mips.org
cc:	ralf@linux-mips.org
Message-Id: <20071202120032.2A477C2EB6@solo.franken.de>
Date:	Sun,  2 Dec 2007 13:00:32 +0100 (CET)
Return-Path: <tsbogend@alpha.franken.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17662
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tsbogend@alpha.franken.de
Precedence: bulk
X-list: linux-mips

Add support for SGI IP28 machines (Indigo 2 with R10k CPUs)
This work is mainly based on Peter Fuersts work.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

Changes to last version:

- restructered Kconfig to make device/feature selection easier

 arch/mips/Kconfig                                  |   66 ++-
 arch/mips/Makefile                                 |   14 +
 arch/mips/sgi-ip22/Makefile                        |    8 +-
 arch/mips/sgi-ip22/ip22-mc.c                       |    4 +
 arch/mips/sgi-ip22/ip28-berr.c                     |  700 ++++++++++++++++++++
 include/asm-mips/dma.h                             |    7 +-
 include/asm-mips/mach-ip28/cpu-feature-overrides.h |   50 ++
 include/asm-mips/mach-ip28/ds1286.h                |    4 +
 include/asm-mips/mach-ip28/spaces.h                |   22 +
 include/asm-mips/mach-ip28/war.h                   |   25 +
 10 files changed, 890 insertions(+), 10 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 455bd1f..aae317d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -122,6 +122,7 @@ config MACH_JAZZ
 	select ARCH_MAY_HAVE_PC_FDC
 	select CEVT_R4K
 	select CSRC_R4K
+	select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
 	select GENERIC_ISA_DMA
 	select IRQ_CPU
 	select I8253
@@ -398,6 +399,7 @@ config SGI_IP22
 	select BOOT_ELF32
 	select CEVT_R4K
 	select CSRC_R4K
+	select DEFAULT_SGI_PARTITION
 	select DMA_NONCOHERENT
 	select HW_HAS_EISA
 	select I8253
@@ -405,6 +407,12 @@ config SGI_IP22
 	select IP22_CPU_SCACHE
 	select IRQ_CPU
 	select GENERIC_ISA_DMA_SUPPORT_BROKEN
+	select SGI_HAS_DS1286
+	select SGI_HAS_I8042
+	select SGI_HAS_INDYDOG
+	select SGI_HAS_SEEQ
+	select SGI_HAS_WD93
+	select SGI_HAS_ZILOG
 	select SWAP_IO_SPACE
 	select SYS_HAS_CPU_R4X00
 	select SYS_HAS_CPU_R5000
@@ -422,6 +430,7 @@ config SGI_IP27
 	select ARC
 	select ARC64
 	select BOOT_ELF64
+	select DEFAULT_SGI_PARTITION
 	select DMA_IP27
 	select SYS_HAS_EARLY_PRINTK
 	select HW_HAS_PCI
@@ -438,6 +447,35 @@ config SGI_IP27
 	  workstations.  To compile a Linux kernel that runs on these, say Y
 	  here.
 
+config SGI_IP28
+	bool "SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	select ARC
+	select ARC64
+	select BOOT_ELF64
+	select CEVT_R4K
+	select CSRC_R4K
+	select DEFAULT_SGI_PARTITION
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select HW_HAS_EISA
+	select I8253
+	select I8259
+	select SGI_HAS_DS1286
+	select SGI_HAS_I8042
+	select SGI_HAS_INDYDOG
+	select SGI_HAS_SEEQ
+	select SGI_HAS_WD93
+	select SGI_HAS_ZILOG
+	select SWAP_IO_SPACE
+	select SYS_HAS_CPU_R10000
+	select SYS_HAS_EARLY_PRINTK
+	select SYS_SUPPORTS_64BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+      help
+        This is the SGI Indigo2 with R10000 processor.  To compile a Linux
+        kernel that runs on these, say Y here.
+
 config SGI_IP32
 	bool "SGI IP32 (O2)"
 	select ARC
@@ -577,6 +615,7 @@ config SNI_RM
 	select BOOT_ELF32
 	select CEVT_R4K
 	select CSRC_R4K
+	select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
 	select DMA_NONCOHERENT
 	select GENERIC_ISA_DMA
 	select HW_HAS_EISA
@@ -950,6 +989,27 @@ config EMMA2RH
 config SERIAL_RM9000
 	bool
 
+config SGI_HAS_DS1286
+	bool
+
+config SGI_HAS_INDYDOG
+	bool
+
+config SGI_HAS_SEEQ
+	bool
+
+config SGI_HAS_WD93
+	bool
+
+config SGI_HAS_ZILOG
+	bool
+
+config SGI_HAS_I8042
+	bool
+
+config DEFAULT_SGI_PARTITION
+	bool
+
 config ARC32
 	bool
 
@@ -959,7 +1019,7 @@ config BOOT_ELF32
 config MIPS_L1_CACHE_SHIFT
 	int
 	default "4" if MACH_DECSTATION
-	default "7" if SGI_IP27 || SNI_RM
+	default "7" if SGI_IP27 || SGI_IP28 || SNI_RM
 	default "4" if PMC_MSP4200_EVAL
 	default "5"
 
@@ -968,7 +1028,7 @@ config HAVE_STD_PC_SERIAL_PORT
 
 config ARC_CONSOLE
 	bool "ARC console support"
-	depends on SGI_IP22 || (SNI_RM && CPU_LITTLE_ENDIAN)
+	depends on SGI_IP22 || SGI_IP28 || (SNI_RM && CPU_LITTLE_ENDIAN)
 
 config ARC_MEMORY
 	bool
@@ -977,7 +1037,7 @@ config ARC_MEMORY
 
 config ARC_PROMLIB
 	bool
-	depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP32
+	depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32
 	default y
 
 config ARC64
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index a1f8d8b..d91fbca 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -475,6 +475,20 @@ endif
 endif
 
 #
+# SGI IP28 (Indigo2 R10k)
+#
+# Set the load address to >= 0xa800000020080000 if you want to leave space for
+# symmon, 0xa800000020004000 for production kernels ?  Note that the value must
+# be 16kb aligned or the handling of the current variable will break.
+# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
+#
+#core-$(CONFIG_SGI_IP28)		+= arch/mips/sgi-ip22/ arch/mips/arc/arc_con.o
+core-$(CONFIG_SGI_IP28)		+= arch/mips/sgi-ip22/
+cflags-$(CONFIG_SGI_IP28)	+= -mr10k-cache-barrier=1 -Iinclude/asm-mips/mach-ip28
+#cflags-$(CONFIG_SGI_IP28)	+= -Iinclude/asm-mips/mach-ip28
+load-$(CONFIG_SGI_IP28)		+= 0xa800000020004000
+
+#
 # SGI-IP32 (O2)
 #
 # Set the load address to >= 80069000 if you want to leave space for symmon,
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index e3acb51..ef1564e 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -3,9 +3,11 @@
 # under Linux.
 #
 
-obj-y	+= ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \
-	   ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o
+obj-y	+= ip22-mc.o ip22-hpc.o ip22-int.o ip22-time.o ip22-nvram.o \
+	   ip22-platform.o ip22-reset.o ip22-setup.o
 
+obj-$(CONFIG_SGI_IP22) += ip22-berr.o
+obj-$(CONFIG_SGI_IP28) += ip28-berr.o
 obj-$(CONFIG_EISA)	+= ip22-eisa.o
 
-EXTRA_CFLAGS += -Werror
+# EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c
index 01a805d..3f35d63 100644
--- a/arch/mips/sgi-ip22/ip22-mc.c
+++ b/arch/mips/sgi-ip22/ip22-mc.c
@@ -4,6 +4,7 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
  * Copyright (C) 2003 Ladislav Michl  (ladis@linux-mips.org)
+ * Copyright (C) 2004 Peter Fuerst    (pf@net.alphadv.de) - IP28
  */
 
 #include <linux/init.h>
@@ -137,9 +138,12 @@ void __init sgimc_init(void)
 	/* Step 2: Enable all parity checking in cpu control register
 	 *         zero.
 	 */
+	/* don't touch parity settings for IP28 */
+#ifndef CONFIG_SGI_IP28
 	tmp = sgimc->cpuctrl0;
 	tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
 		SGIMC_CCTRL0_R4KNOCHKPARR);
+#endif
 	sgimc->cpuctrl0 = tmp;
 
 	/* Step 3: Setup the MC write buffer depth, this is controlled
diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
new file mode 100644
index 0000000..0ee5be8
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -0,0 +1,700 @@
+/*
+ * ip28-berr.c: Bus error handling.
+ *
+ * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org)
+ * Copyright (C) 2005 Peter Fuerst (pf@net.alphadv.de) - IP28
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/branch.h>
+#include <asm/irq_regs.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/ip22.h>
+#include <asm/r4kcache.h>
+#include <asm/uaccess.h>
+#include <asm/bootinfo.h>
+
+static unsigned int count_be_is_fixup;
+static unsigned int count_be_handler;
+static unsigned int count_be_interrupt;
+static int debug_be_interrupt;
+
+static unsigned int cpu_err_stat;	/* Status reg for CPU */
+static unsigned int gio_err_stat;	/* Status reg for GIO */
+static unsigned int cpu_err_addr;	/* Error address reg for CPU */
+static unsigned int gio_err_addr;	/* Error address reg for GIO */
+static unsigned int extio_stat;
+static unsigned int hpc3_berr_stat;	/* Bus error interrupt status */
+
+struct hpc3_stat {
+	unsigned long addr;
+	unsigned int ctrl;
+	unsigned int cbp;
+	unsigned int ndptr;
+};
+
+static struct {
+	struct hpc3_stat pbdma[8];
+	struct hpc3_stat scsi[2];
+	struct hpc3_stat ethrx, ethtx;
+} hpc3;
+
+static struct {
+	unsigned long err_addr;
+	struct {
+		u32 lo;
+		u32 hi;
+	} tags[1][2], tagd[4][2], tagi[4][2]; /* Way 0/1 */
+} cache_tags;
+
+static inline void save_cache_tags(unsigned busaddr)
+{
+	unsigned long addr = CAC_BASE | busaddr;
+	int i;
+	cache_tags.err_addr = addr;
+
+	/*
+	 * Starting with a bus-address, save secondary cache (indexed by
+	 * PA[23..18:7..6]) tags first.
+	 */
+	addr &= ~1L;
+#define tag cache_tags.tags[0]
+	cache_op(Index_Load_Tag_S, addr);
+	tag[0].lo = read_c0_taglo();	/* PA[35:18], VA[13:12] */
+	tag[0].hi = read_c0_taghi();	/* PA[39:36] */
+	cache_op(Index_Load_Tag_S, addr | 1L);
+	tag[1].lo = read_c0_taglo();	/* PA[35:18], VA[13:12] */
+	tag[1].hi = read_c0_taghi();	/* PA[39:36] */
+#undef tag
+
+	/*
+	 * Save all primary data cache (indexed by VA[13:5]) tags which
+	 * might fit to this bus-address, knowing that VA[11:0] == PA[11:0].
+	 * Saving all tags and evaluating them later is easier and safer
+	 * than relying on VA[13:12] from the secondary cache tags to pick
+	 * matching primary tags here already.
+	 */
+	addr &= (0xffL << 56) | ((1 << 12) - 1);
+#define tag cache_tags.tagd[i]
+	for (i = 0; i < 4; ++i, addr += (1 << 12)) {
+		cache_op(Index_Load_Tag_D, addr);
+		tag[0].lo = read_c0_taglo();	/* PA[35:12] */
+		tag[0].hi = read_c0_taghi();	/* PA[39:36] */
+		cache_op(Index_Load_Tag_D, addr | 1L);
+		tag[1].lo = read_c0_taglo();	/* PA[35:12] */
+		tag[1].hi = read_c0_taghi();	/* PA[39:36] */
+	}
+#undef tag
+
+	/*
+	 * Save primary instruction cache (indexed by VA[13:6]) tags
+	 * the same way.
+	 */
+	addr &= (0xffL << 56) | ((1 << 12) - 1);
+#define tag cache_tags.tagi[i]
+	for (i = 0; i < 4; ++i, addr += (1 << 12)) {
+		cache_op(Index_Load_Tag_I, addr);
+		tag[0].lo = read_c0_taglo();	/* PA[35:12] */
+		tag[0].hi = read_c0_taghi();	/* PA[39:36] */
+		cache_op(Index_Load_Tag_I, addr | 1L);
+		tag[1].lo = read_c0_taglo();	/* PA[35:12] */
+		tag[1].hi = read_c0_taghi();	/* PA[39:36] */
+	}
+#undef tag
+}
+
+#define GIO_ERRMASK	0xff00
+#define CPU_ERRMASK	0x3f00
+
+static void save_and_clear_buserr(void)
+{
+	int i;
+
+	/* save status registers */
+	cpu_err_addr = sgimc->cerr;
+	cpu_err_stat = sgimc->cstat;
+	gio_err_addr = sgimc->gerr;
+	gio_err_stat = sgimc->gstat;
+	extio_stat = sgioc->extio;
+	hpc3_berr_stat = hpc3c0->bestat;
+
+	hpc3.scsi[0].addr  = (unsigned long)&hpc3c0->scsi_chan0;
+	hpc3.scsi[0].ctrl  = hpc3c0->scsi_chan0.ctrl; /* HPC3_SCTRL_ACTIVE ? */
+	hpc3.scsi[0].cbp   = hpc3c0->scsi_chan0.cbptr;
+	hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr;
+
+	hpc3.scsi[1].addr  = (unsigned long)&hpc3c0->scsi_chan1;
+	hpc3.scsi[1].ctrl  = hpc3c0->scsi_chan1.ctrl; /* HPC3_SCTRL_ACTIVE ? */
+	hpc3.scsi[1].cbp   = hpc3c0->scsi_chan1.cbptr;
+	hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr;
+
+	hpc3.ethrx.addr  = (unsigned long)&hpc3c0->ethregs.rx_cbptr;
+	hpc3.ethrx.ctrl  = hpc3c0->ethregs.rx_ctrl; /* HPC3_ERXCTRL_ACTIVE ? */
+	hpc3.ethrx.cbp   = hpc3c0->ethregs.rx_cbptr;
+	hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr;
+
+	hpc3.ethtx.addr  = (unsigned long)&hpc3c0->ethregs.tx_cbptr;
+	hpc3.ethtx.ctrl  = hpc3c0->ethregs.tx_ctrl; /* HPC3_ETXCTRL_ACTIVE ? */
+	hpc3.ethtx.cbp   = hpc3c0->ethregs.tx_cbptr;
+	hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr;
+
+	for (i = 0; i < 8; ++i) {
+		/* HPC3_PDMACTRL_ISACT ? */
+		hpc3.pbdma[i].addr  = (unsigned long)&hpc3c0->pbdma[i];
+		hpc3.pbdma[i].ctrl  = hpc3c0->pbdma[i].pbdma_ctrl;
+		hpc3.pbdma[i].cbp   = hpc3c0->pbdma[i].pbdma_bptr;
+		hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr;
+	}
+	i = 0;
+	if (gio_err_stat & CPU_ERRMASK)
+		i = gio_err_addr;
+	if (cpu_err_stat & CPU_ERRMASK)
+		i = cpu_err_addr;
+	save_cache_tags(i);
+
+	sgimc->cstat = sgimc->gstat = 0;
+}
+
+static void print_cache_tags(void)
+{
+	u32 scb, scw;
+	int i;
+
+	printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr);
+
+	/* PA[31:12] shifted to PTag0 (PA[35:12]) format */
+	scw = (cache_tags.err_addr >> 4) & 0x0fffff00;
+
+	scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1);
+	for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
+		if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw &&
+		    (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw)
+		    continue;
+		printk(KERN_ERR
+		       "D: 0: %08x %08x, 1: %08x %08x  (VA[13:5]  %04x)\n",
+			cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo,
+			cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo,
+			scb | (1 << 12)*i);
+	}
+	scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1);
+	for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
+		if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw &&
+		    (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw)
+		    continue;
+		printk(KERN_ERR
+		       "I: 0: %08x %08x, 1: %08x %08x  (VA[13:6]  %04x)\n",
+			cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo,
+			cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo,
+			scb | (1 << 12)*i);
+	}
+	i = read_c0_config();
+	scb = i & (1 << 13) ? 7:6;      /* scblksize = 2^[7..6] */
+	scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */
+
+	i = ((1 << scw) - 1) & ~((1 << scb) - 1);
+	printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x  (PA[%u:%u] %05x)\n",
+		cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo,
+		cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo,
+		scw-1, scb, i & (unsigned)cache_tags.err_addr);
+}
+
+static inline const char *cause_excode_text(int cause)
+{
+	static const char *txt[32] =
+	{	"Interrupt",
+		"TLB modification",
+		"TLB (load or instruction fetch)",
+		"TLB (store)",
+		"Address error (load or instruction fetch)",
+		"Address error (store)",
+		"Bus error (instruction fetch)",
+		"Bus error (data: load or store)",
+		"Syscall",
+		"Breakpoint",
+		"Reserved instruction",
+		"Coprocessor unusable",
+		"Arithmetic Overflow",
+		"Trap",
+		"14",
+		"Floating-Point",
+		"16", "17", "18", "19", "20", "21", "22",
+		"Watch Hi/Lo",
+		"24", "25", "26", "27", "28", "29", "30", "31",
+	};
+	return txt[(cause & 0x7c) >> 2];
+}
+
+static void print_buserr(const struct pt_regs *regs)
+{
+	const int field = 2 * sizeof(unsigned long);
+	int error = 0;
+
+	if (extio_stat & EXTIO_MC_BUSERR) {
+		printk(KERN_ERR "MC Bus Error\n");
+		error |= 1;
+	}
+	if (extio_stat & EXTIO_HPC3_BUSERR) {
+		printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
+			hpc3_berr_stat,
+			(hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
+					  HPC3_BESTAT_PIDSHIFT,
+			(hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
+			hpc3_berr_stat & HPC3_BESTAT_BLMASK);
+		error |= 2;
+	}
+	if (extio_stat & EXTIO_EISA_BUSERR) {
+		printk(KERN_ERR "EISA Bus Error\n");
+		error |= 4;
+	}
+	if (cpu_err_stat & CPU_ERRMASK) {
+		printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
+			cpu_err_stat,
+			cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
+			cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
+			cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
+			cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
+			cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
+			cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
+			cpu_err_addr);
+		error |= 8;
+	}
+	if (gio_err_stat & GIO_ERRMASK) {
+		printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
+			gio_err_stat,
+			gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
+			gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
+			gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
+			gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
+			gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
+			gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
+			gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
+			gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
+			gio_err_addr);
+		error |= 16;
+	}
+	if (!error)
+		printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n");
+	else {
+		printk(KERN_ERR "CP0: config %08x,  "
+			"MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n"
+			"MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n",
+			read_c0_config(),
+			sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar,
+			sgimc->cmacc, sgimc->gmacc,
+			sgimc->mconfig0, sgimc->mconfig1);
+		print_cache_tags();
+	}
+	printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n",
+	       cause_excode_text(regs->cp0_cause),
+	       field, regs->cp0_epc, field, regs->regs[31]);
+}
+
+/*
+ * Try to find out, whether the bus error is caused by the instruction
+ * at EPC, otherwise we have an asynchronous error.
+ *
+ * Doc1: "MIPS IV Instruction Set", Rev 3.2 (SGI 007-2597-001)
+ * Doc2: "MIPS R10000 Microporcessor User's Manual", Ver 2.0 (SGI 007-2490-001)
+ * Doc3: "MIPS R4000 Microporcessor User's Manual", 2nd Ed. (SGI 007-2489-001)
+ */
+
+#define JMP_INDEX26_OP 1
+#define JMP_REGISTER_OP 2
+#define JMP_PCREL16_OP 3
+#define BASE_OFFSET_OP 4
+#define BASE_IDXREG_OP 5
+
+/* Match virtual address in an insn with physical error address */
+
+static int match_addr(unsigned paddr, unsigned long vaddr)
+{
+	unsigned long uaddr;
+
+	if ((vaddr & 0xffffffff80000000L) == 0xffffffff80000000L)
+		uaddr = (unsigned) CPHYSADDR(vaddr);
+	else if ((vaddr >> 62) == 2)
+		uaddr = (unsigned) XPHYSADDR(vaddr);
+	else {
+		unsigned long eh = vaddr & ~0x1fffL;
+
+		eh |= read_c0_entryhi() & 0xff;
+		write_c0_entryhi(eh);
+		tlb_probe();
+		if (read_c0_index() & 0x80000000)
+			return 0;
+		tlb_read();
+		if (vaddr & (1L << PAGE_SHIFT))
+			uaddr = (unsigned) read_c0_entrylo1();
+		else
+			uaddr = (unsigned) read_c0_entrylo0();
+		uaddr <<= 6;
+		uaddr &= ~PAGE_MASK;
+		uaddr |= vaddr & PAGE_MASK;
+	}
+	return ((uaddr & ~0x7f) == (paddr & ~0x7f));
+}
+
+/* Check, which kind of memory reference is triggered by `insn' */
+
+static int check_special(unsigned insn)
+{
+	/* See Doc1, page A-180 */
+	unsigned func = insn & 0x3f;
+
+	if (8 == func || 8+1 == func) /* JR, JALR */
+		return JMP_REGISTER_OP;
+
+	return 0;
+}
+
+static int check_regimm(unsigned insn)
+{
+	/* See Doc1, page A-180 */
+	unsigned rt = (insn >> 19) & 3; /* bits 20..19[..16] */
+
+	/* BLTZ, BGEZ, BLTZL, BBGEZL || BLTZAL, BGEZAL, BLTZALL, BBGEZALL */
+	if (!rt || 2 == rt)
+		return JMP_PCREL16_OP;
+
+	return 0;
+}
+
+static int check_cop0(unsigned insn)
+{
+	/* See Doc2, pages 287 ff., 187 ff. */
+	if ((insn >> 26) == 5*8+7) /* CACHE */
+		switch ((insn >> 16) & 0x1f) {
+		case Index_Writeback_Inv_D:
+		case Hit_Writeback_Inv_D:
+		case Index_Writeback_Inv_S:
+		case Hit_Writeback_Inv_S:
+			return BASE_OFFSET_OP;
+		}
+	return 0;
+}
+
+static int check_cop1(unsigned insn)
+{
+	/* See Doc1, pages B-108 ff. */
+	unsigned fmt = (insn >> 21) & 0x1f; /* bits 25..21 */
+
+	if (8 == fmt) /* BC1* */
+		return JMP_PCREL16_OP;
+
+	return 0;
+}
+
+static int check_cop1x(unsigned insn)
+{
+	/* See Doc1, pages B-108 ff. */
+	switch (insn & 0x3f) {
+	case 0:   /* LWXC1 */
+	case 1:   /* LDXC1 */
+	case 8:   /* SWXC1 */
+	case 8+1: /* SDXC1 */
+		return BASE_IDXREG_OP;
+	}
+	return 0;
+}
+
+static int check_plain(unsigned insn)
+{
+	/* See Doc1, page A-180 */
+	unsigned opcode = insn >> 26;
+
+	if (2 == opcode || 3 == opcode) /* J, JAL */
+		return JMP_INDEX26_OP;
+
+	if ((4     <= opcode && opcode <= 7) ||   /* BEQ, BNE, BLEZ, BGTZ */
+	    (4+2*8 <= opcode && opcode <= 7+2*8)) /* BEQL, BNEL, BLEZL, BGTZL */
+		return JMP_PCREL16_OP;
+
+	if (6*8+3 == opcode) /* PREF */
+		return 0;
+
+	if (3*8+2 == opcode || 3*8+3 == opcode || /* LDL, LDR */
+	    4*8 <= opcode) /* misc. LOAD, STORE */
+		return BASE_OFFSET_OP;
+
+	return 0;
+}
+
+/* Check, whether the insn at EPC causes a memory access at `paddr' */
+
+static int check_addr_in_insn(unsigned paddr, const struct pt_regs *regs)
+{
+	unsigned long epc;
+	unsigned insn;
+	unsigned long a;
+	int typ;
+
+	epc = regs->cp0_cause & CAUSEF_BD ? regs->cp0_epc:regs->cp0_epc+4;
+
+	/* show_code() from kernel/traps.c */
+	if (__get_user(insn, (u32 *)epc))
+		return 1;
+
+	/* See Doc1, pages A-180, B-108 ff. */
+	switch (insn >> 26) {
+	case 0:
+		typ = check_special(insn);
+		break;
+	case 1:
+		typ = check_regimm(insn);
+		break;
+	case 2*8:   /* COP0 */
+	case 5*8+7: /* CACHE */
+		typ = check_cop0(insn);
+		break;
+	case 2*8+1:
+		typ = check_cop1(insn);
+		break;
+	case 2*8+3:
+		typ = check_cop1x(insn);
+		break;
+	default:
+		typ = check_plain(insn);
+		break;
+	}
+	switch (typ) {
+	case JMP_INDEX26_OP:
+		a = (regs->cp0_epc + 4) & ~0xfffffff;
+		a |= (insn & 0x3ffffff) << 2;
+		return match_addr(paddr, a);
+	case JMP_REGISTER_OP:
+		a = regs->regs[(insn >> 21) & 0x1f];
+		return match_addr(paddr, a);
+	case JMP_PCREL16_OP:
+		a = regs->cp0_epc + 4 + ((insn & 0xffff) << 2);
+		return match_addr(paddr, a);
+	case BASE_OFFSET_OP:
+		a = regs->regs[(insn >> 21) & 0x1f] + (insn & 0xffff);
+		return match_addr(paddr, a);
+	case BASE_IDXREG_OP:
+		a = regs->regs[(insn >> 21) & 0x1f];
+		a += regs->regs[(insn >> 16) & 0x1f];
+		return match_addr(paddr, a);
+	case 0:
+		return 0;
+	}
+	/* Assume it would be too dangerous to continue ... */
+	return 1;
+}
+
+/*
+ * Check, whether MC's (virtual) DMA address caused the bus error.
+ * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI
+ */
+
+static int addr_is_ram(unsigned long addr, unsigned sz)
+{
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long a = boot_mem_map.map[i].addr;
+		if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size)
+			return 1;
+	}
+	return 0;
+}
+
+static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
+{
+	/* This is likely rather similar to correct code ;-) */
+
+	vaddr &= 0x7fffffff; /* Doc. states that top bit is ignored */
+
+	/* If tlb-entry is valid and VPN-high (bits [30:21] ?) matches... */
+	if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) {
+		u32 ctl = sgimc->dma_ctrl;
+		if (ctl & 1) {
+			unsigned int pgsz = (ctl & 2) ? 14:12; /* 16k:4k */
+			/* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
+			unsigned long pte = (lo >> 6) << 12; /* PTEBase */
+			pte += 8*((vaddr >> pgsz) & 0x1ff);
+			if (addr_is_ram(pte, 8)) {
+				/*
+				 * Note: Since DMA hardware does look up
+				 * translation on its own, this PTE *must*
+				 * match the TLB/EntryLo-register format !
+				 */
+				unsigned long a = *(unsigned long *)
+						PHYS_TO_XKSEG_UNCACHED(pte);
+				a = (a & 0x3f) << 6; /* PFN */
+				a += vaddr & ((1 << pgsz) - 1);
+				return (cpu_err_addr == a);
+			}
+		}
+	}
+	return 0;
+}
+
+static int check_vdma_memaddr(void)
+{
+	if (cpu_err_stat & CPU_ERRMASK) {
+		u32 a = sgimc->maddronly;
+
+		if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */
+			return (cpu_err_addr == a);
+
+		if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
+		    check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
+		    check_microtlb(sgimc->dtlb_hi2, sgimc->dtlb_lo2, a) ||
+		    check_microtlb(sgimc->dtlb_hi3, sgimc->dtlb_lo3, a))
+			return 1;
+	}
+	return 0;
+}
+
+static int check_vdma_gioaddr(void)
+{
+	if (gio_err_stat & GIO_ERRMASK) {
+		u32 a = sgimc->gio_dma_trans;
+		a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a);
+		return (gio_err_addr == a);
+	}
+	return 0;
+}
+
+/*
+ * MC sends an interrupt whenever bus or parity errors occur. In addition,
+ * if the error happened during a CPU read, it also asserts the bus error
+ * pin on the R4K. Code in bus error handler save the MC bus error registers
+ * and then clear the interrupt when this happens.
+ */
+
+static int ip28_be_interrupt(const struct pt_regs *regs)
+{
+	int i;
+
+	save_and_clear_buserr();
+	/*
+	 * Try to find out, whether we got here by a mispredicted speculative
+	 * load/store operation.  If so, it's not fatal, we can go on.
+	 */
+	/* Any cause other than "Interrupt" (ExcCode 0) is fatal. */
+	if (regs->cp0_cause & CAUSEF_EXCCODE)
+		goto mips_be_fatal;
+
+	/* Any cause other than "Bus error interrupt" (IP6) is weird. */
+	if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6)
+		goto mips_be_fatal;
+
+	if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR))
+		goto mips_be_fatal;
+
+	/* Any state other than "Memory bus error" is fatal. */
+	if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
+			goto mips_be_fatal;
+
+	/* GIO errors are fatal */
+	if (gio_err_stat & GIO_ERRMASK)
+		goto mips_be_fatal;
+
+	/* Finding `cpu_err_addr' in the insn at EPC is fatal. */
+	if ((cpu_err_stat & CPU_ERRMASK) &&
+	     check_addr_in_insn(cpu_err_addr, regs))
+			goto mips_be_fatal;
+
+	/*
+	 * Now we have an asynchronous bus error, speculatively or DMA caused.
+	 * Need to search all DMA descriptors for the error address.
+	 */
+	for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) {
+		struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
+		if ((cpu_err_stat & CPU_ERRMASK) &&
+		    (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp))
+			break;
+		if ((gio_err_stat & GIO_ERRMASK) &&
+		    (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp))
+			break;
+	}
+	if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) {
+		struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
+		printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:"
+		       " ctl %08x, ndp %08x, cbp %08x\n",
+		       CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp);
+		goto mips_be_fatal;
+	}
+	/* Check MC's virtual DMA stuff. */
+	if (check_vdma_memaddr()) {
+		printk(KERN_ERR "at GIO DMA: mem address 0x%08x.\n",
+			sgimc->maddronly);
+		goto mips_be_fatal;
+	}
+	if (check_vdma_gioaddr()) {
+		printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n",
+			sgimc->gmaddronly);
+		goto mips_be_fatal;
+	}
+	/* A speculative bus error... */
+	if (debug_be_interrupt) {
+		print_buserr(regs);
+		printk(KERN_ERR "discarded!\n");
+	}
+	return MIPS_BE_DISCARD;
+
+mips_be_fatal:
+	print_buserr(regs);
+	return MIPS_BE_FATAL;
+}
+
+void ip22_be_interrupt(int irq)
+{
+	const struct pt_regs *regs = get_irq_regs();
+
+	count_be_interrupt++;
+
+	if (ip28_be_interrupt(regs) != MIPS_BE_DISCARD) {
+		/* Assume it would be too dangerous to continue ... */
+		die_if_kernel("Oops", regs);
+		force_sig(SIGBUS, current);
+	} else if (debug_be_interrupt)
+		show_regs((struct pt_regs *)regs);
+}
+
+static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
+{
+	/*
+	 * We arrive here only in the unusual case of do_be() invocation,
+	 * i.e. by a bus error exception without a bus error interrupt.
+	 */
+	if (is_fixup) {
+		count_be_is_fixup++;
+		save_and_clear_buserr();
+		return MIPS_BE_FIXUP;
+	}
+	count_be_handler++;
+	return ip28_be_interrupt(regs);
+}
+
+void __init ip22_be_init(void)
+{
+	board_be_handler = ip28_be_handler;
+}
+
+int ip28_show_be_info(struct seq_file *m)
+{
+	seq_printf(m, "IP28 be fixups\t\t: %u\n", count_be_is_fixup);
+	seq_printf(m, "IP28 be interrupts\t: %u\n", count_be_interrupt);
+	seq_printf(m, "IP28 be handler\t\t: %u\n", count_be_handler);
+
+	return 0;
+}
+
+static int __init debug_be_setup(char *str)
+{
+	debug_be_interrupt++;
+	return 1;
+}
+__setup("ip28_debug_be", debug_be_setup);
+
diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h
index d6a6c21..1353c81 100644
--- a/include/asm-mips/dma.h
+++ b/include/asm-mips/dma.h
@@ -84,10 +84,9 @@
  * Deskstations or Acer PICA but not the much more versatile DMA logic used
  * for the local devices on Acer PICA or Magnums.
  */
-#ifdef CONFIG_SGI_IP22
-/* Horrible hack to have a correct DMA window on IP22 */
-#include <asm/sgi/mc.h>
-#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SGIMC_SEG0_BADDR + 0x01000000)
+#if defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28)
+/* don't care; ISA bus master won't work, ISA slave DMA supports 32bit addr */
+#define MAX_DMA_ADDRESS		PAGE_OFFSET
 #else
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + 0x01000000)
 #endif
diff --git a/include/asm-mips/mach-ip28/cpu-feature-overrides.h b/include/asm-mips/mach-ip28/cpu-feature-overrides.h
new file mode 100644
index 0000000..9a53b32
--- /dev/null
+++ b/include/asm-mips/mach-ip28/cpu-feature-overrides.h
@@ -0,0 +1,50 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Ralf Baechle
+ * 6/2004	pf
+ */
+#ifndef __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * IP28 only comes with R10000 family processors all using the same config
+ */
+#define cpu_has_watch		1
+#define cpu_has_mips16		0
+#define cpu_has_divec		0
+#define cpu_has_vce		0
+#define cpu_has_cache_cdex_p	0
+#define cpu_has_cache_cdex_s	0
+#define cpu_has_prefetch	1
+#define cpu_has_mcheck		0
+#define cpu_has_ejtag		0
+
+#define cpu_has_llsc		1
+#define cpu_has_vtag_icache	0
+#define cpu_has_dc_aliases	0 /* see probe_pcache() */
+#define cpu_has_ic_fills_f_dc	0
+#define cpu_has_dsp		0
+#define cpu_icache_snoops_remote_store  1
+#define cpu_has_mipsmt		0
+#define cpu_has_userlocal	0
+
+#define cpu_has_nofpuex		0
+#define cpu_has_64bits		1
+
+#define cpu_has_4kex		1
+#define cpu_has_4k_cache	1
+
+#define cpu_has_inclusive_pcaches	1
+
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	64
+
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
+#endif /* __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-ip28/ds1286.h b/include/asm-mips/mach-ip28/ds1286.h
new file mode 100644
index 0000000..471bb9a
--- /dev/null
+++ b/include/asm-mips/mach-ip28/ds1286.h
@@ -0,0 +1,4 @@
+#ifndef __ASM_MACH_IP28_DS1286_H
+#define __ASM_MACH_IP28_DS1286_H
+#include <asm/mach-ip22/ds1286.h>
+#endif /* __ASM_MACH_IP28_DS1286_H */
diff --git a/include/asm-mips/mach-ip28/spaces.h b/include/asm-mips/mach-ip28/spaces.h
new file mode 100644
index 0000000..05aabb2
--- /dev/null
+++ b/include/asm-mips/mach-ip28/spaces.h
@@ -0,0 +1,22 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
+ * Copyright (C) 2000, 2002  Maciej W. Rozycki
+ * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
+ * 2004	pf
+ */
+#ifndef _ASM_MACH_IP28_SPACES_H
+#define _ASM_MACH_IP28_SPACES_H
+
+#define CAC_BASE		0xa800000000000000
+
+#define HIGHMEM_START		(~0UL)
+
+#define PHYS_OFFSET		_AC(0x20000000, UL)
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* _ASM_MACH_IP28_SPACES_H */
diff --git a/include/asm-mips/mach-ip28/war.h b/include/asm-mips/mach-ip28/war.h
new file mode 100644
index 0000000..a1baafa
--- /dev/null
+++ b/include/asm-mips/mach-ip28/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_IP28_WAR_H
+#define __ASM_MIPS_MACH_IP28_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR	0
+#define R4600_V1_HIT_CACHEOP_WAR	0
+#define R4600_V2_HIT_CACHEOP_WAR	0
+#define R5432_CP0_INTERRUPT_WAR		0
+#define BCM1250_M3_WAR			0
+#define SIBYTE_1956_WAR			0
+#define MIPS4K_ICACHE_REFILL_WAR	0
+#define MIPS_CACHE_SYNC_WAR		0
+#define TX49XX_ICACHE_INDEX_INV_WAR	0
+#define RM9000_CDEX_SMP_WAR		0
+#define ICACHE_REFILLS_WORKAROUND_WAR	0
+#define R10000_LLSC_WAR			1
+#define MIPS34K_MISSED_ITLB_WAR		0
+
+#endif /* __ASM_MIPS_MACH_IP28_WAR_H */

From tsbogend@alpha.franken.de Sun Dec  2 12:02:51 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Dec 2007 12:03:01 +0000 (GMT)
Received: from elvis.franken.de ([193.175.24.41]:21221 "EHLO elvis.franken.de")
	by ftp.linux-mips.org with ESMTP id S20023460AbXLBMBD (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Sun, 2 Dec 2007 12:01:03 +0000
Received: from uucp (helo=solo.franken.de)
	by elvis.franken.de with local-bsmtp (Exim 3.36 #1)
	id 1IynVI-0001dY-03; Sun, 02 Dec 2007 13:00:56 +0100
Received: by solo.franken.de (Postfix, from userid 1000)
	id 9A8C8C2EB6; Sun,  2 Dec 2007 12:55:33 +0100 (CET)
From:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To:	linux-kernel@vger.kernel.org, linux-mips@linux-mips.org
cc:	akpm@linux-foundation.org
Subject: [PATCH] SERIAL: Use SGI_HAS_ZILOG for IP22_ZILOG depends
Message-Id: <20071202115533.9A8C8C2EB6@solo.franken.de>
Date:	Sun,  2 Dec 2007 12:55:33 +0100 (CET)
Return-Path: <tsbogend@alpha.franken.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17663
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tsbogend@alpha.franken.de
Precedence: bulk
X-list: linux-mips

- Use SGI_HAS_ZILOG for IP22_ZILOG depends
- remove IP22 from description, because the driver works on more than
  IP22 SGI machines

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

Please apply for 2.6.25.

 drivers/serial/Kconfig |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d7e1996..90eb9ce 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -877,15 +877,15 @@ config SERIAL_SUNHV
 	  systems.  Say Y if you want to be able to use this device.
 
 config SERIAL_IP22_ZILOG
-	tristate "IP22 Zilog8530 serial support"
-	depends on SGI_IP22
+	tristate "SGI Zilog8530 serial support"
+	depends on SGI_HAS_ZILOG
 	select SERIAL_CORE
 	help
-	  This driver supports the Zilog8530 serial ports found on SGI IP22
+	  This driver supports the Zilog8530 serial ports found on SGI 
 	  systems.  Say Y or M if you want to be able to these serial ports.
 
 config SERIAL_IP22_ZILOG_CONSOLE
-	bool "Console on IP22 Zilog8530 serial port"
+	bool "Console on SGI Zilog8530 serial port"
 	depends on SERIAL_IP22_ZILOG=y
 	select SERIAL_CORE_CONSOLE
 

From tsbogend@alpha.franken.de Sun Dec  2 12:03:21 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Dec 2007 12:03:24 +0000 (GMT)
Received: from elvis.franken.de ([193.175.24.41]:21477 "EHLO elvis.franken.de")
	by ftp.linux-mips.org with ESMTP id S20023451AbXLBMBD (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Sun, 2 Dec 2007 12:01:03 +0000
Received: from uucp (helo=solo.franken.de)
	by elvis.franken.de with local-bsmtp (Exim 3.36 #1)
	id 1IynVJ-0001dY-00; Sun, 02 Dec 2007 13:00:57 +0100
Received: by solo.franken.de (Postfix, from userid 1000)
	id 56627C2EB6; Sun,  2 Dec 2007 12:55:36 +0100 (CET)
From:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To:	linux-kernel@vger.kernel.org, linux-mips@linux-mips.org
cc:	akpm@linux-foundation.org
Subject: [PATCH] CHAR: Use SGI_HAS_DS1286 for SGI_DS1286 depends
Message-Id: <20071202115536.56627C2EB6@solo.franken.de>
Date:	Sun,  2 Dec 2007 12:55:36 +0100 (CET)
Return-Path: <tsbogend@alpha.franken.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17664
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tsbogend@alpha.franken.de
Precedence: bulk
X-list: linux-mips

Use SGI_HAS_DS1286 for SGI_DS1286 depends

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

Please apply for 2.6.25.

 drivers/char/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index a509b8d..06271e8 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -777,7 +777,7 @@ config JS_RTC
 
 config SGI_DS1286
 	tristate "SGI DS1286 RTC support"
-	depends on SGI_IP22
+	depends on SGI_HAS_DS1286
 	help
 	  If you say Y here and create a character special file /dev/rtc with
 	  major number 10 and minor number 135 using mknod ("man mknod"), you

From vagabon.xyz@gmail.com Sun Dec  2 21:37:01 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Dec 2007 21:37:09 +0000 (GMT)
Received: from nf-out-0910.google.com ([64.233.182.185]:46289 "EHLO
	nf-out-0910.google.com") by ftp.linux-mips.org with ESMTP
	id S20029466AbXLBVhB (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Sun, 2 Dec 2007 21:37:01 +0000
Received: by nf-out-0910.google.com with SMTP id c10so2349760nfd
        for <linux-mips@linux-mips.org>; Sun, 02 Dec 2007 13:37:00 -0800 (PST)
DKIM-Signature:	v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:message-id:date:from:user-agent:mime-version:to:cc:subject:references:in-reply-to:content-type:content-transfer-encoding;
        bh=UAZtJ3kEYqMZ+aXyXI1j+O2cHDEjVbOGZDCAPwqu7n0=;
        b=QorbrMCunR6s+Dt7kBm7+wX3O3HTWNHhM3sz6yHnayTCb8SqaPN9XmcxU3dACIDfeNtJppCCvCkKYqjMQ186N61RPY/IMB6OcOc9JEkx8YBwqyIfOOavTjYLaVQxf/4DM2zQFVOq5S40bdav7OcuaO0GSuHL7RC7Q0f+ARJ1t9s=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=received:message-id:date:from:user-agent:mime-version:to:cc:subject:references:in-reply-to:content-type:content-transfer-encoding;
        b=vEi+tkwE2AbK8750dhpD8JOLotLYZp1tRI33SShQu6uLfbgrqGRJs/sXmjaWc7B//kFUaxQ3R3D/Q5nfyWdnFgck8qayxogOw49Be84MVnYh7Wu/wC9xUd6nU6nBOEysJgjWFzlGjyF5WEvqLGOsLBTXGNz+M8JbxT0ryq1R85c=
Received: by 10.86.100.7 with SMTP id x7mr9883680fgb.1196631420724;
        Sun, 02 Dec 2007 13:37:00 -0800 (PST)
Received: from ?192.168.0.1? ( [82.235.205.153])
        by mx.google.com with ESMTPS id l19sm11132985fgb.2007.12.02.13.36.59
        (version=TLSv1/SSLv3 cipher=RC4-MD5);
        Sun, 02 Dec 2007 13:36:59 -0800 (PST)
Message-ID: <47532577.804@gmail.com>
Date:	Sun, 02 Dec 2007 22:36:55 +0100
From:	Franck Bui-Huu <vagabon.xyz@gmail.com>
User-Agent: Thunderbird 2.0.0.5 (X11/20070719)
MIME-Version: 1.0
To:	rmk@arm.linux.org.uk
CC:	linux-arch@vger.kernel.org, macro@linux-mips.org,
	linux-mips@linux-mips.org
Subject: Re: [PATCH 1/2] Yet another __initxxx annotations: __initbss/__exitbss
References: <1196543586-6698-1-git-send-email-fbuihuu@gmail.com> <1196543586-6698-2-git-send-email-fbuihuu@gmail.com> <20071201231823.GB5411@flint.arm.linux.org.uk>
In-Reply-To: <20071201231823.GB5411@flint.arm.linux.org.uk>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Return-Path: <vagabon.xyz@gmail.com>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17665
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: vagabon.xyz@gmail.com
Precedence: bulk
X-list: linux-mips

Russell King wrote:
> On Sat, Dec 01, 2007 at 10:13:05PM +0100, Franck Bui-Huu wrote:
>> To select the BSS attribute for a peculiar section, the name of the
>> section must start with 'bss.' pattern. This is at least how GCC
>> 3.2/4.1.2 works and it's the reason why the 2 new sections haven't
>> been called '.{init,exit}.bss'.
>>
>> To mark a data part of one of these 2 sections, we use the 2 new
>> annotations: __initbss/__exitbss.
>>
>> All data marked as part of this section must not be initialized,
>> of course.
> 
> Are you sure about this?  The gcc manual for 4.1.1 says:
> 
>      Use the `section' attribute with an _initialized_ definition of a
>      _global_ variable, as shown in the example.  GCC issues a warning
>      and otherwise ignores the `section' attribute in uninitialized
>      variable declarations.
> 
> which has had that paragraph since at least 3.4.0.  Either the GCC
> documentation is wrong or the compiler is misbehaving if what you say
> works.  Either way, I'd be nervous about relying on this given that
> GCC developers like to change the compiler behaviour.
> 

Thanks for pointing this out.

We already have (incorrectly) uninitialized data which are part of the
init.data section and the section attribute isn't ignored at all, at
least on x86 and mips. On ARM, you could take a look at where
'command_line' array, declared in in arch/arm/kernel/setup.c, is
placed.

So, it seems that we already rely on the compiler behaviour.

> Suggest getting the GCC developers nailed down to ensure we know what
> the intended compiler behaviour is (and getting the docs to reflect that)
> before relying on the existing behaviour.
> 

Yes I agree. Do you have someone in mind to suggest or should I ask to
the GCC mailing list ?

		Franck

From tsbogend@alpha.franken.de Mon Dec  3 07:20:35 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Dec 2007 07:20:43 +0000 (GMT)
Received: from elvis.franken.de ([193.175.24.41]:44165 "EHLO elvis.franken.de")
	by ftp.linux-mips.org with ESMTP id S20022769AbXLCHUf (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Mon, 3 Dec 2007 07:20:35 +0000
Received: from uucp (helo=solo.franken.de)
	by elvis.franken.de with local-bsmtp (Exim 3.36 #1)
	id 1Iz5YT-0000ox-00; Mon, 03 Dec 2007 08:17:25 +0100
Received: by solo.franken.de (Postfix, from userid 1000)
	id 36E3FDE4C4; Sun,  2 Dec 2007 20:43:46 +0100 (CET)
From:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To:	linux-kernel@vger.kernel.org, linux-mips@linux-mips.org
cc:	akpm@linux-foundation.org
Subject: [PATCH] SC26XX: New serial driver for SC2681 uarts
Message-Id: <20071202194346.36E3FDE4C4@solo.franken.de>
Date:	Sun,  2 Dec 2007 20:43:46 +0100 (CET)
Return-Path: <tsbogend@alpha.franken.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17666
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tsbogend@alpha.franken.de
Precedence: bulk
X-list: linux-mips

New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
using these chips for onboard serial ports.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

Please apply for 2.6.25.

 drivers/serial/Kconfig  |   15 +
 drivers/serial/Makefile |    1 +
 drivers/serial/sc26xx.c |  757 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 773 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d7e1996..2ea55d0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1284,4 +1284,19 @@ config SERIAL_OF_PLATFORM
 	  Currently, only 8250 compatible ports are supported, but
 	  others can easily be added.
 
+config SERIAL_SC26XX
+	tristate "SC2681/SC2692 serial port support"
+	depends on SNI_RM
+	select SERIAL_CORE
+	help
+	  This is a driver for the onboard serial ports of 
+	  older RM400 machines.
+
+config SERIAL_SC26XX_CONSOLE
+	bool "Console on SC2681/SC2692 serial port"
+	depends on SERIAL_SC26XX
+	select SERIAL_CORE_CONSOLE
+	help
+	  Support for Console on SC2681/SC2692 serial ports.
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index af6377d..87d09b6 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -64,3 +64,4 @@ obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
 obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
 obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
 obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
+obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c
new file mode 100644
index 0000000..be563ad
--- /dev/null
+++ b/drivers/serial/sc26xx.c
@@ -0,0 +1,757 @@
+/*
+ * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
+ *
+ * Copyright (C) 2006,2007 Thomas Bogendörfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/sysrq.h>
+#include <linux/console.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#define SC26XX_MAJOR         204
+#define SC26XX_MINOR_START   205
+#define SC26XX_NR            2
+
+struct uart_sc26xx_port {
+	struct uart_port      port[2];
+	u8     dsr_mask[2];
+	u8     cts_mask[2];
+	u8     dcd_mask[2];
+	u8     ri_mask[2];
+	u8     dtr_mask[2];
+	u8     rts_mask[2];
+	u8     imr;
+};
+
+/* register common to both ports */
+#define RD_ISR      0x14
+#define RD_IPR      0x34
+
+#define WR_ACR      0x10
+#define WR_IMR      0x14
+#define WR_OPCR     0x34
+#define WR_OPR_SET  0x38
+#define WR_OPR_CLR  0x3C
+
+/* access common register */
+#define READ_SC(p, r)        readb ((p)->membase + RD_##r)
+#define WRITE_SC(p, r, v)    writeb ((v), (p)->membase + WR_##r)
+
+/* register per port */
+#define RD_PORT_MRx 0x00
+#define RD_PORT_SR  0x04
+#define RD_PORT_RHR 0x0c
+
+#define WR_PORT_MRx 0x00
+#define WR_PORT_CSR 0x04
+#define WR_PORT_CR  0x08
+#define WR_PORT_THR 0x0c
+
+/* access port register */
+#define READ_SC_PORT(p, r)     \
+		readb((p)->membase + (p)->line * 0x20 + RD_PORT_##r)
+#define WRITE_SC_PORT(p, r, v) \
+		writeb((v), (p)->membase + (p)->line * 0x20 + WR_PORT_##r)
+
+/* SR bits */
+#define SR_BREAK    (1 << 7)
+#define SR_FRAME    (1 << 6)
+#define SR_PARITY   (1 << 5)
+#define SR_OVERRUN  (1 << 4)
+#define SR_TXRDY    (1 << 2)
+#define SR_RXRDY    (1 << 0)
+
+#define CR_RES_MR   (1 << 4)
+#define CR_RES_RX   (2 << 4)
+#define CR_RES_TX   (3 << 4)
+#define CR_STRT_BRK (6 << 4)
+#define CR_STOP_BRK (7 << 4)
+#define CR_DIS_TX   (1 << 3)
+#define CR_ENA_TX   (1 << 2)
+#define CR_DIS_RX   (1 << 1)
+#define CR_ENA_RX   (1 << 0)
+
+/* ISR bits */
+#define ISR_RXRDYB  (1 << 5)
+#define ISR_TXRDYB  (1 << 4)
+#define ISR_RXRDYA  (1 << 1)
+#define ISR_TXRDYA  (1 << 0)
+
+/* IMR bits */
+#define IMR_RXRDY   (1 << 1)
+#define IMR_TXRDY   (1 << 0)
+
+static void sc26xx_enable_irq(struct uart_port *port, int mask)
+{
+	struct uart_sc26xx_port *up;
+	int line = port->line;
+
+	port -= line;
+	up = (struct uart_sc26xx_port *)port;
+
+	up->imr |= mask << (line * 4);
+	WRITE_SC(port, IMR, up->imr);
+}
+
+static void sc26xx_disable_irq(struct uart_port *port, int mask)
+{
+	struct uart_sc26xx_port *up;
+	int line = port->line;
+
+	port -= line;
+	up = (struct uart_sc26xx_port *)port;
+
+	up->imr &= ~(mask << (line * 4));
+	WRITE_SC(port, IMR, up->imr);
+}
+
+static struct tty_struct *receive_chars(struct uart_port *port)
+{
+	struct tty_struct *tty = NULL;
+	int limit = 10000;
+	unsigned char ch;
+	char flag;
+	u8 status;
+
+	if (port->info != NULL)		/* Unopened serial console */
+		tty = port->info->tty;
+
+	while (limit-- > 0) {
+		status = READ_SC_PORT(port, SR);
+		if (!(status & SR_RXRDY))
+			break;
+		ch = READ_SC_PORT(port, RHR);
+
+		flag = TTY_NORMAL;
+		port->icount.rx++;
+
+		if (unlikely(status & (SR_BREAK | SR_FRAME |
+				       SR_PARITY | SR_OVERRUN))) {
+			if (status & SR_BREAK) {
+				status &= ~(SR_PARITY | SR_FRAME);
+				port->icount.brk++;
+				if (uart_handle_break(port))
+					continue;
+			} else if (status & SR_PARITY)
+				port->icount.parity++;
+			else if (status & SR_FRAME)
+				port->icount.frame++;
+			if (status & SR_OVERRUN)
+				port->icount.overrun++;
+
+			status &= port->read_status_mask;
+			if (status & SR_BREAK)
+				flag = TTY_BREAK;
+			else if (status & SR_PARITY)
+				flag = TTY_PARITY;
+			else if (status & SR_FRAME)
+				flag = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(port, ch))
+			continue;
+
+		if (status & port->ignore_status_mask)
+			continue;
+
+		tty_insert_flip_char(tty, ch, flag);
+	}
+	return tty;
+}
+
+static void transmit_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit;
+
+	if (!port->info)
+		return;
+
+	xmit = &port->info->xmit;
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		sc26xx_disable_irq(port, IMR_TXRDY);
+		return;
+	}
+	while (!uart_circ_empty(xmit)) {
+		if (!(READ_SC_PORT(port, SR) & SR_TXRDY))
+			break;
+
+		WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+	}
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+}
+
+static irqreturn_t sc26xx_interrupt(int irq, void *dev_id)
+{
+	struct uart_sc26xx_port *up = dev_id;
+	struct tty_struct *tty;
+	unsigned long flags;
+	u8 isr;
+
+	spin_lock_irqsave(&up->port[0].lock, flags);
+
+	tty = NULL;
+	isr = READ_SC(&up->port[0], ISR);
+	if (isr & ISR_TXRDYA)
+	    transmit_chars(&up->port[0]);
+	if (isr & ISR_RXRDYA)
+	    tty = receive_chars(&up->port[0]);
+
+	spin_unlock(&up->port[0].lock);
+
+	if (tty)
+		tty_flip_buffer_push(tty);
+
+	spin_lock(&up->port[1].lock);
+
+	tty = NULL;
+	if (isr & ISR_TXRDYB)
+	    transmit_chars(&up->port[1]);
+	if (isr & ISR_RXRDYB)
+	    tty = receive_chars(&up->port[1]);
+
+	spin_unlock_irqrestore(&up->port[1].lock, flags);
+
+	if (tty)
+		tty_flip_buffer_push(tty);
+
+	return IRQ_HANDLED;
+}
+
+/* port->lock is not held.  */
+static unsigned int sc26xx_tx_empty(struct uart_port *port)
+{
+	unsigned long flags;
+	unsigned int ret;
+
+	spin_lock_irqsave(&port->lock, flags);
+	ret = (READ_SC_PORT(port, SR) & SR_TXRDY) ? TIOCSER_TEMT : 0;
+	spin_unlock_irqrestore(&port->lock, flags);
+	return ret;
+}
+
+/* port->lock held by caller.  */
+static void sc26xx_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_sc26xx_port *up;
+	int line = port->line;
+
+	port -= line;
+	up = (struct uart_sc26xx_port *)port;
+
+	if (up->dtr_mask[line]) {
+		if (mctrl & TIOCM_DTR)
+			WRITE_SC(port, OPR_SET, up->dtr_mask[line]);
+		else
+			WRITE_SC(port, OPR_CLR, up->dtr_mask[line]);
+	}
+	if (up->rts_mask[line]) {
+		if (mctrl & TIOCM_RTS)
+			WRITE_SC(port, OPR_SET, up->rts_mask[line]);
+		else
+			WRITE_SC(port, OPR_CLR, up->rts_mask[line]);
+	}
+}
+
+/* port->lock is held by caller and interrupts are disabled.  */
+static unsigned int sc26xx_get_mctrl(struct uart_port *port)
+{
+	struct uart_sc26xx_port *up;
+	int line = port->line;
+	unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR;
+	u8 ipr;
+
+	port -= line;
+	up = (struct uart_sc26xx_port *)port;
+	ipr = READ_SC(port, IPR) ^ 0xff;
+
+	if (up->dsr_mask[line]) {
+		mctrl &= ~TIOCM_DSR;
+		mctrl |= ipr & up->dsr_mask[line] ? TIOCM_DSR : 0;
+	}
+	if (up->cts_mask[line]) {
+		mctrl &= ~TIOCM_CTS;
+		mctrl |= ipr & up->cts_mask[line] ? TIOCM_CTS : 0;
+	}
+	if (up->dcd_mask[line]) {
+		mctrl &= ~TIOCM_CAR;
+		mctrl |= ipr & up->dcd_mask[line] ? TIOCM_CAR : 0;
+	}
+	if (up->ri_mask[line]) {
+		mctrl &= ~TIOCM_RNG;
+		mctrl |= ipr & up->ri_mask[line] ? TIOCM_RNG : 0;
+	}
+	return mctrl;
+}
+
+/* port->lock held by caller.  */
+static void sc26xx_stop_tx(struct uart_port *port)
+{
+	return;
+}
+
+/* port->lock held by caller.  */
+static void sc26xx_start_tx(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+
+	while (!uart_circ_empty(xmit)) {
+		if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) {
+			sc26xx_enable_irq(port, IMR_TXRDY);
+			break;
+		}
+		WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+	}
+}
+
+/* port->lock held by caller.  */
+static void sc26xx_stop_rx(struct uart_port *port)
+{
+}
+
+/* port->lock held by caller.  */
+static void sc26xx_enable_ms(struct uart_port *port)
+{
+}
+
+/* port->lock is not held.  */
+static void sc26xx_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (break_state == -1)
+		WRITE_SC_PORT(port, CR, CR_STRT_BRK);
+	else
+		WRITE_SC_PORT(port, CR, CR_STOP_BRK);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/* port->lock is not held.  */
+static int sc26xx_startup(struct uart_port *port)
+{
+	sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY);
+	WRITE_SC(port, OPCR, 0);
+
+	/* reset tx and rx */
+	WRITE_SC_PORT(port, CR, CR_RES_RX);
+	WRITE_SC_PORT(port, CR, CR_RES_TX);
+
+	/* start rx/tx */
+	WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX);
+
+	/* enable irqs */
+	sc26xx_enable_irq(port, IMR_RXRDY);
+	return 0;
+}
+
+/* port->lock is not held.  */
+static void sc26xx_shutdown(struct uart_port *port)
+{
+	/* disable interrupst */
+	sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY);
+
+	/* stop tx/rx */
+	WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX);
+}
+
+/* port->lock is not held.  */
+static void sc26xx_set_termios(struct uart_port *port, struct ktermios *termios,
+			      struct ktermios *old)
+{
+	unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
+	unsigned int quot = uart_get_divisor(port, baud);
+	unsigned int iflag, cflag;
+	unsigned long flags;
+	u8 mr1, mr2, csr;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc)
+		udelay(2);
+
+	WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX);
+
+	iflag = termios->c_iflag;
+	cflag = termios->c_cflag;
+
+	port->read_status_mask = SR_OVERRUN;
+	if (iflag & INPCK)
+		port->read_status_mask |= SR_PARITY | SR_FRAME;
+	if (iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= SR_BREAK;
+
+	port->ignore_status_mask = 0;
+	if (iflag & IGNBRK)
+		port->ignore_status_mask |= SR_BREAK;
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= SR_BREAK | SR_FRAME |
+					    SR_PARITY | SR_OVERRUN;
+
+	switch (cflag & CSIZE) {
+	case CS5:
+		mr1 = 0x00;
+		break;
+	case CS6:
+		mr1 = 0x01;
+		break;
+	case CS7:
+		mr1 = 0x02;
+		break;
+	default:
+	case CS8:
+		mr1 = 0x03;
+		break;
+	}
+	mr2 = 0x07;
+	if (cflag & CSTOPB)
+		mr2 = 0x0f;
+	if (cflag & PARENB) {
+		if (cflag & PARODD)
+			mr1 |= (1 << 2);
+	} else
+		mr1 |= (2 << 3);
+
+	switch (baud) {
+	case 50:
+		csr = 0x00;
+		break;
+	case 110:
+		csr = 0x11;
+		break;
+	case 134:
+		csr = 0x22;
+		break;
+	case 200:
+		csr = 0x33;
+		break;
+	case 300:
+		csr = 0x44;
+		break;
+	case 600:
+		csr = 0x55;
+		break;
+	case 1200:
+		csr = 0x66;
+		break;
+	case 2400:
+		csr = 0x88;
+		break;
+	case 4800:
+		csr = 0x99;
+		break;
+	default:
+	case 9600:
+		csr = 0xbb;
+		break;
+	case 19200:
+		csr = 0xcc;
+		break;
+	}
+
+	WRITE_SC_PORT(port, CR, CR_RES_MR);
+	WRITE_SC_PORT(port, MRx, mr1);
+	WRITE_SC_PORT(port, MRx, mr2);
+
+	WRITE_SC(port, ACR, 0x80);
+	WRITE_SC_PORT(port, CSR, csr);
+
+	/* reset tx and rx */
+	WRITE_SC_PORT(port, CR, CR_RES_RX);
+	WRITE_SC_PORT(port, CR, CR_RES_TX);
+
+	WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX);
+	while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc)
+		udelay(2);
+
+	/* XXX */
+	uart_update_timeout(port, cflag,
+			    (port->uartclk / (16 * quot)));
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *sc26xx_type(struct uart_port *port)
+{
+	return "SC26XX";
+}
+
+static void sc26xx_release_port(struct uart_port *port)
+{
+}
+
+static int sc26xx_request_port(struct uart_port *port)
+{
+	return 0;
+}
+
+static void sc26xx_config_port(struct uart_port *port, int flags)
+{
+}
+
+static int sc26xx_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	return -EINVAL;
+}
+
+static struct uart_ops sc26xx_ops = {
+	.tx_empty	= sc26xx_tx_empty,
+	.set_mctrl	= sc26xx_set_mctrl,
+	.get_mctrl	= sc26xx_get_mctrl,
+	.stop_tx	= sc26xx_stop_tx,
+	.start_tx	= sc26xx_start_tx,
+	.stop_rx	= sc26xx_stop_rx,
+	.enable_ms	= sc26xx_enable_ms,
+	.break_ctl	= sc26xx_break_ctl,
+	.startup	= sc26xx_startup,
+	.shutdown	= sc26xx_shutdown,
+	.set_termios	= sc26xx_set_termios,
+	.type		= sc26xx_type,
+	.release_port	= sc26xx_release_port,
+	.request_port	= sc26xx_request_port,
+	.config_port	= sc26xx_config_port,
+	.verify_port	= sc26xx_verify_port,
+};
+
+static struct uart_port *sc26xx_port;
+
+#ifdef CONFIG_SERIAL_SC26XX_CONSOLE
+static inline void sc26xx_console_putchar(struct uart_port *port, char c)
+{
+	unsigned long flags;
+	int limit = 1000000;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	while (limit-- > 0) {
+		if (READ_SC_PORT(port, SR) & SR_TXRDY) {
+			WRITE_SC_PORT(port, THR, c);
+			break;
+		}
+		udelay(2);
+	}
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void sc26xx_console_write(struct console *con, const char *s, unsigned n)
+{
+	struct uart_port *port = sc26xx_port;
+	int i;
+
+	for (i = 0; i < n; i++) {
+		if (*s == '\n')
+			sc26xx_console_putchar(port, '\r');
+		sc26xx_console_putchar(port, *s++);
+	}
+}
+
+static int __init sc26xx_console_setup(struct console *con, char *options)
+{
+	struct uart_port *port = sc26xx_port;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if (port->type != PORT_SC26XX)
+		return -1;
+
+	printk(KERN_INFO "Console: ttySC%d (SC26XX)\n", con->index);
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(port, con, baud, parity, bits, flow);
+}
+
+static struct uart_driver sc26xx_reg;
+static struct console sc26xx_console = {
+	.name	=	"ttySC",
+	.write	=	sc26xx_console_write,
+	.device	=	uart_console_device,
+	.setup  =       sc26xx_console_setup,
+	.flags	=	CON_PRINTBUFFER,
+	.index	=	-1,
+	.data	=	&sc26xx_reg,
+};
+#define SC26XX_CONSOLE   &sc26xx_console
+#else
+#define SC26XX_CONSOLE   NULL
+#endif
+
+static struct uart_driver sc26xx_reg = {
+	.owner			= THIS_MODULE,
+	.driver_name		= "SC26xx",
+	.dev_name		= "ttySC",
+	.major			= SC26XX_MAJOR,
+	.minor			= SC26XX_MINOR_START,
+	.nr			= SC26XX_NR,
+	.cons                   = SC26XX_CONSOLE,
+};
+
+static inline u8 sc26xx_flags2mask(unsigned int flags, unsigned int bitpos)
+{
+	unsigned int bit = (flags >> bitpos) & 15;
+
+	return bit ? (1 << (bit - 1)) : 0;
+}
+
+static void __devinit sc26xx_init_masks(struct uart_sc26xx_port *up,
+					int line, unsigned int data)
+{
+	up->dtr_mask[line] = sc26xx_flags2mask(data,  0);
+	up->rts_mask[line] = sc26xx_flags2mask(data,  4);
+	up->dsr_mask[line] = sc26xx_flags2mask(data,  8);
+	up->cts_mask[line] = sc26xx_flags2mask(data, 12);
+	up->dcd_mask[line] = sc26xx_flags2mask(data, 16);
+	up->ri_mask[line]  = sc26xx_flags2mask(data, 20);
+}
+
+static int __devinit sc26xx_probe(struct platform_device *dev)
+{
+	struct resource *res;
+	struct uart_sc26xx_port *up;
+	unsigned int *sc26xx_data = dev->dev.platform_data;
+	int err;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	up = kzalloc(sizeof *up, GFP_KERNEL);
+	if (unlikely(!up))
+		return -ENOMEM;
+
+	up->port[0].line = 0;
+	up->port[0].ops = &sc26xx_ops;
+	up->port[0].type = PORT_SC26XX;
+	up->port[0].uartclk = (29491200 / 16); /* arbitrary */
+
+	up->port[0].mapbase = res->start;
+	up->port[0].membase = ioremap_nocache(up->port[0].mapbase, 0x40);
+	up->port[0].iotype = UPIO_MEM;
+	up->port[0].irq = platform_get_irq(dev, 0);
+
+	up->port[0].dev = &dev->dev;
+
+	sc26xx_init_masks(up, 0, sc26xx_data[0]);
+
+	sc26xx_port = &up->port[0];
+
+	up->port[1].line = 1;
+	up->port[1].ops = &sc26xx_ops;
+	up->port[1].type = PORT_SC26XX;
+	up->port[1].uartclk = (29491200 / 16); /* arbitrary */
+
+	up->port[1].mapbase = up->port[0].mapbase;
+	up->port[1].membase = up->port[0].membase;
+	up->port[1].iotype = UPIO_MEM;
+	up->port[1].irq = up->port[0].irq;
+
+	up->port[1].dev = &dev->dev;
+
+	sc26xx_init_masks(up, 1, sc26xx_data[1]);
+
+	err = uart_register_driver(&sc26xx_reg);
+	if (err)
+		goto out_free_port;
+
+	sc26xx_reg.tty_driver->name_base = sc26xx_reg.minor;
+
+	err = uart_add_one_port(&sc26xx_reg, &up->port[0]);
+	if (err)
+		goto out_unregister_driver;
+
+	err = uart_add_one_port(&sc26xx_reg, &up->port[1]);
+	if (err)
+		goto out_remove_port0;
+
+	err = request_irq(up->port[0].irq, sc26xx_interrupt, 0, "sc26xx", up);
+	if (err)
+		goto out_remove_ports;
+
+	dev_set_drvdata(&dev->dev, up);
+	return 0;
+
+out_remove_ports:
+	uart_remove_one_port(&sc26xx_reg, &up->port[1]);
+out_remove_port0:
+	uart_remove_one_port(&sc26xx_reg, &up->port[0]);
+
+out_unregister_driver:
+	uart_unregister_driver(&sc26xx_reg);
+
+out_free_port:
+	kfree(up);
+	sc26xx_port = NULL;
+	return err;
+}
+
+
+static int __exit sc26xx_driver_remove(struct platform_device *dev)
+{
+	struct uart_sc26xx_port *up = dev_get_drvdata(&dev->dev);
+
+	free_irq(up->port[0].irq, up);
+
+	uart_remove_one_port(&sc26xx_reg, &up->port[0]);
+	uart_remove_one_port(&sc26xx_reg, &up->port[1]);
+
+	uart_unregister_driver(&sc26xx_reg);
+
+	kfree(up);
+	sc26xx_port = NULL;
+
+	dev_set_drvdata(&dev->dev, NULL);
+	return 0;
+}
+
+static struct platform_driver sc26xx_driver = {
+	.probe	= sc26xx_probe,
+	.remove	= __devexit_p(sc26xx_driver_remove),
+	.driver	= {
+		.name	= "SC26xx",
+	},
+};
+
+static int __init sc26xx_init(void)
+{
+	return platform_driver_register(&sc26xx_driver);
+}
+
+static void __exit sc26xx_exit(void)
+{
+	platform_driver_unregister(&sc26xx_driver);
+}
+
+module_init(sc26xx_init);
+module_exit(sc26xx_exit);
+
+
+MODULE_AUTHOR("Thomas Bogendörfer");
+MODULE_DESCRIPTION("SC681/SC2692 serial driver");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");

From ralf@linux-mips.org Mon Dec  3 13:06:44 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Dec 2007 13:06:46 +0000 (GMT)
Received: from localhost.localdomain ([127.0.0.1]:8111 "EHLO
	dl5rb.ham-radio-op.net") by ftp.linux-mips.org with ESMTP
	id S20022380AbXLCNGo (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Mon, 3 Dec 2007 13:06:44 +0000
Received: from denk.linux-mips.net (denk.linux-mips.net [127.0.0.1])
	by dl5rb.ham-radio-op.net (8.14.1/8.13.8) with ESMTP id lB3D5DtN006431;
	Mon, 3 Dec 2007 13:05:38 GMT
Received: (from ralf@localhost)
	by denk.linux-mips.net (8.14.1/8.14.1/Submit) id lB3D5DC5006430;
	Mon, 3 Dec 2007 13:05:13 GMT
Date:	Mon, 3 Dec 2007 13:05:13 +0000
From:	Ralf Baechle <ralf@linux-mips.org>
To:	linux-mips@linux-mips.org, linux-serial@linux-mips.org
Subject: Rename Sibyte duart devices?
Message-ID: <20071203130512.GA6320@linux-mips.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.5.17 (2007-11-01)
Return-Path: <ralf@linux-mips.org>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17667
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: ralf@linux-mips.org
Precedence: bulk
X-list: linux-mips

Devices created by udev have been named duart? instead of the common
ttyS?.  This is a nuisance because it requires changes to all sorts of
config files such as /etc/inittab, /etc/securetty etc. to work.  I
suggest to kill the problem by the root by something like the below
patch.  Comments?

  Ralf

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

 drivers/serial/sb1250-duart.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/sb1250-duart.c b/drivers/serial/sb1250-duart.c
index 2d6c08b..0defbd6 100644
--- a/drivers/serial/sb1250-duart.c
+++ b/drivers/serial/sb1250-duart.c
@@ -897,7 +897,7 @@ static int __init sbd_console_setup(struct console *co, char *options)
 
 static struct uart_driver sbd_reg;
 static struct console sbd_console = {
-	.name	= "duart",
+	.name	= "ttyS",
 	.write	= sbd_console_write,
 	.device	= uart_console_device,
 	.setup	= sbd_console_setup,
@@ -925,7 +925,7 @@ console_initcall(sbd_serial_console_init);
 static struct uart_driver sbd_reg = {
 	.owner		= THIS_MODULE,
 	.driver_name	= "serial",
-	.dev_name	= "duart",
+	.dev_name	= "ttyS",
 	.major		= TTY_MAJOR,
 	.minor		= SB1250_DUART_MINOR_BASE,
 	.nr		= DUART_MAX_CHIP * DUART_MAX_SIDE,

From ralf@linux-mips.org Mon Dec  3 13:10:04 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Dec 2007 13:10:06 +0000 (GMT)
Received: from localhost.localdomain ([127.0.0.1]:39047 "EHLO
	dl5rb.ham-radio-op.net") by ftp.linux-mips.org with ESMTP
	id S20023380AbXLCNKE (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Mon, 3 Dec 2007 13:10:04 +0000
Received: from denk.linux-mips.net (denk.linux-mips.net [127.0.0.1])
	by dl5rb.ham-radio-op.net (8.14.1/8.13.8) with ESMTP id lB3D8Ik2006474;
	Mon, 3 Dec 2007 13:08:38 GMT
Received: (from ralf@localhost)
	by denk.linux-mips.net (8.14.1/8.14.1/Submit) id lB3D8IXo006473;
	Mon, 3 Dec 2007 13:08:18 GMT
Date:	Mon, 3 Dec 2007 13:08:18 +0000
From:	Ralf Baechle <ralf@linux-mips.org>
To:	linux-mips@linux-mips.org, linux-serial@vger.kernel.org
Subject: Rename Sibyte duart devices?
Message-ID: <20071203130818.GA6466@linux-mips.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.5.17 (2007-11-01)
Return-Path: <ralf@linux-mips.org>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17668
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: ralf@linux-mips.org
Precedence: bulk
X-list: linux-mips

Devices created by udev have been named duart? instead of the common
ttyS?.  This is a nuisance because it requires changes to all sorts of
config files such as /etc/inittab, /etc/securetty etc. to work.  I
suggest to kill the problem by the root by something like the below
patch.  Comments?

  Ralf

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

 drivers/serial/sb1250-duart.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/sb1250-duart.c b/drivers/serial/sb1250-duart.c
index 2d6c08b..0defbd6 100644
--- a/drivers/serial/sb1250-duart.c
+++ b/drivers/serial/sb1250-duart.c
@@ -897,7 +897,7 @@ static int __init sbd_console_setup(struct console *co, char *options)
 
 static struct uart_driver sbd_reg;
 static struct console sbd_console = {
-	.name	= "duart",
+	.name	= "ttyS",
 	.write	= sbd_console_write,
 	.device	= uart_console_device,
 	.setup	= sbd_console_setup,
@@ -925,7 +925,7 @@ console_initcall(sbd_serial_console_init);
 static struct uart_driver sbd_reg = {
 	.owner		= THIS_MODULE,
 	.driver_name	= "serial",
-	.dev_name	= "duart",
+	.dev_name	= "ttyS",
 	.major		= TTY_MAJOR,
 	.minor		= SB1250_DUART_MINOR_BASE,
 	.nr		= DUART_MAX_CHIP * DUART_MAX_SIDE,

From yoichi_yuasa@tripeaks.co.jp Mon Dec  3 13:35:50 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Dec 2007 13:35:58 +0000 (GMT)
Received: from mo31.po.2iij.NET ([210.128.50.54]:33099 "EHLO mo31.po.2iij.net")
	by ftp.linux-mips.org with ESMTP id S20024469AbXLCNfu (ORCPT
	<rfc822;linux-mips@linux-mips.org>); Mon, 3 Dec 2007 13:35:50 +0000
Received: by mo.po.2iij.net (mo31) id lB3DYLFh055260; Mon, 3 Dec 2007 22:34:21 +0900 (JST)
Received: from delta (95.26.30.125.dy.iij4u.or.jp [125.30.26.95])
	by mbox.po.2iij.net (po-mbox303) id lB3DYJCt013684
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT);
	Mon, 3 Dec 2007 22:34:19 +0900
Date:	Mon, 3 Dec 2007 22:34:18 +0900
From:	Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
To:	Martin Michlmayr <tbm@cyrius.com>
Cc:	yoichi_yuasa@tripeaks.co.jp, linux-mips@linux-mips.org,
	Richard Purdie <rpurdie@rpsys.net>
Subject: Re: CONFIG_LEDS_COBALT_RAQ not as module
Message-Id: <20071203223418.2fec44a9.yoichi_yuasa@tripeaks.co.jp>
In-Reply-To: <20071130163258.GA10006@deprecation.cyrius.com>
References: <20071130163258.GA10006@deprecation.cyrius.com>
Organization: TriPeaks Corporation
X-Mailer: Sylpheed 2.4.5 (GTK+ 2.12.0; i486-pc-linux-gnu)
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Return-Path: <yoichi_yuasa@tripeaks.co.jp>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17669
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: yoichi_yuasa@tripeaks.co.jp
Precedence: bulk
X-list: linux-mips

Hi,

On Fri, 30 Nov 2007 17:32:58 +0100
Martin Michlmayr <tbm@cyrius.com> wrote:

> Hi Yoichi,
> 
> Is there are good reason why LEDS_COBALT_QUBE is a tristate while
> LEDS_COBALT_RAQ is a bool?  I don't see why the RAQ LED driver
> couldn't be modular.

RAQ LED driver support power off trigger.
Power off trigger is generated at the end of all.

This is the reason why RAQ LED driver doesn't have module_exit function.
Moreover, this is the reason why it is bool.

Yoichi

From ths@networkno.de Mon Dec  3 14:14:34 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Dec 2007 14:14:42 +0000 (GMT)
Received: from relay01.mx.bawue.net ([193.7.176.67]:7043 "EHLO
	relay01.mx.bawue.net") by ftp.linux-mips.org with ESMTP
	id S20023388AbXLCOOe (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Mon, 3 Dec 2007 14:14:34 +0000
Received: from lagash (intrt.mips-uk.com [194.74.144.130])
	(using TLSv1 with cipher AES256-SHA (256/256 bits))
	(No client certificate requested)
	by relay01.mx.bawue.net (Postfix) with ESMTP id 3931F48BE4;
	Mon,  3 Dec 2007 15:14:28 +0100 (CET)
Received: from ths by lagash with local (Exim 4.68)
	(envelope-from <ths@networkno.de>)
	id 1IzC42-0005OA-Uq; Mon, 03 Dec 2007 14:14:26 +0000
Date:	Mon, 3 Dec 2007 14:14:26 +0000
From:	Thiemo Seufer <ths@networkno.de>
To:	Ralf Baechle <ralf@linux-mips.org>
Cc:	linux-mips@linux-mips.org, linux-serial@vger.kernel.org
Subject: Re: Rename Sibyte duart devices?
Message-ID: <20071203141426.GI617@networkno.de>
References: <20071203130818.GA6466@linux-mips.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <20071203130818.GA6466@linux-mips.org>
User-Agent: Mutt/1.5.17 (2007-11-01)
Return-Path: <ths@networkno.de>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17670
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: ths@networkno.de
Precedence: bulk
X-list: linux-mips

Ralf Baechle wrote:
> Devices created by udev have been named duart? instead of the common
> ttyS?.  This is a nuisance because it requires changes to all sorts of
> config files such as /etc/inittab, /etc/securetty etc. to work.  I
> suggest to kill the problem by the root by something like the below
> patch.  Comments?

Debian uses such a patch since forever to avoid all the trouble.


Thiemo

From macro@linux-mips.org Mon Dec  3 14:19:16 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Dec 2007 14:19:24 +0000 (GMT)
Received: from cerber.ds.pg.gda.pl ([153.19.208.18]:17080 "EHLO
	cerber.ds.pg.gda.pl") by ftp.linux-mips.org with ESMTP
	id S20023388AbXLCOTQ (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Mon, 3 Dec 2007 14:19:16 +0000
Received: from localhost (unknown [127.0.0.17])
	by cerber.ds.pg.gda.pl (Postfix) with ESMTP id D7BB340095;
	Mon,  3 Dec 2007 15:18:46 +0100 (CET)
X-Virus-Scanned: amavisd-new at cerber.ds.pg.gda.pl
Received: from cerber.ds.pg.gda.pl ([153.19.208.18])
	by localhost (cerber.ds.pg.gda.pl [153.19.208.18]) (amavisd-new, port 10024)
	with ESMTP id g9SYV-I9mriz; Mon,  3 Dec 2007 15:18:41 +0100 (CET)
Received: from piorun.ds.pg.gda.pl (piorun.ds.pg.gda.pl [153.19.208.8])
	by cerber.ds.pg.gda.pl (Postfix) with ESMTP id 4EDB640003;
	Mon,  3 Dec 2007 15:18:41 +0100 (CET)
Received: from blysk.ds.pg.gda.pl (macro@blysk.ds.pg.gda.pl [153.19.208.6])
	by piorun.ds.pg.gda.pl (8.13.8/8.13.8) with ESMTP id lB3EIidB009318;
	Mon, 3 Dec 2007 15:18:45 +0100
Date:	Mon, 3 Dec 2007 14:18:35 +0000 (GMT)
From:	"Maciej W. Rozycki" <macro@linux-mips.org>
To:	Ralf Baechle <ralf@linux-mips.org>
cc:	linux-mips@linux-mips.org, linux-serial@linux-mips.org
Subject: Re: Rename Sibyte duart devices?
In-Reply-To: <20071203130512.GA6320@linux-mips.org>
Message-ID: <Pine.LNX.4.64N.0712031414070.19235@blysk.ds.pg.gda.pl>
References: <20071203130512.GA6320@linux-mips.org>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
X-Virus-Scanned: ClamAV 0.91.2/4980/Mon Dec  3 03:28:55 2007 on piorun.ds.pg.gda.pl
X-Virus-Status:	Clean
Return-Path: <macro@linux-mips.org>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17671
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: macro@linux-mips.org
Precedence: bulk
X-list: linux-mips

On Mon, 3 Dec 2007, Ralf Baechle wrote:

> Devices created by udev have been named duart? instead of the common
> ttyS?.  This is a nuisance because it requires changes to all sorts of
> config files such as /etc/inittab, /etc/securetty etc. to work.  I
> suggest to kill the problem by the root by something like the below
> patch.  Comments?

 Well, there is no problem with naming your device nodes in the filesystem 
however you like and the only place that only cares is the "console=" 
command line option.  I think the root is ttyS devices should really be 
only used for 8250-based devices and if you plug a standard PC serial 
option card into one of the PCI slots, then all the hell will break loose.  
I might be wrong though and the issue I am referring to may have gone now.

  Maciej

From macro@linux-mips.org Mon Dec  3 14:30:58 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Dec 2007 14:31:07 +0000 (GMT)
Received: from cerber.ds.pg.gda.pl ([153.19.208.18]:20438 "EHLO
	cerber.ds.pg.gda.pl") by ftp.linux-mips.org with ESMTP
	id S20024652AbXLCOa6 (ORCPT <rfc822;linux-mips@linux-mips.org>);
	Mon, 3 Dec 2007 14:30:58 +0000
Received: from localhost (unknown [127.0.0.17])
	by cerber.ds.pg.gda.pl (Postfix) with ESMTP id 3003340095;
	Mon,  3 Dec 2007 15:30:59 +0100 (CET)
X-Virus-Scanned: amavisd-new at cerber.ds.pg.gda.pl
Received: from cerber.ds.pg.gda.pl ([153.19.208.18])
	by localhost (cerber.ds.pg.gda.pl [153.19.208.18]) (amavisd-new, port 10024)
	with ESMTP id fzxSSMXOw8hG; Mon,  3 Dec 2007 15:30:53 +0100 (CET)
Received: from piorun.ds.pg.gda.pl (piorun.ds.pg.gda.pl [153.19.208.8])
	by cerber.ds.pg.gda.pl (Postfix) with ESMTP id AFE1240003;
	Mon,  3 Dec 2007 15:30:53 +0100 (CET)
Received: from blysk.ds.pg.gda.pl (macro@blysk.ds.pg.gda.pl [153.19.208.6])
	by piorun.ds.pg.gda.pl (8.13.8/8.13.8) with ESMTP id lB3EUv0Z011443;
	Mon, 3 Dec 2007 15:30:57 +0100
Date:	Mon, 3 Dec 2007 14:30:47 +0000 (GMT)
From:	"Maciej W. Rozycki" <macro@linux-mips.org>
To:	Ralf Baechle <ralf@linux-mips.org>
cc:	linux-mips@linux-mips.org, linux-serial@vger.kernel.org
Subject: Re: Rename Sibyte duart devices?
In-Reply-To: <20071203130818.GA6466@linux-mips.org>
Message-ID: <Pine.LNX.4.64N.0712031430050.19235@blysk.ds.pg.gda.pl>
References: <20071203130818.GA6466@linux-mips.org>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
X-Virus-Scanned: ClamAV 0.91.2/4980/Mon Dec  3 03:28:55 2007 on piorun.ds.pg.gda.pl
X-Virus-Status:	Clean
Return-Path: <macro@linux-mips.org>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17672
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: macro@linux-mips.org
Precedence: bulk
X-list: linux-mips

On Mon, 3 Dec 2007, Ralf Baechle wrote:

> Devices created by udev have been named duart? instead of the common
> ttyS?.  This is a nuisance because it requires changes to all sorts of
> config files such as /etc/inittab, /etc/securetty etc. to work.  I
> suggest to kill the problem by the root by something like the below
> patch.  Comments?

 Well, there is no problem with naming your device nodes in the filesystem
however you like and the only place that only cares is the "console="
command line option.  I think the root is ttyS devices should really be
only used for 8250-based devices and if you plug a standard PC serial
option card into one of the PCI slots, then all the hell will break loose.
I might be wrong though and the issue I am referring to may have gone now.

 [Sent twice to reach linux-serial.]

  Maciej

From tony.luck@intel.com Mon Dec  3 17:01:05 2007
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Dec 2007 17:01:13 +0000 (GMT)
Received: from mga02.intel.com ([134.134.136.20]:35318 "EHLO mga02.intel.com")
	by ftp.linux-mips.org with ESMTP id S20026145AbXLCRBF convert rfc822-to-8bit
	(ORCPT <rfc822;linux-mips@linux-mips.org>);
	Mon, 3 Dec 2007 17:01:05 +0000
Received: from orsmga001.jf.intel.com ([10.7.209.18])
  by orsmga101.jf.intel.com with ESMTP; 03 Dec 2007 09:00:57 -0800
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="4.23,244,1194249600"; 
   d="scan'208";a="286035360"
Received: from fmsmsx334.amr.corp.intel.com ([132.233.42.1])
  by orsmga001.jf.intel.com with ESMTP; 03 Dec 2007 09:00:57 -0800
Received: from scsmsx411.amr.corp.intel.com ([10.3.90.30]) by fmsmsx334.amr.corp.intel.com with Microsoft SMTPSVC(6.0.3790.1830);
	 Mon, 3 Dec 2007 09:00:50 -0800
X-MimeOLE: Produced By Microsoft Exchange V6.5
Content-class: urn:content-classes:message
MIME-Version: 1.0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 8BIT
Subject: RE: [PATCH 2/2] MIPS: vmlinux.lds.S: handle .{init,exit}.bss sections
Date:	Mon, 3 Dec 2007 09:00:49 -0800
Message-ID: <617E1C2C70743745A92448908E030B2A030FE4C2@scsmsx411.amr.corp.intel.com>
In-Reply-To: <1196543586-6698-3-git-send-email-fbuihuu@gmail.com>
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
Thread-Topic: [PATCH 2/2] MIPS: vmlinux.lds.S: handle .{init,exit}.bss sections
Thread-Index: Acg0Xwu30WWAvFsLTfOiwZEntWZUcQBblNdw
References: <1196543586-6698-1-git-send-email-fbuihuu@gmail.com> <1196543586-6698-3-git-send-email-fbuihuu@gmail.com>
From:	"Luck, Tony" <tony.luck@intel.com>
To:	"Franck Bui-Huu" <fbuihuu@gmail.com>, <linux-arch@vger.kernel.org>
Cc:	<macro@linux-mips.org>, <linux-mips@linux-mips.org>
X-OriginalArrivalTime: 03 Dec 2007 17:00:50.0677 (UTC) FILETIME=[0EBB9A50:01C835CE]
Return-Path: <tony.luck@intel.com>
X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
X-Orcpt: rfc822;linux-mips@linux-mips.org
Original-Recipient: rfc822;linux-mips@linux-mips.org
X-archive-position: 17673
X-ecartis-version: Ecartis v1.0.0
Sender: linux-mips-bounce@linux-mips.org
Errors-to: linux-mips-bounce@linux-mips.org
X-original-sender: tony.luck@intel.com
Precedence: bulk
X-list: linux-mips

+	/*
+	 * We keep init/exit bss sections here to have only one
+	 * segment to load. Note that .bss.exit is also discarded
+	 * at runtime for the same reason as above.
+	 */
+	.exit.bss : {
+		*(.bss.exit)
+	}

This change would also require an audit of the bootloader or early
kernel initialization code (whichever handles zeroing of .bss space)
to make sure that it understands that the kernel will now have an
extra block of memory that needs to be cleared.  Perhaps nothing
needs to be done if the code already handled the general case of
loading an ELF binary with some sections that have an in-memory
size bigger than the on-disk size.  But worth looking at in case
the 