Merge "msm: clock: Remove the clk_set_min_rate() API and set_min_rate ops" into msm-3.0
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3eeac92..2097e0a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1634,6 +1634,12 @@
def_bool n
depends on SPARSEMEM
+config ARCH_ENABLE_MEMORY_HOTPLUG
+ def_bool n
+
+config ARCH_ENABLE_MEMORY_HOTREMOVE
+ def_bool n
+
config FORCE_MAX_ZONEORDER
int "Maximum zone order" if ARCH_SHMOBILE
range 11 64 if ARCH_SHMOBILE
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index 69de152..6561c71 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -15,6 +15,11 @@
<0xF9002000 0x1000>;
};
+ timer {
+ compatible = "qcom,msm-qtimer";
+ interrupts = <18>;
+ };
+
serial@F991F000 {
compatible = "qcom,msm-lsuart-v14";
reg = <0xF991F000 0x1000>;
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 7fcf9dc..fea7044 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/smp.h>
+#include <linux/cpu_pm.h>
#include <linux/cpumask.h>
#include <linux/io.h>
#include <linux/syscore_ops.h>
@@ -282,7 +283,7 @@
return -EINVAL;
mask = 0xff << shift;
- bit = 1 << (cpu + shift);
+ bit = 1 << (cpu_logical_map(cpu) + shift);
raw_spin_lock(&irq_controller_lock);
val = readl_relaxed(reg) & ~mask;
@@ -379,9 +380,15 @@
unsigned int irq_start)
{
unsigned int gic_irqs, irq_limit, i;
+ u32 cpumask;
void __iomem *base = gic->dist_base;
- u32 cpumask = 1 << smp_processor_id();
+ u32 cpu = 0;
+#ifdef CONFIG_SMP
+ cpu = cpu_logical_map(smp_processor_id());
+#endif
+
+ cpumask = 1 << cpu;
cpumask |= cpumask << 8;
cpumask |= cpumask << 16;
@@ -396,6 +403,8 @@
if (gic_irqs > 1020)
gic_irqs = 1020;
+ gic->gic_irqs = gic_irqs;
+
/*
* Set all global interrupts to be level triggered, active low.
*/
@@ -467,6 +476,189 @@
mb();
}
+#ifdef CONFIG_CPU_PM
+/*
+ * Saves the GIC distributor registers during suspend or idle. Must be called
+ * with interrupts disabled but before powering down the GIC. After calling
+ * this function, no interrupts will be delivered by the GIC, and another
+ * platform-specific wakeup source must be enabled.
+ */
+static void gic_dist_save(unsigned int gic_nr)
+{
+ unsigned int gic_irqs;
+ void __iomem *dist_base;
+ int i;
+
+ if (gic_nr >= MAX_GIC_NR)
+ BUG();
+
+ gic_irqs = gic_data[gic_nr].gic_irqs;
+ dist_base = gic_data[gic_nr].dist_base;
+
+ if (!dist_base)
+ return;
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+ gic_data[gic_nr].saved_spi_conf[i] =
+ readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+ gic_data[gic_nr].saved_spi_target[i] =
+ readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+ gic_data[gic_nr].saved_spi_enable[i] =
+ readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+}
+
+/*
+ * Restores the GIC distributor registers during resume or when coming out of
+ * idle. Must be called before enabling interrupts. If a level interrupt
+ * that occured while the GIC was suspended is still present, it will be
+ * handled normally, but any edge interrupts that occured will not be seen by
+ * the GIC and need to be handled by the platform-specific wakeup source.
+ */
+static void gic_dist_restore(unsigned int gic_nr)
+{
+ unsigned int gic_irqs;
+ unsigned int i;
+ void __iomem *dist_base;
+
+ if (gic_nr >= MAX_GIC_NR)
+ BUG();
+
+ gic_irqs = gic_data[gic_nr].gic_irqs;
+ dist_base = gic_data[gic_nr].dist_base;
+
+ if (!dist_base)
+ return;
+
+ writel_relaxed(0, dist_base + GIC_DIST_CTRL);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+ writel_relaxed(gic_data[gic_nr].saved_spi_conf[i],
+ dist_base + GIC_DIST_CONFIG + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+ writel_relaxed(0xa0a0a0a0,
+ dist_base + GIC_DIST_PRI + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+ writel_relaxed(gic_data[gic_nr].saved_spi_target[i],
+ dist_base + GIC_DIST_TARGET + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+ writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
+ dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+ writel_relaxed(1, dist_base + GIC_DIST_CTRL);
+}
+
+static void gic_cpu_save(unsigned int gic_nr)
+{
+ int i;
+ u32 *ptr;
+ void __iomem *dist_base;
+ void __iomem *cpu_base;
+
+ if (gic_nr >= MAX_GIC_NR)
+ BUG();
+
+ dist_base = gic_data[gic_nr].dist_base;
+ cpu_base = gic_data[gic_nr].cpu_base;
+
+ if (!dist_base || !cpu_base)
+ return;
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
+ for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
+ ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
+ for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
+ ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
+
+}
+
+static void gic_cpu_restore(unsigned int gic_nr)
+{
+ int i;
+ u32 *ptr;
+ void __iomem *dist_base;
+ void __iomem *cpu_base;
+
+ if (gic_nr >= MAX_GIC_NR)
+ BUG();
+
+ dist_base = gic_data[gic_nr].dist_base;
+ cpu_base = gic_data[gic_nr].cpu_base;
+
+ if (!dist_base || !cpu_base)
+ return;
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
+ for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
+ writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
+ for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
+ writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
+ writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
+
+ writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
+ writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
+}
+
+static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
+{
+ int i;
+
+ for (i = 0; i < MAX_GIC_NR; i++) {
+ switch (cmd) {
+ case CPU_PM_ENTER:
+ gic_cpu_save(i);
+ break;
+ case CPU_PM_ENTER_FAILED:
+ case CPU_PM_EXIT:
+ gic_cpu_restore(i);
+ break;
+ case CPU_CLUSTER_PM_ENTER:
+ gic_dist_save(i);
+ break;
+ case CPU_CLUSTER_PM_ENTER_FAILED:
+ case CPU_CLUSTER_PM_EXIT:
+ gic_dist_restore(i);
+ break;
+ }
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block gic_notifier_block = {
+ .notifier_call = gic_notifier,
+};
+
+static void __init gic_pm_init(struct gic_chip_data *gic)
+{
+ gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
+ sizeof(u32));
+ BUG_ON(!gic->saved_ppi_enable);
+
+ gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
+ sizeof(u32));
+ BUG_ON(!gic->saved_ppi_conf);
+
+ cpu_pm_register_notifier(&gic_notifier_block);
+}
+#else
+static void __init gic_pm_init(struct gic_chip_data *gic)
+{
+}
+#endif
+
void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
void __iomem *dist_base, void __iomem *cpu_base)
{
@@ -482,8 +674,10 @@
if (gic_nr == 0)
gic_cpu_base_addr = cpu_base;
+ gic_chip.flags |= gic_arch_extn.flags;
gic_dist_init(gic, irq_start);
gic_cpu_init(gic);
+ gic_pm_init(gic);
}
void __cpuinit gic_secondary_init(unsigned int gic_nr)
@@ -506,7 +700,12 @@
#ifdef CONFIG_SMP
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
- unsigned long map = *cpus_addr(*mask);
+ int cpu;
+ unsigned long map = 0;
+
+ /* Convert our logical CPU mask into a physical one. */
+ for_each_cpu(cpu, mask)
+ map |= 1 << cpu_logical_map(cpu);
/*
* Ensure that stores to Normal memory are visible to the
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 9c8c978..4d4c27f 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -44,6 +44,7 @@
CONFIG_HIGH_RES_TIMERS=y
CONFIG_SMP=y
# CONFIG_SMP_ON_UP is not set
+CONFIG_ARM_ARCH_TIMER=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
diff --git a/arch/arm/configs/msm7627_defconfig b/arch/arm/configs/msm7627_defconfig
index 9ae4488..d1d0e66 100644
--- a/arch/arm/configs/msm7627_defconfig
+++ b/arch/arm/configs/msm7627_defconfig
@@ -292,16 +292,13 @@
CONFIG_LOCKUP_DETECTOR=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_TIMER_STATS=y
-CONFIG_SLUB_DEBUG_ON=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_INFO=y
-CONFIG_LATENCYTOP=y
CONFIG_DEBUG_LIST=y
+CONFIG_LATENCYTOP=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index eb4ab41..342aad6 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -104,6 +104,7 @@
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -119,10 +120,11 @@
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -140,9 +142,11 @@
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
CONFIG_BT=y
CONFIG_BT_L2CAP=y
CONFIG_BT_SCO=y
@@ -160,6 +164,8 @@
CONFIG_CFG80211=y
# CONFIG_CFG80211_WEXT is not set
CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_CMDLINE_PARTS=y
@@ -230,8 +236,6 @@
CONFIG_MSM_CAMERA_FLASH_SC628A=y
CONFIG_IMX072=y
CONFIG_RADIO_TAVARUA=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MSM_KGSL=y
CONFIG_FB=y
CONFIG_FB_MSM=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 4836af0..c524759 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -102,6 +102,7 @@
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -117,10 +118,11 @@
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -138,9 +140,11 @@
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
CONFIG_BT=y
CONFIG_BT_L2CAP=y
CONFIG_BT_SCO=y
@@ -158,6 +162,8 @@
CONFIG_CFG80211=y
# CONFIG_CFG80211_WEXT is not set
CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_CMDLINE_PARTS=y
@@ -228,8 +234,6 @@
CONFIG_MSM_CAMERA_FLASH_SC628A=y
CONFIG_IMX072=y
CONFIG_RADIO_TAVARUA=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MSM_KGSL=y
CONFIG_FB=y
CONFIG_FB_MSM=y
@@ -306,20 +310,17 @@
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOCKUP_DETECTOR=y
CONFIG_DEBUG_SHIRQ=y
+CONFIG_LOCKUP_DETECTOR=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_TIMER_STATS=y
-CONFIG_SLUB_DEBUG_ON=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_INFO=y
-CONFIG_LATENCYTOP=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_DEBUG_LIST=y
+CONFIG_LATENCYTOP=y
CONFIG_DEBUG_PAGEALLOC=y
# CONFIG_FTRACE is not set
CONFIG_DYNAMIC_DEBUG=y
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index 64c2c0d..e5fec35 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -99,6 +99,7 @@
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -115,10 +116,11 @@
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -176,6 +178,8 @@
# CONFIG_CFG80211_WEXT is not set
# CONFIG_WIRELESS_EXT_SYSFS is not set
CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_CMDLINE_PARTS=y
@@ -262,8 +266,6 @@
CONFIG_MT9E013=y
CONFIG_MSM_GEMINI=y
CONFIG_RADIO_TAVARUA=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MSM_KGSL=y
CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_FB=y
diff --git a/arch/arm/configs/msm7630_defconfig b/arch/arm/configs/msm7630_defconfig
index 5b4380e..6e3290b 100644
--- a/arch/arm/configs/msm7630_defconfig
+++ b/arch/arm/configs/msm7630_defconfig
@@ -98,6 +98,7 @@
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -114,10 +115,11 @@
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -175,6 +177,8 @@
# CONFIG_CFG80211_WEXT is not set
# CONFIG_WIRELESS_EXT_SYSFS is not set
CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_CMDLINE_PARTS=y
@@ -253,8 +257,6 @@
# CONFIG_MFD_PM8XXX_DEBUG is not set
# CONFIG_MFD_PM8XXX_PWM is not set
# CONFIG_MFD_PM8XXX_MISC is not set
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MSM_KGSL=y
CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_FB=y
@@ -353,10 +355,7 @@
CONFIG_DETECT_HUNG_TASK=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
-CONFIG_SLUB_DEBUG_ON=y
# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_DEBUG_STACK_USAGE=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 5d460b9..01150aa 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -133,6 +133,7 @@
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -150,10 +151,11 @@
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -216,6 +218,8 @@
# CONFIG_CFG80211_WEXT is not set
# CONFIG_WIRELESS_EXT_SYSFS is not set
CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_MISC_DEVICES=y
@@ -320,8 +324,6 @@
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
CONFIG_ION_MSM=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MSM_KGSL=y
CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -331,7 +333,6 @@
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
-CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 4581141..7b2fede 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -123,6 +123,7 @@
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -140,10 +141,11 @@
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -206,10 +208,11 @@
# CONFIG_CFG80211_WEXT is not set
# CONFIG_WIRELESS_EXT_SYSFS is not set
CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_MISC_DEVICES=y
-CONFIG_KERNEL_DEBUGGER_CORE=y
CONFIG_UID_STAT=y
CONFIG_TSIF=m
CONFIG_TSIF_CHRDEV=m
@@ -308,8 +311,6 @@
CONFIG_MT9E013=y
CONFIG_MSM_GEMINI=y
CONFIG_RADIO_TAVARUA=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MSM_KGSL=y
CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -319,7 +320,6 @@
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
-CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
@@ -417,16 +417,14 @@
CONFIG_TIMER_STATS=y
CONFIG_SLUB_DEBUG_ON=y
# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DEBUG_SG=y
CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SG=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 56e0ecd..83d012c 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -26,6 +26,7 @@
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
@@ -50,23 +51,22 @@
CONFIG_MACH_APQ8064_RUMI3=y
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_KERNEL_PMEM_EBI_REGION=y
-# CONFIG_MSM_JTAG_V7 is not set
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
CONFIG_MSM_SMD_PKG4=y
-CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
CONFIG_MSM_BAM_DMUX=y
CONFIG_MSM_DSPS=y
CONFIG_MSM_IPC_ROUTER=y
+CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
# CONFIG_MSM_HW3D is not set
CONFIG_MSM_PIL_QDSP6V4=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_MODEM_8960=y
CONFIG_MSM_LPASS_8960=y
CONFIG_MSM_WCNSS_SSR_8960=y
-CONFIG_MSM_RPM_LOG=y
CONFIG_MSM_TZ_LOG=y
+CONFIG_MSM_RPM_LOG=y
CONFIG_MSM_RPM_STATS_LOG=y
CONFIG_MSM_BUS_SCALING=y
CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED=y
@@ -83,6 +83,7 @@
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
CONFIG_VMALLOC_RESERVE=0x19000000
+CONFIG_CP_ACCESS=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -106,7 +107,6 @@
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
@@ -135,6 +135,7 @@
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -151,10 +152,11 @@
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -201,11 +203,13 @@
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=y
CONFIG_BT_HCISMD=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_WEXT is not set
CONFIG_RFKILL=y
-CONFIG_RFKILL_PM=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
-CONFIG_MISC_DEVICES=y
CONFIG_HAPTIC_ISA1200=y
CONFIG_PMIC8XXX_VIBRATOR=y
CONFIG_TZCOM=y
@@ -231,8 +235,7 @@
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
CONFIG_WCNSS_CORE=m
-CONFIG_CFG80211=y
-CONFIG_CFG80211_WEXT=n
+CONFIG_USB_USBNET=y
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_MODE_SLIP6=y
@@ -295,8 +298,6 @@
CONFIG_RADIO_IRIS_TRANSPORT=m
CONFIG_ION=y
CONFIG_ION_MSM=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
CONFIG_MSM_KGSL=y
CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
CONFIG_FB=y
@@ -306,7 +307,6 @@
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
-CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
@@ -365,7 +365,6 @@
CONFIG_MMC_MSM_SDC3_WP_SUPPORT=y
CONFIG_MMC_MSM_SPS_SUPPORT=y
CONFIG_LEDS_PM8XXX=y
-# CONFIG_LEDS_MSM_PMIC is not set
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_SWITCH=y
@@ -402,7 +401,6 @@
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_SCHED_DEBUG is not set
@@ -416,6 +414,7 @@
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_CRYPTO_SHA256=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index e1b45e1..003f9c1 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -48,6 +48,8 @@
CONFIG_MSM_MODEM_8960=y
CONFIG_MSM_LPASS_8960=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=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_JTAG_V7 is not set
@@ -92,6 +94,15 @@
CONFIG_BLK_DEV_RAM=y
CONFIG_MISC_DEVICES=y
# CONFIG_ANDROID_PMEM is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_NETDEVICES=y
CONFIG_HOSTAP=y
# CONFIG_MSM_RMNET is not set
@@ -119,8 +130,6 @@
CONFIG_I2C_CHARDEV=y
# CONFIG_I2C_MSM is not set
CONFIG_I2C_QUP=y
-CONFIG_MSM_BUS_SCALING=y
-CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED=y
CONFIG_SPI=y
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=m
@@ -135,7 +144,6 @@
# CONFIG_HID_SUPPORT is not set
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_SUSPEND=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_EHSET=y
CONFIG_USB_EHCI_MSM=y
@@ -158,15 +166,6 @@
CONFIG_USB_G_ANDROID=y
CONFIG_RMNET_SMD_CTL_CHANNEL="DATA36_CNTL"
CONFIG_RMNET_SMD_DATA_CHANNEL="DATA36"
-CONFIG_SCSI=y
-CONFIG_SCSI_TGT=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
CONFIG_MMC_UNSAFE_RESUME=y
@@ -217,8 +216,6 @@
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_DEFLATE=y
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index e90400b..9491ab3 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -53,6 +53,14 @@
unsigned int wakeup_irqs[32];
unsigned int enabled_irqs[32];
#endif
+#ifdef CONFIG_CPU_PM
+ u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
+ u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
+ u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
+ u32 __percpu *saved_ppi_enable;
+ u32 __percpu *saved_ppi_conf;
+#endif
+ unsigned int gic_irqs;
};
#endif
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index a6dadf0..8145184 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -71,6 +71,12 @@
extern void platform_smp_prepare_cpus(unsigned int);
/*
+ * Logical CPU mapping.
+ */
+extern int __cpu_logical_map[NR_CPUS];
+#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
+
+/*
* Initial data for bringing up a secondary CPU.
*/
struct secondary_data {
diff --git a/arch/arm/kernel/perf_event_msm_krait_l2.c b/arch/arm/kernel/perf_event_msm_krait_l2.c
index 0512e64..c8b48a8 100644
--- a/arch/arm/kernel/perf_event_msm_krait_l2.c
+++ b/arch/arm/kernel/perf_event_msm_krait_l2.c
@@ -584,10 +584,15 @@
return err;
}
- hwc->config_base = event->attr.config;
hwc->config = 0;
hwc->event_base = 0;
+ /* Check if we came via perf default syms */
+ if (event->attr.config == PERF_COUNT_HW_L2_CYCLES)
+ hwc->config_base = L2CYCLE_CTR_RAW_CODE;
+ else
+ hwc->config_base = event->attr.config;
+
/* Only one CPU can control the cycle counter */
if (hwc->config_base == L2CYCLE_CTR_RAW_CODE) {
/* Check if its already running */
diff --git a/arch/arm/kernel/perf_event_msm_l2.c b/arch/arm/kernel/perf_event_msm_l2.c
index ee6b605..33fb5bf 100644
--- a/arch/arm/kernel/perf_event_msm_l2.c
+++ b/arch/arm/kernel/perf_event_msm_l2.c
@@ -20,6 +20,8 @@
#define BB_L2CYCLE_CTR_EVENT_IDX 4
#define BB_L2CYCLE_CTR_RAW_CODE 0xfe
#define SCORPIONL2_PMNC_E (1 << 0) /* Enable all counters */
+#define SCORPION_L2_EVT_PREFIX 3
+#define SCORPION_MAX_L2_REG 4
/*
* Lock to protect r/m/w sequences to the L2 PMU.
@@ -365,6 +367,26 @@
struct bb_l2_scorp_evt *evtinfo)
{
u32 idx;
+ u8 prefix;
+ u8 reg;
+ u8 code;
+ u8 group;
+
+ prefix = (evt_type & 0xF0000) >> 16;
+ if (prefix == SCORPION_L2_EVT_PREFIX) {
+ reg = (evt_type & 0x0F000) >> 12;
+ code = (evt_type & 0x00FF0) >> 4;
+ group = evt_type & 0x0000F;
+
+ if ((group > 3) || (reg > SCORPION_MAX_L2_REG))
+ return BB_L2_INV_EVTYPE;
+
+ evtinfo->val = 0x80000000 | (code << (group * 8));
+ evtinfo->grp = reg;
+ evtinfo->evt_type_act = group | (reg << 2);
+ return evtinfo->evt_type_act;
+ }
+
if (evt_type < BB_L2_EVT_START_IDX || evt_type >= BB_L2_MAX_EVT)
return BB_L2_INV_EVTYPE;
idx = evt_type - BB_L2_EVT_START_IDX;
@@ -911,10 +933,15 @@
return err;
}
- hwc->config_base = event->attr.config & 0xff;
hwc->config = 0;
hwc->event_base = 0;
+ /* Check if we came via perf default syms */
+ if (event->attr.config == PERF_COUNT_HW_L2_CYCLES)
+ hwc->config_base = BB_L2CYCLE_CTR_RAW_CODE;
+ else
+ hwc->config_base = event->attr.config;
+
/* Only one CPU can control the cycle counter */
if (hwc->config_base == BB_L2CYCLE_CTR_RAW_CODE) {
/* Check if its already running */
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 0045a7f..9fe0964 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -39,6 +39,7 @@
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
#include <asm/localtimer.h>
+#include <asm/smp_plat.h>
/*
* as from 2.5, kernels no longer have an init_tasks structure
@@ -216,7 +217,7 @@
pr_err("CPU%u: cpu didn't die\n", cpu);
return;
}
- printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+ pr_debug("CPU%u: shutdown\n", cpu);
if (!platform_cpu_kill(cpu))
printk("CPU%u: unable to kill\n", cpu);
@@ -261,6 +262,20 @@
}
#endif /* CONFIG_HOTPLUG_CPU */
+int __cpu_logical_map[NR_CPUS];
+
+void __init smp_setup_processor_id(void)
+{
+ int i;
+ u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
+
+ cpu_logical_map(0) = cpu;
+ for (i = 1; i < NR_CPUS; ++i)
+ cpu_logical_map(i) = i == cpu ? 0 : i;
+
+ printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
+}
+
/*
* Called by both boot and secondaries to move global data into
* per-processor storage.
@@ -281,7 +296,7 @@
struct mm_struct *mm = &init_mm;
unsigned int cpu = smp_processor_id();
- printk("CPU%u: Booted secondary processor\n", cpu);
+ pr_debug("CPU%u: Booted secondary processor\n", cpu);
/*
* All kernel threads share the same mm context; grab a
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 9b5c2ae..0078ebc 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -146,7 +146,7 @@
select MIGRATION
select ARCH_MEMORY_PROBE
select ARCH_MEMORY_REMOVE
- select DONT_RESERVE_FROM_MOVABLE_ZONE
+ select FIX_MOVABLE_ZONE
config ARCH_MSM8930
bool "MSM8930"
@@ -177,7 +177,7 @@
select MIGRATION
select ARCH_MEMORY_PROBE
select ARCH_MEMORY_REMOVE
- select DONT_RESERVE_FROM_MOVABLE_ZONE
+ select FIX_MOVABLE_ZONE
select MSM_ULTRASOUND
config ARCH_APQ8064
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index fe270c5..05f4ab4 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,4 +1,7 @@
-obj-y += io.o dma.o memory.o timer.o
+obj-y += io.o dma.o memory.o
+ifndef CONFIG_ARM_ARCH_TIMER
+obj-y += timer.o
+endif
obj-y += clock.o clock-voter.o clock-dummy.o
obj-y += modem_notifier.o subsystem_map.o
obj-$(CONFIG_CPU_FREQ_MSM) += cpufreq.o
@@ -100,7 +103,7 @@
endif
endif
endif
-obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o sdio_tty_ciq.o
+obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o
obj-$(CONFIG_MSM_SMD_TTY) += smd_tty.o
obj-$(CONFIG_MSM_SMD_QMI) += smd_qmi.o
obj-$(CONFIG_MSM_SMD_PKT) += smd_pkt.o
@@ -224,18 +227,22 @@
obj-$(CONFIG_ARCH_MSM8960) += acpuclock-8960.o
obj-$(CONFIG_ARCH_MSM8960) += memory_topology.o
obj-$(CONFIG_ARCH_MSM8960) += saw-regulator.o rpm-regulator.o rpm-regulator-8960.o
-board-msm8960-all-objs += board-msm8960.o board-msm8960-camera.o board-msm8960-display.o board-msm8960-pmic.o board-msm8960-storage.o
-board-msm8930-all-objs += board-msm8930.o board-msm8930-camera.o board-msm8930-display.o board-msm8930-pmic.o board-msm8930-storage.o
-obj-$(CONFIG_MACH_MSM8960_SIM) += board-msm8960-all.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8960_RUMI3) += board-msm8960-all.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8960_CDP) += board-msm8960-all.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8960_MTP) += board-msm8960-all.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8960_FLUID) += board-msm8960-all.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8930_CDP) += board-msm8930-all.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8930_MTP) += board-msm8930-all.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8930_FLUID) += board-msm8930-all.o devices-8960.o board-msm8960-regulator.o
+obj-$(CONFIG_ARCH_MSM8960) += devices-8960.o
+obj-$(CONFIG_ARCH_APQ8064) += devices-8960.o devices-8064.o
+board-8960-all-objs += board-8960.o board-8960-camera.o board-8960-display.o board-8960-pmic.o board-8960-storage.o board-8960-gpiomux.o
+board-8930-all-objs += board-8930.o board-8930-camera.o board-8930-display.o board-8930-pmic.o board-8930-storage.o board-8930-gpiomux.o
+board-8064-all-objs += board-8064.o board-8064-storage.o
+obj-$(CONFIG_MACH_MSM8960_SIM) += board-8960-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8960_RUMI3) += board-8960-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8960_CDP) += board-8960-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8960_MTP) += board-8960-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8960_FLUID) += board-8960-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8930_CDP) += board-8930-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8930_MTP) += board-8930-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8930_FLUID) += board-8930-all.o board-8960-regulator.o
obj-$(CONFIG_ARCH_MSM8960) += bms-batterydata.o
-obj-$(CONFIG_ARCH_APQ8064) += board-apq8064.o devices-8064.o board-apq8064-regulator.o
+obj-$(CONFIG_MACH_APQ8064_SIM) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_APQ8064_RUMI3) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o
obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o
obj-$(CONFIG_ARCH_MSM9615) += rpm-regulator.o rpm-regulator-9615.o
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 659c292..143fb86 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -140,7 +140,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x200,
.aux_clk_sel = MSM_ACC0_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait0", 1150000 },
+ .vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_L24 },
@@ -158,7 +158,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x300,
.aux_clk_sel = MSM_ACC1_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait1", 1150000 },
+ .vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_L24 },
@@ -287,8 +287,8 @@
static uint32_t bus_perf_client;
/* TODO: Update vdd_dig and vdd_mem when voltage data is available. */
-#define L2(x) (&l2_freq_tbl_8960[(x)])
-static struct l2_level l2_freq_tbl_8960[] = {
+#define L2(x) (&l2_freq_tbl_8960_kraitv1[(x)])
+static struct l2_level l2_freq_tbl_8960_kraitv1[] = {
[0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, 1050000, 1050000, 0 },
[1] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
[2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 1 },
@@ -303,7 +303,7 @@
[11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 3 },
};
-static struct acpu_level acpu_freq_tbl_8960[] = {
+static struct acpu_level acpu_freq_tbl_8960_kraitv1[] = {
{ 0, {STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
{ 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
{ 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 950000 },
@@ -319,6 +319,55 @@
{ 0, { 0 } }
};
+#undef L2
+#define L2(x) (&l2_freq_tbl_8960_kraitv2[(x)])
+static struct l2_level l2_freq_tbl_8960_kraitv2[] = {
+ [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, 1050000, 1050000, 0 },
+ [1] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
+ [2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 1 },
+ [3] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 1 },
+ [4] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 1 },
+ [5] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
+ [6] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 2 },
+ [7] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 2 },
+ [8] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 2 },
+ [9] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 3 },
+ [10] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 3 },
+ [11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 3 },
+ [12] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 4 },
+ [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 4 },
+ [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 4 },
+ [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 4 },
+ [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 4 },
+};
+
+static struct acpu_level acpu_freq_tbl_8960_kraitv2[] = {
+ { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 950000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 962500 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 962500 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 987500 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1000000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1087500 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1125000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1137500 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(16), 1300000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1300000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1300000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1300000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1300000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1300000 },
+ { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1300000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1300000 },
+ { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1300000 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1300000 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1300000 },
+ { 0, { 0 } }
+};
+
/* TODO: Update vdd_dig and vdd_mem when voltage data is available. */
#undef L2
#define L2(x) (&l2_freq_tbl_8064[(x)])
@@ -1051,9 +1100,15 @@
/* TODO: Select tables based on PVS data. */
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);
+ if (cpu_is_krait_v1()) {
+ acpu_freq_tbl = acpu_freq_tbl_8960_kraitv1;
+ l2_freq_tbl = l2_freq_tbl_8960_kraitv1;
+ l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8960_kraitv1);
+ } else {
+ acpu_freq_tbl = acpu_freq_tbl_8960_kraitv2;
+ l2_freq_tbl = l2_freq_tbl_8960_kraitv2;
+ l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8960_kraitv2);
+ }
} else if (cpu_is_apq8064()) {
scalable = scalable_8064;
acpu_freq_tbl = acpu_freq_tbl_8064;
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 0041f0d..644a666 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -25,11 +25,13 @@
#include <linux/skbuff.h>
#include <linux/debugfs.h>
#include <linux/clk.h>
+#include <linux/wakelock.h>
#include <mach/sps.h>
#include <mach/bam_dmux.h>
#include <mach/msm_smsm.h>
#include <mach/subsystem_notif.h>
+#include <mach/socinfo.h>
#define BAM_CH_LOCAL_OPEN 0x1
#define BAM_CH_REMOTE_OPEN 0x2
@@ -194,6 +196,8 @@
static DEFINE_RWLOCK(ul_wakeup_lock);
static DECLARE_WORK(kickoff_ul_wakeup, kickoff_ul_wakeup_func);
static int bam_connection_is_active;
+static int wait_for_ack;
+static struct wake_lock bam_wakelock;
/* End A2 power collaspe */
/* subsystem restart */
@@ -228,12 +232,19 @@
return;
info = kmalloc(sizeof(struct rx_pkt_info), GFP_KERNEL);
- if (!info)
- return; /*need better way to handle this */
+ if (!info) {
+ pr_err("%s: unable to alloc rx_pkt_info\n", __func__);
+ return;
+ }
INIT_WORK(&info->work, handle_bam_mux_cmd);
info->skb = __dev_alloc_skb(BUFFER_SIZE, GFP_KERNEL);
+ if (info->skb == NULL) {
+ pr_err("%s: unable to alloc skb\n", __func__);
+ kfree(info);
+ return;
+ }
ptr = skb_put(info->skb, BUFFER_SIZE);
mutex_lock(&bam_rx_pool_mutexlock);
@@ -373,6 +384,7 @@
DMA_TO_DEVICE);
if (!dma_address) {
pr_err("%s: dma_map_single() failed\n", __func__);
+ kfree(pkt);
rc = -ENOMEM;
return rc;
}
@@ -991,6 +1003,8 @@
schedule_delayed_work(&ul_timeout_work,
msecs_to_jiffies(UL_TIMEOUT_DELAY));
} else {
+ wait_for_ack = 1;
+ INIT_COMPLETION(ul_wakeup_ack_completion);
smsm_change_state(SMSM_APPS_STATE, SMSM_A2_POWER_CONTROL, 0);
bam_is_connected = 0;
notify_all(BAM_DMUX_UL_DISCONNECTED, (unsigned long)(NULL));
@@ -999,17 +1013,31 @@
}
static void ul_wakeup(void)
{
+ int ret;
+
mutex_lock(&wakeup_lock);
if (bam_is_connected) { /* bam got connected before lock grabbed */
mutex_unlock(&wakeup_lock);
return;
}
+ /*
+ * must wait for the previous power down request to have been acked
+ * chances are it already came in and this will just fall through
+ * instead of waiting
+ */
+ if (wait_for_ack) {
+ ret = wait_for_completion_interruptible_timeout(
+ &ul_wakeup_ack_completion, HZ);
+ BUG_ON(ret == 0);
+ }
INIT_COMPLETION(ul_wakeup_ack_completion);
smsm_change_state(SMSM_APPS_STATE, 0, SMSM_A2_POWER_CONTROL);
- wait_for_completion_interruptible_timeout(&ul_wakeup_ack_completion,
- HZ);
- wait_for_completion_interruptible_timeout(&bam_connection_completion,
- HZ);
+ ret = wait_for_completion_interruptible_timeout(
+ &ul_wakeup_ack_completion, HZ);
+ BUG_ON(ret == 0);
+ ret = wait_for_completion_interruptible_timeout(
+ &bam_connection_completion, HZ);
+ BUG_ON(ret == 0);
bam_is_connected = 1;
schedule_delayed_work(&ul_timeout_work,
@@ -1070,10 +1098,16 @@
static void vote_dfab(void)
{
+ int rc;
+
+ rc = clk_enable(dfab_clk);
+ if (rc)
+ pr_err("bam_dmux vote for dfab failed rc = %d\n", rc);
}
static void unvote_dfab(void)
{
+ clk_disable(dfab_clk);
}
static int restart_notifier_cb(struct notifier_block *this,
@@ -1151,6 +1185,8 @@
a2_props.options = SPS_BAM_OPT_IRQ_WAKEUP;
a2_props.num_pipes = A2_NUM_PIPES;
a2_props.summing_threshold = A2_SUMMING_THRESHOLD;
+ if (cpu_is_msm9615())
+ a2_props.manage = SPS_BAM_MGR_DEVICE_REMOTE;
/* need to free on tear down */
ret = sps_register_bam_device(&a2_props, &h);
if (ret < 0) {
@@ -1298,14 +1334,19 @@
static void bam_dmux_smsm_cb(void *priv, uint32_t old_state, uint32_t new_state)
{
DBG("%s: smsm activity\n", __func__);
- if (bam_mux_initialized && new_state & SMSM_A2_POWER_CONTROL)
+ if (bam_mux_initialized && new_state & SMSM_A2_POWER_CONTROL) {
+ wake_lock(&bam_wakelock);
reconnect_to_bam();
- else if (bam_mux_initialized && !(new_state & SMSM_A2_POWER_CONTROL))
+ } else if (bam_mux_initialized &&
+ !(new_state & SMSM_A2_POWER_CONTROL)) {
disconnect_to_bam();
- else if (new_state & SMSM_A2_POWER_CONTROL)
+ wake_unlock(&bam_wakelock);
+ } else if (new_state & SMSM_A2_POWER_CONTROL) {
+ wake_lock(&bam_wakelock);
bam_init();
- else
+ } else {
pr_err("%s: unsupported state change\n", __func__);
+ }
}
@@ -1360,6 +1401,7 @@
init_completion(&ul_wakeup_ack_completion);
init_completion(&bam_connection_completion);
INIT_DELAYED_WORK(&ul_timeout_work, ul_timeout);
+ wake_lock_init(&bam_wakelock, WAKE_LOCK_SUSPEND, "bam_dmux_wakelock");
rc = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_A2_POWER_CONTROL,
bam_dmux_smsm_cb, NULL);
diff --git a/arch/arm/mach-msm/board-apq8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
similarity index 99%
rename from arch/arm/mach-msm/board-apq8064-regulator.c
rename to arch/arm/mach-msm/board-8064-regulator.c
index 90a9df1..4873258 100644
--- a/arch/arm/mach-msm/board-apq8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -13,7 +13,7 @@
#include <linux/regulator/pm8921-regulator.h>
-#include "board-apq8064.h"
+#include "board-8064.h"
#define VREG_CONSUMERS(_id) \
static struct regulator_consumer_supply vreg_consumers_##_id[]
diff --git a/arch/arm/mach-msm/board-msm8930-storage.c b/arch/arm/mach-msm/board-8064-storage.c
similarity index 80%
copy from arch/arm/mach-msm/board-msm8930-storage.c
copy to arch/arm/mach-msm/board-8064-storage.c
index 58bd8e5..8a3b958 100644
--- a/arch/arm/mach-msm/board-msm8930-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -22,15 +22,15 @@
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
-#include "board-msm8930.h"
+#include "board-8064.h"
-/* MSM8960 has 5 SDCC controllers */
+
+/* APQ8064 has 4 SDCC controllers */
enum sdcc_controllers {
SDCC1,
SDCC2,
SDCC3,
SDCC4,
- SDCC5,
MAX_SDCC_CONTROLLER
};
@@ -146,18 +146,8 @@
static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
- /*
- * 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}
+ {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_DOWN},
+ {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_DOWN}
};
static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
@@ -206,16 +196,12 @@
},
};
+#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
static unsigned int sdc1_sup_clk_rates[] = {
- 400000, 24000000, 48000000
-};
-
-static unsigned int sdc3_sup_clk_rates[] = {
400000, 24000000, 48000000, 96000000
};
-#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
-static struct mmc_platform_data msm8960_sdc1_data = {
+static struct mmc_platform_data sdc1_data = {
.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
.mmc_bus_width = MMC_CAP_8_BIT_DATA,
@@ -224,45 +210,48 @@
#endif
.sup_clk_table = sdc1_sup_clk_rates,
.sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
- .pclk_src_dfab = 1,
- .nonremovable = 1,
+ .pin_data = &mmc_slot_pin_data[SDCC1],
.vreg_data = &mmc_slot_vreg_data[SDCC1],
- .pin_data = &mmc_slot_pin_data[SDCC1]
};
+static struct mmc_platform_data *apq8064_sdc1_pdata = &sdc1_data;
+#else
+static struct mmc_platform_data *apq8064_sdc1_pdata;
#endif
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
-static struct mmc_platform_data msm8960_sdc3_data = {
+static unsigned int sdc3_sup_clk_rates[] = {
+ 400000, 24000000, 48000000, 96000000
+};
+
+static struct mmc_platform_data sdc3_data = {
.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
.mmc_bus_width = MMC_CAP_4_BIT_DATA,
.sup_clk_table = sdc3_sup_clk_rates,
.sup_clk_cnt = ARRAY_SIZE(sdc3_sup_clk_rates),
- .pclk_src_dfab = 1,
-#ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
- .wpswitch_gpio = PM8921_GPIO_PM_TO_SYS(16),
-#endif
- .vreg_data = &mmc_slot_vreg_data[SDCC3],
.pin_data = &mmc_slot_pin_data[SDCC3],
-#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
- .status_gpio = PM8921_GPIO_PM_TO_SYS(26),
- .status_irq = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
- .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-#endif
- .xpc_cap = 1,
- .uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
- MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
- MMC_CAP_MAX_CURRENT_600)
+ .vreg_data = &mmc_slot_vreg_data[SDCC3],
};
+static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
+#else
+static struct mmc_platform_data *apq8064_sdc3_pdata;
#endif
-void __init msm8930_init_mmc(void)
+void __init apq8064_init_mmc(void)
{
-#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
- /* SDC1 : eMMC card connected */
- msm_add_sdcc(1, &msm8960_sdc1_data);
-#endif
-#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
- /* SDC3: External card slot */
- msm_add_sdcc(3, &msm8960_sdc3_data);
-#endif
+ if ((machine_is_apq8064_rumi3()) || machine_is_apq8064_sim()) {
+ if (apq8064_sdc1_pdata) {
+ if (machine_is_apq8064_sim())
+ apq8064_sdc1_pdata->disable_bam = true;
+ apq8064_sdc1_pdata->disable_runtime_pm = true;
+ apq8064_sdc1_pdata->disable_cmd23 = true;
+ }
+ if (apq8064_sdc3_pdata) {
+ if (machine_is_apq8064_sim())
+ apq8064_sdc3_pdata->disable_bam = true;
+ apq8064_sdc3_pdata->disable_runtime_pm = true;
+ apq8064_sdc3_pdata->disable_cmd23 = true;
+ }
+ }
+ apq8064_add_sdcc(1, apq8064_sdc1_pdata);
+ apq8064_add_sdcc(3, apq8064_sdc3_pdata);
}
diff --git a/arch/arm/mach-msm/board-apq8064.c b/arch/arm/mach-msm/board-8064.c
similarity index 76%
rename from arch/arm/mach-msm/board-apq8064.c
rename to arch/arm/mach-msm/board-8064.c
index 680060d..6e2c044 100644
--- a/arch/arm/mach-msm/board-apq8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -44,7 +44,7 @@
#include <mach/dma.h>
#include "msm_watchdog.h"
-#include "board-apq8064.h"
+#include "board-8064.h"
#define MSM_PMEM_KERNEL_EBI1_SIZE 0x600000
#define MSM_PMEM_ADSP_SIZE 0x3800000
@@ -219,15 +219,6 @@
.pclk_src_name = "dfab_usb_hs_clk",
};
-/* APQ8064 has 4 SDCC controllers */
-enum sdcc_controllers {
- SDCC1,
- SDCC2,
- SDCC3,
- SDCC4,
- MAX_SDCC_CONTROLLER
-};
-
#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_IRQS)
/* Micbias setting is based on 8660 CDP/MTP/FLUID requirement
@@ -268,228 +259,6 @@
},
};
-/* All SDCC controllers require VDD/VCC voltage */
-static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
- /* SDCC1 : eMMC card connected */
- [SDCC1] = {
- .name = "sdc_vdd",
- .high_vol_level = 2950000,
- .low_vol_level = 2950000,
- .always_on = 1,
- .lpm_sup = 1,
- .lpm_uA = 9000,
- .hpm_uA = 200000, /* 200mA */
- },
- /* SDCC3 : External card slot connected */
- [SDCC3] = {
- .name = "sdc_vdd",
- .high_vol_level = 2950000,
- .low_vol_level = 2950000,
- .hpm_uA = 600000, /* 600mA */
- }
-};
-
-/* Only slots having eMMC card will require VCCQ voltage */
-static struct msm_mmc_reg_data mmc_vccq_reg_data[1] = {
- /* SDCC1 : eMMC card connected */
- [SDCC1] = {
- .name = "sdc_vccq",
- .always_on = 1,
- .high_vol_level = 1800000,
- .low_vol_level = 1800000,
- .hpm_uA = 200000, /* 200mA */
- }
-};
-
-/* All SDCC controllers may require voting for VDD PAD voltage */
-static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
- /* SDCC3 : External card slot connected */
- [SDCC3] = {
- .name = "sdc_vddp",
- .high_vol_level = 2950000,
- .low_vol_level = 1850000,
- .always_on = 1,
- .lpm_sup = 1,
- /* Max. Active current required is 16 mA */
- .hpm_uA = 16000,
- /*
- * Sleep current required is ~300 uA. But min. vote can be
- * in terms of mA (min. 1 mA). So let's vote for 2 mA
- * during sleep.
- */
- .lpm_uA = 2000,
- }
-};
-
-static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
- /* SDCC1 : eMMC card connected */
- [SDCC1] = {
- .vdd_data = &mmc_vdd_reg_data[SDCC1],
- .vccq_data = &mmc_vccq_reg_data[SDCC1],
- },
- /* SDCC3 : External card slot connected */
- [SDCC3] = {
- .vdd_data = &mmc_vdd_reg_data[SDCC3],
- .vddp_data = &mmc_vddp_reg_data[SDCC3],
- }
-};
-
-/* SDC1 pad data */
-static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
- {TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
- {TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
- {TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
-};
-
-static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
- {TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
- {TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
- {TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
-};
-
-static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
- {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
- {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
- {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
-};
-
-static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
- {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
- {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_DOWN},
- {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_DOWN}
-};
-
-/* SDC3 pad data */
-static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
- {TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
- {TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
- {TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
-};
-
-static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
- {TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
- {TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
- {TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
-};
-
-static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
- {TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
- {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
- {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
-};
-
-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}
-};
-
-static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
- [SDCC1] = {
- .on = sdc1_pad_pull_on_cfg,
- .off = sdc1_pad_pull_off_cfg,
- .size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
- },
- [SDCC3] = {
- .on = sdc3_pad_pull_on_cfg,
- .off = sdc3_pad_pull_off_cfg,
- .size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
- },
-};
-
-static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
- [SDCC1] = {
- .on = sdc1_pad_drv_on_cfg,
- .off = sdc1_pad_drv_off_cfg,
- .size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
- },
- [SDCC3] = {
- .on = sdc3_pad_drv_on_cfg,
- .off = sdc3_pad_drv_off_cfg,
- .size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
- },
-};
-
-static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
- [SDCC1] = {
- .pull = &mmc_pad_pull_data[SDCC1],
- .drv = &mmc_pad_drv_data[SDCC1]
- },
- [SDCC3] = {
- .pull = &mmc_pad_pull_data[SDCC3],
- .drv = &mmc_pad_drv_data[SDCC3]
- },
-};
-
-static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
- [SDCC1] = {
- .pad_data = &mmc_pad_data[SDCC1],
- },
- [SDCC3] = {
- .pad_data = &mmc_pad_data[SDCC3],
- },
-};
-
-#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
-static unsigned int sdc1_sup_clk_rates[] = {
- 400000, 24000000, 48000000, 96000000
-};
-
-static struct mmc_platform_data sdc1_data = {
- .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
-#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
- .mmc_bus_width = MMC_CAP_8_BIT_DATA,
-#else
- .mmc_bus_width = MMC_CAP_4_BIT_DATA,
-#endif
- .sup_clk_table = sdc1_sup_clk_rates,
- .sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
- .pin_data = &mmc_slot_pin_data[SDCC1],
- .vreg_data = &mmc_slot_vreg_data[SDCC1],
-};
-static struct mmc_platform_data *apq8064_sdc1_pdata = &sdc1_data;
-#else
-static struct mmc_platform_data *apq8064_sdc1_pdata;
-#endif
-
-#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
-static unsigned int sdc3_sup_clk_rates[] = {
- 400000, 24000000, 48000000, 96000000
-};
-
-static struct mmc_platform_data sdc3_data = {
- .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
- .mmc_bus_width = MMC_CAP_4_BIT_DATA,
- .sup_clk_table = sdc3_sup_clk_rates,
- .sup_clk_cnt = ARRAY_SIZE(sdc3_sup_clk_rates),
- .pin_data = &mmc_slot_pin_data[SDCC3],
- .vreg_data = &mmc_slot_vreg_data[SDCC3],
-};
-static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
-#else
-static struct mmc_platform_data *apq8064_sdc3_pdata;
-#endif
-
-static void __init apq8064_init_mmc(void)
-{
- if ((machine_is_apq8064_rumi3()) || machine_is_apq8064_sim()) {
- if (apq8064_sdc1_pdata) {
- if (machine_is_apq8064_sim())
- apq8064_sdc1_pdata->disable_bam = true;
- apq8064_sdc1_pdata->disable_runtime_pm = true;
- apq8064_sdc1_pdata->disable_cmd23 = true;
- }
- if (apq8064_sdc3_pdata) {
- if (machine_is_apq8064_sim())
- apq8064_sdc3_pdata->disable_bam = true;
- apq8064_sdc3_pdata->disable_runtime_pm = true;
- apq8064_sdc3_pdata->disable_cmd23 = true;
- }
- }
- apq8064_add_sdcc(1, apq8064_sdc1_pdata);
- apq8064_add_sdcc(3, apq8064_sdc3_pdata);
-}
-
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
diff --git a/arch/arm/mach-msm/board-apq8064.h b/arch/arm/mach-msm/board-8064.h
similarity index 98%
rename from arch/arm/mach-msm/board-apq8064.h
rename to arch/arm/mach-msm/board-8064.h
index 0928a58..d9da00a 100644
--- a/arch/arm/mach-msm/board-apq8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -41,4 +41,5 @@
int __init apq8064_add_sdcc(unsigned int controller,
struct mmc_platform_data *plat);
+void apq8064_init_mmc(void);
#endif
diff --git a/arch/arm/mach-msm/board-msm8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
similarity index 99%
rename from arch/arm/mach-msm/board-msm8930-camera.c
rename to arch/arm/mach-msm/board-8930-camera.c
index b15f2f1..9161fbf 100644
--- a/arch/arm/mach-msm/board-msm8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -19,7 +19,7 @@
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
-#include "board-msm8930.h"
+#include "board-8930.h"
#if (defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)) && \
defined(CONFIG_I2C)
diff --git a/arch/arm/mach-msm/board-msm8930-display.c b/arch/arm/mach-msm/board-8930-display.c
similarity index 90%
rename from arch/arm/mach-msm/board-msm8930-display.c
rename to arch/arm/mach-msm/board-8930-display.c
index 973f391..ca21fac 100644
--- a/arch/arm/mach-msm/board-msm8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -20,8 +20,9 @@
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/gpiomux.h>
+#include <mach/socinfo.h>
#include "devices.h"
-#include "board-msm8930.h"
+#include "board-8930.h"
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 3) /* 4 bpp x 3 pages */
@@ -577,78 +578,7 @@
};
#endif
-static struct gpiomux_setting mdp_vsync_suspend_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting mdp_vsync_active_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config msm8960_mdp_vsync_configs[] __initdata = {
- {
- .gpio = MDP_VSYNC_GPIO,
- .settings = {
- [GPIOMUX_ACTIVE] = &mdp_vsync_active_cfg,
- [GPIOMUX_SUSPENDED] = &mdp_vsync_suspend_cfg,
- },
- }
-};
-
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-static struct gpiomux_setting hdmi_suspend_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting hdmi_active_1_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting hdmi_active_2_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config msm8960_hdmi_configs[] __initdata = {
- {
- .gpio = 99,
- .settings = {
- [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
- [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
- },
- },
- {
- .gpio = 100,
- .settings = {
- [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
- [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
- },
- },
- {
- .gpio = 101,
- .settings = {
- [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
- [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
- },
- },
- {
- .gpio = 102,
- .settings = {
- [GPIOMUX_ACTIVE] = &hdmi_active_2_cfg,
- [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
- },
- },
-};
-
static int hdmi_enable_5v(int on)
{
/* TBD: PM8921 regulator instead of 8901 */
@@ -826,14 +756,6 @@
void __init msm8930_init_fb(void)
{
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
- msm_gpiomux_install(msm8960_hdmi_configs,
- ARRAY_SIZE(msm8960_hdmi_configs));
-#endif
-
- msm_gpiomux_install(msm8960_mdp_vsync_configs,
- ARRAY_SIZE(msm8960_mdp_vsync_configs));
-
platform_device_register(&msm_fb_device);
#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
@@ -844,7 +766,8 @@
platform_device_register(&mipi_dsi_novatek_panel_device);
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
- platform_device_register(&hdmi_msm_device);
+ if (!cpu_is_msm8627())
+ platform_device_register(&hdmi_msm_device);
#endif
platform_device_register(&mipi_dsi_toshiba_panel_device);
diff --git a/arch/arm/mach-msm/board-8930-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
new file mode 100644
index 0000000..e872d64
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -0,0 +1,662 @@
+/* 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.
+ *
+ */
+
+#include <asm/mach-types.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/socinfo.h>
+#include "devices.h"
+#include "board-8930.h"
+
+/* The SPI configurations apply to GSBI 1*/
+static struct gpiomux_setting spi_active = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_12MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting spi_suspended_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting spi_active_config2 = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting spi_suspended_config2 = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting gsbi3_suspended_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_KEEPER,
+};
+
+static struct gpiomux_setting gsbi3_active_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi5 = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi10 = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi12 = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting cdc_mclk = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting audio_auxpcm[] = {
+ /* Suspended state */
+ {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+ /* Active state */
+ {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+};
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct gpiomux_setting gpio_eth_config = {
+ .pull = GPIOMUX_PULL_NONE,
+ .drv = GPIOMUX_DRV_8MA,
+ .func = GPIOMUX_FUNC_GPIO,
+};
+#endif
+
+static struct gpiomux_setting slimbus = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_KEEPER,
+};
+
+static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting wcnss_5wire_active_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_resout_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_resout_act_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_sleep_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_sleep_act_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_int_act_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_int_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct gpiomux_setting hsic_act_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_12MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting hsic_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+ .dir = GPIOMUX_OUT_LOW,
+};
+
+static struct gpiomux_setting hsic_hub_act_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+#endif
+
+static struct gpiomux_setting hap_lvl_shft_suspended_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hap_lvl_shft_active_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting ap2mdm_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdm2ap_status_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdm2ap_errfatal_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_16MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting ap2mdm_kpdpwr_n_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdp_vsync_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdp_vsync_active_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct gpiomux_setting hdmi_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hdmi_active_1_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting hdmi_active_2_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+#endif
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct msm_gpiomux_config msm8960_ethernet_configs[] = {
+ {
+ .gpio = 90,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_eth_config,
+ }
+ },
+ {
+ .gpio = 89,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_eth_config,
+ }
+ },
+};
+#endif
+
+static struct msm_gpiomux_config msm8960_gsbi_configs[] __initdata = {
+ {
+ .gpio = 6, /* GSBI1 QUP SPI_DATA_MOSI */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config,
+ [GPIOMUX_ACTIVE] = &spi_active,
+ },
+ },
+ {
+ .gpio = 7, /* GSBI1 QUP SPI_DATA_MISO */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config,
+ [GPIOMUX_ACTIVE] = &spi_active,
+ },
+ },
+ {
+ .gpio = 8, /* GSBI1 QUP SPI_CS_N */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config,
+ [GPIOMUX_ACTIVE] = &spi_active,
+ },
+ },
+ {
+ .gpio = 9, /* GSBI1 QUP SPI_CLK */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config,
+ [GPIOMUX_ACTIVE] = &spi_active,
+ },
+ },
+ {
+ .gpio = 14, /* GSBI1 SPI_CS_1 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config2,
+ [GPIOMUX_ACTIVE] = &spi_active_config2,
+ },
+ },
+ {
+ .gpio = 16, /* GSBI3 I2C QUP SDA */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+ [GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+ },
+ },
+ {
+ .gpio = 17, /* GSBI3 I2C QUP SCL */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+ [GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+ },
+ },
+ {
+ .gpio = 22, /* GSBI5 UART2 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi5,
+ },
+ },
+ {
+ .gpio = 23, /* GSBI5 UART2 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi5,
+ },
+ },
+ {
+ .gpio = 24, /* GSBI5 UART2 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi5,
+ },
+ },
+ {
+ .gpio = 25, /* GSBI5 UART2 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi5,
+ },
+ },
+ {
+ .gpio = 44, /* GSBI12 I2C QUP SDA */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi12,
+ },
+ },
+ {
+ .gpio = 45, /* GSBI12 I2C QUP SCL */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi12,
+ },
+ },
+ {
+ .gpio = 73, /* GSBI10 I2C QUP SDA */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi10,
+ },
+ },
+ {
+ .gpio = 74, /* GSBI10 I2C QUP SCL */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi10,
+ },
+ },
+};
+
+static struct msm_gpiomux_config msm8960_slimbus_config[] __initdata = {
+ {
+ .gpio = 60, /* slimbus data */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &slimbus,
+ },
+ },
+ {
+ .gpio = 61, /* slimbus clk */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &slimbus,
+ },
+ },
+};
+
+static struct msm_gpiomux_config msm8960_audio_codec_configs[] __initdata = {
+ {
+ .gpio = 59,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &cdc_mclk,
+ },
+ },
+};
+
+static struct msm_gpiomux_config msm8960_audio_auxpcm_configs[] __initdata = {
+ {
+ .gpio = 63,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 64,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 65,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 66,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+};
+
+static struct msm_gpiomux_config wcnss_5wire_interface[] = {
+ {
+ .gpio = 84,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 85,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 86,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 87,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 88,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+};
+
+static struct msm_gpiomux_config msm8960_cyts_configs[] __initdata = {
+ { /* TS INTERRUPT */
+ .gpio = 11,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cyts_int_act_cfg,
+ [GPIOMUX_SUSPENDED] = &cyts_int_sus_cfg,
+ },
+ },
+ { /* TS SLEEP */
+ .gpio = 50,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cyts_sleep_act_cfg,
+ [GPIOMUX_SUSPENDED] = &cyts_sleep_sus_cfg,
+ },
+ },
+ { /* TS RESOUT */
+ .gpio = 52,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cyts_resout_act_cfg,
+ [GPIOMUX_SUSPENDED] = &cyts_resout_sus_cfg,
+ },
+ },
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct msm_gpiomux_config msm8960_hsic_configs[] = {
+ {
+ .gpio = 150, /*HSIC_STROBE */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hsic_act_cfg,
+ [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+ },
+ },
+ {
+ .gpio = 151, /* HSIC_DATA */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hsic_act_cfg,
+ [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+ },
+ },
+ {
+ .gpio = 91, /* HSIC_HUB_RESET */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hsic_hub_act_cfg,
+ [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+ },
+ },
+};
+#endif
+
+static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
+ {
+ .gpio = 47,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &hap_lvl_shft_suspended_config,
+ [GPIOMUX_ACTIVE] = &hap_lvl_shft_active_config,
+ },
+ },
+};
+
+static struct msm_gpiomux_config mdm_configs[] __initdata = {
+ /* AP2MDM_STATUS */
+ {
+ .gpio = 94,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+ }
+ },
+ /* MDM2AP_STATUS */
+ {
+ .gpio = 69,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
+ }
+ },
+ /* MDM2AP_ERRFATAL */
+ {
+ .gpio = 70,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
+ }
+ },
+ /* AP2MDM_ERRFATAL */
+ {
+ .gpio = 95,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+ }
+ },
+ /* AP2MDM_KPDPWR_N */
+ {
+ .gpio = 81,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+ }
+ },
+ /* AP2MDM_PMIC_RESET_N */
+ {
+ .gpio = 80,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+ }
+ }
+};
+
+static struct msm_gpiomux_config msm8960_mdp_vsync_configs[] __initdata = {
+ {
+ .gpio = 0,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &mdp_vsync_active_cfg,
+ [GPIOMUX_SUSPENDED] = &mdp_vsync_suspend_cfg,
+ },
+ }
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct msm_gpiomux_config msm8960_hdmi_configs[] __initdata = {
+ {
+ .gpio = 99,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 100,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 101,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 102,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_2_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+};
+#endif
+
+int __init msm8930_init_gpiomux(void)
+{
+ int rc = msm_gpiomux_init(NR_GPIO_IRQS);
+ if (rc) {
+ pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
+ return rc;
+ }
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+ msm_gpiomux_install(msm8960_ethernet_configs,
+ ARRAY_SIZE(msm8960_ethernet_configs));
+#endif
+
+ msm_gpiomux_install(msm8960_gsbi_configs,
+ ARRAY_SIZE(msm8960_gsbi_configs));
+
+ msm_gpiomux_install(msm8960_cyts_configs,
+ ARRAY_SIZE(msm8960_cyts_configs));
+
+ msm_gpiomux_install(msm8960_slimbus_config,
+ ARRAY_SIZE(msm8960_slimbus_config));
+
+ msm_gpiomux_install(msm8960_audio_codec_configs,
+ ARRAY_SIZE(msm8960_audio_codec_configs));
+
+ msm_gpiomux_install(msm8960_audio_auxpcm_configs,
+ ARRAY_SIZE(msm8960_audio_auxpcm_configs));
+
+ msm_gpiomux_install(wcnss_5wire_interface,
+ ARRAY_SIZE(wcnss_5wire_interface));
+
+ if (machine_is_msm8930_mtp() || machine_is_msm8930_fluid() ||
+ machine_is_msm8930_cdp())
+ msm_gpiomux_install(hap_lvl_shft_config,
+ ARRAY_SIZE(hap_lvl_shft_config));
+
+ if (PLATFORM_IS_CHARM25())
+ msm_gpiomux_install(mdm_configs,
+ ARRAY_SIZE(mdm_configs));
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+ if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 1) &&
+ !machine_is_msm8930_mtp() &&
+ !machine_is_msm8930_fluid())
+ msm_gpiomux_install(msm8960_hsic_configs,
+ ARRAY_SIZE(msm8960_hsic_configs));
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+ msm_gpiomux_install(msm8960_hdmi_configs,
+ ARRAY_SIZE(msm8960_hdmi_configs));
+#endif
+
+ msm_gpiomux_install(msm8960_mdp_vsync_configs,
+ ARRAY_SIZE(msm8960_mdp_vsync_configs));
+ return 0;
+}
diff --git a/arch/arm/mach-msm/board-msm8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
similarity index 99%
rename from arch/arm/mach-msm/board-msm8930-pmic.c
rename to arch/arm/mach-msm/board-8930-pmic.c
index 82b26e4..cfb2347 100644
--- a/arch/arm/mach-msm/board-msm8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -21,7 +21,7 @@
#include <mach/msm_bus_board.h>
#include <mach/restart.h>
#include "devices.h"
-#include "board-msm8930.h"
+#include "board-8930.h"
struct pm8xxx_gpio_init {
unsigned gpio;
diff --git a/arch/arm/mach-msm/board-msm8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
similarity index 99%
rename from arch/arm/mach-msm/board-msm8930-storage.c
rename to arch/arm/mach-msm/board-8930-storage.c
index 58bd8e5..032d3d0 100644
--- a/arch/arm/mach-msm/board-msm8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -22,7 +22,7 @@
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
-#include "board-msm8930.h"
+#include "board-8930.h"
/* MSM8960 has 5 SDCC controllers */
enum sdcc_controllers {
diff --git a/arch/arm/mach-msm/board-msm8930.c b/arch/arm/mach-msm/board-8930.c
similarity index 79%
rename from arch/arm/mach-msm/board-msm8930.c
rename to arch/arm/mach-msm/board-8930.c
index d61296c..cc020b5 100644
--- a/arch/arm/mach-msm/board-msm8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -64,7 +64,6 @@
#include <mach/msm_bus_board.h>
#include <mach/msm_memtypes.h>
#include <mach/dma.h>
-#include <mach/msm_dsps.h>
#include <mach/msm_xo.h>
#include <mach/restart.h>
@@ -82,7 +81,7 @@
#include "devices.h"
#include "devices-msm8x60.h"
#include "spm.h"
-#include "board-msm8930.h"
+#include "board-8930.h"
#include "pm.h"
#include "cpuidle.h"
#include "rpm_resources.h"
@@ -93,11 +92,6 @@
#include "pm-boot.h"
#include "msm_watchdog.h"
-#define PLATFORM_IS_CHARM25() \
- (machine_is_msm8930_cdp() && \
- (socinfo_get_platform_subtype() == 1) \
- )
-
static struct platform_device msm_fm_platform_init = {
.name = "iris_fm",
.id = -1,
@@ -105,448 +99,8 @@
#define KS8851_RST_GPIO 89
#define KS8851_IRQ_GPIO 90
-
-/* The SPI configurations apply to GSBI 1*/
-static struct gpiomux_setting spi_active = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_12MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting spi_suspended_config = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting spi_active_config2 = {
- .func = GPIOMUX_FUNC_2,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting spi_suspended_config2 = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting gsbi3_suspended_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_KEEPER,
-};
-
-static struct gpiomux_setting gsbi3_active_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting gsbi5 = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting gsbi10 = {
- .func = GPIOMUX_FUNC_2,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting gsbi12 = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting cdc_mclk = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting audio_auxpcm[] = {
- /* Suspended state */
- {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_NONE,
- },
- /* Active state */
- {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_NONE,
- },
-};
-
-#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
-static struct gpiomux_setting gpio_eth_config = {
- .pull = GPIOMUX_PULL_NONE,
- .drv = GPIOMUX_DRV_8MA,
- .func = GPIOMUX_FUNC_GPIO,
-};
-#endif
-
-static struct gpiomux_setting slimbus = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_KEEPER,
-};
-
-static struct msm_gpiomux_config msm8960_gpiomux_configs[NR_GPIO_IRQS] = {
-#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
- {
- .gpio = KS8851_IRQ_GPIO,
- .settings = {
- [GPIOMUX_SUSPENDED] = &gpio_eth_config,
- }
- },
- {
- .gpio = KS8851_RST_GPIO,
- .settings = {
- [GPIOMUX_SUSPENDED] = &gpio_eth_config,
- }
- },
-#endif
-};
-
-static struct msm_gpiomux_config msm8960_gsbi_configs[] __initdata = {
- {
- .gpio = 6, /* GSBI1 QUP SPI_DATA_MOSI */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config,
- [GPIOMUX_ACTIVE] = &spi_active,
- },
- },
- {
- .gpio = 7, /* GSBI1 QUP SPI_DATA_MISO */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config,
- [GPIOMUX_ACTIVE] = &spi_active,
- },
- },
- {
- .gpio = 8, /* GSBI1 QUP SPI_CS_N */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config,
- [GPIOMUX_ACTIVE] = &spi_active,
- },
- },
- {
- .gpio = 9, /* GSBI1 QUP SPI_CLK */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config,
- [GPIOMUX_ACTIVE] = &spi_active,
- },
- },
- {
- .gpio = 14, /* GSBI1 SPI_CS_1 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config2,
- [GPIOMUX_ACTIVE] = &spi_active_config2,
- },
- },
- {
- .gpio = 16, /* GSBI3 I2C QUP SDA */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
- [GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
- },
- },
- {
- .gpio = 17, /* GSBI3 I2C QUP SCL */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
- [GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
- },
- },
- {
- .gpio = 22, /* GSBI5 UART2 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi5,
- },
- },
- {
- .gpio = 23, /* GSBI5 UART2 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi5,
- },
- },
- {
- .gpio = 24, /* GSBI5 UART2 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi5,
- },
- },
- {
- .gpio = 25, /* GSBI5 UART2 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi5,
- },
- },
- {
- .gpio = 44, /* GSBI12 I2C QUP SDA */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi12,
- },
- },
- {
- .gpio = 45, /* GSBI12 I2C QUP SCL */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi12,
- },
- },
- {
- .gpio = 73, /* GSBI10 I2C QUP SDA */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi10,
- },
- },
- {
- .gpio = 74, /* GSBI10 I2C QUP SCL */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi10,
- },
- },
-};
-
-static struct msm_gpiomux_config msm8960_slimbus_config[] __initdata = {
- {
- .gpio = 60, /* slimbus data */
- .settings = {
- [GPIOMUX_SUSPENDED] = &slimbus,
- },
- },
- {
- .gpio = 61, /* slimbus clk */
- .settings = {
- [GPIOMUX_SUSPENDED] = &slimbus,
- },
- },
-};
-
-static struct msm_gpiomux_config msm8960_audio_codec_configs[] __initdata = {
- {
- .gpio = 59,
- .settings = {
- [GPIOMUX_SUSPENDED] = &cdc_mclk,
- },
- },
-};
-
-static struct msm_gpiomux_config msm8960_audio_auxpcm_configs[] __initdata = {
- {
- .gpio = 63,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
- {
- .gpio = 64,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
- {
- .gpio = 65,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
- {
- .gpio = 66,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
-};
-
-static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting wcnss_5wire_active_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config wcnss_5wire_interface[] = {
- {
- .gpio = 84,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
- {
- .gpio = 85,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
- {
- .gpio = 86,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
- {
- .gpio = 87,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
- {
- .gpio = 88,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
-};
-
-static struct gpiomux_setting cyts_resout_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_resout_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_sleep_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting cyts_sleep_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting cyts_int_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_int_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config msm8960_cyts_configs[] __initdata = {
- { /* TS INTERRUPT */
- .gpio = 11,
- .settings = {
- [GPIOMUX_ACTIVE] = &cyts_int_act_cfg,
- [GPIOMUX_SUSPENDED] = &cyts_int_sus_cfg,
- },
- },
- { /* TS SLEEP */
- .gpio = 50,
- .settings = {
- [GPIOMUX_ACTIVE] = &cyts_sleep_act_cfg,
- [GPIOMUX_SUSPENDED] = &cyts_sleep_sus_cfg,
- },
- },
- { /* TS RESOUT */
- .gpio = 52,
- .settings = {
- [GPIOMUX_ACTIVE] = &cyts_resout_act_cfg,
- [GPIOMUX_SUSPENDED] = &cyts_resout_sus_cfg,
- },
- },
-};
-
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-static struct gpiomux_setting hsic_act_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_12MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting hsic_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
- .dir = GPIOMUX_OUT_LOW,
-};
-
-static struct gpiomux_setting hsic_hub_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct msm_gpiomux_config msm8960_hsic_configs[] = {
- {
- .gpio = 150, /*HSIC_STROBE */
- .settings = {
- [GPIOMUX_ACTIVE] = &hsic_act_cfg,
- [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
- },
- },
- {
- .gpio = 151, /* HSIC_DATA */
- .settings = {
- [GPIOMUX_ACTIVE] = &hsic_act_cfg,
- [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
- },
- },
- {
- .gpio = 91, /* HSIC_HUB_RESET */
- .settings = {
- [GPIOMUX_ACTIVE] = &hsic_hub_act_cfg,
- [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
- },
- },
-};
-#endif
-
#define HAP_SHIFT_LVL_OE_GPIO 47
-static struct gpiomux_setting hap_lvl_shft_suspended_config = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting hap_lvl_shft_active_config = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
- {
- .gpio = HAP_SHIFT_LVL_OE_GPIO,
- .settings = {
- [GPIOMUX_SUSPENDED] = &hap_lvl_shft_suspended_config,
- [GPIOMUX_ACTIVE] = &hap_lvl_shft_active_config,
- },
- },
-};
-
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
struct sx150x_platform_data msm8930_sx150x_data[] = {
@@ -1099,75 +653,6 @@
#define AP2MDM_PMIC_RESET_N 80
#define AP2MDM_KPDPWR_N 81
-static struct gpiomux_setting ap2mdm_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting mdm2ap_status_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting mdm2ap_errfatal_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_16MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting ap2mdm_kpdpwr_n_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct msm_gpiomux_config mdm_configs[] __initdata = {
- /* AP2MDM_STATUS */
- {
- .gpio = AP2MDM_STATUS,
- .settings = {
- [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
- }
- },
- /* MDM2AP_STATUS */
- {
- .gpio = MDM2AP_STATUS,
- .settings = {
- [GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
- }
- },
- /* MDM2AP_ERRFATAL */
- {
- .gpio = MDM2AP_ERRFATAL,
- .settings = {
- [GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
- }
- },
- /* AP2MDM_ERRFATAL */
- {
- .gpio = AP2MDM_ERRFATAL,
- .settings = {
- [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
- }
- },
- /* AP2MDM_KPDPWR_N */
- {
- .gpio = AP2MDM_KPDPWR_N,
- .settings = {
- [GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
- }
- },
- /* AP2MDM_PMIC_RESET_N */
- {
- .gpio = AP2MDM_PMIC_RESET_N,
- .settings = {
- [GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
- }
- }
-};
-
static struct resource mdm_resources[] = {
{
.start = MDM2AP_ERRFATAL,
@@ -1225,49 +710,6 @@
&mdm_device,
};
-static int __init gpiomux_init(void)
-{
- int rc;
-
- rc = msm_gpiomux_init(NR_GPIO_IRQS);
- if (rc) {
- pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
- return rc;
- }
-
- msm_gpiomux_install(msm8960_gpiomux_configs,
- ARRAY_SIZE(msm8960_gpiomux_configs));
-
- msm_gpiomux_install(msm8960_gsbi_configs,
- ARRAY_SIZE(msm8960_gsbi_configs));
-
- msm_gpiomux_install(msm8960_cyts_configs,
- ARRAY_SIZE(msm8960_cyts_configs));
-
- msm_gpiomux_install(msm8960_slimbus_config,
- ARRAY_SIZE(msm8960_slimbus_config));
-
- msm_gpiomux_install(msm8960_audio_codec_configs,
- ARRAY_SIZE(msm8960_audio_codec_configs));
-
- msm_gpiomux_install(msm8960_audio_auxpcm_configs,
- ARRAY_SIZE(msm8960_audio_auxpcm_configs));
-
- msm_gpiomux_install(wcnss_5wire_interface,
- ARRAY_SIZE(wcnss_5wire_interface));
-
- if (machine_is_msm8930_mtp() || machine_is_msm8930_fluid() ||
- machine_is_msm8930_cdp())
- msm_gpiomux_install(hap_lvl_shft_config,
- ARRAY_SIZE(hap_lvl_shft_config));
-
- if (PLATFORM_IS_CHARM25())
- msm_gpiomux_install(mdm_configs,
- ARRAY_SIZE(mdm_configs));
-
- return 0;
-}
-
#define MSM_SHARED_RAM_PHYS 0x80000000
static void __init msm8930_map_io(void)
@@ -2058,9 +1500,7 @@
&msm8960_device_qup_i2c_gsbi3,
&msm8960_device_qup_i2c_gsbi4,
&msm8960_device_qup_i2c_gsbi10,
-#ifndef CONFIG_MSM_DSPS
&msm8960_device_qup_i2c_gsbi12,
-#endif
&msm_slim_ctrl,
&msm_device_wcnss_wlan,
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
@@ -2341,24 +1781,6 @@
};
#endif
-/* Sensors DSPS platform data */
-#ifdef CONFIG_MSM_DSPS
-#define DSPS_PIL_GENERIC_NAME "dsps"
-#endif /* CONFIG_MSM_DSPS */
-
-static void __init msm8930_init_dsps(void)
-{
-#ifdef CONFIG_MSM_DSPS
- struct msm_dsps_platform_data *pdata =
- msm_dsps_device.dev.platform_data;
- pdata->pil_name = DSPS_PIL_GENERIC_NAME;
- pdata->gpios = NULL;
- pdata->gpios_num = 0;
-
- platform_device_register(&msm_dsps_device);
-#endif /* CONFIG_MSM_DSPS */
-}
-
static void __init msm8930_init_hsic(void)
{
#ifdef CONFIG_USB_EHCI_MSM_HSIC
@@ -2373,14 +1795,10 @@
machine_is_msm8930_fluid())
return;
- msm_gpiomux_install(msm8960_hsic_configs,
- ARRAY_SIZE(msm8960_hsic_configs));
-
platform_device_register(&msm_device_hsic_host);
#endif
}
-
#ifdef CONFIG_ISL9519_CHARGER
static struct isl_platform_data isl_data __initdata = {
.valid_n_gpio = 0, /* Not required when notify-by-pmic */
@@ -2481,7 +1899,7 @@
msm_clock_init(&msm8960_clock_init_data);
msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
msm_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
- gpiomux_init();
+ msm8930_init_gpiomux();
msm8960_device_qup_spi_gsbi1.dev.platform_data =
&msm8960_qup_spi_gsbi1_pdata;
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
@@ -2505,7 +1923,6 @@
msm8930_init_fb();
slim_register_board_info(msm_slim_devices,
ARRAY_SIZE(msm_slim_devices));
- msm8930_init_dsps();
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),
diff --git a/arch/arm/mach-msm/board-msm8930.h b/arch/arm/mach-msm/board-8930.h
similarity index 94%
rename from arch/arm/mach-msm/board-msm8930.h
rename to arch/arm/mach-msm/board-8930.h
index 54fa56a..c413061 100644
--- a/arch/arm/mach-msm/board-msm8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -72,9 +72,15 @@
void msm8930_init_fb(void);
void msm8930_init_pmic(void);
void msm8930_init_mmc(void);
+int msm8930_init_gpiomux(void);
void msm8930_allocate_fb_region(void);
void msm8930_pm8921_gpio_mpp_init(void);
+#define PLATFORM_IS_CHARM25() \
+ (machine_is_msm8930_cdp() && \
+ (socinfo_get_platform_subtype() == 1) \
+ )
+
#define MSM_8930_GSBI4_QUP_I2C_BUS_ID 4
#define MSM_8930_GSBI3_QUP_I2C_BUS_ID 3
#define MSM_8930_GSBI10_QUP_I2C_BUS_ID 10
diff --git a/arch/arm/mach-msm/board-msm8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
similarity index 99%
rename from arch/arm/mach-msm/board-msm8960-camera.c
rename to arch/arm/mach-msm/board-8960-camera.c
index a17008b..e827b2b 100644
--- a/arch/arm/mach-msm/board-msm8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -19,7 +19,7 @@
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
-#include "board-msm8960.h"
+#include "board-8960.h"
#if (defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)) && \
defined(CONFIG_I2C)
diff --git a/arch/arm/mach-msm/board-msm8960-display.c b/arch/arm/mach-msm/board-8960-display.c
similarity index 92%
rename from arch/arm/mach-msm/board-msm8960-display.c
rename to arch/arm/mach-msm/board-8960-display.c
index 2acca7e..63c51ea 100644
--- a/arch/arm/mach-msm/board-msm8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -21,7 +21,7 @@
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
-#include "board-msm8960.h"
+#include "board-8960.h"
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 3) /* 4 bpp x 3 pages */
@@ -37,7 +37,7 @@
#define MSM_FB_EXT_BUF_SIZE 0
#endif
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
/* width x height x 3 bpp x 2 frame buffer */
#define MSM_FB_WRITEBACK_SIZE (1376 * 768 * 3 * 2)
#define MSM_FB_WRITEBACK_OFFSET \
@@ -732,78 +732,7 @@
};
#endif
-static struct gpiomux_setting mdp_vsync_suspend_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting mdp_vsync_active_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config msm8960_mdp_vsync_configs[] __initdata = {
- {
- .gpio = MDP_VSYNC_GPIO,
- .settings = {
- [GPIOMUX_ACTIVE] = &mdp_vsync_active_cfg,
- [GPIOMUX_SUSPENDED] = &mdp_vsync_suspend_cfg,
- },
- }
-};
-
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-static struct gpiomux_setting hdmi_suspend_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting hdmi_active_1_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting hdmi_active_2_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config msm8960_hdmi_configs[] __initdata = {
- {
- .gpio = 99,
- .settings = {
- [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
- [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
- },
- },
- {
- .gpio = 100,
- .settings = {
- [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
- [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
- },
- },
- {
- .gpio = 101,
- .settings = {
- [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
- [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
- },
- },
- {
- .gpio = 102,
- .settings = {
- [GPIOMUX_ACTIVE] = &hdmi_active_2_cfg,
- [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
- },
- },
-};
-
static int hdmi_enable_5v(int on)
{
/* TBD: PM8921 regulator instead of 8901 */
@@ -981,14 +910,6 @@
void __init msm8960_init_fb(void)
{
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
- msm_gpiomux_install(msm8960_hdmi_configs,
- ARRAY_SIZE(msm8960_hdmi_configs));
-#endif
-
- msm_gpiomux_install(msm8960_mdp_vsync_configs,
- ARRAY_SIZE(msm8960_mdp_vsync_configs));
-
platform_device_register(&msm_fb_device);
#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
diff --git a/arch/arm/mach-msm/board-8960-gpiomux.c b/arch/arm/mach-msm/board-8960-gpiomux.c
new file mode 100644
index 0000000..9be65bb
--- /dev/null
+++ b/arch/arm/mach-msm/board-8960-gpiomux.c
@@ -0,0 +1,662 @@
+/* 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.
+ *
+ */
+
+#include <asm/mach-types.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/socinfo.h>
+#include "devices.h"
+#include "board-8960.h"
+
+/* The SPI configurations apply to GSBI 1*/
+static struct gpiomux_setting spi_active = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_12MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting spi_suspended_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting spi_active_config2 = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting spi_suspended_config2 = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting gsbi3_suspended_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_KEEPER,
+};
+
+static struct gpiomux_setting gsbi3_active_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi5 = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi10 = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi12 = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting cdc_mclk = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting audio_auxpcm[] = {
+ /* Suspended state */
+ {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+ /* Active state */
+ {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+};
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct gpiomux_setting gpio_eth_config = {
+ .pull = GPIOMUX_PULL_NONE,
+ .drv = GPIOMUX_DRV_8MA,
+ .func = GPIOMUX_FUNC_GPIO,
+};
+#endif
+
+static struct gpiomux_setting slimbus = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_KEEPER,
+};
+
+static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting wcnss_5wire_active_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_resout_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_resout_act_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_sleep_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_sleep_act_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_int_act_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_int_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct gpiomux_setting hsic_act_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_12MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting hsic_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+ .dir = GPIOMUX_OUT_LOW,
+};
+
+static struct gpiomux_setting hsic_hub_act_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+#endif
+
+static struct gpiomux_setting hap_lvl_shft_suspended_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hap_lvl_shft_active_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting ap2mdm_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdm2ap_status_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdm2ap_errfatal_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_16MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting ap2mdm_kpdpwr_n_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdp_vsync_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdp_vsync_active_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct gpiomux_setting hdmi_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hdmi_active_1_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting hdmi_active_2_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+#endif
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct msm_gpiomux_config msm8960_ethernet_configs[] = {
+ {
+ .gpio = 90,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_eth_config,
+ }
+ },
+ {
+ .gpio = 89,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_eth_config,
+ }
+ },
+};
+#endif
+
+static struct msm_gpiomux_config msm8960_gsbi_configs[] __initdata = {
+ {
+ .gpio = 6, /* GSBI1 QUP SPI_DATA_MOSI */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config,
+ [GPIOMUX_ACTIVE] = &spi_active,
+ },
+ },
+ {
+ .gpio = 7, /* GSBI1 QUP SPI_DATA_MISO */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config,
+ [GPIOMUX_ACTIVE] = &spi_active,
+ },
+ },
+ {
+ .gpio = 8, /* GSBI1 QUP SPI_CS_N */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config,
+ [GPIOMUX_ACTIVE] = &spi_active,
+ },
+ },
+ {
+ .gpio = 9, /* GSBI1 QUP SPI_CLK */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config,
+ [GPIOMUX_ACTIVE] = &spi_active,
+ },
+ },
+ {
+ .gpio = 14, /* GSBI1 SPI_CS_1 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &spi_suspended_config2,
+ [GPIOMUX_ACTIVE] = &spi_active_config2,
+ },
+ },
+ {
+ .gpio = 16, /* GSBI3 I2C QUP SDA */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+ [GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+ },
+ },
+ {
+ .gpio = 17, /* GSBI3 I2C QUP SCL */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+ [GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+ },
+ },
+ {
+ .gpio = 22, /* GSBI5 UART2 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi5,
+ },
+ },
+ {
+ .gpio = 23, /* GSBI5 UART2 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi5,
+ },
+ },
+ {
+ .gpio = 24, /* GSBI5 UART2 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi5,
+ },
+ },
+ {
+ .gpio = 25, /* GSBI5 UART2 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi5,
+ },
+ },
+ {
+ .gpio = 44, /* GSBI12 I2C QUP SDA */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi12,
+ },
+ },
+ {
+ .gpio = 45, /* GSBI12 I2C QUP SCL */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi12,
+ },
+ },
+ {
+ .gpio = 73, /* GSBI10 I2C QUP SDA */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi10,
+ },
+ },
+ {
+ .gpio = 74, /* GSBI10 I2C QUP SCL */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi10,
+ },
+ },
+};
+
+static struct msm_gpiomux_config msm8960_slimbus_config[] __initdata = {
+ {
+ .gpio = 60, /* slimbus data */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &slimbus,
+ },
+ },
+ {
+ .gpio = 61, /* slimbus clk */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &slimbus,
+ },
+ },
+};
+
+static struct msm_gpiomux_config msm8960_audio_codec_configs[] __initdata = {
+ {
+ .gpio = 59,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &cdc_mclk,
+ },
+ },
+};
+
+static struct msm_gpiomux_config msm8960_audio_auxpcm_configs[] __initdata = {
+ {
+ .gpio = 63,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 64,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 65,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 66,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+};
+
+static struct msm_gpiomux_config wcnss_5wire_interface[] = {
+ {
+ .gpio = 84,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 85,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 86,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 87,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 88,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+};
+
+static struct msm_gpiomux_config msm8960_cyts_configs[] __initdata = {
+ { /* TS INTERRUPT */
+ .gpio = 11,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cyts_int_act_cfg,
+ [GPIOMUX_SUSPENDED] = &cyts_int_sus_cfg,
+ },
+ },
+ { /* TS SLEEP */
+ .gpio = 50,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cyts_sleep_act_cfg,
+ [GPIOMUX_SUSPENDED] = &cyts_sleep_sus_cfg,
+ },
+ },
+ { /* TS RESOUT */
+ .gpio = 52,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cyts_resout_act_cfg,
+ [GPIOMUX_SUSPENDED] = &cyts_resout_sus_cfg,
+ },
+ },
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct msm_gpiomux_config msm8960_hsic_configs[] = {
+ {
+ .gpio = 150, /*HSIC_STROBE */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hsic_act_cfg,
+ [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+ },
+ },
+ {
+ .gpio = 151, /* HSIC_DATA */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hsic_act_cfg,
+ [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+ },
+ },
+ {
+ .gpio = 91, /* HSIC_HUB_RESET */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hsic_hub_act_cfg,
+ [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+ },
+ },
+};
+#endif
+
+static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
+ {
+ .gpio = 47,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &hap_lvl_shft_suspended_config,
+ [GPIOMUX_ACTIVE] = &hap_lvl_shft_active_config,
+ },
+ },
+};
+
+static struct msm_gpiomux_config mdm_configs[] __initdata = {
+ /* AP2MDM_STATUS */
+ {
+ .gpio = 94,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+ }
+ },
+ /* MDM2AP_STATUS */
+ {
+ .gpio = 69,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
+ }
+ },
+ /* MDM2AP_ERRFATAL */
+ {
+ .gpio = 70,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
+ }
+ },
+ /* AP2MDM_ERRFATAL */
+ {
+ .gpio = 95,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+ }
+ },
+ /* AP2MDM_KPDPWR_N */
+ {
+ .gpio = 81,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+ }
+ },
+ /* AP2MDM_PMIC_RESET_N */
+ {
+ .gpio = 80,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+ }
+ }
+};
+
+static struct msm_gpiomux_config msm8960_mdp_vsync_configs[] __initdata = {
+ {
+ .gpio = 0,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &mdp_vsync_active_cfg,
+ [GPIOMUX_SUSPENDED] = &mdp_vsync_suspend_cfg,
+ },
+ }
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct msm_gpiomux_config msm8960_hdmi_configs[] __initdata = {
+ {
+ .gpio = 99,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 100,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 101,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 102,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_2_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+};
+#endif
+
+int __init msm8960_init_gpiomux(void)
+{
+ int rc = msm_gpiomux_init(NR_GPIO_IRQS);
+ if (rc) {
+ pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
+ return rc;
+ }
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+ msm_gpiomux_install(msm8960_ethernet_configs,
+ ARRAY_SIZE(msm8960_ethernet_configs));
+#endif
+
+ msm_gpiomux_install(msm8960_gsbi_configs,
+ ARRAY_SIZE(msm8960_gsbi_configs));
+
+ msm_gpiomux_install(msm8960_cyts_configs,
+ ARRAY_SIZE(msm8960_cyts_configs));
+
+ msm_gpiomux_install(msm8960_slimbus_config,
+ ARRAY_SIZE(msm8960_slimbus_config));
+
+ msm_gpiomux_install(msm8960_audio_codec_configs,
+ ARRAY_SIZE(msm8960_audio_codec_configs));
+
+ msm_gpiomux_install(msm8960_audio_auxpcm_configs,
+ ARRAY_SIZE(msm8960_audio_auxpcm_configs));
+
+ msm_gpiomux_install(wcnss_5wire_interface,
+ ARRAY_SIZE(wcnss_5wire_interface));
+
+ if (machine_is_msm8960_mtp() || machine_is_msm8960_fluid() ||
+ machine_is_msm8960_liquid() || machine_is_msm8960_cdp())
+ msm_gpiomux_install(hap_lvl_shft_config,
+ ARRAY_SIZE(hap_lvl_shft_config));
+
+ if (PLATFORM_IS_CHARM25())
+ msm_gpiomux_install(mdm_configs,
+ ARRAY_SIZE(mdm_configs));
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+ if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 1) &&
+ (PLATFORM_IS_CHARM25() || machine_is_msm8960_liquid()))
+ msm_gpiomux_install(msm8960_hsic_configs,
+ ARRAY_SIZE(msm8960_hsic_configs));
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+ msm_gpiomux_install(msm8960_hdmi_configs,
+ ARRAY_SIZE(msm8960_hdmi_configs));
+#endif
+
+ msm_gpiomux_install(msm8960_mdp_vsync_configs,
+ ARRAY_SIZE(msm8960_mdp_vsync_configs));
+
+ return 0;
+}
diff --git a/arch/arm/mach-msm/board-msm8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
similarity index 99%
rename from arch/arm/mach-msm/board-msm8960-pmic.c
rename to arch/arm/mach-msm/board-8960-pmic.c
index 298956b..44f7be6 100644
--- a/arch/arm/mach-msm/board-msm8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -21,7 +21,7 @@
#include <mach/msm_bus_board.h>
#include <mach/restart.h>
#include "devices.h"
-#include "board-msm8960.h"
+#include "board-8960.h"
struct pm8xxx_gpio_init {
unsigned gpio;
diff --git a/arch/arm/mach-msm/board-msm8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
similarity index 99%
rename from arch/arm/mach-msm/board-msm8960-regulator.c
rename to arch/arm/mach-msm/board-8960-regulator.c
index 976534e..7bc3ca5 100644
--- a/arch/arm/mach-msm/board-msm8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -15,7 +15,7 @@
#include <linux/regulator/gpio-regulator.h>
#include <mach/rpm-regulator.h>
-#include "board-msm8960.h"
+#include "board-8960.h"
#define VREG_CONSUMERS(_id) \
static struct regulator_consumer_supply vreg_consumers_##_id[]
@@ -449,9 +449,9 @@
/* SAW regulator constraints */
struct regulator_init_data msm_saw_regulator_pdata_s5 =
/* ID vreg_name min_uV max_uV */
- SAW_VREG_INIT(S5, "8921_s5", 950000, 1150000);
+ SAW_VREG_INIT(S5, "8921_s5", 950000, 1300000);
struct regulator_init_data msm_saw_regulator_pdata_s6 =
- SAW_VREG_INIT(S6, "8921_s6", 950000, 1150000);
+ SAW_VREG_INIT(S6, "8921_s6", 950000, 1300000);
/* PM8921 regulator constraints */
struct pm8921_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-msm8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
similarity index 99%
rename from arch/arm/mach-msm/board-msm8960-storage.c
rename to arch/arm/mach-msm/board-8960-storage.c
index 357a9d0..dfcafd4 100644
--- a/arch/arm/mach-msm/board-msm8960-storage.c
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -22,7 +22,7 @@
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
-#include "board-msm8960.h"
+#include "board-8960.h"
/* MSM8960 has 5 SDCC controllers */
enum sdcc_controllers {
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-8960.c
similarity index 82%
rename from arch/arm/mach-msm/board-msm8960.c
rename to arch/arm/mach-msm/board-8960.c
index 251c1d9..3d0d0e5 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -83,7 +83,7 @@
#include "devices.h"
#include "devices-msm8x60.h"
#include "spm.h"
-#include "board-msm8960.h"
+#include "board-8960.h"
#include "pm.h"
#include "cpuidle.h"
#include "rpm_resources.h"
@@ -94,11 +94,6 @@
#include "pm-boot.h"
#include "msm_watchdog.h"
-#define PLATFORM_IS_CHARM25() \
- (machine_is_msm8960_cdp() && \
- (socinfo_get_platform_subtype() == 1) \
- )
-
static struct platform_device msm_fm_platform_init = {
.name = "iris_fm",
.id = -1,
@@ -106,448 +101,8 @@
#define KS8851_RST_GPIO 89
#define KS8851_IRQ_GPIO 90
-
-/* The SPI configurations apply to GSBI 1*/
-static struct gpiomux_setting spi_active = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_12MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting spi_suspended_config = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting spi_active_config2 = {
- .func = GPIOMUX_FUNC_2,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting spi_suspended_config2 = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting gsbi3_suspended_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_KEEPER,
-};
-
-static struct gpiomux_setting gsbi3_active_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting gsbi5 = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting gsbi10 = {
- .func = GPIOMUX_FUNC_2,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting gsbi12 = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting cdc_mclk = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting audio_auxpcm[] = {
- /* Suspended state */
- {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_NONE,
- },
- /* Active state */
- {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_NONE,
- },
-};
-
-#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
-static struct gpiomux_setting gpio_eth_config = {
- .pull = GPIOMUX_PULL_NONE,
- .drv = GPIOMUX_DRV_8MA,
- .func = GPIOMUX_FUNC_GPIO,
-};
-#endif
-
-static struct gpiomux_setting slimbus = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_KEEPER,
-};
-
-static struct msm_gpiomux_config msm8960_gpiomux_configs[NR_GPIO_IRQS] = {
-#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
- {
- .gpio = KS8851_IRQ_GPIO,
- .settings = {
- [GPIOMUX_SUSPENDED] = &gpio_eth_config,
- }
- },
- {
- .gpio = KS8851_RST_GPIO,
- .settings = {
- [GPIOMUX_SUSPENDED] = &gpio_eth_config,
- }
- },
-#endif
-};
-
-static struct msm_gpiomux_config msm8960_gsbi_configs[] __initdata = {
- {
- .gpio = 6, /* GSBI1 QUP SPI_DATA_MOSI */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config,
- [GPIOMUX_ACTIVE] = &spi_active,
- },
- },
- {
- .gpio = 7, /* GSBI1 QUP SPI_DATA_MISO */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config,
- [GPIOMUX_ACTIVE] = &spi_active,
- },
- },
- {
- .gpio = 8, /* GSBI1 QUP SPI_CS_N */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config,
- [GPIOMUX_ACTIVE] = &spi_active,
- },
- },
- {
- .gpio = 9, /* GSBI1 QUP SPI_CLK */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config,
- [GPIOMUX_ACTIVE] = &spi_active,
- },
- },
- {
- .gpio = 14, /* GSBI1 SPI_CS_1 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &spi_suspended_config2,
- [GPIOMUX_ACTIVE] = &spi_active_config2,
- },
- },
- {
- .gpio = 16, /* GSBI3 I2C QUP SDA */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
- [GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
- },
- },
- {
- .gpio = 17, /* GSBI3 I2C QUP SCL */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
- [GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
- },
- },
- {
- .gpio = 22, /* GSBI5 UART2 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi5,
- },
- },
- {
- .gpio = 23, /* GSBI5 UART2 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi5,
- },
- },
- {
- .gpio = 24, /* GSBI5 UART2 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi5,
- },
- },
- {
- .gpio = 25, /* GSBI5 UART2 */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi5,
- },
- },
- {
- .gpio = 44, /* GSBI12 I2C QUP SDA */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi12,
- },
- },
- {
- .gpio = 45, /* GSBI12 I2C QUP SCL */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi12,
- },
- },
- {
- .gpio = 73, /* GSBI10 I2C QUP SDA */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi10,
- },
- },
- {
- .gpio = 74, /* GSBI10 I2C QUP SCL */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gsbi10,
- },
- },
-};
-
-static struct msm_gpiomux_config msm8960_slimbus_config[] __initdata = {
- {
- .gpio = 60, /* slimbus data */
- .settings = {
- [GPIOMUX_SUSPENDED] = &slimbus,
- },
- },
- {
- .gpio = 61, /* slimbus clk */
- .settings = {
- [GPIOMUX_SUSPENDED] = &slimbus,
- },
- },
-};
-
-static struct msm_gpiomux_config msm8960_audio_codec_configs[] __initdata = {
- {
- .gpio = 59,
- .settings = {
- [GPIOMUX_SUSPENDED] = &cdc_mclk,
- },
- },
-};
-
-static struct msm_gpiomux_config msm8960_audio_auxpcm_configs[] __initdata = {
- {
- .gpio = 63,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
- {
- .gpio = 64,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
- {
- .gpio = 65,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
- {
- .gpio = 66,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
-};
-
-static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting wcnss_5wire_active_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config wcnss_5wire_interface[] = {
- {
- .gpio = 84,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
- {
- .gpio = 85,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
- {
- .gpio = 86,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
- {
- .gpio = 87,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
- {
- .gpio = 88,
- .settings = {
- [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
- [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
- },
- },
-};
-
-static struct gpiomux_setting cyts_resout_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_resout_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_sleep_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting cyts_sleep_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting cyts_int_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_int_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config msm8960_cyts_configs[] __initdata = {
- { /* TS INTERRUPT */
- .gpio = 11,
- .settings = {
- [GPIOMUX_ACTIVE] = &cyts_int_act_cfg,
- [GPIOMUX_SUSPENDED] = &cyts_int_sus_cfg,
- },
- },
- { /* TS SLEEP */
- .gpio = 50,
- .settings = {
- [GPIOMUX_ACTIVE] = &cyts_sleep_act_cfg,
- [GPIOMUX_SUSPENDED] = &cyts_sleep_sus_cfg,
- },
- },
- { /* TS RESOUT */
- .gpio = 52,
- .settings = {
- [GPIOMUX_ACTIVE] = &cyts_resout_act_cfg,
- [GPIOMUX_SUSPENDED] = &cyts_resout_sus_cfg,
- },
- },
-};
-
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-static struct gpiomux_setting hsic_act_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_12MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting hsic_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
- .dir = GPIOMUX_OUT_LOW,
-};
-
-static struct gpiomux_setting hsic_hub_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct msm_gpiomux_config msm8960_hsic_configs[] = {
- {
- .gpio = 150, /*HSIC_STROBE */
- .settings = {
- [GPIOMUX_ACTIVE] = &hsic_act_cfg,
- [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
- },
- },
- {
- .gpio = 151, /* HSIC_DATA */
- .settings = {
- [GPIOMUX_ACTIVE] = &hsic_act_cfg,
- [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
- },
- },
- {
- .gpio = 91, /* HSIC_HUB_RESET */
- .settings = {
- [GPIOMUX_ACTIVE] = &hsic_hub_act_cfg,
- [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
- },
- },
-};
-#endif
-
#define HAP_SHIFT_LVL_OE_GPIO 47
-static struct gpiomux_setting hap_lvl_shft_suspended_config = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting hap_lvl_shft_active_config = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
- {
- .gpio = HAP_SHIFT_LVL_OE_GPIO,
- .settings = {
- [GPIOMUX_SUSPENDED] = &hap_lvl_shft_suspended_config,
- [GPIOMUX_ACTIVE] = &hap_lvl_shft_active_config,
- },
- },
-};
-
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
struct sx150x_platform_data msm8960_sx150x_data[] = {
@@ -1102,75 +657,6 @@
#define AP2MDM_PMIC_RESET_N 80
#define AP2MDM_KPDPWR_N 81
-static struct gpiomux_setting ap2mdm_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting mdm2ap_status_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting mdm2ap_errfatal_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_16MA,
- .pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting ap2mdm_kpdpwr_n_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct msm_gpiomux_config mdm_configs[] __initdata = {
- /* AP2MDM_STATUS */
- {
- .gpio = AP2MDM_STATUS,
- .settings = {
- [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
- }
- },
- /* MDM2AP_STATUS */
- {
- .gpio = MDM2AP_STATUS,
- .settings = {
- [GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
- }
- },
- /* MDM2AP_ERRFATAL */
- {
- .gpio = MDM2AP_ERRFATAL,
- .settings = {
- [GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
- }
- },
- /* AP2MDM_ERRFATAL */
- {
- .gpio = AP2MDM_ERRFATAL,
- .settings = {
- [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
- }
- },
- /* AP2MDM_KPDPWR_N */
- {
- .gpio = AP2MDM_KPDPWR_N,
- .settings = {
- [GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
- }
- },
- /* AP2MDM_PMIC_RESET_N */
- {
- .gpio = AP2MDM_PMIC_RESET_N,
- .settings = {
- [GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
- }
- }
-};
-
static struct resource mdm_resources[] = {
{
.start = MDM2AP_ERRFATAL,
@@ -1228,49 +714,6 @@
&mdm_device,
};
-static int __init gpiomux_init(void)
-{
- int rc;
-
- rc = msm_gpiomux_init(NR_GPIO_IRQS);
- if (rc) {
- pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
- return rc;
- }
-
- msm_gpiomux_install(msm8960_gpiomux_configs,
- ARRAY_SIZE(msm8960_gpiomux_configs));
-
- msm_gpiomux_install(msm8960_gsbi_configs,
- ARRAY_SIZE(msm8960_gsbi_configs));
-
- msm_gpiomux_install(msm8960_cyts_configs,
- ARRAY_SIZE(msm8960_cyts_configs));
-
- msm_gpiomux_install(msm8960_slimbus_config,
- ARRAY_SIZE(msm8960_slimbus_config));
-
- msm_gpiomux_install(msm8960_audio_codec_configs,
- ARRAY_SIZE(msm8960_audio_codec_configs));
-
- msm_gpiomux_install(msm8960_audio_auxpcm_configs,
- ARRAY_SIZE(msm8960_audio_auxpcm_configs));
-
- msm_gpiomux_install(wcnss_5wire_interface,
- ARRAY_SIZE(wcnss_5wire_interface));
-
- if (machine_is_msm8960_mtp() || machine_is_msm8960_fluid() ||
- machine_is_msm8960_liquid() || machine_is_msm8960_cdp())
- msm_gpiomux_install(hap_lvl_shft_config,
- ARRAY_SIZE(hap_lvl_shft_config));
-
- if (PLATFORM_IS_CHARM25())
- msm_gpiomux_install(mdm_configs,
- ARRAY_SIZE(mdm_configs));
-
- return 0;
-}
-
#define MSM_SHARED_RAM_PHYS 0x80000000
static void __init msm8960_map_io(void)
@@ -1379,6 +822,22 @@
vbus_is_on = false;
}
+static int wr_phy_init_seq[] = {
+ 0x44, 0x80, /* set VBUS valid threshold
+ and disconnect valid threshold */
+ 0x38, 0x81, /* update DC voltage level */
+ 0x14, 0x82, /* set preemphasis and rise/fall time */
+ 0x13, 0x83, /* set source impedance adjusment */
+ -1};
+
+static int liquid_v1_phy_init_seq[] = {
+ 0x44, 0x80,/* set VBUS valid threshold
+ and disconnect valid threshold */
+ 0x3C, 0x81,/* update DC voltage level */
+ 0x18, 0x82,/* set preemphasis and rise/fall time */
+ 0x23, 0x83,/* set source impedance sdjusment */
+ -1};
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PMIC_CONTROL,
@@ -2210,6 +1669,7 @@
&msm_voice,
&msm_voip,
&msm_lpa_pcm,
+ &msm_compr_dsp,
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
@@ -2268,6 +1728,7 @@
&msm_cpudai_afe_02_rx,
&msm_cpudai_afe_02_tx,
&msm_pcm_afe,
+ &msm_compr_dsp,
&msm_pcm_hostless,
&msm_bus_apps_fabric,
&msm_bus_sys_fabric,
@@ -2486,23 +1947,14 @@
#ifdef CONFIG_USB_EHCI_MSM_HSIC
uint32_t version = socinfo_get_version();
- pr_info("%s: version:%d mtp:%d\n", __func__,
- SOCINFO_VERSION_MAJOR(version),
- machine_is_msm8960_mtp());
-
- if ((SOCINFO_VERSION_MAJOR(version) == 1) ||
- machine_is_msm8960_mtp() ||
- machine_is_msm8960_fluid())
+ if (SOCINFO_VERSION_MAJOR(version) == 1)
return;
- msm_gpiomux_install(msm8960_hsic_configs,
- ARRAY_SIZE(msm8960_hsic_configs));
-
- platform_device_register(&msm_device_hsic_host);
+ if (PLATFORM_IS_CHARM25() || machine_is_msm8960_liquid())
+ platform_device_register(&msm_device_hsic_host);
#endif
}
-
#ifdef CONFIG_ISL9519_CHARGER
static struct isl_platform_data isl_data __initdata = {
.valid_n_gpio = 0, /* Not required when notify-by-pmic */
@@ -2608,7 +2060,7 @@
msm8960_init_pmic();
msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
- gpiomux_init();
+ msm8960_init_gpiomux();
msm8960_i2c_init();
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
msm_spm_l2_init(msm_spm_l2_data);
@@ -2641,7 +2093,7 @@
regulator_suppress_info_printing();
platform_device_register(&msm8960_device_rpm_regulator);
msm_clock_init(&msm8960_dummy_clock_init_data);
- gpiomux_init();
+ msm8960_init_gpiomux();
msm8960_init_pmic();
msm8960_device_qup_spi_gsbi1.dev.platform_data =
&msm8960_qup_spi_gsbi1_pdata;
@@ -2681,6 +2133,13 @@
if (machine_is_msm8960_liquid())
msm_otg_pdata.mhl_enable = true;
msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
+ if (machine_is_msm8960_mtp() || machine_is_msm8960_fluid() ||
+ machine_is_msm8960_cdp()) {
+ msm_otg_pdata.phy_init_seq = wr_phy_init_seq;
+ } else if (machine_is_msm8960_liquid()) {
+ msm_otg_pdata.phy_init_seq =
+ liquid_v1_phy_init_seq;
+ }
#ifdef CONFIG_USB_EHCI_MSM_HSIC
if (machine_is_msm8960_liquid()) {
if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
@@ -2688,7 +2147,7 @@
}
#endif
msm_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
- gpiomux_init();
+ msm8960_init_gpiomux();
msm8960_device_qup_spi_gsbi1.dev.platform_data =
&msm8960_qup_spi_gsbi1_pdata;
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
diff --git a/arch/arm/mach-msm/board-msm8960.h b/arch/arm/mach-msm/board-8960.h
similarity index 94%
rename from arch/arm/mach-msm/board-msm8960.h
rename to arch/arm/mach-msm/board-8960.h
index 6fcb2aa..56fa3ca 100644
--- a/arch/arm/mach-msm/board-msm8960.h
+++ b/arch/arm/mach-msm/board-8960.h
@@ -72,9 +72,15 @@
void msm8960_init_fb(void);
void msm8960_init_pmic(void);
void msm8960_init_mmc(void);
+int msm8960_init_gpiomux(void);
void msm8960_allocate_fb_region(void);
void msm8960_pm8921_gpio_mpp_init(void);
+#define PLATFORM_IS_CHARM25() \
+ (machine_is_msm8960_cdp() && \
+ (socinfo_get_platform_subtype() == 1) \
+ )
+
#define MSM_8960_GSBI4_QUP_I2C_BUS_ID 4
#define MSM_8960_GSBI3_QUP_I2C_BUS_ID 3
#define MSM_8960_GSBI10_QUP_I2C_BUS_ID 10
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 724b3c5..0a2e102 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -674,6 +674,14 @@
vbus_is_on = false;
}
+static int shelby_phy_init_seq[] = {
+ 0x44, 0x80,/* set VBUS valid threshold and
+ disconnect valid threshold */
+ 0x38, 0x81, /* update DC voltage level */
+ 0x14, 0x82,/* set preemphasis and rise/fall time */
+ 0x13, 0x83,/* set source impedance adjustment */
+ -1};
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PHY_CONTROL,
@@ -766,6 +774,7 @@
pm8018_platform_data.num_regulators = msm_pm8018_regulator_pdata_len;
msm_device_otg.dev.platform_data = &msm_otg_pdata;
+ msm_otg_pdata.phy_init_seq = shelby_phy_init_seq;
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
acpuclk_init(&acpuclk_9615_soc_data);
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 1a085de..ebe884de 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -16,10 +16,48 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <asm/arch_timer.h>
#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
#include <mach/socinfo.h>
#include <mach/board.h>
-#include "timer.h"
+
+static void __init msm_dt_timer_init(void)
+{
+ struct device_node *node;
+ struct resource res;
+ struct of_irq oirq;
+
+ node = of_find_compatible_node(NULL, NULL, "qcom,msm-qtimer");
+ if (!node) {
+ pr_err("no matching timer node found\n");
+ return;
+ }
+
+ if (of_irq_map_one(node, 0, &oirq)) {
+ pr_err("interrupt not specified in timer node\n");
+ } else {
+ res.start = res.end = oirq.specifier[0];
+ res.flags = IORESOURCE_IRQ;
+ arch_timer_register(&res, 1);
+ }
+ of_node_put(node);
+}
+
+static struct sys_timer msm_dt_timer = {
+ .init = msm_dt_timer_init
+};
+
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+ return 0;
+}
+
+int local_timer_ack(void)
+{
+ return 1;
+}
static void __init msm_dt_init_irq(void)
{
@@ -56,6 +94,6 @@
.map_io = msm_dt_map_io,
.init_irq = msm_dt_init_irq,
.init_machine = msm_dt_init,
- .timer = &msm_timer,
+ .timer = &msm_dt_timer,
.dt_compat = msm_dt_match,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 6b3cad3..5de5ea3 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -3023,7 +3023,6 @@
gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_DISABLE);
- regulator_bulk_disable(ARRAY_SIZE(regs_atmel), regs_atmel);
regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
return 0;
}
diff --git a/arch/arm/mach-msm/board-msm7x30-regulator.c b/arch/arm/mach-msm/board-msm7x30-regulator.c
index edfcc6b..a3f5ee1 100644
--- a/arch/arm/mach-msm/board-msm7x30-regulator.c
+++ b/arch/arm/mach-msm/board-msm7x30-regulator.c
@@ -295,7 +295,7 @@
PCOM_VREG_LDO(ldo16, 35, NULL, 2600000, 2600000, 0, -1, 0, 0, 0, 0),
PCOM_VREG_LDO(ldo17, 36, NULL, 2600000, 2600000, 0, -1, 0, 0, 0, 0),
PCOM_VREG_LDO(ldo18, 37, NULL, 2200000, 2200000, 0, -1, 0, 0, 0, 0),
- PCOM_VREG_LDO(ldo19, 45, NULL, 2500000, 2500000, 0, -1, 0, 0, 0, 0),
+ PCOM_VREG_LDO(ldo19, 45, NULL, 2400000, 2500000, 0, -1, 0, 0, 0, 0),
PCOM_VREG_LDO(ldo20, 38, NULL, 1500000, 1800000, 0, -1, 0, 0, 0, 0),
PCOM_VREG_LDO(ldo21, 39, NULL, 1100000, 1100000, 0, -1, 0, 0, 0, 0),
PCOM_VREG_LDO(ldo22, 40, NULL, 1200000, 1300000, 0, -1, 0, 0, 0, 0),
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 36d6aab..3038ff0 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2622,7 +2622,7 @@
#define MSM_FB_EXT_BUFT_SIZE 0
#endif
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
/* width x height x 3 bpp x 2 frame buffer */
#define MSM_FB_WRITEBACK_SIZE (1024 * 600 * 3 * 2)
#define MSM_FB_WRITEBACK_OFFSET \
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index e814b4e..ad803f8 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1457,6 +1457,11 @@
.id = -1,
};
+struct platform_device msm_compr_dsp = {
+ .name = "msm-compr-dsp",
+ .id = -1,
+};
+
struct platform_device msm_pcm_hostless = {
.name = "msm-pcm-hostless",
.id = -1,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 147f01d..1ba63c9 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -171,6 +171,7 @@
extern struct platform_device msm_cpudai_afe_02_rx;
extern struct platform_device msm_cpudai_afe_02_tx;
extern struct platform_device msm_pcm_afe;
+extern struct platform_device msm_compr_dsp;
extern struct platform_device msm_8960_q6_lpass;
extern struct platform_device msm_8960_q6_mss_fw;
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index 98447fa..a8e2449 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -256,6 +256,14 @@
udelay(RESET_DELAY_US);
/*
+ * Return clocks to their state before this function. For robustness
+ * if memory-retention across collapses is required, clocks should
+ * be disabled before asserting the clamps. Assuming clocks were off
+ * before entering footswitch_disable(), this will be true.
+ */
+ restore_clocks(fs);
+
+ /*
* Clamp the I/O ports of the core to ensure the values
* remain fixed while the core is collapsed.
*/
@@ -266,9 +274,6 @@
regval &= ~ENABLE_BIT;
writel_relaxed(regval, fs->gfs_ctl_reg);
- /* Return clocks to their state before this function. */
- restore_clocks(fs);
-
fs->is_enabled = false;
return rc;
diff --git a/arch/arm/mach-msm/include/mach/irqs-copper.h b/arch/arm/mach-msm/include/mach/irqs-copper.h
index d019047..24da0a4 100644
--- a/arch/arm/mach-msm/include/mach/irqs-copper.h
+++ b/arch/arm/mach-msm/include/mach/irqs-copper.h
@@ -24,9 +24,6 @@
#define GIC_PPI_START 16
#define GIC_SPI_START 32
-#define INT_VGIC (GIC_PPI_START + 0)
-#define INT_DEBUG_TIMER_EXP (GIC_PPI_START + 1)
-#define INT_GP_TIMER_EXP (GIC_PPI_START + 2)
#define AVS_SVICINT (GIC_PPI_START + 6)
#define AVS_SVICINTSWDONE (GIC_PPI_START + 7)
#define INT_ARMQC_PERFMON (GIC_PPI_START + 10)
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
index b62b8cf..a3c9da8 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
@@ -32,12 +32,6 @@
#define COPPER_TLMM_PHYS 0xFD400000
#define COPPER_TLMM_SIZE SZ_16K
-#define COPPER_TMR_PHYS 0xF900A000
-#define COPPER_TMR_SIZE SZ_4K
-
-#define COPPER_TMR0_PHYS 0xF908A000
-#define COPPER_TMR0_SIZE SZ_4K
-
#ifdef CONFIG_DEBUG_MSMCOPPER_UART
#define MSM_DEBUG_UART_BASE IOMEM(0xFA71E000)
#define MSM_DEBUG_UART_PHYS 0xF991E000
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index 0c2cd4b..6d45b7d 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -209,7 +209,13 @@
SMEM_SMEM_LOG_MPROC_WRAP,
SMEM_BOOT_INFO_FOR_APPS,
SMEM_SMSM_SIZE_INFO,
- SMEM_MEM_LAST = SMEM_SMSM_SIZE_INFO,
+ SMEM_SMD_LOOPBACK_REGISTER,
+ SMEM_SSR_REASON_MSS0,
+ SMEM_SSR_REASON_WCNSS0,
+ SMEM_SSR_REASON_LPASS0,
+ SMEM_SSR_REASON_DSPS0,
+ SMEM_SSR_REASON_VCODEC0,
+ SMEM_MEM_LAST = SMEM_SSR_REASON_VCODEC0,
SMEM_NUM_ITEMS,
};
diff --git a/arch/arm/mach-msm/include/mach/sdio_tty.h b/arch/arm/mach-msm/include/mach/sdio_tty.h
deleted file mode 100644
index 86746b3..0000000
--- a/arch/arm/mach-msm/include/mach/sdio_tty.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* 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.
- */
-
-/*
- * SDIO TTY interface.
- */
-
-#ifndef __SDIO_TTY__
-#define __SDIO_TTY__
-
-/**
- * sdio_tty_init_tty - Initialize the SDIO TTY driver.
- *
- * @tty_name: tty name - identify the tty device.
- * @sdio_ch_name: channel name - identify the channel.
- * @return sdio_tty handle on success, NULL on error.
- *
- */
-void *sdio_tty_init_tty(char *tty_name, char* sdio_ch_name);
-
-/**
- * sdio_tty_uninit_tty - Uninitialize the SDIO TTY driver.
- *
- * @sdio_tty_handle: sdio_tty handle.
- * @return 0 on success, negative value on error.
- */
-int sdio_tty_uninit_tty(void *sdio_tty_handle);
-
-/**
- * sdio_tty_enable_debug_msg - Enable/Disable sdio_tty debug
- * messages.
- *
- * @enable: A flag to indicate if to enable or disable the debug
- * messages.
- * @return 0 on success, negative value on error.
- */
-void sdio_tty_enable_debug_msg(void *sdio_tty_handle, int enable);
-
-#endif /* __SDIO_TTY__ */
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index f09c6d9..2d5b0a4 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -284,8 +284,6 @@
MSM_CHIP_DEVICE(QGIC_DIST, COPPER),
MSM_CHIP_DEVICE(QGIC_CPU, COPPER),
MSM_CHIP_DEVICE(TLMM, COPPER),
- MSM_CHIP_DEVICE(TMR, COPPER),
- MSM_CHIP_DEVICE(TMR0, COPPER),
#ifdef CONFIG_DEBUG_MSMCOPPER_UART
MSM_DEVICE(DEBUG_UART),
#endif
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index f0aa13c..7345a89 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -149,9 +149,58 @@
smsm_reset_modem(SMSM_RESET);
}
-int modem_ramdump(int enable, const struct subsys_data *subsys)
+/* FIXME: Get address, size from PIL */
+static struct ramdump_segment modemsw_segments[] = {
+ {0x89000000, 0x8D400000 - 0x89000000},
+};
+
+static struct ramdump_segment modemfw_segments[] = {
+ {0x8D400000, 0x8DA00000 - 0x8D400000},
+};
+
+static struct ramdump_segment smem_segments[] = {
+ {0x80000000, 0x00200000},
+};
+
+static void *modemfw_ramdump_dev;
+static void *modemsw_ramdump_dev;
+static void *smem_ramdump_dev;
+
+static int modem_ramdump(int enable,
+ const struct subsys_data *crashed_subsys)
{
- return 0;
+ int ret = 0;
+
+ if (enable) {
+ ret = do_ramdump(modemsw_ramdump_dev, modemsw_segments,
+ ARRAY_SIZE(modemsw_segments));
+
+ if (ret < 0) {
+ pr_err("Unable to dump modem sw memory (rc = %d).\n",
+ ret);
+ goto out;
+ }
+
+ ret = do_ramdump(modemfw_ramdump_dev, modemfw_segments,
+ ARRAY_SIZE(modemfw_segments));
+
+ if (ret < 0) {
+ pr_err("Unable to dump modem fw memory (rc = %d).\n",
+ ret);
+ goto out;
+ }
+
+ ret = do_ramdump(smem_ramdump_dev, smem_segments,
+ ARRAY_SIZE(smem_segments));
+
+ if (ret < 0) {
+ pr_err("Unable to dump smem memory (rc = %d).\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ return ret;
}
static irqreturn_t modem_wdog_bite_irq(int irq, void *dev_id)
@@ -263,6 +312,33 @@
goto out;
}
+ modemfw_ramdump_dev = create_ramdump_device("modem_fw");
+
+ if (!modemfw_ramdump_dev) {
+ pr_err("%s: Unable to create modem fw ramdump device. (%d)\n",
+ __func__, -ENOMEM);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ modemsw_ramdump_dev = create_ramdump_device("modem_sw");
+
+ if (!modemsw_ramdump_dev) {
+ pr_err("%s: Unable to create modem sw ramdump device. (%d)\n",
+ __func__, -ENOMEM);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ smem_ramdump_dev = create_ramdump_device("smem");
+
+ if (!smem_ramdump_dev) {
+ pr_err("%s: Unable to create smem ramdump device. (%d)\n",
+ __func__, -ENOMEM);
+ ret = -ENOMEM;
+ goto out;
+ }
+
ret = modem_debugfs_init();
pr_info("%s: modem fatal driver init'ed.\n", __func__);
diff --git a/arch/arm/mach-msm/qdsp6v2/Makefile b/arch/arm/mach-msm/qdsp6v2/Makefile
index 7759c74..6d36495 100644
--- a/arch/arm/mach-msm/qdsp6v2/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/Makefile
@@ -17,3 +17,4 @@
obj-y += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o audio_utils.o
obj-y += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_utils_aio.o
obj-$(CONFIG_MSM_ULTRASOUND) += ultrasound/
+obj-y += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_evrc.o audio_qcelp.o amrwb_in.o
diff --git a/arch/arm/mach-msm/qdsp6v2/amrwb_in.c b/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
new file mode 100644
index 0000000..030d08f
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
@@ -0,0 +1,322 @@
+/* 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.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/msm_audio_amrwb.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <sound/apr_audio.h>
+#include <sound/q6asm.h>
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#include "audio_utils.h"
+
+/* Buffer with meta*/
+#define PCM_BUF_SIZE (4096 + sizeof(struct meta_in))
+
+/* Maximum 10 frames in buffer with meta */
+#define FRAME_SIZE (1 + ((61+sizeof(struct meta_out_dsp)) * 10))
+
+void q6asm_amrwb_in_cb(uint32_t opcode, uint32_t token,
+ uint32_t *payload, void *priv)
+{
+ struct q6audio_in * audio = (struct q6audio_in *)priv;
+ unsigned long flags;
+
+ pr_debug("%s:session id %d: opcode - %d\n", __func__,
+ audio->ac->session, opcode);
+
+ spin_lock_irqsave(&audio->dsp_lock, flags);
+ switch (opcode) {
+ case ASM_DATA_EVENT_READ_DONE:
+ audio_in_get_dsp_frames(audio, token, payload);
+ break;
+ case ASM_DATA_EVENT_WRITE_DONE:
+ atomic_inc(&audio->in_count);
+ wake_up(&audio->write_wait);
+ break;
+ case ASM_DATA_CMDRSP_EOS:
+ audio->eos_rsp = 1;
+ wake_up(&audio->read_wait);
+ break;
+ case ASM_STREAM_CMDRSP_GET_ENCDEC_PARAM:
+ break;
+ case ASM_STREAM_CMDRSP_GET_PP_PARAMS:
+ break;
+ case ASM_SESSION_EVENT_TX_OVERFLOW:
+ pr_err("%s:session id %d: ASM_SESSION_EVENT_TX_OVERFLOW\n",
+ __func__, audio->ac->session);
+ break;
+ default:
+ pr_err("%s:session id %d: Ignore opcode[0x%x]\n", __func__,
+ audio->ac->session, opcode);
+ break;
+ }
+ spin_unlock_irqrestore(&audio->dsp_lock, flags);
+}
+
+/* ------------------- device --------------------- */
+static long amrwb_in_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct q6audio_in *audio = file->private_data;
+ int rc = 0;
+ int cnt = 0;
+
+ switch (cmd) {
+ case AUDIO_START: {
+ struct msm_audio_amrwb_enc_config *enc_cfg;
+ enc_cfg = audio->enc_cfg;
+ pr_debug("%s:session id %d: default buf alloc[%d]\n", __func__,
+ audio->ac->session, audio->buf_alloc);
+ if (audio->enabled == 1) {
+ pr_info("%s:AUDIO_START already over\n", __func__);
+ rc = 0;
+ break;
+ }
+ rc = audio_in_buf_alloc(audio);
+ if (rc < 0) {
+ pr_err("%s:session id %d: buffer allocation failed\n",
+ __func__, audio->ac->session);
+ break;
+ }
+
+ rc = q6asm_enc_cfg_blk_amrwb(audio->ac,
+ audio->buf_cfg.frames_per_buf,
+ enc_cfg->band_mode,
+ enc_cfg->dtx_enable);
+
+ if (rc < 0) {
+ pr_err("%s:session id %d: cmd amrwb media format block"
+ "failed\n", __func__, audio->ac->session);
+ break;
+ }
+ if (audio->feedback == NON_TUNNEL_MODE) {
+ rc = q6asm_media_format_block_pcm(audio->ac,
+ audio->pcm_cfg.sample_rate,
+ audio->pcm_cfg.channel_count);
+
+ if (rc < 0) {
+ pr_err("%s:session id %d: media format block"
+ "failed\n", __func__, audio->ac->session);
+ break;
+ }
+ }
+ pr_debug("%s:session id %d: AUDIO_START enable[%d]\n",
+ __func__, audio->ac->session,
+ audio->enabled);
+ rc = audio_in_enable(audio);
+ if (!rc) {
+ audio->enabled = 1;
+ } else {
+ audio->enabled = 0;
+ pr_err("%s:session id %d: Audio Start procedure failed"
+ "rc=%d\n", __func__, audio->ac->session, rc);
+ break;
+ }
+ while (cnt++ < audio->str_cfg.buffer_count)
+ q6asm_read(audio->ac); /* Push buffer to DSP */
+ rc = 0;
+ pr_debug("%s:session id %d: AUDIO_START success enable[%d]\n",
+ __func__, audio->ac->session, audio->enabled);
+ break;
+ }
+ case AUDIO_STOP: {
+ pr_debug("%s:AUDIO_STOP\n", __func__);
+ rc = audio_in_disable(audio);
+ if (rc < 0) {
+ pr_err("%s:session id %d: Audio Stop procedure failed"
+ "rc=%d\n", __func__, audio->ac->session, rc);
+ break;
+ }
+ break;
+ }
+ case AUDIO_GET_AMRWB_ENC_CONFIG: {
+ if (copy_to_user((void *)arg, audio->enc_cfg,
+ sizeof(struct msm_audio_amrwb_enc_config)))
+ rc = -EFAULT;
+ break;
+ }
+ case AUDIO_SET_AMRWB_ENC_CONFIG: {
+ struct msm_audio_amrwb_enc_config cfg;
+ struct msm_audio_amrwb_enc_config *enc_cfg;
+ enc_cfg = audio->enc_cfg;
+ if (copy_from_user(&cfg, (void *) arg,
+ sizeof(struct msm_audio_amrwb_enc_config))) {
+ rc = -EFAULT;
+ break;
+ }
+ if (cfg.band_mode > 8) {
+ pr_err("%s:session id %d: invalid band mode\n",
+ __func__, audio->ac->session);
+ rc = -EINVAL;
+ break;
+ }
+ /* ToDo: AMR WB encoder accepts values between 0-8
+ while openmax provides value between 9-17
+ as per spec */
+ enc_cfg->band_mode = cfg.band_mode;
+ enc_cfg->dtx_enable = (cfg.dtx_enable ? 1 : 0);
+ /* Currently DSP does not support different frameformat */
+ enc_cfg->frame_format = 0;
+ pr_debug("%s:session id %d: band_mode = 0x%x dtx_enable=0x%x\n",
+ __func__, audio->ac->session,
+ enc_cfg->band_mode, enc_cfg->dtx_enable);
+ break;
+ }
+ default:
+ rc = -EINVAL;
+ }
+ return rc;
+}
+
+static int amrwb_in_open(struct inode *inode, struct file *file)
+{
+ struct q6audio_in *audio = NULL;
+ struct msm_audio_amrwb_enc_config *enc_cfg;
+ int rc = 0;
+
+ audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL);
+
+ if (audio == NULL) {
+ pr_err("%s:session id %d: Could not allocate memory for amrwb"
+ "driver\n", __func__, audio->ac->session);
+ return -ENOMEM;
+ }
+ /* Allocate memory for encoder config param */
+ audio->enc_cfg = kzalloc(sizeof(struct msm_audio_amrwb_enc_config),
+ GFP_KERNEL);
+ if (audio->enc_cfg == NULL) {
+ pr_err("%s:session id %d: Could not allocate memory for amrwb"
+ "config param\n", __func__, audio->ac->session);
+ kfree(audio);
+ return -ENOMEM;
+ }
+ enc_cfg = audio->enc_cfg;
+
+ mutex_init(&audio->lock);
+ mutex_init(&audio->read_lock);
+ mutex_init(&audio->write_lock);
+ spin_lock_init(&audio->dsp_lock);
+ init_waitqueue_head(&audio->read_wait);
+ init_waitqueue_head(&audio->write_wait);
+
+ /* Settings will be re-config at AUDIO_SET_CONFIG,
+ * but at least we need to have initial config
+ */
+ audio->str_cfg.buffer_size = FRAME_SIZE;
+ audio->str_cfg.buffer_count = FRAME_NUM;
+ audio->min_frame_size = 32;
+ audio->max_frames_per_buf = 10;
+ audio->pcm_cfg.buffer_size = PCM_BUF_SIZE;
+ audio->pcm_cfg.buffer_count = PCM_BUF_COUNT;
+ enc_cfg->band_mode = 8;
+ enc_cfg->dtx_enable = 0;
+ audio->pcm_cfg.channel_count = 1;
+ audio->pcm_cfg.sample_rate = 16000;
+ audio->buf_cfg.meta_info_enable = 0x01;
+ audio->buf_cfg.frames_per_buf = 0x01;
+
+ audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_amrwb_in_cb,
+ (void *)audio);
+
+ if (!audio->ac) {
+ pr_err("%s:session id %d: Could not allocate memory for audio"
+ "client\n", __func__, audio->ac->session);
+ kfree(audio->enc_cfg);
+ kfree(audio);
+ return -ENOMEM;
+ }
+
+ /* open amrwb encoder in T/NT mode */
+ if ((file->f_mode & FMODE_WRITE) &&
+ (file->f_mode & FMODE_READ)) {
+ audio->feedback = NON_TUNNEL_MODE;
+ rc = q6asm_open_read_write(audio->ac, FORMAT_AMRWB,
+ FORMAT_LINEAR_PCM);
+ if (rc < 0) {
+ pr_err("%s:session id %d: NT mode Open failed rc=%d\n",
+ __func__, audio->ac->session, rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ pr_info("%s:session id %d: NT mode encoder success\n",
+ __func__, audio->ac->session);
+ } else if (!(file->f_mode & FMODE_WRITE) &&
+ (file->f_mode & FMODE_READ)) {
+ audio->feedback = TUNNEL_MODE;
+ rc = q6asm_open_read(audio->ac, FORMAT_AMRWB);
+ if (rc < 0) {
+ pr_err("%s:session id %d: T mode Open failed rc=%d\n",
+ __func__, audio->ac->session, rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ /* register for tx overflow (valid for tunnel mode only) */
+ rc = q6asm_reg_tx_overflow(audio->ac, 0x01);
+ if (rc < 0) {
+ pr_err("%s:session id %d: TX Overflow registration"
+ "failed rc=%d\n", __func__, audio->ac->session,
+ rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ pr_info("%s:session id %d: T mode encoder success\n",
+ __func__, audio->ac->session);
+ } else {
+ pr_err("%s:session id %d: Unexpected mode\n", __func__,
+ audio->ac->session);
+ rc = -EACCES;
+ goto fail;
+ }
+
+ audio->opened = 1;
+ atomic_set(&audio->in_count, PCM_BUF_COUNT);
+ atomic_set(&audio->out_count, 0x00);
+ audio->enc_ioctl = amrwb_in_ioctl;
+ file->private_data = audio;
+
+ pr_info("%s:session id %d: success\n", __func__, audio->ac->session);
+ return 0;
+fail:
+ q6asm_audio_client_free(audio->ac);
+ kfree(audio->enc_cfg);
+ kfree(audio);
+ return rc;
+}
+
+static const struct file_operations audio_in_fops = {
+ .owner = THIS_MODULE,
+ .open = amrwb_in_open,
+ .release = audio_in_release,
+ .read = audio_in_read,
+ .write = audio_in_write,
+ .unlocked_ioctl = audio_in_ioctl,
+};
+
+struct miscdevice audio_amrwb_in_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "msm_amrwb_in",
+ .fops = &audio_in_fops,
+};
+
+static int __init amrwb_in_init(void)
+{
+ return misc_register(&audio_amrwb_in_misc);
+}
+
+device_initcall(amrwb_in_init);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
new file mode 100644
index 0000000..6768f7a
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
@@ -0,0 +1,179 @@
+/* amrnb audio output device
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "audio_utils_aio.h"
+
+static void q6_audio_amrnb_cb(uint32_t opcode, uint32_t token,
+ uint32_t *payload, void *priv)
+{
+ struct q6audio_aio *audio = (struct q6audio_aio *)priv;
+
+ pr_debug("%s:opcde = %d token = 0x%x\n", __func__, opcode, token);
+ switch (opcode) {
+ case ASM_DATA_EVENT_WRITE_DONE:
+ case ASM_DATA_EVENT_READ_DONE:
+ case ASM_DATA_CMDRSP_EOS:
+ audio_aio_cb(opcode, token, payload, audio);
+ break;
+ default:
+ pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode);
+ break;
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+static const struct file_operations audio_amrnb_debug_fops = {
+ .read = audio_aio_debug_read,
+ .open = audio_aio_debug_open,
+};
+#endif
+
+static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct q6audio_aio *audio = file->private_data;
+ int rc = 0;
+
+ switch (cmd) {
+ case AUDIO_START: {
+ pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__,
+ audio, audio->ac->session);
+ if (audio->feedback == NON_TUNNEL_MODE) {
+ /* Configure PCM output block */
+ rc = q6asm_enc_cfg_blk_pcm(audio->ac,
+ audio->pcm_cfg.sample_rate,
+ audio->pcm_cfg.channel_count);
+ if (rc < 0) {
+ pr_err("pcm output block config failed\n");
+ break;
+ }
+ }
+
+ rc = audio_aio_enable(audio);
+ audio->eos_rsp = 0;
+ audio->eos_flag = 0;
+ if (!rc) {
+ audio->enabled = 1;
+ } else {
+ audio->enabled = 0;
+ pr_err("Audio Start procedure failed rc=%d\n", rc);
+ break;
+ }
+ pr_debug("AUDIO_START success enable[%d]\n", audio->enabled);
+ if (audio->stopped == 1)
+ audio->stopped = 0;
+ break;
+ }
+ default:
+ pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
+ rc = audio->codec_ioctl(file, cmd, arg);
+ }
+ return rc;
+}
+
+static int audio_open(struct inode *inode, struct file *file)
+{
+ struct q6audio_aio *audio = NULL;
+ int rc = 0;
+
+#ifdef CONFIG_DEBUG_FS
+ /* 4 bytes represents decoder number, 1 byte for terminate string */
+ char name[sizeof "msm_amrnb_" + 5];
+#endif
+ audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL);
+
+ if (audio == NULL) {
+ pr_err("Could not allocate memory for wma decode driver\n");
+ return -ENOMEM;
+ }
+
+ audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN;
+
+ audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_amrnb_cb,
+ (void *)audio);
+
+ if (!audio->ac) {
+ pr_err("Could not allocate memory for audio client\n");
+ kfree(audio);
+ return -ENOMEM;
+ }
+
+ /* open in T/NT mode */
+ if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) {
+ rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM,
+ FORMAT_AMRNB);
+ if (rc < 0) {
+ pr_err("NT mode Open failed rc=%d\n", rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ audio->feedback = NON_TUNNEL_MODE;
+ audio->buf_cfg.frames_per_buf = 0x01;
+ audio->buf_cfg.meta_info_enable = 0x01;
+ } else if ((file->f_mode & FMODE_WRITE) &&
+ !(file->f_mode & FMODE_READ)) {
+ rc = q6asm_open_write(audio->ac, FORMAT_AMRNB);
+ if (rc < 0) {
+ pr_err("T mode Open failed rc=%d\n", rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ audio->feedback = TUNNEL_MODE;
+ audio->buf_cfg.meta_info_enable = 0x00;
+ } else {
+ pr_err("Not supported mode\n");
+ rc = -EACCES;
+ goto fail;
+ }
+ rc = audio_aio_open(audio, file);
+
+#ifdef CONFIG_DEBUG_FS
+ snprintf(name, sizeof name, "msm_amrnb_%04x", audio->ac->session);
+ audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
+ NULL, (void *)audio,
+ &audio_amrnb_debug_fops);
+
+ if (IS_ERR(audio->dentry))
+ pr_debug("debugfs_create_file failed\n");
+#endif
+ pr_info("%s:amrnb decoder open success, session_id = %d\n", __func__,
+ audio->ac->session);
+ return rc;
+fail:
+ q6asm_audio_client_free(audio->ac);
+ kfree(audio);
+ return rc;
+}
+
+static const struct file_operations audio_amrnb_fops = {
+ .owner = THIS_MODULE,
+ .open = audio_open,
+ .release = audio_aio_release,
+ .unlocked_ioctl = audio_ioctl,
+ .fsync = audio_aio_fsync,
+};
+
+struct miscdevice audio_amrnb_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "msm_amrnb",
+ .fops = &audio_amrnb_fops,
+};
+
+static int __init audio_amrnb_init(void)
+{
+ return misc_register(&audio_amrnb_misc);
+}
+
+device_initcall(audio_amrnb_init);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
new file mode 100644
index 0000000..f95e191
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
@@ -0,0 +1,182 @@
+/* amrwb audio output device
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "audio_utils_aio.h"
+
+static void q6_audio_amrwb_cb(uint32_t opcode, uint32_t token,
+ uint32_t *payload, void *priv)
+{
+ struct q6audio_aio *audio = (struct q6audio_aio *)priv;
+
+ pr_debug("%s:opcde = %d token = 0x%x\n", __func__, opcode, token);
+ switch (opcode) {
+ case ASM_DATA_EVENT_WRITE_DONE:
+ case ASM_DATA_EVENT_READ_DONE:
+ case ASM_DATA_CMDRSP_EOS:
+ audio_aio_cb(opcode, token, payload, audio);
+ break;
+ default:
+ pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode);
+ break;
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+static const struct file_operations audio_amrwb_debug_fops = {
+ .read = audio_aio_debug_read,
+ .open = audio_aio_debug_open,
+};
+#endif
+
+static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct q6audio_aio *audio = file->private_data;
+ int rc = 0;
+
+ switch (cmd) {
+ case AUDIO_START: {
+ pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__,
+ audio, audio->ac->session);
+ if (audio->feedback == NON_TUNNEL_MODE) {
+ /* Configure PCM output block */
+ rc = q6asm_enc_cfg_blk_pcm(audio->ac,
+ audio->pcm_cfg.sample_rate,
+ audio->pcm_cfg.channel_count);
+ if (rc < 0) {
+ pr_err("pcm output block config failed\n");
+ break;
+ }
+ }
+
+ rc = audio_aio_enable(audio);
+ audio->eos_rsp = 0;
+ audio->eos_flag = 0;
+ if (!rc) {
+ audio->enabled = 1;
+ } else {
+ audio->enabled = 0;
+ pr_err("Audio Start procedure failed rc=%d\n", rc);
+ break;
+ }
+ pr_debug("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__,
+ audio->ac->session,
+ audio->enabled);
+ if (audio->stopped == 1)
+ audio->stopped = 0;
+ break;
+ }
+ default:
+ pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
+ rc = audio->codec_ioctl(file, cmd, arg);
+ }
+ return rc;
+}
+
+static int audio_open(struct inode *inode, struct file *file)
+{
+ struct q6audio_aio *audio = NULL;
+ int rc = 0;
+
+#ifdef CONFIG_DEBUG_FS
+ /* 4 bytes represents decoder number, 1 byte for terminate string */
+ char name[sizeof "msm_amrwb_" + 5];
+#endif
+ audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL);
+
+ if (audio == NULL) {
+ pr_err("Could not allocate memory for aac decode driver\n");
+ return -ENOMEM;
+ }
+ audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN;
+
+ audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_amrwb_cb,
+ (void *)audio);
+
+ if (!audio->ac) {
+ pr_err("Could not allocate memory for audio client\n");
+ kfree(audio);
+ return -ENOMEM;
+ }
+
+ /* open in T/NT mode */
+ if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) {
+ rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM,
+ FORMAT_AMRWB);
+ if (rc < 0) {
+ pr_err("NT mode Open failed rc=%d\n", rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ audio->feedback = NON_TUNNEL_MODE;
+ audio->buf_cfg.frames_per_buf = 0x01;
+ audio->buf_cfg.meta_info_enable = 0x01;
+ } else if ((file->f_mode & FMODE_WRITE) &&
+ !(file->f_mode & FMODE_READ)) {
+ rc = q6asm_open_write(audio->ac, FORMAT_AMRWB);
+ if (rc < 0) {
+ pr_err("T mode Open failed rc=%d\n", rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ audio->feedback = TUNNEL_MODE;
+ audio->buf_cfg.meta_info_enable = 0x00;
+ } else {
+ pr_err("Not supported mode\n");
+ rc = -EACCES;
+ goto fail;
+ }
+ rc = audio_aio_open(audio, file);
+
+#ifdef CONFIG_DEBUG_FS
+ snprintf(name, sizeof name, "msm_amrwb_%04x", audio->ac->session);
+ audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
+ NULL, (void *)audio,
+ &audio_amrwb_debug_fops);
+
+ if (IS_ERR(audio->dentry))
+ pr_debug("debugfs_create_file failed\n");
+#endif
+ pr_info("%s: AMRWB dec success mode[%d]session[%d]\n", __func__,
+ audio->feedback,
+ audio->ac->session);
+ return 0;
+fail:
+ q6asm_audio_client_free(audio->ac);
+ kfree(audio);
+ return rc;
+}
+
+static const struct file_operations audio_amrwb_fops = {
+ .owner = THIS_MODULE,
+ .open = audio_open,
+ .release = audio_aio_release,
+ .unlocked_ioctl = audio_ioctl,
+ .fsync = audio_aio_fsync,
+};
+
+struct miscdevice audio_amrwb_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "msm_amrwb",
+ .fops = &audio_amrwb_fops,
+};
+
+static int __init audio_amrwb_init(void)
+{
+ return misc_register(&audio_amrwb_misc);
+}
+
+device_initcall(audio_amrwb_init);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_evrc.c b/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
new file mode 100644
index 0000000..12c815d
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
@@ -0,0 +1,186 @@
+/* evrc audio output device
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "audio_utils_aio.h"
+
+static void q6_audio_evrc_cb(uint32_t opcode, uint32_t token,
+ uint32_t *payload, void *priv)
+{
+ struct q6audio_aio *audio = (struct q6audio_aio *)priv;
+
+ pr_debug("%s:opcde = %d token = 0x%x\n", __func__, opcode, token);
+ switch (opcode) {
+ case ASM_DATA_EVENT_WRITE_DONE:
+ case ASM_DATA_EVENT_READ_DONE:
+ case ASM_DATA_CMDRSP_EOS:
+ audio_aio_cb(opcode, token, payload, audio);
+ break;
+ default:
+ pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode);
+ break;
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+static const struct file_operations audio_evrc_debug_fops = {
+ .read = audio_aio_debug_read,
+ .open = audio_aio_debug_open,
+};
+#endif
+
+static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct q6audio_aio *audio = file->private_data;
+ int rc = 0;
+
+ switch (cmd) {
+ case AUDIO_START: {
+ pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__,
+ audio, audio->ac->session);
+ if (audio->feedback == NON_TUNNEL_MODE) {
+ /* Configure PCM output block */
+ rc = q6asm_enc_cfg_blk_pcm(audio->ac,
+ audio->pcm_cfg.sample_rate,
+ audio->pcm_cfg.channel_count);
+ if (rc < 0) {
+ pr_err("pcm output block config failed\n");
+ break;
+ }
+ }
+
+ rc = audio_aio_enable(audio);
+ audio->eos_rsp = 0;
+ audio->eos_flag = 0;
+ if (!rc) {
+ audio->enabled = 1;
+ } else {
+ audio->enabled = 0;
+ pr_err("Audio Start procedure failed rc=%d\n", rc);
+ break;
+ }
+ pr_debug("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__,
+ audio->ac->session,
+ audio->enabled);
+ if (audio->stopped == 1)
+ audio->stopped = 0;
+ break;
+ }
+ default:
+ pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
+ rc = audio->codec_ioctl(file, cmd, arg);
+ }
+ return rc;
+}
+
+static int audio_open(struct inode *inode, struct file *file)
+{
+ struct q6audio_aio *audio = NULL;
+ int rc = 0;
+
+#ifdef CONFIG_DEBUG_FS
+ /* 4 bytes represents decoder number, 1 byte for terminate string */
+ char name[sizeof "msm_evrc_" + 5];
+#endif
+ audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL);
+
+ if (audio == NULL) {
+ pr_err("Could not allocate memory for aac decode driver\n");
+ return -ENOMEM;
+ }
+
+ /* Settings will be re-config at AUDIO_SET_CONFIG,
+ * but at least we need to have initial config
+ */
+ audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN;
+
+ audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_evrc_cb,
+ (void *)audio);
+
+ if (!audio->ac) {
+ pr_err("Could not allocate memory for audio client\n");
+ kfree(audio);
+ return -ENOMEM;
+ }
+
+ /* open in T/NT mode */
+ if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) {
+ rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM,
+ FORMAT_EVRC);
+ if (rc < 0) {
+ pr_err("NT mode Open failed rc=%d\n", rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ audio->feedback = NON_TUNNEL_MODE;
+ audio->buf_cfg.frames_per_buf = 0x01;
+ audio->buf_cfg.meta_info_enable = 0x01;
+ } else if ((file->f_mode & FMODE_WRITE) &&
+ !(file->f_mode & FMODE_READ)) {
+ rc = q6asm_open_write(audio->ac, FORMAT_EVRC);
+ if (rc < 0) {
+ pr_err("T mode Open failed rc=%d\n", rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ audio->feedback = TUNNEL_MODE;
+ audio->buf_cfg.meta_info_enable = 0x00;
+ } else {
+ pr_err("Not supported mode\n");
+ rc = -EACCES;
+ goto fail;
+ }
+ rc = audio_aio_open(audio, file);
+
+#ifdef CONFIG_DEBUG_FS
+ snprintf(name, sizeof name, "msm_evrc_%04x", audio->ac->session);
+ audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
+ NULL, (void *)audio,
+ &audio_evrc_debug_fops);
+
+ if (IS_ERR(audio->dentry))
+ pr_debug("debugfs_create_file failed\n");
+#endif
+ pr_info("%s:dec success mode[%d]session[%d]\n", __func__,
+ audio->feedback,
+ audio->ac->session);
+ return rc;
+fail:
+ q6asm_audio_client_free(audio->ac);
+ kfree(audio);
+ return rc;
+}
+
+static const struct file_operations audio_evrc_fops = {
+ .owner = THIS_MODULE,
+ .open = audio_open,
+ .release = audio_aio_release,
+ .unlocked_ioctl = audio_ioctl,
+ .fsync = audio_aio_fsync,
+};
+
+struct miscdevice audio_evrc_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "msm_evrc",
+ .fops = &audio_evrc_fops,
+};
+
+static int __init audio_evrc_init(void)
+{
+ return misc_register(&audio_evrc_misc);
+}
+
+device_initcall(audio_evrc_init);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mp3.c b/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
new file mode 100644
index 0000000..bb5dc96
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
@@ -0,0 +1,177 @@
+/* mp3 audio output device
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "audio_utils_aio.h"
+
+static void q6_audio_mp3_cb(uint32_t opcode, uint32_t token,
+ uint32_t *payload, void *priv)
+{
+ struct q6audio_aio *audio = (struct q6audio_aio *)priv;
+
+ pr_debug("%s:opcde = %d token = 0x%x\n", __func__, opcode, token);
+ switch (opcode) {
+ case ASM_DATA_EVENT_WRITE_DONE:
+ case ASM_DATA_EVENT_READ_DONE:
+ case ASM_DATA_CMDRSP_EOS:
+ audio_aio_cb(opcode, token, payload, audio);
+ break;
+ default:
+ pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode);
+ break;
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+static const struct file_operations audio_mp3_debug_fops = {
+ .read = audio_aio_debug_read,
+ .open = audio_aio_debug_open,
+};
+#endif
+
+static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct q6audio_aio *audio = file->private_data;
+ int rc = 0;
+ switch (cmd) {
+ case AUDIO_START: {
+ pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__,
+ audio, audio->ac->session);
+ if (audio->feedback == NON_TUNNEL_MODE) {
+ /* Configure PCM output block */
+ rc = q6asm_enc_cfg_blk_pcm(audio->ac,
+ audio->pcm_cfg.sample_rate,
+ audio->pcm_cfg.channel_count);
+ if (rc < 0) {
+ pr_err("pcm output block config failed\n");
+ break;
+ }
+ }
+
+ rc = audio_aio_enable(audio);
+ audio->eos_rsp = 0;
+ audio->eos_flag = 0;
+ if (!rc) {
+ audio->enabled = 1;
+ } else {
+ audio->enabled = 0;
+ pr_err("Audio Start procedure failed rc=%d\n", rc);
+ break;
+ }
+ pr_info("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__,
+ audio->ac->session,
+ audio->enabled);
+ if (audio->stopped == 1)
+ audio->stopped = 0;
+ break;
+ }
+ default:
+ pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
+ rc = audio->codec_ioctl(file, cmd, arg);
+ }
+ return rc;
+}
+
+static int audio_open(struct inode *inode, struct file *file)
+{
+ struct q6audio_aio *audio = NULL;
+ int rc = 0;
+
+#ifdef CONFIG_DEBUG_FS
+ /* 4 bytes represents decoder number, 1 byte for terminate string */
+ char name[sizeof "msm_mp3_" + 5];
+#endif
+ audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL);
+
+ if (audio == NULL) {
+ pr_err("Could not allocate memory for mp3 decode driver\n");
+ return -ENOMEM;
+ }
+
+ audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN;
+
+ audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_mp3_cb,
+ (void *)audio);
+
+ if (!audio->ac) {
+ pr_err("Could not allocate memory for audio client\n");
+ kfree(audio);
+ return -ENOMEM;
+ }
+
+ /* open in T/NT mode */
+ if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) {
+ rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM,
+ FORMAT_MP3);
+ if (rc < 0) {
+ pr_err("NT mode Open failed rc=%d\n", rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ audio->feedback = NON_TUNNEL_MODE;
+ /* open MP3 decoder, expected frames is always 1
+ audio->buf_cfg.frames_per_buf = 0x01;*/
+ audio->buf_cfg.meta_info_enable = 0x01;
+ } else if ((file->f_mode & FMODE_WRITE) &&
+ !(file->f_mode & FMODE_READ)) {
+ pr_err("%s: Tunnel Mode not supported\n", __func__);
+ return -EACCES;
+ } else {
+ pr_err("Not supported mode\n");
+ rc = -EACCES;
+ goto fail;
+ }
+ rc = audio_aio_open(audio, file);
+
+#ifdef CONFIG_DEBUG_FS
+ snprintf(name, sizeof name, "msm_mp3_%04x", audio->ac->session);
+ audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
+ NULL, (void *)audio,
+ &audio_mp3_debug_fops);
+
+ if (IS_ERR(audio->dentry))
+ pr_debug("debugfs_create_file failed\n");
+#endif
+ pr_info("%s:mp3dec success mode[%d]session[%d]\n", __func__,
+ audio->feedback,
+ audio->ac->session);
+ return rc;
+fail:
+ q6asm_audio_client_free(audio->ac);
+ kfree(audio);
+ return rc;
+}
+
+static const struct file_operations audio_mp3_fops = {
+ .owner = THIS_MODULE,
+ .open = audio_open,
+ .release = audio_aio_release,
+ .unlocked_ioctl = audio_ioctl,
+ .fsync = audio_aio_fsync,
+};
+
+struct miscdevice audio_mp3_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "msm_mp3",
+ .fops = &audio_mp3_fops,
+};
+
+static int __init audio_mp3_init(void)
+{
+ return misc_register(&audio_mp3_misc);
+}
+
+device_initcall(audio_mp3_init);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
new file mode 100644
index 0000000..7b72c97
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
@@ -0,0 +1,192 @@
+/* qcelp(v13k) audio output device
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "audio_utils_aio.h"
+
+#define FRAME_SIZE_DEC_QCELP ((32) + sizeof(struct dec_meta_in))
+
+static void q6_audio_qcelp_cb(uint32_t opcode, uint32_t token,
+ uint32_t *payload, void *priv)
+{
+ struct q6audio_aio *audio = (struct q6audio_aio *)priv;
+
+ switch (opcode) {
+ case ASM_DATA_EVENT_WRITE_DONE:
+ case ASM_DATA_EVENT_READ_DONE:
+ case ASM_DATA_CMDRSP_EOS:
+ audio_aio_cb(opcode, token, payload, audio);
+ break;
+ default:
+ pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode);
+ break;
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+static const struct file_operations audio_qcelp_debug_fops = {
+ .read = audio_aio_debug_read,
+ .open = audio_aio_debug_open,
+};
+#endif
+
+static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct q6audio_aio *audio = file->private_data;
+ int rc = 0;
+
+ switch (cmd) {
+ case AUDIO_START: {
+ pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__,
+ audio, audio->ac->session);
+ if (audio->feedback == NON_TUNNEL_MODE) {
+ /* Configure PCM output block */
+ rc = q6asm_enc_cfg_blk_pcm(audio->ac,
+ audio->pcm_cfg.sample_rate,
+ audio->pcm_cfg.channel_count);
+ if (rc < 0) {
+ pr_err("pcm output block config failed\n");
+ break;
+ }
+ }
+
+ rc = audio_aio_enable(audio);
+ audio->eos_rsp = 0;
+ audio->eos_flag = 0;
+ if (!rc) {
+ audio->enabled = 1;
+ } else {
+ audio->enabled = 0;
+ pr_err("Audio Start procedure failed rc=%d\n", rc);
+ break;
+ }
+ pr_debug("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__,
+ audio->ac->session,
+ audio->enabled);
+ if (audio->stopped == 1)
+ audio->stopped = 0;
+ break;
+ }
+ default:
+ pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
+ rc = audio->codec_ioctl(file, cmd, arg);
+ }
+ return rc;
+}
+
+static int audio_open(struct inode *inode, struct file *file)
+{
+ struct q6audio_aio *audio = NULL;
+ int rc = 0;
+
+#ifdef CONFIG_DEBUG_FS
+ /* 4 bytes represents decoder number, 1 byte for terminate string */
+ char name[sizeof "msm_qcelp_" + 5];
+#endif
+ audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL);
+
+ if (audio == NULL) {
+ pr_err("Could not allocate memory for aac decode driver\n");
+ return -ENOMEM;
+ }
+
+ /* Settings will be re-config at AUDIO_SET_CONFIG,
+ * but at least we need to have initial config
+ */
+ audio->str_cfg.buffer_size = FRAME_SIZE_DEC_QCELP;
+ audio->str_cfg.buffer_count = FRAME_NUM;
+ audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN;
+ audio->pcm_cfg.buffer_count = PCM_BUF_COUNT;
+ audio->pcm_cfg.sample_rate = 8000;
+ audio->pcm_cfg.channel_count = 1;
+
+ audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_qcelp_cb,
+ (void *)audio);
+
+ if (!audio->ac) {
+ pr_err("Could not allocate memory for audio client\n");
+ kfree(audio);
+ return -ENOMEM;
+ }
+
+ /* open in T/NT mode */
+ if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) {
+ rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM,
+ FORMAT_V13K);
+ if (rc < 0) {
+ pr_err("NT mode Open failed rc=%d\n", rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ audio->feedback = NON_TUNNEL_MODE;
+ audio->buf_cfg.frames_per_buf = 0x01;
+ audio->buf_cfg.meta_info_enable = 0x01;
+ } else if ((file->f_mode & FMODE_WRITE) &&
+ !(file->f_mode & FMODE_READ)) {
+ rc = q6asm_open_write(audio->ac, FORMAT_V13K);
+ if (rc < 0) {
+ pr_err("T mode Open failed rc=%d\n", rc);
+ rc = -ENODEV;
+ goto fail;
+ }
+ audio->feedback = TUNNEL_MODE;
+ audio->buf_cfg.meta_info_enable = 0x00;
+ } else {
+ pr_err("Not supported mode\n");
+ rc = -EACCES;
+ goto fail;
+ }
+ rc = audio_aio_open(audio, file);
+
+#ifdef CONFIG_DEBUG_FS
+ snprintf(name, sizeof name, "msm_qcelp_%04x", audio->ac->session);
+ audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
+ NULL, (void *)audio,
+ &audio_qcelp_debug_fops);
+
+ if (IS_ERR(audio->dentry))
+ pr_debug("debugfs_create_file failed\n");
+#endif
+ pr_info("%s:dec success mode[%d]session[%d]\n", __func__,
+ audio->feedback,
+ audio->ac->session);
+ return 0;
+fail:
+ q6asm_audio_client_free(audio->ac);
+ kfree(audio);
+ return rc;
+}
+
+static const struct file_operations audio_qcelp_fops = {
+ .owner = THIS_MODULE,
+ .open = audio_open,
+ .release = audio_aio_release,
+ .unlocked_ioctl = audio_ioctl,
+ .fsync = audio_aio_fsync,
+};
+
+struct miscdevice audio_qcelp_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "msm_qcelp",
+ .fops = &audio_qcelp_fops,
+};
+
+static int __init audio_qcelp_init(void)
+{
+ return misc_register(&audio_qcelp_misc);
+}
+
+device_initcall(audio_qcelp_init);
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
index 8b9abcf..a71aae3 100644
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ b/arch/arm/mach-msm/sdio_al_test.c
@@ -298,6 +298,7 @@
uint32_t smem_counter;
struct platform_device *ciq_app_pdev;
+ struct platform_device *csvt_app_pdev;
wait_queue_head_t wait_q;
int test_completed;
@@ -6162,7 +6163,7 @@
int ret;
pr_debug(TEST_MODULE_NAME ":%s.\n", __func__);
- pr_info(TEST_MODULE_NAME ": init test cahnnel %s.\n", name);
+ pr_info(TEST_MODULE_NAME ": init test channel %s.\n", name);
ch_id = channel_name_to_id(name);
pr_debug(TEST_MODULE_NAME ":id = %d.\n", ch_id);
@@ -6324,6 +6325,35 @@
return sdio_test_channel_remove(pdev);
}
+static int sdio_test_channel_csvt_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ if (!pdev)
+ return -ENODEV;
+
+ test_ctx->csvt_app_pdev = platform_device_alloc("SDIO_CSVT_TEST_APP",
+ -1);
+ ret = platform_device_add(test_ctx->csvt_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_csvt_remove(struct platform_device *pdev)
+{
+ if (!pdev)
+ return -ENODEV;
+
+ platform_device_unregister(test_ctx->csvt_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,
@@ -6388,8 +6418,8 @@
};
static struct platform_driver sdio_csvt_drv = {
- .probe = sdio_test_channel_probe,
- .remove = sdio_test_channel_remove,
+ .probe = sdio_test_channel_csvt_probe,
+ .remove = sdio_test_channel_csvt_remove,
.driver = {
.name = "SDIO_CSVT_TEST",
.owner = THIS_MODULE,
diff --git a/arch/arm/mach-msm/sdio_tty.c b/arch/arm/mach-msm/sdio_tty.c
index fca88d8..e249d06 100644
--- a/arch/arm/mach-msm/sdio_tty.c
+++ b/arch/arm/mach-msm/sdio_tty.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
+#include <linux/module.h>
#include <mach/sdio_al.h>
#define INPUT_SPEED 4800
@@ -24,6 +25,19 @@
#define SDIO_TTY_MODULE_NAME "sdio_tty"
#define SDIO_TTY_MAX_PACKET_SIZE 4096
#define MAX_SDIO_TTY_DRV 1
+#define MAX_SDIO_TTY_DEVS 2
+#define MAX_SDIO_TTY_DEV_NAME_SIZE 25
+
+/* Configurations per channel device */
+/* CIQ */
+#define SDIO_TTY_CIQ_DEV "sdio_tty_ciq_0"
+#define SDIO_TTY_CIQ_TEST_DEV "sdio_tty_ciq_test_0"
+#define SDIO_TTY_CH_CIQ "SDIO_CIQ"
+
+/* CSVT */
+#define SDIO_TTY_CSVT_DEV "sdio_tty_csvt_0"
+#define SDIO_TTY_CSVT_TEST_DEV "sdio_tty_csvt_test_0"
+#define SDIO_TTY_CH_CSVT "SDIO_CSVT"
enum sdio_tty_state {
TTY_INITIAL = 0,
@@ -32,9 +46,27 @@
TTY_CLOSED = 3,
};
+enum sdio_tty_devices {
+ SDIO_CIQ,
+ SDIO_CIQ_TEST_APP,
+ SDIO_CSVT,
+ SDIO_CSVT_TEST_APP,
+};
+
+static const struct platform_device_id sdio_tty_id_table[] = {
+ { "SDIO_CIQ", SDIO_CIQ },
+ { "SDIO_CIQ_TEST_APP", SDIO_CIQ_TEST_APP },
+ { "SDIO_CSVT", SDIO_CSVT },
+ { "SDIO_CSVT_TEST_APP", SDIO_CSVT_TEST_APP },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, sdio_tty_id_table);
+
struct sdio_tty {
struct sdio_channel *ch;
char *sdio_ch_name;
+ char tty_dev_name[MAX_SDIO_TTY_DEV_NAME_SIZE];
+ int device_id;
struct workqueue_struct *workq;
struct work_struct work_read;
wait_queue_head_t waitq;
@@ -44,11 +76,21 @@
char *read_buf;
enum sdio_tty_state sdio_tty_state;
int is_sdio_open;
+ int tty_open_count;
};
-static struct sdio_tty *sdio_tty;
+static struct sdio_tty *sdio_tty[MAX_SDIO_TTY_DEVS];
-#define DEBUG_MSG(sdio_tty, x...) if (sdio_tty->debug_msg_on) pr_info(x)
+#define DEBUG_MSG(sdio_tty_drv, x...) if (sdio_tty_drv->debug_msg_on) pr_info(x)
+
+/*
+ * Enable sdio_tty debug messages
+ * By default the sdio_tty debug messages are turned off
+ */
+static int ciq_debug_msg_on;
+module_param(ciq_debug_msg_on, int, 0);
+static int csvt_debug_msg_on;
+module_param(csvt_debug_msg_on, int, 0);
static void sdio_tty_read(struct work_struct *work)
{
@@ -62,30 +104,30 @@
sdio_tty_drv = container_of(work, struct sdio_tty, work_read);
if (!sdio_tty_drv) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty",
- __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty", __func__);
return ;
}
if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
- __func__, sdio_tty_drv->sdio_tty_state);
+ __func__, sdio_tty_drv->sdio_tty_state);
return;
}
if (!sdio_tty_drv->read_buf) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL read_buf", __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL read_buf for dev %s",
+ __func__, sdio_tty_drv->tty_dev_name);
return;
}
- /* Read the data from teh SDIO channel as long as there is available
+ /* Read the data from the SDIO channel as long as there is available
data */
while (1) {
if (test_bit(TTY_THROTTLED, &sdio_tty_drv->tty_str->flags)) {
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: TTY_THROTTLED bit"
- " is set, exit",
- __func__);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
+ ": %s: TTY_THROTTLED bit is set for "
+ "dev %s, exit", __func__,
+ sdio_tty_drv->tty_dev_name);
return;
}
@@ -93,20 +135,22 @@
read_avail = sdio_read_avail(sdio_tty_drv->ch);
DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
- ": %s: read_avail is %d", __func__,
- read_avail);
+ ": %s: read_avail is %d for dev %s", __func__,
+ read_avail, sdio_tty_drv->tty_dev_name);
if (read_avail == 0) {
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: read_avail is 0",
- __func__);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
+ ": %s: read_avail is 0 for dev %s",
+ __func__, sdio_tty_drv->tty_dev_name);
return;
}
if (read_avail > SDIO_TTY_MAX_PACKET_SIZE) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: read_avail(%d) is "
- "bigger than SDIO_TTY_MAX_PACKET_SIZE(%d)",
- __func__, read_avail, SDIO_TTY_MAX_PACKET_SIZE);
+ "bigger than SDIO_TTY_MAX_PACKET_SIZE(%d) "
+ "for dev %s", __func__, read_avail,
+ SDIO_TTY_MAX_PACKET_SIZE,
+ sdio_tty_drv->tty_dev_name);
return;
}
@@ -114,8 +158,9 @@
sdio_tty_drv->read_buf,
read_avail);
if (ret < 0) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_read error(%d)",
- __func__, ret);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_read error(%d) "
+ "for dev %s", __func__, ret,
+ sdio_tty_drv->tty_dev_name);
return;
}
@@ -132,15 +177,17 @@
if (total_push != read_avail) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: failed, total_push"
- "(%d) != read_avail(%d)\n",
- __func__, total_push, read_avail);
+ "(%d) != read_avail(%d) for dev %s\n",
+ __func__, total_push, read_avail,
+ sdio_tty_drv->tty_dev_name);
}
tty_flip_buffer_push(sdio_tty_drv->tty_str);
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: End of read %d bytes",
- __func__, read_avail);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
+ ": %s: End of read %d bytes for dev %s",
+ __func__, read_avail,
+ sdio_tty_drv->tty_dev_name);
}
}
@@ -159,27 +206,26 @@
struct sdio_tty *sdio_tty_drv = NULL;
if (!tty) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
- __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
return -ENODEV;
}
sdio_tty_drv = tty->driver_data;
if (!sdio_tty_drv) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
- __func__);
+ __func__);
return -ENODEV;
}
if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
- __func__, sdio_tty_drv->sdio_tty_state);
+ __func__, sdio_tty_drv->sdio_tty_state);
return -EPERM;
}
write_avail = sdio_write_avail(sdio_tty_drv->ch);
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: write_avail=%d",
- __func__, write_avail);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: write_avail=%d "
+ "for dev %s", __func__, write_avail,
+ sdio_tty_drv->tty_dev_name);
return write_avail;
}
@@ -205,60 +251,60 @@
struct sdio_tty *sdio_tty_drv = NULL;
if (!tty) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
- __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
return -ENODEV;
}
sdio_tty_drv = tty->driver_data;
if (!sdio_tty_drv) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
- __func__);
+ __func__);
return -ENODEV;
}
if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
- __func__, sdio_tty_drv->sdio_tty_state);
+ __func__, sdio_tty_drv->sdio_tty_state);
return -EPERM;
}
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: WRITING CALLBACK CALLED WITH "
- "%d bytes\n",
- __func__, count);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Write Callback "
+ "called with %d bytes for dev %s\n", __func__, count,
+ sdio_tty_drv->tty_dev_name);
write_avail = sdio_write_avail(sdio_tty_drv->ch);
if (write_avail == 0) {
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: write_avail is 0\n",
- __func__);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
+ "write_avail is 0 for dev %s\n",
+ __func__, sdio_tty_drv->tty_dev_name);
return 0;
}
if (write_avail > SDIO_TTY_MAX_PACKET_SIZE) {
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: write_avail(%d) is "
- "bigger than max packet size,(%d), setting to "
- "max_packet_size\n",
- __func__, write_avail, SDIO_TTY_MAX_PACKET_SIZE);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
+ "write_avail(%d) is bigger than max packet "
+ "size(%d) for dev %s, setting to "
+ "max_packet_size\n", __func__, write_avail,
+ SDIO_TTY_MAX_PACKET_SIZE,
+ sdio_tty_drv->tty_dev_name);
write_avail = SDIO_TTY_MAX_PACKET_SIZE;
}
if (write_avail < count) {
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: write_avail(%d) is "
- "smaller than "
- "required(%d), writing only %d bytes\n",
- __func__, write_avail, count, write_avail);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
+ "write_avail(%d) is smaller than required(%d) "
+ "for dev %s, writing only %d bytes\n",
+ __func__, write_avail, count,
+ sdio_tty_drv->tty_dev_name, write_avail);
len = write_avail;
}
ret = sdio_write(sdio_tty_drv->ch, buf, len);
if (ret) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_write failed, ret=%d\n",
- __func__, ret);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_write failed for "
+ "dev %s, ret=%d\n", __func__,
+ sdio_tty_drv->tty_dev_name, ret);
return 0;
}
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: End of function, len=%d bytes\n",
- __func__, len);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: End of function, "
+ "dev=%s, len=%d bytes\n", __func__,
+ sdio_tty_drv->tty_dev_name, len);
return len;
}
@@ -269,18 +315,18 @@
if (!sdio_tty_drv) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
- __func__);
+ __func__);
}
if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
- __func__, sdio_tty_drv->sdio_tty_state);
+ __func__, sdio_tty_drv->sdio_tty_state);
return;
}
- DEBUG_MSG(sdio_tty_drv,
- SDIO_TTY_MODULE_NAME ": %s: event %d received\n", __func__,
- event);
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: event %d "
+ "received for dev %s\n", __func__, event,
+ sdio_tty_drv->tty_dev_name);
if (event == SDIO_EVENT_DATA_READ_AVAIL)
queue_work(sdio_tty_drv->workq, &sdio_tty_drv->work_read);
@@ -298,20 +344,37 @@
static int sdio_tty_open(struct tty_struct *tty, struct file *file)
{
int ret = 0;
+ int i = 0;
struct sdio_tty *sdio_tty_drv = NULL;
if (!tty) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
- __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
return -ENODEV;
}
- sdio_tty_drv = sdio_tty;
+
+ for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
+ if (sdio_tty[i] == NULL)
+ continue;
+ if (!strncmp(sdio_tty[i]->tty_dev_name, tty->name,
+ MAX_SDIO_TTY_DEV_NAME_SIZE)) {
+ sdio_tty_drv = sdio_tty[i];
+ break;
+ }
+ }
+
if (!sdio_tty_drv) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
__func__);
return -ENODEV;
}
+ sdio_tty_drv->tty_open_count++;
+ if (sdio_tty_drv->sdio_tty_state == TTY_OPENED) {
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: tty dev(%s) is already open",
+ __func__, sdio_tty_drv->tty_dev_name);
+ return -EBUSY;
+ }
+
tty->driver_data = sdio_tty_drv;
sdio_tty_drv->tty_str = tty;
@@ -321,36 +384,31 @@
sdio_tty_drv->read_buf = kzalloc(SDIO_TTY_MAX_PACKET_SIZE, GFP_KERNEL);
if (sdio_tty_drv->read_buf == NULL) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate read_buf",
- __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate read_buf "
+ "for dev %s", __func__, sdio_tty_drv->tty_dev_name);
return -ENOMEM;
}
sdio_tty_drv->workq = create_singlethread_workqueue("sdio_tty_read");
if (!sdio_tty_drv->workq) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to create workq",
- __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to create workq "
+ "for dev %s", __func__, sdio_tty_drv->tty_dev_name);
return -ENOMEM;
}
- if (sdio_tty_drv->sdio_tty_state == TTY_OPENED) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: tty is already open",
- __func__);
- return -EBUSY;
- }
-
if (!sdio_tty_drv->is_sdio_open) {
ret = sdio_open(sdio_tty_drv->sdio_ch_name, &sdio_tty_drv->ch,
sdio_tty_drv, sdio_tty_notify);
if (ret < 0) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_open err=%d\n",
- __func__, ret);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_open err=%d "
+ "for dev %s\n", __func__, ret,
+ sdio_tty_drv->tty_dev_name);
destroy_workqueue(sdio_tty_drv->workq);
return ret;
}
- pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel opened\n",
- __func__);
+ pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel(%s) opened "
+ "\n", __func__, sdio_tty_drv->sdio_ch_name);
sdio_tty_drv->is_sdio_open = 1;
} else {
@@ -363,8 +421,8 @@
sdio_tty_drv->sdio_tty_state = TTY_OPENED;
- pr_info(SDIO_TTY_MODULE_NAME ": %s: TTY device opened\n",
- __func__);
+ pr_info(SDIO_TTY_MODULE_NAME ": %s: TTY device(%s) opened\n",
+ __func__, sdio_tty_drv->tty_dev_name);
return ret;
}
@@ -385,8 +443,7 @@
struct sdio_tty *sdio_tty_drv = NULL;
if (!tty) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
- __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
return;
}
sdio_tty_drv = tty->driver_data;
@@ -397,10 +454,11 @@
}
if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: trying to close a "
- "TTY device that was not opened\n",
- __func__);
+ "TTY device that was not opened\n", __func__);
return;
}
+ if (--sdio_tty_drv->tty_open_count != 0)
+ return;
flush_workqueue(sdio_tty_drv->workq);
destroy_workqueue(sdio_tty_drv->workq);
@@ -410,8 +468,8 @@
sdio_tty_drv->sdio_tty_state = TTY_CLOSED;
- pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel closed\n",
- __func__);
+ pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY device(%s) closed\n",
+ __func__, sdio_tty_drv->tty_dev_name);
}
static void sdio_tty_unthrottle(struct tty_struct *tty)
@@ -419,8 +477,7 @@
struct sdio_tty *sdio_tty_drv = NULL;
if (!tty) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
- __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
return;
}
sdio_tty_drv = tty->driver_data;
@@ -448,33 +505,53 @@
.unthrottle = sdio_tty_unthrottle,
};
-void *sdio_tty_init_tty(char *tty_name, char *sdio_ch_name)
+int sdio_tty_init_tty(char *tty_name, char *sdio_ch_name,
+ enum sdio_tty_devices device_id, int debug_msg_on)
{
int ret = 0;
- struct device *tty_dev;
- struct sdio_tty *sdio_tty_drv;
-
- pr_info(SDIO_TTY_MODULE_NAME ": %s\n", __func__);
+ int i = 0;
+ struct device *tty_dev = NULL;
+ struct sdio_tty *sdio_tty_drv = NULL;
sdio_tty_drv = kzalloc(sizeof(struct sdio_tty), GFP_KERNEL);
if (sdio_tty_drv == NULL) {
- pr_err(SDIO_TTY_MODULE_NAME "%s: failed to allocate sdio_tty",
- __func__);
- return NULL;
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate sdio_tty "
+ "for dev %s", __func__, tty_name);
+ return -ENOMEM;
}
- sdio_tty = sdio_tty_drv;
+ for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
+ if (sdio_tty[i] == NULL) {
+ sdio_tty[i] = sdio_tty_drv;
+ break;
+ }
+ }
+
+ if (i == MAX_SDIO_TTY_DEVS) {
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: tty dev(%s) creation failed,"
+ " max limit(%d) reached.", __func__, tty_name,
+ MAX_SDIO_TTY_DEVS);
+ kfree(sdio_tty_drv);
+ return -ENODEV;
+ }
+
+ snprintf(sdio_tty_drv->tty_dev_name, MAX_SDIO_TTY_DEV_NAME_SIZE,
+ "%s%d", tty_name, 0);
sdio_tty_drv->sdio_ch_name = sdio_ch_name;
+ sdio_tty_drv->device_id = device_id;
+ pr_info(SDIO_TTY_MODULE_NAME ": %s: dev=%s, id=%d, channel=%s\n",
+ __func__, sdio_tty_drv->tty_dev_name, sdio_tty_drv->device_id,
+ sdio_tty_drv->sdio_ch_name);
INIT_WORK(&sdio_tty_drv->work_read, sdio_tty_read);
sdio_tty_drv->tty_drv = alloc_tty_driver(MAX_SDIO_TTY_DRV);
if (!sdio_tty_drv->tty_drv) {
- pr_err(SDIO_TTY_MODULE_NAME ": %s - tty_drv is NULL",
- __func__);
+ pr_err(SDIO_TTY_MODULE_NAME ": %s - tty_drv is NULL for dev %s",
+ __func__, sdio_tty_drv->tty_dev_name);
kfree(sdio_tty_drv);
- return NULL;
+ return -ENODEV;
}
sdio_tty_drv->tty_drv->name = tty_name;
@@ -500,31 +577,38 @@
if (ret) {
put_tty_driver(sdio_tty_drv->tty_drv);
pr_err(SDIO_TTY_MODULE_NAME ": %s: tty_register_driver() "
- "failed\n", __func__);
+ "failed for dev %s\n", __func__,
+ sdio_tty_drv->tty_dev_name);
sdio_tty_drv->tty_drv = NULL;
kfree(sdio_tty_drv);
- return NULL;
+ return -ENODEV;
}
tty_dev = tty_register_device(sdio_tty_drv->tty_drv, 0, NULL);
if (IS_ERR(tty_dev)) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: tty_register_device() "
- "failed\n", __func__);
+ "failed for dev %s\n", __func__,
+ sdio_tty_drv->tty_dev_name);
tty_unregister_driver(sdio_tty_drv->tty_drv);
put_tty_driver(sdio_tty_drv->tty_drv);
kfree(sdio_tty_drv);
- return NULL;
+ return -ENODEV;
}
sdio_tty_drv->sdio_tty_state = TTY_REGISTERED;
- return sdio_tty_drv;
+ if (debug_msg_on) {
+ pr_info(SDIO_TTY_MODULE_NAME ": %s: turn on debug msg for %s",
+ __func__, sdio_tty_drv->tty_dev_name);
+ sdio_tty_drv->debug_msg_on = debug_msg_on;
+ }
+ return 0;
}
-EXPORT_SYMBOL(sdio_tty_init_tty);
int sdio_tty_uninit_tty(void *sdio_tty_handle)
{
int ret = 0;
+ int i = 0;
struct sdio_tty *sdio_tty_drv = sdio_tty_handle;
if (!sdio_tty_drv) {
@@ -546,51 +630,151 @@
ret = tty_unregister_driver(sdio_tty_drv->tty_drv);
if (ret) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: "
- "tty_unregister_driver() failed\n", __func__);
+ "tty_unregister_driver() failed for dev %s\n",
+ __func__, sdio_tty_drv->tty_dev_name);
}
put_tty_driver(sdio_tty_drv->tty_drv);
sdio_tty_drv->sdio_tty_state = TTY_INITIAL;
sdio_tty_drv->tty_drv = NULL;
}
- pr_info(SDIO_TTY_MODULE_NAME ": %s: Freeing sdio_tty structure",
- __func__);
+ for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
+ if (sdio_tty[i] == NULL)
+ continue;
+ if (sdio_tty[i]->device_id == sdio_tty_drv->device_id) {
+ sdio_tty[i] = NULL;
+ break;
+ }
+ }
+
+ DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Freeing sdio_tty "
+ "structure, dev=%s", __func__,
+ sdio_tty_drv->tty_dev_name);
kfree(sdio_tty_drv);
return 0;
}
-EXPORT_SYMBOL(sdio_tty_uninit_tty);
-
-void sdio_tty_enable_debug_msg(void *sdio_tty_handle, int enable)
+static int sdio_tty_probe(struct platform_device *pdev)
{
- struct sdio_tty *sdio_tty_drv = sdio_tty_handle;
+ const struct platform_device_id *id = platform_get_device_id(pdev);
+ enum sdio_tty_devices device_id = id->driver_data;
+ char *device_name = NULL;
+ char *channel_name = NULL;
+ int debug_msg_on = 0;
+ int ret = 0;
+
+ pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
+
+ switch (device_id) {
+ case SDIO_CIQ:
+ device_name = SDIO_TTY_CIQ_DEV;
+ channel_name = SDIO_TTY_CH_CIQ;
+ debug_msg_on = ciq_debug_msg_on;
+ break;
+ case SDIO_CIQ_TEST_APP:
+ device_name = SDIO_TTY_CIQ_TEST_DEV;
+ channel_name = SDIO_TTY_CH_CIQ;
+ debug_msg_on = ciq_debug_msg_on;
+ break;
+ case SDIO_CSVT:
+ device_name = SDIO_TTY_CSVT_DEV;
+ channel_name = SDIO_TTY_CH_CSVT;
+ debug_msg_on = csvt_debug_msg_on;
+ break;
+ case SDIO_CSVT_TEST_APP:
+ device_name = SDIO_TTY_CSVT_TEST_DEV;
+ channel_name = SDIO_TTY_CH_CSVT;
+ debug_msg_on = csvt_debug_msg_on;
+ break;
+ default:
+ pr_err(SDIO_TTY_MODULE_NAME ": %s Invalid device:%s, id:%d",
+ __func__, pdev->name, device_id);
+ ret = -ENODEV;
+ break;
+ }
+
+ if (device_name) {
+ ret = sdio_tty_init_tty(device_name, channel_name,
+ device_id, debug_msg_on);
+ if (ret) {
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_init_tty "
+ "failed for dev:%s", __func__, device_name);
+ }
+ }
+ return ret;
+}
+
+static int sdio_tty_remove(struct platform_device *pdev)
+{
+ const struct platform_device_id *id = platform_get_device_id(pdev);
+ enum sdio_tty_devices device_id = id->driver_data;
+ struct sdio_tty *sdio_tty_drv = NULL;
+ int i = 0;
+ int ret = 0;
+
+ pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
+
+ for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
+ if (sdio_tty[i] == NULL)
+ continue;
+ if (sdio_tty[i]->device_id == device_id) {
+ sdio_tty_drv = sdio_tty[i];
+ break;
+ }
+ }
if (!sdio_tty_drv) {
pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
__func__);
- return;
+ return -ENODEV;
}
- pr_info(SDIO_TTY_MODULE_NAME ": %s: setting debug_msg_on to %d",
- __func__, enable);
- sdio_tty_drv->debug_msg_on = enable;
+
+ ret = sdio_tty_uninit_tty(sdio_tty_drv);
+ if (ret) {
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_uninit_tty "
+ "failed for %s", __func__, pdev->name);
+ }
+ return ret;
}
-EXPORT_SYMBOL(sdio_tty_enable_debug_msg);
+static struct platform_driver sdio_tty_pdrv = {
+ .probe = sdio_tty_probe,
+ .remove = sdio_tty_remove,
+ .id_table = sdio_tty_id_table,
+ .driver = {
+ .name = "SDIO_TTY",
+ .owner = THIS_MODULE,
+ },
+};
+/*
+ * Module Init.
+ *
+ * Register SDIO TTY driver.
+ *
+ */
static int __init sdio_tty_init(void)
{
- return 0;
+ int ret = 0;
+
+ ret = platform_driver_register(&sdio_tty_pdrv);
+ if (ret) {
+ pr_err(SDIO_TTY_MODULE_NAME ": %s: platform_driver_register "
+ "failed", __func__);
+ }
+ return ret;
};
/*
* Module Exit.
*
- * Unregister SDIO driver.
+ * Unregister SDIO TTY driver.
*
*/
static void __exit sdio_tty_exit(void)
{
+ platform_driver_unregister(&sdio_tty_pdrv);
}
module_init(sdio_tty_init);
diff --git a/arch/arm/mach-msm/sdio_tty_ciq.c b/arch/arm/mach-msm/sdio_tty_ciq.c
deleted file mode 100644
index 64b772d..0000000
--- a/arch/arm/mach-msm/sdio_tty_ciq.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* 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.
- */
-
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/debugfs.h>
-#include <mach/sdio_al.h>
-#include <mach/sdio_tty.h>
-
-#define SDIO_TTY_DEV "sdio_tty_ciq_0"
-#define SDIO_CIQ "sdio_ciq"
-#define SDIO_TTY_DEV_TEST "sdio_tty_ciq_test_0"
-#define TTY_CIQ_MODULE_NAME "sdio_tty_ciq"
-
-struct sdio_tty_ciq {
- void *sdio_tty_handle;
-};
-
-static struct sdio_tty_ciq sdio_tty_ciq;
-
-/*
- * Enable sdio_tty debug messages
- * By default the sdio_tty debug messages are turned off
- */
-static int debug_msg_on;
-module_param(debug_msg_on, int, 0);
-
-static int sdio_tty_probe(struct platform_device *pdev)
-{
- sdio_tty_ciq.sdio_tty_handle = sdio_tty_init_tty(SDIO_TTY_DEV,
- "SDIO_CIQ");
- if (!sdio_tty_ciq.sdio_tty_handle) {
- pr_err(TTY_CIQ_MODULE_NAME ": %s: NULL sdio_tty_handle",
- __func__);
- return -ENODEV;
- }
-
- if (debug_msg_on)
- sdio_tty_enable_debug_msg(sdio_tty_ciq.sdio_tty_handle,
- debug_msg_on);
-
- return 0;
-}
-
-static int sdio_tty_test_probe(struct platform_device *pdev)
-{
- sdio_tty_ciq.sdio_tty_handle = sdio_tty_init_tty(SDIO_TTY_DEV_TEST,
- "SDIO_CIQ");
- if (!sdio_tty_ciq.sdio_tty_handle) {
- pr_err(TTY_CIQ_MODULE_NAME ": %s: NULL sdio_tty_handle",
- __func__);
- return -ENODEV;
- }
-
- if (debug_msg_on)
- sdio_tty_enable_debug_msg(sdio_tty_ciq.sdio_tty_handle,
- debug_msg_on);
-
- return 0;
-}
-
-static int sdio_tty_remove(struct platform_device *pdev)
-{
- int ret = 0;
-
- pr_info(TTY_CIQ_MODULE_NAME ": %s", __func__);
- ret = sdio_tty_uninit_tty(sdio_tty_ciq.sdio_tty_handle);
- if (ret) {
- pr_err(TTY_CIQ_MODULE_NAME ": %s: sdio_tty_uninit_tty failed",
- __func__);
- return ret;
- }
-
- return 0;
-}
-
-static struct platform_driver sdio_tty_pdrv = {
- .probe = sdio_tty_probe,
- .remove = sdio_tty_remove,
- .driver = {
- .name = "SDIO_CIQ",
- .owner = THIS_MODULE,
- },
-};
-
-static struct platform_driver sdio_tty_test_pdrv = {
- .probe = sdio_tty_test_probe,
- .remove = sdio_tty_remove,
- .driver = {
- .name = "SDIO_CIQ_TEST_APP",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init sdio_tty_ciq_init(void)
-{
- int ret = 0;
-
- ret = platform_driver_register(&sdio_tty_pdrv);
- if (ret) {
- pr_err(TTY_CIQ_MODULE_NAME ": %s: platform_driver_register "
- "failed", __func__);
- return ret;
- }
- return platform_driver_register(&sdio_tty_test_pdrv);
-};
-
-/*
- * Module Exit.
- *
- * Unregister SDIO driver.
- *
- */
-static void __exit sdio_tty_ciq_exit(void)
-{
- platform_driver_unregister(&sdio_tty_pdrv);
- platform_driver_unregister(&sdio_tty_test_pdrv);
-}
-
-module_init(sdio_tty_ciq_init);
-module_exit(sdio_tty_ciq_exit);
-
-MODULE_DESCRIPTION("SDIO TTY CIQ");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Maya Erez <merez@codeaurora.org>");
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index ba1a869..f076a10 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1027,7 +1027,6 @@
} else {
WARN_ON("Timer running on unknown hardware. Configure this! "
"Assuming default configuration.\n");
- global_timer_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
dgt->freq = 6750000;
}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 5739a34..e5e3486 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -637,6 +637,9 @@
extern u32 dtcm_end;
extern u32 itcm_end;
#endif
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ struct zone *zone;
+#endif
max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
@@ -682,6 +685,14 @@
#endif
}
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ for_each_zone(zone) {
+ if (zone_idx(zone) == ZONE_MOVABLE)
+ total_unmovable_pages = totalram_pages -
+ zone->spanned_pages;
+ }
+#endif
+
/*
* Since our memory may not be contiguous, calculate the
* real number of pages we have in this system
@@ -784,6 +795,7 @@
void free_initmem(void)
{
+ unsigned long reclaimed_initmem;
#ifdef CONFIG_HAVE_TCM
extern char __tcm_start, __tcm_end;
@@ -792,10 +804,15 @@
"TCM link");
#endif
- if (!machine_is_integrator() && !machine_is_cintegrator())
- totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)),
+ if (!machine_is_integrator() && !machine_is_cintegrator()) {
+ reclaimed_initmem = free_area(__phys_to_pfn(__pa(__init_begin)),
__phys_to_pfn(__pa(__init_end)),
"init");
+ totalram_pages += reclaimed_initmem;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ total_unmovable_pages += reclaimed_initmem;
+#endif
+ }
}
#ifdef CONFIG_MEMORY_HOTPLUG
@@ -831,10 +848,16 @@
void free_initrd_mem(unsigned long start, unsigned long end)
{
- if (!keep_initrd)
- totalram_pages += free_area(__phys_to_pfn(__pa(start)),
+ unsigned long reclaimed_initrd_mem;
+ if (!keep_initrd) {
+ reclaimed_initrd_mem = free_area(__phys_to_pfn(__pa(start)),
__phys_to_pfn(__pa(end)),
"initrd");
+ totalram_pages += reclaimed_initrd_mem;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ total_unmovable_pages += reclaimed_initrd_mem;
+#endif
+ }
}
static int __init keepinitrd_setup(char *__unused)
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index e6a1b86..e659df5 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -978,7 +978,6 @@
struct rb_node **p;
struct rb_node *parent = NULL;
struct ion_client *entry;
- char debug_name[64];
pid_t pid;
get_task_struct(current->group_leader);
@@ -1048,8 +1047,8 @@
rb_insert_color(&client->node, &dev->kernel_clients);
}
- snprintf(debug_name, 64, "%u", client->pid);
- client->debug_root = debugfs_create_file(debug_name, 0664,
+
+ client->debug_root = debugfs_create_file(name, 0664,
dev->debug_root, client,
&debug_client_fops);
mutex_unlock(&dev->lock);
@@ -1147,9 +1146,6 @@
struct ion_buffer *buffer = file->private_data;
pr_debug("%s: %d\n", __func__, __LINE__);
- mutex_lock(&buffer->lock);
- buffer->umap_cnt--;
- mutex_unlock(&buffer->lock);
/* drop the reference to the buffer -- this prevents the
buffer from going away because the client holding it exited
while it was being passed */
@@ -1172,6 +1168,9 @@
vma->vm_private_data = NULL;
return;
}
+ mutex_lock(&buffer->lock);
+ buffer->umap_cnt++;
+ mutex_unlock(&buffer->lock);
pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n",
__func__, __LINE__,
atomic_read(&client->ref.refcount),
@@ -1190,6 +1189,14 @@
if (!handle)
return;
client = handle->client;
+ mutex_lock(&buffer->lock);
+ buffer->umap_cnt--;
+ mutex_unlock(&buffer->lock);
+
+ if (buffer->heap->ops->unmap_user)
+ buffer->heap->ops->unmap_user(buffer->heap, buffer);
+
+
pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n",
__func__, __LINE__,
atomic_read(&client->ref.refcount),
@@ -1265,7 +1272,6 @@
/* now map it to userspace */
ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma,
flags);
- buffer->umap_cnt++;
mutex_unlock(&buffer->lock);
if (ret) {
pr_err("%s: failure mapping buffer to userspace\n",
@@ -1490,9 +1496,11 @@
struct miscdevice *miscdev = file->private_data;
struct ion_device *dev = container_of(miscdev, struct ion_device, dev);
struct ion_client *client;
+ char debug_name[64];
pr_debug("%s: %d\n", __func__, __LINE__);
- client = ion_client_create(dev, -1, "user");
+ snprintf(debug_name, 64, "%u", task_pid_nr(current->group_leader));
+ client = ion_client_create(dev, -1, debug_name);
if (IS_ERR_OR_NULL(client))
return PTR_ERR(client);
file->private_data = client;
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index b03fa23..9cb338a 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -139,7 +139,8 @@
container_of(heap, struct ion_carveout_heap, heap);
if (atomic_inc_return(&carveout_heap->map_count) == 1)
- carveout_heap->request_region(carveout_heap->bus_id);
+ if (carveout_heap->request_region)
+ carveout_heap->request_region(carveout_heap->bus_id);
if (ION_IS_CACHED(flags))
return ioremap_cached(buffer->priv_phys, buffer->size);
@@ -157,7 +158,8 @@
buffer->vaddr = NULL;
if (atomic_dec_and_test(&carveout_heap->map_count))
- carveout_heap->release_region(carveout_heap->bus_id);
+ if (carveout_heap->release_region)
+ carveout_heap->release_region(carveout_heap->bus_id);
return;
}
@@ -169,7 +171,8 @@
container_of(heap, struct ion_carveout_heap, heap);
if (atomic_inc_return(&carveout_heap->map_count) == 1)
- carveout_heap->request_region(carveout_heap->bus_id);
+ if (carveout_heap->request_region)
+ carveout_heap->request_region(carveout_heap->bus_id);
if (ION_IS_CACHED(flags))
return remap_pfn_range(vma, vma->vm_start,
@@ -190,7 +193,8 @@
container_of(heap, struct ion_carveout_heap, heap);
if (atomic_dec_and_test(&carveout_heap->map_count))
- carveout_heap->release_region(carveout_heap->bus_id);
+ if (carveout_heap->release_region)
+ carveout_heap->release_region(carveout_heap->bus_id);
}
int ion_carveout_cache_ops(struct ion_heap *heap, struct ion_buffer *buffer,
@@ -379,9 +383,12 @@
carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT;
carveout_heap->allocated_bytes = 0;
carveout_heap->total_size = heap_data->size;
- carveout_heap->bus_id = heap_data->setup_region();
- carveout_heap->request_region = heap_data->request_region;
- carveout_heap->release_region = heap_data->release_region;
+ if (heap_data->setup_region)
+ carveout_heap->bus_id = heap_data->setup_region();
+ if (heap_data->request_region)
+ carveout_heap->request_region = heap_data->request_region;
+ if (heap_data->release_region)
+ carveout_heap->release_region = heap_data->release_region;
return &carveout_heap->heap;
}
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index 56aecab..39a7b04 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -1,4 +1,4 @@
-ccflags-y := -Iinclude/drm
+ccflags-y := -Iinclude/drm -Idrivers/gpu/msm
msm_kgsl_core-y = \
kgsl.o \
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 18bac1b..2681263 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -273,10 +273,13 @@
int sizedwords = 0;
unsigned int mh_mmu_invalidate = 0x00000003; /*invalidate all and tc */
- /* If possible, then set the state via the command stream to avoid
- a CPU idle. Otherwise, use the default setstate which uses register
- writes */
- if (adreno_dev->drawctxt_active) {
+ /*
+ * If possible, then set the state via the command stream to avoid
+ * a CPU idle. Otherwise, use the default setstate which uses register
+ * writes For CFF dump we must idle and use the registers so that it is
+ * easier to filter out the mmu accesses from the dump
+ */
+ if (!kgsl_cff_dump_enable && adreno_dev->drawctxt_active) {
if (flags & KGSL_MMUFLAGS_PTUPDATE) {
/* wait for graphics pipe to be idle */
*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
@@ -934,29 +937,27 @@
return status;
}
-uint8_t *kgsl_sharedmem_convertaddr(struct kgsl_device *device,
- unsigned int pt_base, unsigned int gpuaddr, unsigned int *size)
+const struct kgsl_memdesc *adreno_find_region(struct kgsl_device *device,
+ unsigned int pt_base,
+ unsigned int gpuaddr,
+ unsigned int size)
{
- uint8_t *result = NULL;
+ struct kgsl_memdesc *result = NULL;
struct kgsl_mem_entry *entry;
struct kgsl_process_private *priv;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_ringbuffer *ringbuffer = &adreno_dev->ringbuffer;
+ struct kgsl_context *context;
+ int next = 0;
- if (kgsl_gpuaddr_in_memdesc(&ringbuffer->buffer_desc, gpuaddr)) {
- return kgsl_gpuaddr_to_vaddr(&ringbuffer->buffer_desc,
- gpuaddr, size);
- }
+ if (kgsl_gpuaddr_in_memdesc(&ringbuffer->buffer_desc, gpuaddr, size))
+ return &ringbuffer->buffer_desc;
- if (kgsl_gpuaddr_in_memdesc(&ringbuffer->memptrs_desc, gpuaddr)) {
- return kgsl_gpuaddr_to_vaddr(&ringbuffer->memptrs_desc,
- gpuaddr, size);
- }
+ if (kgsl_gpuaddr_in_memdesc(&ringbuffer->memptrs_desc, gpuaddr, size))
+ return &ringbuffer->memptrs_desc;
- if (kgsl_gpuaddr_in_memdesc(&device->memstore, gpuaddr)) {
- return kgsl_gpuaddr_to_vaddr(&device->memstore,
- gpuaddr, size);
- }
+ if (kgsl_gpuaddr_in_memdesc(&device->memstore, gpuaddr, size))
+ return &device->memstore;
mutex_lock(&kgsl_driver.process_mutex);
list_for_each_entry(priv, &kgsl_driver.process_list, list) {
@@ -966,8 +967,7 @@
entry = kgsl_sharedmem_find_region(priv, gpuaddr,
sizeof(unsigned int));
if (entry) {
- result = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
- gpuaddr, size);
+ result = &entry->memdesc;
spin_unlock(&priv->mem_lock);
mutex_unlock(&kgsl_driver.process_mutex);
return result;
@@ -978,14 +978,52 @@
BUG_ON(!mutex_is_locked(&device->mutex));
list_for_each_entry(entry, &device->memqueue, list) {
- if (kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr)) {
- result = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
- gpuaddr, size);
- break;
+ if (kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, size)) {
+ result = &entry->memdesc;
+ return result;
}
}
- return result;
+
+ while (1) {
+ struct adreno_context *adreno_context = NULL;
+ struct kgsl_memdesc *gpustate;
+ struct kgsl_memdesc *gmemshadow;
+ context = idr_get_next(&device->context_idr, &next);
+ if (context == NULL)
+ break;
+
+ adreno_context = (struct adreno_context *)context->devctxt;
+
+ if (!kgsl_mmu_pt_equal(adreno_context->pagetable, pt_base))
+ continue;
+
+ gpustate = &adreno_context->gpustate;
+ if (kgsl_gpuaddr_in_memdesc(gpustate, gpuaddr, size)) {
+ result = gpustate;
+ return result;
+ }
+ gmemshadow = &adreno_context->context_gmem_shadow.gmemshadow;
+ if (kgsl_gpuaddr_in_memdesc(gmemshadow, gpuaddr, size)) {
+ result = gmemshadow;
+ return result;
+ }
+
+ next = next + 1;
+ }
+
+ return NULL;
+
+}
+
+uint8_t *adreno_convertaddr(struct kgsl_device *device, unsigned int pt_base,
+ unsigned int gpuaddr, unsigned int size)
+{
+ const struct kgsl_memdesc *memdesc;
+
+ memdesc = adreno_find_region(device, pt_base, gpuaddr, size);
+
+ return memdesc ? kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr) : NULL;
}
void adreno_regread(struct kgsl_device *device, unsigned int offsetwords,
@@ -1279,6 +1317,18 @@
adreno_dev->gpudev->irq_control(adreno_dev, state);
}
+static unsigned int adreno_gpuid(struct kgsl_device *device)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+ /* Standard KGSL gpuid format:
+ * top word is 0x0002 for 2D or 0x0003 for 3D
+ * Bottom word is core specific identifer
+ */
+
+ return (0x0003 << 16) | ((int) adreno_dev->gpurev);
+}
+
static const struct kgsl_functable adreno_functable = {
/* Mandatory functions */
.regread = adreno_regread,
@@ -1297,6 +1347,7 @@
.cleanup_pt = adreno_cleanup_pt,
.power_stats = adreno_power_stats,
.irqctrl = adreno_irqctrl,
+ .gpuid = adreno_gpuid,
/* Optional functions */
.setstate = adreno_setstate,
.drawctxt_create = adreno_drawctxt_create,
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 0776a24..99c6c52 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -43,6 +43,7 @@
*/
#define ADRENO_ISTORE_BYTES 12
#define ADRENO_ISTORE_WORDS 3
+#define ADRENO_ISTORE_START 0x5000
enum adreno_gpurev {
ADRENO_REV_UNKNOWN = 0,
@@ -93,8 +94,13 @@
void adreno_regwrite(struct kgsl_device *device, unsigned int offsetwords,
unsigned int value);
-uint8_t *kgsl_sharedmem_convertaddr(struct kgsl_device *device,
- unsigned int pt_base, unsigned int gpuaddr, unsigned int *size);
+const struct kgsl_memdesc *adreno_find_region(struct kgsl_device *device,
+ unsigned int pt_base,
+ unsigned int gpuaddr,
+ unsigned int size);
+
+uint8_t *adreno_convertaddr(struct kgsl_device *device,
+ unsigned int pt_base, unsigned int gpuaddr, unsigned int size);
static inline int adreno_is_a200(struct adreno_device *adreno_dev)
{
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index 419ce9d..c1b9e4c 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -25,9 +25,6 @@
unsigned int kgsl_cff_dump_enable;
int kgsl_pm_regs_enabled;
-static uint32_t kgsl_ib_base;
-static uint32_t kgsl_ib_size;
-
static struct dentry *pm_d_debugfs;
static int pm_dump_set(void *data, u64 val)
@@ -115,98 +112,6 @@
return ss;
}
-static ssize_t kgsl_ib_dump_read(
- struct file *file,
- char __user *buff,
- size_t buff_count,
- loff_t *ppos)
-{
- int i, count = kgsl_ib_size, remaining, pos = 0, tot = 0, ss;
- struct kgsl_device *device = file->private_data;
- const int rowc = 32;
- unsigned int pt_base, ib_memsize;
- uint8_t *base_addr;
- char linebuf[80];
-
- if (!ppos || !device || !kgsl_ib_base)
- return 0;
-
- kgsl_regread(device, MH_MMU_PT_BASE, &pt_base);
- base_addr = kgsl_sharedmem_convertaddr(device, pt_base, kgsl_ib_base,
- &ib_memsize);
-
- if (!base_addr)
- return 0;
-
- pr_info("%s ppos=%ld, buff_count=%d, count=%d\n", __func__, (long)*ppos,
- buff_count, count);
- ss = snprintf(linebuf, sizeof(linebuf), "IB: base=%08x(%08x"
- "), size=%d, memsize=%d\n", kgsl_ib_base,
- (uint32_t)base_addr, kgsl_ib_size, ib_memsize);
- if (*ppos == 0) {
- if (copy_to_user(buff, linebuf, ss+1))
- return -EFAULT;
- tot += ss;
- buff += ss;
- *ppos += ss;
- }
- pos += ss;
- remaining = count;
- for (i = 0; i < count; i += rowc) {
- int linec = min(remaining, rowc);
-
- remaining -= rowc;
- ss = kgsl_hex_dump("IB: %05x: ", i, base_addr, rowc, linec,
- buff);
- if (ss < 0)
- return ss;
-
- if (pos >= *ppos) {
- if (tot+ss >= buff_count) {
- ss = copy_to_user(buff, "", 1);
- return tot;
- }
- tot += ss;
- buff += ss;
- *ppos += ss;
- }
- pos += ss;
- base_addr += linec;
- }
-
- return tot;
-}
-
-static ssize_t kgsl_ib_dump_write(
- struct file *file,
- const char __user *buff,
- size_t count,
- loff_t *ppos)
-{
- char local_buff[64];
-
- if (count >= sizeof(local_buff))
- return -EFAULT;
-
- if (copy_from_user(local_buff, buff, count))
- return -EFAULT;
-
- local_buff[count] = 0; /* end of string */
- sscanf(local_buff, "%x %d", &kgsl_ib_base, &kgsl_ib_size);
-
- pr_info("%s: base=%08X size=%d\n", __func__, kgsl_ib_base,
- kgsl_ib_size);
-
- return count;
-}
-
-static const struct file_operations kgsl_ib_dump_fops = {
- .open = kgsl_dbgfs_open,
- .release = kgsl_dbgfs_release,
- .read = kgsl_ib_dump_read,
- .write = kgsl_ib_dump_write,
-};
-
static int kgsl_regread_nolock(struct kgsl_device *device,
unsigned int offsetwords, unsigned int *value)
{
@@ -223,7 +128,6 @@
return 0;
}
-#define ADRENO_ISTORE_START 0x5000
static ssize_t kgsl_istore_read(
struct file *file,
char __user *buff,
@@ -429,8 +333,6 @@
if (!device->d_debugfs || IS_ERR(device->d_debugfs))
return;
- debugfs_create_file("ib_dump", 0600, device->d_debugfs, device,
- &kgsl_ib_dump_fops);
debugfs_create_file("istore", 0400, device->d_debugfs, device,
&kgsl_istore_fops);
debugfs_create_file("sx_debug", 0400, device->d_debugfs, device,
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index cc69360..c6b850e 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -247,9 +247,8 @@
static void dump_ib(struct kgsl_device *device, char* buffId, uint32_t pt_base,
uint32_t base_offset, uint32_t ib_base, uint32_t ib_size, bool dump)
{
- unsigned int memsize;
- uint8_t *base_addr = kgsl_sharedmem_convertaddr(device, pt_base,
- ib_base, &memsize);
+ uint8_t *base_addr = adreno_convertaddr(device, pt_base,
+ ib_base, ib_size*sizeof(uint32_t));
if (base_addr && dump)
print_hex_dump(KERN_ERR, buffId, DUMP_PREFIX_OFFSET,
@@ -277,14 +276,13 @@
int i, j;
uint32_t value;
uint32_t *ib1_addr;
- unsigned int memsize;
dump_ib(device, "IB1:", pt_base, base_offset, ib1_base,
ib1_size, dump);
/* fetch virtual address for given IB base */
- ib1_addr = (uint32_t *)kgsl_sharedmem_convertaddr(device, pt_base,
- ib1_base, &memsize);
+ ib1_addr = (uint32_t *)adreno_convertaddr(device, pt_base,
+ ib1_base, ib1_size*sizeof(uint32_t));
if (!ib1_addr)
return;
@@ -466,7 +464,7 @@
const uint32_t *rb_vaddr;
int num_item = 0;
int read_idx, write_idx;
- unsigned int ts_processed, rb_memsize;
+ unsigned int ts_processed;
static struct ib_list ib_list;
@@ -681,11 +679,16 @@
KGSL_LOG_DUMP(device, "RB: rd_addr:%8.8x rb_size:%d num_item:%d\n",
cp_rb_base, rb_count<<2, num_item);
- rb_vaddr = (const uint32_t *)kgsl_sharedmem_convertaddr(device,
- cur_pt_base, cp_rb_base, &rb_memsize);
+
+ if (adreno_dev->ringbuffer.buffer_desc.gpuaddr != cp_rb_base)
+ KGSL_LOG_POSTMORTEM_WRITE(device,
+ "rb address mismatch, should be 0x%08x\n",
+ adreno_dev->ringbuffer.buffer_desc.gpuaddr);
+
+ rb_vaddr = adreno_dev->ringbuffer.buffer_desc.hostptr;
if (!rb_vaddr) {
KGSL_LOG_POSTMORTEM_WRITE(device,
- "Can't fetch vaddr for CP_RB_BASE\n");
+ "rb has no kernel mapping!\n");
goto error_vfree;
}
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 75c01b4..7a42dcd 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -774,9 +774,7 @@
BUG_ON(private == NULL);
list_for_each_entry(entry, &private->mem_list, list) {
- if (gpuaddr >= entry->memdesc.gpuaddr &&
- ((gpuaddr + size) <=
- (entry->memdesc.gpuaddr + entry->memdesc.size))) {
+ if (kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, size)) {
result = entry;
break;
}
@@ -786,20 +784,6 @@
}
EXPORT_SYMBOL(kgsl_sharedmem_find_region);
-uint8_t *kgsl_gpuaddr_to_vaddr(const struct kgsl_memdesc *memdesc,
- unsigned int gpuaddr, unsigned int *size)
-{
- BUG_ON(memdesc->hostptr == NULL);
-
- if (memdesc->gpuaddr == 0 || (gpuaddr < memdesc->gpuaddr ||
- gpuaddr >= memdesc->gpuaddr + memdesc->size))
- return NULL;
-
- *size = memdesc->size - (gpuaddr - memdesc->gpuaddr);
- return memdesc->hostptr + (gpuaddr - memdesc->gpuaddr);
-}
-EXPORT_SYMBOL(kgsl_gpuaddr_to_vaddr);
-
/*call all ioctl sub functions with driver locked*/
static long kgsl_ioctl_device_getproperty(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data)
@@ -1680,11 +1664,6 @@
result = -EINVAL;
goto done;
}
- if (!entry->memdesc.hostptr)
- entry->memdesc.hostptr =
- kgsl_gpuaddr_to_vaddr(&entry->memdesc,
- param->gpuaddr, &entry->memdesc.size);
-
if (!entry->memdesc.hostptr) {
KGSL_CORE_ERR("invalid hostptr with gpuaddr %08x\n",
param->gpuaddr);
@@ -2456,8 +2435,6 @@
if (result)
goto err;
- kgsl_mmu_set_mmutype(ksgl_mmu_type);
-
return 0;
err:
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 3bb722d..1135adb 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -145,8 +145,6 @@
#endif
void kgsl_mem_entry_destroy(struct kref *kref);
-uint8_t *kgsl_gpuaddr_to_vaddr(const struct kgsl_memdesc *memdesc,
- unsigned int gpuaddr, unsigned int *size);
struct kgsl_mem_entry *kgsl_sharedmem_find_region(
struct kgsl_process_private *private, unsigned int gpuaddr,
size_t size);
@@ -175,14 +173,24 @@
#endif
static inline int kgsl_gpuaddr_in_memdesc(const struct kgsl_memdesc *memdesc,
- unsigned int gpuaddr)
+ unsigned int gpuaddr, unsigned int size)
{
- if (gpuaddr >= memdesc->gpuaddr && (gpuaddr + sizeof(unsigned int)) <=
- (memdesc->gpuaddr + memdesc->size)) {
+ if (gpuaddr >= memdesc->gpuaddr &&
+ ((gpuaddr + size) <= (memdesc->gpuaddr + memdesc->size))) {
return 1;
}
return 0;
}
+static inline uint8_t *kgsl_gpuaddr_to_vaddr(const struct kgsl_memdesc *memdesc,
+ unsigned int gpuaddr)
+{
+ if (memdesc->hostptr == NULL || memdesc->gpuaddr == 0 ||
+ (gpuaddr < memdesc->gpuaddr ||
+ gpuaddr >= memdesc->gpuaddr + memdesc->size))
+ return NULL;
+
+ return memdesc->hostptr + (gpuaddr - memdesc->gpuaddr);
+}
static inline int timestamp_cmp(unsigned int new, unsigned int old)
{
diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c
index aa33152..e9455cb 100644
--- a/drivers/gpu/msm/kgsl_cffdump.c
+++ b/drivers/gpu/msm/kgsl_cffdump.c
@@ -231,8 +231,6 @@
spin_lock(&cffdump_lock);
if (opcode == CFF_OP_WRITE_MEM) {
- if (op1 < 0x40000000 || op1 >= 0x60000000)
- KGSL_CORE_ERR("addr out-of-range: op1=%08x", op1);
if ((cff_op_write_membuf.addr != op1 &&
cff_op_write_membuf.count)
|| (cff_op_write_membuf.count == MEMBUF_SIZE))
@@ -360,15 +358,7 @@
void kgsl_cffdump_open(enum kgsl_deviceid device_id)
{
- /*TODO: move this to where we can report correct gmemsize*/
- unsigned int va_base;
-
- if (cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_msm8930())
- va_base = 0x40000000;
- else
- va_base = 0x20000000;
-
- kgsl_cffdump_memory_base(device_id, va_base,
+ kgsl_cffdump_memory_base(device_id, KGSL_PAGETABLE_BASE,
CONFIG_MSM_KGSL_PAGE_TABLE_SIZE, SZ_256K);
}
@@ -401,8 +391,6 @@
bool clean_cache)
{
const void *src;
- uint host_size;
- uint physaddr;
if (!kgsl_cff_dump_enable)
return;
@@ -422,13 +410,9 @@
}
memdesc = &entry->memdesc;
}
- BUG_ON(memdesc->gpuaddr == 0);
- BUG_ON(gpuaddr == 0);
- physaddr = kgsl_get_realaddr(memdesc) + (gpuaddr - memdesc->gpuaddr);
-
- src = kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr, &host_size);
- if (src == NULL || host_size < sizebytes) {
- KGSL_CORE_ERR("did not find mapping for "
+ src = (uint *)kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr);
+ if (memdesc->hostptr == NULL) {
+ KGSL_CORE_ERR("no kernel mapping for "
"gpuaddr: 0x%08x, m->host: 0x%p, phys: 0x%08x\n",
gpuaddr, memdesc->hostptr, memdesc->physaddr);
return;
@@ -444,7 +428,6 @@
KGSL_CACHE_OP_INV);
}
- BUG_ON(physaddr > 0x66000000 && physaddr < 0x66ffffff);
while (sizebytes > 3) {
cffdump_printline(-1, CFF_OP_WRITE_MEM, gpuaddr, *(uint *)src,
0, 0, 0);
@@ -462,7 +445,6 @@
if (!kgsl_cff_dump_enable)
return;
- BUG_ON(addr > 0x66000000 && addr < 0x66ffffff);
while (sizebytes > 3) {
/* Use 32bit memory writes as long as there's at least
* 4 bytes left */
@@ -575,7 +557,6 @@
{
static uint level; /* recursion level */
bool ret = true;
- uint host_size;
uint *hostaddr, *hoststart;
int dwords_left = sizedwords; /* dwords left in the current command
buffer */
@@ -596,10 +577,9 @@
}
memdesc = &entry->memdesc;
}
-
- hostaddr = (uint *)kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr, &host_size);
+ hostaddr = (uint *)kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr);
if (hostaddr == NULL) {
- KGSL_CORE_ERR("did not find mapping for "
+ KGSL_CORE_ERR("no kernel mapping for "
"gpuaddr: 0x%08x\n", gpuaddr);
return true;
}
@@ -608,14 +588,9 @@
level++;
- if (!memdesc->physaddr) {
- KGSL_CORE_ERR("no physaddr");
- } else {
- mb();
- kgsl_cache_range_op((struct kgsl_memdesc *)memdesc,
+ mb();
+ kgsl_cache_range_op((struct kgsl_memdesc *)memdesc,
KGSL_CACHE_OP_INV);
- }
-
#ifdef DEBUG
pr_info("kgsl: cffdump: ib: gpuaddr:0x%08x, wc:%d, hptr:%p\n",
gpuaddr, sizedwords, hostaddr);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 1c55199..3ef11ce 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -89,6 +89,7 @@
void (*power_stats)(struct kgsl_device *device,
struct kgsl_power_stats *stats);
void (*irqctrl)(struct kgsl_device *device, int state);
+ unsigned int (*gpuid)(struct kgsl_device *device);
/* Optional functions - these functions are not mandatory. The
driver will check that the function pointer is not NULL before
calling the hook */
@@ -240,6 +241,11 @@
return device->ftbl->idle(device, timeout);
}
+static inline unsigned int kgsl_gpuid(struct kgsl_device *device)
+{
+ return device->ftbl->gpuid(device);
+}
+
static inline int kgsl_create_device_sysfs_files(struct device *root,
const struct device_attribute **list)
{
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 715b9d6..36248ef 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -22,6 +22,7 @@
#include "kgsl_mmu.h"
#include "kgsl_device.h"
#include "kgsl_sharedmem.h"
+#include "adreno_postmortem.h"
#define KGSL_MMU_ALIGN_SHIFT 13
#define KGSL_MMU_ALIGN_MASK (~((1 << KGSL_MMU_ALIGN_SHIFT) - 1))
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index b59761d..ec91b39 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -655,7 +655,7 @@
BUG_ON(memdesc == NULL || memdesc->hostptr == NULL);
BUG_ON(offsetbytes + sizeof(unsigned int) > memdesc->size);
- kgsl_cffdump_setmem(memdesc->physaddr + offsetbytes,
+ kgsl_cffdump_setmem(memdesc->gpuaddr + offsetbytes,
src, sizeof(uint));
writel_relaxed(src, memdesc->hostptr + offsetbytes);
return 0;
@@ -669,8 +669,8 @@
BUG_ON(memdesc == NULL || memdesc->hostptr == NULL);
BUG_ON(offsetbytes + sizebytes > memdesc->size);
- kgsl_cffdump_setmem(memdesc->physaddr + offsetbytes, value,
- sizebytes);
+ kgsl_cffdump_setmem(memdesc->gpuaddr + offsetbytes, value,
+ sizebytes);
memset(memdesc->hostptr + offsetbytes, value, sizebytes);
return 0;
}
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 8413fc4..cf74e64 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -888,6 +888,16 @@
}
}
+static unsigned int z180_gpuid(struct kgsl_device *device)
+{
+ /* Standard KGSL gpuid format:
+ * top word is 0x0002 for 2D or 0x0003 for 3D
+ * Bottom word is core specific identifer
+ */
+
+ return (0x0002 << 16) | 180;
+}
+
static const struct kgsl_functable z180_functable = {
/* Mandatory functions */
.regread = z180_regread,
@@ -905,6 +915,7 @@
.cleanup_pt = z180_cleanup_pt,
.power_stats = z180_power_stats,
.irqctrl = z180_irqctrl,
+ .gpuid = z180_gpuid,
/* Optional functions */
.drawctxt_create = NULL,
.drawctxt_destroy = z180_drawctxt_destroy,
diff --git a/drivers/input/misc/pmic8058-othc.c b/drivers/input/misc/pmic8058-othc.c
index a28e8e1..cac748a 100644
--- a/drivers/input/misc/pmic8058-othc.c
+++ b/drivers/input/misc/pmic8058-othc.c
@@ -536,19 +536,11 @@
struct pm8058_othc *dd =
container_of(work, struct pm8058_othc, detect_work.work);
- if (dd->othc_ir_state) {
- /* inserted */
- rc = pm8058_accessory_report(dd, 1);
- if (rc)
- pr_err("Accessory could not be detected\n");
- } else {
- /* removed */
- rc = pm8058_accessory_report(dd, 0);
- if (rc)
- pr_err("Accessory could not be detected\n");
- /* Clear existing switch state */
- dd->othc_sw_state = false;
- }
+ /* Accessory has been inserted */
+ rc = pm8058_accessory_report(dd, 1);
+ if (rc)
+ pr_err("Accessory insertion could not be detected\n");
+
enable_irq(dd->othc_irq_ir);
}
@@ -637,8 +629,6 @@
ktime_set((dd->switch_debounce_ms / 1000),
(dd->switch_debounce_ms % 1000) * 1000000), HRTIMER_MODE_REL);
- /* disable irq, this gets enabled in the workqueue */
- disable_irq_nosync(dd->othc_irq_ir);
/* Check the MIC_BIAS status, to check if inserted or removed */
rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
@@ -648,8 +638,20 @@
}
dd->othc_ir_state = rc;
- schedule_delayed_work(&dd->detect_work,
+ if (dd->othc_ir_state) {
+ /* disable irq, this gets enabled in the workqueue */
+ disable_irq_nosync(dd->othc_irq_ir);
+ /* Accessory has been inserted, report with detection delay */
+ schedule_delayed_work(&dd->detect_work,
msecs_to_jiffies(dd->detection_delay_ms));
+ } else {
+ /* Accessory has been removed, report removal immediately */
+ rc = pm8058_accessory_report(dd, 0);
+ if (rc)
+ pr_err("Accessory removal could not be detected\n");
+ /* Clear existing switch state */
+ dd->othc_sw_state = false;
+ }
fail_ir:
return IRQ_HANDLED;
diff --git a/drivers/input/touchscreen/synaptics/rmi_f11.c b/drivers/input/touchscreen/synaptics/rmi_f11.c
index 9a23776..4caaf92 100644
--- a/drivers/input/touchscreen/synaptics/rmi_f11.c
+++ b/drivers/input/touchscreen/synaptics/rmi_f11.c
@@ -188,11 +188,7 @@
}
}
input_report_key(function_device->input,
- BTN_TOUCH, fingerDownCount);
- for (finger = 0; finger < (instanceData->sensorInfo->numberOfFingers - 1); finger++) {
- input_report_key(function_device->input,
- BTN_2 + finger, fingerDownCount >= (finger + 2));
- }
+ BTN_TOUCH, !!fingerDownCount);
for (finger = 0; finger < instanceData->sensorInfo->numberOfFingers; finger++) {
int reg;
@@ -269,14 +265,8 @@
}
#ifdef CONFIG_SYNA_MULTI_TOUCH
/* Report Multi-Touch events for each finger */
- /* major axis of touch area ellipse */
- input_report_abs(function_device->input, ABS_MT_TOUCH_MAJOR, Z);
- /* minor axis of touch area ellipse */
- input_report_abs(function_device->input, ABS_MT_WIDTH_MAJOR,
- max(Wx, Wy));
- /* Currently only 2 supported - 1 or 0 */
- input_report_abs(function_device->input, ABS_MT_ORIENTATION,
- (Wx > Wy ? 1 : 0));
+ input_report_abs(function_device->input,
+ ABS_MT_PRESSURE, Z);
input_report_abs(function_device->input, ABS_MT_POSITION_X, X);
input_report_abs(function_device->input, ABS_MT_POSITION_Y, Y);
@@ -284,7 +274,7 @@
/* Could be formed by keeping an id per position and assiging */
/* a new id when fingerStatus changes for that position.*/
input_report_abs(function_device->input, ABS_MT_TRACKING_ID,
- finger+1);
+ finger);
/* MT sync between fingers */
input_mt_sync(function_device->input);
#endif
@@ -297,17 +287,10 @@
instanceData->wasdown = false;
#ifdef CONFIG_SYNA_MULTI_TOUCH
- input_report_abs(function_device->input, ABS_MT_TOUCH_MAJOR, 0);
- input_report_abs(function_device->input, ABS_MT_WIDTH_MAJOR, 0);
- input_report_abs(function_device->input, ABS_MT_POSITION_X, instanceData->oldX);
- input_report_abs(function_device->input, ABS_MT_POSITION_Y, instanceData->oldY);
- input_report_abs(function_device->input, ABS_MT_TRACKING_ID, 1);
+ input_report_abs(function_device->input, ABS_MT_PRESSURE, 0);
+ input_report_key(function_device->input, BTN_TOUCH, 0);
input_mt_sync(function_device->input);
#endif
-
- input_report_abs(function_device->input, ABS_X, instanceData->oldX);
- input_report_abs(function_device->input, ABS_Y, instanceData->oldY);
- instanceData->oldX = instanceData->oldY = 0;
}
FN_11_relreport(rmifninfo);
@@ -468,10 +451,11 @@
input_set_abs_params(function_device->input, ABS_TOOL_WIDTH, 0, 15, 0, 0);
#ifdef CONFIG_SYNA_MULTI_TOUCH
- input_set_abs_params(function_device->input, ABS_MT_TOUCH_MAJOR, 0, 15, 0, 0);
- input_set_abs_params(function_device->input, ABS_MT_TOUCH_MINOR, 0, 15, 0, 0);
+ input_set_abs_params(function_device->input, ABS_MT_PRESSURE,
+ 0, 15, 0, 0);
input_set_abs_params(function_device->input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
- input_set_abs_params(function_device->input, ABS_MT_TRACKING_ID, 1, 10, 0, 0);
+ input_set_abs_params(function_device->input, ABS_MT_TRACKING_ID,
+ 0, 10, 0, 0);
input_set_abs_params(function_device->input, ABS_MT_POSITION_X, xMin, xMax,
0, 0);
input_set_abs_params(function_device->input, ABS_MT_POSITION_Y, yMin, yMax,
@@ -536,8 +520,8 @@
set_bit(EV_ABS, function_device->input->evbit);
set_bit(EV_SYN, function_device->input->evbit);
set_bit(EV_KEY, function_device->input->evbit);
- set_bit(BTN_MISC, function_device->input->keybit);
- set_bit(KEY_OK, function_device->input->keybit);
+ set_bit(BTN_TOUCH, function_device->input->keybit);
+ set_bit(KEY_OK, function_device->input->keybit);
f11_set_abs_params(function_device);
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 0ab22f8..eb0c828 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -648,6 +648,15 @@
return radio_hci_send_cmd(hdev, opcode, 0, NULL);
}
+static int hci_get_fm_trans_conf_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_TRANS_CONF_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
static int hci_set_fm_recv_conf_req(struct radio_hci_dev *hdev,
unsigned long param)
{
@@ -1474,6 +1483,10 @@
msecs_to_jiffies(RADIO_HCI_TIMEOUT));
break;
+ case HCI_FM_GET_TX_CONFIG:
+ ret = radio_hci_request(hdev, hci_get_fm_trans_conf_req, arg,
+ msecs_to_jiffies(RADIO_HCI_TIMEOUT));
+ break;
default:
ret = -EINVAL;
break;
@@ -1502,6 +1515,7 @@
if (status)
return;
+
radio_hci_req_complete(hdev, status);
}
@@ -1531,6 +1545,19 @@
radio_hci_req_complete(hdev, rsp->status);
}
+static void hci_cc_fm_trans_get_conf_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_fm_get_trans_conf_rsp *rsp = (void *)skb->data;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ if (rsp->status)
+ return;
+ memcpy((void *)&radio->trans_conf, (void*)&rsp->trans_conf_rsp,
+ sizeof(rsp->trans_conf_rsp));
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
static void hci_cc_fm_enable_rsp(struct radio_hci_dev *hdev,
struct sk_buff *skb)
{
@@ -1863,6 +1890,9 @@
hci_cc_do_calibration_rsp(hdev, skb);
break;
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_GET_TRANS_CONF_REQ):
+ hci_cc_fm_trans_get_conf_rsp(hdev, skb);
+ break;
default:
FMDERR("%s opcode 0x%x", hdev->name, opcode);
break;
@@ -2646,6 +2676,8 @@
retval = radio_hci_request(radio->fm_hdev,
hci_fm_tone_generator, arg,
msecs_to_jiffies(RADIO_HCI_TIMEOUT));
+ if (retval < 0)
+ FMDERR("Error while setting the tone %d", retval);
break;
case V4L2_CID_AUDIO_VOLUME:
break;
@@ -2673,12 +2705,12 @@
case FM_RECV:
retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
radio->fm_hdev);
-
- radio->mode = FM_RECV;
-
- if (retval < 0)
+ if (retval < 0) {
FMDERR("Error while enabling RECV FM"
" %d\n", retval);
+ return retval;
+ }
+ radio->mode = FM_RECV;
radio->mute_mode.soft_mute = CTRL_ON;
retval = hci_set_fm_mute_mode(
&radio->mute_mode,
@@ -2715,10 +2747,14 @@
retval = hci_cmd(HCI_FM_ENABLE_TRANS_CMD,
radio->fm_hdev);
radio->mode = FM_TRANS;
-
- if (retval < 0)
+ if (retval < 0) {
FMDERR("Error while enabling TRANS FM"
" %d\n", retval);
+ return retval;
+ }
+ retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("get frequency failed %d\n", retval);
break;
case FM_OFF:
switch (radio->mode) {
@@ -2963,7 +2999,14 @@
temp_val = ctrl->value;
retval = hci_set_notch_filter(&temp_val, radio->fm_hdev);
break;
-
+ case V4L2_CID_PRIVATE_IRIS_SRCH_ALGORITHM:
+ /*
+ This private control is a place holder to keep the
+ driver compatible with changes done in the frameworks
+ which are specific to TAVARUA.
+ */
+ retval = 0;
+ break;
default:
retval = -EINVAL;
}
@@ -2978,19 +3021,37 @@
if (tuner->index > 0)
return -EINVAL;
- retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
- if (retval < 0)
- return retval;
+ if (radio->mode == FM_RECV) {
+ retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Failed to Get station params");
+ return retval;
+ }
+ tuner->type = V4L2_TUNER_RADIO;
+ tuner->rangelow =
+ radio->recv_conf.band_low_limit * TUNE_PARAM;
+ tuner->rangehigh =
+ radio->recv_conf.band_high_limit * TUNE_PARAM;
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ tuner->capability = V4L2_TUNER_CAP_LOW;
+ tuner->signal = radio->fm_st_rsp.station_rsp.rssi;
+ tuner->audmode = radio->fm_st_rsp.station_rsp.stereo_prg;
+ tuner->afc = 0;
+ } else if (radio->mode == FM_TRANS) {
+ retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("get Tx config failed %d\n", retval);
+ return retval;
+ } else {
+ tuner->type = V4L2_TUNER_RADIO;
+ tuner->rangelow =
+ radio->trans_conf.band_low_limit * TUNE_PARAM;
+ tuner->rangehigh =
+ radio->trans_conf.band_high_limit * TUNE_PARAM;
+ }
- tuner->type = V4L2_TUNER_RADIO;
- tuner->rangelow = radio->recv_conf.band_low_limit * TUNE_PARAM;
- tuner->rangehigh = radio->recv_conf.band_high_limit * TUNE_PARAM;
- tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- tuner->capability = V4L2_TUNER_CAP_LOW;
- tuner->signal = radio->fm_st_rsp.station_rsp.rssi;
- tuner->audmode = radio->fm_st_rsp.station_rsp.stereo_prg;
- tuner->afc = 0;
-
+ } else
+ return -EINVAL;
return 0;
}
@@ -3020,16 +3081,13 @@
if (retval < 0)
FMDERR(": set tuner failed with %d\n", retval);
return retval;
- } else {
- if (radio->mode == FM_TRANS) {
+ } else if (radio->mode == FM_TRANS) {
radio->trans_conf.band_low_limit =
tuner->rangelow / TUNE_PARAM;
radio->trans_conf.band_high_limit =
tuner->rangehigh / TUNE_PARAM;
- } else {
- return -EINVAL;
- }
- }
+ } else
+ return -EINVAL;
return retval;
}
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 0597308..d09f89f 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -118,6 +118,7 @@
int pi;
/*PS repeatcount for PS Tx */
int ps_repeatcount;
+ int enable_optimized_srch_alg;
};
/**************************************************************************
@@ -1162,6 +1163,169 @@
return 0;
}
+static int optimized_search_algorithm(struct tavarua_device *radio,
+ int region)
+{
+ unsigned char adie_type_bahma;
+ int retval = 0;
+ unsigned int rdsMask = 0;
+ unsigned char value;
+
+ adie_type_bahma = is_bahama();
+
+ switch (region) {
+ case TAVARUA_REGION_US:
+ /*
+ Radio band for all the 200KHz channel-spaced regions
+ coming under EUROPE too, have been set as TAVARUA_REGION_US.
+ */
+ FMDBG("%s: The region selected from APP is"
+ " : TAVARUA_REGION_US", __func__);
+ break;
+ case TAVARUA_REGION_EU:
+ /*
+ Radio band for all the 50KHz channel-spaced regions
+ coming under EUROPE, have been set as TAVARUA_REGION_EU.
+ */
+ FMDBG("%s: The region selected from APP is : "
+ "TAVARUA_REGION_EU", __func__);
+ break;
+ case TAVARUA_REGION_JAPAN:
+ /*
+ Radio band for the 100KHz channel-spaced JAPAN region
+ has been set as TAVARUA_REGION_JAPAN.
+ */
+ FMDBG("%s: The region selected from APP is"
+ " : TAVARUA_REGION_JAPAN", __func__);
+ break;
+ case TAVARUA_REGION_JAPAN_WIDE:
+ /*
+ Radio band for the 50KHz channel-spaced JAPAN WIDE region
+ has been set as TAVARUA_REGION_JAPAN_WIDE.
+ */
+ FMDBG("%s: The region selected from APP is"
+ " : TAVARUA_REGION_JAPAN_WIDE", __func__);
+ break;
+ case TAVARUA_REGION_OTHER:
+ /*
+ Radio band for all the 100KHz channel-spaced regions
+ including those coming under EUROPE have been set as
+ TAVARUA_REGION_OTHER.
+ */
+ FMDBG("%s: The region selected from APP is"
+ " : TAVARUA_REGION_OTHER", __func__);
+ break;
+ default:
+ pr_err("%s: Should not reach here.", __func__);
+ break;
+
+ }
+
+ /* Enable or Disable the 200KHz enforcer */
+ switch (region) {
+ case TAVARUA_REGION_US:
+ case TAVARUA_REGION_JAPAN:
+ case TAVARUA_REGION_OTHER:
+ /*
+ These are the 3 bands for which we need to enable the
+ 200KHz enforcer in ADVCTL reg.
+ */
+ if (adie_type_bahma) {
+ FMDBG("Adie type : Bahama\n");
+ FMDBG("%s: Enabling the 200KHz enforcer for"
+ " Region : %d", __func__, region);
+ /*Enable the 200KHz enforcer*/
+ retval = tavarua_read_registers(radio,
+ ADVCTRL, 1);
+ if (retval >= 0) {
+ rdsMask = radio->registers[ADVCTRL];
+ SET_REG_FIELD(rdsMask, ENF_SRCH200khz,
+ SRCH200KHZ_OFFSET, SRCH_MASK);
+ retval = tavarua_write_register(radio,
+ ADVCTRL, rdsMask);
+ } else
+ return retval;
+ } /* if Marimba do nothing */
+ break;
+ case TAVARUA_REGION_EU:
+ case TAVARUA_REGION_JAPAN_WIDE:
+ /*
+ These are the 2 bands for which we need to disable the
+ 200KHz enforcer in ADVCTL reg.
+ Radio band for all the 50KHz channel-spaced regions
+ coming under EUROPE have been set as TAVARUA_REGION_EU.
+ */
+ if (adie_type_bahma) {
+ FMDBG("Adie type : Bahama\n");
+ FMDBG("%s: Disabling the 200KHz enforcer for"
+ " Region : %d", __func__, region);
+ /*
+ Disable 200KHz enforcer for all 50 KHz
+ spaced regions.
+ */
+ retval = tavarua_read_registers(radio,
+ ADVCTRL, 1);
+ if (retval >= 0) {
+ rdsMask = radio->registers[ADVCTRL];
+ SET_REG_FIELD(rdsMask, NO_SRCH200khz,
+ SRCH200KHZ_OFFSET, SRCH_MASK);
+ retval = tavarua_write_register(radio,
+ ADVCTRL, rdsMask);
+ } else
+ return retval;
+ } /* if Marimba do nothing */
+ break;
+ default:
+ FMDBG("%s: Defaulting in case of Enabling/Disabling"
+ "the 200KHz Enforcer", __func__);
+ break;
+ }
+
+ /* Set channel spacing */
+ switch (region) {
+ case TAVARUA_REGION_US:
+ if (adie_type_bahma) {
+ FMDBG("Adie type : Bahama\n");
+ /*
+ Configuring all 200KHZ spaced regions as 100KHz due to
+ change in the new Bahma FM SoC search algorithm.
+ */
+ value = FM_CH_SPACE_100KHZ;
+ } else {
+ FMDBG("Adie type : Marimba\n");
+ value = FM_CH_SPACE_200KHZ;
+ }
+ break;
+ case TAVARUA_REGION_JAPAN:
+ case TAVARUA_REGION_OTHER:
+ if (adie_type_bahma) {
+ FMDBG("Adie type : Bahama\n");
+ FMDBG("%s: Configuring the channel-spacing as 50KHz"
+ "for the Region : %d", __func__, region);
+ /*
+ Configuring all 100KHZ spaced regions as 50KHz due to
+ change in the new Bahma FM SoC search algorithm.
+ */
+ value = FM_CH_SPACE_50KHZ;
+ } else {
+ FMDBG("Adie type : Marimba\n");
+ value = FM_CH_SPACE_100KHZ;
+ }
+ break;
+ case TAVARUA_REGION_EU:
+ case TAVARUA_REGION_JAPAN_WIDE:
+ value = FM_CH_SPACE_50KHZ;
+ break;
+ default:
+ FMDBG("%s: Defualting in case of Channel-Spacing", __func__);
+ break;
+ }
+
+ SET_REG_FIELD(radio->registers[RDCTRL], value,
+ RDCTRL_CHSPACE_OFFSET, RDCTRL_CHSPACE_MASK);
+
+ return retval;
+}
/*************************************************************************
* fops/IOCTL helper functions
************************************************************************/
@@ -1255,14 +1419,11 @@
switch (region) {
case TAVARUA_REGION_US:
case TAVARUA_REGION_EU:
- case TAVARUA_REGION_JAPAN_WIDE:
SET_REG_FIELD(radio->registers[RDCTRL], 0,
RDCTRL_BAND_OFFSET, RDCTRL_BAND_MASK);
break;
+ case TAVARUA_REGION_JAPAN_WIDE:
case TAVARUA_REGION_JAPAN:
- SET_REG_FIELD(radio->registers[RDCTRL], 1,
- RDCTRL_BAND_OFFSET, RDCTRL_BAND_MASK);
- break;
default:
retval = sync_read_xfr(radio, RADIO_CONFIG, xfr_buf);
if (retval < 0) {
@@ -1286,85 +1447,6 @@
break;
}
- /* Enable/Disable the 200KHz enforcer for respectiver regions */
- switch (region) {
- case TAVARUA_REGION_US:
- if (adie_type_bahma) {
- FMDBG("Adie type : Bahama\n");
- /*Enable the 200KHz enforcer*/
- retval = tavarua_read_registers(radio,
- ADVCTRL, 1);
- if (retval >= 0) {
- rdsMask = radio->registers[ADVCTRL];
- SET_REG_FIELD(rdsMask, ENF_SRCH200khz,
- SRCH200KHZ_OFFSET, SRCH_MASK);
- msleep(TAVARUA_DELAY);
- retval = tavarua_write_register(radio,
- ADVCTRL, rdsMask);
- } else
- return retval;
- } /* if Marimba do nothing */
- break;
- case TAVARUA_REGION_EU:
- case TAVARUA_REGION_JAPAN:
- case TAVARUA_REGION_JAPAN_WIDE:
- default:
- if (adie_type_bahma) {
- FMDBG("Adie type : Bahama\n");
- /*
- Disable 200KHz enforcer for all 100/50 KHz
- spaced regions.
- */
- retval = tavarua_read_registers(radio,
- ADVCTRL, 1);
- if (retval >= 0) {
- rdsMask = radio->registers[ADVCTRL];
- SET_REG_FIELD(rdsMask, NO_SRCH200khz,
- SRCH200KHZ_OFFSET, SRCH_MASK);
- msleep(TAVARUA_DELAY);
- retval = tavarua_write_register(radio,
- ADVCTRL, rdsMask);
- } else
- return retval;
- } /* if Marimba do nothing */
- break;
- }
-
- /* Set channel spacing */
- switch (region) {
- case TAVARUA_REGION_US:
- if (adie_type_bahma) {
- FMDBG("Adie type : Bahama\n");
- /*
- Configuring all 200KHZ spaced regions as
- 100KHz due to change in the new Bahma
- FM SoC search algorithm.
- */
- value = FM_CH_SPACE_100KHZ;
- } else {
- FMDBG("Adie type : Marimba\n");
- value = FM_CH_SPACE_200KHZ;
- }
- break;
- case TAVARUA_REGION_EU:
- case TAVARUA_REGION_JAPAN:
- value = FM_CH_SPACE_100KHZ;
- break;
- case TAVARUA_REGION_JAPAN_WIDE:
- value = FM_CH_SPACE_50KHZ;
- break;
- default:
- /*
- Set the channel spacing as configured from
- the upper layers.
- */
- value = radio->region_params.spacing;
- break;
- }
-
- SET_REG_FIELD(radio->registers[RDCTRL], value,
- RDCTRL_CHSPACE_OFFSET, RDCTRL_CHSPACE_MASK);
-
/* Set De-emphasis and soft band range*/
switch (region) {
case TAVARUA_REGION_US:
@@ -1403,13 +1485,6 @@
if (retval < 0)
return retval;
- FMDBG("RDCTRL: %x\n", radio->registers[RDCTRL]);
- retval = tavarua_write_register(radio, RDCTRL,
- radio->registers[RDCTRL]);
- if (retval < 0) {
- FMDERR("Could not set region in rdctrl\n");
- return retval;
- }
/* setting soft band */
switch (region) {
@@ -1430,6 +1505,101 @@
break;
}
radio->region_params.region = region;
+
+ /* Check for the FM Algorithm used */
+ if (radio->enable_optimized_srch_alg) {
+ FMDBG("Optimized Srch Algorithm!!!");
+ optimized_search_algorithm(radio, region);
+ } else {
+ FMDBG("Native Srch Algorithm!!!");
+ /* Enable/Disable the 200KHz enforcer */
+ switch (region) {
+ case TAVARUA_REGION_US:
+ if (adie_type_bahma) {
+ FMDBG("Adie type : Bahama\n");
+ /*Enable the 200KHz enforcer*/
+ retval = tavarua_read_registers(radio,
+ ADVCTRL, 1);
+ if (retval >= 0) {
+ rdsMask = radio->registers[ADVCTRL];
+ SET_REG_FIELD(rdsMask, ENF_SRCH200khz,
+ SRCH200KHZ_OFFSET, SRCH_MASK);
+ retval = tavarua_write_register(radio,
+ ADVCTRL, rdsMask);
+ } else
+ return retval;
+ } /* if Marimba do nothing */
+ break;
+ case TAVARUA_REGION_EU:
+ case TAVARUA_REGION_JAPAN:
+ case TAVARUA_REGION_JAPAN_WIDE:
+ default:
+ if (adie_type_bahma) {
+ FMDBG("Adie type : Bahama\n");
+ /*
+ Disable 200KHz enforcer for all 100/50 KHz
+ spaced regions.
+ */
+ retval = tavarua_read_registers(radio,
+ ADVCTRL, 1);
+ if (retval >= 0) {
+ rdsMask = radio->registers[ADVCTRL];
+ SET_REG_FIELD(rdsMask, NO_SRCH200khz,
+ SRCH200KHZ_OFFSET, SRCH_MASK);
+ retval = tavarua_write_register(radio,
+ ADVCTRL, rdsMask);
+ } else
+ return retval;
+ } /* if Marimba do nothing */
+ break;
+ }
+
+ /* Set channel spacing */
+ switch (region) {
+ case TAVARUA_REGION_US:
+ if (adie_type_bahma) {
+ FMDBG("Adie type : Bahama\n");
+ /*
+ Configuring all 200KHZ spaced regions as
+ 100KHz due to change in the new Bahma
+ FM SoC search algorithm.
+ */
+ value = FM_CH_SPACE_100KHZ;
+ } else {
+ FMDBG("Adie type : Marimba\n");
+ value = FM_CH_SPACE_200KHZ;
+ }
+ break;
+ case TAVARUA_REGION_JAPAN:
+ value = FM_CH_SPACE_100KHZ;
+ break;
+ case TAVARUA_REGION_EU:
+ case TAVARUA_REGION_JAPAN_WIDE:
+ value = FM_CH_SPACE_50KHZ;
+ break;
+ default:
+ /*
+ Set the channel spacing as configured from
+ the upper layers.
+ */
+ value = radio->region_params.spacing;
+ break;
+ }
+
+ SET_REG_FIELD(radio->registers[RDCTRL], value,
+ RDCTRL_CHSPACE_OFFSET, RDCTRL_CHSPACE_MASK);
+
+ }
+
+ /* Write the config values into RDCTL register */
+ FMDBG("RDCTRL: %x\n", radio->registers[RDCTRL]);
+ retval = tavarua_write_register(radio, RDCTRL,
+ radio->registers[RDCTRL]);
+ if (retval < 0) {
+ FMDERR("Could not set region in rdctrl\n");
+ return retval;
+ }
+
return retval;
}
@@ -2839,6 +3009,11 @@
}
}
break;
+ case V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM:
+ radio->enable_optimized_srch_alg = ctrl->value;
+ FMDBG("V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM : %d",
+ radio->enable_optimized_srch_alg);
+ break;
case V4L2_CID_PRIVATE_TAVARUA_REGION:
retval = tavarua_set_region(radio, ctrl->value);
break;
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index fb809c9..7a0ee4d 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -97,6 +97,7 @@
val |= 0x1 << 10;
val |= 0x1 << 11;
val |= 0x1 << 12;
+ val |= 0x1 << 13;
val |= 0x1 << 28;
msm_io_w(val, csidbase + CSID_CORE_CTRL_ADDR);
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index b62ec84..109b3dd 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -79,7 +79,7 @@
msm_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);
for (i = 0; i < csiphy_params->lane_cnt; i++) {
- msm_io_w(0x10, csiphybase + MIPI_CSIPHY_LNn_CFG1_ADDR + 0x40*i);
+ msm_io_w(0x00, csiphybase + MIPI_CSIPHY_LNn_CFG1_ADDR + 0x40*i);
msm_io_w(0x5F, csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
msm_io_w(csiphy_params->settle_cnt,
csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*i);
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
index 019d6e1..23db5f6b 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c.c
@@ -138,34 +138,155 @@
return rc;
}
+int32_t msm_camera_i2c_set_mask(struct msm_camera_i2c_client *client,
+ uint16_t addr, uint16_t mask,
+ enum msm_camera_i2c_data_type data_type, uint16_t set_mask)
+{
+ int32_t rc;
+ uint16_t reg_data;
+
+ rc = msm_camera_i2c_read(client, addr, ®_data, data_type);
+ if (rc < 0) {
+ S_I2C_DBG("%s read fail\n", __func__);
+ return rc;
+ }
+ S_I2C_DBG("%s addr: 0x%x data: 0x%x setmask: 0x%x\n",
+ __func__, addr, reg_data, mask);
+
+ if (set_mask)
+ reg_data |= mask;
+ else
+ reg_data &= ~mask;
+ S_I2C_DBG("%s write: 0x%x\n", __func__, reg_data);
+
+ rc = msm_camera_i2c_write(client, addr, reg_data, data_type);
+ if (rc < 0)
+ S_I2C_DBG("%s write fail\n", __func__);
+
+ return rc;
+}
+
+int32_t msm_camera_i2c_compare(struct msm_camera_i2c_client *client,
+ uint16_t addr, uint16_t data,
+ enum msm_camera_i2c_data_type data_type)
+{
+ int32_t rc = -EIO;
+ uint16_t reg_data = 0;
+ int data_len = 0;
+ switch (data_type) {
+ case MSM_CAMERA_I2C_BYTE_DATA:
+ case MSM_CAMERA_I2C_WORD_DATA:
+ data_len = data_type;
+ break;
+ case MSM_CAMERA_I2C_SET_BYTE_MASK:
+ case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+ data_len = MSM_CAMERA_I2C_BYTE_DATA;
+ break;
+ case MSM_CAMERA_I2C_SET_WORD_MASK:
+ case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+ data_len = MSM_CAMERA_I2C_WORD_DATA;
+ break;
+ default:
+ pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
+ break;
+ }
+
+ rc = msm_camera_i2c_read(client,
+ addr, ®_data, data_len);
+ if (rc < 0)
+ return rc;
+
+ rc = 0;
+ switch (data_type) {
+ case MSM_CAMERA_I2C_BYTE_DATA:
+ case MSM_CAMERA_I2C_WORD_DATA:
+ if (data == reg_data)
+ return rc;
+ break;
+ case MSM_CAMERA_I2C_SET_BYTE_MASK:
+ case MSM_CAMERA_I2C_SET_WORD_MASK:
+ if ((reg_data & data) == data)
+ return rc;
+ break;
+ case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+ case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+ if (!(reg_data & data))
+ return rc;
+ break;
+ default:
+ pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
+ break;
+ }
+
+ S_I2C_DBG("%s: Register and data does not match\n", __func__);
+ rc = 1;
+ return rc;
+}
+
+int32_t msm_camera_i2c_poll(struct msm_camera_i2c_client *client,
+ uint16_t addr, uint16_t data,
+ enum msm_camera_i2c_data_type data_type)
+{
+ int32_t rc = -EIO;
+ int i;
+ S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n",
+ __func__, addr, data, data_type);
+
+ for (i = 0; i < 20; i++) {
+ rc = msm_camera_i2c_compare(client,
+ addr, data, data_type);
+ if (rc == 0 || rc < 0)
+ break;
+ usleep_range(10000, 11000);
+ }
+ return rc;
+}
+
int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
- struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint8_t size,
+ struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
enum msm_camera_i2c_data_type data_type)
{
int i;
int32_t rc = -EFAULT;
for (i = 0; i < size; i++) {
- rc = msm_camera_i2c_write(
- client,
- reg_conf_tbl->reg_addr,
- reg_conf_tbl->reg_data, data_type);
- if (rc < 0)
- break;
- reg_conf_tbl++;
- }
- return rc;
-}
+ enum msm_camera_i2c_data_type dt;
+ if (reg_conf_tbl->dt == 0)
+ dt = data_type;
+ else
+ dt = reg_conf_tbl->dt;
-int32_t msm_camera_i2c_write_dt_tbl(struct msm_camera_i2c_client *client,
- struct msm_camera_i2c_reg_dt_conf *reg_conf_tbl, uint16_t size)
-{
- int i;
- int32_t rc = -EFAULT;
- for (i = 0; i < size; i++) {
- rc = msm_camera_i2c_write(
- client,
- reg_conf_tbl->reg_addr,
- reg_conf_tbl->reg_data, reg_conf_tbl->dt);
+ switch (dt) {
+ case MSM_CAMERA_I2C_BYTE_DATA:
+ case MSM_CAMERA_I2C_WORD_DATA:
+ rc = msm_camera_i2c_write(
+ client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data, dt);
+ break;
+ case MSM_CAMERA_I2C_SET_BYTE_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_BYTE_DATA, 1);
+ break;
+ case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_BYTE_DATA, 0);
+ break;
+ case MSM_CAMERA_I2C_SET_WORD_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_WORD_DATA, 1);
+ break;
+ case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_WORD_DATA, 0);
+ break;
+ default:
+ pr_err("%s: Unsupport data type: %d\n", __func__, dt);
+ break;
+ }
if (rc < 0)
break;
reg_conf_tbl++;
@@ -202,7 +323,7 @@
else
*data = buf[0] << 8 | buf[1];
- S_I2C_DBG("%s addr = 0x%x data: 0x%x", __func__, addr, *data);
+ S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data);
return rc;
}
@@ -243,15 +364,16 @@
struct msm_camera_i2c_conf_array *array, uint16_t index)
{
int32_t rc;
- if (array[index].data_type != MSM_CAMERA_I2C_HYBRID_DATA) {
- rc = msm_camera_i2c_write_tbl(client,
- (struct msm_camera_i2c_reg_conf *) array[index].conf,
- array[index].size, array[index].data_type);
- } else {
- rc = msm_camera_i2c_write_dt_tbl(client,
- (struct msm_camera_i2c_reg_dt_conf *) array[index].conf,
- array[index].size);
- }
+ if (array[index].pre_process != NULL)
+ array[index].pre_process();
+
+ rc = msm_camera_i2c_write_tbl(client,
+ (struct msm_camera_i2c_reg_conf *) array[index].conf,
+ array[index].size, array[index].data_type);
+
+ if (array[index].post_process != NULL)
+ array[index].post_process();
+
if (array[index].delay > 20)
msleep(array[index].delay);
else
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.h b/drivers/media/video/msm/io/msm_camera_i2c.h
index 201cd03..05b3960 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.h
+++ b/drivers/media/video/msm/io/msm_camera_i2c.h
@@ -35,28 +35,28 @@
enum msm_camera_i2c_reg_addr_type addr_type;
};
-struct msm_camera_i2c_reg_conf {
- uint16_t reg_addr;
- uint16_t reg_data;
-};
-
enum msm_camera_i2c_data_type {
MSM_CAMERA_I2C_BYTE_DATA = 1,
MSM_CAMERA_I2C_WORD_DATA,
- MSM_CAMERA_I2C_HYBRID_DATA,
+ MSM_CAMERA_I2C_SET_BYTE_MASK,
+ MSM_CAMERA_I2C_UNSET_BYTE_MASK,
+ MSM_CAMERA_I2C_SET_WORD_MASK,
+ MSM_CAMERA_I2C_UNSET_WORD_MASK,
};
-struct msm_camera_i2c_reg_dt_conf {
+struct msm_camera_i2c_reg_conf {
uint16_t reg_addr;
uint16_t reg_data;
enum msm_camera_i2c_data_type dt;
};
struct msm_camera_i2c_conf_array {
- void *conf;
+ struct msm_camera_i2c_reg_conf *conf;
uint16_t size;
uint16_t delay;
enum msm_camera_i2c_data_type data_type;
+ int (*pre_process) (void);
+ int (*post_process) (void);
};
int32_t msm_camera_i2c_rxdata(struct msm_camera_i2c_client *client,
@@ -79,12 +79,21 @@
int32_t msm_camera_i2c_write_seq(struct msm_camera_i2c_client *client,
uint16_t addr, uint8_t *data, uint16_t num_byte);
-int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
- struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint8_t size,
+int32_t msm_camera_i2c_set_mask(struct msm_camera_i2c_client *client,
+ uint16_t addr, uint16_t mask,
+ enum msm_camera_i2c_data_type data_type, uint16_t flag);
+
+int32_t msm_camera_i2c_compare(struct msm_camera_i2c_client *client,
+ uint16_t addr, uint16_t data,
enum msm_camera_i2c_data_type data_type);
-int32_t msm_camera_i2c_write_dt_tbl(struct msm_camera_i2c_client *client,
- struct msm_camera_i2c_reg_dt_conf *reg_conf_tbl, uint16_t size);
+int32_t msm_camera_i2c_poll(struct msm_camera_i2c_client *client,
+ uint16_t addr, uint16_t data,
+ enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
+ struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
+ enum msm_camera_i2c_data_type data_type);
int32_t msm_sensor_write_conf_array(struct msm_camera_i2c_client *client,
struct msm_camera_i2c_conf_array *array, uint16_t index);
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 7d3e6c6..d34d5b1 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -2262,17 +2262,17 @@
CDBG("%s: PCA Rolloff Ram0\n", __func__);
for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE * 2; i++) {
- temp2 = (i == (V33_PCA_ROLL_OFF_TABLE_SIZE - 1));
+ temp2 = (i == (V33_PCA_ROLL_OFF_TABLE_SIZE));
if (old_val && temp2)
vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1);
else if (!old_val && temp2)
vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0);
+ *cmdp_local = msm_io_r(vfe32_ctrl->vfebase +
+ VFE33_DMI_DATA_LO);
*(cmdp_local + 1) =
msm_io_r(vfe32_ctrl->vfebase +
VFE33_DMI_DATA_HI);
- *cmdp_local = msm_io_r(vfe32_ctrl->vfebase +
- VFE33_DMI_DATA_LO);
CDBG("%s: %08x%08x\n", __func__,
*(cmdp_local + 1), *cmdp_local);
cmdp_local += 2;
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 42f88d0..373aaf7 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -43,6 +43,7 @@
#define PM8921_REVISION_MASK 0x000F
#define REG_PM8921_PON_CNTRL_3 0x01D
+#define REG_PM8921_PON_CNTRL_4 0x01E
#define PM8921_RESTART_REASON_MASK 0x07
#define SINGLE_IRQ_RESOURCE(_name, _irq) \
@@ -702,6 +703,14 @@
val &= PM8921_RESTART_REASON_MASK;
pr_info("PMIC Restart Reason: %s\n", pm8921_restart_reason[val]);
+ /* Set power-on-reset to 3 seconds */
+ val = 0xBB;
+ rc = msm_ssbi_write(pdev->dev.parent, REG_PM8921_PON_CNTRL_4, &val, 1);
+ if (rc) {
+ pr_err("Cannot write power-on-reset rc=%d\n", rc);
+ goto err;
+ }
+
rc = pm8921_add_subdevices(pdata, pmic);
if (rc) {
pr_err("Cannot add subdevices rc=%d\n", rc);
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 79f78bf..385f8ff 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -66,3 +66,4 @@
obj-$(CONFIG_PMIC8058_MISC) += pmic8058-misc.o
obj-$(CONFIG_PMIC8058_BATTALARM) += pmic8058-batt-alarm.o
obj-$(CONFIG_TZCOM) += tzcom.o
+obj-$(CONFIG_QFP_FUSE) += qfp_fuse.o
diff --git a/drivers/misc/isa1200.c b/drivers/misc/isa1200.c
index a58c7d6..31c79a0 100644
--- a/drivers/misc/isa1200.c
+++ b/drivers/misc/isa1200.c
@@ -187,7 +187,7 @@
rc = isa1200_write_reg(client, ISA1200_HCTRL1, value);
if (rc < 0) {
pr_err("%s: i2c write failure\n", __func__);
- return rc;
+ goto reset_gpios;
}
if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
@@ -224,6 +224,10 @@
reset_hctrl1:
i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
ISA1200_HCTRL1_RESET);
+reset_gpios:
+ gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
+ if (haptic->is_len_gpio_valid == true)
+ gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
return rc;
}
@@ -449,6 +453,11 @@
return 0;
reset_hctrl0:
+ gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
+ if (haptic->is_len_gpio_valid == true)
+ gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
+ i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
+ ISA1200_HCTRL1_RESET);
i2c_smbus_write_byte_data(client, ISA1200_HCTRL0,
ISA1200_HCTRL0_RESET);
setup_fail:
@@ -490,6 +499,10 @@
timed_output_dev_unregister(&haptic->dev);
+ gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
+ if (haptic->is_len_gpio_valid == true)
+ gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
+
gpio_free(haptic->pdata->hap_en_gpio);
if (haptic->is_len_gpio_valid == true)
gpio_free(haptic->pdata->hap_len_gpio);
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 7c8dfea..3dfa68e 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -338,6 +338,13 @@
help
Say Y here to enable support for pm8921 chip bms subdevice
+config LTC4088_CHARGER
+ tristate "LTC4088 Charger driver"
+ depends on GPIOLIB
+ help
+ Say Y here to enable support for ltc4088 chip charger. It controls the
+ operations through GPIO pins.
+
config PM8921_BMS
select PM8XXX_CCADC
tristate "PM8921 Battery Monitoring System driver"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index e168590..03db839 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -48,3 +48,4 @@
obj-$(CONFIG_PM8XXX_CCADC) += pm8xxx-ccadc.o
obj-$(CONFIG_PM8921_BMS) += pm8921-bms.o
obj-$(CONFIG_PM8921_CHARGER) += pm8921-charger.o
+obj-$(CONFIG_LTC4088_CHARGER) += ltc4088-charger.o
diff --git a/drivers/power/ltc4088-charger.c b/drivers/power/ltc4088-charger.c
new file mode 100644
index 0000000..dbc75cd
--- /dev/null
+++ b/drivers/power/ltc4088-charger.c
@@ -0,0 +1,338 @@
+/*
+ * 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.
+ */
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/power_supply.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/power/ltc4088-charger.h>
+
+#define MAX_CURRENT_UA(n) (n)
+#define MAX_CURRENT_MA(n) (n * MAX_CURRENT_UA(1000))
+
+/**
+ * ltc4088_max_current - A typical current values supported by the charger
+ * @LTC4088_MAX_CURRENT_100mA: 100mA current
+ * @LTC4088_MAX_CURRENT_500mA: 500mA current
+ * @LTC4088_MAX_CURRENT_1A: 1A current
+ */
+enum ltc4088_max_current {
+ LTC4088_MAX_CURRENT_100mA = 100,
+ LTC4088_MAX_CURRENT_500mA = 500,
+ LTC4088_MAX_CURRENT_1A = 1000,
+};
+
+/**
+ * struct ltc4088_chg_chip - Device information
+ * @dev: Device pointer to access the parent
+ * @lock: Enable mutual exclusion
+ * @usb_psy: USB device information
+ * @gpio_mode_select_d0: GPIO #pin for D0 charger line
+ * @gpio_mode_select_d1: GPIO #pin for D1 charger line
+ * @gpio_mode_select_d2: GPIO #pin for D2 charger line
+ * @max_current: Maximum current that is supplied at this time
+ */
+struct ltc4088_chg_chip {
+ struct device *dev;
+ struct mutex lock;
+ struct power_supply usb_psy;
+ unsigned int gpio_mode_select_d0;
+ unsigned int gpio_mode_select_d1;
+ unsigned int gpio_mode_select_d2;
+ unsigned int max_current;
+};
+
+static enum power_supply_property pm_power_props[] = {
+ POWER_SUPPLY_PROP_CURRENT_MAX,
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static char *pm_power_supplied_to[] = {
+ "battery",
+};
+
+static int ltc4088_set_charging(struct ltc4088_chg_chip *chip, bool enable)
+{
+ mutex_lock(&chip->lock);
+
+ if (enable) {
+ gpio_set_value_cansleep(chip->gpio_mode_select_d2, 0);
+ } else {
+ /* When disabling charger, set the max current to 0 also */
+ chip->max_current = 0;
+ gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d2, 1);
+ }
+
+ mutex_unlock(&chip->lock);
+
+ return 0;
+}
+
+static void ltc4088_set_max_current(struct ltc4088_chg_chip *chip, int value)
+{
+ mutex_lock(&chip->lock);
+
+ /* If current is less than 100mA, we can not support that granularity */
+ if (value < MAX_CURRENT_MA(LTC4088_MAX_CURRENT_100mA)) {
+ chip->max_current = 0;
+ gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
+ } else if (value < MAX_CURRENT_MA(LTC4088_MAX_CURRENT_500mA)) {
+ chip->max_current = MAX_CURRENT_MA(LTC4088_MAX_CURRENT_100mA);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d0, 0);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d1, 0);
+ } else if (value < MAX_CURRENT_MA(LTC4088_MAX_CURRENT_1A)) {
+ chip->max_current = MAX_CURRENT_MA(LTC4088_MAX_CURRENT_500mA);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d0, 0);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
+ } else {
+ chip->max_current = MAX_CURRENT_MA(LTC4088_MAX_CURRENT_1A);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d1, 0);
+ }
+
+ mutex_unlock(&chip->lock);
+}
+
+static void ltc4088_set_charging_off(struct ltc4088_chg_chip *chip)
+{
+ gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
+ gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
+}
+
+static int ltc4088_set_initial_state(struct ltc4088_chg_chip *chip)
+{
+ int rc;
+
+ rc = gpio_request(chip->gpio_mode_select_d0, "ltc4088_D0");
+ if (rc) {
+ pr_err("gpio request failed for GPIO %d\n",
+ chip->gpio_mode_select_d0);
+ return rc;
+ }
+
+ rc = gpio_request(chip->gpio_mode_select_d1, "ltc4088_D1");
+ if (rc) {
+ pr_err("gpio request failed for GPIO %d\n",
+ chip->gpio_mode_select_d1);
+ goto gpio_err_d0;
+ }
+
+ rc = gpio_request(chip->gpio_mode_select_d2, "ltc4088_D2");
+ if (rc) {
+ pr_err("gpio request failed for GPIO %d\n",
+ chip->gpio_mode_select_d2);
+ goto gpio_err_d1;
+ }
+
+ rc = gpio_direction_output(chip->gpio_mode_select_d0, 0);
+ if (rc) {
+ pr_err("failed to set direction for GPIO %d\n",
+ chip->gpio_mode_select_d0);
+ goto gpio_err_d2;
+ }
+
+ rc = gpio_direction_output(chip->gpio_mode_select_d1, 0);
+ if (rc) {
+ pr_err("failed to set direction for GPIO %d\n",
+ chip->gpio_mode_select_d1);
+ goto gpio_err_d2;
+ }
+
+ rc = gpio_direction_output(chip->gpio_mode_select_d2, 1);
+ if (rc) {
+ pr_err("failed to set direction for GPIO %d\n",
+ chip->gpio_mode_select_d2);
+ goto gpio_err_d2;
+ }
+
+ return 0;
+
+gpio_err_d2:
+ gpio_free(chip->gpio_mode_select_d2);
+gpio_err_d1:
+ gpio_free(chip->gpio_mode_select_d1);
+gpio_err_d0:
+ gpio_free(chip->gpio_mode_select_d0);
+ return rc;
+}
+
+static int pm_power_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct ltc4088_chg_chip *chip;
+
+ if (psy->type == POWER_SUPPLY_TYPE_USB) {
+ chip = container_of(psy, struct ltc4088_chg_chip,
+ usb_psy);
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ if (chip->max_current)
+ val->intval = 1;
+ else
+ val->intval = 0;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ val->intval = chip->max_current;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int pm_power_set_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ struct ltc4088_chg_chip *chip;
+
+ if (psy->type == POWER_SUPPLY_TYPE_USB) {
+ chip = container_of(psy, struct ltc4088_chg_chip,
+ usb_psy);
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ ltc4088_set_charging(chip, val->intval);
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ ltc4088_set_max_current(chip, val->intval);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int __devinit ltc4088_charger_probe(struct platform_device *pdev)
+{
+ int rc;
+ struct ltc4088_chg_chip *chip;
+ const struct ltc4088_charger_platform_data *pdata
+ = pdev->dev.platform_data;
+
+ if (!pdata) {
+ pr_err("missing platform data\n");
+ return -EINVAL;
+ }
+
+ chip = kzalloc(sizeof(struct ltc4088_chg_chip),
+ GFP_KERNEL);
+ if (!chip) {
+ pr_err("Cannot allocate pm_chg_chip\n");
+ return -ENOMEM;
+ }
+
+ chip->dev = &pdev->dev;
+
+ if (pdata->gpio_mode_select_d0 < 0 ||
+ pdata->gpio_mode_select_d1 < 0 ||
+ pdata->gpio_mode_select_d2 < 0) {
+ pr_err("Invalid platform data supplied\n");
+ rc = -EINVAL;
+ goto free_chip;
+ }
+
+ mutex_init(&chip->lock);
+
+ chip->gpio_mode_select_d0 = pdata->gpio_mode_select_d0;
+ chip->gpio_mode_select_d1 = pdata->gpio_mode_select_d1;
+ chip->gpio_mode_select_d2 = pdata->gpio_mode_select_d2;
+
+ chip->usb_psy.name = "usb",
+ chip->usb_psy.type = POWER_SUPPLY_TYPE_USB,
+ chip->usb_psy.supplied_to = pm_power_supplied_to,
+ chip->usb_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to),
+ chip->usb_psy.properties = pm_power_props,
+ chip->usb_psy.num_properties = ARRAY_SIZE(pm_power_props),
+ chip->usb_psy.get_property = pm_power_get_property,
+ chip->usb_psy.set_property = pm_power_set_property,
+
+ rc = power_supply_register(chip->dev, &chip->usb_psy);
+ if (rc < 0) {
+ pr_err("power_supply_register usb failed rc = %d\n", rc);
+ goto free_chip;
+ }
+
+ platform_set_drvdata(pdev, chip);
+
+ rc = ltc4088_set_initial_state(chip);
+ if (rc < 0) {
+ pr_err("setting initial state failed rc = %d\n", rc);
+ goto unregister_usb;
+ }
+
+ return 0;
+
+unregister_usb:
+ platform_set_drvdata(pdev, NULL);
+ power_supply_unregister(&chip->usb_psy);
+free_chip:
+ kfree(chip);
+
+ return rc;
+}
+
+static int __devexit ltc4088_charger_remove(struct platform_device *pdev)
+{
+ struct ltc4088_chg_chip *chip = platform_get_drvdata(pdev);
+
+ ltc4088_set_charging_off(chip);
+
+ gpio_free(chip->gpio_mode_select_d2);
+ gpio_free(chip->gpio_mode_select_d1);
+ gpio_free(chip->gpio_mode_select_d0);
+
+ power_supply_unregister(&chip->usb_psy);
+
+ platform_set_drvdata(pdev, NULL);
+ mutex_destroy(&chip->lock);
+ kfree(chip);
+
+ return 0;
+}
+
+static struct platform_driver ltc4088_charger_driver = {
+ .probe = ltc4088_charger_probe,
+ .remove = __devexit_p(ltc4088_charger_remove),
+ .driver = {
+ .name = LTC4088_CHARGER_DEV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ltc4088_charger_init(void)
+{
+ return platform_driver_register(<c4088_charger_driver);
+}
+
+static void __exit ltc4088_charger_exit(void)
+{
+ platform_driver_unregister(<c4088_charger_driver);
+}
+
+subsys_initcall(ltc4088_charger_init);
+module_exit(ltc4088_charger_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("LTC4088 charger/battery driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:" LTC4088_CHARGER_DEV_NAME);
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 6741ef4..85d8a08 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -120,6 +120,15 @@
module_param_cb(last_ocv_uv, &bms_param_ops, &last_ocv_uv, 0644);
module_param_cb(last_soc, &bms_param_ops, &last_soc, 0644);
+/*
+ * bms_fake_battery is write only, this value is set in setups where a
+ * battery emulator is used instead of a real battery. This makes the
+ * bms driver report a higher value of charge regardless of the calculated
+ * state of charge.
+ */
+static int bms_fake_battery;
+module_param(bms_fake_battery, int, 0644);
+
static int interpolate_fcc(struct pm8921_bms_chip *chip, int batt_temp);
static void readjust_fcc_table(void)
{
@@ -991,7 +1000,8 @@
}
static int calculate_real_fcc(struct pm8921_bms_chip *chip,
- int batt_temp, int chargecycles)
+ int batt_temp, int chargecycles,
+ int *ret_fcc)
{
int fcc, unusable_charge;
int remaining_charge;
@@ -1005,8 +1015,9 @@
&cc_mah);
real_fcc = remaining_charge - cc_mah;
- pr_debug("real_fcc = %d, RC = %d CC = %lld\n",
- real_fcc, remaining_charge, cc_mah);
+ *ret_fcc = fcc;
+ pr_debug("real_fcc = %d, RC = %d CC = %lld fcc = %d\n",
+ real_fcc, remaining_charge, cc_mah, fcc);
return real_fcc;
}
/*
@@ -1015,8 +1026,6 @@
* - unusable charge (due to battery resistance)
* SOC% = (remaining usable charge/ fcc - usable_charge);
*/
-#define BMS_BATT_NOMINAL 3700000
-#define MIN_OPERABLE_SOC 10
#define BATTERY_POWER_SUPPLY_SOC 53
static int calculate_state_of_charge(struct pm8921_bms_chip *chip,
int batt_temp, int chargecycles)
@@ -1040,22 +1049,10 @@
soc = 100;
pr_debug("SOC = %u%%\n", soc);
- if (soc < MIN_OPERABLE_SOC) {
- int ocv = 0, rc;
-
- rc = adc_based_ocv(chip, &ocv);
- if (rc == 0 && ocv >= BMS_BATT_NOMINAL) {
- /*
- * The ocv doesnt seem to have dropped for
- * soc to go negative.
- * The setup must be using a power supply
- * instead of real batteries.
- * Fake high enough soc to prevent userspace
- * shutdown for low battery
- */
- soc = BATTERY_POWER_SUPPLY_SOC;
- pr_debug("Adjusting SOC to %d\n", soc);
- }
+ if (bms_fake_battery) {
+ soc = BATTERY_POWER_SUPPLY_SOC;
+ pr_debug("setting SOC = %u%% bms_fake_battery = %d\n", soc,
+ bms_fake_battery);
}
if (soc < 0) {
@@ -1069,6 +1066,7 @@
last_ocv_uv, chargecycles, batt_temp,
fcc, soc);
update_userspace = 0;
+ soc = 0;
}
if (last_soc == -EINVAL || soc <= last_soc) {
@@ -1261,11 +1259,13 @@
}
EXPORT_SYMBOL_GPL(pm8921_bms_charging_began);
+#define DELTA_FCC_PERCENT 3
void pm8921_bms_charging_end(int is_battery_full)
{
if (is_battery_full && the_chip != NULL) {
unsigned long flags;
int batt_temp, rc, cc_reading;
+ int fcc, new_fcc, delta_fcc;
struct pm8xxx_adc_chan_result result;
rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
@@ -1277,10 +1277,24 @@
pr_debug("batt_temp phy = %lld meas = 0x%llx", result.physical,
result.measurement);
batt_temp = (int)result.physical;
- last_real_fcc = calculate_real_fcc(the_chip,
- batt_temp, last_chargecycles);
- last_real_fcc_batt_temp = batt_temp;
- readjust_fcc_table();
+ new_fcc = calculate_real_fcc(the_chip,
+ batt_temp, last_chargecycles,
+ &fcc);
+ delta_fcc = new_fcc - fcc;
+ if (delta_fcc < 0)
+ delta_fcc = -delta_fcc;
+
+ if (delta_fcc * 100 <= (DELTA_FCC_PERCENT * fcc)) {
+ pr_debug("delta_fcc=%d < %d percent of fcc=%d\n",
+ delta_fcc, DELTA_FCC_PERCENT, fcc);
+ last_real_fcc = new_fcc;
+ last_real_fcc_batt_temp = batt_temp;
+ readjust_fcc_table();
+ } else {
+ pr_debug("delta_fcc=%d > %d percent of fcc=%d"
+ "will not update real fcc\n",
+ delta_fcc, DELTA_FCC_PERCENT, fcc);
+ }
spin_lock_irqsave(&the_chip->bms_output_lock, flags);
pm_bms_lock_output_data(the_chip);
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 03810ce..a184ab6 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -25,6 +25,44 @@
static struct device_type power_supply_dev_type;
+/**
+ * power_supply_set_current_limit - set current limit
+ * @psy: the power supply to control
+ * @limit: current limit in uA from the power supply.
+ * 0 will disable the power supply.
+ *
+ * This function will set a maximum supply current from a source
+ * and it will disable the charger when limit is 0.
+ */
+int power_supply_set_current_limit(struct power_supply *psy, int limit)
+{
+ const union power_supply_propval ret = {limit,};
+
+ if (psy->set_property)
+ return psy->set_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX,
+ &ret);
+
+ return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(power_supply_set_current_limit);
+
+/**
+ * power_supply_set_charging_by - set charging state of the charger
+ * @psy: the power supply to control
+ * @enable: enables or disables the charger
+ */
+int power_supply_set_charging_by(struct power_supply *psy, bool enable)
+{
+ const union power_supply_propval ret = {enable,};
+
+ if (psy->set_property)
+ return psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE,
+ &ret);
+
+ return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(power_supply_set_charging_by);
+
static int __power_supply_changed_work(struct device *dev, void *data)
{
struct power_supply *psy = (struct power_supply *)data;
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 117d3bf..94ed950 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -1089,6 +1089,12 @@
This csw hack feature is for increasing the performance of the mass
storage
+config USB_MSC_PROFILING
+ bool "USB MSC performance profiling"
+ help
+ If you say Y here, support will be added for collecting
+ Mass-storage performance numbers at the VFS level.
+
config MODEM_SUPPORT
boolean "modem support in generic serial function driver"
depends on USB_G_ANDROID
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index c880799..af6f351 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -1090,6 +1090,32 @@
/*-------------------------------------------------------------------------*/
/* /sys/class/android_usb/android%d/ interface */
+static ssize_t remote_wakeup_show(struct device *pdev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ !!(android_config_driver.bmAttributes &
+ USB_CONFIG_ATT_WAKEUP));
+}
+
+static ssize_t remote_wakeup_store(struct device *pdev,
+ struct device_attribute *attr, const char *buff, size_t size)
+{
+ int enable = 0;
+
+ sscanf(buff, "%d", &enable);
+
+ pr_debug("android_usb: %s remote wakeup\n",
+ enable ? "enabling" : "disabling");
+
+ if (enable)
+ android_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ else
+ android_config_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP;
+
+ return size;
+}
+
static ssize_t
functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
{
@@ -1245,6 +1271,8 @@
static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show, functions_store);
static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
+static DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR,
+ remote_wakeup_show, remote_wakeup_store);
static struct device_attribute *android_usb_attributes[] = {
&dev_attr_idVendor,
@@ -1259,6 +1287,7 @@
&dev_attr_functions,
&dev_attr_enable,
&dev_attr_state,
+ &dev_attr_remote_wakeup,
NULL
};
diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 771ebfc..0c42292 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -1103,6 +1103,7 @@
struct msm_endpoint *ept = ui->ept + bit;
struct msm_request *req;
unsigned long flags;
+ int req_dequeue = 1;
unsigned info;
/*
@@ -1111,7 +1112,6 @@
ept->req, ept->req ? ept->req->item_dma : 0);
*/
- del_timer(&ept->prime_timer);
/* expire all requests that are no longer active */
spin_lock_irqsave(&ui->lock, flags);
while ((req = ept->req)) {
@@ -1123,13 +1123,23 @@
break;
}
+dequeue:
/* clean speculative fetches on req->item->info */
dma_coherent_post_ops();
info = req->item->info;
/* if the transaction is still in-flight, stop here */
- if (info & INFO_ACTIVE)
- break;
+ if (info & INFO_ACTIVE) {
+ if (req_dequeue) {
+ req_dequeue = 0;
+ udelay(10);
+ goto dequeue;
+ } else {
+ break;
+ }
+ }
+ req_dequeue = 0;
+ del_timer(&ept->prime_timer);
/* advance ept queue to the next request */
ept->req = req->next;
if (ept->req == 0)
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index 11f9ef6..00b2ec1 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -97,7 +97,7 @@
return -ENODEV;
}
- urb = usb_alloc_urb(0, GFP_KERNEL);
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
dev_err(&dev->udev->dev, "unable to allocate urb\n");
return -ENOMEM;
@@ -108,7 +108,7 @@
diag_bridge_read_cb, dev);
usb_anchor_urb(urb, &dev->submitted);
- ret = usb_submit_urb(urb, GFP_KERNEL);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret) {
dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret);
usb_unanchor_urb(urb);
@@ -154,7 +154,7 @@
return -ENODEV;
}
- urb = usb_alloc_urb(0, GFP_KERNEL);
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
err("unable to allocate urb");
return -ENOMEM;
@@ -165,7 +165,7 @@
diag_bridge_write_cb, dev);
usb_anchor_urb(urb, &dev->submitted);
- ret = usb_submit_urb(urb, GFP_KERNEL);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret) {
err("submitting urb failed err:%d", ret);
usb_unanchor_urb(urb);
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index 80b0a80..7c44a9a 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -872,7 +872,9 @@
}
static const struct usb_device_id bridge_ids[] = {
- { USB_DEVICE(0x5c6, 0x9001) },
+ { USB_DEVICE(0x5c6, 0x9001) },
+
+ { } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, bridge_ids);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index f8b320f..ec922f1 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -39,6 +39,7 @@
#include <linux/mfd/pm8xxx/pm8921-charger.h>
#include <mach/clk.h>
+#include <mach/msm_xo.h>
#define MSM_USB_BASE (motg->regs)
#define DRIVER_NAME "msm_otg"
@@ -506,14 +507,15 @@
return ret;
}
- ulpi_init(motg);
-
ret = msm_otg_link_reset(motg);
if (ret) {
dev_err(otg->dev, "link reset failed\n");
return ret;
}
msleep(100);
+
+ ulpi_init(motg);
+
/* Ensure that RESET operation is completed before turning off clock */
mb();
@@ -568,6 +570,7 @@
int cnt = 0;
bool session_active;
u32 phy_ctrl_val = 0;
+ unsigned ret;
if (atomic_read(&motg->in_lpm))
return 0;
@@ -661,6 +664,12 @@
if (!IS_ERR(motg->pclk_src))
clk_disable(motg->pclk_src);
+ /* usb phy no more require TCXO clock, hence vote for TCXO disable */
+ ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_OFF);
+ if (ret)
+ dev_err(otg->dev, "%s failed to devote for "
+ "TCXO D0 buffer%d\n", __func__, ret);
+
if (motg->caps & ALLOW_PHY_POWER_COLLAPSE && !session_active) {
msm_hsusb_ldo_enable(motg, 0);
motg->lpm_flags |= PHY_PWR_COLLAPSED;
@@ -695,11 +704,19 @@
int cnt = 0;
unsigned temp;
u32 phy_ctrl_val = 0;
+ unsigned ret;
if (!atomic_read(&motg->in_lpm))
return 0;
wake_lock(&motg->wlock);
+
+ /* Vote for TCXO when waking up the phy */
+ ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_ON);
+ if (ret)
+ dev_err(otg->dev, "%s failed to vote for "
+ "TCXO D0 buffer%d\n", __func__, ret);
+
if (!IS_ERR(motg->pclk_src))
clk_enable(motg->pclk_src);
@@ -2282,12 +2299,27 @@
goto free_regs;
}
+ motg->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, "usb");
+ if (IS_ERR(motg->xo_handle)) {
+ dev_err(&pdev->dev, "%s not able to get the handle "
+ "to vote for TCXO D0 buffer\n", __func__);
+ ret = PTR_ERR(motg->xo_handle);
+ goto free_regs;
+ }
+
+ ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_ON);
+ if (ret) {
+ dev_err(&pdev->dev, "%s failed to vote for TCXO "
+ "D0 buffer%d\n", __func__, ret);
+ goto free_xo_handle;
+ }
+
clk_enable(motg->pclk);
ret = msm_hsusb_init_vddcx(motg, 1);
if (ret) {
dev_err(&pdev->dev, "hsusb vddcx init failed\n");
- goto free_regs;
+ goto devote_xo_handle;
}
ret = msm_hsusb_config_vddcx(1);
@@ -2403,6 +2435,10 @@
msm_hsusb_ldo_init(motg, 0);
free_init_vddcx:
msm_hsusb_init_vddcx(motg, 0);
+devote_xo_handle:
+ msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_OFF);
+free_xo_handle:
+ msm_xo_put(motg->xo_handle);
free_regs:
iounmap(motg->regs);
put_core_clk:
@@ -2482,6 +2518,7 @@
clk_disable(motg->pclk_src);
clk_put(motg->pclk_src);
}
+ msm_xo_put(motg->xo_handle);
msm_hsusb_ldo_enable(motg, 0);
msm_hsusb_ldo_init(motg, 0);
msm_hsusb_init_vddcx(motg, 0);
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index f7bf993..35d1714 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -295,11 +295,11 @@
select FB_MSM_MIPI_DSI_SIMULATOR
default n
-config FB_MSM_OVERLAY_WRITEBACK
+config FB_MSM_OVERLAY0_WRITEBACK
depends on FB_MSM_OVERLAY
- bool "MDP overlay write back mode enable"
+ bool "MDP overlay0 write back mode enable"
---help---
- Support for MDP4 OVERLAY write back mode
+ Support for MDP4 OVERLAY0 write back mode
config FB_MSM_WRITEBACK_MSM_PANEL
depends on FB_MSM_OVERLAY
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 1f24cea..0f1d19b 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -51,6 +51,12 @@
static int msm_hdmi_sample_rate = MSM_HDMI_SAMPLE_RATE_48KHZ;
+/* HDMI/HDCP Registers */
+#define HDCP_DDC_STATUS 0x0128
+#define HDCP_DDC_CTRL_0 0x0120
+#define HDCP_DDC_CTRL_1 0x0124
+#define HDMI_DDC_CTRL 0x020C
+
struct workqueue_struct *hdmi_work_queue;
struct hdmi_msm_state_type *hdmi_msm_state;
@@ -1072,6 +1078,8 @@
DEV_DBG("calling reauthenticate from %s HDCP FAIL INT ",
__func__);
+ /* Clear AUTH_FAIL_INFO as well */
+ HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 7)));
return IRQ_HANDLED;
}
/* [8] DDC_XFER_REQ_INT [R] HDCP DDC Transfer Request
@@ -2156,8 +2164,109 @@
if (hdcp_link_status & 0x00000004)
hdcp_auth_info((hdcp_link_status & 0x000000F0) >> 4);
+
+ /* Disable HDCP interrupts */
+ HDMI_OUTP(0x0118, 0x0);
}
+static void check_and_clear_HDCP_DDC_Failure(void)
+{
+ int hdcp_ddc_ctrl1_reg;
+ int hdcp_ddc_status;
+ int failure;
+ int nack0;
+
+ /*
+ * Check for any DDC transfer failures
+ * 0x0128 HDCP_DDC_STATUS
+ * [16] FAILED Indicates that the last HDCP HW DDC transer
+ * failed. This occurs when a transfer is
+ * attempted with HDCP DDC disabled
+ * (HDCP_DDC_DISABLE=1) or the number of retries
+ * match HDCP_DDC_RETRY_CNT
+ *
+ * [14] NACK0 Indicates that the last HDCP HW DDC transfer
+ * was aborted due to a NACK on the first
+ * transaction - cleared by writing 0 to GO bit
+ */
+ hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
+ failure = (hdcp_ddc_status >> 16) & 0x1;
+ nack0 = (hdcp_ddc_status >> 14) & 0x1;
+ DEV_DBG("%s: On Entry: HDCP_DDC_STATUS = 0x%x, FAILURE = %d,"
+ "NACK0 = %d\n", __func__ , hdcp_ddc_status, failure, nack0);
+
+ if (failure == 0x1) {
+ /*
+ * Indicates that the last HDCP HW DDC transfer failed.
+ * This occurs when a transfer is attempted with HDCP DDC
+ * disabled (HDCP_DDC_DISABLE=1) or the number of retries
+ * matches HDCP_DDC_RETRY_CNT.
+ * Failure occured, let's clear it.
+ */
+ DEV_INFO("%s: DDC failure detected. HDCP_DDC_STATUS=0x%08x\n",
+ __func__, hdcp_ddc_status);
+ /*
+ * First, Disable DDC
+ * 0x0120 HDCP_DDC_CTRL_0
+ * [0] DDC_DISABLE Determines whether HDCP Ri and Pj reads
+ * are done unassisted by hardware or by
+ * software via HDMI_DDC (HDCP provides
+ * interrupts to request software
+ * transfers)
+ * 0 : Use Hardware DDC
+ * 1 : Use Software DDC
+ */
+ HDMI_OUTP(HDCP_DDC_CTRL_0, 0x1);
+
+ /*
+ * ACK the Failure to Clear it
+ * 0x0124 HDCP_DDC_CTRL_1
+ * [0] DDC_FAILED_ACK Write 1 to clear
+ * HDCP_STATUS.HDCP_DDC_FAILED
+ */
+ hdcp_ddc_ctrl1_reg = HDMI_INP(HDCP_DDC_CTRL_1);
+ HDMI_OUTP(HDCP_DDC_CTRL_1, hdcp_ddc_ctrl1_reg | 0x1);
+
+ /* Check if the FAILURE got Cleared */
+ hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
+ hdcp_ddc_status = (hdcp_ddc_status >> 16) & 0x1;
+ if (hdcp_ddc_status == 0x0) {
+ DEV_INFO("%s: HDCP DDC Failure has been cleared\n",
+ __func__);
+ } else {
+ DEV_WARN("%s: Error: HDCP DDC Failure DID NOT get"
+ "cleared\n", __func__);
+ }
+
+ /* Re-Enable HDCP DDC */
+ HDMI_OUTP(HDCP_DDC_CTRL_0, 0x0);
+ }
+
+ if (nack0 == 0x1) {
+ /*
+ * 0x020C HDMI_DDC_CTRL
+ * [3] SW_STATUS_RESET Write 1 to reset HDMI_DDC_SW_STATUS
+ * flags, will reset SW_DONE, ABORTED,
+ * TIMEOUT, SW_INTERRUPTED,
+ * BUFFER_OVERFLOW, STOPPED_ON_NACK, NACK0,
+ * NACK1, NACK2, NACK3
+ */
+ HDMI_OUTP_ND(HDMI_DDC_CTRL,
+ HDMI_INP(HDMI_DDC_CTRL) | (0x1 << 3));
+ msleep(20);
+ HDMI_OUTP_ND(HDMI_DDC_CTRL,
+ HDMI_INP(HDMI_DDC_CTRL) & ~(0x1 << 3));
+ }
+
+ hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
+
+ failure = (hdcp_ddc_status >> 16) & 0x1;
+ nack0 = (hdcp_ddc_status >> 14) & 0x1;
+ DEV_DBG("%s: On Exit: HDCP_DDC_STATUS = 0x%x, FAILURE = %d,"
+ "NACK0 = %d\n", __func__ , hdcp_ddc_status, failure, nack0);
+}
+
+
static int hdcp_authentication_part1(void)
{
int ret = 0;
@@ -2275,6 +2384,12 @@
/* encryption_enable | enable */
HDMI_OUTP(0x0110, (1 << 8) | (1 << 0));
+ /*
+ * Check to see if a HDCP DDC Failure is indicated in
+ * HDCP_DDC_STATUS. If yes, clear it.
+ */
+ check_and_clear_HDCP_DDC_Failure();
+
/* 0x0118 HDCP_INT_CTRL
* [2] AUTH_SUCCESS_MASK [R/W] Mask bit for\
* HDCP Authentication
@@ -4344,6 +4459,9 @@
{
int rc;
+ if (cpu_is_msm8627())
+ return 0;
+
if (msm_fb_detect_client("hdmi_msm"))
return 0;
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 989b154..798cd03 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -57,7 +57,7 @@
struct semaphore mdp_ppp_mutex;
struct semaphore mdp_pipe_ctrl_mutex;
-unsigned long mdp_timer_duration = (HZ/50); /* 20 ms */
+unsigned long mdp_timer_duration = (HZ/20); /* 50 msecond */
boolean mdp_ppp_waiting = FALSE;
uint32 mdp_tv_underflow_cnt;
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index aae1711..84beb6a 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1833,7 +1833,6 @@
}
#endif
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
int mdp4_overlay_blt(struct fb_info *info, struct msmfb_overlay_blt *req)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
@@ -1876,7 +1875,6 @@
return ret;
}
-#endif
int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
{
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 9127485..4479ece 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -302,8 +302,6 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
-
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
int mdp4_dsi_overlay_blt_start(struct msm_fb_data_type *mfd)
{
unsigned long flag;
@@ -370,21 +368,6 @@
mdp4_dsi_overlay_blt_stop(mfd);
}
-#else
-int mdp4_dsi_overlay_blt_offset(struct msm_fb_data_type *mfd,
- struct msmfb_overlay_blt *req)
-{
- return 0;
-}
-int mdp4_dsi_overlay_blt_start(struct msm_fb_data_type *mfd)
-{
- return -EBUSY;
-}
-int mdp4_dsi_overlay_blt_stop(struct msm_fb_data_type *mfd)
-{
- return -EBUSY;
-}
-#endif
void mdp4_blt_xy_update(struct mdp4_overlay_pipe *pipe)
{
@@ -447,6 +430,7 @@
mdp_intr_mask &= ~INTR_DMA_P_DONE;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
}
+ mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
mdp_disable_irq_nosync(MDP_DMA2_TERM); /* disable intr */
return;
}
@@ -466,6 +450,8 @@
mdp4_stat.kickoff_dmap++;
/* trigger dsi cmd engine */
mipi_dsi_cmd_mdp_start();
+
+ mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
}
@@ -477,6 +463,7 @@
int diff;
if (dsi_pipe->blt_addr == 0) {
+ mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
spin_lock(&mdp_spin_lock);
dma->busy = FALSE;
spin_unlock(&mdp_spin_lock);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index dc4ef9a..938d7c6 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -545,8 +545,6 @@
complete(&dma->comp);
}
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
-
static void mdp4_overlay_dsi_video_prefill(struct msm_fb_data_type *mfd)
{
unsigned long flag;
@@ -659,24 +657,6 @@
{
mdp4_dsi_video_do_blt(mfd, 0);
}
-#else
-int mdp4_dsi_video_overlay_blt_offset(struct msm_fb_data_type *mfd,
- struct msmfb_overlay_blt *req)
-{
- return 0;
-}
-void mdp4_dsi_video_overlay_blt(struct msm_fb_data_type *mfd,
- struct msmfb_overlay_blt *req)
-{
- return;
-}
-void mdp4_dsi_video_blt_start(struct msm_fb_data_type *mfd)
-{
-}
-void mdp4_dsi_video_blt_stop(struct msm_fb_data_type *mfd)
-{
-}
-#endif
void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd)
{
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index a8e39d0..f318691 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -464,7 +464,6 @@
complete(&dma->comp);
}
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
/*
* make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile
* has enough space h * w * 3 * 2
@@ -531,24 +530,6 @@
{
mdp4_lcdc_do_blt(mfd, 0);
}
-#else
-int mdp4_lcdc_overlay_blt_offset(struct msm_fb_data_type *mfd,
- struct msmfb_overlay_blt *req)
-{
- return 0;
-}
-void mdp4_lcdc_overlay_blt(struct msm_fb_data_type *mfd,
- struct msmfb_overlay_blt *req)
-{
- return;
-}
-void mdp4_lcdc_overlay_blt_start(struct msm_fb_data_type *mfd)
-{
-}
-void mdp4_lcdc_overlay_blt_stop(struct msm_fb_data_type *mfd)
-{
-}
-#endif
void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd)
{
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index a177976..35af84d 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -1491,7 +1491,6 @@
if (isr & DSI_INTR_CMD_MDP_DONE) {
mipi_dsi_mdp_stat_inc(STAT_DSI_MDP);
- mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
spin_lock(&dsi_mdp_lock);
dsi_mdp_busy = FALSE;
spin_unlock(&dsi_mdp_lock);
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 10e4156..59c2afe 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2569,8 +2569,6 @@
return 0;
}
-
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
static int msmfb_overlay_blt(struct fb_info *info, unsigned long *argp)
{
int ret;
@@ -2607,16 +2605,6 @@
return ret;
}
-#else
-static int msmfb_overlay_blt(struct fb_info *info, unsigned long *argp)
-{
- return 0;
-}
-static int msmfb_overlay_blt_off(struct fb_info *info, unsigned long *argp)
-{
- return 0;
-}
-#endif
#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
static int msmfb_overlay_ioctl_writeback_init(struct fb_info *info)
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 3924088..75e0acf 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -1900,7 +1900,8 @@
VCD_MSG_HIGH("Got input done for EOS initiator");
transc->input_done = false;
transc->in_use = true;
- if (codec_config ||
+ if ((codec_config &&
+ (status != VCD_ERR_BITSTREAM_ERR)) ||
((status == VCD_ERR_BITSTREAM_ERR) &&
!(cctxt->status.mask & VCD_FIRST_IP_DONE) &&
(core_type == VCD_CORE_720P)))
diff --git a/fs/yaffs2/yaffs_vfs.c b/fs/yaffs2/yaffs_vfs.c
index a4db5cc..f56e12c 100644
--- a/fs/yaffs2/yaffs_vfs.c
+++ b/fs/yaffs2/yaffs_vfs.c
@@ -65,7 +65,7 @@
#define YPROC_ROOT NULL
-#define Y_INIT_TIMER(a) init_timer_on_stack(a)
+#define Y_INIT_TIMER(a, b, c) setup_deferrable_timer_on_stack(a, b, c)
#define WRITE_SIZE_STR "writesize"
#define WRITE_SIZE(mtd) ((mtd)->writesize)
@@ -1674,10 +1674,9 @@
if (time_before(expires, now))
expires = now + HZ;
- Y_INIT_TIMER(&timer);
+ Y_INIT_TIMER(&timer, yaffs_background_waker,
+ (unsigned long)current);
timer.expires = expires + 1;
- timer.data = (unsigned long)current;
- timer.function = yaffs_background_waker;
set_current_state(TASK_INTERRUPTIBLE);
add_timer(&timer);
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index e1b9e73..4900e9c 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -430,3 +430,4 @@
header-y += qcedev.h
header-y += idle_stats_device.h
header-y += genlock.h
+header-y += msm_audio_amrwb.h
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1d37f42..7213b52 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -11,6 +11,8 @@
#ifndef __LINUX_CLK_H
#define __LINUX_CLK_H
+#include <linux/kernel.h>
+
struct device;
/*
@@ -41,11 +43,31 @@
struct clk *clk_get(struct device *dev, const char *id);
/**
+ * clk_prepare - prepare a clock source
+ * @clk: clock source
+ *
+ * This prepares the clock source for use.
+ *
+ * Must not be called from within atomic context.
+ */
+#ifdef CONFIG_HAVE_CLK_PREPARE
+int clk_prepare(struct clk *clk);
+#else
+static inline int clk_prepare(struct clk *clk)
+{
+ might_sleep();
+ return 0;
+}
+#endif
+
+/**
* clk_enable - inform the system when the clock source should be running.
* @clk: clock source
*
* If the clock can not be enabled/disabled, this should return success.
*
+ * May be called from atomic contexts.
+ *
* Returns success (0) or negative errno.
*/
int clk_enable(struct clk *clk);
@@ -57,6 +79,8 @@
* Inform the system that a clock source is no longer required by
* a driver and may be shut down.
*
+ * May be called from atomic contexts.
+ *
* Implementation detail: if the clock source is shared between
* multiple drivers, clk_enable() calls must be balanced by the
* same number of clk_disable() calls for the clock source to be
@@ -64,6 +88,25 @@
*/
void clk_disable(struct clk *clk);
+
+/**
+ * clk_unprepare - undo preparation of a clock source
+ * @clk: clock source
+ *
+ * This undoes a previously prepared clock. The caller must balance
+ * the number of prepare and unprepare calls.
+ *
+ * Must not be called from within atomic context.
+ */
+#ifdef CONFIG_HAVE_CLK_PREPARE
+void clk_unprepare(struct clk *clk);
+#else
+static inline void clk_unprepare(struct clk *clk)
+{
+ might_sleep();
+}
+#endif
+
/**
* clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
* This is only valid once the clock source has been enabled.
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 07890ac..c73fdf8 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -28,6 +28,9 @@
extern unsigned long num_physpages;
extern unsigned long totalram_pages;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+extern unsigned long total_unmovable_pages;
+#endif
extern void * high_memory;
extern int page_cluster;
diff --git a/include/linux/msm_audio_amrwb.h b/include/linux/msm_audio_amrwb.h
new file mode 100644
index 0000000..2383743
--- /dev/null
+++ b/include/linux/msm_audio_amrwb.h
@@ -0,0 +1,18 @@
+#ifndef __MSM_AUDIO_AMRWB_H
+#define __MSM_AUDIO_AMRWB_H
+
+#include <linux/msm_audio.h>
+
+#define AUDIO_GET_AMRWB_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \
+ (AUDIO_MAX_COMMON_IOCTL_NUM+0), \
+ struct msm_audio_amrwb_enc_config)
+#define AUDIO_SET_AMRWB_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \
+ (AUDIO_MAX_COMMON_IOCTL_NUM+1), \
+ struct msm_audio_amrwb_enc_config)
+
+struct msm_audio_amrwb_enc_config {
+ uint32_t band_mode;
+ uint32_t dtx_enable;
+ uint32_t frame_format;
+};
+#endif /* __MSM_AUDIO_AMRWB_H */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index fc94089..473384b 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -55,6 +55,7 @@
PERF_COUNT_HW_BUS_CYCLES = 6,
PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7,
PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,
+ PERF_COUNT_HW_L2_CYCLES = 9,
PERF_COUNT_HW_MAX, /* non-ABI */
};
@@ -219,8 +220,9 @@
precise_ip : 2, /* skid constraint */
mmap_data : 1, /* non-exec mmap data */
sample_id_all : 1, /* sample_type all events */
+ single_instance:1, /* per-cpu event if unset */
- __reserved_1 : 45;
+ __reserved_1:44;
union {
__u32 wakeup_events; /* wakeup every n events */
diff --git a/include/linux/power/ltc4088-charger.h b/include/linux/power/ltc4088-charger.h
new file mode 100644
index 0000000..7a0bacf
--- /dev/null
+++ b/include/linux/power/ltc4088-charger.h
@@ -0,0 +1,30 @@
+/* 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 LTC4088_CHARGER_H_
+#define LTC4088_CHARGER_H_
+
+#define LTC4088_CHARGER_DEV_NAME "ltc4088-charger"
+
+/**
+ * struct ltc4088_charger_platform_data - platform data for LTC4088 charger
+ * @gpio_mode_select_d0: GPIO #pin for D0 charger line
+ * @gpio_mode_select_d1: GPIO #pin for D1 charger line
+ * @gpio_mode_select_d2: GPIO #pin for D2 charger line
+ */
+struct ltc4088_charger_platform_data {
+ unsigned int gpio_mode_select_d0;
+ unsigned int gpio_mode_select_d1;
+ unsigned int gpio_mode_select_d2;
+};
+
+#endif /* LTC4088_CHARGER_H_ */
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 2287c321..cab042b 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -157,6 +157,8 @@
enum power_supply_property psp);
void (*external_power_changed)(struct power_supply *psy);
void (*set_charged)(struct power_supply *psy);
+ int (*set_current_limit)(struct power_supply *psy, int limit);
+ int (*set_charging_by)(struct power_supply *psy, bool enable);
/* For APM emulation, think legacy userspace. */
int use_for_apm;
@@ -205,6 +207,8 @@
extern void power_supply_changed(struct power_supply *psy);
extern int power_supply_am_i_supplied(struct power_supply *psy);
extern int power_supply_set_battery_charged(struct power_supply *psy);
+extern int power_supply_set_current_limit(struct power_supply *psy, int limit);
+extern int power_supply_set_charging_by(struct power_supply *psy, bool enable);
#if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE)
extern int power_supply_is_system_supplied(void);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 4c01f5b..a2251fe 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -189,6 +189,7 @@
* connected.
* @mA_port: The amount of current drawn by the attached B-device.
* @id_timer: The timer used for polling ID line to detect ACA states.
+ * @xo_handle: TCXO buffer handle
*/
struct msm_otg {
struct otg_transceiver otg;
@@ -220,6 +221,7 @@
unsigned mA_port;
struct timer_list id_timer;
unsigned long caps;
+ struct msm_xo_voter *xo_handle;
/*
* Allowing PHY power collpase turns off the HSUSB 3.3v and 1.8v
* analog regulators while going to low power mode.
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index dbdb651..489c248 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -198,6 +198,7 @@
#define HCI_FM_STATION_DBG_PARAM_CMD 12
#define HCI_FM_ENABLE_TRANS_CMD 13
#define HCI_FM_DISABLE_TRANS_CMD 14
+#define HCI_FM_GET_TX_CONFIG 15
/* Defines for FM TX*/
@@ -241,14 +242,6 @@
__u8 rt_data[TX_RT_DATA_LENGTH];
} __packed;
-struct hci_fm_get_trans_conf_rsp {
- __u8 status;
- __u8 emphasis;
- __u8 rds_std;
- __u32 band_low_limit;
- __u32 band_high_limit;
-} __packed;
-
struct hci_fm_mute_mode_req {
__u8 hard_mute;
__u8 soft_mute;
@@ -428,6 +421,10 @@
struct hci_fm_recv_conf_req recv_conf_rsp;
} __packed;
+struct hci_fm_get_trans_conf_rsp {
+ __u8 status;
+ struct hci_fm_trans_conf_req_struct trans_conf_rsp;
+} __packed;
struct hci_fm_sig_threshold_rsp {
__u8 status;
__u8 sig_threshold;
@@ -547,17 +544,18 @@
V4L2_CID_PRIVATE_IRIS_SSBI_POKE,
V4L2_CID_PRIVATE_IRIS_TX_TONE,
V4L2_CID_PRIVATE_IRIS_RDS_GRP_COUNTERS,
- V4L2_CID_PRIVATE_IRIS_SET_NOTCH_FILTER,/*0x8000028*/
- /*0x8000029 is used for tavarua specific ioctl*/
- V4L2_CID_PRIVATE_IRIS_DO_CALIBRATION = 0x800002a,
- V4L2_CID_PRIVATE_IRIS_READ_DEFAULT = 0x00980928,/*using private CIDs
- under userclass*/
+ V4L2_CID_PRIVATE_IRIS_SET_NOTCH_FILTER, /* 0x8000028 */
+ V4L2_CID_PRIVATE_IRIS_SET_AUDIO_PATH, /* TAVARUA specific command */
+ V4L2_CID_PRIVATE_IRIS_DO_CALIBRATION,
+ V4L2_CID_PRIVATE_IRIS_SRCH_ALGORITHM, /* TAVARUA specific command */
+
+ /*using private CIDs under userclass*/
+ V4L2_CID_PRIVATE_IRIS_READ_DEFAULT = 0x00980928,
V4L2_CID_PRIVATE_IRIS_WRITE_DEFAULT,
V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION,
};
-
enum iris_evt_t {
IRIS_EVT_RADIO_READY,
IRIS_EVT_TUNE_SUCC,
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index 43ce153..d40829e 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -148,13 +148,14 @@
V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA,
V4L2_CID_PRIVATE_TAVARUA_HLSI,
/*
- * Here We have IOCTl's that are specifici to IRIS
- * (V4L2_CID_PRIVATE_BASE+0x1D--V4L2_CID_PRIVATE_BASE+0x27)
+ * Here we have IOCTl's that are specific to IRIS
+ * (V4L2_CID_PRIVATE_BASE + 0x1E to V4L2_CID_PRIVATE_BASE + 0x27)
*/
V4L2_CID_PRIVATE_TAVARUA_SET_NOTCH_FILTER =
- V4L2_CID_PRIVATE_BASE + 0x28,
+ V4L2_CID_PRIVATE_BASE + 0x28, /* IRIS specific command */
V4L2_CID_PRIVATE_TAVARUA_SET_AUDIO_PATH,
- /*0x800002a is used for iris specific ioctl*/
+ V4L2_CID_PRIVATE_TAVARUA_DO_CALIBRATION, /* IRIS specific command */
+ V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM,
V4L2_CID_PRIVATE_TAVARUA_ON_CHANNEL_THRESHOLD =
V4L2_CTRL_CLASS_USER + 0x92B,
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5a15cec..ca15ed0 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -576,7 +576,7 @@
{
atomic_inc(&chan->refcnt);
}
-void hci_chan_put(struct hci_chan *chan);
+int hci_chan_put(struct hci_chan *chan);
struct hci_chan *hci_chan_accept(struct hci_conn *hcon,
struct hci_ext_fs *tx_fs,
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 2480d18..e54ba63 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -646,8 +646,6 @@
next = ktime_add(next, tick_period);
}
local_irq_enable();
-
- printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n", smp_processor_id());
}
/*
@@ -857,10 +855,8 @@
}
#ifdef CONFIG_NO_HZ
- if (tick_nohz_enabled) {
+ if (tick_nohz_enabled)
ts->nohz_mode = NOHZ_MODE_HIGHRES;
- printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n", smp_processor_id());
- }
#endif
}
#endif /* HIGH_RES_TIMERS */
diff --git a/mm/Kconfig b/mm/Kconfig
index 8ca47a5..9f30530 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -136,7 +136,7 @@
bool "Allow for memory hot-add"
depends on SPARSEMEM || X86_64_ACPI_NUMA
depends on HOTPLUG && ARCH_ENABLE_MEMORY_HOTPLUG
- depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390)
+ depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390 || ARM)
config MEMORY_HOTPLUG_SPARSE
def_bool y
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index faf318e..70ea0df 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -379,6 +379,10 @@
unsigned long pfn = page_to_pfn(page);
totalram_pages++;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ if (zone_idx(page_zone(page)) != ZONE_MOVABLE)
+ total_unmovable_pages++;
+#endif
if (pfn >= num_physpages)
num_physpages = pfn + 1;
@@ -965,6 +969,10 @@
zone->zone_pgdat->node_present_pages -= offlined_pages;
totalram_pages -= offlined_pages;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ if (zone_idx(zone) != ZONE_MOVABLE)
+ total_unmovable_pages -= offlined_pages;
+#endif
init_per_zone_wmark_min();
if (!node_present_pages(node)) {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5489c43..60ad5e9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -96,6 +96,9 @@
unsigned long totalram_pages __read_mostly;
unsigned long totalreserve_pages __read_mostly;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+unsigned long total_unmovable_pages __read_mostly;
+#endif
int percpu_pagelist_fraction;
gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
@@ -174,6 +177,9 @@
};
EXPORT_SYMBOL(totalram_pages);
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+EXPORT_SYMBOL(total_unmovable_pages);
+#endif
static char * const zone_names[MAX_NR_ZONES] = {
#ifdef CONFIG_ZONE_DMA
diff --git a/mm/slub.c b/mm/slub.c
index adf609e..03bc30b 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -27,6 +27,7 @@
#include <linux/memory.h>
#include <linux/math64.h>
#include <linux/fault-inject.h>
+#include <linux/stacktrace.h>
#include <trace/events/kmem.h>
@@ -191,8 +192,12 @@
/*
* Tracking user of a slab.
*/
+#define TRACK_ADDRS_COUNT 16
struct track {
unsigned long addr; /* Called from address */
+#ifdef CONFIG_STACKTRACE
+ unsigned long addrs[TRACK_ADDRS_COUNT]; /* Called from address */
+#endif
int cpu; /* Was running on cpu */
int pid; /* Pid context */
unsigned long when; /* When did the operation occur */
@@ -420,6 +425,24 @@
struct track *p = get_track(s, object, alloc);
if (addr) {
+#ifdef CONFIG_STACKTRACE
+ struct stack_trace trace;
+ int i;
+
+ trace.nr_entries = 0;
+ trace.max_entries = TRACK_ADDRS_COUNT;
+ trace.entries = p->addrs;
+ trace.skip = 3;
+ save_stack_trace(&trace);
+
+ /* See rant in lockdep.c */
+ if (trace.nr_entries != 0 &&
+ trace.entries[trace.nr_entries - 1] == ULONG_MAX)
+ trace.nr_entries--;
+
+ for (i = trace.nr_entries; i < TRACK_ADDRS_COUNT; i++)
+ p->addrs[i] = 0;
+#endif
p->addr = addr;
p->cpu = smp_processor_id();
p->pid = current->pid;
@@ -444,6 +467,16 @@
printk(KERN_ERR "INFO: %s in %pS age=%lu cpu=%u pid=%d\n",
s, (void *)t->addr, jiffies - t->when, t->cpu, t->pid);
+#ifdef CONFIG_STACKTRACE
+ {
+ int i;
+ for (i = 0; i < TRACK_ADDRS_COUNT; i++)
+ if (t->addrs[i])
+ printk(KERN_ERR "\t%pS\n", (void *)t->addrs[i]);
+ else
+ break;
+ }
+#endif
}
static void print_tracking(struct kmem_cache *s, void *object)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 45ece89..c33d2ae 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1611,9 +1611,14 @@
struct vm_struct *area;
void *addr;
unsigned long real_size = size;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ unsigned long total_pages = total_unmovable_pages;
+#else
+ unsigned long total_pages = totalram_pages;
+#endif
size = PAGE_ALIGN(size);
- if (!size || (size >> PAGE_SHIFT) > totalram_pages)
+ if (!size || (size >> PAGE_SHIFT) > total_pages)
return NULL;
area = __get_vm_area_node(size, align, VM_ALLOC, start, end, node,
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h
index 8e6c061..e7ee531 100644
--- a/net/bluetooth/bnep/bnep.h
+++ b/net/bluetooth/bnep/bnep.h
@@ -155,6 +155,7 @@
unsigned int role;
unsigned long state;
unsigned long flags;
+ atomic_t terminate;
struct task_struct *task;
struct ethhdr eh;
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index dfadb65..61c946c 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -484,9 +484,11 @@
init_waitqueue_entry(&wait, current);
add_wait_queue(sk_sleep(sk), &wait);
- while (!kthread_should_stop()) {
+ while (1) {
set_current_state(TASK_INTERRUPTIBLE);
+ if (atomic_read(&s->terminate))
+ break;
/* RX */
while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
skb_orphan(skb);
@@ -643,9 +645,10 @@
down_read(&bnep_session_sem);
s = __bnep_get_session(req->dst);
- if (s)
- kthread_stop(s->task);
- else
+ if (s) {
+ atomic_inc(&s->terminate);
+ wake_up_process(s->task);
+ } else
err = -ENOENT;
up_read(&bnep_session_sem);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 5e67829..95718bb 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -505,13 +505,13 @@
return 0;
}
-void hci_chan_put(struct hci_chan *chan)
+int hci_chan_put(struct hci_chan *chan)
{
struct hci_cp_disconn_logical_link cp;
BT_DBG("chan %p refcnt %d", chan, atomic_read(&chan->refcnt));
if (!atomic_dec_and_test(&chan->refcnt))
- return;
+ return 0;
BT_DBG("chan->conn->state %d", chan->conn->state);
if (chan->conn->state == BT_CONNECTED) {
@@ -520,6 +520,8 @@
sizeof(cp), &cp);
} else
hci_chan_del(chan);
+
+ return 1;
}
EXPORT_SYMBOL(hci_chan_put);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 9ab0199..db8f3f5 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -549,8 +549,7 @@
l2cap_pi(sk)->ampcon->l2cap_data = NULL;
l2cap_pi(sk)->ampcon = NULL;
if (l2cap_pi(sk)->ampchan) {
- hci_chan_put(l2cap_pi(sk)->ampchan);
- if (atomic_read(&l2cap_pi(sk)->ampchan->refcnt))
+ if (!hci_chan_put(l2cap_pi(sk)->ampchan))
l2cap_deaggregate(l2cap_pi(sk)->ampchan,
l2cap_pi(sk));
}
@@ -3084,8 +3083,9 @@
if (new->sdu_arr_time)
new_rate = div_u64(new_rate, new->sdu_arr_time);
cur_rate = cur_rate + new_rate;
- agg->sdu_arr_time = div64_u64(agg->max_sdu * 1000000ULL,
- cur_rate);
+ if (cur_rate)
+ agg->sdu_arr_time = div64_u64(
+ agg->max_sdu * 1000000ULL, cur_rate);
}
}
}
@@ -3126,8 +3126,9 @@
if (old->sdu_arr_time)
old_rate = div_u64(old_rate, old->sdu_arr_time);
cur_rate = cur_rate - old_rate;
- agg->sdu_arr_time = div64_u64(agg->max_sdu * 1000000ULL,
- cur_rate);
+ if (cur_rate)
+ agg->sdu_arr_time = div64_u64(
+ agg->max_sdu * 1000000ULL, cur_rate);
}
}
@@ -3749,9 +3750,9 @@
/* Initialize rfc in case no rfc option is received */
rfc.mode = pi->mode;
- rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
- rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
- rfc.max_pdu_size = L2CAP_DEFAULT_MAX_PDU_SIZE;
+ rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
+ rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+ rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
while (len >= L2CAP_CONF_OPT_SIZE) {
len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
@@ -3849,9 +3850,9 @@
/* Initialize rfc in case no rfc option is received */
rfc.mode = pi->mode;
- rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
- rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
- rfc.max_pdu_size = L2CAP_DEFAULT_MAX_PDU_SIZE;
+ rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
+ rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+ rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
return;
@@ -5056,8 +5057,7 @@
if ((!l2cap_pi(sk)->amp_id) &&
(l2cap_pi(sk)->ampchan)) {
/* Have moved off of AMP, free the channel */
- hci_chan_put(l2cap_pi(sk)->ampchan);
- if (atomic_read(&l2cap_pi(sk)->ampchan->refcnt))
+ if (!hci_chan_put(l2cap_pi(sk)->ampchan))
l2cap_deaggregate(l2cap_pi(sk)->ampchan,
l2cap_pi(sk));
l2cap_pi(sk)->ampchan = NULL;
@@ -5115,8 +5115,7 @@
/* Have moved off of AMP, free the channel */
l2cap_pi(sk)->ampcon = NULL;
if (l2cap_pi(sk)->ampchan) {
- hci_chan_put(l2cap_pi(sk)->ampchan);
- if (atomic_read(&l2cap_pi(sk)->ampchan->refcnt))
+ if (!hci_chan_put(l2cap_pi(sk)->ampchan))
l2cap_deaggregate(l2cap_pi(sk)->ampchan,
l2cap_pi(sk));
}
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 0e59d1c..ba59920 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -39,6 +39,8 @@
#define BITS_PER_REG 8
#define TABLA_RX_DAI_ID 1
#define TABLA_TX_DAI_ID 2
+#define TABLA_CFILT_FAST_MODE 0x00
+#define TABLA_CFILT_SLOW_MODE 0x40
#define TABLA_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR)
@@ -60,6 +62,7 @@
u16 mbhc_reg;
u16 int_rbias;
u16 ctl_reg;
+ u8 cfilt_sel;
};
/* Codec supports 2 IIR filters */
@@ -90,6 +93,7 @@
bool clock_active;
bool config_mode_active;
bool mbhc_polling_active;
+ bool fake_insert_context;
int buttons_pressed;
struct tabla_mbhc_calibration *calibration;
@@ -1181,41 +1185,6 @@
return 0;
}
-static void tabla_codec_update_cfilt_usage(struct snd_soc_codec *codec,
- u8 cfilt_sel, int inc)
-{
- struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
- u32 *cfilt_cnt_ptr = NULL;
- u16 micb_cfilt_reg;
-
- switch (cfilt_sel) {
- case TABLA_CFILT1_SEL:
- cfilt_cnt_ptr = &tabla->cfilt1_cnt;
- micb_cfilt_reg = TABLA_A_MICB_CFILT_1_CTL;
- break;
- case TABLA_CFILT2_SEL:
- cfilt_cnt_ptr = &tabla->cfilt2_cnt;
- micb_cfilt_reg = TABLA_A_MICB_CFILT_2_CTL;
- break;
- case TABLA_CFILT3_SEL:
- cfilt_cnt_ptr = &tabla->cfilt3_cnt;
- micb_cfilt_reg = TABLA_A_MICB_CFILT_3_CTL;
- break;
- default:
- return; /* should not happen */
- }
-
- if (inc) {
- if (!(*cfilt_cnt_ptr)++)
- snd_soc_update_bits(codec, micb_cfilt_reg, 0x80, 0x80);
- } else {
- /* check if count not zero, decrement
- * then check if zero, go ahead disable cfilter
- */
- if ((*cfilt_cnt_ptr) && !--(*cfilt_cnt_ptr))
- snd_soc_update_bits(codec, micb_cfilt_reg, 0x80, 0);
- }
-}
static void tabla_codec_disable_button_presses(struct snd_soc_codec *codec)
{
@@ -1253,6 +1222,84 @@
}
}
+static void tabla_codec_switch_cfilt_mode(struct snd_soc_codec *codec,
+ int mode)
+{
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+ u8 reg_mode_val, cur_mode_val;
+ bool mbhc_was_polling = false;
+
+ if (mode)
+ reg_mode_val = TABLA_CFILT_FAST_MODE;
+ else
+ reg_mode_val = TABLA_CFILT_SLOW_MODE;
+
+ cur_mode_val = snd_soc_read(codec,
+ tabla->mbhc_bias_regs.cfilt_ctl) & 0x40;
+
+ if (cur_mode_val != reg_mode_val) {
+ if (tabla->mbhc_polling_active) {
+ tabla_codec_pause_hs_polling(codec);
+ mbhc_was_polling = true;
+ }
+ snd_soc_update_bits(codec,
+ tabla->mbhc_bias_regs.cfilt_ctl, 0x40, reg_mode_val);
+ if (mbhc_was_polling)
+ tabla_codec_start_hs_polling(codec);
+ pr_debug("%s: CFILT mode change (%x to %x)\n", __func__,
+ cur_mode_val, reg_mode_val);
+ } else {
+ pr_debug("%s: CFILT Value is already %x\n",
+ __func__, cur_mode_val);
+ }
+}
+
+static void tabla_codec_update_cfilt_usage(struct snd_soc_codec *codec,
+ u8 cfilt_sel, int inc)
+{
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+ u32 *cfilt_cnt_ptr = NULL;
+ u16 micb_cfilt_reg;
+
+ switch (cfilt_sel) {
+ case TABLA_CFILT1_SEL:
+ cfilt_cnt_ptr = &tabla->cfilt1_cnt;
+ micb_cfilt_reg = TABLA_A_MICB_CFILT_1_CTL;
+ break;
+ case TABLA_CFILT2_SEL:
+ cfilt_cnt_ptr = &tabla->cfilt2_cnt;
+ micb_cfilt_reg = TABLA_A_MICB_CFILT_2_CTL;
+ break;
+ case TABLA_CFILT3_SEL:
+ cfilt_cnt_ptr = &tabla->cfilt3_cnt;
+ micb_cfilt_reg = TABLA_A_MICB_CFILT_3_CTL;
+ break;
+ default:
+ return; /* should not happen */
+ }
+
+ if (inc) {
+ if (!(*cfilt_cnt_ptr)++) {
+ /* Switch CFILT to slow mode if MBHC CFILT being used */
+ if (cfilt_sel == tabla->mbhc_bias_regs.cfilt_sel)
+ tabla_codec_switch_cfilt_mode(codec, 0);
+
+ snd_soc_update_bits(codec, micb_cfilt_reg, 0x80, 0x80);
+ }
+ } else {
+ /* check if count not zero, decrement
+ * then check if zero, go ahead disable cfilter
+ */
+ if ((*cfilt_cnt_ptr) && !--(*cfilt_cnt_ptr)) {
+ snd_soc_update_bits(codec, micb_cfilt_reg, 0x80, 0);
+
+ /* Switch CFILT to fast mode if MBHC CFILT being used */
+ if (cfilt_sel == tabla->mbhc_bias_regs.cfilt_sel)
+ tabla_codec_switch_cfilt_mode(codec, 1);
+ }
+ }
+}
+
static int tabla_find_k_value(unsigned int ldoh_v, unsigned int cfilt_mv)
{
int rc = -EINVAL;
@@ -1306,10 +1353,13 @@
{
struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
int cfilt_k_val;
+ bool mbhc_was_polling = false;
switch (vddio_switch) {
case 1:
if (tabla->mbhc_polling_active) {
+
+ tabla_codec_pause_hs_polling(codec);
/* Enable Mic Bias switch to VDDIO */
tabla->cfilt_k_value = snd_soc_read(codec,
tabla->mbhc_bias_regs.cfilt_val);
@@ -1323,6 +1373,7 @@
tabla->mbhc_bias_regs.mbhc_reg, 0x80, 0x80);
snd_soc_update_bits(codec,
tabla->mbhc_bias_regs.mbhc_reg, 0x10, 0x00);
+ tabla_codec_start_hs_polling(codec);
tabla->mbhc_micbias_switched = true;
pr_debug("%s: Enabled MBHC Mic bias to VDDIO Switch\n",
@@ -1332,6 +1383,10 @@
case 0:
if (tabla->mbhc_micbias_switched) {
+ if (tabla->mbhc_polling_active) {
+ tabla_codec_pause_hs_polling(codec);
+ mbhc_was_polling = true;
+ }
/* Disable Mic Bias switch to VDDIO */
if (tabla->cfilt_k_value != 0)
snd_soc_update_bits(codec,
@@ -1342,6 +1397,9 @@
snd_soc_update_bits(codec,
tabla->mbhc_bias_regs.mbhc_reg, 0x10, 0x00);
+ if (mbhc_was_polling)
+ tabla_codec_start_hs_polling(codec);
+
tabla->mbhc_micbias_switched = false;
pr_debug("%s: Disabled MBHC Mic bias to VDDIO Switch\n",
__func__);
@@ -1661,6 +1719,8 @@
pr_err("%s: Invalid MIC BIAS for MBHC\n", __func__);
}
+ micbias_regs->cfilt_sel = cfilt;
+
switch (cfilt) {
case TABLA_CFILT1_SEL:
micbias_regs->cfilt_val = TABLA_A_MICB_CFILT_1_VAL;
@@ -2316,12 +2376,10 @@
unsigned int value)
{
int ret;
- pr_debug("%s: write reg %x val %x\n", __func__, reg, value);
BUG_ON(reg > TABLA_MAX_REGISTER);
if (!tabla_volatile(codec, reg)) {
- pr_debug("writing to cache\n");
ret = snd_soc_cache_write(codec, reg, value);
if (ret != 0)
dev_err(codec->dev, "Cache write to %x failed: %d\n",
@@ -2340,10 +2398,8 @@
if (!tabla_volatile(codec, reg) && tabla_readable(codec, reg) &&
reg < codec->driver->reg_cache_size) {
- pr_debug("reading from cache\n");
ret = snd_soc_cache_read(codec, reg, &val);
if (ret >= 0) {
- pr_debug("register %x, value %x\n", reg, val);
return val;
} else
dev_err(codec->dev, "Cache read from %x failed: %d\n",
@@ -2351,7 +2407,6 @@
}
val = tabla_reg_read(codec->control_data, reg);
- pr_debug("%s: read reg %x val %x\n", __func__, reg, val);
return val;
}
@@ -2858,6 +2913,7 @@
struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
struct tabla_mbhc_calibration *calibration = tabla->calibration;
short bias_value;
+ u8 cfilt_mode;
if (!calibration) {
pr_err("Error, no tabla calibration\n");
@@ -2876,9 +2932,11 @@
snd_soc_update_bits(codec, TABLA_A_TX_COM_BIAS, 0xE0, 0xE0);
-
- snd_soc_update_bits(codec,
- tabla->mbhc_bias_regs.cfilt_ctl, 0x70, 0x00);
+ /* Make sure CFILT is in fast mode, save current mode */
+ cfilt_mode = snd_soc_read(codec,
+ tabla->mbhc_bias_regs.cfilt_ctl);
+ snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
+ 0x70, 0x00);
snd_soc_update_bits(codec,
tabla->mbhc_bias_regs.ctl_reg, 0x1F, 0x16);
@@ -2901,7 +2959,7 @@
bias_value = tabla_codec_measure_micbias_voltage(codec, 0);
snd_soc_update_bits(codec,
- tabla->mbhc_bias_regs.cfilt_ctl, 0x40, 0x40);
+ tabla->mbhc_bias_regs.cfilt_ctl, 0x40, cfilt_mode);
snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x13, 0x00);
return bias_value;
@@ -2913,6 +2971,7 @@
struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
struct tabla_mbhc_calibration *calibration = tabla->calibration;
int central_bias_enabled = 0;
+ u8 wg_time;
if (!calibration) {
pr_err("Error, no tabla calibration\n");
@@ -2929,20 +2988,28 @@
0x81, 0x01);
snd_soc_update_bits(codec, tabla->mbhc_bias_regs.mbhc_reg,
0x90, 0x00);
+ wg_time = snd_soc_read(codec, TABLA_A_RX_HPH_CNP_WG_TIME) ;
+ wg_time += 1;
/* Enable HPH Schmitt Trigger */
- snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x13, 0x13);
+ snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x11, 0x11);
snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x0C,
calibration->hph_current << 2);
- /* Turn off HPH PAs during insertion detection to avoid false
- * insertion interrupts
+ /* Turn off HPH PAs and DAC's during insertion detection to
+ * avoid false insertion interrupts
*/
if (tabla->mbhc_micbias_switched)
tabla_codec_switch_micbias(codec, 0);
snd_soc_update_bits(codec, TABLA_A_RX_HPH_CNP_EN, 0x30, 0x00);
+ snd_soc_update_bits(codec, TABLA_A_RX_HPH_L_DAC_CTL,
+ 0xC0, 0x00);
+ snd_soc_update_bits(codec, TABLA_A_RX_HPH_R_DAC_CTL,
+ 0xC0, 0x00);
+ usleep_range(wg_time * 1000, wg_time * 1000);
/* setup for insetion detection */
+ snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x02, 0x02);
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x2, 0);
} else {
/* Make sure the HPH schmitt trigger is OFF */
@@ -3042,6 +3109,10 @@
tabla->calibration = calibration;
tabla_get_mbhc_micbias_regs(codec, &tabla->mbhc_bias_regs);
+ /* Put CFILT in fast mode by default */
+ snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
+ 0x40, TABLA_CFILT_FAST_MODE);
+
INIT_DELAYED_WORK(&tabla->btn0_dwork, btn0_lpress_fn);
INIT_WORK(&tabla->hphlocp_work, hphlocp_off_report);
INIT_WORK(&tabla->hphrocp_work, hphrocp_off_report);
@@ -3251,6 +3322,16 @@
0x90, 0x00);
snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x13, 0x00);
+ if (priv->fake_insert_context) {
+ pr_debug("%s: fake context interrupt, reset insertion\n",
+ __func__);
+ priv->fake_insert_context = false;
+ tabla_codec_shutdown_hs_polling(codec);
+ tabla_codec_enable_hs_detect(codec, 1);
+ return IRQ_HANDLED;
+ }
+
+
ldo_h_on = snd_soc_read(codec, TABLA_A_LDO_H_MODE_1) & 0x80;
micb_cfilt_on = snd_soc_read(codec,
priv->mbhc_bias_regs.cfilt_ctl) & 0x80;
@@ -3293,7 +3374,25 @@
if (mic_voltage > threshold_fake_insert) {
pr_debug("%s: Fake insertion interrupt, mic_voltage = %x\n",
__func__, mic_voltage);
- tabla_codec_enable_hs_detect(codec, 1);
+
+ /* Disable HPH trigger and enable MIC line trigger */
+ snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x12, 0x00);
+
+ snd_soc_update_bits(codec, priv->mbhc_bias_regs.mbhc_reg, 0x60,
+ priv->calibration->mic_current << 5);
+ snd_soc_update_bits(codec, priv->mbhc_bias_regs.mbhc_reg,
+ 0x80, 0x80);
+ usleep_range(priv->calibration->mic_pid,
+ priv->calibration->mic_pid);
+ snd_soc_update_bits(codec, priv->mbhc_bias_regs.mbhc_reg,
+ 0x10, 0x10);
+
+ /* Setup for insertion detection */
+ snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x2, 0);
+ priv->fake_insert_context = true;
+ tabla_enable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
+ snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x1, 0x1);
+
} else if (mic_voltage < threshold_no_mic) {
pr_debug("%s: Headphone Detected, mic_voltage = %x\n",
__func__, mic_voltage);
@@ -3661,6 +3760,7 @@
tabla->clock_active = false;
tabla->config_mode_active = false;
tabla->mbhc_polling_active = false;
+ tabla->fake_insert_context = false;
tabla->no_mic_headset_override = false;
tabla->codec = codec;
tabla->pdata = dev_get_platdata(codec->dev->parent);
diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile
index 568fd40..3b257a6 100644
--- a/sound/soc/msm/Makefile
+++ b/sound/soc/msm/Makefile
@@ -56,7 +56,7 @@
obj-$(CONFIG_SND_SOC_MSM_QDSP6_INTF) += qdsp6/
-snd-soc-qdsp6-objs := msm-dai-q6.o msm-pcm-q6.o msm-pcm-routing.o msm-dai-fe.o
+snd-soc-qdsp6-objs := msm-dai-q6.o msm-pcm-q6.o msm-pcm-routing.o msm-dai-fe.o msm-compr-q6.o
obj-$(CONFIG_SND_SOC_VOICE) += msm-pcm-voice.o msm-pcm-voip.o
snd-soc-qdsp6-objs += msm-pcm-lpa.o msm-pcm-afe.o
obj-$(CONFIG_SND_SOC_QDSP6) += snd-soc-qdsp6.o
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
new file mode 100644
index 0000000..cf6f1e7
--- /dev/null
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -0,0 +1,567 @@
+/* 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.
+ */
+
+
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/time.h>
+#include <linux/wait.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <asm/dma.h>
+#include <linux/dma-mapping.h>
+#include <linux/android_pmem.h>
+
+#include "msm-compr-q6.h"
+#include "msm-pcm-routing.h"
+
+static struct audio_locks the_locks;
+
+static struct snd_pcm_hardware msm_compr_hardware_playback = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = 1200 * 1024 * 2,
+ .period_bytes_min = 60 * 1024,
+ .period_bytes_max = 1200 * 1024,
+ .periods_min = 2,
+ .periods_max = 40,
+ .fifo_size = 0,
+};
+
+/* Conventional and unconventional sample rate supported */
+static unsigned int supported_sample_rates[] = {
+ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+};
+
+static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
+ .count = ARRAY_SIZE(supported_sample_rates),
+ .list = supported_sample_rates,
+ .mask = 0,
+};
+
+static void compr_event_handler(uint32_t opcode,
+ uint32_t token, uint32_t *payload, void *priv)
+{
+ struct compr_audio *compr = priv;
+ struct msm_audio *prtd = &compr->prtd;
+ struct snd_pcm_substream *substream = prtd->substream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct audio_aio_write_param param;
+ struct audio_buffer *buf = NULL;
+ int i = 0;
+
+ pr_debug("%s opcode =%08x\n", __func__, opcode);
+ switch (opcode) {
+ case ASM_DATA_EVENT_WRITE_DONE: {
+ uint32_t *ptrmem = (uint32_t *)¶m;
+ pr_debug("ASM_DATA_EVENT_WRITE_DONE\n");
+ pr_debug("Buffer Consumed = 0x%08x\n", *ptrmem);
+ prtd->pcm_irq_pos += prtd->pcm_count;
+ if (atomic_read(&prtd->start))
+ snd_pcm_period_elapsed(substream);
+ atomic_inc(&prtd->out_count);
+ wake_up(&the_locks.write_wait);
+ if (!atomic_read(&prtd->start)) {
+ prtd->pending_buffer = 1;
+ break;
+ } else
+ prtd->pending_buffer = 0;
+
+ if (runtime->status->hw_ptr >= runtime->control->appl_ptr)
+ break;
+ buf = prtd->audio_client->port[IN].buf;
+ pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
+ __func__, prtd->pcm_count, prtd->out_head);
+ pr_debug("%s:writing buffer[%d] from 0x%08x\n",
+ __func__, prtd->out_head,
+ ((unsigned int)buf[0].phys
+ + (prtd->out_head * prtd->pcm_count)));
+
+ param.paddr = (unsigned long)buf[0].phys
+ + (prtd->out_head * prtd->pcm_count);
+ param.len = prtd->pcm_count;
+ param.msw_ts = 0;
+ param.lsw_ts = 0;
+ param.flags = NO_TIMESTAMP;
+ param.uid = (unsigned long)buf[0].phys
+ + (prtd->out_head * prtd->pcm_count);
+ for (i = 0; i < sizeof(struct audio_aio_write_param)/4;
+ i++, ++ptrmem)
+ pr_debug("cmd[%d]=0x%08x\n", i, *ptrmem);
+ if (q6asm_async_write(prtd->audio_client,
+ ¶m) < 0)
+ pr_err("%s:q6asm_async_write failed\n",
+ __func__);
+ else
+ prtd->out_head =
+ (prtd->out_head + 1) & (runtime->periods - 1);
+ break;
+ }
+ case ASM_DATA_CMDRSP_EOS:
+ pr_debug("ASM_DATA_CMDRSP_EOS\n");
+ prtd->cmd_ack = 1;
+ wake_up(&the_locks.eos_wait);
+ break;
+ case APR_BASIC_RSP_RESULT: {
+ switch (payload[0]) {
+ case ASM_SESSION_CMD_RUN: {
+ if (!prtd->pending_buffer &&
+ !atomic_read(&prtd->start))
+ break;
+ pr_debug("%s:writing %d bytes"
+ " of buffer[%d] to dsp\n",
+ __func__, prtd->pcm_count, prtd->out_head);
+ buf = prtd->audio_client->port[IN].buf;
+ pr_debug("%s:writing buffer[%d] from 0x%08x\n",
+ __func__, prtd->out_head,
+ ((unsigned int)buf[0].phys
+ + (prtd->out_head * prtd->pcm_count)));
+ param.paddr = (unsigned long)buf[prtd->out_head].phys;
+ param.len = prtd->pcm_count;
+ param.msw_ts = 0;
+ param.lsw_ts = 0;
+ param.flags = NO_TIMESTAMP;
+ param.uid = (unsigned long)buf[prtd->out_head].phys;
+ if (q6asm_async_write(prtd->audio_client,
+ ¶m) < 0)
+ pr_err("%s:q6asm_async_write failed\n",
+ __func__);
+ else
+ prtd->out_head =
+ (prtd->out_head + 1)
+ & (runtime->periods - 1);
+ }
+ break;
+ case ASM_STREAM_CMD_FLUSH:
+ pr_debug("ASM_STREAM_CMD_FLUSH\n");
+ prtd->cmd_ack = 1;
+ wake_up(&the_locks.eos_wait);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ pr_debug("Not Supported Event opcode[0x%x]\n", opcode);
+ break;
+ }
+}
+
+static int msm_compr_playback_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct compr_audio *compr = runtime->private_data;
+ struct msm_audio *prtd = &compr->prtd;
+ int ret;
+
+ pr_debug("%s\n", __func__);
+ prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
+ prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
+ prtd->pcm_irq_pos = 0;
+ /* rate and channels are sent to audio driver */
+ prtd->samp_rate = runtime->rate;
+ prtd->channel_mode = runtime->channels;
+ prtd->out_head = 0;
+ if (prtd->enabled)
+ return 0;
+
+ ret = q6asm_media_format_block(prtd->audio_client, compr->codec);
+ if (ret < 0)
+ pr_info("%s: CMD Format block failed\n", __func__);
+
+ atomic_set(&prtd->out_count, runtime->periods);
+
+ prtd->enabled = 1;
+ prtd->cmd_ack = 0;
+
+ return 0;
+}
+
+static int msm_compr_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ int ret = 0;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct compr_audio *compr = runtime->private_data;
+ struct msm_audio *prtd = &compr->prtd;
+
+ pr_debug("%s\n", __func__);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ prtd->pcm_irq_pos = 0;
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ pr_debug("%s: Trigger start\n", __func__);
+ q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
+ atomic_set(&prtd->start, 1);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
+ atomic_set(&prtd->start, 0);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ pr_debug("SNDRV_PCM_TRIGGER_PAUSE\n");
+ q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
+ atomic_set(&prtd->start, 0);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static void populate_codec_list(struct compr_audio *compr,
+ struct snd_pcm_runtime *runtime)
+{
+ pr_debug("%s\n", __func__);
+ /* MP3 Block */
+ compr->info.compr_cap.num_codecs = 1;
+ compr->info.compr_cap.min_fragment_size = runtime->hw.period_bytes_min;
+ compr->info.compr_cap.max_fragment_size = runtime->hw.period_bytes_max;
+ compr->info.compr_cap.min_fragments = runtime->hw.periods_min;
+ compr->info.compr_cap.max_fragments = runtime->hw.periods_max;
+ compr->info.compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
+ /* Add new codecs here */
+}
+
+static int msm_compr_open(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
+ struct compr_audio *compr;
+ struct msm_audio *prtd;
+ int ret = 0;
+
+ /* Capture path */
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ return -EINVAL;
+
+ pr_debug("%s\n", __func__);
+ compr = kzalloc(sizeof(struct compr_audio), GFP_KERNEL);
+ if (compr == NULL) {
+ pr_err("Failed to allocate memory for msm_audio\n");
+ return -ENOMEM;
+ }
+ prtd = &compr->prtd;
+ prtd->substream = substream;
+ prtd->audio_client = q6asm_audio_client_alloc(
+ (app_cb)compr_event_handler, compr);
+ if (!prtd->audio_client) {
+ pr_info("%s: Could not allocate memory\n", __func__);
+ kfree(prtd);
+ return -ENOMEM;
+ }
+ runtime->hw = msm_compr_hardware_playback;
+
+ pr_info("%s: session ID %d\n", __func__, prtd->audio_client->session);
+
+ prtd->session_id = prtd->audio_client->session;
+ msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
+ prtd->session_id, substream->stream);
+
+ prtd->cmd_ack = 1;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_sample_rates);
+ if (ret < 0)
+ pr_info("snd_pcm_hw_constraint_list failed\n");
+ /* Ensure that buffer size is a multiple of period size */
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ pr_info("snd_pcm_hw_constraint_integer failed\n");
+
+ prtd->dsp_cnt = 0;
+ prtd->pending_buffer = 1;
+ compr->codec = FORMAT_MP3;
+ populate_codec_list(compr, runtime);
+ runtime->private_data = compr;
+
+ return 0;
+}
+
+static int msm_compr_playback_close(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
+ struct compr_audio *compr = runtime->private_data;
+ struct msm_audio *prtd = &compr->prtd;
+ int dir = 0;
+
+ pr_debug("%s\n", __func__);
+
+ dir = IN;
+
+ q6asm_cmd(prtd->audio_client, CMD_CLOSE);
+ q6asm_audio_client_buf_free_contiguous(dir,
+ prtd->audio_client);
+
+ msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
+ SNDRV_PCM_STREAM_PLAYBACK);
+ q6asm_audio_client_free(prtd->audio_client);
+ kfree(prtd);
+ return 0;
+}
+
+static int msm_compr_close(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ ret = msm_compr_playback_close(substream);
+ else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ ret = EINVAL;
+ return ret;
+}
+static int msm_compr_prepare(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ ret = msm_compr_playback_prepare(substream);
+ else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ ret = EINVAL;
+ return ret;
+}
+
+static snd_pcm_uframes_t msm_compr_pointer(struct snd_pcm_substream *substream)
+{
+
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct compr_audio *compr = runtime->private_data;
+ struct msm_audio *prtd = &compr->prtd;
+
+ if (prtd->pcm_irq_pos >= prtd->pcm_size)
+ prtd->pcm_irq_pos = 0;
+
+ pr_debug("pcm_irq_pos = %d\n", prtd->pcm_irq_pos);
+ return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
+}
+
+static int msm_compr_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ int result = 0;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct compr_audio *compr = runtime->private_data;
+ struct msm_audio *prtd = &compr->prtd;
+
+ pr_debug("%s\n", __func__);
+ prtd->mmap_flag = 1;
+ if (runtime->dma_addr && runtime->dma_bytes) {
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ result = remap_pfn_range(vma, vma->vm_start,
+ runtime->dma_addr >> PAGE_SHIFT,
+ runtime->dma_bytes,
+ vma->vm_page_prot);
+ } else {
+ pr_err("Physical address or size of buf is NULL");
+ return -EINVAL;
+ }
+ return result;
+}
+
+static int msm_compr_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct compr_audio *compr = runtime->private_data;
+ struct msm_audio *prtd = &compr->prtd;
+ struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
+ struct audio_buffer *buf;
+ int dir, ret;
+
+ pr_debug("%s\n", __func__);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dir = IN;
+ else
+ return -EINVAL;
+
+ ret = q6asm_open_write(prtd->audio_client, compr->codec);
+ if (ret < 0) {
+ pr_err("%s: Session out open failed\n", __func__);
+ return -ENOMEM;
+ }
+ ret = q6asm_set_io_mode(prtd->audio_client, ASYNC_IO_MODE);
+ if (ret < 0) {
+ pr_err("%s: Set IO mode failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = q6asm_audio_client_buf_alloc_contiguous(dir,
+ prtd->audio_client,
+ runtime->hw.period_bytes_min,
+ runtime->hw.periods_max);
+ if (ret < 0) {
+ pr_err("Audio Start: Buffer Allocation failed "
+ "rc = %d\n", ret);
+ return -ENOMEM;
+ }
+ buf = prtd->audio_client->port[dir].buf;
+
+ pr_debug("%s:buf = %p\n", __func__, buf);
+ dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
+ dma_buf->dev.dev = substream->pcm->card->dev;
+ dma_buf->private_data = NULL;
+ dma_buf->area = buf[0].data;
+ dma_buf->addr = buf[0].phys;
+ dma_buf->bytes = runtime->hw.buffer_bytes_max;
+ if (!dma_buf->area)
+ return -ENOMEM;
+
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+ return 0;
+}
+
+static int msm_compr_ioctl(struct snd_pcm_substream *substream,
+ unsigned int cmd, void *arg)
+{
+ int rc = 0;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct compr_audio *compr = runtime->private_data;
+ struct msm_audio *prtd = &compr->prtd;
+
+ switch (cmd) {
+ case SNDRV_COMPRESS_GET_CAPS:
+ pr_debug("SNDRV_COMPRESS_GET_CAPS\n");
+ if (copy_to_user((void *) arg, &compr->info.compr_cap,
+ sizeof(struct snd_compr_caps))) {
+ rc = -EFAULT;
+ pr_err("%s: ERROR: copy to user\n", __func__);
+ return rc;
+ }
+ return 0;
+ case SNDRV_COMPRESS_SET_PARAMS:
+ pr_debug("SNDRV_COMPRESS_SET_PARAMS: ");
+ if (copy_from_user(&compr->info.codec_param, (void *) arg,
+ sizeof(struct snd_compr_params))) {
+ rc = -EFAULT;
+ pr_err("%s: ERROR: copy from user\n", __func__);
+ return rc;
+ }
+ switch (compr->info.codec_param.codec.id) {
+ case SND_AUDIOCODEC_MP3:
+ /* For MP3 we dont need any other parameter */
+ pr_debug("SND_AUDIOCODEC_MP3\n");
+ compr->codec = FORMAT_MP3;
+ break;
+ default:
+ pr_debug("FORMAT_LINEAR_PCM\n");
+ compr->codec = FORMAT_LINEAR_PCM;
+ break;
+ }
+ return 0;
+ case SNDRV_PCM_IOCTL1_RESET:
+ prtd->cmd_ack = 0;
+ rc = q6asm_cmd(prtd->audio_client, CMD_FLUSH);
+ if (rc < 0)
+ pr_err("%s: flush cmd failed rc=%d\n", __func__, rc);
+ rc = wait_event_timeout(the_locks.eos_wait,
+ prtd->cmd_ack, 5 * HZ);
+ if (rc < 0)
+ pr_err("Flush cmd timeout\n");
+ prtd->pcm_irq_pos = 0;
+ break;
+ default:
+ break;
+ }
+ return snd_pcm_lib_ioctl(substream, cmd, arg);
+}
+
+static struct snd_pcm_ops msm_compr_ops = {
+ .open = msm_compr_open,
+ .hw_params = msm_compr_hw_params,
+ .close = msm_compr_close,
+ .ioctl = msm_compr_ioctl,
+ .prepare = msm_compr_prepare,
+ .trigger = msm_compr_trigger,
+ .pointer = msm_compr_pointer,
+ .mmap = msm_compr_mmap,
+};
+
+static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_card *card = rtd->card->snd_card;
+ int ret = 0;
+
+ if (!card->dev->coherent_dma_mask)
+ card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+ return ret;
+}
+
+static struct snd_soc_platform_driver msm_soc_platform = {
+ .ops = &msm_compr_ops,
+ .pcm_new = msm_asoc_pcm_new,
+};
+
+static __devinit int msm_compr_probe(struct platform_device *pdev)
+{
+ pr_info("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
+ return snd_soc_register_platform(&pdev->dev,
+ &msm_soc_platform);
+}
+
+static int msm_compr_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_platform(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver msm_compr_driver = {
+ .driver = {
+ .name = "msm-compr-dsp",
+ .owner = THIS_MODULE,
+ },
+ .probe = msm_compr_probe,
+ .remove = __devexit_p(msm_compr_remove),
+};
+
+static int __init msm_soc_platform_init(void)
+{
+ init_waitqueue_head(&the_locks.enable_wait);
+ init_waitqueue_head(&the_locks.eos_wait);
+ init_waitqueue_head(&the_locks.write_wait);
+ init_waitqueue_head(&the_locks.read_wait);
+
+ return platform_driver_register(&msm_compr_driver);
+}
+module_init(msm_soc_platform_init);
+
+static void __exit msm_soc_platform_exit(void)
+{
+ platform_driver_unregister(&msm_compr_driver);
+}
+module_exit(msm_soc_platform_exit);
+
+MODULE_DESCRIPTION("PCM module platform driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/msm-compr-q6.h b/sound/soc/msm/msm-compr-q6.h
new file mode 100644
index 0000000..6dfbcce
--- /dev/null
+++ b/sound/soc/msm/msm-compr-q6.h
@@ -0,0 +1,36 @@
+/*
+ * 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 _MSM_COMPR_H
+#define _MSM_COMPR_H
+#include <sound/apr_audio.h>
+#include <sound/q6asm.h>
+#include <sound/snd_compress_params.h>
+#include <sound/compress_offload.h>
+#include <sound/compress_driver.h>
+
+#include "msm-pcm-q6.h"
+
+struct compr_info {
+ struct snd_compr_caps compr_cap;
+ struct snd_compr_codec_caps codec_caps;
+ struct snd_compr_params codec_param;
+};
+
+struct compr_audio {
+ struct msm_audio prtd;
+ struct compr_info info;
+ uint32_t codec;
+};
+
+#endif /*_MSM_COMPR_H*/
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 401c1a9..16d149e 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -151,6 +151,20 @@
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia3",
},
+ {
+ .playback = {
+ .stream_name = "MultiMedia4 Playback",
+ .rates = (SNDRV_PCM_RATE_8000_48000 |
+ SNDRV_PCM_RATE_KNOT),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_fe_Multimedia_dai_ops,
+ .name = "MultiMedia4",
+ },
/* FE DAIs created for hostless operation purpose */
{
.playback = {
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 97d0760..3573169 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -125,6 +125,8 @@
{INVALID_SESSION, INVALID_SESSION},
/* MULTIMEDIA3 */
{INVALID_SESSION, INVALID_SESSION},
+ /* MULTIMEDIA4 */
+ {INVALID_SESSION, INVALID_SESSION},
};
static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
@@ -615,6 +617,9 @@
SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
@@ -627,6 +632,9 @@
SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
@@ -639,6 +647,9 @@
SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = {
@@ -651,6 +662,9 @@
SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
@@ -663,6 +677,9 @@
SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
@@ -675,6 +692,9 @@
SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
@@ -687,6 +707,9 @@
SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
@@ -1014,6 +1037,7 @@
SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
@@ -1111,16 +1135,19 @@
{"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
{"HDMI Mixer", "MultiMedia1", "MM_DL1"},
{"HDMI Mixer", "MultiMedia2", "MM_DL2"},
{"HDMI Mixer", "MultiMedia3", "MM_DL3"},
+ {"HDMI Mixer", "MultiMedia4", "MM_DL4"},
{"HDMI", NULL, "HDMI Mixer"},
{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
@@ -1130,16 +1157,19 @@
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
{"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
@@ -1153,6 +1183,7 @@
{"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
{"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index db7552d..b7fc82a 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -31,6 +31,7 @@
MSM_FRONTEND_DAI_MULTIMEDIA1 = 0,
MSM_FRONTEND_DAI_MULTIMEDIA2,
MSM_FRONTEND_DAI_MULTIMEDIA3,
+ MSM_FRONTEND_DAI_MULTIMEDIA4,
MSM_FRONTEND_DAI_CS_VOICE,
MSM_FRONTEND_DAI_VOIP,
MSM_FRONTEND_DAI_AFE_RX,
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 268d2e5..ab7f9f7 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -1202,6 +1202,9 @@
case FORMAT_WMA_V10PRO:
open.format = WMA_V10PRO;
break;
+ case FORMAT_MP3:
+ open.format = MP3;
+ break;
default:
pr_err("%s: Invalid format[%d]\n", __func__, format);
goto fail_cmd;
@@ -1865,7 +1868,26 @@
q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
- fmt.format = format;
+ switch (format) {
+ case FORMAT_V13K:
+ fmt.format = V13K_FS;
+ break;
+ case FORMAT_EVRC:
+ fmt.format = EVRC_FS;
+ break;
+ case FORMAT_AMRWB:
+ fmt.format = AMRWB_FS;
+ break;
+ case FORMAT_AMRNB:
+ fmt.format = AMRNB_FS;
+ break;
+ case FORMAT_MP3:
+ fmt.format = MP3;
+ break;
+ default:
+ pr_err("Invalid format[%d]\n", format);
+ goto fail_cmd;
+ }
fmt.cfg_size = 0;
rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);