Merge "tty: n_smux: Add throughput metrics to unit tests"
diff --git a/Documentation/devicetree/bindings/i2c/i2c-qup.txt b/Documentation/devicetree/bindings/i2c/i2c-qup.txt
index a7976e8..fd7b635 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-qup.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-qup.txt
@@ -28,10 +28,18 @@
recovery procedure.
- qcom,sda-gpio : I2C data GPIO number. Required for execution of bus
recovery procedure.
+ - qcom,active-only : Vote for core clock when the application processor goes
+ to active state and remove that vote when it goes to idle
+ state. This flag may improve service time of first i2c
+ request at the expense of power consumption. When this
+ entry is not present, voting is done by the runtime-pm
+ callbacks.
+ - qcom,master-id : Master endpoint number used for voting on clocks using
+ bus-scaling driver.
Example:
- i2c@f9966000 {
- cell-index = <0>;
+ i2c_3: i2c@f9966000 {
+ cell-index = <3>;
compatible = "qcom,i2c-qup";
reg = <0xf9966000 0x1000>;
reg-names = "qup_phys_addr";
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 359ee6c..43df9cc 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -41,6 +41,8 @@
by default. This can then be overriden
writing the the module parameter
"charging_disabled".
+- qcom,duty-cycle-100p: Set this property to enable the 100% duty
+ cycle feature.
- qcom,use-default-batt-values: Set this flag to force reporting of
battery temperature of 250 decidegree
Celsius, state of charge to be 50%
@@ -63,6 +65,10 @@
detection, "bpd_thm_id" selects both.
If the property is not set the hw default will
be used.
+- otg-parent-supply Specify a phandle to a parent supply regulator
+ for the OTG regulator.
+- boost-parent-supply Specify a phandle to a parent supply regulator
+ for the boost regulator.
Sub node required structure:
- A qcom,chg node must be a child of an SPMI node that has specified
@@ -85,6 +91,7 @@
qcom,usb-chgpth:
- usbin-valid
+
qcom,chgr:
- chg-done
- chg-failed
@@ -141,6 +148,16 @@
- limit-error: Limiting error on SMBB boost.
- boost-pwr-ok: Status of boost power.
+Sub node optional properties:
+ qcom,usb-chgpth:
+ - regulator-name: A string used as a descriptive name
+ for the OTG regulator.
+ qcom,boost:
+ - regulator-min-microvolt: Minimum boost voltage setting.
+ - regulator-max-microvolt: Maximum boost voltage setting.
+ - regulator-name: A string used as a descriptive name
+ for the boost regulator.
+
Example:
pm8941-chg {
spmi-dev-container;
@@ -148,6 +165,9 @@
#address-cells = <1>;
#size-cells = <1>;
+ otg-parent-supply = <&pm8941_boost>;
+ boost-parent-supply = <&foo_parent_reg>;
+
qcom,vddmax-mv = <4200>;
qcom,vddsafe-mv = <4200>;
qcom,vinmin-mv = <4200>;
@@ -218,7 +238,7 @@
"batt-pres";
};
- qcom,usb-chgpth@1300 {
+ pm8941_chg_otg: qcom,usb-chgpth@1300 {
reg = <0x1300 0x100>;
interrupts = <0 0x13 0x0>,
<0 0x13 0x1>,
@@ -238,7 +258,7 @@
"coarse-det-dc";
};
- qcom,boost@1500 {
+ pm8941_chg_boost: qcom,boost@1500 {
reg = <0x1500 0x100>;
interrupts = <0x0 0x15 0x0>,
<0x0 0x15 0x1>;
@@ -251,3 +271,15 @@
reg = <0x1600 0x100>;
};
};
+
+In regulator specific device tree file:
+
+ &pm8941_chg_boost {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "8941_smbb_boost";
+ };
+
+ &pm8941_chg_otg {
+ regulator-name = "8941_smbb_otg";
+ };
diff --git a/arch/arm/boot/dts/apq8074-dragonboard.dtsi b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
index ea626c8..5700b8d 100644
--- a/arch/arm/boot/dts/apq8074-dragonboard.dtsi
+++ b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
@@ -92,6 +92,7 @@
};
i2c@f9923000 {
+ status = "ok";
atmel_mxt_ts@4a {
compatible = "atmel,mxt-ts";
reg = <0x4a>;
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 34ea33d..85a5608 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -247,7 +247,7 @@
};
- qcom,usb-chgpth@1300 {
+ pm8941_chg_otg: qcom,usb-chgpth@1300 {
status = "disabled";
reg = <0x1300 0x100>;
interrupts = <0 0x13 0x0>,
@@ -269,7 +269,7 @@
"dcin-valid";
};
- qcom,boost@1500 {
+ pm8941_chg_boost: qcom,boost@1500 {
status = "disabled";
reg = <0x1500 0x100>;
interrupts = <0x0 0x15 0x0>,
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index c2dae28..b30d65c 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -424,10 +424,6 @@
qcom,otg-capability;
};
-&pm8941_mvs1 {
- parent-supply = <&ext_5v>;
-};
-
&pm8941_mvs2 {
parent-supply = <&ext_5v>;
};
@@ -777,6 +773,7 @@
&pm8941_chg {
status = "ok";
+ otg-parent-supply = <&ext_5v>;
qcom,charging-disabled;
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 35f3993..2114686 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -25,7 +25,7 @@
};
pm8941_mvs1: regulator@8300 {
- parent-supply = <&pm8941_boost>;
+ parent-supply = <&pm8941_chg_otg>;
qcom,enable-time = <1000>;
qcom,pull-down-enable = <1>;
interrupts = <0x1 0x83 0x2>;
@@ -552,3 +552,17 @@
regulator-always-on;
};
};
+
+&pm8941_chg {
+ otg-parent-supply = <&pm8941_boost>;
+};
+
+&pm8941_chg_boost {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "8941_smbb_boost";
+};
+
+&pm8941_chg_otg {
+ regulator-name = "8941_smbb_otg";
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-mtp.dts b/arch/arm/boot/dts/msm8974-v2-mtp.dts
index 1735515..792a78c 100644
--- a/arch/arm/boot/dts/msm8974-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-v2-mtp.dts
@@ -36,5 +36,5 @@
};
&pm8941_chg {
- qcom,bpd-detection = "bpd_id";
+ qcom,bpd-detection = "bpd_thm";
};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index e2dd3fd..75c2a92 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -26,6 +26,35 @@
sdhc4 = &sdhc_4; /* SDC4 SDIO slot */
};
+ cpus {
+ #size-cells = <0>;
+ #address-cells = <1>;
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "qcom,krait";
+ reg = <0x0>;
+ };
+
+ CPU1: cpu@1 {
+ device_type = "cpu";
+ compatible = "qcom,krait";
+ reg = <0x1>;
+ };
+
+ CPU2: cpu@2 {
+ device_type = "cpu";
+ compatible = "qcom,krait";
+ reg = <0x2>;
+ };
+
+ CPU3: cpu@3 {
+ device_type = "cpu";
+ compatible = "qcom,krait";
+ reg = <0x3>;
+ };
+ };
+
memory {
secure_mem: secure_region {
linux,contiguous-region;
@@ -738,6 +767,7 @@
interrupt-names = "qup_err_intr";
qcom,i2c-bus-freq = <100000>;
qcom,i2c-src-freq = <50000000>;
+ qcom,master-id = <84>;
};
i2c_1: i2c@f9923000 {
@@ -753,6 +783,7 @@
qcom,i2c-src-freq = <19200000>;
qcom,scl-gpio = <&msmgpio 3 0>;
qcom,sda-gpio = <&msmgpio 2 0>;
+ qcom,master-id = <86>;
status = "disabled";
};
@@ -767,6 +798,7 @@
interrupt-names = "qup_err_intr";
qcom,i2c-bus-freq = <100000>;
qcom,i2c-src-freq = <50000000>;
+ qcom,master-id = <86>;
};
spi_0: spi@f9923000 {
diff --git a/arch/arm/configs/msm9625-perf_defconfig b/arch/arm/configs/msm9625-perf_defconfig
index f434199..c48eb79 100644
--- a/arch/arm/configs/msm9625-perf_defconfig
+++ b/arch/arm/configs/msm9625-perf_defconfig
@@ -161,6 +161,7 @@
CONFIG_CFG80211=m
CONFIG_NL80211_TESTMODE=y
CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_BLOCK=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index ba246e5..4f2a637 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -163,6 +163,7 @@
CONFIG_CFG80211=m
CONFIG_NL80211_TESTMODE=y
CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_BLOCK=y
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index 1034516..5df3f3e 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -3039,6 +3039,18 @@
CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "scm"),
CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "scm"),
CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "scm"),
+
+ /* Add QCEDEV clocks */
+ CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd400000.qcom,qcedev"),
+ CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd400000.qcom,qcedev"),
+ CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "fd400000.qcom,qcedev"),
+ CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "fd400000.qcom,qcedev"),
+
+ /* Add QCRYPTO clocks */
+ CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd404000.qcom,qcrypto"),
+ CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd404000.qcom,qcrypto"),
+ CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "fd404000.qcom,qcrypto"),
+ CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "fd404000.qcom,qcrypto"),
};
static struct clk_lookup msm_clocks_8610_rumi[] = {
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index dabab9f..53e35ef 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -5395,12 +5395,6 @@
writel_relaxed(regval | BIT(26) | BIT(25),
GCC_REG_BASE(APCS_CLOCK_BRANCH_ENA_VOTE));
}
-
- /*
- * TODO: Confirm that no clocks need to be voted on in this sleep vote
- * register.
- */
- writel_relaxed(0x0, GCC_REG_BASE(APCS_CLOCK_SLEEP_ENA_VOTE));
}
static void __init msm8974_clock_post_init(void)
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index e67d973..fff517a 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -559,11 +559,8 @@
{
struct branch_clk *branch = to_branch_clk(c);
- if (!branch->bcr_reg) {
- WARN("clk_reset called on an unsupported clock (%s)\n",
- c->dbg_name);
+ if (!branch->bcr_reg)
return -EPERM;
- }
return __branch_clk_reset(BCR_REG(branch), action);
}
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 608018c..582bccf 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -475,7 +475,7 @@
mutex_lock(&clk->prepare_lock);
/* Return early if the rate isn't going to change */
- if (clk->rate == rate)
+ if (clk->rate == rate && !(clk->flags & CLKFLAG_NO_RATE_CACHE))
goto out;
trace_clock_set_rate(name, rate, raw_smp_processor_id());
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index d3ef0be..7b26bd6 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -510,6 +510,15 @@
bool mhl_enabled;
};
+/**
+ * msm_i2c_platform_data: i2c-qup driver configuration data
+ *
+ * @active_only when set, votes when system active and removes the vote when
+ * system goes idle (optimises for performance). When unset, voting using
+ * runtime pm (optimizes for power).
+ * @master_id master id number of the i2c core or its wrapper (BLSP/GSBI).
+ * When zero, clock path voting is disabled.
+ */
struct msm_i2c_platform_data {
int clk_freq;
uint32_t rmutex;
@@ -523,6 +532,8 @@
int use_gsbi_shared_mode;
int keep_ahb_clk_on;
void (*msm_i2c_config_gpio)(int iface, int config_type);
+ bool active_only;
+ uint32_t master_id;
};
struct msm_i2c_ssbi_platform_data {
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
index 1809456..fae0777 100644
--- a/arch/arm/mach-msm/include/mach/clk.h
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -25,6 +25,7 @@
#define CLKFLAG_MAX 0x00000800
#define CLKFLAG_INIT_DONE 0x00001000
#define CLKFLAG_INIT_ERR 0x00002000
+#define CLKFLAG_NO_RATE_CACHE 0x00004000
struct clk_lookup;
struct clk;
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 676df66..7b73333 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -81,16 +81,6 @@
#define MSM_LPASS_CLK_CTL_BASE IOMEM(0xFA015000) /* 4K */
#define MSM_HFPLL_BASE IOMEM(0xFA016000) /* 4K */
#define MSM_TLMM_BASE IOMEM(0xFA017000) /* 16K */
-#define MSM_SHARED_RAM_BASE IOMEM(0xFA400000) /* 2M */
-#define MSM_SIC_NON_SECURE_BASE IOMEM(0xFA600000) /* 64K */
-#define MSM_HDMI_BASE IOMEM(0xFA800000) /* 4K */
-#define MSM_RPM_BASE IOMEM(0xFA801000) /* 4K */
-#define MSM_RPM_MPM_BASE IOMEM(0xFA802000) /* 4K */
-#define MSM_QFPROM_BASE IOMEM(0xFA700000) /* 4K */
-#define MSM_L2CC_BASE IOMEM(0xFA701000) /* 4K */
-#define MSM_APCS_GLB_BASE IOMEM(0xFA702000) /* 4K */
-#define MSM_SAW2_BASE IOMEM(0xFA703000) /* 4k */
-#define MSM_SAW3_BASE IOMEM(0xFA704000) /* 4k */
#define MSM_VIC_BASE IOMEM(0xFA100000) /* 4K */
#define MSM_CSR_BASE IOMEM(0xFA101000) /* 4K */
#define MSM_GPIO1_BASE IOMEM(0xFA102000) /* 4K */
@@ -99,7 +89,16 @@
#define MSM_CFG_CTL_BASE IOMEM(0xFA105000) /* 4K */
#define MSM_CLK_CTL_SH2_BASE IOMEM(0xFA106000) /* 4K */
#define MSM_MPM2_PSHOLD_BASE IOMEM(0xFA107000) /* 4k */
-#define MSM_MDC_BASE IOMEM(0xFA400000) /* 1M */
+#define MSM_SHARED_RAM_BASE IOMEM(0xFA400000) /* 2M */
+#define MSM_SIC_NON_SECURE_BASE IOMEM(0xFA600000) /* 64K */
+#define MSM_QFPROM_BASE IOMEM(0xFA700000) /* 4K */
+#define MSM_L2CC_BASE IOMEM(0xFA701000) /* 4K */
+#define MSM_APCS_GLB_BASE IOMEM(0xFA702000) /* 4K */
+#define MSM_SAW2_BASE IOMEM(0xFA703000) /* 4k */
+#define MSM_SAW3_BASE IOMEM(0xFA704000) /* 4k */
+#define MSM_HDMI_BASE IOMEM(0xFA800000) /* 4K */
+#define MSM_RPM_BASE IOMEM(0xFA801000) /* 4K */
+#define MSM_RPM_MPM_BASE IOMEM(0xFA802000) /* 4K */
#define MSM_AD5_BASE IOMEM(0xFA900000) /* 13M (D00000)
0xFB600000 */
/* MSM9625 has unaligned imem so we need to map excess 2K virtually
diff --git a/arch/arm/mach-msm/include/mach/msm_ipc_router.h b/arch/arm/mach-msm/include/mach/msm_ipc_router.h
index 894379e..5dc1095 100644
--- a/arch/arm/mach-msm/include/mach/msm_ipc_router.h
+++ b/arch/arm/mach-msm/include/mach/msm_ipc_router.h
@@ -46,9 +46,6 @@
spinlock_t port_lock;
struct comm_mode_info mode_info;
- struct list_head incomplete;
- struct mutex incomplete_lock;
-
struct list_head port_rx_q;
struct mutex port_rx_q_lock;
char rx_wakelock_name[MAX_WAKELOCK_NAME_SZ];
diff --git a/arch/arm/mach-msm/include/mach/sps.h b/arch/arm/mach-msm/include/mach/sps.h
index c5ad35d..3332701 100644
--- a/arch/arm/mach-msm/include/mach/sps.h
+++ b/arch/arm/mach-msm/include/mach/sps.h
@@ -1271,6 +1271,15 @@
int sps_get_bam_debug_info(u32 dev, u32 option, u32 para,
u32 tb_sel, u32 desc_sel);
+/**
+ * Vote for or relinquish BAM DMA clock
+ *
+ * @clk_on - to turn on or turn off the clock
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_ctrl_bam_dma_clk(bool clk_on);
#else
static inline int sps_register_bam_device(const struct sps_bam_props
*bam_props, u32 *dev_handle)
@@ -1433,6 +1442,11 @@
{
return -EPERM;
}
+
+static inline int sps_ctrl_bam_dma_clk(bool clk_on)
+{
+ return -EPERM;
+}
#endif
#endif /* _SPS_H_ */
diff --git a/arch/arm/mach-msm/trace_msm_low_power.h b/arch/arm/mach-msm/include/mach/trace_msm_low_power.h
similarity index 98%
rename from arch/arm/mach-msm/trace_msm_low_power.h
rename to arch/arm/mach-msm/include/mach/trace_msm_low_power.h
index 4e9da85..faa4209 100644
--- a/arch/arm/mach-msm/trace_msm_low_power.h
+++ b/arch/arm/mach-msm/include/mach/trace_msm_low_power.h
@@ -149,6 +149,6 @@
);
#endif
#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_PATH mach
#define TRACE_INCLUDE_FILE trace_msm_low_power
#include <trace/define_trace.h>
diff --git a/arch/arm/mach-msm/trace_rpm_smd.h b/arch/arm/mach-msm/include/mach/trace_rpm_smd.h
similarity index 98%
rename from arch/arm/mach-msm/trace_rpm_smd.h
rename to arch/arm/mach-msm/include/mach/trace_rpm_smd.h
index eff4860..1b019d8 100644
--- a/arch/arm/mach-msm/trace_rpm_smd.h
+++ b/arch/arm/mach-msm/include/mach/trace_rpm_smd.h
@@ -74,6 +74,6 @@
);
#endif
#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_PATH mach
#define TRACE_INCLUDE_FILE trace_rpm_smd
#include <trace/define_trace.h>
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 73e960f..7fb2c88 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -69,7 +69,6 @@
MSM_CHIP_DEVICE(GPIO2, MSM7XXX),
MSM_CHIP_DEVICE(CLK_CTL, MSM7XXX),
MSM_CHIP_DEVICE(AD5, MSM7XXX),
- MSM_CHIP_DEVICE(MDC, MSM7XXX),
#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
defined(CONFIG_DEBUG_MSM_UART3)
MSM_DEVICE(DEBUG_UART),
@@ -117,7 +116,6 @@
MSM_DEVICE(SIRC),
MSM_DEVICE(SCPLL),
MSM_DEVICE(AD5),
- MSM_DEVICE(MDC),
MSM_DEVICE(TCSR),
#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
defined(CONFIG_DEBUG_MSM_UART3)
@@ -353,7 +351,6 @@
MSM_CHIP_DEVICE(CLK_CTL, MSM7X30),
MSM_CHIP_DEVICE(CLK_CTL_SH2, MSM7X30),
MSM_CHIP_DEVICE(AD5, MSM7X30),
- MSM_CHIP_DEVICE(MDC, MSM7X30),
MSM_CHIP_DEVICE(ACC0, MSM7X30),
MSM_CHIP_DEVICE(SAW0, MSM7X30),
MSM_CHIP_DEVICE(APCS_GCC, MSM7X30),
@@ -476,7 +473,6 @@
MSM_CHIP_DEVICE(SAW2, MSM8625),
MSM_CHIP_DEVICE(SAW3, MSM8625),
MSM_CHIP_DEVICE(AD5, MSM7XXX),
- MSM_CHIP_DEVICE(MDC, MSM7XXX),
#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
defined(CONFIG_DEBUG_MSM_UART3)
MSM_DEVICE(DEBUG_UART),
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index f95ef3b..573b9a3 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -115,7 +115,6 @@
#define SRV_HASH_SIZE 32
static struct list_head server_list[SRV_HASH_SIZE];
static DEFINE_MUTEX(server_list_lock);
-static wait_queue_head_t newserver_wait;
struct msm_ipc_server {
struct list_head list;
@@ -182,9 +181,6 @@
static DEFINE_MUTEX(routing_table_lock);
static int routing_table_inited;
-static LIST_HEAD(msm_ipc_board_dev_list);
-static DEFINE_MUTEX(msm_ipc_board_dev_list_lock);
-
static void do_read_data(struct work_struct *work);
#define RR_STATE_IDLE 0
@@ -586,8 +582,6 @@
}
spin_lock_init(&port_ptr->port_lock);
- INIT_LIST_HEAD(&port_ptr->incomplete);
- mutex_init(&port_ptr->incomplete_lock);
INIT_LIST_HEAD(&port_ptr->port_rx_q);
mutex_init(&port_ptr->port_rx_q_lock);
init_waitqueue_head(&port_ptr->port_rx_wait_q);
@@ -3120,7 +3114,6 @@
}
mutex_unlock(&routing_table_lock);
- init_waitqueue_head(&newserver_wait);
init_waitqueue_head(&subsystem_restart_wait);
ret = msm_ipc_router_init_sockets();
if (ret < 0)
diff --git a/arch/arm/mach-msm/lpm_resources.c b/arch/arm/mach-msm/lpm_resources.c
index 624a27c..1d9c539 100644
--- a/arch/arm/mach-msm/lpm_resources.c
+++ b/arch/arm/mach-msm/lpm_resources.c
@@ -23,11 +23,12 @@
#include <linux/tick.h>
#include <mach/mpm.h>
#include <mach/rpm-smd.h>
+#include <mach/trace_msm_low_power.h>
#include "spm.h"
#include "lpm_resources.h"
#include "rpm-notifier.h"
#include "idle.h"
-#include "trace_msm_low_power.h"
+
/*Debug Definitions*/
enum {
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 1680993..d7d3081 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -384,7 +384,28 @@
return 0;
}
-/* This function scans the device tree to populate the memory hole table */
+/* Function to remove any meminfo blocks which are of size zero */
+static void merge_meminfo(void)
+{
+ int i = 0;
+
+ while (i < meminfo.nr_banks) {
+ struct membank *bank = &meminfo.bank[i];
+
+ if (bank->size == 0) {
+ memmove(bank, bank + 1,
+ (meminfo.nr_banks - i) * sizeof(*bank));
+ meminfo.nr_banks--;
+ continue;
+ }
+ i++;
+ }
+}
+
+/*
+ * Function to scan the device tree and adjust the meminfo table to
+ * reflect the memory holes.
+ */
int __init dt_scan_for_memory_hole(unsigned long node, const char *uname,
int depth, void *data)
{
@@ -413,16 +434,6 @@
hole_start = be32_to_cpu(memory_remove_prop[0]);
hole_size = be32_to_cpu(memory_remove_prop[1]);
- if (hole_start + hole_size <= MAX_HOLE_ADDRESS) {
- if (memory_hole_start == 0 && memory_hole_end == 0) {
- memory_hole_start = hole_start;
- memory_hole_end = hole_start + hole_size;
- } else if ((memory_hole_end - memory_hole_start)
- <= hole_size) {
- memory_hole_start = hole_start;
- memory_hole_end = hole_start + hole_size;
- }
- }
adjust_meminfo(hole_start, hole_size);
}
@@ -452,6 +463,7 @@
bank[1].start = (start + size);
bank[1].size -= (bank->size + size);
bank[1].highmem = 0;
+ merge_meminfo();
}
}
}
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 5e44a4e..4a54dd4 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -35,6 +35,8 @@
#include <mach/system.h>
#include <mach/scm.h>
#include <mach/socinfo.h>
+#define CREATE_TRACE_POINTS
+#include <mach/trace_msm_low_power.h>
#include <mach/msm-krait-l2-accessors.h>
#include <mach/msm_bus.h>
#include <asm/cacheflush.h>
@@ -56,8 +58,7 @@
#include "timer.h"
#include "pm-boot.h"
#include <mach/event_timer.h>
-#define CREATE_TRACE_POINTS
-#include "trace_msm_low_power.h"
+
#define SCM_L2_RETENTION (0x2)
#define SCM_CMD_TERMINATE_PC (0x2)
diff --git a/arch/arm/mach-msm/rpm-smd.c b/arch/arm/mach-msm/rpm-smd.c
index 1eb66f4..38ed867 100644
--- a/arch/arm/mach-msm/rpm-smd.c
+++ b/arch/arm/mach-msm/rpm-smd.c
@@ -36,9 +36,9 @@
#include <mach/socinfo.h>
#include <mach/msm_smd.h>
#include <mach/rpm-smd.h>
-#include "rpm-notifier.h"
#define CREATE_TRACE_POINTS
-#include "trace_rpm_smd.h"
+#include <mach/trace_rpm_smd.h>
+#include "rpm-notifier.h"
/* Debug Definitions */
enum {
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 26b92d4..34cb153 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -395,32 +395,29 @@
unsigned long hole_end_virt;
/*
- * Find the start and end of the hole, using meminfo
- * if it hasnt been found already.
+ * Find the start and end of the hole, using meminfo.
*/
- if (memory_hole_start == 0 && memory_hole_end == 0) {
- for (i = 0; i < (meminfo.nr_banks - 1); i++) {
- if ((meminfo.bank[i].start + meminfo.bank[i].size) !=
+ for (i = 0; i < (meminfo.nr_banks - 1); i++) {
+ if ((meminfo.bank[i].start + meminfo.bank[i].size) !=
meminfo.bank[i+1].start) {
- if (meminfo.bank[i].start + meminfo.bank[i].size
+ if (meminfo.bank[i].start + meminfo.bank[i].size
<= MAX_HOLE_ADDRESS) {
- hole_start = meminfo.bank[i].start +
+ hole_start = meminfo.bank[i].start +
meminfo.bank[i].size;
- hole_size = meminfo.bank[i+1].start -
+ hole_size = meminfo.bank[i+1].start -
hole_start;
- if (memory_hole_start == 0 &&
+ if (memory_hole_start == 0 &&
memory_hole_end == 0) {
- memory_hole_start = hole_start;
- memory_hole_end = hole_start +
+ memory_hole_start = hole_start;
+ memory_hole_end = hole_start +
hole_size;
- } else if ((memory_hole_end -
+ } else if ((memory_hole_end -
memory_hole_start) <= hole_size) {
- memory_hole_start = hole_start;
- memory_hole_end = hole_start +
+ memory_hole_start = hole_start;
+ memory_hole_end = hole_start +
hole_size;
- }
}
}
}
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 9870648..a18fb8b 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1943,13 +1943,11 @@
podev->platform_support.bus_scale_table = NULL;
podev->platform_support.sha_hmac = 1;
- if (podev->ce_support.is_shared == false) {
- podev->platform_support.bus_scale_table =
- (struct msm_bus_scale_pdata *)
- msm_bus_cl_get_pdata(pdev);
- if (!podev->platform_support.bus_scale_table)
- pr_err("bus_scale_table is NULL\n");
- }
+ podev->platform_support.bus_scale_table =
+ (struct msm_bus_scale_pdata *)
+ msm_bus_cl_get_pdata(pdev);
+ if (!podev->platform_support.bus_scale_table)
+ pr_err("bus_scale_table is NULL\n");
} else {
platform_support =
(struct msm_ce_hw_support *)pdev->dev.platform_data;
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index a4bb2f1..375516b 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -3393,13 +3393,11 @@
cp->platform_support.bus_scale_table = NULL;
cp->platform_support.sha_hmac = 1;
- if (cp->ce_support.is_shared == false) {
- cp->platform_support.bus_scale_table =
- (struct msm_bus_scale_pdata *)
- msm_bus_cl_get_pdata(pdev);
- if (!cp->platform_support.bus_scale_table)
- pr_warn("bus_scale_table is NULL\n");
- }
+ cp->platform_support.bus_scale_table =
+ (struct msm_bus_scale_pdata *)
+ msm_bus_cl_get_pdata(pdev);
+ if (!cp->platform_support.bus_scale_table)
+ pr_warn("bus_scale_table is NULL\n");
} else {
platform_support =
(struct msm_ce_hw_support *)pdev->dev.platform_data;
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index a77dacb..b96349e 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -37,6 +37,7 @@
#include <linux/of_gpio.h>
#include <mach/board.h>
#include <mach/gpiomux.h>
+#include <mach/msm_bus_board.h>
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.2");
@@ -142,6 +143,22 @@
.pull = GPIOMUX_PULL_NONE,
};
+/**
+ * qup_i2c_clk_path_vote: data to use bus scaling driver for clock path vote
+ *
+ * @client_hdl when zero, client is not registered with the bus scaling driver,
+ * and bus scaling functionality should not be used. When non zero, it
+ * is a bus scaling client id and may be used to vote for clock path.
+ * @reg_err when true, registration error was detected and an error message was
+ * logged. i2c will attempt to re-register but will log error only once.
+ * once registration succeed, the flag is set to false.
+ */
+struct qup_i2c_clk_path_vote {
+ u32 client_hdl;
+ struct msm_bus_scale_pdata *pdata;
+ bool reg_err;
+};
+
struct qup_i2c_dev {
struct device *dev;
void __iomem *base; /* virtual */
@@ -172,6 +189,7 @@
struct mutex mlock;
void *complete;
int i2c_gpios[ARRAY_SIZE(i2c_rsrcs)];
+ struct qup_i2c_clk_path_vote clk_path_vote;
};
#ifdef DEBUG
@@ -333,11 +351,160 @@
mb();
}
+#define MSM_I2C_CLK_PATH_SUSPEND (0)
+#define MSM_I2C_CLK_PATH_RESUME (1)
+#define MSM_I2C_CLK_PATH_MAX_BW(dev) ((dev->pdata->src_clk_rate * 8) / 1000)
+
+static int i2c_qup_clk_path_init(struct platform_device *pdev,
+ struct qup_i2c_dev *dev)
+{
+ struct msm_bus_vectors *paths = NULL;
+ struct msm_bus_paths *usecases = NULL;
+
+ if (!dev->pdata->master_id)
+ return 0;
+
+ dev_dbg(&pdev->dev, "initialises bus-scaling clock voting");
+
+ paths = devm_kzalloc(&pdev->dev, sizeof(*paths) * 2, GFP_KERNEL);
+ if (!paths) {
+ dev_err(&pdev->dev,
+ "msm_bus_paths.paths memory allocation failed");
+ return -ENOMEM;
+ }
+
+ usecases = devm_kzalloc(&pdev->dev, sizeof(*usecases) * 2, GFP_KERNEL);
+ if (!usecases) {
+ dev_err(&pdev->dev,
+ "msm_bus_scale_pdata.usecases memory allocation failed");
+ goto path_init_err;
+ }
+
+ dev->clk_path_vote.pdata = devm_kzalloc(&pdev->dev,
+ sizeof(*dev->clk_path_vote.pdata),
+ GFP_KERNEL);
+ if (!dev->clk_path_vote.pdata) {
+ dev_err(&pdev->dev,
+ "msm_bus_scale_pdata memory allocation failed");
+ goto path_init_err;
+ }
+
+ paths[MSM_I2C_CLK_PATH_SUSPEND] = (struct msm_bus_vectors) {
+ dev->pdata->master_id, MSM_BUS_SLAVE_EBI_CH0, 0, 0
+ };
+
+ paths[MSM_I2C_CLK_PATH_RESUME] = (struct msm_bus_vectors) {
+ dev->pdata->master_id, MSM_BUS_SLAVE_EBI_CH0, 0,
+ MSM_I2C_CLK_PATH_MAX_BW(dev)
+ };
+
+ usecases[MSM_I2C_CLK_PATH_SUSPEND] = (struct msm_bus_paths) {
+ .num_paths = 1,
+ .vectors = &paths[MSM_I2C_CLK_PATH_SUSPEND],
+ };
+
+ usecases[MSM_I2C_CLK_PATH_RESUME] = (struct msm_bus_paths) {
+ .num_paths = 1,
+ .vectors = &paths[MSM_I2C_CLK_PATH_RESUME],
+ };
+
+ *dev->clk_path_vote.pdata = (struct msm_bus_scale_pdata) {
+ .active_only = dev->pdata->active_only,
+ .name = pdev->name,
+ .num_usecases = 2,
+ .usecase = usecases,
+ };
+
+ return 0;
+
+path_init_err:
+ devm_kfree(&pdev->dev, paths);
+ devm_kfree(&pdev->dev, usecases);
+ devm_kfree(&pdev->dev, dev->clk_path_vote.pdata);
+ dev->clk_path_vote.pdata = NULL;
+ return -ENOMEM;
+}
+
+static void i2c_qup_clk_path_teardown(struct qup_i2c_dev *dev)
+{
+ if (dev->clk_path_vote.client_hdl) {
+ msm_bus_scale_unregister_client(dev->clk_path_vote.client_hdl);
+ dev->clk_path_vote.client_hdl = 0;
+ }
+}
+
+static void i2c_qup_clk_path_vote(struct qup_i2c_dev *dev)
+{
+ if (dev->clk_path_vote.client_hdl)
+ msm_bus_scale_client_update_request(
+ dev->clk_path_vote.client_hdl,
+ MSM_I2C_CLK_PATH_RESUME);
+}
+
+static void i2c_qup_clk_path_unvote(struct qup_i2c_dev *dev)
+{
+ if (dev->clk_path_vote.client_hdl)
+ msm_bus_scale_client_update_request(
+ dev->clk_path_vote.client_hdl,
+ MSM_I2C_CLK_PATH_SUSPEND);
+}
+
+/**
+ * i2c_qup_clk_path_postponed_register: reg with bus-scaling after it is probed
+ *
+ * Workaround: i2c driver may be probed before the bus scaling driver. Thus,
+ * this function should be called not from probe but from a later context.
+ * This function may be called more then once before register succeed. At
+ * this case only one error message will be logged. At boot time all clocks
+ * are on, so earlier i2c transactions should succeed.
+ */
+static void i2c_qup_clk_path_postponed_register(struct qup_i2c_dev *dev)
+{
+ /*
+ * bail out if path voting is diabled (master_id == 0) or if it is
+ * already registered (client_hdl != 0)
+ */
+ if (!dev->pdata->master_id || dev->clk_path_vote.client_hdl)
+ return;
+
+ dev->clk_path_vote.client_hdl = msm_bus_scale_register_client(
+ dev->clk_path_vote.pdata);
+
+ if (dev->clk_path_vote.client_hdl) {
+ if (dev->clk_path_vote.reg_err) {
+ /* log a success message if an error msg was logged */
+ dev->clk_path_vote.reg_err = false;
+ dev_info(dev->dev,
+ "msm_bus_scale_register_client(mstr-id:%d "
+ "actv-only:%d):0x%x",
+ dev->pdata->master_id, dev->pdata->active_only,
+ dev->clk_path_vote.client_hdl);
+ }
+
+ if (dev->pdata->active_only)
+ i2c_qup_clk_path_vote(dev);
+ } else {
+ /* guard to log only one error on multiple failure */
+ if (!dev->clk_path_vote.reg_err) {
+ dev->clk_path_vote.reg_err = true;
+
+ dev_info(dev->dev,
+ "msm_bus_scale_register_client(mstr-id:%d "
+ "actv-only:%d):0",
+ dev->pdata->master_id, dev->pdata->active_only);
+ }
+ }
+}
+
static void
qup_i2c_pwr_mgmt(struct qup_i2c_dev *dev, unsigned int state)
{
dev->pwr_state = state;
if (state != 0) {
+ i2c_qup_clk_path_postponed_register(dev);
+ if (!dev->pdata->active_only)
+ i2c_qup_clk_path_vote(dev);
+
clk_prepare_enable(dev->clk);
if (!dev->pdata->keep_ahb_clk_on)
clk_prepare_enable(dev->pclk);
@@ -347,6 +514,8 @@
qup_config_core_on_en(dev);
if (!dev->pdata->keep_ahb_clk_on)
clk_disable_unprepare(dev->pclk);
+ if (!dev->pdata->active_only)
+ i2c_qup_clk_path_unvote(dev);
}
}
@@ -1099,11 +1268,12 @@
enum msm_i2c_dt_entry_type {
DT_U32,
DT_GPIO,
+ DT_BOOL,
};
struct msm_i2c_dt_to_pdata_map {
const char *dt_name;
- int *ptr_data;
+ void *ptr_data;
enum msm_i2c_dt_entry_status status;
enum msm_i2c_dt_entry_type type;
int default_val;
@@ -1119,28 +1289,42 @@
{"qcom,i2c-bus-freq", &pdata->clk_freq , DT_REQUIRED , DT_U32 , 0},
{"cell-index" , &pdev->id , DT_REQUIRED , DT_U32 , -1},
{"qcom,i2c-src-freq", &pdata->src_clk_rate, DT_SUGGESTED, DT_U32, 0},
+ {"qcom,master-id" , &pdata->master_id , DT_SUGGESTED, DT_U32, 0},
{"qcom,scl-gpio" , gpios , DT_OPTIONAL , DT_GPIO, -1},
{"qcom,sda-gpio" , gpios + 1 , DT_OPTIONAL , DT_GPIO, -1},
+ {"qcom,active-only" , &pdata->active_only , DT_OPTIONAL , DT_BOOL, 0},
{NULL , NULL , 0 , 0 , 0},
};
for (itr = map; itr->dt_name ; ++itr) {
- if (itr->type == DT_GPIO) {
+ switch (itr->type) {
+ case DT_GPIO:
ret = of_get_named_gpio(node, itr->dt_name, 0);
if (ret >= 0) {
- *itr->ptr_data = ret;
+ *((int *) itr->ptr_data) = ret;
ret = 0;
}
- } else {
+ break;
+ case DT_U32:
ret = of_property_read_u32(node, itr->dt_name,
- itr->ptr_data);
+ (u32 *) itr->ptr_data);
+ break;
+ case DT_BOOL:
+ *((bool *) itr->ptr_data) =
+ of_property_read_bool(node, itr->dt_name);
+ ret = 0;
+ break;
+ default:
+ dev_err(&pdev->dev, "%d is an unknown DT entry type\n",
+ itr->type);
+ ret = -EBADE;
}
dev_dbg(&pdev->dev, "DT entry ret:%d name:%s val:%d\n",
- ret, itr->dt_name, *itr->ptr_data);
+ ret, itr->dt_name, *((int *)itr->ptr_data));
if (ret) {
- *itr->ptr_data = itr->default_val;
+ *((int *)itr->ptr_data) = itr->default_val;
if (itr->status < DT_OPTIONAL) {
dev_err(&pdev->dev, "Missing '%s' DT entry\n",
@@ -1326,6 +1510,14 @@
dev->clk_ctl = 0;
dev->pos = 0;
+ ret = i2c_qup_clk_path_init(pdev, dev);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Failed to init clock path-voting data structs. err:%d", ret);
+ /* disable i2c_qup_clk_path_xxx() functionality */
+ dev->pdata->master_id = 0;
+ }
+
if (dev->pdata->src_clk_rate <= 0) {
dev_info(&pdev->dev,
"No src_clk_rate specified in platfrom data\n");
@@ -1443,6 +1635,7 @@
err_reset_failed:
clk_disable_unprepare(dev->clk);
clk_disable_unprepare(dev->pclk);
+ i2c_qup_clk_path_teardown(dev);
err_gsbi_failed:
iounmap(dev->base);
err_ioremap_failed:
@@ -1488,6 +1681,11 @@
clk_put(dev->pclk);
}
clk_put(dev->clk);
+
+ if (dev->pdata->active_only)
+ i2c_qup_clk_path_unvote(dev);
+ i2c_qup_clk_path_teardown(dev);
+
if (dev->gsbi)
iounmap(dev->gsbi);
iounmap(dev->base);
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 9bc77be..0a2906c 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -45,7 +45,6 @@
#include "qseecom_kernel.h"
#define QSEECOM_DEV "qseecom"
-#define QSEOS_VERSION_13 0x13
#define QSEOS_VERSION_14 0x14
#define QSEEE_VERSION_00 0x400000
#define QSEE_VERSION_01 0x401000
@@ -90,11 +89,6 @@
static dev_t qseecom_device_no;
static struct cdev qseecom_cdev;
-/* Data structures used in legacy support */
-static void *pil;
-static uint32_t pil_ref_cnt;
-static DEFINE_MUTEX(pil_access_lock);
-
static DEFINE_MUTEX(qsee_bw_mutex);
static DEFINE_MUTEX(app_access_lock);
static DEFINE_MUTEX(clk_access_lock);
@@ -3023,10 +3017,10 @@
}
qseecom.qseos_version = QSEOS_VERSION_14;
} else {
- qseecom.qseos_version = QSEOS_VERSION_13;
- qseecom.qsee_version = 0;
- pil = NULL;
- pil_ref_cnt = 0;
+ pr_err("QSEE legacy version is not supported:");
+ pr_err("Support for TZ1.3 and earlier is deprecated\n");
+ rc = -EINVAL;
+ goto err;
}
qseecom.commonlib_loaded = false;
qseecom.pdev = class_dev;
diff --git a/drivers/platform/msm/ipa/a2_service.c b/drivers/platform/msm/ipa/a2_service.c
index fa71efc..0d77741 100644
--- a/drivers/platform/msm/ipa/a2_service.c
+++ b/drivers/platform/msm/ipa/a2_service.c
@@ -536,6 +536,8 @@
__func__);
return -EFAULT;
}
+ if (sps_ctrl_bam_dma_clk(true))
+ WARN_ON(1);
memset(&connect_params, 0, sizeof(struct ipa_sys_connect_params));
connect_params.client = IPA_CLIENT_A2_TETHERED_CONS;
connect_params.notify = ipa_tethered_notify;
@@ -606,6 +608,8 @@
ipa_bridge_teardown(IPA_BRIDGE_DIR_UL, IPA_BRIDGE_TYPE_TETHERED,
a2_mux_ctx->tethered_prod);
bridge_tethered_ul_failed:
+ if (sps_ctrl_bam_dma_clk(false))
+ WARN_ON(1);
return ret;
}
@@ -647,6 +651,8 @@
__func__, ret);
return ret;
}
+ if (sps_ctrl_bam_dma_clk(false))
+ WARN_ON(1);
verify_tx_queue_is_empty(__func__);
(void) ipa_rm_release_resource(IPA_RM_RESOURCE_A2_PROD);
if (a2_mux_ctx->disconnect_ack)
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index a85e31c..9e3bab3 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -23,6 +23,9 @@
#include <linux/input.h>
#include <linux/log2.h>
+/* Common PNP defines */
+#define QPNP_PON_REVISION2(base) (base + 0x01)
+
/* PON common register addresses */
#define QPNP_PON_RT_STS(base) (base + 0x10)
#define QPNP_PON_PULL_CTL(base) (base + 0x70)
@@ -38,6 +41,7 @@
#define QPNP_PON_RESIN_S2_TIMER(base) (base + 0x45)
#define QPNP_PON_RESIN_S2_CNTL(base) (base + 0x46)
#define QPNP_PON_PS_HOLD_RST_CTL(base) (base + 0x5A)
+#define QPNP_PON_PS_HOLD_RST_CTL2(base) (base + 0x5B)
#define QPNP_PON_WARM_RESET_TFT BIT(4)
@@ -140,17 +144,31 @@
int qpnp_pon_system_pwr_off(bool reset)
{
int rc;
+ u8 reg;
+ u16 rst_en_reg;
struct qpnp_pon *pon = sys_reset_dev;
if (!pon)
return -ENODEV;
- rc = qpnp_pon_masked_write(pon, QPNP_PON_PS_HOLD_RST_CTL(pon->base),
- QPNP_PON_RESET_EN, 0);
+ rc = spmi_ext_register_readl(pon->spmi->ctrl, pon->spmi->sid,
+ QPNP_PON_REVISION2(pon->base), ®, 1);
+ if (rc) {
+ dev_err(&pon->spmi->dev,
+ "Unable to read addr=%x, rc(%d)\n",
+ QPNP_PON_REVISION2(pon->base), rc);
+ return rc;
+ }
+
+ if (reg == 0x00)
+ rst_en_reg = QPNP_PON_PS_HOLD_RST_CTL(pon->base);
+ else
+ rst_en_reg = QPNP_PON_PS_HOLD_RST_CTL2(pon->base);
+
+ rc = qpnp_pon_masked_write(pon, rst_en_reg, QPNP_PON_RESET_EN, 0);
if (rc)
dev_err(&pon->spmi->dev,
- "Unable to write to addr=%x, rc(%d)\n",
- QPNP_PON_PS_HOLD_RST_CTL(pon->base), rc);
+ "Unable to write to addr=%x, rc(%d)\n", rst_en_reg, rc);
/*
* We need 10 sleep clock cycles here. But since the clock is
@@ -167,13 +185,11 @@
"Unable to write to addr=%x, rc(%d)\n",
QPNP_PON_PS_HOLD_RST_CTL(pon->base), rc);
- rc = qpnp_pon_masked_write(pon, QPNP_PON_PS_HOLD_RST_CTL(pon->base),
- QPNP_PON_RESET_EN,
- QPNP_PON_RESET_EN);
+ rc = qpnp_pon_masked_write(pon, rst_en_reg, QPNP_PON_RESET_EN,
+ QPNP_PON_RESET_EN);
if (rc)
dev_err(&pon->spmi->dev,
- "Unable to write to addr=%x, rc(%d)\n",
- QPNP_PON_PS_HOLD_RST_CTL(pon->base), rc);
+ "Unable to write to addr=%x, rc(%d)\n", rst_en_reg, rc);
return rc;
}
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index 81d80e6..2e77114 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -1985,6 +1985,35 @@
EXPORT_SYMBOL(sps_get_unused_desc_num);
/**
+ * Vote for or relinquish BAM DMA clock
+ *
+ */
+int sps_ctrl_bam_dma_clk(bool clk_on)
+{
+ int ret;
+
+ SPS_DBG("sps:%s.", __func__);
+
+ if (!sps->is_ready)
+ return -EPROBE_DEFER;
+
+ if (clk_on == true) {
+ SPS_DBG("sps:vote for bam dma clk.\n");
+ ret = clk_prepare_enable(sps->bamdma_clk);
+ if (ret) {
+ SPS_ERR("sps:fail to enable bamdma_clk:ret=%d\n", ret);
+ return ret;
+ }
+ } else {
+ SPS_DBG("sps:relinquish bam dma clk.\n");
+ clk_disable_unprepare(sps->bamdma_clk);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(sps_ctrl_bam_dma_clk);
+
+/**
* Register a BAM device
*
*/
@@ -2525,11 +2554,13 @@
SPS_ERR("sps:sps_device_init err.");
#ifdef CONFIG_SPS_SUPPORT_BAMDMA
clk_disable_unprepare(sps->dfab_clk);
+ clk_disable_unprepare(sps->bamdma_clk);
#endif
goto sps_device_init_err;
}
#ifdef CONFIG_SPS_SUPPORT_BAMDMA
clk_disable_unprepare(sps->dfab_clk);
+ clk_disable_unprepare(sps->bamdma_clk);
#endif
sps->is_ready = true;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 24825ea..a5da421 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -25,6 +25,9 @@
#include <linux/power_supply.h>
#include <linux/bitops.h>
#include <linux/ratelimit.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/machine.h>
/* Interrupt offsets */
#define INT_RT_STS(base) (base + 0x10)
@@ -92,8 +95,12 @@
#define SEC_ACCESS 0xD0
#define BAT_IF_VREF_BAT_THM_CTRL 0x4A
#define BAT_IF_BPD_CTRL 0x48
+#define BOOST_VSET 0x41
+#define BOOST_ENABLE_CONTROL 0x46
+#define COMP_OVR1 0xEA
#define REG_OFFSET_PERP_SUBTYPE 0x05
+
/* SMBB peripheral subtype values */
#define SMBB_CHGR_SUBTYPE 0x01
#define SMBB_BUCK_SUBTYPE 0x02
@@ -132,6 +139,7 @@
#define REV_BST_DETECTED BIT(0)
#define BAT_THM_EN BIT(1)
#define BAT_ID_EN BIT(0)
+#define BOOST_PWR_EN BIT(7)
/* Interrupt definitions */
/* smbb_chg_interrupts */
@@ -183,12 +191,18 @@
/* Workaround flags */
#define CHG_FLAGS_VCP_WA BIT(0)
+#define BOOST_FLASH_WA BIT(1)
struct qpnp_chg_irq {
unsigned int irq;
unsigned long disabled;
};
+struct qpnp_chg_regulator {
+ struct regulator_desc rdesc;
+ struct regulator_dev *rdev;
+};
+
/**
* struct qpnp_chg_chip - device information
* @dev: device pointer to access the parent
@@ -263,6 +277,7 @@
bool batt_present;
bool charging_disabled;
bool use_default_batt_values;
+ bool duty_cycle_100p;
unsigned int bpd_detection;
unsigned int max_bat_chg_current;
unsigned int warm_bat_chg_ma;
@@ -295,6 +310,8 @@
struct delayed_work arb_stop_work;
struct delayed_work eoc_work;
struct wake_lock eoc_wake_lock;
+ struct qpnp_chg_regulator otg_vreg;
+ struct qpnp_chg_regulator boost_vreg;
};
@@ -425,6 +442,25 @@
}
static int
+qpnp_chg_is_boost_en_set(struct qpnp_chg_chip *chip)
+{
+ u8 boost_en_ctl;
+ int rc;
+
+ rc = qpnp_chg_read(chip, &boost_en_ctl,
+ chip->boost_base + BOOST_ENABLE_CONTROL, 1);
+ if (rc) {
+ pr_err("spmi read failed: addr=%03X, rc=%d\n",
+ chip->boost_base + BOOST_ENABLE_CONTROL, rc);
+ return rc;
+ }
+
+ pr_debug("boost en 0x%x\n", boost_en_ctl);
+
+ return (boost_en_ctl & BOOST_PWR_EN) ? 1 : 0;
+}
+
+static int
qpnp_chg_is_batt_present(struct qpnp_chg_chip *chip)
{
u8 batt_pres_rt_sts;
@@ -610,6 +646,32 @@
disable ? CHGR_ON_BAT_FORCE_BIT : 0, 1);
}
+#define BUCK_DUTY_MASK_100P 0x30
+static int
+qpnp_buck_set_100_duty_cycle_enable(struct qpnp_chg_chip *chip, int enable)
+{
+ int rc;
+
+ pr_debug("enable: %d\n", enable);
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->buck_base + SEC_ACCESS, 0xA5, 0xA5, 1);
+ if (rc) {
+ pr_debug("failed to write sec access rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->buck_base + BUCK_TEST_SMBC_MODES,
+ BUCK_DUTY_MASK_100P, enable ? 0x00 : 0x10, 1);
+ if (rc) {
+ pr_debug("failed enable 100p duty cycle rc=%d\n", rc);
+ return rc;
+ }
+
+ return rc;
+}
+
#define COMPATATOR_OVERRIDE_0 0x80
static int
qpnp_chg_toggle_chg_done_logic(struct qpnp_chg_chip *chip, int enable)
@@ -1215,21 +1277,6 @@
chip->bms_psy = power_supply_get_by_name("bms");
chip->usb_psy->get_property(chip->usb_psy,
- POWER_SUPPLY_PROP_SCOPE, &ret);
- if (ret.intval) {
- if ((ret.intval == POWER_SUPPLY_SCOPE_SYSTEM)
- && !qpnp_chg_is_otg_en_set(chip)) {
- switch_usb_to_host_mode(chip);
- return;
- }
- if ((ret.intval == POWER_SUPPLY_SCOPE_DEVICE)
- && qpnp_chg_is_otg_en_set(chip)) {
- switch_usb_to_charge_mode(chip);
- return;
- }
- }
-
- chip->usb_psy->get_property(chip->usb_psy,
POWER_SUPPLY_PROP_ONLINE, &ret);
/* Only honour requests while USB is present */
@@ -1457,6 +1504,48 @@
return qpnp_chg_write(chip, &temp, chip->chgr_base + CHGR_VDD_MAX, 1);
}
+#define BOOST_MIN_UV 4200000
+#define BOOST_MAX_UV 5500000
+#define BOOST_STEP_UV 50000
+#define BOOST_MIN 16
+#define N_BOOST_V ((BOOST_MAX_UV - BOOST_MIN_UV) / BOOST_STEP_UV + 1)
+static int
+qpnp_boost_vset(struct qpnp_chg_chip *chip, int voltage)
+{
+ u8 reg = 0;
+
+ if (voltage < BOOST_MIN_UV || voltage > BOOST_MAX_UV) {
+ pr_err("invalid voltage requested %d uV\n", voltage);
+ return -EINVAL;
+ }
+
+ reg = DIV_ROUND_UP(voltage - BOOST_MIN_UV, BOOST_STEP_UV) + BOOST_MIN;
+
+ pr_debug("voltage=%d setting %02x\n", voltage, reg);
+ return qpnp_chg_write(chip, ®, chip->boost_base + BOOST_VSET, 1);
+}
+
+static int
+qpnp_boost_vget_uv(struct qpnp_chg_chip *chip)
+{
+ int rc;
+ u8 boost_reg;
+
+ rc = qpnp_chg_read(chip, &boost_reg,
+ chip->boost_base + BOOST_VSET, 1);
+ if (rc) {
+ pr_err("failed to read BOOST_VSET rc=%d\n", rc);
+ return rc;
+ }
+
+ if (boost_reg < BOOST_MIN) {
+ pr_err("Invalid reading from 0x%x\n", boost_reg);
+ return -EINVAL;
+ }
+
+ return BOOST_MIN_UV + ((boost_reg - BOOST_MIN) * BOOST_STEP_UV);
+}
+
/* JEITA compliance logic */
static void
qpnp_chg_set_appropriate_vddmax(struct qpnp_chg_chip *chip)
@@ -1519,6 +1608,228 @@
}
}
+/* OTG regulator operations */
+static int
+qpnp_chg_regulator_otg_enable(struct regulator_dev *rdev)
+{
+ struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+
+ return switch_usb_to_host_mode(chip);
+}
+
+static int
+qpnp_chg_regulator_otg_disable(struct regulator_dev *rdev)
+{
+ struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+
+ return switch_usb_to_charge_mode(chip);
+}
+
+static int
+qpnp_chg_regulator_otg_is_enabled(struct regulator_dev *rdev)
+{
+ struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+
+ return qpnp_chg_is_otg_en_set(chip);
+}
+
+static int
+qpnp_chg_regulator_boost_enable(struct regulator_dev *rdev)
+{
+ struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+ int rc;
+
+ if (qpnp_chg_is_usb_chg_plugged_in(chip) &&
+ (chip->flags & BOOST_FLASH_WA)) {
+ qpnp_chg_usb_suspend_enable(chip, 1);
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->usb_chgpth_base + SEC_ACCESS,
+ 0xFF,
+ 0xA5, 1);
+ if (rc) {
+ pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->usb_chgpth_base + COMP_OVR1,
+ 0xFF,
+ 0x2F, 1);
+ if (rc) {
+ pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ return qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ENABLE_CONTROL,
+ BOOST_PWR_EN,
+ BOOST_PWR_EN, 1);
+}
+
+/* Boost regulator operations */
+#define ABOVE_VBAT_WEAK BIT(1)
+static int
+qpnp_chg_regulator_boost_disable(struct regulator_dev *rdev)
+{
+ struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+ int rc;
+ u8 vbat_sts;
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ENABLE_CONTROL,
+ BOOST_PWR_EN,
+ 0, 1);
+ if (rc) {
+ pr_err("failed to disable boost rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_chg_read(chip, &vbat_sts,
+ chip->chgr_base + CHGR_VBAT_STATUS, 1);
+ if (rc) {
+ pr_err("failed to read bat sts rc=%d\n", rc);
+ return rc;
+ }
+
+ if (!(vbat_sts & ABOVE_VBAT_WEAK) && (chip->flags & BOOST_FLASH_WA)) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->chgr_base + SEC_ACCESS,
+ 0xFF,
+ 0xA5, 1);
+ if (rc) {
+ pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->chgr_base + COMP_OVR1,
+ 0xFF,
+ 0x20, 1);
+ if (rc) {
+ pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
+ return rc;
+ }
+
+ usleep(2000);
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->chgr_base + SEC_ACCESS,
+ 0xFF,
+ 0xA5, 1);
+ if (rc) {
+ pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->chgr_base + COMP_OVR1,
+ 0xFF,
+ 0x00, 1);
+ if (rc) {
+ pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ if (qpnp_chg_is_usb_chg_plugged_in(chip)
+ && (chip->flags & BOOST_FLASH_WA)) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->usb_chgpth_base + SEC_ACCESS,
+ 0xFF,
+ 0xA5, 1);
+ if (rc) {
+ pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->usb_chgpth_base + COMP_OVR1,
+ 0xFF,
+ 0x00, 1);
+ if (rc) {
+ pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
+ return rc;
+ }
+
+ usleep(1000);
+
+ qpnp_chg_usb_suspend_enable(chip, 0);
+ }
+
+ return rc;
+}
+
+static int
+qpnp_chg_regulator_boost_is_enabled(struct regulator_dev *rdev)
+{
+ struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+
+ return qpnp_chg_is_boost_en_set(chip);
+}
+
+static int
+qpnp_chg_regulator_boost_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV, unsigned *selector)
+{
+ int uV = min_uV;
+ int rc;
+ struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+
+ if (uV < BOOST_MIN_UV && max_uV >= BOOST_MIN_UV)
+ uV = BOOST_MIN_UV;
+
+
+ if (uV < BOOST_MIN_UV || uV > BOOST_MAX_UV) {
+ pr_err("request %d uV is out of bounds\n", uV);
+ return -EINVAL;
+ }
+
+ *selector = DIV_ROUND_UP(uV - BOOST_MIN_UV, BOOST_STEP_UV);
+ if ((*selector * BOOST_STEP_UV + BOOST_MIN_UV) > max_uV) {
+ pr_err("no available setpoint [%d, %d] uV\n", min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ rc = qpnp_boost_vset(chip, uV);
+
+ return rc;
+}
+
+static int
+qpnp_chg_regulator_boost_get_voltage(struct regulator_dev *rdev)
+{
+ struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+
+ return qpnp_boost_vget_uv(chip);
+}
+
+static int
+qpnp_chg_regulator_boost_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ if (selector >= N_BOOST_V)
+ return 0;
+
+ return BOOST_MIN_UV + (selector * BOOST_STEP_UV);
+}
+
+static struct regulator_ops qpnp_chg_otg_reg_ops = {
+ .enable = qpnp_chg_regulator_otg_enable,
+ .disable = qpnp_chg_regulator_otg_disable,
+ .is_enabled = qpnp_chg_regulator_otg_is_enabled,
+};
+
+static struct regulator_ops qpnp_chg_boost_reg_ops = {
+ .enable = qpnp_chg_regulator_boost_enable,
+ .disable = qpnp_chg_regulator_boost_disable,
+ .is_enabled = qpnp_chg_regulator_boost_is_enabled,
+ .set_voltage = qpnp_chg_regulator_boost_set_voltage,
+ .get_voltage = qpnp_chg_regulator_boost_get_voltage,
+ .list_voltage = qpnp_chg_regulator_boost_list_voltage,
+};
+
#define CONSECUTIVE_COUNT 3
static void
qpnp_eoc_work(struct work_struct *work)
@@ -1705,6 +2016,8 @@
{
if (chip->revision > 0 && chip->type == SMBB)
chip->flags |= CHG_FLAGS_VCP_WA;
+ if (chip->type == SMBB)
+ chip->flags |= BOOST_FLASH_WA;
}
static int
@@ -1906,6 +2219,8 @@
{
int rc = 0;
u8 reg = 0;
+ struct regulator_init_data *init_data;
+ struct regulator_desc *rdesc;
switch (subtype) {
case SMBB_CHGR_SUBTYPE:
@@ -2022,6 +2337,38 @@
}
}
+ init_data = of_get_regulator_init_data(chip->dev,
+ spmi_resource->of_node);
+ if (!init_data) {
+ pr_err("unable to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ if (init_data->constraints.name) {
+ if (of_get_property(chip->dev->of_node,
+ "otg-parent-supply", NULL))
+ init_data->supply_regulator = "otg-parent";
+
+ rdesc = &(chip->otg_vreg.rdesc);
+ rdesc->owner = THIS_MODULE;
+ rdesc->type = REGULATOR_VOLTAGE;
+ rdesc->ops = &qpnp_chg_otg_reg_ops;
+ rdesc->name = init_data->constraints.name;
+
+ init_data->constraints.valid_ops_mask
+ |= REGULATOR_CHANGE_STATUS;
+
+ chip->otg_vreg.rdev = regulator_register(rdesc,
+ chip->dev, init_data, chip,
+ spmi_resource->of_node);
+ if (IS_ERR(chip->otg_vreg.rdev)) {
+ rc = PTR_ERR(chip->otg_vreg.rdev);
+ if (rc != -EPROBE_DEFER)
+ pr_err("OTG reg failed, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
rc = qpnp_chg_masked_write(chip,
chip->usb_chgpth_base + USB_OVP_CTL,
USB_VALID_DEB_20MS,
@@ -2047,6 +2394,38 @@
break;
case SMBB_BOOST_SUBTYPE:
case SMBBP_BOOST_SUBTYPE:
+ init_data = of_get_regulator_init_data(chip->dev,
+ spmi_resource->of_node);
+ if (!init_data) {
+ pr_err("unable to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ if (init_data->constraints.name) {
+ if (of_get_property(chip->dev->of_node,
+ "boost-parent-supply", NULL))
+ init_data->supply_regulator = "boost-parent";
+
+ rdesc = &(chip->boost_vreg.rdesc);
+ rdesc->owner = THIS_MODULE;
+ rdesc->type = REGULATOR_VOLTAGE;
+ rdesc->ops = &qpnp_chg_boost_reg_ops;
+ rdesc->name = init_data->constraints.name;
+
+ init_data->constraints.valid_ops_mask
+ |= REGULATOR_CHANGE_STATUS
+ | REGULATOR_CHANGE_VOLTAGE;
+
+ chip->boost_vreg.rdev = regulator_register(rdesc,
+ chip->dev, init_data, chip,
+ spmi_resource->of_node);
+ if (IS_ERR(chip->boost_vreg.rdev)) {
+ rc = PTR_ERR(chip->boost_vreg.rdev);
+ if (rc != -EPROBE_DEFER)
+ pr_err("boost reg failed, rc=%d\n", rc);
+ return rc;
+ }
+ }
break;
case SMBB_MISC_SUBTYPE:
case SMBBP_MISC_SUBTYPE:
@@ -2149,6 +2528,18 @@
chip->charging_disabled = of_property_read_bool(chip->spmi->dev.of_node,
"qcom,charging-disabled");
+ /* Get the duty-cycle-100p property */
+ chip->duty_cycle_100p = of_property_read_bool(
+ chip->spmi->dev.of_node,
+ "qcom,duty-cycle-100p");
+ if (chip->duty_cycle_100p) {
+ rc = qpnp_buck_set_100_duty_cycle_enable(chip, 1);
+ if (rc) {
+ pr_err("failed to enable duty cycle %d\n", rc);
+ return rc;
+ }
+ }
+
/* Get the fake-batt-values property */
chip->use_default_batt_values =
of_property_read_bool(chip->spmi->dev.of_node,
@@ -2298,7 +2689,8 @@
chip->usb_chgpth_base = resource->start;
rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
if (rc) {
- pr_err("Failed to init subtype 0x%x rc=%d\n",
+ if (rc != -EPROBE_DEFER)
+ pr_err("Failed to init subtype 0x%x rc=%d\n",
subtype, rc);
goto fail_chg_enable;
}
@@ -2317,7 +2709,8 @@
chip->boost_base = resource->start;
rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
if (rc) {
- pr_err("Failed to init subtype 0x%x rc=%d\n",
+ if (rc != -EPROBE_DEFER)
+ pr_err("Failed to init subtype 0x%x rc=%d\n",
subtype, rc);
goto fail_chg_enable;
}
@@ -2470,6 +2863,12 @@
cancel_work_sync(&chip->adc_measure_work);
cancel_delayed_work_sync(&chip->eoc_work);
+ if (chip->otg_vreg.rdev)
+ regulator_unregister(chip->otg_vreg.rdev);
+
+ if (chip->boost_vreg.rdev)
+ regulator_unregister(chip->boost_vreg.rdev);
+
dev_set_drvdata(&spmi->dev, NULL);
kfree(chip);
diff --git a/drivers/usb/gadget/f_qc_ecm.c b/drivers/usb/gadget/f_qc_ecm.c
index 5e68296..4f9cbf1 100644
--- a/drivers/usb/gadget/f_qc_ecm.c
+++ b/drivers/usb/gadget/f_qc_ecm.c
@@ -389,6 +389,7 @@
IPA_P_BAM : A2_P_BAM;
ecm_qc_bam_port.cdev = cdev;
+ ecm_qc_bam_port.func = &dev->port.func;
ecm_qc_bam_port.in = dev->port.in_ep;
ecm_qc_bam_port.out = dev->port.out_ep;
diff --git a/drivers/usb/gadget/f_qc_rndis.c b/drivers/usb/gadget/f_qc_rndis.c
index baea664..267cf53 100644
--- a/drivers/usb/gadget/f_qc_rndis.c
+++ b/drivers/usb/gadget/f_qc_rndis.c
@@ -426,6 +426,7 @@
struct usb_gadget *gadget = cdev->gadget;
dev->bam_port.cdev = cdev;
+ dev->bam_port.func = &dev->port.func;
dev->bam_port.in = dev->port.in_ep;
dev->bam_port.out = dev->port.out_ep;
diff --git a/drivers/usb/gadget/u_bam_data.c b/drivers/usb/gadget/u_bam_data.c
index 081a09c..c638164 100644
--- a/drivers/usb/gadget/u_bam_data.c
+++ b/drivers/usb/gadget/u_bam_data.c
@@ -178,6 +178,15 @@
reenable_eps:
/* Re-Enable the relevant EPs, if EPs were originally enabled */
if (reenable_eps) {
+ if (config_ep_by_speed(port->port_usb->cdev->gadget,
+ port->port_usb->func, port->port_usb->in) ||
+ config_ep_by_speed(port->port_usb->cdev->gadget,
+ port->port_usb->func, port->port_usb->out)) {
+ pr_err("%s: config_ep_by_speed failed", __func__);
+ port->port_usb->in->desc = NULL;
+ port->port_usb->out->desc = NULL;
+ return -EINVAL;
+ }
ret = usb_ep_enable(port->port_usb->in);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
diff --git a/drivers/usb/gadget/u_bam_data.h b/drivers/usb/gadget/u_bam_data.h
index 486191b5..5ce678d 100644
--- a/drivers/usb/gadget/u_bam_data.h
+++ b/drivers/usb/gadget/u_bam_data.h
@@ -23,6 +23,7 @@
struct data_port {
struct usb_composite_dev *cdev;
+ struct usb_function *func;
struct usb_ep *in;
struct usb_ep *out;
};
diff --git a/include/linux/topology.h b/include/linux/topology.h
index 92a89f0..c2d9c17 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -118,7 +118,7 @@
#define SD_MC_INIT (struct sched_domain) { \
.min_interval = 1, \
.max_interval = 4, \
- .busy_factor = 64, \
+ .busy_factor = 1, \
.imbalance_pct = 125, \
.cache_nice_tries = 1, \
.busy_idx = 2, \
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 8946dce..ab96baf 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -3108,7 +3108,7 @@
}
release_firmware(fw);
break;
- case SND_SOC_DAPM_POST_PMD:
+ case SND_SOC_DAPM_PRE_PMD:
msleep(40);
snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B1_CTL, 0x01, 0x00);
snd_soc_update_bits(codec, TAIKO_A_CDC_ANC2_B1_CTL, 0x02, 0x00);
@@ -3209,8 +3209,6 @@
snd_soc_update_bits(codec,
TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x00);
msleep(40);
- }
- if (w->shift == 5) {
snd_soc_update_bits(codec,
TAIKO_A_TX_7_MBHC_EN, 0x80, 00);
ret |= taiko_codec_enable_anc(w, kcontrol, event);
diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
index 4db3ea5..02f6ff1 100644
--- a/sound/soc/msm/msm8x10.c
+++ b/sound/soc/msm/msm8x10.c
@@ -613,6 +613,21 @@
.ignore_pmdown_time = 1,
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
},
+ {/* hw:x,13 */
+ .name = "Voice2",
+ .stream_name = "Voice2",
+ .cpu_dai_name = "Voice2",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
/* Backend I2S DAI Links */
{
.name = LPASS_BE_SEC_MI2S_RX,
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index 620f667..6bccdb7 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -125,7 +125,6 @@
int i = 0;
int time_stamp_flag = 0;
int buffer_length = 0;
- int stop_playback = 0;
pr_debug("%s opcode =%08x\n", __func__, opcode);
switch (opcode) {
@@ -150,15 +149,9 @@
/*
* check for underrun
*/
- snd_pcm_stream_lock_irq(substream);
- if (snd_pcm_playback_empty(substream)) {
+ if (runtime->status->hw_ptr >= runtime->control->appl_ptr) {
+ pr_err("render stopped");
runtime->render_flag |= SNDRV_RENDER_STOPPED;
- stop_playback = 1;
- }
- snd_pcm_stream_unlock_irq(substream);
-
- if (stop_playback) {
- pr_err("%s empty buffer, stop writes\n", __func__);
break;
}
@@ -493,15 +486,6 @@
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
prtd->pcm_irq_pos = 0;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (!atomic_cmpxchg(&compressed_audio.audio_ocmem_req,
- 0, 1))
- audio_ocmem_process_req(AUDIO, true);
- else
- atomic_inc(&compressed_audio.audio_ocmem_req);
- pr_debug("%s: req: %d\n", __func__,
- atomic_read(&compressed_audio.audio_ocmem_req));
- }
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
switch (compr->info.codec_param.codec.id) {
@@ -624,17 +608,32 @@
runtime->private_data = compr;
atomic_set(&prtd->eos, 0);
compressed_audio.prtd = &compr->prtd;
-
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (!atomic_cmpxchg(&compressed_audio.audio_ocmem_req, 0, 1))
+ audio_ocmem_process_req(AUDIO, true);
+ else
+ atomic_inc(&compressed_audio.audio_ocmem_req);
+ pr_debug("%s: req: %d\n", __func__,
+ atomic_read(&compressed_audio.audio_ocmem_req));
+ }
return 0;
}
int compressed_set_volume(unsigned volume)
{
int rc = 0;
+ int avg_vol = 0;
if (compressed_audio.prtd && compressed_audio.prtd->audio_client) {
- rc = q6asm_set_lrgain(compressed_audio.prtd->audio_client,
- (volume >> 16) & 0xFFFF,
- volume & 0xFFFF);
+ if (compressed_audio.prtd->channel_mode > 2) {
+ avg_vol = (((volume >> 16) & 0xFFFF) +
+ (volume & 0xFFFF)) / 2;
+ rc = q6asm_set_volume(
+ compressed_audio.prtd->audio_client, avg_vol);
+ } else {
+ rc = q6asm_set_lrgain(
+ compressed_audio.prtd->audio_client,
+ (volume >> 16) & 0xFFFF, volume & 0xFFFF);
+ }
if (rc < 0) {
pr_err("%s: Send Volume command failed rc=%d\n",
__func__, rc);
@@ -742,9 +741,17 @@
struct msm_audio *prtd = runtime->private_data;
struct audio_client *ac = prtd->audio_client;
struct audio_port_data *apd = ac->port;
- struct audio_buffer *ab = &(apd[IN].buf[0]);
+ struct audio_buffer *ab;
+ int dir = -1;
+
prtd->mmap_flag = 1;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dir = IN;
+ else
+ dir = OUT;
+ ab = &(apd[dir].buf[0]);
+
return msm_audio_ion_mmap(ab, vma);
}
@@ -794,6 +801,11 @@
prtd->audio_client->perf_mode,
prtd->session_id,
substream->stream);
+ /* the number of channels are required to call volume api
+ accoridngly. So, get channels from hw params */
+ if ((params_channels(params) > 0) &&
+ (params_periods(params) <= runtime->hw.channels_max))
+ prtd->channel_mode = params_channels(params);
ret = compressed_set_volume(0);
if (ret < 0)
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index 2a64ae2..c4b44fe 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
+#include <linux/msm_audio_ion.h>
#include <sound/core.h>
#include <sound/soc.h>
@@ -517,21 +518,21 @@
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct pcm_afe_info *prtd = runtime->private_data;
- int result = 0;
+ struct afe_audio_client *ac = prtd->audio_client;
+ struct afe_audio_port_data *apd = ac->port;
+ struct afe_audio_buffer *ab;
+ int dir = -1;
pr_debug("%s\n", __func__);
prtd->mmap_flag = 1;
- if (runtime->dma_addr && runtime->dma_bytes) {
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- result = remap_pfn_range(vma, vma->vm_start,
- runtime->dma_addr >> PAGE_SHIFT,
- runtime->dma_bytes,
- vma->vm_page_prot);
- } else {
- pr_err("Physical address or size of buf is NULL");
- return -EINVAL;
- }
- return result;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dir = IN;
+ else
+ dir = OUT;
+ ab = &(apd[dir].buf[0]);
+
+ return msm_audio_ion_mmap((struct audio_buffer *)ab, vma);
}
static int msm_afe_trigger(struct snd_pcm_substream *substream, int cmd)
{
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
index 7055c57..9899f97 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
@@ -427,9 +427,17 @@
struct msm_audio *prtd = runtime->private_data;
struct audio_client *ac = prtd->audio_client;
struct audio_port_data *apd = ac->port;
- struct audio_buffer *ab = &(apd[IN].buf[0]);
+ struct audio_buffer *ab;
+ int dir = -1;
+
prtd->mmap_flag = 1;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dir = IN;
+ else
+ dir = OUT;
+ ab = &(apd[dir].buf[0]);
+
return msm_audio_ion_mmap(ab, vma);
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index f4ca5b8..0592d10 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -633,9 +633,17 @@
struct msm_audio *prtd = runtime->private_data;
struct audio_client *ac = prtd->audio_client;
struct audio_port_data *apd = ac->port;
- struct audio_buffer *ab = &(apd[IN].buf[0]);
+ struct audio_buffer *ab;
+ int dir = -1;
+
prtd->mmap_flag = 1;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dir = IN;
+ else
+ dir = OUT;
+ ab = &(apd[dir].buf[0]);
+
return msm_audio_ion_mmap(ab, vma);
}
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 60999fa..26d9d48 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -4769,4 +4769,4 @@
return rc;
}
-device_initcall(voice_init);
+late_initcall(voice_init);