Merge commit 'AU_LINUX_ANDROID_ICS.04.00.04.00.130' into msm-3.4
* commit 'AU_LINUX_ANDROID_ICS.04.00.04.00.130': (39 commits)
msm: vidc: Add support for DIVX 4/5/6
msm_fb: display: Set the minimal sleep time for DSI PHY Initialisation
board: 8930: add debounce interval for gpio-keys
regulator: Extend of_get_regulator_init_data to support non-DT consumers
regulator: pm8xxx-regulator: Add slew_rate platform data parameter
crypto: Fix initialization of array variable.
arm: free all .init memory when CONFIG_STRICT_MEMORY_RWX is set
msm: clock-copper: Remove block reset ability from most clocks
msm: clock-local2: Fix local_vote_clk_reset to use right to_*_clk macro
EHCI: HSIC: Add support for suspend, resume and URB logging
arm/dt: msm-pm8941: Change boost regulator register address to 0xA000
msm: camera: Move server code into seperate file.
msm: camera: Close camera gracefully in case of userspace crash
media: dvb: mpq: Support getting decoder's buffer status
Bluetooth: Wait for wcnss to be ready after SSR
msm: msm_sdcc: Add device tree support for SDCC controllers
msm: display: Change DSI escape clock to byte clock
msm: clock-8960: Change source of DSI escape clock to byte clock
ASOC: msm: Enable mpq8064 machine driver.
EHCI: HSIC: Set the interrupt threshold control value to 8ms
...
Signed-off-by: Steve Muckle <smuckle@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
index 5b7a408..b2c4387 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -10,6 +10,11 @@
- regulator-always-on: boolean, regulator should never be disabled
- regulator-boot-on: bootloader/firmware enabled regulator
- <name>-supply: phandle to the parent supply/regulator node
+- qcom,consumer-supplies: flattened list of supply and dev_name pairs
+ This property is used to support regulator consumers that have no device
+ tree node. An empty string, "", can be used to specify a null device
+ name. A null device name is used to allow calls such as:
+ regulator_get(NULL, "pll_vdd").
Example:
@@ -18,6 +23,7 @@
regulator-max-microvolt = <2500000>;
regulator-always-on;
vin-supply = <&vin>;
+ qcom,consumer-supplies = "pll_vdd", "", "lcd_vcc", "foo.1";
};
Regulator Consumers:
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 2698ea7..e62dfbd 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -315,9 +315,9 @@
};
};
- regulator@1d00 {
+ regulator@a000 {
regulator-name = "8941_boost";
- reg = <0x1d00 0x100>;
+ reg = <0xa000 0x100>;
compatible = "qcom,qpnp-regulator";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/msmcopper-regulator.dtsi b/arch/arm/boot/dts/msmcopper-regulator.dtsi
index bb26e00..0d0c587 100644
--- a/arch/arm/boot/dts/msmcopper-regulator.dtsi
+++ b/arch/arm/boot/dts/msmcopper-regulator.dtsi
@@ -41,7 +41,7 @@
status = "okay";
};
- pm8941_boost: regulator@1d00 {
+ pm8941_boost: regulator@a000 {
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
qcom,enable-time = <500>;
diff --git a/arch/arm/boot/dts/msmcopper-rumi.dts b/arch/arm/boot/dts/msmcopper-rumi.dts
index 5bfb228..dff1973 100644
--- a/arch/arm/boot/dts/msmcopper-rumi.dts
+++ b/arch/arm/boot/dts/msmcopper-rumi.dts
@@ -31,17 +31,17 @@
};
qcom,sdcc@f9824000 {
- status = "disable";
- };
+ qcom,sdcc-clk-rates = <400000 19200000>;
+ };
+
+ qcom,sdcc@f98a4000 {
+ qcom,sdcc-clk-rates = <400000 19200000>;
+ };
qcom,sdcc@f9864000 {
status = "disable";
};
- qcom,sdcc@f98a4000 {
- status = "disable";
- };
-
qcom,sdcc@f98e4000 {
status = "disable";
};
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index e0811ac..148f17f 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -47,6 +47,7 @@
CONFIG_MSM_PIL_LPASS_QDSP6V5=y
CONFIG_MSM_TZ_LOG=y
CONFIG_MSM_PIL_PRONTO=y
+CONFIG_MSM_IOMMU=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_OCMEM=y
CONFIG_NO_HZ=y
diff --git a/arch/arm/include/asm/mach/flash.h b/arch/arm/include/asm/mach/flash.h
index 36938ea..7ed9630 100644
--- a/arch/arm/include/asm/mach/flash.h
+++ b/arch/arm/include/asm/mach/flash.h
@@ -13,6 +13,11 @@
struct mtd_partition;
struct mtd_info;
+enum sw_version {
+ VERSION_1 = 0,
+ VERSION_2,
+};
+
/*
* map_name: the map probe function name
* name: flash device name (eg, as used with mtdparts=)
@@ -24,6 +29,7 @@
* mmcontrol: method called to enable or disable Sync. Burst Read in OneNAND
* parts: optional array of mtd_partitions for static partitioning
* nr_parts: number of mtd_partitions for static partitoning
+ * version: software register interface version
*/
struct flash_platform_data {
const char *map_name;
@@ -36,6 +42,7 @@
void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
struct mtd_partition *parts;
unsigned int nr_parts;
+ enum sw_version version;
};
#endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 975c1798..44bef1b 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -311,6 +311,8 @@
obj-$(CONFIG_ARCH_MSM8960) += rpm_resources.o
obj-$(CONFIG_ARCH_MSM8X60) += rpm_resources.o
obj-$(CONFIG_ARCH_MSM9615) += rpm_resources.o
+endif
+ifdef CONFIG_MSM_RPM_SMD
obj-$(CONFIG_ARCH_MSMCOPPER) += lpm_levels.o
endif
obj-$(CONFIG_MSM_MPM) += mpm.o
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 55e8123..71ad49a 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -227,7 +227,7 @@
};
static int mdp_core_clk_rate_table[] = {
- 85330000,
+ 59080000,
128000000,
160000000,
200000000,
@@ -235,7 +235,7 @@
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = MDP_VSYNC_GPIO,
- .mdp_core_clk_rate = 85330000,
+ .mdp_core_clk_rate = 59080000,
.mdp_core_clk_table = mdp_core_clk_rate_table,
.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
.mdp_bus_scale_table = &mdp_bus_scale_pdata,
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index b22c684..b941bd4 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -1023,6 +1023,151 @@
},
};
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+static struct gpiomux_setting sdc2_clk_active_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting sdc2_cmd_data_0_3_active_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting sdc2_suspended_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting sdc2_data_1_suspended_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct msm_gpiomux_config apq8064_sdc2_configs[] __initdata = {
+ {
+ .gpio = 59,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc2_clk_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+ },
+ },
+ {
+ .gpio = 57,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+ },
+
+ },
+ {
+ .gpio = 62,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+ },
+ },
+ {
+ .gpio = 61,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc2_data_1_suspended_cfg,
+ },
+ },
+ {
+ .gpio = 60,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+ },
+ },
+ {
+ .gpio = 58,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+ },
+ },
+};
+#endif
+
+
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+static struct gpiomux_setting sdc4_clk_active_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting sdc4_cmd_data_0_3_active_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting sdc4_suspended_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting sdc4_data_1_suspended_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct msm_gpiomux_config apq8064_sdc4_configs[] __initdata = {
+ {
+ .gpio = 68,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc4_clk_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+ },
+ },
+ {
+ .gpio = 67,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+ },
+
+ },
+ {
+ .gpio = 66,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+ },
+ },
+ {
+ .gpio = 65,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc4_data_1_suspended_cfg,
+ },
+ },
+ {
+ .gpio = 64,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+ },
+ },
+ {
+ .gpio = 63,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+ [GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+ },
+ },
+};
+#endif
+
void __init apq8064_init_gpiomux(void)
{
int rc;
@@ -1104,4 +1249,14 @@
if (machine_is_mpq8064_cdp())
msm_gpiomux_install(mpq8064_ir_configs,
ARRAY_SIZE(mpq8064_ir_configs));
+
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+ msm_gpiomux_install(apq8064_sdc2_configs,
+ ARRAY_SIZE(apq8064_sdc2_configs));
+#endif
+
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+ msm_gpiomux_install(apq8064_sdc4_configs,
+ ARRAY_SIZE(apq8064_sdc4_configs));
+#endif
}
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index ed186c3..193fc4a 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -188,13 +188,50 @@
},
};
+static struct msm_mmc_gpio sdc2_gpio[] = {
+ {59, "sdc2_clk"},
+ {57, "sdc2_cmd"},
+ {62, "sdc2_dat_0"},
+ {61, "sdc2_dat_1"},
+ {60, "sdc2_dat_2"},
+ {58, "sdc2_dat_3"},
+};
+
+static struct msm_mmc_gpio sdc4_gpio[] = {
+ {68, "sdc4_clk"},
+ {67, "sdc4_cmd"},
+ {66, "sdc4_dat_0"},
+ {65, "sdc4_dat_1"},
+ {64, "sdc4_dat_2"},
+ {63, "sdc4_dat_3"},
+};
+
+static 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_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
[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
@@ -227,6 +264,26 @@
static struct mmc_platform_data *apq8064_sdc1_pdata;
#endif
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+static unsigned int sdc2_sup_clk_rates[] = {
+ 400000, 24000000, 48000000
+};
+
+static struct mmc_platform_data sdc2_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
+ .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,
+ .pin_data = &mmc_slot_pin_data[SDCC2],
+ .sdiowakeup_irq = MSM_GPIO_TO_INT(61),
+ .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
+};
+static struct mmc_platform_data *apq8064_sdc2_pdata = &sdc2_data;
+#else
+static struct mmc_platform_data *apq8064_sdc2_pdata;
+#endif
+
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
static unsigned int sdc3_sup_clk_rates[] = {
400000, 24000000, 48000000, 96000000, 192000000
@@ -258,6 +315,27 @@
static struct mmc_platform_data *apq8064_sdc3_pdata;
#endif
+
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+static unsigned int sdc4_sup_clk_rates[] = {
+ 400000, 24000000, 48000000
+};
+
+static struct mmc_platform_data sdc4_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
+ .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,
+ .pin_data = &mmc_slot_pin_data[SDCC4],
+ .sdiowakeup_irq = MSM_GPIO_TO_INT(65),
+ .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
+};
+static struct mmc_platform_data *apq8064_sdc4_pdata = &sdc4_data;
+#else
+static struct mmc_platform_data *apq8064_sdc4_pdata;
+#endif
+
void __init apq8064_init_mmc(void)
{
if ((machine_is_apq8064_rumi3()) || machine_is_apq8064_sim()) {
@@ -278,6 +356,9 @@
if (apq8064_sdc1_pdata)
apq8064_add_sdcc(1, apq8064_sdc1_pdata);
+ if (apq8064_sdc2_pdata)
+ apq8064_add_sdcc(2, apq8064_sdc2_pdata);
+
if (apq8064_sdc3_pdata) {
if (!machine_is_apq8064_cdp()) {
apq8064_sdc3_pdata->wpswitch_gpio = 0;
@@ -292,4 +373,7 @@
}
apq8064_add_sdcc(3, apq8064_sdc3_pdata);
}
+
+ if (apq8064_sdc4_pdata)
+ apq8064_add_sdcc(4, apq8064_sdc4_pdata);
}
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 9f78ea7..806bbd8 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2192,6 +2192,7 @@
&apq8064_rpm_device,
&apq8064_rpm_log_device,
&apq8064_rpm_stat_device,
+ &apq_device_tz_log,
&msm_bus_8064_apps_fabric,
&msm_bus_8064_sys_fabric,
&msm_bus_8064_mm_fabric,
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index f7e6801..98d9f3a 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1789,6 +1789,7 @@
.gpio = GPIO_VOLUME_UP,
.wakeup = 1,
.active_low = 1,
+ .debounce_interval = 15,
},
{
.code = KEY_VOLUMEDOWN,
@@ -1797,6 +1798,7 @@
.gpio = GPIO_VOLUME_DOWN,
.wakeup = 1,
.active_low = 1,
+ .debounce_interval = 15,
},
{
.code = KEY_CAMERA_FOCUS,
@@ -1805,6 +1807,7 @@
.gpio = GPIO_CAMERA_FOCUS,
.wakeup = 1,
.active_low = 1,
+ .debounce_interval = 15,
},
{
.code = KEY_CAMERA_SNAPSHOT,
@@ -1813,6 +1816,7 @@
.gpio = GPIO_CAMERA_SNAPSHOT,
.wakeup = 1,
.active_low = 1,
+ .debounce_interval = 15,
},
};
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 6ecd1e3..1c32b5e 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -637,8 +637,9 @@
static u32 msm_calculate_batt_capacity(u32 current_voltage);
static struct msm_psy_batt_pdata msm_psy_batt_data = {
- .voltage_min_design = 2800,
- .voltage_max_design = 4300,
+ .voltage_min_design = 3200,
+ .voltage_max_design = 4200,
+ .voltage_fail_safe = 3340,
.avail_chg_sources = AC_CHG | USB_CHG ,
.batt_technology = POWER_SUPPLY_TECHNOLOGY_LION,
.calculate_capacity = &msm_calculate_batt_capacity,
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index db0c9c0..7708310 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -582,8 +582,9 @@
static u32 msm_calculate_batt_capacity(u32 current_voltage);
static struct msm_psy_batt_pdata msm_psy_batt_data = {
- .voltage_min_design = 2800,
- .voltage_max_design = 4300,
+ .voltage_min_design = 3200,
+ .voltage_max_design = 4200,
+ .voltage_fail_safe = 3340,
.avail_chg_sources = AC_CHG | USB_CHG ,
.batt_technology = POWER_SUPPLY_TECHNOLOGY_LION,
.calculate_capacity = &msm_calculate_batt_capacity,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index a1b9c1c..7b4ca29 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -6107,6 +6107,9 @@
if (cpu_is_msm8960() || cpu_is_apq8064())
rmwreg(0x2, DSI2_BYTE_NS_REG, 0x7);
+ /* Source the dsi1_esc_clk from the DSI1 PHY PLLs */
+ rmwreg(0x1, DSI1_ESC_NS_REG, 0x7);
+
/*
* Source the sata_phy_ref_clk from PXO and set predivider of
* sata_pmalive_clk to 1.
diff --git a/arch/arm/mach-msm/clock-copper.c b/arch/arm/mach-msm/clock-copper.c
index 4d5f773..fc0b0af 100644
--- a/arch/arm/mach-msm/clock-copper.c
+++ b/arch/arm/mach-msm/clock-copper.c
@@ -1398,7 +1398,6 @@
.cbcr_reg = BAM_DMA_AHB_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(12),
- .bcr_reg = BAM_DMA_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_bam_dma_ahb_clk",
@@ -1411,7 +1410,6 @@
.cbcr_reg = BLSP1_AHB_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(17),
- .bcr_reg = BLSP1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_ahb_clk",
@@ -1424,7 +1422,6 @@
.cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP1_QUP1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
@@ -1436,7 +1433,6 @@
static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
.parent = &blsp1_qup1_spi_apps_clk_src.c,
- .bcr_reg = BLSP1_QUP1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
@@ -1449,7 +1445,6 @@
.cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP1_QUP2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
@@ -1461,7 +1456,6 @@
static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
.parent = &blsp1_qup2_spi_apps_clk_src.c,
- .bcr_reg = BLSP1_QUP2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
@@ -1474,7 +1468,6 @@
.cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP1_QUP3_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
@@ -1486,7 +1479,6 @@
static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
.parent = &blsp1_qup3_spi_apps_clk_src.c,
- .bcr_reg = BLSP1_QUP3_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
@@ -1499,7 +1491,6 @@
.cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP1_QUP4_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
@@ -1511,7 +1502,6 @@
static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
.parent = &blsp1_qup4_spi_apps_clk_src.c,
- .bcr_reg = BLSP1_QUP4_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
@@ -1524,7 +1514,6 @@
.cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP1_QUP5_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
@@ -1536,7 +1525,6 @@
static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
.parent = &blsp1_qup5_spi_apps_clk_src.c,
- .bcr_reg = BLSP1_QUP5_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
@@ -1549,7 +1537,6 @@
.cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP1_QUP6_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
@@ -1561,7 +1548,6 @@
static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
.parent = &blsp1_qup6_spi_apps_clk_src.c,
- .bcr_reg = BLSP1_QUP6_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
@@ -1573,7 +1559,6 @@
static struct branch_clk gcc_blsp1_uart1_apps_clk = {
.cbcr_reg = BLSP1_UART1_APPS_CBCR,
.parent = &blsp1_uart1_apps_clk_src.c,
- .bcr_reg = BLSP1_UART1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_uart1_apps_clk",
@@ -1585,7 +1570,6 @@
static struct branch_clk gcc_blsp1_uart2_apps_clk = {
.cbcr_reg = BLSP1_UART2_APPS_CBCR,
.parent = &blsp1_uart2_apps_clk_src.c,
- .bcr_reg = BLSP1_UART2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_uart2_apps_clk",
@@ -1597,7 +1581,6 @@
static struct branch_clk gcc_blsp1_uart3_apps_clk = {
.cbcr_reg = BLSP1_UART3_APPS_CBCR,
.parent = &blsp1_uart3_apps_clk_src.c,
- .bcr_reg = BLSP1_UART3_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_uart3_apps_clk",
@@ -1609,7 +1592,6 @@
static struct branch_clk gcc_blsp1_uart4_apps_clk = {
.cbcr_reg = BLSP1_UART4_APPS_CBCR,
.parent = &blsp1_uart4_apps_clk_src.c,
- .bcr_reg = BLSP1_UART4_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_uart4_apps_clk",
@@ -1621,7 +1603,6 @@
static struct branch_clk gcc_blsp1_uart5_apps_clk = {
.cbcr_reg = BLSP1_UART5_APPS_CBCR,
.parent = &blsp1_uart5_apps_clk_src.c,
- .bcr_reg = BLSP1_UART5_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_uart5_apps_clk",
@@ -1633,7 +1614,6 @@
static struct branch_clk gcc_blsp1_uart6_apps_clk = {
.cbcr_reg = BLSP1_UART6_APPS_CBCR,
.parent = &blsp1_uart6_apps_clk_src.c,
- .bcr_reg = BLSP1_UART6_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp1_uart6_apps_clk",
@@ -1646,7 +1626,6 @@
.cbcr_reg = BOOT_ROM_AHB_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(10),
- .bcr_reg = BOOT_ROM_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_boot_rom_ahb_clk",
@@ -1659,7 +1638,6 @@
.cbcr_reg = BLSP2_AHB_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(15),
- .bcr_reg = BLSP2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_ahb_clk",
@@ -1672,7 +1650,6 @@
.cbcr_reg = BLSP2_QUP1_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP2_QUP1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup1_i2c_apps_clk",
@@ -1684,7 +1661,6 @@
static struct branch_clk gcc_blsp2_qup1_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP1_SPI_APPS_CBCR,
.parent = &blsp2_qup1_spi_apps_clk_src.c,
- .bcr_reg = BLSP2_QUP1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup1_spi_apps_clk",
@@ -1697,7 +1673,6 @@
.cbcr_reg = BLSP2_QUP2_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP2_QUP2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup2_i2c_apps_clk",
@@ -1709,7 +1684,6 @@
static struct branch_clk gcc_blsp2_qup2_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP2_SPI_APPS_CBCR,
.parent = &blsp2_qup2_spi_apps_clk_src.c,
- .bcr_reg = BLSP2_QUP2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup2_spi_apps_clk",
@@ -1722,7 +1696,6 @@
.cbcr_reg = BLSP2_QUP3_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP2_QUP3_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup3_i2c_apps_clk",
@@ -1734,7 +1707,6 @@
static struct branch_clk gcc_blsp2_qup3_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP3_SPI_APPS_CBCR,
.parent = &blsp2_qup3_spi_apps_clk_src.c,
- .bcr_reg = BLSP2_QUP3_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup3_spi_apps_clk",
@@ -1747,7 +1719,6 @@
.cbcr_reg = BLSP2_QUP4_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP2_QUP4_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup4_i2c_apps_clk",
@@ -1759,7 +1730,6 @@
static struct branch_clk gcc_blsp2_qup4_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP4_SPI_APPS_CBCR,
.parent = &blsp2_qup4_spi_apps_clk_src.c,
- .bcr_reg = BLSP2_QUP4_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup4_spi_apps_clk",
@@ -1772,7 +1742,6 @@
.cbcr_reg = BLSP2_QUP5_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP2_QUP5_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup5_i2c_apps_clk",
@@ -1784,7 +1753,6 @@
static struct branch_clk gcc_blsp2_qup5_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP5_SPI_APPS_CBCR,
.parent = &blsp2_qup5_spi_apps_clk_src.c,
- .bcr_reg = BLSP2_QUP5_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup5_spi_apps_clk",
@@ -1797,7 +1765,6 @@
.cbcr_reg = BLSP2_QUP6_I2C_APPS_CBCR,
.parent = &cxo_clk_src.c,
.has_sibling = 1,
- .bcr_reg = BLSP2_QUP6_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup6_i2c_apps_clk",
@@ -1809,7 +1776,6 @@
static struct branch_clk gcc_blsp2_qup6_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP6_SPI_APPS_CBCR,
.parent = &blsp2_qup6_spi_apps_clk_src.c,
- .bcr_reg = BLSP2_QUP6_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_qup6_spi_apps_clk",
@@ -1821,7 +1787,6 @@
static struct branch_clk gcc_blsp2_uart1_apps_clk = {
.cbcr_reg = BLSP2_UART1_APPS_CBCR,
.parent = &blsp2_uart1_apps_clk_src.c,
- .bcr_reg = BLSP2_UART1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_uart1_apps_clk",
@@ -1833,7 +1798,6 @@
static struct branch_clk gcc_blsp2_uart2_apps_clk = {
.cbcr_reg = BLSP2_UART2_APPS_CBCR,
.parent = &blsp2_uart2_apps_clk_src.c,
- .bcr_reg = BLSP2_UART2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_uart2_apps_clk",
@@ -1845,7 +1809,6 @@
static struct branch_clk gcc_blsp2_uart3_apps_clk = {
.cbcr_reg = BLSP2_UART3_APPS_CBCR,
.parent = &blsp2_uart3_apps_clk_src.c,
- .bcr_reg = BLSP2_UART3_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_uart3_apps_clk",
@@ -1857,7 +1820,6 @@
static struct branch_clk gcc_blsp2_uart4_apps_clk = {
.cbcr_reg = BLSP2_UART4_APPS_CBCR,
.parent = &blsp2_uart4_apps_clk_src.c,
- .bcr_reg = BLSP2_UART4_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_uart4_apps_clk",
@@ -1869,7 +1831,6 @@
static struct branch_clk gcc_blsp2_uart5_apps_clk = {
.cbcr_reg = BLSP2_UART5_APPS_CBCR,
.parent = &blsp2_uart5_apps_clk_src.c,
- .bcr_reg = BLSP2_UART5_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_uart5_apps_clk",
@@ -1881,7 +1842,6 @@
static struct branch_clk gcc_blsp2_uart6_apps_clk = {
.cbcr_reg = BLSP2_UART6_APPS_CBCR,
.parent = &blsp2_uart6_apps_clk_src.c,
- .bcr_reg = BLSP2_UART6_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_blsp2_uart6_apps_clk",
@@ -1894,7 +1854,6 @@
.cbcr_reg = CE1_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(5),
- .bcr_reg = CE1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_ce1_clk",
@@ -1907,7 +1866,6 @@
.cbcr_reg = CE1_AHB_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(3),
- .bcr_reg = CE1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_ce1_ahb_clk",
@@ -1920,7 +1878,6 @@
.cbcr_reg = CE1_AXI_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(4),
- .bcr_reg = CE1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_ce1_axi_clk",
@@ -1933,7 +1890,6 @@
.cbcr_reg = CE2_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(2),
- .bcr_reg = CE2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_ce2_clk",
@@ -1946,7 +1902,6 @@
.cbcr_reg = CE2_AHB_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(0),
- .bcr_reg = CE2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_ce1_ahb_clk",
@@ -1959,7 +1914,6 @@
.cbcr_reg = CE2_AXI_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(1),
- .bcr_reg = CE2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_ce1_axi_clk",
@@ -2004,7 +1958,6 @@
static struct branch_clk gcc_pdm2_clk = {
.cbcr_reg = PDM2_CBCR,
.parent = &pdm2_clk_src.c,
- .bcr_reg = PDM_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_pdm2_clk",
@@ -2016,7 +1969,6 @@
static struct branch_clk gcc_pdm_ahb_clk = {
.cbcr_reg = PDM_AHB_CBCR,
.has_sibling = 1,
- .bcr_reg = PDM_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_pdm_ahb_clk",
@@ -2029,7 +1981,6 @@
.cbcr_reg = PRNG_AHB_CBCR,
.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(13),
- .bcr_reg = PRNG_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_prng_ahb_clk",
@@ -2041,7 +1992,6 @@
static struct branch_clk gcc_sdcc1_ahb_clk = {
.cbcr_reg = SDCC1_AHB_CBCR,
.has_sibling = 1,
- .bcr_reg = SDCC1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_sdcc1_ahb_clk",
@@ -2053,7 +2003,6 @@
static struct branch_clk gcc_sdcc1_apps_clk = {
.cbcr_reg = SDCC1_APPS_CBCR,
.parent = &sdcc1_apps_clk_src.c,
- .bcr_reg = SDCC1_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_sdcc1_apps_clk",
@@ -2065,7 +2014,6 @@
static struct branch_clk gcc_sdcc2_ahb_clk = {
.cbcr_reg = SDCC2_AHB_CBCR,
.has_sibling = 1,
- .bcr_reg = SDCC2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_sdcc2_ahb_clk",
@@ -2077,7 +2025,6 @@
static struct branch_clk gcc_sdcc2_apps_clk = {
.cbcr_reg = SDCC2_APPS_CBCR,
.parent = &sdcc2_apps_clk_src.c,
- .bcr_reg = SDCC2_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_sdcc2_apps_clk",
@@ -2089,7 +2036,6 @@
static struct branch_clk gcc_sdcc3_ahb_clk = {
.cbcr_reg = SDCC3_AHB_CBCR,
.has_sibling = 1,
- .bcr_reg = SDCC3_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_sdcc3_ahb_clk",
@@ -2101,7 +2047,6 @@
static struct branch_clk gcc_sdcc3_apps_clk = {
.cbcr_reg = SDCC3_APPS_CBCR,
.parent = &sdcc3_apps_clk_src.c,
- .bcr_reg = SDCC3_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_sdcc3_apps_clk",
@@ -2113,7 +2058,6 @@
static struct branch_clk gcc_sdcc4_ahb_clk = {
.cbcr_reg = SDCC4_AHB_CBCR,
.has_sibling = 1,
- .bcr_reg = SDCC4_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_sdcc4_ahb_clk",
@@ -2125,7 +2069,6 @@
static struct branch_clk gcc_sdcc4_apps_clk = {
.cbcr_reg = SDCC4_APPS_CBCR,
.parent = &sdcc4_apps_clk_src.c,
- .bcr_reg = SDCC4_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_sdcc4_apps_clk",
@@ -2137,7 +2080,6 @@
static struct branch_clk gcc_tsif_ahb_clk = {
.cbcr_reg = TSIF_AHB_CBCR,
.has_sibling = 1,
- .bcr_reg = TSIF_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_tsif_ahb_clk",
@@ -2149,7 +2091,6 @@
static struct branch_clk gcc_tsif_ref_clk = {
.cbcr_reg = TSIF_REF_CBCR,
.parent = &tsif_ref_clk_src.c,
- .bcr_reg = TSIF_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_tsif_ref_clk",
@@ -2162,7 +2103,6 @@
.cbcr_reg = USB30_MASTER_CBCR,
.parent = &usb30_master_clk_src.c,
.has_sibling = 1,
- .bcr_reg = USB_30_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_usb30_master_clk",
@@ -2174,7 +2114,6 @@
static struct branch_clk gcc_usb30_mock_utmi_clk = {
.cbcr_reg = USB30_MOCK_UTMI_CBCR,
.parent = &usb30_mock_utmi_clk_src.c,
- .bcr_reg = USB_30_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_usb30_mock_utmi_clk",
@@ -2186,7 +2125,6 @@
static struct branch_clk gcc_usb_hs_ahb_clk = {
.cbcr_reg = USB_HS_AHB_CBCR,
.has_sibling = 1,
- .bcr_reg = USB_HS_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_usb_hs_ahb_clk",
@@ -2198,7 +2136,6 @@
static struct branch_clk gcc_usb_hs_system_clk = {
.cbcr_reg = USB_HS_SYSTEM_CBCR,
.parent = &usb_hs_system_clk_src.c,
- .bcr_reg = USB_HS_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_usb_hs_system_clk",
@@ -2210,7 +2147,6 @@
static struct branch_clk gcc_usb_hsic_ahb_clk = {
.cbcr_reg = USB_HSIC_AHB_CBCR,
.has_sibling = 1,
- .bcr_reg = USB_HS_HSIC_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_usb_hsic_ahb_clk",
@@ -2222,7 +2158,6 @@
static struct branch_clk gcc_usb_hsic_clk = {
.cbcr_reg = USB_HSIC_CBCR,
.parent = &usb_hsic_clk_src.c,
- .bcr_reg = USB_HS_HSIC_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_usb_hsic_clk",
@@ -2234,7 +2169,6 @@
static struct branch_clk gcc_usb_hsic_io_cal_clk = {
.cbcr_reg = USB_HSIC_IO_CAL_CBCR,
.parent = &usb_hsic_io_cal_clk_src.c,
- .bcr_reg = USB_HS_HSIC_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_usb_hsic_io_cal_clk",
@@ -2246,7 +2180,6 @@
static struct branch_clk gcc_usb_hsic_system_clk = {
.cbcr_reg = USB_HSIC_SYSTEM_CBCR,
.parent = &usb_hsic_system_clk_src.c,
- .bcr_reg = USB_HS_HSIC_BCR,
.base = &virt_bases[GCC_BASE],
.c = {
.dbg_name = "gcc_usb_hsic_system_clk",
@@ -2938,7 +2871,6 @@
.cbcr_reg = CAMSS_CCI_CCI_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CCI_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_cci_cci_ahb_clk",
@@ -2951,7 +2883,6 @@
.cbcr_reg = CAMSS_CCI_CCI_CBCR,
.parent = &cci_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_CCI_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_cci_cci_clk",
@@ -2964,7 +2895,6 @@
.cbcr_reg = CAMSS_CSI0_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi0_ahb_clk",
@@ -2977,7 +2907,6 @@
.cbcr_reg = CAMSS_CSI0_CBCR,
.parent = &csi0_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi0_clk",
@@ -2990,7 +2919,6 @@
.cbcr_reg = CAMSS_CSI0PHY_CBCR,
.parent = &csi0_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI0PHY_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi0phy_clk",
@@ -3003,7 +2931,6 @@
.cbcr_reg = CAMSS_CSI0PIX_CBCR,
.parent = &csi0_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI0PIX_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi0pix_clk",
@@ -3016,7 +2943,6 @@
.cbcr_reg = CAMSS_CSI0RDI_CBCR,
.parent = &csi0_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI0RDI_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi0rdi_clk",
@@ -3029,7 +2955,6 @@
.cbcr_reg = CAMSS_CSI1_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI1_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi1_ahb_clk",
@@ -3042,7 +2967,6 @@
.cbcr_reg = CAMSS_CSI1_CBCR,
.parent = &csi1_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI1_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi1_clk",
@@ -3055,7 +2979,6 @@
.cbcr_reg = CAMSS_CSI1PHY_CBCR,
.parent = &csi1_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI1PHY_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi1phy_clk",
@@ -3068,7 +2991,6 @@
.cbcr_reg = CAMSS_CSI1PIX_CBCR,
.parent = &csi1_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI1PIX_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi1pix_clk",
@@ -3081,7 +3003,6 @@
.cbcr_reg = CAMSS_CSI1RDI_CBCR,
.parent = &csi1_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI1RDI_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi1rdi_clk",
@@ -3094,7 +3015,6 @@
.cbcr_reg = CAMSS_CSI2_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI2_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi2_ahb_clk",
@@ -3107,7 +3027,6 @@
.cbcr_reg = CAMSS_CSI2_CBCR,
.parent = &csi2_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI2_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi2_clk",
@@ -3120,7 +3039,6 @@
.cbcr_reg = CAMSS_CSI2PHY_CBCR,
.parent = &csi2_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI2PHY_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi2phy_clk",
@@ -3133,7 +3051,6 @@
.cbcr_reg = CAMSS_CSI2PIX_CBCR,
.parent = &csi2_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI2PIX_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi2pix_clk",
@@ -3146,7 +3063,6 @@
.cbcr_reg = CAMSS_CSI2RDI_CBCR,
.parent = &csi2_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI2RDI_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi2rdi_clk",
@@ -3159,7 +3075,6 @@
.cbcr_reg = CAMSS_CSI3_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI3_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi3_ahb_clk",
@@ -3172,7 +3087,6 @@
.cbcr_reg = CAMSS_CSI3_CBCR,
.parent = &csi3_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI3_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi3_clk",
@@ -3185,7 +3099,6 @@
.cbcr_reg = CAMSS_CSI3PHY_CBCR,
.parent = &csi3_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI3PHY_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi3phy_clk",
@@ -3198,7 +3111,6 @@
.cbcr_reg = CAMSS_CSI3PIX_CBCR,
.parent = &csi3_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI3PIX_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi3pix_clk",
@@ -3211,7 +3123,6 @@
.cbcr_reg = CAMSS_CSI3RDI_CBCR,
.parent = &csi3_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI3RDI_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi3rdi_clk",
@@ -3224,7 +3135,6 @@
.cbcr_reg = CAMSS_CSI_VFE0_CBCR,
.parent = &vfe0_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI_VFE0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi_vfe0_clk",
@@ -3237,7 +3147,6 @@
.cbcr_reg = CAMSS_CSI_VFE1_CBCR,
.parent = &vfe1_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_CSI_VFE1_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_csi_vfe1_clk",
@@ -3250,7 +3159,6 @@
.cbcr_reg = CAMSS_GP0_CBCR,
.parent = &mmss_gp0_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_GP0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_gp0_clk",
@@ -3263,7 +3171,6 @@
.cbcr_reg = CAMSS_GP1_CBCR,
.parent = &mmss_gp1_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_GP1_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_gp1_clk",
@@ -3276,7 +3183,6 @@
.cbcr_reg = CAMSS_ISPIF_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_ISPIF_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_ispif_ahb_clk",
@@ -3289,7 +3195,6 @@
.cbcr_reg = CAMSS_JPEG_JPEG0_CBCR,
.parent = &jpeg0_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_JPEG_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_jpeg_jpeg0_clk",
@@ -3302,7 +3207,6 @@
.cbcr_reg = CAMSS_JPEG_JPEG1_CBCR,
.parent = &jpeg1_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_JPEG_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_jpeg_jpeg1_clk",
@@ -3315,7 +3219,6 @@
.cbcr_reg = CAMSS_JPEG_JPEG2_CBCR,
.parent = &jpeg2_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_JPEG_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_jpeg_jpeg2_clk",
@@ -3328,7 +3231,6 @@
.cbcr_reg = CAMSS_JPEG_JPEG_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_JPEG_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_jpeg_jpeg_ahb_clk",
@@ -3341,7 +3243,6 @@
.cbcr_reg = CAMSS_JPEG_JPEG_AXI_CBCR,
.parent = &axi_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_JPEG_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_jpeg_jpeg_axi_clk",
@@ -3353,7 +3254,6 @@
static struct branch_clk camss_jpeg_jpeg_ocmemnoc_clk = {
.cbcr_reg = CAMSS_JPEG_JPEG_OCMEMNOC_CBCR,
.has_sibling = 1,
- .bcr_reg = CAMSS_JPEG_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_jpeg_jpeg_ocmemnoc_clk",
@@ -3366,7 +3266,6 @@
.cbcr_reg = CAMSS_MCLK0_CBCR,
.parent = &mclk0_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_MCLK0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_mclk0_clk",
@@ -3379,7 +3278,6 @@
.cbcr_reg = CAMSS_MCLK1_CBCR,
.parent = &mclk1_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_MCLK1_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_mclk1_clk",
@@ -3392,7 +3290,6 @@
.cbcr_reg = CAMSS_MCLK2_CBCR,
.parent = &mclk2_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_MCLK2_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_mclk2_clk",
@@ -3405,7 +3302,6 @@
.cbcr_reg = CAMSS_MCLK3_CBCR,
.parent = &mclk3_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_MCLK3_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_mclk3_clk",
@@ -3418,7 +3314,6 @@
.cbcr_reg = CAMSS_MICRO_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_MICRO_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_micro_ahb_clk",
@@ -3431,7 +3326,6 @@
.cbcr_reg = CAMSS_PHY0_CSI0PHYTIMER_CBCR,
.parent = &csi0phytimer_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_PHY0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_phy0_csi0phytimer_clk",
@@ -3444,7 +3338,6 @@
.cbcr_reg = CAMSS_PHY1_CSI1PHYTIMER_CBCR,
.parent = &csi1phytimer_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_PHY1_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_phy1_csi1phytimer_clk",
@@ -3457,7 +3350,6 @@
.cbcr_reg = CAMSS_PHY2_CSI2PHYTIMER_CBCR,
.parent = &csi2phytimer_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_PHY2_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_phy2_csi2phytimer_clk",
@@ -3470,7 +3362,6 @@
.cbcr_reg = CAMSS_TOP_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_TOP_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_top_ahb_clk",
@@ -3483,7 +3374,6 @@
.cbcr_reg = CAMSS_VFE_CPP_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_VFE_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_vfe_cpp_ahb_clk",
@@ -3496,7 +3386,6 @@
.cbcr_reg = CAMSS_VFE_CPP_CBCR,
.parent = &cpp_clk_src.c,
.has_sibling = 0,
- .bcr_reg = CAMSS_VFE_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_vfe_cpp_clk",
@@ -3509,7 +3398,6 @@
.cbcr_reg = CAMSS_VFE_VFE0_CBCR,
.parent = &vfe0_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_VFE_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_vfe_vfe0_clk",
@@ -3522,7 +3410,6 @@
.cbcr_reg = CAMSS_VFE_VFE1_CBCR,
.parent = &vfe1_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_VFE_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_vfe_vfe1_clk",
@@ -3535,7 +3422,6 @@
.cbcr_reg = CAMSS_VFE_VFE_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_VFE_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_vfe_vfe_ahb_clk",
@@ -3548,7 +3434,6 @@
.cbcr_reg = CAMSS_VFE_VFE_AXI_CBCR,
.parent = &axi_clk_src.c,
.has_sibling = 1,
- .bcr_reg = CAMSS_VFE_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_vfe_vfe_axi_clk",
@@ -3560,7 +3445,6 @@
static struct branch_clk camss_vfe_vfe_ocmemnoc_clk = {
.cbcr_reg = CAMSS_VFE_VFE_OCMEMNOC_CBCR,
.has_sibling = 1,
- .bcr_reg = CAMSS_VFE_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "camss_vfe_vfe_ocmemnoc_clk",
@@ -3573,7 +3457,6 @@
.cbcr_reg = MDSS_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_ahb_clk",
@@ -3586,7 +3469,6 @@
.cbcr_reg = MDSS_AXI_CBCR,
.parent = &axi_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_axi_clk",
@@ -3599,7 +3481,6 @@
.cbcr_reg = MDSS_BYTE0_CBCR,
.parent = &byte0_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_byte0_clk",
@@ -3612,7 +3493,6 @@
.cbcr_reg = MDSS_BYTE1_CBCR,
.parent = &byte1_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_byte1_clk",
@@ -3625,7 +3505,6 @@
.cbcr_reg = MDSS_EDPAUX_CBCR,
.parent = &edpaux_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_edpaux_clk",
@@ -3638,7 +3517,6 @@
.cbcr_reg = MDSS_EDPLINK_CBCR,
.parent = &edplink_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_edplink_clk",
@@ -3651,7 +3529,6 @@
.cbcr_reg = MDSS_EDPPIXEL_CBCR,
.parent = &edppixel_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_edppixel_clk",
@@ -3664,7 +3541,6 @@
.cbcr_reg = MDSS_ESC0_CBCR,
.parent = &esc0_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_esc0_clk",
@@ -3677,7 +3553,6 @@
.cbcr_reg = MDSS_ESC1_CBCR,
.parent = &esc1_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_esc1_clk",
@@ -3690,7 +3565,6 @@
.cbcr_reg = MDSS_EXTPCLK_CBCR,
.parent = &extpclk_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_extpclk_clk",
@@ -3703,7 +3577,6 @@
.cbcr_reg = MDSS_HDMI_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_hdmi_ahb_clk",
@@ -3716,7 +3589,6 @@
.cbcr_reg = MDSS_HDMI_CBCR,
.parent = &hdmi_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_hdmi_clk",
@@ -3729,7 +3601,6 @@
.cbcr_reg = MDSS_MDP_CBCR,
.parent = &mdp_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_mdp_clk",
@@ -3742,7 +3613,6 @@
.cbcr_reg = MDSS_MDP_LUT_CBCR,
.parent = &mdp_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_mdp_lut_clk",
@@ -3755,7 +3625,6 @@
.cbcr_reg = MDSS_PCLK0_CBCR,
.parent = &pclk0_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_pclk0_clk",
@@ -3768,7 +3637,6 @@
.cbcr_reg = MDSS_PCLK1_CBCR,
.parent = &pclk1_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_pclk1_clk",
@@ -3781,7 +3649,6 @@
.cbcr_reg = MDSS_VSYNC_CBCR,
.parent = &vsync_clk_src.c,
.has_sibling = 0,
- .bcr_reg = MDSS_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mdss_vsync_clk",
@@ -3794,7 +3661,6 @@
.cbcr_reg = MMSS_MISC_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MMSSNOCAHB_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mmss_misc_ahb_clk",
@@ -3807,7 +3673,6 @@
.cbcr_reg = MMSS_MMSSNOC_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MMSSNOCAHB_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mmss_mmssnoc_ahb_clk",
@@ -3820,7 +3685,6 @@
.cbcr_reg = MMSS_MMSSNOC_BTO_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MMSSNOCAHB_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mmss_mmssnoc_bto_ahb_clk",
@@ -3833,7 +3697,6 @@
.cbcr_reg = MMSS_MMSSNOC_AXI_CBCR,
.parent = &axi_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MMSSNOCAXI_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mmss_mmssnoc_axi_clk",
@@ -3846,7 +3709,6 @@
.cbcr_reg = MMSS_S0_AXI_CBCR,
.parent = &axi_clk_src.c,
.has_sibling = 1,
- .bcr_reg = MMSSNOCAXI_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mmss_s0_axi_clk",
@@ -3859,7 +3721,6 @@
.cbcr_reg = VENUS0_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = VENUS0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "venus0_ahb_clk",
@@ -3872,7 +3733,6 @@
.cbcr_reg = VENUS0_AXI_CBCR,
.parent = &axi_clk_src.c,
.has_sibling = 1,
- .bcr_reg = VENUS0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "venus0_axi_clk",
@@ -3884,7 +3744,6 @@
static struct branch_clk venus0_ocmemnoc_clk = {
.cbcr_reg = VENUS0_OCMEMNOC_CBCR,
.has_sibling = 1,
- .bcr_reg = VENUS0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "venus0_ocmemnoc_clk",
@@ -3897,7 +3756,6 @@
.cbcr_reg = VENUS0_VCODEC0_CBCR,
.parent = &vcodec0_clk_src.c,
.has_sibling = 0,
- .bcr_reg = VENUS0_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "venus0_vcodec0_clk",
@@ -3909,7 +3767,6 @@
static struct branch_clk oxili_gfx3d_clk = {
.cbcr_reg = OXILI_GFX3D_CBCR,
.has_sibling = 1,
- .bcr_reg = OXILI_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "oxili_gfx3d_clk",
@@ -3922,7 +3779,6 @@
.cbcr_reg = OXILICX_AHB_CBCR,
.parent = &ahb_clk_src.c,
.has_sibling = 1,
- .bcr_reg = OXILICX_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "oxilicx_ahb_clk",
@@ -3935,7 +3791,6 @@
.cbcr_reg = OXILICX_AXI_CBCR,
.parent = &axi_clk_src.c,
.has_sibling = 1,
- .bcr_reg = OXILICX_BCR,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "oxilicx_axi_clk",
@@ -4370,7 +4225,6 @@
static struct branch_clk mss_bus_q6_clk = {
.cbcr_reg = MSS_BUS_Q6_CBCR,
- .bcr_reg = MSS_Q6SS_BCR,
.has_sibling = 1,
.base = &virt_bases[MSS_BASE],
.c = {
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index e8e88d7..cf45e63 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -462,14 +462,16 @@
}
static int __branch_clk_reset(void __iomem *bcr_reg,
- enum clk_reset_action action)
+ enum clk_reset_action action, const char *name)
{
int ret = 0;
unsigned long flags;
u32 reg_val;
- if (!bcr_reg)
+ if (!bcr_reg) {
+ WARN("clk_reset called on an unsupported clock (%s)\n", name);
return -EPERM;
+ }
spin_lock_irqsave(&local_clock_reg_lock, flags);
reg_val = readl_relaxed(bcr_reg);
@@ -495,7 +497,7 @@
static int branch_clk_reset(struct clk *c, enum clk_reset_action action)
{
struct branch_clk *branch = to_branch_clk(c);
- return __branch_clk_reset(BCR_REG(branch), action);
+ return __branch_clk_reset(BCR_REG(branch), action, c->dbg_name);
}
/*
@@ -503,8 +505,8 @@
*/
static int local_vote_clk_reset(struct clk *c, enum clk_reset_action action)
{
- struct branch_clk *vclk = to_branch_clk(c);
- return __branch_clk_reset(BCR_REG(vclk), action);
+ struct local_vote_clk *vclk = to_local_vote_clk(c);
+ return __branch_clk_reset(BCR_REG(vclk), action, c->dbg_name);
}
static int local_vote_clk_enable(struct clk *c)
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index ef9b62a..1382632 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -850,6 +850,22 @@
},
};
+#define SHARED_IMEM_TZ_BASE 0x2a03f720
+static struct resource tzlog_resources[] = {
+ {
+ .start = SHARED_IMEM_TZ_BASE,
+ .end = SHARED_IMEM_TZ_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device apq_device_tz_log = {
+ .name = "tz_log",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tzlog_resources),
+ .resource = tzlog_resources,
+};
+
/* MSM Video core device */
#ifdef CONFIG_MSM_BUS_SCALING
static struct msm_bus_vectors vidc_init_vectors[] = {
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 76d79a6..85d00eb 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -627,8 +627,7 @@
};
struct flash_platform_data msm_nand_data = {
- .parts = NULL,
- .nr_parts = 0,
+ .version = VERSION_2,
};
struct platform_device msm_device_nand = {
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 2d79f62..4654606 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -417,7 +417,9 @@
},
};
-struct flash_platform_data msm_nand_data;
+struct flash_platform_data msm_nand_data = {
+ .version = VERSION_2,
+};
struct platform_device msm_device_nand = {
.name = "msm_nand",
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 00768a3..de70429 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -655,9 +655,7 @@
};
struct flash_platform_data msm_nand_data = {
- .parts = NULL,
- .nr_parts = 0,
- .interleave = 0,
+ .version = VERSION_2,
};
struct platform_device msm_device_nand = {
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index f8ab18a..f180aa5 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -401,3 +401,5 @@
extern struct platform_device copper_device_tz_log;
extern struct platform_device mdm_sglte_device;
+
+extern struct platform_device apq_device_tz_log;
diff --git a/arch/arm/mach-msm/include/mach/msm_battery.h b/arch/arm/mach-msm/include/mach/msm_battery.h
index c54e7d8..fe496d5 100644
--- a/arch/arm/mach-msm/include/mach/msm_battery.h
+++ b/arch/arm/mach-msm/include/mach/msm_battery.h
@@ -21,6 +21,7 @@
struct msm_psy_batt_pdata {
u32 voltage_max_design;
u32 voltage_min_design;
+ u32 voltage_fail_safe;
u32 avail_chg_sources;
u32 batt_technology;
u32 (*calculate_capacity)(u32 voltage);
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index fec27bd..e7287c1 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -176,7 +176,7 @@
node = rb_entry(p, struct msm_iova_data, node);
if (domain_num < node->domain_num)
p = p->rb_left;
- else if (domain_num > domain_num)
+ else if (domain_num > node->domain_num)
p = p->rb_right;
else {
mutex_unlock(&domain_mutex);
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index 5649784..b2e6490 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -53,6 +53,7 @@
struct delayed_work read_work;
spinlock_t ss_reset_lock; /*Subsystem reset lock*/
int ss_reset;
+ void *pil;
};
struct msm_ipc_router_smd_xprt_work {
@@ -203,10 +204,16 @@
static int msm_ipc_router_smd_remote_close(struct msm_ipc_router_xprt *xprt)
{
+ int rc;
struct msm_ipc_router_smd_xprt *smd_xprtp =
container_of(xprt, struct msm_ipc_router_smd_xprt, xprt);
- return smd_close(smd_xprtp->channel);
+ rc = smd_close(smd_xprtp->channel);
+ if (smd_xprtp->pil) {
+ pil_put(smd_xprtp->pil);
+ smd_xprtp->pil = NULL;
+ }
+ return rc;
}
static void smd_xprt_read_data(struct work_struct *work)
@@ -388,6 +395,23 @@
}
}
+static void *msm_ipc_load_subsystem(uint32_t edge)
+{
+ void *pil = NULL;
+ const char *peripheral;
+
+ peripheral = smd_edge_to_subsystem(edge);
+ if (peripheral) {
+ pil = pil_get(peripheral);
+ if (IS_ERR(pil)) {
+ pr_err("%s: Failed to load %s\n",
+ __func__, peripheral);
+ pil = NULL;
+ }
+ }
+ return pil;
+}
+
static int msm_ipc_router_smd_remote_probe(struct platform_device *pdev)
{
int rc;
@@ -425,6 +449,8 @@
spin_lock_init(&smd_remote_xprt[id].ss_reset_lock);
smd_remote_xprt[id].ss_reset = 0;
+ smd_remote_xprt[id].pil = msm_ipc_load_subsystem(
+ smd_xprt_cfg[id].edge);
rc = smd_named_open_on_edge(smd_xprt_cfg[id].ch_name,
smd_xprt_cfg[id].edge,
&smd_remote_xprt[id].channel,
@@ -433,6 +459,10 @@
if (rc < 0) {
pr_err("%s: Channel open failed for %s\n",
__func__, smd_xprt_cfg[id].ch_name);
+ if (smd_remote_xprt[id].pil) {
+ pil_put(smd_remote_xprt[id].pil);
+ smd_remote_xprt[id].pil = NULL;
+ }
destroy_workqueue(smd_remote_xprt[id].smd_xprt_wq);
return rc;
}
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index b6de881..66bd739 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
+#include <linux/semaphore.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/wakelock.h>
@@ -44,7 +45,9 @@
static int hcismd_set;
-static DEFINE_MUTEX(hci_smd_enable);
+static DEFINE_SEMAPHORE(hci_smd_enable);
+
+static int restart_in_progress;
static int hcismd_set_enable(const char *val, struct kernel_param *kp);
module_param_call(hcismd_set, hcismd_set_enable, NULL, &hcismd_set, 0644);
@@ -497,18 +500,24 @@
static void hci_dev_restart(struct work_struct *worker)
{
- mutex_lock(&hci_smd_enable);
+ down(&hci_smd_enable);
+ restart_in_progress = 1;
hci_smd_deregister_dev(&hs);
hci_smd_register_smd(&hs);
- mutex_unlock(&hci_smd_enable);
+ up(&hci_smd_enable);
kfree(worker);
}
static void hci_dev_smd_open(struct work_struct *worker)
{
- mutex_lock(&hci_smd_enable);
+ down(&hci_smd_enable);
+ if (restart_in_progress == 1) {
+ /* Allow wcnss to initialize */
+ restart_in_progress = 0;
+ msleep(10000);
+ }
hci_smd_hci_register_dev(&hs);
- mutex_unlock(&hci_smd_enable);
+ up(&hci_smd_enable);
kfree(worker);
}
@@ -516,7 +525,9 @@
{
int ret = 0;
- mutex_lock(&hci_smd_enable);
+ pr_err("hcismd_set_enable %d", hcismd_set);
+
+ down(&hci_smd_enable);
ret = param_set_int(val, kp);
@@ -526,7 +537,8 @@
switch (hcismd_set) {
case 1:
- hci_smd_register_smd(&hs);
+ if (hs.hdev == NULL)
+ hci_smd_register_smd(&hs);
break;
case 0:
hci_smd_deregister_dev(&hs);
@@ -536,7 +548,7 @@
}
done:
- mutex_unlock(&hci_smd_enable);
+ up(&hci_smd_enable);
return ret;
}
static int __init hci_smd_init(void)
@@ -545,6 +557,8 @@
"msm_smd_Rx");
wake_lock_init(&hs.wake_lock_tx, WAKE_LOCK_SUSPEND,
"msm_smd_Tx");
+ restart_in_progress = 0;
+ hs.hdev = NULL;
return 0;
}
module_init(hci_smd_init);
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index fff494c..2a191d5 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -352,7 +352,7 @@
}
kzfree(handle);
file->private_data = NULL;
- if (podev->platform_support.bus_scale_table != NULL)
+ if (podev != NULL && podev->platform_support.bus_scale_table != NULL)
qcedev_ce_high_bw_req(podev, false);
return 0;
}
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 168edaa..a41a64b 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -889,7 +889,7 @@
ctx->authsize, 1);
} else {
- unsigned char tmp[SHA256_DIGESTSIZE];
+ unsigned char tmp[SHA256_DIGESTSIZE] = {0};
/* compare icv from src */
scatterwalk_map_and_copy(tmp,
diff --git a/drivers/iommu/msm_iommu_dev.c b/drivers/iommu/msm_iommu_dev.c
index c164825..967283d 100644
--- a/drivers/iommu/msm_iommu_dev.c
+++ b/drivers/iommu/msm_iommu_dev.c
@@ -69,7 +69,7 @@
r.name = ctx_name;
found = device_for_each_child(&msm_iommu_root_dev->dev, &r, each_iommu);
- if (!found || !dev_get_drvdata(r.dev)) {
+ if (found <= 0 || !dev_get_drvdata(r.dev)) {
pr_err("Could not find context <%s>\n", ctx_name);
goto fail;
}
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index a57ad44..e22bc64 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -138,6 +138,9 @@
int (*stop_filtering) (struct dmx_ts_feed* feed);
int (*set_indexing_params) (struct dmx_ts_feed *feed,
struct dmx_indexing_video_params *params);
+ int (*get_decoder_buff_status)(
+ struct dmx_ts_feed *feed,
+ struct dmx_buffer_status *dmx_buffer_status);
};
/*--------------------------------------------------------------------------*/
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 6dfa193..8e5127a 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -849,6 +849,42 @@
spin_lock_irq(&dmxdevfilter->dev->lock);
+ if ((dmxdevfilter->type == DMXDEV_TYPE_PES) &&
+ (dmxdevfilter->params.pes.output == DMX_OUT_DECODER)) {
+ struct dmxdev_feed *feed;
+ int ret;
+
+ /*
+ * Ask for status of decoder's buffer from underlying HW.
+ * In case of PCR/STC extraction, the filter's ring-buffer
+ * is used to gather the PCR/STC data and not using
+ * an internal decoder buffer.
+ */
+ if (!(dmxdevfilter->dev->capabilities &
+ DMXDEV_CAP_PCR_EXTRACTION) ||
+ ((dmxdevfilter->params.pes.pes_type != DMX_PES_PCR0) &&
+ (dmxdevfilter->params.pes.pes_type != DMX_PES_PCR1) &&
+ (dmxdevfilter->params.pes.pes_type != DMX_PES_PCR2) &&
+ (dmxdevfilter->params.pes.pes_type != DMX_PES_PCR3))) {
+ list_for_each_entry(feed, &dmxdevfilter->feed.ts,
+ next) {
+ if (feed->ts->get_decoder_buff_status)
+ ret = feed->ts->get_decoder_buff_status(
+ feed->ts,
+ dmx_buffer_status);
+ else
+ ret = -ENODEV;
+
+ /*
+ * There should not be more than one ts feed
+ * in the list as this is DECODER feed.
+ */
+ spin_unlock_irq(&dmxdevfilter->dev->lock);
+ return ret;
+ }
+ }
+ }
+
dmx_buffer_status->error = buf->error;
if (buf->error)
dvb_ringbuffer_flush(buf);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 0ff2a55..bc72fee 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -1027,6 +1027,32 @@
return ret;
}
+static int dmx_ts_feed_decoder_buff_status(struct dmx_ts_feed *ts_feed,
+ struct dmx_buffer_status *dmx_buffer_status)
+{
+ struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
+ struct dvb_demux *demux = feed->demux;
+ int ret;
+
+ spin_lock_irq(&demux->lock);
+
+ if (feed->state < DMX_STATE_GO) {
+ spin_unlock_irq(&demux->lock);
+ return -EINVAL;
+ }
+
+ if (!demux->decoder_buffer_status) {
+ spin_unlock_irq(&demux->lock);
+ return -ENODEV;
+ }
+
+ ret = demux->decoder_buffer_status(feed, dmx_buffer_status);
+
+ spin_unlock_irq(&demux->lock);
+
+ return ret;
+}
+
static int dmx_ts_set_indexing_params(
struct dmx_ts_feed *ts_feed,
struct dmx_indexing_video_params *params)
@@ -1078,6 +1104,7 @@
(*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
(*ts_feed)->set = dmx_ts_feed_set;
(*ts_feed)->set_indexing_params = dmx_ts_set_indexing_params;
+ (*ts_feed)->get_decoder_buff_status = dmx_ts_feed_decoder_buff_status;
if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
feed->state = DMX_STATE_FREE;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index 17f4960..ebe34ad 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -116,6 +116,8 @@
int (*decoder_fullness_wait)(struct dvb_demux_feed *feed,
size_t required_space);
int (*decoder_fullness_abort)(struct dvb_demux_feed *feed);
+ int (*decoder_buffer_status)(struct dvb_demux_feed *feed,
+ struct dmx_buffer_status *dmx_buffer_status);
u32 (*check_crc32)(struct dvb_demux_feed *feed,
const u8 *buf, size_t len);
void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst,
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
index 03b3929..7223377 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
@@ -719,7 +719,7 @@
int i;
int dvr_index;
int dmx_index;
- struct dvb_demux *dvb_demux = (struct dvb_demux *)demux->priv;
+ struct dvb_demux *dvb_demux = demux->priv;
struct mpq_demux *mpq_demux;
if ((mpq_dmx_info.devices == NULL) || (dvb_demux == NULL)) {
@@ -727,7 +727,7 @@
return -EINVAL;
}
- mpq_demux = (struct mpq_demux *)dvb_demux->priv;
+ mpq_demux = dvb_demux->priv;
if (mpq_demux == NULL) {
MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
return -EINVAL;
@@ -781,8 +781,7 @@
void *packet_buffer;
void *payload_buffer;
struct mpq_video_feed_info *feed_data;
- struct mpq_demux *mpq_demux =
- (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
struct mpq_streambuffer *stream_buffer;
int actual_buffer_size;
@@ -993,11 +992,8 @@
return -EINVAL;
}
- mpq_demux =
- (struct mpq_demux *)feed->demux->priv;
-
- feed_data =
- (struct mpq_video_feed_info *)feed->priv;
+ mpq_demux = feed->demux->priv;
+ feed_data = feed->priv;
spin_lock(&mpq_demux->feed_lock);
feed->priv = NULL;
@@ -1024,10 +1020,7 @@
int mpq_dmx_decoder_fullness_init(struct dvb_demux_feed *feed)
{
- struct mpq_demux *mpq_demux;
-
- mpq_demux =
- (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
if (mpq_dmx_is_video_feed(feed)) {
struct mpq_video_feed_info *feed_data;
@@ -1042,9 +1035,7 @@
return -EINVAL;
}
- feed_data =
- (struct mpq_video_feed_info *)feed->priv;
-
+ feed_data = feed->priv;
feed_data->fullness_wait_cancel = 0;
spin_unlock(&mpq_demux->feed_lock);
@@ -1066,10 +1057,7 @@
struct dvb_demux_feed *feed,
size_t required_space)
{
- struct mpq_demux *mpq_demux;
-
- mpq_demux =
- (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
if (mpq_dmx_is_video_feed(feed)) {
int ret;
@@ -1083,11 +1071,8 @@
return -EINVAL;
}
- feed_data =
- (struct mpq_video_feed_info *)feed->priv;
-
- video_buff =
- &feed_data->video_buffer->raw_data;
+ feed_data = feed->priv;
+ video_buff = &feed_data->video_buffer->raw_data;
ret = 0;
if ((feed_data != NULL) &&
@@ -1145,10 +1130,7 @@
int mpq_dmx_decoder_fullness_abort(struct dvb_demux_feed *feed)
{
- struct mpq_demux *mpq_demux;
-
- mpq_demux =
- (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
if (mpq_dmx_is_video_feed(feed)) {
struct mpq_video_feed_info *feed_data;
@@ -1164,11 +1146,9 @@
return -EINVAL;
}
- feed_data =
- (struct mpq_video_feed_info *)feed->priv;
+ feed_data = feed->priv;
- video_buff =
- &feed_data->video_buffer->raw_data;
+ video_buff = &feed_data->video_buffer->raw_data;
feed_data->fullness_wait_cancel = 1;
spin_unlock(&mpq_demux->feed_lock);
@@ -1402,12 +1382,11 @@
u32 pattern_addr = 0;
int is_video_frame = 0;
- mpq_demux = (struct mpq_demux *)feed->demux->priv;
+ mpq_demux = feed->demux->priv;
spin_lock(&mpq_demux->feed_lock);
- feed_data = (struct mpq_video_feed_info *)feed->priv;
-
+ feed_data = feed->priv;
if (unlikely(feed_data == NULL)) {
spin_unlock(&mpq_demux->feed_lock);
return 0;
@@ -1713,12 +1692,11 @@
struct pes_packet_header *pes_header;
struct mpq_demux *mpq_demux;
- mpq_demux = (struct mpq_demux *)feed->demux->priv;
+ mpq_demux = feed->demux->priv;
spin_lock(&mpq_demux->feed_lock);
- feed_data = (struct mpq_video_feed_info *)feed->priv;
-
+ feed_data = feed->priv;
if (unlikely(feed_data == NULL)) {
spin_unlock(&mpq_demux->feed_lock);
return 0;
@@ -1869,6 +1847,50 @@
return 0;
}
+int mpq_dmx_decoder_buffer_status(struct dvb_demux_feed *feed,
+ struct dmx_buffer_status *dmx_buffer_status)
+{
+ struct mpq_demux *mpq_demux = feed->demux->priv;
+
+ if (mpq_dmx_is_video_feed(feed)) {
+ struct mpq_video_feed_info *feed_data;
+ struct dvb_ringbuffer *video_buff;
+
+ spin_lock(&mpq_demux->feed_lock);
+
+ if (feed->priv == NULL) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: invalid feed, feed->priv is NULL\n",
+ __func__);
+ spin_unlock(&mpq_demux->feed_lock);
+ return -EINVAL;
+ }
+
+ feed_data = feed->priv;
+ video_buff = &feed_data->video_buffer->raw_data;
+
+ dmx_buffer_status->error = video_buff->error;
+ dmx_buffer_status->fullness = dvb_ringbuffer_avail(video_buff);
+ dmx_buffer_status->free_bytes = dvb_ringbuffer_free(video_buff);
+ dmx_buffer_status->read_offset = video_buff->pread;
+ dmx_buffer_status->write_offset = video_buff->pwrite;
+ dmx_buffer_status->size = video_buff->size;
+
+ spin_unlock(&mpq_demux->feed_lock);
+
+ return 0;
+ }
+
+ /* else */
+ MPQ_DVB_ERR_PRINT(
+ "%s: Invalid feed type %d\n",
+ __func__,
+ feed->pes_type);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(mpq_dmx_decoder_buffer_status);
+
int mpq_dmx_process_video_packet(
struct dvb_demux_feed *feed,
const u8 *buf)
@@ -1888,8 +1910,7 @@
u64 pcr;
u64 stc;
u8 output[PCR_STC_LEN];
- struct mpq_demux *mpq_demux =
- (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
const struct ts_packet_header *ts_header;
const struct ts_adaptation_field *adaptation_field;
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
index 0275b14..68cfcd1 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
@@ -426,6 +426,18 @@
struct dvb_demux_feed *feed);
/**
+ * mpq_dmx_decoder_buffer_status - Returns the
+ * status of the decoder's buffer.
+ *
+ * @feed: The decoder's feed
+ * @dmx_buffer_status: Status of decoder's buffer
+ *
+ * Return error code.
+ */
+int mpq_dmx_decoder_buffer_status(struct dvb_demux_feed *feed,
+ struct dmx_buffer_status *dmx_buffer_status);
+
+/**
* mpq_dmx_process_video_packet - Assemble PES data and output it
* to the stream-buffer connected to the decoder.
*
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
index bfd6b96..e7d6b74 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
@@ -414,8 +414,7 @@
static int mpq_tsif_dmx_start_filtering(struct dvb_demux_feed *feed)
{
int ret = 0;
- struct mpq_demux *mpq_demux =
- (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
MPQ_DVB_DBG_PRINT(
"%s(%d) executed\n",
@@ -482,8 +481,7 @@
static int mpq_tsif_dmx_stop_filtering(struct dvb_demux_feed *feed)
{
int ret = 0;
- struct mpq_demux *mpq_demux =
- (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
MPQ_DVB_DBG_PRINT(
"%s(%d) executed\n",
@@ -559,7 +557,7 @@
static int mpq_tsif_dmx_get_caps(struct dmx_demux *demux,
struct dmx_caps *caps)
{
- struct dvb_demux *dvb_demux = (struct dvb_demux *)demux->priv;
+ struct dvb_demux *dvb_demux = demux->priv;
if ((dvb_demux == NULL) || (caps == NULL)) {
MPQ_DVB_ERR_PRINT(
@@ -627,6 +625,9 @@
mpq_demux->demux.decoder_fullness_abort =
mpq_dmx_decoder_fullness_abort;
+ mpq_demux->demux.decoder_buffer_status =
+ mpq_dmx_decoder_buffer_status;
+
/* Initialize dvb_demux object */
result = dvb_dmx_init(&mpq_demux->demux);
if (result < 0) {
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
index a552fdf..f374d91 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
@@ -264,7 +264,7 @@
*/
static int mpq_tspp_dmx_add_channel(struct dvb_demux_feed *feed)
{
- struct mpq_demux *mpq_demux = (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
enum tspp_source tspp_source;
struct tspp_filter tspp_filter;
int tsif;
@@ -455,7 +455,7 @@
int channel_id;
int *channel_ref_count;
struct tspp_filter tspp_filter;
- struct mpq_demux *mpq_demux = (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
/* determine the TSIF we are reading from */
if (mpq_demux->source == DMX_SOURCE_FRONT0) {
@@ -559,8 +559,7 @@
static int mpq_tspp_dmx_start_filtering(struct dvb_demux_feed *feed)
{
int ret;
- struct mpq_demux *mpq_demux =
- (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
MPQ_DVB_DBG_PRINT(
"%s(%d) executed\n",
@@ -620,7 +619,7 @@
static int mpq_tspp_dmx_stop_filtering(struct dvb_demux_feed *feed)
{
int ret = 0;
- struct mpq_demux *mpq_demux = (struct mpq_demux *)feed->demux->priv;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
MPQ_DVB_DBG_PRINT(
"%s(%d) executed\n",
@@ -677,7 +676,7 @@
static int mpq_tspp_dmx_get_caps(struct dmx_demux *demux,
struct dmx_caps *caps)
{
- struct dvb_demux *dvb_demux = (struct dvb_demux *)demux->priv;
+ struct dvb_demux *dvb_demux = demux->priv;
if ((dvb_demux == NULL) || (caps == NULL)) {
MPQ_DVB_ERR_PRINT(
@@ -737,6 +736,9 @@
mpq_demux->demux.decoder_fullness_abort =
mpq_dmx_decoder_fullness_abort;
+ mpq_demux->demux.decoder_buffer_status =
+ mpq_dmx_decoder_buffer_status;
+
/* Initialize dvb_demux object */
result = dvb_dmx_init(&mpq_demux->demux);
if (result < 0) {
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c
index 6c484a0..74b7c22 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c
@@ -62,7 +62,7 @@
static int mpq_tspp_dmx_get_caps(struct dmx_demux *demux,
struct dmx_caps *caps)
{
- struct dvb_demux *dvb_demux = (struct dvb_demux *)demux->priv;
+ struct dvb_demux *dvb_demux = demux->priv;
if ((dvb_demux == NULL) || (caps == NULL)) {
MPQ_DVB_ERR_PRINT(
@@ -124,6 +124,7 @@
mpq_demux->demux.decoder_fullness_init = NULL;
mpq_demux->demux.decoder_fullness_wait = NULL;
mpq_demux->demux.decoder_fullness_abort = NULL;
+ mpq_demux->demux.decoder_buffer_status = NULL;
/* Initialize dvb_demux object */
result = dvb_dmx_init(&mpq_demux->demux);
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index b60f99f..e4d4081 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -11,8 +11,9 @@
EXTRA_CFLAGS += -Idrivers/media/video/msm/eeprom
EXTRA_CFLAGS += -Idrivers/media/video/msm/sensors
EXTRA_CFLAGS += -Idrivers/media/video/msm/actuators
+ EXTRA_CFLAGS += -Idrivers/media/video/msm/server
obj-$(CONFIG_MSM_CAMERA) += msm_isp.o msm.o msm_mem.o msm_mctl.o msm_mctl_buf.o msm_mctl_pp.o
- obj-$(CONFIG_MSM_CAMERA) += io/ eeprom/ sensors/ actuators/ csi/
+ obj-$(CONFIG_MSM_CAMERA) += server/ eeprom/ sensors/ actuators/ csi/
obj-$(CONFIG_MSM_CAMERA) += msm_gesture.o
else
obj-$(CONFIG_MSM_CAMERA) += msm_camera.o
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index 0495b7b..bb2a1d4 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -108,6 +108,8 @@
void __iomem *csidbase;
csid_dev = v4l2_get_subdevdata(cfg_params->subdev);
csidbase = csid_dev->base;
+ if (csidbase == NULL)
+ return -ENOMEM;
csid_params = cfg_params->parms;
val = csid_params->lane_cnt - 1;
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index c384b5a..e25660b 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -69,6 +69,9 @@
void __iomem *csiphybase;
csiphy_dev = v4l2_get_subdevdata(cfg_params->subdev);
csiphybase = csiphy_dev->base;
+ if (csiphybase == NULL)
+ return -ENOMEM;
+
csiphy_params = cfg_params->parms;
lane_mask = csiphy_params->lane_mask;
lane_cnt = csiphy_params->lane_cnt;
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 07db742..09511b1 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -20,13 +20,9 @@
#include <linux/spinlock.h>
#include <linux/proc_fs.h>
#include "msm.h"
-#include "msm_csid.h"
-#include "msm_csic.h"
-#include "msm_csiphy.h"
-#include "msm_ispif.h"
+#include "msm_cam_server.h"
#include "msm_sensor.h"
#include "msm_actuator.h"
-#include "msm_vfe32.h"
#include "msm_camera_eeprom.h"
#define MSM_MAX_CAMERA_SENSORS 5
@@ -38,111 +34,11 @@
#endif
static unsigned msm_camera_v4l2_nr = -1;
-static struct msm_cam_server_dev g_server_dev;
-static struct class *msm_class;
-static dev_t msm_devno;
static int vnode_count;
module_param(msm_camera_v4l2_nr, uint, 0644);
MODULE_PARM_DESC(msm_camera_v4l2_nr, "videoX start number, -1 is autodetect");
-static long msm_server_send_v4l2_evt(void *evt);
-static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
- unsigned int notification, void *arg);
-
-static void msm_queue_init(struct msm_device_queue *queue, const char *name)
-{
- D("%s\n", __func__);
- spin_lock_init(&queue->lock);
- queue->len = 0;
- queue->max = 0;
- queue->name = name;
- INIT_LIST_HEAD(&queue->list);
- init_waitqueue_head(&queue->wait);
-}
-
-static void msm_enqueue(struct msm_device_queue *queue,
- struct list_head *entry)
-{
- unsigned long flags;
- spin_lock_irqsave(&queue->lock, flags);
- queue->len++;
- if (queue->len > queue->max) {
- queue->max = queue->len;
- pr_info("%s: queue %s new max is %d\n", __func__,
- queue->name, queue->max);
- }
- list_add_tail(entry, &queue->list);
- wake_up(&queue->wait);
- D("%s: woke up %s\n", __func__, queue->name);
- spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-static void msm_drain_eventq(struct msm_device_queue *queue)
-{
- unsigned long flags;
- struct msm_queue_cmd *qcmd;
- spin_lock_irqsave(&queue->lock, flags);
- while (!list_empty(&queue->list)) {
- qcmd = list_first_entry(&queue->list,
- struct msm_queue_cmd, list_eventdata);
- list_del_init(&qcmd->list_eventdata);
- kfree(qcmd->command);
- free_qcmd(qcmd);
- }
- spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-static int32_t msm_find_free_queue(void)
-{
- int i;
- for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
- struct msm_cam_server_queue *queue;
- queue = &g_server_dev.server_queue[i];
- if (!queue->queue_active)
- return i;
- }
- return -EINVAL;
-}
-
-uint32_t msm_camera_get_mctl_handle(void)
-{
- uint32_t i;
- if ((g_server_dev.mctl_handle_cnt << 8) == 0)
- g_server_dev.mctl_handle_cnt++;
- for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
- if (g_server_dev.mctl[i].handle == 0) {
- g_server_dev.mctl[i].handle =
- (++g_server_dev.mctl_handle_cnt) << 8 | i;
- memset(&g_server_dev.mctl[i].mctl,
- 0, sizeof(g_server_dev.mctl[i].mctl));
- return g_server_dev.mctl[i].handle;
- }
- }
- return 0;
-}
-
-struct msm_cam_media_controller *msm_camera_get_mctl(uint32_t handle)
-{
- uint32_t mctl_index;
- mctl_index = handle & 0xff;
- if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
- (g_server_dev.mctl[mctl_index].handle == handle))
- return &g_server_dev.mctl[mctl_index].mctl;
- return NULL;
-}
-
-void msm_camera_free_mctl(uint32_t handle)
-{
- uint32_t mctl_index;
- mctl_index = handle & 0xff;
- if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
- (g_server_dev.mctl[mctl_index].handle == handle))
- g_server_dev.mctl[mctl_index].handle = 0;
- else
- pr_err("%s: invalid free handle\n", __func__);
-}
-
/* callback function from all subdevices of a msm_cam_v4l2_device */
static void msm_cam_v4l2_subdev_notify(struct v4l2_subdev *sd,
unsigned int notification, void *arg)
@@ -158,664 +54,11 @@
if (pcam == NULL)
return;
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
if (pmctl == NULL)
return;
}
-static int msm_ctrl_cmd_done(void *arg)
-{
- void __user *uptr;
- struct msm_queue_cmd *qcmd;
- struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
- struct msm_ctrl_cmd *command =
- kzalloc(sizeof(struct msm_ctrl_cmd), GFP_KERNEL);
- if (!command) {
- pr_err("%s Insufficient memory. return", __func__);
- return -ENOMEM;
- }
-
- D("%s\n", __func__);
- if (copy_from_user(command, (void __user *)ioctl_ptr->ioctl_ptr,
- sizeof(struct msm_ctrl_cmd))) {
- pr_err("%s: copy_from_user failed, size=%d\n",
- __func__, sizeof(struct msm_ctrl_cmd));
- return -EINVAL;
- }
-
- D("%s qid %d evtid %d %d\n", __func__, command->queue_idx,
- command->evt_id,
- g_server_dev.server_queue[command->queue_idx].evt_id);
- g_server_dev.server_queue[command->queue_idx].ctrl = command;
- if (command->evt_id !=
- g_server_dev.server_queue[command->queue_idx].evt_id) {
- pr_err("%s Invalid event id from userspace cmd id %d %d qid %d\n",
- __func__, command->evt_id,
- g_server_dev.server_queue[command->queue_idx].evt_id,
- command->queue_idx);
- return -EINVAL;
- }
-
- mutex_lock(&g_server_dev.server_queue_lock);
- qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
- atomic_set(&qcmd->on_heap, 1);
- uptr = command->value;
- qcmd->command = command;
-
- if (command->length > 0) {
- command->value =
- g_server_dev.server_queue[command->queue_idx].ctrl_data;
- if (command->length > max_control_command_size) {
- pr_err("%s: user data %d is too big (max %d)\n",
- __func__, command->length,
- max_control_command_size);
- free_qcmd(qcmd);
- return -EINVAL;
- }
- if (copy_from_user(command->value, uptr, command->length)) {
- free_qcmd(qcmd);
- return -EINVAL;
- }
- }
- msm_enqueue(&g_server_dev.server_queue
- [command->queue_idx].ctrl_q, &qcmd->list_control);
- mutex_unlock(&g_server_dev.server_queue_lock);
- return 0;
-}
-
-/* send control command to config and wait for results*/
-static int msm_server_control(struct msm_cam_server_dev *server_dev,
- struct msm_ctrl_cmd *out)
-{
- int rc = 0;
- void *value;
- struct msm_queue_cmd *rcmd;
- struct msm_queue_cmd *event_qcmd;
- struct msm_ctrl_cmd *ctrlcmd;
- struct msm_device_queue *queue =
- &server_dev->server_queue[out->queue_idx].ctrl_q;
-
- struct v4l2_event v4l2_evt;
- struct msm_isp_event_ctrl *isp_event;
- isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
- if (!isp_event) {
- pr_err("%s Insufficient memory. return", __func__);
- return -ENOMEM;
- }
- event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
- if (!event_qcmd) {
- pr_err("%s Insufficient memory. return", __func__);
- return -ENOMEM;
- }
-
- D("%s\n", __func__);
- mutex_lock(&server_dev->server_queue_lock);
- if (++server_dev->server_evt_id == 0)
- server_dev->server_evt_id++;
- D("%s qid %d evtid %d\n", __func__, out->queue_idx,
- server_dev->server_evt_id);
-
- server_dev->server_queue[out->queue_idx].evt_id =
- server_dev->server_evt_id;
- v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_V4L2;
- v4l2_evt.id = 0;
- v4l2_evt.u.data[0] = out->queue_idx;
- /* setup event object to transfer the command; */
- isp_event->resptype = MSM_CAM_RESP_V4L2;
- isp_event->isp_data.ctrl = *out;
- isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
-
- atomic_set(&event_qcmd->on_heap, 1);
- event_qcmd->command = isp_event;
-
- msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
- &event_qcmd->list_eventdata);
-
- /* now send command to config thread in userspace,
- * and wait for results */
- v4l2_event_queue(server_dev->server_command_queue.pvdev,
- &v4l2_evt);
- D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
- mutex_unlock(&server_dev->server_queue_lock);
-
- /* wait for config return status */
- D("Waiting for config status\n");
- rc = wait_event_interruptible_timeout(queue->wait,
- !list_empty_careful(&queue->list),
- msecs_to_jiffies(out->timeout_ms));
- D("Waiting is over for config status\n");
- if (list_empty_careful(&queue->list)) {
- if (!rc)
- rc = -ETIMEDOUT;
- if (rc < 0) {
- kfree(isp_event);
- pr_err("%s: wait_event error %d\n", __func__, rc);
- return rc;
- }
- }
-
- rcmd = msm_dequeue(queue, list_control);
- BUG_ON(!rcmd);
- D("%s Finished servicing ioctl\n", __func__);
-
- ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
- value = out->value;
- if (ctrlcmd->length > 0 && value != NULL &&
- ctrlcmd->length <= out->length)
- memcpy(value, ctrlcmd->value, ctrlcmd->length);
-
- memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
- out->value = value;
-
- kfree(ctrlcmd);
- server_dev->server_queue[out->queue_idx].ctrl = NULL;
-
- free_qcmd(rcmd);
- kfree(isp_event);
- D("%s: rc %d\n", __func__, rc);
- /* rc is the time elapsed. */
- if (rc >= 0) {
- /* TODO: Refactor msm_ctrl_cmd::status field */
- if (out->status == 0)
- rc = -1;
- else if (out->status == 1 || out->status == 4)
- rc = 0;
- else
- rc = -EINVAL;
- }
- return rc;
-}
-
-/*send open command to server*/
-static int msm_send_open_server(struct msm_cam_v4l2_device *pcam)
-{
- int rc = 0;
- struct msm_ctrl_cmd ctrlcmd;
- D("%s qid %d\n", __func__, pcam->server_queue_idx);
- ctrlcmd.type = MSM_V4L2_OPEN;
- ctrlcmd.timeout_ms = 10000;
- ctrlcmd.length = strnlen(g_server_dev.config_info.config_dev_name[0],
- MAX_DEV_NAME_LEN)+1;
- ctrlcmd.value = (char *)g_server_dev.config_info.config_dev_name[0];
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
- /* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
- return rc;
-}
-
-static int msm_send_close_server(struct msm_cam_v4l2_device *pcam)
-{
- int rc = 0;
- struct msm_ctrl_cmd ctrlcmd;
- D("%s qid %d\n", __func__, pcam->server_queue_idx);
- ctrlcmd.type = MSM_V4L2_CLOSE;
- ctrlcmd.timeout_ms = 10000;
- ctrlcmd.length = strnlen(g_server_dev.config_info.config_dev_name[0],
- MAX_DEV_NAME_LEN)+1;
- ctrlcmd.value = (char *)g_server_dev.config_info.config_dev_name[0];
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
- /* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
- return rc;
-}
-
-static int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
- struct v4l2_format *pfmt)
-{
- int rc = 0;
- int i = 0;
- struct v4l2_pix_format *pix = &pfmt->fmt.pix;
- struct msm_ctrl_cmd ctrlcmd;
- struct img_plane_info plane_info;
-
- plane_info.width = pix->width;
- plane_info.height = pix->height;
- plane_info.pixelformat = pix->pixelformat;
- plane_info.buffer_type = pfmt->type;
- plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
- plane_info.num_planes = 1;
- D("%s: %d, %d, 0x%x\n", __func__,
- pfmt->fmt.pix.width, pfmt->fmt.pix.height,
- pfmt->fmt.pix.pixelformat);
-
- if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- D("%s, Attention! Wrong buf-type %d\n", __func__, pfmt->type);
-
- for (i = 0; i < pcam->num_fmts; i++)
- if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
- break;
- if (i == pcam->num_fmts) {
- pr_err("%s: User requested pixelformat %x not supported\n",
- __func__, pix->pixelformat);
- return -EINVAL;
- }
-
- ctrlcmd.type = MSM_V4L2_VID_CAP_TYPE;
- ctrlcmd.length = sizeof(struct img_plane_info);
- ctrlcmd.value = (void *)&plane_info;
- ctrlcmd.timeout_ms = 10000;
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
- /* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
- if (rc >= 0) {
- pcam->dev_inst[idx]->vid_fmt = *pfmt;
- pcam->dev_inst[idx]->sensor_pxlcode
- = pcam->usr_fmts[i].pxlcode;
- D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
- __func__, (u32)pcam->dev_inst[idx], idx,
- pcam->dev_inst[idx]->vid_fmt.fmt.pix.width,
- pcam->dev_inst[idx]->vid_fmt.fmt.pix.height);
- pcam->dev_inst[idx]->plane_info = plane_info;
- }
-
- return rc;
-}
-
-static int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
- struct v4l2_format *pfmt)
-{
- int rc = 0;
- int i = 0;
- struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
- struct msm_ctrl_cmd ctrlcmd;
- struct img_plane_info plane_info;
-
- plane_info.width = pix_mp->width;
- plane_info.height = pix_mp->height;
- plane_info.pixelformat = pix_mp->pixelformat;
- plane_info.buffer_type = pfmt->type;
- plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
- plane_info.num_planes = pix_mp->num_planes;
- if (plane_info.num_planes <= 0 ||
- plane_info.num_planes > VIDEO_MAX_PLANES) {
- pr_err("%s Invalid number of planes set %d", __func__,
- plane_info.num_planes);
- return -EINVAL;
- }
- D("%s: %d, %d, 0x%x\n", __func__,
- pfmt->fmt.pix_mp.width, pfmt->fmt.pix_mp.height,
- pfmt->fmt.pix_mp.pixelformat);
-
- if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- pr_err("%s, Attention! Wrong buf-type %d\n",
- __func__, pfmt->type);
- return -EINVAL;
- }
-
- for (i = 0; i < pcam->num_fmts; i++)
- if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
- break;
- if (i == pcam->num_fmts) {
- pr_err("%s: User requested pixelformat %x not supported\n",
- __func__, pix_mp->pixelformat);
- return -EINVAL;
- }
-
- ctrlcmd.type = MSM_V4L2_VID_CAP_TYPE;
- ctrlcmd.length = sizeof(struct img_plane_info);
- ctrlcmd.value = (void *)&plane_info;
- ctrlcmd.timeout_ms = 10000;
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
-
- /* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
- if (rc >= 0) {
- pcam->dev_inst[idx]->vid_fmt = *pfmt;
- pcam->dev_inst[idx]->sensor_pxlcode
- = pcam->usr_fmts[i].pxlcode;
- D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
- __func__, (u32)pcam->dev_inst[idx], idx,
- pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.width,
- pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.height);
- pcam->dev_inst[idx]->plane_info = plane_info;
- }
-
- return rc;
-}
-
-static int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx)
-{
- int rc = 0;
- struct msm_ctrl_cmd ctrlcmd;
- D("%s\n", __func__);
- ctrlcmd.type = MSM_V4L2_STREAM_ON;
- ctrlcmd.timeout_ms = 10000;
- ctrlcmd.length = 0;
- ctrlcmd.value = NULL;
- ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-
- /* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
- return rc;
-}
-
-static int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx)
-{
- int rc = 0;
- struct msm_ctrl_cmd ctrlcmd;
-
- D("%s, pcam = 0x%x\n", __func__, (u32)pcam);
- ctrlcmd.type = MSM_V4L2_STREAM_OFF;
- ctrlcmd.timeout_ms = 10000;
- ctrlcmd.length = 0;
- ctrlcmd.value = NULL;
- ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
- /* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
- return rc;
-}
-
-static int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
- struct v4l2_control *ctrl, int is_set_cmd)
-{
- int rc = 0;
- struct msm_ctrl_cmd ctrlcmd, *tmp_cmd;
- uint8_t *ctrl_data = NULL;
- void __user *uptr_cmd;
- void __user *uptr_value;
- uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
- uint32_t value_len;
-
- tmp_cmd = (struct msm_ctrl_cmd *)ctrl->value;
- uptr_cmd = (void __user *)ctrl->value;
- uptr_value = (void __user *)tmp_cmd->value;
- value_len = tmp_cmd->length;
-
- D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
- __func__, tmp_cmd->type, (uint32_t)uptr_cmd, cmd_len,
- (uint32_t)uptr_value, tmp_cmd->length);
-
- ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
- if (ctrl_data == 0) {
- pr_err("%s could not allocate memory\n", __func__);
- rc = -ENOMEM;
- goto end;
- }
- tmp_cmd = (struct msm_ctrl_cmd *)ctrl_data;
- if (copy_from_user((void *)ctrl_data, uptr_cmd,
- cmd_len)) {
- pr_err("%s: copy_from_user failed.\n", __func__);
- rc = -EINVAL;
- goto end;
- }
- tmp_cmd->value = (void *)(ctrl_data+cmd_len);
- if (uptr_value && tmp_cmd->length > 0) {
- if (copy_from_user((void *)tmp_cmd->value, uptr_value,
- value_len)) {
- pr_err("%s: copy_from_user failed, size=%d\n",
- __func__, value_len);
- rc = -EINVAL;
- goto end;
- }
- } else
- tmp_cmd->value = NULL;
-
- ctrlcmd.type = MSM_V4L2_SET_CTRL_CMD;
- ctrlcmd.length = cmd_len + value_len;
- ctrlcmd.value = (void *)ctrl_data;
- if (tmp_cmd->timeout_ms > 0)
- ctrlcmd.timeout_ms = tmp_cmd->timeout_ms;
- else
- ctrlcmd.timeout_ms = 1000;
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
- /* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
- D("%s: msm_server_control rc=%d\n", __func__, rc);
- if (rc == 0) {
- if (uptr_value && tmp_cmd->length > 0 &&
- copy_to_user((void __user *)uptr_value,
- (void *)(ctrl_data+cmd_len), tmp_cmd->length)) {
- pr_err("%s: copy_to_user failed, size=%d\n",
- __func__, tmp_cmd->length);
- rc = -EINVAL;
- goto end;
- }
- tmp_cmd->value = uptr_value;
- if (copy_to_user((void __user *)uptr_cmd,
- (void *)tmp_cmd, cmd_len)) {
- pr_err("%s: copy_to_user failed in cpy, size=%d\n",
- __func__, cmd_len);
- rc = -EINVAL;
- goto end;
- }
- }
-end:
- D("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
- __func__, tmp_cmd->type, (uint32_t)tmp_cmd->value,
- tmp_cmd->length, tmp_cmd->status, rc);
- kfree(ctrl_data);
- return rc;
-}
-
-static int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
- struct v4l2_control *ctrl)
-{
- int rc = 0;
- struct msm_ctrl_cmd ctrlcmd;
- uint8_t ctrl_data[max_control_command_size];
-
- WARN_ON(ctrl == NULL);
- if (ctrl == NULL) {
- pr_err("%s Invalid control\n", __func__);
- return -EINVAL;
- }
- if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
- return msm_server_proc_ctrl_cmd(pcam, ctrl, 1);
-
- memset(ctrl_data, 0, sizeof(ctrl_data));
-
- ctrlcmd.type = MSM_V4L2_SET_CTRL;
- ctrlcmd.length = sizeof(struct v4l2_control);
- ctrlcmd.value = (void *)ctrl_data;
- memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
- ctrlcmd.timeout_ms = 1000;
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
- /* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
- return rc;
-}
-
-static int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
- struct v4l2_control *ctrl)
-{
- int rc = 0;
- struct msm_ctrl_cmd ctrlcmd;
- uint8_t ctrl_data[max_control_command_size];
-
- WARN_ON(ctrl == NULL);
- if (ctrl == NULL) {
- pr_err("%s Invalid control\n", __func__);
- return -EINVAL;
- }
- if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
- return msm_server_proc_ctrl_cmd(pcam, ctrl, 0);
-
- memset(ctrl_data, 0, sizeof(ctrl_data));
-
- ctrlcmd.type = MSM_V4L2_GET_CTRL;
- ctrlcmd.length = sizeof(struct v4l2_control);
- ctrlcmd.value = (void *)ctrl_data;
- memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
- ctrlcmd.timeout_ms = 1000;
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
- /* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
- ctrl->value = ((struct v4l2_control *)ctrlcmd.value)->value;
-
- return rc;
-}
-
-static int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
- struct v4l2_queryctrl *queryctrl)
-{
- int rc = 0;
- struct msm_ctrl_cmd ctrlcmd;
- uint8_t ctrl_data[max_control_command_size];
-
- WARN_ON(queryctrl == NULL);
- memset(ctrl_data, 0, sizeof(ctrl_data));
-
- ctrlcmd.type = MSM_V4L2_QUERY_CTRL;
- ctrlcmd.length = sizeof(struct v4l2_queryctrl);
- ctrlcmd.value = (void *)ctrl_data;
- memcpy(ctrlcmd.value, queryctrl, ctrlcmd.length);
- ctrlcmd.timeout_ms = 1000;
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
- /* send command to config thread in userspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
- D("%s: rc = %d\n", __func__, rc);
-
- if (rc >= 0)
- memcpy(queryctrl, ctrlcmd.value, sizeof(struct v4l2_queryctrl));
-
- return rc;
-}
-
-static int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
- int idx, struct v4l2_format *pfmt)
-{
- struct v4l2_pix_format *pix = &pfmt->fmt.pix;
-
- pix->width = pcam->dev_inst[idx]->vid_fmt.fmt.pix.width;
- pix->height = pcam->dev_inst[idx]->vid_fmt.fmt.pix.height;
- pix->field = pcam->dev_inst[idx]->vid_fmt.fmt.pix.field;
- pix->pixelformat = pcam->dev_inst[idx]->vid_fmt.fmt.pix.pixelformat;
- pix->bytesperline = pcam->dev_inst[idx]->vid_fmt.fmt.pix.bytesperline;
- pix->colorspace = pcam->dev_inst[idx]->vid_fmt.fmt.pix.colorspace;
- if (pix->bytesperline < 0)
- return pix->bytesperline;
-
- pix->sizeimage = pix->height * pix->bytesperline;
-
- return 0;
-}
-
-static int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
- int idx, struct v4l2_format *pfmt)
-{
- *pfmt = pcam->dev_inst[idx]->vid_fmt;
- return 0;
-}
-
-static int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
- struct v4l2_format *pfmt)
-{
- int rc = 0;
- int i = 0;
- struct v4l2_pix_format *pix = &pfmt->fmt.pix;
-
- D("%s: 0x%x\n", __func__, pix->pixelformat);
- if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- pr_err("%s: pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE!\n",
- __func__);
- return -EINVAL;
- }
-
- /* check if the format is supported by this host-sensor combo */
- for (i = 0; i < pcam->num_fmts; i++) {
- D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
- pcam->usr_fmts[i].fourcc);
- if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
- break;
- }
-
- if (i == pcam->num_fmts) {
- pr_err("%s: Format %x not found\n", __func__, pix->pixelformat);
- return -EINVAL;
- }
- return rc;
-}
-
-static int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
- struct v4l2_format *pfmt)
-{
- int rc = 0;
- int i = 0;
- struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
-
- D("%s: 0x%x\n", __func__, pix_mp->pixelformat);
- if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- pr_err("%s: Incorrect format type %d ",
- __func__, pfmt->type);
- return -EINVAL;
- }
-
- /* check if the format is supported by this host-sensor combo */
- for (i = 0; i < pcam->num_fmts; i++) {
- D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
- pcam->usr_fmts[i].fourcc);
- if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
- break;
- }
-
- if (i == pcam->num_fmts) {
- pr_err("%s: Format %x not found\n",
- __func__, pix_mp->pixelformat);
- return -EINVAL;
- }
- return rc;
-}
-
-static int msm_camera_get_crop(struct msm_cam_v4l2_device *pcam,
- int idx, struct v4l2_crop *crop)
-{
- int rc = 0;
- struct msm_ctrl_cmd ctrlcmd;
-
- BUG_ON(crop == NULL);
-
- ctrlcmd.type = MSM_V4L2_GET_CROP;
- ctrlcmd.length = sizeof(struct v4l2_crop);
- ctrlcmd.value = (void *)crop;
- ctrlcmd.timeout_ms = 1000;
- ctrlcmd.vnode_id = pcam->vnode_id;
- ctrlcmd.queue_idx = pcam->server_queue_idx;
- ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
- ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
- /* send command to config thread in userspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
- D("%s: rc = %d\n", __func__, rc);
-
- return rc;
-}
-
/*
*
* implementation of v4l2_ioctl_ops
@@ -1117,7 +360,7 @@
not in use when we free the buffers */
mutex_lock(&pcam->vid_lock);
pcam_inst->streamon = 0;
- if (g_server_dev.use_count > 0)
+ if (msm_server_get_usecount() > 0)
rc = msm_server_streamoff(pcam, pcam_inst->my_index);
mutex_unlock(&pcam->vid_lock);
if (rc < 0)
@@ -1261,7 +504,7 @@
(void *)pfmt->fmt.pix.priv);
WARN_ON(pctx != f->private_data);
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
if (pmctl == NULL)
return -EINVAL;
@@ -1296,7 +539,7 @@
D("%s Inst %p\n", __func__, pcam_inst);
WARN_ON(pctx != f->private_data);
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
if (pmctl == NULL)
return -EINVAL;
@@ -1349,7 +592,7 @@
WARN_ON(pctx != f->private_data);
mutex_lock(&pcam->vid_lock);
- rc = msm_camera_get_crop(pcam, pcam_inst->my_index, crop);
+ rc = msm_server_get_crop(pcam, pcam_inst->my_index, crop);
mutex_unlock(&pcam->vid_lock);
return rc;
}
@@ -1442,55 +685,6 @@
return rc;
}
-static int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- int rc = 0;
-
- D("%s: fh = 0x%x, type = 0x%x", __func__, (u32)fh, sub->type);
- if (sub->type == V4L2_EVENT_ALL) {
- /*sub->type = MSM_ISP_EVENT_START;*/
- sub->type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_CTRL;
- D("sub->type start = 0x%x\n", sub->type);
- do {
- rc = v4l2_event_subscribe(fh, sub, 30);
- if (rc < 0) {
- D("%s: failed for evtType = 0x%x, rc = %d\n",
- __func__, sub->type, rc);
- /* unsubscribe all events here and return */
- sub->type = V4L2_EVENT_ALL;
- v4l2_event_unsubscribe(fh, sub);
- return rc;
- } else
- D("%s: subscribed evtType = 0x%x, rc = %d\n",
- __func__, sub->type, rc);
- sub->type++;
- D("sub->type while = 0x%x\n", sub->type);
- } while (sub->type !=
- V4L2_EVENT_PRIVATE_START + MSM_SVR_RESP_MAX);
- } else {
- D("sub->type not V4L2_EVENT_ALL = 0x%x\n", sub->type);
- rc = v4l2_event_subscribe(fh, sub, 30);
- if (rc < 0)
- D("%s: failed for evtType = 0x%x, rc = %d\n",
- __func__, sub->type, rc);
- }
-
- D("%s: rc = %d\n", __func__, rc);
- return rc;
-}
-
-static int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- int rc = 0;
-
- D("%s: fh = 0x%x\n", __func__, (u32)fh);
- rc = v4l2_event_unsubscribe(fh, sub);
- D("%s: rc = %d\n", __func__, rc);
- return rc;
-}
-
/* v4l2_ioctl_ops */
static const struct v4l2_ioctl_ops g_msm_ioctl_ops = {
.vidioc_querycap = msm_camera_v4l2_querycap,
@@ -1532,214 +726,10 @@
.vidioc_unsubscribe_event = msm_camera_v4l2_unsubscribe_event,
};
-/* open an active camera session to manage the streaming logic */
-static int msm_cam_server_open_session(struct msm_cam_server_dev *ps,
- struct msm_cam_v4l2_device *pcam)
-{
- int rc = 0;
- struct msm_cam_media_controller *pmctl;
-
- D("%s\n", __func__);
-
- if (!ps || !pcam) {
- pr_err("%s NULL pointer passed in!\n", __func__);
- return rc;
- }
-
- /* The number of camera instance should be controlled by the
- resource manager. Currently supporting one active instance
- until multiple instances are supported */
- if (atomic_read(&ps->number_pcam_active) > 0) {
- pr_err("%s Cannot have more than one active camera %d\n",
- __func__, atomic_read(&ps->number_pcam_active));
- return -EINVAL;
- }
- /* book keeping this camera session*/
- ps->pcam_active = pcam;
- atomic_inc(&ps->number_pcam_active);
-
- D("config pcam = 0x%p\n", ps->pcam_active);
-
- /* initialization the media controller module*/
- msm_mctl_init(pcam);
-
- /*for single VFE msms (8660, 8960v1), just populate the session
- with our VFE devices that registered*/
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
- pmctl->axi_sdev = ps->axi_device[0];
- pmctl->isp_sdev = ps->isp_subdev[0];
- return rc;
-}
-
-/* close an active camera session to server */
-static int msm_cam_server_close_session(struct msm_cam_server_dev *ps,
- struct msm_cam_v4l2_device *pcam)
-{
- int rc = 0;
- D("%s\n", __func__);
-
- if (!ps || !pcam) {
- D("%s NULL pointer passed in!\n", __func__);
- return rc;
- }
-
-
- atomic_dec(&ps->number_pcam_active);
- ps->pcam_active = NULL;
-
- msm_mctl_free(pcam);
- return rc;
-}
-
-int msm_server_open_client(int *p_qidx)
-{
- int rc = 0;
- int server_q_idx = 0;
- struct msm_cam_server_queue *queue = NULL;
-
- mutex_lock(&g_server_dev.server_lock);
- server_q_idx = msm_find_free_queue();
- if (server_q_idx < 0) {
- mutex_unlock(&g_server_dev.server_lock);
- return server_q_idx;
- }
-
- *p_qidx = server_q_idx;
- queue = &g_server_dev.server_queue[server_q_idx];
- queue->ctrl = NULL;
- queue->ctrl_data = kzalloc(sizeof(uint8_t) *
- max_control_command_size, GFP_KERNEL);
- msm_queue_init(&queue->ctrl_q, "control");
- msm_queue_init(&queue->eventData_q, "eventdata");
- queue->queue_active = 1;
- mutex_unlock(&g_server_dev.server_lock);
- return rc;
-}
-
-int msm_server_send_ctrl(struct msm_ctrl_cmd *out,
- int ctrl_id)
-{
- int rc = 0;
- void *value;
- struct msm_queue_cmd *rcmd;
- struct msm_queue_cmd *event_qcmd;
- struct msm_ctrl_cmd *ctrlcmd;
- struct msm_cam_server_dev *server_dev = &g_server_dev;
- struct msm_device_queue *queue =
- &server_dev->server_queue[out->queue_idx].ctrl_q;
-
- struct v4l2_event v4l2_evt;
- struct msm_isp_event_ctrl *isp_event;
- isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
- if (!isp_event) {
- pr_err("%s Insufficient memory. return", __func__);
- return -ENOMEM;
- }
- event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
- if (!event_qcmd) {
- pr_err("%s Insufficient memory. return", __func__);
- kfree(isp_event);
- return -ENOMEM;
- }
-
- D("%s\n", __func__);
- mutex_lock(&server_dev->server_queue_lock);
- if (++server_dev->server_evt_id == 0)
- server_dev->server_evt_id++;
-
- D("%s qid %d evtid %d\n", __func__, out->queue_idx,
- server_dev->server_evt_id);
- server_dev->server_queue[out->queue_idx].evt_id =
- server_dev->server_evt_id;
- v4l2_evt.type = V4L2_EVENT_PRIVATE_START + ctrl_id;
- v4l2_evt.id = 0;
- v4l2_evt.u.data[0] = out->queue_idx;
- /* setup event object to transfer the command; */
- isp_event->resptype = MSM_CAM_RESP_V4L2;
- isp_event->isp_data.ctrl = *out;
- isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
-
- atomic_set(&event_qcmd->on_heap, 1);
- event_qcmd->command = isp_event;
-
- msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
- &event_qcmd->list_eventdata);
-
- /* now send command to config thread in userspace,
- * and wait for results */
- v4l2_event_queue(server_dev->server_command_queue.pvdev,
- &v4l2_evt);
- D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
- mutex_unlock(&server_dev->server_queue_lock);
-
- /* wait for config return status */
- D("Waiting for config status\n");
- rc = wait_event_interruptible_timeout(queue->wait,
- !list_empty_careful(&queue->list),
- msecs_to_jiffies(out->timeout_ms));
- D("Waiting is over for config status\n");
- if (list_empty_careful(&queue->list)) {
- if (!rc)
- rc = -ETIMEDOUT;
- if (rc < 0) {
- kfree(isp_event);
- pr_err("%s: wait_event error %d\n", __func__, rc);
- return rc;
- }
- }
-
- rcmd = msm_dequeue(queue, list_control);
- BUG_ON(!rcmd);
- D("%s Finished servicing ioctl\n", __func__);
-
- ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
- value = out->value;
- if (ctrlcmd->length > 0)
- memcpy(value, ctrlcmd->value, ctrlcmd->length);
-
- memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
- out->value = value;
-
- kfree(ctrlcmd);
- server_dev->server_queue[out->queue_idx].ctrl = NULL;
-
- free_qcmd(rcmd);
- kfree(isp_event);
- D("%s: rc %d\n", __func__, rc);
- /* rc is the time elapsed. */
- if (rc >= 0) {
- /* TODO: Refactor msm_ctrl_cmd::status field */
- if (out->status == 0)
- rc = -1;
- else if (out->status == 1 || out->status == 4)
- rc = 0;
- else
- rc = -EINVAL;
- }
- return rc;
-}
-
-int msm_server_close_client(int idx)
-{
- int rc = 0;
- struct msm_cam_server_queue *queue = NULL;
- mutex_lock(&g_server_dev.server_lock);
- queue = &g_server_dev.server_queue[idx];
- queue->queue_active = 0;
- kfree(queue->ctrl);
- queue->ctrl = NULL;
- kfree(queue->ctrl_data);
- queue->ctrl_data = NULL;
- msm_queue_drain(&queue->ctrl_q, list_control);
- msm_drain_eventq(&queue->eventData_q);
- mutex_unlock(&g_server_dev.server_lock);
- return rc;
-}
/* v4l2_file_operations */
static int msm_open(struct file *f)
{
- int i;
- int rc = -EINVAL;
+ int i, rc = -EINVAL;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
int ion_client_created = 0;
#endif
@@ -1749,7 +739,6 @@
struct msm_cam_v4l2_device *pcam = video_drvdata(f);
struct msm_cam_v4l2_dev_inst *pcam_inst;
struct msm_cam_media_controller *pmctl = NULL;
- struct msm_cam_server_queue *queue = NULL;
D("%s\n", __func__);
@@ -1757,7 +746,7 @@
pr_err("%s NULL pointer passed in!\n", __func__);
return rc;
}
- if (!g_server_dev.use_count) {
+ if (!msm_server_get_usecount()) {
pr_err("%s: error, daemon not yet started.", __func__);
return -EINVAL;
}
@@ -1792,28 +781,12 @@
pcam->use_count++;
D("%s use_count %d\n", __func__, pcam->use_count);
if (pcam->use_count == 1) {
- int ges_evt = MSM_V4L2_GES_CAM_OPEN;
- pcam->server_queue_idx = server_q_idx;
- queue = &g_server_dev.server_queue[server_q_idx];
- queue->ctrl = NULL;
- queue->ctrl_data = kzalloc(sizeof(uint8_t) *
- max_control_command_size, GFP_KERNEL);
- msm_queue_init(&queue->ctrl_q, "control");
- msm_queue_init(&queue->eventData_q, "eventdata");
- queue->queue_active = 1;
-
- pr_err("%s send gesture evt\n", __func__);
- msm_cam_server_subdev_notify(g_server_dev.gesture_device,
- NOTIFY_GESTURE_CAM_EVT, &ges_evt);
-
- rc = msm_cam_server_open_session(&g_server_dev, pcam);
+ rc = msm_server_begin_session(pcam, server_q_idx);
if (rc < 0) {
- pr_err("%s: cam_server_open_session failed %d\n",
- __func__, rc);
- goto msm_cam_server_open_session_failed;
+ pr_err("%s error starting server session ", __func__);
+ goto msm_cam_server_begin_session_failed;
}
-
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
pmctl->client = msm_ion_client_create(-1, "camera");
@@ -1855,14 +828,14 @@
if (pcam->use_count == 1) {
rc = msm_send_open_server(pcam);
- if (rc < 0) {
+ if (rc < 0 && rc != -ERESTARTSYS) {
pr_err("%s: msm_send_open_server failed %d\n",
__func__, rc);
goto msm_send_open_server_failed;
}
}
mutex_unlock(&pcam->vid_lock);
- D("%s: end", __func__);
+ D("%s: end\n", __func__);
return rc;
msm_send_open_server_failed:
@@ -1876,25 +849,16 @@
if (pcam->use_count == 1) {
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
if (ion_client_created) {
- pr_err("%s: destroy ion client", __func__);
+ D("%s: destroy ion client", __func__);
kref_put(&pmctl->refcount, msm_release_ion_client);
}
#endif
- if (msm_cam_server_close_session(&g_server_dev, pcam) < 0)
- pr_err("%s: msm_cam_server_close_session failed\n",
+ if (msm_server_end_session(pcam) < 0)
+ pr_err("%s: msm_server_end_session failed\n",
__func__);
}
-msm_cam_server_open_session_failed:
+msm_cam_server_begin_session_failed:
if (pcam->use_count == 1) {
- if (queue != NULL) {
- queue->queue_active = 0;
- msm_drain_eventq(&queue->eventData_q);
- kfree(queue->ctrl_data);
- queue->ctrl_data = NULL;
- msm_queue_drain(&queue->ctrl_q, list_control);
- msm_drain_eventq(&queue->eventData_q);
- queue = NULL;
- }
pcam->dev_inst[i] = NULL;
pcam->use_count = 0;
}
@@ -1904,73 +868,6 @@
return rc;
}
-int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam)
-{
- int rc = 0;
- struct msm_cam_media_controller *pmctl = NULL;
-
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
- if (!pmctl) {
- D("%s: invalid handle\n", __func__);
- return -ENODEV;
- }
-
- if (pmctl->mctl_release) {
- rc = pmctl->mctl_release(pmctl);
- if (rc < 0)
- pr_err("mctl_release fails %d\n", rc);
- }
-
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- kref_put(&pmctl->refcount, msm_release_ion_client);
-#endif
-
- rc = msm_cam_server_close_session(&g_server_dev, pcam);
- if (rc < 0)
- pr_err("msm_cam_server_close_session fails %d\n", rc);
-
- return rc;
-}
-
-int msm_cam_server_open_mctl_session(struct msm_cam_v4l2_device *pcam,
- int *p_active)
-{
- int rc = 0;
- struct msm_cam_media_controller *pmctl = NULL;
- D("%s: %p", __func__, g_server_dev.pcam_active);
- *p_active = 0;
- if (g_server_dev.pcam_active) {
- D("%s: Active camera present return", __func__);
- return 0;
- }
- rc = msm_cam_server_open_session(&g_server_dev, pcam);
- if (rc < 0) {
- pr_err("%s: cam_server_open_session failed %d\n",
- __func__, rc);
- return rc;
- }
-
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
- /* Should be set to sensor ops if any but right now its OK!! */
- if (!pmctl->mctl_open) {
- D("%s: media contoller is not inited\n",
- __func__);
- rc = -ENODEV;
- return rc;
- }
-
- D("%s: call mctl_open\n", __func__);
- rc = pmctl->mctl_open(pmctl, MSM_APPS_ID_V4L2);
-
- if (rc < 0) {
- pr_err("%s: HW open failed rc = 0x%x\n", __func__, rc);
- return rc;
- }
- pmctl->pcam_ptr = pcam;
- *p_active = 1;
- return rc;
-}
-
static int msm_addr_remap(struct msm_cam_v4l2_dev_inst *pcam_inst,
struct vm_area_struct *vma)
{
@@ -1980,7 +877,7 @@
int rc = 0;
struct msm_cam_media_controller *mctl;
- mctl = msm_camera_get_mctl(pcam_inst->pcam->mctl_handle);
+ mctl = msm_cam_server_get_mctl(pcam_inst->pcam->mctl_handle);
if (!mctl) {
pr_err("%s: invalid mctl pointer", __func__);
return -EFAULT;
@@ -2038,8 +935,8 @@
void msm_release_ion_client(struct kref *ref)
{
struct msm_cam_media_controller *mctl = container_of(ref,
- struct msm_cam_media_controller, refcount);
- pr_err("%s Calling ion_client_destroy ", __func__);
+ struct msm_cam_media_controller, refcount);
+ pr_err("%s Calling ion_client_destroy\n", __func__);
ion_client_destroy(mctl->client);
}
@@ -2048,7 +945,6 @@
int rc = 0;
struct msm_cam_v4l2_device *pcam;
struct msm_cam_v4l2_dev_inst *pcam_inst;
- struct msm_cam_server_queue *queue;
struct msm_cam_media_controller *pmctl;
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
@@ -2058,7 +954,7 @@
return -EINVAL;
}
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
if (!pmctl) {
pr_err("%s NULL mctl pointer\n", __func__);
return -EINVAL;
@@ -2094,37 +990,24 @@
f->private_data = NULL;
if (pcam->use_count == 0) {
- int ges_evt = MSM_V4L2_GES_CAM_CLOSE;
- if (g_server_dev.use_count > 0) {
+ if (msm_server_get_usecount() > 0) {
rc = msm_send_close_server(pcam);
if (rc < 0)
pr_err("msm_send_close_server failed %d\n", rc);
}
+
if (pmctl->mctl_release) {
rc = pmctl->mctl_release(pmctl);
if (rc < 0)
pr_err("mctl_release fails %d\n", rc);
}
+
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
kref_put(&pmctl->refcount, msm_release_ion_client);
#endif
- queue = &g_server_dev.server_queue[pcam->server_queue_idx];
- queue->queue_active = 0;
- kfree(queue->ctrl);
- queue->ctrl = NULL;
- kfree(queue->ctrl_data);
- queue->ctrl_data = NULL;
- msm_queue_drain(&queue->ctrl_q, list_control);
- msm_drain_eventq(&queue->eventData_q);
- rc = msm_cam_server_close_session(&g_server_dev, pcam);
+ rc = msm_server_end_session(pcam);
if (rc < 0)
- pr_err("msm_cam_server_close_session fails %d\n", rc);
-
- if (g_server_dev.use_count == 0)
- mutex_unlock(&g_server_dev.server_lock);
-
- msm_cam_server_subdev_notify(g_server_dev.gesture_device,
- NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+ pr_err("msm_server_end_session fails %d\n", rc);
}
mutex_unlock(&pcam->vid_lock);
return rc;
@@ -2159,281 +1042,8 @@
return rc;
}
-static unsigned int msm_poll_server(struct file *fp,
- struct poll_table_struct *wait)
-{
- int rc = 0;
-
- D("%s\n", __func__);
- poll_wait(fp,
- &g_server_dev.server_command_queue.eventHandle.wait,
- wait);
- if (v4l2_event_pending(&g_server_dev.server_command_queue.eventHandle))
- rc |= POLLPRI;
-
- return rc;
-}
-static long msm_ioctl_server(struct file *file, void *fh,
- bool valid_prio, int cmd, void *arg)
-{
- int rc = -EINVAL;
- struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
- struct msm_camera_info temp_cam_info;
- struct msm_cam_config_dev_info temp_config_info;
- struct msm_mctl_node_info temp_mctl_info;
- int i;
-
- D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
-
- switch (cmd) {
- case MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO:
- if (copy_from_user(&temp_cam_info,
- (void __user *)ioctl_ptr->ioctl_ptr,
- sizeof(struct msm_camera_info))) {
- rc = -EINVAL;
- return rc;
- }
- for (i = 0; i < g_server_dev.camera_info.num_cameras; i++) {
- if (copy_to_user((void __user *)
- temp_cam_info.video_dev_name[i],
- g_server_dev.camera_info.video_dev_name[i],
- strnlen(
- g_server_dev.camera_info.video_dev_name[i],
- MAX_DEV_NAME_LEN))) {
- rc = -EINVAL;
- return rc;
- }
- temp_cam_info.has_3d_support[i] =
- g_server_dev.camera_info.has_3d_support[i];
- temp_cam_info.is_internal_cam[i] =
- g_server_dev.camera_info.is_internal_cam[i];
- temp_cam_info.s_mount_angle[i] =
- g_server_dev.camera_info.s_mount_angle[i];
- temp_cam_info.sensor_type[i] =
- g_server_dev.camera_info.sensor_type[i];
-
- }
- temp_cam_info.num_cameras =
- g_server_dev.camera_info.num_cameras;
- if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
- &temp_cam_info,
- sizeof(struct msm_camera_info))) {
- rc = -EINVAL;
- return rc;
- }
- rc = 0;
- break;
-
- case MSM_CAM_V4L2_IOCTL_GET_CONFIG_INFO:
- if (copy_from_user(&temp_config_info,
- (void __user *)ioctl_ptr->ioctl_ptr,
- sizeof(struct msm_cam_config_dev_info))) {
-
- rc = -EINVAL;
- return rc;
- }
- for (i = 0;
- i < g_server_dev.config_info.num_config_nodes; i++) {
- if (copy_to_user(
- (void __user *)temp_config_info.config_dev_name[i],
- g_server_dev.config_info.config_dev_name[i],
- strlen(g_server_dev.config_info.config_dev_name[i]))) {
- rc = -EINVAL;
- return rc;
- }
- }
- temp_config_info.num_config_nodes =
- g_server_dev.config_info.num_config_nodes;
- if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
- &temp_config_info,
- sizeof(struct msm_cam_config_dev_info))) {
- rc = -EINVAL;
- return rc;
- }
- rc = 0;
- break;
- case MSM_CAM_V4L2_IOCTL_GET_MCTL_INFO:
- if (copy_from_user(&temp_mctl_info,
- (void __user *)ioctl_ptr->ioctl_ptr,
- sizeof(struct msm_mctl_node_info))) {
- rc = -EINVAL;
- return rc;
- }
- for (i = 0; i < g_server_dev.mctl_node_info.num_mctl_nodes;
- i++) {
- if (copy_to_user((void __user *)
- temp_mctl_info.mctl_node_name[i],
- g_server_dev.mctl_node_info.mctl_node_name[i], strnlen(
- g_server_dev.mctl_node_info.mctl_node_name[i],
- MAX_DEV_NAME_LEN))) {
- rc = -EINVAL;
- return rc;
- }
- }
- temp_mctl_info.num_mctl_nodes =
- g_server_dev.mctl_node_info.num_mctl_nodes;
- if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
- &temp_mctl_info,
- sizeof(struct msm_mctl_node_info))) {
- rc = -EINVAL;
- return rc;
- }
- rc = 0;
- break;
-
- case MSM_CAM_V4L2_IOCTL_CTRL_CMD_DONE:
- D("%s: MSM_CAM_IOCTL_CTRL_CMD_DONE\n", __func__);
- rc = msm_ctrl_cmd_done(arg);
- break;
-
- case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
- struct msm_queue_cmd *event_cmd;
- struct msm_isp_event_ctrl u_isp_event;
- struct msm_isp_event_ctrl *k_isp_event;
- struct msm_device_queue *queue;
- void __user *u_ctrl_value = NULL;
- if (copy_from_user(&u_isp_event,
- (void __user *)ioctl_ptr->ioctl_ptr,
- sizeof(struct msm_isp_event_ctrl))) {
- rc = -EINVAL;
- return rc;
- }
- queue = &g_server_dev.server_queue
- [u_isp_event.isp_data.ctrl.queue_idx].eventData_q;
- event_cmd = msm_dequeue(queue, list_eventdata);
- if (!event_cmd) {
- pr_err("%s: No event payload\n", __func__);
- rc = -EINVAL;
- return rc;
- }
- k_isp_event = (struct msm_isp_event_ctrl *)
- event_cmd->command;
- free_qcmd(event_cmd);
-
- /* Save the pointer of the user allocated command buffer*/
- u_ctrl_value = u_isp_event.isp_data.ctrl.value;
-
- /* Copy the event structure into user struct*/
- u_isp_event = *k_isp_event;
-
- /* Restore the saved pointer of the user
- * allocated command buffer. */
- u_isp_event.isp_data.ctrl.value = u_ctrl_value;
-
- /* Copy the ctrl cmd, if present*/
- if (k_isp_event->isp_data.ctrl.length > 0) {
- void *k_ctrl_value =
- k_isp_event->isp_data.ctrl.value;
- if (copy_to_user(u_ctrl_value, k_ctrl_value,
- k_isp_event->isp_data.ctrl.length)) {
- rc = -EINVAL;
- break;
- }
- }
- if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
- &u_isp_event,
- sizeof(struct msm_isp_event_ctrl))) {
- rc = -EINVAL;
- return rc;
- }
- rc = 0;
- break;
- }
-
- case MSM_CAM_IOCTL_SEND_EVENT:
- rc = msm_server_send_v4l2_evt(arg);
- break;
-
- default:
- pr_err("%s: Invalid IOCTL = %d", __func__, cmd);
- break;
- }
- return rc;
-}
-
-static int msm_open_server(struct file *fp)
-{
- int rc = 0;
- D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
- mutex_lock(&g_server_dev.server_lock);
- g_server_dev.use_count++;
- if (g_server_dev.use_count == 1)
- fp->private_data =
- &g_server_dev.server_command_queue.eventHandle;
- mutex_unlock(&g_server_dev.server_lock);
- return rc;
-}
-
-static unsigned int msm_poll_config(struct file *fp,
- struct poll_table_struct *wait)
-{
- int rc = 0;
- struct msm_cam_config_dev *config = fp->private_data;
- if (config == NULL)
- return -EINVAL;
-
- D("%s\n", __func__);
-
- poll_wait(fp,
- &config->config_stat_event_queue.eventHandle.wait, wait);
- if (v4l2_event_pending(&config->config_stat_event_queue.eventHandle))
- rc |= POLLPRI;
- return rc;
-}
-
-static int msm_close_server(struct file *fp)
-{
- struct v4l2_event_subscription sub;
- D("%s\n", __func__);
- mutex_lock(&g_server_dev.server_lock);
- if (g_server_dev.use_count > 0)
- g_server_dev.use_count--;
- mutex_unlock(&g_server_dev.server_lock);
- if (g_server_dev.use_count == 0) {
- if (g_server_dev.pcam_active) {
- struct v4l2_event v4l2_ev;
- mutex_lock(&g_server_dev.server_lock);
-
- v4l2_ev.type = V4L2_EVENT_PRIVATE_START
- + MSM_CAM_APP_NOTIFY_ERROR_EVENT;
- v4l2_ev.id = 0;
- ktime_get_ts(&v4l2_ev.timestamp);
- v4l2_event_queue(
- g_server_dev.pcam_active->pvdev, &v4l2_ev);
- }
- sub.type = V4L2_EVENT_ALL;
- msm_server_v4l2_unsubscribe_event(
- &g_server_dev.server_command_queue.eventHandle, &sub);
- }
- return 0;
-}
-
-static long msm_server_send_v4l2_evt(void *evt)
-{
- struct v4l2_event *v4l2_ev = (struct v4l2_event *)evt;
- int rc = 0;
- v4l2_ev->id = 0;
- if (NULL == evt) {
- pr_err("%s: evt is NULL\n", __func__);
- return -EINVAL;
- }
-
- D("%s: evt type 0x%x\n", __func__, v4l2_ev->type);
- if ((v4l2_ev->type >= MSM_GES_APP_EVT_MIN) &&
- (v4l2_ev->type < MSM_GES_APP_EVT_MAX)) {
- msm_cam_server_subdev_notify(g_server_dev.gesture_device,
- NOTIFY_GESTURE_EVT, v4l2_ev);
- } else {
- pr_err("%s: Invalid evt %d\n", __func__, v4l2_ev->type);
- rc = -EINVAL;
- }
- D("%s: end\n", __func__);
-
- return rc;
-}
-
-static long msm_v4l2_evt_notify(struct msm_cam_media_controller *mctl,
- unsigned int cmd, unsigned long evt)
+long msm_v4l2_evt_notify(struct msm_cam_media_controller *mctl,
+ unsigned int cmd, unsigned long evt)
{
struct v4l2_event v4l2_ev;
struct msm_cam_v4l2_device *pcam = NULL;
@@ -2456,280 +1066,6 @@
return 0;
}
-static long msm_ioctl_config(struct file *fp, unsigned int cmd,
- unsigned long arg)
-{
-
- int rc = 0;
- struct v4l2_event ev;
- struct msm_cam_config_dev *config_cam = fp->private_data;
- struct v4l2_event_subscription temp_sub;
- ev.id = 0;
- D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
-
- switch (cmd) {
- /* memory management shall be handeld here*/
- case MSM_CAM_IOCTL_REGISTER_PMEM:
- return msm_register_pmem(
- &config_cam->p_mctl->stats_info.pmem_stats_list,
- (void __user *)arg, config_cam->p_mctl->client);
- break;
-
- case MSM_CAM_IOCTL_UNREGISTER_PMEM:
- return msm_pmem_table_del(
- &config_cam->p_mctl->stats_info.pmem_stats_list,
- (void __user *)arg, config_cam->p_mctl->client);
- break;
-
- case VIDIOC_SUBSCRIBE_EVENT:
- if (copy_from_user(&temp_sub,
- (void __user *)arg,
- sizeof(struct v4l2_event_subscription))) {
- rc = -EINVAL;
- return rc;
- }
- rc = msm_server_v4l2_subscribe_event
- (&config_cam->config_stat_event_queue.eventHandle,
- &temp_sub);
- if (rc < 0) {
- pr_err("%s: cam_v4l2_subscribe_event failed rc=%d\n",
- __func__, rc);
- return rc;
- }
- break;
-
- case VIDIOC_UNSUBSCRIBE_EVENT:
- if (copy_from_user(&temp_sub, (void __user *)arg,
- sizeof(struct v4l2_event_subscription))) {
- rc = -EINVAL;
- return rc;
- }
- rc = msm_server_v4l2_unsubscribe_event
- (&config_cam->config_stat_event_queue.eventHandle,
- &temp_sub);
- if (rc < 0) {
- pr_err("%s: server_unsubscribe_event failed rc=%d\n",
- __func__, rc);
- return rc;
- }
- break;
-
- case VIDIOC_DQEVENT: {
- void __user *u_msg_value = NULL, *user_ptr = NULL;
- struct msm_isp_event_ctrl u_isp_event;
- struct msm_isp_event_ctrl *k_isp_event;
-
- /* First, copy the v4l2 event structure from userspace */
- D("%s: VIDIOC_DQEVENT\n", __func__);
- if (copy_from_user(&ev, (void __user *)arg,
- sizeof(struct v4l2_event)))
- break;
- /* Next, get the pointer to event_ctrl structure
- * embedded inside the v4l2_event.u.data array. */
- user_ptr = (void __user *)(*((uint32_t *)ev.u.data));
-
- /* Next, copy the userspace event ctrl structure */
- if (copy_from_user((void *)&u_isp_event, user_ptr,
- sizeof(struct msm_isp_event_ctrl))) {
- break;
- }
- /* Save the pointer of the user allocated command buffer*/
- u_msg_value = u_isp_event.isp_data.isp_msg.data;
-
- /* Dequeue the event queued into the v4l2 queue*/
- rc = v4l2_event_dequeue(
- &config_cam->config_stat_event_queue.eventHandle,
- &ev, fp->f_flags & O_NONBLOCK);
- if (rc < 0) {
- pr_err("no pending events?");
- break;
- }
- /* Use k_isp_event to point to the event_ctrl structure
- * embedded inside v4l2_event.u.data */
- k_isp_event = (struct msm_isp_event_ctrl *)
- (*((uint32_t *)ev.u.data));
- /* Copy the event structure into user struct. */
- u_isp_event = *k_isp_event;
- if (ev.type != (V4L2_EVENT_PRIVATE_START +
- MSM_CAM_RESP_DIV_FRAME_EVT_MSG) &&
- ev.type != (V4L2_EVENT_PRIVATE_START +
- MSM_CAM_RESP_MCTL_PP_EVENT)) {
-
- /* Restore the saved pointer of the
- * user allocated command buffer. */
- u_isp_event.isp_data.isp_msg.data = u_msg_value;
-
- if (ev.type == (V4L2_EVENT_PRIVATE_START +
- MSM_CAM_RESP_STAT_EVT_MSG)) {
- if (k_isp_event->isp_data.isp_msg.len > 0) {
- void *k_msg_value =
- k_isp_event->isp_data.isp_msg.data;
- if (copy_to_user(u_msg_value,
- k_msg_value,
- k_isp_event->isp_data.isp_msg.len)) {
- rc = -EINVAL;
- break;
- }
- kfree(k_msg_value);
- }
- }
- }
- /* Copy the event ctrl structure back
- * into user's structure. */
- if (copy_to_user(user_ptr,
- (void *)&u_isp_event, sizeof(
- struct msm_isp_event_ctrl))) {
- rc = -EINVAL;
- break;
- }
- kfree(k_isp_event);
-
- /* Copy the v4l2_event structure back to the user*/
- if (copy_to_user((void __user *)arg, &ev,
- sizeof(struct v4l2_event))) {
- rc = -EINVAL;
- break;
- }
- }
-
- break;
-
- case MSM_CAM_IOCTL_V4L2_EVT_NOTIFY:
- rc = msm_v4l2_evt_notify(config_cam->p_mctl, cmd, arg);
- break;
-
- case MSM_CAM_IOCTL_SET_MEM_MAP_INFO:
- if (copy_from_user(&config_cam->mem_map, (void __user *)arg,
- sizeof(struct msm_mem_map_info)))
- rc = -EINVAL;
- break;
-
- default:{
- /* For the rest of config command, forward to media controller*/
- struct msm_cam_media_controller *p_mctl = config_cam->p_mctl;
- if (p_mctl && p_mctl->mctl_cmd) {
- rc = config_cam->p_mctl->mctl_cmd(p_mctl, cmd, arg);
- } else {
- rc = -EINVAL;
- pr_err("%s: media controller is null\n", __func__);
- }
-
- break;
- } /* end of default*/
- } /* end of switch*/
- return rc;
-}
-
-static int msm_mmap_config(struct file *fp, struct vm_area_struct *vma)
-{
- struct msm_cam_config_dev *config_cam = fp->private_data;
- int rc = 0;
- int phyaddr;
- int retval;
- unsigned long size;
-
- D("%s: phy_addr=0x%x", __func__, config_cam->mem_map.cookie);
- phyaddr = (int)config_cam->mem_map.cookie;
- if (!phyaddr) {
- pr_err("%s: no physical memory to map", __func__);
- return -EFAULT;
- }
- memset(&config_cam->mem_map, 0,
- sizeof(struct msm_mem_map_info));
- size = vma->vm_end - vma->vm_start;
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- retval = remap_pfn_range(vma, vma->vm_start,
- phyaddr >> PAGE_SHIFT,
- size, vma->vm_page_prot);
- if (retval) {
- pr_err("%s: remap failed, rc = %d",
- __func__, retval);
- rc = -ENOMEM;
- goto end;
- }
- D("%s: phy_addr=0x%x: %08lx-%08lx, pgoff %08lx\n",
- __func__, (uint32_t)phyaddr,
- vma->vm_start, vma->vm_end, vma->vm_pgoff);
-end:
- return rc;
-}
-
-static int msm_open_config(struct inode *inode, struct file *fp)
-{
- int rc;
- struct msm_cam_config_dev *config_cam = container_of(inode->i_cdev,
- struct msm_cam_config_dev, config_cdev);
-
- D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
-
- rc = nonseekable_open(inode, fp);
- if (rc < 0) {
- pr_err("%s: nonseekable_open error %d\n", __func__, rc);
- return rc;
- }
- config_cam->use_count++;
-
- /*config_cam->isp_subdev = g_server_dev.pcam_active->mctl.isp_sdev;*/
- /* assume there is only one active camera possible*/
- config_cam->p_mctl =
- msm_camera_get_mctl(g_server_dev.pcam_active->mctl_handle);
-
- INIT_HLIST_HEAD(&config_cam->p_mctl->stats_info.pmem_stats_list);
- spin_lock_init(&config_cam->p_mctl->stats_info.pmem_stats_spinlock);
-
- config_cam->p_mctl->config_device = config_cam;
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- kref_get(&config_cam->p_mctl->refcount);
-#endif
- fp->private_data = config_cam;
- return rc;
-}
-
-static int msm_close_config(struct inode *node, struct file *f)
-{
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- struct msm_cam_config_dev *config_cam = f->private_data;
- D("%s Decrementing ref count of config node ", __func__);
- kref_put(&config_cam->p_mctl->refcount, msm_release_ion_client);
-#endif
- return 0;
-}
-
-static struct v4l2_file_operations g_msm_fops = {
- .owner = THIS_MODULE,
- .open = msm_open,
- .poll = msm_poll,
- .mmap = msm_mmap,
- .release = msm_close,
- .ioctl = video_ioctl2,
-};
-
-/* Init a config node for ISP control,
- * which will create a config device (/dev/config0/ and plug in
- * ISP's operation "v4l2_ioctl_ops*"
- */
-static const struct v4l2_file_operations msm_fops_server = {
- .owner = THIS_MODULE,
- .open = msm_open_server,
- .poll = msm_poll_server,
- .unlocked_ioctl = video_ioctl2,
- .release = msm_close_server,
-};
-
-static const struct v4l2_ioctl_ops msm_ioctl_ops_server = {
- .vidioc_subscribe_event = msm_server_v4l2_subscribe_event,
- .vidioc_default = msm_ioctl_server,
-};
-
-static const struct file_operations msm_fops_config = {
- .owner = THIS_MODULE,
- .open = msm_open_config,
- .poll = msm_poll_config,
- .unlocked_ioctl = msm_ioctl_config,
- .mmap = msm_mmap_config,
- .release = msm_close_config,
-};
-
int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
struct video_device *pvdev)
{
@@ -2743,340 +1079,14 @@
return rc;
}
-static int msm_setup_config_dev(int node, char *device_name)
-{
- int rc = -ENODEV;
- struct device *device_config;
- int dev_num = node;
- dev_t devno;
- struct msm_cam_config_dev *config_cam;
-
- config_cam = kzalloc(sizeof(*config_cam), GFP_KERNEL);
- if (!config_cam) {
- pr_err("%s: could not allocate memory for msm_cam_config_device\n",
- __func__);
- return -ENOMEM;
- }
-
- D("%s\n", __func__);
-
- devno = MKDEV(MAJOR(msm_devno), dev_num+1);
- device_config = device_create(msm_class, NULL, devno, NULL, "%s%d",
- device_name, dev_num);
-
- if (IS_ERR(device_config)) {
- rc = PTR_ERR(device_config);
- pr_err("%s: error creating device: %d\n", __func__, rc);
- goto config_setup_fail;
- }
-
- cdev_init(&config_cam->config_cdev, &msm_fops_config);
- config_cam->config_cdev.owner = THIS_MODULE;
-
- rc = cdev_add(&config_cam->config_cdev, devno, 1);
- if (rc < 0) {
- pr_err("%s: error adding cdev: %d\n", __func__, rc);
- device_destroy(msm_class, devno);
- goto config_setup_fail;
- }
-
- g_server_dev.config_info.config_dev_name[dev_num] =
- dev_name(device_config);
- D("%s Connected config device %s\n", __func__,
- g_server_dev.config_info.config_dev_name[dev_num]);
- g_server_dev.config_info.config_dev_id[dev_num] = dev_num;
-
- config_cam->config_stat_event_queue.pvdev = video_device_alloc();
- if (config_cam->config_stat_event_queue.pvdev == NULL) {
- pr_err("%s: video_device_alloc failed\n", __func__);
- goto config_setup_fail;
- }
-
- rc = msm_setup_v4l2_event_queue(
- &config_cam->config_stat_event_queue.eventHandle,
- config_cam->config_stat_event_queue.pvdev);
- if (rc < 0) {
- pr_err("%s failed to initialize event queue\n", __func__);
- video_device_release(config_cam->config_stat_event_queue.pvdev);
- goto config_setup_fail;
- }
-
- return rc;
-
-config_setup_fail:
- kfree(config_cam);
- return rc;
-}
-
-static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
- unsigned int notification, void *arg)
-{
- int rc = -EINVAL;
- struct msm_sensor_ctrl_t *s_ctrl;
- struct msm_camera_sensor_info *sinfo;
- struct msm_camera_device_platform_data *camdev;
- uint8_t csid_core = 0;
-
- if (notification == NOTIFY_CID_CHANGE ||
- notification == NOTIFY_ISPIF_STREAM ||
- notification == NOTIFY_PCLK_CHANGE ||
- notification == NOTIFY_CSIPHY_CFG ||
- notification == NOTIFY_CSID_CFG ||
- notification == NOTIFY_CSIC_CFG) {
- s_ctrl = get_sctrl(sd);
- sinfo = (struct msm_camera_sensor_info *) s_ctrl->sensordata;
- camdev = sinfo->pdata;
- csid_core = camdev->csid_core;
- }
-
- switch (notification) {
- case NOTIFY_CID_CHANGE:
- /* reconfig the ISPIF*/
- if (g_server_dev.ispif_device) {
- struct msm_ispif_params_list ispif_params;
- ispif_params.len = 1;
- ispif_params.params[0].intftype = PIX0;
- ispif_params.params[0].cid_mask = 0x0001;
- ispif_params.params[0].csid = csid_core;
-
- rc = v4l2_subdev_call(
- g_server_dev.ispif_device, core, ioctl,
- VIDIOC_MSM_ISPIF_CFG, &ispif_params);
- if (rc < 0)
- return;
- }
- break;
- case NOTIFY_ISPIF_STREAM:
- /* call ISPIF stream on/off */
- rc = v4l2_subdev_call(g_server_dev.ispif_device, video,
- s_stream, (int)arg);
- if (rc < 0)
- return;
-
- break;
- case NOTIFY_ISP_MSG_EVT:
- case NOTIFY_VFE_MSG_OUT:
- case NOTIFY_VFE_MSG_STATS:
- case NOTIFY_VFE_MSG_COMP_STATS:
- case NOTIFY_VFE_BUF_EVT:
- case NOTIFY_VFE_BUF_FREE_EVT:
- if (g_server_dev.isp_subdev[0] &&
- g_server_dev.isp_subdev[0]->isp_notify) {
- rc = g_server_dev.isp_subdev[0]->isp_notify(
- g_server_dev.vfe_device[0], notification, arg);
- }
- break;
- case NOTIFY_VPE_MSG_EVT: {
- struct msm_cam_media_controller *pmctl =
- (struct msm_cam_media_controller *)
- v4l2_get_subdev_hostdata(sd);
- struct msm_vpe_resp *vdata = (struct msm_vpe_resp *)arg;
- msm_mctl_pp_notify(pmctl,
- (struct msm_mctl_pp_frame_info *)
- vdata->extdata);
- break;
- }
- case NOTIFY_VFE_IRQ:{
- struct msm_vfe_cfg_cmd cfg_cmd;
- struct msm_camvfe_params vfe_params;
- cfg_cmd.cmd_type = CMD_VFE_PROCESS_IRQ;
- vfe_params.vfe_cfg = &cfg_cmd;
- vfe_params.data = arg;
- rc = v4l2_subdev_call(g_server_dev.vfe_device[0],
- core, ioctl, 0, &vfe_params);
- }
- break;
- case NOTIFY_AXI_IRQ:
- rc = v4l2_subdev_call(g_server_dev.axi_device[0],
- core, ioctl, VIDIOC_MSM_AXI_IRQ, arg);
- break;
- case NOTIFY_PCLK_CHANGE:
- if (g_server_dev.axi_device[0])
- rc = v4l2_subdev_call(g_server_dev.axi_device[0], video,
- s_crystal_freq, *(uint32_t *)arg, 0);
- else
- rc = v4l2_subdev_call(g_server_dev.vfe_device[0], video,
- s_crystal_freq, *(uint32_t *)arg, 0);
- break;
- case NOTIFY_CSIPHY_CFG:
- rc = v4l2_subdev_call(g_server_dev.csiphy_device[csid_core],
- core, ioctl, VIDIOC_MSM_CSIPHY_CFG, arg);
- break;
- case NOTIFY_CSID_CFG:
- rc = v4l2_subdev_call(g_server_dev.csid_device[csid_core],
- core, ioctl, VIDIOC_MSM_CSID_CFG, arg);
- break;
- case NOTIFY_CSIC_CFG:
- rc = v4l2_subdev_call(g_server_dev.csic_device[csid_core],
- core, ioctl, VIDIOC_MSM_CSIC_CFG, arg);
- break;
- case NOTIFY_GESTURE_EVT:
- rc = v4l2_subdev_call(g_server_dev.gesture_device,
- core, ioctl, VIDIOC_MSM_GESTURE_EVT, arg);
- break;
- case NOTIFY_GESTURE_CAM_EVT:
- rc = v4l2_subdev_call(g_server_dev.gesture_device,
- core, ioctl, VIDIOC_MSM_GESTURE_CAM_EVT, arg);
- break;
- default:
- break;
- }
-
- return;
-}
-
-void msm_cam_release_subdev_node(struct video_device *vdev)
-{
- struct v4l2_subdev *sd = video_get_drvdata(vdev);
- sd->devnode = NULL;
- kfree(vdev);
-}
-
-int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
- enum msm_cam_subdev_type sdev_type, uint8_t index)
-{
- struct video_device *vdev;
- int err = 0;
-
- if (sdev_type == CSIPHY_DEV) {
- if (index >= MAX_NUM_CSIPHY_DEV)
- return -EINVAL;
- g_server_dev.csiphy_device[index] = sd;
- } else if (sdev_type == CSID_DEV) {
- if (index >= MAX_NUM_CSID_DEV)
- return -EINVAL;
- g_server_dev.csid_device[index] = sd;
- } else if (sdev_type == CSIC_DEV) {
- if (index >= MAX_NUM_CSIC_DEV)
- return -EINVAL;
- g_server_dev.csic_device[index] = sd;
- } else if (sdev_type == ISPIF_DEV) {
- g_server_dev.ispif_device = sd;
- } else if (sdev_type == VFE_DEV) {
- if (index >= MAX_NUM_VFE_DEV)
- return -EINVAL;
- g_server_dev.vfe_device[index] = sd;
- } else if (sdev_type == VPE_DEV) {
- if (index >= MAX_NUM_VPE_DEV)
- return -EINVAL;
- g_server_dev.vpe_device[index] = sd;
- } else if (sdev_type == AXI_DEV) {
- if (index >= MAX_NUM_AXI_DEV)
- return -EINVAL;
- g_server_dev.axi_device[index] = sd;
- } else if (sdev_type == GESTURE_DEV) {
- g_server_dev.gesture_device = sd;
- }
-
- err = v4l2_device_register_subdev(&g_server_dev.v4l2_dev, sd);
- if (err < 0)
- return err;
-
- /* Register a device node for every subdev marked with the
- * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
- */
- if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
- return err;
-
- vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
- if (!vdev) {
- err = -ENOMEM;
- goto clean_up;
- }
-
- video_set_drvdata(vdev, sd);
- strlcpy(vdev->name, sd->name, sizeof(vdev->name));
- vdev->v4l2_dev = &g_server_dev.v4l2_dev;
- vdev->fops = &v4l2_subdev_fops;
- vdev->release = msm_cam_release_subdev_node;
- err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
- sd->owner);
- if (err < 0) {
- kfree(vdev);
- goto clean_up;
- }
-#if defined(CONFIG_MEDIA_CONTROLLER)
- sd->entity.info.v4l.major = VIDEO_MAJOR;
- sd->entity.info.v4l.minor = vdev->minor;
-#endif
- sd->devnode = vdev;
- return 0;
-
-clean_up:
- if (sd->devnode)
- video_unregister_device(sd->devnode);
- return err;
-}
-
-static int msm_setup_server_dev(struct platform_device *pdev)
-{
- int rc = -ENODEV, i;
-
- D("%s\n", __func__);
- g_server_dev.server_pdev = pdev;
- g_server_dev.v4l2_dev.dev = &pdev->dev;
- g_server_dev.v4l2_dev.notify = msm_cam_server_subdev_notify;
- rc = v4l2_device_register(g_server_dev.v4l2_dev.dev,
- &g_server_dev.v4l2_dev);
- if (rc < 0)
- return -EINVAL;
-
- g_server_dev.video_dev = video_device_alloc();
- if (g_server_dev.video_dev == NULL) {
- pr_err("%s: video_device_alloc failed\n", __func__);
- return rc;
- }
-
- strlcpy(g_server_dev.video_dev->name, pdev->name,
- sizeof(g_server_dev.video_dev->name));
-
- g_server_dev.video_dev->v4l2_dev = &g_server_dev.v4l2_dev;
- g_server_dev.video_dev->fops = &msm_fops_server;
- g_server_dev.video_dev->ioctl_ops = &msm_ioctl_ops_server;
- g_server_dev.video_dev->release = video_device_release;
- g_server_dev.video_dev->minor = 100;
- g_server_dev.video_dev->vfl_type = 1;
-
- video_set_drvdata(g_server_dev.video_dev, &g_server_dev);
-
- strlcpy(g_server_dev.media_dev.model, "qcamera",
- sizeof(g_server_dev.media_dev.model));
- g_server_dev.media_dev.dev = &pdev->dev;
- rc = media_device_register(&g_server_dev.media_dev);
- g_server_dev.v4l2_dev.mdev = &g_server_dev.media_dev;
-
- rc = video_register_device(g_server_dev.video_dev,
- VFL_TYPE_GRABBER, 100);
-
- mutex_init(&g_server_dev.server_lock);
- mutex_init(&g_server_dev.server_queue_lock);
- g_server_dev.pcam_active = NULL;
- g_server_dev.camera_info.num_cameras = 0;
- atomic_set(&g_server_dev.number_pcam_active, 0);
- g_server_dev.server_evt_id = 0;
-
- /*initialize fake video device and event queue*/
-
- g_server_dev.server_command_queue.pvdev = g_server_dev.video_dev;
- rc = msm_setup_v4l2_event_queue(
- &g_server_dev.server_command_queue.eventHandle,
- g_server_dev.server_command_queue.pvdev);
-
- if (rc < 0) {
- pr_err("%s failed to initialize event queue\n", __func__);
- video_device_release(g_server_dev.server_command_queue.pvdev);
- return rc;
- }
-
- for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
- struct msm_cam_server_queue *queue;
- queue = &g_server_dev.server_queue[i];
- queue->queue_active = 0;
- msm_queue_init(&queue->ctrl_q, "control");
- msm_queue_init(&queue->eventData_q, "eventdata");
- }
- return rc;
-}
+static struct v4l2_file_operations g_msm_fops = {
+ .owner = THIS_MODULE,
+ .open = msm_open,
+ .poll = msm_poll,
+ .mmap = msm_mmap,
+ .release = msm_close,
+ .ioctl = video_ioctl2,
+};
static int msm_cam_dev_init(struct msm_cam_v4l2_device *pcam)
{
@@ -3117,7 +1127,7 @@
strlcpy(pvdev->name, pcam->sensor_sdev->name, sizeof(pvdev->name));
pvdev->release = video_device_release;
- pvdev->fops = &g_msm_fops;
+ pvdev->fops = &g_msm_fops;
pvdev->ioctl_ops = &g_msm_ioctl_ops;
pvdev->minor = -1;
pvdev->vfl_type = 1;
@@ -3143,16 +1153,7 @@
pcam->pvdev = pvdev;
video_set_drvdata(pcam->pvdev, pcam);
- /* If isp HW registeration is successful,
- * then create event queue to
- * receievent event froms HW
- */
- /* yyan: no global - each sensor will
- * create a new vidoe node! */
- /* g_pmsm_camera_v4l2_dev = pmsm_camera_v4l2_dev; */
- /* g_pmsm_camera_v4l2_dev->pvdev = pvdev; */
-
- return rc ;
+ return rc;
reg_fail:
video_device_release(pvdev);
@@ -3293,46 +1294,7 @@
__func__, rc);
goto failure;
}
-
- g_server_dev.camera_info.video_dev_name
- [g_server_dev.camera_info.num_cameras]
- = video_device_node_name(pcam->pvdev);
- D("%s Connected video device %s\n", __func__,
- g_server_dev.camera_info.video_dev_name
- [g_server_dev.camera_info.num_cameras]);
-
- g_server_dev.camera_info.s_mount_angle
- [g_server_dev.camera_info.num_cameras]
- = sdata->sensor_platform_info->mount_angle;
-
- g_server_dev.camera_info.is_internal_cam
- [g_server_dev.camera_info.num_cameras]
- = sdata->camera_type;
-
- g_server_dev.mctl_node_info.mctl_node_name
- [g_server_dev.mctl_node_info.num_mctl_nodes]
- = video_device_node_name(pcam->mctl_node.pvdev);
-
- pr_info("%s mctl_node_name[%d] = %s\n", __func__,
- g_server_dev.mctl_node_info.num_mctl_nodes,
- g_server_dev.mctl_node_info.mctl_node_name
- [g_server_dev.mctl_node_info.num_mctl_nodes]);
-
- /*Temporary solution to store info in media device structure
- until we can expand media device structure to support more
- device info*/
- snprintf(pcam->media_dev.serial,
- sizeof(pcam->media_dev.serial),
- "%s-%d-%d", QCAMERA_NAME,
- sdata->sensor_platform_info->mount_angle,
- sdata->camera_type);
-
- g_server_dev.camera_info.num_cameras++;
- g_server_dev.mctl_node_info.num_mctl_nodes++;
-
- D("%s done, rc = %d\n", __func__, rc);
- D("%s number of sensors connected is %d\n", __func__,
- g_server_dev.camera_info.num_cameras);
+ msm_server_update_sensor_info(pcam, sdata);
/* register the subdevice, must be done for callbacks */
rc = msm_cam_register_subdev_node(sensor_sd, SENSOR_DEV, vnode_count);
@@ -3370,83 +1332,3 @@
}
EXPORT_SYMBOL(msm_sensor_register);
-static int __devinit msm_camera_probe(struct platform_device *pdev)
-{
- int rc = 0, i;
- /*for now just create a config 0 node
- put logic here later to know how many configs to create*/
- g_server_dev.config_info.num_config_nodes = 1;
-
- rc = msm_isp_init_module(g_server_dev.config_info.num_config_nodes);
- if (rc < 0) {
- pr_err("Failed to initialize isp\n");
- return rc;
- }
-
- if (!msm_class) {
- rc = alloc_chrdev_region(&msm_devno, 0,
- g_server_dev.config_info.num_config_nodes+1, "msm_camera");
- if (rc < 0) {
- pr_err("%s: failed to allocate chrdev: %d\n", __func__,
- rc);
- return rc;
- }
-
- msm_class = class_create(THIS_MODULE, "msm_camera");
- if (IS_ERR(msm_class)) {
- rc = PTR_ERR(msm_class);
- pr_err("%s: create device class failed: %d\n",
- __func__, rc);
- return rc;
- }
- }
-
- D("creating server and config nodes\n");
- rc = msm_setup_server_dev(pdev);
- if (rc < 0) {
- pr_err("%s: failed to create server dev: %d\n", __func__,
- rc);
- return rc;
- }
-
- for (i = 0; i < g_server_dev.config_info.num_config_nodes; i++) {
- rc = msm_setup_config_dev(i, "config");
- if (rc < 0) {
- pr_err("%s:failed to create config dev: %d\n",
- __func__, rc);
- return rc;
- }
- }
-
- msm_isp_register(&g_server_dev);
- return rc;
-}
-
-static int __exit msm_camera_exit(struct platform_device *pdev)
-{
- msm_isp_unregister(&g_server_dev);
- return 0;
-}
-
-
-static struct platform_driver msm_cam_server_driver = {
- .probe = msm_camera_probe,
- .remove = msm_camera_exit,
- .driver = {
- .name = "msm_cam_server",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init msm_camera_init(void)
-{
- return platform_driver_register(&msm_cam_server_driver);
-}
-
-static void __exit msm_cam_server_exit(void)
-{
- platform_driver_unregister(&msm_cam_server_driver);
-}
-
-module_init(msm_camera_init);
-module_exit(msm_cam_server_exit);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index a91f0e1..8500d47 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -397,7 +397,6 @@
uint32_t queue_active;
struct msm_device_queue ctrl_q;
struct msm_device_queue eventData_q;
- struct msm_ctrl_cmd *ctrl;
uint8_t *ctrl_data;
uint32_t evt_id;
};
@@ -456,7 +455,6 @@
/* camera server related functions */
-
/* ISP related functions */
void msm_isp_vfe_dev_init(struct v4l2_subdev *vd);
/*
@@ -571,15 +569,14 @@
void msm_release_ion_client(struct kref *ref);
int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
enum msm_cam_subdev_type sdev_type, uint8_t index);
-uint32_t msm_camera_get_mctl_handle(void);
-struct msm_cam_media_controller *msm_camera_get_mctl(uint32_t handle);
-void msm_camera_free_mctl(uint32_t handle);
int msm_server_open_client(int *p_qidx);
int msm_server_send_ctrl(struct msm_ctrl_cmd *out, int ctrl_id);
int msm_server_close_client(int idx);
int msm_cam_server_open_mctl_session(struct msm_cam_v4l2_device *pcam,
int *p_active);
int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam);
+long msm_v4l2_evt_notify(struct msm_cam_media_controller *mctl,
+ unsigned int cmd, unsigned long evt);
#endif /* __KERNEL__ */
#endif /* _MSM_H */
diff --git a/drivers/media/video/msm/msm_gesture.c b/drivers/media/video/msm/msm_gesture.c
index 258c73d..6b81d15 100644
--- a/drivers/media/video/msm/msm_gesture.c
+++ b/drivers/media/video/msm/msm_gesture.c
@@ -200,32 +200,31 @@
D("%s: Received gesture evt 0x%x ", __func__, evt->type);
p_gesture_ctrl->event.evt_len = 0;
p_gesture_ctrl->event.evt_data = NULL;
- if (0 != evt->u.data[0]) {
- p_ges_evt = (struct msm_ges_evt *)evt->u.data;
- D("%s: event data %p len %d", __func__,
- p_ges_evt->evt_data,
- p_ges_evt->evt_len);
- if (p_ges_evt->evt_len > 0) {
- p_gesture_ctrl->event.evt_data =
- kzalloc(p_ges_evt->evt_len, GFP_KERNEL);
+ p_ges_evt = (struct msm_ges_evt *)evt->u.data;
+ D("%s: event data %p len %d", __func__,
+ p_ges_evt->evt_data,
+ p_ges_evt->evt_len);
- if (NULL == p_gesture_ctrl->event.evt_data) {
- pr_err("%s: cannot allocate event", __func__);
- rc = -ENOMEM;
+ if (p_ges_evt->evt_len > 0) {
+ p_gesture_ctrl->event.evt_data =
+ kzalloc(p_ges_evt->evt_len, GFP_KERNEL);
+
+ if (NULL == p_gesture_ctrl->event.evt_data) {
+ pr_err("%s: cannot allocate event", __func__);
+ rc = -ENOMEM;
+ } else {
+ if (copy_from_user(
+ (void *)p_gesture_ctrl->event.evt_data,
+ (void __user *)p_ges_evt->evt_data,
+ p_ges_evt->evt_len)) {
+ pr_err("%s: copy_from_user failed",
+ __func__);
+ rc = -EFAULT;
} else {
- if (copy_from_user(
- (void *)p_gesture_ctrl->event.evt_data,
- (void __user *)p_ges_evt->evt_data,
- p_ges_evt->evt_len)) {
- pr_err("%s: copy_from_user failed",
- __func__);
- rc = -EFAULT;
- } else {
- D("%s: copied the event", __func__);
- p_gesture_ctrl->event.evt_len =
- p_ges_evt->evt_len;
- }
+ D("%s: copied the event", __func__);
+ p_gesture_ctrl->event.evt_len =
+ p_ges_evt->evt_len;
}
}
}
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 9844271..716575a 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -30,6 +30,7 @@
#include <mach/cpuidle.h>
#include "msm.h"
+#include "msm_cam_server.h"
#include "msm_csid.h"
#include "msm_csic.h"
#include "msm_csiphy.h"
@@ -852,13 +853,13 @@
pr_err("%s: param is NULL", __func__);
return -EINVAL;
}
- pcam->mctl_handle = msm_camera_get_mctl_handle();
+ pcam->mctl_handle = msm_cam_server_get_mctl_handle();
if (pcam->mctl_handle == 0) {
pr_err("%s: cannot get mctl handle", __func__);
return -EINVAL;
}
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
if (!pmctl) {
pr_err("%s: invalid mctl controller", __func__);
return -EINVAL;
@@ -898,7 +899,7 @@
struct msm_cam_media_controller *pmctl = NULL;
D("%s\n", __func__);
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
if (!pmctl) {
pr_err("%s: invalid mctl controller", __func__);
return -EINVAL;
@@ -906,7 +907,7 @@
mutex_destroy(&pmctl->lock);
pm_qos_remove_request(&pmctl->idle_pm_qos);
- msm_camera_free_mctl(pcam->mctl_handle);
+ msm_cam_server_free_mctl(pcam->mctl_handle);
return rc;
}
@@ -962,7 +963,7 @@
return rc;
}
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
if (!pmctl) {
pr_err("%s mctl NULL!\n", __func__);
return rc;
@@ -1038,7 +1039,7 @@
return -EINVAL;
}
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
mutex_lock(&pcam->mctl_node.dev_lock);
D("%s : active %d ", __func__, pcam->mctl_node.active);
if (pcam->mctl_node.active == 1) {
@@ -1473,7 +1474,7 @@
(void *)pfmt->fmt.pix.priv);
WARN_ON(pctx != f->private_data);
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
if (!pcam_inst->vbqueue_initialized) {
pmctl->mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
V4L2_BUF_TYPE_VIDEO_CAPTURE);
@@ -1497,7 +1498,7 @@
pcam_inst, pcam_inst->vbqueue_initialized);
WARN_ON(pctx != f->private_data);
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
if (!pcam_inst->vbqueue_initialized) {
pmctl->mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 88e89a3..1088a54 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -26,6 +26,7 @@
#include <linux/android_pmem.h>
#include "msm.h"
+#include "msm_cam_server.h"
#include "msm_ispif.h"
#ifdef CONFIG_MSM_CAMERA_DEBUG
@@ -55,8 +56,8 @@
*num_planes = pcam_inst->plane_info.num_planes;
for (i = 0; i < pcam_inst->vid_fmt.fmt.pix_mp.num_planes; i++) {
sizes[i] = pcam_inst->plane_info.plane[i].size;
- D("%s Inst %p : Plane %d Offset = %d Size = %ld "
- "Aligned Size = %d\n", __func__, pcam_inst, i,
+ D("%s Inst %p : Plane %d Offset = %d Size = %ld"
+ "Aligned Size = %d", __func__, pcam_inst, i,
pcam_inst->plane_info.plane[i].offset,
pcam_inst->plane_info.plane[i].size, sizes[i]);
}
@@ -114,7 +115,7 @@
pcam_inst->plane_info.plane[0].offset;
}
buf_idx = vb->v4l2_buf.index;
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
for (i = 0; i < vb->num_planes; i++) {
mem = vb2_plane_cookie(vb, i);
if (buf_type == VIDEOBUF2_MULTIPLE_PLANES)
@@ -250,7 +251,7 @@
}
spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
}
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
for (i = 0; i < vb->num_planes; i++) {
mem = vb2_plane_cookie(vb, i);
videobuf2_pmem_contig_user_put(mem, pmctl->client);
@@ -471,7 +472,7 @@
int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam)
{
struct msm_cam_media_controller *pmctl;
- pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
pmctl->mctl_vbqueue_init = msm_vbqueue_init;
return 0;
}
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.c b/drivers/media/video/msm/msm_vfe31_v4l2.c
index be8d84b..a010817 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.c
@@ -368,7 +368,6 @@
static void vfe31_stop(void)
{
- uint8_t axiBusyFlag = true;
unsigned long flags;
atomic_set(&vfe31_ctrl->vstate, 0);
@@ -398,7 +397,52 @@
* at any time. stop camif immediately. */
msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+}
+void axi_start(void)
+{
+ switch (vfe31_ctrl->operation_mode) {
+ case VFE_OUTPUTS_PREVIEW:
+ case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+ if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+ } else if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+ }
+ break;
+ default:
+ if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+ } else if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
+ }
+ break;
+ }
+}
+
+void axi_stop(void)
+{
+ uint8_t axiBusyFlag = true;
/* axi halt command. */
msm_camera_io_w(AXI_HALT,
vfe31_ctrl->vfebase + VFE_AXI_CMD);
@@ -955,43 +999,6 @@
}
msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- switch (vfe31_ctrl->operation_mode) {
- case VFE_OUTPUTS_PREVIEW:
- case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
- if (vfe31_ctrl->outpath.output_mode &
- VFE31_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
- } else if (vfe31_ctrl->outpath.output_mode &
- VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
- }
- break;
- default:
- if (vfe31_ctrl->outpath.output_mode &
- VFE31_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
- } else if (vfe31_ctrl->outpath.output_mode &
- VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
- }
- break;
- }
msm_camio_bus_scale_cfg(
pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
vfe31_start_common();
@@ -3326,12 +3333,14 @@
cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
- if (copy_from_user(&vfecmd,
- (void __user *)(cmd->value),
- sizeof(vfecmd))) {
- pr_err("%s %d: copy_from_user failed\n", __func__,
- __LINE__);
- return -EFAULT;
+ if (NULL != cmd->value) {
+ if (copy_from_user(&vfecmd,
+ (void __user *)(cmd->value),
+ sizeof(vfecmd))) {
+ pr_err("%s %d: copy_from_user failed\n",
+ __func__, __LINE__);
+ return -EFAULT;
+ }
}
} else {
/* here eith stats release or frame release. */
@@ -3572,6 +3581,14 @@
}
break;
+ case CMD_AXI_START:
+ axi_start();
+ break;
+
+ case CMD_AXI_STOP:
+ axi_stop();
+ break;
+
default:
pr_err("%s Unsupported AXI configuration %x ", __func__,
cmd->cmd_type);
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 53fd6f1..98c1ca0 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -359,7 +359,6 @@
static void vfe32_stop(void)
{
- uint8_t axiBusyFlag = true;
unsigned long flags;
atomic_set(&vfe32_ctrl->vstate, 0);
@@ -390,31 +389,6 @@
msm_camera_io_w(CAMIF_COMMAND_STOP_IMMEDIATELY,
vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
- /* axi halt command. */
- msm_camera_io_w(AXI_HALT,
- vfe32_ctrl->vfebase + VFE_AXI_CMD);
- wmb();
- while (axiBusyFlag) {
- if (msm_camera_io_r(vfe32_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
- axiBusyFlag = false;
- }
- /* Ensure the write order while writing
- to the command register using the barrier */
- msm_camera_io_w_mb(AXI_HALT_CLEAR,
- vfe32_ctrl->vfebase + VFE_AXI_CMD);
-
- /* after axi halt, then ok to apply global reset. */
- /* enable reset_ack and async timer interrupt only while
- stopping the pipeline.*/
- msm_camera_io_w(0xf0000000,
- vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
- msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
- vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
-
- /* Ensure the write order while writing
- to the command register using the barrier */
- msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
- vfe32_ctrl->vfebase + VFE_GLOBAL_RESET);
}
static void vfe32_subdev_notify(int id, int path)
@@ -911,7 +885,6 @@
static int vfe32_start(struct msm_cam_media_controller *pmctl)
{
uint32_t irq_comp_mask = 0;
-
irq_comp_mask =
msm_camera_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
@@ -935,44 +908,6 @@
}
msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- switch (vfe32_ctrl->operation_mode) {
- case VFE_OUTPUTS_PREVIEW:
- case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
- if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
- } else if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
- }
- break;
- default:
- if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
- } else if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
- }
- break;
- }
-
msm_camio_bus_scale_cfg(
pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
vfe32_start_common();
@@ -3999,23 +3934,97 @@
vfe32_ctrl->vfebase = 0;
}
+void axi_start(void)
+{
+ switch (vfe32_ctrl->operation_mode) {
+ case VFE_OUTPUTS_PREVIEW:
+ case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
+ }
+ break;
+ default:
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
+ }
+ break;
+ }
+}
+
+void axi_stop(void)
+{
+ uint8_t axiBusyFlag = true;
+ /* axi halt command. */
+ msm_camera_io_w(AXI_HALT,
+ vfe32_ctrl->vfebase + VFE_AXI_CMD);
+ wmb();
+ while (axiBusyFlag) {
+ if (msm_camera_io_r(vfe32_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
+ axiBusyFlag = false;
+ }
+ /* Ensure the write order while writing
+ to the command register using the barrier */
+ msm_camera_io_w_mb(AXI_HALT_CLEAR,
+ vfe32_ctrl->vfebase + VFE_AXI_CMD);
+
+ /* after axi halt, then ok to apply global reset. */
+ /* enable reset_ack and async timer interrupt only while
+ stopping the pipeline.*/
+ msm_camera_io_w(0xf0000000,
+ vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+ msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
+ vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+ /* Ensure the write order while writing
+ to the command register using the barrier */
+ msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+ vfe32_ctrl->vfebase + VFE_GLOBAL_RESET);
+}
+
static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
{
struct msm_vfe_cfg_cmd cfgcmd;
struct msm_isp_cmd vfecmd;
int rc = 0;
- if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
- ERR_COPY_FROM_USER();
- return -EFAULT;
+ if (NULL != arg) {
+ if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+ ERR_COPY_FROM_USER();
+ return -EFAULT;
+ }
}
-
- if (copy_from_user(&vfecmd,
- (void __user *)(cfgcmd.value),
- sizeof(vfecmd))) {
- pr_err("%s %d: copy_from_user failed\n", __func__,
- __LINE__);
- return -EFAULT;
+ if (NULL != cfgcmd.value) {
+ if (copy_from_user(&vfecmd,
+ (void __user *)(cfgcmd.value),
+ sizeof(vfecmd))) {
+ pr_err("%s %d: copy_from_user failed\n", __func__,
+ __LINE__);
+ return -EFAULT;
+ }
}
switch (cfgcmd.cmd_type) {
@@ -4118,6 +4127,12 @@
pr_err("%s Invalid/Unsupported AXI configuration %x",
__func__, cfgcmd.cmd_type);
break;
+ case CMD_AXI_START:
+ axi_start();
+ break;
+ case CMD_AXI_STOP:
+ axi_stop();
+ break;
default:
pr_err("%s Unsupported AXI configuration %x ", __func__,
cfgcmd.cmd_type);
diff --git a/drivers/media/video/msm/server/Makefile b/drivers/media/video/msm/server/Makefile
new file mode 100644
index 0000000..55abeed
--- /dev/null
+++ b/drivers/media/video/msm/server/Makefile
@@ -0,0 +1,11 @@
+GCC_VERSION := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+
+ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
+ EXTRA_CFLAGS += -Idrivers/media/video/msm
+ EXTRA_CFLAGS += -Idrivers/media/video/msm/io
+ EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
+ EXTRA_CFLAGS += -Idrivers/media/video/msm/eeprom
+ EXTRA_CFLAGS += -Idrivers/media/video/msm/sensors
+ EXTRA_CFLAGS += -Idrivers/media/video/msm/actuators
+ obj-$(CONFIG_MSM_CAMERA) += msm_cam_server.o
+endif
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
new file mode 100644
index 0000000..8d004f6
--- /dev/null
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -0,0 +1,2342 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_cam_server.h"
+#include "msm_csid.h"
+#include "msm_csic.h"
+#include "msm_csiphy.h"
+#include "msm_ispif.h"
+#include "msm_sensor.h"
+#include "msm_actuator.h"
+#include "msm_vfe32.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+static struct msm_cam_server_dev g_server_dev;
+static struct class *msm_class;
+static dev_t msm_devno;
+
+static long msm_server_send_v4l2_evt(void *evt);
+static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
+ unsigned int notification, void *arg);
+
+static void msm_queue_init(struct msm_device_queue *queue, const char *name)
+{
+ D("%s\n", __func__);
+ spin_lock_init(&queue->lock);
+ queue->len = 0;
+ queue->max = 0;
+ queue->name = name;
+ INIT_LIST_HEAD(&queue->list);
+ init_waitqueue_head(&queue->wait);
+}
+
+static void msm_enqueue(struct msm_device_queue *queue,
+ struct list_head *entry)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&queue->lock, flags);
+ queue->len++;
+ if (queue->len > queue->max) {
+ queue->max = queue->len;
+ pr_info("%s: queue %s new max is %d\n", __func__,
+ queue->name, queue->max);
+ }
+ list_add_tail(entry, &queue->list);
+ wake_up(&queue->wait);
+ D("%s: woke up %s\n", __func__, queue->name);
+ spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+static void msm_drain_eventq(struct msm_device_queue *queue)
+{
+ unsigned long flags;
+ struct msm_queue_cmd *qcmd;
+ struct msm_isp_event_ctrl *isp_event;
+ spin_lock_irqsave(&queue->lock, flags);
+ while (!list_empty(&queue->list)) {
+ qcmd = list_first_entry(&queue->list,
+ struct msm_queue_cmd, list_eventdata);
+ list_del_init(&qcmd->list_eventdata);
+ isp_event =
+ (struct msm_isp_event_ctrl *)
+ qcmd->command;
+ if (isp_event->isp_data.ctrl.value != NULL)
+ kfree(isp_event->isp_data.ctrl.value);
+ kfree(qcmd->command);
+ free_qcmd(qcmd);
+ }
+ spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+int32_t msm_find_free_queue(void)
+{
+ int i;
+ for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+ struct msm_cam_server_queue *queue;
+ queue = &g_server_dev.server_queue[i];
+ if (!queue->queue_active)
+ return i;
+ }
+ return -EINVAL;
+}
+
+uint32_t msm_cam_server_get_mctl_handle(void)
+{
+ uint32_t i;
+ if ((g_server_dev.mctl_handle_cnt << 8) == 0)
+ g_server_dev.mctl_handle_cnt++;
+ for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+ if (g_server_dev.mctl[i].handle == 0) {
+ g_server_dev.mctl[i].handle =
+ (++g_server_dev.mctl_handle_cnt) << 8 | i;
+ memset(&g_server_dev.mctl[i].mctl,
+ 0, sizeof(g_server_dev.mctl[i].mctl));
+ return g_server_dev.mctl[i].handle;
+ }
+ }
+ return 0;
+}
+
+void msm_cam_server_free_mctl(uint32_t handle)
+{
+ uint32_t mctl_index;
+ mctl_index = handle & 0xff;
+ if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
+ (g_server_dev.mctl[mctl_index].handle == handle))
+ g_server_dev.mctl[mctl_index].handle = 0;
+ else
+ pr_err("%s: invalid free handle\n", __func__);
+}
+
+struct msm_cam_media_controller *msm_cam_server_get_mctl(uint32_t handle)
+{
+ uint32_t mctl_index;
+ mctl_index = handle & 0xff;
+ if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
+ (g_server_dev.mctl[mctl_index].handle == handle))
+ return &g_server_dev.mctl[mctl_index].mctl;
+ return NULL;
+}
+
+static int msm_ctrl_cmd_done(void *arg)
+{
+ void __user *uptr;
+ struct msm_queue_cmd *qcmd;
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+ struct msm_ctrl_cmd *command;
+ D("%s\n", __func__);
+
+ command = kzalloc(sizeof(struct msm_ctrl_cmd), GFP_KERNEL);
+ if (!command) {
+ pr_err("%s Insufficient memory. return", __func__);
+ goto command_alloc_fail;
+ }
+
+ qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+ if (!qcmd) {
+ pr_err("%s Insufficient memory. return", __func__);
+ goto qcmd_alloc_fail;
+ }
+
+ mutex_lock(&g_server_dev.server_queue_lock);
+
+ if (copy_from_user(command, (void __user *)ioctl_ptr->ioctl_ptr,
+ sizeof(struct msm_ctrl_cmd))) {
+ pr_err("%s: copy_from_user failed, size=%d\n",
+ __func__, sizeof(struct msm_ctrl_cmd));
+ goto ctrl_cmd_done_error;
+ }
+
+ if (!g_server_dev.server_queue[command->queue_idx].queue_active) {
+ pr_err("%s: Invalid queue\n", __func__);
+ goto ctrl_cmd_done_error;
+ }
+
+ D("%s qid %d evtid %d %d\n", __func__, command->queue_idx,
+ command->evt_id,
+ g_server_dev.server_queue[command->queue_idx].evt_id);
+
+ if (command->evt_id !=
+ g_server_dev.server_queue[command->queue_idx].evt_id) {
+ pr_err("Invalid event id from userspace\n");
+ goto ctrl_cmd_done_error;
+ }
+
+ atomic_set(&qcmd->on_heap, 1);
+ uptr = command->value;
+ qcmd->command = command;
+
+ if (command->length > 0) {
+ command->value =
+ g_server_dev.server_queue[command->queue_idx].ctrl_data;
+ if (command->length > max_control_command_size) {
+ pr_err("%s: user data %d is too big (max %d)\n",
+ __func__, command->length,
+ max_control_command_size);
+ goto ctrl_cmd_done_error;
+ }
+ if (copy_from_user(command->value, uptr, command->length)) {
+ pr_err("%s: copy_from_user failed, size=%d\n",
+ __func__, sizeof(struct msm_ctrl_cmd));
+ goto ctrl_cmd_done_error;
+ }
+ }
+ msm_enqueue(&g_server_dev.server_queue
+ [command->queue_idx].ctrl_q, &qcmd->list_control);
+ mutex_unlock(&g_server_dev.server_queue_lock);
+ return 0;
+
+ctrl_cmd_done_error:
+ mutex_unlock(&g_server_dev.server_queue_lock);
+ free_qcmd(qcmd);
+qcmd_alloc_fail:
+ kfree(command);
+command_alloc_fail:
+ return -EINVAL;
+}
+
+/* send control command to config and wait for results*/
+static int msm_server_control(struct msm_cam_server_dev *server_dev,
+ struct msm_ctrl_cmd *out)
+{
+ int rc = 0;
+ void *value;
+ struct msm_queue_cmd *rcmd;
+ struct msm_queue_cmd *event_qcmd;
+ struct msm_ctrl_cmd *ctrlcmd;
+ struct msm_device_queue *queue =
+ &server_dev->server_queue[out->queue_idx].ctrl_q;
+
+ struct v4l2_event v4l2_evt;
+ struct msm_isp_event_ctrl *isp_event;
+ void *ctrlcmd_data;
+
+ event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+ if (!event_qcmd) {
+ pr_err("%s Insufficient memory. return", __func__);
+ rc = -ENOMEM;
+ goto event_qcmd_alloc_fail;
+ }
+
+ isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
+ if (!isp_event) {
+ pr_err("%s Insufficient memory. return", __func__);
+ rc = -ENOMEM;
+ goto isp_event_alloc_fail;
+ }
+
+ D("%s\n", __func__);
+ mutex_lock(&server_dev->server_queue_lock);
+ if (++server_dev->server_evt_id == 0)
+ server_dev->server_evt_id++;
+
+ D("%s qid %d evtid %d\n", __func__, out->queue_idx,
+ server_dev->server_evt_id);
+ server_dev->server_queue[out->queue_idx].evt_id =
+ server_dev->server_evt_id;
+ v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_V4L2;
+ v4l2_evt.id = 0;
+ v4l2_evt.u.data[0] = out->queue_idx;
+ /* setup event object to transfer the command; */
+ isp_event->resptype = MSM_CAM_RESP_V4L2;
+ isp_event->isp_data.ctrl = *out;
+ isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
+
+ if (out->value != NULL && out->length != 0) {
+ ctrlcmd_data = kzalloc(out->length, GFP_KERNEL);
+ if (!ctrlcmd_data) {
+ rc = -ENOMEM;
+ goto ctrlcmd_alloc_fail;
+ }
+ memcpy(ctrlcmd_data, out->value, out->length);
+ isp_event->isp_data.ctrl.value = ctrlcmd_data;
+ }
+
+ atomic_set(&event_qcmd->on_heap, 1);
+ event_qcmd->command = isp_event;
+
+ msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
+ &event_qcmd->list_eventdata);
+
+ /* now send command to config thread in userspace,
+ * and wait for results */
+ v4l2_event_queue(server_dev->server_command_queue.pvdev,
+ &v4l2_evt);
+ D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
+ mutex_unlock(&server_dev->server_queue_lock);
+
+ /* wait for config return status */
+ D("Waiting for config status\n");
+ rc = wait_event_interruptible_timeout(queue->wait,
+ !list_empty_careful(&queue->list),
+ msecs_to_jiffies(out->timeout_ms));
+ D("Waiting is over for config status\n");
+ if (list_empty_careful(&queue->list)) {
+ if (!rc)
+ rc = -ETIMEDOUT;
+ if (rc < 0) {
+ if (++server_dev->server_evt_id == 0)
+ server_dev->server_evt_id++;
+ pr_err("%s: wait_event error %d\n", __func__, rc);
+ return rc;
+ }
+ }
+
+ rcmd = msm_dequeue(queue, list_control);
+ BUG_ON(!rcmd);
+ D("%s Finished servicing ioctl\n", __func__);
+
+ ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
+ value = out->value;
+ if (ctrlcmd->length > 0 && value != NULL &&
+ ctrlcmd->length <= out->length)
+ memcpy(value, ctrlcmd->value, ctrlcmd->length);
+
+ memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
+ out->value = value;
+
+ kfree(ctrlcmd);
+ free_qcmd(rcmd);
+ D("%s: rc %d\n", __func__, rc);
+ /* rc is the time elapsed. */
+ if (rc >= 0) {
+ /* TODO: Refactor msm_ctrl_cmd::status field */
+ if (out->status == 0)
+ rc = -1;
+ else if (out->status == 1 || out->status == 4)
+ rc = 0;
+ else
+ rc = -EINVAL;
+ }
+ return rc;
+
+ctrlcmd_alloc_fail:
+ kfree(isp_event);
+isp_event_alloc_fail:
+ kfree(event_qcmd);
+event_qcmd_alloc_fail:
+ return rc;
+}
+
+int msm_server_get_crop(struct msm_cam_v4l2_device *pcam,
+ int idx, struct v4l2_crop *crop)
+{
+ int rc = 0;
+ struct msm_ctrl_cmd ctrlcmd;
+
+ BUG_ON(crop == NULL);
+
+ ctrlcmd.type = MSM_V4L2_GET_CROP;
+ ctrlcmd.length = sizeof(struct v4l2_crop);
+ ctrlcmd.value = (void *)crop;
+ ctrlcmd.timeout_ms = 1000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+ /* send command to config thread in userspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ D("%s: rc = %d\n", __func__, rc);
+
+ return rc;
+}
+
+/*send open command to server*/
+int msm_send_open_server(struct msm_cam_v4l2_device *pcam)
+{
+ int rc = 0;
+ struct msm_ctrl_cmd ctrlcmd;
+ D("%s qid %d\n", __func__, pcam->server_queue_idx);
+ ctrlcmd.type = MSM_V4L2_OPEN;
+ ctrlcmd.timeout_ms = 10000;
+ ctrlcmd.length = strnlen(g_server_dev.config_info.config_dev_name[0],
+ MAX_DEV_NAME_LEN)+1;
+ ctrlcmd.value = (char *)g_server_dev.config_info.config_dev_name[0];
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+ return rc;
+}
+
+int msm_send_close_server(struct msm_cam_v4l2_device *pcam)
+{
+ int rc = 0;
+ struct msm_ctrl_cmd ctrlcmd;
+ D("%s qid %d\n", __func__, pcam->server_queue_idx);
+ ctrlcmd.type = MSM_V4L2_CLOSE;
+ ctrlcmd.timeout_ms = 10000;
+ ctrlcmd.length = strnlen(g_server_dev.config_info.config_dev_name[0],
+ MAX_DEV_NAME_LEN)+1;
+ ctrlcmd.value = (char *)g_server_dev.config_info.config_dev_name[0];
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+ return rc;
+}
+
+int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
+ struct v4l2_format *pfmt)
+{
+ int rc = 0;
+ int i = 0;
+ struct v4l2_pix_format *pix = &pfmt->fmt.pix;
+ struct msm_ctrl_cmd ctrlcmd;
+ struct img_plane_info plane_info;
+
+ plane_info.width = pix->width;
+ plane_info.height = pix->height;
+ plane_info.pixelformat = pix->pixelformat;
+ plane_info.buffer_type = pfmt->type;
+ plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
+ plane_info.num_planes = 1;
+ D("%s: %d, %d, 0x%x\n", __func__,
+ pfmt->fmt.pix.width, pfmt->fmt.pix.height,
+ pfmt->fmt.pix.pixelformat);
+
+ if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ D("%s, Attention! Wrong buf-type %d\n", __func__, pfmt->type);
+
+ for (i = 0; i < pcam->num_fmts; i++)
+ if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
+ break;
+ if (i == pcam->num_fmts) {
+ pr_err("%s: User requested pixelformat %x not supported\n",
+ __func__, pix->pixelformat);
+ return -EINVAL;
+ }
+
+ ctrlcmd.type = MSM_V4L2_VID_CAP_TYPE;
+ ctrlcmd.length = sizeof(struct img_plane_info);
+ ctrlcmd.value = (void *)&plane_info;
+ ctrlcmd.timeout_ms = 10000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+ if (rc >= 0) {
+ pcam->dev_inst[idx]->vid_fmt = *pfmt;
+ pcam->dev_inst[idx]->sensor_pxlcode
+ = pcam->usr_fmts[i].pxlcode;
+ D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
+ __func__, (u32)pcam->dev_inst[idx], idx,
+ pcam->dev_inst[idx]->vid_fmt.fmt.pix.width,
+ pcam->dev_inst[idx]->vid_fmt.fmt.pix.height);
+ pcam->dev_inst[idx]->plane_info = plane_info;
+ }
+
+ return rc;
+}
+
+int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
+ struct v4l2_format *pfmt)
+{
+ int rc = 0;
+ int i = 0;
+ struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
+ struct msm_ctrl_cmd ctrlcmd;
+ struct img_plane_info plane_info;
+
+ plane_info.width = pix_mp->width;
+ plane_info.height = pix_mp->height;
+ plane_info.pixelformat = pix_mp->pixelformat;
+ plane_info.buffer_type = pfmt->type;
+ plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
+ plane_info.num_planes = pix_mp->num_planes;
+ if (plane_info.num_planes <= 0 ||
+ plane_info.num_planes > VIDEO_MAX_PLANES) {
+ pr_err("%s Invalid number of planes set %d", __func__,
+ plane_info.num_planes);
+ return -EINVAL;
+ }
+ D("%s: %d, %d, 0x%x\n", __func__,
+ pfmt->fmt.pix_mp.width, pfmt->fmt.pix_mp.height,
+ pfmt->fmt.pix_mp.pixelformat);
+
+ if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ pr_err("%s, Attention! Wrong buf-type %d\n",
+ __func__, pfmt->type);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < pcam->num_fmts; i++)
+ if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
+ break;
+ if (i == pcam->num_fmts) {
+ pr_err("%s: User requested pixelformat %x not supported\n",
+ __func__, pix_mp->pixelformat);
+ return -EINVAL;
+ }
+
+ ctrlcmd.type = MSM_V4L2_VID_CAP_TYPE;
+ ctrlcmd.length = sizeof(struct img_plane_info);
+ ctrlcmd.value = (void *)&plane_info;
+ ctrlcmd.timeout_ms = 10000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ if (rc >= 0) {
+ pcam->dev_inst[idx]->vid_fmt = *pfmt;
+ pcam->dev_inst[idx]->sensor_pxlcode
+ = pcam->usr_fmts[i].pxlcode;
+ D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
+ __func__, (u32)pcam->dev_inst[idx], idx,
+ pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.width,
+ pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.height);
+ pcam->dev_inst[idx]->plane_info = plane_info;
+ }
+
+ return rc;
+}
+
+int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx)
+{
+ int rc = 0;
+ struct msm_ctrl_cmd ctrlcmd;
+ D("%s\n", __func__);
+ ctrlcmd.type = MSM_V4L2_STREAM_ON;
+ ctrlcmd.timeout_ms = 10000;
+ ctrlcmd.length = 0;
+ ctrlcmd.value = NULL;
+ ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+ return rc;
+}
+
+int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx)
+{
+ int rc = 0;
+ struct msm_ctrl_cmd ctrlcmd;
+
+ D("%s, pcam = 0x%x\n", __func__, (u32)pcam);
+ ctrlcmd.type = MSM_V4L2_STREAM_OFF;
+ ctrlcmd.timeout_ms = 10000;
+ ctrlcmd.length = 0;
+ ctrlcmd.value = NULL;
+ ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+ return rc;
+}
+
+int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_control *ctrl, int is_set_cmd)
+{
+ int rc = 0;
+ struct msm_ctrl_cmd ctrlcmd, *tmp_cmd;
+ uint8_t *ctrl_data = NULL;
+ void __user *uptr_cmd;
+ void __user *uptr_value;
+ uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
+ uint32_t value_len;
+
+ tmp_cmd = (struct msm_ctrl_cmd *)ctrl->value;
+ uptr_cmd = (void __user *)ctrl->value;
+ uptr_value = (void __user *)tmp_cmd->value;
+ value_len = tmp_cmd->length;
+
+ D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
+ __func__, tmp_cmd->type, (uint32_t)uptr_cmd, cmd_len,
+ (uint32_t)uptr_value, tmp_cmd->length);
+
+ ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
+ if (ctrl_data == 0) {
+ pr_err("%s could not allocate memory\n", __func__);
+ rc = -ENOMEM;
+ goto end;
+ }
+ tmp_cmd = (struct msm_ctrl_cmd *)ctrl_data;
+ if (copy_from_user((void *)ctrl_data, uptr_cmd,
+ cmd_len)) {
+ pr_err("%s: copy_from_user failed.\n", __func__);
+ rc = -EINVAL;
+ goto end;
+ }
+ tmp_cmd->value = (void *)(ctrl_data+cmd_len);
+ if (uptr_value && tmp_cmd->length > 0) {
+ if (copy_from_user((void *)tmp_cmd->value, uptr_value,
+ value_len)) {
+ pr_err("%s: copy_from_user failed, size=%d\n",
+ __func__, value_len);
+ rc = -EINVAL;
+ goto end;
+ }
+ } else
+ tmp_cmd->value = NULL;
+
+ ctrlcmd.type = MSM_V4L2_SET_CTRL_CMD;
+ ctrlcmd.length = cmd_len + value_len;
+ ctrlcmd.value = (void *)ctrl_data;
+ if (tmp_cmd->timeout_ms > 0)
+ ctrlcmd.timeout_ms = tmp_cmd->timeout_ms;
+ else
+ ctrlcmd.timeout_ms = 1000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ D("%s: msm_server_control rc=%d\n", __func__, rc);
+ if (rc == 0) {
+ if (uptr_value && tmp_cmd->length > 0 &&
+ copy_to_user((void __user *)uptr_value,
+ (void *)(ctrl_data+cmd_len), tmp_cmd->length)) {
+ pr_err("%s: copy_to_user failed, size=%d\n",
+ __func__, tmp_cmd->length);
+ rc = -EINVAL;
+ goto end;
+ }
+ tmp_cmd->value = uptr_value;
+ if (copy_to_user((void __user *)uptr_cmd,
+ (void *)tmp_cmd, cmd_len)) {
+ pr_err("%s: copy_to_user failed in cpy, size=%d\n",
+ __func__, cmd_len);
+ rc = -EINVAL;
+ goto end;
+ }
+ }
+end:
+ D("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
+ __func__, tmp_cmd->type, (uint32_t)tmp_cmd->value,
+ tmp_cmd->length, tmp_cmd->status, rc);
+ kfree(ctrl_data);
+ return rc;
+}
+
+int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_control *ctrl)
+{
+ int rc = 0;
+ struct msm_ctrl_cmd ctrlcmd;
+ uint8_t ctrl_data[max_control_command_size];
+
+ WARN_ON(ctrl == NULL);
+ if (ctrl == NULL) {
+ pr_err("%s Invalid control\n", __func__);
+ return -EINVAL;
+ }
+ if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
+ return msm_server_proc_ctrl_cmd(pcam, ctrl, 1);
+
+ memset(ctrl_data, 0, sizeof(ctrl_data));
+
+ ctrlcmd.type = MSM_V4L2_SET_CTRL;
+ ctrlcmd.length = sizeof(struct v4l2_control);
+ ctrlcmd.value = (void *)ctrl_data;
+ memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
+ ctrlcmd.timeout_ms = 1000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+ return rc;
+}
+
+int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_control *ctrl)
+{
+ int rc = 0;
+ struct msm_ctrl_cmd ctrlcmd;
+ uint8_t ctrl_data[max_control_command_size];
+
+ WARN_ON(ctrl == NULL);
+ if (ctrl == NULL) {
+ pr_err("%s Invalid control\n", __func__);
+ return -EINVAL;
+ }
+ if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
+ return msm_server_proc_ctrl_cmd(pcam, ctrl, 0);
+
+ memset(ctrl_data, 0, sizeof(ctrl_data));
+
+ ctrlcmd.type = MSM_V4L2_GET_CTRL;
+ ctrlcmd.length = sizeof(struct v4l2_control);
+ ctrlcmd.value = (void *)ctrl_data;
+ memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
+ ctrlcmd.timeout_ms = 1000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+ ctrl->value = ((struct v4l2_control *)ctrlcmd.value)->value;
+
+ return rc;
+}
+
+int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_queryctrl *queryctrl)
+{
+ int rc = 0;
+ struct msm_ctrl_cmd ctrlcmd;
+ uint8_t ctrl_data[max_control_command_size];
+
+ WARN_ON(queryctrl == NULL);
+ memset(ctrl_data, 0, sizeof(ctrl_data));
+
+ ctrlcmd.type = MSM_V4L2_QUERY_CTRL;
+ ctrlcmd.length = sizeof(struct v4l2_queryctrl);
+ ctrlcmd.value = (void *)ctrl_data;
+ memcpy(ctrlcmd.value, queryctrl, ctrlcmd.length);
+ ctrlcmd.timeout_ms = 1000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+ /* send command to config thread in userspace, and get return value */
+ rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ D("%s: rc = %d\n", __func__, rc);
+
+ if (rc >= 0)
+ memcpy(queryctrl, ctrlcmd.value, sizeof(struct v4l2_queryctrl));
+
+ return rc;
+}
+
+int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
+ int idx, struct v4l2_format *pfmt)
+{
+ struct v4l2_pix_format *pix = &pfmt->fmt.pix;
+
+ pix->width = pcam->dev_inst[idx]->vid_fmt.fmt.pix.width;
+ pix->height = pcam->dev_inst[idx]->vid_fmt.fmt.pix.height;
+ pix->field = pcam->dev_inst[idx]->vid_fmt.fmt.pix.field;
+ pix->pixelformat = pcam->dev_inst[idx]->vid_fmt.fmt.pix.pixelformat;
+ pix->bytesperline = pcam->dev_inst[idx]->vid_fmt.fmt.pix.bytesperline;
+ pix->colorspace = pcam->dev_inst[idx]->vid_fmt.fmt.pix.colorspace;
+ if (pix->bytesperline < 0)
+ return pix->bytesperline;
+
+ pix->sizeimage = pix->height * pix->bytesperline;
+
+ return 0;
+}
+
+int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+ int idx, struct v4l2_format *pfmt)
+{
+ *pfmt = pcam->dev_inst[idx]->vid_fmt;
+ return 0;
+}
+
+int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_format *pfmt)
+{
+ int rc = 0;
+ int i = 0;
+ struct v4l2_pix_format *pix = &pfmt->fmt.pix;
+
+ D("%s: 0x%x\n", __func__, pix->pixelformat);
+ if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ pr_err("%s: pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE!\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* check if the format is supported by this host-sensor combo */
+ for (i = 0; i < pcam->num_fmts; i++) {
+ D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
+ pcam->usr_fmts[i].fourcc);
+ if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
+ break;
+ }
+
+ if (i == pcam->num_fmts) {
+ pr_err("%s: Format %x not found\n", __func__, pix->pixelformat);
+ return -EINVAL;
+ }
+ return rc;
+}
+
+int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_format *pfmt)
+{
+ int rc = 0;
+ int i = 0;
+ struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
+
+ D("%s: 0x%x\n", __func__, pix_mp->pixelformat);
+ if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ pr_err("%s: Incorrect format type %d ",
+ __func__, pfmt->type);
+ return -EINVAL;
+ }
+
+ /* check if the format is supported by this host-sensor combo */
+ for (i = 0; i < pcam->num_fmts; i++) {
+ D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
+ pcam->usr_fmts[i].fourcc);
+ if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
+ break;
+ }
+
+ if (i == pcam->num_fmts) {
+ pr_err("%s: Format %x not found\n",
+ __func__, pix_mp->pixelformat);
+ return -EINVAL;
+ }
+ return rc;
+}
+
+int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ int rc = 0;
+
+ D("%s: fh = 0x%x, type = 0x%x", __func__, (u32)fh, sub->type);
+ if (sub->type == V4L2_EVENT_ALL) {
+ /*sub->type = MSM_ISP_EVENT_START;*/
+ sub->type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_CTRL;
+ D("sub->type start = 0x%x\n", sub->type);
+ do {
+ rc = v4l2_event_subscribe(fh, sub, 30);
+ if (rc < 0) {
+ D("%s: failed for evtType = 0x%x, rc = %d\n",
+ __func__, sub->type, rc);
+ /* unsubscribe all events here and return */
+ sub->type = V4L2_EVENT_ALL;
+ v4l2_event_unsubscribe(fh, sub);
+ return rc;
+ } else
+ D("%s: subscribed evtType = 0x%x, rc = %d\n",
+ __func__, sub->type, rc);
+ sub->type++;
+ D("sub->type while = 0x%x\n", sub->type);
+ } while (sub->type !=
+ V4L2_EVENT_PRIVATE_START + MSM_SVR_RESP_MAX);
+ } else {
+ D("sub->type not V4L2_EVENT_ALL = 0x%x\n", sub->type);
+ rc = v4l2_event_subscribe(fh, sub, 30);
+ if (rc < 0)
+ D("%s: failed for evtType = 0x%x, rc = %d\n",
+ __func__, sub->type, rc);
+ }
+
+ D("%s: rc = %d\n", __func__, rc);
+ return rc;
+}
+
+int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ int rc = 0;
+
+ D("%s: fh = 0x%x\n", __func__, (u32)fh);
+ rc = v4l2_event_unsubscribe(fh, sub);
+ D("%s: rc = %d\n", __func__, rc);
+ return rc;
+}
+
+/* open an active camera session to manage the streaming logic */
+static int msm_cam_server_open_session(struct msm_cam_server_dev *ps,
+ struct msm_cam_v4l2_device *pcam)
+{
+ int rc = 0;
+ struct msm_cam_media_controller *pmctl;
+
+ D("%s\n", __func__);
+
+ if (!ps || !pcam) {
+ pr_err("%s NULL pointer passed in!\n", __func__);
+ return rc;
+ }
+
+ /* The number of camera instance should be controlled by the
+ resource manager. Currently supporting one active instance
+ until multiple instances are supported */
+ if (atomic_read(&ps->number_pcam_active) > 0) {
+ pr_err("%s Cannot have more than one active camera %d\n",
+ __func__, atomic_read(&ps->number_pcam_active));
+ return -EINVAL;
+ }
+ /* book keeping this camera session*/
+ ps->pcam_active = pcam;
+ atomic_inc(&ps->number_pcam_active);
+
+ D("config pcam = 0x%p\n", ps->pcam_active);
+
+ /* initialization the media controller module*/
+ msm_mctl_init(pcam);
+
+ /*for single VFE msms (8660, 8960v1), just populate the session
+ with our VFE devices that registered*/
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+ pmctl->axi_sdev = ps->axi_device[0];
+ pmctl->isp_sdev = ps->isp_subdev[0];
+ return rc;
+}
+
+/* close an active camera session to server */
+static int msm_cam_server_close_session(struct msm_cam_server_dev *ps,
+ struct msm_cam_v4l2_device *pcam)
+{
+ int rc = 0;
+ D("%s\n", __func__);
+
+ if (!ps || !pcam) {
+ D("%s NULL pointer passed in!\n", __func__);
+ return rc;
+ }
+
+
+ atomic_dec(&ps->number_pcam_active);
+ ps->pcam_active = NULL;
+
+ msm_mctl_free(pcam);
+ return rc;
+}
+
+static long msm_ioctl_server(struct file *file, void *fh,
+ bool valid_prio, int cmd, void *arg)
+{
+ int rc = -EINVAL;
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+ struct msm_camera_info temp_cam_info;
+ struct msm_cam_config_dev_info temp_config_info;
+ struct msm_mctl_node_info temp_mctl_info;
+ int i;
+
+ D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+
+ switch (cmd) {
+ case MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO:
+ if (copy_from_user(&temp_cam_info,
+ (void __user *)ioctl_ptr->ioctl_ptr,
+ sizeof(struct msm_camera_info))) {
+ pr_err("%s Copy from user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ for (i = 0; i < g_server_dev.camera_info.num_cameras; i++) {
+ if (copy_to_user((void __user *)
+ temp_cam_info.video_dev_name[i],
+ g_server_dev.camera_info.video_dev_name[i],
+ strnlen(g_server_dev.camera_info.video_dev_name[i],
+ MAX_DEV_NAME_LEN))) {
+ pr_err("%s Copy to user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ temp_cam_info.has_3d_support[i] =
+ g_server_dev.camera_info.has_3d_support[i];
+ temp_cam_info.is_internal_cam[i] =
+ g_server_dev.camera_info.is_internal_cam[i];
+ temp_cam_info.s_mount_angle[i] =
+ g_server_dev.camera_info.s_mount_angle[i];
+ temp_cam_info.sensor_type[i] =
+ g_server_dev.camera_info.sensor_type[i];
+
+ }
+ temp_cam_info.num_cameras =
+ g_server_dev.camera_info.num_cameras;
+ if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+ &temp_cam_info, sizeof(struct msm_camera_info))) {
+ pr_err("%s Copy to user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ rc = 0;
+ break;
+
+ case MSM_CAM_V4L2_IOCTL_GET_CONFIG_INFO:
+ if (copy_from_user(&temp_config_info,
+ (void __user *)ioctl_ptr->ioctl_ptr,
+ sizeof(struct msm_cam_config_dev_info))) {
+ pr_err("%s Copy from user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ for (i = 0;
+ i < g_server_dev.config_info.num_config_nodes; i++) {
+ if (copy_to_user(
+ (void __user *)temp_config_info.config_dev_name[i],
+ g_server_dev.config_info.config_dev_name[i],
+ strnlen(g_server_dev.config_info.config_dev_name[i],
+ MAX_DEV_NAME_LEN))) {
+ pr_err("%s Copy to user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ }
+ temp_config_info.num_config_nodes =
+ g_server_dev.config_info.num_config_nodes;
+ if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+ &temp_config_info,
+ sizeof(struct msm_cam_config_dev_info))) {
+ pr_err("%s Copy to user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ rc = 0;
+ break;
+ case MSM_CAM_V4L2_IOCTL_GET_MCTL_INFO:
+ if (copy_from_user(&temp_mctl_info,
+ (void __user *)ioctl_ptr->ioctl_ptr,
+ sizeof(struct msm_mctl_node_info))) {
+ pr_err("%s Copy from user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ for (i = 0; i < g_server_dev.mctl_node_info.num_mctl_nodes;
+ i++) {
+ if (copy_to_user((void __user *)
+ temp_mctl_info.mctl_node_name[i],
+ g_server_dev.mctl_node_info.mctl_node_name[i], strnlen(
+ g_server_dev.mctl_node_info.mctl_node_name[i],
+ MAX_DEV_NAME_LEN))) {
+ pr_err("%s Copy to user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ }
+ temp_mctl_info.num_mctl_nodes =
+ g_server_dev.mctl_node_info.num_mctl_nodes;
+ if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+ &temp_mctl_info, sizeof(struct msm_mctl_node_info))) {
+ pr_err("%s Copy to user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ rc = 0;
+ break;
+
+ case MSM_CAM_V4L2_IOCTL_CTRL_CMD_DONE:
+ D("%s: MSM_CAM_IOCTL_CTRL_CMD_DONE\n", __func__);
+ rc = msm_ctrl_cmd_done(arg);
+ break;
+
+ case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
+ struct msm_queue_cmd *event_cmd;
+ struct msm_isp_event_ctrl u_isp_event;
+ struct msm_isp_event_ctrl *k_isp_event;
+ struct msm_device_queue *queue;
+ void __user *u_ctrl_value = NULL;
+ if (copy_from_user(&u_isp_event,
+ (void __user *)ioctl_ptr->ioctl_ptr,
+ sizeof(struct msm_isp_event_ctrl))) {
+ pr_err("%s Copy from user failed for cmd %d",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+
+ mutex_lock(&g_server_dev.server_queue_lock);
+ if (!g_server_dev.server_queue
+ [u_isp_event.isp_data.ctrl.queue_idx].queue_active) {
+ pr_err("%s: Invalid queue\n", __func__);
+ mutex_unlock(&g_server_dev.server_queue_lock);
+ rc = -EINVAL;
+ return rc;
+ }
+ queue = &g_server_dev.server_queue
+ [u_isp_event.isp_data.ctrl.queue_idx].eventData_q;
+ event_cmd = msm_dequeue(queue, list_eventdata);
+ if (!event_cmd) {
+ pr_err("%s: No event payload\n", __func__);
+ rc = -EINVAL;
+ mutex_unlock(&g_server_dev.server_queue_lock);
+ return rc;
+ }
+ k_isp_event = (struct msm_isp_event_ctrl *)
+ event_cmd->command;
+ free_qcmd(event_cmd);
+
+ /* Save the pointer of the user allocated command buffer*/
+ u_ctrl_value = u_isp_event.isp_data.ctrl.value;
+
+ /* Copy the event structure into user struct*/
+ u_isp_event = *k_isp_event;
+
+ /* Restore the saved pointer of the user
+ * allocated command buffer. */
+ u_isp_event.isp_data.ctrl.value = u_ctrl_value;
+
+ /* Copy the ctrl cmd, if present*/
+ if (k_isp_event->isp_data.ctrl.length > 0 &&
+ k_isp_event->isp_data.ctrl.value != NULL) {
+ void *k_ctrl_value =
+ k_isp_event->isp_data.ctrl.value;
+ if (copy_to_user(u_ctrl_value, k_ctrl_value,
+ k_isp_event->isp_data.ctrl.length)) {
+ pr_err("%s Copy to user failed for cmd %d",
+ __func__, cmd);
+ kfree(k_isp_event->isp_data.ctrl.value);
+ kfree(k_isp_event);
+ rc = -EINVAL;
+ mutex_unlock(&g_server_dev.server_queue_lock);
+ break;
+ }
+ kfree(k_isp_event->isp_data.ctrl.value);
+ }
+ if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+ &u_isp_event, sizeof(struct msm_isp_event_ctrl))) {
+ pr_err("%s Copy to user failed for cmd %d",
+ __func__, cmd);
+ kfree(k_isp_event);
+ mutex_unlock(&g_server_dev.server_queue_lock);
+ rc = -EINVAL;
+ return rc;
+ }
+ kfree(k_isp_event);
+ mutex_unlock(&g_server_dev.server_queue_lock);
+ rc = 0;
+ break;
+ }
+
+ case MSM_CAM_IOCTL_SEND_EVENT:
+ rc = msm_server_send_v4l2_evt(arg);
+ break;
+
+ default:
+ pr_err("%s: Invalid IOCTL = %d", __func__, cmd);
+ break;
+ }
+ return rc;
+}
+
+static int msm_open_server(struct file *fp)
+{
+ int rc = 0;
+ D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
+ mutex_lock(&g_server_dev.server_lock);
+ g_server_dev.use_count++;
+ if (g_server_dev.use_count == 1)
+ fp->private_data =
+ &g_server_dev.server_command_queue.eventHandle;
+ mutex_unlock(&g_server_dev.server_lock);
+ return rc;
+}
+
+static int msm_close_server(struct file *fp)
+{
+ struct v4l2_event_subscription sub;
+ D("%s\n", __func__);
+ mutex_lock(&g_server_dev.server_lock);
+ if (g_server_dev.use_count > 0)
+ g_server_dev.use_count--;
+ mutex_unlock(&g_server_dev.server_lock);
+
+ if (g_server_dev.use_count == 0) {
+ mutex_lock(&g_server_dev.server_lock);
+ if (g_server_dev.pcam_active) {
+ struct v4l2_event v4l2_ev;
+ struct msm_cam_media_controller *pmctl = NULL;
+ int rc;
+
+ pmctl = msm_cam_server_get_mctl(
+ g_server_dev.pcam_active->mctl_handle);
+ if (pmctl && pmctl->mctl_release) {
+ rc = pmctl->mctl_release(pmctl);
+ if (rc < 0)
+ pr_err("mctl_release fails %d\n", rc);
+ /*so that it isn't closed again*/
+ pmctl->mctl_release = NULL;
+ }
+
+ v4l2_ev.id = 0;
+ v4l2_ev.type = V4L2_EVENT_PRIVATE_START
+ + MSM_CAM_APP_NOTIFY_ERROR_EVENT;
+ ktime_get_ts(&v4l2_ev.timestamp);
+ v4l2_event_queue(
+ g_server_dev.pcam_active->pvdev, &v4l2_ev);
+ }
+ sub.type = V4L2_EVENT_ALL;
+ msm_server_v4l2_unsubscribe_event(
+ &g_server_dev.server_command_queue.eventHandle, &sub);
+ mutex_unlock(&g_server_dev.server_lock);
+ }
+ return 0;
+}
+
+static unsigned int msm_poll_server(struct file *fp,
+ struct poll_table_struct *wait)
+{
+ int rc = 0;
+
+ D("%s\n", __func__);
+ poll_wait(fp,
+ &g_server_dev.server_command_queue.eventHandle.wait,
+ wait);
+ if (v4l2_event_pending(&g_server_dev.server_command_queue.eventHandle))
+ rc |= POLLPRI;
+
+ return rc;
+}
+
+int msm_server_get_usecount(void)
+{
+ return g_server_dev.use_count;
+}
+
+int msm_server_update_sensor_info(struct msm_cam_v4l2_device *pcam,
+ struct msm_camera_sensor_info *sdata)
+{
+ int rc = 0;
+
+ if (!pcam || !sdata) {
+ pr_err("%s Input data is null ", __func__);
+ return -EINVAL;
+ }
+
+ g_server_dev.camera_info.video_dev_name
+ [g_server_dev.camera_info.num_cameras]
+ = video_device_node_name(pcam->pvdev);
+ D("%s Connected video device %s\n", __func__,
+ g_server_dev.camera_info.video_dev_name
+ [g_server_dev.camera_info.num_cameras]);
+
+ g_server_dev.camera_info.s_mount_angle
+ [g_server_dev.camera_info.num_cameras]
+ = sdata->sensor_platform_info->mount_angle;
+
+ g_server_dev.camera_info.is_internal_cam
+ [g_server_dev.camera_info.num_cameras]
+ = sdata->camera_type;
+
+ g_server_dev.mctl_node_info.mctl_node_name
+ [g_server_dev.mctl_node_info.num_mctl_nodes]
+ = video_device_node_name(pcam->mctl_node.pvdev);
+
+ pr_info("%s mctl_node_name[%d] = %s\n", __func__,
+ g_server_dev.mctl_node_info.num_mctl_nodes,
+ g_server_dev.mctl_node_info.mctl_node_name
+ [g_server_dev.mctl_node_info.num_mctl_nodes]);
+
+ /*Temporary solution to store info in media device structure
+ until we can expand media device structure to support more
+ device info*/
+ snprintf(pcam->media_dev.serial,
+ sizeof(pcam->media_dev.serial),
+ "%s-%d-%d", QCAMERA_NAME,
+ sdata->sensor_platform_info->mount_angle,
+ sdata->camera_type);
+
+ g_server_dev.camera_info.num_cameras++;
+ g_server_dev.mctl_node_info.num_mctl_nodes++;
+
+ D("%s done, rc = %d\n", __func__, rc);
+ D("%s number of sensors connected is %d\n", __func__,
+ g_server_dev.camera_info.num_cameras);
+
+ return rc;
+}
+
+int msm_server_begin_session(struct msm_cam_v4l2_device *pcam,
+ int server_q_idx)
+{
+ int rc = -EINVAL, ges_evt;
+ struct msm_cam_server_queue *queue;
+
+ if (!pcam) {
+ pr_err("%s pcam passed is null ", __func__);
+ return rc;
+ }
+
+ ges_evt = MSM_V4L2_GES_CAM_OPEN;
+ D("%s send gesture evt\n", __func__);
+ msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+ NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+
+ pcam->server_queue_idx = server_q_idx;
+ queue = &g_server_dev.server_queue[server_q_idx];
+ queue->ctrl_data = kzalloc(sizeof(uint8_t) *
+ max_control_command_size, GFP_KERNEL);
+ msm_queue_init(&queue->ctrl_q, "control");
+ msm_queue_init(&queue->eventData_q, "eventdata");
+ queue->queue_active = 1;
+
+ rc = msm_cam_server_open_session(&g_server_dev, pcam);
+ if (rc < 0) {
+ pr_err("%s: cam_server_open_session failed %d\n",
+ __func__, rc);
+ goto error;
+ }
+
+ return rc;
+error:
+ ges_evt = MSM_V4L2_GES_CAM_CLOSE;
+ msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+ NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+
+ queue->queue_active = 0;
+ msm_drain_eventq(&queue->eventData_q);
+ msm_queue_drain(&queue->ctrl_q, list_control);
+ kfree(queue->ctrl_data);
+ queue->ctrl_data = NULL;
+ queue = NULL;
+ return rc;
+}
+
+int msm_server_end_session(struct msm_cam_v4l2_device *pcam)
+{
+ int rc = -EINVAL, ges_evt;
+ struct msm_cam_server_queue *queue;
+
+ mutex_lock(&g_server_dev.server_queue_lock);
+ queue = &g_server_dev.server_queue[pcam->server_queue_idx];
+ queue->queue_active = 0;
+ kfree(queue->ctrl_data);
+ queue->ctrl_data = NULL;
+ msm_queue_drain(&queue->ctrl_q, list_control);
+ msm_drain_eventq(&queue->eventData_q);
+ mutex_unlock(&g_server_dev.server_queue_lock);
+
+ rc = msm_cam_server_close_session(&g_server_dev, pcam);
+ if (rc < 0)
+ pr_err("msm_cam_server_close_session fails %d\n", rc);
+
+ ges_evt = MSM_V4L2_GES_CAM_CLOSE;
+ msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+ NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+
+ return rc;
+}
+
+/* Init a config node for ISP control,
+ * which will create a config device (/dev/config0/ and plug in
+ * ISP's operation "v4l2_ioctl_ops*"
+ */
+static const struct v4l2_file_operations msm_fops_server = {
+ .owner = THIS_MODULE,
+ .open = msm_open_server,
+ .poll = msm_poll_server,
+ .unlocked_ioctl = video_ioctl2,
+ .release = msm_close_server,
+};
+
+static const struct v4l2_ioctl_ops msm_ioctl_ops_server = {
+ .vidioc_subscribe_event = msm_server_v4l2_subscribe_event,
+ .vidioc_default = msm_ioctl_server,
+};
+
+static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
+ unsigned int notification, void *arg)
+{
+ int rc = -EINVAL;
+ struct msm_sensor_ctrl_t *s_ctrl;
+ struct msm_camera_sensor_info *sinfo;
+ struct msm_camera_device_platform_data *camdev;
+ uint8_t csid_core = 0;
+
+ if (notification == NOTIFY_CID_CHANGE ||
+ notification == NOTIFY_ISPIF_STREAM ||
+ notification == NOTIFY_PCLK_CHANGE ||
+ notification == NOTIFY_CSIPHY_CFG ||
+ notification == NOTIFY_CSID_CFG ||
+ notification == NOTIFY_CSIC_CFG) {
+ s_ctrl = get_sctrl(sd);
+ sinfo = (struct msm_camera_sensor_info *) s_ctrl->sensordata;
+ camdev = sinfo->pdata;
+ csid_core = camdev->csid_core;
+ }
+
+ switch (notification) {
+ case NOTIFY_CID_CHANGE:
+ /* reconfig the ISPIF*/
+ if (g_server_dev.ispif_device) {
+ struct msm_ispif_params_list ispif_params;
+ ispif_params.len = 1;
+ ispif_params.params[0].intftype = PIX0;
+ ispif_params.params[0].cid_mask = 0x0001;
+ ispif_params.params[0].csid = csid_core;
+
+ rc = v4l2_subdev_call(
+ g_server_dev.ispif_device, core, ioctl,
+ VIDIOC_MSM_ISPIF_CFG, &ispif_params);
+ if (rc < 0)
+ return;
+ }
+ break;
+ case NOTIFY_ISPIF_STREAM:
+ /* call ISPIF stream on/off */
+ rc = v4l2_subdev_call(g_server_dev.ispif_device, video,
+ s_stream, (int)arg);
+ if (rc < 0)
+ return;
+
+ break;
+ case NOTIFY_ISP_MSG_EVT:
+ case NOTIFY_VFE_MSG_OUT:
+ case NOTIFY_VFE_MSG_STATS:
+ case NOTIFY_VFE_MSG_COMP_STATS:
+ case NOTIFY_VFE_BUF_EVT:
+ case NOTIFY_VFE_BUF_FREE_EVT:
+ if (g_server_dev.isp_subdev[0] &&
+ g_server_dev.isp_subdev[0]->isp_notify) {
+ rc = g_server_dev.isp_subdev[0]->isp_notify(
+ g_server_dev.vfe_device[0], notification, arg);
+ }
+ break;
+ case NOTIFY_VPE_MSG_EVT: {
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)
+ v4l2_get_subdev_hostdata(sd);
+ struct msm_vpe_resp *vdata = (struct msm_vpe_resp *)arg;
+ msm_mctl_pp_notify(pmctl,
+ (struct msm_mctl_pp_frame_info *)
+ vdata->extdata);
+ break;
+ }
+ case NOTIFY_VFE_IRQ:{
+ struct msm_vfe_cfg_cmd cfg_cmd;
+ struct msm_camvfe_params vfe_params;
+ cfg_cmd.cmd_type = CMD_VFE_PROCESS_IRQ;
+ vfe_params.vfe_cfg = &cfg_cmd;
+ vfe_params.data = arg;
+ rc = v4l2_subdev_call(g_server_dev.vfe_device[0],
+ core, ioctl, 0, &vfe_params);
+ }
+ break;
+ case NOTIFY_AXI_IRQ:
+ rc = v4l2_subdev_call(g_server_dev.axi_device[0],
+ core, ioctl, VIDIOC_MSM_AXI_IRQ, arg);
+ break;
+ case NOTIFY_PCLK_CHANGE:
+ if (g_server_dev.axi_device[0])
+ rc = v4l2_subdev_call(g_server_dev.axi_device[0], video,
+ s_crystal_freq, *(uint32_t *)arg, 0);
+ else
+ rc = v4l2_subdev_call(g_server_dev.vfe_device[0], video,
+ s_crystal_freq, *(uint32_t *)arg, 0);
+ break;
+ case NOTIFY_CSIPHY_CFG:
+ rc = v4l2_subdev_call(g_server_dev.csiphy_device[csid_core],
+ core, ioctl, VIDIOC_MSM_CSIPHY_CFG, arg);
+ break;
+ case NOTIFY_CSID_CFG:
+ rc = v4l2_subdev_call(g_server_dev.csid_device[csid_core],
+ core, ioctl, VIDIOC_MSM_CSID_CFG, arg);
+ break;
+ case NOTIFY_CSIC_CFG:
+ rc = v4l2_subdev_call(g_server_dev.csic_device[csid_core],
+ core, ioctl, VIDIOC_MSM_CSIC_CFG, arg);
+ break;
+ case NOTIFY_GESTURE_EVT:
+ rc = v4l2_subdev_call(g_server_dev.gesture_device,
+ core, ioctl, VIDIOC_MSM_GESTURE_EVT, arg);
+ break;
+ case NOTIFY_GESTURE_CAM_EVT:
+ rc = v4l2_subdev_call(g_server_dev.gesture_device,
+ core, ioctl, VIDIOC_MSM_GESTURE_CAM_EVT, arg);
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
+void msm_cam_release_subdev_node(struct video_device *vdev)
+{
+ struct v4l2_subdev *sd = video_get_drvdata(vdev);
+ sd->devnode = NULL;
+ kfree(vdev);
+}
+
+int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
+ enum msm_cam_subdev_type sdev_type, uint8_t index)
+{
+ struct video_device *vdev;
+ int err = 0;
+
+ switch (sdev_type) {
+ case CSIPHY_DEV:
+ if (index >= MAX_NUM_CSIPHY_DEV) {
+ pr_err("%s Invalid CSIPHY idx %d", __func__, index);
+ err = -EINVAL;
+ break;
+ }
+ g_server_dev.csiphy_device[index] = sd;
+ break;
+
+ case CSID_DEV:
+ if (index >= MAX_NUM_CSID_DEV) {
+ pr_err("%s Invalid CSID idx %d", __func__, index);
+ err = -EINVAL;
+ break;
+ }
+ g_server_dev.csid_device[index] = sd;
+ break;
+
+ case CSIC_DEV:
+ if (index >= MAX_NUM_CSIC_DEV) {
+ pr_err("%s Invalid CSIC idx %d", __func__, index);
+ err = -EINVAL;
+ break;
+ }
+ g_server_dev.csic_device[index] = sd;
+ break;
+
+ case ISPIF_DEV:
+ g_server_dev.ispif_device = sd;
+ break;
+
+ case VFE_DEV:
+ if (index >= MAX_NUM_VFE_DEV) {
+ pr_err("%s Invalid VFE idx %d", __func__, index);
+ err = -EINVAL;
+ break;
+ }
+ g_server_dev.vfe_device[index] = sd;
+ break;
+
+ case VPE_DEV:
+ if (index >= MAX_NUM_VPE_DEV) {
+ pr_err("%s Invalid VPE idx %d", __func__, index);
+ err = -EINVAL;
+ break;
+ }
+ g_server_dev.vpe_device[index] = sd;
+ break;
+
+ case AXI_DEV:
+ if (index >= MAX_NUM_VPE_DEV) {
+ pr_err("%s Invalid AXI idx %d", __func__, index);
+ err = -EINVAL;
+ break;
+ }
+ g_server_dev.axi_device[index] = sd;
+ break;
+
+ case GESTURE_DEV:
+ g_server_dev.gesture_device = sd;
+ break;
+ default:
+ break;
+ }
+
+ if (err < 0)
+ return err;
+
+ err = v4l2_device_register_subdev(&g_server_dev.v4l2_dev, sd);
+ if (err < 0) {
+ pr_err("%s v4l2 subdev register failed for %d ret = %d",
+ __func__, sdev_type, err);
+ return err;
+ }
+
+ /* Register a device node for every subdev marked with the
+ * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
+ */
+ if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
+ return err;
+
+ vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
+ if (!vdev) {
+ err = -ENOMEM;
+ goto clean_up;
+ }
+
+ video_set_drvdata(vdev, sd);
+ strlcpy(vdev->name, sd->name, sizeof(vdev->name));
+ vdev->v4l2_dev = &g_server_dev.v4l2_dev;
+ vdev->fops = &v4l2_subdev_fops;
+ vdev->release = msm_cam_release_subdev_node;
+ err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
+ sd->owner);
+ if (err < 0) {
+ kfree(vdev);
+ goto clean_up;
+ }
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ sd->entity.info.v4l.major = VIDEO_MAJOR;
+ sd->entity.info.v4l.minor = vdev->minor;
+#endif
+ sd->devnode = vdev;
+ return 0;
+
+clean_up:
+ if (sd->devnode)
+ video_unregister_device(sd->devnode);
+ return err;
+}
+
+static int msm_setup_server_dev(struct platform_device *pdev)
+{
+ int rc = -ENODEV, i;
+
+ D("%s\n", __func__);
+ g_server_dev.server_pdev = pdev;
+ g_server_dev.v4l2_dev.dev = &pdev->dev;
+ g_server_dev.v4l2_dev.notify = msm_cam_server_subdev_notify;
+ rc = v4l2_device_register(g_server_dev.v4l2_dev.dev,
+ &g_server_dev.v4l2_dev);
+ if (rc < 0)
+ return -EINVAL;
+
+ g_server_dev.video_dev = video_device_alloc();
+ if (g_server_dev.video_dev == NULL) {
+ pr_err("%s: video_device_alloc failed\n", __func__);
+ return rc;
+ }
+
+ strlcpy(g_server_dev.video_dev->name, pdev->name,
+ sizeof(g_server_dev.video_dev->name));
+
+ g_server_dev.video_dev->v4l2_dev = &g_server_dev.v4l2_dev;
+ g_server_dev.video_dev->fops = &msm_fops_server;
+ g_server_dev.video_dev->ioctl_ops = &msm_ioctl_ops_server;
+ g_server_dev.video_dev->release = video_device_release;
+ g_server_dev.video_dev->minor = 100;
+ g_server_dev.video_dev->vfl_type = 1;
+
+ video_set_drvdata(g_server_dev.video_dev, &g_server_dev);
+
+ strlcpy(g_server_dev.media_dev.model, "qcamera",
+ sizeof(g_server_dev.media_dev.model));
+ g_server_dev.media_dev.dev = &pdev->dev;
+ rc = media_device_register(&g_server_dev.media_dev);
+ g_server_dev.v4l2_dev.mdev = &g_server_dev.media_dev;
+
+ rc = video_register_device(g_server_dev.video_dev,
+ VFL_TYPE_GRABBER, 100);
+
+ mutex_init(&g_server_dev.server_lock);
+ mutex_init(&g_server_dev.server_queue_lock);
+ g_server_dev.pcam_active = NULL;
+ g_server_dev.camera_info.num_cameras = 0;
+ atomic_set(&g_server_dev.number_pcam_active, 0);
+ g_server_dev.server_evt_id = 0;
+
+ /*initialize fake video device and event queue*/
+
+ g_server_dev.server_command_queue.pvdev = g_server_dev.video_dev;
+ rc = msm_setup_v4l2_event_queue(
+ &g_server_dev.server_command_queue.eventHandle,
+ g_server_dev.server_command_queue.pvdev);
+
+ if (rc < 0) {
+ pr_err("%s failed to initialize event queue\n", __func__);
+ video_device_release(g_server_dev.server_command_queue.pvdev);
+ return rc;
+ }
+
+ for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+ struct msm_cam_server_queue *queue;
+ queue = &g_server_dev.server_queue[i];
+ queue->queue_active = 0;
+ msm_queue_init(&queue->ctrl_q, "control");
+ msm_queue_init(&queue->eventData_q, "eventdata");
+ }
+ return rc;
+}
+
+static long msm_server_send_v4l2_evt(void *evt)
+{
+ struct v4l2_event *v4l2_ev = (struct v4l2_event *)evt;
+ int rc = 0;
+
+ if (NULL == evt) {
+ pr_err("%s: evt is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ D("%s: evt type 0x%x\n", __func__, v4l2_ev->type);
+ if ((v4l2_ev->type >= MSM_GES_APP_EVT_MIN) &&
+ (v4l2_ev->type < MSM_GES_APP_EVT_MAX)) {
+ msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+ NOTIFY_GESTURE_EVT, v4l2_ev);
+ } else {
+ pr_err("%s: Invalid evt %d\n", __func__, v4l2_ev->type);
+ rc = -EINVAL;
+ }
+ D("%s: end\n", __func__);
+
+ return rc;
+}
+
+int msm_cam_server_open_mctl_session(struct msm_cam_v4l2_device *pcam,
+ int *p_active)
+{
+ int rc = 0;
+ struct msm_cam_media_controller *pmctl = NULL;
+ D("%s: %p", __func__, g_server_dev.pcam_active);
+ *p_active = 0;
+ if (g_server_dev.pcam_active) {
+ D("%s: Active camera present return", __func__);
+ return 0;
+ }
+ rc = msm_cam_server_open_session(&g_server_dev, pcam);
+ if (rc < 0) {
+ pr_err("%s: cam_server_open_session failed %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+ if (!pmctl->mctl_open) {
+ D("%s: media contoller is not inited\n",
+ __func__);
+ rc = -ENODEV;
+ return rc;
+ }
+
+ D("%s: call mctl_open\n", __func__);
+ rc = pmctl->mctl_open(pmctl, MSM_APPS_ID_V4L2);
+
+ if (rc < 0) {
+ pr_err("%s: HW open failed rc = 0x%x\n", __func__, rc);
+ return rc;
+ }
+ pmctl->pcam_ptr = pcam;
+ *p_active = 1;
+ return rc;
+}
+
+int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam)
+{
+ int rc = 0;
+ struct msm_cam_media_controller *pmctl = NULL;
+
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+ if (!pmctl) {
+ D("%s: invalid handle\n", __func__);
+ return -ENODEV;
+ }
+
+ if (pmctl->mctl_release) {
+ rc = pmctl->mctl_release(pmctl);
+ if (rc < 0)
+ pr_err("mctl_release fails %d\n", rc);
+ }
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ kref_put(&pmctl->refcount, msm_release_ion_client);
+#endif
+
+ rc = msm_cam_server_close_session(&g_server_dev, pcam);
+ if (rc < 0)
+ pr_err("msm_cam_server_close_session fails %d\n", rc);
+
+ return rc;
+}
+
+int msm_server_open_client(int *p_qidx)
+{
+ int rc = 0;
+ int server_q_idx = 0;
+ struct msm_cam_server_queue *queue = NULL;
+
+ mutex_lock(&g_server_dev.server_lock);
+ server_q_idx = msm_find_free_queue();
+ if (server_q_idx < 0) {
+ mutex_unlock(&g_server_dev.server_lock);
+ return server_q_idx;
+ }
+
+ *p_qidx = server_q_idx;
+ queue = &g_server_dev.server_queue[server_q_idx];
+ queue->ctrl_data = kzalloc(sizeof(uint8_t) *
+ max_control_command_size, GFP_KERNEL);
+ msm_queue_init(&queue->ctrl_q, "control");
+ msm_queue_init(&queue->eventData_q, "eventdata");
+ queue->queue_active = 1;
+ mutex_unlock(&g_server_dev.server_lock);
+ return rc;
+}
+
+int msm_server_send_ctrl(struct msm_ctrl_cmd *out,
+ int ctrl_id)
+{
+ int rc = 0;
+ void *value;
+ struct msm_queue_cmd *rcmd;
+ struct msm_queue_cmd *event_qcmd;
+ struct msm_ctrl_cmd *ctrlcmd;
+ struct msm_cam_server_dev *server_dev = &g_server_dev;
+ struct msm_device_queue *queue =
+ &server_dev->server_queue[out->queue_idx].ctrl_q;
+
+ struct v4l2_event v4l2_evt;
+ struct msm_isp_event_ctrl *isp_event;
+ isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
+ if (!isp_event) {
+ pr_err("%s Insufficient memory. return", __func__);
+ return -ENOMEM;
+ }
+ event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+ if (!event_qcmd) {
+ pr_err("%s Insufficient memory. return", __func__);
+ kfree(isp_event);
+ return -ENOMEM;
+ }
+
+ D("%s\n", __func__);
+ mutex_lock(&server_dev->server_queue_lock);
+ if (++server_dev->server_evt_id == 0)
+ server_dev->server_evt_id++;
+
+ D("%s qid %d evtid %d\n", __func__, out->queue_idx,
+ server_dev->server_evt_id);
+ server_dev->server_queue[out->queue_idx].evt_id =
+ server_dev->server_evt_id;
+ v4l2_evt.type = V4L2_EVENT_PRIVATE_START + ctrl_id;
+ v4l2_evt.u.data[0] = out->queue_idx;
+ /* setup event object to transfer the command; */
+ isp_event->resptype = MSM_CAM_RESP_V4L2;
+ isp_event->isp_data.ctrl = *out;
+ isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
+
+ atomic_set(&event_qcmd->on_heap, 1);
+ event_qcmd->command = isp_event;
+
+ msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
+ &event_qcmd->list_eventdata);
+
+ /* now send command to config thread in userspace,
+ * and wait for results */
+ v4l2_event_queue(server_dev->server_command_queue.pvdev,
+ &v4l2_evt);
+ D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
+ mutex_unlock(&server_dev->server_queue_lock);
+
+ /* wait for config return status */
+ D("Waiting for config status\n");
+ rc = wait_event_interruptible_timeout(queue->wait,
+ !list_empty_careful(&queue->list),
+ msecs_to_jiffies(out->timeout_ms));
+ D("Waiting is over for config status\n");
+ if (list_empty_careful(&queue->list)) {
+ if (!rc)
+ rc = -ETIMEDOUT;
+ if (rc < 0) {
+ kfree(isp_event);
+ pr_err("%s: wait_event error %d\n", __func__, rc);
+ return rc;
+ }
+ }
+
+ rcmd = msm_dequeue(queue, list_control);
+ BUG_ON(!rcmd);
+ D("%s Finished servicing ioctl\n", __func__);
+
+ ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
+ value = out->value;
+ if (ctrlcmd->length > 0 && value != NULL &&
+ ctrlcmd->length <= out->length)
+ memcpy(value, ctrlcmd->value, ctrlcmd->length);
+
+ memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
+ out->value = value;
+
+ kfree(ctrlcmd);
+ free_qcmd(rcmd);
+ kfree(isp_event);
+ D("%s: rc %d\n", __func__, rc);
+ /* rc is the time elapsed. */
+ if (rc >= 0) {
+ /* TODO: Refactor msm_ctrl_cmd::status field */
+ if (out->status == 0)
+ rc = -1;
+ else if (out->status == 1 || out->status == 4)
+ rc = 0;
+ else
+ rc = -EINVAL;
+ }
+ return rc;
+}
+
+int msm_server_close_client(int idx)
+{
+ int rc = 0;
+ struct msm_cam_server_queue *queue = NULL;
+ mutex_lock(&g_server_dev.server_lock);
+ queue = &g_server_dev.server_queue[idx];
+ queue->queue_active = 0;
+ kfree(queue->ctrl_data);
+ queue->ctrl_data = NULL;
+ msm_queue_drain(&queue->ctrl_q, list_control);
+ msm_drain_eventq(&queue->eventData_q);
+ mutex_unlock(&g_server_dev.server_lock);
+ return rc;
+}
+
+static unsigned int msm_poll_config(struct file *fp,
+ struct poll_table_struct *wait)
+{
+ int rc = 0;
+ struct msm_cam_config_dev *config = fp->private_data;
+ if (config == NULL)
+ return -EINVAL;
+
+ D("%s\n", __func__);
+
+ poll_wait(fp,
+ &config->config_stat_event_queue.eventHandle.wait, wait);
+ if (v4l2_event_pending(&config->config_stat_event_queue.eventHandle))
+ rc |= POLLPRI;
+ return rc;
+}
+
+static int msm_mmap_config(struct file *fp, struct vm_area_struct *vma)
+{
+ struct msm_cam_config_dev *config_cam = fp->private_data;
+ int rc = 0;
+ int phyaddr;
+ int retval;
+ unsigned long size;
+
+ D("%s: phy_addr=0x%x", __func__, config_cam->mem_map.cookie);
+ phyaddr = (int)config_cam->mem_map.cookie;
+ if (!phyaddr) {
+ pr_err("%s: no physical memory to map", __func__);
+ return -EFAULT;
+ }
+ memset(&config_cam->mem_map, 0,
+ sizeof(struct msm_mem_map_info));
+ size = vma->vm_end - vma->vm_start;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ retval = remap_pfn_range(vma, vma->vm_start,
+ phyaddr >> PAGE_SHIFT,
+ size, vma->vm_page_prot);
+ if (retval) {
+ pr_err("%s: remap failed, rc = %d",
+ __func__, retval);
+ rc = -ENOMEM;
+ goto end;
+ }
+ D("%s: phy_addr=0x%x: %08lx-%08lx, pgoff %08lx\n",
+ __func__, (uint32_t)phyaddr,
+ vma->vm_start, vma->vm_end, vma->vm_pgoff);
+end:
+ return rc;
+}
+
+static int msm_open_config(struct inode *inode, struct file *fp)
+{
+ int rc;
+ struct msm_cam_config_dev *config_cam = container_of(inode->i_cdev,
+ struct msm_cam_config_dev, config_cdev);
+
+ D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
+
+ rc = nonseekable_open(inode, fp);
+ if (rc < 0) {
+ pr_err("%s: nonseekable_open error %d\n", __func__, rc);
+ return rc;
+ }
+ config_cam->use_count++;
+
+ /* assume there is only one active camera possible*/
+ config_cam->p_mctl =
+ msm_cam_server_get_mctl(g_server_dev.pcam_active->mctl_handle);
+
+ INIT_HLIST_HEAD(&config_cam->p_mctl->stats_info.pmem_stats_list);
+ spin_lock_init(&config_cam->p_mctl->stats_info.pmem_stats_spinlock);
+
+ config_cam->p_mctl->config_device = config_cam;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ kref_get(&config_cam->p_mctl->refcount);
+#endif
+ fp->private_data = config_cam;
+ return rc;
+}
+
+static long msm_ioctl_config(struct file *fp, unsigned int cmd,
+ unsigned long arg)
+{
+
+ int rc = 0;
+ struct v4l2_event ev;
+ struct msm_cam_config_dev *config_cam = fp->private_data;
+ struct v4l2_event_subscription temp_sub;
+
+ D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+ ev.id = 0;
+
+ switch (cmd) {
+ /* memory management shall be handeld here*/
+ case MSM_CAM_IOCTL_REGISTER_PMEM:
+ return msm_register_pmem(
+ &config_cam->p_mctl->stats_info.pmem_stats_list,
+ (void __user *)arg, config_cam->p_mctl->client);
+ break;
+
+ case MSM_CAM_IOCTL_UNREGISTER_PMEM:
+ return msm_pmem_table_del(
+ &config_cam->p_mctl->stats_info.pmem_stats_list,
+ (void __user *)arg, config_cam->p_mctl->client);
+ break;
+
+ case VIDIOC_SUBSCRIBE_EVENT:
+ if (copy_from_user(&temp_sub,
+ (void __user *)arg,
+ sizeof(struct v4l2_event_subscription))) {
+ pr_err("%s copy_from_user failed for cmd %d ",
+ __func__, cmd);
+ rc = -EINVAL;
+ return rc;
+ }
+ rc = msm_server_v4l2_subscribe_event
+ (&config_cam->config_stat_event_queue.eventHandle,
+ &temp_sub);
+ if (rc < 0) {
+ pr_err("%s: cam_v4l2_subscribe_event failed rc=%d\n",
+ __func__, rc);
+ return rc;
+ }
+ break;
+
+ case VIDIOC_UNSUBSCRIBE_EVENT:
+ if (copy_from_user(&temp_sub, (void __user *)arg,
+ sizeof(struct v4l2_event_subscription))) {
+ rc = -EINVAL;
+ return rc;
+ }
+ rc = msm_server_v4l2_unsubscribe_event
+ (&config_cam->config_stat_event_queue.eventHandle,
+ &temp_sub);
+ if (rc < 0) {
+ pr_err("%s: cam_v4l2_unsubscribe_event failed rc=%d\n",
+ __func__, rc);
+ return rc;
+ }
+ break;
+
+ case VIDIOC_DQEVENT: {
+ void __user *u_msg_value = NULL, *user_ptr = NULL;
+ struct msm_isp_event_ctrl u_isp_event;
+ struct msm_isp_event_ctrl *k_isp_event;
+
+ /* First, copy the v4l2 event structure from userspace */
+ D("%s: VIDIOC_DQEVENT\n", __func__);
+ if (copy_from_user(&ev, (void __user *)arg,
+ sizeof(struct v4l2_event)))
+ break;
+ /* Next, get the pointer to event_ctrl structure
+ * embedded inside the v4l2_event.u.data array. */
+ user_ptr = (void __user *)(*((uint32_t *)ev.u.data));
+
+ /* Next, copy the userspace event ctrl structure */
+ if (copy_from_user((void *)&u_isp_event, user_ptr,
+ sizeof(struct msm_isp_event_ctrl))) {
+ break;
+ }
+ /* Save the pointer of the user allocated command buffer*/
+ u_msg_value = u_isp_event.isp_data.isp_msg.data;
+
+ /* Dequeue the event queued into the v4l2 queue*/
+ rc = v4l2_event_dequeue(
+ &config_cam->config_stat_event_queue.eventHandle,
+ &ev, fp->f_flags & O_NONBLOCK);
+ if (rc < 0) {
+ pr_err("no pending events?");
+ break;
+ }
+ /* Use k_isp_event to point to the event_ctrl structure
+ * embedded inside v4l2_event.u.data */
+ k_isp_event = (struct msm_isp_event_ctrl *)
+ (*((uint32_t *)ev.u.data));
+ /* Copy the event structure into user struct. */
+ u_isp_event = *k_isp_event;
+ if (ev.type != (V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_RESP_DIV_FRAME_EVT_MSG) &&
+ ev.type != (V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_RESP_MCTL_PP_EVENT)) {
+
+ /* Restore the saved pointer of the
+ * user allocated command buffer. */
+ u_isp_event.isp_data.isp_msg.data = u_msg_value;
+
+ if (ev.type == (V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_RESP_STAT_EVT_MSG)) {
+ if (k_isp_event->isp_data.isp_msg.len > 0) {
+ void *k_msg_value =
+ k_isp_event->isp_data.isp_msg.data;
+ if (copy_to_user(u_msg_value,
+ k_msg_value,
+ k_isp_event->isp_data.isp_msg.len)) {
+ rc = -EINVAL;
+ break;
+ }
+ kfree(k_msg_value);
+ }
+ }
+ }
+ /* Copy the event ctrl structure back
+ * into user's structure. */
+ if (copy_to_user(user_ptr,
+ (void *)&u_isp_event, sizeof(
+ struct msm_isp_event_ctrl))) {
+ rc = -EINVAL;
+ break;
+ }
+ kfree(k_isp_event);
+
+ /* Copy the v4l2_event structure back to the user*/
+ if (copy_to_user((void __user *)arg, &ev,
+ sizeof(struct v4l2_event))) {
+ rc = -EINVAL;
+ break;
+ }
+ }
+
+ break;
+
+ case MSM_CAM_IOCTL_V4L2_EVT_NOTIFY:
+ rc = msm_v4l2_evt_notify(config_cam->p_mctl, cmd, arg);
+ break;
+
+ case MSM_CAM_IOCTL_SET_MEM_MAP_INFO:
+ if (copy_from_user(&config_cam->mem_map, (void __user *)arg,
+ sizeof(struct msm_mem_map_info)))
+ rc = -EINVAL;
+ break;
+
+ default:{
+ /* For the rest of config command, forward to media controller*/
+ struct msm_cam_media_controller *p_mctl = config_cam->p_mctl;
+ if (p_mctl && p_mctl->mctl_cmd) {
+ rc = config_cam->p_mctl->mctl_cmd(p_mctl, cmd, arg);
+ } else {
+ rc = -EINVAL;
+ pr_err("%s: media controller is null\n", __func__);
+ }
+
+ break;
+ } /* end of default*/
+ } /* end of switch*/
+ return rc;
+}
+
+static int msm_close_config(struct inode *node, struct file *f)
+{
+ struct v4l2_event ev;
+ struct v4l2_event_subscription sub;
+ struct msm_isp_event_ctrl *isp_event;
+ struct msm_cam_config_dev *config_cam = f->private_data;
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ D("%s Decrementing ref count of config node ", __func__);
+ kref_put(&config_cam->p_mctl->refcount, msm_release_ion_client);
+#endif
+ sub.type = V4L2_EVENT_ALL;
+ msm_server_v4l2_unsubscribe_event(
+ &config_cam->config_stat_event_queue.eventHandle,
+ &sub);
+ while (v4l2_event_pending(
+ &config_cam->config_stat_event_queue.eventHandle)) {
+ v4l2_event_dequeue(
+ &config_cam->config_stat_event_queue.eventHandle,
+ &ev, O_NONBLOCK);
+ isp_event = (struct msm_isp_event_ctrl *)
+ (*((uint32_t *)ev.u.data));
+ if (isp_event) {
+ if (isp_event->isp_data.isp_msg.len != 0 &&
+ isp_event->isp_data.isp_msg.data != NULL)
+ kfree(isp_event->isp_data.isp_msg.data);
+ kfree(isp_event);
+ }
+ }
+ return 0;
+}
+
+static const struct file_operations msm_fops_config = {
+ .owner = THIS_MODULE,
+ .open = msm_open_config,
+ .poll = msm_poll_config,
+ .unlocked_ioctl = msm_ioctl_config,
+ .mmap = msm_mmap_config,
+ .release = msm_close_config,
+};
+
+static int msm_setup_config_dev(int node, char *device_name)
+{
+ int rc = -ENODEV;
+ struct device *device_config;
+ int dev_num = node;
+ dev_t devno;
+ struct msm_cam_config_dev *config_cam;
+
+ config_cam = kzalloc(sizeof(*config_cam), GFP_KERNEL);
+ if (!config_cam) {
+ pr_err("%s: could not allocate memory for config_device\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ D("%s\n", __func__);
+
+ devno = MKDEV(MAJOR(msm_devno), dev_num+1);
+ device_config = device_create(msm_class, NULL, devno, NULL, "%s%d",
+ device_name, dev_num);
+
+ if (IS_ERR(device_config)) {
+ rc = PTR_ERR(device_config);
+ pr_err("%s: error creating device: %d\n", __func__, rc);
+ goto config_setup_fail;
+ }
+
+ cdev_init(&config_cam->config_cdev, &msm_fops_config);
+ config_cam->config_cdev.owner = THIS_MODULE;
+
+ rc = cdev_add(&config_cam->config_cdev, devno, 1);
+ if (rc < 0) {
+ pr_err("%s: error adding cdev: %d\n", __func__, rc);
+ device_destroy(msm_class, devno);
+ goto config_setup_fail;
+ }
+ g_server_dev.config_info.config_dev_name[dev_num] =
+ dev_name(device_config);
+ D("%s Connected config device %s\n", __func__,
+ g_server_dev.config_info.config_dev_name[dev_num]);
+ g_server_dev.config_info.config_dev_id[dev_num] =
+ dev_num;
+
+ config_cam->config_stat_event_queue.pvdev = video_device_alloc();
+ if (config_cam->config_stat_event_queue.pvdev == NULL) {
+ pr_err("%s: video_device_alloc failed\n", __func__);
+ goto config_setup_fail;
+ }
+
+ rc = msm_setup_v4l2_event_queue(
+ &config_cam->config_stat_event_queue.eventHandle,
+ config_cam->config_stat_event_queue.pvdev);
+ if (rc < 0) {
+ pr_err("%s failed to initialize event queue\n", __func__);
+ video_device_release(config_cam->config_stat_event_queue.pvdev);
+ goto config_setup_fail;
+ }
+
+ return rc;
+
+config_setup_fail:
+ kfree(config_cam);
+ return rc;
+}
+
+static int __devinit msm_camera_probe(struct platform_device *pdev)
+{
+ int rc = 0, i;
+ /*for now just create a config 0 node
+ put logic here later to know how many configs to create*/
+ g_server_dev.config_info.num_config_nodes = 1;
+
+ rc = msm_isp_init_module(g_server_dev.config_info.num_config_nodes);
+ if (rc < 0) {
+ pr_err("Failed to initialize isp\n");
+ return rc;
+ }
+
+ if (!msm_class) {
+ rc = alloc_chrdev_region(&msm_devno, 0,
+ g_server_dev.config_info.num_config_nodes+1, "msm_camera");
+ if (rc < 0) {
+ pr_err("%s: failed to allocate chrdev: %d\n", __func__,
+ rc);
+ return rc;
+ }
+
+ msm_class = class_create(THIS_MODULE, "msm_camera");
+ if (IS_ERR(msm_class)) {
+ rc = PTR_ERR(msm_class);
+ pr_err("%s: create device class failed: %d\n",
+ __func__, rc);
+ return rc;
+ }
+ }
+
+ D("creating server and config nodes\n");
+ rc = msm_setup_server_dev(pdev);
+ if (rc < 0) {
+ pr_err("%s: failed to create server dev: %d\n", __func__,
+ rc);
+ return rc;
+ }
+
+ for (i = 0; i < g_server_dev.config_info.num_config_nodes; i++) {
+ rc = msm_setup_config_dev(i, "config");
+ if (rc < 0) {
+ pr_err("%s:failed to create config dev: %d\n",
+ __func__, rc);
+ return rc;
+ }
+ }
+
+ msm_isp_register(&g_server_dev);
+ return rc;
+}
+
+static int __exit msm_camera_exit(struct platform_device *pdev)
+{
+ msm_isp_unregister(&g_server_dev);
+ return 0;
+}
+
+static struct platform_driver msm_cam_server_driver = {
+ .probe = msm_camera_probe,
+ .remove = msm_camera_exit,
+ .driver = {
+ .name = "msm_cam_server",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init msm_cam_server_init(void)
+{
+ return platform_driver_register(&msm_cam_server_driver);
+}
+
+static void __exit msm_cam_server_exit(void)
+{
+ platform_driver_unregister(&msm_cam_server_driver);
+}
+
+module_init(msm_cam_server_init);
+module_exit(msm_cam_server_exit);
+MODULE_DESCRIPTION("msm camera server");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/server/msm_cam_server.h b/drivers/media/video/msm/server/msm_cam_server.h
new file mode 100644
index 0000000..2fe4c2b
--- /dev/null
+++ b/drivers/media/video/msm/server/msm_cam_server.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MSM_CAM_SERVER_H
+#define _MSM_CAM_SERVER_H
+
+#include <linux/proc_fs.h>
+#include <linux/ioctl.h>
+#include <mach/camera.h>
+#include "msm.h"
+
+uint32_t msm_cam_server_get_mctl_handle(void);
+struct msm_cam_media_controller *msm_cam_server_get_mctl(uint32_t handle);
+void msm_cam_server_free_mctl(uint32_t handle);
+/* Server session control APIs */
+int msm_server_begin_session(struct msm_cam_v4l2_device *pcam,
+ int server_q_idx);
+int msm_server_end_session(struct msm_cam_v4l2_device *pcam);
+int msm_send_open_server(struct msm_cam_v4l2_device *pcam);
+int msm_send_close_server(struct msm_cam_v4l2_device *pcam);
+int msm_server_update_sensor_info(struct msm_cam_v4l2_device *pcam,
+ struct msm_camera_sensor_info *sdata);
+/* Server camera control APIs */
+int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx);
+int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx);
+int msm_server_get_usecount(void);
+int32_t msm_find_free_queue(void);
+int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_control *ctrl, int is_set_cmd);
+int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_control *ctrl);
+int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_control *ctrl);
+int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_queryctrl *queryctrl);
+int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
+ struct v4l2_format *pfmt);
+int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
+ struct v4l2_format *pfmt);
+int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
+ int idx, struct v4l2_format *pfmt);
+int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+ int idx, struct v4l2_format *pfmt);
+int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_format *pfmt);
+int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+ struct v4l2_format *pfmt);
+int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub);
+int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub);
+int msm_server_get_crop(struct msm_cam_v4l2_device *pcam,
+ int idx, struct v4l2_crop *crop);
+
+#endif /* _MSM_CAM_SERVER_H */
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 20a0cd0..0c26027 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -224,6 +224,14 @@
.num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
+ },
+ {
+ .name = "DIVX",
+ .description = "DIVX 4/5/6 compressed format",
+ .fourcc = V4L2_PIX_FMT_DIVX,
+ .num_planes = 1,
+ .get_frame_size = get_frame_size_compressed,
+ .type = OUTPUT_PORT,
}
};
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 6b06943..52f1dca 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -629,8 +629,10 @@
case V4L2_PIX_FMT_DIVX_311:
codec = HAL_VIDEO_CODEC_DIVX_311;
break;
+ case V4L2_PIX_FMT_DIVX:
+ codec = HAL_VIDEO_CODEC_DIVX;
+ break;
/*HAL_VIDEO_CODEC_MVC
- HAL_VIDEO_CODEC_DIVX
HAL_VIDEO_CODEC_SPARK
HAL_VIDEO_CODEC_VP6
HAL_VIDEO_CODEC_VP7
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 cb44d3a..02b9699 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
+++ b/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
@@ -510,9 +510,12 @@
if (sizeof(struct
hfi_msg_session_fill_buffer_done_compressed_packet)
!= pkt->size) {
- HAL_MSG_ERROR("hal_process_session_ftb_done:"
- "bad_pkt_size");
+ HAL_MSG_ERROR("%s: bad_pkt_size", __func__);
return;
+ } else if (pkt->error_type != HFI_ERR_NONE) {
+ HAL_MSG_ERROR("%s: got buffer back with error %x",
+ __func__, pkt->error_type);
+ /* Proceed with the FBD */
}
data_done.device_id = device->device_id;
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c
index 1748df7..bd36aea 100644
--- a/drivers/mtd/devices/msm_nand.c
+++ b/drivers/mtd/devices/msm_nand.c
@@ -76,6 +76,8 @@
uint32_t ecc_bch_cfg;
uint32_t ecc_parity_bytes;
unsigned cw_size;
+ unsigned int uncorrectable_bit_mask;
+ unsigned int num_err_mask;
};
#define CFG1_WIDE_FLASH (1U << 1)
@@ -1111,9 +1113,8 @@
}
if (pageerr) {
for (n = start_sector; n < cwperpage; n++) {
- if (enable_bch_ecc ?
- (dma_buffer->data.result[n].buffer_status & 0x10) :
- (dma_buffer->data.result[n].buffer_status & 0x8)) {
+ if (dma_buffer->data.result[n].buffer_status &
+ chip->uncorrectable_bit_mask) {
/* not thread safe */
mtd->ecc_stats.failed++;
pageerr = -EBADMSG;
@@ -1123,9 +1124,9 @@
}
if (!rawerr) { /* check for corretable errors */
for (n = start_sector; n < cwperpage; n++) {
- ecc_errors = enable_bch_ecc ?
- (dma_buffer->data.result[n].buffer_status & 0xF) :
- (dma_buffer->data.result[n].buffer_status & 0x7);
+ ecc_errors =
+ (dma_buffer->data.result[n].buffer_status
+ & chip->num_err_mask);
if (ecc_errors) {
total_ecc_errors += ecc_errors;
/* not thread safe */
@@ -1893,7 +1894,7 @@
if (pageerr) {
for (n = start_sector; n < cwperpage; n++) {
if (dma_buffer->data.result[n].buffer_status
- & MSM_NAND_BUF_STAT_UNCRCTBL_ERR) {
+ & chip->uncorrectable_bit_mask) {
/* not thread safe */
mtd->ecc_stats.failed++;
pageerr = -EBADMSG;
@@ -1905,7 +1906,7 @@
for (n = start_sector; n < cwperpage; n++) {
ecc_errors = dma_buffer->data.
result[n].buffer_status
- & MSM_NAND_BUF_STAT_NUM_ERR_MASK;
+ & chip->num_err_mask;
if (ecc_errors) {
total_ecc_errors += ecc_errors;
/* not thread safe */
@@ -7043,6 +7044,15 @@
pr_info("%s: allocated dma buffer at %p, dma_addr %x\n",
__func__, info->msm_nand.dma_buffer, info->msm_nand.dma_addr);
+ /* Let default be VERSION_1 for backward compatibility */
+ info->msm_nand.uncorrectable_bit_mask = BIT(3);
+ info->msm_nand.num_err_mask = 0x7;
+
+ if (plat_data && (plat_data->version == VERSION_2)) {
+ info->msm_nand.uncorrectable_bit_mask = BIT(8);
+ info->msm_nand.num_err_mask = 0x1F;
+ }
+
info->mtd.name = dev_name(&pdev->dev);
info->mtd.priv = &info->msm_nand;
info->mtd.owner = THIS_MODULE;
diff --git a/drivers/mtd/devices/msm_nand.h b/drivers/mtd/devices/msm_nand.h
index 2729c6b..8156b92 100644
--- a/drivers/mtd/devices/msm_nand.h
+++ b/drivers/mtd/devices/msm_nand.h
@@ -187,9 +187,6 @@
#define EBI2_CFG_REG EBI2_REG(0x0004)
#define EBI2_NAND_ADM_MUX EBI2_REG(0x005C)
-#define MSM_NAND_BUF_STAT_UNCRCTBL_ERR (1 << 8)
-#define MSM_NAND_BUF_STAT_NUM_ERR_MASK (enable_bch_ecc ? 0x1F : 0x0F)
-
extern struct flash_platform_data msm_nand_data;
#endif
diff --git a/drivers/power/msm_battery.c b/drivers/power/msm_battery.c
index 0555399..5abc032 100644
--- a/drivers/power/msm_battery.c
+++ b/drivers/power/msm_battery.c
@@ -209,6 +209,7 @@
struct msm_battery_info {
u32 voltage_max_design;
u32 voltage_min_design;
+ u32 voltage_fail_safe;
u32 chg_api_version;
u32 batt_technology;
u32 batt_api_version;
@@ -760,8 +761,10 @@
if (msm_batt_info.batt_handle != INVALID_BATT_HANDLE) {
rc = msm_batt_modify_client(msm_batt_info.batt_handle,
- BATTERY_LOW, BATTERY_VOLTAGE_BELOW_THIS_LEVEL,
- BATTERY_CB_ID_LOW_VOL, BATTERY_LOW);
+ msm_batt_info.voltage_fail_safe,
+ BATTERY_VOLTAGE_BELOW_THIS_LEVEL,
+ BATTERY_CB_ID_LOW_VOL,
+ msm_batt_info.voltage_fail_safe);
if (rc < 0) {
pr_err("%s: msm_batt_modify_client. rc=%d\n",
@@ -784,8 +787,9 @@
if (msm_batt_info.batt_handle != INVALID_BATT_HANDLE) {
rc = msm_batt_modify_client(msm_batt_info.batt_handle,
- BATTERY_LOW, BATTERY_ALL_ACTIVITY,
- BATTERY_CB_ID_ALL_ACTIV, BATTERY_ALL_ACTIVITY);
+ msm_batt_info.voltage_fail_safe,
+ BATTERY_ALL_ACTIVITY,
+ BATTERY_CB_ID_ALL_ACTIV, BATTERY_ALL_ACTIVITY);
if (rc < 0) {
pr_err("%s: msm_batt_modify_client FAIL rc=%d\n",
__func__, rc);
@@ -1373,6 +1377,8 @@
msm_batt_info.voltage_max_design = pdata->voltage_max_design;
msm_batt_info.voltage_min_design = pdata->voltage_min_design;
+ msm_batt_info.voltage_fail_safe = pdata->voltage_fail_safe;
+
msm_batt_info.batt_technology = pdata->batt_technology;
msm_batt_info.calculate_capacity = pdata->calculate_capacity;
@@ -1380,6 +1386,8 @@
msm_batt_info.voltage_min_design = BATTERY_LOW;
if (!msm_batt_info.voltage_max_design)
msm_batt_info.voltage_max_design = BATTERY_HIGH;
+ if (!msm_batt_info.voltage_fail_safe)
+ msm_batt_info.voltage_fail_safe = BATTERY_LOW;
if (msm_batt_info.batt_technology == POWER_SUPPLY_TECHNOLOGY_UNKNOWN)
msm_batt_info.batt_technology = POWER_SUPPLY_TECHNOLOGY_LION;
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 679734d..fea22b6 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/string.h>
#include <linux/regulator/machine.h>
static void of_get_regulation_constraints(struct device_node *np,
@@ -61,6 +62,71 @@
constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;
}
+static const char *consumer_supply_prop_name = "qcom,consumer-supplies";
+#define MAX_DEV_NAME_LEN 256
+/*
+ * Fill in regulator init_data based on qcom legacy requirements.
+ */
+static int of_get_qcom_regulator_init_data(struct device *dev,
+ struct regulator_init_data **init_data)
+{
+ struct device_node *node = dev->of_node;
+ struct regulator_consumer_supply *consumer_supplies;
+ int i, rc, num_consumer_supplies, array_len;
+
+ array_len = of_property_count_strings(node, consumer_supply_prop_name);
+ if (array_len > 0) {
+ /* Array length must be divisible by 2. */
+ if (array_len & 1) {
+ dev_err(dev, "error: %s device node property value "
+ "contains an odd number of elements: %d\n",
+ consumer_supply_prop_name, array_len);
+ return -EINVAL;
+ }
+ num_consumer_supplies = array_len / 2;
+
+ consumer_supplies = devm_kzalloc(dev,
+ sizeof(struct regulator_consumer_supply)
+ * num_consumer_supplies, GFP_KERNEL);
+ if (consumer_supplies == NULL) {
+ dev_err(dev, "devm_kzalloc failed\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < num_consumer_supplies; i++) {
+ rc = of_property_read_string_index(node,
+ consumer_supply_prop_name, i * 2,
+ &consumer_supplies[i].supply);
+ if (rc) {
+ dev_err(dev, "of_property_read_string_index "
+ "failed, rc=%d\n", rc);
+ devm_kfree(dev, consumer_supplies);
+ return rc;
+ }
+
+ rc = of_property_read_string_index(node,
+ consumer_supply_prop_name, (i * 2) + 1,
+ &consumer_supplies[i].dev_name);
+ if (rc) {
+ dev_err(dev, "of_property_read_string_index "
+ "failed, rc=%d\n", rc);
+ devm_kfree(dev, consumer_supplies);
+ return rc;
+ }
+
+ /* Treat dev_name = "" as a wildcard. */
+ if (strnlen(consumer_supplies[i].dev_name,
+ MAX_DEV_NAME_LEN) == 0)
+ consumer_supplies[i].dev_name = NULL;
+ }
+
+ (*init_data)->consumer_supplies = consumer_supplies;
+ (*init_data)->num_consumer_supplies = num_consumer_supplies;
+ }
+
+ return 0;
+}
+
/**
* of_get_regulator_init_data - extract regulator_init_data structure info
* @dev: device requesting for regulator_init_data
@@ -73,6 +139,7 @@
struct device_node *node)
{
struct regulator_init_data *init_data;
+ int rc;
if (!node)
return NULL;
@@ -82,6 +149,12 @@
return NULL; /* Out of memory? */
of_get_regulation_constraints(node, &init_data);
+ rc = of_get_qcom_regulator_init_data(dev, &init_data);
+ if (rc) {
+ devm_kfree(dev, init_data);
+ return NULL;
+ }
+
return init_data;
}
EXPORT_SYMBOL_GPL(of_get_regulator_init_data);
diff --git a/drivers/regulator/pm8xxx-regulator.c b/drivers/regulator/pm8xxx-regulator.c
index 833c513..dfdbb44 100644
--- a/drivers/regulator/pm8xxx-regulator.c
+++ b/drivers/regulator/pm8xxx-regulator.c
@@ -595,6 +595,29 @@
return enabled;
}
+/*
+ * Adds delay when increasing in voltage to account for the slew rate of
+ * the regulator.
+ */
+static void pm8xxx_vreg_delay_for_slew(struct pm8xxx_vreg *vreg, int prev_uV,
+ int new_uV)
+{
+ int delay;
+
+ if (vreg->pdata.slew_rate == 0 || new_uV <= prev_uV ||
+ !_pm8xxx_vreg_is_enabled(vreg))
+ return;
+
+ delay = DIV_ROUND_UP(new_uV - prev_uV, vreg->pdata.slew_rate);
+
+ if (delay >= 1000) {
+ mdelay(delay / 1000);
+ udelay(delay % 1000);
+ } else {
+ udelay(delay);
+ }
+}
+
static int pm8xxx_pldo_get_voltage(struct regulator_dev *rdev)
{
struct pm8xxx_vreg *vreg = rdev_get_drvdata(rdev);
@@ -655,7 +678,7 @@
{
struct pm8xxx_vreg *vreg = rdev_get_drvdata(rdev);
int rc = 0, uV = min_uV;
- int vmin;
+ int vmin, prev_uV;
unsigned vprog, fine_step;
u8 range_ext, range_sel, fine_step_reg, prev_reg;
bool reg_changed = false;
@@ -699,6 +722,8 @@
return -EINVAL;
}
+ prev_uV = pm8xxx_pldo_get_voltage(rdev);
+
mutex_lock(&vreg->pc_lock);
/* Write fine step, range select and program voltage update. */
@@ -746,8 +771,10 @@
if (rc)
vreg_err(vreg, "pm8xxx_vreg_masked_write failed, rc=%d\n", rc);
- else
+ else {
+ pm8xxx_vreg_delay_for_slew(vreg, prev_uV, uV);
pm8xxx_vreg_show_state(rdev, PM8XXX_REGULATOR_ACTION_VOLTAGE);
+ }
return rc;
}
@@ -783,7 +810,7 @@
{
struct pm8xxx_vreg *vreg = rdev_get_drvdata(rdev);
unsigned vprog, fine_step_reg, prev_reg;
- int rc;
+ int rc, prev_uV;
int uV = min_uV;
if (uV < NLDO_UV_MIN && max_uV >= NLDO_UV_MIN)
@@ -808,6 +835,8 @@
return -EINVAL;
}
+ prev_uV = pm8xxx_nldo_get_voltage(rdev);
+
mutex_lock(&vreg->pc_lock);
/* Write fine step. */
@@ -840,8 +869,10 @@
if (rc)
vreg_err(vreg, "pm8xxx_vreg_masked_write failed, rc=%d\n", rc);
- else
+ else {
+ pm8xxx_vreg_delay_for_slew(vreg, prev_uV, uV);
pm8xxx_vreg_show_state(rdev, PM8XXX_REGULATOR_ACTION_VOLTAGE);
+ }
return rc;
}
@@ -897,7 +928,7 @@
int max_uV)
{
u8 vprog, range;
- int rc;
+ int rc, prev_uV;
int uV = min_uV;
if (uV < NLDO1200_LOW_UV_MIN && max_uV >= NLDO1200_LOW_UV_MIN)
@@ -931,6 +962,8 @@
return -EINVAL;
}
+ prev_uV = _pm8xxx_nldo1200_get_voltage(vreg);
+
/* Set to advanced mode */
rc = pm8xxx_vreg_masked_write(vreg, vreg->test_addr,
NLDO1200_ADVANCED_MODE | REGULATOR_BANK_SEL(2)
@@ -948,6 +981,7 @@
vreg->save_uV = uV;
+ pm8xxx_vreg_delay_for_slew(vreg, prev_uV, uV);
bail:
if (rc)
vreg_err(vreg, "pm8xxx_vreg_masked_write failed, rc=%d\n", rc);
@@ -1208,6 +1242,9 @@
{
struct pm8xxx_vreg *vreg = rdev_get_drvdata(rdev);
int rc = 0;
+ int prev_uV, new_uV;
+
+ prev_uV = pm8xxx_smps_get_voltage(rdev);
mutex_lock(&vreg->pc_lock);
@@ -1218,8 +1255,12 @@
mutex_unlock(&vreg->pc_lock);
- if (!rc)
+ new_uV = pm8xxx_smps_get_voltage(rdev);
+
+ if (!rc) {
+ pm8xxx_vreg_delay_for_slew(vreg, prev_uV, new_uV);
pm8xxx_vreg_show_state(rdev, PM8XXX_REGULATOR_ACTION_VOLTAGE);
+ }
return rc;
}
@@ -1291,6 +1332,7 @@
int rc = 0;
u8 vprog, band;
int uV = min_uV;
+ int prev_uV;
if (uV < FTSMPS_BAND1_UV_MIN && max_uV >= FTSMPS_BAND1_UV_MIN)
uV = FTSMPS_BAND1_UV_MIN;
@@ -1336,6 +1378,8 @@
return -EINVAL;
}
+ prev_uV = _pm8xxx_ftsmps_get_voltage(vreg);
+
/*
* Do not set voltage if regulator is currently disabled because doing
* so will enable it.
@@ -1358,6 +1402,8 @@
vreg->save_uV = uV;
+ pm8xxx_vreg_delay_for_slew(vreg, prev_uV, uV);
+
bail:
if (rc)
vreg_err(vreg, "pm8xxx_vreg_masked_write failed, rc=%d\n", rc);
@@ -1402,7 +1448,7 @@
int max_uV, unsigned *selector)
{
struct pm8xxx_vreg *vreg = rdev_get_drvdata(rdev);
- int rc;
+ int rc, prev_uV;
int uV = min_uV;
u8 val;
@@ -1426,13 +1472,17 @@
return -EINVAL;
}
+ prev_uV = pm8xxx_ncp_get_voltage(rdev);
+
/* voltage setting */
rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr, val,
NCP_VPROG_MASK, &vreg->ctrl_reg);
if (rc)
vreg_err(vreg, "pm8xxx_vreg_masked_write failed, rc=%d\n", rc);
- else
+ else {
+ pm8xxx_vreg_delay_for_slew(vreg, prev_uV, uV);
pm8xxx_vreg_show_state(rdev, PM8XXX_REGULATOR_ACTION_VOLTAGE);
+ }
return rc;
}
@@ -1460,7 +1510,7 @@
int max_uV, unsigned *selector)
{
struct pm8xxx_vreg *vreg = rdev_get_drvdata(rdev);
- int rc;
+ int rc, prev_uV;
int uV = min_uV;
u8 val;
@@ -1484,13 +1534,17 @@
return -EINVAL;
}
+ prev_uV = pm8xxx_boost_get_voltage(rdev);
+
/* voltage setting */
rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr, val,
BOOST_VPROG_MASK, &vreg->ctrl_reg);
if (rc)
vreg_err(vreg, "pm8xxx_vreg_masked_write failed, rc=%d\n", rc);
- else
+ else {
+ pm8xxx_vreg_delay_for_slew(vreg, prev_uV, uV);
pm8xxx_vreg_show_state(rdev, PM8XXX_REGULATOR_ACTION_VOLTAGE);
+ }
return rc;
}
@@ -3151,6 +3205,16 @@
sizeof(struct pm8xxx_regulator_platform_data));
vreg->pdata.pin_ctrl = pin_ctrl;
vreg->pdata.pin_fn = pin_fn;
+ /*
+ * If slew_rate isn't specified but enable_time is, then set
+ * slew_rate = max_uV / enable_time.
+ */
+ if (vreg->pdata.enable_time > 0
+ && vreg->pdata.init_data.constraints.max_uV > 0
+ && vreg->pdata.slew_rate <= 0)
+ vreg->pdata.slew_rate =
+ DIV_ROUND_UP(vreg->pdata.init_data.constraints.max_uV,
+ vreg->pdata.enable_time);
vreg->dev = &pdev->dev;
} else {
/* Pin control regulator */
diff --git a/drivers/tty/smux_loopback.c b/drivers/tty/smux_loopback.c
index 52ce17f..bf6d50b 100644
--- a/drivers/tty/smux_loopback.c
+++ b/drivers/tty/smux_loopback.c
@@ -262,8 +262,7 @@
smux_init_pkt(&reply_pkt);
reply_pkt.hdr.lcid = lcid;
reply_pkt.hdr.cmd = SMUX_CMD_PWR_CTL;
- reply_pkt.hdr.flags = SMUX_CMD_PWR_CTL_SLEEP_REQ
- | SMUX_CMD_PWR_CTL_ACK;
+ reply_pkt.hdr.flags = SMUX_CMD_PWR_CTL_ACK;
reply_pkt.hdr.payload_len = 0;
reply_pkt.payload = NULL;
reply_pkt.hdr.pad_len = pkt->hdr.pad_len;
diff --git a/drivers/tty/smux_private.h b/drivers/tty/smux_private.h
index 5ce8fb8..6bd9713 100644
--- a/drivers/tty/smux_private.h
+++ b/drivers/tty/smux_private.h
@@ -78,7 +78,6 @@
/* Power command flags */
enum {
SMUX_CMD_PWR_CTL_ACK = 1 << 0,
- SMUX_CMD_PWR_CTL_SLEEP_REQ = 1 << 1,
};
/* Local logical channel states */
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 7c37aff..66ba02b 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1599,6 +1599,9 @@
usbmon_urb_complete(&hcd->self, urb, status);
usb_unanchor_urb(urb);
+ if (hcd->driver->log_urb_complete)
+ hcd->driver->log_urb_complete(urb, "C", status);
+
/* pass ownership to the completion handler */
urb->status = status;
urb->complete (urb);
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index bdde862..6a6f6e5 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -691,6 +691,9 @@
hw->hw_alt_next = QTD_NEXT(ehci, ehci->async->dummy->qtd_dma);
/* clear interrupt enables, set irq latency */
+ if (ehci->max_log2_irq_thresh)
+ log2_irq_thresh = ehci->max_log2_irq_thresh;
+
if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
log2_irq_thresh = 0;
temp = 1 << (16 + log2_irq_thresh);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index fd3d1ca..6bd0577 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -39,6 +39,7 @@
#include <mach/msm_iomap.h>
#include <mach/msm_xo.h>
#include <linux/spinlock.h>
+#include <linux/cpu.h>
#define MSM_USB_BASE (hcd->regs)
@@ -64,6 +65,183 @@
};
static bool debug_bus_voting_enabled = true;
+
+static unsigned int enable_dbg_log = 1;
+module_param(enable_dbg_log, uint, S_IRUGO | S_IWUSR);
+/*by default log ep0 and efs sync ep*/
+static unsigned int ep_addr_rxdbg_mask = 9;
+module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
+static unsigned int ep_addr_txdbg_mask = 9;
+module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);
+
+/* Maximum debug message length */
+#define DBG_MSG_LEN 100UL
+
+/* Maximum number of messages */
+#define DBG_MAX_MSG 256UL
+
+#define TIME_BUF_LEN 20
+
+enum event_type {
+ EVENT_UNDEF = -1,
+ URB_SUBMIT,
+ URB_COMPLETE,
+ EVENT_NONE,
+};
+
+#define EVENT_STR_LEN 5
+
+static char *event_to_str(enum event_type e)
+{
+ switch (e) {
+ case URB_SUBMIT:
+ return "S";
+ case URB_COMPLETE:
+ return "C";
+ case EVENT_NONE:
+ return "NONE";
+ default:
+ return "UNDEF";
+ }
+}
+
+static enum event_type str_to_event(const char *name)
+{
+ if (!strncasecmp("S", name, EVENT_STR_LEN))
+ return URB_SUBMIT;
+ if (!strncasecmp("C", name, EVENT_STR_LEN))
+ return URB_COMPLETE;
+ if (!strncasecmp("", name, EVENT_STR_LEN))
+ return EVENT_NONE;
+
+ return EVENT_UNDEF;
+}
+
+/*log ep0 activity*/
+static struct {
+ char (buf[DBG_MAX_MSG])[DBG_MSG_LEN]; /* buffer */
+ unsigned idx; /* index */
+ rwlock_t lck; /* lock */
+} dbg_hsic_ctrl = {
+ .idx = 0,
+ .lck = __RW_LOCK_UNLOCKED(lck)
+};
+
+static struct {
+ char (buf[DBG_MAX_MSG])[DBG_MSG_LEN]; /* buffer */
+ unsigned idx; /* index */
+ rwlock_t lck; /* lock */
+} dbg_hsic_data = {
+ .idx = 0,
+ .lck = __RW_LOCK_UNLOCKED(lck)
+};
+
+/**
+ * dbg_inc: increments debug event index
+ * @idx: buffer index
+ */
+static void dbg_inc(unsigned *idx)
+{
+ *idx = (*idx + 1) & (DBG_MAX_MSG-1);
+}
+
+/*get_timestamp - returns time of day in us */
+static char *get_timestamp(char *tbuf)
+{
+ unsigned long long t;
+ unsigned long nanosec_rem;
+
+ t = cpu_clock(smp_processor_id());
+ nanosec_rem = do_div(t, 1000000000)/1000;
+ scnprintf(tbuf, TIME_BUF_LEN, "[%5lu.%06lu] ", (unsigned long)t,
+ nanosec_rem);
+ return tbuf;
+}
+
+static int allow_dbg_log(int ep_addr)
+{
+ int dir, num;
+
+ dir = ep_addr & USB_DIR_IN ? USB_DIR_IN : USB_DIR_OUT;
+ num = ep_addr & ~USB_DIR_IN;
+ num = 1 << num;
+
+ if ((dir == USB_DIR_IN) && (num & ep_addr_rxdbg_mask))
+ return 1;
+ if ((dir == USB_DIR_OUT) && (num & ep_addr_txdbg_mask))
+ return 1;
+
+ return 0;
+}
+
+static void dbg_log_event(struct urb *urb, char * event, unsigned extra)
+{
+ unsigned long flags;
+ int ep_addr;
+ char tbuf[TIME_BUF_LEN];
+
+ if (!enable_dbg_log)
+ return;
+
+ if (!urb) {
+ write_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
+ scnprintf(dbg_hsic_ctrl.buf[dbg_hsic_ctrl.idx], DBG_MSG_LEN,
+ "%s: %s : %u\n", get_timestamp(tbuf), event, extra);
+ dbg_inc(&dbg_hsic_ctrl.idx);
+ write_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
+ return;
+ }
+
+ ep_addr = urb->ep->desc.bEndpointAddress;
+ if (!allow_dbg_log(ep_addr))
+ return;
+
+ if ((ep_addr & 0x0f) == 0x0) {
+ /*submit event*/
+ if (!str_to_event(event)) {
+ write_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
+ scnprintf(dbg_hsic_ctrl.buf[dbg_hsic_ctrl.idx],
+ DBG_MSG_LEN, "%s: [%s : %p]:[%s] "
+ "%02x %02x %04x %04x %04x %u %d\n",
+ get_timestamp(tbuf), event, urb,
+ (ep_addr & USB_DIR_IN) ? "in" : "out",
+ urb->setup_packet[0], urb->setup_packet[1],
+ (urb->setup_packet[3] << 8) |
+ urb->setup_packet[2],
+ (urb->setup_packet[5] << 8) |
+ urb->setup_packet[4],
+ (urb->setup_packet[7] << 8) |
+ urb->setup_packet[6],
+ urb->transfer_buffer_length, urb->status);
+
+ dbg_inc(&dbg_hsic_ctrl.idx);
+ write_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
+ } else {
+ write_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
+ scnprintf(dbg_hsic_ctrl.buf[dbg_hsic_ctrl.idx],
+ DBG_MSG_LEN, "%s: [%s : %p]:[%s] %u %d\n",
+ get_timestamp(tbuf), event, urb,
+ (ep_addr & USB_DIR_IN) ? "in" : "out",
+ urb->actual_length, extra);
+
+ dbg_inc(&dbg_hsic_ctrl.idx);
+ write_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
+ }
+ } else {
+ write_lock_irqsave(&dbg_hsic_data.lck, flags);
+ scnprintf(dbg_hsic_data.buf[dbg_hsic_data.idx], DBG_MSG_LEN,
+ "%s: [%s : %p]:ep%d[%s] %u %d\n",
+ get_timestamp(tbuf), event, urb, ep_addr & 0x0f,
+ (ep_addr & USB_DIR_IN) ? "in" : "out",
+ str_to_event(event) ? urb->actual_length :
+ urb->transfer_buffer_length,
+ str_to_event(event) ? extra : urb->status);
+
+ dbg_inc(&dbg_hsic_data.idx);
+ write_unlock_irqrestore(&dbg_hsic_data.lck, flags);
+ }
+}
+
static inline struct msm_hsic_hcd *hcd_to_hsic(struct usb_hcd *hcd)
{
return (struct msm_hsic_hcd *) (hcd->hcd_priv);
@@ -589,6 +767,25 @@
return 0;
}
+static int ehci_hsic_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags)
+{
+ dbg_log_event(urb, event_to_str(URB_SUBMIT), 0);
+ return ehci_urb_enqueue(hcd, urb, mem_flags);
+}
+
+static int ehci_hsic_bus_suspend(struct usb_hcd *hcd)
+{
+ dbg_log_event(NULL, "Suspend RH", 0);
+ return ehci_bus_suspend(hcd);
+}
+
+static int ehci_hsic_bus_resume(struct usb_hcd *hcd)
+{
+ dbg_log_event(NULL, "Resume RH", 0);
+ return ehci_bus_resume(hcd);
+}
+
static struct hc_driver msm_hsic_driver = {
.description = hcd_name,
.product_desc = "Qualcomm EHCI Host Controller using HSIC",
@@ -609,7 +806,7 @@
/*
* managing i/o requests and associated device resources
*/
- .urb_enqueue = ehci_urb_enqueue,
+ .urb_enqueue = ehci_hsic_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
@@ -631,8 +828,10 @@
/*
* PM support
*/
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
+ .bus_suspend = ehci_hsic_bus_suspend,
+ .bus_resume = ehci_hsic_bus_resume,
+
+ .log_urb_complete = dbg_log_event,
};
static int msm_hsic_init_clocks(struct msm_hsic_hcd *mehci, u32 init)
@@ -729,6 +928,7 @@
struct msm_hsic_hcd *mehci = data;
mehci->wakeup_int_cnt++;
+ dbg_log_event(NULL, "Remote Wakeup IRQ", mehci->wakeup_int_cnt);
dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt cnt: %u\n",
__func__, mehci->wakeup_int_cnt);
@@ -822,6 +1022,68 @@
.release = single_release,
};
+static int ehci_hsic_msm_data_events_show(struct seq_file *s, void *unused)
+{
+ unsigned long flags;
+ unsigned i;
+
+ read_lock_irqsave(&dbg_hsic_data.lck, flags);
+
+ i = dbg_hsic_data.idx;
+ for (dbg_inc(&i); i != dbg_hsic_data.idx; dbg_inc(&i)) {
+ if (!strnlen(dbg_hsic_data.buf[i], DBG_MSG_LEN))
+ continue;
+ seq_printf(s, "%s\n", dbg_hsic_data.buf[i]);
+ }
+
+ read_unlock_irqrestore(&dbg_hsic_data.lck, flags);
+
+ return 0;
+}
+
+static int ehci_hsic_msm_data_events_open(struct inode *inode, struct file *f)
+{
+ return single_open(f, ehci_hsic_msm_data_events_show, inode->i_private);
+}
+
+const struct file_operations ehci_hsic_msm_dbg_data_fops = {
+ .open = ehci_hsic_msm_data_events_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int ehci_hsic_msm_ctrl_events_show(struct seq_file *s, void *unused)
+{
+ unsigned long flags;
+ unsigned i;
+
+ read_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
+
+ i = dbg_hsic_ctrl.idx;
+ for (dbg_inc(&i); i != dbg_hsic_ctrl.idx; dbg_inc(&i)) {
+ if (!strnlen(dbg_hsic_ctrl.buf[i], DBG_MSG_LEN))
+ continue;
+ seq_printf(s, "%s\n", dbg_hsic_ctrl.buf[i]);
+ }
+
+ read_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
+
+ return 0;
+}
+
+static int ehci_hsic_msm_ctrl_events_open(struct inode *inode, struct file *f)
+{
+ return single_open(f, ehci_hsic_msm_ctrl_events_show, inode->i_private);
+}
+
+const struct file_operations ehci_hsic_msm_dbg_ctrl_fops = {
+ .open = ehci_hsic_msm_ctrl_events_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static struct dentry *ehci_hsic_msm_dbg_root;
static int ehci_hsic_msm_debugfs_init(struct msm_hsic_hcd *mehci)
{
@@ -852,6 +1114,26 @@
return -ENODEV;
}
+ ehci_hsic_msm_dentry = debugfs_create_file("show_ctrl_events",
+ S_IRUGO,
+ ehci_hsic_msm_dbg_root, mehci,
+ &ehci_hsic_msm_dbg_ctrl_fops);
+
+ if (!ehci_hsic_msm_dentry) {
+ debugfs_remove_recursive(ehci_hsic_msm_dbg_root);
+ return -ENODEV;
+ }
+
+ ehci_hsic_msm_dentry = debugfs_create_file("show_data_events",
+ S_IRUGO,
+ ehci_hsic_msm_dbg_root, mehci,
+ &ehci_hsic_msm_dbg_data_fops);
+
+ if (!ehci_hsic_msm_dentry) {
+ debugfs_remove_recursive(ehci_hsic_msm_dbg_root);
+ return -ENODEV;
+ }
+
return 0;
}
@@ -913,6 +1195,8 @@
mehci->ehci.susp_sof_bug = 1;
+ mehci->ehci.max_log2_irq_thresh = 6;
+
res = platform_get_resource_byname(pdev,
IORESOURCE_IRQ,
"peripheral_status_irq");
@@ -1075,6 +1359,8 @@
dev_dbg(dev, "ehci-msm-hsic PM suspend\n");
+ dbg_log_event(NULL, "PM Suspend", 0);
+
if (device_may_wakeup(dev))
enable_irq_wake(hcd->irq);
@@ -1092,6 +1378,8 @@
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+ dbg_log_event(NULL, "PM Resume", 0);
+
if (device_may_wakeup(dev))
disable_irq_wake(hcd->irq);
@@ -1121,6 +1409,9 @@
struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
dev_dbg(dev, "EHCI runtime suspend\n");
+
+ dbg_log_event(NULL, "Run Time PM Suspend", 0);
+
return msm_hsic_suspend(mehci);
}
@@ -1130,6 +1421,9 @@
struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
dev_dbg(dev, "EHCI runtime resume\n");
+
+ dbg_log_event(NULL, "Run Time PM Resume", 0);
+
return msm_hsic_resume(mehci);
}
#endif
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index c69104d..6afb70b 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -135,6 +135,8 @@
ktime_t last_periodic_enable;
u32 command;
+ unsigned max_log2_irq_thresh;
+
/* SILICON QUIRKS */
unsigned no_selective_suspend:1;
unsigned has_fsl_port_bug:1; /* FreeScale */
diff --git a/drivers/video/msm/mipi_chimei_wuxga.c b/drivers/video/msm/mipi_chimei_wuxga.c
index 6ddf74d..e9e291e 100644
--- a/drivers/video/msm/mipi_chimei_wuxga.c
+++ b/drivers/video/msm/mipi_chimei_wuxga.c
@@ -143,6 +143,7 @@
pinfo->mipi.data_lane1 = true;
pinfo->mipi.data_lane2 = true;
pinfo->mipi.data_lane3 = true;
+ pinfo->mipi.esc_byte_ratio = 6;
pinfo->mipi.mode = DSI_VIDEO_MODE;
/*
diff --git a/drivers/video/msm/mipi_chimei_wxga_pt.c b/drivers/video/msm/mipi_chimei_wxga_pt.c
index 1ab50b7..88a5193 100644
--- a/drivers/video/msm/mipi_chimei_wxga_pt.c
+++ b/drivers/video/msm/mipi_chimei_wxga_pt.c
@@ -130,6 +130,7 @@
pinfo->mipi.tx_eot_append = true;
pinfo->mipi.t_clk_post = 34; /* Calculated */
pinfo->mipi.t_clk_pre = 64; /* Calculated */
+ pinfo->mipi.esc_byte_ratio = 4;
pinfo->mipi.dsi_phy_db = &dsi_video_mode_phy_db;
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index 7564016..1ba1444 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -36,6 +36,7 @@
#include "mdp4.h"
u32 dsi_irq;
+u32 esc_byte_ratio;
static boolean tlmm_settings = FALSE;
@@ -164,6 +165,7 @@
fbi = mfd->fbi;
var = &fbi->var;
pinfo = &mfd->panel_info;
+ esc_byte_ratio = pinfo->mipi.esc_byte_ratio;
if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save)
mipi_dsi_pdata->dsi_power_save(1);
diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h
index d54c5b5..2bc49c0 100644
--- a/drivers/video/msm/mipi_dsi.h
+++ b/drivers/video/msm/mipi_dsi.h
@@ -126,6 +126,7 @@
extern struct device dsi_dev;
extern int mipi_dsi_clk_on;
extern u32 dsi_irq;
+extern u32 esc_byte_ratio;
extern void __iomem *periph_base;
extern char *mmss_cc_base; /* mutimedia sub system clock control */
diff --git a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
index fbd2495..f139f4c 100644
--- a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
+++ b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
@@ -73,6 +73,7 @@
pinfo.mipi.dst_format = DSI_CMD_DST_FORMAT_RGB888;
pinfo.mipi.vc = 0;
pinfo.mipi.data_lane0 = TRUE;
+ pinfo.mipi.esc_byte_ratio = 4;
#if defined(NOVATEK_TWO_LANE)
pinfo.mipi.data_lane1 = TRUE;
#endif
diff --git a/drivers/video/msm/mipi_novatek_video_qhd_pt.c b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
index 42ddfbe..7a9d556 100644
--- a/drivers/video/msm/mipi_novatek_video_qhd_pt.c
+++ b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
@@ -73,6 +73,7 @@
pinfo.mipi.vc = 0;
pinfo.mipi.rgb_swap = DSI_RGB_SWAP_BGR;
pinfo.mipi.data_lane0 = TRUE;
+ pinfo.mipi.esc_byte_ratio = 4;
#if defined(NOVATEK_TWO_LANE)
pinfo.mipi.data_lane1 = TRUE;
#endif
diff --git a/drivers/video/msm/mipi_orise_video_720p_pt.c b/drivers/video/msm/mipi_orise_video_720p_pt.c
index 629ff10..da8b5e5 100644
--- a/drivers/video/msm/mipi_orise_video_720p_pt.c
+++ b/drivers/video/msm/mipi_orise_video_720p_pt.c
@@ -85,6 +85,7 @@
pinfo.mipi.frame_rate = 55;
pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
pinfo.mipi.tx_eot_append = TRUE;
+ pinfo.mipi.esc_byte_ratio = 4;
ret = mipi_orise_device_register(&pinfo, MIPI_DSI_PRIM,
MIPI_DSI_PANEL_720P_PT);
diff --git a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
index 2a8610b..6edd776 100644
--- a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
+++ b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
@@ -86,6 +86,7 @@
pinfo.mipi.data_lane2 = TRUE;
pinfo.mipi.t_clk_post = 0x20;
pinfo.mipi.t_clk_pre = 0x2d;
+ pinfo.mipi.esc_byte_ratio = 4;
pinfo.mipi.stream = 0; /* dma_p */
pinfo.mipi.mdp_trigger = 0;
pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
diff --git a/drivers/video/msm/mipi_toshiba_video_wuxga.c b/drivers/video/msm/mipi_toshiba_video_wuxga.c
index 297248f..8eddce4 100644
--- a/drivers/video/msm/mipi_toshiba_video_wuxga.c
+++ b/drivers/video/msm/mipi_toshiba_video_wuxga.c
@@ -85,6 +85,7 @@
pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
pinfo.mipi.frame_rate = 60;
pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+ pinfo.mipi.esc_byte_ratio = 9;
ret = mipi_toshiba_device_register(&pinfo, MIPI_DSI_PRIM,
MIPI_DSI_PANEL_WUXGA);
diff --git a/drivers/video/msm/msm_dss_io_7x27a.c b/drivers/video/msm/msm_dss_io_7x27a.c
index f4f8375..17ee976 100644
--- a/drivers/video/msm/msm_dss_io_7x27a.c
+++ b/drivers/video/msm/msm_dss_io_7x27a.c
@@ -257,10 +257,10 @@
MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0001);/* start phy sw reset */
wmb();
- usleep(10);
+ usleep(1000);
MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0000);/* end phy w reset */
wmb();
- usleep(10);
+ usleep(1000);
MIPI_OUTP(MIPI_DSI_BASE + 0x2cc, 0x0003);/* regulator_ctrl_0 */
MIPI_OUTP(MIPI_DSI_BASE + 0x2d0, 0x0001);/* regulator_ctrl_1 */
MIPI_OUTP(MIPI_DSI_BASE + 0x2d4, 0x0001);/* regulator_ctrl_2 */
diff --git a/drivers/video/msm/msm_dss_io_8960.c b/drivers/video/msm/msm_dss_io_8960.c
index b17c195..70c8afc 100644
--- a/drivers/video/msm/msm_dss_io_8960.c
+++ b/drivers/video/msm/msm_dss_io_8960.c
@@ -661,8 +661,8 @@
if (clk_set_rate(dsi_byte_div_clk, 1) < 0) /* divided by 1 */
pr_err("%s: dsi_byte_div_clk - "
"clk_set_rate failed\n", __func__);
- if (clk_set_rate(dsi_esc_clk, 2) < 0) /* divided by 2 */
- pr_err("%s: dsi_esc_clk - "
+ if (clk_set_rate(dsi_esc_clk, esc_byte_ratio) < 0) /* divided by esc */
+ pr_err("%s: dsi_esc_clk - " /* clk ratio */
"clk_set_rate failed\n", __func__);
mipi_dsi_pclk_ctrl(&dsi_pclk, 1);
mipi_dsi_clk_ctrl(&dsicore_clk, 1);
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index 9d16b7b..8ccc21c 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -129,6 +129,8 @@
char mdp_trigger;
char dma_trigger;
uint32 dsi_pclk_rate;
+ /* byte to esc clk ratio */
+ uint32 esc_byte_ratio;
/* The packet-size should not bet changed */
char no_max_pkt_size;
/* Clock required during LP commands */
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 6d93360..a1d192d 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -56,7 +56,11 @@
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
- printk("%sFAT-fs (%s): %pV\n", level, sb->s_id, &vaf);
+ if (!strncmp(level, KERN_ERR, sizeof(KERN_ERR)))
+ printk_ratelimited("%sFAT-fs (%s): %pV\n", level,
+ sb->s_id, &vaf);
+ else
+ printk("%sFAT-fs (%s): %pV\n", level, sb->s_id, &vaf);
va_end(args);
}
diff --git a/include/linux/regulator/pm8xxx-regulator.h b/include/linux/regulator/pm8xxx-regulator.h
index 21352e8..4ca624b 100644
--- a/include/linux/regulator/pm8xxx-regulator.h
+++ b/include/linux/regulator/pm8xxx-regulator.h
@@ -67,6 +67,9 @@
* @enable_time: time in us taken to enable a regulator to the maximum
* allowed voltage for the system. This is dependent upon
* the load and capacitance for a regulator on the board.
+ * @slew_rate: worst case rate of change of regulator output voltage
+ * in units of uV/us (V/s). This is dependent upon the
+ * load and capacitance for a regulator on the board.
* @ocp_enable: enable over current protection logic (available for
* LVS and MVS type switches)
* @ocp_enable_time: time in us to delay between enabling the switch and then
@@ -81,6 +84,7 @@
enum pm8xxx_vreg_pin_function pin_fn;
int system_uA;
int enable_time;
+ int slew_rate;
unsigned ocp_enable;
int ocp_enable_time;
};
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 9cdbfdd..d9ec332 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -344,6 +344,10 @@
*/
int (*update_device)(struct usb_hcd *, struct usb_device *);
int (*set_usb2_hw_lpm)(struct usb_hcd *, struct usb_device *, int);
+
+ /* to log completion events*/
+ void (*log_urb_complete)(struct urb *urb, char * event,
+ unsigned extra);
};
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 0696b13..c148b75 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -399,7 +399,8 @@
#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */
#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */
#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
-#define V4L2_PIX_FMT_DIVX_311 v4l2_fourcc('D', 'I', 'V', '3') /* DIVX */
+#define V4L2_PIX_FMT_DIVX_311 v4l2_fourcc('D', 'I', 'V', '3') /* DIVX311 */
+#define V4L2_PIX_FMT_DIVX v4l2_fourcc('D', 'I', 'V', 'X') /* DIVX */
/* Vendor-specific formats */
#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index d4cf1d2..8222b67 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -448,6 +448,9 @@
#define CMD_AXI_CFG_SEC 0xF4
#define CMD_AXI_CFG_SEC_ALL_CHNLS 0xF8
+#define CMD_AXI_START 0xE1
+#define CMD_AXI_STOP 0xE2
+
/* vfe config command: config command(from config thread)*/
struct msm_vfe_cfg_cmd {
int cmd_type;
diff --git a/kernel/power/main.c b/kernel/power/main.c
index a1d13f5..596bf9f 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -502,8 +502,6 @@
#endif
static struct attribute *g[] = {
- &touch_event_attr.attr,
- &touch_event_timer_attr.attr,
&state_attr.attr,
#ifdef CONFIG_PM_TRACE
&pm_trace_attr.attr,
@@ -512,6 +510,8 @@
#ifdef CONFIG_PM_SLEEP
&pm_async_attr.attr,
&wakeup_count_attr.attr,
+ &touch_event_attr.attr,
+ &touch_event_timer_attr.attr,
#ifdef CONFIG_PM_DEBUG
&pm_test_attr.attr,
#endif
diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile
index 0df028c..43c678d 100644
--- a/sound/soc/msm/Makefile
+++ b/sound/soc/msm/Makefile
@@ -62,7 +62,7 @@
snd-soc-qdsp6-objs += msm-pcm-lpa.o msm-pcm-afe.o
obj-$(CONFIG_SND_SOC_QDSP6) += snd-soc-qdsp6.o
-snd-soc-msm8960-objs := msm8960.o apq8064.o msm8930.o
+snd-soc-msm8960-objs := msm8960.o apq8064.o msm8930.o mpq8064.o
obj-$(CONFIG_SND_SOC_MSM8960) += snd-soc-msm8960.o
# Generic MSM drivers
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index ad1278c..0f91665 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -44,6 +44,11 @@
#define SITAR_MBHC_DEF_BUTTONS 8
#define SITAR_MBHC_DEF_RLOADS 5
+#define GPIO_AUX_PCM_DOUT 63
+#define GPIO_AUX_PCM_DIN 64
+#define GPIO_AUX_PCM_SYNC 65
+#define GPIO_AUX_PCM_CLK 66
+
static int msm8930_spk_control;
static int msm8930_slim_0_rx_ch = 1;
static int msm8930_slim_0_tx_ch = 1;
@@ -734,6 +739,80 @@
return 0;
}
+static int msm8930_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ /* PCM only supports mono output with 8khz sample rate */
+ rate->min = rate->max = 8000;
+ channels->min = channels->max = 1;
+
+ return 0;
+}
+
+static int msm8930_aux_pcm_get_gpios(void)
+{
+ int ret = 0;
+
+ pr_debug("%s\n", __func__);
+
+ ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT");
+ if (ret < 0) {
+ pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT",
+ __func__, GPIO_AUX_PCM_DOUT);
+
+ goto fail_dout;
+ }
+
+ ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN");
+ if (ret < 0) {
+ pr_err("%s: Failed to request gpio(%d): AUX PCM DIN",
+ __func__, GPIO_AUX_PCM_DIN);
+ goto fail_din;
+ }
+
+ ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC");
+ if (ret < 0) {
+ pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC",
+ __func__, GPIO_AUX_PCM_SYNC);
+ goto fail_sync;
+ }
+
+ ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK");
+ if (ret < 0) {
+ pr_err("%s: Failed to request gpio(%d): AUX PCM CLK",
+ __func__, GPIO_AUX_PCM_CLK);
+ goto fail_clk;
+ }
+
+ return 0;
+
+fail_clk:
+ gpio_free(GPIO_AUX_PCM_SYNC);
+fail_sync:
+ gpio_free(GPIO_AUX_PCM_DIN);
+fail_din:
+ gpio_free(GPIO_AUX_PCM_DOUT);
+fail_dout:
+
+ return ret;
+}
+
+static int msm8930_aux_pcm_free_gpios(void)
+{
+ gpio_free(GPIO_AUX_PCM_DIN);
+ gpio_free(GPIO_AUX_PCM_DOUT);
+ gpio_free(GPIO_AUX_PCM_SYNC);
+ gpio_free(GPIO_AUX_PCM_CLK);
+
+ return 0;
+}
+
static int msm8930_startup(struct snd_pcm_substream *substream)
{
pr_debug("%s(): substream = %s stream = %d\n", __func__,
@@ -741,6 +820,26 @@
return 0;
}
+static int msm8930_auxpcm_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+
+ pr_debug("%s(): substream = %s\n", __func__, substream->name);
+ ret = msm8930_aux_pcm_get_gpios();
+ if (ret < 0) {
+ pr_err("%s: Aux PCM GPIO request failed\n", __func__);
+ return -EINVAL;
+ }
+ return 0;
+
+}
+
+static void msm8930_auxpcm_shutdown(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s(): substream = %s\n", __func__, substream->name);
+ msm8930_aux_pcm_free_gpios();
+}
+
static void msm8930_shutdown(struct snd_pcm_substream *substream)
{
pr_debug("%s(): substream = %s stream = %d\n", __func__,
@@ -753,6 +852,11 @@
.shutdown = msm8930_shutdown,
};
+static struct snd_soc_ops msm8930_auxpcm_be_ops = {
+ .startup = msm8930_auxpcm_startup,
+ .shutdown = msm8930_auxpcm_shutdown,
+};
+
/* Digital audio interface glue - connects codec <---> CPU */
static struct snd_soc_dai_link msm8930_dai[] = {
/* FrontEnd DAI Links */
@@ -1019,6 +1123,30 @@
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
},
+ /* AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_AUXPCM_RX,
+ .stream_name = "AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
+ .be_hw_params_fixup = msm8930_auxpcm_be_params_fixup,
+ .ops = &msm8930_auxpcm_be_ops,
+ },
+ {
+ .name = LPASS_BE_AUXPCM_TX,
+ .stream_name = "AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
+ .be_hw_params_fixup = msm8930_auxpcm_be_params_fixup,
+ },
/* Incall Music BACK END DAI Link */
{
.name = LPASS_BE_VOICE_PLAYBACK_TX,