summaryrefslogtreecommitdiff
path: root/drivers/s390/cio/cio.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-04-19 16:17:34 (GMT)
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-04-19 16:17:34 (GMT)
commitcf816ecb533ab96b883dfdc0db174598b5b5c4d2 (patch)
tree1b7705db288ae2917105e624b01fdf81e0882bf1 /drivers/s390/cio/cio.c
parentadf6d34e460387ee3e8f1e1875d52bff51212c7d (diff)
parent15f7d677ccff6f0f5de8a1ee43a792567e9f9de9 (diff)
downloadlinux-fsl-qoriq-cf816ecb533ab96b883dfdc0db174598b5b5c4d2.tar.xz
Merge branch 'merge-fixes' into devel
Diffstat (limited to 'drivers/s390/cio/cio.c')
-rw-r--r--drivers/s390/cio/cio.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 60590a1..23ffcc4 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -24,6 +24,7 @@
#include <asm/ipl.h>
#include <asm/chpid.h>
#include <asm/airq.h>
+#include <asm/cpu.h>
#include "cio.h"
#include "css.h"
#include "chsc.h"
@@ -649,13 +650,10 @@ do_IRQ (struct pt_regs *regs)
old_regs = set_irq_regs(regs);
irq_enter();
- asm volatile ("mc 0,0");
- if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer)
- /**
- * Make sure that the i/o interrupt did not "overtake"
- * the last HZ timer interrupt.
- */
- account_ticks(S390_lowcore.int_clock);
+ s390_idle_check();
+ if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
+ /* Serve timer interrupts first. */
+ clock_comparator_work();
/*
* Get interrupt information from lowcore
*/
@@ -672,10 +670,14 @@ do_IRQ (struct pt_regs *regs)
continue;
}
sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
- if (sch)
- spin_lock(sch->lock);
+ if (!sch) {
+ /* Clear pending interrupt condition. */
+ tsch(tpi_info->schid, irb);
+ continue;
+ }
+ spin_lock(sch->lock);
/* Store interrupt response block to lowcore. */
- if (tsch (tpi_info->schid, irb) == 0 && sch) {
+ if (tsch(tpi_info->schid, irb) == 0) {
/* Keep subchannel information word up to date. */
memcpy (&sch->schib.scsw, &irb->scsw,
sizeof (irb->scsw));
@@ -683,8 +685,7 @@ do_IRQ (struct pt_regs *regs)
if (sch->driver && sch->driver->irq)
sch->driver->irq(sch);
}
- if (sch)
- spin_unlock(sch->lock);
+ spin_unlock(sch->lock);
/*
* Are more interrupts pending?
* If so, the tpi instruction will update the lowcore
@@ -710,8 +711,9 @@ void *cio_get_console_priv(void)
/*
* busy wait for the next interrupt on the console
*/
-void
-wait_cons_dev (void)
+void wait_cons_dev(void)
+ __releases(console_subchannel.lock)
+ __acquires(console_subchannel.lock)
{
unsigned long cr6 __attribute__ ((aligned (8)));
unsigned long save_cr6 __attribute__ ((aligned (8)));