Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Apr 2011 14:39:55 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r220297 - in head/sys/mips: conf rt305x
Message-ID:  <201104031439.p33EdtH4030436@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sun Apr  3 14:39:55 2011
New Revision: 220297
URL: http://svn.freebsd.org/changeset/base/220297

Log:
  Import the initial CPU support for the MIPS RALink RT305x SoC.
  This is a MIPS4KC CPU with various embedded peripherals, including
  wireless and ethernet support.
  
  This commit includes the platform, UART, ethernet MAC and GPIO support.
  The interrupt-driven GPIO code is disabled for now pending GPIO changes
  from the submitter.
  
  Submitted by:	Aleksandr Rybalko <ray@dlink.ua>

Added:
  head/sys/mips/conf/RT305X   (contents, props changed)
  head/sys/mips/conf/RT305X.hints   (contents, props changed)
  head/sys/mips/rt305x/
  head/sys/mips/rt305x/files.rt305x   (contents, props changed)
  head/sys/mips/rt305x/obio.c   (contents, props changed)
  head/sys/mips/rt305x/obiovar.h   (contents, props changed)
  head/sys/mips/rt305x/rt305x_dotg.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_gpio.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_gpio.h   (contents, props changed)
  head/sys/mips/rt305x/rt305x_gpiovar.h   (contents, props changed)
  head/sys/mips/rt305x/rt305x_ic.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_icvar.h   (contents, props changed)
  head/sys/mips/rt305x/rt305x_machdep.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_sysctl.c   (contents, props changed)
  head/sys/mips/rt305x/rt305x_sysctlvar.h   (contents, props changed)
  head/sys/mips/rt305x/rt305xreg.h   (contents, props changed)
  head/sys/mips/rt305x/rt_swreg.h   (contents, props changed)
  head/sys/mips/rt305x/std.rt305x   (contents, props changed)
  head/sys/mips/rt305x/uart_bus_rt305x.c   (contents, props changed)
  head/sys/mips/rt305x/uart_cpu_rt305x.c   (contents, props changed)
  head/sys/mips/rt305x/uart_dev_rt305x.c   (contents, props changed)
  head/sys/mips/rt305x/uart_dev_rt305x.h   (contents, props changed)

