1
0
mirror of https://git.yoctoproject.org/meta-ti synced 2026-06-04 18:00:36 +00:00

linux: remove old platform-specific 2.6.37 kernels

Most of the legacy devices should be working fine with latest kernels,
either ti-staging or mainline.

Signed-off-by: Denys Dmytriyenko <denys@ti.com>
This commit is contained in:
Denys Dmytriyenko
2014-06-20 17:18:40 -04:00
parent a09450e12d
commit bf0741681d
233 changed files with 0 additions and 156701 deletions
@@ -1,44 +0,0 @@
From 10fbd32a96aedd644b6bf38888a2af64cc13a35f Mon Sep 17 00:00:00 2001
From: Matt Porter <mporter@ti.com>
Date: Mon, 5 Dec 2011 15:29:35 -0600
Subject: [PATCH] musb: update PIO mode help information in Kconfig
* Updated the Kconfig help information for the PIO mode for MUSB
to make it more clear to the customer when to select this option
and which devices currently have issues with this option.
* This is in accordance with the findings for CPPI4.1 DMA usage
for MUSB
Upstream-Status: Submitted
* Submitted to the PSP team using the lpr list
Signed-off-by: Matt Porter <mporter@ti.com>
Signed-off-by: Chase Maupin <Chase.Maupin@ti.com>
---
drivers/usb/musb/Kconfig | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index ee75cbc..d56f23d 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -107,10 +107,13 @@ config MUSB_PIO_ONLY
All data is copied between memory and FIFO by the CPU.
DMA controllers are ignored.
- Do not select 'n' here unless DMA support for your SOC or board
- is unavailable (or unstable). When DMA is enabled at compile time,
- you can still disable it at run time using the "use_dma=n" module
- parameter.
+ Select 'y' here if DMA support for your SOC or board
+ is unavailable (or unstable). On CPPI 4.1 DMA based
+ systems (AM335x, AM35x, and AM180x) DMA support is
+ considered unstable and this option should be enabled
+ in production. When DMA is enabled at compile time,
+ you can still disable it at run time using the "use_dma=n"
+ module parameter.
config USB_UX500_DMA_HW
select USB_UX500_DMA
--
1.7.0.4
File diff suppressed because it is too large Load Diff
@@ -1,111 +0,0 @@
From a520a30ffd932bce334d894adce12a6ceec2be00 Mon Sep 17 00:00:00 2001
From: Greg Guyotte <gguyotte@ti.com>
Date: Tue, 21 Jun 2011 21:56:06 -0500
Subject: [PATCH] Fix matrix suspend
* Added new OMAP config option OMAP3_PM_DISABLE_VT_SWITCH which
disables the VT console switch which normally occurs during
suspend. This console switch, when performed with Matrix
running, hangs. The VT switch is considered unnecessary.
* Modified OMAP3 EVM and OMAP3 Beagle defconfig files to default
the OMAP3_PM_DISABLE_VT_SWITCH=y, and also to default
MMC_UNSAFE_RESUME=y. The latter case causes a hang during suspend
if the root filesystem is located on the MMC card. This
fix has actually been done in another patch, but the defconfigs
were not updated.
Signed-off-by: Greg Guyotte <gguyotte@ti.com>
Fix mistake in Kconfig
Did not mean to add the two lines in Kconfig under ARCH_OMAP3.
Signed-off-by: Greg Guyotte <gguyotte@ti.com>
---
arch/arm/configs/omap3_beagle_defconfig | 3 ++-
arch/arm/configs/omap3_evm_defconfig | 3 ++-
arch/arm/mach-omap2/Kconfig | 10 ++++++++++
arch/arm/mach-omap2/pm34xx.c | 4 ++++
4 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig
index cef7597..6e8d50c 100644
--- a/arch/arm/configs/omap3_beagle_defconfig
+++ b/arch/arm/configs/omap3_beagle_defconfig
@@ -97,6 +97,7 @@ CONFIG_MACH_OMAP3_BEAGLE=y
# CONFIG_MACH_OMAP_3630SDP is not set
# CONFIG_OMAP3_EMU is not set
# CONFIG_OMAP3_SDRC_AC_TIMING is not set
+CONFIG_OMAP3_PM_DISABLE_VT_SWITCH=y
#
# Processor Features
@@ -504,7 +505,7 @@ CONFIG_USB_ETH=y
CONFIG_USB_ETH_RNDIS=y
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_UNSAFE_RESUME is not set
+CONFIG_MMC_UNSAFE_RESUME=y
#
# MMC/SD/SDIO Card Drivers
diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig
index 675ae9c..8db3574 100644
--- a/arch/arm/configs/omap3_evm_defconfig
+++ b/arch/arm/configs/omap3_evm_defconfig
@@ -97,6 +97,7 @@ CONFIG_MACH_OMAP3EVM=y
# CONFIG_MACH_OMAP_3630SDP is not set
# CONFIG_OMAP3_EMU is not set
# CONFIG_OMAP3_SDRC_AC_TIMING is not set
+CONFIG_OMAP3_PM_DISABLE_VT_SWITCH=y
#
# Processor Features
@@ -557,7 +558,7 @@ CONFIG_USB_ETH=y
CONFIG_USB_ETH_RNDIS=y
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_UNSAFE_RESUME is not set
+CONFIG_MMC_UNSAFE_RESUME=y
#
# MMC/SD/SDIO Card Drivers
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index dfa5464..43dc070 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -338,6 +338,16 @@ config OMAP3_EMU
help
Say Y here to enable debugging hardware of omap3
+config OMAP3_PM_DISABLE_VT_SWITCH
+ bool "OMAP3 Disable PM Console Switch"
+ depends on ARCH_OMAP3
+ default y
+ help
+ This option disables the default PM VT switch behavior for OMAP3.
+ Some platforms hang during suspend due to a failed attempt to
+ perform the VT switch. The VT switch is unnecessary on many
+ platforms.
+
config OMAP3_SDRC_AC_TIMING
bool "Enable SDRC AC timing register changes"
depends on ARCH_OMAP3
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 242babc..1d23b55 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -1072,6 +1072,10 @@ static int __init omap3_pm_init(void)
printk(KERN_ERR "Power Management for TI OMAP3.\n");
+#ifdef CONFIG_OMAP3_PM_DISABLE_VT_SWITCH
+ pm_set_vt_switch(0);
+#endif
+
/* XXX prcm_setup_regs needs to be before enabling hw
* supervised mode for powerdomains */
prcm_setup_regs();
--
1.7.0.4
@@ -1,130 +0,0 @@
From f4019d96a708b09a804f59667d5dfd2a9eaaced5 Mon Sep 17 00:00:00 2001
From: Chase Maupin <Chase.Maupin@ti.com>
Date: Mon, 27 Jun 2011 13:33:43 -0500
Subject: [PATCH 1/3] OCF support: remove support for non-TI hardware
* Base OCF patch was updated to not patch in support for non-TI
hardware.
* Makefile and Kconfig needed updating to remove these options
Upstream-Status: Inappropriate [TI SDK specific]
Signed-off-by: Chase Maupin <Chase.Maupin@ti.com>
---
crypto/ocf/Kconfig | 77 ---------------------------------------------------
crypto/ocf/Makefile | 11 -------
2 files changed, 0 insertions(+), 88 deletions(-)
diff --git a/crypto/ocf/Kconfig b/crypto/ocf/Kconfig
index b9c24ff..805cb4c 100644
--- a/crypto/ocf/Kconfig
+++ b/crypto/ocf/Kconfig
@@ -31,83 +31,6 @@ config OCF_CRYPTOSOFT
A software driver for the OCF framework that uses
the kernel CryptoAPI.
-config OCF_SAFE
- tristate "safenet (HW crypto engine)"
- depends on OCF_OCF
- help
- A driver for a number of the safenet Excel crypto accelerators.
- Currently tested and working on the 1141 and 1741.
-
-config OCF_IXP4XX
- tristate "IXP4xx (HW crypto engine)"
- depends on OCF_OCF
- help
- XScale IXP4xx crypto accelerator driver. Requires the
- Intel Access library.
-
-config OCF_IXP4XX_SHA1_MD5
- bool "IXP4xx SHA1 and MD5 Hashing"
- depends on OCF_IXP4XX
- help
- Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
- Note: this is MUCH slower than using cryptosoft (software crypto engine).
-
-config OCF_HIFN
- tristate "hifn (HW crypto engine)"
- depends on OCF_OCF
- help
- OCF driver for various HIFN based crypto accelerators.
- (7951, 7955, 7956, 7751, 7811)
-
-config OCF_HIFNHIPP
- tristate "Hifn HIPP (HW packet crypto engine)"
- depends on OCF_OCF
- help
- OCF driver for various HIFN (HIPP) based crypto accelerators
- (7855)
-
-config OCF_TALITOS
- tristate "talitos (HW crypto engine)"
- depends on OCF_OCF
- help
- OCF driver for Freescale's security engine (SEC/talitos).
-
-config OCF_PASEMI
- tristate "pasemi (HW crypto engine)"
- depends on OCF_OCF && PPC_PASEMI
- help
- OCF driver for the PA Semi PWRficient DMA Engine
-
-config OCF_EP80579
- tristate "ep80579 (HW crypto engine)"
- depends on OCF_OCF
- help
- OCF driver for the Intel EP80579 Integrated Processor Product Line.
-
-config OCF_CRYPTOCTEON
- tristate "cryptocteon (HW crypto engine)"
- depends on OCF_OCF
- help
- OCF driver for the Cavium OCTEON Processors.
-
-config OCF_KIRKWOOD
- tristate "kirkwood (HW crypto engine)"
- depends on OCF_OCF
- help
- OCF driver for the Marvell Kirkwood (88F6xxx) Processors.
-
-config OCF_C7108
- tristate "Micronas 7108 (HW crypto engine)"
- depends on OCF_OCF
- help
- OCF driver for the Microna 7108 Cipher processors.
-
-config OCF_OCFNULL
- tristate "ocfnull (fake crypto engine)"
- depends on OCF_OCF
- help
- OCF driver for measuring ipsec overheads (does no crypto)
-
config OCF_BENCH
tristate "ocf-bench (HW crypto in-kernel benchmark)"
depends on OCF_OCF
diff --git a/crypto/ocf/Makefile b/crypto/ocf/Makefile
index fa951f4..aab3fae 100644
--- a/crypto/ocf/Makefile
+++ b/crypto/ocf/Makefile
@@ -37,17 +37,6 @@ obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
-$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
-$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
-$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
-$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
-$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
-$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
-$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)
-$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)
-$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
-$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)
-
ocf-objs := $(OCF_OBJS)
$(list-multi) dummy1: $(ocf-objs)
--
1.7.0.4
@@ -1,319 +0,0 @@
From 0192a1d0731d3e8959b817bbc458c21e1c51408f Mon Sep 17 00:00:00 2001
From: Greg Guyotte <gguyotte@ti.com>
Date: Tue, 5 Jun 2012 16:54:26 -0500
Subject: [PATCH] am37x: Adding ABB Support for 1GHz OPP
This patch adds ABB support for the AM37x 1GHz OPP. When 1GHz
operation occurs, the ABB LDO will be enabled, effectively
boosting MPU voltage. At any time that we are not operating
at 1GHz, the ABB LDO will be bypassed. This change is
required for operation at 1GHz on the AM37x device.
This patch only affects AM37x. In the course of booting,
it boosts the MPU rate to 1GHz and turns on the ABB LDO. It
is expected that the system will be operating at 800MHz
prior to this time, as set by Uboot. Also note that after
MPU rate is changed, the loops_per_jiffy global is updated,
which is required in order to get the proper readout from
BogoMIPS.
Upstream-Status: Not Appropriate
* This patch is a quick fix based on an old kernel.
* This will be reworked for the Linux mainline kernel.
Signed-off-by: Greg Guyotte <gguyotte@ti.com>
---
arch/arm/mach-omap2/pm.c | 30 +++++++-
arch/arm/mach-omap2/prm-regbits-34xx.h | 20 +++++
arch/arm/mach-omap2/prm2xxx_3xxx.h | 5 ++
arch/arm/mach-omap2/voltage.c | 123 ++++++++++++++++++++++++++++++++
4 files changed, 176 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index f7e4d1b..678877c 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -27,6 +27,8 @@
#include "cm2xxx_3xxx.h"
#include "pm.h"
+#define RATE_1GHZ 1000000000
+
static struct omap_device_pm_latency *pm_lats;
static struct device *mpu_dev;
@@ -61,7 +63,6 @@ struct device *omap4_get_dsp_device(void)
}
EXPORT_SYMBOL(omap4_get_dsp_device);
-#ifndef CONFIG_CPU_FREQ
static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
{
unsigned long new_jiffy_l, new_jiffy_h;
@@ -81,7 +82,6 @@ static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
return new_jiffy_h + new_jiffy_l * 100;
}
-#endif
/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
static int _init_omap_device(char *name, struct device **new_dev)
@@ -289,6 +289,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
struct clk *clk;
struct opp *opp;
unsigned long freq, bootup_volt;
+ int ret;
if (!vdd_name || !clk_name || !dev) {
printk(KERN_ERR "%s: Invalid parameters!\n", __func__);
@@ -311,6 +312,11 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
freq = clk->rate;
clk_put(clk);
+
+ /* set up for a voltage to support 1GHz */
+ if (cpu_is_omap3630())
+ if (!strcmp(vdd_name, "mpu"))
+ freq = RATE_1GHZ;
opp = opp_find_freq_ceil(dev, &freq);
if (IS_ERR(opp)) {
@@ -327,6 +333,26 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
}
omap_voltage_scale_vdd(voltdm, bootup_volt);
+
+ /* once voltage is changed, we can scale freq to max */
+ if (cpu_is_omap3630()) {
+ if (!strcmp(vdd_name, "mpu")) {
+ unsigned long cur_rate;
+ cur_rate = clk->rate;
+
+ ret = clk_set_rate(clk, RATE_1GHZ);
+ if (ret) {
+ dev_warn(dev, "%s: Unable to set rate to %d\n",
+ __func__, RATE_1GHZ);
+ return ret;
+ }
+ /* Update loops_per_jiffy because processor speed is
+ being changed. Necessary to keep BogoMIPS happy. */
+ loops_per_jiffy = compute_lpj(loops_per_jiffy,
+ cur_rate / 1000000,
+ RATE_1GHZ / 1000000);
+ }
+ }
return 0;
exit:
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index 64c087a..2758fa3 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -89,6 +89,7 @@
#define OMAP3430_LASTPOWERSTATEENTERED_MASK (0x3 << 0)
/* PRM_IRQSTATUS_IVA2, PRM_IRQSTATUS_MPU shared bits */
+#define OMAP3630_ABB_LDO_TRANXDONE_ST (1 << 26)
#define OMAP3430_WKUP_ST_MASK (1 << 0)
/* PRM_IRQENABLE_IVA2, PRM_IRQENABLE_MPU shared bits */
@@ -216,6 +217,9 @@
/* PRM_SYSCONFIG specific bits */
/* PRM_IRQSTATUS_MPU specific bits */
+#define OMAP3630_VC_BYPASS_ACK_EN (1 << 28)
+#define OMAP3630_VC_VP1_ACK_EN (1 << 27)
+#define OMAP3630_VC_ABB_LDO_TRANXDONE_EN (1 << 26)
#define OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT 25
#define OMAP3430ES2_SND_PERIPH_DPLL_ST_MASK (1 << 25)
#define OMAP3430_VC_TIMEOUTERR_ST_MASK (1 << 24)
@@ -587,6 +591,22 @@
/* PRM_VP2_STATUS specific bits */
+/* PRM_LDO_ABB_SETUP */
+#define OMAP3630_SR2_IN_TRANSITION (1 << 6)
+#define OMAP3630_SR2_STATUS_SHIFT 3
+#define OMAP3630_SR2_STATUS_MASK (0x3 << 3)
+#define OMAP3630_OPP_CHANGE (1 << 2)
+#define OMAP3630_OPP_SEL_SHIFT 0
+#define OMAP3630_OPP_SEL_MASK (0x3 << 0)
+
+/* PRM_LDO_ABB_CTRL */
+#define OMAP3630_SR2_WTCNT_VALUE_SHIFT 8
+#define OMAP3630_SR2_WTCNT_VALUE_MASK (0xff << 8)
+#define OMAP3630_SLEEP_RBB_SEL (1 << 3)
+#define OMAP3630_ACTIVE_FBB_SEL (1 << 2)
+#define OMAP3630_ACTIVE_RBB_SEL (1 << 1)
+#define OMAP3630_SR2EN (1 << 0)
+
/* RM_RSTST_NEON specific bits */
/* PM_WKDEP_NEON specific bits */
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index 613f83c..79c9ad5 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -171,6 +171,11 @@
#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4
#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
+#define OMAP3_PRM_LDO_ABB_SETUP_OFFSET 0x00f0
+#define OMAP3430_PRM_LDO_ABB_SETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00f0)
+#define OMAP3_PRM_LDO_ABB_CTRL_OFFSET 0x00f4
+#define OMAP3430_PRM_LDO_ABB_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00f4)
+
#define OMAP3_PRM_CLKSEL_OFFSET 0x0040
#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 2e015a7..32944d0 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -45,6 +45,10 @@
#define VP_TRANXDONE_TIMEOUT 300
#define VOLTAGE_DIR_SIZE 16
+#define ABB_TRANXDONE_TIMEOUT 100
+#define ABB_FAST_OPP 1
+#define ABB_NOMINAL_OPP 2
+
/* Voltage processor register offsets */
struct vp_reg_offs {
u8 vpconfig;
@@ -764,6 +768,112 @@ static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
return 0;
}
+/**
+ * omap3630_abb_change_active_opp - handle OPP changes with Adaptive Body-Bias
+ * @target_opp_no: ABB_FAST_OPP or ABB_NOMINAL_OPP
+ *
+ * Adaptive Body-Bias is a 3630-specific technique to boost voltage in high
+ * OPPs for silicon with weak characteristics as well as lower voltage in low
+ * OPPs for silicon with strong characteristics.
+ *
+ * Only Foward Body-Bias for operating at high OPPs is implemented below.
+ * Reverse Body-Bias for saving power in active cases and sleep cases is not
+ * yet implemented.
+ */
+static int omap3630_abb_change_active_opp(u32 target_opp_no)
+{
+ u32 sr2en_enabled;
+ int timeout;
+
+ /* has SR2EN been enabled previously? */
+ sr2en_enabled = (omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
+ OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
+ OMAP3630_SR2EN);
+
+ /* select OPP */
+ /* FIXME: shouldn't be hardcoded OPP here */
+ if (target_opp_no == ABB_FAST_OPP) {
+ /* program for fast opp - enable fbb */
+ omap2_prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
+ (ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
+
+ /* enable the ABB ldo if not done already */
+ if (!sr2en_enabled)
+ omap2_prm_set_mod_reg_bits(OMAP3630_SR2EN,
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
+ pr_debug("ABB: ABB LDO Enabled\n");
+ } else if (sr2en_enabled) {
+ /* program for nominal opp - bypass abb ldo */
+ omap2_prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
+ (ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
+ pr_debug("ABB: ABB LDO Bypassed\n");
+ } else {
+ /* nothing to do here */
+ return 0;
+ }
+
+ /* set ACTIVE_FBB_SEL for all 3630 silicon */
+ omap2_prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
+
+ /* program settling time of 30us for ABB ldo transition */
+ omap2_prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
+ (0x62 << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
+
+ /* clear ABB ldo interrupt status */
+ omap2_prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
+ OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+
+ /* enable ABB LDO OPP change */
+ omap2_prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
+
+ timeout = 0;
+
+ /* wait until OPP change completes */
+ while ((timeout < ABB_TRANXDONE_TIMEOUT ) &&
+ (!(omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET) &
+ OMAP3630_ABB_LDO_TRANXDONE_ST))) {
+ udelay(1);
+ timeout++;
+ }
+
+ if (timeout == ABB_TRANXDONE_TIMEOUT)
+ pr_warning("ABB: TRANXDONE timed out waiting for OPP change\n");
+
+ timeout = 0;
+
+ /* Clear all pending TRANXDONE interrupts/status */
+ while (timeout < ABB_TRANXDONE_TIMEOUT) {
+ omap2_prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
+ OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ if (!(omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET)
+ & OMAP3630_ABB_LDO_TRANXDONE_ST))
+ break;
+
+ udelay(1);
+ timeout++;
+ }
+
+ if (timeout == ABB_TRANXDONE_TIMEOUT)
+ pr_warning("ABB: TRANXDONE timed out trying to clear status\n");
+
+ return 0;
+}
+
/* VP force update method of voltage scaling */
static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
unsigned long target_volt)
@@ -858,6 +968,19 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
vpconfig &= ~vdd->vp_reg.vpconfig_forceupdate;
vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ if (cpu_is_omap3630() && !strcmp(vdd->voltdm.name, "mpu")) {
+ if (vdd->curr_volt == OMAP3630_VDD_MPU_OPP1G_UV) {
+ pr_debug("%s: vdd_%s: Attempting ABB enable\n",
+ __func__, vdd->voltdm.name);
+ omap3630_abb_change_active_opp(ABB_FAST_OPP);
+ }
+ else {
+ pr_debug("%s: vdd_%s: Attempting ABB disable\n",
+ __func__, vdd->voltdm.name);
+ omap3630_abb_change_active_opp(ABB_NOMINAL_OPP);
+ }
+ }
+
return 0;
}
--
1.7.0.4
@@ -1,29 +0,0 @@
From ac7635211d2a5b133bac56fec4b6ed087f553e49 Mon Sep 17 00:00:00 2001
From: Punya Prakash <pprakash@ti.com>
Date: Thu, 30 Jun 2011 13:52:18 -0500
Subject: [PATCH] mt9t111: enable clock pad register in configuration
* fixes the issue where sensor sync pulses were not generated during first loopback after boot-up
Upstream-Status: Pending
Signed-off-by: Punya Prakash <pprakash@ti.com>
---
drivers/media/video/mt9t111.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/mt9t111.c b/drivers/media/video/mt9t111.c
index f18aa24..02c18a5 100644
--- a/drivers/media/video/mt9t111.c
+++ b/drivers/media/video/mt9t111.c
@@ -290,6 +290,9 @@ static int mt9t111_configure(struct v4l2_subdev *subdev)
if (err)
goto out;
+ // Enable Clock pad
+ err = mt9t111_write_reg(client, 0x0016, 0x0400);
+
err = mt9t111_write_regs(client, def_regs1,
sizeof(def_regs1) / sizeof(mt9t111_regs));
if (err)
--
@@ -1,96 +0,0 @@
From 33f43b37f82038e8383e76d621448a9983ed35e4 Mon Sep 17 00:00:00 2001
From: Eyal Reizer <eyalr@ti.com>
Date: Wed, 3 Aug 2011 14:48:18 +0300
Subject: [PATCH 1/6] nlcp: sdio fixes for wowlan support
Upstream status: pending
Signed-off-by: Eyal Reizer <eyalr@ti.com>
---
drivers/mmc/core/core.c | 8 ++++++--
drivers/mmc/core/sdio.c | 2 +-
drivers/mmc/host/omap_hsmmc.c | 2 ++
include/linux/mmc/host.h | 9 +++++++++
4 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 2762ad2..55bc015 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1705,7 +1705,7 @@ int mmc_suspend_host(struct mmc_host *host)
}
mmc_bus_put(host);
- if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
+ if (!err && !mmc_card_keep_power(host))
mmc_power_off(host);
return err;
@@ -1723,7 +1723,7 @@ int mmc_resume_host(struct mmc_host *host)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
- if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
+ if (!mmc_card_keep_power(host)) {
mmc_power_up(host);
mmc_select_voltage(host, host->ocr);
/*
@@ -1748,6 +1748,10 @@ int mmc_resume_host(struct mmc_host *host)
err = 0;
}
}
+
+ /* clear flag */
+ host->pm_flags &= ~MMC_PM_KEEP_POWER;
+
mmc_bus_put(host);
return err;
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index b424fbe..4a198b2 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -616,7 +616,7 @@ static int mmc_sdio_suspend(struct mmc_host *host)
}
}
- if (!err && host->pm_flags & MMC_PM_KEEP_POWER) {
+ if (!err && mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
mmc_claim_host(host);
sdio_disable_wide(host->card);
mmc_release_host(host);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index c75c799..b5f496d 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2222,6 +2222,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
if (mmc_slot(host).nonremovable)
mmc->caps |= MMC_CAP_NONREMOVABLE;
+ mmc->pm_caps |= MMC_PM_KEEP_POWER;
+
omap_hsmmc_conf_bus_power(host);
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 86d74a5..74694c4 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -312,5 +312,14 @@ static inline int mmc_card_is_powered_resumed(struct mmc_host *host)
return host->pm_flags & MMC_PM_KEEP_POWER;
}
+static inline int mmc_card_keep_power(struct mmc_host *host)
+{
+ return host->pm_flags & MMC_PM_KEEP_POWER;
+}
+
+static inline int mmc_card_wake_sdio_irq(struct mmc_host *host)
+{
+ return host->pm_flags & MMC_PM_WAKE_SDIO_IRQ;
+}
#endif
--
1.7.0.4
@@ -1,48 +0,0 @@
From 2056c6802c5afbd722fcffc99a5cf50bbaee23c8 Mon Sep 17 00:00:00 2001
From: Tom Rini <trini@ti.com>
Date: Tue, 15 Nov 2011 17:43:31 -0700
Subject: [PATCH 1/3] omap3:am3517evm: Allow for NAND to really be disabled
On boards with both NAND and NOR and NOR being selected, NAND needs
to be disabled fully.
Signed-off-by: Tom Rini <trini@ti.com>
---
.../arch/arm/mach-omap2/board-am3517evm.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 3992b86..1d17415 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -59,6 +59,7 @@
#define NAND_BLOCK_SIZE SZ_128K
+#ifdef CONFIG_MTD_NAND_OMAP2
static struct mtd_partition am3517evm_nand_partitions[] = {
/* All the partition sizes are listed in terms of NAND block size */
{
@@ -89,6 +90,7 @@ static struct mtd_partition am3517evm_nand_partitions[] = {
.offset = MTDPART_OFS_APPEND,
},
};
+#endif
static struct mdio_platform_data am3517_evm_mdio_pdata = {
.bus_freq = AM35XX_EVM_MDIO_FREQUENCY,
@@ -926,9 +928,11 @@ static void __init am3517_evm_init(void)
/* DSS */
am3517_evm_display_init();
+#ifdef CONFIG_MTD_NAND_OMAP2
/* NAND */
board_nand_init(am3517evm_nand_partitions,
ARRAY_SIZE(am3517evm_nand_partitions), 0, NAND_BUSWIDTH_16);
+#endif
/* RTC - S35390A */
am3517_evm_rtc_init();
--
1.7.0.4
@@ -1,147 +0,0 @@
From 20a525629de613000b6f22f91f40063b0a43e7cc Mon Sep 17 00:00:00 2001
From: Eyal Reizer <eyalr@ti.com>
Date: Tue, 12 Apr 2011 22:50:51 +0300
Subject: [PATCH] omap3evm:add support for the WL12xx WLAN module
Signed-off-by: Eyal Reizer <eyalr@ti.com>
---
arch/arm/mach-omap2/board-omap3evm.c | 89 ++++++++++++++++++++++++++++++++++
1 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index c8aabff..4088840 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -31,6 +31,8 @@
#include <linux/usb/otg.h>
#include <linux/smsc911x.h>
+#include <linux/wl12xx.h>
+#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <linux/mmc/host.h>
@@ -452,6 +454,16 @@ static struct omap2_hsmmc_info mmc[] = {
.gpio_cd = -EINVAL,
.gpio_wp = 63,
},
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ {
+ .name = "wl1271",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
+#endif
{} /* Terminator */
};
@@ -671,6 +683,47 @@ static struct regulator_init_data omap3_evm_vio = {
.consumer_supplies = omap3_evm_vio_supply,
};
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+
+#define OMAP3EVM_WLAN_PMENA_GPIO (150)
+#define OMAP3EVM_WLAN_IRQ_GPIO (149)
+
+static struct regulator_consumer_supply omap3evm_vmmc2_supply =
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1");
+
+/* VMMC2 for driving the WL12xx module */
+static struct regulator_init_data omap3evm_vmmc2 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3evm_vmmc2_supply,
+};
+
+static struct fixed_voltage_config omap3evm_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.80V */
+ .gpio = OMAP3EVM_WLAN_PMENA_GPIO,
+ .startup_delay = 70000, /* 70ms */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &omap3evm_vmmc2,
+};
+
+static struct platform_device omap3evm_wlan_regulator = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &omap3evm_vwlan,
+ },
+};
+
+struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(OMAP3EVM_WLAN_IRQ_GPIO),
+ .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
+};
+#endif
+
static struct twl4030_platform_data omap3evm_twldata = {
.irq_base = TWL4030_IRQ_BASE,
.irq_end = TWL4030_IRQ_END,
@@ -876,6 +929,21 @@ static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP_PIN_OFF_NONE),
OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
OMAP_PIN_OFF_NONE),
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WLAN IRQ - GPIO 149 */
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* WLAN POWER ENABLE - GPIO 150 */
+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* MMC2 SDIO pin muxes for WL12xx */
+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+#endif
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
@@ -901,6 +969,21 @@ static struct omap_board_mux omap36x_board_mux[] __initdata = {
OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WLAN IRQ - GPIO 149 */
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* WLAN POWER ENABLE - GPIO 150 */
+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* MMC2 SDIO pin muxes for WL12xx */
+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+#endif
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#else
@@ -976,6 +1059,12 @@ static void __init omap3_evm_init(void)
0, NAND_BUSWIDTH_16);
board_onenand_init(omap3_evm_onenand_partitions,
ARRAY_SIZE(omap3_evm_onenand_partitions), 0);
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WL12xx WLAN Init */
+ if (wl12xx_set_platform_data(&omap3evm_wlan_data))
+ pr_err("error setting wl12xx data\n");
+ platform_device_register(&omap3evm_wlan_regulator);
+#endif
}
MACHINE_START(OMAP3EVM, "OMAP3 EVM")
--
1.7.0.4
@@ -1,49 +0,0 @@
From 5e7643b6e4fe8144e576f2faf9f1e07fd2a7753f Mon Sep 17 00:00:00 2001
From: Eyal Reizer <eyalr@ti.com>
Date: Wed, 3 Aug 2011 14:01:45 +0300
Subject: [PATCH 1/8] omap3evm: add wake on wlan support
Upstream status: pending
Signed-off-by: Eyal Reizer <eyalr@ti.com>
---
arch/arm/mach-omap2/board-omap3evm.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 4088840..08c074a 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -458,7 +458,8 @@ static struct omap2_hsmmc_info mmc[] = {
{
.name = "wl1271",
.mmc = 2,
- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD
+ | MMC_PM_KEEP_POWER ,
.gpio_wp = -EINVAL,
.gpio_cd = -EINVAL,
.nonremovable = true,
@@ -931,7 +932,8 @@ static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP_PIN_OFF_NONE),
#ifdef CONFIG_WL12XX_PLATFORM_DATA
/* WLAN IRQ - GPIO 149 */
- OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT |
+ OMAP_PIN_OFF_WAKEUPENABLE),
/* WLAN POWER ENABLE - GPIO 150 */
OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
@@ -971,7 +973,8 @@ static struct omap_board_mux omap36x_board_mux[] __initdata = {
OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
#ifdef CONFIG_WL12XX_PLATFORM_DATA
/* WLAN IRQ - GPIO 149 */
- OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT |
+ OMAP_PIN_OFF_WAKEUPENABLE),
/* WLAN POWER ENABLE - GPIO 150 */
OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
--
1.7.0.4
@@ -1,34 +0,0 @@
From a4f14adcde615d2f6689ed9046464dad8a5465f6 Mon Sep 17 00:00:00 2001
From: Chase Maupin <Chase.Maupin@ti.com>
Date: Mon, 21 Nov 2011 07:40:40 -0600
Subject: [PATCH] omap_hsmmc: make default dto value 14
* It seems that making the dto value makes all the various SD
cards work. If not we will sometimes see -110 errors during
boot with certain SD cards.
* Based on input from Steve Kipisz
Upstream-Status: Pending
Signed-off-by: Chase Maupin <Chase.Maupin@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b5f496d..6985331 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1494,6 +1494,9 @@ static void set_data_timeout(struct omap_hsmmc_host *host,
dto = 14;
}
+ // Use 14 by default because this seems to work will with all cards
+ dto = 14;
+
reg &= ~DTO_MASK;
reg |= dto << DTO_SHIFT;
OMAP_HSMMC_WRITE(host->base, SYSCTL, reg);
--
1.7.0.4
@@ -1,38 +0,0 @@
From f0cf4495fc1d4dfb71a93eb6e315789c276221da Mon Sep 17 00:00:00 2001
From: Bin Liu <b-liu@ti.com>
Date: Wed, 30 May 2012 15:35:07 -0500
Subject: [PATCH 1/2] usb: musb: am35x: set default VBUS timeout value
The issue was:
musb->a_wait_bcon was not set so the OTG timer does not start when
a USB device gets disconnected to reset the OTG back to b_idle state.
Signed-off-by: Bin Liu <b-liu@ti.com>
---
drivers/usb/musb/am35x.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 57d4417..a59a5e7 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -79,6 +79,8 @@
#define AM35X_TX_INTR_MASK (AM35X_TX_EP_MASK << AM35X_INTR_TX_SHIFT)
#define AM35X_RX_INTR_MASK (AM35X_RX_EP_MASK << AM35X_INTR_RX_SHIFT)
+#define A_WAIT_BCON_TIMEOUT 1100 /* in ms */
+
/* CPPI 4.1 queue manager registers */
#define QMGR_PEND0_REG 0x4090
#define QMGR_PEND1_REG 0x4094
@@ -599,6 +601,7 @@ static int am35x_musb_init(struct musb *musb)
cppi41_init(musb);
#endif
+ musb->a_wait_bcon = A_WAIT_BCON_TIMEOUT;
musb->isr = am35x_musb_interrupt;
/* clear level interrupt */
--
1.7.0.4
@@ -1,37 +0,0 @@
From bc0118889db3c48fd5760fcd8d9633373a18d8fc Mon Sep 17 00:00:00 2001
From: Eyal Reizer <eyalr@ti.com>
Date: Wed, 30 Mar 2011 15:39:26 +0200
Subject: [PATCH 153/153] allow selecting WL12XX_PLATFROM_DATA independently of whether mac80211
and wl12xx drivers are selected in the kernel.
Needed for building with compat-wireless
Signed-off-by: Eyal Reizer <eyalr@ti.com>
---
arch/arm/mach-omap2/Kconfig | 1 +
drivers/net/wireless/wl12xx/Kconfig | 1 -
2 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index c787aef..0f67445 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -37,6 +37,7 @@ config ARCH_OMAP3
select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4
select ARCH_HAS_OPP
select PM_OPP if PM
+ select WL12XX_PLATFORM_DATA
config ARCH_OMAP4
bool "TI OMAP4"
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index b447559..441aaf6 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -42,5 +42,4 @@ config WL1271_SDIO
config WL12XX_PLATFORM_DATA
bool
- depends on WL1271_SDIO != n
default y
--
1.7.0.4
@@ -1,82 +0,0 @@
From 3c61d0342093f4fbaeed8f063474ddfb250062fe Mon Sep 17 00:00:00 2001
From: Ohad Ben-Cohen <ohad@wizery.com>
Date: Sat, 2 Oct 2010 13:54:13 +0200
Subject: [PATCH 2/6] mmc: sdio: support suspend/resume while runtime suspended
Bring SDIO devices back to full power before their suspend
handler is invoked.
Doing so ensures that SDIO suspend/resume semantics are
maintained (drivers still get to decide whether their
card should be removed or kept during system suspend,
and at what power state), and that SDIO suspend/resume
execution paths are unchanged.
This is achieved by resuming a runtime-suspended SDIO device
in its ->prepare() PM callback (similary to the PCI subsystem).
Since the PM core always increments the run-time usage
counter before calling the ->prepare() callback and decrements
it after calling the ->complete() callback, it is guaranteed
that when the system will come out of suspend, our device's
power state will reflect its runtime PM usage counter.
Upstream status: accepted
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Tested-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/mmc/core/sdio_bus.c | 29 +++++++++++++++++++++++++++++
1 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index d29b9c3..aadb12d 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -197,12 +197,41 @@ out:
#ifdef CONFIG_PM_RUNTIME
+static int sdio_bus_pm_prepare(struct device *dev)
+{
+ /*
+ * Resume an SDIO device which was suspended at run time at this
+ * point, in order to allow standard SDIO suspend/resume paths
+ * to keep working as usual.
+ *
+ * Ultimately, the SDIO driver itself will decide (in its
+ * suspend handler, or lack thereof) whether the card should be
+ * removed or kept, and if kept, at what power state.
+ *
+ * At this point, PM core have increased our use count, so it's
+ * safe to directly resume the device. After system is resumed
+ * again, PM core will drop back its runtime PM use count, and if
+ * needed device will be suspended again.
+ *
+ * The end result is guaranteed to be a power state that is
+ * coherent with the device's runtime PM use count.
+ *
+ * The return value of pm_runtime_resume is deliberately unchecked
+ * since there is little point in failing system suspend if a
+ * device can't be resumed.
+ */
+ pm_runtime_resume(dev);
+
+ return 0;
+}
+
static const struct dev_pm_ops sdio_bus_pm_ops = {
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
pm_generic_runtime_idle
)
+ .prepare = sdio_bus_pm_prepare,
};
#define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops)
--
1.7.0.4
@@ -1,58 +0,0 @@
From 3cf420f85f2ccaf01e8b76a7bbdc0b7119269032 Mon Sep 17 00:00:00 2001
From: Tom Rini <trini@ti.com>
Date: Tue, 15 Nov 2011 17:44:24 -0700
Subject: [PATCH 2/3] omap3:am3517evm: Update NOR partition table
With newer U-Boot we use a different partition table on NOR
Signed-off-by: Tom Rini <trini@ti.com>
---
.../arch/arm/mach-omap2/board-am3517evm.c | 19 ++++++-------------
1 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 1d17415..e559f33 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -758,32 +758,25 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
/* NOR flash information */
static struct mtd_partition am3517_evm_norflash_partitions[] = {
- /* primiary bootloader (X-loader) in first 4 sectors(32K) */
- {
- .name = "X-Loader-NOR",
- .offset = 0,
- .size = 4 * SZ_32K,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- /* secondary bootloader (U-Boot, etc) in first 5 sectors(128K) */
+ /* Bootloader (U-Boot) in first 512K */
{
.name = "U-Boot-NOR",
- .offset = MTDPART_OFS_APPEND,
- .size = 5 * SZ_128K,
+ .offset = 0,
+ .size = 4 * SZ_128K,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
- /* bootloader params in the next 2 sectors */
+ /* bootloader params in the next sector */
{
.name = "Boot Env-NOR",
.offset = MTDPART_OFS_APPEND,
- .size = 2 * SZ_128K,
+ .size = SZ_128K,
.mask_flags = 0,
},
/* kernel */
{
.name = "Kernel-NOR",
.offset = MTDPART_OFS_APPEND,
- .size = 32 * SZ_128K,
+ .size = 27 * SZ_128K,
.mask_flags = 0
},
/* file system */
--
1.7.0.4
@@ -1,67 +0,0 @@
From 96fa47d92d10382f4e0d9b6e3ab2c627e4671716 Mon Sep 17 00:00:00 2001
From: Bin Liu <b-liu@ti.com>
Date: Wed, 30 May 2012 18:28:07 -0500
Subject: [PATCH 2/2] usb: musb: am35x: fix role switching issue
Fixing the role switching issue seen when followed steps below:
a) Configure port in OTG mode
b) Connect MSC device through micro-A-plug to std-A-receptacle
c) MSC enumerated and works fine
d) Disconnect MSC device and let cable be connected to port
e) Now disconnect cable also
f) Connect port to host PC using micro-B plug to std-A plug
e) PC doesn't recognise the gadget driver
Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
Signed-off-by: Bin Liu <b-liu@ti.com>
---
drivers/usb/musb/am35x.c | 25 ++++++++++++++++++++-----
1 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index a59a5e7..d32fb77 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -368,6 +368,13 @@ static void otg_timer(unsigned long _musb)
devctl = musb_readb(mregs, MUSB_DEVCTL);
if (devctl & MUSB_DEVCTL_BDEVICE)
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
+ else if ((devctl & MUSB_DEVCTL_SESSION) &&
+ !(devctl & MUSB_DEVCTL_BDEVICE)) {
+ mod_timer(&otg_workaround,
+ jiffies + POLL_SECONDS * HZ);
+ musb_writeb(musb->mregs, MUSB_DEVCTL, devctl &
+ ~MUSB_DEVCTL_SESSION);
+ }
else
musb->xceiv->state = OTG_STATE_A_IDLE;
break;
@@ -502,11 +509,19 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
WARNING("VBUS error workaround (delay coming)\n");
} else if (is_host_enabled(musb) && drvvbus) {
- MUSB_HST_MODE(musb);
- musb->xceiv->default_a = 1;
- musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
- portstate(musb->port1_status |= USB_PORT_STAT_POWER);
- del_timer(&otg_workaround);
+ if (!(devctl & MUSB_DEVCTL_SESSION) ||
+ (devctl & MUSB_DEVCTL_BDEVICE) ||
+ (devctl & MUSB_DEVCTL_HM)) {
+ if (musb->is_active)
+ del_timer(&otg_workaround);
+ else
+ musb->is_active = 1;
+
+ MUSB_HST_MODE(musb);
+ musb->xceiv->default_a = 1;
+ musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+ portstate(musb->port1_status |= USB_PORT_STAT_POWER);
+ }
} else {
musb->is_active = 0;
MUSB_DEV_MODE(musb);
--
1.7.0.4
@@ -1,256 +0,0 @@
From 0fa5a9c5cf331d5df578797e778f18de223e02aa Mon Sep 17 00:00:00 2001
From: Tom Rini <trini@ti.com>
Date: Wed, 16 Nov 2011 09:02:23 -0700
Subject: [PATCH 3/3] AM3517: Add am3517_evn_nor_defconfig
When building for NOR, we need to disable NAND. Provide a config
that does so.
Signed-off-by: Tom Rini <trini@ti.com>
---
arch/arm/configs/am3517_evm_nor_defconfig | 233 ++++++++++++++++++++
1 files changed, 233 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/configs/am3517_evm_nor_defconfig
diff --git a/arch/arm/configs/am3517_evm_nor_defconfig b/arch/arm/configs/am3517_evm_nor_defconfig
new file mode 100644
index 0000000..70bd7dd
--- /dev/null
+++ b/arch/arm/configs/am3517_evm_nor_defconfig
@@ -0,0 +1,233 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_OMAP=y
+CONFIG_OMAP_RESET_CLOCKS=y
+CONFIG_OMAP_MUX_DEBUG=y
+# CONFIG_ARCH_OMAP2 is not set
+# CONFIG_ARCH_OMAP4 is not set
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_DEVKIT8000 is not set
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OMAP3530_LV_SOM is not set
+# CONFIG_MACH_OMAP3_TORPEDO is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP3_TOUCHBOOK is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RM680 is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
+# CONFIG_MACH_OMAP_ZOOM3 is not set
+# CONFIG_MACH_CM_T35 is not set
+# CONFIG_MACH_CM_T3517 is not set
+# CONFIG_MACH_IGEP0020 is not set
+# CONFIG_MACH_IGEP0030 is not set
+# CONFIG_MACH_SBC3530 is not set
+# CONFIG_MACH_OMAP_3630SDP is not set
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_458693=y
+CONFIG_ARM_ERRATA_460075=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PM_DEBUG=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_VCAN=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_TI_HECC=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_OOPS=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MD=y
+CONFIG_NETDEVICES=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+CONFIG_TI_DAVINCI_EMAC=y
+CONFIG_USB_USBNET=y
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_DM9601=y
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_INPUT_JOYDEV=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_TCA6416=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_TSC2004=y
+CONFIG_INPUT_MISC=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_HW_RANDOM=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_OMAP24XX=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_OMAP_WATCHDOG=y
+CONFIG_REGULATOR_DUMMY=y
+CONFIG_REGULATOR_TPS65023=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+# CONFIG_IR_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEO_TVP514X=y
+CONFIG_VIDEO_VPFE_CAPTURE=y
+CONFIG_VIDEO_OMAP2_VOUT=y
+CONFIG_USB_VIDEO_CLASS=y
+# CONFIG_RADIO_ADAPTERS is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_OMAP2_VRAM_SIZE=4
+CONFIG_OMAP2_DSS_DSI=y
+CONFIG_OMAP2_DSS_USE_DSI_PLL=y
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=1
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_NUM_FBS=1
+CONFIG_PANEL_GENERIC=y
+CONFIG_PANEL_SHARP_LQ043T1DG01=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=m
+CONFIG_DISPLAY_SUPPORT=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_OMAP_SOC_AM3517EVM=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG_WHITELIST is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_AM35X_GLUE=y
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_DEBUG=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_TEST=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_MMC=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_OMAP=y
+CONFIG_MMC_OMAP_HS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_QUOTA=y
+CONFIG_QFMT_V2=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCK_STAT=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+CONFIG_SECURITY=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=y
--
1.7.0.4
@@ -1,43 +0,0 @@
From 3627429b1a0cbe9380a9834fb91419fcb81be2ef Mon Sep 17 00:00:00 2001
From: Ohad Ben-Cohen <ohad@wizery.com>
Date: Sun, 28 Nov 2010 07:21:28 +0200
Subject: [PATCH 1/6] mmc: skip detection of nonremovable cards on rescan
mmc_rescan() checks whether registered cards are still present before
skipping them, by calling the bus-specific ->detect() handler.
With buses that support runtime PM, the card may be powered off at
this point, so they need to be powered on and fully reinitialized before
->detect() executes.
This whole process is redundant with nonremovable cards; in those cases,
we can safely skip calling ->detect() and implicitly assume its success.
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Reviewed-by: Chris Ball <cjb@laptop.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
---
drivers/mmc/core/core.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 57dcf8f..305e2a5 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1446,8 +1446,12 @@ void mmc_rescan(struct work_struct *work)
mmc_bus_get(host);
- /* if there is a card registered, check whether it is still present */
- if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
+ /*
+ * if there is a _removable_ card registered, check whether it is
+ * still present
+ */
+ if (host->bus_ops && host->bus_ops->detect && !host->bus_dead
+ && mmc_card_is_removable(host))
host->bus_ops->detect(host);
mmc_bus_put(host);
--
1.7.1
@@ -1,69 +0,0 @@
From 92093bb141b85f6f7396a0efd79d9f93c264baa3 Mon Sep 17 00:00:00 2001
From: Eyal Reizer <eyalr@ti.com>
Date: Wed, 3 Aug 2011 15:03:46 +0300
Subject: [PATCH 3/6] mmc_card_keep_power cleanups
mmc_card_is_powered_resumed is a mouthful; instead, simply use
mmc_card_keep_power, which also better explains the purpose of
the macro.
Employ mmc_card_keep_power() where possible.
Upstream status: accepted
Based on Ohad Ben-Cohen <ohad@wizery.com> original patch.
Signed-off-by: Eyal Reizer <eyalr@ti.com>
---
drivers/mmc/core/sdio.c | 14 +++++++-------
include/linux/mmc/host.h | 2 +-
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 4a198b2..e43ff56 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -635,12 +635,12 @@ static int mmc_sdio_resume(struct mmc_host *host)
/* Basic card reinitialization. */
mmc_claim_host(host);
- /* No need to reinitialize powered-resumed nonremovable cards */
- if (mmc_card_is_removable(host) || !mmc_card_is_powered_resumed(host))
- err = mmc_sdio_init_card(host, host->ocr, host->card,
- (host->pm_flags & MMC_PM_KEEP_POWER));
- else if (mmc_card_is_powered_resumed(host)) {
- /* We may have switched to 1-bit mode during suspend */
+ /* No need to reinitialize powered-resumed nonremovable cards */
+ if (mmc_card_is_removable(host) || !mmc_card_keep_power(host))
+ err = mmc_sdio_init_card(host, host->ocr, host->card,
+ mmc_card_keep_power(host));
+ else if (mmc_card_keep_power(host)) {
+ /* We may have switched to 1-bit mode during suspend */
err = sdio_enable_4bit_bus(host->card);
if (err > 0) {
mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
@@ -682,7 +682,7 @@ static int mmc_sdio_power_restore(struct mmc_host *host)
mmc_claim_host(host);
ret = mmc_sdio_init_card(host, host->ocr, host->card,
- (host->pm_flags & MMC_PM_KEEP_POWER));
+ mmc_card_keep_power(host));
if (!ret && host->sdio_irqs)
mmc_signal_sdio_irq(host);
mmc_release_host(host);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 74694c4..db2548f 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -307,7 +307,7 @@ static inline int mmc_card_is_removable(struct mmc_host *host)
return !(host->caps & MMC_CAP_NONREMOVABLE) && mmc_assume_removable;
}
-static inline int mmc_card_is_powered_resumed(struct mmc_host *host)
+static inline int mmc_card_keep_power(struct mmc_host *host)
{
return host->pm_flags & MMC_PM_KEEP_POWER;
}
--
1.7.0.4
@@ -1,283 +0,0 @@
From c49824d3d41982eb6d655f5cc4cc4c7e20d511c4 Mon Sep 17 00:00:00 2001
From: Chase Maupin <Chase.Maupin@ti.com>
Date: Mon, 27 Jun 2011 14:06:58 -0500
Subject: [PATCH 3/3] omap3_evm_defconfig: add WLAN config options
* Added the WLAN config options to be base default configuration.
Upstream-Status: Inappropriate [SDK specific changes]
Signed-off-by: Chase Maupin <Chase.Maupin@ti.com>
---
arch/arm/configs/omap3_evm_defconfig | 167 +++++++++++++++++++++++++++++++--
1 files changed, 156 insertions(+), 11 deletions(-)
diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig
index 6b9c736..5d44b2d 100644
--- a/arch/arm/configs/omap3_evm_defconfig
+++ b/arch/arm/configs/omap3_evm_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux/arm 2.6.37 Kernel Configuration
-# Mon Jun 27 13:40:14 2011
+# Tue Jun 28 07:29:21 2011
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -515,7 +515,123 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETLABEL is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
-# CONFIG_NETFILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+CONFIG_NF_CONNTRACK=y
+# CONFIG_NF_CONNTRACK_MARK is not set
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+# CONFIG_NF_CT_PROTO_DCCP is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+# CONFIG_NF_CONNTRACK_SANE is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+# CONFIG_NF_CT_NETLINK is not set
+CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+# CONFIG_NETFILTER_XT_MARK is not set
+# CONFIG_NETFILTER_XT_CONNMARK is not set
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATE is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=y
+# CONFIG_IP_NF_TARGET_REJECT is not set
+CONFIG_IP_NF_TARGET_LOG=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=y
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+# CONFIG_IP_NF_TARGET_REDIRECT is not set
+# CONFIG_NF_NAT_SNMP_BASIC is not set
+# CONFIG_NF_NAT_FTP is not set
+# CONFIG_NF_NAT_IRC is not set
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+# CONFIG_NF_NAT_SIP is not set
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_SECURITY is not set
+# CONFIG_IP_NF_ARPTABLES is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
# CONFIG_RDS is not set
@@ -548,7 +664,31 @@ CONFIG_DNS_RESOLVER=y
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
-# CONFIG_BT is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+# CONFIG_BT_HCIUART_BCSP is not set
+# CONFIG_BT_HCIUART_ATH3K is not set
+CONFIG_BT_HCIUART_LL=y
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
CONFIG_WIRELESS_EXT=y
@@ -566,7 +706,8 @@ CONFIG_WIRELESS_EXT_SYSFS=y
# Some wireless drivers require a rate control algorithm
#
# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
+CONFIG_RFKILL=y
+# CONFIG_RFKILL_INPUT is not set
# CONFIG_NET_9P is not set
# CONFIG_CAIF is not set
# CONFIG_CEPH_LIB is not set
@@ -851,6 +992,7 @@ CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=y
# CONFIG_USB_NET_CX82310_ETH is not set
+# CONFIG_USB_HSO is not set
# CONFIG_USB_NET_INT51X1 is not set
# CONFIG_USB_IPHETH is not set
# CONFIG_USB_SIERRA_NET is not set
@@ -1278,7 +1420,7 @@ CONFIG_TWL4030_CODEC=y
CONFIG_REGULATOR=y
# CONFIG_REGULATOR_DEBUG is not set
CONFIG_REGULATOR_DUMMY=y
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
# CONFIG_REGULATOR_BQ24022 is not set
@@ -1643,6 +1785,7 @@ CONFIG_USB_HID=y
# CONFIG_HID_CYPRESS is not set
# CONFIG_HID_DRAGONRISE is not set
# CONFIG_HID_EGALAX is not set
+# CONFIG_HID_ELECOM is not set
# CONFIG_HID_EZKEY is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_UCLOGIC is not set
@@ -1651,6 +1794,7 @@ CONFIG_USB_HID=y
# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MAGICMOUSE is not set
# CONFIG_HID_MICROSOFT is not set
# CONFIG_HID_MOSART is not set
# CONFIG_HID_MONTEREY is not set
@@ -1671,6 +1815,7 @@ CONFIG_USB_HID=y
# CONFIG_HID_SMARTJOYPLUS is not set
# CONFIG_HID_TOPSEED is not set
# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
# CONFIG_HID_ZEROPLUS is not set
# CONFIG_HID_ZYDACRON is not set
CONFIG_USB_SUPPORT=y
@@ -2286,7 +2431,7 @@ CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CBC=y
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_ECB=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_XTS is not set
@@ -2305,7 +2450,7 @@ CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_MICHAEL_MIC=y
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
@@ -2319,9 +2464,9 @@ CONFIG_CRYPTO_MD5=y
#
# Ciphers
#
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
@@ -2367,11 +2512,11 @@ CONFIG_BINARY_PRINTF=y
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
# CONFIG_CRC_T10DIF is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=y
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
--
1.7.0.4
@@ -1,43 +0,0 @@
From fbd81cb717ed6a875abd1f09e32e8f803a066a91 Mon Sep 17 00:00:00 2001
From: Eyal Reizer <eyalr@ti.com>
Date: Wed, 3 Aug 2011 15:10:30 +0300
Subject: [PATCH 4/6] mmc: do not switch to 1-bit mode if not required
6b5eda36 followed SDIO spec part E1 section 8, which states that
in case SDIO interrupts are being used to wake up a suspended host,
then it is required to switch to 1-bit mode before stopping the clock.
Before switching to 1-bit mode (or back to 4-bit mode on resume),
make sure that SDIO interrupts are really being used to wake the host.
This is helpful for devices which have an external irq line (e.g.
wl1271), and do not use SDIO interrupts to wake up the host.
In this case, switching to 1-bit mode (and back to 4-bit mode on resume)
is not necessary.
Upstream status: accepted
Based on patch made by Ohad Ben-Cohen <ohad@wizery.com>
Signed-off-by: Eyal Reizer <eyalr@ti.com>
---
drivers/mmc/core/sdio.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index e43ff56..2eeeaa2 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -639,7 +639,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
if (mmc_card_is_removable(host) || !mmc_card_keep_power(host))
err = mmc_sdio_init_card(host, host->ocr, host->card,
mmc_card_keep_power(host));
- else if (mmc_card_keep_power(host)) {
+ else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
/* We may have switched to 1-bit mode during suspend */
err = sdio_enable_4bit_bus(host->card);
if (err > 0) {
--
1.7.0.4
@@ -1,77 +0,0 @@
From 756d4919d44948a7a7d2860db75077c753a75039 Mon Sep 17 00:00:00 2001
From: Ohad Ben-Cohen <ohad@wizery.com>
Date: Sun, 28 Nov 2010 07:21:29 +0200
Subject: [PATCH 2/6] mmc: sdio: don't reinitialize nonremovable powered-resumed cards
Upon system resume, SDIO core must reinitialize cards that were
powered off during suspend.
If the card had its power kept during suspend (and thus it is
'powered-resumed'), SDIO core performs only a limited reinitializing,
mainly needed to make sure that the card wasn't removed/replaced.
If a __nonremovable__ card is powered-resumed, we can safely skip the
reinitializing phase.
Note: 9b966aa (mmc: sdio: fully reconfigure oldcard on resume) removed
the bus width reconfiguration since mmc_sdio_init_card already does it.
It is brought back now in case mmc_sdio_init_card is skipped.
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
---
drivers/mmc/core/sdio.c | 16 ++++++++++++++--
include/linux/mmc/host.h | 5 +++++
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index efef5f9..b424fbe 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -627,15 +627,27 @@ static int mmc_sdio_suspend(struct mmc_host *host)
static int mmc_sdio_resume(struct mmc_host *host)
{
- int i, err;
+ int i, err = 0;
BUG_ON(!host);
BUG_ON(!host->card);
/* Basic card reinitialization. */
mmc_claim_host(host);
- err = mmc_sdio_init_card(host, host->ocr, host->card,
+
+ /* No need to reinitialize powered-resumed nonremovable cards */
+ if (mmc_card_is_removable(host) || !mmc_card_is_powered_resumed(host))
+ err = mmc_sdio_init_card(host, host->ocr, host->card,
(host->pm_flags & MMC_PM_KEEP_POWER));
+ else if (mmc_card_is_powered_resumed(host)) {
+ /* We may have switched to 1-bit mode during suspend */
+ err = sdio_enable_4bit_bus(host->card);
+ if (err > 0) {
+ mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
+ err = 0;
+ }
+ }
+
if (!err && host->sdio_irqs)
mmc_signal_sdio_irq(host);
mmc_release_host(host);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 30f6fad..86d74a5 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -307,5 +307,10 @@ static inline int mmc_card_is_removable(struct mmc_host *host)
return !(host->caps & MMC_CAP_NONREMOVABLE) && mmc_assume_removable;
}
+static inline int mmc_card_is_powered_resumed(struct mmc_host *host)
+{
+ return host->pm_flags & MMC_PM_KEEP_POWER;
+}
+
#endif
--
1.7.1
@@ -1,41 +0,0 @@
From 6dc280ffc189b8d534e7e9ff758b12f31a8d3234 Mon Sep 17 00:00:00 2001
From: Linus Walleij <linus.walleij@stericsson.com>
Date: Wed, 5 Jan 2011 00:44:32 +0100
Subject: [PATCH 5/6] mmc: fix division by zero in MMC core
The card is not always clocked and the clock frequency zero is perfectly
legal, thus this code in mmc_set_data_timeout() may cause a division by
zero. It will be triggered more often if you're using software clock
gating but can be triggered under other conditions too.
Upstream status: accepted
Reported-by: Pierre Tardy <tardyp@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Reviewed-by: Chris Ball <cjb@laptop.org>
Cc: <stable@kernel.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/mmc/core/core.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 55bc015..6448c6b 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -296,8 +296,9 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
unsigned int timeout_us, limit_us;
timeout_us = data->timeout_ns / 1000;
- timeout_us += data->timeout_clks * 1000 /
- (card->host->ios.clock / 1000);
+ if (card->host->ios.clock)
+ timeout_us += data->timeout_clks * 1000 /
+ (card->host->ios.clock / 1000);
if (data->flags & MMC_DATA_WRITE)
/*
--
1.7.0.4
@@ -1,112 +0,0 @@
From 3d72f4e09138025931b1e0cb2ef921478f7d6d11 Mon Sep 17 00:00:00 2001
From: Ohad Ben-Cohen <ohad@wizery.com>
Date: Sun, 28 Nov 2010 07:21:30 +0200
Subject: [PATCH 3/6] mmc: sdio: don't power up cards on system suspend
Initial SDIO runtime PM implementation took a conservative approach
of powering up cards (and fully reinitializing them) on system suspend,
just before the suspend handlers of the relevant drivers were executed.
To avoid redundant power and reinitialization cycles, this patch removes
this behavior: if a card is already powered off when system suspend kicks
in, it is left at that state.
If a card is active when a system sleep starts, everything is
straightforward and works exactly like before. But if the card was
already suspended before the sleep began, then when the MMC core powers
it back up on resume, its run-time PM status has to be updated to reflect
the actual post-system sleep status.
The technique to do that is borrowed from the I2C runtime PM
implementation (for more info see Documentation/power/runtime_pm.txt).
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Reviewed-by: Chris Ball <cjb@laptop.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
---
drivers/mmc/core/core.c | 13 +++++++++++++
drivers/mmc/core/sdio_bus.c | 32 --------------------------------
2 files changed, 13 insertions(+), 32 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 305e2a5..2762ad2 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -22,6 +22,7 @@
#include <linux/scatterlist.h>
#include <linux/log2.h>
#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -1725,6 +1726,18 @@ int mmc_resume_host(struct mmc_host *host)
if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
mmc_power_up(host);
mmc_select_voltage(host, host->ocr);
+ /*
+ * Tell runtime PM core we just powered up the card,
+ * since it still believes the card is powered off.
+ * Note that currently runtime PM is only enabled
+ * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
+ */
+ if (mmc_card_sdio(host->card) &&
+ (host->caps & MMC_CAP_POWER_OFF_CARD)) {
+ pm_runtime_disable(&host->card->dev);
+ pm_runtime_set_active(&host->card->dev);
+ pm_runtime_enable(&host->card->dev);
+ }
}
BUG_ON(!host->bus_ops->resume);
err = host->bus_ops->resume(host);
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 203da44..d29b9c3 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -197,44 +197,12 @@ out:
#ifdef CONFIG_PM_RUNTIME
-static int sdio_bus_pm_prepare(struct device *dev)
-{
- struct sdio_func *func = dev_to_sdio_func(dev);
-
- /*
- * Resume an SDIO device which was suspended at run time at this
- * point, in order to allow standard SDIO suspend/resume paths
- * to keep working as usual.
- *
- * Ultimately, the SDIO driver itself will decide (in its
- * suspend handler, or lack thereof) whether the card should be
- * removed or kept, and if kept, at what power state.
- *
- * At this point, PM core have increased our use count, so it's
- * safe to directly resume the device. After system is resumed
- * again, PM core will drop back its runtime PM use count, and if
- * needed device will be suspended again.
- *
- * The end result is guaranteed to be a power state that is
- * coherent with the device's runtime PM use count.
- *
- * The return value of pm_runtime_resume is deliberately unchecked
- * since there is little point in failing system suspend if a
- * device can't be resumed.
- */
- if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
- pm_runtime_resume(dev);
-
- return 0;
-}
-
static const struct dev_pm_ops sdio_bus_pm_ops = {
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
pm_generic_runtime_idle
)
- .prepare = sdio_bus_pm_prepare,
};
#define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops)
--
1.7.1
@@ -1,30 +0,0 @@
From ddcdd25ae15a5b6ec1d179ce018c09e0880f36a8 Mon Sep 17 00:00:00 2001
From: Ido Reis <idor@ti.com>
Date: Thu, 7 Jul 2011 00:21:55 +0300
Subject: [PATCH 6/6] revert duplicate insertion of mmc_card_keep_power function in include/linux/mmc/host.h
Upstream status: accepted
---
include/linux/mmc/host.h | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index db2548f..c797318 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -312,11 +312,6 @@ static inline int mmc_card_keep_power(struct mmc_host *host)
return host->pm_flags & MMC_PM_KEEP_POWER;
}
-static inline int mmc_card_keep_power(struct mmc_host *host)
-{
- return host->pm_flags & MMC_PM_KEEP_POWER;
-}
-
static inline int mmc_card_wake_sdio_irq(struct mmc_host *host)
{
return host->pm_flags & MMC_PM_WAKE_SDIO_IRQ;
--
1.7.0.4
@@ -1,64 +0,0 @@
From c3c1429faed56c53d96bf5c98dcaa7140a616ea5 Mon Sep 17 00:00:00 2001
From: Ido Yariv <ido@wizery.com>
Date: Wed, 6 Apr 2011 00:36:41 +0300
Subject: [PATCH 5/6] wl12xx: Backport wl12xx platform data
In order to build a more recent wl12xx driver externally (using
compat-wireless), the builtin platform data structure needs to match the
one used in the driver.
Fix this by backporting wl12xx.h from Luciano's tree.
Signed-off-by: Ido Yariv <ido@wizery.com>
---
include/linux/wl12xx.h | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 4f902e1..4b69739 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -24,14 +24,41 @@
#ifndef _LINUX_WL12XX_H
#define _LINUX_WL12XX_H
+/* Reference clock values */
+enum {
+ WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
+ WL12XX_REFCLOCK_26 = 1, /* 26 MHz */
+ WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */
+ WL12XX_REFCLOCK_52 = 3, /* 52 MHz */
+ WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
+ WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
+};
+
+/* TCXO clock values */
+enum {
+ WL12XX_TCXOCLOCK_19_2 = 0, /* 19.2MHz */
+ WL12XX_TCXOCLOCK_26 = 1, /* 26 MHz */
+ WL12XX_TCXOCLOCK_38_4 = 2, /* 38.4MHz */
+ WL12XX_TCXOCLOCK_52 = 3, /* 52 MHz */
+ WL12XX_TCXOCLOCK_16_368 = 4, /* 16.368 MHz */
+ WL12XX_TCXOCLOCK_32_736 = 5, /* 32.736 MHz */
+ WL12XX_TCXOCLOCK_16_8 = 6, /* 16.8 MHz */
+ WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */
+};
+
struct wl12xx_platform_data {
void (*set_power)(bool enable);
/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
int irq;
bool use_eeprom;
int board_ref_clock;
+ int board_tcxo_clock;
+ unsigned long platform_quirks;
};
+/* Platform does not support level trigger interrupts */
+#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0)
+
#ifdef CONFIG_WL12XX_PLATFORM_DATA
int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
--
1.7.1
@@ -1,26 +0,0 @@
From 6133415cf067d656c40997e00eace06d07aeab34 Mon Sep 17 00:00:00 2001
From: Eyal Reizer <eyalr@ti.com>
Date: Mon, 16 May 2011 17:47:46 +0300
Subject: [PATCH] PSP04.02.00.07.sdk: activate wireless extensions interface used by iwconfig
Signed-off-by: Eyal Reizer <eyalr@ti.com>
---
arch/arm/mach-omap2/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index dfa5464..8152b72 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -34,6 +34,7 @@ config ARCH_OMAP3
select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4
select ARCH_HAS_OPP
select PM_OPP if PM
select WL12XX_PLATFORM_DATA
+ select WIRELESS_EXT
config ARCH_OMAP4
bool "TI OMAP4"
--
1.7.0.4
File diff suppressed because it is too large Load Diff
@@ -1,103 +0,0 @@
require linux.inc
require setup-defconfig.inc
DESCRIPTION = "Linux kernel for OMAP3 EVM from PSP, based on linux-omap3 kernel"
COMPATIBLE_MACHINE = "omap3"
# SRCREV corresponds to tag v2.6.37_OMAPPSP_04.02.00.07
SRCREV= "adcd067326836777c049e3cb32a5b7d9d401fc31"
BRANCH = "OMAPPSP_04.02.00.07"
# The main PR is now using MACHINE_KERNEL_PR, for omap3 devices
# see conf/machine/include/omap3.inc
MACHINE_KERNEL_PR_append = "b"
PR = "${MACHINE_KERNEL_PR}"
SRC_URI = "git://arago-project.org/git/projects/linux-omap3.git;protocol=git;branch=${BRANCH} \
file://defconfig"
# The following patches below have been upstreamed to linux kernel 2.6.39 tree
# and will not be needed once we move to this kernel.
# The only exception is "0002-allow-selecting-WL12XX_PLATFROM_DATA-independently.patch"
# which is needed for building against a compat-wireless package
SRC_URI += " \
file://0001-linux-omap3-Add-OCF-support-to-2.6.37-kernel.patch \
file://0001-omap3evm-add-support-for-the-WL12xx-WLAN-module.patch \
file://0002-allow-selecting-WL12XX_PLATFROM_DATA-independently.patch \
file://0003-mmc-skip-detection-of-nonremovable-cards-on-rescan.patch \
file://0004-mmc-sdio-don-t-reinitialize-nonremovable-powered-res.patch \
file://0005-mmc-sdio-don-t-power-up-cards-on-system-suspend.patch \
file://0006-wl12xx-Backport-wl12xx-platform-data.patch \
file://0007-activate-wireless-extensions.patch \
"
# Update the kernel to support suspend/resume when the file system is located
# on the SD card. This is also being submitted to the PSP team for inclusion
# in future releases.
SRC_URI += " \
file://0001-Fix-matrix-suspend.patch \
"
# Update the OCF kernel patch to remove non-existing components for
# non-TI hardware. This allows the make clean target to work.
# Update the defconfig for omap3 to enable OCF and WLAN by default
SRC_URI += " \
file://0001-OCF-support-remove-support-for-non-TI-hardware.patch \
file://0002-omap3_evm_defconfig-add-OCF-driver-support.patch \
file://0003-omap3_evm_defconfig-add-WLAN-config-options.patch \
"
# Enable clock pad register in mt9t111 sensor driver. This fixes the issue where
# sensor sync pulses were not generated during first loopback after boot-up.
SRC_URI += " \
file://0001-mt9t111-enable-clock-pad-register-in-configuration.patch \
"
# The following patches add support for wake on wlan (WoWlan)
# which is supported in nlcp R4 release
SRC_URI += "file://0001-omap3evm-add-wake-on-wlan-support.patch \
file://0001-nlcp-sdio-fixes-for-wowlan-support.patch \
file://0002-mmc-sdio-support-suspend-resume-while-runtime-suspen.patch \
file://0003-mmc_card_keep_power-cleanups.patch \
file://0004-mmc-do-not-switch-to-1-bit-mode-if-not-required.patch \
file://0005-mmc-fix-division-by-zero-in-MMC-core.patch \
file://0006-revert-duplicate-insertion-of-mmc_card_keep_power-fu.patch \
"
# The following patches allow for NOR to be enabled and built
# easily.
SRC_URI += " \
file://0001-omap3-am3517evm-Allow-for-NAND-to-really-be-disabled.patch \
file://0002-omap3-am3517evm-Update-NOR-partition-table.patch \
file://0003-AM3517-Add-am3517_evn_nor_defconfig.patch \
"
# The following patch sets the dto timeout for SD cards to the max of 14.
# This has been found to make SD cards work more reliably in the omap3 systems
SRC_URI += " \
file://0001-omap_hsmmc-make-default-dto-value-14.patch \
"
# Add ABB support to the Linux kernel to enable 1GHz OPP and to allow
# booting at 1GHz
SRC_URI += " \
file://0001-am37x-Adding-ABB-Support-for-1GHz-OPP.patch \
"
# Fix USB role switching when leaving USB cable connected
SRC_URI += " \
file://0001-usb-musb-am35x-set-default-VBUS-timeout-value.patch \
file://0002-usb-musb-am35x-fix-role-switching-issue.patch \
"
# Fix alignment issue with gcc-4.7
SRC_URI += " \
file://0001-arm-fix-builds-with-gcc-4.7.patch \
"
# Updated PIO mode for MUSB help description
SRC_URI_append_am3517-evm = " file://0001-musb-update-PIO-mode-help-information-in-Kconfig.patch"
S = "${WORKDIR}/git"
@@ -1,29 +0,0 @@
From 3b1dc08ab568d1fdbc2a3731d7643cfeb48023e8 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Thu, 10 Mar 2011 14:16:08 +0100
Subject: [PATCH] BeagleBoard: Adjust USER button pin for xM
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
---
arch/arm/mach-omap2/board-omap3beagle.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 731f4b5..fae3104 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -949,6 +949,11 @@ static void __init omap3_beagle_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3_beagle_init_rev();
omap3_beagle_i2c_init();
+
+ if (cpu_is_omap3630()) {
+ gpio_buttons[0].gpio = 4;
+ }
+
platform_add_devices(omap3_beagle_devices,
ARRAY_SIZE(omap3_beagle_devices));
omap_serial_init();
--
1.7.0
@@ -1,94 +0,0 @@
From d9c289c5f98bb109aa7a9e5a802638ba89639e70 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Thu, 10 Mar 2011 13:15:38 +0100
Subject: [PATCH] beagleboard: hack in support from xM rev C
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
---
arch/arm/mach-omap2/board-omap3beagle.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 6abb79a..731f4b5 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -64,6 +64,7 @@
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
* XMA = GPIO173, GPIO172, GPIO171: 0 0 0
* XMB = GPIO173, GPIO172, GPIO171: 0 0 1
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
*/
enum {
OMAP3BEAGLE_BOARD_UNKN = 0,
@@ -71,6 +72,7 @@ enum {
OMAP3BEAGLE_BOARD_C1_3,
OMAP3BEAGLE_BOARD_C4,
OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
};
static u8 omap3_beagle_version;
@@ -129,9 +131,13 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM B\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ case 2:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
default:
- printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd, assuming xM C or newer\n", beagle_rev);
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}
return;
@@ -484,7 +490,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r;
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
@@ -517,7 +523,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
*/
- if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM && omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "EHCI_nOC");
if (!r) {
r = gpio_direction_input(gpio + 1);
@@ -539,7 +545,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
/* DVI reset GPIO is different between beagle revisions */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC)
beagle_dvi_device.reset_gpio = 129;
else
beagle_dvi_device.reset_gpio = 170;
@@ -553,7 +559,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "nDVI_PWR_EN");
if (!r) {
r = gpio_direction_output(gpio + 1, 0);
@@ -899,7 +905,7 @@ static void __init beagle_opp_init(void)
}
/* Custom OPP enabled for XM */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
struct omap_hwmod *dh = omap_hwmod_lookup("iva");
struct device *dev;
--
1.6.6.1
@@ -1,91 +0,0 @@
From e5e52482147151aaaafbd388d1e5978268e51d24 Mon Sep 17 00:00:00 2001
Message-Id: <e5e52482147151aaaafbd388d1e5978268e51d24.1307392642.git.dvhart@linux.intel.com>
From: Darren Hart <dvhart@linux.intel.com>
Date: Mon, 6 Jun 2011 10:17:56 -0700
Subject: [PATCH 1/2] board-omap3beagle: whitespace cleanup
Eliminate leading and trailing whitespace.
Indent with tabs.
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
arch/arm/mach-omap2/board-omap3beagle.c | 28 ++++++++++++++--------------
1 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index b035bb5..b618cb6 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -167,12 +167,12 @@ struct wl12xx_platform_data omap_beagle_wlan_data __initdata = {
.board_ref_clock = 2, /* 38.4 MHz */
};
- static struct omap2_hsmmc_info mmcbbt[] = {
- {
- .mmc = 1,
- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
- .gpio_wp = 29,
- },
+static struct omap2_hsmmc_info mmcbbt[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 29,
+ },
{
.name = "wl1271",
.mmc = 2,
@@ -181,8 +181,8 @@ struct wl12xx_platform_data omap_beagle_wlan_data __initdata = {
.gpio_cd = -EINVAL,
.nonremovable = true,
},
- {} /* Terminator */
- };
+ {} /* Terminator */
+};
static struct regulator_consumer_supply beagle_vmmc2_supply = {
.supply = "vmmc",
@@ -455,7 +455,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
mmc[0].gpio_cd = gpio + 0;
#if defined(CONFIG_WL1271) || defined(CONFIG_WL1271_MODULE)
- if(!strcmp(expansionboard_name, "bbtoys-wifi")) {
+ if(!strcmp(expansionboard_name, "bbtoys-wifi")) {
omap2_hsmmc_init(mmcbbt);
/* link regulators to MMC adapters */
beagle_vmmc1_supply.dev = mmcbbt[0].dev;
@@ -648,9 +648,9 @@ static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = {
};
static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
- {
- I2C_BOARD_INFO("eeprom", 0x50),
- },
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
};
#if defined(CONFIG_RTC_DRV_DS1307) || \
@@ -888,7 +888,7 @@ static void __init omap3_beagle_init(void)
/* REVISIT leave DVI powered down until it's needed ... */
gpio_direction_output(170, true);
- if(!strcmp(expansionboard_name, "zippy"))
+ if(!strcmp(expansionboard_name, "zippy"))
{
printk(KERN_INFO "Beagle expansionboard: initializing enc28j60\n");
omap3beagle_enc28j60_init();
@@ -897,7 +897,7 @@ static void __init omap3_beagle_init(void)
mmc[1].gpio_cd = 162;
}
- if(!strcmp(expansionboard_name, "zippy2"))
+ if(!strcmp(expansionboard_name, "zippy2"))
{
printk(KERN_INFO "Beagle expansionboard: initializing ks_8851\n");
omap3beagle_ks8851_init();
--
1.7.1
@@ -1,26 +0,0 @@
From 095749d8941257799eaf5b2509918373f1a08152 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Thu, 10 Mar 2011 14:03:08 +0100
Subject: [PATCH] omap3: allow 1GHz mpurates
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
---
arch/arm/plat-omap/clock.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index fc62fb5..f3e3d29 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -181,7 +181,7 @@ static int __init omap_clk_setup(char *str)
if (!mpurate)
return 1;
- if (mpurate < 1000)
+ if (mpurate < 2000)
mpurate *= 1000000;
return 1;
--
1.6.6.1
@@ -1,27 +0,0 @@
From d53f988fc10fe22ec7e64457eac22f264bb72491 Mon Sep 17 00:00:00 2001
From: Robert Nelson <robertcnelson@gmail.com>
Date: Thu, 13 Jan 2011 11:37:56 -0600
Subject: [PATCH] xM audio fix from Ashok
Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
---
sound/soc/omap/omap-mcbsp.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 7e84f24..1038686 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -332,6 +332,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
} else if (cpu_is_omap343x()) {
dma = omap24xx_dma_reqs[bus_id][substream->stream];
port = omap34xx_mcbsp_port[bus_id][substream->stream];
+ } else if (cpu_is_omap3630()) {
+ dma = omap24xx_dma_reqs[bus_id][substream->stream];
+ port = omap34xx_mcbsp_port[bus_id][substream->stream];
} else {
return -ENODEV;
}
--
1.7.1
@@ -1,42 +0,0 @@
From 1b9bc1583d882866d64420df39bf5df4bce22bd6 Mon Sep 17 00:00:00 2001
Message-Id: <1b9bc1583d882866d64420df39bf5df4bce22bd6.1307392642.git.dvhart@linux.intel.com>
In-Reply-To: <e5e52482147151aaaafbd388d1e5978268e51d24.1307392642.git.dvhart@linux.intel.com>
References: <e5e52482147151aaaafbd388d1e5978268e51d24.1307392642.git.dvhart@linux.intel.com>
From: Darren Hart <dvhart@linux.intel.com>
Date: Mon, 6 Jun 2011 10:19:00 -0700
Subject: [PATCH 2/2] board-omap3beagle: allow for building without wl1271
While the header file wl12xx.h is ifdef'd to include if the wl1271 driver is
built, the init routine calls into it regardless. Ideally, the module would
perform its own initialization at load time and we wouldn't need to ifdef these
calls in the general board initialization. For now, follow the existing practice
in this file and ifdef the wl1271 init block.
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
arch/arm/mach-omap2/board-omap3beagle.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index b618cb6..caaed82 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -937,6 +937,7 @@ static void __init omap3_beagle_init(void)
gpio_export(162, 1);
}
+#if defined(CONFIG_WL1271) || defined(CONFIG_WL1271_MODULE)
if(!strcmp(expansionboard_name, "bbtoys-wifi"))
{
if (wl12xx_set_platform_data(&omap_beagle_wlan_data))
@@ -944,6 +945,7 @@ static void __init omap3_beagle_init(void)
printk(KERN_INFO "Beagle expansionboard: registering wl12xx platform device\n");
platform_device_register(&omap_vwlan_device);
}
+#endif
usb_musb_init(&musb_board_data);
usb_ehci_init(&ehci_pdata);
--
1.7.1
@@ -1,44 +0,0 @@
From 3d2f0e2f29320d9c6a6e4d8d5aeff9127a2106cb Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@beagleboard.org>
Date: Tue, 11 Jan 2011 17:13:35 +0000
Subject: [PATCH 01/28] omap3: beaglexm: fix EHCI power up GPIO dir
EHCI enable power pin is inverted (active high) in comparison
to vanilla beagle which is active low. Handle this case conditionally.
Without this fix, Beagle XM 4 port EHCI will not function and no
networking will be available
[nm@ti.com: split up, added descriptive changelogs]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Koen Kooi <koen@beagleboard.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/board-omap3beagle.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 6c12760..af1166b 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -297,9 +297,15 @@ static int beagle_twl_gpio_setup(struct device *dev,
gpio_request(gpio + 1, "EHCI_nOC");
gpio_direction_input(gpio + 1);
- /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
+ /*
+ * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
+ * high / others active low)
+ */
gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
+ else
+ gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
--
1.6.6.1
@@ -1,48 +0,0 @@
From e1dd1afba99853083da545f632a1f7c6899ae379 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@beagleboard.org>
Date: Tue, 11 Jan 2011 17:13:36 +0000
Subject: [PATCH 02/28] omap3: beaglexm: fix DVI reset GPIO
GPIO reset line for Beagle XM is different from vanilla beagle
so we populate it as part of gpio update routine.
This in part fixes the issue of display not functioning on beagle XM
platform.
[nm@ti.com: split up, added descriptive changelogs]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Koen Kooi <koen@beagleboard.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/board-omap3beagle.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index af1166b..673deb9 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -199,7 +199,7 @@ static struct omap_dss_device beagle_dvi_device = {
.name = "dvi",
.driver_name = "generic_panel",
.phy.dpi.data_lines = 24,
- .reset_gpio = 170,
+ .reset_gpio = -EINVAL,
.platform_enable = beagle_enable_dvi,
.platform_disable = beagle_disable_dvi,
};
@@ -307,6 +307,12 @@ static int beagle_twl_gpio_setup(struct device *dev,
else
gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
+ /* DVI reset GPIO is different between beagle revisions */
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ beagle_dvi_device.reset_gpio = 129;
+ else
+ beagle_dvi_device.reset_gpio = 170;
+
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
--
1.6.6.1
@@ -1,94 +0,0 @@
From 4004c3e68b973f4cb736048b1e90ee3b511f5865 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@beagleboard.org>
Date: Wed, 12 Jan 2011 00:23:29 +0000
Subject: [PATCH 03/28] omap3: beaglexm: fix power on of DVI
TFP410 DVI chip is used to provide display out.
This chip is controlled by 2 lines:
LDO which supplies the power is controlled over gpio + 2
and the enable of the chip itself is done over gpio + 1
NOTE: the LDO is necessary for LED, serial blocks as well.
gpio + 1 was used to sense USB overcurrent in vanilla beagle.
Without this fix, the display would not function as the LDO
remains shut down.
[nm@ti.com: split up, added descriptive changelogs]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Koen Kooi <koen@beagleboard.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/board-omap3beagle.c | 42 ++++++++++++++++++++++++++++--
1 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 673deb9..2ed8040 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -273,6 +273,8 @@ static struct gpio_led gpio_leds[];
static int beagle_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
+ int r;
+
if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
@@ -293,9 +295,16 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
*/
-
- gpio_request(gpio + 1, "EHCI_nOC");
- gpio_direction_input(gpio + 1);
+ if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) {
+ r = gpio_request(gpio + 1, "EHCI_nOC");
+ if (!r) {
+ r = gpio_direction_input(gpio + 1);
+ if (r)
+ gpio_free(gpio + 1);
+ }
+ if (r)
+ pr_err("%s: unable to configure EHCI_nOC\n", __func__);
+ }
/*
* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
@@ -316,6 +325,33 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+ /*
+ * gpio + 1 on Xm controls the TFP410's enable line (active low)
+ * gpio + 2 control varies depending on the board rev as follows:
+ * P7/P8 revisions(prototype): Camera EN
+ * A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
+ */
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ r = gpio_request(gpio + 1, "nDVI_PWR_EN");
+ if (!r) {
+ r = gpio_direction_output(gpio + 1, 0);
+ if (r)
+ gpio_free(gpio + 1);
+ }
+ if (r)
+ pr_err("%s: unable to configure nDVI_PWR_EN\n",
+ __func__);
+ r = gpio_request(gpio + 2, "DVI_LDO_EN");
+ if (!r) {
+ r = gpio_direction_output(gpio + 2, 1);
+ if (r)
+ gpio_free(gpio + 2);
+ }
+ if (r)
+ pr_err("%s: unable to configure DVI_LDO_EN\n",
+ __func__);
+ }
+
return 0;
}
--
1.6.6.1
@@ -1,43 +0,0 @@
From 24b7a742b27ed2c05c6bc7800b0299a77af37a82 Mon Sep 17 00:00:00 2001
From: Robert Nelson <robertcnelson@gmail.com>
Date: Tue, 9 Nov 2010 08:34:55 -0600
Subject: [PATCH 04/28] omap: Beagle: detect new xM revision B
The xM B uses a DM3730 ES1.1 over the ES1.0 on xM A's, no other board changes.
Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
Signed-off-by: Koen Kooi <koen@beagleboard.org>
---
arch/arm/mach-omap2/board-omap3beagle.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 2ed8040..f9fb64b 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -58,7 +58,8 @@
* AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
* C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1
*/
enum {
OMAP3BEAGLE_BOARD_UNKN = 0,
@@ -117,7 +118,11 @@ static void __init omap3_beagle_init_rev(void)
omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
break;
case 0:
- printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM A\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ break;
+ case 1:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM B\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
default:
--
1.6.6.1
@@ -1,219 +0,0 @@
From a564ca287c115928a9e7febf7c99bbab582290e6 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Wed, 6 Oct 2010 10:19:34 +0200
Subject: [PATCH 05/28] ARM: OMAP: beagleboard: Add infrastructure to do fixups based on expansionboard name passed by u-boot
Add support for Tincantools Zippy and Zippy2 expansionboards as well
Signed-off-by: Koen Kooi <koen@beagleboard.org>
---
arch/arm/mach-omap2/board-omap3beagle.c | 142 ++++++++++++++++++++++++++++++-
1 files changed, 139 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index f9fb64b..d777b3b 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/gpio.h>
+#include <linux/irq.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
@@ -143,6 +144,92 @@ fail0:
return;
}
+char expansionboard_name[16];
+
+#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE)
+
+#include <plat/mcspi.h>
+#include <linux/spi/spi.h>
+
+#define OMAP3BEAGLE_GPIO_ENC28J60_IRQ 157
+
+static struct omap2_mcspi_device_config enc28j60_spi_chip_info = {
+ .turbo_mode = 0,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct spi_board_info omap3beagle_zippy_spi_board_info[] __initdata = {
+ {
+ .modalias = "enc28j60",
+ .bus_num = 4,
+ .chip_select = 0,
+ .max_speed_hz = 20000000,
+ .controller_data = &enc28j60_spi_chip_info,
+ },
+};
+
+static void __init omap3beagle_enc28j60_init(void)
+{
+ if ((gpio_request(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, "ENC28J60_IRQ") == 0) &&
+ (gpio_direction_input(OMAP3BEAGLE_GPIO_ENC28J60_IRQ) == 0)) {
+ gpio_export(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, 0);
+ omap3beagle_zippy_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_ENC28J60_IRQ);
+ set_irq_type(omap3beagle_zippy_spi_board_info[0].irq, IRQ_TYPE_EDGE_FALLING);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for ENC28J60_IRQ\n");
+ return;
+ }
+
+ spi_register_board_info(omap3beagle_zippy_spi_board_info,
+ ARRAY_SIZE(omap3beagle_zippy_spi_board_info));
+}
+
+#else
+static inline void __init omap3beagle_enc28j60_init(void) { return; }
+#endif
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+
+#include <plat/mcspi.h>
+#include <linux/spi/spi.h>
+
+#define OMAP3BEAGLE_GPIO_KS8851_IRQ 157
+
+static struct omap2_mcspi_device_config ks8851_spi_chip_info = {
+ .turbo_mode = 0,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct spi_board_info omap3beagle_zippy2_spi_board_info[] __initdata = {
+ {
+ .modalias = "ks8851",
+ .bus_num = 4,
+ .chip_select = 0,
+ .max_speed_hz = 36000000,
+ .controller_data = &ks8851_spi_chip_info,
+ },
+};
+
+static void __init omap3beagle_ks8851_init(void)
+{
+ if ((gpio_request(OMAP3BEAGLE_GPIO_KS8851_IRQ, "KS8851_IRQ") == 0) &&
+ (gpio_direction_input(OMAP3BEAGLE_GPIO_KS8851_IRQ) == 0)) {
+ gpio_export(OMAP3BEAGLE_GPIO_KS8851_IRQ, 0);
+ omap3beagle_zippy2_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_KS8851_IRQ);
+ set_irq_type(omap3beagle_zippy2_spi_board_info[0].irq, IRQ_TYPE_EDGE_FALLING);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for KS8851_IRQ\n");
+ return;
+ }
+
+ spi_register_board_info(omap3beagle_zippy2_spi_board_info,
+ ARRAY_SIZE(omap3beagle_zippy2_spi_board_info));
+}
+
+#else
+static inline void __init omap3beagle_ks8851_init(void) { return; }
+#endif
+
static struct mtd_partition omap3beagle_nand_partitions[] = {
/* All the partition sizes are listed in terms of NAND block size */
{
@@ -262,6 +349,12 @@ static struct omap2_hsmmc_info mmc[] = {
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = 29,
},
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .transceiver = true,
+ .ocr_mask = 0x00100000, /* 3.3V */
+ },
{} /* Terminator */
};
@@ -457,7 +550,7 @@ static struct twl4030_platform_data beagle_twldata = {
.vpll2 = &beagle_vpll2,
};
-static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
+static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = {
{
I2C_BOARD_INFO("twl4030", 0x48),
.flags = I2C_CLIENT_WAKE,
@@ -472,10 +565,24 @@ static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
},
};
+#if defined(CONFIG_RTC_DRV_DS1307) || \
+ defined(CONFIG_RTC_DRV_DS1307_MODULE)
+
+static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("ds1307", 0x68),
+ },
+};
+#else
+static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {};
+#endif
+
static int __init omap3_beagle_i2c_init(void)
{
- omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
- ARRAY_SIZE(beagle_i2c_boardinfo));
+ omap_register_i2c_bus(1, 2600, beagle_i2c1_boardinfo,
+ ARRAY_SIZE(beagle_i2c1_boardinfo));
+ omap_register_i2c_bus(2, 400, beagle_i2c2_boardinfo,
+ ARRAY_SIZE(beagle_i2c2_boardinfo));
/* Bus 3 is attached to the DVI port where devices like the pico DLP
* projector don't work reliably with 400kHz */
omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
@@ -609,6 +716,15 @@ static struct omap_musb_board_data musb_board_data = {
.power = 100,
};
+static int __init expansionboard_setup(char *str)
+{
+ if (!str)
+ return -EINVAL;
+ strncpy(expansionboard_name, str, 16);
+ printk(KERN_INFO "Beagle expansionboard: %s\n", expansionboard_name);
+ return 0;
+}
+
static void __init omap3_beagle_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -623,6 +739,24 @@ static void __init omap3_beagle_init(void)
/* REVISIT leave DVI powered down until it's needed ... */
gpio_direction_output(170, true);
+ if(!strcmp(expansionboard_name, "zippy"))
+ {
+ printk(KERN_INFO "Beagle expansionboard: initializing enc28j60\n");
+ omap3beagle_enc28j60_init();
+ printk(KERN_INFO "Beagle expansionboard: assigning GPIO 141 and 162 to MMC1\n");
+ mmc[1].gpio_wp = 141;
+ mmc[1].gpio_cd = 162;
+ }
+
+ if(!strcmp(expansionboard_name, "zippy2"))
+ {
+ printk(KERN_INFO "Beagle expansionboard: initializing ks_8851\n");
+ omap3beagle_ks8851_init();
+ printk(KERN_INFO "Beagle expansionboard: assigning GPIO 141 and 162 to MMC1\n");
+ mmc[1].gpio_wp = 141;
+ mmc[1].gpio_cd = 162;
+ }
+
usb_musb_init(&musb_board_data);
usb_ehci_init(&ehci_pdata);
omap3beagle_flash_init();
@@ -634,6 +768,8 @@ static void __init omap3_beagle_init(void)
beagle_display_init();
}
+early_param("buddy", expansionboard_setup);
+
MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
/* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
.boot_params = 0x80000100,
--
1.6.6.1
@@ -1,57 +0,0 @@
From 0c2c9a4d7fd299444b66e08aa34acc868261003f Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Sun, 5 Dec 2010 13:25:00 +0100
Subject: [PATCH 06/28] ARM: OMAP: beagleboard: pre-export GPIOs to userspace when using a Tincantools trainerboard
This really needs a for loop, patches welcome
Signed-off-by: Koen Kooi <koen@beagleboard.org>
---
arch/arm/mach-omap2/board-omap3beagle.c | 31 +++++++++++++++++++++++++++++++
1 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index d777b3b..64a181e 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -757,6 +757,37 @@ static void __init omap3_beagle_init(void)
mmc[1].gpio_cd = 162;
}
+ if(!strcmp(expansionboard_name, "trainer"))
+ {
+ printk(KERN_INFO "Beagle expansionboard: exporting GPIOs 130-141,162 to userspace\n");
+ gpio_request(130, "sysfs");
+ gpio_export(130, 1);
+ gpio_request(131, "sysfs");
+ gpio_export(131, 1);
+ gpio_request(132, "sysfs");
+ gpio_export(132, 1);
+ gpio_request(133, "sysfs");
+ gpio_export(133, 1);
+ gpio_request(134, "sysfs");
+ gpio_export(134, 1);
+ gpio_request(135, "sysfs");
+ gpio_export(135, 1);
+ gpio_request(136, "sysfs");
+ gpio_export(136, 1);
+ gpio_request(137, "sysfs");
+ gpio_export(137, 1);
+ gpio_request(138, "sysfs");
+ gpio_export(138, 1);
+ gpio_request(139, "sysfs");
+ gpio_export(139, 1);
+ gpio_request(140, "sysfs");
+ gpio_export(140, 1);
+ gpio_request(141, "sysfs");
+ gpio_export(141, 1);
+ gpio_request(162, "sysfs");
+ gpio_export(162, 1);
+ }
+
usb_musb_init(&musb_board_data);
usb_ehci_init(&ehci_pdata);
omap3beagle_flash_init();
--
1.6.6.1
@@ -1,28 +0,0 @@
From ed12d865de851c5aed3ae7685337551b831bb045 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Mon, 8 Mar 2010 14:38:31 +0100
Subject: [PATCH 07/28] modedb.c: add proper 720p60 mode
Signed-off-by: Koen Kooi <koen@beagleboard.org>
---
drivers/video/modedb.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index de450c1..1cd8153 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -46,6 +46,10 @@ static const struct fb_videomode modedb[] = {
NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
0, FB_VMODE_NONINTERLACED
}, {
+ /* 1280x720 @ 60 Hz, 45 kHz hsync, CEA 681-E Format 4 */
+ "hd720", 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
/* 800x600 @ 56 Hz, 35.15 kHz hsync */
NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
0, FB_VMODE_NONINTERLACED
--
1.6.6.1
@@ -1,28 +0,0 @@
From 13235700be3729d183143bdb75ee58742372d6aa Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Mon, 4 Jan 2010 19:20:25 -0800
Subject: [PATCH 08/28] mmc: don't display single block read console messages
mmc: don't display single block read console messages
---
drivers/mmc/card/block.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 217f820..b0b68cc 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -434,8 +434,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
if (brq.cmd.error || brq.data.error || brq.stop.error) {
if (brq.data.blocks > 1 && rq_data_dir(req) == READ) {
/* Redo read one sector at a time */
- printk(KERN_WARNING "%s: retrying using single "
- "block read\n", req->rq_disk->disk_name);
+ /* printk(KERN_WARNING "%s: retrying using single "
+ "block read\n", req->rq_disk->disk_name); */
disable_multi = 1;
continue;
}
--
1.6.6.1
@@ -1,63 +0,0 @@
From 8b0c56b910811acd23c15bed273b3dbd959ef96a Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Mon, 26 Apr 2010 11:17:26 -0700
Subject: [PATCH 09/28] MTD: silence ecc errors on mtdblock0
mtdblock0 is the x-load partition, which uses hw ecc
this confuses linux, which uses sw ecc
this patch silences ecc error messages when linux peeks into mtdblock0
* not for upstream submission *
---
block/blk-core.c | 7 ++++---
drivers/mtd/nand/nand_ecc.c | 2 +-
fs/buffer.c | 3 ++-
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/block/blk-core.c b/block/blk-core.c
index 4ce953f..1ef9a01 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2028,9 +2028,10 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
if (error && req->cmd_type == REQ_TYPE_FS &&
!(req->cmd_flags & REQ_QUIET)) {
- printk(KERN_ERR "end_request: I/O error, dev %s, sector %llu\n",
- req->rq_disk ? req->rq_disk->disk_name : "?",
- (unsigned long long)blk_rq_pos(req));
+ if (req->rq_disk && (strcmp(req->rq_disk->disk_name, "mtdblock0") != 0))
+ printk(KERN_ERR "end_request: I/O error, dev %s, sector %llu\n",
+ req->rq_disk ? req->rq_disk->disk_name : "?",
+ (unsigned long long)blk_rq_pos(req));
}
blk_account_io_completion(req, nr_bytes);
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 271b8e7..5924ba7 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -507,7 +507,7 @@ int __nand_correct_data(unsigned char *buf,
if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
return 1; /* error in ecc data; no action needed */
- printk(KERN_ERR "uncorrectable error : ");
+// printk(KERN_ERR "uncorrectable error : ");
return -1;
}
EXPORT_SYMBOL(__nand_correct_data);
diff --git a/fs/buffer.c b/fs/buffer.c
index 5930e38..06a00d5 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -114,7 +114,8 @@ static int quiet_error(struct buffer_head *bh)
static void buffer_io_error(struct buffer_head *bh)
{
char b[BDEVNAME_SIZE];
- printk(KERN_ERR "Buffer I/O error on device %s, logical block %Lu\n",
+ if (strcmp(bdevname(bh->b_bdev, b), "mtdblock0") != 0)
+ printk(KERN_ERR "Buffer I/O error on device %s, logical block %Lu\n",
bdevname(bh->b_bdev, b),
(unsigned long long)bh->b_blocknr);
}
--
1.6.6.1
@@ -1,504 +0,0 @@
From ce4f1f734efd638af01f1849ffffdc2746ad4a55 Mon Sep 17 00:00:00 2001
From: Mike Galbraith <efault@gmx.de>
Date: Fri, 19 Nov 2010 12:52:42 +0100
Subject: [PATCH 10/28] Miracle patch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On Sun, 2010-11-14 at 16:26 -0800, Linus Torvalds wrote:
> On Sun, Nov 14, 2010 at 4:15 PM, Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
> >
> > THAT is why I think it's so silly to try to be so strict and walk over
> > all processes while holding a couple of spinlocks.
>
> Btw, let me say that I think the patch is great even with that thing
> in. It looks clean, the thing I'm complaining about is not a big deal,
> and it seems to perform very much as advertized. The difference with
> autogroup scheduling is very noticeable with a simple "make -j64"
> kernel compile.
>
> So I really don't think it's a big deal. The sysctl handler isn't even
> complicated. But boy does it hurt my eyes to see a spinlock held
> around a "do_each_thread()". And I do get the feeling that the
> simplest way to fix it would be to just remove the code entirely, and
> just say that "enabling/disabling may be delayed for old processes
> with existing autogroups".
Which is what I just did. If the oddball case isn't a big deal, the
patch shrinks, which is a good thing. I just wanted to cover all bases.
Patchlet with handler whacked:
A recurring complaint from CFS users is that parallel kbuild has a negative
impact on desktop interactivity. This patch implements an idea from Linus,
to automatically create task groups. This patch only implements Linus' per
tty task group suggestion, and only for fair class tasks, but leaves the way
open for enhancement.
Implementation: each task's signal struct contains an inherited pointer to a
refcounted autogroup struct containing a task group pointer, the default for
all tasks pointing to the init_task_group. When a task calls __proc_set_tty(),
the process wide reference to the default group is dropped, a new task group is
created, and the process is moved into the new task group. Children thereafter
inherit this task group, and increase it's refcount. On exit, a reference to the
current task group is dropped when the last reference to each signal struct is
dropped. The task group is destroyed when the last signal struct referencing
it is freed. At runqueue selection time, IFF a task has no cgroup assignment,
it's current autogroup is used.
The feature is enabled from boot by default if CONFIG_SCHED_AUTOGROUP is
selected, but can be disabled via the boot option noautogroup, and can be
also be turned on/off on the fly via..
echo [01] > /proc/sys/kernel/sched_autogroup_enabled.
..which will automatically move tasks to/from the root task group.
Some numbers.
A 100% hog overhead measurement proggy pinned to the same CPU as a make -j10
About measurement proggy:
pert/sec = perturbations/sec
min/max/avg = scheduler service latencies in usecs
sum/s = time accrued by the competition per sample period (1 sec here)
overhead = %CPU received by the competition per sample period
pert/s: 31 >40475.37us: 3 min: 0.37 max:48103.60 avg:29573.74 sum/s:916786us overhead:90.24%
pert/s: 23 >41237.70us: 12 min: 0.36 max:56010.39 avg:40187.01 sum/s:924301us overhead:91.99%
pert/s: 24 >42150.22us: 12 min: 8.86 max:61265.91 avg:39459.91 sum/s:947038us overhead:92.20%
pert/s: 26 >42344.91us: 11 min: 3.83 max:52029.60 avg:36164.70 sum/s:940282us overhead:91.12%
pert/s: 24 >44262.90us: 14 min: 5.05 max:82735.15 avg:40314.33 sum/s:967544us overhead:92.22%
Same load with this patch applied.
pert/s: 229 >5484.43us: 41 min: 0.15 max:12069.42 avg:2193.81 sum/s:502382us overhead:50.24%
pert/s: 222 >5652.28us: 43 min: 0.46 max:12077.31 avg:2248.56 sum/s:499181us overhead:49.92%
pert/s: 211 >5809.38us: 43 min: 0.16 max:12064.78 avg:2381.70 sum/s:502538us overhead:50.25%
pert/s: 223 >6147.92us: 43 min: 0.15 max:16107.46 avg:2282.17 sum/s:508925us overhead:50.49%
pert/s: 218 >6252.64us: 43 min: 0.16 max:12066.13 avg:2324.11 sum/s:506656us overhead:50.27%
Average service latency is an order of magnitude better with autogroup.
(Imagine that pert were Xorg or whatnot instead)
Using Mathieu Desnoyers' wakeup-latency testcase:
With taskset -c 3 make -j 10 running..
taskset -c 3 ./wakeup-latency& sleep 30;killall wakeup-latency
without:
maximum latency: 42963.2 µs
average latency: 9077.0 µs
missed timer events: 0
with:
maximum latency: 4160.7 µs
average latency: 149.4 µs
missed timer events: 0
Signed-off-by: Mike Galbraith <efault@gmx.de>
---
Documentation/kernel-parameters.txt | 2 +
drivers/tty/tty_io.c | 1 +
include/linux/sched.h | 19 +++++
init/Kconfig | 12 +++
kernel/fork.c | 5 +-
kernel/sched.c | 25 ++++--
kernel/sched_autogroup.c | 140 +++++++++++++++++++++++++++++++++++
kernel/sched_autogroup.h | 18 +++++
kernel/sysctl.c | 11 +++
9 files changed, 224 insertions(+), 9 deletions(-)
create mode 100644 kernel/sched_autogroup.c
create mode 100644 kernel/sched_autogroup.h
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 01ece1b..1031923 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1622,6 +1622,8 @@ and is between 256 and 4096 characters. It is defined in the file
noapic [SMP,APIC] Tells the kernel to not make use of any
IOAPICs that may be present in the system.
+ noautogroup Disable scheduler automatic task group creation.
+
nobats [PPC] Do not use BATs for mapping kernel lowmem
on "Classic" PPC cores.
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 35480dd..1849f4a 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3169,6 +3169,7 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
put_pid(tsk->signal->tty_old_pgrp);
tsk->signal->tty = tty_kref_get(tty);
tsk->signal->tty_old_pgrp = NULL;
+ sched_autogroup_create_attach(tsk);
}
static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2238745..3a775e3 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -509,6 +509,8 @@ struct thread_group_cputimer {
spinlock_t lock;
};
+struct autogroup;
+
/*
* NOTE! "signal_struct" does not have it's own
* locking, because a shared signal_struct always
@@ -576,6 +578,9 @@ struct signal_struct {
struct tty_struct *tty; /* NULL if no tty */
+#ifdef CONFIG_SCHED_AUTOGROUP
+ struct autogroup *autogroup;
+#endif
/*
* Cumulative resource counters for dead threads in the group,
* and for reaped dead child processes forked by this group.
@@ -1931,6 +1936,20 @@ int sched_rt_handler(struct ctl_table *table, int write,
extern unsigned int sysctl_sched_compat_yield;
+#ifdef CONFIG_SCHED_AUTOGROUP
+extern unsigned int sysctl_sched_autogroup_enabled;
+
+extern void sched_autogroup_create_attach(struct task_struct *p);
+extern void sched_autogroup_detach(struct task_struct *p);
+extern void sched_autogroup_fork(struct signal_struct *sig);
+extern void sched_autogroup_exit(struct signal_struct *sig);
+#else
+static inline void sched_autogroup_create_attach(struct task_struct *p) { }
+static inline void sched_autogroup_detach(struct task_struct *p) { }
+static inline void sched_autogroup_fork(struct signal_struct *sig) { }
+static inline void sched_autogroup_exit(struct signal_struct *sig) { }
+#endif
+
#ifdef CONFIG_RT_MUTEXES
extern int rt_mutex_getprio(struct task_struct *p);
extern void rt_mutex_setprio(struct task_struct *p, int prio);
diff --git a/init/Kconfig b/init/Kconfig
index c972899..a4985d9 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -741,6 +741,18 @@ config NET_NS
endif # NAMESPACES
+config SCHED_AUTOGROUP
+ bool "Automatic process group scheduling"
+ select CGROUPS
+ select CGROUP_SCHED
+ select FAIR_GROUP_SCHED
+ help
+ This option optimizes the scheduler for common desktop workloads by
+ automatically creating and populating task groups. This separation
+ of workloads isolates aggressive CPU burners (like build jobs) from
+ desktop applications. Task group autogeneration is currently based
+ upon task tty association.
+
config MM_OWNER
bool
diff --git a/kernel/fork.c b/kernel/fork.c
index 5447dc7..70ea75f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -174,8 +174,10 @@ static inline void free_signal_struct(struct signal_struct *sig)
static inline void put_signal_struct(struct signal_struct *sig)
{
- if (atomic_dec_and_test(&sig->sigcnt))
+ if (atomic_dec_and_test(&sig->sigcnt)) {
+ sched_autogroup_exit(sig);
free_signal_struct(sig);
+ }
}
void __put_task_struct(struct task_struct *tsk)
@@ -905,6 +907,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
posix_cpu_timers_init_group(sig);
tty_audit_fork(sig);
+ sched_autogroup_fork(sig);
sig->oom_adj = current->signal->oom_adj;
sig->oom_score_adj = current->signal->oom_score_adj;
diff --git a/kernel/sched.c b/kernel/sched.c
index 297d1a0..53ff9a1 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -78,6 +78,7 @@
#include "sched_cpupri.h"
#include "workqueue_sched.h"
+#include "sched_autogroup.h"
#define CREATE_TRACE_POINTS
#include <trace/events/sched.h>
@@ -605,11 +606,14 @@ static inline int cpu_of(struct rq *rq)
*/
static inline struct task_group *task_group(struct task_struct *p)
{
+ struct task_group *tg;
struct cgroup_subsys_state *css;
css = task_subsys_state_check(p, cpu_cgroup_subsys_id,
lockdep_is_held(&task_rq(p)->lock));
- return container_of(css, struct task_group, css);
+ tg = container_of(css, struct task_group, css);
+
+ return autogroup_task_group(p, tg);
}
/* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */
@@ -2063,6 +2067,7 @@ static void update_rq_clock_task(struct rq *rq, s64 delta)
#include "sched_idletask.c"
#include "sched_fair.c"
#include "sched_rt.c"
+#include "sched_autogroup.c"
#include "sched_stoptask.c"
#ifdef CONFIG_SCHED_DEBUG
# include "sched_debug.c"
@@ -8164,7 +8169,7 @@ void __init sched_init(void)
#ifdef CONFIG_CGROUP_SCHED
list_add(&init_task_group.list, &task_groups);
INIT_LIST_HEAD(&init_task_group.children);
-
+ autogroup_init(&init_task);
#endif /* CONFIG_CGROUP_SCHED */
#if defined CONFIG_FAIR_GROUP_SCHED && defined CONFIG_SMP
@@ -8694,15 +8699,11 @@ void sched_destroy_group(struct task_group *tg)
/* change task's runqueue when it moves between groups.
* The caller of this function should have put the task in its new group
* by now. This function just updates tsk->se.cfs_rq and tsk->se.parent to
- * reflect its new group.
+ * reflect its new group. Called with the runqueue lock held.
*/
-void sched_move_task(struct task_struct *tsk)
+void __sched_move_task(struct task_struct *tsk, struct rq *rq)
{
int on_rq, running;
- unsigned long flags;
- struct rq *rq;
-
- rq = task_rq_lock(tsk, &flags);
running = task_current(rq, tsk);
on_rq = tsk->se.on_rq;
@@ -8723,7 +8724,15 @@ void sched_move_task(struct task_struct *tsk)
tsk->sched_class->set_curr_task(rq);
if (on_rq)
enqueue_task(rq, tsk, 0);
+}
+void sched_move_task(struct task_struct *tsk)
+{
+ struct rq *rq;
+ unsigned long flags;
+
+ rq = task_rq_lock(tsk, &flags);
+ __sched_move_task(tsk, rq);
task_rq_unlock(rq, &flags);
}
#endif /* CONFIG_CGROUP_SCHED */
diff --git a/kernel/sched_autogroup.c b/kernel/sched_autogroup.c
new file mode 100644
index 0000000..62f1d0e
--- /dev/null
+++ b/kernel/sched_autogroup.c
@@ -0,0 +1,140 @@
+#ifdef CONFIG_SCHED_AUTOGROUP
+
+unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1;
+
+struct autogroup {
+ struct kref kref;
+ struct task_group *tg;
+};
+
+static struct autogroup autogroup_default;
+
+static void autogroup_init(struct task_struct *init_task)
+{
+ autogroup_default.tg = &init_task_group;
+ kref_init(&autogroup_default.kref);
+ init_task->signal->autogroup = &autogroup_default;
+}
+
+static inline void autogroup_destroy(struct kref *kref)
+{
+ struct autogroup *ag = container_of(kref, struct autogroup, kref);
+ struct task_group *tg = ag->tg;
+
+ kfree(ag);
+ sched_destroy_group(tg);
+}
+
+static inline void autogroup_kref_put(struct autogroup *ag)
+{
+ kref_put(&ag->kref, autogroup_destroy);
+}
+
+static inline struct autogroup *autogroup_kref_get(struct autogroup *ag)
+{
+ kref_get(&ag->kref);
+ return ag;
+}
+
+static inline struct autogroup *autogroup_create(void)
+{
+ struct autogroup *ag = kmalloc(sizeof(*ag), GFP_KERNEL);
+
+ if (!ag)
+ goto out_fail;
+
+ ag->tg = sched_create_group(&init_task_group);
+ kref_init(&ag->kref);
+
+ if (!(IS_ERR(ag->tg)))
+ return ag;
+
+out_fail:
+ if (ag) {
+ kfree(ag);
+ WARN_ON(1);
+ } else
+ WARN_ON(1);
+
+ return autogroup_kref_get(&autogroup_default);
+}
+
+static inline struct task_group *
+autogroup_task_group(struct task_struct *p, struct task_group *tg)
+{
+ int enabled = ACCESS_ONCE(sysctl_sched_autogroup_enabled);
+
+ enabled &= (tg == &root_task_group);
+ enabled &= (p->sched_class == &fair_sched_class);
+ enabled &= (!(p->flags & PF_EXITING));
+
+ if (enabled)
+ return p->signal->autogroup->tg;
+
+ return tg;
+}
+
+static void
+autogroup_move_group(struct task_struct *p, struct autogroup *ag)
+{
+ struct autogroup *prev;
+ struct task_struct *t;
+ struct rq *rq;
+ unsigned long flags;
+
+ rq = task_rq_lock(p, &flags);
+ prev = p->signal->autogroup;
+ if (prev == ag) {
+ task_rq_unlock(rq, &flags);
+ return;
+ }
+
+ p->signal->autogroup = autogroup_kref_get(ag);
+ __sched_move_task(p, rq);
+ task_rq_unlock(rq, &flags);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(t, &p->thread_group, thread_group) {
+ sched_move_task(t);
+ }
+ rcu_read_unlock();
+
+ autogroup_kref_put(prev);
+}
+
+void sched_autogroup_create_attach(struct task_struct *p)
+{
+ struct autogroup *ag = autogroup_create();
+
+ autogroup_move_group(p, ag);
+ /* drop extra refrence added by autogroup_create() */
+ autogroup_kref_put(ag);
+}
+EXPORT_SYMBOL(sched_autogroup_create_attach);
+
+/* currently has no users */
+void sched_autogroup_detach(struct task_struct *p)
+{
+ autogroup_move_group(p, &autogroup_default);
+}
+EXPORT_SYMBOL(sched_autogroup_detach);
+
+void sched_autogroup_fork(struct signal_struct *sig)
+{
+ sig->autogroup = autogroup_kref_get(current->signal->autogroup);
+}
+
+void sched_autogroup_exit(struct signal_struct *sig)
+{
+ autogroup_kref_put(sig->autogroup);
+}
+
+static int __init setup_autogroup(char *str)
+{
+ sysctl_sched_autogroup_enabled = 0;
+
+ return 1;
+}
+
+__setup("noautogroup", setup_autogroup);
+#endif
diff --git a/kernel/sched_autogroup.h b/kernel/sched_autogroup.h
new file mode 100644
index 0000000..6048f5d
--- /dev/null
+++ b/kernel/sched_autogroup.h
@@ -0,0 +1,18 @@
+#ifdef CONFIG_SCHED_AUTOGROUP
+
+static void __sched_move_task(struct task_struct *tsk, struct rq *rq);
+
+static inline struct task_group *
+autogroup_task_group(struct task_struct *p, struct task_group *tg);
+
+#else /* !CONFIG_SCHED_AUTOGROUP */
+
+static inline void autogroup_init(struct task_struct *init_task) { }
+
+static inline struct task_group *
+autogroup_task_group(struct task_struct *p, struct task_group *tg)
+{
+ return tg;
+}
+
+#endif /* CONFIG_SCHED_AUTOGROUP */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 5abfa15..b162f65 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -382,6 +382,17 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
+#ifdef CONFIG_SCHED_AUTOGROUP
+ {
+ .procname = "sched_autogroup_enabled",
+ .data = &sysctl_sched_autogroup_enabled,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
+#endif
#ifdef CONFIG_PROVE_LOCKING
{
.procname = "prove_locking",
--
1.6.6.1
@@ -1,81 +0,0 @@
From 8b34449d7eb89e1ae1c1c84f90ef5ea1e397787e Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Tue, 23 Nov 2010 11:40:20 +0100
Subject: [PATCH 11/28] ARM: OMAP: add omap_rev_* macros
This is just to make the SGX modules build that depend on omap_rev_lt_3_0
Signed-off-by: Koen Kooi <koen@beagleboard.org>
---
arch/arm/plat-omap/include/plat/cpu.h | 55 +++++++++++++++++++++++++++++++++
1 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 3fd8b40..1a8c347 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -394,6 +394,61 @@ IS_OMAP_TYPE(3517, 0x3517)
#define OMAP4430_REV_ES2_0 0x44301044
/*
+ * Silicon revisions
+ */
+#define OMAP_ES_1_0 0x00
+#define OMAP_ES_2_0 0x10
+#define OMAP_ES_2_1 0x20
+#define OMAP_ES_3_0 0x30
+#define OMAP_ES_3_1 0x40
+
+#define OMAP_REV_MASK 0x0000ff00
+#define OMAP_REV_BITS ((omap_rev() & OMAP_REV_MASK) >> 8)
+
+#define OMAP_REV_IS(revid) \
+static inline u8 omap_rev_is_ ##revid (void) \
+{ \
+ return (OMAP_REV_BITS == OMAP_ES_ ##revid) ? 1 : 0; \
+}
+
+#define OMAP_REV_LT(revid) \
+static inline u8 omap_rev_lt_ ##revid (void) \
+{ \
+ return (OMAP_REV_BITS < OMAP_ES_ ##revid) ? 1 : 0; \
+}
+
+#define OMAP_REV_LE(revid) \
+static inline u8 omap_rev_le_ ##revid (void) \
+{ \
+ return (OMAP_REV_BITS <= OMAP_ES_ ##revid) ? 1 : 0; \
+}
+
+#define OMAP_REV_GT(revid) \
+static inline u8 omap_rev_gt_ ##revid (void) \
+{ \
+ return (OMAP_REV_BITS > OMAP_ES_ ##revid) ? 1 : 0; \
+}
+
+#define OMAP_REV_GE(revid) \
+static inline u8 omap_rev_ge_ ##revid (void) \
+{ \
+ return (OMAP_REV_BITS >= OMAP_ES_ ##revid) ? 1 : 0; \
+}
+
+#define OMAP_REV_FUNCTIONS(revid) \
+ OMAP_REV_IS(revid) \
+ OMAP_REV_LT(revid) \
+ OMAP_REV_LE(revid) \
+ OMAP_REV_GT(revid) \
+ OMAP_REV_GE(revid)
+
+OMAP_REV_FUNCTIONS(1_0)
+OMAP_REV_FUNCTIONS(2_0)
+OMAP_REV_FUNCTIONS(2_1)
+OMAP_REV_FUNCTIONS(3_0)
+OMAP_REV_FUNCTIONS(3_1)
+
+/*
* omap_chip bits
*
* CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is
--
1.6.6.1
@@ -1,31 +0,0 @@
From cd8a01e55dc674bba0030b99bff4f58d587aaecd Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Mon, 10 May 2010 20:44:09 -0700
Subject: [PATCH 12/28] OMAP: DSS2: enable hsclk in dsi_pll_init for OMAP36XX
Signed-off-by: Koen Kooi <koen@beagleboard.org>
---
drivers/video/omap2/dss/dpi.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 960e977..23047b6 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -177,7 +177,12 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
dss_clk_enable(DSS_CLK_FCK2);
- r = dsi_pll_init(dssdev, 0, 1);
+
+ if (cpu_is_omap3630())
+ r = dsi_pll_init(dssdev, 1, 1);
+ else
+ r = dsi_pll_init(dssdev, 0, 1);
+
if (r)
goto err3;
#endif
--
1.6.6.1
@@ -1,128 +0,0 @@
From f7d71be36165002251727019b1a03a19938bfa64 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@beagleboard.org>
Date: Mon, 20 Dec 2010 11:57:56 +0100
Subject: [PATCH 13/28] omap3: beagleboard: add WIP support for beagleboardtoys WL12xx board
Based on a patch by Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Koen Kooi <koen@beagleboard.org>
---
arch/arm/mach-omap2/board-omap3beagle.c | 84 ++++++++++++++++++++++++++++++-
1 files changed, 83 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 64a181e..59b26da 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -146,6 +146,67 @@ fail0:
char expansionboard_name[16];
+#if defined(CONFIG_WL1271) || defined(CONFIG_WL1271_MODULE)
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
+
+#define OMAP_BEAGLE_WLAN_EN_GPIO (139)
+#define OMAP_BEAGLE_WLAN_IRQ_GPIO (137)
+
+struct wl12xx_platform_data omap_beagle_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(OMAP_BEAGLE_WLAN_IRQ_GPIO),
+ .board_ref_clock = 2, /* 38.4 MHz */
+};
+
+ static struct omap2_hsmmc_info mmcbbt[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 29,
+ },
+ {
+ .name = "wl1271",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
+ {} /* Terminator */
+ };
+
+static struct regulator_consumer_supply beagle_vmmc2_supply = {
+ .supply = "vmmc",
+ .dev_name = "mmci-omap-hs.1",
+};
+
+static struct regulator_init_data beagle_vmmc2 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &beagle_vmmc2_supply,
+};
+
+static struct fixed_voltage_config beagle_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = OMAP_BEAGLE_WLAN_EN_GPIO,
+ .startup_delay = 70000, /* 70ms */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &beagle_vmmc2,
+};
+
+static struct platform_device omap_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &beagle_vwlan,
+ },
+};
+#endif
+
#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE)
#include <plat/mcspi.h>
@@ -384,11 +445,24 @@ static int beagle_twl_gpio_setup(struct device *dev,
}
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
mmc[0].gpio_cd = gpio + 0;
+#if defined(CONFIG_WL1271) || defined(CONFIG_WL1271_MODULE)
+ if(!strcmp(expansionboard_name, "bbtoys-wifi")) {
+ omap2_hsmmc_init(mmcbbt);
+ /* link regulators to MMC adapters */
+ beagle_vmmc1_supply.dev = mmcbbt[0].dev;
+ beagle_vsim_supply.dev = mmcbbt[0].dev;
+ } else {
+ omap2_hsmmc_init(mmc);
+ /* link regulators to MMC adapters */
+ beagle_vmmc1_supply.dev = mmc[0].dev;
+ beagle_vsim_supply.dev = mmc[0].dev;
+ }
+#else
omap2_hsmmc_init(mmc);
-
/* link regulators to MMC adapters */
beagle_vmmc1_supply.dev = mmc[0].dev;
beagle_vsim_supply.dev = mmc[0].dev;
+#endif
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
@@ -788,6 +862,14 @@ static void __init omap3_beagle_init(void)
gpio_export(162, 1);
}
+ if(!strcmp(expansionboard_name, "bbtoys-wifi"))
+ {
+ if (wl12xx_set_platform_data(&omap_beagle_wlan_data))
+ pr_err("error setting wl12xx data\n");
+ printk(KERN_INFO "Beagle expansionboard: registering wl12xx platform device\n");
+ platform_device_register(&omap_vwlan_device);
+ }
+
usb_musb_init(&musb_board_data);
usb_ehci_init(&ehci_pdata);
omap3beagle_flash_init();
--
1.6.6.1
@@ -1,29 +0,0 @@
From a47bbc5c9742e4ce250ee3bfba62732f3fea40b7 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <sakoman@gmail.com>
Date: Tue, 15 Dec 2009 15:17:44 -0800
Subject: [PATCH 14/28] drivers: net: smsc911x: return ENODEV if device is not found
Signed-off-by: Steve Sakoman <sakoman@gmail.com>
---
drivers/net/smsc911x.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 64bfdae..ba2a00e 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -2019,8 +2019,10 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
}
retval = smsc911x_init(dev);
- if (retval < 0)
+ if (retval < 0) {
+ retval = -ENODEV;
goto out_unmap_io_3;
+ }
/* configure irq polarity and type before connecting isr */
if (pdata->config.irq_polarity == SMSC911X_IRQ_POLARITY_ACTIVE_HIGH)
--
1.6.6.1
@@ -1,47 +0,0 @@
From 713eb96dd137e1436198aa07094049ae0e0f9f1f Mon Sep 17 00:00:00 2001
From: Steve Sakoman <sakoman@gmail.com>
Date: Tue, 15 Dec 2009 15:24:10 -0800
Subject: [PATCH 15/28] drivers: input: touchscreen: ads7846: return ENODEV if device is not found
Signed-off-by: Steve Sakoman <sakoman@gmail.com>
---
drivers/input/touchscreen/ads7846.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 14ea54b..c775e38 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -1325,11 +1325,18 @@ static int __devinit ads7846_probe(struct spi_device *spi)
* the touchscreen, in case it's not connected.
*/
if (ts->model == 7845)
- ads7845_read12_ser(&spi->dev, PWRDOWN);
+ err = ads7845_read12_ser(&spi->dev, PWRDOWN);
else
- (void) ads7846_read12_ser(&spi->dev,
+ err = ads7846_read12_ser(&spi->dev,
READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
+ /* if sample is all 0's or all 1's then there is no device on spi */
+ if ( (err == 0x000) || (err == 0xfff)) {
+ dev_info(&spi->dev, "no device detected, test read result was 0x%08X\n", err);
+ err = -ENODEV;
+ goto err_free_irq;
+ }
+
err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
if (err)
goto err_remove_hwmon;
@@ -1353,7 +1360,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
err_put_regulator:
regulator_put(ts->reg);
err_free_gpio:
- if (ts->gpio_pendown != -1)
+ if (!ts->get_pendown_state && ts->gpio_pendown != -1)
gpio_free(ts->gpio_pendown);
err_cleanup_filter:
if (ts->filter_cleanup)
--
1.6.6.1
@@ -1,27 +0,0 @@
From de63bf4fdf6c64e543c207792cb2d8ebcd089342 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 17 Dec 2009 12:45:20 -0800
Subject: [PATCH 16/28] ASoC: enable audio capture by default for twl4030
---
sound/soc/codecs/twl4030.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index cbebec6..430cd10 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -56,8 +56,8 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
0x00, /* REG_OPTION (0x2) */
0x00, /* REG_UNKNOWN (0x3) */
0x00, /* REG_MICBIAS_CTL (0x4) */
- 0x00, /* REG_ANAMICL (0x5) */
- 0x00, /* REG_ANAMICR (0x6) */
+ 0x34, /* REG_ANAMICL (0x5) */
+ 0x14, /* REG_ANAMICR (0x6) */
0x00, /* REG_AVADC_CTL (0x7) */
0x00, /* REG_ADCMICSEL (0x8) */
0x00, /* REG_DIGMIXING (0x9) */
--
1.6.6.1
@@ -1,51 +0,0 @@
From 18934b05f81025c1254d64c1774832e95187cbd9 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Sat, 23 Jan 2010 06:26:54 -0800
Subject: [PATCH 17/28] MFD: enable madc clock
---
drivers/mfd/twl-core.c | 8 ++++++++
include/linux/i2c/twl.h | 1 +
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 35275ba..5aa7358 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -208,6 +208,11 @@
/* Few power values */
#define R_CFG_BOOT 0x05
+#define R_GPBR1 0x0C
+
+/* MADC clock values for R_GPBR1 */
+#define MADC_HFCLK_EN 0x80
+#define DEFAULT_MADC_CLK_EN 0x10
/* some fields in R_CFG_BOOT */
#define HFCLK_FREQ_19p2_MHZ (1 << 0)
@@ -929,6 +934,9 @@ static void clocks_init(struct device *dev,
e |= unprotect_pm_master();
/* effect->MADC+USB ck en */
+ if (twl_has_madc())
+ e |= twl_i2c_write_u8(TWL_MODULE_INTBR,
+ MADC_HFCLK_EN | DEFAULT_MADC_CLK_EN, R_GPBR1);
e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, ctrl, R_CFG_BOOT);
e |= protect_pm_master();
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index c760991..cfdfdd3 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -74,6 +74,7 @@
#define TWL_MODULE_USB TWL4030_MODULE_USB
#define TWL_MODULE_AUDIO_VOICE TWL4030_MODULE_AUDIO_VOICE
+#define TWL_MODULE_INTBR TWL4030_MODULE_INTBR
#define TWL_MODULE_PIH TWL4030_MODULE_PIH
#define TWL_MODULE_MADC TWL4030_MODULE_MADC
#define TWL_MODULE_MAIN_CHARGE TWL4030_MODULE_MAIN_CHARGE
--
1.6.6.1
@@ -1,740 +0,0 @@
From 562dc52ebe3df1e5d23416e78306db7c568dc427 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 17 Dec 2009 14:19:34 -0800
Subject: [PATCH 18/28] MFD: add twl4030 madc driver
---
drivers/mfd/Kconfig | 21 ++
drivers/mfd/Makefile | 1 +
drivers/mfd/twl4030-madc.c | 537 ++++++++++++++++++++++++++++++++++++++
include/linux/i2c/twl4030-madc.h | 130 +++++++++
4 files changed, 689 insertions(+), 0 deletions(-)
create mode 100644 drivers/mfd/twl4030-madc.c
create mode 100644 include/linux/i2c/twl4030-madc.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3a1493b..26ca160 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -186,6 +186,27 @@ config TWL4030_CODEC
select MFD_CORE
default n
+config TWL4030_MADC
+ tristate "TWL4030 MADC Driver"
+ depends on TWL4030_CORE
+ help
+ The TWL4030 Monitoring ADC driver enables the host
+ processor to monitor analog signals using analog-to-digital
+ conversions on the input source. TWL4030 MADC provides the
+ following features:
+ - Single 10-bit ADC with successive approximation register (SAR) conversion;
+ - Analog multiplexer for 16 inputs;
+ - Seven (of the 16) inputs are freely available;
+ - Battery voltage monitoring;
+ - Concurrent conversion request management;
+ - Interrupt signal to Primary Interrupt Handler;
+ - Averaging feature;
+ - Selective enable/disable of the averaging feature.
+
+ Say 'y' here to statically link this module into the kernel or 'm'
+ to build it as a dinamically loadable module. The module will be
+ called twl4030-madc.ko
+
config TWL6030_PWM
tristate "TWL6030 PWM (Pulse Width Modulator) Support"
depends on TWL4030_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f54b365..8c4ccb2 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_MENELAUS) += menelaus.o
obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o
+obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
new file mode 100644
index 0000000..4adf880
--- /dev/null
+++ b/drivers/mfd/twl4030-madc.c
@@ -0,0 +1,537 @@
+/*
+ * TWL4030 MADC module driver
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Mikko Ylinen <mikko.k.ylinen@nokia.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 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/i2c/twl.h>
+#include <linux/i2c/twl4030-madc.h>
+
+#include <asm/uaccess.h>
+
+#define TWL4030_MADC_PFX "twl4030-madc: "
+
+struct twl4030_madc_data {
+ struct device *dev;
+ struct mutex lock;
+ struct work_struct ws;
+ struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
+ int imr;
+ int isr;
+};
+
+static struct twl4030_madc_data *the_madc;
+
+static
+const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
+ [TWL4030_MADC_RT] = {
+ .sel = TWL4030_MADC_RTSELECT_LSB,
+ .avg = TWL4030_MADC_RTAVERAGE_LSB,
+ .rbase = TWL4030_MADC_RTCH0_LSB,
+ },
+ [TWL4030_MADC_SW1] = {
+ .sel = TWL4030_MADC_SW1SELECT_LSB,
+ .avg = TWL4030_MADC_SW1AVERAGE_LSB,
+ .rbase = TWL4030_MADC_GPCH0_LSB,
+ .ctrl = TWL4030_MADC_CTRL_SW1,
+ },
+ [TWL4030_MADC_SW2] = {
+ .sel = TWL4030_MADC_SW2SELECT_LSB,
+ .avg = TWL4030_MADC_SW2AVERAGE_LSB,
+ .rbase = TWL4030_MADC_GPCH0_LSB,
+ .ctrl = TWL4030_MADC_CTRL_SW2,
+ },
+};
+
+static int twl4030_madc_read(struct twl4030_madc_data *madc, u8 reg)
+{
+ int ret;
+ u8 val;
+
+ ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, reg);
+ if (ret) {
+ dev_dbg(madc->dev, "unable to read register 0x%X\n", reg);
+ return ret;
+ }
+
+ return val;
+}
+
+static void twl4030_madc_write(struct twl4030_madc_data *madc, u8 reg, u8 val)
+{
+ int ret;
+
+ ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, reg);
+ if (ret)
+ dev_err(madc->dev, "unable to write register 0x%X\n", reg);
+}
+
+static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
+{
+ u8 msb, lsb;
+
+ /* For each ADC channel, we have MSB and LSB register pair. MSB address
+ * is always LSB address+1. reg parameter is the addr of LSB register */
+ msb = twl4030_madc_read(madc, reg + 1);
+ lsb = twl4030_madc_read(madc, reg);
+
+ return (int)(((msb << 8) | lsb) >> 6);
+}
+
+static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
+ u8 reg_base, u16 channels, int *buf)
+{
+ int count = 0;
+ u8 reg, i;
+
+ if (unlikely(!buf))
+ return 0;
+
+ for (i = 0; i < TWL4030_MADC_MAX_CHANNELS; i++) {
+ if (channels & (1<<i)) {
+ reg = reg_base + 2*i;
+ buf[i] = twl4030_madc_channel_raw_read(madc, reg);
+ count++;
+ }
+ }
+ return count;
+}
+
+static void twl4030_madc_enable_irq(struct twl4030_madc_data *madc, int id)
+{
+ u8 val;
+
+ val = twl4030_madc_read(madc, madc->imr);
+ val &= ~(1 << id);
+ twl4030_madc_write(madc, madc->imr, val);
+}
+
+static void twl4030_madc_disable_irq(struct twl4030_madc_data *madc, int id)
+{
+ u8 val;
+
+ val = twl4030_madc_read(madc, madc->imr);
+ val |= (1 << id);
+ twl4030_madc_write(madc, madc->imr, val);
+}
+
+static irqreturn_t twl4030_madc_irq_handler(int irq, void *_madc)
+{
+ struct twl4030_madc_data *madc = _madc;
+ u8 isr_val, imr_val;
+ int i;
+
+#ifdef CONFIG_LOCKDEP
+ /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
+ * we don't want and can't tolerate. Although it might be
+ * friendlier not to borrow this thread context...
+ */
+ local_irq_enable();
+#endif
+
+ /* Use COR to ack interrupts since we have no shared IRQs in ISRx */
+ isr_val = twl4030_madc_read(madc, madc->isr);
+ imr_val = twl4030_madc_read(madc, madc->imr);
+
+ isr_val &= ~imr_val;
+
+ for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
+
+ if (!(isr_val & (1<<i)))
+ continue;
+
+ twl4030_madc_disable_irq(madc, i);
+ madc->requests[i].result_pending = 1;
+ }
+
+ schedule_work(&madc->ws);
+
+ return IRQ_HANDLED;
+}
+
+static void twl4030_madc_work(struct work_struct *ws)
+{
+ const struct twl4030_madc_conversion_method *method;
+ struct twl4030_madc_data *madc;
+ struct twl4030_madc_request *r;
+ int len, i;
+
+ madc = container_of(ws, struct twl4030_madc_data, ws);
+ mutex_lock(&madc->lock);
+
+ for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
+
+ r = &madc->requests[i];
+
+ /* No pending results for this method, move to next one */
+ if (!r->result_pending)
+ continue;
+
+ method = &twl4030_conversion_methods[r->method];
+
+ /* Read results */
+ len = twl4030_madc_read_channels(madc, method->rbase,
+ r->channels, r->rbuf);
+
+ /* Return results to caller */
+ if (r->func_cb != NULL) {
+ r->func_cb(len, r->channels, r->rbuf);
+ r->func_cb = NULL;
+ }
+
+ /* Free request */
+ r->result_pending = 0;
+ r->active = 0;
+ }
+
+ mutex_unlock(&madc->lock);
+}
+
+static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
+ struct twl4030_madc_request *req)
+{
+ struct twl4030_madc_request *p;
+
+ p = &madc->requests[req->method];
+
+ memcpy(p, req, sizeof *req);
+
+ twl4030_madc_enable_irq(madc, req->method);
+
+ return 0;
+}
+
+static inline void twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
+ int conv_method)
+{
+ const struct twl4030_madc_conversion_method *method;
+
+ method = &twl4030_conversion_methods[conv_method];
+
+ switch (conv_method) {
+ case TWL4030_MADC_SW1:
+ case TWL4030_MADC_SW2:
+ twl4030_madc_write(madc, method->ctrl, TWL4030_MADC_SW_START);
+ break;
+ case TWL4030_MADC_RT:
+ default:
+ break;
+ }
+}
+
+static int twl4030_madc_wait_conversion_ready(
+ struct twl4030_madc_data *madc,
+ unsigned int timeout_ms, u8 status_reg)
+{
+ unsigned long timeout;
+
+ timeout = jiffies + msecs_to_jiffies(timeout_ms);
+ do {
+ u8 reg;
+
+ reg = twl4030_madc_read(madc, status_reg);
+ if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
+ return 0;
+ } while (!time_after(jiffies, timeout));
+
+ return -EAGAIN;
+}
+
+int twl4030_madc_conversion(struct twl4030_madc_request *req)
+{
+ const struct twl4030_madc_conversion_method *method;
+ u8 ch_msb, ch_lsb;
+ int ret;
+
+ if (unlikely(!req))
+ return -EINVAL;
+
+ mutex_lock(&the_madc->lock);
+
+ /* Do we have a conversion request ongoing */
+ if (the_madc->requests[req->method].active) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ch_msb = (req->channels >> 8) & 0xff;
+ ch_lsb = req->channels & 0xff;
+
+ method = &twl4030_conversion_methods[req->method];
+
+ /* Select channels to be converted */
+ twl4030_madc_write(the_madc, method->sel + 1, ch_msb);
+ twl4030_madc_write(the_madc, method->sel, ch_lsb);
+
+ /* Select averaging for all channels if do_avg is set */
+ if (req->do_avg) {
+ twl4030_madc_write(the_madc, method->avg + 1, ch_msb);
+ twl4030_madc_write(the_madc, method->avg, ch_lsb);
+ }
+
+ if ((req->type == TWL4030_MADC_IRQ_ONESHOT) && (req->func_cb != NULL)) {
+ twl4030_madc_set_irq(the_madc, req);
+ twl4030_madc_start_conversion(the_madc, req->method);
+ the_madc->requests[req->method].active = 1;
+ ret = 0;
+ goto out;
+ }
+
+ /* With RT method we should not be here anymore */
+ if (req->method == TWL4030_MADC_RT) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ twl4030_madc_start_conversion(the_madc, req->method);
+ the_madc->requests[req->method].active = 1;
+
+ /* Wait until conversion is ready (ctrl register returns EOC) */
+ ret = twl4030_madc_wait_conversion_ready(the_madc, 5, method->ctrl);
+ if (ret) {
+ dev_dbg(the_madc->dev, "conversion timeout!\n");
+ the_madc->requests[req->method].active = 0;
+ goto out;
+ }
+
+ ret = twl4030_madc_read_channels(the_madc, method->rbase, req->channels,
+ req->rbuf);
+
+ the_madc->requests[req->method].active = 0;
+
+out:
+ mutex_unlock(&the_madc->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(twl4030_madc_conversion);
+
+static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
+ int chan, int on)
+{
+ int ret;
+ u8 regval;
+
+ /* Current generator is only available for ADCIN0 and ADCIN1. NB:
+ * ADCIN1 current generator only works when AC or VBUS is present */
+ if (chan > 1)
+ return EINVAL;
+
+ ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
+ &regval, TWL4030_BCI_BCICTL1);
+ if (on)
+ regval |= (chan) ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
+ else
+ regval &= (chan) ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
+ ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
+ regval, TWL4030_BCI_BCICTL1);
+
+ return ret;
+}
+
+static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
+{
+ u8 regval;
+
+ regval = twl4030_madc_read(madc, TWL4030_MADC_CTRL1);
+ if (on)
+ regval |= TWL4030_MADC_MADCON;
+ else
+ regval &= ~TWL4030_MADC_MADCON;
+ twl4030_madc_write(madc, TWL4030_MADC_CTRL1, regval);
+
+ return 0;
+}
+
+static long twl4030_madc_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct twl4030_madc_user_parms par;
+ int val, ret;
+
+ ret = copy_from_user(&par, (void __user *) arg, sizeof(par));
+ if (ret) {
+ dev_dbg(the_madc->dev, "copy_from_user: %d\n", ret);
+ return -EACCES;
+ }
+
+ switch (cmd) {
+ case TWL4030_MADC_IOCX_ADC_RAW_READ: {
+ struct twl4030_madc_request req;
+ if (par.channel >= TWL4030_MADC_MAX_CHANNELS)
+ return -EINVAL;
+
+ req.channels = (1 << par.channel);
+ req.do_avg = par.average;
+ req.method = TWL4030_MADC_SW1;
+ req.func_cb = NULL;
+
+ val = twl4030_madc_conversion(&req);
+ if (val <= 0) {
+ par.status = -1;
+ } else {
+ par.status = 0;
+ par.result = (u16)req.rbuf[par.channel];
+ }
+ break;
+ }
+ default:
+ return -EINVAL;
+ }
+
+ ret = copy_to_user((void __user *) arg, &par, sizeof(par));
+ if (ret) {
+ dev_dbg(the_madc->dev, "copy_to_user: %d\n", ret);
+ return -EACCES;
+ }
+
+ return 0;
+}
+
+static struct file_operations twl4030_madc_fileops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = twl4030_madc_ioctl
+};
+
+static struct miscdevice twl4030_madc_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "twl4030-madc",
+ .fops = &twl4030_madc_fileops
+};
+
+static int __init twl4030_madc_probe(struct platform_device *pdev)
+{
+ struct twl4030_madc_data *madc;
+ struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
+ int ret;
+ u8 regval;
+
+ madc = kzalloc(sizeof *madc, GFP_KERNEL);
+ if (!madc)
+ return -ENOMEM;
+
+ if (!pdata) {
+ dev_dbg(&pdev->dev, "platform_data not available\n");
+ ret = -EINVAL;
+ goto err_pdata;
+ }
+
+ madc->imr = (pdata->irq_line == 1) ? TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2;
+ madc->isr = (pdata->irq_line == 1) ? TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2;
+
+ ret = misc_register(&twl4030_madc_device);
+ if (ret) {
+ dev_dbg(&pdev->dev, "could not register misc_device\n");
+ goto err_misc;
+ }
+ twl4030_madc_set_power(madc, 1);
+ twl4030_madc_set_current_generator(madc, 0, 1);
+
+ /* Enable ADCIN3 through 6 */
+ ret = twl_i2c_read_u8(TWL4030_MODULE_USB,
+ &regval, TWL4030_USB_CARKIT_ANA_CTRL);
+
+ regval |= TWL4030_USB_SEL_MADC_MCPC;
+
+ ret = twl_i2c_write_u8(TWL4030_MODULE_USB,
+ regval, TWL4030_USB_CARKIT_ANA_CTRL);
+
+
+ ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
+ &regval, TWL4030_BCI_BCICTL1);
+
+ regval |= TWL4030_BCI_MESBAT;
+
+ ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
+ regval, TWL4030_BCI_BCICTL1);
+
+ ret = request_irq(platform_get_irq(pdev, 0), twl4030_madc_irq_handler,
+ 0, "twl4030_madc", madc);
+ if (ret) {
+ dev_dbg(&pdev->dev, "could not request irq\n");
+ goto err_irq;
+ }
+
+ platform_set_drvdata(pdev, madc);
+ mutex_init(&madc->lock);
+ INIT_WORK(&madc->ws, twl4030_madc_work);
+
+ the_madc = madc;
+
+ return 0;
+
+err_irq:
+ misc_deregister(&twl4030_madc_device);
+
+err_misc:
+err_pdata:
+ kfree(madc);
+
+ return ret;
+}
+
+static int __exit twl4030_madc_remove(struct platform_device *pdev)
+{
+ struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
+
+ twl4030_madc_set_power(madc, 0);
+ twl4030_madc_set_current_generator(madc, 0, 0);
+ free_irq(platform_get_irq(pdev, 0), madc);
+ cancel_work_sync(&madc->ws);
+ misc_deregister(&twl4030_madc_device);
+
+ return 0;
+}
+
+static struct platform_driver twl4030_madc_driver = {
+ .probe = twl4030_madc_probe,
+ .remove = __exit_p(twl4030_madc_remove),
+ .driver = {
+ .name = "twl4030_madc",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init twl4030_madc_init(void)
+{
+ return platform_driver_register(&twl4030_madc_driver);
+}
+module_init(twl4030_madc_init);
+
+static void __exit twl4030_madc_exit(void)
+{
+ platform_driver_unregister(&twl4030_madc_driver);
+}
+module_exit(twl4030_madc_exit);
+
+MODULE_ALIAS("platform:twl4030-madc");
+MODULE_AUTHOR("Nokia Corporation");
+MODULE_DESCRIPTION("twl4030 ADC driver");
+MODULE_LICENSE("GPL");
+
diff --git a/include/linux/i2c/twl4030-madc.h b/include/linux/i2c/twl4030-madc.h
new file mode 100644
index 0000000..341a665
--- /dev/null
+++ b/include/linux/i2c/twl4030-madc.h
@@ -0,0 +1,130 @@
+/*
+ * include/linux/i2c/twl4030-madc.h
+ *
+ * TWL4030 MADC module driver header
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Mikko Ylinen <mikko.k.ylinen@nokia.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 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _TWL4030_MADC_H
+#define _TWL4030_MADC_H
+
+struct twl4030_madc_conversion_method {
+ u8 sel;
+ u8 avg;
+ u8 rbase;
+ u8 ctrl;
+};
+
+#define TWL4030_MADC_MAX_CHANNELS 16
+
+struct twl4030_madc_request {
+ u16 channels;
+ u16 do_avg;
+ u16 method;
+ u16 type;
+ int active;
+ int result_pending;
+ int rbuf[TWL4030_MADC_MAX_CHANNELS];
+ void (*func_cb)(int len, int channels, int *buf);
+};
+
+enum conversion_methods {
+ TWL4030_MADC_RT,
+ TWL4030_MADC_SW1,
+ TWL4030_MADC_SW2,
+ TWL4030_MADC_NUM_METHODS
+};
+
+enum sample_type {
+ TWL4030_MADC_WAIT,
+ TWL4030_MADC_IRQ_ONESHOT,
+ TWL4030_MADC_IRQ_REARM
+};
+
+#define TWL4030_MADC_CTRL1 0x00
+#define TWL4030_MADC_CTRL2 0x01
+
+#define TWL4030_MADC_RTSELECT_LSB 0x02
+#define TWL4030_MADC_SW1SELECT_LSB 0x06
+#define TWL4030_MADC_SW2SELECT_LSB 0x0A
+
+#define TWL4030_MADC_RTAVERAGE_LSB 0x04
+#define TWL4030_MADC_SW1AVERAGE_LSB 0x08
+#define TWL4030_MADC_SW2AVERAGE_LSB 0x0C
+
+#define TWL4030_MADC_CTRL_SW1 0x12
+#define TWL4030_MADC_CTRL_SW2 0x13
+
+#define TWL4030_MADC_RTCH0_LSB 0x17
+#define TWL4030_MADC_GPCH0_LSB 0x37
+
+#define TWL4030_MADC_MADCON (1<<0) /* MADC power on */
+#define TWL4030_MADC_BUSY (1<<0) /* MADC busy */
+#define TWL4030_MADC_EOC_SW (1<<1) /* MADC conversion completion */
+#define TWL4030_MADC_SW_START (1<<5) /* MADC SWx start conversion */
+
+#define TWL4030_MADC_ADCIN0 (1<<0)
+#define TWL4030_MADC_ADCIN1 (1<<1)
+#define TWL4030_MADC_ADCIN2 (1<<2)
+#define TWL4030_MADC_ADCIN3 (1<<3)
+#define TWL4030_MADC_ADCIN4 (1<<4)
+#define TWL4030_MADC_ADCIN5 (1<<5)
+#define TWL4030_MADC_ADCIN6 (1<<6)
+#define TWL4030_MADC_ADCIN7 (1<<7)
+#define TWL4030_MADC_ADCIN8 (1<<8)
+#define TWL4030_MADC_ADCIN9 (1<<9)
+#define TWL4030_MADC_ADCIN10 (1<<10)
+#define TWL4030_MADC_ADCIN11 (1<<11)
+#define TWL4030_MADC_ADCIN12 (1<<12)
+#define TWL4030_MADC_ADCIN13 (1<<13)
+#define TWL4030_MADC_ADCIN14 (1<<14)
+#define TWL4030_MADC_ADCIN15 (1<<15)
+
+/* Fixed channels */
+#define TWL4030_MADC_BTEMP TWL4030_MADC_ADCIN1
+#define TWL4030_MADC_VBUS TWL4030_MADC_ADCIN8
+#define TWL4030_MADC_VBKB TWL4030_MADC_ADCIN9
+#define TWL4030_MADC_ICHG TWL4030_MADC_ADCIN10
+#define TWL4030_MADC_VCHG TWL4030_MADC_ADCIN11
+#define TWL4030_MADC_VBAT TWL4030_MADC_ADCIN12
+
+/* BCI related - XXX To be moved elsewhere */
+#define TWL4030_BCI_BCICTL1 0x23
+#define TWL4030_BCI_MESBAT (1<<1)
+#define TWL4030_BCI_TYPEN (1<<4)
+#define TWL4030_BCI_ITHEN (1<<3)
+
+/* USB related - XXX To be moved elsewhere */
+#define TWL4030_USB_CARKIT_ANA_CTRL 0xBB
+#define TWL4030_USB_SEL_MADC_MCPC (1<<3)
+
+#define TWL4030_MADC_IOC_MAGIC '`'
+#define TWL4030_MADC_IOCX_ADC_RAW_READ _IO(TWL4030_MADC_IOC_MAGIC, 0)
+
+struct twl4030_madc_user_parms {
+ int channel;
+ int average;
+ int status;
+ u16 result;
+};
+
+int twl4030_madc_conversion(struct twl4030_madc_request *conv);
+
+#endif
--
1.6.6.1
@@ -1,32 +0,0 @@
From a33c4e0fb917ca059e900c2851849ba604758ff9 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 17 Dec 2009 14:27:15 -0800
Subject: [PATCH 19/28] ARM: OMAP: Add twl4030 madc support to Overo
---
arch/arm/mach-omap2/board-overo.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index cb26e5d..17f066a 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -369,10 +369,15 @@ static struct twl4030_codec_data overo_codec_data = {
/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
+static struct twl4030_madc_platform_data overo_madc_data = {
+ .irq_line = 1,
+};
+
static struct twl4030_platform_data overo_twldata = {
.irq_base = TWL4030_IRQ_BASE,
.irq_end = TWL4030_IRQ_END,
.gpio = &overo_gpio_data,
+ .madc = &overo_madc_data,
.usb = &overo_usb_data,
.codec = &overo_codec_data,
.vmmc1 = &overo_vmmc1,
--
1.6.6.1
@@ -1,35 +0,0 @@
From fe51c97f26f8d6798909b1f22a5fb4ca84684f36 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 17 Dec 2009 14:32:36 -0800
Subject: [PATCH 20/28] ARM: OMAP: Add twl4030 madc support to Beagle
---
arch/arm/mach-omap2/board-omap3beagle.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index f699701..9259780 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -604,6 +604,10 @@ static struct twl4030_codec_data beagle_codec_data = {
.audio = &beagle_audio_data,
};
+static struct twl4030_madc_platform_data beagle_madc_data = {
+ .irq_line = 1,
+};
+
static struct twl4030_platform_data beagle_twldata = {
.irq_base = TWL4030_IRQ_BASE,
.irq_end = TWL4030_IRQ_END,
@@ -612,6 +616,7 @@ static struct twl4030_platform_data beagle_twldata = {
.usb = &beagle_usb_data,
.gpio = &beagle_gpio_data,
.codec = &beagle_codec_data,
+ .madc = &beagle_madc_data,
.vmmc1 = &beagle_vmmc1,
.vsim = &beagle_vsim,
.vdac = &beagle_vdac,
--
1.6.6.1
@@ -1,173 +0,0 @@
From f8049ce6302904c1d08d8813f8a60b10b8a476e7 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Tue, 23 Feb 2010 14:40:27 -0800
Subject: [PATCH 21/28] OMAP: DSS2: Add support for Samsung LTE430WQ-F0C panel
---
.../omap2/displays/panel-samsung-lte430wq-f0c.c | 154 ++++++++++++++++++++
1 files changed, 154 insertions(+), 0 deletions(-)
create mode 100644 drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c
diff --git a/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c
new file mode 100644
index 0000000..6a29f9c
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c
@@ -0,0 +1,154 @@
+/*
+ * LCD panel driver for Samsung LTE430WQ-F0C
+ *
+ * Author: Steve Sakoman <steve@sakoman.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 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <plat/display.h>
+
+static struct omap_video_timings samsung_lte_timings = {
+ .x_res = 480,
+ .y_res = 272,
+
+ .pixel_clock = 9200,
+
+ .hsw = 41,
+ .hfp = 8,
+ .hbp = 45-41,
+
+ .vsw = 10,
+ .vfp = 4,
+ .vbp = 12-10,
+};
+
+static int samsung_lte_panel_power_on(struct omap_dss_device *dssdev)
+{
+ int r;
+
+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+ r = omapdss_dpi_display_enable(dssdev);
+ if (r)
+ goto err0;
+
+ if (dssdev->platform_enable) {
+ r = dssdev->platform_enable(dssdev);
+ if (r)
+ goto err1;
+ }
+
+ return 0;
+err1:
+ omapdss_dpi_display_disable(dssdev);
+err0:
+ return r;
+}
+
+static void samsung_lte_panel_power_off(struct omap_dss_device *dssdev)
+{
+ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return;
+
+ if (dssdev->platform_disable)
+ dssdev->platform_disable(dssdev);
+
+ omapdss_dpi_display_disable(dssdev);
+}
+
+static int samsung_lte_panel_probe(struct omap_dss_device *dssdev)
+{
+ dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+ OMAP_DSS_LCD_IHS;
+ dssdev->panel.timings = samsung_lte_timings;
+
+ return 0;
+}
+
+static void samsung_lte_panel_remove(struct omap_dss_device *dssdev)
+{
+}
+
+static int samsung_lte_panel_enable(struct omap_dss_device *dssdev)
+{
+ int r = 0;
+
+ r = samsung_lte_panel_power_on(dssdev);
+ if (r)
+ return r;
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+}
+
+static void samsung_lte_panel_disable(struct omap_dss_device *dssdev)
+{
+ samsung_lte_panel_power_off(dssdev);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static int samsung_lte_panel_suspend(struct omap_dss_device *dssdev)
+{
+ samsung_lte_panel_disable(dssdev);
+ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+ return 0;
+}
+
+static int samsung_lte_panel_resume(struct omap_dss_device *dssdev)
+{
+ int r;
+
+ r = samsung_lte_panel_enable(dssdev);
+ if (r)
+ return r;
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+}
+
+static struct omap_dss_driver samsung_lte_driver = {
+ .probe = samsung_lte_panel_probe,
+ .remove = samsung_lte_panel_remove,
+
+ .enable = samsung_lte_panel_enable,
+ .disable = samsung_lte_panel_disable,
+ .suspend = samsung_lte_panel_suspend,
+ .resume = samsung_lte_panel_resume,
+
+ .driver = {
+ .name = "samsung_lte_panel",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init samsung_lte_panel_drv_init(void)
+{
+ return omap_dss_register_driver(&samsung_lte_driver);
+}
+
+static void __exit samsung_lte_panel_drv_exit(void)
+{
+ omap_dss_unregister_driver(&samsung_lte_driver);
+}
+
+module_init(samsung_lte_panel_drv_init);
+module_exit(samsung_lte_panel_drv_exit);
+MODULE_LICENSE("GPL");
--
1.6.6.1
@@ -1,299 +0,0 @@
From 93032782a4803072d7ab1e22da029325f8f3cf44 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 17 Dec 2009 15:05:30 -0800
Subject: [PATCH 22/28] OMAP: DSS2: Add support for LG Philips LB035Q02 panel
---
drivers/video/omap2/displays/Kconfig | 12 +
drivers/video/omap2/displays/Makefile | 2 +
.../omap2/displays/panel-lgphilips-lb035q02.c | 244 ++++++++++++++++++++
3 files changed, 258 insertions(+), 0 deletions(-)
create mode 100644 drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 12327bb..48e872f 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -7,6 +7,18 @@ config PANEL_GENERIC
Generic panel driver.
Used for DVI output for Beagle and OMAP3 SDP.
+config PANEL_LGPHILIPS_LB035Q02
+ tristate "LG.Philips LB035Q02 LCD Panel"
+ depends on OMAP2_DSS
+ help
+ LCD Panel used on Overo Palo35
+
+config PANEL_SAMSUNG_LTE430WQ_F0C
+ tristate "Samsung LTE430WQ-F0C LCD Panel"
+ depends on OMAP2_DSS
+ help
+ LCD Panel used on Overo Palo43
+
config PANEL_SHARP_LS037V7DW01
tristate "Sharp LS037V7DW01 LCD Panel"
depends on OMAP2_DSS
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index aa38609..2fb1a57 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,4 +1,6 @@
obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o
+obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
+obj-$(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) += panel-samsung-lte430wq-f0c.o
obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
new file mode 100644
index 0000000..4ad709d
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -0,0 +1,244 @@
+/*
+ * LCD panel driver for LG.Philips LB035Q02
+ *
+ * Author: Steve Sakoman <steve@sakoman.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 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+
+#include <plat/display.h>
+
+static struct spi_device *spidev;
+
+static struct omap_video_timings lb035q02_timings = {
+ .x_res = 320,
+ .y_res = 240,
+
+ .pixel_clock = 6500,
+
+ .hsw = 2,
+ .hfp = 20,
+ .hbp = 68,
+
+ .vsw = 2,
+ .vfp = 4,
+ .vbp = 18,
+};
+
+static int lb035q02_write_reg(u8 reg, u16 val)
+{
+ struct spi_message msg;
+ struct spi_transfer index_xfer = {
+ .len = 3,
+ .cs_change = 1,
+ };
+ struct spi_transfer value_xfer = {
+ .len = 3,
+ };
+ u8 buffer[16];
+
+ spi_message_init(&msg);
+
+ /* register index */
+ buffer[0] = 0x70;
+ buffer[1] = 0x00;
+ buffer[2] = reg & 0x7f;
+ index_xfer.tx_buf = buffer;
+ spi_message_add_tail(&index_xfer, &msg);
+
+ /* register value */
+ buffer[4] = 0x72;
+ buffer[5] = val >> 8;
+ buffer[6] = val;
+ value_xfer.tx_buf = buffer + 4;
+ spi_message_add_tail(&value_xfer, &msg);
+
+ return spi_sync(spidev, &msg);
+}
+
+static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
+{
+ int r;
+
+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+ r = omapdss_dpi_display_enable(dssdev);
+ if (r)
+ goto err0;
+
+ if (dssdev->platform_enable) {
+ r = dssdev->platform_enable(dssdev);
+ if (r)
+ goto err1;
+ }
+
+ /* Panel init sequence from page 28 of the spec */
+ lb035q02_write_reg(0x01, 0x6300);
+ lb035q02_write_reg(0x02, 0x0200);
+ lb035q02_write_reg(0x03, 0x0177);
+ lb035q02_write_reg(0x04, 0x04c7);
+ lb035q02_write_reg(0x05, 0xffc0);
+ lb035q02_write_reg(0x06, 0xe806);
+ lb035q02_write_reg(0x0a, 0x4008);
+ lb035q02_write_reg(0x0b, 0x0000);
+ lb035q02_write_reg(0x0d, 0x0030);
+ lb035q02_write_reg(0x0e, 0x2800);
+ lb035q02_write_reg(0x0f, 0x0000);
+ lb035q02_write_reg(0x16, 0x9f80);
+ lb035q02_write_reg(0x17, 0x0a0f);
+ lb035q02_write_reg(0x1e, 0x00c1);
+ lb035q02_write_reg(0x30, 0x0300);
+ lb035q02_write_reg(0x31, 0x0007);
+ lb035q02_write_reg(0x32, 0x0000);
+ lb035q02_write_reg(0x33, 0x0000);
+ lb035q02_write_reg(0x34, 0x0707);
+ lb035q02_write_reg(0x35, 0x0004);
+ lb035q02_write_reg(0x36, 0x0302);
+ lb035q02_write_reg(0x37, 0x0202);
+ lb035q02_write_reg(0x3a, 0x0a0d);
+ lb035q02_write_reg(0x3b, 0x0806);
+
+ return 0;
+err1:
+ omapdss_dpi_display_disable(dssdev);
+err0:
+ return r;
+}
+
+static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
+{
+ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return;
+
+ if (dssdev->platform_disable)
+ dssdev->platform_disable(dssdev);
+
+ omapdss_dpi_display_disable(dssdev);
+}
+
+static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
+{
+ dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+ OMAP_DSS_LCD_IHS;
+ dssdev->panel.timings = lb035q02_timings;
+
+ return 0;
+}
+
+static void lb035q02_panel_remove(struct omap_dss_device *dssdev)
+{
+}
+
+static int lb035q02_panel_enable(struct omap_dss_device *dssdev)
+{
+ int r = 0;
+
+ r = lb035q02_panel_power_on(dssdev);
+ if (r)
+ return r;
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+}
+
+static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
+{
+ lb035q02_panel_power_off(dssdev);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static int lb035q02_panel_suspend(struct omap_dss_device *dssdev)
+{
+ lb035q02_panel_disable(dssdev);
+ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+ return 0;
+}
+
+static int lb035q02_panel_resume(struct omap_dss_device *dssdev)
+{
+ int r;
+
+ r = lb035q02_panel_power_on(dssdev);
+ if (r)
+ return r;
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+}
+
+static struct omap_dss_driver lb035q02_driver = {
+ .probe = lb035q02_panel_probe,
+ .remove = lb035q02_panel_remove,
+
+ .enable = lb035q02_panel_enable,
+ .disable = lb035q02_panel_disable,
+ .suspend = lb035q02_panel_suspend,
+ .resume = lb035q02_panel_resume,
+
+ .driver = {
+ .name = "lgphilips_lb035q02_panel",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __devinit lb035q02_panel_spi_probe(struct spi_device *spi)
+{
+ spidev = spi;
+ return 0;
+}
+
+static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi)
+{
+ return 0;
+}
+
+static struct spi_driver lb035q02_spi_driver = {
+ .driver = {
+ .name = "lgphilips_lb035q02_panel-spi",
+ .owner = THIS_MODULE,
+ },
+ .probe = lb035q02_panel_spi_probe,
+ .remove = __devexit_p (lb035q02_panel_spi_remove),
+};
+
+static int __init lb035q02_panel_drv_init(void)
+{
+ int r;
+ r = spi_register_driver(&lb035q02_spi_driver);
+ if (r != 0)
+ pr_err("lgphilips_lb035q02: Unable to register SPI driver: %d\n", r);
+
+ r = omap_dss_register_driver(&lb035q02_driver);
+ if (r != 0)
+ pr_err("lgphilips_lb035q02: Unable to register panel driver: %d\n", r);
+
+ return r;
+}
+
+static void __exit lb035q02_panel_drv_exit(void)
+{
+ spi_unregister_driver(&lb035q02_spi_driver);
+ omap_dss_unregister_driver(&lb035q02_driver);
+}
+
+module_init(lb035q02_panel_drv_init);
+module_exit(lb035q02_panel_drv_exit);
+MODULE_LICENSE("GPL");
--
1.6.6.1
@@ -1,75 +0,0 @@
From f046a207183e3e338c7e851085265f0df95f4cc2 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Tue, 19 Jan 2010 21:19:15 -0800
Subject: [PATCH 23/28] OMAP: DSS2: add bootarg for selecting svideo or composite for tv output
also add pal-16 and ntsc-16 omapfb.mode settings for 16bpp
---
drivers/video/omap2/dss/venc.c | 22 ++++++++++++++++++++++
drivers/video/omap2/omapfb/omapfb-main.c | 10 +++++++++-
2 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index eff3505..e1f4aab 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -87,6 +87,11 @@
#define VENC_OUTPUT_TEST 0xC8
#define VENC_DAC_B__DAC_C 0xC8
+static char *tv_connection;
+
+module_param_named(tvcable, tv_connection, charp, 0);
+MODULE_PARM_DESC(tvcable, "TV connection type (svideo, composite)");
+
struct venc_config {
u32 f_control;
u32 vidout_ctrl;
@@ -459,6 +464,23 @@ static int venc_panel_probe(struct omap_dss_device *dssdev)
{
dssdev->panel.timings = omap_dss_pal_timings;
+ /* Allow the TV output to be overriden */
+ if (tv_connection) {
+ if (strcmp(tv_connection, "svideo") == 0) {
+ printk(KERN_INFO
+ "omapdss: tv output is svideo.\n");
+ dssdev->phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO;
+ } else if (strcmp(tv_connection, "composite") == 0) {
+ printk(KERN_INFO
+ "omapdss: tv output is composite.\n");
+ dssdev->phy.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+ } else {
+ printk(KERN_INFO
+ "omapdss: unsupported output type'%s'.\n",
+ tv_connection);
+ }
+ }
+
return 0;
}
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 6a704f1..7ee833f 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2036,7 +2036,15 @@ static int omapfb_mode_to_timings(const char *mode_str,
int r;
#ifdef CONFIG_OMAP2_DSS_VENC
- if (strcmp(mode_str, "pal") == 0) {
+ if (strcmp(mode_str, "pal-16") == 0) {
+ *timings = omap_dss_pal_timings;
+ *bpp = 16;
+ return 0;
+ } else if (strcmp(mode_str, "ntsc-16") == 0) {
+ *timings = omap_dss_ntsc_timings;
+ *bpp = 16;
+ return 0;
+ } else if (strcmp(mode_str, "pal") == 0) {
*timings = omap_dss_pal_timings;
*bpp = 24;
return 0;
--
1.6.6.1
@@ -1,39 +0,0 @@
From 66bba5baf225a1420c734aa0268e7dd37fc3f73b Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Sun, 24 Jan 2010 09:33:56 -0800
Subject: [PATCH 24/28] ARM: OMAP2: mmc-twl4030: move clock input selection prior to vcc test
otherwise it is not executed on systems that use non-twl regulators
---
arch/arm/mach-omap2/hsmmc.c | 14 ++++++--------
1 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 34272e4..a74631d 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -186,15 +186,13 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot,
if (mmc->slots[0].remux)
mmc->slots[0].remux(dev, slot, power_on);
- if (power_on) {
- /* Only MMC2 supports a CLKIN */
- if (mmc->slots[0].internal_clock) {
- u32 reg;
+ /* Only MMC2 supports a CLKIN */
+ if (mmc->slots[0].internal_clock) {
+ u32 reg;
- reg = omap_ctrl_readl(control_devconf1_offset);
- reg |= OMAP2_MMCSDIO2ADPCLKISEL;
- omap_ctrl_writel(reg, control_devconf1_offset);
- }
+ reg = omap_ctrl_readl(control_devconf1_offset);
+ reg |= OMAP2_MMCSDIO2ADPCLKISEL;
+ omap_ctrl_writel(reg, control_devconf1_offset);
}
}
--
1.6.6.1
@@ -1,55 +0,0 @@
From ae08111e55d17183382dd06d161066adf9f80f3c Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 4 Feb 2010 12:26:22 -0800
Subject: [PATCH 25/28] RTC: add support for backup battery recharge
---
drivers/rtc/rtc-twl.c | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index ed1b868..33a8598 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -30,6 +30,23 @@
#include <linux/i2c/twl.h>
+/*
+ * PM_RECEIVER block register offsets (use TWL4030_MODULE_PM_RECEIVER)
+ */
+#define REG_BB_CFG 0x12
+
+/* PM_RECEIVER BB_CFG bitfields */
+#define BIT_PM_RECEIVER_BB_CFG_BBCHEN 0x10
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL 0x0C
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_2V5 0x00
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3V0 0x04
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3V1 0x08
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3v2 0x0c
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL 0x03
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_25UA 0x00
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_150UA 0x01
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_500UA 0x02
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_1MA 0x03
/*
* RTC block register offsets (use TWL_MODULE_RTC)
@@ -508,6 +525,14 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
if (ret < 0)
goto out2;
+ /* enable backup battery charging */
+ /* use a conservative 25uA @ 3.1V */
+ ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ BIT_PM_RECEIVER_BB_CFG_BBCHEN |
+ BIT_PM_RECEIVER_BB_CFG_BBSEL_3V1 |
+ BIT_PM_RECEIVER_BB_CFG_BBISEL_25UA,
+ REG_BB_CFG);
+
return ret;
out2:
--
1.6.6.1
@@ -1,49 +0,0 @@
From dd53a7c1ab8addfd2a943ea44b5ccc5700648323 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Wed, 24 Feb 2010 10:37:22 -0800
Subject: [PATCH 26/28] ARM: OMAP: automatically set musb mode in platform data based on CONFIG options
---
arch/arm/mach-omap2/board-omap3beagle.c | 6 ++++++
arch/arm/mach-omap2/board-overo.c | 6 ++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 9259780..ad0c1d8 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -785,7 +785,13 @@ static struct omap_board_mux board_mux[] __initdata = {
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_ULPI,
+#if defined(CONFIG_USB_MUSB_OTG)
.mode = MUSB_OTG,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#else
+ .mode = MUSB_HOST,
+#endif
.power = 100,
};
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 17f066a..b28a9d5 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -447,7 +447,13 @@ static struct omap_board_mux board_mux[] __initdata = {
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_ULPI,
+#if defined(CONFIG_USB_MUSB_OTG)
.mode = MUSB_OTG,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#else
+ .mode = MUSB_HOST,
+#endif
.power = 100,
};
--
1.6.6.1
@@ -1,34 +0,0 @@
From ec3e66ef2e222feb0408f16a3498be1ea9b6a9c0 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Mon, 10 May 2010 13:59:14 -0700
Subject: [PATCH 27/28] OMAP: DSS2: check for both cpu type and revision, rather than just revision
---
drivers/video/omap2/dss/dispc.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index fa40fa5..133916a 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2101,7 +2101,7 @@ void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode)
static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
int vsw, int vfp, int vbp)
{
- if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
+ if (cpu_is_omap24xx() || (cpu_is_omap34xx() && omap_rev_lt_3_0())) {
if (hsw < 1 || hsw > 64 ||
hfp < 1 || hfp > 256 ||
hbp < 1 || hbp > 256 ||
@@ -2134,7 +2134,7 @@ static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp,
{
u32 timing_h, timing_v;
- if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
+ if (cpu_is_omap24xx() || (cpu_is_omap34xx() && omap_rev_lt_3_0())) {
timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
FLD_VAL(hbp-1, 27, 20);
--
1.6.6.1
@@ -1,355 +0,0 @@
From 9b2bfa418f2e1b7ed3e210cb7cba3cdd67f9925f Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Fri, 18 Dec 2009 06:39:24 -0800
Subject: [PATCH 28/28] OMAP: DSS2: Add DSS2 support for Overo
---
arch/arm/mach-omap2/board-overo.c | 238 +++++++++++++++++++++++++++++++------
1 files changed, 204 insertions(+), 34 deletions(-)
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index b28a9d5..8a44c17 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -28,6 +28,7 @@
#include <linux/platform_device.h>
#include <linux/i2c/twl.h>
#include <linux/regulator/machine.h>
+#include <linux/spi/spi.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
@@ -41,10 +42,13 @@
#include <plat/board.h>
#include <plat/common.h>
+#include <plat/display.h>
#include <mach/gpio.h>
#include <plat/gpmc.h>
#include <mach/hardware.h>
#include <plat/nand.h>
+#include <plat/mcspi.h>
+#include <plat/mux.h>
#include <plat/usb.h>
#include "mux.h"
@@ -68,8 +72,6 @@
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-#include <plat/mcspi.h>
-#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
static struct omap2_mcspi_device_config ads7846_mcspi_config = {
@@ -94,18 +96,6 @@ static struct ads7846_platform_data ads7846_config = {
.keep_vref_on = 1,
};
-static struct spi_board_info overo_spi_board_info[] __initdata = {
- {
- .modalias = "ads7846",
- .bus_num = 1,
- .chip_select = 0,
- .max_speed_hz = 1500000,
- .controller_data = &ads7846_mcspi_config,
- .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
- .platform_data = &ads7846_config,
- }
-};
-
static void __init overo_ads7846_init(void)
{
if ((gpio_request(OVERO_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) &&
@@ -115,9 +105,6 @@ static void __init overo_ads7846_init(void)
printk(KERN_ERR "could not obtain gpio for ADS7846_PENDOWN\n");
return;
}
-
- spi_register_board_info(overo_spi_board_info,
- ARRAY_SIZE(overo_spi_board_info));
}
#else
@@ -233,6 +220,139 @@ static inline void __init overo_init_smsc911x(void)
static inline void __init overo_init_smsc911x(void) { return; }
#endif
+/* DSS */
+static int lcd_enabled;
+static int dvi_enabled;
+
+#define OVERO_GPIO_LCD_EN 144
+#define OVERO_GPIO_LCD_BL 145
+
+static void __init overo_display_init(void)
+{
+ if ((gpio_request(OVERO_GPIO_LCD_EN, "OVERO_GPIO_LCD_EN") == 0) &&
+ (gpio_direction_output(OVERO_GPIO_LCD_EN, 1) == 0))
+ gpio_export(OVERO_GPIO_LCD_EN, 0);
+ else
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_LCD_EN\n");
+
+ if ((gpio_request(OVERO_GPIO_LCD_BL, "OVERO_GPIO_LCD_BL") == 0) &&
+ (gpio_direction_output(OVERO_GPIO_LCD_BL, 1) == 0))
+ gpio_export(OVERO_GPIO_LCD_BL, 0);
+ else
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_LCD_BL\n");
+}
+
+static int overo_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ dvi_enabled = 0;
+}
+
+static struct omap_dss_device overo_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "generic_panel",
+ .phy.dpi.data_lines = 24,
+ .platform_enable = overo_panel_enable_dvi,
+ .platform_disable = overo_panel_disable_dvi,
+};
+
+static struct omap_dss_device overo_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+static int overo_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(OVERO_GPIO_LCD_EN, 1);
+ gpio_set_value(OVERO_GPIO_LCD_BL, 1);
+ lcd_enabled = 1;
+ return 0;
+}
+
+static void overo_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(OVERO_GPIO_LCD_EN, 0);
+ gpio_set_value(OVERO_GPIO_LCD_BL, 0);
+ lcd_enabled = 0;
+}
+
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+static struct omap_dss_device overo_lcd35_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "lcd35",
+ .driver_name = "lgphilips_lb035q02_panel",
+ .phy.dpi.data_lines = 24,
+ .platform_enable = overo_panel_enable_lcd,
+ .platform_disable = overo_panel_disable_lcd,
+};
+#endif
+
+#if defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) || \
+ defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C_MODULE)
+static struct omap_dss_device overo_lcd43_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "lcd43",
+ .driver_name = "samsung_lte_panel",
+ .phy.dpi.data_lines = 24,
+ .platform_enable = overo_panel_enable_lcd,
+ .platform_disable = overo_panel_disable_lcd,
+};
+#endif
+
+static struct omap_dss_device *overo_dss_devices[] = {
+ &overo_dvi_device,
+ &overo_tv_device,
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+ &overo_lcd35_device,
+#endif
+#if defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) || \
+ defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C_MODULE)
+ &overo_lcd43_device,
+#endif
+};
+
+static struct omap_dss_board_info overo_dss_data = {
+ .num_devices = ARRAY_SIZE(overo_dss_devices),
+ .devices = overo_dss_devices,
+ .default_device = &overo_dvi_device,
+};
+
+static struct platform_device overo_dss_device = {
+ .name = "omapdss",
+ .id = -1,
+ .dev = {
+ .platform_data = &overo_dss_data,
+ },
+};
+
+static struct regulator_consumer_supply overo_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss");
+
+static struct regulator_consumer_supply overo_vdds_dsi_supply =
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss");
+
static struct mtd_partition overo_nand_partitions[] = {
{
.name = "xloader",
@@ -358,6 +478,37 @@ static struct regulator_init_data overo_vmmc1 = {
.consumer_supplies = &overo_vmmc1_supply,
};
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data overo_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &overo_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data overo_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &overo_vdds_dsi_supply,
+};
+
+/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
+
static struct twl4030_codec_audio_data overo_audio_data = {
.audio_mclk = 26000000,
};
@@ -367,8 +518,6 @@ static struct twl4030_codec_data overo_codec_data = {
.audio = &overo_audio_data,
};
-/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
-
static struct twl4030_madc_platform_data overo_madc_data = {
.irq_line = 1,
};
@@ -381,6 +530,8 @@ static struct twl4030_platform_data overo_twldata = {
.usb = &overo_usb_data,
.codec = &overo_codec_data,
.vmmc1 = &overo_vmmc1,
+ .vdac = &overo_vdac,
+ .vpll2 = &overo_vpll2,
};
static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
@@ -401,23 +552,41 @@ static int __init overo_i2c_init(void)
return 0;
}
-static struct platform_device overo_lcd_device = {
- .name = "overo_lcd",
- .id = -1,
-};
-
-static struct omap_lcd_config overo_lcd_config __initdata = {
- .ctrl_name = "internal",
+static struct spi_board_info overo_spi_board_info[] __initdata = {
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ {
+ .modalias = "ads7846",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 1500000,
+ .controller_data = &ads7846_mcspi_config,
+ .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
+ .platform_data = &ads7846_config,
+ },
+#endif
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+ {
+ .modalias = "lgphilips_lb035q02_panel-spi",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 500000,
+ .mode = SPI_MODE_3,
+ },
+#endif
};
-static struct omap_board_config_kernel overo_config[] __initdata = {
- { OMAP_TAG_LCD, &overo_lcd_config },
-};
+static int __init overo_spi_init(void)
+{
+ overo_ads7846_init();
+ spi_register_board_info(overo_spi_board_info,
+ ARRAY_SIZE(overo_spi_board_info));
+ return 0;
+}
static void __init overo_init_irq(void)
{
- omap_board_config = overo_config;
- omap_board_config_size = ARRAY_SIZE(overo_config);
omap2_init_common_infrastructure();
omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
@@ -425,7 +594,7 @@ static void __init overo_init_irq(void)
}
static struct platform_device *overo_devices[] __initdata = {
- &overo_lcd_device,
+ &overo_dss_device,
};
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
@@ -466,8 +635,9 @@ static void __init overo_init(void)
overo_flash_init();
usb_musb_init(&musb_board_data);
usb_ehci_init(&ehci_pdata);
- overo_ads7846_init();
+ overo_spi_init();
overo_init_smsc911x();
+ overo_display_init();
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
@@ -510,7 +680,7 @@ static void __init overo_init(void)
"OVERO_GPIO_USBH_CPEN\n");
}
-MACHINE_START(OVERO, "Gumstix Overo")
+MACHINE_START(OVERO, "Gumstsix Overo")
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
--
1.6.6.1
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,60 +0,0 @@
From 8548db6d3cf115b29142f803d701122dc4cbb775 Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 31 Dec 2010 13:35:02 +0530
Subject: [PATCH 01/20] OMAP3: PM: Adding T2 enabling of smartreflex
The smartreflex bit on twl4030 needs to be enabled by default irrespective
of whether smartreflex module is enabled on the OMAP side or not.
This is because without this bit enabled the voltage scaling through
vp forceupdate does not function properly on OMAP3.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/omap_twl.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 15f8c6c..a59f36b 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -58,7 +58,9 @@
static bool is_offset_valid;
static u8 smps_offset;
+#define TWL4030_DCDC_GLOBAL_CFG 0x06
#define REG_SMPS_OFFSET 0xE0
+#define SMARTREFLEX_ENABLE BIT(3)
unsigned long twl4030_vsel_to_uv(const u8 vsel)
{
@@ -256,6 +258,7 @@ int __init omap4_twl_init(void)
int __init omap3_twl_init(void)
{
struct voltagedomain *voltdm;
+ u8 temp;
if (!cpu_is_omap34xx())
return -ENODEV;
@@ -267,6 +270,19 @@ int __init omap3_twl_init(void)
omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
}
+ /*
+ * The smartreflex bit on twl4030 needs to be enabled by
+ * default irrespective of whether smartreflex module is
+ * enabled on the OMAP side or not. This is because without
+ * this bit enabled the voltage scaling through
+ * vp forceupdate does not function properly on OMAP3.
+ */
+ twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &temp,
+ TWL4030_DCDC_GLOBAL_CFG);
+ temp |= SMARTREFLEX_ENABLE;
+ twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, temp,
+ TWL4030_DCDC_GLOBAL_CFG);
+
voltdm = omap_voltage_domain_lookup("mpu");
omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info);
--
1.6.6.1
@@ -1,27 +0,0 @@
From e446cbf4aa8359d58180a81282df70045b8a41c1 Mon Sep 17 00:00:00 2001
From: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
Date: Wed, 11 Aug 2010 17:02:43 -0700
Subject: [PATCH 02/20] OMAP: CPUfreq: ensure driver initializes after cpufreq framework and governors
Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/plat-omap/cpu-omap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 11c54ec..79d2155 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -160,7 +160,7 @@ static int __init omap_cpufreq_init(void)
return cpufreq_register_driver(&omap_driver);
}
-arch_initcall(omap_cpufreq_init);
+late_initcall(omap_cpufreq_init);
/*
* if ever we want to remove this, upon cleanup call:
--
1.6.6.1
@@ -1,31 +0,0 @@
From 647691beb64312327646a84dc161faf35935e7f7 Mon Sep 17 00:00:00 2001
From: Kevin Hilman <khilman@deeprootsystems.com>
Date: Wed, 11 Aug 2010 17:05:38 -0700
Subject: [PATCH 03/20] OMAP: CPUfreq: ensure policy is fully initialized
Ensure policy min/max/cur values are initialized when OMAP
CPUfreq driver starts.
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/plat-omap/cpu-omap.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 79d2155..bfa063b 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -126,6 +126,10 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy)
VERY_HI_RATE) / 1000;
}
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = omap_getspeed(0);
+
/* FIXME: what's the actual transition time? */
policy->cpuinfo.transition_latency = 300 * 1000;
--
1.6.6.1
@@ -1,269 +0,0 @@
From f6b96e3b9e31da193189d92320b3dd9fac7c9ba9 Mon Sep 17 00:00:00 2001
From: Rajendra Nayak <rnayak@ti.com>
Date: Mon, 10 Nov 2008 17:00:25 +0530
Subject: [PATCH 04/20] OMAP3 PM: CPUFreq driver for OMAP3
CPUFreq driver for OMAP3
With additional fixes and cleanups from Tero Kristo:
- Fix rate calculation bug in omap3_select_table_rate
- Refreshed DVFS VDD1 control against latest clock fw
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
OMAP3: PM: CPUFreq: Fix omap_getspeed.
Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
Make sure omap cpufreq driver initializes after cpufreq framework and governors
Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
merge: CPUFreq: remove obsolete funcs
OMAP3 clock: Update cpufreq driver
This patch removes all refrences to virtual clock
nodes in CPUFreq driver.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Jean Pihet <jpihet@mvista.com>
PM: Prevent direct cpufreq scaling during initialization
It is seen that the OMAP specific cpufreq initialization code tries to
scale the MPU frequency to the highest possible without taking care of
the voltage level. On power on reset the power IC does not provide the
necessary voltage for the highest available MPU frequency (that would
satisfy all Si families). This potentially is an window of opportunity
for things to go wrong.
Signed-off-by: Romit Dasgupta <romit@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
OMAP3: PM: enable 600MHz (overdrive) OPP
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
omap3: introduce cpufreq
OMAP OPP layer functions now have dependencies of CONFIG_CPU_FREQ only.
With this patch, omap opp layer now has its compilation flags
bound to CONFIG_CPU_FREQ. Also its code has been removed from pm34xx.c.
A new file has been created to contain cpu freq code related to
OMAP3: cpufreq34xx.c
OMAP34xx and OMAP36xx family OPPs are made available
Signed-off-by: Eduardo Valentin <eduardo.valentin@nokia.com>
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Romit Dasgupta <romit@ti.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
omap3: cpufreq: allow default opp table init
For board files which choose to override the defaults, the existing
mechanism will work, for boards that would like to work with defaults,
allow init_common_hw to call init_opp_table to initialize if not
already initialized. this will allow all omap boards which have opp
tables predefined for a silicon to use the same.
Originally reported for overo:
http://marc.info/?t=127265269400004&r=1&w=2
Signed-off-by: Nishanth Menon <nm@ti.com>
Reported-by: Peter Tseng <tsenpet09@gmail.com>
Cc: Cliff Brake <cliff.brake@gmail.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
OMAP2: update OPP data to be device based
Cc: Nishanth Menon <nm@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
OMAP3: CPUfreq: update to device-based OPP API
Update usage of OPP API to use new device-based API. This requires
getting the 'struct device' for the MPU and using that with the OPP
API.
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
omap3: opp: make independent of cpufreq
Make opp3xx data which is registered with the opp layer
dependent purely on CONFIG_PM as opp layer and pm.c users
are CONFIG_PM dependent not cpufreq dependent.
so we rename the data definition to opp3xxx_data.c (inline with what
we have for omap2), also move the build definition to be under
the existing CONFIG_PM build instead of CPUFREQ.
Cc: Eduardo Valentin <eduardo.valentin@nokia.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
arch/arm/mach-omap2/clock.h | 14 +++++++++++++-
arch/arm/mach-omap2/clock34xx.c | 2 ++
arch/arm/plat-omap/cpu-omap.c | 35 ++++++++++++++++++++++++++++++++---
3 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 896584e..29b5cf0 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -137,7 +137,9 @@ extern const struct clksel_rate gpt_32k_rates[];
extern const struct clksel_rate gpt_sys_rates[];
extern const struct clksel_rate gfx_l3_rates[];
-#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
+#ifdef CONFIG_CPU_FREQ
+
+#ifdef CONFIG_ARCH_OMAP2
extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
#else
@@ -145,6 +147,16 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
#define omap2_clk_exit_cpufreq_table 0
#endif
+#ifdef CONFIG_ARCH_OMAP3
+extern void omap3_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+extern void omap3_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
+#else
+#define omap3_clk_init_cpufreq_table 0
+#define omap3_clk_exit_cpufreq_table 0
+#endif
+
+#endif /* CONFIG_CPU_FREQ */
+
extern const struct clkops clkops_omap3_noncore_dpll_ops;
#endif
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 287abc4..85d3877 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -20,6 +20,8 @@
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/cpufreq.h>
#include <plat/clock.h>
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index bfa063b..608216b 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -8,6 +8,10 @@
*
* Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
*
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Updated to support OMAP3
+ * 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.
@@ -21,17 +25,25 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/opp.h>
#include <mach/hardware.h>
#include <plat/clock.h>
+#include <plat/common.h>
#include <asm/system.h>
+#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+#include <plat/omap-pm.h>
+#endif
+
#define VERY_HI_RATE 900000000
static struct cpufreq_frequency_table *freq_table;
#ifdef CONFIG_ARCH_OMAP1
#define MPU_CLK "mpu"
+#elif CONFIG_ARCH_OMAP3
+#define MPU_CLK "arm_fck"
#else
#define MPU_CLK "virt_prcm_set"
#endif
@@ -73,7 +85,13 @@ static int omap_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
+#ifdef CONFIG_ARCH_OMAP1
struct cpufreq_freqs freqs;
+#endif
+#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+ unsigned long freq;
+ struct device *mpu_dev = omap2_get_mpuss_device();
+#endif
int ret = 0;
/* Ensure desired rate is within allowed range. Some govenors
@@ -83,13 +101,13 @@ static int omap_target(struct cpufreq_policy *policy,
if (target_freq > policy->max)
target_freq = policy->max;
+#ifdef CONFIG_ARCH_OMAP1
freqs.old = omap_getspeed(0);
freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
freqs.cpu = 0;
if (freqs.old == freqs.new)
return ret;
-
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
#ifdef CONFIG_CPU_FREQ_DEBUG
printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
@@ -97,7 +115,11 @@ static int omap_target(struct cpufreq_policy *policy,
#endif
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
+#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+ freq = target_freq * 1000;
+ if (opp_find_freq_ceil(mpu_dev, &freq))
+ omap_pm_cpu_set_freq(freq);
+#endif
return ret;
}
@@ -114,7 +136,14 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy)
policy->cur = policy->min = policy->max = omap_getspeed(0);
- clk_init_cpufreq_table(&freq_table);
+ if (!cpu_is_omap34xx()) {
+ clk_init_cpufreq_table(&freq_table);
+ } else {
+ struct device *mpu_dev = omap2_get_mpuss_device();
+
+ opp_init_cpufreq_table(mpu_dev, &freq_table);
+ }
+
if (freq_table) {
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
if (!result)
--
1.6.6.1
@@ -1,32 +0,0 @@
From 25ea605d0aaf1d60030b4df122a3384c7878d86e Mon Sep 17 00:00:00 2001
From: Silesh C V <silesh@ti.com>
Date: Wed, 29 Sep 2010 14:52:54 +0530
Subject: [PATCH 05/20] OMAP: PM: CPUFREQ: Fix conditional compilation
Fix conditional compilation. A conditional expresiion
should follow "#elif", in this case #elif clause should
check whether CONFIG_ARCH_OMAP3 is defined or not
(ie. defined(CONFIG_ARCH_OMAP3)) rather than checking for
the value of the macro.
Signed-off-by: Silesh C V <silesh@ti.com>
---
arch/arm/plat-omap/cpu-omap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 608216b..671e4b9 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -42,7 +42,7 @@ static struct cpufreq_frequency_table *freq_table;
#ifdef CONFIG_ARCH_OMAP1
#define MPU_CLK "mpu"
-#elif CONFIG_ARCH_OMAP3
+#elif defined(CONFIG_ARCH_OMAP3)
#define MPU_CLK "arm_fck"
#else
#define MPU_CLK "virt_prcm_set"
--
1.6.6.1
@@ -1,199 +0,0 @@
From a4107498616e8dafa2a0155a6d45a990766b161b Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 29 Oct 2010 20:43:07 +0530
Subject: [PATCH 06/20] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
This patch introduces a user list of devices associated with each
voltage domain instance. The user list is implemented using plist
structure with priority node populated with the voltage values.
This patch also adds an API which will take in a device and
requested voltage as parameters, adds the info to the user list
and returns back the maximum voltage requested by all the user
devices. This can be used anytime to get the voltage that the
voltage domain instance can be transitioned into.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 97 +++++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/voltage.h | 8 +++
2 files changed, 105 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index ed6079c..76c98c6 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -24,6 +24,9 @@
#include <linux/err.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/plist.h>
+#include <linux/slab.h>
#include <plat/common.h>
#include <plat/voltage.h>
@@ -118,6 +121,20 @@ struct vc_reg_info {
};
/**
+ * struct omap_vdd_user_list - The per vdd user list
+ *
+ * @dev: The device asking for the vdd to be set at a particular
+ * voltage
+ * @node: The list head entry
+ * @volt: The voltage requested by the device <dev>
+ */
+struct omap_vdd_user_list {
+ struct device *dev;
+ struct plist_node node;
+ u32 volt;
+};
+
+/**
* omap_vdd_info - Per Voltage Domain info
*
* @volt_data : voltage table having the distinct voltages supported
@@ -132,6 +149,10 @@ struct vc_reg_info {
* shifts, masks etc.
* @voltdm : pointer to the voltage domain structure
* @debug_dir : debug directory for this voltage domain.
+ * @user_lock : the lock to be used by the plist user_list
+ * @user_list : the list head maintaining the various users.
+ * @scaling_mutex : the dvfs muutex.
+ * of this vdd with the voltage requested by each user.
* @curr_volt : current voltage for this vdd.
* @ocp_mod : The prm module for accessing the prm irqstatus reg.
* @prm_irqst_reg : prm irqstatus register.
@@ -146,6 +167,9 @@ struct omap_vdd_info {
struct vc_reg_info vc_reg;
struct voltagedomain voltdm;
struct dentry *debug_dir;
+ spinlock_t user_lock;
+ struct plist_head user_list;
+ struct mutex scaling_mutex;
u32 curr_volt;
u16 ocp_mod;
u8 prm_irqst_reg;
@@ -869,6 +893,11 @@ static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
vdd->write_reg = omap3_voltage_write_reg;
vdd->volt_scale = vp_forceupdate_scale_voltage;
vdd->vp_enabled = false;
+ /* Init the plist */
+ spin_lock_init(&vdd->user_lock);
+ plist_head_init(&vdd->user_list, &vdd->user_lock);
+ /* Init the DVFS mutex */
+ mutex_init(&vdd->scaling_mutex);
/* VC parameters */
vdd->vc_reg.prm_mod = OMAP3430_GR_MOD;
@@ -1059,6 +1088,11 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
vdd->write_reg = omap4_voltage_write_reg;
vdd->volt_scale = vp_forceupdate_scale_voltage;
vdd->vp_enabled = false;
+ /* Init the plist */
+ spin_lock_init(&vdd->user_lock);
+ plist_head_init(&vdd->user_list, &vdd->user_lock);
+ /* Init the DVFS mutex */
+ mutex_init(&vdd->scaling_mutex);
/* VC parameters */
vdd->vc_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
@@ -1171,6 +1205,69 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
return vdd->pmic_info->vsel_to_uv(curr_vsel);
}
+/**
+ * omap_voltage_add_request() - API to keep track of various requests to
+ * scale the VDD and returns the best possible
+ * voltage the VDD can be put to.
+ * @volt_domain: pointer to the voltage domain.
+ * @dev: the device pointer.
+ * @volt: the voltage which is requested by the device.
+ *
+ * This API is to be called before the actual voltage scaling is
+ * done to determine what is the best possible voltage the VDD can
+ * be put to. This API adds the device <dev> in the user list of the
+ * vdd <volt_domain> with <volt> as the requested voltage. The user list
+ * is a plist with the priority element absolute voltage values.
+ * The API then finds the maximum of all the requested voltages for
+ * the VDD and returns it back through <volt> pointer itself.
+ * Returns error value in case of any errors.
+ */
+int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
+ unsigned long *volt)
+{
+ struct omap_vdd_info *vdd;
+ struct omap_vdd_user_list *user;
+ struct plist_node *node;
+ int found = 0;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ mutex_lock(&vdd->scaling_mutex);
+
+ plist_for_each_entry(user, &vdd->user_list, node) {
+ if (user->dev == dev) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ user = kzalloc(sizeof(struct omap_vdd_user_list), GFP_KERNEL);
+ if (!user) {
+ pr_err("%s: Unable to creat a new user for vdd_%s\n",
+ __func__, voltdm->name);
+ mutex_unlock(&vdd->scaling_mutex);
+ return -ENOMEM;
+ }
+ user->dev = dev;
+ } else {
+ plist_del(&user->node, &vdd->user_list);
+ }
+
+ plist_node_init(&user->node, *volt);
+ plist_add(&user->node, &vdd->user_list);
+ node = plist_last(&vdd->user_list);
+ *volt = user->volt = node->prio;
+
+ mutex_unlock(&vdd->scaling_mutex);
+
+ return 0;
+}
/**
* omap_vp_enable() - API to enable a particular VP
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index 0ff1233..bd07eca 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -132,6 +132,9 @@ int omap_voltage_register_pmic(struct voltagedomain *voltdm,
void omap_change_voltscale_method(struct voltagedomain *voltdm,
int voltscale_method);
int omap_voltage_late_init(void);
+int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
+ unsigned long *volt);
+
#else
static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
struct omap_volt_pmic_info *pmic_info) {}
@@ -141,6 +144,11 @@ static inline int omap_voltage_late_init(void)
{
return -EINVAL;
}
+static inline int omap_voltage_add_request(struct voltagedomain *voltdm,
+ struct device *dev, unsigned long *volt)
+{
+ return -EINVAL;
+}
#endif
#endif
--
1.6.6.1
@@ -1,82 +0,0 @@
From dac6c4c03140835b758e32c72eb004d379c35fec Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 29 Oct 2010 20:43:10 +0530
Subject: [PATCH 07/20] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage.
This patch adds an API in the opp layer to get the opp table entry
corresponding to the voltage passed as the parameter.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
drivers/base/power/opp.c | 28 ++++++++++++++++++++++++++++
include/linux/opp.h | 8 ++++++++
2 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index 2bb9b4c..60b4478 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -354,6 +354,34 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)
}
/**
+ * opp_find_voltage() - search for an exact voltage
+ * @dev: device pointer associated with the opp type
+ * @volt: voltage to search for
+ *
+ * Searches for exact match in the opp list and returns handle to the matching
+ * opp if found, else returns ERR_PTR in case of error and should be handled
+ * using IS_ERR.
+ */
+struct opp *opp_find_voltage(struct device *dev, unsigned long volt)
+{
+ struct device_opp *dev_opp;
+ struct opp *temp_opp, *opp = ERR_PTR(-ENODEV);
+
+ dev_opp = find_device_opp(dev);
+ if (IS_ERR(dev_opp))
+ return opp;
+
+ list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) {
+ if (temp_opp->available && temp_opp->u_volt == volt) {
+ opp = temp_opp;
+ break;
+ }
+ }
+
+ return opp;
+}
+
+/**
* opp_add() - Add an OPP table from a table definitions
* @dev: device for which we do this operation
* @freq: Frequency in Hz for this OPP
diff --git a/include/linux/opp.h b/include/linux/opp.h
index 5449945..4977d5c 100644
--- a/include/linux/opp.h
+++ b/include/linux/opp.h
@@ -34,6 +34,8 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq);
struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq);
+struct opp *opp_find_voltage(struct device *dev, unsigned long volt);
+
int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt);
int opp_enable(struct device *dev, unsigned long freq);
@@ -74,6 +76,12 @@ static inline struct opp *opp_find_freq_ceil(struct device *dev,
return ERR_PTR(-EINVAL);
}
+static inline struct opp *opp_find_voltage(struct device *dev,
+ unsigned long volt)
+{
+ return ERR_PTR(-EINVAL);
+}
+
static inline int opp_add(struct device *dev, unsigned long freq,
unsigned long u_volt)
{
--
1.6.6.1
@@ -1,182 +0,0 @@
From 3fcad983e7df504ecb1d0db79e3fe2e3abc44850 Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 29 Oct 2010 20:43:24 +0530
Subject: [PATCH 08/20] OMAP: Introduce API to register a device with a voltagedomain
This patch adds an API in the voltage layer that
can be used during omap_device_build to register the built
device with the voltage domain. This API is to be typically called
only once per device during the device registeration. This approach
makes it easy during dvfs to scale all the devices associated with
a voltage domain and then scale the voltage domain.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 50 +++++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/voltage.h | 7 +++-
arch/arm/plat-omap/omap_device.c | 12 +++++++
3 files changed, 68 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 76c98c6..7381fa6 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -134,6 +134,11 @@ struct omap_vdd_user_list {
u32 volt;
};
+struct omap_vdd_dev_list {
+ struct device *dev;
+ struct list_head node;
+};
+
/**
* omap_vdd_info - Per Voltage Domain info
*
@@ -153,6 +158,7 @@ struct omap_vdd_user_list {
* @user_list : the list head maintaining the various users.
* @scaling_mutex : the dvfs muutex.
* of this vdd with the voltage requested by each user.
+ * @dev_list : list of devices bwlonging to this voltage domain.
* @curr_volt : current voltage for this vdd.
* @ocp_mod : The prm module for accessing the prm irqstatus reg.
* @prm_irqst_reg : prm irqstatus register.
@@ -170,6 +176,7 @@ struct omap_vdd_info {
spinlock_t user_lock;
struct plist_head user_list;
struct mutex scaling_mutex;
+ struct list_head dev_list;
u32 curr_volt;
u16 ocp_mod;
u8 prm_irqst_reg;
@@ -1093,6 +1100,8 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
plist_head_init(&vdd->user_list, &vdd->user_lock);
/* Init the DVFS mutex */
mutex_init(&vdd->scaling_mutex);
+ /* Init the device list */
+ INIT_LIST_HEAD(&vdd->dev_list);
/* VC parameters */
vdd->vc_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
@@ -1269,6 +1278,40 @@ int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
return 0;
}
+int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev)
+{
+ struct omap_vdd_info *vdd;
+ struct omap_vdd_dev_list *temp_dev;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ list_for_each_entry(temp_dev, &vdd->dev_list, node) {
+ if (temp_dev->dev == dev) {
+ dev_warn(dev, "%s: Device already added to vdee_%s\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+ }
+
+ temp_dev = kzalloc(sizeof(struct omap_vdd_dev_list), GFP_KERNEL);
+ if (!temp_dev) {
+ dev_err(dev, "%s: Unable to creat a new device for vdd_%s\n",
+ __func__, voltdm->name);
+ return -ENOMEM;
+ }
+
+ temp_dev->dev = dev;
+
+ list_add(&temp_dev->node, &vdd->dev_list);
+
+ return 0;
+}
+
/**
* omap_vp_enable() - API to enable a particular VP
* @voltdm: pointer to the VDD whose VP is to be enabled.
@@ -1649,6 +1692,8 @@ int __init omap_voltage_late_init(void)
*/
static int __init omap_voltage_early_init(void)
{
+ int i;
+
if (cpu_is_omap34xx()) {
vdd_info = omap3_vdd_info;
nr_scalable_vdd = OMAP3_NR_SCALABLE_VDD;
@@ -1661,8 +1706,13 @@ static int __init omap_voltage_early_init(void)
vdd_data_configure = omap4_vdd_data_configure;
} else {
pr_warning("%s: voltage driver support not added\n", __func__);
+ return -EINVAL;
}
+ /* Init the device list */
+ for (i = 0; i < nr_scalable_vdd; i++)
+ INIT_LIST_HEAD(&(vdd_info[i].dev_list));
+
return 0;
}
core_initcall(omap_voltage_early_init);
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index bd07eca..adbc6af 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -134,7 +134,7 @@ void omap_change_voltscale_method(struct voltagedomain *voltdm,
int omap_voltage_late_init(void);
int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
unsigned long *volt);
-
+int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev);
#else
static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
struct omap_volt_pmic_info *pmic_info) {}
@@ -149,6 +149,11 @@ static inline int omap_voltage_add_request(struct voltagedomain *voltdm,
{
return -EINVAL;
}
+static inline int omap_voltage_add_dev(struct voltagedomain *voltdm,
+ struct device *dev)
+{
+ return -EINVAL;
+}
#endif
#endif
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 57adb27..2c95e61 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -86,6 +86,7 @@
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
+#include <plat/voltage.h>
/* These parameters are passed to _omap_device_{de,}activate() */
#define USE_WAKEUP_LAT 0
@@ -481,6 +482,17 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
for (i = 0; i < oh_cnt; i++) {
hwmods[i]->od = od;
_add_optional_clock_alias(od, hwmods[i]);
+ if (hwmods[i]->vdd_name) {
+ struct omap_hwmod *oh = hwmods[i];
+ struct voltagedomain *voltdm;
+
+ if (is_early_device)
+ continue;
+
+ voltdm = omap_voltage_domain_lookup(oh->vdd_name);
+ if (!omap_voltage_add_dev(voltdm, &od->pdev.dev))
+ oh->voltdm = voltdm;
+ }
}
if (ret)
--
1.6.6.1
@@ -1,120 +0,0 @@
From 6ec7cf889c9a8ddf97fbbcbda4888b0f17930e04 Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 29 Oct 2010 20:43:29 +0530
Subject: [PATCH 09/20] OMAP: Introduce device specific set rate and get rate in omap_device structure
This patch extends the omap_device structure to contain
pointers to scale the operating rate of the
device and to retrieve the operating rate of the device.
This patch also adds the three new APIs in the omap device layer
namely omap_device_set_rate that can be called to set a new operating
rate for a device, omap_device_get_rate that can be called to retrieve
the operating frequency for a device and omap_device_populate_rate_fns
to populte the device specific set_rate and get_rate API's.
The omap_device_set_rate and omap_device_get_rate does some routine error
checks and finally calls into the device specific set_rate
and get_rate APIs populated through omap_device_populate_rate_fns.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/plat-omap/include/plat/omap_device.h | 9 +++++
arch/arm/plat-omap/omap_device.c | 49 +++++++++++++++++++++++++
2 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e4c349f..1178b86 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -50,6 +50,8 @@ extern struct device omap_device_parent;
* @hwmods: (one .. many per omap_device)
* @hwmods_cnt: ARRAY_SIZE() of @hwmods
* @pm_lats: ptr to an omap_device_pm_latency table
+ * @set_rate: fn ptr to change the operating rate.
+ * @get_rate: fn ptr to retrieve the current operating rate.
* @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
* @pm_lat_level: array index of the last odpl entry executed - -1 if never
* @dev_wakeup_lat: dev wakeup latency in nanoseconds
@@ -67,6 +69,8 @@ struct omap_device {
struct platform_device pdev;
struct omap_hwmod **hwmods;
struct omap_device_pm_latency *pm_lats;
+ int (*set_rate)(struct device *dev, unsigned long rate);
+ unsigned long (*get_rate) (struct device *dev);
u32 dev_wakeup_lat;
u32 _dev_wakeup_lat_limit;
u8 pm_lats_cnt;
@@ -108,6 +112,11 @@ int omap_device_align_pm_lat(struct platform_device *pdev,
u32 new_wakeup_lat_limit);
struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
u32 omap_device_get_context_loss_count(struct platform_device *pdev);
+int omap_device_set_rate(struct device *dev, unsigned long freq);
+unsigned long omap_device_get_rate(struct device *dev);
+void omap_device_populate_rate_fns(struct device *dev,
+ int (*set_rate)(struct device *dev, unsigned long rate),
+ unsigned long (*get_rate) (struct device *dev));
/* Other */
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 2c95e61..0d67af6 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -813,6 +813,55 @@ int omap_device_enable_clocks(struct omap_device *od)
return 0;
}
+int omap_device_set_rate(struct device *dev, unsigned long freq)
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+ if (!od->set_rate) {
+ dev_err(dev, "%s: No set_rate API for scaling device\n",
+ __func__);
+ return -ENODATA;
+ }
+
+ return od->set_rate(dev, freq);
+}
+
+unsigned long omap_device_get_rate(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+
+ if (!od->get_rate) {
+ dev_err(dev, "%s: No get rate API for the device\n",
+ __func__);
+ return 0;
+ }
+
+ return od->get_rate(dev);
+}
+
+void omap_device_populate_rate_fns(struct device *dev,
+ int (*set_rate)(struct device *dev, unsigned long rate),
+ unsigned long (*get_rate) (struct device *dev))
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+ od->set_rate = set_rate;
+ od->get_rate = get_rate;
+}
+
struct device omap_device_parent = {
.init_name = "omap",
.parent = &platform_bus,
--
1.6.6.1
@@ -1,134 +0,0 @@
From 96ee5b07e3162056169689b363f4c0edae7d7303 Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 29 Oct 2010 20:43:34 +0530
Subject: [PATCH 10/20] OMAP: Voltage layer changes to support DVFS.
This patch introduces an API to take in the voltage domain and the
new voltage as parameter and to scale all the scalable devices
associated with the the voltage domain to the rate corresponding to the
new voltage and scale the voltage domain to the new voltage.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 69 +++++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/voltage.h | 7 +++
2 files changed, 76 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 7381fa6..9adf9d1 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -27,9 +27,11 @@
#include <linux/spinlock.h>
#include <linux/plist.h>
#include <linux/slab.h>
+#include <linux/opp.h>
#include <plat/common.h>
#include <plat/voltage.h>
+#include <plat/omap_device.h>
#include "prm-regbits-34xx.h"
#include "prm-regbits-44xx.h"
@@ -1656,6 +1658,73 @@ struct voltagedomain *omap_voltage_domain_lookup(char *name)
}
/**
+ * omap_voltage_scale : API to scale the devices associated with a
+ * voltage domain vdd voltage.
+ * @volt_domain : the voltage domain to be scaled
+ * @volt : the new voltage for the voltage domain
+ *
+ * This API runs through the list of devices associated with the
+ * voltage domain and scales the device rates to those corresponding
+ * to the new voltage of the voltage domain. This API also scales
+ * the voltage domain voltage to the new value. Returns 0 on success
+ * else the error value.
+ */
+int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
+{
+ unsigned long curr_volt;
+ int is_volt_scaled = 0;
+ struct omap_vdd_info *vdd;
+ struct omap_vdd_dev_list *temp_dev;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ mutex_lock(&vdd->scaling_mutex);
+
+ curr_volt = omap_voltage_get_nom_volt(voltdm);
+
+ if (curr_volt == volt) {
+ is_volt_scaled = 1;
+ } else if (curr_volt < volt) {
+ omap_voltage_scale_vdd(voltdm, volt);
+ is_volt_scaled = 1;
+ }
+
+ list_for_each_entry(temp_dev, &vdd->dev_list, node) {
+ struct device *dev;
+ struct opp *opp;
+ unsigned long freq;
+
+ dev = temp_dev->dev;
+
+ opp = opp_find_voltage(dev, volt);
+ if (IS_ERR(opp))
+ continue;
+
+ freq = opp_get_freq(opp);
+
+ if (freq == omap_device_get_rate(dev)) {
+ dev_warn(dev, "%s: Already at the requested"
+ "rate %ld\n", __func__, freq);
+ continue;
+ }
+
+ omap_device_set_rate(dev, freq);
+ }
+
+ if (!is_volt_scaled)
+ omap_voltage_scale_vdd(voltdm, volt);
+
+ mutex_unlock(&vdd->scaling_mutex);
+
+ return 0;
+}
+
+/**
* omap_voltage_late_init() - Init the various voltage parameters
*
* This API is to be called in the later stages of the
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index adbc6af..6782c5e 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -135,6 +135,7 @@ int omap_voltage_late_init(void);
int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
unsigned long *volt);
int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev);
+int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt);
#else
static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
struct omap_volt_pmic_info *pmic_info) {}
@@ -154,6 +155,12 @@ static inline int omap_voltage_add_dev(struct voltagedomain *voltdm,
{
return -EINVAL;
}
+
+static inline int omap_voltage_scale(struct voltagedomain *voltdm,
+ unsigned long volt)
+{
+ return -EINVAL;
+}
#endif
#endif
--
1.6.6.1
@@ -1,195 +0,0 @@
From b1b41c78d5a19260605fcb259a51ca7cd71c097a Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 2 Jul 2010 13:06:57 +0530
Subject: [PATCH 11/20] OMAP: Introduce dependent voltage domain support.
There could be dependencies between various voltage domains for
maintaining system performance or hardware limitation reasons
like VDD<X> should be at voltage v1 when VDD<Y> is at voltage v2.
This patch introduce dependent vdd information structures in the
voltage layer which can be used to populate these dependencies
for a voltage domain. This patch also adds support to scale
the dependent vdd and the scalable devices belonging to it
during the scaling of a main vdd through omap_voltage_scale.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 122 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 9adf9d1..c83d968 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -123,6 +123,36 @@ struct vc_reg_info {
};
/**
+ * omap_vdd_dep_volt - Table containing the parent vdd voltage and the
+ * dependent vdd voltage corresponding to it.
+ *
+ * @main_vdd_volt : The main vdd voltage
+ * @dep_vdd_volt : The voltage at which the dependent vdd should be
+ * when the main vdd is at <main_vdd_volt> voltage
+ */
+struct omap_vdd_dep_volt {
+ u32 main_vdd_volt;
+ u32 dep_vdd_volt;
+};
+
+/**
+ * omap_vdd_dep_info - Dependent vdd info
+ *
+ * @name : Dependent vdd name
+ * @voltdm : Dependent vdd pointer
+ * @dep_table : Table containing the dependent vdd voltage
+ * corresponding to every main vdd voltage.
+ * @cur_dep_volt : The voltage to which dependent vdd should be put
+ * to for the current main vdd voltage.
+ */
+struct omap_vdd_dep_info {
+ char *name;
+ struct voltagedomain *voltdm;
+ struct omap_vdd_dep_volt *dep_table;
+ unsigned long cur_dep_volt;
+};
+
+/**
* struct omap_vdd_user_list - The per vdd user list
*
* @dev: The device asking for the vdd to be set at a particular
@@ -174,11 +204,13 @@ struct omap_vdd_info {
struct vp_reg_val vp_reg;
struct vc_reg_info vc_reg;
struct voltagedomain voltdm;
+ struct omap_vdd_dep_info *dep_vdd_info;
struct dentry *debug_dir;
spinlock_t user_lock;
struct plist_head user_list;
struct mutex scaling_mutex;
struct list_head dev_list;
+ int nr_dep_vdd;
u32 curr_volt;
u16 ocp_mod;
u8 prm_irqst_reg;
@@ -1160,6 +1192,80 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
return 0;
}
+static int calc_dep_vdd_volt(struct device *dev,
+ struct omap_vdd_info *main_vdd, unsigned long main_volt)
+{
+ struct omap_vdd_dep_info *dep_vdds;
+ int i, ret = 0;
+
+ if (!main_vdd->dep_vdd_info) {
+ pr_debug("%s: No dependent VDD's for vdd_%s\n",
+ __func__, main_vdd->voltdm.name);
+ return 0;
+ }
+
+ dep_vdds = main_vdd->dep_vdd_info;
+
+ for (i = 0; i < main_vdd->nr_dep_vdd; i++) {
+ struct omap_vdd_dep_volt *volt_table = dep_vdds[i].dep_table;
+ int nr_volt = 0;
+ unsigned long dep_volt = 0, act_volt = 0;
+
+ while (volt_table[nr_volt].main_vdd_volt != 0) {
+ if (volt_table[nr_volt].main_vdd_volt == main_volt) {
+ dep_volt = volt_table[nr_volt].dep_vdd_volt;
+ break;
+ }
+ nr_volt++;
+ }
+ if (!dep_volt) {
+ pr_warning("%s: Not able to find a matching volt for"
+ "vdd_%s corresponding to vdd_%s %ld volt\n",
+ __func__, dep_vdds[i].name,
+ main_vdd->voltdm.name, main_volt);
+ ret = -EINVAL;
+ continue;
+ }
+
+ if (!dep_vdds[i].voltdm)
+ dep_vdds[i].voltdm =
+ omap_voltage_domain_lookup(dep_vdds[i].name);
+
+ act_volt = dep_volt;
+
+ /* See if dep_volt is possible for the vdd*/
+ ret = omap_voltage_add_request(dep_vdds[i].voltdm, dev,
+ &act_volt);
+
+ /*
+ * Currently we do not bother if the dep volt and act volt are
+ * different. We could add a check if needed.
+ */
+ dep_vdds[i].cur_dep_volt = act_volt;
+ }
+
+ return ret;
+}
+
+static int scale_dep_vdd(struct omap_vdd_info *main_vdd)
+{
+ struct omap_vdd_dep_info *dep_vdds;
+ int i;
+
+ if (!main_vdd->dep_vdd_info) {
+ pr_debug("%s: No dependent VDD's for vdd_%s\n",
+ __func__, main_vdd->voltdm.name);
+ return 0;
+ }
+
+ dep_vdds = main_vdd->dep_vdd_info;
+
+ for (i = 0; i < main_vdd->nr_dep_vdd; i++)
+ omap_voltage_scale(dep_vdds[i].voltdm,
+ dep_vdds[i].cur_dep_volt);
+ return 0;
+}
+
/* Public functions */
/**
* omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
@@ -1675,6 +1781,8 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
int is_volt_scaled = 0;
struct omap_vdd_info *vdd;
struct omap_vdd_dev_list *temp_dev;
+ struct plist_node *node;
+ struct omap_vdd_user_list *user;
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
@@ -1687,6 +1795,17 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
curr_volt = omap_voltage_get_nom_volt(voltdm);
+ /* Find the device requesting the voltage scaling */
+ node = plist_first(&vdd->user_list);
+ user = container_of(node, struct omap_vdd_user_list, node);
+
+ /* calculate the voltages for dependent vdd's */
+ if (calc_dep_vdd_volt(user->dev, vdd, volt)) {
+ pr_warning("%s: Error in calculating dependent vdd voltages"
+ "for vdd_%s\n", __func__, voltdm->name);
+ return -EINVAL;
+ }
+
if (curr_volt == volt) {
is_volt_scaled = 1;
} else if (curr_volt < volt) {
@@ -1721,6 +1840,9 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
mutex_unlock(&vdd->scaling_mutex);
+ /* Scale dependent vdds */
+ scale_dep_vdd(vdd);
+
return 0;
}
--
1.6.6.1
@@ -1,134 +0,0 @@
From b461bd17384c73bbb243c54bf1d6466c94e594c3 Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 2 Jul 2010 13:07:35 +0530
Subject: [PATCH 12/20] OMAP: Introduce device scale
This patch adds omap_device_scale API which can be used to generic
device rate scaling.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/plat-omap/include/plat/omap_device.h | 3 +-
arch/arm/plat-omap/omap_device.c | 78 +++++++++++++++++++++++++
2 files changed, 80 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 1178b86..e44a0f7 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -117,6 +117,8 @@ unsigned long omap_device_get_rate(struct device *dev);
void omap_device_populate_rate_fns(struct device *dev,
int (*set_rate)(struct device *dev, unsigned long rate),
unsigned long (*get_rate) (struct device *dev));
+int omap_device_scale(struct device *req_dev, struct device *dev,
+ unsigned long rate);
/* Other */
@@ -126,7 +128,6 @@ int omap_device_enable_hwmods(struct omap_device *od);
int omap_device_disable_clocks(struct omap_device *od);
int omap_device_enable_clocks(struct omap_device *od);
-
/*
* Entries should be kept in latency order ascending
*
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 0d67af6..458d648 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -83,6 +83,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <linux/opp.h>
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
@@ -862,6 +863,83 @@ void omap_device_populate_rate_fns(struct device *dev,
od->get_rate = get_rate;
}
+/**
+ * omap_device_scale() - Set a new rate at which the device is to operate
+ * @req_dev: pointer to the device requesting the scaling.
+ * @dev: pointer to the device that is to be scaled
+ * @rate: the rnew rate for the device.
+ *
+ * This API gets the device opp table associated with this device and
+ * tries putting the device to the requested rate and the voltage domain
+ * associated with the device to the voltage corresponding to the
+ * requested rate. Since multiple devices can be assocciated with a
+ * voltage domain this API finds out the possible voltage the
+ * voltage domain can enter and then decides on the final device
+ * rate. Return 0 on success else the error value
+ */
+int omap_device_scale(struct device *req_dev, struct device *dev,
+ unsigned long rate)
+{
+ struct opp *opp;
+ unsigned long volt, freq, min_freq, max_freq;
+ struct voltagedomain *voltdm;
+ struct platform_device *pdev;
+ struct omap_device *od;
+ int ret;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+ /*
+ * Figure out if the desired frquency lies between the
+ * maximum and minimum possible for the particular device
+ */
+ min_freq = 0;
+ if (IS_ERR(opp_find_freq_ceil(dev, &min_freq))) {
+ dev_err(dev, "%s: Unable to find lowest opp\n", __func__);
+ return -ENODEV;
+ }
+
+ max_freq = ULONG_MAX;
+ if (IS_ERR(opp_find_freq_floor(dev, &max_freq))) {
+ dev_err(dev, "%s: Unable to find highest opp\n", __func__);
+ return -ENODEV;
+ }
+
+ if (rate < min_freq)
+ freq = min_freq;
+ else if (rate > max_freq)
+ freq = max_freq;
+ else
+ freq = rate;
+
+ opp = opp_find_freq_ceil(dev, &freq);
+ if (IS_ERR(opp)) {
+ dev_err(dev, "%s: Unable to find OPP for freq%ld\n",
+ __func__, rate);
+ return -ENODEV;
+ }
+
+ /* Get the voltage corresponding to the requested frequency */
+ volt = opp_get_voltage(opp);
+
+ /*
+ * Call into the voltage layer to get the final voltage possible
+ * for the voltage domain associated with the device.
+ */
+ voltdm = od->hwmods[0]->voltdm;
+ ret = omap_voltage_add_request(voltdm, req_dev, &volt);
+ if (ret) {
+ dev_err(dev, "%s: Unable to get the final volt for scaling\n",
+ __func__);
+ return ret;
+ }
+
+ /* Do the actual scaling */
+ return omap_voltage_scale(voltdm, volt);
+}
+EXPORT_SYMBOL(omap_device_scale);
+
struct device omap_device_parent = {
.init_name = "omap",
.parent = &platform_bus,
--
1.6.6.1
@@ -1,50 +0,0 @@
From 4c68660aa69a5eaeaff7fda7e2297e2d31de0333 Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 2 Jul 2010 13:06:57 +0530
Subject: [PATCH 13/20] OMAP: Disable smartreflex across DVFS
This patch disables smartreflex for a particular voltage
domain when the the voltage domain and the devices belonging
to it is being scaled and re-enables it back once the scaling
is done.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index c83d968..2f331de 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -32,6 +32,7 @@
#include <plat/common.h>
#include <plat/voltage.h>
#include <plat/omap_device.h>
+#include <plat/smartreflex.h>
#include "prm-regbits-34xx.h"
#include "prm-regbits-44xx.h"
@@ -1806,6 +1807,9 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
return -EINVAL;
}
+ /* Disable smartreflex module across voltage and frequency scaling */
+ omap_sr_disable(voltdm);
+
if (curr_volt == volt) {
is_volt_scaled = 1;
} else if (curr_volt < volt) {
@@ -1840,6 +1844,9 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
mutex_unlock(&vdd->scaling_mutex);
+ /* Enable Smartreflex module */
+ omap_sr_enable(voltdm);
+
/* Scale dependent vdds */
scale_dep_vdd(vdd);
--
1.6.6.1
@@ -1,176 +0,0 @@
From 6fb7bd2b3da02e6e799d3c7661a1acb6572f9add Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Wed, 18 Aug 2010 16:22:32 +0530
Subject: [PATCH 14/20] OMAP3: Introduce custom set rate and get rate APIs for scalable devices
This patch also introduces omap3_mpu_set_rate, omap3_iva_set_rate,
omap3_l3_set_rate, omap3_mpu_get_rate, omap3_iva_get_rate,
omap3_l3_get_rate as device specific set rate and get rate
APIs for OMAP3 mpu, iva and l3_main devices. This patch also
calls into omap_device_populate_rate_fns during system init to register
various set_rate and get_rate APIs with the omap device layer
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/pm.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 110 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index d5a102c..94ab0dd 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -14,6 +14,7 @@
#include <linux/io.h>
#include <linux/err.h>
#include <linux/opp.h>
+#include <linux/delay.h>
#include <plat/omap-pm.h>
#include <plat/omap_device.h>
@@ -22,6 +23,8 @@
#include "powerdomain.h"
#include "clockdomain.h"
+#include "cm-regbits-34xx.h"
+#include "cm2xxx_3xxx.h"
#include "pm.h"
static struct omap_device_pm_latency *pm_lats;
@@ -31,6 +34,8 @@ static struct device *iva_dev;
static struct device *l3_dev;
static struct device *dsp_dev;
+static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
+
struct device *omap2_get_mpuss_device(void)
{
WARN_ON_ONCE(!mpu_dev);
@@ -56,6 +61,26 @@ struct device *omap4_get_dsp_device(void)
}
EXPORT_SYMBOL(omap4_get_dsp_device);
+static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
+{
+ unsigned long new_jiffy_l, new_jiffy_h;
+
+ /*
+ * Recalculate loops_per_jiffy. We do it this way to
+ * avoid math overflow on 32-bit machines. Maybe we
+ * should make this architecture dependent? If you have
+ * a better way of doing this, please replace!
+ *
+ * new = old * mult / div
+ */
+ new_jiffy_h = ref / div;
+ new_jiffy_l = (ref % div) / 100;
+ new_jiffy_h *= mult;
+ new_jiffy_l = new_jiffy_l * mult / div;
+
+ return new_jiffy_h + new_jiffy_l * 100;
+}
+
/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
static int _init_omap_device(char *name, struct device **new_dev)
{
@@ -77,6 +102,74 @@ static int _init_omap_device(char *name, struct device **new_dev)
return 0;
}
+static unsigned long omap3_mpu_get_rate(struct device *dev)
+{
+ return dpll1_clk->rate;
+}
+
+static int omap3_mpu_set_rate(struct device *dev, unsigned long rate)
+{
+ unsigned long cur_rate = omap3_mpu_get_rate(dev);
+ int ret;
+
+#ifdef CONFIG_CPU_FREQ
+ struct cpufreq_freqs freqs_notify;
+
+ freqs_notify.old = cur_rate / 1000;
+ freqs_notify.new = rate / 1000;
+ freqs_notify.cpu = 0;
+ /* Send pre notification to CPUFreq */
+ cpufreq_notify_transition(&freqs_notify, CPUFREQ_PRECHANGE);
+#endif
+ ret = clk_set_rate(dpll1_clk, rate);
+ if (ret) {
+ dev_warn(dev, "%s: Unable to set rate to %ld\n",
+ __func__, rate);
+ return ret;
+ }
+
+#ifdef CONFIG_CPU_FREQ
+ /* Send a post notification to CPUFreq */
+ cpufreq_notify_transition(&freqs_notify, CPUFREQ_POSTCHANGE);
+#endif
+
+#ifndef CONFIG_CPU_FREQ
+ /*Update loops_per_jiffy if processor speed is being changed*/
+ loops_per_jiffy = compute_lpj(loops_per_jiffy,
+ cur_rate / 1000, rate / 1000);
+#endif
+ return 0;
+}
+
+static int omap3_iva_set_rate(struct device *dev, unsigned long rate)
+{
+ return clk_set_rate(dpll2_clk, rate);
+}
+
+static unsigned long omap3_iva_get_rate(struct device *dev)
+{
+ return dpll2_clk->rate;
+}
+
+static int omap3_l3_set_rate(struct device *dev, unsigned long rate)
+{
+ int l3_div;
+
+ l3_div = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+ OMAP3430_CLKSEL_L3_MASK;
+
+ return clk_set_rate(dpll3_clk, rate * l3_div);
+}
+
+static unsigned long omap3_l3_get_rate(struct device *dev)
+{
+ int l3_div;
+
+ l3_div = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+ OMAP3430_CLKSEL_L3_MASK;
+ return dpll3_clk->rate / l3_div;
+}
+
/*
* Build omap_devices for processors and bus.
*/
@@ -90,6 +183,23 @@ static void omap2_init_processor_devices(void)
} else {
_init_omap_device("l3_main", &l3_dev);
}
+
+ if (cpu_is_omap34xx()) {
+ dpll1_clk = clk_get(NULL, "dpll1_ck");
+ dpll2_clk = clk_get(NULL, "dpll2_ck");
+ dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
+
+ if (mpu_dev)
+ omap_device_populate_rate_fns(mpu_dev,
+ omap3_mpu_set_rate, omap3_mpu_get_rate);
+ if (iva_dev)
+ omap_device_populate_rate_fns(iva_dev,
+ omap3_iva_set_rate, omap3_iva_get_rate);
+ if (l3_dev)
+ omap_device_populate_rate_fns(l3_dev,
+ omap3_l3_set_rate, omap3_l3_get_rate);
+
+ }
}
/* Types of sleep_switch used in omap_set_pwrdm_state */
--
1.6.6.1
@@ -1,54 +0,0 @@
From d8fae1dcedb636a37096ee92e6b81b112d5f32a5 Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Fri, 2 Jul 2010 13:07:49 +0530
Subject: [PATCH 15/20] OMAP3: Update cpufreq driver to use the new set_rate API
This patch updates the cpufreq driver to use the device
set rate API to scale the mpu frequency for OMAP3.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/plat-omap/cpu-omap.c | 11 ++++-------
1 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 671e4b9..71777db 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -31,10 +31,7 @@
#include <plat/clock.h>
#include <plat/common.h>
#include <asm/system.h>
-
-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
-#include <plat/omap-pm.h>
-#endif
+#include <plat/omap_device.h>
#define VERY_HI_RATE 900000000
@@ -88,7 +85,7 @@ static int omap_target(struct cpufreq_policy *policy,
#ifdef CONFIG_ARCH_OMAP1
struct cpufreq_freqs freqs;
#endif
-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+#if defined(CONFIG_ARCH_OMAP3)
unsigned long freq;
struct device *mpu_dev = omap2_get_mpuss_device();
#endif
@@ -115,10 +112,10 @@ static int omap_target(struct cpufreq_policy *policy,
#endif
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+#elif defined(CONFIG_ARCH_OMAP3)
freq = target_freq * 1000;
if (opp_find_freq_ceil(mpu_dev, &freq))
- omap_pm_cpu_set_freq(freq);
+ omap_device_scale(mpu_dev, mpu_dev, freq);
#endif
return ret;
}
--
1.6.6.1
@@ -1,45 +0,0 @@
From b54b316174e1d59a820e68c45c4abfc1336d8e09 Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Wed, 18 Aug 2010 16:22:43 +0530
Subject: [PATCH 16/20] OMAP3: Introduce voltage domain info in the hwmod structures.
This patch adds voltage domain info in the relevant
device hwmod structures so as to enable OMAP3 DVFS
support.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 8d81813..c57f34d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -94,6 +94,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
static struct omap_hwmod omap3xxx_l3_main_hwmod = {
.name = "l3_main",
.class = &l3_hwmod_class,
+ .vdd_name = "core",
.masters = omap3xxx_l3_main_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters),
.slaves = omap3xxx_l3_main_slaves,
@@ -384,6 +385,7 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
.name = "mpu",
.class = &mpu_hwmod_class,
.main_clk = "arm_fck",
+ .vdd_name = "mpu",
.masters = omap3xxx_mpu_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_mpu_masters),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -412,6 +414,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_iva_masters[] = {
static struct omap_hwmod omap3xxx_iva_hwmod = {
.name = "iva",
.class = &iva_hwmod_class,
+ .vdd_name = "mpu",
.masters = omap3xxx_iva_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_iva_masters),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
--
1.6.6.1
@@ -1,61 +0,0 @@
From c196a4ac3941fb9af4654d5d028ad21f4b91d721 Mon Sep 17 00:00:00 2001
From: Thara Gopinath <thara@ti.com>
Date: Wed, 18 Aug 2010 16:22:49 +0530
Subject: [PATCH 17/20] OMAP3: Add voltage dependency table for VDD1.
In OMAP3, for perfomrance reasons when VDD1 is at voltage above
1.075V, VDD2 should be at 1.15V for perfomrance reasons. This
patch introduce this cross VDD dependency for OMAP3 VDD1.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 24 ++++++++++++++++++++++--
1 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 2f331de..d10cb1b 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -374,6 +374,23 @@ static struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
VOLT_DATA_DEFINE(0, 0, 0, 0),
};
+/* OMAP 3430 MPU Core VDD dependency table */
+static struct omap_vdd_dep_volt omap34xx_vdd1_vdd2_data[] = {
+ {.main_vdd_volt = 975000, .dep_vdd_volt = 1050000},
+ {.main_vdd_volt = 1075000, .dep_vdd_volt = 1050000},
+ {.main_vdd_volt = 1200000, .dep_vdd_volt = 1150000},
+ {.main_vdd_volt = 1270000, .dep_vdd_volt = 1150000},
+ {.main_vdd_volt = 1350000, .dep_vdd_volt = 1150000},
+ {.main_vdd_volt = 0, .dep_vdd_volt = 0},
+};
+
+static struct omap_vdd_dep_info omap34xx_vdd1_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap34xx_vdd1_vdd2_data,
+ },
+};
+
static struct dentry *voltage_dir;
/* Init function pointers */
@@ -879,10 +896,13 @@ static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
}
if (!strcmp(vdd->voltdm.name, "mpu")) {
- if (cpu_is_omap3630())
+ if (cpu_is_omap3630()) {
vdd->volt_data = omap36xx_vddmpu_volt_data;
- else
+ } else {
vdd->volt_data = omap34xx_vddmpu_volt_data;
+ vdd->dep_vdd_info = omap34xx_vdd1_dep_info;
+ vdd->nr_dep_vdd = ARRAY_SIZE(omap34xx_vdd1_dep_info);
+ }
vdd->vp_reg.tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK;
vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET;
--
1.6.6.1
@@ -1,62 +0,0 @@
From 16c7667d2908631149ef38b7b6dd7b08d6d5502e Mon Sep 17 00:00:00 2001
From: Nishanth Menon <nm@ti.com>
Date: Wed, 5 Jan 2011 14:14:55 -0600
Subject: [PATCH 18/20] omap3|4: opp: make omapx_opp_init non-static
omap3 and omap4 opp_init should be made non-static to allow
for platform specific opp table tweaking. making these static
conflicts with the definition in pm.h(global) as well.
we include pm.h as well to ensure that there are no such prototype
conflicts with actual implementation in the future.
Signed-off-by: Nishanth Menon <nm@ti.com>
---
arch/arm/mach-omap2/opp3xxx_data.c | 3 ++-
arch/arm/mach-omap2/opp4xxx_data.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
index 0486fce..fd3a1af 100644
--- a/arch/arm/mach-omap2/opp3xxx_data.c
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -21,6 +21,7 @@
#include <plat/cpu.h>
#include "omap_opp_data.h"
+#include "pm.h"
static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
/* MPU OPP1 */
@@ -88,7 +89,7 @@ static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
/**
* omap3_opp_init() - initialize omap3 opp table
*/
-static int __init omap3_opp_init(void)
+int __init omap3_opp_init(void)
{
int r = -ENODEV;
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
index a11fa56..f0e9939 100644
--- a/arch/arm/mach-omap2/opp4xxx_data.c
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -22,6 +22,7 @@
#include <plat/cpu.h>
#include "omap_opp_data.h"
+#include "pm.h"
static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
@@ -42,7 +43,7 @@ static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
/**
* omap4_opp_init() - initialize omap4 opp table
*/
-static int __init omap4_opp_init(void)
+int __init omap4_opp_init(void)
{
int r = -ENODEV;
--
1.6.6.1
@@ -1,107 +0,0 @@
From 897e90138695dccac0dca1601542fd5f4c85b657 Mon Sep 17 00:00:00 2001
From: Nishanth Menon <nm@ti.com>
Date: Wed, 5 Jan 2011 14:16:59 -0600
Subject: [PATCH 19/20] OMAP3: beagle xm: enable upto 1GHz OPP
Beagle XM uses 3730 and the board design allows enabling 800MHz and 1GHz
OPPs. tweak the default table to allow for higher OPP tables
Reported-by: Koen Kooi <koen@beagleboard.org>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
arch/arm/mach-omap2/board-omap3beagle.c | 54 +++++++++++++++++++++++++++++++
1 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index ad0c1d8..1e0870e 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -24,6 +24,7 @@
#include <linux/irq.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
+#include <linux/opp.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -45,10 +46,12 @@
#include <plat/gpmc.h>
#include <plat/nand.h>
#include <plat/usb.h>
+#include <plat/omap_device.h>
#include "mux.h"
#include "hsmmc.h"
#include "timer-gp.h"
+#include "pm.h"
#define NAND_BLOCK_SIZE SZ_128K
@@ -804,6 +807,56 @@ static int __init expansionboard_setup(char *str)
return 0;
}
+static void __init beagle_opp_init(void)
+{
+ int r = 0;
+
+ /* Initialize the omap3 opp table */
+ if (omap3_opp_init()) {
+ pr_err("%s: opp default init failed\n", __func__);
+ return;
+ }
+
+ /* Custom OPP enabled for XM */
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
+ struct omap_hwmod *dh = omap_hwmod_lookup("iva");
+ struct device *dev;
+
+ if (!mh || !dh) {
+ pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
+ __func__, mh, dh);
+ r = -EINVAL;
+ } else {
+ /* Enable MPU 1GHz and lower opps */
+ dev = &mh->od->pdev.dev;
+ r = opp_enable(dev, 800000000);
+ r |= opp_enable(dev, 1000000000);
+
+ /* Enable IVA 800MHz and lower opps */
+ dev = &dh->od->pdev.dev;
+ r |= opp_enable(dev, 660000000);
+ r |= opp_enable(dev, 800000000);
+ }
+ if (r) {
+ pr_err("%s: failed to enable higher opp %d\n",
+ __func__, r);
+ /*
+ * Cleanup - disable the higher freqs - we dont care
+ * about the results
+ */
+ dev = &mh->od->pdev.dev;
+ opp_disable(dev, 800000000);
+ opp_disable(dev, 1000000000);
+ dev = &dh->od->pdev.dev;
+ opp_disable(dev, 660000000);
+ opp_disable(dev, 800000000);
+ } else {
+ pr_err("%s: turbo OPPs enabled!\n", __func__);
+ }
+ }
+}
+
static void __init omap3_beagle_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -876,6 +929,7 @@ static void __init omap3_beagle_init(void)
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
beagle_display_init();
+ beagle_opp_init();
}
early_param("buddy", expansionboard_setup);
--
1.6.6.1
@@ -1,202 +0,0 @@
From bb655c594a2f77b17d0747116795f46e00d5ffcb Mon Sep 17 00:00:00 2001
From: Sanjeev Premi <premi@ti.com>
Date: Tue, 18 Jan 2011 13:19:55 +0530
Subject: [PATCH 20/20] omap3: Add basic support for 720MHz part
This patch adds support for new speed enhanced parts with ARM
and IVA running at 720MHz and 520MHz respectively. These parts
can be probed at run-time by reading PRODID.SKUID[3:0] at
0x4830A20C [1].
This patch specifically does following:
* Detect devices capable of 720MHz.
* Add new OPP
* Ensure that OPP is conditionally enabled.
* Check for presence of IVA before attempting to enable
the corresponding OPP.
[1] http://focus.ti.com/lit/ug/spruff1d/spruff1d.pdf
Signed-off-by: Sanjeev Premi <premi@ti.com>
---
arch/arm/mach-omap2/control.h | 7 ++++
arch/arm/mach-omap2/id.c | 10 +++++
arch/arm/mach-omap2/opp3xxx_data.c | 63 ++++++++++++++++++++++++++++++++-
arch/arm/plat-omap/include/plat/cpu.h | 2 +
4 files changed, 81 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index f0629ae..eebc045 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -365,6 +365,13 @@
#define FEAT_NEON 0
#define FEAT_NEON_NONE 1
+/*
+ * Product ID register
+ */
+#define OMAP3_PRODID 0x020C
+
+#define OMAP3_SKUID_MASK 0x0f
+#define OMAP3_SKUID_720MHZ 0x08
#ifndef __ASSEMBLY__
#ifdef CONFIG_ARCH_OMAP2PLUS
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 5f9086c..53fbe01 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -195,6 +195,15 @@ static void __init omap3_check_features(void)
* TODO: Get additional info (where applicable)
* e.g. Size of L2 cache.
*/
+
+ /*
+ * Does it support 720MHz?
+ */
+ status = (OMAP3_SKUID_MASK & read_tap_reg(OMAP3_PRODID));
+
+ if (status & OMAP3_SKUID_720MHZ) {
+ omap3_features |= OMAP3_HAS_720MHZ;
+ }
}
static void __init omap3_check_revision(void)
@@ -445,6 +454,7 @@ static void __init omap3_cpuinfo(void)
OMAP3_SHOW_FEATURE(neon);
OMAP3_SHOW_FEATURE(isp);
OMAP3_SHOW_FEATURE(192mhz_clk);
+ OMAP3_SHOW_FEATURE(720mhz);
printk(")\n");
}
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
index fd3a1af..76d26c7 100644
--- a/arch/arm/mach-omap2/opp3xxx_data.c
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -17,8 +17,10 @@
* GNU General Public License for more details.
*/
#include <linux/module.h>
+#include <linux/opp.h>
#include <plat/cpu.h>
+#include <plat/omap_device.h>
#include "omap_opp_data.h"
#include "pm.h"
@@ -34,6 +36,8 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
OPP_INITIALIZER("mpu", true, 550000000, 1270000),
/* MPU OPP5 */
OPP_INITIALIZER("mpu", true, 600000000, 1350000),
+ /* MPU OPP6 */
+ OPP_INITIALIZER("mpu", false, 720000000, 1350000),
/*
* L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
@@ -59,6 +63,8 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
OPP_INITIALIZER("iva", true, 400000000, 1270000),
/* DSP OPP5 */
OPP_INITIALIZER("iva", true, 430000000, 1350000),
+ /* DSP OPP6 */
+ OPP_INITIALIZER("iva", false, 520000000, 1350000),
};
static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
@@ -86,6 +92,57 @@ static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
OPP_INITIALIZER("iva", false, 800000000, 1375000),
};
+
+/**
+ * omap3_opp_enable_720Mhz() - Enable the OPP corresponding to 720MHz
+ *
+ * This function would be executed only if the silicon is capable of
+ * running at the 720MHz.
+ */
+static int __init omap3_opp_enable_720Mhz(void)
+{
+ int r = -ENODEV;
+ struct omap_hwmod *oh_mpu = omap_hwmod_lookup("mpu");
+ struct omap_hwmod *oh_iva;
+ struct platform_device *pdev;
+
+ if (!oh_mpu || !oh_mpu->od) {
+ goto err;
+ } else {
+ pdev = &oh_mpu->od->pdev;
+
+ r = opp_enable(&pdev->dev, 720000000);
+ if (r < 0) {
+ dev_err(&pdev->dev,
+ "opp_enable() failed for mpu@720MHz");
+ goto err;
+ }
+ }
+
+ if (omap3_has_iva()) {
+ oh_iva = omap_hwmod_lookup("iva");
+
+ if (!oh_iva || !oh_iva->od) {
+ r = -ENODEV;
+ goto err;
+ } else {
+ pdev = &oh_iva->od->pdev;
+
+ r = opp_enable(&pdev->dev, 520000000);
+ if (r < 0) {
+ dev_err(&pdev->dev,
+ "opp_enable() failed for iva@520MHz");
+ goto err;
+ }
+ }
+ }
+
+ dev_info(&pdev->dev, "Enabled OPP corresponding to 720MHz\n");
+
+err:
+ return r;
+}
+
/**
* omap3_opp_init() - initialize omap3 opp table
*/
@@ -99,10 +156,14 @@ int __init omap3_opp_init(void)
if (cpu_is_omap3630())
r = omap_init_opp_table(omap36xx_opp_def_list,
ARRAY_SIZE(omap36xx_opp_def_list));
- else
+ else {
r = omap_init_opp_table(omap34xx_opp_def_list,
ARRAY_SIZE(omap34xx_opp_def_list));
+ if (omap3_has_720mhz())
+ r = omap3_opp_enable_720Mhz();
+ }
+
return r;
}
device_initcall(omap3_opp_init);
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 1a8c347..7d24faa 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -510,6 +510,7 @@ extern u32 omap3_features;
#define OMAP3_HAS_ISP BIT(4)
#define OMAP3_HAS_192MHZ_CLK BIT(5)
#define OMAP3_HAS_IO_WAKEUP BIT(6)
+#define OMAP3_HAS_720MHZ BIT(7)
#define OMAP3_HAS_FEATURE(feat,flag) \
static inline unsigned int omap3_has_ ##feat(void) \
@@ -524,5 +525,6 @@ OMAP3_HAS_FEATURE(neon, NEON)
OMAP3_HAS_FEATURE(isp, ISP)
OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
+OMAP3_HAS_FEATURE(720mhz, 720MHZ)
#endif
--
1.6.6.1
@@ -1,29 +0,0 @@
From 679fd7bc2af7980a4b9360ff42f515c3cc4e3674 Mon Sep 17 00:00:00 2001
From: Lennert Buytenhek <buytenh@wantstofly.org>
Date: Wed, 15 Dec 2010 07:20:16 +0800
Subject: [PATCH 01/65] ARM: pxa: PXA_ESERIES depends on FB_W100.
As arch/arm/mach-pxa/eseries.c references w100fb_gpio_{read,write}()
directly.
Signed-off-by: Lennert Buytenhek <buytenh@secretlab.ca>
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
---
arch/arm/mach-pxa/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index dd235ec..c93e73d 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -540,6 +540,7 @@ config MACH_ICONTROL
config ARCH_PXA_ESERIES
bool "PXA based Toshiba e-series PDAs"
select PXA25x
+ select FB_W100
config MACH_E330
bool "Toshiba e330"
--
1.6.6.1
@@ -1,32 +0,0 @@
From d7bbfe094baebc1515d3919a1e886fcfa655ff5a Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@arm.linux.org.uk>
Date: Sat, 18 Dec 2010 13:57:00 +0000
Subject: [PATCH 02/65] ARM: smp: avoid incrementing mm_users on CPU startup
We should not be incrementing mm_users when we startup a secondary
CPU - doing so results in mm_users incrementing by one each time we
hotplug a CPU, which will eventually wrap, and will cause problems.
Other architectures such as x86 do not increment mm_users, but only
mm_count, so we follow that pattern.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/kernel/smp.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 8c19595..9066473 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -310,7 +310,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
* All kernel threads share the same mm context; grab a
* reference and switch to it.
*/
- atomic_inc(&mm->mm_users);
atomic_inc(&mm->mm_count);
current->active_mm = mm;
cpumask_set_cpu(cpu, mm_cpumask(mm));
--
1.6.6.1
@@ -1,186 +0,0 @@
From b4edc88b911049a85162600f579d0364ee311d4e Mon Sep 17 00:00:00 2001
From: Nicolas Pitre <nicolas.pitre@linaro.org>
Date: Wed, 15 Dec 2010 15:14:45 -0500
Subject: [PATCH 03/65] ARM: get rid of kmap_high_l1_vipt()
Since commit 3e4d3af501 "mm: stack based kmap_atomic()", it is no longer
necessary to carry an ad hoc version of kmap_atomic() added in commit
7e5a69e83b "ARM: 6007/1: fix highmem with VIPT cache and DMA" to cope
with reentrancy.
In fact, it is now actively wrong to rely on fixed kmap type indices
(namely KM_L1_CACHE) as kmap_atomic() totally ignores them now and a
concurrent instance of it may reuse any slot for any purpose.
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
---
arch/arm/include/asm/highmem.h | 3 -
arch/arm/mm/dma-mapping.c | 7 ++-
arch/arm/mm/flush.c | 7 ++-
arch/arm/mm/highmem.c | 87 ----------------------------------------
4 files changed, 8 insertions(+), 96 deletions(-)
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 1fc684e..7080e2c 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -25,9 +25,6 @@ extern void *kmap_high(struct page *page);
extern void *kmap_high_get(struct page *page);
extern void kunmap_high(struct page *page);
-extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
-extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
-
/*
* The following functions are already defined by <linux/highmem.h>
* when CONFIG_HIGHMEM is not set.
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ac6a361..809f1bf 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <linux/highmem.h>
#include <asm/memory.h>
#include <asm/highmem.h>
@@ -480,10 +481,10 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
op(vaddr, len, dir);
kunmap_high(page);
} else if (cache_is_vipt()) {
- pte_t saved_pte;
- vaddr = kmap_high_l1_vipt(page, &saved_pte);
+ /* unmapped pages might still be cached */
+ vaddr = kmap_atomic(page);
op(vaddr + offset, len, dir);
- kunmap_high_l1_vipt(page, saved_pte);
+ kunmap_atomic(vaddr);
}
} else {
vaddr = page_address(page) + offset;
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 391ffae..c29f283 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
+#include <linux/highmem.h>
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
@@ -180,10 +181,10 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
__cpuc_flush_dcache_area(addr, PAGE_SIZE);
kunmap_high(page);
} else if (cache_is_vipt()) {
- pte_t saved_pte;
- addr = kmap_high_l1_vipt(page, &saved_pte);
+ /* unmapped pages might still be cached */
+ addr = kmap_atomic(page);
__cpuc_flush_dcache_area(addr, PAGE_SIZE);
- kunmap_high_l1_vipt(page, saved_pte);
+ kunmap_atomic(addr);
}
}
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index c435fd9..807c057 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -140,90 +140,3 @@ struct page *kmap_atomic_to_page(const void *ptr)
pte = TOP_PTE(vaddr);
return pte_page(*pte);
}
-
-#ifdef CONFIG_CPU_CACHE_VIPT
-
-#include <linux/percpu.h>
-
-/*
- * The VIVT cache of a highmem page is always flushed before the page
- * is unmapped. Hence unmapped highmem pages need no cache maintenance
- * in that case.
- *
- * However unmapped pages may still be cached with a VIPT cache, and
- * it is not possible to perform cache maintenance on them using physical
- * addresses unfortunately. So we have no choice but to set up a temporary
- * virtual mapping for that purpose.
- *
- * Yet this VIPT cache maintenance may be triggered from DMA support
- * functions which are possibly called from interrupt context. As we don't
- * want to keep interrupt disabled all the time when such maintenance is
- * taking place, we therefore allow for some reentrancy by preserving and
- * restoring the previous fixmap entry before the interrupted context is
- * resumed. If the reentrancy depth is 0 then there is no need to restore
- * the previous fixmap, and leaving the current one in place allow it to
- * be reused the next time without a TLB flush (common with DMA).
- */
-
-static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
-
-void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
-{
- unsigned int idx, cpu;
- int *depth;
- unsigned long vaddr, flags;
- pte_t pte, *ptep;
-
- if (!in_interrupt())
- preempt_disable();
-
- cpu = smp_processor_id();
- depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
-
- idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
- vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
- ptep = TOP_PTE(vaddr);
- pte = mk_pte(page, kmap_prot);
-
- raw_local_irq_save(flags);
- (*depth)++;
- if (pte_val(*ptep) == pte_val(pte)) {
- *saved_pte = pte;
- } else {
- *saved_pte = *ptep;
- set_pte_ext(ptep, pte, 0);
- local_flush_tlb_kernel_page(vaddr);
- }
- raw_local_irq_restore(flags);
-
- return (void *)vaddr;
-}
-
-void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
-{
- unsigned int idx, cpu = smp_processor_id();
- int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
- unsigned long vaddr, flags;
- pte_t pte, *ptep;
-
- idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
- vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
- ptep = TOP_PTE(vaddr);
- pte = mk_pte(page, kmap_prot);
-
- BUG_ON(pte_val(*ptep) != pte_val(pte));
- BUG_ON(*depth <= 0);
-
- raw_local_irq_save(flags);
- (*depth)--;
- if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
- set_pte_ext(ptep, saved_pte, 0);
- local_flush_tlb_kernel_page(vaddr);
- }
- raw_local_irq_restore(flags);
-
- if (!in_interrupt())
- preempt_enable();
-}
-
-#endif /* CONFIG_CPU_CACHE_VIPT */
--
1.6.6.1
@@ -1,189 +0,0 @@
From fc077c0fbb09ca255691d05789076d121ae11789 Mon Sep 17 00:00:00 2001
From: Nicolas Pitre <nicolas.pitre@linaro.org>
Date: Wed, 15 Dec 2010 23:29:04 -0500
Subject: [PATCH 04/65] ARM: fix cache-xsc3l2 after stack based kmap_atomic()
Since commit 3e4d3af501 "mm: stack based kmap_atomic()", it is actively
wrong to rely on fixed kmap type indices (namely KM_L2_CACHE) as
kmap_atomic() totally ignores them and a concurrent instance of it may
happily reuse any slot for any purpose. Because kmap_atomic() is now
able to deal with reentrancy, we can get rid of the ad hoc mapping here,
and we even don't have to disable IRQs anymore (highmem case).
While the code is made much simpler, there is a needless cache flush
introduced by the usage of __kunmap_atomic(). It is not clear if the
performance difference to remove that is worth the cost in code
maintenance (I don't think there are that many highmem users on that
platform if at all anyway).
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
---
arch/arm/mm/cache-xsc3l2.c | 57 ++++++++++++++++---------------------------
1 files changed, 21 insertions(+), 36 deletions(-)
diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
index c315492..5a32020 100644
--- a/arch/arm/mm/cache-xsc3l2.c
+++ b/arch/arm/mm/cache-xsc3l2.c
@@ -17,14 +17,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
+#include <linux/highmem.h>
#include <asm/system.h>
#include <asm/cputype.h>
#include <asm/cacheflush.h>
-#include <asm/kmap_types.h>
-#include <asm/fixmap.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-#include "mm.h"
#define CR_L2 (1 << 26)
@@ -71,16 +67,15 @@ static inline void xsc3_l2_inv_all(void)
dsb();
}
+static inline void l2_unmap_va(unsigned long va)
+{
#ifdef CONFIG_HIGHMEM
-#define l2_map_save_flags(x) raw_local_save_flags(x)
-#define l2_map_restore_flags(x) raw_local_irq_restore(x)
-#else
-#define l2_map_save_flags(x) ((x) = 0)
-#define l2_map_restore_flags(x) ((void)(x))
+ if (va != -1)
+ kunmap_atomic((void *)va);
#endif
+}
-static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
- unsigned long flags)
+static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va)
{
#ifdef CONFIG_HIGHMEM
unsigned long va = prev_va & PAGE_MASK;
@@ -89,17 +84,10 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
/*
* Switching to a new page. Because cache ops are
* using virtual addresses only, we must put a mapping
- * in place for it. We also enable interrupts for a
- * short while and disable them again to protect this
- * mapping.
+ * in place for it.
*/
- unsigned long idx;
- raw_local_irq_restore(flags);
- idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
- va = __fix_to_virt(FIX_KMAP_BEGIN + idx);
- raw_local_irq_restore(flags | PSR_I_BIT);
- set_pte_ext(TOP_PTE(va), pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL), 0);
- local_flush_tlb_kernel_page(va);
+ l2_unmap_va(prev_va);
+ va = (unsigned long)kmap_atomic_pfn(pa >> PAGE_SHIFT);
}
return va + (pa_offset >> (32 - PAGE_SHIFT));
#else
@@ -109,7 +97,7 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
{
- unsigned long vaddr, flags;
+ unsigned long vaddr;
if (start == 0 && end == -1ul) {
xsc3_l2_inv_all();
@@ -117,13 +105,12 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
}
vaddr = -1; /* to force the first mapping */
- l2_map_save_flags(flags);
/*
* Clean and invalidate partial first cache line.
*/
if (start & (CACHE_LINE_SIZE - 1)) {
- vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr, flags);
+ vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr);
xsc3_l2_clean_mva(vaddr);
xsc3_l2_inv_mva(vaddr);
start = (start | (CACHE_LINE_SIZE - 1)) + 1;
@@ -133,7 +120,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
* Invalidate all full cache lines between 'start' and 'end'.
*/
while (start < (end & ~(CACHE_LINE_SIZE - 1))) {
- vaddr = l2_map_va(start, vaddr, flags);
+ vaddr = l2_map_va(start, vaddr);
xsc3_l2_inv_mva(vaddr);
start += CACHE_LINE_SIZE;
}
@@ -142,31 +129,30 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
* Clean and invalidate partial last cache line.
*/
if (start < end) {
- vaddr = l2_map_va(start, vaddr, flags);
+ vaddr = l2_map_va(start, vaddr);
xsc3_l2_clean_mva(vaddr);
xsc3_l2_inv_mva(vaddr);
}
- l2_map_restore_flags(flags);
+ l2_unmap_va(vaddr);
dsb();
}
static void xsc3_l2_clean_range(unsigned long start, unsigned long end)
{
- unsigned long vaddr, flags;
+ unsigned long vaddr;
vaddr = -1; /* to force the first mapping */
- l2_map_save_flags(flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
- vaddr = l2_map_va(start, vaddr, flags);
+ vaddr = l2_map_va(start, vaddr);
xsc3_l2_clean_mva(vaddr);
start += CACHE_LINE_SIZE;
}
- l2_map_restore_flags(flags);
+ l2_unmap_va(vaddr);
dsb();
}
@@ -193,7 +179,7 @@ static inline void xsc3_l2_flush_all(void)
static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
{
- unsigned long vaddr, flags;
+ unsigned long vaddr;
if (start == 0 && end == -1ul) {
xsc3_l2_flush_all();
@@ -201,17 +187,16 @@ static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
}
vaddr = -1; /* to force the first mapping */
- l2_map_save_flags(flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
- vaddr = l2_map_va(start, vaddr, flags);
+ vaddr = l2_map_va(start, vaddr);
xsc3_l2_clean_mva(vaddr);
xsc3_l2_inv_mva(vaddr);
start += CACHE_LINE_SIZE;
}
- l2_map_restore_flags(flags);
+ l2_unmap_va(vaddr);
dsb();
}
--
1.6.6.1
@@ -1,119 +0,0 @@
From ccb2858c9bd5fff216feab665db14ca32be8d6fe Mon Sep 17 00:00:00 2001
From: Nicolas Pitre <nicolas.pitre@linaro.org>
Date: Thu, 16 Dec 2010 14:56:34 -0500
Subject: [PATCH 05/65] ARM: fix cache-feroceon-l2 after stack based kmap_atomic()
Since commit 3e4d3af501 "mm: stack based kmap_atomic()", it is actively
wrong to rely on fixed kmap type indices (namely KM_L2_CACHE) as
kmap_atomic() totally ignores them and a concurrent instance of it may
happily reuse any slot for any purpose. Because kmap_atomic() is now
able to deal with reentrancy, we can get rid of the ad hoc mapping here.
While the code is made much simpler, there is a needless cache flush
introduced by the usage of __kunmap_atomic(). It is not clear if the
performance difference to remove that is worth the cost in code
maintenance (I don't think there are that many highmem users on that
platform anyway) but that should be reconsidered when/if someone cares
enough to do some measurements.
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
---
arch/arm/mm/cache-feroceon-l2.c | 37 +++++++++++++++++++------------------
1 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index 6e77c04..e0b0e7a 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -13,13 +13,9 @@
*/
#include <linux/init.h>
+#include <linux/highmem.h>
#include <asm/cacheflush.h>
-#include <asm/kmap_types.h>
-#include <asm/fixmap.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
#include <plat/cache-feroceon-l2.h>
-#include "mm.h"
/*
* Low-level cache maintenance operations.
@@ -39,27 +35,30 @@
* between which we don't want to be preempted.
*/
-static inline unsigned long l2_start_va(unsigned long paddr)
+static inline unsigned long l2_get_va(unsigned long paddr)
{
#ifdef CONFIG_HIGHMEM
/*
- * Let's do our own fixmap stuff in a minimal way here.
* Because range ops can't be done on physical addresses,
* we simply install a virtual mapping for it only for the
* TLB lookup to occur, hence no need to flush the untouched
- * memory mapping. This is protected with the disabling of
- * interrupts by the caller.
+ * memory mapping afterwards (note: a cache flush may happen
+ * in some circumstances depending on the path taken in kunmap_atomic).
*/
- unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
- unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
- set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0);
- local_flush_tlb_kernel_page(vaddr);
- return vaddr + (paddr & ~PAGE_MASK);
+ void *vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT);
+ return (unsigned long)vaddr + (paddr & ~PAGE_MASK);
#else
return __phys_to_virt(paddr);
#endif
}
+static inline void l2_put_va(unsigned long vaddr)
+{
+#ifdef CONFIG_HIGHMEM
+ kunmap_atomic((void *)vaddr);
+#endif
+}
+
static inline void l2_clean_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
@@ -76,13 +75,14 @@ static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
*/
BUG_ON((start ^ end) >> PAGE_SHIFT);
- raw_local_irq_save(flags);
- va_start = l2_start_va(start);
+ va_start = l2_get_va(start);
va_end = va_start + (end - start);
+ raw_local_irq_save(flags);
__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
"mcr p15, 1, %1, c15, c9, 5"
: : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
+ l2_put_va(va_start);
}
static inline void l2_clean_inv_pa(unsigned long addr)
@@ -106,13 +106,14 @@ static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
*/
BUG_ON((start ^ end) >> PAGE_SHIFT);
- raw_local_irq_save(flags);
- va_start = l2_start_va(start);
+ va_start = l2_get_va(start);
va_end = va_start + (end - start);
+ raw_local_irq_save(flags);
__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
"mcr p15, 1, %1, c15, c11, 5"
: : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
+ l2_put_va(va_start);
}
static inline void l2_inv_all(void)
--
1.6.6.1
@@ -1,45 +0,0 @@
From b4defd15cd77597734bab7089fa721fde6e3cfd5 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Tue, 14 Dec 2010 10:06:46 -0800
Subject: [PATCH 06/65] drm/i915: Set the required VFMUNIT clock gating disable on Ironlake.
It's required by the specs, but we don't know why. Let's not find out
why.
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_reg.h | 3 +++
drivers/gpu/drm/i915/intel_display.c | 2 ++
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 878fc76..8470a97 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2471,6 +2471,9 @@
# define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18)
# define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1)
+#define PCH_3DCGDIS1 0x46024
+# define VFMUNIT_CLOCK_GATE_DISABLE (1 << 11)
+
#define FDI_PLL_FREQ_CTL 0x46030
#define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24)
#define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d9b7092..97e374e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5825,6 +5825,8 @@ void intel_init_clock_gating(struct drm_device *dev)
I915_WRITE(PCH_3DCGDIS0,
MARIUNIT_CLOCK_GATE_DISABLE |
SVSMUNIT_CLOCK_GATE_DISABLE);
+ I915_WRITE(PCH_3DCGDIS1,
+ VFMUNIT_CLOCK_GATE_DISABLE);
}
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
--
1.6.6.1
@@ -1,38 +0,0 @@
From 184e12ee6bca758bee292970ed045d7a0405168c Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Thu, 23 Dec 2010 09:43:48 +0000
Subject: [PATCH 07/65] drm/i915/sdvo: Add hdmi connector properties after initing the connector
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=25012
Reported-by: Tõnu Raitviir <jussuf@linux.ee>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/intel_sdvo.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 27e63ab..6bc42fa 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2040,13 +2040,14 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
SDVO_COLORIMETRY_RGB256);
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
- intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
intel_sdvo->is_hdmi = true;
}
intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT));
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
+ if (intel_sdvo->is_hdmi)
+ intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
return true;
}
--
1.6.6.1
@@ -1,190 +0,0 @@
From 38684934e58030113d3e89a3f60472e22e2e1ea6 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 20 Dec 2010 18:40:06 -0800
Subject: [PATCH 08/65] drm/i915, intel_ips: When i915 loads after IPS, make IPS relink to i915.
The IPS driver is designed to be able to run detached from i915 and
just not enable GPU turbo in that case, in order to avoid module
dependencies between the two drivers. This means that we don't know
what the load order between the two is going to be, and we had
previously only supported IPS after (optionally) i915, but not i915
after IPS. If the wrong order was chosen, you'd get no GPU turbo, and
something like half the possible graphics performance.
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: stable@kernel.org
---
drivers/gpu/drm/i915/i915_dma.c | 23 +++++++++++++++++++++++
drivers/platform/x86/intel_ips.c | 36 +++++++++++++++++++++++++++++++++---
drivers/platform/x86/intel_ips.h | 21 +++++++++++++++++++++
3 files changed, 77 insertions(+), 3 deletions(-)
create mode 100644 drivers/platform/x86/intel_ips.h
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index e680081..cb900dc 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -34,6 +34,7 @@
#include "i915_drm.h"
#include "i915_drv.h"
#include "i915_trace.h"
+#include "../../../platform/x86/intel_ips.h"
#include <linux/pci.h>
#include <linux/vgaarb.h>
#include <linux/acpi.h>
@@ -1871,6 +1872,26 @@ out_unlock:
EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
/**
+ * Tells the intel_ips driver that the i915 driver is now loaded, if
+ * IPS got loaded first.
+ *
+ * This awkward dance is so that neither module has to depend on the
+ * other in order for IPS to do the appropriate communication of
+ * GPU turbo limits to i915.
+ */
+static void
+ips_ping_for_i915_load(void)
+{
+ void (*link)(void);
+
+ link = symbol_get(ips_link_to_i915_driver);
+ if (link) {
+ link();
+ symbol_put(ips_link_to_i915_driver);
+ }
+}
+
+/**
* i915_driver_load - setup chip and create an initial config
* @dev: DRM device
* @flags: startup flags
@@ -2075,6 +2096,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->mchdev_lock = &mchdev_lock;
spin_unlock(&mchdev_lock);
+ ips_ping_for_i915_load();
+
return 0;
out_workqueue_free:
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index c44a5e8..f0b3ad1 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -75,6 +75,7 @@
#include <drm/i915_drm.h>
#include <asm/msr.h>
#include <asm/processor.h>
+#include "intel_ips.h"
#define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32
@@ -245,6 +246,7 @@
#define thm_writel(off, val) writel((val), ips->regmap + (off))
static const int IPS_ADJUST_PERIOD = 5000; /* ms */
+static bool late_i915_load = false;
/* For initial average collection */
static const int IPS_SAMPLE_PERIOD = 200; /* ms */
@@ -339,6 +341,9 @@ struct ips_driver {
u64 orig_turbo_ratios;
};
+static bool
+ips_gpu_turbo_enabled(struct ips_driver *ips);
+
/**
* ips_cpu_busy - is CPU busy?
* @ips: IPS driver struct
@@ -517,7 +522,7 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips)
*/
static bool ips_gpu_busy(struct ips_driver *ips)
{
- if (!ips->gpu_turbo_enabled)
+ if (!ips_gpu_turbo_enabled(ips))
return false;
return ips->gpu_busy();
@@ -532,7 +537,7 @@ static bool ips_gpu_busy(struct ips_driver *ips)
*/
static void ips_gpu_raise(struct ips_driver *ips)
{
- if (!ips->gpu_turbo_enabled)
+ if (!ips_gpu_turbo_enabled(ips))
return;
if (!ips->gpu_raise())
@@ -549,7 +554,7 @@ static void ips_gpu_raise(struct ips_driver *ips)
*/
static void ips_gpu_lower(struct ips_driver *ips)
{
- if (!ips->gpu_turbo_enabled)
+ if (!ips_gpu_turbo_enabled(ips))
return;
if (!ips->gpu_lower())
@@ -1454,6 +1459,31 @@ out_err:
return false;
}
+static bool
+ips_gpu_turbo_enabled(struct ips_driver *ips)
+{
+ if (!ips->gpu_busy && late_i915_load) {
+ if (ips_get_i915_syms(ips)) {
+ dev_info(&ips->dev->dev,
+ "i915 driver attached, reenabling gpu turbo\n");
+ ips->gpu_turbo_enabled = !(thm_readl(THM_HTS) & HTS_GTD_DIS);
+ }
+ }
+
+ return ips->gpu_turbo_enabled;
+}
+
+void
+ips_link_to_i915_driver()
+{
+ /* We can't cleanly get at the various ips_driver structs from
+ * this caller (the i915 driver), so just set a flag saying
+ * that it's time to try getting the symbols again.
+ */
+ late_i915_load = true;
+}
+EXPORT_SYMBOL_GPL(ips_link_to_i915_driver);
+
static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), },
diff --git a/drivers/platform/x86/intel_ips.h b/drivers/platform/x86/intel_ips.h
new file mode 100644
index 0000000..73299be
--- /dev/null
+++ b/drivers/platform/x86/intel_ips.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+void ips_link_to_i915_driver(void);
--
1.6.6.1
@@ -1,69 +0,0 @@
From b3ae260de2254a0aed982b5964396a9914859c0e Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Tue, 14 Dec 2010 19:21:29 +0000
Subject: [PATCH 09/65] drm/i915: Verify Ironlake eDP presence on DP_A using the capability fuse
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_reg.h | 7 +++++++
drivers/gpu/drm/i915/intel_display.c | 19 ++++++++++++++++++-
2 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8470a97..cb8f434 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2591,6 +2591,13 @@
#define ILK_DISPLAY_CHICKEN2 0x42004
#define ILK_DPARB_GATE (1<<22)
#define ILK_VSDPFD_FULL (1<<21)
+#define ILK_DISPLAY_CHICKEN_FUSES 0x42014
+#define ILK_INTERNAL_GRAPHICS_DISABLE (1<<31)
+#define ILK_INTERNAL_DISPLAY_DISABLE (1<<30)
+#define ILK_DISPLAY_DEBUG_DISABLE (1<<29)
+#define ILK_HDCP_DISABLE (1<<25)
+#define ILK_eDP_A_DISABLE (1<<24)
+#define ILK_DESKTOP (1<<23)
#define ILK_DSPCLK_GATE 0x42020
#define ILK_DPARB_CLK_GATE (1<<5)
/* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 97e374e..fca5232 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5379,6 +5379,23 @@ static int intel_encoder_clones(struct drm_device *dev, int type_mask)
return index_mask;
}
+static bool has_edp_a(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (!IS_MOBILE(dev))
+ return false;
+
+ if ((I915_READ(DP_A) & DP_DETECTED) == 0)
+ return false;
+
+ if (IS_GEN5(dev) &&
+ (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE))
+ return false;
+
+ return true;
+}
+
static void intel_setup_outputs(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5396,7 +5413,7 @@ static void intel_setup_outputs(struct drm_device *dev)
if (HAS_PCH_SPLIT(dev)) {
dpd_is_edp = intel_dpd_is_edp(dev);
- if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED))
+ if (has_edp_a(dev))
intel_dp_init(dev, DP_A);
if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
--
1.6.6.1
@@ -1,42 +0,0 @@
From 233828cbb5d2331e47cba932130428ea5f915f91 Mon Sep 17 00:00:00 2001
From: Stephen Warren <swarren@nvidia.com>
Date: Wed, 22 Dec 2010 04:52:05 +0100
Subject: [PATCH 10/65] ARM: 6536/1: Add missing SZ_{32,64,128}
... and also remove misleading comment stating that this header is
auto-generated.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Uwe Kleine-Knig <u.kleine-koenig@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/include/asm/sizes.h | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h
index 4fc1565..316bb2b 100644
--- a/arch/arm/include/asm/sizes.h
+++ b/arch/arm/include/asm/sizes.h
@@ -13,9 +13,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* DO NOT EDIT!! - this file automatically generated
- * from .s file by awk -f s2h.awk
- */
/* Size definitions
* Copyright (C) ARM Limited 1998. All rights reserved.
*/
@@ -25,6 +22,9 @@
/* handy sizes */
#define SZ_16 0x00000010
+#define SZ_32 0x00000020
+#define SZ_64 0x00000040
+#define SZ_128 0x00000080
#define SZ_256 0x00000100
#define SZ_512 0x00000200
--
1.6.6.1
@@ -1,65 +0,0 @@
From 1efad2ad25ed60a4d90a87f7e77babb808b3052f Mon Sep 17 00:00:00 2001
From: Linus Walleij <linus.walleij@stericsson.com>
Date: Wed, 22 Dec 2010 09:18:29 +0100
Subject: [PATCH 11/65] ARM: 6537/1: update Nomadik, U300 and Ux500 maintainers
Adding in self as maintainer for Nomadik and Ux500, I'm running
an active -next tree for that stuff now. Extend file matchers to
cover a few more relevant drivers and add git references.
Cc: Alessandro Rubini <rubini@unipv.it>
Acked-by: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
MAINTAINERS | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 4607f18..1c15602 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -792,11 +792,14 @@ S: Maintained
ARM/NOMADIK ARCHITECTURE
M: Alessandro Rubini <rubini@unipv.it>
+M: Linus Walleij <linus.walleij@stericsson.com>
M: STEricsson <STEricsson_nomadik_linux@list.st.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-nomadik/
F: arch/arm/plat-nomadik/
+F: drivers/i2c/busses/i2c-nomadik.c
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
M: Nelson Castillo <arhuaco@freaks-unidos.net>
@@ -998,12 +1001,24 @@ F: drivers/i2c/busses/i2c-stu300.c
F: drivers/rtc/rtc-coh901331.c
F: drivers/watchdog/coh901327_wdt.c
F: drivers/dma/coh901318*
+F: drivers/mfd/ab3100*
+F: drivers/rtc/rtc-ab3100.c
+F: drivers/rtc/rtc-coh901331.c
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
-ARM/U8500 ARM ARCHITECTURE
+ARM/Ux500 ARM ARCHITECTURE
M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+M: Linus Walleij <linus.walleij@stericsson.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-ux500/
+F: drivers/dma/ste_dma40*
+F: drivers/mfd/ab3550*
+F: drivers/mfd/abx500*
+F: drivers/mfd/ab8500*
+F: drivers/mfd/stmpe*
+F: drivers/rtc/rtc-ab8500.c
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
ARM/VFP SUPPORT
M: Russell King <linux@arm.linux.org.uk>
--
1.6.6.1
@@ -1,44 +0,0 @@
From d0427fe2982e2f4f644b936fe39636916b69fee1 Mon Sep 17 00:00:00 2001
From: Todd Android Poynor <toddpoynor@google.com>
Date: Thu, 23 Dec 2010 01:52:44 +0100
Subject: [PATCH 12/65] ARM: 6540/1: Stop irqsoff trace on return to user
If the irqsoff tracer is in use, stop tracing the interrupt disable
interval when returning to userspace. Tracing userspace execution time
as interrupts disabled time is not helpful for kernel performance
analysis purposes. Only do so if the irqsoff tracer is enabled, to
avoid overhead for lockdep, which doesn't care.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/kernel/entry-common.S | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 8bfa987..80bf8cd 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -29,6 +29,9 @@ ret_fast_syscall:
ldr r1, [tsk, #TI_FLAGS]
tst r1, #_TIF_WORK_MASK
bne fast_work_pending
+#if defined(CONFIG_IRQSOFF_TRACER)
+ asm_trace_hardirqs_on
+#endif
/* perform architecture specific actions before user return */
arch_ret_to_user r1, lr
@@ -65,6 +68,9 @@ ret_slow_syscall:
tst r1, #_TIF_WORK_MASK
bne work_pending
no_work_pending:
+#if defined(CONFIG_IRQSOFF_TRACER)
+ asm_trace_hardirqs_on
+#endif
/* perform architecture specific actions before user return */
arch_ret_to_user r1, lr
--
1.6.6.1
@@ -1,100 +0,0 @@
From c23a13703fb00384d49a00875fc12a5e00f1946a Mon Sep 17 00:00:00 2001
From: Dan Williams <dcbw@redhat.com>
Date: Sun, 19 Dec 2010 08:17:50 +0000
Subject: [PATCH 13/65] ueagle-atm: fix PHY signal initialization race
A race exists when initializing ueagle-atm devices where the generic atm
device may not yet be created before the driver attempts to initialize
it's PHY signal state, which checks whether the atm device has been
created or not. This often causes the sysfs 'carrier' attribute to be
'1' even though no signal has actually been found.
uea_probe
usbatm_usb_probe
driver->bind (uea_bind)
uea_boot
kthread_run(uea_kthread) uea_kthread
usbatm_atm_init uea_start_reset
atm_dev_register UPDATE_ATM_SIGNAL
UPDATE_ATM_SIGNAL checks whether the ATM device has been created and if
not, will not update the PHY signal state. Because of the race that
does not always happen in time, and the PHY signal state remains
ATM_PHY_SIG_FOUND even though no signal exists.
To fix the race, just create the kthread during initialization, and only
after initialization is complete, start the thread that reboots the
device and initializes PHY state.
[ 3030.490931] uea_probe: calling usbatm_usb_probe
[ 3030.490946] ueagle-atm 8-2:1.0: usbatm_usb_probe: trying driver ueagle-atm with vendor=1110, product=9031, ifnum 0
[ 3030.493691] uea_bind: setting usbatm
[ 3030.496932] usb 8-2: [ueagle-atm] using iso mode
[ 3030.497283] ueagle-atm 8-2:1.0: usbatm_usb_probe: using 3021 byte buffer for rx channel 0xffff880125953508
<kthread already started before usbatm_usb_probe() has returned>
[ 3030.497292] usb 8-2: [ueagle-atm] (re)booting started
<UPDATE_ATM_SIGNAL checks whether ATM device has been created yet before setting PHY state>
[ 3030.497298] uea_start_reset: atm dev (null)
<and since it hasn't been created yet PHY state is not set>
[ 3030.497306] ueagle-atm 8-2:1.0: usbatm_usb_probe: using 3392 byte buffer for tx channel 0xffff8801259535b8
[ 3030.497374] usbatm_usb_probe: about to init
[ 3030.497379] usbatm_usb_probe: calling usbatm_atm_init
<atm device finally gets created>
[ 3030.497384] usbatm_atm_init: creating atm device!
Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/usb/atm/ueagle-atm.c | 22 +++++++++++++++++++---
1 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index 44447f5..99ac70e 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -2206,8 +2206,11 @@ static int uea_boot(struct uea_softc *sc)
goto err1;
}
- sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");
- if (sc->kthread == ERR_PTR(-ENOMEM)) {
+ /* Create worker thread, but don't start it here. Start it after
+ * all usbatm generic initialization is done.
+ */
+ sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm");
+ if (IS_ERR(sc->kthread)) {
uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
goto err2;
}
@@ -2624,6 +2627,7 @@ static struct usbatm_driver uea_usbatm_driver = {
static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *usb = interface_to_usbdev(intf);
+ int ret;
uea_enters(usb);
uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n",
@@ -2637,7 +2641,19 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (UEA_IS_PREFIRM(id))
return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
- return usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+ ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+ if (ret == 0) {
+ struct usbatm_data *usbatm = usb_get_intfdata(intf);
+ struct uea_softc *sc = usbatm->driver_data;
+
+ /* Ensure carrier is initialized to off as early as possible */
+ UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST);
+
+ /* Only start the worker thread when all init is done */
+ wake_up_process(sc->kthread);
+ }
+
+ return ret;
}
static void uea_disconnect(struct usb_interface *intf)
--
1.6.6.1

Some files were not shown because too many files have changed in this diff Show More