Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: sunxi_intc.c
- ===================================================================
- RCS file: /cvsroot/src/sys/arch/arm/sunxi/sunxi_intc.c,v
- retrieving revision 1.3
- diff -u -p -r1.3 sunxi_intc.c
- --- sunxi_intc.c 24 Oct 2017 15:07:09 -0000 1.3
- +++ sunxi_intc.c 31 Dec 2019 21:12:34 -0000
- @@ -44,26 +44,53 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_intc.c
- #include <arm/pic/picvar.h>
- #include <arm/fdt/arm_fdtvar.h>
- -#define INTC_MAX_SOURCES 96
- -#define INTC_MAX_GROUPS 3
- +#define SUNXI_INTC_MAX_SOURCES 96
- +#define SUNXI_INTC_MAX_GROUPS 3
- -#define INTC_VECTOR_REG 0x00
- -#define INTC_BASE_ADDR_REG 0x04
- -#define INTC_PROTECT_REG 0x08
- -#define INTC_PROTECT_EN __BIT(0)
- -#define INTC_NMII_CTRL_REG 0x0c
- -#define INTC_IRQ_PEND_REG(n) (0x10 + ((n) * 4))
- -#define INTC_FIQ_PEND_REG(n) (0x20 + ((n) * 4))
- -#define INTC_SEL_REG(n) (0x30 + ((n) * 4))
- -#define INTC_EN_REG(n) (0x40 + ((n) * 4))
- -#define INTC_MASK_REG(n) (0x50 + ((n) * 4))
- -#define INTC_RESP_REG(n) (0x60 + ((n) * 4))
- -#define INTC_FORCE_REG(n) (0x70 + ((n) * 4))
- -#define INTC_SRC_PRIO_REG(n) (0x80 + ((n) * 4))
- -
- -static const char * const compatible[] = {
- - "allwinner,sun4i-a10-ic",
- - NULL
- +#define SUNIV_INTC_MAX_SOURCES 64
- +#define SUNIV_INTC_MAX_GROUPS 2
- +
- +#define INTC_MAX_SOURCES(sc) ((sc)->sc_conf->max_sources)
- +#define INTC_MAX_GROUPS(sc) ((sc)->sc_conf->max_groups)
- +
- +#define INTC_VECTOR_REG 0x00
- +#define INTC_BASE_ADDR_REG 0x04
- +#define INTC_PROTECT_REG(sc) ((sc)->sc_conf->protect_reg_offset)
- +#define INTC_PROTECT_EN __BIT(0)
- +#define INTC_IRQ_PEND_REG(n) (0x10 + ((n) * 4))
- +#define INTC_EN_REG(sc, n) \
- + ((sc)->sc_conf->en_reg_offset + ((n) * 4))
- +#define INTC_MASK_REG(sc, n) \
- + ((sc)->sc_conf->mask_reg_offset + ((n) * 4))
- +
- +struct sunxi_intc_config {
- + int max_sources;
- + int max_groups;
- + int protect_reg_offset;
- + int en_reg_offset;
- + int mask_reg_offset;
- +};
- +
- +static const struct sunxi_intc_config sun4i_a10_ic_config = {
- + .max_sources = SUNXI_INTC_MAX_SOURCES,
- + .max_groups = SUNXI_INTC_MAX_GROUPS,
- + .protect_reg_offset = 0x08,
- + .en_reg_offset = 0x40,
- + .mask_reg_offset = 0x50,
- +};
- +
- +static const struct sunxi_intc_config suniv_ic_config = {
- + .max_sources = SUNIV_INTC_MAX_SOURCES,
- + .max_groups = SUNIV_INTC_MAX_GROUPS,
- + .protect_reg_offset = 0, /* no PROTECT_REG */
- + .en_reg_offset = 0x20,
- + .mask_reg_offset = 0x30,
- +};
- +
- +static const struct of_compat_data compat_data[] = {
- + { "allwinner,sun4i-a10-ic", (uintptr_t)&sun4i_a10_ic_config },
- + { "allwinner,suniv-ic", (uintptr_t)&suniv_ic_config },
- + { NULL }
- };
- struct sunxi_intc_softc {
- @@ -72,7 +99,9 @@ struct sunxi_intc_softc {
- bus_space_handle_t sc_bsh;
- int sc_phandle;
- - uint32_t sc_enabled_irqs[INTC_MAX_GROUPS];
- + const struct sunxi_intc_config *sc_conf;
- +
- + uint32_t sc_enabled_irqs[SUNXI_INTC_MAX_GROUPS];
- struct pic_softc sc_pic;
- };
- @@ -95,8 +124,8 @@ sunxi_intc_unblock_irqs(struct pic_softc
- KASSERT((mask & sc->sc_enabled_irqs[group]) == 0);
- sc->sc_enabled_irqs[group] |= mask;
- - INTC_WRITE(sc, INTC_EN_REG(group), sc->sc_enabled_irqs[group]);
- - INTC_WRITE(sc, INTC_MASK_REG(group), ~sc->sc_enabled_irqs[group]);
- + INTC_WRITE(sc, INTC_EN_REG(sc, group), sc->sc_enabled_irqs[group]);
- + INTC_WRITE(sc, INTC_MASK_REG(sc, group), ~sc->sc_enabled_irqs[group]);
- }
- static void
- @@ -106,14 +135,16 @@ sunxi_intc_block_irqs(struct pic_softc *
- const u_int group = irqbase / 32;
- sc->sc_enabled_irqs[group] &= ~mask;
- - INTC_WRITE(sc, INTC_EN_REG(group), sc->sc_enabled_irqs[group]);
- - INTC_WRITE(sc, INTC_MASK_REG(group), ~sc->sc_enabled_irqs[group]);
- + INTC_WRITE(sc, INTC_EN_REG(sc, group), sc->sc_enabled_irqs[group]);
- + INTC_WRITE(sc, INTC_MASK_REG(sc, group), ~sc->sc_enabled_irqs[group]);
- }
- static void
- sunxi_intc_establish_irq(struct pic_softc *pic, struct intrsource *is)
- {
- - KASSERT(is->is_irq < INTC_MAX_SOURCES);
- + struct sunxi_intc_softc * const sc = PICTOSOFTC(pic);
- +
- + KASSERT(is->is_irq < INTC_MAX_SOURCES(sc));
- KASSERT(is->is_type == IST_LEVEL);
- }
- @@ -133,10 +164,12 @@ static void *
- sunxi_intc_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags,
- int (*func)(void *), void *arg)
- {
- + struct sunxi_intc_softc * const sc = device_private(dev);
- +
- /* 1st cell is the interrupt number */
- const u_int irq = be32toh(specifier[0]);
- - if (irq >= INTC_MAX_SOURCES) {
- + if (irq >= INTC_MAX_SOURCES(sc)) {
- #ifdef DIAGNOSTIC
- device_printf(dev, "IRQ %u is invalid\n", irq);
- #endif
- @@ -196,16 +229,14 @@ sunxi_intc_irq_handler(void *frame)
- struct sunxi_intc_softc * const sc = intc_softc;
- const int oldipl = ci->ci_cpl;
- const uint32_t oldipl_mask = __BIT(oldipl);
- - int ipl_mask = 0;
- + int i, ipl_mask = 0;
- ci->ci_data.cpu_nintr++;
- - if (sc->sc_enabled_irqs[0])
- - ipl_mask |= sunxi_intc_find_pending_irqs(sc, 0);
- - if (sc->sc_enabled_irqs[1])
- - ipl_mask |= sunxi_intc_find_pending_irqs(sc, 1);
- - if (sc->sc_enabled_irqs[2])
- - ipl_mask |= sunxi_intc_find_pending_irqs(sc, 2);
- + for (i = 0; i < INTC_MAX_GROUPS(sc); i++) {
- + if (sc->sc_enabled_irqs[i])
- + ipl_mask |= sunxi_intc_find_pending_irqs(sc, i);
- + }
- if ((ipl_mask & ~oldipl_mask) > oldipl_mask)
- pic_do_pending_ints(I32_bit, oldipl, frame);
- @@ -216,7 +247,7 @@ sunxi_intc_match(device_t parent, cfdata
- {
- struct fdt_attach_args * const faa = aux;
- - return of_match_compatible(faa->faa_phandle, compatible);
- + return of_match_compat_data(faa->faa_phandle, compat_data);
- }
- static void
- @@ -241,22 +272,24 @@ sunxi_intc_attach(device_t parent, devic
- aprint_error(": couldn't map registers\n");
- return;
- }
- + sc->sc_conf = (void *)of_search_compatible(phandle, compat_data)->data;
- aprint_naive("\n");
- aprint_normal(": Interrupt Controller\n");
- /* Disable IRQs */
- - for (i = 0; i < INTC_MAX_GROUPS; i++) {
- - INTC_WRITE(sc, INTC_EN_REG(i), 0);
- - INTC_WRITE(sc, INTC_MASK_REG(i), ~0U);
- + for (i = 0; i < INTC_MAX_GROUPS(sc); i++) {
- + INTC_WRITE(sc, INTC_EN_REG(sc, i), 0);
- + INTC_WRITE(sc, INTC_MASK_REG(sc, i), ~0U);
- INTC_WRITE(sc, INTC_IRQ_PEND_REG(i),
- INTC_READ(sc, INTC_IRQ_PEND_REG(i)));
- }
- /* Disable user mode access to intc registers */
- - INTC_WRITE(sc, INTC_PROTECT_REG, INTC_PROTECT_EN);
- + if (INTC_PROTECT_REG(sc))
- + INTC_WRITE(sc, INTC_PROTECT_REG(sc), INTC_PROTECT_EN);
- sc->sc_pic.pic_ops = &sunxi_intc_picops;
- - sc->sc_pic.pic_maxsources = INTC_MAX_SOURCES;
- + sc->sc_pic.pic_maxsources = INTC_MAX_SOURCES(sc);
- snprintf(sc->sc_pic.pic_name, sizeof(sc->sc_pic.pic_name), "intc");
- pic_add(&sc->sc_pic, 0);
Add Comment
Please, Sign In to add comment