Added: head/sys/mips/conf/RT305X
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/conf/RT305X	Sun Apr  3 14:39:55 2011	(r220297)
@@ -0,0 +1,134 @@
+# RT305X -- Kernel configuration file for FreeBSD/mips for Ralink RT305xF systems
+#
+# For more information on this file, please read the handbook section on
+# Kernel Configuration Files:
+#
+#    http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files. 
+# If you are in doubt as to the purpose or necessity of a line, check first 
+# in NOTES.
+#
+# $FreeBSD$
+
+ident		RT305X
+
+machine		mips mipsel
+makeoptions	MIPS_LITTLE_ENDIAN=defined
+makeoptions	KERNLOADADDR=0x80001000
+
+# Don't build any modules yet.
+makeoptions	MODULES_OVERRIDE="wlan_xauth wlan_wep wlan_tkip wlan_acl wlan_amrr wlan_ccmp wlan_rssadapt random if_bridge bridgestp msdosfs md ipfw dummynet libalias geom/geom_label ufs usb/uplcom usb/u3g usb/umodem usb/umass usb/ucom cam zlib"
+makeoptions	RT3052F
+
+include		"../rt305x/std.rt305x"
+
+hints		"RT305X.hints"		#Default places to look for devices.
+
+#makeoptions	DEBUG=-g		#Build kernel with gdb(1) debug symbols
+
+# Debugging for use in -current
+#options 	DEADLKRES		#Enable the deadlock resolver
+#options		INVARIANTS		#Enable calls of extra sanity checking
+#options		INVARIANT_SUPPORT	#Extra sanity checks of internal structures, required by INVARIANTS
+#options		WITNESS			#Enable checks to detect deadlocks and cycles
+#options		WITNESS_SKIPSPIN	#Don't run witness on spinlocks for speed
+#options         DIAGNOSTIC
+#options     DEBUG_LOCKS
+#options     DEBUG_VFS_LOCKS
+#options 	GDB
+options 	DDB
+options 	KDB
+
+options 	SCHED_ULE
+#options 	SCHED_4BSD		#4BSD scheduler
+#options		COMPAT_43
+options 	INET			#InterNETworking
+options 	NFSCLIENT		#Network Filesystem Client
+options 	NFS_ROOT		#NFS usable as /, requires NFSCLIENT
+options 	PSEUDOFS		#Pseudo-filesystem framework
+#options 	_KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+
+options 	BOOTP
+#options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=rt0
+options 	BOOTP_COMPAT
+options 	CD9660			# ISO 9660 Filesystem
+options		ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uncompress\"
+options 	TMPFS			# TMP Memory Filesystem
+
+#options 	FFS			#Berkeley Fast Filesystem
+#options 	SOFTUPDATES		#Enable FFS soft updates support
+#options 	UFS_ACL			#Support for access control lists
+#options 	UFS_DIRHASH		#Improve performance on big directories
+#options 	ROOTDEVNAME=\"nfs:10.0.0.1:/mnt/bsd\"
+
+# Options for making kernel less hangry
+makeoptions	INLINE_LIMIT=1024
+options		MAXUSERS=3
+options		MAXFILES=512
+options		NSFBUFS=256
+options		SHMALL=128
+options		MSGBUF_SIZE=65536
+
+# Options for making kernel smallest 
+options		NO_SYSCTL_DESCR		# No description string of sysctl
+#options		NO_FFS_SNAPSHOT		# Disable Snapshot supporting
+options		SCSI_NO_SENSE_STRINGS
+options		SCSI_NO_OP_STRINGS
+options		RWLOCK_NOINLINE
+options		SX_NOINLINE
+options		NO_SWAPPING
+options 	ZERO_COPY_SOCKETS
+options         MROUTING                # Multicast routing
+options		IPFIREWALL_DEFAULT_TO_ACCEPT
+
+device		random
+device		loop
+# RT3050F, RT3052F have only pseudo PHYs
+#device		mii
+#device		miibus
+device 		pty			# Pseudo-ttys (telnet etc)
+device		ether
+device 		bpf			# Berkeley packet filter
+device		vlan
+#device		lagg
+#device          if_bridge
+device		uart
+nodevice	uart_ns8250
+device 		tun			# Packet tunnel.
+
+device		wlan
+
+
+device		gpio
+device		gpioled
+
+device		cfi			# Detect Flash memmory
+device		cfid
+
+device		nvram2env
+
+device		usb
+#device		dotg			# DWC like USB OTG Controller driver
+#device		u3g
+#device		umodem
+#device		uplcom
+#device		umass
+#device		da
+#device		pass
+#device		scbus
+options 	SCSI_DELAY=1000		# Delay (in ms) before probing SCSI
+
+#options		USB_EHCI_BIG_ENDIAN_DESC        # handle big-endian byte order
+#options		USB_DEBUG
+#options		USB_REQ_DEBUG
+
+

