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