Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Apr 2016 01:44:21 +0000 (UTC)
From:      Glen Barber <gjb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r297605 - in projects/release-pkg: . share/man/man4 sys/amd64/linux sys/amd64/linux32 sys/arm/broadcom/bcm2835 sys/arm/conf sys/arm/nvidia sys/arm/nvidia/tegra124 sys/arm/ti sys/boot/fd...
Message-ID:  <201604060144.u361iLKD034200@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gjb
Date: Wed Apr  6 01:44:21 2016
New Revision: 297605
URL: https://svnweb.freebsd.org/changeset/base/297605

Log:
  MFH
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/release-pkg/Makefile.inc1
  projects/release-pkg/Makefile.libcompat
  projects/release-pkg/share/man/man4/usb_quirk.4
  projects/release-pkg/sys/amd64/linux/linux_sysvec.c
  projects/release-pkg/sys/amd64/linux32/linux32_sysvec.c
  projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
  projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2835_intr.c
  projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2836.c
  projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2836.h
  projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2836_mp.c
  projects/release-pkg/sys/arm/conf/RPI-B
  projects/release-pkg/sys/arm/conf/RPI2
  projects/release-pkg/sys/arm/nvidia/tegra124/tegra124_clk_pll.c
  projects/release-pkg/sys/arm/nvidia/tegra124/tegra124_clk_super.c
  projects/release-pkg/sys/arm/nvidia/tegra124/tegra124_cpufreq.c
  projects/release-pkg/sys/arm/nvidia/tegra_ehci.c
  projects/release-pkg/sys/arm/ti/aintc.c
  projects/release-pkg/sys/boot/fdt/dts/arm/bcm2835.dtsi
  projects/release-pkg/sys/boot/fdt/dts/arm/bcm2836.dtsi
  projects/release-pkg/sys/dev/fdc/fdc.c
  projects/release-pkg/sys/dev/iicbus/ds1307.c
  projects/release-pkg/sys/dev/iicbus/ds1307reg.h
  projects/release-pkg/sys/dev/urtwn/if_urtwn.c
  projects/release-pkg/sys/dev/urtwn/if_urtwnvar.h
  projects/release-pkg/sys/dev/usb/controller/ehci_fsl.c
  projects/release-pkg/sys/dev/usb/controller/ehci_imx.c
  projects/release-pkg/sys/dev/usb/controller/musb_otg.c
  projects/release-pkg/sys/dev/usb/serial/uftdi.c
  projects/release-pkg/sys/dev/usb/wlan/if_rsu.c
  projects/release-pkg/sys/dev/xen/control/control.c
  projects/release-pkg/sys/i386/linux/linux_sysvec.c
  projects/release-pkg/sys/kern/kern_racct.c
  projects/release-pkg/sys/kern/kern_rctl.c
  projects/release-pkg/sys/kern/subr_smp.c
  projects/release-pkg/sys/net/netisr.c
  projects/release-pkg/sys/net80211/ieee80211.c
  projects/release-pkg/sys/net80211/ieee80211_freebsd.h
  projects/release-pkg/sys/net80211/ieee80211_hostap.c
  projects/release-pkg/sys/net80211/ieee80211_ht.h
  projects/release-pkg/sys/net80211/ieee80211_node.c
  projects/release-pkg/sys/net80211/ieee80211_output.c
  projects/release-pkg/sys/net80211/ieee80211_phy.c
  projects/release-pkg/sys/net80211/ieee80211_phy.h
  projects/release-pkg/sys/net80211/ieee80211_sta.c
  projects/release-pkg/sys/net80211/ieee80211_superg.c
  projects/release-pkg/sys/net80211/ieee80211_superg.h
  projects/release-pkg/sys/net80211/ieee80211_var.h
  projects/release-pkg/sys/powerpc/mpc85xx/i2c.c
  projects/release-pkg/sys/sys/param.h
  projects/release-pkg/sys/x86/x86/mp_x86.c
  projects/release-pkg/usr.bin/sed/compile.c
  projects/release-pkg/usr.sbin/bhyve/pci_ahci.c
  projects/release-pkg/usr.sbin/bhyveload/bhyveload.c
Directory Properties:
  projects/release-pkg/   (props changed)
  projects/release-pkg/share/   (props changed)
  projects/release-pkg/share/man/man4/   (props changed)
  projects/release-pkg/sys/   (props changed)
  projects/release-pkg/sys/boot/   (props changed)
  projects/release-pkg/usr.sbin/bhyve/   (props changed)
  projects/release-pkg/usr.sbin/bhyveload/   (props changed)