Added: head/sys/mips/conf/RT305X.hints
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/conf/RT305X.hints	Sun Apr  3 14:39:55 2011	(r220297)
@@ -0,0 +1,136 @@
+# $FreeBSD$
+# device.hints
+hint.obio.0.at="nexus0"
+hint.obio.0.maddr=0x10000000
+hint.obio.0.msize=0x10000000
+
+hint.nvram.0.sig=0xe5e60a74
+hint.nvram.0.base=0x1f030000
+hint.nvram.0.maxsize=0x2000
+hint.nvram.0.flags=3 # 1 = No check, 2 = Format Generic
+hint.nvram.1.sig=0x5a045e94
+hint.nvram.1.base=0x1f032000
+hint.nvram.1.maxsize=0x4000
+hint.nvram.1.flags=3 # 1 = No check, 2 = Format Generic
+
+# on-board Ralink Frame Engine
+#hint.rt.0.at="nexus0"
+#hint.rt.0.maddr=0x12000000
+#hint.rt.0.msize=0x200000
+#hint.rt.0.irq=9
+hint.rt.0.macaddr="00:18:e7:d5:83:90"
+
+# on-board Ralink 2872 802.11n core
+hint.rt2860.0.at="nexus0"
+hint.rt2860.0.maddr=0x10180000
+hint.rt2860.0.msize=0x40000
+hint.rt2860.0.irq=4
+
+# uart0
+#hint.uart.0.at="obio0"
+#hint.uart.0.maddr=0x10000C00
+#hint.uart.0.msize=0x100
+#hint.uart.0.irq=12
+#hint.uart.0.flags="0x30"
+
+# uart1
+#hint.uart.1.at="obio0"
+#hint.uart.1.maddr=0x10000500
+#hint.uart.1.msize=0x100
+#hint.uart.1.irq=5
+#hint.uart.1.flags="0x30"
+
+
+# gpio
+# GPIO0  - WPS BTN	IN II IO
+hint.gpiobutton.0.at="gpiobus0"
+hint.gpiobutton.0.pins="0x01"
+hint.gpiobutton.0.name="wps"
+hint.gpiobutton.0.flags="0x0581"
+
+# GPIO7  - MODE SW AP	IN II IO
+hint.gpiobutton.1.at="gpiobus0"
+hint.gpiobutton.1.pins="0x80"
+hint.gpiobutton.1.name="mode_ap"
+hint.gpiobutton.1.flags="0x0581"
+
+# GPIO8  - ST LEDRED	OUT	/* 2pin BiDir RED/BLUE LED */
+# GPIO9  - ST LEDBLUE	OUT
+hint.gpioled.0.at="gpiobus0"
+hint.gpioled.0.pins="0x100"
+hint.gpioled.0.name="status_red"
+hint.gpioled.0.flags="0x0002"
+hint.gpioled.1.at="gpiobus0"
+hint.gpioled.1.pins="0x200"
+#hint.gpioled.1.name="status_blue"
+hint.gpioled.1.name="status"
+hint.gpioled.1.flags="0x0002"
+
+# GPIO10 - RST BTN	IN II IO
+hint.gpiobutton.2.at="gpiobus0"
+hint.gpiobutton.2.pins="0x400"
+hint.gpiobutton.2.name="reset"
+hint.gpiobutton.2.flags="0x0581"
+
+# GPIO11 - MODE SW CL	IN II IO
+hint.gpiobutton.3.at="gpiobus0"
+hint.gpiobutton.3.pins="0x800"
+hint.gpiobutton.3.name="mode_wlan_client"
+hint.gpiobutton.3.flags="0x0581"
+
+# GPIO14 - WPS LED	OUT II IO
+hint.gpioled.2.at="gpiobus0"
+hint.gpioled.2.pins="0x4000"
+hint.gpioled.2.name="wps"
+hint.gpioled.2.flags="0x0182"
+
+
+
+#0x00000000-0x00030000 : "Bootloader"
+#0x00030000-0x00040000 : "Factory"
+#0x00040000-0x00070000 : "Config"
+#0x00070000-0x000b0000 : "Language"
+#0x000b0000-0x001a0000 : "Kernel"
+#0x001a0000-0x01000000 : "RootFS"
+
+hint.map.0.at="cfid0"
+hint.map.0.start=0x00000000
+hint.map.0.end=0x00030000
+hint.map.0.name="bootloader"
+hint.map.0.readonly=1
+
+hint.map.1.at="cfid0"
+hint.map.1.start=0x00030000
+hint.map.1.end=0x00040000
+hint.map.1.name="factory"
+
+hint.map.2.at="cfid0"
+hint.map.2.start=0x00040000
+hint.map.2.end=0x00800000
+hint.map.2.name="upgrade"
+
+hint.map.3.at="cfid0"
+hint.map.3.start=0x00040000
+hint.map.3.end=0x00050000
+hint.map.3.name="config"
+
+hint.map.4.at="cfid0"
+hint.map.4.start=0x00000000
+hint.map.4.end=0x00000000
+hint.map.4.name="language"
+
+hint.map.5.at="cfid0"
+hint.map.5.start=0x00050000
+hint.map.5.end=0x00150000
+hint.map.5.name="kernel"
+
+hint.map.6.at="cfid0"
+hint.map.6.start=0x00150000
+hint.map.6.end=0x00800000
+hint.map.6.name="rootfs"
+
+
+hint.rt.0.phymask=0x1f
+hint.rt.0.media=100
+hint.rt.0.fduplex=1
+

