Merge "Bluetooth: Avoid link entering sniff mode during pairing process." into msm-3.0
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml
index deb6602..8af0a42 100644
--- a/Documentation/DocBook/v4l/pixfmt.xml
+++ b/Documentation/DocBook/v4l/pixfmt.xml
@@ -741,10 +741,55 @@
<row id="V4L2-PIX-FMT-MPEG">
<entry><constant>V4L2_PIX_FMT_MPEG</constant></entry>
<entry>'MPEG'</entry>
- <entry>MPEG stream. The actual format is determined by
+ <entry>MPEG multiplexed stream. The actual format is determined by
extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
<xref linkend="mpeg-control-id" />.</entry>
</row>
+ <row id="V4L2-PIX-FMT-H264">
+ <entry><constant>V4L2_PIX_FMT_H264</constant></entry>
+ <entry>'H264'</entry>
+ <entry>H264 video elementary stream with start codes.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-H264-NO-SC">
+ <entry><constant>V4L2_PIX_FMT_H264_NO_SC</constant></entry>
+ <entry>'AVC1'</entry>
+ <entry>H264 video elementary stream without start codes.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-H263">
+ <entry><constant>V4L2_PIX_FMT_H263</constant></entry>
+ <entry>'H263'</entry>
+ <entry>H263 video elementary stream.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-MPEG1">
+ <entry><constant>V4L2_PIX_FMT_MPEG1</constant></entry>
+ <entry>'MPG1'</entry>
+ <entry>MPEG1 video elementary stream.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-MPEG2">
+ <entry><constant>V4L2_PIX_FMT_MPEG2</constant></entry>
+ <entry>'MPG2'</entry>
+ <entry>MPEG2 video elementary stream.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-MPEG4">
+ <entry><constant>V4L2_PIX_FMT_MPEG4</constant></entry>
+ <entry>'MPG4'</entry>
+ <entry>MPEG4 video elementary stream.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-XVID">
+ <entry><constant>V4L2_PIX_FMT_XVID</constant></entry>
+ <entry>'XVID'</entry>
+ <entry>Xvid video elementary stream.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-VC1-ANNEX-G">
+ <entry><constant>V4L2_PIX_FMT_VC1_ANNEX_G</constant></entry>
+ <entry>'VC1G'</entry>
+ <entry>VC1, SMPTE 421M Annex G compliant stream.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-VC1-ANNEX-L">
+ <entry><constant>V4L2_PIX_FMT_VC1_ANNEX_L</constant></entry>
+ <entry>'VC1L'</entry>
+ <entry>VC1, SMPTE 421M Annex L compliant stream.</entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/Documentation/genlock.txt b/Documentation/genlock.txt
index d3a44e2..6f24a76 100644
--- a/Documentation/genlock.txt
+++ b/Documentation/genlock.txt
@@ -82,15 +82,13 @@
Release a handle.
* struct genlock * genlock_create_lock(struct genlock_handle *)
-Create a new lock and attach it to the handle.
+Create a new lock and attach it to the handle. Once a lock is attached to a
+handle it stays attached until the handle is destroyed.
* struct genlock * genlock_attach_lock(struct genlock_handle *handle, int fd)
Given a valid file descriptor, get the lock associated with it and attach it to
the handle.
-* void genlock_release_lock(struct genlock_handle *)
-Release a lock attached to a handle.
-
* int genlock_lock(struct genlock_handle *, int op, int flags, u32 timeout)
Lock or unlock the lock attached to the handle. A zero timeout value will
be treated just like if the GENOCK_NOBLOCK flag is passed; if the lock
@@ -155,7 +153,4 @@
-EINVAL if a zero timeout is passed, or -ETIMEDOUT if the timeout expires.
* GENLOCK_IOC_RELEASE
-Use this to release an existing lock. This is useful if you wish to attach a
-different lock to the same handle. You do not need to call this under normal
-circumstances; when the handle is closed the reference to the lock is released.
-No data is passed from the user for this ioctl.
+This ioctl has been deprecated. Do not use.
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 3421fa1..a708fbc 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -33,6 +33,7 @@
CONFIG_ARCH_MSMCOPPER=y
CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_KERNEL_PMEM_EBI_REGION=y
CONFIG_CPU_HAS_L2_PMU=y
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
@@ -99,6 +100,8 @@
# CONFIG_BATTERY_MSM is not set
# CONFIG_HWMON is not set
# CONFIG_MFD_SUPPORT is not set
+CONFIG_ION=y
+CONFIG_ION_MSM=y
# CONFIG_HID_SUPPORT is not set
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_CI13XXX_MSM=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index fc1d81a..76ff09c 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -201,6 +201,7 @@
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 3cf01a1..3ddb0c9 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -201,6 +201,7 @@
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index a872cdc..07aeb32 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -257,6 +257,7 @@
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_PMIC8XXX=y
CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 3337d06..47736ea 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -258,6 +258,7 @@
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_PMIC8XXX=y
CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h
index d493d0b..ec4b8b8 100644
--- a/arch/arm/include/asm/fiq.h
+++ b/arch/arm/include/asm/fiq.h
@@ -33,11 +33,22 @@
void *dev_id;
};
+#ifdef CONFIG_FIQ
extern int claim_fiq(struct fiq_handler *f);
extern void release_fiq(struct fiq_handler *f);
extern void set_fiq_handler(void *start, unsigned int length);
extern void enable_fiq(int fiq);
extern void disable_fiq(int fiq);
+#else
+static inline int claim_fiq(struct fiq_handler *f)
+{
+ return 0;
+}
+static inline void release_fiq(struct fiq_handler *f) { }
+static inline void set_fiq_handler(void *start, unsigned int length) { }
+static inline void enable_fiq(int fiq) { }
+static inline void disable_fiq(int fiq) { }
+#endif
/* helpers defined in fiqasm.S: */
extern void __set_fiq_regs(unsigned long const *regs);
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 6a7158b..0083033 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -73,10 +73,6 @@
enum arm_perf_pmu_ids id;
const char *name;
irqreturn_t (*handle_irq)(int irq_num, void *dev);
-#ifdef CONFIG_SMP
- void (*secondary_enable)(unsigned int irq);
- void (*secondary_disable)(unsigned int irq);
-#endif
void (*enable)(struct hw_perf_event *evt, int idx);
void (*disable)(struct hw_perf_event *evt, int idx);
int (*get_event_idx)(struct cpu_hw_events *cpuc,
@@ -92,6 +88,8 @@
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX];
const unsigned (*event_map)[PERF_COUNT_HW_MAX];
+ int (*request_pmu_irq)(int irq, irq_handler_t *irq_h);
+ void (*free_pmu_irq)(int irq);
u32 raw_event_mask;
int num_events;
u64 max_period;
@@ -396,6 +394,21 @@
}
static int
+armpmu_generic_request_irq(int irq, irq_handler_t *handle_irq)
+{
+ return request_irq(irq, *handle_irq,
+ IRQF_DISABLED | IRQF_NOBALANCING,
+ "armpmu", NULL);
+}
+
+static void
+armpmu_generic_free_irq(int irq)
+{
+ if (irq >= 0)
+ free_irq(irq, NULL);
+}
+
+static int
armpmu_reserve_hardware(void)
{
struct arm_pmu_platdata *plat;
@@ -426,25 +439,20 @@
if (irq < 0)
continue;
- err = request_irq(irq, handle_irq,
- IRQF_DISABLED | IRQF_NOBALANCING,
- "armpmu", NULL);
+ err = armpmu->request_pmu_irq(irq, &handle_irq);
+
if (err) {
pr_warning("unable to request IRQ%d for ARM perf "
"counters\n", irq);
break;
-#ifdef CONFIG_SMP
- } else if (armpmu->secondary_enable) {
- armpmu->secondary_enable(irq);
-#endif
}
}
if (err) {
for (i = i - 1; i >= 0; --i) {
irq = platform_get_irq(pmu_device, i);
- if (irq >= 0)
- free_irq(irq, NULL);
+
+ armpmu->free_pmu_irq(irq);
}
release_pmu(pmu_device);
pmu_device = NULL;
@@ -460,13 +468,7 @@
for (i = pmu_device->num_resources - 1; i >= 0; --i) {
irq = platform_get_irq(pmu_device, i);
- if (irq >= 0) {
- free_irq(irq, NULL);
-#ifdef CONFIG_SMP
- if (armpmu->secondary_disable)
- armpmu->secondary_disable(irq);
-#endif
- }
+ armpmu->free_pmu_irq(irq);
}
armpmu->stop();
diff --git a/arch/arm/kernel/perf_event_msm.c b/arch/arm/kernel/perf_event_msm.c
index e37d2a7..a55ce3f 100644
--- a/arch/arm/kernel/perf_event_msm.c
+++ b/arch/arm/kernel/perf_event_msm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -11,6 +11,8 @@
* GNU General Public License for more details.
*/
+#include <linux/cpumask.h>
+
#include <asm/vfp.h>
#include <asm/system.h>
#include "../vfp/vfpinstr.h"
@@ -670,32 +672,52 @@
raw_spin_unlock_irqrestore(&pmu_lock, flags);
}
-#ifdef CONFIG_SMP
-static void scorpion_secondary_enable_callback(void *info)
+static void enable_irq_callback(void *info)
{
int irq = *(unsigned int *)info;
- if (irq_get_chip(irq)->irq_unmask)
- irq_get_chip(irq)->irq_unmask(irq_get_irq_data(irq));
+ enable_percpu_irq(irq, 0);
}
-static void scorpion_secondary_disable_callback(void *info)
+
+static void disable_irq_callback(void *info)
{
int irq = *(unsigned int *)info;
- if (irq_get_chip(irq)->irq_mask)
- irq_get_chip(irq)->irq_mask(irq_get_irq_data(irq));
+ disable_percpu_irq(irq);
}
-static void scorpion_secondary_enable(unsigned int irq)
+static int
+msm_request_irq(int irq, irq_handler_t *handle_irq)
{
- smp_call_function(scorpion_secondary_enable_callback, &irq, 1);
+ int err = 0;
+ int cpu;
+
+ err = request_percpu_irq(irq, *handle_irq, "armpmu",
+ &cpu_hw_events);
+
+ if (!err) {
+ for_each_cpu(cpu, cpu_online_mask) {
+ smp_call_function_single(cpu,
+ enable_irq_callback, &irq, 1);
+ }
+ }
+
+ return err;
}
-static void scorpion_secondary_disable(unsigned int irq)
+static void
+msm_free_irq(int irq)
{
- smp_call_function(scorpion_secondary_disable_callback, &irq, 1);
+ int cpu;
+
+ if (irq >= 0) {
+ for_each_cpu(cpu, cpu_online_mask) {
+ smp_call_function_single(cpu,
+ disable_irq_callback, &irq, 1);
+ }
+ free_percpu_irq(irq, &cpu_hw_events);
+ }
}
-#endif
static void scorpion_pmu_reset(void *info)
{
@@ -719,10 +741,8 @@
static struct arm_pmu scorpion_pmu = {
.handle_irq = armv7pmu_handle_irq,
-#ifdef CONFIG_SMP
- .secondary_enable = scorpion_secondary_enable,
- .secondary_disable = scorpion_secondary_disable,
-#endif
+ .request_pmu_irq = msm_request_irq,
+ .free_pmu_irq = msm_free_irq,
.enable = scorpion_pmu_enable_event,
.disable = scorpion_pmu_disable_event,
.read_counter = armv7pmu_read_counter,
diff --git a/arch/arm/kernel/perf_event_msm_krait.c b/arch/arm/kernel/perf_event_msm_krait.c
index 3c8fb84..1ce4dd6 100644
--- a/arch/arm/kernel/perf_event_msm_krait.c
+++ b/arch/arm/kernel/perf_event_msm_krait.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -498,10 +498,8 @@
static struct arm_pmu krait_pmu = {
.handle_irq = armv7pmu_handle_irq,
-#ifdef CONFIG_SMP
- .secondary_enable = scorpion_secondary_enable,
- .secondary_disable = scorpion_secondary_disable,
-#endif
+ .request_pmu_irq = msm_request_irq,
+ .free_pmu_irq = msm_free_irq,
.enable = krait_pmu_enable_event,
.disable = krait_pmu_disable_event,
.read_counter = armv7pmu_read_counter,
diff --git a/arch/arm/kernel/perf_event_msm_krait_l2.c b/arch/arm/kernel/perf_event_msm_krait_l2.c
index 335ccaf..baa05ac 100644
--- a/arch/arm/kernel/perf_event_msm_krait_l2.c
+++ b/arch/arm/kernel/perf_event_msm_krait_l2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -653,6 +653,8 @@
/* Avoid spurious interrupt if any */
get_reset_pmovsr();
+ raw_spin_lock_init(&hw_krait_l2_pmu.lock);
+
/* Don't return an arm_pmu here */
return NULL;
}
diff --git a/arch/arm/kernel/perf_event_msm_l2.c b/arch/arm/kernel/perf_event_msm_l2.c
index c242754..26753d8 100644
--- a/arch/arm/kernel/perf_event_msm_l2.c
+++ b/arch/arm/kernel/perf_event_msm_l2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -998,6 +998,8 @@
/* Avoid spurious interrupts at startup */
bb_l2_get_reset_pmovsr();
+ raw_spin_lock_init(&hw_bb_l2_pmu.lock);
+
/* Don't return an arm_pmu here */
return NULL;
}
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
index 0635b7e..8f9e4d0 100644
--- a/arch/arm/kernel/perf_event_v6.c
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -611,6 +611,8 @@
.id = ARM_PERF_PMU_ID_V6,
.name = "v6",
.handle_irq = armv6pmu_handle_irq,
+ .request_pmu_irq = armpmu_generic_request_irq,
+ .free_pmu_irq = armpmu_generic_free_irq,
.enable = armv6pmu_enable_event,
.disable = armv6pmu_disable_event,
.read_counter = armv6pmu_read_counter,
@@ -641,6 +643,8 @@
.id = ARM_PERF_PMU_ID_V6MP,
.name = "v6mpcore",
.handle_irq = armv6pmu_handle_irq,
+ .request_pmu_irq = armpmu_generic_request_irq,
+ .free_pmu_irq = armpmu_generic_free_irq,
.enable = armv6pmu_enable_event,
.disable = armv6mpcore_pmu_disable_event,
.read_counter = armv6pmu_read_counter,
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 3689e07..beb25c2 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -1178,6 +1178,8 @@
static struct arm_pmu armv7pmu = {
.handle_irq = armv7pmu_handle_irq,
+ .request_pmu_irq = armpmu_generic_request_irq,
+ .free_pmu_irq = armpmu_generic_free_irq,
.enable = armv7pmu_enable_event,
.disable = armv7pmu_disable_event,
.read_counter = armv7pmu_read_counter,
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
index 21977cf..aeb9d95 100644
--- a/arch/arm/kernel/perf_event_xscale.c
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -776,6 +776,8 @@
.id = ARM_PERF_PMU_ID_XSCALE2,
.name = "xscale2",
.handle_irq = xscale2pmu_handle_irq,
+ .request_pmu_irq = armpmu_generic_request_irq,
+ .free_pmu_irq = armpmu_generic_free_irq,
.enable = xscale2pmu_enable_event,
.disable = xscale2pmu_disable_event,
.read_counter = xscale2pmu_read_counter,
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 32b4a99..3f04ce0 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -8,6 +8,7 @@
select MSM_VIC
select CPU_V6
select MSM_REMOTE_SPINLOCK_SWP
+ select MSM_PM if PM
config ARCH_MSM7X25
bool "MSM7x25"
@@ -16,6 +17,7 @@
select CPU_V6
select MSM_REMOTE_SPINLOCK_SWP
select MULTI_IRQ_HANDLER
+ select MSM_PM if PM
config ARCH_MSM7X27
bool "MSM7x27"
@@ -32,6 +34,7 @@
select MSM_PROC_COMM_REGULATOR
select CLEANCACHE
select QCACHE
+ select MSM_PM2 if PM
config ARCH_MSM7X30
bool "MSM7x30"
@@ -55,6 +58,7 @@
select REGULATOR
select MSM_PROC_COMM_REGULATOR
select MULTI_IRQ_HANDLER
+ select MSM_PM2 if PM
config ARCH_QSD8X50
bool "QSD8X50"
@@ -66,6 +70,7 @@
select EMULATE_DOMAIN_MANAGER_V7
select MSM_GPIOMUX
select MSM_DALRPC
+ select MSM_PM2 if PM
config ARCH_MSM8X60
bool "MSM8X60"
@@ -121,6 +126,7 @@
select MSM_SPM_V1
select MSM_SCM if SMP
select MULTI_IRQ_HANDLER
+ select MSM_PM8X60 if PM
config ARCH_MSM8960
bool "MSM8960"
@@ -159,6 +165,7 @@
select QCACHE
select MSM_MULTIMEDIA_USE_ION
select MULTI_IRQ_HANDLER
+ select MSM_PM8X60 if PM
config ARCH_MSM8930
bool "MSM8930"
@@ -195,6 +202,7 @@
select FIX_MOVABLE_ZONE
select MSM_ULTRASOUND
select MULTI_IRQ_HANDLER
+ select MSM_PM8X60 if PM
config ARCH_APQ8064
bool "APQ8064"
@@ -212,6 +220,7 @@
select MSM_RPM
select MSM_SPM_V2
select MSM_L2_SPM
+ select MSM_PM8X60 if PM
config ARCH_MSMCOPPER
bool "MSM Copper"
@@ -222,6 +231,7 @@
select MSM_SCM if SMP
select MSM_GPIOMUX
select MULTI_IRQ_HANDLER
+ select MSM_MULTIMEDIA_USE_ION
config ARCH_FSM9XXX
bool "FSM9XXX"
@@ -246,6 +256,7 @@
select REGULATOR
select MSM_RPM_REGULATOR
select MULTI_IRQ_HANDLER
+ select MSM_PM8X60 if PM
config ARCH_MSM8625
bool "MSM8625"
@@ -763,7 +774,7 @@
config KERNEL_PMEM_EBI_REGION
bool "Enable in-kernel PMEM region for EBI"
default y if ARCH_MSM8X60
- depends on ANDROID_PMEM && (ARCH_MSM8X60 || ARCH_MSM8960)
+ depends on ANDROID_PMEM && (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSMCOPPER)
help
Enable the in-kernel PMEM allocator to use EBI memory.
@@ -1839,6 +1850,22 @@
config MSM_NATIVE_RESTART
bool
+config MSM_PM
+ depends on PM
+ bool
+
+config MSM_PM2
+ depends on PM
+ bool
+
+config MSM_PM8X60
+ depends on PM
+ bool
+
+config MSM_NOPM
+ default y if !PM
+ bool
+
config MSM_BUS_SCALING
bool "Bus scaling driver"
default n
@@ -2016,4 +2043,21 @@
instead of pmem. Selecting this may also involve userspace
dependencies as well.
+config MSM_RTB
+ bool "Register tracing"
+ help
+ Add support for logging different events to a small uncached
+ region. This is designed to aid in debugging reset cases where the
+ caches may not be flushed before the target resets.
+
+config MSM_RTB_SEPARATE_CPUS
+ bool "Separate entries for each cpu"
+ depends on MSM_RTB
+ help
+ Under some circumstances, it may be beneficial to give dedicated space
+ for each cpu to log accesses. Selecting this option will log each cpu
+ separately. This will guarantee that the last acesses for each cpu
+ will be logged but there will be fewer entries per cpu
+
+
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index a3ed7ab..ed85663 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -140,21 +140,11 @@
obj-$(CONFIG_MSM8X60_AUDIO) += qdsp6v2/
obj-$(CONFIG_MSM_AUDIO_QDSP6) += qdsp6v2/
obj-$(CONFIG_MSM_HW3D) += hw3d.o
-ifdef CONFIG_PM
- obj-$(CONFIG_ARCH_APQ8064) += pm-8x60.o
- obj-$(CONFIG_ARCH_MSM8960) += pm-8x60.o
- obj-$(CONFIG_ARCH_MSM8X60) += pm-8x60.o
- obj-$(CONFIG_ARCH_MSM9615) += pm-8x60.o
- obj-$(CONFIG_ARCH_QSD8X50) += pm2.o
- obj-$(CONFIG_ARCH_MSM7X30) += pm2.o
- obj-$(CONFIG_ARCH_MSM7X27) += pm2.o
- obj-$(CONFIG_ARCH_MSM7X27A) += pm2.o
- obj-$(CONFIG_ARCH_MSM7X25) += pm.o
- obj-$(CONFIG_ARCH_MSM7X01A) += pm.o
- obj-y += pm-boot.o
-else
- obj-y += no-pm.o
-endif
+obj-$(CONFIG_PM) += pm-boot.o
+obj-$(CONFIG_MSM_PM8X60) += pm-8x60.o
+obj-$(CONFIG_MSM_PM2) += pm2.o
+obj-$(CONFIG_MSM_PM) += pm.o
+obj-$(CONFIG_MSM_NOPM) += no-pm.o
obj-$(CONFIG_MSM_SPM_V1) += spm.o
obj-$(CONFIG_MSM_SPM_V2) += spm-v2.o spm_devices.o
@@ -222,11 +212,11 @@
obj-$(CONFIG_MACH_MSM7X27_SURF) += board-msm7x27.o devices-msm7x27.o
obj-$(CONFIG_MACH_MSM7X27_FFA) += board-msm7x27.o devices-msm7x27.o
obj-$(CONFIG_ARCH_MSM7X27A) += clock-pcom-lookup.o devices-msm7x27a.o
-obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7627A_EVB) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
+obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7627A_EVB) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
obj-$(CONFIG_ARCH_MSM8625) += devices-msm7x27a.o clock-pcom-lookup.o
obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o memory_topology.o
@@ -324,3 +314,4 @@
endif
obj-$(CONFIG_ARCH_MSM8960) += mdm2.o mdm_common.o
+obj-$(CONFIG_MSM_RTB) += msm_rtb.o
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index fa82e34..f8ecd5b 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -221,6 +221,7 @@
static DEFINE_SPINLOCK(wakelock_reference_lock);
static int wakelock_reference_count;
static struct delayed_work msm9615_bam_init_work;
+static int a2_pc_disabled_wakelock_skipped;
/* End A2 power collaspe */
/* subsystem restart */
@@ -1476,7 +1477,6 @@
static void ul_wakeup(void)
{
int ret;
- static int called_before;
mutex_lock(&wakeup_lock);
if (bam_is_connected) { /* bam got connected before lock grabbed */
@@ -1490,10 +1490,10 @@
* don't grab the wakelock the first time because it is
* already grabbed when a2 powers on
*/
- if (likely(called_before))
+ if (likely(a2_pc_disabled_wakelock_skipped))
grab_wakelock();
else
- called_before = 1;
+ a2_pc_disabled_wakelock_skipped = 1;
if (wait_for_dfab) {
ret = wait_for_completion_timeout(
&dfab_unvote_completion, HZ);
@@ -1717,6 +1717,7 @@
write_unlock_irqrestore(&ul_wakeup_lock, flags);
ul_powerdown_finish();
a2_pc_disabled = 0;
+ a2_pc_disabled_wakelock_skipped = 0;
/* Cleanup Channel States */
for (i = 0; i < BAM_DMUX_NUM_CHANNELS; ++i) {
@@ -1795,7 +1796,7 @@
if (bam_tx_pipe == NULL) {
pr_err("%s: tx alloc endpoint failed\n", __func__);
ret = -ENOMEM;
- goto register_bam_failed;
+ goto tx_alloc_endpoint_failed;
}
ret = sps_get_config(bam_tx_pipe, &tx_connection);
if (ret) {
@@ -1815,7 +1816,7 @@
if (tx_desc_mem_buf.base == NULL) {
pr_err("%s: tx memory alloc failed\n", __func__);
ret = -ENOMEM;
- goto tx_mem_failed;
+ goto tx_get_config_failed;
}
tx_desc_mem_buf.phys_base = dma_addr;
memset(tx_desc_mem_buf.base, 0x0, tx_desc_mem_buf.size);
@@ -1832,7 +1833,7 @@
if (bam_rx_pipe == NULL) {
pr_err("%s: rx alloc endpoint failed\n", __func__);
ret = -ENOMEM;
- goto tx_connect_failed;
+ goto rx_alloc_endpoint_failed;
}
ret = sps_get_config(bam_rx_pipe, &rx_connection);
if (ret) {
@@ -1901,15 +1902,16 @@
dma_free_coherent(NULL, rx_desc_mem_buf.size, rx_desc_mem_buf.base,
rx_desc_mem_buf.phys_base);
rx_mem_failed:
- sps_disconnect(bam_tx_pipe);
rx_get_config_failed:
sps_free_endpoint(bam_rx_pipe);
+rx_alloc_endpoint_failed:
+ sps_disconnect(bam_tx_pipe);
tx_connect_failed:
dma_free_coherent(NULL, tx_desc_mem_buf.size, tx_desc_mem_buf.base,
tx_desc_mem_buf.phys_base);
tx_get_config_failed:
sps_free_endpoint(bam_tx_pipe);
-tx_mem_failed:
+tx_alloc_endpoint_failed:
sps_deregister_bam_device(h);
/*
* sps_deregister_bam_device() calls iounmap. calling iounmap on the
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index f30f0bf..cd84722 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -13,9 +13,9 @@
#include <asm/mach-types.h>
#include <linux/i2c.h>
+#include <linux/gpio.h>
#include <mach/board.h>
#include <mach/msm_bus_board.h>
-#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
@@ -157,19 +157,6 @@
#ifdef CONFIG_MSM_CAMERA
-static uint16_t msm_cam_gpio_2d_tbl[] = {
- 5, /*CAMIF_MCLK*/
- 10, /*CAMIF_I2C_DATA*/
- 11, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
- .cam_gpiomux_conf_tbl = apq8064_cam_2d_configs,
- .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(apq8064_cam_2d_configs),
- .cam_gpio_tbl = msm_cam_gpio_2d_tbl,
- .cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
static struct msm_bus_vectors cam_init_vectors[] = {
{
.src = MSM_BUS_MASTER_VFE,
@@ -306,19 +293,57 @@
static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
{
- .ioclk.mclk_clk_rate = 24000000,
- .ioclk.vfe_clk_rate = 228570000,
.csid_core = 0,
+ .is_csiphy = 1,
+ .is_csid = 1,
+ .is_ispif = 1,
+ .is_vpe = 1,
.cam_bus_scale_table = &cam_bus_client_pdata,
},
{
- .ioclk.mclk_clk_rate = 24000000,
- .ioclk.vfe_clk_rate = 228570000,
.csid_core = 1,
+ .is_csiphy = 1,
+ .is_csid = 1,
+ .is_ispif = 1,
+ .is_vpe = 1,
.cam_bus_scale_table = &cam_bus_client_pdata,
},
};
+static struct camera_vreg_t msm_8064_back_cam_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+static struct gpio apq8064_common_cam_gpio[] = {
+ {5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+ {20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+ {21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
+static struct gpio apq8064_back_cam_gpio[] = {
+ {107, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl apq8064_back_cam_gpio_set_tbl[] = {
+ {107, GPIOF_OUT_INIT_LOW, 1000},
+ {107, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf apq8064_back_cam_gpio_conf = {
+ .cam_gpiomux_conf_tbl = apq8064_cam_2d_configs,
+ .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(apq8064_cam_2d_configs),
+ .cam_gpio_common_tbl = apq8064_common_cam_gpio,
+ .cam_gpio_common_tbl_size = ARRAY_SIZE(apq8064_common_cam_gpio),
+ .cam_gpio_req_tbl = apq8064_back_cam_gpio,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(apq8064_back_cam_gpio),
+ .cam_gpio_set_tbl = apq8064_back_cam_gpio_set_tbl,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(apq8064_back_cam_gpio_set_tbl),
+};
+
#ifdef CONFIG_IMX074
static struct msm_camera_sensor_flash_data flash_imx074 = {
.flash_type = MSM_CAMERA_FLASH_NONE,
@@ -326,10 +351,9 @@
static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
.mount_angle = 90,
- .sensor_reset = 107,
- .sensor_pwd = 85,
- .vcm_pwd = 0,
- .vcm_enable = 1,
+ .cam_vreg = msm_8064_back_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8064_back_cam_vreg),
+ .gpio_conf = &apq8064_back_cam_gpio_conf,
};
static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -337,7 +361,6 @@
.pdata = &msm_camera_csi_device_data[0],
.flash_data = &flash_imx074,
.sensor_platform_info = &sensor_board_info_imx074,
- .gpio_conf = &gpio_conf,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
};
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 032d8da..2182079 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -43,12 +43,19 @@
.dev_id = 0,
};
+static struct pm8xxx_rtc_platform_data
+apq8064_pm8921_rtc_pdata = {
+ .rtc_write_enable = false,
+ .rtc_alarm_powerup = false,
+};
+
static struct pm8921_platform_data
apq8064_pm8921_platform_data __devinitdata = {
.regulator_pdatas = msm8064_pm8921_regulator_pdata,
.irq_pdata = &apq8064_pm8921_irq_pdata,
.gpio_pdata = &apq8064_pm8921_gpio_pdata,
.mpp_pdata = &apq8064_pm8921_mpp_pdata,
+ .rtc_pdata = &apq8064_pm8921_rtc_pdata,
};
static struct pm8xxx_irq_platform_data
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 02fff0b..29b8afb 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1159,10 +1159,10 @@
static void __init apq8064_clock_init(void)
{
- if (machine_is_apq8064_sim())
- msm_clock_init(&apq8064_clock_init_data);
- else
+ if (machine_is_apq8064_rumi3())
msm_clock_init(&apq8064_dummy_clock_init_data);
+ else
+ msm_clock_init(&apq8064_clock_init_data);
}
static void __init apq8064_common_init(void)
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index a32699f..30c912e 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -12,9 +12,9 @@
*/
#include <asm/mach-types.h>
+#include <linux/gpio.h>
#include <mach/board.h>
#include <mach/msm_bus_board.h>
-#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
#include "board-8930.h"
@@ -95,7 +95,7 @@
};
-static struct msm_gpiomux_config msm8960_cam_common_configs[] = {
+static struct msm_gpiomux_config msm8930_cam_common_configs[] = {
{
.gpio = 2,
.settings = {
@@ -140,7 +140,7 @@
},
};
-static struct msm_gpiomux_config msm8960_cam_2d_configs[] = {
+static struct msm_gpiomux_config msm8930_cam_2d_configs[] = {
{
.gpio = 18,
.settings = {
@@ -172,20 +172,6 @@
};
#ifdef CONFIG_MSM_CAMERA
-
-static uint16_t msm_cam_gpio_2d_tbl[] = {
- 5, /*CAMIF_MCLK*/
- 20, /*CAMIF_I2C_DATA*/
- 21, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
- .cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
- .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
- .cam_gpio_tbl = msm_cam_gpio_2d_tbl,
- .cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
#define VFE_CAMIF_TIMER1_GPIO 2
#define VFE_CAMIF_TIMER2_GPIO 3
#define VFE_CAMIF_TIMER3_GPIO_INT 4
@@ -345,8 +331,6 @@
static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
{
- .ioclk.mclk_clk_rate = 24000000,
- .ioclk.vfe_clk_rate = 228570000,
.csid_core = 0,
.is_csiphy = 1,
.is_csid = 1,
@@ -355,8 +339,6 @@
.cam_bus_scale_table = &cam_bus_client_pdata,
},
{
- .ioclk.mclk_clk_rate = 24000000,
- .ioclk.vfe_clk_rate = 228570000,
.csid_core = 1,
.is_csiphy = 1,
.is_csid = 1,
@@ -366,6 +348,67 @@
},
};
+static struct camera_vreg_t msm_8930_back_cam_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+static struct camera_vreg_t msm_8930_front_cam_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+};
+
+static struct gpio msm8930_common_cam_gpio[] = {
+ {5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+ {20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+ {21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
+static struct gpio msm8930_front_cam_gpio[] = {
+ {76, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct gpio msm8930_back_cam_gpio[] = {
+ {107, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl msm8930_front_cam_gpio_set_tbl[] = {
+ {76, GPIOF_OUT_INIT_LOW, 1000},
+ {76, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_gpio_set_tbl msm8930_back_cam_gpio_set_tbl[] = {
+ {107, GPIOF_OUT_INIT_LOW, 1000},
+ {107, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf msm_8930_front_cam_gpio_conf = {
+ .cam_gpiomux_conf_tbl = msm8930_cam_2d_configs,
+ .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8930_cam_2d_configs),
+ .cam_gpio_common_tbl = msm8930_common_cam_gpio,
+ .cam_gpio_common_tbl_size = ARRAY_SIZE(msm8930_common_cam_gpio),
+ .cam_gpio_req_tbl = msm8930_front_cam_gpio,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(msm8930_front_cam_gpio),
+ .cam_gpio_set_tbl = msm8930_front_cam_gpio_set_tbl,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_front_cam_gpio_set_tbl),
+};
+
+static struct msm_camera_gpio_conf msm_8930_back_cam_gpio_conf = {
+ .cam_gpiomux_conf_tbl = msm8930_cam_2d_configs,
+ .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8930_cam_2d_configs),
+ .cam_gpio_common_tbl = msm8930_common_cam_gpio,
+ .cam_gpio_common_tbl_size = ARRAY_SIZE(msm8930_common_cam_gpio),
+ .cam_gpio_req_tbl = msm8930_back_cam_gpio,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio),
+ .cam_gpio_set_tbl = msm8930_back_cam_gpio_set_tbl,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio_set_tbl),
+};
+
#ifdef CONFIG_IMX074_ACT
static struct i2c_board_info imx074_actuator_i2c_info = {
I2C_BOARD_INFO("imx074_act", 0x11),
@@ -389,10 +432,9 @@
static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
.mount_angle = 90,
- .sensor_reset = 107,
- .sensor_pwd = 85,
- .vcm_pwd = 0,
- .vcm_enable = 1,
+ .cam_vreg = msm_8930_back_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8930_back_cam_vreg),
+ .gpio_conf = &msm_8930_back_cam_gpio_conf,
};
static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -401,7 +443,6 @@
.flash_data = &flash_imx074,
.strobe_flash_data = &strobe_flash_xenon,
.sensor_platform_info = &sensor_board_info_imx074,
- .gpio_conf = &gpio_conf,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
#ifdef CONFIG_IMX074_ACT
@@ -417,7 +458,9 @@
static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
.mount_angle = 90,
- .sensor_reset = 107,
+ .cam_vreg = msm_8930_back_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8930_back_cam_vreg),
+ .gpio_conf = &msm_8930_back_cam_gpio_conf,
};
static struct msm_camera_sensor_info msm_camera_sensor_mt9m114_data = {
@@ -425,7 +468,6 @@
.pdata = &msm_camera_csi_device_data[0],
.flash_data = &flash_mt9m114,
.sensor_platform_info = &sensor_board_info_mt9m114,
- .gpio_conf = &gpio_conf,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
};
@@ -438,10 +480,9 @@
static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
.mount_angle = 0,
- .sensor_reset = 76,
- .sensor_pwd = 85,
- .vcm_pwd = 0,
- .vcm_enable = 1,
+ .cam_vreg = msm_8930_front_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8930_front_cam_vreg),
+ .gpio_conf = &msm_8930_front_cam_gpio_conf,
};
static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
@@ -449,7 +490,6 @@
.pdata = &msm_camera_csi_device_data[1],
.flash_data = &flash_ov2720,
.sensor_platform_info = &sensor_board_info_ov2720,
- .gpio_conf = &gpio_conf,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
};
@@ -457,8 +497,8 @@
void __init msm8930_init_cam(void)
{
- msm_gpiomux_install(msm8960_cam_common_configs,
- ARRAY_SIZE(msm8960_cam_common_configs));
+ msm_gpiomux_install(msm8930_cam_common_configs,
+ ARRAY_SIZE(msm8930_cam_common_configs));
platform_device_register(&msm8960_device_csiphy0);
platform_device_register(&msm8960_device_csiphy1);
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index c652238..6c01764 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -70,6 +70,9 @@
REGULATOR_SUPPLY("iris_vddio", "wcnss_wlan.0"),
REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
REGULATOR_SUPPLY("sdc_vccq", "msm_sdcc.1"),
+ REGULATOR_SUPPLY("VDDIO_CDC", "sitar-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_TX", "sitar-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_RX", "sitar-slim"),
};
VREG_CONSUMERS(L12) = {
REGULATOR_SUPPLY("8038_l12", NULL),
@@ -97,6 +100,8 @@
};
VREG_CONSUMERS(L20) = {
REGULATOR_SUPPLY("8038_l20", NULL),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "sitar-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "sitar-slim"),
};
VREG_CONSUMERS(L21) = {
REGULATOR_SUPPLY("8038_l21", NULL),
@@ -138,6 +143,7 @@
};
VREG_CONSUMERS(S4) = {
REGULATOR_SUPPLY("8038_s4", NULL),
+ REGULATOR_SUPPLY("CDC_VDD_CP", "sitar-slim"),
};
VREG_CONSUMERS(S5) = {
REGULATOR_SUPPLY("8038_s5", NULL),
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index fc91337..f080d50 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -30,7 +30,6 @@
#ifdef CONFIG_ANDROID_PMEM
#include <linux/android_pmem.h>
#endif
-#include <linux/cyttsp.h>
#include <linux/dma-mapping.h>
#include <linux/platform_data/qcom_crypto_device.h>
#include <linux/platform_data/qcom_wcnss_device.h>
@@ -1339,128 +1338,6 @@
},
};
-#define CYTTSP_TS_GPIO_IRQ 11
-#define CYTTSP_TS_SLEEP_GPIO 50
-#define CYTTSP_TS_RESOUT_N_GPIO 52
-
-/*virtual key support */
-static ssize_t tma340_vkeys_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-{
- return snprintf(buf, 200,
- __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":73:1120:97:97"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":230:1120:97:97"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":389:1120:97:97"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":544:1120:97:97"
- "\n");
-}
-
-static struct kobj_attribute tma340_vkeys_attr = {
- .attr = {
- .mode = S_IRUGO,
- },
- .show = &tma340_vkeys_show,
-};
-
-static struct attribute *tma340_properties_attrs[] = {
- &tma340_vkeys_attr.attr,
- NULL
-};
-
-static struct attribute_group tma340_properties_attr_group = {
- .attrs = tma340_properties_attrs,
-};
-
-
-static int cyttsp_platform_init(struct i2c_client *client)
-{
- int rc = 0;
- static struct kobject *tma340_properties_kobj;
-
- tma340_vkeys_attr.attr.name = "virtualkeys.cyttsp-i2c";
- tma340_properties_kobj = kobject_create_and_add("board_properties",
- NULL);
- if (tma340_properties_kobj)
- rc = sysfs_create_group(tma340_properties_kobj,
- &tma340_properties_attr_group);
- if (!tma340_properties_kobj || rc)
- pr_err("%s: failed to create board_properties\n",
- __func__);
-
- return 0;
-}
-
-static struct cyttsp_regulator regulator_data[] = {
- {
- .name = "vdd",
- .min_uV = CY_TMA300_VTG_MIN_UV,
- .max_uV = CY_TMA300_VTG_MAX_UV,
- .hpm_load_uA = CY_TMA300_CURR_24HZ_UA,
- .lpm_load_uA = CY_TMA300_SLEEP_CURR_UA,
- },
- /* TODO: Remove after runtime PM is enabled in I2C driver */
- {
- .name = "vcc_i2c",
- .min_uV = CY_I2C_VTG_MIN_UV,
- .max_uV = CY_I2C_VTG_MAX_UV,
- .hpm_load_uA = CY_I2C_CURR_UA,
- .lpm_load_uA = CY_I2C_SLEEP_CURR_UA,
- },
-};
-
-static struct cyttsp_platform_data cyttsp_pdata = {
- .panel_maxx = 634,
- .panel_maxy = 1166,
- .disp_maxx = 616,
- .disp_maxy = 1023,
- .disp_minx = 0,
- .disp_miny = 16,
- .flags = 0x01,
- .gen = CY_GEN3, /* or */
- .use_st = CY_USE_ST,
- .use_mt = CY_USE_MT,
- .use_hndshk = CY_SEND_HNDSHK,
- .use_trk_id = CY_USE_TRACKING_ID,
- .use_sleep = CY_USE_DEEP_SLEEP_SEL | CY_USE_LOW_POWER_SEL,
- .use_gestures = CY_USE_GESTURES,
- .fw_fname = "cyttsp_8960_cdp.hex",
- /* activate up to 4 groups
- * and set active distance
- */
- .gest_set = CY_GEST_GRP1 | CY_GEST_GRP2 |
- CY_GEST_GRP3 | CY_GEST_GRP4 |
- CY_ACT_DIST,
- /* change act_intrvl to customize the Active power state
- * scanning/processing refresh interval for Operating mode
- */
- .act_intrvl = CY_ACT_INTRVL_DFLT,
- /* change tch_tmout to customize the touch timeout for the
- * Active power state for Operating mode
- */
- .tch_tmout = CY_TCH_TMOUT_DFLT,
- /* change lp_intrvl to customize the Low Power power state
- * scanning/processing refresh interval for Operating mode
- */
- .lp_intrvl = CY_LP_INTRVL_DFLT,
- .sleep_gpio = CYTTSP_TS_SLEEP_GPIO,
- .resout_gpio = CYTTSP_TS_RESOUT_N_GPIO,
- .irq_gpio = CYTTSP_TS_GPIO_IRQ,
- .regulator_info = regulator_data,
- .num_regulators = ARRAY_SIZE(regulator_data),
- .init = cyttsp_platform_init,
- .correct_fw_ver = 9,
-};
-
-static struct i2c_board_info cyttsp_info[] __initdata = {
- {
- I2C_BOARD_INFO(CY_I2C_NAME, 0x24),
- .platform_data = &cyttsp_pdata,
-#ifndef CY_USE_TIMER
- .irq = MSM_GPIO_TO_INT(CYTTSP_TS_GPIO_IRQ),
-#endif /* CY_USE_TIMER */
- },
-};
-
#define MXT_TS_GPIO_IRQ 11
#define MXT_TS_RESET_GPIO 52
@@ -1475,8 +1352,8 @@
27, 0, 5, 1, 0, 0, 8, 8, 0, 0,
/* T9 Object */
131, 0, 0, 19, 11, 0, 16, 35, 1, 3,
- 10, 15, 1, 11, 4, 5, 40, 10, 54, 2,
- 43, 4, 0, 0, 0, 0, 143, 40, 143, 80,
+ 10, 15, 1, 11, 4, 5, 40, 10, 43, 4,
+ 54, 2, 0, 0, 0, 0, 143, 40, 143, 80,
18, 15, 50, 50, 2,
/* T15 Object */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1513,10 +1390,10 @@
struct kobj_attribute *attr, char *buf)
{
return snprintf(buf, 200,
- __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":65:938:90:90"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":208:938:90:90"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":348:938:90:90"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":490:938:90:90"
+ __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":57:1030:90:90"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":206:1030:90:90"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":366:1030:90:90"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":503:1030:90:90"
"\n");
}
@@ -1568,8 +1445,10 @@
static struct mxt_platform_data mxt_platform_data_8930 = {
.config_array = mxt_config_array,
.config_array_size = ARRAY_SIZE(mxt_config_array),
- .x_size = 1067,
- .y_size = 566,
+ .x_size = 540,
+ .y_size = 960,
+ .touch_x_size = 566,
+ .touch_y_size = 1067,
.irqflags = IRQF_TRIGGER_FALLING,
#ifdef MSM8930_PHASE_2
.digital_pwr_regulator = true,
@@ -2140,12 +2019,6 @@
ARRAY_SIZE(isl_charger_i2c_info),
},
#endif /* CONFIG_ISL9519_CHARGER */
- {
- I2C_SURF | I2C_FFA | I2C_FLUID,
- MSM_8930_GSBI3_QUP_I2C_BUS_ID,
- cyttsp_info,
- ARRAY_SIZE(cyttsp_info),
- },
#ifndef MSM8930_PHASE_2
{
I2C_LIQUID,
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 2ad92b3..2995679 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -12,9 +12,9 @@
*/
#include <asm/mach-types.h>
+#include <linux/gpio.h>
#include <mach/board.h>
#include <mach/msm_bus_board.h>
-#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
#include "board-8960.h"
@@ -181,20 +181,6 @@
};
#ifdef CONFIG_MSM_CAMERA
-
-static uint16_t msm_cam_gpio_2d_tbl[] = {
- 5, /*CAMIF_MCLK*/
- 20, /*CAMIF_I2C_DATA*/
- 21, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
- .cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
- .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
- .cam_gpio_tbl = msm_cam_gpio_2d_tbl,
- .cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
#define VFE_CAMIF_TIMER1_GPIO 2
#define VFE_CAMIF_TIMER2_GPIO 3
#define VFE_CAMIF_TIMER3_GPIO_INT 4
@@ -350,8 +336,6 @@
static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
{
- .ioclk.mclk_clk_rate = 24000000,
- .ioclk.vfe_clk_rate = 228570000,
.csid_core = 0,
.is_csiphy = 1,
.is_csid = 1,
@@ -360,8 +344,6 @@
.cam_bus_scale_table = &cam_bus_client_pdata,
},
{
- .ioclk.mclk_clk_rate = 24000000,
- .ioclk.vfe_clk_rate = 228570000,
.csid_core = 1,
.is_csiphy = 1,
.is_csid = 1,
@@ -371,6 +353,67 @@
},
};
+static struct camera_vreg_t msm_8960_back_cam_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vio", REG_VS, 0, 0, 0},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
+};
+
+static struct camera_vreg_t msm_8960_front_cam_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vio", REG_VS, 0, 0, 0},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+};
+
+static struct gpio msm8960_common_cam_gpio[] = {
+ {5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+ {20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+ {21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
+static struct gpio msm8960_front_cam_gpio[] = {
+ {76, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct gpio msm8960_back_cam_gpio[] = {
+ {107, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl msm8960_front_cam_gpio_set_tbl[] = {
+ {76, GPIOF_OUT_INIT_LOW, 1000},
+ {76, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_gpio_set_tbl msm8960_back_cam_gpio_set_tbl[] = {
+ {107, GPIOF_OUT_INIT_LOW, 1000},
+ {107, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf msm_8960_front_cam_gpio_conf = {
+ .cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
+ .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
+ .cam_gpio_common_tbl = msm8960_common_cam_gpio,
+ .cam_gpio_common_tbl_size = ARRAY_SIZE(msm8960_common_cam_gpio),
+ .cam_gpio_req_tbl = msm8960_front_cam_gpio,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(msm8960_front_cam_gpio),
+ .cam_gpio_set_tbl = msm8960_front_cam_gpio_set_tbl,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(msm8960_front_cam_gpio_set_tbl),
+};
+
+static struct msm_camera_gpio_conf msm_8960_back_cam_gpio_conf = {
+ .cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
+ .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
+ .cam_gpio_common_tbl = msm8960_common_cam_gpio,
+ .cam_gpio_common_tbl_size = ARRAY_SIZE(msm8960_common_cam_gpio),
+ .cam_gpio_req_tbl = msm8960_back_cam_gpio,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(msm8960_back_cam_gpio),
+ .cam_gpio_set_tbl = msm8960_back_cam_gpio_set_tbl,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(msm8960_back_cam_gpio_set_tbl),
+};
+
#ifdef CONFIG_IMX074_ACT
static struct i2c_board_info imx074_actuator_i2c_info = {
I2C_BOARD_INFO("imx074_act", 0x11),
@@ -394,10 +437,9 @@
static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
.mount_angle = 90,
- .sensor_reset = 107,
- .sensor_pwd = 85,
- .vcm_pwd = 0,
- .vcm_enable = 1,
+ .cam_vreg = msm_8960_back_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_back_cam_vreg),
+ .gpio_conf = &msm_8960_back_cam_gpio_conf,
};
static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -406,7 +448,6 @@
.flash_data = &flash_imx074,
.strobe_flash_data = &strobe_flash_xenon,
.sensor_platform_info = &sensor_board_info_imx074,
- .gpio_conf = &gpio_conf,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
#ifdef CONFIG_IMX074_ACT
@@ -422,7 +463,9 @@
static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
.mount_angle = 90,
- .sensor_reset = 107,
+ .cam_vreg = msm_8960_back_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_back_cam_vreg),
+ .gpio_conf = &msm_8960_back_cam_gpio_conf,
};
static struct msm_camera_sensor_info msm_camera_sensor_mt9m114_data = {
@@ -430,7 +473,6 @@
.pdata = &msm_camera_csi_device_data[0],
.flash_data = &flash_mt9m114,
.sensor_platform_info = &sensor_board_info_mt9m114,
- .gpio_conf = &gpio_conf,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
};
@@ -443,10 +485,9 @@
static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
.mount_angle = 0,
- .sensor_reset = 76,
- .sensor_pwd = 85,
- .vcm_pwd = 0,
- .vcm_enable = 1,
+ .cam_vreg = msm_8960_front_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_front_cam_vreg),
+ .gpio_conf = &msm_8960_front_cam_gpio_conf,
};
static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
@@ -454,16 +495,36 @@
.pdata = &msm_camera_csi_device_data[1],
.flash_data = &flash_ov2720,
.sensor_platform_info = &sensor_board_info_ov2720,
- .gpio_conf = &gpio_conf,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
};
#endif
-static struct msm8960_privacy_light_cfg privacy_light_info = {
- .mpp = PM8921_MPP_PM_TO_SYS(12),
+static struct pm8xxx_mpp_config_data privacy_light_on_config = {
+ .type = PM8XXX_MPP_TYPE_SINK,
+ .level = PM8XXX_MPP_CS_OUT_5MA,
+ .control = PM8XXX_MPP_CS_CTRL_MPP_LOW_EN,
};
+static struct pm8xxx_mpp_config_data privacy_light_off_config = {
+ .type = PM8XXX_MPP_TYPE_SINK,
+ .level = PM8XXX_MPP_CS_OUT_5MA,
+ .control = PM8XXX_MPP_CS_CTRL_DISABLE,
+};
+
+static int32_t msm_camera_8960_ext_power_ctrl(int enable)
+{
+ int rc = 0;
+ if (enable) {
+ rc = pm8xxx_mpp_config(PM8921_MPP_PM_TO_SYS(12),
+ &privacy_light_on_config);
+ } else {
+ rc = pm8xxx_mpp_config(PM8921_MPP_PM_TO_SYS(12),
+ &privacy_light_off_config);
+ }
+ return rc;
+}
+
void __init msm8960_init_cam(void)
{
msm_gpiomux_install(msm8960_cam_common_configs,
@@ -488,9 +549,8 @@
s_info = &msm_camera_sensor_imx074_data;
s_info->sensor_platform_info->mount_angle = 180;
s_info = &msm_camera_sensor_ov2720_data;
- s_info->sensor_platform_info->privacy_light = 1;
- s_info->sensor_platform_info->privacy_light_info =
- &privacy_light_info;
+ s_info->sensor_platform_info->ext_power_ctrl =
+ msm_camera_8960_ext_power_ctrl;
}
platform_device_register(&msm8960_device_csiphy0);
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index c7e32c0..04376bc 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -449,14 +449,17 @@
{
.name = "led:red",
.flags = PM8XXX_ID_LED_0,
+ .default_trigger = "battery-charging",
},
{
.name = "led:green",
.flags = PM8XXX_ID_LED_0,
+ .default_trigger = "battery-full",
},
{
.name = "led:blue",
.flags = PM8XXX_ID_LED_2,
+ .default_trigger = "dc-online",
},
};
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index 5520bf9..6819d5d 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -217,6 +217,7 @@
};
VREG_CONSUMERS(USB_OTG) = {
REGULATOR_SUPPLY("8921_usb_otg", NULL),
+ REGULATOR_SUPPLY("vbus_otg", "msm_otg"),
};
VREG_CONSUMERS(HDMI_MVS) = {
REGULATOR_SUPPLY("8921_hdmi_mvs", NULL),
@@ -240,12 +241,12 @@
};
VREG_CONSUMERS(EXT_OTG_SW) = {
REGULATOR_SUPPLY("ext_otg_sw", NULL),
- REGULATOR_SUPPLY("vbus_otg", "msm_otg"),
};
#define PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \
_apply_uV, _pull_down, _always_on, _supply_regulator, \
- _system_uA, _enable_time, _reg_id) \
+ _system_uA, _enable_time, _reg_id, _ocp_enable, \
+ _ocp_enable_time) \
{ \
.init_data = { \
.constraints = { \
@@ -267,6 +268,8 @@
.pull_down_enable = _pull_down, \
.system_uA = _system_uA, \
.enable_time = _enable_time, \
+ .ocp_enable = _ocp_enable, \
+ .ocp_enable_time = _ocp_enable_time, \
}
#define PM8XXX_LDO(_id, _name, _always_on, _pull_down, _min_uV, _max_uV, \
@@ -275,7 +278,7 @@
| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
REGULATOR_CHANGE_DRMS, 0, _pull_down, _always_on, \
- _supply_regulator, _system_uA, _enable_time, _reg_id)
+ _supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
#define PM8XXX_NLDO1200(_id, _name, _always_on, _pull_down, _min_uV, \
_max_uV, _enable_time, _supply_regulator, _system_uA, _reg_id) \
@@ -283,7 +286,7 @@
| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
REGULATOR_CHANGE_DRMS, 0, _pull_down, _always_on, \
- _supply_regulator, _system_uA, _enable_time, _reg_id)
+ _supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
#define PM8XXX_SMPS(_id, _name, _always_on, _pull_down, _min_uV, _max_uV, \
_enable_time, _supply_regulator, _system_uA, _reg_id) \
@@ -291,32 +294,32 @@
| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
REGULATOR_CHANGE_DRMS, 0, _pull_down, _always_on, \
- _supply_regulator, _system_uA, _enable_time, _reg_id)
+ _supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
#define PM8XXX_FTSMPS(_id, _name, _always_on, _pull_down, _min_uV, _max_uV, \
_enable_time, _supply_regulator, _system_uA, _reg_id) \
PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, REGULATOR_MODE_NORMAL, \
REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS \
| REGULATOR_CHANGE_MODE, 0, _pull_down, _always_on, \
- _supply_regulator, _system_uA, _enable_time, _reg_id)
+ _supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
#define PM8XXX_VS(_id, _name, _always_on, _pull_down, _enable_time, \
- _supply_regulator, _reg_id) \
+ _ocp_enable, _ocp_enable_time, _supply_regulator, _reg_id) \
PM8XXX_VREG_INIT(_id, _name, 0, 0, 0, REGULATOR_CHANGE_STATUS, 0, \
_pull_down, _always_on, _supply_regulator, 0, _enable_time, \
- _reg_id)
+ _reg_id, _ocp_enable, _ocp_enable_time)
#define PM8XXX_VS300(_id, _name, _always_on, _pull_down, _enable_time, \
- _supply_regulator, _reg_id) \
+ _ocp_enable, _ocp_enable_time, _supply_regulator, _reg_id) \
PM8XXX_VREG_INIT(_id, _name, 0, 0, 0, REGULATOR_CHANGE_STATUS, 0, \
_pull_down, _always_on, _supply_regulator, 0, _enable_time, \
- _reg_id)
+ _reg_id, _ocp_enable, _ocp_enable_time)
#define PM8XXX_NCP(_id, _name, _always_on, _min_uV, _max_uV, _enable_time, \
_supply_regulator, _reg_id) \
PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, 0, \
REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, 0, 0, \
- _always_on, _supply_regulator, 0, _enable_time, _reg_id)
+ _always_on, _supply_regulator, 0, _enable_time, _reg_id, 0, 0)
/* Pin control initialization */
#define PM8XXX_PC(_id, _name, _always_on, _pin_fn, _pin_ctrl, \
@@ -465,7 +468,7 @@
GPIO_VREG(EXT_3P3V, "ext_3p3v", "ext_3p3v_en",
PM8921_GPIO_PM_TO_SYS(17), NULL),
GPIO_VREG(EXT_OTG_SW, "ext_otg_sw", "ext_otg_sw_en",
- PM8921_GPIO_PM_TO_SYS(42), "8921_usb_otg"),
+ PM8921_GPIO_PM_TO_SYS(42), "ext_5v"),
};
/* SAW regulator constraints */
@@ -491,9 +494,13 @@
PM8XXX_LDO(L29, "8921_l29", 0, 1, 2050000, 2100000, 200, "8921_s8",
0, 4),
- /* ID name always_on pd en_t supply reg_ID */
- PM8XXX_VS300(USB_OTG, "8921_usb_otg", 0, 1, 0, "ext_5v", 5),
- PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1, 0, "ext_5v", 6),
+ /*
+ * ID name always_on pd en_t ocp ocp_t supply
+ * reg_ID
+ */
+ PM8XXX_VS300(USB_OTG, "8921_usb_otg", 0, 0, 0, 1, 500, "ext_otg_sw",
+ 5),
+ PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1, 0, 0, 0, "ext_5v", 6),
};
static struct rpm_regulator_init_data
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index d628eeb..c5614b1 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1767,8 +1767,8 @@
&msm_device_saw_core0,
&msm_device_saw_core1,
&msm8960_device_ext_5v_vreg,
- &msm8960_device_ssbi_pmic,
&msm8960_device_ext_otg_sw_vreg,
+ &msm8960_device_ssbi_pmic,
&msm8960_device_qup_spi_gsbi1,
&msm8960_device_qup_i2c_gsbi3,
&msm8960_device_qup_i2c_gsbi4,
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index c89aee5..1bfb759 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -19,14 +19,192 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
+#ifdef CONFIG_ION_MSM
+#include <linux/ion.h>
+#endif
+#include <linux/memory.h>
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
#include <asm/mach/map.h>
#include <asm/hardware/gic.h>
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include <mach/msm_iomap.h>
+#ifdef CONFIG_ION_MSM
+#include <mach/ion.h>
+#endif
+#include <mach/msm_memtypes.h>
#include "clock.h"
+#define MSM_KERNEL_EBI1_MEM_SIZE 0x280000
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+#define MSM_ION_SF_SIZE 0x4000000 /* 64 Mbytes */
+#else
+#define MSM_ION_SF_SIZE 0x2800000 /* 40 Mbytes */
+#endif
+#define MSM_ION_MM_FW_SIZE 0x200000 /* (2MB) */
+#define MSM_ION_MM_SIZE 0x7800000 /* (120MB) */
+#define MSM_ION_QSECOM_SIZE 0x100000 /* (1MB) */
+#define MSM_ION_MFC_SIZE SZ_8K
+#define MSM_ION_AUDIO_SIZE 0x2B4000
+#define MSM_ION_HEAP_NUM 8
+
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+static unsigned kernel_ebi1_mem_size = MSM_KERNEL_EBI1_MEM_SIZE;
+static int __init kernel_ebi1_mem_size_setup(char *p)
+{
+ kernel_ebi1_mem_size = memparse(p, NULL);
+ return 0;
+}
+early_param("kernel_ebi1_mem_size", kernel_ebi1_mem_size_setup);
+#endif
+
+static struct memtype_reserve msm_copper_reserve_table[] __initdata = {
+ [MEMTYPE_SMI] = {
+ },
+ [MEMTYPE_EBI0] = {
+ .flags = MEMTYPE_FLAGS_1M_ALIGN,
+ },
+ [MEMTYPE_EBI1] = {
+ .flags = MEMTYPE_FLAGS_1M_ALIGN,
+ },
+};
+
+static int msm_copper_paddr_to_memtype(unsigned int paddr)
+{
+ return MEMTYPE_EBI1;
+}
+
+#ifdef CONFIG_ION_MSM
+static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
+ .permission_type = IPT_TYPE_MM_CARVEOUT,
+ .align = PAGE_SIZE,
+};
+
+static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
+ .permission_type = IPT_TYPE_MFC_SHAREDMEM,
+ .align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata co_ion_pdata = {
+ .adjacent_mem_id = INVALID_HEAP_ID,
+ .align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata fw_co_ion_pdata = {
+ .adjacent_mem_id = ION_CP_MM_HEAP_ID,
+ .align = SZ_128K,
+};
+
+static struct ion_platform_data ion_pdata = {
+ .nr = MSM_ION_HEAP_NUM,
+ .heaps = {
+ {
+ .id = ION_SYSTEM_HEAP_ID,
+ .type = ION_HEAP_TYPE_SYSTEM,
+ .name = ION_VMALLOC_HEAP_NAME,
+ },
+ {
+ .id = ION_SF_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_SF_HEAP_NAME,
+ .size = MSM_ION_SF_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ {
+ .id = ION_CP_MM_HEAP_ID,
+ .type = ION_HEAP_TYPE_CP,
+ .name = ION_MM_HEAP_NAME,
+ .size = MSM_ION_MM_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &cp_mm_ion_pdata,
+ },
+ {
+ .id = ION_MM_FIRMWARE_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_MM_FIRMWARE_HEAP_NAME,
+ .size = MSM_ION_MM_FW_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &fw_co_ion_pdata,
+ },
+ {
+ .id = ION_CP_MFC_HEAP_ID,
+ .type = ION_HEAP_TYPE_CP,
+ .name = ION_MFC_HEAP_NAME,
+ .size = MSM_ION_MFC_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &cp_mfc_ion_pdata,
+ },
+ {
+ .id = ION_IOMMU_HEAP_ID,
+ .type = ION_HEAP_TYPE_IOMMU,
+ .name = ION_IOMMU_HEAP_NAME,
+ },
+ {
+ .id = ION_QSECOM_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_QSECOM_HEAP_NAME,
+ .size = MSM_ION_QSECOM_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ {
+ .id = ION_AUDIO_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_AUDIO_HEAP_NAME,
+ .size = MSM_ION_AUDIO_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ }
+};
+
+static struct platform_device ion_dev = {
+ .name = "ion-msm",
+ .id = 1,
+ .dev = { .platform_data = &ion_pdata },
+};
+
+static void reserve_ion_memory(void)
+{
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += kernel_ebi1_mem_size;
+#endif
+}
+#endif
+
+static void __init msm_copper_calculate_reserve_sizes(void)
+{
+#ifdef CONFIG_ION_MSM
+ reserve_ion_memory();
+#endif
+}
+
+static struct reserve_info msm_copper_reserve_info __initdata = {
+ .memtype_reserve_table = msm_copper_reserve_table,
+ .calculate_reserve_sizes = msm_copper_calculate_reserve_sizes,
+ .paddr_to_memtype = msm_copper_paddr_to_memtype,
+};
+
+static void __init msm_copper_early_memory(void)
+{
+ reserve_info = &msm_copper_reserve_info;
+}
+
+void __init msm_copper_reserve(void)
+{
+ msm_reserve();
+}
+
static int __init gpiomux_init(void)
{
int rc;
@@ -42,6 +220,9 @@
void __init msm_copper_add_devices(void)
{
+#ifdef CONFIG_ION_MSM
+ platform_device_register(&ion_dev);
+#endif
}
static struct of_device_id irq_match[] __initdata = {
@@ -102,3 +283,8 @@
*adata = msm_copper_auxdata_lookup;
}
+
+void __init msm_copper_very_early(void)
+{
+ msm_copper_early_memory();
+}
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 6c5f74a..51ca29d 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -90,6 +90,18 @@
NULL
};
+static void __init msm_dt_reserve(void)
+{
+ if (early_machine_is_copper())
+ msm_copper_reserve();
+}
+
+static void __init msm_dt_init_very_early(void)
+{
+ if (early_machine_is_copper())
+ msm_copper_very_early();
+}
+
DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
.map_io = msm_dt_map_io,
.init_irq = msm_dt_init_irq,
@@ -98,4 +110,6 @@
.timer = &msm_dt_timer,
.dt_compat = msm_dt_match,
.nr_irqs = -1,
+ .reserve = msm_dt_reserve,
+ .init_very_early = msm_dt_init_very_early,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index c92a898..5acfcd5 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -100,6 +100,8 @@
{
if (machine_is_msm7627a_qrd1())
gpio_bt_sys_rest_en = 114;
+ if (machine_is_msm7627a_evb())
+ gpio_bt_sys_rest_en = 16;
}
static int bt_set_gpio(int on)
@@ -933,9 +935,6 @@
int i, rc = 0;
struct device *dev;
- if (machine_is_msm7627a_evb())
- return;
-
gpio_bt_config();
i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index bde38c3..e3f668f 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -479,8 +479,8 @@
.ioext.csiirq = INT_CSI_IRQ_1,
.ioclk.mclk_clk_rate = 24000000,
.ioclk.vfe_clk_rate = 192000000,
- .ioext.appphy = MSM_CLK_CTL_PHYS,
- .ioext.appsz = MSM_CLK_CTL_SIZE,
+ .ioext.appphy = MSM7XXX_CLK_CTL_PHYS,
+ .ioext.appsz = MSM7XXX_CLK_CTL_SIZE,
};
struct msm_camera_device_platform_data msm_camera_device_data_front = {
@@ -491,8 +491,8 @@
.ioext.csiirq = INT_CSI_IRQ_0,
.ioclk.mclk_clk_rate = 24000000,
.ioclk.vfe_clk_rate = 192000000,
- .ioext.appphy = MSM_CLK_CTL_PHYS,
- .ioext.appsz = MSM_CLK_CTL_SIZE,
+ .ioext.appphy = MSM7XXX_CLK_CTL_PHYS,
+ .ioext.appsz = MSM7XXX_CLK_CTL_SIZE,
};
#ifdef CONFIG_S5K4E1
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 8c03d17..030c129 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -602,9 +602,6 @@
}
} else {
gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
-
- if (pmapp_disp_backlight_set_brightness(0))
- pr_err("backlight set brightness failed\n");
}
rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
new file mode 100644
index 0000000..6df7626
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -0,0 +1,368 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <asm/mach-types.h>
+#include <mach/rpc_pmapp.h>
+#include "board-msm7627a.h"
+#include "devices-msm7x2xa.h"
+#include "timer.h"
+
+#define GPIO_WLAN_3V3_EN 119
+static const char *id = "WLAN";
+
+enum {
+ WLAN_VREG_S3 = 0,
+ WLAN_VREG_L17,
+ WLAN_VREG_L19
+};
+
+struct wlan_vreg_info {
+ const char *vreg_id;
+ unsigned int level_min;
+ unsigned int level_max;
+ unsigned int pmapp_id;
+ unsigned int is_vreg_pin_controlled;
+ struct regulator *reg;
+};
+
+static struct wlan_vreg_info vreg_info[] = {
+ {"msme1", 1800000, 1800000, 2, 0, NULL},
+ {"bt", 3300000, 3300000, 21, 1, NULL},
+ {"wlan4", 1800000, 1800000, 23, 1, NULL}
+};
+
+int gpio_wlan_sys_rest_en = 134;
+static void gpio_wlan_config(void)
+{
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb())
+ gpio_wlan_sys_rest_en = 124;
+}
+
+static unsigned int qrf6285_init_regs(void)
+{
+ struct regulator_bulk_data regs[ARRAY_SIZE(vreg_info)];
+ int i = 0, rc = 0;
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ regs[i].supply = vreg_info[i].vreg_id;
+ regs[i].min_uV = vreg_info[i].level_min;
+ regs[i].max_uV = vreg_info[i].level_max;
+ }
+
+ rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs), regs);
+ if (rc) {
+ pr_err("%s: could not get regulators: %d\n", __func__, rc);
+ goto out;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++)
+ vreg_info[i].reg = regs[i].consumer;
+
+out:
+ return rc;
+}
+
+static unsigned int setup_wlan_gpio(bool on)
+{
+ int rc = 0;
+
+ if (on) {
+ rc = gpio_direction_output(gpio_wlan_sys_rest_en, 1);
+ msleep(100);
+ } else {
+ gpio_set_value_cansleep(gpio_wlan_sys_rest_en, 0);
+ rc = gpio_direction_input(gpio_wlan_sys_rest_en);
+ msleep(100);
+ }
+
+ if (rc)
+ pr_err("%s: WLAN sys_reset_en GPIO: Error", __func__);
+
+ return rc;
+}
+
+static unsigned int setup_wlan_clock(bool on)
+{
+ int rc = 0;
+
+ if (on) {
+ /* Vote for A0 clock */
+ rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
+ PMAPP_CLOCK_VOTE_ON);
+ } else {
+ /* Vote against A0 clock */
+ rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
+ PMAPP_CLOCK_VOTE_OFF);
+ }
+
+ if (rc)
+ pr_err("%s: Configuring A0 clock for WLAN: Error", __func__);
+
+ return rc;
+}
+
+static unsigned int wlan_switch_regulators(int on)
+{
+ int rc = 0, index = 0;
+
+ if (machine_is_msm7627a_qrd1())
+ index = 2;
+
+ for ( ; index < ARRAY_SIZE(vreg_info); index++) {
+ if (on) {
+ rc = regulator_set_voltage(vreg_info[index].reg,
+ vreg_info[index].level_min,
+ vreg_info[index].level_max);
+ if (rc) {
+ pr_err("%s:%s set voltage failed %d\n",
+ __func__, vreg_info[index].vreg_id, rc);
+ goto reg_disable;
+ }
+
+ rc = regulator_enable(vreg_info[index].reg);
+ if (rc) {
+ pr_err("%s:%s vreg enable failed %d\n",
+ __func__, vreg_info[index].vreg_id, rc);
+ goto reg_disable;
+ }
+
+ if (vreg_info[index].is_vreg_pin_controlled) {
+ rc = pmapp_vreg_lpm_pincntrl_vote(id,
+ vreg_info[index].pmapp_id,
+ PMAPP_CLOCK_ID_A0, 1);
+ if (rc) {
+ pr_err("%s:%s pincntrl failed %d\n",
+ __func__,
+ vreg_info[index].vreg_id, rc);
+ goto pin_cnt_fail;
+ }
+ }
+ } else {
+ if (vreg_info[index].is_vreg_pin_controlled) {
+ rc = pmapp_vreg_lpm_pincntrl_vote(id,
+ vreg_info[index].pmapp_id,
+ PMAPP_CLOCK_ID_A0, 0);
+ if (rc) {
+ pr_err("%s:%s pincntrl failed %d\n",
+ __func__,
+ vreg_info[index].vreg_id, rc);
+ goto pin_cnt_fail;
+ }
+ }
+
+ rc = regulator_disable(vreg_info[index].reg);
+ if (rc) {
+ pr_err("%s:%s vreg disable failed %d\n",
+ __func__,
+ vreg_info[index].vreg_id, rc);
+ goto reg_disable;
+ }
+ }
+ }
+ return 0;
+pin_cnt_fail:
+ if (on)
+ regulator_disable(vreg_info[index].reg);
+reg_disable:
+ if (!machine_is_msm7627a_qrd1()) {
+ while (index) {
+ if (on) {
+ index--;
+ regulator_disable(vreg_info[index].reg);
+ regulator_put(vreg_info[index].reg);
+ }
+ }
+ }
+ return rc;
+}
+
+static unsigned int msm_AR600X_setup_power(bool on)
+{
+ int rc = 0;
+ static bool init_done;
+
+ if (unlikely(!init_done)) {
+ gpio_wlan_config();
+ rc = qrf6285_init_regs();
+ if (rc) {
+ pr_err("%s: qrf6285 init failed = %d\n", __func__, rc);
+ return rc;
+ } else {
+ init_done = true;
+ }
+ }
+
+ rc = wlan_switch_regulators(on);
+ if (rc) {
+ pr_err("%s: wlan_switch_regulators error = %d\n", __func__, rc);
+ goto out;
+ }
+
+ /* GPIO_WLAN_3V3_EN is only required for the QRD7627a */
+ if (machine_is_msm7627a_qrd1()) {
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_WLAN_3V3_EN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+ __func__, rc);
+ goto reg_disable;
+ }
+ gpio_set_value(GPIO_WLAN_3V3_EN, 1);
+ }
+
+ /*
+ * gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
+ * EVB1.0 and QRD8625,so the below step is required for those devices.
+ */
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+ rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+ __func__, rc);
+ goto qrd_gpio_fail;
+ }
+ gpio_set_value(gpio_wlan_sys_rest_en, 1);
+ } else {
+ rc = gpio_request(gpio_wlan_sys_rest_en, "WLAN_DEEP_SLEEP_N");
+ if (rc) {
+ pr_err("%s: WLAN sys_rest_en GPIO %d request failed %d\n",
+ __func__,
+ gpio_wlan_sys_rest_en, rc);
+ goto qrd_gpio_fail;
+ }
+ rc = setup_wlan_gpio(on);
+ if (rc) {
+ pr_err("%s: wlan_set_gpio = %d\n", __func__, rc);
+ goto gpio_fail;
+ }
+ }
+
+ /* Enable the A0 clock */
+ rc = setup_wlan_clock(on);
+ if (rc) {
+ pr_err("%s: setup_wlan_clock = %d\n", __func__, rc);
+ goto set_gpio_fail;
+ }
+
+ /* Configure A0 clock to be slave to WLAN_CLK_PWR_REQ */
+ rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
+ PMAPP_CLOCK_VOTE_PIN_CTRL);
+ if (rc) {
+ pr_err("%s: Configuring A0 to Pin controllable failed %d\n",
+ __func__, rc);
+ goto set_clock_fail;
+ }
+
+ pr_info("WLAN power-up success\n");
+ return 0;
+set_clock_fail:
+ setup_wlan_clock(0);
+set_gpio_fail:
+ setup_wlan_gpio(0);
+gpio_fail:
+ gpio_free(gpio_wlan_sys_rest_en);
+qrd_gpio_fail:
+ gpio_free(GPIO_WLAN_3V3_EN);
+reg_disable:
+ wlan_switch_regulators(0);
+out:
+ pr_info("WLAN power-up failed\n");
+ return rc;
+}
+
+static unsigned int msm_AR600X_shutdown_power(bool on)
+{
+ int rc = 0;
+
+ /* Disable the A0 clock */
+ rc = setup_wlan_clock(on);
+ if (rc) {
+ pr_err("%s: setup_wlan_clock = %d\n", __func__, rc);
+ goto set_clock_fail;
+ }
+
+ /*
+ * gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
+ * EVB1.0 and QRD8625,so the below step is required for those devices.
+ */
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+ rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+ __func__, rc);
+ goto gpio_fail;
+ }
+ gpio_set_value(gpio_wlan_sys_rest_en, 0);
+ } else {
+ rc = setup_wlan_gpio(on);
+ if (rc) {
+ pr_err("%s: wlan_set_gpio = %d\n", __func__, rc);
+ goto set_gpio_fail;
+ }
+ gpio_free(gpio_wlan_sys_rest_en);
+ }
+
+ /* GPIO_WLAN_3V3_EN is only required for the QRD7627a */
+ if (machine_is_msm7627a_qrd1()) {
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_WLAN_3V3_EN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+ __func__, rc);
+ goto qrd_gpio_fail;
+ }
+ gpio_set_value(GPIO_WLAN_3V3_EN, 0);
+ }
+
+ rc = wlan_switch_regulators(on);
+ if (rc) {
+ pr_err("%s: wlan_switch_regulators error = %d\n",
+ __func__, rc);
+ goto reg_disable;
+ }
+
+ pr_info("WLAN power-down success\n");
+ return 0;
+set_clock_fail:
+ setup_wlan_clock(0);
+set_gpio_fail:
+ setup_wlan_gpio(0);
+gpio_fail:
+ gpio_free(gpio_wlan_sys_rest_en);
+qrd_gpio_fail:
+ gpio_free(GPIO_WLAN_3V3_EN);
+reg_disable:
+ wlan_switch_regulators(0);
+ pr_info("WLAN power-down failed\n");
+ return rc;
+}
+
+int ar600x_wlan_power(bool on)
+{
+ if (on)
+ msm_AR600X_setup_power(on);
+ else
+ msm_AR600X_shutdown_power(on);
+
+ return 0;
+}
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index 9385a58..5c189fe 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -1063,10 +1063,10 @@
static struct msm_camera_device_platform_data msm_camera_device_data = {
.camera_gpio_on = config_camera_on_gpios,
.camera_gpio_off = config_camera_off_gpios,
- .ioext.mdcphy = MSM_MDC_PHYS,
- .ioext.mdcsz = MSM_MDC_SIZE,
- .ioext.appphy = MSM_CLK_CTL_PHYS,
- .ioext.appsz = MSM_CLK_CTL_SIZE,
+ .ioext.mdcphy = MSM7XXX_MDC_PHYS,
+ .ioext.mdcsz = MSM7XXX_MDC_SIZE,
+ .ioext.appphy = MSM7XXX_CLK_CTL_PHYS,
+ .ioext.appsz = MSM7XXX_CLK_CTL_SIZE,
};
int pmic_set_flash_led_current(enum pmic8058_leds id, unsigned mA)
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 8b50c53..0437134 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -151,6 +151,10 @@
.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
};
+static struct msm_i2c_platform_data msm8625_gsbi0_qup_i2c_pdata = {
+ .clk_freq = 100000,
+};
+
#ifdef CONFIG_ARCH_MSM7X27A
#define MSM_PMEM_MDP_SIZE 0x2300000
#define MSM7x25A_MSM_PMEM_MDP_SIZE 0x1500000
@@ -681,6 +685,7 @@
static struct platform_device *msm8625_rumi3_devices[] __initdata = {
&msm8625_device_dmov,
&msm8625_device_uart1,
+ &msm8625_device_qup_i2c_gsbi0,
};
static struct platform_device *surf_ffa_devices[] __initdata = {
@@ -796,6 +801,12 @@
static void __init msm_device_i2c_init(void)
{
+ if (machine_is_msm8625_rumi3()) {
+ msm8625_device_qup_i2c_gsbi0.dev.platform_data =
+ &msm8625_gsbi0_qup_i2c_pdata;
+ return;
+ }
+
msm_gsbi0_qup_i2c_device.dev.platform_data = &msm_gsbi0_qup_i2c_pdata;
msm_gsbi1_qup_i2c_device.dev.platform_data = &msm_gsbi1_qup_i2c_pdata;
}
@@ -1061,6 +1072,7 @@
static void __init msm8625_rumi3_init(void)
{
msm7x2x_misc_init();
+ msm_device_i2c_init();
platform_add_devices(msm8625_rumi3_devices,
ARRAY_SIZE(msm8625_rumi3_devices));
}
@@ -1071,6 +1083,7 @@
#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
static int __init msm7x27a_init_ar6000pm(void)
{
+ msm_wlan_ar6000_pm_device.dev.platform_data = &ar600x_wlan_power;
return platform_device_register(&msm_wlan_ar6000_pm_device);
}
#else
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index d54ebc5..3e7b7f4 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -138,6 +138,13 @@
#define PM_FLIP_MPP 5 /* PMIC MPP 06 */
+#define DDR1_BANK_BASE 0X20000000
+#define DDR2_BANK_BASE 0X40000000
+
+static unsigned int phys_add = DDR2_BANK_BASE;
+unsigned long ebi1_phys_offset = DDR2_BANK_BASE;
+EXPORT_SYMBOL(ebi1_phys_offset);
+
struct pm8xxx_gpio_init_info {
unsigned gpio;
struct pm_gpio config;
@@ -6898,9 +6905,9 @@
static int msm7x30_paddr_to_memtype(unsigned int paddr)
{
- if (paddr < 0x40000000)
+ if (paddr < phys_add)
return MEMTYPE_EBI0;
- if (paddr >= 0x40000000 && paddr < 0x80000000)
+ if (paddr >= phys_add && paddr < 0x80000000)
return MEMTYPE_EBI1;
return MEMTYPE_NONE;
}
@@ -6944,6 +6951,19 @@
msm7x30_allocate_memory_regions();
}
+static void __init msm7x30_fixup(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ for (; tags->hdr.size; tags = tag_next(tags)) {
+ if (tags->hdr.tag == ATAG_MEM && tags->u.mem.start ==
+ DDR1_BANK_BASE) {
+ ebi1_phys_offset = DDR1_BANK_BASE;
+ phys_add = DDR1_BANK_BASE;
+ break;
+ }
+ }
+}
+
MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
.boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = msm7x30_map_io,
@@ -6953,6 +6973,7 @@
.timer = &msm_timer,
.init_early = msm7x30_init_early,
.handle_irq = vic_handle_irq,
+ .fixup = msm7x30_fixup,
MACHINE_END
MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
@@ -6964,6 +6985,7 @@
.timer = &msm_timer,
.init_early = msm7x30_init_early,
.handle_irq = vic_handle_irq,
+ .fixup = msm7x30_fixup,
MACHINE_END
MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
@@ -6975,6 +6997,7 @@
.timer = &msm_timer,
.init_early = msm7x30_init_early,
.handle_irq = vic_handle_irq,
+ .fixup = msm7x30_fixup,
MACHINE_END
MACHINE_START(MSM8X55_SURF, "QCT MSM8X55 SURF")
@@ -6986,6 +7009,7 @@
.timer = &msm_timer,
.init_early = msm7x30_init_early,
.handle_irq = vic_handle_irq,
+ .fixup = msm7x30_fixup,
MACHINE_END
MACHINE_START(MSM8X55_FFA, "QCT MSM8X55 FFA")
@@ -6997,6 +7021,7 @@
.timer = &msm_timer,
.init_early = msm7x30_init_early,
.handle_irq = vic_handle_irq,
+ .fixup = msm7x30_fixup,
MACHINE_END
MACHINE_START(MSM8X55_SVLTE_SURF, "QCT MSM8X55 SVLTE SURF")
.boot_params = PHYS_OFFSET + 0x100,
@@ -7007,6 +7032,7 @@
.timer = &msm_timer,
.init_early = msm7x30_init_early,
.handle_irq = vic_handle_irq,
+ .fixup = msm7x30_fixup,
MACHINE_END
MACHINE_START(MSM8X55_SVLTE_FFA, "QCT MSM8X55 SVLTE FFA")
.boot_params = PHYS_OFFSET + 0x100,
@@ -7017,4 +7043,5 @@
.timer = &msm_timer,
.init_early = msm7x30_init_early,
.handle_irq = vic_handle_irq,
+ .fixup = msm7x30_fixup,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index f7e908b..5052bb0 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -679,7 +679,6 @@
#ifdef CONFIG_BT
&msm_bt_power_device,
#endif
- &msm_wlan_ar6000_pm_device,
&asoc_msm_pcm,
&asoc_msm_dai0,
&asoc_msm_dai1,
@@ -1011,6 +1010,12 @@
}
}
+static int __init msm_qrd_init_ar6000pm(void)
+{
+ msm_wlan_ar6000_pm_device.dev.platform_data = &ar600x_wlan_power;
+ return platform_device_register(&msm_wlan_ar6000_pm_device);
+}
+
#define UART1DM_RX_GPIO 45
static void __init msm_qrd_init(void)
{
@@ -1033,6 +1038,8 @@
platform_add_devices(qrd_common_devices,
ARRAY_SIZE(qrd_common_devices));
+ /* Ensure ar6000pm device is registered before MMC/SDC */
+ msm_qrd_init_ar6000pm();
msm7627a_init_mmc();
#ifdef CONFIG_USB_EHCI_MSM_72K
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index e16cac5..c949dc0 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4248,7 +4248,7 @@
.ctl_reg = ns, \
.en_mask = BIT(19), \
.halt_reg = h_r, \
- .halt_check = ENABLE, \
+ .halt_check = DELAY, \
}, \
.ns_reg = ns, \
.ext_mask = BIT(18), \
@@ -4812,13 +4812,16 @@
};
static struct clk_lookup msm_clocks_8064[] = {
- CLK_LOOKUP("cxo", cxo_clk.c, NULL),
- CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
- CLK_LOOKUP("cxo", cxo_clk.c, "pil_riva"),
- CLK_LOOKUP("pll2", pll2_clk.c, NULL),
- CLK_LOOKUP("pll8", pll8_clk.c, NULL),
- CLK_LOOKUP("pll4", pll4_clk.c, NULL),
- CLK_LOOKUP("measure", measure_clk.c, "debug"),
+ CLK_LOOKUP("cxo", cxo_clk.c, NULL),
+ CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
+ CLK_LOOKUP("cxo", cxo_clk.c, "pil_riva"),
+ CLK_LOOKUP("xo", pxo_clk.c, "pil_qdsp6v4.0"),
+ CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.1"),
+ CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.2"),
+ CLK_LOOKUP("pll2", pll2_clk.c, NULL),
+ CLK_LOOKUP("pll8", pll8_clk.c, NULL),
+ CLK_LOOKUP("pll4", pll4_clk.c, NULL),
+ CLK_LOOKUP("measure", measure_clk.c, "debug"),
CLK_DUMMY("bus_clk", AFAB_CLK, "msm_apps_fab", 0),
CLK_DUMMY("bus_a_clk", AFAB_A_CLK, "msm_apps_fab", 0),
@@ -5051,13 +5054,16 @@
};
static struct clk_lookup msm_clocks_8960_v1[] __initdata = {
- CLK_LOOKUP("cxo", cxo_clk.c, NULL),
- CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
- CLK_LOOKUP("cxo", cxo_clk.c, "pil_riva"),
- CLK_LOOKUP("pll2", pll2_clk.c, NULL),
- CLK_LOOKUP("pll8", pll8_clk.c, NULL),
- CLK_LOOKUP("pll4", pll4_clk.c, NULL),
- CLK_LOOKUP("measure", measure_clk.c, "debug"),
+ CLK_LOOKUP("cxo", cxo_clk.c, NULL),
+ CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
+ CLK_LOOKUP("cxo", cxo_clk.c, "pil_riva"),
+ CLK_LOOKUP("xo", pxo_clk.c, "pil_qdsp6v4.0"),
+ CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.1"),
+ CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.2"),
+ CLK_LOOKUP("pll2", pll2_clk.c, NULL),
+ CLK_LOOKUP("pll8", pll8_clk.c, NULL),
+ CLK_LOOKUP("pll4", pll4_clk.c, NULL),
+ CLK_LOOKUP("measure", measure_clk.c, "debug"),
CLK_LOOKUP("bus_clk", afab_clk.c, "msm_apps_fab"),
CLK_LOOKUP("bus_a_clk", afab_a_clk.c, "msm_apps_fab"),
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 94fafda..17f5d01 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3520,6 +3520,7 @@
static struct clk_lookup msm_clocks_8x60[] = {
CLK_LOOKUP("cxo", cxo_clk.c, NULL),
+ CLK_LOOKUP("xo", pxo_clk.c, "pil_modem"),
CLK_LOOKUP("pll4", pll4_clk.c, "pil_qdsp6v3"),
CLK_LOOKUP("measure", measure_clk.c, "debug"),
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 3592c43..40ac701 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1201,7 +1201,7 @@
.ctl_reg = ns, \
.en_mask = BIT(19), \
.halt_reg = h_r, \
- .halt_check = ENABLE, \
+ .halt_check = DELAY, \
}, \
.ns_reg = ns, \
.ext_mask = BIT(18), \
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 2d5ae78..1bb9c86 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -631,7 +631,8 @@
bank_info = &bank_masks->bank1_mask;
ns_mask = bank_info->ns_mask;
- md_val = readl_relaxed(bank_info->md_reg);
+ md_val = bank_info->md_reg ?
+ readl_relaxed(bank_info->md_reg) : 0;
} else {
ns_mask = clk->ns_mask;
md_val = clk->md_reg ? readl_relaxed(clk->md_reg) : 0;
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 0ced722..872d9d4 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -30,7 +30,6 @@
#include <mach/rpm.h>
#include <mach/msm_bus_board.h>
#include <mach/msm_memtypes.h>
-#include <mach/msm_xo.h>
#include <sound/msm-dai-q6.h>
#include <sound/apr_audio.h>
#include "clock.h"
@@ -843,7 +842,6 @@
.strap_ahb_upper = 0x00290000,
.strap_ahb_lower = 0x00000280,
.aclk_reg = SFAB_LPASS_Q6_ACLK_CTL,
- .xo_id = MSM_XO_PXO,
.name = "q6",
.pas_id = PAS_Q6,
.bus_port = MSM_BUS_MASTER_LPASS_PROC,
@@ -881,7 +879,6 @@
.strap_ahb_lower = 0x00000080,
.aclk_reg = SFAB_MSS_Q6_FW_ACLK_CTL,
.jtag_clk_reg = MSS_Q6FW_JTAG_CLK_CTL,
- .xo_id = MSM_XO_CXO,
.name = "modem_fw",
.depends = "q6",
.pas_id = PAS_MODEM_FW,
@@ -919,7 +916,6 @@
.strap_ahb_lower = 0x00000080,
.aclk_reg = SFAB_MSS_Q6_SW_ACLK_CTL,
.jtag_clk_reg = MSS_Q6SW_JTAG_CLK_CTL,
- .xo_id = MSM_XO_CXO,
.name = "modem",
.depends = "modem_fw",
.pas_id = PAS_MODEM_SW,
diff --git a/arch/arm/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c
index cdb43ad..b895870 100644
--- a/arch/arm/mach-msm/devices-msm7x27.c
+++ b/arch/arm/mach-msm/devices-msm7x27.c
@@ -43,8 +43,8 @@
.flags = IORESOURCE_IRQ,
},
{
- .start = MSM_UART1_PHYS,
- .end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
+ .start = MSM7XXX_UART1_PHYS,
+ .end = MSM7XXX_UART1_PHYS + MSM7XXX_UART1_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
@@ -56,8 +56,8 @@
.flags = IORESOURCE_IRQ,
},
{
- .start = MSM_UART2_PHYS,
- .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
+ .start = MSM7XXX_UART2_PHYS,
+ .end = MSM7XXX_UART2_PHYS + MSM7XXX_UART2_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 6a59b08..f3a95a6 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -228,8 +228,8 @@
.flags = IORESOURCE_IRQ,
},
{
- .start = MSM_UART1_PHYS,
- .end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
+ .start = MSM7XXX_UART1_PHYS,
+ .end = MSM7XXX_UART1_PHYS + MSM7XXX_UART1_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
@@ -573,8 +573,8 @@
static struct resource msm_clkctl_resources[] = {
{
.name = "clk_ctl",
- .start = MSM_CLK_CTL_PHYS,
- .end = MSM_CLK_CTL_PHYS + MSM_CLK_CTL_SIZE - 1,
+ .start = MSM7XXX_CLK_CTL_PHYS,
+ .end = MSM7XXX_CLK_CTL_PHYS + MSM7XXX_CLK_CTL_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
@@ -802,8 +802,8 @@
.flags = IORESOURCE_IRQ,
},
{
- .start = MSM_UART1_PHYS,
- .end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
+ .start = MSM7XXX_UART1_PHYS,
+ .end = MSM7XXX_UART1_PHYS + MSM7XXX_UART1_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
@@ -837,6 +837,35 @@
},
};
+static struct resource gsbi0_msm8625_qup_resources[] = {
+ {
+ .name = "qup_phys_addr",
+ .start = MSM_GSBI0_QUP_PHYS,
+ .end = MSM_GSBI0_QUP_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "gsbi_qup_i2c_addr",
+ .start = MSM_GSBI0_PHYS,
+ .end = MSM_GSBI0_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "qup_err_intr",
+ .start = MSM8625_INT_PWB_I2C,
+ .end = MSM8625_INT_PWB_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Use GSBI0 QUP for /dev/i2c-0 */
+struct platform_device msm8625_device_qup_i2c_gsbi0 = {
+ .name = "qup_i2c",
+ .id = MSM_GSBI0_QUP_I2C_BUS_ID,
+ .num_resources = ARRAY_SIZE(gsbi0_msm8625_qup_resources),
+ .resource = gsbi0_msm8625_qup_resources,
+};
+
static struct clk_lookup msm_clock_8625_dummy[] = {
CLK_DUMMY("core_clk", adm_clk.c, "msm_dmov", 0),
CLK_DUMMY("adsp_clk", adsp_clk.c, NULL, 0),
@@ -931,6 +960,13 @@
(0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) | \
(0x1 << L2X0_AUX_CTRL_EVNT_MON_BUS_EN_SHIFT);
+ if (cpu_is_msm8625()) {
+ /* Way Size 011(0x3) 64KB */
+ aux_ctrl |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) | \
+ (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) | \
+ (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT);
+ }
+
l2x0_init(MSM_L2CC_BASE, aux_ctrl, L2X0_AUX_CTRL_MASK);
return 0;
@@ -966,7 +1002,7 @@
if (socinfo_init() < 0)
pr_err("%s: socinfo_init() failed!\n", __func__);
-
+ msm7x27x_cache_init();
}
static int msm7627a_init_gpio(void)
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index a59ade3..be6a645 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -25,4 +25,5 @@
extern struct platform_device msm7x27a_device_clkctl;
void __init msm8625_init_irq(void);
void __init msm8625_map_io(void);
+int ar600x_wlan_power(bool on);
#endif
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 176d14a..5d42f99 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -118,6 +118,8 @@
extern struct platform_device msm_gsbi9_qup_i2c_device;
extern struct platform_device msm_gsbi12_qup_i2c_device;
+extern struct platform_device msm8625_device_qup_i2c_gsbi0;
+
extern struct platform_device msm_slim_ctrl;
extern struct platform_device msm_device_sps;
extern struct platform_device msm_device_usb_bam;
diff --git a/arch/arm/mach-msm/footswitch-pcom.c b/arch/arm/mach-msm/footswitch-pcom.c
index c48c141..340f19b 100644
--- a/arch/arm/mach-msm/footswitch-pcom.c
+++ b/arch/arm/mach-msm/footswitch-pcom.c
@@ -18,6 +18,7 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/clk.h>
+#include <mach/socinfo.h>
#include "footswitch.h"
#include "proc_comm.h"
@@ -305,6 +306,8 @@
struct footswitch *fs;
int ret;
+ if (cpu_is_msm8625())
+ return 0;
/*
* Enable all footswitches in manual mode (ie. not controlled along
* with pcom clocks).
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index d11c13f..c7ef271 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -172,26 +172,43 @@
BACK_CAMERA_INT_3D,
};
-struct msm8960_privacy_light_cfg {
- unsigned mpp;
+enum camera_vreg_type {
+ REG_LDO,
+ REG_VS,
};
-struct msm_camera_sensor_platform_info {
- int mount_angle;
- int sensor_reset_enable;
- int sensor_reset;
- int sensor_pwd;
- int vcm_pwd;
- int vcm_enable;
- int privacy_light;
- void *privacy_light_info;
+struct camera_vreg_t {
+ char *reg_name;
+ enum camera_vreg_type type;
+ int min_voltage;
+ int max_voltage;
+ int op_mode;
+};
+
+struct msm_gpio_set_tbl {
+ unsigned gpio;
+ unsigned long flags;
+ uint32_t delay;
};
struct msm_camera_gpio_conf {
void *cam_gpiomux_conf_tbl;
uint8_t cam_gpiomux_conf_tbl_size;
- uint16_t *cam_gpio_tbl;
- uint8_t cam_gpio_tbl_size;
+ struct gpio *cam_gpio_common_tbl;
+ uint8_t cam_gpio_common_tbl_size;
+ struct gpio *cam_gpio_req_tbl;
+ uint8_t cam_gpio_req_tbl_size;
+ struct msm_gpio_set_tbl *cam_gpio_set_tbl;
+ uint8_t cam_gpio_set_tbl_size;
+};
+
+struct msm_camera_sensor_platform_info {
+ int mount_angle;
+ int sensor_reset;
+ struct camera_vreg_t *cam_vreg;
+ int num_vreg;
+ int32_t (*ext_power_ctrl) (int enable);
+ struct msm_camera_gpio_conf *gpio_conf;
};
struct msm_actuator_info {
@@ -219,7 +236,6 @@
struct msm_camera_csi_params csi_params;
struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;
char *eeprom_data;
- struct msm_camera_gpio_conf *gpio_conf;
enum msm_camera_type camera_type;
struct msm_actuator_info *actuator_info;
};
@@ -454,6 +470,8 @@
void msm_init_irq(void);
void msm_copper_init_irq(void);
void vic_handle_irq(struct pt_regs *regs);
+void msm_copper_reserve(void);
+void msm_copper_very_early(void);
struct mmc_platform_data;
int msm_add_sdcc(unsigned int controller,
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 1abfd7b..bb33289 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -19,6 +19,7 @@
#include <linux/cdev.h>
#include <linux/platform_device.h>
#include <linux/wakelock.h>
+#include <linux/regulator/consumer.h>
#include "linux/types.h"
#include <mach/board.h>
@@ -74,7 +75,7 @@
VFE_MSG_STATS_AEC,
VFE_MSG_STATS_AF,
VFE_MSG_STATS_AWB,
- VFE_MSG_STATS_RS,
+ VFE_MSG_STATS_RS, /* 10 */
VFE_MSG_STATS_CS,
VFE_MSG_STATS_IHIST,
VFE_MSG_STATS_SKIN,
@@ -84,11 +85,13 @@
VFE_MSG_SYNC_TIMER2,
VFE_MSG_COMMON,
VFE_MSG_V32_START,
- VFE_MSG_V32_START_RECORDING,
+ VFE_MSG_V32_START_RECORDING, /* 20 */
VFE_MSG_V32_CAPTURE,
VFE_MSG_OUTPUT_IRQ,
VFE_MSG_V2X_PREVIEW,
VFE_MSG_V2X_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY,
+ VFE_MSG_OUTPUT_SECONDARY,
};
enum vpe_resp_msg {
@@ -687,7 +690,15 @@
int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
struct clk **clk_ptr, int num_clk, int enable);
-int msm_sensor_probe_on(struct device *);
-int msm_sensor_probe_off(struct device *);
int msm_cam_core_reset(void);
+
+int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+ int num_vreg, struct regulator **reg_ptr, int config);
+int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+ int num_vreg, struct regulator **reg_ptr, int enable);
+
+int msm_camera_config_gpio_table
+ (struct msm_camera_sensor_info *sinfo, int gpio_en);
+int msm_camera_request_gpio_table
+ (struct msm_camera_sensor_info *sinfo, int gpio_en);
#endif
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index e1fc054..6e946aa 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -44,7 +44,11 @@
#define EBI0_PAGE_OFFSET PAGE_OFFSET
#define EBI0_SIZE 0x10000000
-#define EBI1_PHYS_OFFSET 0x40000000
+#ifndef __ASSEMBLY__
+
+extern unsigned long ebi1_phys_offset;
+
+#define EBI1_PHYS_OFFSET (ebi1_phys_offset)
#define EBI1_PAGE_OFFSET (EBI0_PAGE_OFFSET + EBI0_SIZE)
#if (defined(CONFIG_SPARSEMEM) && defined(CONFIG_VMSPLIT_3G))
@@ -60,6 +64,7 @@
(virt) - EBI0_PAGE_OFFSET + EBI0_PHYS_OFFSET)
#endif
+#endif
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
index ba50a30..88bc3c6 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
@@ -35,80 +35,43 @@
*
*/
-#define MSM_VIC_BASE IOMEM(0xFA000000)
-#define MSM_VIC_PHYS 0xC0000000
-#define MSM_VIC_SIZE SZ_4K
+#define MSM7XXX_VIC_PHYS 0xC0000000
+#define MSM7XXX_VIC_SIZE SZ_4K
-#define MSM_CSR_BASE IOMEM(0xFA001000)
-#define MSM_CSR_PHYS 0xC0100000
-#define MSM_CSR_SIZE SZ_4K
+#define MSM7XXX_CSR_PHYS 0xC0100000
+#define MSM7XXX_CSR_SIZE SZ_4K
-#define MSM_TMR_PHYS MSM_CSR_PHYS
-#define MSM_TMR_BASE MSM_CSR_BASE
-#define MSM_TMR_SIZE SZ_4K
+#define MSM7XXX_TMR_PHYS MSM7XXX_CSR_PHYS
+#define MSM7XXX_TMR_SIZE SZ_4K
-#define MSM_TMR0_BASE MSM_TMR_BASE
+#define MSM7XXX_TMR0_PHYS 0xC0800000
+#define MSM7XXX_TMR0_SIZE SZ_4K
-#define MSM_GPIO1_BASE IOMEM(0xFA003000)
-#define MSM_GPIO1_PHYS 0xA9200000
-#define MSM_GPIO1_SIZE SZ_4K
+#define MSM7XXX_GPIO1_PHYS 0xA9200000
+#define MSM7XXX_GPIO1_SIZE SZ_4K
-#define MSM_GPIO2_BASE IOMEM(0xFA004000)
-#define MSM_GPIO2_PHYS 0xA9300000
-#define MSM_GPIO2_SIZE SZ_4K
+#define MSM7XXX_GPIO2_PHYS 0xA9300000
+#define MSM7XXX_GPIO2_SIZE SZ_4K
-#define MSM_CLK_CTL_BASE IOMEM(0xFA005000)
-#define MSM_CLK_CTL_PHYS 0xA8600000
-#define MSM_CLK_CTL_SIZE SZ_4K
+#define MSM7XXX_CLK_CTL_PHYS 0xA8600000
+#define MSM7XXX_CLK_CTL_SIZE SZ_4K
-#define MSM_L2CC_BASE IOMEM(0xFA006000)
-#define MSM_L2CC_PHYS 0xC0400000
-#define MSM_L2CC_SIZE SZ_4K
+#define MSM7XXX_L2CC_PHYS 0xC0400000
+#define MSM7XXX_L2CC_SIZE SZ_4K
-#define MSM_QGIC_DIST_BASE IOMEM(0xFA000000)
-#define MSM_QGIC_DIST_PHYS 0xC0000000
-#define MSM_QGIC_DIST_SIZE SZ_4K
+#define MSM7XXX_UART1_PHYS 0xA9A00000
+#define MSM7XXX_UART1_SIZE SZ_4K
-#define MSM_QGIC_CPU_BASE IOMEM(0xFA007000)
-#define MSM_QGIC_CPU_PHYS 0xC0002000
-#define MSM_QGIC_CPU_SIZE SZ_256
+#define MSM7XXX_UART2_PHYS 0xA9B00000
+#define MSM7XXX_UART2_SIZE SZ_4K
-#define MSM_SCU_BASE IOMEM(0xFA008000)
-#define MSM_SCU_PHYS 0xC0600000
-#define MSM_SCU_SIZE SZ_256
+#define MSM7XXX_UART3_PHYS 0xA9C00000
+#define MSM7XXX_UART3_SIZE SZ_4K
-#define MSM_SPM0_BASE IOMEM(0xFA009000)
-#define MSM_SPM0_PHYS 0xC0200000
-#define MSM_SPM0_SIZE SZ_4K
+#define MSM7XXX_MDC_PHYS 0xAA500000
+#define MSM7XXX_MDC_SIZE SZ_1M
-#define MSM_SPM1_BASE IOMEM(0xFA00A000)
-#define MSM_SPM1_PHYS 0xC0700000
-#define MSM_SPM1_SIZE SZ_4K
-
-#define MSM_CFG_CTL_BASE IOMEM(0xFA00B000)
-#define MSM_CFG_CTL_PHYS 0xA9800000
-#define MSM_CFG_CTL_SIZE SZ_4K
-
-#define MSM_SHARED_RAM_BASE IOMEM(0xFA100000)
-#define MSM_SHARED_RAM_SIZE SZ_1M
-
-#define MSM_UART1_PHYS 0xA9A00000
-#define MSM_UART1_SIZE SZ_4K
-
-#define MSM_UART2_PHYS 0xA9B00000
-#define MSM_UART2_SIZE SZ_4K
-
-#define MSM_UART3_PHYS 0xA9C00000
-#define MSM_UART3_SIZE SZ_4K
-
-#define MSM_MDC_BASE IOMEM(0xFA200000)
-#define MSM_MDC_PHYS 0xAA500000
-#define MSM_MDC_SIZE SZ_1M
-
-#define MSM_AD5_BASE IOMEM(0xFA300000)
-#define MSM_AD5_PHYS 0xAC000000
-#define MSM_AD5_SIZE (SZ_1M*13)
-
-#define MSM_STRONGLY_ORDERED_PAGE 0xFA0F0000
+#define MSM7XXX_AD5_PHYS 0xAC000000
+#define MSM7XXX_AD5_SIZE (SZ_1M*13)
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
new file mode 100644
index 0000000..8088a4c
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough. Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_8625_H
+#define __ASM_ARCH_MSM_IOMAP_8625_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM8625_TMR_PHYS 0xC0800000
+#define MSM8625_TMR_SIZE SZ_4K
+
+#define MSM8625_TMR0_PHYS 0xC0100000
+#define MSM8625_TMR0_SIZE SZ_4K
+
+#define MSM8625_CLK_CTL_PHYS 0xA8600000
+#define MSM8625_CLK_CTL_SIZE SZ_4K
+
+#define MSM8625_QGIC_DIST_PHYS 0xC0000000
+#define MSM8625_QGIC_DIST_SIZE SZ_4K
+
+#define MSM8625_QGIC_CPU_PHYS 0xC0002000
+#define MSM8625_QGIC_CPU_SIZE SZ_4K
+
+#define MSM8625_SCU_PHYS 0xC0600000
+#define MSM8625_SCU_SIZE SZ_256
+
+#define MSM8625_SPM0_PHYS 0xC0200000
+#define MSM8625_SPM0_SIZE SZ_4K
+
+#define MSM8625_SPM1_PHYS 0xC0700000
+#define MSM8625_SPM1_SIZE SZ_4K
+
+#define MSM8625_CFG_CTL_PHYS 0xA9800000
+#define MSM8625_CFG_CTL_SIZE SZ_4K
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index ff0b368..ca8daaa 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -47,7 +47,10 @@
#if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
defined(CONFIG_ARCH_MSM8930) || defined(CONFIG_ARCH_MSM9615) || \
- defined(CONFIG_ARCH_MSMCOPPER)
+ defined(CONFIG_ARCH_MSMCOPPER) || defined(CONFIG_ARCH_MSM7X27) || \
+ defined(CONFIG_ARCH_MSM7X01A) || defined(CONFIG_ARCH_MSM7X25) || \
+ defined(CONFIG_ARCH_MSM8625)
+
/* Unified iomap */
#define MSM_TMR_BASE IOMEM(0xFA000000) /* 4K */
@@ -79,8 +82,21 @@
#define MSM_APCS_GLB_BASE IOMEM(0xFA702000) /* 4K */
#define MSM_SAW2_BASE IOMEM(0xFA703000) /* 4k */
#define MSM_SAW3_BASE IOMEM(0xFA704000) /* 4k */
+#define MSM_VIC_BASE IOMEM(0xFA705000) /* 4K */
+#define MSM_CSR_BASE MSM_TMR_BASE /* 4K */
+#define MSM_GPIO1_BASE IOMEM(0xFA706000) /* 4K */
+#define MSM_GPIO2_BASE IOMEM(0xFA707000) /* 4K */
+#define MSM_SCU_BASE IOMEM(0xFA708000) /* 4K */
+#define MSM_SPM0_BASE IOMEM(0xFA709000) /* 4K */
+#define MSM_SPM1_BASE IOMEM(0xFA70A000) /* 4K */
+#define MSM_CFG_CTL_BASE IOMEM(0xFA70B000) /* 4K */
+#define MSM_MDC_BASE IOMEM(0xFA70C000) /* 4K */
+#define MSM_AD5_BASE IOMEM(0xFA70D000) /* 4K */
-#if defined(CONFIG_ARCH_MSM9615)
+
+#define MSM_STRONGLY_ORDERED_PAGE 0xFA0F0000
+
+#if defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_MSM7X27)
#define MSM_SHARED_RAM_SIZE SZ_1M
#else
#define MSM_SHARED_RAM_SIZE SZ_2M
@@ -91,6 +107,8 @@
#include "msm_iomap-8064.h"
#include "msm_iomap-9615.h"
#include "msm_iomap-copper.h"
+#include "msm_iomap-7xxx.h"
+#include "msm_iomap-8625.h"
#else
/* Legacy single-target iomap */
@@ -104,7 +122,7 @@
#elif defined(CONFIG_ARCH_FSM9XXX)
#include "msm_iomap-fsm9xxx.h"
#else
-#include "msm_iomap-7xxx.h"
+#error "Target compiling without iomap"
#endif
#if defined(CONFIG_DEBUG_MSM_UART1)
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
new file mode 100644
index 0000000..2831428
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __MSM_RTB_H__
+#define __MSM_RTB_H__
+
+enum logk_event_type {
+ LOGK_NONE = 0,
+ LOGK_READL,
+ LOGK_WRITEL,
+ LOGK_OTHER,
+};
+
+#if defined(CONFIG_MSM_RTB)
+/*
+ * returns 1 if data was logged, 0 otherwise
+ */
+int uncached_logk_pc(enum logk_event_type log_type, void *caller,
+ void *data);
+
+/*
+ * returns 1 if data was logged, 0 otherwise
+ */
+int uncached_logk(enum logk_event_type log_type, void *data);
+
+#else
+
+static inline int uncached_logk_pc(enum logk_event_type log_type,
+ void *caller,
+ void *data) { return 0; }
+
+static inline int uncached_logk(enum logk_event_type log_type,
+ void *data) { return 0; }
+#endif
+#endif
diff --git a/arch/arm/mach-msm/include/mach/qpnp-int.h b/arch/arm/mach-msm/include/mach/qpnp-int.h
new file mode 100644
index 0000000..a79d2fc
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qpnp-int.h
@@ -0,0 +1,83 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef QPNPINT_H
+#define QPNPINT_H
+
+#include <linux/spmi.h>
+
+struct qpnp_irq_spec {
+ uint8_t slave; /* 0-15 */
+ uint8_t per; /* 0-255 */
+ uint8_t irq; /* 0-7 */
+};
+
+struct qpnp_local_int {
+ /* mask - Invoke PMIC Arbiter local mask handler */
+ int (*mask)(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec,
+ uint32_t priv_d);
+ /* unmask - Invoke PMIC Arbiter local unmask handler */
+ int (*unmask)(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec,
+ uint32_t priv_d);
+ /* register_priv_data - Return per irq priv data */
+ int (*register_priv_data)(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec,
+ uint32_t *priv_d);
+};
+
+#ifdef CONFIG_MSM_QPNP_INT
+/**
+ * qpnpint_of_init() - Device Tree irq initialization
+ *
+ * Standard Device Tree init routine to be called from
+ * of_irq_init().
+ */
+int __init qpnpint_of_init(struct device_node *node,
+ struct device_node *parent);
+
+/**
+ * qpnpint_register_controller() - Register local interrupt callbacks
+ *
+ * Used by the PMIC Arbiter driver or equivalent to register
+ * callbacks for interrupt events.
+ */
+int qpnpint_register_controller(unsigned int busno,
+ struct qpnp_local_int *li_cb);
+
+/**
+ * qpnpint_handle_irq - Main interrupt handling routine
+ *
+ * Pass a PMIC Arbiter interrupt to Linux.
+ */
+int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec);
+#else
+static inline int __init qpnpint_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return -ENXIO;
+}
+static inline int qpnpint_register_controller(unsigned int busno,
+ struct qpnp_local_int *li_cb)
+{
+ return -ENXIO;
+}
+
+static inline int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec)
+{
+ return -ENXIO;
+}
+#endif /* CONFIG_MSM_QPNP_INT */
+#endif /* QPNPINT_H */
diff --git a/arch/arm/mach-msm/include/mach/smem_log.h b/arch/arm/mach-msm/include/mach/smem_log.h
index b977a82..a94ae76 100644
--- a/arch/arm/mach-msm/include/mach/smem_log.h
+++ b/arch/arm/mach-msm/include/mach/smem_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -37,6 +37,7 @@
#define SMEM_LOG_PROC_ID_MODEM 0x00000000
#define SMEM_LOG_PROC_ID_Q6 0x40000000
#define SMEM_LOG_PROC_ID_APPS 0x80000000
+#define SMEM_LOG_PROC_ID_WCNSS 0xC0000000
#define SMEM_LOG_CONT 0x10000000
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 79c9aed..db64acf 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -58,23 +58,23 @@
#if defined(CONFIG_ARCH_MSM7X01A) || defined(CONFIG_ARCH_MSM7X27) \
|| defined(CONFIG_ARCH_MSM7X25)
static struct map_desc msm_io_desc[] __initdata = {
- MSM_DEVICE(VIC),
- MSM_DEVICE(CSR),
- MSM_DEVICE(TMR),
- MSM_DEVICE(GPIO1),
- MSM_DEVICE(GPIO2),
- MSM_DEVICE(CLK_CTL),
- MSM_DEVICE(AD5),
- MSM_DEVICE(MDC),
+ MSM_CHIP_DEVICE(VIC, MSM7XXX),
+ MSM_CHIP_DEVICE(CSR, MSM7XXX),
+ MSM_CHIP_DEVICE(TMR, MSM7XXX),
+ MSM_CHIP_DEVICE(GPIO1, MSM7XXX),
+ MSM_CHIP_DEVICE(GPIO2, MSM7XXX),
+ MSM_CHIP_DEVICE(CLK_CTL, MSM7XXX),
+ MSM_CHIP_DEVICE(AD5, MSM7XXX),
+ MSM_CHIP_DEVICE(MDC, MSM7XXX),
#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
defined(CONFIG_DEBUG_MSM_UART3)
- MSM_DEVICE(DEBUG_UART),
+ MSM_CHIP_DEVICE(DEBUG_UART, MSM7XXX),
#endif
#ifdef CONFIG_CACHE_L2X0
{
.virtual = (unsigned long) MSM_L2CC_BASE,
- .pfn = __phys_to_pfn(MSM_L2CC_PHYS),
- .length = MSM_L2CC_SIZE,
+ .pfn = __phys_to_pfn(MSM7XXX_L2CC_PHYS),
+ .length = MSM7XXX_L2CC_SIZE,
.type = MT_DEVICE,
},
#endif
@@ -399,27 +399,27 @@
#ifdef CONFIG_ARCH_MSM8625
static struct map_desc msm8625_io_desc[] __initdata = {
- MSM_DEVICE(QGIC_DIST),
- MSM_DEVICE(QGIC_CPU),
- MSM_DEVICE(TMR),
- MSM_DEVICE(TMR0),
- MSM_DEVICE(CSR),
- MSM_DEVICE(SCU),
- MSM_DEVICE(CFG_CTL),
- MSM_DEVICE(GPIO1),
- MSM_DEVICE(GPIO2),
- MSM_DEVICE(CLK_CTL),
- MSM_DEVICE(SPM0),
- MSM_DEVICE(SPM1),
+ MSM_CHIP_DEVICE(CSR, MSM7XXX),
+ MSM_CHIP_DEVICE(GPIO1, MSM7XXX),
+ MSM_CHIP_DEVICE(GPIO2, MSM7XXX),
+ MSM_CHIP_DEVICE(QGIC_DIST, MSM8625),
+ MSM_CHIP_DEVICE(QGIC_CPU, MSM8625),
+ MSM_CHIP_DEVICE(TMR, MSM8625),
+ MSM_CHIP_DEVICE(TMR0, MSM8625),
+ MSM_CHIP_DEVICE(SCU, MSM8625),
+ MSM_CHIP_DEVICE(CFG_CTL, MSM8625),
+ MSM_CHIP_DEVICE(CLK_CTL, MSM8625),
+ MSM_CHIP_DEVICE(SPM0, MSM8625),
+ MSM_CHIP_DEVICE(SPM1, MSM8625),
#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
defined(CONFIG_DEBUG_MSM_UART3)
- MSM_DEVICE(DEBUG_UART),
+ MSM_CHIP_DEVICE(DEBUG_UART, MSM7XXX),
#endif
#ifdef CONFIG_CACHE_L2X0
{
.virtual = (unsigned long) MSM_L2CC_BASE,
- .pfn = __phys_to_pfn(MSM_L2CC_PHYS),
- .length = MSM_L2CC_SIZE,
+ .pfn = __phys_to_pfn(MSM7XXX_L2CC_PHYS),
+ .length = MSM7XXX_L2CC_SIZE,
.type = MT_DEVICE,
},
#endif
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index 093d044..4b0d26a 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -27,6 +27,7 @@
#include <net/sock.h>
#include <mach/peripheral-loader.h>
+#include <mach/socinfo.h>
#include "ipc_router.h"
@@ -46,11 +47,18 @@
static void *msm_ipc_router_load_modem(void)
{
- void *pil;
+ void *pil = NULL;
int rc;
- pil = pil_get("modem");
- if (IS_ERR(pil)) {
+ /* Load GNSS for Standalone 8064 but not for Fusion 3 */
+ if (cpu_is_apq8064()) {
+ if (socinfo_get_platform_subtype() == 0x0)
+ pil = pil_get("gnss");
+ } else {
+ pil = pil_get("modem");
+ }
+
+ if (IS_ERR(pil) || !pil) {
pr_debug("%s: modem load failed\n", __func__);
pil = NULL;
} else {
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 11b9092..5eccf06 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -66,6 +66,28 @@
.notifier_call = riva_notifier_cb,
};
+static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
+ void *ss_handle)
+{
+ int ret;
+ switch (code) {
+ case SUBSYS_BEFORE_SHUTDOWN:
+ pr_debug("%s: M-Notify: Shutdown started\n", __func__);
+ ret = sysmon_send_event(SYSMON_SS_LPASS, "modem",
+ SUBSYS_BEFORE_SHUTDOWN);
+ if (ret < 0)
+ pr_err("%s: sysmon_send_event error %d", __func__,
+ ret);
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+static void *ssr_modem_notif_hdle;
+static struct notifier_block mnb = {
+ .notifier_call = modem_notifier_cb,
+};
+
static void lpass_fatal_fn(struct work_struct *work)
{
pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
@@ -213,6 +235,18 @@
goto out;
}
+ ssr_modem_notif_hdle = subsys_notif_register_notifier("modem",
+ &mnb);
+ if (IS_ERR(ssr_modem_notif_hdle) < 0) {
+ ret = PTR_ERR(ssr_modem_notif_hdle);
+ pr_err("%s: subsys_register_notifier for Modem: err = %d\n",
+ __func__, ret);
+ subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+ iounmap(q6_wakeup_intr);
+ free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+ goto out;
+ }
+
pr_info("%s: lpass SSR driver init'ed.\n", __func__);
out:
return ret;
@@ -221,6 +255,7 @@
static void __exit lpass_fatal_exit(void)
{
subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+ subsys_notif_unregister_notifier(ssr_modem_notif_hdle, &mnb);
iounmap(q6_wakeup_intr);
free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
}
diff --git a/arch/arm/mach-msm/msm_rtb.c b/arch/arm/mach-msm/msm_rtb.c
new file mode 100644
index 0000000..d765f6a
--- /dev/null
+++ b/arch/arm/mach-msm/msm_rtb.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/atomic.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/memory_alloc.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/io.h>
+#include <asm-generic/sizes.h>
+#include <mach/memory.h>
+#include <mach/msm_rtb.h>
+#include <mach/system.h>
+
+#define SENTINEL_BYTE_1 0xFF
+#define SENTINEL_BYTE_2 0xAA
+#define SENTINEL_BYTE_3 0xFF
+
+/* Write
+ * 1) 3 bytes sentinel
+ * 2) 1 bytes of log type
+ * 3) 4 bytes of where the caller came from
+ * 4) 4 bytes index
+ * 4) 4 bytes extra data from the caller
+ *
+ * Total = 16 bytes.
+ */
+struct msm_rtb_layout {
+ unsigned char sentinel[3];
+ unsigned char log_type;
+ void *caller;
+ unsigned long idx;
+ void *data;
+} __attribute__ ((__packed__));
+
+
+struct msm_rtb_state {
+ struct msm_rtb_layout *rtb;
+ unsigned long phys;
+ int nentries;
+ int size;
+ int enabled;
+ uint32_t filter;
+ int step_size;
+};
+
+#if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
+DEFINE_PER_CPU(atomic_t, msm_rtb_idx_cpu);
+#else
+static atomic_t msm_rtb_idx;
+#endif
+
+struct msm_rtb_state msm_rtb = {
+ .size = SZ_1M,
+};
+
+module_param_named(filter, msm_rtb.filter, uint, 0644);
+module_param_named(enable, msm_rtb.enabled, int, 0644);
+
+int msm_rtb_event_should_log(enum logk_event_type log_type)
+{
+ return msm_rtb.enabled &&
+ ((1 << log_type) & msm_rtb.filter);
+}
+EXPORT_SYMBOL(msm_rtb_event_should_log);
+
+static void msm_rtb_emit_sentinel(struct msm_rtb_layout *start)
+{
+ start->sentinel[0] = SENTINEL_BYTE_1;
+ start->sentinel[1] = SENTINEL_BYTE_2;
+ start->sentinel[2] = SENTINEL_BYTE_3;
+}
+
+static void msm_rtb_write_type(enum logk_event_type log_type,
+ struct msm_rtb_layout *start)
+{
+ start->log_type = (char)log_type;
+}
+
+static void msm_rtb_write_caller(void *caller, struct msm_rtb_layout *start)
+{
+ start->caller = caller;
+}
+
+static void msm_rtb_write_idx(unsigned long idx,
+ struct msm_rtb_layout *start)
+{
+ start->idx = idx;
+}
+
+static void msm_rtb_write_data(void *data, struct msm_rtb_layout *start)
+{
+ start->data = data;
+}
+
+static int __init msm_rtb_set_buffer_size(char *p)
+{
+ int s;
+
+ s = memparse(p, NULL);
+ msm_rtb.size = ALIGN(s, SZ_4K);
+ return 0;
+}
+early_param("msm_rtb_size", msm_rtb_set_buffer_size);
+
+#if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
+static int msm_rtb_get_idx(void)
+{
+ int cpu, i;
+ atomic_t *index;
+
+ /*
+ * ideally we would use get_cpu but this is a close enough
+ * approximation for our purposes.
+ */
+ cpu = raw_smp_processor_id();
+
+ index = &per_cpu(msm_rtb_idx_cpu, cpu);
+
+ i = atomic_add_return(msm_rtb.step_size, index);
+ i -= msm_rtb.step_size;
+
+ return i;
+}
+#else
+static int msm_rtb_get_idx(void)
+{
+ int i;
+
+ i = atomic_inc_return(&msm_rtb_idx);
+ i--;
+
+ return i;
+}
+#endif
+
+int uncached_logk_pc(enum logk_event_type log_type, void *caller,
+ void *data)
+{
+ int i;
+ struct msm_rtb_layout *start;
+
+ if (!msm_rtb_event_should_log(log_type))
+ return 0;
+
+ i = msm_rtb_get_idx();
+
+ start = &msm_rtb.rtb[i & (msm_rtb.nentries - 1)];
+
+ msm_rtb_emit_sentinel(start);
+ msm_rtb_write_type(log_type, start);
+ msm_rtb_write_caller(caller, start);
+ msm_rtb_write_idx(i, start);
+ msm_rtb_write_data(data, start);
+ mb();
+
+ return 1;
+}
+EXPORT_SYMBOL(uncached_logk_pc);
+
+noinline int uncached_logk(enum logk_event_type log_type, void *data)
+{
+ return uncached_logk_pc(log_type, __builtin_return_address(0), data);
+}
+EXPORT_SYMBOL(uncached_logk);
+
+int msm_rtb_init(void)
+{
+#if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
+ unsigned int cpu;
+#endif
+
+ if (msm_rtb.size <= 0 || msm_rtb.size > SZ_1M)
+ return -EINVAL;
+
+ /*
+ * The ioremap call is made separately to store the physical
+ * address of the buffer. This is necessary for cases where
+ * the only way to access the buffer is a physical address.
+ */
+ msm_rtb.phys = allocate_contiguous_ebi_nomap(msm_rtb.size, SZ_4K);
+
+ if (!msm_rtb.phys)
+ return -ENOMEM;
+
+ msm_rtb.rtb = ioremap(msm_rtb.phys, msm_rtb.size);
+
+ if (!msm_rtb.rtb) {
+ free_contiguous_memory_by_paddr(msm_rtb.phys);
+ return -ENOMEM;
+ }
+
+ msm_rtb.nentries = msm_rtb.size / sizeof(struct msm_rtb_layout);
+
+ /* Round this down to a power of 2 */
+ msm_rtb.nentries = __rounddown_pow_of_two(msm_rtb.nentries);
+
+ memset(msm_rtb.rtb, 0, msm_rtb.size);
+
+
+#if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
+ for_each_possible_cpu(cpu) {
+ atomic_t *a = &per_cpu(msm_rtb_idx_cpu, cpu);
+ atomic_set(a, cpu);
+ }
+ msm_rtb.step_size = num_possible_cpus();
+#else
+ atomic_set(&msm_rtb_idx, 0);
+ msm_rtb.step_size = 1;
+#endif
+
+
+ msm_rtb.enabled = 1;
+ return 0;
+}
+module_init(msm_rtb_init)
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 5aa3834..1d13508 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -18,9 +18,10 @@
#include <linux/elf.h>
#include <linux/delay.h>
#include <linux/err.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
#include <mach/msm_iomap.h>
-#include <mach/msm_xo.h>
#include "peripheral-loader.h"
#include "scm-pas.h"
@@ -52,8 +53,8 @@
struct modem_data {
void __iomem *base;
unsigned long start_addr;
- struct msm_xo_voter *pxo;
- struct timer_list timer;
+ struct clk *xo;
+ struct delayed_work work;
};
static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
@@ -61,28 +62,30 @@
return 0;
}
-static void remove_proxy_votes(unsigned long data)
-{
- struct modem_data *drv = (struct modem_data *)data;
- msm_xo_mode_vote(drv->pxo, MSM_XO_MODE_OFF);
-}
-
-static void make_modem_proxy_votes(struct device *dev)
+static int make_modem_proxy_votes(struct device *dev)
{
int ret;
struct modem_data *drv = dev_get_drvdata(dev);
- ret = msm_xo_mode_vote(drv->pxo, MSM_XO_MODE_ON);
- if (ret)
- dev_err(dev, "Failed to enable PXO\n");
- mod_timer(&drv->timer, jiffies + msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+ ret = clk_prepare_enable(drv->xo);
+ if (ret) {
+ dev_err(dev, "Failed to enable XO\n");
+ return ret;
+ }
+ schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+ return 0;
+}
+
+static void remove_modem_proxy_votes(struct work_struct *work)
+{
+ struct modem_data *drv;
+ drv = container_of(work, struct modem_data, work.work);
+ clk_disable_unprepare(drv->xo);
}
static void remove_modem_proxy_votes_now(struct modem_data *drv)
{
- /* If the proxy vote hasn't been removed yet, remove it immediately. */
- if (del_timer(&drv->timer))
- remove_proxy_votes((unsigned long)drv);
+ flush_delayed_work(&drv->work);
}
static int modem_init_image(struct pil_desc *pil, const u8 *metadata,
@@ -97,9 +100,12 @@
static int modem_reset(struct pil_desc *pil)
{
u32 reg;
+ int ret;
const struct modem_data *drv = dev_get_drvdata(pil->dev);
- make_modem_proxy_votes(pil->dev);
+ ret = make_modem_proxy_votes(pil->dev);
+ if (ret)
+ return ret;
/* Put modem AHB0,1,2 clocks into reset */
writel_relaxed(BIT(0) | BIT(1), MAHB0_SFAB_PORT_RESET);
@@ -235,7 +241,9 @@
int ret;
struct modem_data *drv = dev_get_drvdata(pil->dev);
- make_modem_proxy_votes(pil->dev);
+ ret = make_modem_proxy_votes(pil->dev);
+ if (ret)
+ return ret;
ret = pas_auth_and_reset(PAS_MODEM);
if (ret)
@@ -269,6 +277,7 @@
struct modem_data *drv;
struct resource *res;
struct pil_desc *desc;
+ int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
@@ -283,15 +292,14 @@
if (!drv->base)
return -ENOMEM;
- drv->pxo = msm_xo_get(MSM_XO_PXO, dev_name(&pdev->dev));
- if (IS_ERR(drv->pxo))
- return PTR_ERR(drv->pxo);
+ drv->xo = clk_get(&pdev->dev, "xo");
+ if (IS_ERR(drv->xo))
+ return PTR_ERR(drv->xo);
desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
if (!desc)
return -ENOMEM;
- setup_timer(&drv->timer, remove_proxy_votes, (unsigned long)drv);
desc->name = "modem";
desc->depends_on = "q6";
desc->dev = &pdev->dev;
@@ -303,19 +311,21 @@
desc->ops = &pil_modem_ops;
dev_info(&pdev->dev, "using non-secure boot\n");
}
+ INIT_DELAYED_WORK(&drv->work, remove_modem_proxy_votes);
- if (msm_pil_register(desc)) {
- msm_xo_put(drv->pxo);
- return -EINVAL;
+ ret = msm_pil_register(desc);
+ if (ret) {
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
}
- return 0;
+ return ret;
}
static int __devexit pil_modem_driver_exit(struct platform_device *pdev)
{
struct modem_data *drv = platform_get_drvdata(pdev);
- del_timer_sync(&drv->timer);
- msm_xo_put(drv->pxo);
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index cdbfc48..511377d 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -20,10 +20,10 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/workqueue.h>
+#include <linux/clk.h>
#include <mach/msm_bus.h>
#include <mach/msm_iomap.h>
-#include <mach/msm_xo.h>
#include "peripheral-loader.h"
#include "pil-q6v4.h"
@@ -71,7 +71,7 @@
struct regulator *vreg;
struct regulator *pll_supply;
bool vreg_enabled;
- struct msm_xo_voter *xo;
+ struct clk *xo;
struct delayed_work work;
};
@@ -89,18 +89,29 @@
return 0;
}
-static void pil_q6v4_make_proxy_votes(struct device *dev)
+static int pil_q6v4_make_proxy_votes(struct device *dev)
{
struct q6v4_data *drv = dev_get_drvdata(dev);
int ret;
- msm_xo_mode_vote(drv->xo, MSM_XO_MODE_ON);
+ ret = clk_prepare_enable(drv->xo);
+ if (ret) {
+ dev_err(dev, "Failed to enable XO\n");
+ goto err;
+ }
if (drv->pll_supply) {
ret = regulator_enable(drv->pll_supply);
- if (ret)
- dev_err(dev, "failed to enable pll supply\n");
+ if (ret) {
+ dev_err(dev, "Failed to enable pll supply\n");
+ goto err_regulator;
+ }
}
schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+ return 0;
+err_regulator:
+ clk_disable_unprepare(drv->xo);
+err:
+ return ret;
}
static void pil_q6v4_remove_proxy_votes(struct work_struct *work)
@@ -108,7 +119,7 @@
struct q6v4_data *drv = container_of(work, struct q6v4_data, work.work);
if (drv->pll_supply)
regulator_disable(drv->pll_supply);
- msm_xo_mode_vote(drv->xo, MSM_XO_MODE_OFF);
+ clk_disable_unprepare(drv->xo);
}
static void pil_q6v4_remove_proxy_votes_now(struct device *dev)
@@ -191,7 +202,9 @@
const struct q6v4_data *drv = dev_get_drvdata(pil->dev);
const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
- pil_q6v4_make_proxy_votes(pil->dev);
+ err = pil_q6v4_make_proxy_votes(pil->dev);
+ if (err)
+ return err;
err = pil_q6v4_power_up(pil->dev);
if (err)
@@ -331,7 +344,9 @@
const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
int err;
- pil_q6v4_make_proxy_votes(pil->dev);
+ err = pil_q6v4_make_proxy_votes(pil->dev);
+ if (err)
+ return err;
err = pil_q6v4_power_up(pil->dev);
if (err)
@@ -442,7 +457,7 @@
goto err;
}
- drv->xo = msm_xo_get(pdata->xo_id, pdata->name);
+ drv->xo = clk_get(&pdev->dev, "xo");
if (IS_ERR(drv->xo)) {
ret = PTR_ERR(drv->xo);
goto err_xo;
@@ -454,8 +469,8 @@
goto err_pil;
return 0;
err_pil:
- cancel_delayed_work_sync(&drv->work);
- msm_xo_put(drv->xo);
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
err_xo:
regulator_put(drv->vreg);
err:
@@ -466,8 +481,8 @@
static int __devexit pil_q6v4_driver_exit(struct platform_device *pdev)
{
struct q6v4_data *drv = platform_get_drvdata(pdev);
- cancel_delayed_work_sync(&drv->work);
- msm_xo_put(drv->xo);
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
regulator_put(drv->vreg);
regulator_put(drv->pll_supply);
return 0;
diff --git a/arch/arm/mach-msm/pil-q6v4.h b/arch/arm/mach-msm/pil-q6v4.h
index 54bdf88..b0b97d0 100644
--- a/arch/arm/mach-msm/pil-q6v4.h
+++ b/arch/arm/mach-msm/pil-q6v4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -18,7 +18,6 @@
const unsigned long strap_ahb_lower;
void __iomem *aclk_reg;
void __iomem *jtag_clk_reg;
- const int xo_id;
const char *name;
const char *depends;
const unsigned pas_id;
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 7e78a15..29a9df9 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -88,20 +88,29 @@
struct regulator *pll_supply;
};
-static void pil_riva_make_proxy_votes(struct device *dev)
+static int pil_riva_make_proxy_votes(struct device *dev)
{
struct riva_data *drv = dev_get_drvdata(dev);
int ret;
+ ret = regulator_enable(drv->pll_supply);
+ if (ret) {
+ dev_err(dev, "failed to enable pll supply\n");
+ goto err;
+ }
if (drv->use_cxo) {
ret = clk_prepare_enable(drv->xo);
- if (ret)
+ if (ret) {
dev_err(dev, "failed to enable xo\n");
+ goto err_clk;
+ }
}
- ret = regulator_enable(drv->pll_supply);
- if (ret)
- dev_err(dev, "failed to enable pll supply\n");
schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+ return 0;
+err_clk:
+ regulator_disable(drv->pll_supply);
+err:
+ return ret;
}
static void pil_riva_remove_proxy_votes(struct work_struct *work)
@@ -156,7 +165,14 @@
writel_relaxed(reg, base + RIVA_PMU_A2XB_CFG);
drv->use_cxo = cxo_is_needed(drv);
- pil_riva_make_proxy_votes(pil->dev);
+ ret = pil_riva_make_proxy_votes(pil->dev);
+ if (ret) {
+ reg &= ~RIVA_PMU_A2XB_CFG_EN;
+ writel_relaxed(reg, base + RIVA_PMU_A2XB_CFG);
+ mb();
+ clk_disable_unprepare(drv->xo);
+ return ret;
+ }
/* Program PLL 13 to 960 MHz */
reg = readl_relaxed(RIVA_PLL_MODE);
@@ -298,8 +314,9 @@
if (ret)
return ret;
/* Proxy-vote for resources RIVA needs */
- pil_riva_make_proxy_votes(pil->dev);
- ret = pas_auth_and_reset(PAS_RIVA);
+ ret = pil_riva_make_proxy_votes(pil->dev);
+ if (!ret)
+ ret = pas_auth_and_reset(PAS_RIVA);
clk_disable_unprepare(drv->xo);
return ret;
}
@@ -390,7 +407,7 @@
goto err_register;
return 0;
err_register:
- cancel_delayed_work_sync(&drv->work);
+ flush_delayed_work_sync(&drv->work);
clk_put(drv->xo);
err:
regulator_put(drv->pll_supply);
@@ -400,7 +417,7 @@
static int __devexit pil_riva_remove(struct platform_device *pdev)
{
struct riva_data *drv = platform_get_drvdata(pdev);
- cancel_delayed_work_sync(&drv->work);
+ flush_delayed_work_sync(&drv->work);
clk_put(drv->xo);
regulator_put(drv->pll_supply);
return 0;
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index 13d92d1..37428da 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -27,6 +27,7 @@
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/slab.h>
+#include <asm/mach-types.h>
#include <mach/peripheral-loader.h>
#include <mach/msm_smd.h>
#include <mach/qdsp6v2/apr.h>
@@ -373,7 +374,11 @@
if (!q6.pil) {
pr_err("APR: Unable to load q6 image\n");
mutex_unlock(&q6.lock);
- return svc;
+ /* Return failure if not intended for simulator */
+ if (!machine_is_apq8064_sim()) {
+ pr_debug("APR: Not apq8064 sim\n");
+ return svc;
+ }
}
q6.state = APR_Q6_LOADED;
}
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index 2e61e90..ce5d084 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -783,6 +783,7 @@
pr_err("%s: More Audproc Cal then expected, "
"size received: %d\n", __func__, size);
store_audvol_cal(TX_CAL, data);
+ break;
case AUDIO_SET_AUDPROC_RX_VOL_CAL:
if (size > sizeof(struct cal_block))
pr_err("%s: More Audproc Cal then expected, "
diff --git a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
index 7096669..f02e0a0 100644
--- a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
+++ b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
@@ -1906,6 +1906,7 @@
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0xAC)}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0xAC)}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0x24, 0x24)}, \
+ {ADIE_CODEC_ACTION_DELAY_WAIT, 0x4E1F}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x3C)}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x3C)}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x1C)}, \
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 0bc3b0e..6c526de 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -1135,8 +1135,10 @@
return 0;
while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
- if (!ch_is_open(ch))
+ if (!ch_is_open(ch)) {
+ len = orig_len;
break;
+ }
if (xfer > len)
xfer = len;
if (user_buf) {
diff --git a/arch/arm/mach-msm/smem_log.c b/arch/arm/mach-msm/smem_log.c
index 6b7573c..bf598b7 100644
--- a/arch/arm/mach-msm/smem_log.c
+++ b/arch/arm/mach-msm/smem_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -133,6 +133,7 @@
{ SMEM_LOG_PROC_ID_MODEM, "MODM" },
{ SMEM_LOG_PROC_ID_Q6, "QDSP" },
{ SMEM_LOG_PROC_ID_APPS, "APPS" },
+ { SMEM_LOG_PROC_ID_WCNSS, "WCNSS" },
};
struct sym base_syms[] = {
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 67b1f7b..3d44075 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -978,7 +978,7 @@
if (cpu_is_msm7x01() || cpu_is_msm7x25() || cpu_is_msm7x27() ||
cpu_is_msm7x25a() || cpu_is_msm7x27a() || cpu_is_msm7x25aa() ||
- cpu_is_msm7x27aa()) {
+ cpu_is_msm7x27aa() || cpu_is_msm8625()) {
dgt->shift = MSM_DGT_SHIFT;
dgt->freq = 19200000 >> MSM_DGT_SHIFT;
dgt->clockevent.shift = 32 + MSM_DGT_SHIFT;
@@ -989,6 +989,11 @@
gpt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT
| MSM_CLOCK_FLAGS_ODD_MATCH_WRITE
| MSM_CLOCK_FLAGS_DELAYED_WRITE_POST;
+ if (cpu_is_msm8625()) {
+ dgt->irq = MSM8625_INT_DEBUG_TIMER_EXP;
+ gpt->irq = MSM8625_INT_GP_TIMER_EXP;
+ global_timer_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
+ }
} else if (cpu_is_qsd8x50()) {
dgt->freq = 4800000;
gpt->regbase = MSM_TMR_BASE;
@@ -1069,7 +1074,8 @@
ce->irq = clock->irq;
if (cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_apq8064() ||
- cpu_is_msm8930() || cpu_is_msm9615()) {
+ cpu_is_msm8930() || cpu_is_msm9615() ||
+ cpu_is_msm8625()) {
clock->percpu_evt = alloc_percpu(struct clock_event_device *);
if (!clock->percpu_evt) {
pr_err("msm_timer_init: memory allocation "
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index 7e25684..1507915 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -110,6 +110,11 @@
{
struct genlock *lock;
+ if (IS_ERR_OR_NULL(handle)) {
+ GENLOCK_LOG_ERR("Invalid handle\n");
+ return ERR_PTR(-EINVAL);
+ }
+
if (handle->lock != NULL) {
GENLOCK_LOG_ERR("Handle already has a lock attached\n");
return ERR_PTR(-EINVAL);
@@ -177,6 +182,11 @@
struct file *file;
struct genlock *lock;
+ if (IS_ERR_OR_NULL(handle)) {
+ GENLOCK_LOG_ERR("Invalid handle\n");
+ return ERR_PTR(-EINVAL);
+ }
+
if (handle->lock != NULL) {
GENLOCK_LOG_ERR("Handle already has a lock attached\n");
return ERR_PTR(-EINVAL);
@@ -392,9 +402,17 @@
int genlock_lock(struct genlock_handle *handle, int op, int flags,
uint32_t timeout)
{
- struct genlock *lock = handle->lock;
+ struct genlock *lock;
+
int ret = 0;
+ if (IS_ERR_OR_NULL(handle)) {
+ GENLOCK_LOG_ERR("Invalid handle\n");
+ return -EINVAL;
+ }
+
+ lock = handle->lock;
+
if (lock == NULL) {
GENLOCK_LOG_ERR("Handle does not have a lock attached\n");
return -EINVAL;
@@ -426,11 +444,18 @@
int genlock_wait(struct genlock_handle *handle, uint32_t timeout)
{
- struct genlock *lock = handle->lock;
+ struct genlock *lock;
unsigned long irqflags;
int ret = 0;
unsigned int ticks = msecs_to_jiffies(timeout);
+ if (IS_ERR_OR_NULL(handle)) {
+ GENLOCK_LOG_ERR("Invalid handle\n");
+ return -EINVAL;
+ }
+
+ lock = handle->lock;
+
if (lock == NULL) {
GENLOCK_LOG_ERR("Handle does not have a lock attached\n");
return -EINVAL;
@@ -471,12 +496,7 @@
return ret;
}
-/**
- * genlock_release_lock - Release a lock attached to a handle
- * @handle - Pointer to the handle holding the lock
- */
-
-void genlock_release_lock(struct genlock_handle *handle)
+static void genlock_release_lock(struct genlock_handle *handle)
{
unsigned long flags;
@@ -497,7 +517,6 @@
handle->lock = NULL;
handle->active = 0;
}
-EXPORT_SYMBOL(genlock_release_lock);
/*
* Release function called when all references to a handle are released
@@ -589,6 +608,9 @@
struct genlock *lock;
int ret;
+ if (IS_ERR_OR_NULL(handle))
+ return -EINVAL;
+
switch (cmd) {
case GENLOCK_IOC_NEW: {
lock = genlock_create_lock(handle);
@@ -643,8 +665,13 @@
return genlock_wait(handle, param.timeout);
}
case GENLOCK_IOC_RELEASE: {
- genlock_release_lock(handle);
- return 0;
+ /*
+ * Return error - this ioctl has been deprecated.
+ * Locks should only be released when the handle is
+ * destroyed
+ */
+ GENLOCK_LOG_ERR("Deprecated RELEASE ioctl called\n");
+ return -EINVAL;
}
default:
GENLOCK_LOG_ERR("Invalid ioctl\n");
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index dbd1bd4..332922e 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -25,6 +25,7 @@
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/wakelock.h>
+#include <linux/workqueue.h>
#include <linux/uaccess.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -47,6 +48,7 @@
static int hcismd_set_enable(const char *val, struct kernel_param *kp);
module_param_call(hcismd_set, hcismd_set_enable, NULL, &hcismd_set, 0644);
+static void hci_dev_restart(struct work_struct *worker);
struct hci_smd_data {
struct hci_dev *hdev;
@@ -312,6 +314,7 @@
{
struct hci_dev *hdev = hs.hdev;
struct hci_smd_data *hsmd = &hs;
+ struct work_struct *reset_worker;
int len = 0;
if (!hdev) {
@@ -335,6 +338,13 @@
case SMD_EVENT_CLOSE:
BT_INFO("Closing HCI-SMD channel :%s", EVENT_CHANNEL);
hci_smd_close(hdev);
+ reset_worker = kzalloc(sizeof(*reset_worker), GFP_ATOMIC);
+ if (!reset_worker) {
+ BT_ERR("Out of memory");
+ break;
+ }
+ INIT_WORK(reset_worker, hci_dev_restart);
+ schedule_work(reset_worker);
break;
default:
break;
@@ -464,6 +474,15 @@
}
}
+static void hci_dev_restart(struct work_struct *worker)
+{
+ mutex_lock(&hci_smd_enable);
+ hci_smd_deregister_dev(&hs);
+ hci_smd_register_dev(&hs);
+ mutex_unlock(&hci_smd_enable);
+ kfree(worker);
+}
+
static int hcismd_set_enable(const char *val, struct kernel_param *kp)
{
int ret = 0;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 9c1473f..6aed95c 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -60,6 +60,9 @@
#define MIN_LATENCY_MULTIPLIER (100)
#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
+#define POWERSAVE_BIAS_MAXLEVEL (1000)
+#define POWERSAVE_BIAS_MINLEVEL (-1000)
+
static void do_dbs_timer(struct work_struct *work);
static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
unsigned int event);
@@ -100,6 +103,9 @@
};
static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info);
+static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info);
+static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info);
+
static unsigned int dbs_enable; /* number of CPUs using this policy */
/*
@@ -117,7 +123,7 @@
unsigned int down_differential;
unsigned int ignore_nice;
unsigned int sampling_down_factor;
- unsigned int powersave_bias;
+ int powersave_bias;
unsigned int io_is_busy;
} dbs_tuners_ins = {
.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
@@ -179,10 +185,11 @@
unsigned int freq_next,
unsigned int relation)
{
- unsigned int freq_req, freq_reduc, freq_avg;
+ unsigned int freq_req, freq_avg;
unsigned int freq_hi, freq_lo;
unsigned int index = 0;
unsigned int jiffies_total, jiffies_hi, jiffies_lo;
+ int freq_reduc;
struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info,
policy->cpu);
@@ -225,6 +232,26 @@
return freq_hi;
}
+static int ondemand_powersave_bias_setspeed(struct cpufreq_policy *policy,
+ struct cpufreq_policy *altpolicy,
+ int level)
+{
+ if (level == POWERSAVE_BIAS_MAXLEVEL) {
+ /* maximum powersave; set to lowest frequency */
+ __cpufreq_driver_target(policy,
+ (altpolicy) ? altpolicy->min : policy->min,
+ CPUFREQ_RELATION_L);
+ return 1;
+ } else if (level == POWERSAVE_BIAS_MINLEVEL) {
+ /* minimum powersave; set to highest frequency */
+ __cpufreq_driver_target(policy,
+ (altpolicy) ? altpolicy->max : policy->max,
+ CPUFREQ_RELATION_H);
+ return 1;
+ }
+ return 0;
+}
+
static void ondemand_powersave_bias_init_cpu(int cpu)
{
struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
@@ -263,7 +290,12 @@
show_one(down_differential, down_differential);
show_one(sampling_down_factor, sampling_down_factor);
show_one(ignore_nice_load, ignore_nice);
-show_one(powersave_bias, powersave_bias);
+
+static ssize_t show_powersave_bias
+(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", dbs_tuners_ins.powersave_bias);
+}
static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
@@ -378,18 +410,75 @@
static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
{
- unsigned int input;
- int ret;
- ret = sscanf(buf, "%u", &input);
+ int input = 0;
+ int bypass = 0;
+ int ret, cpu, reenable_timer;
+ struct cpu_dbs_info_s *dbs_info;
+
+ ret = sscanf(buf, "%d", &input);
if (ret != 1)
return -EINVAL;
- if (input > 1000)
- input = 1000;
+ if (input >= POWERSAVE_BIAS_MAXLEVEL) {
+ input = POWERSAVE_BIAS_MAXLEVEL;
+ bypass = 1;
+ } else if (input <= POWERSAVE_BIAS_MINLEVEL) {
+ input = POWERSAVE_BIAS_MINLEVEL;
+ bypass = 1;
+ }
+
+ if (input == dbs_tuners_ins.powersave_bias) {
+ /* no change */
+ return count;
+ }
+
+ reenable_timer = ((dbs_tuners_ins.powersave_bias ==
+ POWERSAVE_BIAS_MAXLEVEL) ||
+ (dbs_tuners_ins.powersave_bias ==
+ POWERSAVE_BIAS_MINLEVEL));
dbs_tuners_ins.powersave_bias = input;
- ondemand_powersave_bias_init();
+ if (!bypass) {
+ if (reenable_timer) {
+ /* reinstate dbs timer */
+ for_each_online_cpu(cpu) {
+ if (lock_policy_rwsem_write(cpu) < 0)
+ continue;
+
+ dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+ if (dbs_info->cur_policy) {
+ /* restart dbs timer */
+ dbs_timer_init(dbs_info);
+ }
+ unlock_policy_rwsem_write(cpu);
+ }
+ }
+ ondemand_powersave_bias_init();
+ } else {
+ /* running at maximum or minimum frequencies; cancel
+ dbs timer as periodic load sampling is not necessary */
+ for_each_online_cpu(cpu) {
+ if (lock_policy_rwsem_write(cpu) < 0)
+ continue;
+
+ dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+ if (dbs_info->cur_policy) {
+ /* cpu using ondemand, cancel dbs timer */
+ mutex_lock(&dbs_info->timer_mutex);
+ dbs_timer_exit(dbs_info);
+
+ ondemand_powersave_bias_setspeed(
+ dbs_info->cur_policy,
+ NULL,
+ input);
+
+ mutex_unlock(&dbs_info->timer_mutex);
+ }
+ unlock_policy_rwsem_write(cpu);
+ }
+ }
+
return count;
}
@@ -680,6 +769,12 @@
{
int i;
+ if ((dbs_tuners_ins.powersave_bias == POWERSAVE_BIAS_MAXLEVEL) ||
+ (dbs_tuners_ins.powersave_bias == POWERSAVE_BIAS_MINLEVEL)) {
+ /* nothing to do */
+ return;
+ }
+
for_each_online_cpu(i) {
queue_work_on(i, input_wq, &per_cpu(dbs_refresh_work, i));
}
@@ -799,7 +894,12 @@
mutex_unlock(&dbs_mutex);
mutex_init(&this_dbs_info->timer_mutex);
- dbs_timer_init(this_dbs_info);
+
+ if (!ondemand_powersave_bias_setspeed(
+ this_dbs_info->cur_policy,
+ NULL,
+ dbs_tuners_ins.powersave_bias))
+ dbs_timer_init(this_dbs_info);
break;
case CPUFREQ_GOV_STOP:
@@ -828,6 +928,11 @@
else if (policy->min > this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L);
+ else if (dbs_tuners_ins.powersave_bias != 0)
+ ondemand_powersave_bias_setspeed(
+ this_dbs_info->cur_policy,
+ policy,
+ dbs_tuners_ins.powersave_bias);
mutex_unlock(&this_dbs_info->timer_mutex);
break;
}
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 8847a8d..a6c36c8 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -274,6 +274,7 @@
return handle;
}
+/* Client lock must be locked when calling */
static void ion_handle_destroy(struct kref *kref)
{
struct ion_handle *handle = container_of(kref, struct ion_handle, ref);
@@ -282,10 +283,8 @@
*/
WARN_ON(handle->kmap_cnt || handle->dmap_cnt || handle->usermap_cnt);
ion_buffer_put(handle->buffer);
- mutex_lock(&handle->client->lock);
if (!RB_EMPTY_NODE(&handle->node))
rb_erase(&handle->node, &handle->client->handles);
- mutex_unlock(&handle->client->lock);
kfree(handle);
}
@@ -448,13 +447,13 @@
mutex_lock(&client->lock);
valid_handle = ion_handle_validate(client, handle);
- mutex_unlock(&client->lock);
-
if (!valid_handle) {
+ mutex_unlock(&client->lock);
WARN("%s: invalid handle passed to free.\n", __func__);
return;
}
ion_handle_put(handle);
+ mutex_unlock(&client->lock);
}
EXPORT_SYMBOL(ion_free);
@@ -1254,7 +1253,9 @@
atomic_read(&client->ref.refcount),
atomic_read(&handle->ref.refcount),
atomic_read(&buffer->ref.refcount));
+ mutex_lock(&client->lock);
ion_handle_put(handle);
+ mutex_unlock(&client->lock);
ion_client_put(client);
pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n",
__func__, __LINE__,
@@ -1349,7 +1350,9 @@
mutex_unlock(&buffer->lock);
/* drop the reference to the handle */
err1:
+ mutex_lock(&client->lock);
ion_handle_put(handle);
+ mutex_unlock(&client->lock);
err:
/* drop the reference to the client */
ion_client_put(client);
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index 16ace6f..fc1cfb6 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -26,6 +26,7 @@
#include <linux/vmalloc.h>
#include <linux/memory_alloc.h>
#include <linux/seq_file.h>
+#include <linux/fmem.h>
#include <mach/msm_memtypes.h>
#include <mach/scm.h>
#include "ion_priv.h"
@@ -43,7 +44,7 @@
* @secure_base: Base address used when securing a heap that is shared.
* @secure_size: Size used when securing a heap that is shared.
* @lock: mutex to protect shared access.
- * @heap_secured: Identifies the heap_id as secure or not.
+ * @heap_protected: Indicates whether heap has been protected or not.
* @allocated_bytes: the total number of allocated bytes from the pool.
* @total_size: the total size of the memory pool.
* @request_region: function pointer to call when first mapping of memory
@@ -51,11 +52,14 @@
* @release_region: function pointer to call when last mapping of memory
* unmapped.
* @bus_id: token used with request/release region.
- * @kmap_count: the total number of times this heap has been mapped in
- * kernel space.
+ * @kmap_cached_count: the total number of times this heap has been mapped in
+ * kernel space (cached).
+ * @kmap_uncached_count:the total number of times this heap has been mapped in
+ * kernel space (un-cached).
* @umap_count: the total number of times this heap has been mapped in
* user space.
- * @alloc_count:the total number of times this heap has been allocated
+ * @reusable: indicates if the memory should be reused via fmem.
+ * @reserved_vrange: reserved virtual address range for use with fmem
*/
struct ion_cp_heap {
struct ion_heap heap;
@@ -65,20 +69,22 @@
ion_phys_addr_t secure_base;
size_t secure_size;
struct mutex lock;
- unsigned int heap_secured;
+ unsigned int heap_protected;
unsigned long allocated_bytes;
unsigned long total_size;
int (*request_region)(void *);
int (*release_region)(void *);
void *bus_id;
- unsigned long kmap_count;
+ unsigned long kmap_cached_count;
+ unsigned long kmap_uncached_count;
unsigned long umap_count;
- unsigned long alloc_count;
+ int reusable;
+ void *reserved_vrange;
};
enum {
- NON_SECURED_HEAP = 0,
- SECURED_HEAP = 1,
+ HEAP_NOT_PROTECTED = 0,
+ HEAP_PROTECTED = 1,
};
static int ion_cp_protect_mem(unsigned int phy_base, unsigned int size,
@@ -87,9 +93,19 @@
static int ion_cp_unprotect_mem(unsigned int phy_base, unsigned int size,
unsigned int permission_type);
+/**
+ * Get the total number of kernel mappings.
+ * Must be called with heap->lock locked.
+ */
+static unsigned long ion_cp_get_total_kmap_count(
+ const struct ion_cp_heap *cp_heap)
+{
+ return cp_heap->kmap_cached_count + cp_heap->kmap_uncached_count;
+}
/**
- * Protects memory if heap is unsecured heap.
+ * Protects memory if heap is unsecured heap. Also ensures that we are in
+ * the correct FMEM state if this heap is a reusable heap.
* Must be called with heap->lock locked.
*/
static int ion_cp_protect(struct ion_heap *heap)
@@ -98,23 +114,38 @@
container_of(heap, struct ion_cp_heap, heap);
int ret_value = 0;
- if (cp_heap->heap_secured == NON_SECURED_HEAP) {
- int ret_value = ion_cp_protect_mem(cp_heap->secure_base,
+ if (cp_heap->heap_protected == HEAP_NOT_PROTECTED) {
+ /* Make sure we are in C state when the heap is protected. */
+ if (cp_heap->reusable && !cp_heap->allocated_bytes) {
+ ret_value = fmem_set_state(FMEM_C_STATE);
+ if (ret_value)
+ goto out;
+ }
+
+ ret_value = ion_cp_protect_mem(cp_heap->secure_base,
cp_heap->secure_size, cp_heap->permission_type);
if (ret_value) {
pr_err("Failed to protect memory for heap %s - "
"error code: %d\n", heap->name, ret_value);
+
+ if (cp_heap->reusable && !cp_heap->allocated_bytes) {
+ if (fmem_set_state(FMEM_T_STATE) != 0)
+ pr_err("%s: unable to transition heap to T-state\n",
+ __func__);
+ }
} else {
- cp_heap->heap_secured = SECURED_HEAP;
- pr_debug("Protected heap %s @ 0x%x\n",
- heap->name, (unsigned int) cp_heap->base);
+ cp_heap->heap_protected = HEAP_PROTECTED;
+ pr_debug("Protected heap %s @ 0x%lx\n",
+ heap->name, cp_heap->base);
}
}
+out:
return ret_value;
}
/**
- * Unprotects memory if heap is secure heap.
+ * Unprotects memory if heap is secure heap. Also ensures that we are in
+ * the correct FMEM state if this heap is a reusable heap.
* Must be called with heap->lock locked.
*/
static void ion_cp_unprotect(struct ion_heap *heap)
@@ -122,7 +153,7 @@
struct ion_cp_heap *cp_heap =
container_of(heap, struct ion_cp_heap, heap);
- if (cp_heap->heap_secured == SECURED_HEAP) {
+ if (cp_heap->heap_protected == HEAP_PROTECTED) {
int error_code = ion_cp_unprotect_mem(
cp_heap->secure_base, cp_heap->secure_size,
cp_heap->permission_type);
@@ -130,9 +161,15 @@
pr_err("Failed to un-protect memory for heap %s - "
"error code: %d\n", heap->name, error_code);
} else {
- cp_heap->heap_secured = NON_SECURED_HEAP;
+ cp_heap->heap_protected = HEAP_NOT_PROTECTED;
pr_debug("Un-protected heap %s @ 0x%x\n", heap->name,
(unsigned int) cp_heap->base);
+
+ if (cp_heap->reusable && !cp_heap->allocated_bytes) {
+ if (fmem_set_state(FMEM_T_STATE) != 0)
+ pr_err("%s: unable to transition heap to T-state",
+ __func__);
+ }
}
}
}
@@ -149,29 +186,35 @@
container_of(heap, struct ion_cp_heap, heap);
mutex_lock(&cp_heap->lock);
-
- if (!secure_allocation && cp_heap->heap_secured == SECURED_HEAP) {
+ if (!secure_allocation && cp_heap->heap_protected == HEAP_PROTECTED) {
mutex_unlock(&cp_heap->lock);
pr_err("ION cannot allocate un-secure memory from protected"
" heap %s\n", heap->name);
return ION_CP_ALLOCATE_FAIL;
}
- if (secure_allocation && cp_heap->umap_count > 0) {
+ if (secure_allocation &&
+ (cp_heap->umap_count > 0 || cp_heap->kmap_cached_count > 0)) {
mutex_unlock(&cp_heap->lock);
pr_err("ION cannot allocate secure memory from heap with "
- "outstanding user space mappings for heap %s\n",
- heap->name);
+ "outstanding mappings: User space: %lu, kernel space "
+ "(cached): %lu\n", cp_heap->umap_count,
+ cp_heap->kmap_cached_count);
return ION_CP_ALLOCATE_FAIL;
}
- if (secure_allocation && ion_cp_protect(heap)) {
- mutex_unlock(&cp_heap->lock);
- return ION_CP_ALLOCATE_FAIL;
+ /*
+ * if this is the first reusable allocation, transition
+ * the heap
+ */
+ if (cp_heap->reusable && !cp_heap->allocated_bytes) {
+ if (fmem_set_state(FMEM_C_STATE) != 0) {
+ mutex_unlock(&cp_heap->lock);
+ return ION_RESERVED_ALLOCATE_FAIL;
+ }
}
cp_heap->allocated_bytes += size;
- ++cp_heap->alloc_count;
mutex_unlock(&cp_heap->lock);
offset = gen_pool_alloc_aligned(cp_heap->pool,
@@ -189,11 +232,12 @@
cp_heap->allocated_bytes, size);
cp_heap->allocated_bytes -= size;
- --cp_heap->alloc_count;
- if (cp_heap->alloc_count == 0)
- ion_cp_unprotect(heap);
-
+ if (cp_heap->reusable && !cp_heap->allocated_bytes) {
+ if (fmem_set_state(FMEM_T_STATE) != 0)
+ pr_err("%s: unable to transition heap to T-state\n",
+ __func__);
+ }
mutex_unlock(&cp_heap->lock);
return ION_CP_ALLOCATE_FAIL;
@@ -213,12 +257,13 @@
gen_pool_free(cp_heap->pool, addr, size);
mutex_lock(&cp_heap->lock);
-
cp_heap->allocated_bytes -= size;
- --cp_heap->alloc_count;
- if (cp_heap->alloc_count == 0)
- ion_cp_unprotect(heap);
+ if (cp_heap->reusable && !cp_heap->allocated_bytes) {
+ if (fmem_set_state(FMEM_T_STATE) != 0)
+ pr_err("%s: unable to transition heap to T-state\n",
+ __func__);
+ }
mutex_unlock(&cp_heap->lock);
}
@@ -248,30 +293,6 @@
buffer->priv_phys = ION_CP_ALLOCATE_FAIL;
}
-
-/**
- * Checks if user space mapping is allowed.
- * NOTE: Will increment the mapping count if
- * mapping is allowed.
- * Will fail mapping if heap is secured.
- */
-static unsigned int is_user_mapping_allowed(struct ion_heap *heap)
-{
- struct ion_cp_heap *cp_heap =
- container_of(heap, struct ion_cp_heap, heap);
-
- mutex_lock(&cp_heap->lock);
-
- if (cp_heap->heap_secured == SECURED_HEAP) {
- mutex_unlock(&cp_heap->lock);
- return 0;
- }
- ++cp_heap->umap_count;
-
- mutex_unlock(&cp_heap->lock);
- return 1;
-}
-
struct scatterlist *ion_cp_heap_map_dma(struct ion_heap *heap,
struct ion_buffer *buffer)
{
@@ -304,7 +325,7 @@
static int ion_cp_request_region(struct ion_cp_heap *cp_heap)
{
int ret_value = 0;
- if ((cp_heap->umap_count+cp_heap->kmap_count) == 1)
+ if ((cp_heap->umap_count + ion_cp_get_total_kmap_count(cp_heap)) == 0)
if (cp_heap->request_region)
ret_value = cp_heap->request_region(cp_heap->bus_id);
return ret_value;
@@ -316,48 +337,76 @@
static int ion_cp_release_region(struct ion_cp_heap *cp_heap)
{
int ret_value = 0;
- if ((cp_heap->umap_count + cp_heap->kmap_count) == 0)
+ if ((cp_heap->umap_count + ion_cp_get_total_kmap_count(cp_heap)) == 0)
if (cp_heap->release_region)
ret_value = cp_heap->release_region(cp_heap->bus_id);
return ret_value;
}
+void *ion_map_fmem_buffer(struct ion_buffer *buffer, unsigned long phys_base,
+ void *virt_base, unsigned long flags)
+{
+ int ret;
+ unsigned int offset = buffer->priv_phys - phys_base;
+ unsigned long start = ((unsigned long)virt_base) + offset;
+ const struct mem_type *type = ION_IS_CACHED(flags) ?
+ get_mem_type(MT_DEVICE_CACHED) :
+ get_mem_type(MT_DEVICE);
+
+ if (phys_base > buffer->priv_phys)
+ return NULL;
+
+
+ ret = ioremap_page_range(start, start + buffer->size,
+ buffer->priv_phys, __pgprot(type->prot_pte));
+
+ if (!ret)
+ return (void *)start;
+ else
+ return NULL;
+}
+
void *ion_cp_heap_map_kernel(struct ion_heap *heap,
struct ion_buffer *buffer,
unsigned long flags)
{
struct ion_cp_heap *cp_heap =
container_of(heap, struct ion_cp_heap, heap);
- void *ret_value;
+ void *ret_value = NULL;
mutex_lock(&cp_heap->lock);
+ if ((cp_heap->heap_protected == HEAP_NOT_PROTECTED) ||
+ ((cp_heap->heap_protected == HEAP_PROTECTED) &&
+ !ION_IS_CACHED(flags))) {
- if (cp_heap->heap_secured == SECURED_HEAP && ION_IS_CACHED(flags)) {
- pr_err("Unable to map secured heap %s as cached\n", heap->name);
- mutex_unlock(&cp_heap->lock);
- return NULL;
- }
+ if (ion_cp_request_region(cp_heap)) {
+ mutex_unlock(&cp_heap->lock);
+ return NULL;
+ }
- ++cp_heap->kmap_count;
+ if (cp_heap->reusable) {
+ ret_value = ion_map_fmem_buffer(buffer, cp_heap->base,
+ cp_heap->reserved_vrange, flags);
- if (ion_cp_request_region(cp_heap)) {
- --cp_heap->kmap_count;
- mutex_unlock(&cp_heap->lock);
- return NULL;
+ } else {
+ if (ION_IS_CACHED(flags))
+ ret_value = ioremap_cached(buffer->priv_phys,
+ buffer->size);
+ else
+ ret_value = ioremap(buffer->priv_phys,
+ buffer->size);
+ }
+
+ if (!ret_value) {
+ ion_cp_release_region(cp_heap);
+ } else {
+ if (ION_IS_CACHED(buffer->flags))
+ ++cp_heap->kmap_cached_count;
+ else
+ ++cp_heap->kmap_uncached_count;
+ }
}
mutex_unlock(&cp_heap->lock);
-
- if (ION_IS_CACHED(flags))
- ret_value = ioremap_cached(buffer->priv_phys, buffer->size);
- else
- ret_value = ioremap(buffer->priv_phys, buffer->size);
-
- if (!ret_value) {
- mutex_lock(&cp_heap->lock);
- --cp_heap->kmap_count;
- ion_cp_release_region(cp_heap);
- mutex_unlock(&cp_heap->lock);
- }
return ret_value;
}
@@ -367,11 +416,18 @@
struct ion_cp_heap *cp_heap =
container_of(heap, struct ion_cp_heap, heap);
- __arch_iounmap(buffer->vaddr);
+ if (cp_heap->reusable)
+ unmap_kernel_range((unsigned long)buffer->vaddr, buffer->size);
+ else
+ __arch_iounmap(buffer->vaddr);
+
buffer->vaddr = NULL;
mutex_lock(&cp_heap->lock);
- --cp_heap->kmap_count;
+ if (ION_IS_CACHED(buffer->flags))
+ --cp_heap->kmap_cached_count;
+ else
+ --cp_heap->kmap_uncached_count;
ion_cp_release_region(cp_heap);
mutex_unlock(&cp_heap->lock);
@@ -382,17 +438,15 @@
struct vm_area_struct *vma, unsigned long flags)
{
int ret_value = -EAGAIN;
- if (is_user_mapping_allowed(heap)) {
+ struct ion_cp_heap *cp_heap =
+ container_of(heap, struct ion_cp_heap, heap);
- struct ion_cp_heap *cp_heap =
- container_of(heap, struct ion_cp_heap, heap);
-
- mutex_lock(&cp_heap->lock);
+ mutex_lock(&cp_heap->lock);
+ if (cp_heap->heap_protected == HEAP_NOT_PROTECTED) {
if (ion_cp_request_region(cp_heap)) {
mutex_unlock(&cp_heap->lock);
return -EINVAL;
}
- mutex_unlock(&cp_heap->lock);
if (ION_IS_CACHED(flags))
ret_value = remap_pfn_range(vma, vma->vm_start,
@@ -407,13 +461,12 @@
vma->vm_end - vma->vm_start,
pgprot_noncached(vma->vm_page_prot));
- if (ret_value) {
- mutex_lock(&cp_heap->lock);
- --cp_heap->umap_count;
+ if (ret_value)
ion_cp_release_region(cp_heap);
- mutex_unlock(&cp_heap->lock);
- }
+ else
+ ++cp_heap->umap_count;
}
+ mutex_unlock(&cp_heap->lock);
return ret_value;
}
@@ -459,28 +512,26 @@
{
unsigned long total_alloc;
unsigned long total_size;
- unsigned long alloc_count;
unsigned long umap_count;
unsigned long kmap_count;
- unsigned long heap_secured;
+ unsigned long heap_protected;
struct ion_cp_heap *cp_heap =
container_of(heap, struct ion_cp_heap, heap);
mutex_lock(&cp_heap->lock);
total_alloc = cp_heap->allocated_bytes;
total_size = cp_heap->total_size;
- alloc_count = cp_heap->alloc_count;
umap_count = cp_heap->umap_count;
- kmap_count = cp_heap->kmap_count;
- heap_secured = cp_heap->heap_secured == SECURED_HEAP;
+ kmap_count = ion_cp_get_total_kmap_count(cp_heap);
+ heap_protected = cp_heap->heap_protected == HEAP_PROTECTED;
mutex_unlock(&cp_heap->lock);
seq_printf(s, "total bytes currently allocated: %lx\n", total_alloc);
seq_printf(s, "total heap size: %lx\n", total_size);
- seq_printf(s, "allocation count: %lx\n", alloc_count);
seq_printf(s, "umapping count: %lx\n", umap_count);
seq_printf(s, "kmapping count: %lx\n", kmap_count);
- seq_printf(s, "secured heap: %s\n", heap_secured ? "Yes" : "No");
+ seq_printf(s, "heap protected: %s\n", heap_protected ? "Yes" : "No");
+ seq_printf(s, "reusable: %s\n", cp_heap->reusable ? "Yes" : "No");
return 0;
}
@@ -491,7 +542,15 @@
struct ion_cp_heap *cp_heap =
container_of(heap, struct ion_cp_heap, heap);
mutex_lock(&cp_heap->lock);
- ret_value = ion_cp_protect(heap);
+ if (cp_heap->umap_count == 0 && cp_heap->kmap_cached_count == 0) {
+ ret_value = ion_cp_protect(heap);
+ } else {
+ pr_err("ION cannot secure heap with outstanding mappings: "
+ "User space: %lu, kernel space (cached): %lu\n",
+ cp_heap->umap_count, cp_heap->kmap_cached_count);
+ ret_value = -EINVAL;
+ }
+
mutex_unlock(&cp_heap->lock);
return ret_value;
}
@@ -545,18 +604,20 @@
goto destroy_pool;
cp_heap->allocated_bytes = 0;
- cp_heap->alloc_count = 0;
cp_heap->umap_count = 0;
- cp_heap->kmap_count = 0;
+ cp_heap->kmap_cached_count = 0;
+ cp_heap->kmap_uncached_count = 0;
cp_heap->total_size = heap_data->size;
cp_heap->heap.ops = &cp_heap_ops;
cp_heap->heap.type = ION_HEAP_TYPE_CP;
- cp_heap->heap_secured = NON_SECURED_HEAP;
+ cp_heap->heap_protected = HEAP_NOT_PROTECTED;
cp_heap->secure_base = cp_heap->base;
cp_heap->secure_size = heap_data->size;
if (heap_data->extra_data) {
struct ion_cp_heap_pdata *extra_data =
heap_data->extra_data;
+ cp_heap->reusable = extra_data->reusable;
+ cp_heap->reserved_vrange = extra_data->virt_addr;
cp_heap->permission_type = extra_data->permission_type;
if (extra_data->secure_size) {
cp_heap->secure_base = extra_data->secure_base;
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 78dfe6e..1d40aef 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -230,6 +230,9 @@
struct ion_heap *ion_cp_heap_create(struct ion_platform_heap *);
void ion_cp_heap_destroy(struct ion_heap *);
+struct ion_heap *ion_reusable_heap_create(struct ion_platform_heap *);
+void ion_reusable_heap_destroy(struct ion_heap *);
+
/**
* kernel api to allocate/free from carveout -- used when carveout is
* used to back an architecture specific custom heap
@@ -248,4 +251,24 @@
#define ION_CARVEOUT_ALLOCATE_FAIL -1
#define ION_CP_ALLOCATE_FAIL -1
+/**
+ * The reserved heap returns physical addresses, since 0 may be a valid
+ * physical address, this is used to indicate allocation failed
+ */
+#define ION_RESERVED_ALLOCATE_FAIL -1
+
+/**
+ * ion_map_fmem_buffer - map fmem allocated memory into the kernel
+ * @buffer - buffer to map
+ * @phys_base - physical base of the heap
+ * @virt_base - virtual base of the heap
+ * @flags - flags for the heap
+ *
+ * Map fmem allocated memory into the kernel address space. This
+ * is designed to be used by other heaps that need fmem behavior.
+ * The virtual range must be pre-allocated.
+ */
+void *ion_map_fmem_buffer(struct ion_buffer *buffer, unsigned long phys_base,
+ void *virt_base, unsigned long flags);
+
#endif /* _ION_PRIV_H */
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index f71f514..2a2892e 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -15,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/memory_alloc.h>
+#include <linux/fmem.h>
#include <mach/ion.h>
#include <mach/msm_memtypes.h>
#include "../ion_priv.h"
@@ -86,10 +87,20 @@
if (shared_heap) {
struct ion_cp_heap_pdata *cp_data =
(struct ion_cp_heap_pdata *) shared_heap->extra_data;
- heap->base = msm_ion_get_base(
- heap->size + shared_heap->size,
- shared_heap->memory_type,
- co_heap_data->align);
+ if (cp_data->reusable) {
+ const struct fmem_data *fmem_info =
+ fmem_get_info();
+ heap->base = fmem_info->phys -
+ fmem_info->reserved_size;
+ cp_data->virt_addr = fmem_info->virt;
+ pr_info("ION heap %s using FMEM\n",
+ shared_heap->name);
+ } else {
+ heap->base = msm_ion_get_base(
+ heap->size + shared_heap->size,
+ shared_heap->memory_type,
+ co_heap_data->align);
+ }
if (heap->base) {
shared_heap->base = heap->base + heap->size;
cp_data->secure_base = heap->base;
@@ -138,13 +149,24 @@
((struct ion_co_heap_pdata *) heap->extra_data)->align;
break;
case ION_HEAP_TYPE_CP:
- align =
- ((struct ion_cp_heap_pdata *) heap->extra_data)->align;
+ {
+ struct ion_cp_heap_pdata *data =
+ (struct ion_cp_heap_pdata *)
+ heap->extra_data;
+ if (data->reusable) {
+ const struct fmem_data *fmem_info =
+ fmem_get_info();
+ heap->base = fmem_info->phys;
+ data->virt_addr = fmem_info->virt;
+ pr_info("ION heap %s using FMEM\n", heap->name);
+ }
+ align = data->align;
break;
+ }
default:
break;
}
- if (align) {
+ if (align && !heap->base) {
heap->base = msm_ion_get_base(heap->size,
heap->memory_type,
align);
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index cf9a60a..7098002 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1320,7 +1320,6 @@
= (unsigned int *)((char *)drawctxt->gpustate.hostptr + CMD_OFFSET);
/* build indirect command buffers to save & restore regs/constants */
- adreno_idle(&adreno_dev->dev, KGSL_TIMEOUT_DEFAULT);
build_regrestore_cmds(adreno_dev, drawctxt);
build_regsave_cmds(adreno_dev, drawctxt);
@@ -1366,8 +1365,6 @@
tmp_ctx.cmd = build_chicken_restore_cmds(drawctxt);
/* build indirect command buffers to save & restore gmem */
- /* Idle because we are reading PM override registers */
- adreno_idle(&adreno_dev->dev, KGSL_TIMEOUT_DEFAULT);
drawctxt->context_gmem_shadow.gmem_save_commands = tmp_ctx.cmd;
tmp_ctx.cmd =
build_gmem2sys_cmds(adreno_dev, drawctxt,
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 71bdcde..d2a8879 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -303,6 +303,8 @@
struct mxt_info info;
struct mxt_finger finger[MXT_MAX_FINGER];
unsigned int irq;
+ unsigned int touch_x_size;
+ unsigned int touch_y_size;
struct regulator *vcc_ana;
struct regulator *vcc_dig;
struct regulator *vcc_i2c;
@@ -667,9 +669,9 @@
x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
y = (message->message[2] << 4) | ((message->message[3] & 0xf));
- if (data->pdata->x_size < 1024)
+ if (data->touch_x_size < 1024)
x = x >> 2;
- if (data->pdata->y_size < 1024)
+ if (data->touch_y_size < 1024)
y = y >> 2;
area = message->message[4];
@@ -1362,6 +1364,12 @@
}
+static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
+{
+ return (regulator_count_voltages(reg) > 0) ?
+ regulator_set_optimum_mode(reg, load_uA) : 0;
+}
+
static int mxt_power_on(struct mxt_data *data, bool on)
{
int rc;
@@ -1369,7 +1377,7 @@
if (on == false)
goto power_off;
- rc = regulator_set_optimum_mode(data->vcc_ana, MXT_ACTIVE_LOAD_UA);
+ rc = reg_set_optimum_mode_check(data->vcc_ana, MXT_ACTIVE_LOAD_UA);
if (rc < 0) {
dev_err(&data->client->dev,
"Regulator vcc_ana set_opt failed rc=%d\n", rc);
@@ -1384,8 +1392,8 @@
}
if (data->pdata->digital_pwr_regulator) {
- rc = regulator_set_optimum_mode(data->vcc_dig,
- MXT_ACTIVE_LOAD_DIG_UA);
+ rc = reg_set_optimum_mode_check(data->vcc_dig,
+ MXT_ACTIVE_LOAD_DIG_UA);
if (rc < 0) {
dev_err(&data->client->dev,
"Regulator vcc_dig set_opt failed rc=%d\n",
@@ -1402,7 +1410,7 @@
}
if (data->pdata->i2c_pull_up) {
- rc = regulator_set_optimum_mode(data->vcc_i2c, MXT_I2C_LOAD_UA);
+ rc = reg_set_optimum_mode_check(data->vcc_i2c, MXT_I2C_LOAD_UA);
if (rc < 0) {
dev_err(&data->client->dev,
"Regulator vcc_i2c set_opt failed rc=%d\n", rc);
@@ -1423,28 +1431,28 @@
error_reg_en_vcc_i2c:
if (data->pdata->i2c_pull_up)
- regulator_set_optimum_mode(data->vcc_i2c, 0);
+ reg_set_optimum_mode_check(data->vcc_i2c, 0);
error_reg_opt_i2c:
if (data->pdata->digital_pwr_regulator)
regulator_disable(data->vcc_dig);
error_reg_en_vcc_dig:
if (data->pdata->digital_pwr_regulator)
- regulator_set_optimum_mode(data->vcc_dig, 0);
+ reg_set_optimum_mode_check(data->vcc_dig, 0);
error_reg_opt_vcc_dig:
regulator_disable(data->vcc_ana);
error_reg_en_vcc_ana:
- regulator_set_optimum_mode(data->vcc_ana, 0);
+ reg_set_optimum_mode_check(data->vcc_ana, 0);
return rc;
power_off:
- regulator_set_optimum_mode(data->vcc_ana, 0);
+ reg_set_optimum_mode_check(data->vcc_ana, 0);
regulator_disable(data->vcc_ana);
if (data->pdata->digital_pwr_regulator) {
- regulator_set_optimum_mode(data->vcc_dig, 0);
+ reg_set_optimum_mode_check(data->vcc_dig, 0);
regulator_disable(data->vcc_dig);
}
if (data->pdata->i2c_pull_up) {
- regulator_set_optimum_mode(data->vcc_i2c, 0);
+ reg_set_optimum_mode_check(data->vcc_i2c, 0);
regulator_disable(data->vcc_i2c);
}
msleep(50);
@@ -1560,7 +1568,7 @@
if (on == false)
goto regulator_hpm;
- rc = regulator_set_optimum_mode(data->vcc_ana, MXT_LPM_LOAD_UA);
+ rc = reg_set_optimum_mode_check(data->vcc_ana, MXT_LPM_LOAD_UA);
if (rc < 0) {
dev_err(&data->client->dev,
"Regulator vcc_ana set_opt failed rc=%d\n", rc);
@@ -1568,7 +1576,7 @@
}
if (data->pdata->digital_pwr_regulator) {
- rc = regulator_set_optimum_mode(data->vcc_dig,
+ rc = reg_set_optimum_mode_check(data->vcc_dig,
MXT_LPM_LOAD_DIG_UA);
if (rc < 0) {
dev_err(&data->client->dev,
@@ -1578,7 +1586,7 @@
}
if (data->pdata->i2c_pull_up) {
- rc = regulator_set_optimum_mode(data->vcc_i2c,
+ rc = reg_set_optimum_mode_check(data->vcc_i2c,
MXT_I2C_LPM_LOAD_UA);
if (rc < 0) {
dev_err(&data->client->dev,
@@ -1591,7 +1599,7 @@
regulator_hpm:
- rc = regulator_set_optimum_mode(data->vcc_ana, MXT_ACTIVE_LOAD_UA);
+ rc = reg_set_optimum_mode_check(data->vcc_ana, MXT_ACTIVE_LOAD_UA);
if (rc < 0) {
dev_err(&data->client->dev,
"Regulator vcc_ana set_opt failed rc=%d\n", rc);
@@ -1599,7 +1607,7 @@
}
if (data->pdata->digital_pwr_regulator) {
- rc = regulator_set_optimum_mode(data->vcc_dig,
+ rc = reg_set_optimum_mode_check(data->vcc_dig,
MXT_ACTIVE_LOAD_DIG_UA);
if (rc < 0) {
dev_err(&data->client->dev,
@@ -1609,7 +1617,7 @@
}
if (data->pdata->i2c_pull_up) {
- rc = regulator_set_optimum_mode(data->vcc_i2c, MXT_I2C_LOAD_UA);
+ rc = reg_set_optimum_mode_check(data->vcc_i2c, MXT_I2C_LOAD_UA);
if (rc < 0) {
dev_err(&data->client->dev,
"Regulator vcc_i2c set_opt failed rc=%d\n", rc);
@@ -1620,21 +1628,21 @@
return 0;
fail_regulator_lpm:
- regulator_set_optimum_mode(data->vcc_ana, MXT_ACTIVE_LOAD_UA);
+ reg_set_optimum_mode_check(data->vcc_ana, MXT_ACTIVE_LOAD_UA);
if (data->pdata->digital_pwr_regulator)
- regulator_set_optimum_mode(data->vcc_dig,
- MXT_ACTIVE_LOAD_DIG_UA);
+ reg_set_optimum_mode_check(data->vcc_dig,
+ MXT_ACTIVE_LOAD_DIG_UA);
if (data->pdata->i2c_pull_up)
- regulator_set_optimum_mode(data->vcc_i2c, MXT_I2C_LOAD_UA);
+ reg_set_optimum_mode_check(data->vcc_i2c, MXT_I2C_LOAD_UA);
return rc;
fail_regulator_hpm:
- regulator_set_optimum_mode(data->vcc_ana, MXT_LPM_LOAD_UA);
+ reg_set_optimum_mode_check(data->vcc_ana, MXT_LPM_LOAD_UA);
if (data->pdata->digital_pwr_regulator)
- regulator_set_optimum_mode(data->vcc_dig, MXT_LPM_LOAD_DIG_UA);
+ reg_set_optimum_mode_check(data->vcc_dig, MXT_LPM_LOAD_DIG_UA);
if (data->pdata->i2c_pull_up)
- regulator_set_optimum_mode(data->vcc_i2c, MXT_I2C_LPM_LOAD_UA);
+ reg_set_optimum_mode_check(data->vcc_i2c, MXT_I2C_LPM_LOAD_UA);
return rc;
}
@@ -1809,7 +1817,7 @@
goto err_free_mem;
}
- input_dev->name = "Atmel maXTouch Touchscreen";
+ input_dev->name = "atmel_mxt_ts";
input_dev->id.bustype = BUS_I2C;
input_dev->dev.parent = &client->dev;
input_dev->open = mxt_input_open;
@@ -1842,6 +1850,16 @@
input_set_abs_params(input_dev, ABS_MT_PRESSURE,
0, 255, 0, 0);
+ if (pdata->touch_x_size)
+ data->touch_x_size = pdata->touch_x_size;
+ else
+ data->touch_x_size = pdata->x_size;
+
+ if (pdata->touch_y_size)
+ data->touch_y_size = pdata->touch_y_size;
+ else
+ data->touch_y_size = pdata->y_size;
+
/* set key array supported keys */
if (pdata->key_codes) {
for (i = 0; i < MXT_KEYARRAY_MAX_KEYS; i++) {
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 4212f18..545c61c 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -3029,6 +3029,11 @@
case V4L2_CID_PRIVATE_IRIS_ANTENNA:
temp_val = ctrl->value;
retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Set Antenna failed retval = %x", retval);
+ return retval;
+ }
+ radio->g_antenna = ctrl->value;
break;
case V4L2_CID_RDS_TX_PTY:
radio->pty = ctrl->value;
diff --git a/drivers/media/video/msm/io/msm_io_util.c b/drivers/media/video/msm/io/msm_io_util.c
index 9f58d6e..0ae247e 100644
--- a/drivers/media/video/msm/io/msm_io_util.c
+++ b/drivers/media/video/msm/io/msm_io_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -12,8 +12,11 @@
#include <linux/delay.h>
#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
#include <mach/board.h>
#include <mach/camera.h>
+#include <mach/gpiomux.h>
int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
struct clk **clk_ptr, int num_clk, int enable)
@@ -66,3 +69,183 @@
return rc;
}
+int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+ int num_vreg, struct regulator **reg_ptr, int config)
+{
+ int i = 0;
+ int rc = 0;
+ struct camera_vreg_t *curr_vreg;
+ if (config) {
+ for (i = 0; i < num_vreg; i++) {
+ curr_vreg = &cam_vreg[i];
+ reg_ptr[i] = regulator_get(dev,
+ curr_vreg->reg_name);
+ if (IS_ERR(reg_ptr[i])) {
+ pr_err("%s: %s get failed\n",
+ __func__,
+ curr_vreg->reg_name);
+ reg_ptr[i] = NULL;
+ goto vreg_get_fail;
+ }
+ if (curr_vreg->type == REG_LDO) {
+ rc = regulator_set_voltage(
+ reg_ptr[i],
+ curr_vreg->min_voltage,
+ curr_vreg->max_voltage);
+ if (rc < 0) {
+ pr_err(
+ "%s: %s set voltage failed\n",
+ __func__,
+ curr_vreg->reg_name);
+ goto vreg_set_voltage_fail;
+ }
+ rc = regulator_set_optimum_mode(
+ reg_ptr[i],
+ curr_vreg->op_mode);
+ if (rc < 0) {
+ pr_err(
+ "%s: %s set optimum mode failed\n",
+ __func__,
+ curr_vreg->reg_name);
+ goto vreg_set_opt_mode_fail;
+ }
+ }
+ }
+ } else {
+ for (i = num_vreg-1; i >= 0; i--) {
+ curr_vreg = &cam_vreg[i];
+ if (reg_ptr[i]) {
+ if (curr_vreg->type == REG_LDO) {
+ regulator_set_optimum_mode(
+ reg_ptr[i], 0);
+ regulator_set_voltage(
+ reg_ptr[i],
+ 0, curr_vreg->max_voltage);
+ }
+ regulator_put(reg_ptr[i]);
+ reg_ptr[i] = NULL;
+ }
+ }
+ }
+ return 0;
+
+vreg_unconfig:
+if (curr_vreg->type == REG_LDO)
+ regulator_set_optimum_mode(reg_ptr[i], 0);
+
+vreg_set_opt_mode_fail:
+if (curr_vreg->type == REG_LDO)
+ regulator_set_voltage(reg_ptr[i], 0,
+ curr_vreg->max_voltage);
+
+vreg_set_voltage_fail:
+ regulator_put(reg_ptr[i]);
+ reg_ptr[i] = NULL;
+
+vreg_get_fail:
+ for (i--; i >= 0; i--) {
+ curr_vreg = &cam_vreg[i];
+ goto vreg_unconfig;
+ }
+ return -ENODEV;
+}
+
+int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+ int num_vreg, struct regulator **reg_ptr, int enable)
+{
+ int i = 0, rc = 0;
+ if (enable) {
+ for (i = 0; i < num_vreg; i++) {
+ if (IS_ERR(reg_ptr[i])) {
+ pr_err("%s: %s null regulator\n",
+ __func__, cam_vreg[i].reg_name);
+ goto disable_vreg;
+ }
+ rc = regulator_enable(reg_ptr[i]);
+ if (rc < 0) {
+ pr_err("%s: %s enable failed\n",
+ __func__, cam_vreg[i].reg_name);
+ goto disable_vreg;
+ }
+ }
+ } else {
+ for (i = num_vreg-1; i >= 0; i--)
+ regulator_disable(reg_ptr[i]);
+ }
+ return rc;
+disable_vreg:
+ for (i--; i >= 0; i--) {
+ regulator_disable(reg_ptr[i]);
+ goto disable_vreg;
+ }
+ return rc;
+}
+
+int msm_camera_request_gpio_table(struct msm_camera_sensor_info *sinfo,
+ int gpio_en)
+{
+ int rc = 0;
+ struct msm_camera_gpio_conf *gpio_conf =
+ sinfo->sensor_platform_info->gpio_conf;
+
+ if (gpio_conf->cam_gpio_req_tbl == NULL ||
+ gpio_conf->cam_gpio_common_tbl == NULL) {
+ pr_err("%s: NULL camera gpio table\n", __func__);
+ return -EFAULT;
+ }
+
+ if (gpio_en) {
+ if (gpio_conf->cam_gpiomux_conf_tbl != NULL) {
+ msm_gpiomux_install(
+ (struct msm_gpiomux_config *)gpio_conf->
+ cam_gpiomux_conf_tbl,
+ gpio_conf->cam_gpiomux_conf_tbl_size);
+ }
+ rc = gpio_request_array(gpio_conf->cam_gpio_common_tbl,
+ gpio_conf->cam_gpio_common_tbl_size);
+ if (rc < 0) {
+ pr_err("%s common gpio request failed\n", __func__);
+ return rc;
+ }
+ rc = gpio_request_array(gpio_conf->cam_gpio_req_tbl,
+ gpio_conf->cam_gpio_req_tbl_size);
+ if (rc < 0) {
+ pr_err("%s camera gpio request failed\n", __func__);
+ gpio_free_array(gpio_conf->cam_gpio_common_tbl,
+ gpio_conf->cam_gpio_common_tbl_size);
+ return rc;
+ }
+ } else {
+ gpio_free_array(gpio_conf->cam_gpio_req_tbl,
+ gpio_conf->cam_gpio_req_tbl_size);
+ gpio_free_array(gpio_conf->cam_gpio_common_tbl,
+ gpio_conf->cam_gpio_common_tbl_size);
+ }
+ return rc;
+}
+
+int msm_camera_config_gpio_table(struct msm_camera_sensor_info *sinfo,
+ int gpio_en)
+{
+ struct msm_camera_gpio_conf *gpio_conf =
+ sinfo->sensor_platform_info->gpio_conf;
+ int rc = 0, i;
+
+ if (gpio_en) {
+ for (i = 0; i < gpio_conf->cam_gpio_set_tbl_size; i++) {
+ gpio_set_value_cansleep(
+ gpio_conf->cam_gpio_set_tbl[i].gpio,
+ gpio_conf->cam_gpio_set_tbl[i].flags);
+ usleep_range(gpio_conf->cam_gpio_set_tbl[i].delay,
+ gpio_conf->cam_gpio_set_tbl[i].delay + 1000);
+ }
+ } else {
+ for (i = gpio_conf->cam_gpio_set_tbl_size - 1; i >= 0; i--) {
+ if (gpio_conf->cam_gpio_set_tbl[i].flags)
+ gpio_set_value_cansleep(
+ gpio_conf->cam_gpio_set_tbl[i].gpio,
+ GPIOF_OUT_INIT_LOW);
+ }
+ }
+ return rc;
+}
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index a9aa28b..ed77185 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -38,9 +38,6 @@
module_param(msm_camera_v4l2_nr, uint, 0644);
MODULE_PARM_DESC(msm_camera_v4l2_nr, "videoX start number, -1 is autodetect");
-static int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
- struct video_device *pvdev);
-
static void msm_queue_init(struct msm_device_queue *queue, const char *name)
{
D("%s\n", __func__);
@@ -835,7 +832,8 @@
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
- D("%s Inst = %p\n", __func__, pcam_inst);
+ D("%s Inst=%p, mode=%d, idx=%d\n", __func__, pcam_inst,
+ pcam_inst->image_mode, pb->index);
WARN_ON(pctx != f->private_data);
if (!pcam_inst->buf_offset) {
@@ -865,7 +863,8 @@
}
rc = vb2_qbuf(&pcam_inst->vid_bufq, pb);
- D("%s, videobuf_qbuf returns %d\n", __func__, rc);
+ D("%s, videobuf_qbuf mode %d and idx %d returns %d\n", __func__,
+ pcam_inst->image_mode, pb->index, rc);
return rc;
}
@@ -1677,6 +1676,7 @@
struct v4l2_event ev;
struct msm_camera_info temp_cam_info;
struct msm_cam_config_dev_info temp_config_info;
+ struct msm_mctl_node_info temp_mctl_info;
struct v4l2_event_subscription temp_sub;
int i;
@@ -1744,6 +1744,34 @@
}
rc = 0;
break;
+ case MSM_CAM_IOCTL_GET_MCTL_INFO:
+ if (copy_from_user(&temp_mctl_info, (void __user *)arg,
+ sizeof(struct msm_mctl_node_info))) {
+ rc = -EINVAL;
+ return rc;
+ }
+
+ for (i = 0; i < g_server_dev.mctl_node_info.num_mctl_nodes;
+ i++) {
+ if (copy_to_user((void __user *)
+ temp_mctl_info.mctl_node_name[i],
+ g_server_dev.mctl_node_info.mctl_node_name[i], strnlen(
+ g_server_dev.mctl_node_info.mctl_node_name[i],
+ MAX_DEV_NAME_LEN))) {
+ rc = -EINVAL;
+ return rc;
+ }
+ }
+ temp_mctl_info.num_mctl_nodes =
+ g_server_dev.mctl_node_info.num_mctl_nodes;
+ if (copy_to_user((void __user *)arg,
+ &temp_mctl_info,
+ sizeof(struct msm_mctl_node_info))) {
+ rc = -EINVAL;
+ return rc;
+ }
+ rc = 0;
+ break;
case VIDIOC_SUBSCRIBE_EVENT:
if (copy_from_user(&temp_sub, (void __user *)arg,
@@ -1991,7 +2019,6 @@
(*((uint32_t *)ev.u.data));
/* Copy the event structure into user struct. */
u_isp_event = *k_isp_event;
-
if (ev.type != (V4L2_EVENT_PRIVATE_START +
MSM_CAM_RESP_DIV_FRAME_EVT_MSG) &&
ev.type != (V4L2_EVENT_PRIVATE_START +
@@ -2152,7 +2179,7 @@
.mmap = msm_mmap_config,
};
-static int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
+int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
struct video_device *pvdev)
{
int rc = 0;
@@ -2476,6 +2503,7 @@
/* init the user count and lock*/
pcam->use_count = 0;
mutex_init(&pcam->vid_lock);
+ mutex_init(&pcam->mctl_node.dev_lock);
/* Initialize the formats supported */
rc = msm_mctl_init_user_formats(pcam);
@@ -2486,11 +2514,18 @@
if (rc < 0)
goto failure;
+ rc = msm_setup_mctl_node(pcam);
+ if (rc < 0) {
+ pr_err("%s:failed to create mctl device: %d\n",
+ __func__, rc);
+ goto failure;
+ }
+
g_server_dev.camera_info.video_dev_name
[g_server_dev.camera_info.num_cameras]
= video_device_node_name(pcam->pvdev);
D("%s Connected video device %s\n", __func__,
- g_server_dev.camera_info.video_dev_name
+ g_server_dev.camera_info.video_dev_name
[g_server_dev.camera_info.num_cameras]);
g_server_dev.camera_info.s_mount_angle
@@ -2501,7 +2536,17 @@
[g_server_dev.camera_info.num_cameras]
= sdata->camera_type;
+ g_server_dev.mctl_node_info.mctl_node_name
+ [g_server_dev.mctl_node_info.num_mctl_nodes]
+ = video_device_node_name(pcam->mctl_node.pvdev);
+
+ pr_info("%s mctl_node_name[%d] = %s\n", __func__,
+ g_server_dev.mctl_node_info.num_mctl_nodes,
+ g_server_dev.mctl_node_info.mctl_node_name
+ [g_server_dev.mctl_node_info.num_mctl_nodes]);
+
g_server_dev.camera_info.num_cameras++;
+ g_server_dev.mctl_node_info.num_mctl_nodes++;
D("%s done, rc = %d\n", __func__, rc);
D("%s number of sensors connected is %d\n", __func__,
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index cc2e8b4..22322b8 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -235,6 +235,10 @@
struct pm_qos_request_list pm_qos_req_list;
struct msm_mctl_pp_info pp_info;
struct ion_client *client;
+ /* VFE output mode.
+ * Used to interpret the Primary/Secondary messages
+ * to preview/video/main/thumbnail image types*/
+ uint32_t vfe_output_mode;
};
/* abstract camera device represents a VFE and connected sensor */
@@ -290,6 +294,16 @@
struct img_plane_info plane_info;
int vbqueue_initialized;
};
+
+struct msm_cam_mctl_node {
+ /* MCTL V4l2 device */
+ struct v4l2_device v4l2_dev;
+ struct video_device *pvdev;
+ struct msm_cam_v4l2_dev_inst *dev_inst[MSM_DEV_INST_MAX];
+ struct msm_cam_v4l2_dev_inst *dev_inst_map[MSM_MAX_IMG_MODE];
+ struct mutex dev_lock;
+};
+
/* abstract camera device for each sensor successfully probed*/
struct msm_cam_v4l2_device {
/* standard device interfaces */
@@ -340,6 +354,7 @@
uint8_t ctrl_data[max_control_command_size];
struct msm_ctrl_cmd ctrl;
uint32_t event_mask;
+ struct msm_cam_mctl_node mctl_node;
};
static inline struct msm_cam_v4l2_device *to_pcam(
struct v4l2_device *v4l2_dev)
@@ -387,7 +402,8 @@
int use_count;
/* all the registered ISP subdevice*/
struct msm_isp_ops *isp_subdev[MSM_MAX_CAMERA_CONFIGS];
-
+ /* info of MCTL nodes successfully probed*/
+ struct msm_mctl_node_info mctl_node_info;
};
/* camera server related functions */
@@ -412,8 +428,10 @@
int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
int msg_type, struct msm_free_buf *frame, int dirty);
int msm_mctl_reserve_free_buf(struct msm_cam_media_controller *pmctl,
+ struct msm_cam_v4l2_dev_inst *pcam_inst,
int path, struct msm_free_buf *free_buf);
int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
+ struct msm_cam_v4l2_dev_inst *pcam_inst,
int path, struct msm_free_buf *free_buf);
/*Memory(PMEM) functions*/
int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
@@ -454,7 +472,7 @@
unsigned int cmd, unsigned long arg);
int msm_mctl_pp_notify(struct msm_cam_media_controller *pmctl,
struct msm_mctl_pp_frame_info *pp_frame_info);
-int msm_mctl_out_type_to_inst_index(struct msm_cam_v4l2_device *pcam,
+int msm_mctl_img_mode_to_inst_index(struct msm_cam_media_controller *pmctl,
int out_type);
struct msm_frame_buffer *msm_mctl_buf_find(
struct msm_cam_media_controller *pmctl,
@@ -490,7 +508,16 @@
int msm_mctl_pp_divert_done(
struct msm_cam_media_controller *p_mctl,
void __user *arg);
-
+int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
+ struct video_device *pvdev);
+int msm_setup_mctl_node(struct msm_cam_v4l2_device *pcam);
+struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
+ struct msm_cam_media_controller *pmctl,
+ int image_mode);
+int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
+ int image_mode, struct msm_frame_buffer *buf);
+int msm_mctl_pp_mctl_divert_done(struct msm_cam_media_controller *p_mctl,
+ void __user *arg);
#endif /* __KERNEL__ */
#endif /* _MSM_H */
diff --git a/drivers/media/video/msm/msm_io_8960.c b/drivers/media/video/msm/msm_io_8960.c
index f35b5f1..79294a3 100644
--- a/drivers/media/video/msm/msm_io_8960.c
+++ b/drivers/media/video/msm/msm_io_8960.c
@@ -27,38 +27,14 @@
#define BUFF_SIZE_128 128
-#define CAM_VAF_MINUV 2800000
-#define CAM_VAF_MAXUV 2800000
-#define CAM_VDIG_MINUV 1200000
-#define CAM_VDIG_MAXUV 1200000
-#define CAM_VANA_MINUV 2800000
-#define CAM_VANA_MAXUV 2850000
-#define CAM_CSI_VDD_MINUV 1200000
-#define CAM_CSI_VDD_MAXUV 1200000
-
-#define CAM_VAF_LOAD_UA 300000
-#define CAM_VDIG_LOAD_UA 105000
-#define CAM_VANA_LOAD_UA 85600
-#define CAM_CSI_LOAD_UA 20000
-
-static struct clk *camio_cam_clk;
-
static struct clk *camio_jpeg_clk;
static struct clk *camio_jpeg_pclk;
static struct regulator *fs_ijpeg;
-static struct regulator *cam_vana;
-static struct regulator *cam_vio;
-static struct regulator *cam_vdig;
-static struct regulator *cam_vaf;
-static struct regulator *mipi_csi_vdd;
-static struct msm_camera_io_clk camio_clk;
static struct platform_device *camio_dev;
static struct resource *s3drw_io, *s3dctl_io;
static struct resource *s3drw_mem, *s3dctl_mem;
void __iomem *s3d_rw, *s3d_ctl;
-struct msm_bus_scale_pdata *cam_bus_scale_table;
-
void msm_io_w(u32 data, void __iomem *addr)
{
@@ -136,213 +112,12 @@
msm_io_dump(dest_addr, len);
}
-static int msm_camera_vreg_enable(struct device *dev)
-{
- if (mipi_csi_vdd == NULL) {
- mipi_csi_vdd = regulator_get(dev, "mipi_csi_vdd");
- if (IS_ERR(mipi_csi_vdd)) {
- CDBG("%s: VREG MIPI CSI VDD get failed\n", __func__);
- mipi_csi_vdd = NULL;
- return -ENODEV;
- }
- if (regulator_set_voltage(mipi_csi_vdd, CAM_CSI_VDD_MINUV,
- CAM_CSI_VDD_MAXUV)) {
- CDBG("%s: VREG MIPI CSI VDD set voltage failed\n",
- __func__);
- goto mipi_csi_vdd_put;
- }
- if (regulator_set_optimum_mode(mipi_csi_vdd,
- CAM_CSI_LOAD_UA) < 0) {
- CDBG("%s: VREG MIPI CSI set optimum mode failed\n",
- __func__);
- goto mipi_csi_vdd_release;
- }
- if (regulator_enable(mipi_csi_vdd)) {
- CDBG("%s: VREG MIPI CSI VDD enable failed\n",
- __func__);
- goto mipi_csi_vdd_disable;
- }
- }
- if (cam_vana == NULL) {
- cam_vana = regulator_get(dev, "cam_vana");
- if (IS_ERR(cam_vana)) {
- CDBG("%s: VREG CAM VANA get failed\n", __func__);
- cam_vana = NULL;
- goto mipi_csi_vdd_disable;
- }
- if (regulator_set_voltage(cam_vana, CAM_VANA_MINUV,
- CAM_VANA_MAXUV)) {
- CDBG("%s: VREG CAM VANA set voltage failed\n",
- __func__);
- goto cam_vana_put;
- }
- if (regulator_set_optimum_mode(cam_vana,
- CAM_VANA_LOAD_UA) < 0) {
- CDBG("%s: VREG CAM VANA set optimum mode failed\n",
- __func__);
- goto cam_vana_release;
- }
- if (regulator_enable(cam_vana)) {
- CDBG("%s: VREG CAM VANA enable failed\n", __func__);
- goto cam_vana_disable;
- }
- }
- if (cam_vio == NULL) {
- cam_vio = regulator_get(dev, "cam_vio");
- if (IS_ERR(cam_vio)) {
- CDBG("%s: VREG VIO get failed\n", __func__);
- cam_vio = NULL;
- goto cam_vana_disable;
- }
- if (regulator_enable(cam_vio)) {
- CDBG("%s: VREG VIO enable failed\n", __func__);
- goto cam_vio_put;
- }
- }
- if (cam_vdig == NULL) {
- cam_vdig = regulator_get(dev, "cam_vdig");
- if (IS_ERR(cam_vdig)) {
- CDBG("%s: VREG CAM VDIG get failed\n", __func__);
- cam_vdig = NULL;
- goto cam_vio_disable;
- }
- if (regulator_set_voltage(cam_vdig, CAM_VDIG_MINUV,
- CAM_VDIG_MAXUV)) {
- CDBG("%s: VREG CAM VDIG set voltage failed\n",
- __func__);
- goto cam_vdig_put;
- }
- if (regulator_set_optimum_mode(cam_vdig,
- CAM_VDIG_LOAD_UA) < 0) {
- CDBG("%s: VREG CAM VDIG set optimum mode failed\n",
- __func__);
- goto cam_vdig_release;
- }
- if (regulator_enable(cam_vdig)) {
- CDBG("%s: VREG CAM VDIG enable failed\n", __func__);
- goto cam_vdig_disable;
- }
- }
- if (cam_vaf == NULL) {
- cam_vaf = regulator_get(dev, "cam_vaf");
- if (IS_ERR(cam_vaf)) {
- CDBG("%s: VREG CAM VAF get failed\n", __func__);
- cam_vaf = NULL;
- goto cam_vdig_disable;
- }
- if (regulator_set_voltage(cam_vaf, CAM_VAF_MINUV,
- CAM_VAF_MAXUV)) {
- CDBG("%s: VREG CAM VAF set voltage failed\n",
- __func__);
- goto cam_vaf_put;
- }
- if (regulator_set_optimum_mode(cam_vaf,
- CAM_VAF_LOAD_UA) < 0) {
- CDBG("%s: VREG CAM VAF set optimum mode failed\n",
- __func__);
- goto cam_vaf_release;
- }
- if (regulator_enable(cam_vaf)) {
- CDBG("%s: VREG CAM VAF enable failed\n", __func__);
- goto cam_vaf_disable;
- }
- }
- return 0;
-
-cam_vaf_disable:
- regulator_set_optimum_mode(cam_vaf, 0);
-cam_vaf_release:
- regulator_set_voltage(cam_vaf, 0, CAM_VAF_MAXUV);
- regulator_disable(cam_vaf);
-cam_vaf_put:
- regulator_put(cam_vaf);
- cam_vaf = NULL;
-cam_vdig_disable:
- regulator_set_optimum_mode(cam_vdig, 0);
-cam_vdig_release:
- regulator_set_voltage(cam_vdig, 0, CAM_VDIG_MAXUV);
- regulator_disable(cam_vdig);
-cam_vdig_put:
- regulator_put(cam_vdig);
- cam_vdig = NULL;
-cam_vio_disable:
- regulator_disable(cam_vio);
-cam_vio_put:
- regulator_put(cam_vio);
- cam_vio = NULL;
-cam_vana_disable:
- regulator_set_optimum_mode(cam_vana, 0);
-cam_vana_release:
- regulator_set_voltage(cam_vana, 0, CAM_VANA_MAXUV);
- regulator_disable(cam_vana);
-cam_vana_put:
- regulator_put(cam_vana);
- cam_vana = NULL;
-mipi_csi_vdd_disable:
- regulator_set_optimum_mode(mipi_csi_vdd, 0);
-mipi_csi_vdd_release:
- regulator_set_voltage(mipi_csi_vdd, 0, CAM_CSI_VDD_MAXUV);
- regulator_disable(mipi_csi_vdd);
-
-mipi_csi_vdd_put:
- regulator_put(mipi_csi_vdd);
- mipi_csi_vdd = NULL;
- return -ENODEV;
-}
-
-static void msm_camera_vreg_disable(void)
-{
- if (mipi_csi_vdd) {
- regulator_set_voltage(mipi_csi_vdd, 0, CAM_CSI_VDD_MAXUV);
- regulator_set_optimum_mode(mipi_csi_vdd, 0);
- regulator_disable(mipi_csi_vdd);
- regulator_put(mipi_csi_vdd);
- mipi_csi_vdd = NULL;
- }
-
- if (cam_vana) {
- regulator_set_voltage(cam_vana, 0, CAM_VANA_MAXUV);
- regulator_set_optimum_mode(cam_vana, 0);
- regulator_disable(cam_vana);
- regulator_put(cam_vana);
- cam_vana = NULL;
- }
-
- if (cam_vio) {
- regulator_disable(cam_vio);
- regulator_put(cam_vio);
- cam_vio = NULL;
- }
-
- if (cam_vdig) {
- regulator_set_voltage(cam_vdig, 0, CAM_VDIG_MAXUV);
- regulator_set_optimum_mode(cam_vdig, 0);
- regulator_disable(cam_vdig);
- regulator_put(cam_vdig);
- cam_vdig = NULL;
- }
-
- if (cam_vaf) {
- regulator_set_voltage(cam_vaf, 0, CAM_VAF_MAXUV);
- regulator_set_optimum_mode(cam_vaf, 0);
- regulator_disable(cam_vaf);
- regulator_put(cam_vaf);
- cam_vaf = NULL;
- }
-}
-
int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
{
int rc = 0;
struct clk *clk = NULL;
switch (clktype) {
- case CAMIO_CAM_MCLK_CLK:
- camio_cam_clk =
- clk = clk_get(&camio_dev->dev, "cam_clk");
- msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
- break;
-
case CAMIO_JPEG_CLK:
camio_jpeg_clk =
clk = clk_get(NULL, "ijpeg_clk");
@@ -375,10 +150,6 @@
struct clk *clk = NULL;
switch (clktype) {
- case CAMIO_CAM_MCLK_CLK:
- clk = camio_cam_clk;
- break;
-
case CAMIO_JPEG_CLK:
clk = camio_jpeg_clk;
break;
@@ -403,12 +174,6 @@
return rc;
}
-void msm_camio_clk_rate_set(int rate)
-{
- struct clk *clk = camio_cam_clk;
- clk_set_rate(clk, rate);
-}
-
void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
{
clk_set_rate(clk, rate);
@@ -459,38 +224,6 @@
return rc;
}
-static int config_gpio_table(struct msm_camera_sensor_info *sinfo, int gpio_en)
-{
- struct msm_camera_gpio_conf *gpio_conf = sinfo->gpio_conf;
- int rc = 0, i = 0;
-
- if (gpio_conf->cam_gpio_tbl == NULL || gpio_conf->cam_gpiomux_conf_tbl
- == NULL) {
- pr_err("%s: Invalid NULL cam gpio config table\n", __func__);
- return -EFAULT;
- }
-
- if (gpio_en) {
- msm_gpiomux_install((struct msm_gpiomux_config *)gpio_conf->
- cam_gpiomux_conf_tbl,
- gpio_conf->cam_gpiomux_conf_tbl_size);
- for (i = 0; i < gpio_conf->cam_gpio_tbl_size; i++) {
- rc = gpio_request(gpio_conf->cam_gpio_tbl[i],
- "CAM_GPIO");
- if (rc < 0) {
- pr_err("%s not able to get gpio\n", __func__);
- for (i--; i >= 0; i--)
- gpio_free(gpio_conf->cam_gpio_tbl[i]);
- break;
- }
- }
- } else {
- for (i = 0; i < gpio_conf->cam_gpio_tbl_size; i++)
- gpio_free(gpio_conf->cam_gpio_tbl[i]);
- }
- return rc;
-}
-
int32_t msm_camio_3d_enable(const struct msm_camera_sensor_info *s_info)
{
int32_t val = 0, rc = 0;
@@ -557,61 +290,6 @@
release_mem_region(s3drw_mem->start, resource_size(s3drw_mem));
}
-static struct pm8xxx_mpp_config_data privacy_light_on_config = {
- .type = PM8XXX_MPP_TYPE_SINK,
- .level = PM8XXX_MPP_CS_OUT_5MA,
- .control = PM8XXX_MPP_CS_CTRL_MPP_LOW_EN,
-};
-
-static struct pm8xxx_mpp_config_data privacy_light_off_config = {
- .type = PM8XXX_MPP_TYPE_SINK,
- .level = PM8XXX_MPP_CS_OUT_5MA,
- .control = PM8XXX_MPP_CS_CTRL_DISABLE,
-};
-
-static struct msm_cam_clk_info cam_clk_info[] = {
- {"cam_clk", 24000000},
-};
-
-int msm_sensor_probe_on(struct device *dev)
-{
- int rc = 0;
- struct msm_camera_sensor_info *sinfo = dev->platform_data;
- struct msm_camera_device_platform_data *camdev = sinfo->pdata;
- camio_clk = camdev->ioclk;
-
- rc = config_gpio_table(sinfo, 1);
- if (rc < 0)
- return rc;
- msm_camera_vreg_enable(dev);
- if (sinfo->sensor_platform_info->privacy_light) {
- struct msm8960_privacy_light_cfg *privacy_light_config =
- sinfo->sensor_platform_info->privacy_light_info;
- pm8xxx_mpp_config(privacy_light_config->mpp,
- &privacy_light_on_config);
- }
- return msm_cam_clk_enable(dev, cam_clk_info,
- &camio_cam_clk, ARRAY_SIZE(cam_clk_info), 1);
-}
-
-int msm_sensor_probe_off(struct device *dev)
-{
- int rc = 0;
- struct msm_camera_sensor_info *sinfo = dev->platform_data;
- if (sinfo->sensor_platform_info->privacy_light) {
- struct msm8960_privacy_light_cfg *privacy_light_config =
- sinfo->sensor_platform_info->privacy_light_info;
- pm8xxx_mpp_config(privacy_light_config->mpp,
- &privacy_light_off_config);
- }
- msm_camera_vreg_disable();
- rc = config_gpio_table(sinfo, 0);
- if (rc < 0)
- return rc;
- return msm_cam_clk_enable(dev, cam_clk_info,
- &camio_cam_clk, ARRAY_SIZE(cam_clk_info), 0);
-}
-
void msm_camio_mode_config(enum msm_cam_mode mode)
{
uint32_t val;
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 6a9d7c4..6b3aef7 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -83,9 +83,64 @@
return 0;
}
+int msm_isp_vfe_msg_to_img_mode(struct msm_cam_media_controller *pmctl,
+ int vfe_msg)
+{
+ int image_mode;
+ if (vfe_msg == VFE_MSG_OUTPUT_PRIMARY) {
+ switch (pmctl->vfe_output_mode) {
+ case VFE_OUTPUTS_MAIN_AND_PREVIEW:
+ case VFE_OUTPUTS_MAIN_AND_VIDEO:
+ case VFE_OUTPUTS_MAIN_AND_THUMB:
+ case VFE_OUTPUTS_RAW:
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+ break;
+ case VFE_OUTPUTS_THUMB_AND_MAIN:
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
+ break;
+ case VFE_OUTPUTS_VIDEO:
+ case VFE_OUTPUTS_VIDEO_AND_PREVIEW:
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
+ break;
+ case VFE_OUTPUTS_PREVIEW:
+ case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+ break;
+ default:
+ image_mode = -1;
+ break;
+ }
+ } else if (vfe_msg == VFE_MSG_OUTPUT_SECONDARY) {
+ switch (pmctl->vfe_output_mode) {
+ case VFE_OUTPUTS_MAIN_AND_PREVIEW:
+ case VFE_OUTPUTS_VIDEO_AND_PREVIEW:
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+ break;
+ case VFE_OUTPUTS_MAIN_AND_VIDEO:
+ case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
+ break;
+ case VFE_OUTPUTS_MAIN_AND_THUMB:
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
+ break;
+ case VFE_OUTPUTS_THUMB_AND_MAIN:
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+ break;
+ default:
+ image_mode = -1;
+ break;
+ }
+ } else
+ image_mode = -1;
+
+ D("%s Selected image mode %d vfe output mode %d, vfe msg %d\n",
+ __func__, image_mode, pmctl->vfe_output_mode, vfe_msg);
+ return image_mode;
+}
+
static int msm_isp_notify_VFE_BUF_EVT(struct v4l2_subdev *sd, void *arg)
{
- int rc = -EINVAL;
+ int rc = -EINVAL, image_mode;
struct msm_vfe_resp *vdata = (struct msm_vfe_resp *)arg;
struct msm_free_buf free_buf;
struct msm_camvfe_params vfe_params;
@@ -100,19 +155,24 @@
msm_isp_sync_free(vdata);
return rc;
}
+ /* Convert the vfe msg to the image mode */
+ image_mode = msm_isp_vfe_msg_to_img_mode(&pcam->mctl, vfe_id);
+ BUG_ON(image_mode < 0);
switch (vdata->type) {
case VFE_MSG_V32_START:
case VFE_MSG_V32_START_RECORDING:
case VFE_MSG_V2X_PREVIEW:
D("%s Got V32_START_*: Getting ping addr id = %d",
__func__, vfe_id);
- msm_mctl_reserve_free_buf(&pcam->mctl, vfe_id, &free_buf);
+ msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
+ image_mode, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
cfgcmd.value = &vfe_id;
vfe_params.vfe_cfg = &cfgcmd;
vfe_params.data = (void *)&free_buf;
rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
- msm_mctl_reserve_free_buf(&pcam->mctl, vfe_id, &free_buf);
+ msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
+ image_mode, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
cfgcmd.value = &vfe_id;
vfe_params.vfe_cfg = &cfgcmd;
@@ -123,7 +183,8 @@
case VFE_MSG_V2X_CAPTURE:
pr_err("%s Got V32_CAPTURE: getting buffer for id = %d",
__func__, vfe_id);
- msm_mctl_reserve_free_buf(&pcam->mctl, vfe_id, &free_buf);
+ msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
+ image_mode, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
cfgcmd.value = &vfe_id;
vfe_params.vfe_cfg = &cfgcmd;
@@ -139,7 +200,8 @@
case VFE_MSG_OUTPUT_IRQ:
D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
__func__, vfe_id);
- msm_mctl_reserve_free_buf(&pcam->mctl, vfe_id, &free_buf);
+ msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
+ image_mode, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_FREE_BUF_ADDR;
cfgcmd.value = &vfe_id;
vfe_params.vfe_cfg = &cfgcmd;
@@ -219,6 +281,12 @@
case MSG_ID_OUTPUT_S:
msgid = VFE_MSG_OUTPUT_S;
break;
+ case MSG_ID_OUTPUT_PRIMARY:
+ msgid = VFE_MSG_OUTPUT_PRIMARY;
+ break;
+ case MSG_ID_OUTPUT_SECONDARY:
+ msgid = VFE_MSG_OUTPUT_SECONDARY;
+ break;
default:
pr_err("%s: Invalid VFE output id: %d\n",
__func__, isp_output->output_id);
@@ -232,6 +300,8 @@
isp_event->isp_data.isp_msg.frame_id =
isp_output->frameCounter;
buf = isp_output->buf;
+ msgid = msm_isp_vfe_msg_to_img_mode(pmctl, msgid);
+ BUG_ON(msgid < 0);
msm_mctl_buf_done(pmctl, msgid,
&buf, isp_output->frameCounter);
}
@@ -561,6 +631,11 @@
case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
case CMD_AXI_CFG_ZSL_ALL_CHNLS:
case CMD_RAW_PICT_AXI_CFG:
+ case CMD_AXI_CFG_PRIM:
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS:
+ case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC:
+ case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS:
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC:
/* Dont need to pass buffer information.
* subdev will get the buffer from media
* controller free queue.
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index e76b1d2..2c4fbe4 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -277,6 +277,21 @@
return rc;
}
+static int msm_mctl_set_vfe_output_mode(struct msm_cam_media_controller
+ *p_mctl, void __user *arg)
+{
+ int rc = 0;
+ if (copy_from_user(&p_mctl->vfe_output_mode,
+ (void __user *)arg, sizeof(p_mctl->vfe_output_mode))) {
+ pr_err("%s Copy from user failed ", __func__);
+ rc = -EFAULT;
+ } else {
+ pr_info("%s: mctl=0x%p, vfe output mode =0x%x",
+ __func__, p_mctl, p_mctl->vfe_output_mode);
+ }
+ return rc;
+}
+
/* called by the server or the config nodes to handle user space
commands*/
static int msm_mctl_cmd(struct msm_cam_media_controller *p_mctl,
@@ -409,6 +424,14 @@
rc = msm_mctl_pp_release_free_frame(p_mctl,
(void __user *)arg);
break;
+ case MSM_CAM_IOCTL_SET_VFE_OUTPUT_TYPE:
+ rc = msm_mctl_set_vfe_output_mode(p_mctl,
+ (void __user *)arg);
+ break;
+ case MSM_CAM_IOCTL_MCTL_DIVERT_DONE:
+ rc = msm_mctl_pp_mctl_divert_done(p_mctl,
+ (void __user *)arg);
+ break;
/* ISFIF config*/
default:
/* ISP config*/
@@ -778,6 +801,7 @@
/* init mctl buf */
msm_mctl_buf_init(pcam);
memset(&pmctl->pp_info, 0, sizeof(pmctl->pp_info));
+ pmctl->vfe_output_mode = 0;
spin_lock_init(&pmctl->pp_info.lock);
/* init sub device*/
v4l2_subdev_init(&(pmctl->mctl_sdev), &mctl_subdev_ops);
@@ -785,3 +809,778 @@
return 0;
}
+
+
+/* mctl node v4l2_file_operations */
+static int msm_mctl_dev_open(struct file *f)
+{
+ int rc = -EINVAL, i;
+ /* get the video device */
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ D("%s : E ", __func__);
+
+ if (!pcam) {
+ pr_err("%s NULL pointer passed in!\n", __func__);
+ return rc;
+ }
+
+ mutex_lock(&pcam->mctl_node.dev_lock);
+ for (i = 0; i < MSM_DEV_INST_MAX; i++) {
+ if (pcam->mctl_node.dev_inst[i] == NULL)
+ break;
+ }
+ /* if no instance is available, return error */
+ if (i == MSM_DEV_INST_MAX) {
+ mutex_unlock(&pcam->mctl_node.dev_lock);
+ return rc;
+ }
+ pcam_inst = kzalloc(sizeof(struct msm_cam_v4l2_dev_inst), GFP_KERNEL);
+ if (!pcam_inst) {
+ mutex_unlock(&pcam->mctl_node.dev_lock);
+ return rc;
+ }
+
+ pcam_inst->sensor_pxlcode = pcam->usr_fmts[0].pxlcode;
+ pcam_inst->my_index = i;
+ pcam_inst->pcam = pcam;
+ pcam->mctl_node.dev_inst[i] = pcam_inst;
+
+ D("%s pcam_inst %p my_index = %d\n", __func__,
+ pcam_inst, pcam_inst->my_index);
+ D("%s for %s\n", __func__, pcam->pdev->name);
+ rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
+ pcam->mctl_node.pvdev);
+ if (rc < 0) {
+ mutex_unlock(&pcam->mctl_node.dev_lock);
+ return rc;
+ }
+ pcam_inst->vbqueue_initialized = 0;
+
+ f->private_data = &pcam_inst->eventHandle;
+
+ D("f->private_data = 0x%x, pcam = 0x%x\n",
+ (u32)f->private_data, (u32)pcam_inst);
+
+ mutex_unlock(&pcam->mctl_node.dev_lock);
+ D("%s : X ", __func__);
+ return rc;
+}
+
+static unsigned int msm_mctl_dev_poll(struct file *f,
+ struct poll_table_struct *wait)
+{
+ int rc = 0;
+ struct msm_cam_v4l2_device *pcam;
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+ pcam = pcam_inst->pcam;
+
+ D("%s : E pcam_inst = %p", __func__, pcam_inst);
+ if (!pcam) {
+ pr_err("%s NULL pointer of camera device!\n", __func__);
+ return -EINVAL;
+ }
+
+ poll_wait(f, &(pcam_inst->eventHandle.events->wait), wait);
+ if (v4l2_event_pending(&pcam_inst->eventHandle)) {
+ rc |= POLLPRI;
+ D("%s Event available on mctl node ", __func__);
+ }
+
+ D("%s poll on vb2\n", __func__);
+ if (!pcam_inst->vid_bufq.streaming) {
+ D("%s vid_bufq.streaming is off, inst=0x%x\n",
+ __func__, (u32)pcam_inst);
+ return rc;
+ }
+ rc |= vb2_poll(&pcam_inst->vid_bufq, f, wait);
+
+ D("%s : X ", __func__);
+ return rc;
+}
+
+static int msm_mctl_dev_close(struct file *f)
+{
+ int rc = 0;
+ struct msm_cam_v4l2_device *pcam;
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+ pcam = pcam_inst->pcam;
+
+ D("%s : E ", __func__);
+ if (!pcam) {
+ pr_err("%s NULL pointer of camera device!\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&pcam->mctl_node.dev_lock);
+ pcam_inst->streamon = 0;
+ pcam->mctl_node.dev_inst_map[pcam_inst->image_mode] = NULL;
+ if (pcam_inst->vbqueue_initialized)
+ vb2_queue_release(&pcam_inst->vid_bufq);
+ D("%s Closing down instance %p ", __func__, pcam_inst);
+ pcam->mctl_node.dev_inst[pcam_inst->my_index] = NULL;
+ v4l2_fh_del(&pcam_inst->eventHandle);
+ v4l2_fh_exit(&pcam_inst->eventHandle);
+
+ kfree(pcam_inst);
+ f->private_data = NULL;
+ mutex_unlock(&pcam->mctl_node.dev_lock);
+ D("%s : X ", __func__);
+ return rc;
+}
+
+static struct v4l2_file_operations g_msm_mctl_fops = {
+ .owner = THIS_MODULE,
+ .open = msm_mctl_dev_open,
+ .poll = msm_mctl_dev_poll,
+ .release = msm_mctl_dev_close,
+ .unlocked_ioctl = video_ioctl2,
+};
+
+/*
+ *
+ * implementation of mctl node v4l2_ioctl_ops
+ *
+ */
+static int msm_mctl_v4l2_querycap(struct file *f, void *pctx,
+ struct v4l2_capability *pcaps)
+{
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ strlcpy(pcaps->driver, pcam->pdev->name, sizeof(pcaps->driver));
+ pcaps->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ return 0;
+}
+
+static int msm_mctl_v4l2_queryctrl(struct file *f, void *pctx,
+ struct v4l2_queryctrl *pqctrl)
+{
+ int rc = 0;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_g_ctrl(struct file *f, void *pctx,
+ struct v4l2_control *c)
+{
+ int rc = 0;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_s_ctrl(struct file *f, void *pctx,
+ struct v4l2_control *ctrl)
+{
+ int rc = 0;
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s\n", __func__);
+
+ WARN_ON(pctx != f->private_data);
+ mutex_lock(&pcam->mctl_node.dev_lock);
+ if (ctrl->id == MSM_V4L2_PID_PP_PLANE_INFO) {
+ if (copy_from_user(&pcam_inst->plane_info,
+ (void *)ctrl->value,
+ sizeof(struct img_plane_info))) {
+ pr_err("%s inst %p Copying plane_info failed ",
+ __func__, pcam_inst);
+ rc = -EFAULT;
+ }
+ D("%s inst %p got plane info: num_planes = %d,"
+ "plane size = %ld %ld ", __func__, pcam_inst,
+ pcam_inst->plane_info.num_planes,
+ pcam_inst->plane_info.plane[0].size,
+ pcam_inst->plane_info.plane[1].size);
+ } else
+ pr_err("%s Unsupported S_CTRL Value ", __func__);
+
+ mutex_unlock(&pcam->mctl_node.dev_lock);
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_reqbufs(struct file *f, void *pctx,
+ struct v4l2_requestbuffers *pb)
+{
+ int rc = 0, i, j;
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+ rc = vb2_reqbufs(&pcam_inst->vid_bufq, pb);
+ if (rc < 0) {
+ pr_err("%s reqbufs failed %d ", __func__, rc);
+ return rc;
+ }
+ if (!pb->count) {
+ /* Deallocation. free buf_offset array */
+ D("%s Inst %p freeing buffer offsets array",
+ __func__, pcam_inst);
+ for (j = 0 ; j < pcam_inst->buf_count ; j++)
+ kfree(pcam_inst->buf_offset[j]);
+ kfree(pcam_inst->buf_offset);
+ pcam_inst->buf_offset = NULL;
+ /* If the userspace has deallocated all the
+ * buffers, then release the vb2 queue */
+ if (pcam_inst->vbqueue_initialized) {
+ vb2_queue_release(&pcam_inst->vid_bufq);
+ pcam_inst->vbqueue_initialized = 0;
+ }
+ } else {
+ D("%s Inst %p Allocating buf_offset array",
+ __func__, pcam_inst);
+ /* Allocation. allocate buf_offset array */
+ pcam_inst->buf_offset = (struct msm_cam_buf_offset **)
+ kzalloc(pb->count * sizeof(struct msm_cam_buf_offset *),
+ GFP_KERNEL);
+ if (!pcam_inst->buf_offset) {
+ pr_err("%s out of memory ", __func__);
+ return -ENOMEM;
+ }
+ for (i = 0; i < pb->count; i++) {
+ pcam_inst->buf_offset[i] =
+ kzalloc(sizeof(struct msm_cam_buf_offset) *
+ pcam_inst->plane_info.num_planes, GFP_KERNEL);
+ if (!pcam_inst->buf_offset[i]) {
+ pr_err("%s out of memory ", __func__);
+ for (j = i-1 ; j >= 0; j--)
+ kfree(pcam_inst->buf_offset[j]);
+ kfree(pcam_inst->buf_offset);
+ pcam_inst->buf_offset = NULL;
+ return -ENOMEM;
+ }
+ }
+ }
+ pcam_inst->buf_count = pb->count;
+ D("%s inst %p, buf count %d ", __func__,
+ pcam_inst, pcam_inst->buf_count);
+ return rc;
+}
+
+static int msm_mctl_v4l2_querybuf(struct file *f, void *pctx,
+ struct v4l2_buffer *pb)
+{
+ /* get the video device */
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+ return vb2_querybuf(&pcam_inst->vid_bufq, pb);
+}
+
+static int msm_mctl_v4l2_qbuf(struct file *f, void *pctx,
+ struct v4l2_buffer *pb)
+{
+ int rc = 0, i = 0;
+ /* get the camera device */
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s Inst = %p\n", __func__, pcam_inst);
+ WARN_ON(pctx != f->private_data);
+
+ if (!pcam_inst->buf_offset) {
+ pr_err("%s Buffer is already released. Returning. ", __func__);
+ return -EINVAL;
+ }
+
+ if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ /* Reject the buffer if planes array was not allocated */
+ if (pb->m.planes == NULL) {
+ pr_err("%s Planes array is null ", __func__);
+ return -EINVAL;
+ }
+ for (i = 0; i < pcam_inst->plane_info.num_planes; i++) {
+ D("%s stored offsets for plane %d as"
+ "addr offset %d, data offset %d",
+ __func__, i, pb->m.planes[i].reserved[0],
+ pb->m.planes[i].data_offset);
+ pcam_inst->buf_offset[pb->index][i].data_offset =
+ pb->m.planes[i].data_offset;
+ pcam_inst->buf_offset[pb->index][i].addr_offset =
+ pb->m.planes[i].reserved[0];
+ }
+ } else {
+ D("%s stored reserved info %d", __func__, pb->reserved);
+ pcam_inst->buf_offset[pb->index][0].addr_offset = pb->reserved;
+ }
+
+ rc = vb2_qbuf(&pcam_inst->vid_bufq, pb);
+ D("%s, videobuf_qbuf returns %d\n", __func__, rc);
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_dqbuf(struct file *f, void *pctx,
+ struct v4l2_buffer *pb)
+{
+ int rc = 0;
+ /* get the camera device */
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ rc = vb2_dqbuf(&pcam_inst->vid_bufq, pb, f->f_flags & O_NONBLOCK);
+ D("%s, videobuf_dqbuf returns %d\n", __func__, rc);
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_streamon(struct file *f, void *pctx,
+ enum v4l2_buf_type buf_type)
+{
+ int rc = 0;
+ /* get the camera device */
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s Inst %p\n", __func__, pcam_inst);
+ WARN_ON(pctx != f->private_data);
+
+ if ((buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+ pr_err("%s Invalid buffer type ", __func__);
+ return -EINVAL;
+ }
+
+ D("%s Calling videobuf_streamon", __func__);
+ /* if HW streaming on is successful, start buffer streaming */
+ rc = vb2_streamon(&pcam_inst->vid_bufq, buf_type);
+ D("%s, videobuf_streamon returns %d\n", __func__, rc);
+
+ mutex_lock(&pcam->mctl_node.dev_lock);
+ /* turn HW (VFE/sensor) streaming */
+ pcam_inst->streamon = 1;
+ mutex_unlock(&pcam->mctl_node.dev_lock);
+ D("%s rc = %d\n", __func__, rc);
+ return rc;
+}
+
+static int msm_mctl_v4l2_streamoff(struct file *f, void *pctx,
+ enum v4l2_buf_type buf_type)
+{
+ int rc = 0;
+ /* get the camera device */
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s Inst %p\n", __func__, pcam_inst);
+ WARN_ON(pctx != f->private_data);
+
+ if ((buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+ pr_err("%s Invalid buffer type ", __func__);
+ return -EINVAL;
+ }
+
+ /* first turn of HW (VFE/sensor) streaming so that buffers are
+ not in use when we free the buffers */
+ mutex_lock(&pcam->mctl_node.dev_lock);
+ pcam_inst->streamon = 0;
+ mutex_unlock(&pcam->mctl_node.dev_lock);
+ if (rc < 0)
+ pr_err("%s: hw failed to stop streaming\n", __func__);
+
+ /* stop buffer streaming */
+ rc = vb2_streamoff(&pcam_inst->vid_bufq, buf_type);
+ D("%s, videobuf_streamoff returns %d\n", __func__, rc);
+ return rc;
+}
+
+static int msm_mctl_v4l2_enum_fmt_cap(struct file *f, void *pctx,
+ struct v4l2_fmtdesc *pfmtdesc)
+{
+ /* get the video device */
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ const struct msm_isp_color_fmt *isp_fmt;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+ if ((pfmtdesc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ (pfmtdesc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
+ return -EINVAL;
+
+ if (pfmtdesc->index >= pcam->num_fmts)
+ return -EINVAL;
+
+ isp_fmt = &pcam->usr_fmts[pfmtdesc->index];
+
+ if (isp_fmt->name)
+ strlcpy(pfmtdesc->description, isp_fmt->name,
+ sizeof(pfmtdesc->description));
+
+ pfmtdesc->pixelformat = isp_fmt->fourcc;
+
+ D("%s: [%d] 0x%x, %s\n", __func__, pfmtdesc->index,
+ isp_fmt->fourcc, isp_fmt->name);
+ return 0;
+}
+
+static int msm_mctl_v4l2_g_fmt_cap(struct file *f,
+ void *pctx, struct v4l2_format *pfmt)
+{
+ int rc = 0;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_g_fmt_cap_mplane(struct file *f,
+ void *pctx, struct v4l2_format *pfmt)
+{
+ int rc = 0;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ return -EINVAL;
+
+ return rc;
+}
+
+/* This function will readjust the format parameters based in HW
+ capabilities. Called by s_fmt_cap
+*/
+static int msm_mctl_v4l2_try_fmt_cap(struct file *f, void *pctx,
+ struct v4l2_format *pfmt)
+{
+ int rc = 0;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_try_fmt_cap_mplane(struct file *f, void *pctx,
+ struct v4l2_format *pfmt)
+{
+ int rc = 0;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ return rc;
+}
+
+/* This function will reconfig the v4l2 driver and HW device, it should be
+ called after the streaming is stopped.
+*/
+static int msm_mctl_v4l2_s_fmt_cap(struct file *f, void *pctx,
+ struct v4l2_format *pfmt)
+{
+ int rc = 0;
+ /* get the video device */
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s\n", __func__);
+ D("%s, inst=0x%x,idx=%d,priv = 0x%p\n",
+ __func__, (u32)pcam_inst, pcam_inst->my_index,
+ (void *)pfmt->fmt.pix.priv);
+ WARN_ON(pctx != f->private_data);
+
+ if (!pcam_inst->vbqueue_initialized) {
+ pcam->mctl.mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ pcam_inst->vbqueue_initialized = 1;
+ }
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_s_fmt_cap_mplane(struct file *f, void *pctx,
+ struct v4l2_format *pfmt)
+{
+ int rc = 0, i;
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s Inst %p vbqueue %d\n", __func__,
+ pcam_inst, pcam_inst->vbqueue_initialized);
+ WARN_ON(pctx != f->private_data);
+
+ if (!pcam_inst->vbqueue_initialized) {
+ pcam->mctl.mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ pcam_inst->vbqueue_initialized = 1;
+ }
+ for (i = 0; i < pcam->num_fmts; i++)
+ if (pcam->usr_fmts[i].fourcc == pfmt->fmt.pix_mp.pixelformat)
+ break;
+ if (i == pcam->num_fmts) {
+ pr_err("%s: User requested pixelformat %x not supported\n",
+ __func__, pfmt->fmt.pix_mp.pixelformat);
+ return -EINVAL;
+ }
+ pcam_inst->vid_fmt = *pfmt;
+ pcam_inst->sensor_pxlcode =
+ pcam->usr_fmts[i].pxlcode;
+ D("%s: inst=%p, width=%d, heigth=%d\n",
+ __func__, pcam_inst,
+ pcam_inst->vid_fmt.fmt.pix_mp.width,
+ pcam_inst->vid_fmt.fmt.pix_mp.height);
+ return rc;
+}
+static int msm_mctl_v4l2_g_jpegcomp(struct file *f, void *pctx,
+ struct v4l2_jpegcompression *pcomp)
+{
+ int rc = -EINVAL;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_s_jpegcomp(struct file *f, void *pctx,
+ struct v4l2_jpegcompression *pcomp)
+{
+ int rc = -EINVAL;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ return rc;
+}
+
+
+static int msm_mctl_v4l2_g_crop(struct file *f, void *pctx,
+ struct v4l2_crop *crop)
+{
+ int rc = -EINVAL;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ return rc;
+}
+
+static int msm_mctl_v4l2_s_crop(struct file *f, void *pctx,
+ struct v4l2_crop *a)
+{
+ int rc = -EINVAL;
+
+ D("%s\n", __func__);
+ WARN_ON(pctx != f->private_data);
+
+ return rc;
+}
+
+/* Stream type-dependent parameter ioctls */
+static int msm_mctl_v4l2_g_parm(struct file *f, void *pctx,
+ struct v4l2_streamparm *a)
+{
+ int rc = -EINVAL;
+ return rc;
+}
+
+static int msm_mctl_vidbuf_get_path(u32 extendedmode)
+{
+ switch (extendedmode) {
+ case MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL:
+ return OUTPUT_TYPE_T;
+ case MSM_V4L2_EXT_CAPTURE_MODE_MAIN:
+ return OUTPUT_TYPE_S;
+ case MSM_V4L2_EXT_CAPTURE_MODE_VIDEO:
+ return OUTPUT_TYPE_V;
+ case MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT:
+ case MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW:
+ default:
+ return OUTPUT_TYPE_P;
+ }
+}
+
+static int msm_mctl_v4l2_s_parm(struct file *f, void *pctx,
+ struct v4l2_streamparm *a)
+{
+ int rc = 0;
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+ pcam_inst->image_mode = a->parm.capture.extendedmode;
+ pcam_inst->pcam->mctl_node.dev_inst_map[pcam_inst->image_mode] =
+ pcam_inst;
+ pcam_inst->path = msm_mctl_vidbuf_get_path(pcam_inst->image_mode);
+ D("%s path=%d, image mode = %d rc=%d\n", __func__,
+ pcam_inst->path, pcam_inst->image_mode, rc);
+ return rc;
+}
+
+static int msm_mctl_v4l2_subscribe_event(struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ int rc = 0;
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst =
+ (struct msm_cam_v4l2_dev_inst *)container_of(fh,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s:fh = 0x%x, type = 0x%x\n", __func__, (u32)fh, sub->type);
+
+ if (sub->type == V4L2_EVENT_ALL)
+ sub->type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_EVENT;
+ rc = v4l2_event_subscribe(fh, sub);
+ if (rc < 0)
+ pr_err("%s: failed for evtType = 0x%x, rc = %d\n",
+ __func__, sub->type, rc);
+ return rc;
+}
+
+static int msm_mctl_v4l2_unsubscribe_event(struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ int rc = 0;
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst =
+ (struct msm_cam_v4l2_dev_inst *)container_of(fh,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ D("%s: fh = 0x%x\n", __func__, (u32)fh);
+
+ rc = v4l2_event_unsubscribe(fh, sub);
+ D("%s: rc = %d\n", __func__, rc);
+ return rc;
+}
+
+/* mctl node v4l2_ioctl_ops */
+static const struct v4l2_ioctl_ops g_msm_mctl_ioctl_ops = {
+ .vidioc_querycap = msm_mctl_v4l2_querycap,
+
+ .vidioc_s_crop = msm_mctl_v4l2_s_crop,
+ .vidioc_g_crop = msm_mctl_v4l2_g_crop,
+
+ .vidioc_queryctrl = msm_mctl_v4l2_queryctrl,
+ .vidioc_g_ctrl = msm_mctl_v4l2_g_ctrl,
+ .vidioc_s_ctrl = msm_mctl_v4l2_s_ctrl,
+
+ .vidioc_reqbufs = msm_mctl_v4l2_reqbufs,
+ .vidioc_querybuf = msm_mctl_v4l2_querybuf,
+ .vidioc_qbuf = msm_mctl_v4l2_qbuf,
+ .vidioc_dqbuf = msm_mctl_v4l2_dqbuf,
+
+ .vidioc_streamon = msm_mctl_v4l2_streamon,
+ .vidioc_streamoff = msm_mctl_v4l2_streamoff,
+
+ /* format ioctls */
+ .vidioc_enum_fmt_vid_cap = msm_mctl_v4l2_enum_fmt_cap,
+ .vidioc_enum_fmt_vid_cap_mplane = msm_mctl_v4l2_enum_fmt_cap,
+ .vidioc_try_fmt_vid_cap = msm_mctl_v4l2_try_fmt_cap,
+ .vidioc_try_fmt_vid_cap_mplane = msm_mctl_v4l2_try_fmt_cap_mplane,
+ .vidioc_g_fmt_vid_cap = msm_mctl_v4l2_g_fmt_cap,
+ .vidioc_g_fmt_vid_cap_mplane = msm_mctl_v4l2_g_fmt_cap_mplane,
+ .vidioc_s_fmt_vid_cap = msm_mctl_v4l2_s_fmt_cap,
+ .vidioc_s_fmt_vid_cap_mplane = msm_mctl_v4l2_s_fmt_cap_mplane,
+
+ .vidioc_g_jpegcomp = msm_mctl_v4l2_g_jpegcomp,
+ .vidioc_s_jpegcomp = msm_mctl_v4l2_s_jpegcomp,
+
+ /* Stream type-dependent parameter ioctls */
+ .vidioc_g_parm = msm_mctl_v4l2_g_parm,
+ .vidioc_s_parm = msm_mctl_v4l2_s_parm,
+
+ /* event subscribe/unsubscribe */
+ .vidioc_subscribe_event = msm_mctl_v4l2_subscribe_event,
+ .vidioc_unsubscribe_event = msm_mctl_v4l2_unsubscribe_event,
+};
+
+int msm_setup_mctl_node(struct msm_cam_v4l2_device *pcam)
+{
+ int rc = -EINVAL;
+ struct video_device *pvdev = NULL;
+ struct i2c_client *client = v4l2_get_subdevdata(pcam->mctl.sensor_sdev);
+
+ D("%s\n", __func__);
+
+ /* first register the v4l2 device */
+ pcam->mctl_node.v4l2_dev.dev = &client->dev;
+ rc = v4l2_device_register(pcam->mctl_node.v4l2_dev.dev,
+ &pcam->mctl_node.v4l2_dev);
+ if (rc < 0)
+ return -EINVAL;
+ /* else
+ pcam->v4l2_dev.notify = msm_cam_v4l2_subdev_notify; */
+
+ /* now setup video device */
+ pvdev = video_device_alloc();
+ if (pvdev == NULL) {
+ pr_err("%s: video_device_alloc failed\n", __func__);
+ return rc;
+ }
+
+ /* init video device's driver interface */
+ D("sensor name = %s, sizeof(pvdev->name)=%d\n",
+ pcam->mctl.sensor_sdev->name, sizeof(pvdev->name));
+
+ /* device info - strlcpy is safer than strncpy but
+ only if architecture supports*/
+ strlcpy(pvdev->name, pcam->mctl.sensor_sdev->name,
+ sizeof(pvdev->name));
+
+ pvdev->release = video_device_release;
+ pvdev->fops = &g_msm_mctl_fops;
+ pvdev->ioctl_ops = &g_msm_mctl_ioctl_ops;
+ pvdev->minor = -1;
+ pvdev->vfl_type = 1;
+
+ /* register v4l2 video device to kernel as /dev/videoXX */
+ D("%s video_register_device\n", __func__);
+ rc = video_register_device(pvdev,
+ VFL_TYPE_GRABBER,
+ -1);
+ if (rc) {
+ pr_err("%s: video_register_device failed\n", __func__);
+ goto reg_fail;
+ }
+ D("%s: video device registered as /dev/video%d\n",
+ __func__, pvdev->num);
+
+ /* connect pcam and mctl video dev to each other */
+ pcam->mctl_node.pvdev = pvdev;
+ video_set_drvdata(pcam->mctl_node.pvdev, pcam);
+
+ return rc ;
+
+reg_fail:
+ video_device_release(pvdev);
+ v4l2_device_unregister(&pcam->mctl_node.v4l2_dev);
+ pcam->mctl_node.v4l2_dev.dev = NULL;
+ return rc;
+}
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 7a0cc02..1ab76fe 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -186,6 +186,8 @@
buf->state = MSM_BUFFER_STATE_DEQUEUED;
D("%s: inst=0x%x, buf=0x, %x, idx=%d\n", __func__,
(uint32_t)pcam_inst, (uint32_t)buf, vb->v4l2_buf.index);
+ D("%s: inst=%p, buf=%x, idx=%d\n", __func__,
+ pcam_inst, (uint32_t)buf, vb->v4l2_buf.index);
return 0;
}
@@ -260,12 +262,6 @@
static int msm_vb2_ops_stop_streaming(struct vb2_queue *q)
{
- int rc = 0;
- struct msm_free_buf *free_buf = NULL;
- struct msm_cam_v4l2_dev_inst *pcam_inst = vb2_get_drv_priv(q);
- if (rc != 0)
- msm_mctl_release_free_buf(&pcam_inst->pcam->mctl,
- pcam_inst->path, free_buf);
return 0;
}
@@ -286,6 +282,8 @@
D("%s pcam_inst=%p,(vb=0x%p),idx=%d,len=%d\n",
__func__, pcam_inst,
vb, vb->v4l2_buf.index, vb->v4l2_buf.length);
+ D("%s pcam_inst=%p, idx=%d\n", __func__, pcam_inst,
+ vb->v4l2_buf.index);
buf = container_of(vb, struct msm_frame_buffer, vidbuf);
spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
/* we are returning a buffer to the queue */
@@ -326,29 +324,13 @@
return 0;
}
-int msm_mctl_out_type_to_inst_index(struct msm_cam_v4l2_device *pcam,
- int out_type)
+int msm_mctl_img_mode_to_inst_index(struct msm_cam_media_controller *pmctl,
+ int image_mode)
{
- int image_mode;
- switch (out_type) {
- case VFE_MSG_OUTPUT_P:
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
- break;
- case VFE_MSG_OUTPUT_V:
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
- break;
- case VFE_MSG_OUTPUT_S:
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
- break;
- case VFE_MSG_OUTPUT_T:
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
- break;
- default:
- image_mode = -1;
- break;
- }
- if ((image_mode >= 0) && pcam->dev_inst_map[image_mode])
- return pcam->dev_inst_map[image_mode]->my_index;
+ if ((image_mode >= 0) &&
+ pmctl->sync.pcam_sync->dev_inst_map[image_mode])
+ return pmctl->sync.pcam_sync->
+ dev_inst_map[image_mode]->my_index;
else
return -EINVAL;
}
@@ -367,7 +349,7 @@
struct msm_frame_buffer *msm_mctl_buf_find(
struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst, int del_buf,
- int msg_type, struct msm_free_buf *fbuf)
+ int image_mode, struct msm_free_buf *fbuf)
{
struct msm_frame_buffer *buf = NULL, *tmp;
uint32_t buf_phyaddr = 0;
@@ -408,14 +390,14 @@
int msm_mctl_buf_done_proc(
struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst,
- int msg_type, struct msm_free_buf *fbuf,
+ int image_mode, struct msm_free_buf *fbuf,
uint32_t *frame_id, int gen_timestamp)
{
struct msm_frame_buffer *buf = NULL;
int del_buf = 1;
buf = msm_mctl_buf_find(pmctl, pcam_inst, del_buf,
- msg_type, fbuf);
+ image_mode, fbuf);
if (!buf) {
pr_err("%s: buf=0x%x not found\n",
__func__, fbuf->ch_paddr[0]);
@@ -431,23 +413,24 @@
return 0;
}
+
int msm_mctl_buf_done(struct msm_cam_media_controller *p_mctl,
- int msg_type, struct msm_free_buf *fbuf,
+ int image_mode, struct msm_free_buf *fbuf,
uint32_t frame_id)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
int idx, rc;
int pp_divert_type = 0, pp_type = 0;
- msm_mctl_check_pp(p_mctl, msg_type, &pp_divert_type, &pp_type);
- D("%s: pp_type=%d, pp_divert_type = %d",
- __func__, pp_type, pp_divert_type);
+ msm_mctl_check_pp(p_mctl, image_mode, &pp_divert_type, &pp_type);
+ D("%s: pp_type=%d, pp_divert_type = %d, frame_id = 0x%x",
+ __func__, pp_type, pp_divert_type, frame_id);
if (pp_type || pp_divert_type)
rc = msm_mctl_do_pp_divert(p_mctl,
- msg_type, fbuf, frame_id, pp_type);
+ image_mode, fbuf, frame_id, pp_type);
else {
- idx = msm_mctl_out_type_to_inst_index(
- p_mctl->sync.pcam_sync, msg_type);
+ idx = msm_mctl_img_mode_to_inst_index(
+ p_mctl, image_mode);
if (idx < 0) {
pr_err("%s Invalid instance, dropping buffer\n",
__func__);
@@ -455,7 +438,7 @@
}
pcam_inst = p_mctl->sync.pcam_sync->dev_inst[idx];
rc = msm_mctl_buf_done_proc(p_mctl, pcam_inst,
- msg_type, fbuf,
+ image_mode, fbuf,
&frame_id, 1);
}
return rc;
@@ -467,15 +450,47 @@
return 0;
}
+struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
+ struct msm_cam_media_controller *pmctl,
+ int image_mode)
+{
+ struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+ struct msm_cam_v4l2_device *pcam = pmctl->sync.pcam_sync;
+ int idx;
+
+ if (image_mode >= 0) {
+ /* Valid image mode. Search the mctl node first.
+ * If mctl node doesnt have the instance, then
+ * search in the user's video node */
+ if (pcam->mctl_node.dev_inst_map[image_mode]) {
+ idx =
+ pcam->mctl_node.dev_inst_map[image_mode]->my_index;
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ D("%s Found instance %p in mctl node device\n",
+ __func__, pcam_inst);
+ } else if (pcam->dev_inst_map[image_mode]) {
+ idx = pcam->dev_inst_map[image_mode]->my_index;
+ pcam_inst = pcam->dev_inst[idx];
+ D("%s Found instance %p in video device",
+ __func__, pcam_inst);
+ }
+ } else
+ pr_err("%s Invalid image mode %d. Return NULL\n",
+ __func__, image_mode);
+
+ return pcam_inst;
+}
+
int msm_mctl_reserve_free_buf(
struct msm_cam_media_controller *pmctl,
- int msg_type, struct msm_free_buf *free_buf)
+ struct msm_cam_v4l2_dev_inst *pref_pcam_inst,
+ int image_mode, struct msm_free_buf *free_buf)
{
- struct msm_cam_v4l2_dev_inst *pcam_inst;
+ struct msm_cam_v4l2_dev_inst *pcam_inst = pref_pcam_inst;
unsigned long flags = 0;
struct videobuf2_contig_pmem *mem;
struct msm_frame_buffer *buf = NULL;
- int rc = -EINVAL, idx, i;
+ int rc = -EINVAL, i;
uint32_t buf_idx, plane_offset = 0;
if (!free_buf || !pmctl) {
@@ -483,13 +498,14 @@
return rc;
}
memset(free_buf, 0, sizeof(struct msm_free_buf));
- idx = msm_mctl_out_type_to_inst_index(pmctl->sync.pcam_sync,
- msg_type);
- if (idx < 0) {
- pr_err("%s Invalid instance, returning\n", __func__);
- return idx;
- }
- pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
+
+ /* If the caller wants to reserve a buffer from a particular
+ * camera instance, he would send the preferred camera instance.
+ * If the preferred camera instance is NULL, get the
+ * camera instance using the image mode passed */
+ if (!pcam_inst)
+ pcam_inst = msm_mctl_get_pcam_inst(pmctl, image_mode);
+
if (!pcam_inst || !pcam_inst->streamon) {
pr_err("%s: stream is turned off\n", __func__);
return rc;
@@ -518,6 +534,7 @@
videobuf2_to_pmem_contig(&buf->vidbuf, i) +
pcam_inst->buf_offset[buf_idx][i].data_offset +
plane_offset;
+
}
} else {
mem = vb2_plane_cookie(&buf->vidbuf, 0);
@@ -529,9 +546,9 @@
}
free_buf->vb = (uint32_t)buf;
buf->state = MSM_BUFFER_STATE_RESERVED;
- D("%s idx=%d,inst=0x%p,idx=%d,paddr=0x%x, "
+ D("%s inst=0x%p, idx=%d, paddr=0x%x, "
"ch1 addr=0x%x\n", __func__,
- idx, pcam_inst, buf->vidbuf.v4l2_buf.index,
+ pcam_inst, buf->vidbuf.v4l2_buf.index,
free_buf->ch_paddr[0], free_buf->ch_paddr[1]);
rc = 0;
break;
@@ -544,23 +561,23 @@
}
int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
- int msg_type, struct msm_free_buf *free_buf)
+ struct msm_cam_v4l2_dev_inst *pcam_inst,
+ int image_mode, struct msm_free_buf *free_buf)
{
- struct msm_cam_v4l2_dev_inst *pcam_inst;
unsigned long flags = 0;
struct msm_frame_buffer *buf = NULL;
uint32_t buf_phyaddr = 0;
- int rc = -EINVAL, idx;
+ int rc = -EINVAL;
if (!free_buf)
return rc;
- idx = msm_mctl_out_type_to_inst_index(pmctl->sync.pcam_sync, msg_type);
- if (idx < 0) {
- pr_err("%s Invalid instance, buffer not released\n", __func__);
- return idx;
+ if (!pcam_inst) {
+ pr_err("%s Invalid instance, buffer not released\n",
+ __func__);
+ return rc;
}
- pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
+
spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
list_for_each_entry(buf, &pcam_inst->free_vq, list) {
buf_phyaddr =
@@ -582,40 +599,46 @@
int msm_mctl_buf_done_pp(
struct msm_cam_media_controller *pmctl,
- int msg_type, struct msm_free_buf *frame, int dirty)
+ int image_mode, struct msm_free_buf *frame, int dirty)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
- int idx, rc = 0;
+ int rc = 0, idx;
- idx = msm_mctl_out_type_to_inst_index(
- pmctl->sync.pcam_sync, msg_type);
+ idx = msm_mctl_img_mode_to_inst_index(pmctl, image_mode);
if (idx < 0) {
- pr_err("%s Invalid instance, buffer dropped\n", __func__);
+ pr_err("%s Invalid instance, buffer not released\n", __func__);
return idx;
}
pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
+ if (!pcam_inst) {
+ pr_err("%s Invalid instance, cannot send buf to user",
+ __func__);
+ return -EINVAL;
+ }
+
D("%s:inst=0x%p, paddr=0x%x, dirty=%d",
__func__, pcam_inst, frame->ch_paddr[0], dirty);
if (dirty)
/* the frame is dirty, not going to disptach to app */
- rc = msm_mctl_release_free_buf(pmctl, msg_type, frame);
+ rc = msm_mctl_release_free_buf(pmctl, pcam_inst,
+ image_mode, frame);
else
rc = msm_mctl_buf_done_proc(pmctl, pcam_inst,
- msg_type, frame, NULL, 0);
+ image_mode, frame, NULL, 0);
return rc;
}
struct msm_frame_buffer *msm_mctl_get_free_buf(
struct msm_cam_media_controller *pmctl,
- int msg_type)
+ int image_mode)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
unsigned long flags = 0;
struct msm_frame_buffer *buf = NULL;
int rc = -EINVAL, idx;
- idx = msm_mctl_out_type_to_inst_index(pmctl->sync.pcam_sync,
- msg_type);
+ idx = msm_mctl_img_mode_to_inst_index(pmctl,
+ image_mode);
if (idx < 0) {
pr_err("%s Invalid instance, cant get buffer\n", __func__);
return NULL;
@@ -646,15 +669,15 @@
int msm_mctl_put_free_buf(
struct msm_cam_media_controller *pmctl,
- int msg_type, struct msm_frame_buffer *my_buf)
+ int image_mode, struct msm_frame_buffer *my_buf)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
unsigned long flags = 0;
int rc = 0, idx;
struct msm_frame_buffer *buf = NULL;
- idx = msm_mctl_out_type_to_inst_index(pmctl->sync.pcam_sync,
- msg_type);
+ idx = msm_mctl_img_mode_to_inst_index(pmctl,
+ image_mode);
if (idx < 0) {
pr_err("%s Invalid instance, cant put buffer\n", __func__);
return idx;
@@ -680,7 +703,7 @@
}
int msm_mctl_buf_del(struct msm_cam_media_controller *pmctl,
- int msg_type,
+ int image_mode,
struct msm_frame_buffer *my_buf)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
@@ -688,8 +711,8 @@
unsigned long flags = 0;
int idx;
- idx = msm_mctl_out_type_to_inst_index(pmctl->sync.pcam_sync,
- msg_type);
+ idx = msm_mctl_img_mode_to_inst_index(pmctl,
+ image_mode);
if (idx < 0) {
pr_err("%s Invalid instance, cant delete buffer\n", __func__);
return idx;
@@ -712,3 +735,43 @@
return -EINVAL;
}
+int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
+ int image_mode, struct msm_frame_buffer *rbuf)
+{
+ int idx = 0;
+ struct msm_frame_buffer *buf = NULL;
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ struct msm_cam_v4l2_device *pcam = pmctl->sync.pcam_sync;
+ unsigned long flags = 0;
+
+ if (pcam->mctl_node.dev_inst_map[image_mode]) {
+ idx = pcam->mctl_node.dev_inst_map[image_mode]->my_index;
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ D("%s Found instance %p in mctl node device\n",
+ __func__, pcam_inst);
+ } else {
+ pr_err("%s Invalid image mode %d ", __func__, image_mode);
+ return -EINVAL;
+ }
+
+ if (!pcam_inst) {
+ pr_err("%s Invalid instance\n", __func__);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
+ if (!list_empty(&pcam_inst->free_vq)) {
+ list_for_each_entry(buf, &pcam_inst->free_vq, list) {
+ if (rbuf == buf) {
+ D("%s Return buffer %x in pcam_inst %p ",
+ __func__, (int)rbuf, pcam_inst);
+ buf->state = MSM_BUFFER_STATE_QUEUED;
+ spin_unlock_irqrestore(&pcam_inst->vq_irqlock,
+ flags);
+ return 0;
+ }
+ }
+ }
+ spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+ return -EINVAL;
+}
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index 6a2c8aa..1593e7e 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -66,39 +66,36 @@
}
int msm_mctl_check_pp(struct msm_cam_media_controller *p_mctl,
- int msg_type, int *pp_divert_type, int *pp_type)
+ int image_mode, int *pp_divert_type, int *pp_type)
{
int rc = 0;
unsigned long flags;
uint32_t pp_key = 0;
- int image_mode = MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT;
*pp_type = 0;
*pp_divert_type = 0;
spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
- switch (msg_type) {
- case VFE_MSG_OUTPUT_P:
+ switch (image_mode) {
+ case MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW:
pp_key = PP_PREV;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
if (p_mctl->pp_info.pp_key & pp_key)
*pp_divert_type = OUTPUT_TYPE_P;
if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_P)
*pp_type = OUTPUT_TYPE_P;
break;
- case VFE_MSG_OUTPUT_S:
+ case MSM_V4L2_EXT_CAPTURE_MODE_MAIN:
pp_key = PP_SNAP;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
if (p_mctl->pp_info.pp_key & pp_key)
*pp_divert_type = OUTPUT_TYPE_S;
if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_S)
*pp_type = OUTPUT_TYPE_P;
break;
- case VFE_MSG_OUTPUT_V:
- if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_V)
+ case MSM_V4L2_EXT_CAPTURE_MODE_VIDEO:
+ if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_V)
*pp_type = OUTPUT_TYPE_V;
break;
- case VFE_MSG_OUTPUT_T:
- if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_T)
+ case MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL:
+ if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_T)
*pp_type = OUTPUT_TYPE_T;
break;
default:
@@ -108,36 +105,37 @@
*pp_divert_type = 0;
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
D("%s: pp_type=%d, pp_divert_type = %d",
- __func__, *pp_type, *pp_divert_type);
+ __func__, *pp_type, *pp_divert_type);
return rc;
}
int msm_mctl_do_pp_divert(
struct msm_cam_media_controller *p_mctl,
- int msg_type, struct msm_free_buf *fbuf,
+ int image_mode, struct msm_free_buf *fbuf,
uint32_t frame_id, int pp_type)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
- int idx, rc = 0, i, buf_idx;
+ int rc = 0, i, buf_idx;
int del_buf = 0; /* delete from free queue */
struct msm_cam_evt_divert_frame div;
struct msm_frame_buffer *vb = NULL;
struct videobuf2_contig_pmem *mem;
- idx = msm_mctl_out_type_to_inst_index(
- p_mctl->sync.pcam_sync, msg_type);
- if (idx < 0) {
- pr_err("%s Invalid instance. returning\n", __func__);
+ pcam_inst = msm_mctl_get_pcam_inst(p_mctl, image_mode);
+ if (!pcam_inst) {
+ pr_err("%s Invalid instance. Cannot divert frame.\n",
+ __func__);
return -EINVAL;
}
- pcam_inst = p_mctl->sync.pcam_sync->dev_inst[idx];
vb = msm_mctl_buf_find(p_mctl, pcam_inst,
- del_buf, msg_type, fbuf);
+ del_buf, image_mode, fbuf);
if (!vb)
return -EINVAL;
vb->vidbuf.v4l2_buf.sequence = frame_id;
buf_idx = vb->vidbuf.v4l2_buf.index;
+ D("%s Diverting frame %d %x Image mode %d\n", __func__, buf_idx,
+ (uint32_t)vb, pcam_inst->image_mode);
div.image_mode = pcam_inst->image_mode;
div.op_mode = pcam_inst->pcam->op_mode;
div.inst_idx = pcam_inst->my_index;
@@ -145,6 +143,7 @@
p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode] = frame_id;
div.frame.frame_id =
p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode];
+ div.frame.buf_idx = buf_idx;
div.frame.handle = (uint32_t)vb;
msm_mctl_gettimeofday(&div.frame.timestamp);
vb->vidbuf.v4l2_buf.timestamp = div.frame.timestamp;
@@ -180,8 +179,11 @@
mem = vb2_plane_cookie(&vb->vidbuf, i);
div.frame.mp[i].phy_addr =
videobuf2_to_pmem_contig(&vb->vidbuf, i);
- div.frame.mp[i].data_offset =
- pcam_inst->buf_offset[buf_idx][i].data_offset;
+ if (!pcam_inst->buf_offset)
+ div.frame.mp[i].data_offset = 0;
+ else
+ div.frame.mp[i].data_offset =
+ pcam_inst->buf_offset[buf_idx][i].data_offset;
div.frame.mp[i].addr_offset =
mem->addr_offset;
div.frame.mp[i].fd = (int)mem->vaddr;
@@ -211,6 +213,7 @@
pp_frame->handle = (uint32_t)vb;
pp_frame->frame_id = vb->vidbuf.v4l2_buf.sequence;
pp_frame->timestamp = vb->vidbuf.v4l2_buf.timestamp;
+ pp_frame->buf_idx = buf_idx;
/* Get the cookie for 1st plane and store the path.
* Also use this to check the number of planes in
* this buffer.*/
@@ -312,7 +315,7 @@
struct msm_vpe_clock_rate clk_rate;
if (sizeof(struct msm_vpe_clock_rate) !=
pp_cmd->length) {
- D("%s: vpe cmd size mismatch "
+ pr_err("%s: vpe cmd size mismatch "
"(id=%d, length = %d, expect size = %d",
__func__, pp_cmd->id, pp_cmd->length,
sizeof(struct msm_vpe_clock_rate));
@@ -321,7 +324,7 @@
}
if (copy_from_user(&clk_rate, pp_cmd->value,
sizeof(struct msm_vpe_clock_rate))) {
- D("%s:clk_rate copy failed", __func__);
+ pr_err("%s:clk_rate copy failed", __func__);
return -EFAULT;
}
pp_cmd->value = (void *)&clk_rate;
@@ -527,18 +530,19 @@
return rc;
}
-static int msm_mctl_pp_path_to_msg_type(int path)
+static int msm_mctl_pp_path_to_img_mode(int path)
{
switch (path) {
case OUTPUT_TYPE_P:
- return VFE_MSG_OUTPUT_P;
+ return MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
case OUTPUT_TYPE_V:
- return VFE_MSG_OUTPUT_V;
+ return MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
case OUTPUT_TYPE_S:
- return VFE_MSG_OUTPUT_S;
+ return MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
case OUTPUT_TYPE_T:
+ return MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
default:
- return VFE_MSG_OUTPUT_T;
+ return -EINVAL;
}
}
@@ -549,7 +553,7 @@
struct msm_mctl_pp_frame_buffer pp_buffer;
struct msm_frame_buffer *buf = NULL;
void __user *argp = (void __user *)pp_cmd->value;
- int msg_type = VFE_MSG_OUTPUT_V;
+ int img_mode;
unsigned long flags;
switch (pp_cmd->id) {
@@ -557,8 +561,12 @@
if (copy_from_user(&pp_buffer, pp_cmd->value,
sizeof(pp_buffer)))
return -EFAULT;
- msg_type = msm_mctl_pp_path_to_msg_type(pp_buffer.path);
- buf = msm_mctl_get_free_buf(p_mctl, msg_type);
+ img_mode = msm_mctl_pp_path_to_img_mode(pp_buffer.path);
+ if (img_mode < 0) {
+ pr_err("%s Invalid image mode\n", __func__);
+ return img_mode;
+ }
+ buf = msm_mctl_get_free_buf(p_mctl, img_mode);
pp_buffer.buf_handle = (uint32_t)buf;
if (copy_to_user((void *)argp,
&pp_buffer,
@@ -572,9 +580,13 @@
if (copy_from_user(&pp_buffer, pp_cmd->value,
sizeof(pp_buffer)))
return -EFAULT;
- msg_type = msm_mctl_pp_path_to_msg_type(pp_buffer.path);
- buf = (struct msm_frame_buffer *)pp_buffer.buf_handle;
- msm_mctl_put_free_buf(p_mctl, msg_type, buf);
+ img_mode = msm_mctl_pp_path_to_img_mode(pp_buffer.path);
+ if (img_mode < 0) {
+ pr_err("%s Invalid image mode\n", __func__);
+ return img_mode;
+ }
+ buf = (struct msm_frame_buffer *)pp_buffer.buf_handle;
+ msm_mctl_put_free_buf(p_mctl, img_mode, buf);
break;
}
case MCTL_CMD_DIVERT_FRAME_PP_PATH: {
@@ -646,17 +658,20 @@
if ((MSM_MCTL_PP_VPE_FRAME_TO_APP &
pp_frame_cmd->vpe_output_action)) {
struct msm_free_buf done_frame;
- int msg_type =
- msm_mctl_pp_path_to_msg_type(
+ int img_mode =
+ msm_mctl_pp_path_to_img_mode(
pp_frame_cmd->path);
-
+ if (img_mode < 0) {
+ pr_err("%s Invalid image mode\n", __func__);
+ return img_mode;
+ }
done_frame.ch_paddr[0] =
pp_frame_info->dest_frame.sp.phy_addr;
done_frame.vb =
pp_frame_info->dest_frame.handle;
msm_mctl_buf_done_pp(
- p_mctl, msg_type, &done_frame, 0);
- pr_info("%s: vpe done to app, vb=0x%x, path=%d, phy=0x%x",
+ p_mctl, img_mode, &done_frame, 0);
+ D("%s: vpe done to app, vb=0x%x, path=%d, phy=0x%x",
__func__, done_frame.vb,
pp_frame_cmd->path, done_frame.ch_paddr[0]);
}
@@ -701,43 +716,38 @@
void __user *arg)
{
struct msm_cam_evt_divert_frame frame;
- int msg_type, image_mode, rc = 0;
+ int image_mode, rc = 0;
struct msm_free_buf free_buf;
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+
memset(&free_buf, 0, sizeof(struct msm_free_buf));
if (copy_from_user(&frame, arg,
sizeof(struct msm_cam_evt_divert_frame)))
return -EFAULT;
- switch (frame.frame.path) {
- case OUTPUT_TYPE_P:
- msg_type = VFE_MSG_OUTPUT_P;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
- break;
- case OUTPUT_TYPE_S:
- msg_type = VFE_MSG_OUTPUT_S;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
- break;
- case OUTPUT_TYPE_V:
- msg_type = VFE_MSG_OUTPUT_V;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
- break;
- case OUTPUT_TYPE_T:
- default:
- rc = -EFAULT;
- return rc;
+
+ image_mode = frame.image_mode;
+ if (image_mode <= 0) {
+ pr_err("%s Invalid image mode %d", __func__, image_mode);
+ return -EINVAL;
}
- rc = msm_mctl_reserve_free_buf(p_mctl, msg_type, &free_buf);
+ /* Always reserve the buffer from user's video node */
+ pcam_inst = p_mctl->sync.pcam_sync->dev_inst[image_mode];
+ if (!pcam_inst) {
+ pr_err("%s Instance already closed ", __func__);
+ return -EINVAL;
+ }
+ rc = msm_mctl_reserve_free_buf(p_mctl, pcam_inst,
+ image_mode, &free_buf);
if (rc == 0) {
- frame.frame.sp.phy_addr = free_buf.ch_paddr[0];
- frame.frame.handle = free_buf.vb;
- if (copy_to_user((void *)arg,
- &frame,
- sizeof(frame))) {
+ msm_mctl_pp_get_phy_addr(pcam_inst, free_buf.vb, &frame.frame);
+ if (copy_to_user((void *)arg, &frame, sizeof(frame))) {
ERR_COPY_TO_USER();
rc = -EFAULT;
}
}
- D("%s: reserve free buf, rc = %d, phy = 0x%x",
- __func__, rc, free_buf.ch_paddr[0]);
+ D("%s: reserve free buf got buffer %d from %p rc = %d, phy = 0x%x",
+ __func__, frame.frame.buf_idx,
+ pcam_inst, rc, free_buf.ch_paddr[0]);
return rc;
}
@@ -745,33 +755,36 @@
struct msm_cam_media_controller *p_mctl,
void __user *arg)
{
- struct msm_cam_evt_divert_frame frame;
- int msg_type, image_mode, rc = 0;
+ struct msm_cam_evt_divert_frame div_frame;
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ struct msm_pp_frame *frame;
+ int image_mode, rc = 0;
struct msm_free_buf free_buf;
- if (copy_from_user(&frame, arg,
+ if (copy_from_user(&div_frame, arg,
sizeof(struct msm_cam_evt_divert_frame)))
return -EFAULT;
- switch (frame.frame.path) {
- case OUTPUT_TYPE_P:
- msg_type = VFE_MSG_OUTPUT_P;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
- break;
- case OUTPUT_TYPE_S:
- msg_type = VFE_MSG_OUTPUT_S;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
- break;
- case OUTPUT_TYPE_V:
- msg_type = VFE_MSG_OUTPUT_V;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
- break;
- case OUTPUT_TYPE_T:
- default:
- rc = -EFAULT;
- return rc;
+
+ image_mode = div_frame.image_mode;
+ if (image_mode < 0) {
+ pr_err("%s Invalid image mode %d\n", __func__, image_mode);
+ return -EINVAL;
}
- free_buf.ch_paddr[0] = frame.frame.sp.phy_addr;
- rc = msm_mctl_release_free_buf(p_mctl, msg_type, &free_buf);
+ frame = &div_frame.frame;
+ if (frame->num_planes > 1)
+ free_buf.ch_paddr[0] = frame->mp[0].phy_addr;
+ else
+ free_buf.ch_paddr[0] = frame->sp.phy_addr;
+
+ pcam_inst = msm_mctl_get_pcam_inst(p_mctl, image_mode);
+ if (!pcam_inst) {
+ pr_err("%s Invalid instance. Cannot release frame.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ rc = msm_mctl_release_free_buf(p_mctl, pcam_inst,
+ image_mode, &free_buf);
D("%s: release free buf, rc = %d, phy = 0x%x",
__func__, rc, free_buf.ch_paddr[0]);
@@ -799,7 +812,7 @@
void __user *arg)
{
struct msm_pp_frame frame;
- int msg_type, image_mode, rc = 0;
+ int image_mode, rc = 0;
int dirty = 0;
struct msm_free_buf buf;
unsigned long flags;
@@ -808,23 +821,10 @@
return -EFAULT;
spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
- switch (frame.path) {
- case OUTPUT_TYPE_P:
- msg_type = VFE_MSG_OUTPUT_P;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
- break;
- case OUTPUT_TYPE_S:
- msg_type = VFE_MSG_OUTPUT_S;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
- break;
- case OUTPUT_TYPE_V:
- msg_type = VFE_MSG_OUTPUT_V;
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
- break;
- case OUTPUT_TYPE_T:
- default:
- rc = -EFAULT;
- goto err;
+ image_mode = msm_mctl_pp_path_to_img_mode(frame.path);
+ if (image_mode < 0) {
+ pr_err("%s Invalid image mode\n", __func__);
+ return image_mode;
}
D("%s Returning frame %x id %d to kernel ", __func__,
(int)frame.handle, frame.frame_id);
@@ -848,10 +848,7 @@
}
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
/* here buf.addr is phy_addr */
- rc = msm_mctl_buf_done_pp(p_mctl, msg_type, &buf, dirty);
- return rc;
-err:
- spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+ rc = msm_mctl_buf_done_pp(p_mctl, image_mode, &buf, dirty);
return rc;
}
@@ -864,11 +861,13 @@
int dirty = 0;
struct msm_free_buf buf;
unsigned long flags;
+ D("%s enter\n", __func__);
if (copy_from_user(&frame, arg, sizeof(frame)))
return -EFAULT;
spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+ D("%s Frame path: %d\n", __func__, frame.path);
switch (frame.path) {
case OUTPUT_TYPE_P:
msg_type = VFE_MSG_OUTPUT_P;
@@ -887,17 +886,47 @@
rc = -EFAULT;
goto err;
}
+
if (frame.num_planes > 1)
- buf.ch_paddr[0] = frame.mp[0].phy_addr;
+ buf.ch_paddr[0] = frame.mp[0].phy_addr +
+ frame.mp[0].data_offset;
else
- buf.ch_paddr[0] = frame.sp.phy_addr;
+ buf.ch_paddr[0] = frame.sp.phy_addr + frame.sp.y_off;
+
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
- /* here buf.addr is phy_addr */
- rc = msm_mctl_buf_done_pp(p_mctl, msg_type, &buf, dirty);
+ D("%s Frame done id: %d\n", __func__, frame.frame_id);
+ rc = msm_mctl_buf_done_pp(p_mctl, image_mode, &buf, dirty);
return rc;
err:
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
return rc;
}
+int msm_mctl_pp_mctl_divert_done(
+ struct msm_cam_media_controller *p_mctl,
+ void __user *arg)
+{
+ struct msm_cam_evt_divert_frame div_frame;
+ struct msm_frame_buffer *buf;
+ int image_mode, rc = 0;
+ if (copy_from_user(&div_frame, arg,
+ sizeof(struct msm_cam_evt_divert_frame))) {
+ pr_err("%s copy from user failed ", __func__);
+ return -EFAULT;
+ }
+
+ if (!div_frame.frame.handle) {
+ pr_err("%s Invalid buffer handle ", __func__);
+ return -EINVAL;
+ }
+ image_mode = div_frame.image_mode;
+ buf = (struct msm_frame_buffer *)div_frame.frame.handle;
+ D("%s Returning buffer %x Image mode %d ", __func__,
+ (int)buf, image_mode);
+ rc = msm_mctl_buf_return_buf(p_mctl, image_mode, buf);
+ if (rc < 0)
+ pr_err("%s Error returning mctl buffer ", __func__);
+
+ return rc;
+}
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index b04f07c..4b86bd8 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -460,63 +460,35 @@
vfe32_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
switch (mode) {
-
- case OUTPUT_2:
- vfe32_ctrl->outpath.output_mode |= VFE32_OUTPUT_MODE_PT;
+ case OUTPUT_PRIM:
+ vfe32_ctrl->outpath.output_mode =
+ VFE32_OUTPUT_MODE_PRIMARY;
break;
-
- case OUTPUT_1_AND_2:
- /* use wm0& 4 for thumbnail, wm1&5 for main image.*/
- vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_S; /* main image.*/
- vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_PT; /* thumbnail. */
+ case OUTPUT_PRIM_ALL_CHNLS:
+ vfe32_ctrl->outpath.output_mode =
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
break;
-
- case OUTPUT_1_2_AND_3:
- CDBG("%s: OUTPUT_ZSL", __func__);
- /* use wm0& 4 for postview, wm1&5 for preview.*/
- /* use wm2& 6 for main img */
+ case OUTPUT_PRIM|OUTPUT_SEC:
+ vfe32_ctrl->outpath.output_mode =
+ VFE32_OUTPUT_MODE_PRIMARY;
vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_S; /* main image.*/
- vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_P; /* preview. */
- vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_T; /* thumbnail. */
+ VFE32_OUTPUT_MODE_SECONDARY;
break;
-
- case OUTPUT_1_AND_3:
- /* use wm0& 4 for preview, wm1&5 for video.*/
+ case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
+ vfe32_ctrl->outpath.output_mode =
+ VFE32_OUTPUT_MODE_PRIMARY;
vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_V; /* video*/
- vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_PT; /* preview */
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
break;
- case CAMIF_TO_AXI_VIA_OUTPUT_2:
- /* use wm0 only */
- CDBG("config axi for raw snapshot.\n");
- vfe32_ctrl->outpath.out1.ch0 = 0; /* raw */
- vfe32_ctrl->outpath.output_mode |= VFE32_OUTPUT_MODE_S;
- break;
- case OUTPUT_ALL_CHNLS:
- /* YV12 preview */
+ case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
+ vfe32_ctrl->outpath.output_mode =
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_P_ALL_CHNLS;
- /* video */
- vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_V;
- break;
- case OUTPUT_ZSL_ALL_CHNLS:
- CDBG("%s: OUTPUT_ZSL_ALL_CHNLS", __func__);
- vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_S; /* main image.*/
- vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_P_ALL_CHNLS; /* preview. */
- vfe32_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_T; /* thumbnail. */
+ VFE32_OUTPUT_MODE_SECONDARY;
break;
default:
- break;
+ pr_err("%s Invalid AXI mode %d ", __func__, mode);
+ return -EINVAL;
}
msm_io_w(*ao, vfe32_ctrl->vfebase +
VFE_BUS_IO_FORMAT_CFG);
@@ -545,7 +517,8 @@
vfe32_ctrl->update_ack_pending = FALSE;
spin_unlock_irqrestore(&vfe32_ctrl->update_ack_lock, flags);
- vfe32_ctrl->recording_state = VFE_REC_STATE_IDLE;
+ vfe32_ctrl->recording_state = VFE_STATE_IDLE;
+ vfe32_ctrl->liveshot_state = VFE_STATE_IDLE;
atomic_set(&vfe32_ctrl->vstate, 0);
@@ -734,7 +707,7 @@
struct msm_sync *sync = vfe_syncdata;
msm_camio_bus_scale_cfg(
sync->sdata->pdata->cam_bus_scale_table, S_VIDEO);
- vfe32_ctrl->recording_state = VFE_REC_STATE_START_REQUESTED;
+ vfe32_ctrl->recording_state = VFE_STATE_START_REQUESTED;
msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
return 0;
}
@@ -742,17 +715,24 @@
static int vfe32_stop_recording(void)
{
struct msm_sync *sync = vfe_syncdata;
- vfe32_ctrl->recording_state = VFE_REC_STATE_STOP_REQUESTED;
+ vfe32_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
msm_camio_bus_scale_cfg(
sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
return 0;
}
-static void vfe32_liveshot(void){
+static void vfe32_start_liveshot(void){
struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
if (p_sync)
p_sync->liveshot_enabled = true;
+
+ /* Hardcode 1 live snapshot for now. */
+ vfe32_ctrl->outpath.out0.capture_cnt = 1;
+ vfe32_ctrl->vfe_capture_count = vfe32_ctrl->outpath.out0.capture_cnt;
+
+ vfe32_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
+ msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
}
static int vfe32_zsl(void)
@@ -765,55 +745,57 @@
CDBG("%s:op mode %d O/P Mode %d\n", __func__,
vfe32_ctrl->operation_mode, vfe32_ctrl->outpath.output_mode);
- if ((vfe32_ctrl->operation_mode == VFE_MODE_OF_OPERATION_ZSL)) {
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_P) {
- irq_comp_mask |=
- ((0x1 << (vfe32_ctrl->outpath.out0.ch0)) |
+
+ if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PRIMARY) {
+ irq_comp_mask |= ((0x1 << (vfe32_ctrl->outpath.out0.ch0)) |
(0x1 << (vfe32_ctrl->outpath.out0.ch1)));
- } else if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_P_ALL_CHNLS) {
- pr_debug("%s Enabling all channels ", __func__);
- irq_comp_mask |= (0x1 << vfe32_ctrl->outpath.out0.ch0 |
- 0x1 << vfe32_ctrl->outpath.out0.ch1 |
- 0x1 << vfe32_ctrl->outpath.out0.ch2);
- }
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_T) {
- irq_comp_mask |=
- ((0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8)) |
- (0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8)));
- }
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_S) {
- irq_comp_mask |=
- ((0x1 << (vfe32_ctrl->outpath.out2.ch0 + 8)) |
- (0x1 << (vfe32_ctrl->outpath.out2.ch1 + 8)));
- }
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_P) {
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
- } else if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_P_ALL_CHNLS) {
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
- }
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_T) {
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
- }
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_S) {
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch0]);
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch1]);
- }
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ irq_comp_mask |= ((0x1 << (vfe32_ctrl->outpath.out0.ch0)) |
+ (0x1 << (vfe32_ctrl->outpath.out0.ch1)) |
+ (0x1 << (vfe32_ctrl->outpath.out0.ch2)));
}
+
+ if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_SECONDARY) {
+ irq_comp_mask |= ((0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8)) |
+ (0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8)));
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ irq_comp_mask |= ((0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8)) |
+ (0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8)) |
+ (0x1 << (vfe32_ctrl->outpath.out1.ch2 + 8)));
+ }
+
+ if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
+ }
+
+ if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_SECONDARY) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
+ }
+
msm_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
vfe32_start_common();
msm_camio_bus_scale_cfg(
@@ -823,6 +805,29 @@
msm_io_w(1, vfe32_ctrl->vfebase + 0x188);
return 0;
}
+static int vfe32_capture_raw(uint32_t num_frames_capture)
+{
+ uint32_t irq_comp_mask = 0;
+ struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+
+ vfe32_ctrl->outpath.out0.capture_cnt = num_frames_capture;
+ vfe32_ctrl->vfe_capture_count = num_frames_capture;
+
+ irq_comp_mask =
+ msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+ if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PRIMARY) {
+ irq_comp_mask |= (0x1 << (vfe32_ctrl->outpath.out0.ch0));
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ }
+
+ msm_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+ msm_camio_bus_scale_cfg(
+ p_sync->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+ vfe32_start_common();
+ return 0;
+}
static int vfe32_capture(uint32_t num_frames_capture)
{
@@ -834,51 +839,49 @@
}
/* capture command is valid for both idle and active state. */
vfe32_ctrl->outpath.out1.capture_cnt = num_frames_capture;
- if (vfe32_ctrl->operation_mode == VFE_MODE_OF_OPERATION_SNAPSHOT) {
+ if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
vfe32_ctrl->outpath.out0.capture_cnt =
- num_frames_capture;
+ num_frames_capture;
}
vfe32_ctrl->vfe_capture_count = num_frames_capture;
- irq_comp_mask =
- msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+ irq_comp_mask = msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- if (vfe32_ctrl->operation_mode == VFE_MODE_OF_OPERATION_SNAPSHOT) {
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PT) {
+ if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
irq_comp_mask |= (0x1 << vfe32_ctrl->outpath.out0.ch0 |
0x1 << vfe32_ctrl->outpath.out0.ch1);
}
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_S) {
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY) {
irq_comp_mask |=
- (0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8) |
- 0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8));
+ (0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8) |
+ 0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8));
}
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PT) {
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
}
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_S) {
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY) {
msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
}
- } else { /* this is raw snapshot mode. */
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_S) {
- irq_comp_mask |=
- (0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8));
- msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
- }
}
msm_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_camio_bus_scale_cfg(
p_sync->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+
vfe32_start_common();
- msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
/* for debug */
msm_io_w(1, vfe32_ctrl->vfebase + 0x18C);
msm_io_w(1, vfe32_ctrl->vfebase + 0x188);
@@ -889,44 +892,62 @@
{
uint32_t irq_comp_mask = 0;
struct msm_sync *sync = vfe_syncdata;
- /* start command now is only good for continuous mode. */
- if ((vfe32_ctrl->operation_mode != VFE_MODE_OF_OPERATION_CONTINUOUS) &&
- (vfe32_ctrl->operation_mode != VFE_MODE_OF_OPERATION_VIDEO))
- return 0;
+
irq_comp_mask =
msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PT) {
+ if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PRIMARY) {
irq_comp_mask |= (0x1 << vfe32_ctrl->outpath.out0.ch0 |
0x1 << vfe32_ctrl->outpath.out0.ch1);
} else if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_P_ALL_CHNLS) {
- pr_debug("%s Enabling all channels ", __func__);
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
irq_comp_mask |= (0x1 << vfe32_ctrl->outpath.out0.ch0 |
0x1 << vfe32_ctrl->outpath.out0.ch1 |
0x1 << vfe32_ctrl->outpath.out0.ch2);
}
-
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_V) {
- irq_comp_mask |= (0x1 << (vfe32_ctrl->outpath.out2.ch0 + 16)|
- 0x1 << (vfe32_ctrl->outpath.out2.ch1 + 16));
+ if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_SECONDARY) {
+ irq_comp_mask |= (0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8) |
+ 0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8));
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ irq_comp_mask |= (0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8) |
+ 0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8) |
+ 0x1 << (vfe32_ctrl->outpath.out1.ch2 + 8));
}
-
msm_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PT) {
- msm_io_w(1, vfe32_ctrl->vfebase +
+ if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
- msm_io_w(1, vfe32_ctrl->vfebase +
+ msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
- } else if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_P_ALL_CHNLS) {
- msm_io_w(1, vfe32_ctrl->vfebase +
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
- msm_io_w(1, vfe32_ctrl->vfebase +
+ msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
- msm_io_w(1, vfe32_ctrl->vfebase +
+ msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
+ }
+ } else {
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
+ }
}
msm_camio_bus_scale_cfg(
sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
@@ -1107,39 +1128,13 @@
{
struct vfe32_output_ch *ch = NULL;
- switch (vfe32_ctrl->operation_mode) {
- case VFE_MODE_OF_OPERATION_CONTINUOUS:
- if (path == VFE_MSG_OUTPUT_P)
- ch = &vfe32_ctrl->outpath.out0;
- break;
- case VFE_MODE_OF_OPERATION_SNAPSHOT:
- if (path == VFE_MSG_OUTPUT_T)
- ch = &vfe32_ctrl->outpath.out0;
- else if (path == VFE_MSG_OUTPUT_S)
- ch = &vfe32_ctrl->outpath.out1;
- break;
- case VFE_MODE_OF_OPERATION_VIDEO:
- if (path == VFE_MSG_OUTPUT_P)
- ch = &vfe32_ctrl->outpath.out0;
- else if (path == VFE_MSG_OUTPUT_V)
- ch = &vfe32_ctrl->outpath.out2;
- break;
- case VFE_MODE_OF_OPERATION_RAW_SNAPSHOT:
- if (path == VFE_MSG_OUTPUT_S)
- ch = &vfe32_ctrl->outpath.out0;
- break;
- case VFE_MODE_OF_OPERATION_ZSL:
- if (path == VFE_MSG_OUTPUT_P)
- ch = &vfe32_ctrl->outpath.out0;
- else if (path == VFE_MSG_OUTPUT_T)
- ch = &vfe32_ctrl->outpath.out1;
- else if (path == VFE_MSG_OUTPUT_S)
- ch = &vfe32_ctrl->outpath.out2;
- break;
- default:
- pr_err("%s: Unsupported operation mode %d\n", __func__,
- vfe32_ctrl->operation_mode);
- }
+ if (path == VFE_MSG_OUTPUT_PRIMARY)
+ ch = &vfe32_ctrl->outpath.out0;
+ else if (path == VFE_MSG_OUTPUT_SECONDARY)
+ ch = &vfe32_ctrl->outpath.out1;
+ else
+ pr_err("%s: Invalid path %d\n", __func__,
+ path);
BUG_ON(ch == NULL);
return ch;
@@ -1170,7 +1165,7 @@
outch->pong.ch_paddr[0]);
if (vfe32_ctrl->operation_mode !=
- VFE_MODE_OF_OPERATION_RAW_SNAPSHOT) {
+ VFE_OUTPUTS_RAW) {
vfe32_put_ch_ping_addr(outch->ch1,
outch->ping.ch_paddr[1]);
vfe32_put_ch_pong_addr(outch->ch1,
@@ -1242,11 +1237,18 @@
case VFE_CMD_START:
pr_info("vfe32_proc_general: cmdID = %s\n",
vfe32_general_cmd[cmd->id]);
- rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_START,
- VFE_MSG_OUTPUT_P);
+ if (vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO)
+ /* Configure primary channel */
+ rc = vfe32_configure_pingpong_buffers(
+ VFE_MSG_V32_START, VFE_MSG_OUTPUT_PRIMARY);
+ else
+ /* Configure secondary channel */
+ rc = vfe32_configure_pingpong_buffers(
+ VFE_MSG_V32_START, VFE_MSG_OUTPUT_SECONDARY);
if (rc < 0) {
pr_err("%s error configuring pingpong buffers"
- " for preview", __func__);
+ " for preview", __func__);
rc = -EINVAL;
goto proc_general_done;
}
@@ -1255,6 +1257,23 @@
case VFE_CMD_UPDATE:
vfe32_update();
break;
+ case VFE_CMD_CAPTURE_RAW:
+ pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
+ if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
+ sizeof(uint32_t))) {
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY);
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers"
+ " for snapshot", __func__);
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ rc = vfe32_capture_raw(snapshot_cnt);
+ break;
case VFE_CMD_CAPTURE:
pr_info("vfe32_proc_general: cmdID = %s\n",
vfe32_general_cmd[cmd->id]);
@@ -1263,32 +1282,39 @@
rc = -EFAULT;
goto proc_general_done;
}
+ /* Configure primary channel */
rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
- VFE_MSG_OUTPUT_S);
+ VFE_MSG_OUTPUT_PRIMARY);
if (rc < 0) {
pr_err("%s error configuring pingpong buffers"
- " for snapshot", __func__);
+ " for primary output", __func__);
rc = -EINVAL;
goto proc_general_done;
}
- if (vfe32_ctrl->operation_mode !=
- VFE_MODE_OF_OPERATION_RAW_SNAPSHOT) {
- rc = vfe32_configure_pingpong_buffers(
- VFE_MSG_V32_CAPTURE, VFE_MSG_OUTPUT_T);
- if (rc < 0) {
- pr_err("%s error configuring pingpong buffers"
- " for thumbnail", __func__);
- rc = -EINVAL;
- goto proc_general_done;
- }
+ /* Configure secondary channel */
+ rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
+ VFE_MSG_OUTPUT_SECONDARY);
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers"
+ " for secondary output", __func__);
+ rc = -EINVAL;
+ goto proc_general_done;
}
rc = vfe32_capture(snapshot_cnt);
break;
case VFE_CMD_START_RECORDING:
pr_info("vfe32_proc_general: cmdID = %s\n",
vfe32_general_cmd[cmd->id]);
- rc = vfe32_configure_pingpong_buffers(
- VFE_MSG_V32_START_RECORDING, VFE_MSG_OUTPUT_V);
+ if (vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO)
+ rc = vfe32_configure_pingpong_buffers(
+ VFE_MSG_V32_START_RECORDING,
+ VFE_MSG_OUTPUT_SECONDARY);
+ else if (vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_VIDEO_AND_PREVIEW)
+ rc = vfe32_configure_pingpong_buffers(
+ VFE_MSG_V32_START_RECORDING,
+ VFE_MSG_OUTPUT_PRIMARY);
if (rc < 0) {
pr_err("%s error configuring pingpong buffers"
" for video", __func__);
@@ -1685,7 +1711,16 @@
break;
case VFE_CMD_LIVESHOT:
- vfe32_liveshot();
+ /* Configure primary channel */
+ rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY);
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers"
+ " for primary output", __func__);
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ vfe32_start_liveshot();
break;
case VFE_CMD_LINEARIZATION_CFG:
@@ -2113,15 +2148,11 @@
case VFE_CMD_ZSL:
rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_START,
- VFE_MSG_OUTPUT_P);
+ VFE_MSG_OUTPUT_PRIMARY);
if (rc < 0)
goto proc_general_done;
rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_START,
- VFE_MSG_OUTPUT_T);
- if (rc < 0)
- goto proc_general_done;
- rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_START,
- VFE_MSG_OUTPUT_S);
+ VFE_MSG_OUTPUT_SECONDARY);
if (rc < 0)
goto proc_general_done;
@@ -2425,50 +2456,59 @@
static void vfe32_process_reg_update_irq(void)
{
- uint32_t old_val;
unsigned long flags;
- if (vfe32_ctrl->recording_state == VFE_REC_STATE_START_REQUESTED) {
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_V) {
+
+ if (vfe32_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
+ if (vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch0]);
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
msm_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch1]);
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ } else if (vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
}
- vfe32_ctrl->recording_state = VFE_REC_STATE_STARTED;
+ vfe32_ctrl->recording_state = VFE_STATE_STARTED;
msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
CDBG("start video triggered .\n");
} else if (vfe32_ctrl->recording_state ==
- VFE_REC_STATE_STOP_REQUESTED) {
- if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_V) {
- msm_io_w_mb(0, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch0]);
- msm_io_w_mb(0, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch1]);
+ VFE_STATE_STOP_REQUESTED) {
+ if (vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+ msm_io_w(0, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ msm_io_w(0, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ } else if (vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+ msm_io_w(0, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_io_w(0, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
}
-
- /*disable rs& cs when stop recording. */
- old_val = msm_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
- old_val &= (~RS_CS_ENABLE_MASK);
- msm_io_w(old_val, vfe32_ctrl->vfebase + VFE_MODULE_CFG);
-
CDBG("stop video triggered .\n");
}
+
if (vfe32_ctrl->start_ack_pending == TRUE) {
vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_START_ACK);
vfe32_ctrl->start_ack_pending = FALSE;
} else {
if (vfe32_ctrl->recording_state ==
- VFE_REC_STATE_STOP_REQUESTED) {
- vfe32_ctrl->recording_state = VFE_REC_STATE_STOPPED;
+ VFE_STATE_STOP_REQUESTED) {
+ vfe32_ctrl->recording_state = VFE_STATE_STOPPED;
/* request a reg update and send STOP_REC_ACK
* when we process the next reg update irq.
*/
msm_io_w_mb(1,
vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
} else if (vfe32_ctrl->recording_state ==
- VFE_REC_STATE_STOPPED) {
+ VFE_STATE_STOPPED) {
vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_STOP_REC_ACK);
- vfe32_ctrl->recording_state = VFE_REC_STATE_IDLE;
+ vfe32_ctrl->recording_state = VFE_STATE_IDLE;
}
spin_lock_irqsave(&vfe32_ctrl->update_ack_lock, flags);
if (vfe32_ctrl->update_ack_pending == TRUE) {
@@ -2481,30 +2521,60 @@
&vfe32_ctrl->update_ack_lock, flags);
}
}
- if (vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_SNAPSHOT) { /* in snapshot mode */
+
+ if (vfe32_ctrl->liveshot_state == VFE_STATE_START_REQUESTED) {
+ pr_info("%s enabling liveshot output\n", __func__);
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ msm_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ vfe32_ctrl->liveshot_state = VFE_STATE_STARTED;
+ }
+ }
+
+ if (vfe32_ctrl->liveshot_state == VFE_STATE_STARTED) {
+ vfe32_ctrl->vfe_capture_count--;
+ if (!vfe32_ctrl->vfe_capture_count)
+ vfe32_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
+ msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ } else if (vfe32_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED) {
+ CDBG("%s: disabling liveshot output\n", __func__);
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_io_w(0, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ msm_io_w(0, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ vfe32_ctrl->liveshot_state = VFE_STATE_STOPPED;
+ msm_io_w_mb(1, vfe32_ctrl->vfebase +
+ VFE_REG_UPDATE_CMD);
+ }
+ } else if (vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED) {
+ vfe32_ctrl->liveshot_state = VFE_STATE_IDLE;
+ }
+
+ if ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
+ (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB)) {
+ /* in snapshot mode */
/* later we need to add check for live snapshot mode. */
vfe32_ctrl->vfe_capture_count--;
/* if last frame to be captured: */
if (vfe32_ctrl->vfe_capture_count == 0) {
- /* stop the bus output: write master enable = 0*/
if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PT) {
+ VFE32_OUTPUT_MODE_PRIMARY) {
msm_io_w(0, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- outpath.out0.ch0]);
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
msm_io_w(0, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- outpath.out0.ch1]);
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
}
if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_S) {
+ VFE32_OUTPUT_MODE_SECONDARY) {
msm_io_w(0, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- outpath.out1.ch0]);
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
msm_io_w(0, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- outpath.out1.ch1]);
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
}
msm_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
@@ -2512,7 +2582,7 @@
/* then do reg_update. */
msm_io_w(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
}
- } /* if snapshot mode. */
+ } /* in snapshot mode. */
}
static void vfe32_set_default_reg_values(void)
@@ -2570,9 +2640,8 @@
static void vfe32_process_camif_sof_irq(void)
{
- /* in raw snapshot mode */
if (vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_RAW_SNAPSHOT) {
+ VFE_OUTPUTS_RAW) {
if (vfe32_ctrl->start_ack_pending) {
vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_START_ACK);
vfe32_ctrl->start_ack_pending = FALSE;
@@ -2585,10 +2654,8 @@
msm_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
}
- } /* if raw snapshot mode. */
+ }
vfe32_ctrl->vfeFrameId++;
- if (vfe32_ctrl->vfeFrameId == 0)
- vfe32_ctrl->vfeFrameId = 1; /* wrapped back */
vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_SOF_ACK);
CDBG("camif_sof_irq, frameId = %d\n", vfe32_ctrl->vfeFrameId);
@@ -2602,14 +2669,12 @@
static void vfe32_process_error_irq(uint32_t errStatus)
{
- uint32_t camifStatus;
- uint32_t *temp;
+ uint32_t reg_value;
if (errStatus & VFE32_IMASK_CAMIF_ERROR) {
pr_err("vfe32_irq: camif errors\n");
- temp = (uint32_t *)(vfe32_ctrl->vfebase + VFE_CAMIF_STATUS);
- camifStatus = msm_io_r(temp);
- pr_err("camifStatus = 0x%x\n", camifStatus);
+ reg_value = msm_io_r(vfe32_ctrl->vfebase + VFE_CAMIF_STATUS);
+ pr_err("camifStatus = 0x%x\n", reg_value);
vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_CAMIF_ERROR);
}
@@ -2631,8 +2696,12 @@
if (errStatus & VFE32_IMASK_REALIGN_BUF_CR_OVFL)
pr_err("vfe32_irq: realign bug CR overflow\n");
- if (errStatus & VFE32_IMASK_VIOLATION)
+ if (errStatus & VFE32_IMASK_VIOLATION) {
pr_err("vfe32_irq: violation interrupt\n");
+ reg_value =
+ msm_io_r(vfe32_ctrl->vfebase + VFE_VIOLATION_STATUS);
+ pr_err("%s: violationStatus = 0x%x\n", __func__, reg_value);
+ }
if (errStatus & VFE32_IMASK_IMG_MAST_0_BUS_OVFL)
pr_err("vfe32_irq: image master 0 bus overflow\n");
@@ -2703,26 +2772,24 @@
uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
uint8_t out_bool = 0;
struct msm_free_buf *free_buf = NULL;
- if (vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_SNAPSHOT)
- free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
- VFE_MSG_OUTPUT_T);
- else
- free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
- VFE_MSG_OUTPUT_P);
+
+ free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+ VFE_MSG_OUTPUT_PRIMARY);
+
/* we render frames in the following conditions:
1. Continuous mode and the free buffer is avaialable.
2. In snapshot shot mode, free buffer is not always available.
when pending snapshot count is <=1, then no need to use
free buffer.
*/
- out_bool =
- ((vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_SNAPSHOT ||
- vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_RAW_SNAPSHOT) &&
- (vfe32_ctrl->vfe_capture_count <= 1)) ||
- free_buf;
+ out_bool = ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_RAW ||
+ vfe32_ctrl->liveshot_state == VFE_STATE_STARTED ||
+ vfe32_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED ||
+ vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED) &&
+ (vfe32_ctrl->vfe_capture_count <= 1)) || free_buf;
+
if (out_bool) {
ping_pong = msm_io_r(vfe32_ctrl->vfebase +
VFE_BUS_PING_PONG_STATUS);
@@ -2754,87 +2821,27 @@
free_buf->ch_paddr[2]);
}
if (vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_SNAPSHOT) {
- /* will add message for multi-shot. */
+ VFE_OUTPUTS_THUMB_AND_MAIN ||
+ vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_MAIN_AND_THUMB ||
+ vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_RAW ||
+ vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED)
vfe32_ctrl->outpath.out0.capture_cnt--;
- vfe_send_outmsg(&vfe32_ctrl->subdev,
- MSG_ID_OUTPUT_T, ch0_paddr,
- ch1_paddr, ch2_paddr);
- } else {
- /* always send message for continous mode. */
- /* if continuous mode, for display. (preview) */
- vfe_send_outmsg(&vfe32_ctrl->subdev,
- MSG_ID_OUTPUT_P, ch0_paddr,
- ch1_paddr, ch2_paddr);
- }
+
+ vfe_send_outmsg(&vfe32_ctrl->subdev,
+ MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
+ ch1_paddr, ch2_paddr);
+
+ if (vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED)
+ vfe32_ctrl->liveshot_state = VFE_STATE_IDLE;
+
} else {
vfe32_ctrl->outpath.out0.frame_drop_cnt++;
CDBG("path_irq_0 - no free buffer!\n");
}
}
-static void vfe32_process_zsl_frame(void)
-{
- uint32_t ping_pong;
- uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
- struct msm_free_buf *free_buf = NULL;
-
- ping_pong = msm_io_r(vfe32_ctrl->vfebase +
- VFE_BUS_PING_PONG_STATUS);
-
- /* Thumbnail */
- free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
- VFE_MSG_OUTPUT_T);
- if (free_buf) {
- ch0_paddr = vfe32_get_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out1.ch0);
- ch1_paddr = vfe32_get_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out1.ch1);
- ch2_paddr = vfe32_get_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out1.ch2);
-
- vfe32_put_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out1.ch0,
- free_buf->ch_paddr[0]);
- vfe32_put_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out1.ch1,
- free_buf->ch_paddr[1]);
- if (free_buf->num_planes > 2)
- vfe32_put_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out1.ch2,
- free_buf->ch_paddr[2]);
- vfe_send_outmsg(&vfe32_ctrl->subdev,
- MSG_ID_OUTPUT_T, ch0_paddr,
- ch1_paddr, ch2_paddr);
- }
-
- /* Mainimg */
- free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
- VFE_MSG_OUTPUT_S);
- if (free_buf) {
- ch0_paddr = vfe32_get_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch0);
- ch1_paddr = vfe32_get_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch1);
- ch2_paddr = vfe32_get_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch2);
- if (free_buf->num_planes > 2)
- vfe32_put_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch2,
- free_buf->ch_paddr[2]);
-
- vfe32_put_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch0,
- free_buf->ch_paddr[0]);
- vfe32_put_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch1,
- free_buf->ch_paddr[1]);
- vfe_send_outmsg(&vfe32_ctrl->subdev,
- MSG_ID_OUTPUT_S, ch0_paddr,
- ch1_paddr, ch2_paddr);
- }
-}
-
static void vfe32_process_output_path_irq_1(void)
{
uint32_t ping_pong;
@@ -2843,26 +2850,17 @@
uint8_t out_bool = 0;
struct msm_free_buf *free_buf = NULL;
- if (vfe32_ctrl->operation_mode == VFE_MODE_OF_OPERATION_ZSL) {
- vfe32_process_zsl_frame();
- return;
- }
-
free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
- VFE_MSG_OUTPUT_S);
+ VFE_MSG_OUTPUT_SECONDARY);
- /* we render frames in the following conditions:
- 1. Continuous mode and the free buffer is avaialable.
- 2. In snapshot shot mode, free buffer is not always available.
- -- when pending snapshot count is <=1, then no need to use
- free buffer.
- */
- out_bool =
- ((vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_SNAPSHOT ||
+ out_bool = ((vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_THUMB_AND_MAIN ||
vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_RAW_SNAPSHOT) &&
- (vfe32_ctrl->vfe_capture_count <= 1)) || free_buf;
+ VFE_OUTPUTS_MAIN_AND_THUMB ||
+ vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_RAW) &&
+ (vfe32_ctrl->vfe_capture_count <= 1)) || free_buf;
+
if (out_bool) {
ping_pong = msm_io_r(vfe32_ctrl->vfebase +
VFE_BUS_PING_PONG_STATUS);
@@ -2876,8 +2874,8 @@
ch2_paddr = vfe32_get_ch_addr(ping_pong,
vfe32_ctrl->outpath.out1.ch2);
- CDBG("snapshot main, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
- ch0_paddr, ch1_paddr, ch2_paddr);
+ pr_debug("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+ __func__, ch0_paddr, ch1_paddr, ch2_paddr);
if (free_buf) {
/* Y channel */
vfe32_put_ch_addr(ping_pong,
@@ -2892,85 +2890,23 @@
vfe32_ctrl->outpath.out1.ch2,
free_buf->ch_paddr[2]);
}
-
if (vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_SNAPSHOT ||
+ VFE_OUTPUTS_THUMB_AND_MAIN ||
vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_RAW_SNAPSHOT) {
+ VFE_OUTPUTS_MAIN_AND_THUMB ||
+ vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_RAW)
vfe32_ctrl->outpath.out1.capture_cnt--;
- vfe_send_outmsg(&vfe32_ctrl->subdev,
- MSG_ID_OUTPUT_S, ch0_paddr,
- ch1_paddr, ch2_paddr);
- }
+
+ vfe_send_outmsg(&vfe32_ctrl->subdev,
+ MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
+ ch1_paddr, ch2_paddr);
} else {
vfe32_ctrl->outpath.out1.frame_drop_cnt++;
CDBG("path_irq_1 - no free buffer!\n");
}
}
-static void vfe32_process_output_path_irq_2(void)
-{
- uint32_t ping_pong;
- uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
- struct msm_free_buf *free_buf = NULL;
-
- if (vfe32_ctrl->recording_state == VFE_REC_STATE_STOP_REQUESTED) {
- vfe32_ctrl->outpath.out2.frame_drop_cnt++;
- CDBG("%s: path_irq_2 - recording stop requested ", __func__);
- return;
- }
-
- free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
- VFE_MSG_OUTPUT_V);
- /* we render frames in the following conditions:
- 1. Continuous mode and the free buffer is avaialable.
- 2. In snapshot shot mode, free buffer is not always available.
- -- when pending snapshot count is <=1, then no need to use
- free buffer.
- */
-
- CDBG("%s: op mode = %d, capture_cnt = %d\n", __func__,
- vfe32_ctrl->operation_mode, vfe32_ctrl->vfe_capture_count);
-
- if (free_buf) {
- ping_pong = msm_io_r(vfe32_ctrl->vfebase +
- VFE_BUS_PING_PONG_STATUS);
-
- /* Y channel */
- ch0_paddr = vfe32_get_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch0);
- /* Chroma channel */
- ch1_paddr = vfe32_get_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch1);
- ch2_paddr = vfe32_get_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch2);
-
- CDBG("video output, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
- ch0_paddr, ch1_paddr, ch2_paddr);
-
- /* Y channel */
- vfe32_put_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch0,
- free_buf->ch_paddr[0]);
- /* Chroma channel */
- vfe32_put_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch1,
- free_buf->ch_paddr[1]);
- if (free_buf->num_planes > 2)
- vfe32_put_ch_addr(ping_pong,
- vfe32_ctrl->outpath.out2.ch2,
- free_buf->ch_paddr[2]);
-
- vfe_send_outmsg(&vfe32_ctrl->subdev,
- MSG_ID_OUTPUT_V, ch0_paddr,
- ch1_paddr, ch2_paddr);
-
- } else {
- vfe32_ctrl->outpath.out2.frame_drop_cnt++;
- CDBG("path_irq_2 - no free buffer!\n");
- }
-}
-
static void vfe32_process_stats_comb_irq(uint32_t *irqstatus)
{
return;
@@ -3076,6 +3012,8 @@
} else{
spin_unlock_irqrestore(&vfe32_ctrl->aec_ack_lock, flags);
vfe32_ctrl->aecStatsControl.droppedStatsFrameCount++;
+ CDBG("%s: droppedStatsFrameCount = %d", __func__,
+ vfe32_ctrl->aecStatsControl.droppedStatsFrameCount);
}
}
@@ -3094,6 +3032,8 @@
} else{
spin_unlock_irqrestore(&vfe32_ctrl->awb_ack_lock, flags);
vfe32_ctrl->awbStatsControl.droppedStatsFrameCount++;
+ CDBG("%s: droppedStatsFrameCount = %d", __func__,
+ vfe32_ctrl->awbStatsControl.droppedStatsFrameCount);
}
}
@@ -3112,6 +3052,8 @@
} else{
spin_unlock_irqrestore(&vfe32_ctrl->af_ack_lock, flags);
vfe32_ctrl->afStatsControl.droppedStatsFrameCount++;
+ CDBG("%s: droppedStatsFrameCount = %d", __func__,
+ vfe32_ctrl->afStatsControl.droppedStatsFrameCount);
}
}
@@ -3124,8 +3066,11 @@
vfe_send_stats_msg(vfe32_ctrl->ihistStatsControl.bufToRender,
statsIhistNum);
- } else
+ } else {
vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+ CDBG("%s: droppedStatsFrameCount = %d", __func__,
+ vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount);
+ }
}
static void vfe32_process_stats_rs_irq(void)
@@ -3137,8 +3082,11 @@
vfe_send_stats_msg(vfe32_ctrl->rsStatsControl.bufToRender,
statsRsNum);
- } else
+ } else {
vfe32_ctrl->rsStatsControl.droppedStatsFrameCount++;
+ CDBG("%s: droppedStatsFrameCount = %d", __func__,
+ vfe32_ctrl->rsStatsControl.droppedStatsFrameCount);
+ }
}
static void vfe32_process_stats_cs_irq(void)
@@ -3150,8 +3098,11 @@
vfe_send_stats_msg(vfe32_ctrl->csStatsControl.bufToRender,
statsCsNum);
- } else
+ } else {
vfe32_ctrl->csStatsControl.droppedStatsFrameCount++;
+ CDBG("%s: droppedStatsFrameCount = %d", __func__,
+ vfe32_ctrl->csStatsControl.droppedStatsFrameCount);
+ }
}
static void vfe32_do_tasklet(unsigned long data)
@@ -3215,17 +3166,14 @@
CDBG("Image composite done 1 irq occured.\n");
vfe32_process_output_path_irq_1();
}
- if (qcmd->vfeInterruptStatus0 &
- VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK) {
- CDBG("Image composite done 2 irq occured.\n");
- vfe32_process_output_path_irq_2();
- }
/* in snapshot mode if done then send
snapshot done message */
if (vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_SNAPSHOT ||
+ VFE_OUTPUTS_THUMB_AND_MAIN ||
vfe32_ctrl->operation_mode ==
- VFE_MODE_OF_OPERATION_RAW_SNAPSHOT) {
+ VFE_OUTPUTS_MAIN_AND_THUMB ||
+ vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_RAW) {
if ((vfe32_ctrl->outpath.out0.capture_cnt == 0)
&& (vfe32_ctrl->outpath.out1.
capture_cnt == 0)) {
@@ -3446,7 +3394,12 @@
case CMD_STATS_CS_ENABLE:
rc = vfe_stats_cs_buf_init(scfg);
break;
+ default:
+ pr_err("%s Unsupported cmd type %d",
+ __func__, cmd->cmd_type);
+ break;
}
+ goto vfe32_config_done;
}
switch (cmd->cmd_type) {
case CMD_GENERAL:
@@ -3496,7 +3449,7 @@
vfe32_stats_cs_ack(sack);
break;
- case CMD_AXI_CFG_PREVIEW: {
+ case CMD_AXI_CFG_PRIM: {
uint32_t *axio = NULL;
axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
GFP_ATOMIC);
@@ -3511,12 +3464,11 @@
rc = -EFAULT;
break;
}
- vfe32_config_axi(OUTPUT_2, axio);
+ vfe32_config_axi(OUTPUT_PRIM, axio);
kfree(axio);
}
break;
-
- case CMD_RAW_PICT_AXI_CFG: {
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
uint32_t *axio = NULL;
axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
GFP_ATOMIC);
@@ -3531,12 +3483,11 @@
rc = -EFAULT;
break;
}
- vfe32_config_axi(CAMIF_TO_AXI_VIA_OUTPUT_2, axio);
+ vfe32_config_axi(OUTPUT_PRIM_ALL_CHNLS, axio);
kfree(axio);
}
break;
-
- case CMD_AXI_CFG_SNAP: {
+ case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
uint32_t *axio = NULL;
axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
GFP_ATOMIC);
@@ -3551,14 +3502,12 @@
rc = -EFAULT;
break;
}
- vfe32_config_axi(OUTPUT_1_AND_2, axio);
+ vfe32_config_axi(OUTPUT_PRIM|OUTPUT_SEC, axio);
kfree(axio);
}
break;
-
- case CMD_AXI_CFG_ZSL: {
+ case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
uint32_t *axio = NULL;
- CDBG("%s, CMD_AXI_CFG_ZSL\n", __func__);
axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
GFP_ATOMIC);
if (!axio) {
@@ -3572,14 +3521,12 @@
rc = -EFAULT;
break;
}
- vfe32_config_axi(OUTPUT_1_2_AND_3, axio);
+ vfe32_config_axi(OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
kfree(axio);
}
break;
-
- case CMD_AXI_CFG_ZSL_ALL_CHNLS: {
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
uint32_t *axio = NULL;
- CDBG("%s, CMD_AXI_CFG_ZSL\n", __func__);
axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
GFP_ATOMIC);
if (!axio) {
@@ -3593,51 +3540,17 @@
rc = -EFAULT;
break;
}
- vfe32_config_axi(OUTPUT_ZSL_ALL_CHNLS, axio);
+ vfe32_config_axi(OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
kfree(axio);
}
break;
-
- case CMD_AXI_CFG_VIDEO: {
- uint32_t *axio = NULL;
- axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
- GFP_ATOMIC);
- if (!axio) {
- rc = -ENOMEM;
- break;
- }
-
- if (copy_from_user(axio, (void __user *)(vfecmd.value),
- vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
- kfree(axio);
- rc = -EFAULT;
- break;
- }
- vfe32_config_axi(OUTPUT_1_AND_3, axio);
- kfree(axio);
- }
- break;
-
- case CMD_AXI_CFG_VIDEO_ALL_CHNLS: {
- uint32_t *axio = NULL;
- axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
- GFP_ATOMIC);
- if (!axio) {
- rc = -ENOMEM;
- break;
- }
-
- if (copy_from_user(axio, (void __user *)(vfecmd.value),
- vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
- kfree(axio);
- rc = -EFAULT;
- break;
- }
- vfe32_config_axi(OUTPUT_ALL_CHNLS, axio);
- kfree(axio);
- }
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS:
+ pr_err("%s Invalid/Unsupported AXI configuration %x",
+ __func__, cmd->cmd_type);
break;
default:
+ pr_err("%s Unsupported AXI configuration %x ", __func__,
+ cmd->cmd_type);
break;
}
vfe32_config_done:
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index ff42c28..1adfffd 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -13,6 +13,8 @@
#ifndef __MSM_VFE32_H__
#define __MSM_VFE32_H__
+#include <linux/bitops.h>
+
#define TRUE 1
#define FALSE 0
@@ -191,17 +193,12 @@
ROLLOFF_RAM1_BANK1 = 0x15,
};
-enum VFE_STATE {
+enum vfe_output_state {
VFE_STATE_IDLE,
- VFE_STATE_ACTIVE
-};
-
-enum vfe_recording_state {
- VFE_REC_STATE_IDLE,
- VFE_REC_STATE_START_REQUESTED,
- VFE_REC_STATE_STARTED,
- VFE_REC_STATE_STOP_REQUESTED,
- VFE_REC_STATE_STOPPED,
+ VFE_STATE_START_REQUESTED,
+ VFE_STATE_STARTED,
+ VFE_STATE_STOP_REQUESTED,
+ VFE_STATE_STOPPED,
};
#define V32_CAMIF_OFF 0x000001E4
@@ -870,18 +867,23 @@
#define VFE_DMI_CFG 0x00000598
#define VFE_DMI_ADDR 0x0000059C
#define VFE_DMI_DATA_LO 0x000005A4
-#define VFE_BUS_IO_FORMAT_CFG 0x000006F8
+#define VFE_BUS_IO_FORMAT_CFG 0x000006F8
#define VFE_PIXEL_IF_CFG 0x000006FC
+#define VFE_VIOLATION_STATUS 0x000007B4
#define VFE33_DMI_DATA_HI 0x000005A0
#define VFE33_DMI_DATA_LO 0x000005A4
-#define VFE32_OUTPUT_MODE_PT (0x1 << 0)
-#define VFE32_OUTPUT_MODE_S (0x1 << 1)
-#define VFE32_OUTPUT_MODE_V (0x1 << 2)
-#define VFE32_OUTPUT_MODE_P (0x1 << 3)
-#define VFE32_OUTPUT_MODE_T (0x1 << 4)
-#define VFE32_OUTPUT_MODE_P_ALL_CHNLS (0x1 << 5)
+#define VFE32_OUTPUT_MODE_PT BIT(0)
+#define VFE32_OUTPUT_MODE_S BIT(1)
+#define VFE32_OUTPUT_MODE_V BIT(2)
+#define VFE32_OUTPUT_MODE_P BIT(3)
+#define VFE32_OUTPUT_MODE_T BIT(4)
+#define VFE32_OUTPUT_MODE_P_ALL_CHNLS BIT(5)
+#define VFE32_OUTPUT_MODE_PRIMARY BIT(6)
+#define VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS BIT(7)
+#define VFE32_OUTPUT_MODE_SECONDARY BIT(8)
+#define VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS BIT(9)
struct vfe_stats_control {
uint8_t ackPending;
@@ -912,11 +914,12 @@
int8_t stop_ack_pending;
int8_t reset_ack_pending;
int8_t update_ack_pending;
- enum vfe_recording_state recording_state;
+ enum vfe_output_state recording_state;
int8_t update_linear;
int8_t update_rolloff;
int8_t update_la;
int8_t update_gamma;
+ enum vfe_output_state liveshot_state;
spinlock_t tasklet_lock;
struct list_head tasklet_q;
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index fcf2495..7186e58 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -156,9 +156,7 @@
msm_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_IMAGE_SIZE_OFFSET);
msm_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
msm_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_SIZE_OFFSET);
- vpe_ctrl->in_h_w = *p;
msm_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_XY_OFFSET);
- CDBG("%s: in_h_w=0x%x", __func__, vpe_ctrl->in_h_w);
}
void vpe_output_plane_config(uint32_t *p)
@@ -168,7 +166,6 @@
msm_io_w(*(++p), vpe_ctrl->vpebase + VPE_OUT_YSTRIDE1_OFFSET);
msm_io_w(*(++p), vpe_ctrl->vpebase + VPE_OUT_SIZE_OFFSET);
msm_io_w(*(++p), vpe_ctrl->vpebase + VPE_OUT_XY_OFFSET);
- vpe_ctrl->pcbcr_dis_offset = *(++p);
}
static int vpe_operation_config(uint32_t *p)
@@ -187,9 +184,8 @@
vpe_ctrl->out_w = w;
vpe_ctrl->out_h = h;
}
- vpe_ctrl->dis_en = *p;
- CDBG("%s: out_w=%d, out_h=%d, dis_en=%d",
- __func__, vpe_ctrl->out_w, vpe_ctrl->out_h, vpe_ctrl->dis_en);
+ CDBG("%s: out_w=%d, out_h=%d", __func__, vpe_ctrl->out_w,
+ vpe_ctrl->out_h);
return 0;
}
@@ -202,7 +198,6 @@
uint32_t out_ROI_width, out_ROI_height;
uint32_t src_ROI_width, src_ROI_height;
- uint32_t rc = 0; /* default to no zoom. */
/*
* phase_step_x, phase_step_y, phase_init_x and phase_init_y
* are represented in fixed-point, unsigned 3.29 format
@@ -216,26 +211,7 @@
uint32_t yscale_filter_sel, xscale_filter_sel;
uint32_t scale_unit_sel_x, scale_unit_sel_y;
uint64_t numerator, denominator;
- if ((pcrop->src_w >= pcrop->dst_w) &&
- (pcrop->src_h >= pcrop->dst_h)) {
- CDBG(" =======VPE no zoom needed.\n");
- temp = msm_io_r(vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET)
- & 0xfffffffc;
- msm_io_w(temp, vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET);
-
-
- msm_io_w(0, vpe_ctrl->vpebase + VPE_SRC_XY_OFFSET);
-
- CDBG("vpe_ctrl->in_h_w = %d\n", vpe_ctrl->in_h_w);
- msm_io_w(vpe_ctrl->in_h_w , vpe_ctrl->vpebase +
- VPE_SRC_SIZE_OFFSET);
-
- return rc;
- }
- /* If fall through then scaler is needed.*/
-
- CDBG("========VPE zoom needed.\n");
/* assumption is both direction need zoom. this can be
improved. */
temp =
@@ -414,18 +390,6 @@
return 1;
}
-static inline void vpe_get_zoom_dis_xy(
- struct dis_offset_type *dis_offset,
- struct msm_pp_crop *pcrop,
- int32_t *zoom_dis_x,
- int32_t *zoom_dis_y)
-{
- *zoom_dis_x = dis_offset->dis_offset_x *
- pcrop->src_w / pcrop->dst_w;
- *zoom_dis_y = dis_offset->dis_offset_y *
- pcrop->src_h / pcrop->dst_h;
-}
-
int msm_vpe_is_busy(void)
{
int busy = 0;
@@ -596,7 +560,10 @@
spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
vpe_ctrl->pp_frame_info = pp_frame_info;
msm_vpe_cfg_update(
- &vpe_ctrl->pp_frame_info->pp_frame_cmd.crop);
+ &vpe_ctrl->pp_frame_info->pp_frame_cmd.crop);
+ CDBG("%s Sending frame idx %d id %d to VPE ", __func__,
+ pp_frame_info->src_frame.buf_idx,
+ pp_frame_info->src_frame.frame_id);
rc = msm_send_frame_to_vpe();
return rc;
}
@@ -644,7 +611,6 @@
break;
case VPE_CMD_INPUT_PLANE_UPDATE:
case VPE_CMD_FLUSH:
- case VPE_CMD_DIS_OFFSET_CFG:
default:
break;
}
diff --git a/drivers/media/video/msm/msm_vpe.h b/drivers/media/video/msm/msm_vpe.h
index 6d84f4e..46c9d2f 100644
--- a/drivers/media/video/msm/msm_vpe.h
+++ b/drivers/media/video/msm/msm_vpe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -91,12 +91,6 @@
VPE_STATE_ACTIVE,
};
-struct dis_offset_type {
- int32_t dis_offset_x;
- int32_t dis_offset_y;
- uint32_t frame_id;
-};
-
struct vpe_ctrl_type {
spinlock_t lock;
uint32_t irq_status;
@@ -105,14 +99,9 @@
void *extdata;
uint32_t extlen;
struct msm_vpe_callback *resp;
- uint32_t in_h_w;
uint32_t out_h; /* this is BEFORE rotation. */
uint32_t out_w; /* this is BEFORE rotation. */
- uint32_t dis_en;
struct timespec ts;
- struct dis_offset_type dis_offset;
- uint32_t pcbcr_before_dis;
- uint32_t pcbcr_dis_offset;
int output_type;
int frame_pack;
uint8_t pad_2k_bool;
@@ -149,7 +138,7 @@
struct vpe_input_plane_update_type {
struct vpe_src_size_packed src_roi_size;
- /* DIS updates this set. */
+ /* crop updates this set. */
struct vpe_src_xy_packed src_roi_offset;
/* input address*/
uint8_t *src_p0_addr;
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index c77cfc3..f31aece 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -331,6 +331,7 @@
.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx074_subdev_info),
.sensor_v4l2_subdev_ops = &imx074_subdev_ops,
.func_tbl = &imx074_func_tbl,
+ .clk_rate = MSM_SENSOR_MCLK_24HZ,
};
module_init(msm_sensor_init_module);
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 227e606..2c296618 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -445,26 +445,84 @@
return rc;
}
+static struct msm_cam_clk_info cam_clk_info[] = {
+ {"cam_clk", MSM_SENSOR_MCLK_24HZ},
+};
+
int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
{
int32_t rc = 0;
struct msm_camera_sensor_info *data = s_ctrl->sensordata;
CDBG("%s: %d\n", __func__, __LINE__);
- msm_sensor_probe_on(&s_ctrl->sensor_i2c_client->client->dev);
- msm_camio_clk_rate_set(MSM_SENSOR_MCLK_24HZ);
- rc = gpio_request(data->sensor_platform_info->sensor_reset,
- "SENSOR_NAME");
- if (!rc) {
- CDBG("%s: reset sensor\n", __func__);
- gpio_direction_output(data->sensor_platform_info->sensor_reset,
- 0);
- usleep_range(1000, 2000);
- gpio_set_value_cansleep(data->sensor_platform_info->
- sensor_reset, 1);
- usleep_range(4000, 5000);
- } else {
- CDBG("%s: gpio request fail", __func__);
+ s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
+ * data->sensor_platform_info->num_vreg, GFP_KERNEL);
+ if (!s_ctrl->reg_ptr) {
+ pr_err("%s: could not allocate mem for regulators\n",
+ __func__);
+ return -ENOMEM;
}
+
+ rc = msm_camera_request_gpio_table(data, 1);
+ if (rc < 0) {
+ pr_err("%s: request gpio failed\n", __func__);
+ goto request_gpio_failed;
+ }
+
+ rc = msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+ s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->reg_ptr, 1);
+ if (rc < 0) {
+ pr_err("%s: regulator on failed\n", __func__);
+ goto config_vreg_failed;
+ }
+
+ rc = msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+ s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->reg_ptr, 1);
+ if (rc < 0) {
+ pr_err("%s: enable regulator failed\n", __func__);
+ goto enable_vreg_failed;
+ }
+
+ rc = msm_camera_config_gpio_table(data, 1);
+ if (rc < 0) {
+ pr_err("%s: config gpio failed\n", __func__);
+ goto config_gpio_failed;
+ }
+
+ if (s_ctrl->clk_rate != 0)
+ cam_clk_info->clk_rate = s_ctrl->clk_rate;
+
+ rc = msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
+ cam_clk_info, &s_ctrl->cam_clk, ARRAY_SIZE(cam_clk_info), 1);
+ if (rc < 0) {
+ pr_err("%s: clk enable failed\n", __func__);
+ goto enable_clk_failed;
+ }
+
+ if (data->sensor_platform_info->ext_power_ctrl != NULL)
+ data->sensor_platform_info->ext_power_ctrl(1);
+
+ return rc;
+enable_clk_failed:
+ msm_camera_config_gpio_table(data, 0);
+config_gpio_failed:
+ msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+ s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->reg_ptr, 0);
+
+enable_vreg_failed:
+ msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+ s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->reg_ptr, 0);
+config_vreg_failed:
+ msm_camera_request_gpio_table(data, 0);
+request_gpio_failed:
+ kfree(s_ctrl->reg_ptr);
return rc;
}
@@ -472,10 +530,21 @@
{
struct msm_camera_sensor_info *data = s_ctrl->sensordata;
CDBG("%s\n", __func__);
- msm_sensor_probe_off(&s_ctrl->sensor_i2c_client->client->dev);
- gpio_set_value_cansleep(data->sensor_platform_info->sensor_reset, 0);
- usleep_range(1000, 2000);
- gpio_free(data->sensor_platform_info->sensor_reset);
+ if (data->sensor_platform_info->ext_power_ctrl != NULL)
+ data->sensor_platform_info->ext_power_ctrl(0);
+ msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
+ cam_clk_info, &s_ctrl->cam_clk, ARRAY_SIZE(cam_clk_info), 0);
+ msm_camera_config_gpio_table(data, 0);
+ msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+ s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->reg_ptr, 0);
+ msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+ s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->reg_ptr, 0);
+ msm_camera_request_gpio_table(data, 0);
+ kfree(s_ctrl->reg_ptr);
return 0;
}
@@ -530,6 +599,10 @@
}
s_ctrl->sensordata = client->dev.platform_data;
+ if (s_ctrl->sensordata == NULL) {
+ pr_err("%s: NULL sensor data\n", __func__);
+ return -EFAULT;
+ }
rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
if (rc < 0)
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index ba366e6..2b1be1e 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -166,6 +166,9 @@
uint8_t sensor_v4l2_subdev_info_size;
struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
struct msm_sensor_fn_t *func_tbl;
+ struct regulator **reg_ptr;
+ struct clk *cam_clk;
+ long clk_rate;
};
void msm_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl);
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index 6389498..246900e 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -492,6 +492,7 @@
.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov2720_subdev_info),
.sensor_v4l2_subdev_ops = &ov2720_subdev_ops,
.func_tbl = &ov2720_func_tbl,
+ .clk_rate = MSM_SENSOR_MCLK_24HZ,
};
module_init(msm_sensor_init_module);
diff --git a/drivers/media/video/msm/wfd/enc-subdev.c b/drivers/media/video/msm/wfd/enc-subdev.c
index abba5d4..00a688c 100644
--- a/drivers/media/video/msm/wfd/enc-subdev.c
+++ b/drivers/media/video/msm/wfd/enc-subdev.c
@@ -403,11 +403,12 @@
vcd_property_hdr.prop_id = VCD_I_CODEC;
vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
vcd_property_codec.codec = VCD_CODEC_H264;
+
switch (codec) {
- case V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC:
+ case V4L2_PIX_FMT_H264:
vcd_property_codec.codec = VCD_CODEC_H264;
break;
- case V4L2_MPEG_VIDEO_ENCODING_MPEG_1:
+ case V4L2_PIX_FMT_MPEG4:
vcd_property_codec.codec = VCD_CODEC_MPEG4;
break;
default:
@@ -418,39 +419,6 @@
&vcd_property_hdr, &vcd_property_codec);
}
-static long venc_get_codec(struct video_client_ctx *client_ctx, __s32 *codec)
-{
- struct vcd_property_codec vcd_property_codec;
- struct vcd_property_hdr vcd_property_hdr;
- int rc = 0;
-
- vcd_property_hdr.prop_id = VCD_I_CODEC;
- vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-
- rc = vcd_get_property(client_ctx->vcd_handle,
- &vcd_property_hdr, &vcd_property_codec);
-
- if (rc < 0) {
- WFD_MSG_ERR("Failed to get codec property");
- return rc;
- }
-
- switch (vcd_property_codec.codec) {
- case VCD_CODEC_H264:
- *codec = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
- break;
- case VCD_CODEC_MPEG4:
- *codec = V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
- break;
- default:
- WFD_MSG_ERR("Unrecognized codec");
- return -EINVAL;
- break;
- }
-
- return rc;
-}
-
static long venc_set_codec_level(struct video_client_ctx *client_ctx,
__s32 codec, __s32 level)
{
@@ -939,6 +907,12 @@
WFD_MSG_ERR("Invalid parameters\n");
return -EINVAL;
}
+ rc = venc_set_codec(client_ctx, fmt->fmt.pix.pixelformat);
+ if (rc) {
+ WFD_MSG_ERR("Failed to set codec, rc = %d\n", rc);
+ goto err;
+ }
+
rc = venc_set_frame_size(client_ctx, fmt->fmt.pix.height,
fmt->fmt.pix.width);
if (rc) {
@@ -1233,9 +1207,6 @@
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
rc = venc_set_bitrate_mode(client_ctx, ctrl->value);
break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- rc = venc_set_codec(client_ctx, ctrl->value);
- break;
case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
rc = venc_set_h264_intra_period(client_ctx, ctrl->value);
break;
@@ -1270,9 +1241,6 @@
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
rc = venc_get_bitrate_mode(client_ctx, &ctrl->value);
break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- rc = venc_get_codec(client_ctx, &ctrl->value);
- break;
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
rc = venc_get_codec_level(client_ctx, ctrl->id, &ctrl->value);
break;
diff --git a/drivers/media/video/msm/wfd/wfd-ioctl.c b/drivers/media/video/msm/wfd/wfd-ioctl.c
index 27a8888..93dd367 100644
--- a/drivers/media/video/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm/wfd/wfd-ioctl.c
@@ -490,9 +490,9 @@
return -EINVAL;
}
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_NV12) {
+ fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_H264) {
WFD_MSG_ERR("Only V4L2_BUF_TYPE_VIDEO_CAPTURE and "
- "V4L2_PIX_FMT_NV12 are supported\n");
+ "V4L2_PIX_FMT_H264 are supported\n");
return -EINVAL;
}
rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, SET_FORMAT,
@@ -707,7 +707,7 @@
fmt.fmt.pix.height = inst->height = DEFAULT_WFD_HEIGHT;
fmt.fmt.pix.width = inst->width = DEFAULT_WFD_WIDTH;
fmt.fmt.pix.pixelformat = inst->pixelformat
- = V4L2_PIX_FMT_NV12;
+ = V4L2_PIX_FMT_H264;
spin_unlock_irqrestore(&inst->inst_lock, flags);
wfdioc_s_fmt(filp, filp->private_data, &fmt);
return 0;
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index 37b935b..c12bed3 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -239,6 +239,7 @@
}
paddr = mem->msm_buffer->iova[0];
mem->mapped_phyaddr = paddr + addr_offset;
+ mem->addr_offset = addr_offset;
return rc;
}
EXPORT_SYMBOL_GPL(videobuf2_pmem_contig_user_get);
diff --git a/drivers/mfd/pm8018-core.c b/drivers/mfd/pm8018-core.c
index fc85a42..5c4b705 100644
--- a/drivers/mfd/pm8018-core.c
+++ b/drivers/mfd/pm8018-core.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -253,8 +253,8 @@
SMPS("8018_s4", "8018_s4_pc", 0x1E8, 0x1ED, 0x00C, 0x1EA, SMPS_1500),
SMPS("8018_s5", "8018_s5_pc", 0x1F0, 0x1F5, 0x00D, 0x1F2, SMPS_1500),
- /* name pc_name ctrl */
- VS("8018_lvs1", "8018_lvs1_pc", 0x060),
+ /* name pc_name ctrl test */
+ VS("8018_lvs1", "8018_lvs1_pc", 0x060, 0x061),
};
#define MAX_NAME_COMPARISON_LEN 32
diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c
index 8a9d289..ceb4210 100644
--- a/drivers/mfd/pm8038-core.c
+++ b/drivers/mfd/pm8038-core.c
@@ -313,9 +313,9 @@
FTSMPS("8038_s5", 0x025, 0x02E, 0x026, 0x032, SMPS_2000),
FTSMPS("8038_s6", 0x036, 0x03F, 0x037, 0x043, SMPS_2000),
- /* name pc_name ctrl */
- VS("8038_lvs1", "8038_lvs1_pc", 0x060),
- VS("8038_lvs2", "8038_lvs2_pc", 0x062),
+ /* name pc_name ctrl test */
+ VS("8038_lvs1", "8038_lvs1_pc", 0x060, 0x061),
+ VS("8038_lvs2", "8038_lvs2_pc", 0x062, 0x063),
};
#define MAX_NAME_COMPARISON_LEN 32
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 2c99a7f..e4d8bd5 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -412,16 +412,16 @@
SMPS("8921_s7", "8921_s7_pc", 0x1F0, 0x1F5, 0x012, 0x1F2, SMPS_1500),
SMPS("8921_s8", "8921_s8_pc", 0x1F8, 0x1FD, 0x013, 0x1FA, SMPS_1500),
- /* name pc_name ctrl */
- VS("8921_lvs1", "8921_lvs1_pc", 0x060),
- VS300("8921_lvs2", 0x062),
- VS("8921_lvs3", "8921_lvs3_pc", 0x064),
- VS("8921_lvs4", "8921_lvs4_pc", 0x066),
- VS("8921_lvs5", "8921_lvs5_pc", 0x068),
- VS("8921_lvs6", "8921_lvs6_pc", 0x06A),
- VS("8921_lvs7", "8921_lvs7_pc", 0x06C),
- VS300("8921_usb_otg", 0x06E),
- VS300("8921_hdmi_mvs", 0x070),
+ /* name pc_name ctrl test */
+ VS("8921_lvs1", "8921_lvs1_pc", 0x060, 0x061),
+ VS300("8921_lvs2", 0x062, 0x063),
+ VS("8921_lvs3", "8921_lvs3_pc", 0x064, 0x065),
+ VS("8921_lvs4", "8921_lvs4_pc", 0x066, 0x067),
+ VS("8921_lvs5", "8921_lvs5_pc", 0x068, 0x069),
+ VS("8921_lvs6", "8921_lvs6_pc", 0x06A, 0x06B),
+ VS("8921_lvs7", "8921_lvs7_pc", 0x06C, 0x06D),
+ VS300("8921_usb_otg", 0x06E, 0x06F),
+ VS300("8921_hdmi_mvs", 0x070, 0x071),
/* name ctrl */
NCP("8921_ncp", 0x090),
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index 283f985..eb0048a 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -132,6 +132,9 @@
#define UART_PATH_SEL_MASK 0x60
#define UART_PATH_SEL_SHIFT 0x5
+#define USB_ID_PU_EN_MASK 0x10 /* PM8921 family only */
+#define USB_ID_PU_EN_SHIFT 4
+
/* Shutdown/restart delays to allow for LDO 7/dVdd regulator load settling. */
#define PM8901_DELAY_AFTER_REG_DISABLE_MS 4
#define PM8901_DELAY_BEFORE_SHUTDOWN_MS 8
@@ -944,6 +947,48 @@
}
EXPORT_SYMBOL(pm8xxx_uart_gpio_mux_ctrl);
+/**
+ * pm8xxx_usb_id_pullup - Control a pullup for USB ID
+ *
+ * @enable: enable (1) or disable (0) the pullup
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_usb_id_pullup(int enable)
+{
+ struct pm8xxx_misc_chip *chip;
+ unsigned long flags;
+ int rc = -ENXIO;
+
+ spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+ /* Loop over all attached PMICs and call specific functions for them. */
+ list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+ switch (chip->version) {
+ case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8922:
+ case PM8XXX_VERSION_8917:
+ case PM8XXX_VERSION_8038:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8XXX_GPIO_MUX_CTRL, USB_ID_PU_EN_MASK,
+ enable << USB_ID_PU_EN_SHIFT);
+
+ if (rc)
+ pr_err("Fail: reg=%x, rc=%d\n",
+ REG_PM8XXX_GPIO_MUX_CTRL, rc);
+ break;
+ default:
+ /* Functionality not supported */
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_usb_id_pullup);
+
static int __pm8901_preload_dVdd(struct pm8xxx_misc_chip *chip)
{
int rc;
diff --git a/drivers/mfd/pm8xxx-pwm.c b/drivers/mfd/pm8xxx-pwm.c
index 523d3b6..05f02c4 100644
--- a/drivers/mfd/pm8xxx-pwm.c
+++ b/drivers/mfd/pm8xxx-pwm.c
@@ -27,8 +27,14 @@
#define PM8XXX_PWM_CHANNELS 3
-#define PM8XXX_LPG_BANKS 8
-#define PM8XXX_LPG_PWM_CHANNELS PM8XXX_LPG_BANKS
+/*
+ * For the lack of better term to distinguish functional
+ * differences, hereby, LPG version 0 (V0, v0) denotes
+ * PM8058/8921, and version 1 (V1, v1) denotes
+ * PM8922/8038.
+ */
+#define PM8XXX_LPG_V0_PWM_CHANNELS 8
+#define PM8XXX_LPG_V1_PWM_CHANNELS 6
#define PM8XXX_LPG_CTL_REGS 7
/* PM8XXX PWM */
@@ -149,32 +155,32 @@
#define NSEC_32768HZ (NSEC_PER_SEC / 32768)
#define NSEC_19P2MHZ (NSEC_PER_SEC / 19200000)
-#define CLK_PERIOD_MIN NSEC_19P2MHZ
-#define CLK_PERIOD_MAX NSEC_1024HZ
-
-#define NUM_LPG_PRE_DIVIDE 3 /* No default support for pre-divide = 6 */
+#define NUM_LPG_PRE_DIVIDE 4
#define NUM_PWM_PRE_DIVIDE 2
-#define PRE_DIVIDE_0 2
-#define PRE_DIVIDE_1 3
-#define PRE_DIVIDE_2 5
-
-#define PRE_DIVIDE_MIN PRE_DIVIDE_0
-#define PRE_DIVIDE_MAX PRE_DIVIDE_2
+#define PRE_DIVIDE_1 1 /* v1 */
+#define PRE_DIVIDE_2 2
+#define PRE_DIVIDE_3 3
+#define PRE_DIVIDE_5 5
+#define PRE_DIVIDE_6 6
static unsigned int pt_t[NUM_LPG_PRE_DIVIDE][NUM_CLOCKS] = {
- { PRE_DIVIDE_0 * NSEC_1024HZ,
- PRE_DIVIDE_0 * NSEC_32768HZ,
- PRE_DIVIDE_0 * NSEC_19P2MHZ,
- },
- { PRE_DIVIDE_1 * NSEC_1024HZ,
- PRE_DIVIDE_1 * NSEC_32768HZ,
- PRE_DIVIDE_1 * NSEC_19P2MHZ,
- },
{ PRE_DIVIDE_2 * NSEC_1024HZ,
PRE_DIVIDE_2 * NSEC_32768HZ,
PRE_DIVIDE_2 * NSEC_19P2MHZ,
},
+ { PRE_DIVIDE_3 * NSEC_1024HZ,
+ PRE_DIVIDE_3 * NSEC_32768HZ,
+ PRE_DIVIDE_3 * NSEC_19P2MHZ,
+ },
+ { PRE_DIVIDE_5 * NSEC_1024HZ,
+ PRE_DIVIDE_5 * NSEC_32768HZ,
+ PRE_DIVIDE_5 * NSEC_19P2MHZ,
+ },
+ { PRE_DIVIDE_6 * NSEC_1024HZ,
+ PRE_DIVIDE_6 * NSEC_32768HZ,
+ PRE_DIVIDE_6 * NSEC_19P2MHZ,
+ },
};
/* Private data */
@@ -1337,11 +1343,19 @@
if (version == PM8XXX_VERSION_8921 ||
version == PM8XXX_VERSION_8058 ||
- version == PM8XXX_VERSION_8922) {
+ version == PM8XXX_VERSION_8922 ||
+ version == PM8XXX_VERSION_8038) {
chip->is_lpg_supported = 1;
}
if (chip->is_lpg_supported) {
- chip->pwm_channels = PM8XXX_LPG_PWM_CHANNELS;
+ if (version == PM8XXX_VERSION_8922 ||
+ version == PM8XXX_VERSION_8038) {
+ for (i = 0; i < NUM_CLOCKS; i++)
+ pt_t[0][i] /= PRE_DIVIDE_2;
+ chip->pwm_channels = PM8XXX_LPG_V1_PWM_CHANNELS;
+ } else {
+ chip->pwm_channels = PM8XXX_LPG_V0_PWM_CHANNELS;
+ }
chip->pwm_total_pre_divs = NUM_LPG_PRE_DIVIDE;
} else {
chip->pwm_channels = PM8XXX_PWM_CHANNELS;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 9a99cf3..8f42e5b 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2817,10 +2817,9 @@
u8 phase)
{
int rc = 0;
- u8 grey_coded_phase_table[] = {0x0, 0x1, 0x3, 0x2, 0x6,
- 0x7, 0x5, 0x4, 0x8, 0x9,
- 0xB, 0xA, 0xE, 0xF, 0xD,
- 0xC};
+ u8 grey_coded_phase_table[] = {0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4,
+ 0xC, 0xD, 0xF, 0xE, 0xA, 0xB, 0x9,
+ 0x8};
unsigned long flags;
u32 config;
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 293c25d..2e80692 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -1318,6 +1318,8 @@
read_soc_params_raw(the_chip, &raw);
+ calculate_cc_uah(the_chip, raw.cc, &bms_end_cc_uah);
+
if (is_battery_full) {
unsigned long flags;
int fcc_uah, new_fcc_uah, delta_fcc_uah;
@@ -1355,10 +1357,9 @@
bms_end_percent = the_chip->end_percent;
bms_end_ocv_uv = raw.last_good_ocv_uv;
- calculate_cc_uah(the_chip, raw.cc, &bms_end_cc_uah);
if (the_chip->end_percent > the_chip->start_percent) {
- last_charge_increase =
+ last_charge_increase +=
the_chip->end_percent - the_chip->start_percent;
if (last_charge_increase > 100) {
last_chargecycles++;
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index c40f13e..51ec91c 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -263,6 +263,7 @@
enum pm8921_chg_hot_thr hot_thr;
};
+static int usb_max_current;
static int charging_disabled;
static int thermal_mitigation;
@@ -575,6 +576,22 @@
return 0;
}
+struct usb_ma_limit_entry {
+ int usb_ma;
+ u8 chg_iusb_value;
+};
+
+static struct usb_ma_limit_entry usb_ma_table[] = {
+ {100, 0},
+ {500, 1},
+ {700, 2},
+ {850, 3},
+ {900, 4},
+ {1100, 5},
+ {1300, 6},
+ {1500, 7},
+};
+
#define PM8921_CHG_IUSB_MASK 0x1C
#define PM8921_CHG_IUSB_MAX 7
#define PM8921_CHG_IUSB_MIN 0
@@ -591,6 +608,26 @@
temp);
}
+static int pm_chg_iusbmax_get(struct pm8921_chg_chip *chip, int *mA)
+{
+ u8 temp;
+ int i, rc;
+
+ *mA = 0;
+ rc = pm8xxx_readb(chip->dev->parent, PBL_ACCESS2, &temp);
+ if (rc) {
+ pr_err("err=%d reading PBL_ACCESS2\n", rc);
+ return rc;
+ }
+ temp &= PM8921_CHG_IUSB_MASK;
+ temp = temp >> 2;
+ for (i = ARRAY_SIZE(usb_ma_table) - 1; i >= 0; i--) {
+ if (usb_ma_table[i].chg_iusb_value == temp)
+ *mA = usb_ma_table[i].usb_ma;
+ }
+ return rc;
+}
+
#define PM8921_CHG_WD_MASK 0x1F
static int pm_chg_disable_wd(struct pm8921_chg_chip *chip)
{
@@ -1209,27 +1246,17 @@
}
}
-struct usb_ma_limit_entry {
- int usb_ma;
- u8 chg_iusb_value;
-};
-
-static struct usb_ma_limit_entry usb_ma_table[] = {
- {100, 0},
- {500, 1},
- {700, 2},
- {850, 3},
- {900, 4},
- {1100, 5},
- {1300, 6},
- {1500, 7},
-};
-
/* assumes vbus_lock is held */
static void __pm8921_charger_vbus_draw(unsigned int mA)
{
int i, rc;
+ if (usb_max_current && mA > usb_max_current) {
+ pr_warn("restricting usb current to %d instead of %d\n",
+ usb_max_current, mA);
+ mA = usb_max_current;
+ }
+
if (mA > 0 && mA <= 2) {
usb_chg_current = 0;
rc = pm_chg_iusbmax_set(the_chip,
@@ -2391,6 +2418,28 @@
param_get_uint,
&thermal_mitigation, 0644);
+static int set_usb_max_current(const char *val, struct kernel_param *kp)
+{
+ int ret, mA;
+ struct pm8921_chg_chip *chip = the_chip;
+
+ ret = param_set_int(val, kp);
+ if (ret) {
+ pr_err("error setting value %d\n", ret);
+ return ret;
+ }
+ if (chip) {
+ pr_warn("setting current max to %d\n", usb_max_current);
+ pm_chg_iusbmax_get(chip, &mA);
+ if (mA > usb_max_current)
+ pm8921_charger_vbus_draw(usb_max_current);
+ return 0;
+ }
+ return -EINVAL;
+}
+module_param_call(usb_max_current, set_usb_max_current, param_get_uint,
+ &usb_max_current, 0644);
+
static void free_irqs(struct pm8921_chg_chip *chip)
{
int i;
@@ -3200,6 +3249,7 @@
enable_irq_wake(chip->pmic_chg_irq[USBIN_UV_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[BAT_TEMP_OK_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[VBATDET_LOW_IRQ]);
+ enable_irq_wake(chip->pmic_chg_irq[FASTCHG_IRQ]);
/*
* if both the cool_temp_dc and warm_temp_dc are invalid device doesnt
* care for jeita compliance
diff --git a/drivers/regulator/pm8xxx-regulator.c b/drivers/regulator/pm8xxx-regulator.c
index 15a9cb1..94b028d 100644
--- a/drivers/regulator/pm8xxx-regulator.c
+++ b/drivers/regulator/pm8xxx-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,7 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/module.h>
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/kernel.h>
@@ -356,12 +357,21 @@
#define VS_PULL_DOWN_DISABLE 0x40
#define VS_PULL_DOWN_ENABLE 0x00
+#define VS_MODE_MASK 0x30
+#define VS_MODE_NORMAL 0x10
+#define VS_MODE_LPM 0x20
+
#define VS_PIN_CTRL_MASK 0x0F
#define VS_PIN_CTRL_EN0 0x08
#define VS_PIN_CTRL_EN1 0x04
#define VS_PIN_CTRL_EN2 0x02
#define VS_PIN_CTRL_EN3 0x01
+/* TEST register */
+#define VS_OCP_MASK 0x10
+#define VS_OCP_ENABLE 0x00
+#define VS_OCP_DISABLE 0x10
+
/* VS300 masks and values */
/* CTRL register */
@@ -372,6 +382,10 @@
#define VS300_PULL_DOWN_ENABLE_MASK 0x20
#define VS300_PULL_DOWN_ENABLE 0x20
+#define VS300_MODE_MASK 0x18
+#define VS300_MODE_NORMAL 0x00
+#define VS300_MODE_LPM 0x08
+
/* NCP masks and values */
/* CTRL register */
@@ -1900,9 +1914,32 @@
mutex_lock(&vreg->pc_lock);
- rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr, VS_ENABLE,
- VS_ENABLE_MASK, &vreg->ctrl_reg);
+ if (vreg->pdata.ocp_enable) {
+ /* Disable OCP. */
+ rc = pm8xxx_vreg_masked_write(vreg, vreg->test_addr,
+ VS_OCP_DISABLE, VS_OCP_MASK, &vreg->test_reg[0]);
+ if (rc)
+ goto done;
+ /* Enable the switch while OCP is disabled. */
+ rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr,
+ VS_ENABLE | VS_MODE_NORMAL,
+ VS_ENABLE_MASK | VS_MODE_MASK,
+ &vreg->ctrl_reg);
+ if (rc)
+ goto done;
+
+ /* Wait for inrush current to subside, then enable OCP. */
+ udelay(vreg->pdata.ocp_enable_time);
+ rc = pm8xxx_vreg_masked_write(vreg, vreg->test_addr,
+ VS_OCP_ENABLE, VS_OCP_MASK, &vreg->test_reg[0]);
+ } else {
+ /* Enable the switch without touching OCP. */
+ rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr, VS_ENABLE,
+ VS_ENABLE_MASK, &vreg->ctrl_reg);
+ }
+
+done:
if (!rc)
vreg->is_enabled = true;
@@ -1944,13 +1981,39 @@
struct pm8xxx_vreg *vreg = rdev_get_drvdata(rdev);
int rc;
- rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr, VS300_CTRL_ENABLE,
- VS300_CTRL_ENABLE_MASK, &vreg->ctrl_reg);
+ if (vreg->pdata.ocp_enable) {
+ /* Disable OCP. */
+ rc = pm8xxx_vreg_masked_write(vreg, vreg->test_addr,
+ VS_OCP_DISABLE, VS_OCP_MASK, &vreg->test_reg[0]);
+ if (rc)
+ goto done;
- if (rc)
+ /* Enable the switch while OCP is disabled. */
+ rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr,
+ VS300_CTRL_ENABLE | VS300_MODE_NORMAL,
+ VS300_CTRL_ENABLE_MASK | VS300_MODE_MASK,
+ &vreg->ctrl_reg);
+ if (rc)
+ goto done;
+
+ /* Wait for inrush current to subside, then enable OCP. */
+ udelay(vreg->pdata.ocp_enable_time);
+ rc = pm8xxx_vreg_masked_write(vreg, vreg->test_addr,
+ VS_OCP_ENABLE, VS_OCP_MASK, &vreg->test_reg[0]);
+ } else {
+ /* Enable the regulator without touching OCP. */
+ rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr,
+ VS300_CTRL_ENABLE, VS300_CTRL_ENABLE_MASK,
+ &vreg->ctrl_reg);
+ }
+
+done:
+ if (rc) {
vreg_err(vreg, "pm8xxx_vreg_masked_write failed, rc=%d\n", rc);
- else
+ } else {
+ vreg->is_enabled = true;
pm8xxx_vreg_show_state(rdev, PM8XXX_REGULATOR_ACTION_ENABLE);
+ }
return rc;
}
@@ -2805,6 +2868,14 @@
return rc;
}
+ /* Save the current test register state. */
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+ &vreg->test_reg[0]);
+ if (rc) {
+ vreg_err(vreg, "pm8xxx_readb failed, rc=%d\n", rc);
+ return rc;
+ }
+
if (is_real) {
/* Set pull down enable based on platform data. */
rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr,
@@ -2833,6 +2904,14 @@
return rc;
}
+ /* Save the current test register state. */
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+ &vreg->test_reg[0]);
+ if (rc) {
+ vreg_err(vreg, "pm8xxx_readb failed, rc=%d\n", rc);
+ return rc;
+ }
+
/* Set pull down enable based on platform data. */
rc = pm8xxx_vreg_masked_write(vreg, vreg->ctrl_addr,
(vreg->pdata.pull_down_enable ? VS300_PULL_DOWN_ENABLE : 0),
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 1ac301f..6733396 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -25,6 +25,8 @@
#define SLIM_HDL_TO_FLOW(hdl) (((u32)(hdl) & 0xFF0000) >> 16)
#define SLIM_HDL_TO_PORT(hdl) ((u32)(hdl) & 0xFF)
+#define SLIM_HDL_TO_CHIDX(hdl) ((u16)(hdl) & 0xFF)
+
#define SLIM_SLAVE_PORT(p, la) (((la)<<16) | (p))
#define SLIM_MGR_PORT(p) ((0xFF << 16) | (p))
#define SLIM_LA_MANAGER 0xFF
@@ -1104,75 +1106,117 @@
}
/*
- * slim_connect_ports: Connect port(s) to channel.
+ * slim_connect_src: Connect source port to channel.
* @sb: client handle
- * @srch: source handles to be connected to this channel
- * @nrsc: number of source ports
- * @sinkh: sink handle to be connected to this channel
+ * @srch: source handle to be connected to this channel
* @chanh: Channel with which the ports need to be associated with.
- * Per slimbus specification, a channel may have multiple source-ports and 1
- * sink port.Channel specified in chanh needs to be allocated first.
+ * Per slimbus specification, a channel may have 1 source port.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if source is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
*/
-int slim_connect_ports(struct slim_device *sb, u32 *srch, int nsrc, u32 sinkh,
- u16 chanh)
+int slim_connect_src(struct slim_device *sb, u32 srch, u16 chanh)
+{
+ struct slim_controller *ctrl = sb->ctrl;
+ int ret;
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
+ struct slim_ich *slc = &ctrl->chans[chan];
+ enum slim_port_flow flow = SLIM_HDL_TO_FLOW(srch);
+
+ if (flow != SLIM_SRC)
+ return -EINVAL;
+
+ mutex_lock(&ctrl->m_ctrl);
+
+ if (slc->state == SLIM_CH_FREE) {
+ ret = -ENOTCONN;
+ goto connect_src_err;
+ }
+ /*
+ * Once channel is removed, its ports can be considered disconnected
+ * So its ports can be reassigned. Source port is zeroed
+ * when channel is deallocated.
+ */
+ if (slc->srch) {
+ ret = -EALREADY;
+ goto connect_src_err;
+ }
+
+ ret = connect_port_ch(ctrl, chan, srch, SLIM_SRC);
+
+ if (!ret)
+ slc->srch = srch;
+
+connect_src_err:
+ mutex_unlock(&ctrl->m_ctrl);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(slim_connect_src);
+
+/*
+ * slim_connect_sink: Connect sink port(s) to channel.
+ * @sb: client handle
+ * @sinkh: sink handle(s) to be connected to this channel
+ * @nsink: number of sinks
+ * @chanh: Channel with which the ports need to be associated with.
+ * Per slimbus specification, a channel may have multiple sink-ports.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if sink is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
+ */
+int slim_connect_sink(struct slim_device *sb, u32 *sinkh, int nsink, u16 chanh)
{
struct slim_controller *ctrl = sb->ctrl;
int j;
int ret = 0;
- u8 chan = (u8)(chanh & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
struct slim_ich *slc = &ctrl->chans[chan];
+ if (!sinkh || !nsink)
+ return -EINVAL;
+
mutex_lock(&ctrl->m_ctrl);
- /* Make sure the channel is not already pending reconf. or active */
- if (slc->state >= SLIM_CH_PENDING_ACTIVE) {
- dev_err(&ctrl->dev, "Channel %d already active", chan);
- ret = -EISCONN;
- goto connect_port_err;
- }
/*
* Once channel is removed, its ports can be considered disconnected
- * So its ports can be reassigned. Source port array is freed
- * when channel is deallocated.
+ * So its ports can be reassigned. Sink ports are freed when channel
+ * is deallocated.
*/
- slc->srch = krealloc(slc->srch, (sizeof(u32) * nsrc), GFP_KERNEL);
- if (!slc->srch) {
- ret = -ENOMEM;
- goto connect_port_err;
+ if (slc->state == SLIM_CH_FREE) {
+ ret = -ENOTCONN;
+ goto connect_sink_err;
}
- /* connect source */
- for (j = 0; j < nsrc; j++) {
- ret = connect_port_ch(ctrl, chan, srch[j], SLIM_SRC);
+ for (j = 0; j < nsink; j++) {
+ enum slim_port_flow flow = SLIM_HDL_TO_FLOW(sinkh[j]);
+ if (flow != SLIM_SINK)
+ ret = -EINVAL;
+ else
+ ret = connect_port_ch(ctrl, chan, sinkh[j], SLIM_SINK);
if (ret) {
- for ( ; j >= 0 ; j--)
- disconnect_port_ch(ctrl,
- srch[j]);
- kfree(slc->srch);
- slc->srch = NULL;
- goto connect_port_err;
+ for (j = j - 1; j >= 0; j--)
+ disconnect_port_ch(ctrl, sinkh[j]);
+ goto connect_sink_err;
}
}
- /* connect sink */
- ret = connect_port_ch(ctrl, chan, sinkh, SLIM_SINK);
- if (ret) {
- for (j = 0; j < nsrc; j++)
- disconnect_port_ch(ctrl, srch[j]);
- kfree(slc->srch);
- slc->srch = NULL;
- goto connect_port_err;
+
+ slc->sinkh = krealloc(slc->sinkh, (sizeof(u32) * (slc->nsink + nsink)),
+ GFP_KERNEL);
+ if (!slc->sinkh) {
+ ret = -ENOMEM;
+ for (j = 0; j < nsink; j++)
+ disconnect_port_ch(ctrl, sinkh[j]);
+ goto connect_sink_err;
}
- memcpy(slc->srch, srch, (sizeof(u32) * nsrc));
- slc->nsrc = nsrc;
- if (sinkh)
- slc->sinkh = sinkh;
+ memcpy(slc->sinkh + slc->nsink, sinkh, (sizeof(u32) * nsink));
+ slc->nsink += nsink;
-connect_port_err:
+connect_sink_err:
mutex_unlock(&ctrl->m_ctrl);
return ret;
}
-EXPORT_SYMBOL_GPL(slim_connect_ports);
+EXPORT_SYMBOL_GPL(slim_connect_sink);
/*
* slim_disconnect_ports: Disconnect port(s) from channel
@@ -1332,8 +1376,8 @@
slc->state = SLIM_CH_ALLOCATED;
slc->newintr = 0;
slc->newoff = 0;
- for (i = 0; i < slc->nsrc; i++) {
- ph = slc->srch[i];
+ for (i = 0; i < slc->nsink; i++) {
+ ph = slc->sinkh[i];
la = SLIM_HDL_TO_LA(ph);
/*
* For ports managed by manager's ported device, no need to send
@@ -1344,11 +1388,15 @@
ctrl->ports[SLIM_HDL_TO_PORT(ph)].state = SLIM_P_UNCFG;
}
- ph = slc->sinkh;
+ ph = slc->srch;
la = SLIM_HDL_TO_LA(ph);
if (la == SLIM_LA_MANAGER)
ctrl->ports[SLIM_HDL_TO_PORT(ph)].state = SLIM_P_UNCFG;
+ kfree(slc->sinkh);
+ slc->sinkh = NULL;
+ slc->srch = 0;
+ slc->nsink = 0;
return 0;
}
@@ -1608,7 +1656,7 @@
int slim_dealloc_ch(struct slim_device *sb, u16 chanh)
{
struct slim_controller *ctrl = sb->ctrl;
- u8 chan = (u8)(chanh & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
struct slim_ich *slc = &ctrl->chans[chan];
if (!ctrl)
return -EINVAL;
@@ -1631,8 +1679,6 @@
return -EISCONN;
}
slc->ref--;
- kfree(slc->srch);
- slc->srch = NULL;
slc->state = SLIM_CH_FREE;
mutex_unlock(&ctrl->m_ctrl);
dev_dbg(&ctrl->dev, "remove chan:%d,hdl:%d,ref:%d",
@@ -1647,7 +1693,7 @@
*/
enum slim_ch_state slim_get_ch_state(struct slim_device *sb, u16 chanh)
{
- u8 chan = (u8)(chanh & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
struct slim_ich *slc = &sb->ctrl->chans[chan];
return slc->state;
}
@@ -1678,7 +1724,7 @@
return -EINVAL;
mutex_lock(&ctrl->m_ctrl);
for (i = 0; i < nchan; i++) {
- u8 chan = (u8)(chanh[i] & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
struct slim_ich *slc = &ctrl->chans[chan];
dev_dbg(&ctrl->dev, "define_ch: ch:%d, state:%d", chan,
(int)ctrl->chans[chan].state);
@@ -1713,7 +1759,7 @@
if (grp)
*grph = chanh[0];
for (i = 0; i < nchan; i++) {
- u8 chan = (u8)(chanh[i] & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
struct slim_ich *slc = &ctrl->chans[chan];
if (slc->state == SLIM_CH_ALLOCATED)
slc->state = SLIM_CH_DEFINED;
@@ -2265,7 +2311,7 @@
for (; last > 0; last--) {
struct slim_ich *slc1 = slc;
struct slim_ich *slc2;
- u8 next = (u8)(slc1->nextgrp & 0xFF);
+ u8 next = SLIM_HDL_TO_CHIDX(slc1->nextgrp);
slc2 = &ctrl->chans[next];
for (second = 1; second <= last && slc2 &&
(slc2->state == SLIM_CH_ACTIVE ||
@@ -2280,7 +2326,7 @@
break;
}
slc1 = slc2;
- next = (u8)(slc1->nextgrp & 0xFF);
+ next = SLIM_HDL_TO_CHIDX(slc1->nextgrp);
slc2 = &ctrl->chans[next];
}
if (slc2 == NULL)
@@ -2692,7 +2738,7 @@
struct slim_ich *slc;
int ret = 0;
/* Get rid of the group flag in MSB if any */
- u8 chan = (u8)(chanh & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
mutex_lock(&sb->sldev_reconf);
mutex_lock(&ctrl->m_ctrl);
do {
@@ -2729,7 +2775,7 @@
}
if (!(slc->nextgrp & SLIM_END_GRP))
- chan = (u8)(slc->nextgrp & 0xFF);
+ chan = SLIM_HDL_TO_CHIDX(slc->nextgrp);
} while (!(slc->nextgrp & SLIM_END_GRP));
mutex_unlock(&ctrl->m_ctrl);
if (!ret && commit == true)
diff --git a/drivers/staging/qcache/fmem.c b/drivers/staging/qcache/fmem.c
index 489d27a..d12c8e8 100644
--- a/drivers/staging/qcache/fmem.c
+++ b/drivers/staging/qcache/fmem.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -51,12 +51,14 @@
{
struct fmem_platform_data *pdata = pdev->dev.platform_data;
- if (!pdata->size)
+ fmem_data.phys = pdata->phys + pdata->reserved_size;
+ fmem_data.size = pdata->size - pdata->reserved_size;
+ fmem_data.reserved_size = pdata->reserved_size;
+
+ if (!fmem_data.size)
return -ENODEV;
- fmem_data.phys = pdata->phys;
- fmem_data.size = pdata->size;
- fmem_data.area = get_vm_area(pdata->size, VM_IOREMAP);
+ fmem_data.area = get_vm_area(fmem_data.size, VM_IOREMAP);
if (!fmem_data.area)
return -ENOMEM;
@@ -177,7 +179,7 @@
if (fmem_state == FMEM_UNINITIALIZED) {
if (new_state == FMEM_T_STATE) {
- tmem_enable(false);
+ tmem_enable();
create_sysfs = 1;
goto out_set;
}
@@ -194,7 +196,7 @@
ret = PTR_ERR(v);
goto out;
}
- tmem_enable(true);
+ tmem_enable();
} else {
tmem_disable();
fmem_unmap_virtual_area();
diff --git a/drivers/staging/qcache/tmem.c b/drivers/staging/qcache/tmem.c
index 8c9049c..e5c3f30 100644
--- a/drivers/staging/qcache/tmem.c
+++ b/drivers/staging/qcache/tmem.c
@@ -810,26 +810,24 @@
}
/* The following must be called with tmem state locked */
-static void tmem_reset(void)
+static void tmem_cleanup(void)
{
(*tmem_hostops.flush_all_obj)();
}
-void tmem_enable(bool reset)
+void tmem_enable(void)
{
pr_info("turning tmem on\n");
tmem_enabled = true;
- if (!reset)
- return;
-
- tmem_reset();
(*tmem_hostops.control)(false);
}
void tmem_disable(void)
{
pr_info("turning tmem off\n");
- (*tmem_hostops.control)(true);
tmem_enabled = false;
+
+ tmem_cleanup();
+ (*tmem_hostops.control)(true);
}
diff --git a/drivers/staging/qcache/tmem.h b/drivers/staging/qcache/tmem.h
index 9f6bfbb..dd8a6ea 100644
--- a/drivers/staging/qcache/tmem.h
+++ b/drivers/staging/qcache/tmem.h
@@ -207,6 +207,6 @@
extern int tmem_flush_pool(struct tmem_pool *);
extern void tmem_new_pool(struct tmem_pool *, uint32_t);
-extern void tmem_enable(bool);
+extern void tmem_enable(void);
extern void tmem_disable(void);
#endif /* _TMEM_H */
diff --git a/drivers/thermal/msm8960_tsens.c b/drivers/thermal/msm8960_tsens.c
index f2be9dc..2a2166a 100644
--- a/drivers/thermal/msm8960_tsens.c
+++ b/drivers/thermal/msm8960_tsens.c
@@ -176,7 +176,6 @@
TSENS_TRDY_RDY_MAX_TIME);
tmdev->prev_reading_avail = true;
}
-
code = readl_relaxed(TSENS_S0_STATUS_ADDR +
(sensor_num << TSENS_STATUS_ADDR_OFFSET));
*temp = tsens_tz_code_to_degC(code, sensor_num);
@@ -726,7 +725,7 @@
tmdev->sensor[i].calib_data_backup;
if (!tmdev->sensor[i].calib_data) {
- pr_err("%s: No temperature sensor:%d data for"
+ WARN(1, "%s: No temperature sensor:%d data for"
" calibration in QFPROM!\n", __func__, i);
return -ENODEV;
}
@@ -789,12 +788,14 @@
rc = tsens_check_version_support();
if (rc < 0) {
kfree(tmdev);
+ tmdev = NULL;
return rc;
}
rc = tsens_calib_sensors();
if (rc < 0) {
kfree(tmdev);
+ tmdev = NULL;
return rc;
}
@@ -846,6 +847,7 @@
fail:
tsens_disable_mode();
kfree(tmdev);
+ tmdev = NULL;
mb();
return rc;
}
@@ -860,6 +862,7 @@
for (i = 0; i < tmdev->tsens_num_sensor; i++)
thermal_zone_device_unregister(tmdev->sensor[i].tz_dev);
kfree(tmdev);
+ tmdev = NULL;
}
module_init(tsens_tm_init);
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 25290ba..ed80b1b 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -75,7 +75,7 @@
tsens_dev.sensor_num = DEF_TEMP_SENSOR;
ret = tsens_get_temp(&tsens_dev, &temp);
if (ret) {
- pr_err("msm_thermal: Unable to read TSENS sensor %d\n",
+ pr_debug("msm_thermal: Unable to read TSENS sensor %d\n",
tsens_dev.sensor_num);
goto reschedule;
}
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index ee7a2a9..c0c6c1e 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -1493,6 +1493,7 @@
}
static struct platform_driver android_platform_driver = {
+ .probe = android_probe,
.driver = { .name = "android_usb"},
};
@@ -1527,7 +1528,7 @@
composite_driver.setup = android_setup;
composite_driver.disconnect = android_disconnect;
- ret = platform_driver_probe(&android_platform_driver, android_probe);
+ ret = platform_driver_register(&android_platform_driver);
if (ret) {
pr_err("%s(): Failed to register android"
"platform driver\n", __func__);
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index 10a9256..987ae65 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -525,7 +525,6 @@
if (rc) {
ERROR(dev->cdev, "can't enable %s, result %d\n",
dev->in->name, rc);
- dev->in->driver_data = NULL;
return rc;
}
dev->out->driver_data = dev;
@@ -534,8 +533,6 @@
ERROR(dev->cdev, "can't enable %s, result %d\n",
dev->out->name, rc);
usb_ep_disable(dev->in);
- dev->in->driver_data = NULL;
- dev->out->driver_data = NULL;
return rc;
}
schedule_work(&dev->config_work);
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index f59b683..2049dc0 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -5,7 +5,7 @@
* Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
* Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
* Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -116,6 +116,8 @@
atomic_t online;
atomic_t notify_count;
+ struct platform_driver pdrv;
+ u8 is_pdrv_used;
struct rmnet_smd_ch_info smd_ctl;
struct rmnet_smd_ch_info smd_data;
@@ -134,6 +136,8 @@
unsigned long cpkts_to_modem;
};
+static struct rmnet_smd_dev *rmnet_smd;
+
static struct usb_interface_descriptor rmnet_smd_interface_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
@@ -856,6 +860,10 @@
list_add_tail(&qmi->list, &dev->qmi_resp_pool);
}
+ if (dev->is_pdrv_used) {
+ platform_driver_unregister(&dev->pdrv);
+ dev->is_pdrv_used = 0;
+ }
}
/* SMD close may sleep
@@ -894,7 +902,18 @@
ret = smd_open(rmnet_ctl_ch, &dev->smd_ctl.ch,
&dev->smd_ctl, rmnet_smd_event_notify);
if (ret) {
- ERROR(cdev, "Unable to open control smd channel\n");
+ ERROR(cdev, "Unable to open control smd channel: %d\n", ret);
+ /*
+ * Register platform driver to be notified in case SMD channels
+ * later becomes ready to be opened.
+ */
+ ret = platform_driver_register(&dev->pdrv);
+ if (ret)
+ ERROR(cdev, "Platform driver %s register failed %d\n",
+ dev->pdrv.driver.name, ret);
+ else
+ dev->is_pdrv_used = 1;
+
return;
}
wait_event(dev->smd_ctl.wait, test_bit(CH_OPENED,
@@ -916,6 +935,15 @@
rmnet_smd_start_rx(dev);
}
+static int rmnet_smd_ch_probe(struct platform_device *pdev)
+{
+ DBG(rmnet_smd->cdev, "Probe called for device: %s\n", pdev->name);
+
+ queue_work(rmnet_smd->wq, &rmnet_smd->connect_work);
+
+ return 0;
+}
+
/* SMD open may sleep.
* Schedule a work to open smd channels and enable
* endpoints if smd channels are opened successfully.
@@ -1272,6 +1300,8 @@
if (!dev)
return -ENOMEM;
+ rmnet_smd = dev;
+
dev->wq = create_singlethread_workqueue("k_rmnet_work");
if (!dev->wq) {
ret = -ENOMEM;
@@ -1299,6 +1329,10 @@
init_waitqueue_head(&dev->smd_ctl.wait);
init_waitqueue_head(&dev->smd_data.wait);
+ dev->pdrv.probe = rmnet_smd_ch_probe;
+ dev->pdrv.driver.name = CONFIG_RMNET_SMD_CTL_CHANNEL;
+ dev->pdrv.driver.owner = THIS_MODULE;
+
INIT_LIST_HEAD(&dev->qmi_req_pool);
INIT_LIST_HEAD(&dev->qmi_req_q);
INIT_LIST_HEAD(&dev->qmi_resp_pool);
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index d9a901b..de8c8ed 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -477,7 +477,6 @@
if (gser->notify->driver_data) {
DBG(cdev, "reset generic ctl ttyGS%d\n", gser->port_num);
usb_ep_disable(gser->notify);
- gser->notify->driver_data = NULL;
}
gser->notify_desc = ep_choose(cdev->gadget,
gser->hs.notify,
@@ -520,7 +519,6 @@
#ifdef CONFIG_MODEM_SUPPORT
usb_ep_fifo_flush(gser->notify);
usb_ep_disable(gser->notify);
- gser->notify->driver_data = NULL;
#endif
gser->online = 0;
}
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ca298cd..0360f56 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -2766,17 +2766,14 @@
if (fsg->bulk_in_enabled) {
usb_ep_disable(fsg->bulk_in);
fsg->bulk_in_enabled = 0;
- fsg_bulk_in->driver_data = NULL;
}
if (fsg->bulk_out_enabled) {
usb_ep_disable(fsg->bulk_out);
fsg->bulk_out_enabled = 0;
- fsg_bulk_out->driver_data = NULL;
}
if (fsg->intr_in_enabled) {
usb_ep_disable(fsg->intr_in);
fsg->intr_in_enabled = 0;
- fsg_intr_in->driver_data = NULL;
}
fsg->running = 0;
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index edba510..a55fc77 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -59,7 +59,7 @@
struct grmnet *port_usb;
spinlock_t port_lock;
- struct work_struct connect_w;
+ struct delayed_work connect_w;
};
static struct rmnet_ctrl_ports {
@@ -320,7 +320,7 @@
static void grmnet_ctrl_smd_connect_w(struct work_struct *w)
{
struct rmnet_ctrl_port *port =
- container_of(w, struct rmnet_ctrl_port, connect_w);
+ container_of(w, struct rmnet_ctrl_port, connect_w.work);
struct smd_ch_info *c = &port->ctrl_ch;
unsigned long flags;
int ret;
@@ -332,8 +332,16 @@
ret = smd_open(c->name, &c->ch, port, grmnet_ctrl_smd_notify);
if (ret) {
- pr_err("%s: Unable to open smd ch:%s err:%d\n",
- __func__, c->name, ret);
+ if (ret == -EAGAIN) {
+ /* port not ready - retry */
+ pr_debug("%s: SMD port not ready - rescheduling:%s err:%d\n",
+ __func__, c->name, ret);
+ queue_delayed_work(grmnet_ctrl_wq, &port->connect_w,
+ msecs_to_jiffies(250));
+ } else {
+ pr_err("%s: unable to open smd port:%s err:%d\n",
+ __func__, c->name, ret);
+ }
return;
}
@@ -370,7 +378,7 @@
gr->notify_modem = gsmd_ctrl_send_cbits_tomodem;
spin_unlock_irqrestore(&port->port_lock, flags);
- queue_work(grmnet_ctrl_wq, &port->connect_w);
+ queue_delayed_work(grmnet_ctrl_wq, &port->connect_w, 0);
return 0;
}
@@ -442,7 +450,8 @@
/* if usb is online, try opening smd_ch */
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_usb)
- queue_work(grmnet_ctrl_wq, &port->connect_w);
+ queue_delayed_work(grmnet_ctrl_wq,
+ &port->connect_w, 0);
spin_unlock_irqrestore(&port->port_lock, flags);
break;
@@ -503,7 +512,7 @@
port->port_num = portno;
spin_lock_init(&port->port_lock);
- INIT_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
+ INIT_DELAYED_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
c = &port->ctrl_ch;
c->name = rmnet_ctrl_names[portno];
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index eb76b30..896f21b 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1030,7 +1030,9 @@
return;
if (motg->pdata->vbus_power) {
- motg->pdata->vbus_power(on);
+ ret = motg->pdata->vbus_power(on);
+ if (!ret)
+ vbus_is_on = on;
return;
}
@@ -1862,7 +1864,6 @@
otg->state = OTG_STATE_B_PERIPHERAL;
break;
case USB_SDP_CHARGER:
- msm_otg_notify_charger(motg, IUNIT);
msm_otg_start_peripheral(otg, 1);
otg->state = OTG_STATE_B_PERIPHERAL;
break;
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h
index c47b6ec..de8d490 100644
--- a/drivers/usb/serial/usb-wwan.h
+++ b/drivers/usb/serial/usb-wwan.h
@@ -31,10 +31,10 @@
/* per port private data */
-#define N_IN_URB 4
-#define N_OUT_URB 4
-#define IN_BUFLEN 4096
-#define OUT_BUFLEN 4096
+#define N_IN_URB 5
+#define N_OUT_URB 5
+#define IN_BUFLEN 65536
+#define OUT_BUFLEN 65536
struct usb_wwan_intf_private {
spinlock_t susp_lock;
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index fcf4b08..2a08101 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -410,6 +410,7 @@
tty->raw = 1;
tty->real_raw = 1;
+ set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);
dbg("%s", __func__);
/* Start reading from the IN endpoint */
@@ -552,7 +553,7 @@
init_usb_anchor(&portdata->delayed);
for (j = 0; j < N_IN_URB; j++) {
- buffer = (u8 *) __get_free_page(GFP_KERNEL);
+ buffer = kmalloc(IN_BUFLEN, GFP_KERNEL);
if (!buffer)
goto bail_out_error;
portdata->in_buffer[j] = buffer;
@@ -581,8 +582,7 @@
kfree(portdata->out_buffer[j]);
bail_out_error:
for (j = 0; j < N_IN_URB; j++)
- if (portdata->in_buffer[j])
- free_page((unsigned long)portdata->in_buffer[j]);
+ kfree(portdata->in_buffer[j]);
kfree(portdata);
return 1;
}
@@ -628,8 +628,7 @@
for (j = 0; j < N_IN_URB; j++) {
usb_free_urb(portdata->in_urbs[j]);
- free_page((unsigned long)
- portdata->in_buffer[j]);
+ kfree(portdata->in_buffer[j]);
portdata->in_urbs[j] = NULL;
}
for (j = 0; j < N_OUT_URB; j++) {
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 1449c8e..512480c 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1326,10 +1326,9 @@
struct msm_fb_panel_data *pdata = NULL;
int rc;
resource_size_t size ;
+ unsigned long flag;
#ifdef CONFIG_FB_MSM_MDP40
int intf, if_no;
-#else
- unsigned long flag;
#endif
#if defined(CONFIG_FB_MSM_MIPI_DSI) && defined(CONFIG_FB_MSM_MDP40)
struct mipi_panel_info *mipi;
@@ -1474,6 +1473,17 @@
mfd->vsync_gpio = -1;
#ifdef CONFIG_FB_MSM_MDP40
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ mdp_intr_mask |= INTR_OVERLAY0_DONE;
+ if (mdp_hw_revision < MDP4_REVISION_V2_1) {
+ /* dmas dmap switch */
+ mdp_intr_mask |= INTR_DMA_S_DONE;
+ }
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
if (mfd->panel.type == EBI2_PANEL)
intf = EBI2_INTF;
else
@@ -1530,10 +1540,8 @@
case MIPI_CMD_PANEL:
#ifndef CONFIG_FB_MSM_MDP303
mfd->dma_fnc = mdp4_dsi_cmd_overlay;
-#ifdef CONFIG_FB_MSM_MDP40
mipi = &mfd->panel_info.mipi;
configure_mdp_core_clk_table((mipi->dsi_pclk_rate) * 3 / 2);
-#endif
if (mfd->panel_info.pdest == DISPLAY_1) {
if_no = PRIMARY_INTF_SEL;
mfd->dma = &dma2_data;
@@ -1544,6 +1552,13 @@
mfd->lut_update = mdp_lut_update_nonlcdc;
mfd->do_histogram = mdp_do_histogram;
mdp4_display_intf_sel(if_no, DSI_CMD_INTF);
+
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ mdp_intr_mask |= INTR_OVERLAY0_DONE;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
#else
mfd->dma_fnc = mdp_dma2_update;
mfd->do_histogram = mdp_do_histogram;
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index db1580e..3862823 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -130,8 +130,7 @@
#define INTR_OVERLAY2_DONE BIT(30)
#ifdef CONFIG_FB_MSM_OVERLAY
-#define MDP4_ANY_INTR_MASK (INTR_OVERLAY0_DONE|INTR_DMA_S_DONE | \
- INTR_DMA_P_HISTOGRAM)
+#define MDP4_ANY_INTR_MASK (INTR_DMA_P_HISTOGRAM)
#else
#define MDP4_ANY_INTR_MASK (INTR_DMA_P_DONE| \
INTR_DMA_P_HISTOGRAM)
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index a262cc4..3a1a9aa 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -455,7 +455,7 @@
if (!(data & 0x1) || (pipe == NULL))
return;
wait_for_completion_timeout(&dtv_pipe->comp,
- msecs_to_jiffies(VSYNC_PERIOD));
+ msecs_to_jiffies(VSYNC_PERIOD*2));
mdp_disable_irq(MDP_OVERLAY1_TERM);
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index d2969b6..51a72c8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1457,6 +1457,7 @@
vcd_status = VCD_S_SUCCESS;
}
}
+ break;
case VCD_I_INTRA_REFRESH:
{
struct vcd_property_intra_refresh_mb_number
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index 795d1e3..c32ac81 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -255,11 +255,11 @@
VCDRES_MSG_LOW("%s(): Enabling the clocks\n", __func__);
if (resource_context.vcodec_clk &&
resource_context.vcodec_pclk) {
- if (clk_enable(resource_context.vcodec_pclk)) {
+ if (clk_prepare_enable(resource_context.vcodec_pclk)) {
VCDRES_MSG_ERROR("vidc pclk Enable fail\n");
goto bail_out;
}
- if (clk_enable(resource_context.vcodec_clk)) {
+ if (clk_prepare_enable(resource_context.vcodec_clk)) {
VCDRES_MSG_ERROR("vidc core clk Enable fail\n");
goto vidc_disable_pclk;
}
@@ -275,7 +275,7 @@
mutex_unlock(&resource_context.lock);
return true;
vidc_disable_pclk:
- clk_disable(resource_context.vcodec_pclk);
+ clk_disable_unprepare(resource_context.vcodec_pclk);
bail_out:
mutex_unlock(&resource_context.lock);
return false;
@@ -322,9 +322,9 @@
VCDRES_MSG_LOW("%s(): Disabling the clocks ...\n", __func__);
resource_context.clock_enabled = 0;
if (resource_context.vcodec_clk)
- clk_disable(resource_context.vcodec_clk);
+ clk_disable_unprepare(resource_context.vcodec_clk);
if (resource_context.vcodec_pclk)
- clk_disable(resource_context.vcodec_pclk);
+ clk_disable_unprepare(resource_context.vcodec_pclk);
status = true;
}
mutex_unlock(&resource_context.lock);
@@ -696,7 +696,7 @@
ret = PTR_ERR(vidc_mmu_clks[i].mmu_clk);
}
if (!ret) {
- ret = clk_enable(vidc_mmu_clks[i].mmu_clk);
+ ret = clk_prepare_enable(vidc_mmu_clks[i].mmu_clk);
if (ret) {
clk_put(vidc_mmu_clks[i].mmu_clk);
vidc_mmu_clks[i].mmu_clk = NULL;
@@ -704,7 +704,7 @@
}
if (ret) {
for (i--; i >= 0; i--) {
- clk_disable(vidc_mmu_clks[i].mmu_clk);
+ clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk);
clk_put(vidc_mmu_clks[i].mmu_clk);
vidc_mmu_clks[i].mmu_clk = NULL;
}
@@ -725,7 +725,7 @@
}
resource_context.mmu_clks_on = 0;
for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) {
- clk_disable(vidc_mmu_clks[i].mmu_clk);
+ clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk);
clk_put(vidc_mmu_clks[i].mmu_clk);
vidc_mmu_clks[i].mmu_clk = NULL;
}
diff --git a/fs/yaffs2/yaffs_vfs.c b/fs/yaffs2/yaffs_vfs.c
index f56e12c..70d88ef 100644
--- a/fs/yaffs2/yaffs_vfs.c
+++ b/fs/yaffs2/yaffs_vfs.c
@@ -53,6 +53,7 @@
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/freezer.h>
+#include <linux/cleancache.h>
#include <asm/div64.h>
@@ -1139,6 +1140,10 @@
(unsigned)(pg->index << PAGE_CACHE_SHIFT),
(unsigned)PAGE_CACHE_SIZE);
+ ret = cleancache_get_page(pg);
+ if (!ret)
+ goto cleancache_got;
+
obj = yaffs_dentry_to_obj(f->f_dentry);
dev = obj->my_dev;
@@ -1158,11 +1163,13 @@
if (ret >= 0)
ret = 0;
+cleancache_got:
if (ret) {
ClearPageUptodate(pg);
SetPageError(pg);
} else {
SetPageUptodate(pg);
+ SetPageMappedToDisk(pg);
ClearPageError(pg);
}
@@ -2364,6 +2371,7 @@
dev->is_checkpointed);
yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: done");
+ cleancache_init_fs(sb);
return sb;
}
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index d1c7733..1cb5401 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -53,7 +53,12 @@
#define APQ8060_TOOLS_ID 4062
#define AO8960_TOOLS_ID 4064
#define APQ8064_TOOLS_ID 4072
-#define MSM8930_TOOLS_ID 4072
+#define MSM8930_TOOLS_ID 4076
+#define MSM8630_TOOLS_ID 4077
+#define MSM8230_TOOLS_ID 4078
+#define APQ8030_TOOLS_ID 4079
+#define MSM8627_TOOLS_ID 4080
+#define MSM8227_TOOLS_ID 4081
#define MSM8974_TOOLS_ID 4072
#define MSG_MASK_0 (0x00000001)
diff --git a/include/linux/fmem.h b/include/linux/fmem.h
index c9e36b5..aebeec4 100644
--- a/include/linux/fmem.h
+++ b/include/linux/fmem.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -20,6 +20,7 @@
struct fmem_platform_data {
unsigned long phys;
unsigned long size;
+ unsigned long reserved_size;
};
struct fmem_data {
@@ -27,6 +28,7 @@
void *virt;
struct vm_struct *area;
unsigned long size;
+ unsigned long reserved_size;
};
enum fmem_state {
diff --git a/include/linux/genlock.h b/include/linux/genlock.h
index 2e9f9d6..9351a15 100644
--- a/include/linux/genlock.h
+++ b/include/linux/genlock.h
@@ -12,7 +12,7 @@
struct genlock *genlock_create_lock(struct genlock_handle *);
struct genlock *genlock_attach_lock(struct genlock_handle *, int fd);
int genlock_wait(struct genlock_handle *handle, u32 timeout);
-void genlock_release_lock(struct genlock_handle *);
+/* genlock_release_lock was deprecated */
int genlock_lock(struct genlock_handle *handle, int op, int flags,
u32 timeout);
#endif
@@ -39,6 +39,8 @@
struct genlock_lock)
#define GENLOCK_IOC_LOCK _IOW(GENLOCK_IOC_MAGIC, 3, \
struct genlock_lock)
+
+/* Deprecated */
#define GENLOCK_IOC_RELEASE _IO(GENLOCK_IOC_MAGIC, 4)
#define GENLOCK_IOC_WAIT _IOW(GENLOCK_IOC_MAGIC, 5, \
struct genlock_lock)
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 7ae8342..500ee6b 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -46,6 +46,8 @@
unsigned int x_size;
unsigned int y_size;
+ unsigned int touch_x_size;
+ unsigned int touch_y_size;
unsigned long irqflags;
bool i2c_pull_up;
bool digital_pwr_regulator;
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 41f99e4..ade87e6 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -99,6 +99,7 @@
#define ION_WB_HEAP_NAME "wb"
#define ION_MM_FIRMWARE_HEAP_NAME "mm_fw"
#define ION_QSECOM_HEAP_NAME "qsecom"
+#define ION_FMEM_HEAP_NAME "fmem"
#define CACHED 1
#define UNCACHED 0
@@ -123,6 +124,7 @@
be converted to phys_addr_t. For the time being many kernel interfaces
do not accept phys_addr_t's that would have to */
#define ion_phys_addr_t unsigned long
+#define ion_virt_addr_t unsigned long
/**
* struct ion_platform_heap - defines a heap in the given platform
@@ -132,15 +134,8 @@
* @name: used for debug purposes
* @base: base address of heap in physical memory if applicable
* @size: size of the heap in bytes if applicable
- * @memory_type: Memory type used for the heap
- * @ion_memory_id: Memory ID used to identify the memory to TZ
- * @request_region: function to be called when the number of allocations goes
- * from 0 -> 1
- * @release_region: function to be called when the number of allocations goes
- * from 1 -> 0
- * @setup_region: function to be called upon ion registration
- *
- * Provided by the board file.
+ * @memory_type:Memory type used for the heap
+ * @extra_data: Extra data specific to each heap type
*/
struct ion_platform_heap {
enum ion_heap_type type;
@@ -152,16 +147,50 @@
void *extra_data;
};
+/**
+ * struct ion_cp_heap_pdata - defines a content protection heap in the given
+ * platform
+ * @permission_type: Memory ID used to identify the memory to TZ
+ * @align: Alignment requirement for the memory
+ * @secure_base: Base address for securing the heap.
+ * Note: This might be different from actual base address
+ * of this heap in the case of a shared heap.
+ * @secure_size: Memory size for securing the heap.
+ * Note: This might be different from actual size
+ * of this heap in the case of a shared heap.
+ * @reusable Flag indicating whether this heap is reusable of not.
+ * (see FMEM)
+ * @virt_addr: Virtual address used when using fmem.
+ * @request_region: function to be called when the number of allocations
+ * goes from 0 -> 1
+ * @release_region: function to be called when the number of allocations
+ * goes from 1 -> 0
+ * @setup_region: function to be called upon ion registration
+ *
+ */
struct ion_cp_heap_pdata {
enum ion_permission_type permission_type;
unsigned int align;
ion_phys_addr_t secure_base; /* Base addr used when heap is shared */
size_t secure_size; /* Size used for securing heap when heap is shared*/
+ int reusable;
+ ion_virt_addr_t *virt_addr;
int (*request_region)(void *);
int (*release_region)(void *);
void *(*setup_region)(void);
};
+/**
+ * struct ion_co_heap_pdata - defines a carveout heap in the given platform
+ * @adjacent_mem_id: Id of heap that this heap must be adjacent to.
+ * @align: Alignment requirement for the memory
+ * @request_region: function to be called when the number of allocations
+ * goes from 0 -> 1
+ * @release_region: function to be called when the number of allocations
+ * goes from 1 -> 0
+ * @setup_region: function to be called upon ion registration
+ *
+ */
struct ion_co_heap_pdata {
int adjacent_mem_id;
unsigned int align;
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index f9fc498..c4f601b 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -172,6 +172,15 @@
*/
int pm8xxx_preload_dVdd(void);
+/**
+ * pm8xxx_usb_id_pullup - Control a pullup for USB ID
+ *
+ * @enable: enable (1) or disable (0) the pullup
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_usb_id_pullup(int enable);
+
#else
static inline int pm8xxx_reset_pwr_off(int reset)
@@ -212,6 +221,10 @@
{
return -ENODEV;
}
+static inline int pm8xxx_usb_id_pullup(int enable)
+{
+ return -ENODEV;
+}
#endif
#endif
diff --git a/include/linux/mfd/pm8xxx/pm8018.h b/include/linux/mfd/pm8xxx/pm8018.h
index e0ec0b4..20c9d26 100644
--- a/include/linux/mfd/pm8xxx/pm8018.h
+++ b/include/linux/mfd/pm8xxx/pm8018.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -57,6 +57,8 @@
#define PM8018_ADC_BATT_TEMP_WARM_IRQ PM8018_IRQ_BLOCK_BIT(9, 1)
#define PM8018_ADC_BATT_TEMP_COLD_IRQ PM8018_IRQ_BLOCK_BIT(9, 0)
+#define PM8018_LVS1_OCP_IRQ PM8921_IRQ_BLOCK_BIT(13, 0)
+
struct pm8018_platform_data {
struct pm8xxx_irq_platform_data *irq_pdata;
struct pm8xxx_gpio_platform_data *gpio_pdata;
diff --git a/include/linux/mfd/pm8xxx/pm8921.h b/include/linux/mfd/pm8xxx/pm8921.h
index ee1216d..22293fe 100644
--- a/include/linux/mfd/pm8xxx/pm8921.h
+++ b/include/linux/mfd/pm8xxx/pm8921.h
@@ -112,6 +112,16 @@
#define PM8921_TEMPSTAT_IRQ PM8921_IRQ_BLOCK_BIT(6, 7)
#define PM8921_RESOUT_IRQ PM8921_IRQ_BLOCK_BIT(6, 4)
+#define PM8921_USB_OTG_OCP_IRQ PM8921_IRQ_BLOCK_BIT(6, 0)
+#define PM8921_LVS7_OCP_IRQ PM8921_IRQ_BLOCK_BIT(13, 7)
+#define PM8921_LVS6_OCP_IRQ PM8921_IRQ_BLOCK_BIT(13, 6)
+#define PM8921_LVS5_OCP_IRQ PM8921_IRQ_BLOCK_BIT(13, 5)
+#define PM8921_LVS4_OCP_IRQ PM8921_IRQ_BLOCK_BIT(13, 4)
+#define PM8921_LVS3_OCP_IRQ PM8921_IRQ_BLOCK_BIT(13, 3)
+#define PM8921_LVS2_OCP_IRQ PM8921_IRQ_BLOCK_BIT(13, 2)
+#define PM8921_LVS1_OCP_IRQ PM8921_IRQ_BLOCK_BIT(13, 1)
+#define PM8921_HDMI_MVS_OCP_IRQ PM8921_IRQ_BLOCK_BIT(13, 0)
+
/* PMIC I/O Resources */
#define PM8921_RTC_BASE 0x11D
diff --git a/include/linux/mfd/pm8xxx/pwm.h b/include/linux/mfd/pm8xxx/pwm.h
index be3ec65..9169e90 100644
--- a/include/linux/mfd/pm8xxx/pwm.h
+++ b/include/linux/mfd/pm8xxx/pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,8 +17,8 @@
#define PM8XXX_PWM_DEV_NAME "pm8xxx-pwm"
-#define PM8XXX_PWM_PERIOD_MAX (327 * USEC_PER_SEC)
-#define PM8XXX_PWM_PERIOD_MIN 7 /* micro seconds */
+#define PM8XXX_PWM_PERIOD_MIN 7 /* usec: 19.2M, n=6, m=0, pre=2 */
+#define PM8XXX_PWM_PERIOD_MAX (384 * USEC_PER_SEC) /* 1K, n=9, m=7, pre=6 */
#define PM_PWM_LUT_SIZE 64
#define PM_PWM_LUT_DUTY_TIME_MAX 512 /* ms */
diff --git a/include/linux/mfd/pm8xxx/regulator.h b/include/linux/mfd/pm8xxx/regulator.h
index 38700cb..9e0ce86 100644
--- a/include/linux/mfd/pm8xxx/regulator.h
+++ b/include/linux/mfd/pm8xxx/regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -227,20 +227,22 @@
.prev_write_count = -1, \
}
-#define VS(_name, _pc_name, _ctrl_addr) \
+#define VS(_name, _pc_name, _ctrl_addr, _test_addr) \
{ \
.type = PM8XXX_REGULATOR_TYPE_VS, \
.ctrl_addr = _ctrl_addr, \
+ .test_addr = _test_addr, \
.rdesc.name = _name, \
.rdesc_pc.name = _pc_name, \
.write_count = 0, \
.prev_write_count = -1, \
}
-#define VS300(_name, _ctrl_addr) \
+#define VS300(_name, _ctrl_addr, _test_addr) \
{ \
.type = PM8XXX_REGULATOR_TYPE_VS300, \
.ctrl_addr = _ctrl_addr, \
+ .test_addr = _test_addr, \
.rdesc.name = _name, \
.write_count = 0, \
.prev_write_count = -1, \
diff --git a/include/linux/regulator/pm8xxx-regulator.h b/include/linux/regulator/pm8xxx-regulator.h
index 7c8d778..ddf1901 100644
--- a/include/linux/regulator/pm8xxx-regulator.h
+++ b/include/linux/regulator/pm8xxx-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -66,6 +66,11 @@
* @enable_time: time in us taken to enable a regulator to the maximum
* allowed voltage for the system. This is dependent upon
* the load and capacitance for a regulator on the board.
+ * @ocp_enable: enable over current protection logic (available for
+ * LVS and MVS type switches)
+ * @ocp_enable_time: time in us to delay between enabling the switch and then
+ * enabling OCP for it. This delay is needed to avoid
+ * false triggering due to inrush current.
*/
struct pm8xxx_regulator_platform_data {
struct regulator_init_data init_data;
@@ -75,6 +80,8 @@
enum pm8xxx_vreg_pin_function pin_fn;
int system_uA;
int enable_time;
+ unsigned ocp_enable;
+ int ocp_enable_time;
};
#endif
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index d161d41..448d9ab 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -378,9 +378,9 @@
* @seglen: Segment length of this channel.
* @rootexp: root exponent of this channel. Rate can be found using rootexp and
* coefficient. Used during scheduling.
- * @srch: Source ports used by this channel.
- * @nsrc: number of source ports used by this channel.
- * @sinkh: Sink port used by this channel.
+ * @srch: Source port used by this channel.
+ * @sinkh: Sink ports used by this channel.
+ * @nsink: number of sink ports used by this channel.
* @chan: Channel number sent on hardware lines for this channel. May not be
* equal to array-index into chans if client requested to use number beyond
* channel-array for the controller.
@@ -404,9 +404,9 @@
u32 newintr;
u32 seglen;
u8 rootexp;
- u32 *srch;
- int nsrc;
- u32 sinkh;
+ u32 srch;
+ u32 *sinkh;
+ int nsink;
u8 chan;
int ref;
int def;
@@ -760,19 +760,31 @@
u32 ph, u8 **done_buf, u32 *done_len);
/*
- * slim_connect_ports: Connect port(s) to channel.
+ * slim_connect_src: Connect source port to channel.
* @sb: client handle
- * @srch: source handles to be connected to this channel
- * @nrsc: number of source ports
- * @sinkh: sink handle to be connected to this channel
+ * @srch: source handle to be connected to this channel
* @chanh: Channel with which the ports need to be associated with.
- * Per slimbus specification, a channel may have multiple source-ports and 1
- * sink port.Channel specified in chanh needs to be allocated first.
+ * Per slimbus specification, a channel may have 1 source port.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if source is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
*/
-extern int slim_connect_ports(struct slim_device *sb, u32 *srch, int nsrc,
- u32 sinkh, u16 chanh);
+extern int slim_connect_src(struct slim_device *sb, u32 srch, u16 chanh);
/*
+ * slim_connect_sink: Connect sink port(s) to channel.
+ * @sb: client handle
+ * @sinkh: sink handle(s) to be connected to this channel
+ * @nsink: number of sinks
+ * @chanh: Channel with which the ports need to be associated with.
+ * Per slimbus specification, a channel may have multiple sink-ports.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if sink is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
+ */
+extern int slim_connect_sink(struct slim_device *sb, u32 *sinkh, int nsink,
+ u16 chanh);
+/*
* slim_disconnect_ports: Disconnect port(s) from channel
* @sb: client handle
* @ph: ports to be disconnected
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 75fa487..ebd2b75 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -376,7 +376,16 @@
#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */
#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */
#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */
-#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 */
+#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 Multiplexed */
+#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */
+#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */
+#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */
+#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */
+#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */
+#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 ES */
+#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */
+#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */
+#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
/* Vendor-specific formats */
#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
@@ -703,6 +712,11 @@
/* Flags for 'capability' and 'capturemode' fields */
#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */
#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */
+#define V4L2_CAP_QCOM_FRAMESKIP 0x2000 /* frame skipping is supported */
+
+struct v4l2_qcom_frameskip {
+ __u64 maxframeinterval;
+};
struct v4l2_outputparm {
__u32 capability; /* Supported modes */
@@ -1156,7 +1170,7 @@
#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
-/* MPEG streams */
+/* MPEG streams, specific to multiplexed streams */
#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0)
enum v4l2_mpeg_stream_type {
V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */
@@ -1178,7 +1192,7 @@
V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */
};
-/* MPEG audio */
+/* MPEG audio controls specific to multiplexed streams */
#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100)
enum v4l2_mpeg_audio_sampling_freq {
V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
@@ -1294,7 +1308,7 @@
V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18,
};
-/* MPEG video */
+/* MPEG video controls specific to multiplexed streams */
#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
enum v4l2_mpeg_video_encoding {
V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0,
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index d905b22..8d2852b 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1,3 +1,15 @@
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
#ifndef __LINUX_MSM_CAMERA_H
#define __LINUX_MSM_CAMERA_H
@@ -168,6 +180,15 @@
#define MSM_CAM_IOCTL_GET_KERNEL_SYSTEM_TIME \
_IOW(MSM_CAM_IOCTL_MAGIC, 50, struct timeval *)
+#define MSM_CAM_IOCTL_SET_VFE_OUTPUT_TYPE \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 51, uint32_t *)
+
+#define MSM_CAM_IOCTL_GET_MCTL_INFO \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 51, struct msm_mctl_node_info *)
+
+#define MSM_CAM_IOCTL_MCTL_DIVERT_DONE \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 52, struct msm_cam_evt_divert_frame *)
+
struct msm_mctl_pp_cmd {
int32_t id;
uint16_t length;
@@ -265,6 +286,7 @@
struct msm_pp_frame {
uint32_t handle; /* stores vb cookie */
uint32_t frame_id;
+ unsigned short buf_idx;
int path;
unsigned short image_type;
unsigned short num_planes; /* 1 for sp */
@@ -403,6 +425,11 @@
#define CMD_AXI_CFG_VIDEO_ALL_CHNLS 50
#define CMD_VFE_BUFFER_RELEASE 51
+#define CMD_AXI_CFG_PRIM 0xF1
+#define CMD_AXI_CFG_PRIM_ALL_CHNLS 0xF2
+#define CMD_AXI_CFG_SEC 0xF4
+#define CMD_AXI_CFG_SEC_ALL_CHNLS 0xF8
+
/* vfe config command: config command(from config thread)*/
struct msm_vfe_cfg_cmd {
int cmd_type;
@@ -495,6 +522,12 @@
#define OUTPUT_ZSL_ALL_CHNLS 10
#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_ZSL_ALL_CHNLS
+#define OUTPUT_PRIM 0xF1
+#define OUTPUT_PRIM_ALL_CHNLS 0xF2
+#define OUTPUT_SEC 0xF4
+#define OUTPUT_SEC_ALL_CHNLS 0xF8
+
+
#define MSM_FRAME_PREV_1 0
#define MSM_FRAME_PREV_2 1
#define MSM_FRAME_ENC 2
@@ -640,7 +673,8 @@
#define MSM_V4L2_PID_STROBE_FLASH (V4L2_CID_PRIVATE_BASE+15)
#define MSM_V4L2_PID_MMAP_ENTRY (V4L2_CID_PRIVATE_BASE+16)
#define MSM_V4L2_PID_MMAP_INST (V4L2_CID_PRIVATE_BASE+17)
-#define MSM_V4L2_PID_MAX MSM_V4L2_PID_MMAP_INST
+#define MSM_V4L2_PID_PP_PLANE_INFO (V4L2_CID_PRIVATE_BASE+18)
+#define MSM_V4L2_PID_MAX MSM_V4L2_PID_PP_PLANE_INFO
/* camera operation mode for video recording - two frame output queues */
#define MSM_V4L2_CAM_OP_DEFAULT 0
@@ -1143,6 +1177,11 @@
int config_dev_id[MSM_MAX_CAMERA_CONFIGS];
};
+struct msm_mctl_node_info {
+ int num_mctl_nodes;
+ const char *mctl_node_name[MSM_MAX_CAMERA_SENSORS];
+};
+
struct flash_ctrl_data {
int flashtype;
union {
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index dae4a12..7caafb6 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -1,6 +1,20 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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_ISP_H__
#define __MSM_ISP_H__
+#define BIT(nr) (1UL << (nr))
+
/* ISP message IDs */
#define MSG_ID_RESET_ACK 0
#define MSG_ID_START_ACK 1
@@ -42,6 +56,8 @@
#define MSG_ID_SOF_ACK 37
#define MSG_ID_STOP_REC_ACK 38
#define MSG_ID_STATS_AWB_AEC 39
+#define MSG_ID_OUTPUT_PRIMARY 40
+#define MSG_ID_OUTPUT_SECONDARY 41
/* ISP command IDs */
#define VFE_CMD_DUMMY_0 0
@@ -180,6 +196,8 @@
#define VFE_CMD_Y_GAMMA_CONFIG 133
#define VFE_CMD_SCALE_OUTPUT1_CONFIG 134
#define VFE_CMD_SCALE_OUTPUT2_CONFIG 135
+#define VFE_CMD_CAPTURE_RAW 136
+#define VFE_CMD_STOP_LIVESHOT 137
struct msm_isp_cmd {
int32_t id;
@@ -199,8 +217,8 @@
#define VPE_CMD_OUTPUT_PLANE_CFG 9
#define VPE_CMD_INPUT_PLANE_UPDATE 10
#define VPE_CMD_SCALE_CFG_TYPE 11
-#define VPE_CMD_DIS_OFFSET_CFG 12
#define VPE_CMD_ZOOM 13
+#define VPE_CMD_MAX 14
#define MSM_PP_CMD_TYPE_NOT_USED 0 /* not used */
#define MSM_PP_CMD_TYPE_VPE 1 /* VPE cmd */
@@ -215,9 +233,9 @@
#define MCTL_PP_EVENT_NOTUSED 0
#define MCTL_PP_EVENT_CMD_ACK 1
-#define VPE_OPERATION_MODE_CFG_LEN 8
+#define VPE_OPERATION_MODE_CFG_LEN 4
#define VPE_INPUT_PLANE_CFG_LEN 24
-#define VPE_OUTPUT_PLANE_CFG_LEN 24
+#define VPE_OUTPUT_PLANE_CFG_LEN 20
#define VPE_INPUT_PLANE_UPDATE_LEN 12
#define VPE_SCALER_CONFIG_LEN 260
#define VPE_DIS_OFFSET_CFG_LEN 12
@@ -242,10 +260,6 @@
uint8_t scaler_cfg[VPE_SCALER_CONFIG_LEN];
};
-struct msm_vpe_dis_offset_cfg {
- uint8_t dis_offset_cfg[VPE_DIS_OFFSET_CFG_LEN];
-};
-
struct msm_vpe_flush_frame_buffer {
uint32_t src_buf_handle;
uint32_t dest_buf_handle;
@@ -287,5 +301,15 @@
/* TBD: 3D related */
};
+#define VFE_OUTPUTS_MAIN_AND_PREVIEW BIT(0)
+#define VFE_OUTPUTS_MAIN_AND_VIDEO BIT(1)
+#define VFE_OUTPUTS_MAIN_AND_THUMB BIT(2)
+#define VFE_OUTPUTS_THUMB_AND_MAIN BIT(3)
+#define VFE_OUTPUTS_PREVIEW_AND_VIDEO BIT(4)
+#define VFE_OUTPUTS_VIDEO_AND_PREVIEW BIT(5)
+#define VFE_OUTPUTS_PREVIEW BIT(6)
+#define VFE_OUTPUTS_VIDEO BIT(7)
+#define VFE_OUTPUTS_RAW BIT(8)
+
#endif /*__MSM_ISP_H__*/
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 4918caa..0a3b91d 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -1158,6 +1158,7 @@
if (skb->len < sizeof(*grsp))
goto cpl_finished;
grsp = (struct a2mp_getinfo_rsp *) skb_pull(skb, sizeof(*hdr));
+ skb_pull(skb, sizeof(*grsp));
if (grsp->status)
goto cpl_finished;
if (grsp->id != ctx->d.cpl.remote_id)
@@ -1171,7 +1172,6 @@
ctrl->min_latency = le32_to_cpu(grsp->min_latency);
ctrl->pal_cap = le16_to_cpu(grsp->pal_cap);
ctrl->max_assoc_size = le16_to_cpu(grsp->assoc_size);
- skb_pull(skb, sizeof(*grsp));
ctx->d.cpl.max_len = ctrl->max_assoc_size;
@@ -1191,8 +1191,6 @@
goto cpl_finished;
hdr = (void *) skb->data;
arsp = (void *) skb_pull(skb, sizeof(*hdr));
- if (arsp->id != ctx->d.cpl.remote_id)
- goto cpl_finished;
if (arsp->status != 0)
goto cpl_finished;
@@ -1200,12 +1198,12 @@
assoc = (u8 *) skb_pull(skb, sizeof(*arsp));
ctx->d.cpl.len_so_far = 0;
ctx->d.cpl.rem_len = hdr->len - sizeof(*arsp);
+ skb_pull(skb, ctx->d.cpl.rem_len);
rassoc = kmalloc(ctx->d.cpl.rem_len, GFP_ATOMIC);
if (!rassoc)
goto cpl_finished;
memcpy(rassoc, assoc, ctx->d.cpl.rem_len);
ctx->d.cpl.remote_assoc = rassoc;
- skb_pull(skb, ctx->d.cpl.rem_len);
/* set up CPL command */
ctx->d.cpl.phy_handle = physlink_handle(ctx->hdev);
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 92d72b7..0719874 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -523,6 +523,7 @@
struct sock *sk = sock->sk;
struct hci_dev *hdev;
struct sk_buff *skb;
+ int reserve = 0;
int err;
BT_DBG("sock %p sk %p", sock, sk);
@@ -560,10 +561,18 @@
goto done;
}
- skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
+ /* Allocate extra headroom for Qualcomm PAL */
+ if (hdev->dev_type == HCI_AMP && hdev->manufacturer == 0x001d)
+ reserve = BT_SKB_RESERVE_80211;
+
+ skb = bt_skb_send_alloc(sk, len + reserve,
+ msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
goto done;
+ if (reserve)
+ skb_reserve(skb, reserve);
+
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
err = -EFAULT;
goto drop;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a570ff9..17a80bf 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -408,6 +408,7 @@
bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
/* internal helpers */
+bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
struct key_params *params, int key_idx,
bool pairwise, const u8 *mac_addr);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0fc46b3..1a84262 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3947,23 +3947,6 @@
NL80211_WPA_VERSION_2));
}
-static bool nl80211_valid_akm_suite(u32 akm)
-{
- return akm == WLAN_AKM_SUITE_8021X ||
- akm == WLAN_AKM_SUITE_PSK;
-}
-
-static bool nl80211_valid_cipher_suite(u32 cipher)
-{
- return cipher == WLAN_CIPHER_SUITE_WEP40 ||
- cipher == WLAN_CIPHER_SUITE_WEP104 ||
- cipher == WLAN_CIPHER_SUITE_TKIP ||
- cipher == WLAN_CIPHER_SUITE_CCMP ||
- cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
- cipher == WLAN_CIPHER_SUITE_SMS4;
-}
-
-
static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -4096,15 +4079,17 @@
memcpy(settings->ciphers_pairwise, data, len);
for (i = 0; i < settings->n_ciphers_pairwise; i++)
- if (!nl80211_valid_cipher_suite(
- settings->ciphers_pairwise[i]))
+ if (!cfg80211_supported_cipher_suite(
+ &rdev->wiphy,
+ settings->ciphers_pairwise[i]))
return -EINVAL;
}
if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
settings->cipher_group =
nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
- if (!nl80211_valid_cipher_suite(settings->cipher_group))
+ if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
+ settings->cipher_group))
return -EINVAL;
}
@@ -4117,7 +4102,7 @@
if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
void *data;
- int len, i;
+ int len;
data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
@@ -4130,10 +4115,6 @@
return -EINVAL;
memcpy(settings->akm_suites, data, len);
-
- for (i = 0; i < settings->n_akm_suites; i++)
- if (!nl80211_valid_akm_suite(settings->akm_suites[i]))
- return -EINVAL;
}
return 0;
diff --git a/net/wireless/util.c b/net/wireless/util.c
index c00a511..c69e653 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -150,12 +150,19 @@
set_mandatory_flags_band(wiphy->bands[band], band);
}
+bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher)
+{
+ int i;
+ for (i = 0; i < wiphy->n_cipher_suites; i++)
+ if (cipher == wiphy->cipher_suites[i])
+ return true;
+ return false;
+}
+
int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
struct key_params *params, int key_idx,
bool pairwise, const u8 *mac_addr)
{
- int i;
-
if (key_idx > 5)
return -EINVAL;
@@ -229,10 +236,7 @@
}
}
- for (i = 0; i < rdev->wiphy.n_cipher_suites; i++)
- if (params->cipher == rdev->wiphy.cipher_suites[i])
- break;
- if (i == rdev->wiphy.n_cipher_suites)
+ if (!cfg80211_supported_cipher_suite(&rdev->wiphy, params->cipher))
return -EINVAL;
return 0;
diff --git a/scripts/gcc-wrapper.py b/scripts/gcc-wrapper.py
index cbe2eae..65744e1 100755
--- a/scripts/gcc-wrapper.py
+++ b/scripts/gcc-wrapper.py
@@ -1,7 +1,7 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+# Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -40,6 +40,7 @@
# force LANG to be set to en_US.UTF-8 to get consistent warnings.
allowed_warnings = set([
+ "alignment.c:298",
"alignment.c:720",
"async.c:122",
"async.c:270",
@@ -59,6 +60,7 @@
"nf_conntrack_netlink.c:790",
"nf_nat_standalone.c:118",
"return_address.c:62",
+ "sch_generic.c:678",
"soc-core.c:1719",
"xt_log.h:50",
"vx6953.c:3124",
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 50dede5..380eb49 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -3441,7 +3441,6 @@
snd_soc_write(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x0A);
snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x04);
snd_soc_write(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x02);
- snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x04);
snd_soc_write(codec, TABLA_A_MBHC_SCALING_MUX_1, 0x81);
usleep_range(100, 100);
snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x04);
@@ -3461,7 +3460,6 @@
snd_soc_write(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x0A);
snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x02);
snd_soc_write(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x02);
- snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x02);
snd_soc_write(codec, TABLA_A_MBHC_SCALING_MUX_1, 0x81);
usleep_range(100, 100);
snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x02);
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 96260ab..27a27ec 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -420,6 +420,7 @@
switch (dai->id) {
case PRIMARY_I2S_TX:
case PRIMARY_I2S_RX:
+ case SECONDARY_I2S_RX:
rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream);
break;
case MI2S_RX:
@@ -820,6 +821,7 @@
case PRIMARY_I2S_TX:
case PRIMARY_I2S_RX:
case MI2S_RX:
+ case SECONDARY_I2S_RX:
rc = msm_dai_q6_cdc_set_fmt(dai, fmt);
break;
default:
@@ -1086,6 +1088,7 @@
switch (pdev->id) {
case PRIMARY_I2S_RX:
+ case SECONDARY_I2S_RX:
rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_rx_dai);
break;
case PRIMARY_I2S_TX:
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 1331ebf..94ed504 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -118,6 +118,7 @@
{ VOICE_RECORD_RX, 0, NULL, 0, 0},
{ VOICE_RECORD_TX, 0, NULL, 0, 0},
{ MI2S_RX, 0, NULL, 0, 0},
+ { SECONDARY_I2S_RX, 0, NULL, 0, 0},
};
@@ -668,6 +669,21 @@
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_I2S_RX ,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_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_SEC_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[] = {
SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -824,6 +840,15 @@
msm_routing_put_voice_mixer),
};
+static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = {
+ SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+};
+
static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -1134,6 +1159,8 @@
/* Stream name equals to backend dai link stream name
*/
SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback",
+ 0, 0, 0 , 0),
SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
@@ -1166,6 +1193,8 @@
/* Mixer definitions */
SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+ sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
@@ -1186,6 +1215,10 @@
SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
ARRAY_SIZE(pri_rx_voice_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_RX_Voice Mixer",
+ SND_SOC_NOPM, 0, 0,
+ sec_i2s_rx_voice_mixer_controls,
+ ARRAY_SIZE(sec_i2s_rx_voice_mixer_controls)),
SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
SND_SOC_NOPM, 0, 0,
slimbus_rx_voice_mixer_controls,
@@ -1230,6 +1263,12 @@
{"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
+ {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_I2S_RX", NULL, "SEC_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"},
@@ -1295,6 +1334,10 @@
{"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
+ {"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
+ {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
+
{"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index a8d2d91..25efb58 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,7 @@
#define LPASS_BE_VOICE_PLAYBACK_TX "(Backend) VOICE_PLAYBACK_TX"
#define LPASS_BE_INCALL_RECORD_RX "(Backend) INCALL_RECORD_TX"
#define LPASS_BE_INCALL_RECORD_TX "(Backend) INCALL_RECORD_RX"
+#define LPASS_BE_SEC_I2S_RX "(Backend) SECONDARY_I2S_RX"
#define LPASS_BE_MI2S_RX "(Backend) MI2S_RX"
@@ -71,6 +72,7 @@
MSM_BACKEND_DAI_INCALL_RECORD_RX,
MSM_BACKEND_DAI_INCALL_RECORD_TX,
MSM_BACKEND_DAI_MI2S_RX,
+ MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_BACKEND_DAI_MAX,
};
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 2acf59e..532d92b 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -17,6 +17,7 @@
#include <linux/wait.h>
#include <linux/mutex.h>
+#include <asm/mach-types.h>
#include <mach/qdsp6v2/audio_acdb.h>
#include <mach/qdsp6v2/rtac.h>
@@ -2070,8 +2071,14 @@
mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
mvm_set_voice_timing.timing.mode = 0;
mvm_set_voice_timing.timing.enc_offset = 8000;
- mvm_set_voice_timing.timing.dec_req_offset = 3300;
- mvm_set_voice_timing.timing.dec_offset = 8300;
+ if (machine_is_apq8064_sim()) {
+ pr_debug("%s: Machine is apq8064 sim\n", __func__);
+ mvm_set_voice_timing.timing.dec_req_offset = 0;
+ mvm_set_voice_timing.timing.dec_offset = 18000;
+ } else {
+ mvm_set_voice_timing.timing.dec_req_offset = 3300;
+ mvm_set_voice_timing.timing.dec_offset = 8300;
+ }
v->mvm_state = CMD_STATUS_FAIL;