Merge "msm_fb: lvds: Fix uninitialized variable warnings" into msm-3.0
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 064b787..c186be4 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -93,6 +93,7 @@
CONFIG_MSM_L1_ERR_PANIC=y
CONFIG_MSM_L2_ERP_1BIT_PANIC=y
CONFIG_MSM_L2_ERP_2BIT_PANIC=y
+CONFIG_MSM_CACHE_DUMP=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 5bb5139..5668e75 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -50,8 +50,11 @@
void gic_enable_ppi(unsigned int);
bool gic_is_spi_pending(unsigned int irq);
void gic_clear_spi_pending(unsigned int irq);
+#ifdef CONFIG_ARM_GIC
void gic_set_irq_secure(unsigned int irq);
-
+#else
+static inline void gic_set_irq_secure(unsigned int irq) { }
+#endif
static inline void gic_init(unsigned int nr, int start,
void __iomem *dist , void __iomem *cpu)
{
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 3c2d47a..ad4f12a 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -265,6 +265,7 @@
select MSM_XO
select MSM_QDSP6_APR
select MSM_AUDIO_QDSP6 if SND_SOC
+ select FIQ
config ARCH_MSM8625
bool "MSM8625"
@@ -2221,4 +2222,12 @@
config HAVE_ARCH_HAS_CURRENT_TIMER
bool
+
+config MSM_CACHE_DUMP
+ bool "Cache dumping support"
+ help
+ Add infrastructure to dump the L1 and L2 caches to an allocated buffer.
+ This allows for analysis of the caches in case cache corruption is
+ suspected.
+
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index c7943f4..0f438e1 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -204,6 +204,7 @@
obj-$(CONFIG_ARCH_FSM9XXX) += restart-fsm9xxx.o xo-fsm9xxx.o
obj-$(CONFIG_MSM_WATCHDOG) += msm_watchdog.o
+obj-$(CONFIG_MSM_WATCHDOG) += msm_watchdog_asm.o
obj-$(CONFIG_MACH_MSM8X60_RUMI3) += board-msm8x60.o
obj-$(CONFIG_MACH_MSM8X60_SIM) += board-msm8x60.o
obj-$(CONFIG_MACH_MSM8X60_SURF) += board-msm8x60.o
@@ -332,3 +333,4 @@
obj-$(CONFIG_ARCH_MSM8960) += mdm2.o mdm_common.o
obj-$(CONFIG_MSM_RTB) += msm_rtb.o
obj-$(CONFIG_MSM_CACHE_ERP) += cache_erp.o
+obj-$(CONFIG_MSM_CACHE_DUMP) += msm_cache_dump.o
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 433fb2e..6949b62 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -46,7 +46,16 @@
#define MSM_FB_EXT_BUF_SIZE 0
#endif
-#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE, 4096)
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+#define MSM_FB_WFD_BUF_SIZE \
+ (roundup((1280 * 736 * 2), 4096) * 1) /* 2 bpp x 1 page */
+#else
+#define MSM_FB_WFD_BUF_SIZE 0
+#endif
+
+#define MSM_FB_SIZE \
+ roundup(MSM_FB_PRIM_BUF_SIZE + \
+ MSM_FB_EXT_BUF_SIZE + MSM_FB_WFD_BUF_SIZE, 4096)
#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
#define MSM_FB_OVERLAY0_WRITEBACK_SIZE roundup((1376 * 768 * 3 * 2), 4096)
@@ -297,6 +306,19 @@
.dev.platform_data = &hdmi_msm_data,
};
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+static struct platform_device wfd_panel_device = {
+ .name = "wfd_panel",
+ .id = 0,
+ .dev.platform_data = NULL,
+};
+
+static struct platform_device wfd_device = {
+ .name = "msm_wfd",
+ .id = -1,
+};
+#endif
+
/* HDMI related GPIOs */
#define HDMI_CEC_VAR_GPIO 69
#define HDMI_DDC_CLK_GPIO 70
@@ -897,6 +919,11 @@
platform_device_register(&msm_fb_device);
platform_device_register(&lvds_chimei_panel_device);
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+ platform_device_register(&wfd_panel_device);
+ platform_device_register(&wfd_device);
+#endif
+
if (machine_is_apq8064_liquid())
platform_device_register(&mipi_dsi2lvds_bridge_device);
if (machine_is_apq8064_mtp())
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 8212808..93cfc099 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -686,8 +686,6 @@
epm_adc_pdata.chan_per_mux = 8;
};
-#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_IRQS)
-
/* Micbias setting is based on 8660 CDP/MTP/FLUID requirement
* 4 micbiases are used to power various analog and digital
* microphones operating at 1800 mV. Technically, all micbiases
@@ -1870,6 +1868,11 @@
&apq8064_msm_gov_device,
&apq8064_device_cache_erp,
&epm_adc_device,
+ &apq8064_qdss_device,
+ &msm_etb_device,
+ &msm_tpiu_device,
+ &msm_funnel_device,
+ &apq8064_etm_device,
};
static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 938d2ea..115929c 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -31,6 +31,8 @@
#define PM8821_MPP_PM_TO_SYS(pm_mpp) (pm_mpp - 1 + PM8821_MPP_BASE)
#define PM8821_IRQ_BASE (PM8921_IRQ_BASE + PM8921_NR_IRQS)
+#define TABLA_INTERRUPT_BASE (PM8821_IRQ_BASE + PM8821_NR_IRQS)
+
extern struct pm8xxx_regulator_platform_data
msm8064_pm8921_regulator_pdata[] __devinitdata;
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index dc6c135..864d7b6 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1693,6 +1693,7 @@
&msm_device_tz_log,
#ifdef CONFIG_MSM_QDSS
+ &msm_qdss_device,
&msm_etb_device,
&msm_tpiu_device,
&msm_funnel_device,
@@ -1995,7 +1996,7 @@
ARRAY_SIZE(msm_isa1200_board_info),
},
{
- I2C_SURF,
+ I2C_SURF | I2C_FFA | I2C_FLUID,
MSM_8930_GSBI3_QUP_I2C_BUS_ID,
mxt_device_info_8930,
ARRAY_SIZE(mxt_device_info_8930),
@@ -2098,8 +2099,7 @@
msm8930_init_cam();
msm8930_init_mmc();
acpuclk_init(&acpuclk_8930_soc_data);
- if (machine_is_msm8930_cdp() || machine_is_msm8627_cdp())
- mxt_init_vkeys_8930();
+ mxt_init_vkeys_8930();
register_i2c_devices();
msm8930_init_fb();
slim_register_board_info(msm_slim_devices,
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 4ef7d6e..724dd80 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -79,6 +79,8 @@
#include <mach/mdm2.h>
#include <mach/mdm-peripheral.h>
#include <mach/msm_rtb.h>
+#include <mach/msm_cache_dump.h>
+#include <mach/scm.h>
#include <linux/fmem.h>
@@ -590,6 +592,43 @@
msm8960_mdp_writeback(msm8960_reserve_table);
}
+#if defined(CONFIG_MSM_CACHE_DUMP)
+static struct msm_cache_dump_platform_data msm_cache_dump_pdata = {
+ .l2_size = L2_BUFFER_SIZE,
+};
+
+static struct platform_device msm_cache_dump_device = {
+ .name = "msm_cache_dump",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm_cache_dump_pdata,
+ },
+};
+
+#endif
+
+static void reserve_cache_dump_memory(void)
+{
+#ifdef CONFIG_MSM_CACHE_DUMP
+ unsigned int spare;
+ unsigned int l1_size;
+ unsigned int total;
+ int ret;
+
+ ret = scm_call(L1C_SERVICE_ID, L1C_BUFFER_GET_SIZE_COMMAND_ID, &spare,
+ sizeof(spare), &l1_size, sizeof(l1_size));
+
+ if (ret)
+ /* Fall back to something reasonable here */
+ l1_size = L1_BUFFER_SIZE;
+
+ total = l1_size + L2_BUFFER_SIZE;
+
+ msm8960_reserve_table[MEMTYPE_EBI1].size += total;
+ msm_cache_dump_pdata.l1_size = l1_size;
+#endif
+}
+
static void __init msm8960_calculate_reserve_sizes(void)
{
size_pmem_devices();
@@ -597,6 +636,7 @@
reserve_ion_memory();
reserve_mdp_memory();
reserve_rtb_memory();
+ reserve_cache_dump_memory();
}
static struct reserve_info msm8960_reserve_info __initdata = {
@@ -2201,6 +2241,7 @@
&msm8960_rpm_stat_device,
&msm_device_tz_log,
#ifdef CONFIG_MSM_QDSS
+ &msm_qdss_device,
&msm_etb_device,
&msm_tpiu_device,
&msm_funnel_device,
@@ -2214,6 +2255,9 @@
&msm8960_cpu_idle_device,
&msm8960_msm_gov_device,
&msm8960_device_cache_erp,
+#ifdef CONFIG_MSM_CACHE_DUMP
+ &msm_cache_dump_device,
+#endif
};
static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index fcbf2a6..81abbc0 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -20,6 +20,7 @@
#include <asm/gpio.h>
#include <asm/mach-types.h>
#include <mach/rpc_pmapp.h>
+#include <mach/socinfo.h>
#include "board-msm7627a.h"
#include "devices-msm7x2xa.h"
@@ -98,12 +99,19 @@
int gpio_bt_sys_rest_en = 133;
static void gpio_bt_config(void)
{
+ u32 socinfo = socinfo_get_platform_version();
if (machine_is_msm7627a_qrd1())
gpio_bt_sys_rest_en = 114;
if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
gpio_bt_sys_rest_en = 16;
if (machine_is_msm8625_qrd7())
gpio_bt_sys_rest_en = 88;
+ if (machine_is_msm7627a_qrd3()) {
+ if (socinfo == 0x70002)
+ gpio_bt_sys_rest_en = 88;
+ else
+ gpio_bt_sys_rest_en = 85;
+ }
}
static int bt_set_gpio(int on)
@@ -962,8 +970,6 @@
int i, rc = 0;
struct device *dev;
- if (machine_is_msm7627a_qrd3())
- return;
gpio_bt_config();
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index e4ee52e..564c59d 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -151,7 +151,9 @@
static void gpio_sdc1_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_sdc1_hw_det = 42;
}
@@ -253,7 +255,9 @@
if (!status) {
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())
status = !gpio_get_value(gpio_sdc1_hw_det);
else
status = gpio_get_value(gpio_sdc1_hw_det);
@@ -367,11 +371,15 @@
{
/* eMMC slot */
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
- if (mmc_regulator_init(3, "emmc", 3000000))
- return;
- sdc3_plat_data.swfi_latency = msm7627a_power_collapse_latency(
+
+ /* There is no eMMC on SDC3 for QRD3 based devices */
+ if (!(machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())) {
+ if (mmc_regulator_init(3, "emmc", 3000000))
+ return;
+ sdc3_plat_data.swfi_latency = msm7627a_power_collapse_latency(
MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT);
- msm_add_sdcc(3, &sdc3_plat_data);
+ msm_add_sdcc(3, &sdc3_plat_data);
+ }
#endif
/* Micro-SD slot */
#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
@@ -392,9 +400,12 @@
/* Not Used */
#if (defined(CONFIG_MMC_MSM_SDC4_SUPPORT)\
&& !defined(CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT))
- if (mmc_regulator_init(4, "smps3", 1800000))
- return;
- msm_add_sdcc(4, &sdc4_plat_data);
+ /* There is no SDC4 for QRD3/7 based devices */
+ if (!(machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())) {
+ if (mmc_regulator_init(4, "smps3", 1800000))
+ return;
+ msm_add_sdcc(4, &sdc4_plat_data);
+ }
#endif
}
#endif
diff --git a/arch/arm/mach-msm/board-msm7627a.h b/arch/arm/mach-msm/board-msm7627a.h
index 48848d5..e3c9469 100644
--- a/arch/arm/mach-msm/board-msm7627a.h
+++ b/arch/arm/mach-msm/board-msm7627a.h
@@ -22,7 +22,7 @@
void __init msm_fb_add_devices(void);
#define PMEM_KERNEL_EBI1_SIZE 0x3A000
-#define MSM_PMEM_AUDIO_SIZE 0x5B000
+#define MSM_PMEM_AUDIO_SIZE 0x1F4000
#define MSM_PMEM_MDP_SIZE 0x2300000
#define MSM_PMEM_ADSP_SIZE 0x1100000
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 3387440..947c639 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2686,9 +2686,9 @@
#define MSM_FB_OVERLAY1_WRITEBACK_SIZE (0)
#endif /* CONFIG_FB_MSM_OVERLAY1_WRITEBACK */
-#define MSM_PMEM_KERNEL_EBI1_SIZE 0x600000
+#define MSM_PMEM_KERNEL_EBI1_SIZE 0x3BC000
#define MSM_PMEM_ADSP_SIZE 0x2000000
-#define MSM_PMEM_AUDIO_SIZE 0x28B000
+#define MSM_PMEM_AUDIO_SIZE 0x4CF000
#define MSM_SMI_BASE 0x38000000
#define MSM_SMI_SIZE 0x4000000
@@ -2712,9 +2712,9 @@
#endif
#define MSM_ION_QSECOM_SIZE 0x600000 /* (6MB) */
-#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
#define MSM_ION_HEAP_NUM 9
#define MSM_HDMI_PRIM_ION_SF_SIZE MSM_HDMI_PRIM_PMEM_SF_SIZE
static unsigned msm_ion_sf_size = MSM_ION_SF_SIZE;
@@ -5477,6 +5477,7 @@
msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_CAMERA_SIZE;
msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_WB_SIZE;
msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
+ msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
#endif
}
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 0b7b7de..44ba518 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -507,10 +507,8 @@
static void __init msm_pm_init(void)
{
- if (machine_is_msm8625_qrd7())
- return;
- if (!machine_is_msm8625_evb()) {
+ if (!cpu_is_msm8625()) {
msm_pm_set_platform_data(msm7627a_pm_data,
ARRAY_SIZE(msm7627a_pm_data));
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 67d5618..044bd79 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5479,7 +5479,7 @@
};
static struct clk_lookup msm_clocks_8930[] = {
- CLK_LOOKUP("xo", cxo_clk.c, "msm_otg"),
+ CLK_LOOKUP("xo", cxo_clk.c, "msm_xo"),
CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
CLK_LOOKUP("cxo", cxo_clk.c, "pil_riva"),
CLK_LOOKUP("xo", pxo_clk.c, "pil_qdsp6v4.0"),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 3965413..7c2fca4 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -31,6 +31,7 @@
#include <mach/mdm2.h>
#include <mach/msm_smd.h>
#include <mach/msm_dcvs.h>
+#include <mach/qdss.h>
#include <linux/ion.h>
#include "clock.h"
#include "devices.h"
@@ -2210,3 +2211,42 @@
.num_resources = ARRAY_SIZE(msm_cache_erp_resources),
.resource = msm_cache_erp_resources,
};
+
+#define MSM_QDSS_PHYS_BASE 0x01A00000
+#define MSM_ETM_PHYS_BASE (MSM_QDSS_PHYS_BASE + 0x1C000)
+
+#define QDSS_SOURCE(src_name, fpm) { .name = src_name, .fport_mask = fpm, }
+
+static struct qdss_source msm_qdss_sources[] = {
+ QDSS_SOURCE("msm_etm", 0x33),
+ QDSS_SOURCE("msm_oxili", 0x80),
+};
+
+static struct msm_qdss_platform_data qdss_pdata = {
+ .src_table = msm_qdss_sources,
+ .size = ARRAY_SIZE(msm_qdss_sources),
+ .afamily = 1,
+};
+
+struct platform_device apq8064_qdss_device = {
+ .name = "msm_qdss",
+ .id = -1,
+ .dev = {
+ .platform_data = &qdss_pdata,
+ },
+};
+
+static struct resource msm_etm_resources[] = {
+ {
+ .start = MSM_ETM_PHYS_BASE,
+ .end = MSM_ETM_PHYS_BASE + (SZ_4K * 4) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device apq8064_etm_device = {
+ .name = "msm_etm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(msm_etm_resources),
+ .resource = msm_etm_resources,
+};
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index b03f137..0ab81a4 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -34,6 +34,7 @@
#include <sound/msm-dai-q6.h>
#include <sound/apr_audio.h>
#include <mach/msm_tsif.h>
+#include <mach/qdss.h>
#include "clock.h"
#include "devices.h"
#include "devices-msm8x60.h"
@@ -3167,6 +3168,26 @@
#define MSM_FUNNEL_PHYS_BASE (MSM_QDSS_PHYS_BASE + 0x4000)
#define MSM_ETM_PHYS_BASE (MSM_QDSS_PHYS_BASE + 0x1C000)
+#define QDSS_SOURCE(src_name, fpm) { .name = src_name, .fport_mask = fpm, }
+
+static struct qdss_source msm_qdss_sources[] = {
+ QDSS_SOURCE("msm_etm", 0x3),
+};
+
+static struct msm_qdss_platform_data qdss_pdata = {
+ .src_table = msm_qdss_sources,
+ .size = ARRAY_SIZE(msm_qdss_sources),
+ .afamily = 1,
+};
+
+struct platform_device msm_qdss_device = {
+ .name = "msm_qdss",
+ .id = -1,
+ .dev = {
+ .platform_data = &qdss_pdata,
+ },
+};
+
static struct resource msm_etb_resources[] = {
{
.start = MSM_ETB_PHYS_BASE,
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 1acc833..5e62507 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -64,7 +64,8 @@
static struct msm_watchdog_pdata msm_watchdog_pdata = {
.pet_time = 10000,
.bark_time = 11000,
- .has_secure = true,
+ .has_secure = false,
+ .use_kernel_fiq = true,
};
struct platform_device msm9615_device_watchdog = {
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index 3ad3ee4..ba7ac2a 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -331,6 +331,7 @@
.config_gpio = 1,
.uart_tx_gpio = 67,
.uart_rx_gpio = 66,
+ .line = 1,
};
static struct resource msm_uart_gsbi9_resources[] = {
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index ac9feee..18b0a52 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -318,10 +318,13 @@
extern struct platform_device msm9615_device_watchdog;
extern struct platform_device fsm9xxx_device_watchdog;
+extern struct platform_device apq8064_qdss_device;
+extern struct platform_device msm_qdss_device;
extern struct platform_device msm_etb_device;
extern struct platform_device msm_tpiu_device;
extern struct platform_device msm_funnel_device;
extern struct platform_device msm_etm_device;
+extern struct platform_device apq8064_etm_device;
#endif
extern struct platform_device msm_bus_8064_apps_fabric;
diff --git a/arch/arm/mach-msm/include/mach/irqs-9615.h b/arch/arm/mach-msm/include/mach/irqs-9615.h
index 6252cef..39058a6 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9615.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9615.h
@@ -21,6 +21,7 @@
* 32+: SPI (shared peripheral interrupts)
*/
+#define FIQ_START 16
#define GIC_PPI_START 16
#define GIC_SPI_START 32
diff --git a/arch/arm/mach-msm/include/mach/msm_cache_dump.h b/arch/arm/mach-msm/include/mach/msm_cache_dump.h
new file mode 100644
index 0000000..a8d2987
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_cache_dump.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _MACH_MSM_CACHE_DUMP_
+#define _MACH_MSM_CACHE_DUMP_
+
+#include <asm-generic/sizes.h>
+
+
+struct l2_cache_line_dump {
+ unsigned int l2dcrtr0_val;
+ unsigned int l2dcrtr1_val;
+ unsigned int cache_line_data[32];
+ unsigned int ddr_data[32];
+} __packed;
+
+struct l2_cache_dump {
+ unsigned int magic_number;
+ unsigned int version;
+ unsigned int tag_size;
+ unsigned int line_size;
+ unsigned int total_lines;
+ struct l2_cache_line_dump cache[8*1024];
+ unsigned int l2esr;
+} __packed;
+
+
+struct l1_cache_dump {
+ unsigned int magic;
+ unsigned int version;
+ unsigned int flags;
+ unsigned int cpu_count;
+ unsigned int i_tag_size;
+ unsigned int i_line_size;
+ unsigned int i_num_sets;
+ unsigned int i_num_ways;
+ unsigned int d_tag_size;
+ unsigned int d_line_size;
+ unsigned int d_num_sets;
+ unsigned int d_num_ways;
+ unsigned int spare[32];
+ unsigned int lines[];
+} __packed;
+
+
+struct msm_cache_dump_platform_data {
+ unsigned int l1_size;
+ unsigned int l2_size;
+};
+
+#define L1_BUFFER_SIZE SZ_1M
+#define L2_BUFFER_SIZE (sizeof(struct l2_cache_dump))
+
+#define CACHE_BUFFER_DUMP_SIZE (L1_BUFFER_SIZE + L2_BUFFER_SIZE)
+
+#define L1C_SERVICE_ID 3
+#define L1C_BUFFER_SET_COMMAND_ID 4
+#define L1C_BUFFER_GET_SIZE_COMMAND_ID 6
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h b/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h
index e2bdaea..577a097 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h
@@ -18,6 +18,7 @@
unsigned config_gpio;
unsigned uart_tx_gpio;
unsigned uart_rx_gpio;
+ int line;
};
#endif
diff --git a/arch/arm/mach-msm/include/mach/qdss.h b/arch/arm/mach-msm/include/mach/qdss.h
index 530bcb2..3b236b8 100644
--- a/arch/arm/mach-msm/include/mach/qdss.h
+++ b/arch/arm/mach-msm/include/mach/qdss.h
@@ -13,10 +13,30 @@
#ifndef __MACH_QDSS_H
#define __MACH_QDSS_H
+struct qdss_source {
+ struct list_head link;
+ const char *name;
+ uint32_t fport_mask;
+};
+
+struct msm_qdss_platform_data {
+ struct qdss_source *src_table;
+ size_t size;
+ uint8_t afamily;
+};
+
#ifdef CONFIG_MSM_QDSS
+extern struct qdss_source *qdss_get(const char *name);
+extern void qdss_put(struct qdss_source *src);
+extern int qdss_enable(struct qdss_source *src);
+extern void qdss_disable(struct qdss_source *src);
extern int qdss_clk_enable(void);
extern void qdss_clk_disable(void);
#else
+static inline struct qdss_source *qdss_get(const char *name) { return NULL; }
+static inline void qdss_put(struct qdss_source *src) {}
+static inline int qdss_enable(struct qdss_source *src) { return -ENOSYS; }
+static inline void qdss_disable(struct qdss_source *src) {}
static inline int qdss_clk_enable(void) { return -ENOSYS; }
static inline void qdss_clk_disable(void) {}
#endif
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index d26d76b..8dbf304 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -146,7 +146,7 @@
flush_axi_bus_buffer();
}
-void *alloc_bootmem_aligned(unsigned long size, unsigned long alignment)
+void * __init alloc_bootmem_aligned(unsigned long size, unsigned long alignment)
{
void *unused_addr = NULL;
unsigned long addr, tmp_size, unused_size;
diff --git a/arch/arm/mach-msm/msm-krait-l2-accessors.c b/arch/arm/mach-msm/msm-krait-l2-accessors.c
index b03e2d2..3d341e3 100644
--- a/arch/arm/mach-msm/msm-krait-l2-accessors.c
+++ b/arch/arm/mach-msm/msm-krait-l2-accessors.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -29,14 +29,13 @@
mb();
asm volatile ("mcr p15, 3, %[l2cpselr], c15, c0, 6\n\t"
+ "isb\n\t"
"mcr p15, 3, %[l2cpdr], c15, c0, 7\n\t"
- :
+ "isb\n\t"
+ "mrc p15, 3, %[l2cpdr_read], c15, c0, 7\n\t"
+ : [l2cpdr_read]"=r" (ret_val)
: [l2cpselr]"r" (reg_addr), [l2cpdr]"r" (val)
);
- isb();
- /* Ensure the value took */
- asm volatile ("mrc p15, 3, %0, c15, c0, 7" : "=r" (ret_val));
-
raw_spin_unlock_irqrestore(&l2_access_lock, flags);
return ret_val;
@@ -53,11 +52,12 @@
raw_spin_lock_irqsave(&l2_access_lock, flags);
mb();
asm volatile ("mcr p15, 3, %[l2cpselr], c15, c0, 6\n\t"
+ "isb\n\t"
"mcr p15, 3, %[l2cpdr], c15, c0, 7\n\t"
+ "isb\n\t"
:
: [l2cpselr]"r" (reg_addr), [l2cpdr]"r" (val)
);
- isb();
raw_spin_unlock_irqrestore(&l2_access_lock, flags);
}
EXPORT_SYMBOL(set_l2_indirect_reg);
@@ -72,6 +72,7 @@
raw_spin_lock_irqsave(&l2_access_lock, flags);
asm volatile ("mcr p15, 3, %[l2cpselr], c15, c0, 6\n\t"
+ "isb\n\t"
"mrc p15, 3, %[l2cpdr], c15, c0, 7\n\t"
: [l2cpdr]"=r" (val)
: [l2cpselr]"r" (reg_addr)
diff --git a/arch/arm/mach-msm/msm_cache_dump.c b/arch/arm/mach-msm/msm_cache_dump.c
new file mode 100644
index 0000000..40c358a
--- /dev/null
+++ b/arch/arm/mach-msm/msm_cache_dump.c
@@ -0,0 +1,100 @@
+/* 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/memory_alloc.h>
+#include <mach/scm.h>
+#include <mach/msm_cache_dump.h>
+#include <mach/memory.h>
+#include <mach/msm_iomap.h>
+
+#define L2C_IMEM_ADDR 0x2a03f014
+
+static unsigned long msm_cache_dump_addr;
+
+/*
+ * These are dummy pointers so the defintion of l1_cache_dump
+ * and l2_cache_dump don't get optimized away. If they aren't
+ * referenced, the structure definitions don't show up in the
+ * debugging information which is needed for post processing.
+ */
+static struct l1_cache_dump __used *l1_dump;
+static struct l2_cache_dump __used *l2_dump;
+
+static int msm_cache_dump_probe(struct platform_device *pdev)
+{
+ struct msm_cache_dump_platform_data *d = pdev->dev.platform_data;
+ int ret;
+ struct {
+ unsigned long buf;
+ unsigned long size;
+ } l1_cache_data;
+ unsigned int *imem_loc;
+ void *temp;
+ unsigned long total_size = d->l1_size + d->l2_size;
+
+ msm_cache_dump_addr = allocate_contiguous_ebi_nomap(total_size, SZ_4K);
+
+ if (!msm_cache_dump_addr) {
+ pr_err("%s: Could not get memory for cache dumping\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ temp = ioremap(msm_cache_dump_addr, total_size);
+ memset(temp, 0xFF, total_size);
+ iounmap(temp);
+
+ l1_cache_data.buf = msm_cache_dump_addr;
+ l1_cache_data.size = d->l1_size;
+
+ ret = scm_call(L1C_SERVICE_ID, L1C_BUFFER_SET_COMMAND_ID,
+ &l1_cache_data, sizeof(l1_cache_data), NULL, 0);
+
+ if (ret)
+ pr_err("%s: could not register L1 buffer ret = %d.\n",
+ __func__, ret);
+
+ imem_loc = ioremap(L2C_IMEM_ADDR, SZ_4K);
+ __raw_writel(msm_cache_dump_addr + d->l1_size, imem_loc);
+ iounmap(imem_loc);
+
+ return 0;
+}
+
+static struct platform_driver msm_cache_dump_driver = {
+ .driver = {
+ .name = "msm_cache_dump",
+ .owner = THIS_MODULE
+ },
+};
+
+static int __init msm_cache_dump_init(void)
+{
+ return platform_driver_probe(&msm_cache_dump_driver,
+ msm_cache_dump_probe);
+}
+
+static void __exit msm_cache_dump_exit(void)
+{
+ platform_driver_unregister(&msm_cache_dump_driver);
+}
+late_initcall(msm_cache_dump_init);
+module_exit(msm_cache_dump_exit)
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index 994dca6..aabb644 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -23,6 +23,8 @@
#include <linux/suspend.h>
#include <linux/percpu.h>
#include <linux/interrupt.h>
+#include <asm/fiq.h>
+#include <asm/hardware/gic.h>
#include <mach/msm_iomap.h>
#include <asm/mach-types.h>
#include <mach/scm.h>
@@ -42,6 +44,8 @@
#define WDT_HZ 32768
+struct msm_watchdog_dump msm_dump_cpu_ctx;
+
static void __iomem *msm_tmr0_base;
static unsigned long delay_time;
@@ -78,6 +82,8 @@
static int appsbark;
module_param(appsbark, int, 0);
+static int appsbark_fiq;
+
/*
* Use /sys/module/msm_watchdog/parameters/print_all_stacks
* to control whether stacks of all running
@@ -96,6 +102,13 @@
static DECLARE_DELAYED_WORK(dogwork_struct, pet_watchdog_work);
static DECLARE_WORK(init_dogwork_struct, init_watchdog_work);
+/* Called from the FIQ bark handler */
+void msm_wdog_bark_fin(void)
+{
+ pr_crit("\nApps Watchdog bark received - Calling Panic\n");
+ panic("Apps Watchdog Bark received\n");
+}
+
static int msm_watchdog_suspend(struct device *dev)
{
if (!enable)
@@ -166,9 +179,11 @@
free_irq(WDT0_ACCSCSSNBARK_INT, 0);
} else {
disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
- free_percpu_irq(WDT0_ACCSCSSNBARK_INT,
- percpu_pdata);
- free_percpu(percpu_pdata);
+ if (!appsbark_fiq) {
+ free_percpu_irq(WDT0_ACCSCSSNBARK_INT,
+ percpu_pdata);
+ free_percpu(percpu_pdata);
+ }
}
enable = 0;
atomic_notifier_chain_unregister(&panic_notifier_list,
@@ -231,8 +246,11 @@
free_irq(WDT0_ACCSCSSNBARK_INT, 0);
} else {
disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
- free_percpu_irq(WDT0_ACCSCSSNBARK_INT, percpu_pdata);
- free_percpu(percpu_pdata);
+ if (!appsbark_fiq) {
+ free_percpu_irq(WDT0_ACCSCSSNBARK_INT,
+ percpu_pdata);
+ free_percpu(percpu_pdata);
+ }
}
enable = 0;
/* In case we got suspended mid-exit */
@@ -329,26 +347,35 @@
__raw_writel(1, msm_tmr0_base + WDT0_RST);
last_pet = sched_clock();
+ if (!has_vic)
+ enable_percpu_irq(WDT0_ACCSCSSNBARK_INT, IRQ_TYPE_EDGE_RISING);
+
printk(KERN_INFO "MSM Watchdog Initialized\n");
return;
}
+struct fiq_handler wdog_fh = {
+ .name = MODULE_NAME,
+};
+
static int msm_watchdog_probe(struct platform_device *pdev)
{
struct msm_watchdog_pdata *pdata = pdev->dev.platform_data;
int ret;
+ void *stack;
if (!enable || !pdata || !pdata->pet_time || !pdata->bark_time) {
printk(KERN_INFO "MSM Watchdog Not Initialized\n");
return -ENODEV;
}
- if (!pdata->has_secure)
- appsbark = 1;
-
bark_time = pdata->bark_time;
has_vic = pdata->has_vic;
+ if (!pdata->has_secure) {
+ appsbark = 1;
+ appsbark_fiq = pdata->use_kernel_fiq;
+ }
msm_tmr0_base = msm_timer_get_timer0_base();
@@ -357,6 +384,18 @@
"apps_wdog_bark", NULL);
if (ret)
return ret;
+ } else if (appsbark_fiq) {
+ claim_fiq(&wdog_fh);
+ set_fiq_handler(&msm_wdog_fiq_start, msm_wdog_fiq_length);
+ stack = (void *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
+ if (!stack) {
+ pr_info("No free pages available - %s fails\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ msm_wdog_fiq_setup(stack);
+ gic_set_irq_secure(WDT0_ACCSCSSNBARK_INT);
} else {
percpu_pdata = alloc_percpu(struct msm_watchdog_pdata *);
if (!percpu_pdata) {
@@ -373,8 +412,6 @@
free_percpu(percpu_pdata);
return ret;
}
-
- enable_percpu_irq(WDT0_ACCSCSSNBARK_INT, IRQ_TYPE_EDGE_RISING);
}
/*
diff --git a/arch/arm/mach-msm/msm_watchdog.h b/arch/arm/mach-msm/msm_watchdog.h
index 7156dfc..00ff0b6 100644
--- a/arch/arm/mach-msm/msm_watchdog.h
+++ b/arch/arm/mach-msm/msm_watchdog.h
@@ -21,8 +21,53 @@
bool has_secure;
bool needs_expired_enable;
bool has_vic;
+ /* You have to be running in secure mode to use FIQ */
+ bool use_kernel_fiq;
};
+struct msm_watchdog_dump {
+ uint32_t magic;
+ uint32_t curr_cpsr;
+ uint32_t usr_r0;
+ uint32_t usr_r1;
+ uint32_t usr_r2;
+ uint32_t usr_r3;
+ uint32_t usr_r4;
+ uint32_t usr_r5;
+ uint32_t usr_r6;
+ uint32_t usr_r7;
+ uint32_t usr_r8;
+ uint32_t usr_r9;
+ uint32_t usr_r10;
+ uint32_t usr_r11;
+ uint32_t usr_r12;
+ uint32_t usr_r13;
+ uint32_t usr_r14;
+ uint32_t irq_spsr;
+ uint32_t irq_r13;
+ uint32_t irq_r14;
+ uint32_t svc_spsr;
+ uint32_t svc_r13;
+ uint32_t svc_r14;
+ uint32_t abt_spsr;
+ uint32_t abt_r13;
+ uint32_t abt_r14;
+ uint32_t und_spsr;
+ uint32_t und_r13;
+ uint32_t und_r14;
+ uint32_t fiq_spsr;
+ uint32_t fiq_r8;
+ uint32_t fiq_r9;
+ uint32_t fiq_r10;
+ uint32_t fiq_r11;
+ uint32_t fiq_r12;
+ uint32_t fiq_r13;
+ uint32_t fiq_r14;
+};
+
+void msm_wdog_fiq_setup(void *stack);
+extern unsigned int msm_wdog_fiq_length, msm_wdog_fiq_start;
+
#ifdef CONFIG_MSM_WATCHDOG
void pet_watchdog(void);
#else
diff --git a/arch/arm/mach-msm/msm_watchdog_asm.S b/arch/arm/mach-msm/msm_watchdog_asm.S
new file mode 100644
index 0000000..c0377d6
--- /dev/null
+++ b/arch/arm/mach-msm/msm_watchdog_asm.S
@@ -0,0 +1,84 @@
+/* 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/linkage.h>
+#include <asm/assembler.h>
+
+#define VERSION_ID 0x1
+#define MAGIC 0xDEAD0000 | VERSION_ID
+
+ .text
+
+ .align 3
+
+ENTRY(msm_wdog_fiq_start)
+ mov sp, r8 @get stack
+ ldr r8, Ldump_cpu_ctx
+ @ store magic to indicate a valid dump
+ ldr r9, Lmagic
+ str r9, [r8], #4
+ @ get the current cpsr
+ mrs r9, cpsr
+ str r9, [r8],#4
+ @ get the USR r0-r7
+ stmia r8!, {r0-r7}
+ mov r4, r8
+ mov r5, #PSR_I_BIT | PSR_F_BIT | SYSTEM_MODE
+ msr cpsr_c, r5 @ select SYSTEM mode
+ stmia r4!, {r8-r14}
+ mov r5, #PSR_I_BIT | PSR_F_BIT | IRQ_MODE
+ msr cpsr_c, r5 @ select IRQ mode
+ mrs r5, spsr
+ str r5, [r4], #4
+ stmia r4!, {r13-r14}
+ mov r5, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ msr cpsr_c, r5 @ select SVC mode
+ mrs r5, spsr
+ str r5, [r4], #4
+ stmia r4!, {r13-r14}
+ mov r5, #PSR_I_BIT | PSR_F_BIT | ABT_MODE
+ msr cpsr_c, r5 @ select ABT mode
+ mrs r5, spsr
+ str r5, [r4], #4
+ stmia r4!, {r13-r14}
+ mov r5, #PSR_I_BIT | PSR_F_BIT | UND_MODE
+ msr cpsr_c, r5 @ select UND mode
+ mrs r5, spsr
+ str r5, [r4], #4
+ stmia r4!, {r13-r14}
+ mov r5, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
+ msr cpsr_c, r5 @ select FIQ mode
+ mrs r5, spsr
+ str r5, [r4], #4
+ stmia r4!, {r8-r14}
+ dsb
+ mov r5, #PSR_F_BIT | SVC_MODE
+ msr cpsr_c, r5 @ select SVC mode
+ ldr r2, Lwatchdog_bark_fin
+ blx r2
+Ldump_cpu_ctx:
+ .word msm_dump_cpu_ctx
+Lmagic:
+ .word MAGIC
+Lwatchdog_bark_fin:
+ .word msm_wdog_bark_fin
+ENTRY(msm_wdog_fiq_length)
+ .word . - msm_wdog_fiq_start
+
+/* setup the stack */
+ENTRY(msm_wdog_fiq_setup)
+ mrs r3, cpsr
+ msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)
+ mov r8, r0
+ msr cpsr_c, r3
+ bx lr
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index 80e5a55..8d4ca8b 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -181,8 +181,6 @@
__raw_writel(readl_relaxed(pdata->v_addr +
MPA5_CFG_CTL_REG) | BIT(26),
pdata->v_addr + MPA5_CFG_CTL_REG);
-
- msm_pm_boot_before_pc = msm_pm_write_boot_vector;
}
break;
default:
diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c
index 9521e87..8760e443 100644
--- a/arch/arm/mach-msm/qdsp5/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5/audio_lpa.c
@@ -73,7 +73,7 @@
/* Size must be power of 2 */
#define MAX_BUF 2
-#define BUFSZ (167210)
+#define BUFSZ (1024000)
#define AUDDEC_DEC_PCM 0
diff --git a/arch/arm/mach-msm/qdss-etb.c b/arch/arm/mach-msm/qdss-etb.c
index 8b5f8db..96eba26 100644
--- a/arch/arm/mach-msm/qdss-etb.c
+++ b/arch/arm/mach-msm/qdss-etb.c
@@ -318,7 +318,7 @@
return ret;
}
-static void etb_sysfs_exit(void)
+static void __exit etb_sysfs_exit(void)
{
sysfs_remove_file(etb.kobj, &trigger_cntr_attr.attr);
kobject_put(etb.kobj);
@@ -371,7 +371,7 @@
return ret;
}
-static int etb_remove(struct platform_device *pdev)
+static int __devexit etb_remove(struct platform_device *pdev)
{
if (etb.enabled)
etb_disable();
@@ -386,18 +386,23 @@
static struct platform_driver etb_driver = {
.probe = etb_probe,
- .remove = etb_remove,
+ .remove = __devexit_p(etb_remove),
.driver = {
.name = "msm_etb",
},
};
-int __init etb_init(void)
+static int __init etb_init(void)
{
return platform_driver_register(&etb_driver);
}
+module_init(etb_init);
-void etb_exit(void)
+static void __exit etb_exit(void)
{
platform_driver_unregister(&etb_driver);
}
+module_exit(etb_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight Embedded Trace Buffer driver");
diff --git a/arch/arm/mach-msm/qdss-etm.c b/arch/arm/mach-msm/qdss-etm.c
index eeb7519..251db45 100644
--- a/arch/arm/mach-msm/qdss-etm.c
+++ b/arch/arm/mach-msm/qdss-etm.c
@@ -156,6 +156,7 @@
bool enabled;
struct wake_lock wake_lock;
struct pm_qos_request_list qos_req;
+ struct qdss_source *src;
struct mutex mutex;
struct device *dev;
struct kobject *kobj;
@@ -339,10 +340,6 @@
goto err;
}
- ret = qdss_clk_enable();
- if (ret)
- goto err;
-
wake_lock(&etm.wake_lock);
/* 1. causes all online cpus to come out of idle PC
* 2. prevents idle PC until save restore flag is enabled atomically
@@ -353,11 +350,10 @@
*/
pm_qos_update_request(&etm.qos_req, 0);
- etb_disable();
- tpiu_disable();
- /* enable ETB first to avoid loosing any trace data */
- etb_enable();
- funnel_enable(0x0, 0x3);
+ ret = qdss_enable(etm.src);
+ if (ret)
+ goto err_qdss;
+
for_each_online_cpu(cpu)
__etm_enable(cpu);
@@ -368,6 +364,10 @@
dev_info(etm.dev, "ETM tracing enabled\n");
return 0;
+
+err_qdss:
+ pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
+ wake_unlock(&etm.wake_lock);
err:
return ret;
}
@@ -407,17 +407,14 @@
for_each_online_cpu(cpu)
__etm_disable(cpu);
- etb_dump();
- etb_disable();
- funnel_disable(0x0, 0x3);
+
+ qdss_disable(etm.src);
etm.enabled = false;
pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
wake_unlock(&etm.wake_lock);
- qdss_clk_disable();
-
dev_info(etm.dev, "ETM tracing disabled\n");
return 0;
err:
@@ -1151,14 +1148,14 @@
return ret;
}
-static void etm_sysfs_exit(void)
+static void __exit etm_sysfs_exit(void)
{
sysfs_remove_group(etm.kobj, &etm_attr_grp);
sysfs_remove_file(etm.kobj, &enabled_attr.attr);
kobject_put(etm.kobj);
}
-static bool etm_arch_supported(uint8_t arch)
+static bool __init etm_arch_supported(uint8_t arch)
{
switch (arch) {
case PFT_ARCH_V1_1:
@@ -1249,6 +1246,12 @@
wake_lock_init(&etm.wake_lock, WAKE_LOCK_SUSPEND, "msm_etm");
pm_qos_add_request(&etm.qos_req, PM_QOS_CPU_DMA_LATENCY,
PM_QOS_DEFAULT_VALUE);
+ etm.src = qdss_get("msm_etm");
+ if (IS_ERR(etm.src)) {
+ ret = PTR_ERR(etm.src);
+ goto err_qdssget;
+ }
+
ret = qdss_clk_enable();
if (ret)
goto err_clk;
@@ -1276,6 +1279,8 @@
err_arch:
qdss_clk_disable();
err_clk:
+ qdss_put(etm.src);
+err_qdssget:
pm_qos_remove_request(&etm.qos_req);
wake_lock_destroy(&etm.wake_lock);
mutex_destroy(&etm.mutex);
@@ -1286,11 +1291,12 @@
return ret;
}
-static int etm_remove(struct platform_device *pdev)
+static int __devexit etm_remove(struct platform_device *pdev)
{
if (etm.enabled)
etm_disable();
etm_sysfs_exit();
+ qdss_put(etm.src);
pm_qos_remove_request(&etm.qos_req);
wake_lock_destroy(&etm.wake_lock);
mutex_destroy(&etm.mutex);
@@ -1301,7 +1307,7 @@
static struct platform_driver etm_driver = {
.probe = etm_probe,
- .remove = etm_remove,
+ .remove = __devexit_p(etm_remove),
.driver = {
.name = "msm_etm",
},
@@ -1311,8 +1317,13 @@
{
return platform_driver_register(&etm_driver);
}
+module_init(etm_init);
-void etm_exit(void)
+void __exit etm_exit(void)
{
platform_driver_unregister(&etm_driver);
}
+module_exit(etm_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight Program Flow Trace driver");
diff --git a/arch/arm/mach-msm/qdss-funnel.c b/arch/arm/mach-msm/qdss-funnel.c
index 990295b..2d80603 100644
--- a/arch/arm/mach-msm/qdss-funnel.c
+++ b/arch/arm/mach-msm/qdss-funnel.c
@@ -159,7 +159,7 @@
return ret;
}
-static void funnel_sysfs_exit(void)
+static void __exit funnel_sysfs_exit(void)
{
sysfs_remove_file(funnel.kobj, &priority_attr.attr);
kobject_put(funnel.kobj);
@@ -197,7 +197,7 @@
return ret;
}
-static int funnel_remove(struct platform_device *pdev)
+static int __devexit funnel_remove(struct platform_device *pdev)
{
if (funnel.enabled)
funnel_disable(0x0, 0xFF);
@@ -210,18 +210,23 @@
static struct platform_driver funnel_driver = {
.probe = funnel_probe,
- .remove = funnel_remove,
+ .remove = __devexit_p(funnel_remove),
.driver = {
.name = "msm_funnel",
},
};
-int __init funnel_init(void)
+static int __init funnel_init(void)
{
return platform_driver_register(&funnel_driver);
}
+module_init(funnel_init);
-void funnel_exit(void)
+static void __exit funnel_exit(void)
{
platform_driver_unregister(&funnel_driver);
}
+module_exit(funnel_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight Funnel driver");
diff --git a/arch/arm/mach-msm/qdss-priv.h b/arch/arm/mach-msm/qdss-priv.h
index b9f3072..f39bc52 100644
--- a/arch/arm/mach-msm/qdss-priv.h
+++ b/arch/arm/mach-msm/qdss-priv.h
@@ -58,15 +58,6 @@
#define BMVAL(val, lsb, msb) ((val & BM(lsb, msb)) >> lsb)
#define BVAL(val, n) ((val & BIT(n)) >> n)
-int etb_init(void);
-void etb_exit(void);
-int tpiu_init(void);
-void tpiu_exit(void);
-int funnel_init(void);
-void funnel_exit(void);
-int etm_init(void);
-void etm_exit(void);
-
void etb_enable(void);
void etb_disable(void);
void etb_dump(void);
diff --git a/arch/arm/mach-msm/qdss-tpiu.c b/arch/arm/mach-msm/qdss-tpiu.c
index 4481a0a..fa15635 100644
--- a/arch/arm/mach-msm/qdss-tpiu.c
+++ b/arch/arm/mach-msm/qdss-tpiu.c
@@ -108,7 +108,7 @@
return ret;
}
-static int tpiu_remove(struct platform_device *pdev)
+static int __devexit tpiu_remove(struct platform_device *pdev)
{
if (tpiu.enabled)
tpiu_disable();
@@ -119,18 +119,23 @@
static struct platform_driver tpiu_driver = {
.probe = tpiu_probe,
- .remove = tpiu_remove,
+ .remove = __devexit_p(tpiu_remove),
.driver = {
.name = "msm_tpiu",
},
};
-int __init tpiu_init(void)
+static int __init tpiu_init(void)
{
return platform_driver_register(&tpiu_driver);
}
+module_init(tpiu_init);
-void tpiu_exit(void)
+static void __exit tpiu_exit(void)
{
platform_driver_unregister(&tpiu_driver);
}
+module_exit(tpiu_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight Trace Port Interface Unit driver");
diff --git a/arch/arm/mach-msm/qdss.c b/arch/arm/mach-msm/qdss.c
index 80ec65a..cfe65ad 100644
--- a/arch/arm/mach-msm/qdss.c
+++ b/arch/arm/mach-msm/qdss.c
@@ -24,26 +24,155 @@
#include "rpm_resources.h"
#include "qdss-priv.h"
+#define MAX_STR_LEN (65535)
+
enum {
QDSS_CLK_OFF,
QDSS_CLK_ON_DBG,
QDSS_CLK_ON_HSDBG,
};
+/*
+ * Exclusion rules for structure fields.
+ *
+ * S: qdss.sources_mutex protected.
+ * I: qdss.sink_mutex protected.
+ * C: qdss.clk_mutex protected.
+ */
struct qdss_ctx {
- struct kobject *modulekobj;
- uint8_t max_clk;
- uint8_t clk_count;
- struct mutex clk_mutex;
+ struct kobject *modulekobj;
+ struct msm_qdss_platform_data *pdata;
+ struct list_head sources; /* S: sources list */
+ struct mutex sources_mutex;
+ uint8_t sink_count; /* I: sink count */
+ struct mutex sink_mutex;
+ uint8_t max_clk;
+ uint8_t clk_count; /* C: clk count */
+ struct mutex clk_mutex;
};
static struct qdss_ctx qdss;
-
-struct kobject *qdss_get_modulekobj(void)
+/**
+ * qdss_get - get the qdss source handle
+ * @name: name of the qdss source
+ *
+ * Searches the sources list to get the qdss source handle for this source.
+ *
+ * CONTEXT:
+ * Typically called from init or probe functions
+ *
+ * RETURNS:
+ * pointer to struct qdss_source on success, %NULL on failure
+ */
+struct qdss_source *qdss_get(const char *name)
{
- return qdss.modulekobj;
+ struct qdss_source *src, *source = NULL;
+
+ mutex_lock(&qdss.sources_mutex);
+ list_for_each_entry(src, &qdss.sources, link) {
+ if (src->name) {
+ if (strncmp(src->name, name, MAX_STR_LEN))
+ continue;
+ source = src;
+ break;
+ }
+ }
+ mutex_unlock(&qdss.sources_mutex);
+
+ return source ? source : ERR_PTR(-ENOENT);
}
+EXPORT_SYMBOL(qdss_get);
+
+/**
+ * qdss_put - release the qdss source handle
+ * @name: name of the qdss source
+ *
+ * CONTEXT:
+ * Typically called from driver remove or exit functions
+ */
+void qdss_put(struct qdss_source *src)
+{
+}
+EXPORT_SYMBOL(qdss_put);
+
+/**
+ * qdss_enable - enable qdss for the source
+ * @src: handle for the source making the call
+ *
+ * Enables qdss block (relevant funnel ports and sink) if not already
+ * enabled, otherwise increments the reference count
+ *
+ * CONTEXT:
+ * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
+ *
+ * RETURNS:
+ * 0 on success, non-zero on failure
+ */
+int qdss_enable(struct qdss_source *src)
+{
+ int ret;
+
+ if (!src)
+ return -EINVAL;
+
+ ret = qdss_clk_enable();
+ if (ret)
+ goto err;
+
+ if ((qdss.pdata)->afamily) {
+ mutex_lock(&qdss.sink_mutex);
+ if (qdss.sink_count == 0) {
+ etb_disable();
+ tpiu_disable();
+ /* enable ETB first to avoid losing any trace data */
+ etb_enable();
+ }
+ qdss.sink_count++;
+ mutex_unlock(&qdss.sink_mutex);
+ }
+
+ funnel_enable(0x0, src->fport_mask);
+ return 0;
+err:
+ return ret;
+}
+EXPORT_SYMBOL(qdss_enable);
+
+/**
+ * qdss_disable - disable qdss for the source
+ * @src: handle for the source making the call
+ *
+ * Disables qdss block (relevant funnel ports and sink) if the reference count
+ * is one, otherwise decrements the reference count
+ *
+ * CONTEXT:
+ * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
+ */
+void qdss_disable(struct qdss_source *src)
+{
+ if (!src)
+ return;
+
+ if ((qdss.pdata)->afamily) {
+ mutex_lock(&qdss.sink_mutex);
+ if (WARN(qdss.sink_count == 0, "qdss is unbalanced\n"))
+ goto out;
+ if (qdss.sink_count == 1) {
+ etb_dump();
+ etb_disable();
+ }
+ qdss.sink_count--;
+ mutex_unlock(&qdss.sink_mutex);
+ }
+
+ funnel_disable(0x0, src->fport_mask);
+ qdss_clk_disable();
+ return;
+out:
+ mutex_unlock(&qdss.sink_mutex);
+}
+EXPORT_SYMBOL(qdss_disable);
/**
* qdss_clk_enable - enable qdss clocks
@@ -111,6 +240,11 @@
}
EXPORT_SYMBOL(qdss_clk_disable);
+struct kobject *qdss_get_modulekobj(void)
+{
+ return qdss.modulekobj;
+}
+
#define QDSS_ATTR(name) \
static struct kobj_attribute name##_attr = \
__ATTR(name, S_IRUGO | S_IWUSR, name##_show, name##_store)
@@ -136,6 +270,16 @@
}
QDSS_ATTR(max_clk);
+static void __init qdss_add_sources(struct qdss_source *srcs, size_t num)
+{
+ mutex_lock(&qdss.sources_mutex);
+ while (num--) {
+ list_add_tail(&srcs->link, &qdss.sources);
+ srcs++;
+ }
+ mutex_unlock(&qdss.sources_mutex);
+}
+
static int __init qdss_sysfs_init(void)
{
int ret;
@@ -158,58 +302,85 @@
return ret;
}
-static void qdss_sysfs_exit(void)
+static void __exit qdss_sysfs_exit(void)
{
sysfs_remove_file(qdss.modulekobj, &max_clk_attr.attr);
}
-static int __init qdss_init(void)
+static int __devinit qdss_probe(struct platform_device *pdev)
{
int ret;
+ struct qdss_source *src_table;
+ size_t num_srcs;
+ mutex_init(&qdss.sources_mutex);
mutex_init(&qdss.clk_mutex);
+ mutex_init(&qdss.sink_mutex);
+
+ if (pdev->dev.platform_data == NULL) {
+ pr_err("%s: platform data is NULL\n", __func__);
+ ret = -ENODEV;
+ goto err_pdata;
+ }
+ qdss.pdata = pdev->dev.platform_data;
+
+ INIT_LIST_HEAD(&qdss.sources);
+ src_table = (qdss.pdata)->src_table;
+ num_srcs = (qdss.pdata)->size;
+ qdss_add_sources(src_table, num_srcs);
+
+ pr_info("QDSS arch initialized\n");
+ return 0;
+err_pdata:
+ mutex_destroy(&qdss.sink_mutex);
+ mutex_destroy(&qdss.clk_mutex);
+ mutex_destroy(&qdss.sources_mutex);
+ pr_err("QDSS init failed\n");
+ return ret;
+}
+
+static int __devexit qdss_remove(struct platform_device *pdev)
+{
+ qdss_sysfs_exit();
+ mutex_destroy(&qdss.sink_mutex);
+ mutex_destroy(&qdss.clk_mutex);
+ mutex_destroy(&qdss.sources_mutex);
+
+ return 0;
+}
+
+static struct platform_driver qdss_driver = {
+ .probe = qdss_probe,
+ .remove = __devexit_p(qdss_remove),
+ .driver = {
+ .name = "msm_qdss",
+ },
+};
+
+static int __init qdss_init(void)
+{
+ return platform_driver_register(&qdss_driver);
+}
+arch_initcall(qdss_init);
+
+static int __init qdss_module_init(void)
+{
+ int ret;
ret = qdss_sysfs_init();
if (ret)
goto err_sysfs;
- ret = etb_init();
- if (ret)
- goto err_etb;
- ret = tpiu_init();
- if (ret)
- goto err_tpiu;
- ret = funnel_init();
- if (ret)
- goto err_funnel;
- ret = etm_init();
- if (ret)
- goto err_etm;
- pr_info("QDSS initialized\n");
+ pr_info("QDSS module initialized\n");
return 0;
-err_etm:
- funnel_exit();
-err_funnel:
- tpiu_exit();
-err_tpiu:
- etb_exit();
-err_etb:
- qdss_sysfs_exit();
err_sysfs:
- mutex_destroy(&qdss.clk_mutex);
- pr_err("QDSS init failed\n");
return ret;
}
-module_init(qdss_init);
+module_init(qdss_module_init);
static void __exit qdss_exit(void)
{
- qdss_sysfs_exit();
- etm_exit();
- funnel_exit();
- tpiu_exit();
- etb_exit();
- mutex_destroy(&qdss.clk_mutex);
+ platform_driver_unregister(&qdss_driver);
}
module_exit(qdss_exit);
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index bbfe702..3cf0550 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -2365,26 +2365,19 @@
return;
}
- /* queue state entries */
- for (n = 0; n < SMSM_NUM_ENTRIES; n++) {
- new_state = __raw_readl(SMSM_STATE_ADDR(n));
-
- ret = kfifo_in(&smsm_snapshot_fifo,
- &new_state, sizeof(new_state));
- if (ret != sizeof(new_state)) {
- pr_err("%s: SMSM snapshot failure %d\n", __func__, ret);
- return;
- }
- }
-
- /* queue wakelock usage flag */
- ret = kfifo_in(&smsm_snapshot_fifo,
- &use_wakelock, sizeof(use_wakelock));
- if (ret != sizeof(use_wakelock)) {
- pr_err("%s: SMSM snapshot failure %d\n", __func__, ret);
- return;
- }
-
+ /*
+ * To avoid a race condition with notify_smsm_cb_clients_worker, the
+ * following sequence must be followed:
+ * 1) increment snapshot count
+ * 2) insert data into FIFO
+ *
+ * Potentially in parallel, the worker:
+ * a) verifies >= 1 snapshots are in FIFO
+ * b) processes snapshot
+ * c) decrements reference count
+ *
+ * This order ensures that 1 will always occur before abc.
+ */
if (use_wakelock) {
spin_lock_irqsave(&smsm_snapshot_count_lock, flags);
if (smsm_snapshot_count == 0) {
@@ -2394,7 +2387,44 @@
++smsm_snapshot_count;
spin_unlock_irqrestore(&smsm_snapshot_count_lock, flags);
}
+
+ /* queue state entries */
+ for (n = 0; n < SMSM_NUM_ENTRIES; n++) {
+ new_state = __raw_readl(SMSM_STATE_ADDR(n));
+
+ ret = kfifo_in(&smsm_snapshot_fifo,
+ &new_state, sizeof(new_state));
+ if (ret != sizeof(new_state)) {
+ pr_err("%s: SMSM snapshot failure %d\n", __func__, ret);
+ goto restore_snapshot_count;
+ }
+ }
+
+ /* queue wakelock usage flag */
+ ret = kfifo_in(&smsm_snapshot_fifo,
+ &use_wakelock, sizeof(use_wakelock));
+ if (ret != sizeof(use_wakelock)) {
+ pr_err("%s: SMSM snapshot failure %d\n", __func__, ret);
+ goto restore_snapshot_count;
+ }
+
schedule_work(&smsm_cb_work);
+ return;
+
+restore_snapshot_count:
+ if (use_wakelock) {
+ spin_lock_irqsave(&smsm_snapshot_count_lock, flags);
+ if (smsm_snapshot_count) {
+ --smsm_snapshot_count;
+ if (smsm_snapshot_count == 0) {
+ SMx_POWER_INFO("SMSM snapshot wake unlock\n");
+ wake_unlock(&smsm_snapshot_wakelock);
+ }
+ } else {
+ pr_err("%s: invalid snapshot count\n", __func__);
+ }
+ spin_unlock_irqrestore(&smsm_snapshot_count_lock, flags);
+ }
}
static irqreturn_t smsm_irq_handler(int irq, void *data)
diff --git a/arch/arm/mach-msm/smem_log.c b/arch/arm/mach-msm/smem_log.c
index 98f9957..2e9a97c 100644
--- a/arch/arm/mach-msm/smem_log.c
+++ b/arch/arm/mach-msm/smem_log.c
@@ -59,10 +59,20 @@
#define D(x...) do {} while (0)
#endif
+/*
+ * Legacy targets use the 32KHz hardware timer and new targets will use
+ * the scheduler timer scaled to a 32KHz tick count.
+ *
+ * As testing on legacy targets permits, we will move them to use
+ * sched_clock() and eventually remove the conditiona compilation.
+ */
#if defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) \
|| defined(CONFIG_ARCH_FSM9XXX)
#define TIMESTAMP_ADDR (MSM_TMR_BASE + 0x08)
-#else
+#elif defined(CONFIG_ARCH_APQ8064) || defined(CONFIG_ARCH_MSM7X01A) || \
+ defined(CONFIG_ARCH_MSM7x25) || defined(CONFIG_ARCH_MSM7X27) || \
+ defined(CONFIG_ARCH_MSM7X27A) || defined(CONFIG_ARCH_MSM8960) || \
+ defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_QSD8X50)
#define TIMESTAMP_ADDR (MSM_TMR_BASE + 0x04)
#endif
@@ -623,6 +633,8 @@
static void init_syms(void) {}
#endif
+#ifdef TIMESTAMP_ADDR
+/* legacy timestamp using 32.768KHz clock */
static inline unsigned int read_timestamp(void)
{
unsigned int tick = 0;
@@ -637,6 +649,18 @@
return tick;
}
+#else
+static inline unsigned int read_timestamp(void)
+{
+ unsigned long long val;
+
+ /* SMEM LOG uses a 32.768KHz timestamp */
+ val = sched_clock() * 32768U;
+ do_div(val, 1000000000U);
+
+ return (unsigned int)val;
+}
+#endif
static void smem_log_event_from_user(struct smem_log_inst *inst,
const char __user *buf, int size, int num)
@@ -649,6 +673,11 @@
int first = 1;
int ret;
+ if (!inst->idx) {
+ pr_err("%s: invalid write index\n", __func__);
+ return;
+ }
+
remote_spin_lock_irqsave(inst->remote_spinlock, flags);
while (num--) {
@@ -898,6 +927,9 @@
local_inst = fp->private_data;
+ if (!local_inst->idx)
+ return -ENODEV;
+
remote_spin_lock_irqsave(local_inst->remote_spinlock, flags);
orig_idx = *local_inst->idx;
@@ -947,6 +979,8 @@
struct smem_log_inst *inst;
inst = fp->private_data;
+ if (!inst->idx)
+ return -ENODEV;
remote_spin_lock_irqsave(inst->remote_spinlock, flags);
@@ -1185,8 +1219,10 @@
int curr_read_avail;
unsigned long flags = 0;
- remote_spin_lock_irqsave(inst->remote_spinlock, flags);
+ if (!inst->idx)
+ return 0;
+ remote_spin_lock_irqsave(inst->remote_spinlock, flags);
curr_read_avail = (*inst->idx - inst->read_idx);
if (curr_read_avail < 0)
curr_read_avail = inst->num - inst->read_idx + *inst->idx;
@@ -1694,6 +1730,10 @@
static int debug_dump(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[GEN].idx || !inst[GEN].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[GEN]);
r = wait_event_interruptible_timeout(inst[GEN].read_wait,
@@ -1714,6 +1754,10 @@
static int debug_dump_sym(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[GEN].idx || !inst[GEN].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[GEN]);
r = wait_event_interruptible_timeout(inst[GEN].read_wait,
@@ -1734,6 +1778,10 @@
static int debug_dump_static(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[STA].idx || !inst[STA].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[STA]);
r = wait_event_interruptible_timeout(inst[STA].read_wait,
@@ -1754,6 +1802,10 @@
static int debug_dump_static_sym(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[STA].idx || !inst[STA].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[STA]);
r = wait_event_interruptible_timeout(inst[STA].read_wait,
@@ -1774,6 +1826,10 @@
static int debug_dump_power(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[POW].idx || !inst[POW].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[POW]);
r = wait_event_interruptible_timeout(inst[POW].read_wait,
@@ -1794,6 +1850,10 @@
static int debug_dump_power_sym(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[POW].idx || !inst[POW].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[POW]);
r = wait_event_interruptible_timeout(inst[POW].read_wait,
@@ -1822,10 +1882,15 @@
size_t count, loff_t *ppos)
{
int r;
- static int bsize;
+ int bsize = 0;
int (*fill)(char *, int, uint32_t) = file->private_data;
- if (!(*ppos))
+ if (!(*ppos)) {
bsize = fill(debug_buffer, EVENTS_PRINT_SIZE, 0);
+
+ if (bsize < 0)
+ bsize = scnprintf(debug_buffer,
+ EVENTS_PRINT_SIZE, "Log not available\n");
+ }
DBG("%s: count %d ppos %d\n", __func__, count, (unsigned int)*ppos);
r = simple_read_from_buffer(buf, count, ppos, debug_buffer,
bsize);
@@ -1840,12 +1905,21 @@
int bsize;
if (!buffer)
return -ENOMEM;
+
bsize = fill(buffer, count, 1);
+ if (bsize < 0) {
+ if (*ppos == 0)
+ bsize = scnprintf(buffer, count, "Log not available\n");
+ else
+ bsize = 0;
+ }
+
DBG("%s: count %d bsize %d\n", __func__, count, bsize);
if (copy_to_user(buf, buffer, bsize)) {
kfree(buffer);
return -EFAULT;
}
+ *ppos += bsize;
kfree(buffer);
return bsize;
}
diff --git a/arch/arm/mach-msm/timer.h b/arch/arm/mach-msm/timer.h
index caef19d..7da9e6a 100644
--- a/arch/arm/mach-msm/timer.h
+++ b/arch/arm/mach-msm/timer.h
@@ -17,9 +17,14 @@
extern struct sys_timer msm_timer;
void __iomem *msm_timer_get_timer0_base(void);
-int64_t msm_timer_enter_idle(void);
-void msm_timer_exit_idle(int low_power);
int64_t msm_timer_get_sclk_time(int64_t *period);
uint32_t msm_timer_get_sclk_ticks(void);
int msm_timer_init_time_sync(void (*timeout)(void));
+#ifndef CONFIG_ARM_ARCH_TIMER
+int64_t msm_timer_enter_idle(void);
+void msm_timer_exit_idle(int low_power);
+#else
+static inline int64_t msm_timer_enter_idle(void) { return 0; }
+static inline void msm_timer_exit_idle(int low_power) { return; }
+#endif
#endif
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index d083702..5634a19 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -443,7 +443,7 @@
sg_set_page(&memdesc->sg[i], page, PAGE_SIZE, 0);
}
- kgsl_cache_range_op(memdesc, KGSL_CACHE_OP_INV);
+ kgsl_cache_range_op(memdesc, KGSL_CACHE_OP_FLUSH);
ret = kgsl_mmu_map(pagetable, memdesc, protflags);
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index fb73321..a2ec006 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -1078,6 +1078,10 @@
{
struct tavarua_device *radio = container_of(work,
struct tavarua_device, work.work);
+ FMDERR("%s: Releasing the FM I2S GPIO\n", __func__);
+ if (radio->pdata->config_i2s_gpio != NULL)
+ radio->pdata->config_i2s_gpio(FM_I2S_OFF);
+ FMDERR("%s: Shutting down FM SOC\n", __func__);
radio->pdata->fm_shutdown(radio->pdata);
complete(&radio->shutdown_done);
}
@@ -1163,8 +1167,9 @@
return -EINVAL;
irq = radio->pdata->irq;
disable_irq_wake(irq);
- flush_workqueue(radio->wqueue);
free_irq(irq, radio);
+ cancel_delayed_work_sync(&radio->work);
+ flush_workqueue(radio->wqueue);
return 0;
}
@@ -2043,10 +2048,7 @@
FMDBG("In %s", __func__);
- /* disable radio ctrl */
- retval = tavarua_write_register(radio, RDCTRL, 0x00);
-
- FMDBG("%s, Disable IRQs\n", __func__);
+ FMDBG("%s, Disabling the IRQs\n", __func__);
/* disable irq */
retval = tavarua_disable_irq(radio);
if (retval < 0) {
@@ -2054,6 +2056,13 @@
return retval;
}
+ /* disable radio ctrl */
+ retval = tavarua_write_register(radio, RDCTRL, 0x00);
+ if (retval < 0) {
+ printk(KERN_ERR "%s: failed to disable FM\n", __func__);
+ return retval;
+ }
+
init_completion(&radio->shutdown_done);
bahama_present = is_bahama();
@@ -2146,8 +2155,6 @@
/* teardown gpio and pmic */
marimba_set_fm_status(radio->marimba, false);
wait_for_completion(&radio->shutdown_done);
- if (radio->pdata->config_i2s_gpio != NULL)
- radio->pdata->config_i2s_gpio(FM_I2S_OFF);
radio->handle_irq = 1;
atomic_inc(&radio->users);
radio->marimba->mod_id = SLAVE_ID_BAHAMA;
@@ -2992,7 +2999,7 @@
}
/* check if off */
else if ((ctrl->value == FM_OFF) && radio->registers[RDCTRL]) {
- FMDBG("turning off...\n");
+ FMDBG("%s: turning off...\n", __func__);
tavarua_write_register(radio, RDCTRL, ctrl->value);
/* flush the event and work queues */
kfifo_reset(&radio->data_buf[TAVARUA_BUF_EVENTS]);
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index a9b8e40..6744479 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -21,27 +21,22 @@
#include <media/rc-core.h>
#include <media/gpio-ir-recv.h>
-#define TSOP_DRIVER_NAME "gpio-rc-recv"
-#define TSOP_DEVICE_NAME "gpio_ir_recv"
+#define GPIO_IR_DRIVER_NAME "gpio-rc-recv"
+#define GPIO_IR_DEVICE_NAME "gpio_ir_recv"
struct gpio_rc_dev {
struct rc_dev *rcdev;
- struct mutex lock;
unsigned int gpio_nr;
bool active_low;
- bool can_wakeup;
- struct work_struct work;
};
-static void ir_decoder_work(struct work_struct *work)
+static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id)
{
- struct gpio_rc_dev *gpio_dev = container_of(work,
- struct gpio_rc_dev, work);
+ struct gpio_rc_dev *gpio_dev = dev_id;
unsigned int gval;
int rc = 0;
enum raw_event_type type = IR_SPACE;
- mutex_lock(&gpio_dev->lock);
gval = gpio_get_value_cansleep(gpio_dev->gpio_nr);
if (gval < 0)
@@ -60,15 +55,6 @@
ir_raw_event_handle(gpio_dev->rcdev);
err_get_value:
- mutex_unlock(&gpio_dev->lock);
-}
-
-static irqreturn_t gpio_ir_recv_irq_handler(int irq, void *data)
-{
- struct gpio_rc_dev *gpio_dev = data;
-
- schedule_work(&gpio_dev->work);
-
return IRQ_HANDLED;
}
@@ -78,7 +64,7 @@
struct rc_dev *rcdev;
const struct gpio_ir_recv_platform_data *pdata =
pdev->dev.platform_data;
- int rc = 0;
+ int rc;
if (!pdata)
return -EINVAL;
@@ -90,8 +76,6 @@
if (!gpio_dev)
return -ENOMEM;
- mutex_init(&gpio_dev->lock);
-
rcdev = rc_allocate_device();
if (!rcdev) {
rc = -ENOMEM;
@@ -99,18 +83,15 @@
}
rcdev->driver_type = RC_DRIVER_IR_RAW;
- rcdev->allowed_protos = RC_TYPE_NEC;
- rcdev->input_name = TSOP_DEVICE_NAME;
+ rcdev->allowed_protos = RC_TYPE_ALL;
+ rcdev->input_name = GPIO_IR_DEVICE_NAME;
rcdev->input_id.bustype = BUS_HOST;
- rcdev->driver_name = TSOP_DRIVER_NAME;
- rcdev->map_name = RC_MAP_SAMSUNG_NECX;
+ rcdev->driver_name = GPIO_IR_DRIVER_NAME;
+ rcdev->map_name = RC_MAP_EMPTY;
gpio_dev->rcdev = rcdev;
gpio_dev->gpio_nr = pdata->gpio_nr;
gpio_dev->active_low = pdata->active_low;
- gpio_dev->can_wakeup = pdata->can_wakeup;
-
- INIT_WORK(&gpio_dev->work, ir_decoder_work);
rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv");
if (rc < 0)
@@ -127,22 +108,15 @@
platform_set_drvdata(pdev, gpio_dev);
- rc = request_irq(gpio_to_irq(pdata->gpio_nr), gpio_ir_recv_irq_handler,
+ rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr),
+ gpio_ir_recv_irq,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
- "gpio-ir-recv-irq", gpio_dev);
+ "gpio-ir-recv-irq", gpio_dev);
if (rc < 0)
goto err_request_irq;
- if (pdata->can_wakeup == true) {
- rc = enable_irq_wake(gpio_to_irq(pdata->gpio_nr));
- if (rc < 0)
- goto err_enable_irq_wake;
- }
-
return 0;
-err_enable_irq_wake:
- free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev);
err_request_irq:
platform_set_drvdata(pdev, NULL);
rc_unregister_device(rcdev);
@@ -153,7 +127,6 @@
rc_free_device(rcdev);
rcdev = NULL;
err_allocate_device:
- mutex_destroy(&gpio_dev->lock);
kfree(gpio_dev);
return rc;
}
@@ -162,24 +135,57 @@
{
struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
- flush_work_sync(&gpio_dev->work);
- disable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev);
platform_set_drvdata(pdev, NULL);
rc_unregister_device(gpio_dev->rcdev);
gpio_free(gpio_dev->gpio_nr);
rc_free_device(gpio_dev->rcdev);
- mutex_destroy(&gpio_dev->lock);
kfree(gpio_dev);
return 0;
}
+#ifdef CONFIG_PM
+static int gpio_ir_recv_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
+ else
+ disable_irq(gpio_to_irq(gpio_dev->gpio_nr));
+
+ return 0;
+}
+
+static int gpio_ir_recv_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
+ else
+ enable_irq(gpio_to_irq(gpio_dev->gpio_nr));
+
+ return 0;
+}
+
+static const struct dev_pm_ops gpio_ir_recv_pm_ops = {
+ .suspend = gpio_ir_recv_suspend,
+ .resume = gpio_ir_recv_resume,
+};
+#endif
+
static struct platform_driver gpio_ir_recv_driver = {
.probe = gpio_ir_recv_probe,
.remove = __devexit_p(gpio_ir_recv_remove),
.driver = {
- .name = TSOP_DRIVER_NAME,
+ .name = GPIO_IR_DRIVER_NAME,
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &gpio_ir_recv_pm_ops,
+#endif
},
};
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index a2b005e..9063e98 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -2889,7 +2889,8 @@
}
#ifdef CONFIG_HIGHMEM
- __free_pages(test->highmem, BUFFER_ORDER);
+ if (test->highmem)
+ __free_pages(test->highmem, BUFFER_ORDER);
#endif
kfree(test->buffer);
kfree(test);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 2620108..d07487b 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -372,6 +372,7 @@
tasklet_schedule (&dev->bh);
break;
case 0:
+ usb_mark_last_busy(dev->udev);
__skb_queue_tail (&dev->rxq, skb);
}
} else {
diff --git a/drivers/of/of_spmi.c b/drivers/of/of_spmi.c
index 112497c..61085c9 100644
--- a/drivers/of/of_spmi.c
+++ b/drivers/of/of_spmi.c
@@ -203,9 +203,18 @@
struct device_node *node;
int rc, i, num_dev_node = 0;
- /* first count the total number of device_nodes */
- for_each_child_of_node(container, node)
+ if (!of_device_is_available(container))
+ return;
+
+ /*
+ * Count the total number of device_nodes so we know how much
+ * device_store to allocate.
+ */
+ for_each_child_of_node(container, node) {
+ if (!of_device_is_available(node))
+ continue;
num_dev_node++;
+ }
rc = of_spmi_alloc_device_store(d_info, num_dev_node);
if (rc) {
@@ -214,9 +223,10 @@
return;
}
- /* allocate resources per device_node */
i = 0;
for_each_child_of_node(container, node) {
+ if (!of_device_is_available(node))
+ continue;
of_spmi_init_resource(&r_info, node);
of_spmi_sum_node_resources(&r_info, 1);
rc = of_spmi_allocate_node_resources(d_info, &r_info, i);
@@ -226,17 +236,6 @@
of_spmi_free_device_resources(d_info);
return;
}
- i++;
- }
-
- /**
- * Now we need to cycle through again and actually populate
- * the resources for each node.
- */
- i = 0;
- for_each_child_of_node(container, node) {
- of_spmi_init_resource(&r_info, node);
- of_spmi_sum_node_resources(&r_info, 1);
of_spmi_populate_node_resources(d_info, &r_info, i);
i++;
}
@@ -265,6 +264,9 @@
for_each_child_of_node(container, node) {
struct of_spmi_res_info r_info;
+ if (!of_device_is_available(node))
+ continue;
+
/**
* Check to see if this node contains children which
* should be all created as the same spmi_device.
@@ -365,6 +367,9 @@
continue;
}
+ if (!of_device_is_available(node))
+ continue;
+
rc = of_spmi_alloc_device_store(&d_info, 1);
if (rc) {
dev_err(&ctrl->dev, "%s: unable to allocate"
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 8bd5bd8..fa9d1df 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -88,10 +88,80 @@
#define QC_DEVID_PGD 0x5
#define QC_MSM_DEVS 5
+#define PGD_THIS_EE(r, v) ((v) ? PGD_THIS_EE_V2(r) : PGD_THIS_EE_V1(r))
+#define PGD_PORT(r, p, v) ((v) ? PGD_PORT_V2(r, p) : PGD_PORT_V1(r, p))
+#define CFG_PORT(r, v) ((v) ? CFG_PORT_V2(r) : CFG_PORT_V1(r))
+
+#define PGD_THIS_EE_V2(r) (dev->base + (r ## _V2) + (dev->ee * 0x1000))
+#define PGD_PORT_V2(r, p) (dev->base + (r ## _V2) + ((p) * 0x1000))
+#define CFG_PORT_V2(r) ((r ## _V2))
/* Component registers */
-enum comp_reg {
- COMP_CFG = 0,
- COMP_TRUST_CFG = 0x14,
+enum comp_reg_v2 {
+ COMP_CFG_V2 = 4,
+ COMP_TRUST_CFG_V2 = 0x3000,
+};
+
+/* Manager PGD registers */
+enum pgd_reg_v2 {
+ PGD_CFG_V2 = 0x800,
+ PGD_STAT_V2 = 0x804,
+ PGD_INT_EN_V2 = 0x810,
+ PGD_INT_STAT_V2 = 0x814,
+ PGD_INT_CLR_V2 = 0x818,
+ PGD_OWN_EEn_V2 = 0x300C,
+ PGD_PORT_INT_EN_EEn_V2 = 0x5000,
+ PGD_PORT_INT_ST_EEn_V2 = 0x5004,
+ PGD_PORT_INT_CL_EEn_V2 = 0x5008,
+ PGD_PORT_CFGn_V2 = 0x14000,
+ PGD_PORT_STATn_V2 = 0x14004,
+ PGD_PORT_PARAMn_V2 = 0x14008,
+ PGD_PORT_BLKn_V2 = 0x1400C,
+ PGD_PORT_TRANn_V2 = 0x14010,
+ PGD_PORT_MCHANn_V2 = 0x14014,
+ PGD_PORT_PSHPLLn_V2 = 0x14018,
+ PGD_PORT_PC_CFGn_V2 = 0x8000,
+ PGD_PORT_PC_VALn_V2 = 0x8004,
+ PGD_PORT_PC_VFR_TSn_V2 = 0x8008,
+ PGD_PORT_PC_VFR_STn_V2 = 0x800C,
+ PGD_PORT_PC_VFR_CLn_V2 = 0x8010,
+ PGD_IE_STAT_V2 = 0x820,
+ PGD_VE_STAT_V2 = 0x830,
+};
+
+#define PGD_THIS_EE_V1(r) (dev->base + (r ## _V1) + (dev->ee * 16))
+#define PGD_PORT_V1(r, p) (dev->base + (r ## _V1) + ((p) * 32))
+#define CFG_PORT_V1(r) ((r ## _V1))
+/* Component registers */
+enum comp_reg_v1 {
+ COMP_CFG_V1 = 0,
+ COMP_TRUST_CFG_V1 = 0x14,
+};
+
+/* Manager PGD registers */
+enum pgd_reg_v1 {
+ PGD_CFG_V1 = 0x1000,
+ PGD_STAT_V1 = 0x1004,
+ PGD_INT_EN_V1 = 0x1010,
+ PGD_INT_STAT_V1 = 0x1014,
+ PGD_INT_CLR_V1 = 0x1018,
+ PGD_OWN_EEn_V1 = 0x1020,
+ PGD_PORT_INT_EN_EEn_V1 = 0x1030,
+ PGD_PORT_INT_ST_EEn_V1 = 0x1034,
+ PGD_PORT_INT_CL_EEn_V1 = 0x1038,
+ PGD_PORT_CFGn_V1 = 0x1080,
+ PGD_PORT_STATn_V1 = 0x1084,
+ PGD_PORT_PARAMn_V1 = 0x1088,
+ PGD_PORT_BLKn_V1 = 0x108C,
+ PGD_PORT_TRANn_V1 = 0x1090,
+ PGD_PORT_MCHANn_V1 = 0x1094,
+ PGD_PORT_PSHPLLn_V1 = 0x1098,
+ PGD_PORT_PC_CFGn_V1 = 0x1600,
+ PGD_PORT_PC_VALn_V1 = 0x1604,
+ PGD_PORT_PC_VFR_TSn_V1 = 0x1608,
+ PGD_PORT_PC_VFR_STn_V1 = 0x160C,
+ PGD_PORT_PC_VFR_CLn_V1 = 0x1610,
+ PGD_IE_STAT_V1 = 0x1700,
+ PGD_VE_STAT_V1 = 0x1710,
};
/* Manager registers */
@@ -143,33 +213,6 @@
INTF_VE_STAT = 0x640,
};
-/* Manager PGD registers */
-enum pgd_reg {
- PGD_CFG = 0x1000,
- PGD_STAT = 0x1004,
- PGD_INT_EN = 0x1010,
- PGD_INT_STAT = 0x1014,
- PGD_INT_CLR = 0x1018,
- PGD_OWN_EEn = 0x1020,
- PGD_PORT_INT_EN_EEn = 0x1030,
- PGD_PORT_INT_ST_EEn = 0x1034,
- PGD_PORT_INT_CL_EEn = 0x1038,
- PGD_PORT_CFGn = 0x1080,
- PGD_PORT_STATn = 0x1084,
- PGD_PORT_PARAMn = 0x1088,
- PGD_PORT_BLKn = 0x108C,
- PGD_PORT_TRANn = 0x1090,
- PGD_PORT_MCHANn = 0x1094,
- PGD_PORT_PSHPLLn = 0x1098,
- PGD_PORT_PC_CFGn = 0x1600,
- PGD_PORT_PC_VALn = 0x1604,
- PGD_PORT_PC_VFR_TSn = 0x1608,
- PGD_PORT_PC_VFR_STn = 0x160C,
- PGD_PORT_PC_VFR_CLn = 0x1610,
- PGD_IE_STAT = 0x1700,
- PGD_VE_STAT = 0x1710,
-};
-
enum rsc_grp {
EE_MGR_RSC_GRP = 1 << 10,
EE_NGD_2 = 2 << 6,
@@ -245,6 +288,7 @@
bool chan_active;
enum msm_ctrl_state state;
int nsats;
+ u32 ver;
};
struct msm_sat_chan {
@@ -509,13 +553,13 @@
mb();
complete(&dev->reconf);
}
- pstat = readl_relaxed(dev->base + PGD_PORT_INT_ST_EEn + (16 * dev->ee));
+ pstat = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_ST_EEn, dev->ver));
if (pstat != 0) {
int i = 0;
for (i = dev->pipe_b; i < MSM_SLIM_NPORTS; i++) {
if (pstat & 1 << i) {
- u32 val = readl_relaxed(dev->base +
- PGD_PORT_STATn + (i * 32));
+ u32 val = readl_relaxed(PGD_PORT(PGD_PORT_STATn,
+ i, dev->ver));
if (val & (1 << 19)) {
dev->ctrl.ports[i].err =
SLIM_P_DISCONNECT;
@@ -532,8 +576,8 @@
dev->ctrl.ports[i].err =
SLIM_P_UNDERFLOW;
}
- writel_relaxed(1, dev->base + PGD_PORT_INT_CL_EEn +
- (dev->ee * 16));
+ writel_relaxed(1, PGD_THIS_EE(PGD_PORT_INT_CL_EEn,
+ dev->ver));
}
/*
* Guarantee that port interrupt bit(s) clearing writes go
@@ -612,13 +656,13 @@
static void msm_hw_set_port(struct msm_slim_ctrl *dev, u8 pn)
{
u32 set_cfg = DEF_WATERMARK | DEF_ALIGN | DEF_PACK | ENABLE_PORT;
- u32 int_port = readl_relaxed(dev->base + PGD_PORT_INT_EN_EEn +
- (dev->ee * 16));
- writel_relaxed(set_cfg, dev->base + PGD_PORT_CFGn + (pn * 32));
- writel_relaxed(DEF_BLKSZ, dev->base + PGD_PORT_BLKn + (pn * 32));
- writel_relaxed(DEF_TRANSZ, dev->base + PGD_PORT_TRANn + (pn * 32));
- writel_relaxed((int_port | 1 << pn) , dev->base + PGD_PORT_INT_EN_EEn +
- (dev->ee * 16));
+ u32 int_port = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
+ dev->ver));
+ writel_relaxed(set_cfg, PGD_PORT(PGD_PORT_CFGn, pn, dev->ver));
+ writel_relaxed(DEF_BLKSZ, PGD_PORT(PGD_PORT_BLKn, pn, dev->ver));
+ writel_relaxed(DEF_TRANSZ, PGD_PORT(PGD_PORT_TRANn, pn, dev->ver));
+ writel_relaxed((int_port | 1 << pn) , PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
+ dev->ver));
/* Make sure that port registers are updated before returning */
mb();
}
@@ -645,8 +689,8 @@
}
}
- stat = readl_relaxed(dev->base + PGD_PORT_STATn +
- (32 * (pn + dev->pipe_b)));
+ stat = readl_relaxed(PGD_PORT(PGD_PORT_STATn, (pn + dev->pipe_b),
+ dev->ver));
if (dev->ctrl.ports[pn].flow == SLIM_SRC) {
cfg->destination = dev->bam.hdl;
cfg->source = SPS_DEV_HANDLE_MEM;
@@ -1947,10 +1991,13 @@
clk_set_rate(dev->rclk, SLIM_ROOT_FREQ);
clk_prepare_enable(dev->rclk);
+ dev->ver = readl_relaxed(dev->base);
+ /* Version info in 16 MSbits */
+ dev->ver >>= 16;
/* Component register initialization */
- writel_relaxed(1, dev->base + COMP_CFG);
+ writel_relaxed(1, dev->base + CFG_PORT(COMP_CFG, dev->ver));
writel_relaxed((EE_MGR_RSC_GRP | EE_NGD_2 | EE_NGD_1),
- dev->base + COMP_TRUST_CFG);
+ dev->base + CFG_PORT(COMP_TRUST_CFG, dev->ver));
/*
* Manager register initialization
@@ -2001,15 +2048,16 @@
* ported generic device inside MSM manager
*/
mb();
- writel_relaxed(1, dev->base + PGD_CFG);
- writel_relaxed(0x3F<<17, dev->base + (PGD_OWN_EEn + (4 * dev->ee)));
+ writel_relaxed(1, dev->base + CFG_PORT(PGD_CFG, dev->ver));
+ writel_relaxed(0x3F<<17, dev->base + CFG_PORT(PGD_OWN_EEn, dev->ver) +
+ (4 * dev->ee));
/*
* Make sure that ported generic device is enabled and port-EE settings
* are written through before finally enabling the component
*/
mb();
- writel_relaxed(1, dev->base + COMP_CFG);
+ writel_relaxed(1, dev->base + CFG_PORT(COMP_CFG, dev->ver));
/*
* Make sure that all writes have gone through before exiting this
* function
@@ -2026,7 +2074,7 @@
return 0;
err_ctrl_failed:
- writel_relaxed(0, dev->base + COMP_CFG);
+ writel_relaxed(0, dev->base + CFG_PORT(COMP_CFG, dev->ver));
err_clk_get_failed:
kfree(dev->satd);
err_request_irq_failed:
diff --git a/drivers/staging/qcache/fmem.c b/drivers/staging/qcache/fmem.c
index acca6f1..4250ff5 100644
--- a/drivers/staging/qcache/fmem.c
+++ b/drivers/staging/qcache/fmem.c
@@ -223,6 +223,9 @@
{
int ret = 0;
+ if (fmem_state == FMEM_UNINITIALIZED)
+ return NOTIFY_OK;
+
switch (action) {
case MEM_ONLINE:
fmem_mem_online_callback(arg);
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 9a8d552..285d1de 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -141,6 +141,16 @@
return UART_TO_MSM(port)->is_uartdm;
}
+static int get_line(struct platform_device *pdev)
+{
+ const struct msm_serial_hslite_platform_data *pdata =
+ pdev->dev.platform_data;
+ if (pdata)
+ return pdata->line;
+
+ return pdev->id;
+}
+
static int clk_en(struct uart_port *port, int enable)
{
struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
@@ -1243,7 +1253,7 @@
struct uart_port *port;
struct platform_device *pdev = to_platform_device(dev);
- port = get_port_from_line(pdev->id);
+ port = get_port_from_line(get_line(pdev));
enable = get_console_state(port);
@@ -1264,7 +1274,7 @@
struct uart_port *port;
struct platform_device *pdev = to_platform_device(dev);
- port = get_port_from_line(pdev->id);
+ port = get_port_from_line(get_line(pdev));
cur_state = get_console_state(port);
enable = buf[0] - '0';
@@ -1332,12 +1342,12 @@
if (pdev->id == -1)
pdev->id = atomic_inc_return(&msm_serial_hsl_next_id) - 1;
- if (unlikely(pdev->id < 0 || pdev->id >= UART_NR))
+ if (unlikely(get_line(pdev) < 0 || get_line(pdev) >= UART_NR))
return -ENXIO;
printk(KERN_INFO "msm_serial_hsl: detected port #%d\n", pdev->id);
- port = get_port_from_line(pdev->id);
+ port = get_port_from_line(get_line(pdev));
port->dev = &pdev->dev;
msm_hsl_port = UART_TO_MSM(port);
@@ -1395,7 +1405,7 @@
if (unlikely(ret))
pr_err("%s():Can't create console attribute\n", __func__);
#endif
- msm_hsl_debugfs_init(msm_hsl_port, pdev->id);
+ msm_hsl_debugfs_init(msm_hsl_port, get_line(pdev));
/* Temporarily increase the refcount on the GSBI clock to avoid a race
* condition with the earlyprintk handover mechanism.
@@ -1413,7 +1423,7 @@
struct msm_hsl_port *msm_hsl_port = platform_get_drvdata(pdev);
struct uart_port *port;
- port = get_port_from_line(pdev->id);
+ port = get_port_from_line(get_line(pdev));
#ifdef CONFIG_SERIAL_MSM_HSL_CONSOLE
device_remove_file(&pdev->dev, &dev_attr_console);
#endif
@@ -1436,7 +1446,7 @@
{
struct platform_device *pdev = to_platform_device(dev);
struct uart_port *port;
- port = get_port_from_line(pdev->id);
+ port = get_port_from_line(get_line(pdev));
if (port) {
@@ -1455,7 +1465,7 @@
{
struct platform_device *pdev = to_platform_device(dev);
struct uart_port *port;
- port = get_port_from_line(pdev->id);
+ port = get_port_from_line(get_line(pdev));
if (port) {
@@ -1478,7 +1488,7 @@
{
struct platform_device *pdev = to_platform_device(dev);
struct uart_port *port;
- port = get_port_from_line(pdev->id);
+ port = get_port_from_line(get_line(pdev));
dev_dbg(dev, "pm_runtime: suspending\n");
msm_hsl_deinit_clock(port);
@@ -1489,7 +1499,7 @@
{
struct platform_device *pdev = to_platform_device(dev);
struct uart_port *port;
- port = get_port_from_line(pdev->id);
+ port = get_port_from_line(get_line(pdev));
dev_dbg(dev, "pm_runtime: resuming\n");
msm_hsl_init_clock(port);
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index ee44846..3e5c6f1 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -183,6 +183,12 @@
.bConfigurationValue = 1,
};
+enum android_device_state {
+ USB_DISCONNECTED,
+ USB_CONNECTED,
+ USB_CONFIGURED,
+};
+
static void android_work(struct work_struct *data)
{
struct android_dev *dev = container_of(data, struct android_dev, work);
@@ -191,18 +197,45 @@
char *connected[2] = { "USB_STATE=CONNECTED", NULL };
char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
char **uevent_envp = NULL;
+ static enum android_device_state last_uevent, next_state;
unsigned long flags;
spin_lock_irqsave(&cdev->lock, flags);
- if (cdev->config)
+ if (cdev->config) {
uevent_envp = configured;
- else if (dev->connected != dev->sw_connected)
+ next_state = USB_CONFIGURED;
+ } else if (dev->connected != dev->sw_connected) {
uevent_envp = dev->connected ? connected : disconnected;
+ next_state = dev->connected ? USB_CONNECTED : USB_DISCONNECTED;
+ }
dev->sw_connected = dev->connected;
spin_unlock_irqrestore(&cdev->lock, flags);
if (uevent_envp) {
+ /*
+ * Some userspace modules, e.g. MTP, work correctly only if
+ * CONFIGURED uevent is preceded by DISCONNECT uevent.
+ * Check if we missed sending out a DISCONNECT uevent. This can
+ * happen if host PC resets and configures device really quick.
+ */
+ if (((uevent_envp == connected) &&
+ (last_uevent != USB_DISCONNECTED)) ||
+ ((uevent_envp == configured) &&
+ (last_uevent == USB_CONFIGURED))) {
+ pr_info("%s: sent missed DISCONNECT event\n", __func__);
+ kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
+ disconnected);
+ msleep(20);
+ }
+ /*
+ * Before sending out CONFIGURED uevent give function drivers
+ * a chance to wakeup userspace threads and notify disconnect
+ */
+ if (uevent_envp == configured)
+ msleep(50);
+
kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp);
+ last_uevent = next_state;
pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]);
} else {
pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 90702f3..eec600e 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -18,6 +18,9 @@
/* #define DEBUG */
#define DEV_DBG_PREFIX "EXT_COMMON: "
+/* The start of the data block collection within the CEA Extension Version 3 */
+#define DBC_START_OFFSET 4
+
#include "msm_fb.h"
#include "hdmi_msm.h"
#include "external_common.h"
@@ -317,6 +320,18 @@
return ret;
}
+static ssize_t hdmi_common_rda_edid_scan_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = snprintf(buf, PAGE_SIZE, "%d, %d, %d\n",
+ external_common_state->pt_scan_info,
+ external_common_state->it_scan_info,
+ external_common_state->ce_scan_info);
+ DEV_DBG("%s: '%s'\n", __func__, buf);
+
+ return ret;
+}
+
static ssize_t hdmi_common_rda_hdcp(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -681,6 +696,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(scan_info, S_IRUGO,
+ hdmi_common_rda_edid_scan_info, NULL);
static DEVICE_ATTR(3d_present, S_IRUGO, hdmi_common_rda_3d_present, NULL);
static DEVICE_ATTR(hdcp_present, S_IRUGO, hdmi_common_rda_hdcp_present, NULL);
#endif
@@ -699,6 +716,7 @@
&dev_attr_edid_modes.attr,
&dev_attr_hdcp.attr,
&dev_attr_hpd.attr,
+ &dev_attr_scan_info.attr,
&dev_attr_3d_present.attr,
&dev_attr_hdcp_present.attr,
#endif
@@ -926,11 +944,12 @@
31500, 60000, 108108, 60000, TRUE},
};
-static const uint8 *hdmi_edid_find_block(const uint8 *in_buf, uint8 type,
- uint8 *len)
+static const uint8 *hdmi_edid_find_block(const uint8 *in_buf,
+ uint32 start_offset, uint8 type, uint8 *len)
{
/* the start of data block collection, start of Video Data Block */
- uint32 offset = 4;
+ uint32 offset = start_offset;
+ uint32 end_dbc_offset = in_buf[2];
*len = 0;
@@ -938,11 +957,11 @@
present.
edid buffer 1, byte 2 being 0 menas no non-DTD/DATA block collection
present and no DTD data present.*/
- if ((in_buf[2] == 0) || (in_buf[2] == 4)) {
+ if ((end_dbc_offset == 0) || (end_dbc_offset == 4)) {
DEV_WARN("EDID: no DTD or non-DTD data present\n");
return NULL;
}
- while (offset < 0x80) {
+ while (offset < end_dbc_offset) {
uint8 block_len = in_buf[offset] & 0x1F;
if ((in_buf[offset] >> 5) == type) {
*len = block_len;
@@ -970,7 +989,8 @@
static uint32 hdmi_edid_extract_ieee_reg_id(const uint8 *in_buf)
{
uint8 len;
- const uint8 *vsd = hdmi_edid_find_block(in_buf, 3, &len);
+ const uint8 *vsd = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 3,
+ &len);
if (vsd == NULL)
return 0;
@@ -983,7 +1003,8 @@
static void hdmi_edid_extract_3d_present(const uint8 *in_buf)
{
uint8 len, offset;
- const uint8 *vsd = hdmi_edid_find_block(in_buf, 3, &len);
+ const uint8 *vsd = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 3,
+ &len);
external_common_state->present_3d = 0;
if (vsd == NULL || len < 9) {
@@ -1003,7 +1024,8 @@
static void hdmi_edid_extract_latency_fields(const uint8 *in_buf)
{
uint8 len;
- const uint8 *vsd = hdmi_edid_find_block(in_buf, 3, &len);
+ const uint8 *vsd = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 3,
+ &len);
if (vsd == NULL || len < 12 || !(vsd[8] & BIT(7))) {
external_common_state->video_latency = (uint16)-1;
@@ -1021,7 +1043,8 @@
static void hdmi_edid_extract_speaker_allocation_data(const uint8 *in_buf)
{
uint8 len;
- const uint8 *sad = hdmi_edid_find_block(in_buf, 4, &len);
+ const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 4,
+ &len);
if (sad == NULL)
return;
@@ -1041,7 +1064,8 @@
static void hdmi_edid_extract_audio_data_blocks(const uint8 *in_buf)
{
uint8 len;
- const uint8 *sad = hdmi_edid_find_block(in_buf, 1, &len);
+ const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 1,
+ &len);
uint32 *adb = external_common_state->audio_data_blocks;
if (sad == NULL)
@@ -1060,6 +1084,63 @@
}
}
+static void hdmi_edid_extract_extended_data_blocks(const uint8 *in_buf)
+{
+ uint8 len = 0;
+ uint8 const *prev_etag = in_buf;
+ uint32 start_offset = DBC_START_OFFSET;
+
+ /* A Tage code of 7 identifies extended data blocks */
+ uint8 const *etag = hdmi_edid_find_block(in_buf, start_offset, 7, &len);
+
+ while (etag != NULL) {
+ /* The extended data block should at least be 2 bytes long */
+ if (len < 2) {
+ DEV_DBG("EDID: Found an extended data block of length"
+ "less than 2 bytes. Ignoring ...\n");
+ } else {
+ /*
+ * The second byte of the extended data block has the
+ * extended tag code
+ */
+ switch (etag[1]) {
+ case 0:
+ /* Video Capability Data Block */
+ DEV_DBG("EDID: VCDB=%02X %02X\n", etag[1],
+ etag[2]);
+
+ /*
+ * Check if the sink specifies underscan
+ * support for:
+ * BIT 5: preferred video format
+ * BIT 3: IT video format
+ * BIT 1: CE video format
+ */
+ external_common_state->pt_scan_info = (etag[2] &
+ (BIT(4) | BIT(5))) >> 4;
+ external_common_state->it_scan_info = (etag[2] &
+ (BIT(3) | BIT(2))) >> 2;
+ external_common_state->ce_scan_info = etag[2] &
+ (BIT(1) | BIT(0));
+ DEV_DBG("EDID: Scan Information (pt|it|ce): "
+ "(%d|%d|%d)",
+ external_common_state->pt_scan_info,
+ external_common_state->it_scan_info,
+ external_common_state->ce_scan_info);
+ break;
+ default:
+ DEV_DBG("EDID: Extend Tag Code %d not"
+ "supported\n", etag[1]);
+ break;
+ }
+ }
+
+ /* There could be more that one extended data block */
+ start_offset = etag - prev_etag + len + 1;
+ prev_etag = etag;
+ etag = hdmi_edid_find_block(in_buf, start_offset, 7, &len);
+ }
+}
static void hdmi_edid_detail_desc(const uint8 *data_buf, uint32 *disp_mode)
{
@@ -1204,7 +1285,8 @@
const uint8 *edid_blk0 = &data_buf[0x0];
const uint8 *edid_blk1 = &data_buf[0x80];
const uint8 *svd = num_og_cea_blocks ?
- hdmi_edid_find_block(data_buf+0x80, 2, &len) : NULL;
+ hdmi_edid_find_block(data_buf+0x80, DBC_START_OFFSET,
+ 2, &len) : NULL;
disp_mode_list->num_of_elements = 0;
if (svd != NULL) {
@@ -1216,6 +1298,11 @@
video_format = (*svd & 0x7F) - 1;
add_supported_video_format(disp_mode_list,
video_format);
+ /* Make a note of the preferred video format */
+ if (i == 0) {
+ external_common_state->preferred_video_format =
+ video_format;
+ }
if (video_format == HDMI_VFRMT_640x480p60_4_3)
has480p = TRUE;
}
@@ -1238,6 +1325,11 @@
video_format);
if (video_format == HDMI_VFRMT_640x480p60_4_3)
has480p = TRUE;
+ /* Make a note of the preferred video format */
+ if (i == 0) {
+ external_common_state->preferred_video_format =
+ video_format;
+ }
desc_offset += 0x12;
++i;
}
@@ -1258,6 +1350,11 @@
video_format);
if (video_format == HDMI_VFRMT_640x480p60_4_3)
has480p = TRUE;
+ /* Make a note of the preferred video format */
+ if (i == 0) {
+ external_common_state->preferred_video_format =
+ video_format;
+ }
desc_offset += 0x12;
++i;
}
@@ -1281,6 +1378,11 @@
video_format);
if (video_format == HDMI_VFRMT_640x480p60_4_3)
has480p = TRUE;
+ /* Make a note of the preferred video format */
+ if (i == 0) {
+ external_common_state->preferred_video_format =
+ video_format;
+ }
desc_offset += 0x12;
++i;
}
@@ -1359,6 +1461,7 @@
/* EDID_BLOCK_SIZE[0x80] Each page size in the EDID ROM */
uint8 edid_buf[0x80 * 4];
+ external_common_state->preferred_video_format = 0;
external_common_state->present_3d = 0;
memset(&external_common_state->disp_mode_list, 0,
sizeof(external_common_state->disp_mode_list));
@@ -1410,6 +1513,7 @@
edid_buf+0x80);
hdmi_edid_extract_audio_data_blocks(edid_buf+0x80);
hdmi_edid_extract_3d_present(edid_buf+0x80);
+ hdmi_edid_extract_extended_data_blocks(edid_buf+0x80);
}
break;
case 2:
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index c9ab88e..c6dfeb1 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -216,6 +216,10 @@
uint8 speaker_allocation_block;
uint16 video_latency, audio_latency;
uint8 audio_data_block_cnt;
+ uint32 preferred_video_format;
+ uint8 pt_scan_info;
+ uint8 it_scan_info;
+ uint8 ce_scan_info;
boolean present_3d;
boolean present_hdcp;
uint32 audio_data_blocks[16];
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 1ea6403..30ce90b 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -3675,6 +3675,7 @@
uint32 regVal;
int i;
int mode = 0;
+ boolean use_ce_scan_info = TRUE;
switch (external_common_state->video_resolution) {
case HDMI_VFRMT_720x480p60_4_3:
@@ -3740,6 +3741,48 @@
/* Data Byte 01: 0 Y1 Y0 A0 B1 B0 S1 S0 */
aviInfoFrame[3] = hdmi_msm_avi_iframe_lut[0][mode];
+
+ /*
+ * If the sink specified support for both underscan/overscan
+ * then, by default, set the underscan bit.
+ * Only checking underscan support for preferred format and cea formats
+ */
+ if ((external_common_state->video_resolution ==
+ external_common_state->preferred_video_format)) {
+ use_ce_scan_info = FALSE;
+ switch (external_common_state->pt_scan_info) {
+ case 0:
+ /*
+ * Need to use the info specified for the corresponding
+ * IT or CE format
+ */
+ DEV_DBG("%s: No underscan information specified for the"
+ " preferred video format\n", __func__);
+ use_ce_scan_info = TRUE;
+ break;
+ case 3:
+ DEV_DBG("%s: Setting underscan bit for the preferred"
+ " video format\n", __func__);
+ aviInfoFrame[3] |= 0x02;
+ break;
+ default:
+ DEV_DBG("%s: Underscan information not set for the"
+ " preferred video format\n", __func__);
+ break;
+ }
+ }
+
+ if (use_ce_scan_info) {
+ if (3 == external_common_state->ce_scan_info) {
+ DEV_DBG("%s: Setting underscan bit for the CE video"
+ " format\n", __func__);
+ aviInfoFrame[3] |= 0x02;
+ } else {
+ DEV_DBG("%s: Not setting underscan bit for the CE video"
+ " format\n", __func__);
+ }
+ }
+
/* Data Byte 02: C1 C0 M1 M0 R3 R2 R1 R0 */
aviInfoFrame[4] = hdmi_msm_avi_iframe_lut[1][mode];
/* Data Byte 03: ITC EC2 EC1 EC0 Q1 Q0 SC1 SC0 */
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e.c b/drivers/video/msm/mipi_truly_tft540960_1_e.c
index 937a598..30e255e 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e.c
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e.c
@@ -59,7 +59,7 @@
/* add 0X BD command */
static char cmd26_2[6] = {
- 0xBD, 0x01, 0x60, 0x10, 0x38, 0x01 /* 55 HZ */
+ 0xBD, 0x01, 0x48, 0x10, 0x38, 0x01 /* 59 HZ */
};
static char cmd5[5] = {
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c b/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c
index 82efbef..b3805c5 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c
@@ -64,7 +64,7 @@
pinfo.lcd.vsync_enable = TRUE;
pinfo.lcd.hw_vsync_mode = TRUE;
- pinfo.lcd.refx100 = 6000; /* adjust refx100 to prevent tearing */
+ pinfo.lcd.refx100 = 6100; /* adjust refx100 to prevent tearing */
pinfo.mipi.mode = DSI_CMD_MODE;
pinfo.mipi.dst_format = DSI_CMD_DST_FORMAT_RGB888;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 56e8438..aa54b71 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -25,7 +25,7 @@
#define MSMFB_RESUME_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 129, unsigned int)
#define MSMFB_CURSOR _IOW(MSMFB_IOCTL_MAGIC, 130, struct fb_cursor)
#define MSMFB_SET_LUT _IOW(MSMFB_IOCTL_MAGIC, 131, struct fb_cmap)
-#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram)
+#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram_data)
/* new ioctls's for set/get ccs matrix */
#define MSMFB_GET_CCS_MATRIX _IOWR(MSMFB_IOCTL_MAGIC, 133, struct mdp_ccs)
#define MSMFB_SET_CCS_MATRIX _IOW(MSMFB_IOCTL_MAGIC, 134, struct mdp_ccs)
@@ -44,8 +44,9 @@
#define MSMFB_OVERLAY_BLT _IOWR(MSMFB_IOCTL_MAGIC, 142, \
struct msmfb_overlay_blt)
#define MSMFB_OVERLAY_BLT_OFFSET _IOW(MSMFB_IOCTL_MAGIC, 143, unsigned int)
-#define MSMFB_HISTOGRAM_START _IO(MSMFB_IOCTL_MAGIC, 144)
-#define MSMFB_HISTOGRAM_STOP _IO(MSMFB_IOCTL_MAGIC, 145)
+#define MSMFB_HISTOGRAM_START _IOR(MSMFB_IOCTL_MAGIC, 144, \
+ struct mdp_histogram_start_req)
+#define MSMFB_HISTOGRAM_STOP _IOR(MSMFB_IOCTL_MAGIC, 145, unsigned int)
#define MSMFB_NOTIFY_UPDATE _IOW(MSMFB_IOCTL_MAGIC, 146, unsigned int)
#define MSMFB_OVERLAY_3D _IOWR(MSMFB_IOCTL_MAGIC, 147, \
@@ -328,6 +329,32 @@
MDP_BLOCK_MAX,
};
+/*
+ * mdp_histogram_start_req is used to provide the parameters for
+ * histogram start request
+ */
+
+struct mdp_histogram_start_req {
+ uint32_t block;
+ uint8_t frame_cnt;
+ uint8_t bit_mask;
+ uint8_t num_bins;
+};
+
+/*
+ * mdp_histogram_data is used to return the histogram data, once
+ * the histogram is done/stopped/cance
+ */
+
+struct mdp_histogram_data {
+ uint32_t block;
+ uint8_t bin_cnt;
+ uint32_t *c0;
+ uint32_t *c1;
+ uint32_t *c2;
+ uint32_t extra_info[2];
+};
+
struct mdp_pcc_coeff {
uint32_t c, r, g, b, rr, gg, bb, rg, gb, rb, rgb_0, rgb_1;
};
diff --git a/include/media/gpio-ir-recv.h b/include/media/gpio-ir-recv.h
index 3eab611..61a7fbb 100644
--- a/include/media/gpio-ir-recv.h
+++ b/include/media/gpio-ir-recv.h
@@ -16,7 +16,6 @@
struct gpio_ir_recv_platform_data {
unsigned int gpio_nr;
bool active_low;
- bool can_wakeup;
};
#endif /* __GPIO_IR_RECV_H__ */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 739b04c..47b6d4d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5465,7 +5465,9 @@
} else if ((pi->amp_move_state !=
L2CAP_AMP_STATE_WAIT_MOVE_RSP_SUCCESS) &&
(pi->amp_move_state !=
- L2CAP_AMP_STATE_WAIT_MOVE_CONFIRM)) {
+ L2CAP_AMP_STATE_WAIT_MOVE_CONFIRM) &&
+ (pi->amp_move_state !=
+ L2CAP_AMP_STATE_WAIT_MOVE_CONFIRM_RSP)) {
/* Move was not in expected state, free the channel */
ampchan = pi->ampchan;
ampcon = pi->ampcon;
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 2c43792..74e2dc0 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -3591,6 +3591,7 @@
ret = wcd9xxx_close_slim_sch_rx(tabla,
tabla_p->dai[j].ch_num,
tabla_p->dai[j].ch_tot);
+ usleep_range(5000, 5000);
tabla_p->dai[j].rate = 0;
memset(tabla_p->dai[j].ch_num, 0, (sizeof(u32)*
tabla_p->dai[j].ch_tot));