Modified: projects/release-pkg/Makefile.inc1
==============================================================================
--- projects/release-pkg/Makefile.inc1	Wed Apr  6 01:22:20 2016	(r297604)
+++ projects/release-pkg/Makefile.inc1	Wed Apr  6 01:44:21 2016	(r297605)
@@ -470,7 +470,7 @@ LIBCOMPAT= SOFT
 
 WMAKE=		${WMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 DESTDIR=${WORLDTMP}
 
-IMAKEENV=	${CROSSENV:N_LDSCRIPTROOT=*}
+IMAKEENV=	${CROSSENV}
 IMAKE=		${IMAKEENV} ${MAKE} -f Makefile.inc1 \
 		${IMAKE_INSTALL} ${IMAKE_MTREE}
 .if empty(.MAKEFLAGS:M-n)

Modified: projects/release-pkg/Makefile.libcompat
==============================================================================
--- projects/release-pkg/Makefile.libcompat	Wed Apr  6 01:22:20 2016	(r297604)
+++ projects/release-pkg/Makefile.libcompat	Wed Apr  6 01:44:21 2016	(r297605)
@@ -97,7 +97,7 @@ LIBCOMPATWMAKEFLAGS+= CC="${XCC} ${LIBCO
 		MK_TESTS=no
 LIBCOMPATWMAKE+=	${LIBCOMPATWMAKEENV} ${MAKE} ${LIBCOMPATWMAKEFLAGS} \
 			MK_MAN=no MK_HTML=no
-LIBCOMPATIMAKE+=	${LIBCOMPATWMAKE:NINSTALL=*:NDESTDIR=*:N_LDSCRIPTROOT=*} \
+LIBCOMPATIMAKE+=	${LIBCOMPATWMAKE:NINSTALL=*:NDESTDIR=*} \
 			MK_TOOLCHAIN=no ${IMAKE_INSTALL} \
 			-DLIBRARIES_ONLY
 

Modified: projects/release-pkg/share/man/man4/usb_quirk.4
==============================================================================
--- projects/release-pkg/share/man/man4/usb_quirk.4	Wed Apr  6 01:22:20 2016	(r297604)
+++ projects/release-pkg/share/man/man4/usb_quirk.4	Wed Apr  6 01:44:21 2016	(r297605)
@@ -16,7 +16,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 26, 2015
+.Dd April 4, 2016
 .Dt USB_QUIRK 4
 .Os
 .Sh NAME
@@ -234,6 +234,12 @@ device which appears as a USB device on
 usbconfig -d ugen0.3 add_quirk UQ_MSC_EJECT_WAIT
 .Ed
 .Pp
+Enable a Holtec/Keep Out F85 gaming keyboard on
+.Pa ugen1.4 :
+.Bd -literal -offset indent
+usbconfig -d ugen1.4 add_quirk UQ_KBD_BOOTPROTO
+.Ed
+.Pp
 To install a quirk at boot time, place one or several lines like the
 following in
 .Xr loader.conf 5 :

Modified: projects/release-pkg/sys/amd64/linux/linux_sysvec.c
==============================================================================
--- projects/release-pkg/sys/amd64/linux/linux_sysvec.c	Wed Apr  6 01:22:20 2016	(r297604)
+++ projects/release-pkg/sys/amd64/linux/linux_sysvec.c	Wed Apr  6 01:44:21 2016	(r297605)
@@ -992,3 +992,4 @@ static moduledata_t linux64_elf_mod = {
 
 DECLARE_MODULE_TIED(linux64elf, linux64_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
 MODULE_DEPEND(linux64elf, linux_common, 1, 1, 1);
+FEATURE(linux64, "Linux 64bit support");

Modified: projects/release-pkg/sys/amd64/linux32/linux32_sysvec.c
==============================================================================
--- projects/release-pkg/sys/amd64/linux32/linux32_sysvec.c	Wed Apr  6 01:22:20 2016	(r297604)
+++ projects/release-pkg/sys/amd64/linux32/linux32_sysvec.c	Wed Apr  6 01:44:21 2016	(r297605)
@@ -1205,3 +1205,4 @@ static moduledata_t linux_elf_mod = {
 
 DECLARE_MODULE_TIED(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
 MODULE_DEPEND(linuxelf, linux_common, 1, 1, 1);
+FEATURE(linux, "Linux 32bit support");

Modified: projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
==============================================================================
--- projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2835_gpio.c	Wed Apr  6 01:22:20 2016	(r297604)
+++ projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2835_gpio.c	Wed Apr  6 01:44:21 2016	(r297605)
@@ -28,6 +28,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_platform.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
@@ -37,10 +39,12 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
+#include <sys/proc.h>
 #include <sys/rman.h>
 #include <sys/sysctl.h>
 
 #include <machine/bus.h>
+#include <machine/intr.h>
 
 #include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/ofw_bus.h>
@@ -49,6 +53,10 @@ __FBSDID("$FreeBSD$");
 
 #include "gpio_if.h"
 
+#ifdef ARM_INTRNG
+#include "pic_if.h"
+#endif
+
 #ifdef DEBUG
 #define dprintf(fmt, args...) do { printf("%s(): ", __func__);   \
     printf(fmt,##args); } while (0)
@@ -64,10 +72,10 @@ __FBSDID("$FreeBSD$");
 
 static struct resource_spec bcm_gpio_res_spec[] = {
 	{ SYS_RES_MEMORY, 0, RF_ACTIVE },
-	{ SYS_RES_IRQ, 0, RF_ACTIVE },
-	{ SYS_RES_IRQ, 1, RF_ACTIVE },
-	{ SYS_RES_IRQ, 2, RF_ACTIVE },
-	{ SYS_RES_IRQ, 3, RF_ACTIVE },
+	{ SYS_RES_IRQ, 0, RF_ACTIVE },	/* bank 0 interrupt */
+	{ SYS_RES_IRQ, 1, RF_ACTIVE },	/* bank 1 interrupt */
+	{ SYS_RES_IRQ, 2, RF_ACTIVE },	/* bank 1 interrupt (mirrored) */
+	{ SYS_RES_IRQ, 3, RF_ACTIVE },	/* bank 0-1 interrupt (united) */
 	{ -1, 0, 0 }
 };
 
@@ -76,6 +84,15 @@ struct bcm_gpio_sysctl {
 	uint32_t		pin;
 };
 
+#ifdef ARM_INTRNG
+struct bcm_gpio_irqsrc {
+	struct intr_irqsrc	bgi_isrc;
+	uint32_t		bgi_irq;
+	uint32_t		bgi_reg;
+	uint32_t		bgi_mask;
+};
+#endif
+
 struct bcm_gpio_softc {
 	device_t		sc_dev;
 	device_t		sc_busdev;
@@ -88,10 +105,16 @@ struct bcm_gpio_softc {
 	int			sc_ro_npins;
 	int			sc_ro_pins[BCM_GPIO_PINS];
 	struct gpio_pin		sc_gpio_pins[BCM_GPIO_PINS];
+#ifndef ARM_INTRNG
 	struct intr_event *	sc_events[BCM_GPIO_PINS];
+#endif
 	struct bcm_gpio_sysctl	sc_sysctl[BCM_GPIO_PINS];
+#ifdef ARM_INTRNG
+	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 {
@@ -130,6 +153,13 @@ enum bcm_gpio_pud {
 
 static struct bcm_gpio_softc *bcm_gpio_sc = NULL;
 
+#ifdef ARM_INTRNG
+static int bcm_gpio_intr_bank0(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_detach(struct bcm_gpio_softc *sc);
+#endif
+
 static int
 bcm_gpio_pin_is_ro(struct bcm_gpio_softc *sc, int pin)
 {
@@ -661,6 +691,7 @@ bcm_gpio_get_reserved_pins(struct bcm_gp
 	return (0);
 }
 
+#ifndef ARM_INTRNG
 static int
 bcm_gpio_intr(void *arg)
 {
@@ -694,6 +725,7 @@ bcm_gpio_intr(void *arg)
 
 	return (FILTER_HANDLED);
 }
+#endif
 
 static int
 bcm_gpio_probe(device_t dev)
@@ -709,6 +741,49 @@ bcm_gpio_probe(device_t dev)
 	return (BUS_PROBE_DEFAULT);
 }
 
+#ifdef ARM_INTRNG
+static int
+bcm_gpio_intr_attach(device_t dev)
+{
+	struct bcm_gpio_softc *sc;
+
+	/*
+	 *  Only first two interrupt lines are used. Third line is
+	 *  mirrored second line and forth line is common for all banks.
+	 */
+	sc = device_get_softc(dev);
+	if (sc->sc_res[1] == NULL || sc->sc_res[2] == NULL)
+		return (-1);
+
+	if (bcm_gpio_pic_attach(sc) != 0) {
+		device_printf(dev, "unable to attach PIC\n");
+		return (-1);
+	}
+	if (bus_setup_intr(dev, sc->sc_res[1], INTR_TYPE_MISC | INTR_MPSAFE,
+	    bcm_gpio_intr_bank0, NULL, sc, &sc->sc_intrhand[0]) != 0)
+		return (-1);
+	if (bus_setup_intr(dev, sc->sc_res[2], INTR_TYPE_MISC | INTR_MPSAFE,
+	    bcm_gpio_intr_bank1, NULL, sc, &sc->sc_intrhand[1]) != 0)
+		return (-1);
+
+	return (0);
+}
+
+static void
+bcm_gpio_intr_detach(device_t dev)
+{
+	struct bcm_gpio_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->sc_intrhand[0] != NULL)
+		bus_teardown_intr(dev, sc->sc_res[1], sc->sc_intrhand[0]);
+	if (sc->sc_intrhand[1] != NULL)
+		bus_teardown_intr(dev, sc->sc_res[2], sc->sc_intrhand[1]);
+
+	bcm_gpio_pic_detach(sc);
+}
+
+#else
 static int
 bcm_gpio_intr_attach(device_t dev)
 {
@@ -741,6 +816,7 @@ bcm_gpio_intr_detach(device_t dev)
 		}
 	}
 }
+#endif
 
 static int
 bcm_gpio_attach(device_t dev)
@@ -786,9 +862,11 @@ bcm_gpio_attach(device_t dev)
 		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_flags = bcm_gpio_func_flag(func);
+#ifndef ARM_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++;
 	}
 	sc->sc_gpio_npins = i;
@@ -814,6 +892,289 @@ bcm_gpio_detach(device_t dev)
 	return (EBUSY);
 }
 
+#ifdef ARM_INTRNG
+static inline void
+bcm_gpio_isrc_eoi(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
+{
+	uint32_t bank;
+
+	/* Write 1 to clear. */
+	bank = BCM_GPIO_BANK(bgi->bgi_irq);
+	BCM_GPIO_WRITE(sc, BCM_GPIO_GPEDS(bank), bgi->bgi_mask);
+}
+
+static inline bool
+bcm_gpio_isrc_is_level(struct bcm_gpio_irqsrc *bgi)
+{
+	uint32_t bank;
+
+	bank = BCM_GPIO_BANK(bgi->bgi_irq);
+	return (bgi->bgi_reg == BCM_GPIO_GPHEN(bank) ||
+	    bgi->bgi_reg == BCM_GPIO_GPLEN(bank));
+}
+
+static inline void
+bcm_gpio_isrc_mask(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
+{
+
+	BCM_GPIO_LOCK(sc);
+	BCM_GPIO_CLEAR_BITS(sc, bgi->bgi_reg, bgi->bgi_mask);
+	BCM_GPIO_UNLOCK(bcm_gpio_sc);
+}
+
+static inline void
+bcm_gpio_isrc_unmask(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
+{
+
+	BCM_GPIO_LOCK(sc);
+	BCM_GPIO_SET_BITS(sc, bgi->bgi_reg, bgi->bgi_mask);
+	BCM_GPIO_UNLOCK(sc);
+}
+
+static int
+bcm_gpio_intr_internal(struct bcm_gpio_softc *sc, uint32_t bank)
+{
+	u_int irq;
+	struct bcm_gpio_irqsrc *bgi;
+	uint32_t reg;
+
+	/* Do not care of spurious interrupt on GPIO. */
+	reg = BCM_GPIO_READ(sc, BCM_GPIO_GPEDS(bank));
+	while (reg != 0) {
+		irq = BCM_GPIO_PINS_PER_BANK * bank + ffs(reg) - 1;
+		bgi = sc->sc_isrcs + irq;
+		if (!bcm_gpio_isrc_is_level(bgi))
+			bcm_gpio_isrc_eoi(sc, bgi);
+		if (intr_isrc_dispatch(&bgi->bgi_isrc,
+		    curthread->td_intr_frame) != 0) {
+			bcm_gpio_isrc_mask(sc, bgi);
+			if (bcm_gpio_isrc_is_level(bgi))
+				bcm_gpio_isrc_eoi(sc, bgi);
+			device_printf(sc->sc_dev, "Stray irq %u disabled\n",
+			    irq);
+		}
+		reg &= ~bgi->bgi_mask;
+	}
+	return (FILTER_HANDLED);
+}
+
+static int
+bcm_gpio_intr_bank0(void *arg)
+{
+
+	return (bcm_gpio_intr_internal(arg, 0));
+}
+
+static int
+bcm_gpio_intr_bank1(void *arg)
+{
+
+	return (bcm_gpio_intr_internal(arg, 1));
+}
+
+static int
+bcm_gpio_pic_attach(struct bcm_gpio_softc *sc)
+{
+	int error;
+	uint32_t irq;
+	const char *name;
+
+	name = device_get_nameunit(sc->sc_dev);
+	for (irq = 0; irq < BCM_GPIO_PINS; irq++) {
+		sc->sc_isrcs[irq].bgi_irq = irq;
+		sc->sc_isrcs[irq].bgi_mask = BCM_GPIO_MASK(irq);
+		sc->sc_isrcs[irq].bgi_reg = 0;
+
+		error = intr_isrc_register(&sc->sc_isrcs[irq].bgi_isrc,
+		    sc->sc_dev, 0, "%s,%u", name, irq);
+		if (error != 0)
+			return (error); /* XXX deregister ISRCs */
+	}
+	return (intr_pic_register(sc->sc_dev,
+	    OF_xref_from_node(ofw_bus_get_node(sc->sc_dev))));
+}
+
+static int
+bcm_gpio_pic_detach(struct bcm_gpio_softc *sc)
+{
+
+	/*
+	 *  There has not been established any procedure yet
+	 *  how to detach PIC from living system correctly.
+	 */
+	device_printf(sc->sc_dev, "%s: not implemented yet\n", __func__);
+	return (EBUSY);
+}
+
+static void
+bcm_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
+
+	bcm_gpio_isrc_mask(sc, bgi);
+}
+
+static void
+bcm_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
+
+	arm_irq_memory_barrier(bgi->bgi_irq);
+	bcm_gpio_isrc_unmask(sc, bgi);
+}
+
+static int
+bcm_gpio_pic_map_fdt(struct bcm_gpio_softc *sc, u_int ncells, pcell_t *cells,
+    u_int *irqp, uint32_t *regp)
+{
+	u_int irq;
+	uint32_t reg, bank;
+
+	/*
+	 * The first cell is the interrupt number.
+	 * The second cell is used to specify flags:
+	 *	bits[3:0] trigger type and level flags:
+	 *		1 = low-to-high edge triggered.
+	 *		2 = high-to-low edge triggered.
+	 *		4 = active high level-sensitive.
+	 *		8 = active low level-sensitive.
+	 */
+	if (ncells != 2)
+		return (EINVAL);
+
+	irq = cells[0];
+	if (irq >= BCM_GPIO_PINS || bcm_gpio_pin_is_ro(sc, irq))
+		return (EINVAL);
+
+	/*
+	 * All interrupt types could be set for an interrupt at one moment.
+	 * At least, the combination of 'low-to-high' and 'high-to-low' edge
+	 * triggered interrupt types can make a sense. However, no combo is
+	 * supported now.
+	 */
+	bank = BCM_GPIO_BANK(irq);
+	if (cells[1] == 1)
+		reg = BCM_GPIO_GPREN(bank);
+	else if (cells[1] == 2)
+		reg = BCM_GPIO_GPFEN(bank);
+	else if (cells[1] == 4)
+		reg = BCM_GPIO_GPHEN(bank);
+	else if (cells[1] == 8)
+		reg = BCM_GPIO_GPLEN(bank);
+	else
+		return (EINVAL);
+
+	*irqp = irq;
+	if (regp != NULL)
+		*regp = reg;
+	return (0);
+}
+
+static int
+bcm_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
+    struct intr_irqsrc **isrcp)
+{
+	int error;
+	u_int irq;
+	struct bcm_gpio_softc *sc;
+
+	if (data->type != INTR_MAP_DATA_FDT)
+		return (ENOTSUP);
+
+	sc = device_get_softc(dev);
+	error = bcm_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells,
+	    &irq, NULL);
+	if (error == 0)
+		*isrcp = &sc->sc_isrcs[irq].bgi_isrc;
+	return (error);
+}
+
+static void
+bcm_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
+
+	if (bcm_gpio_isrc_is_level(bgi))
+		bcm_gpio_isrc_eoi(sc, bgi);
+}
+
+static void
+bcm_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
+{
+
+	bcm_gpio_pic_enable_intr(dev, isrc);
+}
+
+static void
+bcm_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
+
+	bcm_gpio_isrc_mask(sc, bgi);
+	if (bcm_gpio_isrc_is_level(bgi))
+		bcm_gpio_isrc_eoi(sc, bgi);
+}
+
+static int
+bcm_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
+    struct resource *res, struct intr_map_data *data)
+{
+	u_int irq;
+	uint32_t bank, reg;
+	struct bcm_gpio_softc *sc;
+	struct bcm_gpio_irqsrc *bgi;
+
+	if (data == NULL || data->type != INTR_MAP_DATA_FDT)
+		return (ENOTSUP);
+
+	sc = device_get_softc(dev);
+	bgi = (struct bcm_gpio_irqsrc *)isrc;
+
+	/* Get and check config for an interrupt. */
+	if (bcm_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells, &irq,
+	    &reg) != 0 || bgi->bgi_irq != irq)
+		return (EINVAL);
+
+	/*
+	 * If this is a setup for another handler,
+	 * only check that its configuration match.
+	 */
+	if (isrc->isrc_handlers != 0)
+		return (bgi->bgi_reg == reg ? 0 : EINVAL);
+
+	bank = BCM_GPIO_BANK(irq);
+	BCM_GPIO_LOCK(sc);
+	BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
+	BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
+	BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask);
+	BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask);
+	bgi->bgi_reg = reg;
+	BCM_GPIO_SET_BITS(sc, reg, bgi->bgi_mask);
+	BCM_GPIO_UNLOCK(sc);
+	return (0);
+}
+
+static int
+bcm_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
+    struct resource *res, struct intr_map_data *data)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
+
+	if (isrc->isrc_handlers == 0) {
+		BCM_GPIO_LOCK(sc);
+		BCM_GPIO_CLEAR_BITS(sc, bgi->bgi_reg, bgi->bgi_mask);
+		bgi->bgi_reg = 0;
+		BCM_GPIO_UNLOCK(sc);
+	}
+	return (0);
+}
+
+#else
 static uint32_t
 bcm_gpio_intr_reg(struct bcm_gpio_softc *sc, unsigned int irq, uint32_t bank)
 {
@@ -984,6 +1345,7 @@ bcm_gpio_teardown_intr(device_t dev, dev
 
 	return (err);
 }
+#endif
 
 static phandle_t
 bcm_gpio_get_node(device_t bus, device_t dev)
@@ -1010,13 +1372,24 @@ static device_method_t bcm_gpio_methods[
 	DEVMETHOD(gpio_pin_set,		bcm_gpio_pin_set),
 	DEVMETHOD(gpio_pin_toggle,	bcm_gpio_pin_toggle),
 
+#ifdef ARM_INTRNG
+	/* Interrupt controller interface */
+	DEVMETHOD(pic_disable_intr,	bcm_gpio_pic_disable_intr),
+	DEVMETHOD(pic_enable_intr,	bcm_gpio_pic_enable_intr),
+	DEVMETHOD(pic_map_intr,		bcm_gpio_pic_map_intr),
+	DEVMETHOD(pic_post_filter,	bcm_gpio_pic_post_filter),
+	DEVMETHOD(pic_post_ithread,	bcm_gpio_pic_post_ithread),
+	DEVMETHOD(pic_pre_ithread,	bcm_gpio_pic_pre_ithread),
+	DEVMETHOD(pic_setup_intr,	bcm_gpio_pic_setup_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 */
 	DEVMETHOD(ofw_bus_get_node,	bcm_gpio_get_node),
 

Modified: projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2835_intr.c
==============================================================================
--- projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2835_intr.c	Wed Apr  6 01:22:20 2016	(r297604)
+++ projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2835_intr.c	Wed Apr  6 01:44:21 2016	(r297605)
@@ -30,12 +30,15 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_platform.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
 #include <sys/ktr.h>
 #include <sys/module.h>
+#include <sys/proc.h>
 #include <sys/rman.h>
 #include <machine/bus.h>
 #include <machine/intr.h>
@@ -49,6 +52,10 @@ __FBSDID("$FreeBSD$");
 #include <arm/broadcom/bcm2835/bcm2836.h>
 #endif
 
+#ifdef ARM_INTRNG
+#include "pic_if.h"
+#endif
+
 #define	INTC_PENDING_BASIC	0x00
 #define	INTC_PENDING_BANK1	0x04
 #define	INTC_PENDING_BANK2	0x08
@@ -60,17 +67,55 @@ __FBSDID("$FreeBSD$");
 #define	INTC_DISABLE_BANK2	0x20
 #define	INTC_DISABLE_BASIC	0x24
 
+#define INTC_PENDING_BASIC_ARM		0x0000FF
+#define INTC_PENDING_BASIC_GPU1_PEND	0x000100
+#define INTC_PENDING_BASIC_GPU2_PEND	0x000200
+#define INTC_PENDING_BASIC_GPU1_7	0x000400
+#define INTC_PENDING_BASIC_GPU1_9	0x000800
+#define INTC_PENDING_BASIC_GPU1_10	0x001000
+#define INTC_PENDING_BASIC_GPU1_18	0x002000
+#define INTC_PENDING_BASIC_GPU1_19	0x004000
+#define INTC_PENDING_BASIC_GPU2_21	0x008000
+#define INTC_PENDING_BASIC_GPU2_22	0x010000
+#define INTC_PENDING_BASIC_GPU2_23	0x020000
+#define INTC_PENDING_BASIC_GPU2_24	0x040000
+#define INTC_PENDING_BASIC_GPU2_25	0x080000
+#define INTC_PENDING_BASIC_GPU2_30	0x100000
+#define INTC_PENDING_BASIC_MASK		0x1FFFFF
+
+#define INTC_PENDING_BASIC_GPU1_MASK	(INTC_PENDING_BASIC_GPU1_7 |	\
+					 INTC_PENDING_BASIC_GPU1_9 |	\
+					 INTC_PENDING_BASIC_GPU1_10 |	\
+					 INTC_PENDING_BASIC_GPU1_18 |	\
+					 INTC_PENDING_BASIC_GPU1_19)
+
+#define INTC_PENDING_BASIC_GPU2_MASK	(INTC_PENDING_BASIC_GPU2_21 |	\
+					 INTC_PENDING_BASIC_GPU2_22 |	\
+					 INTC_PENDING_BASIC_GPU2_23 |	\
+					 INTC_PENDING_BASIC_GPU2_24 |	\
+					 INTC_PENDING_BASIC_GPU2_25 |	\
+					 INTC_PENDING_BASIC_GPU2_30)
+
+#define INTC_PENDING_BANK1_MASK (~((1 << 7) | (1 << 9) | (1 << 10) | \
+    (1 << 18) | (1 << 19)))
+#define INTC_PENDING_BANK2_MASK (~((1 << 21) | (1 << 22) | (1 << 23) | \
+    (1 << 24) | (1 << 25) | (1 << 30)))
+
 #define	BANK1_START	8
 #define	BANK1_END	(BANK1_START + 32 - 1)
 #define	BANK2_START	(BANK1_START + 32)
 #define	BANK2_END	(BANK2_START + 32 - 1)
