Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/s3c2xx0 + add an arg to s3c2800_intr_establish(...



details:   https://anonhg.NetBSD.org/src/rev/52ea2cc776ee
branches:  trunk
changeset: 547058:52ea2cc776ee
user:      bsh <bsh%NetBSD.org@localhost>
date:      Mon May 12 07:48:37 2003 +0000

description:
+ add an arg to s3c2800_intr_establish() for interrupt type:
  IST_EDGE_{FALLING,RISING,BOTH}, or IST_LEVEL_{LOW,HIGH}. This
  argument is valid only for GPIO interrupts (IRQ0..7).

+ Don't clear interrupt pending bits for IIC in interrupt handler.
  Since clearing these bits starts next IIC transmission immediately,
  IIC driver should handle these.

diffstat:

 sys/arch/arm/s3c2xx0/s3c2800_intr.c |  48 +++++++++++++++++++++++++++++++++---
 1 files changed, 44 insertions(+), 4 deletions(-)

diffs (94 lines):

diff -r 489b89bc9589 -r 52ea2cc776ee sys/arch/arm/s3c2xx0/s3c2800_intr.c
--- a/sys/arch/arm/s3c2xx0/s3c2800_intr.c       Mon May 12 06:05:52 2003 +0000
+++ b/sys/arch/arm/s3c2xx0/s3c2800_intr.c       Mon May 12 07:48:37 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: s3c2800_intr.c,v 1.3 2003/01/03 00:38:18 thorpej Exp $ */
+/* $NetBSD: s3c2800_intr.c,v 1.4 2003/05/12 07:48:37 bsh Exp $ */
 
 /*
  * Copyright (c) 2002 Fujitsu Component Limited
@@ -75,6 +75,15 @@
        IPL_SOFTNET,            /* SI_SOFTNET */
        IPL_SOFTSERIAL,         /* SI_SOFTSERIAL */
 };
+
+/*
+ *   Clearing interrupt pending bits affects some built-in
+ * peripherals.  For example, IIC starts transmitting next data when
+ * its interrupt pending bit is cleared.
+ *   We need to leave those bits to peripheral handlers.
+ */
+#define PENDING_CLEAR_MASK     (~((1<<S3C2800_INT_IIC0)|(1<<S3C2800_INT_IIC1)))
+
 /*
  * called from irq_entry.
  */
@@ -99,7 +108,7 @@
                        s3c2xx0_setipl(handler[irqno].level);
 
                /* clear pending bit */
-               icreg(INTCTL_SRCPND) = 1 << irqno;
+               icreg(INTCTL_SRCPND) = PENDING_CLEAR_MASK & (1 << irqno);
 #ifdef notyet
                /* Enable interrupt */
 #endif
@@ -120,14 +129,24 @@
                s3c2xx0_do_pending();
 }
 
+static const u_char s3c2800_ist[] = {
+       EXTINTR_LOW,            /* NONE */
+       EXTINTR_FALLING,        /* PULSE */
+       EXTINTR_FALLING,        /* EDGE */
+       EXTINTR_LOW,            /* LEVEL */
+       EXTINTR_HIGH,
+       EXTINTR_RISING,
+       EXTINTR_BOTH,
+};
 
 void *
-s3c2800_intr_establish(int irqno, int level,
+s3c2800_intr_establish(int irqno, int level, int type,
     int (* func) (void *), void *cookie)
 {
        int save;
 
-       if (irqno < 0 || irqno >= ICU_LEN)
+       if (irqno < 0 || irqno >= ICU_LEN ||
+           type < IST_NONE || IST_EDGE_BOTH < type)
                panic("intr_establish: bogus irq or type");
 
        save = disable_interrupts(I32_bit);
@@ -138,6 +157,26 @@
 
        s3c2xx0_update_intr_masks(irqno, level);
 
+       if (irqno <= S3C2800_INT_EXT(7)) {
+               /*
+                * Update external interrupt control
+                */
+               uint32_t reg;
+               u_int   trig;
+
+               trig = s3c2800_ist[type];
+
+               reg = bus_space_read_4(s3c2xx0_softc->sc_iot,
+                                      s3c2xx0_softc->sc_gpio_ioh,
+                                      GPIO_EXTINTR);
+
+               reg = reg & ~(0x0f << (4*irqno));
+               reg |= trig << (4*irqno);
+
+               bus_space_write_4(s3c2xx0_softc->sc_iot, s3c2xx0_softc->sc_gpio_ioh,
+                                 GPIO_EXTINTR, reg);
+       }
+
        intr_mask = s3c2xx0_imask[current_spl_level];
        *s3c2xx0_intr_mask_reg = intr_mask;
 
@@ -159,4 +198,5 @@
        icreg(INTCTL_SRCPND) = 0xffffffff;
 
        s3c2xx0_intr_init(handler, ICU_LEN);
+
 }



Home | Main Index | Thread Index | Old Index