Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 May 2014 20:52:10 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r266352 - in stable/10/sys: arm/arm arm/freescale/imx arm/samsung/exynos boot/fdt/dts/arm
Message-ID:  <201405172052.s4HKqAbe089568@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sat May 17 20:52:10 2014
New Revision: 266352
URL: http://svnweb.freebsd.org/changeset/base/266352

Log:
  MFC 264052, 264057, 264065, 264094, 264103, 264120
  
    Actually save the mpcore clock frequency retrieved from fdt data.
  
    imx6..
    - Don't call sdhci_init_slot() until after handling the FDT properties
      related to detecting card presence.
    - Flag several sysctl variables as tunables.
    - Rework the cpu frequency management code for imx6 to add "operating
      points" and min/max frequency controls.
  
    generic timer...
    - 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.

Modified:
  stable/10/sys/arm/arm/generic_timer.c
  stable/10/sys/arm/arm/mpcore_timer.c
  stable/10/sys/arm/freescale/imx/imx6_anatop.c
  stable/10/sys/arm/freescale/imx/imx_sdhci.c
  stable/10/sys/arm/samsung/exynos/chrome_kb.c
  stable/10/sys/boot/fdt/dts/arm/exynos5250.dtsi
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/arm/arm/generic_timer.c
==============================================================================
--- stable/10/sys/arm/arm/generic_timer.c	Sat May 17 20:39:39 2014	(r266351)
+++ stable/10/sys/arm/arm/generic_timer.c	Sat May 17 20:52:10 2014	(r266352)
@@ -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: stable/10/sys/arm/arm/mpcore_timer.c
==============================================================================
--- stable/10/sys/arm/arm/mpcore_timer.c	Sat May 17 20:39:39 2014	(r266351)
+++ stable/10/sys/arm/arm/mpcore_timer.c	Sat May 17 20:52:10 2014	(r266352)
@@ -301,6 +301,7 @@ arm_tmr_attach(device_t dev)
 				    "attribute in FDT\n");
 				return (ENXIO);
 			}
+			sc->clkfreq = clock;
 		}
 	}
 

Modified: stable/10/sys/arm/freescale/imx/imx6_anatop.c
==============================================================================
--- stable/10/sys/arm/freescale/imx/imx6_anatop.c	Sat May 17 20:39:39 2014	(r266351)
+++ stable/10/sys/arm/freescale/imx/imx6_anatop.c	Sat May 17 20:52:10 2014	(r266352)
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/callout.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/sysctl.h>
 #include <sys/module.h>
 #include <sys/bus.h>
@@ -74,6 +75,8 @@ __FBSDID("$FreeBSD$");
 #include <arm/freescale/imx/imx6_anatopreg.h>
 #include <arm/freescale/imx/imx6_anatopvar.h>
 
