PERFORCE change 195061 for review

Jakub Wojciech Klama jceel at FreeBSD.org
Mon Jun 20 21:54:14 UTC 2011


http://p4web.freebsd.org/@@195061?ac=10

Change 195061 by jceel at jceel_cyclone on 2011/06/20 21:54:10

	Add working RTC driver.

Affected files ...

.. //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/files.lpc#2 edit
.. //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/lpc_rtc.c#2 edit
.. //depot/projects/soc2011/jceel_lpc/sys/boot/fdt/dts/ea3250.dts#2 edit

Differences ...

==== //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/files.lpc#2 (text+ko) ====

@@ -8,6 +8,7 @@
 arm/lpc/lpc_pwr.c			standard
 arm/lpc/lpc_intc.c			standard
 arm/lpc/lpc_timer.c			standard
+arm/lpc/lpc_rtc.c			standard
 arm/lpc/if_lpe.c			optional	lpe
 dev/uart/uart_dev_ns8250.c		optional	uart
 kern/kern_clocksource.c			standard

==== //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/lpc_rtc.c#2 (text+ko) ====

@@ -38,15 +38,20 @@
 #include <sys/module.h>
 
 #include <machine/bus.h>
+#include <machine/resource.h>
 
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
 #include <arm/lpc/lpcreg.h>
 
 #include "clock_if.h"
 
 struct lpc_rtc_softc {
+	device_t			lr_dev;
 	struct resource	*		lr_mem_res;
-	struct bus_space_tag_t		lr_tag;
-	struct bus_space_handle_t	lr_handle
+	bus_space_tag_t			lr_bst;
+	bus_space_handle_t		lr_bsh;
 };
 
 static int lpc_rtc_probe(device_t dev);
@@ -58,16 +63,77 @@
 lpc_rtc_probe(device_t dev)
 {
 
+	if (!ofw_bus_is_compatible(dev, "lpc,rtc"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 real time clock");
+	return (BUS_PROBE_DEFAULT);
 }
 
 static int
 lpc_rtc_attach(device_t dev)
 {
+	struct lpc_rtc_softc *sc = device_get_softc(dev);
+	int rid = 0;
+
+	sc->lr_dev = dev;
+
+	clock_register(dev, 1000000);
+
+	sc->lr_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->lr_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->lr_bst = rman_get_bustag(sc->lr_mem_res);
+	sc->lr_bsh = rman_get_bushandle(sc->lr_mem_res);
+
+	return (0);
+}
+
+static int
+lpc_rtc_gettime(device_t dev, struct timespec *ts)
+{
+	struct lpc_rtc_softc *sc = device_get_softc(dev);
+
+	ts->tv_sec = bus_space_read_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_UCOUNT);
+	ts->tv_nsec = 0;
+
+	return (0);
+}
+
+static int
+lpc_rtc_settime(device_t dev, struct timespec *ts)
+{
+	struct lpc_rtc_softc *sc = device_get_softc(dev);
+	uint32_t ctrl;
+
+	/* Stop RTC */
+	ctrl = bus_space_read_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_CTRL);
+	bus_space_write_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_CTRL, ctrl | LPC_RTC_CTRL_DISABLE);
 
+	/* Write actual value */
+	bus_space_write_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_UCOUNT, ts->tv_sec);
+
+	/* Start RTC */
+	ctrl = bus_space_read_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_CTRL);
+	bus_space_write_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_CTRL, ctrl & ~LPC_RTC_CTRL_DISABLE);
+
+	return (0);	
 }
 
 static device_method_t lpc_rtc_methods[] = {
-	
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpc_rtc_probe),
+	DEVMETHOD(device_attach,	lpc_rtc_attach),
+
+	/* Clock interface */
+	DEVMETHOD(clock_gettime,	lpc_rtc_gettime),
+	DEVMETHOD(clock_settime,	lpc_rtc_settime),
+
+	{ 0, 0 },
 };
 
 static driver_t lpc_rtc_driver = {

==== //depot/projects/soc2011/jceel_lpc/sys/boot/fdt/dts/ea3250.dts#2 (text+ko) ====

@@ -91,6 +91,13 @@
 			interrupt-parent = <&PIC>;
 		};
 
+		rtc at 24000 {
+			compatible = "lpc,rtc";
+			reg = <0x24000 0x4000>;
+			interrupts = <52>;
+			interrupt-parent = <&PIC>;
+		};
+
 		serial0: serial at 14000 {
 			compatible = "ns16550";
 			status = "disabled";


More information about the p4-projects mailing list