Merge "bluetooth: 8960: adding tasklets to read from SMD driver" into msm-3.0
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index eb9b463..b2dbee3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -134,6 +134,15 @@
default y
depends on SMP && PREEMPT
+config ARM_TICKET_LOCKS
+ bool
+ help
+ Enable ticket locks, which help preserve fairness among
+ contended locks and prevent livelock in multicore systems.
+ Say 'y' if system stability is important.
+ default y if ARCH_MSM_SCORPIONMP
+ depends on SMP
+
config RWSEM_GENERIC_SPINLOCK
bool
default y
@@ -1350,7 +1359,7 @@
ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
MSM_SMP || ARCH_SHMOBILE
select USE_GENERIC_SMP_HELPERS
- select HAVE_ARM_SCU if !MSM_SMP
+ select HAVE_ARM_SCU
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -2146,7 +2155,7 @@
source "kernel/power/Kconfig"
config ARCH_SUSPEND_POSSIBLE
- depends on !ARCH_S5P64X0 && !ARCH_S5PC100 && !ARCH_FSM9XXX && !ARCH_MSM9615
+ depends on !ARCH_S5P64X0 && !ARCH_S5PC100 && !ARCH_FSM9XXX
depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE
def_bool y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 11821ee..8be0165 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -17,7 +17,7 @@
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+CONFIG_OPROFILE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
@@ -52,7 +52,7 @@
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
-# CONFIG_CP_ACCESS is not set
+CONFIG_CP_ACCESS=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 827d5d9..ed4fd41 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -16,7 +16,7 @@
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+CONFIG_OPROFILE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
@@ -51,7 +51,7 @@
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
-# CONFIG_CP_ACCESS is not set
+CONFIG_CP_ACCESS=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 2cd7953..5577fd8 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -319,7 +319,7 @@
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
CONFIG_FB_MSM_OVERLAY_WRITEBACK=y
-CONFIG_FB_MSM_LCDC_PANEL_AUTO_DETECT=y
+CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 705021a..2dc6b36 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -310,7 +310,7 @@
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
CONFIG_FB_MSM_OVERLAY_WRITEBACK=y
-CONFIG_FB_MSM_LCDC_PANEL_AUTO_DETECT=y
+CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 2f512c5..ddbe87c 100755
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -59,6 +59,7 @@
CONFIG_MSM_WCNSS_SSR_8960=y
CONFIG_MSM_RPM_LOG=y
CONFIG_MSM_BUS_SCALING=y
+CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED=y
CONFIG_MSM_WATCHDOG=y
CONFIG_MSM_DLOAD_MODE=y
CONFIG_MSM_QDSS=y
@@ -214,6 +215,7 @@
CONFIG_SMC91X=y
CONFIG_SMC911X=y
CONFIG_SMSC911X=y
+CONFIG_KS8851=m
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
CONFIG_WCNSS_CORE=m
@@ -283,6 +285,7 @@
CONFIG_FB_VIRTUAL=y
CONFIG_FB_MSM=y
# CONFIG_FB_MSM_BACKLIGHT is not set
+CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
CONFIG_FB_MSM_OVERLAY_WRITEBACK=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 2dbdb8f..52a4d20 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -53,6 +53,7 @@
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_IDLE=y
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
@@ -61,6 +62,7 @@
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
+CONFIG_PM=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_MISC_DEVICES=y
@@ -98,6 +100,39 @@
CONFIG_REGULATOR=y
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_CLKGATE is not set
+CONFIG_MMC_EMBEDDED_SDIO=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SDIO_SUPPORT=y
+# CONFIG_MMC_MSM_CARD_HW_DETECTION is not set
+CONFIG_MMC_MSM_SDC1_SUPPORT=y
+# CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT is not set
+CONFIG_MMC_MSM_SDC2_SUPPORT=y
+# CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT is not set
+# CONFIG_MMC_MSM_SDC3_SUPPORT is not set
+# CONFIG_MMC_MSM_SDC4_SUPPORT is not set
+# CONFIG_MMC_MSM_SDC5_SUPPORT is not set
+# CONFIG_MMC_MSM_SPS_SUPPORT is not set
CONFIG_MSM_SSBI=y
CONFIG_SPS=y
CONFIG_SPS_SUPPORT_BAMDMA=y
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index 89ad180..2635c8b 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -5,7 +5,7 @@
#include <linux/threads.h>
#include <asm/irq.h>
-#define NR_IPI 5
+#define NR_IPI 6
typedef struct {
unsigned int __softirq_pending;
diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h
index 65fa3c8..582c9b3 100644
--- a/arch/arm/include/asm/spinlock.h
+++ b/arch/arm/include/asm/spinlock.h
@@ -58,6 +58,7 @@
#endif
}
+#ifndef CONFIG_ARM_TICKET_LOCKS
/*
* ARMv6 Spin-locking.
*
@@ -126,6 +127,131 @@
dsb_sev();
}
+#else
+/*
+ * ARM Ticket spin-locking
+ *
+ * Ticket locks are conceptually two parts, one indicating the current head of
+ * the queue, and the other indicating the current tail. The lock is acquired
+ * by atomically noting the tail and incrementing it by one (thus adding
+ * ourself to the queue and noting our position), then waiting until the head
+ * becomes equal to the the initial value of the tail.
+ *
+ * Unlocked value: 0
+ * Locked value: now_serving != next_ticket
+ *
+ * 31 17 16 15 14 0
+ * +----------------------------------------------------+
+ * | now_serving | next_ticket |
+ * +----------------------------------------------------+
+ */
+
+#define TICKET_SHIFT 16
+#define TICKET_BITS 16
+#define TICKET_MASK 0xFFFF
+
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+
+static inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+ unsigned long tmp, ticket, next_ticket;
+
+ /* Grab the next ticket and wait for it to be "served" */
+ __asm__ __volatile__(
+"1: ldrex %[ticket], [%[lockaddr]]\n"
+" uadd16 %[next_ticket], %[ticket], %[val1]\n"
+" strex %[tmp], %[next_ticket], [%[lockaddr]]\n"
+" teq %[tmp], #0\n"
+" bne 1b\n"
+" uxth %[ticket], %[ticket]\n"
+"2:\n"
+#ifdef CONFIG_CPU_32v6K
+" wfene\n"
+#endif
+" ldr %[tmp], [%[lockaddr]]\n"
+" cmp %[ticket], %[tmp], lsr #16\n"
+" bne 2b"
+ : [ticket]"=&r" (ticket), [tmp]"=&r" (tmp), [next_ticket]"=&r" (next_ticket)
+ : [lockaddr]"r" (&lock->lock), [val1]"r" (1)
+ : "cc");
+ smp_mb();
+}
+
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
+{
+ unsigned long tmp, ticket, next_ticket;
+
+ /* Grab lock if now_serving == next_ticket and access is exclusive */
+ __asm__ __volatile__(
+" ldrex %[ticket], [%[lockaddr]]\n"
+" ror %[tmp], %[ticket], #16\n"
+" eors %[tmp], %[tmp], %[ticket]\n"
+" bne 1f\n"
+" uadd16 %[next_ticket], %[ticket], %[val1]\n"
+" strex %[tmp], %[next_ticket], [%[lockaddr]]\n"
+"1:"
+ : [ticket]"=&r" (ticket), [tmp]"=&r" (tmp),
+ [next_ticket]"=&r" (next_ticket)
+ : [lockaddr]"r" (&lock->lock), [val1]"r" (1)
+ : "cc");
+ if (!tmp)
+ smp_mb();
+ return !tmp;
+}
+
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+ unsigned long ticket, tmp;
+
+ smp_mb();
+
+ /* Bump now_serving by 1 */
+ __asm__ __volatile__(
+"1: ldrex %[ticket], [%[lockaddr]]\n"
+" uadd16 %[ticket], %[ticket], %[serving1]\n"
+" strex %[tmp], %[ticket], [%[lockaddr]]\n"
+" teq %[tmp], #0\n"
+" bne 1b"
+ : [ticket]"=&r" (ticket), [tmp]"=&r" (tmp)
+ : [lockaddr]"r" (&lock->lock), [serving1]"r" (0x00010000)
+ : "cc");
+ dsb_sev();
+}
+
+static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
+{
+ unsigned long ticket;
+
+ /* Wait for now_serving == next_ticket */
+ __asm__ __volatile__(
+#ifdef CONFIG_CPU_32v6K
+" cmpne %[lockaddr], %[lockaddr]\n"
+"1: wfene\n"
+#else
+"1:\n"
+#endif
+" ldr %[ticket], [%[lockaddr]]\n"
+" eor %[ticket], %[ticket], %[ticket], lsr #16\n"
+" uxth %[ticket], %[ticket]\n"
+" cmp %[ticket], #0\n"
+" bne 1b"
+ : [ticket]"=&r" (ticket)
+ : [lockaddr]"r" (&lock->lock)
+ : "cc");
+}
+
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
+{
+ unsigned long tmp = ACCESS_ONCE(lock->lock);
+ return (((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK) != 0;
+}
+
+static inline int arch_spin_is_contended(arch_spinlock_t *lock)
+{
+ unsigned long tmp = ACCESS_ONCE(lock->lock);
+ return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1;
+}
+#endif
/*
* RWLOCKS
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index a9d1a5c..5478f55 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -48,6 +48,7 @@
struct secondary_data secondary_data;
enum ipi_msg_type {
+ IPI_CPU_START = 1,
IPI_TIMER = 2,
IPI_RESCHEDULE,
IPI_CALL_FUNC,
@@ -399,7 +400,8 @@
}
static const char *ipi_types[NR_IPI] = {
-#define S(x,s) [x - IPI_TIMER] = s
+#define S(x,s) [x - IPI_CPU_START] = s
+ S(IPI_CPU_START, "CPU start interrupts"),
S(IPI_TIMER, "Timer broadcast interrupts"),
S(IPI_RESCHEDULE, "Rescheduling interrupts"),
S(IPI_CALL_FUNC, "Function call interrupts"),
@@ -563,10 +565,13 @@
unsigned int cpu = smp_processor_id();
struct pt_regs *old_regs = set_irq_regs(regs);
- if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
- __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
+ if (ipinr >= IPI_CPU_START && ipinr < IPI_CPU_START + NR_IPI)
+ __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_CPU_START]);
switch (ipinr) {
+ case IPI_CPU_START:
+ /* Wake up from WFI/WFE using SGI */
+ break;
case IPI_TIMER:
ipi_timer();
break;
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 1e5f485..2acc8e0 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -134,6 +134,15 @@
select MSM_NATIVE_RESTART
select DONT_MAP_HOLE_AFTER_MEMBANK0
select MSM_REMOTE_SPINLOCK_SFPB
+ select ARCH_POPULATES_NODE_MAP
+ select ARCH_SPARSEMEM_ENABLE
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select MEMORY_HOTPLUG
+ select MEMORY_HOTREMOVE
+ select MIGRATION
+ select ARCH_MEMORY_PROBE
+ select ARCH_MEMORY_REMOVE
+ select DONT_RESERVE_FROM_MOVABLE_ZONE
config ARCH_APQ8064
bool "APQ8064"
@@ -887,13 +896,6 @@
prompt "Package 4"
endchoice
-config MSM_IPC_ROUTER_SMD_XPRT
- depends on MSM_SMD
- default n
- bool "MSM SMD XPRT Layer"
- help
- SMD Transport Layer for IPC Router
-
config MSM_RPC_SDIO_XPRT
depends on MSM_SDIO_AL
default y
@@ -1055,13 +1057,21 @@
the ARM9 and ARM11
config MSM_IPC_ROUTER
- depends on MSM_IPC_ROUTER_SMD_XPRT
+ depends on NET
default n
bool "MSM IPC Router support"
help
Support for the MSM IPC Router for communication between
the APPs and the MODEM
+config MSM_IPC_ROUTER_SMD_XPRT
+ depends on MSM_SMD
+ depends on MSM_IPC_ROUTER
+ default n
+ bool "MSM SMD XPRT Layer"
+ help
+ SMD Transport Layer for IPC Router
+
config MSM_ONCRPCROUTER_DEBUG
depends on MSM_ONCRPCROUTER
default y
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index a469e7d..e81bdcd 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -130,6 +130,7 @@
ifdef CONFIG_PM
obj-$(CONFIG_ARCH_MSM8960) += pm-8x60.o
obj-$(CONFIG_ARCH_MSM8X60) += pm-8x60.o
+ obj-$(CONFIG_ARCH_MSM9615) += pm-8x60.o
obj-$(CONFIG_ARCH_QSD8X50) += pm2.o
obj-$(CONFIG_ARCH_MSM7X30) += pm2.o
obj-$(CONFIG_ARCH_MSM7X27) += pm2.o
@@ -174,6 +175,7 @@
ifdef CONFIG_CPU_IDLE
obj-$(CONFIG_ARCH_MSM8960) += cpuidle.o
obj-$(CONFIG_ARCH_MSM8X60) += cpuidle.o
+ obj-$(CONFIG_ARCH_MSM9615) += cpuidle.o
endif
obj-$(CONFIG_ARCH_FSM9XXX) += devices-fsm9xxx.o
@@ -216,7 +218,7 @@
obj-$(CONFIG_ARCH_MSM8960) += bms-batterydata.o
obj-$(CONFIG_ARCH_APQ8064) += board-apq8064.o devices-8064.o board-apq8064-regulator.o
obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o
-obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o
+obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire-keypad.o board-sapphire-panel.o
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index a5a6ff1..1d0e1a8 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -223,8 +223,6 @@
static struct l2_level *l2_freq_tbl;
static struct acpu_level *acpu_freq_tbl;
static int l2_freq_tbl_size;
-static int cpu_boot_idx;
-static int l2_boot_idx;
/* Instantaneous bandwidth requests in MB/s. */
#define BW_MBPS(_bw) \
@@ -415,10 +413,6 @@
/* Wait for switch to complete. */
mb();
udelay(1);
-
- /* Re-enable secondary source clock gating. */
- regval &= ~SECCLKAGD;
- set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
}
/* Enable an already-configured HFPLL. */
@@ -875,9 +869,11 @@
static void __init per_cpu_init(void *data)
{
+ struct acpu_level *max_acpu_level = data;
int cpu = smp_processor_id();
- init_clock_sources(&scalable[cpu], &acpu_freq_tbl[cpu_boot_idx].speed);
- scalable[cpu].l2_vote = &l2_freq_tbl[l2_boot_idx];
+
+ init_clock_sources(&scalable[cpu], &max_acpu_level->speed);
+ scalable[cpu].l2_vote = max_acpu_level->l2_level;
}
/* Register with bus driver. */
@@ -988,6 +984,35 @@
.notifier_call = acpuclock_cpu_callback,
};
+static struct acpu_level * __init select_freq_plan(void)
+{
+ struct acpu_level *l, *max_acpu_level = NULL;
+
+ /* Select frequency tables. */
+ if (cpu_is_msm8960()) {
+ scalable = scalable_8960;
+ acpu_freq_tbl = acpu_freq_tbl_8960;
+ l2_freq_tbl = l2_freq_tbl_8960;
+ l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8960);
+ } else if (cpu_is_apq8064()) {
+ scalable = scalable_8064;
+ acpu_freq_tbl = acpu_freq_tbl_8064;
+ l2_freq_tbl = l2_freq_tbl_8064;
+ l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8064);
+ } else {
+ BUG();
+ }
+
+ /* Find the max supported scaling frequency. */
+ for (l = acpu_freq_tbl; l->speed.khz != 0; l++)
+ if (l->use_for_scaling)
+ max_acpu_level = l;
+ BUG_ON(!max_acpu_level);
+ pr_info("Max ACPU freq: %u KHz\n", max_acpu_level->speed.khz);
+
+ return max_acpu_level;
+}
+
static struct acpuclk_data acpuclk_8960_data = {
.set_rate = acpuclk_8960_set_rate,
.get_rate = acpuclk_8960_get_rate,
@@ -997,24 +1022,9 @@
static int __init acpuclk_8960_init(struct acpuclk_soc_data *soc_data)
{
- if (cpu_is_msm8960()) {
- scalable = scalable_8960;
- acpu_freq_tbl = acpu_freq_tbl_8960;
- l2_freq_tbl = l2_freq_tbl_8960;
- l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8960);
- l2_boot_idx = 11;
- cpu_boot_idx = 11;
- } else if (cpu_is_apq8064()) {
- scalable = scalable_8064;
- acpu_freq_tbl = acpu_freq_tbl_8064;
- l2_freq_tbl = l2_freq_tbl_8064;
- l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8064);
- l2_boot_idx = 11;
- cpu_boot_idx = 11;
- }
-
- init_clock_sources(&scalable[L2], &l2_freq_tbl[l2_boot_idx].speed);
- on_each_cpu(per_cpu_init, NULL, true);
+ struct acpu_level *max_acpu_level = select_freq_plan();
+ init_clock_sources(&scalable[L2], &max_acpu_level->l2_level->speed);
+ on_each_cpu(per_cpu_init, max_acpu_level, true);
regulator_init();
bus_init();
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 728dbf1..5ed4456 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -201,6 +201,7 @@
rx_skb->data = (unsigned char *)(rx_hdr + 1);
rx_skb->tail = rx_skb->data + rx_hdr->pkt_len;
rx_skb->len = rx_hdr->pkt_len;
+ rx_skb->truesize = rx_hdr->pkt_len + sizeof(struct sk_buff);
event_data = (unsigned long)(rx_skb);
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index ed93c3a..aa6ce58 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -25,6 +25,8 @@
#include "timer.h"
#include "devices.h"
#include "board-9615.h"
+#include "cpuidle.h"
+#include "pm.h"
static struct platform_device *common_devices[] = {
&msm9615_device_dmov,
@@ -415,6 +417,36 @@
#else
static void __init msm9615_init_mmc(void) { }
#endif
+static struct msm_cpuidle_state msm_cstates[] __initdata = {
+ {0, 0, "C0", "WFI",
+ MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
+
+ {0, 1, "C1", "STANDALONE_POWER_COLLAPSE",
+ MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE},
+
+ {0, 2, "C2", "POWER_COLLAPSE",
+ MSM_PM_SLEEP_MODE_POWER_COLLAPSE},
+};
+static struct msm_pm_platform_data msm_pm_data[MSM_PM_SLEEP_MODE_NR] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
+ .idle_supported = 1,
+ .suspend_supported = 1,
+ .idle_enabled = 0,
+ .suspend_enabled = 0,
+ },
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
+ .idle_supported = 1,
+ .suspend_supported = 1,
+ .idle_enabled = 0,
+ .suspend_enabled = 0,
+ },
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
+ .idle_supported = 1,
+ .suspend_supported = 1,
+ .idle_enabled = 1,
+ .suspend_enabled = 1,
+ },
+};
static int __init gpiomux_init(void)
{
@@ -460,6 +492,10 @@
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
msm9615_init_mmc();
+ msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
+ msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
+ msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
+ msm_pm_data);
}
static void __init msm9615_cdp_init(void)
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index 5f205f4..9629b5c 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -58,16 +58,17 @@
#include <linux/android_pmem.h>
#include <mach/camera.h>
+#ifdef CONFIG_USB_G_ANDROID
+#include <linux/usb/android.h>
+#include <mach/usbdiag.h>
+#endif
+
#include "devices.h"
#include "clock.h"
#include "acpuclock.h"
#include "msm-keypad-devices.h"
#include "pm.h"
-#ifdef CONFIG_USB_ANDROID
-#include <linux/usb/android_composite.h>
-#endif
-
#ifdef CONFIG_ARCH_MSM7X25
#define MSM_PMEM_MDP_SIZE 0xb21000
#define MSM_PMEM_ADSP_SIZE 0x97b000
@@ -103,135 +104,16 @@
},
};
-#ifdef CONFIG_USB_FUNCTION
-static struct usb_mass_storage_platform_data usb_mass_storage_pdata = {
- .nluns = 0x02,
- .buf_size = 16384,
- .vendor = "GOOGLE",
- .product = "Mass storage",
- .release = 0xffff,
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
};
-static struct platform_device mass_storage_device = {
- .name = "usb_mass_storage",
- .id = -1,
- .dev = {
- .platform_data = &usb_mass_storage_pdata,
- },
-};
-#endif
-#ifdef CONFIG_USB_ANDROID
-static char *usb_functions_default[] = {
- "diag",
- "modem",
- "nmea",
- "rmnet",
- "usb_mass_storage",
-};
-
-static char *usb_functions_default_adb[] = {
- "diag",
- "adb",
- "modem",
- "nmea",
- "rmnet",
- "usb_mass_storage",
-};
-
-static char *usb_functions_rndis[] = {
- "rndis",
-};
-
-static char *usb_functions_rndis_adb[] = {
- "rndis",
- "adb",
-};
-
-static char *usb_functions_all[] = {
-#ifdef CONFIG_USB_ANDROID_RNDIS
- "rndis",
-#endif
-#ifdef CONFIG_USB_ANDROID_DIAG
- "diag",
-#endif
- "adb",
-#ifdef CONFIG_USB_F_SERIAL
- "modem",
- "nmea",
-#endif
-#ifdef CONFIG_USB_ANDROID_RMNET
- "rmnet",
-#endif
- "usb_mass_storage",
-#ifdef CONFIG_USB_ANDROID_ACM
- "acm",
-#endif
-};
-
-static struct android_usb_product usb_products[] = {
- {
- .product_id = 0x9026,
- .num_functions = ARRAY_SIZE(usb_functions_default),
- .functions = usb_functions_default,
- },
- {
- .product_id = 0x9025,
- .num_functions = ARRAY_SIZE(usb_functions_default_adb),
- .functions = usb_functions_default_adb,
- },
- {
- .product_id = 0xf00e,
- .num_functions = ARRAY_SIZE(usb_functions_rndis),
- .functions = usb_functions_rndis,
- },
- {
- .product_id = 0x9024,
- .num_functions = ARRAY_SIZE(usb_functions_rndis_adb),
- .functions = usb_functions_rndis_adb,
- },
-};
-
-static struct usb_mass_storage_platform_data mass_storage_pdata = {
- .nluns = 1,
- .vendor = "Qualcomm Incorporated",
- .product = "Mass storage",
- .release = 0x0100,
- .can_stall = 1,
-};
-
-static struct platform_device usb_mass_storage_device = {
- .name = "usb_mass_storage",
- .id = -1,
- .dev = {
- .platform_data = &mass_storage_pdata,
- },
-};
-
-static struct usb_ether_platform_data rndis_pdata = {
- /* ethaddr is filled by board_serialno_setup */
- .vendorID = 0x05C6,
- .vendorDescr = "Qualcomm Incorporated",
-};
-
-static struct platform_device rndis_device = {
- .name = "rndis",
- .id = -1,
- .dev = {
- .platform_data = &rndis_pdata,
- },
-};
-
+#ifdef CONFIG_USB_G_ANDROID
static struct android_usb_platform_data android_usb_pdata = {
- .vendor_id = 0x05C6,
- .product_id = 0x9026,
- .version = 0x0100,
- .product_name = "Qualcomm HSUSB Device",
- .manufacturer_name = "Qualcomm Incorporated",
- .num_products = ARRAY_SIZE(usb_products),
- .products = usb_products,
- .num_functions = ARRAY_SIZE(usb_functions_all),
- .functions = usb_functions_all,
- .serial_number = "1234567890ABCDEF",
+ .update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
};
static struct platform_device android_usb_device = {
@@ -241,114 +123,6 @@
.platform_data = &android_usb_pdata,
},
};
-
-static int __init board_serialno_setup(char *serialno)
-{
- int i;
- char *src = serialno;
-
- /* create a fake MAC address from our serial number.
- * first byte is 0x02 to signify locally administered.
- */
- rndis_pdata.ethaddr[0] = 0x02;
- for (i = 0; *src; i++) {
- /* XOR the USB serial across the remaining bytes */
- rndis_pdata.ethaddr[i % (ETH_ALEN - 1) + 1] ^= *src++;
- }
-
- android_usb_pdata.serial_number = serialno;
- return 1;
-}
-__setup("androidboot.serialno=", board_serialno_setup);
-#endif
-
-static struct platform_device smc91x_device = {
- .name = "smc91x",
- .id = 0,
- .num_resources = ARRAY_SIZE(smc91x_resources),
- .resource = smc91x_resources,
-};
-
-#ifdef CONFIG_USB_FUNCTION
-static struct usb_function_map usb_functions_map[] = {
- {"diag", 0},
- {"adb", 1},
- {"modem", 2},
- {"nmea", 3},
- {"mass_storage", 4},
- {"ethernet", 5},
- {"rmnet", 6},
-};
-
-/* dynamic composition */
-static struct usb_composition usb_func_composition[] = {
- {
- .product_id = 0x9012,
- .functions = 0x5, /* 0101 */
- },
-
- {
- .product_id = 0x9013,
- .functions = 0x15, /* 10101 */
- },
-
- {
- .product_id = 0x9014,
- .functions = 0x30, /* 110000 */
- },
-
- {
- .product_id = 0x9016,
- .functions = 0xD, /* 01101 */
- },
-
- {
- .product_id = 0x9017,
- .functions = 0x1D, /* 11101 */
- },
-
- {
- .product_id = 0xF000,
- .functions = 0x10, /* 10000 */
- },
-
- {
- .product_id = 0xF009,
- .functions = 0x20, /* 100000 */
- },
-
- {
- .product_id = 0x9018,
- .functions = 0x1F, /* 011111 */
- },
-#ifdef CONFIG_USB_FUNCTION_RMNET
- {
- .product_id = 0x9021,
- /* DIAG + RMNET */
- .functions = 0x41,
- },
- {
- .product_id = 0x9022,
- /* DIAG + ADB + RMNET */
- .functions = 0x43,
- },
-#endif
-
-};
-
-static struct msm_hsusb_platform_data msm_hsusb_pdata = {
- .version = 0x0100,
- .phy_info = (USB_PHY_INTEGRATED | USB_PHY_MODEL_65NM),
- .vendor_id = 0x5c6,
- .product_name = "Qualcomm HSUSB Device",
- .serial_number = "1234567890ABCDEF",
- .manufacturer_name = "Qualcomm Incorporated",
- .compositions = usb_func_composition,
- .num_compositions = ARRAY_SIZE(usb_func_composition),
- .function_map = usb_functions_map,
- .num_functions = ARRAY_SIZE(usb_functions_map),
- .config_gpio = NULL,
-};
#endif
#ifdef CONFIG_USB_EHCI_MSM_72K
@@ -1410,22 +1184,10 @@
#endif
#endif
-#ifdef CONFIG_USB_FUNCTION
- &msm_device_hsusb_peripheral,
- &mass_storage_device,
-#endif
-
-#ifdef CONFIG_USB_ANDROID
- &usb_mass_storage_device,
- &rndis_device,
-#ifdef CONFIG_USB_ANDROID_DIAG
- &usb_diag_device,
-#endif
-#ifdef CONFIG_USB_F_SERIAL
- &usb_gadget_fserial_device,
-#endif
+#ifdef CONFIG_USB_G_ANDROID
&android_usb_device,
#endif
+
&msm_device_i2c,
&smc91x_device,
&msm_device_tssc,
@@ -1891,13 +1653,6 @@
usb_mpp_init();
-#ifdef CONFIG_USB_FUNCTION
- msm_hsusb_pdata.swfi_latency =
- msm7x27_pm_data
- [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
-
- msm_device_hsusb_peripheral.dev.platform_data = &msm_hsusb_pdata;
-#endif
#ifdef CONFIG_USB_MSM_OTG_72K
msm_device_otg.dev.platform_data = &msm_otg_pdata;
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index f51c61d..67b1dcc 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -638,65 +638,80 @@
goto reg_disable;
}
+ rc = on ? regulator_set_voltage(bt_vregs[i].reg,
+ bt_vregs[i].level, bt_vregs[i].level) : 0;
+ if (rc) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: could not set voltage for %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+
+ rc = on ? regulator_enable(bt_vregs[i].reg) : 0;
+ if (rc) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: could not %sable regulator %s: %d\n",
+ __func__, "en", bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+
if (bt_vregs[i].is_pin_controlled) {
- rc = pmapp_vreg_pincntrl_vote(id,
+ rc = pmapp_vreg_lpm_pincntrl_vote(id,
bt_vregs[i].pmapp_id,
PMAPP_CLOCK_ID_D1,
on ? PMAPP_CLOCK_VOTE_ON :
PMAPP_CLOCK_VOTE_OFF);
- } else {
- rc = on ? regulator_enable(bt_vregs[i].reg) :
- regulator_disable(bt_vregs[i].reg);
+ if (rc) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: pin control failed for %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto pin_cnt_fail;
+ }
}
+ rc = on ? 0 : regulator_disable(bt_vregs[i].reg);
if (rc) {
dev_err(&msm_bt_power_device.dev,
"%s: could not %sable regulator %s: %d\n",
- __func__, on ? "en" : "dis",
- bt_vregs[i].name, rc);
- i++;
+ __func__, "dis", bt_vregs[i].name, rc);
goto reg_disable;
}
}
return rc;
-
+pin_cnt_fail:
+ if (on)
+ regulator_disable(bt_vregs[i].reg);
reg_disable:
- while (i--) {
- if (bt_vregs[i].is_pin_controlled) {
- pmapp_vreg_pincntrl_vote(id, bt_vregs[i].pmapp_id,
- PMAPP_CLOCK_ID_D1,
- on ? PMAPP_CLOCK_VOTE_OFF :
- PMAPP_CLOCK_VOTE_ON);
- } else {
- if (on)
- regulator_disable(bt_vregs[i].reg);
- else
- regulator_enable(bt_vregs[i].reg);
+ while (i) {
+ if (on) {
+ i--;
+ regulator_disable(bt_vregs[i].reg);
+ regulator_put(bt_vregs[i].reg);
}
}
return rc;
}
-static struct regulator *reg_bahama;
+static struct regulator *reg_s3;
static unsigned int msm_bahama_setup_power(void)
{
int rc = 0;
- reg_bahama = regulator_get(NULL, "msme1");
- if (IS_ERR(reg_bahama)) {
- rc = PTR_ERR(reg_bahama);
+ reg_s3 = regulator_get(NULL, "msme1");
+ if (IS_ERR(reg_s3)) {
+ rc = PTR_ERR(reg_s3);
pr_err("%s: could not get regulator: %d\n", __func__, rc);
goto out;
}
- rc = regulator_set_voltage(reg_bahama, 1800000, 1800000);
+ rc = regulator_set_voltage(reg_s3, 1800000, 1800000);
if (rc) {
pr_err("%s: could not set voltage: %d\n", __func__, rc);
goto reg_fail;
}
- rc = regulator_enable(reg_bahama);
+ rc = regulator_enable(reg_s3);
if (rc < 0) {
pr_err("%s: could not enable regulator: %d\n", __func__, rc);
goto reg_fail;
@@ -722,11 +737,11 @@
gpio_fail:
gpio_free(GPIO_BT_SYS_REST_EN);
reg_disable:
- regulator_disable(reg_bahama);
+ regulator_disable(reg_s3);
reg_fail:
- regulator_put(reg_bahama);
+ regulator_put(reg_s3);
out:
- reg_bahama = NULL;
+ reg_s3 = NULL;
return rc;
}
@@ -734,12 +749,12 @@
{
int rc = 0;
- if (IS_ERR_OR_NULL(reg_bahama)) {
- rc = reg_bahama ? PTR_ERR(reg_bahama) : -ENODEV;
+ if (IS_ERR_OR_NULL(reg_s3)) {
+ rc = reg_s3 ? PTR_ERR(reg_s3) : -ENODEV;
goto out;
}
- rc = regulator_disable(reg_bahama);
+ rc = regulator_disable(reg_s3);
if (rc) {
pr_err("%s: could not disable regulator: %d\n", __func__, rc);
goto out;
@@ -750,18 +765,15 @@
if (rc) {
pr_err("%s: bt_set_gpio = %d\n",
__func__, rc);
- goto reg_enable;
}
gpio_free(GPIO_BT_SYS_REST_EN);
}
- regulator_put(reg_bahama);
- reg_bahama = NULL;
+ regulator_put(reg_s3);
+ reg_s3 = NULL;
return 0;
-reg_enable:
- regulator_enable(reg_bahama);
out:
return rc;
}
@@ -933,21 +945,12 @@
__func__, bt_vregs[i].name, rc);
goto reg_get_fail;
}
- rc = regulator_set_voltage(bt_vregs[i].reg,
- bt_vregs[i].level, bt_vregs[i].level);
- if (rc) {
- dev_err(dev, "%s: could not set voltage for %s: %d\n",
- __func__, bt_vregs[i].name, rc);
- goto reg_set_fail;
- }
}
dev->platform_data = &bluetooth_power;
return rc;
-reg_set_fail:
- i++;
reg_get_fail:
while (i--) {
regulator_put(bt_vregs[i].reg);
@@ -1832,18 +1835,29 @@
}
};
+#define PANEL_NAME_MAX_LEN 30
+#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
+#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
+
static int msm_fb_detect_panel(const char *name)
{
- int ret = -EPERM;
+ if (!strncmp(name, MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
+ strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
- if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
- if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21))
- ret = 0;
- } else {
- ret = -ENODEV;
- }
-
- return ret;
+#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
+ !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
+ !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
+ if (machine_is_msm7x27a_surf() ||
+ machine_is_msm7625a_surf()) {
+ if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
+ strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+ }
+#endif
+ return -ENODEV;
}
static struct msm_fb_platform_data msm_fb_pdata = {
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index 3ac41ed..2cf0a70 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -830,6 +830,26 @@
};
#endif
+#define DSP_RAM_BASE_8960 0x8da00000
+#define DSP_RAM_SIZE_8960 0x1800000
+static int dspcrashd_pdata_8960 = 0xDEADDEAD;
+
+static struct resource resources_dspcrashd_8960[] = {
+ {
+ .name = "msm_dspcrashd",
+ .start = DSP_RAM_BASE_8960,
+ .end = DSP_RAM_BASE_8960 + DSP_RAM_SIZE_8960,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device msm_device_dspcrashd_8960 = {
+ .name = "msm_dspcrashd",
+ .num_resources = ARRAY_SIZE(resources_dspcrashd_8960),
+ .resource = resources_dspcrashd_8960,
+ .dev = { .platform_data = &dspcrashd_pdata_8960 },
+};
+
static struct memtype_reserve msm8960_reserve_table[] __initdata = {
[MEMTYPE_SMI] = {
},
@@ -998,8 +1018,6 @@
};
#endif
-#ifdef CONFIG_MSM_BUS_SCALING
-
static struct msm_bus_vectors cam_init_vectors[] = {
{
.src = MSM_BUS_MASTER_VFE,
@@ -1133,24 +1151,19 @@
ARRAY_SIZE(cam_bus_client_config),
.name = "msm_camera",
};
-#endif
struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
{
.ioclk.mclk_clk_rate = 24000000,
.ioclk.vfe_clk_rate = 228570000,
.csid_core = 0,
-#ifdef CONFIG_MSM_BUS_SCALING
.cam_bus_scale_table = &cam_bus_client_pdata,
-#endif
},
{
.ioclk.mclk_clk_rate = 24000000,
.ioclk.vfe_clk_rate = 228570000,
.csid_core = 1,
-#ifdef CONFIG_MSM_BUS_SCALING
.cam_bus_scale_table = &cam_bus_client_pdata,
-#endif
},
};
@@ -1334,10 +1347,15 @@
#define MDP_VSYNC_GPIO 0
-#define TOSHIBA_PANEL_NAME "mipi_video_toshiba_wsvga"
-#define TOSHIBA_PANEL_NAME_LEN 24
-#define CHIMEI_PANEL_NAME "mipi_chimei_wxga"
-#define CHIMEI_PANEL_NAME_LEN 16
+#define PANEL_NAME_MAX_LEN 30
+#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
+#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
+#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
+#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
+#define MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME "mipi_video_simulator_vga"
+#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
+#define HDMI_PANEL_NAME "hdmi_msm"
+#define TVOUT_PANEL_NAME "tvout_msm"
static struct resource msm_fb_resources[] = {
{
@@ -1345,35 +1363,66 @@
}
};
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
static int msm_fb_detect_panel(const char *name)
{
if (machine_is_msm8960_liquid()) {
- if (!strncmp(name, CHIMEI_PANEL_NAME, CHIMEI_PANEL_NAME_LEN))
+ if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
+ strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
return 0;
} else {
- if (!strncmp(name, TOSHIBA_PANEL_NAME, TOSHIBA_PANEL_NAME_LEN))
+ if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
+ strnlen(MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
return 0;
+
+#ifndef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+ if (!strncmp(name, MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
+ strnlen(MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+
+ if (!strncmp(name, MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
+ strnlen(MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+
+ if (!strncmp(name, MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
+ strnlen(MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+
+ if (!strncmp(name, MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
+ strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+#endif
}
- pr_warning("%s: not supported '%s'", __func__, name);
+ if (!strncmp(name, HDMI_PANEL_NAME,
+ strnlen(HDMI_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+ if (!strncmp(name, TVOUT_PANEL_NAME,
+ strnlen(TVOUT_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+
+ pr_warning("%s: not supported '%s'", __func__, name);
return -ENODEV;
}
static struct msm_fb_platform_data msm_fb_pdata = {
.detect_client = msm_fb_detect_panel,
};
-#endif /* CONFIG_FB_MSM_MIPI_PANEL_DETECT */
static struct platform_device msm_fb_device = {
.name = "msm_fb",
.id = 0,
.num_resources = ARRAY_SIZE(msm_fb_resources),
.resource = msm_fb_resources,
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
.dev.platform_data = &msm_fb_pdata,
-#endif /* CONFIG_FB_MSM_MIPI_PANEL_DETECT */
};
static bool dsi_power_on;
@@ -2629,8 +2678,18 @@
static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
- {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_DOWN},
- {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_DOWN}
+ /*
+ * SDC3 CMD line should be PULLed UP otherwise fluid platform will
+ * see transitions (1 -> 0 and 0 -> 1) on card detection line,
+ * which would result in false card detection interrupts.
+ */
+ {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
+ /*
+ * Keeping DATA lines status to PULL UP will make sure that
+ * there is no current leak during sleep if external pull up
+ * is connected to DATA lines.
+ */
+ {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
};
struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
@@ -3479,6 +3538,7 @@
&msm_funnel_device,
&msm_ptm_device,
#endif
+ &msm_device_dspcrashd_8960,
};
static struct platform_device *sim_devices[] __initdata = {
@@ -3597,7 +3657,7 @@
static void __init msm8960_gfx_init(void)
{
- uint32_t soc_platform_version = socinfo_get_platform_version();
+ uint32_t soc_platform_version = socinfo_get_version();
if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
struct kgsl_device_platform_data *kgsl_3d0_pdata =
msm_kgsl_3d0.dev.platform_data;
@@ -3860,40 +3920,41 @@
#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
-/**
- * 'flag' stores three values; led id, led mode, and max current of led.
- * The bit packing format is as follow,
- * reserved (1 byte) | max_current (2 bytes) | led_mode (1 nibble) |
- * led_id (1 nibble)
- */
-#define PM8XXX_SET_FLAG(led_id, led_mode, led_max_current) \
- (((led_id << PM8XXX_LED_ID_SHIFT) & PM8XXX_LED_ID_MASK) |\
- ((led_mode << PM8XXX_LED_MODE_SHIFT) & PM8XXX_LED_MODE_MASK) |\
- ((led_max_current << PM8XXX_LED_MAX_CURRENT_SHIFT) & \
- PM8XXX_LED_MAX_CURRENT_MASK))
-
static struct led_info pm8921_led_info[] = {
[0] = {
.name = "led:usb",
.default_trigger = "usb-online",
- .flags = PM8XXX_SET_FLAG(PM8XXX_ID_LED_0,
- PM8XXX_LED_MODE_MANUAL,
- PM8921_LC_LED_MAX_CURRENT),
},
[1] = {
.name = "led:ac",
.default_trigger = "ac-online",
- .flags = PM8XXX_SET_FLAG(PM8XXX_ID_LED_1,
- PM8XXX_LED_MODE_MANUAL,
- PM8921_LC_LED_MAX_CURRENT),
},
};
-static struct led_platform_data pm8xxx_leds_pdata = {
+static struct led_platform_data pm8921_led_core_pdata = {
.num_leds = ARRAY_SIZE(pm8921_led_info),
.leds = pm8921_led_info,
};
+static struct pm8xxx_led_config pm8921_led_configs[] = {
+ [0] = {
+ .id = PM8XXX_ID_LED_0,
+ .mode = PM8XXX_LED_MODE_MANUAL,
+ .max_current = PM8921_LC_LED_MAX_CURRENT,
+ },
+ [1] = {
+ .id = PM8XXX_ID_LED_1,
+ .mode = PM8XXX_LED_MODE_MANUAL,
+ .max_current = PM8921_LC_LED_MAX_CURRENT,
+ },
+};
+
+static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
+ .led_core = &pm8921_led_core_pdata,
+ .configs = pm8921_led_configs,
+ .num_configs = ARRAY_SIZE(pm8921_led_configs),
+};
+
static struct pm8921_platform_data pm8921_platform_data __devinitdata = {
.irq_pdata = &pm8xxx_irq_pdata,
.gpio_pdata = &pm8xxx_gpio_pdata,
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 2af1087..79bad3f 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -139,6 +139,13 @@
#define LCDC_AUO_SPI_DEVICE_NAME "lcdc_auo_nt35582"
#define LCDC_NT35582_PANEL_NAME "lcdc_nt35582_wvga"
+#define PANEL_NAME_MAX_LEN 30
+#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
+#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
+#define MIPI_VIDEO_TOSHIBA_WVGA_PANEL_NAME "mipi_video_toshiba_wvga"
+#define HDMI_PANEL_NAME "hdmi_msm"
+#define TVOUT_PANEL_NAME "tvout_msm"
+
#define DSPS_PIL_GENERIC_NAME "dsps"
#define DSPS_PIL_FLUID_NAME "dsps_fluid"
@@ -2663,7 +2670,6 @@
}
};
-#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
static int msm_fb_detect_panel(const char *name)
{
if (machine_is_msm8x60_fluid()) {
@@ -2671,33 +2677,61 @@
if (SOCINFO_VERSION_MAJOR(soc_platform_version) < 3) {
#ifdef CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT
if (!strncmp(name, LCDC_SAMSUNG_OLED_PANEL_NAME,
- strlen(LCDC_SAMSUNG_OLED_PANEL_NAME)))
+ strnlen(LCDC_SAMSUNG_OLED_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
return 0;
#endif
} else { /*P3 and up use AUO panel */
#ifdef CONFIG_FB_MSM_LCDC_AUO_WVGA
if (!strncmp(name, LCDC_AUO_PANEL_NAME,
- strlen(LCDC_AUO_PANEL_NAME)))
+ strnlen(LCDC_AUO_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
return 0;
#endif
}
- if (!strncmp(name, LCDC_SAMSUNG_WSVGA_PANEL_NAME,
- strlen(LCDC_SAMSUNG_WSVGA_PANEL_NAME)))
- return -ENODEV;
#ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
} else if machine_is_msm8x60_dragon() {
if (!strncmp(name, LCDC_NT35582_PANEL_NAME,
- sizeof(LCDC_NT35582_PANEL_NAME) - 1))
+ strnlen(LCDC_NT35582_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
return 0;
#endif
} else {
if (!strncmp(name, LCDC_SAMSUNG_WSVGA_PANEL_NAME,
- strlen(LCDC_SAMSUNG_WSVGA_PANEL_NAME)))
+ strnlen(LCDC_SAMSUNG_WSVGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
return 0;
- if (!strncmp(name, LCDC_SAMSUNG_OLED_PANEL_NAME,
- strlen(LCDC_SAMSUNG_OLED_PANEL_NAME)))
- return -ENODEV;
+
+#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
+ !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
+ !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
+ if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WVGA_PANEL_NAME,
+ strnlen(MIPI_VIDEO_TOSHIBA_WVGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+
+ if (!strncmp(name, MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
+ strnlen(MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+
+ if (!strncmp(name, MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
+ strnlen(MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+#endif
}
+
+ if (!strncmp(name, HDMI_PANEL_NAME,
+ strnlen(HDMI_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+
+ if (!strncmp(name, TVOUT_PANEL_NAME,
+ strnlen(TVOUT_PANEL_NAME,
+ PANEL_NAME_MAX_LEN)))
+ return 0;
+
pr_warning("%s: not supported '%s'", __func__, name);
return -ENODEV;
}
@@ -2705,16 +2739,13 @@
static struct msm_fb_platform_data msm_fb_pdata = {
.detect_client = msm_fb_detect_panel,
};
-#endif /* CONFIG_FB_MSM_LCDC_AUTO_DETECT */
static struct platform_device msm_fb_device = {
.name = "msm_fb",
.id = 0,
.num_resources = ARRAY_SIZE(msm_fb_resources),
.resource = msm_fb_resources,
-#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
.dev.platform_data = &msm_fb_pdata,
-#endif /* CONFIG_FB_MSM_LCDC_AUTO_DETECT */
};
#ifdef CONFIG_ANDROID_PMEM
@@ -4893,10 +4924,6 @@
#ifdef CONFIG_MSM_SDIO_AL
&msm_device_sdio_al,
#endif
-#ifdef CONFIG_MSM_SDIO_AL
- &msm_device_sdio_al,
-#endif
-
};
#ifdef CONFIG_SND_SOC_MSM8660_APQ
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index af313c0..9aa5700 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -252,6 +252,12 @@
#define MM_PLL1_TEST_CTL_REG REG_MM(0x0330)
#define MM_PLL1_STATUS_REG REG_MM(0x0334)
#define MM_PLL3_MODE_REG REG_MM(0x0338)
+#define MM_PLL3_L_VAL_REG REG_MM(0x033C)
+#define MM_PLL3_M_VAL_REG REG_MM(0x0340)
+#define MM_PLL3_N_VAL_REG REG_MM(0x0344)
+#define MM_PLL3_CONFIG_REG REG_MM(0x0348)
+#define MM_PLL3_TEST_CTL_REG REG_MM(0x034C)
+#define MM_PLL3_STATUS_REG REG_MM(0x0350)
#define ROT_CC_REG REG_MM(0x00E0)
#define ROT_NS_REG REG_MM(0x00E8)
#define SAXI_EN_REG REG_MM(0x0030)
@@ -786,6 +792,23 @@
},
};
+/* For 8064, gfx3d_axi_clk is set as a dependency of gmem_axi_clk at runtime */
+static struct branch_clk gfx3d_axi_clk = {
+ .b = {
+ .ctl_reg = MAXI_EN5_REG,
+ .en_mask = BIT(25),
+ .reset_reg = SW_RESET_AXI_REG,
+ .reset_mask = BIT(17),
+ .halt_reg = DBG_BUS_VEC_J_REG,
+ .halt_bit = 30,
+ },
+ .c = {
+ .dbg_name = "gfx3d_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gfx3d_axi_clk.c),
+ },
+};
+
/* AHB Interfaces */
static struct branch_clk amp_p_clk = {
.b = {
@@ -3390,6 +3413,7 @@
F_END
};
+/* TODO: need to add 325MHz back once it is fixed in the simulation model */
static struct clk_freq_tbl clk_tbl_gfx3d_8064[] = {
F_GFX3D( 0, gnd, 0, 0, NONE),
F_GFX3D( 27000000, pxo, 0, 0, LOW),
@@ -3405,7 +3429,6 @@
F_GFX3D(200000000, pll2, 1, 4, NOMINAL),
F_GFX3D(228571000, pll2, 2, 7, NOMINAL),
F_GFX3D(266667000, pll2, 1, 3, NOMINAL),
- F_GFX3D(325000000, pll15, 1, 3, NOMINAL),
F_GFX3D(400000000, pll2, 1, 2, HIGH),
F_END
};
@@ -3451,6 +3474,83 @@
},
};
+#define F_VCAP(f, s, m, n, v) \
+ { \
+ .freq_hz = f, \
+ .src_clk = &s##_clk.c, \
+ .md_val = MD4(4, m, 0, n), \
+ .ns_val = NS_MND_BANKED4(18, 14, n, m, 3, 0, s##_to_mm_mux), \
+ .ctl_val = CC_BANKED(9, 6, n), \
+ .mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
+ .sys_vdd = v, \
+ }
+
+static struct clk_freq_tbl clk_tbl_vcap[] = {
+ F_VCAP( 0, gnd, 0, 0, NONE),
+ F_VCAP( 27000000, pxo, 0, 0, LOW),
+ F_VCAP( 54860000, pll8, 1, 7, LOW),
+ F_VCAP( 64000000, pll8, 1, 6, LOW),
+ F_VCAP( 76800000, pll8, 1, 5, LOW),
+ F_VCAP(128000000, pll8, 1, 3, NOMINAL),
+ F_VCAP(160000000, pll2, 1, 5, NOMINAL),
+ F_VCAP(200000000, pll2, 1, 4, NOMINAL),
+ F_END
+};
+
+static struct bank_masks bmnd_info_vcap = {
+ .bank_sel_mask = BIT(11),
+ .bank0_mask = {
+ .md_reg = VCAP_MD0_REG,
+ .ns_mask = BM(21, 18) | BM(5, 3),
+ .rst_mask = BIT(23),
+ .mnd_en_mask = BIT(8),
+ .mode_mask = BM(10, 9),
+ },
+ .bank1_mask = {
+ .md_reg = VCAP_MD1_REG,
+ .ns_mask = BM(17, 14) | BM(2, 0),
+ .rst_mask = BIT(22),
+ .mnd_en_mask = BIT(5),
+ .mode_mask = BM(7, 6),
+ },
+};
+
+static struct rcg_clk vcap_clk = {
+ .b = {
+ .ctl_reg = VCAP_CC_REG,
+ .en_mask = BIT(0),
+ .halt_reg = DBG_BUS_VEC_J_REG,
+ .halt_bit = 15,
+ },
+ .ns_reg = VCAP_NS_REG,
+ .root_en_mask = BIT(2),
+ .set_rate = set_rate_mnd_banked,
+ .freq_tbl = clk_tbl_vcap,
+ .bank_info = &bmnd_info_vcap,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "vcap_clk",
+ .ops = &clk_ops_rcg_8960,
+ .depends = &vcap_axi_clk.c,
+ CLK_INIT(vcap_clk.c),
+ },
+};
+
+static struct branch_clk vcap_npl_clk = {
+ .b = {
+ .ctl_reg = VCAP_CC_REG,
+ .en_mask = BIT(13),
+ .halt_reg = DBG_BUS_VEC_J_REG,
+ .halt_bit = 25,
+ },
+ .parent = &vcap_clk.c,
+ .c = {
+ .dbg_name = "vcap_npl_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(vcap_npl_clk.c),
+ },
+};
+
#define F_IJPEG(f, s, d, m, n, v) \
{ \
.freq_hz = f, \
@@ -3487,7 +3587,7 @@
F_IJPEG(128000000, pll8, 3, 0, 0, LOW),
F_IJPEG(153600000, pll8, 1, 2, 5, NOMINAL),
F_IJPEG(200000000, pll2, 4, 0, 0, NOMINAL),
- F_IJPEG(228000000, pll2, 1, 2, 7, NOMINAL),
+ F_IJPEG(228571000, pll2, 1, 2, 7, NOMINAL),
F_IJPEG(320000000, pll2, 1, 2, 5, HIGH),
F_END
};
@@ -3567,7 +3667,7 @@
.mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
.sys_vdd = v, \
}
-static struct clk_freq_tbl clk_tbl_mdp[] = {
+static struct clk_freq_tbl clk_tbl_mdp_8960[] = {
F_MDP( 0, gnd, 0, 0, NONE),
F_MDP( 9600000, pll8, 1, 40, LOW),
F_MDP( 13710000, pll8, 1, 28, LOW),
@@ -3586,6 +3686,25 @@
F_END
};
+static struct clk_freq_tbl clk_tbl_mdp_8064[] = {
+ F_MDP( 0, gnd, 0, 0, NONE),
+ F_MDP( 9600000, pll8, 1, 40, LOW),
+ F_MDP( 13710000, pll8, 1, 28, LOW),
+ F_MDP( 29540000, pll8, 1, 13, LOW),
+ F_MDP( 34910000, pll8, 1, 11, LOW),
+ F_MDP( 38400000, pll8, 1, 10, LOW),
+ F_MDP( 59080000, pll8, 2, 13, LOW),
+ F_MDP( 76800000, pll8, 1, 5, LOW),
+ F_MDP( 85330000, pll8, 2, 9, LOW),
+ F_MDP( 96000000, pll8, 1, 4, LOW),
+ F_MDP(128000000, pll8, 1, 3, LOW),
+ F_MDP(160000000, pll2, 1, 5, NOMINAL),
+ F_MDP(177780000, pll2, 2, 9, NOMINAL),
+ F_MDP(200000000, pll2, 1, 4, NOMINAL),
+ F_MDP(266000000, pll2, 1, 3, NOMINAL),
+ F_END
+};
+
static struct bank_masks bmnd_info_mdp = {
.bank_sel_mask = BIT(11),
.bank0_mask = {
@@ -3616,7 +3735,7 @@
.ns_reg = MDP_NS_REG,
.root_en_mask = BIT(2),
.set_rate = set_rate_mnd_banked,
- .freq_tbl = clk_tbl_mdp,
+ .freq_tbl = clk_tbl_mdp_8960,
.bank_info = &bmnd_info_mdp,
.current_freq = &rcg_dummy_freq,
.c = {
@@ -4621,7 +4740,10 @@
{ TEST_MM_HS(0x30), &csi_pix1_clk.c },
{ TEST_MM_HS(0x31), &csi_rdi1_clk.c },
{ TEST_MM_HS(0x32), &csi_rdi2_clk.c },
+ { TEST_MM_HS(0x33), &vcap_clk.c },
+ { TEST_MM_HS(0x34), &vcap_npl_clk.c },
{ TEST_MM_HS(0x36), &vcap_axi_clk.c },
+ { TEST_MM_HS(0x39), &gfx3d_axi_clk.c },
{ TEST_LPA(0x0F), &mi2s_bit_clk.c },
{ TEST_LPA(0x10), &codec_i2s_mic_bit_clk.c },
@@ -4815,7 +4937,7 @@
static struct clk_lookup msm_clocks_8064[] __initdata = {
CLK_LOOKUP("cxo", cxo_clk.c, NULL),
- CLK_DUMMY("pll2", PLL2, NULL, 0),
+ CLK_LOOKUP("pll2", pll2_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
CLK_DUMMY("pll4", PLL4, NULL, 0),
CLK_LOOKUP("measure", measure_clk.c, "debug"),
@@ -4898,66 +5020,84 @@
CLK_LOOKUP("pmic_ssbi2", pmic_ssbi2_clk.c, NULL),
CLK_LOOKUP("rpm_msg_ram_pclk", rpm_msg_ram_p_clk.c, NULL),
CLK_LOOKUP("amp_clk", amp_clk.c, NULL),
- CLK_DUMMY("cam_clk", CAM0_CLK, NULL, OFF),
- CLK_DUMMY("cam_clk", CAM1_CLK, NULL, OFF),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, NULL),
+ CLK_LOOKUP("cam_clk", cam1_clk.c, NULL),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, NULL),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, NULL),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, NULL),
CLK_DUMMY("csi_src_clk", CSI0_SRC_CLK, NULL, OFF),
- CLK_DUMMY("csi_src_clk", CSI1_SRC_CLK, NULL, OFF),
+ CLK_LOOKUP("csi_src_clk", csi1_src_clk.c, NULL),
+ CLK_LOOKUP("csi_src_clk", csi1_src_clk.c, NULL),
+ CLK_LOOKUP("csi_src_clk", csi2_src_clk.c, NULL),
CLK_DUMMY("csi_clk", CSI0_CLK, NULL, OFF),
- CLK_DUMMY("csi_clk", CSI1_CLK, NULL, OFF),
+ CLK_LOOKUP("csi_clk", csi1_clk.c, NULL),
+ CLK_LOOKUP("csi_clk", csi1_clk.c, NULL),
+ CLK_LOOKUP("csi_clk", csi2_clk.c, NULL),
+ CLK_DUMMY("csi_phy_clk", CSI0_PHY_CLK, NULL, OFF),
+ CLK_LOOKUP("csi_phy_clk", csi1_phy_clk.c, NULL),
+ CLK_LOOKUP("csi_phy_clk", csi1_phy_clk.c, NULL),
+ CLK_LOOKUP("csi_phy_clk", csi2_phy_clk.c, NULL),
CLK_DUMMY("csi_pix_clk", CSI_PIX_CLK, NULL, OFF),
CLK_DUMMY("csi_rdi_clk", CSI_RDI_CLK, NULL, OFF),
- CLK_DUMMY("csiphy_timer_src_clk", CSIPHY_TIMER_SRC_CLK, NULL, OFF),
- CLK_DUMMY("csi0phy_timer_clk", CSIPHY0_TIMER_CLK, NULL, OFF),
- CLK_DUMMY("csi1phy_timer_clk", CSIPHY1_TIMER_CLK, NULL, OFF),
- CLK_DUMMY("dsi_byte_div_clk", DSI1_BYTE_CLK, "mipi_dsi.1", OFF),
- CLK_DUMMY("dsi_byte_div_clk", DSI2_BYTE_CLK, "mipi_dsi.2", OFF),
- CLK_DUMMY("dsi_esc_clk", DSI1_ESC_CLK, "mipi_dsi.1", OFF),
- CLK_DUMMY("dsi_esc_clk", DSI2_ESC_CLK, "mipi_dsi.2", OFF),
- CLK_DUMMY("gfx3d_clk", GFX3D_CLK, NULL, OFF),
- CLK_DUMMY("ijpeg_clk", IJPEG_CLK, NULL, OFF),
- CLK_DUMMY("imem_axi_clk", IMEM_AXI_CLK, NULL, OFF),
- CLK_DUMMY("jpegd_clk", JPEGD_CLK, NULL, OFF),
- CLK_DUMMY("mdp_clk", MDP_CLK, NULL, OFF),
- CLK_DUMMY("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, OFF),
- CLK_DUMMY("lut_mdp", LUT_MDP_CLK, NULL, OFF),
- CLK_DUMMY("rot_clk", ROT_CLK, NULL, OFF),
+ CLK_DUMMY("csi_pix_clk", CSI_PIX1_CLK, NULL, OFF),
+ CLK_DUMMY("csi_rdi_clk", CSI_RDI1_CLK, NULL, OFF),
+ CLK_DUMMY("csi_rdi_clk", CSI_RDI2_CLK, NULL, OFF),
+ CLK_LOOKUP("csiphy_timer_src_clk", csiphy_timer_src_clk.c, NULL),
+ CLK_LOOKUP("csiphy_timer_clk", csi0phy_timer_clk.c, NULL),
+ CLK_LOOKUP("csiphy_timer_clk", csi1phy_timer_clk.c, NULL),
+ CLK_LOOKUP("csiphy_timer_clk", csi2phy_timer_clk.c, NULL),
+ CLK_LOOKUP("dsi_byte_div_clk", dsi1_byte_clk.c, NULL),
+ CLK_LOOKUP("dsi_byte_div_clk", dsi2_byte_clk.c, NULL),
+ CLK_LOOKUP("dsi_esc_clk", dsi1_esc_clk.c, NULL),
+ CLK_LOOKUP("dsi_esc_clk", dsi2_esc_clk.c, NULL),
+ CLK_DUMMY("rgb_tv_clk", RGB_TV_CLK, NULL, OFF),
+ CLK_DUMMY("npl_tv_clk", NPL_TV_CLK, NULL, OFF),
+ CLK_LOOKUP("core_clk", gfx3d_clk.c, NULL),
+ CLK_LOOKUP("iface_clk", vcap_p_clk.c, NULL),
+ CLK_LOOKUP("bus_clk", vcap_axi_clk.c, NULL),
+ CLK_LOOKUP("core_clk", vcap_clk.c, NULL),
+ CLK_LOOKUP("vcap_npl_clk", vcap_npl_clk.c, NULL),
+ CLK_LOOKUP("bus_clk", ijpeg_axi_clk.c, NULL),
+ CLK_LOOKUP("mem_clk", imem_axi_clk.c, NULL),
+ CLK_LOOKUP("ijpeg_clk", ijpeg_clk.c, NULL),
+ CLK_LOOKUP("jpegd_clk", jpegd_clk.c, NULL),
+ CLK_LOOKUP("mdp_clk", mdp_clk.c, NULL),
+ CLK_LOOKUP("mdp_vsync_clk", mdp_vsync_clk.c, NULL),
+ CLK_LOOKUP("lut_mdp", lut_mdp_clk.c, NULL),
+ CLK_LOOKUP("rot_clk", rot_clk.c, NULL),
CLK_DUMMY("tv_src_clk", TV_SRC_CLK, NULL, OFF),
- CLK_DUMMY("tv_enc_clk", TV_ENC_CLK, NULL, OFF),
- CLK_DUMMY("tv_dac_clk", TV_DAC_CLK, NULL, OFF),
- CLK_DUMMY("vcodec_clk", VCODEC_CLK, NULL, OFF),
+ CLK_LOOKUP("core_clk", vcodec_clk.c, NULL),
CLK_DUMMY("mdp_tv_clk", MDP_TV_CLK, NULL, OFF),
CLK_DUMMY("hdmi_clk", HDMI_TV_CLK, NULL, OFF),
- CLK_DUMMY("core_clk", HDMI_APP_CLK, NULL, OFF),
- CLK_DUMMY("vpe_clk", VPE_CLK, NULL, OFF),
- CLK_DUMMY("vfe_clk", VFE_CLK, NULL, OFF),
- CLK_DUMMY("csi_vfe_clk", CSI0_VFE_CLK, NULL, OFF),
- CLK_DUMMY("vfe_axi_clk", VFE_AXI_CLK, NULL, OFF),
- CLK_DUMMY("ijpeg_axi_clk", IJPEG_AXI_CLK, NULL, OFF),
- CLK_DUMMY("mdp_axi_clk", MDP_AXI_CLK, NULL, OFF),
- CLK_DUMMY("rot_axi_clk", ROT_AXI_CLK, NULL, OFF),
- CLK_DUMMY("vcodec_axi_clk", VCODEC_AXI_CLK, NULL, OFF),
- CLK_DUMMY("vcodec_axi_a_clk", VCODEC_AXI_A_CLK, NULL, OFF),
- CLK_DUMMY("vcodec_axi_b_clk", VCODEC_AXI_B_CLK, NULL, OFF),
- CLK_DUMMY("vpe_axi_clk", VPE_AXI_CLK, NULL, OFF),
- CLK_DUMMY("amp_pclk", AMP_P_CLK, NULL, OFF),
- CLK_DUMMY("csi_pclk", CSI0_P_CLK, NULL, OFF),
- CLK_DUMMY("dsi_m_pclk", DSI1_M_P_CLK, "mipi_dsi.1", OFF),
- CLK_DUMMY("dsi_s_pclk", DSI1_S_P_CLK, "mipi_dsi.1", OFF),
- CLK_DUMMY("dsi_m_pclk", DSI2_M_P_CLK, "mipi_dsi.2", OFF),
- CLK_DUMMY("dsi_s_pclk", DSI2_S_P_CLK, "mipi_dsi.2", OFF),
- CLK_DUMMY("gfx3d_pclk", GFX3D_P_CLK, NULL, OFF),
- CLK_DUMMY("master_iface_clk", HDMI_M_P_CLK, NULL, OFF),
- CLK_DUMMY("slave_iface_clk", HDMI_S_P_CLK, NULL, OFF),
- CLK_DUMMY("ijpeg_pclk", IJPEG_P_CLK, NULL, OFF),
- CLK_DUMMY("jpegd_pclk", JPEGD_P_CLK, NULL, OFF),
- CLK_DUMMY("imem_pclk", IMEM_P_CLK, NULL, OFF),
- CLK_DUMMY("mdp_pclk", MDP_P_CLK, NULL, OFF),
- CLK_DUMMY("smmu_pclk", SMMU_P_CLK, NULL, OFF),
- CLK_DUMMY("rotator_pclk", ROT_P_CLK, NULL, OFF),
- CLK_DUMMY("tv_enc_pclk", TV_ENC_P_CLK, NULL, OFF),
- CLK_DUMMY("vcodec_pclk", VCODEC_P_CLK, NULL, OFF),
- CLK_DUMMY("vfe_pclk", VFE_P_CLK, NULL, OFF),
- CLK_DUMMY("vpe_pclk", VPE_P_CLK, NULL, OFF),
+ CLK_LOOKUP("core_clk", hdmi_app_clk.c, NULL),
+ CLK_LOOKUP("vpe_clk", vpe_clk.c, NULL),
+ CLK_LOOKUP("vfe_clk", vfe_clk.c, NULL),
+ CLK_LOOKUP("csi_vfe_clk", csi_vfe_clk.c, NULL),
+ CLK_LOOKUP("vfe_axi_clk", vfe_axi_clk.c, NULL),
+ CLK_LOOKUP("mdp_axi_clk", mdp_axi_clk.c, NULL),
+ CLK_LOOKUP("rot_axi_clk", rot_axi_clk.c, NULL),
+ CLK_LOOKUP("bus_clk", vcodec_axi_clk.c, NULL),
+ CLK_LOOKUP("bus_a_clk", vcodec_axi_a_clk.c, NULL),
+ CLK_LOOKUP("bus_b_clk", vcodec_axi_b_clk.c, NULL),
+ CLK_LOOKUP("vpe_axi_clk", vpe_axi_clk.c, NULL),
+ CLK_LOOKUP("amp_pclk", amp_p_clk.c, NULL),
+ CLK_LOOKUP("csi_pclk", csi_p_clk.c, NULL),
+ CLK_LOOKUP("dsi_m_pclk", dsi1_m_p_clk.c, NULL),
+ CLK_LOOKUP("dsi_s_pclk", dsi1_s_p_clk.c, NULL),
+ CLK_LOOKUP("dsi_m_pclk", dsi2_m_p_clk.c, NULL),
+ CLK_LOOKUP("dsi_s_pclk", dsi2_s_p_clk.c, NULL),
+ CLK_LOOKUP("iface_clk", gfx3d_p_clk.c, NULL),
+ CLK_LOOKUP("master_iface_clk", hdmi_m_p_clk.c, NULL),
+ CLK_LOOKUP("slave_iface_clk", hdmi_s_p_clk.c, NULL),
+ CLK_LOOKUP("ijpeg_pclk", ijpeg_p_clk.c, NULL),
+ CLK_LOOKUP("jpegd_pclk", jpegd_p_clk.c, NULL),
+ CLK_LOOKUP("imem_pclk", imem_p_clk.c, NULL),
+ CLK_LOOKUP("mdp_pclk", mdp_p_clk.c, NULL),
+ CLK_LOOKUP("iface_clk", smmu_p_clk.c, NULL),
+ CLK_LOOKUP("rotator_pclk", rot_p_clk.c, NULL),
+ CLK_LOOKUP("iface_clk", vcodec_p_clk.c, NULL),
+ CLK_LOOKUP("vfe_pclk", vfe_p_clk.c, NULL),
+ CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, NULL),
CLK_DUMMY("mi2s_osr_clk", MI2S_OSR_CLK, NULL, OFF),
CLK_DUMMY("mi2s_bit_clk", MI2S_BIT_CLK, NULL, OFF),
CLK_DUMMY("i2s_mic_osr_clk", CODEC_I2S_MIC_OSR_CLK, NULL, OFF),
@@ -4970,10 +5110,16 @@
CLK_DUMMY("i2s_spkr_bit_clk", SPARE_I2S_SPKR_BIT_CLK, NULL, OFF),
CLK_DUMMY("pcm_clk", PCM_CLK, NULL, OFF),
CLK_DUMMY("audio_slimbus_clk", AUDIO_SLIMBUS_CLK, NULL, OFF),
- CLK_DUMMY("iommu_clk", JPEGD_AXI_CLK, NULL, 0),
- CLK_DUMMY("iommu_clk", VFE_AXI_CLK, NULL, 0),
- CLK_DUMMY("iommu_clk", VCODEC_AXI_CLK, NULL, 0),
- CLK_DUMMY("iommu_clk", GFX3D_CLK, NULL, 0),
+ CLK_LOOKUP("core_clk", jpegd_axi_clk.c, NULL),
+ CLK_LOOKUP("core_clk", vpe_axi_clk.c, NULL),
+ CLK_LOOKUP("core_clk", mdp_axi_clk.c, NULL),
+ CLK_LOOKUP("core_clk", vcap_axi_clk.c, NULL),
+ CLK_LOOKUP("core_clk", rot_axi_clk.c, NULL),
+ CLK_LOOKUP("core_clk", ijpeg_axi_clk.c, NULL),
+ CLK_LOOKUP("core_clk", vfe_axi_clk.c, NULL),
+ CLK_LOOKUP("core_clk", vcodec_axi_a_clk.c, NULL),
+ CLK_LOOKUP("core_clk", vcodec_axi_b_clk.c, NULL),
+ CLK_DUMMY("core_clk", GFX3D_AXI_CLK, NULL, 0),
CLK_DUMMY("dfab_dsps_clk", DFAB_DSPS_CLK, NULL, 0),
CLK_DUMMY("dfab_usb_hs_clk", DFAB_USB_HS_CLK, NULL, 0),
CLK_DUMMY("bus_clk", DFAB_SDC1_CLK, NULL, 0),
@@ -5014,6 +5160,7 @@
CLK_LOOKUP("mmfab_a_clk", mmfab_a_clk.c, NULL),
CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, NULL),
CLK_LOOKUP("mmfpb_a_clk", mmfpb_a_clk.c, NULL),
+ CLK_LOOKUP("mmfpb_a_clk", mmfpb_a_clk.c, "clock-8960"),
CLK_LOOKUP("sfab_clk", sfab_clk.c, NULL),
CLK_LOOKUP("sfab_a_clk", sfab_a_clk.c, NULL),
CLK_LOOKUP("sfpb_clk", sfpb_clk.c, NULL),
@@ -5344,6 +5491,8 @@
rmwreg(0x80FF0000, VFE_CC_REG, 0xE0FF4010);
rmwreg(0x800000FF, VFE_CC2_REG, 0xE00000FF);
rmwreg(0x80FF0000, VPE_CC_REG, 0xE0FF0010);
+ if (cpu_is_apq8064())
+ rmwreg(0x80FF0000, VCAP_CC_REG, 0xE0FF1010);
/*
* Initialize USB_HS_HCLK_FS registers: Set FORCE_C_ON bits so that
@@ -5475,6 +5624,53 @@
set_fsm_mode(BB_PLL14_MODE_REG);
}
+ /* Program PLL2 to 800MHz with ref clk = 27MHz */
+ writel_relaxed(0x1D, MM_PLL1_L_VAL_REG);
+ writel_relaxed(0x11, MM_PLL1_M_VAL_REG);
+ writel_relaxed(0x1B, MM_PLL1_N_VAL_REG);
+
+ regval = readl_relaxed(MM_PLL1_CONFIG_REG);
+
+ /* Enable the main output and the MN accumulator */
+ regval |= BIT(23) | BIT(22);
+
+ /* Set pre-divider and post-divider values to 1 and 1 */
+ regval &= ~BIT(19);
+ regval &= ~BM(21, 20);
+
+ writel_relaxed(regval, MM_PLL1_CONFIG_REG);
+
+ /* Set VCO frequency */
+ rmwreg(0x20000, MM_PLL1_CONFIG_REG, 0x30000);
+
+ /* Enable AUX output */
+ regval = readl_relaxed(MM_PLL1_TEST_CTL_REG);
+ regval |= BIT(12);
+ writel_relaxed(regval, MM_PLL1_TEST_CTL_REG);
+
+ /* Program PLL15 to 975MHz with ref clk = 27MHz */
+ writel_relaxed(0x24, MM_PLL3_L_VAL_REG);
+ writel_relaxed(0x1, MM_PLL3_M_VAL_REG);
+ writel_relaxed(0x9, MM_PLL3_N_VAL_REG);
+
+ regval = readl_relaxed(MM_PLL3_CONFIG_REG);
+
+ /* Enable the main output and the MN accumulator */
+ regval |= BIT(23) | BIT(22);
+
+ /* Set pre-divider and post-divider values to 1 and 1 */
+ regval &= ~BIT(19);
+ regval &= ~BM(21, 20);
+
+ writel_relaxed(regval, MM_PLL3_CONFIG_REG);
+
+ /* Set VCO frequency */
+ rmwreg(0x20000, MM_PLL3_CONFIG_REG, 0x30000);
+
+ /* Enable AUX output */
+ regval = readl_relaxed(MM_PLL3_TEST_CTL_REG);
+ regval |= BIT(12);
+ writel_relaxed(regval, MM_PLL3_TEST_CTL_REG);
}
}
@@ -5510,12 +5706,15 @@
/*
* Change the freq tables for gfx3d_clk, ijpeg_clk, mdp_clk,
- * tv_src_clk and vfe_clk at runtime.
+ * tv_src_clk and vfe_clk at runtime and chain gmem_axi_clk
+ * with gfx3d_axi_clk for 8064.
*/
if (cpu_is_apq8064()) {
gfx3d_clk.freq_tbl = clk_tbl_gfx3d_8064;
ijpeg_clk.freq_tbl = clk_tbl_ijpeg_8064;
+ mdp_clk.freq_tbl = clk_tbl_mdp_8064;
vfe_clk.freq_tbl = clk_tbl_vfe_8064;
+ gmem_axi_clk.c.depends = &gfx3d_axi_clk.c;
}
soc_update_sys_vdd = msm8960_update_sys_vdd;
@@ -5565,6 +5764,20 @@
static int __init msm8960_clock_late_init(void)
{
+ int rc;
+ struct clk *mmfpb_a_clk = clk_get_sys("clock-8960", "mmfpb_a_clk");
+
+ /* Vote for MMFPB to be at least 76.8MHz when an Apps CPU is active. */
+ if (WARN(IS_ERR(mmfpb_a_clk), "mmfpb_a_clk not found (%ld)\n",
+ PTR_ERR(mmfpb_a_clk)))
+ return PTR_ERR(mmfpb_a_clk);
+ rc = clk_set_min_rate(mmfpb_a_clk, 76800000);
+ if (WARN(rc, "mmfpb_a_clk rate was not set (%d)\n", rc))
+ return rc;
+ rc = clk_enable(mmfpb_a_clk);
+ if (WARN(rc, "mmfpb_a_clk not enabled (%d)\n", rc))
+ return rc;
+
return local_unvote_sys_vdd(HIGH);
}
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index d58de8f..a5db9b2 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -26,9 +26,11 @@
#include <mach/msm_iomap.h>
#include <mach/clk.h>
#include <mach/msm_xo.h>
+#include <mach/rpm-9615.h>
#include "clock-local.h"
#include "clock-voter.h"
+#include "clock-rpm.h"
#include "devices.h"
#define REG(off) (MSM_CLK_CTL_BASE + (off))
@@ -1252,11 +1254,17 @@
},
};
-static DEFINE_CLK_VOTER(dfab_usb_hs_clk, &dummy_clk);
-static DEFINE_CLK_VOTER(dfab_sdc1_clk, &dummy_clk);
-static DEFINE_CLK_VOTER(dfab_sdc2_clk, &dummy_clk);
-static DEFINE_CLK_VOTER(dfab_sps_clk, &dummy_clk);
-static DEFINE_CLK_VOTER(ebi1_msmbus_clk, &dummy_clk);
+DEFINE_CLK_RPM(cfpb_clk, cfpb_a_clk, CFPB, NULL);
+DEFINE_CLK_RPM(dfab_clk, dfab_a_clk, DAYTONA_FABRIC, NULL);
+DEFINE_CLK_RPM(ebi1_clk, ebi1_a_clk, EBI1, NULL);
+DEFINE_CLK_RPM(sfab_clk, sfab_a_clk, SYSTEM_FABRIC, NULL);
+DEFINE_CLK_RPM(sfpb_clk, sfpb_a_clk, SFPB, NULL);
+
+static DEFINE_CLK_VOTER(dfab_usb_hs_clk, &dfab_clk.c);
+static DEFINE_CLK_VOTER(dfab_sdc1_clk, &dfab_clk.c);
+static DEFINE_CLK_VOTER(dfab_sdc2_clk, &dfab_clk.c);
+static DEFINE_CLK_VOTER(dfab_sps_clk, &dfab_clk.c);
+static DEFINE_CLK_VOTER(ebi1_msmbus_clk, &ebi1_clk.c);
/*
* TODO: replace dummy_clk below with ebi1_clk.c once the
@@ -1277,8 +1285,11 @@
{ TEST_PER_LS(0x14), &sdc2_p_clk.c },
{ TEST_PER_LS(0x15), &sdc2_clk.c },
{ TEST_PER_LS(0x26), &pmem_clk.c },
+ { TEST_PER_LS(0x25), &dfab_clk.c },
+ { TEST_PER_LS(0x25), &dfab_a_clk.c },
{ TEST_PER_LS(0x32), &dma_bam_p_clk.c },
- { TEST_PER_LS(0x3D), &gsbi1_p_clk.c },
+ { TEST_PER_LS(0x33), &cfpb_clk.c },
+ { TEST_PER_LS(0x33), &cfpb_a_clk.c },
{ TEST_PER_LS(0x3E), &gsbi1_uart_clk.c },
{ TEST_PER_LS(0x3F), &gsbi1_qup_clk.c },
{ TEST_PER_LS(0x41), &gsbi2_p_clk.c },
@@ -1293,6 +1304,8 @@
{ TEST_PER_LS(0x4D), &gsbi5_p_clk.c },
{ TEST_PER_LS(0x4E), &gsbi5_uart_clk.c },
{ TEST_PER_LS(0x50), &gsbi5_qup_clk.c },
+ { TEST_PER_LS(0x78), &sfpb_clk.c },
+ { TEST_PER_LS(0x78), &sfpb_a_clk.c },
{ TEST_PER_LS(0x7A), &pmic_ssbi2_clk.c },
{ TEST_PER_LS(0x7B), &pmic_arb0_p_clk.c },
{ TEST_PER_LS(0x7C), &pmic_arb1_p_clk.c },
@@ -1307,8 +1320,12 @@
{ TEST_PER_LS(0x8B), &usb_hsic_hsio_cal_clk.c },
{ TEST_PER_LS(0x8D), &usb_hs1_sys_clk.c },
{ TEST_PER_LS(0x92), &ce1_p_clk.c },
+ { TEST_PER_HS(0x18), &sfab_clk.c },
+ { TEST_PER_HS(0x18), &sfab_a_clk.c },
{ TEST_PER_LS(0xA4), &ce1_core_clk.c },
{ TEST_PER_HS(0x2A), &adm0_clk.c },
+ { TEST_PER_HS(0x34), &ebi1_clk.c },
+ { TEST_PER_HS(0x34), &ebi1_a_clk.c },
{ TEST_LPA(0x0F), &mi2s_bit_clk.c },
{ TEST_LPA(0x10), &codec_i2s_mic_bit_clk.c },
{ TEST_LPA(0x11), &codec_i2s_spkr_bit_clk.c },
@@ -1482,17 +1499,16 @@
CLK_LOOKUP("pll14", pll14_clk.c, NULL),
CLK_LOOKUP("measure", measure_clk.c, "debug"),
- /* TODO: Make these real when the RPM driver's ready. */
- CLK_DUMMY("cfpb_clk", cfpb_clk.c, NULL, OFF),
- CLK_DUMMY("cfpb_a_clk", cfpb_a_clk.c, NULL, OFF),
- CLK_DUMMY("dfab_clk", dfab_clk.c, NULL, OFF),
- CLK_DUMMY("dfab_a_clk", dfab_a_clk.c, NULL, OFF),
- CLK_DUMMY("ebi1_clk", ebi1_clk.c, NULL, OFF),
- CLK_DUMMY("ebi1_a_clk", ebi1_a_clk.c, NULL, OFF),
- CLK_DUMMY("sfab_clk", sfab_clk.c, NULL, OFF),
- CLK_DUMMY("sfab_a_clk", sfab_a_clk.c, NULL, OFF),
- CLK_DUMMY("sfpb_clk", sfpb_clk.c, NULL, OFF),
- CLK_DUMMY("sfpb_a_clk", sfpb_a_clk.c, NULL, OFF),
+ CLK_LOOKUP("cfpb_clk", cfpb_clk.c, NULL),
+ CLK_LOOKUP("cfpb_a_clk", cfpb_a_clk.c, NULL),
+ CLK_LOOKUP("dfab_clk", dfab_clk.c, NULL),
+ CLK_LOOKUP("dfab_a_clk", dfab_a_clk.c, NULL),
+ CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL),
+ CLK_LOOKUP("ebi1_a_clk", ebi1_a_clk.c, NULL),
+ CLK_LOOKUP("sfab_clk", sfab_clk.c, NULL),
+ CLK_LOOKUP("sfab_a_clk", sfab_a_clk.c, NULL),
+ CLK_LOOKUP("sfpb_clk", sfpb_clk.c, NULL),
+ CLK_LOOKUP("sfpb_a_clk", sfpb_a_clk.c, NULL),
CLK_LOOKUP("core_clk", gsbi1_uart_clk.c, NULL),
CLK_LOOKUP("core_clk", gsbi2_uart_clk.c, NULL),
@@ -1557,9 +1573,8 @@
CLK_LOOKUP("bus_clk", dfab_sdc2_clk.c, "msm_sdcc.2"),
CLK_LOOKUP("dfab_clk", dfab_sps_clk.c, "msm_sps"),
- /* TODO: Make this real when RPM's ready. */
- CLK_DUMMY("ebi1_msmbus_clk", ebi1_msmbus_clk.c, NULL, OFF),
- CLK_DUMMY("mem_clk", ebi1_adm_clk.c, "msm_dmov", OFF),
+ CLK_LOOKUP("ebi1_msmbus_clk", ebi1_msmbus_clk.c, NULL),
+ CLK_LOOKUP("mem_clk", ebi1_adm_clk.c, "msm_dmov"),
};
@@ -1651,9 +1666,36 @@
set_fsm_mode(SC_PLL0_MODE_REG);
- } else if (readl_relaxed(SC_PLL0_MODE_REG) & BIT(20))
+ } else if (!(readl_relaxed(SC_PLL0_MODE_REG) & BIT(20)))
WARN(1, "PLL9 enabled in non-FSM mode!\n");
+ /* Check if PLL14 is enabled in FSM mode */
+ is_pll_enabled = readl_relaxed(BB_PLL14_STATUS_REG) & BIT(16);
+
+ if (!is_pll_enabled) {
+ writel_relaxed(0x19, BB_PLL14_L_VAL_REG);
+ writel_relaxed(0x0, BB_PLL14_M_VAL_REG);
+ writel_relaxed(0x1, BB_PLL14_N_VAL_REG);
+
+ regval = readl_relaxed(BB_PLL14_CONFIG_REG);
+
+ /* Enable main output and the MN accumulator */
+ regval |= BIT(23) | BIT(22);
+
+ /* Set pre-divider and post-divider values to 1 and 1 */
+ regval &= ~BIT(19);
+ regval &= ~BM(21, 20);
+
+ /* Set VCO frequency */
+ regval &= ~BM(17, 16);
+
+ writel_relaxed(regval, BB_PLL14_CONFIG_REG);
+
+ set_fsm_mode(BB_PLL14_MODE_REG);
+
+ } else if (!(readl_relaxed(BB_PLL14_MODE_REG) & BIT(20)))
+ WARN(1, "PLL14 enabled in non-FSM mode!\n");
+
/* Enable PLL4 source on the LPASS Primary PLL Mux */
regval = readl_relaxed(LCC_PRI_PLL_CLK_CTL_REG);
writel_relaxed(regval | BIT(0), LCC_PRI_PLL_CLK_CTL_REG);
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 6c826dd..d542b96 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -531,7 +531,51 @@
.mpm_apps_ipc_reg = MSM_APCS_GCC_BASE + 0x008,
.mpm_apps_ipc_val = BIT(1),
.mpm_ipc_irq = RPM_APCC_CPU0_GP_MEDIUM_IRQ,
+};
+static uint8_t spm_wfi_cmd_sequence[] __initdata = {
+ 0x00, 0x03, 0x0B, 0x00,
+ 0x0f,
+};
+
+static uint8_t spm_power_collapse_without_rpm[] __initdata = {
+ 0x30, 0x20, 0x10, 0x00,
+ 0x50, 0x03, 0x50, 0x00,
+ 0x10, 0x20, 0x30, 0x0f,
+};
+
+static uint8_t spm_power_collapse_with_rpm[] __initdata = {
+ 0x30, 0x20, 0x10, 0x00,
+ 0x50, 0x07, 0x50, 0x00,
+ 0x10, 0x20, 0x30, 0x0f,
+};
+
+static struct msm_spm_seq_entry msm_spm_seq_list[] __initdata = {
+ [0] = {
+ .mode = MSM_SPM_MODE_CLOCK_GATING,
+ .notify_rpm = false,
+ .cmd = spm_wfi_cmd_sequence,
+ },
+ [1] = {
+ .mode = MSM_SPM_MODE_POWER_COLLAPSE,
+ .notify_rpm = false,
+ .cmd = spm_power_collapse_without_rpm,
+ },
+ [2] = {
+ .mode = MSM_SPM_MODE_POWER_COLLAPSE,
+ .notify_rpm = true,
+ .cmd = spm_power_collapse_with_rpm,
+ },
+};
+
+static struct msm_spm_platform_data msm_spm_data[] __initdata = {
+ [0] = {
+ .reg_base_addr = MSM_SAW0_BASE,
+ .reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
+ .reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
+ .num_modes = ARRAY_SIZE(msm_spm_seq_list),
+ .modes = msm_spm_seq_list,
+ },
};
static struct msm_rpmrs_level msm_rpmrs_levels[] __initdata = {
@@ -558,6 +602,7 @@
void __init msm9615_device_init(void)
{
+ msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
msm_clock_init(&msm9615_clock_init_data);
acpuclk_init(&acpuclk_9615_soc_data);
BUG_ON(msm_rpm_init(&msm_rpm_data));
diff --git a/arch/arm/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c
index 250cbad..3772884 100644
--- a/arch/arm/mach-msm/devices-msm7x27.c
+++ b/arch/arm/mach-msm/devices-msm7x27.c
@@ -33,7 +33,6 @@
#include <asm/mach/mmc.h>
#include <mach/msm_hsusb.h>
#include <mach/usbdiag.h>
-#include <mach/usb_gadget_fserial.h>
#include <mach/rpc_hsusb.h>
static struct resource resources_uart1[] = {
@@ -299,35 +298,6 @@
return platform_device_register(pdev);
}
-#ifdef CONFIG_USB_ANDROID_DIAG
-struct usb_diag_platform_data usb_diag_pdata = {
- .ch_name = DIAG_LEGACY,
- .update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
-};
-
-struct platform_device usb_diag_device = {
- .name = "usb_diag",
- .id = -1,
- .dev = {
- .platform_data = &usb_diag_pdata,
- },
-};
-#endif
-
-#ifdef CONFIG_USB_F_SERIAL
-static struct usb_gadget_fserial_platform_data fserial_pdata = {
- .no_ports = 2,
-};
-
-struct platform_device usb_gadget_fserial_device = {
- .name = "usb_fserial",
- .id = -1,
- .dev = {
- .platform_data = &fserial_pdata,
- },
-};
-#endif
-
struct platform_device asoc_msm_pcm = {
.name = "msm-dsp-audio",
.id = 0,
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index ef187a6..488db75 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -414,14 +414,14 @@
},
{
.name = "sdcc_dma_chnl",
- .start = DMOV_SDC4_CHAN,
- .end = DMOV_SDC4_CHAN,
+ .start = DMOV_SDC3_CHAN,
+ .end = DMOV_SDC3_CHAN,
.flags = IORESOURCE_DMA,
},
{
.name = "sdcc_dma_crci",
- .start = DMOV_SDC4_CRCI,
- .end = DMOV_SDC4_CRCI,
+ .start = DMOV_SDC3_CRCI,
+ .end = DMOV_SDC3_CRCI,
.flags = IORESOURCE_DMA,
},
};
@@ -439,14 +439,14 @@
},
{
.name = "sdcc_dma_chnl",
- .start = DMOV_SDC3_CHAN,
- .end = DMOV_SDC3_CHAN,
+ .start = DMOV_SDC4_CHAN,
+ .end = DMOV_SDC4_CHAN,
.flags = IORESOURCE_DMA,
},
{
.name = "sdcc_dma_crci",
- .start = DMOV_SDC3_CRCI,
- .end = DMOV_SDC3_CRCI,
+ .start = DMOV_SDC4_CRCI,
+ .end = DMOV_SDC4_CRCI,
.flags = IORESOURCE_DMA,
},
};
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index e1a3b4c..0da9de3 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -666,14 +666,14 @@
},
{
.name = "sdcc_dma_chnl",
- .start = DMOV_SDC4_CHAN,
- .end = DMOV_SDC4_CHAN,
+ .start = DMOV_SDC3_CHAN,
+ .end = DMOV_SDC3_CHAN,
.flags = IORESOURCE_DMA,
},
{
.name = "sdcc_dma_crci",
- .start = DMOV_SDC4_CRCI,
- .end = DMOV_SDC4_CRCI,
+ .start = DMOV_SDC3_CRCI,
+ .end = DMOV_SDC3_CRCI,
.flags = IORESOURCE_DMA,
},
};
@@ -691,14 +691,14 @@
},
{
.name = "sdcc_dma_chnl",
- .start = DMOV_SDC3_CHAN,
- .end = DMOV_SDC3_CHAN,
+ .start = DMOV_SDC4_CHAN,
+ .end = DMOV_SDC4_CHAN,
.flags = IORESOURCE_DMA,
},
{
.name = "sdcc_dma_crci",
- .start = DMOV_SDC3_CRCI,
- .end = DMOV_SDC3_CRCI,
+ .start = DMOV_SDC4_CRCI,
+ .end = DMOV_SDC4_CRCI,
.flags = IORESOURCE_DMA,
},
};
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index f4bc5f0..8280aa0 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -1461,6 +1461,22 @@
#define MHZ (1000*1000)
+#define TCSR_GSBI_IRQ_MUX_SEL 0x0044
+
+#define GSBI_IRQ_MUX_SEL_MASK 0xF
+#define GSBI_IRQ_MUX_SEL_DSPS 0xB
+
+static void dsps_init1(struct msm_dsps_platform_data *data)
+{
+ int val;
+
+ /* route GSBI12 interrutps to DSPS */
+ val = secure_readl(MSM_TCSR_BASE + TCSR_GSBI_IRQ_MUX_SEL);
+ val &= ~GSBI_IRQ_MUX_SEL_MASK;
+ val |= GSBI_IRQ_MUX_SEL_DSPS;
+ secure_writel(val, MSM_TCSR_BASE + TCSR_GSBI_IRQ_MUX_SEL);
+}
+
static struct dsps_clk_info dsps_clks[] = {
{
.name = "ppss_pclk",
@@ -1503,6 +1519,7 @@
.gpios_num = 0,
.regs = dsps_regs,
.regs_num = ARRAY_SIZE(dsps_regs),
+ .init = dsps_init1,
.signature = DSPS_SIGNATURE,
};
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 2dbbc7d..df6a64c 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -24,9 +24,7 @@
#include <linux/leds-pmic8058.h>
#include <linux/clkdev.h>
#include <linux/msm_ssbi.h>
-#ifdef CONFIG_MSM_BUS_SCALING
#include <mach/msm_bus.h>
-#endif
struct msm_camera_io_ext {
uint32_t mdcphy;
@@ -62,9 +60,7 @@
struct msm_camera_io_ext ioext;
struct msm_camera_io_clk ioclk;
uint8_t csid_core;
-#ifdef CONFIG_MSM_BUS_SCALING
struct msm_bus_scale_pdata *cam_bus_scale_table;
-#endif
};
enum msm_camera_csi_data_format {
CSI_8BIT,
diff --git a/arch/arm/mach-msm/include/mach/msm_dsps.h b/arch/arm/mach-msm/include/mach/msm_dsps.h
index 824ef5f..cfb2024 100644
--- a/arch/arm/mach-msm/include/mach/msm_dsps.h
+++ b/arch/arm/mach-msm/include/mach/msm_dsps.h
@@ -86,6 +86,7 @@
struct dsps_regulator_info *regs;
int regs_num;
int dsps_pwr_ctl_en;
+ void (*init)(struct msm_dsps_platform_data *data);
u32 signature;
};
diff --git a/arch/arm/mach-msm/include/mach/rpm-8960.h b/arch/arm/mach-msm/include/mach/rpm-8960.h
index bee47a5..d5ebba0 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8960.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8960.h
@@ -440,8 +440,10 @@
MSM_RPM_STATUS_ID_HDMI_SWITCH = 120,
MSM_RPM_STATUS_ID_DDR_DMM_0 = 121,
MSM_RPM_STATUS_ID_DDR_DMM_1 = 122,
+ MSM_RPM_STATUS_ID_EBI1_CH0_RANGE = 123,
+ MSM_RPM_STATUS_ID_EBI1_CH1_RANGE = 124,
- MSM_RPM_STATUS_ID_LAST = MSM_RPM_STATUS_ID_DDR_DMM_1
+ MSM_RPM_STATUS_ID_LAST = MSM_RPM_STATUS_ID_EBI1_CH1_RANGE,
};
#endif /* __ARCH_ARM_MACH_MSM_RPM_8960_H */
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index ea9d246..3d34a30 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -176,6 +176,8 @@
static DEFINE_MUTEX(xprt_info_list_lock);
DECLARE_COMPLETION(msm_ipc_remote_router_up);
+static DECLARE_COMPLETION(msm_ipc_local_router_up);
+#define IPC_ROUTER_INIT_TIMEOUT (10 * HZ)
static uint32_t next_port_id;
static DEFINE_MUTEX(next_port_id_lock);
@@ -2399,8 +2401,16 @@
struct msm_ipc_router_xprt_info *xprt_info = xprt->priv;
struct msm_ipc_router_xprt_work *xprt_work;
struct rr_packet *pkt;
+ unsigned long ret;
- BUG_ON(!msm_ipc_router_workqueue);
+ if (!msm_ipc_router_workqueue) {
+ ret = wait_for_completion_timeout(&msm_ipc_local_router_up,
+ IPC_ROUTER_INIT_TIMEOUT);
+ if (!ret || !msm_ipc_router_workqueue) {
+ pr_err("%s: IPC Router not initialized\n", __func__);
+ return;
+ }
+ }
switch (event) {
case IPC_ROUTER_XPRT_EVENT_OPEN:
@@ -2515,6 +2525,7 @@
if (ret < 0)
pr_err("%s: Init sockets failed\n", __func__);
+ complete_all(&msm_ipc_local_router_up);
return ret;
}
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index 5987752..997d4b5 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -46,7 +46,14 @@
static struct msm_ipc_router_smd_xprt smd_remote_xprt;
+struct msm_ipc_router_smd_xprt_work {
+ struct msm_ipc_router_xprt *xprt;
+ struct work_struct work;
+};
+
static void smd_xprt_read_data(struct work_struct *work);
+static void smd_xprt_open_event(struct work_struct *work);
+static void smd_xprt_close_event(struct work_struct *work);
static DECLARE_DELAYED_WORK(work_read_data, smd_xprt_read_data);
static struct workqueue_struct *smd_xprt_workqueue;
@@ -201,8 +208,10 @@
D("%s: Allocated rr_packet\n", __func__);
}
- if ((pkt_size >= MIN_FRAG_SZ) &&
- (smd_read_avail(smd_remote_xprt.channel) < MIN_FRAG_SZ))
+ if (((pkt_size >= MIN_FRAG_SZ) &&
+ (smd_read_avail(smd_remote_xprt.channel) < MIN_FRAG_SZ)) ||
+ ((pkt_size < MIN_FRAG_SZ) &&
+ (smd_read_avail(smd_remote_xprt.channel) < pkt_size)))
return;
sz = smd_read_avail(smd_remote_xprt.channel);
@@ -249,9 +258,32 @@
}
}
+static void smd_xprt_open_event(struct work_struct *work)
+{
+ struct msm_ipc_router_smd_xprt_work *xprt_work =
+ container_of(work, struct msm_ipc_router_smd_xprt_work, work);
+
+ msm_ipc_router_xprt_notify(xprt_work->xprt,
+ IPC_ROUTER_XPRT_EVENT_OPEN, NULL);
+ D("%s: Notified IPC Router of OPEN Event\n", __func__);
+ kfree(xprt_work);
+}
+
+static void smd_xprt_close_event(struct work_struct *work)
+{
+ struct msm_ipc_router_smd_xprt_work *xprt_work =
+ container_of(work, struct msm_ipc_router_smd_xprt_work, work);
+
+ msm_ipc_router_xprt_notify(xprt_work->xprt,
+ IPC_ROUTER_XPRT_EVENT_CLOSE, NULL);
+ D("%s: Notified IPC Router of CLOSE Event\n", __func__);
+ kfree(xprt_work);
+}
+
static void msm_ipc_router_smd_remote_notify(void *_dev, unsigned event)
{
unsigned long flags;
+ struct msm_ipc_router_smd_xprt_work *xprt_work;
switch (event) {
case SMD_EVENT_DATA:
@@ -266,9 +298,16 @@
spin_lock_irqsave(&modem_reset_lock, flags);
modem_reset = 0;
spin_unlock_irqrestore(&modem_reset_lock, flags);
- msm_ipc_router_xprt_notify(&smd_remote_xprt.xprt,
- IPC_ROUTER_XPRT_EVENT_OPEN, NULL);
- D("%s: Notified IPC Router of OPEN Event\n", __func__);
+ xprt_work = kmalloc(sizeof(struct msm_ipc_router_smd_xprt_work),
+ GFP_ATOMIC);
+ if (!xprt_work) {
+ pr_err("%s: Couldn't notify %d event to IPC Router\n",
+ __func__, event);
+ return;
+ }
+ xprt_work->xprt = &smd_remote_xprt.xprt;
+ INIT_WORK(&xprt_work->work, smd_xprt_open_event);
+ queue_work(smd_xprt_workqueue, &xprt_work->work);
break;
case SMD_EVENT_CLOSE:
@@ -276,9 +315,16 @@
modem_reset = 1;
spin_unlock_irqrestore(&modem_reset_lock, flags);
wake_up(&write_avail_wait_q);
- msm_ipc_router_xprt_notify(&smd_remote_xprt.xprt,
- IPC_ROUTER_XPRT_EVENT_CLOSE, NULL);
- D("%s: Notified IPC Router of CLOSE Event\n", __func__);
+ xprt_work = kmalloc(sizeof(struct msm_ipc_router_smd_xprt_work),
+ GFP_ATOMIC);
+ if (!xprt_work) {
+ pr_err("%s: Couldn't notify %d event to IPC Router\n",
+ __func__, event);
+ return;
+ }
+ xprt_work->xprt = &smd_remote_xprt.xprt;
+ INIT_WORK(&xprt_work->work, smd_xprt_close_event);
+ queue_work(smd_xprt_workqueue, &xprt_work->work);
break;
}
}
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index 014ea99..d8323e3 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -620,7 +620,7 @@
struct msm_bus_fabric_registration *pdata;
fabric = kzalloc(sizeof(struct msm_bus_fabric), GFP_KERNEL);
- if (ZERO_OR_NULL_PTR(fabric)) {
+ if (!fabric) {
MSM_BUS_ERR("Fabric alloc failed\n");
return -ENOMEM;
}
diff --git a/arch/arm/mach-msm/msm_dsps.c b/arch/arm/mach-msm/msm_dsps.c
index b622e74..bcb777f 100644
--- a/arch/arm/mach-msm/msm_dsps.c
+++ b/arch/arm/mach-msm/msm_dsps.c
@@ -505,6 +505,10 @@
} else {
pr_debug("%s: ppss_wdog not supported.\n", __func__);
}
+
+ if (drv->pdata->init)
+ drv->pdata->init(drv->pdata);
+
return 0;
request_irq_err:
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index c517178..8a9ac36 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -39,7 +39,7 @@
static void __iomem *msm_tmr0_base;
/* Watchdog pet interval in ms */
-#define PET_DELAY 3000
+#define PET_DELAY 10000
static unsigned long delay_time;
static unsigned long long last_pet;
@@ -317,11 +317,11 @@
/* 32768 ticks = 1 second */
if (machine_is_msm8960_sim()) {
- __raw_writel(32768*8, msm_tmr0_base + WDT0_BARK_TIME);
- __raw_writel(32768*10, msm_tmr0_base + WDT0_BITE_TIME);
+ __raw_writel(32768*15, msm_tmr0_base + WDT0_BARK_TIME);
+ __raw_writel(32768*17, msm_tmr0_base + WDT0_BITE_TIME);
} else {
- __raw_writel(32768*4, msm_tmr0_base + WDT0_BARK_TIME);
- __raw_writel(32768*5, msm_tmr0_base + WDT0_BITE_TIME);
+ __raw_writel(32768*11, msm_tmr0_base + WDT0_BARK_TIME);
+ __raw_writel(32768*12, msm_tmr0_base + WDT0_BITE_TIME);
}
ret = register_pm_notifier(&msm_watchdog_power_notifier);
diff --git a/arch/arm/mach-msm/peripheral-loader.h b/arch/arm/mach-msm/peripheral-loader.h
index 7357432..097d9d7 100644
--- a/arch/arm/mach-msm/peripheral-loader.h
+++ b/arch/arm/mach-msm/peripheral-loader.h
@@ -9,8 +9,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-#ifndef __MACH_PERIPHERAL_LOADER_H
-#define __MACH_PERIPHERAL_LOADER_H
+#ifndef __MSM_PERIPHERAL_LOADER_H
+#define __MSM_PERIPHERAL_LOADER_H
#include <linux/list.h>
#include <linux/mutex.h>
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 84e798a..3f40a12 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -27,8 +27,6 @@
#include "pm.h"
#include "scm-boot.h"
-#define SECONDARY_CPU_WAIT_MS 10
-
int pen_release = -1;
/* Initialize the present map (cpu_set(i, cpu_present_map)). */
@@ -138,8 +136,8 @@
while (pen_release != 0xFFFFFFFF) {
dmac_inv_range((void *)&pen_release,
(void *)(&pen_release+sizeof(pen_release)));
- msleep_interruptible(1);
- if (cnt++ >= SECONDARY_CPU_WAIT_MS)
+ usleep(500);
+ if (cnt++ >= 10)
break;
}
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index c86fe87..a929659 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -1173,7 +1173,7 @@
init_completion(&dev->cpu_killed);
#endif
}
-
+#ifdef CONFIG_MSM_SCM
ret = scm_set_boot_addr((void *)virt_to_phys(msm_pm_boot_entry),
SCM_FLAG_WARMBOOT_CPU0 | SCM_FLAG_WARMBOOT_CPU1);
if (ret) {
@@ -1181,6 +1181,7 @@
__func__, ret);
return ret;
}
+#endif
#ifdef CONFIG_MSM_IDLE_STATS
for_each_possible_cpu(cpu) {
diff --git a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
index d1a4fe0..401c759 100644
--- a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
+++ b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
@@ -54,6 +54,26 @@
#define SNDDEV_GPIO_MIC1_ANCL_SEL 295
#define SNDDEV_GPIO_HS_MIC4_SEL 296
+#define DSP_RAM_BASE_8x60 0x46700000
+#define DSP_RAM_SIZE_8x60 0x2000000
+static int dspcrashd_pdata_8x60 = 0xDEADDEAD;
+
+static struct resource resources_dspcrashd_8x60[] = {
+ {
+ .name = "msm_dspcrashd",
+ .start = DSP_RAM_BASE_8x60,
+ .end = DSP_RAM_BASE_8x60 + DSP_RAM_SIZE_8x60,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device msm_device_dspcrashd_8x60 = {
+ .name = "msm_dspcrashd",
+ .num_resources = ARRAY_SIZE(resources_dspcrashd_8x60),
+ .resource = resources_dspcrashd_8x60,
+ .dev = { .platform_data = &dspcrashd_pdata_8x60 },
+};
+
static struct resource msm_cdcclk_ctl_resources[] = {
{
.name = "msm_snddev_tx_mclk",
@@ -2571,6 +2591,7 @@
&msm_cdcclk_ctl_device,
&msm_mi2s_device,
&msm_uplink_rx_device,
+ &msm_device_dspcrashd_8x60,
};
#ifdef CONFIG_MSM8X60_FTM_AUDIO_DEVICES
diff --git a/arch/arm/mach-msm/qdsp6v2/dsp_debug.c b/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
index 4382c23..1d8195e 100644
--- a/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
+++ b/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
@@ -22,6 +22,7 @@
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/delay.h>
+#include <linux/platform_device.h>
#include <asm/atomic.h>
#include "../proc_comm.h"
@@ -57,8 +58,6 @@
}
if (cb_ptr)
cb_ptr(DSP_STATE_CRASH_DUMP_DONE);
-
- BUG();
}
static int dsp_open(struct inode *inode, struct file *file)
@@ -125,10 +124,9 @@
return count;
}
-#define DSP_RAM_BASE 0x46700000
-#define DSP_RAM_SIZE 0x2000000
-
static unsigned copy_ok_count;
+static uint32_t dsp_ram_size;
+static uint32_t dsp_ram_base;
static ssize_t dsp_read(struct file *file, char __user *buf,
size_t count, loff_t *pos)
@@ -140,13 +138,20 @@
unsigned int flags = MSM_SUBSYSTEM_MAP_KADDR | MSM_SUBSYSTEM_MAP_CACHED;
struct msm_mapped_buffer *mem_buffer;
- if (*pos >= DSP_RAM_SIZE)
+ if ((dsp_ram_base == 0) || (dsp_ram_size == 0)) {
+ pr_err("[%s:%s] Memory Invalid or not initialized, Base = 0x%x,"
+ " size = 0x%x\n", __MM_FILE__,
+ __func__, dsp_ram_base, dsp_ram_size);
+ return -EINVAL;
+ }
+
+ if (*pos >= dsp_ram_size)
return 0;
if (*pos & (PAGE_SIZE - 1))
return -EINVAL;
- addr = (*pos + DSP_RAM_BASE);
+ addr = (*pos + dsp_ram_base);
/* don't blow up if we're unaligned */
if (addr & (PAGE_SIZE - 1))
@@ -200,6 +205,28 @@
return 0;
}
+static int dspcrashd_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ struct resource *res;
+ int *pdata;
+
+ pdata = pdev->dev.platform_data;
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA,
+ "msm_dspcrashd");
+ if (!res) {
+ pr_err("%s: failed to get resources for dspcrashd\n", __func__);
+ return -ENODEV;
+ }
+
+ dsp_ram_base = res->start;
+ dsp_ram_size = res->end - res->start;
+ pr_info("%s: Platform driver values: Base = 0x%x, Size = 0x%x,"
+ "pdata = 0x%x\n", __func__,
+ dsp_ram_base, dsp_ram_size, *pdata);
+ return rc;
+}
+
static const struct file_operations dsp_fops = {
.owner = THIS_MODULE,
.open = dsp_open,
@@ -214,11 +241,27 @@
.fops = &dsp_fops,
};
+static struct platform_driver dspcrashd_driver = {
+ .probe = dspcrashd_probe,
+ .driver = { .name = "msm_dspcrashd"}
+};
static int __init dsp_init(void)
{
+ int rc = 0;
init_waitqueue_head(&dsp_wait);
+ rc = platform_driver_register(&dspcrashd_driver);
+ if (IS_ERR_VALUE(rc)) {
+ pr_err("%s: platform_driver_register for dspcrashd failed\n",
+ __func__);
+ }
return misc_register(&dsp_misc);
}
+static int __exit dsp_exit(void)
+{
+ platform_driver_unregister(&dspcrashd_driver);
+ return 0;
+}
+
device_initcall(dsp_init);
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_out.c b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
index b8521f6..75975cc 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_out.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
@@ -52,7 +52,6 @@
atomic_t out_stopped;
atomic_t out_prefill;
struct wake_lock wakelock;
- struct wake_lock idlelock;
};
void pcm_out_cb(uint32_t opcode, uint32_t token,
@@ -77,14 +76,12 @@
{
pr_debug("%s:\n", __func__);
wake_lock(&audio->wakelock);
- wake_lock(&audio->idlelock);
}
static void audio_allow_sleep(struct pcm *audio)
{
pr_debug("%s:\n", __func__);
wake_unlock(&audio->wakelock);
- wake_unlock(&audio->idlelock);
}
static int pcm_out_enable(struct pcm *pcm)
@@ -336,8 +333,6 @@
atomic_set(&pcm->out_opened, 1);
snprintf(name, sizeof name, "audio_pcm_%x", pcm->ac->session);
wake_lock_init(&pcm->wakelock, WAKE_LOCK_SUSPEND, name);
- snprintf(name, sizeof name, "audio_pcm_idle_%x", pcm->ac->session);
- wake_lock_init(&pcm->idlelock, WAKE_LOCK_IDLE, name);
rc = auddev_register_evt_listner(pcm->stream_event,
AUDDEV_CLNT_DEC,
@@ -441,7 +436,6 @@
q6asm_audio_client_free(pcm->ac);
audio_allow_sleep(pcm);
wake_lock_destroy(&pcm->wakelock);
- wake_lock_destroy(&pcm->idlelock);
mutex_destroy(&pcm->lock);
mutex_destroy(&pcm->write_lock);
kfree(pcm);
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c
index 0abc9ff..a1bdcfd 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c
@@ -374,6 +374,9 @@
trc = afe_open(icodec->data->copp_id, &afe_config, icodec->sample_rate);
+ if (trc < 0)
+ pr_err("%s: afe open failed, trc = %d\n", __func__, trc);
+
/* Enable ADIE */
if (icodec->adie_path) {
adie_codec_proceed_stage(icodec->adie_path,
@@ -665,18 +668,24 @@
mutex_lock(&drv->rx_lock);
if (drv->rx_active) {
mutex_unlock(&drv->rx_lock);
+ pr_err("%s: rx_active is set, return EBUSY\n",
+ __func__);
rc = -EBUSY;
goto error;
}
rc = snddev_icodec_open_rx(icodec);
if (!IS_ERR_VALUE(rc)) {
- drv->rx_active = 1;
if ((icodec->data->dev_vol_type & (
SNDDEV_DEV_VOL_DIGITAL |
SNDDEV_DEV_VOL_ANALOG)))
rc = snddev_icodec_set_device_volume_impl(
dev_info, dev_info->dev_volume);
+ if (!IS_ERR_VALUE(rc))
+ drv->rx_active = 1;
+ else
+ pr_err("%s: set_device_volume_impl"
+ " error(rx) = %d\n", __func__, rc);
}
mutex_unlock(&drv->rx_lock);
} else if (icodec->data->capability & SNDDEV_CAP_LB) {
@@ -696,18 +705,24 @@
mutex_lock(&drv->tx_lock);
if (drv->tx_active) {
mutex_unlock(&drv->tx_lock);
+ pr_err("%s: tx_active is set, return EBUSY\n",
+ __func__);
rc = -EBUSY;
goto error;
}
rc = snddev_icodec_open_tx(icodec);
if (!IS_ERR_VALUE(rc)) {
- drv->tx_active = 1;
if ((icodec->data->dev_vol_type & (
SNDDEV_DEV_VOL_DIGITAL |
SNDDEV_DEV_VOL_ANALOG)))
rc = snddev_icodec_set_device_volume_impl(
dev_info, dev_info->dev_volume);
+ if (!IS_ERR_VALUE(rc))
+ drv->tx_active = 1;
+ else
+ pr_err("%s: set_device_volume_impl"
+ " error(tx) = %d\n", __func__, rc);
}
mutex_unlock(&drv->tx_lock);
}
@@ -731,12 +746,15 @@
mutex_lock(&drv->rx_lock);
if (!drv->rx_active) {
mutex_unlock(&drv->rx_lock);
+ pr_err("%s: rx_active not set, return\n", __func__);
rc = -EPERM;
goto error;
}
rc = snddev_icodec_close_rx(icodec);
if (!IS_ERR_VALUE(rc))
drv->rx_active = 0;
+ else
+ pr_err("%s: close rx failed, rc = %d\n", __func__, rc);
mutex_unlock(&drv->rx_lock);
} else if (icodec->data->capability & SNDDEV_CAP_LB) {
mutex_lock(&drv->lb_lock);
@@ -746,12 +764,15 @@
mutex_lock(&drv->tx_lock);
if (!drv->tx_active) {
mutex_unlock(&drv->tx_lock);
+ pr_err("%s: tx_active not set, return\n", __func__);
rc = -EPERM;
goto error;
}
rc = snddev_icodec_close_tx(icodec);
if (!IS_ERR_VALUE(rc))
drv->tx_active = 0;
+ else
+ pr_err("%s: close tx failed, rc = %d\n", __func__, rc);
mutex_unlock(&drv->tx_lock);
}
@@ -789,10 +810,12 @@
icodec = dev_info->private_data;
if (adie_codec_freq_supported(icodec->data->profile, rate) != 0) {
+ pr_err("%s: adie_codec_freq_supported() failed\n", __func__);
rc = -EINVAL;
goto error;
} else {
if (snddev_icodec_check_freq(rate) != 0) {
+ pr_err("%s: check_freq failed\n", __func__);
rc = -EINVAL;
goto error;
} else
diff --git a/arch/arm/mach-msm/qdss-etb.c b/arch/arm/mach-msm/qdss-etb.c
index d4f7940..16f8a5b 100644
--- a/arch/arm/mach-msm/qdss-etb.c
+++ b/arch/arm/mach-msm/qdss-etb.c
@@ -12,6 +12,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
@@ -20,6 +23,7 @@
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/mutex.h>
#include "qdss.h"
@@ -47,6 +51,7 @@
#define BYTES_PER_WORD 4
#define ETB_SIZE_WORDS 4096
+#define FRAME_SIZE_WORDS 4
#define ETB_LOCK() \
do { \
@@ -132,12 +137,24 @@
uint32_t read_data;
uint32_t read_ptr;
uint32_t write_ptr;
+ uint32_t frame_off;
+ uint32_t frame_endoff;
ETB_UNLOCK();
read_ptr = etb_readl(etb, ETB_RAM_READ_POINTER);
write_ptr = etb_readl(etb, ETB_RAM_WRITE_POINTER);
+ frame_off = write_ptr % FRAME_SIZE_WORDS;
+ frame_endoff = FRAME_SIZE_WORDS - frame_off;
+ if (frame_off) {
+ dev_err(etb.dev, "write_ptr: %lu not aligned to formatter "
+ "frame size\n", (unsigned long)write_ptr);
+ dev_err(etb.dev, "frameoff: %lu, frame_endoff: %lu\n",
+ (unsigned long)frame_off, (unsigned long)frame_endoff);
+ write_ptr += frame_endoff;
+ }
+
if ((etb_readl(etb, ETB_STATUS_REG) & BIT(0)) == 0)
etb_writel(etb, 0x0, ETB_RAM_READ_POINTER);
else
@@ -146,14 +163,20 @@
buf_ptr = etb.buf;
for (i = 0; i < ETB_SIZE_WORDS; i++) {
read_data = etb_readl(etb, ETB_RAM_READ_DATA_REG);
- *buf_ptr = read_data >> 0;
- buf_ptr++;
- *buf_ptr = read_data >> 8;
- buf_ptr++;
- *buf_ptr = read_data >> 16;
- buf_ptr++;
- *buf_ptr = read_data >> 24;
- buf_ptr++;
+ *buf_ptr++ = read_data >> 0;
+ *buf_ptr++ = read_data >> 8;
+ *buf_ptr++ = read_data >> 16;
+ *buf_ptr++ = read_data >> 24;
+ }
+
+ if (frame_off) {
+ buf_ptr -= (frame_endoff * BYTES_PER_WORD);
+ for (i = 0; i < frame_endoff; i++) {
+ *buf_ptr++ = 0x0;
+ *buf_ptr++ = 0x0;
+ *buf_ptr++ = 0x0;
+ *buf_ptr++ = 0x0;
+ }
}
etb_writel(etb, read_ptr, ETB_RAM_READ_POINTER);
diff --git a/arch/arm/mach-msm/qdss-funnel.c b/arch/arm/mach-msm/qdss-funnel.c
index 9ad407b..290b418 100644
--- a/arch/arm/mach-msm/qdss-funnel.c
+++ b/arch/arm/mach-msm/qdss-funnel.c
@@ -12,6 +12,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
diff --git a/arch/arm/mach-msm/qdss-ptm.c b/arch/arm/mach-msm/qdss-ptm.c
index 28dd171..4e8add7 100644
--- a/arch/arm/mach-msm/qdss-ptm.c
+++ b/arch/arm/mach-msm/qdss-ptm.c
@@ -12,6 +12,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
diff --git a/arch/arm/mach-msm/qdss-tpiu.c b/arch/arm/mach-msm/qdss-tpiu.c
index def7467..60a8dd2 100644
--- a/arch/arm/mach-msm/qdss-tpiu.c
+++ b/arch/arm/mach-msm/qdss-tpiu.c
@@ -12,6 +12,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
@@ -56,7 +58,6 @@
struct tpiu_ctx {
void __iomem *base;
bool enabled;
- atomic_t in_use;
struct device *dev;
};
diff --git a/arch/arm/mach-msm/qdss.h b/arch/arm/mach-msm/qdss.h
index e4e6b0c..a41d7e2 100644
--- a/arch/arm/mach-msm/qdss.h
+++ b/arch/arm/mach-msm/qdss.h
@@ -13,6 +13,8 @@
#ifndef _ARCH_ARM_MACH_MSM_QDSS_H_
#define _ARCH_ARM_MACH_MSM_QDSS_H_
+#include <linux/bitops.h>
+
/* Coresight management registers (0xF00-0xFCC) */
#define CS_ITCTRL (0xF00)
#define CS_CLAIMSET (0xFA0)
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
index d71313d..9653b9a 100644
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ b/arch/arm/mach-msm/sdio_al_test.c
@@ -58,6 +58,7 @@
#define MAX_XFER_SIZE (16*1024)
#define SMEM_MAX_XFER_SIZE 0xBC000
#define A2_MIN_PACKET_SIZE 5
+#define RMNT_PACKET_SIZE (4*1024)
#define DUN_PACKET_SIZE (2*1024)
#define TEST_DBG(x...) if (test_ctx->runtime_debug) pr_info(x)
@@ -72,6 +73,12 @@
#define A2_HEADER_OVERHEAD 8
+enum rx_process_state {
+ RX_PROCESS_PACKET_INIT,
+ RX_PROCESS_A2_HEADER,
+ RX_PROCESS_PACKET_DATA,
+};
+
enum sdio_test_case_type {
SDIO_TEST_LOOPBACK_HOST,
SDIO_TEST_LOOPBACK_CLIENT,
@@ -80,6 +87,7 @@
SDIO_TEST_LPM_RANDOM,
SDIO_TEST_HOST_SENDER_NO_LP,
SDIO_TEST_CLOSE_CHANNEL,
+ SDIO_TEST_A2_VALIDATION,
/* The following tests are not part of the 9k tests and should be
* kept last in case new tests are added
*/
@@ -228,6 +236,8 @@
struct dentry *rpc_qmi_diag_sender_test;
struct dentry *smem_test;
struct dentry *smem_rpc_test;
+ struct dentry *rmnet_a2_validation_test;
+ struct dentry *dun_a2_validation_test;
struct dentry *rmnet_a2_perf_test;
struct dentry *dun_a2_perf_test;
struct dentry *rmnet_dun_a2_perf_test;
@@ -280,6 +290,8 @@
u8 *smem_buf;
uint32_t smem_counter;
+ struct platform_device *ciq_app_pdev;
+
wait_queue_head_t wait_q;
int test_completed;
int test_result;
@@ -293,6 +305,7 @@
/* FORWARD DECLARATIONS */
static int set_params_loopback_9k(struct test_channel *tch);
static int set_params_smem_test(struct test_channel *tch);
+static int set_params_a2_validation(struct test_channel *tch);
static int set_params_a2_perf(struct test_channel *tch);
static int set_params_8k_sender_no_lp(struct test_channel *tch);
static int set_params_a2_small_pkts(struct test_channel *tch);
@@ -662,6 +675,140 @@
.read = smem_rpc_test_read,
};
+/* RMNET A2 VALIDATION TEST */
+static ssize_t rmnet_a2_validation_test_write(struct file *file,
+ const char __user *buf,
+ size_t count,
+ loff_t *ppos)
+{
+ int ret = 0;
+ int i = 0;
+ int number = -1;
+
+ pr_info(TEST_MODULE_NAME "-- RMNET A2 VALIDATION TEST --\n");
+
+ number = sdio_al_test_extract_number(buf, count);
+
+ if (number < 0) {
+ pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
+ "failed. number = %d\n", __func__, number);
+ return count;
+ }
+
+ for (i = 0 ; i < number ; ++i) {
+ pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
+ pr_info(TEST_MODULE_NAME " ===================");
+
+ sdio_al_test_initial_dev_and_chan(test_ctx);
+
+ set_params_a2_validation(test_ctx->test_ch_arr[SDIO_RMNT]);
+
+ ret = test_start();
+
+ if (ret)
+ break;
+ }
+
+ return count;
+}
+
+static ssize_t rmnet_a2_validation_test_read(struct file *file,
+ char __user *buffer,
+ size_t count,
+ loff_t *offset)
+{
+ memset((void *)buffer, 0, count);
+
+ snprintf(buffer, count,
+ "\nRMNET_A2_VALIDATION_TEST\n"
+ "=========================\n"
+ "Description:\n"
+ "In this test, the HOST sends multiple packets to the\n"
+ "CLIENT and validates the packets loop backed from A2\n"
+ "for the RMNET channel.\n\n"
+ "END OF DESCRIPTION\n");
+
+ if (message_repeat == 1) {
+ message_repeat = 0;
+ return strnlen(buffer, count);
+ } else {
+ return 0;
+ }
+}
+
+const struct file_operations rmnet_a2_validation_test_ops = {
+ .open = sdio_al_test_open,
+ .write = rmnet_a2_validation_test_write,
+ .read = rmnet_a2_validation_test_read,
+};
+
+/* DUN A2 VALIDATION TEST */
+static ssize_t dun_a2_validation_test_write(struct file *file,
+ const char __user *buf,
+ size_t count,
+ loff_t *ppos)
+{
+ int ret = 0;
+ int i = 0;
+ int number = -1;
+
+ pr_info(TEST_MODULE_NAME "-- DUN A2 VALIDATION TEST --\n");
+
+ number = sdio_al_test_extract_number(buf, count);
+
+ if (number < 0) {
+ pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
+ "failed. number = %d\n", __func__, number);
+ return count;
+ }
+
+ for (i = 0 ; i < number ; ++i) {
+ pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
+ pr_info(TEST_MODULE_NAME " ===================");
+
+ sdio_al_test_initial_dev_and_chan(test_ctx);
+
+ set_params_a2_validation(test_ctx->test_ch_arr[SDIO_DUN]);
+
+ ret = test_start();
+
+ if (ret)
+ break;
+ }
+
+ return count;
+}
+
+static ssize_t dun_a2_validation_test_read(struct file *file,
+ char __user *buffer,
+ size_t count,
+ loff_t *offset)
+{
+ memset((void *)buffer, 0, count);
+
+ snprintf(buffer, count,
+ "\nDUN_A2_VALIDATION_TEST\n"
+ "=========================\n"
+ "Description:\n"
+ "In this test, the HOST sends multiple packets to the\n"
+ "CLIENT and validates the packets loop backed from A2\n"
+ "for the DUN channel.\n\n"
+ "END OF DESCRIPTION\n");
+
+ if (message_repeat == 1) {
+ message_repeat = 0;
+ return strnlen(buffer, count);
+ } else {
+ return 0;
+ }
+}
+
+const struct file_operations dun_a2_validation_test_ops = {
+ .open = sdio_al_test_open,
+ .write = dun_a2_validation_test_write,
+ .read = dun_a2_validation_test_read,
+};
+
/* RMNET A2 PERFORMANCE TEST */
static ssize_t rmnet_a2_perf_test_write(struct file *file,
const char __user *buf,
@@ -2170,50 +2317,64 @@
NULL,
&rpc_qmi_diag_sender_test_ops);
- test_ctx->debug.smem_test =
- debugfs_create_file("40_smem_test",
+ test_ctx->debug.rmnet_a2_validation_test =
+ debugfs_create_file("30_rmnet_a2_validation_test",
S_IRUGO | S_IWUGO,
test_ctx->debug.debug_root,
NULL,
- &smem_test_ops);
+ &rmnet_a2_validation_test_ops);
- test_ctx->debug.smem_rpc_test =
- debugfs_create_file("50_smem_rpc_test",
+ test_ctx->debug.dun_a2_validation_test =
+ debugfs_create_file("40_dun_a2_validation_test",
S_IRUGO | S_IWUGO,
test_ctx->debug.debug_root,
NULL,
- &smem_rpc_test_ops);
+ &dun_a2_validation_test_ops);
test_ctx->debug.rmnet_a2_perf_test =
- debugfs_create_file("60_rmnet_a2_perf_test",
+ debugfs_create_file("50_rmnet_a2_perf_test",
S_IRUGO | S_IWUGO,
test_ctx->debug.debug_root,
NULL,
&rmnet_a2_perf_test_ops);
test_ctx->debug.dun_a2_perf_test =
- debugfs_create_file("70_dun_a2_perf_test",
+ debugfs_create_file("60_dun_a2_perf_test",
S_IRUGO | S_IWUGO,
test_ctx->debug.debug_root,
NULL,
&dun_a2_perf_test_ops);
test_ctx->debug.rmnet_dun_a2_perf_test =
- debugfs_create_file("80_rmnet_dun_a2_perf_test",
+ debugfs_create_file("70_rmnet_dun_a2_perf_test",
S_IRUGO | S_IWUGO,
test_ctx->debug.debug_root,
NULL,
&rmnet_dun_a2_perf_test_ops);
test_ctx->debug.rpc_sender_rmnet_a2_perf_test =
- debugfs_create_file("90_rpc_sender_rmnet_a2_perf_test",
+ debugfs_create_file("80_rpc_sender_rmnet_a2_perf_test",
S_IRUGO | S_IWUGO,
test_ctx->debug.debug_root,
NULL,
&rpc_sender_rmnet_a2_perf_test_ops);
+ test_ctx->debug.smem_test =
+ debugfs_create_file("90_smem_test",
+ S_IRUGO | S_IWUGO,
+ test_ctx->debug.debug_root,
+ NULL,
+ &smem_test_ops);
+
+ test_ctx->debug.smem_rpc_test =
+ debugfs_create_file("100_smem_rpc_test",
+ S_IRUGO | S_IWUGO,
+ test_ctx->debug.debug_root,
+ NULL,
+ &smem_rpc_test_ops);
+
test_ctx->debug.all_channels_test =
- debugfs_create_file("100_all_channels_test",
+ debugfs_create_file("150_all_channels_test",
S_IRUGO | S_IWUGO,
test_ctx->debug.debug_root,
NULL,
@@ -3019,7 +3180,6 @@
if (test_dev->open_channels_counter_to_recv != 0 ||
test_dev->open_channels_counter_to_send != 0) {
test_ch->test_completed = 1;
- test_ch->next_index_in_sent_msg_per_chan = 0;
return 0;
} else {
test_ctx->number_of_active_devices--;
@@ -3056,9 +3216,6 @@
test_dev->final_result_per_dev = 0; /* FAILED */
}
- test_dev->next_avail_entry_in_array = 0;
- test_ch->next_index_in_sent_msg_per_chan = 0;
-
check_test_completion();
kfree(test_ch->test_device->lpm_arr);
@@ -3142,8 +3299,7 @@
"thread", __func__);
}
- while (test_ch->next_index_in_sent_msg_per_chan <=
- test_ch->config_msg.num_packets - 1) {
+ while (1) {
struct lpm_msg msg;
u32 ret = 0;
@@ -3201,6 +3357,14 @@
test_ch->next_index_in_sent_msg_per_chan++;
+ if (test_ch->next_index_in_sent_msg_per_chan ==
+ test_ch->config_msg.num_packets) {
+ spin_unlock_irqrestore(
+ &test_dev->lpm_array_lock,
+ test_dev->lpm_array_lock_flags);
+ break;
+ }
+
spin_unlock_irqrestore(&test_dev->lpm_array_lock,
test_dev->lpm_array_lock_flags);
}
@@ -4189,6 +4353,285 @@
/**
+ * Process Rx Data - Helper for A2 Validation Test
+ * @test_ch(in/out) : Test channel that contains Rx data buffer to process.
+ *
+ * @rx_unprocessed_bytes(in) : Number of bytes to process in the buffer.
+ *
+ * @rx_process_packet_state(in/out) :
+ * Current processing state (used to identify what to process
+ * next in a partial packet)
+ *
+ * @rx_packet_size(in/out) :
+ * Number of bytes remaining in the packet to be processed.
+ *
+ * @rx_packet_count(in/out) :
+ * Number of packets processed.
+ */
+static int process_rx_data(struct test_channel *test_ch,
+ u32 rx_unprocessed_bytes,
+ int *rx_process_packet_state,
+ u16 *rx_packet_size,
+ int *rx_packet_count)
+{
+ u8 *buf = (u8 *)test_ch->buf;
+ int eop = 0;
+ int i = 0;
+ int ret = 0;
+ u32 *ptr = 0;
+ u16 size = 0;
+
+ /* process rx data */
+ while (rx_unprocessed_bytes) {
+ TEST_DBG(TEST_MODULE_NAME ": unprocessed bytes : %u\n",
+ rx_unprocessed_bytes);
+
+ switch (*rx_process_packet_state) {
+ case RX_PROCESS_PACKET_INIT:
+ /* process the A2 header */
+ TEST_DBG(TEST_MODULE_NAME ": "
+ "RX_PROCESS_PACKET_INIT\n");
+ *rx_process_packet_state = RX_PROCESS_PACKET_INIT;
+ if (rx_unprocessed_bytes < 4)
+ break;
+
+ i += 4;
+ rx_unprocessed_bytes -= 4;
+
+ case RX_PROCESS_A2_HEADER:
+ /* process the rest of A2 header */
+ TEST_DBG(TEST_MODULE_NAME ": RX_PROCESS_A2_HEADER\n");
+ *rx_process_packet_state = RX_PROCESS_A2_HEADER;
+ if (rx_unprocessed_bytes < 4)
+ break;
+
+ ptr = (u32 *)&buf[i];
+ /*
+ * upper 2 bytes of the last 4 bytes of A2 header
+ * contains the size of the packet
+ */
+ *rx_packet_size = *ptr >> 0x10;
+
+ i += 4;
+ rx_unprocessed_bytes -= 4;
+
+ case RX_PROCESS_PACKET_DATA:
+ /* process the2_2_ packet data */
+ TEST_DBG(TEST_MODULE_NAME ": RX_PROCESS_PACKET_DATA "
+ "- packet size - %u\n", *rx_packet_size);
+ *rx_process_packet_state = RX_PROCESS_PACKET_DATA;
+
+ size = *rx_packet_size;
+ if (*rx_packet_size <= rx_unprocessed_bytes) {
+ eop = *rx_packet_size;
+ *rx_packet_size = 0;
+ } else {
+ eop = rx_unprocessed_bytes;
+ *rx_packet_size = *rx_packet_size -
+ rx_unprocessed_bytes;
+ }
+
+ /* no more bytes available to process */
+ if (!eop)
+ break;
+ /*
+ * end of packet is starting from
+ * the current position
+ */
+ eop = eop + i;
+ TEST_DBG(TEST_MODULE_NAME ": size - %u, "
+ "packet size - %u eop - %d\n",
+ size, *rx_packet_size, eop);
+
+ /* validate the data */
+ for (; i < eop; i++) {
+ if (buf[i] != (test_ch->rx_bytes % 256)) {
+ pr_err(TEST_MODULE_NAME ": "
+ "Corrupt data. buf:%u, "
+ "data:%u\n", buf[i],
+ test_ch->rx_bytes % 256);
+ ret = -EINVAL;
+ goto err;
+ }
+ rx_unprocessed_bytes--;
+ test_ch->rx_bytes++;
+ }
+
+ /* have more data to be processed */
+ if (*rx_packet_size)
+ break;
+
+ /*
+ * A2 sends data in 4 byte alignment,
+ * skip the padding
+ */
+ if (size % 4) {
+ i += 4 - (size % 4);
+ rx_unprocessed_bytes -= 4 - (size % 4);
+ }
+ *rx_packet_count = *rx_packet_count + 1;
+
+ /* re init the state to process new packet */
+ *rx_process_packet_state = RX_PROCESS_PACKET_INIT;
+ break;
+ default:
+ pr_err(TEST_MODULE_NAME ": Invalid case: %d\n",
+ *rx_process_packet_state);
+ ret = -EINVAL;
+ goto err;
+ }
+ TEST_DBG(TEST_MODULE_NAME ": Continue processing "
+ "if more data is available\n");
+ }
+
+err:
+ return ret;
+}
+
+/**
+ * A2 Validation Test
+ * Send packets and validate the returned packets.
+ * Transmit one packet at a time, while process multiple rx
+ * packets in a single transaction.
+ * A transaction is of size min(random number, write_avail).
+ * A packet consists of a min of 1 byte to channel supported max.
+ */
+static void a2_validation_test(struct test_channel *test_ch)
+{
+ int ret = 0 ;
+ u32 read_avail = 0;
+ u32 write_avail = 0;
+ int tx_packet_count = 0;
+ int rx_packet_count = 0;
+ int initial_rx_packet_count = 0;
+ u32 size = 0;
+ u8 *buf8 = (u8 *)test_ch->buf;
+ int i = 0;
+ int max_packets = test_ch->config_msg.num_packets;
+ u16 tx_packet_size = 0;
+ u16 rx_packet_size = 0;
+ u32 random_num = 0;
+ int rx_process_packet_state = RX_PROCESS_PACKET_INIT;
+
+ pr_info(TEST_MODULE_NAME ": A2 VALIDATION TEST START for chan %s\n",
+ test_ch->name);
+
+ /* Wait for the initial rx messages before starting the test. */
+ rx_cleanup(test_ch, &initial_rx_packet_count);
+
+ test_ch->tx_bytes = 0;
+ test_ch->rx_bytes = 0;
+
+ /* Continue till we have transmitted and received all packets */
+ while ((tx_packet_count < max_packets) ||
+ (rx_packet_count < max_packets)) {
+
+ if (test_ctx->exit_flag) {
+ pr_info(TEST_MODULE_NAME ":Exit Test.\n");
+ return;
+ }
+
+ random_num = get_random_int();
+ size = (random_num % test_ch->packet_length) + 1;
+ TEST_DBG(TEST_MODULE_NAME ": Random tx packet size =%u", size);
+
+ /*
+ * wait for data ready event
+ * use a func to avoid compiler optimizations
+ */
+ write_avail = sdio_write_avail(test_ch->ch);
+ read_avail = sdio_read_avail(test_ch->ch);
+ TEST_DBG(TEST_MODULE_NAME ": write_avail=%d, "
+ "read_avail=%d for chan %s\n",
+ write_avail, read_avail, test_ch->name);
+
+ if ((write_avail == 0) && (read_avail == 0)) {
+ wait_event(test_ch->wait_q,
+ atomic_read(&test_ch->any_notify_count));
+ atomic_set(&test_ch->any_notify_count, 0);
+ }
+
+ /* Transmit data */
+ write_avail = sdio_write_avail(test_ch->ch);
+ if ((tx_packet_count < max_packets) && (write_avail > 0)) {
+ tx_packet_size = min(size, write_avail) ;
+ TEST_DBG(TEST_MODULE_NAME ": tx size = %u, "
+ "write_avail = %u tx_packet# = %d\n",
+ tx_packet_size, write_avail,
+ tx_packet_count);
+ memset(test_ch->buf, 0, test_ch->buf_size);
+ /* populate the buffer */
+ for (i = 0; i < tx_packet_size; i++) {
+ buf8[i] = test_ch->tx_bytes % 256;
+ test_ch->tx_bytes++;
+ }
+
+ ret = sdio_write(test_ch->ch, test_ch->buf,
+ tx_packet_size);
+ if (ret) {
+ pr_err(TEST_MODULE_NAME ":sdio_write err=%d"
+ " for chan %s\n",
+ -ret, test_ch->name);
+ goto exit_err;
+ }
+ tx_packet_count++;
+ }
+
+ /* Receive data */
+ read_avail = sdio_read_avail(test_ch->ch);
+ if (read_avail > 0) {
+ TEST_DBG(TEST_MODULE_NAME ": rx size = %u, "
+ "rx_packet#=%d.\n",
+ read_avail, rx_packet_count);
+ memset(test_ch->buf, 0, test_ch->buf_size);
+
+ ret = sdio_read(test_ch->ch, test_ch->buf,
+ read_avail);
+ if (ret) {
+ pr_err(TEST_MODULE_NAME ": sdio_read "
+ "size %d err=%d for chan %s\n",
+ size, -ret, test_ch->name);
+ goto exit_err;
+ }
+
+ /* Process data */
+ ret = process_rx_data(test_ch, read_avail,
+ &rx_process_packet_state,
+ &rx_packet_size,
+ &rx_packet_count);
+
+ if (ret != 0)
+ goto exit_err;
+ }
+ TEST_DBG(TEST_MODULE_NAME ": Continue loop ...\n");
+ }
+
+ if (test_ch->tx_bytes != test_ch->rx_bytes) {
+ pr_err(TEST_MODULE_NAME ": Total number of bytes "
+ "transmitted (%u) does not match the total "
+ "number of bytes received (%u).", test_ch->tx_bytes,
+ test_ch->rx_bytes);
+ goto exit_err;
+ }
+
+ pr_info(TEST_MODULE_NAME ": A2 VALIDATION TEST END for chan %s.\n",
+ test_ch->name);
+
+ pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
+ test_ch->test_completed = 1;
+ test_ch->test_result = TEST_PASSED;
+ check_test_completion();
+ return;
+
+exit_err:
+ pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
+ test_ch->test_completed = 1;
+ test_ch->test_result = TEST_FAILED;
+ check_test_completion();
+ return;
+}
+
+/**
* sender No loopback Test
*/
static void sender_no_loopback_test(struct test_channel *test_ch)
@@ -4509,6 +4952,9 @@
case SDIO_TEST_MODEM_RESET:
modem_reset_test(test_ch);
break;
+ case SDIO_TEST_A2_VALIDATION:
+ a2_validation_test(test_ch);
+ break;
default:
pr_err(TEST_MODULE_NAME ":Bad Test type = %d.\n",
(int) test_type);
@@ -4847,6 +5293,7 @@
LPM_ARRAY_SIZE;
test_dev->modem_result_per_dev = 1;
tch->modem_result_per_chan = 0;
+ test_dev->next_avail_entry_in_array = 0;
spin_lock_init(&test_dev->
lpm_array_lock);
@@ -4978,6 +5425,7 @@
/* in case there are values left from previous tests */
tch->notify_counter_per_chan = 0;
+ tch->next_index_in_sent_msg_per_chan = 0;
memset(tch->buf, 0x00, tch->buf_size);
tch->test_result = TEST_NO_RESULT;
@@ -5234,6 +5682,31 @@
return 0;
}
+static int set_params_a2_validation(struct test_channel *tch)
+{
+ if (!tch) {
+ pr_err(TEST_MODULE_NAME ":NULL channel\n");
+ return -EINVAL;
+ }
+ tch->is_used = 1;
+ tch->test_type = SDIO_TEST_A2_VALIDATION;
+ tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
+ tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
+
+ if (tch->ch_id == SDIO_RMNT)
+ tch->packet_length = RMNT_PACKET_SIZE;
+ else if (tch->ch_id == SDIO_DUN)
+ tch->packet_length = DUN_PACKET_SIZE;
+ else
+ tch->packet_length = MAX_XFER_SIZE;
+
+ tch->config_msg.num_packets = 10000;
+ tch->config_msg.num_iterations = 1;
+ tch->timer_interval_ms = 0;
+
+ return 0;
+}
+
static int set_params_smem_test(struct test_channel *tch)
{
if (!tch) {
@@ -5544,6 +6017,34 @@
}
+static int sdio_test_channel_ciq_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ if (!pdev)
+ return -ENODEV;
+
+ test_ctx->ciq_app_pdev = platform_device_alloc("SDIO_CIQ_TEST_APP", -1);
+ ret = platform_device_add(test_ctx->ciq_app_pdev);
+ if (ret) {
+ pr_err(MODULE_NAME ":platform_device_add failed, "
+ "ret=%d\n", ret);
+ return ret;
+ }
+
+ return sdio_test_channel_probe(pdev);
+}
+
+static int sdio_test_channel_ciq_remove(struct platform_device *pdev)
+{
+ if (!pdev)
+ return -ENODEV;
+
+ platform_device_unregister(test_ctx->ciq_app_pdev);
+
+ return sdio_test_channel_remove(pdev);
+}
+
static struct platform_driver sdio_rpc_drv = {
.probe = sdio_test_channel_probe,
.remove = sdio_test_channel_remove,
@@ -5599,8 +6100,8 @@
};
static struct platform_driver sdio_ciq_drv = {
- .probe = sdio_test_channel_probe,
- .remove = sdio_test_channel_remove,
+ .probe = sdio_test_channel_ciq_probe,
+ .remove = sdio_test_channel_ciq_remove,
.driver = {
.name = "SDIO_CIQ_TEST",
.owner = THIS_MODULE,
diff --git a/arch/arm/mach-msm/sdio_tty_ciq.c b/arch/arm/mach-msm/sdio_tty_ciq.c
index 8f3d776..64b772d 100644
--- a/arch/arm/mach-msm/sdio_tty_ciq.c
+++ b/arch/arm/mach-msm/sdio_tty_ciq.c
@@ -96,7 +96,7 @@
.probe = sdio_tty_test_probe,
.remove = sdio_tty_remove,
.driver = {
- .name = "SDIO_CIQ_TEST",
+ .name = "SDIO_CIQ_TEST_APP",
.owner = THIS_MODULE,
},
};
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 3db19b6..7dec32a 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -591,6 +591,16 @@
return ret;
}
+static void smd_reset_edge(struct smd_half_channel *ch, unsigned new_state)
+{
+ if (ch->state != SMD_SS_CLOSED) {
+ ch->state = new_state;
+ ch->fDSR = 0;
+ ch->fCTS = 0;
+ ch->fCD = 0;
+ ch->fSTATE = 1;
+ }
+}
static void smd_channel_reset_state(struct smd_alloc_elm *shared,
unsigned new_state, unsigned pid)
@@ -612,20 +622,17 @@
if (!shared2)
continue;
- if (pid_is_on_edge(shared2, type, pid, &local_ch, &remote_ch) ||
- (pid == SMSM_MODEM &&
- pid_is_on_edge(shared2, type, SMD_MODEM_Q6_FW,
- &local_ch, &remote_ch))) {
+ if (pid_is_on_edge(shared2, type, pid, &local_ch, &remote_ch))
+ smd_reset_edge(local_ch, new_state);
- /* force remote state for processor being restarted */
- if (local_ch->state != SMD_SS_CLOSED) {
- local_ch->state = new_state;
- local_ch->fDSR = 0;
- local_ch->fCTS = 0;
- local_ch->fCD = 0;
- local_ch->fSTATE = 1;
- }
- }
+ /*
+ * ModemFW is in the same subsystem as ModemSW, but has
+ * separate SMD edges that need to be reset.
+ */
+ if (pid == SMSM_MODEM &&
+ pid_is_on_edge(shared2, type, SMD_MODEM_Q6_FW,
+ &local_ch, &remote_ch))
+ smd_reset_edge(local_ch, new_state);
}
}
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 118c90b..8e4d98c 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1071,7 +1071,7 @@
int __cpuinit local_timer_setup(struct clock_event_device *evt)
{
unsigned long flags;
- static bool first_boot = true;
+ static DEFINE_PER_CPU(bool, first_boot) = true;
struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
/* Use existing clock_event for cpu 0 */
@@ -1081,11 +1081,11 @@
global_timer_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
__raw_writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
- if (first_boot) {
+ if (__get_cpu_var(first_boot)) {
__raw_writel(0, clock->regbase + TIMER_ENABLE);
__raw_writel(0, clock->regbase + TIMER_CLEAR);
__raw_writel(~0, clock->regbase + TIMER_MATCH_VAL);
- first_boot = false;
+ __get_cpu_var(first_boot) = false;
}
evt->irq = clock->irq.irq;
evt->name = "local_timer";
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 25a4260..95a7079 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -28,6 +28,7 @@
static void __iomem *l2x0_base;
static uint32_t aux_ctrl_save;
+static uint32_t data_latency_ctrl;
static DEFINE_SPINLOCK(l2x0_lock);
static uint32_t l2x0_way_mask; /* Bitmask of active ways */
static uint32_t l2x0_size;
@@ -413,6 +414,7 @@
{
/* Save aux control register value */
aux_ctrl_save = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+ data_latency_ctrl = readl_relaxed(l2x0_base + L2X0_DATA_LATENCY_CTRL);
/* Flush all cache */
l2x0_flush_all();
/* Disable the cache */
@@ -430,6 +432,8 @@
/* Restore aux control register value */
writel_relaxed(aux_ctrl_save, l2x0_base + L2X0_AUX_CTRL);
+ writel_relaxed(data_latency_ctrl, l2x0_base +
+ L2X0_DATA_LATENCY_CTRL);
/* Invalidate the cache */
l2x0_inv_all();
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 4b5e6be..ca501ef 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -658,7 +658,14 @@
else if (!page_count(page))
free_pages++;
page++;
+#ifdef CONFIG_SPARSEMEM
+ pfn1++;
+ if (!(pfn1 % PAGES_PER_SECTION))
+ page = pfn_to_page(pfn1);
+ } while (pfn1 < pfn2);
+#else
} while (page < end);
+#endif
}
/*
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 5c685c3..292fbc3 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -46,6 +46,7 @@
#define MSG_MASK_SIZE 8000
#define LOG_MASK_SIZE 8000
#define EVENT_MASK_SIZE 1000
+#define USER_SPACE_DATA 8000
#define PKT_SIZE 4096
#define MAX_EQUIP_ID 12
@@ -157,6 +158,7 @@
unsigned char *buf_in_wcnss_cntl;
unsigned char *usb_buf_out;
unsigned char *apps_rsp_buf;
+ unsigned char *user_space_data;
smd_channel_t *ch;
smd_channel_t *ch_cntl;
smd_channel_t *chqdsp;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index c9a9d57..6fa043c 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -355,6 +355,8 @@
mutex_lock(&driver->diagchar_mutex);
temp = driver->logging_mode;
driver->logging_mode = (int)ioarg;
+ if (driver->logging_mode == UART_MODE)
+ driver->logging_mode = MEMORY_DEVICE_MODE;
driver->logging_process_id = current->tgid;
mutex_unlock(&driver->diagchar_mutex);
if (temp == MEMORY_DEVICE_MODE && driver->logging_mode
@@ -363,12 +365,14 @@
driver->in_busy_2 = 1;
driver->in_busy_qdsp_1 = 1;
driver->in_busy_qdsp_2 = 1;
+ driver->in_busy_wcnss = 1;
} else if (temp == NO_LOGGING_MODE && driver->logging_mode
== MEMORY_DEVICE_MODE) {
driver->in_busy_1 = 0;
driver->in_busy_2 = 0;
driver->in_busy_qdsp_1 = 0;
driver->in_busy_qdsp_2 = 0;
+ driver->in_busy_wcnss = 0;
/* Poll SMD channels to check for data*/
if (driver->ch)
queue_work(driver->diag_wq,
@@ -376,6 +380,9 @@
if (driver->chqdsp)
queue_work(driver->diag_wq,
&(driver->diag_read_smd_qdsp_work));
+ if (driver->ch_wcnss)
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_wcnss_work));
}
#ifdef CONFIG_DIAG_OVER_USB
else if (temp == USB_MODE && driver->logging_mode
@@ -391,6 +398,7 @@
driver->in_busy_2 = 0;
driver->in_busy_qdsp_2 = 0;
driver->in_busy_qdsp_2 = 0;
+ driver->in_busy_wcnss = 0;
/* Poll SMD channels to check for data*/
if (driver->ch)
queue_work(driver->diag_wq,
@@ -398,6 +406,9 @@
if (driver->chqdsp)
queue_work(driver->diag_wq,
&(driver->diag_read_smd_qdsp_work));
+ if (driver->ch_wcnss)
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_wcnss_work));
} else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode
== USB_MODE)
diagfwd_connect();
@@ -426,10 +437,10 @@
driver->data_ready[index]);
mutex_lock(&driver->diagchar_mutex);
- if ((driver->data_ready[index] & MEMORY_DEVICE_LOG_TYPE) && (driver->
+ if ((driver->data_ready[index] & USER_SPACE_LOG_TYPE) && (driver->
logging_mode == MEMORY_DEVICE_MODE)) {
/*Copy the type of data being passed*/
- data_type = driver->data_ready[index] & MEMORY_DEVICE_LOG_TYPE;
+ data_type = driver->data_ready[index] & USER_SPACE_LOG_TYPE;
COPY_USER_SPACE_OR_EXIT(buf, data_type, 4);
/* place holder for number of data field */
ret += 4;
@@ -496,8 +507,7 @@
driver->write_ptr_2->length);
driver->in_busy_2 = 0;
}
-
- /* copy q6 data */
+ /* copy lpass data */
if (driver->in_busy_qdsp_1 == 1) {
num_data++;
/*Copy the length of data being passed*/
@@ -520,23 +530,37 @@
write_ptr_qdsp_2->length);
driver->in_busy_qdsp_2 = 0;
}
-
+ /* copy wncss data */
+ if (driver->in_busy_wcnss == 1) {
+ num_data++;
+ /*Copy the length of data being passed*/
+ COPY_USER_SPACE_OR_EXIT(buf+ret,
+ (driver->write_ptr_wcnss->length), 4);
+ /*Copy the actual data being passed*/
+ COPY_USER_SPACE_OR_EXIT(buf+ret, *(driver->
+ buf_in_wcnss),
+ driver->write_ptr_wcnss->length);
+ driver->in_busy_wcnss = 0;
+ }
/* copy number of data fields */
COPY_USER_SPACE_OR_EXIT(buf+4, num_data, 4);
ret -= 4;
- driver->data_ready[index] ^= MEMORY_DEVICE_LOG_TYPE;
+ driver->data_ready[index] ^= USER_SPACE_LOG_TYPE;
if (driver->ch)
queue_work(driver->diag_wq,
&(driver->diag_read_smd_work));
if (driver->chqdsp)
queue_work(driver->diag_wq,
&(driver->diag_read_smd_qdsp_work));
+ if (driver->ch_wcnss)
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_wcnss_work));
APPEND_DEBUG('n');
goto exit;
- } else if (driver->data_ready[index] & MEMORY_DEVICE_LOG_TYPE) {
+ } else if (driver->data_ready[index] & USER_SPACE_LOG_TYPE) {
/* In case, the thread wakes up and the logging mode is
not memory device any more, the condition needs to be cleared */
- driver->data_ready[index] ^= MEMORY_DEVICE_LOG_TYPE;
+ driver->data_ready[index] ^= USER_SPACE_LOG_TYPE;
}
if (driver->data_ready[index] & DEINIT_TYPE) {
@@ -612,21 +636,27 @@
#endif /* DIAG over USB */
/* Get the packet type F3/log/event/Pkt response */
err = copy_from_user((&pkt_type), buf, 4);
- /*First 4 bytes indicate the type of payload - ignore these */
+ /* First 4 bytes indicate the type of payload - ignore these */
payload_size = count - 4;
- if (pkt_type == MEMORY_DEVICE_LOG_TYPE) {
- if (!mask_request_validate((unsigned char *)buf)) {
- printk(KERN_ALERT "mask request Invalid ..cannot send to modem \n");
- return -EFAULT;
+ if (pkt_type == USER_SPACE_LOG_TYPE) {
+ err = copy_from_user(driver->user_space_data, buf + 4,
+ payload_size);
+ /* Check masks for On-Device logging */
+ if (pkt_type == USER_SPACE_LOG_TYPE) {
+ if (!mask_request_validate((unsigned char *)buf)) {
+ pr_alert("diag: mask request Invalid\n");
+ return -EFAULT;
+ }
}
buf = buf + 4;
#ifdef DIAG_DEBUG
- pr_debug("diag: masks: %d\n", payload_size);
+ pr_debug("diag: user space data %d\n", payload_size);
for (i = 0; i < payload_size; i++)
printk(KERN_DEBUG "\t %x", *(((unsigned char *)buf)+i));
#endif
- diag_process_hdlc((void *)buf, payload_size);
+ diag_process_hdlc((void *)(driver->user_space_data),
+ payload_size);
return 0;
}
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index f9664c4..e49d57c 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -61,7 +61,8 @@
driver->write_ptr_1->length = (int)(enc.dest - \
(void *)(driver->buf_in_1)); \
driver->in_busy_1 = 1; \
- usb_diag_write(driver->legacy_ch, driver->write_ptr_1); \
+ diag_device_write(driver->buf_in_1, MODEM_DATA, \
+ driver->write_ptr_1); \
memset(driver->apps_rsp_buf, '\0', 500); \
} \
} while (0)
@@ -153,7 +154,7 @@
driver->logging_process_id)
break;
if (i < driver->num_clients) {
- driver->data_ready[i] |= MEMORY_DEVICE_LOG_TYPE;
+ driver->data_ready[i] |= USER_SPACE_LOG_TYPE;
wake_up_interruptible(&driver->wait_q);
} else
return -EINVAL;
@@ -982,13 +983,15 @@
{
printk(KERN_DEBUG "diag: USB disconnected\n");
driver->usb_connected = 0;
- driver->in_busy_1 = 1;
- driver->in_busy_2 = 1;
- driver->in_busy_qdsp_1 = 1;
- driver->in_busy_qdsp_2 = 1;
- driver->in_busy_wcnss = 1;
driver->debug_flag = 1;
usb_diag_free_req(driver->legacy_ch);
+ if (driver->logging_mode == USB_MODE) {
+ driver->in_busy_1 = 1;
+ driver->in_busy_2 = 1;
+ driver->in_busy_qdsp_1 = 1;
+ driver->in_busy_qdsp_2 = 1;
+ driver->in_busy_wcnss = 1;
+ }
#ifdef CONFIG_DIAG_SDIO_PIPE
if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
if (driver->mdm_ch && !IS_ERR(driver->mdm_ch))
@@ -1235,6 +1238,10 @@
if (driver->hdlc_buf == NULL
&& (driver->hdlc_buf = kzalloc(HDLC_MAX, GFP_KERNEL)) == NULL)
goto err;
+ if (driver->user_space_data == NULL)
+ driver->user_space_data = kzalloc(USER_SPACE_DATA, GFP_KERNEL);
+ if (driver->user_space_data == NULL)
+ goto err;
if (driver->msg_masks == NULL
&& (driver->msg_masks = kzalloc(MSG_MASK_SIZE,
GFP_KERNEL)) == NULL)
@@ -1350,6 +1357,7 @@
kfree(driver->write_ptr_wcnss);
kfree(driver->usb_read_ptr);
kfree(driver->apps_rsp_buf);
+ kfree(driver->user_space_data);
if (driver->diag_wq)
destroy_workqueue(driver->diag_wq);
}
@@ -1391,5 +1399,6 @@
kfree(driver->write_ptr_wcnss);
kfree(driver->usb_read_ptr);
kfree(driver->apps_rsp_buf);
+ kfree(driver->user_space_data);
destroy_workqueue(driver->diag_wq);
}
diff --git a/drivers/char/diag/diagfwd_sdio.c b/drivers/char/diag/diagfwd_sdio.c
index 8be9f46..f3873aa 100644
--- a/drivers/char/diag/diagfwd_sdio.c
+++ b/drivers/char/diag/diagfwd_sdio.c
@@ -124,10 +124,11 @@
int diagfwd_disconnect_sdio(void)
{
- driver->in_busy_sdio = 1;
usb_diag_free_req(driver->mdm_ch);
- if (driver->sdio_ch && (driver->logging_mode == USB_MODE))
+ if (driver->sdio_ch && (driver->logging_mode == USB_MODE)) {
+ driver->in_busy_sdio = 1;
diag_sdio_close();
+ }
return 0;
}
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index de75935..a9dfc60 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -587,6 +587,80 @@
return handle;
}
+static int check_vaddr_bounds(unsigned long start, unsigned long end)
+{
+ struct mm_struct *mm = current->active_mm;
+ struct vm_area_struct *vma;
+ int ret = 1;
+
+ if (end < start)
+ goto out;
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, start);
+ if (vma && vma->vm_start < end) {
+ if (start < vma->vm_start)
+ goto out_up;
+ if (end > vma->vm_end)
+ goto out_up;
+ ret = 0;
+ }
+
+out_up:
+ up_read(&mm->mmap_sem);
+out:
+ return ret;
+}
+
+int ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
+ void *uaddr, unsigned long offset, unsigned long len,
+ unsigned int cmd)
+{
+ struct ion_buffer *buffer;
+ unsigned long start, end;
+ int ret = -EINVAL;
+
+ mutex_lock(&client->lock);
+ if (!ion_handle_validate(client, handle)) {
+ pr_err("%s: invalid handle passed to do_cache_op.\n",
+ __func__);
+ mutex_unlock(&client->lock);
+ return -EINVAL;
+ }
+ buffer = handle->buffer;
+ mutex_lock(&buffer->lock);
+
+ if (ION_IS_CACHED(buffer->flags)) {
+ ret = 0;
+ goto out;
+ }
+
+ if (!handle->buffer->heap->ops->cache_op) {
+ pr_err("%s: cache_op is not implemented by this heap.\n",
+ __func__);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ start = (unsigned long) uaddr;
+ end = (unsigned long) uaddr + len;
+
+ if (check_vaddr_bounds(start, end)) {
+ pr_err("%s: virtual address %p is out of bounds\n",
+ __func__, uaddr);
+ goto out;
+ }
+
+ ret = buffer->heap->ops->cache_op(buffer->heap, buffer, uaddr,
+ offset, len, cmd);
+
+out:
+ mutex_unlock(&buffer->lock);
+ mutex_unlock(&client->lock);
+ return ret;
+
+}
+
static const struct file_operations ion_share_fops;
struct ion_handle *ion_import_fd(struct ion_client *client, int fd)
@@ -1075,6 +1149,20 @@
return -EFAULT;
return dev->custom_ioctl(client, data.cmd, data.arg);
}
+ case ION_IOC_CLEAN_CACHES:
+ case ION_IOC_INV_CACHES:
+ case ION_IOC_CLEAN_INV_CACHES:
+ {
+ struct ion_flush_data data;
+
+ if (copy_from_user(&data, (void __user *)arg,
+ sizeof(struct ion_flush_data)))
+ return -EFAULT;
+
+ return ion_do_cache_op(client, data.handle, data.vaddr,
+ data.offset, data.length, cmd);
+
+ }
default:
return -ENOTTY;
}
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index ed9b9b5..44536c8 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -100,7 +100,7 @@
struct ion_buffer *buffer,
unsigned long flags)
{
- if (flags & ION_SET_CACHE(CACHED))
+ if (ION_IS_CACHED(flags))
return ioremap_cached(buffer->priv_phys, buffer->size);
else
return ioremap(buffer->priv_phys, buffer->size);
@@ -117,7 +117,7 @@
int ion_carveout_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
struct vm_area_struct *vma, unsigned long flags)
{
- if (flags & ION_SET_CACHE(CACHED))
+ if (ION_IS_CACHED(flags))
return remap_pfn_range(vma, vma->vm_start,
__phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff,
buffer->size,
@@ -129,6 +129,32 @@
pgprot_noncached(vma->vm_page_prot));
}
+int ion_carveout_cache_ops(struct ion_heap *heap, struct ion_buffer *buffer,
+ void *vaddr, unsigned int offset, unsigned int length,
+ unsigned int cmd)
+{
+ unsigned long vstart, pstart;
+
+ pstart = buffer->priv_phys + offset;
+ vstart = (unsigned long)vaddr;
+
+ switch (cmd) {
+ case ION_IOC_CLEAN_CACHES:
+ clean_caches(vstart, length, pstart);
+ break;
+ case ION_IOC_INV_CACHES:
+ invalidate_caches(vstart, length, pstart);
+ break;
+ case ION_IOC_CLEAN_INV_CACHES:
+ clean_and_invalidate_caches(vstart, length, pstart);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static struct ion_heap_ops carveout_heap_ops = {
.allocate = ion_carveout_heap_allocate,
.free = ion_carveout_heap_free,
@@ -136,6 +162,7 @@
.map_user = ion_carveout_heap_map_user,
.map_kernel = ion_carveout_heap_map_kernel,
.unmap_kernel = ion_carveout_heap_unmap_kernel,
+ .cache_op = ion_carveout_cache_ops,
};
struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data)
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 581abe5..fd5c125 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -101,6 +101,9 @@
void (*unmap_kernel) (struct ion_heap *heap, struct ion_buffer *buffer);
int (*map_user) (struct ion_heap *mapper, struct ion_buffer *buffer,
struct vm_area_struct *vma, unsigned long flags);
+ int (*cache_op)(struct ion_heap *heap, struct ion_buffer *buffer,
+ void *vaddr, unsigned int offset,
+ unsigned int length, unsigned int cmd);
};
/**
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index b34b455..5609b72 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "ion_priv.h"
+#include <mach/memory.h>
static int ion_system_heap_allocate(struct ion_heap *heap,
struct ion_buffer *buffer,
@@ -78,7 +79,7 @@
struct ion_buffer *buffer,
unsigned long flags)
{
- if (flags & ION_SET_CACHE(CACHED))
+ if (ION_IS_CACHED(flags))
return buffer->priv_virt;
else {
pr_err("%s: cannot map system heap uncached\n", __func__);
@@ -94,7 +95,7 @@
int ion_system_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
struct vm_area_struct *vma, unsigned long flags)
{
- if (flags & ION_SET_CACHE(CACHED))
+ if (ION_IS_CACHED(flags))
return remap_vmalloc_range(vma, buffer->priv_virt,
vma->vm_pgoff);
else {
@@ -103,6 +104,51 @@
}
}
+int ion_system_heap_cache_ops(struct ion_heap *heap, struct ion_buffer *buffer,
+ void *vaddr, unsigned int offset, unsigned int length,
+ unsigned int cmd)
+{
+ unsigned long vstart, pstart;
+ void *vtemp;
+ unsigned long ln = 0;
+ void (*op)(unsigned long, unsigned long, unsigned long);
+
+ switch (cmd) {
+ case ION_IOC_CLEAN_CACHES:
+ op = clean_caches;
+ break;
+ case ION_IOC_INV_CACHES:
+ op = invalidate_caches;
+ break;
+ case ION_IOC_CLEAN_INV_CACHES:
+ op = clean_and_invalidate_caches;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ for (vtemp = buffer->priv_virt + offset,
+ vstart = (unsigned long) vaddr;
+ ln < length;
+ vtemp += PAGE_SIZE, ln += PAGE_SIZE,
+ vstart += PAGE_SIZE) {
+ pstart = page_to_phys(vmalloc_to_page(vtemp));
+ /*
+ * If vmalloc -> page -> phys is returning NULL, something
+ * has really gone wrong...
+ */
+ if (!pstart) {
+ WARN(1, "Could not translate %p to physical address\n",
+ vtemp);
+ return -EINVAL;
+ }
+
+ op(vstart, PAGE_SIZE, pstart);
+ }
+
+ return 0;
+}
+
static struct ion_heap_ops vmalloc_ops = {
.allocate = ion_system_heap_allocate,
.free = ion_system_heap_free,
@@ -111,6 +157,7 @@
.map_kernel = ion_system_heap_map_kernel,
.unmap_kernel = ion_system_heap_unmap_kernel,
.map_user = ion_system_heap_map_user,
+ .cache_op = ion_system_heap_cache_ops,
};
struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
@@ -176,7 +223,7 @@
{
unsigned long pfn = __phys_to_pfn(virt_to_phys(buffer->priv_virt));
- if (flags & ION_SET_CACHE(CACHED))
+ if (ION_IS_CACHED(flags))
return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
@@ -186,6 +233,39 @@
}
}
+int ion_system_contig_heap_cache_ops(struct ion_heap *heap,
+ struct ion_buffer *buffer, void *vaddr,
+ unsigned int offset, unsigned int length,
+ unsigned int cmd)
+{
+ unsigned long vstart, pstart;
+
+ pstart = virt_to_phys(buffer->priv_virt) + offset;
+ if (!pstart) {
+ WARN(1, "Could not do virt to phys translation on %p\n",
+ buffer->priv_virt);
+ return -EINVAL;
+ }
+
+ vstart = (unsigned long) vaddr;
+
+ switch (cmd) {
+ case ION_IOC_CLEAN_CACHES:
+ clean_caches(vstart, length, pstart);
+ break;
+ case ION_IOC_INV_CACHES:
+ invalidate_caches(vstart, length, pstart);
+ break;
+ case ION_IOC_CLEAN_INV_CACHES:
+ clean_and_invalidate_caches(vstart, length, pstart);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static struct ion_heap_ops kmalloc_ops = {
.allocate = ion_system_contig_heap_allocate,
.free = ion_system_contig_heap_free,
@@ -195,6 +275,7 @@
.map_kernel = ion_system_heap_map_kernel,
.unmap_kernel = ion_system_heap_unmap_kernel,
.map_user = ion_system_contig_heap_map_user,
+ .cache_op = ion_system_contig_heap_cache_ops,
};
struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 526c971..4207def 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -66,9 +66,6 @@
| (MMU_CONFIG << MH_MMU_CONFIG__TC_R_CLNT_BEHAVIOR__SHIFT) \
| (MMU_CONFIG << MH_MMU_CONFIG__PA_W_CLNT_BEHAVIOR__SHIFT))
-/* max msecs to wait for gpu to finish its operation(s) */
-#define MAX_WAITGPU_SECS (HZ + HZ/2)
-
static const struct kgsl_functable adreno_functable;
static struct adreno_device device_3d0 = {
@@ -429,6 +426,8 @@
adreno_dev = ADRENO_DEVICE(device);
device->parentdev = &pdev->dev;
+ adreno_dev->wait_timeout = 10000; /* default value in milliseconds */
+
init_completion(&device->recovery_gate);
status = adreno_ringbuffer_init(device);
@@ -835,7 +834,9 @@
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
unsigned int rbbm_status;
- unsigned long wait_time = jiffies + MAX_WAITGPU_SECS;
+ unsigned long wait_timeout =
+ msecs_to_jiffies(adreno_dev->wait_timeout);
+ unsigned long wait_time = jiffies + wait_timeout;
kgsl_cffdump_regpoll(device->id, REG_RBBM_STATUS << 2,
0x00000000, 0x80000000);
@@ -855,7 +856,7 @@
}
/* now, wait for the GPU to finish its operations */
- wait_time = jiffies + MAX_WAITGPU_SECS;
+ wait_time = jiffies + wait_timeout;
while (time_before(jiffies, wait_time)) {
adreno_regread(device, REG_RBBM_STATUS, &rbbm_status);
if (rbbm_status == 0x110)
@@ -865,7 +866,7 @@
err:
KGSL_DRV_ERR(device, "spun too long waiting for RB to idle\n");
if (!adreno_dump_and_recover(device)) {
- wait_time = jiffies + MAX_WAITGPU_SECS;
+ wait_time = jiffies + wait_timeout;
goto retry;
}
return -ETIMEDOUT;
@@ -1073,6 +1074,10 @@
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+ /* Don't wait forever, set a max value for now */
+ if (msecs == -1)
+ msecs = adreno_dev->wait_timeout;
+
if (timestamp != adreno_dev->ringbuffer.timestamp &&
timestamp_cmp(timestamp,
adreno_dev->ringbuffer.timestamp)) {
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 94b96a1..0098045 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -64,6 +64,7 @@
struct adreno_ringbuffer ringbuffer;
unsigned int mharb;
struct adreno_gpudev *gpudev;
+ unsigned int wait_timeout;
};
struct adreno_gpudev {
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 8a7ab35..064b05e 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1520,6 +1520,7 @@
if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
KGSL_CMD_WARN(rb->device, "ringbuffer ib1/rb interrupt\n");
+ queue_work(device->work_queue, &device->ts_expired_ws);
wake_up_interruptible_all(&device->wait_queue);
atomic_notifier_call_chain(&(device->ts_notifier_list),
device->id,
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index b917849..c878a2c 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -421,6 +421,8 @@
void adreno_debugfs_init(struct kgsl_device *device)
{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
if (!device->d_debugfs || IS_ERR(device->d_debugfs))
return;
@@ -436,6 +438,8 @@
&kgsl_mh_debug_fops);
debugfs_create_file("cff_dump", 0644, device->d_debugfs, device,
&kgsl_cff_dump_enable_fops);
+ debugfs_create_u32("wait_timeout", 0644, device->d_debugfs,
+ &adreno_dev->wait_timeout);
/* Create post mortem control files */
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 5d20d9b..165bbbf 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -180,35 +180,28 @@
list_add_tail(&entry->list, &device->memqueue);
}
-static void kgsl_memqueue_drain(struct kgsl_device *device)
+static void kgsl_timestamp_expired(struct work_struct *work)
{
+ struct kgsl_device *device = container_of(work, struct kgsl_device,
+ ts_expired_ws);
struct kgsl_mem_entry *entry, *entry_tmp;
uint32_t ts_processed;
- BUG_ON(!mutex_is_locked(&device->mutex));
+ mutex_lock(&device->mutex);
/* get current EOP timestamp */
ts_processed = device->ftbl->readtimestamp(device,
KGSL_TIMESTAMP_RETIRED);
+ /* Flush the freememontimestamp queue */
list_for_each_entry_safe(entry, entry_tmp, &device->memqueue, list) {
- KGSL_MEM_INFO(device,
- "ts_processed %d ts_free %d gpuaddr %x)\n",
- ts_processed, entry->free_timestamp,
- entry->memdesc.gpuaddr);
if (!timestamp_cmp(ts_processed, entry->free_timestamp))
break;
list_del(&entry->list);
kgsl_mem_entry_put(entry);
}
-}
-static void kgsl_memqueue_drain_unlocked(struct kgsl_device *device)
-{
- mutex_lock(&device->mutex);
- kgsl_check_suspended(device);
- kgsl_memqueue_drain(device);
mutex_unlock(&device->mutex);
}
@@ -767,16 +760,10 @@
dev_priv->device->active_cnt++;
- /* Don't wait forever, set a max value for now */
- if (param->timeout == -1)
- param->timeout = 10 * MSEC_PER_SEC;
-
result = dev_priv->device->ftbl->waittimestamp(dev_priv->device,
param->timestamp,
param->timeout);
- kgsl_memqueue_drain(dev_priv->device);
-
/* Fire off any pending suspend operations that are in flight */
INIT_COMPLETION(dev_priv->device->suspend_gate);
@@ -954,7 +941,6 @@
if (entry) {
kgsl_memqueue_freememontimestamp(dev_priv->device, entry,
param->timestamp, param->type);
- kgsl_memqueue_drain(dev_priv->device);
} else {
KGSL_DRV_ERR(dev_priv->device,
"invalid gpuaddr %08x\n", param->gpuaddr);
@@ -1066,9 +1052,6 @@
if (!kgsl_mmu_enabled())
return -ENODEV;
- /* Make sure all pending freed memory is collected */
- kgsl_memqueue_drain_unlocked(dev_priv->device);
-
if (!param->hostptr) {
KGSL_CORE_ERR("invalid hostptr %x\n", param->hostptr);
result = -EINVAL;
@@ -1387,8 +1370,6 @@
if (entry == NULL)
return -ENOMEM;
- kgsl_memqueue_drain_unlocked(dev_priv->device);
-
if (_IOC_SIZE(cmd) == sizeof(struct kgsl_sharedmem_from_pmem))
memtype = KGSL_USER_MEM_TYPE_PMEM;
else
@@ -1528,9 +1509,6 @@
if (entry == NULL)
return -ENOMEM;
- /* Make sure all pending freed memory is collected */
- kgsl_memqueue_drain_unlocked(dev_priv->device);
-
result = kgsl_allocate_user(&entry->memdesc, private->pagetable,
param->size, param->flags);
@@ -1918,6 +1896,7 @@
goto err_devlist;
INIT_WORK(&device->idle_check_ws, kgsl_idle_check);
+ INIT_WORK(&device->ts_expired_ws, kgsl_timestamp_expired);
INIT_LIST_HEAD(&device->memqueue);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 10e345a..2f369ed 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -165,6 +165,7 @@
struct kgsl_pwrscale pwrscale;
struct kobject pwrscale_kobj;
struct pm_qos_request_list pm_qos_req_dma;
+ struct work_struct ts_expired_ws;
};
struct kgsl_context {
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 37ba621..61a3edb 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -234,6 +234,7 @@
count &= 255;
z180_dev->timestamp += count;
+ queue_work(device->work_queue, &device->ts_expired_ws);
wake_up_interruptible(&device->wait_queue);
atomic_notifier_call_chain(
@@ -806,6 +807,11 @@
unsigned int msecs)
{
int status = -EINVAL;
+
+ /* Don't wait forever, set a max (10 sec) value for now */
+ if (msecs == -1)
+ msecs = 10 * MSEC_PER_SEC;
+
mutex_unlock(&device->mutex);
status = z180_wait(device, timestamp, msecs);
mutex_lock(&device->mutex);
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 8f2a942..00c7633 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -335,8 +335,15 @@
else /* 1-bit delay before we check for bus busy */
udelay(dev->one_bit_t);
}
- if (retries++ == 1000)
- udelay(100);
+ if (retries++ == 1000) {
+ /*
+ * Wait for FIFO number of bytes to be absolutely sure
+ * that I2C write state machine is not idle. Each byte
+ * takes 9 clock cycles. (8 bits + 1 ack)
+ */
+ usleep_range((dev->one_bit_t * (dev->out_fifo_sz * 9)),
+ (dev->one_bit_t * (dev->out_fifo_sz * 9)));
+ }
}
qup_print_status(dev);
return -ETIMEDOUT;
@@ -520,7 +527,7 @@
*/
if (rem > 1) {
struct i2c_msg *next = msg + 1;
- if (next->addr == msg->addr && (next->flags | I2C_M_RD)
+ if (next->addr == msg->addr && (next->flags & I2C_M_RD)
&& *idx == ((dev->wr_sz*2) - 4)) {
writel_relaxed(((last_entry |
msg->buf[dev->pos]) |
@@ -1076,7 +1083,7 @@
platform_set_drvdata(pdev, dev);
- dev->one_bit_t = USEC_PER_SEC/pdata->clk_freq;
+ dev->one_bit_t = (USEC_PER_SEC/pdata->clk_freq) + 1;
dev->pdata = pdata;
dev->clk_ctl = 0;
dev->pos = 0;
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index d73f49c..07b6c81 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -61,7 +61,6 @@
{
/* Interrupts are disabled, just acquire the lock. */
spin_lock(&client->buffer_lock);
- wake_lock_timeout(&client->wake_lock, 5 * HZ);
wake_lock_timeout(&client->wake_lock, 5 * HZ);
client->buffer[client->head++] = *event;
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index b35597e..fc9d579 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -229,6 +229,7 @@
#define MXT_MAX_FINGER 10
#define MXT_BUFF_SIZE 100
+#define T7_DATA_SIZE 3
struct mxt_info {
u8 family_id;
@@ -280,6 +281,8 @@
#if defined(CONFIG_HAS_EARLYSUSPEND)
struct early_suspend early_suspend;
#endif
+ u8 t7_data[T7_DATA_SIZE];
+ u8 t9_ctrl;
};
static bool mxt_object_readable(unsigned int type)
@@ -839,7 +842,7 @@
{
struct i2c_client *client = data->client;
struct mxt_info *info = &data->info;
- int error;
+ int error, i;
int timeout_counter = 0;
u8 val;
u8 command_register;
@@ -866,6 +869,23 @@
if (error)
return error;
+ /* Store T7 and T9 locally, used in suspend/resume operations */
+ for (i = 0; i < T7_DATA_SIZE; i++) {
+ error = mxt_read_object(data, MXT_GEN_POWER, i,
+ &data->t7_data[i]);
+ if (error < 0) {
+ dev_err(&client->dev,
+ "failed to save current power state\n");
+ return error;
+ }
+ }
+ error = mxt_read_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_CTRL,
+ &data->t9_ctrl);
+ if (error < 0) {
+ dev_err(&client->dev, "failed to save current touch object\n");
+ return error;
+ }
+
mxt_handle_pdata(data);
/* Backup to memory */
@@ -1088,25 +1108,63 @@
.attrs = mxt_attrs,
};
-static void mxt_start(struct mxt_data *data)
+static int mxt_start(struct mxt_data *data)
{
- /* Touch enable */
- mxt_write_object(data,
- MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0x83);
+ int i, error;
+ /* restore the old power state values and reenable touch */
+ for (i = 0; i < T7_DATA_SIZE; i++) {
+ error = mxt_write_object(data, MXT_GEN_POWER, i,
+ data->t7_data[i]);
+ if (error < 0) {
+ dev_err(&data->client->dev,
+ "failed to restore old power state\n");
+ return error;
+ }
+ }
+ error = mxt_write_object(data,
+ MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, data->t9_ctrl);
+ if (error < 0) {
+ dev_err(&data->client->dev, "failed to restore touch\n");
+ return error;
+ }
+
+ return 0;
}
-static void mxt_stop(struct mxt_data *data)
+static int mxt_stop(struct mxt_data *data)
{
- /* Touch disable */
- mxt_write_object(data,
+ int i, error;
+ /* configure deep sleep mode and disable touch */
+ for (i = 0; i < T7_DATA_SIZE; i++) {
+ error = mxt_write_object(data, MXT_GEN_POWER, i, 0);
+ if (error < 0) {
+ dev_err(&data->client->dev,
+ "failed to configure deep sleep mode\n");
+ return error;
+ }
+ }
+
+ error = mxt_write_object(data,
MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0);
+ if (error < 0) {
+ dev_err(&data->client->dev,
+ "failed to disable touch\n");
+ return error;
+ }
+
+ return 0;
}
static int mxt_input_open(struct input_dev *dev)
{
struct mxt_data *data = input_get_drvdata(dev);
+ int error;
- mxt_start(data);
+ error = mxt_start(data);
+ if (error < 0) {
+ dev_err(&data->client->dev, "mxt_start failed in input_open\n");
+ return error;
+ }
return 0;
}
@@ -1114,8 +1172,12 @@
static void mxt_input_close(struct input_dev *dev)
{
struct mxt_data *data = input_get_drvdata(dev);
+ int error;
- mxt_stop(data);
+ error = mxt_stop(data);
+ if (error < 0)
+ dev_err(&data->client->dev, "mxt_stop failed in input_close\n");
+
}
static int mxt_power_on(struct mxt_data *data, bool on)
@@ -1253,11 +1315,19 @@
struct i2c_client *client = to_i2c_client(dev);
struct mxt_data *data = i2c_get_clientdata(client);
struct input_dev *input_dev = data->input_dev;
+ int error;
mutex_lock(&input_dev->mutex);
- if (input_dev->users)
- mxt_stop(data);
+ if (input_dev->users) {
+ error = mxt_stop(data);
+ if (error < 0) {
+ dev_err(&client->dev, "mxt_stop failed in suspend\n");
+ mutex_unlock(&input_dev->mutex);
+ return error;
+ }
+
+ }
mutex_unlock(&input_dev->mutex);
@@ -1269,7 +1339,7 @@
struct i2c_client *client = to_i2c_client(dev);
struct mxt_data *data = i2c_get_clientdata(client);
struct input_dev *input_dev = data->input_dev;
-
+ int error;
/* Soft reset */
mxt_write_object(data, MXT_GEN_COMMAND,
MXT_COMMAND_RESET, 1);
@@ -1278,8 +1348,14 @@
mutex_lock(&input_dev->mutex);
- if (input_dev->users)
- mxt_start(data);
+ if (input_dev->users) {
+ error = mxt_start(data);
+ if (error < 0) {
+ dev_err(&client->dev, "mxt_start failed in resume\n");
+ mutex_unlock(&input_dev->mutex);
+ return error;
+ }
+ }
mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/cyttsp-i2c.c b/drivers/input/touchscreen/cyttsp-i2c.c
index db5c658..a3446a3 100644
--- a/drivers/input/touchscreen/cyttsp-i2c.c
+++ b/drivers/input/touchscreen/cyttsp-i2c.c
@@ -288,6 +288,9 @@
#define REC_DATA_OFFSET 9
#define REC_LINE_SIZE 141
+#define NUM_CHAR_IN_HEX 2
+#define ID_INFO_REC_LEN 9
+
static int cyttsp_soft_reset(struct cyttsp *ts)
{
int retval = 0, tries = 0;
@@ -372,7 +375,10 @@
unsigned long ulval;
int rc;
- if (!str && strlen(str) < 2)
+ if (!str)
+ return -EINVAL;
+
+ if (strnlen(str, NUM_CHAR_IN_HEX) < 2)
return -EINVAL;
substr[0] = str[0];
@@ -776,7 +782,8 @@
if ((data[i] == REC_START_CHR) && j) {
buf[j] = 0;
j = 0;
- if (!strncmp(buf, ID_INFO_REC, strlen(ID_INFO_REC))) {
+ if (!strncmp(buf, ID_INFO_REC,
+ strnlen(ID_INFO_REC, ID_INFO_REC_LEN))) {
cyttspfw_flash_start(ts, data, data_len,
buf, force);
break;
@@ -788,7 +795,8 @@
/* check in the last record of firmware */
if (j) {
buf[j] = 0;
- if (!strncmp(buf, ID_INFO_REC, strlen(ID_INFO_REC))) {
+ if (!strncmp(buf, ID_INFO_REC,
+ strnlen(ID_INFO_REC, ID_INFO_REC_LEN))) {
cyttspfw_flash_start(ts, data, data_len,
buf, force);
}
@@ -2808,9 +2816,8 @@
/*
i2c_del_driver(&cyttsp_driver);
*/
- retval = -ENODEV;
- } else
- cyttsp_openlog();
+ return -ENODEV;
+ }
}
#ifdef CONFIG_HAS_EARLYSUSPEND
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index 47ac04d..94af3ce 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.c
@@ -54,13 +54,6 @@
#define PM8XXX_LED_OFFSET(id) ((id) - PM8XXX_ID_LED_0)
-#define PM8XXX_GET_LED_ID(flag) (flag & PM8XXX_LED_ID_MASK >> \
- PM8XXX_LED_ID_SHIFT)
-#define PM8XXX_GET_LED_MODE(flag) ((flag & PM8XXX_LED_MODE_MASK) >> \
- PM8XXX_LED_MODE_SHIFT)
-#define PM8XXX_GET_LED_MAX_CURRENT(flag) ((flag & PM8XXX_LED_MAX_CURRENT_MASK)\
- >> PM8XXX_LED_MAX_CURRENT_SHIFT)
-
/**
* struct pm8xxx_led_data - internal led data structure
* @led_classdev - led class device
@@ -279,30 +272,38 @@
static int __devinit pm8xxx_led_probe(struct platform_device *pdev)
{
- const struct led_platform_data *pdata = pdev->dev.platform_data;
+ const struct pm8xxx_led_platform_data *pdata = pdev->dev.platform_data;
+ const struct led_platform_data *pcore_data;
struct led_info *curr_led;
struct pm8xxx_led_data *led, *led_dat;
- int rc, i, led_mode;
+ struct pm8xxx_led_config *led_cfg;
+ int rc, i;
if (pdata == NULL) {
dev_err(&pdev->dev, "platform data not supplied\n");
return -EINVAL;
}
- /* Let the last member of the list be zero to
- * mark the end of the list.
- */
- led = kcalloc(pdata->num_leds + 1, sizeof(*led), GFP_KERNEL);
+ pcore_data = pdata->led_core;
+
+ if (pcore_data->num_leds != pdata->num_configs) {
+ dev_err(&pdev->dev, "#no. of led configs and #no. of led"
+ "entries are not equal\n");
+ return -EINVAL;
+ }
+
+ led = kcalloc(pcore_data->num_leds, sizeof(*led), GFP_KERNEL);
if (led == NULL) {
dev_err(&pdev->dev, "failed to alloc memory\n");
return -ENOMEM;
}
- for (i = 0; i < pdata->num_leds; i++) {
- curr_led = &pdata->leds[i];
+ for (i = 0; i < pcore_data->num_leds; i++) {
+ curr_led = &pcore_data->leds[i];
led_dat = &led[i];
- /* the flags variable is used for led-id */
- led_dat->id = PM8XXX_GET_LED_ID(curr_led->flags);
+ led_cfg = &pdata->configs[i];
+
+ led_dat->id = led_cfg->id;
if (!((led_dat->id >= PM8XXX_ID_LED_KB_LIGHT) &&
(led_dat->id <= PM8XXX_ID_FLASH_LED_1))) {
@@ -317,17 +318,15 @@
led_dat->cdev.brightness_set = pm8xxx_led_set;
led_dat->cdev.brightness_get = pm8xxx_led_get;
led_dat->cdev.brightness = LED_OFF;
- led_dat->cdev.flags = LED_CORE_SUSPENDRESUME;
+ led_dat->cdev.flags = curr_led->flags;
led_dat->dev = &pdev->dev;
rc = get_init_value(led_dat, &led_dat->reg);
if (rc < 0)
goto fail_id_check;
- led_mode = PM8XXX_GET_LED_MODE(curr_led->flags);
-
- rc = pm8xxx_set_led_mode_and_max_brightness(led_dat, led_mode,
- PM8XXX_GET_LED_MAX_CURRENT(curr_led->flags));
+ rc = pm8xxx_set_led_mode_and_max_brightness(led_dat,
+ led_cfg->mode, led_cfg->max_current);
if (rc < 0)
goto fail_id_check;
@@ -341,7 +340,7 @@
goto fail_id_check;
}
- if (led_mode != PM8XXX_LED_MODE_MANUAL)
+ if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL)
__pm8xxx_led_work(led_dat,
led_dat->cdev.max_brightness);
else
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 2f83234..727b751 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -136,17 +136,20 @@
struct msm_device_queue *queue = &server_dev->ctrl_q;
struct v4l2_event v4l2_evt;
- struct msm_isp_stats_event_ctrl *isp_event;
+ struct msm_isp_event_ctrl *isp_event;
+ isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
+ if (!isp_event) {
+ pr_err("%s Insufficient memory. return", __func__);
+ return -ENOMEM;
+ }
D("%s\n", __func__);
v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_V4L2;
-
/* setup event object to transfer the command; */
- isp_event = (struct msm_isp_stats_event_ctrl *)v4l2_evt.u.data;
+ *((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
isp_event->resptype = MSM_CAM_RESP_V4L2;
isp_event->isp_data.ctrl = *out;
-
- /* now send command to config thread in usersspace,
+ /* now send command to config thread in userspace,
* and wait for results */
v4l2_event_queue(server_dev->server_command_queue.pvdev,
&v4l2_evt);
@@ -181,6 +184,7 @@
out->value = value;
free_qcmd(rcmd);
+ kfree(isp_event);
D("%s: rc %d\n", __func__, rc);
/* rc is the time elapsed. */
if (rc >= 0) {
@@ -1586,7 +1590,7 @@
if (pcam->use_count == 0) {
v4l2_device_unregister_subdev(&pcam->mctl.isp_sdev->sd);
-
+ v4l2_device_unregister_subdev(&pcam->mctl.isp_sdev->sd_vpe);
rc = msm_cam_server_close_session(&g_server_dev, pcam);
if (rc < 0)
pr_err("msm_cam_server_close_session fails %d\n", rc);
@@ -1739,45 +1743,80 @@
break;
case VIDIOC_DQEVENT: {
- void __user *u_ctrl_value = NULL;
- struct msm_isp_stats_event_ctrl *u_isp_event;
- struct msm_isp_stats_event_ctrl *k_isp_event;
+ void __user *u_ctrl_value = NULL, *user_ptr = NULL;
+ struct msm_isp_event_ctrl u_isp_event;
+ struct msm_isp_event_ctrl *k_isp_event;
- /* Make a copy of control value and event data pointer */
+ /* First, copy the event structure from userspace */
D("%s: VIDIOC_DQEVENT\n", __func__);
if (copy_from_user(&ev, (void __user *)arg,
- sizeof(struct v4l2_event)))
+ sizeof(struct v4l2_event))) {
break;
- u_isp_event = (struct msm_isp_stats_event_ctrl *)ev.u.data;
- u_ctrl_value = u_isp_event->isp_data.ctrl.value;
+ }
+ /* Next, get the pointer to event_ctrl structure
+ * embedded inside the v4l2_event.u.data array. */
+ user_ptr = (void __user *)(*((uint32_t *)ev.u.data));
+ /* Next, copy the userspace event ctrl structure */
+ if (copy_from_user((void *)&u_isp_event, user_ptr,
+ sizeof(struct msm_isp_event_ctrl))) {
+ break;
+ }
+
+ /* Save the pointer of the user allocated command buffer*/
+ u_ctrl_value = u_isp_event.isp_data.ctrl.value;
+
+ /* Dequeue the event queued into the v4l2 queue*/
rc = v4l2_event_dequeue(
&g_server_dev.server_command_queue.eventHandle,
- &ev, fp->f_flags & O_NONBLOCK);
+ &ev, fp->f_flags & O_NONBLOCK);
if (rc < 0) {
pr_err("no pending events?");
break;
}
- k_isp_event = (struct msm_isp_stats_event_ctrl *)ev.u.data;
- if (ev.type == V4L2_EVENT_PRIVATE_START+MSM_CAM_RESP_V4L2 &&
- k_isp_event->isp_data.ctrl.length > 0) {
- void *k_ctrl_value = k_isp_event->isp_data.ctrl.value;
- if (copy_to_user(u_ctrl_value, k_ctrl_value,
- u_isp_event->isp_data.ctrl.length)) {
+ /* Use k_isp_event to point to the event_ctrl structure
+ * embedded inside v4l2_event.u.data */
+ k_isp_event = (struct msm_isp_event_ctrl *)
+ (*((uint32_t *)ev.u.data));
+ if (!k_isp_event) {
+ pr_err("%s Invalid event ctrl structure. ", __func__);
+ break;
+ }
+
+ /* Copy the event structure into user struct*/
+ u_isp_event = *k_isp_event;
+
+ /* Restore the saved pointer of the user
+ * allocated command buffer. */
+ u_isp_event.isp_data.ctrl.value = u_ctrl_value;
+ if (ev.type == V4L2_EVENT_PRIVATE_START+MSM_CAM_RESP_V4L2) {
+ /* Copy the ctrl cmd, if present*/
+ if (k_isp_event->isp_data.ctrl.length > 0) {
+ void *k_ctrl_value =
+ k_isp_event->isp_data.ctrl.value;
+ if (copy_to_user(u_ctrl_value, k_ctrl_value,
+ k_isp_event->isp_data.ctrl.length)) {
+ rc = -EINVAL;
+ break;
+ }
+ }
+ /* Copy the event ctrl structure back into
+ * user's structure. */
+ if (copy_to_user(user_ptr, (void *)&u_isp_event,
+ sizeof(struct msm_isp_event_ctrl))) {
rc = -EINVAL;
break;
}
}
- k_isp_event->isp_data.ctrl.value = u_ctrl_value;
+ /* Copy the v4l2_event structure back to the user*/
if (copy_to_user((void __user *)arg, &ev,
sizeof(struct v4l2_event))) {
rc = -EINVAL;
break;
}
}
-
break;
case MSM_CAM_IOCTL_CTRL_CMD_DONE:
@@ -1900,46 +1939,77 @@
break;
case VIDIOC_DQEVENT: {
- void __user *u_msg_value = NULL;
- struct msm_isp_stats_event_ctrl *u_isp_event;
- struct msm_isp_stats_event_ctrl *k_isp_event;
+ void __user *u_msg_value = NULL, *user_ptr = NULL;
+ struct msm_isp_event_ctrl u_isp_event;
+ struct msm_isp_event_ctrl *k_isp_event;
- /* Make a copy of control value and event data pointer */
+ /* First, copy the v4l2 event structure from userspace */
D("%s: VIDIOC_DQEVENT\n", __func__);
if (copy_from_user(&ev, (void __user *)arg,
sizeof(struct v4l2_event)))
break;
- u_isp_event =
- (struct msm_isp_stats_event_ctrl *)ev.u.data;
- u_msg_value = u_isp_event->isp_data.isp_msg.data;
+ /* Next, get the pointer to event_ctrl structure
+ * embedded inside the v4l2_event.u.data array. */
+ user_ptr = (void __user *)(*((uint32_t *)ev.u.data));
+ /* Next, copy the userspace event ctrl structure */
+ if (copy_from_user((void *)&u_isp_event, user_ptr,
+ sizeof(struct msm_isp_event_ctrl))) {
+ break;
+ }
+ /* Save the pointer of the user allocated command buffer*/
+ u_msg_value = u_isp_event.isp_data.isp_msg.data;
+
+ /* Dequeue the event queued into the v4l2 queue*/
rc = v4l2_event_dequeue(
- &config_cam->config_stat_event_queue.eventHandle,
- &ev, fp->f_flags & O_NONBLOCK);
+ &config_cam->config_stat_event_queue.eventHandle,
+ &ev, fp->f_flags & O_NONBLOCK);
if (rc < 0) {
pr_err("no pending events?");
break;
}
+ /* Use k_isp_event to point to the event_ctrl structure
+ * embedded inside v4l2_event.u.data */
+ k_isp_event = (struct msm_isp_event_ctrl *)
+ (*((uint32_t *)ev.u.data));
+ /* Copy the event structure into user struct. */
+ u_isp_event = *k_isp_event;
+
if (ev.type != (V4L2_EVENT_PRIVATE_START +
MSM_CAM_RESP_DIV_FRAME_EVT_MSG) &&
ev.type != (V4L2_EVENT_PRIVATE_START +
MSM_CAM_RESP_MCTL_PP_EVENT)) {
- k_isp_event =
- (struct msm_isp_stats_event_ctrl *)ev.u.data;
+
+ /* Restore the saved pointer of the
+ * user allocated command buffer. */
+ u_isp_event.isp_data.isp_msg.data = u_msg_value;
+
if (ev.type == (V4L2_EVENT_PRIVATE_START +
- MSM_CAM_RESP_STAT_EVT_MSG) &&
- k_isp_event->isp_data.isp_msg.len > 0) {
- void *k_msg_value =
+ MSM_CAM_RESP_STAT_EVT_MSG)) {
+ if (k_isp_event->isp_data.isp_msg.len > 0) {
+ void *k_msg_value =
k_isp_event->isp_data.isp_msg.data;
- if (copy_to_user(u_msg_value, k_msg_value,
- k_isp_event->isp_data.isp_msg.len)) {
- rc = -EINVAL;
- break;
+ if (copy_to_user(u_msg_value,
+ k_msg_value,
+ k_isp_event->isp_data.isp_msg.len)) {
+ rc = -EINVAL;
+ break;
+ }
+ kfree(k_msg_value);
}
- kfree(k_msg_value);
}
- k_isp_event->isp_data.isp_msg.data = u_msg_value;
}
+ /* Copy the event ctrl structure back
+ * into user's structure. */
+ if (copy_to_user(user_ptr,
+ (void *)&u_isp_event, sizeof(
+ struct msm_isp_event_ctrl))) {
+ rc = -EINVAL;
+ break;
+ }
+ kfree(k_isp_event);
+
+ /* Copy the v4l2_event structure back to the user*/
if (copy_to_user((void __user *)arg, &ev,
sizeof(struct v4l2_event))) {
rc = -EINVAL;
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 701f2d9..d914404 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -142,7 +142,7 @@
{
int rc = 0;
struct v4l2_event v4l2_evt;
- struct msm_isp_stats_event_ctrl *isp_event;
+ struct msm_isp_event_ctrl *isp_event;
struct msm_sync *sync =
(struct msm_sync *)v4l2_get_subdev_hostdata(sd);
struct msm_cam_media_controller *pmctl = &sync->pcam_sync->mctl;
@@ -157,9 +157,16 @@
if (notification == NOTIFY_VFE_BUF_EVT)
return msm_isp_notify_VFE_BUF_EVT(sd, arg);
+ isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
+ if (!isp_event) {
+ pr_err("%s Insufficient memory. return", __func__);
+ return -ENOMEM;
+ }
+
v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
MSM_CAM_RESP_STAT_EVT_MSG;
- isp_event = (struct msm_isp_stats_event_ctrl *)v4l2_evt.u.data;
+ *((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
+
isp_event->resptype = MSM_CAM_RESP_STAT_EVT_MSG;
isp_event->isp_data.isp_msg.type = MSM_CAMERA_MSG;
isp_event->isp_data.isp_msg.len = 0;
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index a83fa00..a8554ee 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -516,8 +516,8 @@
idx = msm_mctl_out_type_to_inst_index(pmctl->sync.pcam_sync,
msg_type);
pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
- if (!pcam_inst->streamon) {
- D("%s: stream 0x%p is off\n", __func__, pcam_inst);
+ if (!pcam_inst || !pcam_inst->streamon) {
+ D("%s: stream is turned off\n", __func__);
return rc;
}
spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index f0c1bfa..7040c29 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -41,14 +41,22 @@
struct msm_cam_evt_divert_frame *div)
{
struct v4l2_event v4l2_evt;
-
+ struct msm_isp_event_ctrl *isp_event;
+ isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl),
+ GFP_KERNEL);
+ if (!isp_event) {
+ pr_err("%s Insufficient memory. return", __func__);
+ return -ENOMEM;
+ }
D("%s: msm_cam_evt_divert_frame=%d",
__func__, sizeof(struct msm_cam_evt_divert_frame));
memset(&v4l2_evt, 0, sizeof(v4l2_evt));
v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
MSM_CAM_RESP_DIV_FRAME_EVT_MSG;
- memcpy(&v4l2_evt.u.data[0], div,
- sizeof(struct msm_cam_evt_divert_frame));
+ *((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
+ /* Copy the divert frame struct into event ctrl struct. */
+ isp_event->isp_data.div_frame = *div;
+
D("%s inst=%p, img_mode=%d, frame_id=%d,phy=0x%x,len=%d\n",
__func__, pcam_inst, pcam_inst->image_mode, div->frame_id,
(uint32_t)div->phy_addr, div->length);
@@ -563,7 +571,7 @@
pp_frame_info->dest_frame.handle;
msm_mctl_buf_done_pp(
p_mctl, msg_type, &done_frame, 0);
- pr_err("%s: vpe done to app, vb=0x%x, path=%d, phy=0x%x",
+ pr_info("%s: vpe done to app, vb=0x%x, path=%d, phy=0x%x",
__func__, done_frame.vb,
pp_frame_cmd->path, done_frame.ch_paddr[0]);
}
@@ -571,21 +579,31 @@
pp_frame_cmd->vpe_output_action)) {
struct v4l2_event v4l2_evt;
struct msm_mctl_pp_event_info *pp_event_info;
+ struct msm_isp_event_ctrl *isp_event;
+ isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl),
+ GFP_KERNEL);
+ if (!isp_event) {
+ pr_err("%s Insufficient memory.", __func__);
+ return -ENOMEM;
+ }
memset(&v4l2_evt, 0, sizeof(v4l2_evt));
- pp_event_info =
- (struct msm_mctl_pp_event_info *)v4l2_evt.
- u.data;
+ *((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
+
+ /* Get hold of pp event info struct inside event ctrl.*/
+ pp_event_info = &(isp_event->isp_data.pp_event_info);
+
pp_event_info->event = MCTL_PP_EVENT_CMD_ACK;
pp_event_info->ack.cmd = pp_frame_info->user_cmd;
pp_event_info->ack.status = 0;
pp_event_info->ack.cookie = pp_frame_cmd->cookie;
v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
MSM_CAM_RESP_MCTL_PP_EVENT;
+
v4l2_event_queue(
p_mctl->config_device->
config_stat_event_queue.pvdev,
&v4l2_evt);
- pr_err("%s: ack to daemon, cookie=0x%x, event = 0x%x",
+ D("%s: ack to daemon, cookie=0x%x, event = 0x%x",
__func__, pp_frame_info->pp_frame_cmd.cookie,
v4l2_evt.type);
}
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 1e80ef8..faf8d6d 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -678,7 +678,7 @@
msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
- msm_io_dump(vfe32_ctrl->vfebase, 0x740);
+ msm_io_dump(vfe32_ctrl->vfebase, 0x7B4);
/* Ensure the write order while writing
to the command register using the barrier */
@@ -882,6 +882,23 @@
vfe32_ctrl->update_rolloff = false;
}
+ if (vfe32_ctrl->update_la) {
+ if (!msm_io_r(vfe32_ctrl->vfebase + V32_LA_OFF))
+ msm_io_w(1,
+ vfe32_ctrl->vfebase + V32_LA_OFF);
+ else
+ msm_io_w(0,
+ vfe32_ctrl->vfebase + V32_LA_OFF);
+ vfe32_ctrl->update_la = false;
+ }
+
+ if (vfe32_ctrl->update_gamma) {
+ value = msm_io_r(vfe32_ctrl->vfebase + V32_RGB_G_OFF);
+ value ^= V32_GAMMA_LUT_BANK_SEL_MASK;
+ msm_io_w(value, vfe32_ctrl->vfebase + V32_RGB_G_OFF);
+ vfe32_ctrl->update_gamma = false;
+ }
+
spin_lock_irqsave(&vfe32_ctrl->update_ack_lock, flags);
vfe32_ctrl->update_ack_pending = TRUE;
spin_unlock_irqrestore(&vfe32_ctrl->update_ack_lock, flags);
@@ -997,6 +1014,7 @@
}
vfe32_program_dmi_cfg(NO_MEM_SELECTED);
}
+
static struct vfe32_output_ch *vfe32_get_ch(int path)
{
struct vfe32_output_ch *ch = NULL;
@@ -1350,7 +1368,8 @@
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
/* Incrementing with 4 so as to point to the 2nd Register as
the 2nd register has the mce_enable bit */
- old_val = msm_io_r(vfe32_ctrl->vfebase + V32_CHROMA_EN_OFF + 4);
+ old_val = msm_io_r(vfe32_ctrl->vfebase +
+ V32_CHROMA_SUP_OFF + 4);
if (!cmdp) {
rc = -ENOMEM;
goto proc_general_done;
@@ -1365,15 +1384,16 @@
new_val = *cmdp_local;
old_val &= MCE_EN_MASK;
new_val = new_val | old_val;
- msm_io_memcpy(vfe32_ctrl->vfebase + V32_CHROMA_EN_OFF + 4,
- &new_val, 4);
+ msm_io_memcpy(vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF + 4,
+ &new_val, 4);
cmdp_local += 1;
- old_val = msm_io_r(vfe32_ctrl->vfebase + V32_CHROMA_EN_OFF + 8);
+ old_val = msm_io_r(vfe32_ctrl->vfebase +
+ V32_CHROMA_SUP_OFF + 8);
new_val = *cmdp_local;
old_val &= MCE_Q_K_MASK;
new_val = new_val | old_val;
- msm_io_memcpy(vfe32_ctrl->vfebase + V32_CHROMA_EN_OFF + 8,
+ msm_io_memcpy(vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF + 8,
&new_val, 4);
cmdp_local += 1;
msm_io_memcpy(vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
@@ -1421,6 +1441,26 @@
break;
case VFE_CMD_LA_CFG:
+ cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+ if (!cmdp) {
+ rc = -ENOMEM;
+ goto proc_general_done;
+ }
+ if (copy_from_user(cmdp,
+ (void __user *)(cmd->value),
+ cmd->length)) {
+
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ cmdp_local = cmdp;
+ msm_io_memcpy(vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+ cmdp_local, (vfe32_cmd[cmd->id].length));
+
+ cmdp_local += 1;
+ vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0, cmdp_local);
+ break;
+
case VFE_CMD_LA_UPDATE: {
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
@@ -1434,17 +1474,17 @@
rc = -EFAULT;
goto proc_general_done;
}
- msm_io_memcpy(vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
- cmdp, (vfe32_cmd[cmd->id].length));
- old_val = *cmdp;
- cmdp += 1;
- if (old_val == 0x0)
- vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0 , cmdp);
+ cmdp_local = cmdp + 1;
+ old_val = msm_io_r(vfe32_ctrl->vfebase + V32_LA_OFF);
+ if (old_val != 0x0)
+ vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+ cmdp_local);
else
- vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1 , cmdp);
- cmdp -= 1;
+ vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
+ cmdp_local);
}
+ vfe32_ctrl->update_la = true;
break;
case VFE_CMD_SK_ENHAN_CFG:
@@ -1504,7 +1544,7 @@
}
cmdp_local = cmdp;
cmdp_local++;
- msm_io_memcpy(vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF1,
+ msm_io_memcpy(vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF1 + 4,
cmdp_local, (V32_LINEARIZATION_LEN1 - 4));
cmdp_local += 3;
msm_io_memcpy(vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF2,
@@ -1664,13 +1704,14 @@
goto proc_general_done;
}
msm_io_memcpy(vfe32_ctrl->vfebase + V32_RGB_G_OFF,
- cmdp, 4);
+ cmdp, 4);
cmdp += 1;
- vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0 , cmdp);
- vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0 , cmdp);
- vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0 , cmdp);
- cmdp -= 1;
+
+ vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
+ vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
+ vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
}
+ cmdp -= 1;
break;
case VFE_CMD_RGB_G_UPDATE: {
@@ -1685,21 +1726,20 @@
goto proc_general_done;
}
- msm_io_memcpy(vfe32_ctrl->vfebase + V32_RGB_G_OFF, cmdp, 4);
- old_val = *cmdp;
+ old_val = msm_io_r(vfe32_ctrl->vfebase + V32_RGB_G_OFF);
cmdp += 1;
-
- if (old_val) {
- vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK1 , cmdp);
- vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK1 , cmdp);
- vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK1 , cmdp);
+ if (old_val != 0x0) {
+ vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
+ vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
+ vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
} else {
- vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0 , cmdp);
- vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0 , cmdp);
- vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0 , cmdp);
+ vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK1, cmdp);
+ vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK1, cmdp);
+ vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK1, cmdp);
}
+ }
+ vfe32_ctrl->update_gamma = TRUE;
cmdp -= 1;
- }
break;
case VFE_CMD_STATS_AWB_STOP: {
@@ -1845,16 +1885,16 @@
msm_io_memcpy(vfe32_ctrl->vfebase + V33_PCA_ROLL_OFF_CFG_OFF2,
cmdp_local, V33_PCA_ROLL_OFF_CFG_LEN2);
+ cmdp_local += 3;
CDBG("%s: start writing RollOff Ram0 table\n", __func__);
vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0);
msm_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
- msm_io_w(*cmdp_local,
+ msm_io_w(*(cmdp_local + 1),
vfe32_ctrl->vfebase + VFE33_DMI_DATA_HI);
- cmdp_local++;
msm_io_w(*cmdp_local,
vfe32_ctrl->vfebase + VFE33_DMI_DATA_LO);
- cmdp_local++;
+ cmdp_local += 2;
}
CDBG("%s: end writing RollOff Ram0 table\n", __func__);
@@ -1862,10 +1902,9 @@
vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0);
msm_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
- cmdp_local++;
msm_io_w(*cmdp_local,
vfe32_ctrl->vfebase + VFE33_DMI_DATA_LO);
- cmdp_local++;
+ cmdp_local += 2;
}
CDBG("%s: end writing RollOff Ram1 table\n", __func__);
@@ -1901,12 +1940,11 @@
msm_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
- msm_io_w(*cmdp_local,
+ msm_io_w(*(cmdp_local + 1),
vfe32_ctrl->vfebase + VFE33_DMI_DATA_HI);
- cmdp_local++;
msm_io_w(*cmdp_local,
vfe32_ctrl->vfebase + VFE33_DMI_DATA_LO);
- cmdp_local++;
+ cmdp_local += 2;
}
CDBG("%s: end writing RollOff Ram0 table\n", __func__);
@@ -1918,10 +1956,9 @@
msm_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
- cmdp_local++;
msm_io_w(*cmdp_local,
vfe32_ctrl->vfebase + VFE33_DMI_DATA_LO);
- cmdp_local++;
+ cmdp_local += 2;
}
CDBG("%s: end writing RollOff Ram1 table\n", __func__);
@@ -3035,6 +3072,8 @@
vfe32_ctrl->vfeio = vfeio;
vfe32_ctrl->update_linear = false;
vfe32_ctrl->update_rolloff = false;
+ vfe32_ctrl->update_la = false;
+ vfe32_ctrl->update_gamma = false;
return 0;
cmd_init_failed3:
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index 000beb2..d3ed0e6 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -253,6 +253,7 @@
#define V32_MESH_ROLL_OFF_INIT_TABLE_SIZE 13
#define V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE 208
#define V32_MESH_ROLL_OFF_DELTA_TABLE_OFFSET 32
+#define V32_GAMMA_LUT_BANK_SEL_MASK 0x00000007
#define V33_PCA_ROLL_OFF_CFG_LEN1 16
#define V33_PCA_ROLL_OFF_CFG_OFF1 0x00000274
@@ -279,7 +280,7 @@
#define V32_CHROMA_SUP_OFF 0x000003E8
#define V32_CHROMA_SUP_LEN 12
-#define V32_MCE_OFF 0x000003E8
+#define V32_MCE_OFF 0x000003F4
#define V32_MCE_LEN 36
#define V32_STATS_AF_OFF 0x0000053c
#define V32_STATS_AF_LEN 16
@@ -894,6 +895,8 @@
enum vfe_recording_state recording_state;
int8_t update_linear;
int8_t update_rolloff;
+ int8_t update_la;
+ int8_t update_gamma;
spinlock_t tasklet_lock;
struct list_head tasklet_q;
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index be15b779..d50ea43 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -83,10 +83,10 @@
{0x4005, 0x08},
{0x404f, 0x84},
{0x4051, 0x00},
- {0x5000, 0xff},
+ {0x5000, 0xcf},
{0x3a18, 0x00},
{0x3a19, 0x80},
- {0x3503, 0x13},
+ {0x3503, 0x03},
{0x4521, 0x00},
{0x5183, 0xb0},
{0x5184, 0xb0},
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index fa07d6b..f05fb8e 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -529,7 +529,7 @@
if (pdata->leds_pdata) {
leds_cell.platform_data = pdata->leds_pdata;
- leds_cell.pdata_size = sizeof(struct led_platform_data);
+ leds_cell.pdata_size = sizeof(struct pm8xxx_led_platform_data);
ret = mfd_add_devices(pmic->dev, 0, &leds_cell, 1, NULL, 0);
if (ret) {
pr_err("Failed to add leds subdevice ret=%d\n", ret);
diff --git a/drivers/mfd/pm8xxx-debug.c b/drivers/mfd/pm8xxx-debug.c
index 3b69121..7115726 100644
--- a/drivers/mfd/pm8xxx-debug.c
+++ b/drivers/mfd/pm8xxx-debug.c
@@ -132,8 +132,6 @@
return -ENOMEM;
}
- mutex_init(&debugdev->debug_mutex);
-
debugdev->parent = pdev->dev.parent;
debugdev->addr = -1;
@@ -160,6 +158,8 @@
goto file_error;
}
+ mutex_init(&debugdev->debug_mutex);
+
debugdev->dir = dir;
platform_set_drvdata(pdev, debugdev);
@@ -179,6 +179,7 @@
if (debugdev) {
debugfs_remove_recursive(debugdev->dir);
+ mutex_destroy(&debugdev->debug_mutex);
kfree(debugdev);
}
diff --git a/drivers/mfd/pmic8058.c b/drivers/mfd/pmic8058.c
index ff22339..7f433db 100644
--- a/drivers/mfd/pmic8058.c
+++ b/drivers/mfd/pmic8058.c
@@ -1205,6 +1205,7 @@
struct pm8058_dbg_device *dbgdev;
struct dentry *dent;
struct dentry *temp;
+ int rc;
if (chip == NULL) {
pr_err("%s: no parent data passed in.\n", __func__);
@@ -1217,8 +1218,6 @@
return -ENOMEM;
}
- mutex_init(&dbgdev->dbg_mutex);
-
dbgdev->pm_chip = chip;
dbgdev->addr = -1;
@@ -1226,7 +1225,8 @@
if (dent == NULL || IS_ERR(dent)) {
pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
__func__, (unsigned)dent);
- return -ENOMEM;
+ rc = PTR_ERR(dent);
+ goto dir_error;
}
temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, dent,
@@ -1234,6 +1234,7 @@
if (temp == NULL || IS_ERR(temp)) {
pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
__func__, (unsigned)temp);
+ rc = PTR_ERR(temp);
goto debug_error;
}
@@ -1242,9 +1243,12 @@
if (temp == NULL || IS_ERR(temp)) {
pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
__func__, (unsigned)temp);
+ rc = PTR_ERR(temp);
goto debug_error;
}
+ mutex_init(&dbgdev->dbg_mutex);
+
dbgdev->dent = dent;
pmic_dbg_device = dbgdev;
@@ -1253,13 +1257,17 @@
debug_error:
debugfs_remove_recursive(dent);
- return -ENOMEM;
+dir_error:
+ kfree(dbgdev);
+
+ return rc;
}
static int __devexit pmic8058_dbg_remove(void)
{
if (pmic_dbg_device) {
debugfs_remove_recursive(pmic_dbg_device->dent);
+ mutex_destroy(&pmic_dbg_device->dbg_mutex);
kfree(pmic_dbg_device);
}
return 0;
diff --git a/drivers/mfd/pmic8901.c b/drivers/mfd/pmic8901.c
index da46656..390de33 100644
--- a/drivers/mfd/pmic8901.c
+++ b/drivers/mfd/pmic8901.c
@@ -679,6 +679,7 @@
struct pm8901_dbg_device *dbgdev;
struct dentry *dent;
struct dentry *temp;
+ int rc;
if (chip == NULL) {
pr_err("%s: no parent data passed in.\n", __func__);
@@ -691,8 +692,6 @@
return -ENOMEM;
}
- mutex_init(&dbgdev->dbg_mutex);
-
dbgdev->pm_chip = chip;
dbgdev->addr = -1;
@@ -700,7 +699,8 @@
if (dent == NULL || IS_ERR(dent)) {
pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
__func__, (unsigned)dent);
- return -ENOMEM;
+ rc = PTR_ERR(dent);
+ goto dir_error;
}
temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, dent,
@@ -708,6 +708,7 @@
if (temp == NULL || IS_ERR(temp)) {
pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
__func__, (unsigned)temp);
+ rc = PTR_ERR(temp);
goto debug_error;
}
@@ -716,9 +717,12 @@
if (temp == NULL || IS_ERR(temp)) {
pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
__func__, (unsigned)temp);
+ rc = PTR_ERR(temp);
goto debug_error;
}
+ mutex_init(&dbgdev->dbg_mutex);
+
dbgdev->dent = dent;
pmic_dbg_device = dbgdev;
@@ -727,13 +731,17 @@
debug_error:
debugfs_remove_recursive(dent);
- return -ENOMEM;
+dir_error:
+ kfree(dbgdev);
+
+ return rc;
}
static int __devexit pmic8901_dbg_remove(void)
{
if (pmic_dbg_device) {
debugfs_remove_recursive(pmic_dbg_device->dent);
+ mutex_destroy(&pmic_dbg_device->dbg_mutex);
kfree(pmic_dbg_device);
}
return 0;
diff --git a/drivers/misc/pmic8058-xoadc.c b/drivers/misc/pmic8058-xoadc.c
index d2d8cba..f21668a 100644
--- a/drivers/misc/pmic8058-xoadc.c
+++ b/drivers/misc/pmic8058-xoadc.c
@@ -23,6 +23,7 @@
#include <linux/slab.h>
#include <linux/ratelimit.h>
#include <linux/delay.h>
+#include <linux/wakelock.h>
#include <mach/mpp.h>
#include <mach/msm_xo.h>
@@ -65,6 +66,9 @@
struct adc_conv_slot conv_queue_elements[MAX_QUEUE_LENGTH];
int xoadc_num;
struct msm_xo_voter *adc_voter;
+ struct wake_lock adc_wakelock;
+ /* flag to warn/bug if wakelocks are taken after suspend_noirq */
+ int msm_suspend_check;
};
static struct pmic8058_adc *pmic_adc[XOADC_PMIC_0 + 1];
@@ -117,7 +121,7 @@
EXPORT_SYMBOL(pm8058_xoadc_slot_request);
static int32_t pm8058_xoadc_arb_cntrl(uint32_t arb_cntrl,
- uint32_t adc_instance)
+ uint32_t adc_instance, uint32_t channel)
{
struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
int i, rc;
@@ -128,9 +132,13 @@
ADC_ARB_USRP_CNTRL_RSV4;
if (arb_cntrl) {
+ if (adc_pmic->msm_suspend_check)
+ pr_err("XOADC request being made after suspend irq "
+ "with channel id:%d\n", channel);
data_arb_cntrl |= ADC_ARB_USRP_CNTRL_EN_ARB;
msm_xo_mode_vote(adc_pmic->adc_voter, MSM_XO_MODE_ON);
adc_pmic->pdata->xoadc_mpp_config();
+ wake_lock(&adc_pmic->adc_wakelock);
}
/* Write twice to the CNTRL register for the arbiter settings
@@ -144,8 +152,10 @@
}
}
- if (!arb_cntrl)
+ if (!arb_cntrl) {
msm_xo_mode_vote(adc_pmic->adc_voter, MSM_XO_MODE_OFF);
+ wake_unlock(&adc_pmic->adc_wakelock);
+ }
return 0;
}
@@ -159,7 +169,7 @@
u8 data_dig_param, data_ana_param2;
int rc;
- rc = pm8058_xoadc_arb_cntrl(1, adc_instance);
+ rc = pm8058_xoadc_arb_cntrl(1, adc_instance, slot->chan_path);
if (rc < 0) {
pr_debug("%s: Configuring ADC Arbiter"
"enable failed\n", __func__);
@@ -461,7 +471,7 @@
/* Default value for switching off the arbiter after reading
the ADC value. Bit 0 set to 0. */
if (adc_pmic->xoadc_queue_count == 0) {
- rc = pm8058_xoadc_arb_cntrl(0, adc_instance);
+ rc = pm8058_xoadc_arb_cntrl(0, adc_instance, CHANNEL_MUXOFF);
if (rc < 0) {
pr_debug("%s: Configuring ADC Arbiter disable"
"failed\n", __func__);
@@ -607,6 +617,37 @@
}
EXPORT_SYMBOL(pm8058_xoadc_calibrate);
+#ifdef CONFIG_PM
+static int pm8058_xoadc_suspend_noirq(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pmic8058_adc *adc_pmic = platform_get_drvdata(pdev);
+
+ adc_pmic->msm_suspend_check = 1;
+
+ return 0;
+}
+
+static int pm8058_xoadc_resume_noirq(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pmic8058_adc *adc_pmic = platform_get_drvdata(pdev);
+
+ adc_pmic->msm_suspend_check = 0;
+
+ return 0;
+}
+
+static const struct dev_pm_ops pm8058_xoadc_dev_pm_ops = {
+ .suspend_noirq = pm8058_xoadc_suspend_noirq,
+ .resume_noirq = pm8058_xoadc_resume_noirq,
+};
+
+#define PM8058_XOADC_DEV_PM_OPS (&pm8058_xoadc_dev_pm_ops)
+#else
+#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);
@@ -614,6 +655,7 @@
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, adc_pmic->pm_chip);
device_init_wakeup(&pdev->dev, 0);
@@ -728,6 +770,9 @@
}
}
+ wake_lock_init(&adc_pmic->adc_wakelock, WAKE_LOCK_SUSPEND,
+ "pmic8058_xoadc_wakelock");
+
pmic_adc[adc_pmic->xoadc_num] = adc_pmic;
if (pdata->xoadc_vreg_setup != NULL)
@@ -750,6 +795,7 @@
.driver = {
.name = "pm8058-xoadc",
.owner = THIS_MODULE,
+ .pm = PM8058_XOADC_DEV_PM_OPS,
},
};
diff --git a/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c b/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c
index 51dd125..5da7a42 100644
--- a/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c
+++ b/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c
@@ -65,19 +65,11 @@
goto out;
}
- rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs), regs);
- if (rc) {
- pr_err("%s: could not set voltages: %d\n", __func__, rc);
- goto reg_free;
- }
-
for (i = 0; i < ARRAY_SIZE(regs); i++)
vreg_info[i].reg = regs[i].consumer;
return 0;
-reg_free:
- regulator_bulk_free(ARRAY_SIZE(regs), regs);
out:
return rc;
}
@@ -134,6 +126,25 @@
for (index = 0; index < ARRAY_SIZE(vreg_info); index++) {
if (on) {
+
+ rc = regulator_set_voltage(vreg_info[index].reg,
+ vreg_info[index].vreg_level,
+ vreg_info[index].vreg_level);
+ if (rc) {
+ pr_err("%s:%s set voltage failed %d\n",
+ __func__, vreg_info[index].vreg_id, rc);
+
+ goto vreg_fail;
+ }
+
+ rc = regulator_enable(vreg_info[index].reg);
+ if (rc) {
+ pr_err("%s:%s vreg enable failed %d\n",
+ __func__, vreg_info[index].vreg_id, rc);
+
+ goto vreg_fail;
+ }
+
if (vreg_info[index].is_vreg_pin_controlled) {
rc = pmapp_vreg_lpm_pincntrl_vote(id,
vreg_info[index].pmapp_id,
@@ -143,17 +154,10 @@
" for enable failed %d\n",
__func__,
vreg_info[index].vreg_id, rc);
- goto vreg_fail;
- }
- } else {
- rc = regulator_enable(vreg_info[index].reg);
- if (rc) {
- pr_err("%s:%s vreg enable failed %d\n",
- __func__,
- vreg_info[index].vreg_id, rc);
- goto vreg_fail;
+ goto vreg_clock_vote_fail;
}
}
+
/*At this point CLK_PWR_REQ is high*/
if (WLAN_VREG_L6 == index) {
/*
@@ -182,13 +186,11 @@
__func__,
vreg_info[index].vreg_id, rc);
}
- } else {
- rc = regulator_disable(vreg_info[index].reg);
- if (rc) {
- pr_err("%s:%s vreg disable failed %d\n",
- __func__,
- vreg_info[index].vreg_id, rc);
- }
+ }
+ rc = regulator_disable(vreg_info[index].reg);
+ if (rc) {
+ pr_err("%s:%s vreg disable failed %d\n",
+ __func__, vreg_info[index].vreg_id, rc);
}
}
}
@@ -196,7 +198,7 @@
vreg_fail:
index--;
vreg_clock_vote_fail:
- while (index > 0) {
+ while (index >= 0) {
rc = regulator_disable(vreg_info[index].reg);
if (rc) {
pr_err("%s:%s vreg disable failed %d\n",
diff --git a/drivers/power/msm_charger.c b/drivers/power/msm_charger.c
index 207572e..0cd7967 100644
--- a/drivers/power/msm_charger.c
+++ b/drivers/power/msm_charger.c
@@ -993,8 +993,6 @@
static int __init determine_initial_batt_status(void)
{
- int rc;
-
if (is_battery_present())
if (is_battery_id_valid())
if (is_battery_temp_within_range())
@@ -1010,13 +1008,6 @@
if (is_batt_status_capable_of_charging())
handle_battery_inserted();
- rc = power_supply_register(msm_chg.dev, &msm_psy_batt);
- if (rc < 0) {
- dev_err(msm_chg.dev, "%s: power_supply_register failed"
- " rc=%d\n", __func__, rc);
- return rc;
- }
-
/* start updaing the battery powersupply every msm_chg.update_time
* milliseconds */
queue_delayed_work(msm_chg.event_wq_thread,
@@ -1156,11 +1147,20 @@
void msm_battery_gauge_register(struct msm_battery_gauge *batt_gauge)
{
+ int rc;
+
if (msm_batt_gauge) {
msm_batt_gauge = batt_gauge;
pr_err("msm-charger %s multiple battery gauge called\n",
__func__);
} else {
+ rc = power_supply_register(msm_chg.dev, &msm_psy_batt);
+ if (rc < 0) {
+ dev_err(msm_chg.dev, "%s: power_supply_register failed"
+ " rc=%d\n", __func__, rc);
+ return;
+ }
+
msm_batt_gauge = batt_gauge;
determine_initial_batt_status();
}
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index 4896556..aaeb790 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -172,11 +172,17 @@
static char const * const spi_rsrcs[] = {
"spi_clk",
- "spi_cs",
"spi_miso",
"spi_mosi"
};
+static char const * const spi_cs_rsrcs[] = {
+ "spi_cs",
+ "spi_cs1",
+ "spi_cs2",
+ "spi_cs3",
+};
+
enum msm_spi_mode {
SPI_FIFO_MODE = 0x0, /* 00 */
SPI_BLOCK_MODE = 0x1, /* 01 */
@@ -184,6 +190,12 @@
SPI_MODE_NONE = 0xFF, /* invalid value */
};
+/* Structure for SPI CS GPIOs */
+struct spi_cs_gpio {
+ int gpio_num;
+ bool valid;
+};
+
/* Structures for Data Mover */
struct spi_dmov_cmd {
dmov_box box; /* data aligned to max(dm_burst_size, block_size)
@@ -330,8 +342,10 @@
struct spi_transfer *cur_rx_transfer;
/* Temporary buffer used for WR-WR or WR-RD transfers */
u8 *temp_buf;
- /* GPIO pin numbers for SPI clk, cs, miso and mosi */
+ /* GPIO pin numbers for SPI clk, miso and mosi */
int spi_gpios[ARRAY_SIZE(spi_rsrcs)];
+ /* SPI CS GPIOs for each slave */
+ struct spi_cs_gpio cs_gpios[ARRAY_SIZE(spi_cs_rsrcs)];
};
/* Forward declaration */
@@ -635,8 +649,8 @@
if (dd->spi_gpios[i] >= 0) {
result = gpio_request(dd->spi_gpios[i], spi_rsrcs[i]);
if (result) {
- pr_err("%s: gpio_request for pin %d failed\
- with error%d\n", __func__,
+ dev_err(dd->dev, "%s: gpio_request for pin %d "
+ "failed with error %d\n", __func__,
dd->spi_gpios[i], result);
goto error;
}
@@ -660,6 +674,13 @@
if (dd->spi_gpios[i] >= 0)
gpio_free(dd->spi_gpios[i]);
}
+
+ for (i = 0; i < ARRAY_SIZE(spi_cs_rsrcs); ++i) {
+ if (dd->cs_gpios[i].valid) {
+ gpio_free(dd->cs_gpios[i].gpio_num);
+ dd->cs_gpios[i].valid = 0;
+ }
+ }
}
static void msm_spi_clock_set(struct msm_spi *dd, int speed)
@@ -1652,7 +1673,24 @@
static void msm_spi_process_message(struct msm_spi *dd)
{
int xfrs_grped = 0;
+ int cs_num;
+ int rc;
+
dd->write_xfr_cnt = dd->read_xfr_cnt = 0;
+ cs_num = dd->cur_msg->spi->chip_select;
+ if ((!(dd->cur_msg->spi->mode & SPI_LOOP)) &&
+ (!(dd->cs_gpios[cs_num].valid)) &&
+ (dd->cs_gpios[cs_num].gpio_num >= 0)) {
+ rc = gpio_request(dd->cs_gpios[cs_num].gpio_num,
+ spi_cs_rsrcs[cs_num]);
+ if (rc) {
+ dev_err(dd->dev, "gpio_request for pin %d failed with "
+ "error %d\n", dd->cs_gpios[cs_num].gpio_num,
+ rc);
+ return;
+ }
+ dd->cs_gpios[cs_num].valid = 1;
+ }
dd->cur_transfer = list_first_entry(&dd->cur_msg->transfers,
struct spi_transfer,
@@ -1664,7 +1702,7 @@
&dd->cur_msg->transfers,
transfer_list) {
if (!dd->cur_transfer->len)
- return;
+ goto error;
if (xfrs_grped) {
xfrs_grped--;
continue;
@@ -1686,12 +1724,20 @@
int ret = msm_spi_map_dma_buffers(dd);
if (ret < 0) {
dd->cur_msg->status = ret;
- return;
+ goto error;
}
}
dd->cur_tx_transfer = dd->cur_rx_transfer = dd->cur_transfer;
msm_spi_process_transfer(dd);
}
+
+ return;
+
+error:
+ if (dd->cs_gpios[cs_num].valid) {
+ gpio_free(dd->cs_gpios[cs_num].gpio_num);
+ dd->cs_gpios[cs_num].valid = 0;
+ }
}
/* workqueue - pull messages from queue & process */
@@ -2257,9 +2303,17 @@
dd->spi_gpios[i] = resource ? resource->start : -1;
}
+ for (i = 0; i < ARRAY_SIZE(spi_cs_rsrcs); ++i) {
+ resource = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ spi_cs_rsrcs[i]);
+ dd->cs_gpios[i].gpio_num = resource ? resource->start : -1;
+ dd->cs_gpios[i].valid = 0;
+ }
+
rc = msm_spi_request_gpios(dd);
if (rc)
goto err_probe_gpio;
+
spin_lock_init(&dd->queue_lock);
mutex_init(&dd->core_lock);
INIT_LIST_HEAD(&dd->queue);
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 7cf888c..9017706 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2074,6 +2074,7 @@
continue; /* not configured */
if (hw_test_and_clear_complete(i)) {
+ udelay(200);
err = isr_tr_complete_low(mEp);
if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
if (err > 0) /* needs status phase */
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index dc06da6..4c33695 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -37,7 +37,7 @@
*/
/* big enough to hold our biggest descriptor */
-#define USB_BUFSIZ 1024
+#define USB_BUFSIZ 4096
static struct usb_composite_driver *composite;
static int (*composite_gadget_bind)(struct usb_composite_dev *cdev);
@@ -859,6 +859,10 @@
struct usb_function *f = NULL;
u8 endp;
+
+ if (w_length > USB_BUFSIZ)
+ return value;
+
/* partial re-init of the response message; the function or the
* gadget might need to intercept e.g. a control-OUT completion
* when we delegate to it.
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index ecade02..55d9a307 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2649,7 +2649,6 @@
*/
if (!fsg_is_set(common))
break;
- common->ep0req->length = 0;
if (test_and_clear_bit(IGNORE_BULK_OUT,
&common->fsg->atomic_bitflags))
usb_ep_clear_halt(common->fsg->bulk_in);
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index 0bb50de..ebbd1d8 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -41,6 +41,7 @@
int ifc_id;
u8 port_num;
atomic_t online;
+ atomic_t ctrl_online;
struct usb_composite_dev *cdev;
spinlock_t lock;
@@ -297,6 +298,8 @@
static void frmnet_disable(struct usb_function *f)
{
struct f_rmnet *dev = func_to_rmnet(f);
+ unsigned long flags;
+ struct rmnet_ctrl_pkt *cpkt;
pr_debug("%s: port#%d\n", __func__, dev->port_num);
@@ -304,6 +307,17 @@
atomic_set(&dev->online, 0);
+ spin_lock_irqsave(&dev->lock, flags);
+ while (!list_empty(&dev->cpkt_resp_q)) {
+ cpkt = list_first_entry(&dev->cpkt_resp_q,
+ struct rmnet_ctrl_pkt, list);
+
+ list_del(&cpkt->list);
+ rmnet_free_ctrl_pkt(cpkt);
+ }
+ atomic_set(&dev->notify_count, 0);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
gport_rmnet_disconnect(dev);
}
@@ -384,6 +398,73 @@
}
}
+static void frmnet_connect(struct grmnet *gr)
+{
+ struct f_rmnet *dev;
+
+ if (!gr) {
+ pr_err("%s: Invalid grmnet:%p\n", __func__, gr);
+ return;
+ }
+
+ dev = port_to_rmnet(gr);
+
+ atomic_set(&dev->ctrl_online, 1);
+}
+
+static void frmnet_disconnect(struct grmnet *gr)
+{
+ struct f_rmnet *dev;
+ unsigned long flags;
+ struct usb_cdc_notification *event;
+ int status;
+ struct rmnet_ctrl_pkt *cpkt;
+
+ if (!gr) {
+ pr_err("%s: Invalid grmnet:%p\n", __func__, gr);
+ return;
+ }
+
+ dev = port_to_rmnet(gr);
+
+ atomic_set(&dev->ctrl_online, 0);
+
+ if (!atomic_read(&dev->online)) {
+ pr_debug("%s: nothing to do\n", __func__);
+ return;
+ }
+
+ usb_ep_fifo_flush(dev->notify);
+
+ event = dev->notify_req->buf;
+ event->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS
+ | USB_RECIP_INTERFACE;
+ event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION;
+ event->wValue = cpu_to_le16(0);
+ event->wIndex = cpu_to_le16(dev->ifc_id);
+ event->wLength = cpu_to_le16(0);
+
+ status = usb_ep_queue(dev->notify, dev->notify_req, GFP_KERNEL);
+ if (status < 0) {
+ if (!atomic_read(&dev->online))
+ return;
+ pr_err("%s: rmnet notify ep enqueue error %d\n",
+ __func__, status);
+ }
+
+ spin_lock_irqsave(&dev->lock, flags);
+ while (!list_empty(&dev->cpkt_resp_q)) {
+ cpkt = list_first_entry(&dev->cpkt_resp_q,
+ struct rmnet_ctrl_pkt, list);
+
+ list_del(&cpkt->list);
+ rmnet_free_ctrl_pkt(cpkt);
+ }
+ atomic_set(&dev->notify_count, 0);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+}
+
static int
frmnet_send_cpkt_response(struct grmnet *gr, struct rmnet_ctrl_pkt *cpkt)
{
@@ -400,7 +481,7 @@
pr_debug("%s: dev:%p port#%d\n", __func__, dev, dev->port_num);
- if (!atomic_read(&dev->online)) {
+ if (!atomic_read(&dev->online) || !atomic_read(&dev->ctrl_online)) {
rmnet_free_ctrl_pkt(cpkt);
return 0;
}
@@ -459,6 +540,9 @@
pr_err("rmnet notify ep error %d\n", status);
/* FALLTHROUGH */
case 0:
+ if (!atomic_read(&dev->ctrl_online))
+ break;
+
if (atomic_dec_and_test(&dev->notify_count))
break;
@@ -493,8 +577,6 @@
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
| USB_CDC_SEND_ENCAPSULATED_COMMAND:
- if (w_length > req->length)
- goto invalid;
ret = w_length;
req->complete = frmnet_cmd_complete;
req->context = dev;
@@ -708,6 +790,8 @@
f->set_alt = frmnet_set_alt;
f->setup = frmnet_setup;
dev->port.send_cpkt_response = frmnet_send_cpkt_response;
+ dev->port.disconnect = frmnet_disconnect;
+ dev->port.connect = frmnet_connect;
status = usb_add_function(c, f);
if (status) {
diff --git a/drivers/usb/gadget/f_rmnet_sdio.c b/drivers/usb/gadget/f_rmnet_sdio.c
index 61a67bb..b15c221 100644
--- a/drivers/usb/gadget/f_rmnet_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_sdio.c
@@ -534,8 +534,6 @@
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
| USB_CDC_SEND_ENCAPSULATED_COMMAND:
- if (w_length > req->length)
- goto invalid;
ret = w_length;
req->complete = rmnet_sdio_command_complete;
req->context = dev;
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index 08a6799..b8dd3a5 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -534,8 +534,6 @@
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
| USB_CDC_SEND_ENCAPSULATED_COMMAND:
- if (w_length > req->length)
- goto invalid;
ret = w_length;
req->complete = rmnet_smd_command_complete;
req->context = dev;
diff --git a/drivers/usb/gadget/f_rmnet_smd_sdio.c b/drivers/usb/gadget/f_rmnet_smd_sdio.c
index b9120ca..eda547a 100644
--- a/drivers/usb/gadget/f_rmnet_smd_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_smd_sdio.c
@@ -1110,8 +1110,6 @@
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
| USB_CDC_SEND_ENCAPSULATED_COMMAND:
- if (w_length > req->length)
- goto invalid;
ret = w_length;
req->complete = rmnet_mux_command_complete;
req->context = dev;
diff --git a/drivers/usb/gadget/u_rmnet.h b/drivers/usb/gadget/u_rmnet.h
index aeaddee..3c21316 100644
--- a/drivers/usb/gadget/u_rmnet.h
+++ b/drivers/usb/gadget/u_rmnet.h
@@ -48,6 +48,9 @@
void (*send_cbits_tomodem)(struct grmnet *g,
u8 port_num,
int cbits);
+
+ void (*disconnect)(struct grmnet *g);
+ void (*connect)(struct grmnet *g);
};
int gbam_setup(unsigned int count);
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index b4d2828..fc159cc 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -273,6 +273,8 @@
{
struct rmnet_ctrl_port *port = p;
struct smd_ch_info *c = &port->ctrl_ch;
+ struct rmnet_ctrl_pkt *cpkt;
+ unsigned long flags;
pr_debug("%s: EVENT_(%s)\n", __func__, get_smd_event(event));
@@ -285,10 +287,27 @@
break;
case SMD_EVENT_OPEN:
set_bit(CH_OPENED, &c->flags);
- wake_up(&c->wait);
+
+ if (port && port->port_usb && port->port_usb->connect)
+ port->port_usb->connect(port->port_usb);
+
break;
case SMD_EVENT_CLOSE:
clear_bit(CH_OPENED, &c->flags);
+
+ if (port && port->port_usb && port->port_usb->disconnect)
+ port->port_usb->disconnect(port->port_usb);
+
+ spin_lock_irqsave(&port->port_lock, flags);
+ while (!list_empty(&c->tx_q)) {
+ cpkt = list_first_entry(&c->tx_q,
+ struct rmnet_ctrl_pkt, list);
+
+ list_del(&cpkt->list);
+ free_rmnet_ctrl_pkt(cpkt);
+ }
+ spin_unlock_irqrestore(&port->port_lock, flags);
+
break;
}
}
@@ -357,6 +376,7 @@
struct rmnet_ctrl_port *port;
unsigned long flags;
struct smd_ch_info *c;
+ struct rmnet_ctrl_pkt *cpkt;
pr_debug("%s: grmnet:%p port#%d\n", __func__, gr, port_num);
@@ -378,6 +398,14 @@
gr->send_cpkt_request = 0;
gr->send_cbits_tomodem = 0;
c->cbits_tomodem = 0;
+
+ while (!list_empty(&c->tx_q)) {
+ cpkt = list_first_entry(&c->tx_q, struct rmnet_ctrl_pkt, list);
+
+ list_del(&cpkt->list);
+ free_rmnet_ctrl_pkt(cpkt);
+ }
+
spin_unlock_irqrestore(&port->port_lock, flags);
if (test_bit(CH_OPENED, &c->flags)) {
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 3c130e9..4658469 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -2144,7 +2144,6 @@
static int msm_otg_pm_resume(struct device *dev)
{
struct msm_otg *motg = dev_get_drvdata(dev);
- int ret = 0;
dev_dbg(dev, "OTG PM resume\n");
@@ -2153,7 +2152,7 @@
* Do not resume hardware as part of system resume,
* rather, wait for the ASYNC INT from the h/w
*/
- return ret;
+ return 0;
#endif
return msm_otg_resume(motg);
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index ddc26b1..d3059d1 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -386,6 +386,7 @@
config FB_MSM_MIPI_PANEL_DETECT
bool "MIPI Panel Detect"
+ select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
select FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT
select FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
@@ -412,6 +413,24 @@
---help---
Support for LCDC panel auto detect
+config FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT
+ bool "LCDC + MIPI Panel Auto Detect"
+ select FB_MSM_LCDC_AUTO_DETECT
+ select FB_MSM_LCDC_SAMSUNG_WSVGA
+ select FB_MSM_LCDC_AUO_WVGA
+ select FB_MSM_LCDC_SAMSUNG_OLED_PT
+ select FB_MSM_LCDC_NT35582_WVGA
+ select FB_MSM_LCDC_TOSHIBA_FWVGA_PT
+ select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
+ select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+ select FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT
+ select FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
+ select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
+ select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+ select FB_MSM_MIPI_SIMULATOR_VIDEO
+ ---help---
+ Support for LCDC + MIPI panel auto detect
+
config FB_MSM_MDDI_PRISM_WVGA
bool "MDDI Prism WVGA Panel"
select FB_MSM_MDDI
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index dffde1b..3e89f0b 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -107,12 +107,6 @@
obj-$(CONFIG_FB_MSM_MDDI_QUICKVX) += mddi_quickvx.o
endif
-ifeq ($(CONFIG_FB_MSM_MIPI_PANEL_DETECT),y)
-obj-y += mipi_toshiba_video_wvga_pt.o mipi_toshiba_video_wsvga_pt.o
-obj-y += mipi_novatek_video_qhd_pt.o mipi_novatek_cmd_qhd_pt.o
-obj-y += mipi_renesas_video_fwvga_pt.o mipi_renesas_cmd_fwvga_pt.o
-obj-y += mipi_chimei_wxga_pt.o
-else
obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT) += mipi_toshiba_video_wvga_pt.o
obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT) += mipi_toshiba_video_wsvga_pt.o
obj-$(CONFIG_FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT) += mipi_novatek_video_qhd_pt.o
@@ -121,7 +115,6 @@
obj-$(CONFIG_FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT) += mipi_renesas_cmd_fwvga_pt.o
obj-$(CONFIG_FB_MSM_MIPI_SIMULATOR_VIDEO) += mipi_simulator_video.o
obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WXGA) += mipi_chimei_wxga_pt.o
-endif
obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
obj-$(CONFIG_FB_MSM_LCDC_PRISM_WVGA) += lcdc_prism.o
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index b9d8171..7eca334 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -276,17 +276,18 @@
} else {
hdmi_msm_state->hpd_cable_chg_detected = FALSE;
mutex_unlock(&hdmi_msm_state_mutex);
+ /* QDSP OFF preceding the HPD event notification */
+ envp[0] = "HDCP_STATE=FAIL";
+ envp[1] = NULL;
+ DEV_INFO("HDMI HPD: QDSP OFF\n");
+ kobject_uevent_env(external_common_state->uevent_kobj,
+ KOBJ_CHANGE, envp);
if (hpd_state) {
hdmi_msm_read_edid();
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
hdmi_msm_state->reauth = FALSE ;
#endif
/* Build EDID table */
- envp[0] = "HDCP_STATE=FAIL";
- envp[1] = NULL;
- DEV_INFO("HDMI HPD: QDSP OFF\n");
- kobject_uevent_env(external_common_state->uevent_kobj,
- KOBJ_CHANGE, envp);
hdmi_msm_turn_on();
DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
kobject_uevent(external_common_state->uevent_kobj,
@@ -3351,7 +3352,7 @@
hdmi_msm_hpd_off();
hdmi_msm_powerdown_phy();
hdmi_msm_dump_regs("HDMI-OFF: ");
- hdmi_msm_hpd_on(false);
+ hdmi_msm_hpd_on(true);
mutex_lock(&external_common_state_hpd_mutex);
if (!external_common_state->hpd_feature_on)
@@ -3668,6 +3669,9 @@
{
int rc;
+ if (msm_fb_detect_client("hdmi_msm"))
+ return 0;
+
hdmi_msm_setup_video_mode_lut();
hdmi_msm_state = kzalloc(sizeof(*hdmi_msm_state), GFP_KERNEL);
if (!hdmi_msm_state) {
diff --git a/drivers/video/msm/lcdc_auo_wvga.c b/drivers/video/msm/lcdc_auo_wvga.c
index b1c3af0..6b0733f 100644
--- a/drivers/video/msm/lcdc_auo_wvga.c
+++ b/drivers/video/msm/lcdc_auo_wvga.c
@@ -335,12 +335,10 @@
int ret;
struct msm_panel_info *pinfo;
-#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
if (msm_fb_detect_client(LCDC_AUO_PANEL_NAME)) {
pr_err("%s: detect failed\n", __func__);
return 0;
}
-#endif
ret = platform_driver_register(&this_driver);
if (ret) {
diff --git a/drivers/video/msm/lcdc_chimei_wxga.c b/drivers/video/msm/lcdc_chimei_wxga.c
index b5cce2c..7453ecb 100644
--- a/drivers/video/msm/lcdc_chimei_wxga.c
+++ b/drivers/video/msm/lcdc_chimei_wxga.c
@@ -187,10 +187,8 @@
int ret;
struct msm_panel_info *pinfo;
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
- if (msm_fb_detect_client("lcdc_chimei_lvds_wxga"))
+ if (msm_fb_detect_client("lcdc_chimei_wxga"))
return 0;
-#endif
ret = platform_driver_register(&this_driver);
if (ret)
diff --git a/drivers/video/msm/lcdc_samsung_oled_pt.c b/drivers/video/msm/lcdc_samsung_oled_pt.c
index dccc997..16790f3 100644
--- a/drivers/video/msm/lcdc_samsung_oled_pt.c
+++ b/drivers/video/msm/lcdc_samsung_oled_pt.c
@@ -551,12 +551,10 @@
{
int ret;
-#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
if (msm_fb_detect_client("lcdc_samsung_oled")) {
pr_err("%s: detect failed\n", __func__);
return 0;
}
-#endif
ret = platform_driver_register(&this_driver);
if (ret) {
diff --git a/drivers/video/msm/lcdc_samsung_wsvga.c b/drivers/video/msm/lcdc_samsung_wsvga.c
index b4bf8cf..6b35e52 100644
--- a/drivers/video/msm/lcdc_samsung_wsvga.c
+++ b/drivers/video/msm/lcdc_samsung_wsvga.c
@@ -48,12 +48,12 @@
static void lcdc_samsung_panel_set_backlight(struct msm_fb_data_type *mfd)
{
+#ifdef CONFIG_PMIC8058_PWM
int bl_level;
int ret;
bl_level = mfd->bl_level;
-#ifdef CONFIG_PMIC8058_PWM
if (bl_pwm0) {
ret = pwm_config(bl_pwm0, PWM_DUTY_LEVEL * bl_level,
PWM_PERIOD_USEC);
@@ -222,10 +222,8 @@
int ret;
struct msm_panel_info *pinfo;
-#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
if (msm_fb_detect_client("lcdc_samsung_wsvga"))
return 0;
-#endif
ret = platform_driver_register(&this_driver);
if (ret)
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 313814e..c522b0f 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -541,7 +541,7 @@
#ifdef CONFIG_FB_MSM_MDP303
#ifdef CONFIG_FB_MSM_MIPI_DSI
- mipi_dsi_cmd_mdp_sw_trigger();
+ mipi_dsi_cmd_mdp_start();
#endif
#endif
@@ -1085,6 +1085,18 @@
__func__, mdp_hw_revision);
}
+int mdp4_writeback_offset(void)
+{
+ int off = 0;
+
+ if (mdp_pdata->writeback_offset)
+ off = mdp_pdata->writeback_offset();
+
+ pr_debug("%s: writeback_offset=%d %x\n", __func__, off, off);
+
+ return off;
+}
+
#ifdef CONFIG_FB_MSM_MDP40
static void configure_mdp_core_clk_table(uint32 min_clk_rate)
{
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 39d69f8..0740f42 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -343,32 +343,6 @@
ulong err_format;
};
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
-static inline int mdp4_overlay_writeback_setup(struct fb_info *fbi,
- struct mdp4_overlay_pipe *pipe, uint8 *buf, int bpp)
-{
- struct msm_fb_data_type *mfd = fbi->par;
- int off;
-
- pipe->blt_base = (ulong) buf;
- off = ALIGN(fbi->var.xres, 32) * fbi->var.yres * bpp * mfd->fb_page;
- off += (1920 * 1080 * 2 * 1); /* hdmi */
- pipe->blt_base += off;
-
- pr_info("%s: base=%x offset=%x\n",
- __func__, (int) pipe->blt_base, (int)off);
-
- return off;
-
-}
-#else
-static inline int mdp4_overlay_writeback_setup(struct fb_info *fbi,
- struct mdp4_overlay_pipe *pipe, uint8 *buf, int bpp)
-{
- return 0;
-}
-#endif
-
void mdp4_sw_reset(unsigned long bits);
void mdp4_display_intf_sel(int output, unsigned long intf);
void mdp4_overlay_cfg(int layer, int blt_mode, int refresh, int direct_out);
@@ -624,6 +598,7 @@
struct msmfb_overlay_3d *r3d);
int mdp4_mixer_info(int mixer_num, struct mdp_mixer_info *info);
+int mdp4_writeback_offset(void);
void mdp_dmap_vsync_set(int enable);
int mdp_dmap_vsync_get(void);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 3870afd..ecefdc3 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -507,7 +507,7 @@
char *vg_base;
uint32 frame_size, src_size, src_xy, dst_size, dst_xy;
uint32 format, pattern, luma_offset, chroma_offset;
- int pnum;
+ int pnum, ptype;
pnum = pipe->pipe_num - OVERLAY_PIPE_VG1; /* start from 0 */
vg_base = MDP_BASE + MDP4_VIDEO_BASE;
@@ -519,16 +519,16 @@
dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
+ ptype = mdp4_overlay_format2type(pipe->src_format);
format = mdp4_overlay_format(pipe);
pattern = mdp4_overlay_unpack_pattern(pipe);
/* not RGB use VG pipe, pure VG pipe */
- if (pipe->pipe_type != OVERLAY_TYPE_RGB)
-#ifdef MDP4_IGC_LUT_ENABLE
- pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR |
- MDP4_OP_IGC_LUT_EN);
-#else
+ if (ptype != OVERLAY_TYPE_RGB)
pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR);
+
+#ifdef MDP4_IGC_LUT_ENABLE
+ pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
#endif
mdp4_scale_setup(pipe);
@@ -548,8 +548,14 @@
* present before the offset. This is required for video
* frames coming with unused green pixels along the left margin
*/
- mdp4_overlay_vg_get_src_offset(pipe, vg_base, &luma_offset,
- &chroma_offset);
+ /* not RGB use VG pipe, pure VG pipe */
+ if (ptype != OVERLAY_TYPE_RGB) {
+ mdp4_overlay_vg_get_src_offset(pipe, vg_base, &luma_offset,
+ &chroma_offset);
+ } else {
+ luma_offset = 0;
+ chroma_offset = 0;
+ }
/* luma component plane */
outpdw(vg_base + 0x0010, pipe->srcp0_addr + luma_offset);
@@ -1158,6 +1164,14 @@
void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
{
uint32 data, mask, snum, stage, mixer, pnum;
+ struct mdp4_overlay_pipe *spipe;
+
+ spipe = mdp4_overlay_stage_pipe(pipe->mixer_num, pipe->mixer_stage);
+ if ((spipe != NULL) && (spipe != pipe)) {
+ pr_err("%s: unable to stage pipe=%d at mixer_stage=%d\n",
+ __func__, pipe->pipe_ndx, pipe->mixer_stage);
+ return;
+ }
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 0b28c8b..0020fd5 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -115,7 +115,7 @@
void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd)
{
MDPIBUF *iBuf = &mfd->ibuf;
- struct fb_info *fbi;
+ struct fb_info *fbi = mfd->fbi;
uint8 *src;
int ptype;
struct mdp4_overlay_pipe *pipe;
@@ -155,11 +155,14 @@
dsi_pipe = pipe; /* keep it */
- fbi = mfd->fbi;
- bpp = fbi->var.bits_per_pixel / 8;
- src = (uint8 *) iBuf->buf;
- writeback_offset = mdp4_overlay_writeback_setup(
- fbi, pipe, src, bpp);
+ writeback_offset = mdp4_writeback_offset();
+
+ if (writeback_offset > 0) {
+ pipe->blt_base = (ulong)fbi->fix.smem_start;
+ pipe->blt_base += writeback_offset;
+ } else {
+ pipe->blt_base = 0;
+ }
} else {
pipe = dsi_pipe;
}
@@ -168,8 +171,8 @@
* dma_p = 0, dma_s = 1
*/
MDP_OUTP(MDP_BASE + 0x000a0, 0x10);
- /* enable dsi trigger on dma_p */
- MDP_OUTP(MDP_BASE + 0x000a4, 0x01);
+ /* disable dsi trigger */
+ MDP_OUTP(MDP_BASE + 0x000a4, 0x00);
/* whole screen for base layer */
src = (uint8 *) iBuf->buf;
@@ -304,6 +307,11 @@
pr_debug("%s: blt_end=%d blt_addr=%x pid=%d\n",
__func__, dsi_pipe->blt_end, (int)dsi_pipe->blt_addr, current->pid);
+ if (dsi_pipe->blt_base == 0) {
+ pr_info("%s: no blt_base assigned\n", __func__);
+ return -EBUSY;
+ }
+
if (dsi_pipe->blt_addr == 0) {
mdp4_dsi_cmd_dma_busy_wait(mfd);
spin_lock_irqsave(&mdp_spin_lock, flag);
@@ -453,7 +461,7 @@
/* kick off dmap */
outpdw(MDP_BASE + 0x000c, 0x0);
/* trigger dsi cmd engine */
- mipi_dsi_cmd_mdp_sw_trigger();
+ mipi_dsi_cmd_mdp_start();
mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
}
@@ -513,7 +521,7 @@
/* kick off dmap */
outpdw(MDP_BASE + 0x000c, 0x0);
/* trigger dsi cmd engine */
- mipi_dsi_cmd_mdp_sw_trigger();
+ mipi_dsi_cmd_mdp_start();
mdp_disable_irq_nosync(MDP_OVERLAY0_TERM);
}
@@ -630,6 +638,11 @@
/* change mdp clk */
mdp4_set_perf_level();
+ mipi_dsi_mdp_busy_wait(mfd);
+
+ if (dsi_pipe->blt_addr == 0)
+ mipi_dsi_cmd_mdp_start();
+
mdp4_overlay_dsi_state_set(ST_DSI_PLAYING);
spin_lock_irqsave(&mdp_spin_lock, flag);
@@ -640,11 +653,6 @@
/* start OVERLAY pipe */
spin_unlock_irqrestore(&mdp_spin_lock, flag);
mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
-
- if (dsi_pipe->blt_addr == 0) {
- /* trigger dsi cmd engine */
- mipi_dsi_cmd_mdp_sw_trigger();
- }
}
void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd)
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 5ec271ec..93933f3 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -141,8 +141,14 @@
dsi_pipe = pipe; /* keep it */
init_completion(&dsi_video_comp);
- writeback_offset = mdp4_overlay_writeback_setup(
- fbi, pipe, buf, bpp);
+ writeback_offset = mdp4_writeback_offset();
+
+ if (writeback_offset > 0) {
+ pipe->blt_base = (ulong)fbi->fix.smem_start;
+ pipe->blt_base += writeback_offset;
+ } else {
+ pipe->blt_base = 0;
+ }
} else {
pipe = dsi_pipe;
}
@@ -568,6 +574,11 @@
int data;
int change = 0;
+ if (dsi_pipe->blt_base == 0) {
+ pr_info("%s: no blt_base assigned\n", __func__);
+ return;
+ }
+
spin_lock_irqsave(&mdp_spin_lock, flag);
if (enable && dsi_pipe->blt_addr == 0) {
dsi_pipe->blt_addr = dsi_pipe->blt_base;
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 470c677..e840230 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -128,8 +128,14 @@
lcdc_pipe = pipe; /* keep it */
init_completion(&lcdc_comp);
- writeback_offset = mdp4_overlay_writeback_setup(
- fbi, pipe, buf, bpp);
+ writeback_offset = mdp4_writeback_offset();
+
+ if (writeback_offset > 0) {
+ pipe->blt_base = (ulong)fbi->fix.smem_start;
+ pipe->blt_base += writeback_offset;
+ } else {
+ pipe->blt_base = 0;
+ }
} else {
pipe = lcdc_pipe;
}
@@ -463,6 +469,11 @@
unsigned long flag;
int change = 0;
+ if (lcdc_pipe->blt_base == 0) {
+ pr_debug("%s: no blt_base assigned\n", __func__);
+ return;
+ }
+
spin_lock_irqsave(&mdp_spin_lock, flag);
if (enable && lcdc_pipe->blt_addr == 0) {
lcdc_pipe->blt_addr = lcdc_pipe->blt_base;
diff --git a/drivers/video/msm/mipi_chimei_wxga_pt.c b/drivers/video/msm/mipi_chimei_wxga_pt.c
index f070466..fe7035a 100644
--- a/drivers/video/msm/mipi_chimei_wxga_pt.c
+++ b/drivers/video/msm/mipi_chimei_wxga_pt.c
@@ -33,6 +33,7 @@
#include "msm_fb.h"
#include "msm_fb_panel.h"
#include "mipi_dsi.h"
+#include "mipi_tc358764_dsi2lvds.h"
#define MHZ (1000*1000)
@@ -40,7 +41,7 @@
* Panel info parameters.
* The panel info is passed to the mipi framebuffer driver.
*/
-static struct msm_panel_info chimei_waga_pinfo;
+static struct msm_panel_info chimei_wxga_pinfo;
/**
* The mipi_dsi_phy_ctrl is calculated according to the
@@ -70,45 +71,6 @@
};
/**
- * Register the panel device.
- *
- * @param pinfo
- * @param channel_id
- * @param panel_id
- *
- * @return int
- */
-static int mipi_chimei_wxga_register_panel(struct msm_panel_info *pinfo,
- u32 channel_id, u32 panel_id)
-{
- struct platform_device *pdev = NULL;
- int ret;
- /* Use DSI-to-LVDS bridge */
- const char driver_name[] = "mipi_tc358764";
-
- pr_debug("%s.\n", __func__);
-
- /* Note: the device id should be non-zero */
- pdev = platform_device_alloc(driver_name, (panel_id << 8)|channel_id);
- if (pdev == NULL)
- return -ENOMEM;
-
- pdev->dev.platform_data = pinfo;
-
- ret = platform_device_add(pdev);
- if (ret) {
- pr_err("%s: platform_device_register failed!\n", __func__);
- goto err_device_put;
- }
-
- return 0;
-
-err_device_put:
- platform_device_put(pdev);
- return ret;
-}
-
-/**
* Module init.
*
* Register the panel-info.
@@ -122,15 +84,12 @@
static int __init mipi_chimei_wxga_init(void)
{
int ret;
- struct msm_panel_info *pinfo = &chimei_waga_pinfo;
+ struct msm_panel_info *pinfo = &chimei_wxga_pinfo;
- pr_info("mipi-dsi chimei wxga (1366x768) driver ver 1.0.\n");
-
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
- if (msm_fb_detect_client("mipi_chimei_wxga"))
+ if (msm_fb_detect_client("mipi_video_chimei_wxga"))
return 0;
-#endif
+ pr_debug("mipi-dsi chimei wxga (1366x768) driver ver 1.0.\n");
/* Landscape */
pinfo->xres = 1366;
pinfo->yres = 768;
@@ -212,7 +171,7 @@
pinfo->mipi.fixed_packet_size = 4;
pinfo->mipi.force_clk_lane_hs = 1;
- ret = mipi_chimei_wxga_register_panel(pinfo, MIPI_DSI_PRIM,
+ ret = mipi_tc358764_dsi2lvds_register(pinfo, MIPI_DSI_PRIM,
MIPI_DSI_PANEL_WXGA);
if (ret)
pr_err("%s: failed to register device!\n", __func__);
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index c18f2a0..00256e6 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -87,6 +87,7 @@
if (mdp_rev >= MDP_REV_41) {
mdp4_dsi_cmd_dma_busy_wait(mfd);
mdp4_dsi_blt_dmap_busy_wait(mfd);
+ mipi_dsi_mdp_busy_wait(mfd);
} else {
mdp3_dsi_cmd_dma_busy_wait(mfd);
}
diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h
index 9f6ea7d..9907109 100644
--- a/drivers/video/msm/mipi_dsi.h
+++ b/drivers/video/msm/mipi_dsi.h
@@ -47,9 +47,10 @@
#define MIPI_DSI_PANEL_WVGA 1
#define MIPI_DSI_PANEL_WVGA_PT 2
#define MIPI_DSI_PANEL_FWVGA_PT 3
-#define MIPI_DSI_PANEL_WXGA 4
-
-#define DSI_PANEL_MAX 4
+#define MIPI_DSI_PANEL_WSVGA_PT 4
+#define MIPI_DSI_PANEL_QHD_PT 5
+#define MIPI_DSI_PANEL_WXGA 6
+#define DSI_PANEL_MAX 6
enum { /* mipi dsi panel */
DSI_VIDEO_MODE,
@@ -221,6 +222,17 @@
#define DTYPE_PERIPHERAL_OFF 0x22
#define DTYPE_PERIPHERAL_ON 0x32
+/*
+ * dcs response
+ */
+#define DTYPE_ACK_ERR_RESP 0x02
+#define DTYPE_EOT_RESP 0x08 /* end of tx */
+#define DTYPE_GEN_READ1_RESP 0x11 /* 1 parameter, short */
+#define DTYPE_GEN_READ2_RESP 0x12 /* 2 parameter, short */
+#define DTYPE_GEN_LREAD_RESP 0x1a
+#define DTYPE_DCS_LREAD_RESP 0x1c
+#define DTYPE_DCS_READ1_RESP 0x21 /* 1 parameter, short */
+#define DTYPE_DCS_READ2_RESP 0x22 /* 2 parameter, short */
struct dsi_cmd_desc {
int dtype;
@@ -260,7 +272,7 @@
void mipi_dsi_op_mode_config(int mode);
void mipi_dsi_cmd_mode_ctrl(int enable);
void mdp4_dsi_cmd_trigger(void);
-void mipi_dsi_cmd_mdp_sw_trigger(void);
+void mipi_dsi_cmd_mdp_start(void);
void mipi_dsi_cmd_bta_sw_trigger(void);
void mipi_dsi_ack_err_status(void);
void mipi_dsi_set_tear_on(struct msm_fb_data_type *mfd);
@@ -275,6 +287,7 @@
void mipi_dsi_post_kickoff_del(struct dsi_kickoff_action *act);
void mipi_dsi_controller_cfg(int enable);
void mipi_dsi_sw_reset(void);
+void mipi_dsi_mdp_busy_wait(struct msm_fb_data_type *mfd);
irqreturn_t mipi_dsi_isr(int irq, void *ptr);
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index 0697aac..9caa154 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -41,10 +41,12 @@
int mipi_dsi_clk_on;
static struct completion dsi_dma_comp;
+static struct completion dsi_mdp_comp;
static struct dsi_buf dsi_tx_buf;
static int dsi_irq_enabled;
-static int dsi_cmd_trigger;
-static spinlock_t dsi_lock;
+static spinlock_t dsi_irq_lock;
+static spinlock_t dsi_mdp_lock;
+static int dsi_mdp_busy;
static struct list_head pre_kickoff_list;
static struct list_head post_kickoff_list;
@@ -52,54 +54,44 @@
void mipi_dsi_init(void)
{
init_completion(&dsi_dma_comp);
+ init_completion(&dsi_mdp_comp);
mipi_dsi_buf_alloc(&dsi_tx_buf, DSI_BUF_SIZE);
- spin_lock_init(&dsi_lock);
+ spin_lock_init(&dsi_irq_lock);
+ spin_lock_init(&dsi_mdp_lock);
INIT_LIST_HEAD(&pre_kickoff_list);
INIT_LIST_HEAD(&post_kickoff_list);
}
-void mipi_dsi_enable_irq(enum dsi_trigger_type type)
+void mipi_dsi_enable_irq(void)
{
unsigned long flags;
- spin_lock_irqsave(&dsi_lock, flags);
- if (type == DSI_CMD_MODE_DMA)
- dsi_cmd_trigger = 1;
-
- pr_debug("%s(): dsi_irq_enabled %u, dsi_cmd_trigger %u\n",
- __func__, dsi_irq_enabled, dsi_cmd_trigger);
-
+ spin_lock_irqsave(&dsi_irq_lock, flags);
if (dsi_irq_enabled) {
pr_debug("%s: IRQ aleady enabled\n", __func__);
- spin_unlock_irqrestore(&dsi_lock, flags);
+ spin_unlock_irqrestore(&dsi_irq_lock, flags);
return;
}
dsi_irq_enabled = 1;
enable_irq(dsi_irq);
- spin_unlock_irqrestore(&dsi_lock, flags);
+ spin_unlock_irqrestore(&dsi_irq_lock, flags);
}
-void mipi_dsi_disable_irq(enum dsi_trigger_type type)
+void mipi_dsi_disable_irq(void)
{
unsigned long flags;
- spin_lock_irqsave(&dsi_lock, flags);
- if (type == DSI_CMD_MODE_DMA)
- dsi_cmd_trigger = 0;
-
- pr_debug("%s(): dsi_irq_enabled %u, dsi_cmd_trigger %u\n",
- __func__, dsi_irq_enabled, dsi_cmd_trigger);
-
+ spin_lock_irqsave(&dsi_irq_lock, flags);
if (dsi_irq_enabled == 0) {
pr_debug("%s: IRQ already disabled\n", __func__);
- spin_unlock_irqrestore(&dsi_lock, flags);
+ spin_unlock_irqrestore(&dsi_irq_lock, flags);
return;
}
dsi_irq_enabled = 0;
disable_irq(dsi_irq);
- spin_unlock_irqrestore(&dsi_lock, flags);
+ spin_unlock_irqrestore(&dsi_irq_lock, flags);
}
/*
@@ -108,19 +100,16 @@
*/
void mipi_dsi_disable_irq_nosync(void)
{
- spin_lock(&dsi_lock);
- pr_debug("%s(): dsi_irq_enabled %u, dsi_cmd_trigger %u\n",
- __func__, dsi_irq_enabled, dsi_cmd_trigger);
-
- if (dsi_irq_enabled == 0 || dsi_cmd_trigger == 1) {
+ spin_lock(&dsi_irq_lock);
+ if (dsi_irq_enabled == 0) {
pr_debug("%s: IRQ cannot be disabled\n", __func__);
- spin_unlock(&dsi_lock);
+ spin_unlock(&dsi_irq_lock);
return;
}
dsi_irq_enabled = 0;
disable_irq_nosync(dsi_irq);
- spin_unlock(&dsi_lock);
+ spin_unlock(&dsi_irq_lock);
}
void mipi_dsi_turn_on_clks(void)
@@ -728,6 +717,43 @@
return len;
}
+/*
+ * mipi_dsi_short_read1_resp: 1 parameter
+ */
+static int mipi_dsi_short_read1_resp(struct dsi_buf *rp)
+{
+ /* strip out dcs type */
+ rp->data++;
+ rp->len = 1;
+ return rp->len;
+}
+
+/*
+ * mipi_dsi_short_read2_resp: 2 parameter
+ */
+static int mipi_dsi_short_read2_resp(struct dsi_buf *rp)
+{
+ /* strip out dcs type */
+ rp->data++;
+ rp->len = 2;
+ return rp->len;
+}
+
+static int mipi_dsi_long_read_resp(struct dsi_buf *rp)
+{
+ short len;
+
+ len = rp->data[2];
+ len <<= 8;
+ len |= rp->data[1];
+ /* strip out dcs header */
+ rp->data += 4;
+ rp->len -= 4;
+ /* strip out 2 bytes of checksum */
+ rp->len -= 2;
+ return len;
+}
+
void mipi_dsi_host_init(struct mipi_panel_info *pinfo)
{
uint32 dsi_ctrl, intr_ctrl;
@@ -936,12 +962,42 @@
wmb();
}
-void mipi_dsi_cmd_mdp_sw_trigger(void)
+void mipi_dsi_mdp_busy_wait(struct msm_fb_data_type *mfd)
{
- mipi_dsi_pre_kickoff_action();
- mipi_dsi_enable_irq(DSI_CMD_MODE_MDP);
- MIPI_OUTP(MIPI_DSI_BASE + 0x090, 0x01); /* trigger */
- wmb();
+ unsigned long flag;
+ int need_wait = 0;
+
+ pr_debug("%s: start pid=%d\n",
+ __func__, current->pid);
+ spin_lock_irqsave(&dsi_mdp_lock, flag);
+ if (dsi_mdp_busy == TRUE) {
+ INIT_COMPLETION(dsi_mdp_comp);
+ need_wait++;
+ }
+ spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+
+ if (need_wait) {
+ /* wait until DMA finishes the current job */
+ pr_debug("%s: pending pid=%d\n",
+ __func__, current->pid);
+ wait_for_completion(&dsi_mdp_comp);
+ }
+ pr_debug("%s: done pid=%d\n",
+ __func__, current->pid);
+}
+
+void mipi_dsi_cmd_mdp_start(void)
+{
+ unsigned long flag;
+
+
+ if (!in_interrupt())
+ mipi_dsi_pre_kickoff_action();
+
+ spin_lock_irqsave(&dsi_mdp_lock, flag);
+ mipi_dsi_enable_irq();
+ dsi_mdp_busy = TRUE;
+ spin_unlock_irqrestore(&dsi_mdp_lock, flag);
}
@@ -1024,6 +1080,7 @@
struct dsi_cmd_desc *cm;
uint32 dsi_ctrl, ctrl;
int i, video_mode;
+ unsigned long flag;
/* turn on cmd mode
* for video mode, do not send cmds more than
@@ -1050,7 +1107,11 @@
}
}
- mipi_dsi_enable_irq(DSI_CMD_MODE_DMA);
+ spin_lock_irqsave(&dsi_mdp_lock, flag);
+ mipi_dsi_enable_irq();
+ dsi_mdp_busy = TRUE;
+ spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+
cm = cmds;
mipi_dsi_buf_init(tp);
for (i = 0; i < cnt; i++) {
@@ -1061,7 +1122,12 @@
msleep(cm->wait);
cm++;
}
- mipi_dsi_disable_irq(DSI_CMD_MODE_DMA);
+
+ spin_lock_irqsave(&dsi_mdp_lock, flag);
+ dsi_mdp_busy = FALSE;
+ mipi_dsi_disable_irq();
+ complete(&dsi_mdp_comp);
+ spin_unlock_irqrestore(&dsi_mdp_lock, flag);
if (video_mode)
MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl); /* restore */
@@ -1091,10 +1157,14 @@
*/
int mipi_dsi_cmds_rx(struct msm_fb_data_type *mfd,
struct dsi_buf *tp, struct dsi_buf *rp,
- struct dsi_cmd_desc *cmds, int len)
+ struct dsi_cmd_desc *cmds, int rlen)
{
- int cnt;
- static int pkt_size;
+ int cnt, len, diff, pkt_size;
+ unsigned long flag;
+ char cmd;
+
+ len = rlen;
+ diff = 0;
if (len <= 2)
cnt = 4; /* short read */
@@ -1108,6 +1178,7 @@
len = MIPI_DSI_LEN; /* 8 bytes at most */
len = (len + 3) & ~0x03; /* len 4 bytes align */
+ diff = len - rlen;
/*
* add extra 2 bytes to len to have overall
* packet size is multipe by 4. This also make
@@ -1128,16 +1199,17 @@
#endif
}
- mipi_dsi_enable_irq(DSI_CMD_MODE_DMA);
- if (pkt_size != len) {
- /* set new max pkt size */
- pkt_size = len;
- max_pktsize[0] = pkt_size;
+ spin_lock_irqsave(&dsi_mdp_lock, flag);
+ mipi_dsi_enable_irq();
+ dsi_mdp_busy = TRUE;
+ spin_unlock_irqrestore(&dsi_mdp_lock, flag);
- mipi_dsi_buf_init(tp);
- mipi_dsi_cmd_dma_add(tp, pkt_size_cmd);
- mipi_dsi_cmd_dma_tx(tp);
- }
+ /* packet size need to be set at every read */
+ pkt_size = len;
+ max_pktsize[0] = pkt_size;
+ mipi_dsi_buf_init(tp);
+ mipi_dsi_cmd_dma_add(tp, pkt_size_cmd);
+ mipi_dsi_cmd_dma_tx(tp);
mipi_dsi_buf_init(tp);
mipi_dsi_cmd_dma_add(tp, cmds);
@@ -1149,21 +1221,36 @@
* return data from client is ready and stored
* at RDBK_DATA register already
*/
+ mipi_dsi_buf_init(rp);
mipi_dsi_cmd_dma_rx(rp, cnt);
- mipi_dsi_disable_irq(DSI_CMD_MODE_DMA);
+ spin_lock_irqsave(&dsi_mdp_lock, flag);
+ dsi_mdp_busy = FALSE;
+ mipi_dsi_disable_irq();
+ complete(&dsi_mdp_comp);
+ spin_unlock_irqrestore(&dsi_mdp_lock, flag);
- /* strip off dcs header & crc */
- if (cnt > 4) { /* long response */
- if (mfd->panel_info.mipi.fixed_packet_size)
- rp->data += (cnt - len - 6); /* skip padding */
-
- rp->data += 4; /* skip dcs header */
- rp->len -= 6; /* deduct 4 bytes header + 2 bytes crc */
+ cmd = rp->data[0];
+ switch (cmd) {
+ case DTYPE_ACK_ERR_RESP:
+ pr_debug("%s: rx ACK_ERR_PACLAGE\n", __func__);
+ break;
+ case DTYPE_GEN_READ1_RESP:
+ case DTYPE_DCS_READ1_RESP:
+ mipi_dsi_short_read1_resp(rp);
+ break;
+ case DTYPE_GEN_READ2_RESP:
+ case DTYPE_DCS_READ2_RESP:
+ mipi_dsi_short_read2_resp(rp);
+ break;
+ case DTYPE_GEN_LREAD_RESP:
+ case DTYPE_DCS_LREAD_RESP:
+ mipi_dsi_long_read_resp(rp);
rp->len -= 2; /* extra 2 bytes added */
- } else {
- rp->data += 1; /* skip dcs short header */
- rp->len -= 2; /* deduct 1 byte header + 1 byte ecc */
+ rp->len -= diff; /* align bytes */
+ break;
+ default:
+ break;
}
return rp->len;
@@ -1343,6 +1430,10 @@
}
if (isr & DSI_INTR_CMD_MDP_DONE) {
+ spin_lock(&dsi_mdp_lock);
+ dsi_mdp_busy = FALSE;
+ spin_unlock(&dsi_mdp_lock);
+ complete(&dsi_mdp_comp);
mipi_dsi_disable_irq_nosync();
mipi_dsi_post_kickoff_action();
}
diff --git a/drivers/video/msm/mipi_novatek.c b/drivers/video/msm/mipi_novatek.c
index d467581..1ff950d 100644
--- a/drivers/video/msm/mipi_novatek.c
+++ b/drivers/video/msm/mipi_novatek.c
@@ -24,7 +24,7 @@
static struct dsi_buf novatek_tx_buf;
static struct dsi_buf novatek_rx_buf;
-
+static int mipi_novatek_lcd_init(void);
#define MIPI_DSI_NOVATEK_SPI_DEVICE_NAME "dsi_novatek_3d_panel_spi"
#define HPCI_FPGA_READ_CMD 0x84
@@ -312,9 +312,6 @@
tp = &novatek_tx_buf;
rp = &novatek_rx_buf;
- mipi_dsi_buf_init(rp);
- mipi_dsi_buf_init(tp);
-
cmd = &novatek_manufacture_id_cmd;
mipi_dsi_cmds_rx(mfd, tp, rp, cmd, 3);
lp = (uint32 *)rp->data;
@@ -445,6 +442,7 @@
/* mdp4_dsi_cmd_busy_wait: will turn on dsi clock also */
mdp4_dsi_cmd_dma_busy_wait(mfd);
mdp4_dsi_blt_dmap_busy_wait(mfd);
+ mipi_dsi_mdp_busy_wait(mfd);
led_pwm1[1] = (unsigned char)(mfd->bl_level);
mipi_dsi_cmds_tx(mfd, &novatek_tx_buf, novatek_cmd_backlight_cmds,
@@ -585,6 +583,12 @@
ch_used[channel] = TRUE;
+ ret = mipi_novatek_lcd_init();
+ if (ret) {
+ pr_err("mipi_novatek_lcd_init() failed with ret %u\n", ret);
+ return ret;
+ }
+
pdev = platform_device_alloc("mipi_novatek", (panel << 8)|channel);
if (!pdev)
return -ENOMEM;
@@ -613,7 +617,7 @@
return ret;
}
-static int __init mipi_novatek_lcd_init(void)
+static int mipi_novatek_lcd_init(void)
{
#ifdef CONFIG_SPI_QUP
int ret;
@@ -631,5 +635,3 @@
return platform_driver_register(&this_driver);
}
-
-module_init(mipi_novatek_lcd_init);
diff --git a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
index aaf86ae..fbd2495 100644
--- a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
+++ b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
@@ -39,10 +39,8 @@
{
int ret;
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
if (msm_fb_detect_client("mipi_cmd_novatek_qhd"))
return 0;
-#endif
pinfo.xres = 540;
pinfo.yres = 960;
@@ -81,7 +79,7 @@
pinfo.mipi.t_clk_post = 0x22;
pinfo.mipi.t_clk_pre = 0x3f;
pinfo.mipi.stream = 0; /* dma_p */
- pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+ pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
pinfo.mipi.te_sel = 1; /* TE from vsycn gpio */
pinfo.mipi.interleave_max = 1;
@@ -91,7 +89,7 @@
pinfo.mipi.dsi_phy_db = &dsi_cmd_mode_phy_db;
ret = mipi_novatek_device_register(&pinfo, MIPI_DSI_PRIM,
- MIPI_DSI_PANEL_WVGA_PT);
+ MIPI_DSI_PANEL_QHD_PT);
if (ret)
pr_err("%s: failed to register device!\n", __func__);
diff --git a/drivers/video/msm/mipi_novatek_video_qhd_pt.c b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
index 635b66e..42ddfbe 100644
--- a/drivers/video/msm/mipi_novatek_video_qhd_pt.c
+++ b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
@@ -39,10 +39,8 @@
{
int ret;
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
if (msm_fb_detect_client("mipi_video_novatek_qhd"))
return 0;
-#endif
pinfo.xres = 540;
pinfo.yres = 960;
@@ -88,7 +86,7 @@
pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
ret = mipi_novatek_device_register(&pinfo, MIPI_DSI_PRIM,
- MIPI_DSI_PANEL_WVGA_PT);
+ MIPI_DSI_PANEL_QHD_PT);
if (ret)
pr_err("%s: failed to register device!\n", __func__);
diff --git a/drivers/video/msm/mipi_renesas.c b/drivers/video/msm/mipi_renesas.c
index f0d424f..6a7027a 100644
--- a/drivers/video/msm/mipi_renesas.c
+++ b/drivers/video/msm/mipi_renesas.c
@@ -22,6 +22,8 @@
static struct dsi_buf renesas_tx_buf;
static struct dsi_buf renesas_rx_buf;
+static int mipi_renesas_lcd_init(void);
+
static char config_sleep_out[2] = {0x11, 0x00};
static char config_CMD_MODE[2] = {0x40, 0x01};
static char config_WRTXHT[7] = {0x92, 0x16, 0x08, 0x08, 0x00, 0x01, 0xe0};
@@ -1219,6 +1221,12 @@
ch_used[channel] = TRUE;
+ ret = mipi_renesas_lcd_init();
+ if (ret) {
+ pr_err("mipi_renesas_lcd_init() failed with ret %u\n", ret);
+ return ret;
+ }
+
pdev = platform_device_alloc("mipi_renesas", (panel << 8)|channel);
if (!pdev)
return -ENOMEM;
@@ -1245,12 +1253,10 @@
return ret;
}
-static int __init mipi_renesas_lcd_init(void)
+static int mipi_renesas_lcd_init(void)
{
mipi_dsi_buf_alloc(&renesas_tx_buf, DSI_BUF_SIZE);
mipi_dsi_buf_alloc(&renesas_rx_buf, DSI_BUF_SIZE);
return platform_driver_register(&this_driver);
}
-
-module_init(mipi_renesas_lcd_init);
diff --git a/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c b/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
index 796fbd2..7f5ac70 100644
--- a/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
+++ b/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
@@ -57,10 +57,8 @@
{
int ret;
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
if (msm_fb_detect_client("mipi_cmd_renesas_fwvga"))
return 0;
-#endif
pinfo.xres = 480;
pinfo.yres = 864;
diff --git a/drivers/video/msm/mipi_renesas_video_fwvga_pt.c b/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
index 0e49011..e826773 100644
--- a/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
+++ b/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
@@ -59,10 +59,8 @@
{
int ret;
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
if (msm_fb_detect_client("mipi_video_renesas_fwvga"))
return 0;
-#endif
pinfo.xres = 480;
pinfo.yres = 864;
diff --git a/drivers/video/msm/mipi_simulator.c b/drivers/video/msm/mipi_simulator.c
index da697b5..c6bf534 100644
--- a/drivers/video/msm/mipi_simulator.c
+++ b/drivers/video/msm/mipi_simulator.c
@@ -18,6 +18,8 @@
static struct dsi_buf simulator_rx_buf;
static struct msm_panel_common_pdata *mipi_simulator_pdata;
+static int mipi_simulator_lcd_init(void);
+
static char display_on[2] = {0x00, 0x00};
static char display_off[2] = {0x00, 0x00};
@@ -122,6 +124,11 @@
ch_used[channel] = TRUE;
pr_debug("%s:%d, debug info", __func__, __LINE__);
+ ret = mipi_simulator_lcd_init();
+ if (ret) {
+ pr_err("mipi_simulator_lcd_init() failed with ret %u\n", ret);
+ return ret;
+ }
pdev = platform_device_alloc("mipi_simulator", (panel << 8)|channel);
if (!pdev)
@@ -151,12 +158,10 @@
return ret;
}
-static int __init mipi_simulator_lcd_init(void)
+static int mipi_simulator_lcd_init(void)
{
mipi_dsi_buf_alloc(&simulator_tx_buf, DSI_BUF_SIZE);
mipi_dsi_buf_alloc(&simulator_rx_buf, DSI_BUF_SIZE);
return platform_driver_register(&this_driver);
}
-
-module_init(mipi_simulator_lcd_init);
diff --git a/drivers/video/msm/mipi_simulator_video.c b/drivers/video/msm/mipi_simulator_video.c
index 8795554..845df75 100644
--- a/drivers/video/msm/mipi_simulator_video.c
+++ b/drivers/video/msm/mipi_simulator_video.c
@@ -31,10 +31,8 @@
{
int ret;
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
- if (msm_fb_detect_client("mipi_video_simulator"))
+ if (msm_fb_detect_client("mipi_video_simulator_vga"))
return 0;
-#endif
pinfo.xres = 640;
pinfo.yres = 480;
pinfo.type = MIPI_VIDEO_PANEL;
@@ -78,7 +76,7 @@
pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
ret = mipi_simulator_device_register(&pinfo, MIPI_DSI_PRIM,
- MIPI_DSI_PANEL_FWVGA_PT);
+ MIPI_DSI_PANEL_VGA);
if (ret)
pr_err("%s: failed to register device!\n", __func__);
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.c b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
index 491afad..b1cdf78 100644
--- a/drivers/video/msm/mipi_tc358764_dsi2lvds.c
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
@@ -70,6 +70,7 @@
#include <linux/pwm.h>
#include "msm_fb.h"
#include "mipi_dsi.h"
+#include "mipi_tc358764_dsi2lvds.h"
/* Registers definition */
@@ -215,6 +216,7 @@
static int bl_level;
static u32 d2l_gpio_out_mask;
static u32 d2l_gpio_out_val;
+static int mipi_d2l_init(void);
/**
* Read a bridge register
@@ -607,6 +609,50 @@
return 0;
}
+/**
+ * Register the panel device.
+ *
+ * @param pinfo
+ * @param channel_id
+ * @param panel_id
+ *
+ * @return int
+ */
+int mipi_tc358764_dsi2lvds_register(struct msm_panel_info *pinfo,
+ u32 channel_id, u32 panel_id)
+{
+ struct platform_device *pdev = NULL;
+ int ret;
+ /* Use DSI-to-LVDS bridge */
+ const char driver_name[] = "mipi_tc358764";
+
+ pr_debug("%s.\n", __func__);
+ ret = mipi_d2l_init();
+ if (ret) {
+ pr_err("mipi_d2l_init() failed with ret %u\n", ret);
+ return ret;
+ }
+
+ /* Note: the device id should be non-zero */
+ pdev = platform_device_alloc(driver_name, (panel_id << 8)|channel_id);
+ if (pdev == NULL)
+ return -ENOMEM;
+
+ pdev->dev.platform_data = pinfo;
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ pr_err("%s: platform_device_register failed!\n", __func__);
+ goto err_device_put;
+ }
+
+ return 0;
+
+err_device_put:
+ platform_device_put(pdev);
+ return ret;
+}
+
static struct platform_driver d2l_driver = {
.probe = mipi_d2l_probe,
.remove = __devexit_p(mipi_d2l_remove),
@@ -620,29 +666,12 @@
*
* @return int
*/
-static int __init mipi_d2l_init(void)
+static int mipi_d2l_init(void)
{
pr_debug("%s.\n", __func__);
-
- d2l_common_pdata = NULL;
-
return platform_driver_register(&d2l_driver);
}
-/**
- * Module Exit.
- *
- */
-static void __exit mipi_d2l_exit(void)
-{
- pr_debug("%s.\n", __func__);
-
- platform_driver_unregister(&d2l_driver);
-}
-
-module_init(mipi_d2l_init);
-module_exit(mipi_d2l_exit);
-
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Toshiba MIPI-DSI-to-LVDS bridge driver");
MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.h b/drivers/video/msm/mipi_tc358764_dsi2lvds.h
new file mode 100644
index 0000000..072d1f4
--- /dev/null
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.h
@@ -0,0 +1,19 @@
+/* Copyright (c) 2011, 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 MIPI_TC358764_DSI2LVDS_H
+#define MIPI_TC358764_DSI2LVDS_H
+
+int mipi_tc358764_dsi2lvds_register(struct msm_panel_info *pinfo,
+ u32 channel_id, u32 panel_id);
+#endif /* MIPI_TC358764_DSI2LVDS_H */
diff --git a/drivers/video/msm/mipi_toshiba.c b/drivers/video/msm/mipi_toshiba.c
index 9e5d06a..5788f27 100644
--- a/drivers/video/msm/mipi_toshiba.c
+++ b/drivers/video/msm/mipi_toshiba.c
@@ -18,9 +18,11 @@
static struct pwm_device *bl_lpm;
static struct mipi_dsi_panel_platform_data *mipi_toshiba_pdata;
+#define TM_GET_PID(id) (((id) & 0xff00)>>8)
static struct dsi_buf toshiba_tx_buf;
static struct dsi_buf toshiba_rx_buf;
+static int mipi_toshiba_lcd_init(void);
#ifdef TOSHIBA_CMDS_UNUSED
static char one_lane[3] = {0xEF, 0x60, 0x62};
@@ -37,7 +39,6 @@
static char display_off[2] = {0x28, 0x00};
static char enter_sleep[2] = {0x10, 0x00};
-#ifdef CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
static char mcap_off[2] = {0xb2, 0x00};
static char ena_test_reg[3] = {0xEF, 0x01, 0x01};
static char two_lane[3] = {0xEF, 0x60, 0x63};
@@ -49,7 +50,7 @@
static char hor_addr_2B_wvga[5] = {0x2B, 0x00, 0x00, 0x03, 0x55};
static char if_sel_video[2] = {0x53, 0x01};
-static struct dsi_cmd_desc toshiba_display_on_cmds[] = {
+static struct dsi_cmd_desc toshiba_wvga_display_on_cmds[] = {
{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(mcap_off), mcap_off},
{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(ena_test_reg), ena_test_reg},
{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(two_lane), two_lane},
@@ -69,9 +70,6 @@
{DTYPE_DCS_WRITE, 1, 0, 0, 0, sizeof(display_on), display_on}
};
-#endif
-
-#ifdef CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
static char mcap_start[2] = {0xb0, 0x04};
static char num_out_pixelform[3] = {0xb3, 0x00, 0x87};
static char dsi_ctrl[3] = {0xb6, 0x30, 0x83};
@@ -135,7 +133,7 @@
static char set_pixel_format[2] = {0x3a, 0x70};
-static struct dsi_cmd_desc toshiba_display_on_cmds[] = {
+static struct dsi_cmd_desc toshiba_wsvga_display_on_cmds[] = {
{DTYPE_GEN_WRITE2, 1, 0, 0, 10, sizeof(mcap_start), mcap_start},
{DTYPE_GEN_LWRITE, 1, 0, 0, 10, sizeof(num_out_pixelform),
num_out_pixelform},
@@ -177,7 +175,6 @@
{DTYPE_DCS_WRITE, 1, 0, 0, 120, sizeof(exit_sleep), exit_sleep},
{DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(display_on), display_on}
};
-#endif
static struct dsi_cmd_desc toshiba_display_off_cmds[] = {
{DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(display_off), display_off},
@@ -195,8 +192,16 @@
if (mfd->key != MFD_KEY)
return -EINVAL;
- mipi_dsi_cmds_tx(mfd, &toshiba_tx_buf, toshiba_display_on_cmds,
- ARRAY_SIZE(toshiba_display_on_cmds));
+ if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WVGA_PT)
+ mipi_dsi_cmds_tx(mfd, &toshiba_tx_buf,
+ toshiba_wvga_display_on_cmds,
+ ARRAY_SIZE(toshiba_wvga_display_on_cmds));
+ else if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WSVGA_PT)
+ mipi_dsi_cmds_tx(mfd, &toshiba_tx_buf,
+ toshiba_wsvga_display_on_cmds,
+ ARRAY_SIZE(toshiba_wsvga_display_on_cmds));
+ else
+ return -EINVAL;
return 0;
}
@@ -296,6 +301,12 @@
ch_used[channel] = TRUE;
+ ret = mipi_toshiba_lcd_init();
+ if (ret) {
+ pr_err("mipi_toshiba_lcd_init() failed with ret %u\n", ret);
+ return ret;
+ }
+
pdev = platform_device_alloc("mipi_toshiba", (panel << 8)|channel);
if (!pdev)
return -ENOMEM;
@@ -324,12 +335,10 @@
return ret;
}
-static int __init mipi_toshiba_lcd_init(void)
+static int mipi_toshiba_lcd_init(void)
{
mipi_dsi_buf_alloc(&toshiba_tx_buf, DSI_BUF_SIZE);
mipi_dsi_buf_alloc(&toshiba_rx_buf, DSI_BUF_SIZE);
return platform_driver_register(&this_driver);
}
-
-module_init(mipi_toshiba_lcd_init);
diff --git a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
index 3602e75..ed34aa7 100644
--- a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
+++ b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
@@ -38,10 +38,8 @@
{
int ret;
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
if (msm_fb_detect_client("mipi_video_toshiba_wsvga"))
return 0;
-#endif
pinfo.xres = 600;
pinfo.yres = 1024;
@@ -96,7 +94,7 @@
pinfo.mipi.tx_eot_append = TRUE;
ret = mipi_toshiba_device_register(&pinfo, MIPI_DSI_PRIM,
- MIPI_DSI_PANEL_WVGA_PT);
+ MIPI_DSI_PANEL_WSVGA_PT);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
diff --git a/drivers/video/msm/mipi_toshiba_video_wvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
index 1913513..d6cabfc 100644
--- a/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
+++ b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
@@ -52,10 +52,8 @@
{
int ret;
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
if (msm_fb_detect_client("mipi_video_toshiba_wvga"))
return 0;
-#endif
pinfo.xres = 480;
pinfo.yres = 864; /* 856 for V1 surf */
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 542eea4..bde0573 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -188,25 +188,42 @@
};
#endif
+#define PANEL_NAME_MAX_LEN 30
static struct msm_fb_platform_data *msm_fb_pdata;
-static char panel_name[128];
-module_param_string(panel_name, panel_name, sizeof(panel_name) , 0);
+static char prim_panel_name[PANEL_NAME_MAX_LEN];
+static char ext_panel_name[PANEL_NAME_MAX_LEN];
+module_param_string(prim_display, prim_panel_name, sizeof(prim_panel_name) , 0);
+module_param_string(ext_display, ext_panel_name, sizeof(ext_panel_name) , 0);
int msm_fb_detect_client(const char *name)
{
- int ret = -EPERM;
+ int ret = 0;
+ u32 len;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
u32 id;
#endif
-
- MSM_FB_DEBUG("\n name = %s, panel_name = %s", name, panel_name);
- if (strlen(panel_name)) {
- if (!strcmp((char *)panel_name, name))
+ len = strnlen(name, PANEL_NAME_MAX_LEN);
+ if (strnlen(prim_panel_name, PANEL_NAME_MAX_LEN)) {
+ MSM_FB_DEBUG("\n name = %s, prim_display = %s",
+ name, prim_panel_name);
+ if (!strncmp((char *)prim_panel_name, name, len))
return 0;
else
- return -EPERM;
+ ret = -EPERM;
+ }
+ if (strnlen(ext_panel_name, PANEL_NAME_MAX_LEN)) {
+ MSM_FB_DEBUG("\n name = %s, ext_display = %s",
+ name, ext_panel_name);
+ if (!strncmp((char *)ext_panel_name, name, len))
+ return 0;
+ else
+ ret = -EPERM;
}
+ if (ret)
+ return ret;
+
+ ret = -EPERM;
if (msm_fb_pdata && msm_fb_pdata->detect_client) {
ret = msm_fb_pdata->detect_client(name);
diff --git a/drivers/video/msm/tvout_msm.c b/drivers/video/msm/tvout_msm.c
index 6912961..9ee55cc 100644
--- a/drivers/video/msm/tvout_msm.c
+++ b/drivers/video/msm/tvout_msm.c
@@ -601,6 +601,10 @@
static int __init tvout_init(void)
{
int ret;
+
+ if (msm_fb_detect_client("tvout_msm"))
+ return 0;
+
tvout_msm_state = kzalloc(sizeof(*tvout_msm_state), GFP_KERNEL);
if (!tvout_msm_state) {
DEV_ERR("tvout_msm_init FAILED: out of memory\n");
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index abe2216..bb26c51 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1660,8 +1660,11 @@
if (!decoder->codec.codec)
return false;
- min_dpb = ddl_decoder_min_num_dpb(decoder);
if (estimate) {
+ if (!decoder->cont_mode)
+ min_dpb = ddl_decoder_min_num_dpb(decoder);
+ else
+ min_dpb = 5;
frame_size = &decoder->client_frame_size;
output_buf_req = &decoder->client_output_buf_req;
input_buf_req = &decoder->client_input_buf_req;
@@ -1678,7 +1681,7 @@
}
memset(output_buf_req, 0,
sizeof(struct vcd_buffer_requirement));
- if ((!estimate && !decoder->idr_only_decoding) || (decoder->cont_mode))
+ if (!estimate && !decoder->idr_only_decoding && !decoder->cont_mode)
output_buf_req->actual_count = min_dpb + 4;
else
output_buf_req->actual_count = min_dpb;
@@ -1699,7 +1702,7 @@
input_buf_req->min_count = 1;
input_buf_req->actual_count = input_buf_req->min_count + 1;
input_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
- input_buf_req->sz = (1024 * 1024);
+ input_buf_req->sz = (1024 * 1024 * 2);
input_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES;
decoder->min_input_buf_req = *input_buf_req;
return true;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index a69b810..0d8fcc2 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -411,21 +411,24 @@
return !islist_empty;
}
-static u32 vid_enc_get_next_msg(struct video_client_ctx *client_ctx,
+static int vid_enc_get_next_msg(struct video_client_ctx *client_ctx,
struct venc_msg *venc_msg_info)
{
int rc;
struct vid_enc_msg *vid_enc_msg = NULL;
if (!client_ctx)
- return false;
+ return -EIO;
rc = wait_event_interruptible(client_ctx->msg_wait,
vid_enc_msg_pending(client_ctx));
- if (rc < 0 || client_ctx->stop_msg) {
- DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg);
- return false;
+ if (rc < 0) {
+ DBG("rc = %d,stop_msg= %u\n", rc, client_ctx->stop_msg);
+ return rc;
+ } else if (client_ctx->stop_msg) {
+ DBG("stopped stop_msg = %u\n", client_ctx->stop_msg);
+ return -EIO;
}
mutex_lock(&client_ctx->msg_queue_lock);
@@ -440,7 +443,7 @@
kfree(vid_enc_msg);
}
mutex_unlock(&client_ctx->msg_queue_lock);
- return true;
+ return 0;
}
static u32 vid_enc_close_client(struct video_client_ctx *client_ctx)
@@ -727,6 +730,7 @@
struct venc_ioctl_msg venc_msg;
void __user *arg = (void __user *)u_arg;
u32 result = true;
+ int result_read = -1;
DBG("%s\n", __func__);
@@ -743,9 +747,9 @@
if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
return -EFAULT;
DBG("VEN_IOCTL_CMD_READ_NEXT_MSG\n");
- result = vid_enc_get_next_msg(client_ctx, &cb_msg);
- if (!result)
- return -EIO;
+ result_read = vid_enc_get_next_msg(client_ctx, &cb_msg);
+ if (result_read < 0)
+ return result_read;
if (copy_to_user(venc_msg.out, &cb_msg, sizeof(cb_msg)))
return -EFAULT;
break;
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 22270de..91d67d5 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -18,10 +18,11 @@
#define EVENT_MASKS_TYPE 4
#define PKT_TYPE 8
#define DEINIT_TYPE 16
-#define MEMORY_DEVICE_LOG_TYPE 32
+#define USER_SPACE_LOG_TYPE 32
#define USB_MODE 1
#define MEMORY_DEVICE_MODE 2
#define NO_LOGGING_MODE 3
+#define UART_MODE 4
/* different values that go in for diag_data_type */
#define DATA_TYPE_EVENT 0
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 91cbbda..df44376 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -17,9 +17,11 @@
#ifndef _LINUX_ION_H
#define _LINUX_ION_H
+#include <linux/ioctl.h>
#include <linux/types.h>
#include <mach/ion.h>
+
struct ion_handle;
/**
* enum ion_heap_types - list of all possible types of heaps
@@ -69,6 +71,8 @@
#define ION_SET_CACHE(__cache) ((__cache) << ION_CACHE_SHIFT)
+#define ION_IS_CACHED(__flags) ((__flags) & (1 << ION_CACHE_SHIFT))
+
#ifdef __KERNEL__
struct ion_device;
struct ion_heap;
@@ -328,6 +332,24 @@
unsigned long arg;
};
+
+/* struct ion_flush_data - data passed to ion for flushing caches
+ *
+ * @handle: handle with data to flush
+ * @vaddr: userspace virtual address mapped with mmap
+ * @offset: offset into the handle to flush
+ * @length: length of handle to flush
+ *
+ * Performs cache operations on the handle. If p is the start address
+ * of the handle, p + offset through p + offset + length will have
+ * the cache operations performed
+ */
+struct ion_flush_data {
+ struct ion_handle *handle;
+ void *vaddr;
+ unsigned int offset;
+ unsigned int length;
+};
#define ION_IOC_MAGIC 'I'
/**
@@ -384,4 +406,26 @@
*/
#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)
+
+/**
+ * DOC: ION_IOC_CLEAN_CACHES - clean the caches
+ *
+ * Clean the caches of the handle specified.
+ */
+#define ION_IOC_CLEAN_CACHES _IOWR(ION_IOC_MAGIC, 7, \
+ struct ion_flush_data)
+/**
+ * DOC: ION_MSM_IOC_INV_CACHES - invalidate the caches
+ *
+ * Invalidate the caches of the handle specified.
+ */
+#define ION_IOC_INV_CACHES _IOWR(ION_IOC_MAGIC, 8, \
+ struct ion_flush_data)
+/**
+ * DOC: ION_MSM_IOC_CLEAN_CACHES - clean and invalidate the caches
+ *
+ * Clean and invalidate the caches of the handle specified.
+ */
+#define ION_IOC_CLEAN_INV_CACHES _IOWR(ION_IOC_MAGIC, 9, \
+ struct ion_flush_data)
#endif /* _LINUX_ION_H */
diff --git a/include/linux/leds-pm8xxx.h b/include/linux/leds-pm8xxx.h
index 4096355..edd3c28 100644
--- a/include/linux/leds-pm8xxx.h
+++ b/include/linux/leds-pm8xxx.h
@@ -13,16 +13,10 @@
#ifndef __LEDS_PM8XXX_H__
#define __LEDS_PM8XXX_H__
+#include <linux/kernel.h>
#define PM8XXX_LEDS_DEV_NAME "pm8xxx-led"
-#define PM8XXX_LED_ID_SHIFT 0
-#define PM8XXX_LED_MODE_SHIFT 4
-#define PM8XXX_LED_MAX_CURRENT_SHIFT 8
-#define PM8XXX_LED_ID_MASK 0xF
-#define PM8XXX_LED_MODE_MASK 0xF0
-#define PM8XXX_LED_MAX_CURRENT_MASK 0xFFFF00
-
/**
* enum pm8xxx_leds - PMIC8XXX supported led ids
* @PM8XXX_ID_LED_KB_LIGHT - keyboard backlight led
@@ -55,4 +49,30 @@
PM8XXX_LED_MODE_DTEST4
};
+/**
+ * pm8xxx_led_config - led configuration parameters
+ * id - LED id
+ * mode - LED mode
+ * max_current - maximum current that LED can sustain
+ */
+struct pm8xxx_led_config {
+ u8 id;
+ u8 mode;
+ u16 max_current;
+};
+
+/**
+ * pm8xxx_led_platform_data - platform data for LED
+ * led_core - array of LEDs. Each datum in array contains
+ * core data for the LED
+ * configs - array of platform configuration parameters
+ * for each LED. It maps one-to-one with
+ * array of LEDs
+ * num_configs - count of members of configs array
+ */
+struct pm8xxx_led_platform_data {
+ struct led_platform_data *led_core;
+ struct pm8xxx_led_config *configs;
+ u32 num_configs;
+};
#endif /* __LEDS_PM8XXX_H__ */
diff --git a/include/linux/mfd/pm8xxx/pm8921.h b/include/linux/mfd/pm8xxx/pm8921.h
index bde5bbc..64bdab1 100644
--- a/include/linux/mfd/pm8xxx/pm8921.h
+++ b/include/linux/mfd/pm8xxx/pm8921.h
@@ -33,7 +33,7 @@
#include <linux/mfd/pm8xxx/pm8921-charger.h>
#include <linux/mfd/pm8xxx/pm8921-adc.h>
#include <linux/mfd/pm8xxx/pm8921-bms.h>
-#include <linux/leds.h>
+#include <linux/leds-pm8xxx.h>
#include <linux/mfd/pm8xxx/vibrator.h>
#define PM8921_NR_IRQS 256
@@ -126,7 +126,7 @@
struct pm8921_regulator_platform_data *regulator_pdatas;
int num_regulators;
struct pm8921_adc_platform_data *adc_pdata;
- struct led_platform_data *leds_pdata;
+ struct pm8xxx_led_platform_data *leds_pdata;
struct pm8xxx_vibrator_platform_data *vibrator_pdata;
};
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 3c47a92..4c9b53e 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -239,11 +239,26 @@
uint32_t vb;
};
-struct msm_isp_stats_event_ctrl {
+struct msm_mctl_pp_cmd_ack_event {
+ uint32_t cmd; /* VPE_CMD_ZOOM? */
+ int status; /* 0 done, < 0 err */
+ uint32_t cookie; /* daemon's cookie */
+};
+
+struct msm_mctl_pp_event_info {
+ int32_t event;
+ union {
+ struct msm_mctl_pp_cmd_ack_event ack;
+ };
+};
+
+struct msm_isp_event_ctrl {
unsigned short resptype;
union {
struct msm_cam_evt_msg isp_msg;
struct msm_ctrl_cmd ctrl;
+ struct msm_cam_evt_divert_frame div_frame;
+ struct msm_mctl_pp_event_info pp_event_info;
} isp_data;
};
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index fd46692..bd69d46 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -273,12 +273,6 @@
/* TBD: 3D related */
};
-struct msm_mctl_pp_cmd_ack_event {
- uint32_t cmd; /* VPE_CMD_ZOOM? */
- int status; /* 0 done, < 0 err */
- uint32_t cookie; /* daemon's cookie */
-};
-
struct msm_pp_frame_sp {
unsigned long phy_addr;
uint32_t y_off;
@@ -307,13 +301,5 @@
};
};
-struct msm_mctl_pp_event_info {
- int32_t event;
- union {
- struct msm_mctl_pp_cmd_ack_event ack;
- };
-};
-
-
#endif /*__MSM_ISP_H__*/
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index d5a3009..dc154f2 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -244,6 +244,7 @@
{
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
+ int mask_this_irq = 0;
irqreturn_t action_ret;
might_sleep();
@@ -253,8 +254,10 @@
kstat_incr_irqs_this_cpu(irq, desc);
action = desc->action;
- if (unlikely(!action || irqd_irq_disabled(&desc->irq_data)))
+ if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) {
+ mask_this_irq = 1;
goto out_unlock;
+ }
irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
raw_spin_unlock_irq(&desc->lock);
@@ -268,6 +271,11 @@
out_unlock:
raw_spin_unlock_irq(&desc->lock);
+ if (unlikely(mask_this_irq)) {
+ chip_bus_lock(desc);
+ mask_irq(desc);
+ chip_bus_sync_unlock(desc);
+ }
}
EXPORT_SYMBOL_GPL(handle_nested_irq);
diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c
index 9f77f61..e9f49b5 100644
--- a/kernel/power/wakelock.c
+++ b/kernel/power/wakelock.c
@@ -386,7 +386,8 @@
if (debug_mask & DEBUG_SUSPEND)
pr_info("power_suspend_late return %d\n", ret);
- msm_suspend_check_done = 1;
+ if (ret == 0)
+ msm_suspend_check_done = 1;
return ret;
}
diff --git a/kernel/printk.c b/kernel/printk.c
index ccdfac7..bddd32b 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -53,10 +53,6 @@
#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
-#ifdef CONFIG_DEBUG_LL
-extern void printascii(char *);
-#endif
-
/* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
@@ -928,9 +924,6 @@
printed_len += vscnprintf(printk_buf + printed_len,
sizeof(printk_buf) - printed_len, fmt, args);
-#ifdef CONFIG_DEBUG_LL
- printascii(printk_buf);
-#endif
p = printk_buf;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 079538b..733e9d2 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -50,10 +50,13 @@
struct hci_dev *hdev = conn->hdev;
struct hci_cp_le_create_conn cp;
+ BT_DBG("%p", conn);
+
conn->state = BT_CONNECT;
conn->out = 1;
conn->link_mode |= HCI_LM_MASTER;
conn->sec_level = BT_SECURITY_LOW;
+ conn->type = LE_LINK;
memset(&cp, 0, sizeof(cp));
cp.scan_interval = cpu_to_le16(0x0004);
@@ -300,9 +303,6 @@
BT_DBG("conn %p state %d", conn, conn->state);
- if (atomic_read(&conn->refcnt))
- return;
-
hci_dev_lock(hdev);
switch (conn->state) {
@@ -317,11 +317,14 @@
break;
case BT_CONFIG:
case BT_CONNECTED:
- reason = hci_proto_disconn_ind(conn);
- hci_acl_disconn(conn, reason);
+ if (!atomic_read(&conn->refcnt)) {
+ reason = hci_proto_disconn_ind(conn);
+ hci_acl_disconn(conn, reason);
+ }
break;
default:
- conn->state = BT_CLOSED;
+ if (!atomic_read(&conn->refcnt))
+ conn->state = BT_CLOSED;
break;
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index ad88382..699284a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1401,7 +1401,7 @@
int hci_register_dev(struct hci_dev *hdev)
{
struct list_head *head = &hci_dev_list, *p;
- int i, id = 0;
+ int i, id;
BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name,
hdev->bus, hdev->owner);
@@ -1409,6 +1409,8 @@
if (!hdev->open || !hdev->close || !hdev->destruct)
return -EINVAL;
+ id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
+
write_lock_bh(&hci_dev_list_lock);
/* Find first available device id */
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e2d6490..da8b780 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1352,6 +1352,10 @@
else
BT_ERR("No memory for new connection");
}
+
+ if (conn)
+ mod_timer(&conn->disc_timer,
+ jiffies + msecs_to_jiffies(5000));
}
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d103bef6..dea21c1 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -909,6 +909,37 @@
}
}
+/* Find socket with fixed cid with given source and destination bdaddrs.
+ * Returns closest match, locked.
+ */
+static struct sock *l2cap_get_sock_by_fixed_scid(int state,
+ __le16 cid, bdaddr_t *src, bdaddr_t *dst)
+{
+ struct sock *sk = NULL, *sk1 = NULL;
+ struct hlist_node *node;
+
+ read_lock(&l2cap_sk_list.lock);
+
+ sk_for_each(sk, node, &l2cap_sk_list.head) {
+ if (state && sk->sk_state != state)
+ continue;
+
+ if (l2cap_pi(sk)->scid == cid && !bacmp(&bt_sk(sk)->dst, dst)) {
+ /* Exact match. */
+ if (!bacmp(&bt_sk(sk)->src, src))
+ break;
+
+ /* Closest match */
+ if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
+ sk1 = sk;
+ }
+ }
+
+ read_unlock(&l2cap_sk_list.lock);
+
+ return node ? sk : sk1;
+}
+
/* Find socket with cid and source bdaddr.
* Returns closest match, locked.
*/
@@ -7051,7 +7082,7 @@
{
struct sock *sk;
- sk = l2cap_get_sock_by_scid(0, cid, conn->src);
+ sk = l2cap_get_sock_by_fixed_scid(0, cid, conn->src, conn->dst);
if (!sk)
goto drop;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 848a515..a328db9 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1411,6 +1411,10 @@
BT_DBG("Unable to find a pending command");
return;
}
+
+ if (status)
+ pairing_complete(cmd, status);
+
hci_conn_put(conn);
}
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index aea2447..a6e2aab 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -438,6 +438,7 @@
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
&reason);
del_timer(&hcon->smp_timer);
+ mgmt_auth_failed(hcon->hdev->id, conn->dst, reason);
hci_conn_put(hcon);
} else if (hcon->cfm_pending) {
BT_DBG("send_pairing_confirm");
@@ -845,6 +846,7 @@
reason = 0;
err = -EPERM;
del_timer(&hcon->smp_timer);
+ mgmt_auth_failed(hcon->hdev->id, conn->dst, skb->data[1]);
hci_conn_put(hcon);
break;
@@ -893,6 +895,7 @@
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
&reason);
del_timer(&hcon->smp_timer);
+ mgmt_auth_failed(hcon->hdev->id, conn->dst, reason);
hci_conn_put(hcon);
}
@@ -986,6 +989,7 @@
hcon->disconn_cfm_cb(hcon, 0);
del_timer(&hcon->smp_timer);
+ mgmt_auth_failed(hcon->hdev->id, conn->dst, SMP_UNSPECIFIED);
hci_conn_put(hcon);
}
@@ -1016,5 +1020,6 @@
BT_DBG("%p", conn);
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), &reason);
+ mgmt_auth_failed(conn->hcon->hdev->id, conn->dst, SMP_UNSPECIFIED);
hci_conn_put(conn->hcon);
}
diff --git a/sound/soc/codecs/wcd9310-tables.c b/sound/soc/codecs/wcd9310-tables.c
index 98a5139..a97a981 100644
--- a/sound/soc/codecs/wcd9310-tables.c
+++ b/sound/soc/codecs/wcd9310-tables.c
@@ -319,6 +319,18 @@
[TABLA_A_CDC_TX8_DMIC_CTL] = 1,
[TABLA_A_CDC_TX9_DMIC_CTL] = 1,
[TABLA_A_CDC_TX10_DMIC_CTL] = 1,
+ [TABLA_A_CDC_ANC2_CTL] = 1,
+ [TABLA_A_CDC_ANC2_SHIFT] = 1,
+ [TABLA_A_CDC_ANC2_FILT1_B1_CTL] = 1,
+ [TABLA_A_CDC_ANC2_FILT1_B2_CTL] = 1,
+ [TABLA_A_CDC_ANC2_FILT1_B3_CTL] = 1,
+ [TABLA_A_CDC_ANC2_FILT1_B4_CTL] = 1,
+ [TABLA_A_CDC_ANC2_FILT2_B1_CTL] = 1,
+ [TABLA_A_CDC_ANC2_FILT2_B2_CTL] = 1,
+ [TABLA_A_CDC_ANC2_FILT2_B3_CTL] = 1,
+ [TABLA_A_CDC_ANC2_SPARE] = 1,
+ [TABLA_A_CDC_ANC2_FILT3_CTL] = 1,
+ [TABLA_A_CDC_ANC2_FILT4_CTL] = 1,
[TABLA_A_CDC_SRC1_PDA_CFG] = 1,
[TABLA_A_CDC_SRC2_PDA_CFG] = 1,
[TABLA_A_CDC_SRC1_FS_CTL] = 1,
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index fd00253..548b834 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1095,7 +1095,7 @@
pr_err("%s: Failed to configure gpio %d\n", __func__,
PM8921_GPIO_PM_TO_SYS(35));
else
- gpio_direction_output(PM8921_GPIO_PM_TO_SYS(35), 1);
+ gpio_direction_output(PM8921_GPIO_PM_TO_SYS(35), 0);
return 0;
}
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index b287c70..ecfef5b 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -137,9 +137,10 @@
session_id = common.voice[VOC_PATH_PASSIVE].session_id;
else
session_id = common.voice[VOC_PATH_FULL].session_id;
- }
- pr_debug("%s: %s has session id 0x%x\n", __func__, name, session_id);
+ pr_debug("%s: %s has session id 0x%x\n", __func__, name,
+ session_id);
+ }
return session_id;
}