Added: head/sys/mips/rt305x/files.rt305x
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/rt305x/files.rt305x	Sun Apr  3 14:39:55 2011	(r220297)
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+# RT305X on-board devices
+mips/rt305x/rt305x_machdep.c	standard
+mips/rt305x/obio.c		standard
+mips/rt305x/rt305x_sysctl.c	standard
+mips/rt305x/rt305x_ic.c		standard
+mips/rt305x/rt305x_gpio.c	optional gpio
+mips/rt305x/uart_bus_rt305x.c	optional uart
+mips/rt305x/uart_cpu_rt305x.c	optional uart
+mips/rt305x/uart_dev_rt305x.c	optional uart
+mips/mips/intr_machdep.c        standard
+mips/mips/tick.c		standard

Added: head/sys/mips/rt305x/obio.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/rt305x/obio.c	Sun Apr  3 14:39:55 2011	(r220297)
@@ -0,0 +1,627 @@
+/*	$NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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 WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+
+#include <mips/rt305x/rt305xreg.h>
+#include <mips/rt305x/obiovar.h>
+#include <mips/rt305x/rt305x_icvar.h>
+
+/* MIPS HW interrupts of IRQ/FIQ respectively */
+#define RT305X_INTR		0
+#define RT305X_FAST_INTR	1
+
+/* Interrupt levels */
+#define INTR_IRQ 0
+#define INTR_FIQ 1
+
+
+int irq_priorities[NIRQS] = {
+	INTR_IRQ,	/* SYSCTL */
+	INTR_FIQ,	/* TIMER0 */
+	INTR_FIQ,	/* WDTIMER */
+	INTR_IRQ,	/* Illegal Access */
+	INTR_IRQ,	/* PCM */
+	INTR_IRQ,	/* UART */
+	INTR_IRQ,	/* GPIO */
+	INTR_FIQ,	/* GDMA */
+	INTR_IRQ,	/* NAND */
+	INTR_IRQ,	/* Perfomance Counter */
+	INTR_IRQ,	/* I2S */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* UARTLITE */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* EtherNet Switch */
+	INTR_FIQ,	/* OTG */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+	INTR_IRQ,	/* unknown */
+};
+
+
+#define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(INTCTL_BASE + (o)))
+#define REG_WRITE(o,v) (REG_READ(o)) = (v)
+
+static int	obio_activate_resource(device_t, device_t, int, int,
+		    struct resource *);
+static device_t	obio_add_child(device_t, u_int, const char *, int);
+static struct resource *
+		obio_alloc_resource(device_t, device_t, int, int *, u_long,
+		    u_long, u_long, u_int);
+static int	obio_attach(device_t);
+static int	obio_deactivate_resource(device_t, device_t, int, int,
+		    struct resource *);
+static struct resource_list *
+		obio_get_resource_list(device_t, device_t);
+static void	obio_add_res_child(device_t, const char *, int, long, int, int);
+static void	obio_hinted_child(device_t, const char *, int);
+static int	obio_intr(void *);
+static int	obio_probe(device_t);
+static int	obio_release_resource(device_t, device_t, int, int,
+		    struct resource *);
+static int	obio_setup_intr(device_t, device_t, struct resource *, int,
+		    driver_filter_t *, driver_intr_t *, void *, void **);
+static int	obio_teardown_intr(device_t, device_t, struct resource *,
+		    void *);
+
+static void 
+obio_mask_irq(void *source)
+{
+	int irq;
+	uint32_t irqmask;
+
+	irq = (int)source;
+	irqmask = 1 << irq;
+
+	/* disable IRQ */
+	rt305x_ic_set(IC_INT_DIS, irqmask);
+}
+
+static void 
+obio_unmask_irq(void *source)
+{
+	int irq;
+	uint32_t irqmask;
+
+	irq = (int)source;
+	irqmask = 1 << irq;
+
+	/* enable IRQ */
+	rt305x_ic_set(IC_INT_ENA, irqmask);
+
+}
+
+
+static int
+obio_probe(device_t dev)
+{
+
+	return (0);
+}
+
+static int
+obio_attach(device_t dev)
+{
+	struct obio_softc *sc = device_get_softc(dev);
+	int rid;
+
+	sc->oba_mem_rman.rm_type = RMAN_ARRAY;
+	sc->oba_mem_rman.rm_descr = "OBIO memory";
+	if (rman_init(&sc->oba_mem_rman) != 0 ||
+	    rman_manage_region(&sc->oba_mem_rman, OBIO_MEM_START,
+	        OBIO_MEM_END) != 0)
+		panic("obio_attach: failed to set up I/O rman");
+
+	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
+	sc->oba_irq_rman.rm_descr = "OBIO IRQ";
+	if (rman_init(&sc->oba_irq_rman) != 0 ||
+	    rman_manage_region(&sc->oba_irq_rman, 0, NIRQS-1) != 0)
+		panic("obio_attach: failed to set up IRQ rman");
+
+	/* Hook up our interrupt handler. */
+	if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+	    RT305X_INTR, RT305X_INTR, 1,
+	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+		device_printf(dev, "unable to allocate IRQ resource\n");
+		return (ENXIO);
+	}
+
+	if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, obio_intr, NULL,
+	    sc, &sc->sc_ih))) {
+		device_printf(dev,
+		    "WARNING: unable to register interrupt handler\n");
+		return (ENXIO);
+	}
+
+	/* Hook up our FAST interrupt handler. */
+	if ((sc->sc_fast_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+	    RT305X_FAST_INTR, RT305X_FAST_INTR, 1,
+	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+		device_printf(dev, "unable to allocate IRQ resource\n");
+		return (ENXIO);
+	}
+
+	if ((bus_setup_intr(dev, sc->sc_fast_irq, INTR_TYPE_MISC, obio_intr,
+	    NULL, sc, &sc->sc_fast_ih))) {
+		device_printf(dev,
+		    "WARNING: unable to register interrupt handler\n");
+		return (ENXIO);
+	}
+
+	/* disable all interrupts */
+	rt305x_ic_set(IC_INT_DIS, IC_INT_MASK|IC_LINE_GLOBAL);
+
+	bus_generic_probe(dev);
+
+	obio_add_res_child(dev, "rt305x_sysctl", 0, 
+	    SYSCTL_BASE, (SYSCTL_END - SYSCTL_BASE + 1),
+	    IC_SYSCTL);
+	obio_add_res_child(dev, "rt305x_ic", 0, 
+	    INTCTL_BASE, (INTCTL_END - INTCTL_BASE + 1),
+	    -1);
+#ifdef notyet
+	obio_add_res_child(dev, "timer",0, 
+	    TIMER_BASE, (TIMER_END - TIMER_BASE  + 1),
+	    IC_TIMER0);
+	obio_add_res_child(dev, "rt305x_memc", 0,
+	    MEMCTRL_BASE, (MEMCTRL_END - MEMCTRL_BASE + 1),
+	    -1);
+	obio_add_res_child(dev, "pcm", 	0, 
+	    PCM_BASE, (PCM_END - PCM_BASE  + 1),
+	    IC_PCM);
+	obio_add_res_child(dev, "uart", 0, 
+	    UART_BASE, (UART_END - UART_BASE + 1),
+	    IC_UART);
+#endif
+	obio_add_res_child(dev, "gpio", 0, 
+	    PIO_BASE, (PIO_END - PIO_BASE  + 1),
+	    IC_PIO);
+#ifdef notyet
+	obio_add_res_child(dev, "rt305x_dma", 0,
+	    GDMA_BASE, (GDMA_END - GDMA_BASE + 1),
+	    IC_DMA);
+	obio_add_res_child(dev, "rt305x_nandc", 0,
+	    NANDFC_BASE, (NANDFC_END - NANDFC_BASE  + 1),
+	    IC_NAND);
+	obio_add_res_child(dev, "i2c", 	0,
+	    I2C_BASE, (I2C_END - I2C_BASE  + 1),
+	    -1);
+	obio_add_res_child(dev, "i2s", 0,
+	    I2S_BASE, (I2S_END - I2S_BASE  + 1),
+	    IC_I2S);
+	obio_add_res_child(dev, "spi", 0, 
+	    SPI_BASE, (SPI_END - SPI_BASE  + 1),
+	    -1);
+#endif
+	obio_add_res_child(dev, "uart", 1,
+	    UARTLITE_BASE, (UARTLITE_END - UARTLITE_BASE + 1),
+	    IC_UARTLITE);
+	obio_add_res_child(dev, "cfi", 	0,
+	    FLASH_BASE, (FLASH_END - FLASH_BASE  + 1),
+	    -1);
+	obio_add_res_child(dev, "dotg", 0,
+	    USB_OTG_BASE, (USB_OTG_END - USB_OTG_BASE  + 1),
+	    IC_OTG);
+	obio_add_res_child(dev, "switch", 0,
+	    ETHSW_BASE, (ETHSW_END - ETHSW_BASE  + 1),
+	    IC_ETHSW);
+
+	bus_enumerate_hinted_children(dev);
+	bus_generic_attach(dev);
+
+	/* enable IC */
+	rt305x_ic_set(IC_INT_ENA, IC_LINE_GLOBAL);
+
+	return (0);
+}
+
+static struct resource *
+obio_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct obio_softc		*sc = device_get_softc(bus);
+	struct obio_ivar		*ivar = device_get_ivars(child);
+	struct resource			*rv;
+	struct resource_list_entry	*rle;
+	struct rman			*rm;
+	int				 isdefault, needactivate, passthrough;
+
+	isdefault = (start == 0UL && end == ~0UL && count == 1);
+	needactivate = flags & RF_ACTIVE;
+	passthrough = (device_get_parent(child) != bus);
+	rle = NULL;
+
+	if (passthrough)
+		return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type,
+		    rid, start, end, count, flags));
+
+	/*
+	 * If this is an allocation of the "default" range for a given RID,
+	 * and we know what the resources for this device are (ie. they aren't
+	 * maintained by a child bus), then work out the start/end values.
+	 */
+	if (isdefault) {
+		rle = resource_list_find(&ivar->resources, type, *rid);
+		if (rle == NULL)
+			return (NULL);
+		if (rle->res != NULL) {
+			panic("%s: resource entry is busy", __func__);
+		}
+		start = rle->start;
+		end = rle->end;
+		count = rle->count;
+	}
+
+	switch (type) {
+	case SYS_RES_IRQ:
+		rm = &sc->oba_irq_rman;
+		break;
+	case SYS_RES_MEMORY:
+		rm = &sc->oba_mem_rman;
+		break;
+	default:
+		printf("%s: unknown resource type %d\n", __func__, type);
+		return (0);
+	}
+
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (rv == 0) {
+		printf("%s: could not reserve resource\n", __func__);
+		return (0);
+	}
+
+	rman_set_rid(rv, *rid);
+
+	if (needactivate) {
+		if (bus_activate_resource(child, type, *rid, rv)) {
+			printf("%s: could not activate resource\n", __func__);
+			rman_release_resource(rv);
+			return (0);
+		}
+	}
+
+	return (rv);
+}
+
+static int
+obio_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+	/*
+	 * If this is a memory resource, track the direct mapping
+	 * in the uncached MIPS KSEG1 segment.
+	 */
+	if (type == SYS_RES_MEMORY) {
+		void *vaddr;
+
+		vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r));
+		rman_set_virtual(r, vaddr);
+		rman_set_bustag(r, mips_bus_space_generic);
+		rman_set_bushandle(r, (bus_space_handle_t)vaddr);
+	}
+
+	return (rman_activate_resource(r));
+}
+
+static int
+obio_deactivate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+	return (rman_deactivate_resource(r));
+}
+
+static int
+obio_release_resource(device_t dev, device_t child, int type,
+    int rid, struct resource *r)
+{
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+
+	rl = obio_get_resource_list(dev, child);
+	if (rl == NULL)
+		return (EINVAL);
+	rle = resource_list_find(rl, type, rid);
+	if (rle == NULL)
+		return (EINVAL);
+	rman_release_resource(r);
+	rle->res = NULL;
+
+	return (0);
+}
+
+static int
+obio_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 obio_softc *sc = device_get_softc(dev);
+	struct intr_event *event;
+	int irq, error, priority;
+	uint32_t irqmask;
+
+	irq = rman_get_start(ires);
+
+	if (irq >= NIRQS)
+		panic("%s: bad irq %d", __func__, irq);
+
+	event = sc->sc_eventstab[irq];
+	if (event == NULL) {
+		error = intr_event_create(&event, (void *)irq, 0, irq,
+		    obio_mask_irq, obio_unmask_irq,
+		    NULL, NULL, "obio intr%d:", irq);
+
+		sc->sc_eventstab[irq] = event;
+	}
+	else
+		panic("obio: Can't share IRQs");
+
+	intr_event_add_handler(event, device_get_nameunit(child), filt,
+	    handler, arg, intr_priority(flags), flags, cookiep);
+
+	irqmask = 1 << irq;
+	priority = irq_priorities[irq];
+
+	if (priority == INTR_FIQ)
+		rt305x_ic_set(IC_INTTYPE, rt305x_ic_get(IC_INTTYPE) | irqmask);
+	else
+		rt305x_ic_set(IC_INTTYPE, rt305x_ic_get(IC_INTTYPE) & ~irqmask);
+
+	/* enable */
+	obio_unmask_irq((void*)irq);
+
+	return (0);
+}
+
+static int
+obio_teardown_intr(device_t dev, device_t child, struct resource *ires,
+    void *cookie)
+{
+	struct obio_softc *sc = device_get_softc(dev);
+	int irq, result, priority;
+	uint32_t irqmask;
+
+	irq = rman_get_start(ires);
+	if (irq >= NIRQS)
+		panic("%s: bad irq %d", __func__, irq);
+
+	if (sc->sc_eventstab[irq] == NULL)
+		panic("Trying to teardown unoccupied IRQ");
+
+	irqmask = (1 << irq);
+	priority = irq_priorities[irq];
+
+	if (priority == INTR_FIQ)
+		rt305x_ic_set(IC_INTTYPE, rt305x_ic_get(IC_INTTYPE) & ~irqmask);
+	else
+		rt305x_ic_set(IC_INTTYPE, rt305x_ic_get(IC_INTTYPE) | irqmask);
+
+	/* disable */
+	obio_mask_irq((void*)irq);
+
+	result = intr_event_remove_handler(cookie);
+	if (!result) {
+		sc->sc_eventstab[irq] = NULL;
+	}
+
+	return (result);
+}
+
+static int
+obio_intr(void *arg)
+{
+	struct obio_softc *sc = arg;
+	struct intr_event *event;
+	uint32_t irqstat;
+	int irq;
+
+	irqstat = rt305x_ic_get(IC_IRQ0STAT);
+	irqstat |= rt305x_ic_get(IC_IRQ1STAT);
+
+	irq = 0;
+	while (irqstat != 0) {
+		if ((irqstat & 1) == 1) {
+			event = sc->sc_eventstab[irq];
+			if (!event || TAILQ_EMPTY(&event->ie_handlers))
+				continue;
+
+			/* TODO: pass frame as an argument*/
+			/* TODO: log stray interrupt */
+			intr_event_handle(event, NULL);
+		}
+		irq++;
+		irqstat >>= 1;
+	}
+
+	return (FILTER_HANDLED);
+}
+
+static void
+obio_add_res_child(device_t bus, const char *dname, int dunit, 
+    long maddr, int msize, int irq)
+{
+	device_t		child;
+	int			result;
+
+	child = BUS_ADD_CHILD(bus, 0, dname, dunit);
+
+	result = bus_set_resource(child, SYS_RES_MEMORY, 0,
+	    maddr, msize);
+	if (result != 0)
+		device_printf(bus, "warning: bus_set_resource() failed\n");
+
+	if (irq != -1) {
+		result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
+		if (result != 0)
+			device_printf(bus,
+			    "warning: bus_set_resource() failed\n");
+	}
+}
+
+static void
+obio_hinted_child(device_t bus, const char *dname, int dunit)
+{
+	long			maddr;
+	int			msize;
+	int			irq;
+
+	/*
+	 * Set hard-wired resources for hinted child using
+	 * specific RIDs.
+	 */
+	resource_long_value(dname, dunit, "maddr", &maddr);
+	resource_int_value(dname, dunit, "msize", &msize);
+
+
+	if (resource_int_value(dname, dunit, "irq", &irq) == 0) irq = -1;
+
+	obio_add_res_child(bus, dname, dunit, maddr, msize, irq);
+}
+
+static device_t
+obio_add_child(device_t bus, u_int order, const char *name, int unit)
+{
+	device_t		child;
+	struct obio_ivar	*ivar;
+
+	ivar = malloc(sizeof(struct obio_ivar), M_DEVBUF, M_WAITOK | M_ZERO);
+	if (ivar == NULL) {
+		printf("Failed to allocate ivar\n");
+		return (0);
+	}
+	resource_list_init(&ivar->resources);
+
+	child = device_add_child_ordered(bus, order, name, unit);
+	if (child == NULL) {
+		printf("Can't add child %s%d ordered\n", name, unit);
+		return (0);
+	}
+
+	device_set_ivars(child, ivar);
+
+	return (child);
+}
+
+/*
+ * Helper routine for bus_generic_rl_get_resource/bus_generic_rl_set_resource
+ * Provides pointer to resource_list for these routines
+ */
+static struct resource_list *
+obio_get_resource_list(device_t dev, device_t child)
+{
+	struct obio_ivar *ivar;
+
+	ivar = device_get_ivars(child);
+	return (&(ivar->resources));
+}
+
+static int
+obio_print_all_resources(device_t dev)
+{
+	struct obio_ivar *ivar = device_get_ivars(dev);
+	struct resource_list *rl = &ivar->resources;
+	int retval = 0;
+
+	if (STAILQ_FIRST(rl))
+		retval += printf(" at");
+
+	retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
+	retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
+
+	return (retval);
+}
+
+static int
+obio_print_child(device_t bus, device_t child)
+{
+	int retval = 0;
+
+	retval += bus_print_child_header(bus, child);
+	retval += obio_print_all_resources(child);
+	if (device_get_flags(child))
+		retval += printf(" flags %#x", device_get_flags(child));
+	retval += printf(" on %s\n", device_get_nameunit(bus));
+
+	return (retval);
+}
+
+static device_method_t obio_methods[] = {
+	DEVMETHOD(bus_activate_resource,	obio_activate_resource),
+	DEVMETHOD(bus_add_child,		obio_add_child),
+	DEVMETHOD(bus_alloc_resource,		obio_alloc_resource),
+	DEVMETHOD(bus_deactivate_resource,	obio_deactivate_resource),
+	DEVMETHOD(bus_get_resource_list,	obio_get_resource_list),
+	DEVMETHOD(bus_hinted_child,		obio_hinted_child),
+	DEVMETHOD(bus_print_child,		obio_print_child),
+	DEVMETHOD(bus_release_resource,		obio_release_resource),
+	DEVMETHOD(bus_setup_intr,		obio_setup_intr),
+	DEVMETHOD(bus_teardown_intr,		obio_teardown_intr),
+	DEVMETHOD(device_attach,		obio_attach),
+	DEVMETHOD(device_probe,			obio_probe),
+        DEVMETHOD(bus_get_resource,		bus_generic_rl_get_resource),
+        DEVMETHOD(bus_set_resource,		bus_generic_rl_set_resource),
+
+	{0, 0},
+};
+
+static driver_t obio_driver = {
+	"obio",
+	obio_methods,
+	sizeof(struct obio_softc),
+};
+static devclass_t obio_devclass;
+
+DRIVER_MODULE(obio, nexus, obio_driver, obio_devclass, 0, 0);

