svn commit: r264065 - in head/sys: arm/arm boot/fdt/dts/arm

Ruslan Bukin br at FreeBSD.org
Thu Apr 3 05:48:57 UTC 2014


Author: br
Date: Thu Apr  3 05:48:56 2014
New Revision: 264065
URL: http://svnweb.freebsd.org/changeset/base/264065

Log:
  - Setup both secure and non-secure timer IRQs.
    We don't know our ARM security state, so one of them will operate.
  - Don't set frequency, since it's unpossible in non-secure state.
    Only rely on DTS clock-frequency value or get clock from timer.
  
  Discussed with:	ian, cognet

Modified:
  head/sys/arm/arm/generic_timer.c
  head/sys/boot/fdt/dts/arm/exynos5250.dtsi

Modified: head/sys/arm/arm/generic_timer.c
==============================================================================
--- head/sys/arm/arm/generic_timer.c	Thu Apr  3 05:48:28 2014	(r264064)
+++ head/sys/arm/arm/generic_timer.c	Thu Apr  3 05:48:56 2014	(r264065)
@@ -73,16 +73,23 @@ __FBSDID("$FreeBSD$");
 #define	GT_CNTKCTL_PL0VCTEN	(1 << 1) /* PL0 CNTVCT and CNTFRQ access */
 #define	GT_CNTKCTL_PL0PCTEN	(1 << 0) /* PL0 CNTPCT and CNTFRQ access */
 
-#define	GT_CNTPSIRQ	29
-
 struct arm_tmr_softc {
-	struct resource		*irq_res;
+	struct resource		*res[4];
+	void			*ihl[4];
 	uint32_t		clkfreq;
 	struct eventtimer	et;
 };
 
 static struct arm_tmr_softc *arm_tmr_sc = NULL;
 
+static struct resource_spec timer_spec[] = {
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },	/* Secure */
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },	/* Non-secure */
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },	/* Virt */
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },	/* Hyp */
+	{ -1, 0 }
+};
+
 static timecounter_get_t arm_tmr_get_timecount;
 
 static struct timecounter arm_tmr_timecount = {
@@ -261,9 +268,8 @@ arm_tmr_attach(device_t dev)
 	struct arm_tmr_softc *sc;
 	phandle_t node;
 	pcell_t clock;
-	void *ihl;
-	int rid;
 	int error;
+	int i;
 
 	sc = device_get_softc(dev);
 	if (arm_tmr_sc)
@@ -272,29 +278,37 @@ arm_tmr_attach(device_t dev)
 	/* Get the base clock frequency */
 	node = ofw_bus_get_node(dev);
 	error = OF_getprop(node, "clock-frequency", &clock, sizeof(clock));
-	if (error <= 0) {
-		device_printf(dev, "missing clock-frequency "
-		    "attribute in FDT\n");
+	if (error > 0) {
+		sc->clkfreq = fdt32_to_cpu(clock);
+	}
+
+	if (sc->clkfreq == 0) {
+		/* Try to get clock frequency from timer */
+		sc->clkfreq = get_freq();
+	}
+
+	if (sc->clkfreq == 0) {
+		device_printf(dev, "No clock frequency specified\n");
 		return (ENXIO);
 	}
-	sc->clkfreq = fdt32_to_cpu(clock);
 
-	rid = 0;
-	sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
-	    GT_CNTPSIRQ, GT_CNTPSIRQ,
-	    1, RF_SHAREABLE | RF_ACTIVE);
+	if (bus_alloc_resources(dev, timer_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	};
 
 	arm_tmr_sc = sc;
 
-	/* Setup and enable the timer */
-	if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CLK, arm_tmr_intr,
-		NULL, sc, &ihl) != 0) {
-		bus_release_resource(dev, SYS_RES_IRQ, rid, sc->irq_res);
-		device_printf(dev, "Unable to setup the CLK irq handler.\n");
-		return (ENXIO);
+	/* Setup secure and non-secure IRQs handler */
+	for (i = 0; i < 2; i++) {
+		error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK,
+		    arm_tmr_intr, NULL, sc, &sc->ihl[i]);
+		if (error) {
+			device_printf(dev, "Unable to alloc int resource.\n");
+			return (ENXIO);
+		}
 	}
 
-	set_freq(sc->clkfreq);
 	disable_user_access();
 
 	arm_tmr_timecount.tc_frequency = sc->clkfreq;

Modified: head/sys/boot/fdt/dts/arm/exynos5250.dtsi
==============================================================================
--- head/sys/boot/fdt/dts/arm/exynos5250.dtsi	Thu Apr  3 05:48:28 2014	(r264064)
+++ head/sys/boot/fdt/dts/arm/exynos5250.dtsi	Thu Apr  3 05:48:56 2014	(r264065)
@@ -81,6 +81,8 @@
 		generic_timer {
 			compatible = "arm,armv7-timer";
 			clock-frequency = <24000000>;
+			interrupts = < 29 30 27 26 >;
+			interrupt-parent = <&GIC>;
 		};
 
 		pwm {


More information about the svn-src-head mailing list