+static SYSCTL_NODE(_hw, OID_AUTO, imx6, CTLFLAG_RW, NULL, "i.MX6 container");
+
 static struct resource_spec imx6_anatop_spec[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
@@ -85,14 +88,15 @@ static struct resource_spec imx6_anatop_
 struct imx6_anatop_softc {
 	device_t	dev;
 	struct resource	*res[2];
-	uint32_t	cpu_curhz;
 	uint32_t	cpu_curmhz;
 	uint32_t	cpu_curmv;
-	uint32_t	cpu_minhz;
+	uint32_t	cpu_minmhz;
 	uint32_t	cpu_minmv;
-	uint32_t	cpu_maxhz;
+	uint32_t	cpu_maxmhz;
 	uint32_t	cpu_maxmv;
-	uint32_t	refosc_hz;
+	uint32_t	cpu_maxmhz_hw;
+	boolean_t	cpu_overclock_enable;
+	uint32_t	refosc_mhz;
 	void		*temp_intrhand;
 	uint32_t	temp_high_val;
 	uint32_t	temp_high_cnt;
@@ -108,16 +112,27 @@ struct imx6_anatop_softc {
 static struct imx6_anatop_softc *imx6_anatop_sc;
 
 /*
- * Tables of CPU max frequencies and corresponding voltages.  This is indexed by
- * the max frequency value (0-3) from the ocotp CFG3 register.
+ * Table of "operating points".
+ * These are combinations of frequency and voltage blessed by Freescale.
  */
-static uint32_t imx6_cpu_maxhz_tab[] = {
-	 792000000, 852000000, 996000000, 1200000000
-};
-static uint32_t imx6_cpu_millivolt_tab[] = {
-	1150, 1225, 1225, 1275
+static struct oppt {
+	uint32_t	mhz;
+	uint32_t	mv;
+} imx6_oppt_table[] = {
+/*      { 396,	 925},  XXX: need functional ccm code for this speed */
+	{ 792,	1150},
+	{ 852,	1225},
+	{ 996,	1225},
+	{1200,	1275},
 };
 
+/*
+ * Table of CPU max frequencies.  This is used to translate the max frequency
+ * value (0-3) from the ocotp CFG3 register into a mhz value that can be looked
+ * up in the operating points table.
+ */
+static uint32_t imx6_ocotp_mhz_tab[] = {792, 852, 996, 1200};
+
 #define	TZ_ZEROC	2732	/* deci-Kelvin <-> deci-Celcius offset. */
 
 uint32_t
@@ -193,49 +208,58 @@ vdd_set(struct imx6_anatop_softc *sc, in
 	imx6_anatop_write_4(IMX6_ANALOG_PMU_REG_CORE, pmureg);
 	DELAY(delay);
 	sc->cpu_curmv = newtarg * 25 + 700;
-	device_printf(sc->dev, "voltage set to %u\n", sc->cpu_curmv);
 }
 
 static inline uint32_t
-cpufreq_hz_from_div(struct imx6_anatop_softc *sc, uint32_t div)
+cpufreq_mhz_from_div(struct imx6_anatop_softc *sc, uint32_t div)
 {
 
-	return (sc->refosc_hz * (div / 2));
+	return (sc->refosc_mhz * (div / 2));
 }
 
 static inline uint32_t
-cpufreq_hz_to_div(struct imx6_anatop_softc *sc, uint32_t cpu_hz)
+cpufreq_mhz_to_div(struct imx6_anatop_softc *sc, uint32_t cpu_mhz)
 {
 
-	return (cpu_hz / (sc->refosc_hz / 2));
+	return (cpu_mhz / (sc->refosc_mhz / 2));
 }
 
 static inline uint32_t
-cpufreq_actual_hz(struct imx6_anatop_softc *sc, uint32_t cpu_hz)
+cpufreq_actual_mhz(struct imx6_anatop_softc *sc, uint32_t cpu_mhz)
+{
+
+	return (cpufreq_mhz_from_div(sc, cpufreq_mhz_to_div(sc, cpu_mhz)));
+}
+
+static struct oppt *
+cpufreq_nearest_oppt(struct imx6_anatop_softc *sc, uint32_t cpu_newmhz)
 {
+	int d, diff, i, nearest;
 
-	return (cpufreq_hz_from_div(sc, cpufreq_hz_to_div(sc, cpu_hz)));
+	if (cpu_newmhz > sc->cpu_maxmhz_hw && !sc->cpu_overclock_enable)
+		cpu_newmhz = sc->cpu_maxmhz_hw;
+
+	diff = INT_MAX;
+	nearest = 0;
+	for (i = 0; i < nitems(imx6_oppt_table); ++i) {
+		d = abs((int)cpu_newmhz - (int)imx6_oppt_table[i].mhz);
+		if (diff > d) {
+			diff = d;
+			nearest = i;
+		}
+	}
+	return (&imx6_oppt_table[nearest]);
 }
 
 static void 
-cpufreq_set_clock(struct imx6_anatop_softc * sc, uint32_t cpu_newhz)
+cpufreq_set_clock(struct imx6_anatop_softc * sc, struct oppt *op)
 {
-	uint32_t div, timeout, wrk32;
-	const uint32_t mindiv =  54;
-	const uint32_t maxdiv = 108;
-
-	/*
-	 * Clip the requested frequency to the configured max, then clip the
-	 * resulting divisor to the documented min/max values.
-	 */
-	cpu_newhz = min(cpu_newhz, sc->cpu_maxhz);
-	div = cpufreq_hz_to_div(sc, cpu_newhz);
-	if (div < mindiv)
-		div = mindiv;
-	else if (div > maxdiv)
-		div = maxdiv;
-	sc->cpu_curhz = cpufreq_hz_from_div(sc, div);
-	sc->cpu_curmhz = sc->cpu_curhz / 1000000;
+	uint32_t timeout, wrk32;
+
+	/* If increasing the frequency, we must first increase the voltage. */
+	if (op->mhz > sc->cpu_curmhz) {
+		vdd_set(sc, op->mv);
+	}
 
 	/*
 	 * I can't find a documented procedure for changing the ARM PLL divisor,
@@ -244,7 +268,7 @@ cpufreq_set_clock(struct imx6_anatop_sof
 	 *  - Set the PLL into bypass mode; cpu should now be running at 24mhz.
 	 *  - Change the divisor.
 	 *  - Wait for the LOCK bit to come on; it takes ~50 loop iterations.
-	 *  - Turn off bypass mode; cpu should now be running at cpu_newhz.
+	 *  - Turn off bypass mode; cpu should now be running at the new speed.
 	 */
 	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR, 
 	    IMX6_ANALOG_CCM_PLL_ARM_CLK_SRC_MASK);
@@ -253,7 +277,7 @@ cpufreq_set_clock(struct imx6_anatop_sof
 
 	wrk32 = imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM);
 	wrk32 &= ~IMX6_ANALOG_CCM_PLL_ARM_DIV_MASK;
-	wrk32 |= div;
+	wrk32 |= cpufreq_mhz_to_div(sc, op->mhz);
 	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM, wrk32);
 
 	timeout = 10000;
@@ -265,26 +289,114 @@ cpufreq_set_clock(struct imx6_anatop_sof
 	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR, 
 	    IMX6_ANALOG_CCM_PLL_ARM_BYPASS);
 
-	arm_tmr_change_frequency(sc->cpu_curhz / 2);
+	/* If lowering the frequency, it is now safe to lower the voltage. */
+	if (op->mhz < sc->cpu_curmhz)
+		vdd_set(sc, op->mv);
+	sc->cpu_curmhz = op->mhz;
+
+	/* Tell the mpcore timer that its frequency has changed. */
+        arm_tmr_change_frequency(
+	    cpufreq_actual_mhz(sc, sc->cpu_curmhz) * 1000000 / 2);
+}
+
+static int
+cpufreq_sysctl_minmhz(SYSCTL_HANDLER_ARGS)
+{
+	struct imx6_anatop_softc *sc;
+	struct oppt * op;
+	uint32_t temp;
+	int err;
+
+	sc = arg1;
+
+	temp = sc->cpu_minmhz;
+	err = sysctl_handle_int(oidp, &temp, 0, req);
+	if (err != 0 || req->newptr == NULL)
+		return (err);
+
+	op = cpufreq_nearest_oppt(sc, temp);
+	if (op->mhz > sc->cpu_maxmhz)
+		return (ERANGE);
+	else if (op->mhz == sc->cpu_minmhz)
+		return (0);
+
+	/*
+	 * Value changed, update softc.  If the new min is higher than the
+	 * current speed, raise the current speed to match.
+	 */
+	sc->cpu_minmhz = op->mhz;
+	if (sc->cpu_minmhz > sc->cpu_curmhz) {
+		cpufreq_set_clock(sc, op);
+	}
+	return (err);
+}
+
+static int
+cpufreq_sysctl_maxmhz(SYSCTL_HANDLER_ARGS)
+{
+	struct imx6_anatop_softc *sc;
+	struct oppt * op;
+	uint32_t temp;
+	int err;
+
+	sc = arg1;
+
+	temp = sc->cpu_maxmhz;
+	err = sysctl_handle_int(oidp, &temp, 0, req);
+	if (err != 0 || req->newptr == NULL)
+		return (err);
+
+	op = cpufreq_nearest_oppt(sc, temp);
+	if (op->mhz < sc->cpu_minmhz)
+		return (ERANGE);
+	else if (op->mhz == sc->cpu_maxmhz)
+		return (0);
+
+	/*
+	 *  Value changed, update softc and hardware.  The hardware update is
+	 *  unconditional.  We always try to run at max speed, so any change of
+	 *  the max means we need to change the current speed too, regardless of
+	 *  whether it is higher or lower than the old max.
+	 */
+	sc->cpu_maxmhz = op->mhz;
+	cpufreq_set_clock(sc, op);
+
+	return (err);
 }
 
 static void
 cpufreq_initialize(struct imx6_anatop_softc *sc)
 {
 	uint32_t cfg3speed;
-	struct sysctl_ctx_list *ctx;
+	struct oppt * op;
 
-	ctx = device_get_sysctl_ctx(sc->dev);
-	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
 	    OID_AUTO, "cpu_mhz", CTLFLAG_RD, &sc->cpu_curmhz, 0, 
-	    "CPU frequency in MHz");
+	    "CPU frequency");
+
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6), 
+	    OID_AUTO, "cpu_minmhz", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
+	    cpufreq_sysctl_minmhz, "IU", "Minimum CPU frequency");
+
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
+	    OID_AUTO, "cpu_maxmhz", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
+	    cpufreq_sysctl_maxmhz, "IU", "Maximum CPU frequency");
+
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
+	    OID_AUTO, "cpu_maxmhz_hw", CTLFLAG_RD, &sc->cpu_maxmhz_hw, 0, 
+	    "Maximum CPU frequency allowed by hardware");
+
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
+	    OID_AUTO, "cpu_overclock_enable", CTLFLAG_RWTUN, 
+	    &sc->cpu_overclock_enable, 0, 
+	    "Allow setting CPU frequency higher than cpu_maxmhz_hw");
 
 	/*
 	 * XXX 24mhz shouldn't be hard-coded, should get this from imx6_ccm
 	 * (even though in the real world it will always be 24mhz).  Oh wait a
 	 * sec, I never wrote imx6_ccm.
 	 */