Added: head/sys/mips/rt305x/obiovar.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/rt305x/obiovar.h	Sun Apr  3 14:39:55 2011	(r220297)
@@ -0,0 +1,58 @@
+/*	$NetBSD: obiovar.h,v 1.4 2003/06/16 17:40:53 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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 WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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 _RT305X_OBIOVAR_H_
+#define	_RT305X_OBIOVAR_H_
+
+#include <sys/rman.h>
+
+/* Number of IRQs */
+#define	NIRQS	32
+
+
+struct obio_softc {
+	struct rman		oba_mem_rman;
+	struct rman		oba_irq_rman;
+	struct rman		oba_gpio_rman;
+	struct intr_event	*sc_eventstab[NIRQS]; /* IRQ events structs */
+	struct resource		*sc_irq;	/* IRQ resource */
+	void			*sc_ih;		/* interrupt cookie */
+	struct resource		*sc_fast_irq;	/* IRQ resource */
+	void			*sc_fast_ih;	/* interrupt cookie */
+};
+
+struct obio_ivar {
+	struct resource_list	resources;
+};
+
+#endif /* _RT305X_OBIOVAR_H_ */

Added: head/sys/mips/rt305x/rt305x_dotg.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/rt305x/rt305x_dotg.c	Sun Apr  3 14:39:55 2011	(r220297)
@@ -0,0 +1,247 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*-
+ * Copyright (c) 2010,2011 Aleksandr Rybalko. All rights reserved.
+ * Copyright (c) 2007-2008 Hans Petter Selasky. 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

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



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