Merge "msm: 8610: Compile Low power management drivers"
diff --git a/Documentation/devicetree/bindings/coresight/coresight.txt b/Documentation/devicetree/bindings/coresight/coresight.txt
index f860618..b3037d8 100644
--- a/Documentation/devicetree/bindings/coresight/coresight.txt
+++ b/Documentation/devicetree/bindings/coresight/coresight.txt
@@ -32,6 +32,7 @@
- coresight-child-ports : list of input port numbers of the children
- coresight-default-sink : represents the default compile time CoreSight sink
- qcom,pc-save : program counter save implemented
+- qcom,blk-size : block size for tmc-etr to usb transfers
Examples:
diff --git a/Documentation/devicetree/bindings/power/bq28400-battery.txt b/Documentation/devicetree/bindings/power/bq28400-battery.txt
index 1460d70..a95e61f 100644
--- a/Documentation/devicetree/bindings/power/bq28400-battery.txt
+++ b/Documentation/devicetree/bindings/power/bq28400-battery.txt
@@ -4,15 +4,20 @@
The device interface is I2C, its I2C slave 7-bit address is 0xb.
The device is usually embedded inside the "smart battery" pack.
-node required properties:
-- compatible: Must be "ti,bq28400-battery" or "ti,bq30z55-battery"
-- reg: I2C Address must be 0xb.
+Required properties:
+
+ - compatible : Must be "ti,bq28400-battery" or "ti,bq30z55-battery"
+ - reg : I2C Address must be 0xb.
+ - ti,temp-cold : Cold temperature limit in celsius degree
+ - ti,temp-hot : Hot temperature limit in celsius degree
Example:
i2c@f9967000 {
battery@b {
compatible = "ti,bq28400-battery", "ti,bq30z55-battery";
reg = <0xb>;
+ ti,temp-cold = <2>;
+ ti,temp-hot = <43>;
};
};
diff --git a/Documentation/devicetree/bindings/regulator/krait-regulator.txt b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
index e3da903..149445d 100644
--- a/Documentation/devicetree/bindings/regulator/krait-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
@@ -10,10 +10,17 @@
"mdd" - string to identify the area where mdd registers reside.
- qcom,headroom-voltage: The minimum required voltage drop between the input
voltage and the output voltage for the LDO to be
- operational, in microvolts
-- qcom,retention-voltage: The value for retention voltage in microvolts
-- qcom,ldo-default-voltage: The default value for LDO voltage in microvolts
-- qcom,ldo-threshold-voltage: The voltage value above which LDO is nonfunctional
+ operational, in microvolts. Acceptable values are from
+ 50000uV to 250000uV
+- qcom,retention-voltage: The value for retention voltage in microvolts. Acceptable
+ values are from 465000uV to 750000uV
+- qcom,ldo-default-voltage: The default value for LDO voltage in microvolts. Acceptable
+ values are from 465000uV to 750000uV
+- qcom,ldo-threshold-voltage: The voltage value above which LDO is nonfunctional.
+ Acceptable values are from 600000uV to 900000uV
+- qcom,ldo-delta-voltage: The delta used to reduce the requested voltage in order
+ to derive the LDO output voltage while switching
+ to LDO mode. Acceptable values are from 1000uV to 100000uV
Any property defined as part of the core regulator
binding, defined in regulator.txt, can also be used.
@@ -31,5 +38,6 @@
qcom,retention-voltage = <745000>;
qcom,ldo-default-voltage = <745000>;
qcom,ldo-threshold-voltage = <750000>;
+ qcom,ldo-delta-voltage = <50000>;
};
diff --git a/arch/arm/boot/dts/msm-iommu.dtsi b/arch/arm/boot/dts/msm-iommu.dtsi
index 5a9e1ee..9bb642d 100755
--- a/arch/arm/boot/dts/msm-iommu.dtsi
+++ b/arch/arm/boot/dts/msm-iommu.dtsi
@@ -40,8 +40,8 @@
0x2010
0x2014>;
- qcom,iommu-bfb-data = <0xffffffff
- 0xffffffff
+ qcom,iommu-bfb-data = <0x0000ffff
+ 0x0
0x4
0x4
0x0
@@ -111,7 +111,7 @@
0x2020>;
qcom,iommu-bfb-data = <0xffffffff
- 0xffffffff
+ 0x0
0x00000004
0x00000010
0x00000000
@@ -261,8 +261,8 @@
0x2414
0x2008>;
- qcom,iommu-bfb-data = <0xffffffff
- 0xffffffff
+ qcom,iommu-bfb-data = <0x00000003
+ 0x0
0x00000004
0x00000010
0x00000000
@@ -322,7 +322,7 @@
0x2020>;
qcom,iommu-bfb-data = <0xffffffff
- 0xffffffff
+ 0x00000000
0x4
0x8
0x0
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 9c198ec..06bab30 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -269,6 +269,11 @@
status = "ok";
};
+&ehci {
+ status = "ok";
+ vbus-supply = <&usb2_otg_sw>;
+};
+
&usb3 {
qcom,otg-capability;
};
diff --git a/arch/arm/boot/dts/msm8974-coresight.dtsi b/arch/arm/boot/dts/msm8974-coresight.dtsi
index ee3df10..6bb7b28 100644
--- a/arch/arm/boot/dts/msm8974-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8974-coresight.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -190,5 +190,7 @@
coresight-id = <14>;
coresight-name = "coresight-csr";
coresight-nr-inports = <0>;
+
+ qcom,blk-size = <3>;
};
};
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 7e1f438..f15f572 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -285,8 +285,6 @@
&pm8941_chg {
status = "ok";
- qcom,chg-charging-disabled;
-
qcom,chg-chgr@1000 {
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index 7368788..f0f79b0 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -26,6 +26,8 @@
battery@b {
compatible = "ti,bq28400-battery";
reg = <0xb>;
+ ti,temp-cold = <2>; /* degree celsius */
+ ti,temp-hot = <43>; /* degree celsius */
};
charger@2b {
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index dc52fda6..40eaf2d 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -272,8 +272,6 @@
&pm8941_chg {
status = "ok";
- qcom,chg-charging-disabled;
-
qcom,chg-chgr@1000 {
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8974-pm.dtsi b/arch/arm/boot/dts/msm8974-pm.dtsi
index 1302ccb..ab105a9 100644
--- a/arch/arm/boot/dts/msm8974-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-pm.dtsi
@@ -179,6 +179,8 @@
#address-cells = <1>;
#size-cells = <0>;
+ qcom,use-qtimer;
+
qcom,lpm-level@0 {
reg = <0x0>;
qcom,mode = <0>; /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 5fa2364..c6c5452 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -434,7 +434,8 @@
qcom,headroom-voltage = <150000>;
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
- qcom,ldo-threshold-voltage = <750000>;
+ qcom,ldo-threshold-voltage = <850000>;
+ qcom,ldo-delta-voltage = <50000>;
};
krait1_vreg: regulator@f9098000 {
@@ -448,7 +449,8 @@
qcom,headroom-voltage = <150000>;
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
- qcom,ldo-threshold-voltage = <750000>;
+ qcom,ldo-threshold-voltage = <850000>;
+ qcom,ldo-delta-voltage = <50000>;
};
krait2_vreg: regulator@f90a8000 {
@@ -462,7 +464,8 @@
qcom,headroom-voltage = <150000>;
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
- qcom,ldo-threshold-voltage = <750000>;
+ qcom,ldo-threshold-voltage = <850000>;
+ qcom,ldo-delta-voltage = <50000>;
};
krait3_vreg: regulator@f90b8000 {
@@ -476,7 +479,8 @@
qcom,headroom-voltage = <150000>;
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
- qcom,ldo-threshold-voltage = <750000>;
+ qcom,ldo-threshold-voltage = <850000>;
+ qcom,ldo-delta-voltage = <50000>;
};
spi_eth_vreg: spi_eth_phy_vreg {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index d3a3e03..1072e7e 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -672,6 +672,19 @@
<61 512 240000 960000>;
};
+ ehci: qcom,ehci-host@f9a55000 {
+ compatible = "qcom,ehci-host";
+ status = "disabled";
+ reg = <0xf9a55000 0x400>;
+ interrupts = <0 134 0>, <0 140 0>;
+ interrupt-names = "core_irq", "async_irq";
+ HSUSB_VDDCX-supply = <&pm8841_s2>;
+ HSUSB_1p8-supply = <&pm8941_l6>;
+ HSUSB_3p3-supply = <&pm8941_l24>;
+ qcom,usb2-enable-hsphy2;
+ qcom,usb2-power-budget = <500>;
+ };
+
gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
parent-supply = <&pm8841_s4_corner>;
};
diff --git a/arch/arm/boot/dts/msm9625-coresight.dtsi b/arch/arm/boot/dts/msm9625-coresight.dtsi
index 9a49c32..f352c3f 100644
--- a/arch/arm/boot/dts/msm9625-coresight.dtsi
+++ b/arch/arm/boot/dts/msm9625-coresight.dtsi
@@ -126,5 +126,7 @@
coresight-id = <9>;
coresight-name = "coresight-csr";
coresight-nr-inports = <0>;
+
+ qcom,blk-size = <1>;
};
};
diff --git a/arch/arm/boot/dts/msm9625-pm.dtsi b/arch/arm/boot/dts/msm9625-pm.dtsi
index 71fcfd6..5a925cb 100644
--- a/arch/arm/boot/dts/msm9625-pm.dtsi
+++ b/arch/arm/boot/dts/msm9625-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -71,6 +71,8 @@
#address-cells = <1>;
#size-cells = <0>;
+ qcom,use-qtimer;
+
qcom,lpm-level@0 {
reg = <0x0>;
qcom,mode = <0>; /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 3dfbd8a..c2ed824 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -609,6 +609,12 @@
<0xfc330000 0x1000>;
reg-names = "etm-base","debug-base";
};
+
+ qcom,msm-rtb {
+ compatible = "qcom,msm-rtb";
+ qcom,memory-reservation-type = "EBI1";
+ qcom,memory-reservation-size = <0x1000>; /* 4K EBI1 buffer */
+ };
};
/include/ "msm-pm8019-rpm-regulator.dtsi"
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index fda9074..ecf1c68 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -217,6 +217,9 @@
CONFIG_USB_GADGET=y
CONFIG_USB_CI13XXX_MSM=y
CONFIG_USB_G_ANDROID=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MSM_HSIC=y
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
CONFIG_MMC_UNSAFE_RESUME=y
@@ -302,3 +305,4 @@
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MSM_RTB=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 0cc17b8..5cf6bd2 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -289,6 +289,7 @@
select DONT_MAP_HOLE_AFTER_MEMBANK0
select SENSORS_ADSP
select MSM_ULTRASOUND_B
+ select MSM_LPM_TEST
config ARCH_MPQ8092
bool "MPQ8092"
@@ -955,6 +956,15 @@
help
Support for the Qualcomm APQ8064 CDP device.
+config MACH_FSM8064_EP
+ depends on ARCH_APQ8064
+ bool "FSM8064 EP"
+ help
+ Support for the Qualcomm FSM8064 EP device.
+ This board also known as Femto development platform (FDP)
+ is based on APQ8064 chipset. This board does not support
+ keyboard, display or multimedia.
+
config MACH_APQ8064_MTP
depends on ARCH_APQ8064
bool "APQ8064 MTP"
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 336c2fc..c4d9048 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -38,6 +38,7 @@
obj-$(CONFIG_ARCH_MSM9625) += pmu.o perf_event_msm_pl310.o
obj-$(CONFIG_ARCH_MSM8625) += pmu.o perf_event_msm_pl310.o
obj-$(CONFIG_ARCH_MSM9615) += pmu.o perf_event_msm_pl310.o
+obj-$(CONFIG_DEBUG_FS) += perf_debug.o
endif
ifndef CONFIG_MSM_SMP
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 476a191..dc9120a 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -143,6 +143,11 @@
#define PCIE_PWR_EN_PMIC_GPIO 13
#define PCIE_RST_N_PMIC_MPP 1
+/* PCIe pmic gpios for fsm8064_ep */
+/* Unused pin. The WAKE feature is not supported on fsm8064_ep */
+#define PCIE_EP_WAKE_N_PMIC_GPIO 11
+#define PCIE_EP_RST_N_PMIC_GPIO 37
+
#ifdef CONFIG_KERNEL_MSM_CONTIG_MEM_REGION
static unsigned msm_contig_mem_size = MSM_CONTIG_MEM_SIZE;
static int __init msm_contig_mem_size_setup(char *p)
@@ -959,7 +964,7 @@
{
if (machine_is_apq8064_liquid() || machine_is_mpq8064_cdp() ||
machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv() ||
- machine_is_apq8064_cdp()) {
+ machine_is_apq8064_cdp() || machine_is_fsm8064_ep()) {
if (machine_is_apq8064_liquid())
msm_ehci_host_pdata3.dock_connect_irq =
PM8921_MPP_IRQ(PM8921_IRQ_BASE, 9);
@@ -2479,6 +2484,19 @@
.wake_n = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PCIE_WAKE_N_PMIC_GPIO),
};
+/* FSM8064_EP PCIe gpios */
+static struct msm_pcie_gpio_info_t ep_pcie_gpio_info[MSM_PCIE_MAX_GPIO] = {
+ {"rst_n", PM8921_GPIO_PM_TO_SYS(PCIE_EP_RST_N_PMIC_GPIO), 0},
+ {"pwr_en", PM8921_GPIO_PM_TO_SYS(PCIE_PWR_EN_PMIC_GPIO), 1},
+};
+
+static struct msm_pcie_platform ep_pcie_platform_data = {
+ .gpio = ep_pcie_gpio_info,
+ .axi_addr = PCIE_AXI_BAR_PHYS,
+ .axi_size = PCIE_AXI_BAR_SIZE,
+ .wake_n = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PCIE_EP_WAKE_N_PMIC_GPIO),
+};
+
static int __init mpq8064_pcie_enabled(void)
{
return !((readl_relaxed(QFPROM_RAW_FEAT_CONFIG_ROW0_MSB) & BIT(21)) ||
@@ -2493,6 +2511,12 @@
}
}
+static void __init fsm8064_ep_pcie_init(void)
+{
+ msm_device_pcie.dev.platform_data = &ep_pcie_platform_data;
+ platform_device_register(&msm_device_pcie);
+}
+
static struct platform_device mpq8064_device_ext_3p3v_vreg = {
.name = "reg-fixed-voltage",
.dev = {
@@ -2588,6 +2612,100 @@
&mpq_cpudai_pseudo,
};
+static struct platform_device *ep_devices[] __initdata = {
+ &msm_device_smd_apq8064,
+ &apq8064_device_gadget_peripheral,
+ &apq8064_device_hsusb_host,
+ &android_usb_device,
+ &msm_device_wcnss_wlan,
+ &msm_device_iris_fm,
+ &apq8064_fmem_device,
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+ &apq8064_android_pmem_device,
+ &apq8064_android_pmem_adsp_device,
+ &apq8064_android_pmem_audio_device,
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+#endif /*CONFIG_ANDROID_PMEM*/
+#ifdef CONFIG_ION_MSM
+ &apq8064_ion_dev,
+#endif
+ &msm8064_device_watchdog,
+ &msm8064_device_saw_regulator_core0,
+ &msm8064_device_saw_regulator_core1,
+ &msm8064_device_saw_regulator_core2,
+ &msm8064_device_saw_regulator_core3,
+#if defined(CONFIG_QSEECOM)
+ &qseecom_device,
+#endif
+
+ &msm_8064_device_tsif[0],
+ &msm_8064_device_tsif[1],
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+ defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+ &qcrypto_device,
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+ defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+ &qcedev_device,
+#endif
+
+#ifdef CONFIG_HW_RANDOM_MSM
+ &apq8064_device_rng,
+#endif
+ &apq_pcm,
+ &apq_pcm_routing,
+ &apq8064_rpm_device,
+ &apq8064_rpm_log_device,
+ &apq8064_rpm_stat_device,
+ &apq8064_rpm_master_stat_device,
+ &apq_device_tz_log,
+ &msm_bus_8064_apps_fabric,
+ &msm_bus_8064_sys_fabric,
+ &msm_bus_8064_mm_fabric,
+ &msm_bus_8064_sys_fpb,
+ &msm_bus_8064_cpss_fpb,
+ &msm_pil_dsps,
+ &msm_8960_q6_lpass,
+ &msm_pil_vidc,
+ &msm_gss,
+ &apq8064_rtb_device,
+ &apq8064_dcvs_device,
+ &apq8064_msm_gov_device,
+ &apq8064_device_cache_erp,
+ &msm8960_device_ebi1_ch0_erp,
+ &msm8960_device_ebi1_ch1_erp,
+ &epm_adc_device,
+ &coresight_tpiu_device,
+ &coresight_etb_device,
+ &apq8064_coresight_funnel_device,
+ &coresight_etm0_device,
+ &coresight_etm1_device,
+ &coresight_etm2_device,
+ &coresight_etm3_device,
+#ifdef CONFIG_MSM_GEMINI
+ &msm8960_gemini_device,
+#endif
+ &msm_tsens_device,
+ &apq8064_cache_dump_device,
+ &msm_8064_device_tspp,
+#ifdef CONFIG_BATTERY_BCL
+ &battery_bcl_device,
+#endif
+ &apq8064_msm_mpd_device,
+ &apq8064_device_qup_i2c_gsbi1,
+ &apq8064_device_uart_gsbi2,
+ &apq8064_device_uart_gsbi1,
+ &apq8064_device_uart_gsbi4,
+ &msm_device_sps_apq8064,
+#ifdef CONFIG_MSM_ROTATOR
+ &msm_rotator_device,
+#endif
+ &msm8064_pc_cntr,
+};
+
static struct platform_device *common_i2s_devices[] __initdata = {
&apq_cpudai_mi2s,
&apq_cpudai_i2s_rx,
@@ -2998,12 +3116,14 @@
wmb();
iounmap(gsbi_mem);
apq8064_i2c_qup_gsbi1_pdata.use_gsbi_shared_mode = 1;
- apq8064_device_qup_i2c_gsbi3.dev.platform_data =
- &apq8064_i2c_qup_gsbi3_pdata;
apq8064_device_qup_i2c_gsbi1.dev.platform_data =
&apq8064_i2c_qup_gsbi1_pdata;
- apq8064_device_qup_i2c_gsbi4.dev.platform_data =
- &apq8064_i2c_qup_gsbi4_pdata;
+ if (!machine_is_fsm8064_ep()) {
+ apq8064_device_qup_i2c_gsbi3.dev.platform_data =
+ &apq8064_i2c_qup_gsbi3_pdata;
+ apq8064_device_qup_i2c_gsbi4.dev.platform_data =
+ &apq8064_i2c_qup_gsbi4_pdata;
+ }
mpq8064_device_qup_i2c_gsbi5.dev.platform_data =
&mpq8064_i2c_qup_gsbi5_pdata;
}
@@ -3519,6 +3639,8 @@
mach_mask = I2C_LIQUID;
else if (PLATFORM_IS_MPQ8064())
mach_mask = I2C_MPQ_CDP;
+ else if (machine_is_fsm8064_ep())
+ mach_mask = I2C_SURF;
else
pr_err("unmatched machine ID in register_i2c_devices\n");
@@ -3644,9 +3766,11 @@
ARRAY_SIZE(pm8917_common_devices));
if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
platform_device_register(&apq8064_device_ext_ts_sw_vreg);
- platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+ if (!machine_is_fsm8064_ep())
+ platform_add_devices(common_devices,
+ ARRAY_SIZE(common_devices));
if (!(machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
- machine_is_mpq8064_dtv()))
+ machine_is_mpq8064_dtv() || machine_is_fsm8064_ep()))
platform_add_devices(common_not_mpq_devices,
ARRAY_SIZE(common_not_mpq_devices));
@@ -3797,6 +3921,26 @@
}
}
+static void __init fsm8064_ep_init(void)
+{
+ if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
+ pr_err("meminfo_init() failed!\n");
+
+ apq8064_common_init();
+ ethernet_init();
+ msm_rotator_set_split_iommu_domain();
+ fsm8064_ep_pcie_init();
+ platform_add_devices(ep_devices, ARRAY_SIZE(ep_devices));
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ apq8064_init_gpu();
+ platform_add_devices(apq8064_footswitch, apq8064_num_footswitch);
+ platform_device_register(&cdp_kp_pdev);
+#ifdef CONFIG_MSM_CAMERA
+ apq8064_init_cam();
+#endif
+ change_memory_power = &apq8064_change_memory_power;
+}
+
MACHINE_START(APQ8064_CDP, "QCT APQ8064 CDP")
.map_io = apq8064_map_io,
.reserve = apq8064_reserve,
@@ -3810,6 +3954,18 @@
.smp = &msm8960_smp_ops,
MACHINE_END
+MACHINE_START(FSM8064_EP, "QCT FSM8064 EP")
+ .map_io = apq8064_map_io,
+ .reserve = apq8064_reserve,
+ .init_irq = apq8064_init_irq,
+ .handle_irq = gic_handle_irq,
+ .timer = &msm_timer,
+ .init_machine = fsm8064_ep_init,
+ .init_early = apq8064_allocate_memory_regions,
+ .init_very_early = apq8064_early_reserve,
+ .restart = msm_restart,
+MACHINE_END
+
MACHINE_START(APQ8064_MTP, "QCT APQ8064 MTP")
.map_io = apq8064_map_io,
.reserve = apq8064_reserve,
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 9cfee09..9b02a5d 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -112,6 +112,8 @@
"msm-tsens", NULL),
OF_DEV_AUXDATA("qcom,usb-bam-msm", 0xF9A44000, \
"usb_bam", NULL),
+ OF_DEV_AUXDATA("qcom,hsic-host", 0xF9A15000, \
+ "msm_hsic_host", NULL),
{}
};
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 5b74d44..14f369df 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -3049,22 +3049,30 @@
return -ENXIO;
}
-static enum handoff pix_rdi_clk_handoff(struct clk *c)
+static struct clk *pix_rdi_clk_get_parent(struct clk *c)
{
u32 reg;
struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
+
+ reg = readl_relaxed(rdi->s_reg);
+ rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
+ reg = readl_relaxed(rdi->s2_reg);
+ rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
+
+ return pix_rdi_mux_map[rdi->cur_rate];
+}
+
+static enum handoff pix_rdi_clk_handoff(struct clk *c)
+{
+ struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
enum handoff ret;
ret = branch_handoff(&rdi->b, &rdi->c);
if (ret == HANDOFF_DISABLED_CLK)
return ret;
- reg = readl_relaxed(rdi->s_reg);
- rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
- reg = readl_relaxed(rdi->s2_reg);
- rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
- c->parent = pix_rdi_mux_map[rdi->cur_rate];
-
+ rdi->prepared = true;
+ rdi->enabled = true;
return HANDOFF_ENABLED_CLK;
}
@@ -3078,6 +3086,7 @@
.get_rate = pix_rdi_clk_get_rate,
.list_rate = pix_rdi_clk_list_rate,
.reset = pix_rdi_clk_reset,
+ .get_parent = pix_rdi_clk_get_parent,
};
static struct pix_rdi_clk csi_pix_clk = {
@@ -5283,8 +5292,10 @@
CLK_LOOKUP("core_clk", gp2_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi1_uart_clk.c, "msm_serial_hsl.1"),
CLK_LOOKUP("core_clk", gsbi2_uart_clk.c, ""),
+ CLK_LOOKUP("core_clk", gsbi2_uart_clk.c, "msm_serial_hsl.3"),
CLK_LOOKUP("core_clk", gsbi3_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi4_uart_clk.c, ""),
+ CLK_LOOKUP("core_clk", gsbi4_uart_clk.c, "msm_serial_hsl.4"),
CLK_LOOKUP("core_clk", gsbi5_uart_clk.c, "msm_serial_hsl.2"),
CLK_LOOKUP("core_clk", gsbi6_uart_clk.c, "msm_serial_hs.0"),
CLK_LOOKUP("core_clk", gsbi7_uart_clk.c, "msm_serial_hsl.0"),
@@ -5332,6 +5343,7 @@
CLK_LOOKUP("iface_clk", gsbi1_p_clk.c, "msm_serial_hsl.1"),
CLK_LOOKUP("iface_clk", gsbi1_p_clk.c, "qup_i2c.0"),
CLK_LOOKUP("iface_clk", gsbi2_p_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gsbi2_p_clk.c, "msm_serial_hsl.3"),
CLK_LOOKUP("iface_clk", gsbi3_p_clk.c, "qup_i2c.3"),
CLK_LOOKUP("iface_clk", gsbi4_p_clk.c, "qup_i2c.4"),
CLK_LOOKUP("iface_clk", gsbi5_p_clk.c, "msm_serial_hsl.2"),
@@ -5340,6 +5352,7 @@
CLK_LOOKUP("iface_clk", gsbi6_p_clk.c, "msm_serial_hs.0"),
CLK_LOOKUP("iface_clk", gsbi6_p_clk.c, "spi_qsd.1"),
CLK_LOOKUP("iface_clk", gsbi7_p_clk.c, "msm_serial_hsl.0"),
+ CLK_LOOKUP("iface_clk", gsbi7_p_clk.c, "msm_serial_hsl.4"),
CLK_LOOKUP("ref_clk", tsif_ref_clk.c, "msm_tspp.0"),
CLK_LOOKUP("iface_clk", tsif_p_clk.c, "msm_tspp.0"),
CLK_LOOKUP("iface_clk", usb_fs1_p_clk.c, ""),
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 4432795..a173ba9 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, 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
@@ -598,20 +598,21 @@
static enum handoff branch_clk_handoff(struct clk *c)
{
struct branch_clk *br = to_branch_clk(c);
- return branch_handoff(&br->b, &br->c);
+ if (branch_handoff(&br->b, &br->c) == HANDOFF_ENABLED_CLK) {
+ br->enabled = true;
+ return HANDOFF_ENABLED_CLK;
+ }
+
+ return HANDOFF_DISABLED_CLK;
}
-static enum handoff rcg_clk_handoff(struct clk *c)
+static struct clk *rcg_clk_get_parent(struct clk *c)
{
struct rcg_clk *rcg = to_rcg_clk(c);
uint32_t ctl_val, ns_val, md_val, ns_mask;
struct clk_freq_tbl *freq;
- enum handoff ret;
ctl_val = readl_relaxed(rcg->b.ctl_reg);
- ret = branch_handoff(&rcg->b, &rcg->c);
- if (ret == HANDOFF_DISABLED_CLK)
- return HANDOFF_DISABLED_CLK;
if (rcg->bank_info) {
const struct bank_masks *bank_masks = rcg->bank_info;
@@ -628,21 +629,40 @@
ns_mask = rcg->ns_mask;
md_val = rcg->md_reg ? readl_relaxed(rcg->md_reg) : 0;
}
+
if (!ns_mask)
- return HANDOFF_UNKNOWN_RATE;
+ return NULL;
+
ns_val = readl_relaxed(rcg->ns_reg) & ns_mask;
for (freq = rcg->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
if ((freq->ns_val & ns_mask) == ns_val &&
(!freq->md_val || freq->md_val == md_val))
break;
}
+
if (freq->freq_hz == FREQ_END)
- return HANDOFF_UNKNOWN_RATE;
+ return NULL;
+ /* Cache the results for the handoff code. */
rcg->current_freq = freq;
- c->parent = freq->src_clk;
- c->rate = freq->freq_hz;
+ return freq->src_clk;
+}
+
+static enum handoff rcg_clk_handoff(struct clk *c)
+{
+ struct rcg_clk *rcg = to_rcg_clk(c);
+ enum handoff ret;
+
+ if (rcg->current_freq && rcg->current_freq->freq_hz != FREQ_END)
+ c->rate = rcg->current_freq->freq_hz;
+
+ ret = branch_handoff(&rcg->b, &rcg->c);
+ if (ret == HANDOFF_DISABLED_CLK)
+ return HANDOFF_DISABLED_CLK;
+
+ rcg->prepared = true;
+ rcg->enabled = true;
return HANDOFF_ENABLED_CLK;
}
@@ -861,6 +881,7 @@
.round_rate = rcg_clk_round_rate,
.reset = rcg_clk_reset,
.set_flags = rcg_clk_set_flags,
+ .get_parent = rcg_clk_get_parent,
};
static int cdiv_clk_enable(struct clk *c)
@@ -940,6 +961,7 @@
reg_val >>= cdiv->div_offset;
cdiv->cur_div = (reg_val & (cdiv->max_div - 1)) + 1;
}
+ c->rate = cdiv->cur_div;
return HANDOFF_ENABLED_CLK;
}
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index cf42355..dd78557 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -69,8 +69,8 @@
#define MND_MODE_MASK BM(13, 12)
#define MND_DUAL_EDGE_MODE_BVAL BVAL(13, 12, 0x2)
#define CMD_RCGR_CONFIG_DIRTY_MASK BM(7, 4)
-#define CBCR_BRANCH_CDIV_MASK BM(24, 16)
-#define CBCR_BRANCH_CDIV_MASKED(val) BVAL(24, 16, (val));
+#define CBCR_CDIV_LSB 16
+#define CBCR_CDIV_MSB 24
enum branch_state {
BRANCH_ON,
@@ -235,21 +235,17 @@
return (rcg->freq_tbl + n)->freq_hz;
}
-static enum handoff _rcg_clk_handoff(struct rcg_clk *rcg, int has_mnd)
+static struct clk *_rcg_clk_get_parent(struct rcg_clk *rcg, int has_mnd)
{
u32 n_regval = 0, m_regval = 0, d_regval = 0;
u32 cfg_regval;
struct clk_freq_tbl *freq;
u32 cmd_rcgr_regval;
- /* Is the root enabled? */
- cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
- if ((cmd_rcgr_regval & CMD_RCGR_ROOT_STATUS_BIT))
- return HANDOFF_DISABLED_CLK;
-
/* Is there a pending configuration? */
+ cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK)
- return HANDOFF_UNKNOWN_RATE;
+ return NULL;
/* Get values of m, n, d, div and src_sel registers. */
if (has_mnd) {
@@ -299,23 +295,45 @@
/* No known frequency found */
if (freq->freq_hz == FREQ_END)
- return HANDOFF_UNKNOWN_RATE;
+ return NULL;
rcg->current_freq = freq;
- rcg->c.parent = freq->src_clk;
- rcg->c.rate = freq->freq_hz;
+ return freq->src_clk;
+}
+
+static enum handoff _rcg_clk_handoff(struct rcg_clk *rcg)
+{
+ u32 cmd_rcgr_regval;
+
+ if (rcg->current_freq && rcg->current_freq->freq_hz != FREQ_END)
+ rcg->c.rate = rcg->current_freq->freq_hz;
+
+ /* Is the root enabled? */
+ cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
+ if ((cmd_rcgr_regval & CMD_RCGR_ROOT_STATUS_BIT))
+ return HANDOFF_DISABLED_CLK;
return HANDOFF_ENABLED_CLK;
}
+static struct clk *rcg_mnd_clk_get_parent(struct clk *c)
+{
+ return _rcg_clk_get_parent(to_rcg_clk(c), 1);
+}
+
+static struct clk *rcg_clk_get_parent(struct clk *c)
+{
+ return _rcg_clk_get_parent(to_rcg_clk(c), 0);
+}
+
static enum handoff rcg_mnd_clk_handoff(struct clk *c)
{
- return _rcg_clk_handoff(to_rcg_clk(c), 1);
+ return _rcg_clk_handoff(to_rcg_clk(c));
}
static enum handoff rcg_clk_handoff(struct clk *c)
{
- return _rcg_clk_handoff(to_rcg_clk(c), 0);
+ return _rcg_clk_handoff(to_rcg_clk(c));
}
#define BRANCH_CHECK_MASK BM(31, 28)
@@ -412,8 +430,8 @@
spin_lock_irqsave(&local_clock_reg_lock, flags);
regval = readl_relaxed(CBCR_REG(branch));
- regval &= ~CBCR_BRANCH_CDIV_MASK;
- regval |= CBCR_BRANCH_CDIV_MASKED(rate);
+ regval &= ~BM(CBCR_CDIV_MSB, CBCR_CDIV_LSB);
+ regval |= BVAL(CBCR_CDIV_MSB, CBCR_CDIV_LSB, rate);
writel_relaxed(regval, CBCR_REG(branch));
spin_unlock_irqrestore(&local_clock_reg_lock, flags);
@@ -496,9 +514,12 @@
if ((cbcr_regval & CBCR_BRANCH_OFF_BIT))
return HANDOFF_DISABLED_CLK;
- if (c->parent) {
- if (c->parent->ops->handoff)
- return c->parent->ops->handoff(c->parent);
+ if (branch->max_div) {
+ cbcr_regval &= BM(CBCR_CDIV_MSB, CBCR_CDIV_LSB);
+ cbcr_regval >>= CBCR_CDIV_LSB;
+ c->rate = cbcr_regval;
+ } else if (!branch->has_sibling) {
+ c->rate = clk_get_rate(c->parent);
}
return HANDOFF_ENABLED_CLK;
@@ -611,6 +632,7 @@
.list_rate = rcg_clk_list_rate,
.round_rate = rcg_clk_round_rate,
.handoff = rcg_clk_handoff,
+ .get_parent = rcg_clk_get_parent,
};
struct clk_ops clk_ops_rcg_mnd = {
@@ -619,6 +641,7 @@
.list_rate = rcg_clk_list_rate,
.round_rate = rcg_clk_round_rate,
.handoff = rcg_mnd_clk_handoff,
+ .get_parent = rcg_mnd_clk_get_parent,
};
struct clk_ops clk_ops_branch = {
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 79bc639..aca6494 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -348,6 +348,16 @@
return ret;
}
+static enum handoff mdss_dsi_pll_handoff(struct clk *c)
+{
+ /*
+ * FIXME: Continuous display is not implemented. So the display is
+ * always off. Implement a poor man's handoff by always returning
+ * "disabled".
+ */
+ return HANDOFF_DISABLED_CLK;
+}
+
void hdmi_pll_disable(void)
{
clk_enable(mdss_dsi_ahb_clk);
@@ -766,6 +776,7 @@
.disable = mdss_dsi_pll_disable,
.set_rate = mdss_dsi_pll_pixel_set_rate,
.round_rate = mdss_dsi_pll_pixel_round_rate,
+ .handoff = mdss_dsi_pll_handoff,
};
struct clk_ops clk_ops_dsi_byte_pll = {
@@ -773,4 +784,5 @@
.disable = mdss_dsi_pll_disable,
.set_rate = mdss_dsi_pll_byte_set_rate,
.round_rate = mdss_dsi_pll_byte_round_rate,
+ .handoff = mdss_dsi_pll_handoff,
};
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index a4def28..c1cc27b 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -285,6 +285,18 @@
if (rc < 0)
return HANDOFF_DISABLED_CLK;
+ /*
+ * Since RPM handoff code may update the software rate of the clock by
+ * querying the RPM, we need to make sure our request to RPM now
+ * matches the software rate of the clock. When we send the request
+ * to RPM, we also need to update any other state info we would
+ * normally update. So, call the appropriate clock function instead
+ * of directly using the RPM driver APIs.
+ */
+ rc = rpm_clk_prepare(clk);
+ if (rc < 0)
+ return HANDOFF_DISABLED_CLK;
+
return HANDOFF_ENABLED_CLK;
}
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index 7421ba6..c3145ef 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -139,11 +138,17 @@
static enum handoff voter_clk_handoff(struct clk *clk)
{
- /* Apply default rate vote */
- if (clk->rate)
- return HANDOFF_ENABLED_CLK;
+ if (!clk->rate)
+ return HANDOFF_DISABLED_CLK;
- return HANDOFF_DISABLED_CLK;
+ /*
+ * Send the default rate to the parent if necessary and update the
+ * software state of the voter clock.
+ */
+ if (voter_clk_prepare(clk) < 0)
+ return HANDOFF_DISABLED_CLK;
+
+ return HANDOFF_ENABLED_CLK;
}
struct clk_ops clk_ops_voter = {
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index c2bf5ba..e0ee084 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/clock.c
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2013, 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
@@ -467,56 +467,83 @@
}
EXPORT_SYMBOL(msm_clock_register);
-static enum handoff __init __handoff_clk(struct clk *clk)
+static int __init __handoff_clk(struct clk *clk)
{
- enum handoff ret;
- struct handoff_clk *h;
- unsigned long rate;
- int err = 0;
+ enum handoff state = HANDOFF_DISABLED_CLK;
+ struct handoff_clk *h = NULL;
+ int rc;
+
+ if (clk == NULL || clk->flags & CLKFLAG_INIT_DONE ||
+ clk->flags & CLKFLAG_SKIP_HANDOFF)
+ return 0;
+
+ if (clk->flags & CLKFLAG_INIT_ERR)
+ return -ENXIO;
+
+ /* Handoff any 'depends' clock first. */
+ rc = __handoff_clk(clk->depends);
+ if (rc)
+ goto err;
/*
- * Tree roots don't have parents, but need to be handed off. So,
- * terminate recursion by returning "enabled". Also return "enabled"
- * for clocks with non-zero enable counts since they must have already
- * been handed off.
+ * Handoff functions for the parent must be called before the
+ * children can be handed off. Without handing off the parents and
+ * knowing their rate and state (on/off), it's impossible to figure
+ * out the rate and state of the children.
*/
- if (clk == NULL || clk->count)
- return HANDOFF_ENABLED_CLK;
+ if (clk->ops->get_parent)
+ clk->parent = clk->ops->get_parent(clk);
- /* Clocks without handoff functions are assumed to be disabled. */
- if (!clk->ops->handoff || (clk->flags & CLKFLAG_SKIP_HANDOFF))
- return HANDOFF_DISABLED_CLK;
+ if (IS_ERR(clk->parent)) {
+ rc = PTR_ERR(clk->parent);
+ goto err;
+ }
- /*
- * Handoff functions for children must be called before their parents'
- * so that the correct parent is available below.
- */
- ret = clk->ops->handoff(clk);
- if (ret == HANDOFF_ENABLED_CLK) {
- ret = __handoff_clk(clk->parent);
- if (ret == HANDOFF_ENABLED_CLK) {
- h = kmalloc(sizeof(*h), GFP_KERNEL);
- if (!h) {
- err = -ENOMEM;
- goto out;
- }
- err = clk_prepare_enable(clk);
- if (err)
- goto out;
- rate = clk_get_rate(clk);
- if (rate)
- pr_debug("%s rate=%lu\n", clk->dbg_name, rate);
- h->clk = clk;
- list_add_tail(&h->list, &handoff_list);
+ rc = __handoff_clk(clk->parent);
+ if (rc)
+ goto err;
+
+ if (clk->ops->handoff)
+ state = clk->ops->handoff(clk);
+
+ if (state == HANDOFF_ENABLED_CLK) {
+
+ h = kmalloc(sizeof(*h), GFP_KERNEL);
+ if (!h) {
+ rc = -ENOMEM;
+ goto err;
}
+
+ rc = clk_prepare_enable(clk->parent);
+ if (rc)
+ goto err;
+
+ rc = clk_prepare_enable(clk->depends);
+ if (rc)
+ goto err_depends;
+
+ rc = vote_rate_vdd(clk, clk->rate);
+ WARN(rc, "%s unable to vote for voltage!\n", clk->dbg_name);
+
+ clk->count = 1;
+ clk->prepare_count = 1;
+ h->clk = clk;
+ list_add_tail(&h->list, &handoff_list);
+
+ pr_debug("Handed off %s rate=%lu\n", clk->dbg_name, clk->rate);
}
-out:
- if (err) {
- pr_err("%s handoff failed (%d)\n", clk->dbg_name, err);
- kfree(h);
- ret = HANDOFF_DISABLED_CLK;
- }
- return ret;
+
+ clk->flags |= CLKFLAG_INIT_DONE;
+
+ return 0;
+
+err_depends:
+ clk_disable_unprepare(clk->parent);
+err:
+ kfree(h);
+ clk->flags |= CLKFLAG_INIT_ERR;
+ pr_err("%s handoff failed (%d)\n", clk->dbg_name, rc);
+ return rc;
}
/**
diff --git a/arch/arm/mach-msm/cpuidle.c b/arch/arm/mach-msm/cpuidle.c
index dd2dc1d..056f19e 100644
--- a/arch/arm/mach-msm/cpuidle.c
+++ b/arch/arm/mach-msm/cpuidle.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -80,8 +80,7 @@
cpu_pm_enter();
#endif
- pm_mode = msm_pm_idle_prepare(dev, drv, index);
- dev->last_residency = msm_pm_idle_enter(pm_mode);
+ pm_mode = msm_pm_idle_enter(dev, drv, index);
for (i = 0; i < dev->state_count; i++) {
st_usage = &dev->states_usage[i];
if ((enum msm_pm_sleep_mode) cpuidle_get_statedata(st_usage)
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index c986064..f87c540 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -24,6 +24,7 @@
#include <mach/board.h>
#include <mach/msm_iomap.h>
#include <mach/usbdiag.h>
+#include <mach/msm_serial_hs_lite.h>
#include <mach/msm_sps.h>
#include <mach/dma.h>
#include <mach/msm_dsps.h>
@@ -51,6 +52,7 @@
/* Address of GSBI blocks */
#define MSM_GSBI1_PHYS 0x12440000
+#define MSM_GSBI2_PHYS 0x12480000
#define MSM_GSBI3_PHYS 0x16200000
#define MSM_GSBI4_PHYS 0x16300000
#define MSM_GSBI5_PHYS 0x1A200000
@@ -59,7 +61,9 @@
/* GSBI UART devices */
#define MSM_UART1DM_PHYS (MSM_GSBI1_PHYS + 0x10000)
+#define MSM_UART2DM_PHYS (MSM_GSBI2_PHYS + 0x10000)
#define MSM_UART3DM_PHYS (MSM_GSBI3_PHYS + 0x40000)
+#define MSM_UART4DM_PHYS (MSM_GSBI4_PHYS + 0x40000)
#define MSM_UART5DM_PHYS (MSM_GSBI5_PHYS + 0x40000)
#define MSM_UART6DM_PHYS (MSM_GSBI6_PHYS + 0x40000)
#define MSM_UART7DM_PHYS (MSM_GSBI7_PHYS + 0x40000)
@@ -203,6 +207,38 @@
.resource = resources_uart_gsbi1,
};
+static struct resource resources_uart_gsbi2[] = {
+ {
+ .start = APQ8064_GSBI2_UARTDM_IRQ,
+ .end = APQ8064_GSBI2_UARTDM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART2DM_PHYS,
+ .end = MSM_UART2DM_PHYS + PAGE_SIZE - 1,
+ .name = "uartdm_resource",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MSM_GSBI2_PHYS,
+ .end = MSM_GSBI2_PHYS + PAGE_SIZE - 1,
+ .name = "gsbi_resource",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct msm_serial_hslite_platform_data uart_gsbi2_pdata = {
+ .line = 0,
+};
+
+struct platform_device apq8064_device_uart_gsbi2 = {
+ .name = "msm_serial_hsl",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(resources_uart_gsbi2),
+ .resource = resources_uart_gsbi2,
+ .dev.platform_data = &uart_gsbi2_pdata,
+};
+
static struct resource resources_uart_gsbi3[] = {
{
.start = GSBI3_UARTDM_IRQ,
@@ -350,6 +386,38 @@
.resource = resources_qup_i2c_gsbi4,
};
+static struct resource resources_uart_gsbi4[] = {
+ {
+ .start = GSBI4_UARTDM_IRQ,
+ .end = GSBI4_UARTDM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART4DM_PHYS,
+ .end = MSM_UART4DM_PHYS + PAGE_SIZE - 1,
+ .name = "uartdm_resource",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MSM_GSBI4_PHYS,
+ .end = MSM_GSBI4_PHYS + PAGE_SIZE - 1,
+ .name = "gsbi_resource",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct msm_serial_hslite_platform_data uart_gsbi4_pdata = {
+ .line = 2,
+};
+
+struct platform_device apq8064_device_uart_gsbi4 = {
+ .name = "msm_serial_hsl",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(resources_uart_gsbi4),
+ .resource = resources_uart_gsbi4,
+ .dev.platform_data = &uart_gsbi4_pdata,
+};
+
static struct resource resources_qup_spi_gsbi5[] = {
{
.name = "spi_base",
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 248af88..8301c29 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -85,7 +85,9 @@
extern struct platform_device msm8960_device_ebi1_ch1_erp;
extern struct platform_device apq8064_device_uart_gsbi1;
+extern struct platform_device apq8064_device_uart_gsbi2;
extern struct platform_device apq8064_device_uart_gsbi3;
+extern struct platform_device apq8064_device_uart_gsbi4;
extern struct platform_device apq8064_device_uart_gsbi7;
extern struct platform_device apq8064_device_qup_i2c_gsbi1;
extern struct platform_device apq8064_device_qup_i2c_gsbi3;
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
index 0f2feaa..475b483 100644
--- a/arch/arm/mach-msm/include/mach/clk-provider.h
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2007-2013, 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
@@ -69,7 +69,6 @@
enum handoff {
HANDOFF_ENABLED_CLK,
HANDOFF_DISABLED_CLK,
- HANDOFF_UNKNOWN_RATE,
};
struct clk_ops {
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
index d69b372..1191bb7 100644
--- a/arch/arm/mach-msm/include/mach/clk.h
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2012-2013 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
@@ -21,6 +21,8 @@
#define CLKFLAG_SKIP_HANDOFF 0x00000100
#define CLKFLAG_MIN 0x00000400
#define CLKFLAG_MAX 0x00000800
+#define CLKFLAG_INIT_DONE 0x00001000
+#define CLKFLAG_INIT_ERR 0x00002000
struct clk_lookup;
struct clk;
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
index 137d243..2d47e4e 100644
--- a/arch/arm/mach-msm/include/mach/gpio.h
+++ b/arch/arm/mach-msm/include/mach/gpio.h
@@ -16,7 +16,7 @@
#ifndef __ASM_ARCH_MSM_GPIO_H
#define __ASM_ARCH_MSM_GPIO_H
-#define ARCH_NR_GPIOS 512
+#define ARCH_NR_GPIOS 1024
#include <linux/interrupt.h>
#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index e88c4df..9a031b2 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -199,10 +199,13 @@
SMEM_SSR_REASON_DSPS0,
SMEM_SSR_REASON_VCODEC0,
SMEM_SMP2P_APPS_BASE = 427,
- SMEM_SMP2P_MODEM_BASE = 435,
- SMEM_SMP2P_AUDIO_BASE = 443,
- SMEM_SMP2P_WIRLESS_BASE = 451,
- SMEM_SMP2P_POWER_BASE = 459,
+ SMEM_SMP2P_MODEM_BASE = SMEM_SMP2P_APPS_BASE + 8, /* 435 */
+ SMEM_SMP2P_AUDIO_BASE = SMEM_SMP2P_MODEM_BASE + 8, /* 443 */
+ SMEM_SMP2P_WIRLESS_BASE = SMEM_SMP2P_AUDIO_BASE + 8, /* 451 */
+ SMEM_SMP2P_POWER_BASE = SMEM_SMP2P_WIRLESS_BASE + 8, /* 459 */
+ SMEM_FLASH_DEVICE_INFO = SMEM_SMP2P_POWER_BASE + 8, /* 467 */
+ SMEM_BAM_PIPE_MEMORY, /* 468 */
+ SMEM_IMAGE_VERSION_TABLE, /* 469 */
SMEM_NUM_ITEMS,
};
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index 8c0bf4b..5d1b5e4 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -40,7 +40,7 @@
#define MIN_FRAG_SZ (IPC_ROUTER_HDR_SIZE + sizeof(union rr_control_msg))
-#define NUM_SMD_XPRTS 3
+#define NUM_SMD_XPRTS 4
#define XPRT_NAME_LEN (SMD_MAX_CH_NAME_LEN + 12)
struct msm_ipc_router_smd_xprt {
@@ -76,6 +76,7 @@
{"RPCRPY_CNTL", "ipc_rtr_smd_rpcrpy_cntl", SMD_APPS_MODEM, 1},
{"IPCRTR", "ipc_rtr_smd_ipcrtr", SMD_APPS_MODEM, 1},
{"IPCRTR", "ipc_rtr_q6_ipcrtr", SMD_APPS_QDSP, 1},
+ {"IPCRTR", "ipc_rtr_wcnss_ipcrtr", SMD_APPS_WCNSS, 1},
};
static struct msm_ipc_router_smd_xprt smd_remote_xprt[NUM_SMD_XPRTS];
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index b6d6965..aa03a6a 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -27,9 +27,11 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/krait-regulator.h>
+#include <linux/debugfs.h>
#include <mach/msm_iomap.h>
#include "spm.h"
+#include "pm.h"
/*
* supply
@@ -119,6 +121,18 @@
#define VREF_LDO_BIT_POS 0
#define VREF_LDO_MASK KRAIT_MASK(6, 0)
+#define LDO_HDROOM_MIN 50000
+#define LDO_HDROOM_MAX 250000
+
+#define LDO_UV_MIN 465000
+#define LDO_UV_MAX 750000
+
+#define LDO_TH_MIN 600000
+#define LDO_TH_MAX 900000
+
+#define LDO_DELTA_MIN 10000
+#define LDO_DELTA_MAX 100000
+
/**
* struct pmic_gang_vreg -
* @name: the string used to represent the gang
@@ -138,6 +152,8 @@
struct list_head krait_power_vregs;
struct mutex krait_power_vregs_lock;
bool pfm_mode;
+ int pmic_min_uV_for_retention;
+ bool retention_enabled;
};
static struct pmic_gang_vreg *the_gang;
@@ -162,11 +178,21 @@
int retention_uV;
int headroom_uV;
int ldo_threshold_uV;
+ int ldo_delta_uV;
bool online;
};
static u32 version;
+static int is_between(int left, int right, int value)
+{
+ if (left >= right && left >= value && value >= right)
+ return 1;
+ if (left <= right && left <= value && value <= right)
+ return 1;
+ return 0;
+}
+
static void krait_masked_write(struct krait_power_vreg *kvreg,
int reg, uint32_t mask, uint32_t val)
{
@@ -185,6 +211,23 @@
mb();
}
+static int get_krait_retention_ldo_uv(struct krait_power_vreg *kvreg)
+{
+ uint32_t reg_val;
+ int uV;
+
+ reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
+ reg_val &= VREF_RET_MASK;
+ reg_val >>= VREF_RET_POS;
+
+ if (reg_val == 0)
+ uV = 0;
+ else
+ uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
+
+ return uV;
+}
+
static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
{
uint32_t reg_val;
@@ -260,7 +303,8 @@
static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
{
- if (kvreg->mode == LDO_MODE && get_krait_ldo_uv(kvreg) == kvreg->uV)
+ if (kvreg->mode == LDO_MODE
+ && get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
return 0;
/*
@@ -270,7 +314,7 @@
if (kvreg->mode == LDO_MODE)
switch_to_using_hs(kvreg);
- set_krait_ldo_uv(kvreg, kvreg->uV);
+ set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
/*
* enable ldo - note that both LDO and BHS are are supplying voltage to
@@ -328,6 +372,22 @@
uV = PMIC_VOLTAGE_MAX;
}
+ if (uV < pvreg->pmic_min_uV_for_retention) {
+ if (pvreg->retention_enabled) {
+ pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
+ uV, pvreg->pmic_min_uV_for_retention);
+ msm_pm_enable_retention(false);
+ pvreg->retention_enabled = false;
+ }
+ } else {
+ if (!pvreg->retention_enabled) {
+ pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
+ uV, pvreg->pmic_min_uV_for_retention);
+ msm_pm_enable_retention(true);
+ pvreg->retention_enabled = true;
+ }
+ }
+
setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
rc = msm_spm_apcs_set_vdd(setpoint);
@@ -349,18 +409,19 @@
list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
if (!kvreg->online)
continue;
- if (kvreg->uV > kvreg->ldo_threshold_uV
- || kvreg->uV > vmax - kvreg->headroom_uV) {
- rc = switch_to_using_hs(kvreg);
+ if (kvreg->uV <= kvreg->ldo_threshold_uV
+ && kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
+ <= vmax) {
+ rc = switch_to_using_ldo(kvreg);
if (rc < 0) {
- pr_err("could not switch %s to hs rc = %d\n",
+ pr_err("could not switch %s to ldo rc = %d\n",
kvreg->name, rc);
return rc;
}
} else {
- rc = switch_to_using_ldo(kvreg);
+ rc = switch_to_using_hs(kvreg);
if (rc < 0) {
- pr_err("could not switch %s to ldo rc = %d\n",
+ pr_err("could not switch %s to hs rc = %d\n",
kvreg->name, rc);
return rc;
}
@@ -482,6 +543,8 @@
pvreg->name = "pmic_gang";
pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
pvreg->pmic_phase_count = 1;
+ pvreg->retention_enabled = true;
+ pvreg->pmic_min_uV_for_retention = INT_MAX;
mutex_init(&pvreg->krait_power_vregs_lock);
INIT_LIST_HEAD(&pvreg->krait_power_vregs);
@@ -740,6 +803,43 @@
.is_enabled = krait_power_is_enabled,
};
+static struct dentry *dent;
+static int get_retention_dbg_uV(void *data, u64 *val)
+{
+ struct pmic_gang_vreg *pvreg = data;
+ struct krait_power_vreg *kvreg;
+
+ mutex_lock(&pvreg->krait_power_vregs_lock);
+ if (!list_empty(&pvreg->krait_power_vregs)) {
+ /* return the retention voltage on just the first cpu */
+ kvreg = list_entry((&pvreg->krait_power_vregs)->next,
+ typeof(*kvreg), link);
+ *val = get_krait_retention_ldo_uv(kvreg);
+ }
+ mutex_unlock(&pvreg->krait_power_vregs_lock);
+ return 0;
+}
+
+static int set_retention_dbg_uV(void *data, u64 val)
+{
+ struct pmic_gang_vreg *pvreg = data;
+ struct krait_power_vreg *kvreg;
+ int retention_uV = val;
+
+ if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
+ return -EINVAL;
+
+ mutex_lock(&pvreg->krait_power_vregs_lock);
+ list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
+ kvreg->retention_uV = retention_uV;
+ set_krait_retention_uv(kvreg, retention_uV);
+ }
+ mutex_unlock(&pvreg->krait_power_vregs_lock);
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
+ get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
+
static void kvreg_hw_init(struct krait_power_vreg *kvreg)
{
/*
@@ -765,24 +865,6 @@
pr_debug("version= 0x%x\n", version);
}
-static int is_between(int left, int right, int value)
-{
- if (left >= right && left >= value && value >= right)
- return 1;
- if (left <= right && left <= value && value <= right)
- return 1;
- return 0;
-}
-
-#define LDO_HDROOM_MIN 50000
-#define LDO_HDROOM_MAX 250000
-
-#define LDO_UV_MIN 465000
-#define LDO_UV_MAX 750000
-
-#define LDO_TH_MIN 600000
-#define LDO_TH_MAX 800000
-
static int __devinit krait_power_probe(struct platform_device *pdev)
{
struct krait_power_vreg *kvreg;
@@ -790,6 +872,7 @@
struct regulator_init_data *init_data = pdev->dev.platform_data;
int rc = 0;
int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
+ int ldo_delta_uV;
/* Initialize the pmic gang if it hasn't been initialized already */
if (the_gang == NULL) {
@@ -803,6 +886,12 @@
glb_init(pdev);
}
+ if (dent == NULL) {
+ dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
+ debugfs_create_file("retention_uV",
+ 0644, dent, the_gang, &retention_fops);
+ }
+
if (pdev->dev.of_node) {
/* Get init_data from device tree. */
init_data = of_get_regulator_init_data(&pdev->dev,
@@ -865,6 +954,19 @@
ldo_threshold_uV);
return -EINVAL;
}
+
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,ldo-delta-voltage",
+ &ldo_delta_uV);
+ if (rc < 0) {
+ pr_err("ldo-delta-voltage missing rc=%d\n", rc);
+ return rc;
+ }
+ if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
+ pr_err("bad ldo-delta-voltage = %d specified\n",
+ ldo_delta_uV);
+ return -EINVAL;
+ }
}
if (!init_data) {
@@ -916,10 +1018,14 @@
kvreg->retention_uV = retention_uV;
kvreg->ldo_default_uV = ldo_default_uV;
kvreg->ldo_threshold_uV = ldo_threshold_uV;
+ kvreg->ldo_delta_uV = ldo_delta_uV;
platform_set_drvdata(pdev, kvreg);
mutex_lock(&the_gang->krait_power_vregs_lock);
+ the_gang->pmic_min_uV_for_retention
+ = min(the_gang->pmic_min_uV_for_retention,
+ kvreg->retention_uV + kvreg->headroom_uV);
list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
mutex_unlock(&the_gang->krait_power_vregs_lock);
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 463f2a5..fcb4299 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -57,8 +57,6 @@
bool from_idle, bool notify_rpm)
{
int ret = 0;
- int debug_mask;
- struct msm_rpmrs_limits *l = (struct msm_rpmrs_limits *)limits;
struct msm_lpm_sleep_data sleep_data;
sleep_data.limits = limits;
@@ -66,28 +64,34 @@
atomic_notifier_call_chain(&__get_cpu_var(lpm_notify_head),
MSM_LPM_STATE_ENTER, &sleep_data);
- ret = msm_rpm_enter_sleep();
- if (ret) {
- pr_warn("%s(): RPM failed to enter sleep err:%d\n",
- __func__, ret);
- goto bail;
+ if (notify_rpm) {
+ int debug_mask;
+ struct msm_rpmrs_limits *l = (struct msm_rpmrs_limits *)limits;
+
+ ret = msm_rpm_enter_sleep();
+ if (ret) {
+ pr_warn("%s(): RPM failed to enter sleep err:%d\n",
+ __func__, ret);
+ goto bail;
+ }
+ if (from_idle)
+ debug_mask = msm_lpm_lvl_dbg_msk &
+ MSM_LPM_LVL_DBG_IDLE_LIMITS;
+ else
+ debug_mask = msm_lpm_lvl_dbg_msk &
+ MSM_LPM_LVL_DBG_SUSPEND_LIMITS;
+
+ if (debug_mask)
+ pr_info("%s(): pxo:%d l2:%d mem:0x%x(0x%x) dig:0x%x(0x%x)\n",
+ __func__, l->pxo, l->l2_cache,
+ l->vdd_mem_lower_bound,
+ l->vdd_mem_upper_bound,
+ l->vdd_dig_lower_bound,
+ l->vdd_dig_upper_bound);
+
+ ret = msm_lpmrs_enter_sleep(sclk_count, l, from_idle,
+ notify_rpm);
}
- if (from_idle)
- debug_mask = msm_lpm_lvl_dbg_msk &
- MSM_LPM_LVL_DBG_IDLE_LIMITS;
- else
- debug_mask = msm_lpm_lvl_dbg_msk &
- MSM_LPM_LVL_DBG_SUSPEND_LIMITS;
-
- if (debug_mask)
- pr_info("%s(): pxo:%d l2:%d mem:0x%x(0x%x) dig:0x%x(0x%x)\n",
- __func__, l->pxo, l->l2_cache,
- l->vdd_mem_lower_bound,
- l->vdd_mem_upper_bound,
- l->vdd_dig_lower_bound,
- l->vdd_dig_upper_bound);
-
- ret = msm_lpmrs_enter_sleep(sclk_count, l, from_idle, notify_rpm);
bail:
return ret;
}
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
index ea17efe..d416c19 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -1932,17 +1932,18 @@
}
for (i = 0; i < info->node_info->num_mports; i++) {
- /* If in bypass mode, update priority */
- if (info->node_info->mode != BIMC_QOS_MODE_BYPASS)
+ /* If not in bypass mode, update priority */
+ if (info->node_info->mode != BIMC_QOS_MODE_BYPASS) {
msm_bus_bimc_set_qos_prio(binfo, info->node_info->
qport[i], info->node_info->mode, qmode);
- /* If in fixed mode, update bandwidth */
- if (info->node_info->mode != BIMC_QOS_MODE_FIXED) {
- struct msm_bus_bimc_qos_bw qbw;
- qbw.ws = info->node_info->ws;
- msm_bus_bimc_set_qos_bw(binfo,
- info->node_info->qport[i], &qbw);
+ /* If not in fixed mode, update bandwidth */
+ if (info->node_info->mode != BIMC_QOS_MODE_FIXED) {
+ struct msm_bus_bimc_qos_bw qbw;
+ qbw.ws = info->node_info->ws;
+ msm_bus_bimc_set_qos_bw(binfo,
+ info->node_info->qport[i], &qbw);
+ }
}
/* set mode */
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c b/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
index 88fab96..7c2b4c9 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -101,7 +101,7 @@
if (ret) {
MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n",
rsc_type);
- return ret;
+ goto free_rpm_request;
}
MSM_BUS_DBG("Added Key: %d, Val: %llu, size: %d\n", key,
@@ -112,22 +112,26 @@
if (ret) {
MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n",
rsc_type);
- return ret;
+ goto free_rpm_request;
}
}
msg_id = msm_rpm_send_request(rpm_req);
if (!msg_id) {
MSM_BUS_WARN("RPM: No message ID for req\n");
- return -ENXIO;
+ ret = -ENXIO;
+ goto free_rpm_request;
}
ret = msm_rpm_wait_for_ack(msg_id);
if (ret) {
MSM_BUS_WARN("RPM: Ack failed\n");
- return ret;
+ goto free_rpm_request;
}
+free_rpm_request:
+ msm_rpm_free_request(rpm_req);
+
return ret;
}
diff --git a/arch/arm/mach-msm/msm_watchdog_v2.c b/arch/arm/mach-msm/msm_watchdog_v2.c
index 6aa14a6..ef10cdc 100644
--- a/arch/arm/mach-msm/msm_watchdog_v2.c
+++ b/arch/arm/mach-msm/msm_watchdog_v2.c
@@ -333,7 +333,14 @@
wdog_dd->last_pet, nanosec_rem / 1000);
if (wdog_dd->do_ipi_ping)
dump_cpu_alive_mask(wdog_dd);
- panic("Apps watchdog bark received!");
+ printk(KERN_INFO "Causing a watchdog bite!");
+ __raw_writel(1, wdog_dd->base + WDT0_BITE_TIME);
+ mb();
+ __raw_writel(1, wdog_dd->base + WDT0_RST);
+ mb();
+ /* Delay to make sure bite occurs */
+ mdelay(1);
+ panic("Failed to cause a watchdog bite! - Falling back to kernel panic!");
return IRQ_HANDLED;
}
diff --git a/arch/arm/mach-msm/no-pm.c b/arch/arm/mach-msm/no-pm.c
index 0db6e68..a8d4fdb 100644
--- a/arch/arm/mach-msm/no-pm.c
+++ b/arch/arm/mach-msm/no-pm.c
@@ -37,15 +37,11 @@
void msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls) {}
-int msm_pm_idle_prepare(struct cpuidle_device *dev,
+enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
return -ENOSYS;
}
-int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode)
-{
- return -ENOSYS;
-}
-
void msm_pm_enable_retention(bool enable) {}
+
diff --git a/arch/arm/mach-msm/perf_debug.c b/arch/arm/mach-msm/perf_debug.c
new file mode 100644
index 0000000..52e58a2
--- /dev/null
+++ b/arch/arm/mach-msm/perf_debug.c
@@ -0,0 +1,64 @@
+/* Copyright (c) 2013, 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/types.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+
+/*
+ * Subsequent patches should add an entry to end of this string.
+ * Format is incrementing sequence number followed by text of
+ * patch commit title with newline.
+ * Note trailing ';' is on its own line to simplify addition of
+ * future strings.
+ */
+static char *descriptions =
+ "0 msm: perf: add debug patch logging framework\n"
+;
+
+static ssize_t desc_read(struct file *fp, char __user *buf,
+ size_t count, loff_t *pos)
+{
+ return simple_read_from_buffer(buf, count, pos, descriptions,
+ strlen(descriptions));
+}
+
+static const struct file_operations perf_debug_desc_fops = {
+ .read = desc_read,
+};
+
+static int msm_perf_debugfs_init(void)
+{
+ int ret = 0;
+ struct dentry *dir;
+ struct dentry *file;
+
+ dir = debugfs_create_dir("msm-perf-patches", NULL);
+ if (IS_ERR_OR_NULL(dir)) {
+ pr_err("failed to create msm-perf-patches dir in debugfs\n");
+ ret = PTR_ERR(dir);
+ goto init_exit;
+ }
+
+ file = debugfs_create_file("descriptions", 0444, dir, NULL,
+ &perf_debug_desc_fops);
+ if (IS_ERR_OR_NULL(file)) {
+ debugfs_remove(dir);
+ pr_err("failed to create descriptions file for msm-perf-patches\n");
+ ret = PTR_ERR(file);
+ goto init_exit;
+ }
+
+init_exit:
+ return ret;
+}
+late_initcall(msm_perf_debugfs_init);
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 261d433..af6f8af 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -475,8 +475,6 @@
}
}
-static void *msm_pm_idle_rs_limits;
-
static void msm_pm_swfi(void)
{
msm_pm_config_hw_before_swfi();
@@ -775,8 +773,9 @@
}
}
-int msm_pm_idle_prepare(struct cpuidle_device *dev,
- struct cpuidle_driver *drv, int index)
+static int msm_pm_idle_prepare(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index,
+ void **msm_pm_idle_rs_limits)
{
int i;
unsigned int power_usage = -1;
@@ -803,7 +802,6 @@
struct cpuidle_state_usage *st_usage = &dev->states_usage[i];
enum msm_pm_sleep_mode mode;
bool allow;
- void *rs_limits = NULL;
uint32_t power;
int idx;
@@ -850,17 +848,20 @@
/* fall through */
if (pm_sleep_ops.lowest_limits)
- rs_limits = pm_sleep_ops.lowest_limits(true,
- mode, &time_param, &power);
+ *msm_pm_idle_rs_limits =
+ pm_sleep_ops.lowest_limits(
+ true, mode,
+ &time_param, &power);
if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
pr_info("CPU%u: %s: %s, latency %uus, "
"sleep %uus, limit %p\n",
dev->cpu, __func__, state->desc,
time_param.latency_us,
- time_param.sleep_us, rs_limits);
+ time_param.sleep_us,
+ *msm_pm_idle_rs_limits);
- if (!rs_limits)
+ if (!*msm_pm_idle_rs_limits)
allow = false;
break;
@@ -880,8 +881,6 @@
ret = mode;
}
- if (MSM_PM_SLEEP_MODE_POWER_COLLAPSE == mode)
- msm_pm_idle_rs_limits = rs_limits;
}
}
@@ -895,11 +894,27 @@
return ret;
}
-int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode)
+enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
{
int64_t time;
- int exit_stat;
bool collapsed = 1;
+ int exit_stat = -1;
+ enum msm_pm_sleep_mode sleep_mode;
+ void *msm_pm_idle_rs_limits = NULL;
+ int sleep_delay = 1;
+ int ret = -ENODEV;
+ int64_t timer_expiration = 0;
+ int notify_rpm = false;
+ bool timer_halted = false;
+
+ sleep_mode = msm_pm_idle_prepare(dev, drv, index,
+ &msm_pm_idle_rs_limits);
+
+ if (!msm_pm_idle_rs_limits) {
+ sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
+ goto cpuidle_enter_bail;
+ }
if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
pr_info("CPU%u: %s: mode %d\n",
@@ -907,76 +922,80 @@
time = ktime_to_ns(ktime_get());
- switch (sleep_mode) {
- case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
- msm_pm_swfi();
- exit_stat = MSM_PM_STAT_IDLE_WFI;
- break;
-
- case MSM_PM_SLEEP_MODE_RETENTION:
- msm_pm_retention();
- exit_stat = MSM_PM_STAT_RETENTION;
- break;
-
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
- collapsed = msm_pm_power_collapse_standalone(true);
- exit_stat = MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
- break;
-
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE: {
- int64_t timer_expiration = 0;
- bool timer_halted = false;
- uint32_t sleep_delay;
- int ret = -ENODEV;
- int notify_rpm =
- (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE);
+ if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
+ notify_rpm = true;
timer_expiration = msm_pm_timer_enter_idle();
sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
if (sleep_delay == 0) /* 0 would mean infinite time */
sleep_delay = 1;
+ }
- if (MSM_PM_DEBUG_IDLE_CLK & msm_pm_debug_mask)
- clock_debug_print_enabled();
+ if (pm_sleep_ops.enter_sleep)
+ ret = pm_sleep_ops.enter_sleep(sleep_delay,
+ msm_pm_idle_rs_limits,
+ true, notify_rpm);
+ if (!ret) {
- if (pm_sleep_ops.enter_sleep)
- ret = pm_sleep_ops.enter_sleep(sleep_delay,
- msm_pm_idle_rs_limits,
- true, notify_rpm);
- if (!ret) {
+ switch (sleep_mode) {
+ case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
+ msm_pm_swfi();
+ exit_stat = MSM_PM_STAT_IDLE_WFI;
+ break;
+
+ case MSM_PM_SLEEP_MODE_RETENTION:
+ msm_pm_retention();
+ exit_stat = MSM_PM_STAT_RETENTION;
+ break;
+
+ case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
+ collapsed = msm_pm_power_collapse_standalone(true);
+ exit_stat = MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
+ break;
+
+ case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
+ if (MSM_PM_DEBUG_IDLE_CLK & msm_pm_debug_mask)
+ clock_debug_print_enabled();
+
collapsed = msm_pm_power_collapse(true);
timer_halted = true;
- if (pm_sleep_ops.exit_sleep)
- pm_sleep_ops.exit_sleep(msm_pm_idle_rs_limits,
- true, notify_rpm, collapsed);
+ exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
+ msm_pm_timer_exit_idle(timer_halted);
+ break;
+
+ case MSM_PM_SLEEP_MODE_NOT_SELECTED:
+ goto cpuidle_enter_bail;
+ break;
+
+ default:
+ __WARN();
+ goto cpuidle_enter_bail;
+ break;
}
+ if (pm_sleep_ops.exit_sleep)
+ pm_sleep_ops.exit_sleep(msm_pm_idle_rs_limits,
+ true, notify_rpm, collapsed);
+
+ time = ktime_to_ns(ktime_get()) - time;
+ msm_pm_ftrace_lpm_exit(smp_processor_id(), sleep_mode,
+ collapsed);
+ if (exit_stat >= 0)
+ msm_pm_add_stat(exit_stat, time);
+ do_div(time, 1000);
+ dev->last_residency = (int) time;
+ return sleep_mode;
+
+ } else if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
msm_pm_timer_exit_idle(timer_halted);
- exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
- break;
- }
-
- case MSM_PM_SLEEP_MODE_NOT_SELECTED:
- goto cpuidle_enter_bail;
- break;
-
- default:
- __WARN();
- goto cpuidle_enter_bail;
- break;
- }
-
- time = ktime_to_ns(ktime_get()) - time;
- msm_pm_add_stat(exit_stat, time);
- msm_pm_ftrace_lpm_exit(smp_processor_id(), sleep_mode,
- collapsed);
-
- do_div(time, 1000);
- return (int) time;
+ sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
+ } else
+ sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
cpuidle_enter_bail:
- return 0;
+ dev->last_residency = 0;
+ return sleep_mode;
}
void msm_pm_cpu_enter_lowpower(unsigned int cpu)
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 399194a..43bb7de 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -108,10 +108,9 @@
};
void msm_pm_set_platform_data(struct msm_pm_platform_data *data, int count);
-int msm_pm_idle_prepare(struct cpuidle_device *dev,
+enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index);
void msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls);
-int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode);
void msm_pm_cpu_enter_lowpower(unsigned int cpu);
void __init msm_pm_set_tz_retention_flag(unsigned int flag);
void msm_pm_enable_retention(bool enable);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index 67ef0ad..fc0de3b 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1030,7 +1030,7 @@
return 0;
}
-static void audio_aio_ioport_reset(struct q6audio_aio *audio)
+void audio_aio_ioport_reset(struct q6audio_aio *audio)
{
if (audio->drv_status & ADRV_STATUS_AIO_INTF) {
/* If fsync is in progress, make sure
@@ -1204,15 +1204,15 @@
audio, audio->ac->session);
mutex_lock(&audio->lock);
audio->stopped = 1;
- audio_aio_flush(audio);
- audio->enabled = 0;
- audio->drv_status &= ~ADRV_STATUS_PAUSE;
+ rc = audio_aio_flush(audio);
if (rc < 0) {
pr_err("%s[%p]:Audio Stop procedure failed rc=%d\n",
__func__, audio, rc);
mutex_unlock(&audio->lock);
break;
}
+ audio->enabled = 0;
+ audio->drv_status &= ~ADRV_STATUS_PAUSE;
if (audio->drv_status & ADRV_STATUS_FSYNC) {
pr_debug("%s[%p] Waking up the audio_aio_fsync\n",
__func__, audio);
@@ -1261,8 +1261,6 @@
}
/* Flush DSP */
rc = audio_aio_flush(audio);
- /* Flush input / Output buffer in software*/
- audio_aio_ioport_reset(audio);
if (rc < 0) {
pr_err("%s[%p]:AUDIO_FLUSH interrupted\n",
__func__, audio);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
index d518254..81232ad 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
@@ -1,6 +1,6 @@
/* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2013, 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
@@ -212,6 +212,7 @@
int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync);
void audio_aio_async_out_flush(struct q6audio_aio *audio);
void audio_aio_async_in_flush(struct q6audio_aio *audio);
+void audio_aio_ioport_reset(struct q6audio_aio *audio);
#ifdef CONFIG_DEBUG_FS
ssize_t audio_aio_debug_open(struct inode *inode, struct file *file);
ssize_t audio_aio_debug_read(struct file *file, char __user *buf,
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
index 96f823f..3fe9e95 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013 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
@@ -39,6 +39,9 @@
case ASM_DATA_EVENT_ENC_SR_CM_NOTIFY:
audio_aio_cb(opcode, token, payload, audio);
break;
+ case APR_BASIC_RSP_RESULT:
+ audio_aio_cb(opcode, token, payload, audio);
+ break;
default:
pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode);
break;
@@ -106,6 +109,26 @@
e_payload.stream_info.sample_rate = audio->pcm_cfg.sample_rate;
audio_aio_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload);
break;
+ case APR_BASIC_RSP_RESULT:
+ switch (payload[0]) {
+ case ASM_STREAM_CMD_FLUSH:
+ if (payload[1] == ADSP_EOK) {
+ pr_debug("%s: FLUSH CMD success\n", __func__);
+ audio_aio_ioport_reset(audio);
+ audio->wflush = 0;
+ audio->rflush = 0;
+ } else {
+ pr_err("%s: FLUSH CMD failed with status:%d\n",
+ __func__, payload[1]);
+ audio_aio_ioport_reset(audio);
+ audio->wflush = 0;
+ audio->rflush = 0;
+ }
+ break;
+ default:
+ pr_debug("%s: cmd%x cmd_status:%d\n",
+ __func__, payload[0], payload[1]);
+ }
default:
break;
}
diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c
index 1f6bd1d..e734ece 100644
--- a/drivers/coresight/coresight-csr.c
+++ b/drivers/coresight/coresight-csr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/err.h>
#include <linux/slab.h>
+#include <linux/of.h>
#include <linux/of_coresight.h>
#include <linux/coresight.h>
@@ -74,6 +75,7 @@
void __iomem *base;
struct device *dev;
struct coresight_device *csdev;
+ uint32_t blksize;
};
static struct csr_drvdata *csrdrvdata;
@@ -86,7 +88,7 @@
CSR_UNLOCK(drvdata);
usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
- usbbamctrl = (usbbamctrl & ~0x3) | BLKSIZE_2048;
+ usbbamctrl = (usbbamctrl & ~0x3) | drvdata->blksize;
csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);
usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
@@ -119,6 +121,7 @@
static int __devinit csr_probe(struct platform_device *pdev)
{
+ int ret;
struct device *dev = &pdev->dev;
struct coresight_platform_data *pdata;
struct csr_drvdata *drvdata;
@@ -148,6 +151,13 @@
if (!drvdata->base)
return -ENOMEM;
+ if (pdev->dev.of_node) {
+ ret = of_property_read_u32(pdev->dev.of_node, "qcom,blk-size",
+ &drvdata->blksize);
+ if (ret)
+ drvdata->blksize = BLKSIZE_256;
+ }
+
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
if (!desc)
return -ENOMEM;
diff --git a/drivers/crypto/msm/qcryptohw_50.h b/drivers/crypto/msm/qcryptohw_50.h
index d77311d..0fb924f 100644
--- a/drivers/crypto/msm/qcryptohw_50.h
+++ b/drivers/crypto/msm/qcryptohw_50.h
@@ -59,77 +59,78 @@
#define CRYPTO_ENCR_XTS_KEY6_REG 0x1D038
#define CRYPTO_ENCR_XTS_KEY7_REG 0x1D03C
-#define CRYPTO_ENCR_PIP0_KEY0_REG 0x1E000
-#define CRYPTO_ENCR_PIP0_KEY1_REG 0x1E004
-#define CRYPTO_ENCR_PIP0_KEY2_REG 0x1E008
-#define CRYPTO_ENCR_PIP0_KEY3_REG 0x1E00C
-#define CRYPTO_ENCR_PIP0_KEY4_REG 0x1E010
-#define CRYPTO_ENCR_PIP0_KEY5_REG 0x1E004
-#define CRYPTO_ENCR_PIP0_KEY6_REG 0x1E008
-#define CRYPTO_ENCR_PIP0_KEY7_REG 0x1E00C
+#define CRYPTO_ENCR_PIPE0_KEY0_REG 0x1E000
+#define CRYPTO_ENCR_PIPE0_KEY1_REG 0x1E004
+#define CRYPTO_ENCR_PIPE0_KEY2_REG 0x1E008
+#define CRYPTO_ENCR_PIPE0_KEY3_REG 0x1E00C
+#define CRYPTO_ENCR_PIPE0_KEY4_REG 0x1E010
+#define CRYPTO_ENCR_PIPE0_KEY5_REG 0x1E004
+#define CRYPTO_ENCR_PIPE0_KEY6_REG 0x1E008
+#define CRYPTO_ENCR_PIPE0_KEY7_REG 0x1E00C
-#define CRYPTO_ENCR_PIP1_KEY0_REG 0x1E000
-#define CRYPTO_ENCR_PIP1_KEY1_REG 0x1E004
-#define CRYPTO_ENCR_PIP1_KEY2_REG 0x1E008
-#define CRYPTO_ENCR_PIP1_KEY3_REG 0x1E00C
-#define CRYPTO_ENCR_PIP1_KEY4_REG 0x1E010
-#define CRYPTO_ENCR_PIP1_KEY5_REG 0x1E014
-#define CRYPTO_ENCR_PIP1_KEY6_REG 0x1E018
-#define CRYPTO_ENCR_PIP1_KEY7_REG 0x1E01C
+#define CRYPTO_ENCR_PIPE1_KEY0_REG 0x1E020
+#define CRYPTO_ENCR_PIPE1_KEY1_REG 0x1E024
+#define CRYPTO_ENCR_PIPE1_KEY2_REG 0x1E028
+#define CRYPTO_ENCR_PIPE1_KEY3_REG 0x1E02C
+#define CRYPTO_ENCR_PIPE1_KEY4_REG 0x1E030
+#define CRYPTO_ENCR_PIPE1_KEY5_REG 0x1E034
+#define CRYPTO_ENCR_PIPE1_KEY6_REG 0x1E038
+#define CRYPTO_ENCR_PIPE1_KEY7_REG 0x1E03C
-#define CRYPTO_ENCR_PIP2_KEY0_REG 0x1E020
-#define CRYPTO_ENCR_PIP2_KEY1_REG 0x1E024
-#define CRYPTO_ENCR_PIP2_KEY2_REG 0x1E028
-#define CRYPTO_ENCR_PIP2_KEY3_REG 0x1E02C
-#define CRYPTO_ENCR_PIP2_KEY4_REG 0x1E030
-#define CRYPTO_ENCR_PIP2_KEY5_REG 0x1E034
-#define CRYPTO_ENCR_PIP2_KEY6_REG 0x1E038
-#define CRYPTO_ENCR_PIP2_KEY7_REG 0x1E03C
+#define CRYPTO_ENCR_PIPE2_KEY0_REG 0x1E040
+#define CRYPTO_ENCR_PIPE2_KEY1_REG 0x1E044
+#define CRYPTO_ENCR_PIPE2_KEY2_REG 0x1E048
+#define CRYPTO_ENCR_PIPE2_KEY3_REG 0x1E04C
+#define CRYPTO_ENCR_PIPE2_KEY4_REG 0x1E050
+#define CRYPTO_ENCR_PIPE2_KEY5_REG 0x1E054
+#define CRYPTO_ENCR_PIPE2_KEY6_REG 0x1E058
+#define CRYPTO_ENCR_PIPE2_KEY7_REG 0x1E05C
-#define CRYPTO_ENCR_PIP3_KEY0_REG 0x1E040
-#define CRYPTO_ENCR_PIP3_KEY1_REG 0x1E044
-#define CRYPTO_ENCR_PIP3_KEY2_REG 0x1E048
-#define CRYPTO_ENCR_PIP3_KEY3_REG 0x1E04C
-#define CRYPTO_ENCR_PIP3_KEY4_REG 0x1E050
-#define CRYPTO_ENCR_PIP3_KEY5_REG 0x1E054
-#define CRYPTO_ENCR_PIP3_KEY6_REG 0x1E058
-#define CRYPTO_ENCR_PIP3_KEY7_REG 0x1E05C
+#define CRYPTO_ENCR_PIPE3_KEY0_REG 0x1E060
+#define CRYPTO_ENCR_PIPE3_KEY1_REG 0x1E064
+#define CRYPTO_ENCR_PIPE3_KEY2_REG 0x1E068
+#define CRYPTO_ENCR_PIPE3_KEY3_REG 0x1E06C
+#define CRYPTO_ENCR_PIPE3_KEY4_REG 0x1E070
+#define CRYPTO_ENCR_PIPE3_KEY5_REG 0x1E074
+#define CRYPTO_ENCR_PIPE3_KEY6_REG 0x1E078
+#define CRYPTO_ENCR_PIPE3_KEY7_REG 0x1E07C
-#define CRYPTO_ENCR_PIP0_XTS_KEY0_REG 0x1E200
-#define CRYPTO_ENCR_PIP0_XTS_KEY1_REG 0x1E204
-#define CRYPTO_ENCR_PIP0_XTS_KEY2_REG 0x1E208
-#define CRYPTO_ENCR_PIP0_XTS_KEY3_REG 0x1E20C
-#define CRYPTO_ENCR_PIP0_XTS_KEY4_REG 0x1E210
-#define CRYPTO_ENCR_PIP0_XTS_KEY5_REG 0x1E214
-#define CRYPTO_ENCR_PIP0_XTS_KEY6_REG 0x1E218
-#define CRYPTO_ENCR_PIP0_XTS_KEY7_REG 0x1E21C
-#define CRYPTO_ENCR_PIP1_XTS_KEY0_REG 0x1E220
-#define CRYPTO_ENCR_PIP1_XTS_KEY1_REG 0x1E224
-#define CRYPTO_ENCR_PIP1_XTS_KEY2_REG 0x1E228
-#define CRYPTO_ENCR_PIP1_XTS_KEY3_REG 0x1E22C
-#define CRYPTO_ENCR_PIP1_XTS_KEY4_REG 0x1E230
-#define CRYPTO_ENCR_PIP1_XTS_KEY5_REG 0x1E234
-#define CRYPTO_ENCR_PIP1_XTS_KEY6_REG 0x1E238
-#define CRYPTO_ENCR_PIP1_XTS_KEY7_REG 0x1E23C
+#define CRYPTO_ENCR_PIPE0_XTS_KEY0_REG 0x1E200
+#define CRYPTO_ENCR_PIPE0_XTS_KEY1_REG 0x1E204
+#define CRYPTO_ENCR_PIPE0_XTS_KEY2_REG 0x1E208
+#define CRYPTO_ENCR_PIPE0_XTS_KEY3_REG 0x1E20C
+#define CRYPTO_ENCR_PIPE0_XTS_KEY4_REG 0x1E210
+#define CRYPTO_ENCR_PIPE0_XTS_KEY5_REG 0x1E214
+#define CRYPTO_ENCR_PIPE0_XTS_KEY6_REG 0x1E218
+#define CRYPTO_ENCR_PIPE0_XTS_KEY7_REG 0x1E21C
-#define CRYPTO_ENCR_PIP2_XTS_KEY0_REG 0x1E240
-#define CRYPTO_ENCR_PIP2_XTS_KEY1_REG 0x1E244
-#define CRYPTO_ENCR_PIP2_XTS_KEY2_REG 0x1E248
-#define CRYPTO_ENCR_PIP2_XTS_KEY3_REG 0x1E24C
-#define CRYPTO_ENCR_PIP2_XTS_KEY4_REG 0x1E250
-#define CRYPTO_ENCR_PIP2_XTS_KEY5_REG 0x1E254
-#define CRYPTO_ENCR_PIP2_XTS_KEY6_REG 0x1E258
-#define CRYPTO_ENCR_PIP2_XTS_KEY7_REG 0x1E25C
+#define CRYPTO_ENCR_PIPE1_XTS_KEY0_REG 0x1E220
+#define CRYPTO_ENCR_PIPE1_XTS_KEY1_REG 0x1E224
+#define CRYPTO_ENCR_PIPE1_XTS_KEY2_REG 0x1E228
+#define CRYPTO_ENCR_PIPE1_XTS_KEY3_REG 0x1E22C
+#define CRYPTO_ENCR_PIPE1_XTS_KEY4_REG 0x1E230
+#define CRYPTO_ENCR_PIPE1_XTS_KEY5_REG 0x1E234
+#define CRYPTO_ENCR_PIPE1_XTS_KEY6_REG 0x1E238
+#define CRYPTO_ENCR_PIPE1_XTS_KEY7_REG 0x1E23C
-#define CRYPTO_ENCR_PIP3_XTS_KEY0_REG 0x1E260
-#define CRYPTO_ENCR_PIP3_XTS_KEY1_REG 0x1E264
-#define CRYPTO_ENCR_PIP3_XTS_KEY2_REG 0x1E268
-#define CRYPTO_ENCR_PIP3_XTS_KEY3_REG 0x1E26C
-#define CRYPTO_ENCR_PIP3_XTS_KEY4_REG 0x1E270
-#define CRYPTO_ENCR_PIP3_XTS_KEY5_REG 0x1E274
-#define CRYPTO_ENCR_PIP3_XTS_KEY6_REG 0x1E278
-#define CRYPTO_ENCR_PIP3_XTS_KEY7_REG 0x1E27C
+#define CRYPTO_ENCR_PIPE2_XTS_KEY0_REG 0x1E240
+#define CRYPTO_ENCR_PIPE2_XTS_KEY1_REG 0x1E244
+#define CRYPTO_ENCR_PIPE2_XTS_KEY2_REG 0x1E248
+#define CRYPTO_ENCR_PIPE2_XTS_KEY3_REG 0x1E24C
+#define CRYPTO_ENCR_PIPE2_XTS_KEY4_REG 0x1E250
+#define CRYPTO_ENCR_PIPE2_XTS_KEY5_REG 0x1E254
+#define CRYPTO_ENCR_PIPE2_XTS_KEY6_REG 0x1E258
+#define CRYPTO_ENCR_PIPE2_XTS_KEY7_REG 0x1E25C
+
+#define CRYPTO_ENCR_PIPE3_XTS_KEY0_REG 0x1E260
+#define CRYPTO_ENCR_PIPE3_XTS_KEY1_REG 0x1E264
+#define CRYPTO_ENCR_PIPE3_XTS_KEY2_REG 0x1E268
+#define CRYPTO_ENCR_PIPE3_XTS_KEY3_REG 0x1E26C
+#define CRYPTO_ENCR_PIPE3_XTS_KEY4_REG 0x1E270
+#define CRYPTO_ENCR_PIPE3_XTS_KEY5_REG 0x1E274
+#define CRYPTO_ENCR_PIPE3_XTS_KEY6_REG 0x1E278
+#define CRYPTO_ENCR_PIPE3_XTS_KEY7_REG 0x1E27C
#define CRYPTO_CNTR0_IV0_REG 0x1A20C
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 10f8ae1..7016931 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -933,7 +933,8 @@
if (pdata->set_grp_async != NULL)
pdata->set_grp_async();
- if (pdata->num_levels > KGSL_MAX_PWRLEVELS) {
+ if (pdata->num_levels > KGSL_MAX_PWRLEVELS ||
+ pdata->num_levels < 1) {
KGSL_PWR_ERR(device, "invalid power level count: %d\n",
pdata->num_levels);
result = -EINVAL;
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index 490fac8..e57fcd8 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -25,6 +25,7 @@
#include <linux/scatterlist.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/kmemleak.h>
#include <asm/sizes.h>
@@ -120,6 +121,8 @@
goto fail_mem;
}
+ kmemleak_not_leak(buf);
+
return 0;
fail_mem:
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index 729450d..7716ccb 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, 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
diff --git a/drivers/power/bq28400_battery.c b/drivers/power/bq28400_battery.c
index 1852687..beab4e2 100644
--- a/drivers/power/bq28400_battery.c
+++ b/drivers/power/bq28400_battery.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013 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
@@ -136,6 +136,8 @@
struct power_supply batt_psy;
struct power_supply *dc_psy;
bool is_charging_enabled;
+ u32 temp_cold; /* in degree celsius */
+ u32 temp_hot; /* in degree celsius */
};
static struct bq28400_device *bq28400_dev;
@@ -486,10 +488,14 @@
int rsoc;
s16 current_ma = 0;
u16 battery_status;
+ int temperature;
+ struct bq28400_device *dev = i2c_get_clientdata(client);
battery_status = bq28400_read_reg(client, SBS_BATTERY_STATUS);
rsoc = bq28400_read_rsoc(client);
current_ma = bq28400_read_current(client);
+ temperature = bq28400_read_temperature(client);
+ temperature = temperature / 10; /* in degree celsius */
if (battery_status & BAT_STATUS_EMPTY)
pr_debug("Battery report Empty.\n");
@@ -513,8 +519,11 @@
return POWER_SUPPLY_STATUS_FULL;
}
- /* Enable charging when battery is not full */
- bq28400_enable_charging(bq28400_dev, true);
+ /* Enable charging when battery is not full and temperature is ok */
+ if ((temperature > dev->temp_cold) && (temperature < dev->temp_hot))
+ bq28400_enable_charging(bq28400_dev, true);
+ else
+ bq28400_enable_charging(bq28400_dev, false);
/*
* Positive current indicates charging
@@ -825,6 +834,12 @@
const struct i2c_device_id *id)
{
int ret = 0;
+ struct device_node *dev_node = client->dev.of_node;
+
+ if (dev_node == NULL) {
+ pr_err("Device Tree node doesn't exist.\n");
+ return -ENODEV;
+ }
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -843,6 +858,23 @@
return -ENOMEM;
}
+ /* Note: Lithium-ion battery normal temperature range 0..40 C */
+ ret = of_property_read_u32(dev_node, "ti,temp-cold",
+ &(bq28400_dev->temp_cold));
+ if (ret) {
+ pr_err("Unable to read cold temperature. ret=%d.\n", ret);
+ goto err_dev_node;
+ }
+ pr_debug("cold temperature limit = %d C.\n", bq28400_dev->temp_cold);
+
+ ret = of_property_read_u32(dev_node, "ti,temp-hot",
+ &(bq28400_dev->temp_hot));
+ if (ret) {
+ pr_err("Unable to read hot temperature. ret=%d.\n", ret);
+ goto err_dev_node;
+ }
+ pr_debug("hot temperature limit = %d C.\n", bq28400_dev->temp_hot);
+
bq28400_dev->client = client;
i2c_set_clientdata(client, bq28400_dev);
@@ -864,7 +896,7 @@
schedule_delayed_work(&bq28400_dev->periodic_user_space_update_work,
msecs_to_jiffies(1000));
- pr_info("Device is ready.\n");
+ pr_debug("Device is ready.\n");
return 0;
@@ -873,6 +905,7 @@
debugfs_remove_recursive(bq28400_dev->dent);
power_supply_unregister(&bq28400_dev->batt_psy);
err_register_psy:
+err_dev_node:
kfree(bq28400_dev);
bq28400_dev = NULL;
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 8002e9e..63cab43 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -34,6 +34,8 @@
/* Coulomb counter clear registers */
#define BMS1_CC_DATA_CTL 0x42
#define BMS1_CC_CLEAR_CTL 0x43
+/* BMS Tolerances */
+#define BMS1_TOL_CTL 0X44
/* OCV limit registers */
#define BMS1_OCV_USE_LOW_LIMIT_THR0 0x48
#define BMS1_OCV_USE_LOW_LIMIT_THR1 0x49
@@ -203,6 +205,7 @@
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
};
+static bool bms_reset;
static int qpnp_read_wrapper(struct qpnp_bms_chip *chip, u8 *val,
u16 base, int count)
@@ -889,6 +892,12 @@
chip->iavg_num_samples);
}
+ /*
+ * if we're in bms reset mode, force uuc to be 3% of fcc
+ */
+ if (bms_reset)
+ return (params->fcc_uah * 3) / 100;
+
uuc_uah_iavg = calculate_termination_uuc(chip, params, uuc_iavg_ma,
batt_temp, &pc_unusable);
pr_debug("uuc_iavg_ma = %d uuc with iavg = %d\n",
@@ -1177,6 +1186,76 @@
return soc;
}
+#define IBAT_TOL_MASK 0x0F
+#define OCV_TOL_MASK 0xF0
+#define IBAT_TOL_DEFAULT 0x03
+#define IBAT_TOL_NOCHG 0x0F
+#define OCV_TOL_DEFAULT 0x20
+#define OCV_TOL_NO_OCV 0x00
+static int stop_ocv_updates(struct qpnp_bms_chip *chip)
+{
+ pr_debug("stopping ocv updates\n");
+ return qpnp_masked_write(chip, BMS1_TOL_CTL,
+ OCV_TOL_MASK, OCV_TOL_NO_OCV);
+}
+
+static int reset_bms_for_test(struct qpnp_bms_chip *chip)
+{
+ int ibat_ua, vbat_uv, rc;
+ int ocv_est_uv;
+
+ if (!chip) {
+ pr_err("BMS driver has not been initialized yet!\n");
+ return -EINVAL;
+ }
+
+ rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
+
+ ocv_est_uv = vbat_uv + (ibat_ua * chip->r_conn_mohm) / 1000;
+ pr_debug("forcing ocv to be %d due to bms reset mode\n", ocv_est_uv);
+ chip->last_ocv_uv = ocv_est_uv;
+ chip->last_soc = -EINVAL;
+ reset_cc(chip);
+ chip->last_cc_uah = INT_MIN;
+ stop_ocv_updates(chip);
+
+ pr_debug("bms reset to ocv = %duv vbat_ua = %d ibat_ua = %d\n",
+ chip->last_ocv_uv, vbat_uv, ibat_ua);
+
+ return rc;
+}
+
+static int bms_reset_set(const char *val, const struct kernel_param *kp)
+{
+ int rc;
+
+ rc = param_set_bool(val, kp);
+ if (rc) {
+ pr_err("Unable to set bms_reset: %d\n", rc);
+ return rc;
+ }
+
+ if (*(bool *)kp->arg) {
+ struct power_supply *bms_psy = power_supply_get_by_name("bms");
+ struct qpnp_bms_chip *chip = container_of(bms_psy,
+ struct qpnp_bms_chip, bms_psy);
+
+ rc = reset_bms_for_test(chip);
+ if (rc) {
+ pr_err("Unable to modify bms_reset: %d\n", rc);
+ return rc;
+ }
+ }
+ return 0;
+}
+
+static struct kernel_param_ops bms_reset_ops = {
+ .set = bms_reset_set,
+ .get = param_get_bool,
+};
+
+module_param_cb(bms_reset, &bms_reset_ops, &bms_reset, 0644);
+
static int charging_adjustments(struct qpnp_bms_chip *chip,
struct soc_params *params, int soc,
int vbat_uv, int ibat_ua, int batt_temp)
@@ -1268,6 +1347,12 @@
(s64)params->fcc_uah - params->uuc_uah);
soc_est = bound_soc(soc_est);
+ /* never adjust during bms reset mode */
+ if (bms_reset) {
+ pr_debug("bms reset mode, SOC adjustment skipped\n");
+ goto out;
+ }
+
if (ibat_ua < 0 && !is_batfet_open(chip)) {
soc = charging_adjustments(chip, params, soc, vbat_uv, ibat_ua,
batt_temp);
@@ -1631,6 +1716,8 @@
chg_time_sec = DIV_ROUND_UP(chip->charge_time_us, USEC_PER_SEC);
catch_up_sec = DIV_ROUND_UP(chip->catch_up_time_us, USEC_PER_SEC);
+ if (catch_up_sec == 0)
+ return new_soc;
pr_debug("cts= %d catch_up_sec = %d\n", chg_time_sec, catch_up_sec);
/*
@@ -1730,8 +1817,7 @@
}
/* last_soc < soc ... scale and catch up */
- if (chip->last_soc != -EINVAL && chip->last_soc < soc
- && soc != 100 && chip->catch_up_time_us != 0)
+ if (chip->last_soc != -EINVAL && chip->last_soc < soc && soc != 100)
soc = scale_soc_while_chg(chip, delta_time_us,
soc, chip->last_soc);
diff --git a/drivers/usb/gadget/f_audio_source.c b/drivers/usb/gadget/f_audio_source.c
index aae941e..f0d5c52 100644
--- a/drivers/usb/gadget/f_audio_source.c
+++ b/drivers/usb/gadget/f_audio_source.c
@@ -256,6 +256,8 @@
ktime_t start_time;
/* number of frames sent since start_time */
s64 frames_sent;
+
+ bool audio_ep_enabled;
};
static inline struct audio_dev *func_to_audio_source(struct usb_function *f)
@@ -525,18 +527,26 @@
pr_debug("audio_set_alt intf %d, alt %d\n", intf, alt);
- ret = config_ep_by_speed(cdev->gadget, f, audio->in_ep);
- if (ret) {
- audio->in_ep->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- audio->in_ep->name, ret);
- return ret;
- }
- ret = usb_ep_enable(audio->in_ep);
- if (ret) {
- ERROR(cdev, "failed to enable ep %s, result %d\n",
- audio->in_ep->name, ret);
- return ret;
+ if (intf == as_interface_alt_1_desc.bInterfaceNumber) {
+ if (alt && !audio->audio_ep_enabled) {
+ ret = config_ep_by_speed(cdev->gadget, f, audio->in_ep);
+ if (ret) {
+ audio->in_ep->desc = NULL;
+ ERROR(cdev, "config_ep fail ep %s, result %d\n",
+ audio->in_ep->name, ret);
+ return ret;
+ }
+ ret = usb_ep_enable(audio->in_ep);
+ if (ret) {
+ ERROR(cdev, "failedto enable ep%s, result %d\n",
+ audio->in_ep->name, ret);
+ return ret;
+ }
+ audio->audio_ep_enabled = true;
+ } else if (!alt && audio->audio_ep_enabled) {
+ usb_ep_disable(audio->in_ep);
+ audio->audio_ep_enabled = false;
+ }
}
return 0;
}
@@ -546,7 +556,10 @@
struct audio_dev *audio = func_to_audio_source(f);
pr_debug("audio_disable\n");
- usb_ep_disable(audio->in_ep);
+ if (audio->audio_ep_enabled) {
+ usb_ep_disable(audio->in_ep);
+ audio->audio_ep_enabled = false;
+ }
}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 9333e57..a3b92ed 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -829,6 +829,74 @@
return ret;
}
+static ssize_t hdmi_common_rda_audio_data_block(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int adb_size = 0;
+ int adb_count = 0;
+ ssize_t ret = 0;
+ char *data = buf;
+
+ if (!external_common_state)
+ return 0;
+
+ adb_count = 1;
+ adb_size = external_common_state->adb_size;
+ ret = sizeof(adb_count) + sizeof(adb_size) + adb_size;
+
+ if (ret > PAGE_SIZE) {
+ DEV_DBG("%s: Insufficient buffer size\n", __func__);
+ return 0;
+ }
+
+ /* Currently only extracting one audio data block */
+ memcpy(data, &adb_count, sizeof(adb_count));
+ data += sizeof(adb_count);
+ memcpy(data, &adb_size, sizeof(adb_size));
+ data += sizeof(adb_size);
+ memcpy(data, external_common_state->audio_data_block,
+ external_common_state->adb_size);
+
+ print_hex_dump(KERN_DEBUG, "AUDIO DATA BLOCK: ", DUMP_PREFIX_NONE,
+ 32, 8, buf, ret, false);
+
+ return ret;
+}
+
+static ssize_t hdmi_common_rda_spkr_alloc_data_block(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int sadb_size = 0;
+ int sadb_count = 0;
+ ssize_t ret = 0;
+ char *data = buf;
+
+ if (!external_common_state)
+ return 0;
+
+ sadb_count = 1;
+ sadb_size = external_common_state->sadb_size;
+ ret = sizeof(sadb_count) + sizeof(sadb_size) + sadb_size;
+
+ if (ret > PAGE_SIZE) {
+ DEV_DBG("%s: Insufficient buffer size\n", __func__);
+ return 0;
+ }
+
+ /* Currently only extracting one speaker allocation data block */
+ memcpy(data, &sadb_count, sizeof(sadb_count));
+ data += sizeof(sadb_count);
+ memcpy(data, &sadb_size, sizeof(sadb_size));
+ data += sizeof(sadb_size);
+ memcpy(data, external_common_state->spkr_alloc_data_block,
+ external_common_state->sadb_size);
+
+ print_hex_dump(KERN_DEBUG, "SPKR ALLOC DATA BLOCK: ", DUMP_PREFIX_NONE,
+ 32, 8, buf, ret, false);
+
+ return ret;
+}
+
static DEVICE_ATTR(video_mode, S_IRUGO | S_IWUGO,
external_common_rda_video_mode, external_common_wta_video_mode);
static DEVICE_ATTR(video_mode_str, S_IRUGO, external_common_rda_video_mode_str,
@@ -859,6 +927,10 @@
hdmi_3d_wta_format_3d);
#endif
static DEVICE_ATTR(hdmi_primary, S_IRUGO, hdmi_common_rda_hdmi_primary, NULL);
+static DEVICE_ATTR(audio_data_block, S_IRUGO, hdmi_common_rda_audio_data_block,
+ NULL);
+static DEVICE_ATTR(spkr_alloc_data_block, S_IRUGO,
+ hdmi_common_rda_spkr_alloc_data_block, NULL);
static struct attribute *external_common_fs_attrs[] = {
&dev_attr_video_mode.attr,
@@ -887,6 +959,8 @@
&dev_attr_cec_wr_frame.attr,
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
&dev_attr_hdmi_primary.attr,
+ &dev_attr_audio_data_block.attr,
+ &dev_attr_spkr_alloc_data_block.attr,
NULL,
};
static struct attribute_group external_common_fs_attr_group = {
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 80db0b2..a283e0a 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -588,10 +588,10 @@
msleep(20);
ret = mfd->off_fnc(mfd);
- if (ret) {
+ if (ret)
mfd->panel_power_on = curr_pwr_state;
+ else
mdss_fb_release_fences(mfd);
- }
mfd->op_enable = true;
}
break;
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 2f4c2ed..6030cbc 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -698,6 +698,14 @@
ctl->power_on = false;
ctl->play_cnt = 0;
ctl->clk_rate = 0;
+ if (ctl->mixer_left) {
+ mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(
+ ctl->mixer_left->num), 0);
+ }
+ if (ctl->mixer_right) {
+ mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(
+ ctl->mixer_right->num), 0);
+ }
mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index a1f1bcc..2c0ddda 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -265,6 +265,9 @@
ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data;
if (ctx) {
+ mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
+ NULL, NULL);
+
ctl->priv_data = NULL;
ctx->ref_cnt--;
}
@@ -318,8 +321,6 @@
flush_bits = BIT(16); /* WB */
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, flush_bits);
- mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
- mdss_mdp_writeback_intr_done, ctx);
mdss_mdp_irq_enable(ctx->intr_type, ctx->intf_num);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
@@ -353,6 +354,9 @@
ctx->wb_num = ctl->num; /* wb num should match ctl num */
ctx->initialized = false;
+ mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
+ mdss_mdp_writeback_intr_done, ctx);
+
if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR)
ctl->prepare_fnc = mdss_mdp_writeback_prepare_rot;
else /* wfd or line mode */
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 75a926a..911e29f 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -78,7 +78,7 @@
void (*fnc_ptr)(void *), void *arg)
{
unsigned long flags;
- int index, ret;
+ int index;
index = mdss_mdp_intr2index(intr_type, intf_num);
if (index < 0) {
@@ -88,16 +88,13 @@
}
spin_lock_irqsave(&mdss_mdp_intr_lock, flags);
- if (!mdp_intr_cb[index].func) {
- mdp_intr_cb[index].func = fnc_ptr;
- mdp_intr_cb[index].arg = arg;
- ret = 0;
- } else {
- ret = -EBUSY;
- }
+ WARN(mdp_intr_cb[index].func && fnc_ptr,
+ "replacing current intr callback for ndx=%d\n", index);
+ mdp_intr_cb[index].func = fnc_ptr;
+ mdp_intr_cb[index].arg = arg;
spin_unlock_irqrestore(&mdss_mdp_intr_lock, flags);
- return ret;
+ return 0;
}
static inline void mdss_mdp_intr_done(int index)
diff --git a/include/linux/test-iosched.h b/include/linux/test-iosched.h
index ec28463..3690160 100644
--- a/include/linux/test-iosched.h
+++ b/include/linux/test-iosched.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index f29f02e..9558fa4 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, .qualcomm.com. All rights reserved.
+/* Copyright (c) 2010-2013, 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
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 6b957f6..a867991 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1353,6 +1353,9 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_MI2S_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
@@ -1455,6 +1458,9 @@
SOC_SINGLE_EXT("AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_AUXPCM_TX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("MI2S_TX_VoLTE", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
@@ -2209,6 +2215,12 @@
{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
{"HDMI", NULL, "HDMI_DL_HL"},
+ {"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
+ {"MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
+ {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
+
{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
{"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"},
{"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
@@ -2221,6 +2233,7 @@
{"VoLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_VoLTE", "INT_BT_SCO_TX"},
{"VoLTE_Tx Mixer", "AFE_PCM_TX_VoLTE", "PCM_TX"},
{"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"},
+ {"VoLTE_Tx Mixer", "MI2S_TX_VoLTE", "MI2S_TX"},
{"VoLTE_UL", NULL, "VoLTE_Tx Mixer"},
{"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
{"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"},
@@ -2276,12 +2289,6 @@
{"SLIMBUS_1_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
{"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
- {"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
- {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
- {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
- {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
- {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
-
{"SLIMBUS_3_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
{"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"},