-	sc->refosc_hz = 24000000;
+	sc->refosc_mhz = 24;
 
 	/*
 	 * Get the maximum speed this cpu can be set to.  The values in the
@@ -294,14 +406,25 @@ cpufreq_initialize(struct imx6_anatop_so
 	 *   - 2b'10: 996000000Hz;
 	 *   - 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
 	 *   - 2b'00: 792000000Hz;
+	 * The default hardware max speed can be overridden by a tunable.
 	 */
 	cfg3speed = (fsl_ocotp_read_4(FSL_OCOTP_CFG3) & 
 	    FSL_OCOTP_CFG3_SPEED_MASK) >> FSL_OCOTP_CFG3_SPEED_SHIFT;
+	sc->cpu_maxmhz_hw = imx6_ocotp_mhz_tab[cfg3speed];
+	sc->cpu_maxmhz = sc->cpu_maxmhz_hw;
+
+	TUNABLE_INT_FETCH("hw.imx6.cpu_overclock_enable",
+	    &sc->cpu_overclock_enable);
 
-	sc->cpu_minhz = cpufreq_actual_hz(sc, imx6_cpu_maxhz_tab[0]);
-	sc->cpu_minmv = imx6_cpu_millivolt_tab[0];
-	sc->cpu_maxhz = cpufreq_actual_hz(sc, imx6_cpu_maxhz_tab[cfg3speed]);
-	sc->cpu_maxmv = imx6_cpu_millivolt_tab[cfg3speed];
+	TUNABLE_INT_FETCH("hw.imx6.cpu_minmhz", &sc->cpu_minmhz);
+	op = cpufreq_nearest_oppt(sc, sc->cpu_minmhz);
+	sc->cpu_minmhz = op->mhz;
+	sc->cpu_minmv = op->mv;
+
+	TUNABLE_INT_FETCH("hw.imx6.cpu_maxmhz", &sc->cpu_maxmhz);
+	op = cpufreq_nearest_oppt(sc, sc->cpu_maxmhz);
+	sc->cpu_maxmhz = op->mhz;
+	sc->cpu_maxmv = op->mv;
 
 	/*
 	 * Set the CPU to maximum speed.
@@ -311,9 +434,7 @@ cpufreq_initialize(struct imx6_anatop_so
 	 * basically assumes that a single core can't overheat before interrupts
 	 * are enabled; empirical testing shows that to be a safe assumption.
 	 */