+#ifndef ARM_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_BANK1(n)	(((n) >= BANK1_START) && ((n) <= BANK1_END))
 #define	IS_IRQ_BANK2(n)	(((n) >= BANK2_START) && ((n) <= BANK2_END))
+#ifndef ARM_INTRNG
 #define	ID_IRQ_BCM2836(n) (((n) >= BANK3_START) && ((n) <= BANK3_END))
+#endif
 #define	IRQ_BANK1(n)	((n) - BANK1_START)
 #define	IRQ_BANK2(n)	((n) - BANK2_START)
 
@@ -80,11 +125,28 @@ __FBSDID("$FreeBSD$");
 #define dprintf(fmt, args...)
 #endif
 
+#ifdef ARM_INTRNG
+#define BCM_INTC_NIRQS		72	/* 8 + 32 + 32 */
+
+struct bcm_intc_irqsrc {
+	struct intr_irqsrc	bii_isrc;
+	u_int			bii_irq;
+	uint16_t		bii_disable_reg;
+	uint16_t		bii_enable_reg;
+	uint32_t		bii_mask;
+};
+#endif
+
 struct bcm_intc_softc {
 	device_t		sc_dev;
 	struct resource *	intc_res;
 	bus_space_tag_t		intc_bst;
 	bus_space_handle_t	intc_bsh;
+#ifdef ARM_INTRNG
+	struct resource *	intc_irq_res;
+	void *			intc_irq_hdl;
+	struct bcm_intc_irqsrc	intc_isrcs[BCM_INTC_NIRQS];
+#endif
 };
 
 static struct bcm_intc_softc *bcm_intc_sc = NULL;
