summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-05-14 18:54:34 +0000
committerian <ian@FreeBSD.org>2014-05-14 18:54:34 +0000
commit21fbbde45943109155a62d78963119afc7f3f290 (patch)
treedeee42515173cf5d1de657da766da3d27cce6bb8 /sys/arm
parent9e6ff9cd8c9d75c84e35d396dd9595b3ec4b947f (diff)
downloadFreeBSD-src-21fbbde45943109155a62d78963119afc7f3f290.zip
FreeBSD-src-21fbbde45943109155a62d78963119afc7f3f290.tar.gz
MFC r260281, r260282, r260283, r260285
Implement OFW_BUS_MAP_INTR() in terms of the FDT PIC table Reimplement fdt_intr_to_rl() in terms of OFW_BUS_MAP_INTR() and OFW_BUS_CONFIG_INTR(). Use bus_space_map() rather than pmap_mapdev() in nexus_activate_resource(), when running on FDT systems. Unmap memory in nexus_deactivate_resource(). Remove fdt_pic_table code from MIPS, PowerPC, and x86, as it is no longer used by anything.
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/nexus.c95
1 files changed, 81 insertions, 14 deletions
diff --git a/sys/arm/arm/nexus.c b/sys/arm/arm/nexus.c
index 94f3c37..5200303 100644
--- a/sys/arm/arm/nexus.c
+++ b/sys/arm/arm/nexus.c
@@ -64,7 +64,9 @@ __FBSDID("$FreeBSD$");
#ifdef FDT
#include <dev/ofw/ofw_nexus.h>
+#include <dev/fdt/fdt_common.h>
#include <machine/fdt.h>
+#include "ofw_bus_if.h"
#else
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
@@ -94,6 +96,11 @@ static int nexus_setup_intr(device_t dev, device_t child, struct resource *res,
int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep);
static int nexus_teardown_intr(device_t, device_t, struct resource *, void *);
+#ifdef FDT
+static int nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent,
+ int irq);
+#endif
+
static device_method_t nexus_methods[] = {
#ifndef FDT
/* Device interface */
@@ -109,6 +116,9 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
+#ifdef FDT
+ DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
+#endif
{ 0, 0 }
};
@@ -268,35 +278,92 @@ static int
nexus_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
+ int err;
+ bus_addr_t paddr;
+ bus_size_t psize;
+ bus_space_handle_t vaddr;
+
+ if ((err = rman_activate_resource(r)) != 0)
+ return (err);
+
/*
* If this is a memory resource, map it into the kernel.
*/
if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
- caddr_t vaddr = 0;
- u_int32_t paddr;
- u_int32_t psize;
- u_int32_t poffs;
-
- paddr = rman_get_start(r);
- psize = rman_get_size(r);
- poffs = paddr - trunc_page(paddr);
- vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
- rman_set_virtual(r, vaddr);
+ paddr = (bus_addr_t)rman_get_start(r);
+ psize = (bus_size_t)rman_get_size(r);
#ifdef FDT
+ err = bus_space_map(fdtbus_bs_tag, paddr, psize, 0, &vaddr);
+ if (err != 0) {
+ rman_deactivate_resource(r);
+ return (err);
+ }
rman_set_bustag(r, fdtbus_bs_tag);
#else
+ vaddr = (bus_space_handle_t)pmap_mapdev((vm_offset_t)paddr,
+ (vm_size_t)psize);
+ if (vaddr == 0) {
+ rman_deactivate_resource(r);
+ return (ENOMEM);
+ }
rman_set_bustag(r, (void *)1);
#endif
- rman_set_bushandle(r, (bus_space_handle_t) vaddr);
+ rman_set_virtual(r, (void *)vaddr);
+ rman_set_bushandle(r, vaddr);
}
- return (rman_activate_resource(r));
+ return (0);
}
static int
nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *res)
+ struct resource *r)
{
+ bus_size_t psize;
+ bus_space_handle_t vaddr;
+
+ psize = (bus_size_t)rman_get_size(r);
+ vaddr = rman_get_bushandle(r);
+
+ if (vaddr != 0) {
+#ifdef FDT
+ bus_space_unmap(fdtbus_bs_tag, vaddr, psize);
+#else
+ pmap_unmapdev((vm_offset_t)vaddr, (vm_size_t)psize);
+#endif
+ rman_set_virtual(r, NULL);
+ rman_set_bushandle(r, 0);
+ }
- return (rman_deactivate_resource(res));
+ return (rman_deactivate_resource(r));
}
+#ifdef FDT
+static int
+nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int irq)
+{
+ pcell_t intr[2];
+ fdt_pic_decode_t intr_decode;
+ phandle_t intr_offset;
+ int i, rv, interrupt, trig, pol;
+
+ intr_offset = OF_xref_phandle(iparent);
+ intr[0] = cpu_to_fdt32(irq);
+
+ for (i = 0; fdt_pic_table[i] != NULL; i++) {
+ intr_decode = fdt_pic_table[i];
+ rv = intr_decode(intr_offset, intr, &interrupt, &trig, &pol);
+
+ if (rv == 0) {
+ /* This was recognized as our PIC and decoded. */
+ interrupt = FDT_MAP_IRQ(intr_parent, interrupt);
+ return (interrupt);
+ }
+ }
+
+ /* Not in table, so guess */
+ interrupt = FDT_MAP_IRQ(intr_parent, fdt32_to_cpu(*intr));
+
+ return (interrupt);
+}
+#endif
+
OpenPOWER on IntegriCloud