-	vdd_set(sc, sc->cpu_maxmv);
-	cpufreq_set_clock(sc, sc->cpu_maxhz);
-	device_printf(sc->dev, "CPU frequency %uMHz\n", sc->cpu_curmhz);
+	cpufreq_set_clock(sc, op);
 }
 
 static inline uint32_t
@@ -391,9 +512,8 @@ static void
 tempmon_gofast(struct imx6_anatop_softc *sc)
 {
 
-	if (sc->cpu_curhz < sc->cpu_maxhz) {
-		vdd_set(sc, sc->cpu_maxmv);
-		cpufreq_set_clock(sc, sc->cpu_maxhz);
+	if (sc->cpu_curmhz < sc->cpu_maxmhz) {
+		cpufreq_set_clock(sc, cpufreq_nearest_oppt(sc, sc->cpu_maxmhz));
 	}
 }
 
@@ -401,9 +521,8 @@ static void
 tempmon_goslow(struct imx6_anatop_softc *sc)
 {
 
-	if (sc->cpu_curhz > sc->cpu_minhz) {
-		cpufreq_set_clock(sc, sc->cpu_minhz);
-		vdd_set(sc, sc->cpu_minmv);
+	if (sc->cpu_curmhz > sc->cpu_minmhz) {
+		cpufreq_set_clock(sc, cpufreq_nearest_oppt(sc, sc->cpu_minmhz));
 	}
 }
 
@@ -542,6 +661,10 @@ imx6_anatop_attach(device_t dev)
 	cpufreq_initialize(sc);
 	initialize_tempmon(sc);
 
+	if (bootverbose) {
+		device_printf(sc->dev, "CPU %uMHz @ %umV\n", sc->cpu_curmhz,
+		    sc->cpu_curmv);
+	}
 	err = 0;
 
 out:
@@ -575,7 +698,7 @@ imx6_get_cpu_clock()
 
 	div = imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM) &
 	    IMX6_ANALOG_CCM_PLL_ARM_DIV_MASK;
-	return (cpufreq_hz_from_div(imx6_anatop_sc, div));
+	return (cpufreq_mhz_from_div(imx6_anatop_sc, div));
 }
 
 static device_method_t imx6_anatop_methods[] = {

Modified: stable/10/sys/arm/freescale/imx/imx_sdhci.c
==============================================================================
--- stable/10/sys/arm/freescale/imx/imx_sdhci.c	Sat May 17 20:39:39 2014	(r266351)
+++ stable/10/sys/arm/freescale/imx/imx_sdhci.c	Sat May 17 20:52:10 2014	(r266352)
@@ -730,9 +730,6 @@ imx_sdhci_attach(device_t dev)
 		sc->baseclk_hz = imx51_get_clock(IMX51CLK_PERCLK_ROOT);
 	}
 
