From: Songmao Tian <tiansm@lemote.com>
To: "Maciej W. Rozycki" <macro@linux-mips.org>
Cc: LinuxBIOS Mailing List <linuxbios@linuxbios.org>,
marc.jones@amd.com, linux-kernel@vger.kernel.org,
linux-mips@linux-mips.org
Subject: Re: about cs5536 interrupt ack
Date: Thu, 12 Jul 2007 15:26:07 +0800 [thread overview]
Message-ID: <4695D78F.8010806@lemote.com> (raw)
In-Reply-To: <Pine.LNX.4.64N.0707111634430.26459@blysk.ds.pg.gda.pl>
[-- Attachment #1: Type: text/plain, Size: 2210 bytes --]
8259 problem seems to be done with the attached patch, IDE hung seems
to be the dma setting problem.
Thanks all for your advise, comments. I have learned a lot. now I
continue to trace down the IDE problem.
Mao
Maciej W. Rozycki wrote:
> On Wed, 11 Jul 2007, Songmao Tian wrote:
>
>
>>> Huh? Have you managed to find an 8259A clone *that* broken? So what does
>>> it return if you write 0xc to the address 0x20 in the I/O port space and
>>> then read back from that location? You should complain to the
>>>
>>>
>> It's the value of IRR, so guess IRR. AMD has well documented cs5536, I
>> appreciate that.
>>
>
> Indeed. I am surprised they have decided to drop the poll command -- it
> surely does not require much logic as it mostly reuses what's used to
> produce the vector anyway and it is commonly used when 8259A
> implementations are interfaced to non-i386 processors. PPC is another
> example.
>
>
>>> More or less -- 3-5 should probably be the outcome of a single read
>>> transaction from the north bridge. I.e. you issue a read to a "magic"
>>> location, 3-5 happen, and the data value returned is the vector presented by
>>> the interrupt controller on the PCI bus.
>>>
>>>
>> yeah, we can implement a register in north bridge.
>>
>
> Strictly speaking it would not be a register, but a "PCI INTA address
> space" much like PCI memory or I/O port address spaces. Though as the
> former ignores addresses driven on the bus, the space occupied does not
> have to be extensive -- I would assume whatever slot size is available
> with the address decoder you have implemented would do.
>
>
>>> You can still dispatch interrupts manually by examining the IRR register,
>>> but having a way to ask the 8259A's prioritiser would be nice. Although
>>> given such a lethal erratum you report I would not count on the prioritiser
>>> to provide any useful flexibility...
>>>
>>>
>> yeah, that's a straight thought, tried but failed:(, patch followed.
>>
>
> You may have to modify other functions from arch/mips/kernel/i8259.c;
> yes, this makes the whole experience not as pretty as one would hope...
>
> Maciej
>
>
>
>
[-- Attachment #2: diff --]
[-- Type: text/plain, Size: 2758 bytes --]
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 9c79703..fd7f4ba 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -47,11 +47,7 @@ static struct irq_chip i8259A_chip = {
/*
* This contains the irq mask for both 8259A irq controllers,
*/
-static unsigned int cached_irq_mask = 0xffff;
-
-#define cached_master_mask (cached_irq_mask)
-#define cached_slave_mask (cached_irq_mask >> 8)
-
+unsigned int cached_irq_mask = 0xffff;
void disable_8259A_irq(unsigned int irq)
{
unsigned int mask;
diff --git a/include/asm-mips/i8259.h b/include/asm-mips/i8259.h
index e88a016..e7dcf7b 100644
--- a/include/asm-mips/i8259.h
+++ b/include/asm-mips/i8259.h
@@ -37,11 +37,55 @@
extern spinlock_t i8259A_lock;
+extern unsigned int cached_irq_mask;
+#define cached_master_mask (cached_irq_mask)
+#define cached_slave_mask (cached_irq_mask >> 8)
+
extern void init_8259A(int auto_eoi);
extern void enable_8259A_irq(unsigned int irq);
extern void disable_8259A_irq(unsigned int irq);
extern void init_i8259_irqs(void);
+#define CONFIG_NO_INTERRUPT_ACK
+#ifdef CONFIG_NO_INTERRUPT_ACK
+static inline int _byte_ffs(u8 word)
+{
+ int num = 0;
+ if ((word & 0xf) == 0) {
+ num += 4;
+ word >>= 4;
+ }
+ if ((word & 0x3) == 0) {
+ num += 2;
+ word >>= 2;
+ }
+ if ((word & 0x1) == 0)
+ num += 1;
+ return num;
+}
+
+static inline int read_irq(int port)
+{
+ int irq;
+ outb(0x0A, port);
+ if (port == PIC_MASTER_CMD) {
+ irq = inb(port) & ~cached_master_mask;
+ } else {
+ irq = inb(port) & ~cached_slave_mask;
+ }
+ if (irq == 0)
+ return -1;
+ else
+ return _byte_ffs(irq);
+}
+#else
+static inline int read_irq(int port)
+{
+ /* Perform an interrupt acknowledge cycle on controller 1. */
+ outb(0x0C, port); /* prepare for poll */
+ return inb(port) & 7;
+}
+#endif
/*
* Do the traditional i8259 interrupt polling thing. This is for the few
@@ -54,18 +98,16 @@ static inline int i8259_irq(void)
spin_lock(&i8259A_lock);
- /* Perform an interrupt acknowledge cycle on controller 1. */
- outb(0x0C, PIC_MASTER_CMD); /* prepare for poll */
- irq = inb(PIC_MASTER_CMD) & 7;
+ irq = read_irq(PIC_MASTER_CMD);
if (irq == PIC_CASCADE_IR) {
/*
* Interrupt is cascaded so perform interrupt
* acknowledge on controller 2.
*/
- outb(0x0C, PIC_SLAVE_CMD); /* prepare for poll */
- irq = (inb(PIC_SLAVE_CMD) & 7) + 8;
- }
+ irq = read_irq(PIC_SLAVE_CMD) + 8;
+ }
+#ifndef CONFIG_NO_INTERRUPT_ACK
if (unlikely(irq == 7)) {
/*
* This may be a spurious interrupt.
@@ -78,6 +120,11 @@ static inline int i8259_irq(void)
if(~inb(PIC_MASTER_ISR) & 0x80)
irq = -1;
}
+#else
+ if (cached_irq_mask & (1 << irq)) {
+ irq = -1;
+ }
+#endif
spin_unlock(&i8259A_lock);
next prev parent reply other threads:[~2007-07-12 7:26 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-11 9:36 about cs5536 interrupt ack Songmao Tian
2007-07-11 10:58 ` Songmao Tian
2007-07-11 13:24 ` Maciej W. Rozycki
2007-07-11 15:19 ` Songmao Tian
2007-07-11 15:38 ` Songmao Tian
2007-07-11 15:48 ` Maciej W. Rozycki
2007-07-11 16:51 ` Maciej W. Rozycki
2007-07-12 7:26 ` Songmao Tian [this message]
2007-07-16 15:11 ` Maciej W. Rozycki
2007-07-11 15:42 ` Sergei Shtylyov
2007-07-11 16:05 ` Maciej W. Rozycki
2007-07-11 15:22 ` Sergei Shtylyov
2007-07-11 15:31 ` Sergei Shtylyov
2007-07-11 15:35 ` Songmao Tian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4695D78F.8010806@lemote.com \
--to=tiansm@lemote.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@linux-mips.org \
--cc=linuxbios@linuxbios.org \
--cc=macro@linux-mips.org \
--cc=marc.jones@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.