Merge "ASoC: msm: Add support for multiple instance of compressed audio"
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index 3ee63c0..717dd8c 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -11,11 +11,10 @@
KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules
KERNEL_IMG=$(KERNEL_OUT)/arch/arm/boot/Image
-MSM_ARCH ?= $(shell $(PERL) -e 'while (<>) {$$a = $$1 if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/; $$r = $$1 if /CONFIG_MSM_SOC_REV_(?!NONE)(\w+)=y/;} print lc("$$a$$r\n");' $(KERNEL_CONFIG))
+DTS_NAMES ?= $(shell $(PERL) -e 'while (<>) {$$a = $$1 if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/; $$r = $$1 if /CONFIG_MSM_SOC_REV_(?!NONE)(\w+)=y/; $$arch = $$arch.lc("$$a$$r ") if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/} print $$arch;' $(KERNEL_CONFIG))
KERNEL_USE_OF ?= $(shell $(PERL) -e '$$of = "n"; while (<>) { if (/CONFIG_USE_OF=y/) { $$of = "y"; break; } } print $$of;' kernel/arch/arm/configs/$(KERNEL_DEFCONFIG))
ifeq "$(KERNEL_USE_OF)" "y"
-DTS_NAME ?= $(MSM_ARCH)
DTS_FILES = $(wildcard $(TOP)/kernel/arch/arm/boot/dts/$(DTS_NAME)*.dts)
DTS_FILE = $(lastword $(subst /, ,$(1)))
DTB_FILE = $(addprefix $(KERNEL_OUT)/arch/arm/boot/,$(patsubst %.dts,%.dtb,$(call DTS_FILE,$(1))))
@@ -25,9 +24,10 @@
define append-dtb
mkdir -p $(KERNEL_OUT)/arch/arm/boot;\
-$(foreach d, $(DTS_FILES), \
- $(DTC) -p 1024 -O dtb -o $(call DTB_FILE,$(d)) $(d); \
- cat $(KERNEL_ZIMG) $(call DTB_FILE,$(d)) > $(call ZIMG_FILE,$(d));)
+$(foreach DTS_NAME, $(DTS_NAMES), \
+ $(foreach d, $(DTS_FILES), \
+ $(DTC) -p 1024 -O dtb -o $(call DTB_FILE,$(d)) $(d); \
+ cat $(KERNEL_ZIMG) $(call DTB_FILE,$(d)) > $(call ZIMG_FILE,$(d));))
endef
else
diff --git a/Documentation/devicetree/bindings/arm/msm/debug-pc-cntr.txt b/Documentation/devicetree/bindings/arm/msm/debug-pc-cntr.txt
new file mode 100644
index 0000000..01301be
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/debug-pc-cntr.txt
@@ -0,0 +1,18 @@
+* MSM PC Debug Counters
+
+MSM PC debug counter reserves 16 registers in the IMEM memory space which
+maintains a count on the state of power collapse on each core. This count
+will be useful to debug the power collapse state on each core.
+
+The required nodes for MSM PC Debug Counters are:
+
+- compatible: "qcom,pc-cntr"
+- reg: physical IMEM address reserved for PC counters
+
+Example:
+
+qcom,pc-cntr@fe800000 {
+ compatible = "qcom,pc-cntr";
+ reg = <0xfe800664 0x40>;
+ };
+
diff --git a/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt b/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt
index 2ba7341..d7d3ec2 100644
--- a/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt
+++ b/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt
@@ -40,9 +40,10 @@
Select from the following unsigned int.
0 : Default scaling to convert raw adc code to voltage.
1 : Conversion to temperature based on btm parameters.
- 2 : Returns result in milli degree's Centigrade.
+ 2 : Returns result in degC for 100k pull-up.
3 : Returns current across 0.1 ohm resistor.
4 : Returns XO thermistor voltage in degree's Centigrade.
+ 5 : Returns result in degC for 150k pull-up.
- qcom,hw-settle-time : Settling period for the channel before ADC read.
Select from the following unsigned int.
0 : 0us
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
old mode 100755
new mode 100644
index 751a823..0f5fd1c
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -517,9 +517,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@50 {
- label = "xo_therm1";
- qcom,channel-num = <49>;
+ chan@178 {
+ label = "xo_therm_pu2";
+ qcom,channel-num = <178>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -527,6 +527,61 @@
qcom,hw-settle-time = <0>;
qcom,fast-avg-setup = <0>;
};
+
+ chan@179 {
+ label = "msm_therm";
+ qcom,channel-num = <179>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@180 {
+ label = "emmc_therm";
+ qcom,channel-num = <180>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@181 {
+ label = "pa_therm1";
+ qcom,channel-num = <181>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@183 {
+ label = "pa_therm2";
+ qcom,channel-num = <183>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@184 {
+ label = "quiet_therm";
+ qcom,channel-num = <184>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
};
iadc@3600 {
diff --git a/arch/arm/boot/dts/msm8226-camera.dtsi b/arch/arm/boot/dts/msm8226-camera.dtsi
new file mode 100644
index 0000000..2a9fdf2
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-camera.dtsi
@@ -0,0 +1,18 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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.
+ */
+
+/ {
+ qcom,cam_server {
+ compatible = "qcom,cam_server";
+ reg = <0xfd8C0000 0x10000>;
+ };
+};
diff --git a/arch/arm/boot/dts/msm8226-ion.dtsi b/arch/arm/boot/dts/msm8226-ion.dtsi
new file mode 100644
index 0000000..beaffe5
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-ion.dtsi
@@ -0,0 +1,23 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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.
+ */
+
+/ {
+ qcom,ion {
+ compatible = "qcom,msm-ion";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ion-heap@30 { /* SYSTEM HEAP */
+ reg = <30>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/msm8226-sim.dts b/arch/arm/boot/dts/msm8226-sim.dts
new file mode 100644
index 0000000..4330849
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-sim.dts
@@ -0,0 +1,61 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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.
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+/include/ "msm8226-ion.dtsi"
+/include/ "msm8226-camera.dtsi"
+
+/ {
+ model = "Qualcomm MSM 8226 Simulator";
+ compatible = "qcom,msm8226-sim", "qcom,msm8226";
+ qcom,msm-id = <145 1 0>;
+ interrupt-parent = <&intc>;
+
+ chosen {
+ bootargs ="root=/dev/ram rw init=/init console=ttyHSL0,115200n8 initrd=0x00000000,0x00000000 mem=512M@0x00000000";
+ };
+
+ intc: interrupt-controller@f9000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xF9000000 0x1000>,
+ <0xF9002000 0x1000>;
+ };
+
+ msmgpio: gpio@fd510000 {
+ compatible = "qcom,msm-gpio";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xfd510000 0x4000>;
+ #gpio-cells = <2>;
+ };
+
+ timer {
+ compatible = "qcom,msm-qtimer", "arm,armv7-timer";
+ interrupts = <1 2 0 1 3 0>;
+ clock-frequency = <19200000>;
+ };
+
+ serial@f991f000 {
+ compatible = "qcom,msm-lsuart-v14";
+ reg = <0xf991f000 0x1000>;
+ interrupts = <0 109 0>;
+ };
+
+ serial@f995e000 {
+ compatible = "qcom,msm-lsuart-v14";
+ reg = <0xf995e000 0x1000>;
+ interrupts = <0 114 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974-liquid.dts b/arch/arm/boot/dts/msm8974-liquid.dts
new file mode 100644
index 0000000..5de2d43
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-liquid.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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.
+ */
+
+/dts-v1/;
+
+/include/ "msm8974.dtsi"
+
+/ {
+ model = "Qualcomm MSM 8974 LIQUID";
+ compatible = "qcom,msm8974-liquid", "qcom,msm8974";
+ qcom,msm-id = <126 9 0>;
+
+ serial@f991e000 {
+ status = "ok";
+ };
+};
+
+
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index 0382021..344aa7f 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -41,7 +41,7 @@
core-vdda-supply = <&pm8941_l12>;
core-vcc-supply = <&pm8941_s3>;
qcom,hdmi-tx-supply-names = "hpd-5v", "core-vdda", "core-vcc";
- qcom,hdmi-tx-supply-type = <0 1 1>;
+ qcom,hdmi-tx-supply-type = <1 0 0>;
qcom,hdmi-tx-min-voltage-level = <0 1800000 1800000>;
qcom,hdmi-tx-max-voltage-level = <0 1800000 1800000>;
qcom,hdmi-tx-op-mode = <0 1800000 0>;
diff --git a/arch/arm/boot/dts/msm8974-mtp.dts b/arch/arm/boot/dts/msm8974-mtp.dts
index 1af468a..d3e0bc3 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-mtp.dts
@@ -140,6 +140,19 @@
debounce-interval = <15>;
};
};
+
+ spi@f9923000 {
+ ethernet-switch@2 {
+ compatible = "micrel,ks8851";
+ reg = <2>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <94 0>;
+ spi-max-frequency = <4800000>;
+ rst-gpio = <&pm8941_mpps 6 0>;
+ vdd-io-supply = <&spi_eth_vreg>;
+ vdd-phy-supply = <&spi_eth_vreg>;
+ };
+ };
};
&sdcc2 {
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 1fd96f9..de9e98c 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -58,6 +58,15 @@
status = "okay";
compatible = "qcom,rpm-regulator-smd";
};
+ pm8841_s1_so: regulator-s1-so {
+ regulator-name = "8841_s1_so";
+ qcom,set = <2>;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,init-voltage = <675000>;
+ status = "okay";
+ compatible = "qcom,rpm-regulator-smd";
+ };
};
rpm-regulator-smpb2 {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 918f1f0..fe60c83 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -122,6 +122,8 @@
vdd-supply = <&pm8941_l20>;
vdd-io-supply = <&pm8941_s3>;
+ qcom,sdcc-vdd-always_on;
+ qcom,sdcc-vdd-lpm_sup;
qcom,sdcc-vdd-voltage_level = <2950000 2950000>;
qcom,sdcc-vdd-current_level = <800 500000>;
diff --git a/arch/arm/boot/dts/msm8974_pm.dtsi b/arch/arm/boot/dts/msm8974_pm.dtsi
index 79de997..f3efbb8 100644
--- a/arch/arm/boot/dts/msm8974_pm.dtsi
+++ b/arch/arm/boot/dts/msm8974_pm.dtsi
@@ -383,4 +383,9 @@
<39 93>,
<40 95>;
};
+
+ qcom,pc-cntr@fe800000 {
+ compatible = "qcom,pc-cntr";
+ reg = <0xfe800664 0x40>;
+ };
};
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 25d97af..aeb59af 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -53,6 +53,8 @@
CONFIG_PM8XXX_RPC_VIBRATOR=y
CONFIG_MSM_SPM_V2=y
CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_RTB=y
+CONFIG_MSM_RTB_SEPARATE_CPUS=y
CONFIG_MSM_CPR=y
CONFIG_MSM_VP_REGULATOR=y
CONFIG_ARM_THUMBEE=y
@@ -379,4 +381,3 @@
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 53c2211..471ecd9 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -32,6 +32,7 @@
CONFIG_EFI_PARTITION=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8974=y
+CONFIG_ARCH_MSM8226=y
CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_KERNEL_PMEM_EBI_REGION=y
@@ -77,7 +78,6 @@
CONFIG_HIGHMEM=y
CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_USE_OF=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 7d26726..e46fd92 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -507,7 +507,7 @@
raw_spin_unlock(&stop_lock);
}
- set_cpu_online(cpu, false);
+ set_cpu_active(cpu, false);
local_fiq_disable();
local_irq_disable();
@@ -657,10 +657,10 @@
/* Wait up to one second for other CPUs to stop */
timeout = USEC_PER_SEC;
- while (num_online_cpus() > 1 && timeout--)
+ while (num_active_cpus() > 1 && timeout--)
udelay(1);
- if (num_online_cpus() > 1)
+ if (num_active_cpus() > 1)
pr_warning("SMP: failed to stop secondary CPUs\n");
smp_kill_cpus(&mask);
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 505048c..70234bf 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -116,6 +116,7 @@
ifndef CONFIG_ARCH_MSM8X60
ifndef CONFIG_ARCH_APQ8064
ifndef CONFIG_ARCH_MSM8974
+ifndef CONFIG_ARCH_MSM8226
ifndef CONFIG_ARCH_MSM9625
ifndef CONFIG_ARCH_MPQ8092
obj-y += nand_partitions.o
@@ -125,6 +126,7 @@
endif
endif
endif
+endif
obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o
obj-$(CONFIG_MSM_SMD_TTY) += smd_tty.o
obj-$(CONFIG_MSM_SMD_QMI) += smd_qmi.o
@@ -290,7 +292,7 @@
obj-$(CONFIG_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_MACH_APQ8064_LIQUID) += board-8064-all.o board-8064-regulator.o
-obj-$(CONFIG_MACH_MPQ8064_HRD) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_MPQ8064_HRD) += board-8064-all.o board-8064-regulator.o board-8064-bt.o
obj-$(CONFIG_MACH_MPQ8064_DTV) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o board-9615-gpiomux.o board-9615-storage.o board-9615-display.o
obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o clock-pll.o
@@ -302,6 +304,7 @@
obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o
obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
+obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire-keypad.o board-sapphire-panel.o
@@ -357,6 +360,7 @@
obj-$(CONFIG_ARCH_MSM8974) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MSM9625) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MPQ8092) += gpiomux-v2.o gpiomux.o
+obj-$(CONFIG_ARCH_MSM8226) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += idle_stats_device.o
obj-$(CONFIG_MSM_DCVS) += msm_dcvs_scm.o msm_dcvs.o msm_dcvs_idle.o
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 437933e..526616a 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -54,6 +54,9 @@
# MSM9625
zreladdr-$(CONFIG_ARCH_MSM9625) := 0x20208000
+# MSM8226
+ zreladdr-$(CONFIG_ARCH_MSM8226) := 0x00008000
+
# FSM9XXX
zreladdr-$(CONFIG_ARCH_FSM9XXX) := 0x10008000
params_phys-$(CONFIG_ARCH_FSM9XXX) := 0x10000100
diff --git a/arch/arm/mach-msm/acpuclock-7627.c b/arch/arm/mach-msm/acpuclock-7627.c
index 3bcba5f..7be3667 100644
--- a/arch/arm/mach-msm/acpuclock-7627.c
+++ b/arch/arm/mach-msm/acpuclock-7627.c
@@ -723,7 +723,7 @@
/* Make sure PLL4 is off before reprogramming */
if ((plls_enabled & (1 << tgt_s->pll))) {
clk_disable(pll_clk[tgt_s->pll].clk);
- plls_enabled &= (0 << tgt_s->pll);
+ plls_enabled &= ~(1 << tgt_s->pll);
}
acpuclk_config_pll4(tgt_s->pll_rate);
pll_clk[tgt_s->pll].clk->rate = tgt_s->a11clk_khz*1000;
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index a9521f0..3c80875 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -122,6 +122,7 @@
[13] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 5 },
[14] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 5 },
[15] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 5 },
+ { }
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
index 1642dae..07a7f8f 100644
--- a/arch/arm/mach-msm/acpuclock-8627.c
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -104,6 +104,7 @@
[9] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
[10] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 4 },
[11] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 4 },
+ { }
};
/* TODO: Update core voltages when data is available. */
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index 782ee60..77876ee 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -144,6 +144,7 @@
[13] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
[14] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
[15] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
+ { }
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
index 34ba1da..dbc3e32 100644
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ b/arch/arm/mach-msm/acpuclock-8930aa.c
@@ -111,6 +111,7 @@
[13] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
[14] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
[15] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
+ { }
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 8cc4b13..631bd7e 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -109,6 +109,7 @@
[16] = { { 1242000, HFPLL, 1, 0, 0x2E }, 1150000, 1150000, 6 },
[17] = { { 1296000, HFPLL, 1, 0, 0x30 }, 1150000, 1150000, 6 },
[18] = { { 1350000, HFPLL, 1, 0, 0x32 }, 1150000, 1150000, 6 },
+ { }
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index 3c42090..63bff55 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -99,6 +99,7 @@
[7] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 5 },
[8] = { { 1242000, HFPLL, 1, 0, 0x2E }, 1150000, 1150000, 5 },
[9] = { { 1350000, HFPLL, 1, 0, 0x32 }, 1150000, 1150000, 5 },
+ { }
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index f0b1231..16f77ba 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -134,6 +134,7 @@
[23] = { { 2035200, HFPLL, 1, 0, 106 }, LVL_HIGH, 1050000, 3 },
[24] = { { 2112000, HFPLL, 1, 0, 110 }, LVL_HIGH, 1050000, 3 },
[25] = { { 2188800, HFPLL, 1, 0, 114 }, LVL_HIGH, 1050000, 3 },
+ { }
};
static struct acpu_level acpu_freq_tbl[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8064-bt.c b/arch/arm/mach-msm/board-8064-bt.c
new file mode 100644
index 0000000..a8ae9fa
--- /dev/null
+++ b/arch/arm/mach-msm/board-8064-bt.c
@@ -0,0 +1,547 @@
+/* Copyright (c) 2011-2012, Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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 <linux/delay.h>
+#include <linux/rfkill.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/marimba.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <mach/rpc_pmapp.h>
+#include <mach/msm_xo.h>
+#include <mach/socinfo.h>
+
+#include "board-8064.h"
+
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+
+#define BAHAMA_SLAVE_ID_FM_ADDR 0x2A
+#define BAHAMA_SLAVE_ID_QMEMBIST_ADDR 0x7B
+
+struct bt_vreg_info {
+ const char *name;
+ unsigned int pmapp_id;
+ unsigned int min_level;
+ unsigned int max_level;
+ unsigned int is_pin_controlled;
+ struct regulator *reg;
+};
+
+struct bahama_config_register {
+ u8 reg;
+ u8 value;
+ u8 mask;
+};
+static struct bt_vreg_info bt_vregs[] = {
+ {"bha_vddxo", 2, 1800000, 1800000, 0, NULL},
+ {"bha_vddpx", 21, 1800000, 1800000, 0, NULL},
+ {"bha_vddpa", 21, 2900000, 3300000, 0, NULL}
+};
+
+static struct msm_xo_voter *bt_clock;
+
+static struct platform_device msm_bt_power_device = {
+ .name = "bt_power",
+ .id = -1,
+};
+
+static unsigned bt_config_pcm_on[] = {
+ /*PCM_DOUT*/
+ GPIO_CFG(43, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ /*PCM_DIN*/
+ GPIO_CFG(44, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ /*PCM_SYNC*/
+ GPIO_CFG(45, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ /*PCM_CLK*/
+ GPIO_CFG(46, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+};
+
+static unsigned bt_config_pcm_off[] = {
+ /*PCM_DOUT*/
+ GPIO_CFG(43, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ /*PCM_DIN*/
+ GPIO_CFG(44, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ /*PCM_SYNC*/
+ GPIO_CFG(45, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ /*PCM_CLK*/
+ GPIO_CFG(46, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+};
+
+static int config_pcm(int mode)
+{
+ int pin, rc = 0;
+
+ if (mode == BT_PCM_ON) {
+ pr_err("%s mode =BT_PCM_ON", __func__);
+ for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_on);
+ pin++) {
+ rc = gpio_tlmm_config(bt_config_pcm_on[pin],
+ GPIO_CFG_ENABLE);
+ if (rc < 0)
+ return rc;
+ }
+ } else if (mode == BT_PCM_OFF) {
+ pr_err("%s mode =BT_PCM_OFF", __func__);
+ for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_off);
+ pin++) {
+ rc = gpio_tlmm_config(bt_config_pcm_off[pin],
+ GPIO_CFG_ENABLE);
+ if (rc < 0)
+ return rc;
+ }
+
+ }
+
+ return rc;
+}
+
+static int bahama_bt(int on)
+{
+ int rc = 0;
+ int i;
+
+ struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
+
+ struct bahama_variant_register {
+ const size_t size;
+ const struct bahama_config_register *set;
+ };
+
+ const struct bahama_config_register *p;
+
+ u8 version;
+
+ const struct bahama_config_register v10_bt_on[] = {
+ { 0xE9, 0x00, 0xFF },
+ { 0xF4, 0x80, 0xFF },
+ { 0xE4, 0x00, 0xFF },
+ { 0xE5, 0x00, 0x0F },
+#ifdef CONFIG_WLAN
+ { 0xE6, 0x38, 0x7F },
+ { 0xE7, 0x06, 0xFF },
+#endif
+ { 0xE9, 0x21, 0xFF },
+ { 0x01, 0x0C, 0x1F },
+ { 0x01, 0x08, 0x1F },
+ };
+
+ const struct bahama_config_register v20_bt_on_fm_off[] = {
+ { 0x11, 0x0C, 0xFF },
+ { 0x13, 0x01, 0xFF },
+ { 0xF4, 0x80, 0xFF },
+ { 0xF0, 0x00, 0xFF },
+ { 0xE9, 0x00, 0xFF },
+#ifdef CONFIG_WLAN
+ { 0x81, 0x00, 0x7F },
+ { 0x82, 0x00, 0xFF },
+ { 0xE6, 0x38, 0x7F },
+ { 0xE7, 0x06, 0xFF },
+#endif
+ { 0x8E, 0x15, 0xFF },
+ { 0x8F, 0x15, 0xFF },
+ { 0x90, 0x15, 0xFF },
+
+ { 0xE9, 0x21, 0xFF },
+ };
+
+ const struct bahama_config_register v20_bt_on_fm_on[] = {
+ { 0x11, 0x0C, 0xFF },
+ { 0x13, 0x01, 0xFF },
+ { 0xF4, 0x86, 0xFF },
+ { 0xF0, 0x06, 0xFF },
+ { 0xE9, 0x00, 0xFF },
+#ifdef CONFIG_WLAN
+ { 0x81, 0x00, 0x7F },
+ { 0x82, 0x00, 0xFF },
+ { 0xE6, 0x38, 0x7F },
+ { 0xE7, 0x06, 0xFF },
+#endif
+ { 0xE9, 0x21, 0xFF },
+ };
+
+ const struct bahama_config_register v10_bt_off[] = {
+ { 0xE9, 0x00, 0xFF },
+ };
+
+ const struct bahama_config_register v20_bt_off_fm_off[] = {
+ { 0xF4, 0x84, 0xFF },
+ { 0xF0, 0x04, 0xFF },
+ { 0xE9, 0x00, 0xFF }
+ };
+
+ const struct bahama_config_register v20_bt_off_fm_on[] = {
+ { 0xF4, 0x86, 0xFF },
+ { 0xF0, 0x06, 0xFF },
+ { 0xE9, 0x00, 0xFF }
+ };
+
+ const struct bahama_variant_register bt_bahama[2][3] = {
+ {
+ { ARRAY_SIZE(v10_bt_off), v10_bt_off },
+ { ARRAY_SIZE(v20_bt_off_fm_off), v20_bt_off_fm_off },
+ { ARRAY_SIZE(v20_bt_off_fm_on), v20_bt_off_fm_on }
+ },
+ {
+ { ARRAY_SIZE(v10_bt_on), v10_bt_on },
+ { ARRAY_SIZE(v20_bt_on_fm_off), v20_bt_on_fm_off },
+ { ARRAY_SIZE(v20_bt_on_fm_on), v20_bt_on_fm_on }
+ }
+ };
+
+ u8 offset = 0; /* index into bahama configs */
+ on = on ? 1 : 0;
+ version = marimba_read_bahama_ver(&config);
+ if ((int)version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s : Bahama version read Error, version = %d\n",
+ __func__, version);
+ return -EIO;
+ }
+ if (version == BAHAMA_VER_2_0) {
+ if (marimba_get_fm_status(&config))
+ offset = 0x01;
+ }
+
+ p = bt_bahama[on][version + offset].set;
+
+ dev_dbg(&msm_bt_power_device.dev,
+ "%s: found version %d\n", __func__, version);
+
+ for (i = 0; i < bt_bahama[on][version + offset].size; i++) {
+ u8 value = (p+i)->value;
+ rc = marimba_write_bit_mask(&config,
+ (p+i)->reg,
+ &value,
+ sizeof((p+i)->value),
+ (p+i)->mask);
+ if (rc < 0) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: reg %x write failed: %d\n",
+ __func__, (p+i)->reg, rc);
+ return rc;
+ }
+ dev_dbg(&msm_bt_power_device.dev,
+ "%s: reg 0x%02x write value 0x%02x mask 0x%02x\n",
+ __func__, (p+i)->reg,
+ value, (p+i)->mask);
+ value = 0;
+ rc = marimba_read_bit_mask(&config,
+ (p+i)->reg, &value,
+ sizeof((p+i)->value), (p+i)->mask);
+ if (rc < 0)
+ dev_err(&msm_bt_power_device.dev,
+ "%s marimba_read_bit_mask- error",
+ __func__);
+ dev_dbg(&msm_bt_power_device.dev,
+ "%s: reg 0x%02x read value 0x%02x mask 0x%02x\n",
+ __func__, (p+i)->reg,
+ value, (p+i)->mask);
+ }
+ /* Update BT Status */
+ if (on)
+ marimba_set_bt_status(&config, true);
+ else
+ marimba_set_bt_status(&config, false);
+ return rc;
+}
+
+static int bluetooth_switch_regulators(int on)
+{
+ int i, rc = 0;
+
+ for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
+ if (IS_ERR_OR_NULL(bt_vregs[i].reg)) {
+ bt_vregs[i].reg =
+ regulator_get(&msm_bt_power_device.dev,
+ bt_vregs[i].name);
+ if (IS_ERR(bt_vregs[i].reg)) {
+ rc = PTR_ERR(bt_vregs[i].reg);
+ dev_err(&msm_bt_power_device.dev,
+ "%s: invalid regulator handle for %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+ }
+ rc = on ? regulator_set_voltage(bt_vregs[i].reg,
+ bt_vregs[i].min_level,
+ bt_vregs[i].max_level) : 0;
+ if (rc) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: could not set voltage for %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+
+ rc = on ? regulator_enable(bt_vregs[i].reg) : 0;
+ if (rc) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: could not %sable regulator %s: %d\n",
+ __func__, "en", bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+
+ rc = on ? 0 : regulator_disable(bt_vregs[i].reg);
+
+ if (rc) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: could not %sable regulator %s: %d\n",
+ __func__, "dis", bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+ }
+
+ return rc;
+reg_disable:
+ pr_err("bluetooth_switch_regulators - FAIL!!!!\n");
+ while (i) {
+ if (on) {
+ i--;
+ regulator_disable(bt_vregs[i].reg);
+ regulator_put(bt_vregs[i].reg);
+ bt_vregs[i].reg = NULL;
+ }
+ }
+ return rc;
+}
+
+static unsigned int msm_bahama_setup_power(void)
+{
+ int rc = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
+ bt_vregs[i].reg = regulator_get(&msm_bt_power_device.dev,
+ bt_vregs[i].name);
+ if (IS_ERR(bt_vregs[i].reg)) {
+ rc = PTR_ERR(bt_vregs[i].reg);
+ pr_err("%s: could not get regulator %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_fail;
+ }
+ rc = regulator_set_voltage(bt_vregs[i].reg,
+ bt_vregs[i].min_level,
+ bt_vregs[i].max_level);
+ if (rc) {
+ pr_err("%s: could not set voltage for %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_fail;
+ }
+ rc = regulator_enable(bt_vregs[i].reg);
+ if (rc) {
+ pr_err("%s: could not enable regulator %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_fail;
+ }
+ }
+ return rc;
+reg_fail:
+ pr_err("msm_bahama_setup_power FAILED !!!\n");
+
+ while (i) {
+ i--;
+ regulator_disable(bt_vregs[i].reg);
+ regulator_put(bt_vregs[i].reg);
+ bt_vregs[i].reg = NULL;
+ }
+ return rc;
+}
+
+static unsigned int msm_bahama_shutdown_power(int value)
+{
+ int rc = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
+ rc = regulator_disable(bt_vregs[i].reg);
+
+ if (rc < 0) {
+ pr_err("%s: could not disable regulator %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto out;
+ }
+
+ regulator_put(bt_vregs[i].reg);
+ bt_vregs[i].reg = NULL;
+ }
+out:
+ return rc;
+}
+
+static unsigned int msm_bahama_core_config(int type)
+{
+ int rc = 0;
+
+ if (type == BAHAMA_ID) {
+ int i;
+ struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
+ const struct bahama_config_register v20_init[] = {
+ /* reg, value, mask */
+ { 0xF4, 0x84, 0xFF }, /* AREG */
+ { 0xF0, 0x04, 0xFF } /* DREG */
+ };
+ if (marimba_read_bahama_ver(&config) == BAHAMA_VER_2_0) {
+ for (i = 0; i < ARRAY_SIZE(v20_init); i++) {
+ u8 value = v20_init[i].value;
+ rc = marimba_write_bit_mask(&config,
+ v20_init[i].reg,
+ &value,
+ sizeof(v20_init[i].value),
+ v20_init[i].mask);
+ if (rc < 0) {
+ pr_err("%s: reg %d write failed: %d\n",
+ __func__, v20_init[i].reg, rc);
+ return rc;
+ }
+ pr_debug("%s: reg 0x%02x value 0x%02x mask 0x%02x\n",
+ __func__, v20_init[i].reg,
+ v20_init[i].value, v20_init[i].mask);
+ }
+ }
+ }
+ pr_debug("core type: %d\n", type);
+ return rc;
+}
+
+static int bluetooth_power(int on)
+{
+ int rc = 0;
+ const char *id = "BTPW";
+ int cid = 0;
+
+ pr_debug("bluetooth_power entered....\n");
+ cid = adie_get_detected_connectivity_type();
+ if (cid != BAHAMA_ID) {
+ pr_err("%s: unexpected adie connectivity type: %d\n",
+ __func__, cid);
+ return -ENODEV;
+ }
+
+ if (on) {
+ rc = bluetooth_switch_regulators(on);
+ if (rc < 0) {
+ pr_err("%s: bluetooth_switch_regulators rc = %d",
+ __func__, rc);
+ goto exit;
+ }
+ /* UART GPIO configuration to be done by by UART module*/
+ /*Setup BT clocks*/
+ bt_clock = msm_xo_get(MSM_XO_TCXO_A2, id);
+ if (IS_ERR(bt_clock)) {
+ rc = PTR_ERR(bt_clock);
+ pr_err("%s: failed to get the handle for A2(%d)\n",
+ __func__, rc);
+ }
+ rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_ON);
+ if (rc < 0) {
+ pr_err("%s: Failed to vote for TCXO_A2 ON\n", __func__);
+ goto fail_xo_vote;
+ }
+ msleep(20);
+
+ /*I2C config for Bahama*/
+ rc = bahama_bt(1);
+ if (rc < 0) {
+ pr_err("%s: bahama_bt rc = %d", __func__, rc);
+ goto fail_i2c;
+ }
+ msleep(20);
+
+ /*setup BT PCM lines*/
+ rc = config_pcm(BT_PCM_ON);
+ if (rc < 0) {
+ pr_err("%s: config_pcm , rc =%d\n",
+ __func__, rc);
+ goto fail_power;
+ }
+ /* TO DO - Enable PIN CTRL */
+ /*
+ rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_PIN_CTRL);
+ if (rc < 0) {
+ pr_err("%s: Failed to vote for TCXO_A2 in PIN_CTRL\n",
+ __func__);
+ goto fail_xo_vote;
+ } */
+ } else {
+ rc = bahama_bt(0);
+ if (rc < 0)
+ pr_err("%s: bahama_bt rc = %d", __func__, rc);
+
+ rc = config_pcm(BT_PCM_OFF);
+ if (rc < 0) {
+ pr_err("%s: msm_bahama_setup_pcm_i2s, rc =%d\n",
+ __func__, rc);
+ }
+fail_i2c:
+ pr_err("bluetooth_power...FAIL_I2C\n");
+
+fail_xo_vote:
+ pr_err("bluetooth_power...FAIL_XO_VOTE\n");
+ msm_xo_put(bt_clock);
+fail_power:
+ pr_err("bluetooth_power...FAIL POWER\n");
+ rc = bluetooth_switch_regulators(0);
+ if (rc < 0) {
+ pr_err("%s: switch_regulators : rc = %d",\
+ __func__, rc);
+ goto exit;
+ }
+ }
+ return rc;
+exit:
+ pr_err("%s: failed with rc = %d", __func__, rc);
+ return rc;
+}
+
+static struct marimba_platform_data marimba_pdata = {
+ .slave_id[SLAVE_ID_BAHAMA_FM] = BAHAMA_SLAVE_ID_FM_ADDR,
+ .slave_id[SLAVE_ID_BAHAMA_QMEMBIST] = BAHAMA_SLAVE_ID_QMEMBIST_ADDR,
+ .bahama_setup = msm_bahama_setup_power,
+ .bahama_shutdown = msm_bahama_shutdown_power,
+ .bahama_core_config = msm_bahama_core_config,
+ .fm = NULL,
+};
+
+static struct i2c_board_info bahama_devices[] = {
+{
+ I2C_BOARD_INFO("marimba", 0xc),
+ .platform_data = &marimba_pdata,
+},
+};
+
+void __init apq8064_bt_power_init(void)
+{
+ int rc = 0;
+ struct device *dev;
+
+ rc = i2c_register_board_info(APQ_8064_GSBI5_QUP_I2C_BUS_ID,
+ bahama_devices,
+ ARRAY_SIZE(bahama_devices));
+ if (rc < 0) {
+ pr_err("%s: I2C Register failed\n", __func__);
+ return;
+ }
+ rc = platform_device_register(&msm_bt_power_device);
+ if (rc < 0) {
+ pr_err("%s: device register failed\n", __func__);
+ platform_device_unregister(&msm_bt_power_device);
+ return;
+ }
+
+ dev = &msm_bt_power_device.dev;
+ dev->platform_data = &bluetooth_power;
+
+ return;
+}
+#endif
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index d0f1e87..56c3241 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -16,7 +16,7 @@
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/bootmem.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <asm/mach-types.h>
#include <mach/msm_memtypes.h>
#include <mach/board.h>
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index f4e9a8f..a08f45c 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -1477,9 +1477,9 @@
pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
return;
}
-
- msm_gpiomux_install(wcnss_5wire_interface,
- ARRAY_SIZE(wcnss_5wire_interface));
+ if (!(machine_is_mpq8064_hrd()))
+ msm_gpiomux_install(wcnss_5wire_interface,
+ ARRAY_SIZE(wcnss_5wire_interface));
if (machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
machine_is_mpq8064_dtv()) {
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 3c3293d..3b47d2e 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -142,6 +142,10 @@
PM8921_GPIO_INPUT(17, PM_GPIO_PULL_UP_1P5), /* SD_WP */
};
+static struct pm8xxx_gpio_init pm8921_mpq8064_hrd_gpios[] __initdata = {
+ PM8921_GPIO_OUTPUT(37, 0, LOW), /* MUX1_SEL */
+};
+
/* Initial PM8917 GPIO configurations */
static struct pm8xxx_gpio_init pm8917_gpios[] __initdata = {
PM8921_GPIO_OUTPUT(14, 1, HIGH), /* HDMI Mux Selector */
@@ -223,6 +227,10 @@
apq8064_configure_gpios(pm8921_mpq_gpios,
ARRAY_SIZE(pm8921_mpq_gpios));
+ if (machine_is_mpq8064_hrd())
+ apq8064_configure_gpios(pm8921_mpq8064_hrd_gpios,
+ ARRAY_SIZE(pm8921_mpq8064_hrd_gpios));
+
for (i = 0; i < ARRAY_SIZE(pm8xxx_mpps); i++) {
rc = pm8xxx_mpp_config(pm8xxx_mpps[i].mpp,
&pm8xxx_mpps[i].config);
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index d41eef3..bbb9a81 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -35,6 +35,7 @@
REGULATOR_SUPPLY("dsi1_pll_vdda", "mipi_dsi.1"),
REGULATOR_SUPPLY("HRD_VDDD_CDC_D", "tabla2x-slim"),
REGULATOR_SUPPLY("HRD_CDC_VDDA_A_1P2V", "tabla2x-slim"),
+ REGULATOR_SUPPLY("dsi_pll_vdda", "mdp.0"),
};
VREG_CONSUMERS(L3) = {
REGULATOR_SUPPLY("8921_l3", NULL),
@@ -46,6 +47,7 @@
REGULATOR_SUPPLY("8921_l4", NULL),
REGULATOR_SUPPLY("HSUSB_1p8", "msm_otg"),
REGULATOR_SUPPLY("iris_vddxo", "wcnss_wlan.0"),
+ REGULATOR_SUPPLY("bha_vddxo", "bt_power"),
};
VREG_CONSUMERS(L5) = {
REGULATOR_SUPPLY("8921_l5", NULL),
@@ -74,6 +76,7 @@
VREG_CONSUMERS(L10) = {
REGULATOR_SUPPLY("8921_l10", NULL),
REGULATOR_SUPPLY("iris_vddpa", "wcnss_wlan.0"),
+ REGULATOR_SUPPLY("bha_vddpa", "bt_power"),
};
VREG_CONSUMERS(L11) = {
REGULATOR_SUPPLY("8921_l11", NULL),
@@ -181,6 +184,7 @@
REGULATOR_SUPPLY("CDC_VDDA_TX", "0-000d"),
REGULATOR_SUPPLY("CDC_VDDA_RX", "0-000d"),
REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
+ REGULATOR_SUPPLY("bha_vddpx", "bt_power"),
REGULATOR_SUPPLY("vcc_i2c", "3-005b"),
REGULATOR_SUPPLY("vcc_i2c", "3-0024"),
REGULATOR_SUPPLY("vddp", "0-0048"),
@@ -227,6 +231,7 @@
REGULATOR_SUPPLY("pll_vdd", "pil_riva"),
REGULATOR_SUPPLY("lvds_vdda", "lvds.0"),
REGULATOR_SUPPLY("dsi1_vddio", "mipi_dsi.1"),
+ REGULATOR_SUPPLY("dsi_pll_vddio", "mdp.0"),
REGULATOR_SUPPLY("hdmi_vdda", "hdmi_msm.0"),
};
VREG_CONSUMERS(USB_OTG) = {
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index ec52d1a..8755f08 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -3443,6 +3443,11 @@
#endif
}
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+ if (machine_is_mpq8064_hrd())
+ apq8064_bt_power_init();
+#endif
+
if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
platform_device_register(&cdp_kp_pdev);
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 740fa39..5d6f988 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -110,6 +110,10 @@
void apq8064_pm8xxx_gpio_mpp_init(void);
void __init configure_apq8064_pm8917_power_grid(void);
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+void __init apq8064_bt_power_init(void);
+#endif
+
#define PLATFORM_IS_MPQ8064() \
(machine_is_mpq8064_hrd() || \
machine_is_mpq8064_dtv() || \
diff --git a/arch/arm/mach-msm/board-8226-gpiomux.c b/arch/arm/mach-msm/board-8226-gpiomux.c
new file mode 100644
index 0000000..eb88ef4
--- /dev/null
+++ b/arch/arm/mach-msm/board-8226-gpiomux.c
@@ -0,0 +1,29 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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 <linux/init.h>
+#include <linux/ioport.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+
+void __init msm8226_init_gpiomux(void)
+{
+ int rc;
+
+ rc = msm_gpiomux_init(NR_GPIO_IRQS);
+ if (rc) {
+ pr_err(KERN_ERR "msm_8226_init_gpiomux failed %d\n", rc);
+ return;
+ }
+}
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
new file mode 100644
index 0000000..c845a3a
--- /dev/null
+++ b/arch/arm/mach-msm/board-8226.c
@@ -0,0 +1,114 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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 <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/memory.h>
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+#include <asm/mach/map.h>
+#include <asm/hardware/gic.h>
+#include <asm/arch_timer.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/board.h>
+#include <mach/gpiomux.h>
+#include <mach/msm_iomap.h>
+#ifdef CONFIG_ION_MSM
+#include <mach/ion.h>
+#endif
+#include <mach/msm_memtypes.h>
+#include <mach/socinfo.h>
+#include <mach/board.h>
+#include "clock.h"
+
+static struct clk_lookup msm_clocks_dummy[] = {
+ CLK_DUMMY("core_clk", BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
+ CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
+};
+
+struct clock_init_data msm_dummy_clock_init_data __initdata = {
+ .table = msm_clocks_dummy,
+ .size = ARRAY_SIZE(msm_clocks_dummy),
+};
+
+static struct of_device_id irq_match[] __initdata = {
+ { .compatible = "qcom,msm-qgic2", .data = gic_of_init, },
+ { .compatible = "qcom,msm-gpio", .data = msm_gpio_of_init, },
+ {}
+};
+
+static struct of_dev_auxdata msm8226_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("qcom,msm-lsuart-v14", 0xF991F000, \
+ "msm_serial_hsl.0", NULL),
+ {}
+};
+
+static void __init msm8226_dt_timer_init(void)
+{
+ arch_timer_of_register();
+}
+
+static struct sys_timer msm8226_dt_timer = {
+ .init = msm8226_dt_timer_init
+};
+
+void __init msm8226_init_irq(void)
+{
+ of_irq_init(irq_match);
+}
+
+void __init msm8226_init(struct of_dev_auxdata **adata)
+{
+ msm8226_init_gpiomux();
+
+ msm_clock_init(&msm_dummy_clock_init_data);
+
+ *adata = msm8226_auxdata_lookup;
+}
+
+void __init msm8226_dt_init(void)
+{
+ struct of_dev_auxdata *adata = NULL;
+ msm8226_init(&adata);
+
+ if (socinfo_init() < 0)
+ pr_err("%s: socinfo_init() failed\n", __func__);
+
+ of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
+}
+
+
+static const char *msm8226_dt_match[] __initconst = {
+ "qcom,msm8226",
+ NULL
+};
+
+DT_MACHINE_START(MSM8226_DT, "Qualcomm MSM 8226 (Flattened Device Tree)")
+ .map_io = msm_map_msm8226_io,
+ .init_irq = msm8226_init_irq,
+ .init_machine = msm8226_dt_init,
+ .handle_irq = gic_handle_irq,
+ .timer = &msm8226_dt_timer,
+ .dt_compat = msm8226_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index b454184..a0bfabf 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -22,7 +22,7 @@
#include <mach/board.h>
#include <mach/gpiomux.h>
#include <mach/socinfo.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <mach/ion.h>
#include "devices.h"
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index cc5651d..59e4ba1 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -180,6 +180,8 @@
/* Initial PM8917 MPP configurations */
static struct pm8xxx_mpp_init pm8917_mpps[] __initdata = {
+ PM8917_MPP_INIT(PM8XXX_AMUX_MPP_3, A_INPUT,
+ PM8XXX_MPP_AIN_AMUX_CH8, DIN_TO_INT),
};
void __init msm8930_pm8038_gpio_mpp_init(void)
@@ -527,6 +529,8 @@
ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
{"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
+ {"pa_therm1", ADC_MPP_1_AMUX8, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
};
static struct pm8xxx_adc_properties pm8917_adc_data = {
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8038.c b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
index ed9d802..208f15b 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8038.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
@@ -35,6 +35,7 @@
REGULATOR_SUPPLY("8038_l2", NULL),
REGULATOR_SUPPLY("iris_vdddig", "wcnss_wlan.0"),
REGULATOR_SUPPLY("dsi_vdda", "mipi_dsi.1"),
+ REGULATOR_SUPPLY("dsi_pll_vdda", "mdp.0"),
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_csid.0"),
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_csid.1"),
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_csid.2"),
@@ -146,6 +147,7 @@
VREG_CONSUMERS(L23) = {
REGULATOR_SUPPLY("8038_l23", NULL),
REGULATOR_SUPPLY("dsi_vddio", "mipi_dsi.1"),
+ REGULATOR_SUPPLY("dsi_pll_vddio", "mdp.0"),
REGULATOR_SUPPLY("hdmi_avdd", "hdmi_msm.0"),
REGULATOR_SUPPLY("hdmi_vcc", "hdmi_msm.0"),
REGULATOR_SUPPLY("pll_vdd", "pil_riva"),
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index ac4e363..3052902 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -586,6 +586,8 @@
.mem_hid = MEMTYPE_EBI1,
#endif
.cont_splash_enabled = 0x01,
+ .splash_screen_addr = 0x00,
+ .splash_screen_size = 0x00,
.mdp_iommu_split_domain = 0,
};
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index 8fc26ea..2fa98b6 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -31,6 +31,7 @@
VREG_CONSUMERS(L2) = {
REGULATOR_SUPPLY("8921_l2", NULL),
REGULATOR_SUPPLY("dsi_vdda", "mipi_dsi.1"),
+ REGULATOR_SUPPLY("dsi_pll_vdda", "mdp.0"),
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_csid.0"),
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_csid.1"),
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_csid.2"),
@@ -116,6 +117,7 @@
VREG_CONSUMERS(L23) = {
REGULATOR_SUPPLY("8921_l23", NULL),
REGULATOR_SUPPLY("dsi_vddio", "mipi_dsi.1"),
+ REGULATOR_SUPPLY("dsi_pll_vddio", "mdp.0"),
REGULATOR_SUPPLY("hdmi_avdd", "hdmi_msm.0"),
REGULATOR_SUPPLY("pll_vdd", "pil_riva"),
REGULATOR_SUPPLY("pll_vdd", "pil_qdsp6v4.1"),
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 8deb648..7c9f652 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2120,7 +2120,7 @@
/* T6 Object */
0, 0, 0, 0, 0, 0,
/* T38 Object */
- 12, 4, 0, 5, 7, 12, 0, 0, 0, 0,
+ 12, 5, 0, 28, 8, 12, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -2128,7 +2128,7 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
/* T7 Object */
- 100, 16, 50,
+ 32, 16, 50,
/* T8 Object */
25, 0, 20, 20, 0, 0, 20, 50, 0, 0,
/* T9 Object */
@@ -2380,7 +2380,6 @@
static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi4_pdata = {
.clk_freq = 100000,
.src_clk_rate = 24000000,
- .keep_ahb_clk_on = 1,
};
static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi3_pdata = {
@@ -2801,6 +2800,9 @@
static void __init msm8960_i2c_init(void)
{
+ if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+ msm8960_i2c_qup_gsbi4_pdata.keep_ahb_clk_on = 1;
+
msm8960_device_qup_i2c_gsbi4.dev.platform_data =
&msm8960_i2c_qup_gsbi4_pdata;
@@ -2820,19 +2822,24 @@
msm_kgsl_3d0.dev.platform_data;
uint32_t soc_platform_version = socinfo_get_version();
+ /* Fixup data that needs to change based on GPU ID */
if (cpu_is_msm8960ab()) {
kgsl_3d0_pdata->chipid = ADRENO_CHIPID(3, 2, 1, 0);
/* 8960PRO nominal clock rate is 325Mhz instead of 320Mhz */
kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 325000000;
- } else if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
- kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
- kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
- } else if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3) {
- /* 8960v3 GPU registers returns 5 for patch release
- * but it should be 6, so dummy up the chipid here
- * based the platform type
- */
- kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
+ } else {
+ kgsl_3d0_pdata->iommu_count = 1;
+ if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
+ kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
+ kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
+ }
+ if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3) {
+ /* 8960v3 GPU registers returns 5 for patch release
+ * but it should be 6, so dummy up the chipid here
+ * based the platform type
+ */
+ kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
+ }
}
/* Register the 3D core */
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index dfef866..292f58d 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -543,8 +543,8 @@
};
static struct resource msm_rpm_rbcpr_resource = {
- .start = 0x0010CB00,
- .end = 0x0010CB00 + SZ_8K - 1,
+ .start = 0x0010DB00,
+ .end = 0x0010DB00 + SZ_8K - 1,
.flags = IORESOURCE_MEM,
};
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index d22690c..33782ab 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -3145,18 +3145,29 @@
},
};
-static const struct kgsl_iommu_ctx kgsl_3d0_iommu_ctxs[] = {
+static const struct kgsl_iommu_ctx kgsl_3d0_iommu0_ctxs[] = {
{ "gfx3d_user", 0 },
{ "gfx3d_priv", 1 },
};
+static const struct kgsl_iommu_ctx kgsl_3d0_iommu1_ctxs[] = {
+ { "gfx3d1_user", 0 },
+ { "gfx3d1_priv", 1 },
+};
+
static struct kgsl_device_iommu_data kgsl_3d0_iommu_data[] = {
{
- .iommu_ctxs = kgsl_3d0_iommu_ctxs,
- .iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu_ctxs),
+ .iommu_ctxs = kgsl_3d0_iommu0_ctxs,
+ .iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu0_ctxs),
.physstart = 0x07C00000,
.physend = 0x07C00000 + SZ_1M - 1,
},
+ {
+ .iommu_ctxs = kgsl_3d0_iommu1_ctxs,
+ .iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu1_ctxs),
+ .physstart = 0x07D00000,
+ .physend = 0x07D00000 + SZ_1M - 1,
+ },
};
static struct kgsl_device_platform_data kgsl_3d0_pdata = {
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index ff7af32..8eed48d 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -128,6 +128,19 @@
bne skip
bl v7_flush_dcache_all
skip:
+ mrc p15, 0, r0, c0, c0, 5 /* MPIDR */
+ and r0, r0, #15 /* what CPU am I */
+
+ ldr r1, =msm_pc_debug_counters /*load the IMEM debug location */
+ ldr r1, [r1]
+ cmp r1, #0
+ beq skip_pc_debug1
+ add r1, r1, r0, LSL #4 /* debug location for this CPU */
+ ldr r2, [r1]
+ add r2, #1
+ str r2, [r1]
+skip_pc_debug1:
+
#ifdef CONFIG_ARCH_MSM_KRAIT
ldr r0, =SCM_SVC_BOOT
ldr r1, =SCM_CMD_TERMINATE_PC
@@ -155,6 +168,21 @@
#if defined(CONFIG_MSM_FIQ_SUPPORT)
cpsie f
#endif
+ mrc p15, 0, r0, c0, c0, 5 /* MPIDR */
+ and r0, r0, #15 /* what CPU am I */
+
+ ldr r1, =msm_pc_debug_counters /*load the IMEM debug location */
+ ldr r1, [r1]
+ cmp r1, #0
+ beq skip_pc_debug2
+ add r1, r1, r0, LSL #4 /* debug location for this CPU */
+ add r1, #8
+ ldr r2, [r1]
+ add r2, #1
+ str r2, [r1]
+
+skip_pc_debug2:
+
#ifdef CONFIG_MSM_JTAG
bl msm_jtag_restore_state
#endif
@@ -276,6 +304,22 @@
mrc p15, 0, r0, c0, c0, 5 /* MPIDR */
and r0, r0, #15 /* what CPU am I */
+ ldr r1, =msm_pc_debug_counters_phys /*phys addr for IMEM reg */
+ ldr r2, =msm_pm_boot_entry
+ adr r3, msm_pm_boot_entry
+ add r1, r1, r3 /* translate virt to phys addr */
+ sub r1, r1, r2
+ ldr r1,[r1]
+
+ cmp r1, #0
+ beq skip_pc_debug3
+ add r1, r1, r0, LSL #4 /* debug location for this CPU */
+ add r1, #4 /* warmboot entry counter*/
+ ldr r2, [r1]
+ add r2, #1
+ str r2, [r1]
+
+skip_pc_debug3:
ldr r1, =msm_pm_boot_vector
ldr r2, =msm_pm_boot_entry
adr r3, msm_pm_boot_entry
@@ -320,6 +364,14 @@
l2x0_base_addr:
.long 0x0
+ .globl msm_pc_debug_counters_phys
+msm_pc_debug_counters_phys:
+ .long 0x0
+
+ .globl msm_pc_debug_counters
+msm_pc_debug_counters:
+ .long 0x0
+
/*
* Default the l2 flush flag to 1 so that caches are flushed during power
* collapse unless the L2 driver decides to flush them only during L2
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index d4d2fca..5b8729a 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -395,6 +395,8 @@
u32 ov1_wb_size; /* overlay1 writeback size */
u32 mem_hid;
char cont_splash_enabled;
+ u32 splash_screen_addr;
+ u32 splash_screen_size;
char mdp_iommu_split_domain;
};
@@ -581,6 +583,9 @@
void msm9625_init_gpiomux(void);
void msm_map_mpq8092_io(void);
void mpq8092_init_gpiomux(void);
+void msm_map_msm8226_io(void);
+void msm8226_init_irq(void);
+void msm8226_init_gpiomux(void);
struct mmc_platform_data;
int msm_add_sdcc(unsigned int controller,
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 60ccded..cf36388 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -24,7 +24,7 @@
#include <mach/board.h>
#include <media/msm_camera.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <mach/iommu_domains.h>
#define CONFIG_MSM_CAMERA_DEBUG
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
index c03b513..08bc981 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
@@ -45,4 +45,7 @@
#define MSM_DEBUG_UART_PHYS 0xF991E000
#endif
+#define MSM8226_DBG_IMEM_PHYS 0xFE805000
+#define MSM8226_DBG_IMEM_SIZE SZ_4K
+
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_memory_dump.h b/arch/arm/mach-msm/include/mach/msm_memory_dump.h
index 3b8c9fd..5e686bf 100644
--- a/arch/arm/mach-msm/include/mach/msm_memory_dump.h
+++ b/arch/arm/mach-msm/include/mach/msm_memory_dump.h
@@ -19,9 +19,13 @@
MSM_CPU_CTXT = 0,
MSM_CACHE,
MSM_OCMEM,
- MSM_ETB,
- MSM_ETM,
- MSM_TMC,
+ MSM_TMC_ETFETB,
+ MSM_ETM0_REG,
+ MSM_ETM1_REG,
+ MSM_ETM2_REG,
+ MSM_ETM3_REG,
+ MSM_TMC0_REG, /* TMC_ETR */
+ MSM_TMC1_REG, /* TMC_ETF */
MAX_NUM_CLIENTS,
};
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 9dff013..e0fec65 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -497,7 +497,7 @@
void __init msm_map_mpq8092_io(void)
{
- msm_shared_ram_phys = MSM8974_MSM_SHARED_RAM_PHYS;
+ msm_shared_ram_phys = MSM8092_MSM_SHARED_RAM_PHYS;
msm_map_io(mpq8092_io_desc, ARRAY_SIZE(mpq8092_io_desc));
}
#endif /* CONFIG_ARCH_MPQ8092 */
@@ -509,12 +509,13 @@
MSM_CHIP_DEVICE(APCS_GCC, MSM8226),
MSM_CHIP_DEVICE(TLMM, MSM8226),
MSM_CHIP_DEVICE(IMEM, MSM8226),
+ MSM_CHIP_DEVICE(DBG_IMEM, MSM8226),
{
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
.length = MSM_SHARED_RAM_SIZE,
.type = MT_DEVICE,
},
-#ifdef CONFIG_DEBUG_MPQ8226_UART
+#ifdef CONFIG_DEBUG_MSM8226_UART
MSM_DEVICE(DEBUG_UART),
#endif
};
diff --git a/arch/arm/mach-msm/jtag.c b/arch/arm/mach-msm/jtag.c
index 3b7c5d6..4f14b19 100644
--- a/arch/arm/mach-msm/jtag.c
+++ b/arch/arm/mach-msm/jtag.c
@@ -25,6 +25,12 @@
#include "cp14.h"
+/* DBGv7 with baseline CP14 registers implemented */
+#define ARM_DEBUG_ARCH_V7B (0x3)
+/* DBGv7 with all CP14 registers implemented */
+#define ARM_DEBUG_ARCH_V7 (0x4)
+#define ARM_DEBUG_ARCH_V7p1 (0x5)
+
#define BM(lsb, msb) ((BIT(msb) - BIT(lsb)) + BIT(msb))
#define BMVAL(val, lsb, msb) ((val & BM(lsb, msb)) >> lsb)
#define BVAL(val, n) ((val & BIT(n)) >> n)
@@ -363,7 +369,7 @@
static inline bool dbg_arch_supported(uint8_t arch)
{
switch (arch) {
- case ARM_DEBUG_ARCH_V7_1:
+ case ARM_DEBUG_ARCH_V7p1:
case ARM_DEBUG_ARCH_V7:
case ARM_DEBUG_ARCH_V7B:
break;
@@ -381,7 +387,7 @@
i = cpu * MAX_DBG_REGS;
switch (dbg.arch) {
- case ARM_DEBUG_ARCH_V7_1:
+ case ARM_DEBUG_ARCH_V7p1:
/* Set OS lock to inform the debugger that the OS is in the
* process of saving debug registers. It prevents accidental
* modification of the debug regs by the external debugger.
@@ -440,7 +446,7 @@
i = cpu * MAX_DBG_REGS;
switch (dbg.arch) {
- case ARM_DEBUG_ARCH_V7_1:
+ case ARM_DEBUG_ARCH_V7p1:
/* Clear the OS double lock */
isb();
dbg_write(0x0, DBGOSDLR);
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 3040a31..ba0e242 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -21,6 +21,7 @@
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
+#include <asm/mach-types.h>
#include <mach/msm_iomap.h>
#include "peripheral-loader.h"
@@ -358,12 +359,18 @@
static int __init pil_riva_init(void)
{
+ if (machine_is_mpq8064_hrd()) {
+ pr_err("pil_riva not supported on this target\n");
+ return 0;
+ }
return platform_driver_register(&pil_riva_driver);
}
module_init(pil_riva_init);
static void __exit pil_riva_exit(void)
{
+ if (machine_is_mpq8064_hrd())
+ return;
platform_driver_unregister(&pil_riva_driver);
}
module_exit(pil_riva_exit);
diff --git a/arch/arm/mach-msm/pil-venus.c b/arch/arm/mach-msm/pil-venus.c
index 49c39ec..1ccde72 100644
--- a/arch/arm/mach-msm/pil-venus.c
+++ b/arch/arm/mach-msm/pil-venus.c
@@ -328,6 +328,59 @@
.proxy_unvote = pil_venus_remove_proxy_vote,
};
+static int pil_venus_init_image_trusted(struct pil_desc *pil,
+ const u8 *metadata, size_t size)
+{
+ return pas_init_image(PAS_VIDC, metadata, size);
+}
+
+static int pil_venus_reset_trusted(struct pil_desc *pil)
+{
+ int rc;
+ struct venus_data *drv = dev_get_drvdata(pil->dev);
+
+ /*
+ * GDSC needs to remain on till Venus is shutdown. So, enable
+ * the GDSC here again to make sure it remains on beyond the
+ * expiry of the proxy vote timer.
+ */
+ rc = regulator_enable(drv->gdsc);
+ if (rc) {
+ dev_err(pil->dev, "GDSC enable failed\n");
+ return rc;
+ }
+
+ rc = pas_auth_and_reset(PAS_VIDC);
+ if (rc)
+ regulator_disable(drv->gdsc);
+
+ return rc;
+}
+
+static int pil_venus_shutdown_trusted(struct pil_desc *pil)
+{
+ int rc;
+ struct venus_data *drv = dev_get_drvdata(pil->dev);
+
+ venus_clock_prepare_enable(pil->dev);
+
+ rc = pas_shutdown(PAS_VIDC);
+
+ venus_clock_disable_unprepare(pil->dev);
+
+ regulator_disable(drv->gdsc);
+
+ return rc;
+}
+
+static struct pil_reset_ops pil_venus_ops_trusted = {
+ .init_image = pil_venus_init_image_trusted,
+ .auth_and_reset = pil_venus_reset_trusted,
+ .shutdown = pil_venus_shutdown_trusted,
+ .proxy_vote = pil_venus_make_proxy_vote,
+ .proxy_unvote = pil_venus_remove_proxy_vote,
+};
+
static int __devinit pil_venus_probe(struct platform_device *pdev)
{
struct venus_data *drv;
@@ -422,9 +475,13 @@
desc->owner = THIS_MODULE;
desc->proxy_timeout = VENUS_PROXY_TIMEOUT;
- /* TODO: need to add secure boot when the support is available */
- desc->ops = &pil_venus_ops;
- dev_info(&pdev->dev, "using non-secure boot\n");
+ if (pas_supported(PAS_VIDC) > 0) {
+ desc->ops = &pil_venus_ops_trusted;
+ dev_info(&pdev->dev, "using secure boot\n");
+ } else {
+ desc->ops = &pil_venus_ops;
+ dev_info(&pdev->dev, "using non-secure boot\n");
+ }
drv->pil = msm_pil_register(desc);
if (IS_ERR(drv->pil))
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index b2681b7..f6ed1ea 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -84,7 +84,8 @@
if (!base_ptr)
return -ENODEV;
- if (machine_is_msm8974_sim() || machine_is_mpq8092_sim()) {
+ if (machine_is_msm8974_sim() || machine_is_mpq8092_sim() ||
+ machine_is_msm8226_sim()) {
writel_relaxed(0x800, base_ptr+0x04);
writel_relaxed(0x3FFF, base_ptr+0x14);
}
@@ -159,7 +160,8 @@
if (cpu_is_msm8x60())
return scorpion_release_secondary();
- if (machine_is_msm8974_sim() || machine_is_mpq8092_sim())
+ if (machine_is_msm8974_sim() || machine_is_mpq8092_sim() ||
+ machine_is_msm8226_sim())
return krait_release_secondary_sim(0xf9088000, cpu);
if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 8ddb9e1..dbb23d5 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -24,6 +24,7 @@
#include <linux/smp.h>
#include <linux/suspend.h>
#include <linux/tick.h>
+#include <linux/platform_device.h>
#include <mach/msm_iomap.h>
#include <mach/socinfo.h>
#include <mach/system.h>
@@ -71,7 +72,6 @@
);
static int msm_pm_retention_tz_call;
-
/******************************************************************************
* Sleep Modes and Parameters
*****************************************************************************/
@@ -491,7 +491,6 @@
#ifdef CONFIG_VFP
vfp_pm_suspend();
#endif
-
collapsed = msm_pm_l2x0_power_collapse();
msm_pm_boot_config_after_pc(cpu);
@@ -950,6 +949,46 @@
msm_pm_retention_tz_call = flag;
}
+static int __devinit msm_pc_debug_probe(struct platform_device *pdev)
+{
+ struct resource *res = NULL;
+ int i ;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ goto fail;
+
+ msm_pc_debug_counters_phys = res->start;
+ WARN_ON(resource_size(res) < SZ_64);
+ msm_pc_debug_counters = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+
+ if (!msm_pc_debug_counters)
+ goto fail;
+
+ for (i = 0; i < resource_size(res)/4; i++)
+ __raw_writel(0, msm_pc_debug_counters + i * 4);
+ return 0;
+fail:
+ msm_pc_debug_counters = 0;
+ msm_pc_debug_counters_phys = 0;
+ return -EFAULT;
+}
+
+static struct of_device_id msm_pc_debug_table[] = {
+ {.compatible = "qcom,pc-cntr"},
+ {},
+};
+
+static struct platform_driver msm_pc_counter_driver = {
+ .probe = msm_pc_debug_probe,
+ .driver = {
+ .name = "pc-cntr",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_pc_debug_table,
+ },
+};
+
static int __init msm_pm_init(void)
{
pgd_t *pc_pgd;
@@ -965,6 +1004,7 @@
unsigned long exit_phys;
/* Page table for cores to come back up safely. */
+
pc_pgd = pgd_alloc(&init_mm);
if (!pc_pgd)
return -ENOMEM;
@@ -1007,6 +1047,7 @@
suspend_set_ops(&msm_pm_ops);
msm_pm_qtimer_available();
msm_cpuidle_init();
+ platform_driver_register(&msm_pc_counter_driver);
return 0;
}
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 552fb16..e2553e2 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -131,5 +131,6 @@
#endif
void msm_pm_set_cpr_ops(struct msm_pm_cpr_ops *ops);
-
+extern void *msm_pc_debug_counters;
+extern unsigned long msm_pc_debug_counters_phys;
#endif /* __ARCH_ARM_MACH_MSM_PM_H */
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
index 485234f..44ab611 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -81,7 +81,13 @@
aac_cfg.spectral_data_resilience =
aac_config->aac_spectral_data_resilience_flag;
aac_cfg.ch_cfg = audio->pcm_cfg.channel_count;
- aac_cfg.sample_rate = audio->pcm_cfg.sample_rate;
+ if (audio->feedback == TUNNEL_MODE) {
+ aac_cfg.sample_rate = aac_config->sample_rate;
+ aac_cfg.ch_cfg = aac_config->channel_configuration;
+ } else {
+ aac_cfg.sample_rate = audio->pcm_cfg.sample_rate;
+ aac_cfg.ch_cfg = audio->pcm_cfg.channel_count;
+ }
pr_debug("%s:format=%x aot=%d ch=%d sr=%d\n",
__func__, aac_cfg.format,
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
index fbd94c5..b53edd9 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -43,8 +43,13 @@
struct msm_audio_aac_config *aac_config;
uint32_t sbr_ps = 0x00;
aac_config = (struct msm_audio_aac_config *)audio->codec_cfg;
- aac_cfg.ch_cfg = aac_config->channel_configuration;
- aac_cfg.sample_rate = audio->pcm_cfg.sample_rate;
+ if (audio->feedback == TUNNEL_MODE) {
+ aac_cfg.sample_rate = aac_config->sample_rate;
+ aac_cfg.ch_cfg = aac_config->channel_configuration;
+ } else {
+ aac_cfg.sample_rate = audio->pcm_cfg.sample_rate;
+ aac_cfg.ch_cfg = audio->pcm_cfg.channel_count;
+ }
pr_debug("%s: AUDIO_START session_id[%d]\n", __func__,
audio->ac->session);
if (audio->feedback == NON_TUNNEL_MODE) {
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 25723d5..53736ac 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -26,6 +26,7 @@
#include <linux/mfd/pm8xxx/misc.h>
#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
#include <mach/msm_iomap.h>
#include <mach/restart.h>
@@ -221,6 +222,8 @@
__raw_writel(0x77665501, restart_reason);
}
}
+
+ flush_cache_all();
}
void msm_restart(char mode, const char *cmd)
diff --git a/arch/arm/mach-msm/scm-pas.c b/arch/arm/mach-msm/scm-pas.c
index 55ae2f8..43436e5 100644
--- a/arch/arm/mach-msm/scm-pas.c
+++ b/arch/arm/mach-msm/scm-pas.c
@@ -204,7 +204,11 @@
}
}
- scm_perf_client = msm_bus_scale_register_client(&scm_pas_bus_pdata);
+ /* TODO : Remove once bus scaling driver is in place */
+ if (!cpu_is_msm8226())
+ scm_perf_client = msm_bus_scale_register_client(
+ &scm_pas_bus_pdata);
+
if (!scm_perf_client)
pr_warn("unable to register bus client\n");
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index cbf1d72..f014df9 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/wcnss_wlan.h>
#include <linux/err.h>
+#include <asm/mach-types.h>
#include <mach/irqs.h>
#include <mach/scm.h>
#include <mach/subsystem_restart.h>
@@ -180,13 +181,8 @@
static void riva_crash_shutdown(const struct subsys_desc *subsys)
{
pr_err("%s: crash shutdown : %d\n", MODULE_NAME, riva_crash);
- if (riva_crash != true) {
+ if (riva_crash != true)
smsm_riva_reset();
- /* give sufficient time for wcnss to finish it's error
- * fatal routine */
- msleep(3000);
- }
-
}
static struct subsys_desc riva_8960 = {
@@ -226,6 +222,11 @@
{
int ret;
+ if (machine_is_mpq8064_hrd()) {
+ pr_err("Riva not supported on this target\n");
+ return 0;
+ }
+
ret = smsm_state_cb_register(SMSM_WCNSS_STATE, SMSM_RESET,
smsm_state_cb_hdlr, 0);
if (ret < 0) {
@@ -264,6 +265,8 @@
static void __exit riva_ssr_module_exit(void)
{
+ if (machine_is_mpq8064_hrd())
+ return;
subsys_unregister(riva_8960_dev);
free_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ, NULL);
}
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index 9bc0da5..c0690c8 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -218,8 +218,10 @@
spin_lock_irqsave(&obj->active_list_lock, flags);
err = _sync_pt_has_signaled(pt);
- if (err != 0)
+ if (err != 0) {
+ sync_fence_signal_pt(pt);
goto out;
+ }
list_add_tail(&pt->active_list, &obj->active_list_head);
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 1c14859..b18d709 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -279,12 +279,14 @@
struct diag_request *write_ptr_mdm;
/* HSIC variables */
int hsic_ch;
+ int hsic_inited;
int hsic_device_enabled;
int hsic_device_opened;
int hsic_suspend;
int in_busy_hsic_read_on_device;
int in_busy_hsic_write;
struct work_struct diag_read_hsic_work;
+ struct mutex bridge_mutex;
/* USB MDM channel variables */
int usb_mdm_connected;
int read_len_mdm;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 7e827b9..59139dc 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -93,6 +93,9 @@
ret += length; \
} while (0)
+/* Identifier for data from MDM */
+#define MDM_TOKEN -1
+
static void drain_timer_func(unsigned long data)
{
queue_work(driver->diag_wq , &(driver->diag_drain_work));
@@ -650,6 +653,10 @@
{
int index = -1, i = 0, ret = 0;
int num_data = 0, data_type;
+#if defined(CONFIG_DIAG_SDIO_PIPE) || defined(CONFIG_DIAG_BRIDGE_CODE)
+ int mdm_token = MDM_TOKEN;
+#endif
+
for (i = 0; i < driver->num_clients; i++)
if (driver->client_map[i].pid == current->tgid)
index = i;
@@ -789,6 +796,8 @@
/* copy 9K data over SDIO */
if (driver->in_busy_sdio == 1) {
num_data++;
+ /*Copy the negative token of data being passed*/
+ COPY_USER_SPACE_OR_EXIT(buf+ret, mdm_token, 4);
/*Copy the length of data being passed*/
COPY_USER_SPACE_OR_EXIT(buf+ret,
(driver->write_ptr_mdm->length), 4);
@@ -818,6 +827,14 @@
i, (unsigned int)hsic_buf_tbl[i].buf,
hsic_buf_tbl[i].length);
num_data++;
+
+ /* Copy the negative token */
+ if (copy_to_user(buf+ret, &mdm_token, 4)) {
+ num_data--;
+ goto drop_hsic;
+ }
+ ret += 4;
+
/* Copy the length of data being passed */
if (copy_to_user(buf+ret,
(void *)&(hsic_buf_tbl[i].length),
@@ -846,6 +863,21 @@
diagfwd_write_complete_hsic(NULL);
}
}
+ if (driver->in_busy_smux == 1) {
+ num_data++;
+
+ /* Copy the negative token of data being passed */
+ COPY_USER_SPACE_OR_EXIT(buf+ret, mdm_token, 4);
+ /* Copy the length of data being passed */
+ COPY_USER_SPACE_OR_EXIT(buf+ret,
+ (driver->write_ptr_mdm->length), 4);
+ /* Copy the actual data being passed */
+ COPY_USER_SPACE_OR_EXIT(buf+ret,
+ *(driver->buf_in_smux),
+ driver->write_ptr_mdm->length);
+ pr_debug("diag: SMUX data copied\n");
+ driver->in_busy_smux = 0;
+ }
#endif
/* copy number of data fields */
COPY_USER_SPACE_OR_EXIT(buf+4, num_data, 4);
@@ -950,6 +982,7 @@
size_t count, loff_t *ppos)
{
int err, ret = 0, pkt_type;
+ bool mdm_mask = false;
#ifdef DIAG_DEBUG
int length = 0, i;
#endif
@@ -985,6 +1018,12 @@
payload_size);
/* Check masks for On-Device logging */
if (driver->mask_check) {
+ /* Check if mask is for MDM or MSM */
+ if (*(int *)driver->user_space_data == MDM_TOKEN) {
+ mdm_mask = true;
+ driver->user_space_data += 4;
+ buf += 4;
+ }
if (!mask_request_validate(driver->user_space_data)) {
pr_alert("diag: mask request Invalid\n");
return -EFAULT;
@@ -998,7 +1037,7 @@
#endif
#ifdef CONFIG_DIAG_SDIO_PIPE
/* send masks to 9k too */
- if (driver->sdio_ch) {
+ if (driver->sdio_ch && mdm_mask) {
wait_event_interruptible(driver->wait_q,
(sdio_write_avail(driver->sdio_ch) >=
payload_size));
@@ -1010,7 +1049,7 @@
#endif
#ifdef CONFIG_DIAG_BRIDGE_CODE
/* send masks to 9k too */
- if (driver->hsic_ch && (payload_size > 0)) {
+ if (driver->hsic_ch && (payload_size > 0) && mdm_mask) {
/* wait sending mask updates if HSIC ch not ready */
if (driver->in_busy_hsic_write)
wait_event_interruptible(driver->wait_q,
@@ -1032,9 +1071,22 @@
driver->in_busy_hsic_write = 0;
}
}
+ if (driver->diag_smux_enabled && mdm_mask && driver->lcid) {
+ if (payload_size > 0) {
+ err = msm_smux_write(driver->lcid, NULL,
+ driver->user_space_data,
+ payload_size);
+ if (err) {
+ pr_err("diag:send mask to MDM err %d",
+ err);
+ return err;
+ }
+ }
+ }
#endif
/* send masks to 8k now */
- diag_process_hdlc((void *)(driver->user_space_data),
+ if (!mdm_mask)
+ diag_process_hdlc((void *)(driver->user_space_data),
payload_size);
return 0;
}
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 884e5fe..c827ec7 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
+#include <linux/ratelimit.h>
#include <linux/workqueue.h>
#include <linux/pm_runtime.h>
#include <linux/diagchar.h>
@@ -439,7 +440,8 @@
diagmem_free(driver,
write_ptr_mdm,
POOL_TYPE_HSIC_WRITE);
- pr_err("diag: HSIC write failure\n");
+ pr_err_ratelimited("diag: HSIC write failure, err: %d\n",
+ err);
}
} else {
pr_err("diag: allocate write fail\n");
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 52fd673..e417d5a 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -558,6 +558,7 @@
ret = scnprintf(buf, DEBUG_BUF_SIZE,
"hsic ch: %d\n"
+ "hsic_inited: %d\n"
"hsic enabled: %d\n"
"hsic_opened: %d\n"
"hsic_suspend: %d\n"
@@ -575,6 +576,7 @@
"diag_disconnect_work: %d\n"
"diag_usb_read_complete_work: %d\n",
driver->hsic_ch,
+ driver->hsic_inited,
driver->hsic_device_enabled,
driver->hsic_device_opened,
driver->hsic_suspend,
diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c
index 0b1f720..56f2fae 100644
--- a/drivers/char/diag/diagfwd_hsic.c
+++ b/drivers/char/diag/diagfwd_hsic.c
@@ -71,6 +71,13 @@
write_ptrs_available--;
+ /*
+ * No sense queuing a read if the hsic bridge was
+ * closed in another thread
+ */
+ if (!driver->hsic_ch)
+ break;
+
buf_in_hsic = diagmem_alloc(driver, READ_HSIC_BUF_SIZE,
POOL_TYPE_HSIC);
if (buf_in_hsic) {
@@ -107,7 +114,8 @@
* (-ENODEV is an unrecoverable error), then set up the next read
*/
if ((driver->count_hsic_pool < driver->poolsize_hsic) &&
- (num_reads_submitted == 0) && (err != -ENODEV))
+ (num_reads_submitted == 0) && (err != -ENODEV) &&
+ (driver->hsic_ch != 0))
queue_work(driver->diag_bridge_wq,
&driver->diag_read_hsic_work);
}
@@ -146,7 +154,7 @@
/* If an error, return buffer to the pool */
if (err) {
diagmem_free(driver, buf, POOL_TYPE_HSIC);
- pr_err("diag: In %s, error calling diag_device_write, err: %d\n",
+ pr_err_ratelimited("diag: In %s, error calling diag_device_write, err: %d\n",
__func__, err);
}
}
@@ -228,20 +236,20 @@
.resume = diag_hsic_resume,
};
-static int diag_hsic_close(void)
+static void diag_hsic_close(void)
{
if (driver->hsic_device_enabled) {
driver->hsic_ch = 0;
if (driver->hsic_device_opened) {
driver->hsic_device_opened = 0;
diag_bridge_close();
+ pr_debug("diag: %s: closed successfully\n", __func__);
+ } else {
+ pr_debug("diag: %s: already closed\n", __func__);
}
- pr_debug("diag: in %s: closed successfully\n", __func__);
} else {
- pr_debug("diag: in %s: already closed\n", __func__);
+ pr_debug("diag: %s: HSIC device already removed\n", __func__);
}
-
- return 0;
}
/* diagfwd_cancel_hsic is called to cancel outstanding read/writes */
@@ -249,6 +257,7 @@
{
int err;
+ mutex_lock(&driver->bridge_mutex);
if (driver->hsic_device_enabled) {
if (driver->hsic_device_opened) {
driver->hsic_ch = 0;
@@ -266,6 +275,7 @@
}
}
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -276,6 +286,7 @@
pr_debug("diag: in %s\n", __func__);
+ mutex_lock(&driver->bridge_mutex);
/* If the usb cable is being connected */
if (process_cable) {
err = usb_diag_alloc_req(driver->mdm_ch, N_MDM_WRITE,
@@ -293,6 +304,7 @@
} else if (driver->diag_smux_enabled) {
driver->in_busy_smux = 0;
diagfwd_connect_smux();
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -315,22 +327,24 @@
* Turn on communication over usb mdm and hsic, if the hsic
* device driver is enabled and opened
*/
- if (driver->hsic_device_opened)
+ if (driver->hsic_device_opened) {
driver->hsic_ch = 1;
- /* Poll USB mdm channel to check for data */
- if (driver->logging_mode == USB_MODE)
- queue_work(driver->diag_bridge_wq,
- &driver->diag_read_mdm_work);
+ /* Poll USB mdm channel to check for data */
+ if (driver->logging_mode == USB_MODE)
+ queue_work(driver->diag_bridge_wq,
+ &driver->diag_read_mdm_work);
- /* Poll HSIC channel to check for data */
- queue_work(driver->diag_bridge_wq,
- &driver->diag_read_hsic_work);
+ /* Poll HSIC channel to check for data */
+ queue_work(driver->diag_bridge_wq,
+ &driver->diag_read_hsic_work);
+ }
} else {
/* The hsic device driver has not yet been enabled */
pr_info("diag: HSIC channel not yet enabled\n");
}
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -342,6 +356,8 @@
{
pr_debug("diag: In %s, process_cable: %d\n", __func__, process_cable);
+ mutex_lock(&driver->bridge_mutex);
+
/* If the usb cable is being disconnected */
if (process_cable) {
driver->usb_mdm_connected = 0;
@@ -353,7 +369,7 @@
driver->in_busy_hsic_read_on_device = 1;
driver->in_busy_hsic_write = 1;
/* Turn off communication over usb mdm and hsic */
- return diag_hsic_close();
+ diag_hsic_close();
} else if (driver->diag_smux_enabled &&
driver->logging_mode == USB_MODE) {
driver->in_busy_smux = 1;
@@ -362,6 +378,8 @@
/* Turn off communication over usb mdm and smux */
msm_smux_close(LCID_VALID);
}
+
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -543,13 +561,15 @@
{
int err = 0;
pr_debug("diag: in %s\n", __func__);
- if (!driver->hsic_device_enabled) {
+ if (!driver->hsic_inited) {
diagmem_hsic_init(driver);
INIT_WORK(&(driver->diag_read_hsic_work),
diag_read_hsic_work_fn);
- driver->hsic_device_enabled = 1;
+ driver->hsic_inited = 1;
}
+ mutex_lock(&driver->bridge_mutex);
+
/*
* The probe function was called after the usb was connected
* on the legacy channel OR ODL is turned on. Communication over usb
@@ -557,11 +577,17 @@
*/
if (driver->usb_mdm_connected || (driver->logging_mode ==
MEMORY_DEVICE_MODE)) {
- /* The hsic (diag_bridge) platform device driver is enabled */
+ if (driver->hsic_device_opened) {
+ /* should not happen. close it before re-opening */
+ pr_warn("diag: HSIC channel already opened in probe\n");
+ diag_bridge_close();
+ }
+
err = diag_bridge_open(&hsic_diag_bridge_ops);
if (err) {
pr_err("diag: could not open HSIC, err: %d\n", err);
driver->hsic_device_opened = 0;
+ mutex_unlock(&driver->bridge_mutex);
return err;
}
@@ -583,13 +609,19 @@
&driver->diag_read_hsic_work);
}
+ /* The hsic (diag_bridge) platform device driver is enabled */
+ driver->hsic_device_enabled = 1;
+ mutex_unlock(&driver->bridge_mutex);
return err;
}
static int diag_hsic_remove(struct platform_device *pdev)
{
pr_debug("diag: %s called\n", __func__);
+ mutex_lock(&driver->bridge_mutex);
diag_hsic_close();
+ driver->hsic_device_enabled = 0;
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -662,6 +694,7 @@
driver->itemsize_hsic_write = sizeof(struct diag_request);
driver->poolsize_hsic_write = N_MDM_WRITE;
+ mutex_init(&driver->bridge_mutex);
#ifdef CONFIG_DIAG_OVER_USB
INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn);
#endif
@@ -705,8 +738,9 @@
if (driver->hsic_device_enabled) {
diag_hsic_close();
driver->hsic_device_enabled = 0;
- diagmem_exit(driver, POOL_TYPE_ALL);
}
+ driver->hsic_inited = 0;
+ diagmem_exit(driver, POOL_TYPE_ALL);
if (driver->diag_smux_enabled) {
driver->lcid = LCID_INVALID;
kfree(driver->buf_in_smux);
diff --git a/drivers/char/diag/diagmem.c b/drivers/char/diag/diagmem.c
index 82c47af..1a522d5 100644
--- a/drivers/char/diag/diagmem.c
+++ b/drivers/char/diag/diagmem.c
@@ -106,7 +106,7 @@
printk(KERN_ALERT "Unable to destroy STRUCT mempool");
}
#ifdef CONFIG_DIAG_BRIDGE_CODE
- if (driver->diag_hsic_pool && (driver->hsic_device_enabled == 0)) {
+ if (driver->diag_hsic_pool && (driver->hsic_inited == 0)) {
if (driver->count_hsic_pool == 0) {
mempool_destroy(driver->diag_hdlc_pool);
driver->diag_hdlc_pool = NULL;
@@ -114,8 +114,7 @@
pr_err("Unable to destroy HDLC mempool");
}
- if (driver->diag_hsic_write_pool &&
- (driver->hsic_device_enabled == 0)) {
+ if (driver->diag_hsic_write_pool && (driver->hsic_inited == 0)) {
/*
* Free up struct pool ONLY if there are no outstanding
* transactions(aggregation buffer) with USB
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index 6f3b79b..e1e3ff5 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -28,7 +28,7 @@
#include <linux/file.h>
#include <linux/major.h>
#include <linux/regulator/consumer.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#ifdef CONFIG_MSM_BUS_SCALING
#include <mach/msm_bus.h>
#include <mach/msm_bus_board.h>
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
index 182e50c..f4c4d08 100644
--- a/drivers/coresight/coresight-etm.c
+++ b/drivers/coresight/coresight-etm.c
@@ -31,6 +31,7 @@
#include <linux/coresight.h>
#include <asm/sections.h>
#include <mach/socinfo.h>
+#include <mach/msm_memory_dump.h>
#include "coresight-priv.h"
@@ -131,6 +132,9 @@
#define ETM_SEQ_STATE_MAX_VAL (0x2)
+#define ETM_REG_DUMP_VER_OFF (4)
+#define ETM_REG_DUMP_VER (1)
+
enum etm_addr_type {
ETM_ADDR_TYPE_NONE,
ETM_ADDR_TYPE_SINGLE,
@@ -1412,9 +1416,8 @@
return true;
}
-static int __devinit etm_init_arch_data(struct etm_drvdata *drvdata)
+static void __devinit etm_init_arch_data(struct etm_drvdata *drvdata)
{
- int ret;
uint32_t etmidr;
uint32_t etmccr;
@@ -1432,10 +1435,6 @@
/* find all capabilities */
etmidr = etm_readl(drvdata, ETMIDR);
drvdata->arch = BMVAL(etmidr, 4, 11);
- if (etm_arch_supported(drvdata->arch) == false) {
- ret = -EINVAL;
- goto err;
- }
etmccr = etm_readl(drvdata, ETMCCR);
drvdata->nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
@@ -1447,10 +1446,6 @@
/* Vote for ETM power/clock disable */
etm_set_pwrdwn(drvdata);
ETM_LOCK(drvdata);
-
- return 0;
-err:
- return ret;
}
static void __devinit etm_copy_arch_data(struct etm_drvdata *drvdata)
@@ -1517,7 +1512,10 @@
struct coresight_platform_data *pdata;
struct etm_drvdata *drvdata;
struct resource *res;
- static int etm_count;
+ uint32_t reg_size;
+ static int count;
+ void *baddr;
+ struct msm_client_dump dump;
struct coresight_desc *desc;
/* Fail probe for Krait pass3 until supported */
@@ -1542,6 +1540,7 @@
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
+ reg_size = resource_size(res);
drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
if (!drvdata->base)
@@ -1560,7 +1559,7 @@
if (ret)
goto err0;
- drvdata->cpu = etm_count++;
+ drvdata->cpu = count++;
ret = clk_prepare_enable(drvdata->clk);
if (ret)
@@ -1570,20 +1569,34 @@
* ETMs copy it over from ETM0.
*/
if (drvdata->cpu == 0) {
- ret = etm_init_arch_data(drvdata);
- if (ret)
- goto err1;
+ etm_init_arch_data(drvdata);
etm0drvdata = drvdata;
} else {
- if (etm0drvdata)
- etm_copy_arch_data(drvdata);
- else
- goto err1;
+ etm_copy_arch_data(drvdata);
+ }
+ if (etm_arch_supported(drvdata->arch) == false) {
+ ret = -EINVAL;
+ goto err1;
}
etm_init_default_data(drvdata);
clk_disable_unprepare(drvdata->clk);
+ baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL);
+ if (baddr) {
+ *(uint32_t *)(baddr + ETM_REG_DUMP_VER_OFF) = ETM_REG_DUMP_VER;
+ dump.id = MSM_ETM0_REG + drvdata->cpu;
+ dump.start_addr = virt_to_phys(baddr);
+ dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size;
+ ret = msm_dump_table_register(&dump);
+ if (ret) {
+ devm_kfree(dev, baddr);
+ dev_err(dev, "ETM REG dump setup failed\n");
+ }
+ } else {
+ dev_err(dev, "ETM REG dump space allocation failed\n");
+ }
+
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
if (!desc) {
ret = -ENOMEM;
diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c
index 995ad86..0be5882 100644
--- a/drivers/coresight/coresight-tmc.c
+++ b/drivers/coresight/coresight-tmc.c
@@ -32,6 +32,7 @@
#include <mach/memory.h>
#include <mach/sps.h>
#include <mach/usb_bam.h>
+#include <mach/msm_memory_dump.h>
#include "coresight-priv.h"
@@ -80,6 +81,11 @@
#define TMC_ETR_BAM_PIPE_INDEX 0
#define TMC_ETR_BAM_NR_PIPES 2
+#define TMC_ETFETB_DUMP_VER_OFF (4)
+#define TMC_ETFETB_DUMP_VER (1)
+#define TMC_REG_DUMP_VER_OFF (4)
+#define TMC_REG_DUMP_VER (1)
+
enum tmc_config_type {
TMC_CONFIG_TYPE_ETB,
TMC_CONFIG_TYPE_ETR,
@@ -986,6 +992,11 @@
struct coresight_platform_data *pdata;
struct tmc_drvdata *drvdata;
struct resource *res;
+ uint32_t reg_size;
+ static int etfetb_count;
+ static int count;
+ void *baddr;
+ struct msm_client_dump dump;
struct coresight_desc *desc;
if (pdev->dev.of_node) {
@@ -1004,6 +1015,7 @@
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
+ reg_size = resource_size(res);
drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
if (!drvdata->base)
@@ -1031,7 +1043,8 @@
if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
drvdata->size = SZ_1M;
else
- drvdata->size = tmc_readl(drvdata, TMC_RSZ) * BYTES_PER_WORD;
+ drvdata->size = (tmc_readl(drvdata, TMC_RSZ) * BYTES_PER_WORD)
+ + PAGE_SIZE;
clk_disable_unprepare(drvdata->clk);
@@ -1053,11 +1066,40 @@
if (ret)
goto err0;
} else {
- drvdata->buf = devm_kzalloc(dev, drvdata->size, GFP_KERNEL);
- if (!drvdata->buf)
+ baddr = devm_kzalloc(dev, drvdata->size, GFP_KERNEL);
+ if (!baddr)
return -ENOMEM;
+ drvdata->buf = baddr + PAGE_SIZE;
+ *(uint32_t *)(baddr + TMC_ETFETB_DUMP_VER_OFF) =
+ TMC_ETFETB_DUMP_VER;
+ dump.id = MSM_TMC_ETFETB + etfetb_count;
+ dump.start_addr = virt_to_phys(baddr);
+ dump.end_addr = dump.start_addr + drvdata->size;
+ ret = msm_dump_table_register(&dump);
+ /* Don't free the buffer in case of error since it can still
+ * be used to provide dump collection via the device node
+ */
+ if (ret)
+ dev_info(dev, "TMC ETF-ETB dump setup failed\n");
+ etfetb_count++;
}
+ baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL);
+ if (baddr) {
+ *(uint32_t *)(baddr + TMC_REG_DUMP_VER_OFF) = TMC_REG_DUMP_VER;
+ dump.id = MSM_TMC0_REG + count;
+ dump.start_addr = virt_to_phys(baddr);
+ dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size;
+ ret = msm_dump_table_register(&dump);
+ if (ret) {
+ devm_kfree(dev, baddr);
+ dev_info(dev, "TMC REG dump setup failed\n");
+ }
+ } else {
+ dev_info(dev, "TMC REG dump space allocation failed\n");
+ }
+ count++;
+
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
if (!desc) {
ret = -ENOMEM;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 03fdc5a..c799c1f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -556,7 +556,6 @@
PMICs through RPC.
config GPIO_QPNP_PIN
- depends on ARCH_MSM8974
depends on SPMI
depends on OF_SPMI
depends on MSM_QPNP_INT
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 31bbb1f..7f760ed 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -33,6 +33,7 @@
#include <linux/uaccess.h>
#include <linux/debugfs.h>
#include <linux/dma-buf.h>
+#include <linux/msm_ion.h>
#include <mach/iommu_domains.h>
#include "ion_priv.h"
@@ -701,6 +702,8 @@
if (iommu_map->flags & ION_IOMMU_UNMAP_DELAYED)
kref_get(&iommu_map->ref);
+ } else {
+ ret = PTR_ERR(iommu_map);
}
} else {
if (iommu_map->flags != iommu_flags) {
@@ -819,31 +822,6 @@
}
EXPORT_SYMBOL(ion_unmap_kernel);
-static int check_vaddr_bounds(unsigned long start, unsigned long end)
-{
- struct mm_struct *mm = current->active_mm;
- struct vm_area_struct *vma;
- int ret = 1;
-
- if (end < start)
- goto out;
-
- down_read(&mm->mmap_sem);
- vma = find_vma(mm, start);
- if (vma && vma->vm_start < end) {
- if (start < vma->vm_start)
- goto out_up;
- if (end > vma->vm_end)
- goto out_up;
- ret = 0;
- }
-
-out_up:
- up_read(&mm->mmap_sem);
-out:
- return ret;
-}
-
int ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
void *uaddr, unsigned long offset, unsigned long len,
unsigned int cmd)
@@ -1413,8 +1391,10 @@
sizeof(struct ion_fd_data)))
return -EFAULT;
data.handle = ion_import_dma_buf(client, data.fd);
- if (IS_ERR(data.handle))
+ if (IS_ERR(data.handle)) {
+ ret = PTR_ERR(data.handle);
data.handle = NULL;
+ }
if (copy_to_user((void __user *)arg, &data,
sizeof(struct ion_fd_data)))
return -EFAULT;
@@ -1435,65 +1415,17 @@
return dev->custom_ioctl(client, data.cmd, data.arg);
}
case ION_IOC_CLEAN_CACHES:
+ return client->dev->custom_ioctl(client,
+ ION_IOC_CLEAN_CACHES, arg);
case ION_IOC_INV_CACHES:
+ return client->dev->custom_ioctl(client,
+ ION_IOC_INV_CACHES, arg);
case ION_IOC_CLEAN_INV_CACHES:
- {
- struct ion_flush_data data;
- unsigned long start, end;
- struct ion_handle *handle = NULL;
- int ret;
-
- if (copy_from_user(&data, (void __user *)arg,
- sizeof(struct ion_flush_data)))
- return -EFAULT;
-
- start = (unsigned long) data.vaddr;
- end = (unsigned long) data.vaddr + data.length;
-
- if (check_vaddr_bounds(start, end)) {
- pr_err("%s: virtual address %p is out of bounds\n",
- __func__, data.vaddr);
- return -EINVAL;
- }
-
- if (!data.handle) {
- handle = ion_import_dma_buf(client, data.fd);
- if (IS_ERR(handle)) {
- pr_info("%s: Could not import handle: %d\n",
- __func__, (int)handle);
- return -EINVAL;
- }
- }
-
- ret = ion_do_cache_op(client,
- data.handle ? data.handle : handle,
- data.vaddr, data.offset, data.length,
- cmd);
-
- if (!data.handle)
- ion_free(client, handle);
-
- if (ret < 0)
- return ret;
- break;
-
- }
+ return client->dev->custom_ioctl(client,
+ ION_IOC_CLEAN_INV_CACHES, arg);
case ION_IOC_GET_FLAGS:
- {
- struct ion_flag_data data;
- int ret;
- if (copy_from_user(&data, (void __user *)arg,
- sizeof(struct ion_flag_data)))
- return -EFAULT;
-
- ret = ion_handle_get_flags(client, data.handle, &data.flags);
- if (ret < 0)
- return ret;
- if (copy_to_user((void __user *)arg, &data,
- sizeof(struct ion_flag_data)))
- return -EFAULT;
- break;
- }
+ return client->dev->custom_ioctl(client,
+ ION_IOC_GET_FLAGS, arg);
default:
return -ENOTTY;
}
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index a591eb4..7d7ea36 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -31,6 +31,7 @@
#include <mach/iommu_domains.h>
#include <asm/mach/map.h>
#include <asm/cacheflush.h>
+#include <linux/msm_ion.h>
struct ion_carveout_heap {
struct ion_heap heap;
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index 23ccab3..9f33859 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -19,7 +19,7 @@
#include <linux/err.h>
#include <linux/genalloc.h>
#include <linux/io.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <linux/mm.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c
index 6ea49db..165a7bf 100644
--- a/drivers/gpu/ion/ion_heap.c
+++ b/drivers/gpu/ion/ion_heap.c
@@ -18,6 +18,7 @@
#include <linux/err.h>
#include <linux/ion.h>
#include "ion_priv.h"
+#include <linux/msm_ion.h>
struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
{
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index d0f101c..345c07d 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -12,7 +12,7 @@
*/
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <linux/mm.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index c79c184..ad2ef83 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -27,6 +27,7 @@
#include "ion_priv.h"
#include <mach/memory.h>
#include <asm/cacheflush.h>
+#include <linux/msm_ion.h>
static atomic_t system_heap_allocated;
static atomic_t system_contig_heap_allocated;
diff --git a/drivers/gpu/ion/msm/ion_cp_common.h b/drivers/gpu/ion/msm/ion_cp_common.h
index 69dd19e..634473f 100644
--- a/drivers/gpu/ion/msm/ion_cp_common.h
+++ b/drivers/gpu/ion/msm/ion_cp_common.h
@@ -15,7 +15,7 @@
#define ION_CP_COMMON_H
#include <asm-generic/errno-base.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#define ION_CP_V1 1
#define ION_CP_V2 2
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index c65a000..4c9be1d 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -13,12 +13,17 @@
#include <linux/export.h>
#include <linux/err.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/memory_alloc.h>
#include <linux/fmem.h>
#include <linux/of.h>
+#include <linux/mm.h>
+#include <linux/mm_types.h>
+#include <linux/sched.h>
+#include <linux/rwsem.h>
+#include <linux/uaccess.h>
#include <mach/ion.h>
#include <mach/msm_memtypes.h>
#include "../ion_priv.h"
@@ -556,6 +561,102 @@
return ERR_PTR(ret);
}
+static int check_vaddr_bounds(unsigned long start, unsigned long end)
+{
+ struct mm_struct *mm = current->active_mm;
+ struct vm_area_struct *vma;
+ int ret = 1;
+
+ if (end < start)
+ goto out;
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, start);
+ if (vma && vma->vm_start < end) {
+ if (start < vma->vm_start)
+ goto out_up;
+ if (end > vma->vm_end)
+ goto out_up;
+ ret = 0;
+ }
+
+out_up:
+ up_read(&mm->mmap_sem);
+out:
+ return ret;
+}
+
+static long msm_ion_custom_ioctl(struct ion_client *client,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ switch (cmd) {
+ case ION_IOC_CLEAN_CACHES:
+ case ION_IOC_INV_CACHES:
+ case ION_IOC_CLEAN_INV_CACHES:
+ {
+ struct ion_flush_data data;
+ unsigned long start, end;
+ struct ion_handle *handle = NULL;
+ int ret;
+
+ if (copy_from_user(&data, (void __user *)arg,
+ sizeof(struct ion_flush_data)))
+ return -EFAULT;
+
+ start = (unsigned long) data.vaddr;
+ end = (unsigned long) data.vaddr + data.length;
+
+ if (check_vaddr_bounds(start, end)) {
+ pr_err("%s: virtual address %p is out of bounds\n",
+ __func__, data.vaddr);
+ return -EINVAL;
+ }
+
+ if (!data.handle) {
+ handle = ion_import_dma_buf(client, data.fd);
+ if (IS_ERR(handle)) {
+ pr_info("%s: Could not import handle: %d\n",
+ __func__, (int)handle);
+ return -EINVAL;
+ }
+ }
+
+ ret = ion_do_cache_op(client,
+ data.handle ? data.handle : handle,
+ data.vaddr, data.offset, data.length,
+ cmd);
+
+ if (!data.handle)
+ ion_free(client, handle);
+
+ if (ret < 0)
+ return ret;
+ break;
+
+ }
+ case ION_IOC_GET_FLAGS:
+ {
+ struct ion_flag_data data;
+ int ret;
+ if (copy_from_user(&data, (void __user *)arg,
+ sizeof(struct ion_flag_data)))
+ return -EFAULT;
+
+ ret = ion_handle_get_flags(client, data.handle, &data.flags);
+ if (ret < 0)
+ return ret;
+ if (copy_to_user((void __user *)arg, &data,
+ sizeof(struct ion_flag_data)))
+ return -EFAULT;
+ break;
+ }
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
static int msm_ion_probe(struct platform_device *pdev)
{
struct ion_platform_data *pdata;
@@ -583,7 +684,7 @@
goto out;
}
- idev = ion_device_create(NULL);
+ idev = ion_device_create(msm_ion_custom_ioctl);
if (IS_ERR_OR_NULL(idev)) {
err = PTR_ERR(idev);
goto freeheaps;
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 7317702..cf7f3ce 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -336,13 +336,6 @@
device->mmu.setstate_memory.gpuaddr +
KGSL_IOMMU_SETSTATE_NOP_OFFSET);
}
- /* invalidate all base pointers */
- *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
- *cmds++ = 0x7fff;
-
- cmds += __adreno_add_idle_indirect_cmds(cmds,
- device->mmu.setstate_memory.gpuaddr +
- KGSL_IOMMU_SETSTATE_NOP_OFFSET);
}
if (flags & KGSL_MMUFLAGS_TLBFLUSH) {
/*
@@ -386,6 +379,10 @@
sizedwords += (cmds - &link[0]);
if (sizedwords) {
+ /* invalidate all base pointers */
+ *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
+ *cmds++ = 0x7fff;
+ sizedwords += 2;
/*
* add an interrupt at the end of commands so that the smmu
* disable clock off function will get called
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index ea2cdc4..1f32e54 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1507,7 +1507,7 @@
{
struct kgsl_device *device = &adreno_dev->dev;
- if (context == NULL || (context->flags & CTXT_FLAGS_BEING_DESTOYED))
+ if (context == NULL || (context->flags & CTXT_FLAGS_BEING_DESTROYED))
return;
if (context->flags & CTXT_FLAGS_GPU_HANG)
@@ -1983,10 +1983,10 @@
0x18000000);
}
- if (adreno_is_a203(adreno_dev))
- /* For A203 increase number of clocks that RBBM
- * will wait before de-asserting Register Clock
- * Active signal */
+ if (adreno_is_a20x(adreno_dev))
+ /* For A20X based targets increase number of clocks
+ * that RBBM will wait before de-asserting Register
+ * Clock Active signal */
adreno_regwrite(device, REG_RBBM_CNTL, 0x0000FFFF);
else
adreno_regwrite(device, REG_RBBM_CNTL, 0x00004442);
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 8611b6b..d89e882 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2355,7 +2355,7 @@
{
struct kgsl_device *device = &adreno_dev->dev;
- if (context == NULL || (context->flags & CTXT_FLAGS_BEING_DESTOYED))
+ if (context == NULL || (context->flags & CTXT_FLAGS_BEING_DESTROYED))
return;
if (context->flags & CTXT_FLAGS_GPU_HANG)
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index a50747d..b51342f 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -221,17 +221,13 @@
CTXT_FLAGS_GMEM_SHADOW |
CTXT_FLAGS_STATE_SHADOW);
- drawctxt->flags |= CTXT_FLAGS_BEING_DESTOYED;
+ drawctxt->flags |= CTXT_FLAGS_BEING_DESTROYED;
adreno_drawctxt_switch(adreno_dev, NULL, 0);
}
adreno_idle(device);
- if (adreno_is_a20x(adreno_dev) && adreno_dev->drawctxt_active)
- kgsl_setstate(&device->mmu, adreno_dev->drawctxt_active->id,
- KGSL_MMUFLAGS_PTUPDATE);
-
kgsl_sharedmem_free(&drawctxt->gpustate);
kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow);
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index d58f2da..034d6e9 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -19,35 +19,35 @@
/* Flags */
#define CTXT_FLAGS_NOT_IN_USE 0x00000000
-#define CTXT_FLAGS_IN_USE 0x00000001
+#define CTXT_FLAGS_IN_USE BIT(0)
/* state shadow memory allocated */
-#define CTXT_FLAGS_STATE_SHADOW 0x00000010
+#define CTXT_FLAGS_STATE_SHADOW BIT(1)
/* gmem shadow memory allocated */
-#define CTXT_FLAGS_GMEM_SHADOW 0x00000100
+#define CTXT_FLAGS_GMEM_SHADOW BIT(2)
/* gmem must be copied to shadow */
-#define CTXT_FLAGS_GMEM_SAVE 0x00000200
+#define CTXT_FLAGS_GMEM_SAVE BIT(3)
/* gmem can be restored from shadow */
-#define CTXT_FLAGS_GMEM_RESTORE 0x00000400
+#define CTXT_FLAGS_GMEM_RESTORE BIT(4)
/* preamble packed in cmdbuffer for context switching */
-#define CTXT_FLAGS_PREAMBLE 0x00000800
+#define CTXT_FLAGS_PREAMBLE BIT(5)
/* shader must be copied to shadow */
-#define CTXT_FLAGS_SHADER_SAVE 0x00002000
+#define CTXT_FLAGS_SHADER_SAVE BIT(6)
/* shader can be restored from shadow */
-#define CTXT_FLAGS_SHADER_RESTORE 0x00004000
+#define CTXT_FLAGS_SHADER_RESTORE BIT(7)
/* Context has caused a GPU hang */
-#define CTXT_FLAGS_GPU_HANG 0x00008000
+#define CTXT_FLAGS_GPU_HANG BIT(8)
/* Specifies there is no need to save GMEM */
-#define CTXT_FLAGS_NOGMEMALLOC 0x00010000
+#define CTXT_FLAGS_NOGMEMALLOC BIT(9)
/* Trash state for context */
-#define CTXT_FLAGS_TRASHSTATE 0x00020000
+#define CTXT_FLAGS_TRASHSTATE BIT(10)
/* per context timestamps enabled */
-#define CTXT_FLAGS_PER_CONTEXT_TS 0x00040000
+#define CTXT_FLAGS_PER_CONTEXT_TS BIT(11)
/* Context has caused a GPU hang and recovered properly */
-#define CTXT_FLAGS_GPU_HANG_RECOVERED 0x00008000
+#define CTXT_FLAGS_GPU_HANG_RECOVERED BIT(12)
/* Context is being destroyed so dont save it */
-#define CTXT_FLAGS_BEING_DESTOYED 0x00010000
+#define CTXT_FLAGS_BEING_DESTROYED BIT(13)
struct kgsl_device;
struct adreno_device;
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 7241201..f630f2a 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1380,104 +1380,6 @@
return vma;
}
-static long
-kgsl_ioctl_sharedmem_from_vmalloc(struct kgsl_device_private *dev_priv,
- unsigned int cmd, void *data)
-{
- int result = 0, len = 0;
- struct kgsl_process_private *private = dev_priv->process_priv;
- struct kgsl_sharedmem_from_vmalloc *param = data;
- struct kgsl_mem_entry *entry = NULL;
- struct vm_area_struct *vma;
-
- KGSL_DEV_ERR_ONCE(dev_priv->device, "IOCTL_KGSL_SHAREDMEM_FROM_VMALLOC"
- " is deprecated\n");
- if (!kgsl_mmu_enabled())
- return -ENODEV;
-
- if (!param->hostptr) {
- KGSL_CORE_ERR("invalid hostptr %x\n", param->hostptr);
- result = -EINVAL;
- goto error;
- }
-
- vma = kgsl_get_vma_from_start_addr(param->hostptr);
- if (!vma) {
- result = -EINVAL;
- goto error;
- }
-
- /*
- * If the user specified a length, use it, otherwise try to
- * infer the length if the vma region
- */
- if (param->gpuaddr != 0) {
- len = param->gpuaddr;
- } else {
- /*
- * For this to work, we have to assume the VMA region is only
- * for this single allocation. If it isn't, then bail out
- */
- if (vma->vm_pgoff || (param->hostptr != vma->vm_start)) {
- KGSL_CORE_ERR("VMA region does not match hostaddr\n");
- result = -EINVAL;
- goto error;
- }
-
- len = vma->vm_end - vma->vm_start;
- }
-
- /* Make sure it fits */
- if (len == 0 || param->hostptr + len > vma->vm_end) {
- KGSL_CORE_ERR("Invalid memory allocation length %d\n", len);
- result = -EINVAL;
- goto error;
- }
-
- entry = kgsl_mem_entry_create();
- if (entry == NULL) {
- result = -ENOMEM;
- goto error;
- }
-
- result = kgsl_sharedmem_page_alloc_user(&entry->memdesc,
- private->pagetable, len,
- param->flags);
- if (result != 0)
- goto error_free_entry;
-
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-
- result = kgsl_sharedmem_map_vma(vma, &entry->memdesc);
- if (result) {
- KGSL_CORE_ERR("kgsl_sharedmem_map_vma failed: %d\n", result);
- goto error_free_alloc;
- }
-
- param->gpuaddr = entry->memdesc.gpuaddr;
-
- entry->memtype = KGSL_MEM_ENTRY_KERNEL;
-
- kgsl_mem_entry_attach_process(entry, private);
-
- trace_kgsl_mem_alloc(entry);
- /* Process specific statistics */
- kgsl_process_add_stats(private, entry->memtype, len);
-
- kgsl_check_idle(dev_priv->device);
- return 0;
-
-error_free_alloc:
- kgsl_sharedmem_free(&entry->memdesc);
-
-error_free_entry:
- kfree(entry);
-
-error:
- kgsl_check_idle(dev_priv->device);
- return result;
-}
-
static inline int _check_region(unsigned long start, unsigned long size,
uint64_t len)
{
@@ -2161,8 +2063,6 @@
kgsl_ioctl_map_user_mem, 0),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FREE,
kgsl_ioctl_sharedmem_free, 0),
- KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FROM_VMALLOC,
- kgsl_ioctl_sharedmem_from_vmalloc, 0),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FLUSH_CACHE,
kgsl_ioctl_sharedmem_flush_cache, 0),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_ALLOC,
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index f908181..a384103 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -299,6 +299,80 @@
{419, 128000}
};
+static const struct qpnp_vadc_map_pt adcmap_100k_104ef_104fb[] = {
+ {-40, 1758},
+ {-35, 1742},
+ {-30, 1719},
+ {-25, 1691},
+ {-20, 1654},
+ {-15, 1608},
+ {-10, 1551},
+ {-5, 1483},
+ {0, 1404},
+ {5, 1315},
+ {10, 1218},
+ {15, 1114},
+ {20, 1007},
+ {25, 900},
+ {30, 795},
+ {35, 696},
+ {40, 605},
+ {45, 522},
+ {50, 448},
+ {55, 383},
+ {60, 327},
+ {65, 278},
+ {70, 237},
+ {75, 202},
+ {80, 172},
+ {85, 146},
+ {90, 125},
+ {95, 107},
+ {100, 92},
+ {105, 79},
+ {110, 68},
+ {115, 59},
+ {120, 51},
+ {125, 44}
+};
+
+static const struct qpnp_vadc_map_pt adcmap_150k_104ef_104fb[] = {
+ {-40, 1738},
+ {-35, 1714},
+ {-30, 1682},
+ {-25, 1641},
+ {-20, 1589},
+ {-15, 1526},
+ {-10, 1451},
+ {-5, 1363},
+ {0, 1266},
+ {5, 1159},
+ {10, 1048},
+ {15, 936},
+ {20, 825},
+ {25, 720},
+ {30, 622},
+ {35, 533},
+ {40, 454},
+ {45, 385},
+ {50, 326},
+ {55, 275},
+ {60, 232},
+ {65, 195},
+ {70, 165},
+ {75, 139},
+ {80, 118},
+ {85, 100},
+ {90, 85},
+ {95, 73},
+ {100, 62},
+ {105, 53},
+ {110, 46},
+ {115, 40},
+ {120, 34},
+ {125, 30}
+};
+
static int32_t qpnp_adc_map_linear(const struct qpnp_vadc_map_pt *pts,
uint32_t tablesize, int32_t input, int64_t *output)
{
@@ -504,6 +578,42 @@
}
EXPORT_SYMBOL_GPL(qpnp_adc_scale_batt_therm);
+int32_t qpnp_adc_scale_therm_pu1(int32_t adc_code,
+ const struct qpnp_adc_properties *adc_properties,
+ const struct qpnp_vadc_chan_properties *chan_properties,
+ struct qpnp_vadc_result *adc_chan_result)
+{
+ int64_t therm_voltage = 0;
+
+ therm_voltage = qpnp_adc_scale_ratiometric_calib(adc_code,
+ adc_properties, chan_properties);
+
+ qpnp_adc_map_linear(adcmap_150k_104ef_104fb,
+ ARRAY_SIZE(adcmap_150k_104ef_104fb),
+ therm_voltage, &adc_chan_result->physical);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qpnp_adc_scale_therm_pu1);
+
+int32_t qpnp_adc_scale_therm_pu2(int32_t adc_code,
+ const struct qpnp_adc_properties *adc_properties,
+ const struct qpnp_vadc_chan_properties *chan_properties,
+ struct qpnp_vadc_result *adc_chan_result)
+{
+ int64_t therm_voltage = 0;
+
+ therm_voltage = qpnp_adc_scale_ratiometric_calib(adc_code,
+ adc_properties, chan_properties);
+
+ qpnp_adc_map_linear(adcmap_100k_104ef_104fb,
+ ARRAY_SIZE(adcmap_100k_104ef_104fb),
+ therm_voltage, &adc_chan_result->physical);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qpnp_adc_scale_therm_pu2);
+
int32_t qpnp_adc_scale_batt_id(int32_t adc_code,
const struct qpnp_adc_properties *adc_properties,
const struct qpnp_vadc_chan_properties *chan_properties,
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index a0e7ab9..5690c88 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.c
@@ -119,6 +119,8 @@
[SCALE_BATT_THERM] = {qpnp_adc_scale_batt_therm},
[SCALE_PMIC_THERM] = {qpnp_adc_scale_pmic_therm},
[SCALE_XOTHERM] = {qpnp_adc_tdkntcg_therm},
+ [SCALE_THERM_100K_PULLUP] = {qpnp_adc_scale_therm_pu2},
+ [SCALE_THERM_150K_PULLUP] = {qpnp_adc_scale_therm_pu1},
};
static int32_t qpnp_vadc_read_reg(int16_t reg, u8 *data)
diff --git a/drivers/input/touchscreen/cyttsp-i2c-qc.c b/drivers/input/touchscreen/cyttsp-i2c-qc.c
index a3a12c6..e54a24a 100644
--- a/drivers/input/touchscreen/cyttsp-i2c-qc.c
+++ b/drivers/input/touchscreen/cyttsp-i2c-qc.c
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/input.h>
+#include <linux/input/mt.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/irq.h>
@@ -1698,22 +1699,9 @@
cyttsp_debug("ST->F1:%3d X:%3d Y:%3d Z:%3d\n", \
cur_st_tch[CY_ST_FNGR1_IDX], \
st_x1, st_y1, st_z1);
- if (cur_st_tch[CY_ST_FNGR2_IDX] < CY_NUM_TRK_ID) {
- input_report_key(ts->input, BTN_2, CY_TCH);
- input_report_abs(ts->input, ABS_HAT0X, st_x2);
- input_report_abs(ts->input, ABS_HAT0Y, st_y2);
- cyttsp_debug("ST->F2:%3d X:%3d Y:%3d Z:%3d\n", \
- cur_st_tch[CY_ST_FNGR2_IDX],
- st_x2, st_y2, st_z2);
- } else {
- input_report_key(ts->input,
- BTN_2,
- CY_NTCH);
- }
} else {
input_report_abs(ts->input, ABS_PRESSURE, CY_NTCH);
input_report_key(ts->input, BTN_TOUCH, CY_NTCH);
- input_report_key(ts->input, BTN_2, CY_NTCH);
}
/* update platform data for the current single touch info */
ts->prv_st_tch[CY_ST_FNGR1_IDX] = cur_st_tch[CY_ST_FNGR1_IDX];
@@ -1857,6 +1845,9 @@
id, tmp_trk[id], \
id, snd_trk[id]);
if (snd_trk[id] < CY_NUM_TRK_ID) {
+ input_mt_slot(ts->input, snd_trk[id]);
+ input_mt_report_slot_state(ts->input,
+ MT_TOOL_FINGER, true);
input_report_abs(ts->input,
ABS_MT_TOUCH_MAJOR,
cur_mt_z[snd_trk[id]]);
@@ -1869,7 +1860,6 @@
input_report_abs(ts->input,
ABS_MT_POSITION_Y,
cur_mt_pos[snd_trk[id]][CY_YPOS]);
- CY_MT_SYNC(ts->input);
cyttsp_debug("MT1->TID:%2d X:%3d Y:%3d Z:%3d touch-sent\n", \
snd_trk[id], \
cur_mt_pos[snd_trk[id]][CY_XPOS], \
@@ -1877,19 +1867,10 @@
cur_mt_z[snd_trk[id]]);
} else if (ts->prv_mt_tch[id] < CY_NUM_TRK_ID) {
/* void out this touch */
- input_report_abs(ts->input,
- ABS_MT_TOUCH_MAJOR,
- CY_NTCH);
- input_report_abs(ts->input,
- ABS_MT_WIDTH_MAJOR,
- curr_tool_width);
- input_report_abs(ts->input,
- ABS_MT_POSITION_X,
- ts->prv_mt_pos[ts->prv_mt_tch[id]][CY_XPOS]);
- input_report_abs(ts->input,
- ABS_MT_POSITION_Y,
- ts->prv_mt_pos[ts->prv_mt_tch[id]][CY_YPOS]);
- CY_MT_SYNC(ts->input);
+ input_mt_slot(ts->input,
+ ts->prv_mt_tch[id]);
+ input_mt_report_slot_state(ts->input,
+ MT_TOOL_FINGER, false);
cyttsp_debug("MT2->TID:%2d X:%3d Y:%3d Z:%3d lift off-sent\n", \
ts->prv_mt_tch[id], \
ts->prv_mt_pos[ts->prv_mt_tch[id]][CY_XPOS], \
@@ -2679,7 +2660,6 @@
set_bit(EV_KEY, input_device->evbit);
set_bit(EV_ABS, input_device->evbit);
set_bit(BTN_TOUCH, input_device->keybit);
- set_bit(BTN_2, input_device->keybit);
set_bit(INPUT_PROP_DIRECT, input_device->propbit);
if (ts->platform_data->use_gestures)
@@ -2693,10 +2673,6 @@
ABS_TOOL_WIDTH, 0, CY_LARGE_TOOL_WIDTH, 0 , 0);
input_set_abs_params(input_device,
ABS_PRESSURE, 0, CY_MAXZ, 0, 0);
- input_set_abs_params(input_device,
- ABS_HAT0X, 0, ts->platform_data->panel_maxx, 0, 0);
- input_set_abs_params(input_device,
- ABS_HAT0Y, 0, ts->platform_data->panel_maxy, 0, 0);
if (ts->platform_data->use_gestures) {
input_set_abs_params(input_device,
ABS_HAT1X, 0, CY_MAXZ, 0, 0);
@@ -2714,6 +2690,7 @@
ABS_MT_TOUCH_MAJOR, 0, CY_MAXZ, 0, 0);
input_set_abs_params(input_device,
ABS_MT_WIDTH_MAJOR, 0, CY_LARGE_TOOL_WIDTH, 0, 0);
+ input_mt_init_slots(input_device, CY_NUM_TRK_ID);
if (ts->platform_data->use_trk_id) {
input_set_abs_params(input_device,
ABS_MT_TRACKING_ID, 0, CY_NUM_TRK_ID, 0, 0);
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video.c b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
index 68653ba..3dc31bb 100644
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video.c
+++ b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
@@ -55,6 +55,8 @@
static int mpq_int_vid_dec_decode_frame(struct video_client_ctx *client_ctx,
struct video_data_buffer *input_frame);
+static int mpq_int_vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
+ struct video_buffer_req *vdec_buf_req);
static struct mpq_dvb_video_dev *mpq_dvb_video_device;
@@ -819,11 +821,32 @@
return 0;
}
+static int mpq_int_set_out_buffer_req(struct video_client_ctx *client_ctx,
+ struct video_buffer_req *vdec_buf_req)
+{
+ struct vcd_buffer_requirement buffer_req;
+ u32 vcd_status = VCD_ERR_FAIL;
+
+ buffer_req.actual_count = vdec_buf_req->num_output_buffers;
+ buffer_req.align = vdec_buf_req->output_buf_prop.alignment;
+ buffer_req.max_count = vdec_buf_req->num_output_buffers;
+ buffer_req.min_count = vdec_buf_req->num_output_buffers;
+ buffer_req.sz = vdec_buf_req->output_buf_prop.buf_size;
+
+ vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
+ VCD_BUFFER_OUTPUT, &buffer_req);
+ if (vcd_status)
+ return -EFAULT;
+ else
+ return 0;
+}
+
static int mpq_int_set_full_hd_frame_resolution(
struct video_client_ctx *client_ctx)
{
struct vdec_picsize pic_res;
int rc;
+ struct video_buffer_req vdec_buf_req;
pic_res.frame_height = 1080;
pic_res.frame_width = 1920;
@@ -841,6 +864,15 @@
DBG("Failed in mpq_int_vid_dec_set_cont_on_reconfig : %d\n",\
rc);
+ rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &vdec_buf_req);
+ if (rc)
+ DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
+
+ vdec_buf_req.num_output_buffers = 15;
+ rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_buf_req);
+ if (rc)
+ DBG("Failed in mpq_int_set_out_buffer_req (15) : %d\n", rc);
+
return rc;
}
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index d596782..ac143b1 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -3479,12 +3479,20 @@
struct v4l2_buffer *buffer)
{
struct iris_device *radio = video_get_drvdata(video_devdata(file));
- enum iris_buf_t buf_type = buffer->index;
- struct kfifo *data_fifo;
- unsigned char *buf = (unsigned char *)buffer->m.userptr;
- unsigned int len = buffer->length;
- if (!access_ok(VERIFY_WRITE, buf, len))
- return -EFAULT;
+ enum iris_buf_t buf_type = -1;
+ unsigned char buf_fifo[STD_BUF_SIZE] = {0};
+ struct kfifo *data_fifo = NULL;
+ unsigned char *buf = NULL;
+ unsigned int len = 0, retval = -1;
+
+ if ((radio == NULL) || (buffer == NULL)) {
+ FMDERR("radio/buffer is NULL\n");
+ return -ENXIO;
+ }
+ buf_type = buffer->index;
+ buf = (unsigned char *)buffer->m.userptr;
+ len = buffer->length;
+
if ((buf_type < IRIS_BUF_MAX) && (buf_type >= 0)) {
data_fifo = &radio->data_buf[buf_type];
if (buf_type == IRIS_BUF_EVENTS)
@@ -3495,10 +3503,20 @@
FMDERR("invalid buffer type\n");
return -EINVAL;
}
- buffer->bytesused = kfifo_out_locked(data_fifo, buf, len,
- &radio->buf_lock[buf_type]);
+ if (len <= STD_BUF_SIZE) {
+ buffer->bytesused = kfifo_out_locked(data_fifo, &buf_fifo[0],
+ len, &radio->buf_lock[buf_type]);
+ } else {
+ FMDERR("kfifo_out_locked can not use len more than 128\n");
+ return -EINVAL;
+ }
+ retval = copy_to_user(buf, &buf_fifo[0], buffer->bytesused);
+ if (retval > 0) {
+ FMDERR("Failed to copy %d bytes of data\n", retval);
+ return -EAGAIN;
+ }
- return 0;
+ return retval;
}
static int iris_vidioc_g_fmt_type_private(struct file *file, void *priv,
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw.h b/drivers/media/video/msm/gemini/msm_gemini_hw.h
index 233f082..248ba06 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_hw.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_hw.h
@@ -15,7 +15,7 @@
#include <media/msm_gemini.h>
#include "msm_gemini_hw_reg.h"
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <mach/iommu_domains.h>
struct msm_gemini_hw_buf {
diff --git a/drivers/media/video/msm/gemini/msm_gemini_platform.h b/drivers/media/video/msm/gemini/msm_gemini_platform.h
index eb6b9f0..d7f81aa 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_platform.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_platform.h
@@ -15,7 +15,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <linux/iommu.h>
void msm_gemini_platform_p2v(struct file *file,
struct ion_handle **ionhandle);
diff --git a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
index 9549dcc..d508c1d 100644
--- a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
+++ b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
@@ -139,11 +139,11 @@
switch (perf_setting) {
case S_INIT:
add_axi_qos();
- break;
- case S_PREVIEW:
update_axi_qos(MSM_AXI_QOS_PREVIEW);
axi_allocate(AXI_FLOW_VIEWFINDER_HI);
break;
+ case S_PREVIEW:
+ break;
case S_VIDEO:
update_axi_qos(MSM_AXI_QOS_RECORDING);
break;
diff --git a/drivers/media/video/msm/mercury/msm_mercury_platform.h b/drivers/media/video/msm/mercury/msm_mercury_platform.h
index 8f4a7e3..9edbb30 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_platform.h
+++ b/drivers/media/video/msm/mercury/msm_mercury_platform.h
@@ -15,7 +15,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
int msm_mercury_platform_clk_enable(void);
int msm_mercury_platform_clk_disable(void);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 1e1b4ae..cb59d68 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -33,7 +33,7 @@
#include <mach/camera.h>
#include <mach/iommu.h>
#include <media/msm_isp.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <linux/iommu.h>
#include <media/msm_gestures.h>
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
index 2f1d1ab..dce3630 100644
--- a/drivers/media/video/msm/msm_camera.c
+++ b/drivers/media/video/msm/msm_camera.c
@@ -34,7 +34,7 @@
#include <mach/camera.h>
#include <linux/syscalls.h>
#include <linux/hrtimer.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <mach/cpuidle.h>
DEFINE_MUTEX(ctrl_cmd_lock);
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 2613986..1e17c5c 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -555,6 +555,7 @@
case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC:
case CMD_AXI_START:
case CMD_AXI_STOP:
+ case CMD_AXI_RESET:
case CMD_AXI_CFG_TERT1:
case CMD_AXI_CFG_TERT2:
/* Dont need to pass buffer information.
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 03d666f..999783e 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -86,7 +86,10 @@
output_settings[s_ctrl->curr_res].vt_pixel_clk /
s_ctrl->curr_frame_length_lines /
s_ctrl->curr_line_length_pclk;
- delay = (1000 * s_ctrl->wait_num_frames) / fps / Q10;
+ if (fps == 0)
+ delay = s_ctrl->min_delay;
+ else
+ delay = (1000 * s_ctrl->wait_num_frames) / fps / Q10;
}
CDBG("%s fps = %ld, delay = %d, min_delay %d\n", __func__, fps,
delay, s_ctrl->min_delay);
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index eb6a8b0..f6cf427 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -23,6 +23,8 @@
static struct msm_camera_i2c_reg_conf ov5647_start_settings[] = {
{0x4202, 0x00}, /* streaming on */
+ {0x0100, 0x01},
+ {0x4800, 0x04},
};
static struct msm_camera_i2c_reg_conf ov5647_stop_settings[] = {
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 8c9b602..b78e20d 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -342,6 +342,7 @@
uint32_t id, struct msm_ctrl_cmd *out)
{
int rc = 0;
+ uint8_t wait_count;
void *value;
struct msm_queue_cmd *rcmd;
struct msm_queue_cmd *event_qcmd;
@@ -409,9 +410,20 @@
/* 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));
+ /* wait event may be interrupted by sugnal,
+ * in this case -ERESTARTSYS is returned and retry is needed.
+ * Now we only retry once. */
+ wait_count = 2;
+ do {
+ rc = wait_event_interruptible_timeout(queue->wait,
+ !list_empty_careful(&queue->list),
+ msecs_to_jiffies(out->timeout_ms));
+ wait_count--;
+ if (rc != -ERESTARTSYS)
+ break;
+ D("%s: wait_event interrupted by signal, remain_count = %d",
+ __func__, wait_count);
+ } while (wait_count > 0);
D("Waiting is over for config status\n");
if (list_empty_careful(&queue->list)) {
if (!rc)
@@ -1631,6 +1643,10 @@
rp = (struct msm_vfe_resp *)arg;
frame_info = rp->evt_msg.data;
+ if (!frame_info) {
+ interface = PIX_0;
+ break;
+ }
if (frame_info->inst_handle) {
vnode_id = GET_DEVID_MODE(frame_info->inst_handle);
if (vnode_id < MAX_NUM_ACTIVE_CAMERA &&
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
index 15c38af..9deae65 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
@@ -1561,6 +1561,11 @@
}
return 0;
+ case CMD_AXI_START:
+ case CMD_AXI_STOP:
+ case CMD_AXI_RESET:
+ return 0;
+
case CMD_CONFIG_FREE_BUF_ADDR: {
int path = *((int *)cmd->value);
struct buf_info *outch = vfe2x_get_ch(path);
@@ -1853,9 +1858,6 @@
flags);
if (op_mode & SNAPSHOT_MASK_MODE) {
vfe2x_ctrl->stop_pending = 0;
- vfe2x_send_isp_msg(vfe2x_ctrl,
- msgs_map[MSG_STOP_ACK].
- isp_id);
spin_unlock_irqrestore(
&vfe2x_ctrl->table_lock,
flags);
diff --git a/drivers/media/video/msm_vidc/msm_smem.h b/drivers/media/video/msm_vidc/msm_smem.h
index 37816e1..c109abd 100644
--- a/drivers/media/video/msm_vidc/msm_smem.h
+++ b/drivers/media/video/msm_vidc/msm_smem.h
@@ -14,7 +14,7 @@
#define _MSM_SMEM_H_
#include <linux/types.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
enum smem_type {
SMEM_ION,
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index dd2a207..a4c4b83 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -31,7 +31,6 @@
#include "msm_smem.h"
#define BASE_DEVICE_NUMBER 32
-#define MAX_EVENTS 30
#define SHARED_QSIZE 0x1000000
static struct msm_bus_vectors enc_ocmem_init_vectors[] = {
@@ -47,7 +46,7 @@
{
.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
.dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 414700000,
+ .ab = 138200000,
.ib = 1222000000,
},
};
@@ -56,7 +55,7 @@
{
.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
.dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 940000000,
+ .ab = 414700000,
.ib = 1222000000,
},
};
@@ -65,7 +64,7 @@
{
.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
.dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 1880000000,
+ .ab = 940000000,
.ib = 2444000000U,
},
};
@@ -111,7 +110,7 @@
{
.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
.dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 456200000,
+ .ab = 176900000,
.ib = 1556640000,
},
};
@@ -120,7 +119,7 @@
{
.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
.dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 864800000,
+ .ab = 456200000,
.ib = 1556640000,
},
};
@@ -129,8 +128,8 @@
{
.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
.dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 1729600000,
- .ib = 3113280000U,
+ .ab = 864800000,
+ .ib = 1556640000,
},
};
@@ -451,7 +450,7 @@
};
struct msm_v4l2_vid_inst {
- struct msm_vidc_inst vidc_inst;
+ struct msm_vidc_inst *vidc_inst;
void *mem_client;
struct list_head registered_bufs;
};
@@ -468,22 +467,7 @@
struct msm_vidc_inst *vidc_inst;
vidc_inst = container_of(filp->private_data,
struct msm_vidc_inst, event_handler);
- return container_of((void *)vidc_inst,
- struct msm_v4l2_vid_inst, vidc_inst);
-}
-
-static int msm_vidc_v4l2_setup_event_queue(void *inst,
- struct video_device *pvdev)
-{
- int rc = 0;
- struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
- spin_lock_init(&pvdev->fh_lock);
- INIT_LIST_HEAD(&pvdev->fh_list);
-
- v4l2_fh_init(&vidc_inst->event_handler, pvdev);
- v4l2_fh_add(&vidc_inst->event_handler);
-
- return rc;
+ return (struct msm_v4l2_vid_inst *)vidc_inst->priv;
}
struct buffer_info *get_registered_buf(struct list_head *list,
@@ -556,7 +540,8 @@
rc = -ENOMEM;
goto fail_mem_client;
}
- rc = msm_vidc_open(&v4l2_inst->vidc_inst, core->id, vid_dev->type);
+
+ v4l2_inst->vidc_inst = msm_vidc_open(core->id, vid_dev->type);
if (rc) {
dprintk(VIDC_ERR,
"Failed to create video instance, core: %d, type = %d\n",
@@ -565,9 +550,9 @@
goto fail_open;
}
INIT_LIST_HEAD(&v4l2_inst->registered_bufs);
- rc = msm_vidc_v4l2_setup_event_queue(&v4l2_inst->vidc_inst, vdev);
+ v4l2_inst->vidc_inst->priv = v4l2_inst;
clear_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags);
- filp->private_data = &(v4l2_inst->vidc_inst.event_handler);
+ filp->private_data = &(v4l2_inst->vidc_inst->event_handler);
return rc;
fail_open:
msm_smem_delete_client(v4l2_inst->mem_client);
@@ -667,7 +652,7 @@
buffer_info.m.planes[0].reserved[0],
buffer_info.m.planes[0].reserved[1],
buffer_info.m.planes[0].length);
- rc = msm_vidc_release_buf(&v4l2_inst->vidc_inst,
+ rc = msm_vidc_release_buf(v4l2_inst->vidc_inst,
&buffer_info);
list_del(&bi->list);
if (bi->handle)
@@ -752,7 +737,7 @@
list_add_tail(&binfo->list, &v4l2_inst->registered_bufs);
b->m.planes[i].m.userptr = binfo->device_addr;
}
- rc = msm_vidc_prepare_buf(&v4l2_inst->vidc_inst, b);
+ rc = msm_vidc_prepare_buf(v4l2_inst->vidc_inst, b);
exit:
return rc;
}
@@ -794,7 +779,7 @@
}
}
}
- rc = msm_vidc_qbuf(&v4l2_inst->vidc_inst, b);
+ rc = msm_vidc_qbuf(v4l2_inst->vidc_inst, b);
err_invalid_buff:
return rc;
}
@@ -823,17 +808,17 @@
static int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
- int rc = 0;
- rc = v4l2_event_subscribe(fh, sub, MAX_EVENTS);
- return rc;
+ struct msm_vidc_inst *vidc_inst = container_of(fh,
+ struct msm_vidc_inst, event_handler);
+ return msm_vidc_subscribe_event((void *)vidc_inst, sub);
}
static int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
- int rc = 0;
- rc = v4l2_event_unsubscribe(fh, sub);
- return rc;
+ struct msm_vidc_inst *vidc_inst = container_of(fh,
+ struct msm_vidc_inst, event_handler);
+ return msm_vidc_unsubscribe_event((void *)vidc_inst, sub);
}
static int msm_v4l2_decoder_cmd(struct file *file, void *fh,
@@ -936,7 +921,7 @@
struct msm_iova_layout layout;
int rc = 0;
int i;
- struct iommu_info *io_map = core->resources.io_map;
+ struct msm_vidc_iommu_info *io_map = core->resources.io_map;
strlcpy(io_map[CP_MAP].name, "vidc-cp-map",
sizeof(io_map[CP_MAP].name));
strlcpy(io_map[CP_MAP].ctx, "venus_cp",
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 8240890..be2e848 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -229,6 +229,14 @@
.type = OUTPUT_PORT,
},
{
+ .name = "VC1 SP",
+ .description = "VC-1 compressed format G",
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+ .num_planes = 1,
+ .get_frame_size = get_frame_size_compressed,
+ .type = OUTPUT_PORT,
+ },
+ {
.name = "H264",
.description = "H264 compressed format",
.fourcc = V4L2_PIX_FMT_H264,
@@ -524,6 +532,8 @@
goto err_invalid_fmt;
}
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ inst->prop.width = f->fmt.pix_mp.width;
+ inst->prop.height = f->fmt.pix_mp.height;
fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
OUTPUT_PORT);
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index 449dab2..c7269d3 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -21,6 +21,8 @@
#include "msm_smem.h"
#include <linux/delay.h>
+#define MAX_EVENTS 30
+
int msm_vidc_poll(void *instance, struct file *filp,
struct poll_table_struct *wait)
{
@@ -55,9 +57,28 @@
return rc;
}
+int msm_vidc_get_iommu_maps(void *instance,
+ struct msm_vidc_iommu_info maps[MAX_MAP])
+{
+ struct msm_vidc_inst *inst = instance;
+ int c = 0;
+
+ if (!inst || !maps)
+ return -EINVAL;
+
+ for (c = 0; c < MAX_MAP; ++c)
+ maps[c] = inst->core->resources.io_map[c];
+
+ return 0;
+}
+
int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !cap)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_querycap(instance, cap);
else if (inst->session_type == MSM_VIDC_ENCODER)
@@ -67,6 +88,10 @@
int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !f)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_enum_fmt(instance, f);
else if (inst->session_type == MSM_VIDC_ENCODER)
@@ -76,6 +101,10 @@
int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !f)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_s_fmt(instance, f);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -85,6 +114,10 @@
int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !f)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_g_fmt(instance, f);
else if (inst->session_type == MSM_VIDC_ENCODER)
@@ -94,6 +127,10 @@
int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !control)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_s_ctrl(instance, control);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -103,6 +140,10 @@
int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !control)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_g_ctrl(instance, control);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -112,6 +153,10 @@
int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_reqbufs(instance, b);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -122,6 +167,10 @@
int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_prepare_buf(instance, b);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -132,6 +181,10 @@
int msm_vidc_release_buf(void *instance, struct v4l2_buffer *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_release_buf(instance, b);
return -EINVAL;
@@ -156,6 +209,10 @@
int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_qbuf(instance, b);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -166,6 +223,10 @@
int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_dqbuf(instance, b);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -176,6 +237,10 @@
int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_streamon(instance, i);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -186,6 +251,10 @@
int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_streamoff(instance, i);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -193,13 +262,13 @@
return -EINVAL;
}
-void *vidc_get_userptr(void *alloc_ctx, unsigned long vaddr,
+static void *vidc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
{
return (void *)0xdeadbeef;
}
-void vidc_put_userptr(void *buf_priv)
+static void vidc_put_userptr(void *buf_priv)
{
}
@@ -232,9 +301,60 @@
return vb2_queue_init(q);
}
-int msm_vidc_open(void *vidc_inst, int core_id, int session_type)
+static int setup_event_queue(void *inst,
+ struct video_device *pvdev)
{
- struct msm_vidc_inst *inst = (struct msm_vidc_inst *)vidc_inst;
+ int rc = 0;
+ struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+ spin_lock_init(&pvdev->fh_lock);
+ INIT_LIST_HEAD(&pvdev->fh_list);
+
+ v4l2_fh_init(&vidc_inst->event_handler, pvdev);
+ v4l2_fh_add(&vidc_inst->event_handler);
+
+ return rc;
+}
+
+int msm_vidc_subscribe_event(void *inst, struct v4l2_event_subscription *sub)
+{
+ int rc = 0;
+ struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+ if (!inst || !sub)
+ return -EINVAL;
+
+ rc = v4l2_event_subscribe(&vidc_inst->event_handler, sub, MAX_EVENTS);
+ return rc;
+}
+
+
+int msm_vidc_unsubscribe_event(void *inst, struct v4l2_event_subscription *sub)
+{
+ int rc = 0;
+ struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+ if (!inst || !sub)
+ return -EINVAL;
+
+ rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub);
+ return rc;
+}
+
+int msm_vidc_dqevent(void *inst, struct v4l2_event *event)
+{
+ int rc = 0;
+ struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+ if (!inst || !event)
+ return -EINVAL;
+
+ rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false);
+ return rc;
+}
+
+void *msm_vidc_open(int core_id, int session_type)
+{
+ struct msm_vidc_inst *inst = NULL;
struct msm_vidc_core *core = NULL;
unsigned long flags;
int rc = 0;
@@ -252,6 +372,13 @@
goto err_invalid_core;
}
+ inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+ if (!inst) {
+ pr_err("Failed to allocate memory\n") ;
+ rc = -ENOMEM;
+ goto err_invalid_core;
+ }
+
mutex_init(&inst->sync_lock);
spin_lock_init(&inst->lock);
inst->session_type = session_type;
@@ -276,6 +403,7 @@
msm_venc_inst_init(inst);
msm_venc_ctrl_init(inst);
}
+
rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
session_type);
if (rc) {
@@ -298,17 +426,20 @@
}
inst->debugfs_root =
msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
+
+ setup_event_queue(inst, &core->vdev[core_id].vdev);
+
spin_lock_irqsave(&core->lock, flags);
list_add_tail(&inst->list, &core->instances);
spin_unlock_irqrestore(&core->lock, flags);
- return rc;
+ return inst;
fail_init:
msm_smem_delete_client(inst->mem_client);
fail_mem_client:
kfree(inst);
inst = NULL;
err_invalid_core:
- return rc;
+ return inst;
}
static void cleanup_instance(struct msm_vidc_inst *inst)
@@ -360,6 +491,10 @@
struct msm_vidc_core *core;
struct list_head *ptr, *next;
int rc = 0;
+
+ if (!inst)
+ return -EINVAL;
+
core = inst->core;
mutex_lock(&core->sync_lock);
list_for_each_safe(ptr, next, &core->instances) {
@@ -373,6 +508,7 @@
dprintk(VIDC_ERR,
"Failed to move video instance to uninit state\n");
cleanup_instance(inst);
+ kfree(inst);
dprintk(VIDC_DBG, "Closed the instance\n");
return 0;
}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 5b83cfb..84552a4 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -166,7 +166,7 @@
int rc;
struct iommu_domain *domain;
int i;
- struct iommu_info *io_map;
+ struct msm_vidc_iommu_info *io_map;
struct device *dev;
for (i = 0; i < MAX_MAP; i++) {
io_map = &core->resources.io_map[i];
@@ -202,7 +202,7 @@
{
struct device *dev;
struct iommu_domain *domain;
- struct iommu_info *io_map;
+ struct msm_vidc_iommu_info *io_map;
int i;
if (!core) {
dprintk(VIDC_ERR, "Invalid paramter: %p\n", core);
@@ -737,7 +737,7 @@
dprintk(VIDC_ERR, "Invalid args: %p\n", core);
return -EINVAL;
}
- num_mbs_per_sec = 2 * msm_comm_get_load(core, MSM_VIDC_ENCODER);
+ num_mbs_per_sec = msm_comm_get_load(core, MSM_VIDC_ENCODER);
num_mbs_per_sec += msm_comm_get_load(core, MSM_VIDC_DECODER);
dprintk(VIDC_INFO, "num_mbs_per_sec = %d\n", num_mbs_per_sec);
rc = clk_set_rate(core->resources.clock[VCODEC_CLK].clk,
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 55aec74..3c14123 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -141,20 +141,6 @@
void *cookie;
};
-struct iommu_info {
- u32 addr_range[2];
- char name[MAX_NAME_LENGTH];
- char ctx[MAX_NAME_LENGTH];
- int domain;
- int partition;
-};
-
-enum io_maps {
- CP_MAP,
- NS_MAP,
- MAX_MAP
-};
-
enum vidc_clocks {
VCODEC_CLK,
VCODEC_AHB_CLK,
@@ -188,7 +174,7 @@
struct msm_vidc_resources {
struct msm_vidc_fw fw;
- struct iommu_info io_map[MAX_MAP];
+ struct msm_vidc_iommu_info io_map[MAX_MAP];
struct core_clock clock[VCODEC_MAX_CLKS];
struct vidc_bus_info bus_info;
struct on_chip_mem ocmem;
@@ -247,6 +233,7 @@
u32 ftb_count;
u32 fbd_count;
struct vb2_buffer *vb2_seq_hdr;
+ void *priv;
};
extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index 12ba874..0639dea 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -608,6 +608,9 @@
static void set_vbif_registers(struct hal_device *device)
{
+ /*Disable Dynamic clock gating for Venus VBIF*/
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VENUS_VBIF_CLK_ON, 1, 0);
write_register(device->hal_data->register_base_addr,
VIDC_VBIF_OUT_AXI_AOOO_EN, 0x00000FFF, 0);
write_register(device->hal_data->register_base_addr,
@@ -636,6 +639,8 @@
VIDC_VBIF_OUT_WR_LIM_CONF0, 0x00001010, 0);
write_register(device->hal_data->register_base_addr,
VIDC_VBIF_ARB_CTL, 0x00000030, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY, 0x5555556, 0);
}
int vidc_hal_core_init(void *device, int domain)
@@ -654,10 +659,6 @@
INIT_LIST_HEAD(&dev->sess_head);
spin_lock_init(&dev->read_lock);
spin_lock_init(&dev->write_lock);
-
- /*Disable Dynamic clock gating for Venus VBIF*/
- write_register(dev->hal_data->register_base_addr,
- VIDC_VENUS_VBIF_CLK_ON, 1, 0);
set_vbif_registers(dev);
if (!dev->hal_client) {
dev->hal_client = msm_smem_new_client(SMEM_ION);
diff --git a/drivers/media/video/msm_vidc/vidc_hal_io.h b/drivers/media/video/msm_vidc/vidc_hal_io.h
index c4b1e0c..b85e015 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_io.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_io.h
@@ -124,9 +124,9 @@
#define VIDC_VBIF_AT_NEW_BASE (VIDC_VBIF_BASE_OFFS + 0xC10)
#define VIDC_VBIF_AT_NEW_HIGH (VIDC_VBIF_BASE_OFFS + 0xC18)
-#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_REQ_PRIORITY \
+#define VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY \
(VIDC_WRAPPER_BASE_OFFS + 0x20)
-#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_PRIORITY_LEVEL \
+#define VIDC_VENUS0_WRAPPER_VBIF_PRIORITY_LEVEL \
(VIDC_WRAPPER_BASE_OFFS + 0x24)
#define VIDC_VENUS_VBIF_REQ_PRIORITY (VIDC_WRAPPER_BASE_OFFS + 0x20)
#define VIDC_VENUS_VBIF_PRIORITY_LEVEL (VIDC_WRAPPER_BASE_OFFS + 0x24)
diff --git a/drivers/media/video/msm_wfd/enc-subdev.h b/drivers/media/video/msm_wfd/enc-subdev.h
index 5873e62..00eb6da 100644
--- a/drivers/media/video/msm_wfd/enc-subdev.h
+++ b/drivers/media/video/msm_wfd/enc-subdev.h
@@ -14,7 +14,7 @@
#ifndef _WFD_ENC_SUBDEV_
#define _WFD_ENC_SUBDEV_
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <media/v4l2-subdev.h>
#include <media/videobuf2-core.h>
#define VENC_MAGIC_IOCTL 'V'
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 35ae29a..0ea843c 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -253,6 +253,18 @@
},
};
+static struct wcd9xx_codec_type {
+ u8 byte[4];
+ struct mfd_cell *dev;
+ int size;
+} wcd9xxx_codecs[] = {
+ {{0x2, 0x0, 0x0, 0x1}, tabla_devs, ARRAY_SIZE(tabla_devs)},
+ {{0x1, 0x0, 0x0, 0x1}, tabla1x_devs, ARRAY_SIZE(tabla1x_devs)},
+ {{0x0, 0x0, 0x2, 0x1}, taiko_devs, ARRAY_SIZE(taiko_devs)},
+ {{0x0, 0x0, 0x0, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs)},
+ {{0x1, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs)},
+};
+
static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
{
wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x4);
@@ -298,6 +310,53 @@
wcd9xxx->reset_gpio = 0;
}
}
+static int wcd9xxx_check_codec_type(struct wcd9xxx *wcd9xxx,
+ struct mfd_cell **wcd9xxx_dev,
+ int *wcd9xxx_dev_size)
+{
+ struct wcd9xx_codec_type *cdc = wcd9xxx_codecs;
+ int index;
+ int ret;
+ index = WCD9XXX_A_CHIP_ID_BYTE_0;
+ while (index <= WCD9XXX_A_CHIP_ID_BYTE_3) {
+ ret = wcd9xxx_reg_read(wcd9xxx, index);
+ if (ret < 0)
+ goto exit;
+ wcd9xxx->idbyte[index-WCD9XXX_A_CHIP_ID_BYTE_0] = (u8)ret;
+ pr_debug("%s: wcd9xx read = %x, byte = %x\n", __func__, ret,
+ index);
+ index++;
+ }
+
+ /* Read codec version */
+ ret = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_VERSION);
+ if (ret < 0)
+ goto exit;
+ wcd9xxx->version = (u8)ret & 0x1F;
+
+ while (cdc < (cdc + ARRAY_SIZE(wcd9xxx_codecs)) && cdc != NULL) {
+ if ((cdc->byte[0] == wcd9xxx->idbyte[0]) &&
+ (cdc->byte[1] == wcd9xxx->idbyte[1]) &&
+ (cdc->byte[2] == wcd9xxx->idbyte[2]) &&
+ (cdc->byte[3] == wcd9xxx->idbyte[3])) {
+ pr_info("%s: codec is %s", __func__, cdc->dev->name);
+ *wcd9xxx_dev = cdc->dev;
+ *wcd9xxx_dev_size = cdc->size;
+ break;
+ }
+ cdc++;
+ }
+ if (*wcd9xxx_dev == NULL || *wcd9xxx_dev_size == 0)
+ ret = -ENODEV;
+ pr_info("%s: Read codec idbytes & version\n"
+ "byte_0[%08x] byte_1[%08x] byte_2[%08x]\n"
+ " byte_3[%08x] version = %x\n", __func__,
+ wcd9xxx->idbyte[0], wcd9xxx->idbyte[1],
+ wcd9xxx->idbyte[2], wcd9xxx->idbyte[3],
+ wcd9xxx->version);
+exit:
+ return ret;
+}
static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx, int irq)
{
@@ -326,39 +385,11 @@
goto err;
}
}
+ ret = wcd9xxx_check_codec_type(wcd9xxx, &wcd9xxx_dev,
+ &wcd9xxx_dev_size);
- wcd9xxx->idbyte_0 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_0);
- wcd9xxx->idbyte_1 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_1);
- wcd9xxx->idbyte_2 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_2);
- wcd9xxx->idbyte_3 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_3);
-
- wcd9xxx->version = wcd9xxx_reg_read(wcd9xxx,
- WCD9XXX_A_CHIP_VERSION) & 0x1F;
- pr_info("%s : Codec version %u initialized\n",
- __func__, wcd9xxx->version);
- pr_info("idbyte_0[%08x] idbyte_1[%08x] idbyte_2[%08x] idbyte_3[%08x]\n",
- wcd9xxx->idbyte_0, wcd9xxx->idbyte_1,
- wcd9xxx->idbyte_2, wcd9xxx->idbyte_3);
-
- if (wcd9xxx->idbyte_0 == 0x2 && wcd9xxx->idbyte_1 == 0x0 &&
- wcd9xxx->idbyte_2 == 0x0 && wcd9xxx->idbyte_3 == 0x1) {
- wcd9xxx_dev = tabla_devs;
- wcd9xxx_dev_size = ARRAY_SIZE(tabla_devs);
- } else if (wcd9xxx->idbyte_0 == 0x1 && wcd9xxx->idbyte_1 == 0x0 &&
- wcd9xxx->idbyte_2 == 0x0 && wcd9xxx->idbyte_3 == 0x1) {
- wcd9xxx_dev = tabla1x_devs;
- wcd9xxx_dev_size = ARRAY_SIZE(tabla1x_devs);
- } else if (wcd9xxx->idbyte_0 == 0x0 && wcd9xxx->idbyte_1 == 0x0 &&
- wcd9xxx->idbyte_2 == 0x2 && wcd9xxx->idbyte_3 == 0x1) {
- wcd9xxx_dev = taiko_devs;
- wcd9xxx_dev_size = ARRAY_SIZE(taiko_devs);
- } else if ((wcd9xxx->idbyte_0 == 0x0 && wcd9xxx->idbyte_1 == 0x0 &&
- wcd9xxx->idbyte_2 == 0x0 && wcd9xxx->idbyte_3 == 0x1) ||
- (wcd9xxx->idbyte_0 == 0x1 && wcd9xxx->idbyte_1 == 0x0 &&
- wcd9xxx->idbyte_2 == 0x1 && wcd9xxx->idbyte_3 == 0x1)) {
- wcd9xxx_dev = sitar_devs;
- wcd9xxx_dev_size = ARRAY_SIZE(sitar_devs);
- }
+ if (ret < 0)
+ goto err_irq;
ret = mfd_add_devices(wcd9xxx->dev, -1, wcd9xxx_dev, wcd9xxx_dev_size,
NULL, 0);
if (ret != 0) {
@@ -772,9 +803,9 @@
goto err_device_init;
}
- if ((wcd9xxx->idbyte_0 == 0x2) || (wcd9xxx->idbyte_0 == 0x1))
+ if ((wcd9xxx->idbyte[0] == 0x2) || (wcd9xxx->idbyte[0] == 0x1))
i2c_mode = TABLA_I2C_MODE;
- else if (wcd9xxx->idbyte_0 == 0x0)
+ else if (wcd9xxx->idbyte[0] == 0x0)
i2c_mode = SITAR_I2C_MODE;
ret = wcd9xxx_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, &val, 0);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 52fd5e8..b153b27 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -5798,6 +5798,7 @@
mmc->caps2 |= MMC_CAP2_PACKED_WR_CONTROL;
mmc->caps2 |= (MMC_CAP2_BOOTPART_NOACC | MMC_CAP2_DETECT_ON_ERR);
mmc->caps2 |= MMC_CAP2_SANITIZE;
+ mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
if (plat->nonremovable)
mmc->caps |= MMC_CAP_NONREMOVABLE;
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index 0119ebe..996456f 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -435,6 +435,14 @@
return -EINVAL;
}
+ /* mark the interrupts wakeable if they support linux-key */
+ if (cfg->key_code) {
+ enable_irq_wake(cfg->state_irq);
+ /* special handling for RESIN due to a hardware bug */
+ if (cfg->pon_type == PON_RESIN && cfg->support_reset)
+ enable_irq_wake(cfg->bark_irq);
+ }
+
return rc;
}
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 813e40a..28b641d 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -32,6 +32,7 @@
#include <mach/msm_hsusb.h>
#define CHG_BUCK_CLOCK_CTRL 0x14
+#define CHG_BUCK_CLOCK_CTRL_8038 0xD
#define PBL_ACCESS1 0x04
#define PBL_ACCESS2 0x05
@@ -3678,7 +3679,13 @@
return rc;
}
/* switch to a 3.2Mhz for the buck */
- rc = pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CLOCK_CTRL, 0x15);
+ if (pm8xxx_get_revision(chip->dev->parent) >= PM8XXX_REVISION_8038_1p0)
+ rc = pm8xxx_writeb(chip->dev->parent,
+ CHG_BUCK_CLOCK_CTRL_8038, 0x15);
+ else
+ rc = pm8xxx_writeb(chip->dev->parent,
+ CHG_BUCK_CLOCK_CTRL, 0x15);
+
if (rc) {
pr_err("Failed to switch buck clk rc=%d\n", rc);
return rc;
diff --git a/drivers/regulator/qpnp-regulator.c b/drivers/regulator/qpnp-regulator.c
index 44fdbc1..0549593 100644
--- a/drivers/regulator/qpnp-regulator.c
+++ b/drivers/regulator/qpnp-regulator.c
@@ -71,11 +71,18 @@
QPNP_REGULATOR_SUBTYPE_N300 = 0x03,
QPNP_REGULATOR_SUBTYPE_N600 = 0x04,
QPNP_REGULATOR_SUBTYPE_N1200 = 0x05,
+ QPNP_REGULATOR_SUBTYPE_N600_ST = 0x06,
+ QPNP_REGULATOR_SUBTYPE_N1200_ST = 0x07,
QPNP_REGULATOR_SUBTYPE_P50 = 0x08,
QPNP_REGULATOR_SUBTYPE_P150 = 0x09,
QPNP_REGULATOR_SUBTYPE_P300 = 0x0A,
QPNP_REGULATOR_SUBTYPE_P600 = 0x0B,
QPNP_REGULATOR_SUBTYPE_P1200 = 0x0C,
+ QPNP_REGULATOR_SUBTYPE_LV_P50 = 0x28,
+ QPNP_REGULATOR_SUBTYPE_LV_P150 = 0x29,
+ QPNP_REGULATOR_SUBTYPE_LV_P300 = 0x2A,
+ QPNP_REGULATOR_SUBTYPE_LV_P600 = 0x2B,
+ QPNP_REGULATOR_SUBTYPE_LV_P1200 = 0x2C,
QPNP_REGULATOR_SUBTYPE_LV100 = 0x01,
QPNP_REGULATOR_SUBTYPE_LV300 = 0x02,
QPNP_REGULATOR_SUBTYPE_MV300 = 0x08,
@@ -978,11 +985,20 @@
QPNP_VREG_MAP(LDO, N1200, 0, 0, LDO, ldo, nldo2, 10000),
QPNP_VREG_MAP(LDO, N600, 1, INF, LDO, ldo, nldo3, 10000),
QPNP_VREG_MAP(LDO, N1200, 1, INF, LDO, ldo, nldo3, 10000),
+ QPNP_VREG_MAP(LDO, N600_ST, 0, 0, LDO, ldo, nldo2, 10000),
+ QPNP_VREG_MAP(LDO, N1200_ST, 0, 0, LDO, ldo, nldo2, 10000),
+ QPNP_VREG_MAP(LDO, N600_ST, 1, INF, LDO, ldo, nldo3, 10000),
+ QPNP_VREG_MAP(LDO, N1200_ST, 1, INF, LDO, ldo, nldo3, 10000),
QPNP_VREG_MAP(LDO, P50, 0, INF, LDO, ldo, pldo, 5000),
QPNP_VREG_MAP(LDO, P150, 0, INF, LDO, ldo, pldo, 10000),
QPNP_VREG_MAP(LDO, P300, 0, INF, LDO, ldo, pldo, 10000),
QPNP_VREG_MAP(LDO, P600, 0, INF, LDO, ldo, pldo, 10000),
QPNP_VREG_MAP(LDO, P1200, 0, INF, LDO, ldo, pldo, 10000),
+ QPNP_VREG_MAP(LDO, LV_P50, 0, INF, LDO, ldo, pldo, 5000),
+ QPNP_VREG_MAP(LDO, LV_P150, 0, INF, LDO, ldo, pldo, 10000),
+ QPNP_VREG_MAP(LDO, LV_P300, 0, INF, LDO, ldo, pldo, 10000),
+ QPNP_VREG_MAP(LDO, LV_P600, 0, INF, LDO, ldo, pldo, 10000),
+ QPNP_VREG_MAP(LDO, LV_P1200, 0, INF, LDO, ldo, pldo, 10000),
QPNP_VREG_MAP(VS, LV100, 0, INF, VS, vs, none, 0),
QPNP_VREG_MAP(VS, LV300, 0, INF, VS, vs, none, 0),
QPNP_VREG_MAP(VS, MV300, 0, INF, VS, vs, none, 0),
diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile
index 436822d..674f057 100644
--- a/drivers/slimbus/Makefile
+++ b/drivers/slimbus/Makefile
@@ -2,4 +2,4 @@
# Makefile for kernel slimbus framework.
#
obj-$(CONFIG_SLIMBUS) += slimbus.o
-obj-$(CONFIG_SLIMBUS_MSM_CTRL) += slim-msm-ctrl.o
+obj-$(CONFIG_SLIMBUS_MSM_CTRL) += slim-msm.o slim-msm-ctrl.o
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 556e3ea..6cddf2d 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -16,7 +16,6 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
#include <linux/slimbus/slimbus.h>
#include <linux/delay.h>
#include <linux/kthread.h>
@@ -26,61 +25,11 @@
#include <linux/of_slimbus.h>
#include <mach/sps.h>
#include <mach/qdsp6v2/apr.h>
-
-/* Per spec.max 40 bytes per received message */
-#define SLIM_RX_MSGQ_BUF_LEN 40
-
-#define SLIM_USR_MC_GENERIC_ACK 0x25
-#define SLIM_USR_MC_MASTER_CAPABILITY 0x0
-#define SLIM_USR_MC_REPORT_SATELLITE 0x1
-#define SLIM_USR_MC_ADDR_QUERY 0xD
-#define SLIM_USR_MC_ADDR_REPLY 0xE
-#define SLIM_USR_MC_DEFINE_CHAN 0x20
-#define SLIM_USR_MC_DEF_ACT_CHAN 0x21
-#define SLIM_USR_MC_CHAN_CTRL 0x23
-#define SLIM_USR_MC_RECONFIG_NOW 0x24
-#define SLIM_USR_MC_REQ_BW 0x28
-#define SLIM_USR_MC_CONNECT_SRC 0x2C
-#define SLIM_USR_MC_CONNECT_SINK 0x2D
-#define SLIM_USR_MC_DISCONNECT_PORT 0x2E
-
-/* MSM Slimbus peripheral settings */
-#define MSM_SLIM_PERF_SUMM_THRESHOLD 0x8000
-#define MSM_SLIM_NCHANS 32
-#define MSM_SLIM_NPORTS 24
-#define MSM_SLIM_AUTOSUSPEND MSEC_PER_SEC
-
-/*
- * Need enough descriptors to receive present messages from slaves
- * if received simultaneously. Present message needs 3 descriptors
- * and this size will ensure around 10 simultaneous reports.
- */
-#define MSM_SLIM_DESC_NUM 32
-
-#define SLIM_MSG_ASM_FIRST_WORD(l, mt, mc, dt, ad) \
- ((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16))
+#include "slim-msm.h"
#define MSM_SLIM_NAME "msm_slim_ctrl"
#define SLIM_ROOT_FREQ 24576000
-#define MSM_CONCUR_MSG 8
-#define SAT_CONCUR_MSG 8
-#define DEF_WATERMARK (8 << 1)
-#define DEF_ALIGN 0
-#define DEF_PACK (1 << 6)
-#define ENABLE_PORT 1
-
-#define DEF_BLKSZ 0
-#define DEF_TRANSZ 0
-
-#define SAT_MAGIC_LSB 0xD9
-#define SAT_MAGIC_MSB 0xC5
-#define SAT_MSG_VER 0x1
-#define SAT_MSG_PROT 0x1
-#define MSM_SAT_SUCCSS 0x20
-#define MSM_MAX_NSATS 2
-#define MSM_MAX_SATCH 32
-
#define QC_MFGID_LSB 0x2
#define QC_MFGID_MSB 0x17
#define QC_CHIPID_SL 0x10
@@ -91,82 +40,6 @@
#define INIT_MX_RETRIES 10
#define DEF_RETRY_MS 10
-#define PGD_THIS_EE(r, v) ((v) ? PGD_THIS_EE_V2(r) : PGD_THIS_EE_V1(r))
-#define PGD_PORT(r, p, v) ((v) ? PGD_PORT_V2(r, p) : PGD_PORT_V1(r, p))
-#define CFG_PORT(r, v) ((v) ? CFG_PORT_V2(r) : CFG_PORT_V1(r))
-
-#define PGD_THIS_EE_V2(r) (dev->base + (r ## _V2) + (dev->ee * 0x1000))
-#define PGD_PORT_V2(r, p) (dev->base + (r ## _V2) + ((p) * 0x1000))
-#define CFG_PORT_V2(r) ((r ## _V2))
-/* Component registers */
-enum comp_reg_v2 {
- COMP_CFG_V2 = 4,
- COMP_TRUST_CFG_V2 = 0x3000,
-};
-
-/* Manager PGD registers */
-enum pgd_reg_v2 {
- PGD_CFG_V2 = 0x800,
- PGD_STAT_V2 = 0x804,
- PGD_INT_EN_V2 = 0x810,
- PGD_INT_STAT_V2 = 0x814,
- PGD_INT_CLR_V2 = 0x818,
- PGD_OWN_EEn_V2 = 0x300C,
- PGD_PORT_INT_EN_EEn_V2 = 0x5000,
- PGD_PORT_INT_ST_EEn_V2 = 0x5004,
- PGD_PORT_INT_CL_EEn_V2 = 0x5008,
- PGD_PORT_CFGn_V2 = 0x14000,
- PGD_PORT_STATn_V2 = 0x14004,
- PGD_PORT_PARAMn_V2 = 0x14008,
- PGD_PORT_BLKn_V2 = 0x1400C,
- PGD_PORT_TRANn_V2 = 0x14010,
- PGD_PORT_MCHANn_V2 = 0x14014,
- PGD_PORT_PSHPLLn_V2 = 0x14018,
- PGD_PORT_PC_CFGn_V2 = 0x8000,
- PGD_PORT_PC_VALn_V2 = 0x8004,
- PGD_PORT_PC_VFR_TSn_V2 = 0x8008,
- PGD_PORT_PC_VFR_STn_V2 = 0x800C,
- PGD_PORT_PC_VFR_CLn_V2 = 0x8010,
- PGD_IE_STAT_V2 = 0x820,
- PGD_VE_STAT_V2 = 0x830,
-};
-
-#define PGD_THIS_EE_V1(r) (dev->base + (r ## _V1) + (dev->ee * 16))
-#define PGD_PORT_V1(r, p) (dev->base + (r ## _V1) + ((p) * 32))
-#define CFG_PORT_V1(r) ((r ## _V1))
-/* Component registers */
-enum comp_reg_v1 {
- COMP_CFG_V1 = 0,
- COMP_TRUST_CFG_V1 = 0x14,
-};
-
-/* Manager PGD registers */
-enum pgd_reg_v1 {
- PGD_CFG_V1 = 0x1000,
- PGD_STAT_V1 = 0x1004,
- PGD_INT_EN_V1 = 0x1010,
- PGD_INT_STAT_V1 = 0x1014,
- PGD_INT_CLR_V1 = 0x1018,
- PGD_OWN_EEn_V1 = 0x1020,
- PGD_PORT_INT_EN_EEn_V1 = 0x1030,
- PGD_PORT_INT_ST_EEn_V1 = 0x1034,
- PGD_PORT_INT_CL_EEn_V1 = 0x1038,
- PGD_PORT_CFGn_V1 = 0x1080,
- PGD_PORT_STATn_V1 = 0x1084,
- PGD_PORT_PARAMn_V1 = 0x1088,
- PGD_PORT_BLKn_V1 = 0x108C,
- PGD_PORT_TRANn_V1 = 0x1090,
- PGD_PORT_MCHANn_V1 = 0x1094,
- PGD_PORT_PSHPLLn_V1 = 0x1098,
- PGD_PORT_PC_CFGn_V1 = 0x1600,
- PGD_PORT_PC_VALn_V1 = 0x1604,
- PGD_PORT_PC_VFR_TSn_V1 = 0x1608,
- PGD_PORT_PC_VFR_STn_V1 = 0x160C,
- PGD_PORT_PC_VFR_CLn_V1 = 0x1610,
- PGD_IE_STAT_V1 = 0x1700,
- PGD_VE_STAT_V1 = 0x1710,
-};
-
/* Manager registers */
enum mgr_reg {
MGR_CFG = 0x200,
@@ -217,12 +90,6 @@
INTF_VE_STAT = 0x640,
};
-enum rsc_grp {
- EE_MGR_RSC_GRP = 1 << 10,
- EE_NGD_2 = 2 << 6,
- EE_NGD_1 = 0,
-};
-
enum mgr_intr {
MGR_INT_RECFG_DONE = 1 << 24,
MGR_INT_TX_NACKED_2 = 1 << 25,
@@ -239,118 +106,8 @@
INTR_WAKE = 19,
};
-enum msm_ctrl_state {
- MSM_CTRL_AWAKE,
- MSM_CTRL_SLEEPING,
- MSM_CTRL_ASLEEP,
-};
-
-struct msm_slim_sps_bam {
- u32 hdl;
- void __iomem *base;
- int irq;
-};
-
-struct msm_slim_endp {
- struct sps_pipe *sps;
- struct sps_connect config;
- struct sps_register_event event;
- struct sps_mem_buffer buf;
- struct completion *xcomp;
- bool connected;
-};
-
-struct msm_slim_ctrl {
- struct slim_controller ctrl;
- struct slim_framer framer;
- struct device *dev;
- void __iomem *base;
- struct resource *slew_mem;
- u32 curr_bw;
- u8 msg_cnt;
- u32 tx_buf[10];
- u8 rx_msgs[MSM_CONCUR_MSG][SLIM_RX_MSGQ_BUF_LEN];
- spinlock_t rx_lock;
- int head;
- int tail;
- int irq;
- int err;
- int ee;
- struct completion *wr_comp;
- struct msm_slim_sat *satd[MSM_MAX_NSATS];
- struct msm_slim_endp pipes[7];
- struct msm_slim_sps_bam bam;
- struct msm_slim_endp rx_msgq;
- struct completion rx_msgq_notify;
- struct task_struct *rx_msgq_thread;
- struct clk *rclk;
- struct clk *hclk;
- struct mutex tx_lock;
- u8 pgdla;
- bool use_rx_msgqs;
- int pipe_b;
- struct completion reconf;
- bool reconf_busy;
- bool chan_active;
- enum msm_ctrl_state state;
- int nsats;
- u32 ver;
-};
-
-struct msm_sat_chan {
- u8 chan;
- u16 chanh;
- int req_rem;
- int req_def;
- bool reconf;
-};
-
-struct msm_slim_sat {
- struct slim_device satcl;
- struct msm_slim_ctrl *dev;
- struct workqueue_struct *wq;
- struct work_struct wd;
- u8 sat_msgs[SAT_CONCUR_MSG][40];
- struct msm_sat_chan *satch;
- u8 nsatch;
- bool sent_capability;
- bool pending_reconf;
- bool pending_capability;
- int shead;
- int stail;
- spinlock_t lock;
-};
-
static struct msm_slim_sat *msm_slim_alloc_sat(struct msm_slim_ctrl *dev);
-static int msm_slim_rx_enqueue(struct msm_slim_ctrl *dev, u32 *buf, u8 len)
-{
- spin_lock(&dev->rx_lock);
- if ((dev->tail + 1) % MSM_CONCUR_MSG == dev->head) {
- spin_unlock(&dev->rx_lock);
- dev_err(dev->dev, "RX QUEUE full!");
- return -EXFULL;
- }
- memcpy((u8 *)dev->rx_msgs[dev->tail], (u8 *)buf, len);
- dev->tail = (dev->tail + 1) % MSM_CONCUR_MSG;
- spin_unlock(&dev->rx_lock);
- return 0;
-}
-
-static int msm_slim_rx_dequeue(struct msm_slim_ctrl *dev, u8 *buf)
-{
- unsigned long flags;
- spin_lock_irqsave(&dev->rx_lock, flags);
- if (dev->tail == dev->head) {
- spin_unlock_irqrestore(&dev->rx_lock, flags);
- return -ENODATA;
- }
- memcpy(buf, (u8 *)dev->rx_msgs[dev->head], 40);
- dev->head = (dev->head + 1) % MSM_CONCUR_MSG;
- spin_unlock_irqrestore(&dev->rx_lock, flags);
- return 0;
-}
-
static int msm_sat_enqueue(struct msm_slim_sat *sat, u32 *buf, u8 len)
{
struct msm_slim_ctrl *dev = sat->dev;
@@ -399,36 +156,6 @@
return false;
}
-static int msm_slim_get_ctrl(struct msm_slim_ctrl *dev)
-{
-#ifdef CONFIG_PM_RUNTIME
- int ref = 0;
- int ret = pm_runtime_get_sync(dev->dev);
- if (ret >= 0) {
- ref = atomic_read(&dev->dev->power.usage_count);
- if (ref <= 0) {
- dev_err(dev->dev, "reference count -ve:%d", ref);
- ret = -ENODEV;
- }
- }
- return ret;
-#else
- return -ENODEV;
-#endif
-}
-static void msm_slim_put_ctrl(struct msm_slim_ctrl *dev)
-{
-#ifdef CONFIG_PM_RUNTIME
- int ref;
- pm_runtime_mark_last_busy(dev->dev);
- ref = atomic_read(&dev->dev->power.usage_count);
- if (ref <= 0)
- dev_err(dev->dev, "reference count mismatch:%d", ref);
- else
- pm_runtime_put(dev->dev);
-#endif
-}
-
static struct msm_slim_sat *addr_to_sat(struct msm_slim_ctrl *dev, u8 laddr)
{
struct msm_slim_sat *sat = NULL;
@@ -622,159 +349,6 @@
return IRQ_HANDLED;
}
-static int
-msm_slim_init_endpoint(struct msm_slim_ctrl *dev, struct msm_slim_endp *ep)
-{
- int ret;
- struct sps_pipe *endpoint;
- struct sps_connect *config = &ep->config;
-
- /* Allocate the endpoint */
- endpoint = sps_alloc_endpoint();
- if (!endpoint) {
- dev_err(dev->dev, "sps_alloc_endpoint failed\n");
- return -ENOMEM;
- }
-
- /* Get default connection configuration for an endpoint */
- ret = sps_get_config(endpoint, config);
- if (ret) {
- dev_err(dev->dev, "sps_get_config failed 0x%x\n", ret);
- goto sps_config_failed;
- }
-
- ep->sps = endpoint;
- return 0;
-
-sps_config_failed:
- sps_free_endpoint(endpoint);
- return ret;
-}
-
-static void
-msm_slim_free_endpoint(struct msm_slim_endp *ep)
-{
- sps_free_endpoint(ep->sps);
- ep->sps = NULL;
-}
-
-static int msm_slim_sps_mem_alloc(
- struct msm_slim_ctrl *dev, struct sps_mem_buffer *mem, u32 len)
-{
- dma_addr_t phys;
-
- mem->size = len;
- mem->min_size = 0;
- mem->base = dma_alloc_coherent(dev->dev, mem->size, &phys, GFP_KERNEL);
-
- if (!mem->base) {
- dev_err(dev->dev, "dma_alloc_coherent(%d) failed\n", len);
- return -ENOMEM;
- }
-
- mem->phys_base = phys;
- memset(mem->base, 0x00, mem->size);
- return 0;
-}
-
-static void
-msm_slim_sps_mem_free(struct msm_slim_ctrl *dev, struct sps_mem_buffer *mem)
-{
- dma_free_coherent(dev->dev, mem->size, mem->base, mem->phys_base);
- mem->size = 0;
- mem->base = NULL;
- mem->phys_base = 0;
-}
-
-static void msm_hw_set_port(struct msm_slim_ctrl *dev, u8 pn)
-{
- u32 set_cfg = DEF_WATERMARK | DEF_ALIGN | DEF_PACK | ENABLE_PORT;
- u32 int_port = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
- dev->ver));
- writel_relaxed(set_cfg, PGD_PORT(PGD_PORT_CFGn, pn, dev->ver));
- writel_relaxed(DEF_BLKSZ, PGD_PORT(PGD_PORT_BLKn, pn, dev->ver));
- writel_relaxed(DEF_TRANSZ, PGD_PORT(PGD_PORT_TRANn, pn, dev->ver));
- writel_relaxed((int_port | 1 << pn) , PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
- dev->ver));
- /* Make sure that port registers are updated before returning */
- mb();
-}
-
-static int msm_slim_connect_pipe_port(struct msm_slim_ctrl *dev, u8 pn)
-{
- struct msm_slim_endp *endpoint = &dev->pipes[pn];
- struct sps_connect *cfg = &endpoint->config;
- u32 stat;
- int ret = sps_get_config(dev->pipes[pn].sps, cfg);
- if (ret) {
- dev_err(dev->dev, "sps pipe-port get config error%x\n", ret);
- return ret;
- }
- cfg->options = SPS_O_DESC_DONE | SPS_O_ERROR |
- SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
-
- if (dev->pipes[pn].connected) {
- ret = sps_set_config(dev->pipes[pn].sps, cfg);
- if (ret) {
- dev_err(dev->dev, "sps pipe-port set config erro:%x\n",
- ret);
- return ret;
- }
- }
-
- stat = readl_relaxed(PGD_PORT(PGD_PORT_STATn, (pn + dev->pipe_b),
- dev->ver));
- if (dev->ctrl.ports[pn].flow == SLIM_SRC) {
- cfg->destination = dev->bam.hdl;
- cfg->source = SPS_DEV_HANDLE_MEM;
- cfg->dest_pipe_index = ((stat & (0xFF << 4)) >> 4);
- cfg->src_pipe_index = 0;
- dev_dbg(dev->dev, "flow src:pipe num:%d",
- cfg->dest_pipe_index);
- cfg->mode = SPS_MODE_DEST;
- } else {
- cfg->source = dev->bam.hdl;
- cfg->destination = SPS_DEV_HANDLE_MEM;
- cfg->src_pipe_index = ((stat & (0xFF << 4)) >> 4);
- cfg->dest_pipe_index = 0;
- dev_dbg(dev->dev, "flow dest:pipe num:%d",
- cfg->src_pipe_index);
- cfg->mode = SPS_MODE_SRC;
- }
- /* Space for desciptor FIFOs */
- cfg->desc.size = MSM_SLIM_DESC_NUM * sizeof(struct sps_iovec);
- cfg->config = SPS_CONFIG_DEFAULT;
- ret = sps_connect(dev->pipes[pn].sps, cfg);
- if (!ret) {
- dev->pipes[pn].connected = true;
- msm_hw_set_port(dev, pn + dev->pipe_b);
- }
- return ret;
-}
-
-static u32 *msm_get_msg_buf(struct slim_controller *ctrl, int len)
-{
- struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
- /*
- * Currently we block a transaction until the current one completes.
- * In case we need multiple transactions, use message Q
- */
- return dev->tx_buf;
-}
-
-static int msm_send_msg_buf(struct slim_controller *ctrl, u32 *buf, u8 len)
-{
- int i;
- struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
- for (i = 0; i < (len + 3) >> 2; i++) {
- dev_dbg(dev->dev, "TX data:0x%x\n", buf[i]);
- writel_relaxed(buf[i], dev->base + MGR_TX_MSG + (i * 4));
- }
- /* Guarantee that message is sent before returning */
- mb();
- return 0;
-}
-
static int msm_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
{
DECLARE_COMPLETION_ONSTACK(done);
@@ -820,7 +394,7 @@
}
}
txn->rl--;
- pbuf = msm_get_msg_buf(ctrl, txn->rl);
+ pbuf = msm_get_msg_buf(dev, txn->rl);
dev->wr_comp = NULL;
dev->err = 0;
@@ -890,7 +464,7 @@
mc == SLIM_MSG_MC_BEGIN_RECONFIGURATION)
dev->reconf_busy = true;
dev->wr_comp = &done;
- msm_send_msg_buf(ctrl, pbuf, txn->rl);
+ msm_send_msg_buf(dev, pbuf, txn->rl, MGR_TX_MSG);
timeout = wait_for_completion_timeout(&done, HZ);
if (!timeout)
dev->wr_comp = NULL;
@@ -956,7 +530,7 @@
retry_laddr:
init_completion(&done);
mutex_lock(&dev->tx_lock);
- buf = msm_get_msg_buf(ctrl, 9);
+ buf = msm_get_msg_buf(dev, 9);
buf[0] = SLIM_MSG_ASM_FIRST_WORD(9, SLIM_MSG_MT_CORE,
SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS,
SLIM_MSG_DEST_LOGICALADDR,
@@ -965,7 +539,7 @@
buf[2] = laddr;
dev->wr_comp = &done;
- ret = msm_send_msg_buf(ctrl, buf, 9);
+ ret = msm_send_msg_buf(dev, buf, 9, MGR_TX_MSG);
timeout = wait_for_completion_timeout(&done, HZ);
if (!timeout)
dev->err = -ETIMEDOUT;
@@ -1009,74 +583,6 @@
return 0;
}
-static int msm_config_port(struct slim_controller *ctrl, u8 pn)
-{
- struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
- struct msm_slim_endp *endpoint;
- int ret = 0;
- if (ctrl->ports[pn].req == SLIM_REQ_HALF_DUP ||
- ctrl->ports[pn].req == SLIM_REQ_MULTI_CH)
- return -EPROTONOSUPPORT;
- if (pn >= (MSM_SLIM_NPORTS - dev->pipe_b))
- return -ENODEV;
-
- endpoint = &dev->pipes[pn];
- ret = msm_slim_init_endpoint(dev, endpoint);
- dev_dbg(dev->dev, "sps register bam error code:%x\n", ret);
- return ret;
-}
-
-static enum slim_port_err msm_slim_port_xfer_status(struct slim_controller *ctr,
- u8 pn, u8 **done_buf, u32 *done_len)
-{
- struct msm_slim_ctrl *dev = slim_get_ctrldata(ctr);
- struct sps_iovec sio;
- int ret;
- if (done_len)
- *done_len = 0;
- if (done_buf)
- *done_buf = NULL;
- if (!dev->pipes[pn].connected)
- return SLIM_P_DISCONNECT;
- ret = sps_get_iovec(dev->pipes[pn].sps, &sio);
- if (!ret) {
- if (done_len)
- *done_len = sio.size;
- if (done_buf)
- *done_buf = (u8 *)sio.addr;
- }
- dev_dbg(dev->dev, "get iovec returned %d\n", ret);
- return SLIM_P_INPROGRESS;
-}
-
-static int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, u8 *iobuf,
- u32 len, struct completion *comp)
-{
- struct sps_register_event sreg;
- int ret;
- struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
- if (pn >= 7)
- return -ENODEV;
-
-
- ctrl->ports[pn].xcomp = comp;
- sreg.options = (SPS_EVENT_DESC_DONE|SPS_EVENT_ERROR);
- sreg.mode = SPS_TRIGGER_WAIT;
- sreg.xfer_done = comp;
- sreg.callback = NULL;
- sreg.user = &ctrl->ports[pn];
- ret = sps_register_event(dev->pipes[pn].sps, &sreg);
- if (ret) {
- dev_dbg(dev->dev, "sps register event error:%x\n", ret);
- return ret;
- }
- ret = sps_transfer_one(dev->pipes[pn].sps, (u32)iobuf, len, NULL,
- SPS_IOVEC_FLAG_INT);
- dev_dbg(dev->dev, "sps submit xfer error code:%x\n", ret);
-
- return ret;
-}
-
static int msm_sat_define_ch(struct msm_slim_sat *sat, u8 *buf, u8 len, u8 mc)
{
struct msm_slim_ctrl *dev = sat->dev;
@@ -1521,95 +1027,6 @@
return sat;
}
-static void
-msm_slim_rx_msgq_event(struct msm_slim_ctrl *dev, struct sps_event_notify *ev)
-{
- u32 *buf = ev->data.transfer.user;
- struct sps_iovec *iovec = &ev->data.transfer.iovec;
-
- /*
- * Note the virtual address needs to be offset by the same index
- * as the physical address or just pass in the actual virtual address
- * if the sps_mem_buffer is not needed. Note that if completion is
- * used, the virtual address won't be available and will need to be
- * calculated based on the offset of the physical address
- */
- if (ev->event_id == SPS_EVENT_DESC_DONE) {
-
- pr_debug("buf = 0x%p, data = 0x%x\n", buf, *buf);
-
- pr_debug("iovec = (0x%x 0x%x 0x%x)\n",
- iovec->addr, iovec->size, iovec->flags);
-
- } else {
- dev_err(dev->dev, "%s: unknown event %d\n",
- __func__, ev->event_id);
- }
-}
-
-static void msm_slim_rx_msgq_cb(struct sps_event_notify *notify)
-{
- struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)notify->user;
- msm_slim_rx_msgq_event(dev, notify);
-}
-
-/* Queue up Rx message buffer */
-static inline int
-msm_slim_post_rx_msgq(struct msm_slim_ctrl *dev, int ix)
-{
- int ret;
- u32 flags = SPS_IOVEC_FLAG_INT;
- struct msm_slim_endp *endpoint = &dev->rx_msgq;
- struct sps_mem_buffer *mem = &endpoint->buf;
- struct sps_pipe *pipe = endpoint->sps;
-
- /* Rx message queue buffers are 4 bytes in length */
- u8 *virt_addr = mem->base + (4 * ix);
- u32 phys_addr = mem->phys_base + (4 * ix);
-
- pr_debug("index:%d, phys:0x%x, virt:0x%p\n", ix, phys_addr, virt_addr);
-
- ret = sps_transfer_one(pipe, phys_addr, 4, virt_addr, flags);
- if (ret)
- dev_err(dev->dev, "transfer_one() failed 0x%x, %d\n", ret, ix);
-
- return ret;
-}
-
-static inline int
-msm_slim_rx_msgq_get(struct msm_slim_ctrl *dev, u32 *data, int offset)
-{
- struct msm_slim_endp *endpoint = &dev->rx_msgq;
- struct sps_mem_buffer *mem = &endpoint->buf;
- struct sps_pipe *pipe = endpoint->sps;
- struct sps_iovec iovec;
- int index;
- int ret;
-
- ret = sps_get_iovec(pipe, &iovec);
- if (ret) {
- dev_err(dev->dev, "sps_get_iovec() failed 0x%x\n", ret);
- goto err_exit;
- }
-
- pr_debug("iovec = (0x%x 0x%x 0x%x)\n",
- iovec.addr, iovec.size, iovec.flags);
- BUG_ON(iovec.addr < mem->phys_base);
- BUG_ON(iovec.addr >= mem->phys_base + mem->size);
-
- /* Calculate buffer index */
- index = (iovec.addr - mem->phys_base) / 4;
- *(data + offset) = *((u32 *)mem->base + index);
-
- pr_debug("buf = 0x%p, data = 0x%x\n", (u32 *)mem->base + index, *data);
-
- /* Add buffer back to the queue */
- (void)msm_slim_post_rx_msgq(dev, index);
-
-err_exit:
- return ret;
-}
-
static int msm_slim_rx_msgq_thread(void *data)
{
struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)data;
@@ -1674,219 +1091,6 @@
return 0;
}
-static int __devinit msm_slim_init_rx_msgq(struct msm_slim_ctrl *dev)
-{
- int i, ret;
- u32 pipe_offset;
- struct msm_slim_endp *endpoint = &dev->rx_msgq;
- struct sps_connect *config = &endpoint->config;
- struct sps_mem_buffer *descr = &config->desc;
- struct sps_mem_buffer *mem = &endpoint->buf;
- struct completion *notify = &dev->rx_msgq_notify;
-
- struct sps_register_event sps_error_event; /* SPS_ERROR */
- struct sps_register_event sps_descr_event; /* DESCR_DONE */
-
- init_completion(notify);
- if (!dev->use_rx_msgqs)
- goto rx_thread_create;
-
- /* Allocate the endpoint */
- ret = msm_slim_init_endpoint(dev, endpoint);
- if (ret) {
- dev_err(dev->dev, "init_endpoint failed 0x%x\n", ret);
- goto sps_init_endpoint_failed;
- }
-
- /* Get the pipe indices for the message queues */
- pipe_offset = (readl_relaxed(dev->base + MGR_STATUS) & 0xfc) >> 2;
- dev_dbg(dev->dev, "Message queue pipe offset %d\n", pipe_offset);
-
- config->mode = SPS_MODE_SRC;
- config->source = dev->bam.hdl;
- config->destination = SPS_DEV_HANDLE_MEM;
- config->src_pipe_index = pipe_offset;
- config->options = SPS_O_DESC_DONE | SPS_O_ERROR |
- SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
-
- /* Allocate memory for the FIFO descriptors */
- ret = msm_slim_sps_mem_alloc(dev, descr,
- MSM_SLIM_DESC_NUM * sizeof(struct sps_iovec));
- if (ret) {
- dev_err(dev->dev, "unable to allocate SPS descriptors\n");
- goto alloc_descr_failed;
- }
-
- ret = sps_connect(endpoint->sps, config);
- if (ret) {
- dev_err(dev->dev, "sps_connect failed 0x%x\n", ret);
- goto sps_connect_failed;
- }
-
- /* Register completion for DESC_DONE */
- init_completion(notify);
- memset(&sps_descr_event, 0x00, sizeof(sps_descr_event));
-
- sps_descr_event.mode = SPS_TRIGGER_CALLBACK;
- sps_descr_event.options = SPS_O_DESC_DONE;
- sps_descr_event.user = (void *)dev;
- sps_descr_event.xfer_done = notify;
-
- ret = sps_register_event(endpoint->sps, &sps_descr_event);
- if (ret) {
- dev_err(dev->dev, "sps_connect() failed 0x%x\n", ret);
- goto sps_reg_event_failed;
- }
-
- /* Register callback for errors */
- memset(&sps_error_event, 0x00, sizeof(sps_error_event));
- sps_error_event.mode = SPS_TRIGGER_CALLBACK;
- sps_error_event.options = SPS_O_ERROR;
- sps_error_event.user = (void *)dev;
- sps_error_event.callback = msm_slim_rx_msgq_cb;
-
- ret = sps_register_event(endpoint->sps, &sps_error_event);
- if (ret) {
- dev_err(dev->dev, "sps_connect() failed 0x%x\n", ret);
- goto sps_reg_event_failed;
- }
-
- /* Allocate memory for the message buffer(s), N descrs, 4-byte mesg */
- ret = msm_slim_sps_mem_alloc(dev, mem, MSM_SLIM_DESC_NUM * 4);
- if (ret) {
- dev_err(dev->dev, "dma_alloc_coherent failed\n");
- goto alloc_buffer_failed;
- }
-
- /*
- * Call transfer_one for each 4-byte buffer
- * Use (buf->size/4) - 1 for the number of buffer to post
- */
-
- /* Setup the transfer */
- for (i = 0; i < (MSM_SLIM_DESC_NUM - 1); i++) {
- ret = msm_slim_post_rx_msgq(dev, i);
- if (ret) {
- dev_err(dev->dev, "post_rx_msgq() failed 0x%x\n", ret);
- goto sps_transfer_failed;
- }
- }
-
-rx_thread_create:
- /* Fire up the Rx message queue thread */
- dev->rx_msgq_thread = kthread_run(msm_slim_rx_msgq_thread, dev,
- MSM_SLIM_NAME "_rx_msgq_thread");
- if (!dev->rx_msgq_thread) {
- dev_err(dev->dev, "Failed to start Rx message queue thread\n");
- /* Tear-down BAMs or return? */
- if (!dev->use_rx_msgqs)
- return -EIO;
- else
- ret = -EIO;
- } else
- return 0;
-
-sps_transfer_failed:
- msm_slim_sps_mem_free(dev, mem);
-alloc_buffer_failed:
- memset(&sps_error_event, 0x00, sizeof(sps_error_event));
- sps_register_event(endpoint->sps, &sps_error_event);
-sps_reg_event_failed:
- sps_disconnect(endpoint->sps);
-sps_connect_failed:
- msm_slim_sps_mem_free(dev, descr);
-alloc_descr_failed:
- msm_slim_free_endpoint(endpoint);
-sps_init_endpoint_failed:
- dev->use_rx_msgqs = 0;
- return ret;
-}
-
-/* Registers BAM h/w resource with SPS driver and initializes msgq endpoints */
-static int __devinit
-msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem)
-{
- int i, ret;
- u32 bam_handle;
- struct sps_bam_props bam_props = {0};
-
- static struct sps_bam_sec_config_props sec_props = {
- .ees = {
- [0] = { /* LPASS */
- .vmid = 0,
- .pipe_mask = 0xFFFF98,
- },
- [1] = { /* Krait Apps */
- .vmid = 1,
- .pipe_mask = 0x3F000007,
- },
- [2] = { /* Modem */
- .vmid = 2,
- .pipe_mask = 0x00000060,
- },
- },
- };
-
- bam_props.ee = dev->ee;
- bam_props.virt_addr = dev->bam.base;
- bam_props.phys_addr = bam_mem->start;
- bam_props.irq = dev->bam.irq;
- bam_props.manage = SPS_BAM_MGR_LOCAL;
- bam_props.summing_threshold = MSM_SLIM_PERF_SUMM_THRESHOLD;
-
- bam_props.sec_config = SPS_BAM_SEC_DO_CONFIG;
- bam_props.p_sec_config_props = &sec_props;
-
- bam_props.options = SPS_O_DESC_DONE | SPS_O_ERROR |
- SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
-
- /* First 7 bits are for message Qs */
- for (i = 7; i < 32; i++) {
- /* Check what pipes are owned by Apps. */
- if ((sec_props.ees[dev->ee].pipe_mask >> i) & 0x1)
- break;
- }
- dev->pipe_b = i - 7;
-
- /* Register the BAM device with the SPS driver */
- ret = sps_register_bam_device(&bam_props, &bam_handle);
- if (ret) {
- dev_err(dev->dev, "disabling BAM: reg-bam failed 0x%x\n", ret);
- dev->use_rx_msgqs = 0;
- goto init_rx_msgq;
- }
- dev->bam.hdl = bam_handle;
- dev_dbg(dev->dev, "SLIM BAM registered, handle = 0x%x\n", bam_handle);
-
-init_rx_msgq:
- ret = msm_slim_init_rx_msgq(dev);
- if (ret)
- dev_err(dev->dev, "msm_slim_init_rx_msgq failed 0x%x\n", ret);
- if (ret && bam_handle) {
- sps_deregister_bam_device(bam_handle);
- dev->bam.hdl = 0L;
- }
- return ret;
-}
-
-static void msm_slim_sps_exit(struct msm_slim_ctrl *dev)
-{
- if (dev->use_rx_msgqs) {
- struct msm_slim_endp *endpoint = &dev->rx_msgq;
- struct sps_connect *config = &endpoint->config;
- struct sps_mem_buffer *descr = &config->desc;
- struct sps_mem_buffer *mem = &endpoint->buf;
- struct sps_register_event sps_event;
- memset(&sps_event, 0x00, sizeof(sps_event));
- msm_slim_sps_mem_free(dev, mem);
- sps_register_event(endpoint->sps, &sps_event);
- sps_disconnect(endpoint->sps);
- msm_slim_sps_mem_free(dev, descr);
- msm_slim_free_endpoint(endpoint);
- sps_deregister_bam_device(dev->bam.hdl);
- }
-}
-
static void msm_slim_prg_slew(struct platform_device *pdev,
struct msm_slim_ctrl *dev)
{
@@ -2052,12 +1256,20 @@
else
clk_prepare_enable(dev->hclk);
- ret = msm_slim_sps_init(dev, bam_mem);
+ ret = msm_slim_sps_init(dev, bam_mem, MGR_STATUS);
if (ret != 0) {
dev_err(dev->dev, "error SPS init\n");
goto err_sps_init_failed;
}
+ /* Fire up the Rx message queue thread */
+ dev->rx_msgq_thread = kthread_run(msm_slim_rx_msgq_thread, dev,
+ MSM_SLIM_NAME "_rx_msgq_thread");
+ if (IS_ERR(dev->rx_msgq_thread)) {
+ ret = PTR_ERR(dev->rx_msgq_thread);
+ dev_err(dev->dev, "Failed to start Rx message queue thread\n");
+ goto err_thread_create_failed;
+ }
dev->framer.rootfreq = SLIM_ROOT_FREQ >> 3;
dev->framer.superfreq =
@@ -2183,6 +1395,8 @@
err_clk_get_failed:
kfree(dev->satd);
err_request_irq_failed:
+ kthread_stop(dev->rx_msgq_thread);
+err_thread_create_failed:
msm_slim_sps_exit(dev);
err_sps_init_failed:
if (dev->hclk) {
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
new file mode 100644
index 0000000..8a1ea84
--- /dev/null
+++ b/drivers/slimbus/slim-msm.c
@@ -0,0 +1,578 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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 <linux/pm_runtime.h>
+#include <linux/dma-mapping.h>
+#include <linux/slimbus/slimbus.h>
+#include <mach/sps.h>
+#include "slim-msm.h"
+
+int msm_slim_rx_enqueue(struct msm_slim_ctrl *dev, u32 *buf, u8 len)
+{
+ spin_lock(&dev->rx_lock);
+ if ((dev->tail + 1) % MSM_CONCUR_MSG == dev->head) {
+ spin_unlock(&dev->rx_lock);
+ dev_err(dev->dev, "RX QUEUE full!");
+ return -EXFULL;
+ }
+ memcpy((u8 *)dev->rx_msgs[dev->tail], (u8 *)buf, len);
+ dev->tail = (dev->tail + 1) % MSM_CONCUR_MSG;
+ spin_unlock(&dev->rx_lock);
+ return 0;
+}
+
+int msm_slim_rx_dequeue(struct msm_slim_ctrl *dev, u8 *buf)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dev->rx_lock, flags);
+ if (dev->tail == dev->head) {
+ spin_unlock_irqrestore(&dev->rx_lock, flags);
+ return -ENODATA;
+ }
+ memcpy(buf, (u8 *)dev->rx_msgs[dev->head], 40);
+ dev->head = (dev->head + 1) % MSM_CONCUR_MSG;
+ spin_unlock_irqrestore(&dev->rx_lock, flags);
+ return 0;
+}
+
+int msm_slim_get_ctrl(struct msm_slim_ctrl *dev)
+{
+#ifdef CONFIG_PM_RUNTIME
+ int ref = 0;
+ int ret = pm_runtime_get_sync(dev->dev);
+ if (ret >= 0) {
+ ref = atomic_read(&dev->dev->power.usage_count);
+ if (ref <= 0) {
+ dev_err(dev->dev, "reference count -ve:%d", ref);
+ ret = -ENODEV;
+ }
+ }
+ return ret;
+#else
+ return -ENODEV;
+#endif
+}
+void msm_slim_put_ctrl(struct msm_slim_ctrl *dev)
+{
+#ifdef CONFIG_PM_RUNTIME
+ int ref;
+ pm_runtime_mark_last_busy(dev->dev);
+ ref = atomic_read(&dev->dev->power.usage_count);
+ if (ref <= 0)
+ dev_err(dev->dev, "reference count mismatch:%d", ref);
+ else
+ pm_runtime_put(dev->dev);
+#endif
+}
+
+int msm_slim_init_endpoint(struct msm_slim_ctrl *dev, struct msm_slim_endp *ep)
+{
+ int ret;
+ struct sps_pipe *endpoint;
+ struct sps_connect *config = &ep->config;
+
+ /* Allocate the endpoint */
+ endpoint = sps_alloc_endpoint();
+ if (!endpoint) {
+ dev_err(dev->dev, "sps_alloc_endpoint failed\n");
+ return -ENOMEM;
+ }
+
+ /* Get default connection configuration for an endpoint */
+ ret = sps_get_config(endpoint, config);
+ if (ret) {
+ dev_err(dev->dev, "sps_get_config failed 0x%x\n", ret);
+ goto sps_config_failed;
+ }
+
+ ep->sps = endpoint;
+ return 0;
+
+sps_config_failed:
+ sps_free_endpoint(endpoint);
+ return ret;
+}
+
+void msm_slim_free_endpoint(struct msm_slim_endp *ep)
+{
+ sps_free_endpoint(ep->sps);
+ ep->sps = NULL;
+}
+
+int msm_slim_sps_mem_alloc(
+ struct msm_slim_ctrl *dev, struct sps_mem_buffer *mem, u32 len)
+{
+ dma_addr_t phys;
+
+ mem->size = len;
+ mem->min_size = 0;
+ mem->base = dma_alloc_coherent(dev->dev, mem->size, &phys, GFP_KERNEL);
+
+ if (!mem->base) {
+ dev_err(dev->dev, "dma_alloc_coherent(%d) failed\n", len);
+ return -ENOMEM;
+ }
+
+ mem->phys_base = phys;
+ memset(mem->base, 0x00, mem->size);
+ return 0;
+}
+
+void
+msm_slim_sps_mem_free(struct msm_slim_ctrl *dev, struct sps_mem_buffer *mem)
+{
+ dma_free_coherent(dev->dev, mem->size, mem->base, mem->phys_base);
+ mem->size = 0;
+ mem->base = NULL;
+ mem->phys_base = 0;
+}
+
+void msm_hw_set_port(struct msm_slim_ctrl *dev, u8 pn)
+{
+ u32 set_cfg = DEF_WATERMARK | DEF_ALIGN | DEF_PACK | ENABLE_PORT;
+ u32 int_port = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
+ dev->ver));
+ writel_relaxed(set_cfg, PGD_PORT(PGD_PORT_CFGn, pn, dev->ver));
+ writel_relaxed(DEF_BLKSZ, PGD_PORT(PGD_PORT_BLKn, pn, dev->ver));
+ writel_relaxed(DEF_TRANSZ, PGD_PORT(PGD_PORT_TRANn, pn, dev->ver));
+ writel_relaxed((int_port | 1 << pn) , PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
+ dev->ver));
+ /* Make sure that port registers are updated before returning */
+ mb();
+}
+
+int msm_slim_connect_pipe_port(struct msm_slim_ctrl *dev, u8 pn)
+{
+ struct msm_slim_endp *endpoint = &dev->pipes[pn];
+ struct sps_connect *cfg = &endpoint->config;
+ u32 stat;
+ int ret = sps_get_config(dev->pipes[pn].sps, cfg);
+ if (ret) {
+ dev_err(dev->dev, "sps pipe-port get config error%x\n", ret);
+ return ret;
+ }
+ cfg->options = SPS_O_DESC_DONE | SPS_O_ERROR |
+ SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
+
+ if (dev->pipes[pn].connected) {
+ ret = sps_set_config(dev->pipes[pn].sps, cfg);
+ if (ret) {
+ dev_err(dev->dev, "sps pipe-port set config erro:%x\n",
+ ret);
+ return ret;
+ }
+ }
+
+ stat = readl_relaxed(PGD_PORT(PGD_PORT_STATn, (pn + dev->pipe_b),
+ dev->ver));
+ if (dev->ctrl.ports[pn].flow == SLIM_SRC) {
+ cfg->destination = dev->bam.hdl;
+ cfg->source = SPS_DEV_HANDLE_MEM;
+ cfg->dest_pipe_index = ((stat & (0xFF << 4)) >> 4);
+ cfg->src_pipe_index = 0;
+ dev_dbg(dev->dev, "flow src:pipe num:%d",
+ cfg->dest_pipe_index);
+ cfg->mode = SPS_MODE_DEST;
+ } else {
+ cfg->source = dev->bam.hdl;
+ cfg->destination = SPS_DEV_HANDLE_MEM;
+ cfg->src_pipe_index = ((stat & (0xFF << 4)) >> 4);
+ cfg->dest_pipe_index = 0;
+ dev_dbg(dev->dev, "flow dest:pipe num:%d",
+ cfg->src_pipe_index);
+ cfg->mode = SPS_MODE_SRC;
+ }
+ /* Space for desciptor FIFOs */
+ cfg->desc.size = MSM_SLIM_DESC_NUM * sizeof(struct sps_iovec);
+ cfg->config = SPS_CONFIG_DEFAULT;
+ ret = sps_connect(dev->pipes[pn].sps, cfg);
+ if (!ret) {
+ dev->pipes[pn].connected = true;
+ msm_hw_set_port(dev, pn + dev->pipe_b);
+ }
+ return ret;
+}
+
+int msm_config_port(struct slim_controller *ctrl, u8 pn)
+{
+ struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
+ struct msm_slim_endp *endpoint;
+ int ret = 0;
+ if (ctrl->ports[pn].req == SLIM_REQ_HALF_DUP ||
+ ctrl->ports[pn].req == SLIM_REQ_MULTI_CH)
+ return -EPROTONOSUPPORT;
+ if (pn >= (MSM_SLIM_NPORTS - dev->pipe_b))
+ return -ENODEV;
+
+ endpoint = &dev->pipes[pn];
+ ret = msm_slim_init_endpoint(dev, endpoint);
+ dev_dbg(dev->dev, "sps register bam error code:%x\n", ret);
+ return ret;
+}
+
+enum slim_port_err msm_slim_port_xfer_status(struct slim_controller *ctr,
+ u8 pn, u8 **done_buf, u32 *done_len)
+{
+ struct msm_slim_ctrl *dev = slim_get_ctrldata(ctr);
+ struct sps_iovec sio;
+ int ret;
+ if (done_len)
+ *done_len = 0;
+ if (done_buf)
+ *done_buf = NULL;
+ if (!dev->pipes[pn].connected)
+ return SLIM_P_DISCONNECT;
+ ret = sps_get_iovec(dev->pipes[pn].sps, &sio);
+ if (!ret) {
+ if (done_len)
+ *done_len = sio.size;
+ if (done_buf)
+ *done_buf = (u8 *)sio.addr;
+ }
+ dev_dbg(dev->dev, "get iovec returned %d\n", ret);
+ return SLIM_P_INPROGRESS;
+}
+
+int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, u8 *iobuf,
+ u32 len, struct completion *comp)
+{
+ struct sps_register_event sreg;
+ int ret;
+ struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
+ if (pn >= 7)
+ return -ENODEV;
+
+
+ ctrl->ports[pn].xcomp = comp;
+ sreg.options = (SPS_EVENT_DESC_DONE|SPS_EVENT_ERROR);
+ sreg.mode = SPS_TRIGGER_WAIT;
+ sreg.xfer_done = comp;
+ sreg.callback = NULL;
+ sreg.user = &ctrl->ports[pn];
+ ret = sps_register_event(dev->pipes[pn].sps, &sreg);
+ if (ret) {
+ dev_dbg(dev->dev, "sps register event error:%x\n", ret);
+ return ret;
+ }
+ ret = sps_transfer_one(dev->pipes[pn].sps, (u32)iobuf, len, NULL,
+ SPS_IOVEC_FLAG_INT);
+ dev_dbg(dev->dev, "sps submit xfer error code:%x\n", ret);
+
+ return ret;
+}
+
+int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg)
+{
+ int i;
+ for (i = 0; i < (len + 3) >> 2; i++) {
+ dev_dbg(dev->dev, "TX data:0x%x\n", buf[i]);
+ writel_relaxed(buf[i], dev->base + tx_reg + (i * 4));
+ }
+ /* Guarantee that message is sent before returning */
+ mb();
+ return 0;
+}
+
+u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len)
+{
+ /*
+ * Currently we block a transaction until the current one completes.
+ * In case we need multiple transactions, use message Q
+ */
+ return dev->tx_buf;
+}
+
+static void
+msm_slim_rx_msgq_event(struct msm_slim_ctrl *dev, struct sps_event_notify *ev)
+{
+ u32 *buf = ev->data.transfer.user;
+ struct sps_iovec *iovec = &ev->data.transfer.iovec;
+
+ /*
+ * Note the virtual address needs to be offset by the same index
+ * as the physical address or just pass in the actual virtual address
+ * if the sps_mem_buffer is not needed. Note that if completion is
+ * used, the virtual address won't be available and will need to be
+ * calculated based on the offset of the physical address
+ */
+ if (ev->event_id == SPS_EVENT_DESC_DONE) {
+
+ pr_debug("buf = 0x%p, data = 0x%x\n", buf, *buf);
+
+ pr_debug("iovec = (0x%x 0x%x 0x%x)\n",
+ iovec->addr, iovec->size, iovec->flags);
+
+ } else {
+ dev_err(dev->dev, "%s: unknown event %d\n",
+ __func__, ev->event_id);
+ }
+}
+
+static void msm_slim_rx_msgq_cb(struct sps_event_notify *notify)
+{
+ struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)notify->user;
+ msm_slim_rx_msgq_event(dev, notify);
+}
+
+/* Queue up Rx message buffer */
+static int msm_slim_post_rx_msgq(struct msm_slim_ctrl *dev, int ix)
+{
+ int ret;
+ u32 flags = SPS_IOVEC_FLAG_INT;
+ struct msm_slim_endp *endpoint = &dev->rx_msgq;
+ struct sps_mem_buffer *mem = &endpoint->buf;
+ struct sps_pipe *pipe = endpoint->sps;
+
+ /* Rx message queue buffers are 4 bytes in length */
+ u8 *virt_addr = mem->base + (4 * ix);
+ u32 phys_addr = mem->phys_base + (4 * ix);
+
+ pr_debug("index:%d, phys:0x%x, virt:0x%p\n", ix, phys_addr, virt_addr);
+
+ ret = sps_transfer_one(pipe, phys_addr, 4, virt_addr, flags);
+ if (ret)
+ dev_err(dev->dev, "transfer_one() failed 0x%x, %d\n", ret, ix);
+
+ return ret;
+}
+
+int msm_slim_rx_msgq_get(struct msm_slim_ctrl *dev, u32 *data, int offset)
+{
+ struct msm_slim_endp *endpoint = &dev->rx_msgq;
+ struct sps_mem_buffer *mem = &endpoint->buf;
+ struct sps_pipe *pipe = endpoint->sps;
+ struct sps_iovec iovec;
+ int index;
+ int ret;
+
+ ret = sps_get_iovec(pipe, &iovec);
+ if (ret) {
+ dev_err(dev->dev, "sps_get_iovec() failed 0x%x\n", ret);
+ goto err_exit;
+ }
+
+ pr_debug("iovec = (0x%x 0x%x 0x%x)\n",
+ iovec.addr, iovec.size, iovec.flags);
+ BUG_ON(iovec.addr < mem->phys_base);
+ BUG_ON(iovec.addr >= mem->phys_base + mem->size);
+
+ /* Calculate buffer index */
+ index = (iovec.addr - mem->phys_base) / 4;
+ *(data + offset) = *((u32 *)mem->base + index);
+
+ pr_debug("buf = 0x%p, data = 0x%x\n", (u32 *)mem->base + index, *data);
+
+ /* Add buffer back to the queue */
+ (void)msm_slim_post_rx_msgq(dev, index);
+
+err_exit:
+ return ret;
+}
+
+static int msm_slim_init_rx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg)
+{
+ int i, ret;
+ u32 pipe_offset;
+ struct msm_slim_endp *endpoint = &dev->rx_msgq;
+ struct sps_connect *config = &endpoint->config;
+ struct sps_mem_buffer *descr = &config->desc;
+ struct sps_mem_buffer *mem = &endpoint->buf;
+ struct completion *notify = &dev->rx_msgq_notify;
+
+ struct sps_register_event sps_error_event; /* SPS_ERROR */
+ struct sps_register_event sps_descr_event; /* DESCR_DONE */
+
+ init_completion(notify);
+ if (!dev->use_rx_msgqs)
+ return 0;
+
+ /* Allocate the endpoint */
+ ret = msm_slim_init_endpoint(dev, endpoint);
+ if (ret) {
+ dev_err(dev->dev, "init_endpoint failed 0x%x\n", ret);
+ goto sps_init_endpoint_failed;
+ }
+
+ /* Get the pipe indices for the message queues */
+ pipe_offset = (readl_relaxed(dev->base + pipe_reg) & 0xfc) >> 2;
+ dev_dbg(dev->dev, "Message queue pipe offset %d\n", pipe_offset);
+
+ config->mode = SPS_MODE_SRC;
+ config->source = dev->bam.hdl;
+ config->destination = SPS_DEV_HANDLE_MEM;
+ config->src_pipe_index = pipe_offset;
+ config->options = SPS_O_DESC_DONE | SPS_O_ERROR |
+ SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
+
+ /* Allocate memory for the FIFO descriptors */
+ ret = msm_slim_sps_mem_alloc(dev, descr,
+ MSM_SLIM_DESC_NUM * sizeof(struct sps_iovec));
+ if (ret) {
+ dev_err(dev->dev, "unable to allocate SPS descriptors\n");
+ goto alloc_descr_failed;
+ }
+
+ ret = sps_connect(endpoint->sps, config);
+ if (ret) {
+ dev_err(dev->dev, "sps_connect failed 0x%x\n", ret);
+ goto sps_connect_failed;
+ }
+
+ memset(&sps_descr_event, 0x00, sizeof(sps_descr_event));
+
+ sps_descr_event.mode = SPS_TRIGGER_CALLBACK;
+ sps_descr_event.options = SPS_O_DESC_DONE;
+ sps_descr_event.user = (void *)dev;
+ sps_descr_event.xfer_done = notify;
+
+ ret = sps_register_event(endpoint->sps, &sps_descr_event);
+ if (ret) {
+ dev_err(dev->dev, "sps_connect() failed 0x%x\n", ret);
+ goto sps_reg_event_failed;
+ }
+
+ /* Register callback for errors */
+ memset(&sps_error_event, 0x00, sizeof(sps_error_event));
+ sps_error_event.mode = SPS_TRIGGER_CALLBACK;
+ sps_error_event.options = SPS_O_ERROR;
+ sps_error_event.user = (void *)dev;
+ sps_error_event.callback = msm_slim_rx_msgq_cb;
+
+ ret = sps_register_event(endpoint->sps, &sps_error_event);
+ if (ret) {
+ dev_err(dev->dev, "sps_connect() failed 0x%x\n", ret);
+ goto sps_reg_event_failed;
+ }
+
+ /* Allocate memory for the message buffer(s), N descrs, 4-byte mesg */
+ ret = msm_slim_sps_mem_alloc(dev, mem, MSM_SLIM_DESC_NUM * 4);
+ if (ret) {
+ dev_err(dev->dev, "dma_alloc_coherent failed\n");
+ goto alloc_buffer_failed;
+ }
+
+ /*
+ * Call transfer_one for each 4-byte buffer
+ * Use (buf->size/4) - 1 for the number of buffer to post
+ */
+
+ /* Setup the transfer */
+ for (i = 0; i < (MSM_SLIM_DESC_NUM - 1); i++) {
+ ret = msm_slim_post_rx_msgq(dev, i);
+ if (ret) {
+ dev_err(dev->dev, "post_rx_msgq() failed 0x%x\n", ret);
+ goto sps_transfer_failed;
+ }
+ }
+
+ return 0;
+
+sps_transfer_failed:
+ msm_slim_sps_mem_free(dev, mem);
+alloc_buffer_failed:
+ memset(&sps_error_event, 0x00, sizeof(sps_error_event));
+ sps_register_event(endpoint->sps, &sps_error_event);
+sps_reg_event_failed:
+ sps_disconnect(endpoint->sps);
+sps_connect_failed:
+ msm_slim_sps_mem_free(dev, descr);
+alloc_descr_failed:
+ msm_slim_free_endpoint(endpoint);
+sps_init_endpoint_failed:
+ dev->use_rx_msgqs = 0;
+ return ret;
+}
+
+/* Registers BAM h/w resource with SPS driver and initializes msgq endpoints */
+int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
+ u32 pipe_reg)
+{
+ int i, ret;
+ u32 bam_handle;
+ struct sps_bam_props bam_props = {0};
+
+ static struct sps_bam_sec_config_props sec_props = {
+ .ees = {
+ [0] = { /* LPASS */
+ .vmid = 0,
+ .pipe_mask = 0xFFFF98,
+ },
+ [1] = { /* Krait Apps */
+ .vmid = 1,
+ .pipe_mask = 0x3F000007,
+ },
+ [2] = { /* Modem */
+ .vmid = 2,
+ .pipe_mask = 0x00000060,
+ },
+ },
+ };
+
+ bam_props.ee = dev->ee;
+ bam_props.virt_addr = dev->bam.base;
+ bam_props.phys_addr = bam_mem->start;
+ bam_props.irq = dev->bam.irq;
+ bam_props.manage = SPS_BAM_MGR_LOCAL;
+ bam_props.summing_threshold = MSM_SLIM_PERF_SUMM_THRESHOLD;
+
+ bam_props.sec_config = SPS_BAM_SEC_DO_CONFIG;
+ bam_props.p_sec_config_props = &sec_props;
+
+ bam_props.options = SPS_O_DESC_DONE | SPS_O_ERROR |
+ SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
+
+ /* First 7 bits are for message Qs */
+ for (i = 7; i < 32; i++) {
+ /* Check what pipes are owned by Apps. */
+ if ((sec_props.ees[dev->ee].pipe_mask >> i) & 0x1)
+ break;
+ }
+ dev->pipe_b = i - 7;
+
+ /* Register the BAM device with the SPS driver */
+ ret = sps_register_bam_device(&bam_props, &bam_handle);
+ if (ret) {
+ dev_err(dev->dev, "disabling BAM: reg-bam failed 0x%x\n", ret);
+ dev->use_rx_msgqs = 0;
+ goto init_rx_msgq;
+ }
+ dev->bam.hdl = bam_handle;
+ dev_dbg(dev->dev, "SLIM BAM registered, handle = 0x%x\n", bam_handle);
+
+init_rx_msgq:
+ ret = msm_slim_init_rx_msgq(dev, pipe_reg);
+ if (ret)
+ dev_err(dev->dev, "msm_slim_init_rx_msgq failed 0x%x\n", ret);
+ if (ret && bam_handle) {
+ sps_deregister_bam_device(bam_handle);
+ dev->bam.hdl = 0L;
+ }
+ return ret;
+}
+
+void msm_slim_sps_exit(struct msm_slim_ctrl *dev)
+{
+ if (dev->use_rx_msgqs) {
+ struct msm_slim_endp *endpoint = &dev->rx_msgq;
+ struct sps_connect *config = &endpoint->config;
+ struct sps_mem_buffer *descr = &config->desc;
+ struct sps_mem_buffer *mem = &endpoint->buf;
+ struct sps_register_event sps_event;
+ memset(&sps_event, 0x00, sizeof(sps_event));
+ msm_slim_sps_mem_free(dev, mem);
+ sps_register_event(endpoint->sps, &sps_event);
+ sps_disconnect(endpoint->sps);
+ msm_slim_sps_mem_free(dev, descr);
+ msm_slim_free_endpoint(endpoint);
+ sps_deregister_bam_device(dev->bam.hdl);
+ }
+}
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
new file mode 100644
index 0000000..f68475a
--- /dev/null
+++ b/drivers/slimbus/slim-msm.h
@@ -0,0 +1,251 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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 _SLIM_MSM_H
+#define _SLIM_MSM_H
+/* Per spec.max 40 bytes per received message */
+#define SLIM_RX_MSGQ_BUF_LEN 40
+
+#define SLIM_USR_MC_GENERIC_ACK 0x25
+#define SLIM_USR_MC_MASTER_CAPABILITY 0x0
+#define SLIM_USR_MC_REPORT_SATELLITE 0x1
+#define SLIM_USR_MC_ADDR_QUERY 0xD
+#define SLIM_USR_MC_ADDR_REPLY 0xE
+#define SLIM_USR_MC_DEFINE_CHAN 0x20
+#define SLIM_USR_MC_DEF_ACT_CHAN 0x21
+#define SLIM_USR_MC_CHAN_CTRL 0x23
+#define SLIM_USR_MC_RECONFIG_NOW 0x24
+#define SLIM_USR_MC_REQ_BW 0x28
+#define SLIM_USR_MC_CONNECT_SRC 0x2C
+#define SLIM_USR_MC_CONNECT_SINK 0x2D
+#define SLIM_USR_MC_DISCONNECT_PORT 0x2E
+
+#define MSM_SLIM_AUTOSUSPEND MSEC_PER_SEC
+
+/*
+ * Messages that can be received simultaneously:
+ * Client reads, LPASS master responses, announcement messages
+ * Receive upto 10 messages simultaneously.
+ */
+#define MSM_SLIM_DESC_NUM 32
+
+/* MSM Slimbus peripheral settings */
+#define MSM_SLIM_PERF_SUMM_THRESHOLD 0x8000
+#define MSM_SLIM_NPORTS 24
+#define MSM_SLIM_NCHANS 32
+
+#define SLIM_MSG_ASM_FIRST_WORD(l, mt, mc, dt, ad) \
+ ((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16))
+
+#define MSM_CONCUR_MSG 8
+#define SAT_CONCUR_MSG 8
+#define DEF_WATERMARK (8 << 1)
+#define DEF_ALIGN 0
+#define DEF_PACK (1 << 6)
+#define ENABLE_PORT 1
+
+#define DEF_BLKSZ 0
+#define DEF_TRANSZ 0
+
+#define SAT_MAGIC_LSB 0xD9
+#define SAT_MAGIC_MSB 0xC5
+#define SAT_MSG_VER 0x1
+#define SAT_MSG_PROT 0x1
+#define MSM_SAT_SUCCSS 0x20
+#define MSM_MAX_NSATS 2
+#define MSM_MAX_SATCH 32
+
+#define PGD_THIS_EE(r, v) ((v) ? PGD_THIS_EE_V2(r) : PGD_THIS_EE_V1(r))
+#define PGD_PORT(r, p, v) ((v) ? PGD_PORT_V2(r, p) : PGD_PORT_V1(r, p))
+#define CFG_PORT(r, v) ((v) ? CFG_PORT_V2(r) : CFG_PORT_V1(r))
+
+#define PGD_THIS_EE_V2(r) (dev->base + (r ## _V2) + (dev->ee * 0x1000))
+#define PGD_PORT_V2(r, p) (dev->base + (r ## _V2) + ((p) * 0x1000))
+#define CFG_PORT_V2(r) ((r ## _V2))
+/* Component registers */
+enum comp_reg_v2 {
+ COMP_CFG_V2 = 4,
+ COMP_TRUST_CFG_V2 = 0x3000,
+};
+
+/* Manager PGD registers */
+enum pgd_reg_v2 {
+ PGD_CFG_V2 = 0x800,
+ PGD_STAT_V2 = 0x804,
+ PGD_INT_EN_V2 = 0x810,
+ PGD_INT_STAT_V2 = 0x814,
+ PGD_INT_CLR_V2 = 0x818,
+ PGD_OWN_EEn_V2 = 0x300C,
+ PGD_PORT_INT_EN_EEn_V2 = 0x5000,
+ PGD_PORT_INT_ST_EEn_V2 = 0x5004,
+ PGD_PORT_INT_CL_EEn_V2 = 0x5008,
+ PGD_PORT_CFGn_V2 = 0x14000,
+ PGD_PORT_STATn_V2 = 0x14004,
+ PGD_PORT_PARAMn_V2 = 0x14008,
+ PGD_PORT_BLKn_V2 = 0x1400C,
+ PGD_PORT_TRANn_V2 = 0x14010,
+ PGD_PORT_MCHANn_V2 = 0x14014,
+ PGD_PORT_PSHPLLn_V2 = 0x14018,
+ PGD_PORT_PC_CFGn_V2 = 0x8000,
+ PGD_PORT_PC_VALn_V2 = 0x8004,
+ PGD_PORT_PC_VFR_TSn_V2 = 0x8008,
+ PGD_PORT_PC_VFR_STn_V2 = 0x800C,
+ PGD_PORT_PC_VFR_CLn_V2 = 0x8010,
+ PGD_IE_STAT_V2 = 0x820,
+ PGD_VE_STAT_V2 = 0x830,
+};
+
+#define PGD_THIS_EE_V1(r) (dev->base + (r ## _V1) + (dev->ee * 16))
+#define PGD_PORT_V1(r, p) (dev->base + (r ## _V1) + ((p) * 32))
+#define CFG_PORT_V1(r) ((r ## _V1))
+/* Component registers */
+enum comp_reg_v1 {
+ COMP_CFG_V1 = 0,
+ COMP_TRUST_CFG_V1 = 0x14,
+};
+
+/* Manager PGD registers */
+enum pgd_reg_v1 {
+ PGD_CFG_V1 = 0x1000,
+ PGD_STAT_V1 = 0x1004,
+ PGD_INT_EN_V1 = 0x1010,
+ PGD_INT_STAT_V1 = 0x1014,
+ PGD_INT_CLR_V1 = 0x1018,
+ PGD_OWN_EEn_V1 = 0x1020,
+ PGD_PORT_INT_EN_EEn_V1 = 0x1030,
+ PGD_PORT_INT_ST_EEn_V1 = 0x1034,
+ PGD_PORT_INT_CL_EEn_V1 = 0x1038,
+ PGD_PORT_CFGn_V1 = 0x1080,
+ PGD_PORT_STATn_V1 = 0x1084,
+ PGD_PORT_PARAMn_V1 = 0x1088,
+ PGD_PORT_BLKn_V1 = 0x108C,
+ PGD_PORT_TRANn_V1 = 0x1090,
+ PGD_PORT_MCHANn_V1 = 0x1094,
+ PGD_PORT_PSHPLLn_V1 = 0x1098,
+ PGD_PORT_PC_CFGn_V1 = 0x1600,
+ PGD_PORT_PC_VALn_V1 = 0x1604,
+ PGD_PORT_PC_VFR_TSn_V1 = 0x1608,
+ PGD_PORT_PC_VFR_STn_V1 = 0x160C,
+ PGD_PORT_PC_VFR_CLn_V1 = 0x1610,
+ PGD_IE_STAT_V1 = 0x1700,
+ PGD_VE_STAT_V1 = 0x1710,
+};
+
+enum msm_ctrl_state {
+ MSM_CTRL_AWAKE,
+ MSM_CTRL_SLEEPING,
+ MSM_CTRL_ASLEEP,
+};
+
+struct msm_slim_sps_bam {
+ u32 hdl;
+ void __iomem *base;
+ int irq;
+};
+
+struct msm_slim_endp {
+ struct sps_pipe *sps;
+ struct sps_connect config;
+ struct sps_register_event event;
+ struct sps_mem_buffer buf;
+ struct completion *xcomp;
+ bool connected;
+};
+
+struct msm_slim_ctrl {
+ struct slim_controller ctrl;
+ struct slim_framer framer;
+ struct device *dev;
+ void __iomem *base;
+ struct resource *slew_mem;
+ u32 curr_bw;
+ u8 msg_cnt;
+ u32 tx_buf[10];
+ u8 rx_msgs[MSM_CONCUR_MSG][SLIM_RX_MSGQ_BUF_LEN];
+ spinlock_t rx_lock;
+ int head;
+ int tail;
+ int irq;
+ int err;
+ int ee;
+ struct completion *wr_comp;
+ struct msm_slim_sat *satd[MSM_MAX_NSATS];
+ struct msm_slim_endp pipes[7];
+ struct msm_slim_sps_bam bam;
+ struct msm_slim_endp rx_msgq;
+ struct completion rx_msgq_notify;
+ struct task_struct *rx_msgq_thread;
+ struct clk *rclk;
+ struct clk *hclk;
+ struct mutex tx_lock;
+ u8 pgdla;
+ bool use_rx_msgqs;
+ int pipe_b;
+ struct completion reconf;
+ bool reconf_busy;
+ bool chan_active;
+ enum msm_ctrl_state state;
+ int nsats;
+ u32 ver;
+};
+
+struct msm_sat_chan {
+ u8 chan;
+ u16 chanh;
+ int req_rem;
+ int req_def;
+ bool reconf;
+};
+
+struct msm_slim_sat {
+ struct slim_device satcl;
+ struct msm_slim_ctrl *dev;
+ struct workqueue_struct *wq;
+ struct work_struct wd;
+ u8 sat_msgs[SAT_CONCUR_MSG][40];
+ struct msm_sat_chan *satch;
+ u8 nsatch;
+ bool sent_capability;
+ bool pending_reconf;
+ bool pending_capability;
+ int shead;
+ int stail;
+ spinlock_t lock;
+};
+
+enum rsc_grp {
+ EE_MGR_RSC_GRP = 1 << 10,
+ EE_NGD_2 = 2 << 6,
+ EE_NGD_1 = 0,
+};
+
+
+int msm_slim_rx_enqueue(struct msm_slim_ctrl *dev, u32 *buf, u8 len);
+int msm_slim_rx_dequeue(struct msm_slim_ctrl *dev, u8 *buf);
+int msm_slim_get_ctrl(struct msm_slim_ctrl *dev);
+void msm_slim_put_ctrl(struct msm_slim_ctrl *dev);
+int msm_slim_init_endpoint(struct msm_slim_ctrl *dev, struct msm_slim_endp *ep);
+void msm_slim_free_endpoint(struct msm_slim_endp *ep);
+void msm_hw_set_port(struct msm_slim_ctrl *dev, u8 pn);
+int msm_slim_connect_pipe_port(struct msm_slim_ctrl *dev, u8 pn);
+int msm_config_port(struct slim_controller *ctrl, u8 pn);
+enum slim_port_err msm_slim_port_xfer_status(struct slim_controller *ctr,
+ u8 pn, u8 **done_buf, u32 *done_len);
+int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, u8 *iobuf,
+ u32 len, struct completion *comp);
+int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg);
+u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len);
+int msm_slim_rx_msgq_get(struct msm_slim_ctrl *dev, u32 *data, int offset);
+int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
+ u32 pipe_reg);
+void msm_slim_sps_exit(struct msm_slim_ctrl *dev);
+#endif
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index 4a79f76..c26da60 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -1298,6 +1298,7 @@
container_of(work, struct msm_spi, work_data);
unsigned long flags;
u32 status_error = 0;
+ int rc = 0;
mutex_lock(&dd->core_lock);
@@ -1308,6 +1309,21 @@
if (dd->use_rlock)
remote_mutex_lock(&dd->r_lock);
+ /* Configure the spi clk, miso, mosi and cs gpio */
+ if (dd->pdata->gpio_config) {
+ rc = dd->pdata->gpio_config();
+ if (rc) {
+ dev_err(dd->dev,
+ "%s: error configuring GPIOs\n",
+ __func__);
+ status_error = 1;
+ }
+ }
+
+ rc = msm_spi_request_gpios(dd);
+ if (rc)
+ status_error = 1;
+
clk_prepare_enable(dd->clk);
clk_prepare_enable(dd->pclk);
msm_spi_enable_irqs(dd);
@@ -1339,6 +1355,12 @@
clk_disable_unprepare(dd->clk);
clk_disable_unprepare(dd->pclk);
+ /* Free the spi clk, miso, mosi, cs gpio */
+ if (!rc && dd->pdata && dd->pdata->gpio_release)
+ dd->pdata->gpio_release();
+ if (!rc)
+ msm_spi_free_gpios(dd);
+
if (dd->use_rlock)
remote_mutex_unlock(&dd->r_lock);
@@ -1425,6 +1447,24 @@
if (dd->use_rlock)
remote_mutex_lock(&dd->r_lock);
+ /* Configure the spi clk, miso, mosi, cs gpio */
+ if (dd->pdata->gpio_config) {
+ rc = dd->pdata->gpio_config();
+ if (rc) {
+ dev_err(&spi->dev,
+ "%s: error configuring GPIOs\n",
+ __func__);
+ rc = -ENXIO;
+ goto err_setup_gpio;
+ }
+ }
+
+ rc = msm_spi_request_gpios(dd);
+ if (rc) {
+ rc = -ENXIO;
+ goto err_setup_gpio;
+ }
+
clk_prepare_enable(dd->clk);
clk_prepare_enable(dd->pclk);
@@ -1457,10 +1497,15 @@
clk_disable_unprepare(dd->clk);
clk_disable_unprepare(dd->pclk);
+ /* Free the spi clk, miso, mosi, cs gpio */
+ if (dd->pdata && dd->pdata->gpio_release)
+ dd->pdata->gpio_release();
+ msm_spi_free_gpios(dd);
+
+err_setup_gpio:
if (dd->use_rlock)
remote_mutex_unlock(&dd->r_lock);
mutex_unlock(&dd->core_lock);
-
err_setup_exit:
return rc;
}
@@ -1897,22 +1942,9 @@
dd->use_dma = 1;
master->dma_alignment = dma_get_cache_alignment();
}
-
-skip_dma_resources:
- if (pdata->gpio_config) {
- rc = pdata->gpio_config();
- if (rc) {
- dev_err(&pdev->dev,
- "%s: error configuring GPIOs\n",
- __func__);
- goto err_probe_gpio;
- }
- }
}
- rc = msm_spi_request_gpios(dd);
- if (rc)
- goto err_probe_gpio;
+skip_dma_resources:
spin_lock_init(&dd->queue_lock);
mutex_init(&dd->core_lock);
@@ -1951,8 +1983,8 @@
dd->use_rlock = 1;
dd->pm_lat = pdata->pm_lat;
- pm_qos_add_request(&qos_req_list, PM_QOS_CPU_DMA_LATENCY,
- PM_QOS_DEFAULT_VALUE);
+ pm_qos_add_request(&qos_req_list, PM_QOS_CPU_DMA_LATENCY,
+ PM_QOS_DEFAULT_VALUE);
}
mutex_lock(&dd->core_lock);
@@ -2082,10 +2114,6 @@
err_probe_reqmem:
destroy_workqueue(dd->workqueue);
err_probe_workq:
- msm_spi_free_gpios(dd);
-err_probe_gpio:
- if (pdata && pdata->gpio_release)
- pdata->gpio_release();
err_probe_res:
spi_master_put(master);
err_probe_exit:
@@ -2112,7 +2140,6 @@
/* Wait for transactions to end, or time out */
wait_event_interruptible(dd->continue_suspend, !dd->transfer_pending);
- msm_spi_free_gpios(dd);
suspend_exit:
return 0;
@@ -2129,7 +2156,6 @@
if (!dd)
goto resume_exit;
- BUG_ON(msm_spi_request_gpios(dd) != 0);
dd->suspended = 0;
resume_exit:
return 0;
@@ -2143,17 +2169,13 @@
{
struct spi_master *master = platform_get_drvdata(pdev);
struct msm_spi *dd = spi_master_get_devdata(master);
- struct msm_spi_platform_data *pdata = pdev->dev.platform_data;
pm_qos_remove_request(&qos_req_list);
spi_debugfs_exit(dd);
sysfs_remove_group(&pdev->dev.kobj, &dev_attr_grp);
msm_spi_teardown_dma(dd);
- if (pdata && pdata->gpio_release)
- pdata->gpio_release();
- msm_spi_free_gpios(dd);
clk_put(dd->clk);
clk_put(dd->pclk);
destroy_workqueue(dd->workqueue);
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index 8724138..c32978e 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -21,7 +21,6 @@
config MSM_QPNP_INT
depends on SPARSE_IRQ
- depends on ARCH_MSM8974
depends on SPMI
depends on OF_SPMI
bool "MSM QPNP INT"
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index ae1eff8..45429a1 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -638,6 +638,12 @@
return -ENODEV;
pmic_arb->channel = (u8)prop;
+ ret = irq_set_irq_wake(pmic_arb->pic_irq, 1);
+ if (unlikely(ret)) {
+ pr_err("Unable to set wakeup irq, err=%d\n", ret);
+ return -ENODEV;
+ }
+
pmic_arb->dev = &pdev->dev;
platform_set_drvdata(pdev, pmic_arb);
spmi_set_ctrldata(&pmic_arb->controller, pmic_arb);
@@ -679,6 +685,7 @@
spmi_del_controller(&pmic_arb->controller);
err_add_controller:
platform_set_drvdata(pdev, NULL);
+ irq_set_irq_wake(pmic_arb->pic_irq, 0);
return ret;
}
@@ -686,7 +693,7 @@
{
struct spmi_pmic_arb_dev *pmic_arb = platform_get_drvdata(pdev);
- free_irq(pmic_arb->pic_irq, pmic_arb);
+ irq_set_irq_wake(pmic_arb->pic_irq, 0);
platform_set_drvdata(pdev, NULL);
spmi_del_controller(&pmic_arb->controller);
return 0;
diff --git a/drivers/thermal/pm8xxx-tm.c b/drivers/thermal/pm8xxx-tm.c
index 50238f3..ec04369 100644
--- a/drivers/thermal/pm8xxx-tm.c
+++ b/drivers/thermal/pm8xxx-tm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -65,10 +65,11 @@
struct pm8xxx_tm_chip {
struct pm8xxx_tm_core_data cdata;
- struct work_struct irq_work;
+ struct delayed_work irq_work;
struct device *dev;
struct thermal_zone_device *tz_dev;
unsigned long temp;
+ unsigned int prev_stage;
enum thermal_device_mode mode;
unsigned int thresh;
unsigned int stage;
@@ -82,6 +83,9 @@
SOFTWARE_OVERRIDE_ENABLED,
};
+/* Delay between TEMP_STAT IRQ going high and status value changing in ms. */
+#define STATUS_REGISTER_DELAY_MS 40
+
static inline int pm8xxx_tm_read_ctrl(struct pm8xxx_tm_chip *chip, u8 *reg)
{
int rc;
@@ -312,6 +316,10 @@
if (!chip)
return -EINVAL;
+ /* Mask software override requests if they are not allowed. */
+ if (!chip->cdata.allow_software_override)
+ mode = THERMAL_DEVICE_DISABLED;
+
if (mode != chip->mode) {
if (mode == THERMAL_DEVICE_ENABLED)
pm8xxx_tm_shutdown_override(chip,
@@ -421,31 +429,18 @@
static void pm8xxx_tm_work(struct work_struct *work)
{
+ struct delayed_work *dwork
+ = container_of(work, struct delayed_work, work);
struct pm8xxx_tm_chip *chip
- = container_of(work, struct pm8xxx_tm_chip, irq_work);
- int rc;
+ = container_of(dwork, struct pm8xxx_tm_chip, irq_work);
+ unsigned long temp = 0;
+ int rc, stage, thresh;
u8 reg;
rc = pm8xxx_tm_read_ctrl(chip, ®);
if (rc < 0)
goto bail;
- if (chip->cdata.adc_type == PM8XXX_TM_ADC_NONE) {
- rc = pm8xxx_tm_update_temp_no_adc(chip);
- if (rc < 0)
- goto bail;
- pr_info("%s: Temp Alarm - stage=%u, threshold=%u, "
- "temp=%lu mC\n", chip->cdata.tm_name, chip->stage,
- chip->thresh, chip->temp);
- } else {
- chip->stage = (reg & TEMP_ALARM_CTRL_STATUS_MASK)
- >> TEMP_ALARM_CTRL_STATUS_SHIFT;
- chip->thresh = (reg & TEMP_ALARM_CTRL_THRESH_MASK)
- >> TEMP_ALARM_CTRL_THRESH_SHIFT;
- pr_info("%s: Temp Alarm - stage=%u, threshold=%u\n",
- chip->cdata.tm_name, chip->stage, chip->thresh);
- }
-
/* Clear status bits. */
if (reg & (TEMP_ALARM_CTRL_ST2_SD | TEMP_ALARM_CTRL_ST3_SD)) {
reg &= ~(TEMP_ALARM_CTRL_ST2_SD | TEMP_ALARM_CTRL_ST3_SD
@@ -454,24 +449,47 @@
pm8xxx_tm_write_ctrl(chip, reg);
}
+ stage = (reg & TEMP_ALARM_CTRL_STATUS_MASK)
+ >> TEMP_ALARM_CTRL_STATUS_SHIFT;
+ thresh = (reg & TEMP_ALARM_CTRL_THRESH_MASK)
+ >> TEMP_ALARM_CTRL_THRESH_SHIFT;
+
thermal_zone_device_update(chip->tz_dev);
- /* Notify user space */
- if (chip->mode == THERMAL_DEVICE_ENABLED)
- kobject_uevent(&chip->tz_dev->device.kobj, KOBJ_CHANGE);
+ if (stage != chip->prev_stage) {
+ chip->prev_stage = stage;
+
+ switch (chip->cdata.adc_type) {
+ case PM8XXX_TM_ADC_NONE:
+ rc = pm8xxx_tz_get_temp_no_adc(chip->tz_dev, &temp);
+ break;
+ case PM8XXX_TM_ADC_PM8058_ADC:
+ rc = pm8xxx_tz_get_temp_pm8058_adc(chip->tz_dev, &temp);
+ break;
+ case PM8XXX_TM_ADC_PM8XXX_ADC:
+ rc = pm8xxx_tz_get_temp_pm8xxx_adc(chip->tz_dev, &temp);
+ break;
+ }
+ if (rc < 0)
+ goto bail;
+
+ pr_crit("%s: PMIC Temp Alarm - stage=%u, threshold=%u, temp=%lu mC\n",
+ chip->cdata.tm_name, stage, thresh, temp);
+
+ /* Notify user space */
+ sysfs_notify(&chip->tz_dev->device.kobj, NULL, "type");
+ }
bail:
- enable_irq(chip->tempstat_irq);
- enable_irq(chip->overtemp_irq);
+ return;
}
static irqreturn_t pm8xxx_tm_isr(int irq, void *data)
{
struct pm8xxx_tm_chip *chip = data;
- disable_irq_nosync(chip->tempstat_irq);
- disable_irq_nosync(chip->overtemp_irq);
- schedule_work(&chip->irq_work);
+ schedule_delayed_work(&chip->irq_work,
+ msecs_to_jiffies(STATUS_REGISTER_DELAY_MS) + 1);
return IRQ_HANDLED;
}
@@ -610,7 +628,7 @@
chip->mode = THERMAL_DEVICE_DISABLED;
thermal_zone_device_update(chip->tz_dev);
- INIT_WORK(&chip->irq_work, pm8xxx_tm_work);
+ INIT_DELAYED_WORK(&chip->irq_work, pm8xxx_tm_work);
rc = request_irq(chip->tempstat_irq, pm8xxx_tm_isr, IRQF_TRIGGER_RISING,
chip->cdata.irq_name_temp_stat, chip);
@@ -635,7 +653,7 @@
err_free_irq_tempstat:
free_irq(chip->tempstat_irq, chip);
err_cancel_work:
- cancel_work_sync(&chip->irq_work);
+ cancel_delayed_work_sync(&chip->irq_work);
err_free_tz:
thermal_zone_device_unregister(chip->tz_dev);
err_fail_adc:
@@ -651,7 +669,7 @@
if (chip) {
platform_set_drvdata(pdev, NULL);
- cancel_work_sync(&chip->irq_work);
+ cancel_delayed_work_sync(&chip->irq_work);
free_irq(chip->overtemp_irq, chip);
free_irq(chip->tempstat_irq, chip);
pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
diff --git a/drivers/usb/gadget/ci13xxx_msm_hsic.c b/drivers/usb/gadget/ci13xxx_msm_hsic.c
index 6faaf78..b0b9468 100644
--- a/drivers/usb/gadget/ci13xxx_msm_hsic.c
+++ b/drivers/usb/gadget/ci13xxx_msm_hsic.c
@@ -67,6 +67,7 @@
struct work_struct suspend_w;
struct msm_hsic_peripheral_platform_data *pdata;
enum usb_vdd_type vdd_type;
+ bool connected;
};
static const int vdd_val[VDD_TYPE_MAX][VDD_VAL_MAX] = {
@@ -381,7 +382,7 @@
*/
mb();
- if (!mhsic->pdata->core_clk_always_on_workaround) {
+ if (!mhsic->pdata->core_clk_always_on_workaround || !mhsic->connected) {
clk_disable(mhsic->iface_clk);
clk_disable(mhsic->core_clk);
}
@@ -438,7 +439,7 @@
dev_err(mhsic->dev, "%s failed to vote for TCXO %d\n",
__func__, ret);
- if (!mhsic->pdata->core_clk_always_on_workaround) {
+ if (!mhsic->pdata->core_clk_always_on_workaround || !mhsic->connected) {
clk_enable(mhsic->iface_clk);
clk_enable(mhsic->core_clk);
}
@@ -598,22 +599,38 @@
switch (event) {
case CI13XXX_CONTROLLER_RESET_EVENT:
- dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
+ dev_info(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
writel_relaxed(0, USB_AHBBURST);
writel_relaxed(0x08, USB_AHBMODE);
break;
case CI13XXX_CONTROLLER_CONNECT_EVENT:
- dev_dbg(dev, "CI13XXX_CONTROLLER_CONNECT_EVENT received\n");
- msm_hsic_start();
+ dev_info(dev, "CI13XXX_CONTROLLER_CONNECT_EVENT received\n");
+ msm_hsic_wakeup();
+ the_mhsic->connected = true;
break;
case CI13XXX_CONTROLLER_SUSPEND_EVENT:
- dev_dbg(dev, "CI13XXX_CONTROLLER_SUSPEND_EVENT received\n");
+ dev_info(dev, "CI13XXX_CONTROLLER_SUSPEND_EVENT received\n");
queue_work(mhsic->wq, &mhsic->suspend_w);
break;
case CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT:
- dev_dbg(dev, "CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT received\n");
+ dev_info(dev, "CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT received\n");
msm_hsic_wakeup();
break;
+ case CI13XXX_CONTROLLER_UDC_STARTED_EVENT:
+ dev_info(dev, "CI13XXX_CONTROLLER_UDC_STARTED_EVENT received\n");
+ /*
+ * UDC started, suspend the hsic device until it will be
+ * connected by a pullup (CI13XXX_CONTROLLER_CONNECT_EVENT)
+ * Before suspend, finish required configurations.
+ */
+ hw_device_state(_udc->ep0out.qh.dma);
+ msm_hsic_start();
+ usleep(10000);
+
+ mhsic->connected = false;
+ pm_runtime_put_noidle(the_mhsic->dev);
+ pm_runtime_suspend(the_mhsic->dev);
+ break;
default:
dev_dbg(dev, "unknown ci13xxx_udc event\n");
break;
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 831e970..5b39336 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -3205,6 +3205,11 @@
spin_unlock_irqrestore(udc->lock, flags);
if (retval || put)
pm_runtime_put_sync(&udc->gadget.dev);
+
+ if (udc->udc_driver->notify_event)
+ udc->udc_driver->notify_event(udc,
+ CI13XXX_CONTROLLER_UDC_STARTED_EVENT);
+
return retval;
}
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 6527b76..3162e15 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -126,6 +126,8 @@
#define CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT 3
#define CI13XXX_CONTROLLER_RESUME_EVENT 4
#define CI13XXX_CONTROLLER_DISCONNECT_EVENT 5
+#define CI13XXX_CONTROLLER_UDC_STARTED_EVENT 6
+
void (*notify_event) (struct ci13xxx *udc, unsigned event);
};
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index 1d0b6d4..aa9daf3 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -488,6 +488,8 @@
break;
case USB_GADGET_XPORT_HSIC:
break;
+ case USB_GADGET_XPORT_HSUART:
+ break;
case USB_GADGET_XPORT_NONE:
break;
default:
@@ -515,6 +517,8 @@
break;
case USB_GADGET_XPORT_HSIC:
break;
+ case USB_GADGET_XPORT_HSUART:
+ break;
case USB_GADGET_XPORT_NONE:
break;
default:
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index a9e5d91..45dfb87 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -640,26 +640,6 @@
clear_bit(BAM_CH_OPENED, &d->flags);
}
-static void gbam2bam_disconnect_work(struct work_struct *w)
-{
- struct gbam_port *port =
- container_of(w, struct gbam_port, disconnect_w);
- unsigned long flags;
-
- spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock(&port->port_lock_dl);
- port->port_usb = 0;
- spin_unlock(&port->port_lock_dl);
- spin_unlock_irqrestore(&port->port_lock_ul, flags);
-
- /* disable endpoints */
- usb_ep_disable(port->gr->out);
- usb_ep_disable(port->gr->in);
-
- port->gr->in->driver_data = NULL;
- port->gr->out->driver_data = NULL;
-}
-
static void gbam_connect_work(struct work_struct *w)
{
struct gbam_port *port = container_of(w, struct gbam_port, connect_w);
@@ -699,29 +679,6 @@
struct bam_ch_info *d = &port->data_ch;
u32 sps_params;
int ret;
- unsigned long flags;
-
- ret = usb_ep_enable(port->gr->in);
- if (ret) {
- pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
- __func__, port->gr->in);
- return;
- }
- port->gr->in->driver_data = port;
-
- ret = usb_ep_enable(port->gr->out);
- if (ret) {
- pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
- __func__, port->gr->out);
- port->gr->in->driver_data = 0;
- return;
- }
- port->gr->out->driver_data = port;
- spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock(&port->port_lock_dl);
- port->port_usb = port->gr;
- spin_unlock(&port->port_lock_dl);
- spin_unlock_irqrestore(&port->port_lock_ul, flags);
ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
&d->dst_pipe_idx);
@@ -916,7 +873,6 @@
spin_lock_init(&port->port_lock_dl);
INIT_WORK(&port->connect_w, gbam2bam_connect_work);
- INIT_WORK(&port->disconnect_w, gbam2bam_disconnect_work);
/* data ch */
d = &port->data_ch;
@@ -1071,7 +1027,7 @@
d = &port->data_ch;
port->gr = gr;
- if (trans == USB_GADGET_XPORT_BAM) {
+ if (trans == USB_GADGET_XPORT_BAM)
gbam_free_buffers(port);
spin_lock_irqsave(&port->port_lock_ul, flags);
@@ -1081,12 +1037,15 @@
spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
- /* disable endpoints */
- usb_ep_disable(gr->out);
- usb_ep_disable(gr->in);
- }
+ /* disable endpoints */
+ usb_ep_disable(gr->out);
+ usb_ep_disable(gr->in);
- queue_work(gbam_wq, &port->disconnect_w);
+ gr->in->driver_data = NULL;
+ gr->out->driver_data = NULL;
+
+ if (trans == USB_GADGET_XPORT_BAM)
+ queue_work(gbam_wq, &port->disconnect_w);
}
int gbam_connect(struct grmnet *gr, u8 port_num,
@@ -1121,36 +1080,37 @@
d = &port->data_ch;
- if (trans == USB_GADGET_XPORT_BAM) {
- ret = usb_ep_enable(gr->in);
- if (ret) {
- pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
- __func__, gr->in);
- return ret;
- }
- gr->in->driver_data = port;
+ ret = usb_ep_enable(gr->in);
+ if (ret) {
+ pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
+ __func__, gr->in);
+ return ret;
+ }
+ gr->in->driver_data = port;
- ret = usb_ep_enable(gr->out);
- if (ret) {
- pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
- __func__, gr->out);
- gr->in->driver_data = 0;
- return ret;
- }
- gr->out->driver_data = port;
+ ret = usb_ep_enable(gr->out);
+ if (ret) {
+ pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
+ __func__, gr->out);
+ gr->in->driver_data = 0;
+ return ret;
+ }
+ gr->out->driver_data = port;
spin_lock_irqsave(&port->port_lock_ul, flags);
spin_lock(&port->port_lock_dl);
port->port_usb = gr;
+ if (trans == USB_GADGET_XPORT_BAM) {
d->to_host = 0;
d->to_modem = 0;
d->pending_with_bam = 0;
d->tohost_drp_cnt = 0;
d->tomodem_drp_cnt = 0;
+ }
+
spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
- }
if (trans == USB_GADGET_XPORT_BAM2BAM) {
port->gr = gr;
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index cad411d..b1b7763 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -60,6 +60,11 @@
return -ENODEV;
}
+ if (dev->ops) {
+ pr_err("bridge already opened");
+ return -EALREADY;
+ }
+
dev->ops = ops;
dev->err = 0;
@@ -82,6 +87,16 @@
{
struct diag_bridge *dev = __dev;
+ if (!dev) {
+ pr_err("dev is null");
+ return;
+ }
+
+ if (!dev->ops) {
+ pr_err("can't close bridge that was not open");
+ return;
+ }
+
dev_dbg(&dev->ifc->dev, "%s:\n", __func__);
usb_kill_anchored_urbs(&dev->submitted);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index a6d8c17..5637f19 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -67,6 +67,8 @@
#define USB_PHY_VDD_DIG_VOL_MIN 1045000 /* uV */
#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */
+#define USB_SUSPEND_DELAY_TIME (500 * HZ/1000) /* 500 msec */
+
static DECLARE_COMPLETION(pmic_vbus_init);
static struct msm_otg *the_msm_otg;
static bool debug_aca_enabled;
@@ -686,7 +688,8 @@
if (aca_enabled())
return 0;
- if (atomic_read(&motg->in_lpm) == suspend)
+ if (atomic_read(&motg->in_lpm) == suspend &&
+ !atomic_read(&motg->suspend_work_pending))
return 0;
if (suspend) {
@@ -705,7 +708,9 @@
if (!(motg->caps & ALLOW_LPM_ON_DEV_SUSPEND))
break;
set_bit(A_BUS_SUSPEND, &motg->inputs);
- queue_work(system_nrt_wq, &motg->sm_work);
+ atomic_set(&motg->suspend_work_pending, 1);
+ queue_delayed_work(system_nrt_wq, &motg->suspend_work,
+ USB_SUSPEND_DELAY_TIME);
break;
default:
@@ -2752,6 +2757,14 @@
queue_work(system_nrt_wq, &motg->sm_work);
}
+static void msm_otg_suspend_work(struct work_struct *w)
+{
+ struct msm_otg *motg =
+ container_of(w, struct msm_otg, suspend_work.work);
+ atomic_set(&motg->suspend_work_pending, 0);
+ msm_otg_sm_work(&motg->sm_work);
+}
+
static irqreturn_t msm_otg_irq(int irq, void *data)
{
struct msm_otg *motg = data;
@@ -3629,6 +3642,7 @@
INIT_WORK(&motg->sm_work, msm_otg_sm_work);
INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work);
INIT_DELAYED_WORK(&motg->pmic_id_status_work, msm_pmic_id_status_w);
+ INIT_DELAYED_WORK(&motg->suspend_work, msm_otg_suspend_work);
setup_timer(&motg->id_timer, msm_otg_id_timer_func,
(unsigned long) motg);
ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED,
@@ -3791,6 +3805,7 @@
msm_otg_debugfs_cleanup();
cancel_delayed_work_sync(&motg->chg_work);
cancel_delayed_work_sync(&motg->pmic_id_status_work);
+ cancel_delayed_work_sync(&motg->suspend_work);
cancel_work_sync(&motg->sm_work);
pm_runtime_resume(&pdev->dev);
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 4fc78cd..6e3567f 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -53,7 +53,7 @@
u32 mdp_max_clk = 200000000;
static struct platform_device *mdp_init_pdev;
-static struct regulator *footswitch;
+static struct regulator *footswitch, *dsi_pll_vdda, *dsi_pll_vddio;
static unsigned int mdp_footswitch_on;
struct completion mdp_ppp_comp;
@@ -2244,18 +2244,40 @@
}
disable_irq(mdp_irq);
+ dsi_pll_vdda = regulator_get(&pdev->dev, "dsi_pll_vdda");
+ if (IS_ERR(dsi_pll_vdda)) {
+ dsi_pll_vdda = NULL;
+ } else {
+ if (mdp_rev == MDP_REV_42 || mdp_rev == MDP_REV_44) {
+ ret = regulator_set_voltage(dsi_pll_vdda, 1200000,
+ 1200000);
+ if (ret) {
+ pr_err("set_voltage failed for dsi_pll_vdda, ret=%d\n",
+ ret);
+ }
+ }
+ }
+
+ dsi_pll_vddio = regulator_get(&pdev->dev, "dsi_pll_vddio");
+ if (IS_ERR(dsi_pll_vddio)) {
+ dsi_pll_vddio = NULL;
+ } else {
+ if (mdp_rev == MDP_REV_42) {
+ ret = regulator_set_voltage(dsi_pll_vddio, 1800000,
+ 1800000);
+ if (ret) {
+ pr_err("set_voltage failed for dsi_pll_vddio, ret=%d\n",
+ ret);
+ }
+ }
+ }
+
footswitch = regulator_get(&pdev->dev, "vdd");
- if (IS_ERR(footswitch))
+ if (IS_ERR(footswitch)) {
footswitch = NULL;
- else {
+ } else {
regulator_enable(footswitch);
mdp_footswitch_on = 1;
-
- if (mdp_rev == MDP_REV_42 && !cont_splashScreen) {
- regulator_disable(footswitch);
- msleep(20);
- regulator_enable(footswitch);
- }
}
mdp_clk = clk_get(&pdev->dev, "core_clk");
@@ -2306,6 +2328,17 @@
MSM_FB_DEBUG("mdp_clk: mdp_clk=%d\n", (int)clk_get_rate(mdp_clk));
#endif
+
+ if (mdp_rev == MDP_REV_42 && !cont_splashScreen) {
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ /* DSI Video Timing generator disable */
+ outpdw(MDP_BASE + 0xE0000, 0x0);
+ /* Clear MDP Interrupt Enable register */
+ outpdw(MDP_BASE + 0x50, 0x0);
+ /* Set Overlay Proc 0 to reset state */
+ outpdw(MDP_BASE + 0x10004, 0x3);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ }
return 0;
}
@@ -2324,6 +2357,7 @@
struct mipi_panel_info *mipi;
#endif
static int contSplash_update_done;
+ char *cp;
if ((pdev->id == 0) && (pdev->num_resources > 0)) {
mdp_init_pdev = pdev;
@@ -2398,7 +2432,44 @@
if (mdp_pdata) {
if (mdp_pdata->cont_splash_enabled) {
mfd->cont_splash_done = 0;
+
if (!contSplash_update_done) {
+ uint32 bpp = 3;
+ /*read panel wxh and calculate splash screen
+ size*/
+ mdp_pdata->splash_screen_size =
+ inpdw(MDP_BASE + 0x90004);
+ mdp_pdata->splash_screen_size =
+ (((mdp_pdata->splash_screen_size >> 16) &
+ 0x00000FFF) * (
+ mdp_pdata->splash_screen_size &
+ 0x00000FFF)) * bpp;
+
+ mdp_pdata->splash_screen_addr =
+ inpdw(MDP_BASE + 0x90008);
+
+ mfd->copy_splash_buf = dma_alloc_coherent(NULL,
+ mdp_pdata->splash_screen_size,
+ (dma_addr_t *) &(mfd->copy_splash_phys),
+ GFP_KERNEL);
+
+ if (!mfd->copy_splash_buf) {
+ pr_err("DMA ALLOC FAILED for SPLASH\n");
+ return -ENOMEM;
+ }
+ cp = (char *)ioremap(
+ mdp_pdata->splash_screen_addr,
+ mdp_pdata->splash_screen_size);
+ if (!cp) {
+ pr_err("IOREMAP FAILED for SPLASH\n");
+ return -ENOMEM;
+ }
+ memcpy(mfd->copy_splash_buf, cp,
+ mdp_pdata->splash_screen_size);
+
+ MDP_OUTP(MDP_BASE + 0x90008,
+ mfd->copy_splash_phys);
+
if (mfd->panel.type == MIPI_VIDEO_PANEL ||
mfd->panel.type == LCDC_PANEL)
mdp_pipe_ctrl(MDP_CMD_BLOCK,
@@ -2774,6 +2845,17 @@
return;
}
+ if (dsi_pll_vddio)
+ regulator_enable(dsi_pll_vddio);
+
+ if (dsi_pll_vdda)
+ regulator_enable(dsi_pll_vdda);
+
+ mipi_dsi_prepare_clocks();
+ mipi_dsi_ahb_ctrl(1);
+ mipi_dsi_phy_ctrl(1);
+ mipi_dsi_clk_enable();
+
if (on && !mdp_footswitch_on) {
pr_debug("Enable MDP FS\n");
regulator_enable(footswitch);
@@ -2784,9 +2866,31 @@
mdp_footswitch_on = 0;
}
+ mipi_dsi_clk_disable();
+ mipi_dsi_phy_ctrl(0);
+ mipi_dsi_ahb_ctrl(0);
+ mipi_dsi_unprepare_clocks();
+
+ if (dsi_pll_vdda)
+ regulator_disable(dsi_pll_vdda);
+
+ if (dsi_pll_vddio)
+ regulator_disable(dsi_pll_vddio);
+
mutex_unlock(&mdp_suspend_mutex);
}
+void mdp_free_splash_buffer(struct msm_fb_data_type *mfd)
+{
+ if (mfd->copy_splash_buf) {
+ dma_free_coherent(NULL, mdp_pdata->splash_screen_size,
+ mfd->copy_splash_buf,
+ (dma_addr_t) mfd->copy_splash_phys);
+
+ mfd->copy_splash_buf = NULL;
+ }
+}
+
#ifdef CONFIG_PM
static void mdp_suspend_sub(void)
{
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index af5a661..1397507 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -24,7 +24,7 @@
#include <linux/msm_mdp.h>
#include <linux/memory_alloc.h>
#include <mach/hardware.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#ifdef CONFIG_MSM_BUS_SCALING
#include <mach/msm_bus.h>
@@ -764,7 +764,7 @@
int mdp_lcdc_on(struct platform_device *pdev);
int mdp_lcdc_off(struct platform_device *pdev);
void mdp_lcdc_update(struct msm_fb_data_type *mfd);
-
+void mdp_free_splash_buffer(struct msm_fb_data_type *mfd);
#ifdef CONFIG_FB_MSM_MDP303
int mdp_dsi_video_on(struct platform_device *pdev);
int mdp_dsi_video_off(struct platform_device *pdev);
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 5613398..6f42565 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -14,7 +14,7 @@
#ifndef MDSS_H
#define MDSS_H
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <linux/msm_mdp.h>
#include <linux/spinlock.h>
#include <linux/types.h>
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 5432df0..06d8769 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1137,6 +1137,31 @@
return 0;
}
+static int mdss_fb_handle_pp_ioctl(void __user *argp)
+{
+ int ret;
+ struct msmfb_mdp_pp mdp_pp;
+ u32 copyback = 0;
+
+ ret = copy_from_user(&mdp_pp, argp, sizeof(mdp_pp));
+ if (ret)
+ return ret;
+
+ switch (mdp_pp.op) {
+ case mdp_op_pa_cfg:
+ ret = mdss_mdp_pa_config(&mdp_pp.data.pa_cfg_data,
+ ©back);
+ break;
+ default:
+ pr_err("Unsupported request to MDP_PP IOCTL.\n");
+ ret = -EINVAL;
+ break;
+ }
+ if ((ret == 0) && copyback)
+ ret = copy_to_user(argp, &mdp_pp, sizeof(struct msmfb_mdp_pp));
+ return ret;
+}
+
static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
@@ -1163,6 +1188,10 @@
return ret;
break;
+ case MSMFB_MDP_PP:
+ ret = mdss_fb_handle_pp_ioctl(argp);
+ break;
+
default:
if (mfd->ioctl_handler)
ret = mfd->ioctl_handler(mfd, cmd, argp);
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 342ebb8..a10e5e4 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -14,7 +14,7 @@
#ifndef MDSS_FB_H
#define MDSS_FB_H
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <linux/list.h>
#include <linux/msm_mdp.h>
#include <linux/types.h>
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index b88ff72..9278029 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -1172,6 +1172,41 @@
return rc;
} /* hdmi_tx_clk_ctrl_update */
+static int hdmi_tx_config_power(struct hdmi_tx_ctrl *hdmi_ctrl,
+ enum hdmi_tx_power_module_type module, int config)
+{
+ int rc = 0;
+ struct dss_module_power *power_data = NULL;
+
+ if (!hdmi_ctrl || module >= HDMI_TX_MAX_PM) {
+ DEV_ERR("%s: Error: invalid input\n", __func__);
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ power_data = &hdmi_ctrl->pdata.power_data[module];
+ if (!power_data) {
+ DEV_ERR("%s: Error: invalid power data\n", __func__);
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ if (config)
+ rc = msm_dss_config_vreg(&hdmi_ctrl->pdev->dev,
+ power_data->vreg_config, power_data->num_vreg, 1);
+ else
+ rc = msm_dss_config_vreg(&hdmi_ctrl->pdev->dev,
+ power_data->vreg_config, power_data->num_vreg, 0);
+
+ if (rc)
+ DEV_ERR("%s: Failed to %s %s vreg. Error=%d\n",
+ __func__, config ? "config" : "deconfig",
+ hdmi_pm_name(module), rc);
+
+exit:
+ return rc;
+} /* hdmi_tx_config_power */
+
static int hdmi_tx_enable_power(struct hdmi_tx_ctrl *hdmi_ctrl,
enum hdmi_tx_power_module_type module, int enable)
{
@@ -1192,20 +1227,12 @@
}
if (enable) {
- rc = msm_dss_config_vreg(&hdmi_ctrl->pdev->dev,
- power_data->vreg_config, power_data->num_vreg, 1);
- if (rc) {
- DEV_ERR("%s: Failed to config %s vreg. Error=%d\n",
- __func__, hdmi_pm_name(module), rc);
- return rc;
- }
-
rc = msm_dss_enable_vreg(power_data->vreg_config,
power_data->num_vreg, 1);
if (rc) {
DEV_ERR("%s: Failed to enable %s vreg. Error=%d\n",
__func__, hdmi_pm_name(module), rc);
- goto deconfig_vreg;
+ goto error;
}
rc = msm_dss_enable_gpio(power_data->gpio_config,
@@ -1218,15 +1245,14 @@
} else {
msm_dss_enable_gpio(power_data->gpio_config,
power_data->num_gpio, 0);
+ msm_dss_enable_vreg(power_data->vreg_config,
+ power_data->num_vreg, 0);
}
return rc;
disable_vreg:
msm_dss_enable_vreg(power_data->vreg_config, power_data->num_vreg, 0);
-deconfig_vreg:
- msm_dss_config_vreg(&hdmi_ctrl->pdev->dev, power_data->vreg_config,
- power_data->num_vreg, 0);
error:
return rc;
} /* hdmi_tx_enable_power */
@@ -1833,6 +1859,84 @@
return rc;
} /* hdmi_tx_register_panel */
+static void hdmi_tx_deinit_resource(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ int i;
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return;
+ }
+
+ /* CLK */
+ hdmi_tx_clk_deinit(&hdmi_ctrl->pdata);
+
+ /* VREG */
+ for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--) {
+ if (hdmi_tx_config_power(hdmi_ctrl, i, 0))
+ DEV_ERR("%s: '%s' power deconfig fail\n",
+ __func__, hdmi_pm_name(i));
+ }
+
+ /* IO */
+ for (i = HDMI_TX_MAX_IO - 1; i >= 0; i--) {
+ if (hdmi_ctrl->pdata.io[i].base)
+ iounmap(hdmi_ctrl->pdata.io[i].base);
+ hdmi_ctrl->pdata.io[i].base = NULL;
+ hdmi_ctrl->pdata.io[i].len = 0;
+ }
+} /* hdmi_tx_deinit_resource */
+
+static int hdmi_tx_init_resource(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ int i, rc = 0;
+ struct hdmi_tx_platform_data *pdata = NULL;
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return -EINVAL;
+ }
+
+ pdata = &hdmi_ctrl->pdata;
+
+ /* IO */
+ for (i = 0; i < HDMI_TX_MAX_IO; i++) {
+ rc = msm_dss_ioremap_byname(hdmi_ctrl->pdev, &pdata->io[i],
+ hdmi_tx_io_name(i));
+ if (rc) {
+ DEV_ERR("%s: '%s' remap failed\n", __func__,
+ hdmi_tx_io_name(i));
+ goto error;
+ }
+ DEV_INFO("%s: '%s': start = 0x%x, len=0x%x\n", __func__,
+ hdmi_tx_io_name(i), (u32)pdata->io[i].base,
+ pdata->io[i].len);
+ }
+
+ /* VREG */
+ for (i = 0; i < HDMI_TX_MAX_PM; i++) {
+ rc = hdmi_tx_config_power(hdmi_ctrl, i, 1);
+ if (rc) {
+ DEV_ERR("%s: '%s' power config failed.rc=%d\n",
+ __func__, hdmi_pm_name(i), rc);
+ goto error;
+ }
+ }
+
+ /* CLK */
+ rc = hdmi_tx_clk_init(hdmi_ctrl->pdev, pdata);
+ if (rc) {
+ DEV_ERR("%s: FAILED: clk init. rc=%d\n", __func__, rc);
+ goto error;
+ }
+
+ return rc;
+
+error:
+ hdmi_tx_deinit_resource(hdmi_ctrl);
+ return rc;
+} /* hdmi_tx_init_resource */
+
static void hdmi_tx_put_dt_vreg_data(struct device *dev,
struct dss_module_power *module_power)
{
@@ -2179,20 +2283,11 @@
return;
}
- hdmi_tx_clk_deinit(pdata);
-
for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
hdmi_tx_put_dt_vreg_data(dev, &pdata->power_data[i]);
for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
hdmi_tx_put_dt_gpio_data(dev, &pdata->power_data[i]);
-
- for (i = HDMI_TX_MAX_IO - 1; i >= 0; i--) {
- if (pdata->io[i].base)
- iounmap(pdata->io[i].base);
- pdata->io[i].base = NULL;
- pdata->io[i].len = 0;
- }
} /* hdmi_tx_put_dt_data */
static int hdmi_tx_get_dt_data(struct platform_device *pdev,
@@ -2216,20 +2311,6 @@
}
DEV_DBG("%s: id=%d\n", __func__, pdev->id);
- /* IO */
- for (i = 0; i < HDMI_TX_MAX_IO; i++) {
- rc = msm_dss_ioremap_byname(pdev, &pdata->io[i],
- hdmi_tx_io_name(i));
- if (rc) {
- DEV_ERR("%s: '%s' remap failed\n", __func__,
- hdmi_tx_io_name(i));
- goto error;
- }
- DEV_INFO("%s: '%s': start = 0x%x, len=0x%x\n", __func__,
- hdmi_tx_io_name(i), (u32)pdata->io[i].base,
- pdata->io[i].len);
- }
-
/* GPIO */
for (i = 0; i < HDMI_TX_MAX_PM; i++) {
rc = hdmi_tx_get_dt_gpio_data(&pdev->dev,
@@ -2252,13 +2333,6 @@
}
}
- /* CLK */
- rc = hdmi_tx_clk_init(pdev, pdata);
- if (rc) {
- DEV_ERR("%s: FAILED: clk init. rc=%d\n", __func__, rc);
- goto error;
- }
-
return rc;
error:
@@ -2295,6 +2369,13 @@
goto failed_dt_data;
}
+ rc = hdmi_tx_init_resource(hdmi_ctrl);
+ if (rc) {
+ DEV_ERR("%s: FAILED: resource init. rc=%d\n",
+ __func__, rc);
+ goto failed_res_init;
+ }
+
rc = hdmi_tx_dev_init(hdmi_ctrl);
if (rc) {
DEV_ERR("%s: FAILED: hdmi_tx_dev_init. rc=%d\n", __func__, rc);
@@ -2327,6 +2408,8 @@
failed_reg_panel:
hdmi_tx_dev_deinit(hdmi_ctrl);
failed_dev_init:
+ hdmi_tx_deinit_resource(hdmi_ctrl);
+failed_res_init:
hdmi_tx_put_dt_data(&pdev->dev, &hdmi_ctrl->pdata);
failed_dt_data:
devm_kfree(&pdev->dev, hdmi_ctrl);
@@ -2344,6 +2427,7 @@
hdmi_tx_sysfs_remove(hdmi_ctrl);
hdmi_tx_dev_deinit(hdmi_ctrl);
+ hdmi_tx_deinit_resource(hdmi_ctrl);
hdmi_tx_put_dt_data(&pdev->dev, &hdmi_ctrl->pdata);
devm_kfree(&hdmi_ctrl->pdev->dev, hdmi_ctrl);
diff --git a/drivers/video/msm/mdss/mdss_io_util.c b/drivers/video/msm/mdss/mdss_io_util.c
index c121772..65d08d3 100644
--- a/drivers/video/msm/mdss/mdss_io_util.c
+++ b/drivers/video/msm/mdss/mdss_io_util.c
@@ -32,7 +32,7 @@
{
struct resource *res = NULL;
- if (!pdev) {
+ if (!pdev || !io_data) {
pr_err("%s: invalid input\n", __func__);
return -EINVAL;
}
@@ -65,10 +65,11 @@
curr_vreg = &in_vreg[i];
curr_vreg->vreg = regulator_get(dev,
curr_vreg->vreg_name);
- if (IS_ERR(curr_vreg->vreg)) {
- pr_err("%s: %s get failed\n",
+ rc = IS_ERR(curr_vreg->vreg);
+ if (rc) {
+ pr_err("%s: %s get failed. rc=%d\n",
__func__,
- curr_vreg->vreg_name);
+ curr_vreg->vreg_name, rc);
curr_vreg->vreg = NULL;
goto vreg_get_fail;
}
@@ -100,8 +101,7 @@
} else {
for (i = num_vreg-1; i >= 0; i--) {
curr_vreg = &in_vreg[i];
- if (curr_vreg->vreg &&
- regulator_is_enabled(curr_vreg->vreg)) {
+ if (curr_vreg->vreg) {
if (curr_vreg->type == DSS_REG_LDO) {
if (curr_vreg->optimum_voltage >= 0) {
regulator_set_optimum_mode(
@@ -134,7 +134,7 @@
curr_vreg = &in_vreg[i];
goto vreg_unconfig;
}
- return -EPERM;
+ return rc;
} /* msm_dss_config_vreg */
int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg, int enable)
@@ -142,9 +142,10 @@
int i = 0, rc = 0;
if (enable) {
for (i = 0; i < num_vreg; i++) {
- if (IS_ERR(in_vreg[i].vreg)) {
- pr_err("%s: %s null regulator\n",
- __func__, in_vreg[i].vreg_name);
+ rc = IS_ERR(in_vreg[i].vreg);
+ if (rc) {
+ pr_err("%s: %s regulator error. rc=%d\n",
+ __func__, in_vreg[i].vreg_name, rc);
goto disable_vreg;
}
rc = regulator_enable(in_vreg[i].vreg);
@@ -156,7 +157,8 @@
}
} else {
for (i = num_vreg-1; i >= 0; i--)
- regulator_disable(in_vreg[i].vreg);
+ if (regulator_is_enabled(in_vreg[i].vreg))
+ regulator_disable(in_vreg[i].vreg);
}
return rc;
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 80e056f..3fb70bd 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -846,10 +846,17 @@
pr_err("unable to initialize mdss mdp resources\n");
goto probe_done;
}
+ rc = mdss_mdp_pp_init(&pdev->dev);
+ if (rc) {
+ pr_err("unable to initialize mdss pp resources\n");
+ goto probe_done;
+ }
rc = mdss_mdp_bus_scale_register(mdata);
probe_done:
- if (IS_ERR_VALUE(rc))
+ if (IS_ERR_VALUE(rc)) {
mdss_res = NULL;
+ mdss_mdp_pp_term(&pdev->dev);
+ }
return rc;
}
@@ -942,6 +949,7 @@
if (!mdata)
return -ENODEV;
pm_runtime_disable(&pdev->dev);
+ mdss_mdp_pp_term(&pdev->dev);
mdss_mdp_bus_scale_unregister(mdata);
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index a77c18e..610c132 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -295,7 +295,7 @@
int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg);
int mdss_mdp_csc_setup(u32 block, u32 blk_idx, u32 tbl_idx, u32 csc_type);
-int mdss_mdp_dspp_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_mixer *mixer);
+int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl);
struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(u32 pnum);
struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_locked(u32 type);
@@ -318,4 +318,9 @@
int mdss_mdp_wb_kickoff(struct mdss_mdp_ctl *ctl);
int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
+int mdss_mdp_pp_init(struct device *dev);
+void mdss_mdp_pp_term(struct device *dev);
+int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback);
+
+int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id);
#endif /* MDSS_MDP_H */
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 1486779..26fbca1 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -20,8 +20,8 @@
#include "mdss_fb.h"
#include "mdss_mdp.h"
-/* 1.10 bus fudge factor */
-#define MDSS_MDP_BUS_FUDGE_FACTOR(val) ALIGN((((val) * 11) / 10), SZ_16M)
+/* 1.5 bus fudge factor */
+#define MDSS_MDP_BUS_FUDGE_FACTOR(val) ALIGN((((val) * 3) / 2), SZ_16M)
/* 1.25 clock fudge factor */
#define MDSS_MDP_CLK_FUDGE_FACTOR(val) (((val) * 5) / 4)
@@ -63,7 +63,6 @@
}
}
if (flags & MDSS_MDP_PERF_UPDATE_BUS) {
- bus_ab_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ab_quota);
bus_ib_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ib_quota);
mdss_mdp_bus_scale_set_quota(bus_ab_quota, bus_ib_quota);
}
@@ -808,9 +807,6 @@
{
mixer->params_changed = 0;
- if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF)
- mdss_mdp_dspp_setup(mixer->ctl, mixer);
-
/* skip mixer setup for rotator */
if (!mixer->rotator_mode)
mdss_mdp_mixer_setup(mixer->ctl, mixer);
@@ -864,6 +860,8 @@
ctl->flush_bits |= BIT(17); /* CTL */
}
+ /* postprocessing setup, including dspp */
+ mdss_mdp_pp_setup(ctl);
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl->flush_bits);
wmb();
ctl->flush_bits = 0;
@@ -885,3 +883,30 @@
return ret;
}
+
+int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id)
+{
+ int i;
+ struct mdss_mdp_ctl *ctl;
+ u32 mixer_cnt = 0;
+ mutex_lock(&mdss_mdp_ctl_lock);
+ for (i = 0; i < MDSS_MDP_MAX_CTL; i++) {
+ ctl = &mdss_mdp_ctl_list[i];
+ if ((ctl->power_on) &&
+ (ctl->mfd->index == fb_num)) {
+ if (ctl->mixer_left) {
+ mixer_id[mixer_cnt] = ctl->mixer_left->num;
+ mixer_cnt++;
+ }
+ if (mixer_cnt && ctl->mixer_right) {
+ mixer_id[mixer_cnt] = ctl->mixer_right->num;
+ mixer_cnt++;
+ }
+ if (mixer_cnt)
+ break;
+ }
+ }
+ mutex_unlock(&mdss_mdp_ctl_lock);
+ return mixer_cnt;
+}
+
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index 8825cc6..0139afd 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -321,6 +321,10 @@
MDSS_MDP_MAX_DSPP
};
+#define MDSS_MDP_REG_DSPP_OFFSET(pipe) (0x4600 + ((pipe) * 0x400))
+#define MDSS_MDP_REG_DSPP_OP_MODE 0x000
+#define MDSS_MDP_REG_DSPP_PA_BASE 0x238
+
enum mdss_mpd_intf_index {
MDSS_MDP_NO_INTF,
MDSS_MDP_INTF0,
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index db840a8..7ab3b01 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -13,6 +13,7 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
+#include "mdss_fb.h"
#include "mdss_mdp.h"
struct mdp_csc_cfg mdp_csc_convert[MDSS_MDP_MAX_CSC] = {
@@ -71,6 +72,27 @@
#define CSC_LV_OFF 0x14
#define CSC_POST_OFF 0xC
+#define MDSS_BLOCK_DISP_NUM (MDP_BLOCK_MAX - MDP_LOGICAL_BLOCK_DISP_0)
+
+struct pp_sts_type {
+ u32 pa_sts;
+};
+
+#define PP_FLAGS_DIRTY_PA 0x1
+
+#define PP_STS_ENABLE 0x1
+
+struct mdss_pp_res_type {
+ /* logical info */
+ u32 pp_disp_flags[MDSS_BLOCK_DISP_NUM];
+ struct mdp_pa_cfg_data pa_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ /* physical info */
+ struct pp_sts_type pp_dspp_sts[MDSS_MDP_MAX_DSPP];
+};
+
+static DEFINE_MUTEX(mdss_pp_mutex);
+static struct mdss_pp_res_type *mdss_pp_res;
+
static int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
struct mdp_csc_cfg *data)
{
@@ -160,16 +182,147 @@
return mdss_mdp_csc_setup_data(block, blk_idx, tbl_idx, data);
}
-int mdss_mdp_dspp_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_mixer *mixer)
+static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
+ struct mdss_mdp_mixer *mixer)
{
- int dspp_num;
-
- if (!ctl || !mixer)
- return -EINVAL;
+ u32 flags, base, offset, dspp_num, opmode = 0;
+ struct mdp_pa_cfg_data *pa_config;
+ struct pp_sts_type *pp_sts;
dspp_num = mixer->num;
+ /* no corresponding dspp */
+ if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
+ (dspp_num >= MDSS_MDP_MAX_DSPP))
+ return 0;
- ctl->flush_bits |= BIT(13 + dspp_num); /* DSPP */
+ if (disp_num < MDSS_BLOCK_DISP_NUM)
+ flags = mdss_pp_res->pp_disp_flags[disp_num];
+ else
+ flags = 0;
+
+ /* nothing to update */
+ if (!flags)
+ return 0;
+ pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
+ base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num);
+ if (flags & PP_FLAGS_DIRTY_PA) {
+ pa_config = &mdss_pp_res->pa_disp_cfg[disp_num];
+ if (pa_config->flags & MDP_PP_OPS_WRITE) {
+ offset = base + MDSS_MDP_REG_DSPP_PA_BASE;
+ MDSS_MDP_REG_WRITE(offset, pa_config->hue_adj);
+ offset += 4;
+ MDSS_MDP_REG_WRITE(offset, pa_config->sat_adj);
+ offset += 4;
+ MDSS_MDP_REG_WRITE(offset, pa_config->val_adj);
+ offset += 4;
+ MDSS_MDP_REG_WRITE(offset, pa_config->cont_adj);
+ }
+ if (pa_config->flags & MDP_PP_OPS_DISABLE)
+ pp_sts->pa_sts &= ~PP_STS_ENABLE;
+ else if (pa_config->flags & MDP_PP_OPS_ENABLE)
+ pp_sts->pa_sts |= PP_STS_ENABLE;
+ }
+ if (pp_sts->pa_sts & PP_STS_ENABLE)
+ opmode |= (1 << 20); /* PA_EN */
+ MDSS_MDP_REG_WRITE(base + MDSS_MDP_REG_DSPP_OP_MODE, opmode);
+ ctl->flush_bits |= BIT(13 + dspp_num); /* DSPP */
+ return 0;
+
+}
+int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)
+{
+ u32 disp_num;
+ if ((!ctl->mfd) || (!mdss_pp_res))
+ return -EINVAL;
+
+ /* treat fb_num the same as block logical id*/
+ disp_num = ctl->mfd->index;
+
+ mutex_lock(&mdss_pp_mutex);
+ if (ctl->mixer_left)
+ pp_dspp_setup(disp_num, ctl, ctl->mixer_left);
+ if (ctl->mixer_right)
+ pp_dspp_setup(disp_num, ctl, ctl->mixer_right);
+ /* clear dirty flag */
+ if (disp_num < MDSS_BLOCK_DISP_NUM)
+ mdss_pp_res->pp_disp_flags[disp_num] = 0;
+ mutex_unlock(&mdss_pp_mutex);
return 0;
}
+
+int mdss_mdp_pp_init(struct device *dev)
+{
+ int ret = 0;
+ mutex_lock(&mdss_pp_mutex);
+ if (!mdss_pp_res) {
+ mdss_pp_res = devm_kzalloc(dev, sizeof(*mdss_pp_res),
+ GFP_KERNEL);
+ if (mdss_pp_res == NULL) {
+ pr_err("%s mdss_pp_res allocation failed!", __func__);
+ ret = -ENOMEM;
+ }
+ }
+ mutex_unlock(&mdss_pp_mutex);
+ return ret;
+}
+void mdss_mdp_pp_term(struct device *dev)
+{
+ if (!mdss_pp_res) {
+ mutex_lock(&mdss_pp_mutex);
+ devm_kfree(dev, mdss_pp_res);
+ mdss_pp_res = NULL;
+ mutex_unlock(&mdss_pp_mutex);
+ }
+}
+
+int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback)
+{
+ int i, ret = 0;
+ u32 pa_offset, disp_num, mixer_cnt;
+ u32 mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+
+ if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (config->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+
+ mutex_lock(&mdss_pp_mutex);
+ disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+ if (config->flags & MDP_PP_OPS_READ) {
+ mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
+ if (!mixer_cnt) {
+ ret = -EPERM;
+ goto pa_config_exit;
+ }
+ /* only read the first mixer */
+ for (i = 0; i < mixer_cnt; i++) {
+ if (mixer_id[i] < MDSS_MDP_MAX_DSPP)
+ break;
+ }
+ if (i >= mixer_cnt) {
+ ret = -EPERM;
+ goto pa_config_exit;
+ }
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ pa_offset = MDSS_MDP_REG_DSPP_OFFSET(mixer_id[i]) +
+ MDSS_MDP_REG_DSPP_PA_BASE;
+
+ config->hue_adj = MDSS_MDP_REG_READ(pa_offset);
+ pa_offset += 4;
+ config->sat_adj = MDSS_MDP_REG_READ(pa_offset);
+ pa_offset += 4;
+ config->val_adj = MDSS_MDP_REG_READ(pa_offset);
+ pa_offset += 4;
+ config->cont_adj = MDSS_MDP_REG_READ(pa_offset);
+ *copyback = 1;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ } else {
+ mdss_pp_res->pa_disp_cfg[disp_num] = *config;
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_PA;
+ }
+
+pa_config_exit:
+ mutex_unlock(&mdss_pp_mutex);
+ return ret;
+}
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 50cc025..57e8441 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -16,7 +16,7 @@
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/file.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <linux/iommu.h>
#include <linux/msm_kgsl.h>
#include <linux/spinlock.h>
diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h
index a7832ed..0f37f6f 100644
--- a/drivers/video/msm/mipi_dsi.h
+++ b/drivers/video/msm/mipi_dsi.h
@@ -311,8 +311,6 @@
void mipi_dsi_set_tear_off(struct msm_fb_data_type *mfd);
void mipi_dsi_set_backlight(struct msm_fb_data_type *mfd, int level);
void mipi_dsi_cmd_backlight_tx(struct dsi_buf *dp);
-void mipi_dsi_clk_enable(void);
-void mipi_dsi_clk_disable(void);
void mipi_dsi_pre_kickoff_action(void);
void mipi_dsi_post_kickoff_action(void);
void mipi_dsi_pre_kickoff_add(struct dsi_kickoff_action *act);
@@ -326,16 +324,47 @@
irqreturn_t mipi_dsi_isr(int irq, void *ptr);
void mipi_set_tx_power_mode(int mode);
-void mipi_dsi_phy_ctrl(int on);
void mipi_dsi_phy_init(int panel_ndx, struct msm_panel_info const *panel_info,
int target_type);
int mipi_dsi_clk_div_config(uint8 bpp, uint8 lanes,
uint32 *expected_dsi_pclk);
int mipi_dsi_clk_init(struct platform_device *pdev);
void mipi_dsi_clk_deinit(struct device *dev);
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+void mipi_dsi_clk_enable(void);
+void mipi_dsi_clk_disable(void);
void mipi_dsi_prepare_clocks(void);
void mipi_dsi_unprepare_clocks(void);
void mipi_dsi_ahb_ctrl(u32 enable);
+void mipi_dsi_phy_ctrl(int on);
+#else
+static inline void mipi_dsi_clk_enable(void)
+{
+ /* empty */
+}
+void mipi_dsi_clk_disable(void)
+{
+ /* empty */
+}
+void mipi_dsi_prepare_clocks(void)
+{
+ /* empty */
+}
+void mipi_dsi_unprepare_clocks(void)
+{
+ /* empty */
+}
+void mipi_dsi_ahb_ctrl(u32 enable)
+{
+ /* empty */
+}
+void mipi_dsi_phy_ctrl(int on)
+{
+ /* empty */
+}
+#endif
+
void cont_splash_clk_ctrl(int enable);
void mipi_dsi_turn_on_clks(void);
void mipi_dsi_turn_off_clks(void);
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 0f014cf..9c55fe8 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -1820,6 +1820,9 @@
schedule_delayed_work(&mfd->backlight_worker,
backlight_duration);
+ if (info->node == 0 && (mfd->cont_splash_done)) /* primary */
+ mdp_free_splash_buffer(mfd);
+
++mfd->panel_info.frame_count;
return 0;
}
@@ -2993,6 +2996,9 @@
schedule_delayed_work(&mfd->backlight_worker,
backlight_duration);
+ if (info->node == 0 && (mfd->cont_splash_done)) /* primary */
+ mdp_free_splash_buffer(mfd);
+
return ret;
}
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index 1696a1a..2896349 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -187,6 +187,8 @@
u32 writeback_state;
bool writeback_active_cnt;
int cont_splash_done;
+ void *copy_splash_buf;
+ unsigned char *copy_splash_phys;
};
struct dentry *msm_fb_get_debugfs_root(void);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
index 3620f1a..2af76f3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
@@ -70,7 +70,6 @@
case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED:
case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE:
case VIDC_1080P_ERROR_DIVIDE_BY_ZERO:
- case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE:
case VIDC_1080P_ERROR_VSP_NOT_READY:
case VIDC_1080P_ERROR_BUFFER_FULL_STATE:
@@ -242,6 +241,7 @@
case VIDC_1080P_ERROR_HEADER_NOT_FOUND:
case VIDC_1080P_ERROR_SLICE_PARSE_ERROR:
case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED:
+ case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
vcd_status = VCD_ERR_BITSTREAM_ERR;
DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR");
break;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index c1e460f..4f19de9 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -364,7 +364,7 @@
ddl->command_channel);
} else {
u32 seq_hdr_only_frame = false;
- u32 need_reconfig = false;
+ u32 need_reconfig = false, eos_present = 0;
struct vcd_frame_data *input_vcd_frm =
&ddl->input_frame.vcd_frm;
need_reconfig = ddl_check_reconfig(ddl);
@@ -380,15 +380,25 @@
input_vcd_frm->offset +=
seq_hdr_info.dec_frm_size;
input_vcd_frm->data_len = 0;
- input_vcd_frm->flags |=
- VCD_FRAME_FLAG_CODECCONFIG;
- ddl->input_frame.frm_trans_end =
- !need_reconfig;
- ddl_context->ddl_callback(
+ eos_present =
+ input_vcd_frm->flags & VCD_FRAME_FLAG_EOS;
+ if (!eos_present) {
+ input_vcd_frm->flags |=
+ VCD_FRAME_FLAG_CODECCONFIG;
+ ddl->input_frame.frm_trans_end =
+ !need_reconfig;
+ ddl_context->ddl_callback(
VCD_EVT_RESP_INPUT_DONE,
VCD_S_SUCCESS, &ddl->input_frame,
sizeof(struct ddl_frame_data_tag),
(u32 *) ddl, ddl->client_data);
+ } else {
+ input_vcd_frm->flags &=
+ ~(VCD_FRAME_FLAG_CODECCONFIG);
+ seq_hdr_only_frame = false;
+ pr_err("%s() Codec config buffer with eos\n",
+ __func__);
+ }
} else {
if (decoder->codec.codec ==
VCD_CODEC_VC1_RCV) {
@@ -1175,20 +1185,28 @@
&(decoder->dec_disp_info);
struct ddl_frame_data_tag *output_frame = &(ddl->output_frame);
struct vcd_frame_data *output_vcd_frm = &(output_frame->vcd_frm);
+ enum vidc_1080p_decode_frame frame_type = 0;
u32 vcd_status, free_luma_dpb = 0, disp_pict = 0, is_interlaced;
+ u32 idr_frame = 0, coded_frame = 0;
get_dec_op_done_data(dec_disp_info, decoder->output_order,
&output_vcd_frm->physical, &is_interlaced);
decoder->progressive_only = !(is_interlaced);
output_vcd_frm->frame = VCD_FRAME_YUV;
+ vidc_sm_get_displayed_picture_frame(&ddl->shared_mem
+ [ddl->command_channel], &disp_pict);
+ coded_frame = (disp_pict & 0x03);
+ idr_frame = (disp_pict & 0x20) >> 5;
+ if (idr_frame)
+ frame_type = VIDC_1080P_DECODE_FRAMETYPE_IDR;
+ else
+ frame_type = (disp_pict & 0x1c) >> 2;
if (decoder->codec.codec == VCD_CODEC_MPEG4 ||
decoder->codec.codec == VCD_CODEC_VC1 ||
decoder->codec.codec == VCD_CODEC_VC1_RCV ||
(decoder->codec.codec >= VCD_CODEC_DIVX_3 &&
decoder->codec.codec <= VCD_CODEC_XVID)) {
- vidc_sm_get_displayed_picture_frame(&ddl->shared_mem
- [ddl->command_channel], &disp_pict);
if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) {
- if (!disp_pict) {
+ if (!coded_frame) {
output_vcd_frm->frame = VCD_FRAME_NOTCODED;
vidc_sm_get_available_luma_dpb_address(
&ddl->shared_mem[ddl->command_channel],
@@ -1213,6 +1231,7 @@
DDL_MSG_ERROR("CORRUPTED_OUTPUT_BUFFER_ADDRESS");
ddl_hw_fatal_cb(ddl);
} else {
+ ddl_get_decoded_frame(output_vcd_frm, frame_type);
vidc_sm_get_metadata_status(&ddl->shared_mem
[ddl->command_channel],
&decoder->meta_data_exists);
@@ -1347,6 +1366,10 @@
case VIDC_1080P_DECODE_FRAMETYPE_OTHERS:
frame->frame = VCD_FRAME_YUV;
break;
+ case VIDC_1080P_DECODE_FRAMETYPE_IDR:
+ frame->flags |= VCD_FRAME_FLAG_SYNCFRAME;
+ frame->frame = VCD_FRAME_IDR;
+ break;
case VIDC_1080P_DECODE_FRAMETYPE_32BIT:
default:
DDL_MSG_ERROR("UNKNOWN-FRAMETYPE");
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index 07b2fe2..8099234 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -45,7 +45,7 @@
#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_SHFT 0
#define VIDC_SM_DISP_PIC_FRAME_TYPE_ADDR 0x00c0
-#define VIDC_SM_DISP_PIC_FRAME_TYPE_BMSK 0x00000003
+#define VIDC_SM_DISP_PIC_FRAME_TYPE_BMSK 0x0000003f
#define VIDC_SM_DISP_PIC_FRAME_TYPE_SHFT 0
#define VIDC_SM_FREE_LUMA_DPB_ADDR 0x00c4
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.c b/drivers/video/msm/vidc/1080p/ddl/vidc.c
index d399847..3c445bc 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.c
@@ -520,8 +520,12 @@
u32 frame = 0;
VIDC_HWIO_IN(REG_760102, &frame);
- *pe_frame = (enum vidc_1080p_decode_frame)
- (frame & VIDC_1080P_SI_RG8_DECODE_FRAMETYPE_MASK);
+ if (frame & 0x10)
+ *pe_frame = (enum vidc_1080p_decode_frame)
+ VIDC_1080P_DECODE_FRAMETYPE_IDR;
+ else
+ *pe_frame = (enum vidc_1080p_decode_frame)
+ (frame & VIDC_1080P_SI_RG8_DECODE_FRAMETYPE_MASK);
}
void vidc_1080p_get_decode_frame_result(
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.h b/drivers/video/msm/vidc/1080p/ddl/vidc.h
index 7b8dc6f..22fcd1c 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.h
@@ -277,6 +277,7 @@
VIDC_1080P_DECODE_FRAMETYPE_P = 2,
VIDC_1080P_DECODE_FRAMETYPE_B = 3,
VIDC_1080P_DECODE_FRAMETYPE_OTHERS = 4,
+ VIDC_1080P_DECODE_FRAMETYPE_IDR = 5,
VIDC_1080P_DECODE_FRAMETYPE_32BIT = 0x7FFFFFFF
};
enum vidc_1080P_decode_frame_correct_type {
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 3bba69c..0bdacffa 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -30,11 +30,6 @@
#define CORESIGHT_COMPIDR2 (0xFF8)
#define CORESIGHT_COMPIDR3 (0xFFC)
-/* DBGv7 with baseline CP14 registers implemented */
-#define ARM_DEBUG_ARCH_V7B (0x3)
-/* DBGv7 with all CP14 registers implemented */
-#define ARM_DEBUG_ARCH_V7 (0x4)
-#define ARM_DEBUG_ARCH_V7_1 (0x5)
#define ETM_ARCH_V3_3 (0x23)
#define PFT_ARCH_V1_1 (0x31)
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 2519270..6ac2835 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -704,6 +704,7 @@
struct ion_allocation_data {
size_t len;
size_t align;
+ unsigned int heap_mask;
unsigned int flags;
struct ion_handle *handle;
};
@@ -824,7 +825,7 @@
* descriptor obtained from ION_IOC_SHARE and returns the struct with the handle
* filed set to the corresponding opaque handle.
*/
-#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, int)
+#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data)
/**
* DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl
@@ -840,21 +841,21 @@
*
* Clean the caches of the handle specified.
*/
-#define ION_IOC_CLEAN_CACHES _IOWR(ION_IOC_MAGIC, 7, \
+#define ION_IOC_CLEAN_CACHES _IOWR(ION_IOC_MAGIC, 20, \
struct ion_flush_data)
/**
* DOC: ION_MSM_IOC_INV_CACHES - invalidate the caches
*
* Invalidate the caches of the handle specified.
*/
-#define ION_IOC_INV_CACHES _IOWR(ION_IOC_MAGIC, 8, \
+#define ION_IOC_INV_CACHES _IOWR(ION_IOC_MAGIC, 21, \
struct ion_flush_data)
/**
* DOC: ION_MSM_IOC_CLEAN_CACHES - clean and invalidate the caches
*
* Clean and invalidate the caches of the handle specified.
*/
-#define ION_IOC_CLEAN_INV_CACHES _IOWR(ION_IOC_MAGIC, 9, \
+#define ION_IOC_CLEAN_INV_CACHES _IOWR(ION_IOC_MAGIC, 22, \
struct ion_flush_data)
/**
@@ -863,6 +864,6 @@
* Gets the flags of the current handle which indicate cachability,
* secure state etc.
*/
-#define ION_IOC_GET_FLAGS _IOWR(ION_IOC_MAGIC, 10, \
+#define ION_IOC_GET_FLAGS _IOWR(ION_IOC_MAGIC, 23, \
struct ion_flag_data)
#endif /* _LINUX_ION_H */
diff --git a/include/linux/mfd/pm8xxx/tm.h b/include/linux/mfd/pm8xxx/tm.h
index 6974754..74b77ec 100644
--- a/include/linux/mfd/pm8xxx/tm.h
+++ b/include/linux/mfd/pm8xxx/tm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -22,21 +22,55 @@
#define PM8XXX_TM_DEV_NAME "pm8xxx-tm"
+/**
+ * enum pm8xxx_tm_adc_type - support ADC API types for PMIC thermal manager
+ * %PM8XXX_TM_ADC_NONE: Do not call any ADC API and instead estimate
+ * PMIC temerature based on over temperature stage.
+ * %PM8XXX_TM_ADC_PM8058_ADC: Use the pmic8058-xoadc ADC API
+ * %PM8XXX_TM_ADC_PM8XXX_ADC: Use the pm8xxx-adc ADC API
+ */
enum pm8xxx_tm_adc_type {
- PM8XXX_TM_ADC_NONE, /* Estimates temp based on overload level. */
+ PM8XXX_TM_ADC_NONE,
PM8XXX_TM_ADC_PM8058_ADC,
PM8XXX_TM_ADC_PM8XXX_ADC,
};
+/**
+ * struct pm8xxx_tm_core_data - PM8XXX thermal manager core data
+ * @tm_name: Thermal zone name for the device
+ * @irq_name_temp_stat: String name used to identify TEMP_STAT IRQ
+ * @irq_name_over_temp: String name used to identify OVER_TEMP IRQ
+ * @reg_addr_temp_alarm_ctrl: PMIC SSBI address for temp alarm control
+ * register
+ * @reg_addr_temp_alarm_pwm: PMIC SSBI address for temp alarm pwm register
+ * @adc_type: Determines which ADC API to use in order to read
+ * the PMIC die temperature.
+ * @adc_channel: ADC channel identifier
+ * If adc_type == PM8XXX_TM_ADC_PM8XXX_ADC, then
+ * use a value from enum pm8xxx_adc_channels.
+ * If adc_type == PM8XXX_TM_ADC_PM8058_ADC, then
+ * use a channel value specified in
+ * <linux/pmic8058-xoadc.h>
+ * @default_no_adc_temp: Default temperature in millicelcius to report
+ * while stage == 0 and stage has never been
+ * greater than 0 if adc_type == PM8XXX_TM_ADC_NONE
+ * @allow_software_override: true --> writing "enabled" to thermalfs mode
+ * file results in software override of PMIC
+ * automatic over temperature shutdown
+ * false --> PMIC automatic over temperature
+ * shutdown always enabled. mode file cannot be
+ * set to "enabled".
+ */
struct pm8xxx_tm_core_data {
- int adc_channel;
- unsigned long default_no_adc_temp;
- enum pm8xxx_tm_adc_type adc_type;
- u16 reg_addr_temp_alarm_ctrl;
- u16 reg_addr_temp_alarm_pwm;
- char *tm_name;
- char *irq_name_temp_stat;
- char *irq_name_over_temp;
+ char *tm_name;
+ char *irq_name_temp_stat;
+ char *irq_name_over_temp;
+ u16 reg_addr_temp_alarm_ctrl;
+ u16 reg_addr_temp_alarm_pwm;
+ enum pm8xxx_tm_adc_type adc_type;
+ int adc_channel;
+ unsigned long default_no_adc_temp;
+ bool allow_software_override;
};
#endif
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index 105c2cb..f6d164d 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -157,10 +157,7 @@
int num_rx_port;
int num_tx_port;
- u8 idbyte_0;
- u8 idbyte_1;
- u8 idbyte_2;
- u8 idbyte_3;
+ u8 idbyte[4];
};
int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
diff --git a/include/linux/msm_audio_aac.h b/include/linux/msm_audio_aac.h
index 620e5ab..ee71c3e 100644
--- a/include/linux/msm_audio_aac.h
+++ b/include/linux/msm_audio_aac.h
@@ -60,6 +60,7 @@
unsigned short sbr_ps_on_flag;
unsigned short dual_mono_mode;
unsigned short channel_configuration;
+ unsigned short sample_rate;
};
struct msm_audio_aac_enc_config {
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 7afc896..2253655 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -367,6 +367,12 @@
_IOW(KGSL_IOC_TYPE, 0x22, struct kgsl_bind_gmem_shadow)
/* add a block of memory into the GPU address space */
+
+/*
+ * IOCTL_KGSL_SHAREDMEM_FROM_VMALLOC deprecated 09/2012
+ * use IOCTL_KGSL_GPUMEM_ALLOC instead
+ */
+
struct kgsl_sharedmem_from_vmalloc {
unsigned int gpuaddr; /*output param */
unsigned int hostptr;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index c9f9d74..d03ecfa 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -272,8 +272,10 @@
struct msmfb_img img;
};
+#define MDP_PP_OPS_ENABLE 0x1
#define MDP_PP_OPS_READ 0x2
#define MDP_PP_OPS_WRITE 0x4
+#define MDP_PP_OPS_DISABLE 0x8
struct mdp_qseed_cfg {
uint32_t table_num;
@@ -473,12 +475,22 @@
uint32_t scale;
};
+struct mdp_pa_cfg_data {
+ uint32_t block;
+ uint32_t flags;
+ uint32_t hue_adj;
+ uint32_t sat_adj;
+ uint32_t val_adj;
+ uint32_t cont_adj;
+};
+
enum {
mdp_op_pcc_cfg,
mdp_op_csc_cfg,
mdp_op_lut_cfg,
mdp_op_qseed_cfg,
mdp_bl_scale_cfg,
+ mdp_op_pa_cfg,
mdp_op_max,
};
@@ -490,6 +502,7 @@
struct mdp_lut_cfg_data lut_cfg_data;
struct mdp_qseed_cfg_data qseed_cfg_data;
struct mdp_bl_scale_data bl_scale_data;
+ struct mdp_pa_cfg_data pa_cfg_data;
} data;
};
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 19a1d97..f74db80 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -199,17 +199,21 @@
* digital data relative to ADC reference.
* %ADC_SCALE_DEFAULT: Default scaling to convert raw adc code to voltage.
* %ADC_SCALE_BATT_THERM: Conversion to temperature based on btm parameters.
- * %ADC_SCALE_PA_THERM: Returns temperature in degC.
+ * %ADC_SCALE_THERM_100K_PULLUP: Returns temperature in degC.
+ * Uses a mapping table with 100K pullup.
* %ADC_SCALE_PMIC_THERM: Returns result in milli degree's Centigrade.
* %ADC_SCALE_XOTHERM: Returns XO thermistor voltage in degree's Centigrade.
+ * %ADC_SCALE_THERM_150K_PULLUP: Returns temperature in degC.
+ * Uses a mapping table with 150K pullup.
* %ADC_SCALE_NONE: Do not use this scaling type.
*/
enum qpnp_adc_scale_fn_type {
SCALE_DEFAULT = 0,
SCALE_BATT_THERM,
- SCALE_PA_THERM,
+ SCALE_THERM_100K_PULLUP,
SCALE_PMIC_THERM,
SCALE_XOTHERM,
+ SCALE_THERM_150K_PULLUP,
SCALE_NONE,
};
@@ -766,6 +770,40 @@
const struct qpnp_vadc_chan_properties *chan_prop,
struct qpnp_vadc_result *chan_rslt);
/**
+ * qpnp_adc_scale_therm_pu1() - Scales the pre-calibrated digital output
+ * of an ADC to the ADC reference and compensates for the
+ * gain and offset. Returns the temperature of the therm in degC.
+ * It uses a mapping table computed for a 150K pull-up.
+ * Pull-up1 is an internal pull-up on the AMUX of 150K.
+ * @adc_code: pre-calibrated digital ouput of the ADC.
+ * @adc_prop: adc properties of the pm8xxx adc such as bit resolution,
+ * reference voltage.
+ * @chan_prop: individual channel properties to compensate the i/p scaling,
+ * slope and offset.
+ * @chan_rslt: physical result to be stored.
+ */
+int32_t qpnp_adc_scale_therm_pu1(int32_t adc_code,
+ const struct qpnp_adc_properties *adc_prop,
+ const struct qpnp_vadc_chan_properties *chan_prop,
+ struct qpnp_vadc_result *chan_rslt);
+/**
+ * qpnp_adc_scale_therm_pu2() - Scales the pre-calibrated digital output
+ * of an ADC to the ADC reference and compensates for the
+ * gain and offset. Returns the temperature of the therm in degC.
+ * It uses a mapping table computed for a 100K pull-up.
+ * Pull-up2 is an internal pull-up on the AMUX of 100K.
+ * @adc_code: pre-calibrated digital ouput of the ADC.
+ * @adc_prop: adc properties of the pm8xxx adc such as bit resolution,
+ * reference voltage.
+ * @chan_prop: individual channel properties to compensate the i/p scaling,
+ * slope and offset.
+ * @chan_rslt: physical result to be stored.
+ */
+int32_t qpnp_adc_scale_therm_pu2(int32_t adc_code,
+ const struct qpnp_adc_properties *adc_prop,
+ const struct qpnp_vadc_chan_properties *chan_prop,
+ struct qpnp_vadc_result *chan_rslt);
+/**
* qpnp_vadc_is_ready() - Clients can use this API to check if the
* device is ready to use.
* @result: 0 on success and -EPROBE_DEFER when probe for the device
@@ -806,6 +844,16 @@
const struct qpnp_vadc_chan_properties *chan_prop,
struct qpnp_vadc_result *chan_rslt)
{ return -ENXIO; }
+static inline int32_t qpnp_adc_scale_therm_pu1(int32_t adc_code,
+ const struct qpnp_adc_properties *adc_prop,
+ const struct qpnp_vadc_chan_properties *chan_prop,
+ struct qpnp_vadc_result *chan_rslt);
+{ return -ENXIO; }
+static inline int32_t qpnp_adc_scale_therm_pu2(int32_t adc_code,
+ const struct qpnp_adc_properties *adc_prop,
+ const struct qpnp_vadc_chan_properties *chan_prop,
+ struct qpnp_vadc_result *chan_rslt);
+{ return -ENXIO; }
static inline int32_t qpnp_vadc_is_read(void)
{ return -ENXIO; }
#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 5fb3719..2c9509d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1819,6 +1819,7 @@
#define PF_MEMALLOC 0x00000800 /* Allocating memory */
#define PF_NPROC_EXCEEDED 0x00001000 /* set_user noticed that RLIMIT_NPROC was exceeded */
#define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */
+#define PF_WAKE_UP_IDLE 0x00004000 /* try to wake up on an idle CPU */
#define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */
#define PF_FROZEN 0x00010000 /* frozen for system suspend */
#define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */
@@ -1936,6 +1937,14 @@
}
#endif
+static inline void set_wake_up_idle(bool enabled)
+{
+ if (enabled)
+ current->flags |= PF_WAKE_UP_IDLE;
+ else
+ current->flags &= ~PF_WAKE_UP_IDLE;
+}
+
#ifndef CONFIG_CPUMASK_OFFSTACK
static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
{
diff --git a/include/linux/sync.h b/include/linux/sync.h
index 943f414..4c00f04 100644
--- a/include/linux/sync.h
+++ b/include/linux/sync.h
@@ -24,6 +24,7 @@
struct sync_timeline;
struct sync_pt;
struct sync_fence;
+struct seq_file;
/**
* struct sync_timeline_ops - sync object implementation ops
diff --git a/include/linux/topology.h b/include/linux/topology.h
index e26db03..92a89f0 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -166,7 +166,7 @@
| 1*SD_WAKE_AFFINE \
| 0*SD_PREFER_LOCAL \
| 0*SD_SHARE_CPUPOWER \
- | 0*SD_SHARE_PKG_RESOURCES \
+ | 1*SD_SHARE_PKG_RESOURCES \
| 0*SD_SERIALIZE \
| sd_balance_for_package_power() \
| sd_power_saving_flags() \
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 82f9107..adcc450 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -328,10 +328,12 @@
bool sm_work_pending;
atomic_t pm_suspended;
atomic_t in_lpm;
+ atomic_t suspend_work_pending;
int async_int;
unsigned cur_power;
struct delayed_work chg_work;
struct delayed_work pmic_id_status_work;
+ struct delayed_work suspend_work;
enum usb_chg_state chg_state;
enum usb_chg_type chg_type;
u8 dcd_retries;
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 0ace67a..ed9af2c 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -28,7 +28,7 @@
#include <linux/time.h>
#endif
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#define BIT(nr) (1UL << (nr))
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
index 2efe31c..cfca799 100644
--- a/include/media/msm_vidc.h
+++ b/include/media/msm_vidc.h
@@ -14,8 +14,8 @@
#ifndef _MSM_VIDC_H_
#define _MSM_VIDC_H_
-#include <linux/videodev2.h>
#include <linux/poll.h>
+#include <linux/videodev2.h>
enum core_id {
MSM_VIDC_CORE_0 = 0,
@@ -28,7 +28,21 @@
MSM_VIDC_MAX_DEVICES,
};
-int msm_vidc_open(void *vidc_inst, int core_id, int session_type);
+struct msm_vidc_iommu_info {
+ u32 addr_range[2];
+ char name[64];
+ char ctx[64];
+ int domain;
+ int partition;
+};
+
+enum msm_vidc_io_maps {
+ CP_MAP,
+ NS_MAP,
+ MAX_MAP
+};
+
+void *msm_vidc_open(int core_id, int session_type);
int msm_vidc_close(void *instance);
int msm_vidc_querycap(void *instance, struct v4l2_capability *cap);
int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
@@ -47,4 +61,11 @@
int msm_vidc_encoder_cmd(void *instance, struct v4l2_encoder_cmd *enc);
int msm_vidc_poll(void *instance, struct file *filp,
struct poll_table_struct *pt);
+int msm_vidc_get_iommu_maps(void *instance,
+ struct msm_vidc_iommu_info maps[MAX_MAP]);
+int msm_vidc_subscribe_event(void *instance,
+ struct v4l2_event_subscription *sub);
+int msm_vidc_unsubscribe_event(void *instance,
+ struct v4l2_event_subscription *sub);
+int msm_vidc_dqevent(void *instance, struct v4l2_event *event);
#endif
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index ba705bd..db69518 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -660,7 +660,7 @@
IRIS_REGION_OTHER
};
-#define STD_BUF_SIZE (64)
+#define STD_BUF_SIZE (128)
enum iris_buf_t {
IRIS_BUF_SRCH_LIST,
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index 5285997..f80ddcd 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -17,7 +17,7 @@
#include <media/videobuf2-core.h>
#include <mach/iommu_domains.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
struct videobuf2_mapping {
unsigned int count;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index e955364..9885a9e 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2654,6 +2654,10 @@
if (target == prev_cpu && idle_cpu(prev_cpu))
return prev_cpu;
+ if (!(current->flags & PF_WAKE_UP_IDLE) &&
+ !(p->flags & PF_WAKE_UP_IDLE))
+ return target;
+
/*
* Otherwise, iterate the domains and find an elegible idle cpu.
*/
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index 9fbade8..9bc565e 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -2078,7 +2078,8 @@
int ret;
u32 version = socinfo_get_platform_version();
if (!cpu_is_apq8064() || (socinfo_get_id() == 130) ||
- SOCINFO_VERSION_MINOR(version) == 1) {
+ (machine_is_apq8064_mtp() &&
+ (SOCINFO_VERSION_MINOR(version) == 1))) {
pr_info("%s: Not APQ8064 in SLIMBUS mode\n", __func__);
return -ENODEV;
}
diff --git a/sound/soc/msm/mdm9615.c b/sound/soc/msm/mdm9615.c
index 05786a7..1000a8b 100644
--- a/sound/soc/msm/mdm9615.c
+++ b/sound/soc/msm/mdm9615.c
@@ -271,6 +271,9 @@
static struct snd_soc_jack hs_jack;
static struct snd_soc_jack button_jack;
+static struct platform_device *mdm9615_snd_device_slim;
+static struct platform_device *mdm9615_snd_device_i2s;
+
static bool hs_detect_use_gpio;
module_param(hs_detect_use_gpio, bool, 0444);
MODULE_PARM_DESC(hs_detect_use_gpio, "Use GPIO for headset detection");
@@ -1448,10 +1451,28 @@
pintf->intf_status[i2s_intf][MSM_DIR_TX]);
}
+static void mdm9615_install_codec_i2s_gpio(void)
+{
+ msm_gpiomux_install(msm9615_audio_prim_i2s_codec_configs,
+ ARRAY_SIZE(msm9615_audio_prim_i2s_codec_configs));
+}
+static int msm9615_i2s_prepare(struct snd_pcm_substream *substream)
+{
+ u8 ret = 0;
+
+ if (wcd9xxx_get_intf_type() < 0)
+ ret = -ENODEV;
+ else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
+ mdm9615_install_codec_i2s_gpio();
+
+ return ret;
+}
+
static struct snd_soc_ops msm9615_i2s_be_ops = {
.startup = msm9615_i2s_startup,
.shutdown = msm9615_i2s_shutdown,
.hw_params = msm9615_i2s_hw_params,
+ .prepare = msm9615_i2s_prepare,
};
static int mdm9615_audrx_init(struct snd_soc_pcm_runtime *rtd)
@@ -2068,14 +2089,19 @@
ARRAY_SIZE(mdm9615_dai_slimbus_tabla)];
-static struct snd_soc_card snd_soc_card_mdm9615 = {
- .name = "mdm9615-tabla-snd-card",
+static struct snd_soc_card snd_soc_card_mdm9615[] = {
+ [0] = {
+ .name = "mdm9615-tabla-snd-card",
.controls = tabla_mdm9615_controls,
.num_controls = ARRAY_SIZE(tabla_mdm9615_controls),
+ },
+ [1] = {
+ .name = "mdm9615-tabla-snd-card-i2s",
+ .controls = tabla_mdm9615_controls,
+ .num_controls = ARRAY_SIZE(tabla_mdm9615_controls),
+ },
};
-static struct platform_device *mdm9615_snd_device;
-
static int mdm9615_configure_headset_mic_gpios(void)
{
int ret;
@@ -2127,11 +2153,6 @@
}
}
-void __init install_codec_i2s_gpio(void)
-{
- msm_gpiomux_install(msm9615_audio_prim_i2s_codec_configs,
- ARRAY_SIZE(msm9615_audio_prim_i2s_codec_configs));
-}
static int __init mdm9615_audio_init(void)
{
int ret;
@@ -2146,53 +2167,69 @@
pr_err("Calibration data allocation failed\n");
return -ENOMEM;
}
+ mdm9615_snd_device_slim = platform_device_alloc("soc-audio", 0);
+ if (!mdm9615_snd_device_slim) {
+ pr_err("Platform device allocation failed\n");
+ kfree(mbhc_cfg.calibration);
+ return -ENOMEM;
+ }
- mdm9615_snd_device = platform_device_alloc("soc-audio", 0);
- if (!mdm9615_snd_device) {
+ /* Install SLIM specific links */
+ memcpy(mdm9615_slimbus_dai, mdm9615_dai_common,
+ sizeof(mdm9615_dai_common));
+ memcpy(mdm9615_slimbus_dai + ARRAY_SIZE(mdm9615_dai_common),
+ mdm9615_dai_slimbus_tabla,
+ sizeof(mdm9615_dai_slimbus_tabla));
+ snd_soc_card_mdm9615[0].dai_link = mdm9615_slimbus_dai;
+ snd_soc_card_mdm9615[0].num_links =
+ ARRAY_SIZE(mdm9615_slimbus_dai);
+
+ mdm9615_snd_device_i2s = platform_device_alloc("soc-audio", 1);
+ if (!mdm9615_snd_device_i2s) {
pr_err("Platform device allocation failed\n");
kfree(mbhc_cfg.calibration);
return -ENOMEM;
}
pr_err("%s: Interface Type = %d\n", __func__,
wcd9xxx_get_intf_type());
- if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
- memcpy(mdm9615_slimbus_dai, mdm9615_dai_common,
- sizeof(mdm9615_dai_common));
- memcpy(mdm9615_slimbus_dai + ARRAY_SIZE(mdm9615_dai_common),
- mdm9615_dai_slimbus_tabla,
- sizeof(mdm9615_dai_slimbus_tabla));
- snd_soc_card_mdm9615.dai_link = mdm9615_slimbus_dai;
- snd_soc_card_mdm9615.num_links =
- ARRAY_SIZE(mdm9615_slimbus_dai);
- } else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
- install_codec_i2s_gpio();
- memcpy(mdm9615_i2s_dai, mdm9615_dai_common,
- sizeof(mdm9615_dai_common));
- memcpy(mdm9615_i2s_dai + ARRAY_SIZE(mdm9615_dai_common),
- mdm9615_dai_i2s_tabla,
- sizeof(mdm9615_dai_i2s_tabla));
- snd_soc_card_mdm9615.dai_link = mdm9615_i2s_dai;
- snd_soc_card_mdm9615.num_links =
- ARRAY_SIZE(mdm9615_i2s_dai);
- } else{
- snd_soc_card_mdm9615.dai_link = mdm9615_dai_common;
- snd_soc_card_mdm9615.num_links =
- ARRAY_SIZE(mdm9615_dai_common);
- }
- platform_set_drvdata(mdm9615_snd_device, &snd_soc_card_mdm9615);
- ret = platform_device_add(mdm9615_snd_device);
+ /* Install I2S specific links */
+ memcpy(mdm9615_i2s_dai, mdm9615_dai_common,
+ sizeof(mdm9615_dai_common));
+ memcpy(mdm9615_i2s_dai + ARRAY_SIZE(mdm9615_dai_common),
+ mdm9615_dai_i2s_tabla,
+ sizeof(mdm9615_dai_i2s_tabla));
+ snd_soc_card_mdm9615[1].dai_link = mdm9615_i2s_dai;
+ snd_soc_card_mdm9615[1].num_links =
+ ARRAY_SIZE(mdm9615_i2s_dai);
+ platform_set_drvdata(mdm9615_snd_device_slim, &snd_soc_card_mdm9615[0]);
+ ret = platform_device_add(mdm9615_snd_device_slim);
if (ret) {
- platform_device_put(mdm9615_snd_device);
+ pr_err("%s Slim platform_device_add fail\n", __func__);
+ platform_device_put(mdm9615_snd_device_slim);
kfree(mbhc_cfg.calibration);
return ret;
}
+ platform_set_drvdata(mdm9615_snd_device_i2s, &snd_soc_card_mdm9615[1]);
+ ret = platform_device_add(mdm9615_snd_device_i2s);
+ if (ret) {
+ pr_err("%s I2S platform_device_add fail\n", __func__);
+ platform_device_put(mdm9615_snd_device_i2s);
+ kfree(mbhc_cfg.calibration);
+ return ret;
+ }
+
if (mdm9615_configure_headset_mic_gpios()) {
pr_err("%s Fail to configure headset mic gpios\n", __func__);
mdm9615_headset_gpios_configured = 0;
} else
mdm9615_headset_gpios_configured = 1;
+ /*
+ * Irrespective of audio interface type get virtual address
+ * of LPAIF registers as it may not be guaranted that I2S
+ * will probed successfully in Init.
+ */
atomic_set(&msm9615_auxpcm_ref, 0);
atomic_set(&msm9615_sec_auxpcm_ref, 0);
msm9x15_i2s_ctl.sif_virt_addr = ioremap(LPASS_SIF_MUX_ADDR, 4);
@@ -2214,7 +2251,8 @@
return ;
}
mdm9615_free_headset_mic_gpios();
- platform_device_unregister(mdm9615_snd_device);
+ platform_device_unregister(mdm9615_snd_device_slim);
+ platform_device_unregister(mdm9615_snd_device_i2s);
kfree(mbhc_cfg.calibration);
iounmap(msm9x15_i2s_ctl.sif_virt_addr);
iounmap(msm9x15_i2s_ctl.spare_virt_addr);
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 333f73e..499e4b6 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -54,7 +54,7 @@
#define GPIO_SEC_I2S_RX_WS 48
#define GPIO_SEC_I2S_RX_DOUT 49
#define GPIO_SEC_I2S_RX_MCLK 50
-#define I2S_MCLK_RATE 1536000
+#define I2S_MCLK_RATE 12288000
#define GPIO_MI2S_WS 27
#define GPIO_MI2S_SCLK 28
@@ -813,14 +813,11 @@
static int msm_be_i2s_hw_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);
pr_debug("%s()\n", __func__);
- rate->min = rate->max = 48000;
channels->min = channels->max = 2;
return 0;
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 9b9e028..78b3abc 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -579,7 +579,9 @@
pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_AC3_PASS_THROUGH) {
+ SND_AUDIOCODEC_AC3_PASS_THROUGH ||
+ compr->info.codec_param.codec.id ==
+ SND_AUDIOCODEC_DTS_PASS_THROUGH) {
msm_pcm_routing_reg_psthr_stream(
soc_prtd->dai_link->be_id,
prtd->session_id, substream->stream,
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index d71b726..41f259d 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -274,8 +274,10 @@
}
mutex_lock(&routing_lock);
-
- fe_dai_map[fedai_id][session_type] = dspst_id;
+ if (enable)
+ fe_dai_map[fedai_id][session_type] = dspst_id;
+ else
+ fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
@@ -1450,6 +1452,9 @@
SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
@@ -2384,6 +2389,7 @@
{"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"MultiMedia5 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"},
{"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},