Rework BCM283x gpio interrupt controller for INTRNG. It's used on RPI-B
and RPI2 where INTRNG is already enabled by default. Differential Revision: https://reviews.freebsd.org/D5810
This commit is contained in:
parent
120b6fc9b2
commit
89de2fb6d4
@ -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_gpio_softc *sc)
|
||||
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,
|
||||
®) != 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, device_t child, struct resource *ires,
|
||||
|
||||
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),
|
||||
|
||||
|
@ -144,7 +144,7 @@
|
||||
#gpio-cells = <2>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_reserved>;
|
||||
|
@ -137,7 +137,7 @@
|
||||
#gpio-cells = <2>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_reserved>;
|
||||
|
Loading…
Reference in New Issue
Block a user