Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144609901
D36261.1775748783.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D36261.1775748783.diff
View Options
diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c
--- a/sys/arm64/rockchip/rk_gpio.c
+++ b/sys/arm64/rockchip/rk_gpio.c
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.org>
+ * Copyright (c) 2021 Soren Schmidt <sos@deepcore.dk>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,6 +36,7 @@
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/proc.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -50,28 +52,32 @@
#include <dev/extres/clk/clk.h>
#include "gpio_if.h"
+#include "pic_if.h"
#include "fdt_pinctrl_if.h"
-#define RK_GPIO_SWPORTA_DR 0x00 /* Data register */
-#define RK_GPIO_SWPORTA_DDR 0x04 /* Data direction register */
-
-#define RK_GPIO_INTEN 0x30 /* Interrupt enable register */
-#define RK_GPIO_INTMASK 0x34 /* Interrupt mask register */
-#define RK_GPIO_INTTYPE_LEVEL 0x38 /* Interrupt level register */
-#define RK_GPIO_INT_POLARITY 0x3C /* Interrupt polarity register */
-#define RK_GPIO_INT_STATUS 0x40 /* Interrupt status register */
-#define RK_GPIO_INT_RAWSTATUS 0x44 /* Raw Interrupt status register */
-
-#define RK_GPIO_DEBOUNCE 0x48 /* Debounce enable register */
-
-#define RK_GPIO_PORTA_EOI 0x4C /* Clear interrupt register */
-#define RK_GPIO_EXT_PORTA 0x50 /* External port register */
+enum gpio_regs {
+ RK_GPIO_SWPORTA_DR = 1, /* Data register */
+ RK_GPIO_SWPORTA_DDR, /* Data direction register */
+ RK_GPIO_INTEN, /* Interrupt enable register */
+ RK_GPIO_INTMASK, /* Interrupt mask register */
+ RK_GPIO_INTTYPE_LEVEL, /* Interrupt level register */
+ RK_GPIO_INTTYPE_BOTH, /* Both rise and falling edge */
+ RK_GPIO_INT_POLARITY, /* Interrupt polarity register */
+ RK_GPIO_INT_STATUS, /* Interrupt status register */
+ RK_GPIO_INT_RAWSTATUS, /* Raw Interrupt status register */
+ RK_GPIO_DEBOUNCE, /* Debounce enable register */
+ RK_GPIO_PORTA_EOI, /* Clear interrupt register */
+ RK_GPIO_EXT_PORTA, /* External port register */
+ RK_GPIO_REGNUM
+};
#define RK_GPIO_LS_SYNC 0x60 /* Level sensitive syncronization enable register */
#define RK_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
- GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
+ GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_INTR_EDGE_BOTH | \
+ GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING | \
+ GPIO_INTR_LEVEL_HIGH | GPIO_INTR_LEVEL_LOW)
#define GPIO_FLAGS_PINCTRL GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN
#define RK_GPIO_MAX_PINS 32
@@ -81,6 +87,12 @@
uint32_t flags;
};
+struct rk_pin_irqsrc {
+ struct intr_irqsrc isrc;
+ uint32_t irq;
+ uint32_t mode;
+};
+
struct rk_gpio_softc {
device_t sc_dev;
device_t sc_busdev;
@@ -90,9 +102,11 @@
bus_space_handle_t sc_bsh;
clk_t clk;
device_t pinctrl;
- uint32_t swporta;
- uint32_t swporta_ddr;
+ uint32_t version;
struct pin_cached pin_cached[RK_GPIO_MAX_PINS];
+ void *ihandle;
+ uint8_t regs[RK_GPIO_REGNUM];
+ struct rk_pin_irqsrc isrcs[RK_GPIO_MAX_PINS];
};
static struct ofw_compat_data compat_data[] = {
@@ -106,6 +120,11 @@
{ -1, 0 }
};
+#define RK_GPIO_VERSION 0x78
+#define RK_GPIO_TYPE_V1 0x00000000
+#define RK_GPIO_TYPE_V2 0x01000c2b
+#define RK_GPIO_ISRC(sc, irq) (&(sc->isrcs[irq].isrc))
+
static int rk_gpio_detach(device_t dev);
#define RK_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
@@ -117,6 +136,113 @@
#define RK_GPIO_READ(_sc, _off) \
bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
+static int
+rk_gpio_read_bit(struct rk_gpio_softc *sc, int reg, int bit)
+{
+ int offset = sc->regs[reg];
+ uint32_t value;
+
+ RK_GPIO_LOCK(sc);
+ if (sc->version == RK_GPIO_TYPE_V1) {
+ value = RK_GPIO_READ(sc, offset);
+ value >>= bit;
+ } else {
+ value = RK_GPIO_READ(sc, bit > 15 ? offset + 4 : offset);
+ value >>= (bit % 16);
+ }
+ RK_GPIO_UNLOCK(sc);
+ return (value & 1);
+}
+
+static void
+rk_gpio_write_bit(struct rk_gpio_softc *sc, int reg, int bit, int data)
+{
+ int offset = sc->regs[reg];
+ uint32_t value;
+
+ RK_GPIO_LOCK(sc);
+ if (sc->version == RK_GPIO_TYPE_V1) {
+ value = RK_GPIO_READ(sc, offset);
+ if (data)
+ value |= (1 << bit);
+ else
+ value &= ~(1 << bit);
+ RK_GPIO_WRITE(sc, offset, value);
+ } else {
+ if (data)
+ value = (1 << (bit % 16));
+ else
+ value = 0;
+ value |= (1 << ((bit % 16) + 16));
+ RK_GPIO_WRITE(sc, bit > 15 ? offset + 4 : offset, value);
+ }
+ RK_GPIO_UNLOCK(sc);
+}
+
+static uint32_t
+rk_gpio_read_4(struct rk_gpio_softc *sc, int reg)
+{
+ int offset = sc->regs[reg];
+ uint32_t value;
+
+ RK_GPIO_LOCK(sc);
+ if (sc->version == RK_GPIO_TYPE_V1)
+ value = RK_GPIO_READ(sc, offset);
+ else
+ value = (RK_GPIO_READ(sc, offset) & 0xffff) |
+ (RK_GPIO_READ(sc, offset + 4) << 16);
+ RK_GPIO_UNLOCK(sc);
+ return (value);
+}
+
+static void
+rk_gpio_write_4(struct rk_gpio_softc *sc, int reg, uint32_t value)
+{
+ int offset = sc->regs[reg];
+
+ RK_GPIO_LOCK(sc);
+ if (sc->version == RK_GPIO_TYPE_V1)
+ RK_GPIO_WRITE(sc, offset, value);
+ else {
+ RK_GPIO_WRITE(sc, offset, (value & 0xffff) | 0xffff0000);
+ RK_GPIO_WRITE(sc, offset + 4, (value >> 16) | 0xffff0000);
+ }
+ RK_GPIO_UNLOCK(sc);
+}
+
+static int
+rk_gpio_intr(void *arg)
+{
+ struct rk_gpio_softc *sc = (struct rk_gpio_softc *)arg;;
+ struct trapframe *tf = curthread->td_intr_frame;
+ uint32_t status;
+
+ status = rk_gpio_read_4(sc, RK_GPIO_INT_STATUS);
+ rk_gpio_write_4(sc, RK_GPIO_PORTA_EOI, status);
+ while (status) {
+ int pin = ffs(status) - 1;
+
+ status &= ~(1 << pin);
+ if (intr_isrc_dispatch(RK_GPIO_ISRC(sc, pin), tf)) {
+ device_printf(sc->sc_dev, "Interrupt pin=%d unhandled\n",
+ pin);
+ continue;
+ }
+
+ if ((sc->version == RK_GPIO_TYPE_V1) &&
+ (sc->isrcs[pin].mode & GPIO_INTR_EDGE_BOTH)) {
+ if (rk_gpio_read_bit(sc, RK_GPIO_EXT_PORTA, pin))
+ rk_gpio_write_bit(sc, RK_GPIO_INT_POLARITY,
+ (1 << pin), 0);
+ else
+ rk_gpio_write_bit(sc, RK_GPIO_INT_POLARITY,
+ (1 << pin), 1);
+ }
+ }
+ return (FILTER_HANDLED);
+}
+
+
static int
rk_gpio_probe(device_t dev)
{
@@ -171,6 +297,65 @@
return (ENXIO);
}
+ if ((err = bus_setup_intr(dev, sc->sc_res[1],
+ INTR_TYPE_MISC | INTR_MPSAFE, rk_gpio_intr, NULL,
+ sc, &sc->ihandle))) {
+ device_printf(dev, "Can not setup IRQ\n");
+ rk_gpio_detach(dev);
+ return (ENXIO);
+ }
+
+ switch ((sc->version = RK_GPIO_READ(sc, RK_GPIO_VERSION))) {
+ case RK_GPIO_TYPE_V1:
+ sc->regs[RK_GPIO_SWPORTA_DR] = 0x00;
+ sc->regs[RK_GPIO_SWPORTA_DDR] = 0x04;
+ sc->regs[RK_GPIO_INTEN] = 0x30;
+ sc->regs[RK_GPIO_INTMASK] = 0x34;
+ sc->regs[RK_GPIO_INTTYPE_LEVEL] = 0x38;
+ sc->regs[RK_GPIO_INT_POLARITY] = 0x3c;
+ sc->regs[RK_GPIO_INT_STATUS] = 0x40;
+ sc->regs[RK_GPIO_INT_RAWSTATUS] = 0x44;
+ sc->regs[RK_GPIO_DEBOUNCE] = 0x48;
+ sc->regs[RK_GPIO_PORTA_EOI] = 0x4c;
+ sc->regs[RK_GPIO_EXT_PORTA] = 0x50;
+ break;
+ case RK_GPIO_TYPE_V2:
+ sc->regs[RK_GPIO_SWPORTA_DR] = 0x00;
+ sc->regs[RK_GPIO_SWPORTA_DDR] = 0x08;
+ sc->regs[RK_GPIO_INTEN] = 0x10;
+ sc->regs[RK_GPIO_INTMASK] = 0x18;
+ sc->regs[RK_GPIO_INTTYPE_LEVEL] = 0x20;
+ sc->regs[RK_GPIO_INTTYPE_BOTH] = 0x30;
+ sc->regs[RK_GPIO_INT_POLARITY] = 0x28;
+ sc->regs[RK_GPIO_INT_STATUS] = 0x50;
+ sc->regs[RK_GPIO_INT_RAWSTATUS] = 0x58;
+ sc->regs[RK_GPIO_DEBOUNCE] = 0x38;
+ sc->regs[RK_GPIO_PORTA_EOI] = 0x60;
+ sc->regs[RK_GPIO_EXT_PORTA] = 0x70;
+ break;
+ default:
+ device_printf(dev, "Unknown gpio version %08x\n", sc->version);
+ rk_gpio_detach(dev);
+ return (ENXIO);
+ }
+
+ for (i = 0; i < RK_GPIO_MAX_PINS; i++) {
+ sc->isrcs[i].irq = i;
+ sc->isrcs[i].mode = GPIO_INTR_CONFORM;
+ if ((err = intr_isrc_register(RK_GPIO_ISRC(sc, i),
+ dev, 0, "%s", device_get_nameunit(dev)))) {
+ device_printf(dev, "Can not register isrc %d\n", err);
+ rk_gpio_detach(dev);
+ return (ENXIO);
+ }
+ }
+
+ if (intr_pic_register(dev, OF_xref_from_node(node)) == NULL) {
+ device_printf(dev, "Can not register pic\n");
+ rk_gpio_detach(dev);
+ return (ENXIO);
+ }
+
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL) {
rk_gpio_detach(dev);
@@ -181,11 +366,6 @@
for (i = 0; i < RK_GPIO_MAX_PINS; i++)
sc->pin_cached[i].is_gpio = 2;
- RK_GPIO_LOCK(sc);
- sc->swporta = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR);
- sc->swporta_ddr = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR);
- RK_GPIO_UNLOCK(sc);
-
return (0);
}
@@ -267,7 +447,7 @@
return (rv);
sc->pin_cached[pin].flags = *flags;
- if (sc->swporta_ddr & (1 << pin))
+ if (rk_gpio_read_bit(sc, RK_GPIO_SWPORTA_DDR, pin))
*flags |= GPIO_PIN_OUTPUT;
else
*flags |= GPIO_PIN_INPUT;
@@ -279,6 +459,9 @@
rk_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
{
+ if (pin >= RK_GPIO_MAX_PINS)
+ return EINVAL;
+
*caps = RK_GPIO_DEFAULT_CAPS;
return (0);
}
@@ -291,6 +474,9 @@
sc = device_get_softc(dev);
+ if (pin >= RK_GPIO_MAX_PINS)
+ return (EINVAL);
+
if (__predict_false(sc->pin_cached[pin].is_gpio != 1)) {
rv = FDT_PINCTRL_IS_GPIO(sc->pinctrl, dev, pin, (bool *)&sc->pin_cached[pin].is_gpio);
if (rv != 0)
@@ -306,14 +492,8 @@
return (rv);
}
- RK_GPIO_LOCK(sc);
- if (flags & GPIO_PIN_INPUT)
- sc->swporta_ddr &= ~(1 << pin);
- else if (flags & GPIO_PIN_OUTPUT)
- sc->swporta_ddr |= (1 << pin);
-
- RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DDR, sc->swporta_ddr);
- RK_GPIO_UNLOCK(sc);
+ rk_gpio_write_bit(sc, RK_GPIO_SWPORTA_DDR, pin,
+ (flags & GPIO_PIN_OUTPUT ? 1 : 0));
return (0);
}
@@ -322,16 +502,13 @@
rk_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
struct rk_gpio_softc *sc;
- uint32_t reg;
sc = device_get_softc(dev);
- RK_GPIO_LOCK(sc);
- reg = RK_GPIO_READ(sc, RK_GPIO_EXT_PORTA);
- RK_GPIO_UNLOCK(sc);
-
- *val = reg & (1 << pin) ? 1 : 0;
+ if (pin >= RK_GPIO_MAX_PINS)
+ return (EINVAL);
+ *val = rk_gpio_read_bit(sc, RK_GPIO_EXT_PORTA, pin);
return (0);
}
@@ -342,14 +519,10 @@
sc = device_get_softc(dev);
- RK_GPIO_LOCK(sc);
- if (value)
- sc->swporta |= (1 << pin);
- else
- sc->swporta &= ~(1 << pin);
- RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, sc->swporta);
- RK_GPIO_UNLOCK(sc);
+ if (pin >= RK_GPIO_MAX_PINS)
+ return (EINVAL);
+ rk_gpio_write_bit(sc, RK_GPIO_SWPORTA_DR, pin, value);
return (0);
}
@@ -357,16 +530,15 @@
rk_gpio_pin_toggle(device_t dev, uint32_t pin)
{
struct rk_gpio_softc *sc;
+ int value;
sc = device_get_softc(dev);
- RK_GPIO_LOCK(sc);
- if (sc->swporta & (1 << pin))
- sc->swporta &= ~(1 << pin);
- else
- sc->swporta |= (1 << pin);
- RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, sc->swporta);
- RK_GPIO_UNLOCK(sc);
+ if (pin >= RK_GPIO_MAX_PINS)
+ return (EINVAL);
+
+ value = rk_gpio_read_bit(sc, RK_GPIO_EXT_PORTA, pin);
+ rk_gpio_write_bit(sc, RK_GPIO_SWPORTA_DR, pin, !value);
return (0);
}
@@ -380,17 +552,14 @@
sc = device_get_softc(dev);
- RK_GPIO_LOCK(sc);
- reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR);
+ reg = rk_gpio_read_4(sc, RK_GPIO_SWPORTA_DR);
if (orig_pins)
*orig_pins = reg;
- sc->swporta = reg;
if ((clear_pins | change_pins) != 0) {
reg = (reg & ~clear_pins) ^ change_pins;
- RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, reg);
+ rk_gpio_write_4(sc, RK_GPIO_SWPORTA_DR, reg);
}
- RK_GPIO_UNLOCK(sc);
return (0);
}
@@ -420,13 +589,10 @@
}
}
- RK_GPIO_LOCK(sc);
- reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR);
+ reg = rk_gpio_read_4(sc, RK_GPIO_SWPORTA_DDR);
reg &= ~mask;
reg |= set;
- RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DDR, reg);
- sc->swporta_ddr = reg;
- RK_GPIO_UNLOCK(sc);
+ rk_gpio_write_4(sc, RK_GPIO_SWPORTA_DDR, reg);
return (0);
}
@@ -450,6 +616,120 @@
return (ofw_bus_get_node(bus));
}
+static int
+rk_pic_map_intr(device_t dev, struct intr_map_data *data,
+ struct intr_irqsrc **isrcp)
+{
+ struct rk_gpio_softc *sc = device_get_softc(dev);
+ struct intr_map_data_gpio *gdata;
+ uint32_t irq;
+
+ if (data->type != INTR_MAP_DATA_GPIO) {
+ device_printf(dev, "Wrong type\n");
+ return (ENOTSUP);
+ }
+ gdata = (struct intr_map_data_gpio *)data;
+ irq = gdata->gpio_pin_num;
+ if (irq >= RK_GPIO_MAX_PINS) {
+ device_printf(dev, "Invalid interrupt %u\n", irq);
+ return (EINVAL);
+ }
+ *isrcp = RK_GPIO_ISRC(sc, irq);
+ return (0);
+}
+
+static int
+rk_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
+ struct resource *res, struct intr_map_data *data)
+{
+ struct rk_gpio_softc *sc = device_get_softc(dev);
+ struct rk_pin_irqsrc *rkisrc = (struct rk_pin_irqsrc *)isrc;
+ struct intr_map_data_gpio *gdata;
+ uint32_t mode;
+ uint8_t pin;
+
+ if (!data) {
+ device_printf(dev, "No map data\n");
+ return (ENOTSUP);
+ }
+ gdata = (struct intr_map_data_gpio *)data;
+ mode = gdata->gpio_intr_mode;
+ pin = gdata->gpio_pin_num;
+
+ if (rkisrc->irq != gdata->gpio_pin_num) {
+ device_printf(dev, "Interrupts don't match\n");
+ return (EINVAL);
+ }
+
+ if (isrc->isrc_handlers != 0) {
+ device_printf(dev, "Handler already attached\n");
+ return (rkisrc->mode == mode ? 0 : EINVAL);
+ }
+ rkisrc->mode = mode;
+
+ switch (mode & GPIO_INTR_MASK) {
+ case GPIO_INTR_EDGE_RISING:
+ rk_gpio_write_bit(sc, RK_GPIO_SWPORTA_DDR, pin, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_INTTYPE_LEVEL, pin, 1);
+ rk_gpio_write_bit(sc, RK_GPIO_INT_POLARITY, pin, 1);
+ break;
+ case GPIO_INTR_EDGE_FALLING:
+ rk_gpio_write_bit(sc, RK_GPIO_SWPORTA_DDR, pin, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_INTTYPE_LEVEL, pin, 1);
+ rk_gpio_write_bit(sc, RK_GPIO_INT_POLARITY, pin, 0);
+ break;
+ case GPIO_INTR_EDGE_BOTH:
+ rk_gpio_write_bit(sc, RK_GPIO_SWPORTA_DDR, pin, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_INTTYPE_LEVEL, pin, 1);
+ if (sc->version == RK_GPIO_TYPE_V1) {
+ if (rk_gpio_read_bit(sc, RK_GPIO_EXT_PORTA, pin))
+ rk_gpio_write_bit(sc, RK_GPIO_INT_POLARITY,
+ pin, 0);
+ else
+ rk_gpio_write_bit(sc, RK_GPIO_INT_POLARITY,
+ pin, 1);
+ } else
+ rk_gpio_write_bit(sc, RK_GPIO_INTTYPE_BOTH, pin, 1);
+ break;
+ case GPIO_INTR_LEVEL_HIGH:
+ rk_gpio_write_bit(sc, RK_GPIO_SWPORTA_DDR, pin, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_INTTYPE_LEVEL, pin, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_INT_POLARITY, pin, 1);
+ break;
+ case GPIO_INTR_LEVEL_LOW:
+ rk_gpio_write_bit(sc, RK_GPIO_SWPORTA_DDR, pin, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_INTTYPE_LEVEL, pin, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_INT_POLARITY, pin, 0);
+ break;
+ default:
+ rk_gpio_write_bit(sc, RK_GPIO_INTMASK, pin, 1);
+ rk_gpio_write_bit(sc, RK_GPIO_INTEN, pin, 0);
+ return (EINVAL);
+ }
+ rk_gpio_write_bit(sc, RK_GPIO_DEBOUNCE, pin, 1);
+ rk_gpio_write_bit(sc, RK_GPIO_INTMASK, pin, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_INTEN, pin, 1);
+ return (0);
+}
+
+static int
+rk_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
+ struct resource *res, struct intr_map_data *data)
+{
+ struct rk_gpio_softc *sc = device_get_softc(dev);
+ struct rk_pin_irqsrc *irqsrc;
+
+ irqsrc = (struct rk_pin_irqsrc *)isrc;
+
+ if (isrc->isrc_handlers == 0) {
+ irqsrc->mode = GPIO_INTR_CONFORM;
+ rk_gpio_write_bit(sc, RK_GPIO_INTEN, irqsrc->irq, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_INTMASK, irqsrc->irq, 0);
+ rk_gpio_write_bit(sc, RK_GPIO_DEBOUNCE, irqsrc->irq, 0);
+ }
+ return (0);
+}
+
static device_method_t rk_gpio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, rk_gpio_probe),
@@ -470,6 +750,11 @@
DEVMETHOD(gpio_pin_config_32, rk_gpio_pin_config_32),
DEVMETHOD(gpio_map_gpios, rk_gpio_map_gpios),
+ /* Interrupt controller interface */
+ DEVMETHOD(pic_map_intr, rk_pic_map_intr),
+ DEVMETHOD(pic_setup_intr, rk_pic_setup_intr),
+ DEVMETHOD(pic_teardown_intr, rk_pic_teardown_intr),
+
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, rk_gpio_get_node),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 9, 3:33 PM (14 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28309167
Default Alt Text
D36261.1775748783.diff (15 KB)
Attached To
Mode
D36261: Add support for the RK356X SOC gpio controller
Attached
Detach File
Event Timeline
Log In to Comment