Module Name: src
Committed By: matt
Date: Tue May 24 17:45:49 UTC 2011
Modified Files:
src/sys/arch/arm/marvell: kirkwood.c
Log Message:
Merge in the patch in PR/44965 with some improvements (removing ifs when
possible).
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/marvell/kirkwood.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/marvell/kirkwood.c
diff -u src/sys/arch/arm/marvell/kirkwood.c:1.3 src/sys/arch/arm/marvell/kirkwood.c:1.4
--- src/sys/arch/arm/marvell/kirkwood.c:1.3 Sun May 22 21:52:25 2011
+++ src/sys/arch/arm/marvell/kirkwood.c Tue May 24 17:45:49 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kirkwood.c,v 1.3 2011/05/22 21:52:25 mellon Exp $ */
+/* $NetBSD: kirkwood.c,v 1.4 2011/05/24 17:45:49 matt Exp $ */
/*
* Copyright (c) 2010 KIYOHARA Takashi
* All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kirkwood.c,v 1.3 2011/05/22 21:52:25 mellon Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kirkwood.c,v 1.4 2011/05/24 17:45:49 matt Exp $");
#define _INTR_PRIVATE
@@ -49,12 +49,8 @@
static void kirkwood_intr_init(void);
-static void kirkwood_pic_unblock_low_irqs(struct pic_softc *, size_t, uint32_t);
-static void kirkwood_pic_unblock_high_irqs(struct pic_softc *, size_t,
- uint32_t);
-static void kirkwood_pic_block_low_irqs(struct pic_softc *, size_t, uint32_t);
-static void kirkwood_pic_block_high_irqs(struct pic_softc *, size_t, uint32_t);
-static int kirkwood_pic_find_pending_high_irqs(struct pic_softc *);
+static void kirkwood_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
+static void kirkwood_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
static void kirkwood_pic_establish_irq(struct pic_softc *, struct intrsource *);
static void kirkwood_pic_source_name(struct pic_softc *, int, char *, size_t);
@@ -80,28 +76,16 @@
"Reserved(60)", "Reserved(61)", "Reserved(62)", "Reserved(63)"
};
-static struct pic_ops kirkwood_picops_low = {
- .pic_unblock_irqs = kirkwood_pic_unblock_low_irqs,
- .pic_block_irqs = kirkwood_pic_block_low_irqs,
+static struct pic_ops kirkwood_picops = {
+ .pic_unblock_irqs = kirkwood_pic_unblock_irqs,
+ .pic_block_irqs = kirkwood_pic_block_irqs,
.pic_establish_irq = kirkwood_pic_establish_irq,
.pic_source_name = kirkwood_pic_source_name,
};
-static struct pic_ops kirkwood_picops_high = {
- .pic_unblock_irqs = kirkwood_pic_unblock_high_irqs,
- .pic_block_irqs = kirkwood_pic_block_high_irqs,
- .pic_find_pending_irqs = kirkwood_pic_find_pending_high_irqs,
- .pic_establish_irq = kirkwood_pic_establish_irq,
- .pic_source_name = kirkwood_pic_source_name,
-};
-static struct pic_softc kirkwood_pic_low = {
- .pic_ops = &kirkwood_picops_low,
- .pic_maxsources = 32,
- .pic_name = "kirkwood_low",
-};
-static struct pic_softc kirkwood_pic_high = {
- .pic_ops = &kirkwood_picops_high,
- .pic_maxsources = 32,
- .pic_name = "kirkwood_high",
+static struct pic_softc kirkwood_pic = {
+ .pic_ops = &kirkwood_picops,
+ .pic_maxsources = 64,
+ .pic_name = "kirkwood",
};
@@ -141,12 +125,7 @@
extern struct pic_softc mvsoc_bridge_pic;
void *ih;
- pic_add(&kirkwood_pic_low, 0);
-
- pic_add(&kirkwood_pic_high, 32);
- ih = intr_establish(KIRKWOOD_IRQ_HIGH, IPL_HIGH, IST_LEVEL_HIGH,
- pic_handle_intr, &kirkwood_pic_high);
- KASSERT(ih != NULL);
+ pic_add(&kirkwood_pic, 0);
pic_add(&mvsoc_bridge_pic, 64);
ih = intr_establish(KIRKWOOD_IRQ_BRIDGE, IPL_HIGH, IST_LEVEL_HIGH,
@@ -158,55 +137,26 @@
/* ARGSUSED */
static void
-kirkwood_pic_unblock_low_irqs(struct pic_softc *pic, size_t irqbase,
- uint32_t irq_mask)
+kirkwood_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
+ uint32_t irq_mask)
{
+ const size_t reg = KIRKWOOD_MLMB_MIRQIMLR
+ + irqbase * (KIRKWOOD_MLMB_MIRQIMHR - KIRKWOOD_MLMB_MIRQIMLR) / 32;
- write_mlmbreg(KIRKWOOD_MLMB_MIRQIMLR,
- read_mlmbreg(KIRKWOOD_MLMB_MIRQIMLR) | irq_mask);
+ KASSERT(irqbase < 64);
+ write_mlmbreg(reg, read_mlmbreg(reg) | irq_mask);
}
/* ARGSUSED */
static void
-kirkwood_pic_unblock_high_irqs(struct pic_softc *pic, size_t irqbase,
- uint32_t irq_mask)
+kirkwood_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
+ uint32_t irq_mask)
{
+ const size_t reg = KIRKWOOD_MLMB_MIRQIMLR
+ + irqbase * (KIRKWOOD_MLMB_MIRQIMHR - KIRKWOOD_MLMB_MIRQIMLR) / 32;
- write_mlmbreg(KIRKWOOD_MLMB_MIRQIMHR,
- read_mlmbreg(KIRKWOOD_MLMB_MIRQIMHR) | irq_mask);
-}
-
-/* ARGSUSED */
-static void
-kirkwood_pic_block_low_irqs(struct pic_softc *pic, size_t irqbase,
- uint32_t irq_mask)
-{
-
- write_mlmbreg(KIRKWOOD_MLMB_MIRQIMLR,
- read_mlmbreg(KIRKWOOD_MLMB_MIRQIMLR) & ~irq_mask);
-}
-
-/* ARGSUSED */
-static void
-kirkwood_pic_block_high_irqs(struct pic_softc *pic, size_t irqbase,
- uint32_t irq_mask)
-{
-
- write_mlmbreg(KIRKWOOD_MLMB_MIRQIMHR,
- read_mlmbreg(KIRKWOOD_MLMB_MIRQIMHR) & ~irq_mask);
-}
-
-static int
-kirkwood_pic_find_pending_high_irqs(struct pic_softc *pic)
-{
- uint32_t pending;
-
- pending = read_mlmbreg(KIRKWOOD_MLMB_MICHR) &
- read_mlmbreg(KIRKWOOD_MLMB_MIRQIMHR);
- if (pending == 0)
- return 0;
- pic_mark_pending_sources(pic, 0, pending);
- return 1;
+ KASSERT(irqbase < 64);
+ write_mlmbreg(reg, read_mlmbreg(reg) & ~irq_mask);
}
/* ARGSUSED */
@@ -229,14 +179,23 @@
static int
kirkwood_find_pending_irqs(void)
{
- uint32_t pending;
+ int ipl = 0;
+
+ uint32_t causelow = read_mlmbreg(KIRKWOOD_MLMB_MICLR);
+ uint32_t pendinglow = read_mlmbreg(KIRKWOOD_MLMB_MIRQIMLR);
- pending = read_mlmbreg(KIRKWOOD_MLMB_MICLR) &
- read_mlmbreg(KIRKWOOD_MLMB_MIRQIMLR);
- if (pending == 0)
- return 0;
+ pendinglow &= causelow;
+ if (pendinglow != 0)
+ ipl |= pic_mark_pending_sources(&kirkwood_pic, 0, pendinglow);
+
+ if ((causelow & KIRKWOOD_IRQ_HIGH) == KIRKWOOD_IRQ_HIGH) {
+ uint32_t causehigh = read_mlmbreg(KIRKWOOD_MLMB_MICHR);
+ uint32_t pendinghigh = read_mlmbreg(KIRKWOOD_MLMB_MIRQIMHR);
+ pendinghigh &= causehigh;
+ ipl |= pic_mark_pending_sources(&kirkwood_pic, 32, pendinghigh);
+ }
- return pic_mark_pending_sources(&kirkwood_pic_low, 0, pending);
+ return ipl;
}
/*