Merge "msm: pil: Remove dependence on iomap.h"
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index e882c17..002332b 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -24,6 +24,16 @@
compatible = "ti,bq28400-battery";
reg = <0xb>;
};
+
+ charger@2b {
+ compatible = "summit,smb350-charger";
+ reg = <0x2b>; /* 0x56/0x57 */
+ summit,stat-gpio = <&pm8941_gpios 30 0x00>;
+ summit,chg-en-n-gpio = <&pm8941_gpios 10 0x00>;
+ summit,chg-susp-n-gpio = <&pm8941_gpios 13 0x00>;
+ summit,chg-current-ma = <1600>;
+ summit,term-current-ma = <300>;
+ };
};
gpio_keys {
@@ -219,6 +229,14 @@
};
gpio@c900 { /* GPIO 10 */
+ /* SMB350-CHG-EN-N */
+ qcom,mode = <1>; /* DIG_OUT */
+ qcom,output-type = <0>; /* CMOS */
+ qcom,pull = <5>; /* PULL_NO */
+ qcom,vin-sel = <0>; /* VPH */
+ qcom,out-strength = <2>; /* STRENGTH_MED */
+ qcom,src-sel = <0>; /* CONSTANT */
+ qcom,master-en = <1>;
};
gpio@ca00 { /* GPIO 11 */
@@ -228,6 +246,14 @@
};
gpio@cc00 { /* GPIO 13 */
+ /* SMB350-CHG-SUSP-N */
+ qcom,mode = <1>; /* DIG_OUT */
+ qcom,output-type = <0>; /* CMOS */
+ qcom,pull = <5>; /* PULL_NO */
+ qcom,vin-sel = <0>; /* VPH */
+ qcom,out-strength = <2>; /* STRENGTH_MED */
+ qcom,src-sel = <0>; /* CONSTANT */
+ qcom,master-en = <1>;
};
gpio@cd00 { /* GPIO 14 */
@@ -296,6 +322,12 @@
};
gpio@dd00 { /* GPIO 30 */
+ /* SMB350-STAT */
+ qcom,mode = <0>; /* DIG_IN */
+ qcom,pull = <5>; /* PULL_NO */
+ qcom,vin-sel = <2>; /* S3 1.8V */
+ qcom,src-sel = <0>; /* CONSTANT */
+ qcom,master-en = <1>;
};
gpio@de00 { /* GPIO 31 */
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 0a349f7..7b01020 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -241,6 +241,7 @@
compatible = "qcom,bam_dmux";
reg = <0xfc834000 0x7000>;
interrupts = <0 29 1>;
+ qcom,satellite-mode;
};
qcom,acpuclk@f9010000 {
diff --git a/arch/arm/configs/msm8910_defconfig b/arch/arm/configs/msm8910_defconfig
index 83a499b..3d0d797 100644
--- a/arch/arm/configs/msm8910_defconfig
+++ b/arch/arm/configs/msm8910_defconfig
@@ -22,6 +22,7 @@
CONFIG_BLK_DEV_INITRD=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
+CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 47498d1..cbcd546 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -273,6 +273,7 @@
CONFIG_GPIO_QPNP_PIN_DEBUG=y
CONFIG_POWER_SUPPLY=y
CONFIG_BATTERY_BQ28400=y
+CONFIG_SMB350_CHARGER=y
CONFIG_QPNP_CHARGER=y
CONFIG_QPNP_BMS=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 6bd87de..fd642ee 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -384,6 +384,8 @@
select MULTI_IRQ_HANDLER
select GPIO_MSM_V3
select MSM_GPIOMUX
+ select MSM_NATIVE_RESTART
+ select MSM_RESTART_V2
endmenu
choice
diff --git a/arch/arm/mach-msm/board-8910.c b/arch/arm/mach-msm/board-8910.c
index eaf146b..085b23d 100644
--- a/arch/arm/mach-msm/board-8910.c
+++ b/arch/arm/mach-msm/board-8910.c
@@ -31,6 +31,7 @@
#include <mach/board.h>
#include <mach/gpiomux.h>
#include <mach/msm_iomap.h>
+#include <mach/restart.h>
#ifdef CONFIG_ION_MSM
#include <mach/ion.h>
#endif
@@ -80,4 +81,5 @@
.handle_irq = gic_handle_irq,
.timer = &msm_dt_timer,
.dt_compat = msm8910_dt_match,
+ .restart = msm_restart,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 9b315c0..1aa9c10 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -762,7 +762,7 @@
.regulator = {
{
.name = "CDC_VDD_CP",
- .min_uV = 1800000,
+ .min_uV = 2200000,
.max_uV = 2200000,
.optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
},
@@ -828,7 +828,7 @@
.regulator = {
{
.name = "CDC_VDD_CP",
- .min_uV = 1800000,
+ .min_uV = 2200000,
.max_uV = 2200000,
.optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
},
@@ -2295,7 +2295,6 @@
static struct platform_device *common_devices[] __initdata = {
&msm_8960_q6_lpass,
- &msm_8960_q6_mss,
&msm_8960_riva,
&msm_pil_tzapps,
&msm_pil_vidc,
@@ -2714,11 +2713,34 @@
#endif
}
+/*Modify the WCD9xxx platform data to support supplies from PM8917 */
+static void __init msm8930_pm8917_wcd9xxx_pdata_fixup(
+ struct wcd9xxx_pdata *cdc_pdata)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cdc_pdata->regulator); i++) {
+
+ if (cdc_pdata->regulator[i].name != NULL
+ && strncmp(cdc_pdata->regulator[i].name,
+ "CDC_VDD_CP", 10) == 0) {
+ cdc_pdata->regulator[i].min_uV =
+ cdc_pdata->regulator[i].max_uV = 1800000;
+ pr_info("%s: CDC_VDD_CP forced to 1.8 volts for PM8917\n",
+ __func__);
+ return;
+ }
+ }
+}
+
/* Modify platform data values to match requirements for PM8917. */
static void __init msm8930_pm8917_pdata_fixup(void)
{
struct acpuclk_platform_data *pdata;
+ msm8930_pm8917_wcd9xxx_pdata_fixup(&sitar_platform_data);
+ msm8930_pm8917_wcd9xxx_pdata_fixup(&sitar1p1_platform_data);
+
mhl_platform_data.gpio_mhl_power = MHL_POWER_GPIO_PM8917;
gpio_keys_8930_pdata.buttons = keys_8930_pm8917;
@@ -2825,6 +2847,10 @@
else
msm8930_pm8917_gpio_mpp_init();
#endif
+ /* Don't add modem devices on APQ targets */
+ if (socinfo_get_id() != 119 && socinfo_get_id() != 157
+ && socinfo_get_id() != 160)
+ platform_device_register(&msm_8960_q6_mss);
platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
#ifdef CONFIG_MSM_CAMERA
msm8930_init_cam();
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 5c5b51e..5a9799a 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -607,7 +607,7 @@
},
.c = {
.dbg_name = "smi_2x_axi_clk",
- .ops = &clk_ops_branch,
+ .ops = &clk_ops_smi_2x,
CLK_INIT(smi_2x_axi_clk.c),
},
};
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index d2260cb..c43ca46 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -839,6 +839,14 @@
.set_flags = branch_clk_set_flags,
};
+struct clk_ops clk_ops_smi_2x = {
+ .prepare = branch_clk_enable,
+ .unprepare = branch_clk_disable,
+ .is_enabled = branch_clk_is_enabled,
+ .get_parent = branch_clk_get_parent,
+ .handoff = branch_clk_handoff,
+};
+
struct clk_ops clk_ops_reset = {
.reset = branch_clk_reset,
};
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 1873343..fca6486 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -153,6 +153,7 @@
};
extern struct clk_ops clk_ops_branch;
+extern struct clk_ops clk_ops_smi_2x;
extern struct clk_ops clk_ops_reset;
int branch_reset(struct branch *b, enum clk_reset_action action);
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 1603c93..e7a596d 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -67,7 +67,6 @@
static int pll_byte_clk_rate;
static int pll_pclk_rate;
static int pll_initialized;
-static int pll_enabled;
static struct clk *mdss_dsi_ahb_clk;
static unsigned long dsi_pll_rate;
@@ -208,15 +207,12 @@
return 0;
}
-static int mdss_dsi_pll_enable(struct clk *c)
+static int __mdss_dsi_pll_enable(struct clk *c)
{
u32 status;
u32 max_reads, timeout_us;
int i;
- if (pll_enabled)
- return 0;
-
if (!pll_initialized) {
if (dsi_pll_rate)
mdss_dsi_pll_byte_set_rate(c, dsi_pll_rate);
@@ -266,12 +262,11 @@
pr_debug("%s: **** PLL Lock success\n", __func__);
clk_disable(mdss_dsi_ahb_clk);
- pll_enabled = 1;
return 0;
}
-static void mdss_dsi_pll_disable(struct clk *c)
+static void __mdss_dsi_pll_disable(void)
{
if (!mdss_dsi_ahb_clk)
pr_err("%s: mdss_dsi_ahb_clk not initialized\n",
@@ -282,7 +277,40 @@
clk_disable(mdss_dsi_ahb_clk);
pr_debug("%s: **** disable pll Initialize\n", __func__);
pll_initialized = 0;
- pll_enabled = 0;
+}
+
+static DEFINE_SPINLOCK(dsipll_lock);
+static int dsipll_refcount;
+
+static void mdss_dsi_pll_disable(struct clk *c)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dsipll_lock, flags);
+ if (WARN(dsipll_refcount == 0, "DSI PLL clock is unbalanced"))
+ goto out;
+ if (dsipll_refcount == 1)
+ __mdss_dsi_pll_disable();
+ dsipll_refcount--;
+out:
+ spin_unlock_irqrestore(&dsipll_lock, flags);
+}
+
+static int mdss_dsi_pll_enable(struct clk *c)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&dsipll_lock, flags);
+ if (dsipll_refcount == 0) {
+ ret = __mdss_dsi_pll_enable(c);
+ if (ret < 0)
+ goto out;
+ }
+ dsipll_refcount++;
+out:
+ spin_unlock_irqrestore(&dsipll_lock, flags);
+ return ret;
}
void hdmi_pll_disable(void)
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index daf83e2..63e67b3 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -12,37 +12,29 @@
*/
#include <linux/err.h>
+#include <linux/mutex.h>
#include <mach/clk-provider.h>
#include "rpm_resources.h"
#include "clock-rpm.h"
-#define __clk_rpmrs_set_rate(r, value, ctx, noirq) \
- ((r)->rpmrs_data->set_rate_fn((r), (value), (ctx), (noirq)))
+#define __clk_rpmrs_set_rate(r, value, ctx) \
+ ((r)->rpmrs_data->set_rate_fn((r), (value), (ctx)))
#define clk_rpmrs_set_rate_sleep(r, value) \
- __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_sleep_id, 0)
-
-#define clk_rpmrs_set_rate_sleep_noirq(r, value) \
- __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_sleep_id, 1)
+ __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_sleep_id)
#define clk_rpmrs_set_rate_active(r, value) \
- __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_active_id, 0)
-
-#define clk_rpmrs_set_rate_active_noirq(r, value) \
- __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_active_id, 1)
+ __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_active_id)
static int clk_rpmrs_set_rate(struct rpm_clk *r, uint32_t value,
- uint32_t context, int noirq)
+ uint32_t context)
{
struct msm_rpm_iv_pair iv = {
.id = r->rpm_clk_id,
.value = value,
};
- if (noirq)
- return msm_rpmrs_set_noirq(context, &iv, 1);
- else
- return msm_rpmrs_set(context, &iv, 1);
+ return msm_rpmrs_set(context, &iv, 1);
}
static int clk_rpmrs_get_rate(struct rpm_clk *r)
@@ -72,7 +64,7 @@
}
static int clk_rpmrs_set_rate_smd(struct rpm_clk *r, uint32_t value,
- uint32_t context, int noirq)
+ uint32_t context)
{
struct msm_rpm_kvp kvp = {
.key = r->rpm_key,
@@ -80,12 +72,8 @@
.length = sizeof(value),
};
- if (noirq)
- return msm_rpm_send_message_noirq(context,
- r->rpm_res_type, r->rpm_clk_id, &kvp, 1);
- else
- return msm_rpm_send_message(context, r->rpm_res_type,
- r->rpm_clk_id, &kvp, 1);
+ return msm_rpm_send_message(context, r->rpm_res_type, r->rpm_clk_id,
+ &kvp, 1);
}
static int clk_rpmrs_handoff_smd(struct rpm_clk *r)
@@ -94,8 +82,7 @@
}
struct clk_rpmrs_data {
- int (*set_rate_fn)(struct rpm_clk *r, uint32_t value,
- uint32_t context, int noirq);
+ int (*set_rate_fn)(struct rpm_clk *r, uint32_t value, uint32_t context);
int (*get_rate_fn)(struct rpm_clk *r);
int (*handoff_fn)(struct rpm_clk *r);
int ctx_active_id;
@@ -117,11 +104,10 @@
.ctx_sleep_id = MSM_RPM_CTX_SLEEP_SET,
};
-static DEFINE_SPINLOCK(rpm_clock_lock);
+static DEFINE_MUTEX(rpm_clock_lock);
-static int rpm_clk_enable(struct clk *clk)
+static int rpm_clk_prepare(struct clk *clk)
{
- unsigned long flags;
struct rpm_clk *r = to_rpm_clk(clk);
uint32_t value;
int rc = 0;
@@ -129,7 +115,7 @@
unsigned long peer_khz = 0, peer_sleep_khz = 0;
struct rpm_clk *peer = r->peer;
- spin_lock_irqsave(&rpm_clock_lock, flags);
+ mutex_lock(&rpm_clock_lock);
this_khz = r->last_set_khz;
/* Don't send requests to the RPM if the rate has not been set. */
@@ -148,7 +134,7 @@
if (r->branch)
value = !!value;
- rc = clk_rpmrs_set_rate_active_noirq(r, value);
+ rc = clk_rpmrs_set_rate_active(r, value);
if (rc)
goto out;
@@ -156,28 +142,27 @@
if (r->branch)
value = !!value;
- rc = clk_rpmrs_set_rate_sleep_noirq(r, value);
+ rc = clk_rpmrs_set_rate_sleep(r, value);
if (rc) {
/* Undo the active set vote and restore it to peer_khz */
value = peer_khz;
- rc = clk_rpmrs_set_rate_active_noirq(r, value);
+ rc = clk_rpmrs_set_rate_active(r, value);
}
out:
if (!rc)
r->enabled = true;
- spin_unlock_irqrestore(&rpm_clock_lock, flags);
+ mutex_unlock(&rpm_clock_lock);
return rc;
}
-static void rpm_clk_disable(struct clk *clk)
+static void rpm_clk_unprepare(struct clk *clk)
{
- unsigned long flags;
struct rpm_clk *r = to_rpm_clk(clk);
- spin_lock_irqsave(&rpm_clock_lock, flags);
+ mutex_lock(&rpm_clock_lock);
if (r->last_set_khz) {
uint32_t value;
@@ -192,30 +177,29 @@
}
value = r->branch ? !!peer_khz : peer_khz;
- rc = clk_rpmrs_set_rate_active_noirq(r, value);
+ rc = clk_rpmrs_set_rate_active(r, value);
if (rc)
goto out;
value = r->branch ? !!peer_sleep_khz : peer_sleep_khz;
- rc = clk_rpmrs_set_rate_sleep_noirq(r, value);
+ rc = clk_rpmrs_set_rate_sleep(r, value);
}
r->enabled = false;
out:
- spin_unlock_irqrestore(&rpm_clock_lock, flags);
+ mutex_unlock(&rpm_clock_lock);
return;
}
static int rpm_clk_set_rate(struct clk *clk, unsigned long rate)
{
- unsigned long flags;
struct rpm_clk *r = to_rpm_clk(clk);
unsigned long this_khz, this_sleep_khz;
int rc = 0;
this_khz = DIV_ROUND_UP(rate, r->factor);
- spin_lock_irqsave(&rpm_clock_lock, flags);
+ mutex_lock(&rpm_clock_lock);
/* Active-only clocks don't care what the rate is during sleep. So,
* they vote for zero. */
@@ -236,12 +220,12 @@
}
value = max(this_khz, peer_khz);
- rc = clk_rpmrs_set_rate_active_noirq(r, value);
+ rc = clk_rpmrs_set_rate_active(r, value);
if (rc)
goto out;
value = max(this_sleep_khz, peer_sleep_khz);
- rc = clk_rpmrs_set_rate_sleep_noirq(r, value);
+ rc = clk_rpmrs_set_rate_sleep(r, value);
}
if (!rc) {
r->last_set_khz = this_khz;
@@ -249,7 +233,7 @@
}
out:
- spin_unlock_irqrestore(&rpm_clock_lock, flags);
+ mutex_unlock(&rpm_clock_lock);
return rc;
}
@@ -319,8 +303,8 @@
}
struct clk_ops clk_ops_rpm = {
- .enable = rpm_clk_enable,
- .disable = rpm_clk_disable,
+ .prepare = rpm_clk_prepare,
+ .unprepare = rpm_clk_unprepare,
.set_rate = rpm_clk_set_rate,
.get_rate = rpm_clk_get_rate,
.is_enabled = rpm_clk_is_enabled,
@@ -330,8 +314,8 @@
};
struct clk_ops clk_ops_rpm_branch = {
- .enable = rpm_clk_enable,
- .disable = rpm_clk_disable,
+ .prepare = rpm_clk_prepare,
+ .unprepare = rpm_clk_unprepare,
.is_local = rpm_clk_is_local,
.handoff = rpm_clk_handoff,
};
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 9aa771a..ddb98b4 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1643,6 +1643,7 @@
case 0x771:
case 0x77C:
case 0x780:
+ case 0x785: /* Edge-only MSM8125-0 */
case 0x8D0:
cpu = MSM8625;
break;
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8910.h b/arch/arm/mach-msm/include/mach/msm_iomap-8910.h
index e4cd312..08f21b6 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8910.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8910.h
@@ -30,9 +30,12 @@
#define MSM8910_TLMM_PHYS 0xFD510000
#define MSM8910_TLMM_SIZE SZ_16K
-#define MSM8910_IMEM_PHYS 0xFC42B000
+#define MSM8910_IMEM_PHYS 0xFE805000
#define MSM8910_IMEM_SIZE SZ_4K
+#define MSM8910_MPM2_PSHOLD_PHYS 0xFC4AB000
+#define MSM8910_MPM2_PSHOLD_SIZE SZ_4K
+
#ifdef CONFIG_DEBUG_MSM8910_UART
#define MSM_DEBUG_UART_BASE IOMEM(0xFA71E000)
#define MSM_DEBUG_UART_PHYS 0xF991E000
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 6fa7faa..ae908e1 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -542,6 +542,7 @@
static struct map_desc msm8910_io_desc[] __initdata = {
MSM_CHIP_DEVICE(APCS_GCC, MSM8910),
MSM_CHIP_DEVICE(TLMM, MSM8910),
+ MSM_CHIP_DEVICE(MPM2_PSHOLD, MSM8910),
MSM_CHIP_DEVICE(IMEM, MSM8910),
{
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index d6abdda..fb0ace7 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -779,6 +779,8 @@
__func__, audio, buf_node, buf_node->paddr,
buf_node->buf.data_len,
audio->buf_cfg.meta_info_enable);
+ pr_debug("%s[%p]: flags = 0x%x\n", __func__, audio,
+ buf_node->meta_info.meta_in.nflags);
ac = audio->ac;
/* Offset with appropriate meta */
@@ -798,6 +800,11 @@
param.flags = 0;
else
param.flags = 0xFF00;
+
+ if ((buf_node != NULL) &&
+ (buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOF_SET))
+ param.flags |= AUDIO_DEC_EOF_SET;
+
param.uid = param.paddr;
/* Read command will populate paddr as token */
buf_node->token = param.paddr;
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
index b2829c3..dedf991 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
@@ -36,6 +36,7 @@
#define ADRV_STATUS_FSYNC 0x00000008
#define ADRV_STATUS_PAUSE 0x00000010
#define AUDIO_DEC_EOS_SET 0x00000001
+#define AUDIO_DEC_EOF_SET 0x00000010
#define AUDIO_EVENT_NUM 10
#define __CONTAINS(r, v, l) ({ \
diff --git a/arch/arm/mach-msm/scm-pas.c b/arch/arm/mach-msm/scm-pas.c
index 55ae2f8..e248917 100644
--- a/arch/arm/mach-msm/scm-pas.c
+++ b/arch/arm/mach-msm/scm-pas.c
@@ -24,6 +24,7 @@
#include "scm-pas.h"
#define PAS_INIT_IMAGE_CMD 1
+#define PAS_MEM_SETUP_CMD 2
#define PAS_AUTH_AND_RESET_CMD 5
#define PAS_SHUTDOWN_CMD 6
#define PAS_IS_SUPPORTED_CMD 7
@@ -55,6 +56,28 @@
}
EXPORT_SYMBOL(pas_init_image);
+int pas_mem_setup(enum pas_id id, u32 start_addr, u32 len)
+{
+ int ret;
+ struct pas_init_image_req {
+ u32 proc;
+ u32 start_addr;
+ u32 len;
+ } request;
+ u32 scm_ret = 0;
+
+ request.proc = id;
+ request.start_addr = start_addr;
+ request.len = len;
+
+ ret = scm_call(SCM_SVC_PIL, PAS_MEM_SETUP_CMD, &request,
+ sizeof(request), &scm_ret, sizeof(scm_ret));
+ if (ret)
+ return ret;
+ return scm_ret;
+}
+EXPORT_SYMBOL(pas_mem_setup);
+
static struct msm_bus_paths scm_pas_bw_tbl[] = {
{
.vectors = (struct msm_bus_vectors[]){
diff --git a/arch/arm/mach-msm/scm-pas.h b/arch/arm/mach-msm/scm-pas.h
index 8da1d75..6441a18 100644
--- a/arch/arm/mach-msm/scm-pas.h
+++ b/arch/arm/mach-msm/scm-pas.h
@@ -27,6 +27,7 @@
#ifdef CONFIG_MSM_PIL
extern int pas_init_image(enum pas_id id, const u8 *metadata, size_t size);
+extern int pas_mem_setup(enum pas_id id, u32 start_addr, u32 len);
extern int pas_auth_and_reset(enum pas_id id);
extern int pas_shutdown(enum pas_id id);
extern int pas_supported(enum pas_id id);
@@ -36,6 +37,10 @@
{
return 0;
}
+static inline int pas_mem_setup(enum pas_id id, u32 start_addr, u32 len)
+{
+ return 0;
+}
static inline int pas_auth_and_reset(enum pas_id id)
{
return 0;
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index ecdc951..73ebdf6 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -41,7 +41,7 @@
#ifdef CONFIG_ARCH_FSM9XXX
#define NUM_SMD_PKT_PORTS 4
#else
-#define NUM_SMD_PKT_PORTS 15
+#define NUM_SMD_PKT_PORTS 24
#endif
#define PDRIVER_NAME_MAX_SIZE 32
@@ -711,6 +711,15 @@
"smdcntl6",
"smdcntl7",
"smd22",
+ "smdcnt_rev0",
+ "smdcnt_rev1",
+ "smdcnt_rev2",
+ "smdcnt_rev3",
+ "smdcnt_rev4",
+ "smdcnt_rev5",
+ "smdcnt_rev6",
+ "smdcnt_rev7",
+ "smdcnt_rev8",
"smd_sns_dsps",
"apr_apps2",
"smdcntl8",
@@ -729,6 +738,15 @@
"DATA13_CNTL",
"DATA14_CNTL",
"DATA22",
+ "DATA23_CNTL",
+ "DATA24_CNTL",
+ "DATA25_CNTL",
+ "DATA26_CNTL",
+ "DATA27_CNTL",
+ "DATA28_CNTL",
+ "DATA29_CNTL",
+ "DATA30_CNTL",
+ "DATA31_CNTL",
"SENSOR",
"apr_apps2",
"DATA40_CNTL",
@@ -747,6 +765,15 @@
SMD_APPS_MODEM,
SMD_APPS_MODEM,
SMD_APPS_MODEM,
+ SMD_APPS_MODEM,
+ SMD_APPS_MODEM,
+ SMD_APPS_MODEM,
+ SMD_APPS_MODEM,
+ SMD_APPS_MODEM,
+ SMD_APPS_MODEM,
+ SMD_APPS_MODEM,
+ SMD_APPS_MODEM,
+ SMD_APPS_MODEM,
SMD_APPS_DSPS,
SMD_APPS_QDSP,
SMD_APPS_MODEM,
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 62085f6..6cb9339 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -260,6 +260,7 @@
[128] = MSM_CPU_8625,
[129] = MSM_CPU_8625,
[137] = MSM_CPU_8625,
+ [167] = MSM_CPU_8625,
/* 8064 MPQ ID */
[130] = MSM_CPU_8064,
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
index 50bae55..e2a16ad 100644
--- a/drivers/coresight/coresight-etm.c
+++ b/drivers/coresight/coresight-etm.c
@@ -25,8 +25,9 @@
#include <linux/wakelock.h>
#include <linux/sysfs.h>
#include <linux/stat.h>
-#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <linux/clk.h>
+#include <linux/cpu.h>
#include <linux/of_coresight.h>
#include <linux/coresight.h>
#include <asm/sections.h>
@@ -191,10 +192,12 @@
struct device *dev;
struct coresight_device *csdev;
struct clk *clk;
- struct mutex mutex;
+ spinlock_t spinlock;
struct wake_lock wake_lock;
int cpu;
uint8_t arch;
+ bool enable;
+ bool os_unlock;
uint8_t nr_addr_cmp;
uint8_t nr_cntr;
uint8_t nr_ext_inp;
@@ -203,7 +206,6 @@
uint8_t reset;
uint32_t mode;
uint32_t ctrl;
- uint8_t ctrl_pwrdwn;
uint32_t trigger_event;
uint32_t startstop_ctrl;
uint32_t enable_event;
@@ -230,12 +232,22 @@
uint32_t ctxid_mask;
uint32_t sync_freq;
uint32_t timestamp_event;
- uint8_t pdcr_pwrup;
bool pcsave_impl;
bool pcsave_enable;
};
-static struct etm_drvdata *etm0drvdata;
+static struct etm_drvdata *etmdrvdata[NR_CPUS];
+
+/*
+ * Memory mapped writes to clear os lock are not supported on Krait v1, v2
+ * and OS lock must be unlocked before any memory mapped access, otherwise
+ * memory mapped reads/writes will be invalid.
+ */
+static void etm_os_unlock(void *info)
+{
+ etm_writel_cp14(0x0, ETMOSLAR);
+ isb();
+}
/*
* ETM clock is derived from the processor clock and gets enabled on a
@@ -339,48 +351,18 @@
etm_readl(drvdata, ETMSR));
}
-static void etm_save_pwrdwn(struct etm_drvdata *drvdata)
-{
- drvdata->ctrl_pwrdwn = BVAL(etm_readl(drvdata, ETMCR), 0);
-}
-
-static void etm_restore_pwrdwn(struct etm_drvdata *drvdata)
-{
- uint32_t etmcr;
-
- etmcr = etm_readl(drvdata, ETMCR);
- etmcr = (etmcr & ~BIT(0)) | drvdata->ctrl_pwrdwn;
- etm_writel(drvdata, etmcr, ETMCR);
-}
-
-static void etm_save_pwrup(struct etm_drvdata *drvdata)
-{
- drvdata->pdcr_pwrup = BVAL(etm_readl_mm(drvdata, ETMPDCR), 3);
-}
-
-static void etm_restore_pwrup(struct etm_drvdata *drvdata)
-{
- uint32_t etmpdcr;
-
- etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
- etmpdcr = (etmpdcr & ~BIT(3)) | (drvdata->pdcr_pwrup << 3);
- etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
-}
-
static void etm_enable_pcsave(void *info)
{
struct etm_drvdata *drvdata = info;
ETM_UNLOCK(drvdata);
- etm_save_pwrup(drvdata);
/*
* ETMPDCR is only accessible via memory mapped interface and so use
* it first to enable power/clock to allow subsequent cp14 accesses.
*/
etm_set_pwrup(drvdata);
etm_clr_pwrdwn(drvdata);
- etm_restore_pwrup(drvdata);
ETM_LOCK(drvdata);
}
@@ -391,14 +373,10 @@
ETM_UNLOCK(drvdata);
- etm_save_pwrup(drvdata);
- /*
- * ETMPDCR is only accessible via memory mapped interface and so use
- * it first to enable power/clock to allow subsequent cp14 accesses.
- */
- etm_set_pwrup(drvdata);
- etm_set_pwrdwn(drvdata);
- etm_restore_pwrup(drvdata);
+ if (!drvdata->enable) {
+ etm_set_pwrdwn(drvdata);
+ etm_clr_pwrup(drvdata);
+ }
ETM_LOCK(drvdata);
}
@@ -416,10 +394,10 @@
* to allow subsequent cp14 accesses.
*/
etm_set_pwrup(drvdata);
- etm_save_pwrdwn(drvdata);
/*
* Clear power down bit since when this bit is set writes to
- * certain registers might be ignored.
+ * certain registers might be ignored. This is also a pre-requisite
+ * for trace enable.
*/
etm_clr_pwrdwn(drvdata);
etm_set_prog(drvdata);
@@ -463,7 +441,6 @@
etm_writel(drvdata, 0x00000000, ETMVMIDCVR);
etm_clr_prog(drvdata);
- etm_restore_pwrdwn(drvdata);
ETM_LOCK(drvdata);
dev_dbg(drvdata->dev, "cpu: %d enable smp call done\n", drvdata->cpu);
@@ -480,17 +457,29 @@
if (ret)
goto err_clk;
- mutex_lock(&drvdata->mutex);
- /* executing __etm_enable on the cpu whose ETM is being enabled
+ get_online_cpus();
+ spin_lock(&drvdata->spinlock);
+
+ /*
+ * Executing __etm_enable on the cpu whose ETM is being enabled
* ensures that register writes occur when cpu is powered.
*/
- smp_call_function_single(drvdata->cpu, __etm_enable, drvdata, 1);
- mutex_unlock(&drvdata->mutex);
+ ret = smp_call_function_single(drvdata->cpu, __etm_enable, drvdata, 1);
+ if (ret)
+ goto err;
+ drvdata->enable = true;
+
+ spin_unlock(&drvdata->spinlock);
+ put_online_cpus();
wake_unlock(&drvdata->wake_lock);
dev_info(drvdata->dev, "ETM tracing enabled\n");
return 0;
+err:
+ spin_unlock(&drvdata->spinlock);
+ put_online_cpus();
+ clk_disable_unprepare(drvdata->clk);
err_clk:
wake_unlock(&drvdata->wake_lock);
return ret;
@@ -501,20 +490,15 @@
struct etm_drvdata *drvdata = info;
ETM_UNLOCK(drvdata);
- etm_save_pwrdwn(drvdata);
- /*
- * Clear power down bit since when this bit is set writes to
- * certain registers might be ignored.
- */
- etm_clr_pwrdwn(drvdata);
etm_set_prog(drvdata);
/* program trace enable to low by using always false event */
etm_writel(drvdata, 0x6F | BIT(14), ETMTEEVR);
- etm_restore_pwrdwn(drvdata);
- /* Vote for ETM power/clock disable */
- etm_clr_pwrup(drvdata);
+ if (!drvdata->pcsave_enable) {
+ etm_set_pwrdwn(drvdata);
+ etm_clr_pwrup(drvdata);
+ }
ETM_LOCK(drvdata);
dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu);
@@ -526,12 +510,18 @@
wake_lock(&drvdata->wake_lock);
- mutex_lock(&drvdata->mutex);
- /* executing __etm_disable on the cpu whose ETM is being disabled
+ get_online_cpus();
+ spin_lock(&drvdata->spinlock);
+
+ /*
+ * Executing __etm_disable on the cpu whose ETM is being disabled
* ensures that register writes occur when cpu is powered.
*/
smp_call_function_single(drvdata->cpu, __etm_disable, drvdata, 1);
- mutex_unlock(&drvdata->mutex);
+ drvdata->enable = false;
+
+ spin_unlock(&drvdata->spinlock);
+ put_online_cpus();
clk_disable_unprepare(drvdata->clk);
@@ -600,7 +590,7 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
if (val) {
drvdata->mode = ETM_MODE_EXCLUDE;
drvdata->ctrl = 0x0;
@@ -644,7 +634,7 @@
drvdata->sync_freq = 0x80;
drvdata->timestamp_event = 0x406F;
}
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(reset, S_IRUGO | S_IWUSR, etm_show_reset, etm_store_reset);
@@ -667,7 +657,7 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->mode = val & ETM_MODE_ALL;
if (drvdata->mode & ETM_MODE_EXCLUDE)
@@ -694,7 +684,7 @@
drvdata->ctrl |= (BIT(14) | BIT(15));
else
drvdata->ctrl &= ~(BIT(14) | BIT(15));
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
@@ -796,12 +786,13 @@
if (val >= drvdata->nr_addr_cmp)
return -EINVAL;
- /* Use mutex to ensure index doesn't change while it gets dereferenced
- * multiple times within a mutex block elsewhere.
+ /*
+ * Use spinlock to ensure index doesn't change while it gets
+ * dereferenced multiple times within a spinlock block elsewhere.
*/
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->addr_idx = val;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(addr_idx, S_IRUGO | S_IWUSR, etm_show_addr_idx,
@@ -814,16 +805,16 @@
unsigned long val;
uint8_t idx;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
idx = drvdata->addr_idx;
if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
val = drvdata->addr_val[idx];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -838,17 +829,17 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
idx = drvdata->addr_idx;
if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
drvdata->addr_val[idx] = val;
drvdata->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(addr_single, S_IRUGO | S_IWUSR, etm_show_addr_single,
@@ -861,23 +852,23 @@
unsigned long val1, val2;
uint8_t idx;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
idx = drvdata->addr_idx;
if (idx % 2 != 0) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
(drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
val1 = drvdata->addr_val[idx];
val2 = drvdata->addr_val[idx + 1];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
}
@@ -895,17 +886,17 @@
if (val1 > val2)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
idx = drvdata->addr_idx;
if (idx % 2 != 0) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
(drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
@@ -914,7 +905,7 @@
drvdata->addr_val[idx + 1] = val2;
drvdata->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
drvdata->enable_ctrl1 |= (1 << (idx/2));
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(addr_range, S_IRUGO | S_IWUSR, etm_show_addr_range,
@@ -927,16 +918,16 @@
unsigned long val;
uint8_t idx;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
idx = drvdata->addr_idx;
if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
val = drvdata->addr_val[idx];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -951,11 +942,11 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
idx = drvdata->addr_idx;
if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
@@ -963,7 +954,7 @@
drvdata->addr_type[idx] = ETM_ADDR_TYPE_START;
drvdata->startstop_ctrl |= (1 << idx);
drvdata->enable_ctrl1 |= BIT(25);
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(addr_start, S_IRUGO | S_IWUSR, etm_show_addr_start,
@@ -976,16 +967,16 @@
unsigned long val;
uint8_t idx;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
idx = drvdata->addr_idx;
if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
val = drvdata->addr_val[idx];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1000,11 +991,11 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
idx = drvdata->addr_idx;
if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return -EPERM;
}
@@ -1012,7 +1003,7 @@
drvdata->addr_type[idx] = ETM_ADDR_TYPE_STOP;
drvdata->startstop_ctrl |= (1 << (idx + 16));
drvdata->enable_ctrl1 |= BIT(25);
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(addr_stop, S_IRUGO | S_IWUSR, etm_show_addr_stop,
@@ -1024,9 +1015,9 @@
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
unsigned long val;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
val = drvdata->addr_acctype[drvdata->addr_idx];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1040,9 +1031,9 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->addr_acctype[drvdata->addr_idx] = val;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(addr_acctype, S_IRUGO | S_IWUSR, etm_show_addr_acctype,
@@ -1069,12 +1060,13 @@
if (val >= drvdata->nr_cntr)
return -EINVAL;
- /* Use mutex to ensure index doesn't change while it gets dereferenced
- * multiple times within a mutex block elsewhere.
+ /*
+ * Use spinlock to ensure index doesn't change while it gets
+ * dereferenced multiple times within a spinlock block elsewhere.
*/
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->cntr_idx = val;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(cntr_idx, S_IRUGO | S_IWUSR, etm_show_cntr_idx,
@@ -1086,9 +1078,9 @@
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
unsigned long val;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
val = drvdata->cntr_rld_val[drvdata->cntr_idx];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1102,9 +1094,9 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->cntr_rld_val[drvdata->cntr_idx] = val;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(cntr_rld_val, S_IRUGO | S_IWUSR, etm_show_cntr_rld_val,
@@ -1116,9 +1108,9 @@
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
unsigned long val;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
val = drvdata->cntr_event[drvdata->cntr_idx];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1132,9 +1124,9 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->cntr_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(cntr_event, S_IRUGO | S_IWUSR, etm_show_cntr_event,
@@ -1146,9 +1138,9 @@
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
unsigned long val;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
val = drvdata->cntr_rld_event[drvdata->cntr_idx];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1162,9 +1154,9 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->cntr_rld_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(cntr_rld_event, S_IRUGO | S_IWUSR, etm_show_cntr_rld_event,
@@ -1176,9 +1168,9 @@
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
unsigned long val;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
val = drvdata->cntr_val[drvdata->cntr_idx];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1192,9 +1184,9 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->cntr_val[drvdata->cntr_idx] = val;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(cntr_val, S_IRUGO | S_IWUSR, etm_show_cntr_val,
@@ -1398,12 +1390,13 @@
if (val >= drvdata->nr_ctxid_cmp)
return -EINVAL;
- /* Use mutex to ensure index doesn't change while it gets dereferenced
- * multiple times within a mutex block elsewhere.
+ /*
+ * Use spinlock to ensure index doesn't change while it gets
+ * dereferenced multiple times within a spinlock block elsewhere.
*/
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->ctxid_idx = val;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(ctxid_idx, S_IRUGO | S_IWUSR, etm_show_ctxid_idx,
@@ -1415,9 +1408,9 @@
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
unsigned long val;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
val = drvdata->ctxid_val[drvdata->ctxid_idx];
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1431,9 +1424,9 @@
if (sscanf(buf, "%lx", &val) != 1)
return -EINVAL;
- mutex_lock(&drvdata->mutex);
+ spin_lock(&drvdata->spinlock);
drvdata->ctxid_val[drvdata->ctxid_idx] = val;
- mutex_unlock(&drvdata->mutex);
+ spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR(ctxid_val, S_IRUGO | S_IWUSR, etm_show_ctxid_val,
@@ -1527,26 +1520,43 @@
static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
{
- int ret;
+ int ret = 0;
ret = clk_prepare_enable(drvdata->clk);
if (ret)
return ret;
- mutex_lock(&drvdata->mutex);
+ get_online_cpus();
+ spin_lock(&drvdata->spinlock);
if (val) {
- smp_call_function_single(drvdata->cpu, etm_enable_pcsave,
- drvdata, 1);
+ if (drvdata->pcsave_enable)
+ goto out;
+
+ ret = smp_call_function_single(drvdata->cpu, etm_enable_pcsave,
+ drvdata, 1);
+ if (ret)
+ goto out;
drvdata->pcsave_enable = true;
+
+ dev_info(drvdata->dev, "PC save enabled\n");
} else {
- smp_call_function_single(drvdata->cpu, etm_disable_pcsave,
- drvdata, 1);
+ if (!drvdata->pcsave_enable)
+ goto out;
+
+ ret = smp_call_function_single(drvdata->cpu, etm_disable_pcsave,
+ drvdata, 1);
+ if (ret)
+ goto out;
drvdata->pcsave_enable = false;
+
+ dev_info(drvdata->dev, "PC save disabled\n");
}
- mutex_unlock(&drvdata->mutex);
+out:
+ spin_unlock(&drvdata->spinlock);
+ put_online_cpus();
clk_disable_unprepare(drvdata->clk);
- return 0;
+ return ret;
}
static ssize_t etm_store_pcsave(struct device *dev,
@@ -1613,15 +1623,42 @@
NULL,
};
-/* Memory mapped writes to clear os lock not supported */
-static void etm_os_unlock(void *unused)
+static int etm_cpu_callback(struct notifier_block *nfb, unsigned long action,
+ void *hcpu)
{
- unsigned long value = 0x0;
+ unsigned int cpu = (unsigned long)hcpu;
- asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
- asm("isb\n\t");
+ switch (action & (~CPU_TASKS_FROZEN)) {
+ case CPU_STARTING:
+ if (etmdrvdata[cpu] && !etmdrvdata[cpu]->os_unlock) {
+ spin_lock(&etmdrvdata[cpu]->spinlock);
+ etm_os_unlock(etmdrvdata[cpu]);
+ etmdrvdata[cpu]->os_unlock = true;
+ spin_unlock(&etmdrvdata[cpu]->spinlock);
+ }
+
+ if (etmdrvdata[cpu] && etmdrvdata[cpu]->enable) {
+ spin_lock(&etmdrvdata[cpu]->spinlock);
+ __etm_enable(etmdrvdata[cpu]);
+ spin_unlock(&etmdrvdata[cpu]->spinlock);
+ }
+ break;
+
+ case CPU_DYING:
+ if (etmdrvdata[cpu] && etmdrvdata[cpu]->enable) {
+ spin_lock(&etmdrvdata[cpu]->spinlock);
+ __etm_disable(etmdrvdata[cpu]);
+ spin_unlock(&etmdrvdata[cpu]->spinlock);
+ }
+ break;
+ }
+ return NOTIFY_OK;
}
+static struct notifier_block etm_cpu_notifier = {
+ .notifier_call = etm_cpu_callback,
+};
+
static bool __devinit etm_arch_supported(uint8_t arch)
{
switch (arch) {
@@ -1633,15 +1670,6 @@
return true;
}
-static void __devinit etm_prepare_arch(struct etm_drvdata *drvdata)
-{
- /* Unlock OS lock first to allow memory mapped reads and writes. This
- * is required for Krait pass1
- * */
- etm_os_unlock(NULL);
- smp_call_function(etm_os_unlock, NULL, 1);
-}
-
static void __devinit etm_init_arch_data(void *info)
{
uint32_t etmidr;
@@ -1677,19 +1705,18 @@
drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
etm_set_pwrdwn(drvdata);
- /* Vote for ETM power/clock disable */
etm_clr_pwrup(drvdata);
ETM_LOCK(drvdata);
}
static void __devinit etm_copy_arch_data(struct etm_drvdata *drvdata)
{
- drvdata->arch = etm0drvdata->arch;
- drvdata->nr_addr_cmp = etm0drvdata->nr_addr_cmp;
- drvdata->nr_cntr = etm0drvdata->nr_cntr;
- drvdata->nr_ext_inp = etm0drvdata->nr_ext_inp;
- drvdata->nr_ext_out = etm0drvdata->nr_ext_out;
- drvdata->nr_ctxid_cmp = etm0drvdata->nr_ctxid_cmp;
+ drvdata->arch = etmdrvdata[0]->arch;
+ drvdata->nr_addr_cmp = etmdrvdata[0]->nr_addr_cmp;
+ drvdata->nr_cntr = etmdrvdata[0]->nr_cntr;
+ drvdata->nr_ext_inp = etmdrvdata[0]->nr_ext_inp;
+ drvdata->nr_ext_out = etmdrvdata[0]->nr_ext_out;
+ drvdata->nr_ctxid_cmp = etmdrvdata[0]->nr_ctxid_cmp;
}
static void __devinit etm_init_default_data(struct etm_drvdata *drvdata)
@@ -1774,7 +1801,7 @@
if (!drvdata->base)
return -ENOMEM;
- mutex_init(&drvdata->mutex);
+ spin_lock_init(&drvdata->spinlock);
wake_lock_init(&drvdata->wake_lock, WAKE_LOCK_SUSPEND, "coresight-etm");
drvdata->clk = devm_clk_get(dev, "core_clk");
@@ -1787,23 +1814,32 @@
if (ret)
goto err0;
- drvdata->cpu = count++;
-
ret = clk_prepare_enable(drvdata->clk);
if (ret)
goto err0;
- /* Use CPU0 to populate read-only configuration data for ETM0. For other
- * ETMs copy it over from ETM0.
+ drvdata->cpu = count++;
+
+ get_online_cpus();
+ etmdrvdata[drvdata->cpu] = drvdata;
+
+ if (!smp_call_function_single(drvdata->cpu, etm_os_unlock, NULL, 1))
+ drvdata->os_unlock = true;
+ /*
+ * Use CPU0 to populate read-only configuration data for ETM0. For
+ * other ETMs copy it over from ETM0.
*/
if (drvdata->cpu == 0) {
- etm_prepare_arch(drvdata);
- smp_call_function_single(drvdata->cpu, etm_init_arch_data,
- drvdata, 1);
- etm0drvdata = drvdata;
+ register_hotcpu_notifier(&etm_cpu_notifier);
+ if (smp_call_function_single(drvdata->cpu, etm_init_arch_data,
+ drvdata, 1))
+ dev_err(dev, "ETM arch init failed\n");
} else {
etm_copy_arch_data(drvdata);
}
+
+ put_online_cpus();
+
if (etm_arch_supported(drvdata->arch) == false) {
ret = -EINVAL;
goto err1;
@@ -1821,7 +1857,7 @@
ret = msm_dump_table_register(&dump);
if (ret) {
devm_kfree(dev, baddr);
- dev_err(dev, "ETM REG dump setup failed\n");
+ dev_err(dev, "ETM REG dump setup failed/unsupported\n");
}
} else {
dev_err(dev, "ETM REG dump space allocation failed\n");
@@ -1830,7 +1866,7 @@
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
if (!desc) {
ret = -ENOMEM;
- goto err0;
+ goto err2;
}
desc->type = CORESIGHT_DEV_TYPE_SOURCE;
desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC;
@@ -1842,7 +1878,7 @@
drvdata->csdev = coresight_register(desc);
if (IS_ERR(drvdata->csdev)) {
ret = PTR_ERR(drvdata->csdev);
- goto err0;
+ goto err2;
}
if (pdev->dev.of_node)
@@ -1864,11 +1900,17 @@
__etm_store_pcsave(drvdata, true);
return 0;
+err2:
+ if (drvdata->cpu == 0)
+ unregister_hotcpu_notifier(&etm_cpu_notifier);
+ wake_lock_destroy(&drvdata->wake_lock);
+ return ret;
err1:
+ if (drvdata->cpu == 0)
+ unregister_hotcpu_notifier(&etm_cpu_notifier);
clk_disable_unprepare(drvdata->clk);
err0:
wake_lock_destroy(&drvdata->wake_lock);
- mutex_destroy(&drvdata->mutex);
return ret;
}
@@ -1878,8 +1920,9 @@
device_remove_file(&drvdata->csdev->dev, &dev_attr_pcsave);
coresight_unregister(drvdata->csdev);
+ if (drvdata->cpu == 0)
+ unregister_hotcpu_notifier(&etm_cpu_notifier);
wake_lock_destroy(&drvdata->wake_lock);
- mutex_destroy(&drvdata->mutex);
return 0;
}
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 785ba6c..4b03cfd 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -115,7 +115,12 @@
static struct workqueue_struct *input_wq;
-static DEFINE_PER_CPU(struct work_struct, dbs_refresh_work);
+struct dbs_work_struct {
+ struct work_struct work;
+ unsigned int cpu;
+};
+
+static DEFINE_PER_CPU(struct dbs_work_struct, dbs_refresh_work);
static struct dbs_tuners {
unsigned int sampling_rate;
@@ -831,11 +836,15 @@
return 0;
}
-static void dbs_refresh_callback(struct work_struct *unused)
+static void dbs_refresh_callback(struct work_struct *work)
{
struct cpufreq_policy *policy;
struct cpu_dbs_info_s *this_dbs_info;
- unsigned int cpu = smp_processor_id();
+ struct dbs_work_struct *dbs_work;
+ unsigned int cpu;
+
+ dbs_work = container_of(work, struct dbs_work_struct, work);
+ cpu = dbs_work->cpu;
get_online_cpus();
@@ -877,9 +886,8 @@
return;
}
- for_each_online_cpu(i) {
- queue_work_on(i, input_wq, &per_cpu(dbs_refresh_work, i));
- }
+ for_each_online_cpu(i)
+ queue_work_on(i, input_wq, &per_cpu(dbs_refresh_work, i).work);
}
static int dbs_input_connect(struct input_handler *handler,
@@ -1072,8 +1080,12 @@
for_each_possible_cpu(i) {
struct cpu_dbs_info_s *this_dbs_info =
&per_cpu(od_cpu_dbs_info, i);
+ struct dbs_work_struct *dbs_work =
+ &per_cpu(dbs_refresh_work, i);
+
mutex_init(&this_dbs_info->timer_mutex);
- INIT_WORK(&per_cpu(dbs_refresh_work, i), dbs_refresh_callback);
+ INIT_WORK(&dbs_work->work, dbs_refresh_callback);
+ dbs_work->cpu = i;
}
return cpufreq_register_governor(&cpufreq_gov_ondemand);
diff --git a/drivers/gpu/msm/kgsl_drm.c b/drivers/gpu/msm/kgsl_drm.c
index 2003098..119e25d 100644
--- a/drivers/gpu/msm/kgsl_drm.c
+++ b/drivers/gpu/msm/kgsl_drm.c
@@ -17,6 +17,7 @@
#include "drmP.h"
#include "drm.h"
#include <linux/android_pmem.h>
+#include <linux/msm_ion.h>
#include "kgsl.h"
#include "kgsl_device.h"
@@ -106,6 +107,7 @@
uint32_t type;
struct kgsl_memdesc memdesc;
struct kgsl_pagetable *pagetable;
+ struct ion_handle *ion_handle;
uint64_t mmap_offset;
int bufcount;
int flags;
@@ -129,6 +131,8 @@
struct list_head wait_list;
};
+static struct ion_client *kgsl_drm_ion_phys_client;
+
static int kgsl_drm_inited = DRM_KGSL_NOT_INITED;
/* This is a global list of all the memory currently mapped in the MMU */
@@ -243,15 +247,50 @@
if (TYPE_IS_PMEM(priv->type)) {
if (priv->type == DRM_KGSL_GEM_TYPE_EBI ||
priv->type & DRM_KGSL_GEM_PMEM_EBI) {
- result = kgsl_sharedmem_ebimem_user(
- &priv->memdesc,
- priv->pagetable,
- obj->size * priv->bufcount);
- if (result) {
- DRM_ERROR(
- "Unable to allocate PMEM memory\n");
- return result;
- }
+ priv->ion_handle = ion_alloc(kgsl_drm_ion_phys_client,
+ obj->size * priv->bufcount, PAGE_SIZE,
+ ION_HEAP(ION_SF_HEAP_ID), 0);
+ if (IS_ERR_OR_NULL(priv->ion_handle)) {
+ DRM_ERROR(
+ "Unable to allocate ION Phys memory handle\n");
+ return -ENOMEM;
+ }
+
+ priv->memdesc.pagetable = priv->pagetable;
+
+ result = ion_phys(kgsl_drm_ion_phys_client,
+ priv->ion_handle, (ion_phys_addr_t *)
+ &priv->memdesc.physaddr, &priv->memdesc.size);
+ if (result) {
+ DRM_ERROR(
+ "Unable to get ION Physical memory address\n");
+ ion_free(kgsl_drm_ion_phys_client,
+ priv->ion_handle);
+ priv->ion_handle = NULL;
+ return result;
+ }
+
+ result = memdesc_sg_phys(&priv->memdesc,
+ priv->memdesc.physaddr, priv->memdesc.size);
+ if (result) {
+ DRM_ERROR(
+ "Unable to get sg list\n");
+ ion_free(kgsl_drm_ion_phys_client,
+ priv->ion_handle);
+ priv->ion_handle = NULL;
+ return result;
+ }
+
+ result = kgsl_mmu_map(priv->pagetable, &priv->memdesc,
+ GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
+ if (result) {
+ DRM_ERROR(
+ "Unable to map GPU\n");
+ ion_free(kgsl_drm_ion_phys_client,
+ priv->ion_handle);
+ priv->ion_handle = NULL;
+ return result;
+ }
}
else
return -EINVAL;
@@ -296,7 +335,16 @@
kgsl_gem_mem_flush(&priv->memdesc, priv->type,
DRM_KGSL_GEM_CACHE_OP_FROM_DEV);
- kgsl_sharedmem_free(&priv->memdesc);
+ if (priv->memdesc.gpuaddr)
+ kgsl_mmu_unmap(priv->memdesc.pagetable, &priv->memdesc);
+
+ kgsl_sg_free(priv->memdesc.sg, priv->memdesc.sglen);
+
+ if (priv->ion_handle)
+ ion_free(kgsl_drm_ion_phys_client, priv->ion_handle);
+ priv->ion_handle = NULL;
+
+ memset(&priv->memdesc, 0, sizeof(priv->memdesc));
kgsl_mmu_putpagetable(priv->pagetable);
priv->pagetable = NULL;
@@ -1447,6 +1495,16 @@
DRM_MASTER),
};
+static const struct file_operations kgsl_drm_driver_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = msm_drm_gem_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+};
+
static struct drm_driver driver = {
.driver_features = DRIVER_GEM,
.load = kgsl_drm_load,
@@ -1458,17 +1516,7 @@
.gem_init_object = kgsl_gem_init_object,
.gem_free_object = kgsl_gem_free_object,
.ioctls = kgsl_drm_ioctls,
-
- .fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .unlocked_ioctl = drm_ioctl,
- .mmap = msm_drm_gem_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- },
-
+ .fops = &kgsl_drm_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = DRIVER_DATE,
@@ -1497,6 +1545,14 @@
gem_buf_fence[i].fence_id = ENTRY_EMPTY;
}
+ /* Create ION Client */
+ kgsl_drm_ion_phys_client = msm_ion_client_create(
+ ION_HEAP_CARVEOUT_MASK, ION_SF_HEAP_NAME);
+ if (!kgsl_drm_ion_phys_client) {
+ DRM_ERROR("Unable to create ION client\n");
+ return -ENOMEM;
+ }
+
return drm_platform_init(&driver, dev);
}
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index b476e39..22063d4 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -167,23 +167,7 @@
static u32 get_frame_size_nv12(int plane,
u32 height, u32 width)
{
- int size;
- int luma_h, luma_w, luma_stride, luma_scanl, luma_size;
- int chroma_h, chroma_w, chroma_stride, chroma_scanl, chroma_size;
-
- luma_w = width;
- luma_h = height;
-
- chroma_w = luma_w;
- chroma_h = luma_h/2;
- NV12_IL_CALC_Y_STRIDE(luma_stride, luma_w, 32);
- NV12_IL_CALC_Y_BUFHEIGHT(luma_scanl, luma_h, 32);
- NV12_IL_CALC_UV_STRIDE(chroma_stride, chroma_w, 32);
- NV12_IL_CALC_UV_BUFHEIGHT(chroma_scanl, luma_h, 32);
- NV12_IL_CALC_BUF_SIZE(size, luma_size, luma_stride,
- luma_scanl, chroma_size, chroma_stride, chroma_scanl, 32);
- size = ALIGN(size, SZ_4K);
- return size;
+ return VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
}
static u32 get_frame_size_compressed(int plane,
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 3f892b1..fdadb36 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -461,23 +461,7 @@
static u32 get_frame_size_nv12(int plane, u32 height, u32 width)
{
- int size;
- int luma_h, luma_w, luma_stride, luma_scanl, luma_size;
- int chroma_h, chroma_w, chroma_stride, chroma_scanl, chroma_size;
-
- luma_w = width;
- luma_h = height;
-
- chroma_w = luma_w;
- chroma_h = luma_h/2;
- NV12_IL_CALC_Y_STRIDE(luma_stride, luma_w, 32);
- NV12_IL_CALC_Y_BUFHEIGHT(luma_scanl, luma_h, 32);
- NV12_IL_CALC_UV_STRIDE(chroma_stride, chroma_w, 32);
- NV12_IL_CALC_UV_BUFHEIGHT(chroma_scanl, luma_h, 32);
- NV12_IL_CALC_BUF_SIZE(size, luma_size, luma_stride,
- luma_scanl, chroma_size, chroma_stride, chroma_scanl, 32);
- size = ALIGN(size, SZ_4K);
- return size;
+ return VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
}
static u32 get_frame_size_nv21(int plane, u32 height, u32 width)
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 46dab5c..16f7e2c 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -388,7 +388,9 @@
struct msm_vidc_cb_cmd_done *response = data;
struct msm_vidc_inst *inst;
struct v4l2_event dqevent;
+ struct v4l2_control control = {0};
struct msm_vidc_cb_event *event_notify;
+ int rc = 0;
if (response) {
inst = (struct msm_vidc_inst *)response->session_id;
dqevent.id = 0;
@@ -396,7 +398,16 @@
switch (event_notify->hal_event_type) {
case HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES:
dqevent.type =
- V4L2_EVENT_SEQ_CHANGED_SUFFICIENT;
+ V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
+ control.id =
+ V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
+ rc = v4l2_g_ctrl(&inst->ctrl_handler, &control);
+ if (rc)
+ dprintk(VIDC_WARN,
+ "Failed to get Smooth streamng flag\n");
+ if (!rc && control.value == true)
+ dqevent.type =
+ V4L2_EVENT_SEQ_CHANGED_SUFFICIENT;
break;
case HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES:
dqevent.type =
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index f288cc6..8e1a99e 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -30,6 +30,7 @@
#include <media/v4l2-ctrls.h>
#include <media/videobuf2-core.h>
#include <media/msm_vidc.h>
+#include <media/msm_media_info.h>
#include "vidc_hal_api.h"
@@ -49,33 +50,7 @@
#define MAX_NAME_LENGTH 64
-#define NV12_IL_CALC_Y_STRIDE(stride, frame_width, stride_multiple) \
- { stride = (frame_width + stride_multiple - 1) & \
- (0xffffffff - (stride_multiple - 1)); }
-
-#define NV12_IL_CALC_Y_BUFHEIGHT(buf_height, frame_height,\
- min_buf_height_multiple) \
- { buf_height = (frame_height + min_buf_height_multiple - 1) & \
- (0xffffffff - (min_buf_height_multiple - 1)); }
-
-#define NV12_IL_CALC_UV_STRIDE(stride, frame_width, stride_multiple) \
- { stride = ((((frame_width + 1) >> 1) + stride_multiple - 1) & \
- (0xffffffff - (stride_multiple - 1))) << 1; }
-
-#define NV12_IL_CALC_UV_BUFHEIGHT(buf_height, frame_height,\
- min_buf_height_multiple) \
- { buf_height = ((((frame_height + 1) >> 1) + \
- min_buf_height_multiple - 1) & (0xffffffff - \
- (min_buf_height_multiple - 1))); }
-
-#define NV12_IL_CALC_BUF_SIZE(buf_size, y_buf_size, y_stride, \
- y_buf_height, uv_buf_size, uv_stride, uv_buf_height, uv_alignment) \
- { y_buf_size = (y_stride * y_buf_height); \
- uv_buf_size = (uv_stride * uv_buf_height) + uv_alignment; \
- buf_size = y_buf_size + uv_buf_size; }
-
#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
-
enum vidc_ports {
OUTPUT_PORT,
CAPTURE_PORT,
diff --git a/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c b/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
index 7eb0ae1..e15edbe 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
+++ b/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
@@ -160,7 +160,6 @@
switch (pkt->event_id) {
case HFI_EVENT_SYS_ERROR:
dprintk(VIDC_INFO, "HFI_EVENT_SYS_ERROR");
- hal_process_sys_watchdog_timeout(device);
break;
case HFI_EVENT_SESSION_ERROR:
dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR");
diff --git a/drivers/media/video/msm_wfd/wfd-util.c b/drivers/media/video/msm_wfd/wfd-util.c
index 233668b0..5c00e5c 100644
--- a/drivers/media/video/msm_wfd/wfd-util.c
+++ b/drivers/media/video/msm_wfd/wfd-util.c
@@ -159,10 +159,10 @@
}
case WFD_STAT_EVENT_MDP_QUEUE:
stats->mdp_buf_count++;
- stats->mdp_updates++;
break;
case WFD_STAT_EVENT_MDP_DEQUEUE:
stats->mdp_buf_count--;
+ stats->mdp_updates++;
break;
case WFD_STAT_EVENT_ENC_QUEUE: {
struct wfd_stats_encode_sample *sample = NULL;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 49bbe09..95e7753 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2215,7 +2215,9 @@
}
if ((mrq->cmd->opcode == MMC_WRITE_BLOCK) ||
- (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK))
+ (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) ||
+ ((mrq->cmd->opcode == SD_IO_RW_EXTENDED) &&
+ is_data_pend_for_cmd53(host)))
host->curr.use_wr_data_pend = true;
}
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index af5498e..9fa2027 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -446,6 +446,7 @@
#define MSMSDCC_AUTO_CMD19 (1 << 9)
#define MSMSDCC_AUTO_CMD21 (1 << 10)
#define MSMSDCC_SW_RST_CFG_BROKEN (1 << 11)
+#define MSMSDCC_DATA_PEND_FOR_CMD53 (1 << 12)
#define set_hw_caps(h, val) ((h)->hw_caps |= val)
#define is_sps_mode(h) ((h)->hw_caps & MSMSDCC_SPS_BAM_SUP)
@@ -461,6 +462,7 @@
#define is_auto_cmd21(h) ((h)->hw_caps & MSMSDCC_AUTO_CMD21)
#define is_sw_reset_save_config_broken(h) \
((h)->hw_caps & MSMSDCC_SW_RST_CFG_BROKEN)
+#define is_data_pend_for_cmd53(h) ((h)->hw_caps & MSMSDCC_DATA_PEND_FOR_CMD53)
/* Set controller capabilities based on version */
static inline void set_default_hw_caps(struct msmsdcc_host *host)
@@ -493,7 +495,8 @@
if (step >= 0x2b) /* SDCC v4 2.1.0 and greater */
host->hw_caps |= MSMSDCC_SW_RST | MSMSDCC_SW_RST_CFG |
- MSMSDCC_AUTO_CMD21;
+ MSMSDCC_AUTO_CMD21 |
+ MSMSDCC_DATA_PEND_FOR_CMD53;
if (step == 0x2b)
host->hw_caps |= MSMSDCC_SW_RST_CFG_BROKEN;
diff --git a/drivers/power/bq28400_battery.c b/drivers/power/bq28400_battery.c
index 47fced1..7b82b32 100644
--- a/drivers/power/bq28400_battery.c
+++ b/drivers/power/bq28400_battery.c
@@ -509,13 +509,15 @@
return POWER_SUPPLY_STATUS_FULL;
}
+ /* Enable charging when battery is not full */
+ bq28400_enable_charging(bq28400_dev, true);
+
/*
* Positive current indicates charging
* Negative current indicates discharging.
* Charging is stopped at termination-current.
*/
if (current_ma < 0) {
- bq28400_enable_charging(bq28400_dev, true);
pr_debug("Discharging.\n");
status = POWER_SUPPLY_STATUS_DISCHARGING;
} else if (current_ma > BQ_TERMINATION_CURRENT_MA) {
diff --git a/drivers/power/smb350_charger.c b/drivers/power/smb350_charger.c
index 93e208c..319caba 100644
--- a/drivers/power/smb350_charger.c
+++ b/drivers/power/smb350_charger.c
@@ -753,13 +753,22 @@
i2c_set_clientdata(client, dev);
- pr_debug("set charge-enable + not suspend.\n");
- gpio_set_value_cansleep(dev->chg_en_n_gpio, 1); /* Disable */
+ /* Disable battery charging by default on power up.
+ * Battery charging is enabled by BMS or Battery-Gauge
+ * by using the set_property callback.
+ */
+ smb350_enable_charging(dev, false);
msleep(100);
gpio_set_value_cansleep(dev->chg_susp_n_gpio, 1); /* Normal */
msleep(100); /* Allow the device to exist shutdown */
- smb350_read_reg(client, I2C_SLAVE_ADDR_REG);
+ /* I2C transaction allowed only after device exit suspend */
+ ret = smb350_read_reg(client, I2C_SLAVE_ADDR_REG);
+ if ((ret>>1) != client->addr) {
+ pr_err("No device.\n");
+ ret = -ENODEV;
+ goto err_no_dev;
+ }
ret = smb350_set_volatile_params(dev);
if (ret)
@@ -784,14 +793,13 @@
goto err_irq;
}
- smb350_enable_charging(dev, true);
-
return 0;
err_irq:
err_debugfs:
if (dev->dent)
debugfs_remove_recursive(dev->dent);
+err_no_dev:
err_set_params:
gpio_free(dev->chg_en_n_gpio);
err_en_gpio:
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index e73caf1..91f4964 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -62,6 +62,22 @@
printk(x); \
} while (0)
+static int test_task_flag(struct task_struct *p, int flag)
+{
+ struct task_struct *t = p;
+
+ do {
+ task_lock(t);
+ if (test_tsk_thread_flag(t, flag)) {
+ task_unlock(t);
+ return 1;
+ }
+ task_unlock(t);
+ } while_each_thread(p, t);
+
+ return 0;
+}
+
static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
{
struct task_struct *tsk;
@@ -111,16 +127,17 @@
if (tsk->flags & PF_KTHREAD)
continue;
+ if (time_before_eq(jiffies, lowmem_deathpending_timeout)) {
+ if (test_task_flag(tsk, TIF_MEMDIE)) {
+ rcu_read_unlock();
+ return 0;
+ }
+ }
+
p = find_lock_task_mm(tsk);
if (!p)
continue;
- if (test_tsk_thread_flag(p, TIF_MEMDIE) &&
- time_before_eq(jiffies, lowmem_deathpending_timeout)) {
- task_unlock(p);
- rcu_read_unlock();
- return 0;
- }
oom_score_adj = p->signal->oom_score_adj;
if (oom_score_adj < min_score_adj) {
task_unlock(p);
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 1994b1b..527b02f 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -3279,7 +3279,9 @@
ret = wait_for_completion_interruptible_timeout(
&mfd->msmfb_no_update_notify, 4*HZ);
}
- return (ret > 0) ? 0 : -1;
+ if (ret == 0)
+ ret = -ETIMEDOUT;
+ return (ret > 0) ? 0 : ret;
}
static int msmfb_handle_pp_ioctl(struct msm_fb_data_type *mfd,
diff --git a/include/media/Kbuild b/include/media/Kbuild
index 4b6e6a9..70f6334 100644
--- a/include/media/Kbuild
+++ b/include/media/Kbuild
@@ -7,3 +7,4 @@
header-y += msm_gestures.h
header-y += msm_mercury.h
header-y += msm_jpeg.h
+header-y += msm_media_info.h
diff --git a/include/media/msm_media_info.h b/include/media/msm_media_info.h
new file mode 100644
index 0000000..3098bfe
--- /dev/null
+++ b/include/media/msm_media_info.h
@@ -0,0 +1,113 @@
+#ifndef __MEDIA_INFO_H__
+#define __MEDIA_INFO_H__
+
+#ifndef ALIGN
+#define ALIGN(__sz, __align) (((__sz) + (__align-1)) & (~(__align-1)))
+#endif
+
+enum color_fmts {
+ COLOR_FMT_NV12,
+};
+
+static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width)
+{
+ unsigned int alignment, stride = 0;
+ if (!width)
+ goto invalid_input;
+
+ switch (color_fmt) {
+ case COLOR_FMT_NV12:
+ alignment = 32;
+ stride = ALIGN(width, alignment);
+ break;
+ default:
+ break;
+ }
+invalid_input:
+ return stride;
+}
+
+static inline unsigned int VENUS_UV_STRIDE(int color_fmt, int width)
+{
+ unsigned int alignment, stride = 0;
+ if (!width)
+ goto invalid_input;
+
+ switch (color_fmt) {
+ case COLOR_FMT_NV12:
+ alignment = 32;
+ stride = ALIGN(((width + 1) >> 1), alignment) << 1;
+ break;
+ default:
+ break;
+ }
+invalid_input:
+ return stride;
+}
+
+static inline unsigned int VENUS_Y_SCANLINES(int color_fmt, int height)
+{
+ unsigned int alignment, sclines = 0;
+ if (!height)
+ goto invalid_input;
+
+ switch (color_fmt) {
+ case COLOR_FMT_NV12:
+ alignment = 32;
+ sclines = ALIGN(height, alignment);
+ break;
+ default:
+ break;
+ }
+invalid_input:
+ return sclines;
+}
+
+static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height)
+{
+ unsigned int alignment, sclines = 0;
+ if (!height)
+ goto invalid_input;
+
+ switch (color_fmt) {
+ case COLOR_FMT_NV12:
+ alignment = 32;
+ sclines = ALIGN(((height + 1) >> 1), alignment);
+ break;
+ default:
+ break;
+ }
+invalid_input:
+ return sclines;
+}
+
+static inline unsigned int VENUS_BUFFER_SIZE(
+ int color_fmt, int width, int height)
+{
+ unsigned int uv_alignment;
+ unsigned int size = 0;
+ unsigned int y_plane, uv_plane, y_stride,
+ uv_stride, y_sclines, uv_sclines;
+ if (!width || !height)
+ goto invalid_input;
+
+ y_stride = VENUS_Y_STRIDE(color_fmt, width);
+ uv_stride = VENUS_UV_STRIDE(color_fmt, width);
+ y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
+ uv_sclines = VENUS_UV_SCANLINES(color_fmt, height);
+ switch (color_fmt) {
+ case COLOR_FMT_NV12:
+ uv_alignment = 32;
+ y_plane = y_stride * y_sclines;
+ uv_plane = uv_stride * uv_sclines + uv_alignment;
+ size = y_plane + uv_plane;
+ size = ALIGN(size, 4096);
+ break;
+ default:
+ break;
+ }
+invalid_input:
+ return size;
+}
+
+#endif
diff --git a/sound/soc/codecs/wcd9304.c b/sound/soc/codecs/wcd9304.c
index 5dcfefd..412090f 100644
--- a/sound/soc/codecs/wcd9304.c
+++ b/sound/soc/codecs/wcd9304.c
@@ -1238,9 +1238,9 @@
snd_soc_update_bits(codec, lineout_gain_reg, 0x10, 0x10);
break;
case SND_SOC_DAPM_POST_PMU:
- pr_debug("%s: sleeping 16 ms after %s PA turn on\n",
+ pr_debug("%s: sleeping 32 ms after %s PA turn on\n",
__func__, w->name);
- usleep_range(16000, 16000);
+ usleep_range(32000, 32000);
break;
case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec, lineout_gain_reg, 0x10, 0x00);
@@ -2056,6 +2056,24 @@
return 0;
}
+static int sitar_ear_pa_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ pr_debug("%s: Sleeping 20ms after enabling EAR PA\n",
+ __func__);
+ msleep(20);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pr_debug("%s: Sleeping 20ms after disabling EAR PA\n",
+ __func__);
+ msleep(20);
+ break;
+ }
+ return 0;
+}
+
static const struct snd_soc_dapm_widget sitar_dapm_i2s_widgets[] = {
SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", SITAR_A_CDC_CLK_RX_I2S_CTL,
4, 0, NULL, 0),
@@ -2067,7 +2085,9 @@
/*RX stuff */
SND_SOC_DAPM_OUTPUT("EAR"),
- SND_SOC_DAPM_PGA("EAR PA", SITAR_A_RX_EAR_EN, 4, 0, NULL, 0),
+ SND_SOC_DAPM_PGA_E("EAR PA", SITAR_A_RX_EAR_EN, 4, 0, NULL, 0,
+ sitar_ear_pa_event, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER("DAC1", SITAR_A_RX_EAR_EN, 6, 0, dac1_switch,
ARRAY_SIZE(dac1_switch)),
SND_SOC_DAPM_SUPPLY("EAR DRIVER", SITAR_A_RX_EAR_EN, 3, 0, NULL, 0),
@@ -5137,6 +5157,8 @@
SITAR_REG_VAL(SITAR_A_RX_EAR_GAIN, 0x02),
SITAR_REG_VAL(SITAR_A_RX_EAR_VCM, 0x03),
+ SITAR_REG_VAL(SITAR_A_RX_LINE_BIAS_PA, 0xA7),
+
SITAR_REG_VAL(SITAR_A_CDC_RX1_B5_CTL, 0x78),
SITAR_REG_VAL(SITAR_A_CDC_RX2_B5_CTL, 0x78),
SITAR_REG_VAL(SITAR_A_CDC_RX3_B5_CTL, 0x78),
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index 08cd06c..42699c9 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -183,9 +183,9 @@
pm8xxx_spk_enable(MSM8930_SPK_ON);
}
- pr_debug("%s: slepping 4 ms after turning on external "
+ pr_debug("%s: sleeping 10 ms after turning on external "
" Left Speaker Ampl\n", __func__);
- usleep_range(4000, 4000);
+ usleep_range(10000, 10000);
}
} else {
@@ -218,9 +218,9 @@
pm8xxx_spk_enable(MSM8930_SPK_OFF);
msm8930_ext_spk_pamp = 0;
- pr_debug("%s: slepping 4 ms after turning on external "
+ pr_debug("%s: slepping 10 ms after turning on external "
" Left Speaker Ampl\n", __func__);
- usleep_range(4000, 4000);
+ usleep_range(10000, 10000);
} else {