@@ -94,6 +156,192 @@ static struct bcm_intc_softc *bcm_intc_s
 #define	intc_write_4(_sc, reg, val)		\
     bus_space_write_4((_sc)->intc_bst, (_sc)->intc_bsh, (reg), (val))
 
+#ifdef ARM_INTRNG
+static inline void
+bcm_intc_isrc_mask(struct bcm_intc_softc *sc, struct bcm_intc_irqsrc *bii)
+{
+
+	intc_write_4(sc, bii->bii_disable_reg,  bii->bii_mask);
+}
+
+static inline void
+bcm_intc_isrc_unmask(struct bcm_intc_softc *sc, struct bcm_intc_irqsrc *bii)
+{
+
+	intc_write_4(sc, bii->bii_enable_reg,  bii->bii_mask);
+}
+
+static inline int
+bcm2835_intc_active_intr(struct bcm_intc_softc *sc)
+{
+	uint32_t pending, pending_gpu;
+
+	pending = intc_read_4(sc, INTC_PENDING_BASIC) & INTC_PENDING_BASIC_MASK;
+	if (pending == 0)
+		return (-1);
+	if (pending & INTC_PENDING_BASIC_ARM)
+		return (ffs(pending) - 1);
+	if (pending & INTC_PENDING_BASIC_GPU1_MASK) {
+		if (pending & INTC_PENDING_BASIC_GPU1_7)
+			return (BANK1_START + 7);
+		if (pending & INTC_PENDING_BASIC_GPU1_9)
+			return (BANK1_START + 9);
+		if (pending & INTC_PENDING_BASIC_GPU1_10)
+			return (BANK1_START + 10);
+		if (pending & INTC_PENDING_BASIC_GPU1_18)
+			return (BANK1_START + 18);
+		if (pending & INTC_PENDING_BASIC_GPU1_19)
+			return (BANK1_START + 19);
+	}
+	if (pending & INTC_PENDING_BASIC_GPU2_MASK) {
+		if (pending & INTC_PENDING_BASIC_GPU2_21)
+			return (BANK2_START + 21);
+		if (pending & INTC_PENDING_BASIC_GPU2_22)
+			return (BANK2_START + 22);
+		if (pending & INTC_PENDING_BASIC_GPU2_23)
+			return (BANK2_START + 23);
+		if (pending & INTC_PENDING_BASIC_GPU2_24)
+			return (BANK2_START + 24);
+		if (pending & INTC_PENDING_BASIC_GPU2_25)
+			return (BANK2_START + 25);
+		if (pending & INTC_PENDING_BASIC_GPU2_30)
+			return (BANK2_START + 30);
+	}
+	if (pending & INTC_PENDING_BASIC_GPU1_PEND) {
+		pending_gpu = intc_read_4(sc, INTC_PENDING_BANK1);
+		pending_gpu &= INTC_PENDING_BANK1_MASK;
+		if (pending_gpu != 0)
+			return (BANK1_START + ffs(pending_gpu) - 1);
+	}
+	if (pending & INTC_PENDING_BASIC_GPU2_PEND) {
+		pending_gpu = intc_read_4(sc, INTC_PENDING_BANK2);
+		pending_gpu &= INTC_PENDING_BANK2_MASK;
+		if (pending_gpu != 0)
+			return (BANK2_START + ffs(pending_gpu) - 1);
+	}
+	return (-1);	/* It shouldn't end here, but it's hardware. */
+}
+
+static int
+bcm2835_intc_intr(void *arg)
+{
+	int irq, num;
+	struct bcm_intc_softc *sc = arg;
+
+	for (num = 0; ; num++) {
+		irq = bcm2835_intc_active_intr(sc);
+		if (irq == -1)
+			break;
+		if (intr_isrc_dispatch(&sc->intc_isrcs[irq].bii_isrc,
+		    curthread->td_intr_frame) != 0) {
+			bcm_intc_isrc_mask(sc, &sc->intc_isrcs[irq]);
+			device_printf(sc->sc_dev, "Stray irq %u disabled\n",
+			    irq);
+		}
+		arm_irq_memory_barrier(0); /* XXX */
+	}
+	if (num == 0)
+		device_printf(sc->sc_dev, "Spurious interrupt detected\n");
+
+	return (FILTER_HANDLED);
+}
+
+static void
+bcm_intc_enable_intr(device_t dev, struct intr_irqsrc *isrc)
+{
+	struct bcm_intc_irqsrc *bii = (struct bcm_intc_irqsrc *)isrc;
+
+	arm_irq_memory_barrier(bii->bii_irq);
+	bcm_intc_isrc_unmask(device_get_softc(dev), bii);
+}
+
+static void
+bcm_intc_disable_intr(device_t dev, struct intr_irqsrc *isrc)
+{
+
+	bcm_intc_isrc_mask(device_get_softc(dev),
+	    (struct bcm_intc_irqsrc *)isrc);
+}
+
+static int
+bcm_intc_map_intr(device_t dev, struct intr_map_data *data,
+    struct intr_irqsrc **isrcp)
+{
+	u_int irq;
+	struct bcm_intc_softc *sc;
+
+	if (data->type != INTR_MAP_DATA_FDT)
+		return (ENOTSUP);
+	if (data->fdt.ncells == 1)
+		irq = data->fdt.cells[0];
+	else if (data->fdt.ncells == 2)
+		irq = data->fdt.cells[0] * 32 + data->fdt.cells[1];
+	else
+		return (EINVAL);
+
+	if (irq >= BCM_INTC_NIRQS)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+	*isrcp = &sc->intc_isrcs[irq].bii_isrc;
+	return (0);
+}
+
+static void
+bcm_intc_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
+{
+
+	bcm_intc_disable_intr(dev, isrc);
+}
+
+static void
+bcm_intc_post_ithread(device_t dev, struct intr_irqsrc *isrc)
+{
+
+	bcm_intc_enable_intr(dev, isrc);
+}
+
+static void
+bcm_intc_post_filter(device_t dev, struct intr_irqsrc *isrc)
+{
+}
+
+static int
+bcm_intc_pic_register(struct bcm_intc_softc *sc, intptr_t xref)
+{
+	struct bcm_intc_irqsrc *bii;
+	int error;
+	uint32_t irq;
+	const char *name;
+
+	name = device_get_nameunit(sc->sc_dev);
+	for (irq = 0; irq < BCM_INTC_NIRQS; irq++) {
+		bii = &sc->intc_isrcs[irq];
+		bii->bii_irq = irq;
+		if (IS_IRQ_BASIC(irq)) {
+			bii->bii_disable_reg = INTC_DISABLE_BASIC;
+			bii->bii_enable_reg = INTC_ENABLE_BASIC;
+			bii->bii_mask = 1 << irq;
+		} else if (IS_IRQ_BANK1(irq)) {
+			bii->bii_disable_reg = INTC_DISABLE_BANK1;
+			bii->bii_enable_reg = INTC_ENABLE_BANK1;
+			bii->bii_mask = 1 << IRQ_BANK1(irq);
+		} else if (IS_IRQ_BANK2(irq)) {
+			bii->bii_disable_reg = INTC_DISABLE_BANK2;
+			bii->bii_enable_reg = INTC_ENABLE_BANK2;
+			bii->bii_mask = 1 << IRQ_BANK2(irq);
+		} else
+			return (ENXIO);
+
+		error = intr_isrc_register(&bii->bii_isrc, sc->sc_dev, 0,
+		    "%s,%u", name, irq);
+		if (error != 0)
+			return (error);
+	}
+	return (intr_pic_register(sc->sc_dev, xref));
+}
+#endif
+
 static int
 bcm_intc_probe(device_t dev)
 {
@@ -112,7 +360,9 @@ bcm_intc_attach(device_t dev)
 {
 	struct		bcm_intc_softc *sc = device_get_softc(dev);
 	int		rid = 0;
-
+#ifdef ARM_INTRNG
+	intptr_t	xref;
+#endif
 	sc->sc_dev = dev;
 
 	if (bcm_intc_sc)
@@ -124,6 +374,32 @@ bcm_intc_attach(device_t dev)
 		return (ENXIO);
 	}
 
+#ifdef ARM_INTRNG
+	xref = OF_xref_from_node(ofw_bus_get_node(dev));
+	if (bcm_intc_pic_register(sc, xref) != 0) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->intc_res);
+		device_printf(dev, "could not register PIC\n");
+		return (ENXIO);
+	}
+
+	rid = 0;
+	sc->intc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->intc_irq_res == NULL) {
+		if (intr_pic_claim_root(dev, xref, bcm2835_intc_intr, sc, 0) != 0) {
+			/* XXX clean up */
+			device_printf(dev, "could not set PIC as a root\n");
+			return (ENXIO);
+		}
+	} else {
+		if (bus_setup_intr(dev, sc->intc_irq_res, INTR_TYPE_CLK,
+		    bcm2835_intc_intr, NULL, sc, &sc->intc_irq_hdl)) {
+			/* XXX clean up */
+			device_printf(dev, "could not setup irq handler\n");
+			return (ENXIO);
+		}
+	}
+#endif
 	sc->intc_bst = rman_get_bustag(sc->intc_res);
 	sc->intc_bsh = rman_get_bushandle(sc->intc_res);
 
