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-all
mailing list