Merge "msm: kgsl: Create a separate pool for mapping kgsl allocations" into msm-3.0
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index cc94b69..3ee63c0 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -15,19 +15,21 @@
KERNEL_USE_OF ?= $(shell $(PERL) -e '$$of = "n"; while (<>) { if (/CONFIG_USE_OF=y/) { $$of = "y"; break; } } print $$of;' kernel/arch/arm/configs/$(KERNEL_DEFCONFIG))
ifeq "$(KERNEL_USE_OF)" "y"
+DTS_NAME ?= $(MSM_ARCH)
+DTS_FILES = $(wildcard $(TOP)/kernel/arch/arm/boot/dts/$(DTS_NAME)*.dts)
+DTS_FILE = $(lastword $(subst /, ,$(1)))
+DTB_FILE = $(addprefix $(KERNEL_OUT)/arch/arm/boot/,$(patsubst %.dts,%.dtb,$(call DTS_FILE,$(1))))
+ZIMG_FILE = $(addprefix $(KERNEL_OUT)/arch/arm/boot/,$(patsubst %.dts,%-zImage,$(call DTS_FILE,$(1))))
KERNEL_ZIMG = $(KERNEL_OUT)/arch/arm/boot/zImage
-DTB_FILE = $(KERNEL_OUT)/arch/arm/boot/$(MSM_ARCH).dtb
-DTS_FILE = $(TOP)/kernel/arch/arm/boot/dts/$(MSM_ARCH).dts
-FULL_KERNEL = $(KERNEL_OUT)/arch/arm/boot/$(MSM_ARCH)-zImage
DTC = $(KERNEL_OUT)/scripts/dtc/dtc
define append-dtb
-md $(KERNEL_OUT)/arch/arm/boot;\
-$(DTC) -p 1024 -O dtb -o $(DTB_FILE) $(DTS_FILE);\
-cat $(KERNEL_ZIMG) $(DTB_FILE) > $(FULL_KERNEL)
+mkdir -p $(KERNEL_OUT)/arch/arm/boot;\
+$(foreach d, $(DTS_FILES), \
+ $(DTC) -p 1024 -O dtb -o $(call DTB_FILE,$(d)) $(d); \
+ cat $(KERNEL_ZIMG) $(call DTB_FILE,$(d)) > $(call ZIMG_FILE,$(d));)
endef
else
-FULL_KERNEL = $(KERNEL_IMG)
define append-dtb
endef
diff --git a/arch/arm/boot/dts/msmcopper-rumi.dts b/arch/arm/boot/dts/msmcopper-rumi.dts
new file mode 100644
index 0000000..bb53ff8
--- /dev/null
+++ b/arch/arm/boot/dts/msmcopper-rumi.dts
@@ -0,0 +1,60 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msmcopper.dtsi"
+
+/ {
+ model = "Qualcomm MSM Copper RUMI";
+ compatible = "qcom,msmcopper-rumi", "qcom,msmcopper";
+
+ timer {
+ clock-frequency = <5000000>;
+ };
+
+ serial@f991f000 {
+ status = "disable";
+ };
+
+ usb@f9a55000 {
+ status = "disable";
+ };
+
+ qcom,sdcc@f980b000 {
+ status = "disable";
+ };
+
+ qcom,sdcc@f984b000 {
+ status = "disable";
+ };
+
+ qcom,sps@f998000 {
+ status = "disable";
+ };
+
+ spi@f9924000 {
+ status = "disable";
+ };
+
+ slim@fe12f000 {
+ status = "disable";
+ };
+
+ qcom,spmi@fc4c0000 {
+ status = "disable";
+ };
+
+ i2c@f9966000 {
+ status = "disable";
+ };
+};
diff --git a/arch/arm/boot/dts/msmcopper-sim.dts b/arch/arm/boot/dts/msmcopper-sim.dts
new file mode 100644
index 0000000..ab6b8ba
--- /dev/null
+++ b/arch/arm/boot/dts/msmcopper-sim.dts
@@ -0,0 +1,20 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msmcopper.dtsi"
+
+/ {
+ model = "Qualcomm MSM Copper Simulator";
+ compatible = "qcom,msmcopper-sim", "qcom,msmcopper";
+};
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dtsi
similarity index 89%
rename from arch/arm/boot/dts/msmcopper.dts
rename to arch/arm/boot/dts/msmcopper.dtsi
index 8c8cc12..4aa05e0 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dtsi
@@ -1,10 +1,20 @@
-/dts-v1/;
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
/include/ "skeleton.dtsi"
/ {
model = "Qualcomm MSM Copper";
- compatible = "qcom,msmcopper-sim", "qcom,msmcopper";
+ compatible = "qcom,msmcopper";
interrupt-parent = <&intc>;
intc: interrupt-controller@F9000000 {
@@ -34,6 +44,12 @@
interrupts = <0 109 0>;
};
+ serial@f995e000 {
+ compatible = "qcom,msm-lsuart-v14";
+ reg = <0xf995e000 0x1000>;
+ interrupts = <0 114 0>;
+ };
+
usb@f9a55000 {
compatible = "qcom,hsusb-otg";
reg = <0xf9a55000 0x400>;
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 8594562..c6e314e 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -146,6 +146,8 @@
CONFIG_SPS=y
CONFIG_SPS_SUPPORT_BAMDMA=y
CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_SLIMBUS=y
+CONFIG_SLIMBUS_MSM_CTRL=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT3_FS=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 3384b48..2bc922a 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -53,6 +53,7 @@
CONFIG_MACH_APQ8064_CDP=y
CONFIG_MACH_APQ8064_MTP=y
CONFIG_MACH_APQ8064_LIQUID=y
+CONFIG_MACH_MPQ8064_CDP=y
CONFIG_MACH_MPQ8064_HRD=y
CONFIG_MACH_MPQ8064_DTV=y
# CONFIG_MSM_STACKED_MEMORY is not set
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index c186be4..706bc88 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -52,6 +52,7 @@
CONFIG_MACH_APQ8064_CDP=y
CONFIG_MACH_APQ8064_MTP=y
CONFIG_MACH_APQ8064_LIQUID=y
+CONFIG_MACH_MPQ8064_CDP=y
CONFIG_MACH_MPQ8064_HRD=y
CONFIG_MACH_MPQ8064_DTV=y
# CONFIG_MSM_STACKED_MEMORY is not set
@@ -94,6 +95,7 @@
CONFIG_MSM_L2_ERP_1BIT_PANIC=y
CONFIG_MSM_L2_ERP_2BIT_PANIC=y
CONFIG_MSM_CACHE_DUMP=y
+CONFIG_MSM_CACHE_DUMP_ON_PANIC=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index f5193da..f085d77 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -231,7 +231,8 @@
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_GADGET=y
-CONFIG_USB_CI13XXX_MSM=y
+CONFIG_USB_CI13XXX_MSM=m
+CONFIG_USB_CI13XXX_MSM_HSIC=m
CONFIG_USB_G_ANDROID=y
CONFIG_RMNET_SMD_CTL_CHANNEL="DATA36_CNTL"
CONFIG_RMNET_SMD_DATA_CHANNEL="DATA36"
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index ad4f12a..0202746 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -781,6 +781,12 @@
help
Support for the Qualcomm APQ8064 LIQUID device.
+config MACH_MPQ8064_CDP
+ depends on ARCH_APQ8064
+ bool "MPQ8064 CDP"
+ help
+ Support for the Qualcomm MPQ8064 CDP device.
+
config MACH_MPQ8064_HRD
depends on ARCH_APQ8064
bool "MPQ8064 HRD"
@@ -2230,4 +2236,13 @@
This allows for analysis of the caches in case cache corruption is
suspected.
+config MSM_CACHE_DUMP_ON_PANIC
+ bool "Dump caches on panic"
+ depends on MSM_CACHE_DUMP
+ help
+ By default, the caches are flushed on panic. This means that trying to
+ look at them in a RAM dump will give useless data. Select this if you
+ want to dump the L1 and L2 caches on panic before any flush occurs.
+ If unsure, say N
+
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 0f438e1..f331c4e 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -259,7 +259,7 @@
obj-$(CONFIG_PM8921_BMS) += bms-batterydata.o bms-batterydata-desay.o
obj-$(CONFIG_MACH_APQ8064_SIM) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_MACH_APQ8064_RUMI3) += board-8064-all.o board-8064-regulator.o
-obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o board-9615-gpiomux.o board-9615-storage.o
+obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o board-9615-gpiomux.o board-9615-storage.o board-9615-display.o
obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o
obj-$(CONFIG_ARCH_MSMCOPPER) += board-copper.o board-dt.o board-copper-regulator.o
diff --git a/arch/arm/mach-msm/acpuclock-7x30.c b/arch/arm/mach-msm/acpuclock-7x30.c
index 54d2aa9..29b0065 100644
--- a/arch/arm/mach-msm/acpuclock-7x30.c
+++ b/arch/arm/mach-msm/acpuclock-7x30.c
@@ -461,6 +461,14 @@
BUG_ON(IS_ERR(acpuclk_sources[PLL_2]));
acpuclk_sources[PLL_3] = clk_get_sys("acpu", "pll3_clk");
BUG_ON(IS_ERR(acpuclk_sources[PLL_3]));
+ /*
+ * Prepare all the PLLs because we enable/disable them
+ * from atomic context and can't always ensure they're
+ * all prepared in non-atomic context.
+ */
+ BUG_ON(clk_prepare(acpuclk_sources[PLL_1]));
+ BUG_ON(clk_prepare(acpuclk_sources[PLL_2]));
+ BUG_ON(clk_prepare(acpuclk_sources[PLL_3]));
}
static struct acpuclk_data acpuclk_7x30_data = {
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 4dac062..89d7fc9 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -2036,6 +2036,7 @@
goto register_bam_failed;
}
a2_device_handle = h;
+ toggle_apps_ack();
return 0;
diff --git a/arch/arm/mach-msm/bms-batterydata-desay.c b/arch/arm/mach-msm/bms-batterydata-desay.c
index 5488a2f..f362a72 100644
--- a/arch/arm/mach-msm/bms-batterydata-desay.c
+++ b/arch/arm/mach-msm/bms-batterydata-desay.c
@@ -65,10 +65,11 @@
},
};
-static struct pc_sf_lut desay_5200_pc_sf = {
+static struct sf_lut desay_5200_pc_sf = {
.rows = 1,
.cols = 1,
- .cycles = {0},
+ /* row_entries are cycles here */
+ .row_entries = {0},
.percent = {100},
.sf = {
{100}
@@ -81,4 +82,5 @@
.fcc_sf_lut = &desay_5200_fcc_sf,
.pc_temp_ocv_lut = &desay_5200_pc_temp_ocv,
.pc_sf_lut = &desay_5200_pc_sf,
+ .default_rbatt_mohm = 156,
};
diff --git a/arch/arm/mach-msm/bms-batterydata.c b/arch/arm/mach-msm/bms-batterydata.c
index e71e350..2960a8b 100644
--- a/arch/arm/mach-msm/bms-batterydata.c
+++ b/arch/arm/mach-msm/bms-batterydata.c
@@ -24,10 +24,11 @@
.cols = 5,
};
-static struct pc_sf_lut palladium_1500_pc_sf = {
+static struct sf_lut palladium_1500_pc_sf = {
.rows = 10,
.cols = 5,
- .cycles = {100, 200, 300, 400, 500},
+ /* row_entries are chargecycles */
+ .row_entries = {100, 200, 300, 400, 500},
.percent = {100, 90, 80, 70, 60, 50, 40, 30, 20, 10},
.sf = {
{97, 93, 93, 90, 87},
@@ -43,6 +44,36 @@
},
};
+static struct sf_lut palladium_1500_rbatt_sf = {
+ .rows = 19,
+ .cols = 5,
+ /* row_entries are temperature */
+ .row_entries = {-20, 0, 20, 40, 65},
+ .percent = {100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50,
+ 45, 40, 35, 30, 25, 20, 15, 10
+ },
+ .sf = {
+ {645, 301, 100, 80, 69},
+ {616, 290, 100, 79, 69},
+ {586, 279, 100, 78, 68},
+ {564, 270, 100, 78, 68},
+ {546, 262, 100, 78, 68},
+ {537, 256, 100, 79, 68},
+ {536, 253, 100, 79, 69},
+ {552, 258, 100, 81, 71},
+ {618, 284, 100, 80, 72},
+ {643, 290, 100, 77, 68},
+ {673, 294, 100, 77, 68},
+ {720, 296, 100, 77, 69},
+ {769, 294, 100, 76, 68},
+ {821, 288, 100, 74, 67},
+ {892, 284, 100, 74, 61},
+ {1003, 290, 100, 71, 58},
+ {1192, 307, 100, 70, 58},
+ {1579, 345, 100, 68, 57},
+ {1261, 324, 100, 68, 57},
+ }
+};
static struct pc_temp_ocv_lut palladium_1500_pc_temp_ocv = {
.rows = 29,
.cols = 8,
@@ -90,4 +121,6 @@
.fcc_sf_lut = &palladium_1500_fcc_sf,
.pc_temp_ocv_lut = &palladium_1500_pc_temp_ocv,
.pc_sf_lut = &palladium_1500_pc_sf,
+ .rbatt_sf_lut = &palladium_1500_rbatt_sf,
+ .default_rbatt_mohm = 254,
};
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index 2708283..0ff931a 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -16,10 +16,36 @@
#include <linux/msm_kgsl.h>
#include <mach/msm_bus_board.h>
#include <mach/board.h>
+#include <mach/msm_dcvs.h>
#include "devices.h"
#include "board-8064.h"
+#ifdef CONFIG_MSM_DCVS
+static struct msm_dcvs_freq_entry grp3d_freq[] = {
+ {0, 0, 333932},
+ {0, 0, 497532},
+ {0, 0, 707610},
+ {0, 0, 844545},
+};
+
+static struct msm_dcvs_core_info grp3d_core_info = {
+ .freq_tbl = &grp3d_freq[0],
+ .core_param = {
+ .max_time_us = 100000,
+ .num_freq = ARRAY_SIZE(grp3d_freq),
+ },
+ .algo_param = {
+ .slack_time_us = 39000,
+ .disable_pc_threshold = 86000,
+ .ss_window_size = 1000000,
+ .ss_util_pct = 95,
+ .em_max_util_pct = 97,
+ .ss_iobusy_conv = 100,
+ },
+};
+#endif /* CONFIG_MSM_DCVS */
+
#ifdef CONFIG_MSM_BUS_SCALING
static struct msm_bus_vectors grp3d_init_vectors[] = {
{
@@ -180,6 +206,9 @@
#endif
.iommu_data = kgsl_3d0_iommu_data,
.iommu_count = ARRAY_SIZE(kgsl_3d0_iommu_data),
+#ifdef CONFIG_MSM_DCVS
+ .core_info = &grp3d_core_info,
+#endif
};
struct platform_device device_kgsl_3d0 = {
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 93cfc099..73f02f5 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2370,6 +2370,17 @@
.init_very_early = apq8064_early_reserve,
MACHINE_END
+MACHINE_START(MPQ8064_CDP, "QCT MPQ8064 CDP")
+ .map_io = apq8064_map_io,
+ .reserve = apq8064_reserve,
+ .init_irq = apq8064_init_irq,
+ .handle_irq = gic_handle_irq,
+ .timer = &msm_timer,
+ .init_machine = apq8064_cdp_init,
+ .init_early = apq8064_allocate_memory_regions,
+ .init_very_early = apq8064_early_reserve,
+MACHINE_END
+
MACHINE_START(MPQ8064_HRD, "QCT MPQ8064 HRD")
.map_io = apq8064_map_io,
.reserve = apq8064_reserve,
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index c8c631e..42b20b2 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -496,6 +496,7 @@
.fpga_ctrl_mode = FPGA_SPI_INTF,
.phy_ctrl_settings = &dsi_novatek_cmd_mode_phy_db,
.dlane_swap = 0x1,
+ .enable_wled_bl_ctrl = 0x1,
};
static struct platform_device mipi_dsi_novatek_panel_device = {
diff --git a/arch/arm/mach-msm/board-8930-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
index cd201ef..854f318 100644
--- a/arch/arm/mach-msm/board-8930-gpiomux.c
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -171,26 +171,6 @@
},
};
#endif
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-static struct gpiomux_setting hsic_act_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_12MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting hsic_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
- .dir = GPIOMUX_OUT_LOW,
-};
-
-static struct gpiomux_setting hsic_hub_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-#endif
static struct gpiomux_setting hap_lvl_shft_suspended_config = {
.func = GPIOMUX_FUNC_GPIO,
@@ -487,32 +467,6 @@
},
};
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-static struct msm_gpiomux_config msm8960_hsic_configs[] = {
- {
- .gpio = 150, /*HSIC_STROBE */
- .settings = {
- [GPIOMUX_ACTIVE] = &hsic_act_cfg,
- [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
- },
- },
- {
- .gpio = 151, /* HSIC_DATA */
- .settings = {
- [GPIOMUX_ACTIVE] = &hsic_act_cfg,
- [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
- },
- },
- {
- .gpio = 91, /* HSIC_HUB_RESET */
- .settings = {
- [GPIOMUX_ACTIVE] = &hsic_hub_act_cfg,
- [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
- },
- },
-};
-#endif
-
static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
{
.gpio = 47,
@@ -689,14 +643,6 @@
msm_gpiomux_install(msm8930_haptics_configs,
ARRAY_SIZE(msm8930_haptics_configs));
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
- if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 1) &&
- !machine_is_msm8930_mtp() &&
- !machine_is_msm8930_fluid())
- msm_gpiomux_install(msm8960_hsic_configs,
- ARRAY_SIZE(msm8960_hsic_configs));
-#endif
-
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
msm_gpiomux_install(msm8960_hdmi_configs,
ARRAY_SIZE(msm8960_hdmi_configs));
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 6be2637..86c0438 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -236,6 +236,7 @@
static struct led_info pm8038_led_info[] = {
[0] = {
.name = "wled",
+ .default_trigger = "bkl_trigger",
},
[1] = {
.name = "led:rgb_red",
@@ -285,7 +286,7 @@
.id = PM8XXX_ID_WLED,
.mode = PM8XXX_LED_MODE_MANUAL,
.max_current = PM8038_WLED_MAX_CURRENT,
- .default_state = 1,
+ .default_state = 0,
.wled_cfg = &wled_cfg,
},
[1] = {
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 864d7b6..5493628 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1024,16 +1024,6 @@
};
#endif
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-#define HSIC_HUB_RESET_GPIO 91
-static struct msm_hsic_host_platform_data msm_hsic_pdata = {
- .strobe = 150,
- .data = 151,
-};
-#else
-static struct msm_hsic_host_platform_data msm_hsic_pdata;
-#endif
-
#define PID_MAGIC_ID 0x71432909
#define SERIAL_NUM_MAGIC_ID 0x61945374
#define SERIAL_NUMBER_LENGTH 127
@@ -1942,24 +1932,6 @@
int len;
};
-static void __init msm8930_init_hsic(void)
-{
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
- uint32_t version = socinfo_get_version();
-
- pr_info("%s: version:%d mtp:%d\n", __func__,
- SOCINFO_VERSION_MAJOR(version),
- machine_is_msm8930_mtp());
-
- if ((SOCINFO_VERSION_MAJOR(version) == 1) ||
- machine_is_msm8930_mtp() ||
- machine_is_msm8930_fluid())
- return;
-
- platform_device_register(&msm_device_hsic_host);
-#endif
-}
-
#ifdef CONFIG_ISL9519_CHARGER
static struct isl_platform_data isl_data __initdata = {
.valid_n_gpio = 0, /* Not required when notify-by-pmic */
@@ -2059,7 +2031,6 @@
platform_device_register(&msm8930_device_rpm_regulator);
msm_clock_init(&msm8930_clock_init_data);
msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
- msm_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
msm8930_init_gpiomux();
msm8960_device_qup_spi_gsbi1.dev.platform_data =
&msm8960_qup_spi_gsbi1_pdata;
@@ -2095,7 +2066,6 @@
msm8930_pm8038_gpio_mpp_init();
#endif
platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
- msm8930_init_hsic();
msm8930_init_cam();
msm8930_init_mmc();
acpuclk_init(&acpuclk_8930_soc_data);
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 724dd80..3f0d8df 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -612,6 +612,7 @@
#ifdef CONFIG_MSM_CACHE_DUMP
unsigned int spare;
unsigned int l1_size;
+ unsigned int l2_size;
unsigned int total;
int ret;
@@ -622,10 +623,18 @@
/* Fall back to something reasonable here */
l1_size = L1_BUFFER_SIZE;
- total = l1_size + L2_BUFFER_SIZE;
+ ret = scm_call(L1C_SERVICE_ID, L2C_BUFFER_GET_SIZE_COMMAND_ID, &spare,
+ sizeof(spare), &l2_size, sizeof(l2_size));
+
+ if (ret)
+ /* Fall back to something reasonable here */
+ l2_size = L2_BUFFER_SIZE;
+
+ total = l1_size + l2_size;
msm8960_reserve_table[MEMTYPE_EBI1].size += total;
msm_cache_dump_pdata.l1_size = l1_size;
+ msm_cache_dump_pdata.l2_size = l2_size;
#endif
}
diff --git a/arch/arm/mach-msm/board-9615-display.c b/arch/arm/mach-msm/board-9615-display.c
new file mode 100644
index 0000000..74bc984
--- /dev/null
+++ b/arch/arm/mach-msm/board-9615-display.c
@@ -0,0 +1,169 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <linux/ion.h>
+#include <asm/mach-types.h>
+#include <mach/msm_memtypes.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/ion.h>
+#include <mach/msm_bus_board.h>
+
+#include "devices.h"
+#include "board-9615.h"
+
+/* prim = 240 x 320 x 4(bpp) x 2(pages) */
+#define MSM_FB_PRIM_BUF_SIZE roundup(240 * 320 * 4 * 2, 0x10000)
+#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE, 4096)
+
+#define GPIO_PIN_EBI2_LCD_A_D 21
+#define GPIO_PIN_EBI2_LCD_CS 22
+#define GPIO_PIN_EBI2_LCD_RS 24
+
+
+#ifdef CONFIG_FB_MSM
+
+static struct resource msm_fb_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static int msm_fb_detect_panel(const char *name)
+{
+ return 0;
+}
+
+static struct msm_fb_platform_data msm_fb_pdata = {
+ .detect_client = msm_fb_detect_panel,
+};
+
+static struct platform_device msm_fb_device = {
+ .name = "msm_fb",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(msm_fb_resources),
+ .resource = msm_fb_resources,
+ .dev.platform_data = &msm_fb_pdata,
+};
+
+void __init mdm9615_allocate_fb_region(void)
+{
+ void *addr;
+ unsigned long size;
+
+ size = MSM_FB_SIZE;
+ addr = alloc_bootmem_align(size, 0x1000);
+ msm_fb_resources[0].start = __pa(addr);
+ msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
+ pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
+ size, addr, __pa(addr));
+}
+
+
+static bool ebi2_power_init;
+static int ebi2_panel_power(int on)
+{
+ static struct regulator *panel_power;
+ int rc;
+
+ pr_debug("%s: on=%d\n", __func__, on);
+
+ if (!ebi2_power_init) {
+ panel_power = regulator_get(&msm_ebi2_lcdc_device.dev,
+ "VDDI2");
+ if (IS_ERR_OR_NULL(panel_power)) {
+ pr_err("could not get L14, rc = %ld\n",
+ PTR_ERR(panel_power));
+ return -ENODEV;
+ }
+
+ rc = regulator_set_voltage(panel_power, 2800000, 3800000);
+ if (rc) {
+ pr_err("set_voltage L14 failed, rc=%d\n", rc);
+ return -EINVAL;
+ }
+
+ ebi2_power_init = true;
+ }
+
+ if (on) {
+ rc = regulator_enable(panel_power);
+ if (rc) {
+ pr_err("enable L14 failed, rc=%d\n", rc);
+ return -ENODEV;
+ }
+ rc = gpio_request(GPIO_PIN_EBI2_LCD_A_D, "disp_a_d");
+ if (rc) {
+ pr_err("request gpio EBI2_LCD_A_D failed, rc=%d\n", rc);
+ goto error1;
+ }
+ rc = gpio_request(GPIO_PIN_EBI2_LCD_CS, "disp_cs");
+ if (rc) {
+ pr_err("request gpio EBI2_LCD_CS failed, rc=%d\n", rc);
+ goto error2;
+ }
+ rc = gpio_request(GPIO_PIN_EBI2_LCD_RS, "disp_rs");
+ if (rc) {
+ pr_err("request gpio EBI2_LCD_RS failed, rc=%d\n", rc);
+ goto error3;
+ }
+ } else {
+ gpio_free(GPIO_PIN_EBI2_LCD_RS);
+ gpio_free(GPIO_PIN_EBI2_LCD_CS);
+ gpio_free(GPIO_PIN_EBI2_LCD_A_D);
+
+ rc = regulator_disable(panel_power);
+ if (rc) {
+ pr_err("disable L14 failed, rc=%d\n", rc);
+ return -ENODEV;
+ }
+ }
+
+ return 0;
+error3:
+ gpio_free(GPIO_PIN_EBI2_LCD_CS);
+error2:
+ gpio_free(GPIO_PIN_EBI2_LCD_A_D);
+error1:
+ regulator_disable(panel_power);
+ return rc;
+
+}
+
+static struct lcdc_platform_data ebi2_lcdc_pdata = {
+ .lcdc_power_save = ebi2_panel_power,
+};
+
+static struct lvds_panel_platform_data ebi2_epson_s1d_pdata;
+
+static struct platform_device ebi2_epson_s1d_panel_device = {
+ .name = "ebi2_epson_s1d_qvga",
+ .id = 0,
+ .dev = {
+ .platform_data = &ebi2_epson_s1d_pdata,
+ }
+};
+
+void __init mdm9615_init_fb(void)
+{
+ platform_device_register(&msm_fb_device);
+ platform_device_register(&ebi2_epson_s1d_panel_device);
+
+ msm_fb_register_device("ebi2_lcd", &ebi2_lcdc_pdata);
+}
+#endif
diff --git a/arch/arm/mach-msm/board-9615-gpiomux.c b/arch/arm/mach-msm/board-9615-gpiomux.c
index e61f001..0e18918 100644
--- a/arch/arm/mach-msm/board-9615-gpiomux.c
+++ b/arch/arm/mach-msm/board-9615-gpiomux.c
@@ -85,6 +85,26 @@
.pull = GPIOMUX_PULL_NONE,
};
+#ifdef CONFIG_FB_MSM_EBI2
+static struct gpiomux_setting ebi2_lcdc_a_d = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_12MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting ebi2_lcdc_cs = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_12MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting ebi2_lcdc_rs = {
+ .func = GPIOMUX_FUNC_3,
+ .drv = GPIOMUX_DRV_12MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+#endif
+
static struct msm_gpiomux_config msm9615_audio_codec_configs[] __initdata = {
{
.gpio = 24,
@@ -263,6 +283,29 @@
},
};
+#ifdef CONFIG_FB_MSM_EBI2
+static struct msm_gpiomux_config msm9615_ebi2_lcdc_configs[] __initdata = {
+ {
+ .gpio = 21, /* a_d */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ebi2_lcdc_a_d,
+ },
+ },
+ {
+ .gpio = 22, /* cs */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ebi2_lcdc_cs,
+ },
+ },
+ {
+ .gpio = 24, /* rs */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ebi2_lcdc_rs,
+ },
+ },
+};
+#endif
+
int __init msm9615_init_gpiomux(void)
{
int rc;
@@ -289,5 +332,10 @@
msm_gpiomux_install(msm9615_audio_codec_configs,
ARRAY_SIZE(msm9615_audio_codec_configs));
+#ifdef CONFIG_FB_MSM_EBI2
+ msm_gpiomux_install(msm9615_ebi2_lcdc_configs,
+ ARRAY_SIZE(msm9615_ebi2_lcdc_configs));
+#endif
+
return 0;
}
diff --git a/arch/arm/mach-msm/board-9615-regulator.c b/arch/arm/mach-msm/board-9615-regulator.c
index dd83d6f..8328501 100644
--- a/arch/arm/mach-msm/board-9615-regulator.c
+++ b/arch/arm/mach-msm/board-9615-regulator.c
@@ -65,6 +65,7 @@
};
VREG_CONSUMERS(L14) = {
REGULATOR_SUPPLY("8018_l14", NULL),
+ REGULATOR_SUPPLY("VDDI2", "ebi2_lcd.0"),
};
VREG_CONSUMERS(S1) = {
REGULATOR_SUPPLY("8018_s1", NULL),
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 77ee09f..e0bfc16 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -722,6 +722,9 @@
static void __init msm9615_cdp_init(void)
{
msm9615_common_init();
+#ifdef CONFIG_FB_MSM
+ mdm9615_init_fb();
+#endif
}
static void __init msm9615_mtp_init(void)
@@ -729,6 +732,13 @@
msm9615_common_init();
}
+#ifdef CONFIG_FB_MSM
+static void __init mdm9615_allocate_memory_regions(void)
+{
+ mdm9615_allocate_fb_region();
+}
+#endif
+
MACHINE_START(MSM9615_CDP, "QCT MSM9615 CDP")
.map_io = msm9615_map_io,
.init_irq = msm9615_init_irq,
@@ -736,6 +746,9 @@
.timer = &msm_timer,
.init_machine = msm9615_cdp_init,
.reserve = msm9615_reserve,
+#ifdef CONFIG_FB_MSM
+ .init_early = mdm9615_allocate_memory_regions,
+#endif
MACHINE_END
MACHINE_START(MSM9615_MTP, "QCT MSM9615 MTP")
diff --git a/arch/arm/mach-msm/board-9615.h b/arch/arm/mach-msm/board-9615.h
index 27f5d81..239453f 100644
--- a/arch/arm/mach-msm/board-9615.h
+++ b/arch/arm/mach-msm/board-9615.h
@@ -40,4 +40,6 @@
int msm9615_init_gpiomux(void);
void msm9615_init_mmc(void);
+void mdm9615_allocate_fb_region(void);
+void mdm9615_init_fb(void);
#endif
diff --git a/arch/arm/mach-msm/board-msm7627a-io.c b/arch/arm/mach-msm/board-msm7627a-io.c
index 757c166..8a2f53a 100644
--- a/arch/arm/mach-msm/board-msm7627a-io.c
+++ b/arch/arm/mach-msm/board-msm7627a-io.c
@@ -142,7 +142,7 @@
};
static struct gpio_event_platform_data kp_pdata_8625 = {
- .name = "8625_kp",
+ .name = "7x27a_kp",
.info = kp_info_8625,
.info_count = ARRAY_SIZE(kp_info_8625)
};
@@ -612,6 +612,47 @@
ARRAY_SIZE(ft5x06_device_info));
}
+/* SKU3/SKU7 keypad device information */
+#define KP_INDEX_SKU3(row, col) ((row)*ARRAY_SIZE(kp_col_gpios_sku3) + (col))
+static unsigned int kp_row_gpios_sku3[] = {31, 32};
+static unsigned int kp_col_gpios_sku3[] = {36, 37};
+
+static const unsigned short keymap_sku3[] = {
+ [KP_INDEX_SKU3(0, 0)] = KEY_VOLUMEUP,
+ [KP_INDEX_SKU3(0, 1)] = KEY_VOLUMEDOWN,
+ [KP_INDEX_SKU3(1, 1)] = KEY_CAMERA,
+};
+
+static struct gpio_event_matrix_info kp_matrix_info_sku3 = {
+ .info.func = gpio_event_matrix_func,
+ .keymap = keymap_sku3,
+ .output_gpios = kp_row_gpios_sku3,
+ .input_gpios = kp_col_gpios_sku3,
+ .noutputs = ARRAY_SIZE(kp_row_gpios_sku3),
+ .ninputs = ARRAY_SIZE(kp_col_gpios_sku3),
+ .settle_time.tv_nsec = 40 * NSEC_PER_USEC,
+ .poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
+ .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
+ GPIOKPF_PRINT_UNMAPPED_KEYS,
+};
+
+static struct gpio_event_info *kp_info_sku3[] = {
+ &kp_matrix_info_sku3.info,
+};
+static struct gpio_event_platform_data kp_pdata_sku3 = {
+ .name = "7x27a_kp",
+ .info = kp_info_sku3,
+ .info_count = ARRAY_SIZE(kp_info_sku3)
+};
+
+static struct platform_device kp_pdev_sku3 = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = -1,
+ .dev = {
+ .platform_data = &kp_pdata_sku3,
+ },
+};
+
void __init msm7627a_add_io_devices(void)
{
/* touchscreen */
@@ -689,6 +730,8 @@
/* keypad */
if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
platform_device_register(&kp_pdev_8625);
+ else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())
+ platform_device_register(&kp_pdev_sku3);
/* leds */
if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
index 53d3c56..b72ecd4 100644
--- a/arch/arm/mach-msm/board-msm7627a-wlan.c
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -49,7 +49,9 @@
static void gpio_wlan_config(void)
{
if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
- || machine_is_msm8625_evb())
+ || machine_is_msm8625_evb()
+ || machine_is_msm7627a_qrd3()
+ || machine_is_msm8625_qrd7())
gpio_wlan_sys_rest_en = 124;
}
@@ -231,7 +233,9 @@
* EVB1.0 and QRD8625,so the below step is required for those devices.
*/
if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
- || machine_is_msm8625_evb()) {
+ || machine_is_msm8625_evb()
+ || machine_is_msm7627a_qrd3()
+ || machine_is_msm8625_qrd7()) {
rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
@@ -305,7 +309,9 @@
* EVB1.0 and QRD8625,so the below step is required for those devices.
*/
if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
- || machine_is_msm8625_evb()) {
+ || machine_is_msm8625_evb()
+ || machine_is_msm7627a_qrd3()
+ || machine_is_msm8625_qrd7()) {
rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 44138a5e..b203c29 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -809,6 +809,8 @@
msm7627a_add_io_devices();
/*7x25a kgsl initializations*/
msm7x25a_kgsl_3d0_init();
+ /*8x25 kgsl initializations*/
+ msm8x25_kgsl_3d0_init();
}
static void __init msm7x2x_init_early(void)
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 44ba518..f3b2178 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -566,6 +566,7 @@
msm7627a_camera_init();
qrd7627a_add_io_devices();
msm7x25a_kgsl_3d0_init();
+ msm8x25_kgsl_3d0_init();
}
static void __init qrd7627a_init_early(void)
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index a2882a5..e3447b8 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -2965,8 +2965,7 @@
{USBH3_NS_REG, BIT(6), BIT(6)},
};
-/* Local clock driver initialization. */
-static void __init msm7x30_clock_init(void)
+static void __init msm7x30_clock_pre_init(void)
{
int i;
uint32_t val;
@@ -2979,15 +2978,17 @@
* function is a NOP since writes to shadow regions that we don't own
* are ignored. */
- clk_set_rate(&usb_hs_src_clk.c, clk_tbl_usb[1].freq_hz);
-
for (i = 0; i < ARRAY_SIZE(ri_list); i++) {
val = readl_relaxed(ri_list[i].reg);
val &= ~ri_list[i].mask;
val |= ri_list[i].val;
writel_relaxed(val, ri_list[i].reg);
}
+}
+static void __init msm7x30_clock_post_init(void)
+{
+ clk_set_rate(&usb_hs_src_clk.c, 60000000);
clk_set_rate(&i2c_clk.c, 19200000);
clk_set_rate(&i2c_2_clk.c, 19200000);
clk_set_rate(&qup_i2c_clk.c, 19200000);
@@ -3006,7 +3007,8 @@
struct clock_init_data msm7x30_clock_init_data __initdata = {
.table = msm_clocks_7x30,
.size = ARRAY_SIZE(msm_clocks_7x30),
- .init = msm7x30_clock_init,
+ .pre_init = msm7x30_clock_pre_init,
+ .post_init = msm7x30_clock_post_init,
};
/*
@@ -3035,5 +3037,4 @@
.set_flags = soc_clk_set_flags,
.is_local = local_clk_is_local,
.get_parent = branch_clk_get_parent,
- .set_parent = branch_clk_set_parent,
};
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 044bd79..3c06f98 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -581,7 +581,6 @@
.reset = branch_clk_reset,
.is_local = local_clk_is_local,
.get_parent = branch_clk_get_parent,
- .set_parent = branch_clk_set_parent,
.handoff = branch_clk_handoff,
.set_flags = branch_clk_set_flags,
};
@@ -2866,16 +2865,22 @@
return -ENXIO;
}
-static int pix_rdi_clk_handoff(struct clk *c)
+static enum handoff pix_rdi_clk_handoff(struct clk *c)
{
u32 reg;
struct pix_rdi_clk *clk = to_pix_rdi_clk(c);
+ enum handoff ret;
+
+ ret = branch_handoff(&clk->b, &clk->c);
+ if (ret == HANDOFF_DISABLED_CLK)
+ return ret;
reg = readl_relaxed(clk->s_reg);
clk->cur_rate = reg & clk->s_mask ? 1 : 0;
reg = readl_relaxed(clk->s2_reg);
clk->cur_rate = reg & clk->s2_mask ? 2 : clk->cur_rate;
- return 0;
+
+ return HANDOFF_ENABLED_CLK;
}
static struct clk_ops clk_ops_pix_rdi_8960 = {
@@ -5996,12 +6001,8 @@
}
}
-/* Local clock driver initialization. */
-static void __init msm8960_clock_init(void)
+static void __init msm8960_clock_pre_init(void)
{
- /* Keep PXO on whenever APPS cpu is active */
- clk_prepare_enable(&pxo_a_clk.c);
-
if (cpu_is_apq8064()) {
vdd_sr2_pll.set_vdd = set_vdd_sr2_pll_8064;
} else if (cpu_is_msm8930() || cpu_is_msm8627()) {
@@ -6050,6 +6051,12 @@
/* Initialize clock registers. */
reg_init();
+}
+
+static void __init msm8960_clock_post_init(void)
+{
+ /* Keep PXO on whenever APPS cpu is active */
+ clk_prepare_enable(&pxo_a_clk.c);
/* Initialize rates for clocks that only support one. */
clk_set_rate(&pdm_clk.c, 27000000);
@@ -6131,20 +6138,23 @@
struct clock_init_data msm8960_clock_init_data __initdata = {
.table = msm_clocks_8960,
.size = ARRAY_SIZE(msm_clocks_8960),
- .init = msm8960_clock_init,
+ .pre_init = msm8960_clock_pre_init,
+ .post_init = msm8960_clock_post_init,
.late_init = msm8960_clock_late_init,
};
struct clock_init_data apq8064_clock_init_data __initdata = {
.table = msm_clocks_8064,
.size = ARRAY_SIZE(msm_clocks_8064),
- .init = msm8960_clock_init,
+ .pre_init = msm8960_clock_pre_init,
+ .post_init = msm8960_clock_post_init,
.late_init = msm8960_clock_late_init,
};
struct clock_init_data msm8930_clock_init_data __initdata = {
.table = msm_clocks_8930,
.size = ARRAY_SIZE(msm_clocks_8930),
- .init = msm8960_clock_init,
+ .pre_init = msm8960_clock_pre_init,
+ .post_init = msm8960_clock_post_init,
.late_init = msm8960_clock_late_init,
};
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index c2632ee..771a4bf 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -452,7 +452,6 @@
.reset = branch_clk_reset,
.is_local = local_clk_is_local,
.get_parent = branch_clk_get_parent,
- .set_parent = branch_clk_set_parent,
.set_flags = branch_clk_set_flags,
};
@@ -3751,8 +3750,10 @@
writel_relaxed(regval, reg);
}
-static void __init reg_init(void)
+static void __init msm8660_clock_pre_init(void)
{
+ vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+
/* Setup MM_PLL2 (PLL3), but turn it off. Rate set by set_rate_tv(). */
rmwreg(0, MM_PLL2_MODE_REG, BIT(0)); /* Disable output */
/* Set ref, bypass, assert reset, disable output, disable test mode */
@@ -3836,14 +3837,10 @@
rmwreg(0x400001, MISC_CC2_REG, 0x424003);
}
-/* Local clock driver initialization. */
-static void __init msm8660_clock_init(void)
+static void __init msm8660_clock_post_init(void)
{
- vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
/* Keep PXO on whenever APPS cpu is active */
clk_prepare_enable(&pxo_a_clk.c);
- /* Initialize clock registers. */
- reg_init();
/* Initialize rates for clocks that only support one. */
clk_set_rate(&pdm_clk.c, 27000000);
@@ -3885,6 +3882,7 @@
struct clock_init_data msm8x60_clock_init_data __initdata = {
.table = msm_clocks_8x60,
.size = ARRAY_SIZE(msm_clocks_8x60),
- .init = msm8660_clock_init,
+ .pre_init = msm8660_clock_pre_init,
+ .post_init = msm8660_clock_post_init,
.late_init = msm8660_clock_late_init,
};
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index cc71c0b..48ee4a9 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -388,7 +388,6 @@
.reset = branch_clk_reset,
.is_local = local_clk_is_local,
.get_parent = branch_clk_get_parent,
- .set_parent = branch_clk_set_parent,
};
/*
@@ -1739,10 +1738,14 @@
/*
* Miscellaneous clock register initializations
*/
-static void __init reg_init(void)
+static void __init msm9615_clock_pre_init(void)
{
u32 regval, is_pll_enabled, pll9_lval;
+ vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+
+ clk_ops_pll.enable = sr_pll_clk_enable;
+
/* Enable PDM CXO source. */
regval = readl_relaxed(PDM_CLK_NS_REG);
writel_relaxed(BIT(13) | regval, PDM_CLK_NS_REG);
@@ -1831,18 +1834,11 @@
writel_relaxed(regval, DMA_BAM_HCLK_CTL);
}
-/* Local clock driver initialization. */
-static void __init msm9615_clock_init(void)
+static void __init msm9615_clock_post_init(void)
{
- vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
/* Keep CXO on whenever APPS cpu is active */
clk_prepare_enable(&cxo_a_clk.c);
- clk_ops_pll.enable = sr_pll_clk_enable;
-
- /* Initialize clock registers. */
- reg_init();
-
/* Initialize rates for clocks that only support one. */
clk_set_rate(&pdm_clk.c, 19200000);
clk_set_rate(&prng_clk.c, 32000000);
@@ -1868,6 +1864,7 @@
struct clock_init_data msm9615_clock_init_data __initdata = {
.table = msm_clocks_9615,
.size = ARRAY_SIZE(msm_clocks_9615),
- .init = msm9615_clock_init,
+ .pre_init = msm9615_clock_pre_init,
+ .post_init = msm9615_clock_post_init,
.late_init = msm9615_clock_late_init,
};
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 3546ce0..f990998 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -567,34 +567,36 @@
}
/* Disable hw clock gating if not set at boot */
-static void branch_handoff(struct branch *clk, struct clk *c)
+enum handoff branch_handoff(struct branch *clk, struct clk *c)
{
if (!branch_in_hwcg_mode(clk)) {
clk->hwcg_mask = 0;
c->flags &= ~CLKFLAG_HWCG;
+ if (readl_relaxed(clk->ctl_reg) & clk->en_mask)
+ return HANDOFF_ENABLED_CLK;
} else {
c->flags |= CLKFLAG_HWCG;
}
+ return HANDOFF_DISABLED_CLK;
}
-int branch_clk_handoff(struct clk *c)
+enum handoff branch_clk_handoff(struct clk *c)
{
struct branch_clk *clk = to_branch_clk(c);
- branch_handoff(&clk->b, &clk->c);
- return 0;
+ return branch_handoff(&clk->b, &clk->c);
}
-int rcg_clk_handoff(struct clk *c)
+enum handoff rcg_clk_handoff(struct clk *c)
{
struct rcg_clk *clk = to_rcg_clk(c);
uint32_t ctl_val, ns_val, md_val, ns_mask;
struct clk_freq_tbl *freq;
-
- branch_handoff(&clk->b, &clk->c);
+ enum handoff ret;
ctl_val = readl_relaxed(clk->b.ctl_reg);
- if (!(ctl_val & clk->root_en_mask))
- return 0;
+ ret = branch_handoff(&clk->b, &clk->c);
+ if (ret == HANDOFF_DISABLED_CLK)
+ return HANDOFF_DISABLED_CLK;
if (clk->bank_info) {
const struct bank_masks *bank_masks = clk->bank_info;
@@ -611,7 +613,8 @@
ns_mask = clk->ns_mask;
md_val = clk->md_reg ? readl_relaxed(clk->md_reg) : 0;
}
-
+ if (!ns_mask)
+ return HANDOFF_UNKNOWN_RATE;
ns_val = readl_relaxed(clk->ns_reg) & ns_mask;
for (freq = clk->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
if ((freq->ns_val & ns_mask) == ns_val &&
@@ -621,12 +624,12 @@
}
}
if (freq->freq_hz == FREQ_END)
- return 0;
+ return HANDOFF_UNKNOWN_RATE;
clk->current_freq = freq;
c->rate = freq->freq_hz;
- return 1;
+ return HANDOFF_ENABLED_CLK;
}
int pll_vote_clk_enable(struct clk *clk)
@@ -829,19 +832,6 @@
return branch->parent;
}
-int branch_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- /*
- * We setup the parent pointer at init time in msm_clock_init().
- * This check is to make sure drivers can't change the parent.
- */
- if (parent && list_empty(&clk->siblings)) {
- list_add(&clk->siblings, &parent->children);
- return 0;
- }
- return -EINVAL;
-}
-
int branch_clk_is_enabled(struct clk *clk)
{
struct branch_clk *branch = to_branch_clk(clk);
@@ -1058,12 +1048,15 @@
return n > clk->max_div ? -ENXIO : n;
}
-static int cdiv_clk_handoff(struct clk *c)
+static enum handoff cdiv_clk_handoff(struct clk *c)
{
struct cdiv_clk *clk = to_cdiv_clk(c);
+ enum handoff ret;
u32 reg_val;
- branch_handoff(&clk->b, &clk->c);
+ ret = branch_handoff(&clk->b, &clk->c);
+ if (ret == HANDOFF_DISABLED_CLK)
+ return ret;
reg_val = readl_relaxed(clk->ns_reg);
if (reg_val & clk->ext_mask) {
@@ -1073,7 +1066,7 @@
clk->cur_div = (reg_val & (clk->max_div - 1)) + 1;
}
- return 0;
+ return HANDOFF_ENABLED_CLK;
}
static void cdiv_clk_enable_hwcg(struct clk *c)
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 44e86b1..bc9298f 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -171,7 +171,8 @@
int branch_reset(struct branch *b, enum clk_reset_action action);
void __branch_clk_enable_reg(const struct branch *clk, const char *name);
u32 __branch_clk_disable_reg(const struct branch *clk, const char *name);
-int branch_clk_handoff(struct clk *c);
+enum handoff branch_clk_handoff(struct clk *c);
+enum handoff branch_handoff(struct branch *clk, struct clk *c);
int branch_clk_set_flags(struct clk *clk, unsigned flags);
/*
@@ -211,7 +212,7 @@
int rcg_clk_is_enabled(struct clk *clk);
long rcg_clk_round_rate(struct clk *clk, unsigned long rate);
struct clk *rcg_clk_get_parent(struct clk *c);
-int rcg_clk_handoff(struct clk *c);
+enum handoff rcg_clk_handoff(struct clk *c);
int rcg_clk_reset(struct clk *clk, enum clk_reset_action action);
void rcg_clk_enable_hwcg(struct clk *clk);
void rcg_clk_disable_hwcg(struct clk *clk);
@@ -330,7 +331,6 @@
int branch_clk_enable(struct clk *clk);
void branch_clk_disable(struct clk *clk);
struct clk *branch_clk_get_parent(struct clk *clk);
-int branch_clk_set_parent(struct clk *clk, struct clk *parent);
int branch_clk_is_enabled(struct clk *clk);
int branch_clk_reset(struct clk *c, enum clk_reset_action action);
void branch_clk_enable_hwcg(struct clk *clk);
diff --git a/arch/arm/mach-msm/clock-pcom-lookup.c b/arch/arm/mach-msm/clock-pcom-lookup.c
index a0defe3..ed3b8c2 100644
--- a/arch/arm/mach-msm/clock-pcom-lookup.c
+++ b/arch/arm/mach-msm/clock-pcom-lookup.c
@@ -307,7 +307,7 @@
struct clock_init_data msm7x27_clock_init_data __initdata = {
.table = msm_clocks_7x27,
.size = ARRAY_SIZE(msm_clocks_7x27),
- .init = msm_shared_pll_control_init,
+ .pre_init = msm_shared_pll_control_init,
};
/* Clock table for common clocks between 7627a and 7625a */
@@ -413,7 +413,7 @@
static struct clk_lookup msm_clk_7627a_7625a[ARRAY_SIZE(msm_cmn_clk_7625a_7627a)
+ ARRAY_SIZE(msm_clk_7627a)];
-static void __init msm7627a_clock_init(void)
+static void __init msm7627a_clock_pre_init(void)
{
int size = ARRAY_SIZE(msm_cmn_clk_7625a_7627a);
@@ -432,7 +432,7 @@
struct clock_init_data msm7x27a_clock_init_data __initdata = {
.table = msm_clk_7627a_7625a,
- .init = msm7627a_clock_init,
+ .pre_init = msm7627a_clock_pre_init,
};
static struct clk_lookup msm_clocks_8x50[] = {
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index b5b6ca7..68c390a 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -156,7 +156,7 @@
return true;
}
-static int pll_clk_handoff(struct clk *clk)
+static enum handoff pll_clk_handoff(struct clk *clk)
{
struct pll_shared_clk *pll = to_pll_shared_clk(clk);
unsigned int pll_lval;
@@ -184,7 +184,7 @@
BUG();
}
- return 0;
+ return HANDOFF_ENABLED_CLK;
}
struct clk_ops clk_pll_ops = {
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index ef502b3..9ad653d 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -148,18 +148,6 @@
return clk_round_rate(v->parent, rate);
}
-static int voter_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&voter_clk_lock, flags);
- if (list_empty(&clk->siblings))
- list_add(&clk->siblings, &parent->children);
- spin_unlock_irqrestore(&voter_clk_lock, flags);
-
- return 0;
-}
-
static struct clk *voter_clk_get_parent(struct clk *clk)
{
struct clk_voter *v = to_clk_voter(clk);
@@ -178,7 +166,6 @@
.get_rate = voter_clk_get_rate,
.is_enabled = voter_clk_is_enabled,
.round_rate = voter_clk_round_rate,
- .set_parent = voter_clk_set_parent,
.get_parent = voter_clk_get_parent,
.is_local = voter_clk_is_local,
};
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 884a27e..dcded38 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -401,8 +401,8 @@
size_t num_clocks;
clk_init_data = data;
- if (clk_init_data->init)
- clk_init_data->init();
+ if (clk_init_data->pre_init)
+ clk_init_data->pre_init();
clock_tbl = data->table;
num_clocks = data->size;
@@ -410,9 +410,10 @@
for (n = 0; n < num_clocks; n++) {
struct clk *clk = clock_tbl[n].clk;
struct clk *parent = clk_get_parent(clk);
- clk_set_parent(clk, parent);
+ if (parent && list_empty(&clk->siblings))
+ list_add(&clk->siblings, &parent->children);
if (clk->ops->handoff && !(clk->flags & CLKFLAG_HANDOFF_RATE)) {
- if (clk->ops->handoff(clk)) {
+ if (clk->ops->handoff(clk) == HANDOFF_ENABLED_CLK) {
clk->flags |= CLKFLAG_HANDOFF_RATE;
clk_prepare_enable(clk);
}
@@ -420,6 +421,9 @@
}
clkdev_add_table(clock_tbl, num_clocks);
+
+ if (clk_init_data->post_init)
+ clk_init_data->post_init();
}
/*
@@ -439,24 +443,24 @@
bool handoff = false;
clock_debug_add(clk);
+ spin_lock_irqsave(&clk->lock, flags);
if (!(clk->flags & CLKFLAG_SKIP_AUTO_OFF)) {
- spin_lock_irqsave(&clk->lock, flags);
if (!clk->count && clk->ops->auto_off) {
count++;
clk->ops->auto_off(clk);
}
- if (clk->flags & CLKFLAG_HANDOFF_RATE) {
- clk->flags &= ~CLKFLAG_HANDOFF_RATE;
- handoff = true;
- }
- spin_unlock_irqrestore(&clk->lock, flags);
- /*
- * Calling this outside the lock is safe since
- * it doesn't need to be atomic with the flag change.
- */
- if (handoff)
- clk_disable_unprepare(clk);
}
+ if (clk->flags & CLKFLAG_HANDOFF_RATE) {
+ clk->flags &= ~CLKFLAG_HANDOFF_RATE;
+ handoff = true;
+ }
+ spin_unlock_irqrestore(&clk->lock, flags);
+ /*
+ * Calling this outside the lock is safe since
+ * it doesn't need to be atomic with the flag change.
+ */
+ if (handoff)
+ clk_disable_unprepare(clk);
}
pr_info("clock_late_init() disabled %d unused clocks\n", count);
if (clk_init_data->late_init)
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 785e838..60be654 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -63,6 +63,12 @@
.lock = __SPIN_LOCK_UNLOCKED(lock) \
}
+enum handoff {
+ HANDOFF_ENABLED_CLK,
+ HANDOFF_DISABLED_CLK,
+ HANDOFF_UNKNOWN_RATE,
+};
+
struct clk_ops {
int (*prepare)(struct clk *clk);
int (*enable)(struct clk *clk);
@@ -72,7 +78,7 @@
void (*enable_hwcg)(struct clk *clk);
void (*disable_hwcg)(struct clk *clk);
int (*in_hwcg_mode)(struct clk *clk);
- int (*handoff)(struct clk *clk);
+ enum handoff (*handoff)(struct clk *clk);
int (*reset)(struct clk *clk, enum clk_reset_action action);
int (*set_rate)(struct clk *clk, unsigned long rate);
int (*set_max_rate)(struct clk *clk, unsigned long rate);
@@ -126,13 +132,15 @@
* struct clock_init_data - SoC specific clock initialization data
* @table: table of lookups to add
* @size: size of @table
- * @init: called before registering @table
+ * @pre_init: called before initializing the clock driver.
+ * @post_init: called after registering @table. clock APIs can be called inside.
* @late_init: called during late init
*/
struct clock_init_data {
struct clk_lookup *table;
size_t size;
- void (*init)(void);
+ void (*pre_init)(void);
+ void (*post_init)(void);
int (*late_init)(void);
};
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 0ab81a4..a653353 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -31,6 +31,7 @@
#include <mach/msm_bus_board.h>
#include <mach/msm_memtypes.h>
#include <mach/msm_smd.h>
+#include <mach/msm_dcvs.h>
#include <sound/msm-dai-q6.h>
#include <sound/apr_audio.h>
#include <mach/msm_tsif.h>
@@ -2403,6 +2404,49 @@
},
};
+static struct msm_dcvs_freq_entry grp3d_freq[] = {
+ {0, 0, 333932},
+ {0, 0, 497532},
+ {0, 0, 707610},
+ {0, 0, 844545},
+};
+
+static struct msm_dcvs_freq_entry grp2d_freq[] = {
+ {0, 0, 86000},
+ {0, 0, 200000},
+};
+
+static struct msm_dcvs_core_info grp3d_core_info = {
+ .freq_tbl = &grp3d_freq[0],
+ .core_param = {
+ .max_time_us = 100000,
+ .num_freq = ARRAY_SIZE(grp3d_freq),
+ },
+ .algo_param = {
+ .slack_time_us = 39000,
+ .disable_pc_threshold = 86000,
+ .ss_window_size = 1000000,
+ .ss_util_pct = 95,
+ .em_max_util_pct = 97,
+ .ss_iobusy_conv = 100,
+ },
+};
+
+static struct msm_dcvs_core_info grp2d_core_info = {
+ .freq_tbl = &grp2d_freq[0],
+ .core_param = {
+ .max_time_us = 100000,
+ .num_freq = ARRAY_SIZE(grp2d_freq),
+ },
+ .algo_param = {
+ .slack_time_us = 39000,
+ .disable_pc_threshold = 90000,
+ .ss_window_size = 1000000,
+ .ss_util_pct = 90,
+ .em_max_util_pct = 95,
+ },
+};
+
#ifdef CONFIG_MSM_BUS_SCALING
static struct msm_bus_vectors grp3d_init_vectors[] = {
{
@@ -2632,7 +2676,7 @@
},
},
.init_level = 0,
- .num_levels = 5,
+ .num_levels = ARRAY_SIZE(grp3d_freq) + 1,
.set_grp_async = NULL,
.idle_timeout = HZ/20,
.nap_allowed = true,
@@ -2642,6 +2686,7 @@
#endif
.iommu_data = kgsl_3d0_iommu_data,
.iommu_count = ARRAY_SIZE(kgsl_3d0_iommu_data),
+ .core_info = &grp3d_core_info,
};
struct platform_device msm_kgsl_3d0 = {
@@ -2698,7 +2743,7 @@
},
},
.init_level = 0,
- .num_levels = 3,
+ .num_levels = ARRAY_SIZE(grp2d_freq) + 1,
.set_grp_async = NULL,
.idle_timeout = HZ/5,
.nap_allowed = true,
@@ -2708,6 +2753,7 @@
#endif
.iommu_data = kgsl_2d0_iommu_data,
.iommu_count = ARRAY_SIZE(kgsl_2d0_iommu_data),
+ .core_info = &grp2d_core_info,
};
struct platform_device msm_kgsl_2d0 = {
@@ -2764,7 +2810,7 @@
},
},
.init_level = 0,
- .num_levels = 3,
+ .num_levels = ARRAY_SIZE(grp2d_freq) + 1,
.set_grp_async = NULL,
.idle_timeout = HZ/5,
.nap_allowed = true,
@@ -2774,6 +2820,7 @@
#endif
.iommu_data = kgsl_2d1_iommu_data,
.iommu_count = ARRAY_SIZE(kgsl_2d1_iommu_data),
+ .core_info = &grp2d_core_info,
};
struct platform_device msm_kgsl_2d1 = {
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 5e62507..f7306d2 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -850,6 +850,30 @@
return platform_device_register(pdev);
}
+#ifdef CONFIG_FB_MSM_EBI2
+static struct resource msm_ebi2_lcdc_resources[] = {
+ {
+ .name = "base",
+ .start = 0x1B300000,
+ .end = 0x1B300000 + PAGE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "lcd01",
+ .start = 0x1FC00000,
+ .end = 0x1FC00000 + 0x80000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device msm_ebi2_lcdc_device = {
+ .name = "ebi2_lcd",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(msm_ebi2_lcdc_resources),
+ .resource = msm_ebi2_lcdc_resources,
+};
+#endif
+
#ifdef CONFIG_CACHE_L2X0
static int __init l2x0_cache_init(void)
{
@@ -1273,3 +1297,26 @@
.name = "msm_bus_fabric",
.id = MSM_BUS_FAB_DEFAULT,
};
+
+#ifdef CONFIG_FB_MSM_EBI2
+static void __init msm_register_device(struct platform_device *pdev, void *data)
+{
+ int ret;
+
+ pdev->dev.platform_data = data;
+
+ ret = platform_device_register(pdev);
+ if (ret)
+ dev_err(&pdev->dev,
+ "%s: platform_device_register() failed = %d\n",
+ __func__, ret);
+}
+
+void __init msm_fb_register_device(char *name, void *data)
+{
+ if (!strncmp(name, "ebi2", 4))
+ msm_register_device(&msm_ebi2_lcdc_device, data);
+ else
+ pr_err("%s: unknown device! %s\n", __func__, name);
+}
+#endif
diff --git a/arch/arm/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c
index 3008fe9..77314e7 100644
--- a/arch/arm/mach-msm/devices-msm7x27.c
+++ b/arch/arm/mach-msm/devices-msm7x27.c
@@ -854,7 +854,7 @@
.init_level = 0,
.num_levels = 1,
.set_grp_async = NULL,
- .idle_timeout = HZ/5,
+ .idle_timeout = HZ,
.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM,
};
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 8236e1e..4575166 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -808,7 +808,7 @@
.init_level = 0,
.num_levels = 3,
.set_grp_async = set_grp_xbar_async,
- .idle_timeout = HZ/5,
+ .idle_timeout = HZ,
.nap_allowed = false,
.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM,
};
@@ -834,6 +834,12 @@
}
}
+void __init msm8x25_kgsl_3d0_init(void)
+{
+ if (cpu_is_msm8625())
+ kgsl_3d0_pdata.idle_timeout = HZ/5;
+}
+
static void __init msm_register_device(struct platform_device *pdev, void *data)
{
int ret;
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index 3c81ccf..407554c 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -31,4 +31,5 @@
void __init msm8625_map_io(void);
int ar600x_wlan_power(bool on);
void __init msm8x25_spm_device_init(void);
+void __init msm8x25_kgsl_3d0_init(void);
#endif
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 18b0a52..3c7b22a 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -267,6 +267,7 @@
extern struct platform_device msm_mipi_dsi1_device;
extern struct platform_device msm_lvds_device;
+extern struct platform_device msm_ebi2_lcdc_device;
extern struct clk_lookup msm_clocks_fsm9xxx[];
extern unsigned msm_num_clocks_fsm9xxx;
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 98fa233..5b3f297 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -431,6 +431,7 @@
struct mipi_dsi_phy_ctrl *phy_ctrl_settings;
char dlane_swap;
void (*dsi_pwm_cfg)(void);
+ char enable_wled_bl_ctrl;
};
struct lvds_panel_platform_data {
diff --git a/arch/arm/mach-msm/include/mach/msm_cache_dump.h b/arch/arm/mach-msm/include/mach/msm_cache_dump.h
index a8d2987..6e4f628 100644
--- a/arch/arm/mach-msm/include/mach/msm_cache_dump.h
+++ b/arch/arm/mach-msm/include/mach/msm_cache_dump.h
@@ -58,12 +58,15 @@
};
#define L1_BUFFER_SIZE SZ_1M
-#define L2_BUFFER_SIZE (sizeof(struct l2_cache_dump))
+#define L2_BUFFER_SIZE SZ_4M
#define CACHE_BUFFER_DUMP_SIZE (L1_BUFFER_SIZE + L2_BUFFER_SIZE)
#define L1C_SERVICE_ID 3
#define L1C_BUFFER_SET_COMMAND_ID 4
+#define CACHE_BUFFER_DUMP_COMMAND_ID 5
#define L1C_BUFFER_GET_SIZE_COMMAND_ID 6
+#define L2C_BUFFER_SET_COMMAND_ID 7
+#define L2C_BUFFER_GET_SIZE_COMMAND_ID 8
#endif
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c b/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c
index e63df1b..a936e6f 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c
@@ -550,7 +550,7 @@
i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n%d.%d\n",
(int)ts.tv_sec, (int)ts.tv_nsec);
- msm_bus_rpm_fill_cdata_buffer(&i, buf + i, MAX_BUFF_SIZE, cdata,
+ msm_bus_rpm_fill_cdata_buffer(&i, buf, MAX_BUFF_SIZE, cdata,
nmasters, nslaves, ntslaves);
i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n");
mutex_lock(&msm_bus_dbg_fablist_lock);
diff --git a/arch/arm/mach-msm/msm_cache_dump.c b/arch/arm/mach-msm/msm_cache_dump.c
index 40c358a..404c8f0 100644
--- a/arch/arm/mach-msm/msm_cache_dump.c
+++ b/arch/arm/mach-msm/msm_cache_dump.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/memory_alloc.h>
+#include <linux/notifier.h>
#include <mach/scm.h>
#include <mach/msm_cache_dump.h>
#include <mach/memory.h>
@@ -38,6 +39,25 @@
static struct l1_cache_dump __used *l1_dump;
static struct l2_cache_dump __used *l2_dump;
+static int msm_cache_dump_panic(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+#ifdef CONFIG_MSM_CACHE_DUMP_ON_PANIC
+ scm_call_atomic1(L1C_SERVICE_ID, CACHE_BUFFER_DUMP_COMMAND_ID, 2);
+ scm_call_atomic1(L1C_SERVICE_ID, CACHE_BUFFER_DUMP_COMMAND_ID, 1);
+#endif
+ return 0;
+}
+
+static struct notifier_block msm_cache_dump_blk = {
+ .notifier_call = msm_cache_dump_panic,
+ /*
+ * higher priority to ensure this runs before another panic handler
+ * flushes the caches.
+ */
+ .priority = 1,
+};
+
static int msm_cache_dump_probe(struct platform_device *pdev)
{
struct msm_cache_dump_platform_data *d = pdev->dev.platform_data;
@@ -46,7 +66,9 @@
unsigned long buf;
unsigned long size;
} l1_cache_data;
+#ifndef CONFIG_MSM_CACHE_DUMP_ON_PANIC
unsigned int *imem_loc;
+#endif
void *temp;
unsigned long total_size = d->l1_size + d->l2_size;
@@ -72,14 +94,36 @@
pr_err("%s: could not register L1 buffer ret = %d.\n",
__func__, ret);
+#if defined(CONFIG_MSM_CACHE_DUMP_ON_PANIC)
+ l1_cache_data.buf = msm_cache_dump_addr + d->l1_size;
+ l1_cache_data.size = d->l2_size;
+
+ ret = scm_call(L1C_SERVICE_ID, L2C_BUFFER_SET_COMMAND_ID,
+ &l1_cache_data, sizeof(l1_cache_data), NULL, 0);
+
+ if (ret)
+ pr_err("%s: could not register L2 buffer ret = %d.\n",
+ __func__, ret);
+#else
imem_loc = ioremap(L2C_IMEM_ADDR, SZ_4K);
__raw_writel(msm_cache_dump_addr + d->l1_size, imem_loc);
iounmap(imem_loc);
+#endif
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &msm_cache_dump_blk);
+ return 0;
+}
+
+static int msm_cache_dump_remove(struct platform_device *pdev)
+{
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &msm_cache_dump_blk);
return 0;
}
static struct platform_driver msm_cache_dump_driver = {
+ .remove = __devexit_p(msm_cache_dump_remove),
.driver = {
.name = "msm_cache_dump",
.owner = THIS_MODULE
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 86776d3..407231a 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -15,7 +15,7 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/module.h>
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <linux/debugfs.h>
#include <linux/list.h>
#include <linux/seq_file.h>
@@ -29,7 +29,7 @@
#include "rpm_resources.h"
-static DEFINE_SPINLOCK(msm_xo_lock);
+static DEFINE_MUTEX(msm_xo_lock);
struct msm_xo {
unsigned votes[NUM_MSM_XO_MODES];
@@ -151,13 +151,12 @@
static int msm_xo_show_voters(struct seq_file *m, void *v)
{
- unsigned long flags;
int i;
- spin_lock_irqsave(&msm_xo_lock, flags);
+ mutex_lock(&msm_xo_lock);
for (i = 0; i < ARRAY_SIZE(msm_xo_sources); i++)
msm_xo_dump_xo(m, &msm_xo_sources[i], msm_xo_to_str[i]);
- spin_unlock_irqrestore(&msm_xo_lock, flags);
+ mutex_unlock(&msm_xo_lock);
return 0;
}
@@ -221,7 +220,7 @@
*/
((msm_xo_sources[MSM_XO_CORE].mode ? 1 : 0) << 20) |
((msm_xo_sources[MSM_XO_CORE].mode ? 1 : 0) << 18);
- ret = msm_rpm_set_noirq(MSM_RPM_CTX_SET_0, &cmd, 1);
+ ret = msm_rpm_set(MSM_RPM_CTX_SET_0, &cmd, 1);
if (ret)
xo->mode = prev_vote;
@@ -281,7 +280,6 @@
int msm_xo_mode_vote(struct msm_xo_voter *xo_voter, enum msm_xo_modes mode)
{
int ret;
- unsigned long flags;
if (!xo_voter)
return 0;
@@ -289,9 +287,9 @@
if (mode >= NUM_MSM_XO_MODES || IS_ERR(xo_voter))
return -EINVAL;
- spin_lock_irqsave(&msm_xo_lock, flags);
+ mutex_lock(&msm_xo_lock);
ret = __msm_xo_mode_vote(xo_voter, mode);
- spin_unlock_irqrestore(&msm_xo_lock, flags);
+ mutex_unlock(&msm_xo_lock);
return ret;
}
@@ -310,7 +308,6 @@
struct msm_xo_voter *msm_xo_get(enum msm_xo_ids xo_id, const char *voter)
{
int ret;
- unsigned long flags;
struct msm_xo_voter *xo_voter;
if (xo_id >= NUM_MSM_XO_IDS) {
@@ -333,10 +330,10 @@
xo_voter->xo = &msm_xo_sources[xo_id];
/* Voters vote for OFF by default */
- spin_lock_irqsave(&msm_xo_lock, flags);
+ mutex_lock(&msm_xo_lock);
xo_voter->xo->votes[MSM_XO_MODE_OFF]++;
list_add(&xo_voter->list, &xo_voter->xo->voters);
- spin_unlock_irqrestore(&msm_xo_lock, flags);
+ mutex_unlock(&msm_xo_lock);
return xo_voter;
@@ -357,16 +354,14 @@
*/
void msm_xo_put(struct msm_xo_voter *xo_voter)
{
- unsigned long flags;
-
if (!xo_voter || IS_ERR(xo_voter))
return;
- spin_lock_irqsave(&msm_xo_lock, flags);
+ mutex_lock(&msm_xo_lock);
__msm_xo_mode_vote(xo_voter, MSM_XO_MODE_OFF);
xo_voter->xo->votes[MSM_XO_MODE_OFF]--;
list_del(&xo_voter->list);
- spin_unlock_irqrestore(&msm_xo_lock, flags);
+ mutex_unlock(&msm_xo_lock);
kfree(xo_voter->name);
kfree(xo_voter);
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 92339e9..ecbbcb9 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -80,7 +80,6 @@
void __iomem *base;
unsigned long start_addr;
struct clk *xo;
- bool use_cxo;
struct regulator *pll_supply;
struct pil_device *pil;
};
@@ -97,18 +96,15 @@
struct riva_data *drv = dev_get_drvdata(pil->dev);
int ret;
- drv->use_cxo = cxo_is_needed(drv);
ret = regulator_enable(drv->pll_supply);
if (ret) {
dev_err(pil->dev, "failed to enable pll supply\n");
goto err;
}
- if (drv->use_cxo) {
- ret = clk_prepare_enable(drv->xo);
- if (ret) {
- dev_err(pil->dev, "failed to enable xo\n");
- goto err_clk;
- }
+ ret = clk_prepare_enable(drv->xo);
+ if (ret) {
+ dev_err(pil->dev, "failed to enable xo\n");
+ goto err_clk;
}
return 0;
err_clk:
@@ -121,8 +117,7 @@
{
struct riva_data *drv = dev_get_drvdata(pil->dev);
regulator_disable(drv->pll_supply);
- if (drv->use_cxo)
- clk_disable_unprepare(drv->xo);
+ clk_disable_unprepare(drv->xo);
}
static int pil_riva_init_image(struct pil_desc *pil, const u8 *metadata,
@@ -140,11 +135,8 @@
struct riva_data *drv = dev_get_drvdata(pil->dev);
void __iomem *base = drv->base;
unsigned long start_addr = drv->start_addr;
- int ret;
+ bool use_cxo = cxo_is_needed(drv);
- ret = clk_prepare_enable(drv->xo);
- if (ret)
- return ret;
/* Enable A2XB bridge */
reg = readl_relaxed(base + RIVA_PMU_A2XB_CFG);
reg |= RIVA_PMU_A2XB_CFG_EN;
@@ -155,7 +147,7 @@
reg &= ~(PLL_MODE_BYPASSNL | PLL_MODE_OUTCTRL | PLL_MODE_RESET_N);
writel_relaxed(reg, RIVA_PLL_MODE);
- if (drv->use_cxo)
+ if (use_cxo)
writel_relaxed(0x40000C00 | 50, RIVA_PLL_L_VAL);
else
writel_relaxed(0x40000C00 | 40, RIVA_PLL_L_VAL);
@@ -165,7 +157,7 @@
reg = readl_relaxed(RIVA_PLL_MODE);
reg &= ~(PLL_MODE_REF_XO_SEL);
- reg |= drv->use_cxo ? PLL_MODE_REF_XO_SEL_CXO : PLL_MODE_REF_XO_SEL_RF;
+ reg |= use_cxo ? PLL_MODE_REF_XO_SEL_CXO : PLL_MODE_REF_XO_SEL_RF;
writel_relaxed(reg, RIVA_PLL_MODE);
/* Enable PLL 13 */
@@ -230,7 +222,6 @@
/* Take cCPU out of reset */
reg |= RIVA_PMU_OVRD_VAL_CCPU_RESET;
writel_relaxed(reg, base + RIVA_PMU_OVRD_VAL);
- clk_disable_unprepare(drv->xo);
return 0;
}
@@ -239,11 +230,7 @@
{
struct riva_data *drv = dev_get_drvdata(pil->dev);
u32 reg;
- int ret;
- ret = clk_prepare_enable(drv->xo);
- if (ret)
- return ret;
/* Put cCPU and cCPU clock into reset */
reg = readl_relaxed(drv->base + RIVA_PMU_OVRD_VAL);
reg &= ~(RIVA_PMU_OVRD_VAL_CCPU_RESET | RIVA_PMU_OVRD_VAL_CCPU_CLK);
@@ -262,8 +249,6 @@
writel_relaxed(0, RIVA_RESET);
mb();
- clk_disable_unprepare(drv->xo);
-
return 0;
}
@@ -283,30 +268,12 @@
static int pil_riva_reset_trusted(struct pil_desc *pil)
{
- struct riva_data *drv = dev_get_drvdata(pil->dev);
- int ret;
-
- ret = clk_prepare_enable(drv->xo);
- if (ret)
- return ret;
- /* Proxy-vote for resources RIVA needs */
- ret = pas_auth_and_reset(PAS_RIVA);
- clk_disable_unprepare(drv->xo);
- return ret;
+ return pas_auth_and_reset(PAS_RIVA);
}
static int pil_riva_shutdown_trusted(struct pil_desc *pil)
{
- int ret;
- struct riva_data *drv = dev_get_drvdata(pil->dev);
-
- ret = clk_prepare_enable(drv->xo);
- if (ret)
- return ret;
- ret = pas_shutdown(PAS_RIVA);
- clk_disable_unprepare(drv->xo);
-
- return ret;
+ return pas_shutdown(PAS_RIVA);
}
static struct pil_reset_ops pil_riva_ops_trusted = {
diff --git a/arch/arm/mach-msm/rpm.c b/arch/arm/mach-msm/rpm.c
index 2eac3c1..b0fa3d2 100644
--- a/arch/arm/mach-msm/rpm.c
+++ b/arch/arm/mach-msm/rpm.c
@@ -437,7 +437,6 @@
*
* Return value:
* 0: success
- * -EINTR: interrupted
* -EINVAL: invalid <ctx> or invalid id in <req> array
* -ENOSPC: request rejected
* -ENODEV: RPM driver not initialized
@@ -464,10 +463,7 @@
rc = msm_rpm_set_exclusive_noirq(ctx, sel_masks, req, count);
spin_unlock_irqrestore(&msm_rpm_lock, flags);
} else {
- rc = mutex_lock_interruptible(&msm_rpm_mutex);
- if (rc)
- goto set_common_exit;
-
+ mutex_lock(&msm_rpm_mutex);
rc = msm_rpm_set_exclusive(ctx, sel_masks, req, count);
mutex_unlock(&msm_rpm_mutex);
}
@@ -479,7 +475,6 @@
/*
* Return value:
* 0: success
- * -EINTR: interrupted
* -EINVAL: invalid <ctx> or invalid id in <req> array
* -ENODEV: RPM driver not initialized.
*/
@@ -518,10 +513,7 @@
spin_unlock_irqrestore(&msm_rpm_lock, flags);
BUG_ON(rc);
} else {
- rc = mutex_lock_interruptible(&msm_rpm_mutex);
- if (rc)
- goto clear_common_exit;
-
+ mutex_lock(&msm_rpm_mutex);
rc = msm_rpm_set_exclusive(ctx, sel_masks, r, ARRAY_SIZE(r));
mutex_unlock(&msm_rpm_mutex);
BUG_ON(rc);
@@ -683,7 +675,6 @@
*
* Return value:
* 0: success
- * -EINTR: interrupted
* -EINVAL: invalid <ctx> or invalid id in <req> array
* -ENOSPC: request rejected
* -ENODEV: RPM driver not initialized
@@ -724,7 +715,6 @@
*
* Return value:
* 0: success
- * -EINTR: interrupted
* -EINVAL: invalid <ctx> or invalid id in <req> array
*/
int msm_rpm_clear(int ctx, struct msm_rpm_iv_pair *req, int count)
@@ -769,7 +759,6 @@
*
* Return value:
* 0: success
- * -EINTR: interrupted
* -EINVAL: invalid id in <req> array
* -ENODEV: RPM driver not initialized
*/
@@ -787,9 +776,7 @@
if (rc)
goto register_notification_exit;
- rc = mutex_lock_interruptible(&msm_rpm_mutex);
- if (rc)
- goto register_notification_exit;
+ mutex_lock(&msm_rpm_mutex);
if (!msm_rpm_init_notif_done) {
msm_rpm_initialize_notification();
@@ -823,7 +810,6 @@
*
* Return value:
* 0: success
- * -EINTR: interrupted
* -ENODEV: RPM driver not initialized
*/
int msm_rpm_unregister_notification(struct msm_rpm_notification *n)
@@ -831,13 +817,10 @@
unsigned long flags;
unsigned int ctx;
struct msm_rpm_notif_config cfg;
- int rc;
+ int rc = 0;
int i;
- rc = mutex_lock_interruptible(&msm_rpm_mutex);
- if (rc)
- goto unregister_notification_exit;
-
+ mutex_lock(&msm_rpm_mutex);
ctx = MSM_RPM_CTX_SET_0;
cfg = msm_rpm_notif_cfgs[ctx];
@@ -854,7 +837,6 @@
msm_rpm_update_notification(ctx, &msm_rpm_notif_cfgs[ctx], &cfg);
mutex_unlock(&msm_rpm_mutex);
-unregister_notification_exit:
return rc;
}
EXPORT_SYMBOL(msm_rpm_unregister_notification);
diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c
index 546a917..6282eca 100644
--- a/arch/arm/mach-msm/rpm_resources.c
+++ b/arch/arm/mach-msm/rpm_resources.c
@@ -895,6 +895,9 @@
if (latency_us < level->latency_us)
continue;
+ if (sleep_us <= level->time_overhead_us)
+ continue;
+
if (!msm_rpmrs_irqs_detectable(&level->rs_limits,
irqs_detectable, gpio_detectable))
continue;
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 04dc392..bc4bd21 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -23,6 +23,8 @@
#include <linux/io.h>
#include <linux/kthread.h>
#include <linux/time.h>
+#include <linux/wakelock.h>
+#include <linux/suspend.h>
#include <asm/current.h>
@@ -43,9 +45,12 @@
struct subsys_data *subsys_ptrs[];
};
-struct restart_thread_data {
+struct restart_wq_data {
struct subsys_data *subsys;
+ struct wake_lock ssr_wake_lock;
+ char wakelockname[64];
int coupled;
+ struct work_struct work;
};
struct restart_log {
@@ -56,6 +61,7 @@
static int restart_level;
static int enable_ramdumps;
+struct workqueue_struct *ssr_wq;
static LIST_HEAD(restart_log_list);
static LIST_HEAD(subsystem_list);
@@ -297,9 +303,10 @@
mutex_unlock(&restart_log_mutex);
}
-static int subsystem_restart_thread(void *data)
+static void subsystem_restart_wq_func(struct work_struct *work)
{
- struct restart_thread_data *r_work = data;
+ struct restart_wq_data *r_work = container_of(work,
+ struct restart_wq_data, work);
struct subsys_data **restart_list;
struct subsys_data *subsys = r_work->subsys;
struct subsys_soc_restart_order *soc_restart_order = NULL;
@@ -334,10 +341,8 @@
/* Try to acquire shutdown_lock. If this fails, these subsystems are
* already being restarted - return.
*/
- if (!mutex_trylock(shutdown_lock)) {
- kfree(data);
- do_exit(0);
- }
+ if (!mutex_trylock(shutdown_lock))
+ goto out;
pr_debug("[%p]: Attempting to get powerup lock!\n", current);
@@ -430,15 +435,17 @@
pr_debug("[%p]: Released powerup lock!\n", current);
- kfree(data);
- do_exit(0);
+out:
+ wake_unlock(&r_work->ssr_wake_lock);
+ wake_lock_destroy(&r_work->ssr_wake_lock);
+ kfree(r_work);
}
int subsystem_restart(const char *subsys_name)
{
struct subsys_data *subsys;
- struct task_struct *tsk;
- struct restart_thread_data *data = NULL;
+ struct restart_wq_data *data = NULL;
+ int rc;
if (!subsys_name) {
pr_err("Invalid subsystem name.\n");
@@ -459,7 +466,7 @@
}
if (restart_level != RESET_SOC) {
- data = kzalloc(sizeof(struct restart_thread_data), GFP_KERNEL);
+ data = kzalloc(sizeof(struct restart_wq_data), GFP_KERNEL);
if (!data) {
restart_level = RESET_SOC;
pr_warn("Failed to alloc restart data. Resetting.\n");
@@ -482,18 +489,18 @@
pr_debug("Restarting %s [level=%d]!\n", subsys_name,
restart_level);
- /* Let the kthread handle the actual restarting. Using a
- * workqueue will not work since all restart requests are
- * serialized and it prevents the short circuiting of
- * restart requests for subsystems already in a restart
- * sequence.
- */
- tsk = kthread_run(subsystem_restart_thread, data,
- "subsystem_restart_thread");
- if (IS_ERR(tsk))
- panic("%s: Unable to create thread to restart %s",
- __func__, subsys->name);
+ snprintf(data->wakelockname, sizeof(data->wakelockname),
+ "ssr(%s)", subsys_name);
+ wake_lock_init(&data->ssr_wake_lock, WAKE_LOCK_SUSPEND,
+ data->wakelockname);
+ wake_lock(&data->ssr_wake_lock);
+ INIT_WORK(&data->work, subsystem_restart_wq_func);
+ rc = schedule_work(&data->work);
+
+ if (rc < 0)
+ panic("%s: Unable to schedule work to restart %s",
+ __func__, subsys->name);
break;
case RESET_SOC:
@@ -597,6 +604,11 @@
restart_level = RESET_SOC;
+ ssr_wq = alloc_workqueue("ssr_wq", 0, 0);
+
+ if (!ssr_wq)
+ panic("Couldn't allocate workqueue for subsystem restart.\n");
+
ret = ssr_init_soc_restart_orders();
return ret;
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index 1bdec12..90948ea 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -84,7 +84,6 @@
MODULE_NAME);
return IRQ_HANDLED;
}
- disable_irq_nosync(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ);
ss_restart_inprogress = true;
ret = schedule_work(&riva_fatal_work);
return IRQ_HANDLED;
@@ -115,6 +114,7 @@
{
pil_force_shutdown("wcnss");
flush_delayed_work(&cancel_vote_work);
+ disable_irq_nosync(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ);
return 0;
}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index cde8031..0ff30c3 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1136,6 +1136,7 @@
apq8064_cdp MACH_APQ8064_CDP APQ8064_CDP 3948
apq8064_mtp MACH_APQ8064_MTP APQ8064_MTP 3949
apq8064_liquid MACH_APQ8064_LIQUID APQ8064_LIQUID 3951
+mpq8064_cdp MACH_MPQ8064_CDP MPQ8064_CDP 3993
mpq8064_hrd MACH_MPQ8064_HRD MPQ8064_HRD 3994
mpq8064_dtv MACH_MPQ8064_DTV MPQ8064_DTV 3995
msm7627a_qrd3 MACH_MSM7627A_QRD3 MSM7627A_QRD3 4005
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index 5189388..c3367b5 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -16,6 +16,7 @@
msm_kgsl_core-$(CONFIG_MSM_KGSL_DRM) += kgsl_drm.o
msm_kgsl_core-$(CONFIG_MSM_SCM) += kgsl_pwrscale_trustzone.o
msm_kgsl_core-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += kgsl_pwrscale_idlestats.o
+msm_kgsl_core-$(CONFIG_MSM_DCVS) += kgsl_pwrscale_msm.o
msm_adreno-y += \
adreno_ringbuffer.o \
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index e08088d..b7c3032 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -30,8 +30,10 @@
#define KGSL_CMD_FLAGS_NOT_KERNEL_CMD 0x00000004
/* Command identifiers */
-#define KGSL_CONTEXT_TO_MEM_IDENTIFIER 0xDEADBEEF
-#define KGSL_CMD_IDENTIFIER 0xFEEDFACE
+#define KGSL_CONTEXT_TO_MEM_IDENTIFIER 0x2EADBEEF
+#define KGSL_CMD_IDENTIFIER 0x2EEDFACE
+#define KGSL_START_OF_IB_IDENTIFIER 0x2EADEABE
+#define KGSL_END_OF_IB_IDENTIFIER 0x2ABEDEAD
#ifdef CONFIG_MSM_SCM
#define ADRENO_DEFAULT_PWRSCALE_POLICY (&kgsl_pwrscale_policy_tz)
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index d6648e2..9542dfc 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -575,11 +575,12 @@
drawctxt);
return -EDEADLK;
}
- link = kzalloc(sizeof(unsigned int) * numibs * 3, GFP_KERNEL);
- cmds = link;
+
+ cmds = link = kzalloc(sizeof(unsigned int) * (numibs * 3 + 4),
+ GFP_KERNEL);
if (!link) {
- KGSL_MEM_ERR(device, "Failed to allocate memory for for command"
- " submission, size %x\n", numibs * 3);
+ KGSL_CORE_ERR("kzalloc(%d) failed\n",
+ sizeof(unsigned int) * (numibs * 3 + 4));
return -ENOMEM;
}
@@ -591,6 +592,16 @@
adreno_dev->drawctxt_active == drawctxt)
start_index = 1;
+ if (!start_index) {
+ *cmds++ = cp_nop_packet(1);
+ *cmds++ = KGSL_START_OF_IB_IDENTIFIER;
+ } else {
+ *cmds++ = cp_nop_packet(4);
+ *cmds++ = KGSL_START_OF_IB_IDENTIFIER;
+ *cmds++ = CP_HDR_INDIRECT_BUFFER_PFD;
+ *cmds++ = ibdesc[0].gpuaddr;
+ *cmds++ = ibdesc[0].sizedwords;
+ }
for (i = start_index; i < numibs; i++) {
(void)kgsl_cffdump_parse_ibs(dev_priv, NULL,
ibdesc[i].gpuaddr, ibdesc[i].sizedwords, false);
@@ -600,6 +611,9 @@
*cmds++ = ibdesc[i].sizedwords;
}
+ *cmds++ = cp_nop_packet(1);
+ *cmds++ = KGSL_END_OF_IB_IDENTIFIER;
+
kgsl_setstate(device,
kgsl_mmu_pt_get_flags(device->mmu.hwpagetable,
device->id));
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 8ccd462..6f575ec 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -601,9 +601,7 @@
mutex_lock(&device->mutex);
if (device->state & (KGSL_STATE_ACTIVE | KGSL_STATE_NAP)) {
- if ((device->requested_state != KGSL_STATE_SLEEP) &&
- (device->requested_state != KGSL_STATE_SLUMBER))
- kgsl_pwrscale_idle(device);
+ kgsl_pwrscale_idle(device);
if (kgsl_pwrctrl_sleep(device) != 0) {
mod_timer(&device->idle_timer,
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index f474c21..2222cdf 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,7 @@
#define KGSL_PWRLEVEL_TURBO 0
#define KGSL_PWRLEVEL_NOMINAL 1
+#define KGSL_PWRLEVEL_LAST_OFFSET 2
#define KGSL_MAX_CLKS 5
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index d0b2a41..1cecbc7 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -45,6 +45,9 @@
#ifdef CONFIG_MSM_SLEEP_STATS_DEVICE
&kgsl_pwrscale_policy_idlestats,
#endif
+#ifdef CONFIG_MSM_DCVS
+ &kgsl_pwrscale_policy_msm,
+#endif
NULL
};
diff --git a/drivers/gpu/msm/kgsl_pwrscale.h b/drivers/gpu/msm/kgsl_pwrscale.h
index b4f831e..6023476 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.h
+++ b/drivers/gpu/msm/kgsl_pwrscale.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -54,6 +54,7 @@
extern struct kgsl_pwrscale_policy kgsl_pwrscale_policy_tz;
extern struct kgsl_pwrscale_policy kgsl_pwrscale_policy_idlestats;
+extern struct kgsl_pwrscale_policy kgsl_pwrscale_policy_msm;
int kgsl_pwrscale_init(struct kgsl_device *device);
void kgsl_pwrscale_close(struct kgsl_device *device);
diff --git a/drivers/gpu/msm/kgsl_pwrscale_msm.c b/drivers/gpu/msm/kgsl_pwrscale_msm.c
new file mode 100644
index 0000000..f77a02b
--- /dev/null
+++ b/drivers/gpu/msm/kgsl_pwrscale_msm.c
@@ -0,0 +1,195 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <mach/msm_dcvs.h>
+#include "kgsl.h"
+#include "kgsl_pwrscale.h"
+#include "kgsl_device.h"
+
+struct msm_priv {
+ struct kgsl_device *device;
+ int enabled;
+ int handle;
+ unsigned int cur_freq;
+ struct msm_dcvs_idle idle_source;
+ struct msm_dcvs_freq freq_sink;
+ struct msm_dcvs_core_info *core_info;
+};
+
+static int msm_idle_enable(struct msm_dcvs_idle *self,
+ enum msm_core_control_event event)
+{
+ struct msm_priv *priv = container_of(self, struct msm_priv,
+ idle_source);
+
+ switch (event) {
+ case MSM_DCVS_ENABLE_IDLE_PULSE:
+ priv->enabled = true;
+ break;
+ case MSM_DCVS_DISABLE_IDLE_PULSE:
+ priv->enabled = false;
+ break;
+ case MSM_DCVS_ENABLE_HIGH_LATENCY_MODES:
+ case MSM_DCVS_DISABLE_HIGH_LATENCY_MODES:
+ break;
+ }
+ return 0;
+}
+
+/* Set the requested frequency if it is within 5MHz (delta) of a
+ * supported frequency.
+ */
+static int msm_set_freq(struct msm_dcvs_freq *self,
+ unsigned int freq)
+{
+ int i, delta = 5000000;
+ struct msm_priv *priv = container_of(self, struct msm_priv,
+ freq_sink);
+ struct kgsl_device *device = priv->device;
+ struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+
+ /* msm_dcvs manager uses frequencies in kHz */
+ freq *= 1000;
+ for (i = 0; i < pwr->num_pwrlevels; i++)
+ if (abs(pwr->pwrlevels[i].gpu_freq - freq) < delta)
+ break;
+ if (i == pwr->num_pwrlevels)
+ return 0;
+
+ mutex_lock(&device->mutex);
+ kgsl_pwrctrl_pwrlevel_change(device, i);
+ priv->cur_freq = pwr->pwrlevels[pwr->active_pwrlevel].gpu_freq;
+ mutex_unlock(&device->mutex);
+
+ /* return current frequency in kHz */
+ return priv->cur_freq / 1000;
+}
+
+static unsigned int msm_get_freq(struct msm_dcvs_freq *self)
+{
+ struct msm_priv *priv = container_of(self, struct msm_priv,
+ freq_sink);
+ /* return current frequency in kHz */
+ return priv->cur_freq / 1000;
+}
+
+static void msm_busy(struct kgsl_device *device,
+ struct kgsl_pwrscale *pwrscale)
+{
+ struct msm_priv *priv = pwrscale->priv;
+ if (priv->enabled)
+ msm_dcvs_idle(priv->handle, MSM_DCVS_IDLE_EXIT, 0);
+ return;
+}
+
+static void msm_idle(struct kgsl_device *device,
+ struct kgsl_pwrscale *pwrscale)
+{
+ struct msm_priv *priv = pwrscale->priv;
+ if (priv->enabled && pwrscale->gpu_busy)
+ msm_dcvs_idle(priv->handle, MSM_DCVS_IDLE_ENTER, 0);
+
+ return;
+}
+
+static void msm_sleep(struct kgsl_device *device,
+ struct kgsl_pwrscale *pwrscale)
+{
+ /* do we need to reset any parameters here? */
+}
+
+static int msm_init(struct kgsl_device *device,
+ struct kgsl_pwrscale *pwrscale)
+{
+ struct msm_priv *priv;
+ struct msm_dcvs_freq_entry *tbl;
+ int i, ret, low_level;
+ struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+ struct platform_device *pdev =
+ container_of(device->parentdev, struct platform_device, dev);
+ struct kgsl_device_platform_data *pdata = pdev->dev.platform_data;
+
+ priv = pwrscale->priv = kzalloc(sizeof(struct msm_priv),
+ GFP_KERNEL);
+ if (pwrscale->priv == NULL)
+ return -ENOMEM;
+
+ priv->core_info = pdata->core_info;
+ tbl = priv->core_info->freq_tbl;
+ /* Fill in frequency table from low to high, reversing order. */
+ low_level = pwr->num_pwrlevels - KGSL_PWRLEVEL_LAST_OFFSET;
+ for (i = 0; i <= low_level; i++)
+ tbl[i].freq =
+ pwr->pwrlevels[low_level - i].gpu_freq / 1000;
+ ret = msm_dcvs_register_core(device->name, 0, priv->core_info);
+ if (ret) {
+ KGSL_PWR_ERR(device, "msm_dcvs_register_core failed");
+ goto err;
+ }
+
+ priv->device = device;
+ priv->idle_source.enable = msm_idle_enable;
+ priv->idle_source.core_name = device->name;
+ priv->handle = msm_dcvs_idle_source_register(&priv->idle_source);
+ if (priv->handle < 0) {
+ ret = priv->handle;
+ KGSL_PWR_ERR(device, "msm_dcvs_idle_source_register failed\n");
+ goto err;
+ }
+
+ priv->freq_sink.core_name = device->name;
+ priv->freq_sink.set_frequency = msm_set_freq;
+ priv->freq_sink.get_frequency = msm_get_freq;
+ ret = msm_dcvs_freq_sink_register(&priv->freq_sink);
+ if (ret >= 0) {
+ if (device->ftbl->isidle(device)) {
+ device->pwrscale.gpu_busy = 0;
+ msm_dcvs_idle(priv->handle, MSM_DCVS_IDLE_ENTER, 0);
+ } else {
+ device->pwrscale.gpu_busy = 1;
+ }
+ return 0;
+ }
+
+ KGSL_PWR_ERR(device, "msm_dcvs_freq_sink_register failed\n");
+ msm_dcvs_idle_source_unregister(&priv->idle_source);
+
+err:
+ kfree(pwrscale->priv);
+ pwrscale->priv = NULL;
+
+ return ret;
+}
+
+static void msm_close(struct kgsl_device *device,
+ struct kgsl_pwrscale *pwrscale)
+{
+ struct msm_priv *priv = pwrscale->priv;
+
+ if (pwrscale->priv == NULL)
+ return;
+ msm_dcvs_idle_source_unregister(&priv->idle_source);
+ msm_dcvs_freq_sink_unregister(&priv->freq_sink);
+ kfree(pwrscale->priv);
+ pwrscale->priv = NULL;
+}
+
+struct kgsl_pwrscale_policy kgsl_pwrscale_policy_msm = {
+ .name = "msm",
+ .init = msm_init,
+ .idle = msm_idle,
+ .busy = msm_busy,
+ .sleep = msm_sleep,
+ .close = msm_close,
+};
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index 6770ec8..fa42c2c 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.c
@@ -71,7 +71,7 @@
#define WLED_OP_FDBCK_MASK 0x1C
#define WLED_OP_FDBCK_BIT_SHFT 0x02
-#define WLED_MAX_LEVEL 100
+#define WLED_MAX_LEVEL 255
#define WLED_8_BIT_MASK 0xFF
#define WLED_8_BIT_SHFT 0x08
#define WLED_MAX_DUTY_CYCLE 0xFFF
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 175a441..8d59590 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -1366,6 +1366,14 @@
return rc;
}
+ /* The number of camera instance should be controlled by the
+ resource manager. Currently supporting one active instance
+ until multiple instances are supported */
+ if (atomic_read(&ps->number_pcam_active) > 0) {
+ pr_err("%s Cannot have more than one active camera %d\n",
+ __func__, atomic_read(&ps->number_pcam_active));
+ return -EINVAL;
+ }
/* book keeping this camera session*/
ps->pcam_active = pcam;
atomic_inc(&ps->number_pcam_active);
@@ -1411,6 +1419,9 @@
{
int i;
int rc = -EINVAL;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ int ion_client_created = 0;
+#endif
/*struct msm_isp_ops *p_isp = 0;*/
/* get the video device */
struct msm_cam_v4l2_device *pcam = video_drvdata(f);
@@ -1442,7 +1453,9 @@
pcam_inst->pcam = pcam;
pcam->dev_inst[i] = pcam_inst;
- D("%s for %s\n", __func__, pcam->pdev->name);
+ D("%s index %d nodeid %d count %d\n", __func__,
+ pcam_inst->my_index,
+ pcam->vnode_id, pcam->use_count);
pcam->use_count++;
if (pcam->use_count == 1) {
@@ -1450,19 +1463,19 @@
if (rc < 0) {
pr_err("%s: cam_server_open_session failed %d\n",
__func__, rc);
- mutex_unlock(&pcam->vid_lock);
- return rc;
+ goto err;
}
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
pcam->mctl.client = msm_ion_client_create(-1, "camera");
kref_init(&pcam->mctl.refcount);
+ ion_client_created = 1;
#endif
/* Should be set to sensor ops if any but right now its OK!! */
if (!pcam->mctl.mctl_open) {
D("%s: media contoller is not inited\n",
__func__);
- mutex_unlock(&pcam->vid_lock);
- return -ENODEV;
+ rc = -ENODEV;
+ goto err;
}
/* Now we really have to activate the camera */
@@ -1470,9 +1483,8 @@
rc = pcam->mctl.mctl_open(&(pcam->mctl), MSM_APPS_ID_V4L2);
if (rc < 0) {
- mutex_unlock(&pcam->vid_lock);
pr_err("%s: HW open failed rc = 0x%x\n", __func__, rc);
- return rc;
+ goto err;
}
pcam->mctl.sync.pcam_sync = pcam;
@@ -1480,24 +1492,21 @@
rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
pcam->mctl.isp_sdev->sd);
if (rc < 0) {
- mutex_unlock(&pcam->vid_lock);
pr_err("%s: v4l2_device_register_subdev failed rc = %d\n",
__func__, rc);
- return rc;
+ goto err;
}
if (pcam->mctl.isp_sdev->sd_vpe) {
rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
pcam->mctl.isp_sdev->sd_vpe);
if (rc < 0) {
- mutex_unlock(&pcam->vid_lock);
- return rc;
+ goto err;
}
}
rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
pcam->pvdev);
if (rc < 0) {
- mutex_unlock(&pcam->vid_lock);
- return rc;
+ goto err;
}
}
pcam_inst->vbqueue_initialized = 0;
@@ -1522,6 +1531,21 @@
D("%s: end", __func__);
/* rc = msm_cam_server_open_session(g_server_dev, pcam);*/
return rc;
+
+err:
+ if (pcam->use_count == 1) {
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ if (ion_client_created) {
+ pr_err("%s: destroy ion client", __func__);
+ kref_put(&pcam->mctl.refcount, msm_release_ion_client);
+ }
+#endif
+ pcam->dev_inst[i] = NULL;
+ pcam->use_count = 0;
+ }
+ mutex_unlock(&pcam->vid_lock);
+ kfree(pcam_inst);
+ return rc;
}
static int msm_addr_remap(struct msm_cam_v4l2_dev_inst *pcam_inst,
@@ -1622,6 +1646,8 @@
if (pcam_inst->vbqueue_initialized)
vb2_queue_release(&pcam_inst->vid_bufq);
D("%s Closing down instance %p ", __func__, pcam_inst);
+ D("%s index %d nodeid %d count %d\n", __func__, pcam_inst->my_index,
+ pcam->vnode_id, pcam->use_count);
pcam->dev_inst[pcam_inst->my_index] = NULL;
if (pcam_inst->my_index == 0) {
v4l2_fh_del(&pcam_inst->eventHandle);
@@ -2638,7 +2664,7 @@
D("%s done, rc = %d\n", __func__, rc);
D("%s number of sensors connected is %d\n", __func__,
- g_server_dev.camera_info.num_cameras);
+ g_server_dev.camera_info.num_cameras);
/* register the subdevice, must be done for callbacks */
rc = v4l2_device_register_subdev(&pcam->v4l2_dev, sensor_sd);
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index b655848..64c0bd1 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -999,6 +999,10 @@
{
int rc;
+ /* dVdd preloading is not needed for PMIC PM8901 rev 2.3 and beyond. */
+ if (pm8xxx_get_revision(chip->dev->parent) >= PM8XXX_REVISION_8901_2p3)
+ return 0;
+
rc = pm8xxx_writeb(chip->dev->parent, 0x0BD, 0x0F);
if (rc)
pr_err("pm8xxx_writeb failed for 0x0BD, rc=%d\n", rc);
diff --git a/drivers/mfd/pmic8901.c b/drivers/mfd/pmic8901.c
index aec382a..63ea55a 100644
--- a/drivers/mfd/pmic8901.c
+++ b/drivers/mfd/pmic8901.c
@@ -270,11 +270,23 @@
return rc;
}
+static const char * const pm8901_rev_names[] = {
+ [PM8XXX_REVISION_8901_TEST] = "test",
+ [PM8XXX_REVISION_8901_1p0] = "1.0",
+ [PM8XXX_REVISION_8901_1p1] = "1.1",
+ [PM8XXX_REVISION_8901_2p0] = "2.0",
+ [PM8XXX_REVISION_8901_2p1] = "2.1",
+ [PM8XXX_REVISION_8901_2p2] = "2.2",
+ [PM8XXX_REVISION_8901_2p3] = "2.3",
+};
+
static int __devinit pm8901_probe(struct platform_device *pdev)
{
int rc;
struct pm8901_platform_data *pdata = pdev->dev.platform_data;
+ const char *revision_name = "unknown";
struct pm8901_chip *pmic;
+ int revision;
if (pdata == NULL) {
pr_err("%s: No platform_data or IRQ.\n", __func__);
@@ -298,7 +310,11 @@
pr_err("%s: Failed reading version register rc=%d.\n",
__func__, rc);
- pr_info("%s: PMIC REVISION = %X\n", __func__, pmic->revision);
+ pr_info("%s: PMIC revision reg: %02X\n", __func__, pmic->revision);
+ revision = pm8xxx_get_revision(pmic->dev);
+ if (revision >= 0 && revision < ARRAY_SIZE(pm8901_rev_names))
+ revision_name = pm8901_rev_names[revision];
+ pr_info("%s: PMIC version: PM8901 rev %s\n", __func__, revision_name);
(void) memcpy((void *)&pmic->pdata, (const void *)pdata,
sizeof(pmic->pdata));
diff --git a/drivers/misc/pmic8058-xoadc.c b/drivers/misc/pmic8058-xoadc.c
index 14b790f..3452672 100644
--- a/drivers/misc/pmic8058-xoadc.c
+++ b/drivers/misc/pmic8058-xoadc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -650,23 +650,6 @@
#define PM8058_XOADC_DEV_PM_OPS NULL
#endif
-static int __devexit pm8058_xoadc_teardown(struct platform_device *pdev)
-{
- struct pmic8058_adc *adc_pmic = platform_get_drvdata(pdev);
-
- if (adc_pmic->pdata->xoadc_vreg_shutdown != NULL)
- adc_pmic->pdata->xoadc_vreg_shutdown();
-
- wake_lock_destroy(&adc_pmic->adc_wakelock);
- msm_xo_put(adc_pmic->adc_voter);
- platform_set_drvdata(pdev, NULL);
- device_init_wakeup(&pdev->dev, 0);
- kfree(adc_pmic);
- xoadc_initialized = false;
-
- return 0;
-}
-
static int __devinit pm8058_xoadc_probe(struct platform_device *pdev)
{
struct xoadc_platform_data *pdata = pdev->dev.platform_data;
@@ -678,7 +661,7 @@
return -EINVAL;
}
- adc_pmic = kzalloc(sizeof(struct pmic8058_adc), GFP_KERNEL);
+ adc_pmic = devm_kzalloc(&pdev->dev, sizeof(*adc_pmic), GFP_KERNEL);
if (!adc_pmic) {
dev_err(&pdev->dev, "Unable to allocate memory\n");
return -ENOMEM;
@@ -693,17 +676,16 @@
if (adc_pmic->xoadc_num > XOADC_PMIC_0) {
dev_err(&pdev->dev, "ADC device not supported\n");
- rc = -EINVAL;
- goto err_cleanup;
+ return -EINVAL;
}
adc_pmic->pdata = pdata;
- adc_pmic->adc_graph = kzalloc(sizeof(struct linear_graph)
- * MAX_CHANNEL_PROPERTIES_QUEUE, GFP_KERNEL);
+ adc_pmic->adc_graph = devm_kzalloc(&pdev->dev,
+ sizeof(struct linear_graph) * MAX_CHANNEL_PROPERTIES_QUEUE,
+ GFP_KERNEL);
if (!adc_pmic->adc_graph) {
dev_err(&pdev->dev, "Unable to allocate memory\n");
- rc = -ENOMEM;
- goto err_cleanup;
+ return -ENOMEM;
}
/* Will be replaced by individual channel calibration */
@@ -739,32 +721,29 @@
INIT_LIST_HEAD(&adc_pmic->conv_queue_list->slots);
adc_pmic->adc_irq = platform_get_irq(pdev, 0);
- if (adc_pmic->adc_irq < 0) {
- rc = -ENXIO;
- goto err_cleanup;
- }
+ if (adc_pmic->adc_irq < 0)
+ return -ENXIO;
rc = request_threaded_irq(adc_pmic->adc_irq,
NULL, pm8058_xoadc,
IRQF_TRIGGER_RISING, "pm8058_adc_interrupt", adc_pmic);
if (rc) {
dev_err(&pdev->dev, "failed to request adc irq\n");
- goto err_cleanup;
+ return rc;
}
disable_irq(adc_pmic->adc_irq);
- device_init_wakeup(&pdev->dev, pdata->xoadc_wakeup);
-
if (adc_pmic->adc_voter == NULL) {
adc_pmic->adc_voter = msm_xo_get(MSM_XO_TCXO_D1,
"pmic8058_xoadc");
if (IS_ERR(adc_pmic->adc_voter)) {
dev_err(&pdev->dev, "Failed to get XO vote\n");
- goto err_cleanup;
+ return PTR_ERR(adc_pmic->adc_voter);
}
}
+ device_init_wakeup(&pdev->dev, pdata->xoadc_wakeup);
wake_lock_init(&adc_pmic->adc_wakelock, WAKE_LOCK_SUSPEND,
"pmic8058_xoadc_wakelock");
@@ -777,11 +756,21 @@
xoadc_calib_first_adc = false;
return 0;
+}
-err_cleanup:
- pm8058_xoadc_teardown(pdev);
+static int __devexit pm8058_xoadc_teardown(struct platform_device *pdev)
+{
+ struct pmic8058_adc *adc_pmic = platform_get_drvdata(pdev);
- return rc;
+ if (adc_pmic->pdata->xoadc_vreg_shutdown != NULL)
+ adc_pmic->pdata->xoadc_vreg_shutdown();
+
+ wake_lock_destroy(&adc_pmic->adc_wakelock);
+ msm_xo_put(adc_pmic->adc_voter);
+ device_init_wakeup(&pdev->dev, 0);
+ xoadc_initialized = false;
+
+ return 0;
}
static struct platform_driver pm8058_xoadc_driver = {
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 26a69f1..60e1e55 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1132,11 +1132,13 @@
int ret = 0;
if (!qsee_perf_client)
- return -EINVAL;
+ return ret;
/* Check if the clk is valid */
- if (IS_ERR_OR_NULL(qseecom_bus_clk))
+ if (IS_ERR_OR_NULL(qseecom_bus_clk)) {
+ pr_warn("qseecom bus clock is null or error");
return -EINVAL;
+ }
mutex_lock(&qsee_bw_mutex);
if (!qsee_bw_count) {
@@ -1166,8 +1168,10 @@
return;
/* Check if the clk is valid */
- if (IS_ERR_OR_NULL(qseecom_bus_clk))
+ if (IS_ERR_OR_NULL(qseecom_bus_clk)) {
+ pr_warn("qseecom bus clock is null or error");
return;
+ }
mutex_lock(&qsee_bw_mutex);
if (qsee_bw_count > 0) {
@@ -1420,6 +1424,10 @@
char qsee_not_legacy = 0;
uint32_t system_call_id = QSEOS_CHECK_VERSION_CMD;
+ qsee_bw_count = 0;
+ qseecom_bus_clk = NULL;
+ qsee_perf_client = 0;
+
rc = alloc_chrdev_region(&qseecom_device_no, 0, 1, QSEECOM_DEV);
if (rc < 0) {
pr_err("alloc_chrdev_region failed %d\n", rc);
@@ -1483,8 +1491,8 @@
&qsee_bus_pdata);
if (!qsee_perf_client) {
pr_err("Unable to register bus client\n");
-
- qseecom_bus_clk = clk_get(class_dev, "qseecom");
+ } else {
+ qseecom_bus_clk = clk_get(class_dev, "bus_clk");
if (IS_ERR(qseecom_bus_clk)) {
qseecom_bus_clk = NULL;
} else if (qseecom_bus_clk != NULL) {
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 1778d62..c275a06 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -90,7 +90,8 @@
struct single_row_lut *fcc_temp_lut;
struct single_row_lut *fcc_sf_lut;
struct pc_temp_ocv_lut *pc_temp_ocv_lut;
- struct pc_sf_lut *pc_sf_lut;
+ struct sf_lut *pc_sf_lut;
+ struct sf_lut *rbatt_sf_lut;
struct work_struct calib_hkadc_work;
struct delayed_work calib_ccadc_work;
unsigned int calib_delay_ms;
@@ -118,6 +119,9 @@
int max_voltage_uv;
int batt_temp_suspend;
+ int soc_rbatt_suspend;
+ int default_rbatt_mohm;
+ uint16_t prev_last_good_ocv_raw;
};
static struct pm8921_bms_chip *the_chip;
@@ -620,8 +624,9 @@
return 100;
}
-static int interpolate_scalingfactor_pc(struct pm8921_bms_chip *chip,
- int cycles, int pc)
+static int interpolate_scalingfactor(struct pm8921_bms_chip *chip,
+ struct sf_lut *sf_lut,
+ int row_entry, int pc)
{
int i, scalefactorrow1, scalefactorrow2, scalefactor;
int rows, cols;
@@ -632,71 +637,71 @@
* sf table could be null when no battery aging data is available, in
* that case return 100%
*/
- if (!chip->pc_sf_lut)
+ if (!sf_lut)
return 100;
- rows = chip->pc_sf_lut->rows;
- cols = chip->pc_sf_lut->cols;
- if (pc > chip->pc_sf_lut->percent[0]) {
+ rows = sf_lut->rows;
+ cols = sf_lut->cols;
+ if (pc > sf_lut->percent[0]) {
pr_debug("pc %d greater than known pc ranges for sfd\n", pc);
row1 = 0;
row2 = 0;
}
- if (pc < chip->pc_sf_lut->percent[rows - 1]) {
+ if (pc < sf_lut->percent[rows - 1]) {
pr_debug("pc %d less than known pc ranges for sf", pc);
row1 = rows - 1;
row2 = rows - 1;
}
for (i = 0; i < rows; i++) {
- if (pc == chip->pc_sf_lut->percent[i]) {
+ if (pc == sf_lut->percent[i]) {
row1 = i;
row2 = i;
break;
}
- if (pc > chip->pc_sf_lut->percent[i]) {
+ if (pc > sf_lut->percent[i]) {
row1 = i - 1;
row2 = i;
break;
}
}
- if (cycles < chip->pc_sf_lut->cycles[0])
- cycles = chip->pc_sf_lut->cycles[0];
- if (cycles > chip->pc_sf_lut->cycles[cols - 1])
- cycles = chip->pc_sf_lut->cycles[cols - 1];
+ if (row_entry < sf_lut->row_entries[0])
+ row_entry = sf_lut->row_entries[0];
+ if (row_entry > sf_lut->row_entries[cols - 1])
+ row_entry = sf_lut->row_entries[cols - 1];
for (i = 0; i < cols; i++)
- if (cycles <= chip->pc_sf_lut->cycles[i])
+ if (row_entry <= sf_lut->row_entries[i])
break;
- if (cycles == chip->pc_sf_lut->cycles[i]) {
+ if (row_entry == sf_lut->row_entries[i]) {
scalefactor = linear_interpolate(
- chip->pc_sf_lut->sf[row1][i],
- chip->pc_sf_lut->percent[row1],
- chip->pc_sf_lut->sf[row2][i],
- chip->pc_sf_lut->percent[row2],
+ sf_lut->sf[row1][i],
+ sf_lut->percent[row1],
+ sf_lut->sf[row2][i],
+ sf_lut->percent[row2],
pc);
return scalefactor;
}
scalefactorrow1 = linear_interpolate(
- chip->pc_sf_lut->sf[row1][i - 1],
- chip->pc_sf_lut->cycles[i - 1],
- chip->pc_sf_lut->sf[row1][i],
- chip->pc_sf_lut->cycles[i],
- cycles);
+ sf_lut->sf[row1][i - 1],
+ sf_lut->row_entries[i - 1],
+ sf_lut->sf[row1][i],
+ sf_lut->row_entries[i],
+ row_entry);
scalefactorrow2 = linear_interpolate(
- chip->pc_sf_lut->sf[row2][i - 1],
- chip->pc_sf_lut->cycles[i - 1],
- chip->pc_sf_lut->sf[row2][i],
- chip->pc_sf_lut->cycles[i],
- cycles);
+ sf_lut->sf[row2][i - 1],
+ sf_lut->row_entries[i - 1],
+ sf_lut->sf[row2][i],
+ sf_lut->row_entries[i],
+ row_entry);
scalefactor = linear_interpolate(
scalefactorrow1,
- chip->pc_sf_lut->percent[row1],
+ sf_lut->percent[row1],
scalefactorrow2,
- chip->pc_sf_lut->percent[row2],
+ sf_lut->percent[row2],
pc);
return scalefactor;
@@ -913,8 +918,16 @@
mutex_unlock(&chip->bms_output_lock);
usb_chg = usb_chg_plugged_in();
- convert_vbatt_raw_to_uv(chip, usb_chg,
+
+ if (chip->prev_last_good_ocv_raw == 0 ||
+ chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
+ chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
+ convert_vbatt_raw_to_uv(chip, usb_chg,
raw->last_good_ocv_raw, &raw->last_good_ocv_uv);
+ last_ocv_uv = raw->last_good_ocv_uv;
+ } else {
+ raw->last_good_ocv_uv = last_ocv_uv;
+ }
if (raw->last_good_ocv_uv)
last_ocv_uv = raw->last_good_ocv_uv;
@@ -927,6 +940,27 @@
return 0;
}
+static int get_rbatt(struct pm8921_bms_chip *chip, int soc_rbatt, int batt_temp)
+{
+ int rbatt, scalefactor;
+
+ rbatt = (last_rbatt < 0) ? chip->default_rbatt_mohm : last_rbatt;
+ pr_debug("rbatt before scaling = %d\n", rbatt);
+ if (chip->rbatt_sf_lut == NULL) {
+ pr_debug("RBATT = %d\n", rbatt);
+ return rbatt;
+ }
+
+ scalefactor = interpolate_scalingfactor(chip, chip->rbatt_sf_lut,
+ batt_temp, soc_rbatt);
+ pr_debug("rbatt sf = %d for batt_temp = %d, soc_rbatt = %d\n",
+ scalefactor, batt_temp, soc_rbatt);
+ rbatt = (rbatt * scalefactor) / 100;
+
+ pr_debug("RBATT = %d\n", rbatt);
+ return rbatt;
+}
+
static int calculate_rbatt_resume(struct pm8921_bms_chip *chip,
struct pm8921_rbatt_params *raw)
{
@@ -1000,7 +1034,7 @@
return rc;
}
- rbatt = (last_rbatt < 0) ? DEFAULT_RBATT_MOHMS : last_rbatt;
+ rbatt = (last_rbatt < 0) ? chip->default_rbatt_mohm : last_rbatt;
*ocv = vbatt + (ibatt_ua * rbatt)/1000;
return 0;
}
@@ -1014,7 +1048,8 @@
pr_debug("pc = %u for ocv = %dmicroVolts batt_temp = %d\n",
pc, ocv_uv, batt_temp);
- scalefactor = interpolate_scalingfactor_pc(chip, chargecycles, pc);
+ scalefactor = interpolate_scalingfactor(chip,
+ chip->pc_sf_lut, chargecycles, pc);
pr_debug("scalefactor = %u batt_temp = %d\n", scalefactor, batt_temp);
/* Multiply the initial FCC value by the scale factor. */
@@ -1051,12 +1086,10 @@
}
static int calculate_unusable_charge_uah(struct pm8921_bms_chip *chip,
- struct pm8921_soc_params *raw,
- int fcc_uah, int batt_temp, int chargecycles)
+ int rbatt, int fcc_uah,
+ int batt_temp, int chargecycles)
{
- int rbatt, voltage_unusable_uv, pc_unusable;
-
- rbatt = (last_rbatt < 0) ? DEFAULT_RBATT_MOHMS : last_rbatt;
+ int voltage_unusable_uv, pc_unusable;
/* calculate unusable charge */
voltage_unusable_uv = (rbatt * chip->i_test)
@@ -1106,18 +1139,16 @@
int *fcc_uah,
int *unusable_charge_uah,
int *remaining_charge_uah,
- int *cc_uah)
+ int *cc_uah,
+ int *rbatt)
{
unsigned long flags;
+ int soc_rbatt;
*fcc_uah = calculate_fcc_uah(chip, batt_temp, chargecycles);
pr_debug("FCC = %uuAh batt_temp = %d, cycles = %d\n",
*fcc_uah, batt_temp, chargecycles);
- *unusable_charge_uah = calculate_unusable_charge_uah(chip, raw,
- *fcc_uah, batt_temp, chargecycles);
-
- pr_debug("UUC = %uuAh\n", *unusable_charge_uah);
spin_lock_irqsave(&chip->bms_100_lock, flags);
/* calculate remainging charge */
@@ -1132,6 +1163,15 @@
(int64_t)raw->cc - chip->cc_reading_at_100,
chip->cc_reading_at_100);
spin_unlock_irqrestore(&chip->bms_100_lock, flags);
+
+ soc_rbatt = ((*remaining_charge_uah - *cc_uah) * 100) / *fcc_uah;
+ if (soc_rbatt < 0)
+ soc_rbatt = 0;
+ *rbatt = get_rbatt(chip, soc_rbatt, batt_temp);
+
+ *unusable_charge_uah = calculate_unusable_charge_uah(chip, *rbatt,
+ *fcc_uah, batt_temp, chargecycles);
+ pr_debug("UUC = %uuAh\n", *unusable_charge_uah);
}
static int calculate_real_fcc_uah(struct pm8921_bms_chip *chip,
@@ -1143,12 +1183,14 @@
int remaining_charge_uah;
int cc_uah;
int real_fcc_uah;
+ int rbatt;
calculate_soc_params(chip, raw, batt_temp, chargecycles,
&fcc_uah,
&unusable_charge_uah,
&remaining_charge_uah,
- &cc_uah);
+ &cc_uah,
+ &rbatt);
real_fcc_uah = remaining_charge_uah - cc_uah;
*ret_fcc_uah = fcc_uah;
@@ -1170,12 +1212,14 @@
int remaining_charge_uah, soc;
int update_userspace = 1;
int cc_uah;
+ int rbatt;
calculate_soc_params(chip, raw, batt_temp, chargecycles,
&fcc_uah,
&unusable_charge_uah,
&remaining_charge_uah,
- &cc_uah);
+ &cc_uah,
+ &rbatt);
/* calculate remaining usable charge */
remaining_usable_charge_uah = remaining_charge_uah
@@ -1384,6 +1428,44 @@
}
EXPORT_SYMBOL_GPL(pm8921_bms_get_percent_charge);
+int pm8921_bms_get_rbatt(void)
+{
+ int batt_temp, rc;
+ struct pm8xxx_adc_chan_result result;
+ struct pm8921_soc_params raw;
+ int fcc_uah;
+ int unusable_charge_uah;
+ int remaining_charge_uah;
+ int cc_uah;
+ int rbatt;
+
+ if (!the_chip) {
+ pr_err("called before initialization\n");
+ return -EINVAL;
+ }
+
+ rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
+ if (rc) {
+ pr_err("error reading adc channel = %d, rc = %d\n",
+ the_chip->batt_temp_channel, rc);
+ return rc;
+ }
+ pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
+ result.measurement);
+ batt_temp = (int)result.physical;
+
+ read_soc_params_raw(the_chip, &raw);
+
+ calculate_soc_params(the_chip, &raw, batt_temp, last_chargecycles,
+ &fcc_uah,
+ &unusable_charge_uah,
+ &remaining_charge_uah,
+ &cc_uah,
+ &rbatt);
+ return rbatt;
+}
+EXPORT_SYMBOL_GPL(pm8921_bms_get_rbatt);
+
int pm8921_bms_get_fcc(void)
{
int batt_temp, rc;
@@ -1441,6 +1523,7 @@
EXPORT_SYMBOL_GPL(pm8921_bms_charging_began);
#define DELTA_FCC_PERCENT 3
+#define MIN_START_PERCENT_FOR_LEARNING 30
void pm8921_bms_charging_end(int is_battery_full)
{
int batt_temp, rc;
@@ -1464,7 +1547,8 @@
calculate_cc_uah(the_chip, raw.cc, &bms_end_cc_uah);
- if (is_battery_full) {
+ if (is_battery_full
+ && the_chip->start_percent <= MIN_START_PERCENT_FOR_LEARNING) {
unsigned long flags;
int fcc_uah, new_fcc_uah, delta_fcc_uah;
@@ -1475,18 +1559,25 @@
if (delta_fcc_uah < 0)
delta_fcc_uah = -delta_fcc_uah;
- if (delta_fcc_uah * 100 <= (DELTA_FCC_PERCENT * fcc_uah)) {
- pr_debug("delta_fcc=%d < %d percent of fcc=%d\n",
- delta_fcc_uah, DELTA_FCC_PERCENT, fcc_uah);
- last_real_fcc_mah = new_fcc_uah/1000;
- last_real_fcc_batt_temp = batt_temp;
- readjust_fcc_table();
- } else {
+ if (delta_fcc_uah * 100 > (DELTA_FCC_PERCENT * fcc_uah)) {
+ /* new_fcc_uah is outside the scope limit it */
+ if (new_fcc_uah > fcc_uah)
+ new_fcc_uah
+ = (fcc_uah + DELTA_FCC_PERCENT * fcc_uah);
+ else
+ new_fcc_uah
+ = (fcc_uah - DELTA_FCC_PERCENT * fcc_uah);
+
pr_debug("delta_fcc=%d > %d percent of fcc=%d"
- "will not update real fcc\n",
- delta_fcc_uah, DELTA_FCC_PERCENT, fcc_uah);
+ "restring it to %d\n",
+ delta_fcc_uah, DELTA_FCC_PERCENT,
+ fcc_uah, new_fcc_uah);
}
+ last_real_fcc_mah = new_fcc_uah/1000;
+ last_real_fcc_batt_temp = batt_temp;
+ readjust_fcc_table();
+
spin_lock_irqsave(&the_chip->bms_100_lock, flags);
the_chip->ocv_reading_at_100 = raw.last_good_ocv_raw;
the_chip->cc_reading_at_100 = raw.cc;
@@ -1652,6 +1743,10 @@
int rc;
struct pm8xxx_adc_chan_result result;
struct pm8921_bms_chip *chip = dev_get_drvdata(dev);
+ struct pm8921_soc_params raw;
+ int fcc_uah;
+ int remaining_charge_uah;
+ int cc_uah;
chip->batt_temp_suspend = 0;
rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
@@ -1660,20 +1755,66 @@
chip->batt_temp_channel, rc);
}
chip->batt_temp_suspend = (int)result.physical;
+ read_soc_params_raw(chip, &raw);
+
+ fcc_uah = calculate_fcc_uah(chip,
+ chip->batt_temp_suspend, last_chargecycles);
+ pr_debug("FCC = %uuAh batt_temp = %d, cycles = %d\n",
+ fcc_uah, chip->batt_temp_suspend, last_chargecycles);
+ /* calculate remainging charge */
+ remaining_charge_uah = calculate_remaining_charge_uah(chip, &raw,
+ fcc_uah, chip->batt_temp_suspend,
+ last_chargecycles);
+ pr_debug("RC = %uuAh\n", remaining_charge_uah);
+
+ /* calculate cc micro_volt_hour */
+ calculate_cc_uah(chip, raw.cc, &cc_uah);
+ pr_debug("cc_uah = %duAh raw->cc = %x cc = %lld after subtracting %d\n",
+ cc_uah, raw.cc,
+ (int64_t)raw.cc - chip->cc_reading_at_100,
+ chip->cc_reading_at_100);
+ chip->soc_rbatt_suspend = ((remaining_charge_uah - cc_uah) * 100)
+ / fcc_uah;
return 0;
}
+#define DELTA_RBATT_PERCENT 10
static int pm8921_bms_resume(struct device *dev)
{
struct pm8921_rbatt_params raw;
struct pm8921_bms_chip *chip = dev_get_drvdata(dev);
int rbatt;
+ int expected_rbatt;
+ int scalefactor;
+ int delta_rbatt;
read_rbatt_params_raw(chip, &raw);
rbatt = calculate_rbatt_resume(chip, &raw);
- if (rbatt > 0) /* TODO Check for rbatt values bound based on cycles */
+
+ if (rbatt < 0)
+ return 0;
+
+ expected_rbatt
+ = (last_rbatt < 0) ? chip->default_rbatt_mohm : last_rbatt;
+
+ if (chip->rbatt_sf_lut) {
+ scalefactor = interpolate_scalingfactor(chip,
+ chip->rbatt_sf_lut,
+ chip->batt_temp_suspend,
+ chip->soc_rbatt_suspend);
+ rbatt = rbatt * 100 / scalefactor;
+ }
+
+ delta_rbatt = expected_rbatt - rbatt;
+ if (delta_rbatt)
+ delta_rbatt = -delta_rbatt;
+ /*
+ * only update last_rbatt if rbatt is within some
+ * percent of expected_rbatt
+ */
+ if (delta_rbatt * 100 <= DELTA_RBATT_PERCENT * expected_rbatt)
last_rbatt = rbatt;
- chip->batt_temp_suspend = -EINVAL;
+
return 0;
}
@@ -1767,7 +1908,9 @@
battery_id)) {
goto desay;
} else {
- goto unknown;
+ pr_warn("invalid battid, palladium 1500 assumed batt_id %llx\n",
+ battery_id);
+ goto palladium;
}
palladium:
@@ -1776,22 +1919,17 @@
chip->fcc_sf_lut = palladium_1500_data.fcc_sf_lut;
chip->pc_temp_ocv_lut = palladium_1500_data.pc_temp_ocv_lut;
chip->pc_sf_lut = palladium_1500_data.pc_sf_lut;
+ chip->rbatt_sf_lut = palladium_1500_data.rbatt_sf_lut;
+ chip->default_rbatt_mohm
+ = palladium_1500_data.default_rbatt_mohm;
return 0;
desay:
chip->fcc = desay_5200_data.fcc;
chip->fcc_temp_lut = desay_5200_data.fcc_temp_lut;
- chip->fcc_sf_lut = desay_5200_data.fcc_sf_lut;
chip->pc_temp_ocv_lut = desay_5200_data.pc_temp_ocv_lut;
chip->pc_sf_lut = desay_5200_data.pc_sf_lut;
- return 0;
-unknown:
- pr_warn("invalid battery id, palladium 1500 assumed batt_id %llx\n",
- battery_id);
- chip->fcc = palladium_1500_data.fcc;
- chip->fcc_temp_lut = palladium_1500_data.fcc_temp_lut;
- chip->fcc_sf_lut = palladium_1500_data.fcc_sf_lut;
- chip->pc_temp_ocv_lut = palladium_1500_data.pc_temp_ocv_lut;
- chip->pc_sf_lut = palladium_1500_data.pc_sf_lut;
+ chip->rbatt_sf_lut = desay_5200_data.rbatt_sf_lut;
+ chip->default_rbatt_mohm = desay_5200_data.default_rbatt_mohm;
return 0;
}
@@ -2087,6 +2225,16 @@
goto free_chip;
}
+ if (chip->pc_temp_ocv_lut == NULL) {
+ pr_err("temp ocv lut table is NULL\n");
+ rc = -EINVAL;
+ goto free_chip;
+ }
+
+ /* set defaults in the battery data */
+ if (chip->default_rbatt_mohm <= 0)
+ chip->default_rbatt_mohm = DEFAULT_RBATT_MOHMS;
+
chip->batt_temp_channel = pdata->bms_cdata.batt_temp_channel;
chip->vbat_channel = pdata->bms_cdata.vbat_channel;
chip->ref625mv_channel = pdata->bms_cdata.ref625mv_channel;
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index c4c7941..72bff49 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -664,21 +664,20 @@
struct usb_diag_ch *ch;
list_for_each_entry(ch, &usb_diag_ch_list, list) {
- struct diag_context *ctxt;
+ struct diag_context *ctxt = ch->priv_usb;
- ctxt = ch->priv_usb;
-
- temp += scnprintf(buf + temp, PAGE_SIZE - temp,
- "---Name: %s---\n"
- "endpoints: %s, %s\n"
- "dpkts_tolaptop: %lu\n"
- "dpkts_tomodem: %lu\n"
- "pkts_tolaptop_pending: %u\n",
- ch->name,
- ctxt->in->name, ctxt->out->name,
- ctxt->dpkts_tolaptop,
- ctxt->dpkts_tomodem,
- ctxt->dpkts_tolaptop_pending);
+ if (ctxt)
+ temp += scnprintf(buf + temp, PAGE_SIZE - temp,
+ "---Name: %s---\n"
+ "endpoints: %s, %s\n"
+ "dpkts_tolaptop: %lu\n"
+ "dpkts_tomodem: %lu\n"
+ "pkts_tolaptop_pending: %u\n",
+ ch->name,
+ ctxt->in->name, ctxt->out->name,
+ ctxt->dpkts_tolaptop,
+ ctxt->dpkts_tomodem,
+ ctxt->dpkts_tolaptop_pending);
}
return simple_read_from_buffer(ubuf, count, ppos, buf, temp);
@@ -690,13 +689,13 @@
struct usb_diag_ch *ch;
list_for_each_entry(ch, &usb_diag_ch_list, list) {
- struct diag_context *ctxt;
+ struct diag_context *ctxt = ch->priv_usb;
- ctxt = ch->priv_usb;
-
- ctxt->dpkts_tolaptop = 0;
- ctxt->dpkts_tomodem = 0;
- ctxt->dpkts_tolaptop_pending = 0;
+ if (ctxt) {
+ ctxt->dpkts_tolaptop = 0;
+ ctxt->dpkts_tomodem = 0;
+ ctxt->dpkts_tolaptop_pending = 0;
+ }
}
return count;
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index e6c869f..5a72ad4 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -3,6 +3,8 @@
obj-$(CONFIG_FB_MSM_LOGO) += logo.o
obj-$(CONFIG_FB_BACKLIGHT) += msm_fb_bl.o
+ifeq ($(CONFIG_FB_MSM_MDP_HW),y)
+
# MDP
obj-y += mdp.o
@@ -177,6 +179,12 @@
obj-$(CONFIG_MSM_VIDC_1080P) += vidc/
obj-$(CONFIG_MSM_VIDC_720P) += vidc/
+else
+obj-$(CONFIG_FB_MSM_EBI2) += ebi2_host.o
+obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o
+obj-y += msm_fb_panel.o
+obj-$(CONFIG_FB_MSM_EBI2_EPSON_S1D_QVGA_PANEL) += ebi2_epson_s1d_qvga.o
+endif
clean:
rm *.o .*cmd
diff --git a/drivers/video/msm/adv7520.c b/drivers/video/msm/adv7520.c
index 7386983..df501dd 100644
--- a/drivers/video/msm/adv7520.c
+++ b/drivers/video/msm/adv7520.c
@@ -874,11 +874,11 @@
} else
DEV_ERR("adv7520_probe: failed to add fb device\n");
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- external_common_state->sdev.name = "hdmi_as_primary";
-#else
- external_common_state->sdev.name = "hdmi";
-#endif
+ if (hdmi_prim_display)
+ external_common_state->sdev.name = "hdmi_as_primary";
+ else
+ external_common_state->sdev.name = "hdmi";
+
if (switch_dev_register(&external_common_state->sdev) < 0)
DEV_ERR("Hdmi switch registration failed\n");
diff --git a/drivers/video/msm/ebi2_epson_s1d_qvga.c b/drivers/video/msm/ebi2_epson_s1d_qvga.c
new file mode 100644
index 0000000..8821eab
--- /dev/null
+++ b/drivers/video/msm/ebi2_epson_s1d_qvga.c
@@ -0,0 +1,374 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+
+#include <linux/memory.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include "linux/proc_fs.h"
+
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#define CMD_NOP_C 0x00
+#define CMD_SOFT_RESET_C 0x99
+#define CMD_DISPLAY_ON_C 0xAF
+#define CMD_DISPLAY_OFF_C 0xAE
+#define CMD_SET_DISPLAY_C 0xCA
+#define CMD_SET_DISPLAY_TIMING_C 0xA1
+#define CMD_SET_DATA_C 0xBC
+#define CMD_SET_START_ADDRESS_C 0x15
+#define CMD_SET_END_ADDRESS_C 0x75
+#define CMD_RAM_WRITE_C 0x5C
+#define CMD_RAM_READ_C 0x5D
+#define CMD_SET_AREA_SCROLLING_C 0xAA
+#define CMD_SET_DISPLAY_START_LINE_C 0xAB
+#define CMD_PARTIAL_DISPLAY_IN_C 0xA8
+#define CMD_PARTIAL_DISPLAY_OUT_C 0xA9
+#define CMD_SET_DISPLAY_DATA_INTERFACE_C 0x31
+#define CMD_SET_DISPLAY_COLOR_MODE_C 0x8B
+#define CMD_SELECT_MTP_ROM_MODE_C 0x65
+#define CMD_MTP_ROM_MODE_IN_C 0x67
+#define CMD_MTP_ROM_MODE_OUT_C 0x68
+#define CMD_MTP_ROM_OPERATION_IN_C 0x69
+#define CMD_MTP_ROM_OPERATION_OUT_C 0x70
+#define CMD_GATE_LINE_SCAN_MODE_C 0x6F
+#define CMD_SET_AC_OPERATION_DRIVE_C 0x8C
+#define CMD_SET_ELECTRONIC_CONTROL_C 0x20
+#define CMD_SET_POSITIVE_CORRECTION_CHARS_C 0x22
+#define CMD_SET_NEGATIVE_CORRECTION_CHARS_C 0x25
+#define CMD_SET_POWER_CONTROL_C 0x21
+#define CMD_SET_PARTIAL_POWER_CONTROL_C 0x23
+#define CMD_SET_8_COLOR_CONTROL_C 0x24
+#define CMD_SLEEP_IN_C 0x95
+#define CMD_SLEEP_OUT_C 0x94
+#define CMD_VDD_OFF_C 0x97
+#define CMD_VDD_ON_C 0x96
+#define CMD_STOP_OSCILLATION_C 0x93
+#define CMD_START_OSCILLATION_C 0x92
+#define CMD_TEST_SOURCE_C 0xFD
+#define CMD_TEST_FUSE_C 0xFE
+#define CMD_TEST_C 0xFF
+#define CMD_STATUS_READ_C 0xE8
+#define CMD_REVISION_READ_C 0xE9
+
+#define PANEL_WIDTH 240
+#define PANEL_HEIGHT 320
+#define ACTIVE_WIN_WIDTH PANEL_WIDTH
+#define ACTIVE_WIN_HEIGHT PANEL_HEIGHT
+
+#define ACTIVE_WIN_H_START 0
+#define ACTIVE_WIN_V_START 0
+
+#define DISP_CMD_OUT(cmd) outpw(DISP_CMD_PORT, (cmd << 1));
+#define DISP_DATA_OUT(data) outpw(DISP_DATA_PORT, (data << 1));
+#define DISP_DATA_IN() inpw(DISP_DATA_PORT);
+
+static void *DISP_CMD_PORT;
+static void *DISP_DATA_PORT;
+static boolean disp_initialized;
+static boolean display_on;
+static struct msm_panel_common_pdata *ebi2_epson_pdata;
+
+static void epson_s1d_disp_init(struct platform_device *pdev);
+static int epson_s1d_disp_off(struct platform_device *pdev);
+static int epson_s1d_disp_on(struct platform_device *pdev);
+static void epson_s1d_disp_set_rect(int x, int y, int xres, int yres);
+
+static void epson_s1d_disp_set_rect(int x, int y, int xres, int yres)
+{
+ int right, bottom;
+
+ if (!disp_initialized)
+ return;
+
+ right = x + xres - 1;
+ bottom = y + yres - 1;
+
+ x += ACTIVE_WIN_H_START;
+ y += ACTIVE_WIN_V_START;
+ right += ACTIVE_WIN_H_START;
+ bottom += ACTIVE_WIN_V_START;
+
+ if ((PANEL_WIDTH > x) &&
+ (PANEL_HEIGHT > y) &&
+ (PANEL_WIDTH > right) &&
+ (PANEL_HEIGHT > bottom)) {
+ DISP_CMD_OUT(CMD_SET_START_ADDRESS_C);
+ DISP_DATA_OUT((uint8)x);
+ DISP_DATA_OUT((uint8)(y>>8));
+ DISP_DATA_OUT((uint8)y);
+
+ DISP_CMD_OUT(CMD_SET_END_ADDRESS_C);
+ DISP_DATA_OUT((uint8)right);
+ DISP_DATA_OUT((uint8)(bottom>>8));
+ DISP_DATA_OUT((uint8)bottom);
+ DISP_CMD_OUT(CMD_RAM_WRITE_C);
+ }
+}
+
+static void epson_s1d_disp_init(struct platform_device *pdev)
+{
+ struct msm_fb_data_type *mfd;
+
+ if (disp_initialized)
+ return;
+
+ mfd = platform_get_drvdata(pdev);
+
+ DISP_CMD_PORT = mfd->cmd_port;
+ DISP_DATA_PORT = mfd->data_port;
+
+ disp_initialized = TRUE;
+}
+
+static int epson_s1d_disp_off(struct platform_device *pdev)
+{
+ if (!disp_initialized)
+ epson_s1d_disp_init(pdev);
+
+ if (display_on) {
+ DISP_CMD_OUT(CMD_SOFT_RESET_C);
+ DISP_CMD_OUT(CMD_VDD_OFF_C);
+ display_on = FALSE;
+ }
+
+ return 0;
+}
+
+static int epson_s1d_disp_on(struct platform_device *pdev)
+{
+ int i;
+ if (!disp_initialized)
+ epson_s1d_disp_init(pdev);
+
+ if (!display_on) {
+ /* Enable Vdd regulator */
+ DISP_CMD_OUT(CMD_VDD_ON_C);
+ msleep(20);
+
+ /* Soft Reset before configuring display */
+ DISP_CMD_OUT(CMD_SOFT_RESET_C);
+ msleep(20);
+
+ /* Set display attributes */
+
+ /* GATESCAN */
+ DISP_CMD_OUT(CMD_GATE_LINE_SCAN_MODE_C);
+ DISP_DATA_OUT(0x0);
+
+ /* DISSET */
+ DISP_CMD_OUT(CMD_SET_DISPLAY_C);
+ DISP_DATA_OUT(0x31);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT((uint8)((PANEL_HEIGHT - 1)>>8));
+ DISP_DATA_OUT((uint8)(PANEL_HEIGHT - 1));
+ DISP_DATA_OUT(0x03);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT(0x08);
+
+ /* VOLSET */
+ DISP_CMD_OUT(
+ CMD_SET_ELECTRONIC_CONTROL_C);
+ DISP_DATA_OUT(0x10);
+ DISP_DATA_OUT(0x80);
+ DISP_DATA_OUT(0x11);
+ DISP_DATA_OUT(0x1B);
+ DISP_DATA_OUT(0x02);
+ DISP_DATA_OUT(0x0D);
+ DISP_DATA_OUT(0x00);
+
+ /* PWRCTL */
+ DISP_CMD_OUT(CMD_SET_POWER_CONTROL_C);
+ DISP_DATA_OUT(0x01);
+ DISP_DATA_OUT(0x24);
+ DISP_DATA_OUT(0x0F);
+ DISP_DATA_OUT(0xFE);
+ DISP_DATA_OUT(0x33);
+ DISP_DATA_OUT(0x31);
+ DISP_DATA_OUT(0xFF);
+ DISP_DATA_OUT(0x03);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT(0x77);
+ DISP_DATA_OUT(0x33);
+ DISP_DATA_OUT(0x11);
+ DISP_DATA_OUT(0x44);
+ DISP_DATA_OUT(0x00);
+
+ /* PPWRCTL */
+ DISP_CMD_OUT(CMD_SET_PARTIAL_POWER_CONTROL_C);
+ DISP_DATA_OUT(0x33);
+ DISP_DATA_OUT(0xFF);
+ DISP_DATA_OUT(0x03);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT(0x44);
+ DISP_DATA_OUT(0x00);
+
+ /* SPLOUT */
+ DISP_CMD_OUT(CMD_SLEEP_OUT_C);
+ msleep(100);
+
+ /* DATSET */
+ DISP_CMD_OUT(CMD_SET_DATA_C);
+ DISP_DATA_OUT(0x00);
+
+ /* DISTMEMSET */
+ DISP_CMD_OUT(CMD_SET_DISPLAY_TIMING_C);
+ DISP_DATA_OUT(0x01);
+ DISP_DATA_OUT(0x2E);
+ DISP_DATA_OUT(0x0A);
+ DISP_DATA_OUT(0x2C);
+ DISP_DATA_OUT(0x23);
+ DISP_DATA_OUT(0x2F);
+ DISP_DATA_OUT(0x00);
+
+ /* GAMSETP */
+ DISP_CMD_OUT(CMD_SET_POSITIVE_CORRECTION_CHARS_C);
+ DISP_DATA_OUT(0x37);
+ DISP_DATA_OUT(0xFF);
+ DISP_DATA_OUT(0x7F);
+ DISP_DATA_OUT(0x15);
+ DISP_DATA_OUT(0x37);
+ DISP_DATA_OUT(0x05);
+
+ /* GAMSETN */
+ DISP_CMD_OUT(CMD_SET_NEGATIVE_CORRECTION_CHARS_C);
+ DISP_DATA_OUT(0x37);
+ DISP_DATA_OUT(0xFF);
+ DISP_DATA_OUT(0x7F);
+ DISP_DATA_OUT(0x15);
+ DISP_DATA_OUT(0x37);
+ DISP_DATA_OUT(0x05);
+
+ /* ACDRIVE */
+ DISP_CMD_OUT(CMD_SET_AC_OPERATION_DRIVE_C);
+ DISP_DATA_OUT(0x00);
+
+ /* TEST */
+ DISP_CMD_OUT(CMD_TEST_C);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT(0x01);
+
+ /* COLMOD */
+ DISP_CMD_OUT(CMD_SET_DISPLAY_COLOR_MODE_C);
+ DISP_DATA_OUT(0x00);
+
+ /* STADDSET */
+ DISP_CMD_OUT(CMD_SET_START_ADDRESS_C);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT(0x00);
+
+ /* EDADDSET */
+ DISP_CMD_OUT(CMD_SET_END_ADDRESS_C);
+ DISP_DATA_OUT(0xEF);
+ DISP_DATA_OUT(0x01);
+ DISP_DATA_OUT(0x3F);
+
+ /* Set Display Start Line */
+ DISP_CMD_OUT(CMD_SET_DISPLAY_START_LINE_C);
+ DISP_DATA_OUT(0x00);
+
+ /* Set Display Data Interface */
+ DISP_CMD_OUT(CMD_SET_DISPLAY_DATA_INTERFACE_C);
+ DISP_DATA_OUT(0x00);
+ DISP_DATA_OUT(0x04);
+
+ epson_s1d_disp_set_rect(0,
+ 0,
+ ACTIVE_WIN_WIDTH,
+ ACTIVE_WIN_HEIGHT);
+
+ for (i = 0; i < (ACTIVE_WIN_WIDTH * ACTIVE_WIN_HEIGHT); i++)
+ outpdw(DISP_DATA_PORT, 0);
+
+ /* DISON */
+ DISP_CMD_OUT(CMD_DISPLAY_ON_C);
+ msleep(60);
+
+ display_on = TRUE;
+ }
+
+ return 0;
+}
+
+static int epson_s1d_probe(struct platform_device *pdev)
+{
+ if (pdev->id == 0) {
+ ebi2_epson_pdata = pdev->dev.platform_data;
+ return 0;
+ }
+
+ msm_fb_add_device(pdev);
+ return 0;
+}
+
+static struct platform_driver this_driver = {
+ .probe = epson_s1d_probe,
+ .driver = {
+ .name = "ebi2_epson_s1d_qvga",
+ },
+};
+
+static struct msm_fb_panel_data epson_s1d_panel_data = {
+ .on = epson_s1d_disp_on,
+ .off = epson_s1d_disp_off,
+ .set_rect = epson_s1d_disp_set_rect,
+};
+
+static struct platform_device this_device = {
+ .name = "ebi2_epson_s1d_qvga",
+ .id = 1,
+ .dev = {
+ .platform_data = &epson_s1d_panel_data,
+ }
+};
+
+static int __init epson_s1d_init(void)
+{
+ int ret;
+ struct msm_panel_info *pinfo;
+
+ ret = platform_driver_register(&this_driver);
+ if (!ret) {
+ pinfo = &epson_s1d_panel_data.panel_info;
+ pinfo->xres = PANEL_WIDTH;
+ pinfo->yres = PANEL_HEIGHT;
+ MSM_FB_SINGLE_MODE_PANEL(pinfo);
+ pinfo->type = EBI2_PANEL;
+ pinfo->pdest = DISPLAY_1;
+ pinfo->wait_cycle = 0x048423E8;
+ pinfo->bpp = 18;
+ pinfo->fb_num = 2;
+ pinfo->lcd.vsync_enable = FALSE;
+
+ ret = platform_device_register(&this_device);
+ if (ret)
+ platform_driver_unregister(&this_driver);
+ }
+
+ return ret;
+}
+
+module_init(epson_s1d_init);
diff --git a/drivers/video/msm/ebi2_host.c b/drivers/video/msm/ebi2_host.c
new file mode 100644
index 0000000..8ba5506
--- /dev/null
+++ b/drivers/video/msm/ebi2_host.c
@@ -0,0 +1,307 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/hrtimer.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/clk.h>
+#include <mach/hardware.h>
+#include "msm_fb.h"
+
+struct mdp_ccs mdp_ccs_rgb2yuv;
+struct mdp_ccs mdp_ccs_yuv2rgb;
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+static int ebi2_host_resource_initialized;
+static struct msm_panel_common_pdata *ebi2_host_pdata;
+
+static int ebi2_host_probe(struct platform_device *pdev);
+static int ebi2_host_remove(struct platform_device *pdev);
+
+static int ebi2_host_runtime_suspend(struct device *dev)
+{
+ dev_dbg(dev, "pm_runtime: suspending...\n");
+ return 0;
+}
+
+static int ebi2_host_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "pm_runtime: resuming...\n");
+ return 0;
+}
+
+static const struct dev_pm_ops ebi2_host_dev_pm_ops = {
+ .runtime_suspend = ebi2_host_runtime_suspend,
+ .runtime_resume = ebi2_host_runtime_resume,
+};
+
+
+static struct platform_driver ebi2_host_driver = {
+ .probe = ebi2_host_probe,
+ .remove = ebi2_host_remove,
+ .shutdown = NULL,
+ .driver = {
+ /*
+ * Simulate mdp hw
+ */
+ .name = "mdp",
+ .pm = &ebi2_host_dev_pm_ops,
+ },
+};
+
+void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
+ boolean isr)
+{
+ return;
+}
+int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req)
+{
+ return 0;
+}
+int mdp_start_histogram(struct fb_info *info)
+{
+ return 0;
+}
+int mdp_stop_histogram(struct fb_info *info)
+{
+ return 0;
+}
+void mdp_refresh_screen(unsigned long data)
+{
+ return;
+}
+
+static int ebi2_host_off(struct platform_device *pdev)
+{
+ int ret;
+ ret = panel_next_off(pdev);
+ return ret;
+}
+
+static int ebi2_host_on(struct platform_device *pdev)
+{
+ int ret;
+ ret = panel_next_on(pdev);
+ return ret;
+}
+
+
+static int ebi2_host_probe(struct platform_device *pdev)
+{
+ struct platform_device *msm_fb_dev = NULL;
+ struct msm_fb_data_type *mfd;
+ struct msm_fb_panel_data *pdata = NULL;
+ int rc;
+
+ if ((pdev->id == 0) && (pdev->num_resources > 0)) {
+
+ ebi2_host_pdata = pdev->dev.platform_data;
+
+ ebi2_host_resource_initialized = 1;
+ return 0;
+ }
+
+ ebi2_host_resource_initialized = 1;
+ if (!ebi2_host_resource_initialized)
+ return -EPERM;
+
+ mfd = platform_get_drvdata(pdev);
+
+ if (!mfd)
+ return -ENODEV;
+
+ if (mfd->key != MFD_KEY)
+ return -EINVAL;
+
+ if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+ return -ENOMEM;
+
+ msm_fb_dev = platform_device_alloc("msm_fb", pdev->id);
+ if (!msm_fb_dev)
+ return -ENOMEM;
+
+ /* link to the latest pdev */
+ mfd->pdev = msm_fb_dev;
+
+ if (ebi2_host_pdata) {
+ mfd->mdp_rev = ebi2_host_pdata->mdp_rev;
+ mfd->mem_hid = ebi2_host_pdata->mem_hid;
+ }
+
+ /* add panel data */
+ if (platform_device_add_data
+ (msm_fb_dev, pdev->dev.platform_data,
+ sizeof(struct msm_fb_panel_data))) {
+ pr_err("ebi2_host_probe: platform_device_add_data failed!\n");
+ rc = -ENOMEM;
+ goto ebi2_host_probe_err;
+ }
+ /* data chain */
+ pdata = msm_fb_dev->dev.platform_data;
+ pdata->on = ebi2_host_on;
+ pdata->off = ebi2_host_off;
+ pdata->next = pdev;
+
+ /* set driver data */
+ platform_set_drvdata(msm_fb_dev, mfd);
+
+ rc = platform_device_add(msm_fb_dev);
+ if (rc)
+ goto ebi2_host_probe_err;
+
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+ pdev_list[pdev_list_cnt++] = pdev;
+ return 0;
+
+ebi2_host_probe_err:
+ platform_device_put(msm_fb_dev);
+ return rc;
+}
+
+void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
+ boolean sync)
+{
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+ struct fb_info *fbi = mfd->fbi;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
+ MDPIBUF *iBuf;
+ int bpp = info->var.bits_per_pixel / 8;
+ int yres, remainder;
+
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
+ down(&mfd->sem);
+
+ iBuf = &mfd->ibuf;
+ /* use virtual address */
+ iBuf->buf = (uint8 *) fbi->screen_base;
+
+ if (fbi->var.yoffset < yres) {
+ iBuf->buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ iBuf->buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ iBuf->buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
+
+ iBuf->ibuf_width = info->var.xres_virtual;
+ iBuf->bpp = bpp;
+
+ iBuf->vsync_enable = sync;
+
+ if (dirty) {
+ /*
+ * ToDo: dirty region check inside var.xoffset+xres
+ * <-> var.yoffset+yres
+ */
+ iBuf->dma_x = dirty->xoffset % info->var.xres;
+ iBuf->dma_y = dirty->yoffset % info->var.yres;
+ iBuf->dma_w = dirty->width;
+ iBuf->dma_h = dirty->height;
+ } else {
+ iBuf->dma_x = 0;
+ iBuf->dma_y = 0;
+ iBuf->dma_w = info->var.xres;
+ iBuf->dma_h = info->var.yres;
+ }
+ mfd->ibuf_flushed = FALSE;
+ up(&mfd->sem);
+}
+
+void mdp_dma_pan_update(struct fb_info *info)
+{
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+ MDPIBUF *iBuf;
+ int i, j;
+ uint32 data;
+ uint8 *src;
+ struct msm_fb_panel_data *pdata =
+ (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+ struct fb_info *fbi = mfd->fbi;
+
+ iBuf = &mfd->ibuf;
+
+ invalidate_caches((unsigned long)fbi->screen_base,
+ (unsigned long)info->fix.smem_len,
+ (unsigned long)info->fix.smem_start);
+
+ pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
+ iBuf->dma_h);
+ for (i = 0; i < iBuf->dma_h; i++) {
+ src = iBuf->buf + (fbi->fix.line_length * (iBuf->dma_y + i))
+ + (iBuf->dma_x * iBuf->bpp);
+ for (j = 0; j < iBuf->dma_w; j++) {
+ data = (uint32)(*src++ >> 2) << 12;
+ data |= (uint32)(*src++ >> 2) << 6;
+ data |= (uint32)(*src++ >> 2);
+ data = ((data&0x1FF)<<16) | ((data&0x3FE00)>>9);
+ outpdw(mfd->data_port, data);
+ }
+ }
+}
+
+static int ebi2_host_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static int ebi2_host_register_driver(void)
+{
+ return platform_driver_register(&ebi2_host_driver);
+}
+
+static int __init ebi2_host_driver_init(void)
+{
+ int ret;
+
+ ret = ebi2_host_register_driver();
+ if (ret) {
+ pr_err("ebi2_host_register_driver() failed!\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+module_init(ebi2_host_driver_init);
diff --git a/drivers/video/msm/ebi2_lcd.c b/drivers/video/msm/ebi2_lcd.c
index 68590af..966f974 100644
--- a/drivers/video/msm/ebi2_lcd.c
+++ b/drivers/video/msm/ebi2_lcd.c
@@ -56,8 +56,6 @@
.probe = ebi2_lcd_probe,
.remove = ebi2_lcd_remove,
.suspend = NULL,
- .suspend_late = NULL,
- .resume_early = NULL,
.resume = NULL,
.shutdown = NULL,
.driver = {
@@ -71,17 +69,42 @@
static void *ebi2_lcd_cfg1;
static void __iomem *lcd01_base;
static void __iomem *lcd02_base;
+static int lcd01_base_phys;
static int ebi2_lcd_resource_initialized;
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
+static struct lcdc_platform_data *ebi2_pdata;
+
+static int ebi2_lcd_on(struct platform_device *pdev)
+{
+ int ret;
+
+ if (ebi2_pdata && ebi2_pdata->lcdc_power_save)
+ ebi2_pdata->lcdc_power_save(1);
+
+ ret = panel_next_on(pdev);
+ return ret;
+}
+
+static int ebi2_lcd_off(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = panel_next_off(pdev);
+
+ if (ebi2_pdata && ebi2_pdata->lcdc_power_save)
+ ebi2_pdata->lcdc_power_save(0);
+
+ return ret;
+}
static int ebi2_lcd_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
- int rc, i;
+ int rc, i, hw_version;
if (pdev->id == 0) {
for (i = 0; i < pdev->num_resources; i++) {
@@ -98,6 +121,7 @@
ebi2_lcd_cfg1 = (void *)(ebi2_base + 0x24);
} else if (!strncmp(pdev->resource[i].name,
"lcd01", 5)) {
+ lcd01_base_phys = pdev->resource[i].start;
lcd01_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
@@ -118,7 +142,9 @@
}
}
}
+ ebi2_pdata = pdev->dev.platform_data;
ebi2_lcd_resource_initialized = 1;
+
return 0;
}
@@ -158,15 +184,19 @@
/* data chain */
pdata = mdp_dev->dev.platform_data;
- pdata->on = panel_next_on;
- pdata->off = panel_next_off;
+ pdata->on = ebi2_lcd_on;
+ pdata->off = ebi2_lcd_off;
pdata->next = pdev;
/* get/set panel specific fb info */
mfd->panel_info = pdata->panel_info;
+ hw_version = inp32((int)ebi2_base + 8);
+
if (mfd->panel_info.bpp == 24)
mfd->fb_imgType = MDP_RGB_888;
+ else if (mfd->panel_info.bpp == 18)
+ mfd->fb_imgType = MDP_RGB_888;
else
mfd->fb_imgType = MDP_RGB_565;
@@ -181,10 +211,12 @@
* configure both.
*/
outp32(ebi2_lcd_cfg0, mfd->panel_info.wait_cycle);
- if (mfd->panel_info.bpp == 18)
- outp32(ebi2_lcd_cfg1, 0x01000000);
- else
- outp32(ebi2_lcd_cfg1, 0x0);
+ if (hw_version < 0x2020) {
+ if (mfd->panel_info.bpp == 18)
+ outp32(ebi2_lcd_cfg1, 0x01000000);
+ else
+ outp32(ebi2_lcd_cfg1, 0x0);
+ }
} else {
#ifdef DEBUG_EBI2_LCD
/*
@@ -201,10 +233,18 @@
*/
if (mfd->panel_info.pdest == DISPLAY_1) {
mfd->cmd_port = lcd01_base;
- mfd->data_port =
- (void *)((uint32) mfd->cmd_port + EBI2_PRIM_LCD_RS_PIN);
- mfd->data_port_phys =
- (void *)(LCD_PRIM_BASE_PHYS + EBI2_PRIM_LCD_RS_PIN);
+ if (hw_version >= 0x2020) {
+ mfd->data_port =
+ (void *)((uint32) mfd->cmd_port + 0x80);
+ mfd->data_port_phys =
+ (void *)(lcd01_base_phys + 0x80);
+ } else {
+ mfd->data_port =
+ (void *)((uint32) mfd->cmd_port +
+ EBI2_PRIM_LCD_RS_PIN);
+ mfd->data_port_phys =
+ (void *)(LCD_PRIM_BASE_PHYS + EBI2_PRIM_LCD_RS_PIN);
+ }
} else {
mfd->cmd_port = lcd01_base;
mfd->data_port =
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index eec600e..f6e43bf 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -320,6 +320,18 @@
return ret;
}
+static ssize_t hdmi_common_rda_edid_physical_address(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ external_common_state->physical_address);
+
+ DEV_DBG("%s: '%d'\n", __func__,
+ external_common_state->physical_address);
+ return ret;
+}
+
+
static ssize_t hdmi_common_rda_edid_scan_info(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -328,7 +340,6 @@
external_common_state->it_scan_info,
external_common_state->ce_scan_info);
DEV_DBG("%s: '%s'\n", __func__, buf);
-
return ret;
}
@@ -696,6 +707,8 @@
static DEVICE_ATTR(hpd, S_IRUGO | S_IWUGO, hdmi_common_rda_hpd,
hdmi_common_wta_hpd);
static DEVICE_ATTR(hdcp, S_IRUGO, hdmi_common_rda_hdcp, NULL);
+static DEVICE_ATTR(pa, S_IRUGO,
+ hdmi_common_rda_edid_physical_address, NULL);
static DEVICE_ATTR(scan_info, S_IRUGO,
hdmi_common_rda_edid_scan_info, NULL);
static DEVICE_ATTR(3d_present, S_IRUGO, hdmi_common_rda_3d_present, NULL);
@@ -716,6 +729,7 @@
&dev_attr_edid_modes.attr,
&dev_attr_hdcp.attr,
&dev_attr_hpd.attr,
+ &dev_attr_pa.attr,
&dev_attr_scan_info.attr,
&dev_attr_3d_present.attr,
&dev_attr_hdcp_present.attr,
@@ -996,7 +1010,9 @@
return 0;
DEV_DBG("EDID: VSD PhyAddr=%04x, MaxTMDS=%dMHz\n",
- ((uint32)vsd[6] << 8) + (uint32)vsd[5], (uint32)vsd[7] * 5);
+ ((uint32)vsd[4] << 8) + (uint32)vsd[5], (uint32)vsd[7] * 5);
+ external_common_state->physical_address =
+ ((uint16)vsd[4] << 8) + (uint16)vsd[5];
return ((uint32)vsd[3] << 16) + ((uint32)vsd[2] << 8) + (uint32)vsd[1];
}
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index c6dfeb1..b8d2e5f 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -216,6 +216,7 @@
uint8 speaker_allocation_block;
uint16 video_latency, audio_latency;
uint8 audio_data_block_cnt;
+ uint16 physical_address;
uint32 preferred_video_format;
uint8 pt_scan_info;
uint8 it_scan_info;
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 30ce90b..918f8f2 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4457,11 +4457,10 @@
queue_work(hdmi_work_queue, &hdmi_msm_state->hpd_read_work);
/* Initialize hdmi node and register with switch driver */
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- external_common_state->sdev.name = "hdmi_as_primary";
-#else
- external_common_state->sdev.name = "hdmi";
-#endif
+ if (hdmi_prim_display)
+ external_common_state->sdev.name = "hdmi_as_primary";
+ else
+ external_common_state->sdev.name = "hdmi";
if (switch_dev_register(&external_common_state->sdev) < 0)
DEV_ERR("Hdmi switch registration failed\n");
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 9b8f60f..1f5904b 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -592,7 +592,7 @@
};
static uint32 vg_qseed_table1[] = {
- 0x76543210, 0xfedcba98
+ 0x00000000, 0x20000000,
};
static uint32 vg_qseed_table2[] = {
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index 199e472..a6f03ba 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -1417,7 +1417,7 @@
iBuf.mdpImg.mdpOp |= MDPOP_DITHER;
if (req->flags & MDP_BLEND_FG_PREMULT) {
-#ifdef CONFIG_FB_MSM_MDP31
+#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP303)
iBuf.mdpImg.mdpOp |= MDPOP_FG_PM_ALPHA;
#else
put_img(p_src_file);
diff --git a/drivers/video/msm/mdp_ppp_v20.c b/drivers/video/msm/mdp_ppp_v20.c
index fd04009..fe237ee 100644
--- a/drivers/video/msm/mdp_ppp_v20.c
+++ b/drivers/video/msm/mdp_ppp_v20.c
@@ -2429,37 +2429,102 @@
uint32 *tpVal,
uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
{
- if (perPixelAlpha) {
- *pppop_reg_ptr |= PPP_OP_ROT_ON |
- PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
+ if (mdp_rev == MDP_REV_303) {
+ int bg_alpha;
+
+ *alpha = iBuf->mdpImg.alpha;
+ *tpVal = iBuf->mdpImg.tpVal;
+
+ if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) {
+ if (perPixelAlpha) {
+ *pppop_reg_ptr |= PPP_OP_ROT_ON |
+ PPP_OP_BLEND_ON |
+ PPP_OP_BLEND_CONSTANT_ALPHA;
+ } else {
+ if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+ && (iBuf->mdpImg.alpha == 0xff)) {
+ iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
+ }
+
+ if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+ || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
+
+ *pppop_reg_ptr |= PPP_OP_ROT_ON |
+ PPP_OP_BLEND_ON |
+ PPP_OP_BLEND_CONSTANT_ALPHA |
+ PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
+ }
+ }
+
+ bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
+ PPP_BLEND_BG_ALPHA_REVERSE;
+
+ if (perPixelAlpha) {
+ bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
+ } else {
+ bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
+ bg_alpha |= iBuf->mdpImg.alpha << 24;
+ }
+ outpdw(MDP_BASE + 0x70010, bg_alpha);
+
+ if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
+ *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
+ } else if (perPixelAlpha) {
+ *pppop_reg_ptr |= PPP_OP_ROT_ON |
+ PPP_OP_BLEND_ON |
+ PPP_OP_BLEND_SRCPIXEL_ALPHA;
+ } else {
+ if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+ && (iBuf->mdpImg.alpha == 0xff)) {
+ iBuf->mdpImg.mdpOp &=
+ ~(MDPOP_ALPHAB);
+ }
+
+ if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+ || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
+ *pppop_reg_ptr |= PPP_OP_ROT_ON |
+ PPP_OP_BLEND_ON |
+ PPP_OP_BLEND_CONSTANT_ALPHA |
+ PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
+ }
+
+ if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
+ *pppop_reg_ptr |=
+ PPP_BLEND_CALPHA_TRNASP;
+ }
} else {
- if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
- && (iBuf->mdpImg.alpha == 0xff)) {
- iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
- }
-
- if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
- && (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
- *pppop_reg_ptr |=
- PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
- PPP_OP_BLEND_CONSTANT_ALPHA |
- PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
- PPP_BLEND_CALPHA_TRNASP;
-
- *alpha = iBuf->mdpImg.alpha;
- *tpVal = iBuf->mdpImg.tpVal;
+ if (perPixelAlpha) {
+ *pppop_reg_ptr |= PPP_OP_ROT_ON |
+ PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
} else {
- if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) {
- *pppop_reg_ptr |= PPP_OP_ROT_ON |
- PPP_OP_BLEND_ON |
- PPP_OP_BLEND_SRCPIXEL_TRANSP;
- *tpVal = iBuf->mdpImg.tpVal;
- } else if (iBuf->mdpImg.mdpOp & MDPOP_ALPHAB) {
- *pppop_reg_ptr |= PPP_OP_ROT_ON |
- PPP_OP_BLEND_ON |
+ if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+ && (iBuf->mdpImg.alpha == 0xff)) {
+ iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
+ }
+
+ if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+ && (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
+ *pppop_reg_ptr |=
+ PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
+ PPP_OP_BLEND_CONSTANT_ALPHA |
PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
- PPP_OP_BLEND_CONSTANT_ALPHA;
+ PPP_BLEND_CALPHA_TRNASP;
+
*alpha = iBuf->mdpImg.alpha;
+ *tpVal = iBuf->mdpImg.tpVal;
+ } else {
+ if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) {
+ *pppop_reg_ptr |= PPP_OP_ROT_ON |
+ PPP_OP_BLEND_ON |
+ PPP_OP_BLEND_SRCPIXEL_TRANSP;
+ *tpVal = iBuf->mdpImg.tpVal;
+ } else if (iBuf->mdpImg.mdpOp & MDPOP_ALPHAB) {
+ *pppop_reg_ptr |= PPP_OP_ROT_ON |
+ PPP_OP_BLEND_ON |
+ PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
+ PPP_OP_BLEND_CONSTANT_ALPHA;
+ *alpha = iBuf->mdpImg.alpha;
+ }
}
}
}
diff --git a/drivers/video/msm/mipi_novatek.c b/drivers/video/msm/mipi_novatek.c
index ed0dee4..0070757 100644
--- a/drivers/video/msm/mipi_novatek.c
+++ b/drivers/video/msm/mipi_novatek.c
@@ -14,6 +14,7 @@
#ifdef CONFIG_SPI_QUP
#include <linux/spi/spi.h>
#endif
+#include <linux/leds.h>
#include "msm_fb.h"
#include "mipi_dsi.h"
#include "mipi_novatek.h"
@@ -26,6 +27,8 @@
static struct dsi_buf novatek_rx_buf;
static int mipi_novatek_lcd_init(void);
+static int wled_trigger_initialized;
+
#define MIPI_DSI_NOVATEK_SPI_DEVICE_NAME "dsi_novatek_3d_panel_spi"
#define HPCI_FPGA_READ_CMD 0x84
#define HPCI_FPGA_WRITE_CMD 0x04
@@ -427,12 +430,17 @@
return 0;
}
-
+DEFINE_LED_TRIGGER(bkl_led_trigger);
static void mipi_novatek_set_backlight(struct msm_fb_data_type *mfd)
{
struct mipi_panel_info *mipi;
+ if ((mipi_novatek_pdata->enable_wled_bl_ctrl)
+ && (wled_trigger_initialized)) {
+ led_trigger_event(bkl_led_trigger, mfd->bl_level);
+ return;
+ }
mipi = &mfd->panel_info.mipi;
mutex_lock(&mfd->dma->ov_mutex);
@@ -639,6 +647,10 @@
pr_info("%s: SUCCESS (SPI)\n", __func__);
#endif
+ led_trigger_register_simple("bkl_trigger", &bkl_led_trigger);
+ pr_info("%s: SUCCESS (WLED TRIGGER)\n", __func__);
+ wled_trigger_initialized = 1;
+
mipi_dsi_buf_alloc(&novatek_tx_buf, DSI_BUF_SIZE);
mipi_dsi_buf_alloc(&novatek_rx_buf, DSI_BUF_SIZE);
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 91dc16c..6ec5d70 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -1239,6 +1239,8 @@
snprintf(fix->id, sizeof(fix->id), "msmfb31_%x", (__u32) *id);
#elif defined(CONFIG_FB_MSM_MDP40)
snprintf(fix->id, sizeof(fix->id), "msmfb40_%x", (__u32) *id);
+#elif defined(CONFIG_FB_MSM_MDP_NONE)
+ snprintf(fix->id, sizeof(fix->id), "msmfb0_%x", (__u32) *id);
#else
error CONFIG_FB_MSM_MDP undefined !
#endif
diff --git a/include/linux/mfd/pm8xxx/core.h b/include/linux/mfd/pm8xxx/core.h
index e7bf820..b907219 100644
--- a/include/linux/mfd/pm8xxx/core.h
+++ b/include/linux/mfd/pm8xxx/core.h
@@ -42,6 +42,8 @@
#define PM8XXX_REVISION_8901_1p1 2
#define PM8XXX_REVISION_8901_2p0 3
#define PM8XXX_REVISION_8901_2p1 4
+#define PM8XXX_REVISION_8901_2p2 5
+#define PM8XXX_REVISION_8901_2p3 6
#define PM8XXX_REVISION_8921_TEST 0
#define PM8XXX_REVISION_8921_1p0 1
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index c90d8d1..77683ce 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -79,7 +79,7 @@
};
enum pm8xxx_aux_clk_div {
- X0_DIV_NONE,
+ XO_DIV_NONE,
XO_DIV_1,
XO_DIV_2,
XO_DIV_4,
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 818eeca..d4aaa4b 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -20,8 +20,8 @@
#define FCC_CC_COLS 5
#define FCC_TEMP_COLS 8
-#define PC_CC_ROWS 10
-#define PC_CC_COLS 5
+#define PC_CC_ROWS 29
+#define PC_CC_COLS 13
#define PC_TEMP_ROWS 29
#define PC_TEMP_COLS 8
@@ -35,19 +35,20 @@
};
/**
- * struct pc_sf_lut -
+ * struct sf_lut -
* @rows: number of percent charge entries should be <= PC_CC_ROWS
* @cols: number of charge cycle entries should be <= PC_CC_COLS
- * @cycles: the charge cycles at which sf data is available in the table.
+ * @row_entries: the charge cycles/temperature at which sf data
+ * is available in the table.
* The charge cycles must be in increasing order from 0 to rows.
* @percent: the percent charge at which sf data is available in the table
* The percentcharge must be in decreasing order from 0 to cols.
* @sf: the scaling factor data
*/
-struct pc_sf_lut {
+struct sf_lut {
int rows;
int cols;
- int cycles[PC_CC_COLS];
+ int row_entries[PC_CC_COLS];
int percent[PC_CC_ROWS];
int sf[PC_CC_ROWS][PC_CC_COLS];
};
@@ -74,17 +75,22 @@
* struct pm8921_bms_battery_data -
* @fcc: full charge capacity (mAmpHour)
* @fcc_temp_lut: table to get fcc at a given temp
- * @fcc_sf_lut: table to get fcc scaling factor for given charge cycles
* @pc_temp_ocv_lut: table to get percent charge given batt temp and cycles
* @pc_sf_lut: table to get percent charge scaling factor given cycles
* and percent charge
+ * @rbatt_sf_lut: table to get battery resistance scaling factor given
+ * temperature and percent charge
+ * default_rbatt_mohm: the default value of battery resistance to use when
+ * readings from bms are not available.
*/
struct pm8921_bms_battery_data {
- unsigned int fcc;
- struct single_row_lut *fcc_temp_lut;
- struct single_row_lut *fcc_sf_lut;
- struct pc_temp_ocv_lut *pc_temp_ocv_lut;
- struct pc_sf_lut *pc_sf_lut;
+ unsigned int fcc;
+ struct single_row_lut *fcc_temp_lut;
+ struct single_row_lut *fcc_sf_lut;
+ struct pc_temp_ocv_lut *pc_temp_ocv_lut;
+ struct sf_lut *pc_sf_lut;
+ struct sf_lut *rbatt_sf_lut;
+ int default_rbatt_mohm;
};
struct pm8xxx_bms_core_data {
@@ -185,6 +191,10 @@
*/
int pm8921_bms_get_simultaneous_battery_voltage_and_current(int *ibat_ua,
int *vbat_uv);
+/**
+ * pm8921_bms_get_rbatt - function to get the battery resistance in mOhm.
+ */
+int pm8921_bms_get_rbatt(void);
#else
static inline int pm8921_bms_get_vsense_avg(int *result)
{
@@ -216,6 +226,10 @@
{
return -ENXIO;
}
+static inline int pm8921_bms_get_rbatt(void)
+{
+ return -EINVAL;
+}
#endif
#endif
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 0e62644..22c3772 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -170,6 +170,7 @@
struct msm_bus_scale_pdata *bus_scale_table;
struct kgsl_device_iommu_data *iommu_data;
int iommu_count;
+ struct msm_dcvs_core_info *core_info;
};
#endif
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4c86f24..d98a79d 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -586,10 +586,7 @@
}
int hci_chan_put(struct hci_chan *chan);
-struct hci_chan *hci_chan_accept(struct hci_conn *hcon,
- struct hci_ext_fs *tx_fs,
- struct hci_ext_fs *rx_fs);
-struct hci_chan *hci_chan_create(struct hci_conn *hcon,
+struct hci_chan *hci_chan_create(struct hci_chan *chan,
struct hci_ext_fs *tx_fs,
struct hci_ext_fs *rx_fs);
void hci_chan_modify(struct hci_chan *chan,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 2854395..f87be20 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -520,6 +520,7 @@
return chan;
}
+EXPORT_SYMBOL(hci_chan_add);
int hci_chan_del(struct hci_chan *chan)
{
@@ -1001,18 +1002,12 @@
}
}
-struct hci_chan *hci_chan_accept(struct hci_conn *conn,
+struct hci_chan *hci_chan_create(struct hci_chan *chan,
struct hci_ext_fs *tx_fs, struct hci_ext_fs *rx_fs)
{
- struct hci_chan *chan;
struct hci_cp_create_logical_link cp;
- chan = hci_chan_add(conn->hdev);
- if (!chan)
- return NULL;
-
chan->state = BT_CONNECT;
- chan->conn = conn;
chan->tx_fs = *tx_fs;
chan->rx_fs = *rx_fs;
cp.phy_handle = chan->conn->handle;
@@ -1029,40 +1024,12 @@
cp.rx_fs.acc_latency = cpu_to_le32(chan->rx_fs.acc_latency);
cp.rx_fs.flush_to = cpu_to_le32(chan->rx_fs.flush_to);
hci_conn_hold(chan->conn);
- hci_send_cmd(conn->hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp), &cp);
- return chan;
-}
-EXPORT_SYMBOL(hci_chan_accept);
-
-struct hci_chan *hci_chan_create(struct hci_conn *conn,
- struct hci_ext_fs *tx_fs, struct hci_ext_fs *rx_fs)
-{
- struct hci_chan *chan;
- struct hci_cp_create_logical_link cp;
-
- chan = hci_chan_add(conn->hdev);
- if (!chan)
- return NULL;
-
- chan->state = BT_CONNECT;
- chan->conn = conn;
- chan->tx_fs = *tx_fs;
- chan->rx_fs = *rx_fs;
- cp.phy_handle = chan->conn->handle;
- cp.tx_fs.id = chan->tx_fs.id;
- cp.tx_fs.type = chan->tx_fs.type;
- cp.tx_fs.max_sdu = cpu_to_le16(chan->tx_fs.max_sdu);
- cp.tx_fs.sdu_arr_time = cpu_to_le32(chan->tx_fs.sdu_arr_time);
- cp.tx_fs.acc_latency = cpu_to_le32(chan->tx_fs.acc_latency);
- cp.tx_fs.flush_to = cpu_to_le32(chan->tx_fs.flush_to);
- cp.rx_fs.id = chan->rx_fs.id;
- cp.rx_fs.type = chan->rx_fs.type;
- cp.rx_fs.max_sdu = cpu_to_le16(chan->rx_fs.max_sdu);
- cp.rx_fs.sdu_arr_time = cpu_to_le32(chan->rx_fs.sdu_arr_time);
- cp.rx_fs.acc_latency = cpu_to_le32(chan->rx_fs.acc_latency);
- cp.rx_fs.flush_to = cpu_to_le32(chan->rx_fs.flush_to);
- hci_conn_hold(chan->conn);
- hci_send_cmd(conn->hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp), &cp);
+ if (chan->conn->out)
+ hci_send_cmd(chan->conn->hdev, HCI_OP_CREATE_LOGICAL_LINK,
+ sizeof(cp), &cp);
+ else
+ hci_send_cmd(chan->conn->hdev, HCI_OP_ACCEPT_LOGICAL_LINK,
+ sizeof(cp), &cp);
return chan;
}
EXPORT_SYMBOL(hci_chan_create);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 47b6d4d..de3ab22 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3186,8 +3186,9 @@
return 1;
}
-static struct hci_chan *l2cap_chan_admit(u8 amp_id, struct l2cap_pinfo *pi)
+static struct hci_chan *l2cap_chan_admit(u8 amp_id, struct sock *sk)
{
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
struct hci_dev *hdev;
struct hci_conn *hcon;
struct hci_chan *chan;
@@ -3207,19 +3208,23 @@
chan = hci_chan_list_lookup_id(hdev, hcon->handle);
if (chan) {
l2cap_aggregate(chan, pi);
+ sock_hold(sk);
+ chan->l2cap_sk = sk;
+ hci_chan_hold(chan);
+ pi->ampchan = chan;
goto done;
}
- if (bt_sk(pi)->parent) {
- /* Incoming connection */
- chan = hci_chan_accept(hcon,
- (struct hci_ext_fs *) &pi->local_fs,
- (struct hci_ext_fs *) &pi->remote_fs);
- } else {
- /* Outgoing connection */
- chan = hci_chan_create(hcon,
- (struct hci_ext_fs *) &pi->local_fs,
- (struct hci_ext_fs *) &pi->remote_fs);
+ chan = hci_chan_add(hdev);
+ if (chan) {
+ chan->conn = hcon;
+ sock_hold(sk);
+ chan->l2cap_sk = sk;
+ hci_chan_hold(chan);
+ pi->ampchan = chan;
+ hci_chan_create(chan,
+ (struct hci_ext_fs *) &pi->local_fs,
+ (struct hci_ext_fs *) &pi->remote_fs);
}
done:
hci_dev_put(hdev);
@@ -3625,14 +3630,10 @@
struct hci_chan *chan;
/* Trigger logical link creation only on AMP */
- chan = l2cap_chan_admit(pi->amp_id, pi);
+ chan = l2cap_chan_admit(pi->amp_id, sk);
if (!chan)
return -ECONNREFUSED;
- hci_chan_hold(chan);
- pi->ampchan = chan;
- chan->l2cap_sk = sk;
-
if (chan->state == BT_CONNECTED)
l2cap_create_cfm(chan, 0);
}
@@ -4466,17 +4467,13 @@
/* Already sent a 'pending' response, so set up
* the logical link now
*/
- chan = l2cap_chan_admit(pi->amp_id, pi);
+ chan = l2cap_chan_admit(pi->amp_id, sk);
if (!chan) {
l2cap_send_disconn_req(pi->conn, sk,
ECONNRESET);
goto done;
}
- hci_chan_hold(chan);
- pi->ampchan = chan;
- chan->l2cap_sk = sk;
-
if (chan->state == BT_CONNECTED)
l2cap_create_cfm(chan, 0);
}
@@ -5004,7 +5001,7 @@
}
pi->remote_fs = default_fs;
pi->local_fs = default_fs;
- chan = l2cap_chan_admit(pi->amp_move_id, pi);
+ chan = l2cap_chan_admit(pi->amp_move_id, sk);
if (!chan) {
/* Logical link not available */
l2cap_send_move_chan_cfm(conn, pi, pi->scid,
@@ -5012,10 +5009,6 @@
break;
}
- hci_chan_hold(chan);
- pi->ampchan = chan;
- chan->l2cap_sk = sk;
-
if (chan->state == BT_CONNECTED) {
/* Logical link is already ready to go */
pi->ampcon = chan->conn;
@@ -5323,12 +5316,8 @@
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
pi->remote_fs = default_fs;
pi->local_fs = default_fs;
- chan = l2cap_chan_admit(local_id, pi);
+ chan = l2cap_chan_admit(local_id, sk);
if (chan) {
- hci_chan_hold(chan);
- pi->ampchan = chan;
- chan->l2cap_sk = sk;
-
if (chan->state == BT_CONNECTED) {
/* Logical link is ready to go */
pi->ampcon = chan->conn;
@@ -5546,9 +5535,7 @@
{
struct l2cap_logical_link_work *amp_work;
- if (chan->l2cap_sk) {
- sock_hold(chan->l2cap_sk);
- } else {
+ if (!chan->l2cap_sk) {
BT_ERR("Expected l2cap_sk to point to connecting socket");
return -EFAULT;
}
diff --git a/sound/soc/msm/msm-pcm-q6.c b/sound/soc/msm/msm-pcm-q6.c
index ed880e8..dd194d6 100644
--- a/sound/soc/msm/msm-pcm-q6.c
+++ b/sound/soc/msm/msm-pcm-q6.c
@@ -638,6 +638,8 @@
return -ENOMEM;
}
buf = prtd->audio_client->port[dir].buf;
+ if (buf == NULL || buf[0].data == NULL)
+ return -ENOMEM;
pr_debug("%s:buf = %p\n", __func__, buf);
dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;