-	sdhci_init_slot(dev, &sc->slot, 0);
-	callout_init(&sc->r1bfix_callout, true);
-
 	/*
 	 * If the slot is flagged with the non-removable property, set our flag
 	 * to always force the SDHCI_CARD_PRESENT bit on.
@@ -752,6 +749,9 @@ imx_sdhci_attach(device_t dev)
 		sc->force_card_present = true;
 	}
 
+	callout_init(&sc->r1bfix_callout, true);
+	sdhci_init_slot(dev, &sc->slot, 0);
+
 	bus_generic_probe(dev);
 	bus_generic_attach(dev);
 

Modified: stable/10/sys/arm/samsung/exynos/chrome_kb.c
==============================================================================
--- stable/10/sys/arm/samsung/exynos/chrome_kb.c	Sat May 17 20:39:39 2014	(r266351)
+++ stable/10/sys/arm/samsung/exynos/chrome_kb.c	Sat May 17 20:52:10 2014	(r266352)
@@ -138,7 +138,6 @@ struct ckb_softc {
 };
 
 /* prototypes */
-static void	ckb_set_leds(struct ckb_softc *, uint8_t);
 static int	ckb_set_typematic(keyboard_t *, int);
 static uint32_t	ckb_read_char(keyboard_t *, int);
 static void	ckb_clear_state(keyboard_t *);

Modified: stable/10/sys/boot/fdt/dts/arm/exynos5250.dtsi
==============================================================================
--- stable/10/sys/boot/fdt/dts/arm/exynos5250.dtsi	Sat May 17 20:39:39 2014	(r266351)
+++ stable/10/sys/boot/fdt/dts/arm/exynos5250.dtsi	Sat May 17 20:52:10 2014	(r266352)
@@ -81,6 +81,8 @@
 		generic_timer {
 			compatible = "arm,armv7-timer";
 			clock-frequency = <24000000>;
+			interrupts = < 29 30 27 26 >;
+			interrupt-parent = <&GIC>;
 		};
 
 		pwm {



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