Start to remove the old pre-INTRNG code from the arm platforms. These have
all moved to use INTRNG. Reviewed by: manu, mmel Sponsored by: ABT Systems Ltd Differential Revision: https://reviews.freebsd.org/D8469
This commit is contained in:
parent
31500ce90d
commit
feabce61dc
@ -43,9 +43,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/rman.h>
|
#include <sys/rman.h>
|
||||||
#include <sys/smp.h>
|
#include <sys/smp.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#ifdef INTRNG
|
|
||||||
#include <sys/sched.h>
|
#include <sys/sched.h>
|
||||||
#endif
|
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
#include <machine/intr.h>
|
#include <machine/intr.h>
|
||||||
|
|
||||||
@ -54,9 +52,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/ofw/ofw_bus.h>
|
#include <dev/ofw/ofw_bus.h>
|
||||||
#include <dev/ofw/ofw_bus_subr.h>
|
#include <dev/ofw/ofw_bus_subr.h>
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
#include "pic_if.h"
|
#include "pic_if.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interrupt controller registers
|
* Interrupt controller registers
|
||||||
@ -97,12 +93,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define SW_INT_ENABLE_REG(_b) (0x40 + ((_b) * 4))
|
#define SW_INT_ENABLE_REG(_b) (0x40 + ((_b) * 4))
|
||||||
#define SW_INT_MASK_REG(_b) (0x50 + ((_b) * 4))
|
#define SW_INT_MASK_REG(_b) (0x50 + ((_b) * 4))
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
struct a10_intr_irqsrc {
|
struct a10_intr_irqsrc {
|
||||||
struct intr_irqsrc isrc;
|
struct intr_irqsrc isrc;
|
||||||
u_int irq;
|
u_int irq;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
struct a10_aintc_softc {
|
struct a10_aintc_softc {
|
||||||
device_t sc_dev;
|
device_t sc_dev;
|
||||||
@ -110,9 +104,7 @@ struct a10_aintc_softc {
|
|||||||
bus_space_tag_t aintc_bst;
|
bus_space_tag_t aintc_bst;
|
||||||
bus_space_handle_t aintc_bsh;
|
bus_space_handle_t aintc_bsh;
|
||||||
struct mtx mtx;
|
struct mtx mtx;
|
||||||
#ifdef INTRNG
|
|
||||||
struct a10_intr_irqsrc isrcs[A10_INTR_MAX_NIRQS];
|
struct a10_intr_irqsrc isrcs[A10_INTR_MAX_NIRQS];
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define aintc_read_4(sc, reg) \
|
#define aintc_read_4(sc, reg) \
|
||||||
@ -189,31 +181,6 @@ a10_pending_irq(struct a10_aintc_softc *sc)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
|
|
||||||
static struct a10_aintc_softc *a10_aintc_sc = NULL;
|
|
||||||
|
|
||||||
int
|
|
||||||
arm_get_next_irq(int last_irq)
|
|
||||||
{
|
|
||||||
return (a10_pending_irq(a10_aintc_sc));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
arm_mask_irq(uintptr_t irq)
|
|
||||||
{
|
|
||||||
a10_intr_mask(a10_aintc_sc, irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
arm_unmask_irq(uintptr_t irq)
|
|
||||||
{
|
|
||||||
a10_intr_unmask(a10_aintc_sc, irq);
|
|
||||||
a10_intr_eoi(a10_aintc_sc, irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* INTRNG */
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
a10_intr(void *arg)
|
a10_intr(void *arg)
|
||||||
{
|
{
|
||||||
@ -340,8 +307,6 @@ a10_intr_post_filter(device_t dev, struct intr_irqsrc *isrc)
|
|||||||
a10_intr_eoi(sc, irq);
|
a10_intr_eoi(sc, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* INTRNG */
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
a10_aintc_probe(device_t dev)
|
a10_aintc_probe(device_t dev)
|
||||||
{
|
{
|
||||||
@ -363,13 +328,6 @@ a10_aintc_attach(device_t dev)
|
|||||||
int i;
|
int i;
|
||||||
sc->sc_dev = dev;
|
sc->sc_dev = dev;
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
if (a10_aintc_sc)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
a10_aintc_sc = sc;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sc->aintc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
sc->aintc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||||
&rid, RF_ACTIVE);
|
&rid, RF_ACTIVE);
|
||||||
if (!sc->aintc_res) {
|
if (!sc->aintc_res) {
|
||||||
@ -393,12 +351,10 @@ a10_aintc_attach(device_t dev)
|
|||||||
/* config the external interrupt source type*/
|
/* config the external interrupt source type*/
|
||||||
aintc_write_4(sc, SW_INT_NMI_CTRL_REG, 0x00);
|
aintc_write_4(sc, SW_INT_NMI_CTRL_REG, 0x00);
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
if (a10_intr_pic_attach(sc) != 0) {
|
if (a10_intr_pic_attach(sc) != 0) {
|
||||||
device_printf(dev, "could not attach PIC\n");
|
device_printf(dev, "could not attach PIC\n");
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
@ -411,7 +367,7 @@ error:
|
|||||||
static device_method_t a10_aintc_methods[] = {
|
static device_method_t a10_aintc_methods[] = {
|
||||||
DEVMETHOD(device_probe, a10_aintc_probe),
|
DEVMETHOD(device_probe, a10_aintc_probe),
|
||||||
DEVMETHOD(device_attach, a10_aintc_attach),
|
DEVMETHOD(device_attach, a10_aintc_attach),
|
||||||
#ifdef INTRNG
|
|
||||||
/* Interrupt controller interface */
|
/* Interrupt controller interface */
|
||||||
DEVMETHOD(pic_disable_intr, a10_intr_disable_intr),
|
DEVMETHOD(pic_disable_intr, a10_intr_disable_intr),
|
||||||
DEVMETHOD(pic_enable_intr, a10_intr_enable_intr),
|
DEVMETHOD(pic_enable_intr, a10_intr_enable_intr),
|
||||||
@ -419,7 +375,7 @@ static device_method_t a10_aintc_methods[] = {
|
|||||||
DEVMETHOD(pic_post_filter, a10_intr_post_filter),
|
DEVMETHOD(pic_post_filter, a10_intr_post_filter),
|
||||||
DEVMETHOD(pic_post_ithread, a10_intr_post_ithread),
|
DEVMETHOD(pic_post_ithread, a10_intr_post_ithread),
|
||||||
DEVMETHOD(pic_pre_ithread, a10_intr_pre_ithread),
|
DEVMETHOD(pic_pre_ithread, a10_intr_pre_ithread),
|
||||||
#endif
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold@freebsd.org>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
__FBSDID("$FreeBSD$");
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
#include <sys/bus.h>
|
|
||||||
#include <sys/kernel.h>
|
|
||||||
|
|
||||||
#include <dev/fdt/fdt_common.h>
|
|
||||||
#include <dev/ofw/openfirm.h>
|
|
||||||
|
|
||||||
#include <machine/bus.h>
|
|
||||||
#include <machine/vmparam.h>
|
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
|
|
||||||
static int
|
|
||||||
fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
|
|
||||||
int *pol)
|
|
||||||
{
|
|
||||||
int offset;
|
|
||||||
|
|
||||||
if (fdt_is_compatible(node, "allwinner,sun4i-a10-ic"))
|
|
||||||
offset = 0;
|
|
||||||
else if (fdt_is_compatible(node, "arm,gic"))
|
|
||||||
offset = 32;
|
|
||||||
else
|
|
||||||
return (ENXIO);
|
|
||||||
|
|
||||||
*interrupt = fdt32_to_cpu(intr[0]) + offset;
|
|
||||||
*trig = INTR_TRIGGER_CONFORM;
|
|
||||||
*pol = INTR_POLARITY_CONFORM;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
fdt_pic_decode_t fdt_pic_table[] = {
|
|
||||||
&fdt_aintc_decode_ic,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* INTRNG */
|
|
@ -3,7 +3,6 @@ kern/kern_clocksource.c standard
|
|||||||
|
|
||||||
arm/allwinner/a10_ahci.c optional ahci
|
arm/allwinner/a10_ahci.c optional ahci
|
||||||
arm/allwinner/a10_codec.c optional sound
|
arm/allwinner/a10_codec.c optional sound
|
||||||
arm/allwinner/a10_common.c standard
|
|
||||||
arm/allwinner/a10_dmac.c standard
|
arm/allwinner/a10_dmac.c standard
|
||||||
arm/allwinner/a31_dmac.c standard
|
arm/allwinner/a31_dmac.c standard
|
||||||
arm/allwinner/a10_ehci.c optional ehci
|
arm/allwinner/a10_ehci.c optional ehci
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Developed by Semihalf.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of MARVELL nor the names of contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
__FBSDID("$FreeBSD$");
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
#include <sys/bus.h>
|
|
||||||
#include <sys/kernel.h>
|
|
||||||
#include <sys/malloc.h>
|
|
||||||
#include <sys/kdb.h>
|
|
||||||
#include <sys/reboot.h>
|
|
||||||
|
|
||||||
#include <dev/fdt/fdt_common.h>
|
|
||||||
#include <dev/ofw/openfirm.h>
|
|
||||||
|
|
||||||
#include <machine/bus.h>
|
|
||||||
#include <machine/vmparam.h>
|
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
static int
|
|
||||||
fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
|
|
||||||
int *pol)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (fdt_is_compatible(node, "broadcom,bcm2835-armctrl-ic") ||
|
|
||||||
fdt_is_compatible(node, "brcm,bcm2836-armctrl-ic")) {
|
|
||||||
*interrupt = fdt32_to_cpu(intr[0]);
|
|
||||||
*trig = INTR_TRIGGER_CONFORM;
|
|
||||||
*pol = INTR_POLARITY_CONFORM;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#ifdef SOC_BCM2836
|
|
||||||
if (fdt_is_compatible(node, "brcm,bcm2836-l1-intc")) {
|
|
||||||
*interrupt = fdt32_to_cpu(intr[0]) + 72;
|
|
||||||
*trig = INTR_TRIGGER_CONFORM;
|
|
||||||
*pol = INTR_POLARITY_CONFORM;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return (ENXIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fdt_pic_decode_t fdt_pic_table[] = {
|
|
||||||
&fdt_intc_decode_ic,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
#endif /* INTRNG */
|
|
@ -53,9 +53,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include "gpio_if.h"
|
#include "gpio_if.h"
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
#include "pic_if.h"
|
#include "pic_if.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define dprintf(fmt, args...) do { printf("%s(): ", __func__); \
|
#define dprintf(fmt, args...) do { printf("%s(): ", __func__); \
|
||||||
@ -68,15 +66,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define BCM_GPIO_PINS 54
|
#define BCM_GPIO_PINS 54
|
||||||
#define BCM_GPIO_PINS_PER_BANK 32
|
#define BCM_GPIO_PINS_PER_BANK 32
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
|
#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
|
||||||
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | \
|
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | \
|
||||||
GPIO_INTR_LEVEL_HIGH | GPIO_INTR_EDGE_RISING | \
|
GPIO_INTR_LEVEL_HIGH | GPIO_INTR_EDGE_RISING | \
|
||||||
GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
|
GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
|
||||||
#else
|
|
||||||
#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
|
|
||||||
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct resource_spec bcm_gpio_res_spec[] = {
|
static struct resource_spec bcm_gpio_res_spec[] = {
|
||||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||||
@ -90,14 +83,12 @@ struct bcm_gpio_sysctl {
|
|||||||
uint32_t pin;
|
uint32_t pin;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
struct bcm_gpio_irqsrc {
|
struct bcm_gpio_irqsrc {
|
||||||
struct intr_irqsrc bgi_isrc;
|
struct intr_irqsrc bgi_isrc;
|
||||||
uint32_t bgi_irq;
|
uint32_t bgi_irq;
|
||||||
uint32_t bgi_mode;
|
uint32_t bgi_mode;
|
||||||
uint32_t bgi_mask;
|
uint32_t bgi_mask;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
struct bcm_gpio_softc {
|
struct bcm_gpio_softc {
|
||||||
device_t sc_dev;
|
device_t sc_dev;
|
||||||
@ -111,16 +102,8 @@ struct bcm_gpio_softc {
|
|||||||
int sc_ro_npins;
|
int sc_ro_npins;
|
||||||
int sc_ro_pins[BCM_GPIO_PINS];
|
int sc_ro_pins[BCM_GPIO_PINS];
|
||||||
struct gpio_pin sc_gpio_pins[BCM_GPIO_PINS];
|
struct gpio_pin sc_gpio_pins[BCM_GPIO_PINS];
|
||||||
#ifndef INTRNG
|
|
||||||
struct intr_event * sc_events[BCM_GPIO_PINS];
|
|
||||||
#endif
|
|
||||||
struct bcm_gpio_sysctl sc_sysctl[BCM_GPIO_PINS];
|
struct bcm_gpio_sysctl sc_sysctl[BCM_GPIO_PINS];
|
||||||
#ifdef INTRNG
|
|
||||||
struct bcm_gpio_irqsrc sc_isrcs[BCM_GPIO_PINS];
|
struct bcm_gpio_irqsrc sc_isrcs[BCM_GPIO_PINS];
|
||||||
#else
|
|
||||||
enum intr_trigger sc_irq_trigger[BCM_GPIO_PINS];
|
|
||||||
enum intr_polarity sc_irq_polarity[BCM_GPIO_PINS];
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum bcm_gpio_pud {
|
enum bcm_gpio_pud {
|
||||||
@ -165,12 +148,10 @@ static struct ofw_compat_data compat_data[] = {
|
|||||||
|
|
||||||
static struct bcm_gpio_softc *bcm_gpio_sc = NULL;
|
static struct bcm_gpio_softc *bcm_gpio_sc = NULL;
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
static int bcm_gpio_intr_bank0(void *arg);
|
static int bcm_gpio_intr_bank0(void *arg);
|
||||||
static int bcm_gpio_intr_bank1(void *arg);
|
static int bcm_gpio_intr_bank1(void *arg);
|
||||||
static int bcm_gpio_pic_attach(struct bcm_gpio_softc *sc);
|
static int bcm_gpio_pic_attach(struct bcm_gpio_softc *sc);
|
||||||
static int bcm_gpio_pic_detach(struct bcm_gpio_softc *sc);
|
static int bcm_gpio_pic_detach(struct bcm_gpio_softc *sc);
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bcm_gpio_pin_is_ro(struct bcm_gpio_softc *sc, int pin)
|
bcm_gpio_pin_is_ro(struct bcm_gpio_softc *sc, int pin)
|
||||||
@ -703,42 +684,6 @@ bcm_gpio_get_reserved_pins(struct bcm_gpio_softc *sc)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
static int
|
|
||||||
bcm_gpio_intr(void *arg)
|
|
||||||
{
|
|
||||||
int bank_last, irq;
|
|
||||||
struct bcm_gpio_softc *sc;
|
|
||||||
struct intr_event *event;
|
|
||||||
uint32_t bank, mask, reg;
|
|
||||||
|
|
||||||
sc = (struct bcm_gpio_softc *)arg;
|
|
||||||
reg = 0;
|
|
||||||
bank_last = -1;
|
|
||||||
for (irq = 0; irq < BCM_GPIO_PINS; irq++) {
|
|
||||||
bank = BCM_GPIO_BANK(irq);
|
|
||||||
mask = BCM_GPIO_MASK(irq);
|
|
||||||
if (bank != bank_last) {
|
|
||||||
reg = BCM_GPIO_READ(sc, BCM_GPIO_GPEDS(bank));
|
|
||||||
bank_last = bank;
|
|
||||||
}
|
|
||||||
if (reg & mask) {
|
|
||||||
event = sc->sc_events[irq];
|
|
||||||
if (event != NULL && !TAILQ_EMPTY(&event->ie_handlers))
|
|
||||||
intr_event_handle(event, NULL);
|
|
||||||
else {
|
|
||||||
device_printf(sc->sc_dev, "Stray IRQ %d\n",
|
|
||||||
irq);
|
|
||||||
}
|
|
||||||
/* Clear the Status bit by writing '1' to it. */
|
|
||||||
BCM_GPIO_WRITE(sc, BCM_GPIO_GPEDS(bank), mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (FILTER_HANDLED);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bcm_gpio_probe(device_t dev)
|
bcm_gpio_probe(device_t dev)
|
||||||
{
|
{
|
||||||
@ -753,7 +698,6 @@ bcm_gpio_probe(device_t dev)
|
|||||||
return (BUS_PROBE_DEFAULT);
|
return (BUS_PROBE_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
static int
|
static int
|
||||||
bcm_gpio_intr_attach(device_t dev)
|
bcm_gpio_intr_attach(device_t dev)
|
||||||
{
|
{
|
||||||
@ -795,41 +739,6 @@ bcm_gpio_intr_detach(device_t dev)
|
|||||||
bcm_gpio_pic_detach(sc);
|
bcm_gpio_pic_detach(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
static int
|
|
||||||
bcm_gpio_intr_attach(device_t dev)
|
|
||||||
{
|
|
||||||
struct bcm_gpio_softc *sc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
|
||||||
for (i = 0; i < BCM_GPIO_IRQS; i++) {
|
|
||||||
if (bus_setup_intr(dev, sc->sc_res[i + 1],
|
|
||||||
INTR_TYPE_MISC | INTR_MPSAFE, bcm_gpio_intr,
|
|
||||||
NULL, sc, &sc->sc_intrhand[i]) != 0) {
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bcm_gpio_intr_detach(device_t dev)
|
|
||||||
{
|
|
||||||
struct bcm_gpio_softc *sc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
|
||||||
for (i = 0; i < BCM_GPIO_IRQS; i++) {
|
|
||||||
if (sc->sc_intrhand[i]) {
|
|
||||||
bus_teardown_intr(dev, sc->sc_res[i + 1],
|
|
||||||
sc->sc_intrhand[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bcm_gpio_attach(device_t dev)
|
bcm_gpio_attach(device_t dev)
|
||||||
{
|
{
|
||||||
@ -874,11 +783,6 @@ bcm_gpio_attach(device_t dev)
|
|||||||
sc->sc_gpio_pins[i].gp_pin = j;
|
sc->sc_gpio_pins[i].gp_pin = j;
|
||||||
sc->sc_gpio_pins[i].gp_caps = BCM_GPIO_DEFAULT_CAPS;
|
sc->sc_gpio_pins[i].gp_caps = BCM_GPIO_DEFAULT_CAPS;
|
||||||
sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(func);
|
sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(func);
|
||||||
#ifndef INTRNG
|
|
||||||
/* The default is active-low interrupts. */
|
|
||||||
sc->sc_irq_trigger[i] = INTR_TRIGGER_LEVEL;
|
|
||||||
sc->sc_irq_polarity[i] = INTR_POLARITY_LOW;
|
|
||||||
#endif
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
sc->sc_gpio_npins = i;
|
sc->sc_gpio_npins = i;
|
||||||
@ -904,7 +808,6 @@ bcm_gpio_detach(device_t dev)
|
|||||||
return (EBUSY);
|
return (EBUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
static inline void
|
static inline void
|
||||||
bcm_gpio_modify(struct bcm_gpio_softc *sc, uint32_t reg, uint32_t mask,
|
bcm_gpio_modify(struct bcm_gpio_softc *sc, uint32_t reg, uint32_t mask,
|
||||||
bool set_bits)
|
bool set_bits)
|
||||||
@ -1275,179 +1178,6 @@ bcm_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
static uint32_t
|
|
||||||
bcm_gpio_intr_reg(struct bcm_gpio_softc *sc, unsigned int irq, uint32_t bank)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (irq > BCM_GPIO_PINS)
|
|
||||||
return (0);
|
|
||||||
if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_LEVEL) {
|
|
||||||
if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW)
|
|
||||||
return (BCM_GPIO_GPLEN(bank));
|
|
||||||
else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH)
|
|
||||||
return (BCM_GPIO_GPHEN(bank));
|
|
||||||
} else if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_EDGE) {
|
|
||||||
if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW)
|
|
||||||
return (BCM_GPIO_GPFEN(bank));
|
|
||||||
else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH)
|
|
||||||
return (BCM_GPIO_GPREN(bank));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bcm_gpio_mask_irq(void *source)
|
|
||||||
{
|
|
||||||
uint32_t bank, mask, reg;
|
|
||||||
unsigned int irq;
|
|
||||||
|
|
||||||
irq = (unsigned int)source;
|
|
||||||
if (irq > BCM_GPIO_PINS)
|
|
||||||
return;
|
|
||||||
if (bcm_gpio_pin_is_ro(bcm_gpio_sc, irq))
|
|
||||||
return;
|
|
||||||
bank = BCM_GPIO_BANK(irq);
|
|
||||||
mask = BCM_GPIO_MASK(irq);
|
|
||||||
BCM_GPIO_LOCK(bcm_gpio_sc);
|
|
||||||
reg = bcm_gpio_intr_reg(bcm_gpio_sc, irq, bank);
|
|
||||||
if (reg != 0)
|
|
||||||
BCM_GPIO_CLEAR_BITS(bcm_gpio_sc, reg, mask);
|
|
||||||
BCM_GPIO_UNLOCK(bcm_gpio_sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bcm_gpio_unmask_irq(void *source)
|
|
||||||
{
|
|
||||||
uint32_t bank, mask, reg;
|
|
||||||
unsigned int irq;
|
|
||||||
|
|
||||||
irq = (unsigned int)source;
|
|
||||||
if (irq > BCM_GPIO_PINS)
|
|
||||||
return;
|
|
||||||
if (bcm_gpio_pin_is_ro(bcm_gpio_sc, irq))
|
|
||||||
return;
|
|
||||||
bank = BCM_GPIO_BANK(irq);
|
|
||||||
mask = BCM_GPIO_MASK(irq);
|
|
||||||
BCM_GPIO_LOCK(bcm_gpio_sc);
|
|
||||||
reg = bcm_gpio_intr_reg(bcm_gpio_sc, irq, bank);
|
|
||||||
if (reg != 0)
|
|
||||||
BCM_GPIO_SET_BITS(bcm_gpio_sc, reg, mask);
|
|
||||||
BCM_GPIO_UNLOCK(bcm_gpio_sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
bcm_gpio_activate_resource(device_t bus, device_t child, int type, int rid,
|
|
||||||
struct resource *res)
|
|
||||||
{
|
|
||||||
int pin;
|
|
||||||
|
|
||||||
if (type != SYS_RES_IRQ)
|
|
||||||
return (ENXIO);
|
|
||||||
/* Unmask the interrupt. */
|
|
||||||
pin = rman_get_start(res);
|
|
||||||
bcm_gpio_unmask_irq((void *)pin);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
bcm_gpio_deactivate_resource(device_t bus, device_t child, int type, int rid,
|
|
||||||
struct resource *res)
|
|
||||||
{
|
|
||||||
int pin;
|
|
||||||
|
|
||||||
if (type != SYS_RES_IRQ)
|
|
||||||
return (ENXIO);
|
|
||||||
/* Mask the interrupt. */
|
|
||||||
pin = rman_get_start(res);
|
|
||||||
bcm_gpio_mask_irq((void *)pin);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
bcm_gpio_config_intr(device_t dev, int irq, enum intr_trigger trig,
|
|
||||||
enum intr_polarity pol)
|
|
||||||
{
|
|
||||||
int bank;
|
|
||||||
struct bcm_gpio_softc *sc;
|
|
||||||
uint32_t mask, oldreg, reg;
|
|
||||||
|
|
||||||
if (irq > BCM_GPIO_PINS)
|
|
||||||
return (EINVAL);
|
|
||||||
/* There is no standard trigger or polarity. */
|
|
||||||
if (trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM)
|
|
||||||
return (EINVAL);
|
|
||||||
sc = device_get_softc(dev);
|
|
||||||
if (bcm_gpio_pin_is_ro(sc, irq))
|
|
||||||
return (EINVAL);
|
|
||||||
bank = BCM_GPIO_BANK(irq);
|
|
||||||
mask = BCM_GPIO_MASK(irq);
|
|
||||||
BCM_GPIO_LOCK(sc);
|
|
||||||
oldreg = bcm_gpio_intr_reg(sc, irq, bank);
|
|
||||||
sc->sc_irq_trigger[irq] = trig;
|
|
||||||
sc->sc_irq_polarity[irq] = pol;
|
|
||||||
reg = bcm_gpio_intr_reg(sc, irq, bank);
|
|
||||||
if (reg != 0)
|
|
||||||
BCM_GPIO_SET_BITS(sc, reg, mask);
|
|
||||||
if (reg != oldreg && oldreg != 0)
|
|
||||||
BCM_GPIO_CLEAR_BITS(sc, oldreg, mask);
|
|
||||||
BCM_GPIO_UNLOCK(sc);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
bcm_gpio_setup_intr(device_t bus, device_t child, struct resource *ires,
|
|
||||||
int flags, driver_filter_t *filt, driver_intr_t *handler,
|
|
||||||
void *arg, void **cookiep)
|
|
||||||
{
|
|
||||||
struct bcm_gpio_softc *sc;
|
|
||||||
struct intr_event *event;
|
|
||||||
int pin, error;
|
|
||||||
|
|
||||||
sc = device_get_softc(bus);
|
|
||||||
pin = rman_get_start(ires);
|
|
||||||
if (pin > BCM_GPIO_PINS)
|
|
||||||
panic("%s: bad pin %d", __func__, pin);
|
|
||||||
event = sc->sc_events[pin];
|
|
||||||
if (event == NULL) {
|
|
||||||
error = intr_event_create(&event, (void *)pin, 0, pin,
|
|
||||||
bcm_gpio_mask_irq, bcm_gpio_unmask_irq, NULL, NULL,
|
|
||||||
"gpio%d pin%d:", device_get_unit(bus), pin);
|
|
||||||
if (error != 0)
|
|
||||||
return (error);
|
|
||||||
sc->sc_events[pin] = event;
|
|
||||||
}
|
|
||||||
intr_event_add_handler(event, device_get_nameunit(child), filt,
|
|
||||||
handler, arg, intr_priority(flags), flags, cookiep);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
bcm_gpio_teardown_intr(device_t dev, device_t child, struct resource *ires,
|
|
||||||
void *cookie)
|
|
||||||
{
|
|
||||||
struct bcm_gpio_softc *sc;
|
|
||||||
int pin, err;
|
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
|
||||||
pin = rman_get_start(ires);
|
|
||||||
if (pin > BCM_GPIO_PINS)
|
|
||||||
panic("%s: bad pin %d", __func__, pin);
|
|
||||||
if (sc->sc_events[pin] == NULL)
|
|
||||||
panic("Trying to teardown unoccupied IRQ");
|
|
||||||
err = intr_event_remove_handler(cookie);
|
|
||||||
if (!err)
|
|
||||||
sc->sc_events[pin] = NULL;
|
|
||||||
|
|
||||||
return (err);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static phandle_t
|
static phandle_t
|
||||||
bcm_gpio_get_node(device_t bus, device_t dev)
|
bcm_gpio_get_node(device_t bus, device_t dev)
|
||||||
{
|
{
|
||||||
@ -1473,7 +1203,6 @@ static device_method_t bcm_gpio_methods[] = {
|
|||||||
DEVMETHOD(gpio_pin_set, bcm_gpio_pin_set),
|
DEVMETHOD(gpio_pin_set, bcm_gpio_pin_set),
|
||||||
DEVMETHOD(gpio_pin_toggle, bcm_gpio_pin_toggle),
|
DEVMETHOD(gpio_pin_toggle, bcm_gpio_pin_toggle),
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
/* Interrupt controller interface */
|
/* Interrupt controller interface */
|
||||||
DEVMETHOD(pic_disable_intr, bcm_gpio_pic_disable_intr),
|
DEVMETHOD(pic_disable_intr, bcm_gpio_pic_disable_intr),
|
||||||
DEVMETHOD(pic_enable_intr, bcm_gpio_pic_enable_intr),
|
DEVMETHOD(pic_enable_intr, bcm_gpio_pic_enable_intr),
|
||||||
@ -1483,14 +1212,7 @@ static device_method_t bcm_gpio_methods[] = {
|
|||||||
DEVMETHOD(pic_pre_ithread, bcm_gpio_pic_pre_ithread),
|
DEVMETHOD(pic_pre_ithread, bcm_gpio_pic_pre_ithread),
|
||||||
DEVMETHOD(pic_setup_intr, bcm_gpio_pic_setup_intr),
|
DEVMETHOD(pic_setup_intr, bcm_gpio_pic_setup_intr),
|
||||||
DEVMETHOD(pic_teardown_intr, bcm_gpio_pic_teardown_intr),
|
DEVMETHOD(pic_teardown_intr, bcm_gpio_pic_teardown_intr),
|
||||||
#else
|
|
||||||
/* Bus interface */
|
|
||||||
DEVMETHOD(bus_activate_resource, bcm_gpio_activate_resource),
|
|
||||||
DEVMETHOD(bus_deactivate_resource, bcm_gpio_deactivate_resource),
|
|
||||||
DEVMETHOD(bus_config_intr, bcm_gpio_config_intr),
|
|
||||||
DEVMETHOD(bus_setup_intr, bcm_gpio_setup_intr),
|
|
||||||
DEVMETHOD(bus_teardown_intr, bcm_gpio_teardown_intr),
|
|
||||||
#endif
|
|
||||||
/* ofw_bus interface */
|
/* ofw_bus interface */
|
||||||
DEVMETHOD(ofw_bus_get_node, bcm_gpio_get_node),
|
DEVMETHOD(ofw_bus_get_node, bcm_gpio_get_node),
|
||||||
|
|
||||||
|
@ -48,13 +48,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/ofw/ofw_bus.h>
|
#include <dev/ofw/ofw_bus.h>
|
||||||
#include <dev/ofw/ofw_bus_subr.h>
|
#include <dev/ofw/ofw_bus_subr.h>
|
||||||
|
|
||||||
#ifdef SOC_BCM2836
|
|
||||||
#include <arm/broadcom/bcm2835/bcm2836.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
#include "pic_if.h"
|
#include "pic_if.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#define INTC_PENDING_BASIC 0x00
|
#define INTC_PENDING_BASIC 0x00
|
||||||
#define INTC_PENDING_BANK1 0x04
|
#define INTC_PENDING_BANK1 0x04
|
||||||
@ -105,17 +99,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define BANK1_END (BANK1_START + 32 - 1)
|
#define BANK1_END (BANK1_START + 32 - 1)
|
||||||
#define BANK2_START (BANK1_START + 32)
|
#define BANK2_START (BANK1_START + 32)
|
||||||
#define BANK2_END (BANK2_START + 32 - 1)
|
#define BANK2_END (BANK2_START + 32 - 1)
|
||||||
#ifndef INTRNG
|
|
||||||
#define BANK3_START (BANK2_START + 32)
|
|
||||||
#define BANK3_END (BANK3_START + 32 - 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IS_IRQ_BASIC(n) (((n) >= 0) && ((n) < BANK1_START))
|
#define IS_IRQ_BASIC(n) (((n) >= 0) && ((n) < BANK1_START))
|
||||||
#define IS_IRQ_BANK1(n) (((n) >= BANK1_START) && ((n) <= BANK1_END))
|
#define IS_IRQ_BANK1(n) (((n) >= BANK1_START) && ((n) <= BANK1_END))
|
||||||
#define IS_IRQ_BANK2(n) (((n) >= BANK2_START) && ((n) <= BANK2_END))
|
#define IS_IRQ_BANK2(n) (((n) >= BANK2_START) && ((n) <= BANK2_END))
|
||||||
#ifndef INTRNG
|
|
||||||
#define ID_IRQ_BCM2836(n) (((n) >= BANK3_START) && ((n) <= BANK3_END))
|
|
||||||
#endif
|
|
||||||
#define IRQ_BANK1(n) ((n) - BANK1_START)
|
#define IRQ_BANK1(n) ((n) - BANK1_START)
|
||||||
#define IRQ_BANK2(n) ((n) - BANK2_START)
|
#define IRQ_BANK2(n) ((n) - BANK2_START)
|
||||||
|
|
||||||
@ -125,7 +112,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define dprintf(fmt, args...)
|
#define dprintf(fmt, args...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
#define BCM_INTC_NIRQS 72 /* 8 + 32 + 32 */
|
#define BCM_INTC_NIRQS 72 /* 8 + 32 + 32 */
|
||||||
|
|
||||||
struct bcm_intc_irqsrc {
|
struct bcm_intc_irqsrc {
|
||||||
@ -135,18 +121,15 @@ struct bcm_intc_irqsrc {
|
|||||||
uint16_t bii_enable_reg;
|
uint16_t bii_enable_reg;
|
||||||
uint32_t bii_mask;
|
uint32_t bii_mask;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
struct bcm_intc_softc {
|
struct bcm_intc_softc {
|
||||||
device_t sc_dev;
|
device_t sc_dev;
|
||||||
struct resource * intc_res;
|
struct resource * intc_res;
|
||||||
bus_space_tag_t intc_bst;
|
bus_space_tag_t intc_bst;
|
||||||
bus_space_handle_t intc_bsh;
|
bus_space_handle_t intc_bsh;
|
||||||
#ifdef INTRNG
|
|
||||||
struct resource * intc_irq_res;
|
struct resource * intc_irq_res;
|
||||||
void * intc_irq_hdl;
|
void * intc_irq_hdl;
|
||||||
struct bcm_intc_irqsrc intc_isrcs[BCM_INTC_NIRQS];
|
struct bcm_intc_irqsrc intc_isrcs[BCM_INTC_NIRQS];
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct bcm_intc_softc *bcm_intc_sc = NULL;
|
static struct bcm_intc_softc *bcm_intc_sc = NULL;
|
||||||
@ -156,7 +139,6 @@ static struct bcm_intc_softc *bcm_intc_sc = NULL;
|
|||||||
#define intc_write_4(_sc, reg, val) \
|
#define intc_write_4(_sc, reg, val) \
|
||||||
bus_space_write_4((_sc)->intc_bst, (_sc)->intc_bsh, (reg), (val))
|
bus_space_write_4((_sc)->intc_bst, (_sc)->intc_bsh, (reg), (val))
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
static inline void
|
static inline void
|
||||||
bcm_intc_isrc_mask(struct bcm_intc_softc *sc, struct bcm_intc_irqsrc *bii)
|
bcm_intc_isrc_mask(struct bcm_intc_softc *sc, struct bcm_intc_irqsrc *bii)
|
||||||
{
|
{
|
||||||
@ -375,7 +357,6 @@ bcm_intc_pic_register(struct bcm_intc_softc *sc, intptr_t xref)
|
|||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bcm_intc_probe(device_t dev)
|
bcm_intc_probe(device_t dev)
|
||||||
@ -396,9 +377,7 @@ bcm_intc_attach(device_t dev)
|
|||||||
{
|
{
|
||||||
struct bcm_intc_softc *sc = device_get_softc(dev);
|
struct bcm_intc_softc *sc = device_get_softc(dev);
|
||||||
int rid = 0;
|
int rid = 0;
|
||||||
#ifdef INTRNG
|
|
||||||
intptr_t xref;
|
intptr_t xref;
|
||||||
#endif
|
|
||||||
sc->sc_dev = dev;
|
sc->sc_dev = dev;
|
||||||
|
|
||||||
if (bcm_intc_sc)
|
if (bcm_intc_sc)
|
||||||
@ -410,7 +389,6 @@ bcm_intc_attach(device_t dev)
|
|||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
xref = OF_xref_from_node(ofw_bus_get_node(dev));
|
xref = OF_xref_from_node(ofw_bus_get_node(dev));
|
||||||
if (bcm_intc_pic_register(sc, xref) != 0) {
|
if (bcm_intc_pic_register(sc, xref) != 0) {
|
||||||
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->intc_res);
|
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->intc_res);
|
||||||
@ -435,7 +413,6 @@ bcm_intc_attach(device_t dev)
|
|||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
sc->intc_bst = rman_get_bustag(sc->intc_res);
|
sc->intc_bst = rman_get_bustag(sc->intc_res);
|
||||||
sc->intc_bsh = rman_get_bushandle(sc->intc_res);
|
sc->intc_bsh = rman_get_bushandle(sc->intc_res);
|
||||||
|
|
||||||
@ -448,14 +425,12 @@ static device_method_t bcm_intc_methods[] = {
|
|||||||
DEVMETHOD(device_probe, bcm_intc_probe),
|
DEVMETHOD(device_probe, bcm_intc_probe),
|
||||||
DEVMETHOD(device_attach, bcm_intc_attach),
|
DEVMETHOD(device_attach, bcm_intc_attach),
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
DEVMETHOD(pic_disable_intr, bcm_intc_disable_intr),
|
DEVMETHOD(pic_disable_intr, bcm_intc_disable_intr),
|
||||||
DEVMETHOD(pic_enable_intr, bcm_intc_enable_intr),
|
DEVMETHOD(pic_enable_intr, bcm_intc_enable_intr),
|
||||||
DEVMETHOD(pic_map_intr, bcm_intc_map_intr),
|
DEVMETHOD(pic_map_intr, bcm_intc_map_intr),
|
||||||
DEVMETHOD(pic_post_filter, bcm_intc_post_filter),
|
DEVMETHOD(pic_post_filter, bcm_intc_post_filter),
|
||||||
DEVMETHOD(pic_post_ithread, bcm_intc_post_ithread),
|
DEVMETHOD(pic_post_ithread, bcm_intc_post_ithread),
|
||||||
DEVMETHOD(pic_pre_ithread, bcm_intc_pre_ithread),
|
DEVMETHOD(pic_pre_ithread, bcm_intc_pre_ithread),
|
||||||
#endif
|
|
||||||
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
@ -470,105 +445,3 @@ static devclass_t bcm_intc_devclass;
|
|||||||
|
|
||||||
EARLY_DRIVER_MODULE(intc, simplebus, bcm_intc_driver, bcm_intc_devclass,
|
EARLY_DRIVER_MODULE(intc, simplebus, bcm_intc_driver, bcm_intc_devclass,
|
||||||
0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
|
0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
int
|
|
||||||
arm_get_next_irq(int last_irq)
|
|
||||||
{
|
|
||||||
struct bcm_intc_softc *sc = bcm_intc_sc;
|
|
||||||
uint32_t pending;
|
|
||||||
int32_t irq = last_irq + 1;
|
|
||||||
#ifdef SOC_BCM2836
|
|
||||||
int ret;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Sanity check */
|
|
||||||
if (irq < 0)
|
|
||||||
irq = 0;
|
|
||||||
|
|
||||||
#ifdef SOC_BCM2836
|
|
||||||
if ((ret = bcm2836_get_next_irq(irq)) < 0)
|
|
||||||
return (-1);
|
|
||||||
if (ret != BCM2836_GPU_IRQ)
|
|
||||||
return (ret + BANK3_START);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* TODO: should we mask last_irq? */
|
|
||||||
if (irq < BANK1_START) {
|
|
||||||
pending = intc_read_4(sc, INTC_PENDING_BASIC);
|
|
||||||
if ((pending & 0xFF) == 0) {
|
|
||||||
irq = BANK1_START; /* skip to next bank */
|
|
||||||
} else do {
|
|
||||||
if (pending & (1 << irq))
|
|
||||||
return irq;
|
|
||||||
irq++;
|
|
||||||
} while (irq < BANK1_START);
|
|
||||||
}
|
|
||||||
if (irq < BANK2_START) {
|
|
||||||
pending = intc_read_4(sc, INTC_PENDING_BANK1);
|
|
||||||
if (pending == 0) {
|
|
||||||
irq = BANK2_START; /* skip to next bank */
|
|
||||||
} else do {
|
|
||||||
if (pending & (1 << IRQ_BANK1(irq)))
|
|
||||||
return irq;
|
|
||||||
irq++;
|
|
||||||
} while (irq < BANK2_START);
|
|
||||||
}
|
|
||||||
if (irq < BANK3_START) {
|
|
||||||
pending = intc_read_4(sc, INTC_PENDING_BANK2);
|
|
||||||
if (pending != 0) do {
|
|
||||||
if (pending & (1 << IRQ_BANK2(irq)))
|
|
||||||
return irq;
|
|
||||||
irq++;
|
|
||||||
} while (irq < BANK3_START);
|
|
||||||
}
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
arm_mask_irq(uintptr_t nb)
|
|
||||||
{
|
|
||||||
struct bcm_intc_softc *sc = bcm_intc_sc;
|
|
||||||
dprintf("%s: %d\n", __func__, nb);
|
|
||||||
|
|
||||||
if (IS_IRQ_BASIC(nb))
|
|
||||||
intc_write_4(sc, INTC_DISABLE_BASIC, (1 << nb));
|
|
||||||
else if (IS_IRQ_BANK1(nb))
|
|
||||||
intc_write_4(sc, INTC_DISABLE_BANK1, (1 << IRQ_BANK1(nb)));
|
|
||||||
else if (IS_IRQ_BANK2(nb))
|
|
||||||
intc_write_4(sc, INTC_DISABLE_BANK2, (1 << IRQ_BANK2(nb)));
|
|
||||||
#ifdef SOC_BCM2836
|
|
||||||
else if (ID_IRQ_BCM2836(nb))
|
|
||||||
bcm2836_mask_irq(nb - BANK3_START);
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
printf("arm_mask_irq: Invalid IRQ number: %d\n", nb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
arm_unmask_irq(uintptr_t nb)
|
|
||||||
{
|
|
||||||
struct bcm_intc_softc *sc = bcm_intc_sc;
|
|
||||||
dprintf("%s: %d\n", __func__, nb);
|
|
||||||
|
|
||||||
if (IS_IRQ_BASIC(nb))
|
|
||||||
intc_write_4(sc, INTC_ENABLE_BASIC, (1 << nb));
|
|
||||||
else if (IS_IRQ_BANK1(nb))
|
|
||||||
intc_write_4(sc, INTC_ENABLE_BANK1, (1 << IRQ_BANK1(nb)));
|
|
||||||
else if (IS_IRQ_BANK2(nb))
|
|
||||||
intc_write_4(sc, INTC_ENABLE_BANK2, (1 << IRQ_BANK2(nb)));
|
|
||||||
#ifdef SOC_BCM2836
|
|
||||||
else if (ID_IRQ_BCM2836(nb))
|
|
||||||
bcm2836_unmask_irq(nb - BANK3_START);
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
printf("arm_mask_irq: Invalid IRQ number: %d\n", nb);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SMP
|
|
||||||
void
|
|
||||||
intr_pic_init_secondary(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
@ -53,26 +53,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/ofw/ofw_bus_subr.h>
|
#include <dev/ofw/ofw_bus_subr.h>
|
||||||
#include <dev/ofw/ofw_bus.h>
|
#include <dev/ofw/ofw_bus.h>
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
#include "pic_if.h"
|
#include "pic_if.h"
|
||||||
#else
|
|
||||||
#include <arm/broadcom/bcm2835/bcm2836.h>
|
|
||||||
|
|
||||||
#define ARM_LOCAL_BASE 0x40000000
|
|
||||||
#define ARM_LOCAL_SIZE 0x00001000
|
|
||||||
|
|
||||||
#define ARM_LOCAL_CONTROL 0x00
|
|
||||||
#define ARM_LOCAL_PRESCALER 0x08
|
|
||||||
#define PRESCALER_19_2 0x80000000 /* 19.2 MHz */
|
|
||||||
#define ARM_LOCAL_INT_TIMER(n) (0x40 + (n) * 4)
|
|
||||||
#define ARM_LOCAL_INT_MAILBOX(n) (0x50 + (n) * 4)
|
|
||||||
#define ARM_LOCAL_INT_PENDING(n) (0x60 + (n) * 4)
|
|
||||||
#define INT_PENDING_MASK 0x011f
|
|
||||||
#define MAILBOX0_IRQ 4
|
|
||||||
#define MAILBOX0_IRQEN (1 << 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
#define BCM_LINTC_CONTROL_REG 0x00
|
#define BCM_LINTC_CONTROL_REG 0x00
|
||||||
#define BCM_LINTC_PRESCALER_REG 0x08
|
#define BCM_LINTC_PRESCALER_REG 0x08
|
||||||
#define BCM_LINTC_GPU_ROUTING_REG 0x0c
|
#define BCM_LINTC_GPU_ROUTING_REG 0x0c
|
||||||
@ -751,163 +733,3 @@ static devclass_t bcm_lintc_devclass;
|
|||||||
|
|
||||||
EARLY_DRIVER_MODULE(local_intc, simplebus, bcm_lintc_driver, bcm_lintc_devclass,
|
EARLY_DRIVER_MODULE(local_intc, simplebus, bcm_lintc_driver, bcm_lintc_devclass,
|
||||||
0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* A driver for features of the bcm2836.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct bcm2836_softc {
|
|
||||||
device_t sc_dev;
|
|
||||||
struct resource *sc_mem;
|
|
||||||
};
|
|
||||||
|
|
||||||
static device_identify_t bcm2836_identify;
|
|
||||||
static device_probe_t bcm2836_probe;
|
|
||||||
static device_attach_t bcm2836_attach;
|
|
||||||
|
|
||||||
struct bcm2836_softc *softc;
|
|
||||||
|
|
||||||
static void
|
|
||||||
bcm2836_identify(driver_t *driver, device_t parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (BUS_ADD_CHILD(parent, 0, "bcm2836", -1) == NULL)
|
|
||||||
device_printf(parent, "add child failed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
bcm2836_probe(device_t dev)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (softc != NULL)
|
|
||||||
return (ENXIO);
|
|
||||||
|
|
||||||
device_set_desc(dev, "Broadcom bcm2836");
|
|
||||||
|
|
||||||
return (BUS_PROBE_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
bcm2836_attach(device_t dev)
|
|
||||||
{
|
|
||||||
int i, rid;
|
|
||||||
|
|
||||||
softc = device_get_softc(dev);
|
|
||||||
softc->sc_dev = dev;
|
|
||||||
|
|
||||||
rid = 0;
|
|
||||||
softc->sc_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
|
|
||||||
ARM_LOCAL_BASE, ARM_LOCAL_BASE + ARM_LOCAL_SIZE, ARM_LOCAL_SIZE,
|
|
||||||
RF_ACTIVE);
|
|
||||||
if (softc->sc_mem == NULL) {
|
|
||||||
device_printf(dev, "could not allocate memory resource\n");
|
|
||||||
return (ENXIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
bus_write_4(softc->sc_mem, ARM_LOCAL_CONTROL, 0);
|
|
||||||
bus_write_4(softc->sc_mem, ARM_LOCAL_PRESCALER, PRESCALER_19_2);
|
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), 0);
|
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(i), 1);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bcm2836_get_next_irq(int last_irq)
|
|
||||||
{
|
|
||||||
uint32_t reg;
|
|
||||||
int cpu;
|
|
||||||
int irq;
|
|
||||||
|
|
||||||
cpu = PCPU_GET(cpuid);
|
|
||||||
|
|
||||||
reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_PENDING(cpu));
|
|
||||||
reg &= INT_PENDING_MASK;
|
|
||||||
if (reg == 0)
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
irq = ffs(reg) - 1;
|
|
||||||
|
|
||||||
return (irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
bcm2836_mask_irq(uintptr_t irq)
|
|
||||||
{
|
|
||||||
uint32_t reg;
|
|
||||||
#ifdef SMP
|
|
||||||
int cpu;
|
|
||||||
#endif
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (irq < MAILBOX0_IRQ) {
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
reg = bus_read_4(softc->sc_mem,
|
|
||||||
ARM_LOCAL_INT_TIMER(i));
|
|
||||||
reg &= ~(1 << irq);
|
|
||||||
bus_write_4(softc->sc_mem,
|
|
||||||
ARM_LOCAL_INT_TIMER(i), reg);
|
|
||||||
}
|
|
||||||
#ifdef SMP
|
|
||||||
} else if (irq == MAILBOX0_IRQ) {
|
|
||||||
/* Mailbox 0 for IPI */
|
|
||||||
cpu = PCPU_GET(cpuid);
|
|
||||||
reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu));
|
|
||||||
reg &= ~MAILBOX0_IRQEN;
|
|
||||||
bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu), reg);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
bcm2836_unmask_irq(uintptr_t irq)
|
|
||||||
{
|
|
||||||
uint32_t reg;
|
|
||||||
#ifdef SMP
|
|
||||||
int cpu;
|
|
||||||
#endif
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (irq < MAILBOX0_IRQ) {
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
reg = bus_read_4(softc->sc_mem,
|
|
||||||
ARM_LOCAL_INT_TIMER(i));
|
|
||||||
reg |= (1 << irq);
|
|
||||||
bus_write_4(softc->sc_mem,
|
|
||||||
ARM_LOCAL_INT_TIMER(i), reg);
|
|
||||||
}
|
|
||||||
#ifdef SMP
|
|
||||||
} else if (irq == MAILBOX0_IRQ) {
|
|
||||||
/* Mailbox 0 for IPI */
|
|
||||||
cpu = PCPU_GET(cpuid);
|
|
||||||
reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu));
|
|
||||||
reg |= MAILBOX0_IRQEN;
|
|
||||||
bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu), reg);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static device_method_t bcm2836_methods[] = {
|
|
||||||
/* Device interface */
|
|
||||||
DEVMETHOD(device_identify, bcm2836_identify),
|
|
||||||
DEVMETHOD(device_probe, bcm2836_probe),
|
|
||||||
DEVMETHOD(device_attach, bcm2836_attach),
|
|
||||||
|
|
||||||
DEVMETHOD_END
|
|
||||||
};
|
|
||||||
|
|
||||||
static devclass_t bcm2836_devclass;
|
|
||||||
|
|
||||||
static driver_t bcm2836_driver = {
|
|
||||||
"bcm2836",
|
|
||||||
bcm2836_methods,
|
|
||||||
sizeof(struct bcm2836_softc),
|
|
||||||
};
|
|
||||||
|
|
||||||
EARLY_DRIVER_MODULE(bcm2836, nexus, bcm2836_driver, bcm2836_devclass, 0, 0,
|
|
||||||
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
|
||||||
#endif
|
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 Andrew Turner.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
||||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _BCM2815_BCM2836_H
|
|
||||||
#define _BCM2815_BCM2836_H
|
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
#define BCM2836_GPU_IRQ 8
|
|
||||||
|
|
||||||
int bcm2836_get_next_irq(int);
|
|
||||||
void bcm2836_mask_irq(uintptr_t);
|
|
||||||
void bcm2836_unmask_irq(uintptr_t);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -142,43 +142,3 @@ bcm2836_mp_start_ap(platform_t plat)
|
|||||||
CPU_SET(i, &all_cpus);
|
CPU_SET(i, &all_cpus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
void
|
|
||||||
pic_ipi_send(cpuset_t cpus, u_int ipi)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
dsb();
|
|
||||||
for (i = 0; i < mp_ncpus; i++) {
|
|
||||||
if (CPU_ISSET(i, &cpus))
|
|
||||||
BSWR4(MBOX0SET_CORE(i), 1 << ipi);
|
|
||||||
}
|
|
||||||
wmb();
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
pic_ipi_read(int i)
|
|
||||||
{
|
|
||||||
uint32_t val;
|
|
||||||
int cpu, ipi;
|
|
||||||
|
|
||||||
cpu = PCPU_GET(cpuid);
|
|
||||||
dsb();
|
|
||||||
if (i != -1) {
|
|
||||||
val = BSRD4(MBOX0CLR_CORE(cpu));
|
|
||||||
if (val == 0)
|
|
||||||
return (0);
|
|
||||||
ipi = ffs(val) - 1;
|
|
||||||
BSWR4(MBOX0CLR_CORE(cpu), 1 << ipi);
|
|
||||||
dsb();
|
|
||||||
return (ipi);
|
|
||||||
}
|
|
||||||
return (0x3ff);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pic_ipi_clear(int ipi)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc
|
arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc
|
||||||
arm/broadcom/bcm2835/bcm2835_common.c optional fdt
|
|
||||||
arm/broadcom/bcm2835/bcm2835_cpufreq.c standard
|
arm/broadcom/bcm2835/bcm2835_cpufreq.c standard
|
||||||
arm/broadcom/bcm2835/bcm2835_dma.c standard
|
arm/broadcom/bcm2835/bcm2835_dma.c standard
|
||||||
arm/broadcom/bcm2835/bcm2835_fb.c optional sc
|
arm/broadcom/bcm2835/bcm2835_fb.c optional sc
|
||||||
|
@ -8,6 +8,5 @@ kern/kern_clocksource.c standard
|
|||||||
#
|
#
|
||||||
# Standard qemu virt devices and support.
|
# Standard qemu virt devices and support.
|
||||||
#
|
#
|
||||||
arm/qemu/virt_common.c standard
|
|
||||||
arm/qemu/virt_machdep.c standard
|
arm/qemu/virt_machdep.c standard
|
||||||
arm/qemu/virt_mp.c optional smp
|
arm/qemu/virt_mp.c optional smp
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2015 Andrew Turner
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
__FBSDID("$FreeBSD$");
|
|
||||||
|
|
||||||
#include "opt_platform.h"
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
|
|
||||||
#include <dev/fdt/fdt_common.h>
|
|
||||||
|
|
||||||
#include <machine/intr.h>
|
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
fdt_pic_decode_t fdt_pic_table[] = {
|
|
||||||
&gic_decode_fdt,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
#endif
|
|
@ -48,9 +48,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/ofw/ofw_bus.h>
|
#include <dev/ofw/ofw_bus.h>
|
||||||
#include <dev/ofw/ofw_bus_subr.h>
|
#include <dev/ofw/ofw_bus_subr.h>
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
#include "pic_if.h"
|
#include "pic_if.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#define INTC_REVISION 0x00
|
#define INTC_REVISION 0x00
|
||||||
#define INTC_SYSCONFIG 0x10
|
#define INTC_SYSCONFIG 0x10
|
||||||
@ -68,12 +66,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#define INTC_NIRQS 128
|
#define INTC_NIRQS 128
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
struct ti_aintc_irqsrc {
|
struct ti_aintc_irqsrc {
|
||||||
struct intr_irqsrc tai_isrc;
|
struct intr_irqsrc tai_isrc;
|
||||||
u_int tai_irq;
|
u_int tai_irq;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ti_aintc_softc {
|
struct ti_aintc_softc {
|
||||||
device_t sc_dev;
|
device_t sc_dev;
|
||||||
@ -81,9 +77,7 @@ struct ti_aintc_softc {
|
|||||||
bus_space_tag_t aintc_bst;
|
bus_space_tag_t aintc_bst;
|
||||||
bus_space_handle_t aintc_bsh;
|
bus_space_handle_t aintc_bsh;
|
||||||
uint8_t ver;
|
uint8_t ver;
|
||||||
#ifdef INTRNG
|
|
||||||
struct ti_aintc_irqsrc aintc_isrcs[INTC_NIRQS];
|
struct ti_aintc_irqsrc aintc_isrcs[INTC_NIRQS];
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource_spec ti_aintc_spec[] = {
|
static struct resource_spec ti_aintc_spec[] = {
|
||||||
@ -91,8 +85,6 @@ static struct resource_spec ti_aintc_spec[] = {
|
|||||||
{ -1, 0 }
|
{ -1, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ti_aintc_softc *ti_aintc_sc = NULL;
|
|
||||||
|
|
||||||
#define aintc_read_4(_sc, reg) \
|
#define aintc_read_4(_sc, reg) \
|
||||||
bus_space_read_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg))
|
bus_space_read_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg))
|
||||||
#define aintc_write_4(_sc, reg, val) \
|
#define aintc_write_4(_sc, reg, val) \
|
||||||
@ -105,7 +97,6 @@ static struct ofw_compat_data compat_data[] = {
|
|||||||
{NULL, 0},
|
{NULL, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
static inline void
|
static inline void
|
||||||
ti_aintc_irq_eoi(struct ti_aintc_softc *sc)
|
ti_aintc_irq_eoi(struct ti_aintc_softc *sc)
|
||||||
{
|
{
|
||||||
@ -244,16 +235,6 @@ ti_aintc_pic_attach(struct ti_aintc_softc *sc)
|
|||||||
return (intr_pic_claim_root(sc->sc_dev, xref, ti_aintc_intr, sc, 0));
|
return (intr_pic_claim_root(sc->sc_dev, xref, ti_aintc_intr, sc, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
static void
|
|
||||||
aintc_post_filter(void *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
arm_irq_memory_barrier(0);
|
|
||||||
aintc_write_4(ti_aintc_sc, INTC_CONTROL, 1); /* EOI */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ti_aintc_probe(device_t dev)
|
ti_aintc_probe(device_t dev)
|
||||||
{
|
{
|
||||||
@ -275,9 +256,6 @@ ti_aintc_attach(device_t dev)
|
|||||||
|
|
||||||
sc->sc_dev = dev;
|
sc->sc_dev = dev;
|
||||||
|
|
||||||
if (ti_aintc_sc)
|
|
||||||
return (ENXIO);
|
|
||||||
|
|
||||||
if (bus_alloc_resources(dev, ti_aintc_spec, sc->aintc_res)) {
|
if (bus_alloc_resources(dev, ti_aintc_spec, sc->aintc_res)) {
|
||||||
device_printf(dev, "could not allocate resources\n");
|
device_printf(dev, "could not allocate resources\n");
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
@ -286,8 +264,6 @@ ti_aintc_attach(device_t dev)
|
|||||||
sc->aintc_bst = rman_get_bustag(sc->aintc_res[0]);
|
sc->aintc_bst = rman_get_bustag(sc->aintc_res[0]);
|
||||||
sc->aintc_bsh = rman_get_bushandle(sc->aintc_res[0]);
|
sc->aintc_bsh = rman_get_bushandle(sc->aintc_res[0]);
|
||||||
|
|
||||||
ti_aintc_sc = sc;
|
|
||||||
|
|
||||||
x = aintc_read_4(sc, INTC_REVISION);
|
x = aintc_read_4(sc, INTC_REVISION);
|
||||||
device_printf(dev, "Revision %u.%u\n",(x >> 4) & 0xF, x & 0xF);
|
device_printf(dev, "Revision %u.%u\n",(x >> 4) & 0xF, x & 0xF);
|
||||||
|
|
||||||
@ -300,14 +276,10 @@ ti_aintc_attach(device_t dev)
|
|||||||
/*Set Priority Threshold */
|
/*Set Priority Threshold */
|
||||||
aintc_write_4(sc, INTC_THRESHOLD, 0xFF);
|
aintc_write_4(sc, INTC_THRESHOLD, 0xFF);
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
arm_post_filter = aintc_post_filter;
|
|
||||||
#else
|
|
||||||
if (ti_aintc_pic_attach(sc) != 0) {
|
if (ti_aintc_pic_attach(sc) != 0) {
|
||||||
device_printf(dev, "could not attach PIC\n");
|
device_printf(dev, "could not attach PIC\n");
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,14 +287,12 @@ static device_method_t ti_aintc_methods[] = {
|
|||||||
DEVMETHOD(device_probe, ti_aintc_probe),
|
DEVMETHOD(device_probe, ti_aintc_probe),
|
||||||
DEVMETHOD(device_attach, ti_aintc_attach),
|
DEVMETHOD(device_attach, ti_aintc_attach),
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
DEVMETHOD(pic_disable_intr, ti_aintc_disable_intr),
|
DEVMETHOD(pic_disable_intr, ti_aintc_disable_intr),
|
||||||
DEVMETHOD(pic_enable_intr, ti_aintc_enable_intr),
|
DEVMETHOD(pic_enable_intr, ti_aintc_enable_intr),
|
||||||
DEVMETHOD(pic_map_intr, ti_aintc_map_intr),
|
DEVMETHOD(pic_map_intr, ti_aintc_map_intr),
|
||||||
DEVMETHOD(pic_post_filter, ti_aintc_post_filter),
|
DEVMETHOD(pic_post_filter, ti_aintc_post_filter),
|
||||||
DEVMETHOD(pic_post_ithread, ti_aintc_post_ithread),
|
DEVMETHOD(pic_post_ithread, ti_aintc_post_ithread),
|
||||||
DEVMETHOD(pic_pre_ithread, ti_aintc_pre_ithread),
|
DEVMETHOD(pic_pre_ithread, ti_aintc_pre_ithread),
|
||||||
#endif
|
|
||||||
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
@ -338,46 +308,3 @@ static devclass_t ti_aintc_devclass;
|
|||||||
EARLY_DRIVER_MODULE(aintc, simplebus, ti_aintc_driver, ti_aintc_devclass,
|
EARLY_DRIVER_MODULE(aintc, simplebus, ti_aintc_driver, ti_aintc_devclass,
|
||||||
0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
||||||
SIMPLEBUS_PNP_INFO(compat_data);
|
SIMPLEBUS_PNP_INFO(compat_data);
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
int
|
|
||||||
arm_get_next_irq(int last_irq)
|
|
||||||
{
|
|
||||||
struct ti_aintc_softc *sc = ti_aintc_sc;
|
|
||||||
uint32_t active_irq;
|
|
||||||
|
|
||||||
/* Get the next active interrupt */
|
|
||||||
active_irq = aintc_read_4(sc, INTC_SIR_IRQ);
|
|
||||||
|
|
||||||
/* Check for spurious interrupt */
|
|
||||||
if ((active_irq & 0xffffff80)) {
|
|
||||||
device_printf(sc->sc_dev,
|
|
||||||
"Spurious interrupt detected (0x%08x)\n", active_irq);
|
|
||||||
aintc_write_4(sc, INTC_SIR_IRQ, 0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active_irq != last_irq)
|
|
||||||
return active_irq;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
arm_mask_irq(uintptr_t nb)
|
|
||||||
{
|
|
||||||
struct ti_aintc_softc *sc = ti_aintc_sc;
|
|
||||||
|
|
||||||
aintc_write_4(sc, INTC_MIR_SET(nb >> 5), (1UL << (nb & 0x1F)));
|
|
||||||
aintc_write_4(sc, INTC_CONTROL, 1); /* EOI */
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
arm_unmask_irq(uintptr_t nb)
|
|
||||||
{
|
|
||||||
struct ti_aintc_softc *sc = ti_aintc_sc;
|
|
||||||
|
|
||||||
arm_irq_memory_barrier(nb);
|
|
||||||
aintc_write_4(sc, INTC_MIR_CLEAR(nb >> 5), (1UL << (nb & 0x1F)));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
kern/kern_clocksource.c standard
|
kern/kern_clocksource.c standard
|
||||||
|
|
||||||
arm/ti/ti_common.c standard
|
|
||||||
arm/ti/ti_cpuid.c standard
|
arm/ti/ti_cpuid.c standard
|
||||||
arm/ti/ti_hwmods.c standard
|
arm/ti/ti_hwmods.c standard
|
||||||
arm/ti/ti_machdep.c standard
|
arm/ti/ti_machdep.c standard
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Developed by Semihalf.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of MARVELL nor the names of contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "opt_platform.h"
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
__FBSDID("$FreeBSD$");
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
#include <sys/bus.h>
|
|
||||||
#include <sys/kernel.h>
|
|
||||||
#include <sys/malloc.h>
|
|
||||||
#include <sys/kdb.h>
|
|
||||||
#include <sys/reboot.h>
|
|
||||||
|
|
||||||
#include <dev/fdt/fdt_common.h>
|
|
||||||
#include <dev/ofw/openfirm.h>
|
|
||||||
|
|
||||||
#include <machine/bus.h>
|
|
||||||
#include <machine/intr.h>
|
|
||||||
#include <machine/vmparam.h>
|
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
#ifdef SOC_TI_AM335X
|
|
||||||
static int
|
|
||||||
fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
|
|
||||||
int *pol)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!fdt_is_compatible(node, "ti,aintc") &&
|
|
||||||
!fdt_is_compatible(node, "ti,am33xx-intc"))
|
|
||||||
return (ENXIO);
|
|
||||||
|
|
||||||
*interrupt = fdt32_to_cpu(intr[0]);
|
|
||||||
*trig = INTR_TRIGGER_CONFORM;
|
|
||||||
*pol = INTR_POLARITY_CONFORM;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fdt_pic_decode_t fdt_pic_table[] = {
|
|
||||||
#if defined(SOC_OMAP4)
|
|
||||||
&gic_decode_fdt,
|
|
||||||
#endif
|
|
||||||
#ifdef SOC_TI_AM335X
|
|
||||||
&fdt_aintc_decode_ic,
|
|
||||||
#endif
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
#endif /* !INTRNG */
|
|
@ -66,9 +66,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include "gpio_if.h"
|
#include "gpio_if.h"
|
||||||
#include "ti_gpio_if.h"
|
#include "ti_gpio_if.h"
|
||||||
#ifdef INTRNG
|
|
||||||
#include "pic_if.h"
|
#include "pic_if.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(SOC_OMAP4) && !defined(SOC_TI_AM335X)
|
#if !defined(SOC_OMAP4) && !defined(SOC_TI_AM335X)
|
||||||
#error "Unknown SoC"
|
#error "Unknown SoC"
|
||||||
@ -121,10 +119,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
static int ti_gpio_intr(void *arg);
|
static int ti_gpio_intr(void *arg);
|
||||||
static int ti_gpio_detach(device_t);
|
static int ti_gpio_detach(device_t);
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
static int ti_gpio_pic_attach(struct ti_gpio_softc *sc);
|
static int ti_gpio_pic_attach(struct ti_gpio_softc *sc);
|
||||||
static int ti_gpio_pic_detach(struct ti_gpio_softc *sc);
|
static int ti_gpio_pic_detach(struct ti_gpio_softc *sc);
|
||||||
#endif
|
|
||||||
|
|
||||||
static u_int
|
static u_int
|
||||||
ti_first_gpio_bank(void)
|
ti_first_gpio_bank(void)
|
||||||
@ -321,15 +317,10 @@ ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
|
|||||||
if (ti_gpio_valid_pin(sc, pin) != 0)
|
if (ti_gpio_valid_pin(sc, pin) != 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
*caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP |
|
*caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP |
|
||||||
GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH |
|
GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH |
|
||||||
GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING |
|
GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING |
|
||||||
GPIO_INTR_EDGE_BOTH);
|
GPIO_INTR_EDGE_BOTH);
|
||||||
#else
|
|
||||||
*caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP |
|
|
||||||
GPIO_PIN_PULLDOWN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -558,43 +549,6 @@ ti_gpio_pin_toggle(device_t dev, uint32_t pin)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
/**
|
|
||||||
* ti_gpio_intr - ISR for all GPIO modules
|
|
||||||
* @arg: the soft context pointer
|
|
||||||
*
|
|
||||||
* LOCKING:
|
|
||||||
* Internally locks the context
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
ti_gpio_intr(void *arg)
|
|
||||||
{
|
|
||||||
int bank_last, irq;
|
|
||||||
struct intr_event *event;
|
|
||||||
struct ti_gpio_softc *sc;
|
|
||||||
uint32_t reg;
|
|
||||||
|
|
||||||
sc = (struct ti_gpio_softc *)arg;
|
|
||||||
bank_last = -1;
|
|
||||||
reg = 0; /* squelch bogus gcc warning */
|
|
||||||
reg = ti_gpio_intr_status(sc);
|
|
||||||
for (irq = 0; irq < sc->sc_maxpin; irq++) {
|
|
||||||
if ((reg & TI_GPIO_MASK(irq)) == 0)
|
|
||||||
continue;
|
|
||||||
event = sc->sc_events[irq];
|
|
||||||
if (event != NULL && !TAILQ_EMPTY(&event->ie_handlers))
|
|
||||||
intr_event_handle(event, NULL);
|
|
||||||
else
|
|
||||||
device_printf(sc->sc_dev, "Stray IRQ %d\n", irq);
|
|
||||||
/* Ack the IRQ Status bit. */
|
|
||||||
ti_gpio_intr_ack(sc, TI_GPIO_MASK(irq));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (FILTER_HANDLED);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ti_gpio_bank_init(device_t dev)
|
ti_gpio_bank_init(device_t dev)
|
||||||
{
|
{
|
||||||
@ -667,9 +621,6 @@ static int
|
|||||||
ti_gpio_attach(device_t dev)
|
ti_gpio_attach(device_t dev)
|
||||||
{
|
{
|
||||||
struct ti_gpio_softc *sc;
|
struct ti_gpio_softc *sc;
|
||||||
#ifndef INTRNG
|
|
||||||
unsigned int i;
|
|
||||||
#endif
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
@ -708,34 +659,12 @@ ti_gpio_attach(device_t dev)
|
|||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
if (ti_gpio_pic_attach(sc) != 0) {
|
if (ti_gpio_pic_attach(sc) != 0) {
|
||||||
device_printf(dev, "WARNING: unable to attach PIC\n");
|
device_printf(dev, "WARNING: unable to attach PIC\n");
|
||||||
ti_gpio_detach(dev);
|
ti_gpio_detach(dev);
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* Initialize the interrupt settings. The default is active-low
|
|
||||||
* interrupts.
|
|
||||||
*/
|
|
||||||
sc->sc_irq_trigger = malloc(
|
|
||||||
sizeof(*sc->sc_irq_trigger) * sc->sc_maxpin,
|
|
||||||
M_DEVBUF, M_WAITOK | M_ZERO);
|
|
||||||
sc->sc_irq_polarity = malloc(
|
|
||||||
sizeof(*sc->sc_irq_polarity) * sc->sc_maxpin,
|
|
||||||
M_DEVBUF, M_WAITOK | M_ZERO);
|
|
||||||
for (i = 0; i < sc->sc_maxpin; i++) {
|
|
||||||
sc->sc_irq_trigger[i] = INTR_TRIGGER_LEVEL;
|
|
||||||
sc->sc_irq_polarity[i] = INTR_POLARITY_LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
sc->sc_events = malloc(sizeof(struct intr_event *) * sc->sc_maxpin,
|
|
||||||
M_DEVBUF, M_WAITOK | M_ZERO);
|
|
||||||
|
|
||||||
sc->sc_mask_args = malloc(sizeof(struct ti_gpio_mask_arg) * sc->sc_maxpin,
|
|
||||||
M_DEVBUF, M_WAITOK | M_ZERO);
|
|
||||||
#endif
|
|
||||||
/* We need to go through each block and ensure the clocks are running and
|
/* We need to go through each block and ensure the clocks are running and
|
||||||
* the module is enabled. It might be better to do this only when the
|
* the module is enabled. It might be better to do this only when the
|
||||||
* pins are configured which would result in less power used if the GPIO
|
* pins are configured which would result in less power used if the GPIO
|
||||||
@ -783,19 +712,8 @@ ti_gpio_detach(device_t dev)
|
|||||||
if (sc->sc_mem_res != NULL)
|
if (sc->sc_mem_res != NULL)
|
||||||
ti_gpio_intr_clr(sc, 0xffffffff);
|
ti_gpio_intr_clr(sc, 0xffffffff);
|
||||||
gpiobus_detach_bus(dev);
|
gpiobus_detach_bus(dev);
|
||||||
#ifdef INTRNG
|
|
||||||
if (sc->sc_isrcs != NULL)
|
if (sc->sc_isrcs != NULL)
|
||||||
ti_gpio_pic_detach(sc);
|
ti_gpio_pic_detach(sc);
|
||||||
#else
|
|
||||||
if (sc->sc_events)
|
|
||||||
free(sc->sc_events, M_DEVBUF);
|
|
||||||
if (sc->sc_mask_args)
|
|
||||||
free(sc->sc_mask_args, M_DEVBUF);
|
|
||||||
if (sc->sc_irq_polarity)
|
|
||||||
free(sc->sc_irq_polarity, M_DEVBUF);
|
|
||||||
if (sc->sc_irq_trigger)
|
|
||||||
free(sc->sc_irq_trigger, M_DEVBUF);
|
|
||||||
#endif
|
|
||||||
/* Release the memory and IRQ resources. */
|
/* Release the memory and IRQ resources. */
|
||||||
if (sc->sc_irq_hdl) {
|
if (sc->sc_irq_hdl) {
|
||||||
bus_teardown_intr(dev, sc->sc_irq_res,
|
bus_teardown_intr(dev, sc->sc_irq_res,
|
||||||
@ -810,7 +728,6 @@ ti_gpio_detach(device_t dev)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
static inline void
|
static inline void
|
||||||
ti_gpio_rwreg_modify(struct ti_gpio_softc *sc, uint32_t reg, uint32_t mask,
|
ti_gpio_rwreg_modify(struct ti_gpio_softc *sc, uint32_t reg, uint32_t mask,
|
||||||
bool set_bits)
|
bool set_bits)
|
||||||
@ -1120,210 +1037,6 @@ ti_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
static uint32_t
|
|
||||||
ti_gpio_intr_reg(struct ti_gpio_softc *sc, int irq)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (ti_gpio_valid_pin(sc, irq) != 0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_LEVEL) {
|
|
||||||
if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW)
|
|
||||||
return (TI_GPIO_LEVELDETECT0);
|
|
||||||
else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH)
|
|
||||||
return (TI_GPIO_LEVELDETECT1);
|
|
||||||
} else if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_EDGE) {
|
|
||||||
if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW)
|
|
||||||
return (TI_GPIO_FALLINGDETECT);
|
|
||||||
else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH)
|
|
||||||
return (TI_GPIO_RISINGDETECT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ti_gpio_mask_irq_internal(struct ti_gpio_softc *sc, int irq)
|
|
||||||
{
|
|
||||||
uint32_t reg, val;
|
|
||||||
|
|
||||||
if (ti_gpio_valid_pin(sc, irq) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TI_GPIO_LOCK(sc);
|
|
||||||
ti_gpio_intr_clr(sc, TI_GPIO_MASK(irq));
|
|
||||||
reg = ti_gpio_intr_reg(sc, irq);
|
|
||||||
if (reg != 0) {
|
|
||||||
val = ti_gpio_read_4(sc, reg);
|
|
||||||
val &= ~TI_GPIO_MASK(irq);
|
|
||||||
ti_gpio_write_4(sc, reg, val);
|
|
||||||
}
|
|
||||||
TI_GPIO_UNLOCK(sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ti_gpio_unmask_irq_internal(struct ti_gpio_softc *sc, int irq)
|
|
||||||
{
|
|
||||||
uint32_t reg, val;
|
|
||||||
|
|
||||||
if (ti_gpio_valid_pin(sc, irq) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TI_GPIO_LOCK(sc);
|
|
||||||
reg = ti_gpio_intr_reg(sc, irq);
|
|
||||||
if (reg != 0) {
|
|
||||||
val = ti_gpio_read_4(sc, reg);
|
|
||||||
val |= TI_GPIO_MASK(irq);
|
|
||||||
ti_gpio_write_4(sc, reg, val);
|
|
||||||
ti_gpio_intr_set(sc, TI_GPIO_MASK(irq));
|
|
||||||
}
|
|
||||||
TI_GPIO_UNLOCK(sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ti_gpio_mask_irq(void *source)
|
|
||||||
{
|
|
||||||
struct ti_gpio_mask_arg *arg = source;
|
|
||||||
|
|
||||||
ti_gpio_mask_irq_internal(arg->softc, arg->pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ti_gpio_unmask_irq(void *source)
|
|
||||||
{
|
|
||||||
struct ti_gpio_mask_arg *arg = source;
|
|
||||||
|
|
||||||
ti_gpio_unmask_irq_internal(arg->softc, arg->pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
ti_gpio_activate_resource(device_t dev, device_t child, int type, int rid,
|
|
||||||
struct resource *res)
|
|
||||||
{
|
|
||||||
struct ti_gpio_mask_arg mask_arg;
|
|
||||||
|
|
||||||
if (type != SYS_RES_IRQ)
|
|
||||||
return (ENXIO);
|
|
||||||
|
|
||||||
/* Unmask the interrupt. */
|
|
||||||
mask_arg.pin = rman_get_start(res);
|
|
||||||
mask_arg.softc = device_get_softc(dev);
|
|
||||||
|
|
||||||
ti_gpio_unmask_irq((void *)&mask_arg);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
ti_gpio_deactivate_resource(device_t dev, device_t child, int type, int rid,
|
|
||||||
struct resource *res)
|
|
||||||
{
|
|
||||||
int pin;
|
|
||||||
|
|
||||||
if (type != SYS_RES_IRQ)
|
|
||||||
return (ENXIO);
|
|
||||||
|
|
||||||
/* Mask the interrupt. */
|
|
||||||
pin = rman_get_start(res);
|
|
||||||
ti_gpio_mask_irq((void *)(uintptr_t)pin);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
ti_gpio_config_intr(device_t dev, int irq, enum intr_trigger trig,
|
|
||||||
enum intr_polarity pol)
|
|
||||||
{
|
|
||||||
struct ti_gpio_softc *sc;
|
|
||||||
uint32_t oldreg, reg, val;
|
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
|
||||||
if (ti_gpio_valid_pin(sc, irq) != 0)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
/* There is no standard trigger or polarity. */
|
|
||||||
if (trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
TI_GPIO_LOCK(sc);
|
|
||||||
/*
|
|
||||||
* TRM recommends add the new event before remove the old one to
|
|
||||||
* avoid losing interrupts.
|
|
||||||
*/
|
|
||||||
oldreg = ti_gpio_intr_reg(sc, irq);
|
|
||||||
sc->sc_irq_trigger[irq] = trig;
|
|
||||||
sc->sc_irq_polarity[irq] = pol;
|
|
||||||
reg = ti_gpio_intr_reg(sc, irq);
|
|
||||||
if (reg != 0) {
|
|
||||||
/* Apply the new settings. */
|
|
||||||
val = ti_gpio_read_4(sc, reg);
|
|
||||||
val |= TI_GPIO_MASK(irq);
|
|
||||||
ti_gpio_write_4(sc, reg, val);
|
|
||||||
}
|
|
||||||
if (reg != oldreg && oldreg != 0) {
|
|
||||||
/* Remove the old settings. */
|
|
||||||
val = ti_gpio_read_4(sc, oldreg);
|
|
||||||
val &= ~TI_GPIO_MASK(irq);
|
|
||||||
ti_gpio_write_4(sc, oldreg, val);
|
|
||||||
}
|
|
||||||
TI_GPIO_UNLOCK(sc);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
ti_gpio_setup_intr(device_t dev, device_t child, struct resource *ires,
|
|
||||||
int flags, driver_filter_t *filt, driver_intr_t *handler,
|
|
||||||
void *arg, void **cookiep)
|
|
||||||
{
|
|
||||||
struct ti_gpio_softc *sc;
|
|
||||||
struct intr_event *event;
|
|
||||||
int pin, error;
|
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
|
||||||
pin = rman_get_start(ires);
|
|
||||||
if (ti_gpio_valid_pin(sc, pin) != 0)
|
|
||||||
panic("%s: bad pin %d", __func__, pin);
|
|
||||||
|
|
||||||
event = sc->sc_events[pin];
|
|
||||||
if (event == NULL) {
|
|
||||||
sc->sc_mask_args[pin].softc = sc;
|
|
||||||
sc->sc_mask_args[pin].pin = pin;
|
|
||||||
error = intr_event_create(&event, (void *)&sc->sc_mask_args[pin], 0,
|
|
||||||
pin, ti_gpio_mask_irq, ti_gpio_unmask_irq, NULL, NULL,
|
|
||||||
"gpio%d pin%d:", device_get_unit(dev), pin);
|
|
||||||
if (error != 0)
|
|
||||||
return (error);
|
|
||||||
sc->sc_events[pin] = event;
|
|
||||||
}
|
|
||||||
intr_event_add_handler(event, device_get_nameunit(child), filt,
|
|
||||||
handler, arg, intr_priority(flags), flags, cookiep);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
ti_gpio_teardown_intr(device_t dev, device_t child, struct resource *ires,
|
|
||||||
void *cookie)
|
|
||||||
{
|
|
||||||
struct ti_gpio_softc *sc;
|
|
||||||
int pin, err;
|
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
|
||||||
pin = rman_get_start(ires);
|
|
||||||
if (ti_gpio_valid_pin(sc, pin) != 0)
|
|
||||||
panic("%s: bad pin %d", __func__, pin);
|
|
||||||
if (sc->sc_events[pin] == NULL)
|
|
||||||
panic("Trying to teardown unoccupied IRQ");
|
|
||||||
err = intr_event_remove_handler(cookie);
|
|
||||||
if (!err)
|
|
||||||
sc->sc_events[pin] = NULL;
|
|
||||||
|
|
||||||
return (err);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static phandle_t
|
static phandle_t
|
||||||
ti_gpio_get_node(device_t bus, device_t dev)
|
ti_gpio_get_node(device_t bus, device_t dev)
|
||||||
{
|
{
|
||||||
@ -1347,7 +1060,6 @@ static device_method_t ti_gpio_methods[] = {
|
|||||||
DEVMETHOD(gpio_pin_set, ti_gpio_pin_set),
|
DEVMETHOD(gpio_pin_set, ti_gpio_pin_set),
|
||||||
DEVMETHOD(gpio_pin_toggle, ti_gpio_pin_toggle),
|
DEVMETHOD(gpio_pin_toggle, ti_gpio_pin_toggle),
|
||||||
|
|
||||||
#ifdef INTRNG
|
|
||||||
/* Interrupt controller interface */
|
/* Interrupt controller interface */
|
||||||
DEVMETHOD(pic_disable_intr, ti_gpio_pic_disable_intr),
|
DEVMETHOD(pic_disable_intr, ti_gpio_pic_disable_intr),
|
||||||
DEVMETHOD(pic_enable_intr, ti_gpio_pic_enable_intr),
|
DEVMETHOD(pic_enable_intr, ti_gpio_pic_enable_intr),
|
||||||
@ -1357,14 +1069,6 @@ static device_method_t ti_gpio_methods[] = {
|
|||||||
DEVMETHOD(pic_post_filter, ti_gpio_pic_post_filter),
|
DEVMETHOD(pic_post_filter, ti_gpio_pic_post_filter),
|
||||||
DEVMETHOD(pic_post_ithread, ti_gpio_pic_post_ithread),
|
DEVMETHOD(pic_post_ithread, ti_gpio_pic_post_ithread),
|
||||||
DEVMETHOD(pic_pre_ithread, ti_gpio_pic_pre_ithread),
|
DEVMETHOD(pic_pre_ithread, ti_gpio_pic_pre_ithread),
|
||||||
#else
|
|
||||||
/* Bus interface */
|
|
||||||
DEVMETHOD(bus_activate_resource, ti_gpio_activate_resource),
|
|
||||||
DEVMETHOD(bus_deactivate_resource, ti_gpio_deactivate_resource),
|
|
||||||
DEVMETHOD(bus_config_intr, ti_gpio_config_intr),
|
|
||||||
DEVMETHOD(bus_setup_intr, ti_gpio_setup_intr),
|
|
||||||
DEVMETHOD(bus_teardown_intr, ti_gpio_teardown_intr),
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ofw_bus interface */
|
/* ofw_bus interface */
|
||||||
DEVMETHOD(ofw_bus_get_node, ti_gpio_get_node),
|
DEVMETHOD(ofw_bus_get_node, ti_gpio_get_node),
|
||||||
|
@ -39,19 +39,12 @@
|
|||||||
*/
|
*/
|
||||||
#define MAX_GPIO_INTRS 8
|
#define MAX_GPIO_INTRS 8
|
||||||
|
|
||||||
#ifndef INTRNG
|
|
||||||
struct ti_gpio_mask_arg {
|
|
||||||
void *softc;
|
|
||||||
int pin;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
struct ti_gpio_irqsrc {
|
struct ti_gpio_irqsrc {
|
||||||
struct intr_irqsrc tgi_isrc;
|
struct intr_irqsrc tgi_isrc;
|
||||||
u_int tgi_irq;
|
u_int tgi_irq;
|
||||||
uint32_t tgi_mask;
|
uint32_t tgi_mask;
|
||||||
uint32_t tgi_mode;
|
uint32_t tgi_mode;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure that stores the driver context.
|
* Structure that stores the driver context.
|
||||||
@ -61,11 +54,6 @@ struct ti_gpio_irqsrc {
|
|||||||
struct ti_gpio_softc {
|
struct ti_gpio_softc {
|
||||||
device_t sc_dev;
|
device_t sc_dev;
|
||||||
device_t sc_busdev;
|
device_t sc_busdev;
|
||||||
#ifndef INTRNG
|
|
||||||
/* Interrupt trigger type and level. */
|
|
||||||
enum intr_trigger *sc_irq_trigger;
|
|
||||||
enum intr_polarity *sc_irq_polarity;
|
|
||||||
#endif
|
|
||||||
int sc_bank;
|
int sc_bank;
|
||||||
int sc_maxpin;
|
int sc_maxpin;
|
||||||
struct mtx sc_mtx;
|
struct mtx sc_mtx;
|
||||||
@ -74,13 +62,7 @@ struct ti_gpio_softc {
|
|||||||
struct resource *sc_mem_res;
|
struct resource *sc_mem_res;
|
||||||
int sc_irq_rid;
|
int sc_irq_rid;
|
||||||
struct resource *sc_irq_res;
|
struct resource *sc_irq_res;
|
||||||
#ifndef INTRNG
|
|
||||||
/* Interrupt events. */
|
|
||||||
struct intr_event **sc_events;
|
|
||||||
struct ti_gpio_mask_arg *sc_mask_args;
|
|
||||||
#else
|
|
||||||
struct ti_gpio_irqsrc *sc_isrcs;
|
struct ti_gpio_irqsrc *sc_isrcs;
|
||||||
#endif
|
|
||||||
/* The handle for the register IRQ handlers. */
|
/* The handle for the register IRQ handlers. */
|
||||||
void *sc_irq_hdl;
|
void *sc_irq_hdl;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user