mirror of
https://git.yoctoproject.org/meta-ti
synced 2026-01-12 01:20:20 +00:00
linux-omap: update to 2.6.37-final
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
From c818eb868fd5621ad373e508fbb71b69739a56c1 Mon Sep 17 00:00:00 2001
|
||||
From 5bae403e0f66a67c222ce124422d43b8b9307041 Mon Sep 17 00:00:00 2001
|
||||
From: Koen Kooi <koen@dominion.thruhere.net>
|
||||
Date: Thu, 7 Oct 2010 09:25:45 +0200
|
||||
Subject: [PATCH 01/29] ARM: OMAP: Power on EHCI, serial, camera and DVI on beagleboard-xM
|
||||
Subject: [PATCH 01/26] ARM: OMAP: Power on EHCI, serial, camera and DVI on beagleboard-xM
|
||||
|
||||
Signed-off-by: Koen Kooi <koen@beagleboard.org>
|
||||
---
|
||||
@@ -1,7 +1,7 @@
|
||||
From 3adfccd800f37f6d4eac565366b86cafe96b487a Mon Sep 17 00:00:00 2001
|
||||
From 3258ce5493fd9e603a31cc4156892f08ee1500e9 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Nelson <robertcnelson@gmail.com>
|
||||
Date: Tue, 9 Nov 2010 08:34:55 -0600
|
||||
Subject: [PATCH 02/29] omap: Beagle: detect new xM revision B
|
||||
Subject: [PATCH 02/26] 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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From c857174c0394df227696d145fb1f15a33d870600 Mon Sep 17 00:00:00 2001
|
||||
From 116a1ffd21e520b0a6c7a91576605bc6151138cb 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 03/29] ARM: OMAP: beagleboard: Add infrastructure to do fixups based on expansionboard name passed by u-boot
|
||||
Subject: [PATCH 03/26] 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 35b474d13b609841faa420a763c7a6d9cb13ce66 Mon Sep 17 00:00:00 2001
|
||||
From 64215e5d75084b49c490d2aad78c8d3702e6c419 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 04/29] ARM: OMAP: beagleboard: pre-export GPIOs to userspace when using a Tincantools trainerboard
|
||||
Subject: [PATCH 04/26] ARM: OMAP: beagleboard: pre-export GPIOs to userspace when using a Tincantools trainerboard
|
||||
|
||||
This really needs a for loop, patches welcome
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 1db89a463f04db7c5f6b027910c41f438739e14f Mon Sep 17 00:00:00 2001
|
||||
From 84b16387417976abbba2dd1608147ab0c7692093 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 05/29] modedb.c: add proper 720p60 mode
|
||||
Subject: [PATCH 05/26] modedb.c: add proper 720p60 mode
|
||||
|
||||
Signed-off-by: Koen Kooi <koen@beagleboard.org>
|
||||
---
|
||||
@@ -1,7 +1,7 @@
|
||||
From db401a606f8bb40accbb5a560e445edc29ab995e Mon Sep 17 00:00:00 2001
|
||||
From 11aba6aa87fc0d7c452324d002578aa54d3c9a6b Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Mon, 4 Jan 2010 19:20:25 -0800
|
||||
Subject: [PATCH 06/29] mmc: don't display single block read console messages
|
||||
Subject: [PATCH 06/26] mmc: don't display single block read console messages
|
||||
|
||||
mmc: don't display single block read console messages
|
||||
---
|
||||
@@ -1,7 +1,7 @@
|
||||
From 461835a249017f6e96902f509c78e03ef26ef2a9 Mon Sep 17 00:00:00 2001
|
||||
From 7f3e88e66f1dd872ed087372d6cd81fce5d96d24 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Mon, 26 Apr 2010 11:17:26 -0700
|
||||
Subject: [PATCH 07/29] MTD: silence ecc errors on mtdblock0
|
||||
Subject: [PATCH 07/26] MTD: silence ecc errors on mtdblock0
|
||||
|
||||
mtdblock0 is the x-load partition, which uses hw ecc
|
||||
this confuses linux, which uses sw ecc
|
||||
@@ -1,7 +1,7 @@
|
||||
From 8aa41351f7c9e1f846a3d6e1e4bbd3a85a87d10c Mon Sep 17 00:00:00 2001
|
||||
From d7dbe93075a4e7b5c0fa2a2b745440a53ad26a72 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Galbraith <efault@gmx.de>
|
||||
Date: Fri, 19 Nov 2010 12:52:42 +0100
|
||||
Subject: [PATCH 08/29] Miracle patch
|
||||
Subject: [PATCH 08/26] Miracle patch
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
@@ -113,7 +113,7 @@ Signed-off-by: Mike Galbraith <efault@gmx.de>
|
||||
create mode 100644 kernel/sched_autogroup.h
|
||||
|
||||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
|
||||
index 8b61c93..9408728 100644
|
||||
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
|
||||
@@ -1,7 +1,7 @@
|
||||
From b86550d1c9423b9609cc7260fe723881879989af Mon Sep 17 00:00:00 2001
|
||||
From d378376ed64b5506c352b33085baeb21013e55f2 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 09/29] ARM: OMAP: add omap_rev_* macros
|
||||
Subject: [PATCH 09/26] ARM: OMAP: add omap_rev_* macros
|
||||
|
||||
This is just to make the SGX modules build that depend on omap_rev_lt_3_0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From de23d5117cbd6bb7accd92a9a6628e688d9f5fa2 Mon Sep 17 00:00:00 2001
|
||||
From b5e34d9e5b20b412686f84ea8f4e56245f7d5f7f Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Mon, 10 May 2010 20:44:09 -0700
|
||||
Subject: [PATCH 10/29] OMAP: DSS2: enable hsclk in dsi_pll_init for OMAP36XX
|
||||
Subject: [PATCH 10/26] OMAP: DSS2: enable hsclk in dsi_pll_init for OMAP36XX
|
||||
|
||||
Signed-off-by: Koen Kooi <koen@beagleboard.org>
|
||||
---
|
||||
@@ -1,7 +1,7 @@
|
||||
From 8d0ecb38ebb0b50364f94e72eaee2f4945020cff Mon Sep 17 00:00:00 2001
|
||||
From 7bd039c94c36e206ffeb521e2facab7dc9737eaf Mon Sep 17 00:00:00 2001
|
||||
From: Koen Kooi <koen@beagleboard.org>
|
||||
Date: Mon, 20 Dec 2010 11:57:56 +0100
|
||||
Subject: [PATCH 11/29] omap3: beagleboard: add WIP support for beagleboardtoys WL12xx board
|
||||
Subject: [PATCH 11/26] omap3: beagleboard: add WIP support for beagleboardtoys WL12xx board
|
||||
|
||||
Based on a patch by Luciano Coelho <luciano.coelho@nokia.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 84148dd7b2824a008561b4aabe483d16cf093951 Mon Sep 17 00:00:00 2001
|
||||
From 9eb52cc853ca5aae2cf2b8c4df8ecfd3b666d560 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <sakoman@gmail.com>
|
||||
Date: Tue, 15 Dec 2009 15:17:44 -0800
|
||||
Subject: [PATCH 12/29] drivers: net: smsc911x: return ENODEV if device is not found
|
||||
Subject: [PATCH 12/26] drivers: net: smsc911x: return ENODEV if device is not found
|
||||
|
||||
Signed-off-by: Steve Sakoman <sakoman@gmail.com>
|
||||
---
|
||||
@@ -1,7 +1,7 @@
|
||||
From 5167902964ed42113dbc2302cd64a12df4cd6a8e Mon Sep 17 00:00:00 2001
|
||||
From 090cbb4e522ea0a7e31508435fa1852eecef2fea Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <sakoman@gmail.com>
|
||||
Date: Tue, 15 Dec 2009 15:24:10 -0800
|
||||
Subject: [PATCH 13/29] drivers: input: touchscreen: ads7846: return ENODEV if device is not found
|
||||
Subject: [PATCH 13/26] drivers: input: touchscreen: ads7846: return ENODEV if device is not found
|
||||
|
||||
Signed-off-by: Steve Sakoman <sakoman@gmail.com>
|
||||
---
|
||||
@@ -1,7 +1,7 @@
|
||||
From 6377ecd5556f5329ddd5f5e9b9b5cd019cd76e67 Mon Sep 17 00:00:00 2001
|
||||
From 3afe141cc65d54db2bfc82683d7ac5e142d48dad Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Thu, 17 Dec 2009 12:45:20 -0800
|
||||
Subject: [PATCH 14/29] ASoC: enable audio capture by default for twl4030
|
||||
Subject: [PATCH 14/26] ASoC: enable audio capture by default for twl4030
|
||||
|
||||
---
|
||||
sound/soc/codecs/twl4030.c | 4 ++--
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0e659f27fa00c4a6263e2b2ff96e09759f09b053 Mon Sep 17 00:00:00 2001
|
||||
From f749aa37992fe966db530bd1d3ff00ea0eb8e13f Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Sat, 23 Jan 2010 06:26:54 -0800
|
||||
Subject: [PATCH 15/29] MFD: enable madc clock
|
||||
Subject: [PATCH 15/26] MFD: enable madc clock
|
||||
|
||||
---
|
||||
drivers/mfd/twl-core.c | 8 ++++++++
|
||||
@@ -1,7 +1,7 @@
|
||||
From a68c5e1548041d308fa46f834ff00e3a1ccd0acf Mon Sep 17 00:00:00 2001
|
||||
From bd8ef0fcbab561b010735e12e18946da7a2d81f4 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Thu, 17 Dec 2009 14:19:34 -0800
|
||||
Subject: [PATCH 16/29] MFD: add twl4030 madc driver
|
||||
Subject: [PATCH 16/26] MFD: add twl4030 madc driver
|
||||
|
||||
---
|
||||
drivers/mfd/Kconfig | 21 ++
|
||||
@@ -1,7 +1,7 @@
|
||||
From 7a9db8dd7562102e3c71eb079dc4e21792a650dc Mon Sep 17 00:00:00 2001
|
||||
From e8f9b322f40b10dbd947281203411c9b0c9cb458 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Thu, 17 Dec 2009 14:27:15 -0800
|
||||
Subject: [PATCH 17/29] ARM: OMAP: Add twl4030 madc support to Overo
|
||||
Subject: [PATCH 17/26] ARM: OMAP: Add twl4030 madc support to Overo
|
||||
|
||||
---
|
||||
arch/arm/mach-omap2/board-overo.c | 5 +++++
|
||||
@@ -1,7 +1,7 @@
|
||||
From 11bcde4707cf385ba61ccd0e00c9ab71db76ba6c Mon Sep 17 00:00:00 2001
|
||||
From d37c0152c00ea15b488b2274544dcb30758fb8ca Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Thu, 17 Dec 2009 14:32:36 -0800
|
||||
Subject: [PATCH 18/29] ARM: OMAP: Add twl4030 madc support to Beagle
|
||||
Subject: [PATCH 18/26] ARM: OMAP: Add twl4030 madc support to Beagle
|
||||
|
||||
---
|
||||
arch/arm/mach-omap2/board-omap3beagle.c | 5 +++++
|
||||
@@ -1,7 +1,7 @@
|
||||
From 92f8c713af962a538532279ce29ce5936f7736f7 Mon Sep 17 00:00:00 2001
|
||||
From b8983a303fe84ba5a2ff5075edee0071c0b982ae Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Tue, 23 Feb 2010 14:40:27 -0800
|
||||
Subject: [PATCH 19/29] OMAP: DSS2: Add support for Samsung LTE430WQ-F0C panel
|
||||
Subject: [PATCH 19/26] OMAP: DSS2: Add support for Samsung LTE430WQ-F0C panel
|
||||
|
||||
---
|
||||
.../omap2/displays/panel-samsung-lte430wq-f0c.c | 154 ++++++++++++++++++++
|
||||
@@ -1,7 +1,7 @@
|
||||
From 36be685c580ace452461045b9278631330f18c89 Mon Sep 17 00:00:00 2001
|
||||
From 571cdd24aee8cd6091bcc4dac0d8a0affc3500bf Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Thu, 17 Dec 2009 15:05:30 -0800
|
||||
Subject: [PATCH 20/29] OMAP: DSS2: Add support for LG Philips LB035Q02 panel
|
||||
Subject: [PATCH 20/26] OMAP: DSS2: Add support for LG Philips LB035Q02 panel
|
||||
|
||||
---
|
||||
drivers/video/omap2/displays/Kconfig | 12 +
|
||||
@@ -1,7 +1,7 @@
|
||||
From a8f054b88944b7e1bd9b017eee1db76e90db0039 Mon Sep 17 00:00:00 2001
|
||||
From d4ae1b11c94e268467ff6cb6143b934733ed762a Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Tue, 19 Jan 2010 21:19:15 -0800
|
||||
Subject: [PATCH 21/29] OMAP: DSS2: add bootarg for selecting svideo or composite for tv output
|
||||
Subject: [PATCH 21/26] OMAP: DSS2: add bootarg for selecting svideo or composite for tv output
|
||||
|
||||
also add pal-16 and ntsc-16 omapfb.mode settings for 16bpp
|
||||
---
|
||||
@@ -1,7 +1,7 @@
|
||||
From 036a15634116c64217d424dc1677fed9480cf381 Mon Sep 17 00:00:00 2001
|
||||
From d0f67e031cd9eb514bbcff3147bf6644b92c5ee4 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Sun, 24 Jan 2010 09:33:56 -0800
|
||||
Subject: [PATCH 22/29] ARM: OMAP2: mmc-twl4030: move clock input selection prior to vcc test
|
||||
Subject: [PATCH 22/26] ARM: OMAP2: mmc-twl4030: move clock input selection prior to vcc test
|
||||
|
||||
otherwise it is not executed on systems that use non-twl regulators
|
||||
---
|
||||
@@ -1,7 +1,7 @@
|
||||
From db329c64c7c6abf08929860512964fc00d13f075 Mon Sep 17 00:00:00 2001
|
||||
From 27f251ad46eeda205c220f89b4f9fbeaf930ae54 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Thu, 4 Feb 2010 12:26:22 -0800
|
||||
Subject: [PATCH 23/29] RTC: add support for backup battery recharge
|
||||
Subject: [PATCH 23/26] RTC: add support for backup battery recharge
|
||||
|
||||
---
|
||||
drivers/rtc/rtc-twl.c | 25 +++++++++++++++++++++++++
|
||||
@@ -1,7 +1,7 @@
|
||||
From 12fd29b006ffd5b8b14837088db8949a53d04f04 Mon Sep 17 00:00:00 2001
|
||||
From 4eedcb7fb5101a042102355463a213fa51e52e4f Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Wed, 24 Feb 2010 10:37:22 -0800
|
||||
Subject: [PATCH 24/29] ARM: OMAP: automatically set musb mode in platform data based on CONFIG options
|
||||
Subject: [PATCH 24/26] ARM: OMAP: automatically set musb mode in platform data based on CONFIG options
|
||||
|
||||
---
|
||||
arch/arm/mach-omap2/board-omap3beagle.c | 6 ++++++
|
||||
@@ -1,7 +1,7 @@
|
||||
From 6d36c6f600becef7ee3f9d139c065b733a732a54 Mon Sep 17 00:00:00 2001
|
||||
From 3e9463eb0f8c54286c086f259a598415ba28c28f Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Mon, 10 May 2010 13:59:14 -0700
|
||||
Subject: [PATCH 25/29] OMAP: DSS2: check for both cpu type and revision, rather than just revision
|
||||
Subject: [PATCH 25/26] OMAP: DSS2: check for both cpu type and revision, rather than just revision
|
||||
|
||||
---
|
||||
drivers/video/omap2/dss/dispc.c | 4 ++--
|
||||
@@ -1,7 +1,7 @@
|
||||
From 21da1a248b7a19136bb53a32061989473bc79551 Mon Sep 17 00:00:00 2001
|
||||
From 5ac69358c0af66eadb86561fb99a661280f61f78 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Fri, 18 Dec 2009 06:39:24 -0800
|
||||
Subject: [PATCH 26/29] OMAP: DSS2: Add DSS2 support for Overo
|
||||
Subject: [PATCH 26/26] OMAP: DSS2: Add DSS2 support for Overo
|
||||
|
||||
---
|
||||
arch/arm/mach-omap2/board-overo.c | 238 +++++++++++++++++++++++++++++++------
|
||||
@@ -0,0 +1,60 @@
|
||||
From 405be95c4b7c397815b20052dbaa43ce36c1a724 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/19] 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
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From fe693a9d05c58aa7e5157f695b9af00688a2b91d Mon Sep 17 00:00:00 2001
|
||||
From: Koen Kooi <koen@dominion.thruhere.net>
|
||||
Date: Thu, 6 Jan 2011 13:05:55 +0100
|
||||
Subject: [PATCH 1/4] omap3: add support for 720MHz MPU OPP
|
||||
|
||||
The 720MHz capability can be probed run-time by reading the
|
||||
PRODID.SKUID[3:0] at 0x4830A20C.
|
||||
|
||||
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||
---
|
||||
arch/arm/mach-omap2/opp3xxx_data.c | 4 ++++
|
||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
|
||||
index fd3a1af..a861f5e 100644
|
||||
--- a/arch/arm/mach-omap2/opp3xxx_data.c
|
||||
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
|
||||
@@ -34,6 +34,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 +61,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[] = {
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
From a1df976c51e22bed9d95fcb07832571ef3520f2a 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/19] 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
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
From 154571d1620731a3207da126eb4f139a1534f293 Mon Sep 17 00:00:00 2001
|
||||
From: Koen Kooi <koen@dominion.thruhere.net>
|
||||
Date: Thu, 6 Jan 2011 13:13:18 +0100
|
||||
Subject: [PATCH 2/4] OMAP35x: Add support for 720MHz part
|
||||
|
||||
This patch adds support for ARM running at 720MHz part.
|
||||
|
||||
The 720MHz capability can be probed run-time by reading the
|
||||
PRODID.SKUID[3:0] at 0x4830A20C.
|
||||
|
||||
[1] http://focus.ti.com/lit/ug/spruff1d/spruff1d.pdf
|
||||
|
||||
This is a forward port of https://patchwork.kernel.org/patch/53125/
|
||||
|
||||
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||
---
|
||||
arch/arm/mach-omap2/control.h | 7 +++++++
|
||||
arch/arm/mach-omap2/id.c | 10 ++++++++++
|
||||
arch/arm/plat-omap/include/plat/cpu.h | 2 ++
|
||||
3 files changed, 19 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
|
||||
index f0629ae..b9671d3 100644
|
||||
--- a/arch/arm/mach-omap2/control.h
|
||||
+++ b/arch/arm/mach-omap2/control.h
|
||||
@@ -365,7 +365,14 @@
|
||||
#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
|
||||
extern void __iomem *omap_ctrl_base_get(void);
|
||||
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/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
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From fe6bc036ebf31ca377051ff0ea99da3cdc66854f 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/19] 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
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
From 1a97a3600227fd0b52ee3bfd67bac6dde034af0d Mon Sep 17 00:00:00 2001
|
||||
From: Koen Kooi <koen@dominion.thruhere.net>
|
||||
Date: Thu, 6 Jan 2011 13:23:45 +0100
|
||||
Subject: [PATCH 3/4] OMAP3: beagle C4: enable upto 720MHz OPP
|
||||
|
||||
Beagle C4 uses a recent 3530 and the board design allows enabling 720MHz
|
||||
OPP. tweak the default table to allow for higher OPP tables
|
||||
|
||||
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||
---
|
||||
arch/arm/mach-omap2/board-omap3beagle.c | 35 +++++++++++++++++++++++++++++++
|
||||
1 files changed, 35 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
index 9393e75..a0462b9 100644
|
||||
--- a/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||
@@ -829,6 +829,41 @@ static void __init beagle_opp_init(void)
|
||||
pr_err("%s: turbo OPPs enabled!\n", __func__);
|
||||
}
|
||||
}
|
||||
+ /* Custom OPP enabled for C4 */
|
||||
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4) {
|
||||
+ 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 720MHz */
|
||||
+ dev = &mh->od->pdev.dev;
|
||||
+ r = opp_enable(dev, 720000000);
|
||||
+
|
||||
+ /* Enable IVA 520MHz and lower opps */
|
||||
+ dev = &dh->od->pdev.dev;
|
||||
+ r |= opp_enable(dev, 520000000);
|
||||
+ }
|
||||
+ 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, 720000000);
|
||||
+ dev = &dh->od->pdev.dev;
|
||||
+ opp_disable(dev, 520000000);
|
||||
+ } else {
|
||||
+ pr_err("%s: 720MHz MPU OPPs enabled!\n", __func__);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
static void __init omap3_beagle_init(void)
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
From ba484e6276ba5089a0397aad845ae5be80850bac Mon Sep 17 00:00:00 2001
|
||||
From: Koen Kooi <koen@dominion.thruhere.net>
|
||||
Date: Wed, 12 Jan 2011 17:04:04 +0100
|
||||
Subject: [PATCH 4/4] OMAP3: Overo Tide: enable upto 720MHz OPP
|
||||
|
||||
Overo Tide uses a recent 3530 and the board design allows enabling 720MHz
|
||||
OPP. tweak the default table to allow for higher OPP tables
|
||||
|
||||
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||
---
|
||||
arch/arm/mach-omap2/board-overo.c | 51 +++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 51 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
|
||||
index 8a44c17..d6d8619 100644
|
||||
--- a/arch/arm/mach-omap2/board-overo.c
|
||||
+++ b/arch/arm/mach-omap2/board-overo.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/spi/spi.h>
|
||||
+#include <linux/opp.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
@@ -50,10 +51,12 @@
|
||||
#include <plat/mcspi.h>
|
||||
#include <plat/mux.h>
|
||||
#include <plat/usb.h>
|
||||
+#include <plat/omap_device.h>
|
||||
|
||||
#include "mux.h"
|
||||
#include "sdram-micron-mt46h32m32lf-6.h"
|
||||
#include "hsmmc.h"
|
||||
+#include "pm.h"
|
||||
|
||||
#define OVERO_GPIO_BT_XGATE 15
|
||||
#define OVERO_GPIO_W2W_NRESET 16
|
||||
@@ -626,6 +629,53 @@ static struct omap_musb_board_data musb_board_data = {
|
||||
.power = 100,
|
||||
};
|
||||
|
||||
+static void __init overo_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 Tide */
|
||||
+ if (omap3_has_720mhz()) {
|
||||
+ 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 720MHz */
|
||||
+ dev = &mh->od->pdev.dev;
|
||||
+ r = opp_enable(dev, 720000000);
|
||||
+
|
||||
+ /* Enable IVA 520MHz and lower opps */
|
||||
+ dev = &dh->od->pdev.dev;
|
||||
+ r |= opp_enable(dev, 520000000);
|
||||
+ }
|
||||
+ 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, 720000000);
|
||||
+ dev = &dh->od->pdev.dev;
|
||||
+ opp_disable(dev, 520000000);
|
||||
+ } else {
|
||||
+ pr_err("%s: 720MHz MPU OPPs enabled!\n", __func__);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
static void __init overo_init(void)
|
||||
{
|
||||
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
|
||||
@@ -678,6 +728,7 @@ static void __init overo_init(void)
|
||||
else
|
||||
printk(KERN_ERR "could not obtain gpio for "
|
||||
"OVERO_GPIO_USBH_CPEN\n");
|
||||
+ overo_opp_init();
|
||||
}
|
||||
|
||||
MACHINE_START(OVERO, "Gumstsix Overo")
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
From f7580811a6d3ac015a8401388124e746651ab64c 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/19] 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
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From 3a51f3ffe8299bcc28a6be1bdcd0e0ea39af2042 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/19] 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
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
From c37bb21e4f82e5d88af21f7dbcef407e7a9d5306 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/19] 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
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
From 717bd73868e57fde49a25104af9bb8b9c6400b67 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/19] 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
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
From be5bdabb6206f106f0dcf91b0e90474d23773416 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/19] 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
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
From 50f4db415d1ee9ee5100214cc89cf5df1ee1c1e2 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/19] 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
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
From 3a9b78f58772645a9e1337454faed4e313e55368 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/19] 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
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
From 444b19e90ae45ccd68c84285fe8339d797a08911 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/19] 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
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
From 40c41b250b9430b9d9998751fdf7e03201d1784e 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/19] 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
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From 72eb0b4978e15f56c99900ec8da10b91864eda98 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/19] 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
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
From 42e395f0dcc618300267f440f613572635eb2e55 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/19] 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
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From 0c5c41f6bcf77b388f49615ac28ccde294e7a5bd 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/19] 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
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From a66e4a5a5ee1d98fafab60935bddd28bbd440628 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/19] 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
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
From 6e99ca0e5780932988471f106099c98595cb0aa3 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/19] 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
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
From 53d08ca85f9b623e25ba9a976bc3315f3784a3a7 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/19] 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
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
From 1f77cf1150d5e0205ab3f588ab25cbdf65acdc40 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/19] 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 006dc26..9393e75 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
|
||||
|
||||
@@ -778,6 +781,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);
|
||||
@@ -850,6 +903,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
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
From a74b74a5555c741ed3df896096e33b853995631e 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/66] 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
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From 1ae1b5f053cf36bd0f913e83f3b136fec8152d4d 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/66] 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
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
From 39af22a79232373764904576f31572f1db76af10 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/66] 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
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
From 25cbe45440ea89a3b0f6f7ed326d3d476d53068b 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/66] 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
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
From 6d3e6d3640052cac958d61c44597cc216f6ee09f 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/66] 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
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From 06f37751af77192b424b2b0ff17dc08de65faba0 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/66] 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
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From f797d22121404eac7b63f1291409f96bcab51c11 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/66] 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
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
From 63ee41d794d9c555f84205517a68509848988760 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/66] 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
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
From 4d3024428f5c3ef5295e6f6fb257ae118b3f93a1 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/66] 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
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
From 537de3a67c0c86586eacffde40673b727242dc3a 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/66] 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
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
From 875728807ff001b67a1e0535de5ad2cd3c41d47c 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/66] 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 6a58887..4323f8f 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
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
From d13e5edd7284bedcf5952e1b6490e39ad843cb91 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/66] 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
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
From 12f188f2e59394ec1f1c8c0a4439f48ec16bc336 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/66] 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
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From c4711786986af0cce654f493426ee0a1055e4b17 Mon Sep 17 00:00:00 2001
|
||||
From: Breno Leitao <leitao@linux.vnet.ibm.com>
|
||||
Date: Mon, 20 Dec 2010 09:02:37 +0000
|
||||
Subject: [PATCH 14/66] ehea: Avoid changing vlan flags
|
||||
|
||||
This patch avoids disabling the vlan flags using ethtool.
|
||||
|
||||
Signed-off-by: Breno Leitao <leitao@linux.vnet.ibm.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ehea/ehea_ethtool.c | 7 +++++++
|
||||
1 files changed, 7 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
|
||||
index 1f37ee6..d6cf502 100644
|
||||
--- a/drivers/net/ehea/ehea_ethtool.c
|
||||
+++ b/drivers/net/ehea/ehea_ethtool.c
|
||||
@@ -263,6 +263,13 @@ static void ehea_get_ethtool_stats(struct net_device *dev,
|
||||
|
||||
static int ehea_set_flags(struct net_device *dev, u32 data)
|
||||
{
|
||||
+ /* Avoid changing the VLAN flags */
|
||||
+ if ((data & (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN)) !=
|
||||
+ (ethtool_op_get_flags(dev) & (ETH_FLAG_RXVLAN |
|
||||
+ ETH_FLAG_TXVLAN))){
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
|
||||
| ETH_FLAG_TXVLAN
|
||||
| ETH_FLAG_RXVLAN);
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
From d39cd5e99a0ad88aba6793fb5e5f34e29cda6e6f Mon Sep 17 00:00:00 2001
|
||||
From: stephen hemminger <shemminger@vyatta.com>
|
||||
Date: Mon, 20 Dec 2010 17:58:33 +0000
|
||||
Subject: [PATCH 15/66] ppp: allow disabling multilink protocol ID compression
|
||||
|
||||
Linux would not connect to other router running old version Cisco IOS (12.0).
|
||||
This is most likely a bug in that version of IOS, since it is fixed
|
||||
in later versions. As a workaround this patch allows a module parameter
|
||||
to be set to disable compressing the protocol ID.
|
||||
|
||||
See: https://bugzilla.vyatta.com/show_bug.cgi?id=3979
|
||||
|
||||
RFC 1990 allows an implementation to formulate MP fragments as if protocol
|
||||
compression had been negotiated. This allows us to always send compressed
|
||||
protocol IDs. But some implementations don't accept MP fragments with
|
||||
compressed protocol IDs. This parameter allows us to interoperate with
|
||||
them. The default value of the configurable parameter is the same as the
|
||||
current behavior: protocol compression is enabled. If protocol compression
|
||||
is disabled we will not send compressed protocol IDs.
|
||||
|
||||
This is based on an earlier patch by Bob Gilligan (using a sysctl).
|
||||
Module parameter is writable to allow for enabling even if ppp
|
||||
is already loaded for other uses.
|
||||
|
||||
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
|
||||
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
|
||||
Acked-by: Paul Mackerras <paulus@samba.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ppp_generic.c | 9 +++++++--
|
||||
1 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
|
||||
index 3965997..89294b4 100644
|
||||
--- a/drivers/net/ppp_generic.c
|
||||
+++ b/drivers/net/ppp_generic.c
|
||||
@@ -1285,6 +1285,11 @@ ppp_push(struct ppp *ppp)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPP_MULTILINK
|
||||
+static bool mp_protocol_compress __read_mostly = true;
|
||||
+module_param(mp_protocol_compress, bool, S_IRUGO | S_IWUSR);
|
||||
+MODULE_PARM_DESC(mp_protocol_compress,
|
||||
+ "compress protocol id in multilink fragments");
|
||||
+
|
||||
/*
|
||||
* Divide a packet to be transmitted into fragments and
|
||||
* send them out the individual links.
|
||||
@@ -1347,10 +1352,10 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
|
||||
if (nfree == 0 || nfree < navail / 2)
|
||||
return 0; /* can't take now, leave it in xmit_pending */
|
||||
|
||||
- /* Do protocol field compression (XXX this should be optional) */
|
||||
+ /* Do protocol field compression */
|
||||
p = skb->data;
|
||||
len = skb->len;
|
||||
- if (*p == 0) {
|
||||
+ if (*p == 0 && mp_protocol_compress) {
|
||||
++p;
|
||||
--len;
|
||||
}
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From 4a5fc4e179d79c79ad87bfc12a2d7e9b2371e40c Mon Sep 17 00:00:00 2001
|
||||
From: Dan Carpenter <error27@gmail.com>
|
||||
Date: Thu, 23 Dec 2010 19:17:34 +0000
|
||||
Subject: [PATCH 16/66] skfp: testing the wrong variable in skfp_driver_init()
|
||||
|
||||
The intent here was to test if the allocation failed but we tested
|
||||
"SharedMemSize" instead of "SharedMemAddr" by mistake.
|
||||
|
||||
Signed-off-by: Dan Carpenter <error27@gmail.com>
|
||||
Reviewed-by: Jiri Pirko <jpirko@redhat.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/skfp/skfddi.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
|
||||
index 0a66fed..16c6265 100644
|
||||
--- a/drivers/net/skfp/skfddi.c
|
||||
+++ b/drivers/net/skfp/skfddi.c
|
||||
@@ -412,7 +412,7 @@ static int skfp_driver_init(struct net_device *dev)
|
||||
bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev,
|
||||
bp->SharedMemSize,
|
||||
&bp->SharedMemDMA);
|
||||
- if (!bp->SharedMemSize) {
|
||||
+ if (!bp->SharedMemAddr) {
|
||||
printk("could not allocate mem for ");
|
||||
printk("hardware module: %ld byte\n",
|
||||
bp->SharedMemSize);
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
From 7f984b55acb6530bf854bfcac13104228f3336c1 Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Tue, 28 Dec 2010 21:08:57 +0100
|
||||
Subject: [PATCH 17/66] ASoC: codecs: Add missing control_type initialization
|
||||
|
||||
Some codec drivers do not initialize the control_type field in their private
|
||||
device struct, but still use it when calling snd_soc_codec_set_cache_io.
|
||||
This patch fixes the issue by properly initializing it in the drivers probe
|
||||
functions.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Cc: stable@kernel.org (for 2.6.37 only)
|
||||
---
|
||||
sound/soc/codecs/wm8940.c | 1 +
|
||||
sound/soc/codecs/wm8955.c | 1 +
|
||||
sound/soc/codecs/wm8960.c | 1 +
|
||||
sound/soc/codecs/wm8971.c | 1 +
|
||||
sound/soc/codecs/wm9081.c | 1 +
|
||||
5 files changed, 5 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
|
||||
index 2cb16f8..23086e2 100644
|
||||
--- a/sound/soc/codecs/wm8940.c
|
||||
+++ b/sound/soc/codecs/wm8940.c
|
||||
@@ -768,6 +768,7 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
i2c_set_clientdata(i2c, wm8940);
|
||||
wm8940->control_data = i2c;
|
||||
+ wm8940->control_type = SND_SOC_I2C;
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
&soc_codec_dev_wm8940, &wm8940_dai, 1);
|
||||
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
|
||||
index 9cbab8e..a2ad91d 100644
|
||||
--- a/sound/soc/codecs/wm8955.c
|
||||
+++ b/sound/soc/codecs/wm8955.c
|
||||
@@ -1003,6 +1003,7 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, wm8955);
|
||||
+ wm8955->control_type = SND_SOC_I2C;
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
&soc_codec_dev_wm8955, &wm8955_dai, 1);
|
||||
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
|
||||
index 21986c4..ff6ff2f 100644
|
||||
--- a/sound/soc/codecs/wm8960.c
|
||||
+++ b/sound/soc/codecs/wm8960.c
|
||||
@@ -1013,6 +1013,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, wm8960);
|
||||
+ wm8960->control_type = SND_SOC_I2C;
|
||||
wm8960->control_data = i2c;
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
|
||||
index 63f6dbf..9f18db6 100644
|
||||
--- a/sound/soc/codecs/wm8971.c
|
||||
+++ b/sound/soc/codecs/wm8971.c
|
||||
@@ -718,6 +718,7 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
|
||||
if (wm8971 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
+ wm8971->control_type = SND_SOC_I2C;
|
||||
i2c_set_clientdata(i2c, wm8971);
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
|
||||
index ecc7c37..a486670 100644
|
||||
--- a/sound/soc/codecs/wm9081.c
|
||||
+++ b/sound/soc/codecs/wm9081.c
|
||||
@@ -1335,6 +1335,7 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, wm9081);
|
||||
+ wm9081->control_type = SND_SOC_I2C;
|
||||
wm9081->control_data = i2c;
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
From d24eb0db9c8a7ceecae860bdc636ed1e8a86943a Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Tue, 28 Dec 2010 21:37:56 +0100
|
||||
Subject: [PATCH 18/66] ASoC: codecs: max98088: Fix register cache incoherency
|
||||
|
||||
The multi-component patch(commit f0fba2ad1) moved the allocation of the
|
||||
register cache from the driver to the ASoC core. Most drivers where adjusted to
|
||||
this, but the max98088 driver still uses its own register cache for its
|
||||
private functions, while functions from the ASoC core use the generic cache.
|
||||
Thus we end up with two from each other incoherent caches, which can lead to
|
||||
undefined behaviour.
|
||||
This patch fixes the issue by changing the max98088 driver to use the
|
||||
generic register cache in its private functions.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Cc: Peter Hsiang <Peter.Hsiang@maxim-ic.com>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Cc: stable@kernel.org (for 2.6.37 only)
|
||||
---
|
||||
sound/soc/codecs/max98088.c | 10 ++++------
|
||||
1 files changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
|
||||
index d63e287..6447dbb 100644
|
||||
--- a/sound/soc/codecs/max98088.c
|
||||
+++ b/sound/soc/codecs/max98088.c
|
||||
@@ -40,7 +40,6 @@ struct max98088_cdata {
|
||||
};
|
||||
|
||||
struct max98088_priv {
|
||||
- u8 reg_cache[M98088_REG_CNT];
|
||||
enum max98088_type devtype;
|
||||
void *control_data;
|
||||
struct max98088_pdata *pdata;
|
||||
@@ -1588,7 +1587,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
|
||||
|
||||
static void max98088_sync_cache(struct snd_soc_codec *codec)
|
||||
{
|
||||
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int i;
|
||||
|
||||
if (!codec->cache_sync)
|
||||
@@ -1599,14 +1598,14 @@ static void max98088_sync_cache(struct snd_soc_codec *codec)
|
||||
/* write back cached values if they're writeable and
|
||||
* different from the hardware default.
|
||||
*/
|
||||
- for (i = 1; i < ARRAY_SIZE(max98088->reg_cache); i++) {
|
||||
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
|
||||
if (!max98088_access[i].writable)
|
||||
continue;
|
||||
|
||||
- if (max98088->reg_cache[i] == max98088_reg[i])
|
||||
+ if (reg_cache[i] == max98088_reg[i])
|
||||
continue;
|
||||
|
||||
- snd_soc_write(codec, i, max98088->reg_cache[i]);
|
||||
+ snd_soc_write(codec, i, reg_cache[i]);
|
||||
}
|
||||
|
||||
codec->cache_sync = 0;
|
||||
@@ -1951,7 +1950,6 @@ static int max98088_probe(struct snd_soc_codec *codec)
|
||||
int ret = 0;
|
||||
|
||||
codec->cache_sync = 1;
|
||||
- memcpy(codec->reg_cache, max98088_reg, sizeof(max98088_reg));
|
||||
|
||||
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
|
||||
if (ret != 0) {
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
From beebca312009e9567d5e0229ea6b82bdf9a864cf Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Tue, 28 Dec 2010 21:37:57 +0100
|
||||
Subject: [PATCH 19/66] ASoC: codecs: wm8523: Fix register cache incoherency
|
||||
|
||||
The multi-component patch(commit f0fba2ad1) moved the allocation of the
|
||||
register cache from the driver to the ASoC core. Most drivers where adjusted to
|
||||
this, but the wm8523 driver still uses its own register cache for its
|
||||
private functions, while functions from the ASoC core use the generic cache.
|
||||
Thus we end up with two from each other incoherent caches, which can lead to
|
||||
undefined behaviour.
|
||||
This patch fixes the issue by changing the wm8523 driver to use the
|
||||
generic register cache in its private functions.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Cc: Ian Lartey <ian@opensource.wolfsonmicro.com>
|
||||
Cc: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Cc: stable@kernel.org (for 2.6.37 only)
|
||||
---
|
||||
sound/soc/codecs/wm8523.c | 9 +++++----
|
||||
1 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
|
||||
index 9a433a5..deca79e 100644
|
||||
--- a/sound/soc/codecs/wm8523.c
|
||||
+++ b/sound/soc/codecs/wm8523.c
|
||||
@@ -41,7 +41,6 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
|
||||
/* codec private data */
|
||||
struct wm8523_priv {
|
||||
enum snd_soc_control_type control_type;
|
||||
- u16 reg_cache[WM8523_REGISTER_COUNT];
|
||||
struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
|
||||
unsigned int sysclk;
|
||||
unsigned int rate_constraint_list[WM8523_NUM_RATES];
|
||||
@@ -314,6 +313,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int ret, i;
|
||||
|
||||
switch (level) {
|
||||
@@ -344,7 +344,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
|
||||
/* Sync back default/cached values */
|
||||
for (i = WM8523_AIF_CTRL1;
|
||||
i < WM8523_MAX_REGISTER; i++)
|
||||
- snd_soc_write(codec, i, wm8523->reg_cache[i]);
|
||||
+ snd_soc_write(codec, i, reg_cache[i]);
|
||||
|
||||
|
||||
msleep(100);
|
||||
@@ -414,6 +414,7 @@ static int wm8523_resume(struct snd_soc_codec *codec)
|
||||
static int wm8523_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int ret, i;
|
||||
|
||||
codec->hw_write = (hw_write_t)i2c_master_send;
|
||||
@@ -470,8 +471,8 @@ static int wm8523_probe(struct snd_soc_codec *codec)
|
||||
}
|
||||
|
||||
/* Change some default settings - latch VU and enable ZC */
|
||||
- wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
|
||||
- wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
|
||||
+ reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
|
||||
+ reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
|
||||
|
||||
wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
From 52ca353bc8597dcc1d6d7abc03eecc1b452d79c9 Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Tue, 28 Dec 2010 21:37:58 +0100
|
||||
Subject: [PATCH 20/66] ASoC: codecs: wm8741: Fix register cache incoherency
|
||||
|
||||
The multi-component patch(commit f0fba2ad1) moved the allocation of the
|
||||
register cache from the driver to the ASoC core. Most drivers where adjusted to
|
||||
this, but the wm8741 driver still uses its own register cache for its
|
||||
private functions, while functions from the ASoC core use the generic cache.
|
||||
Thus we end up with two from each other incoherent caches, which can lead to
|
||||
undefined behaviour.
|
||||
This patch fixes the issue by changing the wm8741 driver to use the
|
||||
generic register cache in its private functions.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Cc: Ian Lartey <ian@opensource.wolfsonmicro.com>
|
||||
Cc: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Cc: stable@kernel.org (for 2.6.37 only)
|
||||
---
|
||||
sound/soc/codecs/wm8741.c | 10 +++++-----
|
||||
1 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
|
||||
index 90e31e9..aea60ef 100644
|
||||
--- a/sound/soc/codecs/wm8741.c
|
||||
+++ b/sound/soc/codecs/wm8741.c
|
||||
@@ -41,7 +41,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
|
||||
/* codec private data */
|
||||
struct wm8741_priv {
|
||||
enum snd_soc_control_type control_type;
|
||||
- u16 reg_cache[WM8741_REGISTER_COUNT];
|
||||
struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
|
||||
unsigned int sysclk;
|
||||
struct snd_pcm_hw_constraint_list *sysclk_constraints;
|
||||
@@ -422,6 +421,7 @@ static int wm8741_resume(struct snd_soc_codec *codec)
|
||||
static int wm8741_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int ret = 0;
|
||||
|
||||
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
|
||||
@@ -437,10 +437,10 @@ static int wm8741_probe(struct snd_soc_codec *codec)
|
||||
}
|
||||
|
||||
/* Change some default settings - latch VU */
|
||||
- wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
|
||||
- wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
|
||||
- wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
|
||||
- wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
|
||||
+ reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
|
||||
+ reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
|
||||
+ reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
|
||||
+ reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
|
||||
|
||||
snd_soc_add_controls(codec, wm8741_snd_controls,
|
||||
ARRAY_SIZE(wm8741_snd_controls));
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
From f578a188e8b21be623b48bb0eb3a92174c2e5b82 Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Tue, 28 Dec 2010 21:37:59 +0100
|
||||
Subject: [PATCH 21/66] ASoC: codecs: wm8904: Fix register cache incoherency
|
||||
|
||||
The multi-component patch(commit f0fba2ad1) moved the allocation of the
|
||||
register cache from the driver to the ASoC core. Most drivers where adjusted to
|
||||
this, but the wm8904 driver still uses its own register cache for its
|
||||
private functions, while functions from the ASoC core use the generic cache.
|
||||
Thus we end up with two from each other incoherent caches, which can lead to
|
||||
undefined behaviour.
|
||||
This patch fixes the issue by changing the wm8904 driver to use the
|
||||
generic register cache in its private functions.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Cc: Ian Lartey <ian@opensource.wolfsonmicro.com>
|
||||
Cc: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Cc: stable@kernel.org (for 2.6.37 only)
|
||||
---
|
||||
sound/soc/codecs/wm8904.c | 37 ++++++++++++++++++-------------------
|
||||
1 files changed, 18 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
|
||||
index 9001cc4..1ec12ef 100644
|
||||
--- a/sound/soc/codecs/wm8904.c
|
||||
+++ b/sound/soc/codecs/wm8904.c
|
||||
@@ -50,8 +50,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
|
||||
/* codec private data */
|
||||
struct wm8904_priv {
|
||||
|
||||
- u16 reg_cache[WM8904_MAX_REGISTER + 1];
|
||||
-
|
||||
enum wm8904_type devtype;
|
||||
void *control_data;
|
||||
|
||||
@@ -2094,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
|
||||
|
||||
static void wm8904_sync_cache(struct snd_soc_codec *codec)
|
||||
{
|
||||
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int i;
|
||||
|
||||
if (!codec->cache_sync)
|
||||
@@ -2105,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
|
||||
/* Sync back cached values if they're different from the
|
||||
* hardware default.
|
||||
*/
|
||||
- for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
|
||||
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
|
||||
if (!wm8904_access[i].writable)
|
||||
continue;
|
||||
|
||||
- if (wm8904->reg_cache[i] == wm8904_reg[i])
|
||||
+ if (reg_cache[i] == wm8904_reg[i])
|
||||
continue;
|
||||
|
||||
- snd_soc_write(codec, i, wm8904->reg_cache[i]);
|
||||
+ snd_soc_write(codec, i, reg_cache[i]);
|
||||
}
|
||||
|
||||
codec->cache_sync = 0;
|
||||
@@ -2371,6 +2369,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8904_pdata *pdata = wm8904->pdata;
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int ret, i;
|
||||
|
||||
codec->cache_sync = 1;
|
||||
@@ -2437,19 +2436,19 @@ static int wm8904_probe(struct snd_soc_codec *codec)
|
||||
}
|
||||
|
||||
/* Change some default settings - latch VU and enable ZC */
|
||||
- wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
|
||||
- wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
|
||||
- wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
|
||||
- wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
|
||||
- wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
|
||||
+ reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
|
||||
+ reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
|
||||
+ reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
|
||||
+ reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
|
||||
+ reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
|
||||
WM8904_HPOUTLZC;
|
||||
- wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
|
||||
+ reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
|
||||
WM8904_HPOUTRZC;
|
||||
- wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
|
||||
+ reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
|
||||
WM8904_LINEOUTLZC;
|
||||
- wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
|
||||
+ reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
|
||||
WM8904_LINEOUTRZC;
|
||||
- wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
|
||||
+ reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
|
||||
|
||||
/* Apply configuration from the platform data. */
|
||||
if (wm8904->pdata) {
|
||||
@@ -2457,23 +2456,23 @@ static int wm8904_probe(struct snd_soc_codec *codec)
|
||||
if (!pdata->gpio_cfg[i])
|
||||
continue;
|
||||
|
||||
- wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i]
|
||||
+ reg_cache[WM8904_GPIO_CONTROL_1 + i]
|
||||
= pdata->gpio_cfg[i] & 0xffff;
|
||||
}
|
||||
|
||||
/* Zero is the default value for these anyway */
|
||||
for (i = 0; i < WM8904_MIC_REGS; i++)
|
||||
- wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
|
||||
+ reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
|
||||
= pdata->mic_cfg[i];
|
||||
}
|
||||
|
||||
/* Set Class W by default - this will be managed by the Class
|
||||
* G widget at runtime where bypass paths are available.
|
||||
*/
|
||||
- wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
|
||||
+ reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
|
||||
|
||||
/* Use normal bias source */
|
||||
- wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
|
||||
+ reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
|
||||
|
||||
wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
From 715920d04c787ed718327da53cf51689e51ef3ce Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Tue, 28 Dec 2010 21:38:00 +0100
|
||||
Subject: [PATCH 22/66] ASoC: codecs: wm8955: Fix register cache incoherency
|
||||
|
||||
The multi-component patch(commit f0fba2ad1) moved the allocation of the
|
||||
register cache from the driver to the ASoC core. Most drivers where adjusted to
|
||||
this, but the wm8955 driver still uses its own register cache for its
|
||||
private functions, while functions from the ASoC core use the generic cache.
|
||||
Thus we end up with two from each other incoherent caches, which can lead to
|
||||
undefined behaviour.
|
||||
This patch fixes the issue by changing the wm8955 driver to use the
|
||||
generic register cache in its private functions.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Cc: stable@kernel.org (for 2.6.37 only)
|
||||
---
|
||||
sound/soc/codecs/wm8955.c | 30 +++++++++++++++---------------
|
||||
1 files changed, 15 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
|
||||
index a2ad91d..2ac35b0 100644
|
||||
--- a/sound/soc/codecs/wm8955.c
|
||||
+++ b/sound/soc/codecs/wm8955.c
|
||||
@@ -42,8 +42,6 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
|
||||
struct wm8955_priv {
|
||||
enum snd_soc_control_type control_type;
|
||||
|
||||
- u16 reg_cache[WM8955_MAX_REGISTER + 1];
|
||||
-
|
||||
unsigned int mclk_rate;
|
||||
|
||||
int deemph;
|
||||
@@ -768,6 +766,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int ret, i;
|
||||
|
||||
switch (level) {
|
||||
@@ -800,14 +799,14 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
|
||||
/* Sync back cached values if they're
|
||||
* different from the hardware default.
|
||||
*/
|
||||
- for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) {
|
||||
+ for (i = 0; i < codec->driver->reg_cache_size; i++) {
|
||||
if (i == WM8955_RESET)
|
||||
continue;
|
||||
|
||||
- if (wm8955->reg_cache[i] == wm8955_reg[i])
|
||||
+ if (reg_cache[i] == wm8955_reg[i])
|
||||
continue;
|
||||
|
||||
- snd_soc_write(codec, i, wm8955->reg_cache[i]);
|
||||
+ snd_soc_write(codec, i, reg_cache[i]);
|
||||
}
|
||||
|
||||
/* Enable VREF and VMID */
|
||||
@@ -902,6 +901,7 @@ static int wm8955_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int ret, i;
|
||||
|
||||
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
|
||||
@@ -934,25 +934,25 @@ static int wm8955_probe(struct snd_soc_codec *codec)
|
||||
}
|
||||
|
||||
/* Change some default settings - latch VU and enable ZC */
|
||||
- wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
|
||||
- wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
|
||||
- wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
|
||||
- wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
|
||||
- wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
|
||||
- wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
|
||||
- wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
|
||||
+ reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
|
||||
+ reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
|
||||
+ reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
|
||||
+ reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
|
||||
+ reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
|
||||
+ reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
|
||||
+ reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
|
||||
|
||||
/* Also enable adaptive bass boost by default */
|
||||
- wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
|
||||
+ reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
|
||||
|
||||
/* Set platform data values */
|
||||
if (pdata) {
|
||||
if (pdata->out2_speaker)
|
||||
- wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
|
||||
+ reg_cache[WM8955_ADDITIONAL_CONTROL_2]
|
||||
|= WM8955_ROUT2INV;
|
||||
|
||||
if (pdata->monoin_diff)
|
||||
- wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
|
||||
+ reg_cache[WM8955_MONO_OUT_MIX_1]
|
||||
|= WM8955_DMEN;
|
||||
}
|
||||
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
From 7f87e30ef29951f4509a7f86acf00e1ba48af54a Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Tue, 28 Dec 2010 21:38:01 +0100
|
||||
Subject: [PATCH 23/66] ASoC: codecs: wm8962: Fix register cache incoherency
|
||||
|
||||
The multi-component patch(commit f0fba2ad1) moved the allocation of the
|
||||
register cache from the driver to the ASoC core. Most drivers where adjusted to
|
||||
this, but the wm8962 driver still uses its own register cache for its
|
||||
private functions, while functions from the ASoC core use the generic cache.
|
||||
Thus we end up with two from each other incoherent caches, which can lead to
|
||||
undefined behaviour.
|
||||
This patch fixes the issue by changing the wm8962 driver to use the
|
||||
generic register cache in its private functions.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Cc: stable@kernel.org (for 2.6.37 only)
|
||||
---
|
||||
sound/soc/codecs/wm8962.c | 45 ++++++++++++++++++++-------------------------
|
||||
1 files changed, 20 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
|
||||
index 1304ca9..7c421cc 100644
|
||||
--- a/sound/soc/codecs/wm8962.c
|
||||
+++ b/sound/soc/codecs/wm8962.c
|
||||
@@ -52,8 +52,6 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
|
||||
struct wm8962_priv {
|
||||
struct snd_soc_codec *codec;
|
||||
|
||||
- u16 reg_cache[WM8962_MAX_REGISTER + 1];
|
||||
-
|
||||
int sysclk;
|
||||
int sysclk_rate;
|
||||
|
||||
@@ -1991,8 +1989,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
|
||||
- u16 *reg_cache = wm8962->reg_cache;
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int ret;
|
||||
|
||||
/* Apply the update (if any) */
|
||||
@@ -2020,8 +2017,7 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
|
||||
- u16 *reg_cache = wm8962->reg_cache;
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int ret;
|
||||
|
||||
/* Apply the update (if any) */
|
||||
@@ -2329,8 +2325,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
|
||||
- u16 *reg_cache = wm8962->reg_cache;
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int reg;
|
||||
|
||||
switch (w->shift) {
|
||||
@@ -2719,7 +2714,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
|
||||
|
||||
static void wm8962_sync_cache(struct snd_soc_codec *codec)
|
||||
{
|
||||
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int i;
|
||||
|
||||
if (!codec->cache_sync)
|
||||
@@ -2732,13 +2727,13 @@ static void wm8962_sync_cache(struct snd_soc_codec *codec)
|
||||
/* Sync back cached values if they're different from the
|
||||
* hardware default.
|
||||
*/
|
||||
- for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
|
||||
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
|
||||
if (i == WM8962_SOFTWARE_RESET)
|
||||
continue;
|
||||
- if (wm8962->reg_cache[i] == wm8962_reg[i])
|
||||
+ if (reg_cache[i] == wm8962_reg[i])
|
||||
continue;
|
||||
|
||||
- snd_soc_write(codec, i, wm8962->reg_cache[i]);
|
||||
+ snd_soc_write(codec, i, reg_cache[i]);
|
||||
}
|
||||
|
||||
codec->cache_sync = 0;
|
||||
@@ -3406,12 +3401,11 @@ EXPORT_SYMBOL_GPL(wm8962_mic_detect);
|
||||
#ifdef CONFIG_PM
|
||||
static int wm8962_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
|
||||
u16 *reg_cache = codec->reg_cache;
|
||||
int i;
|
||||
|
||||
/* Restore the registers */
|
||||
- for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
|
||||
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
|
||||
switch (i) {
|
||||
case WM8962_SOFTWARE_RESET:
|
||||
continue;
|
||||
@@ -3705,6 +3699,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
|
||||
struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
|
||||
struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
|
||||
dev);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int i, trigger, irq_pol;
|
||||
|
||||
wm8962->codec = codec;
|
||||
@@ -3804,7 +3799,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
|
||||
|
||||
/* Put the speakers into mono mode? */
|
||||
if (pdata->spk_mono)
|
||||
- wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2]
|
||||
+ reg_cache[WM8962_CLASS_D_CONTROL_2]
|
||||
|= WM8962_SPK_MONO;
|
||||
|
||||
/* Micbias setup, detection enable and detection
|
||||
@@ -3819,16 +3814,16 @@ static int wm8962_probe(struct snd_soc_codec *codec)
|
||||
}
|
||||
|
||||
/* Latch volume update bits */
|
||||
- wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
|
||||
- wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
|
||||
- wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
|
||||
- wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;
|
||||
- wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
|
||||
- wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
|
||||
- wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
|
||||
- wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
|
||||
- wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
|
||||
- wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
|
||||
+ reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
|
||||
+ reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
|
||||
+ reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
|
||||
+ reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;
|
||||
+ reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
|
||||
+ reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
|
||||
+ reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
|
||||
+ reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
|
||||
+ reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
|
||||
+ reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
|
||||
|
||||
wm8962_add_widgets(codec);
|
||||
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
From da280f51d0b341282b4181eb3235f774b0446584 Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Tue, 28 Dec 2010 21:38:02 +0100
|
||||
Subject: [PATCH 24/66] ASoC: codecs: wm9090: Fix register cache incoherency
|
||||
|
||||
The multi-component patch(commit f0fba2ad1) moved the allocation of the
|
||||
register cache from the driver to the ASoC core. Most drivers where adjusted to
|
||||
this, but the wm9090 driver still uses its own register cache for its
|
||||
private functions, while functions from the ASoC core use the generic cache.
|
||||
Thus we end up with two from each other incoherent caches, which can lead to
|
||||
undefined behaviour.
|
||||
This patch fixes the issue by changing the wm9090 driver to use the
|
||||
generic register cache in its private functions.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Cc: stable@kernel.org (for 2.6.37 only)
|
||||
---
|
||||
sound/soc/codecs/wm9090.c | 18 +++++++++---------
|
||||
1 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
|
||||
index 99c046b..6e5f64f 100644
|
||||
--- a/sound/soc/codecs/wm9090.c
|
||||
+++ b/sound/soc/codecs/wm9090.c
|
||||
@@ -141,7 +141,6 @@ static const u16 wm9090_reg_defaults[] = {
|
||||
/* This struct is used to save the context */
|
||||
struct wm9090_priv {
|
||||
struct mutex mutex;
|
||||
- u16 reg_cache[WM9090_MAX_REGISTER + 1];
|
||||
struct wm9090_platform_data pdata;
|
||||
void *control_data;
|
||||
};
|
||||
@@ -552,6 +551,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
|
||||
static int wm9090_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int ret;
|
||||
|
||||
codec->control_data = wm9090->control_data;
|
||||
@@ -576,22 +576,22 @@ static int wm9090_probe(struct snd_soc_codec *codec)
|
||||
/* Configure some defaults; they will be written out when we
|
||||
* bring the bias up.
|
||||
*/
|
||||
- wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
|
||||
+ reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
|
||||
| WM9090_IN1A_ZC;
|
||||
- wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
|
||||
+ reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
|
||||
| WM9090_IN1B_ZC;
|
||||
- wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
|
||||
+ reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
|
||||
| WM9090_IN2A_ZC;
|
||||
- wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
|
||||
+ reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
|
||||
| WM9090_IN2B_ZC;
|
||||
- wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
|
||||
+ reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
|
||||
WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
|
||||
- wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
|
||||
+ reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
|
||||
WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
|
||||
- wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
|
||||
+ reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
|
||||
WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
|
||||
|
||||
- wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
|
||||
+ reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
|
||||
|
||||
wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,514 @@
|
||||
From 776065e36de1d5eb9e33ff908352fef4050ab38d Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Tue, 28 Dec 2010 21:38:03 +0100
|
||||
Subject: [PATCH 25/66] ASoC: codecs: wm8753: Fix register cache incoherency
|
||||
|
||||
The multi-component patch(commit f0fba2ad1) moved the allocation of the
|
||||
register cache from the driver to the ASoC core. Most drivers where adjusted to
|
||||
this, but the wm8753 driver still uses its own register cache for its
|
||||
private functions, while functions from the ASoC core use the generic cache.
|
||||
Furthermore the generic cache uses zero-based numbering while the wm8753 cache
|
||||
uses one-based numbering.
|
||||
Thus we end up with two from each other incoherent caches, which leads to undefined
|
||||
behaviour and crashes.
|
||||
This patch fixes the issue by changing the wm8753 driver to use the generic
|
||||
register cache in its private functions.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
---
|
||||
sound/soc/codecs/wm8753.c | 226 +++++++++++++++++----------------------------
|
||||
1 files changed, 83 insertions(+), 143 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
|
||||
index 8f679a1..87caae5 100644
|
||||
--- a/sound/soc/codecs/wm8753.c
|
||||
+++ b/sound/soc/codecs/wm8753.c
|
||||
@@ -65,22 +65,22 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
|
||||
* are using 2 wire for device control, so we cache them instead.
|
||||
*/
|
||||
static const u16 wm8753_reg[] = {
|
||||
- 0x0008, 0x0000, 0x000a, 0x000a,
|
||||
- 0x0033, 0x0000, 0x0007, 0x00ff,
|
||||
- 0x00ff, 0x000f, 0x000f, 0x007b,
|
||||
- 0x0000, 0x0032, 0x0000, 0x00c3,
|
||||
- 0x00c3, 0x00c0, 0x0000, 0x0000,
|
||||
+ 0x0000, 0x0008, 0x0000, 0x000a,
|
||||
+ 0x000a, 0x0033, 0x0000, 0x0007,
|
||||
+ 0x00ff, 0x00ff, 0x000f, 0x000f,
|
||||
+ 0x007b, 0x0000, 0x0032, 0x0000,
|
||||
+ 0x00c3, 0x00c3, 0x00c0, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000,
|
||||
- 0x0000, 0x0000, 0x0000, 0x0055,
|
||||
- 0x0005, 0x0050, 0x0055, 0x0050,
|
||||
- 0x0055, 0x0050, 0x0055, 0x0079,
|
||||
- 0x0079, 0x0079, 0x0079, 0x0079,
|
||||
0x0000, 0x0000, 0x0000, 0x0000,
|
||||
- 0x0097, 0x0097, 0x0000, 0x0004,
|
||||
- 0x0000, 0x0083, 0x0024, 0x01ba,
|
||||
- 0x0000, 0x0083, 0x0024, 0x01ba,
|
||||
- 0x0000, 0x0000, 0x0000
|
||||
+ 0x0055, 0x0005, 0x0050, 0x0055,
|
||||
+ 0x0050, 0x0055, 0x0050, 0x0055,
|
||||
+ 0x0079, 0x0079, 0x0079, 0x0079,
|
||||
+ 0x0079, 0x0000, 0x0000, 0x0000,
|
||||
+ 0x0000, 0x0097, 0x0097, 0x0000,
|
||||
+ 0x0004, 0x0000, 0x0083, 0x0024,
|
||||
+ 0x01ba, 0x0000, 0x0083, 0x0024,
|
||||
+ 0x01ba, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
/* codec private data */
|
||||
@@ -88,57 +88,10 @@ struct wm8753_priv {
|
||||
enum snd_soc_control_type control_type;
|
||||
unsigned int sysclk;
|
||||
unsigned int pcmclk;
|
||||
- u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
|
||||
int dai_func;
|
||||
};
|
||||
|
||||
-/*
|
||||
- * read wm8753 register cache
|
||||
- */
|
||||
-static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
|
||||
- unsigned int reg)
|
||||
-{
|
||||
- u16 *cache = codec->reg_cache;
|
||||
- if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
|
||||
- return -1;
|
||||
- return cache[reg - 1];
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * write wm8753 register cache
|
||||
- */
|
||||
-static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
|
||||
- unsigned int reg, unsigned int value)
|
||||
-{
|
||||
- u16 *cache = codec->reg_cache;
|
||||
- if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
|
||||
- return;
|
||||
- cache[reg - 1] = value;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * write to the WM8753 register space
|
||||
- */
|
||||
-static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
|
||||
- unsigned int value)
|
||||
-{
|
||||
- u8 data[2];
|
||||
-
|
||||
- /* data is
|
||||
- * D15..D9 WM8753 register offset
|
||||
- * D8...D0 register data
|
||||
- */
|
||||
- data[0] = (reg << 1) | ((value >> 8) & 0x0001);
|
||||
- data[1] = value & 0x00ff;
|
||||
-
|
||||
- wm8753_write_reg_cache(codec, reg, value);
|
||||
- if (codec->hw_write(codec->control_data, data, 2) == 2)
|
||||
- return 0;
|
||||
- else
|
||||
- return -EIO;
|
||||
-}
|
||||
-
|
||||
-#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)
|
||||
+#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
|
||||
|
||||
/*
|
||||
* WM8753 Controls
|
||||
@@ -218,7 +171,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
- int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
|
||||
+ int mode = snd_soc_read(codec, WM8753_IOCTL);
|
||||
|
||||
ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
|
||||
return 0;
|
||||
@@ -228,7 +181,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
- int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
|
||||
+ int mode = snd_soc_read(codec, WM8753_IOCTL);
|
||||
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
|
||||
@@ -738,17 +691,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
|
||||
if (pll_id == WM8753_PLL1) {
|
||||
offset = 0;
|
||||
enable = 0x10;
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef;
|
||||
+ reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
|
||||
} else {
|
||||
offset = 4;
|
||||
enable = 0x8;
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7;
|
||||
+ reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
|
||||
}
|
||||
|
||||
if (!freq_in || !freq_out) {
|
||||
/* disable PLL */
|
||||
- wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
|
||||
- wm8753_write(codec, WM8753_CLOCK, reg);
|
||||
+ snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
|
||||
+ snd_soc_write(codec, WM8753_CLOCK, reg);
|
||||
return 0;
|
||||
} else {
|
||||
u16 value = 0;
|
||||
@@ -759,20 +712,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
|
||||
/* set up N and K PLL divisor ratios */
|
||||
/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
|
||||
value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
|
||||
- wm8753_write(codec, WM8753_PLL1CTL2 + offset, value);
|
||||
+ snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
|
||||
|
||||
/* bits 8:0 = PLL_K[17:9] */
|
||||
value = (pll_div.k & 0x03fe00) >> 9;
|
||||
- wm8753_write(codec, WM8753_PLL1CTL3 + offset, value);
|
||||
+ snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
|
||||
|
||||
/* bits 8:0 = PLL_K[8:0] */
|
||||
value = pll_div.k & 0x0001ff;
|
||||
- wm8753_write(codec, WM8753_PLL1CTL4 + offset, value);
|
||||
+ snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
|
||||
|
||||
/* set PLL as input and enable */
|
||||
- wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
|
||||
+ snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
|
||||
(pll_div.div2 << 3));
|
||||
- wm8753_write(codec, WM8753_CLOCK, reg | enable);
|
||||
+ snd_soc_write(codec, WM8753_CLOCK, reg | enable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -879,7 +832,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
- u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec;
|
||||
+ u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
|
||||
|
||||
/* interface format */
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
@@ -901,7 +854,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- wm8753_write(codec, WM8753_PCM, voice);
|
||||
+ snd_soc_write(codec, WM8753_PCM, voice);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -922,8 +875,8 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
|
||||
- u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
|
||||
- u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
|
||||
+ u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
|
||||
+ u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
|
||||
|
||||
/* bit size */
|
||||
switch (params_format(params)) {
|
||||
@@ -943,9 +896,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
/* sample rate */
|
||||
if (params_rate(params) * 384 == wm8753->pcmclk)
|
||||
srate |= 0x80;
|
||||
- wm8753_write(codec, WM8753_SRATE1, srate);
|
||||
+ snd_soc_write(codec, WM8753_SRATE1, srate);
|
||||
|
||||
- wm8753_write(codec, WM8753_PCM, voice);
|
||||
+ snd_soc_write(codec, WM8753_PCM, voice);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -958,8 +911,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
u16 voice, ioctl;
|
||||
|
||||
- voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f;
|
||||
- ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d;
|
||||
+ voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
|
||||
+ ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
|
||||
|
||||
/* set master/slave audio interface */
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
@@ -1013,8 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- wm8753_write(codec, WM8753_PCM, voice);
|
||||
- wm8753_write(codec, WM8753_IOCTL, ioctl);
|
||||
+ snd_soc_write(codec, WM8753_PCM, voice);
|
||||
+ snd_soc_write(codec, WM8753_IOCTL, ioctl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1026,16 +979,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
|
||||
|
||||
switch (div_id) {
|
||||
case WM8753_PCMDIV:
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f;
|
||||
- wm8753_write(codec, WM8753_CLOCK, reg | div);
|
||||
+ reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
|
||||
+ snd_soc_write(codec, WM8753_CLOCK, reg | div);
|
||||
break;
|
||||
case WM8753_BCLKDIV:
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7;
|
||||
- wm8753_write(codec, WM8753_SRATE2, reg | div);
|
||||
+ reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
|
||||
+ snd_soc_write(codec, WM8753_SRATE2, reg | div);
|
||||
break;
|
||||
case WM8753_VXCLKDIV:
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f;
|
||||
- wm8753_write(codec, WM8753_SRATE2, reg | div);
|
||||
+ reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
|
||||
+ snd_soc_write(codec, WM8753_SRATE2, reg | div);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@@ -1050,7 +1003,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
- u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0;
|
||||
+ u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
|
||||
|
||||
/* interface format */
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
@@ -1072,7 +1025,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- wm8753_write(codec, WM8753_HIFI, hifi);
|
||||
+ snd_soc_write(codec, WM8753_HIFI, hifi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1085,8 +1038,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
u16 ioctl, hifi;
|
||||
|
||||
- hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f;
|
||||
- ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae;
|
||||
+ hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
|
||||
+ ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
|
||||
|
||||
/* set master/slave audio interface */
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
@@ -1140,8 +1093,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- wm8753_write(codec, WM8753_HIFI, hifi);
|
||||
- wm8753_write(codec, WM8753_IOCTL, ioctl);
|
||||
+ snd_soc_write(codec, WM8753_HIFI, hifi);
|
||||
+ snd_soc_write(codec, WM8753_IOCTL, ioctl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1162,8 +1115,8 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
|
||||
- u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
|
||||
- u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
|
||||
+ u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
|
||||
+ u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
|
||||
int coeff;
|
||||
|
||||
/* is digital filter coefficient valid ? */
|
||||
@@ -1172,7 +1125,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||
printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
|
||||
return coeff;
|
||||
}
|
||||
- wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
|
||||
+ snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
|
||||
coeff_div[coeff].usb);
|
||||
|
||||
/* bit size */
|
||||
@@ -1190,7 +1143,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||
break;
|
||||
}
|
||||
|
||||
- wm8753_write(codec, WM8753_HIFI, hifi);
|
||||
+ snd_soc_write(codec, WM8753_HIFI, hifi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1201,8 +1154,8 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
u16 clock;
|
||||
|
||||
/* set clk source as pcmclk */
|
||||
- clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
|
||||
- wm8753_write(codec, WM8753_CLOCK, clock);
|
||||
+ clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
|
||||
+ snd_soc_write(codec, WM8753_CLOCK, clock);
|
||||
|
||||
if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
|
||||
return -EINVAL;
|
||||
@@ -1224,8 +1177,8 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
u16 clock;
|
||||
|
||||
/* set clk source as pcmclk */
|
||||
- clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
|
||||
- wm8753_write(codec, WM8753_CLOCK, clock);
|
||||
+ clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
|
||||
+ snd_soc_write(codec, WM8753_CLOCK, clock);
|
||||
|
||||
if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
|
||||
return -EINVAL;
|
||||
@@ -1239,8 +1192,8 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
u16 clock;
|
||||
|
||||
/* set clk source as mclk */
|
||||
- clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
|
||||
- wm8753_write(codec, WM8753_CLOCK, clock | 0x4);
|
||||
+ clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
|
||||
+ snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
|
||||
|
||||
if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
|
||||
return -EINVAL;
|
||||
@@ -1252,19 +1205,19 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
static int wm8753_mute(struct snd_soc_dai *dai, int mute)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
- u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
|
||||
+ u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
|
||||
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
|
||||
* make sure we check if they are not both active when we mute */
|
||||
if (mute && wm8753->dai_func == 1) {
|
||||
if (!codec->active)
|
||||
- wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
|
||||
+ snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
|
||||
} else {
|
||||
if (mute)
|
||||
- wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
|
||||
+ snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
|
||||
else
|
||||
- wm8753_write(codec, WM8753_DAC, mute_reg);
|
||||
+ snd_soc_write(codec, WM8753_DAC, mute_reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1273,23 +1226,23 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
|
||||
static int wm8753_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
- u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
|
||||
+ u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
/* set vmid to 50k and unmute dac */
|
||||
- wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
|
||||
+ snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
|
||||
break;
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
/* set vmid to 5k for quick power up */
|
||||
- wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
|
||||
+ snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
|
||||
break;
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
/* mute dac and set vmid to 500k, enable VREF */
|
||||
- wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
|
||||
+ snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
|
||||
break;
|
||||
case SND_SOC_BIAS_OFF:
|
||||
- wm8753_write(codec, WM8753_PWR1, 0x0001);
|
||||
+ snd_soc_write(codec, WM8753_PWR1, 0x0001);
|
||||
break;
|
||||
}
|
||||
codec->bias_level = level;
|
||||
@@ -1477,7 +1430,7 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
|
||||
else
|
||||
dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
|
||||
}
|
||||
- wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func);
|
||||
+ snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
|
||||
}
|
||||
|
||||
static void wm8753_work(struct work_struct *work)
|
||||
@@ -1495,22 +1448,19 @@ static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
|
||||
|
||||
static int wm8753_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
+ u16 *reg_cache = codec->reg_cache;
|
||||
int i;
|
||||
- u8 data[2];
|
||||
- u16 *cache = codec->reg_cache;
|
||||
|
||||
/* Sync reg_cache with the hardware */
|
||||
- for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
|
||||
- if (i + 1 == WM8753_RESET)
|
||||
+ for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
|
||||
+ if (i == WM8753_RESET)
|
||||
continue;
|
||||
|
||||
/* No point in writing hardware default values back */
|
||||
- if (cache[i] == wm8753_reg[i])
|
||||
+ if (reg_cache[i] == wm8753_reg[i])
|
||||
continue;
|
||||
|
||||
- data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
|
||||
- data[1] = cache[i] & 0x00ff;
|
||||
- codec->hw_write(codec->control_data, data, 2);
|
||||
+ snd_soc_write(codec, i, reg_cache[i]);
|
||||
}
|
||||
|
||||
wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
@@ -1548,7 +1498,7 @@ static int run_delayed_work(struct delayed_work *dwork)
|
||||
static int wm8753_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
|
||||
- int ret = 0, reg;
|
||||
+ int ret;
|
||||
|
||||
INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
|
||||
|
||||
@@ -1573,26 +1523,16 @@ static int wm8753_probe(struct snd_soc_codec *codec)
|
||||
msecs_to_jiffies(caps_charge));
|
||||
|
||||
/* set the update bits */
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
|
||||
- wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_RDAC);
|
||||
- wm8753_write(codec, WM8753_RDAC, reg | 0x0100);
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_LADC);
|
||||
- wm8753_write(codec, WM8753_LADC, reg | 0x0100);
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_RADC);
|
||||
- wm8753_write(codec, WM8753_RADC, reg | 0x0100);
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V);
|
||||
- wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100);
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
|
||||
- wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
|
||||
- wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
|
||||
- wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
|
||||
- wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
|
||||
- reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
|
||||
- wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
|
||||
+ snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
|
||||
|
||||
snd_soc_add_controls(codec, wm8753_snd_controls,
|
||||
ARRAY_SIZE(wm8753_snd_controls));
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 649497d1a3676020802ebba04a3d9bb31253adb5 Mon Sep 17 00:00:00 2001
|
||||
From: Avi Kivity <avi@redhat.com>
|
||||
Date: Tue, 28 Dec 2010 12:09:07 +0200
|
||||
Subject: [PATCH 26/66] KVM: MMU: Fix incorrect direct gfn for unpaged mode shadow
|
||||
|
||||
We use the physical address instead of the base gfn for the four
|
||||
PAE page directories we use in unpaged mode. When the guest accesses
|
||||
an address above 1GB that is backed by a large host page, a BUG_ON()
|
||||
in kvm_mmu_set_gfn() triggers.
|
||||
|
||||
Resolves: https://bugzilla.kernel.org/show_bug.cgi?id=21962
|
||||
Reported-and-tested-by: Nicolas Prochazka <prochazka.nicolas@gmail.com>
|
||||
KVM-Stable-Tag.
|
||||
Signed-off-by: Avi Kivity <avi@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/mmu.c | 3 ++-
|
||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
|
||||
index fb8b376..fbb04ae 100644
|
||||
--- a/arch/x86/kvm/mmu.c
|
||||
+++ b/arch/x86/kvm/mmu.c
|
||||
@@ -2394,7 +2394,8 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
|
||||
ASSERT(!VALID_PAGE(root));
|
||||
spin_lock(&vcpu->kvm->mmu_lock);
|
||||
kvm_mmu_free_some_pages(vcpu);
|
||||
- sp = kvm_mmu_get_page(vcpu, i << 30, i << 30,
|
||||
+ sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT),
|
||||
+ i << 30,
|
||||
PT32_ROOT_LEVEL, 1, ACC_ALL,
|
||||
NULL);
|
||||
root = __pa(sp->spt);
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 4ef9e11d6867f88951e30db910fa015300e31871 Mon Sep 17 00:00:00 2001
|
||||
From: Hillf Danton <dhillf@gmail.com>
|
||||
Date: Wed, 29 Dec 2010 21:55:28 +0800
|
||||
Subject: [PATCH 27/66] fix freeing user_struct in user cache
|
||||
|
||||
When racing on adding into user cache, the new allocated from mm slab
|
||||
is freed without putting user namespace.
|
||||
|
||||
Since the user namespace is already operated by getting, putting has
|
||||
to be issued.
|
||||
|
||||
Signed-off-by: Hillf Danton <dhillf@gmail.com>
|
||||
Acked-by: Serge Hallyn <serge@hallyn.com>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
kernel/user.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kernel/user.c b/kernel/user.c
|
||||
index 2c7d8d5..5c598ca 100644
|
||||
--- a/kernel/user.c
|
||||
+++ b/kernel/user.c
|
||||
@@ -158,6 +158,7 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
|
||||
spin_lock_irq(&uidhash_lock);
|
||||
up = uid_hash_find(uid, hashent);
|
||||
if (up) {
|
||||
+ put_user_ns(ns);
|
||||
key_put(new->uid_keyring);
|
||||
key_put(new->session_keyring);
|
||||
kmem_cache_free(uid_cachep, new);
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
From 42ce7fd6319bed8ecb26d656c476365da46b29e9 Mon Sep 17 00:00:00 2001
|
||||
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
|
||||
Date: Wed, 29 Dec 2010 11:52:53 +0100
|
||||
Subject: [PATCH 28/66] spi/omap2_mcspi.c: Force CS to be in inactive state after off-mode transition
|
||||
|
||||
When SPI wake up from OFF mode, CS is in the wrong state: force it to the
|
||||
inactive state.
|
||||
|
||||
During the system life, I monitored the CS behavior using a oscilloscope.
|
||||
I also activated debug in omap2_mcspi, so I saw when driver disable the clocks
|
||||
and restore context when device is not used.Each time the CS was in the correct
|
||||
state. It was only when system was put suspend to ram with off-mode activated
|
||||
that on resume the CS was in wrong state( ie activated).
|
||||
|
||||
Changelog:
|
||||
* Change from v1 to v2:
|
||||
- Rebase on linus/master (after 2.6.37-rc1)
|
||||
- Do some clean-up and fix indentation on both patches
|
||||
- Add more explanations for patch 2
|
||||
|
||||
* Change from v2 to v3:
|
||||
- Use directly resume function of spi_master instead of using function
|
||||
- from spi_device as Grant Likely pointed it out.
|
||||
- Force this transition explicitly for each CS used by a device.
|
||||
|
||||
* Change from v3 to v4:
|
||||
- Patch clean-up according to Kevin Hilman and checkpatch.
|
||||
- Now force CS to be in inactive state only if it was inactive when it was
|
||||
suspended.
|
||||
|
||||
* Change from v4 to v5:
|
||||
- Rebase on linus/master (after 2.6.37-rc3)
|
||||
- Collapse some lines as pointed by Grant Likely
|
||||
- Fix a spelling
|
||||
|
||||
* Change from v5 to v6:
|
||||
- Rebase on linus/master (after 2.6.37-rc7)
|
||||
- Use CONFIG_SUSPEND instead of CONFIG_PM
|
||||
- Didn't use legacy PM methods anymore. Instead, add a struct dev_pm_ops and
|
||||
add the resume method there.
|
||||
- Fix multi-line comment style
|
||||
|
||||
* Change from v6 to v7:
|
||||
- Rebase on linus/master (after 2.6.37-rc8)
|
||||
- Drop an extra line
|
||||
|
||||
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
|
||||
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
|
||||
Reviewed-by: Kevin Hilman <khilman@deeprootsystems.com>
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
drivers/spi/omap2_mcspi.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 39 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
|
||||
index 2a651e6..951a160 100644
|
||||
--- a/drivers/spi/omap2_mcspi.c
|
||||
+++ b/drivers/spi/omap2_mcspi.c
|
||||
@@ -1305,10 +1305,49 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
|
||||
/* work with hotplug and coldplug */
|
||||
MODULE_ALIAS("platform:omap2_mcspi");
|
||||
|
||||
+#ifdef CONFIG_SUSPEND
|
||||
+/*
|
||||
+ * When SPI wake up from off-mode, CS is in activate state. If it was in
|
||||
+ * unactive state when driver was suspend, then force it to unactive state at
|
||||
+ * wake up.
|
||||
+ */
|
||||
+static int omap2_mcspi_resume(struct device *dev)
|
||||
+{
|
||||
+ struct spi_master *master = dev_get_drvdata(dev);
|
||||
+ struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
|
||||
+ struct omap2_mcspi_cs *cs;
|
||||
+
|
||||
+ omap2_mcspi_enable_clocks(mcspi);
|
||||
+ list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs,
|
||||
+ node) {
|
||||
+ if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) {
|
||||
+
|
||||
+ /*
|
||||
+ * We need to toggle CS state for OMAP take this
|
||||
+ * change in account.
|
||||
+ */
|
||||
+ MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1);
|
||||
+ __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
|
||||
+ MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0);
|
||||
+ __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
|
||||
+ }
|
||||
+ }
|
||||
+ omap2_mcspi_disable_clocks(mcspi);
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define omap2_mcspi_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static const struct dev_pm_ops omap2_mcspi_pm_ops = {
|
||||
+ .resume = omap2_mcspi_resume,
|
||||
+};
|
||||
+
|
||||
static struct platform_driver omap2_mcspi_driver = {
|
||||
.driver = {
|
||||
.name = "omap2_mcspi",
|
||||
.owner = THIS_MODULE,
|
||||
+ .pm = &omap2_mcspi_pm_ops
|
||||
},
|
||||
.remove = __exit_p(omap2_mcspi_remove),
|
||||
};
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 7ad1227818f09242cfe9bf1845fd24211f5f99bd Mon Sep 17 00:00:00 2001
|
||||
From: Jan Beulich <JBeulich@novell.com>
|
||||
Date: Thu, 9 Dec 2010 08:11:38 +0000
|
||||
Subject: [PATCH 29/66] kconfig: fix undesirable side effect of adding "visible" menu attribute
|
||||
|
||||
This lead to non-selected, non-user-selectable options to be written
|
||||
out to .config. This is not only pointless, but also preventing the
|
||||
user to be prompted should any of those options eventually become
|
||||
visible (e.g. by de-selecting the *_AUTO options the "visible"
|
||||
attribute was added for.
|
||||
|
||||
Furthermore it is quite logical for the "visible" attribute of a menu
|
||||
to control the visibility of all contained prompts, which is what the
|
||||
patch does.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@novell.com>
|
||||
Signed-off-by: Michal Marek <mmarek@suse.cz>
|
||||
---
|
||||
scripts/kconfig/menu.c | 14 ++++++++++++++
|
||||
1 files changed, 14 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
|
||||
index b9d9aa1..5f77dcb 100644
|
||||
--- a/scripts/kconfig/menu.c
|
||||
+++ b/scripts/kconfig/menu.c
|
||||
@@ -140,6 +140,20 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
|
||||
}
|
||||
if (current_entry->prompt && current_entry != &rootmenu)
|
||||
prop_warn(prop, "prompt redefined");
|
||||
+
|
||||
+ /* Apply all upper menus' visibilities to actual prompts. */
|
||||
+ if(type == P_PROMPT) {
|
||||
+ struct menu *menu = current_entry;
|
||||
+
|
||||
+ while ((menu = menu->parent) != NULL) {
|
||||
+ if (!menu->visibility)
|
||||
+ continue;
|
||||
+ prop->visible.expr
|
||||
+ = expr_alloc_and(prop->visible.expr,
|
||||
+ menu->visibility);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
current_entry->prompt = prop;
|
||||
}
|
||||
prop->text = prompt;
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
From 0bc463426ab5eb39e76df637b29a4f191d01b8a0 Mon Sep 17 00:00:00 2001
|
||||
From: Jate Sujjavanich <jsujjavanich@syntech-fuelmaster.com>
|
||||
Date: Wed, 29 Sep 2010 09:44:32 -0400
|
||||
Subject: [PATCH 30/66] spi/m68knommu: Coldfire QSPI platform support
|
||||
|
||||
After grabbing a msg from the msgq, the mcfqspi_work function calls
|
||||
list_del_init on the mcfqspi->msgq which unintentionally deletes the rest
|
||||
of the list before it can be processed. If qspi call was made using
|
||||
spi_sync, this can result in a process hang.
|
||||
|
||||
Signed-off-by: Jate Sujjavanich <jsujjavanich@syntech-fuelmaster.com>
|
||||
Acked-by: Steven King <sfking@fdwdc.com>
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
drivers/spi/coldfire_qspi.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/spi/coldfire_qspi.c b/drivers/spi/coldfire_qspi.c
|
||||
index 052b3c7..8856bcc 100644
|
||||
--- a/drivers/spi/coldfire_qspi.c
|
||||
+++ b/drivers/spi/coldfire_qspi.c
|
||||
@@ -317,7 +317,7 @@ static void mcfqspi_work(struct work_struct *work)
|
||||
msg = container_of(mcfqspi->msgq.next, struct spi_message,
|
||||
queue);
|
||||
|
||||
- list_del_init(&mcfqspi->msgq);
|
||||
+ list_del_init(&msg->queue);
|
||||
spin_unlock_irqrestore(&mcfqspi->lock, flags);
|
||||
|
||||
spi = msg->spi;
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
From d81a12bc29ae4038770e05dce4ab7f26fd5880fb Mon Sep 17 00:00:00 2001
|
||||
From: Dan Rosenberg <drosenberg@vsecurity.com>
|
||||
Date: Sat, 25 Dec 2010 16:23:40 -0500
|
||||
Subject: [PATCH 31/66] sound: Prevent buffer overflow in OSS load_mixer_volumes
|
||||
|
||||
The load_mixer_volumes() function, which can be triggered by
|
||||
unprivileged users via the SOUND_MIXER_SETLEVELS ioctl, is vulnerable to
|
||||
a buffer overflow. Because the provided "name" argument isn't
|
||||
guaranteed to be NULL terminated at the expected 32 bytes, it's possible
|
||||
to overflow past the end of the last element in the mixer_vols array.
|
||||
Further exploitation can result in an arbitrary kernel write (via
|
||||
subsequent calls to load_mixer_volumes()) leading to privilege
|
||||
escalation, or arbitrary kernel reads via get_mixer_levels(). In
|
||||
addition, the strcmp() may leak bytes beyond the mixer_vols array.
|
||||
|
||||
Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
|
||||
Cc: stable <stable@kernel.org>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/oss/soundcard.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
|
||||
index 46c0d03..fcb14a0 100644
|
||||
--- a/sound/oss/soundcard.c
|
||||
+++ b/sound/oss/soundcard.c
|
||||
@@ -87,7 +87,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
|
||||
int i, n;
|
||||
|
||||
for (i = 0; i < num_mixer_volumes; i++) {
|
||||
- if (strcmp(name, mixer_vols[i].name) == 0) {
|
||||
+ if (strncmp(name, mixer_vols[i].name, 32) == 0) {
|
||||
if (present)
|
||||
mixer_vols[i].num = i;
|
||||
return mixer_vols[i].levels;
|
||||
@@ -99,7 +99,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
|
||||
}
|
||||
n = num_mixer_volumes++;
|
||||
|
||||
- strcpy(mixer_vols[n].name, name);
|
||||
+ strncpy(mixer_vols[n].name, name, 32);
|
||||
|
||||
if (present)
|
||||
mixer_vols[n].num = n;
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From e03fa055bc126e536c7f65862e08a9b143138ea9 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel T Chen <crimsun@ubuntu.com>
|
||||
Date: Tue, 28 Dec 2010 17:20:02 -0500
|
||||
Subject: [PATCH 32/66] ALSA: hda: Use LPIB quirk for Dell Inspiron m101z/1120
|
||||
|
||||
Sjoerd Simons reports that, without using position_fix=1, recording
|
||||
experiences overruns. Work around that by applying the LPIB quirk
|
||||
for his hardware.
|
||||
|
||||
Reported-and-tested-by: Sjoerd Simons <sjoerd@debian.org>
|
||||
Cc: <stable@kernel.org>
|
||||
Signed-off-by: Daniel T Chen <crimsun@ubuntu.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/hda_intel.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
|
||||
index b030c8e..a1c4008 100644
|
||||
--- a/sound/pci/hda/hda_intel.c
|
||||
+++ b/sound/pci/hda/hda_intel.c
|
||||
@@ -2300,6 +2300,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
|
||||
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
|
||||
SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
|
||||
SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
|
||||
+ SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
|
||||
SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
|
||||
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
|
||||
SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
From bcfbbce822d219eb587acaba8a6e062bbeae4761 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Date: Thu, 30 Dec 2010 09:07:15 +0000
|
||||
Subject: [PATCH 33/66] Revert "drm/i915/bios: Reverse order of 100/120 Mhz SSC clocks"
|
||||
|
||||
As I feared, whilst this fixed the clocks for the Lenovo U160, it broke
|
||||
many other machines. So lets reverts commit 448f53a1ede54eb854d036abf
|
||||
and search for the real bug.
|
||||
|
||||
Reported-and-tested-by: Travis Hume <travis@computoring.org> [et al]
|
||||
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=25842
|
||||
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32698
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
---
|
||||
drivers/gpu/drm/i915/intel_bios.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
|
||||
index 2b20786..b0b1200 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_bios.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_bios.c
|
||||
@@ -270,7 +270,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
|
||||
general->ssc_freq ? 66 : 48;
|
||||
else if (IS_GEN5(dev) || IS_GEN6(dev))
|
||||
dev_priv->lvds_ssc_freq =
|
||||
- general->ssc_freq ? 120 : 100;
|
||||
+ general->ssc_freq ? 100 : 120;
|
||||
else
|
||||
dev_priv->lvds_ssc_freq =
|
||||
general->ssc_freq ? 100 : 96;
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From cc6455f82edd3f9da3b03870d41cde3cb22ad40d Mon Sep 17 00:00:00 2001
|
||||
From: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Date: Thu, 30 Dec 2010 12:54:00 +0000
|
||||
Subject: [PATCH 34/66] drm/i915/dvo: Report LVDS attached to ch701x as connected
|
||||
|
||||
As we have already detected something attached to the chip during
|
||||
initialisation, always report the LVDS connector status as connected
|
||||
during probing.
|
||||
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
---
|
||||
drivers/gpu/drm/i915/dvo_ch7017.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c
|
||||
index af70337..d3e8c54 100644
|
||||
--- a/drivers/gpu/drm/i915/dvo_ch7017.c
|
||||
+++ b/drivers/gpu/drm/i915/dvo_ch7017.c
|
||||
@@ -242,7 +242,7 @@ fail:
|
||||
|
||||
static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo)
|
||||
{
|
||||
- return connector_status_unknown;
|
||||
+ return connector_status_connected;
|
||||
}
|
||||
|
||||
static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo,
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,402 @@
|
||||
From b83be6f20a0e468f715b14225c9f897538dfe5ad Mon Sep 17 00:00:00 2001
|
||||
From: Christoph Hellwig <hch>
|
||||
Date: Thu, 16 Dec 2010 12:04:54 +0100
|
||||
Subject: [PATCH 35/66] update Documentation/filesystems/Locking
|
||||
|
||||
Mostly inspired by all the recent BKL removal changes, but a lot of older
|
||||
updates also weren't properly recorded.
|
||||
|
||||
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
Documentation/filesystems/Locking | 214 ++++++++++++++++++-------------------
|
||||
1 files changed, 102 insertions(+), 112 deletions(-)
|
||||
|
||||
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
|
||||
index b6426f1..7686e76 100644
|
||||
--- a/Documentation/filesystems/Locking
|
||||
+++ b/Documentation/filesystems/Locking
|
||||
@@ -18,7 +18,6 @@ prototypes:
|
||||
char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
|
||||
|
||||
locking rules:
|
||||
- none have BKL
|
||||
dcache_lock rename_lock ->d_lock may block
|
||||
d_revalidate: no no no yes
|
||||
d_hash no no no yes
|
||||
@@ -42,18 +41,23 @@ ata *);
|
||||
int (*rename) (struct inode *, struct dentry *,
|
||||
struct inode *, struct dentry *);
|
||||
int (*readlink) (struct dentry *, char __user *,int);
|
||||
- int (*follow_link) (struct dentry *, struct nameidata *);
|
||||
+ void * (*follow_link) (struct dentry *, struct nameidata *);
|
||||
+ void (*put_link) (struct dentry *, struct nameidata *, void *);
|
||||
void (*truncate) (struct inode *);
|
||||
int (*permission) (struct inode *, int, struct nameidata *);
|
||||
+ int (*check_acl)(struct inode *, int);
|
||||
int (*setattr) (struct dentry *, struct iattr *);
|
||||
int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
|
||||
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
|
||||
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
|
||||
ssize_t (*listxattr) (struct dentry *, char *, size_t);
|
||||
int (*removexattr) (struct dentry *, const char *);
|
||||
+ void (*truncate_range)(struct inode *, loff_t, loff_t);
|
||||
+ long (*fallocate)(struct inode *inode, int mode, loff_t offset, loff_t len);
|
||||
+ int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
|
||||
|
||||
locking rules:
|
||||
- all may block, none have BKL
|
||||
+ all may block
|
||||
i_mutex(inode)
|
||||
lookup: yes
|
||||
create: yes
|
||||
@@ -66,19 +70,24 @@ rmdir: yes (both) (see below)
|
||||
rename: yes (all) (see below)
|
||||
readlink: no
|
||||
follow_link: no
|
||||
+put_link: no
|
||||
truncate: yes (see below)
|
||||
setattr: yes
|
||||
permission: no
|
||||
+check_acl: no
|
||||
getattr: no
|
||||
setxattr: yes
|
||||
getxattr: no
|
||||
listxattr: no
|
||||
removexattr: yes
|
||||
+truncate_range: yes
|
||||
+fallocate: no
|
||||
+fiemap: no
|
||||
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
|
||||
victim.
|
||||
cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
|
||||
->truncate() is never called directly - it's a callback, not a
|
||||
-method. It's called by vmtruncate() - library function normally used by
|
||||
+method. It's called by vmtruncate() - deprecated library function used by
|
||||
->setattr(). Locking information above applies to that call (i.e. is
|
||||
inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been
|
||||
passed).
|
||||
@@ -91,7 +100,7 @@ prototypes:
|
||||
struct inode *(*alloc_inode)(struct super_block *sb);
|
||||
void (*destroy_inode)(struct inode *);
|
||||
void (*dirty_inode) (struct inode *);
|
||||
- int (*write_inode) (struct inode *, int);
|
||||
+ int (*write_inode) (struct inode *, struct writeback_control *wbc);
|
||||
int (*drop_inode) (struct inode *);
|
||||
void (*evict_inode) (struct inode *);
|
||||
void (*put_super) (struct super_block *);
|
||||
@@ -105,10 +114,11 @@ prototypes:
|
||||
int (*show_options)(struct seq_file *, struct vfsmount *);
|
||||
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
|
||||
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
|
||||
+ int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
|
||||
+ int (*trim_fs) (struct super_block *, struct fstrim_range *);
|
||||
|
||||
locking rules:
|
||||
All may block [not true, see below]
|
||||
- None have BKL
|
||||
s_umount
|
||||
alloc_inode:
|
||||
destroy_inode:
|
||||
@@ -127,6 +137,8 @@ umount_begin: no
|
||||
show_options: no (namespace_sem)
|
||||
quota_read: no (see below)
|
||||
quota_write: no (see below)
|
||||
+bdev_try_to_free_page: no (see below)
|
||||
+trim_fs: no
|
||||
|
||||
->statfs() has s_umount (shared) when called by ustat(2) (native or
|
||||
compat), but that's an accident of bad API; s_umount is used to pin
|
||||
@@ -139,19 +151,25 @@ be the only ones operating on the quota file by the quota code (via
|
||||
dqio_sem) (unless an admin really wants to screw up something and
|
||||
writes to quota files with quotas on). For other details about locking
|
||||
see also dquot_operations section.
|
||||
+->bdev_try_to_free_page is called from the ->releasepage handler of
|
||||
+the block device inode. See there for more details.
|
||||
|
||||
--------------------------- file_system_type ---------------------------
|
||||
prototypes:
|
||||
int (*get_sb) (struct file_system_type *, int,
|
||||
const char *, void *, struct vfsmount *);
|
||||
+ struct dentry *(*mount) (struct file_system_type *, int,
|
||||
+ const char *, void *);
|
||||
void (*kill_sb) (struct super_block *);
|
||||
locking rules:
|
||||
- may block BKL
|
||||
-get_sb yes no
|
||||
-kill_sb yes no
|
||||
+ may block
|
||||
+get_sb yes
|
||||
+mount yes
|
||||
+kill_sb yes
|
||||
|
||||
->get_sb() returns error or 0 with locked superblock attached to the vfsmount
|
||||
(exclusive on ->s_umount).
|
||||
+->mount() returns ERR_PTR or the root dentry.
|
||||
->kill_sb() takes a write-locked superblock, does all shutdown work on it,
|
||||
unlocks and drops the reference.
|
||||
|
||||
@@ -176,27 +194,35 @@ prototypes:
|
||||
void (*freepage)(struct page *);
|
||||
int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
|
||||
loff_t offset, unsigned long nr_segs);
|
||||
- int (*launder_page) (struct page *);
|
||||
+ int (*get_xip_mem)(struct address_space *, pgoff_t, int, void **,
|
||||
+ unsigned long *);
|
||||
+ int (*migratepage)(struct address_space *, struct page *, struct page *);
|
||||
+ int (*launder_page)(struct page *);
|
||||
+ int (*is_partially_uptodate)(struct page *, read_descriptor_t *, unsigned long);
|
||||
+ int (*error_remove_page)(struct address_space *, struct page *);
|
||||
|
||||
locking rules:
|
||||
All except set_page_dirty and freepage may block
|
||||
|
||||
- BKL PageLocked(page) i_mutex
|
||||
-writepage: no yes, unlocks (see below)
|
||||
-readpage: no yes, unlocks
|
||||
-sync_page: no maybe
|
||||
-writepages: no
|
||||
-set_page_dirty no no
|
||||
-readpages: no
|
||||
-write_begin: no locks the page yes
|
||||
-write_end: no yes, unlocks yes
|
||||
-perform_write: no n/a yes
|
||||
-bmap: no
|
||||
-invalidatepage: no yes
|
||||
-releasepage: no yes
|
||||
-freepage: no yes
|
||||
-direct_IO: no
|
||||
-launder_page: no yes
|
||||
+ PageLocked(page) i_mutex
|
||||
+writepage: yes, unlocks (see below)
|
||||
+readpage: yes, unlocks
|
||||
+sync_page: maybe
|
||||
+writepages:
|
||||
+set_page_dirty no
|
||||
+readpages:
|
||||
+write_begin: locks the page yes
|
||||
+write_end: yes, unlocks yes
|
||||
+bmap:
|
||||
+invalidatepage: yes
|
||||
+releasepage: yes
|
||||
+freepage: yes
|
||||
+direct_IO:
|
||||
+get_xip_mem: maybe
|
||||
+migratepage: yes (both)
|
||||
+launder_page: yes
|
||||
+is_partially_uptodate: yes
|
||||
+error_remove_page: yes
|
||||
|
||||
->write_begin(), ->write_end(), ->sync_page() and ->readpage()
|
||||
may be called from the request handler (/dev/loop).
|
||||
@@ -276,9 +302,8 @@ under spinlock (it cannot block) and is sometimes called with the page
|
||||
not locked.
|
||||
|
||||
->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some
|
||||
-filesystems and by the swapper. The latter will eventually go away. All
|
||||
-instances do not actually need the BKL. Please, keep it that way and don't
|
||||
-breed new callers.
|
||||
+filesystems and by the swapper. The latter will eventually go away. Please,
|
||||
+keep it that way and don't breed new callers.
|
||||
|
||||
->invalidatepage() is called when the filesystem must attempt to drop
|
||||
some or all of the buffers from the page when it is being truncated. It
|
||||
@@ -299,47 +324,37 @@ cleaned, or an error value if not. Note that in order to prevent the page
|
||||
getting mapped back in and redirtied, it needs to be kept locked
|
||||
across the entire operation.
|
||||
|
||||
- Note: currently almost all instances of address_space methods are
|
||||
-using BKL for internal serialization and that's one of the worst sources
|
||||
-of contention. Normally they are calling library functions (in fs/buffer.c)
|
||||
-and pass foo_get_block() as a callback (on local block-based filesystems,
|
||||
-indeed). BKL is not needed for library stuff and is usually taken by
|
||||
-foo_get_block(). It's an overkill, since block bitmaps can be protected by
|
||||
-internal fs locking and real critical areas are much smaller than the areas
|
||||
-filesystems protect now.
|
||||
-
|
||||
----------------------- file_lock_operations ------------------------------
|
||||
prototypes:
|
||||
- void (*fl_insert)(struct file_lock *); /* lock insertion callback */
|
||||
- void (*fl_remove)(struct file_lock *); /* lock removal callback */
|
||||
void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
|
||||
void (*fl_release_private)(struct file_lock *);
|
||||
|
||||
|
||||
locking rules:
|
||||
- BKL may block
|
||||
-fl_insert: yes no
|
||||
-fl_remove: yes no
|
||||
-fl_copy_lock: yes no
|
||||
-fl_release_private: yes yes
|
||||
+ file_lock_lock may block
|
||||
+fl_copy_lock: yes no
|
||||
+fl_release_private: maybe no
|
||||
|
||||
----------------------- lock_manager_operations ---------------------------
|
||||
prototypes:
|
||||
int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
|
||||
void (*fl_notify)(struct file_lock *); /* unblock callback */
|
||||
+ int (*fl_grant)(struct file_lock *, struct file_lock *, int);
|
||||
void (*fl_release_private)(struct file_lock *);
|
||||
void (*fl_break)(struct file_lock *); /* break_lease callback */
|
||||
+ int (*fl_mylease)(struct file_lock *, struct file_lock *);
|
||||
+ int (*fl_change)(struct file_lock **, int);
|
||||
|
||||
locking rules:
|
||||
- BKL may block
|
||||
-fl_compare_owner: yes no
|
||||
-fl_notify: yes no
|
||||
-fl_release_private: yes yes
|
||||
-fl_break: yes no
|
||||
-
|
||||
- Currently only NFSD and NLM provide instances of this class. None of the
|
||||
-them block. If you have out-of-tree instances - please, show up. Locking
|
||||
-in that area will change.
|
||||
+ file_lock_lock may block
|
||||
+fl_compare_owner: yes no
|
||||
+fl_notify: yes no
|
||||
+fl_grant: no no
|
||||
+fl_release_private: maybe no
|
||||
+fl_break: yes no
|
||||
+fl_mylease: yes no
|
||||
+fl_change yes no
|
||||
+
|
||||
--------------------------- buffer_head -----------------------------------
|
||||
prototypes:
|
||||
void (*b_end_io)(struct buffer_head *bh, int uptodate);
|
||||
@@ -364,17 +379,17 @@ prototypes:
|
||||
void (*swap_slot_free_notify) (struct block_device *, unsigned long);
|
||||
|
||||
locking rules:
|
||||
- BKL bd_mutex
|
||||
-open: no yes
|
||||
-release: no yes
|
||||
-ioctl: no no
|
||||
-compat_ioctl: no no
|
||||
-direct_access: no no
|
||||
-media_changed: no no
|
||||
-unlock_native_capacity: no no
|
||||
-revalidate_disk: no no
|
||||
-getgeo: no no
|
||||
-swap_slot_free_notify: no no (see below)
|
||||
+ bd_mutex
|
||||
+open: yes
|
||||
+release: yes
|
||||
+ioctl: no
|
||||
+compat_ioctl: no
|
||||
+direct_access: no
|
||||
+media_changed: no
|
||||
+unlock_native_capacity: no
|
||||
+revalidate_disk: no
|
||||
+getgeo: no
|
||||
+swap_slot_free_notify: no (see below)
|
||||
|
||||
media_changed, unlock_native_capacity and revalidate_disk are called only from
|
||||
check_disk_change().
|
||||
@@ -413,34 +428,21 @@ prototypes:
|
||||
unsigned long (*get_unmapped_area)(struct file *, unsigned long,
|
||||
unsigned long, unsigned long, unsigned long);
|
||||
int (*check_flags)(int);
|
||||
+ int (*flock) (struct file *, int, struct file_lock *);
|
||||
+ ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *,
|
||||
+ size_t, unsigned int);
|
||||
+ ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *,
|
||||
+ size_t, unsigned int);
|
||||
+ int (*setlease)(struct file *, long, struct file_lock **);
|
||||
};
|
||||
|
||||
locking rules:
|
||||
- All may block.
|
||||
- BKL
|
||||
-llseek: no (see below)
|
||||
-read: no
|
||||
-aio_read: no
|
||||
-write: no
|
||||
-aio_write: no
|
||||
-readdir: no
|
||||
-poll: no
|
||||
-unlocked_ioctl: no
|
||||
-compat_ioctl: no
|
||||
-mmap: no
|
||||
-open: no
|
||||
-flush: no
|
||||
-release: no
|
||||
-fsync: no (see below)
|
||||
-aio_fsync: no
|
||||
-fasync: no
|
||||
-lock: yes
|
||||
-readv: no
|
||||
-writev: no
|
||||
-sendfile: no
|
||||
-sendpage: no
|
||||
-get_unmapped_area: no
|
||||
-check_flags: no
|
||||
+ All may block except for ->setlease.
|
||||
+ No VFS locks held on entry except for ->fsync and ->setlease.
|
||||
+
|
||||
+->fsync() has i_mutex on inode.
|
||||
+
|
||||
+->setlease has the file_list_lock held and must not sleep.
|
||||
|
||||
->llseek() locking has moved from llseek to the individual llseek
|
||||
implementations. If your fs is not using generic_file_llseek, you
|
||||
@@ -450,17 +452,10 @@ mutex or just to use i_size_read() instead.
|
||||
Note: this does not protect the file->f_pos against concurrent modifications
|
||||
since this is something the userspace has to take care about.
|
||||
|
||||
-Note: ext2_release() was *the* source of contention on fs-intensive
|
||||
-loads and dropping BKL on ->release() helps to get rid of that (we still
|
||||
-grab BKL for cases when we close a file that had been opened r/w, but that
|
||||
-can and should be done using the internal locking with smaller critical areas).
|
||||
-Current worst offender is ext2_get_block()...
|
||||
-
|
||||
-->fasync() is called without BKL protection, and is responsible for
|
||||
-maintaining the FASYNC bit in filp->f_flags. Most instances call
|
||||
-fasync_helper(), which does that maintenance, so it's not normally
|
||||
-something one needs to worry about. Return values > 0 will be mapped to
|
||||
-zero in the VFS layer.
|
||||
+->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags.
|
||||
+Most instances call fasync_helper(), which does that maintenance, so it's
|
||||
+not normally something one needs to worry about. Return values > 0 will be
|
||||
+mapped to zero in the VFS layer.
|
||||
|
||||
->readdir() and ->ioctl() on directories must be changed. Ideally we would
|
||||
move ->readdir() to inode_operations and use a separate method for directory
|
||||
@@ -471,8 +466,6 @@ components. And there are other reasons why the current interface is a mess...
|
||||
->read on directories probably must go away - we should just enforce -EISDIR
|
||||
in sys_read() and friends.
|
||||
|
||||
-->fsync() has i_mutex on inode.
|
||||
-
|
||||
--------------------------- dquot_operations -------------------------------
|
||||
prototypes:
|
||||
int (*write_dquot) (struct dquot *);
|
||||
@@ -507,12 +500,12 @@ prototypes:
|
||||
int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
|
||||
|
||||
locking rules:
|
||||
- BKL mmap_sem PageLocked(page)
|
||||
-open: no yes
|
||||
-close: no yes
|
||||
-fault: no yes can return with page locked
|
||||
-page_mkwrite: no yes can return with page locked
|
||||
-access: no yes
|
||||
+ mmap_sem PageLocked(page)
|
||||
+open: yes
|
||||
+close: yes
|
||||
+fault: yes can return with page locked
|
||||
+page_mkwrite: yes can return with page locked
|
||||
+access: yes
|
||||
|
||||
->fault() is called when a previously not present pte is about
|
||||
to be faulted in. The filesystem must find and return the page associated
|
||||
@@ -539,6 +532,3 @@ VM_IO | VM_PFNMAP VMAs.
|
||||
|
||||
(if you break something or notice that it is broken and do not fix it yourself
|
||||
- at least put it here)
|
||||
-
|
||||
-ipc/shm.c::shm_delete() - may need BKL.
|
||||
-->read() and ->write() in many drivers are (probably) missing BKL.
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From ebb76ce16daf6908dc030dec1c00827d37129fe5 Mon Sep 17 00:00:00 2001
|
||||
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
|
||||
Date: Wed, 29 Dec 2010 14:07:11 -0800
|
||||
Subject: [PATCH 36/66] memcg: fix wrong VM_BUG_ON() in try_charge()'s mm->owner check
|
||||
|
||||
At __mem_cgroup_try_charge(), VM_BUG_ON(!mm->owner) is checked.
|
||||
But as commented in mem_cgroup_from_task(), mm->owner can be NULL
|
||||
in some racy case. This check of VM_BUG_ON() is bad.
|
||||
|
||||
A possible story to hit this is at swapoff()->try_to_unuse(). It passes
|
||||
mm_struct to mem_cgroup_try_charge_swapin() while mm->owner is NULL. If we
|
||||
can't get proper mem_cgroup from swap_cgroup information, mm->owner is used
|
||||
as charge target and we see NULL.
|
||||
|
||||
Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
|
||||
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
|
||||
Reported-by: Hugh Dickins <hughd@google.com>
|
||||
Reported-by: Thomas Meyer <thomas@m3y3r.de>
|
||||
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
|
||||
Reviewed-by: Balbir Singh <balbir@linux.vnet.ibm.com>
|
||||
Signed-off-by: Hugh Dickins <hughd@google.com>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
mm/memcontrol.c | 19 +++++++++----------
|
||||
1 files changed, 9 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
|
||||
index 7a22b41..00bb8a6 100644
|
||||
--- a/mm/memcontrol.c
|
||||
+++ b/mm/memcontrol.c
|
||||
@@ -1925,19 +1925,18 @@ again:
|
||||
|
||||
rcu_read_lock();
|
||||
p = rcu_dereference(mm->owner);
|
||||
- VM_BUG_ON(!p);
|
||||
/*
|
||||
- * because we don't have task_lock(), "p" can exit while
|
||||
- * we're here. In that case, "mem" can point to root
|
||||
- * cgroup but never be NULL. (and task_struct itself is freed
|
||||
- * by RCU, cgroup itself is RCU safe.) Then, we have small
|
||||
- * risk here to get wrong cgroup. But such kind of mis-account
|
||||
- * by race always happens because we don't have cgroup_mutex().
|
||||
- * It's overkill and we allow that small race, here.
|
||||
+ * Because we don't have task_lock(), "p" can exit.
|
||||
+ * In that case, "mem" can point to root or p can be NULL with
|
||||
+ * race with swapoff. Then, we have small risk of mis-accouning.
|
||||
+ * But such kind of mis-account by race always happens because
|
||||
+ * we don't have cgroup_mutex(). It's overkill and we allo that
|
||||
+ * small race, here.
|
||||
+ * (*) swapoff at el will charge against mm-struct not against
|
||||
+ * task-struct. So, mm->owner can be NULL.
|
||||
*/
|
||||
mem = mem_cgroup_from_task(p);
|
||||
- VM_BUG_ON(!mem);
|
||||
- if (mem_cgroup_is_root(mem)) {
|
||||
+ if (!mem || mem_cgroup_is_root(mem)) {
|
||||
rcu_read_unlock();
|
||||
goto done;
|
||||
}
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From e983dc2428164698571e1dd1b25c4322181adbac Mon Sep 17 00:00:00 2001
|
||||
From: Nitin Gupta <ngupta@vflare.org>
|
||||
Date: Thu, 30 Dec 2010 04:07:58 -0500
|
||||
Subject: [PATCH 37/66] Revert "Staging: zram: work around oops due to startup ordering snafu"
|
||||
|
||||
This reverts commit 7e24cce38a99f373450db67bf576fe73e8168d66 because it
|
||||
was never appropriate for mainline.
|
||||
|
||||
Do not check for init flag before starting I/O - zram module is unusable
|
||||
without this fix.
|
||||
|
||||
The oops mentioned in the reverted commit message was actually a problem
|
||||
only with the zram version as present in project's own repository where
|
||||
we allocate struct zram_stats_cpu upon device initialization. OTOH, In
|
||||
mainline/staging version of zram, we allocate struct stats upfront, so
|
||||
this oops cannot happen in mainline version.
|
||||
|
||||
Checking for init_done flag in zram_make_request() results in a *no-op*
|
||||
for any I/O operation since we simply always return success. This flag
|
||||
is actually set when the first write occurs on a zram disk which
|
||||
triggers its initialization.
|
||||
|
||||
Bug report: https://bugzilla.kernel.org/show_bug.cgi?id=25722
|
||||
|
||||
Reported-by: Dennis Jansen <dennis.jansen@web.de>
|
||||
Signed-off-by: Nitin Gupta <ngupta@vflare.org>
|
||||
Cc: Anton Blanchard <anton@samba.org>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
drivers/staging/zram/zram_drv.c | 6 ------
|
||||
1 files changed, 0 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
|
||||
index 8c3c057..d0e9e02 100644
|
||||
--- a/drivers/staging/zram/zram_drv.c
|
||||
+++ b/drivers/staging/zram/zram_drv.c
|
||||
@@ -435,12 +435,6 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio)
|
||||
int ret = 0;
|
||||
struct zram *zram = queue->queuedata;
|
||||
|
||||
- if (unlikely(!zram->init_done)) {
|
||||
- set_bit(BIO_UPTODATE, &bio->bi_flags);
|
||||
- bio_endio(bio, 0);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
if (!valid_io_request(zram, bio)) {
|
||||
zram_stat64_inc(zram, &zram->stats.invalid_io);
|
||||
bio_io_error(bio);
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
From 9f260e0efa4766e56d0ac14f1aeea6ee5eb8fe83 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Rosenberg <drosenberg@vsecurity.com>
|
||||
Date: Sun, 26 Dec 2010 06:54:53 +0000
|
||||
Subject: [PATCH 38/66] CAN: Use inode instead of kernel address for /proc file
|
||||
|
||||
Since the socket address is just being used as a unique identifier, its
|
||||
inode number is an alternative that does not leak potentially sensitive
|
||||
information.
|
||||
|
||||
CC-ing stable because MITRE has assigned CVE-2010-4565 to the issue.
|
||||
|
||||
Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
|
||||
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/can/bcm.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/net/can/bcm.c b/net/can/bcm.c
|
||||
index 6faa825..9d5e8ac 100644
|
||||
--- a/net/can/bcm.c
|
||||
+++ b/net/can/bcm.c
|
||||
@@ -125,7 +125,7 @@ struct bcm_sock {
|
||||
struct list_head tx_ops;
|
||||
unsigned long dropped_usr_msgs;
|
||||
struct proc_dir_entry *bcm_proc_read;
|
||||
- char procname [20]; /* pointer printed in ASCII with \0 */
|
||||
+ char procname [32]; /* inode number in decimal with \0 */
|
||||
};
|
||||
|
||||
static inline struct bcm_sock *bcm_sk(const struct sock *sk)
|
||||
@@ -1521,7 +1521,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
|
||||
|
||||
if (proc_dir) {
|
||||
/* unique socket address as filename */
|
||||
- sprintf(bo->procname, "%p", sock);
|
||||
+ sprintf(bo->procname, "%lu", sock_i_ino(sk));
|
||||
bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
|
||||
proc_dir,
|
||||
&bcm_proc_fops, sk);
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
From 2393c944d5d60eedaede80273ede8a816b5fa3e0 Mon Sep 17 00:00:00 2001
|
||||
From: Jesper Juhl <jj@chaosbits.net>
|
||||
Date: Sun, 26 Dec 2010 09:59:58 +0000
|
||||
Subject: [PATCH 39/66] ISDN, Gigaset: Fix memory leak in do_disconnect_req()
|
||||
|
||||
Hi,
|
||||
|
||||
In drivers/isdn/gigaset/capi.c::do_disconnect_req() we will leak the
|
||||
memory allocated (with kmalloc) to 'b3cmsg' if the call to alloc_skb()
|
||||
fails.
|
||||
|
||||
...
|
||||
b3cmsg = kmalloc(sizeof(*b3cmsg), GFP_KERNEL);
|
||||
allocation here ------^
|
||||
if (!b3cmsg) {
|
||||
dev_err(cs->dev, "%s: out of memory\n", __func__);
|
||||
send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
|
||||
return;
|
||||
}
|
||||
capi_cmsg_header(b3cmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
|
||||
ap->nextMessageNumber++,
|
||||
cmsg->adr.adrPLCI | (1 << 16));
|
||||
b3cmsg->Reason_B3 = CapiProtocolErrorLayer1;
|
||||
b3skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_KERNEL);
|
||||
if (b3skb == NULL) {
|
||||
dev_err(cs->dev, "%s: out of memory\n", __func__);
|
||||
send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
|
||||
return;
|
||||
leak here ------^
|
||||
...
|
||||
|
||||
This leak is easily fixed by just kfree()'ing the memory allocated to
|
||||
'b3cmsg' right before we return. The following patch does that.
|
||||
|
||||
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
|
||||
Acked-by: Tilman Schmidt <tilman@imap.cc>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/isdn/gigaset/capi.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
|
||||
index bcc174e..658e75f 100644
|
||||
--- a/drivers/isdn/gigaset/capi.c
|
||||
+++ b/drivers/isdn/gigaset/capi.c
|
||||
@@ -1900,6 +1900,7 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
|
||||
if (b3skb == NULL) {
|
||||
dev_err(cs->dev, "%s: out of memory\n", __func__);
|
||||
send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
|
||||
+ kfree(b3cmsg);
|
||||
return;
|
||||
}
|
||||
capi_cmsg2message(b3cmsg,
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
From f7e4c9775ea648deed4a8193951e50d0c7706173 Mon Sep 17 00:00:00 2001
|
||||
From: Jesper Juhl <jj@chaosbits.net>
|
||||
Date: Fri, 31 Dec 2010 11:18:48 -0800
|
||||
Subject: [PATCH 40/66] Broadcom CNIC core network driver: fix mem leak on allocation failures in cnic_alloc_uio_rings()
|
||||
|
||||
We are leaking memory in drivers/net/cnic.c::cnic_alloc_uio_rings() if
|
||||
either of the calls to dma_alloc_coherent() fail. This patch fixes it by
|
||||
freeing both the memory allocated with kzalloc() and memory allocated with
|
||||
previous calls to dma_alloc_coherent() when there's a failure.
|
||||
|
||||
Thanks to Joe Perches <joe@perches.com> for suggesting a better
|
||||
implementation than my initial version.
|
||||
|
||||
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
|
||||
Acked-by: Michael Chan <mchan@broadcom.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/cnic.c | 10 ++++++++--
|
||||
1 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
|
||||
index 92bac19..6dff321 100644
|
||||
--- a/drivers/net/cnic.c
|
||||
+++ b/drivers/net/cnic.c
|
||||
@@ -940,7 +940,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
|
||||
&udev->l2_ring_map,
|
||||
GFP_KERNEL | __GFP_COMP);
|
||||
if (!udev->l2_ring)
|
||||
- return -ENOMEM;
|
||||
+ goto err_udev;
|
||||
|
||||
udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
|
||||
udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size);
|
||||
@@ -948,7 +948,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
|
||||
&udev->l2_buf_map,
|
||||
GFP_KERNEL | __GFP_COMP);
|
||||
if (!udev->l2_buf)
|
||||
- return -ENOMEM;
|
||||
+ goto err_dma;
|
||||
|
||||
write_lock(&cnic_dev_lock);
|
||||
list_add(&udev->list, &cnic_udev_list);
|
||||
@@ -959,6 +959,12 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
|
||||
cp->udev = udev;
|
||||
|
||||
return 0;
|
||||
+ err_dma:
|
||||
+ dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size,
|
||||
+ udev->l2_ring, udev->l2_ring_map);
|
||||
+ err_udev:
|
||||
+ kfree(udev);
|
||||
+ return -ENOMEM;
|
||||
}
|
||||
|
||||
static int cnic_init_uio(struct cnic_dev *dev)
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 824f5f38d3005c346a043dedcfe8b048b699b81a Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Wed, 29 Dec 2010 03:40:31 +0000
|
||||
Subject: [PATCH 41/66] tg3: fix return value check in tg3_read_vpd()
|
||||
|
||||
Besides -ETIMEDOUT and -EINTR, pci_read_vpd may return other error
|
||||
values like -ENODEV or -EINVAL which are ignored due to the buggy
|
||||
check, but the data are not read from VPD anyway and this is checked
|
||||
subsequently with at most 3 needless loop iterations. This does not
|
||||
show up as a runtime bug.
|
||||
|
||||
CC: Matt Carlson <mcarlson@broadcom.com>
|
||||
CC: Michael Chan <mchan@broadcom.com>
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/tg3.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
|
||||
index 30ccbb6..6f97b7b 100644
|
||||
--- a/drivers/net/tg3.c
|
||||
+++ b/drivers/net/tg3.c
|
||||
@@ -12658,7 +12658,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp)
|
||||
cnt = pci_read_vpd(tp->pdev, pos,
|
||||
TG3_NVM_VPD_LEN - pos,
|
||||
&vpd_data[pos]);
|
||||
- if (cnt == -ETIMEDOUT || -EINTR)
|
||||
+ if (cnt == -ETIMEDOUT || cnt == -EINTR)
|
||||
cnt = 0;
|
||||
else if (cnt < 0)
|
||||
goto out_not_found;
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From f4d5900a99dbc354ef1ba384d445ff80ae4d77b4 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Wed, 29 Dec 2010 04:26:17 +0000
|
||||
Subject: [PATCH 42/66] starfire: Fix dma_addr_t size test for MIPS
|
||||
|
||||
Commit 56543af "starfire: use BUILD_BUG_ON for netdrv_addr_t" revealed
|
||||
that the preprocessor condition used to find the size of dma_addr_t
|
||||
yielded the wrong result for some architectures and configurations.
|
||||
This was kluged for 64-bit PowerPC in commit 3e502e6 by adding yet
|
||||
another case to the condition. However, 64-bit MIPS configurations
|
||||
are not detected reliably either.
|
||||
|
||||
This should be fixed by using CONFIG_ARCH_DMA_ADDR_T_64BIT, but that
|
||||
isn't yet defined everywhere it should be.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/starfire.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
|
||||
index 4adf124..a4f2bd5 100644
|
||||
--- a/drivers/net/starfire.c
|
||||
+++ b/drivers/net/starfire.c
|
||||
@@ -148,7 +148,7 @@ static int full_duplex[MAX_UNITS] = {0, };
|
||||
* This SUCKS.
|
||||
* We need a much better method to determine if dma_addr_t is 64-bit.
|
||||
*/
|
||||
-#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT))
|
||||
+#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || (defined(CONFIG_MIPS) && ((defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || defined(CONFIG_64BIT))) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT))
|
||||
/* 64-bit dma_addr_t */
|
||||
#define ADDR_64BITS /* This chip uses 64 bit addresses. */
|
||||
#define netdrv_addr_t __le64
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From b9556f9a1abdc56a179ac7ba6053469373b6de0f Mon Sep 17 00:00:00 2001
|
||||
From: Julia Lawall <julia@diku.dk>
|
||||
Date: Wed, 29 Dec 2010 04:01:03 +0000
|
||||
Subject: [PATCH 43/66] drivers/atm/atmtcp.c: add missing atm_dev_put
|
||||
|
||||
The earlier call to atm_dev_lookup increases the reference count of dev,
|
||||
so decrease it on the way out.
|
||||
|
||||
The semantic match that finds this problem is as follows:
|
||||
(http://coccinelle.lip6.fr/)
|
||||
|
||||
// <smpl>
|
||||
@@
|
||||
expression x, E;
|
||||
constant C;
|
||||
@@
|
||||
|
||||
x = atm_dev_lookup(...);
|
||||
... when != false x != NULL
|
||||
when != true x == NULL
|
||||
when != \(E = x\|x = E\)
|
||||
when != atm_dev_put(dev);
|
||||
*return -C;
|
||||
// </smpl>
|
||||
|
||||
Signed-off-by: Julia Lawall <julia@diku.dk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/atm/atmtcp.c | 5 ++++-
|
||||
1 files changed, 4 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
|
||||
index 2b464b6..0b06250 100644
|
||||
--- a/drivers/atm/atmtcp.c
|
||||
+++ b/drivers/atm/atmtcp.c
|
||||
@@ -392,7 +392,10 @@ static int atmtcp_attach(struct atm_vcc *vcc,int itf)
|
||||
atm_dev_put(dev);
|
||||
return -EMEDIUMTYPE;
|
||||
}
|
||||
- if (PRIV(dev)->vcc) return -EBUSY;
|
||||
+ if (PRIV(dev)->vcc) {
|
||||
+ atm_dev_put(dev);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
}
|
||||
else {
|
||||
int error;
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From d0dfc6b74a0c6e9ee46b62713256e2b025244d3c Mon Sep 17 00:00:00 2001
|
||||
From: Avi Kivity <avi@redhat.com>
|
||||
Date: Fri, 31 Dec 2010 10:52:15 +0200
|
||||
Subject: [PATCH 44/66] KVM: i8259: initialize isr_ack
|
||||
|
||||
isr_ack is never initialized. So, until the first PIC reset, interrupts
|
||||
may fail to be injected. This can cause Windows XP to fail to boot, as
|
||||
reported in the fallout from the fix to
|
||||
https://bugzilla.kernel.org/show_bug.cgi?id=21962.
|
||||
|
||||
Reported-and-tested-by: Nicolas Prochazka <prochazka.nicolas@gmail.com>
|
||||
Signed-off-by: Avi Kivity <avi@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/i8259.c | 2 ++
|
||||
1 files changed, 2 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
|
||||
index f628234..3cece05 100644
|
||||
--- a/arch/x86/kvm/i8259.c
|
||||
+++ b/arch/x86/kvm/i8259.c
|
||||
@@ -575,6 +575,8 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
|
||||
s->pics[1].elcr_mask = 0xde;
|
||||
s->pics[0].pics_state = s;
|
||||
s->pics[1].pics_state = s;
|
||||
+ s->pics[0].isr_ack = 0xff;
|
||||
+ s->pics[1].isr_ack = 0xff;
|
||||
|
||||
/*
|
||||
* Initialize PIO device
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From b518a64983cbf2ff31aed530898de2d80e4573d5 Mon Sep 17 00:00:00 2001
|
||||
From: Maurus Cuelenaere <mcuelenaere@gmail.com>
|
||||
Date: Sun, 2 Jan 2011 14:48:16 -0500
|
||||
Subject: [PATCH 45/66] hwmon: (s3c-hwmon) Fix compilation
|
||||
|
||||
The owner field was removed from struct attribute in
|
||||
6fd69dc578fa0b1bbc3aad70ae3af9a137211707, so don't assign it anymore.
|
||||
|
||||
Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com>
|
||||
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
|
||||
---
|
||||
drivers/hwmon/s3c-hwmon.c | 2 --
|
||||
1 files changed, 0 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
|
||||
index 05248f2..92b42db 100644
|
||||
--- a/drivers/hwmon/s3c-hwmon.c
|
||||
+++ b/drivers/hwmon/s3c-hwmon.c
|
||||
@@ -234,7 +234,6 @@ static int s3c_hwmon_create_attr(struct device *dev,
|
||||
attr->index = channel;
|
||||
attr->dev_attr.attr.name = attrs->in_name;
|
||||
attr->dev_attr.attr.mode = S_IRUGO;
|
||||
- attr->dev_attr.attr.owner = THIS_MODULE;
|
||||
attr->dev_attr.show = s3c_hwmon_ch_show;
|
||||
|
||||
ret = device_create_file(dev, &attr->dev_attr);
|
||||
@@ -252,7 +251,6 @@ static int s3c_hwmon_create_attr(struct device *dev,
|
||||
attr->index = channel;
|
||||
attr->dev_attr.attr.name = attrs->label_name;
|
||||
attr->dev_attr.attr.mode = S_IRUGO;
|
||||
- attr->dev_attr.attr.owner = THIS_MODULE;
|
||||
attr->dev_attr.show = s3c_hwmon_label_show;
|
||||
|
||||
ret = device_create_file(dev, &attr->dev_attr);
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
From 551423748a4eba55f2eb0fc250d757986471f187 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sun, 2 Jan 2011 23:02:42 +0000
|
||||
Subject: [PATCH 46/66] watchdog: Improve initialisation error message and documentation
|
||||
|
||||
The error message 'NMI watchdog failed to create perf event...'
|
||||
does not make it clear that this is a fatal error for the
|
||||
watchdog. It also currently prints the error value as a
|
||||
pointer, rather than extracting the error code with PTR_ERR().
|
||||
Fix that.
|
||||
|
||||
Add a note to the description of the 'nowatchdog' kernel
|
||||
parameter to associate it with this message.
|
||||
|
||||
Reported-by: Cesare Leonardi <celeonar@gmail.com>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Cc: 599368@bugs.debian.org
|
||||
Cc: 608138@bugs.debian.org
|
||||
Cc: Don Zickus <dzickus@redhat.com>
|
||||
Cc: Frederic Weisbecker <fweisbec@gmail.com>
|
||||
Cc: <stable@kernel.org> # .37.x and later
|
||||
LKML-Reference: <1294009362.3167.126.camel@localhost>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
---
|
||||
Documentation/kernel-parameters.txt | 2 +-
|
||||
kernel/watchdog.c | 3 ++-
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
|
||||
index 8b61c93..01ece1b 100644
|
||||
--- a/Documentation/kernel-parameters.txt
|
||||
+++ b/Documentation/kernel-parameters.txt
|
||||
@@ -1759,7 +1759,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
|
||||
nousb [USB] Disable the USB subsystem
|
||||
|
||||
- nowatchdog [KNL] Disable the lockup detector.
|
||||
+ nowatchdog [KNL] Disable the lockup detector (NMI watchdog).
|
||||
|
||||
nowb [ARM]
|
||||
|
||||
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
|
||||
index 6e3c41a..5b08215 100644
|
||||
--- a/kernel/watchdog.c
|
||||
+++ b/kernel/watchdog.c
|
||||
@@ -364,7 +364,8 @@ static int watchdog_nmi_enable(int cpu)
|
||||
goto out_save;
|
||||
}
|
||||
|
||||
- printk(KERN_ERR "NMI watchdog failed to create perf event on cpu%i: %p\n", cpu, event);
|
||||
+ printk(KERN_ERR "NMI watchdog disabled for cpu%i: unable to create perf event: %ld\n",
|
||||
+ cpu, PTR_ERR(event));
|
||||
return PTR_ERR(event);
|
||||
|
||||
/* success path */
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
From 7c0ab43e6ab09d72dc8dbac2521b2f819ccc4026 Mon Sep 17 00:00:00 2001
|
||||
From: Axel Lin <axel.lin@gmail.com>
|
||||
Date: Mon, 3 Jan 2011 02:26:53 +0100
|
||||
Subject: [PATCH 47/66] ARM: 6605/1: Add missing include "asm/memory.h"
|
||||
|
||||
This patch fixes below build error by adding the missing asm/memory.h,
|
||||
which is needed for arch_is_coherent().
|
||||
|
||||
$ make pxa3xx_defconfig; make
|
||||
CC init/do_mounts_rd.o
|
||||
In file included from include/linux/list_bl.h:5,
|
||||
from include/linux/rculist_bl.h:7,
|
||||
from include/linux/dcache.h:7,
|
||||
from include/linux/fs.h:381,
|
||||
from init/do_mounts_rd.c:3:
|
||||
include/linux/bit_spinlock.h: In function 'bit_spin_unlock':
|
||||
include/linux/bit_spinlock.h:61: error: implicit declaration of function 'arch_is_coherent'
|
||||
make[1]: *** [init/do_mounts_rd.o] Error 1
|
||||
make: *** [init] Error 2
|
||||
|
||||
Signed-off-by: Axel Lin <axel.lin@gmail.com>
|
||||
Acked-by: Peter Huewe <peterhuewe@gmx.de>
|
||||
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
---
|
||||
arch/arm/include/asm/system.h | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
|
||||
index 1120f18..8002594 100644
|
||||
--- a/arch/arm/include/asm/system.h
|
||||
+++ b/arch/arm/include/asm/system.h
|
||||
@@ -150,6 +150,7 @@ extern unsigned int user_debug;
|
||||
#define rmb() dmb()
|
||||
#define wmb() mb()
|
||||
#else
|
||||
+#include <asm/memory.h>
|
||||
#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
|
||||
#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
|
||||
#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From 8333f65ef094e47020cd01452b4637e7daf5a77f Mon Sep 17 00:00:00 2001
|
||||
From: Saeed Bishara <saeed@marvell.com>
|
||||
Date: Tue, 21 Dec 2010 16:53:39 +0200
|
||||
Subject: [PATCH 48/66] mv_xor: fix race in tasklet function
|
||||
|
||||
use mv_xor_slot_cleanup() instead of __mv_xor_slot_cleanup() as the former function
|
||||
aquires the spin lock that needed to protect the drivers data.
|
||||
|
||||
Cc: <stable@kernel.org>
|
||||
Signed-off-by: Saeed Bishara <saeed@marvell.com>
|
||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
|
||||
---
|
||||
drivers/dma/mv_xor.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
|
||||
index 411d5bf..a25f5f6 100644
|
||||
--- a/drivers/dma/mv_xor.c
|
||||
+++ b/drivers/dma/mv_xor.c
|
||||
@@ -449,7 +449,7 @@ mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
|
||||
static void mv_xor_tasklet(unsigned long data)
|
||||
{
|
||||
struct mv_xor_chan *chan = (struct mv_xor_chan *) data;
|
||||
- __mv_xor_slot_cleanup(chan);
|
||||
+ mv_xor_slot_cleanup(chan);
|
||||
}
|
||||
|
||||
static struct mv_xor_desc_slot *
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From 8f33d5277fada0291ea495f7fd44a3e7b7aa41d3 Mon Sep 17 00:00:00 2001
|
||||
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
||||
Date: Wed, 22 Dec 2010 14:46:46 +0100
|
||||
Subject: [PATCH 49/66] dmaengine: provide dummy functions for DMA_ENGINE=n
|
||||
|
||||
This lets drivers, optionally using the dmaengine, build with DMA_ENGINE
|
||||
unselected.
|
||||
|
||||
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
|
||||
---
|
||||
include/linux/dmaengine.h | 13 ++++++++++---
|
||||
1 files changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
|
||||
index 9d8688b..8cd00ad 100644
|
||||
--- a/include/linux/dmaengine.h
|
||||
+++ b/include/linux/dmaengine.h
|
||||
@@ -824,6 +824,8 @@ enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie);
|
||||
#ifdef CONFIG_DMA_ENGINE
|
||||
enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
|
||||
void dma_issue_pending_all(void);
|
||||
+struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param);
|
||||
+void dma_release_channel(struct dma_chan *chan);
|
||||
#else
|
||||
static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
|
||||
{
|
||||
@@ -831,7 +833,14 @@ static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descript
|
||||
}
|
||||
static inline void dma_issue_pending_all(void)
|
||||
{
|
||||
- do { } while (0);
|
||||
+}
|
||||
+static inline struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask,
|
||||
+ dma_filter_fn fn, void *fn_param)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+static inline void dma_release_channel(struct dma_chan *chan)
|
||||
+{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -842,8 +851,6 @@ void dma_async_device_unregister(struct dma_device *device);
|
||||
void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
|
||||
struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
|
||||
#define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
|
||||
-struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param);
|
||||
-void dma_release_channel(struct dma_chan *chan);
|
||||
|
||||
/* --- Helper iov-locking functions --- */
|
||||
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
From f23b7952d37c69c0caa6c8dfb85dbf2eb9e5fcaa Mon Sep 17 00:00:00 2001
|
||||
From: Andy Walls <awalls@md.metrocast.net>
|
||||
Date: Sun, 5 Dec 2010 19:42:30 -0300
|
||||
Subject: [PATCH 50/66] [media] cx25840: Prevent device probe failure due to volume control ERANGE error
|
||||
|
||||
This patch fixes a regression that crept into 2.6.36.
|
||||
|
||||
The volume control scale in the cx25840 driver has an unusual mapping
|
||||
from register values to v4l2 volume control values. Enforce the mapping
|
||||
limits, so that the default volume control setting does not fall out of
|
||||
bounds to prevent the cx25840 module device probe from failing.
|
||||
|
||||
Signed-off-by: Andy Walls <awalls@md.metrocast.net>
|
||||
Cc: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
---
|
||||
drivers/media/video/cx25840/cx25840-core.c | 19 +++++++++++++++++--
|
||||
1 files changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
|
||||
index dfb198d..f164618 100644
|
||||
--- a/drivers/media/video/cx25840/cx25840-core.c
|
||||
+++ b/drivers/media/video/cx25840/cx25840-core.c
|
||||
@@ -1989,8 +1989,23 @@ static int cx25840_probe(struct i2c_client *client,
|
||||
v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
|
||||
V4L2_CID_HUE, -128, 127, 1, 0);
|
||||
if (!is_cx2583x(state)) {
|
||||
- default_volume = 228 - cx25840_read(client, 0x8d4);
|
||||
- default_volume = ((default_volume / 2) + 23) << 9;
|
||||
+ default_volume = cx25840_read(client, 0x8d4);
|
||||
+ /*
|
||||
+ * Enforce the legacy PVR-350/MSP3400 to PVR-150/CX25843 volume
|
||||
+ * scale mapping limits to avoid -ERANGE errors when
|
||||
+ * initializing the volume control
|
||||
+ */
|
||||
+ if (default_volume > 228) {
|
||||
+ /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
|
||||
+ default_volume = 228;
|
||||
+ cx25840_write(client, 0x8d4, 228);
|
||||
+ }
|
||||
+ else if (default_volume < 20) {
|
||||
+ /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */
|
||||
+ default_volume = 20;
|
||||
+ cx25840_write(client, 0x8d4, 20);
|
||||
+ }
|
||||
+ default_volume = (((228 - default_volume) >> 1) + 23) << 9;
|
||||
|
||||
state->volume = v4l2_ctrl_new_std(&state->hdl,
|
||||
&cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
@@ -0,0 +1,518 @@
|
||||
From 46e67acd5d4cacda758e871eebd15cef4e2c2665 Mon Sep 17 00:00:00 2001
|
||||
From: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
Date: Mon, 3 Jan 2011 09:09:56 -0200
|
||||
Subject: [PATCH 51/66] [media] wm8775: Revert changeset fcb9757333 to avoid a regression
|
||||
|
||||
It seems that cx88 and ivtv use wm8775 on some different modes. The
|
||||
patch that added support for a board with wm8775 broke ivtv boards with
|
||||
this device. As we're too close to release 2.6.37, let's just revert
|
||||
it.
|
||||
|
||||
Reported-by: Andy Walls <awalls@md.metrocast.net>
|
||||
Reported-by: Eric Sharkey <eric@lisaneric.org>
|
||||
Reported-by: Auric <auric@aanet.com.au>
|
||||
Reported by: David Gesswein <djg@pdp8online.com>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
---
|
||||
drivers/media/video/cx88/cx88-alsa.c | 99 ++++---------------------------
|
||||
drivers/media/video/cx88/cx88-cards.c | 7 ++
|
||||
drivers/media/video/cx88/cx88-video.c | 27 +--------
|
||||
drivers/media/video/cx88/cx88.h | 6 +-
|
||||
drivers/media/video/wm8775.c | 104 ++++++++++++--------------------
|
||||
include/media/wm8775.h | 3 -
|
||||
6 files changed, 61 insertions(+), 185 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
|
||||
index 4aaa47c..54b7fcd 100644
|
||||
--- a/drivers/media/video/cx88/cx88-alsa.c
|
||||
+++ b/drivers/media/video/cx88/cx88-alsa.c
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <sound/control.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/tlv.h>
|
||||
-#include <media/wm8775.h>
|
||||
|
||||
#include "cx88.h"
|
||||
#include "cx88-reg.h"
|
||||
@@ -587,47 +586,26 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
|
||||
int left, right, v, b;
|
||||
int changed = 0;
|
||||
u32 old;
|
||||
- struct v4l2_control client_ctl;
|
||||
-
|
||||
- /* Pass volume & balance onto any WM8775 */
|
||||
- if (value->value.integer.value[0] >= value->value.integer.value[1]) {
|
||||
- v = value->value.integer.value[0] << 10;
|
||||
- b = value->value.integer.value[0] ?
|
||||
- (0x8000 * value->value.integer.value[1]) / value->value.integer.value[0] :
|
||||
- 0x8000;
|
||||
- } else {
|
||||
- v = value->value.integer.value[1] << 10;
|
||||
- b = value->value.integer.value[1] ?
|
||||
- 0xffff - (0x8000 * value->value.integer.value[0]) / value->value.integer.value[1] :
|
||||
- 0x8000;
|
||||
- }
|
||||
- client_ctl.value = v;
|
||||
- client_ctl.id = V4L2_CID_AUDIO_VOLUME;
|
||||
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
|
||||
-
|
||||
- client_ctl.value = b;
|
||||
- client_ctl.id = V4L2_CID_AUDIO_BALANCE;
|
||||
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
|
||||
|
||||
left = value->value.integer.value[0] & 0x3f;
|
||||
right = value->value.integer.value[1] & 0x3f;
|
||||
b = right - left;
|
||||
if (b < 0) {
|
||||
- v = 0x3f - left;
|
||||
- b = (-b) | 0x40;
|
||||
+ v = 0x3f - left;
|
||||
+ b = (-b) | 0x40;
|
||||
} else {
|
||||
- v = 0x3f - right;
|
||||
+ v = 0x3f - right;
|
||||
}
|
||||
/* Do we really know this will always be called with IRQs on? */
|
||||
spin_lock_irq(&chip->reg_lock);
|
||||
old = cx_read(AUD_VOL_CTL);
|
||||
if (v != (old & 0x3f)) {
|
||||
- cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v);
|
||||
- changed = 1;
|
||||
+ cx_write(AUD_VOL_CTL, (old & ~0x3f) | v);
|
||||
+ changed = 1;
|
||||
}
|
||||
- if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) {
|
||||
- cx_write(AUD_BAL_CTL, b);
|
||||
- changed = 1;
|
||||
+ if (cx_read(AUD_BAL_CTL) != b) {
|
||||
+ cx_write(AUD_BAL_CTL, b);
|
||||
+ changed = 1;
|
||||
}
|
||||
spin_unlock_irq(&chip->reg_lock);
|
||||
|
||||
@@ -640,7 +618,7 @@ static const struct snd_kcontrol_new snd_cx88_volume = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READ,
|
||||
- .name = "Analog-TV Volume",
|
||||
+ .name = "Playback Volume",
|
||||
.info = snd_cx88_volume_info,
|
||||
.get = snd_cx88_volume_get,
|
||||
.put = snd_cx88_volume_put,
|
||||
@@ -671,14 +649,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
|
||||
vol = cx_read(AUD_VOL_CTL);
|
||||
if (value->value.integer.value[0] != !(vol & bit)) {
|
||||
vol ^= bit;
|
||||
- cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
|
||||
- /* Pass mute onto any WM8775 */
|
||||
- if ((1<<6) == bit) {
|
||||
- struct v4l2_control client_ctl;
|
||||
- client_ctl.value = 0 != (vol & bit);
|
||||
- client_ctl.id = V4L2_CID_AUDIO_MUTE;
|
||||
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
|
||||
- }
|
||||
+ cx_write(AUD_VOL_CTL, vol);
|
||||
ret = 1;
|
||||
}
|
||||
spin_unlock_irq(&chip->reg_lock);
|
||||
@@ -687,7 +658,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
|
||||
|
||||
static const struct snd_kcontrol_new snd_cx88_dac_switch = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
- .name = "Audio-Out Switch",
|
||||
+ .name = "Playback Switch",
|
||||
.info = snd_ctl_boolean_mono_info,
|
||||
.get = snd_cx88_switch_get,
|
||||
.put = snd_cx88_switch_put,
|
||||
@@ -696,49 +667,13 @@ static const struct snd_kcontrol_new snd_cx88_dac_switch = {
|
||||
|
||||
static const struct snd_kcontrol_new snd_cx88_source_switch = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
- .name = "Analog-TV Switch",
|
||||
+ .name = "Capture Switch",
|
||||
.info = snd_ctl_boolean_mono_info,
|
||||
.get = snd_cx88_switch_get,
|
||||
.put = snd_cx88_switch_put,
|
||||
.private_value = (1<<6),
|
||||
};
|
||||
|
||||
-static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol,
|
||||
- struct snd_ctl_elem_value *value)
|
||||
-{
|
||||
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
- struct cx88_core *core = chip->core;
|
||||
- struct v4l2_control client_ctl;
|
||||
-
|
||||
- client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
|
||||
- call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl);
|
||||
- value->value.integer.value[0] = client_ctl.value ? 1 : 0;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol,
|
||||
- struct snd_ctl_elem_value *value)
|
||||
-{
|
||||
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
- struct cx88_core *core = chip->core;
|
||||
- struct v4l2_control client_ctl;
|
||||
-
|
||||
- client_ctl.value = 0 != value->value.integer.value[0];
|
||||
- client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
|
||||
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static struct snd_kcontrol_new snd_cx88_alc_switch = {
|
||||
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
- .name = "Line-In ALC Switch",
|
||||
- .info = snd_ctl_boolean_mono_info,
|
||||
- .get = snd_cx88_alc_get,
|
||||
- .put = snd_cx88_alc_put,
|
||||
-};
|
||||
-
|
||||
/****************************************************************************
|
||||
Basic Flow for Sound Devices
|
||||
****************************************************************************/
|
||||
@@ -860,7 +795,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
|
||||
{
|
||||
struct snd_card *card;
|
||||
snd_cx88_card_t *chip;
|
||||
- struct v4l2_subdev *sd;
|
||||
int err;
|
||||
|
||||
if (devno >= SNDRV_CARDS)
|
||||
@@ -896,15 +830,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
- /* If there's a wm8775 then add a Line-In ALC switch */
|
||||
- list_for_each_entry(sd, &chip->core->v4l2_dev.subdevs, list) {
|
||||
- if (WM8775_GID == sd->grp_id) {
|
||||
- snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch,
|
||||
- chip));
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
strcpy (card->driver, "CX88x");
|
||||
sprintf(card->shortname, "Conexant CX%x", pci->device);
|
||||
sprintf(card->longname, "%s at %#llx",
|
||||
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
|
||||
index 9b9e169..0ccc2af 100644
|
||||
--- a/drivers/media/video/cx88/cx88-cards.c
|
||||
+++ b/drivers/media/video/cx88/cx88-cards.c
|
||||
@@ -1007,15 +1007,22 @@ static const struct cx88_board cx88_boards[] = {
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
+ .audio_chip = V4L2_IDENT_WM8775,
|
||||
.input = {{
|
||||
.type = CX88_VMUX_DVB,
|
||||
.vmux = 0,
|
||||
+ /* 2: Line-In */
|
||||
+ .audioroute = 2,
|
||||
},{
|
||||
.type = CX88_VMUX_COMPOSITE1,
|
||||
.vmux = 1,
|
||||
+ /* 2: Line-In */
|
||||
+ .audioroute = 2,
|
||||
},{
|
||||
.type = CX88_VMUX_SVIDEO,
|
||||
.vmux = 2,
|
||||
+ /* 2: Line-In */
|
||||
+ .audioroute = 2,
|
||||
}},
|
||||
.mpeg = CX88_MPEG_DVB,
|
||||
},
|
||||
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
|
||||
index 62cea95..d9249e5 100644
|
||||
--- a/drivers/media/video/cx88/cx88-video.c
|
||||
+++ b/drivers/media/video/cx88/cx88-video.c
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "cx88.h"
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
-#include <media/wm8775.h>
|
||||
|
||||
MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
|
||||
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
|
||||
@@ -977,7 +976,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl)
|
||||
const struct cx88_ctrl *c = NULL;
|
||||
u32 value,mask;
|
||||
int i;
|
||||
- struct v4l2_control client_ctl;
|
||||
|
||||
for (i = 0; i < CX8800_CTLS; i++) {
|
||||
if (cx8800_ctls[i].v.id == ctl->id) {
|
||||
@@ -991,27 +989,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl)
|
||||
ctl->value = c->v.minimum;
|
||||
if (ctl->value > c->v.maximum)
|
||||
ctl->value = c->v.maximum;
|
||||
-
|
||||
- /* Pass changes onto any WM8775 */
|
||||
- client_ctl.id = ctl->id;
|
||||
- switch (ctl->id) {
|
||||
- case V4L2_CID_AUDIO_MUTE:
|
||||
- client_ctl.value = ctl->value;
|
||||
- break;
|
||||
- case V4L2_CID_AUDIO_VOLUME:
|
||||
- client_ctl.value = (ctl->value) ?
|
||||
- (0x90 + ctl->value) << 8 : 0;
|
||||
- break;
|
||||
- case V4L2_CID_AUDIO_BALANCE:
|
||||
- client_ctl.value = ctl->value << 9;
|
||||
- break;
|
||||
- default:
|
||||
- client_ctl.id = 0;
|
||||
- break;
|
||||
- }
|
||||
- if (client_ctl.id)
|
||||
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
|
||||
-
|
||||
mask=c->mask;
|
||||
switch (ctl->id) {
|
||||
case V4L2_CID_AUDIO_BALANCE:
|
||||
@@ -1558,9 +1535,7 @@ static int radio_queryctrl (struct file *file, void *priv,
|
||||
if (c->id < V4L2_CID_BASE ||
|
||||
c->id >= V4L2_CID_LASTP1)
|
||||
return -EINVAL;
|
||||
- if (c->id == V4L2_CID_AUDIO_MUTE ||
|
||||
- c->id == V4L2_CID_AUDIO_VOLUME ||
|
||||
- c->id == V4L2_CID_AUDIO_BALANCE) {
|
||||
+ if (c->id == V4L2_CID_AUDIO_MUTE) {
|
||||
for (i = 0; i < CX8800_CTLS; i++) {
|
||||
if (cx8800_ctls[i].v.id == c->id)
|
||||
break;
|
||||
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
|
||||
index e8c732e..c9981e7 100644
|
||||
--- a/drivers/media/video/cx88/cx88.h
|
||||
+++ b/drivers/media/video/cx88/cx88.h
|
||||
@@ -398,19 +398,17 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
|
||||
return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
|
||||
}
|
||||
|
||||
-#define call_hw(core, grpid, o, f, args...) \
|
||||
+#define call_all(core, o, f, args...) \
|
||||
do { \
|
||||
if (!core->i2c_rc) { \
|
||||
if (core->gate_ctrl) \
|
||||
core->gate_ctrl(core, 1); \
|
||||
- v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \
|
||||
+ v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \
|
||||
if (core->gate_ctrl) \
|
||||
core->gate_ctrl(core, 0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
-#define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args)
|
||||
-
|
||||
struct cx8800_dev;
|
||||
struct cx8802_dev;
|
||||
|
||||
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
|
||||
index 1355256..fe8ef64 100644
|
||||
--- a/drivers/media/video/wm8775.c
|
||||
+++ b/drivers/media/video/wm8775.c
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-chip-ident.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
-#include <media/wm8775.h>
|
||||
|
||||
MODULE_DESCRIPTION("wm8775 driver");
|
||||
MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
|
||||
@@ -51,16 +50,10 @@ enum {
|
||||
TOT_REGS
|
||||
};
|
||||
|
||||
-#define ALC_HOLD 0x85 /* R17: use zero cross detection, ALC hold time 42.6 ms */
|
||||
-#define ALC_EN 0x100 /* R17: ALC enable */
|
||||
-
|
||||
struct wm8775_state {
|
||||
struct v4l2_subdev sd;
|
||||
struct v4l2_ctrl_handler hdl;
|
||||
struct v4l2_ctrl *mute;
|
||||
- struct v4l2_ctrl *vol;
|
||||
- struct v4l2_ctrl *bal;
|
||||
- struct v4l2_ctrl *loud;
|
||||
u8 input; /* Last selected input (0-0xf) */
|
||||
};
|
||||
|
||||
@@ -92,30 +85,6 @@ static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val)
|
||||
return -1;
|
||||
}
|
||||
|
||||
-static void wm8775_set_audio(struct v4l2_subdev *sd, int quietly)
|
||||
-{
|
||||
- struct wm8775_state *state = to_state(sd);
|
||||
- u8 vol_l, vol_r;
|
||||
- int muted = 0 != state->mute->val;
|
||||
- u16 volume = (u16)state->vol->val;
|
||||
- u16 balance = (u16)state->bal->val;
|
||||
-
|
||||
- /* normalize ( 65535 to 0 -> 255 to 0 (+24dB to -103dB) ) */
|
||||
- vol_l = (min(65536 - balance, 32768) * volume) >> 23;
|
||||
- vol_r = (min(balance, (u16)32768) * volume) >> 23;
|
||||
-
|
||||
- /* Mute */
|
||||
- if (muted || quietly)
|
||||
- wm8775_write(sd, R21, 0x0c0 | state->input);
|
||||
-
|
||||
- wm8775_write(sd, R14, vol_l | 0x100); /* 0x100= Left channel ADC zero cross enable */
|
||||
- wm8775_write(sd, R15, vol_r | 0x100); /* 0x100= Right channel ADC zero cross enable */
|
||||
-
|
||||
- /* Un-mute */
|
||||
- if (!muted)
|
||||
- wm8775_write(sd, R21, state->input);
|
||||
-}
|
||||
-
|
||||
static int wm8775_s_routing(struct v4l2_subdev *sd,
|
||||
u32 input, u32 output, u32 config)
|
||||
{
|
||||
@@ -133,26 +102,25 @@ static int wm8775_s_routing(struct v4l2_subdev *sd,
|
||||
state->input = input;
|
||||
if (!v4l2_ctrl_g_ctrl(state->mute))
|
||||
return 0;
|
||||
- if (!v4l2_ctrl_g_ctrl(state->vol))
|
||||
- return 0;
|
||||
- if (!v4l2_ctrl_g_ctrl(state->bal))
|
||||
- return 0;
|
||||
- wm8775_set_audio(sd, 1);
|
||||
+ wm8775_write(sd, R21, 0x0c0);
|
||||
+ wm8775_write(sd, R14, 0x1d4);
|
||||
+ wm8775_write(sd, R15, 0x1d4);
|
||||
+ wm8775_write(sd, R21, 0x100 + state->input);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct v4l2_subdev *sd = to_sd(ctrl);
|
||||
+ struct wm8775_state *state = to_state(sd);
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
- case V4L2_CID_AUDIO_VOLUME:
|
||||
- case V4L2_CID_AUDIO_BALANCE:
|
||||
- wm8775_set_audio(sd, 0);
|
||||
- return 0;
|
||||
- case V4L2_CID_AUDIO_LOUDNESS:
|
||||
- wm8775_write(sd, R17, (ctrl->val ? ALC_EN : 0) | ALC_HOLD);
|
||||
+ wm8775_write(sd, R21, 0x0c0);
|
||||
+ wm8775_write(sd, R14, 0x1d4);
|
||||
+ wm8775_write(sd, R15, 0x1d4);
|
||||
+ if (!ctrl->val)
|
||||
+ wm8775_write(sd, R21, 0x100 + state->input);
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
@@ -176,7 +144,16 @@ static int wm8775_log_status(struct v4l2_subdev *sd)
|
||||
|
||||
static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
|
||||
{
|
||||
- wm8775_set_audio(sd, 0);
|
||||
+ struct wm8775_state *state = to_state(sd);
|
||||
+
|
||||
+ /* If I remove this, then it can happen that I have no
|
||||
+ sound the first time I tune from static to a valid channel.
|
||||
+ It's difficult to reproduce and is almost certainly related
|
||||
+ to the zero cross detect circuit. */
|
||||
+ wm8775_write(sd, R21, 0x0c0);
|
||||
+ wm8775_write(sd, R14, 0x1d4);
|
||||
+ wm8775_write(sd, R15, 0x1d4);
|
||||
+ wm8775_write(sd, R21, 0x100 + state->input);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -226,7 +203,6 @@ static int wm8775_probe(struct i2c_client *client,
|
||||
{
|
||||
struct wm8775_state *state;
|
||||
struct v4l2_subdev *sd;
|
||||
- int err;
|
||||
|
||||
/* Check if the adapter supports the needed features */
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
@@ -240,21 +216,15 @@ static int wm8775_probe(struct i2c_client *client,
|
||||
return -ENOMEM;
|
||||
sd = &state->sd;
|
||||
v4l2_i2c_subdev_init(sd, client, &wm8775_ops);
|
||||
- sd->grp_id = WM8775_GID; /* subdev group id */
|
||||
state->input = 2;
|
||||
|
||||
- v4l2_ctrl_handler_init(&state->hdl, 4);
|
||||
+ v4l2_ctrl_handler_init(&state->hdl, 1);
|
||||
state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
|
||||
V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
|
||||
- state->vol = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
|
||||
- V4L2_CID_AUDIO_VOLUME, 0, 65535, (65535+99)/100, 0xCF00); /* 0dB*/
|
||||
- state->bal = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
|
||||
- V4L2_CID_AUDIO_BALANCE, 0, 65535, (65535+99)/100, 32768);
|
||||
- state->loud = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
|
||||
- V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 1);
|
||||
sd->ctrl_handler = &state->hdl;
|
||||
- err = state->hdl.error;
|
||||
- if (err) {
|
||||
+ if (state->hdl.error) {
|
||||
+ int err = state->hdl.error;
|
||||
+
|
||||
v4l2_ctrl_handler_free(&state->hdl);
|
||||
kfree(state);
|
||||
return err;
|
||||
@@ -266,25 +236,29 @@ static int wm8775_probe(struct i2c_client *client,
|
||||
wm8775_write(sd, R23, 0x000);
|
||||
/* Disable zero cross detect timeout */
|
||||
wm8775_write(sd, R7, 0x000);
|
||||
- /* HPF enable, I2S mode, 24-bit */
|
||||
- wm8775_write(sd, R11, 0x022);
|
||||
+ /* Left justified, 24-bit mode */
|
||||
+ wm8775_write(sd, R11, 0x021);
|
||||
/* Master mode, clock ratio 256fs */
|
||||
wm8775_write(sd, R12, 0x102);
|
||||
/* Powered up */
|
||||
wm8775_write(sd, R13, 0x000);
|
||||
- /* ALC stereo, ALC target level -5dB FS, ALC max gain +8dB */
|
||||
- wm8775_write(sd, R16, 0x1bb);
|
||||
- /* Set ALC mode and hold time */
|
||||
- wm8775_write(sd, R17, (state->loud->val ? ALC_EN : 0) | ALC_HOLD);
|
||||
+ /* ADC gain +2.5dB, enable zero cross */
|
||||
+ wm8775_write(sd, R14, 0x1d4);
|
||||
+ /* ADC gain +2.5dB, enable zero cross */
|
||||
+ wm8775_write(sd, R15, 0x1d4);
|
||||
+ /* ALC Stereo, ALC target level -1dB FS max gain +8dB */
|
||||
+ wm8775_write(sd, R16, 0x1bf);
|
||||
+ /* Enable gain control, use zero cross detection,
|
||||
+ ALC hold time 42.6 ms */
|
||||
+ wm8775_write(sd, R17, 0x185);
|
||||
/* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */
|
||||
wm8775_write(sd, R18, 0x0a2);
|
||||
/* Enable noise gate, threshold -72dBfs */
|
||||
wm8775_write(sd, R19, 0x005);
|
||||
- /* Transient window 4ms, ALC min gain -5dB */
|
||||
- wm8775_write(sd, R20, 0x0fb);
|
||||
-
|
||||
- wm8775_set_audio(sd, 1); /* set volume/mute/mux */
|
||||
-
|
||||
+ /* Transient window 4ms, lower PGA gain limit -1dB */
|
||||
+ wm8775_write(sd, R20, 0x07a);
|
||||
+ /* LRBOTH = 1, use input 2. */
|
||||
+ wm8775_write(sd, R21, 0x102);
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/include/media/wm8775.h b/include/media/wm8775.h
|
||||
index a1c4d41..60739c5 100644
|
||||
--- a/include/media/wm8775.h
|
||||
+++ b/include/media/wm8775.h
|
||||
@@ -32,7 +32,4 @@
|
||||
#define WM8775_AIN3 4
|
||||
#define WM8775_AIN4 8
|
||||
|
||||
-/* subdev group ID */
|
||||
-#define WM8775_GID (1 << 0)
|
||||
-
|
||||
#endif
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user