mirror of
https://git.yoctoproject.org/poky
synced 2026-04-30 03:32:12 +02:00
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
From a1dbb6dd28e9815a307b87b8d96dcf371d6cfd58 Mon Sep 17 00:00:00 2001
|
||||
From: Jarkko Nikula <jarkko.nikula@nokia.com>
|
||||
Date: Mon, 19 May 2008 13:24:41 +0300
|
||||
Subject: [PATCH] ASoC: OMAP: Add basic support for OMAP34xx in McBSP DAI driver
|
||||
|
||||
This adds support for OMAP34xx McBSP port 1 and 2.
|
||||
|
||||
Signed-off-by: Jarkko Nikula <jarkko.nikula@nokia.com>
|
||||
---
|
||||
sound/soc/omap/omap-mcbsp.c | 20 +++++++++++++++++++-
|
||||
1 files changed, 19 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
|
||||
index 40d87e6..8e6ec9d 100644
|
||||
--- a/sound/soc/omap/omap-mcbsp.c
|
||||
+++ b/sound/soc/omap/omap-mcbsp.c
|
||||
@@ -99,6 +99,21 @@ static const unsigned long omap2420_mcbsp_port[][2] = {
|
||||
static const int omap2420_dma_reqs[][2] = {};
|
||||
static const unsigned long omap2420_mcbsp_port[][2] = {};
|
||||
#endif
|
||||
+#if defined(CONFIG_ARCH_OMAP34XX)
|
||||
+static const int omap34xx_dma_reqs[][2] = {
|
||||
+ { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX },
|
||||
+ { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX },
|
||||
+};
|
||||
+static const unsigned long omap34xx_mcbsp_port[][2] = {
|
||||
+ { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR2,
|
||||
+ OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR2 },
|
||||
+ { OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR2,
|
||||
+ OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR2 },
|
||||
+};
|
||||
+#else
|
||||
+static const int omap34xx_dma_reqs[][2] = {};
|
||||
+static const unsigned long omap34xx_mcbsp_port[][2] = {};
|
||||
+#endif
|
||||
|
||||
static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
@@ -169,9 +184,12 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
} else if (cpu_is_omap2420()) {
|
||||
dma = omap2420_dma_reqs[bus_id][substream->stream];
|
||||
port = omap2420_mcbsp_port[bus_id][substream->stream];
|
||||
+ } else if (cpu_is_omap343x()) {
|
||||
+ dma = omap34xx_dma_reqs[bus_id][substream->stream];
|
||||
+ port = omap34xx_mcbsp_port[bus_id][substream->stream];
|
||||
} else {
|
||||
/*
|
||||
- * TODO: Add support for 2430 and 3430
|
||||
+ * TODO: Add support for 2430
|
||||
*/
|
||||
return -ENODEV;
|
||||
}
|
||||
--
|
||||
1.5.5.1
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
From: "Rajendra Nayak" <rnayak@ti.com>
|
||||
To: <linux-omap@vger.kernel.org>
|
||||
Subject: [PATCH 01/02] OMAP3 CPUidle driver
|
||||
Date: Tue, 10 Jun 2008 12:39:00 +0530
|
||||
|
||||
This patch adds the OMAP3 cpuidle driver. Irq enable/disable is done in the core cpuidle driver
|
||||
before it queries the governor for the next state.
|
||||
|
||||
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
|
||||
|
||||
---
|
||||
arch/arm/mach-omap2/Makefile | 2
|
||||
arch/arm/mach-omap2/cpuidle34xx.c | 293 ++++++++++++++++++++++++++++++++++++++
|
||||
arch/arm/mach-omap2/cpuidle34xx.h | 51 ++++++
|
||||
arch/arm/mach-omap2/pm34xx.c | 5
|
||||
drivers/cpuidle/cpuidle.c | 10 +
|
||||
5 files changed, 359 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:33.855303920 +0530
|
||||
+++ linux-omap-2.6/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:39.569121361 +0530
|
||||
@@ -20,7 +20,7 @@ obj-y += pm.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o
|
||||
obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o
|
||||
-obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
|
||||
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o
|
||||
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
|
||||
endif
|
||||
|
||||
Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c 2008-06-10 11:41:27.644820323 +0530
|
||||
@@ -0,0 +1,293 @@
|
||||
+/*
|
||||
+ * linux/arch/arm/mach-omap2/cpuidle34xx.c
|
||||
+ *
|
||||
+ * OMAP3 CPU IDLE Routines
|
||||
+ *
|
||||
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
+ * Rajendra Nayak <rnayak@ti.com>
|
||||
+ *
|
||||
+ * Copyright (C) 2007 Texas Instruments, Inc.
|
||||
+ * Karthik Dasu <karthik-dp@ti.com>
|
||||
+ *
|
||||
+ * Copyright (C) 2006 Nokia Corporation
|
||||
+ * Tony Lindgren <tony@atomide.com>
|
||||
+ *
|
||||
+ * Copyright (C) 2005 Texas Instruments, Inc.
|
||||
+ * Richard Woodruff <r-woodruff2@ti.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/cpuidle.h>
|
||||
+#include <asm/arch/pm.h>
|
||||
+#include <asm/arch/prcm.h>
|
||||
+#include <asm/arch/powerdomain.h>
|
||||
+#include <asm/arch/clockdomain.h>
|
||||
+#include <asm/arch/irqs.h>
|
||||
+#include "cpuidle34xx.h"
|
||||
+
|
||||
+#ifdef CONFIG_CPU_IDLE
|
||||
+
|
||||
+struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
|
||||
+struct omap3_processor_cx current_cx_state;
|
||||
+
|
||||
+static int omap3_idle_bm_check(void)
|
||||
+{
|
||||
+ /* Check for omap3_fclks_active() here once available */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* omap3_enter_idle - Programs OMAP3 to enter the specified state.
|
||||
+ * returns the total time during which the system was idle.
|
||||
+ */
|
||||
+static int omap3_enter_idle(struct cpuidle_device *dev,
|
||||
+ struct cpuidle_state *state)
|
||||
+{
|
||||
+ struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
|
||||
+ struct timespec ts_preidle, ts_postidle, ts_idle;
|
||||
+ struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd;
|
||||
+ int neon_pwrst;
|
||||
+
|
||||
+ current_cx_state = *cx;
|
||||
+
|
||||
+ if (cx->type == OMAP3_STATE_C0) {
|
||||
+ /* Do nothing for C0, not even a wfi */
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Used to keep track of the total time in idle */
|
||||
+ getnstimeofday(&ts_preidle);
|
||||
+
|
||||
+ mpu_pd = pwrdm_lookup("mpu_pwrdm");
|
||||
+ core_pd = pwrdm_lookup("core_pwrdm");
|
||||
+ per_pd = pwrdm_lookup("per_pwrdm");
|
||||
+ neon_pd = pwrdm_lookup("neon_pwrdm");
|
||||
+
|
||||
+ /* Reset previous power state registers */
|
||||
+ pwrdm_clear_all_prev_pwrst(mpu_pd);
|
||||
+ pwrdm_clear_all_prev_pwrst(neon_pd);
|
||||
+ pwrdm_clear_all_prev_pwrst(core_pd);
|
||||
+ pwrdm_clear_all_prev_pwrst(per_pd);
|
||||
+
|
||||
+ if (omap_irq_pending())
|
||||
+ return 0;
|
||||
+
|
||||
+ neon_pwrst = pwrdm_read_pwrst(neon_pd);
|
||||
+
|
||||
+ /* Program MPU/NEON to target state */
|
||||
+ if (cx->mpu_state < PWRDM_POWER_ON) {
|
||||
+ if (neon_pwrst == PWRDM_POWER_ON) {
|
||||
+ if (cx->mpu_state == PWRDM_POWER_RET)
|
||||
+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET);
|
||||
+ else if (cx->mpu_state == PWRDM_POWER_OFF)
|
||||
+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF);
|
||||
+ }
|
||||
+ pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
|
||||
+ }
|
||||
+
|
||||
+ /* Program CORE to target state */
|
||||
+ if (cx->core_state < PWRDM_POWER_ON)
|
||||
+ pwrdm_set_next_pwrst(core_pd, cx->core_state);
|
||||
+
|
||||
+ /* Execute ARM wfi */
|
||||
+ omap_sram_idle();
|
||||
+
|
||||
+ /* Program MPU/NEON to ON */
|
||||
+ if (cx->mpu_state < PWRDM_POWER_ON) {
|
||||
+ if (neon_pwrst == PWRDM_POWER_ON)
|
||||
+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON);
|
||||
+ pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);
|
||||
+ }
|
||||
+
|
||||
+ if (cx->core_state < PWRDM_POWER_ON)
|
||||
+ pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON);
|
||||
+
|
||||
+ getnstimeofday(&ts_postidle);
|
||||
+ ts_idle = timespec_sub(ts_postidle, ts_preidle);
|
||||
+ return timespec_to_ns(&ts_idle);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * omap3_enter_idle_bm - enter function for states with CPUIDLE_FLAG_CHECK_BM
|
||||
+ *
|
||||
+ * This function checks for all the pre-requisites needed for OMAP3 to enter
|
||||
+ * CORE RET/OFF state. It then calls omap3_enter_idle to program the desired
|
||||
+ * C state.
|
||||
+ */
|
||||
+static int omap3_enter_idle_bm(struct cpuidle_device *dev,
|
||||
+ struct cpuidle_state *state)
|
||||
+{
|
||||
+ struct cpuidle_state *new_state = NULL;
|
||||
+ int i, j;
|
||||
+
|
||||
+ if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
|
||||
+
|
||||
+ /* Find current state in list */
|
||||
+ for (i = 0; i < OMAP3_MAX_STATES; i++)
|
||||
+ if (state == &dev->states[i])
|
||||
+ break;
|
||||
+ BUG_ON(i == OMAP3_MAX_STATES);
|
||||
+
|
||||
+ /* Back up to non 'CHECK_BM' state */
|
||||
+ for (j = i - 1; j > 0; j--) {
|
||||
+ struct cpuidle_state *s = &dev->states[j];
|
||||
+
|
||||
+ if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) {
|
||||
+ new_state = s;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pr_debug("%s: Bus activity: Entering %s (instead of %s)\n",
|
||||
+ __FUNCTION__, new_state->name, state->name);
|
||||
+ }
|
||||
+
|
||||
+ return omap3_enter_idle(dev, new_state ? : state);
|
||||
+}
|
||||
+
|
||||
+DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
|
||||
+
|
||||
+/* omap3_init_power_states - Initialises the OMAP3 specific C states.
|
||||
+ * Below is the desciption of each C state.
|
||||
+ *
|
||||
+ C0 . System executing code
|
||||
+ C1 . MPU WFI + Core active
|
||||
+ C2 . MPU CSWR + Core active
|
||||
+ C3 . MPU OFF + Core active
|
||||
+ C4 . MPU CSWR + Core CSWR
|
||||
+ C5 . MPU OFF + Core CSWR
|
||||
+ C6 . MPU OFF + Core OFF
|
||||
+ */
|
||||
+void omap_init_power_states(void)
|
||||
+{
|
||||
+ /* C0 . System executing code */
|
||||
+ omap3_power_states[0].valid = 1;
|
||||
+ omap3_power_states[0].type = OMAP3_STATE_C0;
|
||||
+ omap3_power_states[0].sleep_latency = 0;
|
||||
+ omap3_power_states[0].wakeup_latency = 0;
|
||||
+ omap3_power_states[0].threshold = 0;
|
||||
+ omap3_power_states[0].mpu_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[0].core_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_SHALLOW;
|
||||
+
|
||||
+ /* C1 . MPU WFI + Core active */
|
||||
+ omap3_power_states[1].valid = 1;
|
||||
+ omap3_power_states[1].type = OMAP3_STATE_C1;
|
||||
+ omap3_power_states[1].sleep_latency = 10;
|
||||
+ omap3_power_states[1].wakeup_latency = 10;
|
||||
+ omap3_power_states[1].threshold = 30;
|
||||
+ omap3_power_states[1].mpu_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[1].core_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_SHALLOW;
|
||||
+
|
||||
+ /* C2 . MPU CSWR + Core active */
|
||||
+ omap3_power_states[2].valid = 1;
|
||||
+ omap3_power_states[2].type = OMAP3_STATE_C2;
|
||||
+ omap3_power_states[2].sleep_latency = 50;
|
||||
+ omap3_power_states[2].wakeup_latency = 50;
|
||||
+ omap3_power_states[2].threshold = 300;
|
||||
+ omap3_power_states[2].mpu_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[2].core_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_BALANCED;
|
||||
+
|
||||
+ /* C3 . MPU OFF + Core active */
|
||||
+ omap3_power_states[3].valid = 0;
|
||||
+ omap3_power_states[3].type = OMAP3_STATE_C3;
|
||||
+ omap3_power_states[3].sleep_latency = 1500;
|
||||
+ omap3_power_states[3].wakeup_latency = 1800;
|
||||
+ omap3_power_states[3].threshold = 4000;
|
||||
+ omap3_power_states[3].mpu_state = PWRDM_POWER_OFF;
|
||||
+ omap3_power_states[3].core_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_BALANCED;
|
||||
+
|
||||
+ /* C4 . MPU CSWR + Core CSWR*/
|
||||
+ omap3_power_states[4].valid = 1;
|
||||
+ omap3_power_states[4].type = OMAP3_STATE_C4;
|
||||
+ omap3_power_states[4].sleep_latency = 2500;
|
||||
+ omap3_power_states[4].wakeup_latency = 7500;
|
||||
+ omap3_power_states[4].threshold = 12000;
|
||||
+ omap3_power_states[4].mpu_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[4].core_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
|
||||
+
|
||||
+ /* C5 . MPU OFF + Core CSWR */
|
||||
+ omap3_power_states[5].valid = 0;
|
||||
+ omap3_power_states[5].type = OMAP3_STATE_C5;
|
||||
+ omap3_power_states[5].sleep_latency = 3000;
|
||||
+ omap3_power_states[5].wakeup_latency = 8500;
|
||||
+ omap3_power_states[5].threshold = 15000;
|
||||
+ omap3_power_states[5].mpu_state = PWRDM_POWER_OFF;
|
||||
+ omap3_power_states[5].core_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
|
||||
+
|
||||
+ /* C6 . MPU OFF + Core OFF */
|
||||
+ omap3_power_states[6].valid = 0;
|
||||
+ omap3_power_states[6].type = OMAP3_STATE_C6;
|
||||
+ omap3_power_states[6].sleep_latency = 10000;
|
||||
+ omap3_power_states[6].wakeup_latency = 30000;
|
||||
+ omap3_power_states[6].threshold = 300000;
|
||||
+ omap3_power_states[6].mpu_state = PWRDM_POWER_OFF;
|
||||
+ omap3_power_states[6].core_state = PWRDM_POWER_OFF;
|
||||
+ omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM;
|
||||
+}
|
||||
+
|
||||
+struct cpuidle_driver omap3_idle_driver = {
|
||||
+ .name = "omap3_idle",
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+/*
|
||||
+ * omap3_idle_init - Init routine for OMAP3 idle.
|
||||
+ * Registers the OMAP3 specific cpuidle driver with the cpuidle f/w
|
||||
+ * with the valid set of states.
|
||||
+ */
|
||||
+int omap3_idle_init(void)
|
||||
+{
|
||||
+ int i, count = 0;
|
||||
+ struct omap3_processor_cx *cx;
|
||||
+ struct cpuidle_state *state;
|
||||
+ struct cpuidle_device *dev;
|
||||
+
|
||||
+ omap_init_power_states();
|
||||
+ cpuidle_register_driver(&omap3_idle_driver);
|
||||
+
|
||||
+ dev = &per_cpu(omap3_idle_dev, smp_processor_id());
|
||||
+
|
||||
+ for (i = 0; i < OMAP3_MAX_STATES; i++) {
|
||||
+ cx = &omap3_power_states[i];
|
||||
+ state = &dev->states[count];
|
||||
+
|
||||
+ if (!cx->valid)
|
||||
+ continue;
|
||||
+ cpuidle_set_statedata(state, cx);
|
||||
+ state->exit_latency = cx->sleep_latency + cx->wakeup_latency;
|
||||
+ state->target_residency = cx->threshold;
|
||||
+ state->flags = cx->flags;
|
||||
+ state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
|
||||
+ omap3_enter_idle_bm : omap3_enter_idle;
|
||||
+ sprintf(state->name, "C%d", count+1);
|
||||
+ count++;
|
||||
+ }
|
||||
+
|
||||
+ if (!count)
|
||||
+ return -EINVAL;
|
||||
+ dev->state_count = count;
|
||||
+
|
||||
+ if (cpuidle_register_device(dev)) {
|
||||
+ printk(KERN_ERR "%s: CPUidle register device failed\n",
|
||||
+ __FUNCTION__);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+__initcall(omap3_idle_init);
|
||||
+#endif /* CONFIG_CPU_IDLE */
|
||||
Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h 2008-06-09 20:15:39.569121361 +0530
|
||||
@@ -0,0 +1,51 @@
|
||||
+/*
|
||||
+ * linux/arch/arm/mach-omap2/cpuidle34xx.h
|
||||
+ *
|
||||
+ * OMAP3 cpuidle structure definitions
|
||||
+ *
|
||||
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
+ * Written by Rajendra Nayak <rnayak@ti.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
+ *
|
||||
+ * History:
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
|
||||
+#define ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
|
||||
+
|
||||
+#define OMAP3_MAX_STATES 7
|
||||
+#define OMAP3_STATE_C0 0 /* C0 - System executing code */
|
||||
+#define OMAP3_STATE_C1 1 /* C1 - MPU WFI + Core active */
|
||||
+#define OMAP3_STATE_C2 2 /* C2 - MPU CSWR + Core active */
|
||||
+#define OMAP3_STATE_C3 3 /* C3 - MPU OFF + Core active */
|
||||
+#define OMAP3_STATE_C4 4 /* C4 - MPU RET + Core RET */
|
||||
+#define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */
|
||||
+#define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */
|
||||
+
|
||||
+extern void omap_sram_idle(void);
|
||||
+extern int omap3_irq_pending(void);
|
||||
+
|
||||
+struct omap3_processor_cx {
|
||||
+ u8 valid;
|
||||
+ u8 type;
|
||||
+ u32 sleep_latency;
|
||||
+ u32 wakeup_latency;
|
||||
+ u32 mpu_state;
|
||||
+ u32 core_state;
|
||||
+ u32 threshold;
|
||||
+ u32 flags;
|
||||
+};
|
||||
+
|
||||
+void omap_init_power_states(void);
|
||||
+int omap3_idle_init(void);
|
||||
+
|
||||
+#endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */
|
||||
+
|
||||
Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:15:33.855303920 +0530
|
||||
+++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:16:20.976798343 +0530
|
||||
@@ -141,7 +141,7 @@ static irqreturn_t prcm_interrupt_handle
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
-static void omap_sram_idle(void)
|
||||
+void omap_sram_idle(void)
|
||||
{
|
||||
/* Variable to tell what needs to be saved and restored
|
||||
* in omap_sram_idle*/
|
||||
@@ -156,6 +156,7 @@ static void omap_sram_idle(void)
|
||||
|
||||
mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
|
||||
switch (mpu_next_state) {
|
||||
+ case PWRDM_POWER_ON:
|
||||
case PWRDM_POWER_RET:
|
||||
/* No need to save context */
|
||||
save_state = 0;
|
||||
@@ -386,7 +387,9 @@ int __init omap3_pm_init(void)
|
||||
|
||||
prcm_setup_regs();
|
||||
|
||||
+#ifndef CONFIG_CPU_IDLE
|
||||
pm_idle = omap3_pm_idle;
|
||||
+#endif
|
||||
|
||||
err1:
|
||||
return ret;
|
||||
Index: linux-omap-2.6/drivers/cpuidle/cpuidle.c
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:33.856303888 +0530
|
||||
+++ linux-omap-2.6/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:39.570121329 +0530
|
||||
@@ -58,6 +58,11 @@ static void cpuidle_idle_call(void)
|
||||
return;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_ARCH_OMAP3
|
||||
+ local_irq_disable();
|
||||
+ local_fiq_disable();
|
||||
+#endif
|
||||
+
|
||||
/* ask the governor for the next state */
|
||||
next_state = cpuidle_curr_governor->select(dev);
|
||||
if (need_resched())
|
||||
@@ -70,6 +75,11 @@ static void cpuidle_idle_call(void)
|
||||
target_state->time += (unsigned long long)dev->last_residency;
|
||||
target_state->usage++;
|
||||
|
||||
+#ifdef CONFIG_ARCH_OMAP3
|
||||
+ local_irq_enable();
|
||||
+ local_fiq_enable();
|
||||
+#endif
|
||||
+
|
||||
/* give the governor an opportunity to reflect on the outcome */
|
||||
if (cpuidle_curr_governor->reflect)
|
||||
cpuidle_curr_governor->reflect(dev);
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
From 7a444ee080c5f1a62ac5042f1e7926622b3e1ce7 Mon Sep 17 00:00:00 2001
|
||||
From: Koen Kooi <koen@openembedded.org>
|
||||
Date: Fri, 30 May 2008 13:43:36 +0200
|
||||
Subject: [PATCH] ARM: OMAP: omap3beagle: add a platform device to hook up the GPIO leds to the leds-gpio driver
|
||||
|
||||
omap3beagle: add a platform device to hook up the GPIO leds to the leds-gpio driver
|
||||
* on revision A5 and earlier board the two leds can't be controlled seperately, should be fixed in rev. B and C boards.
|
||||
|
||||
Signed-off-by: Koen Kooi <koen@openembedded.org>
|
||||
---
|
||||
arch/arm/mach-omap2/board-omap3beagle.c | 28 ++++++++++++++++++++++++++++
|
||||
1 files changed, 28 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
index c992cc7..83891fc 100644
|
||||
--- a/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
+#include <linux/leds.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@@ -72,6 +73,32 @@ static struct omap_lcd_config omap3_beagle_lcd_config __initdata = {
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
+struct gpio_led gpio_leds[] = {
|
||||
+ {
|
||||
+ .name = "beagleboard::led0",
|
||||
+ .default_trigger = "none",
|
||||
+ .gpio = 149,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "beagleboard::led1",
|
||||
+ .default_trigger = "none",
|
||||
+ .gpio = 150,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led_platform_data gpio_led_info = {
|
||||
+ .leds = gpio_leds,
|
||||
+ .num_leds = ARRAY_SIZE(gpio_leds),
|
||||
+};
|
||||
+
|
||||
+static struct platform_device leds_gpio = {
|
||||
+ .name = "leds-gpio",
|
||||
+ .id = -1,
|
||||
+ .dev = {
|
||||
+ .platform_data = &gpio_led_info,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct omap_board_config_kernel omap3_beagle_config[] __initdata = {
|
||||
{ OMAP_TAG_UART, &omap3_beagle_uart_config },
|
||||
{ OMAP_TAG_MMC, &omap3beagle_mmc_config },
|
||||
@@ -83,6 +110,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = {
|
||||
#ifdef CONFIG_RTC_DRV_TWL4030
|
||||
&omap3_beagle_twl4030rtc_device,
|
||||
#endif
|
||||
+ &leds_gpio,
|
||||
};
|
||||
|
||||
static void __init omap3_beagle_init(void)
|
||||
--
|
||||
1.5.4.3
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
From: "Rajendra Nayak" <rnayak@ti.com>
|
||||
To: <linux-omap@vger.kernel.org>
|
||||
Subject: [PATCH 02/02] Kconfig changes
|
||||
Date: Tue, 10 Jun 2008 12:39:02 +0530
|
||||
|
||||
Updates the CPUidle Kconfig
|
||||
|
||||
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
|
||||
|
||||
---
|
||||
arch/arm/Kconfig | 10 ++++++++++
|
||||
drivers/cpuidle/Kconfig | 28 ++++++++++++++++++++++------
|
||||
2 files changed, 32 insertions(+), 6 deletions(-)
|
||||
|
||||
Index: linux-omap-2.6/arch/arm/Kconfig
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/arch/arm/Kconfig 2008-06-10 11:43:10.790502713 +0530
|
||||
+++ linux-omap-2.6/arch/arm/Kconfig 2008-06-10 11:43:38.701604549 +0530
|
||||
@@ -954,6 +954,16 @@ config ATAGS_PROC
|
||||
|
||||
endmenu
|
||||
|
||||
+if (ARCH_OMAP)
|
||||
+
|
||||
+menu "CPUIdle"
|
||||
+
|
||||
+source "drivers/cpuidle/Kconfig"
|
||||
+
|
||||
+endmenu
|
||||
+
|
||||
+endif
|
||||
+
|
||||
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
Index: linux-omap-2.6/drivers/cpuidle/Kconfig
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/drivers/cpuidle/Kconfig 2008-06-10 11:43:10.790502713 +0530
|
||||
+++ linux-omap-2.6/drivers/cpuidle/Kconfig 2008-06-10 12:06:36.139332151 +0530
|
||||
@@ -1,20 +1,36 @@
|
||||
+menu "CPU idle PM support"
|
||||
|
||||
config CPU_IDLE
|
||||
bool "CPU idle PM support"
|
||||
- default ACPI
|
||||
+ default n
|
||||
help
|
||||
CPU idle is a generic framework for supporting software-controlled
|
||||
idle processor power management. It includes modular cross-platform
|
||||
governors that can be swapped during runtime.
|
||||
|
||||
- If you're using an ACPI-enabled platform, you should say Y here.
|
||||
+ If you're using a mobile platform that supports CPU idle PM (e.g.
|
||||
+ an ACPI-capable notebook), you should say Y here.
|
||||
+
|
||||
+if CPU_IDLE
|
||||
+
|
||||
+comment "Governors"
|
||||
|
||||
config CPU_IDLE_GOV_LADDER
|
||||
- bool
|
||||
+ bool "ladder"
|
||||
depends on CPU_IDLE
|
||||
- default y
|
||||
+ default n
|
||||
|
||||
config CPU_IDLE_GOV_MENU
|
||||
- bool
|
||||
+ bool "menu"
|
||||
depends on CPU_IDLE && NO_HZ
|
||||
- default y
|
||||
+ default n
|
||||
+ help
|
||||
+ This cpuidle governor evaluates all available states and chooses the
|
||||
+ deepest state that meets all of the following constraints: BM activity,
|
||||
+ expected time until next timer interrupt, and last break event time
|
||||
+ delta. It is designed to minimize power consumption. Currently
|
||||
+ dynticks is required.
|
||||
+
|
||||
+endif # CPU_IDLE
|
||||
+
|
||||
+endmenu
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Sat, 5 Jul 2008 20:31:56 +0000 (+0100)
|
||||
Subject: omapfb: fix video timings message
|
||||
X-Git-Tag: beagle-5~3
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=2929b75035ebe8702ba2ff2c81b654c487701f64
|
||||
|
||||
omapfb: fix video timings message
|
||||
---
|
||||
|
||||
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
|
||||
index 418ed9f..1166a01 100644
|
||||
--- a/drivers/video/omap/omapfb_main.c
|
||||
+++ b/drivers/video/omap/omapfb_main.c
|
||||
@@ -1789,7 +1789,8 @@ static int omapfb_do_probe(struct platform_device *pdev,
|
||||
vram, fbdev->mem_desc.region_cnt);
|
||||
pr_info("omapfb: Pixclock %lu kHz hfreq %lu.%lu kHz "
|
||||
"vfreq %lu.%lu Hz\n",
|
||||
- phz / 1000, hhz / 10000, hhz % 10, vhz / 10, vhz % 10);
|
||||
+ phz / 1000, hhz / 10000, hhz % 10000,
|
||||
+ vhz / 10, vhz % 10);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
clear
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
|
||||
---
|
||||
|
||||
arch/arm/plat-omap/dmtimer.c | 4 ++++
|
||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
|
||||
index f22506a..e38a11e 100644
|
||||
--- a/arch/arm/plat-omap/dmtimer.c
|
||||
+++ b/arch/arm/plat-omap/dmtimer.c
|
||||
@@ -703,6 +703,10 @@ int __init omap_dm_timer_init(void)
|
||||
timer->fclk = clk_get(NULL, clk_name);
|
||||
}
|
||||
#endif
|
||||
+ omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW |
|
||||
+ OMAP_TIMER_INT_MATCH |
|
||||
+ OMAP_TIMER_INT_CAPTURE);
|
||||
+
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -0,0 +1,97 @@
|
||||
OMAP2/3 system tick GPTIMER: use match interrupts rather than overflow interrupts
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
On some OMAP3 chips, GPTIMER1 will occasionally decline to interrupt
|
||||
the MPU when a timer overflow event occurs. The timer stops running;
|
||||
and TOCR is sometimes incremented; but the MPU apparently never receives
|
||||
the interrupt. This patch was an experiment in using the GPTIMER
|
||||
match interrupt to determine if it resolves the problem.
|
||||
Unfortunately, it does not; the same problem occurs with match
|
||||
interrupts; but this patch is preserved as the base for a
|
||||
match+overflow interrupt workaround used in a following patch.
|
||||
---
|
||||
|
||||
arch/arm/mach-omap2/timer-gp.c | 32 ++++++++++----------------------
|
||||
1 files changed, 10 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
|
||||
index 557603f..51996ba 100644
|
||||
--- a/arch/arm/mach-omap2/timer-gp.c
|
||||
+++ b/arch/arm/mach-omap2/timer-gp.c
|
||||
@@ -36,6 +36,8 @@
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/arch/dmtimer.h>
|
||||
|
||||
+#define GPTIMER_MATCH_VAL 0xffff0000
|
||||
+
|
||||
static struct omap_dm_timer *gptimer;
|
||||
static struct clock_event_device clockevent_gpt;
|
||||
|
||||
@@ -44,7 +46,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
|
||||
struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id;
|
||||
struct clock_event_device *evt = &clockevent_gpt;
|
||||
|
||||
- omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_OVERFLOW);
|
||||
+ omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_MATCH);
|
||||
|
||||
evt->event_handler(evt);
|
||||
return IRQ_HANDLED;
|
||||
@@ -59,7 +61,7 @@ static struct irqaction omap2_gp_timer_irq = {
|
||||
static int omap2_gp_timer_set_next_event(unsigned long cycles,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
- omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles);
|
||||
+ omap_dm_timer_set_load_start(gptimer, 0, GPTIMER_MATCH_VAL - cycles);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -67,29 +69,12 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles,
|
||||
static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
- u32 period;
|
||||
-
|
||||
omap_dm_timer_stop(gptimer);
|
||||
-
|
||||
- switch (mode) {
|
||||
- case CLOCK_EVT_MODE_PERIODIC:
|
||||
- period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
|
||||
- period -= 1;
|
||||
-
|
||||
- omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period);
|
||||
- break;
|
||||
- case CLOCK_EVT_MODE_ONESHOT:
|
||||
- break;
|
||||
- case CLOCK_EVT_MODE_UNUSED:
|
||||
- case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
- case CLOCK_EVT_MODE_RESUME:
|
||||
- break;
|
||||
- }
|
||||
}
|
||||
|
||||
static struct clock_event_device clockevent_gpt = {
|
||||
.name = "gp timer",
|
||||
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
+ .features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.shift = 32,
|
||||
.set_next_event = omap2_gp_timer_set_next_event,
|
||||
.set_mode = omap2_gp_timer_set_mode,
|
||||
@@ -111,12 +96,15 @@ static void __init omap2_gp_clockevent_init(void)
|
||||
|
||||
omap2_gp_timer_irq.dev_id = (void *)gptimer;
|
||||
setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
|
||||
- omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
|
||||
+ omap_dm_timer_stop(gptimer);
|
||||
+ /* omap_dm_timer_set_load(gptimer, 0, 0);*/
|
||||
+ omap_dm_timer_set_match(gptimer, 1, GPTIMER_MATCH_VAL);
|
||||
+ omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH);
|
||||
|
||||
clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC,
|
||||
clockevent_gpt.shift);
|
||||
clockevent_gpt.max_delta_ns =
|
||||
- clockevent_delta2ns(0xffffffff, &clockevent_gpt);
|
||||
+ clockevent_delta2ns(GPTIMER_MATCH_VAL, &clockevent_gpt);
|
||||
clockevent_gpt.min_delta_ns =
|
||||
clockevent_delta2ns(1, &clockevent_gpt);
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Sat, 5 Jul 2008 20:32:38 +0000 (+0100)
|
||||
Subject: omap: set CLKSEL_DSS1 to 2
|
||||
X-Git-Tag: beagle-5~2
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=d23f9c3c5c6243b626f7ec4c255469de2536e488
|
||||
|
||||
omap: set CLKSEL_DSS1 to 2
|
||||
---
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
|
||||
index 8fdf8f3..04dedec 100644
|
||||
--- a/arch/arm/mach-omap2/clock34xx.c
|
||||
+++ b/arch/arm/mach-omap2/clock34xx.c
|
||||
@@ -596,6 +596,8 @@ int __init omap2_clk_init(void)
|
||||
/* u32 clkrate; */
|
||||
u32 cpu_clkflg;
|
||||
|
||||
+ __raw_writel(0x1002, io_p2v(0x48004e40));
|
||||
+
|
||||
/* REVISIT: Ultimately this will be used for multiboot */
|
||||
#if 0
|
||||
if (cpu_is_omap242x()) {
|
||||
@@ -0,0 +1,27 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Sun, 6 Jul 2008 13:15:36 +0000 (+0100)
|
||||
Subject: omapfb: enable overlay optimisation when possible
|
||||
X-Git-Tag: beagle-5~1
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=a63ac3abdf6781f863112321260fe7a5da757802
|
||||
|
||||
omapfb: enable overlay optimisation when possible
|
||||
---
|
||||
|
||||
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
|
||||
index 6aff476..3b36227 100644
|
||||
--- a/drivers/video/omap/dispc.c
|
||||
+++ b/drivers/video/omap/dispc.c
|
||||
@@ -582,11 +582,13 @@ static int omap_dispc_enable_plane(int plane, int enable)
|
||||
const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
|
||||
DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
|
||||
DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
|
||||
+ unsigned overlay_opt = plane & !!enable & !dispc.color_key.key_type;
|
||||
if ((unsigned int)plane > dispc.mem_desc.region_cnt)
|
||||
return -EINVAL;
|
||||
|
||||
enable_lcd_clocks(1);
|
||||
MOD_REG_FLD(at_reg[plane], 1, enable ? 1 : 0);
|
||||
+ MOD_REG_FLD(DISPC_CONTROL, 1<<12 | 1<<5, overlay_opt<<12 | 1<<5);
|
||||
enable_lcd_clocks(0);
|
||||
|
||||
return 0;
|
||||
@@ -0,0 +1,94 @@
|
||||
OMAP2/3 system tick GPTIMER: use overflow interrupts to detect missing match interrupts
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
GPTIMER1 on some OMAP3 chips occasionally misses match conditions
|
||||
between the timer counter and the target register value, and does not
|
||||
interrupt to the MPU. This patch adds another line of defense by
|
||||
setting the timer to generate an overflow interrupt 0.5 seconds after the
|
||||
timer passes the original comparison value.
|
||||
|
||||
If interrupts are masked for a long period of time, one would expect
|
||||
both a match and an overflow interrupt to be logged. This is considered
|
||||
a normal condition. However, if only an overflow interrupt is logged,
|
||||
this is considered evidence of a hardware bug and the kernel will issue
|
||||
a warning.
|
||||
|
||||
This workaround is unlikely to be 100% effective, since GPTIMER1 has
|
||||
also been observed to lose overflow interrupts occasionally. It is
|
||||
hoped that the probability of losing both will be significantly lower
|
||||
than the probability of losing either one.
|
||||
---
|
||||
|
||||
arch/arm/mach-omap2/timer-gp.c | 36 ++++++++++++++++++++++++++++++++----
|
||||
1 files changed, 32 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
|
||||
index 51996ba..ce5c2b4 100644
|
||||
--- a/arch/arm/mach-omap2/timer-gp.c
|
||||
+++ b/arch/arm/mach-omap2/timer-gp.c
|
||||
@@ -36,17 +36,43 @@
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/arch/dmtimer.h>
|
||||
|
||||
-#define GPTIMER_MATCH_VAL 0xffff0000
|
||||
+/*
|
||||
+ * The number of timer ticks to delay will be subtracted from
|
||||
+ * GPTIMER_MATCH_VAL before loading into the timer. So GPTIMER_MATCH_VAL
|
||||
+ * constrains the longest delay that can be generated with the timer.
|
||||
+ * Since the current code uses overflow interrupts as protection against
|
||||
+ * missed comparison interrupts, this value should also be sufficiently
|
||||
+ * large such that there is not an excessively long delay between ticks
|
||||
+ * if the comparison interrupt fails to arrive. The 0xfffff800 value
|
||||
+ * below results in a half-second delay in such a case when using
|
||||
+ * the 32kHz timer as source.
|
||||
+ */
|
||||
+#define GPTIMER_MATCH_VAL (0xffffffff - (32768/2))
|
||||
|
||||
static struct omap_dm_timer *gptimer;
|
||||
static struct clock_event_device clockevent_gpt;
|
||||
|
||||
+static u32 last_load;
|
||||
+
|
||||
static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id;
|
||||
struct clock_event_device *evt = &clockevent_gpt;
|
||||
-
|
||||
- omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_MATCH);
|
||||
+ u32 v;
|
||||
+
|
||||
+ v = omap_dm_timer_read_status(gpt);
|
||||
+ if ((v & OMAP_TIMER_INT_OVERFLOW) && !(v & OMAP_TIMER_INT_MATCH)) {
|
||||
+ /*
|
||||
+ * Should never happen. Current belief is that this is
|
||||
+ * due to a hardware bug in the GPTIMER block on some
|
||||
+ * OMAP3 revisions.
|
||||
+ */
|
||||
+ pr_err("*** GPTIMER missed match interrupt! last load: %08x\n",
|
||||
+ last_load);
|
||||
+ WARN_ON(1);
|
||||
+ }
|
||||
+
|
||||
+ omap_dm_timer_write_status(gpt, v);
|
||||
|
||||
evt->event_handler(evt);
|
||||
return IRQ_HANDLED;
|
||||
@@ -61,6 +87,7 @@ static struct irqaction omap2_gp_timer_irq = {
|
||||
static int omap2_gp_timer_set_next_event(unsigned long cycles,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
+ last_load = GPTIMER_MATCH_VAL - cycles;
|
||||
omap_dm_timer_set_load_start(gptimer, 0, GPTIMER_MATCH_VAL - cycles);
|
||||
|
||||
return 0;
|
||||
@@ -99,7 +126,8 @@ static void __init omap2_gp_clockevent_init(void)
|
||||
omap_dm_timer_stop(gptimer);
|
||||
/* omap_dm_timer_set_load(gptimer, 0, 0);*/
|
||||
omap_dm_timer_set_match(gptimer, 1, GPTIMER_MATCH_VAL);
|
||||
- omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH);
|
||||
+ omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH |
|
||||
+ OMAP_TIMER_INT_OVERFLOW);
|
||||
|
||||
clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC,
|
||||
clockevent_gpt.shift);
|
||||
@@ -0,0 +1,110 @@
|
||||
Add extra debug for the q_d_w_o() when work fn is already active.
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
|
||||
---
|
||||
|
||||
arch/arm/mach-omap2/timer-gp.c | 3 ++-
|
||||
arch/arm/plat-omap/dmtimer.c | 20 ++++++++++++++++++++
|
||||
include/asm-arm/arch-omap/dmtimer.h | 1 +
|
||||
kernel/time/timer_list.c | 8 ++++++++
|
||||
4 files changed, 31 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
|
||||
index ce5c2b4..e3ed368 100644
|
||||
--- a/arch/arm/mach-omap2/timer-gp.c
|
||||
+++ b/arch/arm/mach-omap2/timer-gp.c
|
||||
@@ -50,6 +50,7 @@
|
||||
#define GPTIMER_MATCH_VAL (0xffffffff - (32768/2))
|
||||
|
||||
static struct omap_dm_timer *gptimer;
|
||||
+struct omap_dm_timer *gptimer_pub;
|
||||
static struct clock_event_device clockevent_gpt;
|
||||
|
||||
static u32 last_load;
|
||||
@@ -111,7 +112,7 @@ static void __init omap2_gp_clockevent_init(void)
|
||||
{
|
||||
u32 tick_rate;
|
||||
|
||||
- gptimer = omap_dm_timer_request_specific(1);
|
||||
+ gptimer = gptimer_pub = omap_dm_timer_request_specific(1);
|
||||
BUG_ON(gptimer == NULL);
|
||||
|
||||
#if defined(CONFIG_OMAP_32K_TIMER)
|
||||
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
|
||||
index e38a11e..b10f8ac 100644
|
||||
--- a/arch/arm/plat-omap/dmtimer.c
|
||||
+++ b/arch/arm/plat-omap/dmtimer.c
|
||||
@@ -614,6 +614,26 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
|
||||
omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
|
||||
}
|
||||
|
||||
+void omap_dm_timer_dump_int_enable(struct omap_dm_timer *timer)
|
||||
+{
|
||||
+ u32 l;
|
||||
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
|
||||
+ pr_err("GPT TCRR: %08x\n", l);
|
||||
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_MATCH_REG);
|
||||
+ pr_err("GPT TMAT: %08x\n", l);
|
||||
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
|
||||
+ pr_err("GPT TISR: %08x\n", l);
|
||||
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_INT_EN_REG);
|
||||
+ pr_err("GPT TIER: %08x\n", l);
|
||||
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
|
||||
+ pr_err("GPT TCLR: %08x\n", l);
|
||||
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG);
|
||||
+ pr_err("GPT TOCR: %08x\n", l);
|
||||
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_INT_MASK_COUNT_REG);
|
||||
+ pr_err("GPT TOWR: %08x\n", l);
|
||||
+}
|
||||
+
|
||||
+
|
||||
unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
|
||||
{
|
||||
unsigned int l;
|
||||
diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h
|
||||
index 02b29e8..a8123e9 100644
|
||||
--- a/include/asm-arm/arch-omap/dmtimer.h
|
||||
+++ b/include/asm-arm/arch-omap/dmtimer.h
|
||||
@@ -73,6 +73,7 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
|
||||
|
||||
void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
|
||||
|
||||
+void omap_dm_timer_dump_int_enable(struct omap_dm_timer *timer);
|
||||
unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
|
||||
void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
|
||||
unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
|
||||
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
|
||||
index a40e20f..452eab7 100644
|
||||
--- a/kernel/time/timer_list.c
|
||||
+++ b/kernel/time/timer_list.c
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/tick.h>
|
||||
|
||||
+#include <asm/arch/dmtimer.h>
|
||||
+
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
typedef void (*print_fn_t)(struct seq_file *m, unsigned int *classes);
|
||||
@@ -239,6 +241,8 @@ static void timer_list_show_tickdevices(struct seq_file *m)
|
||||
static void timer_list_show_tickdevices(struct seq_file *m) { }
|
||||
#endif
|
||||
|
||||
+extern struct omap_dm_timer *gptimer_pub;
|
||||
+
|
||||
static int timer_list_show(struct seq_file *m, void *v)
|
||||
{
|
||||
u64 now = ktime_to_ns(ktime_get());
|
||||
@@ -254,6 +258,10 @@ static int timer_list_show(struct seq_file *m, void *v)
|
||||
SEQ_printf(m, "\n");
|
||||
timer_list_show_tickdevices(m);
|
||||
|
||||
+ SEQ_printf(m, "\n");
|
||||
+
|
||||
+ omap_dm_timer_dump_int_enable(gptimer_pub);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Sun, 6 Jul 2008 13:22:54 +0000 (+0100)
|
||||
Subject: omapfb: use PCD if set in panel config
|
||||
X-Git-Tag: beagle-5
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=c8060d36ae156771f00a7a27cabf1b4435c378bd
|
||||
|
||||
omapfb: use PCD if set in panel config
|
||||
---
|
||||
|
||||
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
|
||||
index 3b36227..4e1a8e3 100644
|
||||
--- a/drivers/video/omap/dispc.c
|
||||
+++ b/drivers/video/omap/dispc.c
|
||||
@@ -798,7 +798,13 @@ static void set_lcd_timings(void)
|
||||
l |= panel->acb & 0xff;
|
||||
dispc_write_reg(DISPC_POL_FREQ, l);
|
||||
|
||||
- calc_ck_div(is_tft, panel->pixel_clock * 1000, &lck_div, &pck_div);
|
||||
+ if (panel->pcd) {
|
||||
+ pck_div = panel->pcd;
|
||||
+ lck_div = 1;
|
||||
+ } else {
|
||||
+ calc_ck_div(is_tft, panel->pixel_clock * 1000,
|
||||
+ &lck_div, &pck_div);
|
||||
+ }
|
||||
|
||||
l = dispc_read_reg(DISPC_DIVISOR);
|
||||
l &= ~(FLD_MASK(16, 8) | FLD_MASK(0, 8));
|
||||
@@ -0,0 +1,45 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Mon, 7 Jul 2008 00:13:00 +0000 (+0100)
|
||||
Subject: omapfb: fix display panning
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=9fec252c96b0e69bcef0afd9cb9dd72b7179c239
|
||||
|
||||
omapfb: fix display panning
|
||||
---
|
||||
|
||||
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
|
||||
index 4e1a8e3..c17371c 100644
|
||||
--- a/drivers/video/omap/dispc.c
|
||||
+++ b/drivers/video/omap/dispc.c
|
||||
@@ -435,6 +435,8 @@ static inline int _setup_plane(int plane, int channel_out,
|
||||
|
||||
dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1);
|
||||
|
||||
+ MOD_REG_FLD(DISPC_CONTROL, 1<<5, 1<<5);
|
||||
+
|
||||
return height * screen_width * bpp / 8;
|
||||
}
|
||||
|
||||
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
|
||||
index 1166a01..3e4959e 100644
|
||||
--- a/drivers/video/omap/omapfb_main.c
|
||||
+++ b/drivers/video/omap/omapfb_main.c
|
||||
@@ -206,8 +206,8 @@ static int ctrl_change_mode(struct fb_info *fbi)
|
||||
struct omapfb_device *fbdev = plane->fbdev;
|
||||
struct fb_var_screeninfo *var = &fbi->var;
|
||||
|
||||
- offset = var->yoffset * fbi->fix.line_length +
|
||||
- var->xoffset * var->bits_per_pixel / 8;
|
||||
+ offset = (var->yoffset * var->xres_virtual + var->xoffset) *
|
||||
+ var->bits_per_pixel / 8;
|
||||
|
||||
if (fbdev->ctrl->sync)
|
||||
fbdev->ctrl->sync();
|
||||
@@ -423,6 +423,8 @@ static void set_fb_fix(struct fb_info *fbi)
|
||||
}
|
||||
fix->accel = FB_ACCEL_OMAP1610;
|
||||
fix->line_length = var->xres_virtual * bpp / 8;
|
||||
+ fix->xpanstep = 1;
|
||||
+ fix->ypanstep = 1;
|
||||
}
|
||||
|
||||
static int set_color_mode(struct omapfb_plane_struct *plane,
|
||||
@@ -0,0 +1,31 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Mon, 7 Jul 2008 23:59:08 +0000 (+0100)
|
||||
Subject: omapfb: ensure fck/lcd < 173MHz
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=0523ece1bad659c48c66aea364d83f7490e7e5ae
|
||||
|
||||
omapfb: ensure fck/lcd < 173MHz
|
||||
---
|
||||
|
||||
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
|
||||
index c17371c..85d6cad 100644
|
||||
--- a/drivers/video/omap/dispc.c
|
||||
+++ b/drivers/video/omap/dispc.c
|
||||
@@ -738,14 +738,16 @@ static void setup_color_conv_coef(void)
|
||||
MOD_REG_FLD(at2_reg, (1 << 11), ct->full_range);
|
||||
}
|
||||
|
||||
+#define MAX_FCK_LCD 173000000
|
||||
+
|
||||
static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div)
|
||||
{
|
||||
unsigned long fck, lck;
|
||||
|
||||
- *lck_div = 1;
|
||||
pck = max(1, pck);
|
||||
fck = clk_get_rate(dispc.dss1_fck);
|
||||
- lck = fck;
|
||||
+ *lck_div = (fck + MAX_FCK_LCD - 1) / MAX_FCK_LCD;
|
||||
+ lck = fck / *lck_div;
|
||||
*pck_div = (lck + pck - 1) / pck;
|
||||
if (is_tft)
|
||||
*pck_div = max(2, *pck_div);
|
||||
@@ -0,0 +1,21 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Tue, 8 Jul 2008 18:26:43 +0000 (+0100)
|
||||
Subject: omapfb: set graphics burst size to 16x32
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=4f9e415dfcd5613a8de973f6c9878cab959c5869
|
||||
|
||||
omapfb: set graphics burst size to 16x32
|
||||
---
|
||||
|
||||
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
|
||||
index 85d6cad..fd06ca2 100644
|
||||
--- a/drivers/video/omap/dispc.c
|
||||
+++ b/drivers/video/omap/dispc.c
|
||||
@@ -409,7 +409,7 @@ static inline int _setup_plane(int plane, int channel_out,
|
||||
l |= cconv_en << 9;
|
||||
|
||||
l &= ~(0x03 << burst_shift);
|
||||
- l |= DISPC_BURST_8x32 << burst_shift;
|
||||
+ l |= DISPC_BURST_16x32 << burst_shift;
|
||||
|
||||
l &= ~(1 << chout_shift);
|
||||
l |= chout_val << chout_shift;
|
||||
@@ -0,0 +1,137 @@
|
||||
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
|
||||
index bdeb8fb..bf256f3 100644
|
||||
--- a/drivers/video/omap/Kconfig
|
||||
+++ b/drivers/video/omap/Kconfig
|
||||
@@ -7,6 +7,27 @@ config FB_OMAP
|
||||
help
|
||||
Frame buffer driver for OMAP based boards.
|
||||
|
||||
+choice
|
||||
+ depends on FB_OMAP && MACH_OMAP3_BEAGLE
|
||||
+ prompt "Screen resolution"
|
||||
+ default FB_OMAP_079M3R
|
||||
+ help
|
||||
+ Selected desired screen resolution
|
||||
+
|
||||
+config FB_OMAP_031M3R
|
||||
+ boolean "640 x 480 @ 60 Hz Reduced blanking"
|
||||
+
|
||||
+config FB_OMAP_048M3R
|
||||
+ boolean "800 x 600 @ 60 Hz Reduced blanking"
|
||||
+
|
||||
+config FB_OMAP_079M3R
|
||||
+ boolean "1024 x 768 @ 60 Hz Reduced blanking"
|
||||
+
|
||||
+config FB_OMAP_092M9R
|
||||
+ boolean "1280 x 720 @ 60 Hz Reduced blanking"
|
||||
+
|
||||
+endchoice
|
||||
+
|
||||
config FB_OMAP_LCDC_EXTERNAL
|
||||
bool "External LCD controller support"
|
||||
depends on FB_OMAP
|
||||
diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
|
||||
index 69d4e06..5e098c2 100644
|
||||
--- a/drivers/video/omap/lcd_omap3beagle.c
|
||||
+++ b/drivers/video/omap/lcd_omap3beagle.c
|
||||
@@ -31,10 +31,6 @@
|
||||
|
||||
#define LCD_PANEL_ENABLE_GPIO 170
|
||||
|
||||
-#define LCD_XRES 1024
|
||||
-#define LCD_YRES 768
|
||||
-#define LCD_PIXCLOCK 64000 /* in kHz */
|
||||
-
|
||||
static int omap3beagle_panel_init(struct lcd_panel *panel,
|
||||
struct omapfb_device *fbdev)
|
||||
{
|
||||
@@ -65,19 +61,76 @@ static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
|
||||
struct lcd_panel omap3beagle_panel = {
|
||||
.name = "omap3beagle",
|
||||
.config = OMAP_LCDC_PANEL_TFT,
|
||||
-
|
||||
- .bpp = 24,
|
||||
+ .bpp = 16,
|
||||
.data_lines = 24,
|
||||
- .x_res = LCD_XRES,
|
||||
- .y_res = LCD_YRES,
|
||||
- .hsw = 3, /* hsync_len (4) - 1 */
|
||||
- .hfp = 3, /* right_margin (4) - 1 */
|
||||
- .hbp = 39, /* left_margin (40) - 1 */
|
||||
- .vsw = 1, /* vsync_len (2) - 1 */
|
||||
- .vfp = 2, /* lower_margin */
|
||||
- .vbp = 7, /* upper_margin (8) - 1 */
|
||||
-
|
||||
- .pixel_clock = LCD_PIXCLOCK,
|
||||
+
|
||||
+#if defined CONFIG_FB_OMAP_031M3R
|
||||
+
|
||||
+ /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
|
||||
+ .x_res = 640,
|
||||
+ .y_res = 480,
|
||||
+ .hfp = 48,
|
||||
+ .hsw = 32,
|
||||
+ .hbp = 80,
|
||||
+ .vfp = 3,
|
||||
+ .vsw = 4,
|
||||
+ .vbp = 7,
|
||||
+ .pixel_clock = 23500,
|
||||
+
|
||||
+#elif defined CONFIG_FB_OMAP_048M3R
|
||||
+
|
||||
+ /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */
|
||||
+ .x_res = 800,
|
||||
+ .y_res = 600,
|
||||
+ .hfp = 48,
|
||||
+ .hsw = 32,
|
||||
+ .hbp = 80,
|
||||
+ .vfp = 3,
|
||||
+ .vsw = 4,
|
||||
+ .vbp = 11,
|
||||
+ .pixel_clock = 35500,
|
||||
+
|
||||
+#elif defined CONFIG_FB_OMAP_079M3R
|
||||
+
|
||||
+ /* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
|
||||
+ .x_res = 1024,
|
||||
+ .y_res = 768,
|
||||
+ .hfp = 48,
|
||||
+ .hsw = 32,
|
||||
+ .hbp = 80,
|
||||
+ .vfp = 3,
|
||||
+ .vsw = 4,
|
||||
+ .vbp = 15,
|
||||
+ .pixel_clock = 56000,
|
||||
+
|
||||
+#elif defined CONFIG_FB_OMAP_092M9R
|
||||
+
|
||||
+ /* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.92M9-R */
|
||||
+ .x_res = 1280,
|
||||
+ .y_res = 720,
|
||||
+ .hfp = 48,
|
||||
+ .hsw = 32,
|
||||
+ .hbp = 80,
|
||||
+ .vfp = 3,
|
||||
+ .vsw = 5,
|
||||
+ .vbp = 13,
|
||||
+ .pixel_clock = 64000,
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+ /* use 640 x 480 if no config option */
|
||||
+ /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
|
||||
+ .x_res = 640,
|
||||
+ .y_res = 480,
|
||||
+ .hfp = 48,
|
||||
+ .hsw = 32,
|
||||
+ .hbp = 80,
|
||||
+ .vfp = 3,
|
||||
+ .vsw = 4,
|
||||
+ .vbp = 7,
|
||||
+ .pixel_clock = 23500,
|
||||
+
|
||||
+#endif
|
||||
|
||||
.init = omap3beagle_panel_init,
|
||||
.cleanup = omap3beagle_panel_cleanup,
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Wed, 16 Jul 2008 19:38:43 +0000 (-0700)
|
||||
Subject: omap3beagle: set data rate on i2c-1 to 400, since 2600 seems to be
|
||||
X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=12d6504334a830774ff1d42cee4b7296ac9fb7d2
|
||||
|
||||
omap3beagle: set data rate on i2c-1 to 400, since 2600 seems to be
|
||||
flakey
|
||||
---
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
index fdce787..938ad73 100644
|
||||
--- a/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
@@ -39,7 +39,7 @@ static struct omap_uart_config omap3_beagle_uart_config __initdata = {
|
||||
|
||||
static int __init omap3_beagle_i2c_init(void)
|
||||
{
|
||||
- omap_register_i2c_bus(1, 2600, NULL, 0);
|
||||
+ omap_register_i2c_bus(1, 400, NULL, 0);
|
||||
omap_register_i2c_bus(2, 400, NULL, 0);
|
||||
omap_register_i2c_bus(3, 400, NULL, 0);
|
||||
return 0;
|
||||
@@ -0,0 +1,38 @@
|
||||
From: Purushotam Kumar <purushotam@ti.com>
|
||||
Date: Fri, 18 Jul 2008 23:28:57 +0000 (-0700)
|
||||
Subject: OMAP3:devices.c:Enabling 4-bit for SD card
|
||||
X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=6c4d34031c80ca4b50ffe73a4ef7fe197a760a60
|
||||
|
||||
OMAP3:devices.c:Enabling 4-bit for SD card
|
||||
|
||||
SD card was working in 1-bit mode.This patch will configure SD card in
|
||||
4-bit mode and hence performance will increase.
|
||||
|
||||
Signed-off-by: Purushotam Kumar <purushotam@ti.com>
|
||||
Acked-by: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
|
||||
---
|
||||
|
||||
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
|
||||
index b83f9a6..d0cfceb 100644
|
||||
--- a/arch/arm/plat-omap/devices.c
|
||||
+++ b/arch/arm/plat-omap/devices.c
|
||||
@@ -296,13 +296,17 @@ static void __init omap_init_mmc(void)
|
||||
mmc = &mmc_conf->mmc[0];
|
||||
|
||||
if (cpu_is_omap2430() || cpu_is_omap34xx()) {
|
||||
- if (mmc->enabled)
|
||||
+ if (mmc->enabled) {
|
||||
+ mmc1_data.conf = *mmc;
|
||||
(void) platform_device_register(&mmc_omap_device1);
|
||||
+ }
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
|
||||
mmc = &mmc_conf->mmc[1];
|
||||
- if (mmc->enabled)
|
||||
+ if (mmc->enabled) {
|
||||
+ mmc2_data.conf = *mmc;
|
||||
(void) platform_device_register(&mmc_omap_device2);
|
||||
+ }
|
||||
#endif
|
||||
|
||||
return;
|
||||
@@ -0,0 +1,43 @@
|
||||
TWL4030: remove superfluous PWR interrupt status clear before masking
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
twl_irq_init() clears PWR interrupt status bits, then masks the interrupts
|
||||
off, then clears the PWR interrupt status bits again. The first clear
|
||||
seems unnecessary, so, remove it.
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/chips/twl4030-core.c | 18 ------------------
|
||||
1 files changed, 0 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
|
||||
index adc45d4..ff662bc 100644
|
||||
--- a/drivers/i2c/chips/twl4030-core.c
|
||||
+++ b/drivers/i2c/chips/twl4030-core.c
|
||||
@@ -719,24 +719,6 @@ static void twl_init_irq(void)
|
||||
char *msg = "Unable to register interrupt subsystem";
|
||||
unsigned int irq_num;
|
||||
|
||||
- /*
|
||||
- * We end up with interrupts from other modules before
|
||||
- * they get a chance to handle them...
|
||||
- */
|
||||
- /* PWR_ISR1 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x00);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* PWR_ISR2 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x02);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
/* PWR_IMR1 */
|
||||
res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
|
||||
if (res < 0) {
|
||||
@@ -0,0 +1,71 @@
|
||||
TWL4030: clear TWL GPIO interrupt status registers
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
twl_init_irq() does not clear the TWL GPIO ISR registers, but the PIH
|
||||
ISR thinks that it has. This causes any previously-latched GPIO interrupts
|
||||
to be stuck on until twl4030-gpio.c initializes, often drowning the console in
|
||||
|
||||
TWL4030 module irq 368 is disabled but can't be masked!
|
||||
|
||||
messages. This seems to be a particular problem when booting on Beagle.
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/chips/twl4030-core.c | 42 ++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 42 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
|
||||
index ff662bc..dfc3805 100644
|
||||
--- a/drivers/i2c/chips/twl4030-core.c
|
||||
+++ b/drivers/i2c/chips/twl4030-core.c
|
||||
@@ -857,6 +857,48 @@ static void twl_init_irq(void)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* GPIO_ISR1A */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x19);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* GPIO_ISR2A */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1a);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* GPIO_ISR3A */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1b);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* GPIO_ISR1B */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1f);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* GPIO_ISR2B */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x20);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* GPIO_ISR3B */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x21);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* install an irq handler for each of the PIH modules */
|
||||
for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {
|
||||
set_irq_chip(i, &twl4030_irq_chip);
|
||||
@@ -0,0 +1,82 @@
|
||||
TWL4030: use correct register addresses for BCI IMR registers
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
The existing code to mask and clear BCI interrupts in twl_init_irq() is
|
||||
wrong. It uses the wrong register offsets, it does not mask all of the
|
||||
BCI IMR registers, and it does not clear all of the BCI ISR registers.
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/chips/twl4030-core.c | 40 ++++++++++++++++++++++++++++++++------
|
||||
1 files changed, 34 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
|
||||
index dfc3805..bb0732c 100644
|
||||
--- a/drivers/i2c/chips/twl4030-core.c
|
||||
+++ b/drivers/i2c/chips/twl4030-core.c
|
||||
@@ -750,29 +750,57 @@ static void twl_init_irq(void)
|
||||
/* POWER HACK (END) */
|
||||
/* Slave address 0x4A */
|
||||
|
||||
- /* BCIIMR1_1 */
|
||||
+ /* BCIIMR1A */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x2);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* BCIIMR2A */
|
||||
res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x3);
|
||||
if (res < 0) {
|
||||
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
- /* BCIIMR1_2 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
|
||||
+ /* BCIIMR1B */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x6);
|
||||
if (res < 0) {
|
||||
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
- /* BCIIMR2_1 */
|
||||
+ /* BCIIMR2B */
|
||||
res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x7);
|
||||
if (res < 0) {
|
||||
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
- /* BCIIMR2_2 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x8);
|
||||
+ /* BCIISR1A */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x0);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* BCIISR2A */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x1);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* BCIISR1B */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* BCIISR2B */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x5);
|
||||
if (res < 0) {
|
||||
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
return;
|
||||
@@ -0,0 +1,38 @@
|
||||
TWL4030: clear MADC interrupt status registers upon init
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
twl_init_irq() does not clear MADC interrupt status registers upon init -
|
||||
fix.
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/chips/twl4030-core.c | 14 ++++++++++++++
|
||||
1 files changed, 14 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
|
||||
index bb0732c..9d93524 100644
|
||||
--- a/drivers/i2c/chips/twl4030-core.c
|
||||
+++ b/drivers/i2c/chips/twl4030-core.c
|
||||
@@ -821,6 +821,20 @@ static void twl_init_irq(void)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* MADC_ISR1 */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x61);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* MADC_ISR2 */
|
||||
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x63);
|
||||
+ if (res < 0) {
|
||||
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* key Pad */
|
||||
/* KEYPAD - IMR1 */
|
||||
res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x12));
|
||||
@@ -0,0 +1,303 @@
|
||||
TWL4030: use *_SIH_CTRL.COR bit to determine whether to read or write ISR to clear
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
TWL4030 interrupt status register bits can be cleared in one of two ways:
|
||||
either by reading from the register, or by writing a 1 to the
|
||||
appropriate bit(s) in the register. This behavior can be altered at any
|
||||
time by the <twlmodule>_SIH_CTRL.COR register bit ("clear-on-read").
|
||||
|
||||
The TWL4030 TRM is deeply confused as to whether COR=1 means that the
|
||||
registers are cleared on reads, or cleared on writes. Peter De
|
||||
Schrijver <peter.de-schrijver> confirms that COR=1 means that the registers
|
||||
are cleared on read.
|
||||
|
||||
So, for each TWL4030 SIH, check the value of the *_SIH_CTRL.COR bit, and if
|
||||
it is 1, use reads to clear the ISRs; if it is 0, use writes.
|
||||
|
||||
Also, use WARN_ON() to warn if the read/write failed, and don't skip
|
||||
the rest of the initialization on failure either.
|
||||
|
||||
Thanks to Peter for his help with this patch.
|
||||
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/chips/twl4030-core.c | 183 ++++++++++++++++++++++----------------
|
||||
1 files changed, 106 insertions(+), 77 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
|
||||
index 9d93524..eae0634 100644
|
||||
--- a/drivers/i2c/chips/twl4030-core.c
|
||||
+++ b/drivers/i2c/chips/twl4030-core.c
|
||||
@@ -133,6 +133,16 @@
|
||||
/* on I2C-1 for 2430SDP */
|
||||
#define CONFIG_I2C_TWL4030_ID 1
|
||||
|
||||
+/* SIH_CTRL registers */
|
||||
+#define TWL4030_INT_PWR_SIH_CTRL 0x07
|
||||
+#define TWL4030_INTERRUPTS_BCISIHCTRL 0x0d
|
||||
+#define TWL4030_MADC_MADC_SIH_CTRL 0x67
|
||||
+#define TWL4030_KEYPAD_KEYP_SIH_CTRL 0x17
|
||||
+#define TWL4030_GPIO_GPIO_SIH_CTRL 0x2d
|
||||
+
|
||||
+#define TWL4030_SIH_CTRL_COR_MASK (1 << 2)
|
||||
+
|
||||
+
|
||||
/* Helper functions */
|
||||
static int
|
||||
twl4030_detect_client(struct i2c_adapter *adapter, unsigned char sid);
|
||||
@@ -712,13 +722,61 @@ static int power_companion_init(void)
|
||||
return e;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * twl4030_i2c_clear_isr - clear TWL4030 SIH ISR regs via read + write
|
||||
+ * @mod_no: TWL4030 module number
|
||||
+ * @reg: register index to clear
|
||||
+ * @cor: value of the <module>_SIH_CTRL.COR bit (1 or 0)
|
||||
+ *
|
||||
+ * Either reads (cor == 1) or writes (cor == 0) to a TWL4030 interrupt
|
||||
+ * status register to ensure that any prior interrupts are cleared.
|
||||
+ * Returns the status from the I2C read operation.
|
||||
+ */
|
||||
+static int twl4030_i2c_clear_isr(u8 mod_no, u8 reg, u8 cor)
|
||||
+{
|
||||
+ u8 tmp;
|
||||
+
|
||||
+ return (cor) ? twl4030_i2c_read_u8(mod_no, &tmp, reg) :
|
||||
+ twl4030_i2c_write_u8(mod_no, 0xff, reg);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * twl4030_read_cor_bit - are TWL module ISRs cleared by reads or writes?
|
||||
+ * @mod_no: TWL4030 module number
|
||||
+ * @reg: register index to clear
|
||||
+ *
|
||||
+ * Returns 1 if the TWL4030 SIH interrupt status registers (ISRs) for
|
||||
+ * the specified TWL module are cleared by reads, or 0 if cleared by
|
||||
+ * writes.
|
||||
+ */
|
||||
+static int twl4030_read_cor_bit(u8 mod_no, u8 reg)
|
||||
+{
|
||||
+ u8 tmp = 0;
|
||||
+
|
||||
+ WARN_ON(twl4030_i2c_read_u8(mod_no, &tmp, reg) < 0);
|
||||
+
|
||||
+ tmp &= TWL4030_SIH_CTRL_COR_MASK;
|
||||
+ tmp >>= __ffs(TWL4030_SIH_CTRL_COR_MASK);
|
||||
+
|
||||
+ return tmp;
|
||||
+}
|
||||
+
|
||||
static void twl_init_irq(void)
|
||||
{
|
||||
int i = 0;
|
||||
int res = 0;
|
||||
+ int cor;
|
||||
char *msg = "Unable to register interrupt subsystem";
|
||||
unsigned int irq_num;
|
||||
|
||||
+ /*
|
||||
+ * For each TWL4030 module with ISR/IMR registers, mask all
|
||||
+ * interrupts and then clear any existing interrupt status bits,
|
||||
+ * since we initially do not have any TWL4030 module interrupt
|
||||
+ * handlers present.
|
||||
+ */
|
||||
+
|
||||
+
|
||||
/* PWR_IMR1 */
|
||||
res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
|
||||
if (res < 0) {
|
||||
@@ -734,20 +792,18 @@ static void twl_init_irq(void)
|
||||
}
|
||||
|
||||
/* Clear off any other pending interrupts on power */
|
||||
+
|
||||
+ /* Are PWR interrupt status bits cleared by reads or writes? */
|
||||
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_INT,
|
||||
+ TWL4030_INT_PWR_SIH_CTRL);
|
||||
+ WARN_ON(cor < 0);
|
||||
+
|
||||
/* PWR_ISR1 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x00);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x00, cor) < 0);
|
||||
|
||||
/* PWR_ISR2 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x02);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
- /* POWER HACK (END) */
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x02, cor) < 0);
|
||||
+
|
||||
/* Slave address 0x4A */
|
||||
|
||||
/* BCIIMR1A */
|
||||
@@ -778,33 +834,22 @@ static void twl_init_irq(void)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* Are BCI interrupt status bits cleared by reads or writes? */
|
||||
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_INTERRUPTS,
|
||||
+ TWL4030_INTERRUPTS_BCISIHCTRL);
|
||||
+ WARN_ON(cor < 0);
|
||||
+
|
||||
/* BCIISR1A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x0);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x0, cor) < 0);
|
||||
|
||||
/* BCIISR2A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x1);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x1, cor) < 0);
|
||||
|
||||
/* BCIISR1B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x4, cor) < 0);
|
||||
|
||||
/* BCIISR2B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x5);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x5, cor) < 0);
|
||||
|
||||
/* MAD C */
|
||||
/* MADC_IMR1 */
|
||||
@@ -821,19 +866,16 @@ static void twl_init_irq(void)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* Are MADC interrupt status bits cleared by reads or writes? */
|
||||
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_MADC,
|
||||
+ TWL4030_MADC_MADC_SIH_CTRL);
|
||||
+ WARN_ON(cor < 0);
|
||||
+
|
||||
/* MADC_ISR1 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x61);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x61, cor) < 0);
|
||||
|
||||
/* MADC_ISR2 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x63);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x63, cor) < 0);
|
||||
|
||||
/* key Pad */
|
||||
/* KEYPAD - IMR1 */
|
||||
@@ -842,12 +884,15 @@ static void twl_init_irq(void)
|
||||
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
return;
|
||||
}
|
||||
- {
|
||||
- u8 clear;
|
||||
- /* Clear ISR */
|
||||
- twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
|
||||
- twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
|
||||
- }
|
||||
+
|
||||
+ /* Are keypad interrupt status bits cleared by reads or writes? */
|
||||
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_KEYPAD,
|
||||
+ TWL4030_KEYPAD_KEYP_SIH_CTRL);
|
||||
+ WARN_ON(cor < 0);
|
||||
+
|
||||
+ /* KEYPAD - ISR1 */
|
||||
+ /* XXX does this still need to be done twice for some reason? */
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x11, cor) < 0);
|
||||
|
||||
/* KEYPAD - IMR2 */
|
||||
res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x14));
|
||||
@@ -856,6 +901,9 @@ static void twl_init_irq(void)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* KEYPAD - ISR2 */
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x13, cor) < 0);
|
||||
+
|
||||
/* Slave address 0x49 */
|
||||
/* GPIO_IMR1A */
|
||||
res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1C));
|
||||
@@ -899,47 +947,28 @@ static void twl_init_irq(void)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* Are GPIO interrupt status bits cleared by reads or writes? */
|
||||
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_GPIO,
|
||||
+ TWL4030_GPIO_GPIO_SIH_CTRL);
|
||||
+ WARN_ON(cor < 0);
|
||||
+
|
||||
/* GPIO_ISR1A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x19);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x19, cor) < 0);
|
||||
|
||||
/* GPIO_ISR2A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1a);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1a, cor) < 0);
|
||||
|
||||
/* GPIO_ISR3A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1b);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1b, cor) < 0);
|
||||
|
||||
/* GPIO_ISR1B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1f);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1f, cor) < 0);
|
||||
|
||||
/* GPIO_ISR2B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x20);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x20, cor) < 0);
|
||||
|
||||
/* GPIO_ISR3B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x21);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x21, cor) < 0);
|
||||
|
||||
/* install an irq handler for each of the PIH modules */
|
||||
for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {
|
||||
@@ -0,0 +1,179 @@
|
||||
TWL4030: change init-time IMR mask code to WARN if error
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
twl_init_irq() prints error messages and returns if any interrupt mask
|
||||
register writes fail. Change this to generate a warning traceback and
|
||||
to continue execution rather than skipping TWL init. (These mask
|
||||
writes should not fail at all unless either the I2C bus or the TWL4030
|
||||
is somehow wedged.)
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/chips/twl4030-core.c | 100 +++++++-------------------------------
|
||||
1 files changed, 18 insertions(+), 82 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
|
||||
index eae0634..99cc143 100644
|
||||
--- a/drivers/i2c/chips/twl4030-core.c
|
||||
+++ b/drivers/i2c/chips/twl4030-core.c
|
||||
@@ -778,18 +778,10 @@ static void twl_init_irq(void)
|
||||
|
||||
|
||||
/* PWR_IMR1 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff, 0x1) < 0);
|
||||
|
||||
/* PWR_IMR2 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x3);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff, 0x3) < 0);
|
||||
|
||||
/* Clear off any other pending interrupts on power */
|
||||
|
||||
@@ -807,32 +799,16 @@ static void twl_init_irq(void)
|
||||
/* Slave address 0x4A */
|
||||
|
||||
/* BCIIMR1A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x2);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x2) < 0);
|
||||
|
||||
- /* BCIIMR2A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x3);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ /* BCIIMR2A */
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x3) < 0);
|
||||
|
||||
- /* BCIIMR1B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x6);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ /* BCIIMR2A */
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x6) < 0);
|
||||
|
||||
/* BCIIMR2B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x7);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x7) < 0);
|
||||
|
||||
/* Are BCI interrupt status bits cleared by reads or writes? */
|
||||
cor = twl4030_read_cor_bit(TWL4030_MODULE_INTERRUPTS,
|
||||
@@ -853,18 +829,10 @@ static void twl_init_irq(void)
|
||||
|
||||
/* MAD C */
|
||||
/* MADC_IMR1 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x62);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff, 0x62) < 0);
|
||||
|
||||
/* MADC_IMR2 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x64);
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff, 0x64) < 0);
|
||||
|
||||
/* Are MADC interrupt status bits cleared by reads or writes? */
|
||||
cor = twl4030_read_cor_bit(TWL4030_MODULE_MADC,
|
||||
@@ -879,11 +847,7 @@ static void twl_init_irq(void)
|
||||
|
||||
/* key Pad */
|
||||
/* KEYPAD - IMR1 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x12));
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff, 0x12) < 0);
|
||||
|
||||
/* Are keypad interrupt status bits cleared by reads or writes? */
|
||||
cor = twl4030_read_cor_bit(TWL4030_MODULE_KEYPAD,
|
||||
@@ -895,57 +859,29 @@ static void twl_init_irq(void)
|
||||
WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x11, cor) < 0);
|
||||
|
||||
/* KEYPAD - IMR2 */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x14));
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff, 0x14) < 0);
|
||||
|
||||
/* KEYPAD - ISR2 */
|
||||
WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x13, cor) < 0);
|
||||
|
||||
/* Slave address 0x49 */
|
||||
/* GPIO_IMR1A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1C));
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1c) < 0);
|
||||
|
||||
/* GPIO_IMR2A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1D));
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1d) < 0);
|
||||
|
||||
/* GPIO_IMR3A */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1E));
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1e) < 0);
|
||||
|
||||
/* GPIO_IMR1B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x22));
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x22) < 0);
|
||||
|
||||
/* GPIO_IMR2B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x23));
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x23) < 0);
|
||||
|
||||
/* GPIO_IMR3B */
|
||||
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x24));
|
||||
- if (res < 0) {
|
||||
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
|
||||
- return;
|
||||
- }
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x24) < 0);
|
||||
|
||||
/* Are GPIO interrupt status bits cleared by reads or writes? */
|
||||
cor = twl4030_read_cor_bit(TWL4030_MODULE_GPIO,
|
||||
@@ -0,0 +1,274 @@
|
||||
TWL4030: move TWL module register defs into separate include files
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
twl_init_irq() uses "magic numbers" to access TWL module IMR and ISR
|
||||
registers. Symbolic constants are definitely preferred.
|
||||
|
||||
Rather than duplicating already existing symbolic constants in
|
||||
twl4030-gpio.c and twl4030-pwrirq.c, move the existing constants out
|
||||
into include files. This patch should not change kernel behavior.
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/chips/twl4030-gpio.c | 48 -----------------------
|
||||
drivers/i2c/chips/twl4030-pwrirq.c | 15 +++----
|
||||
include/linux/i2c/twl4030-gpio.h | 76 ++++++++++++++++++++++++++++++++++++
|
||||
include/linux/i2c/twl4030-pwrirq.h | 37 ++++++++++++++++++
|
||||
4 files changed, 121 insertions(+), 55 deletions(-)
|
||||
create mode 100644 include/linux/i2c/twl4030-gpio.h
|
||||
create mode 100644 include/linux/i2c/twl4030-pwrirq.h
|
||||
|
||||
diff --git a/drivers/i2c/chips/twl4030-gpio.c b/drivers/i2c/chips/twl4030-gpio.c
|
||||
index f16a48b..9d17f45 100644
|
||||
--- a/drivers/i2c/chips/twl4030-gpio.c
|
||||
+++ b/drivers/i2c/chips/twl4030-gpio.c
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/twl4030.h>
|
||||
+#include <linux/i2c/twl4030-gpio.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/arch/irqs.h>
|
||||
@@ -47,53 +48,6 @@
|
||||
|
||||
#include <linux/device.h>
|
||||
|
||||
-/*
|
||||
- * GPIO Block Register definitions
|
||||
- */
|
||||
-
|
||||
-#define REG_GPIODATAIN1 0x0
|
||||
-#define REG_GPIODATAIN2 0x1
|
||||
-#define REG_GPIODATAIN3 0x2
|
||||
-#define REG_GPIODATADIR1 0x3
|
||||
-#define REG_GPIODATADIR2 0x4
|
||||
-#define REG_GPIODATADIR3 0x5
|
||||
-#define REG_GPIODATAOUT1 0x6
|
||||
-#define REG_GPIODATAOUT2 0x7
|
||||
-#define REG_GPIODATAOUT3 0x8
|
||||
-#define REG_CLEARGPIODATAOUT1 0x9
|
||||
-#define REG_CLEARGPIODATAOUT2 0xA
|
||||
-#define REG_CLEARGPIODATAOUT3 0xB
|
||||
-#define REG_SETGPIODATAOUT1 0xC
|
||||
-#define REG_SETGPIODATAOUT2 0xD
|
||||
-#define REG_SETGPIODATAOUT3 0xE
|
||||
-#define REG_GPIO_DEBEN1 0xF
|
||||
-#define REG_GPIO_DEBEN2 0x10
|
||||
-#define REG_GPIO_DEBEN3 0x11
|
||||
-#define REG_GPIO_CTRL 0x12
|
||||
-#define REG_GPIOPUPDCTR1 0x13
|
||||
-#define REG_GPIOPUPDCTR2 0x14
|
||||
-#define REG_GPIOPUPDCTR3 0x15
|
||||
-#define REG_GPIOPUPDCTR4 0x16
|
||||
-#define REG_GPIOPUPDCTR5 0x17
|
||||
-#define REG_GPIO_ISR1A 0x19
|
||||
-#define REG_GPIO_ISR2A 0x1A
|
||||
-#define REG_GPIO_ISR3A 0x1B
|
||||
-#define REG_GPIO_IMR1A 0x1C
|
||||
-#define REG_GPIO_IMR2A 0x1D
|
||||
-#define REG_GPIO_IMR3A 0x1E
|
||||
-#define REG_GPIO_ISR1B 0x1F
|
||||
-#define REG_GPIO_ISR2B 0x20
|
||||
-#define REG_GPIO_ISR3B 0x21
|
||||
-#define REG_GPIO_IMR1B 0x22
|
||||
-#define REG_GPIO_IMR2B 0x23
|
||||
-#define REG_GPIO_IMR3B 0x24
|
||||
-#define REG_GPIO_EDR1 0x28
|
||||
-#define REG_GPIO_EDR2 0x29
|
||||
-#define REG_GPIO_EDR3 0x2A
|
||||
-#define REG_GPIO_EDR4 0x2B
|
||||
-#define REG_GPIO_EDR5 0x2C
|
||||
-#define REG_GPIO_SIH_CTRL 0x2D
|
||||
-
|
||||
/* BitField Definitions */
|
||||
|
||||
/* Data banks : 3 banks for 8 gpios each */
|
||||
diff --git a/drivers/i2c/chips/twl4030-pwrirq.c b/drivers/i2c/chips/twl4030-pwrirq.c
|
||||
index a4d2e92..1afdb65 100644
|
||||
--- a/drivers/i2c/chips/twl4030-pwrirq.c
|
||||
+++ b/drivers/i2c/chips/twl4030-pwrirq.c
|
||||
@@ -27,10 +27,8 @@
|
||||
#include <linux/random.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/i2c/twl4030.h>
|
||||
+#include <linux/i2c/twl4030-pwrirq.h>
|
||||
|
||||
-#define PWR_ISR1 0
|
||||
-#define PWR_IMR1 1
|
||||
-#define PWR_SIH_CTRL 7
|
||||
#define PWR_SIH_CTRL_COR (1<<2)
|
||||
|
||||
static u8 twl4030_pwrirq_mask;
|
||||
@@ -93,7 +91,8 @@ static void do_twl4030_pwrmodule_irq(unsigned int irq, irq_desc_t *desc)
|
||||
twl4030_pwrirq_mask |= 1 << (irq - TWL4030_PWR_IRQ_BASE);
|
||||
local_irq_enable();
|
||||
twl4030_i2c_write_u8(TWL4030_MODULE_INT,
|
||||
- twl4030_pwrirq_mask, PWR_IMR1);
|
||||
+ twl4030_pwrirq_mask,
|
||||
+ TWL4030_INT_PWR_IMR1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +114,7 @@ static void do_twl4030_pwrirq(unsigned int irq, irq_desc_t *desc)
|
||||
|
||||
local_irq_enable();
|
||||
ret = twl4030_i2c_read_u8(TWL4030_MODULE_INT, &pwr_isr,
|
||||
- PWR_ISR1);
|
||||
+ TWL4030_INT_PWR_ISR1);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING
|
||||
"I2C error %d while reading TWL4030"
|
||||
@@ -151,7 +150,7 @@ static int twl4030_pwrirq_thread(void *data)
|
||||
twl4030_pwrirq_mask &= ~local_unmask;
|
||||
|
||||
twl4030_i2c_write_u8(TWL4030_MODULE_INT, twl4030_pwrirq_mask,
|
||||
- PWR_IMR1);
|
||||
+ TWL4030_INT_PWR_IMR1);
|
||||
|
||||
local_irq_disable();
|
||||
if (!twl4030_pwrirq_pending_unmask)
|
||||
@@ -172,14 +171,14 @@ static int __init twl4030_pwrirq_init(void)
|
||||
twl4030_pwrirq_pending_unmask = 0;
|
||||
|
||||
err = twl4030_i2c_write_u8(TWL4030_MODULE_INT, twl4030_pwrirq_mask,
|
||||
- PWR_IMR1);
|
||||
+ TWL4030_INT_PWR_IMR1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Enable clear on read */
|
||||
|
||||
err = twl4030_i2c_write_u8(TWL4030_MODULE_INT, PWR_SIH_CTRL_COR,
|
||||
- PWR_SIH_CTRL);
|
||||
+ TWL4030_INT_PWR_SIH_CTRL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
diff --git a/include/linux/i2c/twl4030-gpio.h b/include/linux/i2c/twl4030-gpio.h
|
||||
new file mode 100644
|
||||
index 0000000..7cbf610
|
||||
--- /dev/null
|
||||
+++ b/include/linux/i2c/twl4030-gpio.h
|
||||
@@ -0,0 +1,76 @@
|
||||
+/*
|
||||
+ * twl4030-gpio.h - header for TWL4030 GPIO module
|
||||
+ *
|
||||
+ * Copyright (C) 2005-2006, 2008 Texas Instruments, Inc.
|
||||
+ * Copyright (C) 2008 Nokia Corporation
|
||||
+ *
|
||||
+ * Based on tlv320aic23.c:
|
||||
+ * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __TWL4030_GPIO_H_
|
||||
+#define __TWL4030_GPIO_H_
|
||||
+
|
||||
+/*
|
||||
+ * GPIO Block Register definitions
|
||||
+ */
|
||||
+
|
||||
+#define REG_GPIODATAIN1 0x0
|
||||
+#define REG_GPIODATAIN2 0x1
|
||||
+#define REG_GPIODATAIN3 0x2
|
||||
+#define REG_GPIODATADIR1 0x3
|
||||
+#define REG_GPIODATADIR2 0x4
|
||||
+#define REG_GPIODATADIR3 0x5
|
||||
+#define REG_GPIODATAOUT1 0x6
|
||||
+#define REG_GPIODATAOUT2 0x7
|
||||
+#define REG_GPIODATAOUT3 0x8
|
||||
+#define REG_CLEARGPIODATAOUT1 0x9
|
||||
+#define REG_CLEARGPIODATAOUT2 0xA
|
||||
+#define REG_CLEARGPIODATAOUT3 0xB
|
||||
+#define REG_SETGPIODATAOUT1 0xC
|
||||
+#define REG_SETGPIODATAOUT2 0xD
|
||||
+#define REG_SETGPIODATAOUT3 0xE
|
||||
+#define REG_GPIO_DEBEN1 0xF
|
||||
+#define REG_GPIO_DEBEN2 0x10
|
||||
+#define REG_GPIO_DEBEN3 0x11
|
||||
+#define REG_GPIO_CTRL 0x12
|
||||
+#define REG_GPIOPUPDCTR1 0x13
|
||||
+#define REG_GPIOPUPDCTR2 0x14
|
||||
+#define REG_GPIOPUPDCTR3 0x15
|
||||
+#define REG_GPIOPUPDCTR4 0x16
|
||||
+#define REG_GPIOPUPDCTR5 0x17
|
||||
+#define REG_GPIO_ISR1A 0x19
|
||||
+#define REG_GPIO_ISR2A 0x1A
|
||||
+#define REG_GPIO_ISR3A 0x1B
|
||||
+#define REG_GPIO_IMR1A 0x1C
|
||||
+#define REG_GPIO_IMR2A 0x1D
|
||||
+#define REG_GPIO_IMR3A 0x1E
|
||||
+#define REG_GPIO_ISR1B 0x1F
|
||||
+#define REG_GPIO_ISR2B 0x20
|
||||
+#define REG_GPIO_ISR3B 0x21
|
||||
+#define REG_GPIO_IMR1B 0x22
|
||||
+#define REG_GPIO_IMR2B 0x23
|
||||
+#define REG_GPIO_IMR3B 0x24
|
||||
+#define REG_GPIO_EDR1 0x28
|
||||
+#define REG_GPIO_EDR2 0x29
|
||||
+#define REG_GPIO_EDR3 0x2A
|
||||
+#define REG_GPIO_EDR4 0x2B
|
||||
+#define REG_GPIO_EDR5 0x2C
|
||||
+#define REG_GPIO_SIH_CTRL 0x2D
|
||||
+
|
||||
+#endif /* End of __TWL4030_GPIO_H */
|
||||
diff --git a/include/linux/i2c/twl4030-pwrirq.h b/include/linux/i2c/twl4030-pwrirq.h
|
||||
new file mode 100644
|
||||
index 0000000..7a13368
|
||||
--- /dev/null
|
||||
+++ b/include/linux/i2c/twl4030-pwrirq.h
|
||||
@@ -0,0 +1,37 @@
|
||||
+/*
|
||||
+ * twl4030-gpio.h - header for TWL4030 GPIO module
|
||||
+ *
|
||||
+ * Copyright (C) 2008 Texas Instruments, Inc.
|
||||
+ * Copyright (C) 2008 Nokia Corporation
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __TWL4030_PWRIRQ_H_
|
||||
+#define __TWL4030_PWRIRQ_H_
|
||||
+
|
||||
+/*
|
||||
+ * INT Module Register definitions
|
||||
+ * (not all registers are defined below)
|
||||
+ */
|
||||
+
|
||||
+#define TWL4030_INT_PWR_ISR1 0x0
|
||||
+#define TWL4030_INT_PWR_IMR1 0x1
|
||||
+#define TWL4030_INT_PWR_ISR2 0x2
|
||||
+#define TWL4030_INT_PWR_IMR2 0x3
|
||||
+#define TWL4030_INT_PWR_SIH_CTRL 0x7
|
||||
+
|
||||
+#endif /* End of __TWL4030_PWRIRQ_H */
|
||||
@@ -0,0 +1,278 @@
|
||||
TWL4030: use symbolic ISR/IMR register names during twl_init_irq()
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
twl_init_irq() uses a bunch of magic numbers as register indices; this
|
||||
has already led to several errors, fixed earlier in this patch series.
|
||||
Now use descriptive macros instead of magic numbers. This patch should
|
||||
not change kernel behavior.
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/chips/twl4030-core.c | 188 +++++++++++++++++++-------------------
|
||||
1 files changed, 96 insertions(+), 92 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
|
||||
index 99cc143..38c227a 100644
|
||||
--- a/drivers/i2c/chips/twl4030-core.c
|
||||
+++ b/drivers/i2c/chips/twl4030-core.c
|
||||
@@ -40,6 +40,9 @@
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/twl4030.h>
|
||||
+#include <linux/i2c/twl4030-gpio.h>
|
||||
+#include <linux/i2c/twl4030-madc.h>
|
||||
+#include <linux/i2c/twl4030-pwrirq.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
@@ -114,6 +117,23 @@
|
||||
#define TWL4030_BASEADD_RTC 0x001C
|
||||
#define TWL4030_BASEADD_SECURED_REG 0x0000
|
||||
|
||||
+/* TWL4030 BCI registers */
|
||||
+#define TWL4030_INTERRUPTS_BCIIMR1A 0x2
|
||||
+#define TWL4030_INTERRUPTS_BCIIMR2A 0x3
|
||||
+#define TWL4030_INTERRUPTS_BCIIMR1B 0x6
|
||||
+#define TWL4030_INTERRUPTS_BCIIMR2B 0x7
|
||||
+#define TWL4030_INTERRUPTS_BCIISR1A 0x0
|
||||
+#define TWL4030_INTERRUPTS_BCIISR2A 0x1
|
||||
+#define TWL4030_INTERRUPTS_BCIISR1B 0x4
|
||||
+#define TWL4030_INTERRUPTS_BCIISR2B 0x5
|
||||
+
|
||||
+/* TWL4030 keypad registers */
|
||||
+#define TWL4030_KEYPAD_KEYP_IMR1 0x12
|
||||
+#define TWL4030_KEYPAD_KEYP_IMR2 0x14
|
||||
+#define TWL4030_KEYPAD_KEYP_ISR1 0x11
|
||||
+#define TWL4030_KEYPAD_KEYP_ISR2 0x13
|
||||
+
|
||||
+
|
||||
/* Triton Core internal information (END) */
|
||||
|
||||
/* Few power values */
|
||||
@@ -133,12 +153,10 @@
|
||||
/* on I2C-1 for 2430SDP */
|
||||
#define CONFIG_I2C_TWL4030_ID 1
|
||||
|
||||
-/* SIH_CTRL registers */
|
||||
-#define TWL4030_INT_PWR_SIH_CTRL 0x07
|
||||
+/* SIH_CTRL registers that aren't defined elsewhere */
|
||||
#define TWL4030_INTERRUPTS_BCISIHCTRL 0x0d
|
||||
#define TWL4030_MADC_MADC_SIH_CTRL 0x67
|
||||
#define TWL4030_KEYPAD_KEYP_SIH_CTRL 0x17
|
||||
-#define TWL4030_GPIO_GPIO_SIH_CTRL 0x2d
|
||||
|
||||
#define TWL4030_SIH_CTRL_COR_MASK (1 << 2)
|
||||
|
||||
@@ -776,135 +794,121 @@ static void twl_init_irq(void)
|
||||
* handlers present.
|
||||
*/
|
||||
|
||||
-
|
||||
- /* PWR_IMR1 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff, 0x1) < 0);
|
||||
-
|
||||
- /* PWR_IMR2 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff, 0x3) < 0);
|
||||
-
|
||||
- /* Clear off any other pending interrupts on power */
|
||||
+ /* Mask INT (PWR) interrupts at TWL4030 */
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
|
||||
+ TWL4030_INT_PWR_IMR1) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
|
||||
+ TWL4030_INT_PWR_IMR2) < 0);
|
||||
|
||||
/* Are PWR interrupt status bits cleared by reads or writes? */
|
||||
cor = twl4030_read_cor_bit(TWL4030_MODULE_INT,
|
||||
TWL4030_INT_PWR_SIH_CTRL);
|
||||
WARN_ON(cor < 0);
|
||||
|
||||
- /* PWR_ISR1 */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x00, cor) < 0);
|
||||
-
|
||||
- /* PWR_ISR2 */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x02, cor) < 0);
|
||||
+ /* Clear TWL4030 INT (PWR) ISRs */
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
|
||||
+ TWL4030_INT_PWR_ISR1, cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
|
||||
+ TWL4030_INT_PWR_ISR2, cor) < 0);
|
||||
|
||||
/* Slave address 0x4A */
|
||||
|
||||
- /* BCIIMR1A */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x2) < 0);
|
||||
-
|
||||
- /* BCIIMR2A */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x3) < 0);
|
||||
-
|
||||
- /* BCIIMR2A */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x6) < 0);
|
||||
-
|
||||
- /* BCIIMR2B */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x7) < 0);
|
||||
+ /* Mask BCI interrupts at TWL4030 */
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
|
||||
+ TWL4030_INTERRUPTS_BCIIMR1A) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
|
||||
+ TWL4030_INTERRUPTS_BCIIMR2A) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
|
||||
+ TWL4030_INTERRUPTS_BCIIMR1B) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
|
||||
+ TWL4030_INTERRUPTS_BCIIMR2B) < 0);
|
||||
|
||||
/* Are BCI interrupt status bits cleared by reads or writes? */
|
||||
cor = twl4030_read_cor_bit(TWL4030_MODULE_INTERRUPTS,
|
||||
TWL4030_INTERRUPTS_BCISIHCTRL);
|
||||
WARN_ON(cor < 0);
|
||||
|
||||
- /* BCIISR1A */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x0, cor) < 0);
|
||||
-
|
||||
- /* BCIISR2A */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x1, cor) < 0);
|
||||
-
|
||||
- /* BCIISR1B */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x4, cor) < 0);
|
||||
-
|
||||
- /* BCIISR2B */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x5, cor) < 0);
|
||||
+ /* Clear TWL4030 BCI ISRs */
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
|
||||
+ TWL4030_INTERRUPTS_BCIISR1A, cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
|
||||
+ TWL4030_INTERRUPTS_BCIISR2A, cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
|
||||
+ TWL4030_INTERRUPTS_BCIISR1B, cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
|
||||
+ TWL4030_INTERRUPTS_BCIISR2B, cor) < 0);
|
||||
|
||||
/* MAD C */
|
||||
- /* MADC_IMR1 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff, 0x62) < 0);
|
||||
-
|
||||
- /* MADC_IMR2 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff, 0x64) < 0);
|
||||
+ /* Mask MADC interrupts at TWL4030 */
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
|
||||
+ TWL4030_MADC_IMR1) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
|
||||
+ TWL4030_MADC_IMR2) < 0);
|
||||
|
||||
/* Are MADC interrupt status bits cleared by reads or writes? */
|
||||
cor = twl4030_read_cor_bit(TWL4030_MODULE_MADC,
|
||||
TWL4030_MADC_MADC_SIH_CTRL);
|
||||
WARN_ON(cor < 0);
|
||||
|
||||
- /* MADC_ISR1 */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x61, cor) < 0);
|
||||
-
|
||||
- /* MADC_ISR2 */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x63, cor) < 0);
|
||||
+ /* Clear TWL4030 MADC ISRs */
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
|
||||
+ TWL4030_MADC_ISR1, cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
|
||||
+ TWL4030_MADC_ISR2, cor) < 0);
|
||||
|
||||
/* key Pad */
|
||||
- /* KEYPAD - IMR1 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff, 0x12) < 0);
|
||||
+ /* Mask keypad interrupts at TWL4030 */
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
|
||||
+ TWL4030_KEYPAD_KEYP_IMR1) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
|
||||
+ TWL4030_KEYPAD_KEYP_IMR2) < 0);
|
||||
|
||||
/* Are keypad interrupt status bits cleared by reads or writes? */
|
||||
cor = twl4030_read_cor_bit(TWL4030_MODULE_KEYPAD,
|
||||
TWL4030_KEYPAD_KEYP_SIH_CTRL);
|
||||
WARN_ON(cor < 0);
|
||||
|
||||
- /* KEYPAD - ISR1 */
|
||||
+ /* Clear TWL4030 keypad ISRs */
|
||||
/* XXX does this still need to be done twice for some reason? */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x11, cor) < 0);
|
||||
-
|
||||
- /* KEYPAD - IMR2 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff, 0x14) < 0);
|
||||
-
|
||||
- /* KEYPAD - ISR2 */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x13, cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
|
||||
+ TWL4030_KEYPAD_KEYP_ISR1, cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
|
||||
+ TWL4030_KEYPAD_KEYP_ISR2, cor) < 0);
|
||||
|
||||
/* Slave address 0x49 */
|
||||
- /* GPIO_IMR1A */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1c) < 0);
|
||||
-
|
||||
- /* GPIO_IMR2A */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1d) < 0);
|
||||
-
|
||||
- /* GPIO_IMR3A */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1e) < 0);
|
||||
-
|
||||
- /* GPIO_IMR1B */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x22) < 0);
|
||||
|
||||
- /* GPIO_IMR2B */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x23) < 0);
|
||||
-
|
||||
- /* GPIO_IMR3B */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x24) < 0);
|
||||
+ /* Mask GPIO interrupts at TWL4030 */
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
+ REG_GPIO_IMR1A) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
+ REG_GPIO_IMR2A) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
+ REG_GPIO_IMR3A) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
+ REG_GPIO_IMR1B) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
+ REG_GPIO_IMR2B) < 0);
|
||||
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
+ REG_GPIO_IMR3B) < 0);
|
||||
|
||||
/* Are GPIO interrupt status bits cleared by reads or writes? */
|
||||
cor = twl4030_read_cor_bit(TWL4030_MODULE_GPIO,
|
||||
- TWL4030_GPIO_GPIO_SIH_CTRL);
|
||||
+ REG_GPIO_SIH_CTRL);
|
||||
WARN_ON(cor < 0);
|
||||
|
||||
- /* GPIO_ISR1A */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x19, cor) < 0);
|
||||
-
|
||||
- /* GPIO_ISR2A */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1a, cor) < 0);
|
||||
-
|
||||
- /* GPIO_ISR3A */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1b, cor) < 0);
|
||||
-
|
||||
- /* GPIO_ISR1B */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1f, cor) < 0);
|
||||
-
|
||||
- /* GPIO_ISR2B */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x20, cor) < 0);
|
||||
-
|
||||
- /* GPIO_ISR3B */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x21, cor) < 0);
|
||||
+ /* Clear TWL4030 GPIO ISRs */
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1A,
|
||||
+ cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2A,
|
||||
+ cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3A,
|
||||
+ cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1B,
|
||||
+ cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2B,
|
||||
+ cor) < 0);
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3B,
|
||||
+ cor) < 0);
|
||||
|
||||
/* install an irq handler for each of the PIH modules */
|
||||
for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {
|
||||
@@ -0,0 +1,341 @@
|
||||
TWL4030: convert early interrupt mask/clear funcs to use array
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
Mask/clear TWL module IMRs/ISRs by iterating through arrays rather than
|
||||
using a block of cut-and-pasted commands. Removes 1056 bytes of bloat.
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/chips/twl4030-core.c | 302 +++++++++++++++++++++++---------------
|
||||
1 files changed, 180 insertions(+), 122 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
|
||||
index 38c227a..776b1dd 100644
|
||||
--- a/drivers/i2c/chips/twl4030-core.c
|
||||
+++ b/drivers/i2c/chips/twl4030-core.c
|
||||
@@ -160,6 +160,136 @@
|
||||
|
||||
#define TWL4030_SIH_CTRL_COR_MASK (1 << 2)
|
||||
|
||||
+/**
|
||||
+ * struct twl4030_mod_iregs - TWL module IMR/ISR regs to mask/clear at init
|
||||
+ * @mod_no: TWL4030 module number (e.g., TWL4030_MODULE_GPIO)
|
||||
+ * @sih_ctrl: address of module SIH_CTRL register
|
||||
+ * @reg_cnt: number of IMR/ISR regs
|
||||
+ * @imrs: pointer to array of TWL module interrupt mask register indices
|
||||
+ * @isrs: pointer to array of TWL module interrupt status register indices
|
||||
+ *
|
||||
+ * Ties together TWL4030 modules and lists of IMR/ISR registers to mask/clear
|
||||
+ * during twl_init_irq().
|
||||
+ */
|
||||
+struct twl4030_mod_iregs {
|
||||
+ const u8 mod_no;
|
||||
+ const u8 sih_ctrl;
|
||||
+ const u8 reg_cnt;
|
||||
+ const u8 *imrs;
|
||||
+ const u8 *isrs;
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 INT module interrupt mask registers */
|
||||
+static const u8 __initconst twl4030_int_imr_regs[] = {
|
||||
+ TWL4030_INT_PWR_IMR1,
|
||||
+ TWL4030_INT_PWR_IMR2,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 INT module interrupt status registers */
|
||||
+static const u8 __initconst twl4030_int_isr_regs[] = {
|
||||
+ TWL4030_INT_PWR_ISR1,
|
||||
+ TWL4030_INT_PWR_ISR2,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 INTERRUPTS module interrupt mask registers */
|
||||
+static const u8 __initconst twl4030_interrupts_imr_regs[] = {
|
||||
+ TWL4030_INTERRUPTS_BCIIMR1A,
|
||||
+ TWL4030_INTERRUPTS_BCIIMR1B,
|
||||
+ TWL4030_INTERRUPTS_BCIIMR2A,
|
||||
+ TWL4030_INTERRUPTS_BCIIMR2B,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 INTERRUPTS module interrupt status registers */
|
||||
+static const u8 __initconst twl4030_interrupts_isr_regs[] = {
|
||||
+ TWL4030_INTERRUPTS_BCIISR1A,
|
||||
+ TWL4030_INTERRUPTS_BCIISR1B,
|
||||
+ TWL4030_INTERRUPTS_BCIISR2A,
|
||||
+ TWL4030_INTERRUPTS_BCIISR2B,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 MADC module interrupt mask registers */
|
||||
+static const u8 __initconst twl4030_madc_imr_regs[] = {
|
||||
+ TWL4030_MADC_IMR1,
|
||||
+ TWL4030_MADC_IMR2,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 MADC module interrupt status registers */
|
||||
+static const u8 __initconst twl4030_madc_isr_regs[] = {
|
||||
+ TWL4030_MADC_ISR1,
|
||||
+ TWL4030_MADC_ISR2,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 keypad module interrupt mask registers */
|
||||
+static const u8 __initconst twl4030_keypad_imr_regs[] = {
|
||||
+ TWL4030_KEYPAD_KEYP_IMR1,
|
||||
+ TWL4030_KEYPAD_KEYP_IMR2,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 keypad module interrupt status registers */
|
||||
+static const u8 __initconst twl4030_keypad_isr_regs[] = {
|
||||
+ TWL4030_KEYPAD_KEYP_ISR1,
|
||||
+ TWL4030_KEYPAD_KEYP_ISR2,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 GPIO module interrupt mask registers */
|
||||
+static const u8 __initconst twl4030_gpio_imr_regs[] = {
|
||||
+ REG_GPIO_IMR1A,
|
||||
+ REG_GPIO_IMR1B,
|
||||
+ REG_GPIO_IMR2A,
|
||||
+ REG_GPIO_IMR2B,
|
||||
+ REG_GPIO_IMR3A,
|
||||
+ REG_GPIO_IMR3B,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 GPIO module interrupt status registers */
|
||||
+static const u8 __initconst twl4030_gpio_isr_regs[] = {
|
||||
+ REG_GPIO_ISR1A,
|
||||
+ REG_GPIO_ISR1B,
|
||||
+ REG_GPIO_ISR2A,
|
||||
+ REG_GPIO_ISR2B,
|
||||
+ REG_GPIO_ISR3A,
|
||||
+ REG_GPIO_ISR3B,
|
||||
+};
|
||||
+
|
||||
+/* TWL4030 modules that have IMR/ISR registers that must be masked/cleared */
|
||||
+static const struct twl4030_mod_iregs __initconst twl4030_mod_regs[] = {
|
||||
+ {
|
||||
+ .mod_no = TWL4030_MODULE_INT,
|
||||
+ .sih_ctrl = TWL4030_INT_PWR_SIH_CTRL,
|
||||
+ .reg_cnt = ARRAY_SIZE(twl4030_int_imr_regs),
|
||||
+ .imrs = twl4030_int_imr_regs,
|
||||
+ .isrs = twl4030_int_isr_regs,
|
||||
+ },
|
||||
+ {
|
||||
+ .mod_no = TWL4030_MODULE_INTERRUPTS,
|
||||
+ .sih_ctrl = TWL4030_INTERRUPTS_BCISIHCTRL,
|
||||
+ .reg_cnt = ARRAY_SIZE(twl4030_interrupts_imr_regs),
|
||||
+ .imrs = twl4030_interrupts_imr_regs,
|
||||
+ .isrs = twl4030_interrupts_isr_regs,
|
||||
+ },
|
||||
+ {
|
||||
+ .mod_no = TWL4030_MODULE_MADC,
|
||||
+ .sih_ctrl = TWL4030_MADC_MADC_SIH_CTRL,
|
||||
+ .reg_cnt = ARRAY_SIZE(twl4030_madc_imr_regs),
|
||||
+ .imrs = twl4030_madc_imr_regs,
|
||||
+ .isrs = twl4030_madc_isr_regs,
|
||||
+ },
|
||||
+ {
|
||||
+ .mod_no = TWL4030_MODULE_KEYPAD,
|
||||
+ .sih_ctrl = TWL4030_KEYPAD_KEYP_SIH_CTRL,
|
||||
+ .reg_cnt = ARRAY_SIZE(twl4030_keypad_imr_regs),
|
||||
+ .imrs = twl4030_keypad_imr_regs,
|
||||
+ .isrs = twl4030_keypad_isr_regs,
|
||||
+ },
|
||||
+ {
|
||||
+ .mod_no = TWL4030_MODULE_GPIO,
|
||||
+ .sih_ctrl = REG_GPIO_SIH_CTRL,
|
||||
+ .reg_cnt = ARRAY_SIZE(twl4030_gpio_imr_regs),
|
||||
+ .imrs = twl4030_gpio_imr_regs,
|
||||
+ .isrs = twl4030_gpio_isr_regs,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
|
||||
/* Helper functions */
|
||||
static int
|
||||
@@ -779,136 +909,64 @@ static int twl4030_read_cor_bit(u8 mod_no, u8 reg)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * twl4030_mask_clear_intrs - mask and clear all TWL4030 interrupts
|
||||
+ * @t: pointer to twl4030_mod_iregs array
|
||||
+ * @t_sz: ARRAY_SIZE(t) (starting at 1)
|
||||
+ *
|
||||
+ * Mask all TWL4030 interrupt mask registers (IMRs) and clear all
|
||||
+ * interrupt status registers (ISRs). No return value, but will WARN if
|
||||
+ * any I2C operations fail.
|
||||
+ */
|
||||
+static void __init twl4030_mask_clear_intrs(const struct twl4030_mod_iregs *t,
|
||||
+ const u8 t_sz)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ /*
|
||||
+ * N.B. - further efficiency is possible here. Eight I2C
|
||||
+ * operations on BCI and GPIO modules are avoidable if I2C
|
||||
+ * burst read/write transactions were implemented. Would
|
||||
+ * probably save about 1ms of boot time and a small amount of
|
||||
+ * power.
|
||||
+ */
|
||||
+ for (i = 0; i < t_sz; i++) {
|
||||
+ const struct twl4030_mod_iregs tmr = t[i];
|
||||
+
|
||||
+ for (j = 0; j < tmr.reg_cnt; j++) {
|
||||
+ int cor;
|
||||
+
|
||||
+ /* Mask interrupts at the TWL4030 */
|
||||
+ WARN_ON(twl4030_i2c_write_u8(tmr.mod_no, 0xff,
|
||||
+ tmr.imrs[j]) < 0);
|
||||
+
|
||||
+ /* Are ISRs cleared by reads or writes? */
|
||||
+ cor = twl4030_read_cor_bit(tmr.mod_no, tmr.sih_ctrl);
|
||||
+ WARN_ON(cor < 0);
|
||||
+
|
||||
+ /* Clear TWL4030 ISRs */
|
||||
+ WARN_ON(twl4030_i2c_clear_isr(tmr.mod_no,
|
||||
+ tmr.isrs[j], cor) < 0);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static void twl_init_irq(void)
|
||||
{
|
||||
- int i = 0;
|
||||
+ int i;
|
||||
int res = 0;
|
||||
- int cor;
|
||||
char *msg = "Unable to register interrupt subsystem";
|
||||
unsigned int irq_num;
|
||||
|
||||
/*
|
||||
- * For each TWL4030 module with ISR/IMR registers, mask all
|
||||
- * interrupts and then clear any existing interrupt status bits,
|
||||
- * since we initially do not have any TWL4030 module interrupt
|
||||
- * handlers present.
|
||||
+ * Mask and clear all TWL4030 interrupts since initially we do
|
||||
+ * not have any TWL4030 module interrupt handlers present
|
||||
*/
|
||||
-
|
||||
- /* Mask INT (PWR) interrupts at TWL4030 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
|
||||
- TWL4030_INT_PWR_IMR1) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
|
||||
- TWL4030_INT_PWR_IMR2) < 0);
|
||||
-
|
||||
- /* Are PWR interrupt status bits cleared by reads or writes? */
|
||||
- cor = twl4030_read_cor_bit(TWL4030_MODULE_INT,
|
||||
- TWL4030_INT_PWR_SIH_CTRL);
|
||||
- WARN_ON(cor < 0);
|
||||
-
|
||||
- /* Clear TWL4030 INT (PWR) ISRs */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
|
||||
- TWL4030_INT_PWR_ISR1, cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
|
||||
- TWL4030_INT_PWR_ISR2, cor) < 0);
|
||||
-
|
||||
- /* Slave address 0x4A */
|
||||
-
|
||||
- /* Mask BCI interrupts at TWL4030 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
|
||||
- TWL4030_INTERRUPTS_BCIIMR1A) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
|
||||
- TWL4030_INTERRUPTS_BCIIMR2A) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
|
||||
- TWL4030_INTERRUPTS_BCIIMR1B) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
|
||||
- TWL4030_INTERRUPTS_BCIIMR2B) < 0);
|
||||
-
|
||||
- /* Are BCI interrupt status bits cleared by reads or writes? */
|
||||
- cor = twl4030_read_cor_bit(TWL4030_MODULE_INTERRUPTS,
|
||||
- TWL4030_INTERRUPTS_BCISIHCTRL);
|
||||
- WARN_ON(cor < 0);
|
||||
-
|
||||
- /* Clear TWL4030 BCI ISRs */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
|
||||
- TWL4030_INTERRUPTS_BCIISR1A, cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
|
||||
- TWL4030_INTERRUPTS_BCIISR2A, cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
|
||||
- TWL4030_INTERRUPTS_BCIISR1B, cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
|
||||
- TWL4030_INTERRUPTS_BCIISR2B, cor) < 0);
|
||||
-
|
||||
- /* MAD C */
|
||||
- /* Mask MADC interrupts at TWL4030 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
|
||||
- TWL4030_MADC_IMR1) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
|
||||
- TWL4030_MADC_IMR2) < 0);
|
||||
-
|
||||
- /* Are MADC interrupt status bits cleared by reads or writes? */
|
||||
- cor = twl4030_read_cor_bit(TWL4030_MODULE_MADC,
|
||||
- TWL4030_MADC_MADC_SIH_CTRL);
|
||||
- WARN_ON(cor < 0);
|
||||
-
|
||||
- /* Clear TWL4030 MADC ISRs */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
|
||||
- TWL4030_MADC_ISR1, cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
|
||||
- TWL4030_MADC_ISR2, cor) < 0);
|
||||
-
|
||||
- /* key Pad */
|
||||
- /* Mask keypad interrupts at TWL4030 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
|
||||
- TWL4030_KEYPAD_KEYP_IMR1) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
|
||||
- TWL4030_KEYPAD_KEYP_IMR2) < 0);
|
||||
-
|
||||
- /* Are keypad interrupt status bits cleared by reads or writes? */
|
||||
- cor = twl4030_read_cor_bit(TWL4030_MODULE_KEYPAD,
|
||||
- TWL4030_KEYPAD_KEYP_SIH_CTRL);
|
||||
- WARN_ON(cor < 0);
|
||||
-
|
||||
- /* Clear TWL4030 keypad ISRs */
|
||||
- /* XXX does this still need to be done twice for some reason? */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
|
||||
- TWL4030_KEYPAD_KEYP_ISR1, cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
|
||||
- TWL4030_KEYPAD_KEYP_ISR2, cor) < 0);
|
||||
-
|
||||
- /* Slave address 0x49 */
|
||||
-
|
||||
- /* Mask GPIO interrupts at TWL4030 */
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
- REG_GPIO_IMR1A) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
- REG_GPIO_IMR2A) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
- REG_GPIO_IMR3A) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
- REG_GPIO_IMR1B) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
- REG_GPIO_IMR2B) < 0);
|
||||
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
|
||||
- REG_GPIO_IMR3B) < 0);
|
||||
-
|
||||
- /* Are GPIO interrupt status bits cleared by reads or writes? */
|
||||
- cor = twl4030_read_cor_bit(TWL4030_MODULE_GPIO,
|
||||
- REG_GPIO_SIH_CTRL);
|
||||
- WARN_ON(cor < 0);
|
||||
-
|
||||
- /* Clear TWL4030 GPIO ISRs */
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1A,
|
||||
- cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2A,
|
||||
- cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3A,
|
||||
- cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1B,
|
||||
- cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2B,
|
||||
- cor) < 0);
|
||||
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3B,
|
||||
- cor) < 0);
|
||||
+ twl4030_mask_clear_intrs(twl4030_mod_regs,
|
||||
+ ARRAY_SIZE(twl4030_mod_regs));
|
||||
|
||||
/* install an irq handler for each of the PIH modules */
|
||||
for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {
|
||||
@@ -0,0 +1,238 @@
|
||||
On Tue, 2008-07-01 at 06:23 +0100, Dirk Behme wrote:
|
||||
> Catalin Marinas wrote:
|
||||
> > But, anyway, if you want a patch, Harry is updating it to a recent
|
||||
> > kernel.
|
||||
>
|
||||
> Any news on this? I think there are some people wanting a patch ;)
|
||||
|
||||
See below for a preliminary patch updated to 2.6.26-rc8. Note that I
|
||||
don't plan to submit it in its current form but clean it up a bit first.
|
||||
|
||||
|
||||
Show the cache type of ARMv7 CPUs
|
||||
|
||||
From: Catalin Marinas <catalin.marinas@arm.com>
|
||||
|
||||
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
|
||||
---
|
||||
|
||||
arch/arm/kernel/setup.c | 137 +++++++++++++++++++++++++++++++++++++++++++++-
|
||||
include/asm-arm/system.h | 18 ++++++
|
||||
2 files changed, 153 insertions(+), 2 deletions(-)
|
||||
|
||||
|
||||
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
|
||||
index 5ae0eb2..0cd238d 100644
|
||||
--- a/arch/arm/kernel/setup.c
|
||||
+++ b/arch/arm/kernel/setup.c
|
||||
@@ -256,6 +256,24 @@ static const char *proc_arch[] = {
|
||||
"?(17)",
|
||||
};
|
||||
|
||||
+static const char *v7_cache_policy[4] = {
|
||||
+ "reserved",
|
||||
+ "AVIVT",
|
||||
+ "VIPT",
|
||||
+ "PIPT",
|
||||
+};
|
||||
+
|
||||
+static const char *v7_cache_type[8] = {
|
||||
+ "none",
|
||||
+ "instruction only",
|
||||
+ "data only",
|
||||
+ "separate instruction and data",
|
||||
+ "unified",
|
||||
+ "unknown type",
|
||||
+ "unknown type",
|
||||
+ "unknown type",
|
||||
+};
|
||||
+
|
||||
#define CACHE_TYPE(x) (((x) >> 25) & 15)
|
||||
#define CACHE_S(x) ((x) & (1 << 24))
|
||||
#define CACHE_DSIZE(x) (((x) >> 12) & 4095) /* only if S=1 */
|
||||
@@ -266,6 +284,22 @@ static const char *proc_arch[] = {
|
||||
#define CACHE_M(y) ((y) & (1 << 2))
|
||||
#define CACHE_LINE(y) ((y) & 3)
|
||||
|
||||
+#define CACHE_TYPE_V7(x) (((x) >> 14) & 3)
|
||||
+#define CACHE_UNIFIED(x) ((((x) >> 27) & 7)+1)
|
||||
+#define CACHE_COHERENT(x) ((((x) >> 24) & 7)+1)
|
||||
+
|
||||
+#define CACHE_ID_LEVEL_MASK 7
|
||||
+#define CACHE_ID_LEVEL_BITS 3
|
||||
+
|
||||
+#define CACHE_LINE_V7(v) ((1 << (((v) & 7)+4)))
|
||||
+#define CACHE_ASSOC_V7(v) ((((v) >> 3) & ((1<<10)-1))+1)
|
||||
+#define CACHE_SETS_V7(v) ((((v) >> 13) & ((1<<15)-1))+1)
|
||||
+#define CACHE_SIZE_V7(v) (CACHE_LINE_V7(v)*CACHE_ASSOC_V7(v)*CACHE_SETS_V7(v))
|
||||
+#define CACHE_WA_V7(v) (((v) & (1<<28)) != 0)
|
||||
+#define CACHE_RA_V7(v) (((v) & (1<<29)) != 0)
|
||||
+#define CACHE_WB_V7(v) (((v) & (1<<30)) != 0)
|
||||
+#define CACHE_WT_V7(v) (((v) & (1<<31)) != 0)
|
||||
+
|
||||
static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
|
||||
{
|
||||
unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
|
||||
@@ -279,11 +313,57 @@ static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
|
||||
CACHE_LINE(cache)));
|
||||
}
|
||||
|
||||
+static void dump_v7_cache(const char *type, int cpu, unsigned int level)
|
||||
+{
|
||||
+ unsigned int cachesize;
|
||||
+
|
||||
+ write_extended_cpuid(2,0,0,0,level); /* Set the cache size selection register */
|
||||
+ write_extended_cpuid(0,7,5,4,0); /* Prefetch flush to wait for above */
|
||||
+ cachesize = read_extended_cpuid(1,0,0,0);
|
||||
+
|
||||
+ printk("CPU%u: %s cache: %d bytes, associativity %d, %d byte lines, %d sets,\n supports%s%s%s%s\n",
|
||||
+ cpu, type,
|
||||
+ CACHE_SIZE_V7(cachesize),CACHE_ASSOC_V7(cachesize),
|
||||
+ CACHE_LINE_V7(cachesize),CACHE_SETS_V7(cachesize),
|
||||
+ CACHE_WA_V7(cachesize) ? " WA" : "",
|
||||
+ CACHE_RA_V7(cachesize) ? " RA" : "",
|
||||
+ CACHE_WB_V7(cachesize) ? " WB" : "",
|
||||
+ CACHE_WT_V7(cachesize) ? " WT" : "");
|
||||
+}
|
||||
+
|
||||
static void __init dump_cpu_info(int cpu)
|
||||
{
|
||||
unsigned int info = read_cpuid(CPUID_CACHETYPE);
|
||||
|
||||
- if (info != processor_id) {
|
||||
+ if (info != processor_id && (info & (1 << 31))) {
|
||||
+ /* ARMv7 style of cache info register */
|
||||
+ unsigned int id = read_extended_cpuid(1,0,0,1);
|
||||
+ unsigned int level = 0;
|
||||
+ printk("CPU%u: L1 I %s cache. Caches unified at level %u, coherent at level %u\n",
|
||||
+ cpu,
|
||||
+ v7_cache_policy[CACHE_TYPE_V7(info)],
|
||||
+ CACHE_UNIFIED(id),
|
||||
+ CACHE_COHERENT(id));
|
||||
+
|
||||
+ while (id & CACHE_ID_LEVEL_MASK) {
|
||||
+ printk("CPU%u: Level %u cache is %s\n",
|
||||
+ cpu, (level >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
|
||||
+
|
||||
+ if (id & 1) {
|
||||
+ /* Dump I at this level */
|
||||
+ dump_v7_cache("I", cpu, level | 1);
|
||||
+ }
|
||||
+
|
||||
+ if (id & (4 | 2)) {
|
||||
+ /* Dump D or unified at this level */
|
||||
+ dump_v7_cache((id & 4) ? "unified" : "D", cpu, level);
|
||||
+ }
|
||||
+
|
||||
+ /* Next level out */
|
||||
+ level += 2;
|
||||
+ id >>= CACHE_ID_LEVEL_BITS;
|
||||
+ }
|
||||
+ } else if (info != processor_id) {
|
||||
printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT",
|
||||
cache_types[CACHE_TYPE(info)]);
|
||||
if (CACHE_S(info)) {
|
||||
@@ -916,6 +996,30 @@ c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
|
||||
CACHE_LINE(cache)));
|
||||
}
|
||||
|
||||
+static void c_show_v7_cache(struct seq_file *m, const char *type, unsigned int levelselect)
|
||||
+{
|
||||
+ unsigned int cachesize;
|
||||
+ unsigned int level = (levelselect >> 1) + 1;
|
||||
+
|
||||
+ write_extended_cpuid(2,0,0,0,levelselect); /* Set the cache size selection register */
|
||||
+ write_extended_cpuid(0,7,5,4,0); /* Prefetch flush to wait for above */
|
||||
+ cachesize = read_extended_cpuid(1,0,0,0);
|
||||
+
|
||||
+ seq_printf(m, "L%u %s size\t\t: %d bytes\n"
|
||||
+ "L%u %s assoc\t\t: %d\n"
|
||||
+ "L%u %s line length\t: %d\n"
|
||||
+ "L%u %s sets\t\t: %d\n"
|
||||
+ "L%u %s supports\t\t:%s%s%s%s\n",
|
||||
+ level, type, CACHE_SIZE_V7(cachesize),
|
||||
+ level, type, CACHE_ASSOC_V7(cachesize),
|
||||
+ level, type, CACHE_LINE_V7(cachesize),
|
||||
+ level, type, CACHE_SETS_V7(cachesize),
|
||||
+ level, type, CACHE_WA_V7(cachesize) ? " WA" : "",
|
||||
+ CACHE_RA_V7(cachesize) ? " RA" : "",
|
||||
+ CACHE_WB_V7(cachesize) ? " WB" : "",
|
||||
+ CACHE_WT_V7(cachesize) ? " WT" : "");
|
||||
+}
|
||||
+
|
||||
static int c_show(struct seq_file *m, void *v)
|
||||
{
|
||||
int i;
|
||||
@@ -971,7 +1075,36 @@ static int c_show(struct seq_file *m, void *v)
|
||||
|
||||
{
|
||||
unsigned int cache_info = read_cpuid(CPUID_CACHETYPE);
|
||||
- if (cache_info != processor_id) {
|
||||
+ if (cache_info != processor_id && (cache_info & (1<<31))) {
|
||||
+ /* V7 style of cache info register */
|
||||
+ unsigned int id = read_extended_cpuid(1,0,0,1);
|
||||
+ unsigned int levelselect = 0;
|
||||
+ seq_printf(m, "L1 I cache\t:%s\n"
|
||||
+ "Cache unification level\t: %u\n"
|
||||
+ "Cache coherency level\t: %u\n",
|
||||
+ v7_cache_policy[CACHE_TYPE_V7(cache_info)],
|
||||
+ CACHE_UNIFIED(id),
|
||||
+ CACHE_COHERENT(id));
|
||||
+
|
||||
+ while (id & CACHE_ID_LEVEL_MASK) {
|
||||
+ seq_printf(m, "Level %u cache\t\t: %s\n",
|
||||
+ (levelselect >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
|
||||
+
|
||||
+ if (id & 1) {
|
||||
+ /* Dump I at this level */
|
||||
+ c_show_v7_cache(m, "I", levelselect | 1);
|
||||
+ }
|
||||
+
|
||||
+ if (id & (4 | 2)) {
|
||||
+ /* Dump D or unified at this level */
|
||||
+ c_show_v7_cache(m, (id & 4) ? "cache" : "D", levelselect);
|
||||
+ }
|
||||
+
|
||||
+ /* Next level out */
|
||||
+ levelselect += 2;
|
||||
+ id >>= CACHE_ID_LEVEL_BITS;
|
||||
+ }
|
||||
+ } else if (cache_info != processor_id) {
|
||||
seq_printf(m, "Cache type\t: %s\n"
|
||||
"Cache clean\t: %s\n"
|
||||
"Cache lockdown\t: %s\n"
|
||||
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
|
||||
index 514af79..704738e 100644
|
||||
--- a/include/asm-arm/system.h
|
||||
+++ b/include/asm-arm/system.h
|
||||
@@ -74,6 +74,24 @@
|
||||
: "cc"); \
|
||||
__val; \
|
||||
})
|
||||
+#define read_extended_cpuid(op1,op2,op3,op4) \
|
||||
+ ({ \
|
||||
+ unsigned int __val; \
|
||||
+ asm("mrc p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4) \
|
||||
+ : "=r" (__val) \
|
||||
+ : \
|
||||
+ : "cc"); \
|
||||
+ __val; \
|
||||
+ })
|
||||
+
|
||||
+#define write_extended_cpuid(op1,op2,op3,op4,v) \
|
||||
+ ({ \
|
||||
+ unsigned int __val = v; \
|
||||
+ asm("mcr p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4) \
|
||||
+ : \
|
||||
+ : "r" (__val) \
|
||||
+ : "cc"); \
|
||||
+ })
|
||||
#else
|
||||
extern unsigned int processor_id;
|
||||
#define read_cpuid(reg) (processor_id)
|
||||
|
||||
|
||||
--
|
||||
Catalin
|
||||
|
||||
|
||||
1983
meta/recipes-kernel/linux/linux-omap2-git/beagleboard/defconfig
Normal file
1983
meta/recipes-kernel/linux/linux-omap2-git/beagleboard/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,558 @@
|
||||
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
|
||||
index 13d0043..d582b8f 100644
|
||||
--- a/arch/arm/mach-omap2/Makefile
|
||||
+++ b/arch/arm/mach-omap2/Makefile
|
||||
@@ -44,7 +44,8 @@ obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o \
|
||||
board-omap3evm-flash.o
|
||||
obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \
|
||||
usb-musb.o usb-ehci.o \
|
||||
- hsmmc.o
|
||||
+ hsmmc.o \
|
||||
+ board-omap3beagle-flash.o
|
||||
obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \
|
||||
hsmmc.o \
|
||||
usb-musb.o
|
||||
diff --git a/arch/arm/mach-omap2/board-omap3beagle-flash.c b/arch/arm/mach-omap2/board-omap3beagle-flash.c
|
||||
new file mode 100644
|
||||
index 0000000..5346df0
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-omap2/board-omap3beagle-flash.c
|
||||
@@ -0,0 +1,119 @@
|
||||
+/*
|
||||
+ * board-omap3beagle-flash.c
|
||||
+ *
|
||||
+ * Copyright (c) 2008 Texas Instruments
|
||||
+ *
|
||||
+ * Modified from board-omap3evm-flash.c
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+#include <linux/mtd/nand.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/io.h>
|
||||
+
|
||||
+#include <asm/mach/flash.h>
|
||||
+#include <asm/arch/board.h>
|
||||
+#include <asm/arch/gpmc.h>
|
||||
+#include <asm/arch/nand.h>
|
||||
+
|
||||
+#define GPMC_CS0_BASE 0x60
|
||||
+#define GPMC_CS_SIZE 0x30
|
||||
+
|
||||
+static struct mtd_partition omap3beagle_nand_partitions[] = {
|
||||
+ /* All the partition sizes are listed in terms of NAND block size */
|
||||
+ {
|
||||
+ .name = "X-Loader",
|
||||
+ .offset = 0,
|
||||
+ .size = 4*(64 * 2048),
|
||||
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "U-Boot",
|
||||
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
|
||||
+ .size = 15*(64 * 2048),
|
||||
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "U-Boot Env",
|
||||
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
|
||||
+ .size = 1*(64 * 2048),
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "Kernel",
|
||||
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
|
||||
+ .size = 32*(64 * 2048),
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "File System",
|
||||
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
|
||||
+ .size = MTDPART_SIZ_FULL,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct omap_nand_platform_data omap3beagle_nand_data = {
|
||||
+ .parts = omap3beagle_nand_partitions,
|
||||
+ .nr_parts = ARRAY_SIZE(omap3beagle_nand_partitions),
|
||||
+ .dma_channel = -1, /* disable DMA in OMAP NAND driver */
|
||||
+ .nand_setup = NULL,
|
||||
+ .dev_ready = NULL,
|
||||
+};
|
||||
+
|
||||
+static struct resource omap3beagle_nand_resource = {
|
||||
+ .flags = IORESOURCE_MEM,
|
||||
+};
|
||||
+
|
||||
+static struct platform_device omap3beagle_nand_device = {
|
||||
+ .name = "omap2-nand",
|
||||
+ .id = -1,
|
||||
+ .dev = {
|
||||
+ .platform_data = &omap3beagle_nand_data,
|
||||
+ },
|
||||
+ .num_resources = 1,
|
||||
+ .resource = &omap3beagle_nand_resource,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+void __init omap3beagle_flash_init(void)
|
||||
+{
|
||||
+ u8 cs = 0;
|
||||
+ u8 nandcs = GPMC_CS_NUM + 1;
|
||||
+
|
||||
+ u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
|
||||
+
|
||||
+ /* find out the chip-select on which NAND exists */
|
||||
+ while (cs < GPMC_CS_NUM) {
|
||||
+ u32 ret = 0;
|
||||
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
|
||||
+
|
||||
+ if ((ret & 0xC00) == 0x800) {
|
||||
+ printk(KERN_INFO "Found NAND on CS%d\n", cs);
|
||||
+ if (nandcs > GPMC_CS_NUM)
|
||||
+ nandcs = cs;
|
||||
+ }
|
||||
+ cs++;
|
||||
+ }
|
||||
+
|
||||
+ if (nandcs > GPMC_CS_NUM) {
|
||||
+ printk(KERN_INFO "NAND: Unable to find configuration "
|
||||
+ "in GPMC\n ");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (nandcs < GPMC_CS_NUM) {
|
||||
+ omap3beagle_nand_data.cs = nandcs;
|
||||
+ omap3beagle_nand_data.gpmc_cs_baseaddr = (void *)(gpmc_base_add +
|
||||
+ GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
|
||||
+ omap3beagle_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
|
||||
+
|
||||
+ printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
|
||||
+ if (platform_device_register(&omap3beagle_nand_device) < 0)
|
||||
+ printk(KERN_ERR "Unable to register NAND device\n");
|
||||
+ }
|
||||
+}
|
||||
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
index c992cc7..99e042e 100644
|
||||
--- a/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
@@ -94,6 +94,7 @@ static void __init omap3_beagle_init(void)
|
||||
hsmmc_init();
|
||||
usb_musb_init();
|
||||
usb_ehci_init();
|
||||
+ omap3beagle_flash_init();
|
||||
}
|
||||
|
||||
arch_initcall(omap3_beagle_i2c_init);
|
||||
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
|
||||
index 3d5e432..02b9ced 100644
|
||||
--- a/drivers/mtd/nand/Kconfig
|
||||
+++ b/drivers/mtd/nand/Kconfig
|
||||
@@ -71,7 +71,7 @@ config MTD_NAND_AMS_DELTA
|
||||
|
||||
config MTD_NAND_OMAP2
|
||||
tristate "NAND Flash device on OMAP 2420H4/2430SDP boards"
|
||||
- depends on (ARM && ARCH_OMAP2 && MTD_NAND)
|
||||
+ depends on ARM && MTD_NAND && (ARCH_OMAP2 || ARCH_OMAP3)
|
||||
help
|
||||
Support for NAND flash on Texas Instruments 2430SDP/2420H4 platforms.
|
||||
|
||||
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
|
||||
index 3b7307c..3aac1d2 100644
|
||||
--- a/drivers/mtd/nand/omap2.c
|
||||
+++ b/drivers/mtd/nand/omap2.c
|
||||
@@ -111,15 +111,6 @@
|
||||
static const char *part_probes[] = { "cmdlinepart", NULL };
|
||||
#endif
|
||||
|
||||
-static int hw_ecc = 1;
|
||||
-
|
||||
-/* new oob placement block for use with hardware ecc generation */
|
||||
-static struct nand_ecclayout omap_hw_eccoob = {
|
||||
- .eccbytes = 12,
|
||||
- .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},
|
||||
- .oobfree = {{16, 32}, {33, 63} },
|
||||
-};
|
||||
-
|
||||
struct omap_nand_info {
|
||||
struct nand_hw_control controller;
|
||||
struct omap_nand_platform_data *pdata;
|
||||
@@ -133,6 +124,13 @@ struct omap_nand_info {
|
||||
void __iomem *gpmc_cs_baseaddr;
|
||||
void __iomem *gpmc_baseaddr;
|
||||
};
|
||||
+
|
||||
+/*
|
||||
+ * omap_nand_wp - This function enable or disable the Write Protect feature on
|
||||
+ * NAND device
|
||||
+ * @mtd: MTD device structure
|
||||
+ * @mode: WP ON/OFF
|
||||
+ */
|
||||
static void omap_nand_wp(struct mtd_info *mtd, int mode)
|
||||
{
|
||||
struct omap_nand_info *info = container_of(mtd,
|
||||
@@ -189,11 +187,11 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
||||
}
|
||||
|
||||
/*
|
||||
-* omap_read_buf - read data from NAND controller into buffer
|
||||
-* @mtd: MTD device structure
|
||||
-* @buf: buffer to store date
|
||||
-* @len: number of bytes to read
|
||||
-*/
|
||||
+ * omap_read_buf - read data from NAND controller into buffer
|
||||
+ * @mtd: MTD device structure
|
||||
+ * @buf: buffer to store date
|
||||
+ * @len: number of bytes to read
|
||||
+ */
|
||||
static void omap_read_buf(struct mtd_info *mtd, u_char *buf, int len)
|
||||
{
|
||||
struct omap_nand_info *info = container_of(mtd,
|
||||
@@ -207,11 +205,11 @@ static void omap_read_buf(struct mtd_info *mtd, u_char *buf, int len)
|
||||
}
|
||||
|
||||
/*
|
||||
-* omap_write_buf - write buffer to NAND controller
|
||||
-* @mtd: MTD device structure
|
||||
-* @buf: data buffer
|
||||
-* @len: number of bytes to write
|
||||
-*/
|
||||
+ * omap_write_buf - write buffer to NAND controller
|
||||
+ * @mtd: MTD device structure
|
||||
+ * @buf: data buffer
|
||||
+ * @len: number of bytes to write
|
||||
+ */
|
||||
static void omap_write_buf(struct mtd_info *mtd, const u_char * buf, int len)
|
||||
{
|
||||
struct omap_nand_info *info = container_of(mtd,
|
||||
@@ -250,10 +248,16 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_MTD_NAND_OMAP_HWECC
|
||||
+/*
|
||||
+ * omap_hwecc_init-Initialize the Hardware ECC for NAND flash in GPMC controller
|
||||
+ * @mtd: MTD device structure
|
||||
+ */
|
||||
static void omap_hwecc_init(struct mtd_info *mtd)
|
||||
{
|
||||
struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
|
||||
mtd);
|
||||
+ register struct nand_chip *chip = mtd->priv;
|
||||
unsigned long val = 0x0;
|
||||
|
||||
/* Read from ECC Control Register */
|
||||
@@ -264,16 +268,15 @@ static void omap_hwecc_init(struct mtd_info *mtd)
|
||||
|
||||
/* Read from ECC Size Config Register */
|
||||
val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG);
|
||||
- /* ECCSIZE1=512 | ECCSIZE0=8bytes | Select eccResultsize[0123] */
|
||||
- val = ((0x000000FF<<22) | (0x00000003<<12) | (0x0000000F));
|
||||
+ /* ECCSIZE1=512 | Select eccResultsize[0-3] */
|
||||
+ val = ((((chip->ecc.size >> 1) - 1) << 22) | (0x0000000F));
|
||||
__raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG);
|
||||
-
|
||||
-
|
||||
}
|
||||
|
||||
/*
|
||||
- * This function will generate true ECC value, which can be used
|
||||
+ * gen_true_ecc - This function will generate true ECC value, which can be used
|
||||
* when correcting data read from NAND flash memory core
|
||||
+ * @ecc_buf: buffer to store ecc code
|
||||
*/
|
||||
static void gen_true_ecc(u8 *ecc_buf)
|
||||
{
|
||||
@@ -289,8 +292,12 @@ static void gen_true_ecc(u8 *ecc_buf)
|
||||
}
|
||||
|
||||
/*
|
||||
- * This function compares two ECC's and indicates if there is an error.
|
||||
- * If the error can be corrected it will be corrected to the buffer
|
||||
+ * omap_compare_ecc - This function compares two ECC's and indicates if there
|
||||
+ * is an error. If the error can be corrected it will be corrected to the
|
||||
+ * buffer
|
||||
+ * @ecc_data1: ecc code from nand spare area
|
||||
+ * @ecc_data2: ecc code from hardware register obtained from hardware ecc
|
||||
+ * @page_data: page data
|
||||
*/
|
||||
static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */
|
||||
u8 *ecc_data2, /* read from register */
|
||||
@@ -409,6 +416,14 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * omap_correct_data - Compares the ecc read from nand spare area with ECC
|
||||
+ * registers values and corrects one bit error if it has occured
|
||||
+ * @mtd: MTD device structure
|
||||
+ * @dat: page data
|
||||
+ * @read_ecc: ecc read from nand flash
|
||||
+ * @calc_ecc: ecc read from ECC registers
|
||||
+ */
|
||||
static int omap_correct_data(struct mtd_info *mtd, u_char * dat,
|
||||
u_char * read_ecc, u_char * calc_ecc)
|
||||
{
|
||||
@@ -436,65 +451,64 @@ static int omap_correct_data(struct mtd_info *mtd, u_char * dat,
|
||||
}
|
||||
|
||||
/*
|
||||
-** Generate non-inverted ECC bytes.
|
||||
-**
|
||||
-** Using noninverted ECC can be considered ugly since writing a blank
|
||||
-** page ie. padding will clear the ECC bytes. This is no problem as long
|
||||
-** nobody is trying to write data on the seemingly unused page.
|
||||
-**
|
||||
-** Reading an erased page will produce an ECC mismatch between
|
||||
-** generated and read ECC bytes that has to be dealt with separately.
|
||||
-*/
|
||||
+ * omap_calcuate_ecc - Generate non-inverted ECC bytes.
|
||||
+ * Using noninverted ECC can be considered ugly since writing a blank
|
||||
+ * page ie. padding will clear the ECC bytes. This is no problem as long
|
||||
+ * nobody is trying to write data on the seemingly unused page. Reading
|
||||
+ * an erased page will produce an ECC mismatch between generated and read
|
||||
+ * ECC bytes that has to be dealt with separately.
|
||||
+ * @mtd: MTD device structure
|
||||
+ * @dat: The pointer to data on which ecc is computed
|
||||
+ * @ecc_code: The ecc_code buffer
|
||||
+ */
|
||||
static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
|
||||
u_char *ecc_code)
|
||||
{
|
||||
struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
|
||||
mtd);
|
||||
unsigned long val = 0x0;
|
||||
- unsigned long reg, n;
|
||||
-
|
||||
- /* Ex NAND_ECC_HW12_2048 */
|
||||
- if ((info->nand.ecc.mode == NAND_ECC_HW) &&
|
||||
- (info->nand.ecc.size == 2048))
|
||||
- n = 4;
|
||||
- else
|
||||
- n = 1;
|
||||
+ unsigned long reg;
|
||||
|
||||
/* Start Reading from HW ECC1_Result = 0x200 */
|
||||
reg = (unsigned long)(info->gpmc_baseaddr + GPMC_ECC1_RESULT);
|
||||
- while (n--) {
|
||||
- val = __raw_readl(reg);
|
||||
- *ecc_code++ = val; /* P128e, ..., P1e */
|
||||
- *ecc_code++ = val >> 16; /* P128o, ..., P1o */
|
||||
- /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
|
||||
- *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
|
||||
- reg += 4;
|
||||
- }
|
||||
+ val = __raw_readl(reg);
|
||||
+ *ecc_code++ = val; /* P128e, ..., P1e */
|
||||
+ *ecc_code++ = val >> 16; /* P128o, ..., P1o */
|
||||
+ /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
|
||||
+ *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
|
||||
+ reg += 4;
|
||||
|
||||
return 0;
|
||||
-} /* omap_calculate_ecc */
|
||||
+}
|
||||
|
||||
+/*
|
||||
+ * omap_enable_hwecc - This function enables the hardware ecc functionality
|
||||
+ * @mtd: MTD device structure
|
||||
+ * @mode: Read/Write mode
|
||||
+ */
|
||||
static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
|
||||
{
|
||||
struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
|
||||
mtd);
|
||||
+ register struct nand_chip *chip = mtd->priv;
|
||||
+ unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
|
||||
unsigned long val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_CONFIG);
|
||||
|
||||
switch (mode) {
|
||||
case NAND_ECC_READ :
|
||||
__raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
|
||||
- /* ECC 16 bit col) | ( CS 0 ) | ECC Enable */
|
||||
- val = (1 << 7) | (0x0) | (0x1) ;
|
||||
+ /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
|
||||
+ val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
|
||||
break;
|
||||
case NAND_ECC_READSYN :
|
||||
- __raw_writel(0x100, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
|
||||
- /* ECC 16 bit col) | ( CS 0 ) | ECC Enable */
|
||||
- val = (1 << 7) | (0x0) | (0x1) ;
|
||||
+ __raw_writel(0x100, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
|
||||
+ /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
|
||||
+ val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
|
||||
break;
|
||||
case NAND_ECC_WRITE :
|
||||
__raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
|
||||
- /* ECC 16 bit col) | ( CS 0 ) | ECC Enable */
|
||||
- val = (1 << 7) | (0x0) | (0x1) ;
|
||||
+ /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
|
||||
+ val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
|
||||
break;
|
||||
default:
|
||||
DEBUG(MTD_DEBUG_LEVEL0, "Error: Unrecognized Mode[%d]!\n",
|
||||
@@ -504,7 +518,38 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
|
||||
|
||||
__raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_CONFIG);
|
||||
}
|
||||
+#endif
|
||||
|
||||
+/*
|
||||
+ * omap_wait - Wait function is called during Program and erase
|
||||
+ * operations and the way it is called from MTD layer, we should wait
|
||||
+ * till the NAND chip is ready after the programming/erase operation
|
||||
+ * has completed.
|
||||
+ * @mtd: MTD device structure
|
||||
+ * @chip: NAND Chip structure
|
||||
+ */
|
||||
+static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
|
||||
+{
|
||||
+ register struct nand_chip *this = mtd->priv;
|
||||
+ struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
|
||||
+ mtd);
|
||||
+ int status = 0;
|
||||
+
|
||||
+ this->IO_ADDR_W = (void *) info->gpmc_cs_baseaddr +
|
||||
+ GPMC_CS_NAND_COMMAND;
|
||||
+ this->IO_ADDR_R = (void *) info->gpmc_cs_baseaddr + GPMC_CS_NAND_DATA;
|
||||
+
|
||||
+ while (!(status & 0x40)) {
|
||||
+ __raw_writeb(NAND_CMD_STATUS & 0xFF, this->IO_ADDR_W);
|
||||
+ status = __raw_readb(this->IO_ADDR_R);
|
||||
+ }
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * omap_dev_ready - calls the platform specific dev_ready function
|
||||
+ * @mtd: MTD device structure
|
||||
+ */
|
||||
static int omap_dev_ready(struct mtd_info *mtd)
|
||||
{
|
||||
struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
|
||||
@@ -534,7 +579,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
|
||||
struct omap_nand_info *info;
|
||||
struct omap_nand_platform_data *pdata;
|
||||
int err;
|
||||
- unsigned long val;
|
||||
+ unsigned long val;
|
||||
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
@@ -568,15 +613,20 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Enable RD PIN Monitoring Reg */
|
||||
- val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1);
|
||||
- val |= WR_RD_PIN_MONITORING;
|
||||
- gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG1, val);
|
||||
+ if (pdata->dev_ready) {
|
||||
+ val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1);
|
||||
+ val |= WR_RD_PIN_MONITORING;
|
||||
+ gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG1, val);
|
||||
+ }
|
||||
|
||||
val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG7);
|
||||
val &= ~(0xf << 8);
|
||||
val |= (0xc & 0xf) << 8;
|
||||
gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG7, val);
|
||||
|
||||
+ /* NAND write protect off */
|
||||
+ omap_nand_wp(&info->mtd, NAND_WP_OFF);
|
||||
+
|
||||
if (!request_mem_region(info->phys_base, NAND_IO_SIZE,
|
||||
pdev->dev.driver->name)) {
|
||||
err = -EBUSY;
|
||||
@@ -597,29 +647,39 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
|
||||
info->nand.write_buf = omap_write_buf;
|
||||
info->nand.verify_buf = omap_verify_buf;
|
||||
|
||||
- info->nand.dev_ready = omap_dev_ready;
|
||||
- info->nand.chip_delay = 0;
|
||||
-
|
||||
- /* Options */
|
||||
- info->nand.options = NAND_BUSWIDTH_16;
|
||||
- info->nand.options |= NAND_SKIP_BBTSCAN;
|
||||
-
|
||||
- if (hw_ecc) {
|
||||
- /* init HW ECC */
|
||||
- omap_hwecc_init(&info->mtd);
|
||||
-
|
||||
- info->nand.ecc.calculate = omap_calculate_ecc;
|
||||
- info->nand.ecc.hwctl = omap_enable_hwecc;
|
||||
- info->nand.ecc.correct = omap_correct_data;
|
||||
- info->nand.ecc.mode = NAND_ECC_HW;
|
||||
- info->nand.ecc.bytes = 12;
|
||||
- info->nand.ecc.size = 2048;
|
||||
- info->nand.ecc.layout = &omap_hw_eccoob;
|
||||
-
|
||||
+ /*
|
||||
+ * If RDY/BSY line is connected to OMAP then use the omap ready funcrtion
|
||||
+ * and the generic nand_wait function which reads the status register
|
||||
+ * after monitoring the RDY/BSY line.Otherwise use a standard chip delay
|
||||
+ * which is slightly more than tR (AC Timing) of the NAND device and read
|
||||
+ * status register until you get a failure or success
|
||||
+ */
|
||||
+ if (pdata->dev_ready) {
|
||||
+ info->nand.dev_ready = omap_dev_ready;
|
||||
+ info->nand.chip_delay = 0;
|
||||
} else {
|
||||
- info->nand.ecc.mode = NAND_ECC_SOFT;
|
||||
+ info->nand.waitfunc = omap_wait;
|
||||
+ info->nand.chip_delay = 50;
|
||||
}
|
||||
|
||||
+ info->nand.options |= NAND_SKIP_BBTSCAN;
|
||||
+ if ((gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1) & 0x3000)
|
||||
+ == 0x1000)
|
||||
+ info->nand.options |= NAND_BUSWIDTH_16;
|
||||
+
|
||||
+#ifdef CONFIG_MTD_NAND_OMAP_HWECC
|
||||
+ info->nand.ecc.bytes = 3;
|
||||
+ info->nand.ecc.size = 512;
|
||||
+ info->nand.ecc.calculate = omap_calculate_ecc;
|
||||
+ info->nand.ecc.hwctl = omap_enable_hwecc;
|
||||
+ info->nand.ecc.correct = omap_correct_data;
|
||||
+ info->nand.ecc.mode = NAND_ECC_HW;
|
||||
+
|
||||
+ /* init HW ECC */
|
||||
+ omap_hwecc_init(&info->mtd);
|
||||
+#else
|
||||
+ info->nand.ecc.mode = NAND_ECC_SOFT;
|
||||
+#endif
|
||||
|
||||
/* DIP switches on some boards change between 8 and 16 bit
|
||||
* bus widths for flash. Try the other width if the first try fails.
|
||||
@@ -636,14 +696,12 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
|
||||
err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
|
||||
if (err > 0)
|
||||
add_mtd_partitions(&info->mtd, info->parts, err);
|
||||
- else if (err < 0 && pdata->parts)
|
||||
+ else if (err <= 0 && pdata->parts)
|
||||
add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
|
||||
else
|
||||
#endif
|
||||
add_mtd_device(&info->mtd);
|
||||
|
||||
- omap_nand_wp(&info->mtd, NAND_WP_OFF);
|
||||
-
|
||||
platform_set_drvdata(pdev, &info->mtd);
|
||||
|
||||
return 0;
|
||||
diff --git a/include/asm-arm/arch-omap/board-omap3beagle.h b/include/asm-arm/arch-omap/board-omap3beagle.h
|
||||
index 46dff31..26ecfb8 100644
|
||||
--- a/include/asm-arm/arch-omap/board-omap3beagle.h
|
||||
+++ b/include/asm-arm/arch-omap/board-omap3beagle.h
|
||||
@@ -29,5 +29,7 @@
|
||||
#ifndef __ASM_ARCH_OMAP3_BEAGLE_H
|
||||
#define __ASM_ARCH_OMAP3_BEAGLE_H
|
||||
|
||||
+extern void omap3beagle_flash_init(void);
|
||||
+
|
||||
#endif /* __ASM_ARCH_OMAP3_BEAGLE_H */
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
From linux-omap-owner@vger.kernel.org Tue Jul 15 21:23:13 2008
|
||||
Received: from localhost
|
||||
([127.0.0.1] helo=dominion ident=koen)
|
||||
by dominion.dominion.void with esmtp (Exim 4.69)
|
||||
(envelope-from <linux-omap-owner@vger.kernel.org>)
|
||||
id 1KIq7E-0004FX-VS
|
||||
for koen@localhost; Tue, 15 Jul 2008 21:23:13 +0200
|
||||
Received: from xs.service.utwente.nl [130.89.5.250]
|
||||
by dominion with POP3 (fetchmail-6.3.6)
|
||||
for <koen@localhost> (single-drop); Tue, 15 Jul 2008 21:23:12 +0200 (CEST)
|
||||
Received: from mail.service.utwente.nl ([130.89.5.254]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
|
||||
Tue, 15 Jul 2008 21:01:02 +0200
|
||||
Received: from mx.utwente.nl ([130.89.2.12]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
|
||||
Tue, 15 Jul 2008 21:01:01 +0200
|
||||
Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
|
||||
by mx.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id m6FJ0qDf031889
|
||||
for <k.kooi@student.utwente.nl>; Tue, 15 Jul 2008 21:00:52 +0200
|
||||
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
||||
id S1756776AbYGOTAV (ORCPT <rfc822;k.kooi@student.utwente.nl>);
|
||||
Tue, 15 Jul 2008 15:00:21 -0400
|
||||
Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755065AbYGOTAV
|
||||
(ORCPT <rfc822;linux-omap-outgoing>);
|
||||
Tue, 15 Jul 2008 15:00:21 -0400
|
||||
Received: from utopia.booyaka.com ([72.9.107.138]:35569 "EHLO
|
||||
utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
|
||||
with ESMTP id S1756776AbYGOTAU (ORCPT
|
||||
<rfc822;linux-omap@vger.kernel.org>); Tue, 15 Jul 2008 15:00:20 -0400
|
||||
Received: (qmail 2982 invoked by uid 526); 15 Jul 2008 19:00:18 -0000
|
||||
Date: Tue, 15 Jul 2008 13:00:18 -0600 (MDT)
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
To: linux-omap@vger.kernel.org
|
||||
Subject: [PATCH] i2c-omap: close suspected race between omap_i2c_idle() and
|
||||
omap_i2c_isr()
|
||||
Message-ID: <alpine.DEB.1.00.0807151259180.467@utopia.booyaka.com>
|
||||
User-Agent: Alpine 1.00 (DEB 882 2007-12-20)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: TEXT/PLAIN; charset=US-ASCII
|
||||
Sender: linux-omap-owner@vger.kernel.org
|
||||
Precedence: bulk
|
||||
List-ID: <linux-omap.vger.kernel.org>
|
||||
X-Mailing-List: linux-omap@vger.kernel.org
|
||||
X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact servicedesk@icts.utwente.nl for more information.
|
||||
X-UTwente-MailScanner: Found to be clean
|
||||
X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org
|
||||
X-Spam-Status: No
|
||||
X-OriginalArrivalTime: 15 Jul 2008 19:01:01.0610 (UTC) FILETIME=[1FBA68A0:01C8E6AD]
|
||||
|
||||
|
||||
omap_i2c_idle() sets an internal flag, "dev->idle", instructing its
|
||||
ISR to decline interrupts. It sets this flag before it actually masks
|
||||
the interrupts on the I2C controller. This is problematic, since an
|
||||
I2C interrupt could arrive after dev->idle is set, but before the
|
||||
interrupt source is masked. When this happens, Linux disables the I2C
|
||||
controller's IRQ, causing all future transactions on the bus to fail.
|
||||
|
||||
Symptoms, happening on about 7% of boots:
|
||||
|
||||
irq 56: nobody cared (try booting with the "irqpoll" option)
|
||||
<warning traceback here>
|
||||
Disabling IRQ #56
|
||||
i2c_omap i2c_omap.1: controller timed out
|
||||
|
||||
In omap_i2c_idle(), this patch sets dev->idle only after the interrupt
|
||||
mask write to the I2C controller has left the ARM write buffer.
|
||||
That's probably the major offender. For additional prophylaxis, in
|
||||
omap_i2c_unidle(), the patch clears the dev->idle flag before
|
||||
interrupts are enabled, rather than afterwards.
|
||||
|
||||
The patch has survived twenty-two reboots on the 3430SDP here without
|
||||
wedging I2C1. Not absolutely dispositive, but promising!
|
||||
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
drivers/i2c/busses/i2c-omap.c | 10 ++++++++--
|
||||
1 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
|
||||
index 55779f5..ed7e9ad 100644
|
||||
--- a/drivers/i2c/busses/i2c-omap.c
|
||||
+++ b/drivers/i2c/busses/i2c-omap.c
|
||||
@@ -209,22 +209,28 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
|
||||
if (dev->iclk != NULL)
|
||||
clk_enable(dev->iclk);
|
||||
clk_enable(dev->fclk);
|
||||
+ dev->idle = 0;
|
||||
if (dev->iestate)
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
|
||||
- dev->idle = 0;
|
||||
}
|
||||
|
||||
static void omap_i2c_idle(struct omap_i2c_dev *dev)
|
||||
{
|
||||
u16 iv;
|
||||
|
||||
- dev->idle = 1;
|
||||
dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
|
||||
if (dev->rev1)
|
||||
iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
|
||||
else
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
|
||||
+ /*
|
||||
+ * The wmb() is to ensure that the I2C interrupt mask write
|
||||
+ * reaches the I2C controller before the dev->idle store
|
||||
+ * occurs.
|
||||
+ */
|
||||
+ wmb();
|
||||
+ dev->idle = 1;
|
||||
clk_disable(dev->fclk);
|
||||
if (dev->iclk != NULL)
|
||||
clk_disable(dev->iclk);
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Tue, 22 Jul 2008 00:31:11 +0000 (+0100)
|
||||
Subject: ARM: OMAP: make dpll4_m4_ck programmable with clk_set_rate()
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=2b7b958dc79e51127d7a4ecf88ce12dbc6c31426
|
||||
|
||||
ARM: OMAP: make dpll4_m4_ck programmable with clk_set_rate()
|
||||
|
||||
Filling the set_rate and round_rate fields of dpll4_m4_ck makes
|
||||
this clock programmable through clk_set_rate(). This is needed
|
||||
to give omapfb control over the dss1_alwon_fck rate.
|
||||
---
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
|
||||
index 161da12..876eb13 100644
|
||||
--- a/arch/arm/mach-omap2/clock34xx.h
|
||||
+++ b/arch/arm/mach-omap2/clock34xx.h
|
||||
@@ -815,6 +815,8 @@ static struct clk dpll4_m4_ck = {
|
||||
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
|
||||
PARENT_CONTROLS_CLOCK,
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
+ .set_rate = &omap2_clksel_set_rate,
|
||||
+ .round_rate = &omap2_clksel_round_rate,
|
||||
};
|
||||
|
||||
/* The PWRDN bit is apparently only available on 3430ES2 and above */
|
||||
@@ -0,0 +1,62 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Tue, 22 Jul 2008 00:58:18 +0000 (+0100)
|
||||
Subject: ARM: OMAP: add clk_get_parent() for OMAP2/3
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=e2de5e5578fbaa9b4b75074796da0608fc93e6ae
|
||||
|
||||
ARM: OMAP: add clk_get_parent() for OMAP2/3
|
||||
|
||||
Signed-off-by: Mans Rullgard <mans@mansr.com>
|
||||
---
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
|
||||
index 577be44..28aec36 100644
|
||||
--- a/arch/arm/mach-omap2/clock.c
|
||||
+++ b/arch/arm/mach-omap2/clock.c
|
||||
@@ -824,6 +824,11 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+struct clk *omap2_clk_get_parent(struct clk *clk)
|
||||
+{
|
||||
+ return clk->parent;
|
||||
+}
|
||||
+
|
||||
/* DPLL rate rounding code */
|
||||
|
||||
/**
|
||||
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
|
||||
index 49245f7..4aa69d5 100644
|
||||
--- a/arch/arm/mach-omap2/clock.h
|
||||
+++ b/arch/arm/mach-omap2/clock.h
|
||||
@@ -29,6 +29,7 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
|
||||
int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
|
||||
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
|
||||
+struct clk *omap2_clk_get_parent(struct clk *clk);
|
||||
|
||||
#ifdef CONFIG_OMAP_RESET_CLOCKS
|
||||
void omap2_clk_disable_unused(struct clk *clk);
|
||||
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
|
||||
index 54cc6e1..ed7af21 100644
|
||||
--- a/arch/arm/mach-omap2/clock24xx.c
|
||||
+++ b/arch/arm/mach-omap2/clock24xx.c
|
||||
@@ -422,6 +422,7 @@ static struct clk_functions omap2_clk_functions = {
|
||||
.clk_round_rate = omap2_clk_round_rate,
|
||||
.clk_set_rate = omap2_clk_set_rate,
|
||||
.clk_set_parent = omap2_clk_set_parent,
|
||||
+ .clk_get_parent = omap2_clk_get_parent,
|
||||
.clk_disable_unused = omap2_clk_disable_unused,
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
.clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
|
||||
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
|
||||
index 04dedec..08c8c46 100644
|
||||
--- a/arch/arm/mach-omap2/clock34xx.c
|
||||
+++ b/arch/arm/mach-omap2/clock34xx.c
|
||||
@@ -541,6 +541,7 @@ static struct clk_functions omap2_clk_functions = {
|
||||
.clk_round_rate = omap2_clk_round_rate,
|
||||
.clk_set_rate = omap2_clk_set_rate,
|
||||
.clk_set_parent = omap2_clk_set_parent,
|
||||
+ .clk_get_parent = omap2_clk_get_parent,
|
||||
.clk_disable_unused = omap2_clk_disable_unused,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Wed, 23 Jul 2008 08:40:07 +0000 (+0100)
|
||||
Subject: ARM: OMAP: Set DSS1_ALWON_FCLK to a multiple of the pixel clock
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=01ee28c50701caa94739e764c3dae9298edd8216
|
||||
|
||||
ARM: OMAP: Set DSS1_ALWON_FCLK to a multiple of the pixel clock
|
||||
|
||||
This sets the DSS1_ALWON_FCLK clock as close as possible to a
|
||||
multiple of the requested pixel clock, while keeping it below
|
||||
the 173MHz limit.
|
||||
|
||||
Due to of the structure of the clock tree, dss1_alwon_fck cannot
|
||||
be set directly, and we must use dpll4_m4_ck instead.
|
||||
|
||||
Signed-off-by: Mans Rullgard <mans@mansr.com>
|
||||
---
|
||||
|
||||
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
|
||||
index fd06ca2..e0e8528 100644
|
||||
--- a/drivers/video/omap/dispc.c
|
||||
+++ b/drivers/video/omap/dispc.c
|
||||
@@ -176,6 +176,7 @@ static struct {
|
||||
|
||||
struct clk *dss_ick, *dss1_fck;
|
||||
struct clk *dss_54m_fck;
|
||||
+ struct clk *dpll4_m4_ck;
|
||||
|
||||
enum omapfb_update_mode update_mode;
|
||||
struct omapfb_device *fbdev;
|
||||
@@ -738,21 +739,34 @@ static void setup_color_conv_coef(void)
|
||||
MOD_REG_FLD(at2_reg, (1 << 11), ct->full_range);
|
||||
}
|
||||
|
||||
-#define MAX_FCK_LCD 173000000
|
||||
+#define MAX_FCK 173000000
|
||||
|
||||
static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div)
|
||||
{
|
||||
+ unsigned long prate = clk_get_rate(clk_get_parent(dispc.dpll4_m4_ck));
|
||||
+ unsigned long pcd_min = is_tft? 2: 3;
|
||||
+ unsigned long fck_div;
|
||||
unsigned long fck, lck;
|
||||
|
||||
pck = max(1, pck);
|
||||
+
|
||||
+ if (pck * pcd_min > MAX_FCK) {
|
||||
+ dev_warn(dispc.fbdev->dev, "pixclock %d kHz too high.\n",
|
||||
+ pck / 1000);
|
||||
+ pck = MAX_FCK / pcd_min;
|
||||
+ }
|
||||
+
|
||||
+ fck = pck * 2;
|
||||
+ fck_div = (prate + pck) / fck;
|
||||
+ if (fck_div > 16)
|
||||
+ fck_div /= (fck_div + 15) / 16;
|
||||
+ if (fck_div < 1)
|
||||
+ fck_div = 1;
|
||||
+ clk_set_rate(dispc.dpll4_m4_ck, prate / fck_div);
|
||||
fck = clk_get_rate(dispc.dss1_fck);
|
||||
- *lck_div = (fck + MAX_FCK_LCD - 1) / MAX_FCK_LCD;
|
||||
- lck = fck / *lck_div;
|
||||
- *pck_div = (lck + pck - 1) / pck;
|
||||
- if (is_tft)
|
||||
- *pck_div = max(2, *pck_div);
|
||||
- else
|
||||
- *pck_div = max(3, *pck_div);
|
||||
+
|
||||
+ *lck_div = 1;
|
||||
+ *pck_div = (fck + pck - 1) / pck;
|
||||
if (*pck_div > 255) {
|
||||
*pck_div = 255;
|
||||
lck = pck * *pck_div;
|
||||
@@ -914,11 +928,21 @@ static int get_dss_clocks(void)
|
||||
return PTR_ERR(dispc.dss_54m_fck);
|
||||
}
|
||||
|
||||
+ if (IS_ERR((dispc.dpll4_m4_ck =
|
||||
+ clk_get(dispc.fbdev->dev, "dpll4_m4_ck")))) {
|
||||
+ dev_err(dispc.fbdev->dev, "can't get dpll4_m4_ck");
|
||||
+ clk_put(dispc.dss_ick);
|
||||
+ clk_put(dispc.dss1_fck);
|
||||
+ clk_put(dispc.dss_54m_fck);
|
||||
+ return PTR_ERR(dispc.dss_54m_fck);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void put_dss_clocks(void)
|
||||
{
|
||||
+ clk_put(dispc.dpll4_m4_ck);
|
||||
clk_put(dispc.dss_54m_fck);
|
||||
clk_put(dispc.dss1_fck);
|
||||
clk_put(dispc.dss_ick);
|
||||
@@ -0,0 +1,75 @@
|
||||
From: Mans Rullgard <mans@mansr.com>
|
||||
Date: Wed, 30 Jul 2008 08:25:51 +0000 (+0100)
|
||||
Subject: ARM: NEON L1 cache bug workaround (erratum 451034)
|
||||
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=26023493baf13e0a67fd6cf08d87be5ff6f7c56d
|
||||
|
||||
ARM: NEON L1 cache bug workaround (erratum 451034)
|
||||
|
||||
On Cortex-A8 r1p0 and r1p1, executing a NEON store with an integer
|
||||
store in the store buffer, can cause a processor deadlock under
|
||||
certain conditions.
|
||||
|
||||
Executing a DMB instruction before saving NEON/VFP registers and before
|
||||
return to userspace makes it safe to run code which includes similar
|
||||
counter-measures. Userspace code can still trigger the deadlock, so
|
||||
a different workaround is required to safely run untrusted code.
|
||||
|
||||
See ARM Cortex-A8 Errata Notice (PR120-PRDC-008070) for full details.
|
||||
---
|
||||
|
||||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
|
||||
index 8c75840..1172e14 100644
|
||||
--- a/arch/arm/Kconfig
|
||||
+++ b/arch/arm/Kconfig
|
||||
@@ -1071,6 +1071,22 @@ config NEON
|
||||
Say Y to include support code for NEON, the ARMv7 Advanced SIMD
|
||||
Extension.
|
||||
|
||||
+config NEON_CACHE_BUG
|
||||
+ bool "NEON L1 cache bug workaround (erratum 451034)"
|
||||
+ depends on VFPv3
|
||||
+ help
|
||||
+ On Cortex-A8 r1p0 and r1p1, executing a NEON store with an integer
|
||||
+ store in the store buffer, can cause a processor deadlock under
|
||||
+ certain conditions.
|
||||
+
|
||||
+ See ARM Cortex-A8 Errata Notice (PR120-PRDC-008070) for full details.
|
||||
+
|
||||
+ Say Y to include a workaround.
|
||||
+
|
||||
+ WARNING: Even with this option enabled, userspace code can trigger
|
||||
+ the deadlock. To safely run untrusted code, a different fix is
|
||||
+ required.
|
||||
+
|
||||
endmenu
|
||||
|
||||
menu "Userspace binary formats"
|
||||
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
|
||||
index 597ed00..e50094e 100644
|
||||
--- a/arch/arm/kernel/entry-common.S
|
||||
+++ b/arch/arm/kernel/entry-common.S
|
||||
@@ -68,6 +68,10 @@ no_work_pending:
|
||||
/* perform architecture specific actions before user return */
|
||||
arch_ret_to_user r1, lr
|
||||
|
||||
+#ifdef CONFIG_NEON_CACHE_BUG
|
||||
+ dmb
|
||||
+#endif
|
||||
+
|
||||
@ slow_restore_user_regs
|
||||
ldr r1, [sp, #S_PSR] @ get calling cpsr
|
||||
ldr lr, [sp, #S_PC]! @ get pc
|
||||
diff --git a/include/asm-arm/vfpmacros.h b/include/asm-arm/vfpmacros.h
|
||||
index cccb389..c9d2976 100644
|
||||
--- a/include/asm-arm/vfpmacros.h
|
||||
+++ b/include/asm-arm/vfpmacros.h
|
||||
@@ -32,6 +32,9 @@
|
||||
|
||||
@ write all the working registers out of the VFP
|
||||
.macro VFPFSTMIA, base, tmp
|
||||
+#ifdef CONFIG_NEON_CACHE_BUG
|
||||
+ dmb
|
||||
+#endif
|
||||
#if __LINUX_ARM_ARCH__ < 6
|
||||
STC p11, cr0, [\base],#33*4 @ FSTMIAX \base!, {d0-d15}
|
||||
#else
|
||||
@@ -0,0 +1,15 @@
|
||||
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
|
||||
index 1d437de..33b3feb 100644
|
||||
--- a/fs/jffs2/scan.c
|
||||
+++ b/fs/jffs2/scan.c
|
||||
@@ -647,8 +647,8 @@ scan_more:
|
||||
inbuf_ofs = ofs - buf_ofs;
|
||||
while (inbuf_ofs < scan_end) {
|
||||
if (unlikely(*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff)) {
|
||||
- printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
|
||||
- empty_start, ofs);
|
||||
+// printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
|
||||
+// empty_start, ofs);
|
||||
if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start)))
|
||||
return err;
|
||||
goto scan_more;
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /tmp/Makefile 2008-04-24 14:36:20.509598016 +0200
|
||||
+++ git/arch/arm/Makefile 2008-04-24 14:36:31.949546584 +0200
|
||||
@@ -47,7 +47,7 @@
|
||||
# Note that GCC does not numerically define an architecture version
|
||||
# macro, but instead defines a whole series of macros which makes
|
||||
# testing for a specific architecture or later rather impossible.
|
||||
-arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7a,-march=armv5t -Wa$(comma)-march=armv7a)
|
||||
+arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
|
||||
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
|
||||
# Only override the compiler option if ARMv6. The ARMv6K extensions are
|
||||
# always available in ARMv7
|
||||
@@ -0,0 +1,114 @@
|
||||
From linux-omap-owner@vger.kernel.org Tue Jun 24 09:24:30 2008
|
||||
Received: from localhost
|
||||
([127.0.0.1] helo=dominion ident=koen)
|
||||
by dominion.dominion.void with esmtp (Exim 4.63)
|
||||
(envelope-from <linux-omap-owner@vger.kernel.org>)
|
||||
id 1KB2tB-0005XT-FQ
|
||||
for koen@localhost; Tue, 24 Jun 2008 09:24:30 +0200
|
||||
Received: from xs.service.utwente.nl [130.89.5.250]
|
||||
by dominion with POP3 (fetchmail-6.3.6)
|
||||
for <koen@localhost> (single-drop); Tue, 24 Jun 2008 09:24:29 +0200 (CEST)
|
||||
Received: from mail.service.utwente.nl ([130.89.5.254]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
|
||||
Tue, 24 Jun 2008 09:13:04 +0200
|
||||
Received: from mx.utwente.nl ([130.89.2.13]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
|
||||
Tue, 24 Jun 2008 09:13:03 +0200
|
||||
Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
|
||||
by mx.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id m5O7CcD7008917
|
||||
for <k.kooi@student.utwente.nl>; Tue, 24 Jun 2008 09:12:38 +0200
|
||||
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
||||
id S1751623AbYFXHMh (ORCPT <rfc822;k.kooi@student.utwente.nl>);
|
||||
Tue, 24 Jun 2008 03:12:37 -0400
|
||||
Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751670AbYFXHMh
|
||||
(ORCPT <rfc822;linux-omap-outgoing>);
|
||||
Tue, 24 Jun 2008 03:12:37 -0400
|
||||
Received: from utopia.booyaka.com ([72.9.107.138]:47392 "EHLO
|
||||
utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
|
||||
with ESMTP id S1751623AbYFXHMg (ORCPT
|
||||
<rfc822;linux-omap@vger.kernel.org>); Tue, 24 Jun 2008 03:12:36 -0400
|
||||
Received: (qmail 1797 invoked by uid 526); 24 Jun 2008 07:12:35 -0000
|
||||
Date: Tue, 24 Jun 2008 01:12:35 -0600 (MDT)
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
To: linux-omap@vger.kernel.org
|
||||
Subject: [PATCH] OMAP3 clock: DPLL{1,2}_FCLK clksel can divide by 4
|
||||
Message-ID: <alpine.DEB.1.00.0806240111320.9741@utopia.booyaka.com>
|
||||
User-Agent: Alpine 1.00 (DEB 882 2007-12-20)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: TEXT/PLAIN; charset=US-ASCII
|
||||
Sender: linux-omap-owner@vger.kernel.org
|
||||
Precedence: bulk
|
||||
List-ID: <linux-omap.vger.kernel.org>
|
||||
X-Mailing-List: linux-omap@vger.kernel.org
|
||||
X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact servicedesk@icts.utwente.nl for more information.
|
||||
X-UTwente-MailScanner: Found to be clean
|
||||
X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org
|
||||
X-Spam-Status: No
|
||||
X-OriginalArrivalTime: 24 Jun 2008 07:13:04.0264 (UTC) FILETIME=[BE950880:01C8D5C9]
|
||||
|
||||
|
||||
OMAP34xx ES2 TRM Delta G to H states that the divider for DPLL1_FCLK and
|
||||
DPLL2_FCLK can divide by 4 in addition to dividing by 1 and 2. Encode this
|
||||
into the OMAP3 clock framework.
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
arch/arm/mach-omap2/clock34xx.h | 20 ++++++++++++++++----
|
||||
1 files changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
|
||||
index b4dceea..9605744 100644
|
||||
--- a/arch/arm/mach-omap2/clock34xx.h
|
||||
+++ b/arch/arm/mach-omap2/clock34xx.h
|
||||
@@ -1029,8 +1029,15 @@ static struct clk corex2_fck = {
|
||||
|
||||
/* DPLL power domain clock controls */
|
||||
|
||||
-static const struct clksel div2_core_clksel[] = {
|
||||
- { .parent = &core_ck, .rates = div2_rates },
|
||||
+static const struct clksel_rate div4_rates[] = {
|
||||
+ { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
|
||||
+ { .div = 2, .val = 2, .flags = RATE_IN_343X },
|
||||
+ { .div = 4, .val = 4, .flags = RATE_IN_343X },
|
||||
+ { .div = 0 }
|
||||
+};
|
||||
+
|
||||
+static const struct clksel div4_core_clksel[] = {
|
||||
+ { .parent = &core_ck, .rates = div4_rates },
|
||||
{ .parent = NULL }
|
||||
};
|
||||
|
||||
@@ -1044,7 +1051,7 @@ static struct clk dpll1_fck = {
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.clksel_reg = _OMAP34XX_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
|
||||
.clksel_mask = OMAP3430_MPU_CLK_SRC_MASK,
|
||||
- .clksel = div2_core_clksel,
|
||||
+ .clksel = div4_core_clksel,
|
||||
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
|
||||
PARENT_CONTROLS_CLOCK,
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
@@ -1119,7 +1126,7 @@ static struct clk dpll2_fck = {
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.clksel_reg = _OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
|
||||
.clksel_mask = OMAP3430_IVA2_CLK_SRC_MASK,
|
||||
- .clksel = div2_core_clksel,
|
||||
+ .clksel = div4_core_clksel,
|
||||
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
|
||||
PARENT_CONTROLS_CLOCK,
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
@@ -1155,6 +1162,11 @@ static struct clk iva2_ck = {
|
||||
|
||||
/* Common interface clocks */
|
||||
|
||||
+static const struct clksel div2_core_clksel[] = {
|
||||
+ { .parent = &core_ck, .rates = div2_rates },
|
||||
+ { .parent = NULL }
|
||||
+};
|
||||
+
|
||||
static struct clk l3_ick = {
|
||||
.name = "l3_ick",
|
||||
.parent = &core_ck,
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
From linux-omap-owner@vger.kernel.org Tue Jun 24 09:24:30 2008
|
||||
Received: from localhost
|
||||
([127.0.0.1] helo=dominion ident=koen)
|
||||
by dominion.dominion.void with esmtp (Exim 4.63)
|
||||
(envelope-from <linux-omap-owner@vger.kernel.org>)
|
||||
id 1KB2tC-0005XT-Mj
|
||||
for koen@localhost; Tue, 24 Jun 2008 09:24:30 +0200
|
||||
Received: from xs.service.utwente.nl [130.89.5.250]
|
||||
by dominion with POP3 (fetchmail-6.3.6)
|
||||
for <koen@localhost> (single-drop); Tue, 24 Jun 2008 09:24:30 +0200 (CEST)
|
||||
Received: from mail.service.utwente.nl ([130.89.5.253]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
|
||||
Tue, 24 Jun 2008 09:20:48 +0200
|
||||
Received: from smtp.utwente.nl ([130.89.2.8]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
|
||||
Tue, 24 Jun 2008 09:20:47 +0200
|
||||
Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
|
||||
by smtp.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id m5O7BPWU031214
|
||||
for <k.kooi@student.utwente.nl>; Tue, 24 Jun 2008 09:11:25 +0200
|
||||
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
||||
id S1751128AbYFXHLY (ORCPT <rfc822;k.kooi@student.utwente.nl>);
|
||||
Tue, 24 Jun 2008 03:11:24 -0400
|
||||
Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751405AbYFXHLX
|
||||
(ORCPT <rfc822;linux-omap-outgoing>);
|
||||
Tue, 24 Jun 2008 03:11:23 -0400
|
||||
Received: from utopia.booyaka.com ([72.9.107.138]:44580 "EHLO
|
||||
utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
|
||||
with ESMTP id S1751128AbYFXHLX (ORCPT
|
||||
<rfc822;linux-omap@vger.kernel.org>); Tue, 24 Jun 2008 03:11:23 -0400
|
||||
Received: (qmail 1744 invoked by uid 526); 24 Jun 2008 07:11:21 -0000
|
||||
Date: Tue, 24 Jun 2008 01:11:21 -0600 (MDT)
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
To: linux-omap@vger.kernel.org
|
||||
Subject: [PATCH] OMAP3 clock: fix DPLL jitter correction and rate
|
||||
programming
|
||||
Message-ID: <alpine.DEB.1.00.0806240109440.9741@utopia.booyaka.com>
|
||||
User-Agent: Alpine 1.00 (DEB 882 2007-12-20)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: TEXT/PLAIN; charset=US-ASCII
|
||||
Sender: linux-omap-owner@vger.kernel.org
|
||||
Precedence: bulk
|
||||
List-ID: <linux-omap.vger.kernel.org>
|
||||
X-Mailing-List: linux-omap@vger.kernel.org
|
||||
X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact servicedesk@icts.utwente.nl for more information.
|
||||
X-UTwente-MailScanner: Found to be clean
|
||||
X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org
|
||||
X-Spam-Status: No
|
||||
X-OriginalArrivalTime: 24 Jun 2008 07:20:48.0265 (UTC) FILETIME=[D325F790:01C8D5CA]
|
||||
|
||||
|
||||
Fix DPLL jitter correction programming. Previously,
|
||||
omap3_noncore_dpll_program() stored the FREQSEL jitter correction
|
||||
parameter to the wrong register. This caused jitter correction to be set
|
||||
incorrectly and also caused the DPLL divider to be programmed incorrectly.
|
||||
|
||||
Also, fix DPLL divider programming. An off-by-one error existed in
|
||||
omap3_noncore_dpll_program(), causing DPLLs to be programmed with a higher
|
||||
divider than intended.
|
||||
|
||||
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||
---
|
||||
|
||||
arch/arm/mach-omap2/clock34xx.c | 13 ++++++++-----
|
||||
1 files changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
|
||||
index 408b51a..8fdf8f3 100644
|
||||
--- a/arch/arm/mach-omap2/clock34xx.c
|
||||
+++ b/arch/arm/mach-omap2/clock34xx.c
|
||||
@@ -346,14 +346,17 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
|
||||
/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
|
||||
_omap3_noncore_dpll_bypass(clk);
|
||||
|
||||
+ /* Set jitter correction */
|
||||
+ v = __raw_readl(dd->control_reg);
|
||||
+ v &= ~dd->freqsel_mask;
|
||||
+ v |= freqsel << __ffs(dd->freqsel_mask);
|
||||
+ __raw_writel(v, dd->control_reg);
|
||||
+
|
||||
+ /* Set DPLL multiplier, divider */
|
||||
v = __raw_readl(dd->mult_div1_reg);
|
||||
v &= ~(dd->mult_mask | dd->div1_mask);
|
||||
-
|
||||
- /* Set mult (M), div1 (N), freqsel */
|
||||
v |= m << __ffs(dd->mult_mask);
|
||||
- v |= n << __ffs(dd->div1_mask);
|
||||
- v |= freqsel << __ffs(dd->freqsel_mask);
|
||||
-
|
||||
+ v |= (n - 1) << __ffs(dd->div1_mask);
|
||||
__raw_writel(v, dd->mult_div1_reg);
|
||||
|
||||
/* We let the clock framework set the other output dividers later */
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
||||
@@ -0,0 +1,611 @@
|
||||
Hi,
|
||||
|
||||
This patch adds Oprofile support on ARMv7, using the PMNC unit.
|
||||
Tested on OMAP3430 SDP.
|
||||
|
||||
Feedback and comments are welcome.
|
||||
|
||||
The patch to user space components is attached for reference. It i applies
|
||||
against version 0.9.3 of oprofile source
|
||||
(http://prdownloads.sourceforge.net/oprofile/oprofile-0.9.3.tar.gz).
|
||||
|
||||
Regards,
|
||||
Jean.
|
||||
|
||||
---
|
||||
|
||||
From: Jean Pihet <jpihet@mvista.com>
|
||||
Date: Tue, 6 May 2008 17:21:44 +0200
|
||||
Subject: [PATCH] ARM: Add ARMv7 oprofile support
|
||||
|
||||
Add ARMv7 Oprofile support to kernel
|
||||
|
||||
Signed-off-by: Jean Pihet <jpihet@mvista.com>
|
||||
---
|
||||
|
||||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
|
||||
index c60a27d..60b50a0 100644
|
||||
--- a/arch/arm/Kconfig
|
||||
+++ b/arch/arm/Kconfig
|
||||
@@ -161,6 +161,11 @@ config OPROFILE_MPCORE
|
||||
config OPROFILE_ARM11_CORE
|
||||
bool
|
||||
|
||||
+config OPROFILE_ARMV7
|
||||
+ def_bool y
|
||||
+ depends on CPU_V7 && !SMP
|
||||
+ bool
|
||||
+
|
||||
endif
|
||||
|
||||
config VECTORS_BASE
|
||||
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
|
||||
index e61d0cc..88e31f5 100644
|
||||
--- a/arch/arm/oprofile/Makefile
|
||||
+++ b/arch/arm/oprofile/Makefile
|
||||
@@ -11,3 +11,4 @@ oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o
|
||||
oprofile-$(CONFIG_OPROFILE_ARM11_CORE) += op_model_arm11_core.o
|
||||
oprofile-$(CONFIG_OPROFILE_ARMV6) += op_model_v6.o
|
||||
oprofile-$(CONFIG_OPROFILE_MPCORE) += op_model_mpcore.o
|
||||
+oprofile-$(CONFIG_OPROFILE_ARMV7) += op_model_v7.o
|
||||
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
|
||||
index 0a5cf3a..3fcd752 100644
|
||||
--- a/arch/arm/oprofile/common.c
|
||||
+++ b/arch/arm/oprofile/common.c
|
||||
@@ -145,6 +145,10 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
|
||||
spec = &op_mpcore_spec;
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_OPROFILE_ARMV7
|
||||
+ spec = &op_armv7_spec;
|
||||
+#endif
|
||||
+
|
||||
if (spec) {
|
||||
ret = spec->init();
|
||||
if (ret < 0)
|
||||
diff --git a/arch/arm/oprofile/op_arm_model.h
|
||||
b/arch/arm/oprofile/op_arm_model.h
|
||||
index 4899c62..8c4e4f6 100644
|
||||
--- a/arch/arm/oprofile/op_arm_model.h
|
||||
+++ b/arch/arm/oprofile/op_arm_model.h
|
||||
@@ -26,6 +26,7 @@ extern struct op_arm_model_spec op_xscale_spec;
|
||||
|
||||
extern struct op_arm_model_spec op_armv6_spec;
|
||||
extern struct op_arm_model_spec op_mpcore_spec;
|
||||
+extern struct op_arm_model_spec op_armv7_spec;
|
||||
|
||||
extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
|
||||
|
||||
diff --git a/arch/arm/oprofile/op_model_v7.c b/arch/arm/oprofile/op_model_v7.c
|
||||
new file mode 100644
|
||||
index 0000000..a159bc1
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/oprofile/op_model_v7.c
|
||||
@@ -0,0 +1,407 @@
|
||||
+/**
|
||||
+ * @file op_model_v7.c
|
||||
+ * ARM V7 (Cortex A8) Event Monitor Driver
|
||||
+ *
|
||||
+ * @remark Copyright 2008 Jean Pihet <jpihet@mvista.com>
|
||||
+ * @remark Copyright 2004 ARM SMP Development Team
|
||||
+ */
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/oprofile.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/smp.h>
|
||||
+
|
||||
+#include "op_counter.h"
|
||||
+#include "op_arm_model.h"
|
||||
+#include "op_model_v7.h"
|
||||
+
|
||||
+/* #define DEBUG */
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * ARM V7 PMNC support
|
||||
+ */
|
||||
+
|
||||
+static u32 cnt_en[CNTMAX];
|
||||
+
|
||||
+static inline void armv7_pmnc_write(u32 val)
|
||||
+{
|
||||
+ val &= PMNC_MASK;
|
||||
+ asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (val));
|
||||
+}
|
||||
+
|
||||
+static inline u32 armv7_pmnc_read(void)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static inline u32 armv7_pmnc_enable_counter(unsigned int cnt)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (cnt >= CNTMAX) {
|
||||
+ printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
|
||||
+ " %d\n", smp_processor_id(), cnt);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (cnt == CCNT)
|
||||
+ val = CNTENS_C;
|
||||
+ else
|
||||
+ val = (1 << (cnt - CNT0));
|
||||
+
|
||||
+ val &= CNTENS_MASK;
|
||||
+ asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
|
||||
+
|
||||
+ return cnt;
|
||||
+}
|
||||
+
|
||||
+static inline u32 armv7_pmnc_disable_counter(unsigned int cnt)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (cnt >= CNTMAX) {
|
||||
+ printk(KERN_ERR "oprofile: CPU%u disabling wrong PMNC counter"
|
||||
+ " %d\n", smp_processor_id(), cnt);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (cnt == CCNT)
|
||||
+ val = CNTENC_C;
|
||||
+ else
|
||||
+ val = (1 << (cnt - CNT0));
|
||||
+
|
||||
+ val &= CNTENC_MASK;
|
||||
+ asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
|
||||
+
|
||||
+ return cnt;
|
||||
+}
|
||||
+
|
||||
+static inline u32 armv7_pmnc_enable_intens(unsigned int cnt)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (cnt >= CNTMAX) {
|
||||
+ printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
|
||||
+ " interrupt enable %d\n", smp_processor_id(), cnt);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (cnt == CCNT)
|
||||
+ val = INTENS_C;
|
||||
+ else
|
||||
+ val = (1 << (cnt - CNT0));
|
||||
+
|
||||
+ val &= INTENS_MASK;
|
||||
+ asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
|
||||
+
|
||||
+ return cnt;
|
||||
+}
|
||||
+
|
||||
+static inline u32 armv7_pmnc_getreset_flags(void)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Read */
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
|
||||
+
|
||||
+ /* Write to clear flags */
|
||||
+ val &= FLAG_MASK;
|
||||
+ asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
|
||||
+
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static inline int armv7_pmnc_select_counter(unsigned int cnt)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ if ((cnt == CCNT) || (cnt >= CNTMAX)) {
|
||||
+ printk(KERN_ERR "oprofile: CPU%u selecting wrong PMNC counteri"
|
||||
+ " %d\n", smp_processor_id(), cnt);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ val = (cnt - CNT0) & SELECT_MASK;
|
||||
+ asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
|
||||
+
|
||||
+ return cnt;
|
||||
+}
|
||||
+
|
||||
+static inline void armv7_pmnc_write_evtsel(unsigned int cnt, u32 val)
|
||||
+{
|
||||
+ if (armv7_pmnc_select_counter(cnt) == cnt) {
|
||||
+ val &= EVTSEL_MASK;
|
||||
+ asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void armv7_pmnc_reset_counter(unsigned int cnt)
|
||||
+{
|
||||
+ u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
|
||||
+ u32 val = -(u32)counter_config[cpu_cnt].count;
|
||||
+
|
||||
+ switch (cnt) {
|
||||
+ case CCNT:
|
||||
+ armv7_pmnc_disable_counter(cnt);
|
||||
+
|
||||
+ asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val));
|
||||
+
|
||||
+ if (cnt_en[cnt] != 0)
|
||||
+ armv7_pmnc_enable_counter(cnt);
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ case CNT0:
|
||||
+ case CNT1:
|
||||
+ case CNT2:
|
||||
+ case CNT3:
|
||||
+ armv7_pmnc_disable_counter(cnt);
|
||||
+
|
||||
+ if (armv7_pmnc_select_counter(cnt) == cnt)
|
||||
+ asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val));
|
||||
+
|
||||
+ if (cnt_en[cnt] != 0)
|
||||
+ armv7_pmnc_enable_counter(cnt);
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ printk(KERN_ERR "oprofile: CPU%u resetting wrong PMNC counter"
|
||||
+ " %d\n", smp_processor_id(), cnt);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int armv7_setup_pmnc(void)
|
||||
+{
|
||||
+ unsigned int cnt;
|
||||
+
|
||||
+ if (armv7_pmnc_read() & PMNC_E) {
|
||||
+ printk(KERN_ERR "oprofile: CPU%u PMNC still enabled when setup"
|
||||
+ " new event counter.\n", smp_processor_id());
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Initialize & Reset PMNC: C bit, D bit and P bit.
|
||||
+ * Note: Using a slower count for CCNT (D bit: divide by 64) results
|
||||
+ * in a more stable system
|
||||
+ */
|
||||
+ armv7_pmnc_write(PMNC_P | PMNC_C | PMNC_D);
|
||||
+
|
||||
+
|
||||
+ for (cnt = CCNT; cnt < CNTMAX; cnt++) {
|
||||
+ unsigned long event;
|
||||
+ u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
|
||||
+
|
||||
+ /*
|
||||
+ * Disable counter
|
||||
+ */
|
||||
+ armv7_pmnc_disable_counter(cnt);
|
||||
+ cnt_en[cnt] = 0;
|
||||
+
|
||||
+ if (!counter_config[cpu_cnt].enabled)
|
||||
+ continue;
|
||||
+
|
||||
+ event = counter_config[cpu_cnt].event & 255;
|
||||
+
|
||||
+ /*
|
||||
+ * Set event (if destined for PMNx counters)
|
||||
+ * We don't need to set the event if it's a cycle count
|
||||
+ */
|
||||
+ if (cnt != CCNT)
|
||||
+ armv7_pmnc_write_evtsel(cnt, event);
|
||||
+
|
||||
+ /*
|
||||
+ * Enable interrupt for this counter
|
||||
+ */
|
||||
+ armv7_pmnc_enable_intens(cnt);
|
||||
+
|
||||
+ /*
|
||||
+ * Reset counter
|
||||
+ */
|
||||
+ armv7_pmnc_reset_counter(cnt);
|
||||
+
|
||||
+ /*
|
||||
+ * Enable counter
|
||||
+ */
|
||||
+ armv7_pmnc_enable_counter(cnt);
|
||||
+ cnt_en[cnt] = 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void armv7_start_pmnc(void)
|
||||
+{
|
||||
+ armv7_pmnc_write(armv7_pmnc_read() | PMNC_E);
|
||||
+}
|
||||
+
|
||||
+static inline void armv7_stop_pmnc(void)
|
||||
+{
|
||||
+ armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * CPU counters' IRQ handler (one IRQ per CPU)
|
||||
+ */
|
||||
+static irqreturn_t armv7_pmnc_interrupt(int irq, void *arg)
|
||||
+{
|
||||
+ struct pt_regs *regs = get_irq_regs();
|
||||
+ unsigned int cnt;
|
||||
+ u32 flags;
|
||||
+
|
||||
+
|
||||
+ /*
|
||||
+ * Stop IRQ generation
|
||||
+ */
|
||||
+ armv7_stop_pmnc();
|
||||
+
|
||||
+ /*
|
||||
+ * Get and reset overflow status flags
|
||||
+ */
|
||||
+ flags = armv7_pmnc_getreset_flags();
|
||||
+
|
||||
+ /*
|
||||
+ * Cycle counter
|
||||
+ */
|
||||
+ if (flags & FLAG_C) {
|
||||
+ u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), CCNT);
|
||||
+ armv7_pmnc_reset_counter(CCNT);
|
||||
+ oprofile_add_sample(regs, cpu_cnt);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * PMNC counters 0:3
|
||||
+ */
|
||||
+ for (cnt = CNT0; cnt < CNTMAX; cnt++) {
|
||||
+ if (flags & (1 << (cnt - CNT0))) {
|
||||
+ u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
|
||||
+ armv7_pmnc_reset_counter(cnt);
|
||||
+ oprofile_add_sample(regs, cpu_cnt);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Allow IRQ generation
|
||||
+ */
|
||||
+ armv7_start_pmnc();
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+int armv7_request_interrupts(int *irqs, int nr)
|
||||
+{
|
||||
+ unsigned int i;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ for (i = 0; i < nr; i++) {
|
||||
+ ret = request_irq(irqs[i], armv7_pmnc_interrupt,
|
||||
+ IRQF_DISABLED, "CP15 PMNC", NULL);
|
||||
+ if (ret != 0) {
|
||||
+ printk(KERN_ERR "oprofile: unable to request IRQ%u"
|
||||
+ " for ARMv7\n",
|
||||
+ irqs[i]);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (i != nr)
|
||||
+ while (i-- != 0)
|
||||
+ free_irq(irqs[i], NULL);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void armv7_release_interrupts(int *irqs, int nr)
|
||||
+{
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < nr; i++)
|
||||
+ free_irq(irqs[i], NULL);
|
||||
+}
|
||||
+
|
||||
+#ifdef DEBUG
|
||||
+static void armv7_pmnc_dump_regs(void)
|
||||
+{
|
||||
+ u32 val;
|
||||
+ unsigned int cnt;
|
||||
+
|
||||
+ printk(KERN_INFO "PMNC registers dump:\n");
|
||||
+
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
|
||||
+ printk(KERN_INFO "PMNC =0x%08x\n", val);
|
||||
+
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
|
||||
+ printk(KERN_INFO "CNTENS=0x%08x\n", val);
|
||||
+
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
|
||||
+ printk(KERN_INFO "INTENS=0x%08x\n", val);
|
||||
+
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
|
||||
+ printk(KERN_INFO "FLAGS =0x%08x\n", val);
|
||||
+
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
|
||||
+ printk(KERN_INFO "SELECT=0x%08x\n", val);
|
||||
+
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
|
||||
+ printk(KERN_INFO "CCNT =0x%08x\n", val);
|
||||
+
|
||||
+ for (cnt = CNT0; cnt < CNTMAX; cnt++) {
|
||||
+ armv7_pmnc_select_counter(cnt);
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
|
||||
+ printk(KERN_INFO "CNT[%d] count =0x%08x\n", cnt-CNT0, val);
|
||||
+ asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
|
||||
+ printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", cnt-CNT0, val);
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+static int irqs[] = {
|
||||
+#ifdef CONFIG_ARCH_OMAP3
|
||||
+ INT_34XX_BENCH_MPU_EMUL,
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+static void armv7_pmnc_stop(void)
|
||||
+{
|
||||
+#ifdef DEBUG
|
||||
+ armv7_pmnc_dump_regs();
|
||||
+#endif
|
||||
+ armv7_stop_pmnc();
|
||||
+ armv7_release_interrupts(irqs, ARRAY_SIZE(irqs));
|
||||
+}
|
||||
+
|
||||
+static int armv7_pmnc_start(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+#ifdef DEBUG
|
||||
+ armv7_pmnc_dump_regs();
|
||||
+#endif
|
||||
+ ret = armv7_request_interrupts(irqs, ARRAY_SIZE(irqs));
|
||||
+ if (ret >= 0)
|
||||
+ armv7_start_pmnc();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int armv7_detect_pmnc(void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+struct op_arm_model_spec op_armv7_spec = {
|
||||
+ .init = armv7_detect_pmnc,
|
||||
+ .num_counters = 5,
|
||||
+ .setup_ctrs = armv7_setup_pmnc,
|
||||
+ .start = armv7_pmnc_start,
|
||||
+ .stop = armv7_pmnc_stop,
|
||||
+ .name = "arm/armv7",
|
||||
+};
|
||||
diff --git a/arch/arm/oprofile/op_model_v7.h b/arch/arm/oprofile/op_model_v7.h
|
||||
new file mode 100644
|
||||
index 0000000..08f40ea
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/oprofile/op_model_v7.h
|
||||
@@ -0,0 +1,101 @@
|
||||
+/**
|
||||
+ * @file op_model_v7.h
|
||||
+ * ARM v7 (Cortex A8) Event Monitor Driver
|
||||
+ *
|
||||
+ * @remark Copyright 2008 Jean Pihet <jpihet@mvista.com>
|
||||
+ * @remark Copyright 2004 ARM SMP Development Team
|
||||
+ * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
|
||||
+ * @remark Copyright 2000-2004 MontaVista Software Inc
|
||||
+ * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
|
||||
+ * @remark Copyright 2004 Intel Corporation
|
||||
+ * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
|
||||
+ * @remark Copyright 2004 Oprofile Authors
|
||||
+ *
|
||||
+ * @remark Read the file COPYING
|
||||
+ *
|
||||
+ * @author Zwane Mwaikambo
|
||||
+ */
|
||||
+#ifndef OP_MODEL_V7_H
|
||||
+#define OP_MODEL_V7_H
|
||||
+
|
||||
+/*
|
||||
+ * Per-CPU PMNC: config reg
|
||||
+ */
|
||||
+#define PMNC_E (1 << 0) /* Enable all counters */
|
||||
+#define PMNC_P (1 << 1) /* Reset all counters */
|
||||
+#define PMNC_C (1 << 2) /* Cycle counter reset */
|
||||
+#define PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
|
||||
+#define PMNC_X (1 << 4) /* Export to ETM */
|
||||
+#define PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
|
||||
+#define PMNC_MASK 0x3f /* Mask for writable bits */
|
||||
+
|
||||
+/*
|
||||
+ * Available counters
|
||||
+ */
|
||||
+#define CCNT 0
|
||||
+#define CNT0 1
|
||||
+#define CNT1 2
|
||||
+#define CNT2 3
|
||||
+#define CNT3 4
|
||||
+#define CNTMAX 5
|
||||
+
|
||||
+#define CPU_COUNTER(cpu, counter) ((cpu) * CNTMAX + (counter))
|
||||
+
|
||||
+/*
|
||||
+ * CNTENS: counters enable reg
|
||||
+ */
|
||||
+#define CNTENS_P0 (1 << 0)
|
||||
+#define CNTENS_P1 (1 << 1)
|
||||
+#define CNTENS_P2 (1 << 2)
|
||||
+#define CNTENS_P3 (1 << 3)
|
||||
+#define CNTENS_C (1 << 31)
|
||||
+#define CNTENS_MASK 0x8000000f /* Mask for writable bits */
|
||||
+
|
||||
+/*
|
||||
+ * CNTENC: counters disable reg
|
||||
+ */
|
||||
+#define CNTENC_P0 (1 << 0)
|
||||
+#define CNTENC_P1 (1 << 1)
|
||||
+#define CNTENC_P2 (1 << 2)
|
||||
+#define CNTENC_P3 (1 << 3)
|
||||
+#define CNTENC_C (1 << 31)
|
||||
+#define CNTENC_MASK 0x8000000f /* Mask for writable bits */
|
||||
+
|
||||
+/*
|
||||
+ * INTENS: counters overflow interrupt enable reg
|
||||
+ */
|
||||
+#define INTENS_P0 (1 << 0)
|
||||
+#define INTENS_P1 (1 << 1)
|
||||
+#define INTENS_P2 (1 << 2)
|
||||
+#define INTENS_P3 (1 << 3)
|
||||
+#define INTENS_C (1 << 31)
|
||||
+#define INTENS_MASK 0x8000000f /* Mask for writable bits */
|
||||
+
|
||||
+/*
|
||||
+ * EVTSEL: Event selection reg
|
||||
+ */
|
||||
+#define EVTSEL_MASK 0x7f /* Mask for writable bits */
|
||||
+
|
||||
+/*
|
||||
+ * SELECT: Counter selection reg
|
||||
+ */
|
||||
+#define SELECT_MASK 0x1f /* Mask for writable bits */
|
||||
+
|
||||
+/*
|
||||
+ * FLAG: counters overflow flag status reg
|
||||
+ */
|
||||
+#define FLAG_P0 (1 << 0)
|
||||
+#define FLAG_P1 (1 << 1)
|
||||
+#define FLAG_P2 (1 << 2)
|
||||
+#define FLAG_P3 (1 << 3)
|
||||
+#define FLAG_C (1 << 31)
|
||||
+#define FLAG_MASK 0x8000000f /* Mask for writable bits */
|
||||
+
|
||||
+
|
||||
+int armv7_setup_pmu(void);
|
||||
+int armv7_start_pmu(void);
|
||||
+int armv7_stop_pmu(void);
|
||||
+int armv7_request_interrupts(int *, int);
|
||||
+void armv7_release_interrupts(int *, int);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/include/asm-arm/arch-omap/irqs.h
|
||||
b/include/asm-arm/arch-omap/irqs.h
|
||||
index c80e160..89ca90e 100644
|
||||
--- a/include/asm-arm/arch-omap/irqs.h
|
||||
+++ b/include/asm-arm/arch-omap/irqs.h
|
||||
@@ -297,6 +297,7 @@
|
||||
#define INT_243X_HS_USB_DMA 93
|
||||
#define INT_243X_CARKIT_IRQ 94
|
||||
|
||||
+#define INT_34XX_BENCH_MPU_EMUL 3
|
||||
#define INT_34XX_ST_MCBSP2_IRQ 4
|
||||
#define INT_34XX_ST_MCBSP3_IRQ 5
|
||||
#define INT_34XX_SYS_NIRQ 7
|
||||
@@ -0,0 +1,23 @@
|
||||
OMAP2/3 TAP: enable debug messages
|
||||
|
||||
From: Paul Walmsley <paul@pwsan.com>
|
||||
|
||||
This patch causes the OMAP2/3 chip ID code to display the full DIE_ID registers at boot.
|
||||
|
||||
---
|
||||
|
||||
arch/arm/mach-omap2/id.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
|
||||
index c7f9ab7..a154b5e 100644
|
||||
--- a/arch/arm/mach-omap2/id.c
|
||||
+++ b/arch/arm/mach-omap2/id.c
|
||||
@@ -10,6 +10,7 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
+#define DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -0,0 +1,18 @@
|
||||
--- /tmp/pm34xx.c 2008-07-14 18:09:08.000000000 +0200
|
||||
+++ git/arch/arm/mach-omap2/pm34xx.c 2008-07-14 18:09:42.453198000 +0200
|
||||
@@ -398,13 +398,13 @@
|
||||
INT_34XX_PRCM_MPU_IRQ);
|
||||
goto err1;
|
||||
}
|
||||
-
|
||||
+/*
|
||||
ret = pwrdm_for_each(pwrdms_setup);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "Failed to setup powerdomains\n");
|
||||
goto err2;
|
||||
}
|
||||
-
|
||||
+*/
|
||||
mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
|
||||
if (mpu_pwrdm == NULL) {
|
||||
printk(KERN_ERR "Failed to get mpu_pwrdm\n");
|
||||
1154
meta/recipes-kernel/linux/linux-omap2-git/beagleboard/soc.patch
Normal file
1154
meta/recipes-kernel/linux/linux-omap2-git/beagleboard/soc.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
|
||||
index b854a89..26f5569 100644
|
||||
--- a/kernel/time/tick-sched.c
|
||||
+++ b/kernel/time/tick-sched.c
|
||||
@@ -253,6 +253,16 @@ void tick_nohz_stop_sched_tick(void)
|
||||
|
||||
/* Schedule the tick, if we are at least one jiffie off */
|
||||
if ((long)delta_jiffies >= 1) {
|
||||
+ /*
|
||||
+ * calculate the expiry time for the next timer wheel
|
||||
+ * timer
|
||||
+ */
|
||||
+ expires = ktime_add_ns(last_update, tick_period.tv64 *
|
||||
+ delta_jiffies);
|
||||
+
|
||||
+ /* Skip reprogram of event if its not changed */
|
||||
+ if(ts->tick_stopped && ktime_equal(expires, dev->next_event))
|
||||
+ goto out2;
|
||||
|
||||
if (delta_jiffies > 1)
|
||||
cpu_set(cpu, nohz_cpu_mask);
|
||||
@@ -304,12 +314,7 @@ void tick_nohz_stop_sched_tick(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * calculate the expiry time for the next timer wheel
|
||||
- * timer
|
||||
- */
|
||||
- expires = ktime_add_ns(last_update, tick_period.tv64 *
|
||||
- delta_jiffies);
|
||||
+ /* Mark expiries */
|
||||
ts->idle_expires = expires;
|
||||
|
||||
if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
|
||||
@@ -328,6 +333,7 @@ void tick_nohz_stop_sched_tick(void)
|
||||
tick_do_update_jiffies64(ktime_get());
|
||||
cpu_clear(cpu, nohz_cpu_mask);
|
||||
}
|
||||
+out2:
|
||||
raise_softirq_irqoff(TIMER_SOFTIRQ);
|
||||
out:
|
||||
ts->next_jiffies = next_jiffies;
|
||||
25
meta/recipes-kernel/linux/linux-omap2-git/fixes.patch
Normal file
25
meta/recipes-kernel/linux/linux-omap2-git/fixes.patch
Normal file
@@ -0,0 +1,25 @@
|
||||
Index: git/include/asm-arm/processor.h
|
||||
===================================================================
|
||||
--- git.orig/include/asm-arm/processor.h 2008-08-03 11:27:02.000000000 +0100
|
||||
+++ git/include/asm-arm/processor.h 2008-08-03 11:53:22.000000000 +0100
|
||||
@@ -109,14 +109,16 @@
|
||||
#if __LINUX_ARM_ARCH__ >= 5
|
||||
|
||||
#define ARCH_HAS_PREFETCH
|
||||
-static inline void prefetch(const void *ptr)
|
||||
+#define prefetch(ptr) __builtin_prefetch(ptr)
|
||||
+
|
||||
+/*static inline void prefetch(const void *ptr)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
- "pld\t%0"
|
||||
+ "pld\ta%0"
|
||||
:
|
||||
- : "o" (*(char *)ptr)
|
||||
+ : "p" (ptr)
|
||||
: "cc");
|
||||
-}
|
||||
+}*/
|
||||
|
||||
#define ARCH_HAS_PREFETCHW
|
||||
#define prefetchw(ptr) prefetch(ptr)
|
||||
@@ -0,0 +1,11 @@
|
||||
--- git/drivers/video/omap/lcd_2430sdp.c.orig 2007-08-13 14:35:17.000000000 -0700
|
||||
+++ git/drivers/video/omap/lcd_2430sdp.c 2007-08-13 14:35:55.000000000 -0700
|
||||
@@ -32,7 +32,7 @@
|
||||
#define LCD_PANEL_BACKLIGHT_GPIO 91
|
||||
#define LCD_PANEL_ENABLE_GPIO 154
|
||||
#define LCD_PIXCLOCK_MAX 5400 /* freq 5.4 MHz */
|
||||
-#define PM_RECEIVER TWL4030_MODULE_PM_RECIEVER
|
||||
+#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
|
||||
#define ENABLE_VAUX2_DEDICATED 0x09
|
||||
#define ENABLE_VAUX2_DEV_GRP 0x20
|
||||
|
||||
1303
meta/recipes-kernel/linux/linux-omap2-git/omap-2430sdp/defconfig
Normal file
1303
meta/recipes-kernel/linux/linux-omap2-git/omap-2430sdp/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1119
meta/recipes-kernel/linux/linux-omap2-git/omap2420h4/defconfig
Normal file
1119
meta/recipes-kernel/linux/linux-omap2-git/omap2420h4/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
1303
meta/recipes-kernel/linux/linux-omap2-git/omap2430sdp/defconfig
Normal file
1303
meta/recipes-kernel/linux/linux-omap2-git/omap2430sdp/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
1303
meta/recipes-kernel/linux/linux-omap2-git/omap2430sdp/defconfig.eabi
Normal file
1303
meta/recipes-kernel/linux/linux-omap2-git/omap2430sdp/defconfig.eabi
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
From a1dbb6dd28e9815a307b87b8d96dcf371d6cfd58 Mon Sep 17 00:00:00 2001
|
||||
From: Jarkko Nikula <jarkko.nikula@nokia.com>
|
||||
Date: Mon, 19 May 2008 13:24:41 +0300
|
||||
Subject: [PATCH] ASoC: OMAP: Add basic support for OMAP34xx in McBSP DAI driver
|
||||
|
||||
This adds support for OMAP34xx McBSP port 1 and 2.
|
||||
|
||||
Signed-off-by: Jarkko Nikula <jarkko.nikula@nokia.com>
|
||||
---
|
||||
sound/soc/omap/omap-mcbsp.c | 20 +++++++++++++++++++-
|
||||
1 files changed, 19 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
|
||||
index 40d87e6..8e6ec9d 100644
|
||||
--- a/sound/soc/omap/omap-mcbsp.c
|
||||
+++ b/sound/soc/omap/omap-mcbsp.c
|
||||
@@ -99,6 +99,21 @@ static const unsigned long omap2420_mcbsp_port[][2] = {
|
||||
static const int omap2420_dma_reqs[][2] = {};
|
||||
static const unsigned long omap2420_mcbsp_port[][2] = {};
|
||||
#endif
|
||||
+#if defined(CONFIG_ARCH_OMAP34XX)
|
||||
+static const int omap34xx_dma_reqs[][2] = {
|
||||
+ { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX },
|
||||
+ { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX },
|
||||
+};
|
||||
+static const unsigned long omap34xx_mcbsp_port[][2] = {
|
||||
+ { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR2,
|
||||
+ OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR2 },
|
||||
+ { OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR2,
|
||||
+ OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR2 },
|
||||
+};
|
||||
+#else
|
||||
+static const int omap34xx_dma_reqs[][2] = {};
|
||||
+static const unsigned long omap34xx_mcbsp_port[][2] = {};
|
||||
+#endif
|
||||
|
||||
static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
@@ -169,9 +184,12 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
} else if (cpu_is_omap2420()) {
|
||||
dma = omap2420_dma_reqs[bus_id][substream->stream];
|
||||
port = omap2420_mcbsp_port[bus_id][substream->stream];
|
||||
+ } else if (cpu_is_omap343x()) {
|
||||
+ dma = omap34xx_dma_reqs[bus_id][substream->stream];
|
||||
+ port = omap34xx_mcbsp_port[bus_id][substream->stream];
|
||||
} else {
|
||||
/*
|
||||
- * TODO: Add support for 2430 and 3430
|
||||
+ * TODO: Add support for 2430
|
||||
*/
|
||||
return -ENODEV;
|
||||
}
|
||||
--
|
||||
1.5.5.1
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
From: "Rajendra Nayak" <rnayak@ti.com>
|
||||
To: <linux-omap@vger.kernel.org>
|
||||
Subject: [PATCH 01/02] OMAP3 CPUidle driver
|
||||
Date: Tue, 10 Jun 2008 12:39:00 +0530
|
||||
|
||||
This patch adds the OMAP3 cpuidle driver. Irq enable/disable is done in the core cpuidle driver
|
||||
before it queries the governor for the next state.
|
||||
|
||||
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
|
||||
|
||||
---
|
||||
arch/arm/mach-omap2/Makefile | 2
|
||||
arch/arm/mach-omap2/cpuidle34xx.c | 293 ++++++++++++++++++++++++++++++++++++++
|
||||
arch/arm/mach-omap2/cpuidle34xx.h | 51 ++++++
|
||||
arch/arm/mach-omap2/pm34xx.c | 5
|
||||
drivers/cpuidle/cpuidle.c | 10 +
|
||||
5 files changed, 359 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:33.855303920 +0530
|
||||
+++ linux-omap-2.6/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:39.569121361 +0530
|
||||
@@ -20,7 +20,7 @@ obj-y += pm.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o
|
||||
obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o
|
||||
-obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
|
||||
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o
|
||||
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
|
||||
endif
|
||||
|
||||
Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c 2008-06-10 11:41:27.644820323 +0530
|
||||
@@ -0,0 +1,293 @@
|
||||
+/*
|
||||
+ * linux/arch/arm/mach-omap2/cpuidle34xx.c
|
||||
+ *
|
||||
+ * OMAP3 CPU IDLE Routines
|
||||
+ *
|
||||
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
+ * Rajendra Nayak <rnayak@ti.com>
|
||||
+ *
|
||||
+ * Copyright (C) 2007 Texas Instruments, Inc.
|
||||
+ * Karthik Dasu <karthik-dp@ti.com>
|
||||
+ *
|
||||
+ * Copyright (C) 2006 Nokia Corporation
|
||||
+ * Tony Lindgren <tony@atomide.com>
|
||||
+ *
|
||||
+ * Copyright (C) 2005 Texas Instruments, Inc.
|
||||
+ * Richard Woodruff <r-woodruff2@ti.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/cpuidle.h>
|
||||
+#include <asm/arch/pm.h>
|
||||
+#include <asm/arch/prcm.h>
|
||||
+#include <asm/arch/powerdomain.h>
|
||||
+#include <asm/arch/clockdomain.h>
|
||||
+#include <asm/arch/irqs.h>
|
||||
+#include "cpuidle34xx.h"
|
||||
+
|
||||
+#ifdef CONFIG_CPU_IDLE
|
||||
+
|
||||
+struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
|
||||
+struct omap3_processor_cx current_cx_state;
|
||||
+
|
||||
+static int omap3_idle_bm_check(void)
|
||||
+{
|
||||
+ /* Check for omap3_fclks_active() here once available */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* omap3_enter_idle - Programs OMAP3 to enter the specified state.
|
||||
+ * returns the total time during which the system was idle.
|
||||
+ */
|
||||
+static int omap3_enter_idle(struct cpuidle_device *dev,
|
||||
+ struct cpuidle_state *state)
|
||||
+{
|
||||
+ struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
|
||||
+ struct timespec ts_preidle, ts_postidle, ts_idle;
|
||||
+ struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd;
|
||||
+ int neon_pwrst;
|
||||
+
|
||||
+ current_cx_state = *cx;
|
||||
+
|
||||
+ if (cx->type == OMAP3_STATE_C0) {
|
||||
+ /* Do nothing for C0, not even a wfi */
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Used to keep track of the total time in idle */
|
||||
+ getnstimeofday(&ts_preidle);
|
||||
+
|
||||
+ mpu_pd = pwrdm_lookup("mpu_pwrdm");
|
||||
+ core_pd = pwrdm_lookup("core_pwrdm");
|
||||
+ per_pd = pwrdm_lookup("per_pwrdm");
|
||||
+ neon_pd = pwrdm_lookup("neon_pwrdm");
|
||||
+
|
||||
+ /* Reset previous power state registers */
|
||||
+ pwrdm_clear_all_prev_pwrst(mpu_pd);
|
||||
+ pwrdm_clear_all_prev_pwrst(neon_pd);
|
||||
+ pwrdm_clear_all_prev_pwrst(core_pd);
|
||||
+ pwrdm_clear_all_prev_pwrst(per_pd);
|
||||
+
|
||||
+ if (omap_irq_pending())
|
||||
+ return 0;
|
||||
+
|
||||
+ neon_pwrst = pwrdm_read_pwrst(neon_pd);
|
||||
+
|
||||
+ /* Program MPU/NEON to target state */
|
||||
+ if (cx->mpu_state < PWRDM_POWER_ON) {
|
||||
+ if (neon_pwrst == PWRDM_POWER_ON) {
|
||||
+ if (cx->mpu_state == PWRDM_POWER_RET)
|
||||
+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET);
|
||||
+ else if (cx->mpu_state == PWRDM_POWER_OFF)
|
||||
+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF);
|
||||
+ }
|
||||
+ pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
|
||||
+ }
|
||||
+
|
||||
+ /* Program CORE to target state */
|
||||
+ if (cx->core_state < PWRDM_POWER_ON)
|
||||
+ pwrdm_set_next_pwrst(core_pd, cx->core_state);
|
||||
+
|
||||
+ /* Execute ARM wfi */
|
||||
+ omap_sram_idle();
|
||||
+
|
||||
+ /* Program MPU/NEON to ON */
|
||||
+ if (cx->mpu_state < PWRDM_POWER_ON) {
|
||||
+ if (neon_pwrst == PWRDM_POWER_ON)
|
||||
+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON);
|
||||
+ pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);
|
||||
+ }
|
||||
+
|
||||
+ if (cx->core_state < PWRDM_POWER_ON)
|
||||
+ pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON);
|
||||
+
|
||||
+ getnstimeofday(&ts_postidle);
|
||||
+ ts_idle = timespec_sub(ts_postidle, ts_preidle);
|
||||
+ return timespec_to_ns(&ts_idle);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * omap3_enter_idle_bm - enter function for states with CPUIDLE_FLAG_CHECK_BM
|
||||
+ *
|
||||
+ * This function checks for all the pre-requisites needed for OMAP3 to enter
|
||||
+ * CORE RET/OFF state. It then calls omap3_enter_idle to program the desired
|
||||
+ * C state.
|
||||
+ */
|
||||
+static int omap3_enter_idle_bm(struct cpuidle_device *dev,
|
||||
+ struct cpuidle_state *state)
|
||||
+{
|
||||
+ struct cpuidle_state *new_state = NULL;
|
||||
+ int i, j;
|
||||
+
|
||||
+ if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
|
||||
+
|
||||
+ /* Find current state in list */
|
||||
+ for (i = 0; i < OMAP3_MAX_STATES; i++)
|
||||
+ if (state == &dev->states[i])
|
||||
+ break;
|
||||
+ BUG_ON(i == OMAP3_MAX_STATES);
|
||||
+
|
||||
+ /* Back up to non 'CHECK_BM' state */
|
||||
+ for (j = i - 1; j > 0; j--) {
|
||||
+ struct cpuidle_state *s = &dev->states[j];
|
||||
+
|
||||
+ if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) {
|
||||
+ new_state = s;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pr_debug("%s: Bus activity: Entering %s (instead of %s)\n",
|
||||
+ __FUNCTION__, new_state->name, state->name);
|
||||
+ }
|
||||
+
|
||||
+ return omap3_enter_idle(dev, new_state ? : state);
|
||||
+}
|
||||
+
|
||||
+DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
|
||||
+
|
||||
+/* omap3_init_power_states - Initialises the OMAP3 specific C states.
|
||||
+ * Below is the desciption of each C state.
|
||||
+ *
|
||||
+ C0 . System executing code
|
||||
+ C1 . MPU WFI + Core active
|
||||
+ C2 . MPU CSWR + Core active
|
||||
+ C3 . MPU OFF + Core active
|
||||
+ C4 . MPU CSWR + Core CSWR
|
||||
+ C5 . MPU OFF + Core CSWR
|
||||
+ C6 . MPU OFF + Core OFF
|
||||
+ */
|
||||
+void omap_init_power_states(void)
|
||||
+{
|
||||
+ /* C0 . System executing code */
|
||||
+ omap3_power_states[0].valid = 1;
|
||||
+ omap3_power_states[0].type = OMAP3_STATE_C0;
|
||||
+ omap3_power_states[0].sleep_latency = 0;
|
||||
+ omap3_power_states[0].wakeup_latency = 0;
|
||||
+ omap3_power_states[0].threshold = 0;
|
||||
+ omap3_power_states[0].mpu_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[0].core_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_SHALLOW;
|
||||
+
|
||||
+ /* C1 . MPU WFI + Core active */
|
||||
+ omap3_power_states[1].valid = 1;
|
||||
+ omap3_power_states[1].type = OMAP3_STATE_C1;
|
||||
+ omap3_power_states[1].sleep_latency = 10;
|
||||
+ omap3_power_states[1].wakeup_latency = 10;
|
||||
+ omap3_power_states[1].threshold = 30;
|
||||
+ omap3_power_states[1].mpu_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[1].core_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_SHALLOW;
|
||||
+
|
||||
+ /* C2 . MPU CSWR + Core active */
|
||||
+ omap3_power_states[2].valid = 1;
|
||||
+ omap3_power_states[2].type = OMAP3_STATE_C2;
|
||||
+ omap3_power_states[2].sleep_latency = 50;
|
||||
+ omap3_power_states[2].wakeup_latency = 50;
|
||||
+ omap3_power_states[2].threshold = 300;
|
||||
+ omap3_power_states[2].mpu_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[2].core_state = PWRDM_POWER_ON;
|
||||
+ omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_BALANCED;
|
||||
+
|
||||
+ /* C3 . MPU OFF + Core active */
|
||||
+ omap3_power_states[3].valid = 0;
|
||||
+ omap3_power_states[3].type = OMAP3_STATE_C3;
|
||||
+ omap3_power_states[3].sleep_latency = 1500;
|
||||
+ omap3_power_states[3].wakeup_latency = 1800;
|
||||
+ omap3_power_states[3].threshold = 4000;
|
||||
+ omap3_power_states[3].mpu_state = PWRDM_POWER_OFF;
|
||||
+ omap3_power_states[3].core_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_BALANCED;
|
||||
+
|
||||
+ /* C4 . MPU CSWR + Core CSWR*/
|
||||
+ omap3_power_states[4].valid = 1;
|
||||
+ omap3_power_states[4].type = OMAP3_STATE_C4;
|
||||
+ omap3_power_states[4].sleep_latency = 2500;
|
||||
+ omap3_power_states[4].wakeup_latency = 7500;
|
||||
+ omap3_power_states[4].threshold = 12000;
|
||||
+ omap3_power_states[4].mpu_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[4].core_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
|
||||
+
|
||||
+ /* C5 . MPU OFF + Core CSWR */
|
||||
+ omap3_power_states[5].valid = 0;
|
||||
+ omap3_power_states[5].type = OMAP3_STATE_C5;
|
||||
+ omap3_power_states[5].sleep_latency = 3000;
|
||||
+ omap3_power_states[5].wakeup_latency = 8500;
|
||||
+ omap3_power_states[5].threshold = 15000;
|
||||
+ omap3_power_states[5].mpu_state = PWRDM_POWER_OFF;
|
||||
+ omap3_power_states[5].core_state = PWRDM_POWER_RET;
|
||||
+ omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
|
||||
+
|
||||
+ /* C6 . MPU OFF + Core OFF */
|
||||
+ omap3_power_states[6].valid = 0;
|
||||
+ omap3_power_states[6].type = OMAP3_STATE_C6;
|
||||
+ omap3_power_states[6].sleep_latency = 10000;
|
||||
+ omap3_power_states[6].wakeup_latency = 30000;
|
||||
+ omap3_power_states[6].threshold = 300000;
|
||||
+ omap3_power_states[6].mpu_state = PWRDM_POWER_OFF;
|
||||
+ omap3_power_states[6].core_state = PWRDM_POWER_OFF;
|
||||
+ omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
+ CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM;
|
||||
+}
|
||||
+
|
||||
+struct cpuidle_driver omap3_idle_driver = {
|
||||
+ .name = "omap3_idle",
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+/*
|
||||
+ * omap3_idle_init - Init routine for OMAP3 idle.
|
||||
+ * Registers the OMAP3 specific cpuidle driver with the cpuidle f/w
|
||||
+ * with the valid set of states.
|
||||
+ */
|
||||
+int omap3_idle_init(void)
|
||||
+{
|
||||
+ int i, count = 0;
|
||||
+ struct omap3_processor_cx *cx;
|
||||
+ struct cpuidle_state *state;
|
||||
+ struct cpuidle_device *dev;
|
||||
+
|
||||
+ omap_init_power_states();
|
||||
+ cpuidle_register_driver(&omap3_idle_driver);
|
||||
+
|
||||
+ dev = &per_cpu(omap3_idle_dev, smp_processor_id());
|
||||
+
|
||||
+ for (i = 0; i < OMAP3_MAX_STATES; i++) {
|
||||
+ cx = &omap3_power_states[i];
|
||||
+ state = &dev->states[count];
|
||||
+
|
||||
+ if (!cx->valid)
|
||||
+ continue;
|
||||
+ cpuidle_set_statedata(state, cx);
|
||||
+ state->exit_latency = cx->sleep_latency + cx->wakeup_latency;
|
||||
+ state->target_residency = cx->threshold;
|
||||
+ state->flags = cx->flags;
|
||||
+ state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
|
||||
+ omap3_enter_idle_bm : omap3_enter_idle;
|
||||
+ sprintf(state->name, "C%d", count+1);
|
||||
+ count++;
|
||||
+ }
|
||||
+
|
||||
+ if (!count)
|
||||
+ return -EINVAL;
|
||||
+ dev->state_count = count;
|
||||
+
|
||||
+ if (cpuidle_register_device(dev)) {
|
||||
+ printk(KERN_ERR "%s: CPUidle register device failed\n",
|
||||
+ __FUNCTION__);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+__initcall(omap3_idle_init);
|
||||
+#endif /* CONFIG_CPU_IDLE */
|
||||
Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h 2008-06-09 20:15:39.569121361 +0530
|
||||
@@ -0,0 +1,51 @@
|
||||
+/*
|
||||
+ * linux/arch/arm/mach-omap2/cpuidle34xx.h
|
||||
+ *
|
||||
+ * OMAP3 cpuidle structure definitions
|
||||
+ *
|
||||
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
+ * Written by Rajendra Nayak <rnayak@ti.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
+ *
|
||||
+ * History:
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
|
||||
+#define ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
|
||||
+
|
||||
+#define OMAP3_MAX_STATES 7
|
||||
+#define OMAP3_STATE_C0 0 /* C0 - System executing code */
|
||||
+#define OMAP3_STATE_C1 1 /* C1 - MPU WFI + Core active */
|
||||
+#define OMAP3_STATE_C2 2 /* C2 - MPU CSWR + Core active */
|
||||
+#define OMAP3_STATE_C3 3 /* C3 - MPU OFF + Core active */
|
||||
+#define OMAP3_STATE_C4 4 /* C4 - MPU RET + Core RET */
|
||||
+#define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */
|
||||
+#define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */
|
||||
+
|
||||
+extern void omap_sram_idle(void);
|
||||
+extern int omap3_irq_pending(void);
|
||||
+
|
||||
+struct omap3_processor_cx {
|
||||
+ u8 valid;
|
||||
+ u8 type;
|
||||
+ u32 sleep_latency;
|
||||
+ u32 wakeup_latency;
|
||||
+ u32 mpu_state;
|
||||
+ u32 core_state;
|
||||
+ u32 threshold;
|
||||
+ u32 flags;
|
||||
+};
|
||||
+
|
||||
+void omap_init_power_states(void);
|
||||
+int omap3_idle_init(void);
|
||||
+
|
||||
+#endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */
|
||||
+
|
||||
Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:15:33.855303920 +0530
|
||||
+++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:16:20.976798343 +0530
|
||||
@@ -141,7 +141,7 @@ static irqreturn_t prcm_interrupt_handle
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
-static void omap_sram_idle(void)
|
||||
+void omap_sram_idle(void)
|
||||
{
|
||||
/* Variable to tell what needs to be saved and restored
|
||||
* in omap_sram_idle*/
|
||||
@@ -156,6 +156,7 @@ static void omap_sram_idle(void)
|
||||
|
||||
mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
|
||||
switch (mpu_next_state) {
|
||||
+ case PWRDM_POWER_ON:
|
||||
case PWRDM_POWER_RET:
|
||||
/* No need to save context */
|
||||
save_state = 0;
|
||||
@@ -386,7 +387,9 @@ int __init omap3_pm_init(void)
|
||||
|
||||
prcm_setup_regs();
|
||||
|
||||
+#ifndef CONFIG_CPU_IDLE
|
||||
pm_idle = omap3_pm_idle;
|
||||
+#endif
|
||||
|
||||
err1:
|
||||
return ret;
|
||||
Index: linux-omap-2.6/drivers/cpuidle/cpuidle.c
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:33.856303888 +0530
|
||||
+++ linux-omap-2.6/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:39.570121329 +0530
|
||||
@@ -58,6 +58,11 @@ static void cpuidle_idle_call(void)
|
||||
return;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_ARCH_OMAP3
|
||||
+ local_irq_disable();
|
||||
+ local_fiq_disable();
|
||||
+#endif
|
||||
+
|
||||
/* ask the governor for the next state */
|
||||
next_state = cpuidle_curr_governor->select(dev);
|
||||
if (need_resched())
|
||||
@@ -70,6 +75,11 @@ static void cpuidle_idle_call(void)
|
||||
target_state->time += (unsigned long long)dev->last_residency;
|
||||
target_state->usage++;
|
||||
|
||||
+#ifdef CONFIG_ARCH_OMAP3
|
||||
+ local_irq_enable();
|
||||
+ local_fiq_enable();
|
||||
+#endif
|
||||
+
|
||||
/* give the governor an opportunity to reflect on the outcome */
|
||||
if (cpuidle_curr_governor->reflect)
|
||||
cpuidle_curr_governor->reflect(dev);
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
From 7a444ee080c5f1a62ac5042f1e7926622b3e1ce7 Mon Sep 17 00:00:00 2001
|
||||
From: Koen Kooi <koen@openembedded.org>
|
||||
Date: Fri, 30 May 2008 13:43:36 +0200
|
||||
Subject: [PATCH] ARM: OMAP: omap3beagle: add a platform device to hook up the GPIO leds to the leds-gpio driver
|
||||
|
||||
omap3beagle: add a platform device to hook up the GPIO leds to the leds-gpio driver
|
||||
* on revision A5 and earlier board the two leds can't be controlled seperately, should be fixed in rev. B and C boards.
|
||||
|
||||
Signed-off-by: Koen Kooi <koen@openembedded.org>
|
||||
---
|
||||
arch/arm/mach-omap2/board-omap3beagle.c | 28 ++++++++++++++++++++++++++++
|
||||
1 files changed, 28 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
index c992cc7..83891fc 100644
|
||||
--- a/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
+#include <linux/leds.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@@ -72,6 +73,32 @@ static struct omap_lcd_config omap3_beagle_lcd_config __initdata = {
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
+struct gpio_led gpio_leds[] = {
|
||||
+ {
|
||||
+ .name = "beagleboard::led0",
|
||||
+ .default_trigger = "none",
|
||||
+ .gpio = 149,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "beagleboard::led1",
|
||||
+ .default_trigger = "none",
|
||||
+ .gpio = 150,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led_platform_data gpio_led_info = {
|
||||
+ .leds = gpio_leds,
|
||||
+ .num_leds = ARRAY_SIZE(gpio_leds),
|
||||
+};
|
||||
+
|
||||
+static struct platform_device leds_gpio = {
|
||||
+ .name = "leds-gpio",
|
||||
+ .id = -1,
|
||||
+ .dev = {
|
||||
+ .platform_data = &gpio_led_info,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct omap_board_config_kernel omap3_beagle_config[] __initdata = {
|
||||
{ OMAP_TAG_UART, &omap3_beagle_uart_config },
|
||||
{ OMAP_TAG_MMC, &omap3beagle_mmc_config },
|
||||
@@ -83,6 +110,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = {
|
||||
#ifdef CONFIG_RTC_DRV_TWL4030
|
||||
&omap3_beagle_twl4030rtc_device,
|
||||
#endif
|
||||
+ &leds_gpio,
|
||||
};
|
||||
|
||||
static void __init omap3_beagle_init(void)
|
||||
--
|
||||
1.5.4.3
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
|
||||
To: linux-omap@vger.kernel.org
|
||||
Cc: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
|
||||
Subject: [PATCH 2/3] ARM: OMAP: SmartReflex driver: added required register and bit definitions.
|
||||
Date: Fri, 6 Jun 2008 12:49:48 +0300
|
||||
|
||||
Added new register and bit definitions to enable Smartreflex driver integration.
|
||||
Also PRM_VC_SMPS_SA bit definitions' naming was changed to match the naming of
|
||||
other similar bit definitions.
|
||||
|
||||
Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
|
||||
---
|
||||
arch/arm/mach-omap2/prm-regbits-34xx.h | 27 ++++++--
|
||||
arch/arm/mach-omap2/smartreflex.h | 124 ++++++++++++++++++++++++++++++-
|
||||
include/asm-arm/arch-omap/control.h | 19 +++++
|
||||
include/asm-arm/arch-omap/omap34xx.h | 2 +
|
||||
4 files changed, 163 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
|
||||
index c6a7940..f82b5a7 100644
|
||||
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
|
||||
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
|
||||
@@ -435,10 +435,10 @@
|
||||
/* PM_PWSTST_EMU specific bits */
|
||||
|
||||
/* PRM_VC_SMPS_SA */
|
||||
-#define OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT 16
|
||||
-#define OMAP3430_PRM_VC_SMPS_SA_SA1_MASK (0x7f << 16)
|
||||
-#define OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT 0
|
||||
-#define OMAP3430_PRM_VC_SMPS_SA_SA0_MASK (0x7f << 0)
|
||||
+#define OMAP3430_SMPS_SA1_SHIFT 16
|
||||
+#define OMAP3430_SMPS_SA1_MASK (0x7f << 16)
|
||||
+#define OMAP3430_SMPS_SA0_SHIFT 0
|
||||
+#define OMAP3430_SMPS_SA0_MASK (0x7f << 0)
|
||||
|
||||
/* PRM_VC_SMPS_VOL_RA */
|
||||
#define OMAP3430_VOLRA1_SHIFT 16
|
||||
@@ -452,7 +452,7 @@
|
||||
#define OMAP3430_CMDRA0_SHIFT 0
|
||||
#define OMAP3430_CMDRA0_MASK (0xff << 0)
|
||||
|
||||
-/* PRM_VC_CMD_VAL_0 specific bits */
|
||||
+/* PRM_VC_CMD_VAL */
|
||||
#define OMAP3430_VC_CMD_ON_SHIFT 24
|
||||
#define OMAP3430_VC_CMD_ON_MASK (0xFF << 24)
|
||||
#define OMAP3430_VC_CMD_ONLP_SHIFT 16
|
||||
@@ -462,7 +462,17 @@
|
||||
#define OMAP3430_VC_CMD_OFF_SHIFT 0
|
||||
#define OMAP3430_VC_CMD_OFF_MASK (0xFF << 0)
|
||||
|
||||
+/* PRM_VC_CMD_VAL_0 specific bits */
|
||||
+#define OMAP3430_VC_CMD_VAL0_ON (0x3 << 4)
|
||||
+#define OMAP3430_VC_CMD_VAL0_ONLP (0x3 << 3)
|
||||
+#define OMAP3430_VC_CMD_VAL0_RET (0x3 << 3)
|
||||
+#define OMAP3430_VC_CMD_VAL0_OFF (0x3 << 3)
|
||||
+
|
||||
/* PRM_VC_CMD_VAL_1 specific bits */
|
||||
+#define OMAP3430_VC_CMD_VAL1_ON (0xB << 2)
|
||||
+#define OMAP3430_VC_CMD_VAL1_ONLP (0x3 << 3)
|
||||
+#define OMAP3430_VC_CMD_VAL1_RET (0x3 << 3)
|
||||
+#define OMAP3430_VC_CMD_VAL1_OFF (0x3 << 3)
|
||||
|
||||
/* PRM_VC_CH_CONF */
|
||||
#define OMAP3430_CMD1 (1 << 20)
|
||||
@@ -521,6 +531,13 @@
|
||||
#define OMAP3430_AUTO_RET (1 << 1)
|
||||
#define OMAP3430_AUTO_SLEEP (1 << 0)
|
||||
|
||||
+/* Constants to define setup durations */
|
||||
+#define OMAP3430_CLKSETUP_DURATION 0xff
|
||||
+#define OMAP3430_VOLTSETUP_TIME2 0xfff
|
||||
+#define OMAP3430_VOLTSETUP_TIME1 0xfff
|
||||
+#define OMAP3430_VOLTOFFSET_DURATION 0xff
|
||||
+#define OMAP3430_VOLTSETUP2_DURATION 0xff
|
||||
+
|
||||
/* PRM_SRAM_PCHARGE */
|
||||
#define OMAP3430_PCHARGE_TIME_SHIFT 0
|
||||
#define OMAP3430_PCHARGE_TIME_MASK (0xff << 0)
|
||||
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
|
||||
index 62907ef..2091a15 100644
|
||||
--- a/arch/arm/mach-omap2/smartreflex.h
|
||||
+++ b/arch/arm/mach-omap2/smartreflex.h
|
||||
@@ -1,5 +1,10 @@
|
||||
+#ifndef __ARCH_ARM_MACH_OMAP3_SMARTREFLEX_H
|
||||
+#define __ARCH_ARM_MACH_OMAP3_SMARTREFLEX_H
|
||||
/*
|
||||
- * linux/arch/arm/mach-omap3/smartreflex.h
|
||||
+ * linux/arch/arm/mach-omap2/smartreflex.h
|
||||
+ *
|
||||
+ * Copyright (C) 2008 Nokia Corporation
|
||||
+ * Kalle Jokiniemi
|
||||
*
|
||||
* Copyright (C) 2007 Texas Instruments, Inc.
|
||||
* Lesly A M <x0080970@ti.com>
|
||||
@@ -9,6 +14,21 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
+#define PHY_TO_OFF_PM_MASTER(p) (p - 0x36)
|
||||
+#define PHY_TO_OFF_PM_RECIEVER(p) (p - 0x5b)
|
||||
+#define PHY_TO_OFF_PM_INT(p) (p - 0x2e)
|
||||
+
|
||||
+/* SMART REFLEX REG ADDRESS OFFSET */
|
||||
+#define SRCONFIG 0x00
|
||||
+#define SRSTATUS 0x04
|
||||
+#define SENVAL 0x08
|
||||
+#define SENMIN 0x0C
|
||||
+#define SENMAX 0x10
|
||||
+#define SENAVG 0x14
|
||||
+#define AVGWEIGHT 0x18
|
||||
+#define NVALUERECIPROCAL 0x1C
|
||||
+#define SENERROR 0x20
|
||||
+#define ERRCONFIG 0x24
|
||||
|
||||
/* SR Modules */
|
||||
#define SR1 1
|
||||
@@ -127,10 +147,106 @@
|
||||
#define SR2_ERRMAXLIMIT (0x02 << 8)
|
||||
#define SR2_ERRMINLIMIT (0xF9 << 0)
|
||||
|
||||
+/* T2 SMART REFLEX */
|
||||
+#define R_SRI2C_SLAVE_ADDR 0x12
|
||||
+#define R_VDD1_SR_CONTROL 0x00
|
||||
+#define R_VDD2_SR_CONTROL 0x01
|
||||
+#define T2_SMPS_UPDATE_DELAY 360 /* In uSec */
|
||||
+
|
||||
+/* Vmode control */
|
||||
+#define R_DCDC_GLOBAL_CFG PHY_TO_OFF_PM_RECIEVER(0x61)
|
||||
+
|
||||
+#define R_VDD1_VSEL PHY_TO_OFF_PM_RECIEVER(0xb9)
|
||||
+#define R_VDD1_VMODE_CFG PHY_TO_OFF_PM_RECIEVER(0xba)
|
||||
+#define R_VDD1_VFLOOR PHY_TO_OFF_PM_RECIEVER(0xbb)
|
||||
+#define R_VDD1_VROOF PHY_TO_OFF_PM_RECIEVER(0xbc)
|
||||
+#define R_VDD1_STEP PHY_TO_OFF_PM_RECIEVER(0xbd)
|
||||
+
|
||||
+#define R_VDD2_VSEL PHY_TO_OFF_PM_RECIEVER(0xc7)
|
||||
+#define R_VDD2_VMODE_CFG PHY_TO_OFF_PM_RECIEVER(0xc8)
|
||||
+#define R_VDD2_VFLOOR PHY_TO_OFF_PM_RECIEVER(0xc9)
|
||||
+#define R_VDD2_VROOF PHY_TO_OFF_PM_RECIEVER(0xca)
|
||||
+#define R_VDD2_STEP PHY_TO_OFF_PM_RECIEVER(0xcb)
|
||||
+
|
||||
+/* R_DCDC_GLOBAL_CFG register, SMARTREFLEX_ENABLE valuws */
|
||||
+#define DCDC_GLOBAL_CFG_ENABLE_SRFLX 0x08
|
||||
+
|
||||
+/* VDDs*/
|
||||
+#define PRCM_VDD1 1
|
||||
+#define PRCM_VDD2 2
|
||||
+#define PRCM_MAX_SYSC_REGS 30
|
||||
+
|
||||
+/* XXX: These should be removed/moved from here once we have a working DVFS
|
||||
+ implementation in place */
|
||||
+#define AT_3430 1 /*3430 ES 1.0 */
|
||||
+#define AT_3430_ES2 2 /*3430 ES 2.0 */
|
||||
+
|
||||
+#define ID_OPP 0xE2 /*OPP*/
|
||||
+
|
||||
+/* DEVICE ID/DPLL ID/CLOCK ID: bits 28-31 for OMAP type */
|
||||
+#define OMAP_TYPE_SHIFT 28
|
||||
+#define OMAP_TYPE_MASK 0xF
|
||||
+/* OPP ID: bits: 0-4 for OPP number */
|
||||
+#define OPP_NO_POS 0
|
||||
+#define OPP_NO_MASK 0x1F
|
||||
+/* OPP ID: bits: 5-6 for VDD */
|
||||
+#define VDD_NO_POS 5
|
||||
+#define VDD_NO_MASK 0x3
|
||||
+/* Other IDs: bits 20-27 for ID type */
|
||||
+/* These IDs have bits 25,26,27 as 1 */
|
||||
+#define OTHER_ID_TYPE_SHIFT 20
|
||||
+#define OTHER_ID_TYPE_MASK 0xFF
|
||||
+
|
||||
+#define OTHER_ID_TYPE(X) ((X & OTHER_ID_TYPE_MASK) << OTHER_ID_TYPE_SHIFT)
|
||||
+#define ID_OPP_NO(X) ((X & OPP_NO_MASK) << OPP_NO_POS)
|
||||
+#define ID_VDD(X) ((X & VDD_NO_MASK) << VDD_NO_POS)
|
||||
+#define OMAP(X) ((X >> OMAP_TYPE_SHIFT) & OMAP_TYPE_MASK)
|
||||
+#define get_opp_no(X) ((X >> OPP_NO_POS) & OPP_NO_MASK)
|
||||
+#define get_vdd(X) ((X >> VDD_NO_POS) & VDD_NO_MASK)
|
||||
+
|
||||
+/* VDD1 OPPs */
|
||||
+#define PRCM_VDD1_OPP1 (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
|
||||
+ ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x1))
|
||||
+#define PRCM_VDD1_OPP2 (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
|
||||
+ ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x2))
|
||||
+#define PRCM_VDD1_OPP3 (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
|
||||
+ ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x3))
|
||||
+#define PRCM_VDD1_OPP4 (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
|
||||
+ ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x4))
|
||||
+#define PRCM_VDD1_OPP5 (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
|
||||
+ ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x5))
|
||||
+#define PRCM_NO_VDD1_OPPS 5
|
||||
+
|
||||
+
|
||||
+/* VDD2 OPPs */
|
||||
+#define PRCM_VDD2_OPP1 (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
|
||||
+ ID_VDD(PRCM_VDD2) | ID_OPP_NO(0x1))
|
||||
+#define PRCM_VDD2_OPP2 (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
|
||||
+ ID_VDD(PRCM_VDD2) | ID_OPP_NO(0x2))
|
||||
+#define PRCM_VDD2_OPP3 (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
|
||||
+ ID_VDD(PRCM_VDD2) | ID_OPP_NO(0x3))
|
||||
+#define PRCM_NO_VDD2_OPPS 3
|
||||
+/* XXX: end remove/move */
|
||||
+
|
||||
+
|
||||
+/* XXX: find more appropriate place for these once DVFS is in place */
|
||||
extern u32 current_vdd1_opp;
|
||||
extern u32 current_vdd2_opp;
|
||||
-extern struct kset power_subsys;
|
||||
|
||||
-extern inline int loop_wait(u32 *lcnt, u32 *rcnt, u32 delay);
|
||||
-extern void omap_udelay(u32 udelay);
|
||||
+/*
|
||||
+ * Smartreflex module enable/disable interface.
|
||||
+ * NOTE: if smartreflex is not enabled from sysfs, these functions will not
|
||||
+ * do anything.
|
||||
+ */
|
||||
+#if defined(CONFIG_ARCH_OMAP34XX) && defined(CONFIG_TWL4030_CORE)
|
||||
+void enable_smartreflex(int srid);
|
||||
+void disable_smartreflex(int srid);
|
||||
+#else
|
||||
+static inline void enable_smartreflex(int srid) {}
|
||||
+static inline void disable_smartreflex(int srid) {}
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
|
||||
diff --git a/include/asm-arm/arch-omap/control.h b/include/asm-arm/arch-omap/control.h
|
||||
index 12bc22a..6e64fe7 100644
|
||||
--- a/include/asm-arm/arch-omap/control.h
|
||||
+++ b/include/asm-arm/arch-omap/control.h
|
||||
@@ -138,6 +138,15 @@
|
||||
#define OMAP343X_CONTROL_TEST_KEY_11 (OMAP2_CONTROL_GENERAL + 0x00f4)
|
||||
#define OMAP343X_CONTROL_TEST_KEY_12 (OMAP2_CONTROL_GENERAL + 0x00f8)
|
||||
#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc)
|
||||
+#define OMAP343X_CONTROL_FUSE_OPP1_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110)
|
||||
+#define OMAP343X_CONTROL_FUSE_OPP2_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114)
|
||||
+#define OMAP343X_CONTROL_FUSE_OPP3_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118)
|
||||
+#define OMAP343X_CONTROL_FUSE_OPP4_VDD1 (OMAP2_CONTROL_GENERAL + 0x011c)
|
||||
+#define OMAP343X_CONTROL_FUSE_OPP5_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120)
|
||||
+#define OMAP343X_CONTROL_FUSE_OPP1_VDD2 (OMAP2_CONTROL_GENERAL + 0x0124)
|
||||
+#define OMAP343X_CONTROL_FUSE_OPP2_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)
|
||||
+#define OMAP343X_CONTROL_FUSE_OPP3_VDD2 (OMAP2_CONTROL_GENERAL + 0x012c)
|
||||
+#define OMAP343X_CONTROL_FUSE_SR (OMAP2_CONTROL_GENERAL + 0x0130)
|
||||
#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
|
||||
#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
|
||||
#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4)
|
||||
@@ -172,6 +181,16 @@
|
||||
#define OMAP2_SYSBOOT_1_MASK (1 << 1)
|
||||
#define OMAP2_SYSBOOT_0_MASK (1 << 0)
|
||||
|
||||
+/* CONTROL_FUSE_SR bits */
|
||||
+#define OMAP343X_SR2_SENNENABLE_MASK (0x3 << 10)
|
||||
+#define OMAP343X_SR2_SENNENABLE_SHIFT 10
|
||||
+#define OMAP343X_SR2_SENPENABLE_MASK (0x3 << 8)
|
||||
+#define OMAP343X_SR2_SENPENABLE_SHIFT 8
|
||||
+#define OMAP343X_SR1_SENNENABLE_MASK (0x3 << 2)
|
||||
+#define OMAP343X_SR1_SENNENABLE_SHIFT 2
|
||||
+#define OMAP343X_SR1_SENPENABLE_MASK (0x3 << 0)
|
||||
+#define OMAP343X_SR1_SENPENABLE_SHIFT 0
|
||||
+
|
||||
#ifndef __ASSEMBLY__
|
||||
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
|
||||
extern void __iomem *omap_ctrl_base_get(void);
|
||||
diff --git a/include/asm-arm/arch-omap/omap34xx.h b/include/asm-arm/arch-omap/omap34xx.h
|
||||
index 6a0459a..3667fd6 100644
|
||||
--- a/include/asm-arm/arch-omap/omap34xx.h
|
||||
+++ b/include/asm-arm/arch-omap/omap34xx.h
|
||||
@@ -54,6 +54,8 @@
|
||||
#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000)
|
||||
#define OMAP34XX_HSUSB_HOST_BASE (L4_34XX_BASE + 0x64000)
|
||||
#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000)
|
||||
+#define OMAP34XX_SR1_BASE 0x480C9000
|
||||
+#define OMAP34XX_SR2_BASE 0x480CB000
|
||||
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP3430)
|
||||
--
|
||||
1.5.4.3
|
||||
@@ -0,0 +1,88 @@
|
||||
From: "Rajendra Nayak" <rnayak@ti.com>
|
||||
To: <linux-omap@vger.kernel.org>
|
||||
Subject: [PATCH 02/02] Kconfig changes
|
||||
Date: Tue, 10 Jun 2008 12:39:02 +0530
|
||||
|
||||
Updates the CPUidle Kconfig
|
||||
|
||||
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
|
||||
|
||||
---
|
||||
arch/arm/Kconfig | 10 ++++++++++
|
||||
drivers/cpuidle/Kconfig | 28 ++++++++++++++++++++++------
|
||||
2 files changed, 32 insertions(+), 6 deletions(-)
|
||||
|
||||
Index: linux-omap-2.6/arch/arm/Kconfig
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/arch/arm/Kconfig 2008-06-10 11:43:10.790502713 +0530
|
||||
+++ linux-omap-2.6/arch/arm/Kconfig 2008-06-10 11:43:38.701604549 +0530
|
||||
@@ -954,6 +954,16 @@ config ATAGS_PROC
|
||||
|
||||
endmenu
|
||||
|
||||
+if (ARCH_OMAP)
|
||||
+
|
||||
+menu "CPUIdle"
|
||||
+
|
||||
+source "drivers/cpuidle/Kconfig"
|
||||
+
|
||||
+endmenu
|
||||
+
|
||||
+endif
|
||||
+
|
||||
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
Index: linux-omap-2.6/drivers/cpuidle/Kconfig
|
||||
===================================================================
|
||||
--- linux-omap-2.6.orig/drivers/cpuidle/Kconfig 2008-06-10 11:43:10.790502713 +0530
|
||||
+++ linux-omap-2.6/drivers/cpuidle/Kconfig 2008-06-10 12:06:36.139332151 +0530
|
||||
@@ -1,20 +1,36 @@
|
||||
+menu "CPU idle PM support"
|
||||
|
||||
config CPU_IDLE
|
||||
bool "CPU idle PM support"
|
||||
- default ACPI
|
||||
+ default n
|
||||
help
|
||||
CPU idle is a generic framework for supporting software-controlled
|
||||
idle processor power management. It includes modular cross-platform
|
||||
governors that can be swapped during runtime.
|
||||
|
||||
- If you're using an ACPI-enabled platform, you should say Y here.
|
||||
+ If you're using a mobile platform that supports CPU idle PM (e.g.
|
||||
+ an ACPI-capable notebook), you should say Y here.
|
||||
+
|
||||
+if CPU_IDLE
|
||||
+
|
||||
+comment "Governors"
|
||||
|
||||
config CPU_IDLE_GOV_LADDER
|
||||
- bool
|
||||
+ bool "ladder"
|
||||
depends on CPU_IDLE
|
||||
- default y
|
||||
+ default n
|
||||
|
||||
config CPU_IDLE_GOV_MENU
|
||||
- bool
|
||||
+ bool "menu"
|
||||
depends on CPU_IDLE && NO_HZ
|
||||
- default y
|
||||
+ default n
|
||||
+ help
|
||||
+ This cpuidle governor evaluates all available states and chooses the
|
||||
+ deepest state that meets all of the following constraints: BM activity,
|
||||
+ expected time until next timer interrupt, and last break event time
|
||||
+ delta. It is designed to minimize power consumption. Currently
|
||||
+ dynticks is required.
|
||||
+
|
||||
+endif # CPU_IDLE
|
||||
+
|
||||
+endmenu
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1567
meta/recipes-kernel/linux/linux-omap2-git/omap3evm/defconfig
Normal file
1567
meta/recipes-kernel/linux/linux-omap2-git/omap3evm/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,15 @@
|
||||
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
|
||||
index 1d437de..33b3feb 100644
|
||||
--- a/fs/jffs2/scan.c
|
||||
+++ b/fs/jffs2/scan.c
|
||||
@@ -647,8 +647,8 @@ scan_more:
|
||||
inbuf_ofs = ofs - buf_ofs;
|
||||
while (inbuf_ofs < scan_end) {
|
||||
if (unlikely(*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff)) {
|
||||
- printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
|
||||
- empty_start, ofs);
|
||||
+// printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
|
||||
+// empty_start, ofs);
|
||||
if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start)))
|
||||
return err;
|
||||
goto scan_more;
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /tmp/Makefile 2008-04-24 14:36:20.509598016 +0200
|
||||
+++ git/arch/arm/Makefile 2008-04-24 14:36:31.949546584 +0200
|
||||
@@ -47,7 +47,7 @@
|
||||
# Note that GCC does not numerically define an architecture version
|
||||
# macro, but instead defines a whole series of macros which makes
|
||||
# testing for a specific architecture or later rather impossible.
|
||||
-arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7a,-march=armv5t -Wa$(comma)-march=armv7a)
|
||||
+arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
|
||||
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
|
||||
# Only override the compiler option if ARMv6. The ARMv6K extensions are
|
||||
# always available in ARMv7
|
||||
Reference in New Issue
Block a user