@@ -135,6 +411,16 @@ bcm_intc_attach(device_t dev)
 static device_method_t bcm_intc_methods[] = {
 	DEVMETHOD(device_probe,		bcm_intc_probe),
 	DEVMETHOD(device_attach,	bcm_intc_attach),
+
+#ifdef ARM_INTRNG
+	DEVMETHOD(pic_disable_intr,	bcm_intc_disable_intr),
+	DEVMETHOD(pic_enable_intr,	bcm_intc_enable_intr),
+	DEVMETHOD(pic_map_intr,		bcm_intc_map_intr),
+	DEVMETHOD(pic_post_filter,	bcm_intc_post_filter),
+	DEVMETHOD(pic_post_ithread,	bcm_intc_post_ithread),
+	DEVMETHOD(pic_pre_ithread,	bcm_intc_pre_ithread),
+#endif
+
 	{ 0, 0 }
 };
 
@@ -148,6 +434,7 @@ static devclass_t bcm_intc_devclass;
 
 DRIVER_MODULE(intc, simplebus, bcm_intc_driver, bcm_intc_devclass, 0, 0);
 
+#ifndef ARM_INTRNG
 int
 arm_get_next_irq(int last_irq)
 {
@@ -247,3 +534,4 @@ intr_pic_init_secondary(void)
 {
 }
 #endif
+#endif

Modified: projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2836.c
==============================================================================
--- projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2836.c	Wed Apr  6 01:22:20 2016	(r297604)
+++ projects/release-pkg/sys/arm/broadcom/bcm2835/bcm2836.c	Wed Apr  6 01:44:21 2016	(r297605)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2015 Andrew Turner.
+ * Copyright 2016 Svatopluk Kraus
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,19 +29,33 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_platform.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
+#include <sys/cpuset.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
+#include <sys/proc.h>
 #include <sys/rman.h>
+#ifdef SMP
+#include <sys/smp.h>
+#endif
 
 #include <machine/bus.h>
+#include <machine/intr.h>
 #include <machine/resource.h>
+#ifdef SMP
+#include <machine/smp.h>
+#endif
 
 #include <dev/ofw/ofw_bus_subr.h>
 #include <dev/ofw/ofw_bus.h>
 
+#ifdef ARM_INTRNG
+#include "pic_if.h"
+#else
 #include <arm/broadcom/bcm2835/bcm2836.h>
 
 #define	ARM_LOCAL_BASE	0x40000000
@@ -55,7 +70,703 @@ __FBSDID("$FreeBSD$");
 #define	 INT_PENDING_MASK		0x011f
 #define	MAILBOX0_IRQ			4
 #define	MAILBOX0_IRQEN			(1 << 0)
+#endif
+
+#ifdef ARM_INTRNG
+#define	BCM_LINTC_CONTROL_REG		0x00
+#define	BCM_LINTC_PRESCALER_REG		0x08

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604060144.u361iLKD034200>