Merge "msm: camera: Make memory allocation atomic in vfe irq handler" into msm-3.0
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index befa5bb..d53e471 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1595,6 +1595,7 @@
static void ul_wakeup(void)
{
int ret;
+ int do_vote_dfab = 0;
mutex_lock(&wakeup_lock);
if (bam_is_connected) { /* bam got connected before lock grabbed */
@@ -1621,16 +1622,19 @@
* don't grab the wakelock the first time because it is
* already grabbed when a2 powers on
*/
- if (likely(a2_pc_disabled_wakelock_skipped))
+ if (likely(a2_pc_disabled_wakelock_skipped)) {
grab_wakelock();
- else
+ do_vote_dfab = 1; /* vote must occur after wait */
+ } else {
a2_pc_disabled_wakelock_skipped = 1;
+ }
if (wait_for_dfab) {
ret = wait_for_completion_timeout(
&dfab_unvote_completion, HZ);
BUG_ON(ret == 0);
}
- vote_dfab();
+ if (likely(do_vote_dfab))
+ vote_dfab();
schedule_delayed_work(&ul_timeout_work,
msecs_to_jiffies(UL_TIMEOUT_DELAY));
bam_is_connected = 1;
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index df041f0..be539d0 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1260,7 +1260,6 @@
0,
};
-#ifndef CONFIG_MSM_VCAP
#define MXT_TS_GPIO_IRQ 6
#define MXT_TS_PWR_EN_GPIO PM8921_GPIO_PM_TO_SYS(23)
#define MXT_TS_RESET_GPIO 33
@@ -1312,7 +1311,6 @@
.irq = MSM_GPIO_TO_INT(MXT_TS_GPIO_IRQ),
},
};
-#endif
#define CYTTSP_TS_GPIO_IRQ 6
#define CYTTSP_TS_GPIO_SLEEP 33
@@ -2055,13 +2053,14 @@
},
};
-static struct platform_device *common_devices[] __initdata = {
- &apq8064_device_dmov,
-#ifndef CONFIG_MSM_VCAP
+static struct platform_device *common_not_mpq_devices[] __initdata = {
&apq8064_device_qup_i2c_gsbi1,
&apq8064_device_qup_i2c_gsbi3,
&apq8064_device_qup_i2c_gsbi4,
-#endif
+};
+
+static struct platform_device *common_devices[] __initdata = {
+ &apq8064_device_dmov,
&apq8064_device_qup_spi_gsbi5,
&apq8064_device_ext_5v_vreg,
&apq8064_device_ext_mpp8_vreg,
@@ -2603,14 +2602,12 @@
smb349_charger_i2c_info,
ARRAY_SIZE(smb349_charger_i2c_info)
},
-#ifndef CONFIG_MSM_VCAP
{
I2C_SURF | I2C_LIQUID,
APQ_8064_GSBI3_QUP_I2C_BUS_ID,
mxt_device_info,
ARRAY_SIZE(mxt_device_info),
},
-#endif
{
I2C_FFA,
APQ_8064_GSBI3_QUP_I2C_BUS_ID,
@@ -2813,6 +2810,10 @@
apq8064_ehci_host_init();
apq8064_init_buses();
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+ if (!(machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
+ machine_is_mpq8064_dtv()))
+ platform_add_devices(common_not_mpq_devices,
+ ARRAY_SIZE(common_not_mpq_devices));
enable_ddr3_regulator();
if (machine_is_apq8064_mtp()) {
apq8064_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
diff --git a/arch/arm/mach-msm/board-8960-gpiomux.c b/arch/arm/mach-msm/board-8960-gpiomux.c
index 8b5c693..978eb09 100644
--- a/arch/arm/mach-msm/board-8960-gpiomux.c
+++ b/arch/arm/mach-msm/board-8960-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -597,6 +597,84 @@
};
#endif
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+static struct gpiomux_setting sdcc4_clk_actv_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting sdcc4_cmd_data_0_3_actv_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting sdcc4_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting sdcc4_data_1_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct msm_gpiomux_config msm8960_sdcc4_configs[] __initdata = {
+ {
+ /* SDC4_DATA_3 */
+ .gpio = 83,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc4_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc4_suspend_cfg,
+ },
+ },
+ {
+ /* SDC4_DATA_2 */
+ .gpio = 84,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc4_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc4_suspend_cfg,
+ },
+ },
+ {
+ /* SDC4_DATA_1 */
+ .gpio = 85,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc4_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc4_data_1_suspend_cfg,
+ },
+ },
+ {
+ /* SDC4_DATA_0 */
+ .gpio = 86,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc4_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc4_suspend_cfg,
+ },
+ },
+ {
+ /* SDC4_CMD */
+ .gpio = 87,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc4_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc4_suspend_cfg,
+ },
+ },
+ {
+ /* SDC4_CLK */
+ .gpio = 88,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc4_clk_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc4_suspend_cfg,
+ },
+ },
+};
+#endif
+
+
static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
{
.gpio = 47,
@@ -727,6 +805,83 @@
};
#endif
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+static struct gpiomux_setting sdcc2_clk_actv_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting sdcc2_cmd_data_0_3_actv_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting sdcc2_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting sdcc2_data_1_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct msm_gpiomux_config msm8960_sdcc2_configs[] __initdata = {
+ {
+ /* DATA_3 */
+ .gpio = 92,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc2_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc2_suspend_cfg,
+ },
+ },
+ {
+ /* DATA_2 */
+ .gpio = 91,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc2_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc2_suspend_cfg,
+ },
+ },
+ {
+ /* DATA_1 */
+ .gpio = 90,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc2_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc2_data_1_suspend_cfg,
+ },
+ },
+ {
+ /* DATA_0 */
+ .gpio = 89,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc2_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc2_suspend_cfg,
+ },
+ },
+ {
+ /* CMD */
+ .gpio = 97,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc2_cmd_data_0_3_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc2_suspend_cfg,
+ },
+ },
+ {
+ /* CLK */
+ .gpio = 98,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdcc2_clk_actv_cfg,
+ [GPIOMUX_SUSPENDED] = &sdcc2_suspend_cfg,
+ },
+ },
+};
+#endif
+
int __init msm8960_init_gpiomux(void)
{
int rc = msm_gpiomux_init(NR_GPIO_IRQS);
@@ -758,6 +913,11 @@
msm_gpiomux_install(wcnss_5wire_interface,
ARRAY_SIZE(wcnss_5wire_interface));
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+ msm_gpiomux_install(msm8960_sdcc4_configs,
+ ARRAY_SIZE(msm8960_sdcc4_configs));
+#endif
+
if (machine_is_msm8960_mtp() || machine_is_msm8960_fluid() ||
machine_is_msm8960_liquid() || machine_is_msm8960_cdp())
msm_gpiomux_install(hap_lvl_shft_config,
@@ -798,5 +958,10 @@
msm_gpiomux_install(msm8960_fusion_gsbi_configs,
ARRAY_SIZE(msm8960_fusion_gsbi_configs));
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+ msm_gpiomux_install(msm8960_sdcc2_configs,
+ ARRAY_SIZE(msm8960_sdcc2_configs));
+#endif
+
return 0;
}
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index ed47ae2..3923ecf 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -163,6 +163,8 @@
VREG_CONSUMERS(S4) = {
REGULATOR_SUPPLY("8921_s4", NULL),
REGULATOR_SUPPLY("sdc_vccq", "msm_sdcc.1"),
+ REGULATOR_SUPPLY("sdc_vdd", "msm_sdcc.2"),
+ REGULATOR_SUPPLY("sdc_vddp", "msm_sdcc.4"),
REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
REGULATOR_SUPPLY("hdmi_vcc", "hdmi_msm.0"),
REGULATOR_SUPPLY("VDDIO_CDC", "tabla-slim"),
@@ -193,7 +195,6 @@
};
VREG_CONSUMERS(LVS1) = {
REGULATOR_SUPPLY("8921_lvs1", NULL),
- REGULATOR_SUPPLY("sdc_vdd", "msm_sdcc.4"),
REGULATOR_SUPPLY("iris_vddio", "wcnss_wlan.0"),
};
VREG_CONSUMERS(LVS2) = {
diff --git a/arch/arm/mach-msm/board-8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
index f39a691..df1d846 100644
--- a/arch/arm/mach-msm/board-8960-storage.c
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -46,6 +46,16 @@
.lpm_uA = 9000,
.hpm_uA = 200000, /* 200mA */
},
+ /* SDCC2 : SDIO slot connected */
+ [SDCC2] = {
+ .name = "sdc_vdd",
+ .high_vol_level = 1800000,
+ .low_vol_level = 1800000,
+ .always_on = 1,
+ .lpm_sup = 1,
+ .lpm_uA = 9000,
+ .hpm_uA = 200000, /* 200mA */
+ },
/* SDCC3 : External card slot connected */
[SDCC3] = {
.name = "sdc_vdd",
@@ -84,7 +94,17 @@
* during sleep.
*/
.lpm_uA = 2000,
- }
+ },
+ /* SDCC4 : SDIO slot connected */
+ [SDCC4] = {
+ .name = "sdc_vddp",
+ .high_vol_level = 1800000,
+ .low_vol_level = 1800000,
+ .always_on = 1,
+ .lpm_sup = 1,
+ .hpm_uA = 200000, /* 200mA */
+ .lpm_uA = 2000,
+ },
};
static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
@@ -93,11 +113,19 @@
.vdd_data = &mmc_vdd_reg_data[SDCC1],
.vccq_data = &mmc_vccq_reg_data[SDCC1],
},
+ /* SDCC2 : SDIO card slot connected */
+ [SDCC2] = {
+ .vdd_data = &mmc_vdd_reg_data[SDCC2],
+ },
/* SDCC3 : External card slot connected */
[SDCC3] = {
.vdd_data = &mmc_vdd_reg_data[SDCC3],
.vddp_data = &mmc_vddp_reg_data[SDCC3],
- }
+ },
+ /* SDCC4 : SDIO card slot connected */
+ [SDCC4] = {
+ .vddp_data = &mmc_vddp_reg_data[SDCC4],
+ },
};
/* SDC1 pad data */
@@ -186,6 +214,35 @@
},
};
+struct msm_mmc_gpio sdc2_gpio[] = {
+ {92, "sdc2_dat_3"},
+ {91, "sdc2_dat_2"},
+ {90, "sdc2_dat_1"},
+ {89, "sdc2_dat_0"},
+ {97, "sdc2_cmd"},
+ {98, "sdc2_clk"}
+};
+
+struct msm_mmc_gpio sdc4_gpio[] = {
+ {83, "sdc4_dat_3"},
+ {84, "sdc4_dat_2"},
+ {85, "sdc4_dat_1"},
+ {86, "sdc4_dat_0"},
+ {87, "sdc4_cmd"},
+ {88, "sdc4_clk"}
+};
+
+struct msm_mmc_gpio_data mmc_gpio_data[MAX_SDCC_CONTROLLER] = {
+ [SDCC2] = {
+ .gpio = sdc2_gpio,
+ .size = ARRAY_SIZE(sdc2_gpio),
+ },
+ [SDCC4] = {
+ .gpio = sdc4_gpio,
+ .size = ARRAY_SIZE(sdc4_gpio),
+ },
+};
+
static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
[SDCC1] = {
.pull = &mmc_pad_pull_data[SDCC1],
@@ -201,9 +258,17 @@
[SDCC1] = {
.pad_data = &mmc_pad_data[SDCC1],
},
+ [SDCC2] = {
+ .is_gpio = 1,
+ .gpio_data = &mmc_gpio_data[SDCC2],
+ },
[SDCC3] = {
.pad_data = &mmc_pad_data[SDCC3],
},
+ [SDCC4] = {
+ .is_gpio = 1,
+ .gpio_data = &mmc_gpio_data[SDCC4],
+ },
};
#define MSM_MPM_PIN_SDC1_DAT1 17
@@ -237,6 +302,23 @@
};
#endif
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+static unsigned int sdc2_sup_clk_rates[] = {
+ 400000, 24000000, 48000000
+};
+
+static struct mmc_platform_data msm8960_sdc2_data = {
+ .ocr_mask = MMC_VDD_165_195,
+ .mmc_bus_width = MMC_CAP_4_BIT_DATA,
+ .sup_clk_table = sdc2_sup_clk_rates,
+ .sup_clk_cnt = ARRAY_SIZE(sdc2_sup_clk_rates),
+ .pclk_src_dfab = 1,
+ .vreg_data = &mmc_slot_vreg_data[SDCC2],
+ .pin_data = &mmc_slot_pin_data[SDCC2],
+ .sdiowakeup_irq = MSM_GPIO_TO_INT(90),
+};
+#endif
+
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
static struct mmc_platform_data msm8960_sdc3_data = {
.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
@@ -263,14 +345,39 @@
};
#endif
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+static unsigned int sdc4_sup_clk_rates[] = {
+ 400000, 24000000, 48000000
+};
+
+static struct mmc_platform_data msm8960_sdc4_data = {
+ .ocr_mask = MMC_VDD_165_195,
+ .mmc_bus_width = MMC_CAP_4_BIT_DATA,
+ .sup_clk_table = sdc4_sup_clk_rates,
+ .sup_clk_cnt = ARRAY_SIZE(sdc4_sup_clk_rates),
+ .pclk_src_dfab = 1,
+ .vreg_data = &mmc_slot_vreg_data[SDCC4],
+ .pin_data = &mmc_slot_pin_data[SDCC4],
+ .sdiowakeup_irq = MSM_GPIO_TO_INT(85),
+};
+#endif
+
void __init msm8960_init_mmc(void)
{
#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
/* SDC1 : eMMC card connected */
msm_add_sdcc(1, &msm8960_sdc1_data);
#endif
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+ /* SDC2: SDIO slot for WLAN*/
+ msm_add_sdcc(2, &msm8960_sdc2_data);
+#endif
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
/* SDC3: External card slot */
msm_add_sdcc(3, &msm8960_sdc3_data);
#endif
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+ /* SDC4: SDIO slot for WLAN */
+ msm_add_sdcc(4, &msm8960_sdc4_data);
+#endif
}
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 2c533d9..f6eee76 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -1066,6 +1066,7 @@
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
.memtype = ION_CP_MM_HEAP_ID,
.enable_ion = 1,
+ .cp_enabled = 1,
#else
.memtype = MEMTYPE_EBI1,
.enable_ion = 0,
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index ef5881f..f1553b6 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -682,7 +682,6 @@
#define MSM_SDC2_BASE 0x12140000
#define MSM_SDC2_DML_BASE (MSM_SDC2_BASE + 0x800)
#define MSM_SDC2_BAM_BASE (MSM_SDC2_BASE + 0x2000)
-#define MSM_SDC2_BASE 0x12140000
#define MSM_SDC3_BASE 0x12180000
#define MSM_SDC3_DML_BASE (MSM_SDC3_BASE + 0x800)
#define MSM_SDC3_BAM_BASE (MSM_SDC3_BASE + 0x2000)
@@ -3623,6 +3622,7 @@
struct msm_cache_dump_platform_data msm8960_cache_dump_pdata = {
.l2_size = L2_BUFFER_SIZE,
+ .l1_size = L1_BUFFER_SIZE,
};
struct platform_device msm8960_cache_dump_device = {
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 69c91f1..d433b9e 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -59,19 +59,20 @@
int channel_active;
int sd;
size_t sd_size;
+ struct list_head staged_commands[MSM_DMOV_CHANNEL_COUNT];
struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
- spinlock_t lock;
+ struct mutex lock;
+ spinlock_t list_lock;
unsigned int irq;
struct clk *clk;
struct clk *pclk;
struct clk *ebiclk;
unsigned int clk_ctl;
- struct timer_list timer;
+ struct delayed_work work;
};
-static void msm_dmov_clock_timer(unsigned long);
-static int msm_dmov_clk_toggle(int, int);
+static void msm_dmov_clock_work(struct work_struct *);
#ifdef CONFIG_ARCH_MSM8X60
@@ -163,15 +164,19 @@
{
.crci_conf = adm0_crci_conf,
.chan_conf = adm0_chan_conf,
- .lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
+ .lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
+ .list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
.clk_ctl = CLK_DIS,
- .timer = TIMER_INITIALIZER(msm_dmov_clock_timer, 0, 0),
+ .work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
+ msm_dmov_clock_work),
}, {
.crci_conf = adm1_crci_conf,
.chan_conf = adm1_chan_conf,
- .lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
+ .lock = __MUTEX_INITIALIZER(dmov_conf[1].lock),
+ .list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
.clk_ctl = CLK_DIS,
- .timer = TIMER_INITIALIZER(msm_dmov_clock_timer, 0, 1),
+ .work = __DELAYED_WORK_INITIALIZER(dmov_conf[1].work,
+ msm_dmov_clock_work),
}
};
#else
@@ -179,9 +184,11 @@
{
.crci_conf = NULL,
.chan_conf = NULL,
- .lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
+ .lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
+ .list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
.clk_ctl = CLK_DIS,
- .timer = TIMER_INITIALIZER(msm_dmov_clock_timer, 0, 0),
+ .work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
+ msm_dmov_clock_work),
}
};
#endif
@@ -223,103 +230,153 @@
#define PRINT_FLOW(format, args...) \
MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
-static int msm_dmov_clk_toggle(int adm, int on)
+static int msm_dmov_clk_on(int adm)
{
- int ret = 0;
+ int ret;
- if (on) {
- ret = clk_enable(dmov_conf[adm].clk);
- if (ret)
- goto err;
- if (dmov_conf[adm].pclk) {
- ret = clk_enable(dmov_conf[adm].pclk);
- if (ret) {
- clk_disable(dmov_conf[adm].clk);
- goto err;
- }
+ ret = clk_prepare_enable(dmov_conf[adm].clk);
+ if (ret)
+ return ret;
+ if (dmov_conf[adm].pclk) {
+ ret = clk_prepare_enable(dmov_conf[adm].pclk);
+ if (ret) {
+ clk_disable_unprepare(dmov_conf[adm].clk);
+ return ret;
}
- if (dmov_conf[adm].ebiclk) {
- ret = clk_enable(dmov_conf[adm].ebiclk);
- if (ret) {
- if (dmov_conf[adm].pclk)
- clk_disable(dmov_conf[adm].pclk);
- clk_disable(dmov_conf[adm].clk);
- }
- }
- } else {
- clk_disable(dmov_conf[adm].clk);
- if (dmov_conf[adm].pclk)
- clk_disable(dmov_conf[adm].pclk);
- if (dmov_conf[adm].ebiclk)
- clk_disable(dmov_conf[adm].ebiclk);
}
-err:
+ if (dmov_conf[adm].ebiclk) {
+ ret = clk_prepare_enable(dmov_conf[adm].ebiclk);
+ if (ret) {
+ if (dmov_conf[adm].pclk)
+ clk_disable_unprepare(dmov_conf[adm].pclk);
+ clk_disable_unprepare(dmov_conf[adm].clk);
+ }
+ }
return ret;
}
-static void msm_dmov_clock_timer(unsigned long adm)
+static void msm_dmov_clk_off(int adm)
{
- unsigned long irq_flags;
- spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
- if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
- BUG_ON(dmov_conf[adm].channel_active);
- msm_dmov_clk_toggle(adm, 0);
- dmov_conf[adm].clk_ctl = CLK_DIS;
+ clk_disable_unprepare(dmov_conf[adm].clk);
+ if (dmov_conf[adm].pclk)
+ clk_disable_unprepare(dmov_conf[adm].pclk);
+ if (dmov_conf[adm].ebiclk)
+ clk_disable_unprepare(dmov_conf[adm].ebiclk);
+}
+
+static void msm_dmov_clock_work(struct work_struct *work)
+{
+ struct msm_dmov_conf *conf =
+ container_of(to_delayed_work(work), struct msm_dmov_conf, work);
+ int adm = DMOV_IRQ_TO_ADM(conf->irq);
+ mutex_lock(&conf->lock);
+ if (conf->clk_ctl == CLK_TO_BE_DIS) {
+ BUG_ON(conf->channel_active);
+ msm_dmov_clk_off(adm);
+ conf->clk_ctl = CLK_DIS;
}
- spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+ mutex_unlock(&conf->lock);
}
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
-{
- int adm = DMOV_ID_TO_ADM(id);
- int ch = DMOV_ID_TO_CHAN(id);
- writel_relaxed((graceful << 31), DMOV_REG(DMOV_FLUSH0(ch), adm));
- wmb();
-}
-EXPORT_SYMBOL(msm_dmov_stop_cmd);
+enum {
+ NOFLUSH = 0,
+ GRACEFUL,
+ NONGRACEFUL,
+};
-void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
+/* Caller must hold the list lock */
+static struct msm_dmov_cmd *start_ready_cmd(unsigned ch, int adm)
{
- unsigned long irq_flags;
- unsigned int status;
+ struct msm_dmov_cmd *cmd;
+
+ if (list_empty(&dmov_conf[adm].ready_commands[ch]))
+ return NULL;
+
+ cmd = list_entry(dmov_conf[adm].ready_commands[ch].next, typeof(*cmd),
+ list);
+ list_del(&cmd->list);
+ if (cmd->exec_func)
+ cmd->exec_func(cmd);
+ list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
+ if (!dmov_conf[adm].channel_active)
+ enable_irq(dmov_conf[adm].irq);
+ dmov_conf[adm].channel_active |= BIT(ch);
+ PRINT_IO("msm dmov enqueue command, %x, ch %d\n", cmd->cmdptr, ch);
+ writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
+
+ return cmd;
+}
+
+static void msm_dmov_enqueue_cmd_ext_work(struct work_struct *work)
+{
+ struct msm_dmov_cmd *cmd =
+ container_of(work, struct msm_dmov_cmd, work);
+ unsigned id = cmd->id;
+ unsigned status;
+ unsigned long flags;
int adm = DMOV_ID_TO_ADM(id);
int ch = DMOV_ID_TO_CHAN(id);
- spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+ mutex_lock(&dmov_conf[adm].lock);
if (dmov_conf[adm].clk_ctl == CLK_DIS) {
- status = msm_dmov_clk_toggle(adm, 1);
+ status = msm_dmov_clk_on(adm);
if (status != 0)
goto error;
} else if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS)
- del_timer(&dmov_conf[adm].timer);
+ cancel_delayed_work_sync(&dmov_conf[adm].work);
dmov_conf[adm].clk_ctl = CLK_EN;
+ spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
+
+ cmd = list_entry(dmov_conf[adm].staged_commands[ch].next, typeof(*cmd),
+ list);
+ list_del(&cmd->list);
+ list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
if (status & DMOV_STATUS_CMD_PTR_RDY) {
PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
id, status);
- if (cmd->exec_func)
- cmd->exec_func(cmd);
- list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
- if (!dmov_conf[adm].channel_active)
- enable_irq(dmov_conf[adm].irq);
- dmov_conf[adm].channel_active |= 1U << ch;
- PRINT_IO("Writing %x exactly to register", cmd->cmdptr);
- writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
- } else {
- if (!dmov_conf[adm].channel_active) {
- dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
- mod_timer(&dmov_conf[adm].timer, jiffies + HZ);
+ cmd = start_ready_cmd(ch, adm);
+ /*
+ * We added something to the ready list, and still hold the
+ * list lock. Thus, no need to check for cmd == NULL
+ */
+ if (cmd->toflush) {
+ int flush = (cmd->toflush == GRACEFUL) ? 1 << 31 : 0;
+ writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
}
- if (list_empty(&dmov_conf[adm].active_commands[ch]))
+ } else {
+ cmd->toflush = 0;
+ if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
+ !list_empty(&dmov_conf[adm].ready_commands[ch]))
PRINT_ERROR("msm_dmov_enqueue_cmd_ext(%d), stalled, "
"status %x\n", id, status);
PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
"%x\n", id, status);
- list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
}
+ if (!dmov_conf[adm].channel_active) {
+ dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
+ schedule_delayed_work(&dmov_conf[adm].work, HZ);
+ }
+ spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
error:
- spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+ mutex_unlock(&dmov_conf[adm].lock);
+}
+
+void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
+{
+ int adm = DMOV_ID_TO_ADM(id);
+ int ch = DMOV_ID_TO_CHAN(id);
+ unsigned long flags;
+ cmd->id = id;
+ cmd->toflush = 0;
+ INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
+
+ spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
+ list_add_tail(&cmd->list, &dmov_conf[adm].staged_commands[ch]);
+ spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
+
+ schedule_work(&cmd->work);
}
EXPORT_SYMBOL(msm_dmov_enqueue_cmd_ext);
@@ -338,14 +395,18 @@
int ch = DMOV_ID_TO_CHAN(id);
int adm = DMOV_ID_TO_ADM(id);
int flush = graceful ? DMOV_FLUSH_TYPE : 0;
- spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+ struct msm_dmov_cmd *cmd;
+
+ spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
/* XXX not checking if flush cmd sent already */
if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
}
+ list_for_each_entry(cmd, &dmov_conf[adm].staged_commands[ch], list)
+ cmd->toflush = graceful ? GRACEFUL : NONGRACEFUL;
/* spin_unlock_irqrestore has the necessary barrier */
- spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+ spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
}
EXPORT_SYMBOL(msm_dmov_flush);
@@ -407,7 +468,7 @@
errdata->flush[5] = readl_relaxed(DMOV_REG(DMOV_FLUSH5(ch), adm));
}
-static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
+static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
{
unsigned int int_status;
unsigned int mask;
@@ -420,11 +481,12 @@
struct msm_dmov_cmd *cmd;
int adm = DMOV_IRQ_TO_ADM(irq);
- spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+ mutex_lock(&dmov_conf[adm].lock);
/* read and clear isr */
int_status = readl_relaxed(DMOV_REG(DMOV_ISR, adm));
PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
+ spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
while (int_status) {
mask = int_status & -int_status;
ch = fls(mask) - 1;
@@ -492,50 +554,38 @@
ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch),
adm));
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
- if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) &&
- !list_empty(&dmov_conf[adm].ready_commands[ch])) {
- cmd = list_entry(dmov_conf[adm].
- ready_commands[ch].next, typeof(*cmd),
- list);
- list_del(&cmd->list);
- if (cmd->exec_func)
- cmd->exec_func(cmd);
- list_add_tail(&cmd->list,
- &dmov_conf[adm].active_commands[ch]);
- PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id);
- writel_relaxed(cmd->cmdptr,
- DMOV_REG(DMOV_CMD_PTR(ch), adm));
- }
+ if (ch_status & DMOV_STATUS_CMD_PTR_RDY)
+ start_ready_cmd(ch, adm);
} while (ch_status & DMOV_STATUS_RSLT_VALID);
if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
- list_empty(&dmov_conf[adm].ready_commands[ch]))
+ list_empty(&dmov_conf[adm].ready_commands[ch]))
dmov_conf[adm].channel_active &= ~(1U << ch);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
}
+ spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
if (!dmov_conf[adm].channel_active && valid) {
disable_irq_nosync(dmov_conf[adm].irq);
dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
- mod_timer(&dmov_conf[adm].timer, jiffies + HZ);
+ schedule_delayed_work(&dmov_conf[adm].work, HZ);
}
- spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+ mutex_unlock(&dmov_conf[adm].lock);
return valid ? IRQ_HANDLED : IRQ_NONE;
}
static int msm_dmov_suspend_late(struct device *dev)
{
- unsigned long irq_flags;
struct platform_device *pdev = to_platform_device(dev);
int adm = (pdev->id >= 0) ? pdev->id : 0;
- spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+ mutex_lock(&dmov_conf[adm].lock);
if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
BUG_ON(dmov_conf[adm].channel_active);
- del_timer(&dmov_conf[adm].timer);
- msm_dmov_clk_toggle(adm, 0);
+ cancel_delayed_work_sync(&dmov_conf[adm].work);
+ msm_dmov_clk_off(adm);
dmov_conf[adm].clk_ctl = CLK_DIS;
}
- spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+ mutex_unlock(&dmov_conf[adm].lock);
return 0;
}
@@ -650,8 +700,8 @@
if (!dmov_conf[adm].base)
return -ENOMEM;
- ret = request_irq(dmov_conf[adm].irq, msm_datamover_irq_handler,
- 0, "msmdatamover", NULL);
+ ret = request_threaded_irq(dmov_conf[adm].irq, NULL, msm_dmov_isr,
+ IRQF_ONESHOT, "msmdatamover", NULL);
if (ret) {
PRINT_ERROR("Requesting ADM%d irq %d failed\n", adm,
dmov_conf[adm].irq);
@@ -663,7 +713,7 @@
PRINT_ERROR("Requesting ADM%d clocks failed\n", adm);
goto out_irq;
}
- ret = msm_dmov_clk_toggle(adm, 1);
+ ret = msm_dmov_clk_on(adm);
if (ret) {
PRINT_ERROR("Enabling ADM%d clocks failed\n", adm);
goto out_irq;
@@ -671,6 +721,7 @@
config_datamover(adm);
for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
+ INIT_LIST_HEAD(&dmov_conf[adm].staged_commands[i]);
INIT_LIST_HEAD(&dmov_conf[adm].ready_commands[i]);
INIT_LIST_HEAD(&dmov_conf[adm].active_commands[i]);
@@ -679,7 +730,7 @@
DMOV_REG(DMOV_RSLT_CONF(i), adm));
}
wmb();
- msm_dmov_clk_toggle(adm, 0);
+ msm_dmov_clk_off(adm);
return ret;
out_irq:
free_irq(dmov_conf[adm].irq, NULL);
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index b3e536e..ba621e6 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -35,7 +35,10 @@
unsigned int result,
struct msm_dmov_errdata *err);
void (*exec_func)(struct msm_dmov_cmd *cmd);
+ struct work_struct work;
+ unsigned id; /* For internal use */
void *user; /* Pointer for caller's reference */
+ u8 toflush;
};
struct msm_dmov_pdata {
@@ -45,7 +48,6 @@
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd);
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
void msm_dmov_flush(unsigned int id, int graceful);
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
index d4e4893..bec1d4c 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
@@ -821,13 +821,15 @@
}
/* Allow only single frame */
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- if (cfg.buffer_size != (FRAME_SIZE - 8))
+ if (cfg.buffer_size != (FRAME_SIZE - 8)) {
rc = -EINVAL;
break;
+ }
} else {
- if (cfg.buffer_size != (AMRNB_FRAME_SIZE + 14))
+ if (cfg.buffer_size != (AMRNB_FRAME_SIZE + 14)) {
rc = -EINVAL;
break;
+ }
}
audio->buffer_size = cfg.buffer_size;
break;
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
index 99ad02b..05a16da 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
@@ -799,13 +799,15 @@
}
/* Allow only single frame */
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- if (cfg.buffer_size != (FRAME_SIZE - 8))
+ if (cfg.buffer_size != (FRAME_SIZE - 8)) {
rc = -EINVAL;
break;
+ }
} else {
- if (cfg.buffer_size != (EVRC_FRAME_SIZE + 14))
+ if (cfg.buffer_size != (EVRC_FRAME_SIZE + 14)) {
rc = -EINVAL;
break;
+ }
}
audio->buffer_size = cfg.buffer_size;
break;
diff --git a/arch/arm/mach-msm/qdsp5/audio_out.c b/arch/arm/mach-msm/qdsp5/audio_out.c
index 8fe8cf66..ef7a70b 100644
--- a/arch/arm/mach-msm/qdsp5/audio_out.c
+++ b/arch/arm/mach-msm/qdsp5/audio_out.c
@@ -593,6 +593,7 @@
audio_flush(audio);
mutex_unlock(&audio->write_lock);
}
+ break;
case AUDIO_SET_CONFIG: {
struct msm_audio_config config;
if (copy_from_user(&config, (void*) arg, sizeof(config))) {
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
index 16c70ce..851980d 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
@@ -585,7 +585,7 @@
audio->in_head = 0;
audio->in_tail = 0;
audio->in_count = 0;
- for (i = FRAME_NUM-1; i <= 0; i--) {
+ for (i = FRAME_NUM-1; i >= 0; i--) {
audio->in[i].size = 0;
audio->in[i].read = 0;
}
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
index 6ebd5f9..e6906d0 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
@@ -800,13 +800,15 @@
}
/* Allow only single frame */
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- if (cfg.buffer_size != (FRAME_SIZE - 8))
+ if (cfg.buffer_size != (FRAME_SIZE - 8)) {
rc = -EINVAL;
break;
+ }
} else {
- if (cfg.buffer_size != (QCELP_FRAME_SIZE + 14))
+ if (cfg.buffer_size != (QCELP_FRAME_SIZE + 14)) {
rc = -EINVAL;
break;
+ }
}
audio->buffer_size = cfg.buffer_size;
break;
diff --git a/arch/arm/mach-msm/qdsp5/audio_wma.c b/arch/arm/mach-msm/qdsp5/audio_wma.c
index d767916..b17cdda 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wma.c
@@ -469,6 +469,7 @@
wake_up(&audio->write_wait);
if (audio->pcm_feedback)
audplay_buffer_refresh(audio);
+ break;
case AUDPP_MSG_PCMDMAMISSED:
MM_DBG("PCMDMAMISSED\n");
audio->teos = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_wmapro.c b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
index 7fb08ff..5e806e6 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
@@ -463,6 +463,7 @@
wake_up(&audio->write_wait);
if (audio->pcm_feedback)
audplay_buffer_refresh(audio);
+ break;
case AUDPP_MSG_PCMDMAMISSED:
MM_DBG("PCMDMAMISSED\n");
audio->teos = 1;
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 07a31a3..5aaef24 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -572,7 +572,7 @@
config MSM_VCAP
tristate "Qualcomm MSM VCAP"
depends on VIDEO_DEV && VIDEO_V4L2
- default n
+ default y
---help---
Enables VCAP driver. This device allows for video capture and
video processing using the v4l2 api
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index 1e66843..7531a26 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -333,7 +333,7 @@
{0x5000, 0xff},
{0x3a18, 0x00},
{0x3a19, 0x80},
- {0x3503, 0x00},
+ {0x3503, 0x07},
{0x4521, 0x00},
{0x5183, 0xb0},
{0x5184, 0xb0},
@@ -430,7 +430,7 @@
{0x5000, 0xff},
{0x3a18, 0x00},
{0x3a19, 0x80},
- {0x3503, 0x00},
+ {0x3503, 0x07},
{0x4521, 0x00},
{0x5183, 0xb0},
{0x5184, 0xb0},
@@ -527,7 +527,7 @@
{0x5000, 0xff},
{0x3a18, 0x00},
{0x3a19, 0x80},
- {0x3503, 0x00},
+ {0x3503, 0x07},
{0x4521, 0x00},
{0x5183, 0xb0},
{0x5184, 0xb0},
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index 83c83d1..d30d48b 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -32,11 +32,12 @@
};
static struct msm_camera_i2c_reg_conf ov5647_groupon_settings[] = {
- {0x0104, 0x01},
+ {0x3208, 0x0},
};
static struct msm_camera_i2c_reg_conf ov5647_groupoff_settings[] = {
- {0x0104, 0x0},
+ {0x3208, 0x10},
+ {0x3208, 0xa0},
};
static struct msm_camera_i2c_reg_conf ov5647_prev_settings[] = {
@@ -293,6 +294,8 @@
{0x518a, 0x04},
{0x518b, 0x00},
{0x5000, 0x06}, /*No lenc,WBC on*/
+ {0x4005, 0x18},
+ {0x4051, 0x8f},
};
@@ -407,7 +410,7 @@
uint16_t gain, uint32_t line)
{
- uint16_t max_line;
+ static uint16_t max_line = 1964;
uint8_t gain_lsb, gain_hsb;
u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
@@ -417,8 +420,8 @@
CDBG(KERN_ERR "snapshot exposure seting 0x%x, 0x%x, %d"
, gain, line, line);
+ s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
if (line > 1964) {
- s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_output_reg_addr->frame_length_lines,
(uint8_t)((line+4) >> 8),
@@ -428,21 +431,17 @@
s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
(uint8_t)((line+4) & 0x00FF),
MSM_CAMERA_I2C_BYTE_DATA);
- s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-
max_line = line + 4;
- } else if (line > 1968) {
- s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+ } else if (max_line > 1968) {
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_output_reg_addr->frame_length_lines,
- (uint8_t)((line+4) >> 8),
+ (uint8_t)(1968 >> 8),
MSM_CAMERA_I2C_BYTE_DATA);
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
- (uint8_t)((line+4) & 0x00FF),
+ (uint8_t)(1968 & 0x00FF),
MSM_CAMERA_I2C_BYTE_DATA);
- s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
max_line = 1968;
}
@@ -454,8 +453,6 @@
intg_time_lsb = (u8) (line & 0x00FF);
/* FIXME for BLC trigger */
- s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-
/* Coarse Integration Time */
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
@@ -481,7 +478,7 @@
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
- gain_lsb-1,
+ gain_lsb^0x1,
MSM_CAMERA_I2C_BYTE_DATA);
/* Coarse Integration Time */
@@ -523,7 +520,7 @@
uint16_t gain, uint32_t line)
{
- uint16_t max_line;
+ static uint16_t max_line = 984;
u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
uint8_t gain_lsb, gain_hsb;
@@ -533,9 +530,10 @@
gain_lsb = (uint8_t) (gain);
gain_hsb = (uint8_t)((gain & 0x300)>>8);
+ s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+
/* adjust frame rate */
if (line > 980 && line <= 984) {
-
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_output_reg_addr->frame_length_lines,
(uint8_t)((line+4) >> 8),
@@ -546,7 +544,7 @@
(uint8_t)((line+4) & 0x00FF),
MSM_CAMERA_I2C_BYTE_DATA);
max_line = line + 4;
- } else if (line > 984) {
+ } else if (max_line > 984) {
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_output_reg_addr->frame_length_lines,
@@ -566,7 +564,6 @@
intg_time_msb = (u8) ((line & 0xFF00) >> 8);
intg_time_lsb = (u8) (line & 0x00FF);
- s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
/* Coarse Integration Time */
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 73a31716..0d11dca 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1612,8 +1612,7 @@
if (!cmd->data || cmd->error) {
if (host->curr.data && host->dma.sg &&
host->is_dma_mode)
- msm_dmov_stop_cmd(host->dma.channel,
- &host->dma.hdr, 0);
+ msm_dmov_flush(host->dma.channel, 0);
else if (host->curr.data && host->sps.sg &&
host->is_sps_mode){
/* Stop current SPS transfer */
@@ -1766,8 +1765,7 @@
msmsdcc_data_err(host, data, status);
host->curr.data_xfered = 0;
if (host->dma.sg && host->is_dma_mode)
- msm_dmov_stop_cmd(host->dma.channel,
- &host->dma.hdr, 0);
+ msm_dmov_flush(host->dma.channel, 0);
else if (host->sps.sg && host->is_sps_mode) {
/* Stop current SPS transfer */
msmsdcc_sps_exit_curr_xfer(host);
@@ -4340,8 +4338,7 @@
mrq->data->error = -ETIMEDOUT;
host->curr.data_xfered = 0;
if (host->dma.sg && host->is_dma_mode) {
- msm_dmov_stop_cmd(host->dma.channel,
- &host->dma.hdr, 0);
+ msm_dmov_flush(host->dma.channel, 0);
} else if (host->sps.sg && host->is_sps_mode) {
/* Stop current SPS transfer */
msmsdcc_sps_exit_curr_xfer(host);
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index f559160..d310381 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -769,8 +769,7 @@
*/
mb();
/* do discard flush */
- msm_dmov_stop_cmd(msm_uport->dma_rx_channel,
- &msm_uport->rx.xfer, 0);
+ msm_dmov_flush(msm_uport->dma_rx_channel, 0);
}
msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
@@ -831,8 +830,7 @@
if (msm_uport->rx.flush == FLUSH_NONE) {
wake_lock(&msm_uport->rx.wake_lock);
/* do discard flush */
- msm_dmov_stop_cmd(msm_uport->dma_rx_channel,
- &msm_uport->rx.xfer, 0);
+ msm_dmov_flush(msm_uport->dma_rx_channel, 0);
}
if (msm_uport->rx.flush != FLUSH_SHUTDOWN)
msm_uport->rx.flush = FLUSH_STOP;