From kevink@paralogos.com Sat Jan  1 09:43:04 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 01 Jan 2011 09:43:08 +0100 (CET)
Received: from gateway12.websitewelcome.com ([69.41.245.13]:43165 "HELO
        gateway12.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1491061Ab1AAInE (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sat, 1 Jan 2011 09:43:04 +0100
Received: (qmail 4397 invoked from network); 1 Jan 2011 08:42:12 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway12.websitewelcome.com with SMTP; 1 Jan 2011 08:42:12 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=nVmWzr4J+Atl16t/WSrhklT6+qrmOmLwgHElT7PRDhKP6DP6hWyg/Rv4+vfAzXlhnqexzjIf22i2+gfYqKkf4g1e7jjKBT+tvjgD39EOg7TueDdC/y4gxxw/t+45TkHJ;
Received: from c-98-207-157-135.hsd1.ca.comcast.net ([98.207.157.135]:4097 helo=[127.0.0.1])
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1PYx3D-0000Bw-1w; Sat, 01 Jan 2011 02:42:59 -0600
Message-ID: <4D1EE913.1070203@paralogos.com>
Date:   Sat, 01 Jan 2011 00:42:59 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Anoop P A <anoop.pa@gmail.com>
CC:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Subject: Re: SMTC support status in latest git head.
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>      <1293470392.27661.202.camel@paanoop1-desktop>   <1293524389.27661.210.camel@paanoop1-desktop>   <4D19A31E.1090905@paralogos.com> <1293798476.27661.279.camel@paanoop1-desktop>
In-Reply-To: <1293798476.27661.279.camel@paanoop1-desktop>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28781
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

At this point the logical thing to do would seem to look at your kernel
image and disassemble smtc_ipi_replay(), which is where the EPC of VPE 0
shows the last exception to have been taken.  That's a critical SMTC
routine that gets called whenever an xxx_irq_restore() enables
interrupts, so that virtual per-TC IPI interrupts that were posted while
the TC had interrupts disabled can be handled deterministically.  As I
mentioned in an earlier message, there was some cleanup work from David
Howell that changed a number of irq management-related function names
and prototypes across all architectures, which went into linux-mips.org
at very roughly the time of the breakage.  The SMTC overlay over the irq
implementation has been pretty robust, but it's written in a perhaps
doomed attempt to be both efficient and using a maximum amount of common
code with the general case.  A mechanical or semi-mechanical change
could conceivably have broken things.

            Regards,

            Kevin K.


On 12/31/2010 4:27 AM, Anoop P A wrote:
> Hi ,
>
> Kernel hangs on stop_machine call. Please find mt reg dump below.
> Another important observation is even though 2.6.33 kernel + stackframe
> patch well passes calibration hang , I am still unable boot in to a
> initramfs root ( verified ramfs working with VSMP). So it looks like
> still some issue to fix between 2.6.32 and 2.6.33 .
> ######################## Log ###########################
>
> === MIPS MT State Dump ===
> -- Global State --
>    MVPControl Passed: 00000005
>    MVPControl Read: 00000004
>    MVPConf0 : a8008406
> -- per-VPE State --
>   VPE 0
>    VPEControl : 00008000
>    VPEConf0 : 800f0003
>    VPE0.Status : 11004201
>    VPE0.EPC : 8010dc54 smtc_ipi_replay+0xcc/0x108
>    VPE0.Cause : 50804000
>    VPE0.Config7 : 00010000
>   VPE 1
>    VPEControl : 00068006
>    VPEConf0 : 80cf0003
>    VPE1.Status : 11008301
>    VPE1.EPC : 801022a0 r4k_wait+0x20/0x40
>    VPE1.Cause : 50800000
>    VPE1.Config7 : 00010000
> -- per-TC State --
>   TC 0 (current TC with VPE EPC above)
>    TCStatus : 18102000
>    TCBind : 00000000
>    TCRestart : 803fa19c printk+0xc/0x30
>    TCHalt : 00000000
>    TCContext : 00000000
>   TC 1
>    TCStatus : 18902000
>    TCBind : 00200000
>    TCRestart : 801022a0 r4k_wait+0x20/0x40
>    TCHalt : 00000000
>    TCContext : 00140000
>   TC 2
>    TCStatus : 18902000
>    TCBind : 00400000
>    TCRestart : 801022a0 r4k_wait+0x20/0x40
>    TCHalt : 00000000
>    TCContext : 00280000
>   TC 3
>    TCStatus : 18902000
>    TCBind : 00600000
>    TCRestart : 801022a0 r4k_wait+0x20/0x40
>    TCHalt : 00000000
>    TCContext : 003c0000
>   TC 4
>    TCStatus : 18902000
>    TCBind : 00800001
>    TCRestart : 8010229c r4k_wait+0x1c/0x40
>    TCHalt : 00000000
>    TCContext : 00500000
>   TC 5
>    TCStatus : 18902000
>    TCBind : 00a00001
>    TCRestart : 8010229c r4k_wait+0x1c/0x40
>    TCHalt : 00000000
>    TCContext : 00640000
>   TC 6
>    TCStatus : 18902000
>    TCBind : 00c00001
>    TCRestart : 8010229c r4k_wait+0x1c/0x40
>    TCHalt : 00000000
>    TCContext : 00780000
> Counter Interrupts taken per CPU (TC)
> 0: 0
> 1: 0
> 2: 0
> 3: 0
> 4: 0
> 5: 0
> 6: 0
> 7: 0
> Self-IPI invocations:
> 0: 12
> 1: 0
> 2: 0
> 3: 0
> 4: 0
> 5: 5
> 6: 4
> 7: 0
> IPIQ[0]: head = 0x0, tail = 0x0, depth = 0
> IPIQ[1]: head = 0x0, tail = 0x0, depth = 0
> IPIQ[2]: head = 0x0, tail = 0x0, depth = 0
> IPIQ[3]: head = 0x0, tail = 0x0, depth = 0
> IPIQ[4]: head = 0x0, tail = 0x0, depth = 0
> IPIQ[5]: head = 0x0, tail = 0x0, depth = 0
> IPIQ[6]: head = 0x0, tail = 0x0, depth = 0
> IPIQ[7]: head = 0x0, tail = 0x0, depth = 0
> 0 Recoveries of "stolen" FPU
> ===========================
>
> ################################################################
>
> Thanks
> Anoop
>
> On Tue, 2010-12-28 at 00:43 -0800, Kevin D. Kissell wrote:
>> I took a quick look last night, and the only thing that looked vaguely 
>> dangerous in changes since the timer changes I alluded to earlier was 
>> the global naming cleanup of irq-related function names that David 
>> Howell submitted.  The diff didn't look dangerous in itself, but some of 
>> the definitions are nested subtly for SMTC to maximize the amount of 
>> common code, and I could imagine something getting lost in translation 
>> there.  If that were really the problem, it would of course affect much 
>> more than just the timer subsystem, but early in the boot process, 
>> timers are pretty much the only interrupts that have to be handled 
>> correctly.
>>
>> I'm travelling today, but will take a look at timekeeping_notify() 
>> tomorrow or the next day...
>>
>> /K.
>>
>> On 12/28/10 12:19 AM, Anoop P A wrote:
>>> Hi,
>>>
>>> I had a glance into the code diff without notice of any suspect-able
>>> code .
>>> Tracing the hang showed that it is getting hanged in timekeeping_notify
>>> function.
>>>
>>> Thanks,
>>> Anoop
>>>
>>> PS: I may not be available until Thursday
>>>
>>> On Mon, 2010-12-27 at 22:49 +0530, Anoop P A wrote:
>>>> Hi Kevin,
>>>>
>>>> It is very unlikely that the patch you pointed has any impact on the the
>>>> hang I am seeing. The patch you have mentioned got into kernel around
>>>> 2.6.32 timeframe. I am able to boot both 2.6.32 and  2.6.33 kernel ( +
>>>> stackframe patch) .
>>>>
>>>> Hi Stuart,
>>>>
>>>> I haven't got much time to spend on this today.
>>>>
>>>> I had got 2.6.36-stable(+ stack frame patch) booting last day and I have
>>>> observed hang issue with 2.6.37-rc1 ( Same as rc6 and current git head)
>>>>
>>>> So probably some patches in 2.6.37 branch introduced this hang.
>>>>
>>>> Hopefully I will get some free slot tomorrow so that I can look into
>>>> code diff .
>>>>
>>>> Thanks
>>>> Anoop
>>>>
>>>> On Mon, 2010-12-27 at 09:49 -0600, STUART VENTERS wrote:
>>>>> Kevin,
>>>>>
>>>>> Outstanding, sometimes it's better to be lucky than good.
>>>>>
>>>>>
>>>>> Anoop,
>>>>>
>>>>> Maybe we can get lucky again.
>>>>>
>>>>> If you can isolate the .33 works/.37 works_not bug to a specific pair of versions,
>>>>>     I'll be happy to do another diff.
>>>>>
>>>>>
>>>>> Hope you'll have had a good Christmas as well.
>>>>>    We've had snow in Alabama since Christmas eve!
>>>>>
>>>>>
>>>>> Regards,
>>>>>
>>>>> Stuart
>>>>>
>>>>>
>>>>> -----Original Message-----
>>>>> From: Kevin D. Kissell [mailto:kevink@paralogos.com]
>>>>> Sent: Friday, December 24, 2010 5:34 PM
>>>>> To: Anoop P A
>>>>> Cc: STUART VENTERS; Anoop P.A.; linux-mips@linux-mips.org
>>>>> Subject: Re: SMTC support status in latest git head.
>>>>>
>>>>>
>>>>> Ah, well, at least we have a stackframe.h fix that preserves David's
>>>>> performance tweak for the deeper pipelined processors.  In looking for
>>>>> this, I did notice that someone did some modification to the SMTC clock
>>>>> tick logic that I was skeptical had ever been tested.  If you've still
>>>>> got that kernel binary handy, you might check to see if it boots with
>>>>> maxtcs=1 maxvpes=1, maxtcs=2 maxvpes=1, and/or maxtcs=2 maxvpes=2.
>>>>>
>>>>> Oh, yes, and Merry Christmas one and all!
>>>>>
>>>>>               Regards,
>>>>>
>>>>>               Kevin K.
>>>>>
>>>>> On 12/24/10 8:02 AM, Anoop P A wrote:
>>>>>> On Fri, 2010-12-24 at 06:53 -0800, Kevin D. Kissell wrote:
>>>>>>> Excellent!  Now, does the attached patch (relative to 2.6.37.11) also
>>>>>>> fix things, while preserving the other fixes and performance enhancements?
>>>>>>>
>>>>>> I have tested that patch with 2.6.37 branch it well passes calibration
>>>>>> loop but hangs after switching to mips closource
>>>>>>
>>>>>> TC 6 going on-line as CPU 6
>>>>>> Brought up 7 CPUs
>>>>>> bio: create slab<bio-0>   at 0
>>>>>> SCSI subsystem initialized
>>>>>> Switching to clocksource MIPS
>>>>>>
>>>>>> I Presume this is a different issue as restoring older file didn't help
>>>>>> much to get rid of this hang.
>>>>>>
>>>>>> diff --git a/arch/mips/include/asm/stackframe.h
>>>>>> b/arch/mips/include/asm/stackframe.h
>>>>>> index 58730c5..7fc9f10 100644
>>>>>> --- a/arch/mips/include/asm/stackframe.h
>>>>>> +++ b/arch/mips/include/asm/stackframe.h
>>>>>> @@ -195,9 +195,9 @@
>>>>>>    		 * to cover the pipeline delay.
>>>>>>    		 */
>>>>>>    		.set	mips32
>>>>>> -		mfc0	v1, CP0_TCSTATUS
>>>>>> +		mfc0	v0, CP0_TCSTATUS
>>>>>>    		.set	mips0
>>>>>> -		LONG_S	v1, PT_TCSTATUS(sp)
>>>>>> +		LONG_S	v0, PT_TCSTATUS(sp)
>>>>>>    #endif /* CONFIG_MIPS_MT_SMTC */
>>>>>>    		LONG_S	$4, PT_R4(sp)
>>>>>>    		LONG_S	$5, PT_R5(sp)
>>>>>>
>>>>>>
>>>>>>> /K.
>>>>>>>
>>>>>>> On 12/24/10 6:39 AM, Anoop P A wrote:
>>>>>>>> Hi Kevin, Stuart ,
>>>>>>>>
>>>>>>>> Woohooo You guys spotted !.
>>>>>>>>
>>>>>>>>     http://git.linux-mips.org/?p=linux.git;a=commit;h=d5ec6e3c seems to be
>>>>>>>> the culprit
>>>>>>>>
>>>>>>>> Once I restored previous version of stackframe.h 2.6.33-stable started
>>>>>>>> booting !.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Anoop
>>>>>>>>
>>>>>>>> On Fri, 2010-12-24 at 04:32 -0800, Kevin D. Kissell wrote:
>>>>>>>>> Thank you, Stuart!  I've spotted some definite breakage to SMTC between
>>>>>>>>> those versions.  In arch/mips/include/asm/stackframe.h, someone moved
>>>>>>>>> the store of the Status register value in SAVE_SOME (line 169 or 204,
>>>>>>>>> depending on the version) from two instructions after the mfc0 to a
>>>>>>>>> point after the #ifdef for SMTC, presumably to get better pipelining of
>>>>>>>>> the register access.  Unfortunately, the v1 register is also used in the
>>>>>>>>> SMTC-specific fragment to save TCStatus, so the Status value gets
>>>>>>>>> clobbered before it gets stored.  This will eventually result in the
>>>>>>>>> Status register getting a TCStatus value, which has some bits on common,
>>>>>>>>> but isn't identical and sooner or later Bad Things will happen.
>>>>>>>>>
>>>>>>>>> I'm a little surprised this wasn't caught by visual inspection of the patch.
>>>>>>>>>
>>>>>>>>> Possible solutions would include reverting the store of the CP0_STATUS
>>>>>>>>> value to the block above the #ifdef, or, to retain whatever performance
>>>>>>>>> advantage was obtained by moving the store downward, to use v0/$2
>>>>>>>>> instead of v1/$3, as the staging register for the TCStatus value.  I'd
>>>>>>>>> lean toward the second option, but I'm not in a position to test and
>>>>>>>>> submit a patch just now.
>>>>>>>>>
>>>>>>>>>                 Regards,
>>>>>>>>>
>>>>>>>>>                 Kevin K.
>>>>>>>>>
>>>>>>>>> On 12/23/10 1:09 PM, STUART VENTERS wrote:
>>>>>>>>>> Kevin,
>>>>>>>>>>
>>>>>>>>>> I'm not sure if it's useful,
>>>>>>>>>>        but finally I got the time to look at the two kernel versions Anoop pointed out.
>>>>>>>>>>         works   2.6.32-stable with patch 804
>>>>>>>>>>         works_not 2.6.33-stable
>>>>>>>>>>
>>>>>>>>>> greping for files with CONFIG_MIPS_MT_SMTC
>>>>>>>>>>        and looking for timer interrupt related stuff found the following differences:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> arch/mips/include/asm/irq.h
>>>>>>>>>> arch/mips/kernel/irq.c
>>>>>>>>>>       do_IRQ
>>>>>>>>>>
>>>>>>>>>> arch/mips/include/asm/stackframe.h
>>>>>>>>>>       SAVE_SOME SAVE_TEMP get/set_saved_sp
>>>>>>>>>>
>>>>>>>>>> arch/mips/include/asm/time.h
>>>>>>>>>>       clocksource_set_clock
>>>>>>>>>>
>>>>>>>>>> arch/mips/kernel/process.c
>>>>>>>>>>       cpu_idle
>>>>>>>>>>
>>>>>>>>>> arch/mips/kernel/smtc.c
>>>>>>>>>>       __irq_entry
>>>>>>>>>>       ipi_decode
>>>>>>>>>>           SMTC_CLOCK_TICK
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Enclosed are the two subsets of files for a more expert look.
>>>>>>>>>>
>>>>>>>>>> I'll try to look in more detail after Christmas.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Cheers,
>>>>>>>>>>
>>>>>>>>>> Stuart
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>


From Paul.Gortmaker@windriver.com Sun Jan  2 08:24:54 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 08:25:04 +0100 (CET)
Received: from mail.windriver.com ([147.11.1.11]:36634 "EHLO
        mail.windriver.com" rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org
        with ESMTP id S1491106Ab1ABHYy (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 08:24:54 +0100
Received: from ALA-MAIL03.corp.ad.wrs.com (ala-mail03 [147.11.57.144])
        by mail.windriver.com (8.14.3/8.14.3) with ESMTP id p027N1ea000094;
        Sat, 1 Jan 2011 23:23:01 -0800 (PST)
Received: from ala-mail06.corp.ad.wrs.com ([147.11.57.147]) by ALA-MAIL03.corp.ad.wrs.com with Microsoft SMTPSVC(6.0.3790.1830);
         Sat, 1 Jan 2011 23:23:01 -0800
Received: from yow-pgortmak-d1.corp.ad.wrs.com ([128.224.146.65]) by ala-mail06.corp.ad.wrs.com with Microsoft SMTPSVC(6.0.3790.1830);
         Sat, 1 Jan 2011 23:23:01 -0800
From:   Paul Gortmaker <paul.gortmaker@windriver.com>
To:     stable@kernel.org, linux-kernel@vger.kernel.org
Cc:     stable-review@kernel.org, Ben Hutchings <ben@decadent.org.uk>,
        linux-mips@linux-mips.org, Martin Michlmayr <tbm@cyrius.com>,
        Aurelien Jarno <aurelien@aurel32.net>, 584784@bugs.debian.org,
        Ralf Baechle <ralf@linux-mips.org>,
        Paul Gortmaker <paul.gortmaker@windriver.com>
Subject: [34-longterm 156/260] MIPS: Set io_map_base for several PCI bridges lacking it
Date:   Sun,  2 Jan 2011 02:17:32 -0500
Message-Id: <1293952756-15010-157-git-send-email-paul.gortmaker@windriver.com>
X-Mailer: git-send-email 1.7.3.3
In-Reply-To: <1293952756-15010-1-git-send-email-paul.gortmaker@windriver.com>
References: <1293952756-15010-1-git-send-email-paul.gortmaker@windriver.com>
X-OriginalArrivalTime: 02 Jan 2011 07:23:01.0681 (UTC) FILETIME=[E3892210:01CBAA4D]
Return-Path: <Paul.Gortmaker@windriver.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: 28782
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: paul.gortmaker@windriver.com
Precedence: bulk
X-list: linux-mips

From: Ben Hutchings <ben@decadent.org.uk>

commit 8faf2e6c201d95b780cd3b4674b7a55ede6dcbbb upstream.

Several MIPS platforms don't set pci_controller::io_map_base for their
PCI bridges.  This results in a panic in pci_iomap().  (The panic is
conditional on CONFIG_PCI_DOMAINS, but that is now enabled for all PCI
MIPS systems.)

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Cc: linux-mips@linux-mips.org
Cc: Martin Michlmayr <tbm@cyrius.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: 584784@bugs.debian.org
Patchwork: https://patchwork.linux-mips.org/patch/1377/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 arch/mips/mti-malta/malta-pci.c      |    2 ++
 arch/mips/nxp/pnx8550/common/pci.c   |    1 +
 arch/mips/nxp/pnx8550/common/setup.c |    2 +-
 arch/mips/pci/ops-pmcmsp.c           |    1 +
 arch/mips/pci/pci-yosemite.c         |    1 +
 5 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c
index 2fbfa1a..bf80921 100644
--- a/arch/mips/mti-malta/malta-pci.c
+++ b/arch/mips/mti-malta/malta-pci.c
@@ -247,6 +247,8 @@ void __init mips_pcibios_init(void)
 	iomem_resource.end &= 0xfffffffffULL;			/* 64 GB */
 	ioport_resource.end = controller->io_resource->end;
 
+	controller->io_map_base = mips_io_port_base;
+
 	register_pci_controller(controller);
 }
 
diff --git a/arch/mips/nxp/pnx8550/common/pci.c b/arch/mips/nxp/pnx8550/common/pci.c
index eee4f3d..98e86dd 100644
--- a/arch/mips/nxp/pnx8550/common/pci.c
+++ b/arch/mips/nxp/pnx8550/common/pci.c
@@ -44,6 +44,7 @@ extern struct pci_ops pnx8550_pci_ops;
 
 static struct pci_controller pnx8550_controller = {
 	.pci_ops	= &pnx8550_pci_ops,
+	.io_map_base	= PNX8550_PORT_BASE,
 	.io_resource	= &pci_io_resource,
 	.mem_resource	= &pci_mem_resource,
 };
diff --git a/arch/mips/nxp/pnx8550/common/setup.c b/arch/mips/nxp/pnx8550/common/setup.c
index 2aed50f..64246c9 100644
--- a/arch/mips/nxp/pnx8550/common/setup.c
+++ b/arch/mips/nxp/pnx8550/common/setup.c
@@ -113,7 +113,7 @@ void __init plat_mem_setup(void)
 	PNX8550_GLB2_ENAB_INTA_O = 0;
 
 	/* IO/MEM resources. */
-	set_io_port_base(KSEG1);
+	set_io_port_base(PNX8550_PORT_BASE);
 	ioport_resource.start = 0;
 	ioport_resource.end = ~0;
 	iomem_resource.start = 0;
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
index 04b3147..b7c03d8 100644
--- a/arch/mips/pci/ops-pmcmsp.c
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -944,6 +944,7 @@ static struct pci_controller msp_pci_controller = {
 	.pci_ops	= &msp_pci_ops,
 	.mem_resource	= &pci_mem_resource,
 	.mem_offset	= 0,
+	.io_map_base	= MSP_PCI_IOSPACE_BASE,
 	.io_resource	= &pci_io_resource,
 	.io_offset	= 0
 };
diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c
index 0357946..cf5e1a2 100644
--- a/arch/mips/pci/pci-yosemite.c
+++ b/arch/mips/pci/pci-yosemite.c
@@ -54,6 +54,7 @@ static int __init pmc_yosemite_setup(void)
 		panic(ioremap_failed);
 
 	set_io_port_base(io_v_base);
+	py_controller.io_map_base = io_v_base;
 	TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
 
 	ioport_resource.end = TITAN_IO_SIZE - 1;
-- 
1.7.3.3


From miloody@gmail.com Sun Jan  2 09:12:47 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 09:12:50 +0100 (CET)
Received: from mail-iy0-f177.google.com ([209.85.210.177]:58702 "EHLO
        mail-iy0-f177.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491104Ab1ABIMq (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 09:12:46 +0100
Received: by iyj21 with SMTP id 21so12392924iyj.36
        for <linux-mips@linux-mips.org>; Sun, 02 Jan 2011 00:12:40 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:mime-version:received:received:date:message-id
         :subject:from:to:content-type;
        bh=VijcTEpHKm++EOI2Q0XpO+fpUm/q2gDRTRze4/2/aZ0=;
        b=CVxXwymyu+hocHh5ZJmjvD7MqIeFfDBxhs4vV7JK9NZfTpnmYo/6NoZ4J7fnQbXmXS
         vOpllXGxKbOgXMQk+kk35KqCT5JAiXW62lXn9AZb1RFJ/BRgQn/4lQBzEEg0ItY0BMwH
         9Fl9K68gbUQc7QCWP9SjcGtyWYwTI6SlQ9tSI=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=mime-version:date:message-id:subject:from:to:content-type;
        b=ErWlb1iYbmriEjbsNOeZSA9xKdbcdgs9O6EA9mu/DVVlErFs8Ek1PBgtsOZXFM0pJf
         EUZ7f6Do7WvHbrR++S+3RdLZjLVDeHEjY8fjrNVB4nEWMDKOphwmzatv8CRUghdmgPhG
         3TiqpDuY3TFEZjbOVzI3pLfvNmBa8mY2edKWw=
MIME-Version: 1.0
Received: by 10.42.164.132 with SMTP id g4mr19576764icy.127.1293955960824;
 Sun, 02 Jan 2011 00:12:40 -0800 (PST)
Received: by 10.42.174.131 with HTTP; Sun, 2 Jan 2011 00:12:40 -0800 (PST)
Date:   Sun, 2 Jan 2011 16:12:40 +0800
Message-ID: <AANLkTims5ejcB8hmH5nE3zR5R_57oF88x=NS438ZOM3V@mail.gmail.com>
Subject: functions about dump backtrace function names in mips arch
From:   loody <miloody@gmail.com>
To:     Linux MIPS Mailing List <linux-mips@linux-mips.org>
Content-Type: text/plain; charset=ISO-8859-1
Return-Path: <miloody@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: 28783
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: miloody@gmail.com
Precedence: bulk
X-list: linux-mips

 Dear all:
 If i remember correctly, when kernel panic there is a function I can
 use to dump all the names of backtrace functions.
 I have searched arch/mips/traps.c, but I only can see the dump
 functions of cpu registers,

 If my assumption is true, would anyone tell me what the name is or
 what Doc I can looking for?
 appreciate your help,
miloody

From dengcheng.zhu@gmail.com Sun Jan  2 10:59:28 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 11:14:26 +0100 (CET)
Received: from mail-ww0-f43.google.com ([74.125.82.43]:34010 "EHLO
        mail-ww0-f43.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491102Ab1ABJ72 convert rfc822-to-8bit
        (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Sun, 2 Jan 2011 10:59:28 +0100
Received: by wwi17 with SMTP id 17so12675945wwi.24
        for <linux-mips@linux-mips.org>; Sun, 02 Jan 2011 01:59:21 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:mime-version:received:received:in-reply-to
         :references:date:message-id:subject:from:to:cc:content-type
         :content-transfer-encoding;
        bh=MAggJ9FNGjgV6OjB0u0xnM78pHkuUr2dlC9JfKfq31o=;
        b=rwCPJNgJoCwg+A5LhuCsOnGybIxaMuPEi1yZfzufHeJYGqXhjpHvB/5GAtLPeQ4om7
         fGAMfy+USiAVU6xxLeNrAAWBghuJFStNSVWrBDp+HetQY0MPwetfqE4tpcA6tErYION0
         XbwUVVDve9UvnWwFEXWqCfGDMBJKQHfz7X3tA=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=mime-version:in-reply-to:references:date:message-id:subject:from:to
         :cc:content-type:content-transfer-encoding;
        b=DbHunO4+6/OT8WFaEK6CDkebTVyl9GJROZX0a0uMWDMlxCFMnUN30FEDQR86JS9Jo0
         KjSBTa6HQAWJdhOHjxZY/0CziCb9KsDcJJl3YoT/DsVPx+TSous2oONu3NfNgBHuDLwd
         9GnuwASCvB9ItX6RXgzLI0YB0xT3Xm56vTyRs=
MIME-Version: 1.0
Received: by 10.216.177.9 with SMTP id c9mr20052715wem.34.1293962360939; Sun,
 02 Jan 2011 01:59:20 -0800 (PST)
Received: by 10.216.53.206 with HTTP; Sun, 2 Jan 2011 01:59:20 -0800 (PST)
In-Reply-To: <AANLkTims5ejcB8hmH5nE3zR5R_57oF88x=NS438ZOM3V@mail.gmail.com>
References: <AANLkTims5ejcB8hmH5nE3zR5R_57oF88x=NS438ZOM3V@mail.gmail.com>
Date:   Sun, 2 Jan 2011 17:59:20 +0800
Message-ID: <AANLkTimTXeyTdkPbSqeWDr+zGCBiz_BkCfMfh+uJXs16@mail.gmail.com>
Subject: Re: functions about dump backtrace function names in mips arch
From:   Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
To:     loody <miloody@gmail.com>
Cc:     Linux MIPS Mailing List <linux-mips@linux-mips.org>
Content-Type: text/plain; charset=GB2312
Content-Transfer-Encoding: 8BIT
Return-Path: <dengcheng.zhu@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: 28784
X-Approved-By: ralf@linux-mips.org
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: dengcheng.zhu@gmail.com
Precedence: bulk
X-list: linux-mips

stacktrace.c?


ÔÚ 2011Äê1ÔÂ2ÈÕÐÇÆÚÈÕ£¬loody <miloody@gmail.com> Ð´µÀ£º
>  Dear all:
>  If i remember correctly, when kernel panic there is a function I can
>  use to dump all the names of backtrace functions.
>  I have searched arch/mips/traps.c, but I only can see the dump
>  functions of cpu registers,
>
>  If my assumption is true, would anyone tell me what the name is or
>  what Doc I can looking for?
>  appreciate your help,
> miloody
>
>

From miloody@gmail.com Sun Jan  2 13:32:29 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 13:32:32 +0100 (CET)
Received: from mail-iw0-f177.google.com ([209.85.214.177]:51444 "EHLO
        mail-iw0-f177.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491915Ab1ABMc3 (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 13:32:29 +0100
Received: by iwn38 with SMTP id 38so13759885iwn.36
        for <linux-mips@linux-mips.org>; Sun, 02 Jan 2011 04:32:26 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:mime-version:received:received:date:message-id
         :subject:from:to:cc:content-type;
        bh=HAr1kLxwjh0BSZy2euVDBKqLV2XrVe19WO7MzqBQopk=;
        b=cHaMkgVTnyCkXRZW8CAsNiueD8ytgyMbLMEBXobe/ozHomyN76+SaHI+lF7eq30WxA
         w5wFppsb1je7X4vGqlhvHAj8nnN1jU4DTfruk3dUanRl/90LG2qwhQzeZbmdr7PeXnav
         gQSBx1E2b2QovPX7o2GaZsrCJjouaqoLkHi5k=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=mime-version:date:message-id:subject:from:to:cc:content-type;
        b=BrcCScy8yqLeJEGwvjp8Tixqc+NUdfyMAoxW2rSEvFYuq3NKx4s6/wvYakp/oRyq2m
         SDzA8dcuQfqkcVhTFP9NvFp53pTei7BLAlK+KhWWBjmDd6eQp2hQgiymkd9FB1DISr/n
         CHwKhjix16Z56FWT/OB8SIyiMKk5V7+WxMn0o=
MIME-Version: 1.0
Received: by 10.42.177.137 with SMTP id bi9mr19748573icb.194.1293971546455;
 Sun, 02 Jan 2011 04:32:26 -0800 (PST)
Received: by 10.42.174.131 with HTTP; Sun, 2 Jan 2011 04:32:26 -0800 (PST)
Date:   Sun, 2 Jan 2011 20:32:26 +0800
Message-ID: <AANLkTinBYUHdsaz40216BRadvU3mx2H5F4Hfp1J0NibB@mail.gmail.com>
Subject: is there dummy r/w in mips kernel API
From:   loody <miloody@gmail.com>
To:     Linux MIPS Mailing List <linux-mips@linux-mips.org>
Cc:     linux-usb@vger.kernel.org
Content-Type: text/plain; charset=ISO-8859-1
Return-Path: <miloody@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: 28785
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: miloody@gmail.com
Precedence: bulk
X-list: linux-mips

Dear all:
I am trying porting usb on mips platform.
Due to hw limitation, I have to do the dummy read to make sure data
has been written to the memory, so I announce an volatile parameter,
tmp, such that cpu will read the same address back to me.

Below is what I try to do in usb driver:
                        wmb ();
    389c:       0000000f        sync
                        dummy->hw_token = token;
    38a0:       ae740008        sw      s4,8(s3)
                        tmp = dummy->hw_token;
    38a4:       afb40010        sw      s4,16(sp)
as you can see, the compiler is so smart that he read the register
content instead of re-read the memory for accelerating the read speed.
unfortunately, that isn't I want. Is there already exist kernel API can help me?
appreciate your help,
miloody

From stern+4d39b18a@rowland.harvard.edu Sun Jan  2 15:49:11 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 15:49:14 +0100 (CET)
Received: from netrider.rowland.org ([192.131.102.5]:42702 "HELO
        netrider.rowland.org" rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org
        with SMTP id S1491926Ab1ABOtL (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 15:49:11 +0100
Received: (qmail 23228 invoked by uid 500); 2 Jan 2011 09:49:01 -0500
Received: from localhost (sendmail-bs@127.0.0.1)
  by localhost with SMTP; 2 Jan 2011 09:49:01 -0500
Date:   Sun, 2 Jan 2011 09:49:01 -0500 (EST)
From:   Alan Stern <stern@rowland.harvard.edu>
X-X-Sender: stern@netrider.rowland.org
To:     loody <miloody@gmail.com>
cc:     Linux MIPS Mailing List <linux-mips@linux-mips.org>,
        <linux-usb@vger.kernel.org>
Subject: Re: is there dummy r/w in mips kernel API
In-Reply-To: <AANLkTinBYUHdsaz40216BRadvU3mx2H5F4Hfp1J0NibB@mail.gmail.com>
Message-ID: <Pine.LNX.4.44L0.1101020948030.22996-100000@netrider.rowland.org>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Return-Path: <stern+4d39b18a@rowland.harvard.edu>
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: 28786
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: stern@rowland.harvard.edu
Precedence: bulk
X-list: linux-mips

On Sun, 2 Jan 2011, loody wrote:

> Dear all:
> I am trying porting usb on mips platform.
> Due to hw limitation, I have to do the dummy read to make sure data
> has been written to the memory, so I announce an volatile parameter,
> tmp, such that cpu will read the same address back to me.
> 
> Below is what I try to do in usb driver:
>                         wmb ();
>     389c:       0000000f        sync
>                         dummy->hw_token = token;
>     38a0:       ae740008        sw      s4,8(s3)
>                         tmp = dummy->hw_token;
>     38a4:       afb40010        sw      s4,16(sp)
> as you can see, the compiler is so smart that he read the register
> content instead of re-read the memory for accelerating the read speed.
> unfortunately, that isn't I want. Is there already exist kernel API can help me?
> appreciate your help,

You can try doing:

		tmp = ACCESS_ONCE(dummy->hw_token);

Alan Stern


From juhosg@openwrt.org Sun Jan  2 19:56:48 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 19:56:51 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43333 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491940Ab1ABS4s (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:48 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id D2B913FC039;
        Sun,  2 Jan 2011 19:56:42 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id ED5341F0001;
        Sun,  2 Jan 2011 19:56:41 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs
Date:   Sun,  2 Jan 2011 19:56:13 +0100
Message-Id: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
X-VBMS: A17EB994FD9 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28787
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch set contains initial support for the 
Atheros AR71XX/AR724X/AR913X SoCs.

Generic changes since v1:
    - rebased against 2.6.37-rc7
    - the 'MIPS: Add generic support for multiple machines within a single kernel' 
      patch has been removed, because that is in the mips-queue tree already
    - the 'input: add input driver for polled GPIO buttons' patch has been removed, 
      because a slightly different version of that driver is present in 2.6.37-rc7 
      already as 'gpio_keys_polled'

Generic changes since v2:
    - don't use __init for function declarations

Generic changes since v3:
    - rebased against 2.6.37-rc8

Gabor Juhos (16):
  MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs
  MIPS: ath79: add GPIOLIB support
  MIPS: ath79: utilize the MIPS multi-machine support
  MIPS: ath79: add initial support for the Atheros PB44 reference board
  MIPS: ath79: add common GPIO LEDs device
  watchdog: add driver for the Atheros AR71XX/AR724X/AR913X SoCs
  MIPS: ath79: add common watchdog device
  MIPS: ath79: add common GPIO buttons device
  spi: add SPI controller driver for the Atheros AR71XX/AR724X/AR913X
    SoCs
  MIPS: ath79: add common SPI controller device
  USB: ehci: add workaround for Synopsys HC bug
  USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR913X SoCs
  USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs
  MIPS: ath79: add common USB Host Controller device
  MIPS: ath79: add initial support for the Atheros AP81 reference board
  MIPS: ath79: add common WMAC device for AR913X based boards

 arch/mips/Kbuild.platforms                         |    1 +
 arch/mips/Kconfig                                  |   17 ++
 arch/mips/ath79/Kconfig                            |   60 ++++
 arch/mips/ath79/Makefile                           |   29 ++
 arch/mips/ath79/Platform                           |    7 +
 arch/mips/ath79/common.c                           |   97 +++++++
 arch/mips/ath79/common.h                           |   30 ++
 arch/mips/ath79/dev-ar913x-wmac.c                  |   60 ++++
 arch/mips/ath79/dev-ar913x-wmac.h                  |   17 ++
 arch/mips/ath79/dev-common.c                       |   69 +++++
 arch/mips/ath79/dev-common.h                       |   18 ++
 arch/mips/ath79/dev-gpio-buttons.c                 |   58 ++++
 arch/mips/ath79/dev-gpio-buttons.h                 |   23 ++
 arch/mips/ath79/dev-leds-gpio.c                    |   56 ++++
 arch/mips/ath79/dev-leds-gpio.h                    |   21 ++
 arch/mips/ath79/dev-spi.c                          |   38 +++
 arch/mips/ath79/dev-spi.h                          |   22 ++
 arch/mips/ath79/dev-usb.c                          |  194 +++++++++++++
 arch/mips/ath79/dev-usb.h                          |   17 ++
 arch/mips/ath79/early_printk.c                     |   36 +++
 arch/mips/ath79/gpio.c                             |  197 +++++++++++++
 arch/mips/ath79/irq.c                              |  187 +++++++++++++
 arch/mips/ath79/mach-ap81.c                        |  100 +++++++
 arch/mips/ath79/mach-pb44.c                        |  120 ++++++++
 arch/mips/ath79/machtypes.h                        |   23 ++
 arch/mips/ath79/prom.c                             |   57 ++++
 arch/mips/ath79/setup.c                            |  279 +++++++++++++++++++
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h     |  253 +++++++++++++++++
 arch/mips/include/asm/mach-ath79/ath79.h           |  100 +++++++
 .../include/asm/mach-ath79/ath79_ehci_platform.h   |   18 ++
 .../include/asm/mach-ath79/ath79_spi_platform.h    |   19 ++
 .../include/asm/mach-ath79/cpu-feature-overrides.h |   56 ++++
 arch/mips/include/asm/mach-ath79/gpio.h            |   26 ++
 arch/mips/include/asm/mach-ath79/irq.h             |   36 +++
 .../include/asm/mach-ath79/kernel-entry-init.h     |   32 +++
 arch/mips/include/asm/mach-ath79/war.h             |   25 ++
 drivers/spi/Kconfig                                |    8 +
 drivers/spi/Makefile                               |    1 +
 drivers/spi/ath79_spi.c                            |  290 ++++++++++++++++++++
 drivers/usb/host/Kconfig                           |   16 +
 drivers/usb/host/ehci-ath79.c                      |  176 ++++++++++++
 drivers/usb/host/ehci-hcd.c                        |    5 +
 drivers/usb/host/ehci-q.c                          |    3 +
 drivers/usb/host/ehci.h                            |    1 +
 drivers/usb/host/ohci-ath79.c                      |  162 +++++++++++
 drivers/usb/host/ohci-hcd.c                        |    5 +
 drivers/watchdog/Kconfig                           |    7 +
 drivers/watchdog/Makefile                          |    1 +
 drivers/watchdog/ath79_wdt.c                       |  283 +++++++++++++++++++
 49 files changed, 3356 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/Kconfig
 create mode 100644 arch/mips/ath79/Makefile
 create mode 100644 arch/mips/ath79/Platform
 create mode 100644 arch/mips/ath79/common.c
 create mode 100644 arch/mips/ath79/common.h
 create mode 100644 arch/mips/ath79/dev-ar913x-wmac.c
 create mode 100644 arch/mips/ath79/dev-ar913x-wmac.h
 create mode 100644 arch/mips/ath79/dev-common.c
 create mode 100644 arch/mips/ath79/dev-common.h
 create mode 100644 arch/mips/ath79/dev-gpio-buttons.c
 create mode 100644 arch/mips/ath79/dev-gpio-buttons.h
 create mode 100644 arch/mips/ath79/dev-leds-gpio.c
 create mode 100644 arch/mips/ath79/dev-leds-gpio.h
 create mode 100644 arch/mips/ath79/dev-spi.c
 create mode 100644 arch/mips/ath79/dev-spi.h
 create mode 100644 arch/mips/ath79/dev-usb.c
 create mode 100644 arch/mips/ath79/dev-usb.h
 create mode 100644 arch/mips/ath79/early_printk.c
 create mode 100644 arch/mips/ath79/gpio.c
 create mode 100644 arch/mips/ath79/irq.c
 create mode 100644 arch/mips/ath79/mach-ap81.c
 create mode 100644 arch/mips/ath79/mach-pb44.c
 create mode 100644 arch/mips/ath79/machtypes.h
 create mode 100644 arch/mips/ath79/prom.c
 create mode 100644 arch/mips/ath79/setup.c
 create mode 100644 arch/mips/include/asm/mach-ath79/ar71xx_regs.h
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79.h
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
 create mode 100644 arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
 create mode 100644 arch/mips/include/asm/mach-ath79/gpio.h
 create mode 100644 arch/mips/include/asm/mach-ath79/irq.h
 create mode 100644 arch/mips/include/asm/mach-ath79/kernel-entry-init.h
 create mode 100644 arch/mips/include/asm/mach-ath79/war.h
 create mode 100644 drivers/spi/ath79_spi.c
 create mode 100644 drivers/usb/host/ehci-ath79.c
 create mode 100644 drivers/usb/host/ohci-ath79.c
 create mode 100644 drivers/watchdog/ath79_wdt.c

-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 19:57:10 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 19:57:19 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43339 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491941Ab1ABS4t (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:49 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 1303C3FC03B;
        Sun,  2 Jan 2011 19:56:44 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 9E2D41F0001;
        Sun,  2 Jan 2011 19:56:42 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 01/16] MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs
Date:   Sun,  2 Jan 2011 19:56:14 +0100
Message-Id: <1293994589-6794-2-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17EBF9572B | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28788
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds initial support for various Atheros SoCs based on the
MIPS 24Kc core. The following models are supported at the moment:

  - AR7130
  - AR7141
  - AR7161
  - AR9130
  - AR9132
  - AR7240
  - AR7241
  - AR7242

The current patch contains minimal support only, but the resulting
kernel can boot into user-space with using of an initramfs image on
various boards which are using these SoCs. Support for more built-in
devices and individual boards will be implemented in further patches.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC:
    - the ATH79_DEV_UART Kconfig option is removed, and the URT platform
      code has been moved into dev-common[ch]

Changes since v1:
    - ath79_device_{start,stop} has been renamed to ath79_device_reset_{set,clear}
      to to reflect the purpose of these functions better
    - some definitions has been moved from 'arch/mips/ath79/common.h' to
      'arch/mips/include/asm/mach-ath79/ath79.h' to make them available for
      future drivers
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebase against 2.6.37-rc8

 arch/mips/Kbuild.platforms                         |    1 +
 arch/mips/Kconfig                                  |   15 ++
 arch/mips/ath79/Kconfig                            |   12 +
 arch/mips/ath79/Makefile                           |   18 ++
 arch/mips/ath79/Platform                           |    7 +
 arch/mips/ath79/common.c                           |   97 +++++++
 arch/mips/ath79/common.h                           |   25 ++
 arch/mips/ath79/dev-common.c                       |   59 +++++
 arch/mips/ath79/dev-common.h                       |   17 ++
 arch/mips/ath79/early_printk.c                     |   36 +++
 arch/mips/ath79/irq.c                              |  187 ++++++++++++++
 arch/mips/ath79/prom.c                             |   57 +++++
 arch/mips/ath79/setup.c                            |  263 ++++++++++++++++++++
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h     |  207 +++++++++++++++
 arch/mips/include/asm/mach-ath79/ath79.h           |  100 ++++++++
 .../include/asm/mach-ath79/cpu-feature-overrides.h |   56 ++++
 arch/mips/include/asm/mach-ath79/irq.h             |   36 +++
 .../include/asm/mach-ath79/kernel-entry-init.h     |   32 +++
 arch/mips/include/asm/mach-ath79/war.h             |   25 ++
 19 files changed, 1250 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/Kconfig
 create mode 100644 arch/mips/ath79/Makefile
 create mode 100644 arch/mips/ath79/Platform
 create mode 100644 arch/mips/ath79/common.c
 create mode 100644 arch/mips/ath79/common.h
 create mode 100644 arch/mips/ath79/dev-common.c
 create mode 100644 arch/mips/ath79/dev-common.h
 create mode 100644 arch/mips/ath79/early_printk.c
 create mode 100644 arch/mips/ath79/irq.c
 create mode 100644 arch/mips/ath79/prom.c
 create mode 100644 arch/mips/ath79/setup.c
 create mode 100644 arch/mips/include/asm/mach-ath79/ar71xx_regs.h
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79.h
 create mode 100644 arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
 create mode 100644 arch/mips/include/asm/mach-ath79/irq.h
 create mode 100644 arch/mips/include/asm/mach-ath79/kernel-entry-init.h
 create mode 100644 arch/mips/include/asm/mach-ath79/war.h

diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 78439b8..7ff9b54 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -2,6 +2,7 @@
 
 platforms += alchemy
 platforms += ar7
+platforms += ath79
 platforms += bcm47xx
 platforms += bcm63xx
 platforms += cavium-octeon
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 12d0d0f..2e32137 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -66,6 +66,20 @@ config AR7
 	  Support for the Texas Instruments AR7 System-on-a-Chip
 	  family: TNETD7100, 7200 and 7300.
 
+config ATH79
+	bool "Atheros AR71XX/AR724X/AR913X based boards"
+	select BOOT_RAW
+	select CEVT_R4K
+	select CSRC_R4K
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_HAS_EARLY_PRINTK
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+	help
+	  Support for the Atheros AR71XX/AR724X/AR913X SoCs.
+
 config BCM47XX
 	bool "Broadcom BCM47XX based boards"
 	select CEVT_R4K
@@ -718,6 +732,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
 endchoice
 
 source "arch/mips/alchemy/Kconfig"
+source "arch/mips/ath79/Kconfig"
 source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
new file mode 100644
index 0000000..50b9334
--- /dev/null
+++ b/arch/mips/ath79/Kconfig
@@ -0,0 +1,12 @@
+if ATH79
+
+config SOC_AR71XX
+	def_bool n
+
+config SOC_AR724X
+	def_bool n
+
+config SOC_AR913X
+	def_bool n
+
+endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
new file mode 100644
index 0000000..b4ec9c2
--- /dev/null
+++ b/arch/mips/ath79/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the Atheros AR71XX/AR724X/AR913X specific parts of the kernel
+#
+# Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+
+obj-y	:= prom.o setup.o irq.o common.o
+
+obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
+
+#
+# Devices
+#
+obj-y					+= dev-common.o
diff --git a/arch/mips/ath79/Platform b/arch/mips/ath79/Platform
new file mode 100644
index 0000000..2bd6636
--- /dev/null
+++ b/arch/mips/ath79/Platform
@@ -0,0 +1,7 @@
+#
+# Atheros AR71xx/AR724x/AR913x
+#
+
+platform-$(CONFIG_ATH79)	+= ath79/
+cflags-$(CONFIG_ATH79)		+= -I$(srctree)/arch/mips/include/asm/mach-ath79
+load-$(CONFIG_ATH79)		= 0xffffffff80060000
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
new file mode 100644
index 0000000..58f60e7
--- /dev/null
+++ b/arch/mips/ath79/common.c
@@ -0,0 +1,97 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common routines
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static DEFINE_SPINLOCK(ath79_device_reset_lock);
+
+u32 ath79_cpu_freq;
+EXPORT_SYMBOL_GPL(ath79_cpu_freq);
+
+u32 ath79_ahb_freq;
+EXPORT_SYMBOL_GPL(ath79_ahb_freq);
+
+u32 ath79_ddr_freq;
+EXPORT_SYMBOL_GPL(ath79_ddr_freq);
+
+enum ath79_soc_type ath79_soc;
+
+void __iomem *ath79_pll_base;
+void __iomem *ath79_reset_base;
+EXPORT_SYMBOL_GPL(ath79_reset_base);
+void __iomem *ath79_ddr_base;
+
+void ath79_ddr_wb_flush(u32 reg)
+{
+	void __iomem *flush_reg = ath79_ddr_base + reg;
+
+	/* Flush the DDR write buffer. */
+	__raw_writel(0x1, flush_reg);
+	while (__raw_readl(flush_reg) & 0x1)
+		;
+
+	/* It must be run twice. */
+	__raw_writel(0x1, flush_reg);
+	while (__raw_readl(flush_reg) & 0x1)
+		;
+}
+EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush);
+
+void ath79_device_reset_set(u32 mask)
+{
+	unsigned long flags;
+	u32 reg;
+	u32 t;
+
+	if (soc_is_ar71xx())
+		reg = AR71XX_RESET_REG_RESET_MODULE;
+	else if (soc_is_ar724x())
+		reg = AR724X_RESET_REG_RESET_MODULE;
+	else if (soc_is_ar913x())
+		reg = AR913X_RESET_REG_RESET_MODULE;
+	else
+		BUG();
+
+	spin_lock_irqsave(&ath79_device_reset_lock, flags);
+	t = ath79_reset_rr(reg);
+	ath79_reset_wr(reg, t | mask);
+	spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_set);
+
+void ath79_device_reset_clear(u32 mask)
+{
+	unsigned long flags;
+	u32 reg;
+	u32 t;
+
+	if (soc_is_ar71xx())
+		reg = AR71XX_RESET_REG_RESET_MODULE;
+	else if (soc_is_ar724x())
+		reg = AR724X_RESET_REG_RESET_MODULE;
+	else if (soc_is_ar913x())
+		reg = AR913X_RESET_REG_RESET_MODULE;
+	else
+		BUG();
+
+	spin_lock_irqsave(&ath79_device_reset_lock, flags);
+	t = ath79_reset_rr(reg);
+	ath79_reset_wr(reg, t & ~mask);
+	spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_clear);
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
new file mode 100644
index 0000000..a1bcdbb
--- /dev/null
+++ b/arch/mips/ath79/common.h
@@ -0,0 +1,25 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef __ATH79_COMMON_H
+#define __ATH79_COMMON_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#define ATH79_MEM_SIZE_MIN	(2 * 1024 * 1024)
+#define ATH79_MEM_SIZE_MAX	(128 * 1024 * 1024)
+
+void ath79_ddr_wb_flush(unsigned int reg);
+
+#endif /* __ATH79_COMMON_H */
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
new file mode 100644
index 0000000..897522c
--- /dev/null
+++ b/arch/mips/ath79/dev-common.c
@@ -0,0 +1,59 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common devices
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+
+static struct resource ath79_uart_resources[] = {
+	{
+		.start	= AR71XX_UART_BASE,
+		.end	= AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+static struct plat_serial8250_port ath79_uart_data[] = {
+	{
+		.mapbase	= AR71XX_UART_BASE,
+		.irq		= ATH79_MISC_IRQ_UART,
+		.flags		= AR71XX_UART_FLAGS,
+		.iotype		= UPIO_MEM32,
+		.regshift	= 2,
+	}, {
+		/* terminating entry */
+	}
+};
+
+static struct platform_device ath79_uart_device = {
+	.name		= "serial8250",
+	.id		= PLAT8250_DEV_PLATFORM,
+	.resource	= ath79_uart_resources,
+	.num_resources	= ARRAY_SIZE(ath79_uart_resources),
+	.dev = {
+		.platform_data	= ath79_uart_data
+	},
+};
+
+void __init ath79_register_uart(void)
+{
+	ath79_uart_data[0].uartclk = ath79_ahb_freq;
+	platform_device_register(&ath79_uart_device);
+}
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
new file mode 100644
index 0000000..248622c
--- /dev/null
+++ b/arch/mips/ath79/dev-common.h
@@ -0,0 +1,17 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common devices
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_COMMON_H
+#define _ATH79_DEV_COMMON_H
+
+void ath79_register_uart(void);
+
+#endif /* _ATH79_DEV_COMMON_H */
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
new file mode 100644
index 0000000..7499b0e
--- /dev/null
+++ b/arch/mips/ath79/early_printk.c
@@ -0,0 +1,36 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X SoC early printk support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+#include <asm/addrspace.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+static inline void prom_wait_thre(void __iomem *base)
+{
+	u32 lsr;
+
+	do {
+		lsr = __raw_readl(base + UART_LSR * 4);
+		if (lsr & UART_LSR_THRE)
+			break;
+	} while (1);
+}
+
+void prom_putchar(unsigned char ch)
+{
+	void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
+
+	prom_wait_thre(base);
+	__raw_writel(ch, base + UART_TX * 4);
+	prom_wait_thre(base);
+}
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
new file mode 100644
index 0000000..1bf7f71
--- /dev/null
+++ b/arch/mips/ath79/irq.c
@@ -0,0 +1,187 @@
+/*
+ *  Atheros AR71xx/AR724x/AR913x specific interrupt handling
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static unsigned int ath79_ip2_flush_reg;
+static unsigned int ath79_ip3_flush_reg;
+
+static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	void __iomem *base = ath79_reset_base;
+	u32 pending;
+
+	pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
+		  __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	if (pending & MISC_INT_UART)
+		generic_handle_irq(ATH79_MISC_IRQ_UART);
+
+	else if (pending & MISC_INT_DMA)
+		generic_handle_irq(ATH79_MISC_IRQ_DMA);
+
+	else if (pending & MISC_INT_PERFC)
+		generic_handle_irq(ATH79_MISC_IRQ_PERFC);
+
+	else if (pending & MISC_INT_TIMER)
+		generic_handle_irq(ATH79_MISC_IRQ_TIMER);
+
+	else if (pending & MISC_INT_OHCI)
+		generic_handle_irq(ATH79_MISC_IRQ_OHCI);
+
+	else if (pending & MISC_INT_ERROR)
+		generic_handle_irq(ATH79_MISC_IRQ_ERROR);
+
+	else if (pending & MISC_INT_GPIO)
+		generic_handle_irq(ATH79_MISC_IRQ_GPIO);
+
+	else if (pending & MISC_INT_WDOG)
+		generic_handle_irq(ATH79_MISC_IRQ_WDOG);
+
+	else
+		spurious_interrupt();
+}
+
+static void ar71xx_misc_irq_unmask(unsigned int irq)
+{
+	void __iomem *base = ath79_reset_base;
+	u32 t;
+
+	irq -= ATH79_MISC_IRQ_BASE;
+
+	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+	__raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	/* flush write */
+	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar71xx_misc_irq_mask(unsigned int irq)
+{
+	void __iomem *base = ath79_reset_base;
+	u32 t;
+
+	irq -= ATH79_MISC_IRQ_BASE;
+
+	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+	__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	/* flush write */
+	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar724x_misc_irq_ack(unsigned int irq)
+{
+	void __iomem *base = ath79_reset_base;
+	u32 t;
+
+	irq -= ATH79_MISC_IRQ_BASE;
+
+	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+	__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+	/* flush write */
+	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+}
+
+static struct irq_chip ath79_misc_irq_chip = {
+	.name		= "MISC",
+	.unmask		= ar71xx_misc_irq_unmask,
+	.mask		= ar71xx_misc_irq_mask,
+};
+
+static void __init ath79_misc_irq_init(void)
+{
+	void __iomem *base = ath79_reset_base;
+	int i;
+
+	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+	if (soc_is_ar71xx() || soc_is_ar913x())
+		ath79_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask;
+	else if (soc_is_ar724x())
+		ath79_misc_irq_chip.ack = ar724x_misc_irq_ack;
+	else
+		BUG();
+
+	for (i = ATH79_MISC_IRQ_BASE;
+	     i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		set_irq_chip_and_handler(i, &ath79_misc_irq_chip,
+					 handle_level_irq);
+	}
+
+	set_irq_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned long pending;
+
+	pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+	if (pending & STATUSF_IP7)
+		do_IRQ(ATH79_CPU_IRQ_TIMER);
+
+	else if (pending & STATUSF_IP2) {
+		ath79_ddr_wb_flush(ath79_ip2_flush_reg);
+		do_IRQ(ATH79_CPU_IRQ_IP2);
+	}
+
+	else if (pending & STATUSF_IP4)
+		do_IRQ(ATH79_CPU_IRQ_GE0);
+
+	else if (pending & STATUSF_IP5)
+		do_IRQ(ATH79_CPU_IRQ_GE1);
+
+	else if (pending & STATUSF_IP3) {
+		ath79_ddr_wb_flush(ath79_ip3_flush_reg);
+		do_IRQ(ATH79_CPU_IRQ_USB);
+	}
+
+	else if (pending & STATUSF_IP6)
+		do_IRQ(ATH79_CPU_IRQ_MISC);
+
+	else
+		spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+	if (soc_is_ar71xx()) {
+		ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
+		ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB;
+	} else if (soc_is_ar724x()) {
+		ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
+		ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB;
+	} else if (soc_is_ar913x()) {
+		ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
+		ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
+	} else
+		BUG();
+
+	cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
+	mips_cpu_irq_init();
+	ath79_misc_irq_init();
+}
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c
new file mode 100644
index 0000000..e9cbd7c
--- /dev/null
+++ b/arch/mips/ath79/prom.c
@@ -0,0 +1,57 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X specific prom routines
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+#include "common.h"
+
+static inline int is_valid_ram_addr(void *addr)
+{
+	if (((u32) addr > KSEG0) &&
+	    ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX)))
+		return 1;
+
+	if (((u32) addr > KSEG1) &&
+	    ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX)))
+		return 1;
+
+	return 0;
+}
+
+static __init void ath79_prom_init_cmdline(int argc, char **argv)
+{
+	int i;
+
+	if (!is_valid_ram_addr(argv))
+		return;
+
+	for (i = 0; i < argc; i++)
+		if (is_valid_ram_addr(argv[i])) {
+			strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+			strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
+		}
+}
+
+void __init prom_init(void)
+{
+	ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
+}
+
+void __init prom_free_prom_memory(void)
+{
+	/* We do not have to prom memory to free */
+}
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
new file mode 100644
index 0000000..4157ddc
--- /dev/null
+++ b/arch/mips/ath79/setup.c
@@ -0,0 +1,263 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X specific setup
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h>		/* for mips_hpt_frequency */
+#include <asm/reboot.h>		/* for _machine_{restart,halt} */
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+
+#define ATH79_SYS_TYPE_LEN	64
+
+#define AR71XX_BASE_FREQ	40000000
+#define AR724X_BASE_FREQ	5000000
+#define AR913X_BASE_FREQ	5000000
+
+static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
+
+static void ath79_restart(char *command)
+{
+	ath79_device_reset_set(AR71XX_RESET_FULL_CHIP);
+	for (;;)
+		if (cpu_wait)
+			cpu_wait();
+}
+
+static void ath79_halt(void)
+{
+	while (1)
+		cpu_wait();
+}
+
+static void __init ath79_detect_mem_size(void)
+{
+	unsigned long size;
+
+	for (size = ATH79_MEM_SIZE_MIN; size < ATH79_MEM_SIZE_MAX;
+	     size <<= 1) {
+		if (!memcmp(ath79_detect_mem_size,
+			    ath79_detect_mem_size + size, 1024))
+			break;
+	}
+
+	add_memory_region(0, size, BOOT_MEM_RAM);
+}
+
+static void __init ath79_detect_sys_type(void)
+{
+	char *chip = "????";
+	u32 id;
+	u32 major;
+	u32 minor;
+	u32 rev = 0;
+
+	id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
+	major = id & REV_ID_MAJOR_MASK;
+
+	switch (major) {
+	case REV_ID_MAJOR_AR71XX:
+		minor = id & AR71XX_REV_ID_MINOR_MASK;
+		rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
+		rev &= AR71XX_REV_ID_REVISION_MASK;
+		switch (minor) {
+		case AR71XX_REV_ID_MINOR_AR7130:
+			ath79_soc = ATH79_SOC_AR7130;
+			chip = "7130";
+			break;
+
+		case AR71XX_REV_ID_MINOR_AR7141:
+			ath79_soc = ATH79_SOC_AR7141;
+			chip = "7141";
+			break;
+
+		case AR71XX_REV_ID_MINOR_AR7161:
+			ath79_soc = ATH79_SOC_AR7161;
+			chip = "7161";
+			break;
+		}
+		break;
+
+	case REV_ID_MAJOR_AR7240:
+		ath79_soc = ATH79_SOC_AR7240;
+		chip = "7240";
+		rev = (id & AR724X_REV_ID_REVISION_MASK);
+		break;
+
+	case REV_ID_MAJOR_AR7241:
+		ath79_soc = ATH79_SOC_AR7241;
+		chip = "7241";
+		rev = (id & AR724X_REV_ID_REVISION_MASK);
+		break;
+
+	case REV_ID_MAJOR_AR7242:
+		ath79_soc = ATH79_SOC_AR7242;
+		chip = "7242";
+		rev = (id & AR724X_REV_ID_REVISION_MASK);
+		break;
+
+	case REV_ID_MAJOR_AR913X:
+		minor = id & AR913X_REV_ID_MINOR_MASK;
+		rev = id >> AR913X_REV_ID_REVISION_SHIFT;
+		rev &= AR913X_REV_ID_REVISION_MASK;
+		switch (minor) {
+		case AR913X_REV_ID_MINOR_AR9130:
+			ath79_soc = ATH79_SOC_AR9130;
+			chip = "9130";
+			break;
+
+		case AR913X_REV_ID_MINOR_AR9132:
+			ath79_soc = ATH79_SOC_AR9132;
+			chip = "9132";
+			break;
+		}
+		break;
+
+	default:
+		panic("ath79: unknown SoC, id:0x%08x\n", id);
+	}
+
+	sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
+}
+
+static void __init ar71xx_detect_sys_frequency(void)
+{
+	u32 pll;
+	u32 freq;
+	u32 div;
+
+	pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
+
+	div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
+	freq = div * AR71XX_BASE_FREQ;
+
+	div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
+	ath79_cpu_freq = freq / div;
+
+	div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
+	ath79_ddr_freq = freq / div;
+
+	div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
+	ath79_ahb_freq = ath79_cpu_freq / div;
+}
+
+static void __init ar724x_detect_sys_frequency(void)
+{
+	u32 pll;
+	u32 freq;
+	u32 div;
+
+	pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
+
+	div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
+	freq = div * AR724X_BASE_FREQ;
+
+	div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
+	freq *= div;
+
+	ath79_cpu_freq = freq;
+
+	div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
+	ath79_ddr_freq = freq / div;
+
+	div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
+	ath79_ahb_freq = ath79_cpu_freq / div;
+}
+
+static void __init ar913x_detect_sys_frequency(void)
+{
+	u32 pll;
+	u32 freq;
+	u32 div;
+
+	pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
+
+	div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK);
+	freq = div * AR913X_BASE_FREQ;
+
+	ath79_cpu_freq = freq;
+
+	div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1;
+	ath79_ddr_freq = freq / div;
+
+	div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2;
+	ath79_ahb_freq = ath79_cpu_freq / div;
+}
+
+static void __init ath79_detect_sys_frequency(void)
+{
+	if (soc_is_ar71xx())
+		ar71xx_detect_sys_frequency();
+	else if (soc_is_ar724x())
+		ar724x_detect_sys_frequency();
+	else if (soc_is_ar913x())
+		ar913x_detect_sys_frequency();
+	else
+		BUG();
+}
+
+const char *get_system_type(void)
+{
+	return ath79_sys_type;
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+	return CP0_LEGACY_COMPARE_IRQ;
+}
+
+void __init plat_mem_setup(void)
+{
+	set_io_port_base(KSEG1);
+
+	ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
+					   AR71XX_RESET_SIZE);
+	ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
+					 AR71XX_PLL_SIZE);
+
+	ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
+					 AR71XX_DDR_CTRL_SIZE);
+
+	ath79_detect_sys_type();
+	ath79_detect_mem_size();
+	ath79_detect_sys_frequency();
+
+	pr_info("SoC: %s, CPU:%u.%03u MHz, DDR:%u.%03u MHz, AHB:%u.%03u MHz\n",
+		ath79_sys_type,
+		ath79_cpu_freq / 1000000, (ath79_cpu_freq / 1000) % 1000,
+		ath79_ddr_freq / 1000000, (ath79_ddr_freq / 1000) % 1000,
+		ath79_ahb_freq / 1000000, (ath79_ahb_freq / 1000) % 1000);
+
+	_machine_restart = ath79_restart;
+	_machine_halt = ath79_halt;
+	pm_power_off = ath79_halt;
+}
+
+void __init plat_time_init(void)
+{
+	mips_hpt_frequency = ath79_cpu_freq / 2;
+}
+
+static int __init ath79_setup(void)
+{
+	ath79_register_uart();
+	return 0;
+}
+
+arch_initcall(ath79_setup);
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
new file mode 100644
index 0000000..5a9e5e1
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -0,0 +1,207 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X SoC register definitions
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_AR71XX_REGS_H
+#define __ASM_MACH_AR71XX_REGS_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+
+#define AR71XX_APB_BASE		0x18000000
+
+#define AR71XX_DDR_CTRL_BASE	(AR71XX_APB_BASE + 0x00000000)
+#define AR71XX_DDR_CTRL_SIZE	0x100
+#define AR71XX_UART_BASE	(AR71XX_APB_BASE + 0x00020000)
+#define AR71XX_UART_SIZE	0x100
+#define AR71XX_PLL_BASE		(AR71XX_APB_BASE + 0x00050000)
+#define AR71XX_PLL_SIZE		0x100
+#define AR71XX_RESET_BASE	(AR71XX_APB_BASE + 0x00060000)
+#define AR71XX_RESET_SIZE	0x100
+
+/*
+ * DDR_CTRL block
+ */
+#define AR71XX_DDR_REG_PCI_WIN0		0x7c
+#define AR71XX_DDR_REG_PCI_WIN1		0x80
+#define AR71XX_DDR_REG_PCI_WIN2		0x84
+#define AR71XX_DDR_REG_PCI_WIN3		0x88
+#define AR71XX_DDR_REG_PCI_WIN4		0x8c
+#define AR71XX_DDR_REG_PCI_WIN5		0x90
+#define AR71XX_DDR_REG_PCI_WIN6		0x94
+#define AR71XX_DDR_REG_PCI_WIN7		0x98
+#define AR71XX_DDR_REG_FLUSH_GE0	0x9c
+#define AR71XX_DDR_REG_FLUSH_GE1	0xa0
+#define AR71XX_DDR_REG_FLUSH_USB	0xa4
+#define AR71XX_DDR_REG_FLUSH_PCI	0xa8
+
+#define AR724X_DDR_REG_FLUSH_GE0	0x7c
+#define AR724X_DDR_REG_FLUSH_GE1	0x80
+#define AR724X_DDR_REG_FLUSH_USB	0x84
+#define AR724X_DDR_REG_FLUSH_PCIE	0x88
+
+#define AR913X_DDR_REG_FLUSH_GE0	0x7c
+#define AR913X_DDR_REG_FLUSH_GE1	0x80
+#define AR913X_DDR_REG_FLUSH_USB	0x84
+#define AR913X_DDR_REG_FLUSH_WMAC	0x88
+
+/*
+ * PLL block
+ */
+#define AR71XX_PLL_REG_CPU_CONFIG	0x00
+#define AR71XX_PLL_REG_SEC_CONFIG	0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK	0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK	0x14
+
+#define AR71XX_PLL_DIV_SHIFT		3
+#define AR71XX_PLL_DIV_MASK		0x1f
+#define AR71XX_CPU_DIV_SHIFT		16
+#define AR71XX_CPU_DIV_MASK		0x3
+#define AR71XX_DDR_DIV_SHIFT		18
+#define AR71XX_DDR_DIV_MASK		0x3
+#define AR71XX_AHB_DIV_SHIFT		20
+#define AR71XX_AHB_DIV_MASK		0x7
+
+#define AR724X_PLL_REG_CPU_CONFIG	0x00
+#define AR724X_PLL_REG_PCIE_CONFIG	0x18
+
+#define AR724X_PLL_DIV_SHIFT		0
+#define AR724X_PLL_DIV_MASK		0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT	10
+#define AR724X_PLL_REF_DIV_MASK		0xf
+#define AR724X_AHB_DIV_SHIFT		19
+#define AR724X_AHB_DIV_MASK		0x1
+#define AR724X_DDR_DIV_SHIFT		22
+#define AR724X_DDR_DIV_MASK		0x3
+
+#define AR913X_PLL_REG_CPU_CONFIG	0x00
+#define AR913X_PLL_REG_ETH_CONFIG	0x04
+#define AR913X_PLL_REG_ETH0_INT_CLOCK	0x14
+#define AR913X_PLL_REG_ETH1_INT_CLOCK	0x18
+
+#define AR913X_PLL_DIV_SHIFT		0
+#define AR913X_PLL_DIV_MASK		0x3ff
+#define AR913X_DDR_DIV_SHIFT		22
+#define AR913X_DDR_DIV_MASK		0x3
+#define AR913X_AHB_DIV_SHIFT		19
+#define AR913X_AHB_DIV_MASK		0x1
+
+/*
+ * RESET block
+ */
+#define AR71XX_RESET_REG_TIMER			0x00
+#define AR71XX_RESET_REG_TIMER_RELOAD		0x04
+#define AR71XX_RESET_REG_WDOG_CTRL		0x08
+#define AR71XX_RESET_REG_WDOG			0x0c
+#define AR71XX_RESET_REG_MISC_INT_STATUS	0x10
+#define AR71XX_RESET_REG_MISC_INT_ENABLE	0x14
+#define AR71XX_RESET_REG_PCI_INT_STATUS		0x18
+#define AR71XX_RESET_REG_PCI_INT_ENABLE		0x1c
+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS	0x20
+#define AR71XX_RESET_REG_RESET_MODULE		0x24
+#define AR71XX_RESET_REG_PERFC_CTRL		0x2c
+#define AR71XX_RESET_REG_PERFC0			0x30
+#define AR71XX_RESET_REG_PERFC1			0x34
+#define AR71XX_RESET_REG_REV_ID			0x90
+
+#define AR913X_RESET_REG_GLOBAL_INT_STATUS	0x18
+#define AR913X_RESET_REG_RESET_MODULE		0x1c
+#define AR913X_RESET_REG_PERF_CTRL		0x20
+#define AR913X_RESET_REG_PERFC0			0x24
+#define AR913X_RESET_REG_PERFC1			0x28
+
+#define AR724X_RESET_REG_RESET_MODULE		0x1c
+
+#define MISC_INT_DMA			BIT(7)
+#define MISC_INT_OHCI			BIT(6)
+#define MISC_INT_PERFC			BIT(5)
+#define MISC_INT_WDOG			BIT(4)
+#define MISC_INT_UART			BIT(3)
+#define MISC_INT_GPIO			BIT(2)
+#define MISC_INT_ERROR			BIT(1)
+#define MISC_INT_TIMER			BIT(0)
+
+#define AR71XX_RESET_EXTERNAL		BIT(28)
+#define AR71XX_RESET_FULL_CHIP		BIT(24)
+#define AR71XX_RESET_CPU_NMI		BIT(21)
+#define AR71XX_RESET_CPU_COLD		BIT(20)
+#define AR71XX_RESET_DMA		BIT(19)
+#define AR71XX_RESET_SLIC		BIT(18)
+#define AR71XX_RESET_STEREO		BIT(17)
+#define AR71XX_RESET_DDR		BIT(16)
+#define AR71XX_RESET_GE1_MAC		BIT(13)
+#define AR71XX_RESET_GE1_PHY		BIT(12)
+#define AR71XX_RESET_USBSUS_OVERRIDE	BIT(10)
+#define AR71XX_RESET_GE0_MAC		BIT(9)
+#define AR71XX_RESET_GE0_PHY		BIT(8)
+#define AR71XX_RESET_USB_OHCI_DLL	BIT(6)
+#define AR71XX_RESET_USB_HOST		BIT(5)
+#define AR71XX_RESET_USB_PHY		BIT(4)
+#define AR71XX_RESET_PCI_BUS		BIT(1)
+#define AR71XX_RESET_PCI_CORE		BIT(0)
+
+#define AR724X_RESET_GE1_MDIO		BIT(23)
+#define AR724X_RESET_GE0_MDIO		BIT(22)
+#define AR724X_RESET_PCIE_PHY_SERIAL	BIT(10)
+#define AR724X_RESET_PCIE_PHY		BIT(7)
+#define AR724X_RESET_PCIE		BIT(6)
+#define AR724X_RESET_OHCI_DLL		BIT(3)
+
+#define AR913X_RESET_AMBA2WMAC		BIT(22)
+
+#define REV_ID_MAJOR_MASK		0xfff0
+#define REV_ID_MAJOR_AR71XX		0x00a0
+#define REV_ID_MAJOR_AR913X		0x00b0
+#define REV_ID_MAJOR_AR7240		0x00c0
+#define REV_ID_MAJOR_AR7241		0x0100
+#define REV_ID_MAJOR_AR7242		0x1100
+
+#define AR71XX_REV_ID_MINOR_MASK	0x3
+#define AR71XX_REV_ID_MINOR_AR7130	0x0
+#define AR71XX_REV_ID_MINOR_AR7141	0x1
+#define AR71XX_REV_ID_MINOR_AR7161	0x2
+#define AR71XX_REV_ID_REVISION_MASK	0x3
+#define AR71XX_REV_ID_REVISION_SHIFT	2
+
+#define AR913X_REV_ID_MINOR_MASK	0x3
+#define AR913X_REV_ID_MINOR_AR9130	0x0
+#define AR913X_REV_ID_MINOR_AR9132	0x1
+#define AR913X_REV_ID_REVISION_MASK	0x3
+#define AR913X_REV_ID_REVISION_SHIFT	2
+
+#define AR724X_REV_ID_REVISION_MASK	0x3
+
+/*
+ * SPI block
+ */
+#define AR71XX_SPI_REG_FS	0x00	/* Function Select */
+#define AR71XX_SPI_REG_CTRL	0x04	/* SPI Control */
+#define AR71XX_SPI_REG_IOC	0x08	/* SPI I/O Control */
+#define AR71XX_SPI_REG_RDS	0x0c	/* Read Data Shift */
+
+#define AR71XX_SPI_FS_GPIO	BIT(0)	/* Enable GPIO mode */
+
+#define AR71XX_SPI_CTRL_RD	BIT(6)	/* Remap Disable */
+#define AR71XX_SPI_CTRL_DIV_MASK 0x3f
+
+#define AR71XX_SPI_IOC_DO	BIT(0)	/* Data Out pin */
+#define AR71XX_SPI_IOC_CLK	BIT(8)	/* CLK pin */
+#define AR71XX_SPI_IOC_CS(n)	BIT(16 + (n))
+#define AR71XX_SPI_IOC_CS0	AR71XX_SPI_IOC_CS(0)
+#define AR71XX_SPI_IOC_CS1	AR71XX_SPI_IOC_CS(1)
+#define AR71XX_SPI_IOC_CS2	AR71XX_SPI_IOC_CS(2)
+#define AR71XX_SPI_IOC_CS_ALL	(AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \
+				 AR71XX_SPI_IOC_CS2)
+
+#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
new file mode 100644
index 0000000..34fa294
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -0,0 +1,100 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_ATH79_H
+#define __ASM_MACH_ATH79_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+extern u32 ath79_ahb_freq;
+extern u32 ath79_cpu_freq;
+extern u32 ath79_ddr_freq;
+
+enum ath79_soc_type {
+	ATH79_SOC_UNKNOWN,
+	ATH79_SOC_AR7130,
+	ATH79_SOC_AR7141,
+	ATH79_SOC_AR7161,
+	ATH79_SOC_AR7240,
+	ATH79_SOC_AR7241,
+	ATH79_SOC_AR7242,
+	ATH79_SOC_AR9130,
+	ATH79_SOC_AR9132
+};
+
+extern enum ath79_soc_type ath79_soc;
+
+static inline int soc_is_ar71xx(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7130 ||
+		ath79_soc == ATH79_SOC_AR7141 ||
+		ath79_soc == ATH79_SOC_AR7161);
+}
+
+static inline int soc_is_ar724x(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7240 ||
+		ath79_soc == ATH79_SOC_AR7241 ||
+		ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar7240(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7240);
+}
+
+static inline int soc_is_ar7241(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7241);
+}
+
+static inline int soc_is_ar7242(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar913x(void)
+{
+	return (ath79_soc == ATH79_SOC_AR9130 ||
+		ath79_soc == ATH79_SOC_AR9132);
+}
+
+extern void __iomem *ath79_ddr_base;
+extern void __iomem *ath79_pll_base;
+extern void __iomem *ath79_reset_base;
+
+static inline void ath79_pll_wr(unsigned reg, u32 val)
+{
+	__raw_writel(val, ath79_pll_base + reg);
+}
+
+static inline u32 ath79_pll_rr(unsigned reg)
+{
+	return __raw_readl(ath79_pll_base + reg);
+}
+
+static inline void ath79_reset_wr(unsigned reg, u32 val)
+{
+	__raw_writel(val, ath79_reset_base + reg);
+}
+
+static inline u32 ath79_reset_rr(unsigned reg)
+{
+	return __raw_readl(ath79_reset_base + reg);
+}
+
+void ath79_device_reset_set(u32 mask);
+void ath79_device_reset_clear(u32 mask);
+
+#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
new file mode 100644
index 0000000..4476fa0
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
@@ -0,0 +1,56 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X specific CPU feature overrides
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This file was derived from: include/asm-mips/cpu-features.h
+ *	Copyright (C) 2003, 2004 Ralf Baechle
+ *	Copyright (C) 2004 Maciej W. Rozycki
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb		1
+#define cpu_has_4kex		1
+#define cpu_has_3k_cache	0
+#define cpu_has_4k_cache	1
+#define cpu_has_tx39_cache	0
+#define cpu_has_sb1_cache	0
+#define cpu_has_fpu		0
+#define cpu_has_32fpr		0
+#define cpu_has_counter		1
+#define cpu_has_watch		1
+#define cpu_has_divec		1
+
+#define cpu_has_prefetch	1
+#define cpu_has_ejtag		1
+#define cpu_has_llsc		1
+
+#define cpu_has_mips16		1
+#define cpu_has_mdmx		0
+#define cpu_has_mips3d		0
+#define cpu_has_smartmips	0
+
+#define cpu_has_mips32r1	1
+#define cpu_has_mips32r2	1
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
+#define cpu_has_dsp		0
+#define cpu_has_mipsmt		0
+
+#define cpu_has_64bits		0
+#define cpu_has_64bit_zero_reg	0
+#define cpu_has_64bit_gp_regs	0
+#define cpu_has_64bit_addresses	0
+
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	32
+
+#endif /* __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h
new file mode 100644
index 0000000..189bc6e
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/irq.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_ATH79_IRQ_H
+#define __ASM_MACH_ATH79_IRQ_H
+
+#define MIPS_CPU_IRQ_BASE	0
+#define NR_IRQS			16
+
+#define ATH79_MISC_IRQ_BASE	8
+#define ATH79_MISC_IRQ_COUNT	8
+
+#define ATH79_CPU_IRQ_IP2	(MIPS_CPU_IRQ_BASE + 2)
+#define ATH79_CPU_IRQ_USB	(MIPS_CPU_IRQ_BASE + 3)
+#define ATH79_CPU_IRQ_GE0	(MIPS_CPU_IRQ_BASE + 4)
+#define ATH79_CPU_IRQ_GE1	(MIPS_CPU_IRQ_BASE + 5)
+#define ATH79_CPU_IRQ_MISC	(MIPS_CPU_IRQ_BASE + 6)
+#define ATH79_CPU_IRQ_TIMER	(MIPS_CPU_IRQ_BASE + 7)
+
+#define ATH79_MISC_IRQ_TIMER	(ATH79_MISC_IRQ_BASE + 0)
+#define ATH79_MISC_IRQ_ERROR	(ATH79_MISC_IRQ_BASE + 1)
+#define ATH79_MISC_IRQ_GPIO	(ATH79_MISC_IRQ_BASE + 2)
+#define ATH79_MISC_IRQ_UART	(ATH79_MISC_IRQ_BASE + 3)
+#define ATH79_MISC_IRQ_WDOG	(ATH79_MISC_IRQ_BASE + 4)
+#define ATH79_MISC_IRQ_PERFC	(ATH79_MISC_IRQ_BASE + 5)
+#define ATH79_MISC_IRQ_OHCI	(ATH79_MISC_IRQ_BASE + 6)
+#define ATH79_MISC_IRQ_DMA	(ATH79_MISC_IRQ_BASE + 7)
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_ATH79_IRQ_H */
diff --git a/arch/mips/include/asm/mach-ath79/kernel-entry-init.h b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
new file mode 100644
index 0000000..d8d046b
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
@@ -0,0 +1,32 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X specific kernel entry setup
+ *
+ *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MACH_ATH79_KERNEL_ENTRY_H
+#define __ASM_MACH_ATH79_KERNEL_ENTRY_H
+
+	/*
+	 * Some bootloaders set the 'Kseg0 coherency algorithm' to
+	 * 'Cacheable, noncoherent, write-through, no write allocate'
+	 * and this cause performance issues. Let's go and change it to
+	 * 'Cacheable, noncoherent, write-back, write allocate'
+	 */
+	.macro	kernel_entry_setup
+	mfc0	t0, CP0_CONFIG
+	li	t1, ~CONF_CM_CMASK
+	and	t0, t1
+	ori	t0, CONF_CM_CACHABLE_NONCOHERENT
+	mtc0	t0, CP0_CONFIG
+	nop
+	.endm
+
+	.macro	smp_slave_setup
+	.endm
+
+#endif /* __ASM_MACH_ATH79_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-ath79/war.h b/arch/mips/include/asm/mach-ath79/war.h
new file mode 100644
index 0000000..323d9f1
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/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_MACH_ATH79_WAR_H
+#define __ASM_MACH_ATH79_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			0
+#define MIPS34K_MISSED_ITLB_WAR		0
+
+#endif /* __ASM_MACH_ATH79_WAR_H */
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 19:57:38 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 19:57:44 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43345 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491942Ab1ABS4t (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:49 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 618733FC03C;
        Sun,  2 Jan 2011 19:56:44 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id A12861F0001;
        Sun,  2 Jan 2011 19:56:43 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>
Subject: [PATCH v4 02/16] MIPS: ath79: add GPIOLIB support
Date:   Sun,  2 Jan 2011 19:56:15 +0100
Message-Id: <1293994589-6794-3-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17EC528EC3 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28789
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch implements generic GPIO routines for the built-in
GPIO controllers of the Atheros AR71XX/AR724X/AR913X SoCs.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/Kconfig                              |    1 +
 arch/mips/ath79/Makefile                       |    2 +-
 arch/mips/ath79/common.h                       |    5 +
 arch/mips/ath79/gpio.c                         |  197 ++++++++++++++++++++++++
 arch/mips/ath79/setup.c                        |    2 +-
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h |   21 +++
 arch/mips/include/asm/mach-ath79/gpio.h        |   26 +++
 7 files changed, 252 insertions(+), 2 deletions(-)
 create mode 100644 arch/mips/ath79/gpio.c
 create mode 100644 arch/mips/include/asm/mach-ath79/gpio.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2e32137..944845a 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -68,6 +68,7 @@ config AR7
 
 config ATH79
 	bool "Atheros AR71XX/AR724X/AR913X based boards"
+	select ARCH_REQUIRE_GPIOLIB
 	select BOOT_RAW
 	select CEVT_R4K
 	select CSRC_R4K
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index b4ec9c2..facbb70 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -8,7 +8,7 @@
 # under the terms of the GNU General Public License version 2 as published
 # by the Free Software Foundation.
 
-obj-y	:= prom.o setup.o irq.o common.o
+obj-y	:= prom.o setup.o irq.o common.o gpio.o
 
 obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
index a1bcdbb..cb2f3e8 100644
--- a/arch/mips/ath79/common.h
+++ b/arch/mips/ath79/common.h
@@ -22,4 +22,9 @@
 
 void ath79_ddr_wb_flush(unsigned int reg);
 
+void ath79_gpio_function_enable(u32 mask);
+void ath79_gpio_function_disable(u32 mask);
+void ath79_gpio_function_setup(u32 set, u32 clear);
+void ath79_gpio_init(void) __init;
+
 #endif /* __ATH79_COMMON_H */
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c
new file mode 100644
index 0000000..a0c426b
--- /dev/null
+++ b/arch/mips/ath79/gpio.c
@@ -0,0 +1,197 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X GPIO API support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79.h>
+#include "common.h"
+
+static void __iomem *ath79_gpio_base;
+static unsigned long ath79_gpio_count;
+static DEFINE_SPINLOCK(ath79_gpio_lock);
+
+static void __ath79_gpio_set_value(unsigned gpio, int value)
+{
+	void __iomem *base = ath79_gpio_base;
+
+	if (value)
+		__raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET);
+	else
+		__raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR);
+}
+
+static int __ath79_gpio_get_value(unsigned gpio)
+{
+	return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
+}
+
+static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	return __ath79_gpio_get_value(offset);
+}
+
+static void ath79_gpio_set_value(struct gpio_chip *chip,
+				  unsigned offset, int value)
+{
+	__ath79_gpio_set_value(offset, value);
+}
+
+static int ath79_gpio_direction_input(struct gpio_chip *chip,
+				       unsigned offset)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
+		     base + AR71XX_GPIO_REG_OE);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+	return 0;
+}
+
+static int ath79_gpio_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	if (value)
+		__raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
+	else
+		__raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
+
+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
+		     base + AR71XX_GPIO_REG_OE);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+	return 0;
+}
+
+static struct gpio_chip ath79_gpio_chip = {
+	.label			= "ath79",
+	.get			= ath79_gpio_get_value,
+	.set			= ath79_gpio_set_value,
+	.direction_input	= ath79_gpio_direction_input,
+	.direction_output	= ath79_gpio_direction_output,
+	.base			= 0,
+};
+
+void ath79_gpio_function_enable(u32 mask)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) | mask,
+		     base + AR71XX_GPIO_REG_FUNC);
+	/* flush write */
+	__raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_disable(u32 mask)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~mask,
+		     base + AR71XX_GPIO_REG_FUNC);
+	/* flush write */
+	__raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_setup(u32 set, u32 clear)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	__raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set,
+		     base + AR71XX_GPIO_REG_FUNC);
+	/* flush write */
+	__raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void __init ath79_gpio_init(void)
+{
+	int err;
+
+	if (soc_is_ar71xx())
+		ath79_gpio_count = AR71XX_GPIO_COUNT;
+	else if (soc_is_ar724x())
+		ath79_gpio_count = AR724X_GPIO_COUNT;
+	else if (soc_is_ar913x())
+		ath79_gpio_count = AR913X_GPIO_COUNT;
+	else
+		BUG();
+
+	ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
+	ath79_gpio_chip.ngpio = ath79_gpio_count;
+
+	err = gpiochip_add(&ath79_gpio_chip);
+	if (err)
+		panic("cannot add AR71xx GPIO chip, error=%d", err);
+}
+
+int gpio_get_value(unsigned gpio)
+{
+	if (gpio < ath79_gpio_count)
+		return __ath79_gpio_get_value(gpio);
+
+	return __gpio_get_value(gpio);
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int value)
+{
+	if (gpio < ath79_gpio_count)
+		__ath79_gpio_set_value(gpio, value);
+	else
+		__gpio_set_value(gpio, value);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_to_irq(unsigned gpio)
+{
+	/* FIXME */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(unsigned irq)
+{
+	/* FIXME */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(irq_to_gpio);
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 4157ddc..83dd855 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -230,7 +230,6 @@ void __init plat_mem_setup(void)
 					   AR71XX_RESET_SIZE);
 	ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
 					 AR71XX_PLL_SIZE);
-
 	ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
 					 AR71XX_DDR_CTRL_SIZE);
 
@@ -256,6 +255,7 @@ void __init plat_time_init(void)
 
 static int __init ath79_setup(void)
 {
+	ath79_gpio_init();
 	ath79_register_uart();
 	return 0;
 }
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 5a9e5e1..7f2933d 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -25,6 +25,8 @@
 #define AR71XX_DDR_CTRL_SIZE	0x100
 #define AR71XX_UART_BASE	(AR71XX_APB_BASE + 0x00020000)
 #define AR71XX_UART_SIZE	0x100
+#define AR71XX_GPIO_BASE        (AR71XX_APB_BASE + 0x00040000)
+#define AR71XX_GPIO_SIZE        0x100
 #define AR71XX_PLL_BASE		(AR71XX_APB_BASE + 0x00050000)
 #define AR71XX_PLL_SIZE		0x100
 #define AR71XX_RESET_BASE	(AR71XX_APB_BASE + 0x00060000)
@@ -204,4 +206,23 @@
 #define AR71XX_SPI_IOC_CS_ALL	(AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \
 				 AR71XX_SPI_IOC_CS2)
 
+/*
+ * GPIO block
+ */
+#define AR71XX_GPIO_REG_OE		0x00
+#define AR71XX_GPIO_REG_IN		0x04
+#define AR71XX_GPIO_REG_OUT		0x08
+#define AR71XX_GPIO_REG_SET		0x0c
+#define AR71XX_GPIO_REG_CLEAR		0x10
+#define AR71XX_GPIO_REG_INT_MODE	0x14
+#define AR71XX_GPIO_REG_INT_TYPE	0x18
+#define AR71XX_GPIO_REG_INT_POLARITY	0x1c
+#define AR71XX_GPIO_REG_INT_PENDING	0x20
+#define AR71XX_GPIO_REG_INT_ENABLE	0x24
+#define AR71XX_GPIO_REG_FUNC		0x28
+
+#define AR71XX_GPIO_COUNT		16
+#define AR724X_GPIO_COUNT		18
+#define AR913X_GPIO_COUNT		22
+
 #endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/gpio.h b/arch/mips/include/asm/mach-ath79/gpio.h
new file mode 100644
index 0000000..60dcb62
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/gpio.h
@@ -0,0 +1,26 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X GPIO API definitions
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_MACH_ATH79_GPIO_H
+#define __ASM_MACH_ATH79_GPIO_H
+
+#define ARCH_NR_GPIOS	64
+#include <asm-generic/gpio.h>
+
+int gpio_to_irq(unsigned gpio);
+int irq_to_gpio(unsigned irq);
+int gpio_get_value(unsigned gpio);
+void gpio_set_value(unsigned gpio, int value);
+
+#define gpio_cansleep	__gpio_cansleep
+
+#endif /* __ASM_MACH_ATH79_GPIO_H */
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 19:58:03 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 19:58:08 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43352 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491943Ab1ABS4t (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:49 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id B812F3FC03D;
        Sun,  2 Jan 2011 19:56:44 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 3395F1F0001;
        Sun,  2 Jan 2011 19:56:44 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 03/16] MIPS: ath79: utilize the MIPS multi-machine support
Date:   Sun,  2 Jan 2011 19:56:16 +0100
Message-Id: <1293994589-6794-4-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17ECC8B636 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28790
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/Kconfig           |    1 +
 arch/mips/ath79/machtypes.h |   21 +++++++++++++++++++++
 arch/mips/ath79/setup.c     |   15 +++++++++++++++
 3 files changed, 37 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/machtypes.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 944845a..12dd976 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -74,6 +74,7 @@ config ATH79
 	select CSRC_R4K
 	select DMA_NONCOHERENT
 	select IRQ_CPU
+	select MIPS_MACHINE
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_HAS_EARLY_PRINTK
 	select SYS_SUPPORTS_32BIT_KERNEL
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
new file mode 100644
index 0000000..fac0e26
--- /dev/null
+++ b/arch/mips/ath79/machtypes.h
@@ -0,0 +1,21 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X machine type definitions
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_MACHTYPE_H
+#define _ATH79_MACHTYPE_H
+
+#include <asm/mips_machine.h>
+
+enum ath79_mach_type {
+	ATH79_MACH_GENERIC = 0,
+};
+
+#endif /* _ATH79_MACHTYPE_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 83dd855..5f2b6de 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -18,11 +18,13 @@
 #include <asm/bootinfo.h>
 #include <asm/time.h>		/* for mips_hpt_frequency */
 #include <asm/reboot.h>		/* for _machine_{restart,halt} */
+#include <asm/mips_machine.h>
 
 #include <asm/mach-ath79/ath79.h>
 #include <asm/mach-ath79/ar71xx_regs.h>
 #include "common.h"
 #include "dev-common.h"
+#include "machtypes.h"
 
 #define ATH79_SYS_TYPE_LEN	64
 
@@ -257,7 +259,20 @@ static int __init ath79_setup(void)
 {
 	ath79_gpio_init();
 	ath79_register_uart();
+
+	mips_machine_setup();
+
 	return 0;
 }
 
 arch_initcall(ath79_setup);
+
+static void __init ath79_generic_init(void)
+{
+	/* Nothing to do */
+}
+
+MIPS_MACHINE(ATH79_MACH_GENERIC,
+	     "Generic",
+	     "Generic AR71XX/AR724X/AR913X based board",
+	     ath79_generic_init);
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 19:58:27 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 19:58:32 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43358 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491944Ab1ABS4u (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:50 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 2715A3FC03E;
        Sun,  2 Jan 2011 19:56:45 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 9663B1F0001;
        Sun,  2 Jan 2011 19:56:44 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 04/16] MIPS: ath79: add initial support for the Atheros PB44 reference board
Date:   Sun,  2 Jan 2011 19:56:17 +0100
Message-Id: <1293994589-6794-5-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17ED2ED2D6 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28791
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC:
    - don't use 'default n' for the ATH79_MACH_PB44 Kconfig option

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/Kconfig     |   11 ++++++++
 arch/mips/ath79/Makefile    |    5 ++++
 arch/mips/ath79/mach-pb44.c |   56 +++++++++++++++++++++++++++++++++++++++++++
 arch/mips/ath79/machtypes.h |    1 +
 4 files changed, 73 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/mach-pb44.c

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 50b9334..fabb2b0 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -1,5 +1,16 @@
 if ATH79
 
+menu "Atheros AR71XX/AR724X/AR913X machine selection"
+
+config ATH79_MACH_PB44
+	bool "Atheros PB44 reference board"
+	select SOC_AR71XX
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Atheros PB44 reference board.
+
+endmenu
+
 config SOC_AR71XX
 	def_bool n
 
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index facbb70..a9ba120 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,3 +16,8 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 # Devices
 #
 obj-y					+= dev-common.o
+
+#
+# Machines
+#
+obj-$(CONFIG_ATH79_MACH_PB44)		+= mach-pb44.o
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
new file mode 100644
index 0000000..ffc24d7
--- /dev/null
+++ b/arch/mips/ath79/mach-pb44.c
@@ -0,0 +1,56 @@
+/*
+ *  Atheros PB44 reference board support
+ *
+ *  Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/pcf857x.h>
+
+#include "machtypes.h"
+
+#define PB44_GPIO_I2C_SCL	0
+#define PB44_GPIO_I2C_SDA	1
+
+#define PB44_GPIO_EXP_BASE	16
+
+static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
+	.sda_pin        = PB44_GPIO_I2C_SDA,
+	.scl_pin        = PB44_GPIO_I2C_SCL,
+};
+
+static struct platform_device pb44_i2c_gpio_device = {
+	.name		= "i2c-gpio",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &pb44_i2c_gpio_data,
+	}
+};
+
+static struct pcf857x_platform_data pb44_pcf857x_data = {
+	.gpio_base	= PB44_GPIO_EXP_BASE,
+};
+
+static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("pcf8575", 0x20),
+		.platform_data  = &pb44_pcf857x_data,
+	},
+};
+
+static void __init pb44_init(void)
+{
+	i2c_register_board_info(0, pb44_i2c_board_info,
+				ARRAY_SIZE(pb44_i2c_board_info));
+	platform_device_register(&pb44_i2c_gpio_device);
+}
+
+MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
+	     pb44_init);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
index fac0e26..a796fa3 100644
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -16,6 +16,7 @@
 
 enum ath79_mach_type {
 	ATH79_MACH_GENERIC = 0,
+	ATH79_MACH_PB44,		/* Atheros PB44 reference board */
 };
 
 #endif /* _ATH79_MACHTYPE_H */
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 19:58:51 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 19:58:56 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43399 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491947Ab1ABS4x (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:53 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 2ABBA3FC040;
        Sun,  2 Jan 2011 19:56:46 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 7E7771F0001;
        Sun,  2 Jan 2011 19:56:45 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        Wim Van Sebroeck <wim@iguana.be>,
        linux-watchdog@vger.kernel.org
Subject: [PATCH v4 06/16] watchdog: add driver for the Atheros AR71XX/AR724X/AR913X SoCs
Date:   Sun,  2 Jan 2011 19:56:19 +0100
Message-Id: <1293994589-6794-7-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17EDCE2753 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28792
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds a driver for the built-in hardware watchdog device
of the Atheros AR71XX/AR724X/AR913X SoCs.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: Wim Van Sebroeck <wim@iguana.be>
Cc: linux-watchdog@vger.kernel.org
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - remove #ifdef CONFIG_WATCHDOG_NOWAYOUT for nowayout module-parameter.
    - add ath79_wdt_keepalive when doing un unexpected close of /dev/watchdog
      (the close is considered as communication with /dev/watchdog)
    - replace reboot_notifier with a platform shutdown.
    - add timeout module-parameter
    - rebased against 2.6.37-rc8

 drivers/watchdog/Kconfig     |    7 +
 drivers/watchdog/Makefile    |    1 +
 drivers/watchdog/ath79_wdt.c |  283 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 291 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/ath79_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index a5ad77e..e4be010 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -836,6 +836,13 @@ config SBC_EPX_C3_WATCHDOG
 
 # MIPS Architecture
 
+config ATH79_WDT
+	tristate "Atheros AR71XX/AR724X/AR913X hardware watchdog"
+	depends on ATH79
+	help
+	  Hardware driver for the built-in watchdog timer on the Atheros
+	  AR71XX/AR724X/AR913X SoCs.
+
 config BCM47XX_WDT
 	tristate "Broadcom BCM47xx Watchdog Timer"
 	depends on BCM47XX
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 4b0ef38..01d9063 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -108,6 +108,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
 # M68KNOMMU Architecture
 
 # MIPS Architecture
+obj-$(CONFIG_ATH79_WDT) += ath79_wdt.o
 obj-$(CONFIG_BCM47XX_WDT) += bcm47xx_wdt.o
 obj-$(CONFIG_BCM63XX_WDT) += bcm63xx_wdt.o
 obj-$(CONFIG_RC32434_WDT) += rc32434_wdt.o
diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c
new file mode 100644
index 0000000..f28558c
--- /dev/null
+++ b/drivers/watchdog/ath79_wdt.c
@@ -0,0 +1,283 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X built-in hardware watchdog timer.
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This driver was based on: drivers/watchdog/ixp4xx_wdt.c
+ *	Author: Deepak Saxena <dsaxena@plexity.net>
+ *	Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * which again was based on sa1100 driver,
+ *	Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+#define DRIVER_NAME	"ath79-wdt"
+#define DRIVER_DESC	"Atheros AR71XX/AR724X/AR913X hardware watchdog driver"
+
+#define WDT_TIMEOUT	15	/* seconds */
+
+#define WDOG_CTRL_LAST_RESET	BIT(31)
+#define WDOG_CTRL_ACTION_MASK	3
+#define WDOG_CTRL_ACTION_NONE	0	/* no action */
+#define WDOG_CTRL_ACTION_GPI	1	/* general purpose interrupt */
+#define WDOG_CTRL_ACTION_NMI	2	/* NMI */
+#define WDOG_CTRL_ACTION_FCR	3	/* full chip reset */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
+			   "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static int timeout = WDT_TIMEOUT;
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds "
+			  "(default=" __MODULE_STRING(WDT_TIMEOUT) "s)");
+
+static unsigned long wdt_flags;
+
+#define WDT_FLAGS_BUSY		0
+#define WDT_FLAGS_EXPECT_CLOSE	1
+
+static int boot_status;
+static int max_timeout;
+
+static inline void ath79_wdt_keepalive(void)
+{
+	ath79_reset_wr(AR71XX_RESET_REG_WDOG, ath79_ahb_freq * timeout);
+}
+
+static inline void ath79_wdt_enable(void)
+{
+	ath79_wdt_keepalive();
+	ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
+}
+
+static inline void ath79_wdt_disable(void)
+{
+	ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
+}
+
+static int ath79_wdt_set_timeout(int val)
+{
+	if (val < 1 || val > max_timeout)
+		return -EINVAL;
+
+	timeout = val;
+	ath79_wdt_keepalive();
+
+	return 0;
+}
+
+static int ath79_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags))
+		return -EBUSY;
+
+	clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
+	ath79_wdt_enable();
+
+	return nonseekable_open(inode, file);
+}
+
+static int ath79_wdt_release(struct inode *inode, struct file *file)
+{
+	if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags))
+		ath79_wdt_disable();
+	else {
+		pr_crit(DRIVER_NAME ": device closed unexpectedly, "
+			"watchdog timer will not stop!\n");
+		ath79_wdt_keepalive();
+	}
+
+	clear_bit(WDT_FLAGS_BUSY, &wdt_flags);
+	clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
+
+	return 0;
+}
+
+static ssize_t ath79_wdt_write(struct file *file, const char *data,
+				size_t len, loff_t *ppos)
+{
+	if (len) {
+		if (!nowayout) {
+			size_t i;
+
+			clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
+
+			for (i = 0; i != len; i++) {
+				char c;
+
+				if (get_user(c, data + i))
+					return -EFAULT;
+
+				if (c == 'V')
+					set_bit(WDT_FLAGS_EXPECT_CLOSE,
+						&wdt_flags);
+			}
+		}
+
+		ath79_wdt_keepalive();
+	}
+
+	return len;
+}
+
+static const struct watchdog_info ath79_wdt_info = {
+	.options		= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+				  WDIOF_MAGICCLOSE | WDIOF_CARDRESET,
+	.firmware_version	= 0,
+	.identity		= "ATH79 watchdog",
+};
+
+static long ath79_wdt_ioctl(struct file *file, unsigned int cmd,
+			    unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	int err;
+	int t;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		err = copy_to_user(argp, &ath79_wdt_info,
+				   sizeof(ath79_wdt_info)) ? -EFAULT : 0;
+		break;
+
+	case WDIOC_GETSTATUS:
+		err = put_user(0, p);
+		break;
+
+	case WDIOC_GETBOOTSTATUS:
+		err = put_user(boot_status, p);
+		break;
+
+	case WDIOC_KEEPALIVE:
+		ath79_wdt_keepalive();
+		err = 0;
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		err = get_user(t, p);
+		if (err)
+			break;
+
+		err = ath79_wdt_set_timeout(t);
+		if (err)
+			break;
+
+		/* fallthrough */
+	case WDIOC_GETTIMEOUT:
+		err = put_user(timeout, p);
+		break;
+
+	default:
+		err = -ENOTTY;
+		break;
+	}
+
+	return err;
+}
+
+static const struct file_operations ath79_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= ath79_wdt_write,
+	.unlocked_ioctl	= ath79_wdt_ioctl,
+	.open		= ath79_wdt_open,
+	.release	= ath79_wdt_release,
+};
+
+static struct miscdevice ath79_wdt_miscdev = {
+	.minor = WATCHDOG_MINOR,
+	.name = "watchdog",
+	.fops = &ath79_wdt_fops,
+};
+
+static int __init ath79_wdt_probe(struct platform_device *pdev)
+{
+	u32 ctrl;
+	int err;
+
+	max_timeout = (0xfffffffful / ath79_ahb_freq);
+	if (timeout < 1 || timeout > max_timeout) {
+		timeout = max_timeout;
+		dev_info(&pdev->dev,
+			"timeout value must be 0 < timeout < %d, using %d\n",
+			max_timeout, timeout);
+	}
+
+	ctrl = ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
+	boot_status = (ctrl & WDOG_CTRL_LAST_RESET) ? WDIOF_CARDRESET : 0;
+
+	err = misc_register(&ath79_wdt_miscdev);
+	if (err) {
+		dev_err(&pdev->dev,
+			"unable to register misc device, err=%d\n", err);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	return err;
+}
+
+static int __exit ath79_wdt_remove(struct platform_device *pdev)
+{
+	misc_deregister(&ath79_wdt_miscdev);
+	return 0;
+}
+
+static void ath97_wdt_shutdown(struct platform_device *pdev)
+{
+	ath79_wdt_disable();
+}
+
+static struct platform_driver ath79_wdt_driver = {
+	.remove		= __exit_p(ath79_wdt_remove),
+	.shutdown	= ath97_wdt_shutdown,
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init ath79_wdt_init(void)
+{
+	return platform_driver_probe(&ath79_wdt_driver, ath79_wdt_probe);
+}
+module_init(ath79_wdt_init);
+
+static void __exit ath79_wdt_exit(void)
+{
+	platform_driver_unregister(&ath79_wdt_driver);
+}
+module_exit(ath79_wdt_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org");
+MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 19:59:14 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 19:59:19 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43398 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491946Ab1ABS4x (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:53 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id A2E373FC03F;
        Sun,  2 Jan 2011 19:56:45 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 095CE1F0001;
        Sun,  2 Jan 2011 19:56:45 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 05/16] MIPS: ath79: add common GPIO LEDs device
Date:   Sun,  2 Jan 2011 19:56:18 +0100
Message-Id: <1293994589-6794-6-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17ED870DCA | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28793
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Almost all boards have one or more LEDs connected to GPIO lines. This
patch adds common code to register a platform_device for them.

The patch also adds support for the LEDs on the PB44 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/Kconfig         |    4 +++
 arch/mips/ath79/Makefile        |    1 +
 arch/mips/ath79/dev-leds-gpio.c |   56 +++++++++++++++++++++++++++++++++++++++
 arch/mips/ath79/dev-leds-gpio.h |   21 ++++++++++++++
 arch/mips/ath79/mach-pb44.c     |   18 ++++++++++++
 5 files changed, 100 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/dev-leds-gpio.c
 create mode 100644 arch/mips/ath79/dev-leds-gpio.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index fabb2b0..5bc480e 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,6 +5,7 @@ menu "Atheros AR71XX/AR724X/AR913X machine selection"
 config ATH79_MACH_PB44
 	bool "Atheros PB44 reference board"
 	select SOC_AR71XX
+	select ATH79_DEV_LEDS_GPIO
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Atheros PB44 reference board.
@@ -20,4 +21,7 @@ config SOC_AR724X
 config SOC_AR913X
 	def_bool n
 
+config ATH79_DEV_LEDS_GPIO
+	def_bool n
+
 endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index a9ba120..d14b597 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 # Devices
 #
 obj-y					+= dev-common.o
+obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
 
 #
 # Machines
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c
new file mode 100644
index 0000000..cdade68
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.c
@@ -0,0 +1,56 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "dev-leds-gpio.h"
+
+void __init ath79_register_leds_gpio(int id,
+				     unsigned num_leds,
+				     struct gpio_led *leds)
+{
+	struct platform_device *pdev;
+	struct gpio_led_platform_data pdata;
+	struct gpio_led *p;
+	int err;
+
+	p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return;
+
+	memcpy(p, leds, num_leds * sizeof(*p));
+
+	pdev = platform_device_alloc("leds-gpio", id);
+	if (!pdev)
+		goto err_free_leds;
+
+	memset(&pdata, 0, sizeof(pdata));
+	pdata.num_leds = num_leds;
+	pdata.leds = p;
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err)
+		goto err_put_pdev;
+
+	err = platform_device_add(pdev);
+	if (err)
+		goto err_put_pdev;
+
+	return;
+
+err_put_pdev:
+	platform_device_put(pdev);
+
+err_free_leds:
+	kfree(p);
+}
diff --git a/arch/mips/ath79/dev-leds-gpio.h b/arch/mips/ath79/dev-leds-gpio.h
new file mode 100644
index 0000000..6e5d885
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.h
@@ -0,0 +1,21 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_LEDS_GPIO_H
+#define _ATH79_DEV_LEDS_GPIO_H
+
+#include <linux/leds.h>
+
+void ath79_register_leds_gpio(int id,
+			      unsigned num_leds,
+			      struct gpio_led *leds);
+
+#endif /* _ATH79_DEV_LEDS_GPIO_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index ffc24d7..e176779 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -15,11 +15,14 @@
 #include <linux/i2c/pcf857x.h>
 
 #include "machtypes.h"
+#include "dev-leds-gpio.h"
 
 #define PB44_GPIO_I2C_SCL	0
 #define PB44_GPIO_I2C_SDA	1
 
 #define PB44_GPIO_EXP_BASE	16
+#define PB44_GPIO_LED_JUMP1	(PB44_GPIO_EXP_BASE + 9)
+#define PB44_GPIO_LED_JUMP2	(PB44_GPIO_EXP_BASE + 10)
 
 static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
 	.sda_pin        = PB44_GPIO_I2C_SDA,
@@ -45,11 +48,26 @@ static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
 	},
 };
 
+static struct gpio_led pb44_leds_gpio[] __initdata = {
+	{
+		.name		= "pb44:amber:jump1",
+		.gpio		= PB44_GPIO_LED_JUMP1,
+		.active_low	= 1,
+	}, {
+		.name		= "pb44:green:jump2",
+		.gpio		= PB44_GPIO_LED_JUMP2,
+		.active_low	= 1,
+	},
+};
+
 static void __init pb44_init(void)
 {
 	i2c_register_board_info(0, pb44_i2c_board_info,
 				ARRAY_SIZE(pb44_i2c_board_info));
 	platform_device_register(&pb44_i2c_gpio_device);
+
+	ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
+				 pb44_leds_gpio);
 }
 
 MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 19:59:37 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 19:59:42 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43399 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491948Ab1ABS4x (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:53 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 5C5DC3FC03D;
        Sun,  2 Jan 2011 19:56:50 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id CC9001F0001;
        Sun,  2 Jan 2011 19:56:49 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 15/16] MIPS: ath79: add initial support for the Atheros AP81 reference board
Date:   Sun,  2 Jan 2011 19:56:28 +0100
Message-Id: <1293994589-6794-16-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17F162D47B | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28794
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC:
    - don't use 'default n' for the ATH79_MACH_AP81 Kconfig option

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/Kconfig     |   11 +++++
 arch/mips/ath79/Makefile    |    1 +
 arch/mips/ath79/mach-ap81.c |   94 +++++++++++++++++++++++++++++++++++++++++++
 arch/mips/ath79/machtypes.h |    1 +
 4 files changed, 107 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/mach-ap81.c

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 5d67942..1912d54 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -2,6 +2,17 @@ if ATH79
 
 menu "Atheros AR71XX/AR724X/AR913X machine selection"
 
+config ATH79_MACH_AP81
+	bool "Atheros AP81 reference board"
+	select SOC_AR913X
+	select ATH79_DEV_GPIO_BUTTONS
+	select ATH79_DEV_LEDS_GPIO
+	select ATH79_DEV_SPI
+	select ATH79_DEV_USB
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Atheros AP81 reference board.
+
 config ATH79_MACH_PB44
 	bool "Atheros PB44 reference board"
 	select SOC_AR71XX
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 494d106..1b111d8 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -24,4 +24,5 @@ obj-$(CONFIG_ATH79_DEV_USB)		+= dev-usb.o
 #
 # Machines
 #
+obj-$(CONFIG_ATH79_MACH_AP81)		+= mach-ap81.o
 obj-$(CONFIG_ATH79_MACH_PB44)		+= mach-pb44.o
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
new file mode 100644
index 0000000..909ca5d
--- /dev/null
+++ b/arch/mips/ath79/mach-ap81.c
@@ -0,0 +1,94 @@
+/*
+ *  Atheros AP81 board support
+ *
+ *  Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include "machtypes.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-spi.h"
+#include "dev-usb.h"
+
+#define AP81_GPIO_LED_STATUS	1
+#define AP81_GPIO_LED_AOSS	3
+#define AP81_GPIO_LED_WLAN	6
+#define AP81_GPIO_LED_POWER	14
+
+#define AP81_GPIO_BTN_SW4	12
+#define AP81_GPIO_BTN_SW1	21
+
+#define AP81_KEYS_POLL_INTERVAL		20	/* msecs */
+#define AP81_KEYS_DEBOUNCE_INTERVAL	(3 * AP81_KEYS_POLL_INTERVAL)
+
+static struct gpio_led ap81_leds_gpio[] __initdata = {
+	{
+		.name		= "ap81:green:status",
+		.gpio		= AP81_GPIO_LED_STATUS,
+		.active_low	= 1,
+	}, {
+		.name		= "ap81:amber:aoss",
+		.gpio		= AP81_GPIO_LED_AOSS,
+		.active_low	= 1,
+	}, {
+		.name		= "ap81:green:wlan",
+		.gpio		= AP81_GPIO_LED_WLAN,
+		.active_low	= 1,
+	}, {
+		.name		= "ap81:green:power",
+		.gpio		= AP81_GPIO_LED_POWER,
+		.active_low	= 1,
+	}
+};
+
+static struct gpio_keys_button ap81_gpio_keys[] __initdata = {
+	{
+		.desc		= "sw1",
+		.type		= EV_KEY,
+		.code		= BTN_0,
+		.debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= AP81_GPIO_BTN_SW1,
+		.active_low	= 1,
+	} , {
+		.desc		= "sw4",
+		.type		= EV_KEY,
+		.code		= BTN_1,
+		.debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= AP81_GPIO_BTN_SW4,
+		.active_low	= 1,
+	}
+};
+
+static struct spi_board_info ap81_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p64",
+	}
+};
+
+static struct ath79_spi_platform_data ap81_spi_data = {
+	.bus_num	= 0,
+	.num_chipselect	= 1,
+};
+
+static void __init ap81_setup(void)
+{
+	ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
+				 ap81_leds_gpio);
+	ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
+					ARRAY_SIZE(ap81_gpio_keys),
+					ap81_gpio_keys);
+	ath79_register_spi(&ap81_spi_data, ap81_spi_info,
+			   ARRAY_SIZE(ap81_spi_info));
+	ath79_register_usb();
+}
+
+MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
+	     ap81_setup);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
index a796fa3..3940fe4 100644
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -16,6 +16,7 @@
 
 enum ath79_mach_type {
 	ATH79_MACH_GENERIC = 0,
+	ATH79_MACH_AP81,		/* Atheros AP81 reference board */
 	ATH79_MACH_PB44,		/* Atheros PB44 reference board */
 };
 
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 20:00:01 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 20:00:06 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43416 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491949Ab1ABS4y (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:54 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id EAFC43FC045;
        Sun,  2 Jan 2011 19:56:46 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 4FBEF1F0001;
        Sun,  2 Jan 2011 19:56:46 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 08/16] MIPS: ath79: add common GPIO buttons device
Date:   Sun,  2 Jan 2011 19:56:21 +0100
Message-Id: <1293994589-6794-9-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17EEBB6B28 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28795
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Almost all boards have one or more push buttons connected to GPIO lines.
This patch adds common code to register a platform_device for them.

The patch also adds support for the buttons on the PB44 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - converted to use the gpio_keys_polled driver
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/Kconfig            |    4 ++
 arch/mips/ath79/Makefile           |    1 +
 arch/mips/ath79/dev-gpio-buttons.c |   58 ++++++++++++++++++++++++++++++++++++
 arch/mips/ath79/dev-gpio-buttons.h |   23 ++++++++++++++
 arch/mips/ath79/mach-pb44.c        |   27 ++++++++++++++++
 5 files changed, 113 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/dev-gpio-buttons.c
 create mode 100644 arch/mips/ath79/dev-gpio-buttons.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 5bc480e..185a8d6 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,6 +5,7 @@ menu "Atheros AR71XX/AR724X/AR913X machine selection"
 config ATH79_MACH_PB44
 	bool "Atheros PB44 reference board"
 	select SOC_AR71XX
+	select ATH79_DEV_GPIO_BUTTONS
 	select ATH79_DEV_LEDS_GPIO
 	help
 	  Say 'Y' here if you want your kernel to support the
@@ -21,6 +22,9 @@ config SOC_AR724X
 config SOC_AR913X
 	def_bool n
 
+config ATH79_DEV_GPIO_BUTTONS
+	def_bool n
+
 config ATH79_DEV_LEDS_GPIO
 	def_bool n
 
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index d14b597..0ceb45e 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 # Devices
 #
 obj-y					+= dev-common.o
+obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o
 obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
 
 #
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c
new file mode 100644
index 0000000..4b0168a
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.c
@@ -0,0 +1,58 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include "linux/init.h"
+#include "linux/slab.h"
+#include <linux/platform_device.h>
+
+#include "dev-gpio-buttons.h"
+
+void __init ath79_register_gpio_keys_polled(int id,
+					    unsigned poll_interval,
+					    unsigned nbuttons,
+					    struct gpio_keys_button *buttons)
+{
+	struct platform_device *pdev;
+	struct gpio_keys_platform_data pdata;
+	struct gpio_keys_button *p;
+	int err;
+
+	p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return;
+
+	memcpy(p, buttons, nbuttons * sizeof(*p));
+
+	pdev = platform_device_alloc("gpio-keys-polled", id);
+	if (!pdev)
+		goto err_free_buttons;
+
+	memset(&pdata, 0, sizeof(pdata));
+	pdata.poll_interval = poll_interval;
+	pdata.nbuttons = nbuttons;
+	pdata.buttons = p;
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err)
+		goto err_put_pdev;
+
+	err = platform_device_add(pdev);
+	if (err)
+		goto err_put_pdev;
+
+	return;
+
+err_put_pdev:
+	platform_device_put(pdev);
+
+err_free_buttons:
+	kfree(p);
+}
diff --git a/arch/mips/ath79/dev-gpio-buttons.h b/arch/mips/ath79/dev-gpio-buttons.h
new file mode 100644
index 0000000..481847a
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.h
@@ -0,0 +1,23 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_GPIO_BUTTONS_H
+#define _ATH79_DEV_GPIO_BUTTONS_H
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+void ath79_register_gpio_keys_polled(int id,
+				     unsigned poll_interval,
+				     unsigned nbuttons,
+				     struct gpio_keys_button *buttons);
+
+#endif /* _ATH79_DEV_GPIO_BUTTONS_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index e176779..3dc5080 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -15,15 +15,21 @@
 #include <linux/i2c/pcf857x.h>
 
 #include "machtypes.h"
+#include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
 
 #define PB44_GPIO_I2C_SCL	0
 #define PB44_GPIO_I2C_SDA	1
 
 #define PB44_GPIO_EXP_BASE	16
+#define PB44_GPIO_SW_RESET	(PB44_GPIO_EXP_BASE + 6)
+#define PB44_GPIO_SW_JUMP	(PB44_GPIO_EXP_BASE + 8)
 #define PB44_GPIO_LED_JUMP1	(PB44_GPIO_EXP_BASE + 9)
 #define PB44_GPIO_LED_JUMP2	(PB44_GPIO_EXP_BASE + 10)
 
+#define PB44_KEYS_POLL_INTERVAL		20	/* msecs */
+#define PB44_KEYS_DEBOUNCE_INTERVAL	(3 * PB44_KEYS_POLL_INTERVAL)
+
 static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
 	.sda_pin        = PB44_GPIO_I2C_SDA,
 	.scl_pin        = PB44_GPIO_I2C_SCL,
@@ -60,6 +66,24 @@ static struct gpio_led pb44_leds_gpio[] __initdata = {
 	},
 };
 
+static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
+	{
+		.desc		= "soft_reset",
+		.type		= EV_KEY,
+		.code		= KEY_RESTART,
+		.debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= PB44_GPIO_SW_RESET,
+		.active_low	= 1,
+	} , {
+		.desc		= "jumpstart",
+		.type		= EV_KEY,
+		.code		= KEY_WPS_BUTTON,
+		.debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= PB44_GPIO_SW_JUMP,
+		.active_low	= 1,
+	}
+};
+
 static void __init pb44_init(void)
 {
 	i2c_register_board_info(0, pb44_i2c_board_info,
@@ -68,6 +92,9 @@ static void __init pb44_init(void)
 
 	ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
 				 pb44_leds_gpio);
+	ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
+					ARRAY_SIZE(pb44_gpio_keys),
+					pb44_gpio_keys);
 }
 
 MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 20:00:24 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 20:00:29 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43415 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491950Ab1ABS4y (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:54 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 6E3C63FC043;
        Sun,  2 Jan 2011 19:56:46 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id EF29D1F0001;
        Sun,  2 Jan 2011 19:56:45 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 07/16] MIPS: ath79: add common watchdog device
Date:   Sun,  2 Jan 2011 19:56:20 +0100
Message-Id: <1293994589-6794-8-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17EE4416F1 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28796
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

All supported SoCs have a built-in hardware watchdog driver. This patch
registers a platform_device for that to make it usable.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC:
    - remove the ATH79_DEV_WDT Kconfig option, and move the watchdog platform
      code into dev-common.[ch]

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/dev-common.c |   10 ++++++++++
 arch/mips/ath79/dev-common.h |    1 +
 arch/mips/ath79/setup.c      |    1 +
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
index 897522c..74b1e3b 100644
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -57,3 +57,13 @@ void __init ath79_register_uart(void)
 	ath79_uart_data[0].uartclk = ath79_ahb_freq;
 	platform_device_register(&ath79_uart_device);
 }
+
+static struct platform_device ath79_wdt_device = {
+	.name		= "ath79-wdt",
+	.id		= -1,
+};
+
+void __init ath79_register_wdt(void)
+{
+	platform_device_register(&ath79_wdt_device);
+}
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
index 248622c..0f514e1 100644
--- a/arch/mips/ath79/dev-common.h
+++ b/arch/mips/ath79/dev-common.h
@@ -13,5 +13,6 @@
 #define _ATH79_DEV_COMMON_H
 
 void ath79_register_uart(void);
+void ath79_register_wdt(void);
 
 #endif /* _ATH79_DEV_COMMON_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 5f2b6de..ef4207f 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -259,6 +259,7 @@ static int __init ath79_setup(void)
 {
 	ath79_gpio_init();
 	ath79_register_uart();
+	ath79_register_wdt();
 
 	mips_machine_setup();
 
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 20:00:47 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 20:00:54 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43421 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491952Ab1ABS4y (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:54 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id CA2953FC048;
        Sun,  2 Jan 2011 19:56:47 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 409AD1F0001;
        Sun,  2 Jan 2011 19:56:47 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 10/16] MIPS: ath79: add common SPI controller device
Date:   Sun,  2 Jan 2011 19:56:23 +0100
Message-Id: <1293994589-6794-11-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17EF597FF3 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28797
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Several boards are using the built-in SPI controller of the
AR71XX/AR724X/AR913X SoCs. This patch adds common platform_device
and helper code to register it. Additionally, the patch registers
the SPI bus on the PB44 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/Kconfig                        |    4 ++
 arch/mips/ath79/Makefile                       |    1 +
 arch/mips/ath79/dev-spi.c                      |   38 ++++++++++++++++++++++++
 arch/mips/ath79/dev-spi.h                      |   22 ++++++++++++++
 arch/mips/ath79/mach-pb44.c                    |   17 ++++++++++
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h |    2 +
 6 files changed, 84 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/dev-spi.c
 create mode 100644 arch/mips/ath79/dev-spi.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 185a8d6..cd6c738 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -7,6 +7,7 @@ config ATH79_MACH_PB44
 	select SOC_AR71XX
 	select ATH79_DEV_GPIO_BUTTONS
 	select ATH79_DEV_LEDS_GPIO
+	select ATH79_DEV_SPI
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Atheros PB44 reference board.
@@ -28,4 +29,7 @@ config ATH79_DEV_GPIO_BUTTONS
 config ATH79_DEV_LEDS_GPIO
 	def_bool n
 
+config ATH79_DEV_SPI
+	def_bool n
+
 endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 0ceb45e..a8de078 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 obj-y					+= dev-common.o
 obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o
 obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
+obj-$(CONFIG_ATH79_DEV_SPI)		+= dev-spi.o
 
 #
 # Machines
diff --git a/arch/mips/ath79/dev-spi.c b/arch/mips/ath79/dev-spi.c
new file mode 100644
index 0000000..aa30163
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.c
@@ -0,0 +1,38 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-spi.h"
+
+static struct resource ath79_spi_resources[] = {
+	{
+		.start	= AR71XX_SPI_BASE,
+		.end	= AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ath79_spi_device = {
+	.name		= "ath79-spi",
+	.id		= -1,
+	.resource	= ath79_spi_resources,
+	.num_resources	= ARRAY_SIZE(ath79_spi_resources),
+};
+
+void __init ath79_register_spi(struct ath79_spi_platform_data *pdata,
+			       struct spi_board_info const *info,
+			       unsigned n)
+{
+	spi_register_board_info(info, n);
+	ath79_spi_device.dev.platform_data = pdata;
+	platform_device_register(&ath79_spi_device);
+}
diff --git a/arch/mips/ath79/dev-spi.h b/arch/mips/ath79/dev-spi.h
new file mode 100644
index 0000000..d732565
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.h
@@ -0,0 +1,22 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_SPI_H
+#define _ATH79_DEV_SPI_H
+
+#include <linux/spi/spi.h>
+#include <asm/mach-ath79/ath79_spi_platform.h>
+
+void ath79_register_spi(struct ath79_spi_platform_data *pdata,
+			 struct spi_board_info const *info,
+			 unsigned n);
+
+#endif /* _ATH79_DEV_SPI_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index 3dc5080..ec7b7a1 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -17,6 +17,7 @@
 #include "machtypes.h"
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
+#include "dev-spi.h"
 
 #define PB44_GPIO_I2C_SCL	0
 #define PB44_GPIO_I2C_SDA	1
@@ -84,6 +85,20 @@ static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
 	}
 };
 
+static struct spi_board_info pb44_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p64",
+	},
+};
+
+static struct ath79_spi_platform_data pb44_spi_data = {
+	.bus_num		= 0,
+	.num_chipselect		= 1,
+};
+
 static void __init pb44_init(void)
 {
 	i2c_register_board_info(0, pb44_i2c_board_info,
@@ -95,6 +110,8 @@ static void __init pb44_init(void)
 	ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
 					ARRAY_SIZE(pb44_gpio_keys),
 					pb44_gpio_keys);
+	ath79_register_spi(&pb44_spi_data, pb44_spi_info,
+			   ARRAY_SIZE(pb44_spi_info));
 }
 
 MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 7f2933d..4f2b621 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -20,6 +20,8 @@
 #include <linux/bitops.h>
 
 #define AR71XX_APB_BASE		0x18000000
+#define AR71XX_SPI_BASE		0x1f000000
+#define AR71XX_SPI_SIZE		0x01000000
 
 #define AR71XX_DDR_CTRL_BASE	(AR71XX_APB_BASE + 0x00000000)
 #define AR71XX_DDR_CTRL_SIZE	0x100
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 20:01:13 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 20:01:18 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43422 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491951Ab1ABS4y (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:54 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 756683FC046;
        Sun,  2 Jan 2011 19:56:47 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id C5B761F0001;
        Sun,  2 Jan 2011 19:56:46 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>,
        spi-devel-general@lists.sourceforge.net
Subject: [PATCH v4 09/16] spi: add SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
Date:   Sun,  2 Jan 2011 19:56:22 +0100
Message-Id: <1293994589-6794-10-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17EF135CBE | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28798
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

The Atheros AR71XX/AR724X/AR913X SoCs have a built-in SPI controller. This
patch implements a driver for that.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: spi-devel-general@lists.sourceforge.net
---
Changes since RFC:
    - remove DRV_DESC definition and use its previous value directly in the
      MODULE_DESCRIPTION() macro,
    - use io{read,write}32 accesors instead of __raw_{read,write}l,
    - use __dev{init,exit,exit_p} annotations where in the appropriate places,
    - initialize 'master->bus_num' field to -1 if no platform data specified,
      so that a bus number can be dynamically assigned,
    - rename ath79_spi_drv to ath79_spi_driver to avoid section mismatch
      warnings

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

 .../include/asm/mach-ath79/ath79_spi_platform.h    |   19 ++
 drivers/spi/Kconfig                                |    8 +
 drivers/spi/Makefile                               |    1 +
 drivers/spi/ath79_spi.c                            |  290 ++++++++++++++++++++
 4 files changed, 318 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
 create mode 100644 drivers/spi/ath79_spi.c

diff --git a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
new file mode 100644
index 0000000..aa71216
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
@@ -0,0 +1,19 @@
+/*
+ *  Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_SPI_PLATFORM_H
+#define _ATH79_SPI_PLATFORM_H
+
+struct ath79_spi_platform_data {
+	unsigned	bus_num;
+	unsigned	num_chipselect;
+};
+
+#endif /* _ATH79_SPI_PLATFORM_H */
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 78f9fd0..f2093e1 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -53,6 +53,14 @@ if SPI_MASTER
 
 comment "SPI Master Controller Drivers"
 
+config SPI_ATH79
+	tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
+	depends on ATH79 && GENERIC_GPIO
+	select SPI_BITBANG
+	help
+	  This enables support for the SPI controller present on the
+	  Atheros AR71XX/AR724X/AR913X SoCs.
+
 config SPI_ATMEL
 	tristate "Atmel SPI Controller"
 	depends on (ARCH_AT91 || AVR32)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 8bc1a5a..875bc3d 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SPI_MASTER)		+= spi.o
 
 # SPI master controller drivers (bus)
 obj-$(CONFIG_SPI_ATMEL)			+= atmel_spi.o
+obj-$(CONFIG_SPI_ATH79)			+= ath79_spi.o
 obj-$(CONFIG_SPI_BFIN)			+= spi_bfin5xx.o
 obj-$(CONFIG_SPI_BITBANG)		+= spi_bitbang.o
 obj-$(CONFIG_SPI_AU1550)		+= au1550_spi.o
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
new file mode 100644
index 0000000..96f169a
--- /dev/null
+++ b/drivers/spi/ath79_spi.c
@@ -0,0 +1,290 @@
+/*
+ * SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
+ *
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This driver has been based on the spi-gpio.c:
+ *	Copyright (C) 2006,2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79_spi_platform.h>
+
+#define DRV_NAME	"ath79-spi"
+
+struct ath79_spi {
+	struct	spi_bitbang	bitbang;
+	u32			ioc_base;
+	u32			reg_ctrl;
+
+	void __iomem		*base;
+
+	struct platform_device	*pdev;
+};
+
+static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
+{
+	return ioread32(sp->base + reg);
+}
+
+static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned reg, u32 val)
+{
+	iowrite32(val, sp->base + reg);
+}
+
+static inline struct ath79_spi *spidev_to_sp(struct spi_device *spi)
+{
+	return spi_master_get_devdata(spi->master);
+}
+
+static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
+{
+	struct ath79_spi *sp = spidev_to_sp(spi);
+	int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
+
+	if (is_active) {
+		/* set initial clock polarity */
+		if (spi->mode & SPI_CPOL)
+			sp->ioc_base |= AR71XX_SPI_IOC_CLK;
+		else
+			sp->ioc_base &= ~AR71XX_SPI_IOC_CLK;
+
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+	}
+
+	if (spi->chip_select) {
+		unsigned long gpio = (unsigned long) spi->controller_data;
+
+		/* SPI is normally active-low */
+		gpio_set_value(gpio, cs_high);
+	} else {
+		if (cs_high)
+			sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+		else
+			sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+	}
+
+}
+
+static int ath79_spi_setup_cs(struct spi_device *spi)
+{
+	struct ath79_spi *sp = spidev_to_sp(spi);
+
+	/* enable GPIO mode */
+	ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
+
+	/* save CTRL register */
+	sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL);
+	sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC);
+
+	/* TODO: setup speed? */
+	ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
+
+	if (spi->chip_select) {
+		unsigned long gpio = (unsigned long) spi->controller_data;
+		int status = 0;
+
+		status = gpio_request(gpio, dev_name(&spi->dev));
+		if (status)
+			return status;
+
+		status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH);
+		if (status) {
+			gpio_free(gpio);
+			return status;
+		}
+	} else {
+		if (spi->mode & SPI_CS_HIGH)
+			sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+		else
+			sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+	}
+
+	return 0;
+}
+
+static void ath79_spi_cleanup_cs(struct spi_device *spi)
+{
+	struct ath79_spi *sp = spidev_to_sp(spi);
+
+	if (spi->chip_select) {
+		unsigned long gpio = (unsigned long) spi->controller_data;
+		gpio_free(gpio);
+	}
+
+	/* restore CTRL register */
+	ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
+	/* disable GPIO mode */
+	ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
+}
+
+static int ath79_spi_setup(struct spi_device *spi)
+{
+	int status = 0;
+
+	if (spi->bits_per_word > 32)
+		return -EINVAL;
+
+	if (!spi->controller_state) {
+		status = ath79_spi_setup_cs(spi);
+		if (status)
+			return status;
+	}
+
+	status = spi_bitbang_setup(spi);
+	if (status && !spi->controller_state)
+		ath79_spi_cleanup_cs(spi);
+
+	return status;
+}
+
+static void ath79_spi_cleanup(struct spi_device *spi)
+{
+	ath79_spi_cleanup_cs(spi);
+	spi_bitbang_cleanup(spi);
+}
+
+static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
+			       u32 word, u8 bits)
+{
+	struct ath79_spi *sp = spidev_to_sp(spi);
+	u32 ioc = sp->ioc_base;
+
+	/* clock starts at inactive polarity */
+	for (word <<= (32 - bits); likely(bits); bits--) {
+		u32 out;
+
+		if (word & (1 << 31))
+			out = ioc | AR71XX_SPI_IOC_DO;
+		else
+			out = ioc & ~AR71XX_SPI_IOC_DO;
+
+		/* setup MSB (to slave) on trailing edge */
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK);
+
+		word <<= 1;
+	}
+
+	return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
+}
+
+static __devinit int ath79_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct ath79_spi *sp;
+	struct ath79_spi_platform_data *pdata;
+	struct resource	*r;
+	int ret;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(*sp));
+	if (master == NULL) {
+		dev_err(&pdev->dev, "failed to allocate spi master\n");
+		return -ENOMEM;
+	}
+
+	sp = spi_master_get_devdata(master);
+	platform_set_drvdata(pdev, sp);
+
+	pdata = pdev->dev.platform_data;
+
+	master->setup = ath79_spi_setup;
+	master->cleanup = ath79_spi_cleanup;
+	if (pdata) {
+		master->bus_num = pdata->bus_num;
+		master->num_chipselect = pdata->num_chipselect;
+	} else {
+		master->bus_num = -1;
+		master->num_chipselect = 1;
+	}
+
+	sp->bitbang.master = spi_master_get(master);
+	sp->bitbang.chipselect = ath79_spi_chipselect;
+	sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
+	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
+	sp->bitbang.flags = SPI_CS_HIGH;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (r == NULL) {
+		ret = -ENOENT;
+		goto err_put_master;
+	}
+
+	sp->base = ioremap(r->start, r->end - r->start + 1);
+	if (!sp->base) {
+		ret = -ENXIO;
+		goto err_put_master;
+	}
+
+	ret = spi_bitbang_start(&sp->bitbang);
+	if (ret)
+		goto err_unmap;
+
+	return 0;
+
+err_unmap:
+	iounmap(sp->base);
+err_put_master:
+	platform_set_drvdata(pdev, NULL);
+	spi_master_put(sp->bitbang.master);
+
+	return ret;
+}
+
+static __devexit int ath79_spi_remove(struct platform_device *pdev)
+{
+	struct ath79_spi *sp = platform_get_drvdata(pdev);
+
+	spi_bitbang_stop(&sp->bitbang);
+	iounmap(sp->base);
+	platform_set_drvdata(pdev, NULL);
+	spi_master_put(sp->bitbang.master);
+
+	return 0;
+}
+
+static struct platform_driver ath79_spi_driver = {
+	.probe		= ath79_spi_probe,
+	.remove		= __devexit_p(ath79_spi_remove),
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static __init int ath79_spi_init(void)
+{
+	return platform_driver_register(&ath79_spi_driver);
+}
+module_init(ath79_spi_init);
+
+static __exit void ath79_spi_exit(void)
+{
+	platform_driver_unregister(&ath79_spi_driver);
+}
+module_exit(ath79_spi_exit);
+
+MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR91X");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 20:01:36 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 20:01:42 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43426 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491954Ab1ABS4z (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:55 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id B0CA43FC049;
        Sun,  2 Jan 2011 19:56:48 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 08D311F0001;
        Sun,  2 Jan 2011 19:56:48 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>,
        Greg Kroah-Hartman <gregkh@suse.de>, linux-usb@vger.kernel.org
Subject: [PATCH v4 12/16] USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR913X SoCs
Date:   Sun,  2 Jan 2011 19:56:25 +0100
Message-Id: <1293994589-6794-13-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17F027C157 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28799
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

The Atheros AR71XX/AR724X/AR913X SoCs have a built-in EHCI controller.
This patch adds the necessary glue code to make the generic EHCI driver
usable for them.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-usb@vger.kernel.org
---
Changes since RFC:
    - don't use 'default y if SOC_*', select USB_ARCH_HAS_EHCI option in the
      platform specific Kconfig file instead
    - add missing 'ath79_ehci_platform.h' file

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/Kconfig                            |    3 +
 .../include/asm/mach-ath79/ath79_ehci_platform.h   |   18 ++
 drivers/usb/host/Kconfig                           |    8 +
 drivers/usb/host/ehci-ath79.c                      |  176 ++++++++++++++++++++
 drivers/usb/host/ehci-hcd.c                        |    5 +
 5 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
 create mode 100644 drivers/usb/host/ehci-ath79.c

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index cd6c738..647f535 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -15,12 +15,15 @@ config ATH79_MACH_PB44
 endmenu
 
 config SOC_AR71XX
+	select USB_ARCH_HAS_EHCI
 	def_bool n
 
 config SOC_AR724X
+	select USB_ARCH_HAS_EHCI
 	def_bool n
 
 config SOC_AR913X
+	select USB_ARCH_HAS_EHCI
 	def_bool n
 
 config ATH79_DEV_GPIO_BUTTONS
diff --git a/arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h b/arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
new file mode 100644
index 0000000..6ee075f
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
@@ -0,0 +1,18 @@
+/*
+ *  Platform data definition for Atheros AR71XX/AR913X EHCI controller
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_EHCI_PLATFORM_H
+#define _ATH79_EHCI_PLATFORM_H
+
+struct ath79_ehci_platform_data {
+	u8	is_ar913x;
+};
+
+#endif /* _ATH79_EHCI_PLATFORM_H */
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6f4f8e6..3a2667a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -147,6 +147,14 @@ config USB_W90X900_EHCI
 	---help---
 		Enables support for the W90X900 USB controller
 
+config USB_EHCI_ATH79
+	bool "EHCI support for AR71XX/AR724X/AR913X SoCs"
+	depends on USB_EHCI_HCD && ATH79
+	select USB_EHCI_ROOT_HUB_TT
+	---help---
+	  Enables support for the built-in EHCI controller present
+	  on the Atheros AR71XX/AR724X/AR913X SoCs.
+
 config USB_OXU210HP_HCD
 	tristate "OXU210HP HCD support"
 	depends on USB
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c
new file mode 100644
index 0000000..43a728f
--- /dev/null
+++ b/drivers/usb/host/ehci-ath79.c
@@ -0,0 +1,176 @@
+/*
+ *  Bus Glue for Atheros AR71XX/AR913X built-in EHCI controller.
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *	Copyright (C) 2007 Atheros Communications, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach-ath79/ath79_ehci_platform.h>
+
+static int ehci_ath79_init(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	struct ath79_ehci_platform_data *pdata;
+	int ret;
+
+	pdata = hcd->self.controller->platform_data;
+
+	if (pdata->is_ar913x) {
+		hcd->has_tt = 1;
+
+		ehci->caps = hcd->regs + 0x100;
+		ehci->regs = hcd->regs + 0x100 +
+			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	} else {
+		ehci->has_synopsys_hc_bug = 1;
+
+		ehci->caps = hcd->regs;
+		ehci->regs = hcd->regs +
+			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	}
+
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+	ehci->sbrn = 0x20;
+
+	ehci_reset(ehci);
+
+	ret = ehci_init(hcd);
+	if (ret)
+		return ret;
+
+	ehci_port_power(ehci, 0);
+
+	return 0;
+}
+
+static const struct hc_driver ehci_ath79_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "Atheros built-in EHCI controller",
+	.hcd_priv_size		= sizeof(struct ehci_hcd),
+	.irq			= ehci_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	.reset			= ehci_ath79_init,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_shutdown,
+
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+	.endpoint_reset		= ehci_endpoint_reset,
+
+	.get_frame_number	= ehci_get_frame,
+
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+#ifdef CONFIG_PM
+	.hub_suspend		= ehci_hub_suspend,
+	.hub_resume		= ehci_hub_resume,
+#endif
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+};
+
+static int ehci_ath79_probe(struct platform_device *pdev)
+{
+	struct ath79_ehci_platform_data *pdata;
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int ret;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_dbg(&pdev->dev, "no platform data specified for %s\n",
+			dev_name(&pdev->dev));
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
+			dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+	irq = res->start;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "no base address specified for %s\n",
+			dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+
+	hcd = usb_create_hcd(&ehci_ath79_hc_driver, &pdev->dev,
+			     dev_name(&pdev->dev));
+	if (!hcd)
+		return -ENOMEM;
+
+	hcd->rsrc_start	= res->start;
+	hcd->rsrc_len	= res->end - res->start + 1;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		dev_dbg(&pdev->dev, "controller already in use\n");
+		ret = -EBUSY;
+		goto err_put_hcd;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_dbg(&pdev->dev, "error mapping memory\n");
+		ret = -EFAULT;
+		goto err_release_region;
+	}
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+	if (ret)
+		goto err_iounmap;
+
+	return 0;
+
+err_iounmap:
+	iounmap(hcd->regs);
+
+err_release_region:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+static int ehci_ath79_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	return 0;
+}
+
+static struct platform_driver ehci_ath79_driver = {
+	.probe		= ehci_ath79_probe,
+	.remove		= ehci_ath79_remove,
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "ath79-ehci",
+	}
+};
+
+MODULE_ALIAS("platform:ath79-ehci");
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index e906280..b1313af 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1216,6 +1216,11 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_octeon_driver
 #endif
 
+#ifdef CONFIG_USB_EHCI_ATH79
+#include "ehci-ath79.c"
+#define PLATFORM_DRIVER		ehci_ath79_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
     !defined(XILINX_OF_PLATFORM_DRIVER)
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 20:02:01 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 20:02:06 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43425 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491953Ab1ABS4z (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:55 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 413F93FC039;
        Sun,  2 Jan 2011 19:56:48 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id A3A1A1F0001;
        Sun,  2 Jan 2011 19:56:47 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>,
        Greg Kroah-Hartman <gregkh@suse.de>, linux-usb@vger.kernel.org
Subject: [PATCH v4 11/16] USB: ehci: add workaround for Synopsys HC bug
Date:   Sun,  2 Jan 2011 19:56:24 +0100
Message-Id: <1293994589-6794-12-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17EF90146A | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28800
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

A Synopsys USB core used in various SoCs has a bug which might cause
that the host controller not issuing ping.

When software uses the Doorbell mechanism to remove queue heads, the
host controller still has references to the removed queue head even
after indicating an Interrupt on Async Advance. This happens if the last
executed queue head's Next Link queue head is removed.

Consequences of the defect:
The Host controller fetches the removed queue head, using memory that
would otherwise be deallocated.This results in incorrect transactions on
both the USB and system memory. This may result in undefined behavior.

Workarounds:

1) If no queue head is active (no Status field's Active bit is set)
after removing the queue heads, the software can write one of the valid
queue head addresses to the ASYNCLISTADDR register and deallocate the
removed queue head's memory after 2 microframes.

If one or more of the queue heads is active (the Active bit is set in
the Status field) after removing the queue heads, the software can delay
memory deallocation after time X, where X is the time required for the
Host Controller to go through all the queue heads once. X varies with
the number of queue heads and the time required to process periodic
transactions: if more periodic transactions must be performed, the Host
Controller has less time to process asynchronous transaction processing.

2) Do not use the Doorbell mechanism to remove the queue heads. Disable
the Asynchronous Schedule Enable bit instead.

The bug has been discussed on the linux-usb-devel mailing-list
four years ago, the original thread can be found here:
http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg45345.html

This patch implements the first workaround as suggested by David Brownell.
The built-in USB host controller of the Atheros AR7130/AR7141/AR7161 SoCs
requires this to work properly.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-usb@vger.kernel.org
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

 drivers/usb/host/ehci-q.c |    3 +++
 drivers/usb/host/ehci.h   |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 233c288..343b8de 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1193,6 +1193,9 @@ static void end_unlink_async (struct ehci_hcd *ehci)
 		ehci->reclaim = NULL;
 		start_unlink_async (ehci, next);
 	}
+
+	if (ehci->has_synopsys_hc_bug)
+		writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
 }
 
 /* makes sure the async qh will become idle */
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index ba8eab3..6da85b2 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -133,6 +133,7 @@ struct ehci_hcd {			/* one per controller */
 	unsigned		broken_periodic:1;
 	unsigned		fs_i_thresh:1;	/* Intel iso scheduling */
 	unsigned		use_dummy_qh:1;	/* AMD Frame List table quirk*/
+	unsigned		has_synopsys_hc_bug:1; /* Synopsys HC */
 
 	/* required for usb32 quirk */
 	#define OHCI_CTRL_HCFS          (3 << 6)
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 20:02:24 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 20:02:29 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43432 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491955Ab1ABS4z (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:55 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 459E63FC04A;
        Sun,  2 Jan 2011 19:56:49 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 8B3BD1F0001;
        Sun,  2 Jan 2011 19:56:48 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>,
        Greg Kroah-Hartman <gregkh@suse.de>, linux-usb@vger.kernel.org
Subject: [PATCH v4 13/16] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs
Date:   Sun,  2 Jan 2011 19:56:26 +0100
Message-Id: <1293994589-6794-14-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17F0C0ED59 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28801
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

The Atheros AR71XX/AR7240 SoCs have a built-in OHCI controller.
This patch adds the necessary glue code to make the generic OHCI
driver usable for them.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-usb@vger.kernel.org
---
Changes since RFC:
    - don't use 'defauly y if SOC_*', select the USB_ARCH_HAS_OHCI option
      in the platform specific Kconfig file instead
    - remove ath79_ehci_platform.h, it belongs to the EHCI patch

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/Kconfig       |    2 +
 drivers/usb/host/Kconfig      |    8 ++
 drivers/usb/host/ohci-ath79.c |  162 +++++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/ohci-hcd.c   |    5 +
 4 files changed, 177 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/host/ohci-ath79.c

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 647f535..d4456ce 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -16,10 +16,12 @@ endmenu
 
 config SOC_AR71XX
 	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
 	def_bool n
 
 config SOC_AR724X
 	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
 	def_bool n
 
 config SOC_AR913X
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3a2667a..39ed353 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -240,6 +240,14 @@ config USB_OHCI_HCD_OMAP3
 	  Enables support for the on-chip OHCI controller on
 	  OMAP3 and later chips.
 
+config USB_OHCI_ATH79
+	bool "USB OHCI support for the Atheros AR71XX/AR724X SoCs"
+	depends on USB_OHCI_HCD && (SOC_AR71XX || SOC_AR724X)
+	default y
+	help
+	  Enables support for the uilt-in OHCI controller present on the
+	  Atheros AR71XX/AR724X SoCs.
+
 config USB_OHCI_HCD_PPC_SOC
 	bool "OHCI support for on-chip PPC USB controller"
 	depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
diff --git a/drivers/usb/host/ohci-ath79.c b/drivers/usb/host/ohci-ath79.c
new file mode 100644
index 0000000..6e864bf
--- /dev/null
+++ b/drivers/usb/host/ohci-ath79.c
@@ -0,0 +1,162 @@
+/*
+ *  OHCI HCD (Host Controller Driver) for USB.
+ *
+ *  Bus Glue for Atheros AR71XX/AR724X built-in OHCI controller.
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *	Copyright (C) 2007 Atheros Communications, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+
+static int usb_hcd_ath79_probe(const struct hc_driver *driver,
+			       struct platform_device *pdev)
+{
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
+			dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+	irq = res->start;
+
+	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	if (!hcd)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "no base address specified for %s\n",
+			dev_name(&pdev->dev));
+		ret = -ENODEV;
+		goto err_put_hcd;
+	}
+	hcd->rsrc_start	= res->start;
+	hcd->rsrc_len	= res->end - res->start + 1;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		dev_dbg(&pdev->dev, "controller already in use\n");
+		ret = -EBUSY;
+		goto err_put_hcd;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_dbg(&pdev->dev, "error mapping memory\n");
+		ret = -EFAULT;
+		goto err_release_region;
+	}
+
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+	if (ret)
+		goto err_stop_hcd;
+
+	return 0;
+
+err_stop_hcd:
+	iounmap(hcd->regs);
+err_release_region:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+void usb_hcd_ath79_remove(struct usb_hcd *hcd, struct platform_device *pdev)
+{
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+}
+
+static int __devinit ohci_ath79_start(struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+	int ret;
+
+	ret = ohci_init(ohci);
+	if (ret < 0)
+		return ret;
+
+	ret = ohci_run(ohci);
+	if (ret < 0)
+		goto err;
+
+	return 0;
+
+err:
+	ohci_stop(hcd);
+	return ret;
+}
+
+static const struct hc_driver ohci_ath79_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "Atheros built-in OHCI controller",
+	.hcd_priv_size		= sizeof(struct ohci_hcd),
+
+	.irq			= ohci_irq,
+	.flags			= HCD_USB11 | HCD_MEMORY,
+
+	.start			= ohci_ath79_start,
+	.stop			= ohci_stop,
+	.shutdown		= ohci_shutdown,
+
+	.urb_enqueue		= ohci_urb_enqueue,
+	.urb_dequeue		= ohci_urb_dequeue,
+	.endpoint_disable	= ohci_endpoint_disable,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= ohci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ohci_hub_status_data,
+	.hub_control		= ohci_hub_control,
+	.start_port_reset	= ohci_start_port_reset,
+};
+
+static int ohci_hcd_ath79_drv_probe(struct platform_device *pdev)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	return usb_hcd_ath79_probe(&ohci_ath79_hc_driver, pdev);
+}
+
+static int ohci_hcd_ath79_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_hcd_ath79_remove(hcd, pdev);
+	return 0;
+}
+
+static struct platform_driver ohci_hcd_ath79_driver = {
+	.probe		= ohci_hcd_ath79_drv_probe,
+	.remove		= ohci_hcd_ath79_drv_remove,
+	.shutdown	= usb_hcd_platform_shutdown,
+	.driver		= {
+		.name	= "ath79-ohci",
+		.owner	= THIS_MODULE,
+	},
+};
+
+MODULE_ALIAS("platform:ath79-ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5179acb..6daeb68 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1111,6 +1111,11 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ohci_octeon_driver
 #endif
 
+#ifdef CONFIG_USB_OHCI_ATH79
+#include "ohci-ath79.c"
+#define PLATFORM_DRIVER		ohci_hcd_ath79_driver
+#endif
+
 #if	!defined(PCI_DRIVER) &&		\
 	!defined(PLATFORM_DRIVER) &&	\
 	!defined(OMAP1_PLATFORM_DRIVER) &&	\
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 20:02:47 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 20:02:54 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43433 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491956Ab1ABS4z (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:55 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 05E913FC03B;
        Sun,  2 Jan 2011 19:56:50 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 1AC191F0001;
        Sun,  2 Jan 2011 19:56:49 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 14/16] MIPS: ath79: add common USB Host Controller device
Date:   Sun,  2 Jan 2011 19:56:27 +0100
Message-Id: <1293994589-6794-15-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17F12C11C8 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28802
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Add common platform_device and helper code to make the registration of
the built-in USB controllers easier on the board which are using them.
Also register the USB controller on the PB44 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/Kconfig                        |    4 +
 arch/mips/ath79/Makefile                       |    1 +
 arch/mips/ath79/dev-usb.c                      |  194 ++++++++++++++++++++++++
 arch/mips/ath79/dev-usb.h                      |   17 ++
 arch/mips/ath79/mach-pb44.c                    |    2 +
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h |   22 +++-
 6 files changed, 239 insertions(+), 1 deletions(-)
 create mode 100644 arch/mips/ath79/dev-usb.c
 create mode 100644 arch/mips/ath79/dev-usb.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index d4456ce..5d67942 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -8,6 +8,7 @@ config ATH79_MACH_PB44
 	select ATH79_DEV_GPIO_BUTTONS
 	select ATH79_DEV_LEDS_GPIO
 	select ATH79_DEV_SPI
+	select ATH79_DEV_USB
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Atheros PB44 reference board.
@@ -37,4 +38,7 @@ config ATH79_DEV_LEDS_GPIO
 config ATH79_DEV_SPI
 	def_bool n
 
+config ATH79_DEV_USB
+	def_bool n
+
 endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index a8de078..494d106 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -19,6 +19,7 @@ obj-y					+= dev-common.o
 obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o
 obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
 obj-$(CONFIG_ATH79_DEV_SPI)		+= dev-spi.o
+obj-$(CONFIG_ATH79_DEV_USB)		+= dev-usb.o
 
 #
 # Machines
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
new file mode 100644
index 0000000..fb7033f
--- /dev/null
+++ b/arch/mips/ath79/dev-usb.c
@@ -0,0 +1,194 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X USB Host Controller support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79_ehci_platform.h>
+#include "common.h"
+#include "dev-usb.h"
+
+static void __iomem *ath79_usb_ctrl_base;
+
+static struct resource ar71xx_ohci_resources[] = {
+	[0] = {
+		.start	= AR71XX_OHCI_BASE,
+		.end	= AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= ATH79_MISC_IRQ_OHCI,
+		.end	= ATH79_MISC_IRQ_OHCI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ar724x_usb_resources[] = {
+	[0] = {
+		.start	= AR7240_OHCI_BASE,
+		.end	= AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= ATH79_CPU_IRQ_USB,
+		.end	= ATH79_CPU_IRQ_USB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32);
+static struct platform_device ath79_ohci_device = {
+	.name		= "ath79-ohci",
+	.id		= -1,
+	.resource	= ar71xx_ohci_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_ohci_resources),
+	.dev = {
+		.dma_mask		= &ath79_ohci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+static struct resource ar71xx_ehci_resources[] = {
+	[0] = {
+		.start	= AR71XX_EHCI_BASE,
+		.end	= AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= ATH79_CPU_IRQ_USB,
+		.end	= ATH79_CPU_IRQ_USB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
+static struct ath79_ehci_platform_data ath79_ehci_data;
+
+static struct platform_device ath79_ehci_device = {
+	.name		= "ath79-ehci",
+	.id		= -1,
+	.resource	= ar71xx_ehci_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_ehci_resources),
+	.dev = {
+		.dma_mask		= &ath79_ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &ath79_ehci_data,
+	},
+};
+
+#define AR71XX_USB_RESET_MASK	(AR71XX_RESET_USB_HOST | \
+				 AR71XX_RESET_USB_PHY | \
+				 AR71XX_RESET_USB_OHCI_DLL)
+
+static void __init ar71xx_usb_setup(void)
+{
+	ath79_device_reset_set(AR71XX_USB_RESET_MASK);
+	mdelay(1000);
+	ath79_device_reset_clear(AR71XX_USB_RESET_MASK);
+
+	/* Turning on the Buff and Desc swap bits */
+	__raw_writel(0xf0000, ath79_usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG);
+
+	/* WAR for HW bug. Here it adjusts the duration between two SOFS */
+	__raw_writel(0x20c00, ath79_usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
+
+	mdelay(900);
+
+	platform_device_register(&ath79_ohci_device);
+	platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar7240_usb_setup(void)
+{
+	ath79_device_reset_clear(AR7240_RESET_OHCI_DLL);
+	ath79_device_reset_set(AR7240_RESET_USB_HOST);
+	mdelay(1000);
+	ath79_device_reset_set(AR7240_RESET_OHCI_DLL);
+	ath79_device_reset_clear(AR7240_RESET_USB_HOST);
+
+	/* WAR for HW bug. Here it adjusts the duration between two SOFS */
+	__raw_writel(0x3, ath79_usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
+
+	ath79_ohci_device.resource = ar724x_usb_resources;
+	ath79_ohci_device.num_resources = ARRAY_SIZE(ar724x_usb_resources);
+	platform_device_register(&ath79_ohci_device);
+}
+
+static void __init ar724x_usb_setup(void)
+{
+	ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR724X_RESET_USB_HOST);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR724X_RESET_USB_PHY);
+	mdelay(10);
+
+	ath79_ehci_data.is_ar913x = 1;
+	ath79_ehci_device.resource = ar724x_usb_resources;
+	ath79_ehci_device.num_resources = ARRAY_SIZE(ar724x_usb_resources);
+	platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar913x_usb_setup(void)
+{
+	ath79_device_reset_set(AR71XX_RESET_USBSUS_OVERRIDE);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR71XX_RESET_USB_HOST);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR71XX_RESET_USB_PHY);
+	mdelay(10);
+
+	ath79_ehci_data.is_ar913x = 1;
+	platform_device_register(&ath79_ehci_device);
+}
+
+void __init ath79_register_usb(void)
+{
+	ath79_usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE,
+				      AR71XX_USB_CTRL_SIZE);
+
+	switch (ath79_soc) {
+	case ATH79_SOC_AR7130:
+	case ATH79_SOC_AR7141:
+	case ATH79_SOC_AR7161:
+		ar71xx_usb_setup();
+		break;
+
+	case ATH79_SOC_AR7240:
+		ar7240_usb_setup();
+		break;
+
+	case ATH79_SOC_AR7241:
+	case ATH79_SOC_AR7242:
+		ar724x_usb_setup();
+		break;
+
+	case ATH79_SOC_AR9130:
+	case ATH79_SOC_AR9132:
+		ar913x_usb_setup();
+		break;
+
+	default:
+		BUG();
+	}
+}
diff --git a/arch/mips/ath79/dev-usb.h b/arch/mips/ath79/dev-usb.h
new file mode 100644
index 0000000..4b86a69
--- /dev/null
+++ b/arch/mips/ath79/dev-usb.h
@@ -0,0 +1,17 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X USB Host Controller support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_USB_H
+#define _ATH79_DEV_USB_H
+
+void ath79_register_usb(void);
+
+#endif /* _ATH79_DEV_USB_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index ec7b7a1..fe9701a 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -18,6 +18,7 @@
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
 #include "dev-spi.h"
+#include "dev-usb.h"
 
 #define PB44_GPIO_I2C_SCL	0
 #define PB44_GPIO_I2C_SDA	1
@@ -112,6 +113,7 @@ static void __init pb44_init(void)
 					pb44_gpio_keys);
 	ath79_register_spi(&pb44_spi_data, pb44_spi_info,
 			   ARRAY_SIZE(pb44_spi_info));
+	ath79_register_usb();
 }
 
 MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 4f2b621..f125f1e 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -20,6 +20,10 @@
 #include <linux/bitops.h>
 
 #define AR71XX_APB_BASE		0x18000000
+#define AR71XX_EHCI_BASE	0x1b000000
+#define AR71XX_EHCI_SIZE	0x1000
+#define AR71XX_OHCI_BASE	0x1c000000
+#define AR71XX_OHCI_SIZE	0x1000
 #define AR71XX_SPI_BASE		0x1f000000
 #define AR71XX_SPI_SIZE		0x01000000
 
@@ -27,6 +31,8 @@
 #define AR71XX_DDR_CTRL_SIZE	0x100
 #define AR71XX_UART_BASE	(AR71XX_APB_BASE + 0x00020000)
 #define AR71XX_UART_SIZE	0x100
+#define AR71XX_USB_CTRL_BASE	(AR71XX_APB_BASE + 0x00030000)
+#define AR71XX_USB_CTRL_SIZE	0x100
 #define AR71XX_GPIO_BASE        (AR71XX_APB_BASE + 0x00040000)
 #define AR71XX_GPIO_SIZE        0x100
 #define AR71XX_PLL_BASE		(AR71XX_APB_BASE + 0x00050000)
@@ -34,6 +40,9 @@
 #define AR71XX_RESET_BASE	(AR71XX_APB_BASE + 0x00060000)
 #define AR71XX_RESET_SIZE	0x100
 
+#define AR7240_OHCI_BASE	0x1b000000
+#define AR7240_OHCI_SIZE	0x1000
+
 /*
  * DDR_CTRL block
  */
@@ -102,6 +111,12 @@
 #define AR913X_AHB_DIV_MASK		0x1
 
 /*
+ * USB_CONFIG block
+ */
+#define AR71XX_USB_CTRL_REG_FLADJ	0x00
+#define AR71XX_USB_CTRL_REG_CONFIG	0x04
+
+/*
  * RESET block
  */
 #define AR71XX_RESET_REG_TIMER			0x00
@@ -155,12 +170,17 @@
 #define AR71XX_RESET_PCI_BUS		BIT(1)
 #define AR71XX_RESET_PCI_CORE		BIT(0)
 
+#define AR7240_RESET_USB_HOST		BIT(5)
+#define AR7240_RESET_OHCI_DLL		BIT(3)
+
 #define AR724X_RESET_GE1_MDIO		BIT(23)
 #define AR724X_RESET_GE0_MDIO		BIT(22)
 #define AR724X_RESET_PCIE_PHY_SERIAL	BIT(10)
 #define AR724X_RESET_PCIE_PHY		BIT(7)
 #define AR724X_RESET_PCIE		BIT(6)
-#define AR724X_RESET_OHCI_DLL		BIT(3)
+#define AR724X_RESET_USB_HOST		BIT(5)
+#define AR724X_RESET_USB_PHY		BIT(4)
+#define AR724X_RESET_USBSUS_OVERRIDE	BIT(3)
 
 #define AR913X_RESET_AMBA2WMAC		BIT(22)
 
-- 
1.7.2.1


From juhosg@openwrt.org Sun Jan  2 20:03:13 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 20:03:18 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:43439 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491957Ab1ABS46 (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 19:56:58 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id CE7EC3FC03E;
        Sun,  2 Jan 2011 19:56:50 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 3C8581F0001;
        Sun,  2 Jan 2011 19:56:50 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v4 16/16] MIPS: ath79: add common WMAC device for AR913X based boards
Date:   Sun,  2 Jan 2011 19:56:29 +0100
Message-Id: <1293994589-6794-17-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A17F1A9CA4D | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28803
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Add common platform_device and helper code to make the registration
of the built-in wireless MAC easier on the Atheros AR9130/AR9132
based boards. Also register the WMAC device on the AR81 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

 arch/mips/ath79/Kconfig                        |    5 ++
 arch/mips/ath79/Makefile                       |    1 +
 arch/mips/ath79/dev-ar913x-wmac.c              |   60 ++++++++++++++++++++++++
 arch/mips/ath79/dev-ar913x-wmac.h              |   17 +++++++
 arch/mips/ath79/mach-ap81.c                    |    6 ++
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h |    3 +
 6 files changed, 92 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/dev-ar913x-wmac.c
 create mode 100644 arch/mips/ath79/dev-ar913x-wmac.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 1912d54..af01669 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,6 +5,7 @@ menu "Atheros AR71XX/AR724X/AR913X machine selection"
 config ATH79_MACH_AP81
 	bool "Atheros AP81 reference board"
 	select SOC_AR913X
+	select ATH79_DEV_AR913X_WMAC
 	select ATH79_DEV_GPIO_BUTTONS
 	select ATH79_DEV_LEDS_GPIO
 	select ATH79_DEV_SPI
@@ -40,6 +41,10 @@ config SOC_AR913X
 	select USB_ARCH_HAS_EHCI
 	def_bool n
 
+config ATH79_DEV_AR913X_WMAC
+	depends on SOC_AR913X
+	def_bool n
+
 config ATH79_DEV_GPIO_BUTTONS
 	def_bool n
 
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 1b111d8..48398561 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 # Devices
 #
 obj-y					+= dev-common.o
+obj-$(CONFIG_ATH79_DEV_AR913X_WMAC)	+= dev-ar913x-wmac.o
 obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o
 obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
 obj-$(CONFIG_ATH79_DEV_SPI)		+= dev-spi.o
diff --git a/arch/mips/ath79/dev-ar913x-wmac.c b/arch/mips/ath79/dev-ar913x-wmac.c
new file mode 100644
index 0000000..48f425a
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.c
@@ -0,0 +1,60 @@
+/*
+ *  Atheros AR913X SoC built-in WMAC device support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-ar913x-wmac.h"
+
+static struct ath9k_platform_data ar913x_wmac_data;
+
+static struct resource ar913x_wmac_resources[] = {
+	{
+		.start	= AR913X_WMAC_BASE,
+		.end	= AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= ATH79_CPU_IRQ_IP2,
+		.end	= ATH79_CPU_IRQ_IP2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ar913x_wmac_device = {
+	.name		= "ath9k",
+	.id		= -1,
+	.resource	= ar913x_wmac_resources,
+	.num_resources	= ARRAY_SIZE(ar913x_wmac_resources),
+	.dev = {
+		.platform_data = &ar913x_wmac_data,
+	},
+};
+
+void __init ath79_register_ar913x_wmac(u8 *cal_data)
+{
+	if (cal_data)
+		memcpy(ar913x_wmac_data.eeprom_data, cal_data,
+		       sizeof(ar913x_wmac_data.eeprom_data));
+
+	/* reset the WMAC */
+	ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
+	mdelay(10);
+
+	platform_device_register(&ar913x_wmac_device);
+}
diff --git a/arch/mips/ath79/dev-ar913x-wmac.h b/arch/mips/ath79/dev-ar913x-wmac.h
new file mode 100644
index 0000000..579d562
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.h
@@ -0,0 +1,17 @@
+/*
+ *  Atheros AR913X SoC built-in WMAC device support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_AR913X_WMAC_H
+#define _ATH79_DEV_AR913X_WMAC_H
+
+void ath79_register_ar913x_wmac(u8 *cal_data);
+
+#endif /* _ATH79_DEV_AR913X_WMAC_H */
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
index 909ca5d..03719b8 100644
--- a/arch/mips/ath79/mach-ap81.c
+++ b/arch/mips/ath79/mach-ap81.c
@@ -10,6 +10,7 @@
  */
 
 #include "machtypes.h"
+#include "dev-ar913x-wmac.h"
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
 #include "dev-spi.h"
@@ -26,6 +27,8 @@
 #define AP81_KEYS_POLL_INTERVAL		20	/* msecs */
 #define AP81_KEYS_DEBOUNCE_INTERVAL	(3 * AP81_KEYS_POLL_INTERVAL)
 
+#define AP81_CAL_DATA_ADDR	0x1fff1000
+
 static struct gpio_led ap81_leds_gpio[] __initdata = {
 	{
 		.name		= "ap81:green:status",
@@ -80,6 +83,8 @@ static struct ath79_spi_platform_data ap81_spi_data = {
 
 static void __init ap81_setup(void)
 {
+	u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR);
+
 	ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
 				 ap81_leds_gpio);
 	ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
@@ -88,6 +93,7 @@ static void __init ap81_setup(void)
 	ath79_register_spi(&ap81_spi_data, ap81_spi_info,
 			   ARRAY_SIZE(ap81_spi_info));
 	ath79_register_usb();
+	ath79_register_ar913x_wmac(cal_data);
 }
 
 MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index f125f1e..9beb073 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -43,6 +43,9 @@
 #define AR7240_OHCI_BASE	0x1b000000
 #define AR7240_OHCI_SIZE	0x1000
 
+#define AR913X_WMAC_BASE	(AR71XX_APB_BASE + 0x000C0000)
+#define AR913X_WMAC_SIZE	0x30000
+
 /*
  * DDR_CTRL block
  */
-- 
1.7.2.1


From kevink@kevink.net Sun Jan  2 21:06:30 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 21:06:33 +0100 (CET)
Received: from gateway04.websitewelcome.com ([67.18.21.5]:56234 "HELO
        gateway04.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1491056Ab1ABUGa (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 21:06:30 +0100
Received: (qmail 21877 invoked from network); 2 Jan 2011 20:06:17 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway04.websitewelcome.com with SMTP; 2 Jan 2011 20:06:17 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=kevink.net;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=RDQnmuNIBXGBPwwuo8OJoFsSiyG/5DCeZTsLdBan0m1wc+i6ApfwrfjN3IPwrLsKpmnhstnWwFR5JT6MarHUxdi0WbjHbEiVcVX2nRf1vmAGy/n4DY6bQqOKwVY9wCpH;
Received: from c-98-207-157-135.hsd1.ca.comcast.net ([98.207.157.135]:3574 helo=[127.0.0.1])
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@kevink.net>)
        id 1PZUC2-0007De-8D
        for linux-mips@linux-mips.org; Sun, 02 Jan 2011 14:06:23 -0600
Message-ID: <4D20DABE.5020306@kevink.net>
Date:   Sun, 02 Jan 2011 12:06:22 -0800
From:   "Kevin D. Kissell" <kevink@kevink.net>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Linux MIPS org <linux-mips@linux-mips.org>
Subject: CygWin Cross-tool Package?
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - kevink.net
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@kevink.net>
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: 28804
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: kevink@kevink.net
Precedence: bulk
X-list: linux-mips

As the person guilty of inventing the damned thing, I've been trying to
help folks keep the SMTC kernel working, but it's strictly a spare-time
thing - nobody pays me for time or materials.  So I'm not willing to
spend the time and money to set up a Linux box at home that would serve
only to build SMTC kernels.  For better or for worse, my home office
system is a Windows XP machine.   I've got Cygwin installed, and that
gives me git to peruse the sources, but I've got no means of building a
kernel.  I know that, in theory, I could build my own MIPS/Linux cross
tools under Cygwin, but looking at various email archives, it looks like
the procedure is moderately complex and fragile, and, frankly, I just
don't have the spare time to deal with it.  By any chance, could one of
you point me to a functional, pre-built package I could install under
Cygwin to do kernel builds?

            Regards,

            Kevin K.

From f.fainelli@gmail.com Sun Jan  2 21:22:48 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 21:22:51 +0100 (CET)
Received: from mail-wy0-f177.google.com ([74.125.82.177]:62742 "EHLO
        mail-wy0-f177.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491056Ab1ABUWs (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 21:22:48 +0100
Received: by wyf22 with SMTP id 22so12819205wyf.36
        for <linux-mips@linux-mips.org>; Sun, 02 Jan 2011 12:22:42 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:sender:from:organization:to
         :subject:date:user-agent:cc:references:in-reply-to:mime-version
         :content-type:content-transfer-encoding:message-id;
        bh=mKGi2y7nZzUfZn+/lXrUqutk16fNmXdB83svydWH4mE=;
        b=TU+yvBd6Z5fkRmsec+YgQlzyN24t3cMD6TA06higbb0UYS0s+9FZFdeEUPx6s0Icfd
         LqOlWHFuqMAX2iFkWhXRbAT7x9PXiGAsfAsHhs7ptMc7ovGHRz9opLcIKWFjrkoZ2AUf
         xSujSWUyHxwTOuOI4FZseE1IqXErzBru4EGKQ=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=sender:from:organization:to:subject:date:user-agent:cc:references
         :in-reply-to:mime-version:content-type:content-transfer-encoding
         :message-id;
        b=lV7RsCqaj9sw+JU8olVRzl7vyKc7SrgsQNs1YQvbNvs7SwIEOLkwzMHCy9VlYubH/a
         OSpfYR65GdFy12Zp8y5loFDpBMapiiZc1yi8AD8ZdRPUUywZ+dD4EwH+8NYTUkKn4hB3
         acHeMvdwFN7zlCZh+Z4nNv+AA04DkSHvt9G98=
Received: by 10.216.154.14 with SMTP id g14mr19294876wek.78.1293999762710;
        Sun, 02 Jan 2011 12:22:42 -0800 (PST)
Received: from flexo.localnet (bobafett.staff.proxad.net [213.228.1.121])
        by mx.google.com with ESMTPS id f52sm9450203wes.35.2011.01.02.12.22.40
        (version=SSLv3 cipher=RC4-MD5);
        Sun, 02 Jan 2011 12:22:41 -0800 (PST)
From:   Florian Fainelli <florian@openwrt.org>
Organization: OpenWrt
To:     "Kevin D. Kissell" <kevink@kevink.net>
Subject: Re: CygWin Cross-tool Package?
Date:   Sun, 2 Jan 2011 21:23:11 +0100
User-Agent: KMail/1.13.5 (Linux/2.6.35-24-server; KDE/4.5.1; x86_64; ; )
Cc:     Linux MIPS org <linux-mips@linux-mips.org>
References: <4D20DABE.5020306@kevink.net>
In-Reply-To: <4D20DABE.5020306@kevink.net>
MIME-Version: 1.0
Content-Type: Text/Plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Message-Id: <201101022123.11450.florian@openwrt.org>
Return-Path: <f.fainelli@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: 28805
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: florian@openwrt.org
Precedence: bulk
X-list: linux-mips

Hello Kevin,

On Sunday 02 January 2011 21:06:22 Kevin D. Kissell wrote:
> As the person guilty of inventing the damned thing, I've been trying to
> help folks keep the SMTC kernel working, but it's strictly a spare-time
> thing - nobody pays me for time or materials.  So I'm not willing to
> spend the time and money to set up a Linux box at home that would serve
> only to build SMTC kernels.  For better or for worse, my home office
> system is a Windows XP machine.   I've got Cygwin installed, and that
> gives me git to peruse the sources, but I've got no means of building a
> kernel.  I know that, in theory, I could build my own MIPS/Linux cross
> tools under Cygwin, but looking at various email archives, it looks like
> the procedure is moderately complex and fragile, and, frankly, I just
> don't have the spare time to deal with it.  By any chance, could one of
> you point me to a functional, pre-built package I could install under
> Cygwin to do kernel builds?

Providing that you install of the required dependencies (subversion, flex, 
bison ...), OpenWrt can build a Linux kernel and root filesystem under Cygwin.

Hope that helps.
--
Florian

From f.fainelli@gmail.com Sun Jan  2 21:42:58 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sun, 02 Jan 2011 21:43:01 +0100 (CET)
Received: from mail-wy0-f177.google.com ([74.125.82.177]:58863 "EHLO
        mail-wy0-f177.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491056Ab1ABUm6 (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sun, 2 Jan 2011 21:42:58 +0100
Received: by wyf22 with SMTP id 22so12827074wyf.36
        for <multiple recipients>; Sun, 02 Jan 2011 12:42:52 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:sender:from:organization:to
         :subject:date:user-agent:cc:references:in-reply-to:mime-version
         :content-type:content-transfer-encoding:message-id;
        bh=kFGknynK0L9LAGcdk9hiXOB/GoNSWWDq5V0Vr6i7jIw=;
        b=K0NgEd5JDnSWx6hqt/UTDq0UzyoaV1o1Z03n/J35NR9tsONaWmntooc7kP70rSEGoG
         zcsTmnnyLzYCUcHJXYLuStxSyAKtcVxFPrtbn0HF8UvajksGF0zGKaoAJYkIw+JStpR6
         Qkd+ih1kFQin3QlNi1yaeJ3HbUPY8C7on0FTA=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=sender:from:organization:to:subject:date:user-agent:cc:references
         :in-reply-to:mime-version:content-type:content-transfer-encoding
         :message-id;
        b=b6D4ykYF5rb2/xbbh6SWXbVUTxf9zLXbLvkfiRYE0lQ7wzl0TaxJJ/2NiW0BFFPirV
         GkYaL8ODoLqgDLNacl130WAs8fnCw/WgApiZorJI1A9Nb0CvgVmKRjZzxXCnuyGo9NDw
         O6Y41Bjw9PsOeHi25edHe3yhCf3Ba+KFGsP68=
Received: by 10.216.48.6 with SMTP id u6mr19508665web.77.1294000972364;
        Sun, 02 Jan 2011 12:42:52 -0800 (PST)
Received: from flexo.localnet (bobafett.staff.proxad.net [213.228.1.121])
        by mx.google.com with ESMTPS id t11sm8883454wes.41.2011.01.02.12.42.50
        (version=SSLv3 cipher=RC4-MD5);
        Sun, 02 Jan 2011 12:42:50 -0800 (PST)
From:   Florian Fainelli <florian@openwrt.org>
Organization: OpenWrt
To:     Gabor Juhos <juhosg@openwrt.org>
Subject: Re: [PATCH v4 01/16] MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs
Date:   Sun, 2 Jan 2011 21:43:13 +0100
User-Agent: KMail/1.13.5 (Linux/2.6.35-24-server; KDE/4.5.1; x86_64; ; )
Cc:     Ralf Baechle <ralf@linux-mips.org>, linux-mips@linux-mips.org,
        Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@atheros.com>,
        Kathy Giori <Kathy.Giori@atheros.com>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org> <1293994589-6794-2-git-send-email-juhosg@openwrt.org>
In-Reply-To: <1293994589-6794-2-git-send-email-juhosg@openwrt.org>
MIME-Version: 1.0
Content-Type: Text/Plain;
  charset="utf-8"
Content-Transfer-Encoding: 7bit
Message-Id: <201101022143.13712.florian@openwrt.org>
Return-Path: <f.fainelli@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: 28806
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: florian@openwrt.org
Precedence: bulk
X-list: linux-mips

Hello,

On Sunday 02 January 2011 19:56:14 Gabor Juhos wrote:
> This patch adds initial support for various Atheros SoCs based on the
> MIPS 24Kc core. The following models are supported at the moment:
> 
>   - AR7130
>   - AR7141
>   - AR7161
>   - AR9130
>   - AR9132
>   - AR7240
>   - AR7241
>   - AR7242
> 
> The current patch contains minimal support only, but the resulting
> kernel can boot into user-space with using of an initramfs image on
> various boards which are using these SoCs. Support for more built-in
> devices and individual boards will be implemented in further patches.
> 
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
> ---
> Changes since RFC:
>     - the ATH79_DEV_UART Kconfig option is removed, and the URT platform
>       code has been moved into dev-common[ch]
> 
> Changes since v1:
>     - ath79_device_{start,stop} has been renamed to
> ath79_device_reset_{set,clear} to to reflect the purpose of these
> functions better
>     - some definitions has been moved from 'arch/mips/ath79/common.h' to
>       'arch/mips/include/asm/mach-ath79/ath79.h' to make them available for
>       future drivers
>     - rebased against 2.6.37-rc7
> 
> Changes since v2:
>     - don't use __init for function declarations
> 
> Changes since v3:
>     - rebase against 2.6.37-rc8
[snip]

> +
> +static DEFINE_SPINLOCK(ath79_device_reset_lock);
> +
> +u32 ath79_cpu_freq;
> +EXPORT_SYMBOL_GPL(ath79_cpu_freq);
> +
> +u32 ath79_ahb_freq;
> +EXPORT_SYMBOL_GPL(ath79_ahb_freq);
> +
> +u32 ath79_ddr_freq;
> +EXPORT_SYMBOL_GPL(ath79_ddr_freq);

Why not use the Clock API with fixed rates just like how it is done for AR7?

> +
> +enum ath79_soc_type ath79_soc;
> +
> +void __iomem *ath79_pll_base;
> +void __iomem *ath79_reset_base;
> +EXPORT_SYMBOL_GPL(ath79_reset_base);
> +void __iomem *ath79_ddr_base;
> +

[snip]
--
Florian

From anoop.pa@gmail.com Mon Jan  3 16:01:55 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Jan 2011 16:02:04 +0100 (CET)
Received: from mail-fx0-f49.google.com ([209.85.161.49]:54988 "EHLO
        mail-fx0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491800Ab1ACPBz (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Mon, 3 Jan 2011 16:01:55 +0100
Received: by fxm19 with SMTP id 19so12507870fxm.36
        for <linux-mips@linux-mips.org>; Mon, 03 Jan 2011 07:01:48 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:subject:from:to:cc
         :in-reply-to:references:content-type:date:message-id:mime-version
         :x-mailer:content-transfer-encoding;
        bh=HMQ6uNErAncx7i/TibtcOnIZt8ANyEkFDBr6SLNom54=;
        b=Nos7i4NKqFxjPdUDwIuXlXBpVvWfzw7F/+/GLxhd7xQIxAi+UBWQzfYpiZduEtjUJv
         eLYDF6DW+//ATLBy4lwzarByg2Vqom5EMuXmT8tutirDN2AlpzXlnyrf/OxRqYRKu3o/
         p87OLoTWxFuqZJeLNXryX5QAsOI5PYO98xuOQ=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=subject:from:to:cc:in-reply-to:references:content-type:date
         :message-id:mime-version:x-mailer:content-transfer-encoding;
        b=SjSA6JouKH/DYJvghmQnCIvkP2Mv2NqEkANhjAY3JVvxIdHn7cmH8Jjv9fL+QFou6p
         FS2yHcqx5HwN5CKHFiYYWHDIiTJc7XAi6NL8V0HJehXZHksXemyH5Ay8D5sYR2FgxKCa
         EN2FEpVMpvqUf+IxzLbWUvPyFcf9Iwgn4GImE=
Received: by 10.223.103.8 with SMTP id i8mr718646fao.47.1294066907944;
        Mon, 03 Jan 2011 07:01:47 -0800 (PST)
Received: from [172.16.48.51] ([59.160.135.215])
        by mx.google.com with ESMTPS id f24sm4761813fak.24.2011.01.03.07.01.42
        (version=SSLv3 cipher=RC4-MD5);
        Mon, 03 Jan 2011 07:01:45 -0800 (PST)
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
In-Reply-To: <4D1EE913.1070203@paralogos.com>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
         <1293470392.27661.202.camel@paanoop1-desktop>
         <1293524389.27661.210.camel@paanoop1-desktop>
         <4D19A31E.1090905@paralogos.com>
         <1293798476.27661.279.camel@paanoop1-desktop>
         <4D1EE913.1070203@paralogos.com>
Content-Type: text/plain; charset="UTF-8"
Date:   Mon, 03 Jan 2011 20:42:41 +0530
Message-ID: <1294067561.27661.293.camel@paanoop1-desktop>
Mime-Version: 1.0
X-Mailer: Evolution 2.28.3 
Content-Transfer-Encoding: 7bit
Return-Path: <anoop.pa@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: 28807
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips

Hi ,

Following patch restricts TREE_CPU RCU implementation only for !PREEMPT
SMP kernel.  
http://git.linux-mips.org/?p=linux.git;a=commit;h=687d7a960aea46e016182c7ce346d62c4dbd0366

CONFIG_TREE_PREEMPT_RCU option seems to be not working for SMTC kernel
( which will be only available RCU implementation for SMTC kernel from
2.6.37 onwards) .

With no forced preemption and selecting TREE_CPU I am able to boot
further to the hang that I have reported.

Thanks
Anoop

On Sat, 2011-01-01 at 00:42 -0800, Kevin D. Kissell wrote:
> At this point the logical thing to do would seem to look at your kernel
> image and disassemble smtc_ipi_replay(), which is where the EPC of VPE 0
> shows the last exception to have been taken.  That's a critical SMTC
> routine that gets called whenever an xxx_irq_restore() enables
> interrupts, so that virtual per-TC IPI interrupts that were posted while
> the TC had interrupts disabled can be handled deterministically.  As I
> mentioned in an earlier message, there was some cleanup work from David
> Howell that changed a number of irq management-related function names
> and prototypes across all architectures, which went into linux-mips.org
> at very roughly the time of the breakage.  The SMTC overlay over the irq
> implementation has been pretty robust, but it's written in a perhaps
> doomed attempt to be both efficient and using a maximum amount of common
> code with the general case.  A mechanical or semi-mechanical change
> could conceivably have broken things.
> 
>             Regards,
> 
>             Kevin K.
> 
> 
> On 12/31/2010 4:27 AM, Anoop P A wrote:
> > Hi ,
> >
> > Kernel hangs on stop_machine call. Please find mt reg dump below.
> > Another important observation is even though 2.6.33 kernel + stackframe
> > patch well passes calibration hang , I am still unable boot in to a
> > initramfs root ( verified ramfs working with VSMP). So it looks like
> > still some issue to fix between 2.6.32 and 2.6.33 .
> > ######################## Log ###########################
> >
> > === MIPS MT State Dump ===
> > -- Global State --
> >    MVPControl Passed: 00000005
> >    MVPControl Read: 00000004
> >    MVPConf0 : a8008406
> > -- per-VPE State --
> >   VPE 0
> >    VPEControl : 00008000
> >    VPEConf0 : 800f0003
> >    VPE0.Status : 11004201
> >    VPE0.EPC : 8010dc54 smtc_ipi_replay+0xcc/0x108
> >    VPE0.Cause : 50804000
> >    VPE0.Config7 : 00010000
> >   VPE 1
> >    VPEControl : 00068006
> >    VPEConf0 : 80cf0003
> >    VPE1.Status : 11008301
> >    VPE1.EPC : 801022a0 r4k_wait+0x20/0x40
> >    VPE1.Cause : 50800000
> >    VPE1.Config7 : 00010000
> > -- per-TC State --
> >   TC 0 (current TC with VPE EPC above)
> >    TCStatus : 18102000
> >    TCBind : 00000000
> >    TCRestart : 803fa19c printk+0xc/0x30
> >    TCHalt : 00000000
> >    TCContext : 00000000
> >   TC 1
> >    TCStatus : 18902000
> >    TCBind : 00200000
> >    TCRestart : 801022a0 r4k_wait+0x20/0x40
> >    TCHalt : 00000000
> >    TCContext : 00140000
> >   TC 2
> >    TCStatus : 18902000
> >    TCBind : 00400000
> >    TCRestart : 801022a0 r4k_wait+0x20/0x40
> >    TCHalt : 00000000
> >    TCContext : 00280000
> >   TC 3
> >    TCStatus : 18902000
> >    TCBind : 00600000
> >    TCRestart : 801022a0 r4k_wait+0x20/0x40
> >    TCHalt : 00000000
> >    TCContext : 003c0000
> >   TC 4
> >    TCStatus : 18902000
> >    TCBind : 00800001
> >    TCRestart : 8010229c r4k_wait+0x1c/0x40
> >    TCHalt : 00000000
> >    TCContext : 00500000
> >   TC 5
> >    TCStatus : 18902000
> >    TCBind : 00a00001
> >    TCRestart : 8010229c r4k_wait+0x1c/0x40
> >    TCHalt : 00000000
> >    TCContext : 00640000
> >   TC 6
> >    TCStatus : 18902000
> >    TCBind : 00c00001
> >    TCRestart : 8010229c r4k_wait+0x1c/0x40
> >    TCHalt : 00000000
> >    TCContext : 00780000
> > Counter Interrupts taken per CPU (TC)
> > 0: 0
> > 1: 0
> > 2: 0
> > 3: 0
> > 4: 0
> > 5: 0
> > 6: 0
> > 7: 0
> > Self-IPI invocations:
> > 0: 12
> > 1: 0
> > 2: 0
> > 3: 0
> > 4: 0
> > 5: 5
> > 6: 4
> > 7: 0
> > IPIQ[0]: head = 0x0, tail = 0x0, depth = 0
> > IPIQ[1]: head = 0x0, tail = 0x0, depth = 0
> > IPIQ[2]: head = 0x0, tail = 0x0, depth = 0
> > IPIQ[3]: head = 0x0, tail = 0x0, depth = 0
> > IPIQ[4]: head = 0x0, tail = 0x0, depth = 0
> > IPIQ[5]: head = 0x0, tail = 0x0, depth = 0
> > IPIQ[6]: head = 0x0, tail = 0x0, depth = 0
> > IPIQ[7]: head = 0x0, tail = 0x0, depth = 0
> > 0 Recoveries of "stolen" FPU
> > ===========================
> >
> > ################################################################
> >
> > Thanks
> > Anoop
> >
> > On Tue, 2010-12-28 at 00:43 -0800, Kevin D. Kissell wrote:
> >> I took a quick look last night, and the only thing that looked vaguely 
> >> dangerous in changes since the timer changes I alluded to earlier was 
> >> the global naming cleanup of irq-related function names that David 
> >> Howell submitted.  The diff didn't look dangerous in itself, but some of 
> >> the definitions are nested subtly for SMTC to maximize the amount of 
> >> common code, and I could imagine something getting lost in translation 
> >> there.  If that were really the problem, it would of course affect much 
> >> more than just the timer subsystem, but early in the boot process, 
> >> timers are pretty much the only interrupts that have to be handled 
> >> correctly.
> >>
> >> I'm travelling today, but will take a look at timekeeping_notify() 
> >> tomorrow or the next day...
> >>
> >> /K.
> >>
> >> On 12/28/10 12:19 AM, Anoop P A wrote:
> >>> Hi,
> >>>
> >>> I had a glance into the code diff without notice of any suspect-able
> >>> code .
> >>> Tracing the hang showed that it is getting hanged in timekeeping_notify
> >>> function.
> >>>
> >>> Thanks,
> >>> Anoop
> >>>
> >>> PS: I may not be available until Thursday
> >>>
> >>> On Mon, 2010-12-27 at 22:49 +0530, Anoop P A wrote:
> >>>> Hi Kevin,
> >>>>
> >>>> It is very unlikely that the patch you pointed has any impact on the the
> >>>> hang I am seeing. The patch you have mentioned got into kernel around
> >>>> 2.6.32 timeframe. I am able to boot both 2.6.32 and  2.6.33 kernel ( +
> >>>> stackframe patch) .
> >>>>
> >>>> Hi Stuart,
> >>>>
> >>>> I haven't got much time to spend on this today.
> >>>>
> >>>> I had got 2.6.36-stable(+ stack frame patch) booting last day and I have
> >>>> observed hang issue with 2.6.37-rc1 ( Same as rc6 and current git head)
> >>>>
> >>>> So probably some patches in 2.6.37 branch introduced this hang.
> >>>>
> >>>> Hopefully I will get some free slot tomorrow so that I can look into
> >>>> code diff .
> >>>>
> >>>> Thanks
> >>>> Anoop
> >>>>
> >>>> On Mon, 2010-12-27 at 09:49 -0600, STUART VENTERS wrote:
> >>>>> Kevin,
> >>>>>
> >>>>> Outstanding, sometimes it's better to be lucky than good.
> >>>>>
> >>>>>
> >>>>> Anoop,
> >>>>>
> >>>>> Maybe we can get lucky again.
> >>>>>
> >>>>> If you can isolate the .33 works/.37 works_not bug to a specific pair of versions,
> >>>>>     I'll be happy to do another diff.
> >>>>>
> >>>>>
> >>>>> Hope you'll have had a good Christmas as well.
> >>>>>    We've had snow in Alabama since Christmas eve!
> >>>>>
> >>>>>
> >>>>> Regards,
> >>>>>
> >>>>> Stuart
> >>>>>
> >>>>>
> >>>>> -----Original Message-----
> >>>>> From: Kevin D. Kissell [mailto:kevink@paralogos.com]
> >>>>> Sent: Friday, December 24, 2010 5:34 PM
> >>>>> To: Anoop P A
> >>>>> Cc: STUART VENTERS; Anoop P.A.; linux-mips@linux-mips.org
> >>>>> Subject: Re: SMTC support status in latest git head.
> >>>>>
> >>>>>
> >>>>> Ah, well, at least we have a stackframe.h fix that preserves David's
> >>>>> performance tweak for the deeper pipelined processors.  In looking for
> >>>>> this, I did notice that someone did some modification to the SMTC clock
> >>>>> tick logic that I was skeptical had ever been tested.  If you've still
> >>>>> got that kernel binary handy, you might check to see if it boots with
> >>>>> maxtcs=1 maxvpes=1, maxtcs=2 maxvpes=1, and/or maxtcs=2 maxvpes=2.
> >>>>>
> >>>>> Oh, yes, and Merry Christmas one and all!
> >>>>>
> >>>>>               Regards,
> >>>>>
> >>>>>               Kevin K.
> >>>>>
> >>>>> On 12/24/10 8:02 AM, Anoop P A wrote:
> >>>>>> On Fri, 2010-12-24 at 06:53 -0800, Kevin D. Kissell wrote:
> >>>>>>> Excellent!  Now, does the attached patch (relative to 2.6.37.11) also
> >>>>>>> fix things, while preserving the other fixes and performance enhancements?
> >>>>>>>
> >>>>>> I have tested that patch with 2.6.37 branch it well passes calibration
> >>>>>> loop but hangs after switching to mips closource
> >>>>>>
> >>>>>> TC 6 going on-line as CPU 6
> >>>>>> Brought up 7 CPUs
> >>>>>> bio: create slab<bio-0>   at 0
> >>>>>> SCSI subsystem initialized
> >>>>>> Switching to clocksource MIPS
> >>>>>>
> >>>>>> I Presume this is a different issue as restoring older file didn't help
> >>>>>> much to get rid of this hang.
> >>>>>>
> >>>>>> diff --git a/arch/mips/include/asm/stackframe.h
> >>>>>> b/arch/mips/include/asm/stackframe.h
> >>>>>> index 58730c5..7fc9f10 100644
> >>>>>> --- a/arch/mips/include/asm/stackframe.h
> >>>>>> +++ b/arch/mips/include/asm/stackframe.h
> >>>>>> @@ -195,9 +195,9 @@
> >>>>>>    		 * to cover the pipeline delay.
> >>>>>>    		 */
> >>>>>>    		.set	mips32
> >>>>>> -		mfc0	v1, CP0_TCSTATUS
> >>>>>> +		mfc0	v0, CP0_TCSTATUS
> >>>>>>    		.set	mips0
> >>>>>> -		LONG_S	v1, PT_TCSTATUS(sp)
> >>>>>> +		LONG_S	v0, PT_TCSTATUS(sp)
> >>>>>>    #endif /* CONFIG_MIPS_MT_SMTC */
> >>>>>>    		LONG_S	$4, PT_R4(sp)
> >>>>>>    		LONG_S	$5, PT_R5(sp)
> >>>>>>
> >>>>>>
> >>>>>>> /K.
> >>>>>>>
> >>>>>>> On 12/24/10 6:39 AM, Anoop P A wrote:
> >>>>>>>> Hi Kevin, Stuart ,
> >>>>>>>>
> >>>>>>>> Woohooo You guys spotted !.
> >>>>>>>>
> >>>>>>>>     http://git.linux-mips.org/?p=linux.git;a=commit;h=d5ec6e3c seems to be
> >>>>>>>> the culprit
> >>>>>>>>
> >>>>>>>> Once I restored previous version of stackframe.h 2.6.33-stable started
> >>>>>>>> booting !.
> >>>>>>>>
> >>>>>>>> Thanks,
> >>>>>>>> Anoop
> >>>>>>>>
> >>>>>>>> On Fri, 2010-12-24 at 04:32 -0800, Kevin D. Kissell wrote:
> >>>>>>>>> Thank you, Stuart!  I've spotted some definite breakage to SMTC between
> >>>>>>>>> those versions.  In arch/mips/include/asm/stackframe.h, someone moved
> >>>>>>>>> the store of the Status register value in SAVE_SOME (line 169 or 204,
> >>>>>>>>> depending on the version) from two instructions after the mfc0 to a
> >>>>>>>>> point after the #ifdef for SMTC, presumably to get better pipelining of
> >>>>>>>>> the register access.  Unfortunately, the v1 register is also used in the
> >>>>>>>>> SMTC-specific fragment to save TCStatus, so the Status value gets
> >>>>>>>>> clobbered before it gets stored.  This will eventually result in the
> >>>>>>>>> Status register getting a TCStatus value, which has some bits on common,
> >>>>>>>>> but isn't identical and sooner or later Bad Things will happen.
> >>>>>>>>>
> >>>>>>>>> I'm a little surprised this wasn't caught by visual inspection of the patch.
> >>>>>>>>>
> >>>>>>>>> Possible solutions would include reverting the store of the CP0_STATUS
> >>>>>>>>> value to the block above the #ifdef, or, to retain whatever performance
> >>>>>>>>> advantage was obtained by moving the store downward, to use v0/$2
> >>>>>>>>> instead of v1/$3, as the staging register for the TCStatus value.  I'd
> >>>>>>>>> lean toward the second option, but I'm not in a position to test and
> >>>>>>>>> submit a patch just now.
> >>>>>>>>>
> >>>>>>>>>                 Regards,
> >>>>>>>>>
> >>>>>>>>>                 Kevin K.
> >>>>>>>>>
> >>>>>>>>> On 12/23/10 1:09 PM, STUART VENTERS wrote:
> >>>>>>>>>> Kevin,
> >>>>>>>>>>
> >>>>>>>>>> I'm not sure if it's useful,
> >>>>>>>>>>        but finally I got the time to look at the two kernel versions Anoop pointed out.
> >>>>>>>>>>         works   2.6.32-stable with patch 804
> >>>>>>>>>>         works_not 2.6.33-stable
> >>>>>>>>>>
> >>>>>>>>>> greping for files with CONFIG_MIPS_MT_SMTC
> >>>>>>>>>>        and looking for timer interrupt related stuff found the following differences:
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> arch/mips/include/asm/irq.h
> >>>>>>>>>> arch/mips/kernel/irq.c
> >>>>>>>>>>       do_IRQ
> >>>>>>>>>>
> >>>>>>>>>> arch/mips/include/asm/stackframe.h
> >>>>>>>>>>       SAVE_SOME SAVE_TEMP get/set_saved_sp
> >>>>>>>>>>
> >>>>>>>>>> arch/mips/include/asm/time.h
> >>>>>>>>>>       clocksource_set_clock
> >>>>>>>>>>
> >>>>>>>>>> arch/mips/kernel/process.c
> >>>>>>>>>>       cpu_idle
> >>>>>>>>>>
> >>>>>>>>>> arch/mips/kernel/smtc.c
> >>>>>>>>>>       __irq_entry
> >>>>>>>>>>       ipi_decode
> >>>>>>>>>>           SMTC_CLOCK_TICK
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> Enclosed are the two subsets of files for a more expert look.
> >>>>>>>>>>
> >>>>>>>>>> I'll try to look in more detail after Christmas.
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> Cheers,
> >>>>>>>>>>
> >>>>>>>>>> Stuart
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >
> 



From kevink@paralogos.com Mon Jan  3 16:38:22 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Jan 2011 16:38:25 +0100 (CET)
Received: from gateway15.websitewelcome.com ([67.18.7.8]:59647 "HELO
        gateway15.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1491961Ab1ACPiW (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Mon, 3 Jan 2011 16:38:22 +0100
Received: (qmail 26613 invoked from network); 3 Jan 2011 15:38:26 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway15.websitewelcome.com with SMTP; 3 Jan 2011 15:38:26 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=QT0xWTvQtbPWGu6fmwJoOVxFX9Th3Y0bY9QIhTt2/rrbhDoJ2USbTnGaDweZNGJpX/i0bvdd3w5XJEXF+6DiGA6rTskow2c/8l2oaj4XdOCMijSgS7NQZB/miJK1VUv/;
Received: from c-98-207-157-135.hsd1.ca.comcast.net ([98.207.157.135]:2758 helo=[127.0.0.1])
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1PZmUC-0004GZ-Aq; Mon, 03 Jan 2011 09:38:16 -0600
Message-ID: <4D21ED6C.1020503@paralogos.com>
Date:   Mon, 03 Jan 2011 07:38:20 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Florian Fainelli <florian@openwrt.org>
CC:     "Kevin D. Kissell" <kevink@paralogos.com>,
        Linux MIPS org <linux-mips@linux-mips.org>
Subject: Re: CygWin Cross-tool Package?
References: <4D20DABE.5020306@kevink.net> <201101022123.11450.florian@openwrt.org>
In-Reply-To: <201101022123.11450.florian@openwrt.org>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28808
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

On 1/2/2011 12:23 PM, Florian Fainelli wrote:
> Hello Kevin,
>
> On Sunday 02 January 2011 21:06:22 Kevin D. Kissell wrote:
>> ...By any chance, could one of
>> you point me to a functional, pre-built package I could install under
>> Cygwin to do kernel builds?
> Providing that you install of the required dependencies (subversion, flex, 
> bison ...), OpenWrt can build a Linux kernel and root filesystem under Cygwin.
>
> Hope that helps.
Sigh.  It looked promising, but...

$ make menuconfig
Checking 'working-make'... ok.
Checking 'case-sensitive-fs'... failed.
Checking 'getopt'... ok.
Checking 'fileutils'... ok.
Checking 'working-gcc'... ok.
Checking 'working-g++'... ok.
Checking 'ncurses'... failed.
Checking 'zlib'... ok.
Checking 'gawk'... ok.
Checking 'flex'... ok.
Checking 'unzip'... ok.
Checking 'bzip2'... ok.
Checking 'patch'... ok.
Checking 'perl'... ok.
Checking 'python'... ok.
Checking 'wget'... ok.
Checking 'gnutar'... ok.
Checking 'svn'... ok.
Checking 'gnu-find'... ok.
Checking 'getopt-extended'... ok.
Checking 'non-root'... ok.

Build dependency: OpenWrt can only be built on a case-sensitive filesystem
...

It will probably be easier for me to get some random cheap PC running
Ubuntu than to get a non-case-sensitive filesystem working on an
existing XP platform.

Any recommendations on cross tool packages for X86/X86-64 Ubuntu
installations?  Or would splicing the linux-mips.org kernel tree under
the OpenWrt structure - but under Linux this time - still be the
shortest path?

            Regards, and thanks,

            Kevin K.


From kevink@paralogos.com Mon Jan  3 17:14:13 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Jan 2011 17:14:16 +0100 (CET)
Received: from gateway01.websitewelcome.com ([69.93.136.19]:48521 "HELO
        gateway01.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1491970Ab1ACQON (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Mon, 3 Jan 2011 17:14:13 +0100
Received: (qmail 19839 invoked from network); 3 Jan 2011 16:13:46 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway01.websitewelcome.com with SMTP; 3 Jan 2011 16:13:46 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=TEbJ4dvO3C7v2obLKNzhwF8Z9O28szgSxyeuhL6T4dZVfW+z0ubieP1OlIM6eKnd5j09RG3J6YnED1kzWiC2eAVIsetn607ReVapGIwvkRXHJ8+91lmiOWPDT0Y8nrN1;
Received: from c-98-207-157-135.hsd1.ca.comcast.net ([98.207.157.135]:2988 helo=[127.0.0.1])
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1PZn2t-0004F3-8J; Mon, 03 Jan 2011 10:14:07 -0600
Message-ID: <4D21F5D3.50604@paralogos.com>
Date:   Mon, 03 Jan 2011 08:14:11 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Anoop P A <anoop.pa@gmail.com>
CC:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Subject: Re: SMTC support status in latest git head.
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>         <1293470392.27661.202.camel@paanoop1-desktop>         <1293524389.27661.210.camel@paanoop1-desktop>         <4D19A31E.1090905@paralogos.com>         <1293798476.27661.279.camel@paanoop1-desktop>         <4D1EE913.1070203@paralogos.com> <1294067561.27661.293.camel@paanoop1-desktop>
In-Reply-To: <1294067561.27661.293.camel@paanoop1-desktop>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28809
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

The very first SMTC implementations didn't support full kernel-mode
preemption, which anyway wasn't a priority, given the hardware event
response support in MIPS MT.  I believe it was later made compatible,
but it was never extensively exercised.  Since SMTC has fingers in some
pretty low-level atomicity mechanisms, if a new, parallel set was
implemented for RCU, I can easily imagine that nobody has yet
implemented SMTC-ified variants of that set.

Your last statement isn't very clear, though.  Are you saying that if
you configure for no forced preemption and with TREE_CPU, the 2.6.37
kernel boots all the way up, or that it simply hangs later?   What's the
last rev kernel that actually boots all the way up?

            Regards,

            Kevin K.

On 1/3/2011 7:12 AM, Anoop P A wrote:
> Hi ,
>
> Following patch restricts TREE_CPU RCU implementation only for !PREEMPT
> SMP kernel.  
> http://git.linux-mips.org/?p=linux.git;a=commit;h=687d7a960aea46e016182c7ce346d62c4dbd0366
>
> CONFIG_TREE_PREEMPT_RCU option seems to be not working for SMTC kernel
> ( which will be only available RCU implementation for SMTC kernel from
> 2.6.37 onwards) .
>
> With no forced preemption and selecting TREE_CPU I am able to boot
> further to the hang that I have reported.
>
> Thanks
> Anoop
>
> On Sat, 2011-01-01 at 00:42 -0800, Kevin D. Kissell wrote:
>> At this point the logical thing to do would seem to look at your kernel
>> image and disassemble smtc_ipi_replay(), which is where the EPC of VPE 0
>> shows the last exception to have been taken.  That's a critical SMTC
>> routine that gets called whenever an xxx_irq_restore() enables
>> interrupts, so that virtual per-TC IPI interrupts that were posted while
>> the TC had interrupts disabled can be handled deterministically.  As I
>> mentioned in an earlier message, there was some cleanup work from David
>> Howell that changed a number of irq management-related function names
>> and prototypes across all architectures, which went into linux-mips.org
>> at very roughly the time of the breakage.  The SMTC overlay over the irq
>> implementation has been pretty robust, but it's written in a perhaps
>> doomed attempt to be both efficient and using a maximum amount of common
>> code with the general case.  A mechanical or semi-mechanical change
>> could conceivably have broken things.
>>
>>             Regards,
>>
>>             Kevin K.
>>
>>
>> On 12/31/2010 4:27 AM, Anoop P A wrote:
>>> Hi ,
>>>
>>> Kernel hangs on stop_machine call. Please find mt reg dump below.
>>> Another important observation is even though 2.6.33 kernel + stackframe
>>> patch well passes calibration hang , I am still unable boot in to a
>>> initramfs root ( verified ramfs working with VSMP). So it looks like
>>> still some issue to fix between 2.6.32 and 2.6.33 .
>>> ######################## Log ###########################
>>>
>>> === MIPS MT State Dump ===
>>> -- Global State --
>>>    MVPControl Passed: 00000005
>>>    MVPControl Read: 00000004
>>>    MVPConf0 : a8008406
>>> -- per-VPE State --
>>>   VPE 0
>>>    VPEControl : 00008000
>>>    VPEConf0 : 800f0003
>>>    VPE0.Status : 11004201
>>>    VPE0.EPC : 8010dc54 smtc_ipi_replay+0xcc/0x108
>>>    VPE0.Cause : 50804000
>>>    VPE0.Config7 : 00010000
>>>   VPE 1
>>>    VPEControl : 00068006
>>>    VPEConf0 : 80cf0003
>>>    VPE1.Status : 11008301
>>>    VPE1.EPC : 801022a0 r4k_wait+0x20/0x40
>>>    VPE1.Cause : 50800000
>>>    VPE1.Config7 : 00010000
>>> -- per-TC State --
>>>   TC 0 (current TC with VPE EPC above)
>>>    TCStatus : 18102000
>>>    TCBind : 00000000
>>>    TCRestart : 803fa19c printk+0xc/0x30
>>>    TCHalt : 00000000
>>>    TCContext : 00000000
>>>   TC 1
>>>    TCStatus : 18902000
>>>    TCBind : 00200000
>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
>>>    TCHalt : 00000000
>>>    TCContext : 00140000
>>>   TC 2
>>>    TCStatus : 18902000
>>>    TCBind : 00400000
>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
>>>    TCHalt : 00000000
>>>    TCContext : 00280000
>>>   TC 3
>>>    TCStatus : 18902000
>>>    TCBind : 00600000
>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
>>>    TCHalt : 00000000
>>>    TCContext : 003c0000
>>>   TC 4
>>>    TCStatus : 18902000
>>>    TCBind : 00800001
>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
>>>    TCHalt : 00000000
>>>    TCContext : 00500000
>>>   TC 5
>>>    TCStatus : 18902000
>>>    TCBind : 00a00001
>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
>>>    TCHalt : 00000000
>>>    TCContext : 00640000
>>>   TC 6
>>>    TCStatus : 18902000
>>>    TCBind : 00c00001
>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
>>>    TCHalt : 00000000
>>>    TCContext : 00780000
>>> Counter Interrupts taken per CPU (TC)
>>> 0: 0
>>> 1: 0
>>> 2: 0
>>> 3: 0
>>> 4: 0
>>> 5: 0
>>> 6: 0
>>> 7: 0
>>> Self-IPI invocations:
>>> 0: 12
>>> 1: 0
>>> 2: 0
>>> 3: 0
>>> 4: 0
>>> 5: 5
>>> 6: 4
>>> 7: 0
>>> IPIQ[0]: head = 0x0, tail = 0x0, depth = 0
>>> IPIQ[1]: head = 0x0, tail = 0x0, depth = 0
>>> IPIQ[2]: head = 0x0, tail = 0x0, depth = 0
>>> IPIQ[3]: head = 0x0, tail = 0x0, depth = 0
>>> IPIQ[4]: head = 0x0, tail = 0x0, depth = 0
>>> IPIQ[5]: head = 0x0, tail = 0x0, depth = 0
>>> IPIQ[6]: head = 0x0, tail = 0x0, depth = 0
>>> IPIQ[7]: head = 0x0, tail = 0x0, depth = 0
>>> 0 Recoveries of "stolen" FPU
>>> ===========================
>>>
>>> ################################################################
>>>
>>> Thanks
>>> Anoop
>>>
>>> On Tue, 2010-12-28 at 00:43 -0800, Kevin D. Kissell wrote:
>>>> I took a quick look last night, and the only thing that looked vaguely 
>>>> dangerous in changes since the timer changes I alluded to earlier was 
>>>> the global naming cleanup of irq-related function names that David 
>>>> Howell submitted.  The diff didn't look dangerous in itself, but some of 
>>>> the definitions are nested subtly for SMTC to maximize the amount of 
>>>> common code, and I could imagine something getting lost in translation 
>>>> there.  If that were really the problem, it would of course affect much 
>>>> more than just the timer subsystem, but early in the boot process, 
>>>> timers are pretty much the only interrupts that have to be handled 
>>>> correctly.
>>>>
>>>> I'm travelling today, but will take a look at timekeeping_notify() 
>>>> tomorrow or the next day...
>>>>
>>>> /K.
>>>>
>>>> On 12/28/10 12:19 AM, Anoop P A wrote:
>>>>> Hi,
>>>>>
>>>>> I had a glance into the code diff without notice of any suspect-able
>>>>> code .
>>>>> Tracing the hang showed that it is getting hanged in timekeeping_notify
>>>>> function.
>>>>>
>>>>> Thanks,
>>>>> Anoop
>>>>>
>>>>> PS: I may not be available until Thursday
>>>>>
>>>>> On Mon, 2010-12-27 at 22:49 +0530, Anoop P A wrote:
>>>>>> Hi Kevin,
>>>>>>
>>>>>> It is very unlikely that the patch you pointed has any impact on the the
>>>>>> hang I am seeing. The patch you have mentioned got into kernel around
>>>>>> 2.6.32 timeframe. I am able to boot both 2.6.32 and  2.6.33 kernel ( +
>>>>>> stackframe patch) .
>>>>>>
>>>>>> Hi Stuart,
>>>>>>
>>>>>> I haven't got much time to spend on this today.
>>>>>>
>>>>>> I had got 2.6.36-stable(+ stack frame patch) booting last day and I have
>>>>>> observed hang issue with 2.6.37-rc1 ( Same as rc6 and current git head)
>>>>>>
>>>>>> So probably some patches in 2.6.37 branch introduced this hang.
>>>>>>
>>>>>> Hopefully I will get some free slot tomorrow so that I can look into
>>>>>> code diff .
>>>>>>
>>>>>> Thanks
>>>>>> Anoop
>>>>>>
>>>>>> On Mon, 2010-12-27 at 09:49 -0600, STUART VENTERS wrote:
>>>>>>> Kevin,
>>>>>>>
>>>>>>> Outstanding, sometimes it's better to be lucky than good.
>>>>>>>
>>>>>>>
>>>>>>> Anoop,
>>>>>>>
>>>>>>> Maybe we can get lucky again.
>>>>>>>
>>>>>>> If you can isolate the .33 works/.37 works_not bug to a specific pair of versions,
>>>>>>>     I'll be happy to do another diff.
>>>>>>>
>>>>>>>
>>>>>>> Hope you'll have had a good Christmas as well.
>>>>>>>    We've had snow in Alabama since Christmas eve!
>>>>>>>
>>>>>>>
>>>>>>> Regards,
>>>>>>>
>>>>>>> Stuart
>>>>>>>
>>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: Kevin D. Kissell [mailto:kevink@paralogos.com]
>>>>>>> Sent: Friday, December 24, 2010 5:34 PM
>>>>>>> To: Anoop P A
>>>>>>> Cc: STUART VENTERS; Anoop P.A.; linux-mips@linux-mips.org
>>>>>>> Subject: Re: SMTC support status in latest git head.
>>>>>>>
>>>>>>>
>>>>>>> Ah, well, at least we have a stackframe.h fix that preserves David's
>>>>>>> performance tweak for the deeper pipelined processors.  In looking for
>>>>>>> this, I did notice that someone did some modification to the SMTC clock
>>>>>>> tick logic that I was skeptical had ever been tested.  If you've still
>>>>>>> got that kernel binary handy, you might check to see if it boots with
>>>>>>> maxtcs=1 maxvpes=1, maxtcs=2 maxvpes=1, and/or maxtcs=2 maxvpes=2.
>>>>>>>
>>>>>>> Oh, yes, and Merry Christmas one and all!
>>>>>>>
>>>>>>>               Regards,
>>>>>>>
>>>>>>>               Kevin K.
>>>>>>>
>>>>>>> On 12/24/10 8:02 AM, Anoop P A wrote:
>>>>>>>> On Fri, 2010-12-24 at 06:53 -0800, Kevin D. Kissell wrote:
>>>>>>>>> Excellent!  Now, does the attached patch (relative to 2.6.37.11) also
>>>>>>>>> fix things, while preserving the other fixes and performance enhancements?
>>>>>>>>>
>>>>>>>> I have tested that patch with 2.6.37 branch it well passes calibration
>>>>>>>> loop but hangs after switching to mips closource
>>>>>>>>
>>>>>>>> TC 6 going on-line as CPU 6
>>>>>>>> Brought up 7 CPUs
>>>>>>>> bio: create slab<bio-0>   at 0
>>>>>>>> SCSI subsystem initialized
>>>>>>>> Switching to clocksource MIPS
>>>>>>>>
>>>>>>>> I Presume this is a different issue as restoring older file didn't help
>>>>>>>> much to get rid of this hang.
>>>>>>>>
>>>>>>>> diff --git a/arch/mips/include/asm/stackframe.h
>>>>>>>> b/arch/mips/include/asm/stackframe.h
>>>>>>>> index 58730c5..7fc9f10 100644
>>>>>>>> --- a/arch/mips/include/asm/stackframe.h
>>>>>>>> +++ b/arch/mips/include/asm/stackframe.h
>>>>>>>> @@ -195,9 +195,9 @@
>>>>>>>>    		 * to cover the pipeline delay.
>>>>>>>>    		 */
>>>>>>>>    		.set	mips32
>>>>>>>> -		mfc0	v1, CP0_TCSTATUS
>>>>>>>> +		mfc0	v0, CP0_TCSTATUS
>>>>>>>>    		.set	mips0
>>>>>>>> -		LONG_S	v1, PT_TCSTATUS(sp)
>>>>>>>> +		LONG_S	v0, PT_TCSTATUS(sp)
>>>>>>>>    #endif /* CONFIG_MIPS_MT_SMTC */
>>>>>>>>    		LONG_S	$4, PT_R4(sp)
>>>>>>>>    		LONG_S	$5, PT_R5(sp)
>>>>>>>>
>>>>>>>>
>>>>>>>>> /K.
>>>>>>>>>
>>>>>>>>> On 12/24/10 6:39 AM, Anoop P A wrote:
>>>>>>>>>> Hi Kevin, Stuart ,
>>>>>>>>>>
>>>>>>>>>> Woohooo You guys spotted !.
>>>>>>>>>>
>>>>>>>>>>     http://git.linux-mips.org/?p=linux.git;a=commit;h=d5ec6e3c seems to be
>>>>>>>>>> the culprit
>>>>>>>>>>
>>>>>>>>>> Once I restored previous version of stackframe.h 2.6.33-stable started
>>>>>>>>>> booting !.
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Anoop
>>>>>>>>>>
>>>>>>>>>> On Fri, 2010-12-24 at 04:32 -0800, Kevin D. Kissell wrote:
>>>>>>>>>>> Thank you, Stuart!  I've spotted some definite breakage to SMTC between
>>>>>>>>>>> those versions.  In arch/mips/include/asm/stackframe.h, someone moved
>>>>>>>>>>> the store of the Status register value in SAVE_SOME (line 169 or 204,
>>>>>>>>>>> depending on the version) from two instructions after the mfc0 to a
>>>>>>>>>>> point after the #ifdef for SMTC, presumably to get better pipelining of
>>>>>>>>>>> the register access.  Unfortunately, the v1 register is also used in the
>>>>>>>>>>> SMTC-specific fragment to save TCStatus, so the Status value gets
>>>>>>>>>>> clobbered before it gets stored.  This will eventually result in the
>>>>>>>>>>> Status register getting a TCStatus value, which has some bits on common,
>>>>>>>>>>> but isn't identical and sooner or later Bad Things will happen.
>>>>>>>>>>>
>>>>>>>>>>> I'm a little surprised this wasn't caught by visual inspection of the patch.
>>>>>>>>>>>
>>>>>>>>>>> Possible solutions would include reverting the store of the CP0_STATUS
>>>>>>>>>>> value to the block above the #ifdef, or, to retain whatever performance
>>>>>>>>>>> advantage was obtained by moving the store downward, to use v0/$2
>>>>>>>>>>> instead of v1/$3, as the staging register for the TCStatus value.  I'd
>>>>>>>>>>> lean toward the second option, but I'm not in a position to test and
>>>>>>>>>>> submit a patch just now.
>>>>>>>>>>>
>>>>>>>>>>>                 Regards,
>>>>>>>>>>>
>>>>>>>>>>>                 Kevin K.
>>>>>>>>>>>
>>>>>>>>>>> On 12/23/10 1:09 PM, STUART VENTERS wrote:
>>>>>>>>>>>> Kevin,
>>>>>>>>>>>>
>>>>>>>>>>>> I'm not sure if it's useful,
>>>>>>>>>>>>        but finally I got the time to look at the two kernel versions Anoop pointed out.
>>>>>>>>>>>>         works   2.6.32-stable with patch 804
>>>>>>>>>>>>         works_not 2.6.33-stable
>>>>>>>>>>>>
>>>>>>>>>>>> greping for files with CONFIG_MIPS_MT_SMTC
>>>>>>>>>>>>        and looking for timer interrupt related stuff found the following differences:
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> arch/mips/include/asm/irq.h
>>>>>>>>>>>> arch/mips/kernel/irq.c
>>>>>>>>>>>>       do_IRQ
>>>>>>>>>>>>
>>>>>>>>>>>> arch/mips/include/asm/stackframe.h
>>>>>>>>>>>>       SAVE_SOME SAVE_TEMP get/set_saved_sp
>>>>>>>>>>>>
>>>>>>>>>>>> arch/mips/include/asm/time.h
>>>>>>>>>>>>       clocksource_set_clock
>>>>>>>>>>>>
>>>>>>>>>>>> arch/mips/kernel/process.c
>>>>>>>>>>>>       cpu_idle
>>>>>>>>>>>>
>>>>>>>>>>>> arch/mips/kernel/smtc.c
>>>>>>>>>>>>       __irq_entry
>>>>>>>>>>>>       ipi_decode
>>>>>>>>>>>>           SMTC_CLOCK_TICK
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Enclosed are the two subsets of files for a more expert look.
>>>>>>>>>>>>
>>>>>>>>>>>> I'll try to look in more detail after Christmas.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>
>>>>>>>>>>>> Stuart
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>
>


From awg@embtoolkit.org Mon Jan  3 17:54:34 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Jan 2011 17:54:37 +0100 (CET)
Received: from walscop001.walsimou.com ([82.228.201.70]:34912 "EHLO
        bekkor.walsimou.com" rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org
        with ESMTP id S1491985Ab1ACQye (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Mon, 3 Jan 2011 17:54:34 +0100
Received: from wdebian.fr.swissvoice.net (swissvoice-53-74.cnt.nerim.net [213.215.53.74])
  (AUTH: PLAIN walsimou@walsimou.com, SSL: TLSv1/SSLv3,256bits,CAMELLIA256-SHA)
  by bekkor.walsimou.com with esmtp; Mon, 03 Jan 2011 17:54:22 +0100
  id 0108DC27.4D21FF3E.0000A214
Message-ID: <4D21FEFA.2030904@embtoolkit.org>
Date:   Mon, 03 Jan 2011 17:53:14 +0100
From:   Abdoulaye Walsimou GAYE <awg@embtoolkit.org>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.16) Gecko/20101227 Icedove/3.0.11
MIME-Version: 1.0
To:     "Kevin D. Kissell" <kevink@paralogos.com>
CC:     Florian Fainelli <florian@openwrt.org>,
        Linux MIPS org <linux-mips@linux-mips.org>
Subject: Re: CygWin Cross-tool Package?
References: <4D20DABE.5020306@kevink.net> <201101022123.11450.florian@openwrt.org> <4D21ED6C.1020503@paralogos.com>
In-Reply-To: <4D21ED6C.1020503@paralogos.com>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Return-Path: <awg@embtoolkit.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: 28810
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: awg@embtoolkit.org
Precedence: bulk
X-list: linux-mips

On 01/03/2011 04:38 PM, Kevin D. Kissell wrote:
>
> Sigh.  It looked promising, but...
>
> $ make menuconfig
> Checking 'working-make'... ok.
> Checking 'case-sensitive-fs'... failed.
> Checking 'getopt'... ok.
> Checking 'fileutils'... ok.
> Checking 'working-gcc'... ok.
> Checking 'working-g++'... ok.
> Checking 'ncurses'... failed.
> Checking 'zlib'... ok.
> Checking 'gawk'... ok.
> Checking 'flex'... ok.
> Checking 'unzip'... ok.
> Checking 'bzip2'... ok.
> Checking 'patch'... ok.
> Checking 'perl'... ok.
> Checking 'python'... ok.
> Checking 'wget'... ok.
> Checking 'gnutar'... ok.
> Checking 'svn'... ok.
> Checking 'gnu-find'... ok.
> Checking 'getopt-extended'... ok.
> Checking 'non-root'... ok.
>
> Build dependency: OpenWrt can only be built on a case-sensitive filesystem
> ...
>
> It will probably be easier for me to get some random cheap PC running
> Ubuntu than to get a non-case-sensitive filesystem working on an
> existing XP platform.
>
> Any recommendations on cross tool packages for X86/X86-64 Ubuntu
> installations?  Or would splicing the linux-mips.org kernel tree under
> the OpenWrt structure - but under Linux this time - still be the
> shortest path?
>
>             Regards, and thanks,
>
>             Kevin K.
>   


Hello,
If you really want to still use window$, you can use vwmare with an ubuntu
virtual machine.

Best regards,
AWG

From glikely@secretlab.ca Mon Jan  3 18:02:23 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Jan 2011 18:02:28 +0100 (CET)
Received: from mail-pz0-f49.google.com ([209.85.210.49]:60583 "EHLO
        mail-pz0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491988Ab1ACRCX (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Mon, 3 Jan 2011 18:02:23 +0100
Received: by pzk30 with SMTP id 30so3129519pzk.36
        for <multiple recipients>; Mon, 03 Jan 2011 09:02:15 -0800 (PST)
Received: by 10.142.221.13 with SMTP id t13mr17095994wfg.56.1294074134813;
        Mon, 03 Jan 2011 09:02:14 -0800 (PST)
Received: from angua (S01060002b3d79728.cg.shawcable.net [70.72.87.49])
        by mx.google.com with ESMTPS id w42sm29531176wfh.3.2011.01.03.09.02.12
        (version=TLSv1/SSLv3 cipher=RC4-MD5);
        Mon, 03 Jan 2011 09:02:13 -0800 (PST)
Received: by angua (Postfix, from userid 1000)
        id 5A6433C02D5; Mon,  3 Jan 2011 10:02:11 -0700 (MST)
Date:   Mon, 3 Jan 2011 10:02:11 -0700
From:   Grant Likely <grant.likely@secretlab.ca>
To:     Gabor Juhos <juhosg@openwrt.org>
Cc:     Ralf Baechle <ralf@linux-mips.org>, linux-mips@linux-mips.org,
        David Brownell <dbrownell@users.sourceforge.net>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        spi-devel-general@lists.sourceforge.net,
        Imre Kaloz <kaloz@openwrt.org>
Subject: Re: [PATCH v4 09/16] spi: add SPI controller driver for the
 Atheros AR71XX/AR724X/AR913X SoCs
Message-ID: <20110103170211.GA2522@angua.secretlab.ca>
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org>
 <1293994589-6794-10-git-send-email-juhosg@openwrt.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <1293994589-6794-10-git-send-email-juhosg@openwrt.org>
User-Agent: Mutt/1.5.20 (2009-06-14)
Return-Path: <glikely@secretlab.ca>
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: 28811
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: grant.likely@secretlab.ca
Precedence: bulk
X-list: linux-mips

On Sun, Jan 02, 2011 at 07:56:22PM +0100, Gabor Juhos wrote:
> The Atheros AR71XX/AR724X/AR913X SoCs have a built-in SPI controller. This
> patch implements a driver for that.
> 

Mostly looks okay to me.  A few comments below.  Do you want this one
merged via my spi tree, or does it depend on other patches in this
series?  I'm also okay with it going in with the rest of this series.

After addressing comments, feel free to add:
Acked-by: Grant Likely <grant.likely@secretlab.ca>

g.

> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> Cc: David Brownell <dbrownell@users.sourceforge.net>
> Cc: spi-devel-general@lists.sourceforge.net
> ---
> Changes since RFC:
>     - remove DRV_DESC definition and use its previous value directly in the
>       MODULE_DESCRIPTION() macro,
>     - use io{read,write}32 accesors instead of __raw_{read,write}l,
>     - use __dev{init,exit,exit_p} annotations where in the appropriate places,
>     - initialize 'master->bus_num' field to -1 if no platform data specified,
>       so that a bus number can be dynamically assigned,
>     - rename ath79_spi_drv to ath79_spi_driver to avoid section mismatch
>       warnings
> 
> Changes since v1:
>     - rebased against 2.6.37-rc7
> 
> Changes since v2: ---
> 
> Changes since v3:
>     - rebased against 2.6.37-rc8
> 
>  .../include/asm/mach-ath79/ath79_spi_platform.h    |   19 ++
>  drivers/spi/Kconfig                                |    8 +
>  drivers/spi/Makefile                               |    1 +
>  drivers/spi/ath79_spi.c                            |  290 ++++++++++++++++++++
>  4 files changed, 318 insertions(+), 0 deletions(-)
>  create mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
>  create mode 100644 drivers/spi/ath79_spi.c
> 
> diff --git a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
> new file mode 100644
> index 0000000..aa71216
> --- /dev/null
> +++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
> @@ -0,0 +1,19 @@
> +/*
> + *  Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
> + *
> + *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
> + *
> + *  This program is free software; you can redistribute it and/or modify it
> + *  under the terms of the GNU General Public License version 2 as published
> + *  by the Free Software Foundation.
> + */
> +
> +#ifndef _ATH79_SPI_PLATFORM_H
> +#define _ATH79_SPI_PLATFORM_H
> +
> +struct ath79_spi_platform_data {
> +	unsigned	bus_num;
> +	unsigned	num_chipselect;
> +};
> +
> +#endif /* _ATH79_SPI_PLATFORM_H */
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 78f9fd0..f2093e1 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -53,6 +53,14 @@ if SPI_MASTER
>  
>  comment "SPI Master Controller Drivers"
>  
> +config SPI_ATH79
> +	tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
> +	depends on ATH79 && GENERIC_GPIO
> +	select SPI_BITBANG
> +	help
> +	  This enables support for the SPI controller present on the
> +	  Atheros AR71XX/AR724X/AR913X SoCs.
> +
>  config SPI_ATMEL
>  	tristate "Atmel SPI Controller"
>  	depends on (ARCH_AT91 || AVR32)
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 8bc1a5a..875bc3d 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_SPI_MASTER)		+= spi.o
>  
>  # SPI master controller drivers (bus)
>  obj-$(CONFIG_SPI_ATMEL)			+= atmel_spi.o
> +obj-$(CONFIG_SPI_ATH79)			+= ath79_spi.o
>  obj-$(CONFIG_SPI_BFIN)			+= spi_bfin5xx.o
>  obj-$(CONFIG_SPI_BITBANG)		+= spi_bitbang.o
>  obj-$(CONFIG_SPI_AU1550)		+= au1550_spi.o
> diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
> new file mode 100644
> index 0000000..96f169a
> --- /dev/null
> +++ b/drivers/spi/ath79_spi.c
> @@ -0,0 +1,290 @@
> +/*
> + * SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
> + *
> + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
> + *
> + * This driver has been based on the spi-gpio.c:
> + *	Copyright (C) 2006,2008 David Brownell
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/delay.h>
> +#include <linux/spinlock.h>
> +#include <linux/workqueue.h>
> +#include <linux/platform_device.h>
> +#include <linux/io.h>
> +#include <linux/spi/spi.h>
> +#include <linux/spi/spi_bitbang.h>
> +#include <linux/bitops.h>
> +#include <linux/gpio.h>
> +
> +#include <asm/mach-ath79/ar71xx_regs.h>
> +#include <asm/mach-ath79/ath79_spi_platform.h>
> +
> +#define DRV_NAME	"ath79-spi"
> +
> +struct ath79_spi {
> +	struct	spi_bitbang	bitbang;
> +	u32			ioc_base;
> +	u32			reg_ctrl;
> +
> +	void __iomem		*base;
> +
> +	struct platform_device	*pdev;

This field doesn't seem to actually be used anywhere.

> +};
> +
> +static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
> +{
> +	return ioread32(sp->base + reg);
> +}
> +
> +static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned reg, u32 val)
> +{
> +	iowrite32(val, sp->base + reg);
> +}
> +
> +static inline struct ath79_spi *spidev_to_sp(struct spi_device *spi)

should be ath79_spidev_to_sp()

> +{
> +	return spi_master_get_devdata(spi->master);
> +}
> +
> +static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
> +{
> +	struct ath79_spi *sp = spidev_to_sp(spi);
> +	int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
> +
> +	if (is_active) {
> +		/* set initial clock polarity */
> +		if (spi->mode & SPI_CPOL)
> +			sp->ioc_base |= AR71XX_SPI_IOC_CLK;
> +		else
> +			sp->ioc_base &= ~AR71XX_SPI_IOC_CLK;
> +
> +		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
> +	}
> +
> +	if (spi->chip_select) {
> +		unsigned long gpio = (unsigned long) spi->controller_data;
> +
> +		/* SPI is normally active-low */
> +		gpio_set_value(gpio, cs_high);
> +	} else {
> +		if (cs_high)
> +			sp->ioc_base |= AR71XX_SPI_IOC_CS0;
> +		else
> +			sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
> +
> +		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
> +	}
> +
> +}
> +
> +static int ath79_spi_setup_cs(struct spi_device *spi)
> +{
> +	struct ath79_spi *sp = spidev_to_sp(spi);
> +
> +	/* enable GPIO mode */
> +	ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
> +
> +	/* save CTRL register */
> +	sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL);
> +	sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC);
> +
> +	/* TODO: setup speed? */
> +	ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
> +
> +	if (spi->chip_select) {
> +		unsigned long gpio = (unsigned long) spi->controller_data;

Casting here is bad practice.  It would be better to have an explicit
ath97_spi_controller_data structure.

> +		int status = 0;
> +
> +		status = gpio_request(gpio, dev_name(&spi->dev));
> +		if (status)
> +			return status;
> +
> +		status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH);
> +		if (status) {
> +			gpio_free(gpio);
> +			return status;
> +		}
> +	} else {
> +		if (spi->mode & SPI_CS_HIGH)
> +			sp->ioc_base |= AR71XX_SPI_IOC_CS0;
> +		else
> +			sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
> +		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
> +	}
> +
> +	return 0;
> +}
> +
> +static void ath79_spi_cleanup_cs(struct spi_device *spi)
> +{
> +	struct ath79_spi *sp = spidev_to_sp(spi);
> +
> +	if (spi->chip_select) {
> +		unsigned long gpio = (unsigned long) spi->controller_data;
> +		gpio_free(gpio);
> +	}
> +
> +	/* restore CTRL register */
> +	ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
> +	/* disable GPIO mode */
> +	ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
> +}
> +
> +static int ath79_spi_setup(struct spi_device *spi)
> +{
> +	int status = 0;
> +
> +	if (spi->bits_per_word > 32)
> +		return -EINVAL;
> +
> +	if (!spi->controller_state) {
> +		status = ath79_spi_setup_cs(spi);
> +		if (status)
> +			return status;
> +	}
> +
> +	status = spi_bitbang_setup(spi);
> +	if (status && !spi->controller_state)
> +		ath79_spi_cleanup_cs(spi);
> +
> +	return status;
> +}
> +
> +static void ath79_spi_cleanup(struct spi_device *spi)
> +{
> +	ath79_spi_cleanup_cs(spi);
> +	spi_bitbang_cleanup(spi);
> +}
> +
> +static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
> +			       u32 word, u8 bits)
> +{
> +	struct ath79_spi *sp = spidev_to_sp(spi);
> +	u32 ioc = sp->ioc_base;
> +
> +	/* clock starts at inactive polarity */
> +	for (word <<= (32 - bits); likely(bits); bits--) {
> +		u32 out;
> +
> +		if (word & (1 << 31))
> +			out = ioc | AR71XX_SPI_IOC_DO;
> +		else
> +			out = ioc & ~AR71XX_SPI_IOC_DO;
> +
> +		/* setup MSB (to slave) on trailing edge */
> +		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
> +		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK);
> +
> +		word <<= 1;
> +	}
> +
> +	return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
> +}
> +
> +static __devinit int ath79_spi_probe(struct platform_device *pdev)
> +{
> +	struct spi_master *master;
> +	struct ath79_spi *sp;
> +	struct ath79_spi_platform_data *pdata;
> +	struct resource	*r;
> +	int ret;
> +
> +	master = spi_alloc_master(&pdev->dev, sizeof(*sp));
> +	if (master == NULL) {
> +		dev_err(&pdev->dev, "failed to allocate spi master\n");
> +		return -ENOMEM;
> +	}
> +
> +	sp = spi_master_get_devdata(master);
> +	platform_set_drvdata(pdev, sp);
> +
> +	pdata = pdev->dev.platform_data;
> +
> +	master->setup = ath79_spi_setup;
> +	master->cleanup = ath79_spi_cleanup;
> +	if (pdata) {
> +		master->bus_num = pdata->bus_num;
> +		master->num_chipselect = pdata->num_chipselect;
> +	} else {
> +		master->bus_num = -1;
> +		master->num_chipselect = 1;
> +	}
> +
> +	sp->bitbang.master = spi_master_get(master);
> +	sp->bitbang.chipselect = ath79_spi_chipselect;
> +	sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
> +	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
> +	sp->bitbang.flags = SPI_CS_HIGH;
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (r == NULL) {
> +		ret = -ENOENT;
> +		goto err_put_master;
> +	}
> +
> +	sp->base = ioremap(r->start, r->end - r->start + 1);
> +	if (!sp->base) {
> +		ret = -ENXIO;
> +		goto err_put_master;
> +	}
> +
> +	ret = spi_bitbang_start(&sp->bitbang);
> +	if (ret)
> +		goto err_unmap;
> +
> +	return 0;
> +
> +err_unmap:
> +	iounmap(sp->base);
> +err_put_master:
> +	platform_set_drvdata(pdev, NULL);
> +	spi_master_put(sp->bitbang.master);
> +
> +	return ret;
> +}
> +
> +static __devexit int ath79_spi_remove(struct platform_device *pdev)
> +{
> +	struct ath79_spi *sp = platform_get_drvdata(pdev);
> +
> +	spi_bitbang_stop(&sp->bitbang);
> +	iounmap(sp->base);
> +	platform_set_drvdata(pdev, NULL);
> +	spi_master_put(sp->bitbang.master);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver ath79_spi_driver = {
> +	.probe		= ath79_spi_probe,
> +	.remove		= __devexit_p(ath79_spi_remove),
> +	.driver		= {
> +		.name	= DRV_NAME,
> +		.owner	= THIS_MODULE,
> +	},
> +};
> +
> +static __init int ath79_spi_init(void)
> +{
> +	return platform_driver_register(&ath79_spi_driver);
> +}
> +module_init(ath79_spi_init);
> +
> +static __exit void ath79_spi_exit(void)
> +{
> +	platform_driver_unregister(&ath79_spi_driver);
> +}
> +module_exit(ath79_spi_exit);
> +
> +MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR91X");
> +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:" DRV_NAME);
> -- 
> 1.7.2.1
> 
> 
> ------------------------------------------------------------------------------
> Learn how Oracle Real Application Clusters (RAC) One Node allows customers
> to consolidate database storage, standardize their database environment, and, 
> should the need arise, upgrade to a full multi-node Oracle RAC database 
> without downtime or disruption
> http://p.sf.net/sfu/oracle-sfdevnl
> _______________________________________________
> spi-devel-general mailing list
> spi-devel-general@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/spi-devel-general

From f.fainelli@gmail.com Mon Jan  3 18:25:37 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Jan 2011 18:25:40 +0100 (CET)
Received: from mail-wy0-f177.google.com ([74.125.82.177]:41503 "EHLO
        mail-wy0-f177.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491994Ab1ACRZh (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Mon, 3 Jan 2011 18:25:37 +0100
Received: by wyf22 with SMTP id 22so13482958wyf.36
        for <linux-mips@linux-mips.org>; Mon, 03 Jan 2011 09:25:31 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:sender:from:organization:to
         :subject:date:user-agent:cc:references:in-reply-to:mime-version
         :content-type:content-transfer-encoding:message-id;
        bh=Z5+N+6TkJFYWyA6VpcRlXSUUSr3ZNwCcYEChnxUTk9Q=;
        b=YWv5XgQPeac+zXj4MT/nA92HQoaeLLxIAih0D4hV768g8/csAbss2QKeZSdQFzR9nl
         /Z1W1ePC8LMGUZtuqOwbL3R71olWr4tUCSN4eZn6hLo3zfNUiXTh2HxMOPoQwUq18Lo8
         SMBxaBHsERpW6jBJqEmoDmIa7n0eDU1zWV/sQ=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=sender:from:organization:to:subject:date:user-agent:cc:references
         :in-reply-to:mime-version:content-type:content-transfer-encoding
         :message-id;
        b=gwlarF6L/t3LDttGYSbGyG4aGpkSJNnAkr7/VajduC4OYtcrAHQVltgeYXkdxlepIO
         RaBBrVO9gqIteanJd9Plul6Xy+mm3MZEcalfopp83Ld3kSTvD1C98yB/9zgxqMH6esxd
         HfMd8MnVg3xyIkUvtdBlxITPBtH5F2xpZ04sA=
Received: by 10.227.155.138 with SMTP id s10mr11800010wbw.61.1294075530432;
        Mon, 03 Jan 2011 09:25:30 -0800 (PST)
Received: from flexo.localnet (bobafett.staff.proxad.net [213.228.1.121])
        by mx.google.com with ESMTPS id 11sm14311338wbi.6.2011.01.03.09.25.28
        (version=SSLv3 cipher=RC4-MD5);
        Mon, 03 Jan 2011 09:25:28 -0800 (PST)
From:   Florian Fainelli <florian@openwrt.org>
Organization: OpenWrt
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Subject: Re: CygWin Cross-tool Package?
Date:   Mon, 3 Jan 2011 18:26:05 +0100
User-Agent: KMail/1.13.5 (Linux/2.6.35-24-server; KDE/4.5.1; x86_64; ; )
Cc:     Linux MIPS org <linux-mips@linux-mips.org>
References: <4D20DABE.5020306@kevink.net> <201101022123.11450.florian@openwrt.org> <4D21ED6C.1020503@paralogos.com>
In-Reply-To: <4D21ED6C.1020503@paralogos.com>
MIME-Version: 1.0
Content-Type: Text/Plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Message-Id: <201101031826.05444.florian@openwrt.org>
Return-Path: <f.fainelli@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: 28812
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: florian@openwrt.org
Precedence: bulk
X-list: linux-mips

On Monday 03 January 2011 16:38:20 Kevin D. Kissell wrote:
> On 1/2/2011 12:23 PM, Florian Fainelli wrote:
> > Hello Kevin,
> > 
> > On Sunday 02 January 2011 21:06:22 Kevin D. Kissell wrote:
> >> ...By any chance, could one of
> >> you point me to a functional, pre-built package I could install under
> >> Cygwin to do kernel builds?
> > 
> > Providing that you install of the required dependencies (subversion,
> > flex, bison ...), OpenWrt can build a Linux kernel and root filesystem
> > under Cygwin.
> > 
> > Hope that helps.
> 
> Sigh.  It looked promising, but...
> 
> $ make menuconfig
> Checking 'working-make'... ok.
> Checking 'case-sensitive-fs'... failed.
> Checking 'getopt'... ok.
> Checking 'fileutils'... ok.
> Checking 'working-gcc'... ok.
> Checking 'working-g++'... ok.
> Checking 'ncurses'... failed.
> Checking 'zlib'... ok.
> Checking 'gawk'... ok.
> Checking 'flex'... ok.
> Checking 'unzip'... ok.
> Checking 'bzip2'... ok.
> Checking 'patch'... ok.
> Checking 'perl'... ok.
> Checking 'python'... ok.
> Checking 'wget'... ok.
> Checking 'gnutar'... ok.
> Checking 'svn'... ok.
> Checking 'gnu-find'... ok.
> Checking 'getopt-extended'... ok.
> Checking 'non-root'... ok.
> 
> Build dependency: OpenWrt can only be built on a case-sensitive filesystem
> ...
> 
> It will probably be easier for me to get some random cheap PC running
> Ubuntu than to get a non-case-sensitive filesystem working on an
> existing XP platform.

And that can be achieved simply by using a case sensitive mount:
http://www.mail-archive.com/cygwin@cygwin.com/msg81382.html

> 
> Any recommendations on cross tool packages for X86/X86-64 Ubuntu
> installations?  Or would splicing the linux-mips.org kernel tree under
> the OpenWrt structure - but under Linux this time - still be the
> shortest path?

OpenWrt or some other project like buildroot would work fine building a 
toolchain and kernel for that specific target.
--
Florian

From anoop.pa@gmail.com Mon Jan  3 20:09:34 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Jan 2011 20:09:38 +0100 (CET)
Received: from mail-fx0-f49.google.com ([209.85.161.49]:39474 "EHLO
        mail-fx0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1492002Ab1ACTJe (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Mon, 3 Jan 2011 20:09:34 +0100
Received: by fxm19 with SMTP id 19so12745599fxm.36
        for <linux-mips@linux-mips.org>; Mon, 03 Jan 2011 11:09:29 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:subject:from:to:cc
         :in-reply-to:references:content-type:date:message-id:mime-version
         :x-mailer:content-transfer-encoding;
        bh=y3HbRURs9IsxsY35Uxuv5sPT3U8itjYxt2hlYDgGzKE=;
        b=aqtSzpRAyt/UNV28prKp5bxzj7cciGqXB8AO8vXlDoDKnbyztBmh2xDQkZzOW2TcSq
         oNar/vf2y8WEOy+4HSuuVtgZCAEuG2CVzvFda/hYpIX+sAnewMQPjraoyKlvWYIA4vsX
         Ptp6i3NykLApxylYqFlqM47K6LQ5Whj+VLOqM=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=subject:from:to:cc:in-reply-to:references:content-type:date
         :message-id:mime-version:x-mailer:content-transfer-encoding;
        b=V91LpeeQRP99WBuMpVW8PtI456s2vTuEvO/ABqnEOWEjWrPPk5JH9i6bt+Oj6p2E+/
         62r9utzfLuTiSkg52GUP0x9BKIWTlKdxqYaoZ9lssgNxST2N+0sp6xW0RIW7aPPP3NCj
         x4kmyPrxeKK4Pjxm6pSdLjIYXkOEgE4XMVnvM=
Received: by 10.223.69.141 with SMTP id z13mr9077405fai.9.1294081769035;
        Mon, 03 Jan 2011 11:09:29 -0800 (PST)
Received: from [172.16.48.51] ([59.160.135.215])
        by mx.google.com with ESMTPS id e6sm4857336fav.32.2011.01.03.11.09.25
        (version=SSLv3 cipher=RC4-MD5);
        Mon, 03 Jan 2011 11:09:28 -0800 (PST)
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
In-Reply-To: <4D21F5D3.50604@paralogos.com>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
         <1293470392.27661.202.camel@paanoop1-desktop>
         <1293524389.27661.210.camel@paanoop1-desktop>
         <4D19A31E.1090905@paralogos.com>
         <1293798476.27661.279.camel@paanoop1-desktop>
         <4D1EE913.1070203@paralogos.com>
         <1294067561.27661.293.camel@paanoop1-desktop>
         <4D21F5D3.50604@paralogos.com>
Content-Type: text/plain; charset="UTF-8"
Date:   Tue, 04 Jan 2011 00:50:26 +0530
Message-ID: <1294082426.27661.330.camel@paanoop1-desktop>
Mime-Version: 1.0
X-Mailer: Evolution 2.28.3 
Content-Transfer-Encoding: 7bit
Return-Path: <anoop.pa@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: 28813
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips

Hi Kevin,

On Mon, 2011-01-03 at 08:14 -0800, Kevin D. Kissell wrote:
> The very first SMTC implementations didn't support full kernel-mode
> preemption, which anyway wasn't a priority, given the hardware event
> response support in MIPS MT.  I believe it was later made compatible,
> but it was never extensively exercised.  Since SMTC has fingers in some
> pretty low-level atomicity mechanisms, if a new, parallel set was
> implemented for RCU, I can easily imagine that nobody has yet
> implemented SMTC-ified variants of that set.
> 
> Your last statement isn't very clear, though.  Are you saying that if
> you configure for no forced preemption and with TREE_CPU, the 2.6.37
> kernel boots all the way up, or that it simply hangs later?   What's the
> last rev kernel that actually boots all the way up?

I have debugged this a bit more. It seems that kernel getting stalled
while executing on TC's of second VPE . 
INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
by 1, t=2504 jiffies)
INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
by 1, t=10036 jiffies)
INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
by 1, t=17568 jiffies)
INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
by 1, t=25100 jiffies)
INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
by 1, t=32632 jiffies)
INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
by 1, t=40164 jiffies)

With CONFIG_TREE_CPU we were not hitting this scenario very often.
However with CONFIG_PREEMPT_TREE_CPU stall happens most of the time.

I presume some issue in my timer setup . I am not seeing timer interrupt
(or IPI interrupt) getting  incremented for VPE1 tcs on a completely
booted 2.6.32-stable kernel.

/ # cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
CPU6
  1:        148      15023      15140      15093       3779          8
2            MIPS  SMTC_IPI
  6:          0          0          0          0          0          0
0            MIPS  MSP CIC cascade
  8:          0          0          0          0          0          0
0         MSP_CIC  Softreset button
  9:          0          0          0          0          0          0
0         MSP_CIC  Standby switch
 21:          0          0          0          0          0          0
0         MSP_CIC  MSP PER cascade
 25:      15113        341          4          7          0          0
0         MSP_CIC  timer
 27:        260          9          0          1          0          0
0         MSP_CIC  serial
 34:          0          0          0          0          0          0
0         MSP_CIC  timer

Can't we use separate timer interrupts for VPE1 and VPE0 in SMTC ?. 

I have tried setting up VPE1 timer from get_co_compare_int as follows

unsigned int __cpuinit get_c0_compare_int(void)
{
	if ((1==get_current_vpe()) && !vpe1_timr_installed){
	
	memcpy(&timer_vpe1,&c0_compare_irqaction,sizeof(timer_vpe1));
	
	setup_irq(MSP_INT_VPE1_TIMER, &timer_vpe1);
                  vpe1_timr_installed++;
          }
          return (get_current_vpe() ? MSP_INT_VPE1_TIMER :
MSP_INT_VPE0_TIMER);
}

Thanks
Anoop

> 
>             Regards,
> 
>             Kevin K.
> 
> On 1/3/2011 7:12 AM, Anoop P A wrote:
> > Hi ,
> >
> > Following patch restricts TREE_CPU RCU implementation only for !PREEMPT
> > SMP kernel.  
> > http://git.linux-mips.org/?p=linux.git;a=commit;h=687d7a960aea46e016182c7ce346d62c4dbd0366
> >
> > CONFIG_TREE_PREEMPT_RCU option seems to be not working for SMTC kernel
> > ( which will be only available RCU implementation for SMTC kernel from
> > 2.6.37 onwards) .
> >
> > With no forced preemption and selecting TREE_CPU I am able to boot
> > further to the hang that I have reported.
> >
> > Thanks
> > Anoop
> >
> > On Sat, 2011-01-01 at 00:42 -0800, Kevin D. Kissell wrote:
> >> At this point the logical thing to do would seem to look at your kernel
> >> image and disassemble smtc_ipi_replay(), which is where the EPC of VPE 0
> >> shows the last exception to have been taken.  That's a critical SMTC
> >> routine that gets called whenever an xxx_irq_restore() enables
> >> interrupts, so that virtual per-TC IPI interrupts that were posted while
> >> the TC had interrupts disabled can be handled deterministically.  As I
> >> mentioned in an earlier message, there was some cleanup work from David
> >> Howell that changed a number of irq management-related function names
> >> and prototypes across all architectures, which went into linux-mips.org
> >> at very roughly the time of the breakage.  The SMTC overlay over the irq
> >> implementation has been pretty robust, but it's written in a perhaps
> >> doomed attempt to be both efficient and using a maximum amount of common
> >> code with the general case.  A mechanical or semi-mechanical change
> >> could conceivably have broken things.
> >>
> >>             Regards,
> >>
> >>             Kevin K.
> >>
> >>
> >> On 12/31/2010 4:27 AM, Anoop P A wrote:
> >>> Hi ,
> >>>
> >>> Kernel hangs on stop_machine call. Please find mt reg dump below.
> >>> Another important observation is even though 2.6.33 kernel + stackframe
> >>> patch well passes calibration hang , I am still unable boot in to a
> >>> initramfs root ( verified ramfs working with VSMP). So it looks like
> >>> still some issue to fix between 2.6.32 and 2.6.33 .
> >>> ######################## Log ###########################
> >>>
> >>> === MIPS MT State Dump ===
> >>> -- Global State --
> >>>    MVPControl Passed: 00000005
> >>>    MVPControl Read: 00000004
> >>>    MVPConf0 : a8008406
> >>> -- per-VPE State --
> >>>   VPE 0
> >>>    VPEControl : 00008000
> >>>    VPEConf0 : 800f0003
> >>>    VPE0.Status : 11004201
> >>>    VPE0.EPC : 8010dc54 smtc_ipi_replay+0xcc/0x108
> >>>    VPE0.Cause : 50804000
> >>>    VPE0.Config7 : 00010000
> >>>   VPE 1
> >>>    VPEControl : 00068006
> >>>    VPEConf0 : 80cf0003
> >>>    VPE1.Status : 11008301
> >>>    VPE1.EPC : 801022a0 r4k_wait+0x20/0x40
> >>>    VPE1.Cause : 50800000
> >>>    VPE1.Config7 : 00010000
> >>> -- per-TC State --
> >>>   TC 0 (current TC with VPE EPC above)
> >>>    TCStatus : 18102000
> >>>    TCBind : 00000000
> >>>    TCRestart : 803fa19c printk+0xc/0x30
> >>>    TCHalt : 00000000
> >>>    TCContext : 00000000
> >>>   TC 1
> >>>    TCStatus : 18902000
> >>>    TCBind : 00200000
> >>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
> >>>    TCHalt : 00000000
> >>>    TCContext : 00140000
> >>>   TC 2
> >>>    TCStatus : 18902000
> >>>    TCBind : 00400000
> >>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
> >>>    TCHalt : 00000000
> >>>    TCContext : 00280000
> >>>   TC 3
> >>>    TCStatus : 18902000
> >>>    TCBind : 00600000
> >>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
> >>>    TCHalt : 00000000
> >>>    TCContext : 003c0000
> >>>   TC 4
> >>>    TCStatus : 18902000
> >>>    TCBind : 00800001
> >>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
> >>>    TCHalt : 00000000
> >>>    TCContext : 00500000
> >>>   TC 5
> >>>    TCStatus : 18902000
> >>>    TCBind : 00a00001
> >>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
> >>>    TCHalt : 00000000
> >>>    TCContext : 00640000
> >>>   TC 6
> >>>    TCStatus : 18902000
> >>>    TCBind : 00c00001
> >>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
> >>>    TCHalt : 00000000
> >>>    TCContext : 00780000
> >>> Counter Interrupts taken per CPU (TC)
> >>> 0: 0
> >>> 1: 0
> >>> 2: 0
> >>> 3: 0
> >>> 4: 0
> >>> 5: 0
> >>> 6: 0
> >>> 7: 0
> >>> Self-IPI invocations:
> >>> 0: 12
> >>> 1: 0
> >>> 2: 0
> >>> 3: 0
> >>> 4: 0
> >>> 5: 5
> >>> 6: 4
> >>> 7: 0
> >>> IPIQ[0]: head = 0x0, tail = 0x0, depth = 0
> >>> IPIQ[1]: head = 0x0, tail = 0x0, depth = 0
> >>> IPIQ[2]: head = 0x0, tail = 0x0, depth = 0
> >>> IPIQ[3]: head = 0x0, tail = 0x0, depth = 0
> >>> IPIQ[4]: head = 0x0, tail = 0x0, depth = 0
> >>> IPIQ[5]: head = 0x0, tail = 0x0, depth = 0
> >>> IPIQ[6]: head = 0x0, tail = 0x0, depth = 0
> >>> IPIQ[7]: head = 0x0, tail = 0x0, depth = 0
> >>> 0 Recoveries of "stolen" FPU
> >>> ===========================
> >>>
> >>> ################################################################
> >>>
> >>> Thanks
> >>> Anoop
> >>>
> >>> On Tue, 2010-12-28 at 00:43 -0800, Kevin D. Kissell wrote:
> >>>> I took a quick look last night, and the only thing that looked vaguely 
> >>>> dangerous in changes since the timer changes I alluded to earlier was 
> >>>> the global naming cleanup of irq-related function names that David 
> >>>> Howell submitted.  The diff didn't look dangerous in itself, but some of 
> >>>> the definitions are nested subtly for SMTC to maximize the amount of 
> >>>> common code, and I could imagine something getting lost in translation 
> >>>> there.  If that were really the problem, it would of course affect much 
> >>>> more than just the timer subsystem, but early in the boot process, 
> >>>> timers are pretty much the only interrupts that have to be handled 
> >>>> correctly.
> >>>>
> >>>> I'm travelling today, but will take a look at timekeeping_notify() 
> >>>> tomorrow or the next day...
> >>>>
> >>>> /K.
> >>>>
> >>>> On 12/28/10 12:19 AM, Anoop P A wrote:
> >>>>> Hi,
> >>>>>
> >>>>> I had a glance into the code diff without notice of any suspect-able
> >>>>> code .
> >>>>> Tracing the hang showed that it is getting hanged in timekeeping_notify
> >>>>> function.
> >>>>>
> >>>>> Thanks,
> >>>>> Anoop
> >>>>>
> >>>>> PS: I may not be available until Thursday
> >>>>>
> >>>>> On Mon, 2010-12-27 at 22:49 +0530, Anoop P A wrote:
> >>>>>> Hi Kevin,
> >>>>>>
> >>>>>> It is very unlikely that the patch you pointed has any impact on the the
> >>>>>> hang I am seeing. The patch you have mentioned got into kernel around
> >>>>>> 2.6.32 timeframe. I am able to boot both 2.6.32 and  2.6.33 kernel ( +
> >>>>>> stackframe patch) .
> >>>>>>
> >>>>>> Hi Stuart,
> >>>>>>
> >>>>>> I haven't got much time to spend on this today.
> >>>>>>
> >>>>>> I had got 2.6.36-stable(+ stack frame patch) booting last day and I have
> >>>>>> observed hang issue with 2.6.37-rc1 ( Same as rc6 and current git head)
> >>>>>>
> >>>>>> So probably some patches in 2.6.37 branch introduced this hang.
> >>>>>>
> >>>>>> Hopefully I will get some free slot tomorrow so that I can look into
> >>>>>> code diff .
> >>>>>>
> >>>>>> Thanks
> >>>>>> Anoop
> >>>>>>
> >>>>>> On Mon, 2010-12-27 at 09:49 -0600, STUART VENTERS wrote:
> >>>>>>> Kevin,
> >>>>>>>
> >>>>>>> Outstanding, sometimes it's better to be lucky than good.
> >>>>>>>
> >>>>>>>
> >>>>>>> Anoop,
> >>>>>>>
> >>>>>>> Maybe we can get lucky again.
> >>>>>>>
> >>>>>>> If you can isolate the .33 works/.37 works_not bug to a specific pair of versions,
> >>>>>>>     I'll be happy to do another diff.
> >>>>>>>
> >>>>>>>
> >>>>>>> Hope you'll have had a good Christmas as well.
> >>>>>>>    We've had snow in Alabama since Christmas eve!
> >>>>>>>
> >>>>>>>
> >>>>>>> Regards,
> >>>>>>>
> >>>>>>> Stuart
> >>>>>>>
> >>>>>>>
> >>>>>>> -----Original Message-----
> >>>>>>> From: Kevin D. Kissell [mailto:kevink@paralogos.com]
> >>>>>>> Sent: Friday, December 24, 2010 5:34 PM
> >>>>>>> To: Anoop P A
> >>>>>>> Cc: STUART VENTERS; Anoop P.A.; linux-mips@linux-mips.org
> >>>>>>> Subject: Re: SMTC support status in latest git head.
> >>>>>>>
> >>>>>>>
> >>>>>>> Ah, well, at least we have a stackframe.h fix that preserves David's
> >>>>>>> performance tweak for the deeper pipelined processors.  In looking for
> >>>>>>> this, I did notice that someone did some modification to the SMTC clock
> >>>>>>> tick logic that I was skeptical had ever been tested.  If you've still
> >>>>>>> got that kernel binary handy, you might check to see if it boots with
> >>>>>>> maxtcs=1 maxvpes=1, maxtcs=2 maxvpes=1, and/or maxtcs=2 maxvpes=2.
> >>>>>>>
> >>>>>>> Oh, yes, and Merry Christmas one and all!
> >>>>>>>
> >>>>>>>               Regards,
> >>>>>>>
> >>>>>>>               Kevin K.
> >>>>>>>
> >>>>>>> On 12/24/10 8:02 AM, Anoop P A wrote:
> >>>>>>>> On Fri, 2010-12-24 at 06:53 -0800, Kevin D. Kissell wrote:
> >>>>>>>>> Excellent!  Now, does the attached patch (relative to 2.6.37.11) also
> >>>>>>>>> fix things, while preserving the other fixes and performance enhancements?
> >>>>>>>>>
> >>>>>>>> I have tested that patch with 2.6.37 branch it well passes calibration
> >>>>>>>> loop but hangs after switching to mips closource
> >>>>>>>>
> >>>>>>>> TC 6 going on-line as CPU 6
> >>>>>>>> Brought up 7 CPUs
> >>>>>>>> bio: create slab<bio-0>   at 0
> >>>>>>>> SCSI subsystem initialized
> >>>>>>>> Switching to clocksource MIPS
> >>>>>>>>
> >>>>>>>> I Presume this is a different issue as restoring older file didn't help
> >>>>>>>> much to get rid of this hang.
> >>>>>>>>
> >>>>>>>> diff --git a/arch/mips/include/asm/stackframe.h
> >>>>>>>> b/arch/mips/include/asm/stackframe.h
> >>>>>>>> index 58730c5..7fc9f10 100644
> >>>>>>>> --- a/arch/mips/include/asm/stackframe.h
> >>>>>>>> +++ b/arch/mips/include/asm/stackframe.h
> >>>>>>>> @@ -195,9 +195,9 @@
> >>>>>>>>    		 * to cover the pipeline delay.
> >>>>>>>>    		 */
> >>>>>>>>    		.set	mips32
> >>>>>>>> -		mfc0	v1, CP0_TCSTATUS
> >>>>>>>> +		mfc0	v0, CP0_TCSTATUS
> >>>>>>>>    		.set	mips0
> >>>>>>>> -		LONG_S	v1, PT_TCSTATUS(sp)
> >>>>>>>> +		LONG_S	v0, PT_TCSTATUS(sp)
> >>>>>>>>    #endif /* CONFIG_MIPS_MT_SMTC */
> >>>>>>>>    		LONG_S	$4, PT_R4(sp)
> >>>>>>>>    		LONG_S	$5, PT_R5(sp)
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>> /K.
> >>>>>>>>>
> >>>>>>>>> On 12/24/10 6:39 AM, Anoop P A wrote:
> >>>>>>>>>> Hi Kevin, Stuart ,
> >>>>>>>>>>
> >>>>>>>>>> Woohooo You guys spotted !.
> >>>>>>>>>>
> >>>>>>>>>>     http://git.linux-mips.org/?p=linux.git;a=commit;h=d5ec6e3c seems to be
> >>>>>>>>>> the culprit
> >>>>>>>>>>
> >>>>>>>>>> Once I restored previous version of stackframe.h 2.6.33-stable started
> >>>>>>>>>> booting !.
> >>>>>>>>>>
> >>>>>>>>>> Thanks,
> >>>>>>>>>> Anoop
> >>>>>>>>>>
> >>>>>>>>>> On Fri, 2010-12-24 at 04:32 -0800, Kevin D. Kissell wrote:
> >>>>>>>>>>> Thank you, Stuart!  I've spotted some definite breakage to SMTC between
> >>>>>>>>>>> those versions.  In arch/mips/include/asm/stackframe.h, someone moved
> >>>>>>>>>>> the store of the Status register value in SAVE_SOME (line 169 or 204,
> >>>>>>>>>>> depending on the version) from two instructions after the mfc0 to a
> >>>>>>>>>>> point after the #ifdef for SMTC, presumably to get better pipelining of
> >>>>>>>>>>> the register access.  Unfortunately, the v1 register is also used in the
> >>>>>>>>>>> SMTC-specific fragment to save TCStatus, so the Status value gets
> >>>>>>>>>>> clobbered before it gets stored.  This will eventually result in the
> >>>>>>>>>>> Status register getting a TCStatus value, which has some bits on common,
> >>>>>>>>>>> but isn't identical and sooner or later Bad Things will happen.
> >>>>>>>>>>>
> >>>>>>>>>>> I'm a little surprised this wasn't caught by visual inspection of the patch.
> >>>>>>>>>>>
> >>>>>>>>>>> Possible solutions would include reverting the store of the CP0_STATUS
> >>>>>>>>>>> value to the block above the #ifdef, or, to retain whatever performance
> >>>>>>>>>>> advantage was obtained by moving the store downward, to use v0/$2
> >>>>>>>>>>> instead of v1/$3, as the staging register for the TCStatus value.  I'd
> >>>>>>>>>>> lean toward the second option, but I'm not in a position to test and
> >>>>>>>>>>> submit a patch just now.
> >>>>>>>>>>>
> >>>>>>>>>>>                 Regards,
> >>>>>>>>>>>
> >>>>>>>>>>>                 Kevin K.
> >>>>>>>>>>>
> >>>>>>>>>>> On 12/23/10 1:09 PM, STUART VENTERS wrote:
> >>>>>>>>>>>> Kevin,
> >>>>>>>>>>>>
> >>>>>>>>>>>> I'm not sure if it's useful,
> >>>>>>>>>>>>        but finally I got the time to look at the two kernel versions Anoop pointed out.
> >>>>>>>>>>>>         works   2.6.32-stable with patch 804
> >>>>>>>>>>>>         works_not 2.6.33-stable
> >>>>>>>>>>>>
> >>>>>>>>>>>> greping for files with CONFIG_MIPS_MT_SMTC
> >>>>>>>>>>>>        and looking for timer interrupt related stuff found the following differences:
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> arch/mips/include/asm/irq.h
> >>>>>>>>>>>> arch/mips/kernel/irq.c
> >>>>>>>>>>>>       do_IRQ
> >>>>>>>>>>>>
> >>>>>>>>>>>> arch/mips/include/asm/stackframe.h
> >>>>>>>>>>>>       SAVE_SOME SAVE_TEMP get/set_saved_sp
> >>>>>>>>>>>>
> >>>>>>>>>>>> arch/mips/include/asm/time.h
> >>>>>>>>>>>>       clocksource_set_clock
> >>>>>>>>>>>>
> >>>>>>>>>>>> arch/mips/kernel/process.c
> >>>>>>>>>>>>       cpu_idle
> >>>>>>>>>>>>
> >>>>>>>>>>>> arch/mips/kernel/smtc.c
> >>>>>>>>>>>>       __irq_entry
> >>>>>>>>>>>>       ipi_decode
> >>>>>>>>>>>>           SMTC_CLOCK_TICK
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> Enclosed are the two subsets of files for a more expert look.
> >>>>>>>>>>>>
> >>>>>>>>>>>> I'll try to look in more detail after Christmas.
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> Cheers,
> >>>>>>>>>>>>
> >>>>>>>>>>>> Stuart
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >
> >
> 



From juhosg@openwrt.org Mon Jan  3 20:35:39 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 03 Jan 2011 20:35:42 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:49459 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1492001Ab1ACTfj (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Mon, 3 Jan 2011 20:35:39 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 5AF0345C012;
        Mon,  3 Jan 2011 20:35:34 +0100 (CET)
Received: from [192.168.254.10] (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 0371A1F0001;
        Mon,  3 Jan 2011 20:35:34 +0100 (CET)
Message-ID: <4D222503.1000700@openwrt.org>
Date:   Mon, 03 Jan 2011 20:35:31 +0100
From:   Gabor Juhos <juhosg@openwrt.org>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; hu-HU; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Florian Fainelli <florian@openwrt.org>
CC:     Ralf Baechle <ralf@linux-mips.org>, linux-mips@linux-mips.org,
        Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@atheros.com>,
        Kathy Giori <Kathy.Giori@atheros.com>
Subject: Re: [PATCH v4 01/16] MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X
 SoCs
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org> <1293994589-6794-2-git-send-email-juhosg@openwrt.org> <201101022143.13712.florian@openwrt.org>
In-Reply-To: <201101022143.13712.florian@openwrt.org>
X-Enigmail-Version: 1.1.1
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
X-VBMS: A16D4C31A5A | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28814
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Hi Florian,

<...>

>> +
>> +static DEFINE_SPINLOCK(ath79_device_reset_lock);
>> +
>> +u32 ath79_cpu_freq;
>> +EXPORT_SYMBOL_GPL(ath79_cpu_freq);
>> +
>> +u32 ath79_ahb_freq;
>> +EXPORT_SYMBOL_GPL(ath79_ahb_freq);
>> +
>> +u32 ath79_ddr_freq;
>> +EXPORT_SYMBOL_GPL(ath79_ddr_freq);
> 
> Why not use the Clock API with fixed rates just like how it is done for AR7?

Can you tell me the advantage of that? We can't modify the rates of these
clocks, even we can't {en,dis}able them. Implementing the clock API would add an
unnecessary wrapper layer around the current implementation in my opinion.

Regards,
Gabor

From kevink@paralogos.com Tue Jan  4 09:17:58 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 09:18:02 +0100 (CET)
Received: from gateway01.websitewelcome.com ([67.18.36.19]:41212 "HELO
        gateway01.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1491829Ab1ADIR5 (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 09:17:57 +0100
Received: (qmail 2194 invoked from network); 4 Jan 2011 08:17:30 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway01.websitewelcome.com with SMTP; 4 Jan 2011 08:17:30 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=bmxt2GKtBeHdYE34gWPSp0l14YeNH2KvixNAGm4p1E+uXSEzjR34luG3cCVbATFa1UziqbiWN5kVq5UvqPU6zp9VWtKkXWBaZnQyJV3WkBbnoHD2sk9Zprrx1xu6C8nU;
Received: from c-98-207-157-135.hsd1.ca.comcast.net ([98.207.157.135]:2107 helo=[127.0.0.1])
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1Pa25Y-0006ZL-IR; Tue, 04 Jan 2011 02:17:52 -0600
Message-ID: <4D22D7B3.2050609@paralogos.com>
Date:   Tue, 04 Jan 2011 00:17:55 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Anoop P A <anoop.pa@gmail.com>
CC:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Subject: Re: SMTC support status in latest git head.
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>         <1293470392.27661.202.camel@paanoop1-desktop>         <1293524389.27661.210.camel@paanoop1-desktop>         <4D19A31E.1090905@paralogos.com>         <1293798476.27661.279.camel@paanoop1-desktop>         <4D1EE913.1070203@paralogos.com>         <1294067561.27661.293.camel@paanoop1-desktop>         <4D21F5D3.50604@paralogos.com> <1294082426.27661.330.camel@paanoop1-desktop>
In-Reply-To: <1294082426.27661.330.camel@paanoop1-desktop>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28815
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

Those interrupt counters show that IPIs are being taken everywhere,
though very few by CPUs 5 and 6.  If I understand the configuration
correctly, CPU 4 is a TC in VPE 1, and it's getting a reasonable IPI
rate, *if* we're looking at a tickless kernel under low load.  But there
may be a clue there to part of your problem.  I have no idea why the
behavior would have changed from 2.6.36 to 2.6.37, but it looks as if
you're getting your clock interrupts through the MSP CIC interrupt
controller on VPE 0.  There's nothing symmetric for VPE1. The Malta
example code is perhaps deceptively simple, in that both VPEs have their
count/compare indication wired directly to the 2 clock interrupt inputs,
so that having both of them running with only a single set of irq state
just works.  I don't know whether the MSP CIC timer interrupt is a
gating of the VPE0 count/compare output, or whether it's it's own
interval timer, but I suspect that you may need to do some further
low-level initialization in the platform-specific code to set up an
interrupt on the VPE1 side.  I don't think the snippet you've got below
would work as written.

If it's purely an issue with clock distribution on VPE1, then a boot
with maxvpes=1 maxtcs=4 should be stable.

/K.

On 1/3/2011 11:20 AM, Anoop P A wrote:
> Hi Kevin,
>
> On Mon, 2011-01-03 at 08:14 -0800, Kevin D. Kissell wrote:
>> The very first SMTC implementations didn't support full kernel-mode
>> preemption, which anyway wasn't a priority, given the hardware event
>> response support in MIPS MT.  I believe it was later made compatible,
>> but it was never extensively exercised.  Since SMTC has fingers in some
>> pretty low-level atomicity mechanisms, if a new, parallel set was
>> implemented for RCU, I can easily imagine that nobody has yet
>> implemented SMTC-ified variants of that set.
>>
>> Your last statement isn't very clear, though.  Are you saying that if
>> you configure for no forced preemption and with TREE_CPU, the 2.6.37
>> kernel boots all the way up, or that it simply hangs later?   What's the
>> last rev kernel that actually boots all the way up?
> I have debugged this a bit more. It seems that kernel getting stalled
> while executing on TC's of second VPE . 
> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> by 1, t=2504 jiffies)
> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> by 1, t=10036 jiffies)
> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> by 1, t=17568 jiffies)
> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> by 1, t=25100 jiffies)
> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> by 1, t=32632 jiffies)
> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> by 1, t=40164 jiffies)
>
> With CONFIG_TREE_CPU we were not hitting this scenario very often.
> However with CONFIG_PREEMPT_TREE_CPU stall happens most of the time.
>
> I presume some issue in my timer setup . I am not seeing timer interrupt
> (or IPI interrupt) getting  incremented for VPE1 tcs on a completely
> booted 2.6.32-stable kernel.
>
> / # cat /proc/interrupts
>            CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
> CPU6
>   1:        148      15023      15140      15093       3779          8
> 2            MIPS  SMTC_IPI
>   6:          0          0          0          0          0          0
> 0            MIPS  MSP CIC cascade
>   8:          0          0          0          0          0          0
> 0         MSP_CIC  Softreset button
>   9:          0          0          0          0          0          0
> 0         MSP_CIC  Standby switch
>  21:          0          0          0          0          0          0
> 0         MSP_CIC  MSP PER cascade
>  25:      15113        341          4          7          0          0
> 0         MSP_CIC  timer
>  27:        260          9          0          1          0          0
> 0         MSP_CIC  serial
>  34:          0          0          0          0          0          0
> 0         MSP_CIC  timer
>
> Can't we use separate timer interrupts for VPE1 and VPE0 in SMTC ?. 
>
> I have tried setting up VPE1 timer from get_co_compare_int as follows
>
> unsigned int __cpuinit get_c0_compare_int(void)
> {
> 	if ((1==get_current_vpe()) && !vpe1_timr_installed){
> 	
> 	memcpy(&timer_vpe1,&c0_compare_irqaction,sizeof(timer_vpe1));
> 	
> 	setup_irq(MSP_INT_VPE1_TIMER, &timer_vpe1);
>                   vpe1_timr_installed++;
>           }
>           return (get_current_vpe() ? MSP_INT_VPE1_TIMER :
> MSP_INT_VPE0_TIMER);
> }
>
> Thanks
> Anoop
>
>>             Regards,
>>
>>             Kevin K.
>>
>> On 1/3/2011 7:12 AM, Anoop P A wrote:
>>> Hi ,
>>>
>>> Following patch restricts TREE_CPU RCU implementation only for !PREEMPT
>>> SMP kernel.  
>>> http://git.linux-mips.org/?p=linux.git;a=commit;h=687d7a960aea46e016182c7ce346d62c4dbd0366
>>>
>>> CONFIG_TREE_PREEMPT_RCU option seems to be not working for SMTC kernel
>>> ( which will be only available RCU implementation for SMTC kernel from
>>> 2.6.37 onwards) .
>>>
>>> With no forced preemption and selecting TREE_CPU I am able to boot
>>> further to the hang that I have reported.
>>>
>>> Thanks
>>> Anoop
>>>
>>> On Sat, 2011-01-01 at 00:42 -0800, Kevin D. Kissell wrote:
>>>> At this point the logical thing to do would seem to look at your kernel
>>>> image and disassemble smtc_ipi_replay(), which is where the EPC of VPE 0
>>>> shows the last exception to have been taken.  That's a critical SMTC
>>>> routine that gets called whenever an xxx_irq_restore() enables
>>>> interrupts, so that virtual per-TC IPI interrupts that were posted while
>>>> the TC had interrupts disabled can be handled deterministically.  As I
>>>> mentioned in an earlier message, there was some cleanup work from David
>>>> Howell that changed a number of irq management-related function names
>>>> and prototypes across all architectures, which went into linux-mips.org
>>>> at very roughly the time of the breakage.  The SMTC overlay over the irq
>>>> implementation has been pretty robust, but it's written in a perhaps
>>>> doomed attempt to be both efficient and using a maximum amount of common
>>>> code with the general case.  A mechanical or semi-mechanical change
>>>> could conceivably have broken things.
>>>>
>>>>             Regards,
>>>>
>>>>             Kevin K.
>>>>
>>>>
>>>> On 12/31/2010 4:27 AM, Anoop P A wrote:
>>>>> Hi ,
>>>>>
>>>>> Kernel hangs on stop_machine call. Please find mt reg dump below.
>>>>> Another important observation is even though 2.6.33 kernel + stackframe
>>>>> patch well passes calibration hang , I am still unable boot in to a
>>>>> initramfs root ( verified ramfs working with VSMP). So it looks like
>>>>> still some issue to fix between 2.6.32 and 2.6.33 .
>>>>> ######################## Log ###########################
>>>>>
>>>>> === MIPS MT State Dump ===
>>>>> -- Global State --
>>>>>    MVPControl Passed: 00000005
>>>>>    MVPControl Read: 00000004
>>>>>    MVPConf0 : a8008406
>>>>> -- per-VPE State --
>>>>>   VPE 0
>>>>>    VPEControl : 00008000
>>>>>    VPEConf0 : 800f0003
>>>>>    VPE0.Status : 11004201
>>>>>    VPE0.EPC : 8010dc54 smtc_ipi_replay+0xcc/0x108
>>>>>    VPE0.Cause : 50804000
>>>>>    VPE0.Config7 : 00010000
>>>>>   VPE 1
>>>>>    VPEControl : 00068006
>>>>>    VPEConf0 : 80cf0003
>>>>>    VPE1.Status : 11008301
>>>>>    VPE1.EPC : 801022a0 r4k_wait+0x20/0x40
>>>>>    VPE1.Cause : 50800000
>>>>>    VPE1.Config7 : 00010000
>>>>> -- per-TC State --
>>>>>   TC 0 (current TC with VPE EPC above)
>>>>>    TCStatus : 18102000
>>>>>    TCBind : 00000000
>>>>>    TCRestart : 803fa19c printk+0xc/0x30
>>>>>    TCHalt : 00000000
>>>>>    TCContext : 00000000
>>>>>   TC 1
>>>>>    TCStatus : 18902000
>>>>>    TCBind : 00200000
>>>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
>>>>>    TCHalt : 00000000
>>>>>    TCContext : 00140000
>>>>>   TC 2
>>>>>    TCStatus : 18902000
>>>>>    TCBind : 00400000
>>>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
>>>>>    TCHalt : 00000000
>>>>>    TCContext : 00280000
>>>>>   TC 3
>>>>>    TCStatus : 18902000
>>>>>    TCBind : 00600000
>>>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
>>>>>    TCHalt : 00000000
>>>>>    TCContext : 003c0000
>>>>>   TC 4
>>>>>    TCStatus : 18902000
>>>>>    TCBind : 00800001
>>>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
>>>>>    TCHalt : 00000000
>>>>>    TCContext : 00500000
>>>>>   TC 5
>>>>>    TCStatus : 18902000
>>>>>    TCBind : 00a00001
>>>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
>>>>>    TCHalt : 00000000
>>>>>    TCContext : 00640000
>>>>>   TC 6
>>>>>    TCStatus : 18902000
>>>>>    TCBind : 00c00001
>>>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
>>>>>    TCHalt : 00000000
>>>>>    TCContext : 00780000
>>>>> Counter Interrupts taken per CPU (TC)
>>>>> 0: 0
>>>>> 1: 0
>>>>> 2: 0
>>>>> 3: 0
>>>>> 4: 0
>>>>> 5: 0
>>>>> 6: 0
>>>>> 7: 0
>>>>> Self-IPI invocations:
>>>>> 0: 12
>>>>> 1: 0
>>>>> 2: 0
>>>>> 3: 0
>>>>> 4: 0
>>>>> 5: 5
>>>>> 6: 4
>>>>> 7: 0
>>>>> IPIQ[0]: head = 0x0, tail = 0x0, depth = 0
>>>>> IPIQ[1]: head = 0x0, tail = 0x0, depth = 0
>>>>> IPIQ[2]: head = 0x0, tail = 0x0, depth = 0
>>>>> IPIQ[3]: head = 0x0, tail = 0x0, depth = 0
>>>>> IPIQ[4]: head = 0x0, tail = 0x0, depth = 0
>>>>> IPIQ[5]: head = 0x0, tail = 0x0, depth = 0
>>>>> IPIQ[6]: head = 0x0, tail = 0x0, depth = 0
>>>>> IPIQ[7]: head = 0x0, tail = 0x0, depth = 0
>>>>> 0 Recoveries of "stolen" FPU
>>>>> ===========================
>>>>>
>>>>> ################################################################
>>>>>
>>>>> Thanks
>>>>> Anoop
>>>>>
>>>>> On Tue, 2010-12-28 at 00:43 -0800, Kevin D. Kissell wrote:
>>>>>> I took a quick look last night, and the only thing that looked vaguely 
>>>>>> dangerous in changes since the timer changes I alluded to earlier was 
>>>>>> the global naming cleanup of irq-related function names that David 
>>>>>> Howell submitted.  The diff didn't look dangerous in itself, but some of 
>>>>>> the definitions are nested subtly for SMTC to maximize the amount of 
>>>>>> common code, and I could imagine something getting lost in translation 
>>>>>> there.  If that were really the problem, it would of course affect much 
>>>>>> more than just the timer subsystem, but early in the boot process, 
>>>>>> timers are pretty much the only interrupts that have to be handled 
>>>>>> correctly.
>>>>>>
>>>>>> I'm travelling today, but will take a look at timekeeping_notify() 
>>>>>> tomorrow or the next day...
>>>>>>
>>>>>> /K.
>>>>>>
>>>>>> On 12/28/10 12:19 AM, Anoop P A wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> I had a glance into the code diff without notice of any suspect-able
>>>>>>> code .
>>>>>>> Tracing the hang showed that it is getting hanged in timekeeping_notify
>>>>>>> function.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Anoop
>>>>>>>
>>>>>>> PS: I may not be available until Thursday
>>>>>>>
>>>>>>> On Mon, 2010-12-27 at 22:49 +0530, Anoop P A wrote:
>>>>>>>> Hi Kevin,
>>>>>>>>
>>>>>>>> It is very unlikely that the patch you pointed has any impact on the the
>>>>>>>> hang I am seeing. The patch you have mentioned got into kernel around
>>>>>>>> 2.6.32 timeframe. I am able to boot both 2.6.32 and  2.6.33 kernel ( +
>>>>>>>> stackframe patch) .
>>>>>>>>
>>>>>>>> Hi Stuart,
>>>>>>>>
>>>>>>>> I haven't got much time to spend on this today.
>>>>>>>>
>>>>>>>> I had got 2.6.36-stable(+ stack frame patch) booting last day and I have
>>>>>>>> observed hang issue with 2.6.37-rc1 ( Same as rc6 and current git head)
>>>>>>>>
>>>>>>>> So probably some patches in 2.6.37 branch introduced this hang.
>>>>>>>>
>>>>>>>> Hopefully I will get some free slot tomorrow so that I can look into
>>>>>>>> code diff .
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>> Anoop
>>>>>>>>
>>>>>>>> On Mon, 2010-12-27 at 09:49 -0600, STUART VENTERS wrote:
>>>>>>>>> Kevin,
>>>>>>>>>
>>>>>>>>> Outstanding, sometimes it's better to be lucky than good.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Anoop,
>>>>>>>>>
>>>>>>>>> Maybe we can get lucky again.
>>>>>>>>>
>>>>>>>>> If you can isolate the .33 works/.37 works_not bug to a specific pair of versions,
>>>>>>>>>     I'll be happy to do another diff.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Hope you'll have had a good Christmas as well.
>>>>>>>>>    We've had snow in Alabama since Christmas eve!
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Regards,
>>>>>>>>>
>>>>>>>>> Stuart
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> -----Original Message-----
>>>>>>>>> From: Kevin D. Kissell [mailto:kevink@paralogos.com]
>>>>>>>>> Sent: Friday, December 24, 2010 5:34 PM
>>>>>>>>> To: Anoop P A
>>>>>>>>> Cc: STUART VENTERS; Anoop P.A.; linux-mips@linux-mips.org
>>>>>>>>> Subject: Re: SMTC support status in latest git head.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Ah, well, at least we have a stackframe.h fix that preserves David's
>>>>>>>>> performance tweak for the deeper pipelined processors.  In looking for
>>>>>>>>> this, I did notice that someone did some modification to the SMTC clock
>>>>>>>>> tick logic that I was skeptical had ever been tested.  If you've still
>>>>>>>>> got that kernel binary handy, you might check to see if it boots with
>>>>>>>>> maxtcs=1 maxvpes=1, maxtcs=2 maxvpes=1, and/or maxtcs=2 maxvpes=2.
>>>>>>>>>
>>>>>>>>> Oh, yes, and Merry Christmas one and all!
>>>>>>>>>
>>>>>>>>>               Regards,
>>>>>>>>>
>>>>>>>>>               Kevin K.
>>>>>>>>>
>>>>>>>>> On 12/24/10 8:02 AM, Anoop P A wrote:
>>>>>>>>>> On Fri, 2010-12-24 at 06:53 -0800, Kevin D. Kissell wrote:
>>>>>>>>>>> Excellent!  Now, does the attached patch (relative to 2.6.37.11) also
>>>>>>>>>>> fix things, while preserving the other fixes and performance enhancements?
>>>>>>>>>>>
>>>>>>>>>> I have tested that patch with 2.6.37 branch it well passes calibration
>>>>>>>>>> loop but hangs after switching to mips closource
>>>>>>>>>>
>>>>>>>>>> TC 6 going on-line as CPU 6
>>>>>>>>>> Brought up 7 CPUs
>>>>>>>>>> bio: create slab<bio-0>   at 0
>>>>>>>>>> SCSI subsystem initialized
>>>>>>>>>> Switching to clocksource MIPS
>>>>>>>>>>
>>>>>>>>>> I Presume this is a different issue as restoring older file didn't help
>>>>>>>>>> much to get rid of this hang.
>>>>>>>>>>
>>>>>>>>>> diff --git a/arch/mips/include/asm/stackframe.h
>>>>>>>>>> b/arch/mips/include/asm/stackframe.h
>>>>>>>>>> index 58730c5..7fc9f10 100644
>>>>>>>>>> --- a/arch/mips/include/asm/stackframe.h
>>>>>>>>>> +++ b/arch/mips/include/asm/stackframe.h
>>>>>>>>>> @@ -195,9 +195,9 @@
>>>>>>>>>>    		 * to cover the pipeline delay.
>>>>>>>>>>    		 */
>>>>>>>>>>    		.set	mips32
>>>>>>>>>> -		mfc0	v1, CP0_TCSTATUS
>>>>>>>>>> +		mfc0	v0, CP0_TCSTATUS
>>>>>>>>>>    		.set	mips0
>>>>>>>>>> -		LONG_S	v1, PT_TCSTATUS(sp)
>>>>>>>>>> +		LONG_S	v0, PT_TCSTATUS(sp)
>>>>>>>>>>    #endif /* CONFIG_MIPS_MT_SMTC */
>>>>>>>>>>    		LONG_S	$4, PT_R4(sp)
>>>>>>>>>>    		LONG_S	$5, PT_R5(sp)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> /K.
>>>>>>>>>>>
>>>>>>>>>>> On 12/24/10 6:39 AM, Anoop P A wrote:
>>>>>>>>>>>> Hi Kevin, Stuart ,
>>>>>>>>>>>>
>>>>>>>>>>>> Woohooo You guys spotted !.
>>>>>>>>>>>>
>>>>>>>>>>>>     http://git.linux-mips.org/?p=linux.git;a=commit;h=d5ec6e3c seems to be
>>>>>>>>>>>> the culprit
>>>>>>>>>>>>
>>>>>>>>>>>> Once I restored previous version of stackframe.h 2.6.33-stable started
>>>>>>>>>>>> booting !.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> Anoop
>>>>>>>>>>>>
>>>>>>>>>>>> On Fri, 2010-12-24 at 04:32 -0800, Kevin D. Kissell wrote:
>>>>>>>>>>>>> Thank you, Stuart!  I've spotted some definite breakage to SMTC between
>>>>>>>>>>>>> those versions.  In arch/mips/include/asm/stackframe.h, someone moved
>>>>>>>>>>>>> the store of the Status register value in SAVE_SOME (line 169 or 204,
>>>>>>>>>>>>> depending on the version) from two instructions after the mfc0 to a
>>>>>>>>>>>>> point after the #ifdef for SMTC, presumably to get better pipelining of
>>>>>>>>>>>>> the register access.  Unfortunately, the v1 register is also used in the
>>>>>>>>>>>>> SMTC-specific fragment to save TCStatus, so the Status value gets
>>>>>>>>>>>>> clobbered before it gets stored.  This will eventually result in the
>>>>>>>>>>>>> Status register getting a TCStatus value, which has some bits on common,
>>>>>>>>>>>>> but isn't identical and sooner or later Bad Things will happen.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I'm a little surprised this wasn't caught by visual inspection of the patch.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Possible solutions would include reverting the store of the CP0_STATUS
>>>>>>>>>>>>> value to the block above the #ifdef, or, to retain whatever performance
>>>>>>>>>>>>> advantage was obtained by moving the store downward, to use v0/$2
>>>>>>>>>>>>> instead of v1/$3, as the staging register for the TCStatus value.  I'd
>>>>>>>>>>>>> lean toward the second option, but I'm not in a position to test and
>>>>>>>>>>>>> submit a patch just now.
>>>>>>>>>>>>>
>>>>>>>>>>>>>                 Regards,
>>>>>>>>>>>>>
>>>>>>>>>>>>>                 Kevin K.
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 12/23/10 1:09 PM, STUART VENTERS wrote:
>>>>>>>>>>>>>> Kevin,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I'm not sure if it's useful,
>>>>>>>>>>>>>>        but finally I got the time to look at the two kernel versions Anoop pointed out.
>>>>>>>>>>>>>>         works   2.6.32-stable with patch 804
>>>>>>>>>>>>>>         works_not 2.6.33-stable
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> greping for files with CONFIG_MIPS_MT_SMTC
>>>>>>>>>>>>>>        and looking for timer interrupt related stuff found the following differences:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> arch/mips/include/asm/irq.h
>>>>>>>>>>>>>> arch/mips/kernel/irq.c
>>>>>>>>>>>>>>       do_IRQ
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> arch/mips/include/asm/stackframe.h
>>>>>>>>>>>>>>       SAVE_SOME SAVE_TEMP get/set_saved_sp
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> arch/mips/include/asm/time.h
>>>>>>>>>>>>>>       clocksource_set_clock
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> arch/mips/kernel/process.c
>>>>>>>>>>>>>>       cpu_idle
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> arch/mips/kernel/smtc.c
>>>>>>>>>>>>>>       __irq_entry
>>>>>>>>>>>>>>       ipi_decode
>>>>>>>>>>>>>>           SMTC_CLOCK_TICK
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Enclosed are the two subsets of files for a more expert look.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I'll try to look in more detail after Christmas.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Stuart
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>


From Jaiganesh.Narayanan@Atheros.com Tue Jan  4 12:00:40 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 12:00:42 +0100 (CET)
Received: from mail.atheros.com ([12.19.149.2]:31001 "EHLO mail.atheros.com"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1492043Ab1ADLAj convert rfc822-to-8bit (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 12:00:39 +0100
Received: from mail.atheros.com ([10.10.20.108])
        by sidewinder.atheros.com
        for <linux-mips@linux-mips.org>; Tue, 04 Jan 2011 03:00:22 -0800
Received: from CHEXHC-01.global.atheros.com (10.12.0.100) by
 SC1EXHC-02.global.atheros.com (10.10.20.108) with Microsoft SMTP Server (TLS)
 id 8.2.213.0; Tue, 4 Jan 2011 03:00:25 -0800
Received: from CHEXMB-01.global.atheros.com ([192.168.0.2]) by
 CHEXHC-01.global.atheros.com ([10.12.0.100]) with mapi; Tue, 4 Jan 2011
 16:30:21 +0530
From:   Jaiganesh Narayanan <Jaiganesh.Narayanan@Atheros.com>
To:     "linux-mips@linux-mips.org" <linux-mips@linux-mips.org>
Date:   Tue, 4 Jan 2011 16:30:22 +0530
Subject: linux mips gcov
Thread-Topic: linux mips gcov
Thread-Index: Acur/pWJVCgcy45XRBe6o5SRr7x7FA==
Message-ID: <44EE5C37ADC36343B0625A05DD408C4850DC51E642@CHEXMB-01.global.atheros.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
acceptlanguage: en-US
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 8BIT
MIME-Version: 1.0
Return-Path: <Jaiganesh.Narayanan@Atheros.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: 28816
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: Jaiganesh.Narayanan@Atheros.com
Precedence: bulk
X-list: linux-mips

Hello,

Is it possible to use the GCOV framework in the linux 2.6.31+
kernel to get the code coverage for linux kernel/drivers on mips 
target ? If yes, is there any mips specific steps (or) documentation 
for the code coverage apart from Documentation/gcov.txt ?

TIA,
Jaiganesh.




From anoop.pa@gmail.com Tue Jan  4 13:51:44 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 13:51:48 +0100 (CET)
Received: from mail-yi0-f49.google.com ([209.85.218.49]:47567 "EHLO
        mail-yi0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1492064Ab1ADMvo (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 13:51:44 +0100
Received: by yib2 with SMTP id 2so3637188yib.36
        for <linux-mips@linux-mips.org>; Tue, 04 Jan 2011 04:51:38 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:subject:from:to:cc
         :in-reply-to:references:content-type:date:message-id:mime-version
         :x-mailer:content-transfer-encoding;
        bh=i6LcI+hLZu/29S1rxOj3hmNOe08Vcy3fBGFrc8BAj6k=;
        b=v8OBj9S/xb90xY7IgX4sAe0NW1ltRkzp7WZQ4GX1ni7o+OVBE9yVKYhgOuQbWYZ9BS
         ogZK4Qi2fAvJAu2DIt4hTivbzq1Q1Ss4JAsn9EO6N7zQAMwtcakN7i/27hX+9a0aywRb
         ouAfAb0kSf7zGvs+2ibDYOFawwKaJ+Sfi/ago=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=subject:from:to:cc:in-reply-to:references:content-type:date
         :message-id:mime-version:x-mailer:content-transfer-encoding;
        b=etn5Gi+dI4v9fAR8ap+ycsXZMzx79vR05Qb70gg7LsVjO8pFPawb3TQ6fH4nWJ/pLh
         TERSBCwN60j3xKUp1FKyF2TyB+n8B7Jwse+0cG1Ds27/U3HtHYYIAdb1guN6MONzxWgm
         KxB3nTqxGBN/As74Ct85+gYYZvg4Eovoo2lGw=
Received: by 10.236.95.140 with SMTP id p12mr7774185yhf.24.1294145497940;
        Tue, 04 Jan 2011 04:51:37 -0800 (PST)
Received: from [172.16.48.51] ([59.160.135.215])
        by mx.google.com with ESMTPS id h48sm1791946yha.21.2011.01.04.04.51.33
        (version=SSLv3 cipher=RC4-MD5);
        Tue, 04 Jan 2011 04:51:36 -0800 (PST)
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
In-Reply-To: <4D22D7B3.2050609@paralogos.com>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
         <1293470392.27661.202.camel@paanoop1-desktop>
         <1293524389.27661.210.camel@paanoop1-desktop>
         <4D19A31E.1090905@paralogos.com>
         <1293798476.27661.279.camel@paanoop1-desktop>
         <4D1EE913.1070203@paralogos.com>
         <1294067561.27661.293.camel@paanoop1-desktop>
         <4D21F5D3.50604@paralogos.com>
         <1294082426.27661.330.camel@paanoop1-desktop>
         <4D22D7B3.2050609@paralogos.com>
Content-Type: text/plain; charset="UTF-8"
Date:   Tue, 04 Jan 2011 18:32:45 +0530
Message-ID: <1294146165.27661.361.camel@paanoop1-desktop>
Mime-Version: 1.0
X-Mailer: Evolution 2.28.3 
Content-Transfer-Encoding: 7bit
Return-Path: <anoop.pa@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: 28817
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips

On Tue, 2011-01-04 at 00:17 -0800, Kevin D. Kissell wrote:
> Those interrupt counters show that IPIs are being taken everywhere,
> though very few by CPUs 5 and 6.  If I understand the configuration
> correctly, CPU 4 is a TC in VPE 1, and it's getting a reasonable IPI
Yes CPU4 is in second VPE

> rate, *if* we're looking at a tickless kernel under low load.  But there
No it was not the tickless kernel.I had selected 250 MHz timer. can't we
expect IPI / timer interrupt for all the threads in this case ?.

> may be a clue there to part of your problem.  I have no idea why the
> behavior would have changed from 2.6.36 to 2.6.37, but it looks as if
> you're getting your clock interrupts through the MSP CIC interrupt
> controller on VPE 0.  There's nothing symmetric for VPE1. The Malta
> example code is perhaps deceptively simple, in that both VPEs have their
> count/compare indication wired directly to the 2 clock interrupt inputs,
> so that having both of them running with only a single set of irq state
> just works.  I don't know whether the MSP CIC timer interrupt is a

In my case it is separate irq. MSP_INT_VPE1_TIMER (34) and  
MSP_INT_VPE0_TIMER (25) are wired to CIC . CIC interrupt has been
connected to cpu irq 6. 

I can reproduce cpu stall in VSMP mode If I don't setup VPE1 timer
interrupt . Don't we have support for separate irq in SMTC
implementation ?..

> gating of the VPE0 count/compare output, or whether it's it's own
> interval timer, but I suspect that you may need to do some further
> low-level initialization in the platform-specific code to set up an
> interrupt on the VPE1 side.  I don't think the snippet you've got below
> would work as written.

The routine which I copied works fine for VSMP mode . 

/ # cat /proc/interrupts
           CPU0       CPU1
  0:        187        254            MIPS  IPI_resched
  1:         77        174            MIPS  IPI_call
  6:          0          0            MIPS  MSP CIC cascade
  8:          0          0         MSP_CIC  Softreset button
  9:          0          0         MSP_CIC  Standby switch
 21:          0          0         MSP_CIC  MSP PER cascade
 25:      37077          0         MSP_CIC  timer
 27:        188          0         MSP_CIC  serial
 34:          0      36986         MSP_CIC  timer

Do I want to change anything specific for SMTC ? .  

> 
> If it's purely an issue with clock distribution on VPE1, then a boot
> with maxvpes=1 maxtcs=4 should be stable.

Yes the kernel seems to be stable if I boot with maxvpes=1 maxtcs=4 .

> 
> /K.
> 
> On 1/3/2011 11:20 AM, Anoop P A wrote:
> > Hi Kevin,
> >
> > On Mon, 2011-01-03 at 08:14 -0800, Kevin D. Kissell wrote:
> >> The very first SMTC implementations didn't support full kernel-mode
> >> preemption, which anyway wasn't a priority, given the hardware event
> >> response support in MIPS MT.  I believe it was later made compatible,
> >> but it was never extensively exercised.  Since SMTC has fingers in some
> >> pretty low-level atomicity mechanisms, if a new, parallel set was
> >> implemented for RCU, I can easily imagine that nobody has yet
> >> implemented SMTC-ified variants of that set.
> >>
> >> Your last statement isn't very clear, though.  Are you saying that if
> >> you configure for no forced preemption and with TREE_CPU, the 2.6.37
> >> kernel boots all the way up, or that it simply hangs later?   What's the
> >> last rev kernel that actually boots all the way up?
> > I have debugged this a bit more. It seems that kernel getting stalled
> > while executing on TC's of second VPE . 
> > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > by 1, t=2504 jiffies)
> > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > by 1, t=10036 jiffies)
> > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > by 1, t=17568 jiffies)
> > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > by 1, t=25100 jiffies)
> > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > by 1, t=32632 jiffies)
> > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > by 1, t=40164 jiffies)
> >
> > With CONFIG_TREE_CPU we were not hitting this scenario very often.
> > However with CONFIG_PREEMPT_TREE_CPU stall happens most of the time.
> >
> > I presume some issue in my timer setup . I am not seeing timer interrupt
> > (or IPI interrupt) getting  incremented for VPE1 tcs on a completely
> > booted 2.6.32-stable kernel.
> >
> > / # cat /proc/interrupts
> >            CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
> > CPU6
> >   1:        148      15023      15140      15093       3779          8
> > 2            MIPS  SMTC_IPI
> >   6:          0          0          0          0          0          0
> > 0            MIPS  MSP CIC cascade
> >   8:          0          0          0          0          0          0
> > 0         MSP_CIC  Softreset button
> >   9:          0          0          0          0          0          0
> > 0         MSP_CIC  Standby switch
> >  21:          0          0          0          0          0          0
> > 0         MSP_CIC  MSP PER cascade
> >  25:      15113        341          4          7          0          0
> > 0         MSP_CIC  timer
> >  27:        260          9          0          1          0          0
> > 0         MSP_CIC  serial
> >  34:          0          0          0          0          0          0
> > 0         MSP_CIC  timer
> >
> > Can't we use separate timer interrupts for VPE1 and VPE0 in SMTC ?. 
> >
> > I have tried setting up VPE1 timer from get_co_compare_int as follows
> >
> > unsigned int __cpuinit get_c0_compare_int(void)
> > {
> > 	if ((1==get_current_vpe()) && !vpe1_timr_installed){
> > 	
> > 	memcpy(&timer_vpe1,&c0_compare_irqaction,sizeof(timer_vpe1));
> > 	
> > 	setup_irq(MSP_INT_VPE1_TIMER, &timer_vpe1);
> >                   vpe1_timr_installed++;
> >           }
> >           return (get_current_vpe() ? MSP_INT_VPE1_TIMER :
> > MSP_INT_VPE0_TIMER);
> > }
> >
> > Thanks
> > Anoop
> >
> >>             Regards,
> >>
> >>             Kevin K.
> >>
> >> On 1/3/2011 7:12 AM, Anoop P A wrote:
> >>> Hi ,
> >>>
> >>> Following patch restricts TREE_CPU RCU implementation only for !PREEMPT
> >>> SMP kernel.  
> >>> http://git.linux-mips.org/?p=linux.git;a=commit;h=687d7a960aea46e016182c7ce346d62c4dbd0366
> >>>
> >>> CONFIG_TREE_PREEMPT_RCU option seems to be not working for SMTC kernel
> >>> ( which will be only available RCU implementation for SMTC kernel from
> >>> 2.6.37 onwards) .
> >>>
> >>> With no forced preemption and selecting TREE_CPU I am able to boot
> >>> further to the hang that I have reported.
> >>>
> >>> Thanks
> >>> Anoop
> >>>
> >>> On Sat, 2011-01-01 at 00:42 -0800, Kevin D. Kissell wrote:
> >>>> At this point the logical thing to do would seem to look at your kernel
> >>>> image and disassemble smtc_ipi_replay(), which is where the EPC of VPE 0
> >>>> shows the last exception to have been taken.  That's a critical SMTC
> >>>> routine that gets called whenever an xxx_irq_restore() enables
> >>>> interrupts, so that virtual per-TC IPI interrupts that were posted while
> >>>> the TC had interrupts disabled can be handled deterministically.  As I
> >>>> mentioned in an earlier message, there was some cleanup work from David
> >>>> Howell that changed a number of irq management-related function names
> >>>> and prototypes across all architectures, which went into linux-mips.org
> >>>> at very roughly the time of the breakage.  The SMTC overlay over the irq
> >>>> implementation has been pretty robust, but it's written in a perhaps
> >>>> doomed attempt to be both efficient and using a maximum amount of common
> >>>> code with the general case.  A mechanical or semi-mechanical change
> >>>> could conceivably have broken things.
> >>>>
> >>>>             Regards,
> >>>>
> >>>>             Kevin K.
> >>>>
> >>>>
> >>>> On 12/31/2010 4:27 AM, Anoop P A wrote:
> >>>>> Hi ,
> >>>>>
> >>>>> Kernel hangs on stop_machine call. Please find mt reg dump below.
> >>>>> Another important observation is even though 2.6.33 kernel + stackframe
> >>>>> patch well passes calibration hang , I am still unable boot in to a
> >>>>> initramfs root ( verified ramfs working with VSMP). So it looks like
> >>>>> still some issue to fix between 2.6.32 and 2.6.33 .
> >>>>> ######################## Log ###########################
> >>>>>
> >>>>> === MIPS MT State Dump ===
> >>>>> -- Global State --
> >>>>>    MVPControl Passed: 00000005
> >>>>>    MVPControl Read: 00000004
> >>>>>    MVPConf0 : a8008406
> >>>>> -- per-VPE State --
> >>>>>   VPE 0
> >>>>>    VPEControl : 00008000
> >>>>>    VPEConf0 : 800f0003
> >>>>>    VPE0.Status : 11004201
> >>>>>    VPE0.EPC : 8010dc54 smtc_ipi_replay+0xcc/0x108
> >>>>>    VPE0.Cause : 50804000
> >>>>>    VPE0.Config7 : 00010000
> >>>>>   VPE 1
> >>>>>    VPEControl : 00068006
> >>>>>    VPEConf0 : 80cf0003
> >>>>>    VPE1.Status : 11008301
> >>>>>    VPE1.EPC : 801022a0 r4k_wait+0x20/0x40
> >>>>>    VPE1.Cause : 50800000
> >>>>>    VPE1.Config7 : 00010000
> >>>>> -- per-TC State --
> >>>>>   TC 0 (current TC with VPE EPC above)
> >>>>>    TCStatus : 18102000
> >>>>>    TCBind : 00000000
> >>>>>    TCRestart : 803fa19c printk+0xc/0x30
> >>>>>    TCHalt : 00000000
> >>>>>    TCContext : 00000000
> >>>>>   TC 1
> >>>>>    TCStatus : 18902000
> >>>>>    TCBind : 00200000
> >>>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
> >>>>>    TCHalt : 00000000
> >>>>>    TCContext : 00140000
> >>>>>   TC 2
> >>>>>    TCStatus : 18902000
> >>>>>    TCBind : 00400000
> >>>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
> >>>>>    TCHalt : 00000000
> >>>>>    TCContext : 00280000
> >>>>>   TC 3
> >>>>>    TCStatus : 18902000
> >>>>>    TCBind : 00600000
> >>>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
> >>>>>    TCHalt : 00000000
> >>>>>    TCContext : 003c0000
> >>>>>   TC 4
> >>>>>    TCStatus : 18902000
> >>>>>    TCBind : 00800001
> >>>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
> >>>>>    TCHalt : 00000000
> >>>>>    TCContext : 00500000
> >>>>>   TC 5
> >>>>>    TCStatus : 18902000
> >>>>>    TCBind : 00a00001
> >>>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
> >>>>>    TCHalt : 00000000
> >>>>>    TCContext : 00640000
> >>>>>   TC 6
> >>>>>    TCStatus : 18902000
> >>>>>    TCBind : 00c00001
> >>>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
> >>>>>    TCHalt : 00000000
> >>>>>    TCContext : 00780000
> >>>>> Counter Interrupts taken per CPU (TC)
> >>>>> 0: 0
> >>>>> 1: 0
> >>>>> 2: 0
> >>>>> 3: 0
> >>>>> 4: 0
> >>>>> 5: 0
> >>>>> 6: 0
> >>>>> 7: 0
> >>>>> Self-IPI invocations:
> >>>>> 0: 12
> >>>>> 1: 0
> >>>>> 2: 0
> >>>>> 3: 0
> >>>>> 4: 0
> >>>>> 5: 5
> >>>>> 6: 4
> >>>>> 7: 0
> >>>>> IPIQ[0]: head = 0x0, tail = 0x0, depth = 0
> >>>>> IPIQ[1]: head = 0x0, tail = 0x0, depth = 0
> >>>>> IPIQ[2]: head = 0x0, tail = 0x0, depth = 0
> >>>>> IPIQ[3]: head = 0x0, tail = 0x0, depth = 0
> >>>>> IPIQ[4]: head = 0x0, tail = 0x0, depth = 0
> >>>>> IPIQ[5]: head = 0x0, tail = 0x0, depth = 0
> >>>>> IPIQ[6]: head = 0x0, tail = 0x0, depth = 0
> >>>>> IPIQ[7]: head = 0x0, tail = 0x0, depth = 0
> >>>>> 0 Recoveries of "stolen" FPU
> >>>>> ===========================
> >>>>>
> >>>>> ################################################################
> >>>>>
> >>>>> Thanks
> >>>>> Anoop
> >>>>>
> >>>>> On Tue, 2010-12-28 at 00:43 -0800, Kevin D. Kissell wrote:
> >>>>>> I took a quick look last night, and the only thing that looked vaguely 
> >>>>>> dangerous in changes since the timer changes I alluded to earlier was 
> >>>>>> the global naming cleanup of irq-related function names that David 
> >>>>>> Howell submitted.  The diff didn't look dangerous in itself, but some of 
> >>>>>> the definitions are nested subtly for SMTC to maximize the amount of 
> >>>>>> common code, and I could imagine something getting lost in translation 
> >>>>>> there.  If that were really the problem, it would of course affect much 
> >>>>>> more than just the timer subsystem, but early in the boot process, 
> >>>>>> timers are pretty much the only interrupts that have to be handled 
> >>>>>> correctly.
> >>>>>>
> >>>>>> I'm travelling today, but will take a look at timekeeping_notify() 
> >>>>>> tomorrow or the next day...
> >>>>>>
> >>>>>> /K.
> >>>>>>
> >>>>>> On 12/28/10 12:19 AM, Anoop P A wrote:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> I had a glance into the code diff without notice of any suspect-able
> >>>>>>> code .
> >>>>>>> Tracing the hang showed that it is getting hanged in timekeeping_notify
> >>>>>>> function.
> >>>>>>>
> >>>>>>> Thanks,
> >>>>>>> Anoop
> >>>>>>>
> >>>>>>> PS: I may not be available until Thursday
> >>>>>>>
> >>>>>>> On Mon, 2010-12-27 at 22:49 +0530, Anoop P A wrote:
> >>>>>>>> Hi Kevin,
> >>>>>>>>
> >>>>>>>> It is very unlikely that the patch you pointed has any impact on the the
> >>>>>>>> hang I am seeing. The patch you have mentioned got into kernel around
> >>>>>>>> 2.6.32 timeframe. I am able to boot both 2.6.32 and  2.6.33 kernel ( +
> >>>>>>>> stackframe patch) .
> >>>>>>>>
> >>>>>>>> Hi Stuart,
> >>>>>>>>
> >>>>>>>> I haven't got much time to spend on this today.
> >>>>>>>>
> >>>>>>>> I had got 2.6.36-stable(+ stack frame patch) booting last day and I have
> >>>>>>>> observed hang issue with 2.6.37-rc1 ( Same as rc6 and current git head)
> >>>>>>>>
> >>>>>>>> So probably some patches in 2.6.37 branch introduced this hang.
> >>>>>>>>
> >>>>>>>> Hopefully I will get some free slot tomorrow so that I can look into
> >>>>>>>> code diff .
> >>>>>>>>
> >>>>>>>> Thanks
> >>>>>>>> Anoop
> >>>>>>>>
> >>>>>>>> On Mon, 2010-12-27 at 09:49 -0600, STUART VENTERS wrote:
> >>>>>>>>> Kevin,
> >>>>>>>>>
> >>>>>>>>> Outstanding, sometimes it's better to be lucky than good.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Anoop,
> >>>>>>>>>
> >>>>>>>>> Maybe we can get lucky again.
> >>>>>>>>>
> >>>>>>>>> If you can isolate the .33 works/.37 works_not bug to a specific pair of versions,
> >>>>>>>>>     I'll be happy to do another diff.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Hope you'll have had a good Christmas as well.
> >>>>>>>>>    We've had snow in Alabama since Christmas eve!
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Regards,
> >>>>>>>>>
> >>>>>>>>> Stuart
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> -----Original Message-----
> >>>>>>>>> From: Kevin D. Kissell [mailto:kevink@paralogos.com]
> >>>>>>>>> Sent: Friday, December 24, 2010 5:34 PM
> >>>>>>>>> To: Anoop P A
> >>>>>>>>> Cc: STUART VENTERS; Anoop P.A.; linux-mips@linux-mips.org
> >>>>>>>>> Subject: Re: SMTC support status in latest git head.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Ah, well, at least we have a stackframe.h fix that preserves David's
> >>>>>>>>> performance tweak for the deeper pipelined processors.  In looking for
> >>>>>>>>> this, I did notice that someone did some modification to the SMTC clock
> >>>>>>>>> tick logic that I was skeptical had ever been tested.  If you've still
> >>>>>>>>> got that kernel binary handy, you might check to see if it boots with
> >>>>>>>>> maxtcs=1 maxvpes=1, maxtcs=2 maxvpes=1, and/or maxtcs=2 maxvpes=2.
> >>>>>>>>>
> >>>>>>>>> Oh, yes, and Merry Christmas one and all!
> >>>>>>>>>
> >>>>>>>>>               Regards,
> >>>>>>>>>
> >>>>>>>>>               Kevin K.
> >>>>>>>>>
> >>>>>>>>> On 12/24/10 8:02 AM, Anoop P A wrote:
> >>>>>>>>>> On Fri, 2010-12-24 at 06:53 -0800, Kevin D. Kissell wrote:
> >>>>>>>>>>> Excellent!  Now, does the attached patch (relative to 2.6.37.11) also
> >>>>>>>>>>> fix things, while preserving the other fixes and performance enhancements?
> >>>>>>>>>>>
> >>>>>>>>>> I have tested that patch with 2.6.37 branch it well passes calibration
> >>>>>>>>>> loop but hangs after switching to mips closource
> >>>>>>>>>>
> >>>>>>>>>> TC 6 going on-line as CPU 6
> >>>>>>>>>> Brought up 7 CPUs
> >>>>>>>>>> bio: create slab<bio-0>   at 0
> >>>>>>>>>> SCSI subsystem initialized
> >>>>>>>>>> Switching to clocksource MIPS
> >>>>>>>>>>
> >>>>>>>>>> I Presume this is a different issue as restoring older file didn't help
> >>>>>>>>>> much to get rid of this hang.
> >>>>>>>>>>
> >>>>>>>>>> diff --git a/arch/mips/include/asm/stackframe.h
> >>>>>>>>>> b/arch/mips/include/asm/stackframe.h
> >>>>>>>>>> index 58730c5..7fc9f10 100644
> >>>>>>>>>> --- a/arch/mips/include/asm/stackframe.h
> >>>>>>>>>> +++ b/arch/mips/include/asm/stackframe.h
> >>>>>>>>>> @@ -195,9 +195,9 @@
> >>>>>>>>>>    		 * to cover the pipeline delay.
> >>>>>>>>>>    		 */
> >>>>>>>>>>    		.set	mips32
> >>>>>>>>>> -		mfc0	v1, CP0_TCSTATUS
> >>>>>>>>>> +		mfc0	v0, CP0_TCSTATUS
> >>>>>>>>>>    		.set	mips0
> >>>>>>>>>> -		LONG_S	v1, PT_TCSTATUS(sp)
> >>>>>>>>>> +		LONG_S	v0, PT_TCSTATUS(sp)
> >>>>>>>>>>    #endif /* CONFIG_MIPS_MT_SMTC */
> >>>>>>>>>>    		LONG_S	$4, PT_R4(sp)
> >>>>>>>>>>    		LONG_S	$5, PT_R5(sp)
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>> /K.
> >>>>>>>>>>>
> >>>>>>>>>>> On 12/24/10 6:39 AM, Anoop P A wrote:
> >>>>>>>>>>>> Hi Kevin, Stuart ,
> >>>>>>>>>>>>
> >>>>>>>>>>>> Woohooo You guys spotted !.
> >>>>>>>>>>>>
> >>>>>>>>>>>>     http://git.linux-mips.org/?p=linux.git;a=commit;h=d5ec6e3c seems to be
> >>>>>>>>>>>> the culprit
> >>>>>>>>>>>>
> >>>>>>>>>>>> Once I restored previous version of stackframe.h 2.6.33-stable started
> >>>>>>>>>>>> booting !.
> >>>>>>>>>>>>
> >>>>>>>>>>>> Thanks,
> >>>>>>>>>>>> Anoop
> >>>>>>>>>>>>
> >>>>>>>>>>>> On Fri, 2010-12-24 at 04:32 -0800, Kevin D. Kissell wrote:
> >>>>>>>>>>>>> Thank you, Stuart!  I've spotted some definite breakage to SMTC between
> >>>>>>>>>>>>> those versions.  In arch/mips/include/asm/stackframe.h, someone moved
> >>>>>>>>>>>>> the store of the Status register value in SAVE_SOME (line 169 or 204,
> >>>>>>>>>>>>> depending on the version) from two instructions after the mfc0 to a
> >>>>>>>>>>>>> point after the #ifdef for SMTC, presumably to get better pipelining of
> >>>>>>>>>>>>> the register access.  Unfortunately, the v1 register is also used in the
> >>>>>>>>>>>>> SMTC-specific fragment to save TCStatus, so the Status value gets
> >>>>>>>>>>>>> clobbered before it gets stored.  This will eventually result in the
> >>>>>>>>>>>>> Status register getting a TCStatus value, which has some bits on common,
> >>>>>>>>>>>>> but isn't identical and sooner or later Bad Things will happen.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> I'm a little surprised this wasn't caught by visual inspection of the patch.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Possible solutions would include reverting the store of the CP0_STATUS
> >>>>>>>>>>>>> value to the block above the #ifdef, or, to retain whatever performance
> >>>>>>>>>>>>> advantage was obtained by moving the store downward, to use v0/$2
> >>>>>>>>>>>>> instead of v1/$3, as the staging register for the TCStatus value.  I'd
> >>>>>>>>>>>>> lean toward the second option, but I'm not in a position to test and
> >>>>>>>>>>>>> submit a patch just now.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>                 Regards,
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>                 Kevin K.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> On 12/23/10 1:09 PM, STUART VENTERS wrote:
> >>>>>>>>>>>>>> Kevin,
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> I'm not sure if it's useful,
> >>>>>>>>>>>>>>        but finally I got the time to look at the two kernel versions Anoop pointed out.
> >>>>>>>>>>>>>>         works   2.6.32-stable with patch 804
> >>>>>>>>>>>>>>         works_not 2.6.33-stable
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> greping for files with CONFIG_MIPS_MT_SMTC
> >>>>>>>>>>>>>>        and looking for timer interrupt related stuff found the following differences:
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> arch/mips/include/asm/irq.h
> >>>>>>>>>>>>>> arch/mips/kernel/irq.c
> >>>>>>>>>>>>>>       do_IRQ
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> arch/mips/include/asm/stackframe.h
> >>>>>>>>>>>>>>       SAVE_SOME SAVE_TEMP get/set_saved_sp
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> arch/mips/include/asm/time.h
> >>>>>>>>>>>>>>       clocksource_set_clock
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> arch/mips/kernel/process.c
> >>>>>>>>>>>>>>       cpu_idle
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> arch/mips/kernel/smtc.c
> >>>>>>>>>>>>>>       __irq_entry
> >>>>>>>>>>>>>>       ipi_decode
> >>>>>>>>>>>>>>           SMTC_CLOCK_TICK
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Enclosed are the two subsets of files for a more expert look.
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> I'll try to look in more detail after Christmas.
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Cheers,
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Stuart
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >
> 



From juhosg@openwrt.org Tue Jan  4 13:56:53 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 13:57:00 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:60518 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1492064Ab1ADM4x convert rfc822-to-8bit
        (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Tue, 4 Jan 2011 13:56:53 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 48BB445C013;
        Tue,  4 Jan 2011 13:56:44 +0100 (CET)
Received: from [192.168.254.10] (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 0B9461F0001;
        Tue,  4 Jan 2011 13:56:42 +0100 (CET)
Message-ID: <4D231907.8070302@openwrt.org>
Date:   Tue, 04 Jan 2011 13:56:39 +0100
From:   Gabor Juhos <juhosg@openwrt.org>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; hu-HU; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Grant Likely <grant.likely@secretlab.ca>
CC:     Ralf Baechle <ralf@linux-mips.org>, linux-mips@linux-mips.org,
        David Brownell <dbrownell@users.sourceforge.net>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        spi-devel-general@lists.sourceforge.net,
        Imre Kaloz <kaloz@openwrt.org>
Subject: Re: [PATCH v4 09/16] spi: add SPI controller driver for the Atheros
 AR71XX/AR724X/AR913X SoCs
References: <1293994589-6794-1-git-send-email-juhosg@openwrt.org> <1293994589-6794-10-git-send-email-juhosg@openwrt.org> <20110103170211.GA2522@angua.secretlab.ca>
In-Reply-To: <20110103170211.GA2522@angua.secretlab.ca>
X-Enigmail-Version: 1.1.1
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8BIT
X-VBMS: A1668018B32 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28818
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

2011.01.03. 18:02 keltezéssel, Grant Likely írta:
> On Sun, Jan 02, 2011 at 07:56:22PM +0100, Gabor Juhos wrote:
>> The Atheros AR71XX/AR724X/AR913X SoCs have a built-in SPI controller. This
>> patch implements a driver for that.
>>
> 
> Mostly looks okay to me.  A few comments below.  Do you want this one
> merged via my spi tree, or does it depend on other patches in this
> series?  I'm also okay with it going in with the rest of this series.

The driver won't be usable without the preceding patches in the series.
Additionally, further patches depends on this one so it should go via the MIPS tree.

> After addressing comments, feel free to add:
> Acked-by: Grant Likely <grant.likely@secretlab.ca>

Thank you!

>> <...>
>> +struct ath79_spi {
>> +	struct	spi_bitbang	bitbang;
>> +	u32			ioc_base;
>> +	u32			reg_ctrl;
>> +
>> +	void __iomem		*base;
>> +
>> +	struct platform_device	*pdev;
> 
> This field doesn't seem to actually be used anywhere.

True, i will remove that.

> 
>> +};
>> +
>> +static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
>> +{
>> +	return ioread32(sp->base + reg);
>> +}
>> +
>> +static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned reg, u32 val)
>> +{
>> +	iowrite32(val, sp->base + reg);
>> +}
>> +
>> +static inline struct ath79_spi *spidev_to_sp(struct spi_device *spi)
> 
> should be ath79_spidev_to_sp()

Ok.

> 
>> +{
>> +	return spi_master_get_devdata(spi->master);
>> +}
>> +
>> +static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
>> +{
>> +	struct ath79_spi *sp = spidev_to_sp(spi);
>> +	int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
>> +
>> +	if (is_active) {
>> +		/* set initial clock polarity */
>> +		if (spi->mode & SPI_CPOL)
>> +			sp->ioc_base |= AR71XX_SPI_IOC_CLK;
>> +		else
>> +			sp->ioc_base &= ~AR71XX_SPI_IOC_CLK;
>> +
>> +		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
>> +	}
>> +
>> +	if (spi->chip_select) {
>> +		unsigned long gpio = (unsigned long) spi->controller_data;
>> +
>> +		/* SPI is normally active-low */
>> +		gpio_set_value(gpio, cs_high);
>> +	} else {
>> +		if (cs_high)
>> +			sp->ioc_base |= AR71XX_SPI_IOC_CS0;
>> +		else
>> +			sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
>> +
>> +		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
>> +	}
>> +
>> +}
>> +
>> +static int ath79_spi_setup_cs(struct spi_device *spi)
>> +{
>> +	struct ath79_spi *sp = spidev_to_sp(spi);
>> +
>> +	/* enable GPIO mode */
>> +	ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
>> +
>> +	/* save CTRL register */
>> +	sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL);
>> +	sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC);
>> +
>> +	/* TODO: setup speed? */
>> +	ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
>> +
>> +	if (spi->chip_select) {
>> +		unsigned long gpio = (unsigned long) spi->controller_data;
> 
> Casting here is bad practice.  

It seems that the spi-gpio driver was a bad example. :)

> It would be better to have an explicit ath97_spi_controller_data structure.

I will add the explicit structure. Expect an updated version soon.

Thanks,
Gabor

From anoop.pa@gmail.com Tue Jan  4 15:26:02 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 15:26:06 +0100 (CET)
Received: from mail-vw0-f49.google.com ([209.85.212.49]:64568 "EHLO
        mail-vw0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1492074Ab1ADO0B (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 15:26:01 +0100
Received: by vws5 with SMTP id 5so5634747vws.36
        for <linux-mips@linux-mips.org>; Tue, 04 Jan 2011 06:25:54 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:subject:from:to:cc
         :in-reply-to:references:content-type:date:message-id:mime-version
         :x-mailer:content-transfer-encoding;
        bh=FNuPM+W3f5t+KfgQqzstaQ7meROJMZZgtYi3a7wgzG4=;
        b=MNF8M8KXa+6jNUHik+kq/fIcbXeLECXvHhM6HVp3jRecqCyILHkXlyDH1k87Ja4RLX
         r5WQ967s7algFflTI+rlVAr4FGbcKa1fS8mmONcUuns2hkiQwUbtHqOjmreN6QULFjj4
         Bur7UACaHO5hdcv68h1YFSl8LFjVqfe/kaBCk=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=subject:from:to:cc:in-reply-to:references:content-type:date
         :message-id:mime-version:x-mailer:content-transfer-encoding;
        b=MTEiivBOBdXwFcARh3xe8aGacye+psN3rcF+57Xx7Hfqyp/QUa8pDhGm2loJ92TWbv
         9QisVx2B46mU87jKk6x0Rwnp7TqApwlZujLcF4wxdcVmtW557TX3bzY3UOcTJ+nUmRyW
         y9TqzJRhW5GdzDVOzCIqvQoGtupqk1C0d0zpM=
Received: by 10.220.190.2 with SMTP id dg2mr6755851vcb.156.1294151154366;
        Tue, 04 Jan 2011 06:25:54 -0800 (PST)
Received: from [172.16.48.51] ([59.160.135.215])
        by mx.google.com with ESMTPS id e18sm8102512vbm.15.2011.01.04.06.25.49
        (version=SSLv3 cipher=RC4-MD5);
        Tue, 04 Jan 2011 06:25:52 -0800 (PST)
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
In-Reply-To: <1294146165.27661.361.camel@paanoop1-desktop>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
         <1293470392.27661.202.camel@paanoop1-desktop>
         <1293524389.27661.210.camel@paanoop1-desktop>
         <4D19A31E.1090905@paralogos.com>
         <1293798476.27661.279.camel@paanoop1-desktop>
         <4D1EE913.1070203@paralogos.com>
         <1294067561.27661.293.camel@paanoop1-desktop>
         <4D21F5D3.50604@paralogos.com>
         <1294082426.27661.330.camel@paanoop1-desktop>
         <4D22D7B3.2050609@paralogos.com>
         <1294146165.27661.361.camel@paanoop1-desktop>
Content-Type: text/plain; charset="UTF-8"
Date:   Tue, 04 Jan 2011 20:07:02 +0530
Message-ID: <1294151822.27661.375.camel@paanoop1-desktop>
Mime-Version: 1.0
X-Mailer: Evolution 2.28.3 
Content-Transfer-Encoding: 7bit
Return-Path: <anoop.pa@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: 28819
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips

Hi Kevin,

the stackframe patch that you have suggested had some side effects I was
unable execute init. When I changed some thing like below it started
working .Could you kindly review it ?.

diff --git a/arch/mips/include/asm/stackframe.h
b/arch/mips/include/asm/stackframe.h
index 58730c5..da786ed 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -181,14 +181,6 @@
 #endif
 		LONG_S	k0, PT_R29(sp)
 		LONG_S	$3, PT_R3(sp)
-		/*
-		 * You might think that you don't need to save $0,
-		 * but the FPU emulator and gdb remote debug stub
-		 * need it to operate correctly
-		 */
-		LONG_S	$0, PT_R0(sp)
-		mfc0	v1, CP0_STATUS
-		LONG_S	$2, PT_R2(sp)
 #ifdef CONFIG_MIPS_MT_SMTC
 		/*
 		 * Ideally, these instructions would be shuffled in
@@ -199,6 +191,14 @@
 		.set	mips0
 		LONG_S	v1, PT_TCSTATUS(sp)
 #endif /* CONFIG_MIPS_MT_SMTC */
+		/*
+		 * You might think that you don't need to save $0,
+		 * but the FPU emulator and gdb remote debug stub
+		 * need it to operate correctly
+		 */
+		LONG_S	$0, PT_R0(sp)
+		mfc0	v1, CP0_STATUS
+		LONG_S	$2, PT_R2(sp)
 		LONG_S	$4, PT_R4(sp)
 		LONG_S	$5, PT_R5(sp)
 		LONG_S	v1, PT_STATUS(sp)

Linux-2.6.37-rc7 boots all the way if I specify maxvpes=1 in command
line.

/ # cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
CPU6
  1:        249     218024     218286     218263     218235     218208
218179            MIPS  SMTC_IPI
  6:          0          0          0          0          0          0
0            MIPS  MSP CIC cascade
  8:          0          0          0          0          0          0
0         MSP_CIC  Softreset button
  9:          0          0          0          0          0          0
0         MSP_CIC  Standby switch
 21:          0          0          0          0          0          0
0         MSP_CIC  MSP PER cascade
 25:     218128        711         11          0          0          0
0         MSP_CIC  timer
 27:        341         22          0          0          2          0
6         MSP_CIC  serial

ERR:          0
/ # uname -a
Linux (none) 2.6.37-rc7-pmc-00001-g9cff2d6-dirty #289 SMP PREEMPT Tue
Jan 4 19:48:31 IST 2011 mips GNU/Linux

So clock setup / distribution on VPE1 is some thing need fix.

Thanks
Anoop


On Tue, 2011-01-04 at 18:32 +0530, Anoop P A wrote:
> On Tue, 2011-01-04 at 00:17 -0800, Kevin D. Kissell wrote:
> > Those interrupt counters show that IPIs are being taken everywhere,
> > though very few by CPUs 5 and 6.  If I understand the configuration
> > correctly, CPU 4 is a TC in VPE 1, and it's getting a reasonable IPI
> Yes CPU4 is in second VPE
> 
> > rate, *if* we're looking at a tickless kernel under low load.  But there
> No it was not the tickless kernel.I had selected 250 MHz timer. can't we
> expect IPI / timer interrupt for all the threads in this case ?.
> 
> > may be a clue there to part of your problem.  I have no idea why the
> > behavior would have changed from 2.6.36 to 2.6.37, but it looks as if
> > you're getting your clock interrupts through the MSP CIC interrupt
> > controller on VPE 0.  There's nothing symmetric for VPE1. The Malta
> > example code is perhaps deceptively simple, in that both VPEs have their
> > count/compare indication wired directly to the 2 clock interrupt inputs,
> > so that having both of them running with only a single set of irq state
> > just works.  I don't know whether the MSP CIC timer interrupt is a
> 
> In my case it is separate irq. MSP_INT_VPE1_TIMER (34) and  
> MSP_INT_VPE0_TIMER (25) are wired to CIC . CIC interrupt has been
> connected to cpu irq 6. 
> 
> I can reproduce cpu stall in VSMP mode If I don't setup VPE1 timer
> interrupt . Don't we have support for separate irq in SMTC
> implementation ?..
> 
> > gating of the VPE0 count/compare output, or whether it's it's own
> > interval timer, but I suspect that you may need to do some further
> > low-level initialization in the platform-specific code to set up an
> > interrupt on the VPE1 side.  I don't think the snippet you've got below
> > would work as written.
> 
> The routine which I copied works fine for VSMP mode . 
> 
> / # cat /proc/interrupts
>            CPU0       CPU1
>   0:        187        254            MIPS  IPI_resched
>   1:         77        174            MIPS  IPI_call
>   6:          0          0            MIPS  MSP CIC cascade
>   8:          0          0         MSP_CIC  Softreset button
>   9:          0          0         MSP_CIC  Standby switch
>  21:          0          0         MSP_CIC  MSP PER cascade
>  25:      37077          0         MSP_CIC  timer
>  27:        188          0         MSP_CIC  serial
>  34:          0      36986         MSP_CIC  timer
> 
> Do I want to change anything specific for SMTC ? .  
> 
> > 
> > If it's purely an issue with clock distribution on VPE1, then a boot
> > with maxvpes=1 maxtcs=4 should be stable.
> 
> Yes the kernel seems to be stable if I boot with maxvpes=1 maxtcs=4 .
> 
> > 
> > /K.
> > 
> > On 1/3/2011 11:20 AM, Anoop P A wrote:
> > > Hi Kevin,
> > >
> > > On Mon, 2011-01-03 at 08:14 -0800, Kevin D. Kissell wrote:
> > >> The very first SMTC implementations didn't support full kernel-mode
> > >> preemption, which anyway wasn't a priority, given the hardware event
> > >> response support in MIPS MT.  I believe it was later made compatible,
> > >> but it was never extensively exercised.  Since SMTC has fingers in some
> > >> pretty low-level atomicity mechanisms, if a new, parallel set was
> > >> implemented for RCU, I can easily imagine that nobody has yet
> > >> implemented SMTC-ified variants of that set.
> > >>
> > >> Your last statement isn't very clear, though.  Are you saying that if
> > >> you configure for no forced preemption and with TREE_CPU, the 2.6.37
> > >> kernel boots all the way up, or that it simply hangs later?   What's the
> > >> last rev kernel that actually boots all the way up?
> > > I have debugged this a bit more. It seems that kernel getting stalled
> > > while executing on TC's of second VPE . 
> > > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > > by 1, t=2504 jiffies)
> > > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > > by 1, t=10036 jiffies)
> > > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > > by 1, t=17568 jiffies)
> > > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > > by 1, t=25100 jiffies)
> > > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > > by 1, t=32632 jiffies)
> > > INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> > > by 1, t=40164 jiffies)
> > >
> > > With CONFIG_TREE_CPU we were not hitting this scenario very often.
> > > However with CONFIG_PREEMPT_TREE_CPU stall happens most of the time.
> > >
> > > I presume some issue in my timer setup . I am not seeing timer interrupt
> > > (or IPI interrupt) getting  incremented for VPE1 tcs on a completely
> > > booted 2.6.32-stable kernel.
> > >
> > > / # cat /proc/interrupts
> > >            CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
> > > CPU6
> > >   1:        148      15023      15140      15093       3779          8
> > > 2            MIPS  SMTC_IPI
> > >   6:          0          0          0          0          0          0
> > > 0            MIPS  MSP CIC cascade
> > >   8:          0          0          0          0          0          0
> > > 0         MSP_CIC  Softreset button
> > >   9:          0          0          0          0          0          0
> > > 0         MSP_CIC  Standby switch
> > >  21:          0          0          0          0          0          0
> > > 0         MSP_CIC  MSP PER cascade
> > >  25:      15113        341          4          7          0          0
> > > 0         MSP_CIC  timer
> > >  27:        260          9          0          1          0          0
> > > 0         MSP_CIC  serial
> > >  34:          0          0          0          0          0          0
> > > 0         MSP_CIC  timer
> > >
> > > Can't we use separate timer interrupts for VPE1 and VPE0 in SMTC ?. 
> > >
> > > I have tried setting up VPE1 timer from get_co_compare_int as follows
> > >
> > > unsigned int __cpuinit get_c0_compare_int(void)
> > > {
> > > 	if ((1==get_current_vpe()) && !vpe1_timr_installed){
> > > 	
> > > 	memcpy(&timer_vpe1,&c0_compare_irqaction,sizeof(timer_vpe1));
> > > 	
> > > 	setup_irq(MSP_INT_VPE1_TIMER, &timer_vpe1);
> > >                   vpe1_timr_installed++;
> > >           }
> > >           return (get_current_vpe() ? MSP_INT_VPE1_TIMER :
> > > MSP_INT_VPE0_TIMER);
> > > }
> > >
> > > Thanks
> > > Anoop
> > >
> > >>             Regards,
> > >>
> > >>             Kevin K.
> > >>
> > >> On 1/3/2011 7:12 AM, Anoop P A wrote:
> > >>> Hi ,
> > >>>
> > >>> Following patch restricts TREE_CPU RCU implementation only for !PREEMPT
> > >>> SMP kernel.  
> > >>> http://git.linux-mips.org/?p=linux.git;a=commit;h=687d7a960aea46e016182c7ce346d62c4dbd0366
> > >>>
> > >>> CONFIG_TREE_PREEMPT_RCU option seems to be not working for SMTC kernel
> > >>> ( which will be only available RCU implementation for SMTC kernel from
> > >>> 2.6.37 onwards) .
> > >>>
> > >>> With no forced preemption and selecting TREE_CPU I am able to boot
> > >>> further to the hang that I have reported.
> > >>>
> > >>> Thanks
> > >>> Anoop
> > >>>
> > >>> On Sat, 2011-01-01 at 00:42 -0800, Kevin D. Kissell wrote:
> > >>>> At this point the logical thing to do would seem to look at your kernel
> > >>>> image and disassemble smtc_ipi_replay(), which is where the EPC of VPE 0
> > >>>> shows the last exception to have been taken.  That's a critical SMTC
> > >>>> routine that gets called whenever an xxx_irq_restore() enables
> > >>>> interrupts, so that virtual per-TC IPI interrupts that were posted while
> > >>>> the TC had interrupts disabled can be handled deterministically.  As I
> > >>>> mentioned in an earlier message, there was some cleanup work from David
> > >>>> Howell that changed a number of irq management-related function names
> > >>>> and prototypes across all architectures, which went into linux-mips.org
> > >>>> at very roughly the time of the breakage.  The SMTC overlay over the irq
> > >>>> implementation has been pretty robust, but it's written in a perhaps
> > >>>> doomed attempt to be both efficient and using a maximum amount of common
> > >>>> code with the general case.  A mechanical or semi-mechanical change
> > >>>> could conceivably have broken things.
> > >>>>
> > >>>>             Regards,
> > >>>>
> > >>>>             Kevin K.
> > >>>>
> > >>>>
> > >>>> On 12/31/2010 4:27 AM, Anoop P A wrote:
> > >>>>> Hi ,
> > >>>>>
> > >>>>> Kernel hangs on stop_machine call. Please find mt reg dump below.
> > >>>>> Another important observation is even though 2.6.33 kernel + stackframe
> > >>>>> patch well passes calibration hang , I am still unable boot in to a
> > >>>>> initramfs root ( verified ramfs working with VSMP). So it looks like
> > >>>>> still some issue to fix between 2.6.32 and 2.6.33 .
> > >>>>> ######################## Log ###########################
> > >>>>>
> > >>>>> === MIPS MT State Dump ===
> > >>>>> -- Global State --
> > >>>>>    MVPControl Passed: 00000005
> > >>>>>    MVPControl Read: 00000004
> > >>>>>    MVPConf0 : a8008406
> > >>>>> -- per-VPE State --
> > >>>>>   VPE 0
> > >>>>>    VPEControl : 00008000
> > >>>>>    VPEConf0 : 800f0003
> > >>>>>    VPE0.Status : 11004201
> > >>>>>    VPE0.EPC : 8010dc54 smtc_ipi_replay+0xcc/0x108
> > >>>>>    VPE0.Cause : 50804000
> > >>>>>    VPE0.Config7 : 00010000
> > >>>>>   VPE 1
> > >>>>>    VPEControl : 00068006
> > >>>>>    VPEConf0 : 80cf0003
> > >>>>>    VPE1.Status : 11008301
> > >>>>>    VPE1.EPC : 801022a0 r4k_wait+0x20/0x40
> > >>>>>    VPE1.Cause : 50800000
> > >>>>>    VPE1.Config7 : 00010000
> > >>>>> -- per-TC State --
> > >>>>>   TC 0 (current TC with VPE EPC above)
> > >>>>>    TCStatus : 18102000
> > >>>>>    TCBind : 00000000
> > >>>>>    TCRestart : 803fa19c printk+0xc/0x30
> > >>>>>    TCHalt : 00000000
> > >>>>>    TCContext : 00000000
> > >>>>>   TC 1
> > >>>>>    TCStatus : 18902000
> > >>>>>    TCBind : 00200000
> > >>>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
> > >>>>>    TCHalt : 00000000
> > >>>>>    TCContext : 00140000
> > >>>>>   TC 2
> > >>>>>    TCStatus : 18902000
> > >>>>>    TCBind : 00400000
> > >>>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
> > >>>>>    TCHalt : 00000000
> > >>>>>    TCContext : 00280000
> > >>>>>   TC 3
> > >>>>>    TCStatus : 18902000
> > >>>>>    TCBind : 00600000
> > >>>>>    TCRestart : 801022a0 r4k_wait+0x20/0x40
> > >>>>>    TCHalt : 00000000
> > >>>>>    TCContext : 003c0000
> > >>>>>   TC 4
> > >>>>>    TCStatus : 18902000
> > >>>>>    TCBind : 00800001
> > >>>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
> > >>>>>    TCHalt : 00000000
> > >>>>>    TCContext : 00500000
> > >>>>>   TC 5
> > >>>>>    TCStatus : 18902000
> > >>>>>    TCBind : 00a00001
> > >>>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
> > >>>>>    TCHalt : 00000000
> > >>>>>    TCContext : 00640000
> > >>>>>   TC 6
> > >>>>>    TCStatus : 18902000
> > >>>>>    TCBind : 00c00001
> > >>>>>    TCRestart : 8010229c r4k_wait+0x1c/0x40
> > >>>>>    TCHalt : 00000000
> > >>>>>    TCContext : 00780000
> > >>>>> Counter Interrupts taken per CPU (TC)
> > >>>>> 0: 0
> > >>>>> 1: 0
> > >>>>> 2: 0
> > >>>>> 3: 0
> > >>>>> 4: 0
> > >>>>> 5: 0
> > >>>>> 6: 0
> > >>>>> 7: 0
> > >>>>> Self-IPI invocations:
> > >>>>> 0: 12
> > >>>>> 1: 0
> > >>>>> 2: 0
> > >>>>> 3: 0
> > >>>>> 4: 0
> > >>>>> 5: 5
> > >>>>> 6: 4
> > >>>>> 7: 0
> > >>>>> IPIQ[0]: head = 0x0, tail = 0x0, depth = 0
> > >>>>> IPIQ[1]: head = 0x0, tail = 0x0, depth = 0
> > >>>>> IPIQ[2]: head = 0x0, tail = 0x0, depth = 0
> > >>>>> IPIQ[3]: head = 0x0, tail = 0x0, depth = 0
> > >>>>> IPIQ[4]: head = 0x0, tail = 0x0, depth = 0
> > >>>>> IPIQ[5]: head = 0x0, tail = 0x0, depth = 0
> > >>>>> IPIQ[6]: head = 0x0, tail = 0x0, depth = 0
> > >>>>> IPIQ[7]: head = 0x0, tail = 0x0, depth = 0
> > >>>>> 0 Recoveries of "stolen" FPU
> > >>>>> ===========================
> > >>>>>
> > >>>>> ################################################################
> > >>>>>
> > >>>>> Thanks
> > >>>>> Anoop
> > >>>>>
> > >>>>> On Tue, 2010-12-28 at 00:43 -0800, Kevin D. Kissell wrote:
> > >>>>>> I took a quick look last night, and the only thing that looked vaguely 
> > >>>>>> dangerous in changes since the timer changes I alluded to earlier was 
> > >>>>>> the global naming cleanup of irq-related function names that David 
> > >>>>>> Howell submitted.  The diff didn't look dangerous in itself, but some of 
> > >>>>>> the definitions are nested subtly for SMTC to maximize the amount of 
> > >>>>>> common code, and I could imagine something getting lost in translation 
> > >>>>>> there.  If that were really the problem, it would of course affect much 
> > >>>>>> more than just the timer subsystem, but early in the boot process, 
> > >>>>>> timers are pretty much the only interrupts that have to be handled 
> > >>>>>> correctly.
> > >>>>>>
> > >>>>>> I'm travelling today, but will take a look at timekeeping_notify() 
> > >>>>>> tomorrow or the next day...
> > >>>>>>
> > >>>>>> /K.
> > >>>>>>
> > >>>>>> On 12/28/10 12:19 AM, Anoop P A wrote:
> > >>>>>>> Hi,
> > >>>>>>>
> > >>>>>>> I had a glance into the code diff without notice of any suspect-able
> > >>>>>>> code .
> > >>>>>>> Tracing the hang showed that it is getting hanged in timekeeping_notify
> > >>>>>>> function.
> > >>>>>>>
> > >>>>>>> Thanks,
> > >>>>>>> Anoop
> > >>>>>>>
> > >>>>>>> PS: I may not be available until Thursday
> > >>>>>>>
> > >>>>>>> On Mon, 2010-12-27 at 22:49 +0530, Anoop P A wrote:
> > >>>>>>>> Hi Kevin,
> > >>>>>>>>
> > >>>>>>>> It is very unlikely that the patch you pointed has any impact on the the
> > >>>>>>>> hang I am seeing. The patch you have mentioned got into kernel around
> > >>>>>>>> 2.6.32 timeframe. I am able to boot both 2.6.32 and  2.6.33 kernel ( +
> > >>>>>>>> stackframe patch) .
> > >>>>>>>>
> > >>>>>>>> Hi Stuart,
> > >>>>>>>>
> > >>>>>>>> I haven't got much time to spend on this today.
> > >>>>>>>>
> > >>>>>>>> I had got 2.6.36-stable(+ stack frame patch) booting last day and I have
> > >>>>>>>> observed hang issue with 2.6.37-rc1 ( Same as rc6 and current git head)
> > >>>>>>>>
> > >>>>>>>> So probably some patches in 2.6.37 branch introduced this hang.
> > >>>>>>>>
> > >>>>>>>> Hopefully I will get some free slot tomorrow so that I can look into
> > >>>>>>>> code diff .
> > >>>>>>>>
> > >>>>>>>> Thanks
> > >>>>>>>> Anoop
> > >>>>>>>>
> > >>>>>>>> On Mon, 2010-12-27 at 09:49 -0600, STUART VENTERS wrote:
> > >>>>>>>>> Kevin,
> > >>>>>>>>>
> > >>>>>>>>> Outstanding, sometimes it's better to be lucky than good.
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>> Anoop,
> > >>>>>>>>>
> > >>>>>>>>> Maybe we can get lucky again.
> > >>>>>>>>>
> > >>>>>>>>> If you can isolate the .33 works/.37 works_not bug to a specific pair of versions,
> > >>>>>>>>>     I'll be happy to do another diff.
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>> Hope you'll have had a good Christmas as well.
> > >>>>>>>>>    We've had snow in Alabama since Christmas eve!
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>> Regards,
> > >>>>>>>>>
> > >>>>>>>>> Stuart
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>> -----Original Message-----
> > >>>>>>>>> From: Kevin D. Kissell [mailto:kevink@paralogos.com]
> > >>>>>>>>> Sent: Friday, December 24, 2010 5:34 PM
> > >>>>>>>>> To: Anoop P A
> > >>>>>>>>> Cc: STUART VENTERS; Anoop P.A.; linux-mips@linux-mips.org
> > >>>>>>>>> Subject: Re: SMTC support status in latest git head.
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>> Ah, well, at least we have a stackframe.h fix that preserves David's
> > >>>>>>>>> performance tweak for the deeper pipelined processors.  In looking for
> > >>>>>>>>> this, I did notice that someone did some modification to the SMTC clock
> > >>>>>>>>> tick logic that I was skeptical had ever been tested.  If you've still
> > >>>>>>>>> got that kernel binary handy, you might check to see if it boots with
> > >>>>>>>>> maxtcs=1 maxvpes=1, maxtcs=2 maxvpes=1, and/or maxtcs=2 maxvpes=2.
> > >>>>>>>>>
> > >>>>>>>>> Oh, yes, and Merry Christmas one and all!
> > >>>>>>>>>
> > >>>>>>>>>               Regards,
> > >>>>>>>>>
> > >>>>>>>>>               Kevin K.
> > >>>>>>>>>
> > >>>>>>>>> On 12/24/10 8:02 AM, Anoop P A wrote:
> > >>>>>>>>>> On Fri, 2010-12-24 at 06:53 -0800, Kevin D. Kissell wrote:
> > >>>>>>>>>>> Excellent!  Now, does the attached patch (relative to 2.6.37.11) also
> > >>>>>>>>>>> fix things, while preserving the other fixes and performance enhancements?
> > >>>>>>>>>>>
> > >>>>>>>>>> I have tested that patch with 2.6.37 branch it well passes calibration
> > >>>>>>>>>> loop but hangs after switching to mips closource
> > >>>>>>>>>>
> > >>>>>>>>>> TC 6 going on-line as CPU 6
> > >>>>>>>>>> Brought up 7 CPUs
> > >>>>>>>>>> bio: create slab<bio-0>   at 0
> > >>>>>>>>>> SCSI subsystem initialized
> > >>>>>>>>>> Switching to clocksource MIPS
> > >>>>>>>>>>
> > >>>>>>>>>> I Presume this is a different issue as restoring older file didn't help
> > >>>>>>>>>> much to get rid of this hang.
> > >>>>>>>>>>
> > >>>>>>>>>> diff --git a/arch/mips/include/asm/stackframe.h
> > >>>>>>>>>> b/arch/mips/include/asm/stackframe.h
> > >>>>>>>>>> index 58730c5..7fc9f10 100644
> > >>>>>>>>>> --- a/arch/mips/include/asm/stackframe.h
> > >>>>>>>>>> +++ b/arch/mips/include/asm/stackframe.h
> > >>>>>>>>>> @@ -195,9 +195,9 @@
> > >>>>>>>>>>    		 * to cover the pipeline delay.
> > >>>>>>>>>>    		 */
> > >>>>>>>>>>    		.set	mips32
> > >>>>>>>>>> -		mfc0	v1, CP0_TCSTATUS
> > >>>>>>>>>> +		mfc0	v0, CP0_TCSTATUS
> > >>>>>>>>>>    		.set	mips0
> > >>>>>>>>>> -		LONG_S	v1, PT_TCSTATUS(sp)
> > >>>>>>>>>> +		LONG_S	v0, PT_TCSTATUS(sp)
> > >>>>>>>>>>    #endif /* CONFIG_MIPS_MT_SMTC */
> > >>>>>>>>>>    		LONG_S	$4, PT_R4(sp)
> > >>>>>>>>>>    		LONG_S	$5, PT_R5(sp)
> > >>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>>> /K.
> > >>>>>>>>>>>
> > >>>>>>>>>>> On 12/24/10 6:39 AM, Anoop P A wrote:
> > >>>>>>>>>>>> Hi Kevin, Stuart ,
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> Woohooo You guys spotted !.
> > >>>>>>>>>>>>
> > >>>>>>>>>>>>     http://git.linux-mips.org/?p=linux.git;a=commit;h=d5ec6e3c seems to be
> > >>>>>>>>>>>> the culprit
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> Once I restored previous version of stackframe.h 2.6.33-stable started
> > >>>>>>>>>>>> booting !.
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> Thanks,
> > >>>>>>>>>>>> Anoop
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> On Fri, 2010-12-24 at 04:32 -0800, Kevin D. Kissell wrote:
> > >>>>>>>>>>>>> Thank you, Stuart!  I've spotted some definite breakage to SMTC between
> > >>>>>>>>>>>>> those versions.  In arch/mips/include/asm/stackframe.h, someone moved
> > >>>>>>>>>>>>> the store of the Status register value in SAVE_SOME (line 169 or 204,
> > >>>>>>>>>>>>> depending on the version) from two instructions after the mfc0 to a
> > >>>>>>>>>>>>> point after the #ifdef for SMTC, presumably to get better pipelining of
> > >>>>>>>>>>>>> the register access.  Unfortunately, the v1 register is also used in the
> > >>>>>>>>>>>>> SMTC-specific fragment to save TCStatus, so the Status value gets
> > >>>>>>>>>>>>> clobbered before it gets stored.  This will eventually result in the
> > >>>>>>>>>>>>> Status register getting a TCStatus value, which has some bits on common,
> > >>>>>>>>>>>>> but isn't identical and sooner or later Bad Things will happen.
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>> I'm a little surprised this wasn't caught by visual inspection of the patch.
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>> Possible solutions would include reverting the store of the CP0_STATUS
> > >>>>>>>>>>>>> value to the block above the #ifdef, or, to retain whatever performance
> > >>>>>>>>>>>>> advantage was obtained by moving the store downward, to use v0/$2
> > >>>>>>>>>>>>> instead of v1/$3, as the staging register for the TCStatus value.  I'd
> > >>>>>>>>>>>>> lean toward the second option, but I'm not in a position to test and
> > >>>>>>>>>>>>> submit a patch just now.
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>>                 Regards,
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>>                 Kevin K.
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>> On 12/23/10 1:09 PM, STUART VENTERS wrote:
> > >>>>>>>>>>>>>> Kevin,
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> I'm not sure if it's useful,
> > >>>>>>>>>>>>>>        but finally I got the time to look at the two kernel versions Anoop pointed out.
> > >>>>>>>>>>>>>>         works   2.6.32-stable with patch 804
> > >>>>>>>>>>>>>>         works_not 2.6.33-stable
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> greping for files with CONFIG_MIPS_MT_SMTC
> > >>>>>>>>>>>>>>        and looking for timer interrupt related stuff found the following differences:
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> arch/mips/include/asm/irq.h
> > >>>>>>>>>>>>>> arch/mips/kernel/irq.c
> > >>>>>>>>>>>>>>       do_IRQ
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> arch/mips/include/asm/stackframe.h
> > >>>>>>>>>>>>>>       SAVE_SOME SAVE_TEMP get/set_saved_sp
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> arch/mips/include/asm/time.h
> > >>>>>>>>>>>>>>       clocksource_set_clock
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> arch/mips/kernel/process.c
> > >>>>>>>>>>>>>>       cpu_idle
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> arch/mips/kernel/smtc.c
> > >>>>>>>>>>>>>>       __irq_entry
> > >>>>>>>>>>>>>>       ipi_decode
> > >>>>>>>>>>>>>>           SMTC_CLOCK_TICK
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> Enclosed are the two subsets of files for a more expert look.
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> I'll try to look in more detail after Christmas.
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> Cheers,
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> Stuart
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>
> > >
> > 
> 



From kevink@paralogos.com Tue Jan  4 18:21:32 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 18:21:38 +0100 (CET)
Received: from gateway15.websitewelcome.com ([67.18.82.10]:58861 "HELO
        gateway15.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1490956Ab1ADRVc (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 18:21:32 +0100
Received: (qmail 13476 invoked from network); 4 Jan 2011 17:21:37 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway15.websitewelcome.com with SMTP; 4 Jan 2011 17:21:37 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=EAHUD+LbZo6nh49QFKDZ2WvwgWOQYiw/R7XytbZTUJ3mYIhL/LlzFwP3PFdDH3wP+E1ry52UJaGyG0b5zZSeW8NxsTwz0TNSH7OKezZNjvHY916TPQA5ATc6/bn5dUtl;
Received: from [216.239.45.4] (port=4340 helo=kkissell.mtv.corp.google.com)
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1PaAZZ-0003AR-6i; Tue, 04 Jan 2011 11:21:25 -0600
Message-ID: <4D235717.1000603@paralogos.com>
Date:   Tue, 04 Jan 2011 09:21:27 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101208 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Anoop P A <anoop.pa@gmail.com>
CC:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Subject: Re: SMTC support status in latest git head.
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>         <1293470392.27661.202.camel@paanoop1-desktop>         <1293524389.27661.210.camel@paanoop1-desktop>         <4D19A31E.1090905@paralogos.com>         <1293798476.27661.279.camel@paanoop1-desktop>         <4D1EE913.1070203@paralogos.com>         <1294067561.27661.293.camel@paanoop1-desktop>         <4D21F5D3.50604@paralogos.com>         <1294082426.27661.330.camel@paanoop1-desktop>         <4D22D7B3.2050609@paralogos.com>         <1294146165.27661.361.camel@paanoop1-desktop> <1294151822.27661.375.camel@paanoop1-desktop>
In-Reply-To: <1294151822.27661.375.camel@paanoop1-desktop>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28820
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

I'm trying to figure out a reason why your change below should help, and 
offhand, modulo tool bugs, I don't see it.  I'm assuming that your diff 
below is a diff relative to the pre-patch stackframe.h.   I wouldn't 
bless it as an alternative because it moves code and comments 
unnecessarily - all you should really have to do is to move the


  190                 mfc0    v1, CP0_STATUS
  191                 LONG_S  $2, PT_R2(sp)

to be just after the #endif /* CONFIG_MIPS_MT_SMTC */ at around line 201.

If moving the save of zero to PT_R0(sp) actually makes a difference, 
it's evidence that you've got problems in your toolchain (or, heaven 
forbid, your pipeline)!

But I'd really like to see what your assembler is doing to the original 
patch for it to be broken.  Assembler instruction reordering is armed, 
but it ought not to move register moves and stores around in ways where 
your sequence

197                 .set    mips32
198                 mfc0    v1, CP0_TCSTATUS
199                 .set    mips0
200                 LONG_S  v1, PT_TCSTATUS(sp)
189                 LONG_S  $0, PT_R0(sp)
190                 mfc0    v1, CP0_STATUS
191                 LONG_S  $2, PT_R2(sp)
202                 LONG_S  $4, PT_R4(sp)
203                 LONG_S  $5, PT_R5(sp)
204                 LONG_S  v1, PT_STATUS(sp)

to work while

189                 LONG_S  $0, PT_R0(sp)
190                 mfc0    v1, CP0_STATUS
191                 LONG_S  $2, PT_R2(sp)
197                 .set    mips32
198                 mfc0    v0, CP0_TCSTATUS
199                 .set    mips0
200                 LONG_S  v0, PT_TCSTATUS(sp)
202                 LONG_S  $4, PT_R4(sp)
203                 LONG_S  $5, PT_R5(sp)
204                 LONG_S  v1, PT_STATUS(sp)

does not, provided that the identity of v0=$2, v1=$3 is respected.

One thing that does stick out as being different - though, again, I'd 
need to see the disassembly of an instance of the macro to know what it 
could have done - is that the SMTC conditiona code brackets the mfc0 of 
TCStatus with .set mips32/.set mips0.  Given that the code no longer has 
a .set mips0 early in the macro, it would be more correct to make it:

                 .set    push
                 .set    mips32
                 mfc0    v0, CP0_TCSTATUS    (or v1, if we move the mfc0 
v1,CP0_STATUS)
                 .set    pop

and presumably make a similar chage for the block from line 334 to 429.

But I don't see any causal path from that funniness to failure.

             Regards,

             Kevin K.

On 01/04/11 06:37, Anoop P A wrote:
> Hi Kevin,
>
> the stackframe patch that you have suggested had some side effects I was
> unable execute init. When I changed some thing like below it started
> working .Could you kindly review it ?.
>
> diff --git a/arch/mips/include/asm/stackframe.h
> b/arch/mips/include/asm/stackframe.h
> index 58730c5..da786ed 100644
> --- a/arch/mips/include/asm/stackframe.h
> +++ b/arch/mips/include/asm/stackframe.h
> @@ -181,14 +181,6 @@
>   #endif
>   		LONG_S	k0, PT_R29(sp)
>   		LONG_S	$3, PT_R3(sp)
> -		/*
> -		 * You might think that you don't need to save $0,
> -		 * but the FPU emulator and gdb remote debug stub
> -		 * need it to operate correctly
> -		 */
> -		LONG_S	$0, PT_R0(sp)
> -		mfc0	v1, CP0_STATUS
> -		LONG_S	$2, PT_R2(sp)
>   #ifdef CONFIG_MIPS_MT_SMTC
>   		/*
>   		 * Ideally, these instructions would be shuffled in
> @@ -199,6 +191,14 @@
>   		.set	mips0
>   		LONG_S	v1, PT_TCSTATUS(sp)
>   #endif /* CONFIG_MIPS_MT_SMTC */
> +		/*
> +		 * You might think that you don't need to save $0,
> +		 * but the FPU emulator and gdb remote debug stub
> +		 * need it to operate correctly
> +		 */
> +		LONG_S	$0, PT_R0(sp)
> +		mfc0	v1, CP0_STATUS
> +		LONG_S	$2, PT_R2(sp)
>   		LONG_S	$4, PT_R4(sp)
>   		LONG_S	$5, PT_R5(sp)
>   		LONG_S	v1, PT_STATUS(sp)
>
> Linux-2.6.37-rc7 boots all the way if I specify maxvpes=1 in command
> line.
>
> / # cat /proc/interrupts
>             CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
> CPU6
>    1:        249     218024     218286     218263     218235     218208
> 218179            MIPS  SMTC_IPI
>    6:          0          0          0          0          0          0
> 0            MIPS  MSP CIC cascade
>    8:          0          0          0          0          0          0
> 0         MSP_CIC  Softreset button
>    9:          0          0          0          0          0          0
> 0         MSP_CIC  Standby switch
>   21:          0          0          0          0          0          0
> 0         MSP_CIC  MSP PER cascade
>   25:     218128        711         11          0          0          0
> 0         MSP_CIC  timer
>   27:        341         22          0          0          2          0
> 6         MSP_CIC  serial
>
> ERR:          0
> / # uname -a
> Linux (none) 2.6.37-rc7-pmc-00001-g9cff2d6-dirty #289 SMP PREEMPT Tue
> Jan 4 19:48:31 IST 2011 mips GNU/Linux
>
> So clock setup / distribution on VPE1 is some thing need fix.
>
> Thanks
> Anoop
>
>
> On Tue, 2011-01-04 at 18:32 +0530, Anoop P A wrote:
>> On Tue, 2011-01-04 at 00:17 -0800, Kevin D. Kissell wrote:
>>> Those interrupt counters show that IPIs are being taken everywhere,
>>> though very few by CPUs 5 and 6.  If I understand the configuration
>>> correctly, CPU 4 is a TC in VPE 1, and it's getting a reasonable IPI
>> Yes CPU4 is in second VPE
>>
>>> rate, *if* we're looking at a tickless kernel under low load.  But there
>> No it was not the tickless kernel.I had selected 250 MHz timer. can't we
>> expect IPI / timer interrupt for all the threads in this case ?.
>>
>>> may be a clue there to part of your problem.  I have no idea why the
>>> behavior would have changed from 2.6.36 to 2.6.37, but it looks as if
>>> you're getting your clock interrupts through the MSP CIC interrupt
>>> controller on VPE 0.  There's nothing symmetric for VPE1. The Malta
>>> example code is perhaps deceptively simple, in that both VPEs have their
>>> count/compare indication wired directly to the 2 clock interrupt inputs,
>>> so that having both of them running with only a single set of irq state
>>> just works.  I don't know whether the MSP CIC timer interrupt is a
>> In my case it is separate irq. MSP_INT_VPE1_TIMER (34) and
>> MSP_INT_VPE0_TIMER (25) are wired to CIC . CIC interrupt has been
>> connected to cpu irq 6.
>>
>> I can reproduce cpu stall in VSMP mode If I don't setup VPE1 timer
>> interrupt . Don't we have support for separate irq in SMTC
>> implementation ?..
>>
>>> gating of the VPE0 count/compare output, or whether it's it's own
>>> interval timer, but I suspect that you may need to do some further
>>> low-level initialization in the platform-specific code to set up an
>>> interrupt on the VPE1 side.  I don't think the snippet you've got below
>>> would work as written.
>> The routine which I copied works fine for VSMP mode .
>>
>> / # cat /proc/interrupts
>>             CPU0       CPU1
>>    0:        187        254            MIPS  IPI_resched
>>    1:         77        174            MIPS  IPI_call
>>    6:          0          0            MIPS  MSP CIC cascade
>>    8:          0          0         MSP_CIC  Softreset button
>>    9:          0          0         MSP_CIC  Standby switch
>>   21:          0          0         MSP_CIC  MSP PER cascade
>>   25:      37077          0         MSP_CIC  timer
>>   27:        188          0         MSP_CIC  serial
>>   34:          0      36986         MSP_CIC  timer
>>
>> Do I want to change anything specific for SMTC ? .
>>
>>> If it's purely an issue with clock distribution on VPE1, then a boot
>>> with maxvpes=1 maxtcs=4 should be stable.
>> Yes the kernel seems to be stable if I boot with maxvpes=1 maxtcs=4 .
>>
>>> /K.
>>>
>>> On 1/3/2011 11:20 AM, Anoop P A wrote:
>>>> Hi Kevin,
>>>>
>>>> On Mon, 2011-01-03 at 08:14 -0800, Kevin D. Kissell wrote:
>>>>> The very first SMTC implementations didn't support full kernel-mode
>>>>> preemption, which anyway wasn't a priority, given the hardware event
>>>>> response support in MIPS MT.  I believe it was later made compatible,
>>>>> but it was never extensively exercised.  Since SMTC has fingers in some
>>>>> pretty low-level atomicity mechanisms, if a new, parallel set was
>>>>> implemented for RCU, I can easily imagine that nobody has yet
>>>>> implemented SMTC-ified variants of that set.
>>>>>
>>>>> Your last statement isn't very clear, though.  Are you saying that if
>>>>> you configure for no forced preemption and with TREE_CPU, the 2.6.37
>>>>> kernel boots all the way up, or that it simply hangs later?   What's the
>>>>> last rev kernel that actually boots all the way up?
>>>> I have debugged this a bit more. It seems that kernel getting stalled
>>>> while executing on TC's of second VPE .
>>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>>> by 1, t=2504 jiffies)
>>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>>> by 1, t=10036 jiffies)
>>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>>> by 1, t=17568 jiffies)
>>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>>> by 1, t=25100 jiffies)
>>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>>> by 1, t=32632 jiffies)
>>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>>> by 1, t=40164 jiffies)
>>>>
>>>> With CONFIG_TREE_CPU we were not hitting this scenario very often.
>>>> However with CONFIG_PREEMPT_TREE_CPU stall happens most of the time.
>>>>
>>>> I presume some issue in my timer setup . I am not seeing timer interrupt
>>>> (or IPI interrupt) getting  incremented for VPE1 tcs on a completely
>>>> booted 2.6.32-stable kernel.
>>>>
>>>> / # cat /proc/interrupts
>>>>             CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
>>>> CPU6
>>>>    1:        148      15023      15140      15093       3779          8
>>>> 2            MIPS  SMTC_IPI
>>>>    6:          0          0          0          0          0          0
>>>> 0            MIPS  MSP CIC cascade
>>>>    8:          0          0          0          0          0          0
>>>> 0         MSP_CIC  Softreset button
>>>>    9:          0          0          0          0          0          0
>>>> 0         MSP_CIC  Standby switch
>>>>   21:          0          0          0          0          0          0
>>>> 0         MSP_CIC  MSP PER cascade
>>>>   25:      15113        341          4          7          0          0
>>>> 0         MSP_CIC  timer
>>>>   27:        260          9          0          1          0          0
>>>> 0         MSP_CIC  serial
>>>>   34:          0          0          0          0          0          0
>>>> 0         MSP_CIC  timer
>>>>
>>>> Can't we use separate timer interrupts for VPE1 and VPE0 in SMTC ?.
>>>>
>>>> I have tried setting up VPE1 timer from get_co_compare_int as follows
>>>>
>>>> unsigned int __cpuinit get_c0_compare_int(void)
>>>> {
>>>> 	if ((1==get_current_vpe())&&  !vpe1_timr_installed){
>>>> 	
>>>> 	memcpy(&timer_vpe1,&c0_compare_irqaction,sizeof(timer_vpe1));
>>>> 	
>>>> 	setup_irq(MSP_INT_VPE1_TIMER,&timer_vpe1);
>>>>                    vpe1_timr_installed++;
>>>>            }
>>>>            return (get_current_vpe() ? MSP_INT_VPE1_TIMER :
>>>> MSP_INT_VPE0_TIMER);
>>>> }
>>>>
>>>> Thanks
>>>> Anoop
>>>>
>>>>>              Regards,
>>>>>
>>>>>              Kevin K.
>>>>>
>>>>> On 1/3/2011 7:12 AM, Anoop P A wrote:
>>>>>> Hi ,
>>>>>>
>>>>>> Following patch restricts TREE_CPU RCU implementation only for !PREEMPT
>>>>>> SMP kernel.
>>>>>> http://git.linux-mips.org/?p=linux.git;a=commit;h=687d7a960aea46e016182c7ce346d62c4dbd0366
>>>>>>
>>>>>> CONFIG_TREE_PREEMPT_RCU option seems to be not working for SMTC kernel
>>>>>> ( which will be only available RCU implementation for SMTC kernel from
>>>>>> 2.6.37 onwards) .
>>>>>>
>>>>>> With no forced preemption and selecting TREE_CPU I am able to boot
>>>>>> further to the hang that I have reported.
>>>>>>
>>>>>> Thanks
>>>>>> Anoop
>>>>>>
>>>>>> On Sat, 2011-01-01 at 00:42 -0800, Kevin D. Kissell wrote:
>>>>>>> At this point the logical thing to do would seem to look at your kernel
>>>>>>> image and disassemble smtc_ipi_replay(), which is where the EPC of VPE 0
>>>>>>> shows the last exception to have been taken.  That's a critical SMTC
>>>>>>> routine that gets called whenever an xxx_irq_restore() enables
>>>>>>> interrupts, so that virtual per-TC IPI interrupts that were posted while
>>>>>>> the TC had interrupts disabled can be handled deterministically.  As I
>>>>>>> mentioned in an earlier message, there was some cleanup work from David
>>>>>>> Howell that changed a number of irq management-related function names
>>>>>>> and prototypes across all architectures, which went into linux-mips.org
>>>>>>> at very roughly the time of the breakage.  The SMTC overlay over the irq
>>>>>>> implementation has been pretty robust, but it's written in a perhaps
>>>>>>> doomed attempt to be both efficient and using a maximum amount of common
>>>>>>> code with the general case.  A mechanical or semi-mechanical change
>>>>>>> could conceivably have broken things.
>>>>>>>
>>>>>>>              Regards,
>>>>>>>
>>>>>>>              Kevin K.
>>>>>>>
>>>>>>>
>>>>>>> On 12/31/2010 4:27 AM, Anoop P A wrote:
>>>>>>>> Hi ,
>>>>>>>>
>>>>>>>> Kernel hangs on stop_machine call. Please find mt reg dump below.
>>>>>>>> Another important observation is even though 2.6.33 kernel + stackframe
>>>>>>>> patch well passes calibration hang , I am still unable boot in to a
>>>>>>>> initramfs root ( verified ramfs working with VSMP). So it looks like
>>>>>>>> still some issue to fix between 2.6.32 and 2.6.33 .
>>>>>>>> ######################## Log ###########################
>>>>>>>>
>>>>>>>> === MIPS MT State Dump ===
>>>>>>>> -- Global State --
>>>>>>>>     MVPControl Passed: 00000005
>>>>>>>>     MVPControl Read: 00000004
>>>>>>>>     MVPConf0 : a8008406
>>>>>>>> -- per-VPE State --
>>>>>>>>    VPE 0
>>>>>>>>     VPEControl : 00008000
>>>>>>>>     VPEConf0 : 800f0003
>>>>>>>>     VPE0.Status : 11004201
>>>>>>>>     VPE0.EPC : 8010dc54 smtc_ipi_replay+0xcc/0x108
>>>>>>>>     VPE0.Cause : 50804000
>>>>>>>>     VPE0.Config7 : 00010000
>>>>>>>>    VPE 1
>>>>>>>>     VPEControl : 00068006
>>>>>>>>     VPEConf0 : 80cf0003
>>>>>>>>     VPE1.Status : 11008301
>>>>>>>>     VPE1.EPC : 801022a0 r4k_wait+0x20/0x40
>>>>>>>>     VPE1.Cause : 50800000
>>>>>>>>     VPE1.Config7 : 00010000
>>>>>>>> -- per-TC State --
>>>>>>>>    TC 0 (current TC with VPE EPC above)
>>>>>>>>     TCStatus : 18102000
>>>>>>>>     TCBind : 00000000
>>>>>>>>     TCRestart : 803fa19c printk+0xc/0x30
>>>>>>>>     TCHalt : 00000000
>>>>>>>>     TCContext : 00000000
>>>>>>>>    TC 1
>>>>>>>>     TCStatus : 18902000
>>>>>>>>     TCBind : 00200000
>>>>>>>>     TCRestart : 801022a0 r4k_wait+0x20/0x40
>>>>>>>>     TCHalt : 00000000
>>>>>>>>     TCContext : 00140000
>>>>>>>>    TC 2
>>>>>>>>     TCStatus : 18902000
>>>>>>>>     TCBind : 00400000
>>>>>>>>     TCRestart : 801022a0 r4k_wait+0x20/0x40
>>>>>>>>     TCHalt : 00000000
>>>>>>>>     TCContext : 00280000
>>>>>>>>    TC 3
>>>>>>>>     TCStatus : 18902000
>>>>>>>>     TCBind : 00600000
>>>>>>>>     TCRestart : 801022a0 r4k_wait+0x20/0x40
>>>>>>>>     TCHalt : 00000000
>>>>>>>>     TCContext : 003c0000
>>>>>>>>    TC 4
>>>>>>>>     TCStatus : 18902000
>>>>>>>>     TCBind : 00800001
>>>>>>>>     TCRestart : 8010229c r4k_wait+0x1c/0x40
>>>>>>>>     TCHalt : 00000000
>>>>>>>>     TCContext : 00500000
>>>>>>>>    TC 5
>>>>>>>>     TCStatus : 18902000
>>>>>>>>     TCBind : 00a00001
>>>>>>>>     TCRestart : 8010229c r4k_wait+0x1c/0x40
>>>>>>>>     TCHalt : 00000000
>>>>>>>>     TCContext : 00640000
>>>>>>>>    TC 6
>>>>>>>>     TCStatus : 18902000
>>>>>>>>     TCBind : 00c00001
>>>>>>>>     TCRestart : 8010229c r4k_wait+0x1c/0x40
>>>>>>>>     TCHalt : 00000000
>>>>>>>>     TCContext : 00780000
>>>>>>>> Counter Interrupts taken per CPU (TC)
>>>>>>>> 0: 0
>>>>>>>> 1: 0
>>>>>>>> 2: 0
>>>>>>>> 3: 0
>>>>>>>> 4: 0
>>>>>>>> 5: 0
>>>>>>>> 6: 0
>>>>>>>> 7: 0
>>>>>>>> Self-IPI invocations:
>>>>>>>> 0: 12
>>>>>>>> 1: 0
>>>>>>>> 2: 0
>>>>>>>> 3: 0
>>>>>>>> 4: 0
>>>>>>>> 5: 5
>>>>>>>> 6: 4
>>>>>>>> 7: 0
>>>>>>>> IPIQ[0]: head = 0x0, tail = 0x0, depth = 0
>>>>>>>> IPIQ[1]: head = 0x0, tail = 0x0, depth = 0
>>>>>>>> IPIQ[2]: head = 0x0, tail = 0x0, depth = 0
>>>>>>>> IPIQ[3]: head = 0x0, tail = 0x0, depth = 0
>>>>>>>> IPIQ[4]: head = 0x0, tail = 0x0, depth = 0
>>>>>>>> IPIQ[5]: head = 0x0, tail = 0x0, depth = 0
>>>>>>>> IPIQ[6]: head = 0x0, tail = 0x0, depth = 0
>>>>>>>> IPIQ[7]: head = 0x0, tail = 0x0, depth = 0
>>>>>>>> 0 Recoveries of "stolen" FPU
>>>>>>>> ===========================
>>>>>>>>
>>>>>>>> ################################################################
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>> Anoop
>>>>>>>>
>>>>>>>> On Tue, 2010-12-28 at 00:43 -0800, Kevin D. Kissell wrote:
>>>>>>>>> I took a quick look last night, and the only thing that looked vaguely
>>>>>>>>> dangerous in changes since the timer changes I alluded to earlier was
>>>>>>>>> the global naming cleanup of irq-related function names that David
>>>>>>>>> Howell submitted.  The diff didn't look dangerous in itself, but some of
>>>>>>>>> the definitions are nested subtly for SMTC to maximize the amount of
>>>>>>>>> common code, and I could imagine something getting lost in translation
>>>>>>>>> there.  If that were really the problem, it would of course affect much
>>>>>>>>> more than just the timer subsystem, but early in the boot process,
>>>>>>>>> timers are pretty much the only interrupts that have to be handled
>>>>>>>>> correctly.
>>>>>>>>>
>>>>>>>>> I'm travelling today, but will take a look at timekeeping_notify()
>>>>>>>>> tomorrow or the next day...
>>>>>>>>>
>>>>>>>>> /K.
>>>>>>>>>
>>>>>>>>> On 12/28/10 12:19 AM, Anoop P A wrote:
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> I had a glance into the code diff without notice of any suspect-able
>>>>>>>>>> code .
>>>>>>>>>> Tracing the hang showed that it is getting hanged in timekeeping_notify
>>>>>>>>>> function.
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Anoop
>>>>>>>>>>
>>>>>>>>>> PS: I may not be available until Thursday
>>>>>>>>>>
>>>>>>>>>> On Mon, 2010-12-27 at 22:49 +0530, Anoop P A wrote:
>>>>>>>>>>> Hi Kevin,
>>>>>>>>>>>
>>>>>>>>>>> It is very unlikely that the patch you pointed has any impact on the the
>>>>>>>>>>> hang I am seeing. The patch you have mentioned got into kernel around
>>>>>>>>>>> 2.6.32 timeframe. I am able to boot both 2.6.32 and  2.6.33 kernel ( +
>>>>>>>>>>> stackframe patch) .
>>>>>>>>>>>
>>>>>>>>>>> Hi Stuart,
>>>>>>>>>>>
>>>>>>>>>>> I haven't got much time to spend on this today.
>>>>>>>>>>>
>>>>>>>>>>> I had got 2.6.36-stable(+ stack frame patch) booting last day and I have
>>>>>>>>>>> observed hang issue with 2.6.37-rc1 ( Same as rc6 and current git head)
>>>>>>>>>>>
>>>>>>>>>>> So probably some patches in 2.6.37 branch introduced this hang.
>>>>>>>>>>>
>>>>>>>>>>> Hopefully I will get some free slot tomorrow so that I can look into
>>>>>>>>>>> code diff .
>>>>>>>>>>>
>>>>>>>>>>> Thanks
>>>>>>>>>>> Anoop
>>>>>>>>>>>
>>>>>>>>>>> On Mon, 2010-12-27 at 09:49 -0600, STUART VENTERS wrote:
>>>>>>>>>>>> Kevin,
>>>>>>>>>>>>
>>>>>>>>>>>> Outstanding, sometimes it's better to be lucky than good.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Anoop,
>>>>>>>>>>>>
>>>>>>>>>>>> Maybe we can get lucky again.
>>>>>>>>>>>>
>>>>>>>>>>>> If you can isolate the .33 works/.37 works_not bug to a specific pair of versions,
>>>>>>>>>>>>      I'll be happy to do another diff.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Hope you'll have had a good Christmas as well.
>>>>>>>>>>>>     We've had snow in Alabama since Christmas eve!
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Regards,
>>>>>>>>>>>>
>>>>>>>>>>>> Stuart
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> -----Original Message-----
>>>>>>>>>>>> From: Kevin D. Kissell [mailto:kevink@paralogos.com]
>>>>>>>>>>>> Sent: Friday, December 24, 2010 5:34 PM
>>>>>>>>>>>> To: Anoop P A
>>>>>>>>>>>> Cc: STUART VENTERS; Anoop P.A.; linux-mips@linux-mips.org
>>>>>>>>>>>> Subject: Re: SMTC support status in latest git head.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Ah, well, at least we have a stackframe.h fix that preserves David's
>>>>>>>>>>>> performance tweak for the deeper pipelined processors.  In looking for
>>>>>>>>>>>> this, I did notice that someone did some modification to the SMTC clock
>>>>>>>>>>>> tick logic that I was skeptical had ever been tested.  If you've still
>>>>>>>>>>>> got that kernel binary handy, you might check to see if it boots with
>>>>>>>>>>>> maxtcs=1 maxvpes=1, maxtcs=2 maxvpes=1, and/or maxtcs=2 maxvpes=2.
>>>>>>>>>>>>
>>>>>>>>>>>> Oh, yes, and Merry Christmas one and all!
>>>>>>>>>>>>
>>>>>>>>>>>>                Regards,
>>>>>>>>>>>>
>>>>>>>>>>>>                Kevin K.
>>>>>>>>>>>>
>>>>>>>>>>>> On 12/24/10 8:02 AM, Anoop P A wrote:
>>>>>>>>>>>>> On Fri, 2010-12-24 at 06:53 -0800, Kevin D. Kissell wrote:
>>>>>>>>>>>>>> Excellent!  Now, does the attached patch (relative to 2.6.37.11) also
>>>>>>>>>>>>>> fix things, while preserving the other fixes and performance enhancements?
>>>>>>>>>>>>>>
>>>>>>>>>>>>> I have tested that patch with 2.6.37 branch it well passes calibration
>>>>>>>>>>>>> loop but hangs after switching to mips closource
>>>>>>>>>>>>>
>>>>>>>>>>>>> TC 6 going on-line as CPU 6
>>>>>>>>>>>>> Brought up 7 CPUs
>>>>>>>>>>>>> bio: create slab<bio-0>    at 0
>>>>>>>>>>>>> SCSI subsystem initialized
>>>>>>>>>>>>> Switching to clocksource MIPS
>>>>>>>>>>>>>
>>>>>>>>>>>>> I Presume this is a different issue as restoring older file didn't help
>>>>>>>>>>>>> much to get rid of this hang.
>>>>>>>>>>>>>
>>>>>>>>>>>>> diff --git a/arch/mips/include/asm/stackframe.h
>>>>>>>>>>>>> b/arch/mips/include/asm/stackframe.h
>>>>>>>>>>>>> index 58730c5..7fc9f10 100644
>>>>>>>>>>>>> --- a/arch/mips/include/asm/stackframe.h
>>>>>>>>>>>>> +++ b/arch/mips/include/asm/stackframe.h
>>>>>>>>>>>>> @@ -195,9 +195,9 @@
>>>>>>>>>>>>>     		 * to cover the pipeline delay.
>>>>>>>>>>>>>     		 */
>>>>>>>>>>>>>     		.set	mips32
>>>>>>>>>>>>> -		mfc0	v1, CP0_TCSTATUS
>>>>>>>>>>>>> +		mfc0	v0, CP0_TCSTATUS
>>>>>>>>>>>>>     		.set	mips0
>>>>>>>>>>>>> -		LONG_S	v1, PT_TCSTATUS(sp)
>>>>>>>>>>>>> +		LONG_S	v0, PT_TCSTATUS(sp)
>>>>>>>>>>>>>     #endif /* CONFIG_MIPS_MT_SMTC */
>>>>>>>>>>>>>     		LONG_S	$4, PT_R4(sp)
>>>>>>>>>>>>>     		LONG_S	$5, PT_R5(sp)
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> /K.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 12/24/10 6:39 AM, Anoop P A wrote:
>>>>>>>>>>>>>>> Hi Kevin, Stuart ,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Woohooo You guys spotted !.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>      http://git.linux-mips.org/?p=linux.git;a=commit;h=d5ec6e3c seems to be
>>>>>>>>>>>>>>> the culprit
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Once I restored previous version of stackframe.h 2.6.33-stable started
>>>>>>>>>>>>>>> booting !.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>> Anoop
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Fri, 2010-12-24 at 04:32 -0800, Kevin D. Kissell wrote:
>>>>>>>>>>>>>>>> Thank you, Stuart!  I've spotted some definite breakage to SMTC between
>>>>>>>>>>>>>>>> those versions.  In arch/mips/include/asm/stackframe.h, someone moved
>>>>>>>>>>>>>>>> the store of the Status register value in SAVE_SOME (line 169 or 204,
>>>>>>>>>>>>>>>> depending on the version) from two instructions after the mfc0 to a
>>>>>>>>>>>>>>>> point after the #ifdef for SMTC, presumably to get better pipelining of
>>>>>>>>>>>>>>>> the register access.  Unfortunately, the v1 register is also used in the
>>>>>>>>>>>>>>>> SMTC-specific fragment to save TCStatus, so the Status value gets
>>>>>>>>>>>>>>>> clobbered before it gets stored.  This will eventually result in the
>>>>>>>>>>>>>>>> Status register getting a TCStatus value, which has some bits on common,
>>>>>>>>>>>>>>>> but isn't identical and sooner or later Bad Things will happen.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'm a little surprised this wasn't caught by visual inspection of the patch.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Possible solutions would include reverting the store of the CP0_STATUS
>>>>>>>>>>>>>>>> value to the block above the #ifdef, or, to retain whatever performance
>>>>>>>>>>>>>>>> advantage was obtained by moving the store downward, to use v0/$2
>>>>>>>>>>>>>>>> instead of v1/$3, as the staging register for the TCStatus value.  I'd
>>>>>>>>>>>>>>>> lean toward the second option, but I'm not in a position to test and
>>>>>>>>>>>>>>>> submit a patch just now.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>                  Regards,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>                  Kevin K.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On 12/23/10 1:09 PM, STUART VENTERS wrote:
>>>>>>>>>>>>>>>>> Kevin,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I'm not sure if it's useful,
>>>>>>>>>>>>>>>>>         but finally I got the time to look at the two kernel versions Anoop pointed out.
>>>>>>>>>>>>>>>>>          works   2.6.32-stable with patch 804
>>>>>>>>>>>>>>>>>          works_not 2.6.33-stable
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> greping for files with CONFIG_MIPS_MT_SMTC
>>>>>>>>>>>>>>>>>         and looking for timer interrupt related stuff found the following differences:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> arch/mips/include/asm/irq.h
>>>>>>>>>>>>>>>>> arch/mips/kernel/irq.c
>>>>>>>>>>>>>>>>>        do_IRQ
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> arch/mips/include/asm/stackframe.h
>>>>>>>>>>>>>>>>>        SAVE_SOME SAVE_TEMP get/set_saved_sp
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> arch/mips/include/asm/time.h
>>>>>>>>>>>>>>>>>        clocksource_set_clock
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> arch/mips/kernel/process.c
>>>>>>>>>>>>>>>>>        cpu_idle
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> arch/mips/kernel/smtc.c
>>>>>>>>>>>>>>>>>        __irq_entry
>>>>>>>>>>>>>>>>>        ipi_decode
>>>>>>>>>>>>>>>>>            SMTC_CLOCK_TICK
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Enclosed are the two subsets of files for a more expert look.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I'll try to look in more detail after Christmas.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Stuart
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>
>


From kevink@paralogos.com Tue Jan  4 18:40:39 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 18:40:42 +0100 (CET)
Received: from gateway16.websitewelcome.com ([67.18.21.17]:47635 "HELO
        gateway16.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1490956Ab1ADRki (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 18:40:38 +0100
Received: (qmail 9400 invoked from network); 4 Jan 2011 17:40:08 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway16.websitewelcome.com with SMTP; 4 Jan 2011 17:40:08 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=M3jXPuBg+a3FaC5cpT/Kx8GY8sKg3FplrHV5uTuBpTZ4qq4JcbcF08F66kQdSPj03pHzI6Q0siChxqSv8AfM44KjG3Hqo+Gn+8JGSi3SELpTTD6F+DifI7GkdbMEcr0n;
Received: from [216.239.45.4] (port=21822 helo=kkissell.mtv.corp.google.com)
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1PaAry-0008N4-Nm; Tue, 04 Jan 2011 11:40:27 -0600
Message-ID: <4D235B8D.2070306@paralogos.com>
Date:   Tue, 04 Jan 2011 09:40:29 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101208 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Anoop P A <anoop.pa@gmail.com>
CC:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Subject: Re: SMTC support status in latest git head.
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>      <1293470392.27661.202.camel@paanoop1-desktop>   <1293524389.27661.210.camel@paanoop1-desktop>   <4D19A31E.1090905@paralogos.com>        <1293798476.27661.279.camel@paanoop1-desktop>   <4D1EE913.1070203@paralogos.com>        <1294067561.27661.293.camel@paanoop1-desktop>   <4D21F5D3.50604@paralogos.com>  <1294082426.27661.330.camel@paanoop1-desktop>   <4D22D7B3.2050609@paralogos.com> <1294146165.27661.361.camel@paanoop1-desktop>
In-Reply-To: <1294146165.27661.361.camel@paanoop1-desktop>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28821
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

On 01/04/11 05:02, Anoop P A wrote:
> On Tue, 2011-01-04 at 00:17 -0800, Kevin D. Kissell wrote:
>> Those interrupt counters show that IPIs are being taken everywhere,
>> though very few by CPUs 5 and 6.  If I understand the configuration
>> correctly, CPU 4 is a TC in VPE 1, and it's getting a reasonable IPI
> Yes CPU4 is in second VPE
>
>> rate, *if* we're looking at a tickless kernel under low load.  But there
> No it was not the tickless kernel.I had selected 250 MHz timer. can't we
> expect IPI / timer interrupt for all the threads in this case ?.

In that case, you should expect a distribution of timer interrupts that 
favors the low-numbered TCs within the VPE, as you do in VPE0, and a 
distribution of IPIs that is sort-of the inverse, as you do in VPE0.  
But the low counts on VPE1 are indeed suspicious, as you note.

>> may be a clue there to part of your problem.  I have no idea why the
>> behavior would have changed from 2.6.36 to 2.6.37, but it looks as if
>> you're getting your clock interrupts through the MSP CIC interrupt
>> controller on VPE 0.  There's nothing symmetric for VPE1. The Malta
>> example code is perhaps deceptively simple, in that both VPEs have their
>> count/compare indication wired directly to the 2 clock interrupt inputs,
>> so that having both of them running with only a single set of irq state
>> just works.  I don't know whether the MSP CIC timer interrupt is a
> In my case it is separate irq. MSP_INT_VPE1_TIMER (34) and
> MSP_INT_VPE0_TIMER (25) are wired to CIC . CIC interrupt has been
> connected to cpu irq 6.
>
> I can reproduce cpu stall in VSMP mode If I don't setup VPE1 timer
> interrupt . Don't we have support for separate irq in SMTC
> implementation ?..

There are hooks for platform-specific SMTC support, which is implemented 
for the Malta in arch/mips/mti-malta/malta-smtc.c.  See 
msmtc_init_secondary(), for example, where the clock/compare, profile, 
and IPI interrupts are armed for VPE 1, while I/O peripheral interrupts 
are inhibited.

>> gating of the VPE0 count/compare output, or whether it's it's own
>> interval timer, but I suspect that you may need to do some further
>> low-level initialization in the platform-specific code to set up an
>> interrupt on the VPE1 side.  I don't think the snippet you've got below
>> would work as written.
> The routine which I copied works fine for VSMP mode .
>
> / # cat /proc/interrupts
>             CPU0       CPU1
>    0:        187        254            MIPS  IPI_resched
>    1:         77        174            MIPS  IPI_call
>    6:          0          0            MIPS  MSP CIC cascade
>    8:          0          0         MSP_CIC  Softreset button
>    9:          0          0         MSP_CIC  Standby switch
>   21:          0          0         MSP_CIC  MSP PER cascade
>   25:      37077          0         MSP_CIC  timer
>   27:        188          0         MSP_CIC  serial
>   34:          0      36986         MSP_CIC  timer
>
> Do I want to change anything specific for SMTC ? .

If it works (which I doubt), then we can critique stylistic points like 
using

		if ((1==get_current_vpe())

Instead of the more readable and general

		if (get_current_vpe()>  0)


But I think you're generally looking in the wrong place.  Look at the 
Malta code and see what's done where.  The initial SMTC code had a lot 
of Malta assumptions in the main line that I pushed out to platform code 
in later patches.  I can see how things could be made even more modular, 
but for the moment I think it's just that there's some stuff that ought 
to be done in a "msp_smtc.c" file that doesn't exist in 2.6.37.

             Regards,

             Kevin K.
>
>
>> If it's purely an issue with clock distribution on VPE1, then a boot
>> with maxvpes=1 maxtcs=4 should be stable.
> Yes the kernel seems to be stable if I boot with maxvpes=1 maxtcs=4 .
>
>> /K.
>>
>> On 1/3/2011 11:20 AM, Anoop P A wrote:
>>> Hi Kevin,
>>>
>>> On Mon, 2011-01-03 at 08:14 -0800, Kevin D. Kissell wrote:
>>>> The very first SMTC implementations didn't support full kernel-mode
>>>> preemption, which anyway wasn't a priority, given the hardware event
>>>> response support in MIPS MT.  I believe it was later made compatible,
>>>> but it was never extensively exercised.  Since SMTC has fingers in some
>>>> pretty low-level atomicity mechanisms, if a new, parallel set was
>>>> implemented for RCU, I can easily imagine that nobody has yet
>>>> implemented SMTC-ified variants of that set.
>>>>
>>>> Your last statement isn't very clear, though.  Are you saying that if
>>>> you configure for no forced preemption and with TREE_CPU, the 2.6.37
>>>> kernel boots all the way up, or that it simply hangs later?   What's the
>>>> last rev kernel that actually boots all the way up?
>>> I have debugged this a bit more. It seems that kernel getting stalled
>>> while executing on TC's of second VPE .
>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>> by 1, t=2504 jiffies)
>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>> by 1, t=10036 jiffies)
>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>> by 1, t=17568 jiffies)
>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>> by 1, t=25100 jiffies)
>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>> by 1, t=32632 jiffies)
>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
>>> by 1, t=40164 jiffies)
>>>
>>> With CONFIG_TREE_CPU we were not hitting this scenario very often.
>>> However with CONFIG_PREEMPT_TREE_CPU stall happens most of the time.
>>>
>>> I presume some issue in my timer setup . I am not seeing timer interrupt
>>> (or IPI interrupt) getting  incremented for VPE1 tcs on a completely
>>> booted 2.6.32-stable kernel.
>>>
>>> / # cat /proc/interrupts
>>>             CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
>>> CPU6
>>>    1:        148      15023      15140      15093       3779          8
>>> 2            MIPS  SMTC_IPI
>>>    6:          0          0          0          0          0          0
>>> 0            MIPS  MSP CIC cascade
>>>    8:          0          0          0          0          0          0
>>> 0         MSP_CIC  Softreset button
>>>    9:          0          0          0          0          0          0
>>> 0         MSP_CIC  Standby switch
>>>   21:          0          0          0          0          0          0
>>> 0         MSP_CIC  MSP PER cascade
>>>   25:      15113        341          4          7          0          0
>>> 0         MSP_CIC  timer
>>>   27:        260          9          0          1          0          0
>>> 0         MSP_CIC  serial
>>>   34:          0          0          0          0          0          0
>>> 0         MSP_CIC  timer
>>>
>>> Can't we use separate timer interrupts for VPE1 and VPE0 in SMTC ?.
>>>
>>> I have tried setting up VPE1 timer from get_co_compare_int as follows
>>>
>>> unsigned int __cpuinit get_c0_compare_int(void)
>>> {
>>> 	if ((1==get_current_vpe())&&  !vpe1_timr_installed){
>>> 	
>>> 	memcpy(&timer_vpe1,&c0_compare_irqaction,sizeof(timer_vpe1));
>>> 	
>>> 	setup_irq(MSP_INT_VPE1_TIMER,&timer_vpe1);
>>>                    vpe1_timr_installed++;
>>>            }
>>>            return (get_current_vpe() ? MSP_INT_VPE1_TIMER :
>>> MSP_INT_VPE0_TIMER);
>>> }
>>>
>>> Thanks
>>> Anoop


From anoop.pa@gmail.com Tue Jan  4 18:43:13 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 18:43:18 +0100 (CET)
Received: from mail-fx0-f49.google.com ([209.85.161.49]:49698 "EHLO
        mail-fx0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490956Ab1ADRnN (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 18:43:13 +0100
Received: by fxm19 with SMTP id 19so13596649fxm.36
        for <linux-mips@linux-mips.org>; Tue, 04 Jan 2011 09:43:08 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:subject:from:to:cc
         :in-reply-to:references:content-type:date:message-id:mime-version
         :x-mailer:content-transfer-encoding;
        bh=Kr1igEHCNPKfqZraEqIRAj8n73j89UJqX1j8Wt0qoUU=;
        b=DJUlILRVBpo3pbwHHMpqHgXN8LuEBJbKRVOpGT+uRAjOsHkrtINlWdqArRw6averop
         7tYzmt1jUkbu9+SEjWZU13aYCqFRhbjZwG6NTgsxJXI9fVNXYVNbCxe7DB9dB+Ipxv2t
         vdhSgJnghzLlQz9uZGrfCSAb+TY57HJoS8GVk=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=subject:from:to:cc:in-reply-to:references:content-type:date
         :message-id:mime-version:x-mailer:content-transfer-encoding;
        b=d4PHbFTXwMr8ShMczjsLJFRqXhoBYWfOFPlcSeQ7gN0FScvAxZc39xdspwFmPiVHPZ
         E6c3XzqsrGemYrC9I/iW2/al3UvJJ5mEapkw5mMJv589mQikfX8U4x8HHxjfvK2WP/6V
         gcn9/ieO+J33J1fK2xYvVSKnaOC8BS59L/ZEg=
Received: by 10.223.95.199 with SMTP id e7mr5657906fan.39.1294162988221;
        Tue, 04 Jan 2011 09:43:08 -0800 (PST)
Received: from [172.16.48.51] ([59.160.135.215])
        by mx.google.com with ESMTPS id a2sm5188031faw.46.2011.01.04.09.43.04
        (version=SSLv3 cipher=RC4-MD5);
        Tue, 04 Jan 2011 09:43:07 -0800 (PST)
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
In-Reply-To: <4D235717.1000603@paralogos.com>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
         <1293470392.27661.202.camel@paanoop1-desktop>
         <1293524389.27661.210.camel@paanoop1-desktop>
         <4D19A31E.1090905@paralogos.com>
         <1293798476.27661.279.camel@paanoop1-desktop>
         <4D1EE913.1070203@paralogos.com>
         <1294067561.27661.293.camel@paanoop1-desktop>
         <4D21F5D3.50604@paralogos.com>
         <1294082426.27661.330.camel@paanoop1-desktop>
         <4D22D7B3.2050609@paralogos.com>
         <1294146165.27661.361.camel@paanoop1-desktop>
         <1294151822.27661.375.camel@paanoop1-desktop>
         <4D235717.1000603@paralogos.com>
Content-Type: text/plain; charset="UTF-8"
Date:   Tue, 04 Jan 2011 23:24:17 +0530
Message-ID: <1294163657.27661.386.camel@paanoop1-desktop>
Mime-Version: 1.0
X-Mailer: Evolution 2.28.3 
Content-Transfer-Encoding: 7bit
Return-Path: <anoop.pa@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: 28822
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips

On Tue, 2011-01-04 at 09:21 -0800, Kevin D. Kissell wrote:
> I'm trying to figure out a reason why your change below should help, and 
> offhand, modulo tool bugs, I don't see it.  I'm assuming that your diff 
> below is a diff relative to the pre-patch stackframe.h.   I wouldn't 
Yes patch created against stock code .

> bless it as an alternative because it moves code and comments 
> unnecessarily - all you should really have to do is to move the
> 
> 
>   190                 mfc0    v1, CP0_STATUS
>   191                 LONG_S  $2, PT_R2(sp)
> 
> to be just after the #endif /* CONFIG_MIPS_MT_SMTC */ at around line 201.
Actually I just moved code under CONFIG_MIPS_MT_SMTC to previous block
of code ( which store $0 ) . git diff did the rest on behalf of me :)

> 
> If moving the save of zero to PT_R0(sp) actually makes a difference, 
> it's evidence that you've got problems in your toolchain (or, heaven 
> forbid, your pipeline)!

In previous version of patch usage of V0 was creating issue. I have
verified this with previous version of code ( working code before
David's instruction rearrangement patch.) . 

> 
> But I'd really like to see what your assembler is doing to the original 
> patch for it to be broken.  Assembler instruction reordering is armed, 
> but it ought not to move register moves and stores around in ways where 
> your sequence
> 
> 197                 .set    mips32
> 198                 mfc0    v1, CP0_TCSTATUS
> 199                 .set    mips0
> 200                 LONG_S  v1, PT_TCSTATUS(sp)
> 189                 LONG_S  $0, PT_R0(sp)
> 190                 mfc0    v1, CP0_STATUS
> 191                 LONG_S  $2, PT_R2(sp)
> 202                 LONG_S  $4, PT_R4(sp)
> 203                 LONG_S  $5, PT_R5(sp)
> 204                 LONG_S  v1, PT_STATUS(sp)
> 
> to work while
> 
> 189                 LONG_S  $0, PT_R0(sp)
> 190                 mfc0    v1, CP0_STATUS
> 191                 LONG_S  $2, PT_R2(sp)
> 197                 .set    mips32
> 198                 mfc0    v0, CP0_TCSTATUS
> 199                 .set    mips0
> 200                 LONG_S  v0, PT_TCSTATUS(sp)
> 202                 LONG_S  $4, PT_R4(sp)
> 203                 LONG_S  $5, PT_R5(sp)
> 204                 LONG_S  v1, PT_STATUS(sp)
> 
> does not, provided that the identity of v0=$2, v1=$3 is respected.
> 
> One thing that does stick out as being different - though, again, I'd 
> need to see the disassembly of an instance of the macro to know what it 
> could have done - is that the SMTC conditiona code brackets the mfc0 of 
> TCStatus with .set mips32/.set mips0.  Given that the code no longer has 
> a .set mips0 early in the macro, it would be more correct to make it:
> 
>                  .set    push
>                  .set    mips32
>                  mfc0    v0, CP0_TCSTATUS    (or v1, if we move the mfc0 
> v1,CP0_STATUS)
>                  .set    pop
> 
> and presumably make a similar chage for the block from line 334 to 429.
> 
> But I don't see any causal path from that funniness to failure.
> 
>              Regards,
> 
>              Kevin K.
> 
> On 01/04/11 06:37, Anoop P A wrote:
> > Hi Kevin,
> >
> > the stackframe patch that you have suggested had some side effects I was
> > unable execute init. When I changed some thing like below it started
> > working .Could you kindly review it ?.
> >
> > diff --git a/arch/mips/include/asm/stackframe.h
> > b/arch/mips/include/asm/stackframe.h
> > index 58730c5..da786ed 100644
> > --- a/arch/mips/include/asm/stackframe.h
> > +++ b/arch/mips/include/asm/stackframe.h
> > @@ -181,14 +181,6 @@
> >   #endif
> >   		LONG_S	k0, PT_R29(sp)
> >   		LONG_S	$3, PT_R3(sp)
> > -		/*
> > -		 * You might think that you don't need to save $0,
> > -		 * but the FPU emulator and gdb remote debug stub
> > -		 * need it to operate correctly
> > -		 */
> > -		LONG_S	$0, PT_R0(sp)
> > -		mfc0	v1, CP0_STATUS
> > -		LONG_S	$2, PT_R2(sp)
> >   #ifdef CONFIG_MIPS_MT_SMTC
> >   		/*
> >   		 * Ideally, these instructions would be shuffled in
> > @@ -199,6 +191,14 @@
> >   		.set	mips0
> >   		LONG_S	v1, PT_TCSTATUS(sp)
> >   #endif /* CONFIG_MIPS_MT_SMTC */
> > +		/*
> > +		 * You might think that you don't need to save $0,
> > +		 * but the FPU emulator and gdb remote debug stub
> > +		 * need it to operate correctly
> > +		 */
> > +		LONG_S	$0, PT_R0(sp)
> > +		mfc0	v1, CP0_STATUS
> > +		LONG_S	$2, PT_R2(sp)
> >   		LONG_S	$4, PT_R4(sp)
> >   		LONG_S	$5, PT_R5(sp)
> >   		LONG_S	v1, PT_STATUS(sp)
> >
> > Linux-2.6.37-rc7 boots all the way if I specify maxvpes=1 in command
> > line.
> >
> > / # cat /proc/interrupts
> >             CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
> > CPU6
> >    1:        249     218024     218286     218263     218235     218208
> > 218179            MIPS  SMTC_IPI
> >    6:          0          0          0          0          0          0
> > 0            MIPS  MSP CIC cascade
> >    8:          0          0          0          0          0          0
> > 0         MSP_CIC  Softreset button
> >    9:          0          0          0          0          0          0
> > 0         MSP_CIC  Standby switch
> >   21:          0          0          0          0          0          0
> > 0         MSP_CIC  MSP PER cascade
> >   25:     218128        711         11          0          0          0
> > 0         MSP_CIC  timer
> >   27:        341         22          0          0          2          0
> > 6         MSP_CIC  serial
> >
> > ERR:          0
> > / # uname -a
> > Linux (none) 2.6.37-rc7-pmc-00001-g9cff2d6-dirty #289 SMP PREEMPT Tue
> > Jan 4 19:48:31 IST 2011 mips GNU/Linux
> >
> > So clock setup / distribution on VPE1 is some thing need fix.
> >
> > Thanks
> > Anoop
> >
> >
> > On Tue, 2011-01-04 at 18:32 +0530, Anoop P A wrote:
> >> On Tue, 2011-01-04 at 00:17 -0800, Kevin D. Kissell wrote:
> >>> Those interrupt counters show that IPIs are being taken everywhere,
> >>> though very few by CPUs 5 and 6.  If I understand the configuration
> >>> correctly, CPU 4 is a TC in VPE 1, and it's getting a reasonable IPI
> >> Yes CPU4 is in second VPE
> >>
> >>> rate, *if* we're looking at a tickless kernel under low load.  But there
> >> No it was not the tickless kernel.I had selected 250 MHz timer. can't we
> >> expect IPI / timer interrupt for all the threads in this case ?.
> >>
> >>> may be a clue there to part of your problem.  I have no idea why the
> >>> behavior would have changed from 2.6.36 to 2.6.37, but it looks as if
> >>> you're getting your clock interrupts through the MSP CIC interrupt
> >>> controller on VPE 0.  There's nothing symmetric for VPE1. The Malta
> >>> example code is perhaps deceptively simple, in that both VPEs have their
> >>> count/compare indication wired directly to the 2 clock interrupt inputs,
> >>> so that having both of them running with only a single set of irq state
> >>> just works.  I don't know whether the MSP CIC timer interrupt is a
> >> In my case it is separate irq. MSP_INT_VPE1_TIMER (34) and
> >> MSP_INT_VPE0_TIMER (25) are wired to CIC . CIC interrupt has been
> >> connected to cpu irq 6.
> >>
> >> I can reproduce cpu stall in VSMP mode If I don't setup VPE1 timer
> >> interrupt . Don't we have support for separate irq in SMTC
> >> implementation ?..
> >>
> >>> gating of the VPE0 count/compare output, or whether it's it's own
> >>> interval timer, but I suspect that you may need to do some further
> >>> low-level initialization in the platform-specific code to set up an
> >>> interrupt on the VPE1 side.  I don't think the snippet you've got below
> >>> would work as written.
> >> The routine which I copied works fine for VSMP mode .
> >>
> >> / # cat /proc/interrupts
> >>             CPU0       CPU1
> >>    0:        187        254            MIPS  IPI_resched
> >>    1:         77        174            MIPS  IPI_call
> >>    6:          0          0            MIPS  MSP CIC cascade
> >>    8:          0          0         MSP_CIC  Softreset button
> >>    9:          0          0         MSP_CIC  Standby switch
> >>   21:          0          0         MSP_CIC  MSP PER cascade
> >>   25:      37077          0         MSP_CIC  timer
> >>   27:        188          0         MSP_CIC  serial
> >>   34:          0      36986         MSP_CIC  timer
> >>
> >> Do I want to change anything specific for SMTC ? .
> >>
> >>> If it's purely an issue with clock distribution on VPE1, then a boot
> >>> with maxvpes=1 maxtcs=4 should be stable.
> >> Yes the kernel seems to be stable if I boot with maxvpes=1 maxtcs=4 .
> >>
> >>> /K.
> >>>
> >>> On 1/3/2011 11:20 AM, Anoop P A wrote:
> >>>> Hi Kevin,
> >>>>
> >>>> On Mon, 2011-01-03 at 08:14 -0800, Kevin D. Kissell wrote:
> >>>>> The very first SMTC implementations didn't support full kernel-mode
> >>>>> preemption, which anyway wasn't a priority, given the hardware event
> >>>>> response support in MIPS MT.  I believe it was later made compatible,
> >>>>> but it was never extensively exercised.  Since SMTC has fingers in some
> >>>>> pretty low-level atomicity mechanisms, if a new, parallel set was
> >>>>> implemented for RCU, I can easily imagine that nobody has yet
> >>>>> implemented SMTC-ified variants of that set.
> >>>>>
> >>>>> Your last statement isn't very clear, though.  Are you saying that if
> >>>>> you configure for no forced preemption and with TREE_CPU, the 2.6.37
> >>>>> kernel boots all the way up, or that it simply hangs later?   What's the
> >>>>> last rev kernel that actually boots all the way up?
> >>>> I have debugged this a bit more. It seems that kernel getting stalled
> >>>> while executing on TC's of second VPE .
> >>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>>> by 1, t=2504 jiffies)
> >>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>>> by 1, t=10036 jiffies)
> >>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>>> by 1, t=17568 jiffies)
> >>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>>> by 1, t=25100 jiffies)
> >>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>>> by 1, t=32632 jiffies)
> >>>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>>> by 1, t=40164 jiffies)
> >>>>
> >>>> With CONFIG_TREE_CPU we were not hitting this scenario very often.
> >>>> However with CONFIG_PREEMPT_TREE_CPU stall happens most of the time.
> >>>>
> >>>> I presume some issue in my timer setup . I am not seeing timer interrupt
> >>>> (or IPI interrupt) getting  incremented for VPE1 tcs on a completely
> >>>> booted 2.6.32-stable kernel.
> >>>>
> >>>> / # cat /proc/interrupts
> >>>>             CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
> >>>> CPU6
> >>>>    1:        148      15023      15140      15093       3779          8
> >>>> 2            MIPS  SMTC_IPI
> >>>>    6:          0          0          0          0          0          0
> >>>> 0            MIPS  MSP CIC cascade
> >>>>    8:          0          0          0          0          0          0
> >>>> 0         MSP_CIC  Softreset button
> >>>>    9:          0          0          0          0          0          0
> >>>> 0         MSP_CIC  Standby switch
> >>>>   21:          0          0          0          0          0          0
> >>>> 0         MSP_CIC  MSP PER cascade
> >>>>   25:      15113        341          4          7          0          0
> >>>> 0         MSP_CIC  timer
> >>>>   27:        260          9          0          1          0          0
> >>>> 0         MSP_CIC  serial
> >>>>   34:          0          0          0          0          0          0
> >>>> 0         MSP_CIC  timer
> >>>>
> >>>> Can't we use separate timer interrupts for VPE1 and VPE0 in SMTC ?.
> >>>>
> >>>> I have tried setting up VPE1 timer from get_co_compare_int as follows
> >>>>
> >>>> unsigned int __cpuinit get_c0_compare_int(void)
> >>>> {
> >>>> 	if ((1==get_current_vpe())&&  !vpe1_timr_installed){
> >>>> 	
> >>>> 	memcpy(&timer_vpe1,&c0_compare_irqaction,sizeof(timer_vpe1));
> >>>> 	
> >>>> 	setup_irq(MSP_INT_VPE1_TIMER,&timer_vpe1);
> >>>>                    vpe1_timr_installed++;
> >>>>            }
> >>>>            return (get_current_vpe() ? MSP_INT_VPE1_TIMER :
> >>>> MSP_INT_VPE0_TIMER);
> >>>> }
> >>>>
> >>>> Thanks
> >>>> Anoop
> >>>>
> >>>>>              Regards,
> >>>>>
> >>>>>              Kevin K.
> >>>>>
> >>>>> On 1/3/2011 7:12 AM, Anoop P A wrote:
> >>>>>> Hi ,
> >>>>>>
> >>>>>> Following patch restricts TREE_CPU RCU implementation only for !PREEMPT
> >>>>>> SMP kernel.
> >>>>>> http://git.linux-mips.org/?p=linux.git;a=commit;h=687d7a960aea46e016182c7ce346d62c4dbd0366
> >>>>>>
> >>>>>> CONFIG_TREE_PREEMPT_RCU option seems to be not working for SMTC kernel
> >>>>>> ( which will be only available RCU implementation for SMTC kernel from
> >>>>>> 2.6.37 onwards) .
> >>>>>>
> >>>>>> With no forced preemption and selecting TREE_CPU I am able to boot
> >>>>>> further to the hang that I have reported.
> >>>>>>
> >>>>>> Thanks
> >>>>>> Anoop
> >>>>>>
> >>>>>> On Sat, 2011-01-01 at 00:42 -0800, Kevin D. Kissell wrote:
> >>>>>>> At this point the logical thing to do would seem to look at your kernel
> >>>>>>> image and disassemble smtc_ipi_replay(), which is where the EPC of VPE 0
> >>>>>>> shows the last exception to have been taken.  That's a critical SMTC
> >>>>>>> routine that gets called whenever an xxx_irq_restore() enables
> >>>>>>> interrupts, so that virtual per-TC IPI interrupts that were posted while
> >>>>>>> the TC had interrupts disabled can be handled deterministically.  As I
> >>>>>>> mentioned in an earlier message, there was some cleanup work from David
> >>>>>>> Howell that changed a number of irq management-related function names
> >>>>>>> and prototypes across all architectures, which went into linux-mips.org
> >>>>>>> at very roughly the time of the breakage.  The SMTC overlay over the irq
> >>>>>>> implementation has been pretty robust, but it's written in a perhaps
> >>>>>>> doomed attempt to be both efficient and using a maximum amount of common
> >>>>>>> code with the general case.  A mechanical or semi-mechanical change
> >>>>>>> could conceivably have broken things.
> >>>>>>>
> >>>>>>>              Regards,
> >>>>>>>
> >>>>>>>              Kevin K.
> >>>>>>>
> >>>>>>>
> >>>>>>> On 12/31/2010 4:27 AM, Anoop P A wrote:
> >>>>>>>> Hi ,
> >>>>>>>>
> >>>>>>>> Kernel hangs on stop_machine call. Please find mt reg dump below.
> >>>>>>>> Another important observation is even though 2.6.33 kernel + stackframe
> >>>>>>>> patch well passes calibration hang , I am still unable boot in to a
> >>>>>>>> initramfs root ( verified ramfs working with VSMP). So it looks like
> >>>>>>>> still some issue to fix between 2.6.32 and 2.6.33 .
> >>>>>>>> ######################## Log ###########################
> >>>>>>>>
> >>>>>>>> === MIPS MT State Dump ===
> >>>>>>>> -- Global State --
> >>>>>>>>     MVPControl Passed: 00000005
> >>>>>>>>     MVPControl Read: 00000004
> >>>>>>>>     MVPConf0 : a8008406
> >>>>>>>> -- per-VPE State --
> >>>>>>>>    VPE 0
> >>>>>>>>     VPEControl : 00008000
> >>>>>>>>     VPEConf0 : 800f0003
> >>>>>>>>     VPE0.Status : 11004201
> >>>>>>>>     VPE0.EPC : 8010dc54 smtc_ipi_replay+0xcc/0x108
> >>>>>>>>     VPE0.Cause : 50804000
> >>>>>>>>     VPE0.Config7 : 00010000
> >>>>>>>>    VPE 1
> >>>>>>>>     VPEControl : 00068006
> >>>>>>>>     VPEConf0 : 80cf0003
> >>>>>>>>     VPE1.Status : 11008301
> >>>>>>>>     VPE1.EPC : 801022a0 r4k_wait+0x20/0x40
> >>>>>>>>     VPE1.Cause : 50800000
> >>>>>>>>     VPE1.Config7 : 00010000
> >>>>>>>> -- per-TC State --
> >>>>>>>>    TC 0 (current TC with VPE EPC above)
> >>>>>>>>     TCStatus : 18102000
> >>>>>>>>     TCBind : 00000000
> >>>>>>>>     TCRestart : 803fa19c printk+0xc/0x30
> >>>>>>>>     TCHalt : 00000000
> >>>>>>>>     TCContext : 00000000
> >>>>>>>>    TC 1
> >>>>>>>>     TCStatus : 18902000
> >>>>>>>>     TCBind : 00200000
> >>>>>>>>     TCRestart : 801022a0 r4k_wait+0x20/0x40
> >>>>>>>>     TCHalt : 00000000
> >>>>>>>>     TCContext : 00140000
> >>>>>>>>    TC 2
> >>>>>>>>     TCStatus : 18902000
> >>>>>>>>     TCBind : 00400000
> >>>>>>>>     TCRestart : 801022a0 r4k_wait+0x20/0x40
> >>>>>>>>     TCHalt : 00000000
> >>>>>>>>     TCContext : 00280000
> >>>>>>>>    TC 3
> >>>>>>>>     TCStatus : 18902000
> >>>>>>>>     TCBind : 00600000
> >>>>>>>>     TCRestart : 801022a0 r4k_wait+0x20/0x40
> >>>>>>>>     TCHalt : 00000000
> >>>>>>>>     TCContext : 003c0000
> >>>>>>>>    TC 4
> >>>>>>>>     TCStatus : 18902000
> >>>>>>>>     TCBind : 00800001
> >>>>>>>>     TCRestart : 8010229c r4k_wait+0x1c/0x40
> >>>>>>>>     TCHalt : 00000000
> >>>>>>>>     TCContext : 00500000
> >>>>>>>>    TC 5
> >>>>>>>>     TCStatus : 18902000
> >>>>>>>>     TCBind : 00a00001
> >>>>>>>>     TCRestart : 8010229c r4k_wait+0x1c/0x40
> >>>>>>>>     TCHalt : 00000000
> >>>>>>>>     TCContext : 00640000
> >>>>>>>>    TC 6
> >>>>>>>>     TCStatus : 18902000
> >>>>>>>>     TCBind : 00c00001
> >>>>>>>>     TCRestart : 8010229c r4k_wait+0x1c/0x40
> >>>>>>>>     TCHalt : 00000000
> >>>>>>>>     TCContext : 00780000
> >>>>>>>> Counter Interrupts taken per CPU (TC)
> >>>>>>>> 0: 0
> >>>>>>>> 1: 0
> >>>>>>>> 2: 0
> >>>>>>>> 3: 0
> >>>>>>>> 4: 0
> >>>>>>>> 5: 0
> >>>>>>>> 6: 0
> >>>>>>>> 7: 0
> >>>>>>>> Self-IPI invocations:
> >>>>>>>> 0: 12
> >>>>>>>> 1: 0
> >>>>>>>> 2: 0
> >>>>>>>> 3: 0
> >>>>>>>> 4: 0
> >>>>>>>> 5: 5
> >>>>>>>> 6: 4
> >>>>>>>> 7: 0
> >>>>>>>> IPIQ[0]: head = 0x0, tail = 0x0, depth = 0
> >>>>>>>> IPIQ[1]: head = 0x0, tail = 0x0, depth = 0
> >>>>>>>> IPIQ[2]: head = 0x0, tail = 0x0, depth = 0
> >>>>>>>> IPIQ[3]: head = 0x0, tail = 0x0, depth = 0
> >>>>>>>> IPIQ[4]: head = 0x0, tail = 0x0, depth = 0
> >>>>>>>> IPIQ[5]: head = 0x0, tail = 0x0, depth = 0
> >>>>>>>> IPIQ[6]: head = 0x0, tail = 0x0, depth = 0
> >>>>>>>> IPIQ[7]: head = 0x0, tail = 0x0, depth = 0
> >>>>>>>> 0 Recoveries of "stolen" FPU
> >>>>>>>> ===========================
> >>>>>>>>
> >>>>>>>> ################################################################
> >>>>>>>>
> >>>>>>>> Thanks
> >>>>>>>> Anoop
> >>>>>>>>
> >>>>>>>> On Tue, 2010-12-28 at 00:43 -0800, Kevin D. Kissell wrote:
> >>>>>>>>> I took a quick look last night, and the only thing that looked vaguely
> >>>>>>>>> dangerous in changes since the timer changes I alluded to earlier was
> >>>>>>>>> the global naming cleanup of irq-related function names that David
> >>>>>>>>> Howell submitted.  The diff didn't look dangerous in itself, but some of
> >>>>>>>>> the definitions are nested subtly for SMTC to maximize the amount of
> >>>>>>>>> common code, and I could imagine something getting lost in translation
> >>>>>>>>> there.  If that were really the problem, it would of course affect much
> >>>>>>>>> more than just the timer subsystem, but early in the boot process,
> >>>>>>>>> timers are pretty much the only interrupts that have to be handled
> >>>>>>>>> correctly.
> >>>>>>>>>
> >>>>>>>>> I'm travelling today, but will take a look at timekeeping_notify()
> >>>>>>>>> tomorrow or the next day...
> >>>>>>>>>
> >>>>>>>>> /K.
> >>>>>>>>>
> >>>>>>>>> On 12/28/10 12:19 AM, Anoop P A wrote:
> >>>>>>>>>> Hi,
> >>>>>>>>>>
> >>>>>>>>>> I had a glance into the code diff without notice of any suspect-able
> >>>>>>>>>> code .
> >>>>>>>>>> Tracing the hang showed that it is getting hanged in timekeeping_notify
> >>>>>>>>>> function.
> >>>>>>>>>>
> >>>>>>>>>> Thanks,
> >>>>>>>>>> Anoop
> >>>>>>>>>>
> >>>>>>>>>> PS: I may not be available until Thursday
> >>>>>>>>>>
> >>>>>>>>>> On Mon, 2010-12-27 at 22:49 +0530, Anoop P A wrote:
> >>>>>>>>>>> Hi Kevin,
> >>>>>>>>>>>
> >>>>>>>>>>> It is very unlikely that the patch you pointed has any impact on the the
> >>>>>>>>>>> hang I am seeing. The patch you have mentioned got into kernel around
> >>>>>>>>>>> 2.6.32 timeframe. I am able to boot both 2.6.32 and  2.6.33 kernel ( +
> >>>>>>>>>>> stackframe patch) .
> >>>>>>>>>>>
> >>>>>>>>>>> Hi Stuart,
> >>>>>>>>>>>
> >>>>>>>>>>> I haven't got much time to spend on this today.
> >>>>>>>>>>>
> >>>>>>>>>>> I had got 2.6.36-stable(+ stack frame patch) booting last day and I have
> >>>>>>>>>>> observed hang issue with 2.6.37-rc1 ( Same as rc6 and current git head)
> >>>>>>>>>>>
> >>>>>>>>>>> So probably some patches in 2.6.37 branch introduced this hang.
> >>>>>>>>>>>
> >>>>>>>>>>> Hopefully I will get some free slot tomorrow so that I can look into
> >>>>>>>>>>> code diff .
> >>>>>>>>>>>
> >>>>>>>>>>> Thanks
> >>>>>>>>>>> Anoop
> >>>>>>>>>>>
> >>>>>>>>>>> On Mon, 2010-12-27 at 09:49 -0600, STUART VENTERS wrote:
> >>>>>>>>>>>> Kevin,
> >>>>>>>>>>>>
> >>>>>>>>>>>> Outstanding, sometimes it's better to be lucky than good.
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> Anoop,
> >>>>>>>>>>>>
> >>>>>>>>>>>> Maybe we can get lucky again.
> >>>>>>>>>>>>
> >>>>>>>>>>>> If you can isolate the .33 works/.37 works_not bug to a specific pair of versions,
> >>>>>>>>>>>>      I'll be happy to do another diff.
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> Hope you'll have had a good Christmas as well.
> >>>>>>>>>>>>     We've had snow in Alabama since Christmas eve!
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> Regards,
> >>>>>>>>>>>>
> >>>>>>>>>>>> Stuart
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> -----Original Message-----
> >>>>>>>>>>>> From: Kevin D. Kissell [mailto:kevink@paralogos.com]
> >>>>>>>>>>>> Sent: Friday, December 24, 2010 5:34 PM
> >>>>>>>>>>>> To: Anoop P A
> >>>>>>>>>>>> Cc: STUART VENTERS; Anoop P.A.; linux-mips@linux-mips.org
> >>>>>>>>>>>> Subject: Re: SMTC support status in latest git head.
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> Ah, well, at least we have a stackframe.h fix that preserves David's
> >>>>>>>>>>>> performance tweak for the deeper pipelined processors.  In looking for
> >>>>>>>>>>>> this, I did notice that someone did some modification to the SMTC clock
> >>>>>>>>>>>> tick logic that I was skeptical had ever been tested.  If you've still
> >>>>>>>>>>>> got that kernel binary handy, you might check to see if it boots with
> >>>>>>>>>>>> maxtcs=1 maxvpes=1, maxtcs=2 maxvpes=1, and/or maxtcs=2 maxvpes=2.
> >>>>>>>>>>>>
> >>>>>>>>>>>> Oh, yes, and Merry Christmas one and all!
> >>>>>>>>>>>>
> >>>>>>>>>>>>                Regards,
> >>>>>>>>>>>>
> >>>>>>>>>>>>                Kevin K.
> >>>>>>>>>>>>
> >>>>>>>>>>>> On 12/24/10 8:02 AM, Anoop P A wrote:
> >>>>>>>>>>>>> On Fri, 2010-12-24 at 06:53 -0800, Kevin D. Kissell wrote:
> >>>>>>>>>>>>>> Excellent!  Now, does the attached patch (relative to 2.6.37.11) also
> >>>>>>>>>>>>>> fix things, while preserving the other fixes and performance enhancements?
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>> I have tested that patch with 2.6.37 branch it well passes calibration
> >>>>>>>>>>>>> loop but hangs after switching to mips closource
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> TC 6 going on-line as CPU 6
> >>>>>>>>>>>>> Brought up 7 CPUs
> >>>>>>>>>>>>> bio: create slab<bio-0>    at 0
> >>>>>>>>>>>>> SCSI subsystem initialized
> >>>>>>>>>>>>> Switching to clocksource MIPS
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> I Presume this is a different issue as restoring older file didn't help
> >>>>>>>>>>>>> much to get rid of this hang.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> diff --git a/arch/mips/include/asm/stackframe.h
> >>>>>>>>>>>>> b/arch/mips/include/asm/stackframe.h
> >>>>>>>>>>>>> index 58730c5..7fc9f10 100644
> >>>>>>>>>>>>> --- a/arch/mips/include/asm/stackframe.h
> >>>>>>>>>>>>> +++ b/arch/mips/include/asm/stackframe.h
> >>>>>>>>>>>>> @@ -195,9 +195,9 @@
> >>>>>>>>>>>>>     		 * to cover the pipeline delay.
> >>>>>>>>>>>>>     		 */
> >>>>>>>>>>>>>     		.set	mips32
> >>>>>>>>>>>>> -		mfc0	v1, CP0_TCSTATUS
> >>>>>>>>>>>>> +		mfc0	v0, CP0_TCSTATUS
> >>>>>>>>>>>>>     		.set	mips0
> >>>>>>>>>>>>> -		LONG_S	v1, PT_TCSTATUS(sp)
> >>>>>>>>>>>>> +		LONG_S	v0, PT_TCSTATUS(sp)
> >>>>>>>>>>>>>     #endif /* CONFIG_MIPS_MT_SMTC */
> >>>>>>>>>>>>>     		LONG_S	$4, PT_R4(sp)
> >>>>>>>>>>>>>     		LONG_S	$5, PT_R5(sp)
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>> /K.
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> On 12/24/10 6:39 AM, Anoop P A wrote:
> >>>>>>>>>>>>>>> Hi Kevin, Stuart ,
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> Woohooo You guys spotted !.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>      http://git.linux-mips.org/?p=linux.git;a=commit;h=d5ec6e3c seems to be
> >>>>>>>>>>>>>>> the culprit
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> Once I restored previous version of stackframe.h 2.6.33-stable started
> >>>>>>>>>>>>>>> booting !.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> Thanks,
> >>>>>>>>>>>>>>> Anoop
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> On Fri, 2010-12-24 at 04:32 -0800, Kevin D. Kissell wrote:
> >>>>>>>>>>>>>>>> Thank you, Stuart!  I've spotted some definite breakage to SMTC between
> >>>>>>>>>>>>>>>> those versions.  In arch/mips/include/asm/stackframe.h, someone moved
> >>>>>>>>>>>>>>>> the store of the Status register value in SAVE_SOME (line 169 or 204,
> >>>>>>>>>>>>>>>> depending on the version) from two instructions after the mfc0 to a
> >>>>>>>>>>>>>>>> point after the #ifdef for SMTC, presumably to get better pipelining of
> >>>>>>>>>>>>>>>> the register access.  Unfortunately, the v1 register is also used in the
> >>>>>>>>>>>>>>>> SMTC-specific fragment to save TCStatus, so the Status value gets
> >>>>>>>>>>>>>>>> clobbered before it gets stored.  This will eventually result in the
> >>>>>>>>>>>>>>>> Status register getting a TCStatus value, which has some bits on common,
> >>>>>>>>>>>>>>>> but isn't identical and sooner or later Bad Things will happen.
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> I'm a little surprised this wasn't caught by visual inspection of the patch.
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> Possible solutions would include reverting the store of the CP0_STATUS
> >>>>>>>>>>>>>>>> value to the block above the #ifdef, or, to retain whatever performance
> >>>>>>>>>>>>>>>> advantage was obtained by moving the store downward, to use v0/$2
> >>>>>>>>>>>>>>>> instead of v1/$3, as the staging register for the TCStatus value.  I'd
> >>>>>>>>>>>>>>>> lean toward the second option, but I'm not in a position to test and
> >>>>>>>>>>>>>>>> submit a patch just now.
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>                  Regards,
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>                  Kevin K.
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> On 12/23/10 1:09 PM, STUART VENTERS wrote:
> >>>>>>>>>>>>>>>>> Kevin,
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> I'm not sure if it's useful,
> >>>>>>>>>>>>>>>>>         but finally I got the time to look at the two kernel versions Anoop pointed out.
> >>>>>>>>>>>>>>>>>          works   2.6.32-stable with patch 804
> >>>>>>>>>>>>>>>>>          works_not 2.6.33-stable
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> greping for files with CONFIG_MIPS_MT_SMTC
> >>>>>>>>>>>>>>>>>         and looking for timer interrupt related stuff found the following differences:
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> arch/mips/include/asm/irq.h
> >>>>>>>>>>>>>>>>> arch/mips/kernel/irq.c
> >>>>>>>>>>>>>>>>>        do_IRQ
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> arch/mips/include/asm/stackframe.h
> >>>>>>>>>>>>>>>>>        SAVE_SOME SAVE_TEMP get/set_saved_sp
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> arch/mips/include/asm/time.h
> >>>>>>>>>>>>>>>>>        clocksource_set_clock
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> arch/mips/kernel/process.c
> >>>>>>>>>>>>>>>>>        cpu_idle
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> arch/mips/kernel/smtc.c
> >>>>>>>>>>>>>>>>>        __irq_entry
> >>>>>>>>>>>>>>>>>        ipi_decode
> >>>>>>>>>>>>>>>>>            SMTC_CLOCK_TICK
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> Enclosed are the two subsets of files for a more expert look.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> I'll try to look in more detail after Christmas.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> Cheers,
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> Stuart
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >
> >
> 



From kevink@paralogos.com Tue Jan  4 19:33:24 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 19:33:26 +0100 (CET)
Received: from gateway08.websitewelcome.com ([69.56.170.25]:49822 "HELO
        gateway08.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1490957Ab1ADSdX (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 19:33:23 +0100
Received: (qmail 28074 invoked from network); 4 Jan 2011 18:32:51 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway08.websitewelcome.com with SMTP; 4 Jan 2011 18:32:51 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=MBSdT+E6CMUU0qZxxCeafgqxIJQUfrgZ4ZHJ+sI1pA1OE4voVmBQl3NpIWlHGPnsYG0DD11Luv+uMcqn8TNqCSULIc7m/WZrIEshnFA4uXBd0xUWJEbh1CW7ovIAKLKU;
Received: from [216.239.45.4] (port=41407 helo=kkissell.mtv.corp.google.com)
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1PaBh6-00051n-86; Tue, 04 Jan 2011 12:33:16 -0600
Message-ID: <4D2367EE.7000702@paralogos.com>
Date:   Tue, 04 Jan 2011 10:33:18 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101208 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Anoop P A <anoop.pa@gmail.com>
CC:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Subject: Re: SMTC support status in latest git head.
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>      <1293470392.27661.202.camel@paanoop1-desktop>   <1293524389.27661.210.camel@paanoop1-desktop>   <4D19A31E.1090905@paralogos.com>        <1293798476.27661.279.camel@paanoop1-desktop>   <4D1EE913.1070203@paralogos.com>        <1294067561.27661.293.camel@paanoop1-desktop>   <4D21F5D3.50604@paralogos.com>  <1294082426.27661.330.camel@paanoop1-desktop>   <4D22D7B3.2050609@paralogos.com>        <1294146165.27661.361.camel@paanoop1-desktop>   <1294151822.27661.375.camel@paanoop1-desktop>   <4D235717.1000603@paralogos.com> <1294163657.27661.386.camel@paanoop1-desktop>
In-Reply-To: <1294163657.27661.386.camel@paanoop1-desktop>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28823
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

On 01/04/11 09:54, Anoop P A wrote:
> On Tue, 2011-01-04 at 09:21 -0800, Kevin D. Kissell wrote:
>> I'm trying to figure out a reason why your change below should help, and
>> offhand, modulo tool bugs, I don't see it.  I'm assuming that your diff
>> below is a diff relative to the pre-patch stackframe.h.   I wouldn't
> Yes patch created against stock code .
>
>> bless it as an alternative because it moves code and comments
>> unnecessarily - all you should really have to do is to move the
>>
>>
>>    190                 mfc0    v1, CP0_STATUS
>>    191                 LONG_S  $2, PT_R2(sp)
>>
>> to be just after the #endif /* CONFIG_MIPS_MT_SMTC */ at around line 201.
> Actually I just moved code under CONFIG_MIPS_MT_SMTC to previous block
> of code ( which store $0 ) . git diff did the rest on behalf of me :)
>
>> If moving the save of zero to PT_R0(sp) actually makes a difference,
>> it's evidence that you've got problems in your toolchain (or, heaven
>> forbid, your pipeline)!
> In previous version of patch usage of V0 was creating issue. I have
> verified this with previous version of code ( working code before
> David's instruction rearrangement patch.) .

Argh.  It's not very clearly commented, but it looks as if the system 
call trap handler has an implicit assumption that v0 has never been 
changed by SAVE_SOME, TRACE_IRQS_ON_RELOAD, or STI.  So yeah, moving the 
code around to fix the v1 conflict ends up being better than using v0 - 
otherwise, we'd need to add a LONG_L v0, PT_R2(sp) somewhere after the 
LONG_S v0, PT_TCSTATUS(sp) of the original patch.

             Regards,

             Kevin K.

From juhosg@openwrt.org Tue Jan  4 21:29:07 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:29:10 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48500 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490978Ab1ADU3H (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:07 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id BD38345C016;
        Tue,  4 Jan 2011 21:29:01 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 369A21F0001;
        Tue,  4 Jan 2011 21:29:01 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs
Date:   Tue,  4 Jan 2011 21:28:13 +0100
Message-Id: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
X-VBMS: A1089B7A9F5 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28824
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch set contains initial support for the 
Atheros AR71XX/AR724X/AR913X SoCs.

Generic changes since v1:
    - rebased against 2.6.37-rc7
    - the 'MIPS: Add generic support for multiple machines within a single kernel' 
      patch has been removed, because that is in the mips-queue tree already
    - the 'input: add input driver for polled GPIO buttons' patch has been removed, 
      because a slightly different version of that driver is present in 2.6.37-rc7 
      already as 'gpio_keys_polled'

Generic changes since v2:
    - don't use __init for function declarations

Generic changes since v3:
    - rebased against 2.6.37-rc8
    
Generic changes since v4:
    - implement clock API

Gabor Juhos (16):
  MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs
  MIPS: ath79: add GPIOLIB support
  MIPS: ath79: utilize the MIPS multi-machine support
  MIPS: ath79: add initial support for the Atheros PB44 reference board
  MIPS: ath79: add common GPIO LEDs device
  watchdog: add driver for the Atheros AR71XX/AR724X/AR913X SoCs
  MIPS: ath79: add common watchdog device
  MIPS: ath79: add common GPIO buttons device
  spi: add SPI controller driver for the Atheros AR71XX/AR724X/AR913X
    SoCs
  MIPS: ath79: add common SPI controller device
  USB: ehci: add workaround for Synopsys HC bug
  USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR913X SoCs
  USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs
  MIPS: ath79: add common USB Host Controller device
  MIPS: ath79: add initial support for the Atheros AP81 reference board
  MIPS: ath79: add common WMAC device for AR913X based boards

 arch/mips/Kbuild.platforms                         |    1 +
 arch/mips/Kconfig                                  |   17 ++
 arch/mips/ath79/Kconfig                            |   60 ++++
 arch/mips/ath79/Makefile                           |   29 ++
 arch/mips/ath79/Platform                           |    7 +
 arch/mips/ath79/clock.c                            |  183 ++++++++++++
 arch/mips/ath79/common.c                           |   97 +++++++
 arch/mips/ath79/common.h                           |   31 ++
 arch/mips/ath79/dev-ar913x-wmac.c                  |   60 ++++
 arch/mips/ath79/dev-ar913x-wmac.h                  |   17 ++
 arch/mips/ath79/dev-common.c                       |   77 +++++
 arch/mips/ath79/dev-common.h                       |   18 ++
 arch/mips/ath79/dev-gpio-buttons.c                 |   58 ++++
 arch/mips/ath79/dev-gpio-buttons.h                 |   23 ++
 arch/mips/ath79/dev-leds-gpio.c                    |   56 ++++
 arch/mips/ath79/dev-leds-gpio.h                    |   21 ++
 arch/mips/ath79/dev-spi.c                          |   38 +++
 arch/mips/ath79/dev-spi.h                          |   22 ++
 arch/mips/ath79/dev-usb.c                          |  194 +++++++++++++
 arch/mips/ath79/dev-usb.h                          |   17 ++
 arch/mips/ath79/early_printk.c                     |   36 +++
 arch/mips/ath79/gpio.c                             |  197 +++++++++++++
 arch/mips/ath79/irq.c                              |  187 ++++++++++++
 arch/mips/ath79/mach-ap81.c                        |  100 +++++++
 arch/mips/ath79/mach-pb44.c                        |  120 ++++++++
 arch/mips/ath79/machtypes.h                        |   23 ++
 arch/mips/ath79/prom.c                             |   57 ++++
 arch/mips/ath79/setup.c                            |  206 +++++++++++++
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h     |  253 ++++++++++++++++
 arch/mips/include/asm/mach-ath79/ath79.h           |   96 ++++++
 .../include/asm/mach-ath79/ath79_ehci_platform.h   |   18 ++
 .../include/asm/mach-ath79/ath79_spi_platform.h    |   23 ++
 .../include/asm/mach-ath79/cpu-feature-overrides.h |   56 ++++
 arch/mips/include/asm/mach-ath79/gpio.h            |   26 ++
 arch/mips/include/asm/mach-ath79/irq.h             |   36 +++
 .../include/asm/mach-ath79/kernel-entry-init.h     |   32 ++
 arch/mips/include/asm/mach-ath79/war.h             |   25 ++
 drivers/spi/Kconfig                                |    8 +
 drivers/spi/Makefile                               |    1 +
 drivers/spi/ath79_spi.c                            |  292 +++++++++++++++++++
 drivers/usb/host/Kconfig                           |   16 +
 drivers/usb/host/ehci-ath79.c                      |  176 +++++++++++
 drivers/usb/host/ehci-hcd.c                        |    5 +
 drivers/usb/host/ehci-q.c                          |    3 +
 drivers/usb/host/ehci.h                            |    1 +
 drivers/usb/host/ohci-ath79.c                      |  162 +++++++++++
 drivers/usb/host/ohci-hcd.c                        |    5 +
 drivers/watchdog/Kconfig                           |    7 +
 drivers/watchdog/Makefile                          |    1 +
 drivers/watchdog/ath79_wdt.c                       |  305 ++++++++++++++++++++
 50 files changed, 3499 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/Kconfig
 create mode 100644 arch/mips/ath79/Makefile
 create mode 100644 arch/mips/ath79/Platform
 create mode 100644 arch/mips/ath79/clock.c
 create mode 100644 arch/mips/ath79/common.c
 create mode 100644 arch/mips/ath79/common.h
 create mode 100644 arch/mips/ath79/dev-ar913x-wmac.c
 create mode 100644 arch/mips/ath79/dev-ar913x-wmac.h
 create mode 100644 arch/mips/ath79/dev-common.c
 create mode 100644 arch/mips/ath79/dev-common.h
 create mode 100644 arch/mips/ath79/dev-gpio-buttons.c
 create mode 100644 arch/mips/ath79/dev-gpio-buttons.h
 create mode 100644 arch/mips/ath79/dev-leds-gpio.c
 create mode 100644 arch/mips/ath79/dev-leds-gpio.h
 create mode 100644 arch/mips/ath79/dev-spi.c
 create mode 100644 arch/mips/ath79/dev-spi.h
 create mode 100644 arch/mips/ath79/dev-usb.c
 create mode 100644 arch/mips/ath79/dev-usb.h
 create mode 100644 arch/mips/ath79/early_printk.c
 create mode 100644 arch/mips/ath79/gpio.c
 create mode 100644 arch/mips/ath79/irq.c
 create mode 100644 arch/mips/ath79/mach-ap81.c
 create mode 100644 arch/mips/ath79/mach-pb44.c
 create mode 100644 arch/mips/ath79/machtypes.h
 create mode 100644 arch/mips/ath79/prom.c
 create mode 100644 arch/mips/ath79/setup.c
 create mode 100644 arch/mips/include/asm/mach-ath79/ar71xx_regs.h
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79.h
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
 create mode 100644 arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
 create mode 100644 arch/mips/include/asm/mach-ath79/gpio.h
 create mode 100644 arch/mips/include/asm/mach-ath79/irq.h
 create mode 100644 arch/mips/include/asm/mach-ath79/kernel-entry-init.h
 create mode 100644 arch/mips/include/asm/mach-ath79/war.h
 create mode 100644 drivers/spi/ath79_spi.c
 create mode 100644 drivers/usb/host/ehci-ath79.c
 create mode 100644 drivers/usb/host/ohci-ath79.c
 create mode 100644 drivers/watchdog/ath79_wdt.c

-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:29:29 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:29:39 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48508 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490983Ab1ADU3I (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:08 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 335C645C019;
        Tue,  4 Jan 2011 21:29:03 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 82B541F0001;
        Tue,  4 Jan 2011 21:29:01 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 01/16] MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs
Date:   Tue,  4 Jan 2011 21:28:14 +0100
Message-Id: <1294172909-1309-2-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108A0ADE4B | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28825
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds initial support for various Atheros SoCs based on the
MIPS 24Kc core. The following models are supported at the moment:

  - AR7130
  - AR7141
  - AR7161
  - AR9130
  - AR9132
  - AR7240
  - AR7241
  - AR7242

The current patch contains minimal support only, but the resulting
kernel can boot into user-space with using of an initramfs image on
various boards which are using these SoCs. Support for more built-in
devices and individual boards will be implemented in further patches.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC:
    - the ATH79_DEV_UART Kconfig option is removed, and the URT platform
      code has been moved into dev-common[ch]

Changes since v1:
    - ath79_device_{start,stop} has been renamed to ath79_device_reset_{set,clear}
      to to reflect the purpose of these functions better
    - some definitions has been moved from 'arch/mips/ath79/common.h' to
      'arch/mips/include/asm/mach-ath79/ath79.h' to make them available for
      future drivers
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebase against 2.6.37-rc8

Changes since v4:
    - implement clock API

 arch/mips/Kbuild.platforms                         |    1 +
 arch/mips/Kconfig                                  |   15 ++
 arch/mips/ath79/Kconfig                            |   12 ++
 arch/mips/ath79/Makefile                           |   18 ++
 arch/mips/ath79/Platform                           |    7 +
 arch/mips/ath79/clock.c                            |  183 +++++++++++++++++
 arch/mips/ath79/common.c                           |   97 +++++++++
 arch/mips/ath79/common.h                           |   26 +++
 arch/mips/ath79/dev-common.c                       |   67 +++++++
 arch/mips/ath79/dev-common.h                       |   17 ++
 arch/mips/ath79/early_printk.c                     |   36 ++++
 arch/mips/ath79/irq.c                              |  187 ++++++++++++++++++
 arch/mips/ath79/prom.c                             |   57 ++++++
 arch/mips/ath79/setup.c                            |  190 ++++++++++++++++++
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h     |  207 ++++++++++++++++++++
 arch/mips/include/asm/mach-ath79/ath79.h           |   96 +++++++++
 .../include/asm/mach-ath79/cpu-feature-overrides.h |   56 ++++++
 arch/mips/include/asm/mach-ath79/irq.h             |   36 ++++
 .../include/asm/mach-ath79/kernel-entry-init.h     |   32 +++
 arch/mips/include/asm/mach-ath79/war.h             |   25 +++
 20 files changed, 1365 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/Kconfig
 create mode 100644 arch/mips/ath79/Makefile
 create mode 100644 arch/mips/ath79/Platform
 create mode 100644 arch/mips/ath79/clock.c
 create mode 100644 arch/mips/ath79/common.c
 create mode 100644 arch/mips/ath79/common.h
 create mode 100644 arch/mips/ath79/dev-common.c
 create mode 100644 arch/mips/ath79/dev-common.h
 create mode 100644 arch/mips/ath79/early_printk.c
 create mode 100644 arch/mips/ath79/irq.c
 create mode 100644 arch/mips/ath79/prom.c
 create mode 100644 arch/mips/ath79/setup.c
 create mode 100644 arch/mips/include/asm/mach-ath79/ar71xx_regs.h
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79.h
 create mode 100644 arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
 create mode 100644 arch/mips/include/asm/mach-ath79/irq.h
 create mode 100644 arch/mips/include/asm/mach-ath79/kernel-entry-init.h
 create mode 100644 arch/mips/include/asm/mach-ath79/war.h

diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 78439b8..7ff9b54 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -2,6 +2,7 @@
 
 platforms += alchemy
 platforms += ar7
+platforms += ath79
 platforms += bcm47xx
 platforms += bcm63xx
 platforms += cavium-octeon
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 12d0d0f..2e32137 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -66,6 +66,20 @@ config AR7
 	  Support for the Texas Instruments AR7 System-on-a-Chip
 	  family: TNETD7100, 7200 and 7300.
 
+config ATH79
+	bool "Atheros AR71XX/AR724X/AR913X based boards"
+	select BOOT_RAW
+	select CEVT_R4K
+	select CSRC_R4K
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_HAS_EARLY_PRINTK
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+	help
+	  Support for the Atheros AR71XX/AR724X/AR913X SoCs.
+
 config BCM47XX
 	bool "Broadcom BCM47XX based boards"
 	select CEVT_R4K
@@ -718,6 +732,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
 endchoice
 
 source "arch/mips/alchemy/Kconfig"
+source "arch/mips/ath79/Kconfig"
 source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
new file mode 100644
index 0000000..50b9334
--- /dev/null
+++ b/arch/mips/ath79/Kconfig
@@ -0,0 +1,12 @@
+if ATH79
+
+config SOC_AR71XX
+	def_bool n
+
+config SOC_AR724X
+	def_bool n
+
+config SOC_AR913X
+	def_bool n
+
+endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
new file mode 100644
index 0000000..31e0f83
--- /dev/null
+++ b/arch/mips/ath79/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the Atheros AR71XX/AR724X/AR913X specific parts of the kernel
+#
+# Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+
+obj-y	:= prom.o setup.o irq.o common.o clock.o
+
+obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
+
+#
+# Devices
+#
+obj-y					+= dev-common.o
diff --git a/arch/mips/ath79/Platform b/arch/mips/ath79/Platform
new file mode 100644
index 0000000..2bd6636
--- /dev/null
+++ b/arch/mips/ath79/Platform
@@ -0,0 +1,7 @@
+#
+# Atheros AR71xx/AR724x/AR913x
+#
+
+platform-$(CONFIG_ATH79)	+= ath79/
+cflags-$(CONFIG_ATH79)		+= -I$(srctree)/arch/mips/include/asm/mach-ath79
+load-$(CONFIG_ATH79)		= 0xffffffff80060000
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
new file mode 100644
index 0000000..680bde9
--- /dev/null
+++ b/arch/mips/ath79/clock.c
@@ -0,0 +1,183 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common routines
+ *
+ *  Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+#define AR71XX_BASE_FREQ	40000000
+#define AR724X_BASE_FREQ	5000000
+#define AR913X_BASE_FREQ	5000000
+
+struct clk {
+	unsigned long rate;
+};
+
+static struct clk ath79_ref_clk;
+static struct clk ath79_cpu_clk;
+static struct clk ath79_ddr_clk;
+static struct clk ath79_ahb_clk;
+static struct clk ath79_wdt_clk;
+static struct clk ath79_uart_clk;
+
+static void __init ar71xx_clocks_init(void)
+{
+	u32 pll;
+	u32 freq;
+	u32 div;
+
+	ath79_ref_clk.rate = AR71XX_BASE_FREQ;
+
+	pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
+
+	div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
+	freq = div * ath79_ref_clk.rate;
+
+	div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
+	ath79_cpu_clk.rate = freq / div;
+
+	div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
+	ath79_ddr_clk.rate = freq / div;
+
+	div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
+	ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
+
+	ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+	ath79_uart_clk.rate = ath79_ahb_clk.rate;
+}
+
+static void __init ar724x_clocks_init(void)
+{
+	u32 pll;
+	u32 freq;
+	u32 div;
+
+	ath79_ref_clk.rate = AR724X_BASE_FREQ;
+	pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
+
+	div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
+	freq = div * ath79_ref_clk.rate;
+
+	div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
+	freq *= div;
+
+	ath79_cpu_clk.rate = freq;
+
+	div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
+	ath79_ddr_clk.rate = freq / div;
+
+	div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
+	ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
+
+	ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+	ath79_uart_clk.rate = ath79_ahb_clk.rate;
+}
+
+static void __init ar913x_clocks_init(void)
+{
+	u32 pll;
+	u32 freq;
+	u32 div;
+
+	ath79_ref_clk.rate = AR913X_BASE_FREQ;
+	pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
+
+	div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK);
+	freq = div * ath79_ref_clk.rate;
+
+	ath79_cpu_clk.rate = freq;
+
+	div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1;
+	ath79_ddr_clk.rate = freq / div;
+
+	div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2;
+	ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
+
+	ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+	ath79_uart_clk.rate = ath79_ahb_clk.rate;
+}
+
+void __init ath79_clocks_init(void)
+{
+	if (soc_is_ar71xx())
+		ar71xx_clocks_init();
+	else if (soc_is_ar724x())
+		ar724x_clocks_init();
+	else if (soc_is_ar913x())
+		ar913x_clocks_init();
+	else
+		BUG();
+
+	pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, "
+		"Ref:%lu.%03luMHz",
+		ath79_cpu_clk.rate / 1000000,
+		(ath79_cpu_clk.rate / 1000) % 1000,
+		ath79_ddr_clk.rate / 1000000,
+		(ath79_ddr_clk.rate / 1000) % 1000,
+		ath79_ahb_clk.rate / 1000000,
+		(ath79_ahb_clk.rate / 1000) % 1000,
+		ath79_ref_clk.rate / 1000000,
+		(ath79_ref_clk.rate / 1000) % 1000);
+}
+
+/*
+ * Linux clock API
+ */
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	if (!strcmp(id, "ref"))
+		return &ath79_ref_clk;
+
+	if (!strcmp(id, "cpu"))
+		return &ath79_cpu_clk;
+
+	if (!strcmp(id, "ddr"))
+		return &ath79_ddr_clk;
+
+	if (!strcmp(id, "ahb"))
+		return &ath79_ahb_clk;
+
+	if (!strcmp(id, "wdt"))
+		return &ath79_wdt_clk;
+
+	if (!strcmp(id, "uart"))
+		return &ath79_uart_clk;
+
+	return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
new file mode 100644
index 0000000..58f60e7
--- /dev/null
+++ b/arch/mips/ath79/common.c
@@ -0,0 +1,97 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common routines
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static DEFINE_SPINLOCK(ath79_device_reset_lock);
+
+u32 ath79_cpu_freq;
+EXPORT_SYMBOL_GPL(ath79_cpu_freq);
+
+u32 ath79_ahb_freq;
+EXPORT_SYMBOL_GPL(ath79_ahb_freq);
+
+u32 ath79_ddr_freq;
+EXPORT_SYMBOL_GPL(ath79_ddr_freq);
+
+enum ath79_soc_type ath79_soc;
+
+void __iomem *ath79_pll_base;
+void __iomem *ath79_reset_base;
+EXPORT_SYMBOL_GPL(ath79_reset_base);
+void __iomem *ath79_ddr_base;
+
+void ath79_ddr_wb_flush(u32 reg)
+{
+	void __iomem *flush_reg = ath79_ddr_base + reg;
+
+	/* Flush the DDR write buffer. */
+	__raw_writel(0x1, flush_reg);
+	while (__raw_readl(flush_reg) & 0x1)
+		;
+
+	/* It must be run twice. */
+	__raw_writel(0x1, flush_reg);
+	while (__raw_readl(flush_reg) & 0x1)
+		;
+}
+EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush);
+
+void ath79_device_reset_set(u32 mask)
+{
+	unsigned long flags;
+	u32 reg;
+	u32 t;
+
+	if (soc_is_ar71xx())
+		reg = AR71XX_RESET_REG_RESET_MODULE;
+	else if (soc_is_ar724x())
+		reg = AR724X_RESET_REG_RESET_MODULE;
+	else if (soc_is_ar913x())
+		reg = AR913X_RESET_REG_RESET_MODULE;
+	else
+		BUG();
+
+	spin_lock_irqsave(&ath79_device_reset_lock, flags);
+	t = ath79_reset_rr(reg);
+	ath79_reset_wr(reg, t | mask);
+	spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_set);
+
+void ath79_device_reset_clear(u32 mask)
+{
+	unsigned long flags;
+	u32 reg;
+	u32 t;
+
+	if (soc_is_ar71xx())
+		reg = AR71XX_RESET_REG_RESET_MODULE;
+	else if (soc_is_ar724x())
+		reg = AR724X_RESET_REG_RESET_MODULE;
+	else if (soc_is_ar913x())
+		reg = AR913X_RESET_REG_RESET_MODULE;
+	else
+		BUG();
+
+	spin_lock_irqsave(&ath79_device_reset_lock, flags);
+	t = ath79_reset_rr(reg);
+	ath79_reset_wr(reg, t & ~mask);
+	spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_clear);
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
new file mode 100644
index 0000000..612a6b5
--- /dev/null
+++ b/arch/mips/ath79/common.h
@@ -0,0 +1,26 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef __ATH79_COMMON_H
+#define __ATH79_COMMON_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#define ATH79_MEM_SIZE_MIN	(2 * 1024 * 1024)
+#define ATH79_MEM_SIZE_MAX	(128 * 1024 * 1024)
+
+void ath79_clocks_init(void);
+void ath79_ddr_wb_flush(unsigned int reg);
+
+#endif /* __ATH79_COMMON_H */
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
new file mode 100644
index 0000000..3cfa100
--- /dev/null
+++ b/arch/mips/ath79/dev-common.c
@@ -0,0 +1,67 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common devices
+ *
+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+
+static struct resource ath79_uart_resources[] = {
+	{
+		.start	= AR71XX_UART_BASE,
+		.end	= AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+static struct plat_serial8250_port ath79_uart_data[] = {
+	{
+		.mapbase	= AR71XX_UART_BASE,
+		.irq		= ATH79_MISC_IRQ_UART,
+		.flags		= AR71XX_UART_FLAGS,
+		.iotype		= UPIO_MEM32,
+		.regshift	= 2,
+	}, {
+		/* terminating entry */
+	}
+};
+
+static struct platform_device ath79_uart_device = {
+	.name		= "serial8250",
+	.id		= PLAT8250_DEV_PLATFORM,
+	.resource	= ath79_uart_resources,
+	.num_resources	= ARRAY_SIZE(ath79_uart_resources),
+	.dev = {
+		.platform_data	= ath79_uart_data
+	},
+};
+
+void __init ath79_register_uart(void)
+{
+	struct clk *clk;
+
+	clk = clk_get(NULL, "uart");
+	if (IS_ERR(clk))
+		panic("unable to get UART clock, err=%ld", PTR_ERR(clk));
+
+	ath79_uart_data[0].uartclk = clk_get_rate(clk);
+	platform_device_register(&ath79_uart_device);
+}
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
new file mode 100644
index 0000000..248622c
--- /dev/null
+++ b/arch/mips/ath79/dev-common.h
@@ -0,0 +1,17 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common devices
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_COMMON_H
+#define _ATH79_DEV_COMMON_H
+
+void ath79_register_uart(void);
+
+#endif /* _ATH79_DEV_COMMON_H */
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
new file mode 100644
index 0000000..7499b0e
--- /dev/null
+++ b/arch/mips/ath79/early_printk.c
@@ -0,0 +1,36 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X SoC early printk support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+#include <asm/addrspace.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+static inline void prom_wait_thre(void __iomem *base)
+{
+	u32 lsr;
+
+	do {
+		lsr = __raw_readl(base + UART_LSR * 4);
+		if (lsr & UART_LSR_THRE)
+			break;
+	} while (1);
+}
+
+void prom_putchar(unsigned char ch)
+{
+	void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
+
+	prom_wait_thre(base);
+	__raw_writel(ch, base + UART_TX * 4);
+	prom_wait_thre(base);
+}
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
new file mode 100644
index 0000000..1bf7f71
--- /dev/null
+++ b/arch/mips/ath79/irq.c
@@ -0,0 +1,187 @@
+/*
+ *  Atheros AR71xx/AR724x/AR913x specific interrupt handling
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static unsigned int ath79_ip2_flush_reg;
+static unsigned int ath79_ip3_flush_reg;
+
+static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	void __iomem *base = ath79_reset_base;
+	u32 pending;
+
+	pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
+		  __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	if (pending & MISC_INT_UART)
+		generic_handle_irq(ATH79_MISC_IRQ_UART);
+
+	else if (pending & MISC_INT_DMA)
+		generic_handle_irq(ATH79_MISC_IRQ_DMA);
+
+	else if (pending & MISC_INT_PERFC)
+		generic_handle_irq(ATH79_MISC_IRQ_PERFC);
+
+	else if (pending & MISC_INT_TIMER)
+		generic_handle_irq(ATH79_MISC_IRQ_TIMER);
+
+	else if (pending & MISC_INT_OHCI)
+		generic_handle_irq(ATH79_MISC_IRQ_OHCI);
+
+	else if (pending & MISC_INT_ERROR)
+		generic_handle_irq(ATH79_MISC_IRQ_ERROR);
+
+	else if (pending & MISC_INT_GPIO)
+		generic_handle_irq(ATH79_MISC_IRQ_GPIO);
+
+	else if (pending & MISC_INT_WDOG)
+		generic_handle_irq(ATH79_MISC_IRQ_WDOG);
+
+	else
+		spurious_interrupt();
+}
+
+static void ar71xx_misc_irq_unmask(unsigned int irq)
+{
+	void __iomem *base = ath79_reset_base;
+	u32 t;
+
+	irq -= ATH79_MISC_IRQ_BASE;
+
+	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+	__raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	/* flush write */
+	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar71xx_misc_irq_mask(unsigned int irq)
+{
+	void __iomem *base = ath79_reset_base;
+	u32 t;
+
+	irq -= ATH79_MISC_IRQ_BASE;
+
+	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+	__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	/* flush write */
+	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar724x_misc_irq_ack(unsigned int irq)
+{
+	void __iomem *base = ath79_reset_base;
+	u32 t;
+
+	irq -= ATH79_MISC_IRQ_BASE;
+
+	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+	__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+	/* flush write */
+	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+}
+
+static struct irq_chip ath79_misc_irq_chip = {
+	.name		= "MISC",
+	.unmask		= ar71xx_misc_irq_unmask,
+	.mask		= ar71xx_misc_irq_mask,
+};
+
+static void __init ath79_misc_irq_init(void)
+{
+	void __iomem *base = ath79_reset_base;
+	int i;
+
+	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+	if (soc_is_ar71xx() || soc_is_ar913x())
+		ath79_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask;
+	else if (soc_is_ar724x())
+		ath79_misc_irq_chip.ack = ar724x_misc_irq_ack;
+	else
+		BUG();
+
+	for (i = ATH79_MISC_IRQ_BASE;
+	     i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		set_irq_chip_and_handler(i, &ath79_misc_irq_chip,
+					 handle_level_irq);
+	}
+
+	set_irq_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned long pending;
+
+	pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+	if (pending & STATUSF_IP7)
+		do_IRQ(ATH79_CPU_IRQ_TIMER);
+
+	else if (pending & STATUSF_IP2) {
+		ath79_ddr_wb_flush(ath79_ip2_flush_reg);
+		do_IRQ(ATH79_CPU_IRQ_IP2);
+	}
+
+	else if (pending & STATUSF_IP4)
+		do_IRQ(ATH79_CPU_IRQ_GE0);
+
+	else if (pending & STATUSF_IP5)
+		do_IRQ(ATH79_CPU_IRQ_GE1);
+
+	else if (pending & STATUSF_IP3) {
+		ath79_ddr_wb_flush(ath79_ip3_flush_reg);
+		do_IRQ(ATH79_CPU_IRQ_USB);
+	}
+
+	else if (pending & STATUSF_IP6)
+		do_IRQ(ATH79_CPU_IRQ_MISC);
+
+	else
+		spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+	if (soc_is_ar71xx()) {
+		ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
+		ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB;
+	} else if (soc_is_ar724x()) {
+		ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
+		ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB;
+	} else if (soc_is_ar913x()) {
+		ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
+		ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
+	} else
+		BUG();
+
+	cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
+	mips_cpu_irq_init();
+	ath79_misc_irq_init();
+}
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c
new file mode 100644
index 0000000..e9cbd7c
--- /dev/null
+++ b/arch/mips/ath79/prom.c
@@ -0,0 +1,57 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X specific prom routines
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+#include "common.h"
+
+static inline int is_valid_ram_addr(void *addr)
+{
+	if (((u32) addr > KSEG0) &&
+	    ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX)))
+		return 1;
+
+	if (((u32) addr > KSEG1) &&
+	    ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX)))
+		return 1;
+
+	return 0;
+}
+
+static __init void ath79_prom_init_cmdline(int argc, char **argv)
+{
+	int i;
+
+	if (!is_valid_ram_addr(argv))
+		return;
+
+	for (i = 0; i < argc; i++)
+		if (is_valid_ram_addr(argv[i])) {
+			strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+			strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
+		}
+}
+
+void __init prom_init(void)
+{
+	ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
+}
+
+void __init prom_free_prom_memory(void)
+{
+	/* We do not have to prom memory to free */
+}
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
new file mode 100644
index 0000000..175def8
--- /dev/null
+++ b/arch/mips/ath79/setup.c
@@ -0,0 +1,190 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X specific setup
+ *
+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h>		/* for mips_hpt_frequency */
+#include <asm/reboot.h>		/* for _machine_{restart,halt} */
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+
+#define ATH79_SYS_TYPE_LEN	64
+
+#define AR71XX_BASE_FREQ	40000000
+#define AR724X_BASE_FREQ	5000000
+#define AR913X_BASE_FREQ	5000000
+
+static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
+
+static void ath79_restart(char *command)
+{
+	ath79_device_reset_set(AR71XX_RESET_FULL_CHIP);
+	for (;;)
+		if (cpu_wait)
+			cpu_wait();
+}
+
+static void ath79_halt(void)
+{
+	while (1)
+		cpu_wait();
+}
+
+static void __init ath79_detect_mem_size(void)
+{
+	unsigned long size;
+
+	for (size = ATH79_MEM_SIZE_MIN; size < ATH79_MEM_SIZE_MAX;
+	     size <<= 1) {
+		if (!memcmp(ath79_detect_mem_size,
+			    ath79_detect_mem_size + size, 1024))
+			break;
+	}
+
+	add_memory_region(0, size, BOOT_MEM_RAM);
+}
+
+static void __init ath79_detect_sys_type(void)
+{
+	char *chip = "????";
+	u32 id;
+	u32 major;
+	u32 minor;
+	u32 rev = 0;
+
+	id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
+	major = id & REV_ID_MAJOR_MASK;
+
+	switch (major) {
+	case REV_ID_MAJOR_AR71XX:
+		minor = id & AR71XX_REV_ID_MINOR_MASK;
+		rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
+		rev &= AR71XX_REV_ID_REVISION_MASK;
+		switch (minor) {
+		case AR71XX_REV_ID_MINOR_AR7130:
+			ath79_soc = ATH79_SOC_AR7130;
+			chip = "7130";
+			break;
+
+		case AR71XX_REV_ID_MINOR_AR7141:
+			ath79_soc = ATH79_SOC_AR7141;
+			chip = "7141";
+			break;
+
+		case AR71XX_REV_ID_MINOR_AR7161:
+			ath79_soc = ATH79_SOC_AR7161;
+			chip = "7161";
+			break;
+		}
+		break;
+
+	case REV_ID_MAJOR_AR7240:
+		ath79_soc = ATH79_SOC_AR7240;
+		chip = "7240";
+		rev = (id & AR724X_REV_ID_REVISION_MASK);
+		break;
+
+	case REV_ID_MAJOR_AR7241:
+		ath79_soc = ATH79_SOC_AR7241;
+		chip = "7241";
+		rev = (id & AR724X_REV_ID_REVISION_MASK);
+		break;
+
+	case REV_ID_MAJOR_AR7242:
+		ath79_soc = ATH79_SOC_AR7242;
+		chip = "7242";
+		rev = (id & AR724X_REV_ID_REVISION_MASK);
+		break;
+
+	case REV_ID_MAJOR_AR913X:
+		minor = id & AR913X_REV_ID_MINOR_MASK;
+		rev = id >> AR913X_REV_ID_REVISION_SHIFT;
+		rev &= AR913X_REV_ID_REVISION_MASK;
+		switch (minor) {
+		case AR913X_REV_ID_MINOR_AR9130:
+			ath79_soc = ATH79_SOC_AR9130;
+			chip = "9130";
+			break;
+
+		case AR913X_REV_ID_MINOR_AR9132:
+			ath79_soc = ATH79_SOC_AR9132;
+			chip = "9132";
+			break;
+		}
+		break;
+
+	default:
+		panic("ath79: unknown SoC, id:0x%08x\n", id);
+	}
+
+	sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
+	pr_info("SoC: %s\n", ath79_sys_type);
+}
+
+const char *get_system_type(void)
+{
+	return ath79_sys_type;
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+	return CP0_LEGACY_COMPARE_IRQ;
+}
+
+void __init plat_mem_setup(void)
+{
+	set_io_port_base(KSEG1);
+
+	ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
+					   AR71XX_RESET_SIZE);
+	ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
+					 AR71XX_PLL_SIZE);
+
+	ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
+					 AR71XX_DDR_CTRL_SIZE);
+
+	ath79_detect_sys_type();
+	ath79_detect_mem_size();
+	ath79_clocks_init();
+
+	_machine_restart = ath79_restart;
+	_machine_halt = ath79_halt;
+	pm_power_off = ath79_halt;
+}
+
+void __init plat_time_init(void)
+{
+	struct clk *clk;
+
+	clk = clk_get(NULL, "cpu");
+	if (IS_ERR(clk))
+		panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
+
+	mips_hpt_frequency = clk_get_rate(clk) / 2;
+}
+
+static int __init ath79_setup(void)
+{
+	ath79_register_uart();
+	return 0;
+}
+
+arch_initcall(ath79_setup);
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
new file mode 100644
index 0000000..5a9e5e1
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -0,0 +1,207 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X SoC register definitions
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_AR71XX_REGS_H
+#define __ASM_MACH_AR71XX_REGS_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+
+#define AR71XX_APB_BASE		0x18000000
+
+#define AR71XX_DDR_CTRL_BASE	(AR71XX_APB_BASE + 0x00000000)
+#define AR71XX_DDR_CTRL_SIZE	0x100
+#define AR71XX_UART_BASE	(AR71XX_APB_BASE + 0x00020000)
+#define AR71XX_UART_SIZE	0x100
+#define AR71XX_PLL_BASE		(AR71XX_APB_BASE + 0x00050000)
+#define AR71XX_PLL_SIZE		0x100
+#define AR71XX_RESET_BASE	(AR71XX_APB_BASE + 0x00060000)
+#define AR71XX_RESET_SIZE	0x100
+
+/*
+ * DDR_CTRL block
+ */
+#define AR71XX_DDR_REG_PCI_WIN0		0x7c
+#define AR71XX_DDR_REG_PCI_WIN1		0x80
+#define AR71XX_DDR_REG_PCI_WIN2		0x84
+#define AR71XX_DDR_REG_PCI_WIN3		0x88
+#define AR71XX_DDR_REG_PCI_WIN4		0x8c
+#define AR71XX_DDR_REG_PCI_WIN5		0x90
+#define AR71XX_DDR_REG_PCI_WIN6		0x94
+#define AR71XX_DDR_REG_PCI_WIN7		0x98
+#define AR71XX_DDR_REG_FLUSH_GE0	0x9c
+#define AR71XX_DDR_REG_FLUSH_GE1	0xa0
+#define AR71XX_DDR_REG_FLUSH_USB	0xa4
+#define AR71XX_DDR_REG_FLUSH_PCI	0xa8
+
+#define AR724X_DDR_REG_FLUSH_GE0	0x7c
+#define AR724X_DDR_REG_FLUSH_GE1	0x80
+#define AR724X_DDR_REG_FLUSH_USB	0x84
+#define AR724X_DDR_REG_FLUSH_PCIE	0x88
+
+#define AR913X_DDR_REG_FLUSH_GE0	0x7c
+#define AR913X_DDR_REG_FLUSH_GE1	0x80
+#define AR913X_DDR_REG_FLUSH_USB	0x84
+#define AR913X_DDR_REG_FLUSH_WMAC	0x88
+
+/*
+ * PLL block
+ */
+#define AR71XX_PLL_REG_CPU_CONFIG	0x00
+#define AR71XX_PLL_REG_SEC_CONFIG	0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK	0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK	0x14
+
+#define AR71XX_PLL_DIV_SHIFT		3
+#define AR71XX_PLL_DIV_MASK		0x1f
+#define AR71XX_CPU_DIV_SHIFT		16
+#define AR71XX_CPU_DIV_MASK		0x3
+#define AR71XX_DDR_DIV_SHIFT		18
+#define AR71XX_DDR_DIV_MASK		0x3
+#define AR71XX_AHB_DIV_SHIFT		20
+#define AR71XX_AHB_DIV_MASK		0x7
+
+#define AR724X_PLL_REG_CPU_CONFIG	0x00
+#define AR724X_PLL_REG_PCIE_CONFIG	0x18
+
+#define AR724X_PLL_DIV_SHIFT		0
+#define AR724X_PLL_DIV_MASK		0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT	10
+#define AR724X_PLL_REF_DIV_MASK		0xf
+#define AR724X_AHB_DIV_SHIFT		19
+#define AR724X_AHB_DIV_MASK		0x1
+#define AR724X_DDR_DIV_SHIFT		22
+#define AR724X_DDR_DIV_MASK		0x3
+
+#define AR913X_PLL_REG_CPU_CONFIG	0x00
+#define AR913X_PLL_REG_ETH_CONFIG	0x04
+#define AR913X_PLL_REG_ETH0_INT_CLOCK	0x14
+#define AR913X_PLL_REG_ETH1_INT_CLOCK	0x18
+
+#define AR913X_PLL_DIV_SHIFT		0
+#define AR913X_PLL_DIV_MASK		0x3ff
+#define AR913X_DDR_DIV_SHIFT		22
+#define AR913X_DDR_DIV_MASK		0x3
+#define AR913X_AHB_DIV_SHIFT		19
+#define AR913X_AHB_DIV_MASK		0x1
+
+/*
+ * RESET block
+ */
+#define AR71XX_RESET_REG_TIMER			0x00
+#define AR71XX_RESET_REG_TIMER_RELOAD		0x04
+#define AR71XX_RESET_REG_WDOG_CTRL		0x08
+#define AR71XX_RESET_REG_WDOG			0x0c
+#define AR71XX_RESET_REG_MISC_INT_STATUS	0x10
+#define AR71XX_RESET_REG_MISC_INT_ENABLE	0x14
+#define AR71XX_RESET_REG_PCI_INT_STATUS		0x18
+#define AR71XX_RESET_REG_PCI_INT_ENABLE		0x1c
+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS	0x20
+#define AR71XX_RESET_REG_RESET_MODULE		0x24
+#define AR71XX_RESET_REG_PERFC_CTRL		0x2c
+#define AR71XX_RESET_REG_PERFC0			0x30
+#define AR71XX_RESET_REG_PERFC1			0x34
+#define AR71XX_RESET_REG_REV_ID			0x90
+
+#define AR913X_RESET_REG_GLOBAL_INT_STATUS	0x18
+#define AR913X_RESET_REG_RESET_MODULE		0x1c
+#define AR913X_RESET_REG_PERF_CTRL		0x20
+#define AR913X_RESET_REG_PERFC0			0x24
+#define AR913X_RESET_REG_PERFC1			0x28
+
+#define AR724X_RESET_REG_RESET_MODULE		0x1c
+
+#define MISC_INT_DMA			BIT(7)
+#define MISC_INT_OHCI			BIT(6)
+#define MISC_INT_PERFC			BIT(5)
+#define MISC_INT_WDOG			BIT(4)
+#define MISC_INT_UART			BIT(3)
+#define MISC_INT_GPIO			BIT(2)
+#define MISC_INT_ERROR			BIT(1)
+#define MISC_INT_TIMER			BIT(0)
+
+#define AR71XX_RESET_EXTERNAL		BIT(28)
+#define AR71XX_RESET_FULL_CHIP		BIT(24)
+#define AR71XX_RESET_CPU_NMI		BIT(21)
+#define AR71XX_RESET_CPU_COLD		BIT(20)
+#define AR71XX_RESET_DMA		BIT(19)
+#define AR71XX_RESET_SLIC		BIT(18)
+#define AR71XX_RESET_STEREO		BIT(17)
+#define AR71XX_RESET_DDR		BIT(16)
+#define AR71XX_RESET_GE1_MAC		BIT(13)
+#define AR71XX_RESET_GE1_PHY		BIT(12)
+#define AR71XX_RESET_USBSUS_OVERRIDE	BIT(10)
+#define AR71XX_RESET_GE0_MAC		BIT(9)
+#define AR71XX_RESET_GE0_PHY		BIT(8)
+#define AR71XX_RESET_USB_OHCI_DLL	BIT(6)
+#define AR71XX_RESET_USB_HOST		BIT(5)
+#define AR71XX_RESET_USB_PHY		BIT(4)
+#define AR71XX_RESET_PCI_BUS		BIT(1)
+#define AR71XX_RESET_PCI_CORE		BIT(0)
+
+#define AR724X_RESET_GE1_MDIO		BIT(23)
+#define AR724X_RESET_GE0_MDIO		BIT(22)
+#define AR724X_RESET_PCIE_PHY_SERIAL	BIT(10)
+#define AR724X_RESET_PCIE_PHY		BIT(7)
+#define AR724X_RESET_PCIE		BIT(6)
+#define AR724X_RESET_OHCI_DLL		BIT(3)
+
+#define AR913X_RESET_AMBA2WMAC		BIT(22)
+
+#define REV_ID_MAJOR_MASK		0xfff0
+#define REV_ID_MAJOR_AR71XX		0x00a0
+#define REV_ID_MAJOR_AR913X		0x00b0
+#define REV_ID_MAJOR_AR7240		0x00c0
+#define REV_ID_MAJOR_AR7241		0x0100
+#define REV_ID_MAJOR_AR7242		0x1100
+
+#define AR71XX_REV_ID_MINOR_MASK	0x3
+#define AR71XX_REV_ID_MINOR_AR7130	0x0
+#define AR71XX_REV_ID_MINOR_AR7141	0x1
+#define AR71XX_REV_ID_MINOR_AR7161	0x2
+#define AR71XX_REV_ID_REVISION_MASK	0x3
+#define AR71XX_REV_ID_REVISION_SHIFT	2
+
+#define AR913X_REV_ID_MINOR_MASK	0x3
+#define AR913X_REV_ID_MINOR_AR9130	0x0
+#define AR913X_REV_ID_MINOR_AR9132	0x1
+#define AR913X_REV_ID_REVISION_MASK	0x3
+#define AR913X_REV_ID_REVISION_SHIFT	2
+
+#define AR724X_REV_ID_REVISION_MASK	0x3
+
+/*
+ * SPI block
+ */
+#define AR71XX_SPI_REG_FS	0x00	/* Function Select */
+#define AR71XX_SPI_REG_CTRL	0x04	/* SPI Control */
+#define AR71XX_SPI_REG_IOC	0x08	/* SPI I/O Control */
+#define AR71XX_SPI_REG_RDS	0x0c	/* Read Data Shift */
+
+#define AR71XX_SPI_FS_GPIO	BIT(0)	/* Enable GPIO mode */
+
+#define AR71XX_SPI_CTRL_RD	BIT(6)	/* Remap Disable */
+#define AR71XX_SPI_CTRL_DIV_MASK 0x3f
+
+#define AR71XX_SPI_IOC_DO	BIT(0)	/* Data Out pin */
+#define AR71XX_SPI_IOC_CLK	BIT(8)	/* CLK pin */
+#define AR71XX_SPI_IOC_CS(n)	BIT(16 + (n))
+#define AR71XX_SPI_IOC_CS0	AR71XX_SPI_IOC_CS(0)
+#define AR71XX_SPI_IOC_CS1	AR71XX_SPI_IOC_CS(1)
+#define AR71XX_SPI_IOC_CS2	AR71XX_SPI_IOC_CS(2)
+#define AR71XX_SPI_IOC_CS_ALL	(AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \
+				 AR71XX_SPI_IOC_CS2)
+
+#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
new file mode 100644
index 0000000..6a9f168
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -0,0 +1,96 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_ATH79_H
+#define __ASM_MACH_ATH79_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+enum ath79_soc_type {
+	ATH79_SOC_UNKNOWN,
+	ATH79_SOC_AR7130,
+	ATH79_SOC_AR7141,
+	ATH79_SOC_AR7161,
+	ATH79_SOC_AR7240,
+	ATH79_SOC_AR7241,
+	ATH79_SOC_AR7242,
+	ATH79_SOC_AR9130,
+	ATH79_SOC_AR9132
+};
+
+extern enum ath79_soc_type ath79_soc;
+
+static inline int soc_is_ar71xx(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7130 ||
+		ath79_soc == ATH79_SOC_AR7141 ||
+		ath79_soc == ATH79_SOC_AR7161);
+}
+
+static inline int soc_is_ar724x(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7240 ||
+		ath79_soc == ATH79_SOC_AR7241 ||
+		ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar7240(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7240);
+}
+
+static inline int soc_is_ar7241(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7241);
+}
+
+static inline int soc_is_ar7242(void)
+{
+	return (ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar913x(void)
+{
+	return (ath79_soc == ATH79_SOC_AR9130 ||
+		ath79_soc == ATH79_SOC_AR9132);
+}
+
+extern void __iomem *ath79_ddr_base;
+extern void __iomem *ath79_pll_base;
+extern void __iomem *ath79_reset_base;
+
+static inline void ath79_pll_wr(unsigned reg, u32 val)
+{
+	__raw_writel(val, ath79_pll_base + reg);
+}
+
+static inline u32 ath79_pll_rr(unsigned reg)
+{
+	return __raw_readl(ath79_pll_base + reg);
+}
+
+static inline void ath79_reset_wr(unsigned reg, u32 val)
+{
+	__raw_writel(val, ath79_reset_base + reg);
+}
+
+static inline u32 ath79_reset_rr(unsigned reg)
+{
+	return __raw_readl(ath79_reset_base + reg);
+}
+
+void ath79_device_reset_set(u32 mask);
+void ath79_device_reset_clear(u32 mask);
+
+#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
new file mode 100644
index 0000000..4476fa0
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
@@ -0,0 +1,56 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X specific CPU feature overrides
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This file was derived from: include/asm-mips/cpu-features.h
+ *	Copyright (C) 2003, 2004 Ralf Baechle
+ *	Copyright (C) 2004 Maciej W. Rozycki
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb		1
+#define cpu_has_4kex		1
+#define cpu_has_3k_cache	0
+#define cpu_has_4k_cache	1
+#define cpu_has_tx39_cache	0
+#define cpu_has_sb1_cache	0
+#define cpu_has_fpu		0
+#define cpu_has_32fpr		0
+#define cpu_has_counter		1
+#define cpu_has_watch		1
+#define cpu_has_divec		1
+
+#define cpu_has_prefetch	1
+#define cpu_has_ejtag		1
+#define cpu_has_llsc		1
+
+#define cpu_has_mips16		1
+#define cpu_has_mdmx		0
+#define cpu_has_mips3d		0
+#define cpu_has_smartmips	0
+
+#define cpu_has_mips32r1	1
+#define cpu_has_mips32r2	1
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
+#define cpu_has_dsp		0
+#define cpu_has_mipsmt		0
+
+#define cpu_has_64bits		0
+#define cpu_has_64bit_zero_reg	0
+#define cpu_has_64bit_gp_regs	0
+#define cpu_has_64bit_addresses	0
+
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	32
+
+#endif /* __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h
new file mode 100644
index 0000000..189bc6e
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/irq.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_ATH79_IRQ_H
+#define __ASM_MACH_ATH79_IRQ_H
+
+#define MIPS_CPU_IRQ_BASE	0
+#define NR_IRQS			16
+
+#define ATH79_MISC_IRQ_BASE	8
+#define ATH79_MISC_IRQ_COUNT	8
+
+#define ATH79_CPU_IRQ_IP2	(MIPS_CPU_IRQ_BASE + 2)
+#define ATH79_CPU_IRQ_USB	(MIPS_CPU_IRQ_BASE + 3)
+#define ATH79_CPU_IRQ_GE0	(MIPS_CPU_IRQ_BASE + 4)
+#define ATH79_CPU_IRQ_GE1	(MIPS_CPU_IRQ_BASE + 5)
+#define ATH79_CPU_IRQ_MISC	(MIPS_CPU_IRQ_BASE + 6)
+#define ATH79_CPU_IRQ_TIMER	(MIPS_CPU_IRQ_BASE + 7)
+
+#define ATH79_MISC_IRQ_TIMER	(ATH79_MISC_IRQ_BASE + 0)
+#define ATH79_MISC_IRQ_ERROR	(ATH79_MISC_IRQ_BASE + 1)
+#define ATH79_MISC_IRQ_GPIO	(ATH79_MISC_IRQ_BASE + 2)
+#define ATH79_MISC_IRQ_UART	(ATH79_MISC_IRQ_BASE + 3)
+#define ATH79_MISC_IRQ_WDOG	(ATH79_MISC_IRQ_BASE + 4)
+#define ATH79_MISC_IRQ_PERFC	(ATH79_MISC_IRQ_BASE + 5)
+#define ATH79_MISC_IRQ_OHCI	(ATH79_MISC_IRQ_BASE + 6)
+#define ATH79_MISC_IRQ_DMA	(ATH79_MISC_IRQ_BASE + 7)
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_ATH79_IRQ_H */
diff --git a/arch/mips/include/asm/mach-ath79/kernel-entry-init.h b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
new file mode 100644
index 0000000..d8d046b
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
@@ -0,0 +1,32 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X specific kernel entry setup
+ *
+ *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MACH_ATH79_KERNEL_ENTRY_H
+#define __ASM_MACH_ATH79_KERNEL_ENTRY_H
+
+	/*
+	 * Some bootloaders set the 'Kseg0 coherency algorithm' to
+	 * 'Cacheable, noncoherent, write-through, no write allocate'
+	 * and this cause performance issues. Let's go and change it to
+	 * 'Cacheable, noncoherent, write-back, write allocate'
+	 */
+	.macro	kernel_entry_setup
+	mfc0	t0, CP0_CONFIG
+	li	t1, ~CONF_CM_CMASK
+	and	t0, t1
+	ori	t0, CONF_CM_CACHABLE_NONCOHERENT
+	mtc0	t0, CP0_CONFIG
+	nop
+	.endm
+
+	.macro	smp_slave_setup
+	.endm
+
+#endif /* __ASM_MACH_ATH79_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-ath79/war.h b/arch/mips/include/asm/mach-ath79/war.h
new file mode 100644
index 0000000..323d9f1
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/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_MACH_ATH79_WAR_H
+#define __ASM_MACH_ATH79_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			0
+#define MIPS34K_MISSED_ITLB_WAR		0
+
+#endif /* __ASM_MACH_ATH79_WAR_H */
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:29:58 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:30:05 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48514 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490984Ab1ADU3I (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:08 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 5620745C01B;
        Tue,  4 Jan 2011 21:29:03 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id B59A91F0001;
        Tue,  4 Jan 2011 21:29:02 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>
Subject: [PATCH v5 02/16] MIPS: ath79: add GPIOLIB support
Date:   Tue,  4 Jan 2011 21:28:15 +0100
Message-Id: <1294172909-1309-3-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108A315264 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28826
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch implements generic GPIO routines for the built-in
GPIO controllers of the Atheros AR71XX/AR724X/AR913X SoCs.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4:
    - remove __init from the declaration of ath79_gpio_init

 arch/mips/Kconfig                              |    1 +
 arch/mips/ath79/Makefile                       |    2 +-
 arch/mips/ath79/common.h                       |    5 +
 arch/mips/ath79/gpio.c                         |  197 ++++++++++++++++++++++++
 arch/mips/ath79/setup.c                        |    2 +-
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h |   21 +++
 arch/mips/include/asm/mach-ath79/gpio.h        |   26 +++
 7 files changed, 252 insertions(+), 2 deletions(-)
 create mode 100644 arch/mips/ath79/gpio.c
 create mode 100644 arch/mips/include/asm/mach-ath79/gpio.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2e32137..944845a 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -68,6 +68,7 @@ config AR7
 
 config ATH79
 	bool "Atheros AR71XX/AR724X/AR913X based boards"
+	select ARCH_REQUIRE_GPIOLIB
 	select BOOT_RAW
 	select CEVT_R4K
 	select CSRC_R4K
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 31e0f83..e621d6c 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -8,7 +8,7 @@
 # under the terms of the GNU General Public License version 2 as published
 # by the Free Software Foundation.
 
-obj-y	:= prom.o setup.o irq.o common.o clock.o
+obj-y	:= prom.o setup.o irq.o common.o clock.o gpio.o
 
 obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
index 612a6b5..561906c 100644
--- a/arch/mips/ath79/common.h
+++ b/arch/mips/ath79/common.h
@@ -23,4 +23,9 @@
 void ath79_clocks_init(void);
 void ath79_ddr_wb_flush(unsigned int reg);
 
+void ath79_gpio_function_enable(u32 mask);
+void ath79_gpio_function_disable(u32 mask);
+void ath79_gpio_function_setup(u32 set, u32 clear);
+void ath79_gpio_init(void);
+
 #endif /* __ATH79_COMMON_H */
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c
new file mode 100644
index 0000000..a0c426b
--- /dev/null
+++ b/arch/mips/ath79/gpio.c
@@ -0,0 +1,197 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X GPIO API support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79.h>
+#include "common.h"
+
+static void __iomem *ath79_gpio_base;
+static unsigned long ath79_gpio_count;
+static DEFINE_SPINLOCK(ath79_gpio_lock);
+
+static void __ath79_gpio_set_value(unsigned gpio, int value)
+{
+	void __iomem *base = ath79_gpio_base;
+
+	if (value)
+		__raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET);
+	else
+		__raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR);
+}
+
+static int __ath79_gpio_get_value(unsigned gpio)
+{
+	return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
+}
+
+static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	return __ath79_gpio_get_value(offset);
+}
+
+static void ath79_gpio_set_value(struct gpio_chip *chip,
+				  unsigned offset, int value)
+{
+	__ath79_gpio_set_value(offset, value);
+}
+
+static int ath79_gpio_direction_input(struct gpio_chip *chip,
+				       unsigned offset)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
+		     base + AR71XX_GPIO_REG_OE);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+	return 0;
+}
+
+static int ath79_gpio_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	if (value)
+		__raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
+	else
+		__raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
+
+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
+		     base + AR71XX_GPIO_REG_OE);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+	return 0;
+}
+
+static struct gpio_chip ath79_gpio_chip = {
+	.label			= "ath79",
+	.get			= ath79_gpio_get_value,
+	.set			= ath79_gpio_set_value,
+	.direction_input	= ath79_gpio_direction_input,
+	.direction_output	= ath79_gpio_direction_output,
+	.base			= 0,
+};
+
+void ath79_gpio_function_enable(u32 mask)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) | mask,
+		     base + AR71XX_GPIO_REG_FUNC);
+	/* flush write */
+	__raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_disable(u32 mask)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~mask,
+		     base + AR71XX_GPIO_REG_FUNC);
+	/* flush write */
+	__raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_setup(u32 set, u32 clear)
+{
+	void __iomem *base = ath79_gpio_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+	__raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set,
+		     base + AR71XX_GPIO_REG_FUNC);
+	/* flush write */
+	__raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void __init ath79_gpio_init(void)
+{
+	int err;
+
+	if (soc_is_ar71xx())
+		ath79_gpio_count = AR71XX_GPIO_COUNT;
+	else if (soc_is_ar724x())
+		ath79_gpio_count = AR724X_GPIO_COUNT;
+	else if (soc_is_ar913x())
+		ath79_gpio_count = AR913X_GPIO_COUNT;
+	else
+		BUG();
+
+	ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
+	ath79_gpio_chip.ngpio = ath79_gpio_count;
+
+	err = gpiochip_add(&ath79_gpio_chip);
+	if (err)
+		panic("cannot add AR71xx GPIO chip, error=%d", err);
+}
+
+int gpio_get_value(unsigned gpio)
+{
+	if (gpio < ath79_gpio_count)
+		return __ath79_gpio_get_value(gpio);
+
+	return __gpio_get_value(gpio);
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int value)
+{
+	if (gpio < ath79_gpio_count)
+		__ath79_gpio_set_value(gpio, value);
+	else
+		__gpio_set_value(gpio, value);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_to_irq(unsigned gpio)
+{
+	/* FIXME */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(unsigned irq)
+{
+	/* FIXME */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(irq_to_gpio);
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 175def8..29dde98 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -157,7 +157,6 @@ void __init plat_mem_setup(void)
 					   AR71XX_RESET_SIZE);
 	ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
 					 AR71XX_PLL_SIZE);
-
 	ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
 					 AR71XX_DDR_CTRL_SIZE);
 
@@ -183,6 +182,7 @@ void __init plat_time_init(void)
 
 static int __init ath79_setup(void)
 {
+	ath79_gpio_init();
 	ath79_register_uart();
 	return 0;
 }
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 5a9e5e1..7f2933d 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -25,6 +25,8 @@
 #define AR71XX_DDR_CTRL_SIZE	0x100
 #define AR71XX_UART_BASE	(AR71XX_APB_BASE + 0x00020000)
 #define AR71XX_UART_SIZE	0x100
+#define AR71XX_GPIO_BASE        (AR71XX_APB_BASE + 0x00040000)
+#define AR71XX_GPIO_SIZE        0x100
 #define AR71XX_PLL_BASE		(AR71XX_APB_BASE + 0x00050000)
 #define AR71XX_PLL_SIZE		0x100
 #define AR71XX_RESET_BASE	(AR71XX_APB_BASE + 0x00060000)
@@ -204,4 +206,23 @@
 #define AR71XX_SPI_IOC_CS_ALL	(AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \
 				 AR71XX_SPI_IOC_CS2)
 
+/*
+ * GPIO block
+ */
+#define AR71XX_GPIO_REG_OE		0x00
+#define AR71XX_GPIO_REG_IN		0x04
+#define AR71XX_GPIO_REG_OUT		0x08
+#define AR71XX_GPIO_REG_SET		0x0c
+#define AR71XX_GPIO_REG_CLEAR		0x10
+#define AR71XX_GPIO_REG_INT_MODE	0x14
+#define AR71XX_GPIO_REG_INT_TYPE	0x18
+#define AR71XX_GPIO_REG_INT_POLARITY	0x1c
+#define AR71XX_GPIO_REG_INT_PENDING	0x20
+#define AR71XX_GPIO_REG_INT_ENABLE	0x24
+#define AR71XX_GPIO_REG_FUNC		0x28
+
+#define AR71XX_GPIO_COUNT		16
+#define AR724X_GPIO_COUNT		18
+#define AR913X_GPIO_COUNT		22
+
 #endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/gpio.h b/arch/mips/include/asm/mach-ath79/gpio.h
new file mode 100644
index 0000000..60dcb62
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/gpio.h
@@ -0,0 +1,26 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X GPIO API definitions
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_MACH_ATH79_GPIO_H
+#define __ASM_MACH_ATH79_GPIO_H
+
+#define ARCH_NR_GPIOS	64
+#include <asm-generic/gpio.h>
+
+int gpio_to_irq(unsigned gpio);
+int irq_to_gpio(unsigned irq);
+int gpio_get_value(unsigned gpio);
+void gpio_set_value(unsigned gpio, int value);
+
+#define gpio_cansleep	__gpio_cansleep
+
+#endif /* __ASM_MACH_ATH79_GPIO_H */
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:30:24 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:30:28 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48520 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490989Ab1ADU3I (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:08 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 8FBF145C01C;
        Tue,  4 Jan 2011 21:29:03 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 1CD0A1F0001;
        Tue,  4 Jan 2011 21:29:03 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 03/16] MIPS: ath79: utilize the MIPS multi-machine support
Date:   Tue,  4 Jan 2011 21:28:16 +0100
Message-Id: <1294172909-1309-4-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108AA57B70 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28827
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/Kconfig           |    1 +
 arch/mips/ath79/machtypes.h |   21 +++++++++++++++++++++
 arch/mips/ath79/setup.c     |   15 +++++++++++++++
 3 files changed, 37 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/machtypes.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 944845a..12dd976 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -74,6 +74,7 @@ config ATH79
 	select CSRC_R4K
 	select DMA_NONCOHERENT
 	select IRQ_CPU
+	select MIPS_MACHINE
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_HAS_EARLY_PRINTK
 	select SYS_SUPPORTS_32BIT_KERNEL
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
new file mode 100644
index 0000000..fac0e26
--- /dev/null
+++ b/arch/mips/ath79/machtypes.h
@@ -0,0 +1,21 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X machine type definitions
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_MACHTYPE_H
+#define _ATH79_MACHTYPE_H
+
+#include <asm/mips_machine.h>
+
+enum ath79_mach_type {
+	ATH79_MACH_GENERIC = 0,
+};
+
+#endif /* _ATH79_MACHTYPE_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 29dde98..5e57402 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -20,11 +20,13 @@
 #include <asm/bootinfo.h>
 #include <asm/time.h>		/* for mips_hpt_frequency */
 #include <asm/reboot.h>		/* for _machine_{restart,halt} */
+#include <asm/mips_machine.h>
 
 #include <asm/mach-ath79/ath79.h>
 #include <asm/mach-ath79/ar71xx_regs.h>
 #include "common.h"
 #include "dev-common.h"
+#include "machtypes.h"
 
 #define ATH79_SYS_TYPE_LEN	64
 
@@ -184,7 +186,20 @@ static int __init ath79_setup(void)
 {
 	ath79_gpio_init();
 	ath79_register_uart();
+
+	mips_machine_setup();
+
 	return 0;
 }
 
 arch_initcall(ath79_setup);
+
+static void __init ath79_generic_init(void)
+{
+	/* Nothing to do */
+}
+
+MIPS_MACHINE(ATH79_MACH_GENERIC,
+	     "Generic",
+	     "Generic AR71XX/AR724X/AR913X based board",
+	     ath79_generic_init);
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:30:47 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:30:51 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48525 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491001Ab1ADU3I (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:08 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id C913045C01D;
        Tue,  4 Jan 2011 21:29:03 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 60F2E1F0001;
        Tue,  4 Jan 2011 21:29:03 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 04/16] MIPS: ath79: add initial support for the Atheros PB44 reference board
Date:   Tue,  4 Jan 2011 21:28:17 +0100
Message-Id: <1294172909-1309-5-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108B3991A7 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28828
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC:
    - don't use 'default n' for the ATH79_MACH_PB44 Kconfig option

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/Kconfig     |   11 ++++++++
 arch/mips/ath79/Makefile    |    5 ++++
 arch/mips/ath79/mach-pb44.c |   56 +++++++++++++++++++++++++++++++++++++++++++
 arch/mips/ath79/machtypes.h |    1 +
 4 files changed, 73 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/mach-pb44.c

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 50b9334..fabb2b0 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -1,5 +1,16 @@
 if ATH79
 
+menu "Atheros AR71XX/AR724X/AR913X machine selection"
+
+config ATH79_MACH_PB44
+	bool "Atheros PB44 reference board"
+	select SOC_AR71XX
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Atheros PB44 reference board.
+
+endmenu
+
 config SOC_AR71XX
 	def_bool n
 
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index e621d6c..c3093f7 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,3 +16,8 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 # Devices
 #
 obj-y					+= dev-common.o
+
+#
+# Machines
+#
+obj-$(CONFIG_ATH79_MACH_PB44)		+= mach-pb44.o
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
new file mode 100644
index 0000000..ffc24d7
--- /dev/null
+++ b/arch/mips/ath79/mach-pb44.c
@@ -0,0 +1,56 @@
+/*
+ *  Atheros PB44 reference board support
+ *
+ *  Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/pcf857x.h>
+
+#include "machtypes.h"
+
+#define PB44_GPIO_I2C_SCL	0
+#define PB44_GPIO_I2C_SDA	1
+
+#define PB44_GPIO_EXP_BASE	16
+
+static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
+	.sda_pin        = PB44_GPIO_I2C_SDA,
+	.scl_pin        = PB44_GPIO_I2C_SCL,
+};
+
+static struct platform_device pb44_i2c_gpio_device = {
+	.name		= "i2c-gpio",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &pb44_i2c_gpio_data,
+	}
+};
+
+static struct pcf857x_platform_data pb44_pcf857x_data = {
+	.gpio_base	= PB44_GPIO_EXP_BASE,
+};
+
+static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("pcf8575", 0x20),
+		.platform_data  = &pb44_pcf857x_data,
+	},
+};
+
+static void __init pb44_init(void)
+{
+	i2c_register_board_info(0, pb44_i2c_board_info,
+				ARRAY_SIZE(pb44_i2c_board_info));
+	platform_device_register(&pb44_i2c_gpio_device);
+}
+
+MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
+	     pb44_init);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
index fac0e26..a796fa3 100644
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -16,6 +16,7 @@
 
 enum ath79_mach_type {
 	ATH79_MACH_GENERIC = 0,
+	ATH79_MACH_PB44,		/* Atheros PB44 reference board */
 };
 
 #endif /* _ATH79_MACHTYPE_H */
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:31:10 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:31:16 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48563 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491013Ab1ADU3M (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:12 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 8B8F745C01F;
        Tue,  4 Jan 2011 21:29:04 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id EDA121F0001;
        Tue,  4 Jan 2011 21:29:03 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        Wim Van Sebroeck <wim@iguana.be>,
        linux-watchdog@vger.kernel.org
Subject: [PATCH v5 06/16] watchdog: add driver for the Atheros AR71XX/AR724X/AR913X SoCs
Date:   Tue,  4 Jan 2011 21:28:19 +0100
Message-Id: <1294172909-1309-7-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108C049158 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28829
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds a driver for the built-in hardware watchdog device
of the Atheros AR71XX/AR724X/AR913X SoCs.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: Wim Van Sebroeck <wim@iguana.be>
Cc: linux-watchdog@vger.kernel.org
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - remove #ifdef CONFIG_WATCHDOG_NOWAYOUT for nowayout module-parameter.
    - add ath79_wdt_keepalive when doing un unexpected close of /dev/watchdog
      (the close is considered as communication with /dev/watchdog)
    - replace reboot_notifier with a platform shutdown.
    - add timeout module-parameter
    - rebased against 2.6.37-rc8

Changes since v4:
    - use __dev{init,exit,exit_p}
    - remove DRIVER_DESC definition and use its value directly in
      the MODULE_DESCRIPTION() macro
    - convert to use the clock API

 drivers/watchdog/Kconfig     |    7 +
 drivers/watchdog/Makefile    |    1 +
 drivers/watchdog/ath79_wdt.c |  305 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 313 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/ath79_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index a5ad77e..e4be010 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -836,6 +836,13 @@ config SBC_EPX_C3_WATCHDOG
 
 # MIPS Architecture
 
+config ATH79_WDT
+	tristate "Atheros AR71XX/AR724X/AR913X hardware watchdog"
+	depends on ATH79
+	help
+	  Hardware driver for the built-in watchdog timer on the Atheros
+	  AR71XX/AR724X/AR913X SoCs.
+
 config BCM47XX_WDT
 	tristate "Broadcom BCM47xx Watchdog Timer"
 	depends on BCM47XX
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 4b0ef38..01d9063 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -108,6 +108,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
 # M68KNOMMU Architecture
 
 # MIPS Architecture
+obj-$(CONFIG_ATH79_WDT) += ath79_wdt.o
 obj-$(CONFIG_BCM47XX_WDT) += bcm47xx_wdt.o
 obj-$(CONFIG_BCM63XX_WDT) += bcm63xx_wdt.o
 obj-$(CONFIG_RC32434_WDT) += rc32434_wdt.o
diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c
new file mode 100644
index 0000000..725c84b
--- /dev/null
+++ b/drivers/watchdog/ath79_wdt.c
@@ -0,0 +1,305 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X built-in hardware watchdog timer.
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This driver was based on: drivers/watchdog/ixp4xx_wdt.c
+ *	Author: Deepak Saxena <dsaxena@plexity.net>
+ *	Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * which again was based on sa1100 driver,
+ *	Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+#define DRIVER_NAME	"ath79-wdt"
+
+#define WDT_TIMEOUT	15	/* seconds */
+
+#define WDOG_CTRL_LAST_RESET	BIT(31)
+#define WDOG_CTRL_ACTION_MASK	3
+#define WDOG_CTRL_ACTION_NONE	0	/* no action */
+#define WDOG_CTRL_ACTION_GPI	1	/* general purpose interrupt */
+#define WDOG_CTRL_ACTION_NMI	2	/* NMI */
+#define WDOG_CTRL_ACTION_FCR	3	/* full chip reset */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
+			   "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static int timeout = WDT_TIMEOUT;
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds "
+			  "(default=" __MODULE_STRING(WDT_TIMEOUT) "s)");
+
+static unsigned long wdt_flags;
+
+#define WDT_FLAGS_BUSY		0
+#define WDT_FLAGS_EXPECT_CLOSE	1
+
+static struct clk *wdt_clk;
+static unsigned long wdt_freq;
+static int boot_status;
+static int max_timeout;
+
+static inline void ath79_wdt_keepalive(void)
+{
+	ath79_reset_wr(AR71XX_RESET_REG_WDOG, wdt_freq * timeout);
+}
+
+static inline void ath79_wdt_enable(void)
+{
+	ath79_wdt_keepalive();
+	ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
+}
+
+static inline void ath79_wdt_disable(void)
+{
+	ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
+}
+
+static int ath79_wdt_set_timeout(int val)
+{
+	if (val < 1 || val > max_timeout)
+		return -EINVAL;
+
+	timeout = val;
+	ath79_wdt_keepalive();
+
+	return 0;
+}
+
+static int ath79_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags))
+		return -EBUSY;
+
+	clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
+	ath79_wdt_enable();
+
+	return nonseekable_open(inode, file);
+}
+
+static int ath79_wdt_release(struct inode *inode, struct file *file)
+{
+	if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags))
+		ath79_wdt_disable();
+	else {
+		pr_crit(DRIVER_NAME ": device closed unexpectedly, "
+			"watchdog timer will not stop!\n");
+		ath79_wdt_keepalive();
+	}
+
+	clear_bit(WDT_FLAGS_BUSY, &wdt_flags);
+	clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
+
+	return 0;
+}
+
+static ssize_t ath79_wdt_write(struct file *file, const char *data,
+				size_t len, loff_t *ppos)
+{
+	if (len) {
+		if (!nowayout) {
+			size_t i;
+
+			clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
+
+			for (i = 0; i != len; i++) {
+				char c;
+
+				if (get_user(c, data + i))
+					return -EFAULT;
+
+				if (c == 'V')
+					set_bit(WDT_FLAGS_EXPECT_CLOSE,
+						&wdt_flags);
+			}
+		}
+
+		ath79_wdt_keepalive();
+	}
+
+	return len;
+}
+
+static const struct watchdog_info ath79_wdt_info = {
+	.options		= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+				  WDIOF_MAGICCLOSE | WDIOF_CARDRESET,
+	.firmware_version	= 0,
+	.identity		= "ATH79 watchdog",
+};
+
+static long ath79_wdt_ioctl(struct file *file, unsigned int cmd,
+			    unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	int err;
+	int t;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		err = copy_to_user(argp, &ath79_wdt_info,
+				   sizeof(ath79_wdt_info)) ? -EFAULT : 0;
+		break;
+
+	case WDIOC_GETSTATUS:
+		err = put_user(0, p);
+		break;
+
+	case WDIOC_GETBOOTSTATUS:
+		err = put_user(boot_status, p);
+		break;
+
+	case WDIOC_KEEPALIVE:
+		ath79_wdt_keepalive();
+		err = 0;
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		err = get_user(t, p);
+		if (err)
+			break;
+
+		err = ath79_wdt_set_timeout(t);
+		if (err)
+			break;
+
+		/* fallthrough */
+	case WDIOC_GETTIMEOUT:
+		err = put_user(timeout, p);
+		break;
+
+	default:
+		err = -ENOTTY;
+		break;
+	}
+
+	return err;
+}
+
+static const struct file_operations ath79_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= ath79_wdt_write,
+	.unlocked_ioctl	= ath79_wdt_ioctl,
+	.open		= ath79_wdt_open,
+	.release	= ath79_wdt_release,
+};
+
+static struct miscdevice ath79_wdt_miscdev = {
+	.minor = WATCHDOG_MINOR,
+	.name = "watchdog",
+	.fops = &ath79_wdt_fops,
+};
+
+static int __devinit ath79_wdt_probe(struct platform_device *pdev)
+{
+	u32 ctrl;
+	int err;
+
+	wdt_clk = clk_get(&pdev->dev, "wdt");
+	if (IS_ERR(wdt_clk))
+		return PTR_ERR(wdt_clk);
+
+	err = clk_enable(wdt_clk);
+	if (err)
+		goto err_clk_put;
+
+	wdt_freq = clk_get_rate(wdt_clk);
+	if (!wdt_freq) {
+		err = -EINVAL;
+		goto err_clk_disable;
+	}
+
+	max_timeout = (0xfffffffful / wdt_freq);
+	if (timeout < 1 || timeout > max_timeout) {
+		timeout = max_timeout;
+		dev_info(&pdev->dev,
+			"timeout value must be 0 < timeout < %d, using %d\n",
+			max_timeout, timeout);
+	}
+
+	ctrl = ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
+	boot_status = (ctrl & WDOG_CTRL_LAST_RESET) ? WDIOF_CARDRESET : 0;
+
+	err = misc_register(&ath79_wdt_miscdev);
+	if (err) {
+		dev_err(&pdev->dev,
+			"unable to register misc device, err=%d\n", err);
+		goto err_clk_disable;
+	}
+
+	return 0;
+
+err_clk_disable:
+	clk_disable(wdt_clk);
+err_clk_put:
+	clk_put(wdt_clk);
+	return err;
+}
+
+static int __devexit ath79_wdt_remove(struct platform_device *pdev)
+{
+	misc_deregister(&ath79_wdt_miscdev);
+	clk_disable(wdt_clk);
+	clk_put(wdt_clk);
+	return 0;
+}
+
+static void ath97_wdt_shutdown(struct platform_device *pdev)
+{
+	ath79_wdt_disable();
+}
+
+static struct platform_driver ath79_wdt_driver = {
+	.remove		= __devexit_p(ath79_wdt_remove),
+	.shutdown	= ath97_wdt_shutdown,
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init ath79_wdt_init(void)
+{
+	return platform_driver_probe(&ath79_wdt_driver, ath79_wdt_probe);
+}
+module_init(ath79_wdt_init);
+
+static void __exit ath79_wdt_exit(void)
+{
+	platform_driver_unregister(&ath79_wdt_driver);
+}
+module_exit(ath79_wdt_exit);
+
+MODULE_DESCRIPTION("Atheros AR71XX/AR724X/AR913X hardware watchdog driver");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org");
+MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:31:34 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:31:40 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48563 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491024Ab1ADU3M (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:12 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 0F92745C027;
        Tue,  4 Jan 2011 21:29:08 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 9B73C1F0001;
        Tue,  4 Jan 2011 21:29:07 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 15/16] MIPS: ath79: add initial support for the Atheros AP81 reference board
Date:   Tue,  4 Jan 2011 21:28:28 +0100
Message-Id: <1294172909-1309-16-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108EFD1050 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28830
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC:
    - don't use 'default n' for the ATH79_MACH_AP81 Kconfig option

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/Kconfig     |   11 +++++
 arch/mips/ath79/Makefile    |    1 +
 arch/mips/ath79/mach-ap81.c |   94 +++++++++++++++++++++++++++++++++++++++++++
 arch/mips/ath79/machtypes.h |    1 +
 4 files changed, 107 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/mach-ap81.c

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 5d67942..1912d54 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -2,6 +2,17 @@ if ATH79
 
 menu "Atheros AR71XX/AR724X/AR913X machine selection"
 
+config ATH79_MACH_AP81
+	bool "Atheros AP81 reference board"
+	select SOC_AR913X
+	select ATH79_DEV_GPIO_BUTTONS
+	select ATH79_DEV_LEDS_GPIO
+	select ATH79_DEV_SPI
+	select ATH79_DEV_USB
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Atheros AP81 reference board.
+
 config ATH79_MACH_PB44
 	bool "Atheros PB44 reference board"
 	select SOC_AR71XX
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 563e235..3d74e1c 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -24,4 +24,5 @@ obj-$(CONFIG_ATH79_DEV_USB)		+= dev-usb.o
 #
 # Machines
 #
+obj-$(CONFIG_ATH79_MACH_AP81)		+= mach-ap81.o
 obj-$(CONFIG_ATH79_MACH_PB44)		+= mach-pb44.o
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
new file mode 100644
index 0000000..909ca5d
--- /dev/null
+++ b/arch/mips/ath79/mach-ap81.c
@@ -0,0 +1,94 @@
+/*
+ *  Atheros AP81 board support
+ *
+ *  Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include "machtypes.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-spi.h"
+#include "dev-usb.h"
+
+#define AP81_GPIO_LED_STATUS	1
+#define AP81_GPIO_LED_AOSS	3
+#define AP81_GPIO_LED_WLAN	6
+#define AP81_GPIO_LED_POWER	14
+
+#define AP81_GPIO_BTN_SW4	12
+#define AP81_GPIO_BTN_SW1	21
+
+#define AP81_KEYS_POLL_INTERVAL		20	/* msecs */
+#define AP81_KEYS_DEBOUNCE_INTERVAL	(3 * AP81_KEYS_POLL_INTERVAL)
+
+static struct gpio_led ap81_leds_gpio[] __initdata = {
+	{
+		.name		= "ap81:green:status",
+		.gpio		= AP81_GPIO_LED_STATUS,
+		.active_low	= 1,
+	}, {
+		.name		= "ap81:amber:aoss",
+		.gpio		= AP81_GPIO_LED_AOSS,
+		.active_low	= 1,
+	}, {
+		.name		= "ap81:green:wlan",
+		.gpio		= AP81_GPIO_LED_WLAN,
+		.active_low	= 1,
+	}, {
+		.name		= "ap81:green:power",
+		.gpio		= AP81_GPIO_LED_POWER,
+		.active_low	= 1,
+	}
+};
+
+static struct gpio_keys_button ap81_gpio_keys[] __initdata = {
+	{
+		.desc		= "sw1",
+		.type		= EV_KEY,
+		.code		= BTN_0,
+		.debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= AP81_GPIO_BTN_SW1,
+		.active_low	= 1,
+	} , {
+		.desc		= "sw4",
+		.type		= EV_KEY,
+		.code		= BTN_1,
+		.debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= AP81_GPIO_BTN_SW4,
+		.active_low	= 1,
+	}
+};
+
+static struct spi_board_info ap81_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p64",
+	}
+};
+
+static struct ath79_spi_platform_data ap81_spi_data = {
+	.bus_num	= 0,
+	.num_chipselect	= 1,
+};
+
+static void __init ap81_setup(void)
+{
+	ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
+				 ap81_leds_gpio);
+	ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
+					ARRAY_SIZE(ap81_gpio_keys),
+					ap81_gpio_keys);
+	ath79_register_spi(&ap81_spi_data, ap81_spi_info,
+			   ARRAY_SIZE(ap81_spi_info));
+	ath79_register_usb();
+}
+
+MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
+	     ap81_setup);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
index a796fa3..3940fe4 100644
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -16,6 +16,7 @@
 
 enum ath79_mach_type {
 	ATH79_MACH_GENERIC = 0,
+	ATH79_MACH_AP81,		/* Atheros AP81 reference board */
 	ATH79_MACH_PB44,		/* Atheros PB44 reference board */
 };
 
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:31:58 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:32:04 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48564 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491012Ab1ADU3M (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:12 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 2798245C01E;
        Tue,  4 Jan 2011 21:29:04 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id A112E1F0001;
        Tue,  4 Jan 2011 21:29:03 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 05/16] MIPS: ath79: add common GPIO LEDs device
Date:   Tue,  4 Jan 2011 21:28:18 +0100
Message-Id: <1294172909-1309-6-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108BCE5FDF | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28831
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Almost all boards have one or more LEDs connected to GPIO lines. This
patch adds common code to register a platform_device for them.

The patch also adds support for the LEDs on the PB44 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/Kconfig         |    4 +++
 arch/mips/ath79/Makefile        |    1 +
 arch/mips/ath79/dev-leds-gpio.c |   56 +++++++++++++++++++++++++++++++++++++++
 arch/mips/ath79/dev-leds-gpio.h |   21 ++++++++++++++
 arch/mips/ath79/mach-pb44.c     |   18 ++++++++++++
 5 files changed, 100 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/dev-leds-gpio.c
 create mode 100644 arch/mips/ath79/dev-leds-gpio.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index fabb2b0..5bc480e 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,6 +5,7 @@ menu "Atheros AR71XX/AR724X/AR913X machine selection"
 config ATH79_MACH_PB44
 	bool "Atheros PB44 reference board"
 	select SOC_AR71XX
+	select ATH79_DEV_LEDS_GPIO
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Atheros PB44 reference board.
@@ -20,4 +21,7 @@ config SOC_AR724X
 config SOC_AR913X
 	def_bool n
 
+config ATH79_DEV_LEDS_GPIO
+	def_bool n
+
 endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index c3093f7..f41c029 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 # Devices
 #
 obj-y					+= dev-common.o
+obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
 
 #
 # Machines
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c
new file mode 100644
index 0000000..cdade68
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.c
@@ -0,0 +1,56 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "dev-leds-gpio.h"
+
+void __init ath79_register_leds_gpio(int id,
+				     unsigned num_leds,
+				     struct gpio_led *leds)
+{
+	struct platform_device *pdev;
+	struct gpio_led_platform_data pdata;
+	struct gpio_led *p;
+	int err;
+
+	p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return;
+
+	memcpy(p, leds, num_leds * sizeof(*p));
+
+	pdev = platform_device_alloc("leds-gpio", id);
+	if (!pdev)
+		goto err_free_leds;
+
+	memset(&pdata, 0, sizeof(pdata));
+	pdata.num_leds = num_leds;
+	pdata.leds = p;
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err)
+		goto err_put_pdev;
+
+	err = platform_device_add(pdev);
+	if (err)
+		goto err_put_pdev;
+
+	return;
+
+err_put_pdev:
+	platform_device_put(pdev);
+
+err_free_leds:
+	kfree(p);
+}
diff --git a/arch/mips/ath79/dev-leds-gpio.h b/arch/mips/ath79/dev-leds-gpio.h
new file mode 100644
index 0000000..6e5d885
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.h
@@ -0,0 +1,21 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_LEDS_GPIO_H
+#define _ATH79_DEV_LEDS_GPIO_H
+
+#include <linux/leds.h>
+
+void ath79_register_leds_gpio(int id,
+			      unsigned num_leds,
+			      struct gpio_led *leds);
+
+#endif /* _ATH79_DEV_LEDS_GPIO_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index ffc24d7..e176779 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -15,11 +15,14 @@
 #include <linux/i2c/pcf857x.h>
 
 #include "machtypes.h"
+#include "dev-leds-gpio.h"
 
 #define PB44_GPIO_I2C_SCL	0
 #define PB44_GPIO_I2C_SDA	1
 
 #define PB44_GPIO_EXP_BASE	16
+#define PB44_GPIO_LED_JUMP1	(PB44_GPIO_EXP_BASE + 9)
+#define PB44_GPIO_LED_JUMP2	(PB44_GPIO_EXP_BASE + 10)
 
 static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
 	.sda_pin        = PB44_GPIO_I2C_SDA,
@@ -45,11 +48,26 @@ static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
 	},
 };
 
+static struct gpio_led pb44_leds_gpio[] __initdata = {
+	{
+		.name		= "pb44:amber:jump1",
+		.gpio		= PB44_GPIO_LED_JUMP1,
+		.active_low	= 1,
+	}, {
+		.name		= "pb44:green:jump2",
+		.gpio		= PB44_GPIO_LED_JUMP2,
+		.active_low	= 1,
+	},
+};
+
 static void __init pb44_init(void)
 {
 	i2c_register_board_info(0, pb44_i2c_board_info,
 				ARRAY_SIZE(pb44_i2c_board_info));
 	platform_device_register(&pb44_i2c_gpio_device);
+
+	ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
+				 pb44_leds_gpio);
 }
 
 MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:32:22 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:32:28 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48589 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491030Ab1ADU3N (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:13 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 10AB645C021;
        Tue,  4 Jan 2011 21:29:05 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 83AFA1F0001;
        Tue,  4 Jan 2011 21:29:04 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 08/16] MIPS: ath79: add common GPIO buttons device
Date:   Tue,  4 Jan 2011 21:28:21 +0100
Message-Id: <1294172909-1309-9-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108CCCE465 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28832
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Almost all boards have one or more push buttons connected to GPIO lines.
This patch adds common code to register a platform_device for them.

The patch also adds support for the buttons on the PB44 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - converted to use the gpio_keys_polled driver
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/Kconfig            |    4 ++
 arch/mips/ath79/Makefile           |    1 +
 arch/mips/ath79/dev-gpio-buttons.c |   58 ++++++++++++++++++++++++++++++++++++
 arch/mips/ath79/dev-gpio-buttons.h |   23 ++++++++++++++
 arch/mips/ath79/mach-pb44.c        |   27 ++++++++++++++++
 5 files changed, 113 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/dev-gpio-buttons.c
 create mode 100644 arch/mips/ath79/dev-gpio-buttons.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 5bc480e..185a8d6 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,6 +5,7 @@ menu "Atheros AR71XX/AR724X/AR913X machine selection"
 config ATH79_MACH_PB44
 	bool "Atheros PB44 reference board"
 	select SOC_AR71XX
+	select ATH79_DEV_GPIO_BUTTONS
 	select ATH79_DEV_LEDS_GPIO
 	help
 	  Say 'Y' here if you want your kernel to support the
@@ -21,6 +22,9 @@ config SOC_AR724X
 config SOC_AR913X
 	def_bool n
 
+config ATH79_DEV_GPIO_BUTTONS
+	def_bool n
+
 config ATH79_DEV_LEDS_GPIO
 	def_bool n
 
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index f41c029..344e9ab 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 # Devices
 #
 obj-y					+= dev-common.o
+obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o
 obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
 
 #
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c
new file mode 100644
index 0000000..4b0168a
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.c
@@ -0,0 +1,58 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include "linux/init.h"
+#include "linux/slab.h"
+#include <linux/platform_device.h>
+
+#include "dev-gpio-buttons.h"
+
+void __init ath79_register_gpio_keys_polled(int id,
+					    unsigned poll_interval,
+					    unsigned nbuttons,
+					    struct gpio_keys_button *buttons)
+{
+	struct platform_device *pdev;
+	struct gpio_keys_platform_data pdata;
+	struct gpio_keys_button *p;
+	int err;
+
+	p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return;
+
+	memcpy(p, buttons, nbuttons * sizeof(*p));
+
+	pdev = platform_device_alloc("gpio-keys-polled", id);
+	if (!pdev)
+		goto err_free_buttons;
+
+	memset(&pdata, 0, sizeof(pdata));
+	pdata.poll_interval = poll_interval;
+	pdata.nbuttons = nbuttons;
+	pdata.buttons = p;
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err)
+		goto err_put_pdev;
+
+	err = platform_device_add(pdev);
+	if (err)
+		goto err_put_pdev;
+
+	return;
+
+err_put_pdev:
+	platform_device_put(pdev);
+
+err_free_buttons:
+	kfree(p);
+}
diff --git a/arch/mips/ath79/dev-gpio-buttons.h b/arch/mips/ath79/dev-gpio-buttons.h
new file mode 100644
index 0000000..481847a
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.h
@@ -0,0 +1,23 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_GPIO_BUTTONS_H
+#define _ATH79_DEV_GPIO_BUTTONS_H
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+void ath79_register_gpio_keys_polled(int id,
+				     unsigned poll_interval,
+				     unsigned nbuttons,
+				     struct gpio_keys_button *buttons);
+
+#endif /* _ATH79_DEV_GPIO_BUTTONS_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index e176779..3dc5080 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -15,15 +15,21 @@
 #include <linux/i2c/pcf857x.h>
 
 #include "machtypes.h"
+#include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
 
 #define PB44_GPIO_I2C_SCL	0
 #define PB44_GPIO_I2C_SDA	1
 
 #define PB44_GPIO_EXP_BASE	16
+#define PB44_GPIO_SW_RESET	(PB44_GPIO_EXP_BASE + 6)
+#define PB44_GPIO_SW_JUMP	(PB44_GPIO_EXP_BASE + 8)
 #define PB44_GPIO_LED_JUMP1	(PB44_GPIO_EXP_BASE + 9)
 #define PB44_GPIO_LED_JUMP2	(PB44_GPIO_EXP_BASE + 10)
 
+#define PB44_KEYS_POLL_INTERVAL		20	/* msecs */
+#define PB44_KEYS_DEBOUNCE_INTERVAL	(3 * PB44_KEYS_POLL_INTERVAL)
+
 static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
 	.sda_pin        = PB44_GPIO_I2C_SDA,
 	.scl_pin        = PB44_GPIO_I2C_SCL,
@@ -60,6 +66,24 @@ static struct gpio_led pb44_leds_gpio[] __initdata = {
 	},
 };
 
+static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
+	{
+		.desc		= "soft_reset",
+		.type		= EV_KEY,
+		.code		= KEY_RESTART,
+		.debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= PB44_GPIO_SW_RESET,
+		.active_low	= 1,
+	} , {
+		.desc		= "jumpstart",
+		.type		= EV_KEY,
+		.code		= KEY_WPS_BUTTON,
+		.debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= PB44_GPIO_SW_JUMP,
+		.active_low	= 1,
+	}
+};
+
 static void __init pb44_init(void)
 {
 	i2c_register_board_info(0, pb44_i2c_board_info,
@@ -68,6 +92,9 @@ static void __init pb44_init(void)
 
 	ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
 				 pb44_leds_gpio);
+	ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
+					ARRAY_SIZE(pb44_gpio_keys),
+					pb44_gpio_keys);
 }
 
 MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:32:47 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:32:52 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48588 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491028Ab1ADU3N (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:13 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id A8E6545C020;
        Tue,  4 Jan 2011 21:29:04 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 4EEAC1F0001;
        Tue,  4 Jan 2011 21:29:04 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 07/16] MIPS: ath79: add common watchdog device
Date:   Tue,  4 Jan 2011 21:28:20 +0100
Message-Id: <1294172909-1309-8-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108C37BE83 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28833
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

All supported SoCs have a built-in hardware watchdog driver. This patch
registers a platform_device for that to make it usable.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC:
    - remove the ATH79_DEV_WDT Kconfig option, and move the watchdog platform
      code into dev-common.[ch]

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/dev-common.c |   10 ++++++++++
 arch/mips/ath79/dev-common.h |    1 +
 arch/mips/ath79/setup.c      |    1 +
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
index 3cfa100..3b82e32 100644
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -65,3 +65,13 @@ void __init ath79_register_uart(void)
 	ath79_uart_data[0].uartclk = clk_get_rate(clk);
 	platform_device_register(&ath79_uart_device);
 }
+
+static struct platform_device ath79_wdt_device = {
+	.name		= "ath79-wdt",
+	.id		= -1,
+};
+
+void __init ath79_register_wdt(void)
+{
+	platform_device_register(&ath79_wdt_device);
+}
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
index 248622c..0f514e1 100644
--- a/arch/mips/ath79/dev-common.h
+++ b/arch/mips/ath79/dev-common.h
@@ -13,5 +13,6 @@
 #define _ATH79_DEV_COMMON_H
 
 void ath79_register_uart(void);
+void ath79_register_wdt(void);
 
 #endif /* _ATH79_DEV_COMMON_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 5e57402..159b42f 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -186,6 +186,7 @@ static int __init ath79_setup(void)
 {
 	ath79_gpio_init();
 	ath79_register_uart();
+	ath79_register_wdt();
 
 	mips_machine_setup();
 
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:33:10 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:33:15 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48591 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491036Ab1ADU3N (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:13 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 7771A45C023;
        Tue,  4 Jan 2011 21:29:06 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 98BBA1F0001;
        Tue,  4 Jan 2011 21:29:05 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 10/16] MIPS: ath79: add common SPI controller device
Date:   Tue,  4 Jan 2011 21:28:23 +0100
Message-Id: <1294172909-1309-11-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108D43FC0C | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28834
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Several boards are using the built-in SPI controller of the
AR71XX/AR724X/AR913X SoCs. This patch adds common platform_device
and helper code to register it. Additionally, the patch registers
the SPI bus on the PB44 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/Kconfig                        |    4 ++
 arch/mips/ath79/Makefile                       |    1 +
 arch/mips/ath79/dev-spi.c                      |   38 ++++++++++++++++++++++++
 arch/mips/ath79/dev-spi.h                      |   22 ++++++++++++++
 arch/mips/ath79/mach-pb44.c                    |   17 ++++++++++
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h |    2 +
 6 files changed, 84 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/dev-spi.c
 create mode 100644 arch/mips/ath79/dev-spi.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 185a8d6..cd6c738 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -7,6 +7,7 @@ config ATH79_MACH_PB44
 	select SOC_AR71XX
 	select ATH79_DEV_GPIO_BUTTONS
 	select ATH79_DEV_LEDS_GPIO
+	select ATH79_DEV_SPI
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Atheros PB44 reference board.
@@ -28,4 +29,7 @@ config ATH79_DEV_GPIO_BUTTONS
 config ATH79_DEV_LEDS_GPIO
 	def_bool n
 
+config ATH79_DEV_SPI
+	def_bool n
+
 endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 344e9ab..42f4295 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 obj-y					+= dev-common.o
 obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o
 obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
+obj-$(CONFIG_ATH79_DEV_SPI)		+= dev-spi.o
 
 #
 # Machines
diff --git a/arch/mips/ath79/dev-spi.c b/arch/mips/ath79/dev-spi.c
new file mode 100644
index 0000000..aa30163
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.c
@@ -0,0 +1,38 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-spi.h"
+
+static struct resource ath79_spi_resources[] = {
+	{
+		.start	= AR71XX_SPI_BASE,
+		.end	= AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ath79_spi_device = {
+	.name		= "ath79-spi",
+	.id		= -1,
+	.resource	= ath79_spi_resources,
+	.num_resources	= ARRAY_SIZE(ath79_spi_resources),
+};
+
+void __init ath79_register_spi(struct ath79_spi_platform_data *pdata,
+			       struct spi_board_info const *info,
+			       unsigned n)
+{
+	spi_register_board_info(info, n);
+	ath79_spi_device.dev.platform_data = pdata;
+	platform_device_register(&ath79_spi_device);
+}
diff --git a/arch/mips/ath79/dev-spi.h b/arch/mips/ath79/dev-spi.h
new file mode 100644
index 0000000..d732565
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.h
@@ -0,0 +1,22 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_SPI_H
+#define _ATH79_DEV_SPI_H
+
+#include <linux/spi/spi.h>
+#include <asm/mach-ath79/ath79_spi_platform.h>
+
+void ath79_register_spi(struct ath79_spi_platform_data *pdata,
+			 struct spi_board_info const *info,
+			 unsigned n);
+
+#endif /* _ATH79_DEV_SPI_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index 3dc5080..ec7b7a1 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -17,6 +17,7 @@
 #include "machtypes.h"
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
+#include "dev-spi.h"
 
 #define PB44_GPIO_I2C_SCL	0
 #define PB44_GPIO_I2C_SDA	1
@@ -84,6 +85,20 @@ static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
 	}
 };
 
+static struct spi_board_info pb44_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p64",
+	},
+};
+
+static struct ath79_spi_platform_data pb44_spi_data = {
+	.bus_num		= 0,
+	.num_chipselect		= 1,
+};
+
 static void __init pb44_init(void)
 {
 	i2c_register_board_info(0, pb44_i2c_board_info,
@@ -95,6 +110,8 @@ static void __init pb44_init(void)
 	ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
 					ARRAY_SIZE(pb44_gpio_keys),
 					pb44_gpio_keys);
+	ath79_register_spi(&pb44_spi_data, pb44_spi_info,
+			   ARRAY_SIZE(pb44_spi_info));
 }
 
 MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 7f2933d..4f2b621 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -20,6 +20,8 @@
 #include <linux/bitops.h>
 
 #define AR71XX_APB_BASE		0x18000000
+#define AR71XX_SPI_BASE		0x1f000000
+#define AR71XX_SPI_SIZE		0x01000000
 
 #define AR71XX_DDR_CTRL_BASE	(AR71XX_APB_BASE + 0x00000000)
 #define AR71XX_DDR_CTRL_SIZE	0x100
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:33:34 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:33:38 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48592 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491033Ab1ADU3O (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:14 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id D0D9A45C024;
        Tue,  4 Jan 2011 21:29:06 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 46AA01F0001;
        Tue,  4 Jan 2011 21:29:06 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>,
        Greg Kroah-Hartman <gregkh@suse.de>, linux-usb@vger.kernel.org
Subject: [PATCH v5 11/16] USB: ehci: add workaround for Synopsys HC bug
Date:   Tue,  4 Jan 2011 21:28:24 +0100
Message-Id: <1294172909-1309-12-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108D888504 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28835
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

A Synopsys USB core used in various SoCs has a bug which might cause
that the host controller not issuing ping.

When software uses the Doorbell mechanism to remove queue heads, the
host controller still has references to the removed queue head even
after indicating an Interrupt on Async Advance. This happens if the last
executed queue head's Next Link queue head is removed.

Consequences of the defect:
The Host controller fetches the removed queue head, using memory that
would otherwise be deallocated.This results in incorrect transactions on
both the USB and system memory. This may result in undefined behavior.

Workarounds:

1) If no queue head is active (no Status field's Active bit is set)
after removing the queue heads, the software can write one of the valid
queue head addresses to the ASYNCLISTADDR register and deallocate the
removed queue head's memory after 2 microframes.

If one or more of the queue heads is active (the Active bit is set in
the Status field) after removing the queue heads, the software can delay
memory deallocation after time X, where X is the time required for the
Host Controller to go through all the queue heads once. X varies with
the number of queue heads and the time required to process periodic
transactions: if more periodic transactions must be performed, the Host
Controller has less time to process asynchronous transaction processing.

2) Do not use the Doorbell mechanism to remove the queue heads. Disable
the Asynchronous Schedule Enable bit instead.

The bug has been discussed on the linux-usb-devel mailing-list
four years ago, the original thread can be found here:
http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg45345.html

This patch implements the first workaround as suggested by David Brownell.
The built-in USB host controller of the Atheros AR7130/AR7141/AR7161 SoCs
requires this to work properly.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-usb@vger.kernel.org
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 drivers/usb/host/ehci-q.c |    3 +++
 drivers/usb/host/ehci.h   |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 233c288..343b8de 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1193,6 +1193,9 @@ static void end_unlink_async (struct ehci_hcd *ehci)
 		ehci->reclaim = NULL;
 		start_unlink_async (ehci, next);
 	}
+
+	if (ehci->has_synopsys_hc_bug)
+		writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
 }
 
 /* makes sure the async qh will become idle */
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index ba8eab3..6da85b2 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -133,6 +133,7 @@ struct ehci_hcd {			/* one per controller */
 	unsigned		broken_periodic:1;
 	unsigned		fs_i_thresh:1;	/* Intel iso scheduling */
 	unsigned		use_dummy_qh:1;	/* AMD Frame List table quirk*/
+	unsigned		has_synopsys_hc_bug:1; /* Synopsys HC */
 
 	/* required for usb32 quirk */
 	#define OHCI_CTRL_HCFS          (3 << 6)
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:33:57 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:34:03 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48593 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491038Ab1ADU3N (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:13 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 2829D45C025;
        Tue,  4 Jan 2011 21:29:07 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 8FF4D1F0001;
        Tue,  4 Jan 2011 21:29:06 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>,
        Greg Kroah-Hartman <gregkh@suse.de>, linux-usb@vger.kernel.org
Subject: [PATCH v5 12/16] USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR913X SoCs
Date:   Tue,  4 Jan 2011 21:28:25 +0100
Message-Id: <1294172909-1309-13-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108DDE2F30 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28836
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

The Atheros AR71XX/AR724X/AR913X SoCs have a built-in EHCI controller.
This patch adds the necessary glue code to make the generic EHCI driver
usable for them.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-usb@vger.kernel.org
---
Changes since RFC:
    - don't use 'default y if SOC_*', select USB_ARCH_HAS_EHCI option in the
      platform specific Kconfig file instead
    - add missing 'ath79_ehci_platform.h' file

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/Kconfig                            |    3 +
 .../include/asm/mach-ath79/ath79_ehci_platform.h   |   18 ++
 drivers/usb/host/Kconfig                           |    8 +
 drivers/usb/host/ehci-ath79.c                      |  176 ++++++++++++++++++++
 drivers/usb/host/ehci-hcd.c                        |    5 +
 5 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
 create mode 100644 drivers/usb/host/ehci-ath79.c

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index cd6c738..647f535 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -15,12 +15,15 @@ config ATH79_MACH_PB44
 endmenu
 
 config SOC_AR71XX
+	select USB_ARCH_HAS_EHCI
 	def_bool n
 
 config SOC_AR724X
+	select USB_ARCH_HAS_EHCI
 	def_bool n
 
 config SOC_AR913X
+	select USB_ARCH_HAS_EHCI
 	def_bool n
 
 config ATH79_DEV_GPIO_BUTTONS
diff --git a/arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h b/arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
new file mode 100644
index 0000000..6ee075f
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
@@ -0,0 +1,18 @@
+/*
+ *  Platform data definition for Atheros AR71XX/AR913X EHCI controller
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_EHCI_PLATFORM_H
+#define _ATH79_EHCI_PLATFORM_H
+
+struct ath79_ehci_platform_data {
+	u8	is_ar913x;
+};
+
+#endif /* _ATH79_EHCI_PLATFORM_H */
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6f4f8e6..3a2667a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -147,6 +147,14 @@ config USB_W90X900_EHCI
 	---help---
 		Enables support for the W90X900 USB controller
 
+config USB_EHCI_ATH79
+	bool "EHCI support for AR71XX/AR724X/AR913X SoCs"
+	depends on USB_EHCI_HCD && ATH79
+	select USB_EHCI_ROOT_HUB_TT
+	---help---
+	  Enables support for the built-in EHCI controller present
+	  on the Atheros AR71XX/AR724X/AR913X SoCs.
+
 config USB_OXU210HP_HCD
 	tristate "OXU210HP HCD support"
 	depends on USB
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c
new file mode 100644
index 0000000..43a728f
--- /dev/null
+++ b/drivers/usb/host/ehci-ath79.c
@@ -0,0 +1,176 @@
+/*
+ *  Bus Glue for Atheros AR71XX/AR913X built-in EHCI controller.
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *	Copyright (C) 2007 Atheros Communications, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach-ath79/ath79_ehci_platform.h>
+
+static int ehci_ath79_init(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	struct ath79_ehci_platform_data *pdata;
+	int ret;
+
+	pdata = hcd->self.controller->platform_data;
+
+	if (pdata->is_ar913x) {
+		hcd->has_tt = 1;
+
+		ehci->caps = hcd->regs + 0x100;
+		ehci->regs = hcd->regs + 0x100 +
+			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	} else {
+		ehci->has_synopsys_hc_bug = 1;
+
+		ehci->caps = hcd->regs;
+		ehci->regs = hcd->regs +
+			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	}
+
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+	ehci->sbrn = 0x20;
+
+	ehci_reset(ehci);
+
+	ret = ehci_init(hcd);
+	if (ret)
+		return ret;
+
+	ehci_port_power(ehci, 0);
+
+	return 0;
+}
+
+static const struct hc_driver ehci_ath79_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "Atheros built-in EHCI controller",
+	.hcd_priv_size		= sizeof(struct ehci_hcd),
+	.irq			= ehci_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	.reset			= ehci_ath79_init,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_shutdown,
+
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+	.endpoint_reset		= ehci_endpoint_reset,
+
+	.get_frame_number	= ehci_get_frame,
+
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+#ifdef CONFIG_PM
+	.hub_suspend		= ehci_hub_suspend,
+	.hub_resume		= ehci_hub_resume,
+#endif
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+};
+
+static int ehci_ath79_probe(struct platform_device *pdev)
+{
+	struct ath79_ehci_platform_data *pdata;
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int ret;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_dbg(&pdev->dev, "no platform data specified for %s\n",
+			dev_name(&pdev->dev));
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
+			dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+	irq = res->start;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "no base address specified for %s\n",
+			dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+
+	hcd = usb_create_hcd(&ehci_ath79_hc_driver, &pdev->dev,
+			     dev_name(&pdev->dev));
+	if (!hcd)
+		return -ENOMEM;
+
+	hcd->rsrc_start	= res->start;
+	hcd->rsrc_len	= res->end - res->start + 1;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		dev_dbg(&pdev->dev, "controller already in use\n");
+		ret = -EBUSY;
+		goto err_put_hcd;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_dbg(&pdev->dev, "error mapping memory\n");
+		ret = -EFAULT;
+		goto err_release_region;
+	}
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+	if (ret)
+		goto err_iounmap;
+
+	return 0;
+
+err_iounmap:
+	iounmap(hcd->regs);
+
+err_release_region:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+static int ehci_ath79_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	return 0;
+}
+
+static struct platform_driver ehci_ath79_driver = {
+	.probe		= ehci_ath79_probe,
+	.remove		= ehci_ath79_remove,
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "ath79-ehci",
+	}
+};
+
+MODULE_ALIAS("platform:ath79-ehci");
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index e906280..b1313af 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1216,6 +1216,11 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_octeon_driver
 #endif
 
+#ifdef CONFIG_USB_EHCI_ATH79
+#include "ehci-ath79.c"
+#define PLATFORM_DRIVER		ehci_ath79_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
     !defined(XILINX_OF_PLATFORM_DRIVER)
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:34:22 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:34:29 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48594 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491041Ab1ADU3O (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:14 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id D369745C026;
        Tue,  4 Jan 2011 21:29:07 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id 477261F0001;
        Tue,  4 Jan 2011 21:29:07 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 14/16] MIPS: ath79: add common USB Host Controller device
Date:   Tue,  4 Jan 2011 21:28:27 +0100
Message-Id: <1294172909-1309-15-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108EC9603E | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28837
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Add common platform_device and helper code to make the registration of
the built-in USB controllers easier on the board which are using them.
Also register the USB controller on the PB44 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/Kconfig                        |    4 +
 arch/mips/ath79/Makefile                       |    1 +
 arch/mips/ath79/dev-usb.c                      |  194 ++++++++++++++++++++++++
 arch/mips/ath79/dev-usb.h                      |   17 ++
 arch/mips/ath79/mach-pb44.c                    |    2 +
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h |   22 +++-
 6 files changed, 239 insertions(+), 1 deletions(-)
 create mode 100644 arch/mips/ath79/dev-usb.c
 create mode 100644 arch/mips/ath79/dev-usb.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index d4456ce..5d67942 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -8,6 +8,7 @@ config ATH79_MACH_PB44
 	select ATH79_DEV_GPIO_BUTTONS
 	select ATH79_DEV_LEDS_GPIO
 	select ATH79_DEV_SPI
+	select ATH79_DEV_USB
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Atheros PB44 reference board.
@@ -37,4 +38,7 @@ config ATH79_DEV_LEDS_GPIO
 config ATH79_DEV_SPI
 	def_bool n
 
+config ATH79_DEV_USB
+	def_bool n
+
 endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 42f4295..563e235 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -19,6 +19,7 @@ obj-y					+= dev-common.o
 obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o
 obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
 obj-$(CONFIG_ATH79_DEV_SPI)		+= dev-spi.o
+obj-$(CONFIG_ATH79_DEV_USB)		+= dev-usb.o
 
 #
 # Machines
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
new file mode 100644
index 0000000..fb7033f
--- /dev/null
+++ b/arch/mips/ath79/dev-usb.c
@@ -0,0 +1,194 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X USB Host Controller support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79_ehci_platform.h>
+#include "common.h"
+#include "dev-usb.h"
+
+static void __iomem *ath79_usb_ctrl_base;
+
+static struct resource ar71xx_ohci_resources[] = {
+	[0] = {
+		.start	= AR71XX_OHCI_BASE,
+		.end	= AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= ATH79_MISC_IRQ_OHCI,
+		.end	= ATH79_MISC_IRQ_OHCI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ar724x_usb_resources[] = {
+	[0] = {
+		.start	= AR7240_OHCI_BASE,
+		.end	= AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= ATH79_CPU_IRQ_USB,
+		.end	= ATH79_CPU_IRQ_USB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32);
+static struct platform_device ath79_ohci_device = {
+	.name		= "ath79-ohci",
+	.id		= -1,
+	.resource	= ar71xx_ohci_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_ohci_resources),
+	.dev = {
+		.dma_mask		= &ath79_ohci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+static struct resource ar71xx_ehci_resources[] = {
+	[0] = {
+		.start	= AR71XX_EHCI_BASE,
+		.end	= AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= ATH79_CPU_IRQ_USB,
+		.end	= ATH79_CPU_IRQ_USB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
+static struct ath79_ehci_platform_data ath79_ehci_data;
+
+static struct platform_device ath79_ehci_device = {
+	.name		= "ath79-ehci",
+	.id		= -1,
+	.resource	= ar71xx_ehci_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_ehci_resources),
+	.dev = {
+		.dma_mask		= &ath79_ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &ath79_ehci_data,
+	},
+};
+
+#define AR71XX_USB_RESET_MASK	(AR71XX_RESET_USB_HOST | \
+				 AR71XX_RESET_USB_PHY | \
+				 AR71XX_RESET_USB_OHCI_DLL)
+
+static void __init ar71xx_usb_setup(void)
+{
+	ath79_device_reset_set(AR71XX_USB_RESET_MASK);
+	mdelay(1000);
+	ath79_device_reset_clear(AR71XX_USB_RESET_MASK);
+
+	/* Turning on the Buff and Desc swap bits */
+	__raw_writel(0xf0000, ath79_usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG);
+
+	/* WAR for HW bug. Here it adjusts the duration between two SOFS */
+	__raw_writel(0x20c00, ath79_usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
+
+	mdelay(900);
+
+	platform_device_register(&ath79_ohci_device);
+	platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar7240_usb_setup(void)
+{
+	ath79_device_reset_clear(AR7240_RESET_OHCI_DLL);
+	ath79_device_reset_set(AR7240_RESET_USB_HOST);
+	mdelay(1000);
+	ath79_device_reset_set(AR7240_RESET_OHCI_DLL);
+	ath79_device_reset_clear(AR7240_RESET_USB_HOST);
+
+	/* WAR for HW bug. Here it adjusts the duration between two SOFS */
+	__raw_writel(0x3, ath79_usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
+
+	ath79_ohci_device.resource = ar724x_usb_resources;
+	ath79_ohci_device.num_resources = ARRAY_SIZE(ar724x_usb_resources);
+	platform_device_register(&ath79_ohci_device);
+}
+
+static void __init ar724x_usb_setup(void)
+{
+	ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR724X_RESET_USB_HOST);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR724X_RESET_USB_PHY);
+	mdelay(10);
+
+	ath79_ehci_data.is_ar913x = 1;
+	ath79_ehci_device.resource = ar724x_usb_resources;
+	ath79_ehci_device.num_resources = ARRAY_SIZE(ar724x_usb_resources);
+	platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar913x_usb_setup(void)
+{
+	ath79_device_reset_set(AR71XX_RESET_USBSUS_OVERRIDE);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR71XX_RESET_USB_HOST);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR71XX_RESET_USB_PHY);
+	mdelay(10);
+
+	ath79_ehci_data.is_ar913x = 1;
+	platform_device_register(&ath79_ehci_device);
+}
+
+void __init ath79_register_usb(void)
+{
+	ath79_usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE,
+				      AR71XX_USB_CTRL_SIZE);
+
+	switch (ath79_soc) {
+	case ATH79_SOC_AR7130:
+	case ATH79_SOC_AR7141:
+	case ATH79_SOC_AR7161:
+		ar71xx_usb_setup();
+		break;
+
+	case ATH79_SOC_AR7240:
+		ar7240_usb_setup();
+		break;
+
+	case ATH79_SOC_AR7241:
+	case ATH79_SOC_AR7242:
+		ar724x_usb_setup();
+		break;
+
+	case ATH79_SOC_AR9130:
+	case ATH79_SOC_AR9132:
+		ar913x_usb_setup();
+		break;
+
+	default:
+		BUG();
+	}
+}
diff --git a/arch/mips/ath79/dev-usb.h b/arch/mips/ath79/dev-usb.h
new file mode 100644
index 0000000..4b86a69
--- /dev/null
+++ b/arch/mips/ath79/dev-usb.h
@@ -0,0 +1,17 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X USB Host Controller support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_USB_H
+#define _ATH79_DEV_USB_H
+
+void ath79_register_usb(void);
+
+#endif /* _ATH79_DEV_USB_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index ec7b7a1..fe9701a 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -18,6 +18,7 @@
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
 #include "dev-spi.h"
+#include "dev-usb.h"
 
 #define PB44_GPIO_I2C_SCL	0
 #define PB44_GPIO_I2C_SDA	1
@@ -112,6 +113,7 @@ static void __init pb44_init(void)
 					pb44_gpio_keys);
 	ath79_register_spi(&pb44_spi_data, pb44_spi_info,
 			   ARRAY_SIZE(pb44_spi_info));
+	ath79_register_usb();
 }
 
 MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 4f2b621..f125f1e 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -20,6 +20,10 @@
 #include <linux/bitops.h>
 
 #define AR71XX_APB_BASE		0x18000000
+#define AR71XX_EHCI_BASE	0x1b000000
+#define AR71XX_EHCI_SIZE	0x1000
+#define AR71XX_OHCI_BASE	0x1c000000
+#define AR71XX_OHCI_SIZE	0x1000
 #define AR71XX_SPI_BASE		0x1f000000
 #define AR71XX_SPI_SIZE		0x01000000
 
@@ -27,6 +31,8 @@
 #define AR71XX_DDR_CTRL_SIZE	0x100
 #define AR71XX_UART_BASE	(AR71XX_APB_BASE + 0x00020000)
 #define AR71XX_UART_SIZE	0x100
+#define AR71XX_USB_CTRL_BASE	(AR71XX_APB_BASE + 0x00030000)
+#define AR71XX_USB_CTRL_SIZE	0x100
 #define AR71XX_GPIO_BASE        (AR71XX_APB_BASE + 0x00040000)
 #define AR71XX_GPIO_SIZE        0x100
 #define AR71XX_PLL_BASE		(AR71XX_APB_BASE + 0x00050000)
@@ -34,6 +40,9 @@
 #define AR71XX_RESET_BASE	(AR71XX_APB_BASE + 0x00060000)
 #define AR71XX_RESET_SIZE	0x100
 
+#define AR7240_OHCI_BASE	0x1b000000
+#define AR7240_OHCI_SIZE	0x1000
+
 /*
  * DDR_CTRL block
  */
@@ -102,6 +111,12 @@
 #define AR913X_AHB_DIV_MASK		0x1
 
 /*
+ * USB_CONFIG block
+ */
+#define AR71XX_USB_CTRL_REG_FLADJ	0x00
+#define AR71XX_USB_CTRL_REG_CONFIG	0x04
+
+/*
  * RESET block
  */
 #define AR71XX_RESET_REG_TIMER			0x00
@@ -155,12 +170,17 @@
 #define AR71XX_RESET_PCI_BUS		BIT(1)
 #define AR71XX_RESET_PCI_CORE		BIT(0)
 
+#define AR7240_RESET_USB_HOST		BIT(5)
+#define AR7240_RESET_OHCI_DLL		BIT(3)
+
 #define AR724X_RESET_GE1_MDIO		BIT(23)
 #define AR724X_RESET_GE0_MDIO		BIT(22)
 #define AR724X_RESET_PCIE_PHY_SERIAL	BIT(10)
 #define AR724X_RESET_PCIE_PHY		BIT(7)
 #define AR724X_RESET_PCIE		BIT(6)
-#define AR724X_RESET_OHCI_DLL		BIT(3)
+#define AR724X_RESET_USB_HOST		BIT(5)
+#define AR724X_RESET_USB_PHY		BIT(4)
+#define AR724X_RESET_USBSUS_OVERRIDE	BIT(3)
 
 #define AR913X_RESET_AMBA2WMAC		BIT(22)
 
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:34:47 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:34:52 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48590 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491032Ab1ADU3N (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:13 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id D4A8345C022;
        Tue,  4 Jan 2011 21:29:05 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id D5A891F0001;
        Tue,  4 Jan 2011 21:29:04 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>,
        spi-devel-general@lists.sourceforge.net
Subject: [PATCH v5 09/16] spi: add SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
Date:   Tue,  4 Jan 2011 21:28:22 +0100
Message-Id: <1294172909-1309-10-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108D0900E1 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28838
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

The Atheros AR71XX/AR724X/AR913X SoCs have a built-in SPI controller. This
patch implements a driver for that.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: spi-devel-general@lists.sourceforge.net
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
Changes since RFC:
    - remove DRV_DESC definition and use its previous value directly in the
      MODULE_DESCRIPTION() macro,
    - use io{read,write}32 accesors instead of __raw_{read,write}l,
    - use __dev{init,exit,exit_p} annotations where in the appropriate places,
    - initialize 'master->bus_num' field to -1 if no platform data specified,
      so that a bus number can be dynamically assigned,
    - rename ath79_spi_drv to ath79_spi_driver to avoid section mismatch
      warnings

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4:
    - remove unused pdev field from struct ath79_spi
    - rename spidev_to_sp to ath79_spidev_to_sp
    - add ath79_spidev_controller_data structure
    - fix a typo in MODULE_DESCRIPTION

 .../include/asm/mach-ath79/ath79_spi_platform.h    |   23 ++
 drivers/spi/Kconfig                                |    8 +
 drivers/spi/Makefile                               |    1 +
 drivers/spi/ath79_spi.c                            |  292 ++++++++++++++++++++
 4 files changed, 324 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
 create mode 100644 drivers/spi/ath79_spi.c

diff --git a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
new file mode 100644
index 0000000..aa2283e
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
@@ -0,0 +1,23 @@
+/*
+ *  Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_SPI_PLATFORM_H
+#define _ATH79_SPI_PLATFORM_H
+
+struct ath79_spi_platform_data {
+	unsigned	bus_num;
+	unsigned	num_chipselect;
+};
+
+struct ath79_spi_controller_data {
+	unsigned	gpio;
+};
+
+#endif /* _ATH79_SPI_PLATFORM_H */
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 78f9fd0..f2093e1 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -53,6 +53,14 @@ if SPI_MASTER
 
 comment "SPI Master Controller Drivers"
 
+config SPI_ATH79
+	tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
+	depends on ATH79 && GENERIC_GPIO
+	select SPI_BITBANG
+	help
+	  This enables support for the SPI controller present on the
+	  Atheros AR71XX/AR724X/AR913X SoCs.
+
 config SPI_ATMEL
 	tristate "Atmel SPI Controller"
 	depends on (ARCH_AT91 || AVR32)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 8bc1a5a..875bc3d 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SPI_MASTER)		+= spi.o
 
 # SPI master controller drivers (bus)
 obj-$(CONFIG_SPI_ATMEL)			+= atmel_spi.o
+obj-$(CONFIG_SPI_ATH79)			+= ath79_spi.o
 obj-$(CONFIG_SPI_BFIN)			+= spi_bfin5xx.o
 obj-$(CONFIG_SPI_BITBANG)		+= spi_bitbang.o
 obj-$(CONFIG_SPI_AU1550)		+= au1550_spi.o
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
new file mode 100644
index 0000000..fcff810
--- /dev/null
+++ b/drivers/spi/ath79_spi.c
@@ -0,0 +1,292 @@
+/*
+ * SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
+ *
+ * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This driver has been based on the spi-gpio.c:
+ *	Copyright (C) 2006,2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79_spi_platform.h>
+
+#define DRV_NAME	"ath79-spi"
+
+struct ath79_spi {
+	struct spi_bitbang	bitbang;
+	u32			ioc_base;
+	u32			reg_ctrl;
+	void __iomem		*base;
+};
+
+static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
+{
+	return ioread32(sp->base + reg);
+}
+
+static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned reg, u32 val)
+{
+	iowrite32(val, sp->base + reg);
+}
+
+static inline struct ath79_spi *ath79_spidev_to_sp(struct spi_device *spi)
+{
+	return spi_master_get_devdata(spi->master);
+}
+
+static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
+{
+	struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+	int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
+
+	if (is_active) {
+		/* set initial clock polarity */
+		if (spi->mode & SPI_CPOL)
+			sp->ioc_base |= AR71XX_SPI_IOC_CLK;
+		else
+			sp->ioc_base &= ~AR71XX_SPI_IOC_CLK;
+
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+	}
+
+	if (spi->chip_select) {
+		struct ath79_spi_controller_data *cdata = spi->controller_data;
+
+		/* SPI is normally active-low */
+		gpio_set_value(cdata->gpio, cs_high);
+	} else {
+		if (cs_high)
+			sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+		else
+			sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+	}
+
+}
+
+static int ath79_spi_setup_cs(struct spi_device *spi)
+{
+	struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+	struct ath79_spi_controller_data *cdata;
+
+	cdata = spi->controller_data;
+	if (spi->chip_select && !cdata)
+		return -EINVAL;
+
+	/* enable GPIO mode */
+	ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
+
+	/* save CTRL register */
+	sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL);
+	sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC);
+
+	/* TODO: setup speed? */
+	ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
+
+	if (spi->chip_select) {
+		int status = 0;
+
+		status = gpio_request(cdata->gpio, dev_name(&spi->dev));
+		if (status)
+			return status;
+
+		status = gpio_direction_output(cdata->gpio,
+					       spi->mode & SPI_CS_HIGH);
+		if (status) {
+			gpio_free(cdata->gpio);
+			return status;
+		}
+	} else {
+		if (spi->mode & SPI_CS_HIGH)
+			sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+		else
+			sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+	}
+
+	return 0;
+}
+
+static void ath79_spi_cleanup_cs(struct spi_device *spi)
+{
+	struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+
+	if (spi->chip_select) {
+		struct ath79_spi_controller_data *cdata = spi->controller_data;
+		gpio_free(cdata->gpio);
+	}
+
+	/* restore CTRL register */
+	ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
+	/* disable GPIO mode */
+	ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
+}
+
+static int ath79_spi_setup(struct spi_device *spi)
+{
+	int status = 0;
+
+	if (spi->bits_per_word > 32)
+		return -EINVAL;
+
+	if (!spi->controller_state) {
+		status = ath79_spi_setup_cs(spi);
+		if (status)
+			return status;
+	}
+
+	status = spi_bitbang_setup(spi);
+	if (status && !spi->controller_state)
+		ath79_spi_cleanup_cs(spi);
+
+	return status;
+}
+
+static void ath79_spi_cleanup(struct spi_device *spi)
+{
+	ath79_spi_cleanup_cs(spi);
+	spi_bitbang_cleanup(spi);
+}
+
+static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
+			       u32 word, u8 bits)
+{
+	struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+	u32 ioc = sp->ioc_base;
+
+	/* clock starts at inactive polarity */
+	for (word <<= (32 - bits); likely(bits); bits--) {
+		u32 out;
+
+		if (word & (1 << 31))
+			out = ioc | AR71XX_SPI_IOC_DO;
+		else
+			out = ioc & ~AR71XX_SPI_IOC_DO;
+
+		/* setup MSB (to slave) on trailing edge */
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
+		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK);
+
+		word <<= 1;
+	}
+
+	return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
+}
+
+static __devinit int ath79_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct ath79_spi *sp;
+	struct ath79_spi_platform_data *pdata;
+	struct resource	*r;
+	int ret;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(*sp));
+	if (master == NULL) {
+		dev_err(&pdev->dev, "failed to allocate spi master\n");
+		return -ENOMEM;
+	}
+
+	sp = spi_master_get_devdata(master);
+	platform_set_drvdata(pdev, sp);
+
+	pdata = pdev->dev.platform_data;
+
+	master->setup = ath79_spi_setup;
+	master->cleanup = ath79_spi_cleanup;
+	if (pdata) {
+		master->bus_num = pdata->bus_num;
+		master->num_chipselect = pdata->num_chipselect;
+	} else {
+		master->bus_num = -1;
+		master->num_chipselect = 1;
+	}
+
+	sp->bitbang.master = spi_master_get(master);
+	sp->bitbang.chipselect = ath79_spi_chipselect;
+	sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
+	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
+	sp->bitbang.flags = SPI_CS_HIGH;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (r == NULL) {
+		ret = -ENOENT;
+		goto err_put_master;
+	}
+
+	sp->base = ioremap(r->start, r->end - r->start + 1);
+	if (!sp->base) {
+		ret = -ENXIO;
+		goto err_put_master;
+	}
+
+	ret = spi_bitbang_start(&sp->bitbang);
+	if (ret)
+		goto err_unmap;
+
+	return 0;
+
+err_unmap:
+	iounmap(sp->base);
+err_put_master:
+	platform_set_drvdata(pdev, NULL);
+	spi_master_put(sp->bitbang.master);
+
+	return ret;
+}
+
+static __devexit int ath79_spi_remove(struct platform_device *pdev)
+{
+	struct ath79_spi *sp = platform_get_drvdata(pdev);
+
+	spi_bitbang_stop(&sp->bitbang);
+	iounmap(sp->base);
+	platform_set_drvdata(pdev, NULL);
+	spi_master_put(sp->bitbang.master);
+
+	return 0;
+}
+
+static struct platform_driver ath79_spi_driver = {
+	.probe		= ath79_spi_probe,
+	.remove		= __devexit_p(ath79_spi_remove),
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static __init int ath79_spi_init(void)
+{
+	return platform_driver_register(&ath79_spi_driver);
+}
+module_init(ath79_spi_init);
+
+static __exit void ath79_spi_exit(void)
+{
+	platform_driver_unregister(&ath79_spi_driver);
+}
+module_exit(ath79_spi_exit);
+
+MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR913X");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:35:10 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:35:15 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48595 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491040Ab1ADU3O (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:14 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 76FA445C016;
        Tue,  4 Jan 2011 21:29:07 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id E8ABB1F0001;
        Tue,  4 Jan 2011 21:29:06 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        David Brownell <dbrownell@users.sourceforge.net>,
        Greg Kroah-Hartman <gregkh@suse.de>, linux-usb@vger.kernel.org
Subject: [PATCH v5 13/16] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs
Date:   Tue,  4 Jan 2011 21:28:26 +0100
Message-Id: <1294172909-1309-14-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108E63FC13 | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28839
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

The Atheros AR71XX/AR7240 SoCs have a built-in OHCI controller.
This patch adds the necessary glue code to make the generic OHCI
driver usable for them.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-usb@vger.kernel.org
---
Changes since RFC:
    - don't use 'defauly y if SOC_*', select the USB_ARCH_HAS_OHCI option
      in the platform specific Kconfig file instead
    - remove ath79_ehci_platform.h, it belongs to the EHCI patch

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2: ---

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/Kconfig       |    2 +
 drivers/usb/host/Kconfig      |    8 ++
 drivers/usb/host/ohci-ath79.c |  162 +++++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/ohci-hcd.c   |    5 +
 4 files changed, 177 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/host/ohci-ath79.c

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 647f535..d4456ce 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -16,10 +16,12 @@ endmenu
 
 config SOC_AR71XX
 	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
 	def_bool n
 
 config SOC_AR724X
 	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
 	def_bool n
 
 config SOC_AR913X
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3a2667a..39ed353 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -240,6 +240,14 @@ config USB_OHCI_HCD_OMAP3
 	  Enables support for the on-chip OHCI controller on
 	  OMAP3 and later chips.
 
+config USB_OHCI_ATH79
+	bool "USB OHCI support for the Atheros AR71XX/AR724X SoCs"
+	depends on USB_OHCI_HCD && (SOC_AR71XX || SOC_AR724X)
+	default y
+	help
+	  Enables support for the uilt-in OHCI controller present on the
+	  Atheros AR71XX/AR724X SoCs.
+
 config USB_OHCI_HCD_PPC_SOC
 	bool "OHCI support for on-chip PPC USB controller"
 	depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
diff --git a/drivers/usb/host/ohci-ath79.c b/drivers/usb/host/ohci-ath79.c
new file mode 100644
index 0000000..6e864bf
--- /dev/null
+++ b/drivers/usb/host/ohci-ath79.c
@@ -0,0 +1,162 @@
+/*
+ *  OHCI HCD (Host Controller Driver) for USB.
+ *
+ *  Bus Glue for Atheros AR71XX/AR724X built-in OHCI controller.
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *	Copyright (C) 2007 Atheros Communications, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+
+static int usb_hcd_ath79_probe(const struct hc_driver *driver,
+			       struct platform_device *pdev)
+{
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
+			dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+	irq = res->start;
+
+	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	if (!hcd)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "no base address specified for %s\n",
+			dev_name(&pdev->dev));
+		ret = -ENODEV;
+		goto err_put_hcd;
+	}
+	hcd->rsrc_start	= res->start;
+	hcd->rsrc_len	= res->end - res->start + 1;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		dev_dbg(&pdev->dev, "controller already in use\n");
+		ret = -EBUSY;
+		goto err_put_hcd;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_dbg(&pdev->dev, "error mapping memory\n");
+		ret = -EFAULT;
+		goto err_release_region;
+	}
+
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+	if (ret)
+		goto err_stop_hcd;
+
+	return 0;
+
+err_stop_hcd:
+	iounmap(hcd->regs);
+err_release_region:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+void usb_hcd_ath79_remove(struct usb_hcd *hcd, struct platform_device *pdev)
+{
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+}
+
+static int __devinit ohci_ath79_start(struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+	int ret;
+
+	ret = ohci_init(ohci);
+	if (ret < 0)
+		return ret;
+
+	ret = ohci_run(ohci);
+	if (ret < 0)
+		goto err;
+
+	return 0;
+
+err:
+	ohci_stop(hcd);
+	return ret;
+}
+
+static const struct hc_driver ohci_ath79_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "Atheros built-in OHCI controller",
+	.hcd_priv_size		= sizeof(struct ohci_hcd),
+
+	.irq			= ohci_irq,
+	.flags			= HCD_USB11 | HCD_MEMORY,
+
+	.start			= ohci_ath79_start,
+	.stop			= ohci_stop,
+	.shutdown		= ohci_shutdown,
+
+	.urb_enqueue		= ohci_urb_enqueue,
+	.urb_dequeue		= ohci_urb_dequeue,
+	.endpoint_disable	= ohci_endpoint_disable,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= ohci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ohci_hub_status_data,
+	.hub_control		= ohci_hub_control,
+	.start_port_reset	= ohci_start_port_reset,
+};
+
+static int ohci_hcd_ath79_drv_probe(struct platform_device *pdev)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	return usb_hcd_ath79_probe(&ohci_ath79_hc_driver, pdev);
+}
+
+static int ohci_hcd_ath79_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_hcd_ath79_remove(hcd, pdev);
+	return 0;
+}
+
+static struct platform_driver ohci_hcd_ath79_driver = {
+	.probe		= ohci_hcd_ath79_drv_probe,
+	.remove		= ohci_hcd_ath79_drv_remove,
+	.shutdown	= usb_hcd_platform_shutdown,
+	.driver		= {
+		.name	= "ath79-ohci",
+		.owner	= THIS_MODULE,
+	},
+};
+
+MODULE_ALIAS("platform:ath79-ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5179acb..6daeb68 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1111,6 +1111,11 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ohci_octeon_driver
 #endif
 
+#ifdef CONFIG_USB_OHCI_ATH79
+#include "ohci-ath79.c"
+#define PLATFORM_DRIVER		ohci_hcd_ath79_driver
+#endif
+
 #if	!defined(PCI_DRIVER) &&		\
 	!defined(PLATFORM_DRIVER) &&	\
 	!defined(OMAP1_PLATFORM_DRIVER) &&	\
-- 
1.7.2.1


From juhosg@openwrt.org Tue Jan  4 21:35:34 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 04 Jan 2011 21:35:39 +0100 (CET)
Received: from phoenix3.szarvasnet.hu ([87.101.127.16]:48596 "EHLO
        phoenix3.szarvasnet.hu" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491042Ab1ADU3R (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Tue, 4 Jan 2011 21:29:17 +0100
Received: from mail.szarvas.hu (localhost [127.0.0.1])
        by phoenix3.szarvasnet.hu (Postfix) with SMTP id 6BA8945C028;
        Tue,  4 Jan 2011 21:29:08 +0100 (CET)
Received: from localhost.localdomain (catvpool-576570d8.szarvasnet.hu [87.101.112.216])
        by phoenix3.szarvasnet.hu (Postfix) with ESMTPA id D72DF1F0001;
        Tue,  4 Jan 2011 21:29:07 +0100 (CET)
From:   Gabor Juhos <juhosg@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     linux-mips@linux-mips.org, Imre Kaloz <kaloz@openwrt.org>,
        "Luis R. Rodriguez" <lrodriguez@atheros.com>,
        Cliff Holden <Cliff.Holden@Atheros.com>,
        Kathy Giori <Kathy.Giori@Atheros.com>,
        Gabor Juhos <juhosg@openwrt.org>
Subject: [PATCH v5 16/16] MIPS: ath79: add common WMAC device for AR913X based boards
Date:   Tue,  4 Jan 2011 21:28:29 +0100
Message-Id: <1294172909-1309-17-git-send-email-juhosg@openwrt.org>
X-Mailer: git-send-email 1.7.2.1
In-Reply-To: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
References: <1294172909-1309-1-git-send-email-juhosg@openwrt.org>
X-VBMS: A108F5330BE | phoenix3 | 127.0.0.1 |  | <juhosg@openwrt.org> | 
Return-Path: <juhosg@openwrt.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: 28840
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: juhosg@openwrt.org
Precedence: bulk
X-list: linux-mips

Add common platform_device and helper code to make the registration
of the built-in wireless MAC easier on the Atheros AR9130/AR9132
based boards. Also register the WMAC device on the AR81 board.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC: ---

Changes since v1:
    - rebased against 2.6.37-rc7

Changes since v2:
    - don't use __init for function declarations

Changes since v3:
    - rebased against 2.6.37-rc8

Changes since v4: ---

 arch/mips/ath79/Kconfig                        |    5 ++
 arch/mips/ath79/Makefile                       |    1 +
 arch/mips/ath79/dev-ar913x-wmac.c              |   60 ++++++++++++++++++++++++
 arch/mips/ath79/dev-ar913x-wmac.h              |   17 +++++++
 arch/mips/ath79/mach-ap81.c                    |    6 ++
 arch/mips/include/asm/mach-ath79/ar71xx_regs.h |    3 +
 6 files changed, 92 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/ath79/dev-ar913x-wmac.c
 create mode 100644 arch/mips/ath79/dev-ar913x-wmac.h

diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 1912d54..af01669 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,6 +5,7 @@ menu "Atheros AR71XX/AR724X/AR913X machine selection"
 config ATH79_MACH_AP81
 	bool "Atheros AP81 reference board"
 	select SOC_AR913X
+	select ATH79_DEV_AR913X_WMAC
 	select ATH79_DEV_GPIO_BUTTONS
 	select ATH79_DEV_LEDS_GPIO
 	select ATH79_DEV_SPI
@@ -40,6 +41,10 @@ config SOC_AR913X
 	select USB_ARCH_HAS_EHCI
 	def_bool n
 
+config ATH79_DEV_AR913X_WMAC
+	depends on SOC_AR913X
+	def_bool n
+
 config ATH79_DEV_GPIO_BUTTONS
 	def_bool n
 
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 3d74e1c..57188b6 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
 # Devices
 #
 obj-y					+= dev-common.o
+obj-$(CONFIG_ATH79_DEV_AR913X_WMAC)	+= dev-ar913x-wmac.o
 obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o
 obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
 obj-$(CONFIG_ATH79_DEV_SPI)		+= dev-spi.o
diff --git a/arch/mips/ath79/dev-ar913x-wmac.c b/arch/mips/ath79/dev-ar913x-wmac.c
new file mode 100644
index 0000000..48f425a
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.c
@@ -0,0 +1,60 @@
+/*
+ *  Atheros AR913X SoC built-in WMAC device support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-ar913x-wmac.h"
+
+static struct ath9k_platform_data ar913x_wmac_data;
+
+static struct resource ar913x_wmac_resources[] = {
+	{
+		.start	= AR913X_WMAC_BASE,
+		.end	= AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= ATH79_CPU_IRQ_IP2,
+		.end	= ATH79_CPU_IRQ_IP2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ar913x_wmac_device = {
+	.name		= "ath9k",
+	.id		= -1,
+	.resource	= ar913x_wmac_resources,
+	.num_resources	= ARRAY_SIZE(ar913x_wmac_resources),
+	.dev = {
+		.platform_data = &ar913x_wmac_data,
+	},
+};
+
+void __init ath79_register_ar913x_wmac(u8 *cal_data)
+{
+	if (cal_data)
+		memcpy(ar913x_wmac_data.eeprom_data, cal_data,
+		       sizeof(ar913x_wmac_data.eeprom_data));
+
+	/* reset the WMAC */
+	ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
+	mdelay(10);
+
+	ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
+	mdelay(10);
+
+	platform_device_register(&ar913x_wmac_device);
+}
diff --git a/arch/mips/ath79/dev-ar913x-wmac.h b/arch/mips/ath79/dev-ar913x-wmac.h
new file mode 100644
index 0000000..579d562
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.h
@@ -0,0 +1,17 @@
+/*
+ *  Atheros AR913X SoC built-in WMAC device support
+ *
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_AR913X_WMAC_H
+#define _ATH79_DEV_AR913X_WMAC_H
+
+void ath79_register_ar913x_wmac(u8 *cal_data);
+
+#endif /* _ATH79_DEV_AR913X_WMAC_H */
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
index 909ca5d..03719b8 100644
--- a/arch/mips/ath79/mach-ap81.c
+++ b/arch/mips/ath79/mach-ap81.c
@@ -10,6 +10,7 @@
  */
 
 #include "machtypes.h"
+#include "dev-ar913x-wmac.h"
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
 #include "dev-spi.h"
@@ -26,6 +27,8 @@
 #define AP81_KEYS_POLL_INTERVAL		20	/* msecs */
 #define AP81_KEYS_DEBOUNCE_INTERVAL	(3 * AP81_KEYS_POLL_INTERVAL)
 
+#define AP81_CAL_DATA_ADDR	0x1fff1000
+
 static struct gpio_led ap81_leds_gpio[] __initdata = {
 	{
 		.name		= "ap81:green:status",
@@ -80,6 +83,8 @@ static struct ath79_spi_platform_data ap81_spi_data = {
 
 static void __init ap81_setup(void)
 {
+	u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR);
+
 	ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
 				 ap81_leds_gpio);
 	ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
@@ -88,6 +93,7 @@ static void __init ap81_setup(void)
 	ath79_register_spi(&ap81_spi_data, ap81_spi_info,
 			   ARRAY_SIZE(ap81_spi_info));
 	ath79_register_usb();
+	ath79_register_ar913x_wmac(cal_data);
 }
 
 MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index f125f1e..9beb073 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -43,6 +43,9 @@
 #define AR7240_OHCI_BASE	0x1b000000
 #define AR7240_OHCI_SIZE	0x1000
 
+#define AR913X_WMAC_BASE	(AR71XX_APB_BASE + 0x000C0000)
+#define AR913X_WMAC_SIZE	0x30000
+
 /*
  * DDR_CTRL block
  */
-- 
1.7.2.1


From anoop.pa@gmail.com Wed Jan  5 13:58:07 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 13:58:10 +0100 (CET)
Received: from mail-qy0-f177.google.com ([209.85.216.177]:53999 "EHLO
        mail-qy0-f177.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490979Ab1AEM6H (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Wed, 5 Jan 2011 13:58:07 +0100
Received: by qyk27 with SMTP id 27so17921867qyk.15
        for <linux-mips@linux-mips.org>; Wed, 05 Jan 2011 04:57:57 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:subject:from:to:cc
         :in-reply-to:references:content-type:date:message-id:mime-version
         :x-mailer;
        bh=Mrfhkv6WpyKQg5S9CWaJmkXATOdV/n53Q+DBfOmOqZE=;
        b=rXMl2If0xWpVbYH0qCVXgJoIP+4w4m3mOayZkiLfKydf5oUEYntg5F69oEFEmDxW0l
         peoLsrEleEcwdQfr2Rq8QbtJ+jtR5fyX/gncOU0NBU+HZCnrOYEARiyQDePFa6WODeWb
         pYgJLwAdPjbZ/LtJzDAdnCV0/yZOB78mk2tOA=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=subject:from:to:cc:in-reply-to:references:content-type:date
         :message-id:mime-version:x-mailer;
        b=TgDeu6YBLu57guBicMuj7kNkRINQ01WJk5YIFqGHP/TgIljDKagnEH4sC0d+iPw00e
         D4rUaWZFRmjVos/o9uzouOvHMyp5zPoKeQjd/Bdn6AzFYhvrw6v83binelkhf+jBTglR
         rvJoX1IYCKbpN6lYqBuRYgfS3CbkoufKGv+kw=
Received: by 10.224.11.130 with SMTP id t2mr6237478qat.231.1294232277081;
        Wed, 05 Jan 2011 04:57:57 -0800 (PST)
Received: from [172.16.48.51] ([59.160.135.215])
        by mx.google.com with ESMTPS id q12sm13543818qcu.30.2011.01.05.04.57.50
        (version=SSLv3 cipher=RC4-MD5);
        Wed, 05 Jan 2011 04:57:53 -0800 (PST)
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
In-Reply-To: <4D235B8D.2070306@paralogos.com>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
         <1293470392.27661.202.camel@paanoop1-desktop>
         <1293524389.27661.210.camel@paanoop1-desktop>
         <4D19A31E.1090905@paralogos.com>
         <1293798476.27661.279.camel@paanoop1-desktop>
         <4D1EE913.1070203@paralogos.com>
         <1294067561.27661.293.camel@paanoop1-desktop>
         <4D21F5D3.50604@paralogos.com>
         <1294082426.27661.330.camel@paanoop1-desktop>
         <4D22D7B3.2050609@paralogos.com>
         <1294146165.27661.361.camel@paanoop1-desktop>
         <4D235B8D.2070306@paralogos.com>
Content-Type: multipart/mixed; boundary="=-Qqs3Zx4HpWKhg0KdYC5/"
Date:   Wed, 05 Jan 2011 18:39:17 +0530
Message-ID: <1294232957.27661.389.camel@paanoop1-desktop>
Mime-Version: 1.0
X-Mailer: Evolution 2.28.3 
Return-Path: <anoop.pa@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: 28841
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips


--=-Qqs3Zx4HpWKhg0KdYC5/
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit

On Tue, 2011-01-04 at 09:40 -0800, Kevin D. Kissell wrote:
> On 01/04/11 05:02, Anoop P A wrote:
> > On Tue, 2011-01-04 at 00:17 -0800, Kevin D. Kissell wrote:
> >> Those interrupt counters show that IPIs are being taken everywhere,
> >> though very few by CPUs 5 and 6.  If I understand the configuration
> >> correctly, CPU 4 is a TC in VPE 1, and it's getting a reasonable IPI
> > Yes CPU4 is in second VPE
> >
> >> rate, *if* we're looking at a tickless kernel under low load.  But there
> > No it was not the tickless kernel.I had selected 250 MHz timer. can't we
> > expect IPI / timer interrupt for all the threads in this case ?.
> 
> In that case, you should expect a distribution of timer interrupts that 
> favors the low-numbered TCs within the VPE, as you do in VPE0, and a 
> distribution of IPIs that is sort-of the inverse, as you do in VPE0.  
> But the low counts on VPE1 are indeed suspicious, as you note.
> 
> >> may be a clue there to part of your problem.  I have no idea why the
> >> behavior would have changed from 2.6.36 to 2.6.37, but it looks as if
> >> you're getting your clock interrupts through the MSP CIC interrupt
> >> controller on VPE 0.  There's nothing symmetric for VPE1. The Malta
> >> example code is perhaps deceptively simple, in that both VPEs have their
> >> count/compare indication wired directly to the 2 clock interrupt inputs,
> >> so that having both of them running with only a single set of irq state
> >> just works.  I don't know whether the MSP CIC timer interrupt is a
> > In my case it is separate irq. MSP_INT_VPE1_TIMER (34) and
> > MSP_INT_VPE0_TIMER (25) are wired to CIC . CIC interrupt has been
> > connected to cpu irq 6.
> >
> > I can reproduce cpu stall in VSMP mode If I don't setup VPE1 timer
> > interrupt . Don't we have support for separate irq in SMTC
> > implementation ?..
> 
> There are hooks for platform-specific SMTC support, which is implemented 
> for the Malta in arch/mips/mti-malta/malta-smtc.c.  See 
> msmtc_init_secondary(), for example, where the clock/compare, profile, 
> and IPI interrupts are armed for VPE 1, while I/O peripheral interrupts 
> are inhibited.
> 
> >> gating of the VPE0 count/compare output, or whether it's it's own
> >> interval timer, but I suspect that you may need to do some further
> >> low-level initialization in the platform-specific code to set up an
> >> interrupt on the VPE1 side.  I don't think the snippet you've got below
> >> would work as written.
> > The routine which I copied works fine for VSMP mode .
> >
> > / # cat /proc/interrupts
> >             CPU0       CPU1
> >    0:        187        254            MIPS  IPI_resched
> >    1:         77        174            MIPS  IPI_call
> >    6:          0          0            MIPS  MSP CIC cascade
> >    8:          0          0         MSP_CIC  Softreset button
> >    9:          0          0         MSP_CIC  Standby switch
> >   21:          0          0         MSP_CIC  MSP PER cascade
> >   25:      37077          0         MSP_CIC  timer
> >   27:        188          0         MSP_CIC  serial
> >   34:          0      36986         MSP_CIC  timer
> >
> > Do I want to change anything specific for SMTC ? .
> 
> If it works (which I doubt), then we can critique stylistic points like 
> using
> 
> 		if ((1==get_current_vpe())
> 
> Instead of the more readable and general
> 
> 		if (get_current_vpe()>  0)
> 
> 
> But I think you're generally looking in the wrong place.  Look at the 
> Malta code and see what's done where.  The initial SMTC code had a lot 
> of Malta assumptions in the main line that I pushed out to platform code 
> in later patches.  I can see how things could be made even more modular, 
> but for the moment I think it's just that there's some stuff that ought 
> to be done in a "msp_smtc.c" file that doesn't exist in 2.6.37.
Yes , I am doing similar stuff in msp_smtc.c . Attaching code for your
reference. I am not seeing a VPE1 timer interrupt.

> 
>              Regards,
> 
>              Kevin K.
> >
> >
> >> If it's purely an issue with clock distribution on VPE1, then a boot
> >> with maxvpes=1 maxtcs=4 should be stable.
> > Yes the kernel seems to be stable if I boot with maxvpes=1 maxtcs=4 .
> >
> >> /K.
> >>
> >> On 1/3/2011 11:20 AM, Anoop P A wrote:
> >>> Hi Kevin,
> >>>
> >>> On Mon, 2011-01-03 at 08:14 -0800, Kevin D. Kissell wrote:
> >>>> The very first SMTC implementations didn't support full kernel-mode
> >>>> preemption, which anyway wasn't a priority, given the hardware event
> >>>> response support in MIPS MT.  I believe it was later made compatible,
> >>>> but it was never extensively exercised.  Since SMTC has fingers in some
> >>>> pretty low-level atomicity mechanisms, if a new, parallel set was
> >>>> implemented for RCU, I can easily imagine that nobody has yet
> >>>> implemented SMTC-ified variants of that set.
> >>>>
> >>>> Your last statement isn't very clear, though.  Are you saying that if
> >>>> you configure for no forced preemption and with TREE_CPU, the 2.6.37
> >>>> kernel boots all the way up, or that it simply hangs later?   What's the
> >>>> last rev kernel that actually boots all the way up?
> >>> I have debugged this a bit more. It seems that kernel getting stalled
> >>> while executing on TC's of second VPE .
> >>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>> by 1, t=2504 jiffies)
> >>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>> by 1, t=10036 jiffies)
> >>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>> by 1, t=17568 jiffies)
> >>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>> by 1, t=25100 jiffies)
> >>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>> by 1, t=32632 jiffies)
> >>> INFO: rcu_sched_state detected stalls on CPUs/tasks: { 4 5 6} (detected
> >>> by 1, t=40164 jiffies)
> >>>
> >>> With CONFIG_TREE_CPU we were not hitting this scenario very often.
> >>> However with CONFIG_PREEMPT_TREE_CPU stall happens most of the time.
> >>>
> >>> I presume some issue in my timer setup . I am not seeing timer interrupt
> >>> (or IPI interrupt) getting  incremented for VPE1 tcs on a completely
> >>> booted 2.6.32-stable kernel.
> >>>
> >>> / # cat /proc/interrupts
> >>>             CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
> >>> CPU6
> >>>    1:        148      15023      15140      15093       3779          8
> >>> 2            MIPS  SMTC_IPI
> >>>    6:          0          0          0          0          0          0
> >>> 0            MIPS  MSP CIC cascade
> >>>    8:          0          0          0          0          0          0
> >>> 0         MSP_CIC  Softreset button
> >>>    9:          0          0          0          0          0          0
> >>> 0         MSP_CIC  Standby switch
> >>>   21:          0          0          0          0          0          0
> >>> 0         MSP_CIC  MSP PER cascade
> >>>   25:      15113        341          4          7          0          0
> >>> 0         MSP_CIC  timer
> >>>   27:        260          9          0          1          0          0
> >>> 0         MSP_CIC  serial
> >>>   34:          0          0          0          0          0          0
> >>> 0         MSP_CIC  timer
> >>>
> >>> Can't we use separate timer interrupts for VPE1 and VPE0 in SMTC ?.
> >>>
> >>> I have tried setting up VPE1 timer from get_co_compare_int as follows
> >>>
> >>> unsigned int __cpuinit get_c0_compare_int(void)
> >>> {
> >>> 	if ((1==get_current_vpe())&&  !vpe1_timr_installed){
> >>> 	
> >>> 	memcpy(&timer_vpe1,&c0_compare_irqaction,sizeof(timer_vpe1));
> >>> 	
> >>> 	setup_irq(MSP_INT_VPE1_TIMER,&timer_vpe1);
> >>>                    vpe1_timr_installed++;
> >>>            }
> >>>            return (get_current_vpe() ? MSP_INT_VPE1_TIMER :
> >>> MSP_INT_VPE0_TIMER);
> >>> }
> >>>
> >>> Thanks
> >>> Anoop
> 


--=-Qqs3Zx4HpWKhg0KdYC5/
Content-Disposition: attachment; filename="msp_smtc.c"
Content-Type: text/x-csrc; name="msp_smtc.c"; charset="UTF-8"
Content-Transfer-Encoding: 7bit

/*
 * MSP71xx Platform-specific hooks for SMP operation.
 * Started from malta-smtc.c.
 */
#include <linux/irq.h>
#include <linux/init.h>
#include <linux/sched.h>

#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
#include <asm/smtc.h>
#include <asm/smtc_ipi.h>

/* VPE/SMP Prototype implements platform interfaces directly */

/*
 * Cause the specified action to be performed on a targeted "CPU"
 */

static void msp_smtc_send_ipi_single(int cpu, unsigned int action)
{
	/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
	smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
}

static void msp_smtc_send_ipi_mask(const struct cpumask *mask, unsigned int action)
{
	unsigned int i;

	for_each_cpu(i, mask)
		msp_smtc_send_ipi_single(i, action);
}

/*
 * Post-config but pre-boot cleanup entry point
 */
static int prev_vpe;
static void __cpuinit msp_smtc_init_secondary(void)
{
	void smtc_init_secondary(void);
	int myvpe;

	myvpe = read_c0_tcbind() & TCBIND_CURVPE;
	/* Change status register when we switch to new VPE*/
	if ((myvpe != prev_vpe) && (myvpe > 0)) {
		change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
					 STATUSF_IP6 | STATUSF_IP7);
	}
	prev_vpe = myvpe;
	
	smtc_init_secondary();
}

/*
 * Platform "CPU" startup hook
 */
static void __cpuinit msp_smtc_boot_secondary(int cpu, struct task_struct *idle)
{
	
	smtc_boot_secondary(cpu, idle);
}

/*
 * SMP initialization finalization entry point
 */
static void __cpuinit msp_smtc_smp_finish(void)
{
	smtc_smp_finish();
}

/*
 * Hook for after all CPUs are online
 */

static void msp_smtc_cpus_done(void)
{
}

/*
 * Platform SMP pre-initialization
 *
 * As noted above, we can assume a single CPU for now
 * but it may be multithreaded.
 */

static void __init msp_smtc_smp_setup(void)
{
	/*
	 * we won't get the definitive value until
	 * we've run smtc_prepare_cpus later, but
	 */
	if (read_c0_config3() & (1 << 2))
	smp_num_siblings = smtc_build_cpu_map(0);
}

static void __init msp_smtc_prepare_cpus(unsigned int max_cpus)
{
	smtc_prepare_cpus(max_cpus);
}

struct plat_smp_ops msp_smtc_smp_ops = {
	.send_ipi_single	= msp_smtc_send_ipi_single,
	.send_ipi_mask		= msp_smtc_send_ipi_mask,
	.init_secondary		= msp_smtc_init_secondary,
	.smp_finish		= msp_smtc_smp_finish,
	.cpus_done		= msp_smtc_cpus_done,
	.boot_secondary		= msp_smtc_boot_secondary,
	.smp_setup		= msp_smtc_smp_setup,
	.prepare_cpus		= msp_smtc_prepare_cpus,
};

#if 0
/* TODO */
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
/*
 * IRQ affinity hook
 */


int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
{
	cpumask_t tmask;
	int cpu = 0;
	void smtc_set_irq_affinity(unsigned int irq, cpumask_t aff);

	cpumask_copy(&tmask, affinity);
	for_each_cpu(cpu, affinity) {
		if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu))
			cpu_clear(cpu, tmask);
	}
	cpumask_copy(irq_desc[irq].affinity, &tmask);

	if (cpus_empty(tmask))
		/*
		 * We could restore a default mask here, but the
		 * runtime code can anyway deal with the null set
		 */
		printk(KERN_WARNING
			"IRQ affinity leaves no legal CPU for IRQ %d\n", irq);

	/* Do any generic SMTC IRQ affinity setup */
	smtc_set_irq_affinity(irq, tmask);

	return 0;
}
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
#endif

--=-Qqs3Zx4HpWKhg0KdYC5/--


From anoop.pa@gmail.com Wed Jan  5 14:00:22 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 14:00:25 +0100 (CET)
Received: from mail-qw0-f49.google.com ([209.85.216.49]:35168 "EHLO
        mail-qw0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490978Ab1AENAW (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Wed, 5 Jan 2011 14:00:22 +0100
Received: by qwj9 with SMTP id 9so15536937qwj.36
        for <linux-mips@linux-mips.org>; Wed, 05 Jan 2011 05:00:14 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:subject:from:to:cc
         :in-reply-to:references:content-type:date:message-id:mime-version
         :x-mailer:content-transfer-encoding;
        bh=BQFz5QfUbxZWrTtjsTaa8tDSJIQYFFJEB0P64Idydq0=;
        b=dxM0e/SD2Vz030ihfK3hD9mCZw/YhgAo+MP13WWVKIW7aSCrJoXcr+7iL/jcWDDfbU
         bt1FOMOyCCj46CEuDi1O5g7gubJof7pvah+9M0ckJYhpZHEZna9MLITktrKY9Wzbpqxa
         SEP+iQ4EUy5LseFg8sZQXSoOpA1MbvZvkxLtk=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=subject:from:to:cc:in-reply-to:references:content-type:date
         :message-id:mime-version:x-mailer:content-transfer-encoding;
        b=YTv5SHgfmTphIdlATbQWibw3iDqAiAPIOm/CsHzbQBmbzNDzjqi5ulImjR7mSroQn7
         ebqeCkkytPMpgqkpWEAvhl74IQSrQaRrATzyyJGUSfkMoFL+BVCulHkFO2pZkukhMDF0
         Yzc73dO6FODvEbpaMtU7Wd1dPfaUJbf17tRtU=
Received: by 10.229.75.9 with SMTP id w9mr19952980qcj.108.1294232414468;
        Wed, 05 Jan 2011 05:00:14 -0800 (PST)
Received: from [172.16.48.51] ([59.160.135.215])
        by mx.google.com with ESMTPS id q12sm13542015qcu.6.2011.01.05.05.00.11
        (version=SSLv3 cipher=RC4-MD5);
        Wed, 05 Jan 2011 05:00:13 -0800 (PST)
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
In-Reply-To: <4D2367EE.7000702@paralogos.com>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
         <1293470392.27661.202.camel@paanoop1-desktop>
         <1293524389.27661.210.camel@paanoop1-desktop>
         <4D19A31E.1090905@paralogos.com>
         <1293798476.27661.279.camel@paanoop1-desktop>
         <4D1EE913.1070203@paralogos.com>
         <1294067561.27661.293.camel@paanoop1-desktop>
         <4D21F5D3.50604@paralogos.com>
         <1294082426.27661.330.camel@paanoop1-desktop>
         <4D22D7B3.2050609@paralogos.com>
         <1294146165.27661.361.camel@paanoop1-desktop>
         <1294151822.27661.375.camel@paanoop1-desktop>
         <4D235717.1000603@paralogos.com>
         <1294163657.27661.386.camel@paanoop1-desktop>
         <4D2367EE.7000702@paralogos.com>
Content-Type: text/plain; charset="UTF-8"
Date:   Wed, 05 Jan 2011 18:41:37 +0530
Message-ID: <1294233097.27661.391.camel@paanoop1-desktop>
Mime-Version: 1.0
X-Mailer: Evolution 2.28.3 
Content-Transfer-Encoding: 7bit
Return-Path: <anoop.pa@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: 28842
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips

On Tue, 2011-01-04 at 10:33 -0800, Kevin D. Kissell wrote:
> On 01/04/11 09:54, Anoop P A wrote:
> > On Tue, 2011-01-04 at 09:21 -0800, Kevin D. Kissell wrote:
> >> I'm trying to figure out a reason why your change below should help, and
> >> offhand, modulo tool bugs, I don't see it.  I'm assuming that your diff
> >> below is a diff relative to the pre-patch stackframe.h.   I wouldn't
> > Yes patch created against stock code .
> >
> >> bless it as an alternative because it moves code and comments
> >> unnecessarily - all you should really have to do is to move the
> >>
> >>
> >>    190                 mfc0    v1, CP0_STATUS
> >>    191                 LONG_S  $2, PT_R2(sp)
> >>
> >> to be just after the #endif /* CONFIG_MIPS_MT_SMTC */ at around line 201.
> > Actually I just moved code under CONFIG_MIPS_MT_SMTC to previous block
> > of code ( which store $0 ) . git diff did the rest on behalf of me :)
> >
> >> If moving the save of zero to PT_R0(sp) actually makes a difference,
> >> it's evidence that you've got problems in your toolchain (or, heaven
> >> forbid, your pipeline)!
> > In previous version of patch usage of V0 was creating issue. I have
> > verified this with previous version of code ( working code before
> > David's instruction rearrangement patch.) .
> 
> Argh.  It's not very clearly commented, but it looks as if the system 
> call trap handler has an implicit assumption that v0 has never been 
> changed by SAVE_SOME, TRACE_IRQS_ON_RELOAD, or STI.  So yeah, moving the 
> code around to fix the v1 conflict ends up being better than using v0 - 
> otherwise, we'd need to add a LONG_L v0, PT_R2(sp) somewhere after the 
> LONG_S v0, PT_TCSTATUS(sp) of the original patch.
Well, Here is the patch.

diff --git a/arch/mips/include/asm/stackframe.h
b/arch/mips/include/asm/stackframe.h
index 58730c5..19418c4 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -187,8 +187,6 @@
 		 * need it to operate correctly
 		 */
 		LONG_S	$0, PT_R0(sp)
-		mfc0	v1, CP0_STATUS
-		LONG_S	$2, PT_R2(sp)
 #ifdef CONFIG_MIPS_MT_SMTC
 		/*
 		 * Ideally, these instructions would be shuffled in
@@ -199,6 +197,8 @@
 		.set	mips0
 		LONG_S	v1, PT_TCSTATUS(sp)
 #endif /* CONFIG_MIPS_MT_SMTC */
+		mfc0	v1, CP0_STATUS
+		LONG_S	$2, PT_R2(sp)
 		LONG_S	$4, PT_R4(sp)
 		LONG_S	$5, PT_R5(sp)
 		LONG_S	v1, PT_STATUS(sp)


> 
>              Regards,
> 
>              Kevin K.



From kevink@paralogos.com Wed Jan  5 20:23:21 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:23:24 +0100 (CET)
Received: from gateway01.websitewelcome.com ([69.93.139.19]:46183 "HELO
        gateway01.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1490958Ab1AETXV (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Wed, 5 Jan 2011 20:23:21 +0100
Received: (qmail 9604 invoked from network); 5 Jan 2011 19:22:53 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway01.websitewelcome.com with SMTP; 5 Jan 2011 19:22:53 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=HM6JhP31QDGYGCrZCeCq57wQKYk5IANoTR8HN73SBqoTUvgbxKOIfU90iBzstuMkoTpyh7XrUj1yZX2eMOq3z0DbhyL/XhM1QxES7NA4A9RwWHrHQFpZaenyPCSTVM59;
Received: from [216.239.45.4] (port=34984 helo=kkissell.mtv.corp.google.com)
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1PaYx0-0006Fz-OA; Wed, 05 Jan 2011 13:23:14 -0600
Message-ID: <4D24C525.5000306@paralogos.com>
Date:   Wed, 05 Jan 2011 11:23:17 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101208 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Anoop P A <anoop.pa@gmail.com>
CC:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Subject: Re: SMTC support status in latest git head.
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>         <1293470392.27661.202.camel@paanoop1-desktop>         <1293524389.27661.210.camel@paanoop1-desktop>         <4D19A31E.1090905@paralogos.com>         <1293798476.27661.279.camel@paanoop1-desktop>         <4D1EE913.1070203@paralogos.com>         <1294067561.27661.293.camel@paanoop1-desktop>         <4D21F5D3.50604@paralogos.com>         <1294082426.27661.330.camel@paanoop1-desktop>         <4D22D7B3.2050609@paralogos.com>         <1294146165.27661.361.camel@paanoop1-desktop>         <1294151822.27661.375.camel@paanoop1-desktop>         <4D235717.1000603@paralogos.com>         <1294163657.27661.386.camel@paanoop1-desktop>         <4D2367EE.7000702@paralogos.com> <1294233097.27661.391.camel@paanoop1-desktop>
In-Reply-To: <1294233097.27661.391.camel@paanoop1-desktop>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28843
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

On 01/05/11 05:11, Anoop P A wrote:
> On Tue, 2011-01-04 at 10:33 -0800, Kevin D. Kissell wrote:
>> On 01/04/11 09:54, Anoop P A wrote:
>>> On Tue, 2011-01-04 at 09:21 -0800, Kevin D. Kissell wrote:
>>>> I'm trying to figure out a reason why your change below should help, and
>>>> offhand, modulo tool bugs, I don't see it.  I'm assuming that your diff
>>>> below is a diff relative to the pre-patch stackframe.h.   I wouldn't
>>> Yes patch created against stock code .
>>>
>>>> bless it as an alternative because it moves code and comments
>>>> unnecessarily - all you should really have to do is to move the
>>>>
>>>>
>>>>     190                 mfc0    v1, CP0_STATUS
>>>>     191                 LONG_S  $2, PT_R2(sp)
>>>>
>>>> to be just after the #endif /* CONFIG_MIPS_MT_SMTC */ at around line 201.
>>> Actually I just moved code under CONFIG_MIPS_MT_SMTC to previous block
>>> of code ( which store $0 ) . git diff did the rest on behalf of me :)
>>>
>>>> If moving the save of zero to PT_R0(sp) actually makes a difference,
>>>> it's evidence that you've got problems in your toolchain (or, heaven
>>>> forbid, your pipeline)!
>>> In previous version of patch usage of V0 was creating issue. I have
>>> verified this with previous version of code ( working code before
>>> David's instruction rearrangement patch.) .
>> Argh.  It's not very clearly commented, but it looks as if the system
>> call trap handler has an implicit assumption that v0 has never been
>> changed by SAVE_SOME, TRACE_IRQS_ON_RELOAD, or STI.  So yeah, moving the
>> code around to fix the v1 conflict ends up being better than using v0 -
>> otherwise, we'd need to add a LONG_L v0, PT_R2(sp) somewhere after the
>> LONG_S v0, PT_TCSTATUS(sp) of the original patch.
> Well, Here is the patch.
>
> diff --git a/arch/mips/include/asm/stackframe.h
> b/arch/mips/include/asm/stackframe.h
> index 58730c5..19418c4 100644
> --- a/arch/mips/include/asm/stackframe.h
> +++ b/arch/mips/include/asm/stackframe.h
> @@ -187,8 +187,6 @@
>   		 * need it to operate correctly
>   		 */
>   		LONG_S	$0, PT_R0(sp)
> -		mfc0	v1, CP0_STATUS
> -		LONG_S	$2, PT_R2(sp)
>   #ifdef CONFIG_MIPS_MT_SMTC
>   		/*
>   		 * Ideally, these instructions would be shuffled in
> @@ -199,6 +197,8 @@
>   		.set	mips0
>   		LONG_S	v1, PT_TCSTATUS(sp)
>   #endif /* CONFIG_MIPS_MT_SMTC */
> +		mfc0	v1, CP0_STATUS
> +		LONG_S	$2, PT_R2(sp)
>   		LONG_S	$4, PT_R4(sp)
>   		LONG_S	$5, PT_R5(sp)
>   		LONG_S	v1, PT_STATUS(sp)

That's exactly what I'd propose as the cleanest minimal fix.  I've got a 
version that also replaces the .set mips32 / .set mips0 with the .set 
push / .set pop paradigm, which I'd have used in the original code if 
I'd known at the time about that assembler directive.  I'm hoping to be 
able to test on a Malta/34K reference platform, and make sure there 
isn't breakage on that platform branch as well, before we commit to the 
repository.

Your msp_smtc.c file looks plausible on the face of it.  The 
init_secondary function has the quirk that it expects to execute on each 
"CPU" in numerical order, which is very likely but not guaranteed. It 
*ought* to be harmless in the rare case where it fails, but the 
assumption is worth a comment, IMHO.

At this point, there shouldn't be a whole lot of SMTC-specific mystery 
to get your timer running on the second VPE.  You know it's taking 
interrupts, because of the IPIs getting through, so in principle you 
just need to run the chain of enables from the clock peripheral itself 
through the CIC to the CPU core and the IM bits.

It would be really cool if we could get a stable repository branch that 
boots SMTC out-of-the-box on both Malta and the MSP platform.

             Regards,

             Kevin K.



From blogic@openwrt.org Wed Jan  5 20:55:31 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:55:34 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35658 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490958Ab1AETza (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:30 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        linux-mips@linux-mips.org
Subject: [PATCH 00/10] MIPS: add support for Lantiq SoCs
Date:   Wed,  5 Jan 2011 20:56:09 +0100
Message-Id: <1294257379-417-1-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
Return-Path: <blogic@openwrt.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: 28844
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

This series will add support for the Lantiq/XWAY family of SoCs.

Cc: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: linux-mips@linux-mips.org

John Crispin (10):
  MIPS: lantiq: add initial support for Lantiq SoCs
  MIPS: lantiq: add SoC specific code for XWAY family
  MIPS: lantiq: add PCI controller support.
  MIPS: lantiq: add serial port support
  MIPS: lantiq: add watchdog support
  MIPS: lantiq: add NOR flash support
  MIPS: lantiq: add NOR flash CFI address swizzle
  MIPS: lantiq: add platform device support
  MIPS: lantiq: add mips_machine support
  MIPS: lantiq: add machtypes for lantiq eval kits

 arch/mips/Kbuild.platforms                         |    1 +
 arch/mips/Kconfig                                  |   18 +
 arch/mips/include/asm/mach-lantiq/lantiq.h         |   48 ++
 .../mips/include/asm/mach-lantiq/lantiq_platform.h |   25 +
 arch/mips/include/asm/mach-lantiq/war.h            |   24 +
 arch/mips/include/asm/mach-lantiq/xway/irq.h       |   18 +
 .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h |   62 ++
 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |  119 +++
 arch/mips/lantiq/Kconfig                           |   23 +
 arch/mips/lantiq/Makefile                          |   11 +
 arch/mips/lantiq/Platform                          |    8 +
 arch/mips/lantiq/clk.c                             |  129 ++++
 arch/mips/lantiq/clk.h                             |   18 +
 arch/mips/lantiq/devices.c                         |  127 ++++
 arch/mips/lantiq/devices.h                         |   20 +
 arch/mips/lantiq/early_printk.c                    |   47 ++
 arch/mips/lantiq/irq.c                             |  209 ++++++
 arch/mips/lantiq/machtypes.h                       |   20 +
 arch/mips/lantiq/prom.c                            |   84 +++
 arch/mips/lantiq/prom.h                            |   26 +
 arch/mips/lantiq/setup.c                           |   70 ++
 arch/mips/lantiq/xway/Kconfig                      |   25 +
 arch/mips/lantiq/xway/Makefile                     |    7 +
 arch/mips/lantiq/xway/clk-ase.c                    |   53 ++
 arch/mips/lantiq/xway/clk-xway.c                   |  221 ++++++
 arch/mips/lantiq/xway/devices.c                    |   55 ++
 arch/mips/lantiq/xway/devices.h                    |   16 +
 arch/mips/lantiq/xway/gpio.c                       |  205 ++++++
 arch/mips/lantiq/xway/mach-easy50601.c             |   70 ++
 arch/mips/lantiq/xway/mach-easy50712.c             |   70 ++
 arch/mips/lantiq/xway/pmu.c                        |   36 +
 arch/mips/lantiq/xway/prom-ase.c                   |   41 +
 arch/mips/lantiq/xway/prom-xway.c                  |   56 ++
 arch/mips/lantiq/xway/reset.c                      |   53 ++
 arch/mips/pci/Makefile                             |    1 +
 arch/mips/pci/ops-lantiq.c                         |  118 +++
 arch/mips/pci/pci-lantiq.c                         |  286 ++++++++
 arch/mips/pci/pci-lantiq.h                         |   18 +
 drivers/mtd/chips/Kconfig                          |    9 +
 drivers/mtd/chips/cfi_cmdset_0002.c                |    8 +
 drivers/mtd/maps/Kconfig                           |    7 +
 drivers/mtd/maps/Makefile                          |    1 +
 drivers/mtd/maps/lantiq.c                          |  169 +++++
 drivers/serial/Kconfig                             |    8 +
 drivers/serial/Makefile                            |    1 +
 drivers/serial/lantiq.c                            |  774 ++++++++++++++++++++
 drivers/watchdog/Kconfig                           |    6 +
 drivers/watchdog/Makefile                          |    1 +
 drivers/watchdog/lantiq_wdt.c                      |  208 ++++++
 49 files changed, 3630 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq.h
 create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_platform.h
 create mode 100644 arch/mips/include/asm/mach-lantiq/war.h
 create mode 100644 arch/mips/include/asm/mach-lantiq/xway/irq.h
 create mode 100644 arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
 create mode 100644 arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
 create mode 100644 arch/mips/lantiq/Kconfig
 create mode 100644 arch/mips/lantiq/Makefile
 create mode 100644 arch/mips/lantiq/Platform
 create mode 100644 arch/mips/lantiq/clk.c
 create mode 100644 arch/mips/lantiq/clk.h
 create mode 100644 arch/mips/lantiq/devices.c
 create mode 100644 arch/mips/lantiq/devices.h
 create mode 100644 arch/mips/lantiq/early_printk.c
 create mode 100644 arch/mips/lantiq/irq.c
 create mode 100644 arch/mips/lantiq/machtypes.h
 create mode 100644 arch/mips/lantiq/prom.c
 create mode 100644 arch/mips/lantiq/prom.h
 create mode 100644 arch/mips/lantiq/setup.c
 create mode 100644 arch/mips/lantiq/xway/Kconfig
 create mode 100644 arch/mips/lantiq/xway/Makefile
 create mode 100644 arch/mips/lantiq/xway/clk-ase.c
 create mode 100644 arch/mips/lantiq/xway/clk-xway.c
 create mode 100644 arch/mips/lantiq/xway/devices.c
 create mode 100644 arch/mips/lantiq/xway/devices.h
 create mode 100644 arch/mips/lantiq/xway/gpio.c
 create mode 100644 arch/mips/lantiq/xway/mach-easy50601.c
 create mode 100644 arch/mips/lantiq/xway/mach-easy50712.c
 create mode 100644 arch/mips/lantiq/xway/pmu.c
 create mode 100644 arch/mips/lantiq/xway/prom-ase.c
 create mode 100644 arch/mips/lantiq/xway/prom-xway.c
 create mode 100644 arch/mips/lantiq/xway/reset.c
 create mode 100644 arch/mips/pci/ops-lantiq.c
 create mode 100644 arch/mips/pci/pci-lantiq.c
 create mode 100644 arch/mips/pci/pci-lantiq.h
 create mode 100644 drivers/mtd/maps/lantiq.c
 create mode 100644 drivers/serial/lantiq.c
 create mode 100644 drivers/watchdog/lantiq_wdt.c

-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:55:52 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:56:01 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35659 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490978Ab1AETza (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:30 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        linux-mips@linux-mips.org
Subject: [PATCH 01/10] MIPS: lantiq: add initial support for Lantiq SoCs
Date:   Wed,  5 Jan 2011 20:56:10 +0100
Message-Id: <1294257379-417-2-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28845
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

Add initial support for Mips based SoCs made by Lantiq. This series will add
support for the XWAY family.

The series allows booting a minimal system using a initramfs or NOR. Missing
drivers and support for Amazon and GPON family will be provided in a later
series.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: linux-mips@linux-mips.org
---
 arch/mips/Kbuild.platforms                 |    1 +
 arch/mips/Kconfig                          |   16 ++
 arch/mips/include/asm/mach-lantiq/lantiq.h |   48 +++++++
 arch/mips/include/asm/mach-lantiq/war.h    |   24 +++
 arch/mips/lantiq/Makefile                  |    9 ++
 arch/mips/lantiq/Platform                  |    7 +
 arch/mips/lantiq/clk.c                     |  129 +++++++++++++++++
 arch/mips/lantiq/clk.h                     |   18 +++
 arch/mips/lantiq/early_printk.c            |   47 ++++++
 arch/mips/lantiq/irq.c                     |  209 ++++++++++++++++++++++++++++
 arch/mips/lantiq/prom.c                    |   84 +++++++++++
 arch/mips/lantiq/prom.h                    |   26 ++++
 arch/mips/lantiq/setup.c                   |   45 ++++++
 13 files changed, 663 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq.h
 create mode 100644 arch/mips/include/asm/mach-lantiq/war.h
 create mode 100644 arch/mips/lantiq/Makefile
 create mode 100644 arch/mips/lantiq/Platform
 create mode 100644 arch/mips/lantiq/clk.c
 create mode 100644 arch/mips/lantiq/clk.h
 create mode 100644 arch/mips/lantiq/early_printk.c
 create mode 100644 arch/mips/lantiq/irq.c
 create mode 100644 arch/mips/lantiq/prom.c
 create mode 100644 arch/mips/lantiq/prom.h
 create mode 100644 arch/mips/lantiq/setup.c

diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 78439b8..8b7c26f 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -10,6 +10,7 @@ platforms += dec
 platforms += emma
 platforms += jazz
 platforms += jz4740
+platforms += lantiq
 platforms += lasat
 platforms += loongson
 platforms += mipssim
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 913d50d..a2396f1 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -192,6 +192,22 @@ config MACH_JZ4740
 	select SYS_HAS_EARLY_PRINTK
 	select HAVE_PWM
 
+config LANTIQ
+	bool "Lantiq based platforms"
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select CEVT_R4K
+	select CSRC_R4K
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_MULTITHREADING
+	select SYS_HAS_EARLY_PRINTK
+	select ARCH_REQUIRE_GPIOLIB
+	select SWAP_IO_SPACE
+	select BOOT_RAW
+
 config LASAT
 	bool "LASAT Networks platforms"
 	select CEVT_R4K
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
new file mode 100644
index 0000000..54eb033
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -0,0 +1,48 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_H__
+#define _LANTIQ_H__
+
+/* generic reg access functions */
+#define ltq_r32(reg)						__raw_readl(reg)
+#define ltq_w32(val, reg)				__raw_writel(val, reg)
+#define ltq_w32_mask(clear, set, reg)	\
+	ltq_w32((ltq_r32(reg) & ~clear) | set, reg)
+
+extern unsigned int ltq_get_cpu_ver(void);
+extern unsigned int ltq_get_soc_type(void);
+
+/* clock speeds */
+#define CLOCK_60M			60000000
+#define CLOCK_83M			83333333
+#define CLOCK_111M			111111111
+#define CLOCK_133M			133333333
+#define CLOCK_167M			166666667
+#define CLOCK_200M			200000000
+#define CLOCK_266M			266666666
+#define CLOCK_333M			333333333
+#define CLOCK_400M			400000000
+
+/* spinlock all ebu i/o */
+extern spinlock_t ebu_lock;
+
+/* some irq helpers */
+extern void ltq_disable_irq(unsigned int irq_nr);
+extern void ltq_mask_and_ack_irq(unsigned int irq_nr);
+extern void ltq_enable_irq(unsigned int irq_nr);
+
+#define IOPORT_RESOURCE_START		0x10000000
+#define IOPORT_RESOURCE_END		0xffffffff
+#define IOMEM_RESOURCE_START		0x10000000
+#define IOMEM_RESOURCE_END		0xffffffff
+
+#define LTQ_FLASH_START		0x10000000
+#define LTQ_FLASH_MAX		0x04000000
+
+#endif
diff --git a/arch/mips/include/asm/mach-lantiq/war.h b/arch/mips/include/asm/mach-lantiq/war.h
new file mode 100644
index 0000000..01b08ef
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/war.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ *
+ */
+#ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H
+#define __ASM_MIPS_MACH_LANTIQ_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                 0
+#define MIPS34K_MISSED_ITLB_WAR         0
+
+#endif
diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
new file mode 100644
index 0000000..6a30de6
--- /dev/null
+++ b/arch/mips/lantiq/Makefile
@@ -0,0 +1,9 @@
+# Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+
+obj-y := irq.o setup.o clk.o prom.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform
new file mode 100644
index 0000000..eef587f
--- /dev/null
+++ b/arch/mips/lantiq/Platform
@@ -0,0 +1,7 @@
+#
+# Lantiq
+#
+
+platform-$(CONFIG_LANTIQ)	+= lantiq/
+cflags-$(CONFIG_LANTIQ)		+= -I$(srctree)/arch/mips/include/asm/mach-lantiq
+load-$(CONFIG_LANTIQ)		= 0xffffffff80002000
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
new file mode 100644
index 0000000..4283d92
--- /dev/null
+++ b/arch/mips/lantiq/clk.c
@@ -0,0 +1,129 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/list.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq.h>
+
+#include "clk.h"
+
+struct clk {
+	const char *name;
+	unsigned long rate;
+	unsigned long (*get_rate) (void);
+};
+
+static struct clk *cpu_clk;
+static int cpu_clk_cnt;
+
+static unsigned int r4k_offset;
+static unsigned int r4k_cur;
+
+static struct clk cpu_clk_generic[] = {
+	{
+		.name = "cpu",
+		.get_rate = ltq_get_cpu_hz,
+	}, {
+		.name = "fpi",
+		.get_rate = ltq_get_fpi_hz,
+	}, {
+		.name = "io",
+		.get_rate = ltq_get_io_region_clock,
+	},
+};
+
+void
+clk_init(void)
+{
+	int i;
+	cpu_clk = cpu_clk_generic;
+	cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
+	for (i = 0; i < cpu_clk_cnt; i++)
+		printk(KERN_INFO "%s: %ld\n",
+			cpu_clk[i].name, clk_get_rate(&cpu_clk[i]));
+}
+
+static inline int
+clk_good(struct clk *clk)
+{
+	return clk && !IS_ERR(clk);
+}
+
+unsigned long
+clk_get_rate(struct clk *clk)
+{
+	if (unlikely(!clk_good(clk)))
+		return 0;
+
+	if (clk->rate != 0)
+		return clk->rate;
+
+	if (clk->get_rate != NULL)
+		return clk->get_rate();
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk*
+clk_get(struct device *dev, const char *id)
+{
+	int i;
+	for (i = 0; i < cpu_clk_cnt; i++)
+		if (!strcmp(id, cpu_clk[i].name))
+			return &cpu_clk[i];
+	BUG();
+	return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+void
+clk_put(struct clk *clk)
+{
+	/* not used */
+}
+EXPORT_SYMBOL(clk_put);
+
+static inline u32
+ltq_get_counter_resolution(void)
+{
+	u32 res;
+	__asm__ __volatile__(
+		".set   push\n"
+		".set   mips32r2\n"
+		".set   noreorder\n"
+		"rdhwr  %0, $3\n"
+		"ehb\n"
+		".set pop\n"
+		: "=&r" (res)
+		: /* no input */
+		: "memory");
+	instruction_hazard();
+	return res;
+}
+
+void __init
+plat_time_init(void)
+{
+	struct clk *clk = clk_get(0, "cpu");
+	mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
+	r4k_cur = (read_c0_count() + r4k_offset);
+	write_c0_compare(r4k_cur);
+}
diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h
new file mode 100644
index 0000000..3328925
--- /dev/null
+++ b/arch/mips/lantiq/clk.h
@@ -0,0 +1,18 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_CLK_H__
+#define _LTQ_CLK_H__
+
+extern void clk_init(void);
+
+extern unsigned long ltq_get_cpu_hz(void);
+extern unsigned long ltq_get_fpi_hz(void);
+extern unsigned long ltq_get_io_region_clock(void);
+
+#endif
diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c
new file mode 100644
index 0000000..0aaf4f7
--- /dev/null
+++ b/arch/mips/lantiq/early_printk.c
@@ -0,0 +1,47 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/cpu.h>
+
+#include <lantiq.h>
+#include <lantiq_soc.h>
+
+#define LTQ_ASC_BASE			KSEG1ADDR(LTQ_ASC1_BASE)
+#define ASC_BUF				1024
+#define LTQ_ASC_FSTAT		((u32 *)(LTQ_ASC_BASE + 0x0048))
+#define LTQ_ASC_TBUF			((u32 *)(LTQ_ASC_BASE + 0x0020))
+#define TXMASK				0x3F00
+#define TXOFFSET			8
+
+void
+prom_putchar(char c)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
+	if (c == '\n')
+		ltq_w32('\r', LTQ_ASC_TBUF);
+	ltq_w32(c, LTQ_ASC_TBUF);
+	local_irq_restore(flags);
+}
+
+void
+early_printf(const char *fmt, ...)
+{
+	char buf[ASC_BUF];
+	va_list args;
+	int l;
+	char *p, *buf_end;
+	va_start(args, fmt);
+	l = vsnprintf(buf, ASC_BUF, fmt, args);
+	va_end(args);
+	buf_end = buf + l;
+	for (p = buf; p < buf_end; p++)
+		prom_putchar(*p);
+}
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
new file mode 100644
index 0000000..b1535ee
--- /dev/null
+++ b/arch/mips/lantiq/irq.c
@@ -0,0 +1,209 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq_cpu.h>
+
+#include <lantiq.h>
+#include <irq.h>
+
+#define LTQ_ICU_BASE_ADDR	(KSEG1 | 0x1F880200)
+
+#define LTQ_ICU_IM0_ISR		((u32 *)(LTQ_ICU_BASE_ADDR + 0x0000))
+#define LTQ_ICU_IM0_IER		((u32 *)(LTQ_ICU_BASE_ADDR + 0x0008))
+#define LTQ_ICU_IM0_IOSR		((u32 *)(LTQ_ICU_BASE_ADDR + 0x0010))
+#define LTQ_ICU_IM0_IRSR		((u32 *)(LTQ_ICU_BASE_ADDR + 0x0018))
+#define LTQ_ICU_IM0_IMR		((u32 *)(LTQ_ICU_BASE_ADDR + 0x0020))
+
+#define LTQ_ICU_IM1_ISR		((u32 *)(LTQ_ICU_BASE_ADDR + 0x0028))
+#define LTQ_ICU_IM2_ISR		((u32 *)(LTQ_ICU_BASE_ADDR + 0x0050))
+#define LTQ_ICU_IM3_ISR		((u32 *)(LTQ_ICU_BASE_ADDR + 0x0078))
+#define LTQ_ICU_IM4_ISR		((u32 *)(LTQ_ICU_BASE_ADDR + 0x00A0))
+
+#define LTQ_ICU_OFFSET		(LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
+
+void
+ltq_disable_irq(unsigned int irq_nr)
+{
+	u32 *ier = LTQ_ICU_IM0_IER;
+	irq_nr -= INT_NUM_IRQ0;
+	ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+	irq_nr %= INT_NUM_IM_OFFSET;
+	ltq_w32(ltq_r32(ier) & ~(1 << irq_nr), ier);
+}
+EXPORT_SYMBOL(ltq_disable_irq);
+
+void
+ltq_mask_and_ack_irq(unsigned int irq_nr)
+{
+	u32 *ier = LTQ_ICU_IM0_IER;
+	u32 *isr = LTQ_ICU_IM0_ISR;
+	irq_nr -= INT_NUM_IRQ0;
+	ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+	isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+	irq_nr %= INT_NUM_IM_OFFSET;
+	ltq_w32(ltq_r32(ier) & ~(1 << irq_nr), ier);
+	ltq_w32((1 << irq_nr), isr);
+}
+EXPORT_SYMBOL(ltq_mask_and_ack_irq);
+
+static void
+ltq_ack_irq(unsigned int irq_nr)
+{
+	u32 *isr = LTQ_ICU_IM0_ISR;
+	irq_nr -= INT_NUM_IRQ0;
+	isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+	irq_nr %= INT_NUM_IM_OFFSET;
+	ltq_w32((1 << irq_nr), isr);
+}
+
+void
+ltq_enable_irq(unsigned int irq_nr)
+{
+	u32 *ier = LTQ_ICU_IM0_IER;
+	irq_nr -= INT_NUM_IRQ0;
+	ier += LTQ_ICU_OFFSET  * (irq_nr / INT_NUM_IM_OFFSET);
+	irq_nr %= INT_NUM_IM_OFFSET;
+	ltq_w32(ltq_r32(ier) | (1 << irq_nr), ier);
+}
+EXPORT_SYMBOL(ltq_enable_irq);
+
+static unsigned int
+ltq_startup_irq(unsigned int irq)
+{
+	ltq_enable_irq(irq);
+	return 0;
+}
+
+static void
+ltq_end_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		ltq_enable_irq(irq);
+}
+
+static struct irq_chip
+ltq_irq_type = {
+	"ltq_irq",
+	.startup = ltq_startup_irq,
+	.enable = ltq_enable_irq,
+	.disable = ltq_disable_irq,
+	.unmask = ltq_enable_irq,
+	.ack = ltq_ack_irq,
+	.mask = ltq_disable_irq,
+	.mask_ack = ltq_mask_and_ack_irq,
+	.end = ltq_end_irq,
+};
+
+static void
+ltq_hw_irqdispatch(int module)
+{
+	u32 irq;
+
+	irq = ltq_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
+	if (irq == 0)
+		return;
+
+	/* silicon bug causes only the msb set to 1 to be valid. all
+	   other bits might be bogus */
+	irq = __fls(irq);
+	do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
+}
+
+#define DEFINE_HWx_IRQDISPATCH(x) \
+static void ltq_hw ## x ## _irqdispatch(void)\
+{\
+	ltq_hw_irqdispatch(x); \
+}
+DEFINE_HWx_IRQDISPATCH(0)
+DEFINE_HWx_IRQDISPATCH(1)
+DEFINE_HWx_IRQDISPATCH(2)
+DEFINE_HWx_IRQDISPATCH(3)
+DEFINE_HWx_IRQDISPATCH(4)
+
+static void ltq_hw5_irqdispatch(void)
+{
+	do_IRQ(MIPS_CPU_TIMER_IRQ);
+}
+
+asmlinkage void
+plat_irq_dispatch(void)
+{
+	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+	unsigned int i;
+
+	if (pending & CAUSEF_IP7) {
+		do_IRQ(MIPS_CPU_TIMER_IRQ);
+		goto out;
+	} else {
+		for (i = 0; i < 5; i++) {
+			if (pending & (CAUSEF_IP2 << i)) {
+				ltq_hw_irqdispatch(i);
+				goto out;
+			}
+		}
+	}
+	printk(KERN_ALERT "Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
+
+out:
+	return;
+}
+
+static struct irqaction
+cascade = {
+	.handler = no_action,
+	.flags = IRQF_DISABLED,
+	.name = "cascade",
+};
+
+void __init
+arch_init_irq(void)
+{
+	int i;
+
+	for (i = 0; i < 5; i++)
+		ltq_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
+
+	mips_cpu_irq_init();
+
+	for (i = 2; i <= 6; i++)
+		setup_irq(i, &cascade);
+
+	if (cpu_has_vint) {
+		printk(KERN_INFO "Setting up vectored interrupts\n");
+		set_vi_handler(2, ltq_hw0_irqdispatch);
+		set_vi_handler(3, ltq_hw1_irqdispatch);
+		set_vi_handler(4, ltq_hw2_irqdispatch);
+		set_vi_handler(5, ltq_hw3_irqdispatch);
+		set_vi_handler(6, ltq_hw4_irqdispatch);
+		set_vi_handler(7, ltq_hw5_irqdispatch);
+	}
+
+	for (i = INT_NUM_IRQ0;
+		i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
+		set_irq_chip_and_handler(i, &ltq_irq_type,
+			handle_level_irq);
+
+	#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
+	set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
+		IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+	#else
+	set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
+		IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+	#endif
+}
+
+unsigned int __cpuinit
+get_c0_compare_int(void)
+{
+	return CP0_LEGACY_COMPARE_IRQ;
+}
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
new file mode 100644
index 0000000..6561e4e
--- /dev/null
+++ b/arch/mips/lantiq/prom.c
@@ -0,0 +1,84 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq.h>
+
+#include "prom.h"
+#include "clk.h"
+
+static struct ltq_soc_info soc_info;
+
+/* for Multithreading (APRP) on MIPS34K */
+unsigned long physical_memsize;
+
+/* all access to the ebu must be locked */
+DEFINE_SPINLOCK(ebu_lock);
+EXPORT_SYMBOL_GPL(ebu_lock);
+
+unsigned int
+ltq_get_cpu_ver(void)
+{
+	return soc_info.rev;
+}
+EXPORT_SYMBOL(ltq_get_cpu_ver);
+
+unsigned int
+ltq_get_soc_type(void)
+{
+	return soc_info.type;
+}
+EXPORT_SYMBOL(ltq_get_soc_type);
+
+const char*
+get_system_type(void)
+{
+	return soc_info.sys_type;
+}
+
+void
+prom_free_prom_memory(void)
+{
+}
+
+static void __init
+prom_init_cmdline(void)
+{
+	int argc = fw_arg0;
+	char **argv = (char **) KSEG1ADDR(fw_arg1);
+	int i;
+	arcs_cmdline[0] = '\0';
+	if (argc)
+		for (i = 1; i < argc; i++) {
+			strlcat(arcs_cmdline, (char *)KSEG1ADDR(argv[i]),
+				COMMAND_LINE_SIZE);
+			if (i + 1 != argc)
+				strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
+		}
+	if (!*arcs_cmdline)
+		strcpy(&(arcs_cmdline[0]),
+			"console=ttyS1,115200 rootfstype=squashfs,jffs2");
+}
+
+void __init
+prom_init(void)
+{
+	struct clk *clk;
+	ltq_soc_detect(&soc_info);
+	clk_init();
+	clk = clk_get(0, "cpu");
+	snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d %ldMhz",
+		soc_info.name, soc_info.rev, clk_get_rate(clk) / 1000000);
+	soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
+	printk(KERN_INFO "SoC: %s\n", soc_info.sys_type);
+	prom_init_cmdline();
+}
diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h
new file mode 100644
index 0000000..3b92197
--- /dev/null
+++ b/arch/mips/lantiq/prom.h
@@ -0,0 +1,26 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_PROM_H__
+#define _LTQ_PROM_H__
+
+#define LTQ_SYS_TYPE_LEN	0x100
+
+struct ltq_soc_info {
+	unsigned char *name;
+	unsigned int rev;
+	unsigned int partnum;
+	unsigned int type;
+	unsigned char sys_type[LTQ_SYS_TYPE_LEN];
+};
+
+void ltq_soc_detect(struct ltq_soc_info *i);
+
+void early_printf(const char *fmt, ...);
+
+#endif
diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c
new file mode 100644
index 0000000..f0f74d2
--- /dev/null
+++ b/arch/mips/lantiq/setup.c
@@ -0,0 +1,45 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <asm/bootinfo.h>
+
+#include <lantiq.h>
+
+void __init
+plat_mem_setup(void)
+{
+	/* assume 16M as default */
+	unsigned long memsize = 16;
+	char **envp = (char **) KSEG1ADDR(fw_arg2);
+	u32 status;
+
+	/* make sure to have no "reverse endian" for user mode */
+	status = read_c0_status();
+	status &= (~(1<<25));
+	write_c0_status(status);
+
+	ioport_resource.start = IOPORT_RESOURCE_START;
+	ioport_resource.end = IOPORT_RESOURCE_END;
+	iomem_resource.start = IOMEM_RESOURCE_START;
+	iomem_resource.end = IOMEM_RESOURCE_END;
+
+	while (*envp) {
+		char *e = (char *)KSEG1ADDR(*envp);
+		if (!strncmp(e, "memsize=", 8)) {
+			e += 8;
+			strict_strtoul(e, 0, &memsize);
+		}
+		envp++;
+	}
+	memsize *= 1024 * 1024;
+	add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
+}
-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:56:20 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:56:29 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35665 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490979Ab1AETzd (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:33 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        linux-mips@linux-mips.org
Subject: [PATCH 02/10] MIPS: lantiq: add SoC specific code for XWAY family
Date:   Wed,  5 Jan 2011 20:56:11 +0100
Message-Id: <1294257379-417-3-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28846
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

Add support for the Lantiq XWAY family of Mips24KEc SoCs.

* Danube (PSB50702)
* Twinpass (PSB4000)
* AR9 (PSB50802)
* Amazon SE (PSB5061)

The Amazon SE is a lightweight SoC and has no PCI as well as a different
clock. We split the code out into seperate files to handle this.

The GPIO pins on the SoCs are multi function and there are several bits
we can use to configure the pins. To be as compatible as possible to
GPIOLIB we add a function

int lq_gpio_request(unsigned int pin, unsigned int alt0,
	unsigned int alt1, unsigned int dir, const char *name);

which lets you configure the 2 "alternate function" bits. This way drivers like
PCI can make use of GPIOLIB without a cubersome wrapper.

The pll code inside arch/mips/lantiq/xway/clk-xway.c is voodoo to me. It was
taken from a 2.4.20 source tree and was never really changed by me since then.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: linux-mips@linux-mips.org
---
 arch/mips/Kconfig                                  |    1 +
 arch/mips/include/asm/mach-lantiq/xway/irq.h       |   18 ++
 .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h |   62 ++++++
 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |  119 +++++++++++
 arch/mips/lantiq/Kconfig                           |   21 ++
 arch/mips/lantiq/Makefile                          |    2 +
 arch/mips/lantiq/Platform                          |    1 +
 arch/mips/lantiq/xway/Makefile                     |    4 +
 arch/mips/lantiq/xway/clk-ase.c                    |   53 +++++
 arch/mips/lantiq/xway/clk-xway.c                   |  221 ++++++++++++++++++++
 arch/mips/lantiq/xway/gpio.c                       |  205 ++++++++++++++++++
 arch/mips/lantiq/xway/pmu.c                        |   36 ++++
 arch/mips/lantiq/xway/prom-ase.c                   |   41 ++++
 arch/mips/lantiq/xway/prom-xway.c                  |   56 +++++
 arch/mips/lantiq/xway/reset.c                      |   53 +++++
 15 files changed, 893 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-lantiq/xway/irq.h
 create mode 100644 arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
 create mode 100644 arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
 create mode 100644 arch/mips/lantiq/Kconfig
 create mode 100644 arch/mips/lantiq/xway/Makefile
 create mode 100644 arch/mips/lantiq/xway/clk-ase.c
 create mode 100644 arch/mips/lantiq/xway/clk-xway.c
 create mode 100644 arch/mips/lantiq/xway/gpio.c
 create mode 100644 arch/mips/lantiq/xway/pmu.c
 create mode 100644 arch/mips/lantiq/xway/prom-ase.c
 create mode 100644 arch/mips/lantiq/xway/prom-xway.c
 create mode 100644 arch/mips/lantiq/xway/reset.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a2396f1..9d3fd89 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -736,6 +736,7 @@ source "arch/mips/alchemy/Kconfig"
 source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"
+source "arch/mips/lantiq/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/pmc-sierra/Kconfig"
 source "arch/mips/powertv/Kconfig"
diff --git a/arch/mips/include/asm/mach-lantiq/xway/irq.h b/arch/mips/include/asm/mach-lantiq/xway/irq.h
new file mode 100644
index 0000000..a1471d2
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/xway/irq.h
@@ -0,0 +1,18 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef __LANTIQ_IRQ_H
+#define __LANTIQ_IRQ_H
+
+#include <lantiq_irq.h>
+
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
new file mode 100644
index 0000000..2d29e77
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -0,0 +1,62 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_XWAY_IRQ_H__
+#define _LANTIQ_XWAY_IRQ_H__
+
+#define INT_NUM_IRQ0			8
+#define INT_NUM_IM0_IRL0		(INT_NUM_IRQ0 + 0)
+#define INT_NUM_IM1_IRL0		(INT_NUM_IRQ0 + 32)
+#define INT_NUM_IM2_IRL0		(INT_NUM_IRQ0 + 64)
+#define INT_NUM_IM3_IRL0		(INT_NUM_IRQ0 + 96)
+#define INT_NUM_IM4_IRL0		(INT_NUM_IRQ0 + 128)
+#define INT_NUM_IM_OFFSET		(INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
+
+#define LTQ_ASC_TIR(x)			(INT_NUM_IM3_IRL0 + (x * 8))
+#define LTQ_ASC_RIR(x)			(INT_NUM_IM3_IRL0 + (x * 8) + 1)
+#define LTQ_ASC_EIR(x)			(INT_NUM_IM3_IRL0 + (x * 8) + 2)
+
+#define LTQ_SSC_TIR				(INT_NUM_IM0_IRL0 + 15)
+#define LTQ_SSC_RIR				(INT_NUM_IM0_IRL0 + 14)
+#define LTQ_SSC_EIR				(INT_NUM_IM0_IRL0 + 16)
+
+#define LTQ_MEI_DYING_GASP_INT	(INT_NUM_IM1_IRL0 + 21)
+#define LTQ_MEI_INT				(INT_NUM_IM1_IRL0 + 23)
+
+#define LTQ_TIMER6_INT			(INT_NUM_IM1_IRL0 + 23)
+#define LTQ_USB_INT				(INT_NUM_IM1_IRL0 + 22)
+#define LTQ_USB_OC_INT			(INT_NUM_IM4_IRL0 + 23)
+
+#define MIPS_CPU_TIMER_IRQ		7
+
+#define LTQ_DMA_CH0_INT			(INT_NUM_IM2_IRL0)
+#define LTQ_DMA_CH1_INT			(INT_NUM_IM2_IRL0 + 1)
+#define LTQ_DMA_CH2_INT			(INT_NUM_IM2_IRL0 + 2)
+#define LTQ_DMA_CH3_INT			(INT_NUM_IM2_IRL0 + 3)
+#define LTQ_DMA_CH4_INT			(INT_NUM_IM2_IRL0 + 4)
+#define LTQ_DMA_CH5_INT			(INT_NUM_IM2_IRL0 + 5)
+#define LTQ_DMA_CH6_INT			(INT_NUM_IM2_IRL0 + 6)
+#define LTQ_DMA_CH7_INT			(INT_NUM_IM2_IRL0 + 7)
+#define LTQ_DMA_CH8_INT			(INT_NUM_IM2_IRL0 + 8)
+#define LTQ_DMA_CH9_INT			(INT_NUM_IM2_IRL0 + 9)
+#define LTQ_DMA_CH10_INT			(INT_NUM_IM2_IRL0 + 10)
+#define LTQ_DMA_CH11_INT			(INT_NUM_IM2_IRL0 + 11)
+#define LTQ_DMA_CH12_INT			(INT_NUM_IM2_IRL0 + 25)
+#define LTQ_DMA_CH13_INT			(INT_NUM_IM2_IRL0 + 26)
+#define LTQ_DMA_CH14_INT			(INT_NUM_IM2_IRL0 + 27)
+#define LTQ_DMA_CH15_INT			(INT_NUM_IM2_IRL0 + 28)
+#define LTQ_DMA_CH16_INT			(INT_NUM_IM2_IRL0 + 29)
+#define LTQ_DMA_CH17_INT			(INT_NUM_IM2_IRL0 + 30)
+#define LTQ_DMA_CH18_INT			(INT_NUM_IM2_IRL0 + 16)
+#define LTQ_DMA_CH19_INT			(INT_NUM_IM2_IRL0 + 21)
+
+#define LTQ_PPE_MBOX_INT			(INT_NUM_IM2_IRL0 + 24)
+
+#define INT_NUM_IM4_IRL14		(INT_NUM_IM4_IRL0 + 14)
+
+#endif
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
new file mode 100644
index 0000000..74beeb7
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -0,0 +1,119 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifdef CONFIG_SOC_TYPE_XWAY
+
+#ifndef _LTQ_XWAY_H__
+#define _LTQ_XWAY_H__
+
+#include <lantiq.h>
+
+/* request a non-gpio and set the PIO config */
+extern int  ltq_gpio_request(unsigned int pin, unsigned int alt0,
+	unsigned int alt1, unsigned int dir, const char *name);
+extern int ltq_gpio_setconfig(unsigned int pin,
+	unsigned int reg, unsigned int val);
+
+extern void ltq_pmu_enable(unsigned int module);
+extern void ltq_pmu_disable(unsigned int module);
+
+/*------------ Chip IDs */
+#define SOC_ID_DANUBE1		0x129
+#define SOC_ID_DANUBE2		0x12B
+#define SOC_ID_TWINPASS		0x12D
+#define SOC_ID_AMAZON_SE	0x152
+#define SOC_ID_ARX188		0x16C
+#define SOC_ID_ARX168		0x16D
+#define SOC_ID_ARX182		0x16F
+
+/*------------ SoC Types */
+#define SOC_TYPE_DANUBE		0x01
+#define SOC_TYPE_TWINPASS	0x02
+#define SOC_TYPE_AR9		0x03
+#define SOC_TYPE_AMAZON_SE	0x04
+
+/*------------ ASC0/1 */
+#define LTQ_ASC0_BASE		0x1E100400
+#define LTQ_ASC1_BASE		0x1E100C00
+#define LTQ_ASC_SIZE			0x400
+
+/*------------ RCU */
+#define LTQ_RCU_BASE_ADDR	0xBF203000
+
+/*------------ GPTU */
+#define LTQ_GPTU_BASE_ADDR	0xB8000300
+
+/*------------ EBU */
+#define LTQ_EBU_GPIO_START	0x14000000
+#define LTQ_EBU_GPIO_SIZE	0x1000
+
+#define LTQ_EBU_BASE_ADDR	0xBE105300
+
+#define LTQ_EBU_BUSCON0		((u32 *)(LTQ_EBU_BASE_ADDR + 0x0060))
+#define LTQ_EBU_PCC_CON		((u32 *)(LTQ_EBU_BASE_ADDR + 0x0090))
+#define LTQ_EBU_PCC_IEN		((u32 *)(LTQ_EBU_BASE_ADDR + 0x00A4))
+#define LTQ_EBU_PCC_ISTAT	((u32 *)(LTQ_EBU_BASE_ADDR + 0x00A0))
+#define LTQ_EBU_BUSCON1		((u32 *)(LTQ_EBU_BASE_ADDR + 0x0064))
+#define LTQ_EBU_ADDRSEL1		((u32 *)(LTQ_EBU_BASE_ADDR + 0x0024))
+
+#define EBU_WRDIS			0x80000000
+
+/*------------ CGU */
+#define LTQ_CGU_BASE_ADDR	(KSEG1 + 0x1F103000)
+
+/*------------ PMU */
+#define LTQ_PMU_BASE_ADDR	(KSEG1 + 0x1F102000)
+
+#define PMU_DMA				0x0020
+#define PMU_USB				0x8041
+#define PMU_LED				0x0800
+#define PMU_GPT				0x1000
+#define PMU_PPE				0x2000
+#define PMU_FPI				0x4000
+#define PMU_SWITCH			0x10000000
+
+/*------------ ETOP */
+#define LTQ_PPE32_BASE_ADDR	0xBE180000
+#define LTQ_PPE32_SIZE		0x40000
+
+/*------------ DMA */
+#define LTQ_DMA_BASE_ADDR	0xBE104100
+
+/*------------ PCI */
+#define PCI_CR_BASE_ADDR	(KSEG1 + 0x1E105400)
+#define PCI_CS_BASE_ADDR	(KSEG1 + 0x17000000)
+
+/*------------ WDT */
+#define LTQ_WDT_BASE			0x1F880000
+#define LTQ_WDT_SIZE			0x400
+
+/*------------ Serial To Parallel conversion  */
+#define LTQ_STP_BASE			0x1E100BB0
+#define LTQ_STP_SIZE			0x40
+
+/*------------ GPIO */
+#define LTQ_GPIO0_BASE_ADDR	0x1E100B10
+#define LTQ_GPIO1_BASE_ADDR	0x1E100B40
+#define LTQ_GPIO_SIZE		0x30
+
+/*------------ SSC */
+#define LTQ_SSC_BASE_ADDR	(KSEG1 + 0x1e100800)
+
+/*------------ MEI */
+#define LTQ_MEI_BASE_ADDR	(KSEG1 + 0x1E116000)
+
+/*------------ DEU */
+#define LTQ_DEU_BASE			(KSEG1 + 0x1E103100)
+
+/*------------ MPS */
+#define LTQ_MPS_BASE_ADDR	(KSEG1 + 0x1F107000)
+#define LTQ_MPS_CHIPID		((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
+
+#endif
+
+#endif
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
new file mode 100644
index 0000000..2780461
--- /dev/null
+++ b/arch/mips/lantiq/Kconfig
@@ -0,0 +1,21 @@
+if LANTIQ
+
+config SOC_TYPE_XWAY
+	bool
+	default n
+
+choice
+	prompt "SoC Type"
+	default SOC_XWAY
+
+config SOC_AMAZON_SE
+	bool "Amazon SE"
+	select SOC_TYPE_XWAY
+
+config SOC_XWAY
+	bool "XWAY"
+	select SOC_TYPE_XWAY
+	select HW_HAS_PCI
+endchoice
+
+endif
diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
index 6a30de6..a268391 100644
--- a/arch/mips/lantiq/Makefile
+++ b/arch/mips/lantiq/Makefile
@@ -7,3 +7,5 @@
 obj-y := irq.o setup.o clk.o prom.o
 
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform
index eef587f..f3dff05 100644
--- a/arch/mips/lantiq/Platform
+++ b/arch/mips/lantiq/Platform
@@ -5,3 +5,4 @@
 platform-$(CONFIG_LANTIQ)	+= lantiq/
 cflags-$(CONFIG_LANTIQ)		+= -I$(srctree)/arch/mips/include/asm/mach-lantiq
 load-$(CONFIG_LANTIQ)		= 0xffffffff80002000
+cflags-$(CONFIG_SOC_TYPE_XWAY)	+= -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
new file mode 100644
index 0000000..64730d5
--- /dev/null
+++ b/arch/mips/lantiq/xway/Makefile
@@ -0,0 +1,4 @@
+obj-y := pmu.o reset.o gpio.o
+
+obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
+obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
diff --git a/arch/mips/lantiq/xway/clk-ase.c b/arch/mips/lantiq/xway/clk-ase.c
new file mode 100644
index 0000000..ecc3b7c
--- /dev/null
+++ b/arch/mips/lantiq/xway/clk-ase.c
@@ -0,0 +1,53 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq_soc.h>
+
+#define LTQ_CGU_SYS			((u32 *)(LTQ_CGU_BASE_ADDR + 0x0010))
+
+unsigned int
+ltq_get_io_region_clock(void)
+{
+	return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_io_region_clock);
+
+unsigned int
+ltq_get_fpi_bus_clock(int fpi)
+{
+	return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
+
+unsigned int
+ltq_get_cpu_hz(void)
+{
+	if (ltq_r32(LTQ_CGU_SYS) & (1 << 5))
+		return CLOCK_266M;
+	else
+		return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_cpu_hz);
+
+unsigned int
+ltq_get_fpi_hz(void)
+{
+	return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_fpi_hz);
+
+
diff --git a/arch/mips/lantiq/xway/clk-xway.c b/arch/mips/lantiq/xway/clk-xway.c
new file mode 100644
index 0000000..8e7e3d6
--- /dev/null
+++ b/arch/mips/lantiq/xway/clk-xway.c
@@ -0,0 +1,221 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq_soc.h>
+
+static unsigned int ltq_ram_clocks[] = {
+	CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
+#define DDR_HZ ltq_ram_clocks[ltq_r32(LTQ_CGU_SYS) & 0x3]
+
+#define BASIC_FREQUENCY_1	35328000
+#define BASIC_FREQUENCY_2	36000000
+#define BASIS_REQUENCY_USB	12000000
+
+#define GET_BITS(x, msb, lsb)           \
+			(((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
+
+#define CGU_PLL0_PHASE_DIVIDER_ENABLE   (ltq_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
+#define CGU_PLL0_BYPASS                 (ltq_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
+#define CGU_PLL0_CFG_DSMSEL             (ltq_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
+#define CGU_PLL0_CFG_FRAC_EN            (ltq_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
+#define CGU_PLL1_SRC                    (ltq_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
+#define CGU_PLL2_PHASE_DIVIDER_ENABLE   (ltq_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
+#define CGU_SYS_FPI_SEL                 (1 << 6)
+#define CGU_SYS_DDR_SEL                 0x3
+#define CGU_PLL0_SRC                    (1 << 29)
+
+#define CGU_PLL0_CFG_PLLK               GET_BITS(*LTQ_CGU_PLL0_CFG, 26, 17)
+#define CGU_PLL0_CFG_PLLN               GET_BITS(*LTQ_CGU_PLL0_CFG, 12, 6)
+#define CGU_PLL0_CFG_PLLM               GET_BITS(*LTQ_CGU_PLL0_CFG, 5, 2)
+#define CGU_PLL2_SRC                    GET_BITS(*LTQ_CGU_PLL2_CFG, 18, 17)
+#define CGU_PLL2_CFG_INPUT_DIV          GET_BITS(*LTQ_CGU_PLL2_CFG, 16, 13)
+
+#define LTQ_GPTU_GPT_CLC		((u32 *)(LTQ_GPTU_BASE_ADDR + 0x0000))
+#define LTQ_CGU_PLL0_CFG		((u32 *)(LTQ_CGU_BASE_ADDR + 0x0004))
+#define LTQ_CGU_PLL1_CFG		((u32 *)(LTQ_CGU_BASE_ADDR + 0x0008))
+#define LTQ_CGU_PLL2_CFG		((u32 *)(LTQ_CGU_BASE_ADDR + 0x000C))
+#define LTQ_CGU_SYS			((u32 *)(LTQ_CGU_BASE_ADDR + 0x0010))
+#define LTQ_CGU_UPDATE		((u32 *)(LTQ_CGU_BASE_ADDR + 0x0014))
+#define LTQ_CGU_IF_CLK		((u32 *)(LTQ_CGU_BASE_ADDR + 0x0018))
+#define LTQ_CGU_OSC_CON		((u32 *)(LTQ_CGU_BASE_ADDR + 0x001C))
+#define LTQ_CGU_SMD			((u32 *)(LTQ_CGU_BASE_ADDR + 0x0020))
+#define LTQ_CGU_CT1SR		((u32 *)(LTQ_CGU_BASE_ADDR + 0x0028))
+#define LTQ_CGU_CT2SR		((u32 *)(LTQ_CGU_BASE_ADDR + 0x002C))
+#define LTQ_CGU_PCMCR		((u32 *)(LTQ_CGU_BASE_ADDR + 0x0030))
+#define LTQ_CGU_PCI_CR		((u32 *)(LTQ_CGU_BASE_ADDR + 0x0034))
+#define LTQ_CGU_PD_PC		((u32 *)(LTQ_CGU_BASE_ADDR + 0x0038))
+#define LTQ_CGU_FMR			((u32 *)(LTQ_CGU_BASE_ADDR + 0x003C))
+
+static unsigned int ltq_get_pll0_fdiv(void);
+
+static inline unsigned int
+get_input_clock(int pll)
+{
+	switch (pll) {
+	case 0:
+		if (ltq_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
+			return BASIS_REQUENCY_USB;
+		else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
+			return BASIC_FREQUENCY_1;
+		else
+			return BASIC_FREQUENCY_2;
+	case 1:
+		if (CGU_PLL1_SRC)
+			return BASIS_REQUENCY_USB;
+		else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
+			return BASIC_FREQUENCY_1;
+		else
+			return BASIC_FREQUENCY_2;
+	case 2:
+		switch (CGU_PLL2_SRC) {
+		case 0:
+			return ltq_get_pll0_fdiv();
+		case 1:
+			return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
+				BASIC_FREQUENCY_1 :
+				BASIC_FREQUENCY_2;
+		case 2:
+			return BASIS_REQUENCY_USB;
+		}
+	default:
+		return 0;
+	}
+}
+
+static inline unsigned int
+cal_dsm(int pll, unsigned int num, unsigned int den)
+{
+	u64 res, clock = get_input_clock(pll);
+	res = num * clock;
+	do_div(res, den);
+	return res;
+}
+
+static inline unsigned int
+mash_dsm(int pll, unsigned int M, unsigned int N, unsigned int K)
+{
+	unsigned int num = ((N + 1) << 10) + K;
+	unsigned int den = (M + 1) << 10;
+	return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int
+ssff_dsm_1(int pll, unsigned int M, unsigned int N,	unsigned int K)
+{
+	unsigned int num = ((N + 1) << 11) + K + 512;
+	unsigned int den = (M + 1) << 11;
+	return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int
+ssff_dsm_2(int pll, unsigned int M, unsigned int N, unsigned int K)
+{
+	unsigned int num = K >= 512 ?
+		((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
+	unsigned int den = (M + 1) << 12;
+	return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int
+dsm(int pll, unsigned int M, unsigned int N, unsigned int K,
+	unsigned int dsmsel, unsigned int phase_div_en)
+{
+	if (!dsmsel)
+		return mash_dsm(pll, M, N, K);
+	else if (!phase_div_en)
+		return mash_dsm(pll, M, N, K);
+	else
+		return ssff_dsm_2(pll, M, N, K);
+}
+
+static inline unsigned int
+ltq_get_pll0_fosc(void)
+{
+	if (CGU_PLL0_BYPASS)
+		return get_input_clock(0);
+	else
+		return !CGU_PLL0_CFG_FRAC_EN
+			? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
+				CGU_PLL0_CFG_DSMSEL,
+				CGU_PLL0_PHASE_DIVIDER_ENABLE)
+			: dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
+				CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
+				CGU_PLL0_PHASE_DIVIDER_ENABLE);
+}
+
+static unsigned int
+ltq_get_pll0_fdiv(void)
+{
+	unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
+	return (ltq_get_pll0_fosc() + (div >> 1)) / div;
+}
+
+unsigned int
+ltq_get_io_region_clock(void)
+{
+	unsigned int ret = ltq_get_pll0_fosc();
+	switch (ltq_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
+	default:
+	case 0:
+		return (ret + 1) / 2;
+	case 1:
+		return (ret * 2 + 2) / 5;
+	case 2:
+		return (ret + 1) / 3;
+	case 3:
+		return (ret + 2) / 4;
+	}
+}
+EXPORT_SYMBOL(ltq_get_io_region_clock);
+
+unsigned int
+ltq_get_fpi_bus_clock(int fpi)
+{
+	unsigned int ret = ltq_get_io_region_clock();
+	if ((fpi == 2) && (ltq_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
+		ret >>= 1;
+	return ret;
+}
+EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
+
+unsigned int
+ltq_get_cpu_hz(void)
+{
+	switch (ltq_r32(LTQ_CGU_SYS) & 0xc) {
+	case 0:
+		return CLOCK_333M;
+	case 4:
+		return DDR_HZ;
+	case 8:
+		return DDR_HZ << 1;
+	default:
+		return DDR_HZ >> 1;
+	}
+}
+EXPORT_SYMBOL(ltq_get_cpu_hz);
+
+unsigned int
+ltq_get_fpi_hz(void)
+{
+	unsigned int ddr_clock = DDR_HZ;
+	if (ltq_r32(LTQ_CGU_SYS) & 0x40)
+		return ddr_clock >> 1;
+	return ddr_clock;
+}
+EXPORT_SYMBOL(ltq_get_fpi_hz);
+
+
diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
new file mode 100644
index 0000000..2faa23a
--- /dev/null
+++ b/arch/mips/lantiq/xway/gpio.c
@@ -0,0 +1,205 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <lantiq.h>
+
+#define LQ_GPIO0_BASE_ADDR	0x1E100B10
+#define LQ_GPIO1_BASE_ADDR	0x1E100B40
+#define LQ_GPIO_SIZE		0x30
+
+#define LQ_GPIO_OUT			0x00
+#define LQ_GPIO_IN			0x04
+#define LQ_GPIO_DIR			0x08
+#define LQ_GPIO_ALTSEL0		0x0C
+#define LQ_GPIO_ALTSEL1		0x10
+#define LQ_GPIO_OD			0x14
+
+#define PINS_PER_PORT		16
+
+#define ltq_gpio_getbit(m, r, p)		(!!(ltq_r32(m + r) & (1 << p)))
+#define ltq_gpio_setbit(m, r, p)		ltq_w32_mask(0, (1 << p), m + r)
+#define ltq_gpio_clearbit(m, r, p)	ltq_w32_mask((1 << p), 0, m + r)
+
+struct ltq_gpio {
+	void __iomem *membase;
+	struct gpio_chip chip;
+};
+
+int
+gpio_to_irq(unsigned int gpio)
+{
+	return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int
+irq_to_gpio(unsigned int gpio)
+{
+	return -EINVAL;
+}
+EXPORT_SYMBOL(irq_to_gpio);
+
+int
+ltq_gpio_setconfig(unsigned int pin, unsigned int reg, unsigned int val)
+{
+	void __iomem *membase = (void *)KSEG1ADDR(LQ_GPIO0_BASE_ADDR);
+	if (pin >= (2 * PINS_PER_PORT))
+		return -EINVAL;
+	if (pin >= PINS_PER_PORT) {
+		pin -= PINS_PER_PORT;
+		membase += LQ_GPIO_SIZE;
+	}
+	if (val)
+		ltq_w32_mask(0, (1 << pin), membase + reg);
+	else
+		ltq_w32_mask((1 << pin), 0, membase + reg);
+	return 0;
+}
+EXPORT_SYMBOL(ltq_gpio_setconfig);
+
+int
+ltq_gpio_request(unsigned int pin, unsigned int alt0,
+	unsigned int alt1, unsigned int dir, const char *name)
+{
+	void __iomem *membase = (void *)KSEG1ADDR(LQ_GPIO0_BASE_ADDR);
+	if (pin >= (2 * PINS_PER_PORT))
+		return -EINVAL;
+	if (gpio_request(pin, name)) {
+		printk(KERN_ERR "failed to register %s gpio\n", name);
+		return -EBUSY;
+	}
+	gpio_direction_output(pin, dir);
+	if (pin >= PINS_PER_PORT) {
+		pin -= PINS_PER_PORT;
+		membase += LQ_GPIO_SIZE;
+	}
+	if (alt0)
+		ltq_gpio_setbit(membase, LQ_GPIO_ALTSEL0, pin);
+	else
+		ltq_gpio_clearbit(membase, LQ_GPIO_ALTSEL0, pin);
+	if (alt1)
+		ltq_gpio_setbit(membase, LQ_GPIO_ALTSEL1, pin);
+	else
+		ltq_gpio_clearbit(membase, LQ_GPIO_ALTSEL1, pin);
+	return 0;
+}
+EXPORT_SYMBOL(ltq_gpio_request);
+
+static void
+ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+	if (value)
+		ltq_gpio_setbit(ltq_gpio->membase, LQ_GPIO_OUT, offset);
+	else
+		ltq_gpio_clearbit(ltq_gpio->membase, LQ_GPIO_OUT, offset);
+}
+
+static int
+ltq_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+	return ltq_gpio_getbit(ltq_gpio->membase, LQ_GPIO_IN, offset);
+}
+
+static int
+ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+	ltq_gpio_clearbit(ltq_gpio->membase, LQ_GPIO_OD, offset);
+	ltq_gpio_clearbit(ltq_gpio->membase, LQ_GPIO_DIR, offset);
+	return 0;
+}
+
+static int
+ltq_gpio_direction_output(struct gpio_chip *chip,
+	unsigned int offset, int value)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+	ltq_gpio_setbit(ltq_gpio->membase, LQ_GPIO_OD, offset);
+	ltq_gpio_setbit(ltq_gpio->membase, LQ_GPIO_DIR, offset);
+	ltq_gpio_set(chip, offset, value);
+	return 0;
+}
+
+static int
+ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+	ltq_gpio_clearbit(ltq_gpio->membase, LQ_GPIO_ALTSEL0, offset);
+	ltq_gpio_clearbit(ltq_gpio->membase, LQ_GPIO_ALTSEL1, offset);
+	return 0;
+}
+
+static int
+ltq_gpio_probe(struct platform_device *pdev)
+{
+	struct ltq_gpio *ltq_gpio =
+		kzalloc(sizeof(struct ltq_gpio), GFP_KERNEL);
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	int ret = 0;
+	if (!res) {
+		ret = -ENOENT;
+		goto err_free;
+	}
+	res = request_mem_region(res->start, resource_size(res),
+		dev_name(&pdev->dev));
+	if (!res) {
+		ret = -EBUSY;
+		goto err_free;
+	}
+	ltq_gpio->membase = ioremap_nocache(res->start, resource_size(res));
+	if (!ltq_gpio->membase) {
+		ret = -ENOMEM;
+		goto err_release_mem_region;
+	}
+	ltq_gpio->chip.label = "ltq_gpio";
+	ltq_gpio->chip.direction_input = ltq_gpio_direction_input;
+	ltq_gpio->chip.direction_output = ltq_gpio_direction_output;
+	ltq_gpio->chip.get = ltq_gpio_get;
+	ltq_gpio->chip.set = ltq_gpio_set;
+	ltq_gpio->chip.request = ltq_gpio_req;
+	ltq_gpio->chip.base = PINS_PER_PORT * pdev->id;
+	ltq_gpio->chip.ngpio = PINS_PER_PORT;
+	platform_set_drvdata(pdev, ltq_gpio);
+	ret = gpiochip_add(&ltq_gpio->chip);
+	if (!ret)
+		return 0;
+
+	iounmap(ltq_gpio->membase);
+err_release_mem_region:
+	release_mem_region(res->start, resource_size(res));
+err_free:
+	kfree(ltq_gpio);
+	return ret;
+}
+
+static struct platform_driver
+ltq_gpio_driver = {
+	.probe = ltq_gpio_probe,
+	.driver = {
+		.name = "ltq_gpio",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init
+ltq_gpio_init(void)
+{
+	int ret = platform_driver_register(&ltq_gpio_driver);
+	if (ret)
+		printk(KERN_INFO "ltq_gpio : Error registering platfom driver!");
+	return ret;
+}
+
+arch_initcall(ltq_gpio_init);
diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c
new file mode 100644
index 0000000..78f4a4c
--- /dev/null
+++ b/arch/mips/lantiq/xway/pmu.c
@@ -0,0 +1,36 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <lantiq_soc.h>
+
+#define LTQ_PMU_PWDCR        ((u32 *)(LTQ_PMU_BASE_ADDR + 0x001C))
+#define LTQ_PMU_PWDSR        ((u32 *)(LTQ_PMU_BASE_ADDR + 0x0020))
+
+void
+ltq_pmu_enable(unsigned int module)
+{
+	int err = 1000000;
+
+	ltq_w32(ltq_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
+	do {} while (--err && (ltq_r32(LTQ_PMU_PWDSR) & module));
+
+	if (!err)
+		panic("activating PMU module failed!");
+}
+EXPORT_SYMBOL(ltq_pmu_enable);
+
+void
+ltq_pmu_disable(unsigned int module)
+{
+	ltq_w32(ltq_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
+}
+EXPORT_SYMBOL(ltq_pmu_disable);
diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c
new file mode 100644
index 0000000..55f5041
--- /dev/null
+++ b/arch/mips/lantiq/xway/prom-ase.c
@@ -0,0 +1,41 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+
+#define SOC_AMAZON_SE	"Amazon_SE"
+
+#define PART_SHIFT		12
+#define PART_MASK		0x0FFFFFFF
+#define REV_SHIFT		28
+#define REV_MASK		0xF0000000
+
+void __init
+ltq_soc_detect(struct ltq_soc_info *i)
+{
+	i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
+	i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
+	switch (i->partnum) {
+	case SOC_ID_AMAZON_SE:
+		i->name = SOC_AMAZON_SE;
+		i->type = SOC_TYPE_AMAZON_SE;
+		break;
+
+	default:
+		early_printf(KERN_ERR "unknown chiprev : 0x%08X\n", i->partnum);
+		unreachable();
+		break;
+	}
+}
diff --git a/arch/mips/lantiq/xway/prom-xway.c b/arch/mips/lantiq/xway/prom-xway.c
new file mode 100644
index 0000000..5c4e1a7
--- /dev/null
+++ b/arch/mips/lantiq/xway/prom-xway.c
@@ -0,0 +1,56 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+
+#define SOC_DANUBE		"Danube"
+#define SOC_TWINPASS	"Twinpass"
+#define SOC_AR9			"AR9"
+
+#define PART_SHIFT		12
+#define PART_MASK		0x0FFFFFFF
+#define REV_SHIFT		28
+#define REV_MASK		0xF0000000
+
+void __init
+ltq_soc_detect(struct ltq_soc_info *i)
+{
+	i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
+	i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
+	switch (i->partnum) {
+	case SOC_ID_DANUBE1:
+	case SOC_ID_DANUBE2:
+		i->name = SOC_DANUBE;
+		i->type = SOC_TYPE_DANUBE;
+		break;
+
+	case SOC_ID_TWINPASS:
+		i->name = SOC_TWINPASS;
+		i->type = SOC_TYPE_DANUBE;
+		break;
+
+	case SOC_ID_ARX188:
+	case SOC_ID_ARX168:
+	case SOC_ID_ARX182:
+		i->name = SOC_AR9;
+		i->type = SOC_TYPE_AR9;
+		break;
+
+	default:
+		early_printf("unknown chiprev : 0x%08X\n", i->partnum);
+		unreachable();
+		break;
+	}
+}
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
new file mode 100644
index 0000000..64ecd77
--- /dev/null
+++ b/arch/mips/lantiq/xway/reset.c
@@ -0,0 +1,53 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/pm.h>
+#include <asm/reboot.h>
+
+#include <lantiq_soc.h>
+
+#define LTQ_RCU_RST			((u32 *)(LTQ_RCU_BASE_ADDR + 0x0010))
+#define LTQ_RCU_RST_ALL		0x40000000
+
+static void
+ltq_machine_restart(char *command)
+{
+	printk(KERN_NOTICE "System restart\n");
+	local_irq_disable();
+	ltq_w32(ltq_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL,	LTQ_RCU_RST);
+	unreachable();
+}
+
+static void
+ltq_machine_halt(void)
+{
+	printk(KERN_NOTICE "System halted.\n");
+	local_irq_disable();
+	unreachable();
+}
+
+static void
+ltq_machine_power_off(void)
+{
+	printk(KERN_NOTICE "Please turn off the power now.\n");
+	local_irq_disable();
+	unreachable();
+}
+
+static int __init
+mips_reboot_setup(void)
+{
+	_machine_restart = ltq_machine_restart;
+	_machine_halt = ltq_machine_halt;
+	pm_power_off = ltq_machine_power_off;
+	return 0;
+}
+
+arch_initcall(mips_reboot_setup);
-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:56:48 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:56:52 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35669 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490983Ab1AETze (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:34 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        linux-mips@linux-mips.org
Subject: [PATCH 03/10] MIPS: lantiq: add PCI controller support.
Date:   Wed,  5 Jan 2011 20:56:12 +0100
Message-Id: <1294257379-417-4-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28847
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

The Lantiq family of SoCs have a EBU (External Bus Unit). This patch adds
the driver that allows us to use the EBU as a PCI controller. In order for
PCI to work the EBU is set to endianess swap all the data. In addition we
need to make use of SWAP_IO_SPACE for device->host DMA to work.

The clock of the PCI works in several modes (internal/external). If this
is not configured correctly the SoC will hang.

Currently only 1 pci irq pin is supported.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: linux-mips@linux-mips.org
---
 .../mips/include/asm/mach-lantiq/lantiq_platform.h |   25 ++
 arch/mips/pci/Makefile                             |    1 +
 arch/mips/pci/ops-lantiq.c                         |  118 ++++++++
 arch/mips/pci/pci-lantiq.c                         |  286 ++++++++++++++++++++
 arch/mips/pci/pci-lantiq.h                         |   18 ++
 5 files changed, 448 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_platform.h
 create mode 100644 arch/mips/pci/ops-lantiq.c
 create mode 100644 arch/mips/pci/pci-lantiq.c
 create mode 100644 arch/mips/pci/pci-lantiq.h

diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
new file mode 100644
index 0000000..c0d4c6c
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
@@ -0,0 +1,25 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_PLATFORM_H__
+#define _LANTIQ_PLATFORM_H__
+
+#include <linux/mtd/partitions.h>
+
+/* struct used to pass info to the pci core */
+enum {
+	PCI_CLOCK_INT = 0,
+	PCI_CLOCK_EXT
+};
+
+struct ltq_pci_data {
+	int clock;
+	int req_mask;
+};
+
+#endif
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index c9209ca..4a5d1ae 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_ZAO_CAPCELLA)	+= fixup-capcella.o
 obj-$(CONFIG_WR_PPMC)		+= fixup-wrppmc.o
 obj-$(CONFIG_MIKROTIK_RB532)	+= pci-rc32434.o ops-rc32434.o fixup-rc32434.o
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= pci-octeon.o pcie-octeon.o
+obj-$(CONFIG_SOC_XWAY)	+= pci-lantiq.o ops-lantiq.o
 
 ifdef CONFIG_PCI_MSI
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= msi-octeon.o
diff --git a/arch/mips/pci/ops-lantiq.c b/arch/mips/pci/ops-lantiq.c
new file mode 100644
index 0000000..457c9f1
--- /dev/null
+++ b/arch/mips/pci/ops-lantiq.c
@@ -0,0 +1,118 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <asm/addrspace.h>
+#include <linux/vmalloc.h>
+
+#include <lantiq_soc.h>
+
+#include "pci-lantiq.h"
+
+#define LTQ_PCI_CFG_BUSNUM_SHF 16
+#define LTQ_PCI_CFG_DEVNUM_SHF 11
+#define LTQ_PCI_CFG_FUNNUM_SHF 8
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+static int
+ltq_pci_config_access(unsigned char access_type, struct pci_bus *bus,
+	unsigned int devfn, unsigned int where, u32 *data)
+{
+	unsigned long cfg_base;
+	unsigned long flags;
+
+	u32 temp;
+
+	/* we support slot from 0 to 15 */
+	/* dev_fn 0&0x68 (AD29) is ifxmips itself */
+	if ((bus->number != 0) || ((devfn & 0xf8) > 0x78)
+			|| ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68))
+		return 1;
+
+	spin_lock_irqsave(&ebu_lock, flags);
+
+	cfg_base = ltq_pci_mapped_cfg;
+	cfg_base |= (bus->number << LTQ_PCI_CFG_BUSNUM_SHF) | (devfn <<
+			LTQ_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
+
+	/* Perform access */
+	if (access_type == PCI_ACCESS_WRITE) {
+		ltq_w32(swab32(*data), ((u32 *)cfg_base));
+	} else {
+		*data = ltq_r32(((u32 *)(cfg_base)));
+		*data = swab32(*data);
+	}
+	wmb();
+
+	/* clean possible Master abort */
+	cfg_base = (ltq_pci_mapped_cfg | (0x0 << LTQ_PCI_CFG_FUNNUM_SHF)) + 4;
+	temp = ltq_r32(((u32 *)(cfg_base)));
+	temp = swab32(temp);
+	cfg_base = (ltq_pci_mapped_cfg | (0x68 << LTQ_PCI_CFG_FUNNUM_SHF)) + 4;
+	ltq_w32(temp, ((u32 *)cfg_base));
+
+	spin_unlock_irqrestore(&ebu_lock, flags);
+
+	if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
+		return 1;
+
+	return 0;
+}
+
+int
+ltq_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
+		int where, int size, u32 *val)
+{
+	u32 data = 0;
+
+	if (ltq_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+ltq_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
+		int where, int size, u32 val)
+{
+	u32 data = 0;
+
+	if (size == 4) {
+		data = val;
+	} else {
+		if (ltq_pci_config_access(PCI_ACCESS_READ, bus,
+				devfn, where, &data))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+		if (size == 1)
+			data = (data & ~(0xff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+		else if (size == 2)
+			data = (data & ~(0xffff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+	}
+
+	if (ltq_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c
new file mode 100644
index 0000000..70f7c0f
--- /dev/null
+++ b/arch/mips/pci/pci-lantiq.c
@@ -0,0 +1,286 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/platform_device.h>
+
+#include <asm/pci.h>
+#include <asm/gpio.h>
+#include <asm/addrspace.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_irq.h>
+#include <lantiq_platform.h>
+
+#include "pci-lantiq.h"
+
+#define LTQ_PCI_CFG_BASE		0x17000000
+#define LTQ_PCI_CFG_SIZE		0x00008000
+#define LTQ_PCI_MEM_BASE		0x18000000
+#define LTQ_PCI_MEM_SIZE		0x02000000
+#define LTQ_PCI_IO_BASE		0x1AE00000
+#define LTQ_PCI_IO_SIZE		0x00200000
+
+#define PCI_CR_FCI_ADDR_MAP0	((u32 *)(PCI_CR_BASE_ADDR + 0x00C0))
+#define PCI_CR_FCI_ADDR_MAP1	((u32 *)(PCI_CR_BASE_ADDR + 0x00C4))
+#define PCI_CR_FCI_ADDR_MAP2	((u32 *)(PCI_CR_BASE_ADDR + 0x00C8))
+#define PCI_CR_FCI_ADDR_MAP3	((u32 *)(PCI_CR_BASE_ADDR + 0x00CC))
+#define PCI_CR_FCI_ADDR_MAP4	((u32 *)(PCI_CR_BASE_ADDR + 0x00D0))
+#define PCI_CR_FCI_ADDR_MAP5	((u32 *)(PCI_CR_BASE_ADDR + 0x00D4))
+#define PCI_CR_FCI_ADDR_MAP6	((u32 *)(PCI_CR_BASE_ADDR + 0x00D8))
+#define PCI_CR_FCI_ADDR_MAP7	((u32 *)(PCI_CR_BASE_ADDR + 0x00DC))
+#define PCI_CR_CLK_CTRL			((u32 *)(PCI_CR_BASE_ADDR + 0x0000))
+#define PCI_CR_PCI_MOD			((u32 *)(PCI_CR_BASE_ADDR + 0x0030))
+#define PCI_CR_PC_ARB			((u32 *)(PCI_CR_BASE_ADDR + 0x0080))
+#define PCI_CR_FCI_ADDR_MAP11hg	((u32 *)(PCI_CR_BASE_ADDR + 0x00E4))
+#define PCI_CR_BAR11MASK		((u32 *)(PCI_CR_BASE_ADDR + 0x0044))
+#define PCI_CR_BAR12MASK		((u32 *)(PCI_CR_BASE_ADDR + 0x0048))
+#define PCI_CR_BAR13MASK		((u32 *)(PCI_CR_BASE_ADDR + 0x004C))
+#define PCI_CS_BASE_ADDR1		((u32 *)(PCI_CS_BASE_ADDR + 0x0010))
+#define PCI_CR_PCI_ADDR_MAP11	((u32 *)(PCI_CR_BASE_ADDR + 0x0064))
+#define PCI_CR_FCI_BURST_LENGTH	((u32 *)(PCI_CR_BASE_ADDR + 0x00E8))
+#define PCI_CR_PCI_EOI			((u32 *)(PCI_CR_BASE_ADDR + 0x002C))
+#define PCI_CS_STS_CMD			((u32 *)(PCI_CS_BASE_ADDR + 0x0004))
+
+#define PCI_MASTER0_REQ_MASK_2BITS	8
+#define PCI_MASTER1_REQ_MASK_2BITS	10
+#define PCI_MASTER2_REQ_MASK_2BITS	12
+#define INTERNAL_ARB_ENABLE_BIT		0
+
+#define LTQ_CGU_IFCCR	((u32 *)(LTQ_CGU_BASE_ADDR + 0x0018))
+#define LTQ_CGU_PCICR	((u32 *)(LTQ_CGU_BASE_ADDR + 0x0034))
+
+u32 ltq_pci_mapped_cfg;
+
+int (*ltqpci_plat_dev_init)(struct pci_dev *dev) = NULL;
+
+/* Since the PCI REQ pins can be reused for other functionality, make it
+   possible to exclude those from interpretation by the PCI controller */
+static int ltq_pci_req_mask = 0xf;
+
+struct pci_ops ltq_pci_ops = {
+	.read = ltq_pci_read_config_dword,
+	.write = ltq_pci_write_config_dword
+};
+
+static struct resource pci_io_resource = {
+	.name = "pci io space",
+	.start = LTQ_PCI_IO_BASE,
+	.end = LTQ_PCI_IO_BASE + LTQ_PCI_IO_SIZE - 1,
+	.flags = IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+	.name = "pci memory space",
+	.start = LTQ_PCI_MEM_BASE,
+	.end = LTQ_PCI_MEM_BASE + LTQ_PCI_MEM_SIZE - 1,
+	.flags = IORESOURCE_MEM
+};
+
+static struct pci_controller ltq_pci_controller = {
+	.pci_ops = &ltq_pci_ops,
+	.mem_resource = &pci_mem_resource,
+	.mem_offset	= 0x00000000UL,
+	.io_resource = &pci_io_resource,
+	.io_offset	= 0x00000000UL,
+};
+
+int
+pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	u8 pin;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	switch (pin) {
+	case 0:
+		break;
+	case 1:
+		/* falling edge level triggered:0x4
+		   low level:0xc, rising edge:0x2 */
+		ltq_w32(ltq_r32(LTQ_EBU_PCC_CON) | 0xc, LTQ_EBU_PCC_CON);
+		ltq_w32(ltq_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN);
+		break;
+	case 2:
+	case 3:
+	case 4:
+		printk(KERN_WARNING "interrupt pin %d not supported yet!\n",
+			pin);
+	default:
+		printk(KERN_WARNING "invalid interrupt pin %d\n", pin);
+		return 1;
+	}
+
+	if (ltqpci_plat_dev_init)
+		return ltqpci_plat_dev_init(dev);
+
+	return 0;
+}
+
+static u32
+ltq_calc_bar11mask(void)
+{
+	u32 mem, bar11mask;
+
+	/* BAR11MASK value depends on available memory on system. */
+	mem = num_physpages * PAGE_SIZE;
+	bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) - 1)) - 1)) | 8;
+
+	return bar11mask;
+}
+
+static void
+ltq_pci_setup_clk(int external_clock)
+{
+	/* set clock to 33Mhz */
+	ltq_w32(ltq_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
+	ltq_w32(ltq_r32(LTQ_CGU_IFCCR) | 0x800000,	LTQ_CGU_IFCCR);
+	if (external_clock) {
+		ltq_w32(ltq_r32(LTQ_CGU_IFCCR) & ~(1 << 16), LTQ_CGU_IFCCR);
+		ltq_w32((1 << 30), LTQ_CGU_PCICR);
+	} else {
+		ltq_w32(ltq_r32(LTQ_CGU_IFCCR) | (1 << 16), LTQ_CGU_IFCCR);
+		ltq_w32((1 << 31) | (1 << 30), LTQ_CGU_PCICR);
+	}
+}
+
+static void
+ltq_pci_setup_gpio(void)
+{
+	/* PCI reset line is gpio driven */
+	ltq_gpio_request(21, 0, 0, 1, "pci-reset");
+
+	/* PCI_REQ line */
+	ltq_gpio_request(29, 1, 0, 0, "pci-req");
+
+	/* PCI_GNT line */
+	ltq_gpio_request(30, 1, 0, 1, "pci-gnt");
+}
+
+static int __devinit
+ltq_pci_startup(void)
+{
+	u32 temp_buffer;
+
+	/* setup pci clock and gpis used by pci */
+	ltq_pci_setup_gpio();
+
+	/* enable auto-switching between PCI and EBU */
+	ltq_w32(0xa, PCI_CR_CLK_CTRL);
+
+	/* busy, i.e. configuration is not done, PCI access has to be retried */
+	ltq_w32(ltq_r32(PCI_CR_PCI_MOD) & ~(1 << 24), PCI_CR_PCI_MOD);
+	wmb();
+	/* BUS Master/IO/MEM access */
+	ltq_w32(ltq_r32(PCI_CS_STS_CMD) | 7, PCI_CS_STS_CMD);
+
+	/* enable external 2 PCI masters */
+	temp_buffer = ltq_r32(PCI_CR_PC_ARB);
+	temp_buffer &= (~(ltq_pci_req_mask << 16));
+	/* enable internal arbiter */
+	temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT);
+	/* enable internal PCI master reqest */
+	temp_buffer &= (~(3 << PCI_MASTER0_REQ_MASK_2BITS));
+
+	/* enable EBU request */
+	temp_buffer &= (~(3 << PCI_MASTER1_REQ_MASK_2BITS));
+
+	/* enable all external masters request */
+	temp_buffer &= (~(3 << PCI_MASTER2_REQ_MASK_2BITS));
+	ltq_w32(temp_buffer, PCI_CR_PC_ARB);
+	wmb();
+
+	/* setup BAR memory regions */
+	ltq_w32(0x18000000, PCI_CR_FCI_ADDR_MAP0);
+	ltq_w32(0x18400000, PCI_CR_FCI_ADDR_MAP1);
+	ltq_w32(0x18800000, PCI_CR_FCI_ADDR_MAP2);
+	ltq_w32(0x18c00000, PCI_CR_FCI_ADDR_MAP3);
+	ltq_w32(0x19000000, PCI_CR_FCI_ADDR_MAP4);
+	ltq_w32(0x19400000, PCI_CR_FCI_ADDR_MAP5);
+	ltq_w32(0x19800000, PCI_CR_FCI_ADDR_MAP6);
+	ltq_w32(0x19c00000, PCI_CR_FCI_ADDR_MAP7);
+	ltq_w32(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg);
+	ltq_w32(ltq_calc_bar11mask(), PCI_CR_BAR11MASK);
+	ltq_w32(0, PCI_CR_PCI_ADDR_MAP11);
+	ltq_w32(0, PCI_CS_BASE_ADDR1);
+	/* both TX and RX endian swap are enabled */
+	ltq_w32(ltq_r32(PCI_CR_PCI_EOI) | 3, PCI_CR_PCI_EOI);
+	wmb();
+	ltq_w32(ltq_r32(PCI_CR_BAR12MASK) | 0x80000000, PCI_CR_BAR12MASK);
+	ltq_w32(ltq_r32(PCI_CR_BAR13MASK) | 0x80000000, PCI_CR_BAR13MASK);
+	/*use 8 dw burst length */
+	ltq_w32(0x303, PCI_CR_FCI_BURST_LENGTH);
+	ltq_w32(ltq_r32(PCI_CR_PCI_MOD) | (1 << 24), PCI_CR_PCI_MOD);
+	wmb();
+
+	/* toggle reset pin */
+	__gpio_set_value(21, 0);
+	wmb();
+	mdelay(1);
+	__gpio_set_value(21, 1);
+	return 0;
+}
+
+int __init
+pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	switch (slot) {
+	case 13:
+		/* IDSEL = AD29 --> USB Host Controller */
+		return INT_NUM_IM1_IRL0 + 17;
+	case 14:
+		/* IDSEL = AD30 --> mini PCI connector */
+		return INT_NUM_IM0_IRL0 + 22;
+	default:
+		printk(KERN_INFO "ltq_pci: no IRQ found for slot %d, pin %d\n",
+			slot, pin);
+		return 0;
+	}
+}
+
+static int __devinit
+ltq_pci_probe(struct platform_device *pdev)
+{
+	struct ltq_pci_data *ltq_pci_data =
+		(struct ltq_pci_data *) pdev->dev.platform_data;
+	pci_probe_only = 0;
+	ltq_pci_req_mask = ltq_pci_data->req_mask;
+	ltq_pci_setup_clk(ltq_pci_data->clock);
+	ltq_pci_startup();
+	ltq_pci_mapped_cfg =
+		(u32)ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE);
+	ltq_pci_controller.io_map_base =
+		(unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1);
+	register_pci_controller(&ltq_pci_controller);
+	return 0;
+}
+
+static struct platform_driver
+ltq_pci_driver = {
+	.probe = ltq_pci_probe,
+	.driver = {
+		.name = "ltq_pci",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init
+pcibios_init(void)
+{
+	int ret = platform_driver_register(&ltq_pci_driver);
+	if (ret)
+		printk(KERN_INFO "ltq_pci: Error registering platfom driver!");
+	return ret;
+}
+
+arch_initcall(pcibios_init);
diff --git a/arch/mips/pci/pci-lantiq.h b/arch/mips/pci/pci-lantiq.h
new file mode 100644
index 0000000..de75dd7
--- /dev/null
+++ b/arch/mips/pci/pci-lantiq.h
@@ -0,0 +1,18 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_PCI_H__
+#define _LTQ_PCI_H__
+
+extern u32 ltq_pci_mapped_cfg;
+extern int ltq_pci_read_config_dword(struct pci_bus *bus,
+	unsigned int devfn, int where, int size, u32 *val);
+extern int ltq_pci_write_config_dword(struct pci_bus *bus,
+	unsigned int devfn, int where, int size, u32 val);
+
+#endif
-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:57:11 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:57:20 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35672 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490984Ab1AETzg (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:36 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        Felix Fietkau <nbd@openwrt.org>, linux-mips@linux-mips.org
Subject: [PATCH 04/10] MIPS: lantiq: add serial port support
Date:   Wed,  5 Jan 2011 20:56:13 +0100
Message-Id: <1294257379-417-5-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28848
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds the driver for the 2 serial ports found inside the Lantiq SoC family

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Cc: linux-mips@linux-mips.org
---
 drivers/serial/Kconfig  |    8 +
 drivers/serial/Makefile |    1 +
 drivers/serial/lantiq.c |  774 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 783 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/lantiq.c

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index aff9dcd..e3a45ff 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1454,6 +1454,14 @@ config SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE
 	help
 	  Support for Console on the NWP serial ports.
 
+config SERIAL_LANTIQ
+	bool "Lantiq serial driver"
+	depends on LANTIQ
+	select SERIAL_CORE
+	select SERIAL_CORE_CONSOLE
+	help
+	  Support for console and UART on Lantiq SoCs.
+
 config SERIAL_QE
 	tristate "Freescale QUICC Engine serial port support"
 	depends on QUICC_ENGINE
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index c570576..434e0e0 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -89,3 +89,4 @@ obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
 obj-$(CONFIG_SERIAL_MRST_MAX3110)	+= mrst_max3110.o
 obj-$(CONFIG_SERIAL_MFD_HSU)	+= mfd.o
 obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
+obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
diff --git a/drivers/serial/lantiq.c b/drivers/serial/lantiq.c
new file mode 100644
index 0000000..c08e0a6
--- /dev/null
+++ b/drivers/serial/lantiq.c
@@ -0,0 +1,774 @@
+/*
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright (C) 2004 Infineon IFAP DC COM CPE
+ * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2010 Thomas Langer, <thomas.langer@lantiq.com>
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/device.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#define ltq_r32(reg)			__raw_readl(reg)
+#define ltq_r8(reg)			__raw_readb(reg)
+#define ltq_w32(val, reg)	__raw_writel(val, reg)
+#define ltq_w8(val, reg)		__raw_writeb(val, reg)
+#define ltq_w32_mask(clear, set, reg)	\
+	ltq_w32((ltq_r32(reg) & ~(clear)) | (set), reg)
+
+#define PORT_LTQ_ASC		111
+#define MAXPORTS		2
+
+#define UART_DUMMY_UER_RX 1
+
+#define DRVNAME "ltq_asc"
+
+#ifdef __BIG_ENDIAN
+#define LTQ_ASC_TBUF		(0x0020 + 3)
+#define LTQ_ASC_RBUF		(0x0024 + 3)
+#else
+#define LTQ_ASC_TBUF		0x0020
+#define LTQ_ASC_RBUF		0x0024
+#endif
+
+#define LTQ_ASC_FSTAT		0x0048
+#define LTQ_ASC_WHBSTATE	0x0018
+#define LTQ_ASC_STATE		0x0014
+#define LTQ_ASC_IRNCR		0x00F8
+#define LTQ_ASC_CLC			0x0000
+#define LTQ_ASC_ID			0x0008
+#define LTQ_ASC_PISEL		0x0004
+#define LTQ_ASC_TXFCON		0x0044
+#define LTQ_ASC_RXFCON		0x0040
+#define LTQ_ASC_CON			0x0010
+#define LTQ_ASC_BG			0x0050
+#define LTQ_ASC_IRNREN		0x00F4
+
+#define ASC_IRNREN_TX			0x1
+#define ASC_IRNREN_RX			0x2
+#define ASC_IRNREN_ERR			0x4
+#define ASC_IRNREN_TX_BUF		0x8
+#define ASC_IRNCR_TIR			0x1
+#define ASC_IRNCR_RIR			0x2
+#define ASC_IRNCR_EIR			0x4
+
+#define ASCOPT_CSIZE			0x3
+#define ASCOPT_CS7				0x1
+#define ASCOPT_CS8				0x2
+#define ASCOPT_PARENB			0x4
+#define ASCOPT_STOPB			0x8
+#define ASCOPT_PARODD			0x0
+#define ASCOPT_CREAD			0x20
+#define TXFIFO_FL				1
+#define RXFIFO_FL				1
+#define ASCCLC_DISS				0x2
+#define ASCCLC_RMCMASK			0x0000FF00
+#define ASCCLC_RMCOFFSET		8
+#define ASCCON_M_8ASYNC			0x0
+#define ASCCON_M_7ASYNC			0x2
+#define ASCCON_ODD				0x00000020
+#define ASCCON_STP				0x00000080
+#define ASCCON_BRS				0x00000100
+#define ASCCON_FDE				0x00000200
+#define ASCCON_R				0x00008000
+#define ASCCON_FEN				0x00020000
+#define ASCCON_ROEN				0x00080000
+#define ASCCON_TOEN				0x00100000
+#define ASCSTATE_PE				0x00010000
+#define ASCSTATE_FE				0x00020000
+#define ASCSTATE_ROE			0x00080000
+#define ASCSTATE_ANY			(ASCSTATE_ROE|ASCSTATE_PE|ASCSTATE_FE)
+#define ASCWHBSTATE_CLRREN		0x00000001
+#define ASCWHBSTATE_SETREN		0x00000002
+#define ASCWHBSTATE_CLRPE		0x00000004
+#define ASCWHBSTATE_CLRFE		0x00000008
+#define ASCWHBSTATE_CLRROE		0x00000020
+#define ASCTXFCON_TXFEN			0x0001
+#define ASCTXFCON_TXFFLU		0x0002
+#define ASCTXFCON_TXFITLMASK	0x3F00
+#define ASCTXFCON_TXFITLOFF		8
+#define ASCRXFCON_RXFEN			0x0001
+#define ASCRXFCON_RXFFLU		0x0002
+#define ASCRXFCON_RXFITLMASK	0x3F00
+#define ASCRXFCON_RXFITLOFF		8
+#define ASCFSTAT_RXFFLMASK		0x003F
+#define ASCFSTAT_TXFFLMASK		0x3F00
+#define ASCFSTAT_TXFFLOFF		8
+#define ASCFSTAT_RXFREEMASK		0x003F0000
+#define ASCFSTAT_RXFREEOFF		16
+#define ASCFSTAT_TXFREEMASK		0x3F000000
+#define ASCFSTAT_TXFREEOFF		24
+
+static void lqasc_tx_chars(struct uart_port *port);
+static struct ltq_uart_port *lqasc_port[2];
+static struct uart_driver lqasc_reg;
+
+struct ltq_uart_port {
+	struct uart_port	port;
+	struct clk			*clk;
+	unsigned int		tx_irq;
+	unsigned int		rx_irq;
+	unsigned int		err_irq;
+};
+
+static inline struct
+ltq_uart_port *to_ltq_uart_port(struct uart_port *port)
+{
+	return container_of(port, struct ltq_uart_port, port);
+}
+
+static void
+lqasc_stop_tx(struct uart_port *port)
+{
+	return;
+}
+
+static void
+lqasc_start_tx(struct uart_port *port)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	lqasc_tx_chars(port);
+	local_irq_restore(flags);
+	return;
+}
+
+static void
+lqasc_stop_rx(struct uart_port *port)
+{
+	ltq_w32(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE);
+}
+
+static void
+lqasc_enable_ms(struct uart_port *port)
+{
+}
+
+static void
+lqasc_rx_chars(struct uart_port *port)
+{
+	struct tty_struct *tty = port->state->port.tty;
+	unsigned int ch = 0, rsr = 0, fifocnt;
+
+	fifocnt =
+		ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
+	while (fifocnt--) {
+		u8 flag = TTY_NORMAL;
+		ch = ltq_r8(port->membase + LTQ_ASC_RBUF);
+		rsr = (ltq_r32(port->membase + LTQ_ASC_STATE)
+			& ASCSTATE_ANY) | UART_DUMMY_UER_RX;
+		tty_flip_buffer_push(tty);
+		port->icount.rx++;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		if (rsr & ASCSTATE_ANY) {
+			if (rsr & ASCSTATE_PE) {
+				port->icount.parity++;
+				ltq_w32_mask(0, ASCWHBSTATE_CLRPE,
+					port->membase + LTQ_ASC_WHBSTATE);
+			} else if (rsr & ASCSTATE_FE) {
+				port->icount.frame++;
+				ltq_w32_mask(0, ASCWHBSTATE_CLRFE,
+					port->membase + LTQ_ASC_WHBSTATE);
+			}
+			if (rsr & ASCSTATE_ROE) {
+				port->icount.overrun++;
+				ltq_w32_mask(0, ASCWHBSTATE_CLRROE,
+					port->membase + LTQ_ASC_WHBSTATE);
+			}
+
+			rsr &= port->read_status_mask;
+
+			if (rsr & ASCSTATE_PE)
+				flag = TTY_PARITY;
+			else if (rsr & ASCSTATE_FE)
+				flag = TTY_FRAME;
+		}
+
+		if ((rsr & port->ignore_status_mask) == 0)
+			tty_insert_flip_char(tty, ch, flag);
+
+		if (rsr & ASCSTATE_ROE)
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character
+			 */
+			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+	}
+	if (ch != 0)
+		tty_flip_buffer_push(tty);
+	return;
+}
+
+static void
+lqasc_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->state->xmit;
+	if (uart_tx_stopped(port)) {
+		lqasc_stop_tx(port);
+		return;
+	}
+
+	while (((ltq_r32(port->membase + LTQ_ASC_FSTAT) &
+		ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF) != 0) {
+		if (port->x_char) {
+			ltq_w8(port->x_char, port->membase + LTQ_ASC_TBUF);
+			port->icount.tx++;
+			port->x_char = 0;
+			continue;
+		}
+
+		if (uart_circ_empty(xmit))
+			break;
+
+		ltq_w8(port->state->xmit.buf[port->state->xmit.tail],
+			port->membase + LTQ_ASC_TBUF);
+		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
+lqasc_tx_int(int irq, void *_port)
+{
+	struct uart_port *port = (struct uart_port *)_port;
+	ltq_w32(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
+	lqasc_start_tx(port);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+lqasc_err_int(int irq, void *_port)
+{
+	struct uart_port *port = (struct uart_port *)_port;
+	/* clear any pending interrupts */
+	ltq_w32_mask(0, ASCWHBSTATE_CLRPE | ASCWHBSTATE_CLRFE |
+		ASCWHBSTATE_CLRROE, port->membase + LTQ_ASC_WHBSTATE);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+lqasc_rx_int(int irq, void *_port)
+{
+	struct uart_port *port = (struct uart_port *)_port;
+	ltq_w32(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
+	lqasc_rx_chars(port);
+	return IRQ_HANDLED;
+}
+
+static unsigned int
+lqasc_tx_empty(struct uart_port *port)
+{
+	int status;
+	status = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_TXFFLMASK;
+	return status ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int
+lqasc_get_mctrl(struct uart_port *port)
+{
+	return TIOCM_CTS | TIOCM_CAR | TIOCM_DSR;
+}
+
+static void
+lqasc_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+}
+
+static void
+lqasc_break_ctl(struct uart_port *port, int break_state)
+{
+}
+
+static int
+lqasc_startup(struct uart_port *port)
+{
+	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
+	int retval;
+
+	port->uartclk = clk_get_rate(ltq_port->clk);
+
+	ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
+		port->membase + LTQ_ASC_CLC);
+
+	ltq_w32(0, port->membase + LTQ_ASC_PISEL);
+	ltq_w32(
+		((TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) |
+		ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU,
+		port->membase + LTQ_ASC_TXFCON);
+	ltq_w32(
+		((RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK)
+		| ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU,
+		port->membase + LTQ_ASC_RXFCON);
+	/* make sure other settings are written to hardware before
+	   setting enable bits */
+	wmb();
+	ltq_w32_mask(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN |
+		ASCCON_ROEN, port->membase + LTQ_ASC_CON);
+
+	retval = request_irq(ltq_port->tx_irq, lqasc_tx_int,
+		IRQF_DISABLED, "asc_tx", port);
+	if (retval) {
+		pr_err("failed to request lqasc_tx_int\n");
+		return retval;
+	}
+
+	retval = request_irq(ltq_port->rx_irq, lqasc_rx_int,
+		IRQF_DISABLED, "asc_rx", port);
+	if (retval) {
+		pr_err("failed to request lqasc_rx_int\n");
+		goto err1;
+	}
+
+	retval = request_irq(ltq_port->err_irq, lqasc_err_int,
+		IRQF_DISABLED, "asc_err", port);
+	if (retval) {
+		pr_err("failed to request lqasc_err_int\n");
+		goto err2;
+	}
+
+	ltq_w32(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
+		port->membase + LTQ_ASC_IRNREN);
+	return 0;
+
+err2:
+	free_irq(ltq_port->rx_irq, port);
+err1:
+	free_irq(ltq_port->tx_irq, port);
+	return retval;
+}
+
+static void
+lqasc_shutdown(struct uart_port *port)
+{
+	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
+	free_irq(ltq_port->tx_irq, port);
+	free_irq(ltq_port->rx_irq, port);
+	free_irq(ltq_port->err_irq, port);
+
+	ltq_w32(0, port->membase + LTQ_ASC_CON);
+	ltq_w32_mask(ASCRXFCON_RXFEN, ASCRXFCON_RXFFLU,
+		port->membase + LTQ_ASC_RXFCON);
+	ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
+		port->membase + LTQ_ASC_TXFCON);
+}
+
+static void
+lqasc_set_termios(struct uart_port *port,
+	struct ktermios *new, struct ktermios *old)
+{
+	unsigned int cflag;
+	unsigned int iflag;
+	unsigned int quot;
+	unsigned int baud;
+	unsigned int con = 0;
+	unsigned long flags;
+
+	cflag = new->c_cflag;
+	iflag = new->c_iflag;
+
+	switch (cflag & CSIZE) {
+	case CS7:
+		con = ASCCON_M_7ASYNC;
+		break;
+
+	case CS5:
+	case CS6:
+	default:
+		con = ASCCON_M_8ASYNC;
+		break;
+	}
+
+	if (cflag & CSTOPB)
+		con |= ASCCON_STP;
+
+	if (cflag & PARENB) {
+		if (!(cflag & PARODD))
+			con &= ~ASCCON_ODD;
+		else
+			con |= ASCCON_ODD;
+	}
+
+	port->read_status_mask = ASCSTATE_ROE;
+	if (iflag & INPCK)
+		port->read_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
+
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
+
+	if (iflag & IGNBRK) {
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= ASCSTATE_ROE;
+	}
+
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= UART_DUMMY_UER_RX;
+
+	/* set error signals  - framing, parity  and overrun, enable receiver */
+	con |= ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN;
+
+	local_irq_save(flags);
+
+	/* set up CON */
+	ltq_w32_mask(0, con, port->membase + LTQ_ASC_CON);
+
+	/* Set baud rate - take a divider of 2 into account */
+	baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
+	quot = uart_get_divisor(port, baud);
+	quot = quot / 2 - 1;
+
+	/* disable the baudrate generator */
+	ltq_w32_mask(ASCCON_R, 0, port->membase + LTQ_ASC_CON);
+
+	/* make sure the fractional divider is off */
+	ltq_w32_mask(ASCCON_FDE, 0, port->membase + LTQ_ASC_CON);
+
+	/* set up to use divisor of 2 */
+	ltq_w32_mask(ASCCON_BRS, 0, port->membase + LTQ_ASC_CON);
+
+	/* now we can write the new baudrate into the register */
+	ltq_w32(quot, port->membase + LTQ_ASC_BG);
+
+	/* turn the baudrate generator back on */
+	ltq_w32_mask(0, ASCCON_R, port->membase + LTQ_ASC_CON);
+
+	/* enable rx */
+	ltq_w32(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
+
+	local_irq_restore(flags);
+}
+
+static const char*
+lqasc_type(struct uart_port *port)
+{
+	if (port->type == PORT_LTQ_ASC)
+		return DRVNAME;
+	else
+		return NULL;
+}
+
+static void
+lqasc_release_port(struct uart_port *port)
+{
+	if (port->flags & UPF_IOREMAP) {
+		iounmap(port->membase);
+		port->membase = NULL;
+	}
+}
+
+static int
+lqasc_request_port(struct uart_port *port)
+{
+	struct platform_device *pdev = to_platform_device(port->dev);
+	struct resource *mmres;
+	int size;
+
+	mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mmres)
+		return -ENODEV;
+	size = resource_size(mmres);
+
+	if (port->flags & UPF_IOREMAP) {
+		port->membase = ioremap_nocache(port->mapbase, size);
+		if (port->membase == NULL)
+			return -ENOMEM;
+	}
+	return 0;
+}
+
+static void
+lqasc_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_LTQ_ASC;
+		lqasc_request_port(port);
+	}
+}
+
+static int
+lqasc_verify_port(struct uart_port *port,
+	struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_LTQ_ASC)
+		ret = -EINVAL;
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		ret = -EINVAL;
+	if (ser->baud_base < 9600)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops lqasc_pops = {
+	.tx_empty =	lqasc_tx_empty,
+	.set_mctrl =	lqasc_set_mctrl,
+	.get_mctrl =	lqasc_get_mctrl,
+	.stop_tx =	lqasc_stop_tx,
+	.start_tx =	lqasc_start_tx,
+	.stop_rx =	lqasc_stop_rx,
+	.enable_ms =	lqasc_enable_ms,
+	.break_ctl =	lqasc_break_ctl,
+	.startup =	lqasc_startup,
+	.shutdown =	lqasc_shutdown,
+	.set_termios =	lqasc_set_termios,
+	.type =		lqasc_type,
+	.release_port =	lqasc_release_port,
+	.request_port =	lqasc_request_port,
+	.config_port =	lqasc_config_port,
+	.verify_port =	lqasc_verify_port,
+};
+
+static void
+lqasc_console_putchar(struct uart_port *port, int ch)
+{
+	int fifofree;
+
+	if (!port->membase)
+		return;
+
+	do {
+		fifofree = (ltq_r32(port->membase + LTQ_ASC_FSTAT)
+			& ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF;
+	} while (fifofree == 0);
+	ltq_w8(ch, port->membase + LTQ_ASC_TBUF);
+}
+
+
+static void
+lqasc_console_write(struct console *co, const char *s, u_int count)
+{
+	struct ltq_uart_port *ltq_port;
+	struct uart_port *port;
+	unsigned long flags;
+
+	if (co->index >= MAXPORTS)
+		return;
+
+	ltq_port = lqasc_port[co->index];
+	if (!ltq_port)
+		return;
+
+	port = &ltq_port->port;
+
+	local_irq_save(flags);
+	uart_console_write(port, s, count, lqasc_console_putchar);
+	local_irq_restore(flags);
+}
+
+static int __init
+lqasc_console_setup(struct console *co, char *options)
+{
+	struct ltq_uart_port *ltq_port;
+	struct uart_port *port;
+	int baud = 115200;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if (co->index >= MAXPORTS)
+		return -ENODEV;
+
+	ltq_port = lqasc_port[co->index];
+	if (!ltq_port)
+		return -ENODEV;
+
+	port = &ltq_port->port;
+
+	port->uartclk = clk_get_rate(ltq_port->clk);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console lqasc_console = {
+	.name =		"ttyS",
+	.write =	lqasc_console_write,
+	.device =	uart_console_device,
+	.setup =	lqasc_console_setup,
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
+	.data =		&lqasc_reg,
+};
+
+static int __init
+lqasc_console_init(void)
+{
+	register_console(&lqasc_console);
+	return 0;
+}
+console_initcall(lqasc_console_init);
+
+static struct uart_driver lqasc_reg = {
+	.owner =	THIS_MODULE,
+	.driver_name =	DRVNAME,
+	.dev_name =	"ttyS",
+	.major =	TTY_MAJOR,
+	.minor =	64,
+	.nr =		MAXPORTS,
+	.cons =		&lqasc_console,
+};
+
+static int __devinit
+lqasc_probe(struct platform_device *pdev)
+{
+	struct ltq_uart_port *ltq_port;
+	struct uart_port *port;
+	struct resource *mmres, *irqres;
+	int tx_irq, rx_irq, err_irq;
+	struct clk *clk;
+	int ret;
+
+	mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!mmres || !irqres)
+		return -ENODEV;
+
+	if (pdev->id >= MAXPORTS)
+		return -EBUSY;
+
+	if (lqasc_port[pdev->id] != NULL)
+		return -EBUSY;
+
+	clk = clk_get(&pdev->dev, "fpi");
+	if (IS_ERR(clk)) {
+		pr_err("failed to get fpi clk\n");
+		return -ENOENT;
+	}
+
+	tx_irq = platform_get_irq_byname(pdev, "tx");
+	if (tx_irq < 0) {
+		/* without named resources: assume standard irq scheme */
+		tx_irq = irqres->start;
+		rx_irq = irqres->start+2;
+		err_irq = irqres->start+3;
+	} else {
+		/* other irqs must be named also! */
+		rx_irq = platform_get_irq_byname(pdev, "rx");
+		err_irq = platform_get_irq_byname(pdev, "err");
+		if ((rx_irq < 0) | (err_irq < 0))
+			return -ENODEV;
+	}
+
+	ltq_port = kzalloc(sizeof(struct ltq_uart_port), GFP_KERNEL);
+	if (!ltq_port)
+		return -ENOMEM;
+
+	port = &ltq_port->port;
+
+	port->iotype	= SERIAL_IO_MEM;
+	port->flags	= ASYNC_BOOT_AUTOCONF | UPF_IOREMAP;
+	port->ops	= &lqasc_pops;
+	port->fifosize	= 16;
+	port->type	= PORT_LTQ_ASC,
+	port->line	= pdev->id;
+	port->dev	= &pdev->dev;
+
+	port->irq	= tx_irq; /* unused, just to be backward-compatibe */
+	port->mapbase	= mmres->start;
+
+	ltq_port->clk	= clk;
+
+	ltq_port->tx_irq = tx_irq;
+	ltq_port->rx_irq = rx_irq;
+	ltq_port->err_irq = err_irq;
+
+	lqasc_port[pdev->id] = ltq_port;
+	platform_set_drvdata(pdev, ltq_port);
+
+	ret = uart_add_one_port(&lqasc_reg, port);
+
+	return ret;
+}
+
+static int __devexit
+lqasc_remove(struct platform_device *pdev)
+{
+	struct ltq_uart_port *ltq_port = platform_get_drvdata(pdev);
+	int ret;
+
+	clk_put(ltq_port->clk);
+	platform_set_drvdata(pdev, NULL);
+	lqasc_port[pdev->id] = NULL;
+	ret = uart_remove_one_port(&lqasc_reg, &ltq_port->port);
+	kfree(ltq_port);
+
+	return 0;
+}
+
+static struct platform_driver lqasc_driver = {
+	.probe		= lqasc_probe,
+	.remove		= __devexit_p(lqasc_remove),
+
+	.driver		= {
+		.name	= DRVNAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+int __init
+init_lqasc(void)
+{
+	int ret;
+
+	ret = uart_register_driver(&lqasc_reg);
+	if (ret != 0)
+		return ret;
+
+	ret = platform_driver_register(&lqasc_driver);
+	if (ret != 0)
+		uart_unregister_driver(&lqasc_reg);
+
+	return ret;
+}
+
+void __exit
+exit_lqasc(void)
+{
+	platform_driver_unregister(&lqasc_driver);
+	uart_unregister_driver(&lqasc_reg);
+}
+
+module_init(init_lqasc);
+module_exit(exit_lqasc);
+
+MODULE_DESCRIPTION("Lantiq serial port driver");
+MODULE_LICENSE("GPL");
-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:57:39 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:57:44 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35678 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490987Ab1AETzh (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:37 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        Wim Van Sebroeck <wim@iguana.be>, linux-mips@linux-mips.org,
        linux-watchdog@vger.kernel.org
Subject: [PATCH 05/10] MIPS: lantiq: add watchdog support
Date:   Wed,  5 Jan 2011 20:56:14 +0100
Message-Id: <1294257379-417-6-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28849
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds the driver for the watchdog found inside the Lantiq SoC family.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: Wim Van Sebroeck <wim@iguana.be>
Cc: linux-mips@linux-mips.org
Cc: linux-watchdog@vger.kernel.org
---
 drivers/watchdog/Kconfig      |    6 +
 drivers/watchdog/Makefile     |    1 +
 drivers/watchdog/lantiq_wdt.c |  208 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 215 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/lantiq_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index a5ad77e..3e0733e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -930,6 +930,12 @@ config BCM63XX_WDT
 	  To compile this driver as a loadable module, choose M here.
 	  The module will be called bcm63xx_wdt.
 
+config LANTIQ_WDT
+	tristate "Lantiq SoC watchdog"
+	depends on LANTIQ
+	help
+	  Hardware driver for the Lantiq SoC Watchdog Timer.
+
 # PARISC Architecture
 
 # POWERPC Architecture
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 4b0ef38..d845e47 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -119,6 +119,7 @@ obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
 obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
 obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
 octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
+obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
 
 # PARISC Architecture
 
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
new file mode 100644
index 0000000..543bcf1
--- /dev/null
+++ b/drivers/watchdog/lantiq_wdt.c
@@ -0,0 +1,208 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ *  Based on EP93xx wdt driver
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+
+#include <lantiq.h>
+
+#define LTQ_WDT_PW1			0x00BE0000
+#define LTQ_WDT_PW2			0x00DC0000
+
+#define LTQ_BIU_WDT_CR		0x3F0
+#define LTQ_BIU_WDT_SR		0x3F8
+
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+static int wdt_ok_to_close;
+#endif
+
+static int wdt_timeout = 30;
+static __iomem void *wdt_membase;
+static unsigned long io_region_clk;
+
+static int
+ltq_wdt_enable(unsigned int timeout)
+{
+	ltq_w32(LTQ_WDT_PW1, wdt_membase + LTQ_BIU_WDT_CR);
+	ltq_w32(LTQ_WDT_PW2 |
+		(0x3 << 26) | /* PWL */
+		(0x3 << 24) | /* CLKDIV */
+		(0x1 << 31) | /* enable */
+		((timeout * (io_region_clk / 0x40000)) + 0x1000), /* reload */
+			wdt_membase + LTQ_BIU_WDT_CR);
+	return 0;
+}
+
+static void
+ltq_wdt_disable(void)
+{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+	wdt_ok_to_close = 0;
+#endif
+	ltq_w32(LTQ_WDT_PW1, wdt_membase + LTQ_BIU_WDT_CR);
+	ltq_w32(LTQ_WDT_PW2, wdt_membase + LTQ_BIU_WDT_CR);
+}
+
+static ssize_t
+ltq_wdt_write(struct file *file, const char __user *data,
+		size_t len, loff_t *ppos)
+{
+	size_t i;
+	if (!len)
+		return 0;
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+	for (i = 0; i != len; i++) {
+		char c;
+		if (get_user(c, data + i))
+			return -EFAULT;
+		if (c == 'V')
+			wdt_ok_to_close = 1;
+	}
+#endif
+	ltq_wdt_enable(wdt_timeout);
+	return len;
+}
+
+static struct watchdog_info ident = {
+	.options = WDIOF_MAGICCLOSE,
+	.identity = "ltq_wdt",
+};
+
+static long
+ltq_wdt_ioctl(struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	int ret = -ENOTTY;
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		ret = copy_to_user((struct watchdog_info __user *)arg, &ident,
+				sizeof(ident)) ? -EFAULT : 0;
+		break;
+
+	case WDIOC_GETTIMEOUT:
+		ret = put_user(wdt_timeout, (int __user *)arg);
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		ret = get_user(wdt_timeout, (int __user *)arg);
+		break;
+
+	case WDIOC_KEEPALIVE:
+		ltq_wdt_enable(wdt_timeout);
+		ret = 0;
+		break;
+	}
+	return ret;
+}
+
+static int
+ltq_wdt_open(struct inode *inode, struct file *file)
+{
+	ltq_wdt_enable(wdt_timeout);
+	return nonseekable_open(inode, file);
+}
+
+static int
+ltq_wdt_release(struct inode *inode, struct file *file)
+{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+	if (wdt_ok_to_close)
+		ltq_wdt_disable();
+	else
+#endif
+		printk(KERN_ERR "ltq_wdt: watchdog closed without warning,"
+			" rebooting system\n");
+	return 0;
+}
+
+static const struct file_operations ltq_wdt_fops = {
+	.owner			= THIS_MODULE,
+	.write			= ltq_wdt_write,
+	.unlocked_ioctl	= ltq_wdt_ioctl,
+	.open			= ltq_wdt_open,
+	.release		= ltq_wdt_release,
+};
+
+static struct miscdevice ltq_wdt_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &ltq_wdt_fops,
+};
+
+static int
+ltq_wdt_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct clk *clk;
+	int ret = 0;
+	if (!res)
+		return -ENOENT;
+	res = request_mem_region(res->start, resource_size(res),
+		dev_name(&pdev->dev));
+	if (!res)
+		return -EBUSY;
+	wdt_membase = ioremap_nocache(res->start, resource_size(res));
+	if (!wdt_membase) {
+		ret = -ENOMEM;
+		goto err_release_mem_region;
+	}
+	clk = clk_get(&pdev->dev, "io");
+	io_region_clk = clk_get_rate(clk);;
+	ret = misc_register(&ltq_wdt_miscdev);
+	if (!ret)
+		return 0;
+
+	iounmap(wdt_membase);
+err_release_mem_region:
+	release_mem_region(res->start, resource_size(res));
+	return ret;
+}
+
+static int
+ltq_wdt_remove(struct platform_device *dev)
+{
+	ltq_wdt_disable();
+	misc_deregister(&ltq_wdt_miscdev);
+	return 0;
+}
+
+static struct platform_driver ltq_wdt_driver = {
+	.probe = ltq_wdt_probe,
+	.remove = ltq_wdt_remove,
+	.driver = {
+		.name = "ltq_wdt",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init
+init_ltq_wdt(void)
+{
+	return platform_driver_register(&ltq_wdt_driver);
+}
+
+static void __exit
+exit_ltq_wdt(void)
+{
+	platform_driver_unregister(&ltq_wdt_driver);
+}
+
+module_init(init_ltq_wdt);
+module_exit(exit_ltq_wdt);
+
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("Lantiq Watchdog");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:58:03 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:58:08 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35686 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490989Ab1AETzi (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:38 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        David Woodhouse <dwmw2@infradead.org>,
        linux-mips@linux-mips.org, linux-mtd@lists.infradead.org
Subject: [PATCH 06/10] MIPS: lantiq: add NOR flash support
Date:   Wed,  5 Jan 2011 20:56:15 +0100
Message-Id: <1294257379-417-7-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28850
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

NOR flash is attached to the same EBU (External Bus Unit) as PCI. As described
in the PCI patch, the EBU is a little obscure, resulting in the upper and lower
16 bit of the data on a 32 bit read are swapped. (essentially we have a addr^=2)
This only happens on the read of data. In order to not have to high an impact
on the read performance from the EBU we store all data on the flash with
addr^=2. This allows us to do generic reads without having to do any swapping.
For the write to now work we need to swizzle the the 0x2 bit of the addr.
However this write swizzle needs to only happen when doing a CMD and not a DATA
write.

As the MTD layer currently makes no difference between a CMD and DATA read when
using complex maps, the map driver does not know when the swizzle and when not
to swizzle. The next patch in the series adds a hack to the MTD to workaround
this problem. I am sending these 2 patches to the mtd list aswell. There are
several ways to solve this generically in the mtd layer in a much better way.
This will have minor impact on the actual map code provided in this patch.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: linux-mips@linux-mips.org
Cc: linux-mtd@lists.infradead.org
---
 drivers/mtd/maps/Kconfig  |    7 ++
 drivers/mtd/maps/Makefile |    1 +
 drivers/mtd/maps/lantiq.c |  169 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 177 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/maps/lantiq.c

diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index a0dd7bb..ca69a7f 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -260,6 +260,13 @@ config MTD_BCM963XX
 	  Support for parsing CFE image tag and creating MTD partitions on
 	  Broadcom BCM63xx boards.
 
+config MTD_LANTIQ
+	bool "Lantiq SoC NOR support"
+	depends on LANTIQ && MTD_PARTITIONS
+	help
+	  Support for NOR flash chips on Lantiq SoC. The Chips are connected
+	  to the SoCs EBU (External Bus Unit)
+
 config MTD_DILNETPC
 	tristate "CFI Flash device mapped on DIL/Net PC"
 	depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index c7869c7..bb2ce2f 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -59,3 +59,4 @@ obj-$(CONFIG_MTD_RBTX4939)	+= rbtx4939-flash.o
 obj-$(CONFIG_MTD_VMU)		+= vmu-flash.o
 obj-$(CONFIG_MTD_GPIO_ADDR)	+= gpio-addr-flash.o
 obj-$(CONFIG_MTD_BCM963XX)	+= bcm963xx-flash.o
+obj-$(CONFIG_MTD_LANTIQ)	+= lantiq.o
diff --git a/drivers/mtd/maps/lantiq.c b/drivers/mtd/maps/lantiq.c
new file mode 100644
index 0000000..e5a361e
--- /dev/null
+++ b/drivers/mtd/maps/lantiq.c
@@ -0,0 +1,169 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2004 Liu Peng Infineon IFAP DC COM CPE
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+#include <linux/magic.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_platform.h>
+
+static map_word
+ltq_read16(struct map_info *map, unsigned long adr)
+{
+	unsigned long flags;
+	map_word temp;
+	spin_lock_irqsave(&ebu_lock, flags);
+	adr ^= 2;
+	temp.x[0] = *((__u16 *)(map->virt + adr));
+	spin_unlock_irqrestore(&ebu_lock, flags);
+	return temp;
+}
+
+static void
+ltq_write16(struct map_info *map, map_word d, unsigned long adr)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&ebu_lock, flags);
+	adr ^= 2;
+	*((__u16 *)(map->virt + adr)) = d.x[0];
+	spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+void
+ltq_copy_from(struct map_info *map, void *to,
+	unsigned long from, ssize_t len)
+{
+	unsigned char *p;
+	unsigned char *to_8;
+	unsigned long flags;
+	spin_lock_irqsave(&ebu_lock, flags);
+	from = (unsigned long)(from + map->virt);
+	p = (unsigned char *) from;
+	to_8 = (unsigned char *) to;
+	while (len--)
+		*to_8++ = *p++;
+	spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+void
+ltq_copy_to(struct map_info *map, unsigned long to,
+	const void *from, ssize_t len)
+{
+	unsigned char *p =  (unsigned char *)from;
+	unsigned char *to_8;
+	unsigned long flags;
+	spin_lock_irqsave(&ebu_lock, flags);
+	to += (unsigned long) map->virt;
+	to_8 = (unsigned char *)to;
+	while (len--)
+		*p++ = *to_8++;
+	spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+static const char * const part_probe_types[] = {
+	"cmdlinepart", NULL };
+
+static struct map_info ltq_map = {
+	.name = "ltq_nor",
+	.bankwidth = 2,
+	.read = ltq_read16,
+	.write = ltq_write16,
+	.copy_from = ltq_copy_from,
+	.copy_to = ltq_copy_to,
+};
+
+static int
+ltq_mtd_probe(struct platform_device *pdev)
+{
+	struct physmap_flash_data *ltq_mtd_data =
+		(struct physmap_flash_data *) dev_get_platdata(&pdev->dev);
+	struct mtd_info *ltq_mtd = NULL;
+	struct mtd_partition *parts = NULL;
+	struct resource *res = 0;
+	int nr_parts = 0;
+
+#ifdef CONFIG_SOC_TYPE_XWAY
+	ltq_w32(ltq_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
+#endif
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get memory resource");
+		return -ENOENT;
+	}
+	res = request_mem_region(res->start, resource_size(res),
+		dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev, "failed to request mem resource");
+		return -EBUSY;
+	}
+
+	ltq_map.phys = res->start;
+	ltq_map.size = resource_size(res);
+	ltq_map.virt = ioremap_nocache(ltq_map.phys, ltq_map.size);
+
+	if (!ltq_map.virt) {
+		dev_err(&pdev->dev, "failed to ioremap!\n");
+		return -EIO;
+	}
+
+	ltq_mtd = (struct mtd_info *) do_map_probe("cfi_probe", &ltq_map);
+	if (!ltq_mtd) {
+		iounmap(ltq_map.virt);
+		dev_err(&pdev->dev, "probing failed\n");
+		return -ENXIO;
+	}
+
+	ltq_mtd->owner = THIS_MODULE;
+
+	nr_parts = parse_mtd_partitions(ltq_mtd, part_probe_types, &parts, 0);
+	if (nr_parts > 0) {
+		dev_info(&pdev->dev,
+			"using %d partitions from cmdline", nr_parts);
+	} else {
+		nr_parts = ltq_mtd_data->nr_parts;
+		parts = ltq_mtd_data->parts;
+	}
+
+	add_mtd_partitions(ltq_mtd, parts, nr_parts);
+	return 0;
+}
+
+static struct platform_driver ltq_mtd_driver = {
+	.probe = ltq_mtd_probe,
+	.driver = {
+		.name = "ltq_nor",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init
+init_ltq_mtd(void)
+{
+	int ret = platform_driver_register(&ltq_mtd_driver);
+	if (ret)
+		printk(KERN_INFO "ltq_nor: error registering platfom driver");
+	return ret;
+}
+
+module_init(init_ltq_mtd);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("Lantiq SoC NOR");
-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:58:27 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:58:32 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35692 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490990Ab1AETzj (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:39 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        linux-mips@linux-mips.org
Subject: [PATCH 08/10] MIPS: lantiq: add platform device support
Date:   Wed,  5 Jan 2011 20:56:17 +0100
Message-Id: <1294257379-417-9-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28851
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds the wrappers for registering our platform devices.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lantiq/Makefile       |    2 +-
 arch/mips/lantiq/devices.c      |  127 +++++++++++++++++++++++++++++++++++++++
 arch/mips/lantiq/devices.h      |   20 ++++++
 arch/mips/lantiq/xway/Makefile  |    2 +-
 arch/mips/lantiq/xway/devices.c |   55 +++++++++++++++++
 arch/mips/lantiq/xway/devices.h |   16 +++++
 6 files changed, 220 insertions(+), 2 deletions(-)
 create mode 100644 arch/mips/lantiq/devices.c
 create mode 100644 arch/mips/lantiq/devices.h
 create mode 100644 arch/mips/lantiq/xway/devices.c
 create mode 100644 arch/mips/lantiq/xway/devices.h

diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
index a268391..e5dae0e 100644
--- a/arch/mips/lantiq/Makefile
+++ b/arch/mips/lantiq/Makefile
@@ -4,7 +4,7 @@
 # under the terms of the GNU General Public License version 2 as published
 # by the Free Software Foundation.
 
-obj-y := irq.o setup.o clk.o prom.o
+obj-y := irq.o setup.o clk.o prom.o devices.o
 
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 
diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c
new file mode 100644
index 0000000..2c68d8e
--- /dev/null
+++ b/arch/mips/lantiq/devices.c
@@ -0,0 +1,127 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/etherdevice.h>
+#include <linux/reboot.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+
+#include <lantiq_soc.h>
+
+#include "devices.h"
+
+#define IRQ_RES(resname, irq) \
+	{.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
+
+/* nor flash */
+static struct resource ltq_nor_resource = {
+	.name	= "nor",
+	.start	= LTQ_FLASH_START,
+	.end	= LTQ_FLASH_START + LTQ_FLASH_MAX - 1,
+	.flags  = IORESOURCE_MEM,
+};
+
+static struct platform_device ltq_nor = {
+	.name			= "ltq_nor",
+	.resource		= &ltq_nor_resource,
+	.num_resources	= 1,
+};
+
+void __init
+ltq_register_nor(struct physmap_flash_data *data)
+{
+	ltq_nor.dev.platform_data = data;
+	platform_device_register(&ltq_nor);
+}
+
+/* watchdog */
+static struct resource ltq_wdt_resource = {
+	.name	= "watchdog",
+	.start  = LTQ_WDT_BASE,
+	.end    = LTQ_WDT_BASE + LTQ_WDT_SIZE - 1,
+	.flags  = IORESOURCE_MEM,
+};
+
+void __init
+ltq_register_wdt(void)
+{
+	platform_device_register_simple("ltq_wdt", 0, &ltq_wdt_resource, 1);
+}
+
+/* asc ports */
+static struct resource ltq_asc0_resources[] = {
+	{
+		.start  = LTQ_ASC0_BASE,
+		.end    = LTQ_ASC0_BASE + LTQ_ASC_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	IRQ_RES(tx, LTQ_ASC_TIR(0)),
+	IRQ_RES(rx, LTQ_ASC_RIR(0)),
+	IRQ_RES(err, LTQ_ASC_EIR(0)),
+};
+
+static struct resource ltq_asc1_resources[] = {
+	{
+		.start  = LTQ_ASC1_BASE,
+		.end    = LTQ_ASC1_BASE + LTQ_ASC_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	IRQ_RES(tx, LTQ_ASC_TIR(1)),
+	IRQ_RES(rx, LTQ_ASC_RIR(1)),
+	IRQ_RES(err, LTQ_ASC_EIR(1)),
+};
+
+void __init
+ltq_register_asc(int port)
+{
+	switch (port) {
+	case 0:
+		platform_device_register_simple("ltq_asc", 0,
+			ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources));
+		break;
+	case 1:
+		platform_device_register_simple("ltq_asc", 1,
+			ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources));
+		break;
+	default:
+		break;
+	}
+}
+
+#ifdef CONFIG_PCI
+/* pci */
+static struct platform_device ltq_pci = {
+	.name			= "ltq_pci",
+	.num_resources	= 0,
+};
+
+void __init
+ltq_register_pci(struct ltq_pci_data *data)
+{
+	ltq_pci.dev.platform_data = data;
+	platform_device_register(&ltq_pci);
+}
+#else
+void __init
+ltq_register_pci(struct ltq_pci_data *data)
+{
+}
+#endif
diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h
new file mode 100644
index 0000000..069006c
--- /dev/null
+++ b/arch/mips/lantiq/devices.h
@@ -0,0 +1,20 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_DEVICES_H__
+#define _LTQ_DEVICES_H__
+
+#include <lantiq_platform.h>
+#include <linux/mtd/physmap.h>
+
+extern void ltq_register_nor(struct physmap_flash_data *data);
+extern void ltq_register_wdt(void);
+extern void ltq_register_asc(int port);
+extern void ltq_register_pci(struct ltq_pci_data *data);
+
+#endif
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index 64730d5..7b36708 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,4 +1,4 @@
-obj-y := pmu.o reset.o gpio.o
+obj-y := pmu.o reset.o gpio.o devices.o
 
 obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
 obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
new file mode 100644
index 0000000..c2be742
--- /dev/null
+++ b/arch/mips/lantiq/xway/devices.c
@@ -0,0 +1,55 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mtd/physmap.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/etherdevice.h>
+#include <linux/reboot.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_irq.h>
+#include <lantiq_platform.h>
+
+
+/* gpio */
+static struct resource ltq_gpio_resource[] = {
+	{
+		.name	= "gpio0",
+		.start  = LTQ_GPIO0_BASE_ADDR,
+		.end    = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.name	= "gpio1",
+		.start  = LTQ_GPIO1_BASE_ADDR,
+		.end    = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	}
+};
+
+void __init
+ltq_register_gpio(void)
+{
+	platform_device_register_simple("ltq_gpio", 0,
+		&ltq_gpio_resource[0], 1);
+	platform_device_register_simple("ltq_gpio", 1,
+		&ltq_gpio_resource[1], 1);
+}
diff --git a/arch/mips/lantiq/xway/devices.h b/arch/mips/lantiq/xway/devices.h
new file mode 100644
index 0000000..d248bf3
--- /dev/null
+++ b/arch/mips/lantiq/xway/devices.h
@@ -0,0 +1,16 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_DEVICES_XWAY_H__
+#define _LTQ_DEVICES_XWAY_H__
+
+#include "../devices.h"
+
+extern void ltq_register_gpio(void);
+
+#endif
-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:58:51 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:58:54 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35696 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490993Ab1AETzj (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:39 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        Gabor Juhos <juhosg@openwrt.org>, linux-mips@linux-mips.org
Subject: [PATCH 09/10] MIPS: lantiq: add mips_machine support
Date:   Wed,  5 Jan 2011 20:56:18 +0100
Message-Id: <1294257379-417-10-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28852
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds support for Gabor's mips_machine patch.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: Gabor Juhos <juhosg@openwrt.org>
Cc: linux-mips@linux-mips.org
---
 arch/mips/Kconfig            |    1 +
 arch/mips/lantiq/machtypes.h |   18 ++++++++++++++++++
 arch/mips/lantiq/setup.c     |   25 +++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/lantiq/machtypes.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 9d3fd89..ee5dccf 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -207,6 +207,7 @@ config LANTIQ
 	select ARCH_REQUIRE_GPIOLIB
 	select SWAP_IO_SPACE
 	select BOOT_RAW
+	select MIPS_MACHINE
 
 config LASAT
 	bool "LASAT Networks platforms"
diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h
new file mode 100644
index 0000000..ffcacfc
--- /dev/null
+++ b/arch/mips/lantiq/machtypes.h
@@ -0,0 +1,18 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_MACH_H__
+#define _LANTIQ_MACH_H__
+
+#include <asm/mips_machine.h>
+
+enum lantiq_mach_type {
+	LTQ_MACH_GENERIC = 0,
+};
+
+#endif
diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c
index f0f74d2..b30567e 100644
--- a/arch/mips/lantiq/setup.c
+++ b/arch/mips/lantiq/setup.c
@@ -14,6 +14,9 @@
 
 #include <lantiq.h>
 
+#include "machtypes.h"
+#include "devices.h"
+
 void __init
 plat_mem_setup(void)
 {
@@ -43,3 +46,25 @@ plat_mem_setup(void)
 	memsize *= 1024 * 1024;
 	add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
 }
+
+static int __init
+lantiq_setup(void)
+{
+	ltq_register_asc(0);
+	ltq_register_asc(1);
+	mips_machine_setup();
+	return 0;
+}
+
+arch_initcall(lantiq_setup);
+
+static void __init
+lantiq_generic_init(void)
+{
+	/* Nothing to do */
+}
+
+MIPS_MACHINE(LTQ_MACH_GENERIC,
+	     "Generic",
+	     "Generic Lantiq based board",
+	     lantiq_generic_init);
-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:59:13 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:59:18 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35699 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490996Ab1AETzk (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:55:40 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        David Woodhouse <dwmw2@infradead.org>,
        linux-mips@linux-mips.org, linux-mtd@lists.infradead.org
Subject: [PATCH 07/10] MIPS: lantiq: add NOR flash CFI address swizzle
Date:   Wed,  5 Jan 2011 20:56:16 +0100
Message-Id: <1294257379-417-8-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28853
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds the hack mentioned in the previous patch.

It is only a hack to make the map driver work until a better solution
is discussed.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: linux-mips@linux-mips.org
Cc: linux-mtd@lists.infradead.org
---
 drivers/mtd/chips/Kconfig           |    9 +++++++++
 drivers/mtd/chips/cfi_cmdset_0002.c |    8 ++++++++
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index 35c6a23..9ecb5eb 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -39,6 +39,15 @@ config MTD_CFI_ADV_OPTIONS
 
 	  If unsure, say 'N'.
 
+config MTD_CFI_CMD_SWIZZLE
+	bool "Swizzle last bit of command address"
+	default y
+	depends on LANTIQ
+	help
+	  lantiq SoCs share the external bus unit with the pci interface
+	  for MTD to work at the the same time with PCI, we need to add
+	  this quirk
+
 choice
 	prompt "Flash cmd/query data swapping"
 	depends on MTD_CFI_ADV_OPTIONS
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 3b8e32d..e047af1 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -39,7 +39,12 @@
 #include <linux/mtd/xip.h>
 
 #define AMD_BOOTLOC_BUG
+
+#ifdef CONFIG_MTD_CFI_CMD_SWIZZLE
+#define FORCE_WORD_WRITE 1
+#else
 #define FORCE_WORD_WRITE 0
+#endif
 
 #define MAX_WORD_RETRIES 3
 
@@ -1140,6 +1145,9 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
 	int retry_cnt = 0;
 
 	adr += chip->start;
+#ifdef CONFIG_MTD_CFI_CMD_SWIZZLE
+	adr ^= 2;
+#endif
 
 	mutex_lock(&chip->mutex);
 	ret = get_chip(map, chip, adr, FL_WRITING);
-- 
1.7.2.3


From blogic@openwrt.org Wed Jan  5 20:59:37 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 20:59:41 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35756 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490987Ab1AET7M (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Wed, 5 Jan 2011 20:59:12 +0100
From:   John Crispin <blogic@openwrt.org>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     John Crispin <blogic@openwrt.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        linux-mips@linux-mips.org
Subject: [PATCH 10/10] MIPS: lantiq: add machtypes for lantiq eval kits
Date:   Wed,  5 Jan 2011 20:56:19 +0100
Message-Id: <1294257379-417-11-git-send-email-blogic@openwrt.org>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294257379-417-1-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
Return-Path: <blogic@openwrt.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: 28854
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

This patch adds mach specific code for the Lantiq EASY50712/50601 evaluation
boards

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lantiq/Kconfig               |    2 +
 arch/mips/lantiq/machtypes.h           |    2 +
 arch/mips/lantiq/xway/Kconfig          |   25 +++++++++++
 arch/mips/lantiq/xway/Makefile         |    3 +
 arch/mips/lantiq/xway/mach-easy50601.c |   70 ++++++++++++++++++++++++++++++++
 arch/mips/lantiq/xway/mach-easy50712.c |   70 ++++++++++++++++++++++++++++++++
 6 files changed, 172 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/lantiq/xway/Kconfig
 create mode 100644 arch/mips/lantiq/xway/mach-easy50601.c
 create mode 100644 arch/mips/lantiq/xway/mach-easy50712.c

diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index 2780461..3fccf21 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -18,4 +18,6 @@ config SOC_XWAY
 	select HW_HAS_PCI
 endchoice
 
+source "arch/mips/lantiq/xway/Kconfig"
+
 endif
diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h
index ffcacfc..7e01b8c 100644
--- a/arch/mips/lantiq/machtypes.h
+++ b/arch/mips/lantiq/machtypes.h
@@ -13,6 +13,8 @@
 
 enum lantiq_mach_type {
 	LTQ_MACH_GENERIC = 0,
+	LTQ_MACH_EASY50712,	/* Danube evaluation board */
+	LTQ_MACH_EASY50601,	/* Amazon SE evaluation board */
 };
 
 #endif
diff --git a/arch/mips/lantiq/xway/Kconfig b/arch/mips/lantiq/xway/Kconfig
new file mode 100644
index 0000000..f6d0bec
--- /dev/null
+++ b/arch/mips/lantiq/xway/Kconfig
@@ -0,0 +1,25 @@
+if SOC_XWAY
+
+menu "Mips Machine"
+
+config LANTIQ_MACH_EASY50712
+	bool "Easy50712 - Danube"
+	default y
+
+endmenu
+
+endif
+
+if SOC_AMAZON_SE
+
+menu "Mips Machine"
+
+config LANTIQ_MACH_EASY50601
+	bool "Easy50601 - Amazon SE"
+	default y
+
+endmenu
+
+endif
+
+
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index 7b36708..570507c 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -2,3 +2,6 @@ obj-y := pmu.o reset.o gpio.o devices.o
 
 obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
 obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
+
+obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
+obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c
new file mode 100644
index 0000000..fb591fc
--- /dev/null
+++ b/arch/mips/lantiq/xway/mach-easy50601.c
@@ -0,0 +1,70 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+
+#include <lantiq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition easy50601_partitions[] = {
+	{
+		.name	= "uboot",
+		.offset	= 0x0,
+		.size	= 0x10000,
+	},
+	{
+		.name	= "uboot_env",
+		.offset	= 0x10000,
+		.size	= 0x10000,
+	},
+	{
+		.name	= "linux",
+		.offset	= 0x20000,
+		.size	= 0xE0000,
+	},
+	{
+		.name	= "rootfs",
+		.offset	= 0x100000,
+		.size	= 0x300000,
+	},
+};
+#endif
+
+static struct physmap_flash_data easy50601_flash_data = {
+#ifdef CONFIG_MTD_PARTITIONS
+	.nr_parts	= ARRAY_SIZE(easy50601_partitions),
+	.parts		= easy50601_partitions,
+#endif
+};
+
+static struct ltq_pci_data ltq_pci_data = {
+	.clock      = PCI_CLOCK_INT,
+	.req_mask   = 0xf,
+};
+
+static void __init
+easy50601_init(void)
+{
+	ltq_register_gpio();
+	ltq_register_nor(&easy50601_flash_data);
+	ltq_register_wdt();
+	ltq_register_pci(&ltq_pci_data);
+}
+
+MIPS_MACHINE(LTQ_MACH_EASY50601,
+			"EASY50601",
+			"EASY50601 Eval Board",
+			easy50601_init);
diff --git a/arch/mips/lantiq/xway/mach-easy50712.c b/arch/mips/lantiq/xway/mach-easy50712.c
new file mode 100644
index 0000000..816d1ce
--- /dev/null
+++ b/arch/mips/lantiq/xway/mach-easy50712.c
@@ -0,0 +1,70 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+
+#include <lantiq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition easy50712_partitions[] = {
+	{
+		.name	= "uboot",
+		.offset	= 0x0,
+		.size	= 0x10000,
+	},
+	{
+		.name	= "uboot_env",
+		.offset	= 0x10000,
+		.size	= 0x10000,
+	},
+	{
+		.name	= "linux",
+		.offset	= 0x20000,
+		.size	= 0xE0000,
+	},
+	{
+		.name	= "rootfs",
+		.offset	= 0x100000,
+		.size	= 0x300000,
+	},
+};
+#endif
+
+static struct physmap_flash_data easy50712_flash_data = {
+#ifdef CONFIG_MTD_PARTITIONS
+	.nr_parts	= ARRAY_SIZE(easy50712_partitions),
+	.parts		= easy50712_partitions,
+#endif
+};
+
+static struct ltq_pci_data ltq_pci_data = {
+	.clock      = PCI_CLOCK_INT,
+	.req_mask   = 0xf,
+};
+
+static void __init
+easy50712_init(void)
+{
+	ltq_register_gpio();
+	ltq_register_nor(&easy50712_flash_data);
+	ltq_register_wdt();
+	ltq_register_pci(&ltq_pci_data);
+}
+
+MIPS_MACHINE(LTQ_MACH_EASY50712,
+			"EASY50712",
+			"EASY50712 Eval Board",
+			easy50712_init);
-- 
1.7.2.3


From geert.uytterhoeven@gmail.com Wed Jan  5 21:25:59 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Wed, 05 Jan 2011 21:26:02 +0100 (CET)
Received: from mail-fx0-f49.google.com ([209.85.161.49]:33670 "EHLO
        mail-fx0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490979Ab1AEUZ7 (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Wed, 5 Jan 2011 21:25:59 +0100
Received: by fxm19 with SMTP id 19so14767651fxm.36
        for <multiple recipients>; Wed, 05 Jan 2011 12:25:54 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:mime-version:received:sender:received
         :in-reply-to:references:date:x-google-sender-auth:message-id:subject
         :from:to:cc:content-type:content-transfer-encoding;
        bh=rgCoHn9ottJC/apHZj75UFerThepRKdkm3GJLTmn60U=;
        b=LJKn+pUGpF2venGhjKITJBTlCkNwbbFqAhEzt2EGcFRNuyVcVg6khbWuI91Dmgp/9m
         KysY2d/67W4s3lFye2uvDIw8OGCGOUxZnjlpCEC2+su0a6zB3g56ZGRY6+iYGioAV7lA
         Gy0SeKJF2nHxkNEhXra1QtLqGo4fA6oE9RCcQ=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=mime-version:sender:in-reply-to:references:date
         :x-google-sender-auth:message-id:subject:from:to:cc:content-type
         :content-transfer-encoding;
        b=aphJcwVEMMkQXosih1Dvnye8tgNN+a6J7HJfEfLnH+b0yW/R7SI7Ws9wrwo8xoGsL1
         YlyS6mGwkNLo8AsafMM7y2vmpaDfOt3Aozw041KxFxxgkVhz3iUOripFPQJoze8kM2aF
         Kqubea1HGE9P+T0aISfmwnDKSKL85edupansE=
MIME-Version: 1.0
Received: by 10.223.85.204 with SMTP id p12mr3021114fal.146.1294259153781;
 Wed, 05 Jan 2011 12:25:53 -0800 (PST)
Received: by 10.223.75.194 with HTTP; Wed, 5 Jan 2011 12:25:53 -0800 (PST)
In-Reply-To: <1294257379-417-2-git-send-email-blogic@openwrt.org>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
        <1294257379-417-2-git-send-email-blogic@openwrt.org>
Date:   Wed, 5 Jan 2011 21:25:53 +0100
X-Google-Sender-Auth: bauGJMuPnfhn2as24-itggZC6Bk
Message-ID: <AANLkTinoPugsZ0V9d8HgmSvKnTFNW6HhXBkeCidOFOYn@mail.gmail.com>
Subject: Re: [PATCH 01/10] MIPS: lantiq: add initial support for Lantiq SoCs
From:   Geert Uytterhoeven <geert@linux-m68k.org>
To:     John Crispin <blogic@openwrt.org>
Cc:     Ralf Baechle <ralf@linux-mips.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        linux-mips@linux-mips.org
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
Return-Path: <geert.uytterhoeven@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: 28855
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: geert@linux-m68k.org
Precedence: bulk
X-list: linux-mips

T24gV2VkLCBKYW4gNSwgMjAxMSBhdCAyMDo1NiwgSm9obiBDcmlzcGluIDxibG9naWNAb3Blbndy
dC5vcmc+IHdyb3RlOgo+IC0tLSAvZGV2L251bGwKPiArKysgYi9hcmNoL21pcHMvbGFudGlxL3By
b20uYwo+IEBAIC0wLDAgKzEsODQgQEAKCj4gK3N0YXRpYyB2b2lkIF9faW5pdAo+ICtwcm9tX2lu
aXRfY21kbGluZSh2b2lkKQo+ICt7Cj4gKyDCoCDCoCDCoCBpbnQgYXJnYyA9IGZ3X2FyZzA7Cj4g
KyDCoCDCoCDCoCBjaGFyICoqYXJndiA9IChjaGFyICoqKSBLU0VHMUFERFIoZndfYXJnMSk7Cj4g
KyDCoCDCoCDCoCBpbnQgaTsKPiArIMKgIMKgIMKgIGFyY3NfY21kbGluZVswXSA9ICdcMCc7Cj4g
KyDCoCDCoCDCoCBpZiAoYXJnYykKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGZvciAoaSA9IDE7
IGkgPCBhcmdjOyBpKyspIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHN0
cmxjYXQoYXJjc19jbWRsaW5lLCAoY2hhciAqKUtTRUcxQUREUihhcmd2W2ldKSwKPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIENPTU1BTkRfTElORV9TSVpF
KTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChpICsgMSAhPSBhcmdj
KQo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3RybGNh
dChhcmNzX2NtZGxpbmUsICIgIiwgQ09NTUFORF9MSU5FX1NJWkUpOwo+ICsgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgfQo+ICsgwqAgwqAgwqAgaWYgKCEqYXJjc19jbWRsaW5lKQo+ICsgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgc3RyY3B5KCYoYXJjc19jbWRsaW5lWzBdKSwKPiArIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgICJjb25zb2xlPXR0eVMxLDExNTIwMCByb290ZnN0eXBlPXNxdWFz
aGZzLGpmZnMyIik7CiAgICAgICAgICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXl5e
Xl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXgogICAgICAgICAgICAgICAgICAgICAgICBDT05G
SUdfQ01ETElORT8/PwoKPiArfQoKR3J7b2V0amUsZWV0aW5nfXMsCgrCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCBHZWVydAoKLS0KR2VlcnQgVXl0dGVyaG9ldmVuIC0tIFRoZXJl
J3MgbG90cyBvZiBMaW51eCBiZXlvbmQgaWEzMiAtLSBnZWVydEBsaW51eC1tNjhrLm9yZwoKSW4g
cGVyc29uYWwgY29udmVyc2F0aW9ucyB3aXRoIHRlY2huaWNhbCBwZW9wbGUsIEkgY2FsbCBteXNl
bGYgYSBoYWNrZXIuIEJ1dAp3aGVuIEknbSB0YWxraW5nIHRvIGpvdXJuYWxpc3RzIEkganVzdCBz
YXkgInByb2dyYW1tZXIiIG9yIHNvbWV0aGluZyBsaWtlIHRoYXQuCsKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgwqAgwqDCoCAtLSBMaW51cyBUb3J2YWxkcwo=

From jamie@jamieiles.com Thu Jan  6 00:49:20 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 00:49:24 +0100 (CET)
Received: from mail-ww0-f43.google.com ([74.125.82.43]:62818 "EHLO
        mail-ww0-f43.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490998Ab1AEXtU (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Thu, 6 Jan 2011 00:49:20 +0100
Received: by wwi17 with SMTP id 17so15960004wwi.24
        for <multiple recipients>; Wed, 05 Jan 2011 15:49:14 -0800 (PST)
Received: by 10.216.141.75 with SMTP id f53mr10556824wej.16.1294271353514;
        Wed, 05 Jan 2011 15:49:13 -0800 (PST)
Received: from localhost (cpc1-chap8-2-0-cust102.aztw.cable.virginmedia.com [94.169.120.103])
        by mx.google.com with ESMTPS id n11sm11485128wej.43.2011.01.05.15.49.11
        (version=TLSv1/SSLv3 cipher=RC4-MD5);
        Wed, 05 Jan 2011 15:49:12 -0800 (PST)
Date:   Wed, 5 Jan 2011 23:49:10 +0000
From:   Jamie Iles <jamie@jamieiles.com>
To:     John Crispin <blogic@openwrt.org>
Cc:     Ralf Baechle <ralf@linux-mips.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        Wim Van Sebroeck <wim@iguana.be>, linux-mips@linux-mips.org,
        linux-watchdog@vger.kernel.org
Subject: Re: [PATCH 05/10] MIPS: lantiq: add watchdog support
Message-ID: <20110105234910.GD2112@gallagher>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
 <1294257379-417-6-git-send-email-blogic@openwrt.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <1294257379-417-6-git-send-email-blogic@openwrt.org>
User-Agent: Mutt/1.5.21 (2010-09-15)
Return-Path: <jamie@jamieiles.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: 28856
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: jamie@jamieiles.com
Precedence: bulk
X-list: linux-mips

Hi John,

A few nitpicks inline, but otherwise looks good to me.

Jamie

On Wed, Jan 05, 2011 at 08:56:14PM +0100, John Crispin wrote:
> This patch adds the driver for the watchdog found inside the Lantiq SoC family.
> 
> Signed-off-by: John Crispin <blogic@openwrt.org>
> Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
> Cc: Wim Van Sebroeck <wim@iguana.be>
> Cc: linux-mips@linux-mips.org
> Cc: linux-watchdog@vger.kernel.org
> ---
>  drivers/watchdog/Kconfig      |    6 +
>  drivers/watchdog/Makefile     |    1 +
>  drivers/watchdog/lantiq_wdt.c |  208 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 215 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/watchdog/lantiq_wdt.c
[...]
> diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
> new file mode 100644
> index 0000000..543bcf1
> --- /dev/null
> +++ b/drivers/watchdog/lantiq_wdt.c
> @@ -0,0 +1,208 @@
> +/*
> + *  This program is free software; you can redistribute it and/or modify it
> + *  under the terms of the GNU General Public License version 2 as published
> + *  by the Free Software Foundation.
> + *
> + *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
> + *  Based on EP93xx wdt driver
> + */
> +
> +#include <linux/module.h>
> +#include <linux/fs.h>
> +#include <linux/miscdevice.h>
> +#include <linux/miscdevice.h>

Duplicated include of linux/miscdevice.h

> +#include <linux/watchdog.h>
> +#include <linux/platform_device.h>
> +#include <linux/uaccess.h>
> +#include <linux/clk.h>
> +
> +#include <lantiq.h>
> +
> +#define LTQ_WDT_PW1			0x00BE0000
> +#define LTQ_WDT_PW2			0x00DC0000
> +
> +#define LTQ_BIU_WDT_CR		0x3F0
> +#define LTQ_BIU_WDT_SR		0x3F8

It's not obvious to me what these defines actually mean. A couple of 
short comments to describe what they are?
> +
> +#ifndef CONFIG_WATCHDOG_NOWAYOUT
> +static int wdt_ok_to_close;
> +#endif
> +
> +static int wdt_timeout = 30;
> +static __iomem void *wdt_membase;

I think this would normally be "static void __iomem" rather than "static 
__iomem void". Also these could do with the ltq_ prefix for namespacing.

> +static unsigned long io_region_clk;

Better to name this io_region_clk_rate?

> +
> +static int
> +ltq_wdt_enable(unsigned int timeout)
> +{
> +	ltq_w32(LTQ_WDT_PW1, wdt_membase + LTQ_BIU_WDT_CR);
> +	ltq_w32(LTQ_WDT_PW2 |
> +		(0x3 << 26) | /* PWL */
> +		(0x3 << 24) | /* CLKDIV */
> +		(0x1 << 31) | /* enable */
> +		((timeout * (io_region_clk / 0x40000)) + 0x1000), /* reload */
> +			wdt_membase + LTQ_BIU_WDT_CR);

Perhaps a comment describing the how this value is calculated? What does 
PWL mean and what are the significance of 0x40000 and 0x1000? Also, do 
you need to check that the timeout won't overflow the bits for the 
reload value?

> +	return 0;
> +}
> +
> +static void
> +ltq_wdt_disable(void)
> +{
> +#ifndef CONFIG_WATCHDOG_NOWAYOUT
> +	wdt_ok_to_close = 0;
> +#endif
> +	ltq_w32(LTQ_WDT_PW1, wdt_membase + LTQ_BIU_WDT_CR);
> +	ltq_w32(LTQ_WDT_PW2, wdt_membase + LTQ_BIU_WDT_CR);
> +}
> +
> +static ssize_t
> +ltq_wdt_write(struct file *file, const char __user *data,
> +		size_t len, loff_t *ppos)
> +{
> +	size_t i;
> +	if (!len)
> +		return 0;
> +#ifndef CONFIG_WATCHDOG_NOWAYOUT
> +	for (i = 0; i != len; i++) {
> +		char c;
> +		if (get_user(c, data + i))
> +			return -EFAULT;
> +		if (c == 'V')
> +			wdt_ok_to_close = 1;
> +	}
> +#endif
> +	ltq_wdt_enable(wdt_timeout);
> +	return len;
> +}
> +
> +static struct watchdog_info ident = {
> +	.options = WDIOF_MAGICCLOSE,

I think you can also add WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING.

> +	.identity = "ltq_wdt",
> +};
> +
> +static long
> +ltq_wdt_ioctl(struct file *file,
> +		unsigned int cmd, unsigned long arg)
> +{
> +	int ret = -ENOTTY;
> +	switch (cmd) {
> +	case WDIOC_GETSUPPORT:
> +		ret = copy_to_user((struct watchdog_info __user *)arg, &ident,
> +				sizeof(ident)) ? -EFAULT : 0;
> +		break;
> +
> +	case WDIOC_GETTIMEOUT:
> +		ret = put_user(wdt_timeout, (int __user *)arg);
> +		break;
> +
> +	case WDIOC_SETTIMEOUT:
> +		ret = get_user(wdt_timeout, (int __user *)arg);

Should you reset the WDT with the new timeout here rather than waiting 
for the next keepalive?

> +		break;
> +
> +	case WDIOC_KEEPALIVE:
> +		ltq_wdt_enable(wdt_timeout);
> +		ret = 0;
> +		break;
> +	}
> +	return ret;
> +}
> +
> +static int
> +ltq_wdt_open(struct inode *inode, struct file *file)
> +{
> +	ltq_wdt_enable(wdt_timeout);
> +	return nonseekable_open(inode, file);
> +}
> +
> +static int
> +ltq_wdt_release(struct inode *inode, struct file *file)
> +{
> +#ifndef CONFIG_WATCHDOG_NOWAYOUT
> +	if (wdt_ok_to_close)
> +		ltq_wdt_disable();
> +	else
> +#endif
> +		printk(KERN_ERR "ltq_wdt: watchdog closed without warning,"
> +			" rebooting system\n");
> +	return 0;
> +}
> +
> +static const struct file_operations ltq_wdt_fops = {
> +	.owner			= THIS_MODULE,
> +	.write			= ltq_wdt_write,
> +	.unlocked_ioctl	= ltq_wdt_ioctl,

Align the .unlocked_ioctl assignment with the others?

> +	.open			= ltq_wdt_open,
> +	.release		= ltq_wdt_release,

Add ".llseek = no_llseek"?

> +};
> +
> +static struct miscdevice ltq_wdt_miscdev = {
> +	.minor		= WATCHDOG_MINOR,
> +	.name		= "watchdog",
> +	.fops		= &ltq_wdt_fops,
> +};
> +
> +static int
> +ltq_wdt_probe(struct platform_device *pdev)
> +{
> +	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	struct clk *clk;
> +	int ret = 0;
> +	if (!res)
> +		return -ENOENT;
> +	res = request_mem_region(res->start, resource_size(res),
> +		dev_name(&pdev->dev));
> +	if (!res)
> +		return -EBUSY;
> +	wdt_membase = ioremap_nocache(res->start, resource_size(res));
> +	if (!wdt_membase) {
> +		ret = -ENOMEM;
> +		goto err_release_mem_region;
> +	}

You can use devm_request_mem_region() and devm_ioremap_nocache() to 
simplify the error handling and removal.

> +	clk = clk_get(&pdev->dev, "io");

Do you need a clk_enable() here too? Or a comment explaining it's always 
enabled (if it is)?

> +	io_region_clk = clk_get_rate(clk);;
> +	ret = misc_register(&ltq_wdt_miscdev);
> +	if (!ret)
> +		return 0;
> +
> +	iounmap(wdt_membase);
> +err_release_mem_region:
> +	release_mem_region(res->start, resource_size(res));
> +	return ret;
> +}
> +
> +static int
> +ltq_wdt_remove(struct platform_device *dev)
> +{
> +	ltq_wdt_disable();
> +	misc_deregister(&ltq_wdt_miscdev);

I think you need a clk_put() here too to balance the clk_get() in the 
probe method so you'll need to keep a reference to the clk.

> +	return 0;
> +}
> +
> +static struct platform_driver ltq_wdt_driver = {
> +	.probe = ltq_wdt_probe,
> +	.remove = ltq_wdt_remove,
> +	.driver = {
> +		.name = "ltq_wdt",
> +		.owner = THIS_MODULE,
> +	},
> +};
> +
> +static int __init
> +init_ltq_wdt(void)
> +{
> +	return platform_driver_register(&ltq_wdt_driver);
> +}
> +
> +static void __exit
> +exit_ltq_wdt(void)
> +{
> +	platform_driver_unregister(&ltq_wdt_driver);
> +}
> +
> +module_init(init_ltq_wdt);
> +module_exit(exit_ltq_wdt);
> +
> +MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
> +MODULE_DESCRIPTION("Lantiq Watchdog");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
> -- 
> 1.7.2.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

From greg@kroah.com Thu Jan  6 01:30:30 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 01:30:32 +0100 (CET)
Received: from kroah.org ([198.145.64.141]:54461 "EHLO coco.kroah.org"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490979Ab1AFAa3 (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 01:30:29 +0100
Received: from localhost (c-71-227-141-191.hsd1.wa.comcast.net [71.227.141.191])
        (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
        (No client certificate requested)
        by coco.kroah.org (Postfix) with ESMTPSA id C30AE4898F;
        Wed,  5 Jan 2011 16:30:24 -0800 (PST)
X-Mailbox-Line: From gregkh@clark.site Wed Jan  5 16:23:05 2011
Message-Id: <20110106002304.923508592@clark.site>
User-Agent: quilt/0.48-11.2
Date:   Wed, 05 Jan 2011 16:23:05 -0800
From:   Greg KH <gregkh@suse.de>
To:     linux-kernel@vger.kernel.org, stable@kernel.org
Cc:     stable-review@kernel.org, torvalds@linux-foundation.org,
        akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
        Lars-Peter Clausen <lars@metafoo.de>,
        linux-mips@linux-mips.org, Ralf Baechle <ralf@linux-mips.org>
Subject: [086/152] MIPS: jz4740: qi_lb60: Fix gpio for the 6th row of the keyboard matrix
In-Reply-To: <20110106002500.GA3172@kroah.com>
Return-Path: <greg@kroah.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: 28857
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: gregkh@suse.de
Precedence: bulk
X-list: linux-mips

2.6.36-stable review patch.  If anyone has any objections, please let us know.

------------------

From: Lars-Peter Clausen <lars@metafoo.de>

commit fe749aab1d21cbb4d87527a7df8799583c233496 upstream.

This patch fixes the gpio number for the 6th row of the keyboard matrix.

(And fixes a typo in my name...)

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Cc: linux-mips@linux-mips.org
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 arch/mips/jz4740/board-qi_lb60.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 2009 Qi Hardware inc.,
  * Author: Xiangfu Liu <xiangfu@qi-hardware.com>
- * Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de>
+ * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 or later
@@ -235,7 +235,7 @@ static const unsigned int qi_lb60_keypad
 	QI_LB60_GPIO_KEYIN(3),
 	QI_LB60_GPIO_KEYIN(4),
 	QI_LB60_GPIO_KEYIN(5),
-	QI_LB60_GPIO_KEYIN(7),
+	QI_LB60_GPIO_KEYIN(6),
 	QI_LB60_GPIO_KEYIN8,
 };
 



From cernekee@gmail.com Thu Jan  6 08:39:07 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 08:39:14 +0100 (CET)
Received: from [69.28.251.93] ([69.28.251.93]:37631 "EHLO b32.net"
        rhost-flags-FAIL-FAIL-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490984Ab1AFHjH (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 08:39:07 +0100
Received: (qmail 3079 invoked from network); 6 Jan 2011 07:39:02 -0000
Received: from unknown (HELO vps-1001064-677.cp.jvds.com) (127.0.0.1)
  by 127.0.0.1 with (DHE-RSA-AES128-SHA encrypted) SMTP; 6 Jan 2011 07:39:02 -0000
Received: by vps-1001064-677.cp.jvds.com (sSMTP sendmail emulation); Wed, 05 Jan 2011 23:39:01 -0800
From:   Kevin Cernekee <cernekee@gmail.com>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     <macro@linux-mips.org>, <skuribay@pobox.com>, <raiko@niisi.msk.ru>,
        <linux-mips@linux-mips.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH RESEND 1/6] MIPS: sync after cacheflush
Date:   Wed, 05 Jan 2011 23:31:25 -0800
Message-Id: <8eec0c63f92528c501c0e6a0c8396359@localhost>
User-Agent: vim 7.2
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Return-Path: <cernekee@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: 28858
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: cernekee@gmail.com
Precedence: bulk
X-list: linux-mips

On processors with deep write buffers, it is likely that many cycles
will pass between a CACHE instruction and the time the data actually
gets written out to DRAM.  Add a SYNC instruction to ensure that the
buffers get emptied before the flush functions return.

Actual problem seen in the wild:

1) dma_alloc_coherent() allocates cached memory

2) memset() is called to clear the new pages

3) dma_cache_wback_inv() is called to flush the zero data out to memory

4) dma_alloc_coherent() returns an uncached (kseg1) pointer to the
freshly allocated pages

5) Caller writes data through the kseg1 pointer

6) Buffered writeback data finally gets flushed out to DRAM

7) Part of caller's data is inexplicably zeroed out

This patch adds SYNC between steps 3 and 4, which fixed the problem.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
 arch/mips/mm/c-r4k.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index b4923a7..dc5d9c4 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -604,6 +604,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
 			r4k_blast_scache();
 		else
 			blast_scache_range(addr, addr + size);
+		__sync();
 		return;
 	}
 
@@ -620,6 +621,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
 	}
 
 	bc_wback_inv(addr, size);
+	__sync();
 }
 
 static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
@@ -647,6 +649,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
 				 (addr + size - 1) & almask);
 			blast_inv_scache_range(addr, addr + size);
 		}
+		__sync();
 		return;
 	}
 
@@ -663,6 +666,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
 	}
 
 	bc_inv(addr, size);
+	__sync();
 }
 #endif /* CONFIG_DMA_NONCOHERENT */
 
-- 
1.7.0.4


From cernekee@gmail.com Thu Jan  6 08:39:33 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 08:39:39 +0100 (CET)
Received: from [69.28.251.93] ([69.28.251.93]:37643 "EHLO b32.net"
        rhost-flags-FAIL-FAIL-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490989Ab1AFHjI (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 08:39:08 +0100
Received: (qmail 3202 invoked from network); 6 Jan 2011 07:39:05 -0000
Received: from unknown (HELO vps-1001064-677.cp.jvds.com) (127.0.0.1)
  by 127.0.0.1 with (DHE-RSA-AES128-SHA encrypted) SMTP; 6 Jan 2011 07:39:05 -0000
Received: by vps-1001064-677.cp.jvds.com (sSMTP sendmail emulation); Wed, 05 Jan 2011 23:39:05 -0800
From:   Kevin Cernekee <cernekee@gmail.com>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     <linux-mips@linux-mips.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH RESEND 2/6] MIPS: pfn_valid() is broken on low memory HIGHMEM systems
Date:   Wed, 05 Jan 2011 23:31:26 -0800
Message-Id: <b2191149ada0fd929b3818c51298ae8d@localhost>
In-Reply-To: <8eec0c63f92528c501c0e6a0c8396359@localhost>
References: <8eec0c63f92528c501c0e6a0c8396359@localhost>
User-Agent: vim 7.2
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Return-Path: <cernekee@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: 28859
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: cernekee@gmail.com
Precedence: bulk
X-list: linux-mips

pfn_valid() compares the PFN to max_mapnr:

        __pfn >= min_low_pfn && __pfn < max_mapnr;

On HIGHMEM kernels, highend_pfn is used to set the value of max_mapnr.
Unfortunately, highend_pfn is left at zero if the system does not
actually have enough RAM to reach into the HIGHMEM range.  This causes
pfn_valid() to always return false, and when debug checks are enabled
the kernel will fail catastrophically:

Memory: 22432k/32768k available (2249k kernel code, 10336k reserved, 653k data, 1352k init, 0k highmem)
NR_IRQS:128
kfree_debugcheck: out of range ptr 81c02900h.
Kernel bug detected[#1]:
Cpu 0
$ 0   : 00000000 10008400 00000034 00000000
$ 4   : 8003e160 802a0000 8003e160 00000000
$ 8   : 00000000 0000003e 00000747 00000747
...

On such a configuration, max_low_pfn should be used to set max_mapnr.

This was seen on 2.6.34.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
 arch/mips/mm/init.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 2efcbd2..18183a4 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -370,7 +370,7 @@ void __init mem_init(void)
 #ifdef CONFIG_DISCONTIGMEM
 #error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
 #endif
-	max_mapnr = highend_pfn;
+	max_mapnr = highend_pfn ? : max_low_pfn;
 #else
 	max_mapnr = max_low_pfn;
 #endif
-- 
1.7.0.4


From cernekee@gmail.com Thu Jan  6 08:39:57 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 08:40:08 +0100 (CET)
Received: from [69.28.251.93] ([69.28.251.93]:37676 "EHLO b32.net"
        rhost-flags-FAIL-FAIL-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490990Ab1AFHjO (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 08:39:14 +0100
Received: (qmail 3541 invoked from network); 6 Jan 2011 07:39:11 -0000
Received: from unknown (HELO vps-1001064-677.cp.jvds.com) (127.0.0.1)
  by 127.0.0.1 with (DHE-RSA-AES128-SHA encrypted) SMTP; 6 Jan 2011 07:39:11 -0000
Received: by vps-1001064-677.cp.jvds.com (sSMTP sendmail emulation); Wed, 05 Jan 2011 23:39:11 -0800
From:   Kevin Cernekee <cernekee@gmail.com>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     <anemo@mba.ocn.ne.jp>, <linux-mips@linux-mips.org>,
        <linux-kernel@vger.kernel.org>
Subject: [PATCH v2 RESEND 3/6] MIPS: Move FIXADDR_TOP into spaces.h
Date:   Wed, 05 Jan 2011 23:31:27 -0800
Message-Id: <e89d5c8e0f776a2179da18ee6a92f280@localhost>
In-Reply-To: <8eec0c63f92528c501c0e6a0c8396359@localhost>
References: <8eec0c63f92528c501c0e6a0c8396359@localhost>
User-Agent: vim 7.2
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Return-Path: <cernekee@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: 28860
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: cernekee@gmail.com
Precedence: bulk
X-list: linux-mips

Memory maps and addressing quirks are normally defined in <spaces.h>.
There are already three targets that need to override FIXADDR_TOP, and
others exist.  This will be a cleaner approach than adding lots of
ifdefs in fixmap.h .

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
 arch/mips/include/asm/fixmap.h              |   10 +---------
 arch/mips/include/asm/mach-bcm63xx/spaces.h |   17 +++++++++++++++++
 arch/mips/include/asm/mach-generic/spaces.h |    4 ++++
 arch/mips/include/asm/mach-tx39xx/spaces.h  |   17 +++++++++++++++++
 arch/mips/include/asm/mach-tx49xx/spaces.h  |   17 +++++++++++++++++
 5 files changed, 56 insertions(+), 9 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-bcm63xx/spaces.h
 create mode 100644 arch/mips/include/asm/mach-tx39xx/spaces.h
 create mode 100644 arch/mips/include/asm/mach-tx49xx/spaces.h

diff --git a/arch/mips/include/asm/fixmap.h b/arch/mips/include/asm/fixmap.h
index 0b89b83..98bcc98 100644
--- a/arch/mips/include/asm/fixmap.h
+++ b/arch/mips/include/asm/fixmap.h
@@ -14,6 +14,7 @@
 #define _ASM_FIXMAP_H
 
 #include <asm/page.h>
+#include <spaces.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
 #include <asm/kmap_types.h>
@@ -67,15 +68,6 @@ enum fixed_addresses {
  * the start of the fixmap, and leave one page empty
  * at the top of mem..
  */
-#ifdef CONFIG_BCM63XX
-#define FIXADDR_TOP     ((unsigned long)(long)(int)0xff000000)
-#else
-#if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX)
-#define FIXADDR_TOP	((unsigned long)(long)(int)(0xff000000 - 0x20000))
-#else
-#define FIXADDR_TOP	((unsigned long)(long)(int)0xfffe0000)
-#endif
-#endif
 #define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
 
diff --git a/arch/mips/include/asm/mach-bcm63xx/spaces.h b/arch/mips/include/asm/mach-bcm63xx/spaces.h
new file mode 100644
index 0000000..61e750f
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/spaces.h
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+#ifndef _ASM_BCM63XX_SPACES_H
+#define _ASM_BCM63XX_SPACES_H
+
+#define FIXADDR_TOP		((unsigned long)(long)(int)0xff000000)
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* __ASM_BCM63XX_SPACES_H */
diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h
index c9fa4b1..d7a9efd 100644
--- a/arch/mips/include/asm/mach-generic/spaces.h
+++ b/arch/mips/include/asm/mach-generic/spaces.h
@@ -82,4 +82,8 @@
 #define PAGE_OFFSET		(CAC_BASE + PHYS_OFFSET)
 #endif
 
+#ifndef FIXADDR_TOP
+#define FIXADDR_TOP		((unsigned long)(long)(int)0xfffe0000)
+#endif
+
 #endif /* __ASM_MACH_GENERIC_SPACES_H */
diff --git a/arch/mips/include/asm/mach-tx39xx/spaces.h b/arch/mips/include/asm/mach-tx39xx/spaces.h
new file mode 100644
index 0000000..151fe7a
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx39xx/spaces.h
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+#ifndef _ASM_TX39XX_SPACES_H
+#define _ASM_TX39XX_SPACES_H
+
+#define FIXADDR_TOP		((unsigned long)(long)(int)0xfefe0000)
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* __ASM_TX39XX_SPACES_H */
diff --git a/arch/mips/include/asm/mach-tx49xx/spaces.h b/arch/mips/include/asm/mach-tx49xx/spaces.h
new file mode 100644
index 0000000..0cb10a6
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx49xx/spaces.h
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+#ifndef _ASM_TX49XX_SPACES_H
+#define _ASM_TX49XX_SPACES_H
+
+#define FIXADDR_TOP		((unsigned long)(long)(int)0xfefe0000)
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* __ASM_TX49XX_SPACES_H */
-- 
1.7.0.4


From cernekee@gmail.com Thu Jan  6 08:40:27 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 08:40:33 +0100 (CET)
Received: from [69.28.251.93] ([69.28.251.93]:37705 "EHLO b32.net"
        rhost-flags-FAIL-FAIL-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490996Ab1AFHjT (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 08:39:19 +0100
Received: (qmail 3644 invoked from network); 6 Jan 2011 07:39:15 -0000
Received: from unknown (HELO vps-1001064-677.cp.jvds.com) (127.0.0.1)
  by 127.0.0.1 with (DHE-RSA-AES128-SHA encrypted) SMTP; 6 Jan 2011 07:39:15 -0000
Received: by vps-1001064-677.cp.jvds.com (sSMTP sendmail emulation); Wed, 05 Jan 2011 23:39:15 -0800
From:   Kevin Cernekee <cernekee@gmail.com>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     <dediao@cisco.com>, <ddaney@caviumnetworks.com>,
        <dvomlehn@cisco.com>, <sshtylyov@mvista.com>,
        <linux-mips@linux-mips.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH v4 RESEND 4/6] MIPS: HIGHMEM DMA on noncoherent MIPS32 processors
Date:   Wed, 05 Jan 2011 23:31:28 -0800
Message-Id: <a8638c0dbe654801b2297b5d801b55ed@localhost>
In-Reply-To: <8eec0c63f92528c501c0e6a0c8396359@localhost>
References: <8eec0c63f92528c501c0e6a0c8396359@localhost>
User-Agent: vim 7.2
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Return-Path: <cernekee@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: 28861
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: cernekee@gmail.com
Precedence: bulk
X-list: linux-mips

The MIPS DMA coherency functions do not work properly (i.e. kernel oops)
when HIGHMEM pages are passed in as arguments.  Use kmap_atomic() to
temporarily map high pages for cache maintenance operations.

Tested on a 2.6.37-rc7 1GB HIGHMEM SMP no-alias system.

Signed-off-by: Dezhong Diao <dediao@cisco.com>
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
 arch/mips/mm/dma-default.c |  114 ++++++++++++++++++++++++++------------------
 1 files changed, 68 insertions(+), 46 deletions(-)

diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 4fc1a0f..1e20758 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -15,18 +15,18 @@
 #include <linux/scatterlist.h>
 #include <linux/string.h>
 #include <linux/gfp.h>
+#include <linux/highmem.h>
 
 #include <asm/cache.h>
 #include <asm/io.h>
 
 #include <dma-coherence.h>
 
-static inline unsigned long dma_addr_to_virt(struct device *dev,
+static inline struct page *dma_addr_to_page(struct device *dev,
 	dma_addr_t dma_addr)
 {
-	unsigned long addr = plat_dma_addr_to_phys(dev, dma_addr);
-
-	return (unsigned long)phys_to_virt(addr);
+	return pfn_to_page(
+		plat_dma_addr_to_phys(dev, dma_addr) >> PAGE_SHIFT);
 }
 
 /*
@@ -148,20 +148,20 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
 	free_pages(addr, get_order(size));
 }
 
-static inline void __dma_sync(unsigned long addr, size_t size,
+static inline void __dma_sync_virtual(void *addr, size_t size,
 	enum dma_data_direction direction)
 {
 	switch (direction) {
 	case DMA_TO_DEVICE:
-		dma_cache_wback(addr, size);
+		dma_cache_wback((unsigned long)addr, size);
 		break;
 
 	case DMA_FROM_DEVICE:
-		dma_cache_inv(addr, size);
+		dma_cache_inv((unsigned long)addr, size);
 		break;
 
 	case DMA_BIDIRECTIONAL:
-		dma_cache_wback_inv(addr, size);
+		dma_cache_wback_inv((unsigned long)addr, size);
 		break;
 
 	default:
@@ -169,12 +169,49 @@ static inline void __dma_sync(unsigned long addr, size_t size,
 	}
 }
 
+/*
+ * A single sg entry may refer to multiple physically contiguous
+ * pages. But we still need to process highmem pages individually.
+ * If highmem is not configured then the bulk of this loop gets
+ * optimized out.
+ */
+static inline void __dma_sync(struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	size_t left = size;
+
+	do {
+		size_t len = left;
+
+		if (PageHighMem(page)) {
+			void *addr;
+
+			if (offset + len > PAGE_SIZE) {
+				if (offset >= PAGE_SIZE) {
+					page += offset >> PAGE_SHIFT;
+					offset &= ~PAGE_MASK;
+				}
+				len = PAGE_SIZE - offset;
+			}
+
+			addr = kmap_atomic(page);
+			__dma_sync_virtual(addr + offset, len, direction);
+			kunmap_atomic(addr);
+		} else
+			__dma_sync_virtual(page_address(page) + offset,
+					   size, direction);
+		offset = 0;
+		page++;
+		left -= len;
+	} while (left);
+}
+
 static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
 	size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
 {
 	if (cpu_is_noncoherent_r10000(dev))
-		__dma_sync(dma_addr_to_virt(dev, dma_addr), size,
-		           direction);
+		__dma_sync(dma_addr_to_page(dev, dma_addr),
+			   dma_addr & ~PAGE_MASK, size, direction);
 
 	plat_unmap_dma_mem(dev, dma_addr, size, direction);
 }
@@ -185,13 +222,11 @@ static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg,
 	int i;
 
 	for (i = 0; i < nents; i++, sg++) {
-		unsigned long addr;
-
-		addr = (unsigned long) sg_virt(sg);
-		if (!plat_device_is_coherent(dev) && addr)
-			__dma_sync(addr, sg->length, direction);
-		sg->dma_address = plat_map_dma_mem(dev,
-				                   (void *)addr, sg->length);
+		if (!plat_device_is_coherent(dev))
+			__dma_sync(sg_page(sg), sg->offset, sg->length,
+				   direction);
+		sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) +
+				  sg->offset;
 	}
 
 	return nents;
@@ -201,30 +236,23 @@ static dma_addr_t mips_dma_map_page(struct device *dev, struct page *page,
 	unsigned long offset, size_t size, enum dma_data_direction direction,
 	struct dma_attrs *attrs)
 {
-	unsigned long addr;
-
-	addr = (unsigned long) page_address(page) + offset;
-
 	if (!plat_device_is_coherent(dev))
-		__dma_sync(addr, size, direction);
+		__dma_sync(page, offset, size, direction);
 
-	return plat_map_dma_mem(dev, (void *)addr, size);
+	return plat_map_dma_mem_page(dev, page) + offset;
 }
 
 static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 	int nhwentries, enum dma_data_direction direction,
 	struct dma_attrs *attrs)
 {
-	unsigned long addr;
 	int i;
 
 	for (i = 0; i < nhwentries; i++, sg++) {
 		if (!plat_device_is_coherent(dev) &&
-		    direction != DMA_TO_DEVICE) {
-			addr = (unsigned long) sg_virt(sg);
-			if (addr)
-				__dma_sync(addr, sg->length, direction);
-		}
+		    direction != DMA_TO_DEVICE)
+			__dma_sync(sg_page(sg), sg->offset, sg->length,
+				   direction);
 		plat_unmap_dma_mem(dev, sg->dma_address, sg->length, direction);
 	}
 }
@@ -232,24 +260,18 @@ static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 static void mips_dma_sync_single_for_cpu(struct device *dev,
 	dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
 {
-	if (cpu_is_noncoherent_r10000(dev)) {
-		unsigned long addr;
-
-		addr = dma_addr_to_virt(dev, dma_handle);
-		__dma_sync(addr, size, direction);
-	}
+	if (cpu_is_noncoherent_r10000(dev))
+		__dma_sync(dma_addr_to_page(dev, dma_handle),
+			   dma_handle & ~PAGE_MASK, size, direction);
 }
 
 static void mips_dma_sync_single_for_device(struct device *dev,
 	dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
 {
 	plat_extra_sync_for_device(dev);
-	if (!plat_device_is_coherent(dev)) {
-		unsigned long addr;
-
-		addr = dma_addr_to_virt(dev, dma_handle);
-		__dma_sync(addr, size, direction);
-	}
+	if (!plat_device_is_coherent(dev))
+		__dma_sync(dma_addr_to_page(dev, dma_handle),
+			   dma_handle & ~PAGE_MASK, size, direction);
 }
 
 static void mips_dma_sync_sg_for_cpu(struct device *dev,
@@ -260,8 +282,8 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev,
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (cpu_is_noncoherent_r10000(dev))
-			__dma_sync((unsigned long)page_address(sg_page(sg)),
-			           sg->length, direction);
+			__dma_sync(sg_page(sg), sg->offset, sg->length,
+				   direction);
 	}
 }
 
@@ -273,8 +295,8 @@ static void mips_dma_sync_sg_for_device(struct device *dev,
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (!plat_device_is_coherent(dev))
-			__dma_sync((unsigned long)page_address(sg_page(sg)),
-			           sg->length, direction);
+			__dma_sync(sg_page(sg), sg->offset, sg->length,
+				   direction);
 	}
 }
 
@@ -295,7 +317,7 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 
 	plat_extra_sync_for_device(dev);
 	if (!plat_device_is_coherent(dev))
-		__dma_sync((unsigned long)vaddr, size, direction);
+		__dma_sync_virtual(vaddr, size, direction);
 }
 
 static struct dma_map_ops mips_default_dma_map_ops = {
-- 
1.7.0.4


From cernekee@gmail.com Thu Jan  6 08:40:52 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 08:40:56 +0100 (CET)
Received: from [69.28.251.93] ([69.28.251.93]:37732 "EHLO b32.net"
        rhost-flags-FAIL-FAIL-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490997Ab1AFHjW (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 08:39:22 +0100
Received: (qmail 3801 invoked from network); 6 Jan 2011 07:39:19 -0000
Received: from unknown (HELO vps-1001064-677.cp.jvds.com) (127.0.0.1)
  by 127.0.0.1 with (DHE-RSA-AES128-SHA encrypted) SMTP; 6 Jan 2011 07:39:19 -0000
Received: by vps-1001064-677.cp.jvds.com (sSMTP sendmail emulation); Wed, 05 Jan 2011 23:39:19 -0800
From:   Kevin Cernekee <cernekee@gmail.com>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     <linux-mips@linux-mips.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH RESEND 5/6] MIPS: Install handlers for BMIPS software IRQs
Date:   Wed, 05 Jan 2011 23:31:29 -0800
Message-Id: <15216cd202530798c9d4c5beeb45c6ba@localhost>
In-Reply-To: <8eec0c63f92528c501c0e6a0c8396359@localhost>
References: <8eec0c63f92528c501c0e6a0c8396359@localhost>
User-Agent: vim 7.2
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Return-Path: <cernekee@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: 28862
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: cernekee@gmail.com
Precedence: bulk
X-list: linux-mips

BMIPS4350/4380/5000 CMT/SMT all use SW INT0/INT1 for inter-thread
signaling.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
 arch/mips/kernel/irq_cpu.c |   14 ++++++--------
 1 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 0262abe..70d4736 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -107,14 +107,12 @@ void __init mips_cpu_irq_init(void)
 	clear_c0_status(ST0_IM);
 	clear_c0_cause(CAUSEF_IP);
 
-	/*
-	 * Only MT is using the software interrupts currently, so we just
-	 * leave them uninitialized for other processors.
-	 */
-	if (cpu_has_mipsmt)
-		for (i = irq_base; i < irq_base + 2; i++)
-			set_irq_chip_and_handler(i, &mips_mt_cpu_irq_controller,
-						 handle_percpu_irq);
+	/* Software interrupts are used for MT/CMT IPI */
+	for (i = irq_base; i < irq_base + 2; i++)
+		set_irq_chip_and_handler(i, cpu_has_mipsmt ?
+					 &mips_mt_cpu_irq_controller :
+					 &mips_cpu_irq_controller,
+					 handle_percpu_irq);
 
 	for (i = irq_base + 2; i < irq_base + 8; i++)
 		set_irq_chip_and_handler(i, &mips_cpu_irq_controller,
-- 
1.7.0.4


From cernekee@gmail.com Thu Jan  6 08:41:14 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 08:41:19 +0100 (CET)
Received: from [69.28.251.93] ([69.28.251.93]:37753 "EHLO b32.net"
        rhost-flags-FAIL-FAIL-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490987Ab1AFHjZ (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 08:39:25 +0100
Received: (qmail 3900 invoked from network); 6 Jan 2011 07:39:22 -0000
Received: from unknown (HELO vps-1001064-677.cp.jvds.com) (127.0.0.1)
  by 127.0.0.1 with (DHE-RSA-AES128-SHA encrypted) SMTP; 6 Jan 2011 07:39:22 -0000
Received: by vps-1001064-677.cp.jvds.com (sSMTP sendmail emulation); Wed, 05 Jan 2011 23:39:22 -0800
From:   Kevin Cernekee <cernekee@gmail.com>
To:     Ralf Baechle <ralf@linux-mips.org>
Cc:     <linux-mips@linux-mips.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH 6/6] MIPS: Limit fixrange_init() to the FIXMAP region
Date:   Wed, 05 Jan 2011 23:31:30 -0800
Message-Id: <e19154ae0e4900405b6e8586a31fa878@localhost>
In-Reply-To: <8eec0c63f92528c501c0e6a0c8396359@localhost>
References: <8eec0c63f92528c501c0e6a0c8396359@localhost>
User-Agent: vim 7.2
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Return-Path: <cernekee@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: 28863
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: cernekee@gmail.com
Precedence: bulk
X-list: linux-mips

fixrange_init() allocates page tables for all addresses higher than
FIXADDR_TOP.  On processors that override the default FIXADDR_TOP
address of 0xfffe_0000, this can consume up to 4 pages (1 page per 4MB)
for pgd's that are never used.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
 arch/mips/mm/init.c       |    6 +++---
 arch/mips/mm/pgtable-32.c |    2 +-
 arch/mips/mm/pgtable-64.c |    2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 2efcbd2..deb8b3a 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -279,11 +279,11 @@ void __init fixrange_init(unsigned long start, unsigned long end,
 	k = __pmd_offset(vaddr);
 	pgd = pgd_base + i;
 
-	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+	for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
 		pud = (pud_t *)pgd;
-		for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+		for ( ; (j < PTRS_PER_PUD) && (vaddr < end); pud++, j++) {
 			pmd = (pmd_t *)pud;
-			for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
+			for (; (k < PTRS_PER_PMD) && (vaddr < end); pmd++, k++) {
 				if (pmd_none(*pmd)) {
 					pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
 					set_pmd(pmd, __pmd((unsigned long)pte));
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
index 575e401..adc6911 100644
--- a/arch/mips/mm/pgtable-32.c
+++ b/arch/mips/mm/pgtable-32.c
@@ -52,7 +52,7 @@ void __init pagetable_init(void)
 	 * Fixed mappings:
 	 */
 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-	fixrange_init(vaddr, 0, pgd_base);
+	fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base);
 
 #ifdef CONFIG_HIGHMEM
 	/*
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
index 78eaa4f..cda4e30 100644
--- a/arch/mips/mm/pgtable-64.c
+++ b/arch/mips/mm/pgtable-64.c
@@ -76,5 +76,5 @@ void __init pagetable_init(void)
 	 * Fixed mappings:
 	 */
 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-	fixrange_init(vaddr, 0, pgd_base);
+	fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base);
 }
-- 
1.7.0.4


From blogic@openwrt.org Thu Jan  6 10:50:08 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 10:50:11 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:59035 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490980Ab1AFJuI (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 10:50:08 +0100
Message-ID: <4D25908E.9070509@openwrt.org>
Date:   Thu, 06 Jan 2011 10:51:10 +0100
From:   John Crispin <blogic@openwrt.org>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.12) Gecko/20100913 Icedove/3.0.7
MIME-Version: 1.0
To:     Jamie Iles <jamie@jamieiles.com>
CC:     Ralf Baechle <ralf@linux-mips.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        Wim Van Sebroeck <wim@iguana.be>, linux-mips@linux-mips.org,
        linux-watchdog@vger.kernel.org
Subject: Re: [PATCH 05/10] MIPS: lantiq: add watchdog support
References: <1294257379-417-1-git-send-email-blogic@openwrt.org> <1294257379-417-6-git-send-email-blogic@openwrt.org> <20110105234910.GD2112@gallagher>
In-Reply-To: <20110105234910.GD2112@gallagher>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Return-Path: <blogic@openwrt.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: 28864
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

On 06/01/11 00:49, Jamie Iles wrote:
> I think you need a clk_put() here too to balance the clk_get() in the 
> probe method so you'll need to keep a reference to the clk.
>
>   

Hi Jamie,

i will fold your suggestions into the series.

the clk.c/h implementation on the lantiq target is very simple. it only
allows to read the static rates of the 3 clocks. clk_put is implemented
as follows

void
clk_put(struct clk *clk)
{
    /* not used */
}
EXPORT_SYMBOL(clk_put);

so in theory you are right and we should call that function, however as
it is only a stub and the driver is only used by the lantiq target i
think it is save to leave out the clk_put(); call. we could however put
a commet in the code to make this clear (same as with the clk_enable()
not being needed as the clocks are always running)

Thanks,
John


From blogic@openwrt.org Thu Jan  6 11:05:20 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 11:05:23 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:35323 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490980Ab1AFKFU (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 11:05:20 +0100
Message-ID: <4D25941E.80702@openwrt.org>
Date:   Thu, 06 Jan 2011 11:06:22 +0100
From:   John Crispin <blogic@openwrt.org>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.12) Gecko/20100913 Icedove/3.0.7
MIME-Version: 1.0
To:     David Woodhouse <dwmw2@infradead.org>
CC:     Ralf Baechle <ralf@linux-mips.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        linux-mips@linux-mips.org, linux-mtd@lists.infradead.org
Subject: Re: [PATCH 07/10] MIPS: lantiq: add NOR flash CFI address swizzle
References: <1294257379-417-1-git-send-email-blogic@openwrt.org> <1294257379-417-8-git-send-email-blogic@openwrt.org>
In-Reply-To: <1294257379-417-8-git-send-email-blogic@openwrt.org>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Return-Path: <blogic@openwrt.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: 28865
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

On 05/01/11 20:56, John Crispin wrote:
>  
>  	adr += chip->start;
> +#ifdef CONFIG_MTD_CFI_CMD_SWIZZLE
> +	adr ^= 2;
> +#endif
>  
>  	mutex_lock(&chip->mutex);
>  	ret = get_chip(map, chip, adr, FL_WRITING);
>   

Hi,

What this patch essentially does is to make sure to pass a addr with the
^=2 hack already applied, so that the complex map ends up with an un
swizzled addr as it applies the hack internally again.

I think it would be cleanest to extend the read/write callbacks of
struct map_info; with a flag indicating whether we are doing a CMD or
DATA action. as the 2 following macros are used anyway, it should not be
too hard to implement this.

#define map_read(map, ofs) (map)->read(map, ofs)
#define map_write(map, datum, ofs) (map)->write(map, datum, ofs)

I am not sure however if this is the correct fix.

Thanks,
John



From jamie@jamieiles.com Thu Jan  6 12:15:40 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 12:15:43 +0100 (CET)
Received: from mail-ww0-f43.google.com ([74.125.82.43]:62639 "EHLO
        mail-ww0-f43.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490996Ab1AFLPk (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Thu, 6 Jan 2011 12:15:40 +0100
Received: by wwi17 with SMTP id 17so16334537wwi.24
        for <multiple recipients>; Thu, 06 Jan 2011 03:15:34 -0800 (PST)
Received: by 10.227.129.141 with SMTP id o13mr822852wbs.85.1294312534676;
        Thu, 06 Jan 2011 03:15:34 -0800 (PST)
Received: from localhost (cpc1-chap8-2-0-cust102.aztw.cable.virginmedia.com [94.169.120.103])
        by mx.google.com with ESMTPS id q18sm16702754wbe.17.2011.01.06.03.15.33
        (version=TLSv1/SSLv3 cipher=RC4-MD5);
        Thu, 06 Jan 2011 03:15:33 -0800 (PST)
Date:   Thu, 6 Jan 2011 11:15:30 +0000
From:   Jamie Iles <jamie@jamieiles.com>
To:     John Crispin <blogic@openwrt.org>
Cc:     Jamie Iles <jamie@jamieiles.com>,
        Ralf Baechle <ralf@linux-mips.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        Wim Van Sebroeck <wim@iguana.be>, linux-mips@linux-mips.org,
        linux-watchdog@vger.kernel.org
Subject: Re: [PATCH 05/10] MIPS: lantiq: add watchdog support
Message-ID: <20110106111530.GD2946@pulham.picochip.com>
References: <1294257379-417-1-git-send-email-blogic@openwrt.org>
 <1294257379-417-6-git-send-email-blogic@openwrt.org>
 <20110105234910.GD2112@gallagher>
 <4D25908E.9070509@openwrt.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <4D25908E.9070509@openwrt.org>
User-Agent: Mutt/1.5.21 (2010-09-15)
Return-Path: <jamie@jamieiles.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: 28866
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: jamie@jamieiles.com
Precedence: bulk
X-list: linux-mips

On Thu, Jan 06, 2011 at 10:51:10AM +0100, John Crispin wrote:
> On 06/01/11 00:49, Jamie Iles wrote:
> > I think you need a clk_put() here too to balance the clk_get() in the 
> > probe method so you'll need to keep a reference to the clk.
> >
> >   
> 
> Hi Jamie,
> 
> i will fold your suggestions into the series.
> 
> the clk.c/h implementation on the lantiq target is very simple. it only
> allows to read the static rates of the 3 clocks. clk_put is implemented
> as follows
> 
> void
> clk_put(struct clk *clk)
> {
>     /* not used */
> }
> EXPORT_SYMBOL(clk_put);
> 
> so in theory you are right and we should call that function, however as
> it is only a stub and the driver is only used by the lantiq target i
> think it is save to leave out the clk_put(); call. we could however put
> a commet in the code to make this clear (same as with the clk_enable()
> not being needed as the clocks are always running)

Could that ever change for future devices that share the same watchdog 
block?  If so, then adding in that clk_put() and clk_enable() might be 
worth it as it doesn't cost much.

Jamie

From blogic@openwrt.org Thu Jan  6 12:37:51 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 12:37:54 +0100 (CET)
Received: from nbd.name ([46.4.11.11]:38160 "EHLO nbd.name"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP
        id S1490993Ab1AFLhv (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Thu, 6 Jan 2011 12:37:51 +0100
Message-ID: <4D25A9CD.9050905@openwrt.org>
Date:   Thu, 06 Jan 2011 12:38:53 +0100
From:   John Crispin <blogic@openwrt.org>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.12) Gecko/20100913 Icedove/3.0.7
MIME-Version: 1.0
To:     Jamie Iles <jamie@jamieiles.com>
CC:     Ralf Baechle <ralf@linux-mips.org>,
        Ralph Hempel <ralph.hempel@lantiq.com>,
        Wim Van Sebroeck <wim@iguana.be>, linux-mips@linux-mips.org,
        linux-watchdog@vger.kernel.org
Subject: Re: [PATCH 05/10] MIPS: lantiq: add watchdog support
References: <1294257379-417-1-git-send-email-blogic@openwrt.org> <1294257379-417-6-git-send-email-blogic@openwrt.org> <20110105234910.GD2112@gallagher> <4D25908E.9070509@openwrt.org> <20110106111530.GD2946@pulham.picochip.com>
In-Reply-To: <20110106111530.GD2946@pulham.picochip.com>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Return-Path: <blogic@openwrt.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: 28867
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: blogic@openwrt.org
Precedence: bulk
X-list: linux-mips

On 06/01/11 12:15, Jamie Iles wrote:
> On Thu, Jan 06, 2011 at 10:51:10AM +0100, John Crispin wrote:
>   
>> On 06/01/11 00:49, Jamie Iles wrote:
>>     
>>> I think you need a clk_put() here too to balance the clk_get() in the 
>>> probe method so you'll need to keep a reference to the clk.
>>>
>>>   
>>>       
>> Hi Jamie,
>>
>> i will fold your suggestions into the series.
>>
>> the clk.c/h implementation on the lantiq target is very simple. it only
>> allows to read the static rates of the 3 clocks. clk_put is implemented
>> as follows
>>
>> void
>> clk_put(struct clk *clk)
>> {
>>     /* not used */
>> }
>> EXPORT_SYMBOL(clk_put);
>>
>> so in theory you are right and we should call that function, however as
>> it is only a stub and the driver is only used by the lantiq target i
>> think it is save to leave out the clk_put(); call. we could however put
>> a commet in the code to make this clear (same as with the clk_enable()
>> not being needed as the clocks are always running)
>>     
> Could that ever change for future devices that share the same watchdog 
> block?  If so, then adding in that clk_put() and clk_enable() might be 
> worth it as it doesn't cost much.
>
> Jamie
>
>   
agreed, i will add both calls.

From skuribay@pobox.com Thu Jan  6 17:18:17 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 17:18:21 +0100 (CET)
Received: from b-pb-sasl-quonix.pobox.com ([208.72.237.35]:58278 "EHLO
        sasl.smtp.pobox.com" rhost-flags-OK-OK-OK-FAIL)
        by eddie.linux-mips.org with ESMTP id S1490989Ab1AFQSR (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Thu, 6 Jan 2011 17:18:17 +0100
Received: from sasl.smtp.pobox.com (unknown [127.0.0.1])
        by b-sasl-quonix.pobox.com (Postfix) with ESMTP id 0D6EE8F94;
        Thu,  6 Jan 2011 11:18:13 -0500 (EST)
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=message-id
        :date:from:mime-version:to:cc:subject:references:in-reply-to
        :content-type:content-transfer-encoding; s=sasl; bh=XdjpO4FWLZQ/
        2pXR64yaFxnUxeY=; b=NJF5yWdqevE/wXfVCvL/U8zbaUiuOxuz+U3ghaobEsx6
        j6AeWzQ/vBhRo64/NwLzrDegE2cTt0kFu7bZwCZ7r6VZBDHU+aRmABIy99YZe4f9
        ozxkEDieO80tRzU+Ixgs9g/uD0J80QtS87YonWTF7s69cibPGDtNzSKTMIJcZ50=
DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=message-id:date
        :from:mime-version:to:cc:subject:references:in-reply-to
        :content-type:content-transfer-encoding; q=dns; s=sasl; b=amUoe6
        ONVDaIDesiCRjA6vyg5TCGX/tF9hg62+1c0PmVEaHurXXTdGyGFoSS7WhfJMIdN3
        tOUJizFpOy9ixFQAepMseer/79dW3k2omorarq0KiGjFg9u810wusefOdOkacfwB
        esKWWGXVZW+czZ7dcX+fY0uiHX5wP58ENwomM=
Received: from b-pb-sasl-quonix. (unknown [127.0.0.1])
        by b-sasl-quonix.pobox.com (Postfix) with ESMTP id 9E55B8F93;
        Thu,  6 Jan 2011 11:18:06 -0500 (EST)
Received: from [192.168.11.5] (unknown [180.12.104.147]) (using TLSv1 with
 cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested)
 by b-sasl-quonix.pobox.com (Postfix) with ESMTPSA id 041DB8F81; Thu,  6 Jan
 2011 11:17:57 -0500 (EST)
Message-ID: <4D25EB30.4020905@pobox.com>
Date:   Fri, 07 Jan 2011 01:17:52 +0900
From:   Shinya Kuribayashi <skuribay@pobox.com>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13)
 Gecko/20101208 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Kevin Cernekee <cernekee@gmail.com>
CC:     Ralf Baechle <ralf@linux-mips.org>, macro@linux-mips.org,
        raiko@niisi.msk.ru, linux-mips@linux-mips.org,
        linux-kernel@vger.kernel.org, skuribay@pobox.com
Subject: Re: [PATCH RESEND 1/6] MIPS: sync after cacheflush
References: <8eec0c63f92528c501c0e6a0c8396359@localhost>
In-Reply-To: <8eec0c63f92528c501c0e6a0c8396359@localhost>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Pobox-Relay-ID: 8B7BBEFC-19B0-11E0-81CE-DD55F7BC62F2-47602734!b-pb-sasl-quonix.pobox.com
Return-Path: <skuribay@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: 28868
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: skuribay@pobox.com
Precedence: bulk
X-list: linux-mips

Hi,

sorry for my silence for several resending posts.  I talked with Ralf
on this briefly, when the patch was posted for the first time last
year.  He seems busy these days, so I'm trying to move things forward.

On 01/06/2011 04:31 PM, Kevin Cernekee wrote:
> On processors with deep write buffers, it is likely that many cycles
> will pass between a CACHE instruction and the time the data actually
> gets written out to DRAM.  Add a SYNC instruction to ensure that the
> buffers get emptied before the flush functions return.

Having a talk with appropriate people (probably including MIPS guys),
such CACHE behavior would be eventually considered to be _legitimate_,
Ralf said.  Thus we agree with this change required not only for BMIPS
cores, but also for the rest of processors, as one of cache features.

The problem is how to implement it.

Most of SYNC-equipped processors work fine without this treatment,
so unless it's required, we don't want to have __sync() after every
cacheflush operations.  Having SYNC there is somewhat waste of time.

> diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
> index b4923a7..dc5d9c4 100644
> --- a/arch/mips/mm/c-r4k.c
> +++ b/arch/mips/mm/c-r4k.c
> @@ -604,6 +604,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
>  			r4k_blast_scache();
>  		else
>  			blast_scache_range(addr, addr + size);
> +		__sync();
>  		return;
>  	}
>  

Just random thought, how it's going to be when implementing this as,
- sort of barrier
- sort of hazard
- one of cache features (e.g., cpu_has_xxx or similar way)
- and so on...

Another concern is that, except for four __sync() insertions, are we
missing other places?

Ralf also thinks that run-time probe & detection would be better than
build-time configuration.  Optimization is easy and won't be problem
here, so we'd like to keep things synthesized as much as possible.

I couldn't imagine the final shape how this patch should be as of now,
sorry!

  Shinya

From David.Daney@caviumnetworks.com Thu Jan  6 18:36:41 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 18:36:44 +0100 (CET)
Received: from mail3.caviumnetworks.com ([12.108.191.235]:18810 "EHLO
        mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490979Ab1AFRgl (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Thu, 6 Jan 2011 18:36:41 +0100
Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,7,2,8378)
        id <B4d25fdd30000>; Thu, 06 Jan 2011 09:37:23 -0800
Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 09:36:36 -0800
Received: from dd1.caveonetworks.com ([12.108.191.236]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 09:36:36 -0800
Message-ID: <4D25FDA3.5000807@caviumnetworks.com>
Date:   Thu, 06 Jan 2011 09:36:35 -0800
From:   David Daney <ddaney@caviumnetworks.com>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.15) Gecko/20101027 Fedora/3.0.10-1.fc12 Thunderbird/3.0.10
MIME-Version: 1.0
To:     Kevin Cernekee <cernekee@gmail.com>
CC:     Ralf Baechle <ralf@linux-mips.org>, linux-mips@linux-mips.org,
        linux-kernel@vger.kernel.org
Subject: Re: [PATCH RESEND 2/6] MIPS: pfn_valid() is broken on low memory
 HIGHMEM systems
References: <8eec0c63f92528c501c0e6a0c8396359@localhost> <b2191149ada0fd929b3818c51298ae8d@localhost>
In-Reply-To: <b2191149ada0fd929b3818c51298ae8d@localhost>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-OriginalArrivalTime: 06 Jan 2011 17:36:36.0098 (UTC) FILETIME=[444A5E20:01CBADC8]
Return-Path: <David.Daney@caviumnetworks.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: 28869
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: ddaney@caviumnetworks.com
Precedence: bulk
X-list: linux-mips

On 01/05/2011 11:31 PM, Kevin Cernekee wrote:
[...]
> diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
> index 2efcbd2..18183a4 100644
> --- a/arch/mips/mm/init.c
> +++ b/arch/mips/mm/init.c
> @@ -370,7 +370,7 @@ void __init mem_init(void)
>   #ifdef CONFIG_DISCONTIGMEM
>   #error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
>   #endif
> -	max_mapnr = highend_pfn;
> +	max_mapnr = highend_pfn ? : max_low_pfn;

That is not standard C.

How about: max_mapnr = highend_pfn ? highend_pfn : max_low_pfn;

David Daney

From anoop.pa@gmail.com Thu Jan  6 21:11:40 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 06 Jan 2011 21:11:43 +0100 (CET)
Received: from mail-fx0-f49.google.com ([209.85.161.49]:62299 "EHLO
        mail-fx0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490979Ab1AFULk (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Thu, 6 Jan 2011 21:11:40 +0100
Received: by fxm19 with SMTP id 19so15733269fxm.36
        for <linux-mips@linux-mips.org>; Thu, 06 Jan 2011 12:11:35 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:subject:from:to:cc
         :in-reply-to:references:content-type:date:message-id:mime-version
         :x-mailer:content-transfer-encoding;
        bh=K+5bzQEwroc0ouRBfhfzTPGudJlKJ71izLvqakdBBLg=;
        b=wt+o0gD+VDNGC886hI3FHExIj2soRoRNVGbt/lWKvusqcPmWj5uuqG1oU4MUslySj9
         co2QY/LZDGgQIDs/1RUj2Ig57DfmMydQZ5XWTakPrB0hJqqbu+Dl6OYsgfudq1lBp/zw
         2ZPfRWC9RrHpEuMAsS2uCJzXNsgUoqcs0gzbQ=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=subject:from:to:cc:in-reply-to:references:content-type:date
         :message-id:mime-version:x-mailer:content-transfer-encoding;
        b=cxZPjwrnqmaJCgcklMW2g+Dnr74TFqUp/uzLH42AWMniTrskiB5btrzyWws/QkIgY6
         iKTOv5vFONXi6I2tIsJ9DVl6KkM4vYg4rb89zHeJkQFQgP7t0+FDxn8NhA00FYjkcCX3
         GY8DTo6T7HqjanxJRSXbcYVBjZY+XG5zBNnfQ=
Received: by 10.223.83.144 with SMTP id f16mr756334fal.4.1294344695432;
        Thu, 06 Jan 2011 12:11:35 -0800 (PST)
Received: from [172.16.48.51] ([59.160.135.215])
        by mx.google.com with ESMTPS id n1sm5961573fam.40.2011.01.06.12.11.29
        (version=SSLv3 cipher=RC4-MD5);
        Thu, 06 Jan 2011 12:11:32 -0800 (PST)
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
In-Reply-To: <4D24C525.5000306@paralogos.com>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
         <1293470392.27661.202.camel@paanoop1-desktop>
         <1293524389.27661.210.camel@paanoop1-desktop>
         <4D19A31E.1090905@paralogos.com>
         <1293798476.27661.279.camel@paanoop1-desktop>
         <4D1EE913.1070203@paralogos.com>
         <1294067561.27661.293.camel@paanoop1-desktop>
         <4D21F5D3.50604@paralogos.com>
         <1294082426.27661.330.camel@paanoop1-desktop>
         <4D22D7B3.2050609@paralogos.com>
         <1294146165.27661.361.camel@paanoop1-desktop>
         <1294151822.27661.375.camel@paanoop1-desktop>
         <4D235717.1000603@paralogos.com>
         <1294163657.27661.386.camel@paanoop1-desktop>
         <4D2367EE.7000702@paralogos.com>
         <1294233097.27661.391.camel@paanoop1-desktop>
         <4D24C525.5000306@paralogos.com>
Content-Type: text/plain; charset="UTF-8"
Date:   Fri, 07 Jan 2011 01:53:16 +0530
Message-ID: <1294345396.27661.422.camel@paanoop1-desktop>
Mime-Version: 1.0
X-Mailer: Evolution 2.28.3 
Content-Transfer-Encoding: 7bit
Return-Path: <anoop.pa@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: 28870
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips

On Wed, 2011-01-05 at 11:23 -0800, Kevin D. Kissell wrote:
> >   		LONG_S	$5, PT_R5(sp)
> >   		LONG_S	v1, PT_STATUS(sp)
> 
> That's exactly what I'd propose as the cleanest minimal fix.  I've got a 
> version that also replaces the .set mips32 / .set mips0 with the .set 
> push / .set pop paradigm, which I'd have used in the original code if 
> I'd known at the time about that assembler directive.  I'm hoping to be 
> able to test on a Malta/34K reference platform, and make sure there 
> isn't breakage on that platform branch as well, before we commit to the 
> repository.

I hope somebody can test this patch on Malta/34K platform. I don't have
access to any malta boards and I believe 34K MT simulations is not
available on qemu.

> 
> Your msp_smtc.c file looks plausible on the face of it.  The 
> init_secondary function has the quirk that it expects to execute on each 
> "CPU" in numerical order, which is very likely but not guaranteed. It 
> *ought* to be harmless in the rare case where it fails, but the 
> assumption is worth a comment, IMHO.
Yes I will add a comment. 

> 
> At this point, there shouldn't be a whole lot of SMTC-specific mystery 
> to get your timer running on the second VPE.  You know it's taking 
> interrupts, because of the IPIs getting through, so in principle you 
> just need to run the chain of enables from the clock peripheral itself 
> through the CIC to the CPU core and the IM bits.

I hope we are almost there. I have made some progress with the debug . I
think you should be able to give better insight to the observation I
have made.

1. Without selecting CONFIG_MIPS_MT_SMTC_IM_BACKSTOP My kernel hangs in
calibration loop itself . ( I haven't looked further into this).

2. With CONFIG_MIPS_MT_SMTC_IM_BACKSTOP I found I am getting 3
VPE1-TIMER interrupt ( one for each TC of VPE1) .However this interrupts
are not getting carried till c0_compare_interrupt . 

do_IRQ call had a SMTC hook which is modifying tccontext ( To reduce
complexity I haven't selected SMTC affinity). 

Once I disabled this call . I am seeing VPE1 timer interrupts and able
to boot completely without any issue's so far :).

/ # cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
CPU6
  1:        171     727459     727561     727533         27     727446
727453            MIPS  SMTC_IPI
  6:          0          0          0          0          0          0
0            MIPS  MSP CIC cascade
  8:          0          0          0          0          0          0
0         MSP_CIC  Softreset button
  9:          0          0          0          0          0          0
0         MSP_CIC  Standby switch
 21:          0          0          0          0          0          0
0         MSP_CIC  MSP PER cascade
 25:     727507        484         11          0          0          0
0         MSP_CIC  timer
 27:          0          0          0          0        258         10
1         MSP_CIC  serial
 34:          0          0          0          0     727533          7
1         MSP_CIC  timer


BTW following code in my cic init was setting hwmask.

        /* initialize all the IRQ descriptors */
        for (i = MSP_CIC_INTBASE ; i < MSP_CIC_INTBASE + 32 ; i++) {
                set_irq_chip_and_handler(i, &msp_cic_irq_controller,
                                         handle_level_irq);
#ifdef CONFIG_MIPS_MT_SMTC
                irq_hwmask[i] = C_IRQ4;
#endif
        }



> It would be really cool if we could get a stable repository branch that 
> boots SMTC out-of-the-box on both Malta and the MSP platform.
:)

> 
>              Regards,
> 
>              Kevin K.
> 
> 
Thanks
Anoop


From kevink@paralogos.com Fri Jan  7 00:31:37 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 00:31:41 +0100 (CET)
Received: from gateway16.websitewelcome.com ([70.85.130.5]:40002 "HELO
        gateway16.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1490993Ab1AFXbh (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 00:31:37 +0100
Received: (qmail 2162 invoked from network); 6 Jan 2011 23:31:07 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway16.websitewelcome.com with SMTP; 6 Jan 2011 23:31:07 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=FFdAiPk3borkIi7mmHXkbcHtLMEXVH+W6IDNp4Eh80NP/JEzrCWIKFDPPhG3B/CunEpktdPg3N5AavucUDrjjHV9F8F/hWEtJTygB5+Q1pVfkWtwEri18RSxtH+QPkiz;
Received: from [216.239.45.4] (port=51840 helo=kkissell.mtv.corp.google.com)
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1PazIo-0002zz-Kz; Thu, 06 Jan 2011 17:31:30 -0600
Message-ID: <4D2650D6.4030102@paralogos.com>
Date:   Thu, 06 Jan 2011 15:31:34 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101208 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Anoop P A <anoop.pa@gmail.com>
CC:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Subject: Re: SMTC support status in latest git head.
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>         <1293470392.27661.202.camel@paanoop1-desktop>         <1293524389.27661.210.camel@paanoop1-desktop>         <4D19A31E.1090905@paralogos.com>         <1293798476.27661.279.camel@paanoop1-desktop>         <4D1EE913.1070203@paralogos.com>         <1294067561.27661.293.camel@paanoop1-desktop>         <4D21F5D3.50604@paralogos.com>         <1294082426.27661.330.camel@paanoop1-desktop>         <4D22D7B3.2050609@paralogos.com>         <1294146165.27661.361.camel@paanoop1-desktop>         <1294151822.27661.375.camel@paanoop1-desktop>         <4D235717.1000603@paralogos.com>         <1294163657.27661.386.camel@paanoop1-desktop>         <4D2367EE.7000702@paralogos.com>         <1294233097.27661.391.camel@paanoop1-desktop>         <4D24C525.5000306@paralogos.com> <1294345396.27661.422.camel@paanoop1-desktop>
In-Reply-To: <1294345396.27661.422.camel@paanoop1-desktop>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28871
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

On 01/06/11 12:23, Anoop P A wrote:
> On Wed, 2011-01-05 at 11:23 -0800, Kevin D. Kissell wrote:
>> At this point, there shouldn't be a whole lot of SMTC-specific mystery
>> to get your timer running on the second VPE.  You know it's taking
>> interrupts, because of the IPIs getting through, so in principle you
>> just need to run the chain of enables from the clock peripheral itself
>> through the CIC to the CPU core and the IM bits.
> I hope we are almost there. I have made some progress with the debug . I
> think you should be able to give better insight to the observation I
> have made.
>
> 1. Without selecting CONFIG_MIPS_MT_SMTC_IM_BACKSTOP My kernel hangs in
> calibration loop itself . ( I haven't looked further into this).
That suggests a problem with Status.IM initialization and/or
the handling of irq_hwmask[].  Do you mean that this is always
true, or only if VPE1 is being booted?  You haven't mentioned it
before.

> 2. With CONFIG_MIPS_MT_SMTC_IM_BACKSTOP I found I am getting 3
> VPE1-TIMER interrupt ( one for each TC of VPE1) .However this interrupts
> are not getting carried till c0_compare_interrupt .
Would you expect them to?  I thought you were using an outboard
timer and not the CP0 Compare interrupt.
>   do_IRQ call had a SMTC hook which is modifying tccontext ( To reduce
> complexity I haven't selected SMTC affinity).
>
> Once I disabled this call . I am seeing VPE1 timer interrupts and able
> to boot completely without any issue's so far :).
So long as you've got the IM_BACKSTOP hack enabled, right?
Because otherwise, without that __DO_IRQ_SMTC_HOOK() invocation
> / # cat /proc/interrupts
>             CPU0       CPU1       CPU2       CPU3       CPU4       CPU5
> CPU6
>    1:        171     727459     727561     727533         27     727446
> 727453            MIPS  SMTC_IPI
>    6:          0          0          0          0          0          0
> 0            MIPS  MSP CIC cascade
>    8:          0          0          0          0          0          0
> 0         MSP_CIC  Softreset button
>    9:          0          0          0          0          0          0
> 0         MSP_CIC  Standby switch
>   21:          0          0          0          0          0          0
> 0         MSP_CIC  MSP PER cascade
>   25:     727507        484         11          0          0          0
> 0         MSP_CIC  timer
>   27:          0          0          0          0        258         10
> 1         MSP_CIC  serial
>   34:          0          0          0          0     727533          7
> 1         MSP_CIC  timer
>
>
> BTW following code in my cic init was setting hwmask.
>
>          /* initialize all the IRQ descriptors */
>          for (i = MSP_CIC_INTBASE ; i<  MSP_CIC_INTBASE + 32 ; i++) {
>                  set_irq_chip_and_handler(i,&msp_cic_irq_controller,
>                                           handle_level_irq);
> #ifdef CONFIG_MIPS_MT_SMTC
>                  irq_hwmask[i] = C_IRQ4;
> #endif
>          }

I'm sure I've said this before, and it's in various comments in the SMTC
code, but remember, one of the main problems that the SMTC kernel
had to solve was to prevent all TCs of a VPE from "convoying" after every
interrupt.  The way this is done is that the interrupt vector code, before
clearing EXL, masks off the Status.IM bit associated with the incoming
interrupt.  Of course, to get another interrupt from the same source
(or collection of sources), that IM bit needs to be restored.  The "correct"
mechanism for this is by having the appropriate irq_hwmask[] value set,
so that smtc_im_ack_irq(), which should be invoked on an irq "ack()"
(meaning that the source has been quenched and any new occurrence
should be considered a new interrupt), will restore the bit in Status.
This function got moved around a bit in the various SMTC prototypes,
but it proved least intrusive to put it into the xxx_mask_and_ack() 
functions
for the interrupt controllers - see irq-msc01.c and i8259.c.  If you haven't
done the same in any equivalent code for a different on-chip controller,
you'll definitely have problems.

The Backstop scheme works OK for peripheral interrupts that didn't
have an appropriate irq_hwmask[] value set up, but clock interrupts
don't follow the same code paths and can't depend on the backstop.

             Regards,

             Kevin K.

From David.Daney@caviumnetworks.com Fri Jan  7 03:35:24 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 03:35:27 +0100 (CET)
Received: from mail3.caviumnetworks.com ([12.108.191.235]:13362 "EHLO
        mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491008Ab1AGCfY (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 03:35:24 +0100
Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,7,2,8378)
        id <B4d267c160000>; Thu, 06 Jan 2011 18:36:06 -0800
Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:19 -0800
Received: from dd1.caveonetworks.com ([12.108.191.236]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:19 -0800
Received: from dd1.caveonetworks.com (localhost.localdomain [127.0.0.1])
        by dd1.caveonetworks.com (8.14.4/8.14.3) with ESMTP id p072ZCvL002633;
        Thu, 6 Jan 2011 18:35:12 -0800
Received: (from ddaney@localhost)
        by dd1.caveonetworks.com (8.14.4/8.14.4/Submit) id p072ZApl002631;
        Thu, 6 Jan 2011 18:35:10 -0800
From:   David Daney <ddaney@caviumnetworks.com>
To:     linux-mips@linux-mips.org, ralf@linux-mips.org,
        linux-kernel@vger.kernel.org
Cc:     David Daney <ddaney@caviumnetworks.com>,
        Peter Zijlstra <a.p.zijlstra@chello.nl>,
        Paul Mackerras <paulus@samba.org>, Ingo Molnar <mingo@elte.hu>,
        Arnaldo Carvalho de Melo <acme@redhat.com>,
        Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Subject: [PATCH 0/6] MIPS: perf: Make perf work for 64-bit/Octeon counters.
Date:   Thu,  6 Jan 2011 18:35:01 -0800
Message-Id: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
X-Mailer: git-send-email 1.7.2.3
X-OriginalArrivalTime: 07 Jan 2011 02:35:19.0469 (UTC) FILETIME=[86855DD0:01CBAE13]
Return-Path: <David.Daney@caviumnetworks.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: 28872
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: ddaney@caviumnetworks.com
Precedence: bulk
X-list: linux-mips

The existing MIPS perf hardware counter support only handles 32-bit
wide counters.  Some CPUs (like Octeon) have the 64-bit wide variety.
This patch set allows perf to work on Octeon, and I hope not break
existing systems.  I have not tested it on non-Octeon systems, so it
would be good if someone could test that.

Summary of the patches:

1) Fix faulty Octeon interrupt controller code.

2) Add some register definitions.

3,4) Clean up existing code.

5) 64-bit perf counter support.

6) Octeon perf event bindings.

Patch 4/6 is the biggest and has the highest chance of having broken
something.

This patch set depends on a couple of others that have previously been
sent to Ralf:

http://patchwork.linux-mips.org/patch/1927/
http://patchwork.linux-mips.org/patch/1850/
http://patchwork.linux-mips.org/patch/1851/
http://patchwork.linux-mips.org/patch/1852/
http://patchwork.linux-mips.org/patch/1853/
http://patchwork.linux-mips.org/patch/1854/

David Daney (6):
  MIPS: Octeon: Enable per-CPU IRQs on all CPUs.
  MIPS: Add accessor macros for 64-bit performance counter registers.
  MIPS: perf: Cleanup formatting in arch/mips/kernel/perf_event.c
  MIPS: perf: Reorganize contents of perf support files.
  MIPS: perf: Add support for 64-bit perf counters.
  MIPS: perf: Add Octeon support for hardware perf.

 arch/mips/Kconfig                    |    2 +-
 arch/mips/cavium-octeon/octeon-irq.c |   30 +-
 arch/mips/cavium-octeon/smp.c        |   10 +
 arch/mips/include/asm/mipsregs.h     |    8 +
 arch/mips/kernel/Makefile            |    5 +-
 arch/mips/kernel/perf_event.c        |  521 +--------------
 arch/mips/kernel/perf_event_mipsxx.c | 1265 +++++++++++++++++++++++++---------
 7 files changed, 977 insertions(+), 864 deletions(-)

Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
-- 
1.7.2.3


From David.Daney@caviumnetworks.com Fri Jan  7 03:35:46 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 03:35:51 +0100 (CET)
Received: from mail3.caviumnetworks.com ([12.108.191.235]:13363 "EHLO
        mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491004Ab1AGCf1 (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 03:35:27 +0100
Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,7,2,8378)
        id <B4d267c1c0000>; Thu, 06 Jan 2011 18:36:12 -0800
Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:25 -0800
Received: from dd1.caveonetworks.com ([12.108.191.236]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:25 -0800
Received: from dd1.caveonetworks.com (localhost.localdomain [127.0.0.1])
        by dd1.caveonetworks.com (8.14.4/8.14.3) with ESMTP id p072ZKSh002641;
        Thu, 6 Jan 2011 18:35:21 -0800
Received: (from ddaney@localhost)
        by dd1.caveonetworks.com (8.14.4/8.14.4/Submit) id p072ZKgP002640;
        Thu, 6 Jan 2011 18:35:20 -0800
From:   David Daney <ddaney@caviumnetworks.com>
To:     linux-mips@linux-mips.org, ralf@linux-mips.org,
        linux-kernel@vger.kernel.org
Cc:     David Daney <ddaney@caviumnetworks.com>
Subject: [PATCH 2/6] MIPS: Add accessor macros for 64-bit performance counter registers.
Date:   Thu,  6 Jan 2011 18:35:03 -0800
Message-Id: <1294367707-2593-3-git-send-email-ddaney@caviumnetworks.com>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
References: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
X-OriginalArrivalTime: 07 Jan 2011 02:35:25.0876 (UTC) FILETIME=[8A56FF40:01CBAE13]
Return-Path: <David.Daney@caviumnetworks.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: 28873
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: ddaney@caviumnetworks.com
Precedence: bulk
X-list: linux-mips

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/mips/include/asm/mipsregs.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index d5c9eaa..86c7ec1 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1019,18 +1019,26 @@ do {									\
 #define write_c0_perfctrl0(val)	__write_32bit_c0_register($25, 0, val)
 #define read_c0_perfcntr0()	__read_32bit_c0_register($25, 1)
 #define write_c0_perfcntr0(val)	__write_32bit_c0_register($25, 1, val)
+#define read_c0_perfcntr0_64()	__read_64bit_c0_register($25, 1)
+#define write_c0_perfcntr0_64(val) __write_64bit_c0_register($25, 1, val)
 #define read_c0_perfctrl1()	__read_32bit_c0_register($25, 2)
 #define write_c0_perfctrl1(val)	__write_32bit_c0_register($25, 2, val)
 #define read_c0_perfcntr1()	__read_32bit_c0_register($25, 3)
 #define write_c0_perfcntr1(val)	__write_32bit_c0_register($25, 3, val)
+#define read_c0_perfcntr1_64()	__read_64bit_c0_register($25, 3)
+#define write_c0_perfcntr1_64(val) __write_64bit_c0_register($25, 3, val)
 #define read_c0_perfctrl2()	__read_32bit_c0_register($25, 4)
 #define write_c0_perfctrl2(val)	__write_32bit_c0_register($25, 4, val)
 #define read_c0_perfcntr2()	__read_32bit_c0_register($25, 5)
 #define write_c0_perfcntr2(val)	__write_32bit_c0_register($25, 5, val)
+#define read_c0_perfcntr2_64()	__read_64bit_c0_register($25, 5)
+#define write_c0_perfcntr2_64(val) __write_64bit_c0_register($25, 5, val)
 #define read_c0_perfctrl3()	__read_32bit_c0_register($25, 6)
 #define write_c0_perfctrl3(val)	__write_32bit_c0_register($25, 6, val)
 #define read_c0_perfcntr3()	__read_32bit_c0_register($25, 7)
 #define write_c0_perfcntr3(val)	__write_32bit_c0_register($25, 7, val)
+#define read_c0_perfcntr3_64()	__read_64bit_c0_register($25, 7)
+#define write_c0_perfcntr3_64(val) __write_64bit_c0_register($25, 7, val)
 
 /* RM9000 PerfCount performance counter register */
 #define read_c0_perfcount()	__read_64bit_c0_register($25, 0)
-- 
1.7.2.3


From David.Daney@caviumnetworks.com Fri Jan  7 03:36:10 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 03:36:16 +0100 (CET)
Received: from mail3.caviumnetworks.com ([12.108.191.235]:13369 "EHLO
        mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491011Ab1AGCfa (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 03:35:30 +0100
Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,7,2,8378)
        id <B4d267c1f0000>; Thu, 06 Jan 2011 18:36:15 -0800
Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:28 -0800
Received: from dd1.caveonetworks.com ([12.108.191.236]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:28 -0800
Received: from dd1.caveonetworks.com (localhost.localdomain [127.0.0.1])
        by dd1.caveonetworks.com (8.14.4/8.14.3) with ESMTP id p072ZMWK002645;
        Thu, 6 Jan 2011 18:35:22 -0800
Received: (from ddaney@localhost)
        by dd1.caveonetworks.com (8.14.4/8.14.4/Submit) id p072ZLDd002644;
        Thu, 6 Jan 2011 18:35:21 -0800
From:   David Daney <ddaney@caviumnetworks.com>
To:     linux-mips@linux-mips.org, ralf@linux-mips.org,
        linux-kernel@vger.kernel.org
Cc:     David Daney <ddaney@caviumnetworks.com>,
        Peter Zijlstra <a.p.zijlstra@chello.nl>,
        Paul Mackerras <paulus@samba.org>, Ingo Molnar <mingo@elte.hu>,
        Arnaldo Carvalho de Melo <acme@redhat.com>,
        Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Subject: [PATCH 3/6] MIPS: perf: Cleanup formatting in arch/mips/kernel/perf_event.c
Date:   Thu,  6 Jan 2011 18:35:04 -0800
Message-Id: <1294367707-2593-4-git-send-email-ddaney@caviumnetworks.com>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
References: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
X-OriginalArrivalTime: 07 Jan 2011 02:35:28.0376 (UTC) FILETIME=[8BD47780:01CBAE13]
Return-Path: <David.Daney@caviumnetworks.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: 28874
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: ddaney@caviumnetworks.com
Precedence: bulk
X-list: linux-mips

Get rid of a bunch of useless inline declarations, and join a bunch of
improperly split lines.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
---
 arch/mips/kernel/perf_event.c        |   26 +++++-------
 arch/mips/kernel/perf_event_mipsxx.c |   68 +++++++++++++---------------------
 2 files changed, 37 insertions(+), 57 deletions(-)

diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c
index a824485..931d957 100644
--- a/arch/mips/kernel/perf_event.c
+++ b/arch/mips/kernel/perf_event.c
@@ -118,10 +118,9 @@ struct mips_pmu {
 
 static const struct mips_pmu *mipspmu;
 
-static int
-mipspmu_event_set_period(struct perf_event *event,
-			struct hw_perf_event *hwc,
-			int idx)
+static int mipspmu_event_set_period(struct perf_event *event,
+				    struct hw_perf_event *hwc,
+				    int idx)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	s64 left = local64_read(&hwc->period_left);
@@ -162,8 +161,8 @@ mipspmu_event_set_period(struct perf_event *event,
 }
 
 static void mipspmu_event_update(struct perf_event *event,
-			struct hw_perf_event *hwc,
-			int idx)
+				 struct hw_perf_event *hwc,
+				 int idx)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	unsigned long flags;
@@ -422,8 +421,7 @@ static struct pmu pmu = {
 	.read		= mipspmu_read,
 };
 
-static inline unsigned int
-mipspmu_perf_event_encode(const struct mips_perf_event *pev)
+static unsigned int mipspmu_perf_event_encode(const struct mips_perf_event *pev)
 {
 /*
  * Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for
@@ -439,8 +437,7 @@ mipspmu_perf_event_encode(const struct mips_perf_event *pev)
 #endif
 }
 
-static const struct mips_perf_event *
-mipspmu_map_general_event(int idx)
+static const struct mips_perf_event *mipspmu_map_general_event(int idx)
 {
 	const struct mips_perf_event *pev;
 
@@ -451,8 +448,7 @@ mipspmu_map_general_event(int idx)
 	return pev;
 }
 
-static const struct mips_perf_event *
-mipspmu_map_cache_event(u64 config)
+static const struct mips_perf_event *mipspmu_map_cache_event(u64 config)
 {
 	unsigned int cache_type, cache_op, cache_result;
 	const struct mips_perf_event *pev;
@@ -515,9 +511,9 @@ static int validate_group(struct perf_event *event)
 }
 
 /* This is needed by specific irq handlers in perf_event_*.c */
-static void
-handle_associated_event(struct cpu_hw_events *cpuc,
-	int idx, struct perf_sample_data *data, struct pt_regs *regs)
+static void handle_associated_event(struct cpu_hw_events *cpuc,
+				    int idx, struct perf_sample_data *data,
+				    struct pt_regs *regs)
 {
 	struct perf_event *event = cpuc->events[idx];
 	struct hw_perf_event *hwc = &event->hw;
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index c9406d6..a72e7247 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -49,37 +49,32 @@ static int cpu_has_mipsmt_pertccounters;
 #endif
 
 /* Copied from op_model_mipsxx.c */
-static inline unsigned int vpe_shift(void)
+static unsigned int vpe_shift(void)
 {
 	if (num_possible_cpus() > 1)
 		return 1;
 
 	return 0;
 }
-#else /* !CONFIG_MIPS_MT_SMP */
-#define vpe_id()	0
-
-static inline unsigned int vpe_shift(void)
-{
-	return 0;
-}
-#endif /* CONFIG_MIPS_MT_SMP */
 
-static inline unsigned int
-counters_total_to_per_cpu(unsigned int counters)
+static unsigned int counters_total_to_per_cpu(unsigned int counters)
 {
 	return counters >> vpe_shift();
 }
 
-static inline unsigned int
-counters_per_cpu_to_total(unsigned int counters)
+static unsigned int counters_per_cpu_to_total(unsigned int counters)
 {
 	return counters << vpe_shift();
 }
 
+#else /* !CONFIG_MIPS_MT_SMP */
+#define vpe_id()	0
+
+#endif /* CONFIG_MIPS_MT_SMP */
+
 #define __define_perf_accessors(r, n, np)				\
 									\
-static inline unsigned int r_c0_ ## r ## n(void)			\
+static unsigned int r_c0_ ## r ## n(void)				\
 {									\
 	unsigned int cpu = vpe_id();					\
 									\
@@ -94,7 +89,7 @@ static inline unsigned int r_c0_ ## r ## n(void)			\
 	return 0;							\
 }									\
 									\
-static inline void w_c0_ ## r ## n(unsigned int value)			\
+static void w_c0_ ## r ## n(unsigned int value)				\
 {									\
 	unsigned int cpu = vpe_id();					\
 									\
@@ -121,7 +116,7 @@ __define_perf_accessors(perfctrl, 1, 3)
 __define_perf_accessors(perfctrl, 2, 0)
 __define_perf_accessors(perfctrl, 3, 1)
 
-static inline int __n_counters(void)
+static int __n_counters(void)
 {
 	if (!(read_c0_config1() & M_CONFIG1_PC))
 		return 0;
@@ -135,7 +130,7 @@ static inline int __n_counters(void)
 	return 4;
 }
 
-static inline int n_counters(void)
+static int n_counters(void)
 {
 	int counters;
 
@@ -175,8 +170,7 @@ static void reset_counters(void *arg)
 	}
 }
 
-static inline u64
-mipsxx_pmu_read_counter(unsigned int idx)
+static u64 mipsxx_pmu_read_counter(unsigned int idx)
 {
 	switch (idx) {
 	case 0:
@@ -193,8 +187,7 @@ mipsxx_pmu_read_counter(unsigned int idx)
 	}
 }
 
-static inline void
-mipsxx_pmu_write_counter(unsigned int idx, u64 val)
+static void mipsxx_pmu_write_counter(unsigned int idx, u64 val)
 {
 	switch (idx) {
 	case 0:
@@ -212,8 +205,7 @@ mipsxx_pmu_write_counter(unsigned int idx, u64 val)
 	}
 }
 
-static inline unsigned int
-mipsxx_pmu_read_control(unsigned int idx)
+static unsigned int mipsxx_pmu_read_control(unsigned int idx)
 {
 	switch (idx) {
 	case 0:
@@ -230,8 +222,7 @@ mipsxx_pmu_read_control(unsigned int idx)
 	}
 }
 
-static inline void
-mipsxx_pmu_write_control(unsigned int idx, unsigned int val)
+static void mipsxx_pmu_write_control(unsigned int idx, unsigned int val)
 {
 	switch (idx) {
 	case 0:
@@ -483,9 +474,8 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
 };
 
 #ifdef CONFIG_MIPS_MT_SMP
-static void
-check_and_calc_range(struct perf_event *event,
-			const struct mips_perf_event *pev)
+static void check_and_calc_range(struct perf_event *event,
+				 const struct mips_perf_event *pev)
 {
 	struct hw_perf_event *hwc = &event->hw;
 
@@ -508,9 +498,8 @@ check_and_calc_range(struct perf_event *event,
 		hwc->config_base |= M_TC_EN_ALL;
 }
 #else
-static void
-check_and_calc_range(struct perf_event *event,
-			const struct mips_perf_event *pev)
+static void check_and_calc_range(struct perf_event *event,
+				 const struct mips_perf_event *pev)
 {
 }
 #endif
@@ -705,8 +694,7 @@ static int mipsxx_pmu_handle_shared_irq(void)
 	return handled;
 }
 
-static irqreturn_t
-mipsxx_pmu_handle_irq(int irq, void *dev)
+static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
 {
 	return mipsxx_pmu_handle_shared_irq();
 }
@@ -738,9 +726,8 @@ static void mipsxx_pmu_stop(void)
 #endif
 }
 
-static int
-mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc,
-			struct hw_perf_event *hwc)
+static int mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc,
+				    struct hw_perf_event *hwc)
 {
 	int i;
 
@@ -769,8 +756,7 @@ mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc,
 	return -EAGAIN;
 }
 
-static void
-mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
+static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	unsigned long flags;
@@ -788,8 +774,7 @@ mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
 	local_irq_restore(flags);
 }
 
-static void
-mipsxx_pmu_disable_event(int idx)
+static void mipsxx_pmu_disable_event(int idx)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	unsigned long flags;
@@ -864,8 +849,7 @@ mipsxx_pmu_disable_event(int idx)
  * then 128 needs to be added to 15 as the input for the event config,
  * i.e., 143 (0x8F) to be used.
  */
-static const struct mips_perf_event *
-mipsxx_pmu_map_raw_event(u64 config)
+static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
 {
 	unsigned int raw_id = config & 0xff;
 	unsigned int base_id = raw_id & 0x7f;
-- 
1.7.2.3


From David.Daney@caviumnetworks.com Fri Jan  7 03:36:35 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 03:36:41 +0100 (CET)
Received: from mail3.caviumnetworks.com ([12.108.191.235]:13382 "EHLO
        mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491012Ab1AGCfb (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 03:35:31 +0100
Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,7,2,8378)
        id <B4d267c200001>; Thu, 06 Jan 2011 18:36:16 -0800
Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:29 -0800
Received: from dd1.caveonetworks.com ([12.108.191.236]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:29 -0800
Received: from dd1.caveonetworks.com (localhost.localdomain [127.0.0.1])
        by dd1.caveonetworks.com (8.14.4/8.14.3) with ESMTP id p072ZJkI002637;
        Thu, 6 Jan 2011 18:35:19 -0800
Received: (from ddaney@localhost)
        by dd1.caveonetworks.com (8.14.4/8.14.4/Submit) id p072ZHGZ002636;
        Thu, 6 Jan 2011 18:35:17 -0800
From:   David Daney <ddaney@caviumnetworks.com>
To:     linux-mips@linux-mips.org, ralf@linux-mips.org,
        linux-kernel@vger.kernel.org
Cc:     David Daney <ddaney@caviumnetworks.com>,
        Thomas Gleixner <tglx@linutronix.de>
Subject: [PATCH 1/6] MIPS: Octeon: Enable per-CPU IRQs on all CPUs.
Date:   Thu,  6 Jan 2011 18:35:02 -0800
Message-Id: <1294367707-2593-2-git-send-email-ddaney@caviumnetworks.com>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
References: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
X-OriginalArrivalTime: 07 Jan 2011 02:35:29.0376 (UTC) FILETIME=[8C6D0E00:01CBAE13]
Return-Path: <David.Daney@caviumnetworks.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: 28875
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: ddaney@caviumnetworks.com
Precedence: bulk
X-list: linux-mips

We cannot use on_each_cpu() from low-level irq code, as it ends up
being run with interrupts disabled (a no-no).  Instead use some direct
IPI message bits to enable and disable the MIPS CPU interrupts.

Also, enable the irq on all CPUs for MIPS CPU interrupts.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 arch/mips/cavium-octeon/octeon-irq.c |   30 +++++++++++++++++++++++++++---
 arch/mips/cavium-octeon/smp.c        |   10 ++++++++++
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index ce7500c..023cf04 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -56,7 +56,7 @@ static void octeon_irq_core_eoi(unsigned int irq)
 	set_c0_status(0x100 << bit);
 }
 
-static void octeon_irq_core_enable(unsigned int irq)
+static void octeon_irq_core_enable_local(unsigned int irq)
 {
 	unsigned long flags;
 	unsigned int bit = irq - OCTEON_IRQ_SW0;
@@ -83,16 +83,40 @@ static void octeon_irq_core_disable_local(unsigned int irq)
 	local_irq_restore(flags);
 }
 
+extern void octeon_send_ipi_single(int cpu, unsigned int action);
+
 static void octeon_irq_core_disable(unsigned int irq)
 {
 #ifdef CONFIG_SMP
-	on_each_cpu((void (*)(void *)) octeon_irq_core_disable_local,
-		    (void *) (long) irq, 1);
+	unsigned int bit = irq - OCTEON_IRQ_SW0;
+	int cpu;
+	for_each_online_cpu(cpu) {
+		if (cpu == smp_processor_id())
+			octeon_irq_core_disable_local(irq);
+		else
+			octeon_send_ipi_single(cpu, 0x100 << bit);
+	}
 #else
 	octeon_irq_core_disable_local(irq);
 #endif
 }
 
+static void octeon_irq_core_enable(unsigned int irq)
+{
+#ifdef CONFIG_SMP
+	unsigned int bit = irq - OCTEON_IRQ_SW0;
+	int cpu;
+	for_each_online_cpu(cpu) {
+		if (cpu == smp_processor_id())
+			octeon_irq_core_enable_local(irq);
+		else
+			octeon_send_ipi_single(cpu, 0x10000 << bit);
+	}
+#else
+	octeon_irq_core_enable_local(irq);
+#endif
+}
+
 static struct irq_chip octeon_irq_chip_core = {
 	.name = "Core",
 	.enable = octeon_irq_core_enable,
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 391cefe..92d819b 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -48,6 +48,16 @@ static irqreturn_t mailbox_interrupt(int irq, void *dev_id)
 	/* Check if we've been told to flush the icache */
 	if (action & SMP_ICACHE_FLUSH)
 		asm volatile ("synci 0($0)\n");
+	if (action & 0xff00) {
+		/* Disable MIPS CPU irq*/
+		unsigned int mask = action & 0xff00;
+		clear_c0_status(mask);
+	}
+	if (action & 0xff0000) {
+		/* Enable MIPS CPU irq*/
+		unsigned int mask = (action >> 8) & 0xff00;
+		set_c0_status(mask);
+	}
 	return IRQ_HANDLED;
 }
 
-- 
1.7.2.3


From David.Daney@caviumnetworks.com Fri Jan  7 03:36:59 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 03:37:08 +0100 (CET)
Received: from mail3.caviumnetworks.com ([12.108.191.235]:13400 "EHLO
        mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491013Ab1AGCff (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 03:35:35 +0100
Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,7,2,8378)
        id <B4d267c210000>; Thu, 06 Jan 2011 18:36:17 -0800
Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:30 -0800
Received: from dd1.caveonetworks.com ([12.108.191.236]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:30 -0800
Received: from dd1.caveonetworks.com (localhost.localdomain [127.0.0.1])
        by dd1.caveonetworks.com (8.14.4/8.14.3) with ESMTP id p072ZPI4002649;
        Thu, 6 Jan 2011 18:35:25 -0800
Received: (from ddaney@localhost)
        by dd1.caveonetworks.com (8.14.4/8.14.4/Submit) id p072ZOSZ002648;
        Thu, 6 Jan 2011 18:35:24 -0800
From:   David Daney <ddaney@caviumnetworks.com>
To:     linux-mips@linux-mips.org, ralf@linux-mips.org,
        linux-kernel@vger.kernel.org
Cc:     David Daney <ddaney@caviumnetworks.com>,
        Peter Zijlstra <a.p.zijlstra@chello.nl>,
        Paul Mackerras <paulus@samba.org>, Ingo Molnar <mingo@elte.hu>,
        Arnaldo Carvalho de Melo <acme@redhat.com>,
        Dezhong Diao <dediao@cisco.com>,
        Gabor Juhos <juhosg@openwrt.org>,
        Grant Likely <grant.likely@secretlab.ca>,
        Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Subject: [PATCH 4/6] MIPS: perf: Reorganize contents of perf support files.
Date:   Thu,  6 Jan 2011 18:35:05 -0800
Message-Id: <1294367707-2593-5-git-send-email-ddaney@caviumnetworks.com>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
References: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
X-OriginalArrivalTime: 07 Jan 2011 02:35:30.0376 (UTC) FILETIME=[8D05A480:01CBAE13]
Return-Path: <David.Daney@caviumnetworks.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: 28876
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: ddaney@caviumnetworks.com
Precedence: bulk
X-list: linux-mips

The contents of arch/mips/kernel/perf_event.c and
arch/mips/kernel/perf_event_mipsxx.c were divided in a seemingly ad
hoc manner, with the first including the second.

I moved all the hardware counter support code to perf_event_mipsxx.c
and removed the gating #ifdefs to the Kconfig and Makefile.

Now perf_event.c contains only the callchain support, everything else
is in perf_event_mipsxx.c

There are no code changes, only moving of functions from one file to
the other, or removing empty unneeded functions.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Daney <ddaney@caviumnetworks.com>
Cc: Dezhong Diao <dediao@cisco.com>
Cc: Gabor Juhos <juhosg@openwrt.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
---
 arch/mips/Kconfig                    |    2 +-
 arch/mips/kernel/Makefile            |    5 +-
 arch/mips/kernel/perf_event.c        |  517 +---------------------------------
 arch/mips/kernel/perf_event_mipsxx.c |  532 +++++++++++++++++++++++++++++++++-
 4 files changed, 534 insertions(+), 522 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index acfa1fe..88aaec2 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2016,7 +2016,7 @@ config NODES_SHIFT
 
 config HW_PERF_EVENTS
 	bool "Enable hardware performance counter support for perf events"
-	depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32
+	depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1)
 	default y
 	help
 	  Enable hardware performance counter support for perf events. If
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index cedee2b..753b421 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -11,6 +11,8 @@ obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_early_printk.o = -pg
+CFLAGS_REMOVE_perf_event.o = -pg
+CFLAGS_REMOVE_perf_event_mipsxx.o = -pg
 endif
 
 obj-$(CONFIG_CEVT_BCM1480)	+= cevt-bcm1480.o
@@ -105,7 +107,8 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT)	+= 8250-platform.o
 
 obj-$(CONFIG_MIPS_CPUFREQ)	+= cpufreq/
 
-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
+obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o
+obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event_mipsxx.o
 
 obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
 
diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c
index 931d957..c1cf9c6 100644
--- a/arch/mips/kernel/perf_event.c
+++ b/arch/mips/kernel/perf_event.c
@@ -14,531 +14,16 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/cpumask.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-#include <linux/kernel.h>
 #include <linux/perf_event.h>
-#include <linux/uaccess.h>
 
-#include <asm/irq.h>
-#include <asm/irq_regs.h>
 #include <asm/stacktrace.h>
-#include <asm/time.h> /* For perf_irq */
-
-/* These are for 32bit counters. For 64bit ones, define them accordingly. */
-#define MAX_PERIOD	((1ULL << 32) - 1)
-#define VALID_COUNT	0x7fffffff
-#define TOTAL_BITS	32
-#define HIGHEST_BIT	31
-
-#define MIPS_MAX_HWEVENTS 4
-
-struct cpu_hw_events {
-	/* Array of events on this cpu. */
-	struct perf_event	*events[MIPS_MAX_HWEVENTS];
-
-	/*
-	 * Set the bit (indexed by the counter number) when the counter
-	 * is used for an event.
-	 */
-	unsigned long		used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
-
-	/*
-	 * The borrowed MSB for the performance counter. A MIPS performance
-	 * counter uses its bit 31 (for 32bit counters) or bit 63 (for 64bit
-	 * counters) as a factor of determining whether a counter overflow
-	 * should be signaled. So here we use a separate MSB for each
-	 * counter to make things easy.
-	 */
-	unsigned long		msbs[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
-
-	/*
-	 * Software copy of the control register for each performance counter.
-	 * MIPS CPUs vary in performance counters. They use this differently,
-	 * and even may not use it.
-	 */
-	unsigned int		saved_ctrl[MIPS_MAX_HWEVENTS];
-};
-DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
-	.saved_ctrl = {0},
-};
-
-/* The description of MIPS performance events. */
-struct mips_perf_event {
-	unsigned int event_id;
-	/*
-	 * MIPS performance counters are indexed starting from 0.
-	 * CNTR_EVEN indicates the indexes of the counters to be used are
-	 * even numbers.
-	 */
-	unsigned int cntr_mask;
-	#define CNTR_EVEN	0x55555555
-	#define CNTR_ODD	0xaaaaaaaa
-#ifdef CONFIG_MIPS_MT_SMP
-	enum {
-		T  = 0,
-		V  = 1,
-		P  = 2,
-	} range;
-#else
-	#define T
-	#define V
-	#define P
-#endif
-};
-
-static struct mips_perf_event raw_event;
-static DEFINE_MUTEX(raw_event_mutex);
-
-#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff
-#define C(x) PERF_COUNT_HW_CACHE_##x
-
-struct mips_pmu {
-	const char	*name;
-	int		irq;
-	irqreturn_t	(*handle_irq)(int irq, void *dev);
-	int		(*handle_shared_irq)(void);
-	void		(*start)(void);
-	void		(*stop)(void);
-	int		(*alloc_counter)(struct cpu_hw_events *cpuc,
-					struct hw_perf_event *hwc);
-	u64		(*read_counter)(unsigned int idx);
-	void		(*write_counter)(unsigned int idx, u64 val);
-	void		(*enable_event)(struct hw_perf_event *evt, int idx);
-	void		(*disable_event)(int idx);
-	const struct mips_perf_event *(*map_raw_event)(u64 config);
-	const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX];
-	const struct mips_perf_event (*cache_event_map)
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX];
-	unsigned int	num_counters;
-};
-
-static const struct mips_pmu *mipspmu;
-
-static int mipspmu_event_set_period(struct perf_event *event,
-				    struct hw_perf_event *hwc,
-				    int idx)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	s64 left = local64_read(&hwc->period_left);
-	s64 period = hwc->sample_period;
-	int ret = 0;
-	u64 uleft;
-	unsigned long flags;
-
-	if (unlikely(left <= -period)) {
-		left = period;
-		local64_set(&hwc->period_left, left);
-		hwc->last_period = period;
-		ret = 1;
-	}
-
-	if (unlikely(left <= 0)) {
-		left += period;
-		local64_set(&hwc->period_left, left);
-		hwc->last_period = period;
-		ret = 1;
-	}
-
-	if (left > (s64)MAX_PERIOD)
-		left = MAX_PERIOD;
-
-	local64_set(&hwc->prev_count, (u64)-left);
-
-	local_irq_save(flags);
-	uleft = (u64)(-left) & MAX_PERIOD;
-	uleft > VALID_COUNT ?
-		set_bit(idx, cpuc->msbs) : clear_bit(idx, cpuc->msbs);
-	mipspmu->write_counter(idx, (u64)(-left) & VALID_COUNT);
-	local_irq_restore(flags);
-
-	perf_event_update_userpage(event);
-
-	return ret;
-}
-
-static void mipspmu_event_update(struct perf_event *event,
-				 struct hw_perf_event *hwc,
-				 int idx)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	unsigned long flags;
-	int shift = 64 - TOTAL_BITS;
-	s64 prev_raw_count, new_raw_count;
-	u64 delta;
-
-again:
-	prev_raw_count = local64_read(&hwc->prev_count);
-	local_irq_save(flags);
-	/* Make the counter value be a "real" one. */
-	new_raw_count = mipspmu->read_counter(idx);
-	if (new_raw_count & (test_bit(idx, cpuc->msbs) << HIGHEST_BIT)) {
-		new_raw_count &= VALID_COUNT;
-		clear_bit(idx, cpuc->msbs);
-	} else
-		new_raw_count |= (test_bit(idx, cpuc->msbs) << HIGHEST_BIT);
-	local_irq_restore(flags);
-
-	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
-				new_raw_count) != prev_raw_count)
-		goto again;
-
-	delta = (new_raw_count << shift) - (prev_raw_count << shift);
-	delta >>= shift;
-
-	local64_add(delta, &event->count);
-	local64_sub(delta, &hwc->period_left);
-
-	return;
-}
-
-static void mipspmu_start(struct perf_event *event, int flags)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (!mipspmu)
-		return;
-
-	if (flags & PERF_EF_RELOAD)
-		WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
-
-	hwc->state = 0;
-
-	/* Set the period for the event. */
-	mipspmu_event_set_period(event, hwc, hwc->idx);
-
-	/* Enable the event. */
-	mipspmu->enable_event(hwc, hwc->idx);
-}
-
-static void mipspmu_stop(struct perf_event *event, int flags)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (!mipspmu)
-		return;
-
-	if (!(hwc->state & PERF_HES_STOPPED)) {
-		/* We are working on a local event. */
-		mipspmu->disable_event(hwc->idx);
-		barrier();
-		mipspmu_event_update(event, hwc, hwc->idx);
-		hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
-	}
-}
-
-static int mipspmu_add(struct perf_event *event, int flags)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
-	int idx;
-	int err = 0;
-
-	perf_pmu_disable(event->pmu);
-
-	/* To look for a free counter for this event. */
-	idx = mipspmu->alloc_counter(cpuc, hwc);
-	if (idx < 0) {
-		err = idx;
-		goto out;
-	}
-
-	/*
-	 * If there is an event in the counter we are going to use then
-	 * make sure it is disabled.
-	 */
-	event->hw.idx = idx;
-	mipspmu->disable_event(idx);
-	cpuc->events[idx] = event;
-
-	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
-	if (flags & PERF_EF_START)
-		mipspmu_start(event, PERF_EF_RELOAD);
-
-	/* Propagate our changes to the userspace mapping. */
-	perf_event_update_userpage(event);
-
-out:
-	perf_pmu_enable(event->pmu);
-	return err;
-}
-
-static void mipspmu_del(struct perf_event *event, int flags)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
-	int idx = hwc->idx;
-
-	WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
-
-	mipspmu_stop(event, PERF_EF_UPDATE);
-	cpuc->events[idx] = NULL;
-	clear_bit(idx, cpuc->used_mask);
-
-	perf_event_update_userpage(event);
-}
-
-static void mipspmu_read(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	/* Don't read disabled counters! */
-	if (hwc->idx < 0)
-		return;
-
-	mipspmu_event_update(event, hwc, hwc->idx);
-}
-
-static void mipspmu_enable(struct pmu *pmu)
-{
-	if (mipspmu)
-		mipspmu->start();
-}
-
-static void mipspmu_disable(struct pmu *pmu)
-{
-	if (mipspmu)
-		mipspmu->stop();
-}
-
-static atomic_t active_events = ATOMIC_INIT(0);
-static DEFINE_MUTEX(pmu_reserve_mutex);
-static int (*save_perf_irq)(void);
-
-static int mipspmu_get_irq(void)
-{
-	int err;
-
-	if (mipspmu->irq >= 0) {
-		/* Request my own irq handler. */
-		err = request_irq(mipspmu->irq, mipspmu->handle_irq,
-			IRQF_DISABLED | IRQF_NOBALANCING,
-			"mips_perf_pmu", NULL);
-		if (err) {
-			pr_warning("Unable to request IRQ%d for MIPS "
-			   "performance counters!\n", mipspmu->irq);
-		}
-	} else if (cp0_perfcount_irq < 0) {
-		/*
-		 * We are sharing the irq number with the timer interrupt.
-		 */
-		save_perf_irq = perf_irq;
-		perf_irq = mipspmu->handle_shared_irq;
-		err = 0;
-	} else {
-		pr_warning("The platform hasn't properly defined its "
-			"interrupt controller.\n");
-		err = -ENOENT;
-	}
-
-	return err;
-}
-
-static void mipspmu_free_irq(void)
-{
-	if (mipspmu->irq >= 0)
-		free_irq(mipspmu->irq, NULL);
-	else if (cp0_perfcount_irq < 0)
-		perf_irq = save_perf_irq;
-}
-
-/*
- * mipsxx/rm9000/loongson2 have different performance counters, they have
- * specific low-level init routines.
- */
-static void reset_counters(void *arg);
-static int __hw_perf_event_init(struct perf_event *event);
-
-static void hw_perf_event_destroy(struct perf_event *event)
-{
-	if (atomic_dec_and_mutex_lock(&active_events,
-				&pmu_reserve_mutex)) {
-		/*
-		 * We must not call the destroy function with interrupts
-		 * disabled.
-		 */
-		on_each_cpu(reset_counters,
-			(void *)(long)mipspmu->num_counters, 1);
-		mipspmu_free_irq();
-		mutex_unlock(&pmu_reserve_mutex);
-	}
-}
-
-static int mipspmu_event_init(struct perf_event *event)
-{
-	int err = 0;
-
-	switch (event->attr.type) {
-	case PERF_TYPE_RAW:
-	case PERF_TYPE_HARDWARE:
-	case PERF_TYPE_HW_CACHE:
-		break;
-
-	default:
-		return -ENOENT;
-	}
-
-	if (!mipspmu || event->cpu >= nr_cpumask_bits ||
-		(event->cpu >= 0 && !cpu_online(event->cpu)))
-		return -ENODEV;
-
-	if (!atomic_inc_not_zero(&active_events)) {
-		if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) {
-			atomic_dec(&active_events);
-			return -ENOSPC;
-		}
-
-		mutex_lock(&pmu_reserve_mutex);
-		if (atomic_read(&active_events) == 0)
-			err = mipspmu_get_irq();
-
-		if (!err)
-			atomic_inc(&active_events);
-		mutex_unlock(&pmu_reserve_mutex);
-	}
-
-	if (err)
-		return err;
-
-	err = __hw_perf_event_init(event);
-	if (err)
-		hw_perf_event_destroy(event);
-
-	return err;
-}
-
-static struct pmu pmu = {
-	.pmu_enable	= mipspmu_enable,
-	.pmu_disable	= mipspmu_disable,
-	.event_init	= mipspmu_event_init,
-	.add		= mipspmu_add,
-	.del		= mipspmu_del,
-	.start		= mipspmu_start,
-	.stop		= mipspmu_stop,
-	.read		= mipspmu_read,
-};
-
-static unsigned int mipspmu_perf_event_encode(const struct mips_perf_event *pev)
-{
-/*
- * Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for
- * event_id.
- */
-#ifdef CONFIG_MIPS_MT_SMP
-	return ((unsigned int)pev->range << 24) |
-		(pev->cntr_mask & 0xffff00) |
-		(pev->event_id & 0xff);
-#else
-	return (pev->cntr_mask & 0xffff00) |
-		(pev->event_id & 0xff);
-#endif
-}
-
-static const struct mips_perf_event *mipspmu_map_general_event(int idx)
-{
-	const struct mips_perf_event *pev;
-
-	pev = ((*mipspmu->general_event_map)[idx].event_id ==
-		UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) :
-		&(*mipspmu->general_event_map)[idx]);
-
-	return pev;
-}
-
-static const struct mips_perf_event *mipspmu_map_cache_event(u64 config)
-{
-	unsigned int cache_type, cache_op, cache_result;
-	const struct mips_perf_event *pev;
-
-	cache_type = (config >> 0) & 0xff;
-	if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
-		return ERR_PTR(-EINVAL);
-
-	cache_op = (config >> 8) & 0xff;
-	if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
-		return ERR_PTR(-EINVAL);
-
-	cache_result = (config >> 16) & 0xff;
-	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
-		return ERR_PTR(-EINVAL);
-
-	pev = &((*mipspmu->cache_event_map)
-					[cache_type]
-					[cache_op]
-					[cache_result]);
-
-	if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID)
-		return ERR_PTR(-EOPNOTSUPP);
-
-	return pev;
-
-}
-
-static int validate_event(struct cpu_hw_events *cpuc,
-	       struct perf_event *event)
-{
-	struct hw_perf_event fake_hwc = event->hw;
-
-	/* Allow mixed event group. So return 1 to pass validation. */
-	if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF)
-		return 1;
-
-	return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0;
-}
-
-static int validate_group(struct perf_event *event)
-{
-	struct perf_event *sibling, *leader = event->group_leader;
-	struct cpu_hw_events fake_cpuc;
-
-	memset(&fake_cpuc, 0, sizeof(fake_cpuc));
-
-	if (!validate_event(&fake_cpuc, leader))
-		return -ENOSPC;
-
-	list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
-		if (!validate_event(&fake_cpuc, sibling))
-			return -ENOSPC;
-	}
-
-	if (!validate_event(&fake_cpuc, event))
-		return -ENOSPC;
-
-	return 0;
-}
-
-/* This is needed by specific irq handlers in perf_event_*.c */
-static void handle_associated_event(struct cpu_hw_events *cpuc,
-				    int idx, struct perf_sample_data *data,
-				    struct pt_regs *regs)
-{
-	struct perf_event *event = cpuc->events[idx];
-	struct hw_perf_event *hwc = &event->hw;
-
-	mipspmu_event_update(event, hwc, idx);
-	data->period = event->hw.last_period;
-	if (!mipspmu_event_set_period(event, hwc, idx))
-		return;
-
-	if (perf_event_overflow(event, 0, data, regs))
-		mipspmu->disable_event(idx);
-}
-
-#include "perf_event_mipsxx.c"
 
 /* Callchain handling code. */
 
 /*
  * Leave userspace callchain empty for now. When we find a way to trace
- * the user stack callchains, we add here.
+ * the user stack callchains, we will add it here.
  */
-void perf_callchain_user(struct perf_callchain_entry *entry,
-		    struct pt_regs *regs)
-{
-}
 
 static void save_raw_perf_callchain(struct perf_callchain_entry *entry,
 	unsigned long reg29)
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index a72e7247..498dd85 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -1,5 +1,531 @@
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) || \
-    defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_SB1)
+/*
+ * Linux performance counter support for MIPS.
+ *
+ * Copyright (C) 2010 MIPS Technologies, Inc.
+ * Author: Deng-Cheng Zhu
+ *
+ * This code is based on the implementation for ARM, which is in turn
+ * based on the sparc64 perf event code and the x86 code. Performance
+ * counter access is based on the MIPS Oprofile code. And the callchain
+ * support references the code of MIPS stacktrace.c.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/uaccess.h>
+
+#include <asm/irq.h>
+#include <asm/irq_regs.h>
+#include <asm/stacktrace.h>
+#include <asm/time.h> /* For perf_irq */
+
+/* These are for 32bit counters. For 64bit ones, define them accordingly. */
+#define MAX_PERIOD	((1ULL << 32) - 1)
+#define VALID_COUNT	0x7fffffff
+#define TOTAL_BITS	32
+#define HIGHEST_BIT	31
+
+#define MIPS_MAX_HWEVENTS 4
+
+struct cpu_hw_events {
+	/* Array of events on this cpu. */
+	struct perf_event	*events[MIPS_MAX_HWEVENTS];
+
+	/*
+	 * Set the bit (indexed by the counter number) when the counter
+	 * is used for an event.
+	 */
+	unsigned long		used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
+
+	/*
+	 * The borrowed MSB for the performance counter. A MIPS performance
+	 * counter uses its bit 31 (for 32bit counters) or bit 63 (for 64bit
+	 * counters) as a factor of determining whether a counter overflow
+	 * should be signaled. So here we use a separate MSB for each
+	 * counter to make things easy.
+	 */
+	unsigned long		msbs[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
+
+	/*
+	 * Software copy of the control register for each performance counter.
+	 * MIPS CPUs vary in performance counters. They use this differently,
+	 * and even may not use it.
+	 */
+	unsigned int		saved_ctrl[MIPS_MAX_HWEVENTS];
+};
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
+	.saved_ctrl = {0},
+};
+
+/* The description of MIPS performance events. */
+struct mips_perf_event {
+	unsigned int event_id;
+	/*
+	 * MIPS performance counters are indexed starting from 0.
+	 * CNTR_EVEN indicates the indexes of the counters to be used are
+	 * even numbers.
+	 */
+	unsigned int cntr_mask;
+	#define CNTR_EVEN	0x55555555
+	#define CNTR_ODD	0xaaaaaaaa
+#ifdef CONFIG_MIPS_MT_SMP
+	enum {
+		T  = 0,
+		V  = 1,
+		P  = 2,
+	} range;
+#else
+	#define T
+	#define V
+	#define P
+#endif
+};
+
+static struct mips_perf_event raw_event;
+static DEFINE_MUTEX(raw_event_mutex);
+
+#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+struct mips_pmu {
+	const char	*name;
+	int		irq;
+	irqreturn_t	(*handle_irq)(int irq, void *dev);
+	int		(*handle_shared_irq)(void);
+	void		(*start)(void);
+	void		(*stop)(void);
+	int		(*alloc_counter)(struct cpu_hw_events *cpuc,
+					struct hw_perf_event *hwc);
+	u64		(*read_counter)(unsigned int idx);
+	void		(*write_counter)(unsigned int idx, u64 val);
+	void		(*enable_event)(struct hw_perf_event *evt, int idx);
+	void		(*disable_event)(int idx);
+	const struct mips_perf_event *(*map_raw_event)(u64 config);
+	const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX];
+	const struct mips_perf_event (*cache_event_map)
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX];
+	unsigned int	num_counters;
+};
+
+static const struct mips_pmu *mipspmu;
+
+static int mipspmu_event_set_period(struct perf_event *event,
+				    struct hw_perf_event *hwc,
+				    int idx)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	s64 left = local64_read(&hwc->period_left);
+	s64 period = hwc->sample_period;
+	int ret = 0;
+	u64 uleft;
+	unsigned long flags;
+
+	if (unlikely(left <= -period)) {
+		left = period;
+		local64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+
+	if (unlikely(left <= 0)) {
+		left += period;
+		local64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+
+	if (left > (s64)MAX_PERIOD)
+		left = MAX_PERIOD;
+
+	local64_set(&hwc->prev_count, (u64)-left);
+
+	local_irq_save(flags);
+	uleft = (u64)(-left) & MAX_PERIOD;
+	uleft > VALID_COUNT ?
+		set_bit(idx, cpuc->msbs) : clear_bit(idx, cpuc->msbs);
+	mipspmu->write_counter(idx, (u64)(-left) & VALID_COUNT);
+	local_irq_restore(flags);
+
+	perf_event_update_userpage(event);
+
+	return ret;
+}
+
+static void mipspmu_event_update(struct perf_event *event,
+				 struct hw_perf_event *hwc,
+				 int idx)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	unsigned long flags;
+	int shift = 64 - TOTAL_BITS;
+	s64 prev_raw_count, new_raw_count;
+	u64 delta;
+
+again:
+	prev_raw_count = local64_read(&hwc->prev_count);
+	local_irq_save(flags);
+	/* Make the counter value be a "real" one. */
+	new_raw_count = mipspmu->read_counter(idx);
+	if (new_raw_count & (test_bit(idx, cpuc->msbs) << HIGHEST_BIT)) {
+		new_raw_count &= VALID_COUNT;
+		clear_bit(idx, cpuc->msbs);
+	} else
+		new_raw_count |= (test_bit(idx, cpuc->msbs) << HIGHEST_BIT);
+	local_irq_restore(flags);
+
+	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+				new_raw_count) != prev_raw_count)
+		goto again;
+
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	local64_add(delta, &event->count);
+	local64_sub(delta, &hwc->period_left);
+
+	return;
+}
+
+static void mipspmu_start(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (!mipspmu)
+		return;
+
+	if (flags & PERF_EF_RELOAD)
+		WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+
+	hwc->state = 0;
+
+	/* Set the period for the event. */
+	mipspmu_event_set_period(event, hwc, hwc->idx);
+
+	/* Enable the event. */
+	mipspmu->enable_event(hwc, hwc->idx);
+}
+
+static void mipspmu_stop(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (!mipspmu)
+		return;
+
+	if (!(hwc->state & PERF_HES_STOPPED)) {
+		/* We are working on a local event. */
+		mipspmu->disable_event(hwc->idx);
+		barrier();
+		mipspmu_event_update(event, hwc, hwc->idx);
+		hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
+	}
+}
+
+static int mipspmu_add(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+	int err = 0;
+
+	perf_pmu_disable(event->pmu);
+
+	/* To look for a free counter for this event. */
+	idx = mipspmu->alloc_counter(cpuc, hwc);
+	if (idx < 0) {
+		err = idx;
+		goto out;
+	}
+
+	/*
+	 * If there is an event in the counter we are going to use then
+	 * make sure it is disabled.
+	 */
+	event->hw.idx = idx;
+	mipspmu->disable_event(idx);
+	cpuc->events[idx] = event;
+
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+	if (flags & PERF_EF_START)
+		mipspmu_start(event, PERF_EF_RELOAD);
+
+	/* Propagate our changes to the userspace mapping. */
+	perf_event_update_userpage(event);
+
+out:
+	perf_pmu_enable(event->pmu);
+	return err;
+}
+
+static void mipspmu_del(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+
+	mipspmu_stop(event, PERF_EF_UPDATE);
+	cpuc->events[idx] = NULL;
+	clear_bit(idx, cpuc->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+static void mipspmu_read(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	/* Don't read disabled counters! */
+	if (hwc->idx < 0)
+		return;
+
+	mipspmu_event_update(event, hwc, hwc->idx);
+}
+
+static void mipspmu_enable(struct pmu *pmu)
+{
+	if (mipspmu)
+		mipspmu->start();
+}
+
+static void mipspmu_disable(struct pmu *pmu)
+{
+	if (mipspmu)
+		mipspmu->stop();
+}
+
+static atomic_t active_events = ATOMIC_INIT(0);
+static DEFINE_MUTEX(pmu_reserve_mutex);
+static int (*save_perf_irq)(void);
+
+static int mipspmu_get_irq(void)
+{
+	int err;
+
+	if (mipspmu->irq >= 0) {
+		/* Request my own irq handler. */
+		err = request_irq(mipspmu->irq, mipspmu->handle_irq,
+			IRQF_DISABLED | IRQF_NOBALANCING,
+			"mips_perf_pmu", NULL);
+		if (err) {
+			pr_warning("Unable to request IRQ%d for MIPS "
+			   "performance counters!\n", mipspmu->irq);
+		}
+	} else if (cp0_perfcount_irq < 0) {
+		/*
+		 * We are sharing the irq number with the timer interrupt.
+		 */
+		save_perf_irq = perf_irq;
+		perf_irq = mipspmu->handle_shared_irq;
+		err = 0;
+	} else {
+		pr_warning("The platform hasn't properly defined its "
+			"interrupt controller.\n");
+		err = -ENOENT;
+	}
+
+	return err;
+}
+
+static void mipspmu_free_irq(void)
+{
+	if (mipspmu->irq >= 0)
+		free_irq(mipspmu->irq, NULL);
+	else if (cp0_perfcount_irq < 0)
+		perf_irq = save_perf_irq;
+}
+
+/*
+ * mipsxx/rm9000/loongson2 have different performance counters, they have
+ * specific low-level init routines.
+ */
+static void reset_counters(void *arg);
+static int __hw_perf_event_init(struct perf_event *event);
+
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+	if (atomic_dec_and_mutex_lock(&active_events,
+				&pmu_reserve_mutex)) {
+		/*
+		 * We must not call the destroy function with interrupts
+		 * disabled.
+		 */
+		on_each_cpu(reset_counters,
+			(void *)(long)mipspmu->num_counters, 1);
+		mipspmu_free_irq();
+		mutex_unlock(&pmu_reserve_mutex);
+	}
+}
+
+static int mipspmu_event_init(struct perf_event *event)
+{
+	int err = 0;
+
+	switch (event->attr.type) {
+	case PERF_TYPE_RAW:
+	case PERF_TYPE_HARDWARE:
+	case PERF_TYPE_HW_CACHE:
+		break;
+
+	default:
+		return -ENOENT;
+	}
+
+	if (!mipspmu || event->cpu >= nr_cpumask_bits ||
+		(event->cpu >= 0 && !cpu_online(event->cpu)))
+		return -ENODEV;
+
+	if (!atomic_inc_not_zero(&active_events)) {
+		if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) {
+			atomic_dec(&active_events);
+			return -ENOSPC;
+		}
+
+		mutex_lock(&pmu_reserve_mutex);
+		if (atomic_read(&active_events) == 0)
+			err = mipspmu_get_irq();
+
+		if (!err)
+			atomic_inc(&active_events);
+		mutex_unlock(&pmu_reserve_mutex);
+	}
+
+	if (err)
+		return err;
+
+	err = __hw_perf_event_init(event);
+	if (err)
+		hw_perf_event_destroy(event);
+
+	return err;
+}
+
+static struct pmu pmu = {
+	.pmu_enable	= mipspmu_enable,
+	.pmu_disable	= mipspmu_disable,
+	.event_init	= mipspmu_event_init,
+	.add		= mipspmu_add,
+	.del		= mipspmu_del,
+	.start		= mipspmu_start,
+	.stop		= mipspmu_stop,
+	.read		= mipspmu_read,
+};
+
+static unsigned int mipspmu_perf_event_encode(const struct mips_perf_event *pev)
+{
+/*
+ * Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for
+ * event_id.
+ */
+#ifdef CONFIG_MIPS_MT_SMP
+	return ((unsigned int)pev->range << 24) |
+		(pev->cntr_mask & 0xffff00) |
+		(pev->event_id & 0xff);
+#else
+	return (pev->cntr_mask & 0xffff00) |
+		(pev->event_id & 0xff);
+#endif
+}
+
+static const struct mips_perf_event *mipspmu_map_general_event(int idx)
+{
+	const struct mips_perf_event *pev;
+
+	pev = ((*mipspmu->general_event_map)[idx].event_id ==
+		UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) :
+		&(*mipspmu->general_event_map)[idx]);
+
+	return pev;
+}
+
+static const struct mips_perf_event *mipspmu_map_cache_event(u64 config)
+{
+	unsigned int cache_type, cache_op, cache_result;
+	const struct mips_perf_event *pev;
+
+	cache_type = (config >> 0) & 0xff;
+	if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+		return ERR_PTR(-EINVAL);
+
+	cache_op = (config >> 8) & 0xff;
+	if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+		return ERR_PTR(-EINVAL);
+
+	cache_result = (config >> 16) & 0xff;
+	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+		return ERR_PTR(-EINVAL);
+
+	pev = &((*mipspmu->cache_event_map)
+					[cache_type]
+					[cache_op]
+					[cache_result]);
+
+	if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID)
+		return ERR_PTR(-EOPNOTSUPP);
+
+	return pev;
+
+}
+
+static int validate_event(struct cpu_hw_events *cpuc,
+	       struct perf_event *event)
+{
+	struct hw_perf_event fake_hwc = event->hw;
+
+	/* Allow mixed event group. So return 1 to pass validation. */
+	if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF)
+		return 1;
+
+	return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0;
+}
+
+static int validate_group(struct perf_event *event)
+{
+	struct perf_event *sibling, *leader = event->group_leader;
+	struct cpu_hw_events fake_cpuc;
+
+	memset(&fake_cpuc, 0, sizeof(fake_cpuc));
+
+	if (!validate_event(&fake_cpuc, leader))
+		return -ENOSPC;
+
+	list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+		if (!validate_event(&fake_cpuc, sibling))
+			return -ENOSPC;
+	}
+
+	if (!validate_event(&fake_cpuc, event))
+		return -ENOSPC;
+
+	return 0;
+}
+
+/* This is needed by specific irq handlers in perf_event_*.c */
+static void handle_associated_event(struct cpu_hw_events *cpuc,
+				    int idx, struct perf_sample_data *data,
+				    struct pt_regs *regs)
+{
+	struct perf_event *event = cpuc->events[idx];
+	struct hw_perf_event *hwc = &event->hw;
+
+	mipspmu_event_update(event, hwc, idx);
+	data->period = event->hw.last_period;
+	if (!mipspmu_event_set_period(event, hwc, idx))
+		return;
+
+	if (perf_event_overflow(event, 0, data, regs))
+		mipspmu->disable_event(idx);
+}
 
 #define M_CONFIG1_PC	(1 << 4)
 
@@ -1034,5 +1560,3 @@ init_hw_perf_events(void)
 	return 0;
 }
 arch_initcall(init_hw_perf_events);
-
-#endif /* defined(CONFIG_CPU_MIPS32)... */
-- 
1.7.2.3


From David.Daney@caviumnetworks.com Fri Jan  7 03:37:27 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 03:37:32 +0100 (CET)
Received: from mail3.caviumnetworks.com ([12.108.191.235]:13406 "EHLO
        mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491014Ab1AGCfh (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 03:35:37 +0100
Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,7,2,8378)
        id <B4d267c260000>; Thu, 06 Jan 2011 18:36:22 -0800
Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:35 -0800
Received: from dd1.caveonetworks.com ([12.108.191.236]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:35 -0800
Received: from dd1.caveonetworks.com (localhost.localdomain [127.0.0.1])
        by dd1.caveonetworks.com (8.14.4/8.14.3) with ESMTP id p072ZWgx002659;
        Thu, 6 Jan 2011 18:35:32 -0800
Received: (from ddaney@localhost)
        by dd1.caveonetworks.com (8.14.4/8.14.4/Submit) id p072ZVnj002658;
        Thu, 6 Jan 2011 18:35:31 -0800
From:   David Daney <ddaney@caviumnetworks.com>
To:     linux-mips@linux-mips.org, ralf@linux-mips.org,
        linux-kernel@vger.kernel.org
Cc:     David Daney <ddaney@caviumnetworks.com>,
        Peter Zijlstra <a.p.zijlstra@chello.nl>,
        Paul Mackerras <paulus@samba.org>, Ingo Molnar <mingo@elte.hu>,
        Arnaldo Carvalho de Melo <acme@redhat.com>,
        Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Subject: [PATCH 6/6] MIPS: perf: Add Octeon support for hardware perf.
Date:   Thu,  6 Jan 2011 18:35:07 -0800
Message-Id: <1294367707-2593-7-git-send-email-ddaney@caviumnetworks.com>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
References: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
X-OriginalArrivalTime: 07 Jan 2011 02:35:35.0188 (UTC) FILETIME=[8FE3E540:01CBAE13]
Return-Path: <David.Daney@caviumnetworks.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: 28877
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: ddaney@caviumnetworks.com
Precedence: bulk
X-list: linux-mips

Enable hardware counters for Octeon, and add the corresponding event
mappings.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
---
 arch/mips/Kconfig                    |    2 +-
 arch/mips/kernel/perf_event_mipsxx.c |  147 ++++++++++++++++++++++++++++++++++
 2 files changed, 148 insertions(+), 1 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 88aaec2..6694f23 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2016,7 +2016,7 @@ config NODES_SHIFT
 
 config HW_PERF_EVENTS
 	bool "Enable hardware performance counter support for perf events"
-	depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1)
+	depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON)
 	default y
 	help
 	  Enable hardware performance counter support for perf events. If
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index 9bdac86..527b1b9 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -850,6 +850,16 @@ static const struct mips_perf_event mipsxx74Kcore_event_map
 	[PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
 };
 
+static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL },
+	[PERF_COUNT_HW_INSTRUCTIONS] = { 0x03, CNTR_ALL },
+	[PERF_COUNT_HW_CACHE_REFERENCES] = { 0x2b, CNTR_ALL },
+	[PERF_COUNT_HW_CACHE_MISSES] = { 0x2e, CNTR_ALL  },
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x08, CNTR_ALL },
+	[PERF_COUNT_HW_BRANCH_MISSES] = { 0x09, CNTR_ALL },
+	[PERF_COUNT_HW_BUS_CYCLES] = { 0x25, CNTR_ALL },
+};
+
 /* 24K/34K/1004K cores can share the same cache event map. */
 static const struct mips_perf_event mipsxxcore_cache_map
 				[PERF_COUNT_HW_CACHE_MAX]
@@ -1055,6 +1065,102 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
 },
 };
 
+
+static const struct mips_perf_event octeon_cache_map
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { 0x2b, CNTR_ALL },
+		[C(RESULT_MISS)]	= { 0x2e, CNTR_ALL },
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { 0x30, CNTR_ALL },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(L1I)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { 0x18, CNTR_ALL },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { 0x19, CNTR_ALL },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(LL)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(DTLB)] = {
+	/*
+	 * Only general DTLB misses are counted use the same event for
+	 * read and write.
+	 */
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { 0x35, CNTR_ALL },
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { 0x35, CNTR_ALL },
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(ITLB)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { 0x37, CNTR_ALL },
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(BPU)] = {
+	/* Using the same code for *HW_BRANCH* */
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+};
+
 #ifdef CONFIG_MIPS_MT_SMP
 static void check_and_calc_range(struct perf_event *event,
 				 const struct mips_perf_event *pev)
@@ -1397,6 +1503,39 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
 	return &raw_event;
 }
 
+static const struct mips_perf_event *octeon_pmu_map_raw_event(u64 config)
+{
+	unsigned int raw_id = config & 0xff;
+	unsigned int base_id = raw_id & 0x7f;
+
+
+	raw_event.cntr_mask = CNTR_ALL;
+	raw_event.event_id = base_id;
+
+	if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
+		if (base_id > 0x42)
+			return ERR_PTR(-EOPNOTSUPP);
+	} else {
+		if (base_id > 0x3a)
+			return ERR_PTR(-EOPNOTSUPP);
+	}
+
+	switch (base_id) {
+	case 0x00:
+	case 0x0f:
+	case 0x1e:
+	case 0x1f:
+	case 0x2f:
+	case 0x34:
+	case 0x3b ... 0x3f:
+		return ERR_PTR(-EOPNOTSUPP);
+	default:
+		break;
+	}
+
+	return &raw_event;
+}
+
 static int __init
 init_hw_perf_events(void)
 {
@@ -1456,6 +1595,14 @@ init_hw_perf_events(void)
 		mipspmu.general_event_map = &mipsxxcore_event_map;
 		mipspmu.cache_event_map = &mipsxxcore_cache_map;
 		break;
+	case CPU_CAVIUM_OCTEON:
+	case CPU_CAVIUM_OCTEON_PLUS:
+	case CPU_CAVIUM_OCTEON2:
+		mipspmu.name = "octeon";
+		mipspmu.general_event_map = &octeon_event_map;
+		mipspmu.cache_event_map = &octeon_cache_map;
+		mipspmu.map_raw_event = octeon_pmu_map_raw_event;
+		break;
 	default:
 		pr_cont("Either hardware does not support performance "
 			"counters, or not yet implemented.\n");
-- 
1.7.2.3


From David.Daney@caviumnetworks.com Fri Jan  7 03:37:51 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 03:37:59 +0100 (CET)
Received: from mail3.caviumnetworks.com ([12.108.191.235]:13411 "EHLO
        mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491015Ab1AGCfh (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 03:35:37 +0100
Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,7,2,8378)
        id <B4d267c260001>; Thu, 06 Jan 2011 18:36:22 -0800
Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:35 -0800
Received: from dd1.caveonetworks.com ([12.108.191.236]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675);
         Thu, 6 Jan 2011 18:35:35 -0800
Received: from dd1.caveonetworks.com (localhost.localdomain [127.0.0.1])
        by dd1.caveonetworks.com (8.14.4/8.14.3) with ESMTP id p072ZUrq002654;
        Thu, 6 Jan 2011 18:35:30 -0800
Received: (from ddaney@localhost)
        by dd1.caveonetworks.com (8.14.4/8.14.4/Submit) id p072ZSc2002652;
        Thu, 6 Jan 2011 18:35:28 -0800
From:   David Daney <ddaney@caviumnetworks.com>
To:     linux-mips@linux-mips.org, ralf@linux-mips.org,
        linux-kernel@vger.kernel.org
Cc:     David Daney <ddaney@caviumnetworks.com>,
        Peter Zijlstra <a.p.zijlstra@chello.nl>,
        Paul Mackerras <paulus@samba.org>, Ingo Molnar <mingo@elte.hu>,
        Arnaldo Carvalho de Melo <acme@redhat.com>,
        Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Subject: [PATCH 5/6] MIPS: perf: Add support for 64-bit perf counters.
Date:   Thu,  6 Jan 2011 18:35:06 -0800
Message-Id: <1294367707-2593-6-git-send-email-ddaney@caviumnetworks.com>
X-Mailer: git-send-email 1.7.2.3
In-Reply-To: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
References: <1294367707-2593-1-git-send-email-ddaney@caviumnetworks.com>
X-OriginalArrivalTime: 07 Jan 2011 02:35:35.0188 (UTC) FILETIME=[8FE3E540:01CBAE13]
Return-Path: <David.Daney@caviumnetworks.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: 28878
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: ddaney@caviumnetworks.com
Precedence: bulk
X-list: linux-mips

The hard coded constants are moved to struct mips_pmu.  All counter
register access move to the read_counter and write_counter function
pointers, which are set to either 32-bit or 64-bit access methods at
initialization time.

Many of the function pointers in struct mips_pmu were not needed as
there was only a single implementation, these were removed.

I couldn't figure out what made struct cpu_hw_events.msbs[] at all
useful, so I removed it too.

Some functions and other declarations were reordered to reduce the
need for forward declarations.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
---
 arch/mips/kernel/perf_event_mipsxx.c |  838 ++++++++++++++++------------------
 1 files changed, 385 insertions(+), 453 deletions(-)

diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index 498dd85..9bdac86 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -2,6 +2,7 @@
  * Linux performance counter support for MIPS.
  *
  * Copyright (C) 2010 MIPS Technologies, Inc.
+ * Copyright (C) 2011 Cavium Networks, Inc.
  * Author: Deng-Cheng Zhu
  *
  * This code is based on the implementation for ARM, which is in turn
@@ -26,12 +27,6 @@
 #include <asm/stacktrace.h>
 #include <asm/time.h> /* For perf_irq */
 
-/* These are for 32bit counters. For 64bit ones, define them accordingly. */
-#define MAX_PERIOD	((1ULL << 32) - 1)
-#define VALID_COUNT	0x7fffffff
-#define TOTAL_BITS	32
-#define HIGHEST_BIT	31
-
 #define MIPS_MAX_HWEVENTS 4
 
 struct cpu_hw_events {
@@ -45,15 +40,6 @@ struct cpu_hw_events {
 	unsigned long		used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
 
 	/*
-	 * The borrowed MSB for the performance counter. A MIPS performance
-	 * counter uses its bit 31 (for 32bit counters) or bit 63 (for 64bit
-	 * counters) as a factor of determining whether a counter overflow
-	 * should be signaled. So here we use a separate MSB for each
-	 * counter to make things easy.
-	 */
-	unsigned long		msbs[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
-
-	/*
 	 * Software copy of the control register for each performance counter.
 	 * MIPS CPUs vary in performance counters. They use this differently,
 	 * and even may not use it.
@@ -75,6 +61,7 @@ struct mips_perf_event {
 	unsigned int cntr_mask;
 	#define CNTR_EVEN	0x55555555
 	#define CNTR_ODD	0xaaaaaaaa
+	#define CNTR_ALL	0xffffffff
 #ifdef CONFIG_MIPS_MT_SMP
 	enum {
 		T  = 0,
@@ -95,18 +82,13 @@ static DEFINE_MUTEX(raw_event_mutex);
 #define C(x) PERF_COUNT_HW_CACHE_##x
 
 struct mips_pmu {
+	u64		max_period;
+	u64		valid_count;
+	u64		overflow;
 	const char	*name;
 	int		irq;
-	irqreturn_t	(*handle_irq)(int irq, void *dev);
-	int		(*handle_shared_irq)(void);
-	void		(*start)(void);
-	void		(*stop)(void);
-	int		(*alloc_counter)(struct cpu_hw_events *cpuc,
-					struct hw_perf_event *hwc);
 	u64		(*read_counter)(unsigned int idx);
 	void		(*write_counter)(unsigned int idx, u64 val);
-	void		(*enable_event)(struct hw_perf_event *evt, int idx);
-	void		(*disable_event)(int idx);
 	const struct mips_perf_event *(*map_raw_event)(u64 config);
 	const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX];
 	const struct mips_perf_event (*cache_event_map)
@@ -116,43 +98,300 @@ struct mips_pmu {
 	unsigned int	num_counters;
 };
 
-static const struct mips_pmu *mipspmu;
+static struct mips_pmu mipspmu;
+
+#define M_CONFIG1_PC	(1 << 4)
+
+#define M_PERFCTL_EXL			(1      <<  0)
+#define M_PERFCTL_KERNEL		(1      <<  1)
+#define M_PERFCTL_SUPERVISOR		(1      <<  2)
+#define M_PERFCTL_USER			(1      <<  3)
+#define M_PERFCTL_INTERRUPT_ENABLE	(1      <<  4)
+#define M_PERFCTL_EVENT(event)		(((event) & 0x3ff)  << 5)
+#define M_PERFCTL_VPEID(vpe)		((vpe)    << 16)
+#define M_PERFCTL_MT_EN(filter)		((filter) << 20)
+#define    M_TC_EN_ALL			M_PERFCTL_MT_EN(0)
+#define    M_TC_EN_VPE			M_PERFCTL_MT_EN(1)
+#define    M_TC_EN_TC			M_PERFCTL_MT_EN(2)
+#define M_PERFCTL_TCID(tcid)		((tcid)   << 22)
+#define M_PERFCTL_WIDE			(1      << 30)
+#define M_PERFCTL_MORE			(1      << 31)
+
+#define M_PERFCTL_COUNT_EVENT_WHENEVER	(M_PERFCTL_EXL |		\
+					M_PERFCTL_KERNEL |		\
+					M_PERFCTL_USER |		\
+					M_PERFCTL_SUPERVISOR |		\
+					M_PERFCTL_INTERRUPT_ENABLE)
+
+#ifdef CONFIG_MIPS_MT_SMP
+#define M_PERFCTL_CONFIG_MASK		0x3fff801f
+#else
+#define M_PERFCTL_CONFIG_MASK		0x1f
+#endif
+#define M_PERFCTL_EVENT_MASK		0xfe0
+
+
+#ifdef CONFIG_MIPS_MT_SMP
+static int cpu_has_mipsmt_pertccounters;
+
+/*
+ * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because
+ * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs.
+ */
+#if defined(CONFIG_HW_PERF_EVENTS)
+#define vpe_id()	(cpu_has_mipsmt_pertccounters ? \
+			0 : smp_processor_id())
+#else
+#define vpe_id()	(cpu_has_mipsmt_pertccounters ? \
+			0 : cpu_data[smp_processor_id()].vpe_id)
+#endif
+
+/* Copied from op_model_mipsxx.c */
+static unsigned int vpe_shift(void)
+{
+	if (num_possible_cpus() > 1)
+		return 1;
+
+	return 0;
+}
+
+static unsigned int counters_total_to_per_cpu(unsigned int counters)
+{
+	return counters >> vpe_shift();
+}
+
+static unsigned int counters_per_cpu_to_total(unsigned int counters)
+{
+	return counters << vpe_shift();
+}
+
+#else /* !CONFIG_MIPS_MT_SMP */
+#define vpe_id()	0
+
+#endif /* CONFIG_MIPS_MT_SMP */
+
+static void resume_local_counters(void);
+static void pause_local_counters(void);
+static irqreturn_t mipsxx_pmu_handle_irq(int, void *);
+static int mipsxx_pmu_handle_shared_irq(void);
+
+static unsigned int mipsxx_pmu_swizzle_perf_idx(unsigned int idx)
+{
+	if (vpe_id() == 1)
+		idx = (idx + 2) & 3;
+	return idx;
+}
+
+static u64 mipsxx_pmu_read_counter(unsigned int idx)
+{
+	idx = mipsxx_pmu_swizzle_perf_idx(idx);
+
+	switch (idx) {
+	case 0:
+		return read_c0_perfcntr0();
+	case 1:
+		return read_c0_perfcntr1();
+	case 2:
+		return read_c0_perfcntr2();
+	case 3:
+		return read_c0_perfcntr3();
+	default:
+		WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
+		return 0;
+	}
+}
+
+static u64 mipsxx_pmu_read_counter_64(unsigned int idx)
+{
+	idx = mipsxx_pmu_swizzle_perf_idx(idx);
+
+	switch (idx) {
+	case 0:
+		return read_c0_perfcntr0_64();
+	case 1:
+		return read_c0_perfcntr1_64();
+	case 2:
+		return read_c0_perfcntr2_64();
+	case 3:
+		return read_c0_perfcntr3_64();
+	default:
+		WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
+		return 0;
+	}
+}
+
+static void mipsxx_pmu_write_counter(unsigned int idx, u64 val)
+{
+	idx = mipsxx_pmu_swizzle_perf_idx(idx);
+
+	switch (idx) {
+	case 0:
+		write_c0_perfcntr0(val);
+		return;
+	case 1:
+		write_c0_perfcntr1(val);
+		return;
+	case 2:
+		write_c0_perfcntr2(val);
+		return;
+	case 3:
+		write_c0_perfcntr3(val);
+		return;
+	}
+}
+
+static void mipsxx_pmu_write_counter_64(unsigned int idx, u64 val)
+{
+	idx = mipsxx_pmu_swizzle_perf_idx(idx);
+
+	switch (idx) {
+	case 0:
+		write_c0_perfcntr0_64(val);
+		return;
+	case 1:
+		write_c0_perfcntr1_64(val);
+		return;
+	case 2:
+		write_c0_perfcntr2_64(val);
+		return;
+	case 3:
+		write_c0_perfcntr3_64(val);
+		return;
+	}
+}
+
+static unsigned int mipsxx_pmu_read_control(unsigned int idx)
+{
+	idx = mipsxx_pmu_swizzle_perf_idx(idx);
+
+	switch (idx) {
+	case 0:
+		return read_c0_perfctrl0();
+	case 1:
+		return read_c0_perfctrl1();
+	case 2:
+		return read_c0_perfctrl2();
+	case 3:
+		return read_c0_perfctrl3();
+	default:
+		WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
+		return 0;
+	}
+}
+
+static void mipsxx_pmu_write_control(unsigned int idx, unsigned int val)
+{
+	idx = mipsxx_pmu_swizzle_perf_idx(idx);
+
+	switch (idx) {
+	case 0:
+		write_c0_perfctrl0(val);
+		return;
+	case 1:
+		write_c0_perfctrl1(val);
+		return;
+	case 2:
+		write_c0_perfctrl2(val);
+		return;
+	case 3:
+		write_c0_perfctrl3(val);
+		return;
+	}
+}
+
+static int mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc,
+				    struct hw_perf_event *hwc)
+{
+	int i;
+
+	/*
+	 * We only need to care the counter mask. The range has been
+	 * checked definitely.
+	 */
+	unsigned long cntr_mask = (hwc->event_base >> 8) & 0xffff;
+
+	for (i = mipspmu.num_counters - 1; i >= 0; i--) {
+		/*
+		 * Note that some MIPS perf events can be counted by both
+		 * even and odd counters, wheresas many other are only by
+		 * even _or_ odd counters. This introduces an issue that
+		 * when the former kind of event takes the counter the
+		 * latter kind of event wants to use, then the "counter
+		 * allocation" for the latter event will fail. In fact if
+		 * they can be dynamically swapped, they both feel happy.
+		 * But here we leave this issue alone for now.
+		 */
+		if (test_bit(i, &cntr_mask) &&
+			!test_and_set_bit(i, cpuc->used_mask))
+			return i;
+	}
+
+	return -EAGAIN;
+}
+
+static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	unsigned long flags;
+
+	WARN_ON(idx < 0 || idx >= mipspmu.num_counters);
+
+	local_irq_save(flags);
+	cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) |
+		(evt->config_base & M_PERFCTL_CONFIG_MASK) |
+		/* Make sure interrupt enabled. */
+		M_PERFCTL_INTERRUPT_ENABLE;
+	/*
+	 * We do not actually let the counter run. Leave it until start().
+	 */
+	local_irq_restore(flags);
+}
+
+static void mipsxx_pmu_disable_event(int idx)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	unsigned long flags;
+
+	WARN_ON(idx < 0 || idx >= mipspmu.num_counters);
+
+	local_irq_save(flags);
+	cpuc->saved_ctrl[idx] = mipsxx_pmu_read_control(idx) &
+		~M_PERFCTL_COUNT_EVENT_WHENEVER;
+	mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]);
+	local_irq_restore(flags);
+}
 
 static int mipspmu_event_set_period(struct perf_event *event,
 				    struct hw_perf_event *hwc,
 				    int idx)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	s64 left = local64_read(&hwc->period_left);
-	s64 period = hwc->sample_period;
+	u64 left = local64_read(&hwc->period_left);
+	u64 period = hwc->sample_period;
 	int ret = 0;
-	u64 uleft;
 	unsigned long flags;
 
-	if (unlikely(left <= -period)) {
+	if (unlikely((left + period) & (1ULL << 63))) {
 		left = period;
 		local64_set(&hwc->period_left, left);
 		hwc->last_period = period;
 		ret = 1;
 	}
 
-	if (unlikely(left <= 0)) {
+
+	if (unlikely((left + period) <= period)) {
 		left += period;
 		local64_set(&hwc->period_left, left);
 		hwc->last_period = period;
 		ret = 1;
 	}
 
-	if (left > (s64)MAX_PERIOD)
-		left = MAX_PERIOD;
+	if (left > mipspmu.max_period)
+		left = mipspmu.max_period;
 
-	local64_set(&hwc->prev_count, (u64)-left);
+	local64_set(&hwc->prev_count, mipspmu.overflow - left);
 
 	local_irq_save(flags);
-	uleft = (u64)(-left) & MAX_PERIOD;
-	uleft > VALID_COUNT ?
-		set_bit(idx, cpuc->msbs) : clear_bit(idx, cpuc->msbs);
-	mipspmu->write_counter(idx, (u64)(-left) & VALID_COUNT);
+	mipspmu.write_counter(idx, mipspmu.overflow - left);
 	local_irq_restore(flags);
 
 	perf_event_update_userpage(event);
@@ -164,30 +403,22 @@ static void mipspmu_event_update(struct perf_event *event,
 				 struct hw_perf_event *hwc,
 				 int idx)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	unsigned long flags;
-	int shift = 64 - TOTAL_BITS;
-	s64 prev_raw_count, new_raw_count;
+	u64 prev_raw_count, new_raw_count;
 	u64 delta;
 
 again:
 	prev_raw_count = local64_read(&hwc->prev_count);
 	local_irq_save(flags);
 	/* Make the counter value be a "real" one. */
-	new_raw_count = mipspmu->read_counter(idx);
-	if (new_raw_count & (test_bit(idx, cpuc->msbs) << HIGHEST_BIT)) {
-		new_raw_count &= VALID_COUNT;
-		clear_bit(idx, cpuc->msbs);
-	} else
-		new_raw_count |= (test_bit(idx, cpuc->msbs) << HIGHEST_BIT);
+	new_raw_count = mipspmu.read_counter(idx);
 	local_irq_restore(flags);
 
 	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
 				new_raw_count) != prev_raw_count)
 		goto again;
 
-	delta = (new_raw_count << shift) - (prev_raw_count << shift);
-	delta >>= shift;
+	delta = new_raw_count - prev_raw_count;
 
 	local64_add(delta, &event->count);
 	local64_sub(delta, &hwc->period_left);
@@ -199,9 +430,6 @@ static void mipspmu_start(struct perf_event *event, int flags)
 {
 	struct hw_perf_event *hwc = &event->hw;
 
-	if (!mipspmu)
-		return;
-
 	if (flags & PERF_EF_RELOAD)
 		WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
 
@@ -211,19 +439,16 @@ static void mipspmu_start(struct perf_event *event, int flags)
 	mipspmu_event_set_period(event, hwc, hwc->idx);
 
 	/* Enable the event. */
-	mipspmu->enable_event(hwc, hwc->idx);
+	mipsxx_pmu_enable_event(hwc, hwc->idx);
 }
 
 static void mipspmu_stop(struct perf_event *event, int flags)
 {
 	struct hw_perf_event *hwc = &event->hw;
 
-	if (!mipspmu)
-		return;
-
 	if (!(hwc->state & PERF_HES_STOPPED)) {
 		/* We are working on a local event. */
-		mipspmu->disable_event(hwc->idx);
+		mipsxx_pmu_disable_event(hwc->idx);
 		barrier();
 		mipspmu_event_update(event, hwc, hwc->idx);
 		hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
@@ -240,7 +465,7 @@ static int mipspmu_add(struct perf_event *event, int flags)
 	perf_pmu_disable(event->pmu);
 
 	/* To look for a free counter for this event. */
-	idx = mipspmu->alloc_counter(cpuc, hwc);
+	idx = mipsxx_pmu_alloc_counter(cpuc, hwc);
 	if (idx < 0) {
 		err = idx;
 		goto out;
@@ -251,7 +476,7 @@ static int mipspmu_add(struct perf_event *event, int flags)
 	 * make sure it is disabled.
 	 */
 	event->hw.idx = idx;
-	mipspmu->disable_event(idx);
+	mipsxx_pmu_disable_event(idx);
 	cpuc->events[idx] = event;
 
 	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
@@ -272,7 +497,7 @@ static void mipspmu_del(struct perf_event *event, int flags)
 	struct hw_perf_event *hwc = &event->hw;
 	int idx = hwc->idx;
 
-	WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+	WARN_ON(idx < 0 || idx >= mipspmu.num_counters);
 
 	mipspmu_stop(event, PERF_EF_UPDATE);
 	cpuc->events[idx] = NULL;
@@ -294,14 +519,29 @@ static void mipspmu_read(struct perf_event *event)
 
 static void mipspmu_enable(struct pmu *pmu)
 {
-	if (mipspmu)
-		mipspmu->start();
+#ifdef CONFIG_MIPS_MT_SMP
+	write_unlock(&pmuint_rwlock);
+#endif
+	resume_local_counters();
 }
 
+/*
+ * MIPS performance counters can be per-TC. The control registers can
+ * not be directly accessed accross CPUs. Hence if we want to do global
+ * control, we need cross CPU calls. on_each_cpu() can help us, but we
+ * can not make sure this function is called with interrupts enabled. So
+ * here we pause local counters and then grab a rwlock and leave the
+ * counters on other CPUs alone. If any counter interrupt raises while
+ * we own the write lock, simply pause local counters on that CPU and
+ * spin in the handler. Also we know we won't be switched to another
+ * CPU after pausing local counters and before grabbing the lock.
+ */
 static void mipspmu_disable(struct pmu *pmu)
 {
-	if (mipspmu)
-		mipspmu->stop();
+	pause_local_counters();
+#ifdef CONFIG_MIPS_MT_SMP
+	write_lock(&pmuint_rwlock);
+#endif
 }
 
 static atomic_t active_events = ATOMIC_INIT(0);
@@ -312,21 +552,21 @@ static int mipspmu_get_irq(void)
 {
 	int err;
 
-	if (mipspmu->irq >= 0) {
+	if (mipspmu.irq >= 0) {
 		/* Request my own irq handler. */
-		err = request_irq(mipspmu->irq, mipspmu->handle_irq,
-			IRQF_DISABLED | IRQF_NOBALANCING,
+		err = request_irq(mipspmu.irq, mipsxx_pmu_handle_irq,
+			IRQF_PERCPU | IRQF_NOBALANCING,
 			"mips_perf_pmu", NULL);
 		if (err) {
 			pr_warning("Unable to request IRQ%d for MIPS "
-			   "performance counters!\n", mipspmu->irq);
+			   "performance counters!\n", mipspmu.irq);
 		}
 	} else if (cp0_perfcount_irq < 0) {
 		/*
 		 * We are sharing the irq number with the timer interrupt.
 		 */
 		save_perf_irq = perf_irq;
-		perf_irq = mipspmu->handle_shared_irq;
+		perf_irq = mipsxx_pmu_handle_shared_irq;
 		err = 0;
 	} else {
 		pr_warning("The platform hasn't properly defined its "
@@ -339,8 +579,8 @@ static int mipspmu_get_irq(void)
 
 static void mipspmu_free_irq(void)
 {
-	if (mipspmu->irq >= 0)
-		free_irq(mipspmu->irq, NULL);
+	if (mipspmu.irq >= 0)
+		free_irq(mipspmu.irq, NULL);
 	else if (cp0_perfcount_irq < 0)
 		perf_irq = save_perf_irq;
 }
@@ -361,7 +601,7 @@ static void hw_perf_event_destroy(struct perf_event *event)
 		 * disabled.
 		 */
 		on_each_cpu(reset_counters,
-			(void *)(long)mipspmu->num_counters, 1);
+			(void *)(long)mipspmu.num_counters, 1);
 		mipspmu_free_irq();
 		mutex_unlock(&pmu_reserve_mutex);
 	}
@@ -381,8 +621,8 @@ static int mipspmu_event_init(struct perf_event *event)
 		return -ENOENT;
 	}
 
-	if (!mipspmu || event->cpu >= nr_cpumask_bits ||
-		(event->cpu >= 0 && !cpu_online(event->cpu)))
+	if (event->cpu >= nr_cpumask_bits ||
+	    (event->cpu >= 0 && !cpu_online(event->cpu)))
 		return -ENODEV;
 
 	if (!atomic_inc_not_zero(&active_events)) {
@@ -441,9 +681,9 @@ static const struct mips_perf_event *mipspmu_map_general_event(int idx)
 {
 	const struct mips_perf_event *pev;
 
-	pev = ((*mipspmu->general_event_map)[idx].event_id ==
+	pev = ((*mipspmu.general_event_map)[idx].event_id ==
 		UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) :
-		&(*mipspmu->general_event_map)[idx]);
+		&(*mipspmu.general_event_map)[idx]);
 
 	return pev;
 }
@@ -465,7 +705,7 @@ static const struct mips_perf_event *mipspmu_map_cache_event(u64 config)
 	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
 		return ERR_PTR(-EINVAL);
 
-	pev = &((*mipspmu->cache_event_map)
+	pev = &((*mipspmu.cache_event_map)
 					[cache_type]
 					[cache_op]
 					[cache_result]);
@@ -486,7 +726,7 @@ static int validate_event(struct cpu_hw_events *cpuc,
 	if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF)
 		return 1;
 
-	return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0;
+	return mipsxx_pmu_alloc_counter(cpuc, &fake_hwc) >= 0;
 }
 
 static int validate_group(struct perf_event *event)
@@ -524,123 +764,9 @@ static void handle_associated_event(struct cpu_hw_events *cpuc,
 		return;
 
 	if (perf_event_overflow(event, 0, data, regs))
-		mipspmu->disable_event(idx);
-}
-
-#define M_CONFIG1_PC	(1 << 4)
-
-#define M_PERFCTL_EXL			(1UL      <<  0)
-#define M_PERFCTL_KERNEL		(1UL      <<  1)
-#define M_PERFCTL_SUPERVISOR		(1UL      <<  2)
-#define M_PERFCTL_USER			(1UL      <<  3)
-#define M_PERFCTL_INTERRUPT_ENABLE	(1UL      <<  4)
-#define M_PERFCTL_EVENT(event)		(((event) & 0x3ff)  << 5)
-#define M_PERFCTL_VPEID(vpe)		((vpe)    << 16)
-#define M_PERFCTL_MT_EN(filter)		((filter) << 20)
-#define    M_TC_EN_ALL			M_PERFCTL_MT_EN(0)
-#define    M_TC_EN_VPE			M_PERFCTL_MT_EN(1)
-#define    M_TC_EN_TC			M_PERFCTL_MT_EN(2)
-#define M_PERFCTL_TCID(tcid)		((tcid)   << 22)
-#define M_PERFCTL_WIDE			(1UL      << 30)
-#define M_PERFCTL_MORE			(1UL      << 31)
-
-#define M_PERFCTL_COUNT_EVENT_WHENEVER	(M_PERFCTL_EXL |		\
-					M_PERFCTL_KERNEL |		\
-					M_PERFCTL_USER |		\
-					M_PERFCTL_SUPERVISOR |		\
-					M_PERFCTL_INTERRUPT_ENABLE)
-
-#ifdef CONFIG_MIPS_MT_SMP
-#define M_PERFCTL_CONFIG_MASK		0x3fff801f
-#else
-#define M_PERFCTL_CONFIG_MASK		0x1f
-#endif
-#define M_PERFCTL_EVENT_MASK		0xfe0
-
-#define M_COUNTER_OVERFLOW		(1UL      << 31)
-
-#ifdef CONFIG_MIPS_MT_SMP
-static int cpu_has_mipsmt_pertccounters;
-
-/*
- * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because
- * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs.
- */
-#if defined(CONFIG_HW_PERF_EVENTS)
-#define vpe_id()	(cpu_has_mipsmt_pertccounters ? \
-			0 : smp_processor_id())
-#else
-#define vpe_id()	(cpu_has_mipsmt_pertccounters ? \
-			0 : cpu_data[smp_processor_id()].vpe_id)
-#endif
-
-/* Copied from op_model_mipsxx.c */
-static unsigned int vpe_shift(void)
-{
-	if (num_possible_cpus() > 1)
-		return 1;
-
-	return 0;
-}
-
-static unsigned int counters_total_to_per_cpu(unsigned int counters)
-{
-	return counters >> vpe_shift();
-}
-
-static unsigned int counters_per_cpu_to_total(unsigned int counters)
-{
-	return counters << vpe_shift();
+		mipsxx_pmu_disable_event(idx);
 }
 
-#else /* !CONFIG_MIPS_MT_SMP */
-#define vpe_id()	0
-
-#endif /* CONFIG_MIPS_MT_SMP */
-
-#define __define_perf_accessors(r, n, np)				\
-									\
-static unsigned int r_c0_ ## r ## n(void)				\
-{									\
-	unsigned int cpu = vpe_id();					\
-									\
-	switch (cpu) {							\
-	case 0:								\
-		return read_c0_ ## r ## n();				\
-	case 1:								\
-		return read_c0_ ## r ## np();				\
-	default:							\
-		BUG();							\
-	}								\
-	return 0;							\
-}									\
-									\
-static void w_c0_ ## r ## n(unsigned int value)				\
-{									\
-	unsigned int cpu = vpe_id();					\
-									\
-	switch (cpu) {							\
-	case 0:								\
-		write_c0_ ## r ## n(value);				\
-		return;							\
-	case 1:								\
-		write_c0_ ## r ## np(value);				\
-		return;							\
-	default:							\
-		BUG();							\
-	}								\
-	return;								\
-}									\
-
-__define_perf_accessors(perfcntr, 0, 2)
-__define_perf_accessors(perfcntr, 1, 3)
-__define_perf_accessors(perfcntr, 2, 0)
-__define_perf_accessors(perfcntr, 3, 1)
-
-__define_perf_accessors(perfctrl, 0, 2)
-__define_perf_accessors(perfctrl, 1, 3)
-__define_perf_accessors(perfctrl, 2, 0)
-__define_perf_accessors(perfctrl, 3, 1)
 
 static int __n_counters(void)
 {
@@ -682,87 +808,17 @@ static void reset_counters(void *arg)
 	int counters = (int)(long)arg;
 	switch (counters) {
 	case 4:
-		w_c0_perfctrl3(0);
-		w_c0_perfcntr3(0);
+		mipsxx_pmu_write_control(3, 0);
+		mipspmu.write_counter(3, 0);
 	case 3:
-		w_c0_perfctrl2(0);
-		w_c0_perfcntr2(0);
+		mipsxx_pmu_write_control(2, 0);
+		mipspmu.write_counter(2, 0);
 	case 2:
-		w_c0_perfctrl1(0);
-		w_c0_perfcntr1(0);
-	case 1:
-		w_c0_perfctrl0(0);
-		w_c0_perfcntr0(0);
-	}
-}
-
-static u64 mipsxx_pmu_read_counter(unsigned int idx)
-{
-	switch (idx) {
-	case 0:
-		return r_c0_perfcntr0();
+		mipsxx_pmu_write_control(1, 0);
+		mipspmu.write_counter(1, 0);
 	case 1:
-		return r_c0_perfcntr1();
-	case 2:
-		return r_c0_perfcntr2();
-	case 3:
-		return r_c0_perfcntr3();
-	default:
-		WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
-		return 0;
-	}
-}
-
-static void mipsxx_pmu_write_counter(unsigned int idx, u64 val)
-{
-	switch (idx) {
-	case 0:
-		w_c0_perfcntr0(val);
-		return;
-	case 1:
-		w_c0_perfcntr1(val);
-		return;
-	case 2:
-		w_c0_perfcntr2(val);
-		return;
-	case 3:
-		w_c0_perfcntr3(val);
-		return;
-	}
-}
-
-static unsigned int mipsxx_pmu_read_control(unsigned int idx)
-{
-	switch (idx) {
-	case 0:
-		return r_c0_perfctrl0();
-	case 1:
-		return r_c0_perfctrl1();
-	case 2:
-		return r_c0_perfctrl2();
-	case 3:
-		return r_c0_perfctrl3();
-	default:
-		WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
-		return 0;
-	}
-}
-
-static void mipsxx_pmu_write_control(unsigned int idx, unsigned int val)
-{
-	switch (idx) {
-	case 0:
-		w_c0_perfctrl0(val);
-		return;
-	case 1:
-		w_c0_perfctrl1(val);
-		return;
-	case 2:
-		w_c0_perfctrl2(val);
-		return;
-	case 3:
-		w_c0_perfctrl3(val);
-		return;
+		mipsxx_pmu_write_control(0, 0);
+		mipspmu.write_counter(0, 0);
 	}
 }
 
@@ -1047,7 +1103,7 @@ static int __hw_perf_event_init(struct perf_event *event)
 	} else if (PERF_TYPE_RAW == event->attr.type) {
 		/* We are working on the global raw event. */
 		mutex_lock(&raw_event_mutex);
-		pev = mipspmu->map_raw_event(event->attr.config);
+		pev = mipspmu.map_raw_event(event->attr.config);
 	} else {
 		/* The event type is not (yet) supported. */
 		return -EOPNOTSUPP;
@@ -1092,7 +1148,7 @@ static int __hw_perf_event_init(struct perf_event *event)
 	hwc->config = 0;
 
 	if (!hwc->sample_period) {
-		hwc->sample_period  = MAX_PERIOD;
+		hwc->sample_period  = mipspmu.max_period;
 		hwc->last_period    = hwc->sample_period;
 		local64_set(&hwc->period_left, hwc->sample_period);
 	}
@@ -1105,55 +1161,38 @@ static int __hw_perf_event_init(struct perf_event *event)
 	}
 
 	event->destroy = hw_perf_event_destroy;
-
 	return err;
 }
 
 static void pause_local_counters(void)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	int counters = mipspmu->num_counters;
+	int ctr = mipspmu.num_counters;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	switch (counters) {
-	case 4:
-		cpuc->saved_ctrl[3] = r_c0_perfctrl3();
-		w_c0_perfctrl3(cpuc->saved_ctrl[3] &
-			~M_PERFCTL_COUNT_EVENT_WHENEVER);
-	case 3:
-		cpuc->saved_ctrl[2] = r_c0_perfctrl2();
-		w_c0_perfctrl2(cpuc->saved_ctrl[2] &
-			~M_PERFCTL_COUNT_EVENT_WHENEVER);
-	case 2:
-		cpuc->saved_ctrl[1] = r_c0_perfctrl1();
-		w_c0_perfctrl1(cpuc->saved_ctrl[1] &
-			~M_PERFCTL_COUNT_EVENT_WHENEVER);
-	case 1:
-		cpuc->saved_ctrl[0] = r_c0_perfctrl0();
-		w_c0_perfctrl0(cpuc->saved_ctrl[0] &
-			~M_PERFCTL_COUNT_EVENT_WHENEVER);
-	}
+	do {
+		ctr--;
+		cpuc->saved_ctrl[ctr] = mipsxx_pmu_read_control(ctr);
+		mipsxx_pmu_write_control(ctr, cpuc->saved_ctrl[ctr] &
+					 ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+	} while (ctr > 0);
 	local_irq_restore(flags);
 }
 
 static void resume_local_counters(void)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	int counters = mipspmu->num_counters;
+	int ctr = mipspmu.num_counters;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	switch (counters) {
-	case 4:
-		w_c0_perfctrl3(cpuc->saved_ctrl[3]);
-	case 3:
-		w_c0_perfctrl2(cpuc->saved_ctrl[2]);
-	case 2:
-		w_c0_perfctrl1(cpuc->saved_ctrl[1]);
-	case 1:
-		w_c0_perfctrl0(cpuc->saved_ctrl[0]);
-	}
+
+	do {
+		ctr--;
+		mipsxx_pmu_write_control(ctr, cpuc->saved_ctrl[ctr]);
+	} while (ctr > 0);
+
 	local_irq_restore(flags);
 }
 
@@ -1161,14 +1200,13 @@ static int mipsxx_pmu_handle_shared_irq(void)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct perf_sample_data data;
-	unsigned int counters = mipspmu->num_counters;
-	unsigned int counter;
+	unsigned int counters = mipspmu.num_counters;
+	u64 counter;
 	int handled = IRQ_NONE;
 	struct pt_regs *regs;
 
 	if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26)))
 		return handled;
-
 	/*
 	 * First we pause the local counters, so that when we are locked
 	 * here, the counters are all paused. When it gets locked due to
@@ -1189,13 +1227,9 @@ static int mipsxx_pmu_handle_shared_irq(void)
 #define HANDLE_COUNTER(n)						\
 	case n + 1:							\
 		if (test_bit(n, cpuc->used_mask)) {			\
-			counter = r_c0_perfcntr ## n();			\
-			if (counter & M_COUNTER_OVERFLOW) {		\
-				w_c0_perfcntr ## n(counter &		\
-						VALID_COUNT);		\
-				if (test_and_change_bit(n, cpuc->msbs))	\
-					handle_associated_event(cpuc,	\
-						n, &data, regs);	\
+			counter = mipspmu.read_counter(n);		\
+			if (counter & mipspmu.overflow) {		\
+				handle_associated_event(cpuc, n, &data, regs); \
 				handled = IRQ_HANDLED;			\
 			}						\
 		}
@@ -1225,95 +1259,6 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
 	return mipsxx_pmu_handle_shared_irq();
 }
 
-static void mipsxx_pmu_start(void)
-{
-#ifdef CONFIG_MIPS_MT_SMP
-	write_unlock(&pmuint_rwlock);
-#endif
-	resume_local_counters();
-}
-
-/*
- * MIPS performance counters can be per-TC. The control registers can
- * not be directly accessed accross CPUs. Hence if we want to do global
- * control, we need cross CPU calls. on_each_cpu() can help us, but we
- * can not make sure this function is called with interrupts enabled. So
- * here we pause local counters and then grab a rwlock and leave the
- * counters on other CPUs alone. If any counter interrupt raises while
- * we own the write lock, simply pause local counters on that CPU and
- * spin in the handler. Also we know we won't be switched to another
- * CPU after pausing local counters and before grabbing the lock.
- */
-static void mipsxx_pmu_stop(void)
-{
-	pause_local_counters();
-#ifdef CONFIG_MIPS_MT_SMP
-	write_lock(&pmuint_rwlock);
-#endif
-}
-
-static int mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc,
-				    struct hw_perf_event *hwc)
-{
-	int i;
-
-	/*
-	 * We only need to care the counter mask. The range has been
-	 * checked definitely.
-	 */
-	unsigned long cntr_mask = (hwc->event_base >> 8) & 0xffff;
-
-	for (i = mipspmu->num_counters - 1; i >= 0; i--) {
-		/*
-		 * Note that some MIPS perf events can be counted by both
-		 * even and odd counters, wheresas many other are only by
-		 * even _or_ odd counters. This introduces an issue that
-		 * when the former kind of event takes the counter the
-		 * latter kind of event wants to use, then the "counter
-		 * allocation" for the latter event will fail. In fact if
-		 * they can be dynamically swapped, they both feel happy.
-		 * But here we leave this issue alone for now.
-		 */
-		if (test_bit(i, &cntr_mask) &&
-			!test_and_set_bit(i, cpuc->used_mask))
-			return i;
-	}
-
-	return -EAGAIN;
-}
-
-static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	unsigned long flags;
-
-	WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
-
-	local_irq_save(flags);
-	cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) |
-		(evt->config_base & M_PERFCTL_CONFIG_MASK) |
-		/* Make sure interrupt enabled. */
-		M_PERFCTL_INTERRUPT_ENABLE;
-	/*
-	 * We do not actually let the counter run. Leave it until start().
-	 */
-	local_irq_restore(flags);
-}
-
-static void mipsxx_pmu_disable_event(int idx)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	unsigned long flags;
-
-	WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
-
-	local_irq_save(flags);
-	cpuc->saved_ctrl[idx] = mipsxx_pmu_read_control(idx) &
-		~M_PERFCTL_COUNT_EVENT_WHENEVER;
-	mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]);
-	local_irq_restore(flags);
-}
-
 /* 24K */
 #define IS_UNSUPPORTED_24K_EVENT(r, b)					\
 	((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 ||		\
@@ -1452,40 +1397,11 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
 	return &raw_event;
 }
 
-static struct mips_pmu mipsxxcore_pmu = {
-	.handle_irq = mipsxx_pmu_handle_irq,
-	.handle_shared_irq = mipsxx_pmu_handle_shared_irq,
-	.start = mipsxx_pmu_start,
-	.stop = mipsxx_pmu_stop,
-	.alloc_counter = mipsxx_pmu_alloc_counter,
-	.read_counter = mipsxx_pmu_read_counter,
-	.write_counter = mipsxx_pmu_write_counter,
-	.enable_event = mipsxx_pmu_enable_event,
-	.disable_event = mipsxx_pmu_disable_event,
-	.map_raw_event = mipsxx_pmu_map_raw_event,
-	.general_event_map = &mipsxxcore_event_map,
-	.cache_event_map = &mipsxxcore_cache_map,
-};
-
-static struct mips_pmu mipsxx74Kcore_pmu = {
-	.handle_irq = mipsxx_pmu_handle_irq,
-	.handle_shared_irq = mipsxx_pmu_handle_shared_irq,
-	.start = mipsxx_pmu_start,
-	.stop = mipsxx_pmu_stop,
-	.alloc_counter = mipsxx_pmu_alloc_counter,
-	.read_counter = mipsxx_pmu_read_counter,
-	.write_counter = mipsxx_pmu_write_counter,
-	.enable_event = mipsxx_pmu_enable_event,
-	.disable_event = mipsxx_pmu_disable_event,
-	.map_raw_event = mipsxx_pmu_map_raw_event,
-	.general_event_map = &mipsxx74Kcore_event_map,
-	.cache_event_map = &mipsxx74Kcore_cache_map,
-};
-
 static int __init
 init_hw_perf_events(void)
 {
 	int counters, irq;
+	int counter_bits;
 
 	pr_info("Performance counters: ");
 
@@ -1517,32 +1433,28 @@ init_hw_perf_events(void)
 	}
 #endif
 
-	on_each_cpu(reset_counters, (void *)(long)counters, 1);
+	mipspmu.map_raw_event = mipsxx_pmu_map_raw_event;
 
 	switch (current_cpu_type()) {
 	case CPU_24K:
-		mipsxxcore_pmu.name = "mips/24K";
-		mipsxxcore_pmu.num_counters = counters;
-		mipsxxcore_pmu.irq = irq;
-		mipspmu = &mipsxxcore_pmu;
+		mipspmu.name = "mips/24K";
+		mipspmu.general_event_map = &mipsxxcore_event_map;
+		mipspmu.cache_event_map = &mipsxxcore_cache_map;
 		break;
 	case CPU_34K:
-		mipsxxcore_pmu.name = "mips/34K";
-		mipsxxcore_pmu.num_counters = counters;
-		mipsxxcore_pmu.irq = irq;
-		mipspmu = &mipsxxcore_pmu;
+		mipspmu.name = "mips/34K";
+		mipspmu.general_event_map = &mipsxxcore_event_map;
+		mipspmu.cache_event_map = &mipsxxcore_cache_map;
 		break;
 	case CPU_74K:
-		mipsxx74Kcore_pmu.name = "mips/74K";
-		mipsxx74Kcore_pmu.num_counters = counters;
-		mipsxx74Kcore_pmu.irq = irq;
-		mipspmu = &mipsxx74Kcore_pmu;
+		mipspmu.name = "mips/74K";
+		mipspmu.general_event_map = &mipsxx74Kcore_event_map;
+		mipspmu.cache_event_map = &mipsxx74Kcore_cache_map;
 		break;
 	case CPU_1004K:
-		mipsxxcore_pmu.name = "mips/1004K";
-		mipsxxcore_pmu.num_counters = counters;
-		mipsxxcore_pmu.irq = irq;
-		mipspmu = &mipsxxcore_pmu;
+		mipspmu.name = "mips/1004K";
+		mipspmu.general_event_map = &mipsxxcore_event_map;
+		mipspmu.cache_event_map = &mipsxxcore_cache_map;
 		break;
 	default:
 		pr_cont("Either hardware does not support performance "
@@ -1550,10 +1462,30 @@ init_hw_perf_events(void)
 		return -ENODEV;
 	}
 
-	if (mipspmu)
-		pr_cont("%s PMU enabled, %d counters available to each "
-			"CPU, irq %d%s\n", mipspmu->name, counters, irq,
-			irq < 0 ? " (share with timer interrupt)" : "");
+	mipspmu.num_counters = counters;
+	mipspmu.irq = irq;
+
+	if (read_c0_perfctrl0() & M_PERFCTL_WIDE) {
+		mipspmu.max_period = (1ULL << 63) - 1;
+		mipspmu.valid_count = (1ULL << 63) - 1;
+		mipspmu.overflow = 1ULL << 63;
+		mipspmu.read_counter = mipsxx_pmu_read_counter_64;
+		mipspmu.write_counter = mipsxx_pmu_write_counter_64;
+		counter_bits = 64;
+	} else {
+		mipspmu.max_period = (1ULL << 32) - 1;
+		mipspmu.valid_count = (1ULL << 31) - 1;
+		mipspmu.overflow = 1ULL << 31;
+		mipspmu.read_counter = mipsxx_pmu_read_counter;
+		mipspmu.write_counter = mipsxx_pmu_write_counter;
+		counter_bits = 32;
+	}
+
+	on_each_cpu(reset_counters, (void *)(long)counters, 1);
+
+	pr_cont("%s PMU enabled, %d %d-bit counters available to each "
+		"CPU, irq %d%s\n", mipspmu.name, counters, counter_bits, irq,
+		irq < 0 ? " (share with timer interrupt)" : "");
 
 	perf_pmu_register(&pmu);
 
-- 
1.7.2.3


From anoop.pa@gmail.com Fri Jan  7 08:45:20 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 08:45:24 +0100 (CET)
Received: from mail-yw0-f49.google.com ([209.85.213.49]:61488 "EHLO
        mail-yw0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491033Ab1AGHpU (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 08:45:20 +0100
Received: by ywf7 with SMTP id 7so7286233ywf.36
        for <linux-mips@linux-mips.org>; Thu, 06 Jan 2011 23:45:12 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:received:received:subject:from:to:cc
         :in-reply-to:references:content-type:date:message-id:mime-version
         :x-mailer;
        bh=QEODe1XXZ8V5oIxJuC53hdLga2tRKB03NGlurjIbyUM=;
        b=MXkt1QqitM7Ytai1hcYTmhn5tCIKnioHNXVzQLZr3UygaFCqXlPG5SoiXHWQwvk0L/
         8I8ZxLgz1Lr+mfzOmZIE1VcT/3IWIJvye+h3zQruYZqyFzJbI9Pa5asCK0wpenfQqumi
         pCRT95wdJ+7+BhDWEtQYNKsEJjqTgXBPHSgpA=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=subject:from:to:cc:in-reply-to:references:content-type:date
         :message-id:mime-version:x-mailer;
        b=kxzodfEIaRaIbK+D1Rankc4lDOA2mszZ1UD3sbnZW3GID047xDAIw3aKk9uyMb67wf
         BKZ6Zf5vt5QIlx25giJWEIUeRsWMl/9UXaNwq5QyVKyPsCgOl1lNkWfuF8Eud52s8xsr
         ZrcqOjylbNHRhPsKhzr1YH9Okj04qJKj5Ib7w=
Received: by 10.151.42.3 with SMTP id u3mr5861018ybj.374.1294386312452;
        Thu, 06 Jan 2011 23:45:12 -0800 (PST)
Received: from [172.16.48.51] ([59.160.135.215])
        by mx.google.com with ESMTPS id b7sm2884863ybn.23.2011.01.06.23.45.06
        (version=SSLv3 cipher=RC4-MD5);
        Thu, 06 Jan 2011 23:45:09 -0800 (PST)
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
In-Reply-To: <4D2650D6.4030102@paralogos.com>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
         <1293470392.27661.202.camel@paanoop1-desktop>
         <1293524389.27661.210.camel@paanoop1-desktop>
         <4D19A31E.1090905@paralogos.com>
         <1293798476.27661.279.camel@paanoop1-desktop>
         <4D1EE913.1070203@paralogos.com>
         <1294067561.27661.293.camel@paanoop1-desktop>
         <4D21F5D3.50604@paralogos.com>
         <1294082426.27661.330.camel@paanoop1-desktop>
         <4D22D7B3.2050609@paralogos.com>
         <1294146165.27661.361.camel@paanoop1-desktop>
         <1294151822.27661.375.camel@paanoop1-desktop>
         <4D235717.1000603@paralogos.com>
         <1294163657.27661.386.camel@paanoop1-desktop>
         <4D2367EE.7000702@paralogos.com>
         <1294233097.27661.391.camel@paanoop1-desktop>
         <4D24C525.5000306@paralogos.com>
         <1294345396.27661.422.camel@paanoop1-desktop>
         <4D2650D6.4030102@paralogos.com>
Content-Type: multipart/mixed; boundary="=-nDxvhOOi4yjj2vbP9Xbb"
Date:   Fri, 07 Jan 2011 13:26:59 +0530
Message-ID: <1294387019.27661.458.camel@paanoop1-desktop>
Mime-Version: 1.0
X-Mailer: Evolution 2.28.3 
Return-Path: <anoop.pa@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: 28879
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips


--=-nDxvhOOi4yjj2vbP9Xbb
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit

On Thu, 2011-01-06 at 15:31 -0800, Kevin D. Kissell wrote:
> On 01/06/11 12:23, Anoop P A wrote:

> 
> I'm sure I've said this before, and it's in various comments in the SMTC
> code, but remember, one of the main problems that the SMTC kernel
> had to solve was to prevent all TCs of a VPE from "convoying" after every
> interrupt.  The way this is done is that the interrupt vector code, before
> clearing EXL, masks off the Status.IM bit associated with the incoming
> interrupt.  Of course, to get another interrupt from the same source
> (or collection of sources), that IM bit needs to be restored.  The "correct"
> mechanism for this is by having the appropriate irq_hwmask[] value set,
> so that smtc_im_ack_irq(), which should be invoked on an irq "ack()"
> (meaning that the source has been quenched and any new occurrence
> should be considered a new interrupt), will restore the bit in Status.
> This function got moved around a bit in the various SMTC prototypes,
> but it proved least intrusive to put it into the xxx_mask_and_ack() 
> functions
> for the interrupt controllers - see irq-msc01.c and i8259.c.  If you haven't
> done the same in any equivalent code for a different on-chip controller,
> you'll definitely have problems.
> 
> The Backstop scheme works OK for peripheral interrupts that didn't
> have an appropriate irq_hwmask[] value set up, but clock interrupts
> don't follow the same code paths and can't depend on the backstop.

Ok. Well thanks much for your detailed explanation. Well I hope I found
the root cause . smtc_clockevent_init() was overriding irq_hwmask even
if are using platform specific get_c0_compare_int. With following patch
everything seems to be working for me.
------------------------------------------------------------------------
diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c
index 2e72d30..a25fc59 100644
--- a/arch/mips/kernel/cevt-smtc.c
+++ b/arch/mips/kernel/cevt-smtc.c
@@ -310,9 +310,14 @@ int __cpuinit smtc_clockevent_init(void)
 		return 0;
 	/*
 	 * And we need the hwmask associated with the c0_compare
-	 * vector to be initialized.
+	 * vector to be initialized. However incase of platform 
+	 * specific get_co_compare_int, don't override irq_hwmask
+	 * expect platform code to set a valid mask value. 
 	 */
-	irq_hwmask[irq] = (0x100 << cp0_compare_irq);
+
+	if (!get_c0_compare_int)
+		irq_hwmask[irq] = (0x100 << cp0_compare_irq);
+
 	if (cp0_timer_irq_installed)
 		return 0;
----------------------------------------------------------------------- 


Attaching my msp_ir_cic.c . Kindly have a look if possible.

Thanks
Anoop

> 
>              Regards,
> 
>              Kevin K.


--=-nDxvhOOi4yjj2vbP9Xbb
Content-Disposition: attachment; filename="msp_irq_cic.c"
Content-Type: text/x-csrc; name="msp_irq_cic.c"; charset="UTF-8"
Content-Transfer-Encoding: 7bit

/*
 * Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c
 *
 * This file define the irq handler for MSP CIC subsystem interrupts.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/irq.h>

#include <asm/mipsregs.h>
#include <asm/system.h>

#include <msp_cic_int.h>
#include <msp_regs.h>

/*
 * External API
 */
extern void msp_per_irq_init(void);
extern void msp_per_irq_dispatch(void);


/*
 * Convenience Macro.  Should be somewhere generic.
 */
#define get_current_vpe()   \
	((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE) 

#ifdef CONFIG_SMP

#define LOCK_VPE(flags, mtflags) \
do {				\
	local_irq_save(flags);	\
	mtflags = dmt();	\
} while (0)

#define UNLOCK_VPE(flags, mtflags) \
do {				\
	emt(mtflags);		\
	local_irq_restore(flags);\
} while (0)

#define LOCK_CORE(flags, mtflags) \
do {				\
	local_irq_save(flags);	\
	mtflags = dvpe();	\
} while (0)

#define UNLOCK_CORE(flags, mtflags)		\
do {				\
	evpe(mtflags);		\
	local_irq_restore(flags);\
} while (0)

#else

#define LOCK_VPE(flags, mtflags) 
#define UNLOCK_VPE(flags, mtflags) 

#endif

/* ensure writes to cic are completed */
static inline void cic_wmb(void)
{
	const volatile void __iomem *cic_mem = CIC_VPE0_MSK_REG;
	volatile u32 dummy_read;

	wmb();
	dummy_read = __raw_readl(cic_mem);
	dummy_read++;
}


static inline void unmask_cic_irq(unsigned int irq)
{
	volatile u32   *cic_msk_reg = CIC_VPE0_MSK_REG;
	int vpe;
#ifdef CONFIG_SMP
	unsigned int mtflags;
	unsigned long  flags;

	/*
	* Make sure we have IRQ affinity.  It may have changed while
	* we were processing the IRQ.
	*/
	if (!cpumask_test_cpu(smp_processor_id(), irq_desc[irq].affinity))
		return;
#endif

	vpe = get_current_vpe();
	LOCK_VPE(flags, mtflags);
	cic_msk_reg[vpe] |= (1 << (irq - MSP_CIC_INTBASE));
	UNLOCK_VPE(flags, mtflags);
	cic_wmb();
}

static inline void mask_cic_irq(unsigned int irq)
{
	volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG;
	int	vpe = get_current_vpe();
#ifdef CONFIG_SMP
	unsigned long flags, mtflags;
#endif
	LOCK_VPE(flags, mtflags);
	cic_msk_reg[vpe] &= ~(1 << (irq - MSP_CIC_INTBASE));
	UNLOCK_VPE(flags, mtflags);
	cic_wmb();
}
static inline void msp_cic_irq_ack(unsigned int irq)
{
	mask_cic_irq(irq);
	/*
	* Only really necessary for 18, 16-14 and sometimes 3:0
	* (since these can be edge sensitive) but it doesn't
	* hurt for the others
	*/
	*CIC_STS_REG = (1 << (irq - MSP_CIC_INTBASE));
	smtc_im_ack_irq(irq);
}

static void msp_cic_irq_end(unsigned int irq)
{
	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
		unmask_cic_irq(irq);
}

#ifdef CONFIG_SMP
static inline int msp_cic_irq_set_affinity(unsigned int irq,
					const struct cpumask *cpumask)
{
	int cpu;
	unsigned long flags;
	unsigned int  mtflags;
	unsigned long imask = (1 << (irq - MSP_CIC_INTBASE));
	volatile u32 *cic_mask = (volatile u32 *)CIC_VPE0_MSK_REG;

	/* timer balancing should be disabled in kernel code */
	BUG_ON(irq == MSP_INT_VPE0_TIMER || irq == MSP_INT_VPE1_TIMER);

	LOCK_CORE(flags, mtflags);
	/* enable if any of each VPE's TCs require this IRQ */
	for_each_online_cpu(cpu) {
		if (cpumask_test_cpu(cpu, cpumask))
			cic_mask[cpu] |= imask;
		else
			cic_mask[cpu] &= ~imask;

	}

	UNLOCK_CORE(flags, mtflags);
	return 0;

}
#endif

static struct irq_chip msp_cic_irq_controller = {
	.name = "MSP_CIC",
	.mask = msp_cic_irq_ack,
	.mask_ack = msp_cic_irq_ack,
	.unmask = unmask_cic_irq,
	.ack = msp_cic_irq_ack,
	.end = msp_cic_irq_end,
#ifdef CONFIG_SMP
	.set_affinity = msp_cic_irq_set_affinity,
#endif
};

void __init msp_cic_irq_init(void)
{
	int i;
	/* Mask/clear interrupts. */
	*CIC_VPE0_MSK_REG = 0x00000000;
	*CIC_VPE1_MSK_REG = 0x00000000;
	*CIC_STS_REG      = 0xFFFFFFFF;
	/*
	* The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI.
	* These inputs map to EXT_INT_POL[6:4] inside the CIC.
	* They are to be active low, level sensitive.
	*/
	*CIC_EXT_CFG_REG &= 0xFFFF8F8F;

	/* initialize all the IRQ descriptors */
	for (i = MSP_CIC_INTBASE ; i < MSP_CIC_INTBASE + 32 ; i++) {
		set_irq_chip_and_handler(i, &msp_cic_irq_controller,
					 handle_level_irq);
#ifdef CONFIG_MIPS_MT_SMTC
		/* Mask of CIC interrupt */
		irq_hwmask[i] = C_IRQ4;
#endif
	}

	/* Initialize the PER interrupt sub-system */
	 msp_per_irq_init();
}

/* CIC masked by CIC vector processing before dispatch called */
void msp_cic_irq_dispatch(void)
{
	volatile u32	*cic_msk_reg = (volatile u32 *)CIC_VPE0_MSK_REG;
	u32	cic_mask;
	u32	 pending;
	int	cic_status = *CIC_STS_REG;
	cic_mask = cic_msk_reg[get_current_vpe()];
	pending = cic_status & cic_mask;
	if (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE))) {
		do_IRQ(MSP_INT_VPE0_TIMER);
	} else if (pending & (1 << (MSP_INT_VPE1_TIMER - MSP_CIC_INTBASE))) {
		do_IRQ(MSP_INT_VPE1_TIMER);
	} else if (pending & (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) {
		msp_per_irq_dispatch();
	} else if (pending) {
		do_IRQ(ffs(pending) + MSP_CIC_INTBASE - 1);
	} else{
		spurious_interrupt();
		/* Re-enable the CIC cascaded interrupt. */
		irq_desc[MSP_INT_CIC].chip->end(MSP_INT_CIC);
	}
}

--=-nDxvhOOi4yjj2vbP9Xbb--


From miloody@gmail.com Fri Jan  7 15:21:37 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 15:21:40 +0100 (CET)
Received: from mail-iy0-f177.google.com ([209.85.210.177]:49075 "EHLO
        mail-iy0-f177.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490991Ab1AGOVh (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 15:21:37 +0100
Received: by iyj21 with SMTP id 21so17047496iyj.36
        for <linux-mips@linux-mips.org>; Fri, 07 Jan 2011 06:21:30 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:mime-version:received:received:in-reply-to
         :references:date:message-id:subject:from:to:cc:content-type;
        bh=38ptf/hfaArb6B2lWAvl25w6hV/ntRufgm44vJh4n14=;
        b=VhhkEJ68IGaNQEufOYwbEldDfJdg4HmMxzkbVvUxp8SwlfGH6lZ2klLmgicm5r4kXf
         HKnWVoYEmd37dN7gUBNGxzE9/mgobaKlDDF68iVEt64MtbF8cG0pVkIS+BdeE8fFcPpD
         wps++LGwtFXm97VTK8IKRRQYDo0MQ7kZ1ccuM=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=mime-version:in-reply-to:references:date:message-id:subject:from:to
         :cc:content-type;
        b=e6r9O+cXTiJl+AHHNAlwC7Fs1iZdnlAoUycP6dN2R0iGk5G/iKHU4W3stWC/giAgpz
         diJp/L51sVC+Fq/0bedABGoqJrnqkPj8hYR4ihGn1JMcmeTF0u9iVcRJffK7cO2PtKcR
         7fXvmYel5FPda8SotmfSU5qGHK5xteCSTVqWk=
MIME-Version: 1.0
Received: by 10.42.177.137 with SMTP id bi9mr885807icb.194.1294410090543; Fri,
 07 Jan 2011 06:21:30 -0800 (PST)
Received: by 10.42.174.131 with HTTP; Fri, 7 Jan 2011 06:21:30 -0800 (PST)
In-Reply-To: <AANLkTi=TgZd8XS410kYfiLp79M-=-8etgg0VEZGUme3N@mail.gmail.com>
References: <AANLkTikFNZiM9=Ym2sfZpstjse-zR69fh28OZ_aedUFe@mail.gmail.com>
        <AANLkTi=b52Aprg7G-bXo84W+_Ru6=VigUHRHGGDf-Y51@mail.gmail.com>
        <AANLkTimiXgBQr1arUdGgxGXnfqtoMvCMQivcujYc9VS0@mail.gmail.com>
        <AANLkTi=E7Q9kJvG1KUPv2xS3WK_12byksSrVH_g2UST2@mail.gmail.com>
        <AANLkTimR7PyJS000BsA-Q=pRXXY9Wht6_QtkRowv=OLM@mail.gmail.com>
        <AANLkTi=TgZd8XS410kYfiLp79M-=-8etgg0VEZGUme3N@mail.gmail.com>
Date:   Fri, 7 Jan 2011 22:21:30 +0800
Message-ID: <AANLkTi=zq=Tq+UxZMxdJRXWz=EZQ-oyf1gorm0uysPjk@mail.gmail.com>
Subject: Re: Questions about complete
From:   loody <miloody@gmail.com>
To:     Linux MIPS Mailing List <linux-mips@linux-mips.org>
Cc:     kernelnewbies@kernelnewbies.org
Content-Type: text/plain; charset=ISO-8859-1
Return-Path: <miloody@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: 28880
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: miloody@gmail.com
Precedence: bulk
X-list: linux-mips

hi all:

2011/1/6 Rajat Sharma <fs.rajat@gmail.com>:
> Hi loody,
>
> calling complete will make the waiter process runnable but won't
> necessarily switch to waiter thread and make it run. Its upto
> scheduler to pick this process from run queue and execute based on its
> priority value. I think there is not deterministic time in which the
> waiter process will start executing.
>
> Probably what you want to do is calibrate timeout value in
> wait_for_completion_timeout. I would suggest to do a binary search
> between minimum timeout value (latency by which function A calls
> complete, though this process can also schedule in between) to max
> value (max your application can afford).
>
> Rajat
>
> On Thu, Jan 6, 2011 at 1:35 PM, loody <miloody@gmail.com> wrote:
>> hi:
>>
>> 2011/1/6 Pavan Savoy <pavan_savoy@sify.com>:
>>> On Thu, Jan 6, 2011 at 12:23 PM, loody <miloody@gmail.com> wrote:
>>>> hi:
>>>>
>>>> 2011/1/6 Pavan Savoy <pavan_savoy@sify.com>:
>>>>> On Thu, Jan 6, 2011 at 11:48 AM, loody <miloody@gmail.com> wrote:
>>>>>>
>>>>>> Dear all:
>>>>>> I know complete will wake up the process who call wait_complete.
>>>>>> Is there any methods I can use to measure how long from calling
>>>>>> complete to the process that detect done=1?
>>>>>> Regards,
>>>>>> miloody
>>>>>
>>>>> returned value of wait_for_completion_timeout ?
>>>> No.
>>>> I want to measure the duration of complete to the time of wake up
>>>> process who is pending on wait.
>>>
>>> Ah, Ok, Got it...
>>> I would do a copy of jiffies before the complete and do a diff for
>>> jiffies after the
>>> wait_for_ ...
>>>
>>> I suppose there would be much more better/optimized way ....
>> thank U :)
>> why I ask so is I am porting kernel to other platform right now.
>> and I found the time of getting complete is too long.
>> What I mean is
>> function A call wait_complete_timeout
>> function B complete
>> theoretically A will get complete and leave successfully
>> but my platform A will told me that before timeout the complete is not got.

I doubt my problem comes from cpu timer interrupt is so often such
that when function B get the change to complete, the left time is
almost exhausted.
for not to be confused, I take following jiffies for example:
1               2            3            4            5
6            8
start wait                                      B try complete
       time out

B try to complete but cpu timer keep firing and at 8 it is time out.
My platform is mips and is there any possibility to only let cpu timer
be preemptible?

BTW, in x86 or other ARCH, will they try to let timer ISR be preemptible?


-- 
Regards,
miloody

From mierz@hotmail.com Fri Jan  7 16:45:16 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 16:45:19 +0100 (CET)
Received: from blu0-omc4-s21.blu0.hotmail.com ([65.55.111.160]:63191 "EHLO
        blu0-omc4-s21.blu0.hotmail.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491038Ab1AGPpQ convert rfc822-to-8bit
        (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Fri, 7 Jan 2011 16:45:16 +0100
Received: from BLU124-W4 ([65.55.111.137]) by blu0-omc4-s21.blu0.hotmail.com with Microsoft SMTPSVC(6.0.3790.4675);
         Fri, 7 Jan 2011 07:45:06 -0800
Message-ID: <BLU124-W490D65550F59FC3E0B692A60B0@phx.gbl>
X-Originating-IP: [72.22.182.66]
From:   Erich Mierzejewski <mierz@hotmail.com>
To:     <linux-mips@linux-mips.org>
Subject: [kernel oops] Cavium Octeon, linux 2.6.27
Date:   Fri, 7 Jan 2011 10:45:06 -0500
Importance: Normal
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 8BIT
MIME-Version: 1.0
X-OriginalArrivalTime: 07 Jan 2011 15:45:06.0845 (UTC) FILETIME=[DB991CD0:01CBAE81]
Return-Path: <mierz@hotmail.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: 28881
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: mierz@hotmail.com
Precedence: bulk
X-list: linux-mips


I am facing an intermittent Oops on Cavium-Octeon CN56xx.  The oops is related to networking, and typically includes TIPC (virtually all inter-node comms is using TIPC).  It takes about 2-3 hours of running a directed TIPC client/server test to invoke the oops.  

The signature varies, but typically includes either sock_sendmsg or sock_poll.   Here's an example captured from syslog with sock_poll.   

Feb  5 11:18:42 mpc_1_1 kernel: CPU 2 Unable to handle kernel paging request at virtual address ffffffffc016f970, epc == ffffffff813e8ec4, ra == ffffffff81235658
Feb  5 11:18:44 mpc_1_1 kernel: Oops[#1]:
Feb  5 11:18:44 mpc_1_1 kernel: Cpu 3
Feb  5 11:18:44 mpc_1_1 kernel: $ 0   : 0000000000000000 0000000000000001 ffffffffc016f930 a8000000e9e2aa00
Feb  5 11:18:44 mpc_1_1 kernel: $ 4   : a8000000e92f8600 0000000000000000 0000000000000000 00000000000003e8
Feb  5 11:18:44 mpc_1_1 kernel: $ 8   : 0000000000416248 00000000004186e8 000000007fdba9e0 000000000040243c
Feb  5 11:18:44 mpc_1_1 kernel: $12   : 0000000000000000 ffffffffc0000008 ffffffff81235400 ffffffff89a0a600
Feb  5 11:18:44 mpc_1_1 kernel: $16   : a8000000bc9ec700 a8000000bc9ec718 0000000000000000 a8000000e92f8000
Feb  5 11:18:44 mpc_1_1 kernel: $20   : 0000000000000001 000000007fdba9b0 a8000000e92f8070 0000000000000000
Feb  5 11:18:44 mpc_1_1 kernel: $24   : 0000000000000400 0000000038fbd038                        
Feb  5 11:18:44 mpc_1_1 kernel: $28   : a8000000b9d64000 a8000000b9d67dc0 a8000000e92f9300 ffffffff81235658
Feb  5 11:18:44 mpc_1_1 kernel: Hi    : 0000000000007d7f
Feb  5 11:18:44 mpc_1_1 kernel: Lo    : df3b645a1cac9d39
Feb  5 11:18:44 mpc_1_1 kernel: epc   : ffffffff813e8ec4 sock_poll+0xc/0x18
Feb  5 11:18:44 mpc_1_1 kernel: Not tainted
Feb  5 11:18:44 mpc_1_1 kernel: ra    : ffffffff81235658 SyS_epoll_wait+0x258/0x560
Feb  5 11:18:44 mpc_1_1 kernel: Status: 1000cce3    KX SX UX KERNEL EXL IE
Feb  5 11:18:44 mpc_1_1 kernel: Cause : 00800008
Feb  5 11:18:44 mpc_1_1 kernel: BadVA : ffffffffc016f970
Feb  5 11:18:44 mpc_1_1 kernel: PrId  : 000d0409 (Cavium Octeon)
Feb  5 11:18:44 mpc_1_1 kernel: Modules linked in: usbcore bonding i2c_dev x_tables ip6_tables ip_tables ipv6 libcrc32c sctp spioc binfmt_misc jazz_mod iptable_filter tunnel4 sit ipmi_msghandler ipmi_serial ipmi_serial_terminal_mode ipmi_devintf ipmi_watchdog tipc dti si5326 mt29f
Feb  5 11:18:44 mpc_1_1 kernel: Process tipcServer_mpc (pid: 8226, threadinfo=a8000000b9d64000, task=a8000000bca5e900, tls=000000002ad009a0)
Feb  5 11:18:44 mpc_1_1 kernel: Stack : a8000000b9d67dc0 a8000000b9d67dc0 0000000000000001 0000000000000000
Feb  5 11:18:44 mpc_1_1 kernel: 0000000000000081 0000000000416234 0000000000000001 000000000041e060
Feb  5 11:18:44 mpc_1_1 kernel: a8000000e92f8010 a8000000e92f8030 a8000000e92f8050 a8000000e92f8060
Feb  5 11:18:44 mpc_1_1 kernel: 00000000000000fa a8000000e92f8040 0000000000404db8 0000000000401220
Feb  5 11:18:44 mpc_1_1 kernel: 00000000004b0000 00000000004e8450 00000000004e05f8 00000000004e8450
Feb  5 11:18:44 mpc_1_1 kernel: 0000000000000000 00000000004ed948 000000007fdba968 ffffffff8114732c
Feb  5 11:18:44 mpc_1_1 kernel: 0000000000000000 ffffffff81103be4 000000000000109a 000000002acf9530
Feb  5 11:18:44 mpc_1_1 kernel: 0000000000000003 000000007fdba9b0 0000000000000001 00000000000003e8
Feb  5 11:18:44 mpc_1_1 kernel: 0000000000000001 00000000203d2025 0000000025252525 ffffffff81010100
Feb  5 11:18:44 mpc_1_1 kernel: 0000000000000000 0000000000000010 ffffffff813eaf18 ffffffff89a0a600
Feb  5 11:18:44 mpc_1_1 kernel: ...
Feb  5 11:18:44 mpc_1_1 kernel: Call Trace:
Feb  5 11:18:44 mpc_1_1 kernel: [<ffffffff813e8ec4>] sock_poll+0xc/0x18
Feb  5 11:18:44 mpc_1_1 kernel: [<ffffffff81235658>] SyS_epoll_wait+0x258/0x560
Feb  5 11:18:44 mpc_1_1 kernel: [<ffffffff8114732c>] handle_sys+0x12c/0x148
Feb  5 11:18:44 mpc_1_1 kernel:
Feb  5 11:18:44 mpc_1_1 kernel:
Feb  5 11:18:44 mpc_1_1 kernel: Code: dc830098  00a0302d  dc620010 <dc590040> 03200008  0060282d  dc830098  00a0302d  dc620010
Feb  5 11:18:44 mpc_1_1 kernel: TIPC: Resetting link <1.1.11:bond0-1.1.101:bond0>, requested by peer
Feb  5 11:18:44 mpc_1_1 kernel: TIPC: Lost link <1.1.11:bond0-1.1.101:bond0> on network plane A
Feb  5 11:18:44 mpc_1_1 kernel: TIPC: Lost contact with <1.1.101>
Feb  5 11:18:44 mpc_1_1 kernel: TIPC: Established link <1.1.11:bond0-1.1.101:bond0> on network plane A


Looking at the disassembly of sock_poll, it can be seen that the error occurs when dereferencing ops->poll to store the function pointer in register t9.  

0000000000000048 <sock_poll>:
        struct socket *sock;

        /*
         *      We can't return errors to poll, so it's either yes or no.
         */
        sock = file->private_data;
      48:       dc830098        ld      v1,152(a0)
        return sock->ops->poll(file, sock, wait);
      4c:       00a0302d        move    a2,a1
      50:       dc620010        ld      v0,16(v1)
      54:       dc590040        ld      t9,64(v0)
      58:       03200008        jr      t9
      5c:       0060282d        move    a1,v1

The register file corroborates BadVA to (64)v0, with v0 holding a value of ffffffffc016f930.  

I originally thought this address _was_ bad because all of the kernel code addresses are in the range ffffffff81xxxxxx.  Then it occurred that modules might be loaded at a different address, so checking a live system:

/tmp> grep ffffffffc016f930 /proc/kallsyms
ffffffffc016f930 r msg_ops      [tipc]
/tmp>

Based on this, it seems that sock->ops is valid and correct, and my original assumption about corrupt address was wrong.  I'm left to conclude that the virtual address is correct, but page mapping operation is failing for some other reason.  

Strangely, the mapping fails only intermittently/temporarily.  I conclude this because only one of many processes using TIPC will oops out, while others continue unaffected.  This can be seen in the syslog above in the last 4 lines, as a TIPC link moves from Resetting->Lost->Established. 

Some other (less important?) details:
TIPC is the only protocol loaded as a module. 
Kernel is 64 bit, but userspace is O32 due to some old 3rd party libraries.  
Typically, the processes running TIPC have their core mask set to 0x000F, to limit them to cores 0-3.  I'm repeating the tests with all processes running only on core 0 to see if SMP might be a factor.  


What might be going on here?  Could a page mapping fail even if the VA has a physical mapping in the page table?  Could TIPC module be at fault (how)?  What else can I look at to track down what might be happening?  

Best regards, 

-Erich

 		 	   		  
From wuzhangjin@gmail.com Fri Jan  7 18:10:06 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 18:10:10 +0100 (CET)
Received: from mail-wy0-f177.google.com ([74.125.82.177]:50545 "EHLO
        mail-wy0-f177.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1490991Ab1AGRKG convert rfc822-to-8bit
        (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Fri, 7 Jan 2011 18:10:06 +0100
Received: by wyf22 with SMTP id 22so17501876wyf.36
        for <multiple recipients>; Fri, 07 Jan 2011 09:09:50 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:mime-version:received:received:in-reply-to
         :references:date:message-id:subject:from:to:cc:content-type
         :content-transfer-encoding;
        bh=9xnbrlf9LM+qdRt7HEFbJvP/KZQadpWooDrf9PDG7II=;
        b=sjoUXsKEG6aMaGT4qG6uQqhxwuDe6QfOdl7kAD4kv2kzYiNWmOkENesuD8eSXNyQPB
         C55M+oAV+UcPtPDW0wtVNSiDhRywCJ501qn8Ij64eC56cKZ1WgPZYBCoTYwVv/t8JRS8
         RHazWxP/sTPboViOSQblrAgVeMwQId831OneI=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=mime-version:in-reply-to:references:date:message-id:subject:from:to
         :cc:content-type:content-transfer-encoding;
        b=mZTeHX2alWFg6nzZ26Qe1udHojzYL084qDw/27VpYrB6ypSJJ1mp+6MAD6FvUkbopX
         iOwGhyKYol6F9HQZLHJNPub5RwL0RGTJRUTJDUizJhSDi9X+sPkVUNtvAyMyJN0T3yUk
         M0hoBKQVTNvKdzOJAnehpWypmds87qGc91P5c=
MIME-Version: 1.0
Received: by 10.216.180.76 with SMTP id i54mr1989532wem.33.1294419816630; Fri,
 07 Jan 2011 09:03:36 -0800 (PST)
Received: by 10.216.93.137 with HTTP; Fri, 7 Jan 2011 09:03:36 -0800 (PST)
In-Reply-To: <4D2665CF.2080703@am.sony.com>
References: <4D2665CF.2080703@am.sony.com>
Date:   Sat, 8 Jan 2011 01:03:36 +0800
Message-ID: <AANLkTimTYox05y2_O8Tt+Ox1XCBVUmL-jFjtWZrPjTj7@mail.gmail.com>
Subject: Re: [Celinux-dev] Proposal: fastboot parameter cache for Linux
From:   wu zhangjin <wuzhangjin@gmail.com>
To:     Tim Bird <tim.bird@am.sony.com>
Cc:     CE Linux Developers List <celinux-dev@tree.celinuxforum.org>,
        Ralf Baechle <ralf@linux-mips.org>,
        linux-mips <linux-mips@linux-mips.org>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8BIT
Return-Path: <wuzhangjin@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: 28882
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: wuzhangjin@gmail.com
Precedence: bulk
X-list: linux-mips

Hi, Tim

This is really a wonderful idea, I have thought something similar
today, except caching the parameters in some place, we may be possible
to ask gcc to re-compile the kernel with these parameters(or we can
call them 'run time statistic data') and eliminate some of the
unnecessary branches and calling paths.

To record the persistent parameters at run-time, we may be possible to
mark those parameters as __runtime_fixed and put them into one section
__runtime_fixed_param, once running the kernel, those parameters can
be dumped out with a standard interface(/proc or /sys?), some of them
can be stored in some place and the others can be used to re-compile
the kernel.

For the persistent parameters, the variables marked as __read_mostly
can the candidates, but may be not most of them. so, this may need the
kernel developers carefully mark the variables as __runtime_fixed to
get better optimization.

For the re-compiling stuff, the MIPS specific cpu-feature-overrides.h
strategy is really a good example, lots of macros have been defined in
a common cpu-features.h, e.g.:

#ifndef current_cpu_type
#define current_cpu_type()      current_cpu_data.cputype
#endif

If no static definition of current_cpu_type defined in the board's
cpu-feature-overrides.h, the probed value will be used and the probing
is necessary, otherwise, the related branches and calling paths will
be optimized by the compiler. As a result, both of the boot time and
kernel image size will be saved.

Currently, in mainline linux-MIPS, this cpu-feature-overrides.h is
added by users manually, but why not provide an interface to dump them
out? yup, we can, I added a new kernel config and allow users to dump
the macros for cpu-feature-overrides.h automatically via the
traditional /proc/cpuinfo interface:
http://dev.lemote.com/cgit/linux-loongson-community.git/commit/?h=tiny36&id=56ab52376298dee38aeb27d065c1a20ef94739c3

But perhaps we can take one step ahead, that is we can mark more
run-time-persistent variables as __runtime_fixed(is this name okay?)
and dump them out, cache them for kernel to avoid probing or
re-compile the kernel with them for further optimization.

BTW, I will send a proposal about "Linux-Tiny for MIPS", I have
already done some work on it, that is:

http://dev.lemote.com/cgit/linux-loongson-community.git/log/?h=tiny36

I have forward ported most of the Linux-tiny patches from 2.6.23 to
2.6.36, has made --gc-sections -ffunction-sections -fdata-sections
work on MIPS, and also, some MIPS specific size & boot time reducing
methods has been applied: allow the software or hardware fpu support
be configurable, add more macros in cpu-features.h and allow the users
to dump out the macros and get a cpu-feature-overrides.h
automatically.  The next step is trying to make -fwhole-program -flto
work instead of the old -fwhole-program -combine(gcc doesn't work well
with __attribute__((externally_visible))).

Best Regards,
Wu Zhangjin

On Fri, Jan 7, 2011 at 9:01 AM, Tim Bird <tim.bird@am.sony.com> wrote:
> Fastboot parameter cache for Linux
>
> ; Summary: Fastboot parameter cache for Linux
>
> ; Proposer: Tim Bird
>
> == Description ==
> This proposal would be the creation and mainlining of a fastboot
> parameter cache for the Linux kernel.
>
> The purpose of this cache would be to store values which are
> detected in one boot of the Linux kernel, so they can be
> quickly accessed and used on subsequent boots of the kernel,
> to reduce kernel initialization time (specifically, to avoid
> unneeded probing for non-changing hardware.)
>
> The idea would be to provide an internal facility (API)
> inside the kernel that drivers could use to query for
> hardware parameters, prior to probing.  If a value is found,
> then the probe can be avoided.  If not, then probing is
> done as usual.  It would be important to have a very unintrusive and
> easy-to-use API for this.
>
> The mechanism would need to support a method of persistently storing
> the values for future kernel invocations (for example, by storing
> them in persistent memory, in a device tree, passing them on the
> kernel command line, or attaching them to the kernel boot image)
>
> This can be seen as a generalization of the way probing/autodetection
> is avoided by using a command line parameter for loops_per_jiffy.
>
> Andrew Murray proposed this under the name "boot cache", in August, 2010
> to the kernel mailing list.
>
> == Related work ==
> * See Andrew Murray's talk at ELC Europe 2010 - The Right Approach to Minimal Boot Times
> ** http://elinux.org/images/f/f7/RightApproachMinimalBootTimes.pdf
> * See [[Preset LPJ]] for a description of how preset loops_per_jiffy works
> * Andrew Murray's RFC and discussion on LKML:
> ** See https://lkml.org/lkml/2010/8/31/347
>
> == Scope ==
> The mechanism could probably be developed in 4 to 8 weeks.  Mainlining it
> might take 4 to 6 additional weeks.
>
> == Contractor Candidates ==
>
> == Comments ==
>
> [[Category:Project proposals 2011]]
>
> _______________________________________________
> Celinux-dev mailing list
> Celinux-dev@tree.celinuxforum.org
> http://tree.celinuxforum.org/mailman/listinfo/celinux-dev
>

From kevink@paralogos.com Fri Jan  7 19:46:28 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 07 Jan 2011 19:46:31 +0100 (CET)
Received: from gateway14.websitewelcome.com ([67.18.70.2]:53981 "HELO
        gateway14.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1490981Ab1AGSq2 (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 7 Jan 2011 19:46:28 +0100
Received: (qmail 7244 invoked from network); 7 Jan 2011 18:48:44 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway14.websitewelcome.com with SMTP; 7 Jan 2011 18:48:44 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=uTXH/tK2g8prZGl4qiobaAU2NGYK8BcKTw4nOoMVK7hDWpmP/mDUyKLas3OWj3f8CdIH9emDx2cxayZL4iTM27pxJK6/syJt4ow6x6CsVFi7qhNIXWqOqRKvVPbn/v33;
Received: from [216.239.45.4] (port=1541 helo=kkissell.mtv.corp.google.com)
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1PbHKQ-0003TC-9N; Fri, 07 Jan 2011 12:46:22 -0600
Message-ID: <4D275F80.2000307@paralogos.com>
Date:   Fri, 07 Jan 2011 10:46:24 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101208 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Anoop P A <anoop.pa@gmail.com>
CC:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Subject: Re: SMTC support status in latest git head.
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>      <1293470392.27661.202.camel@paanoop1-desktop>   <1293524389.27661.210.camel@paanoop1-desktop>   <4D19A31E.1090905@paralogos.com>        <1293798476.27661.279.camel@paanoop1-desktop>   <4D1EE913.1070203@paralogos.com>        <1294067561.27661.293.camel@paanoop1-desktop>   <4D21F5D3.50604@paralogos.com>  <1294082426.27661.330.camel@paanoop1-desktop>   <4D22D7B3.2050609@paralogos.com>        <1294146165.27661.361.camel@paanoop1-desktop>   <1294151822.27661.375.camel@paanoop1-desktop>   <4D235717.1000603@paralogos.com>        <1294163657.27661.386.camel@paanoop1-desktop>   <4D2367EE.7000702@paralogos.com>        <1294233097.27661.391.camel@paanoop1-desktop>   <4D24C525.5000306@paralogos.com>        <1294345396.27661.422.camel@paanoop1-desktop>   <4D2650D6.4030102@paralogos.com> <1294387019.27661.458.camel@paanoop1-desktop>
In-Reply-To: <1294387019.27661.458.camel@paanoop1-desktop>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28883
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

On 01/06/11 23:56, Anoop P A wrote:
> On Thu, 2011-01-06 at 15:31 -0800, Kevin D. Kissell wrote:
>> I'm sure I've said this before, and it's in various comments in the SMTC
>> code, but...
As an aside to this conversation, would it be possible to create a
Documentation/mips/SMTC.txt file that would actually propagate
upstream, so that I'd stop being the sole repository of SMTC folklore?
I only maintain it as a hobby.
> Ok. Well thanks much for your detailed explanation. Well I hope I found
> the root cause . smtc_clockevent_init() was overriding irq_hwmask even
> if are using platform specific get_c0_compare_int. With following patch
> everything seems to be working for me.
> ------------------------------------------------------------------------
> diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c
> index 2e72d30..a25fc59 100644
> --- a/arch/mips/kernel/cevt-smtc.c
> +++ b/arch/mips/kernel/cevt-smtc.c
> @@ -310,9 +310,14 @@ int __cpuinit smtc_clockevent_init(void)
>   		return 0;
>   	/*
>   	 * And we need the hwmask associated with the c0_compare
> -	 * vector to be initialized.
> +	 * vector to be initialized. However incase of platform
> +	 * specific get_co_compare_int, don't override irq_hwmask
> +	 * expect platform code to set a valid mask value.
>   	 */
> -	irq_hwmask[irq] = (0x100<<  cp0_compare_irq);
> +
> +	if (!get_c0_compare_int)
> +		irq_hwmask[irq] = (0x100<<  cp0_compare_irq);
> +
>   	if (cp0_timer_irq_installed)
>   		return 0;
> -----------------------------------------------------------------------
I'm still not clear on one point that, to me, is pretty important when
engineering a fix here.  Are you, in fact, using the Count/Compare
interrupt system, but having the externalization of the compare
interrupt routed back through an intervening interrupt controller,
or is your timer coming from another source?

In the former case, I think you're on the right track as to the
possible cause of a problem, but the fix should actually be simpler
and rather more elegant.  Why can't you simply see to it that
cp0_compare_irq is set to the right value, either at compile time,
or in your earliest platform initialization of the interrupt controller?
That would be a one-line, inline change and spare us another
cryptic conditional.

In the later case, you'll presumably be having lots of other problems,
as cevt-smtc.c is intertwined with cevt-r4k.c and the Count/Compare
paradigm.

             Regards,

             Kevin K.


From fs.rajat@gmail.com Sat Jan  8 11:24:37 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 08 Jan 2011 11:24:40 +0100 (CET)
Received: from mail-qy0-f170.google.com ([209.85.216.170]:52978 "EHLO
        mail-qy0-f170.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491022Ab1AHKYh convert rfc822-to-8bit
        (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Sat, 8 Jan 2011 11:24:37 +0100
Received: by qyk10 with SMTP id 10so228758qyk.15
        for <linux-mips@linux-mips.org>; Sat, 08 Jan 2011 02:24:30 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:mime-version:in-reply-to:references:date
         :message-id:subject:from:to:cc:content-type
         :content-transfer-encoding;
        bh=eVAO3bOZwEJCQQYP+B7+6XVt2pdHeADu8OYzsWH8nUg=;
        b=jQ2OqWeWObEHHq4V2dg4kzdegv6QFBuWlk4bPQUkMkG0SorIOCH6H7mu1J0g56XL/i
         MW9y8dqk1gIK0+897DU1HJOnxTjyyK7vRdnKL/2PwrMAR1gp9o0gbcPPxjjcbUtjd/Pn
         JrZ8XyEeXmzM8H2I3qCbDyEskna/aMGWVNA4I=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=mime-version:in-reply-to:references:date:message-id:subject:from:to
         :cc:content-type:content-transfer-encoding;
        b=emuy8NLEVxoCqkTGWXLH6Br+1kdDmqOwOE+TPuwXPtsreE+WAUtyhmRFkpG/l/VNTr
         MbpKYoN/AzUpvKWadlPQ+VdL0t0l0MJiqOHVLne7IJ+5+KXNAnsRBEkO2c3RKY4VmYcL
         pyorrKfwWGJk1SyTJ+prISiAkM85h5s69/euo=
MIME-Version: 1.0
Received: by 10.229.81.12 with SMTP id v12mr3483728qck.132.1294482270626; Sat,
 08 Jan 2011 02:24:30 -0800 (PST)
Received: by 10.229.88.205 with HTTP; Sat, 8 Jan 2011 02:24:30 -0800 (PST)
In-Reply-To: <AANLkTi=zq=Tq+UxZMxdJRXWz=EZQ-oyf1gorm0uysPjk@mail.gmail.com>
References: <AANLkTikFNZiM9=Ym2sfZpstjse-zR69fh28OZ_aedUFe@mail.gmail.com>
        <AANLkTi=b52Aprg7G-bXo84W+_Ru6=VigUHRHGGDf-Y51@mail.gmail.com>
        <AANLkTimiXgBQr1arUdGgxGXnfqtoMvCMQivcujYc9VS0@mail.gmail.com>
        <AANLkTi=E7Q9kJvG1KUPv2xS3WK_12byksSrVH_g2UST2@mail.gmail.com>
        <AANLkTimR7PyJS000BsA-Q=pRXXY9Wht6_QtkRowv=OLM@mail.gmail.com>
        <AANLkTi=TgZd8XS410kYfiLp79M-=-8etgg0VEZGUme3N@mail.gmail.com>
        <AANLkTi=zq=Tq+UxZMxdJRXWz=EZQ-oyf1gorm0uysPjk@mail.gmail.com>
Date:   Sat, 8 Jan 2011 15:54:30 +0530
Message-ID: <AANLkTimGNYeg=xZJy4qr9KmSpAMsy5Ss_pF18mwi1KrM@mail.gmail.com>
Subject: Re: Questions about complete
From:   Rajat Sharma <fs.rajat@gmail.com>
To:     loody <miloody@gmail.com>
Cc:     Linux MIPS Mailing List <linux-mips@linux-mips.org>,
        kernelnewbies@kernelnewbies.org
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8BIT
Return-Path: <fs.rajat@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: 28884
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: fs.rajat@gmail.com
Precedence: bulk
X-list: linux-mips

> B try to complete but cpu timer keep firing and at 8 it is time out.
> My platform is mips and is there any possibility to only let cpu timer
> be preemptible?
>

This seems really strange because when B calls complete, it sets up
condition variable value i.e. completion->done++ by disabling the
local interrupts. Following is code snippet from complete function:

        spin_lock_irqsave(&x->wait.lock, flags);
                   // This will disable interrupts
        x->done++;
                            // signals completion
        __wake_up_common(&x->wait, TASK_NORMAL, 1, 0, NULL);
        spin_unlock_irqrestore(&x->wait.lock, flags);

So now even if process A does not get a chance to execute and
completion timeout occurs before that, as you have shown in your
example, process A would still correctly knows about completion
because x->done was already set. Pleas look at the code snippet for
do_wait_for_common called from wait_for_completion_timeout:

          if (!x->done) {
                 ....
                 do {
                          ....
                 } while (!x->done && timeout);
                __remove_wait_queue(&x->wait, &wait);
                if (!x->done)
                        return timeout;
        }
        x->done--;
        return timeout ?: 1;

From above code, even if timeout expires i.e. timeout=0 and x->done is
already set, this function will still return 1.

> BTW, in x86 or other ARCH, will they try to let timer ISR be preemptible?

completion functions taking spin_lock_irqsave, so timer ISR should not
preempt the complete API.

Rajat

On Fri, Jan 7, 2011 at 7:51 PM, loody <miloody@gmail.com> wrote:
>
> hi all:
>
> 2011/1/6 Rajat Sharma <fs.rajat@gmail.com>:
> > Hi loody,
> >
> > calling complete will make the waiter process runnable but won't
> > necessarily switch to waiter thread and make it run. Its upto
> > scheduler to pick this process from run queue and execute based on its
> > priority value. I think there is not deterministic time in which the
> > waiter process will start executing.
> >
> > Probably what you want to do is calibrate timeout value in
> > wait_for_completion_timeout. I would suggest to do a binary search
> > between minimum timeout value (latency by which function A calls
> > complete, though this process can also schedule in between) to max
> > value (max your application can afford).
> >
> > Rajat
> >
> > On Thu, Jan 6, 2011 at 1:35 PM, loody <miloody@gmail.com> wrote:
> >> hi:
> >>
> >> 2011/1/6 Pavan Savoy <pavan_savoy@sify.com>:
> >>> On Thu, Jan 6, 2011 at 12:23 PM, loody <miloody@gmail.com> wrote:
> >>>> hi:
> >>>>
> >>>> 2011/1/6 Pavan Savoy <pavan_savoy@sify.com>:
> >>>>> On Thu, Jan 6, 2011 at 11:48 AM, loody <miloody@gmail.com> wrote:
> >>>>>>
> >>>>>> Dear all:
> >>>>>> I know complete will wake up the process who call wait_complete.
> >>>>>> Is there any methods I can use to measure how long from calling
> >>>>>> complete to the process that detect done=1?
> >>>>>> Regards,
> >>>>>> miloody
> >>>>>
> >>>>> returned value of wait_for_completion_timeout ?
> >>>> No.
> >>>> I want to measure the duration of complete to the time of wake up
> >>>> process who is pending on wait.
> >>>
> >>> Ah, Ok, Got it...
> >>> I would do a copy of jiffies before the complete and do a diff for
> >>> jiffies after the
> >>> wait_for_ ...
> >>>
> >>> I suppose there would be much more better/optimized way ....
> >> thank U :)
> >> why I ask so is I am porting kernel to other platform right now.
> >> and I found the time of getting complete is too long.
> >> What I mean is
> >> function A call wait_complete_timeout
> >> function B complete
> >> theoretically A will get complete and leave successfully
> >> but my platform A will told me that before timeout the complete is not got.
>
> I doubt my problem comes from cpu timer interrupt is so often such
> that when function B get the change to complete, the left time is
> almost exhausted.
> for not to be confused, I take following jiffies for example:
> 1               2            3            4            5
> 6            8
> start wait                                      B try complete
>       time out
>
> B try to complete but cpu timer keep firing and at 8 it is time out.
> My platform is mips and is there any possibility to only let cpu timer
> be preemptible?
>
> BTW, in x86 or other ARCH, will they try to let timer ISR be preemptible?
>
>
> --
> Regards,
> miloody
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies@kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

From kevink@paralogos.com Sat Jan  8 19:40:55 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 08 Jan 2011 19:40:58 +0100 (CET)
Received: from gateway13.websitewelcome.com ([67.18.22.80]:43687 "HELO
        gateway13.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1491026Ab1AHSkz (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sat, 8 Jan 2011 19:40:55 +0100
Received: (qmail 32457 invoked from network); 8 Jan 2011 18:39:49 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway13.websitewelcome.com with SMTP; 8 Jan 2011 18:39:49 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=SQN9rpsavQuvnjBeKD8tE9PHawPGQ1OgZwoy6WyiAYoJH9U0skS1XZIg7MVTqrGk/SoG9m03YhweBEAmwP1Z3Fs7txKWXDvY+3qlh5kL8qMX9QV2SAEce3sioDzb/dtK;
Received: from c-98-207-157-135.hsd1.ca.comcast.net ([98.207.157.135]:1442 helo=[127.0.0.1])
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
        id 1Pbdia-0005ix-UG; Sat, 08 Jan 2011 12:40:49 -0600
Message-ID: <4D28AFB4.7090108@paralogos.com>
Date:   Sat, 08 Jan 2011 10:40:52 -0800
From:   "Kevin D. Kissell" <kevink@paralogos.com>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7
MIME-Version: 1.0
To:     Linux MIPS org <linux-mips@linux-mips.org>,
        tsbogend@alpha.franken.de
Subject: MIPS Malta and PCNet32 Driver
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - gator750.hostgator.com
X-AntiAbuse: Original Domain - linux-mips.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - paralogos.com
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Return-Path: <kevink@paralogos.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: 28885
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: kevink@paralogos.com
Precedence: bulk
X-list: linux-mips

As per an email to the linux-mips group from Thomas Schwinge on July 30,
2010, there's a problem using current (post 2.6.29) sources for a kernel
with the pcnet32 driver with the PCNet32 chip on the MIPS Malta platform
in some configurations.  The probe1 routine fails the test below and
spits out the "No access methods" diagnostic:

...
        /* NOTE: 16-bit check is first, otherwise some older PCnet chips
fail */
        if (pcnet32_wio_read_csr(ioaddr, 0) == 4 &&
pcnet32_wio_check(ioaddr)) {
                a = &pcnet32_wio;
        } else {
                pcnet32_dwio_reset(ioaddr);
                if (pcnet32_dwio_read_csr(ioaddr, 0) == 4
                    && pcnet32_dwio_check(ioaddr)) {
                        a = &pcnet32_dwio;
                } else {
                        if (pcnet32_debug & NETIF_MSG_PROBE)
                                printk(KERN_ERR PFX "No access methods\n");
                        goto err_release_region;
                }
        }

The chip is visible to the kernel and turns up in lspci:

-bash-3.1# lspci -tv
-[0000:00]-+-0a.0  Intel Corporation 82371AB/EB/MB PIIX4 ISA
           +-0a.1  Intel Corporation 82371AB/EB/MB PIIX4 IDE
           +-0a.2  Intel Corporation 82371AB/EB/MB PIIX4 USB
           +-0a.3  Intel Corporation 82371AB/EB/MB PIIX4 ACPI
           +-0b.0  Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
           +-0c.0  Cirrus Logic Crystal CS4281 PCI Audio
           +-11.0  MIPS Technologies, Inc. SOC-it 101 System Controller
           \-13.0-[0000:01]----00.0  Matrox Graphics, Inc. G400/G450
-bash-3.1# lspci -n
00:0a.0 0601: 8086:7110 (rev 02)
00:0a.1 0101: 8086:7111 (rev 01)
00:0a.2 0c03: 8086:7112 (rev 01)
00:0a.3 0680: 8086:7113 (rev 02)
00:0b.0 0200: 1022:2000 (rev 44)
00:0c.0 0401: 1013:6005 (rev 01)
00:11.0 0600: 153f:0001 (rev 01)
00:13.0 0604: 3388:0021 (rev 13)
01:00.0 0300: 102b:0525 (rev 85)

I'm suspecting that the problem is at least as likely to be in the Malta
PCI support as in the PCNet driver itself.  Is this phenomenon
understood? Has there been a fix circulated for it?

            Regards,

            Kevin K.

From anoop.pa@gmail.com Sat Jan  8 20:34:00 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 08 Jan 2011 20:34:03 +0100 (CET)
Received: from mail-fx0-f49.google.com ([209.85.161.49]:41674 "EHLO
        mail-fx0-f49.google.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with ESMTP id S1491026Ab1AHTeA convert rfc822-to-8bit
        (ORCPT <rfc822;linux-mips@linux-mips.org>);
        Sat, 8 Jan 2011 20:34:00 +0100
Received: by fxm19 with SMTP id 19so17220132fxm.36
        for <linux-mips@linux-mips.org>; Sat, 08 Jan 2011 11:33:54 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:mime-version:received:received:in-reply-to
         :references:date:message-id:subject:from:to:cc:content-type
         :content-transfer-encoding;
        bh=s3x+vER1dHBDK5f6jr2dRooywVSNQNKrAMpNtHlyLaw=;
        b=CB3Df+MY/Hu9VqfUK5Jy3dFUpiwRJ0zNaApaCqF+VZpaEN97qJsxnArfC8QMdA/2ii
         RUYRwT2tQ5BmEbxpP1N3c/VLr3IwQd7GNSJ3f55C8TMvLYTkumaXXtxlDbV27eOxjjTY
         WO4CvP1TGMPhlYqzw09k4ck5VpW6JfaRf7QjQ=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=mime-version:in-reply-to:references:date:message-id:subject:from:to
         :cc:content-type:content-transfer-encoding;
        b=aRCBSJ8EHQbUNniuZs+vA5YKSU+BJBRktG+dc1kUP94NZwbul3w1LmfYf86paymPEz
         LcqNNCkJ4liuJ0gtPLCUFhMUww2XAuh60bnRbvki2uci+t7U4L303V/28j/pxXhLMZlM
         hg2RLyBiS0JP0CrYtMtir+5daHrJ/U7rAzMHA=
MIME-Version: 1.0
Received: by 10.223.100.16 with SMTP id w16mr181825fan.85.1294515233261; Sat,
 08 Jan 2011 11:33:53 -0800 (PST)
Received: by 10.223.74.136 with HTTP; Sat, 8 Jan 2011 11:33:53 -0800 (PST)
In-Reply-To: <4D275F80.2000307@paralogos.com>
References: <8F242B230AD6474C8E7815DE0B4982D7179FB88F@EXV1.corp.adtran.com>
        <1293470392.27661.202.camel@paanoop1-desktop>
        <1293524389.27661.210.camel@paanoop1-desktop>
        <4D19A31E.1090905@paralogos.com>
        <1293798476.27661.279.camel@paanoop1-desktop>
        <4D1EE913.1070203@paralogos.com>
        <1294067561.27661.293.camel@paanoop1-desktop>
        <4D21F5D3.50604@paralogos.com>
        <1294082426.27661.330.camel@paanoop1-desktop>
        <4D22D7B3.2050609@paralogos.com>
        <1294146165.27661.361.camel@paanoop1-desktop>
        <1294151822.27661.375.camel@paanoop1-desktop>
        <4D235717.1000603@paralogos.com>
        <1294163657.27661.386.camel@paanoop1-desktop>
        <4D2367EE.7000702@paralogos.com>
        <1294233097.27661.391.camel@paanoop1-desktop>
        <4D24C525.5000306@paralogos.com>
        <1294345396.27661.422.camel@paanoop1-desktop>
        <4D2650D6.4030102@paralogos.com>
        <1294387019.27661.458.camel@paanoop1-desktop>
        <4D275F80.2000307@paralogos.com>
Date:   Sun, 9 Jan 2011 01:03:53 +0530
Message-ID: <AANLkTi=CD+RmXNsukqmpH5xwTbwfnEr5LK92tJf-FsSn@mail.gmail.com>
Subject: Re: SMTC support status in latest git head.
From:   Anoop P A <anoop.pa@gmail.com>
To:     "Kevin D. Kissell" <kevink@paralogos.com>
Cc:     STUART VENTERS <stuart.venters@adtran.com>,
        "Anoop P.A." <Anoop_P.A@pmc-sierra.com>, linux-mips@linux-mips.org
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8BIT
Return-Path: <anoop.pa@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: 28886
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: anoop.pa@gmail.com
Precedence: bulk
X-list: linux-mips

On Sat, Jan 8, 2011 at 12:16 AM, Kevin D. Kissell <kevink@paralogos.com> wrote:
> On 01/06/11 23:56, Anoop P A wrote:
>>
>> On Thu, 2011-01-06 at 15:31 -0800, Kevin D. Kissell wrote:
>>>
>>> I'm sure I've said this before, and it's in various comments in the SMTC
>>> code, but...
>
> As an aside to this conversation, would it be possible to create a
> Documentation/mips/SMTC.txt file that would actually propagate
> upstream, so that I'd stop being the sole repository of SMTC folklore?
> I only maintain it as a hobby.
>>
>> Ok. Well thanks much for your detailed explanation. Well I hope I found
>> the root cause . smtc_clockevent_init() was overriding irq_hwmask even
>> if are using platform specific get_c0_compare_int. With following patch
>> everything seems to be working for me.
>> ------------------------------------------------------------------------
>> diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c
>> index 2e72d30..a25fc59 100644
>> --- a/arch/mips/kernel/cevt-smtc.c
>> +++ b/arch/mips/kernel/cevt-smtc.c
>> @@ -310,9 +310,14 @@ int __cpuinit smtc_clockevent_init(void)
>>                return 0;
>>        /*
>>         * And we need the hwmask associated with the c0_compare
>> -        * vector to be initialized.
>> +        * vector to be initialized. However incase of platform
>> +        * specific get_co_compare_int, don't override irq_hwmask
>> +        * expect platform code to set a valid mask value.
>>         */
>> -       irq_hwmask[irq] = (0x100<<  cp0_compare_irq);
>> +
>> +       if (!get_c0_compare_int)
>> +               irq_hwmask[irq] = (0x100<<  cp0_compare_irq);
>> +
>>        if (cp0_timer_irq_installed)
>>                return 0;
>> -----------------------------------------------------------------------
>
> I'm still not clear on one point that, to me, is pretty important when
> engineering a fix here.  Are you, in fact, using the Count/Compare
> interrupt system, but having the externalization of the compare
> interrupt routed back through an intervening interrupt controller,
> or is your timer coming from another source?
>
> In the former case, I think you're on the right track as to the
> possible cause of a problem, but the fix should actually be simpler
> and rather more elegant.  Why can't you simply see to it that
> cp0_compare_irq is set to the right value, either at compile time,
> or in your earliest platform initialization of the interrupt controller?
> That would be a one-line, inline change and spare us another
> cryptic conditional.

Yes ,it is first case.

http://git.linux-mips.org/?p=linux.git;a=commit;h=38760d40ca61b18b2809e9c28df8b3ff9af8a02b

Above mentioned patch enables platforms to utilize 4k timer code with
platform specific timer interrupts. cevt-smtc also had ( copied from cevt-r4k)
referred code. Given the specific irq  support in cevt-smtc we should add
support for specific hwmask , IMHO.

>
> In the later case, you'll presumably be having lots of other problems,
> as cevt-smtc.c is intertwined with cevt-r4k.c and the Count/Compare
> paradigm.
>
>            Regards,
>
>            Kevin K.
>
>

From kevink@paralogos.com Sat Jan  8 21:02:19 2011
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 08 Jan 2011 21:02:22 +0100 (CET)
Received: from gateway08.websitewelcome.com ([69.56.159.17]:42828 "HELO
        gateway08.websitewelcome.com" rhost-flags-OK-OK-OK-OK)
        by eddie.linux-mips.org with SMTP id S1491026Ab1AHUCS (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Sat, 8 Jan 2011 21:02:18 +0100
Received: (qmail 11715 invoked from network); 8 Jan 2011 20:01:45 -0000
Received: from gator750.hostgator.com (174.132.194.2)
  by gateway08.websitewelcome.com with SMTP; 8 Jan 2011 20:01:45 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=paralogos.com;
        h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-Source:X-Source-Args:X-Source-Dir;
        b=PwbZgVu+u5JJAW7ln0/Gj34FplnapnFhUOEQ34nGoG2V80l5z1YSQaHUXKZBH4fSQB5lfuLYe15D4fJkpYJnS3W3OKGkbOZk/JyVPTK/VUS9+p8y+tYziVdvCH8L2Lk3;
Received: from c-98-207-157-135.hsd1.ca.comcast.net ([98.207.157.135]:1585 helo=[127.0.0.1])
        by gator750.hostgator.com with esmtpa (Exim 4.69)
        (envelope-from <kevink@paralogos.com>)
  