Merge "USB: android: Handle error conditions in init() function" into msm-3.0
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index d79aead..b1db115 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -266,3 +266,6 @@
pcim_iounmap()
pcim_iomap_table() : array of mapped addresses indexed by BAR
pcim_iomap_regions() : do request_region() and iomap() on multiple BARs
+
+REGULATOR
+ devm_regulator_get()
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index b00237a..fea1c52 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -10,26 +10,26 @@
intc: interrupt-controller@F9000000 {
compatible = "qcom,msm-qgic2";
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <3>;
reg = <0xF9000000 0x1000>,
<0xF9002000 0x1000>;
};
timer {
compatible = "qcom,msm-qtimer";
- interrupts = <18>;
+ interrupts = <1 2 0>;
};
serial@F991F000 {
compatible = "qcom,msm-lsuart-v14";
reg = <0xF991F000 0x1000>;
- interrupts = <109>;
+ interrupts = <0 109 0>;
};
usb@F9A55000 {
compatible = "qcom,hsusb-otg";
reg = <0xF9A55000 0x400>;
- interrupts = <134>;
+ interrupts = <0 134 0>;
qcom,hsusb-otg-phy-type = <2>;
qcom,hsusb-otg-mode = <1>;
@@ -40,7 +40,7 @@
cell-index = <1>;
compatible = "qcom,msm-sdcc";
reg = <0xF980B000 0x1000>;
- interrupts = <123>;
+ interrupts = <0 123 0>;
qcom,sdcc-clk-rates = <400000 24000000 48000000>;
qcom,sdcc-sup-voltages = <3300 3300>;
@@ -53,7 +53,7 @@
cell-index = <3>;
compatible = "qcom,msm-sdcc";
reg = <0xF984B000 0x1000>;
- interrupts = <127>;
+ interrupts = <0 127 0>;
qcom,sdcc-clk-rates = <400000 24000000 48000000>;
qcom,sdcc-sup-voltages = <3300 3300>;
@@ -65,7 +65,7 @@
compatible = "qcom,msm_sps";
reg = <0xF9984000 0x15000>,
<0xF9999000 0xB000>;
- interrupts = <94>;
+ interrupts = <0 94 0>;
qcom,bam-dma-res-pipes = <6>;
};
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index d69305c..3421fa1 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -1,6 +1,7 @@
CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
+CONFIG_SPARSE_IRQ=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index bd92fe3..5f9bd89 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -49,6 +49,9 @@
CONFIG_MACH_MSM8627_MTP=y
CONFIG_MACH_APQ8064_SIM=y
CONFIG_MACH_APQ8064_RUMI3=y
+CONFIG_MACH_APQ8064_CDP=y
+CONFIG_MACH_APQ8064_MTP=y
+CONFIG_MACH_APQ8064_LIQUID=y
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_KERNEL_PMEM_EBI_REGION=y
# CONFIG_MSM_FIQ_SUPPORT is not set
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index b44f46f..bd6df88 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -21,7 +21,7 @@
const char **dt_compat; /* array of device tree
* 'compatible' strings */
- unsigned int nr_irqs; /* number of IRQs */
+ int nr_irqs; /* number of IRQs */
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 4468153..7561081 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -134,8 +134,18 @@
#ifdef CONFIG_SPARSE_IRQ
int __init arch_probe_nr_irqs(void)
{
- nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
- return nr_irqs;
+ /*
+ * machine_desc->nr_irqs < 0 is a special case that
+ * specifies not to preallocate any irq_descs.
+ */
+ if (machine_desc->nr_irqs < 0) {
+ nr_irqs = 0;
+ return nr_irqs;
+ } else {
+ nr_irqs = machine_desc->nr_irqs ?
+ machine_desc->nr_irqs : NR_IRQS;
+ return nr_irqs;
+ }
}
#endif
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 0faa7ea..4328ac3 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -383,8 +383,7 @@
*/
if (max_cpus > ncores)
max_cpus = ncores;
-
- if (max_cpus > 1) {
+ if (ncores > 1 && max_cpus) {
/*
* Enable the local timer or broadcast device for the
* boot CPU, but only if we have more than one CPU.
@@ -392,6 +391,14 @@
percpu_timer_setup();
/*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time. A platform should
+ * re-initialize the map in platform_smp_prepare_cpus() if
+ * present != possible (e.g. physical hotplug).
+ */
+ init_cpu_present(&cpu_possible_map);
+
+ /*
* Initialise the SCU if there are more than one CPU
* and let them know where to start.
*/
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index c5e65a0..b68d5bd 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -154,14 +154,6 @@
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
-
- /*
- * Initialise the present map, which describes the set of CPUs
- * actually populated at the present time.
- */
- for (i = 0; i < max_cpus; i++)
- set_cpu_present(i, true);
scu_enable(scu_base_addr());
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 9df90cd..f77e883 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -198,7 +198,6 @@
config ARCH_APQ8064
bool "APQ8064"
select ARCH_MSM_KRAITMP
- select MACH_APQ8064_SIM if !MACH_APQ8064_RUMI3
select MSM_V2_TLMM
select ARM_GIC
select CPU_V7
@@ -675,6 +674,24 @@
help
Support for the Qualcomm APQ8064 RUMI3 emulator.
+config MACH_APQ8064_CDP
+ depends on ARCH_APQ8064
+ bool "APQ8064 CDP"
+ help
+ Support for the Qualcomm APQ8064 CDP device.
+
+config MACH_APQ8064_MTP
+ depends on ARCH_APQ8064
+ bool "APQ8064 MTP"
+ help
+ Support for the Qualcomm APQ8064 MTP device.
+
+config MACH_APQ8064_LIQUID
+ depends on ARCH_APQ8064
+ bool "APQ8064 LIQUID"
+ help
+ Support for the Qualcomm APQ8064 LIQUID device.
+
config MACH_FSM9XXX_SURF
depends on ARCH_FSM9XXX
depends on !MSM_STACKED_MEMORY
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 10203b1..d001282 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -63,6 +63,7 @@
static uint32_t bam_dmux_write_cpy_cnt;
static uint32_t bam_dmux_write_cpy_bytes;
static uint32_t bam_dmux_tx_sps_failure_cnt;
+static uint32_t bam_dmux_tx_stall_cnt;
#define DBG(x...) do { \
if (msm_bam_dmux_debug_enable) \
@@ -96,12 +97,17 @@
bam_dmux_tx_sps_failure_cnt++; \
} while (0)
+#define DBG_INC_TX_STALL_CNT() do { \
+ bam_dmux_tx_stall_cnt++; \
+} while (0)
+
#else
#define DBG(x...) do { } while (0)
#define DBG_INC_READ_CNT(x...) do { } while (0)
#define DBG_INC_WRITE_CNT(x...) do { } while (0)
#define DBG_INC_WRITE_CPY(x...) do { } while (0)
#define DBG_INC_TX_SPS_FAILURE_CNT() do { } while (0)
+#define DBG_INC_TX_STALL_CNT() do { } while (0)
#endif
struct bam_ch_info {
@@ -551,16 +557,16 @@
INIT_WORK(&pkt->work, bam_mux_write_done);
spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
list_add_tail(&pkt->list_node, &bam_tx_pool);
- spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
rc = sps_transfer_one(bam_tx_pipe, dma_address, len,
pkt, SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT);
if (rc) {
DBG("%s sps_transfer_one failed rc=%d\n", __func__, rc);
- spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
list_del(&pkt->list_node);
DBG_INC_TX_SPS_FAILURE_CNT();
spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
kfree(pkt);
+ } else {
+ spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
}
ul_packet_written = 1;
@@ -718,12 +724,10 @@
INIT_WORK(&pkt->work, bam_mux_write_done);
spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
list_add_tail(&pkt->list_node, &bam_tx_pool);
- spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
rc = sps_transfer_one(bam_tx_pipe, dma_address, skb->len,
pkt, SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT);
if (rc) {
DBG("%s sps_transfer_one failed rc=%d\n", __func__, rc);
- spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
list_del(&pkt->list_node);
DBG_INC_TX_SPS_FAILURE_CNT();
spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
@@ -731,6 +735,7 @@
if (new_skb)
dev_kfree_skb_any(new_skb);
} else {
+ spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
spin_lock_irqsave(&bam_ch[id].lock, flags);
bam_ch[id].num_tx_pkts++;
spin_unlock_irqrestore(&bam_ch[id].lock, flags);
@@ -1124,10 +1129,12 @@
i += scnprintf(buf + i, max - i,
"skb copy cnt: %u\n"
"skb copy bytes: %u\n"
- "sps tx failures: %u\n",
+ "sps tx failures: %u\n"
+ "sps tx stalls: %u\n",
bam_dmux_write_cpy_cnt,
bam_dmux_write_cpy_bytes,
- bam_dmux_tx_sps_failure_cnt
+ bam_dmux_tx_sps_failure_cnt,
+ bam_dmux_tx_stall_cnt
);
return i;
@@ -1241,9 +1248,25 @@
struct dentry *dent,
int (*fill)(char *buf, int max))
{
- debugfs_create_file(name, mode, dent, fill, &debug_ops);
+ struct dentry *file;
+
+ file = debugfs_create_file(name, mode, dent, fill, &debug_ops);
+ if (IS_ERR(file))
+ pr_err("%s: debugfs create failed %d\n", __func__,
+ (int)PTR_ERR(file));
}
+static void debug_create_multiple(const char *name, mode_t mode,
+ struct dentry *dent,
+ int (*fill)(char *buf, int max, loff_t *ppos))
+{
+ struct dentry *file;
+
+ file = debugfs_create_file(name, mode, dent, fill, &debug_ops_multiple);
+ if (IS_ERR(file))
+ pr_err("%s: debugfs create failed %d\n", __func__,
+ (int)PTR_ERR(file));
+}
#endif
static void notify_all(int event, unsigned long data)
@@ -1336,6 +1359,21 @@
return;
}
if (bam_is_connected) {
+ if (!ul_packet_written) {
+ spin_lock(&bam_tx_pool_spinlock);
+ if (!list_empty(&bam_tx_pool)) {
+ struct tx_pkt_info *info;
+
+ info = list_first_entry(&bam_tx_pool,
+ struct tx_pkt_info, list_node);
+ DMUX_LOG_KERR("%s: UL delayed ts=%u.%09lu\n",
+ __func__, info->ts_sec, info->ts_nsec);
+ DBG_INC_TX_STALL_CNT();
+ ul_packet_written = 1;
+ }
+ spin_unlock(&bam_tx_pool_spinlock);
+ }
+
if (ul_packet_written) {
bam_dmux_log("%s: packet written\n", __func__);
ul_packet_written = 0;
@@ -1370,7 +1408,7 @@
else
called_before = 1;
if (wait_for_dfab) {
- ret = wait_for_completion_interruptible_timeout(
+ ret = wait_for_completion_timeout(
&dfab_unvote_completion, HZ);
BUG_ON(ret == 0);
}
@@ -1389,7 +1427,7 @@
*/
if (wait_for_ack) {
bam_dmux_log("%s waiting for previous ack\n", __func__);
- ret = wait_for_completion_interruptible_timeout(
+ ret = wait_for_completion_timeout(
&ul_wakeup_ack_completion, HZ);
BUG_ON(ret == 0);
wait_for_ack = 0;
@@ -1397,12 +1435,10 @@
INIT_COMPLETION(ul_wakeup_ack_completion);
power_vote(1);
bam_dmux_log("%s waiting for wakeup ack\n", __func__);
- ret = wait_for_completion_interruptible_timeout(
- &ul_wakeup_ack_completion, HZ);
+ ret = wait_for_completion_timeout(&ul_wakeup_ack_completion, HZ);
BUG_ON(ret == 0);
bam_dmux_log("%s waiting completion\n", __func__);
- ret = wait_for_completion_interruptible_timeout(
- &bam_connection_completion, HZ);
+ ret = wait_for_completion_timeout(&bam_connection_completion, HZ);
BUG_ON(ret == 0);
bam_is_connected = 1;
@@ -1625,6 +1661,7 @@
int ret;
void *a2_virt_addr;
int i;
+ int skip_iounmap = 0;
vote_dfab();
/* init BAM */
@@ -1772,7 +1809,15 @@
sps_free_endpoint(bam_tx_pipe);
tx_mem_failed:
sps_deregister_bam_device(h);
+ /*
+ * sps_deregister_bam_device() calls iounmap. calling iounmap on the
+ * same handle below will cause a crash, so skip it if we've freed
+ * the handle here.
+ */
+ skip_iounmap = 1;
register_bam_failed:
+ if (!skip_iounmap)
+ iounmap(a2_virt_addr);
ioremap_failed:
/*destroy_workqueue(bam_mux_workqueue);*/
return ret;
@@ -1811,6 +1856,7 @@
return 0;
register_bam_failed:
+ iounmap(a2_virt_addr);
ioremap_failed:
return ret;
}
@@ -1986,8 +2032,7 @@
debug_create("tbl", 0444, dent, debug_tbl);
debug_create("ul_pkt_cnt", 0444, dent, debug_ul_pkt_cnt);
debug_create("stats", 0444, dent, debug_stats);
- debugfs_create_file("log", 0444, dent, debug_log,
- &debug_ops_multiple);
+ debug_create_multiple("log", 0444, dent, debug_log);
}
#endif
ret = kfifo_alloc(&bam_dmux_state_log, PAGE_SIZE, GFP_KERNEL);
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 1aedd55..a582260 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -46,6 +46,7 @@
#include <linux/bootmem.h>
#include <asm/setup.h>
#include <mach/dma.h>
+#include <mach/msm_bus_board.h>
#include "msm_watchdog.h"
#include "board-8064.h"
@@ -558,6 +559,22 @@
},
};
+static void __init apq8064_init_buses(void)
+{
+ msm_bus_rpm_set_mt_mask();
+ msm_bus_8064_apps_fabric_pdata.rpm_enabled = 1;
+ msm_bus_8064_sys_fabric_pdata.rpm_enabled = 1;
+ msm_bus_8064_mm_fabric_pdata.rpm_enabled = 1;
+ msm_bus_8064_apps_fabric.dev.platform_data =
+ &msm_bus_8064_apps_fabric_pdata;
+ msm_bus_8064_sys_fabric.dev.platform_data =
+ &msm_bus_8064_sys_fabric_pdata;
+ msm_bus_8064_mm_fabric.dev.platform_data =
+ &msm_bus_8064_mm_fabric_pdata;
+ msm_bus_8064_sys_fpb.dev.platform_data = &msm_bus_8064_sys_fpb_pdata;
+ msm_bus_8064_cpss_fpb.dev.platform_data = &msm_bus_8064_cpss_fpb_pdata;
+}
+
static struct platform_device *common_devices[] __initdata = {
&apq8064_device_dmov,
&apq8064_device_qup_i2c_gsbi4,
@@ -619,6 +636,11 @@
&apq_pcm_afe,
&apq_cpudai_auxpcm_rx,
&apq_cpudai_auxpcm_tx,
+ &msm_bus_8064_apps_fabric,
+ &msm_bus_8064_sys_fabric,
+ &msm_bus_8064_mm_fabric,
+ &msm_bus_8064_sys_fpb,
+ &msm_bus_8064_cpss_fpb,
};
static struct platform_device *sim_devices[] __initdata = {
@@ -631,6 +653,11 @@
&msm_device_sps_apq8064,
};
+static struct platform_device *cdp_devices[] __initdata = {
+ &apq8064_device_uart_gsbi1,
+ &msm_device_sps_apq8064,
+};
+
static struct msm_spi_platform_data apq8064_qup_spi_gsbi5_pdata = {
.max_clock_speed = 24000000,
};
@@ -712,6 +739,7 @@
&apq8064_qup_spi_gsbi5_pdata;
apq8064_init_pmic();
apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
+ apq8064_init_buses();
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
apq8064_init_mmc();
slim_register_board_info(apq8064_slim_devices,
@@ -736,6 +764,14 @@
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
}
+static void __init apq8064_cdp_init(void)
+{
+ apq8064_common_init();
+ ethernet_init();
+ platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
MACHINE_START(APQ8064_SIM, "QCT APQ8064 SIMULATOR")
.map_io = apq8064_map_io,
.reserve = apq8064_reserve,
@@ -754,3 +790,30 @@
.init_machine = apq8064_rumi3_init,
MACHINE_END
+MACHINE_START(APQ8064_CDP, "QCT APQ8064 CDP")
+ .map_io = apq8064_map_io,
+ .reserve = apq8064_reserve,
+ .init_irq = apq8064_init_irq,
+ .handle_irq = gic_handle_irq,
+ .timer = &msm_timer,
+ .init_machine = apq8064_cdp_init,
+MACHINE_END
+
+MACHINE_START(APQ8064_MTP, "QCT APQ8064 MTP")
+ .map_io = apq8064_map_io,
+ .reserve = apq8064_reserve,
+ .init_irq = apq8064_init_irq,
+ .handle_irq = gic_handle_irq,
+ .timer = &msm_timer,
+ .init_machine = apq8064_cdp_init,
+MACHINE_END
+
+MACHINE_START(APQ8064_LIQUID, "QCT APQ8064 LIQUID")
+ .map_io = apq8064_map_io,
+ .reserve = apq8064_reserve,
+ .init_irq = apq8064_init_irq,
+ .handle_irq = gic_handle_irq,
+ .timer = &msm_timer,
+ .init_machine = apq8064_cdp_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index cf7d6a9..fc9b58f 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -42,9 +42,11 @@
};
VREG_CONSUMERS(L5) = {
REGULATOR_SUPPLY("8038_l5", NULL),
+ REGULATOR_SUPPLY("sdc_vdd", "msm_sdcc.1"),
};
VREG_CONSUMERS(L6) = {
REGULATOR_SUPPLY("8038_l6", NULL),
+ REGULATOR_SUPPLY("sdc_vdd", "msm_sdcc.3"),
};
VREG_CONSUMERS(L7) = {
REGULATOR_SUPPLY("8038_l7", NULL),
@@ -67,6 +69,7 @@
REGULATOR_SUPPLY("vdd_dig", "3-004a"),
REGULATOR_SUPPLY("iris_vddio", "wcnss_wlan.0"),
REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
+ REGULATOR_SUPPLY("sdc_vccq", "msm_sdcc.1"),
};
VREG_CONSUMERS(L12) = {
REGULATOR_SUPPLY("8038_l12", NULL),
@@ -99,6 +102,7 @@
};
VREG_CONSUMERS(L22) = {
REGULATOR_SUPPLY("8038_l22", NULL),
+ REGULATOR_SUPPLY("sdc_vddp", "msm_sdcc.3"),
};
VREG_CONSUMERS(L23) = {
REGULATOR_SUPPLY("8038_l23", NULL),
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index d655ead..eee6d09 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -250,6 +250,8 @@
/*TODO: Insert right replacement for PM8038 */
#ifndef MSM8930_PHASE_2
.wpswitch_gpio = PM8921_GPIO_PM_TO_SYS(16),
+#else
+ .wpswitch_gpio = 66,
#endif
#endif
.vreg_data = &mmc_slot_vreg_data[SDCC3],
@@ -259,6 +261,9 @@
#ifndef MSM8930_PHASE_2
.status_gpio = PM8921_GPIO_PM_TO_SYS(26),
.status_irq = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
+#else
+ .status_gpio = 94,
+ .status_irq = MSM_GPIO_TO_INT(94),
#endif
.irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
.is_status_gpio_active_low = true,
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 2849945..fe125e3 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -117,22 +117,24 @@
#endif
-#define MSM_PMEM_ADSP_SIZE 0x3800000
+#define MSM_PMEM_ADSP_SIZE 0x7800000
#define MSM_PMEM_AUDIO_SIZE 0x2B4000
#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
#else
-#define MSM_PMEM_SIZE 0x1C00000 /* 28 Mbytes */
+#define MSM_PMEM_SIZE 0x2800000 /* 40 Mbytes */
#endif
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
#define MSM_PMEM_KERNEL_EBI1_SIZE 0xB0C000
-#define MSM_ION_SF_SIZE 0x2800000 /* 40MB */
+#define MSM_ION_SF_SIZE MSM_PMEM_SIZE
#define MSM_ION_MM_FW_SIZE 0x200000 /* (2MB) */
-#define MSM_ION_MM_SIZE 0x4000000 /* (64MB) */
+#define MSM_ION_MM_SIZE MSM_PMEM_ADSP_SIZE
+#define MSM_ION_QSECOM_SIZE 0x100000 /* (1MB) */
#define MSM_ION_MFC_SIZE SZ_8K
-#define MSM_ION_HEAP_NUM 6
+#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
+#define MSM_ION_HEAP_NUM 8
#else
#define MSM_PMEM_KERNEL_EBI1_SIZE 0x110C000
#define MSM_ION_HEAP_NUM 1
@@ -348,6 +350,22 @@
.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,
+ },
#endif
}
};
@@ -366,6 +384,8 @@
msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_SIZE;
msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+ msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+ msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
#endif
}
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index b67fdd0..598e18d 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -130,7 +130,7 @@
#endif
-#define MSM_PMEM_ADSP_SIZE 0x4200000
+#define MSM_PMEM_ADSP_SIZE 0x7800000
#define MSM_PMEM_AUDIO_SIZE 0x2B4000
#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
@@ -141,11 +141,13 @@
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
#define MSM_PMEM_KERNEL_EBI1_SIZE 0xB0C000
-#define MSM_ION_SF_SIZE 0x2800000 /* (40MB) */
+#define MSM_ION_SF_SIZE MSM_PMEM_SIZE
#define MSM_ION_MM_FW_SIZE 0x200000 /* (2MB) */
-#define MSM_ION_MM_SIZE 0x4000000 /* (64MB) */
+#define MSM_ION_MM_SIZE MSM_PMEM_ADSP_SIZE
+#define MSM_ION_QSECOM_SIZE 0x100000 /* (1MB) */
#define MSM_ION_MFC_SIZE SZ_8K
-#define MSM_ION_HEAP_NUM 6
+#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
+#define MSM_ION_HEAP_NUM 8
#define MSM_LIQUID_ION_MM_SIZE (MSM_ION_MM_SIZE + 0x600000)
static unsigned int msm_ion_cp_mm_size = MSM_ION_MM_SIZE;
#else
@@ -377,6 +379,22 @@
.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,
+ },
#endif
}
};
@@ -414,6 +432,8 @@
msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+ msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+ msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
#endif
}
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index f26187e..5f31f88 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -18,6 +18,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
+#include <linux/of_irq.h>
#include <asm/mach/map.h>
#include <asm/hardware/gic.h>
#include <mach/board.h>
@@ -43,24 +44,20 @@
{
}
-static struct of_device_id msm_copper_gic_match[] __initdata = {
- { .compatible = "qcom,msm-qgic2", },
+static struct of_device_id irq_match[] __initdata = {
+ { .compatible = "qcom,msm-qgic2", .data = gic_of_init, },
{}
};
void __init msm_copper_init_irq(void)
{
- gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
- (void *)MSM_QGIC_CPU_BASE);
-
/* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
mb();
- irq_domain_generate_simple(msm_copper_gic_match,
- COPPER_QGIC_DIST_PHYS, GIC_SPI_START);
+ of_irq_init(irq_match);
}
static struct clk_lookup msm_clocks_dummy[] = {
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 19f54cf..6c5f74a 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -28,7 +28,7 @@
{
struct device_node *node;
struct resource res;
- struct of_irq oirq;
+ int rc;
node = of_find_compatible_node(NULL, NULL, "qcom,msm-qtimer");
if (!node) {
@@ -36,13 +36,12 @@
return;
}
- if (of_irq_map_one(node, 0, &oirq)) {
+ rc = of_irq_to_resource(node, 0, &res);
+ if (rc < 0)
pr_err("interrupt not specified in timer node\n");
- } else {
- res.start = res.end = oirq.specifier[0];
- res.flags = IORESOURCE_IRQ;
+ else
arch_timer_register(&res, 1);
- }
+
of_node_put(node);
}
@@ -98,4 +97,5 @@
.handle_irq = gic_handle_irq,
.timer = &msm_dt_timer,
.dt_compat = msm_dt_match,
+ .nr_irqs = -1,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index d4f06fa..8b3b606 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.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
@@ -677,11 +677,9 @@
pr_err("%s: could not enable regulator: %d\n", __func__, rc);
goto reg_fail;
}
- if (machine_is_msm7627a_qrd1())
- gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
- GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
- GPIO_CFG_2MA), GPIO_CFG_ENABLE);
-
+ gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
/*setup Bahama_sys_reset_n*/
rc = gpio_request(gpio_bt_sys_rest_en, "bahama sys_rst_n");
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 68c5059..09f70f1 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4450,11 +4450,7 @@
static DEFINE_CLK_VOTER(dfab_scm_clk, &dfab_clk.c);
static DEFINE_CLK_VOTER(ebi1_msmbus_clk, &ebi1_clk.c);
-/*
- * TODO: replace dummy_clk below with ebi1_clk.c once the
- * bus driver starts voting on ebi1 rates.
- */
-static DEFINE_CLK_VOTER(ebi1_adm_clk, &dummy_clk);
+static DEFINE_CLK_VOTER(ebi1_adm_clk, &ebi1_clk.c);
#ifdef CONFIG_DEBUG_FS
struct measure_sel {
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index c33daf7..3e57ebc 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1671,6 +1671,11 @@
CLK_LOOKUP("core_clk", usb_hsic_sys_clk.c, "msm_hsic_host"),
CLK_LOOKUP("iface_clk", usb_hsic_p_clk.c, "msm_hsic_host"),
CLK_LOOKUP("phy_clk", usb_hsic_clk.c, "msm_hsic_host"),
+ CLK_LOOKUP("alt_core_clk", usb_hsic_xcvr_clk.c, "msm_hsic_peripheral"),
+ CLK_LOOKUP("cal_clk", usb_hsic_hsio_cal_clk.c, "msm_hsic_peripheral"),
+ CLK_LOOKUP("core_clk", usb_hsic_sys_clk.c, "msm_hsic_peripheral"),
+ CLK_LOOKUP("iface_clk", usb_hsic_p_clk.c, "msm_hsic_peripheral"),
+ CLK_LOOKUP("phy_clk", usb_hsic_clk.c, "msm_hsic_peripheral"),
CLK_LOOKUP("iface_clk", sdc1_p_clk.c, "msm_sdcc.1"),
CLK_LOOKUP("iface_clk", sdc2_p_clk.c, "msm_sdcc.2"),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 12a00e6..9c77f3d 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -24,6 +24,7 @@
#include <mach/dma.h>
#include <sound/msm-dai-q6.h>
#include <sound/apr_audio.h>
+#include <mach/msm_bus_board.h>
#include "clock.h"
#include "devices.h"
#include "msm_watchdog.h"
@@ -694,6 +695,27 @@
},
};
+struct platform_device msm_bus_8064_sys_fabric = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_SYSTEM,
+};
+struct platform_device msm_bus_8064_apps_fabric = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_APPSS,
+};
+struct platform_device msm_bus_8064_mm_fabric = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_MMSS,
+};
+struct platform_device msm_bus_8064_sys_fpb = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_SYSTEM_FPB,
+};
+struct platform_device msm_bus_8064_cpss_fpb = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_CPSS_FPB,
+};
+
static struct msm_sps_platform_data msm_sps_pdata = {
.bamdma_restricted_pipes = 0x06,
};
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 33a543d..5d28fa9 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -264,3 +264,9 @@
extern struct platform_device msm_funnel_device;
extern struct platform_device msm_ptm_device;
#endif
+
+extern struct platform_device msm_bus_8064_apps_fabric;
+extern struct platform_device msm_bus_8064_sys_fabric;
+extern struct platform_device msm_bus_8064_mm_fabric;
+extern struct platform_device msm_bus_8064_sys_fpb;
+extern struct platform_device msm_bus_8064_cpss_fpb;
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index fd282d5..8961c79 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -155,8 +155,12 @@
struct msm_vpe_phy_info {
uint32_t sbuf_phy;
- uint32_t y_phy;
- uint32_t cbcr_phy;
+ uint32_t planar0_off;
+ uint32_t planar1_off;
+ uint32_t planar2_off;
+ uint32_t p0_phy;
+ uint32_t p1_phy;
+ uint32_t p2_phy;
uint8_t output_id; /* VFE31_OUTPUT_MODE_PT/S/V */
uint32_t frame_id;
};
@@ -193,6 +197,7 @@
#define VFE31_OUTPUT_MODE_V (0x1 << 2)
#define VFE31_OUTPUT_MODE_P (0x1 << 3)
#define VFE31_OUTPUT_MODE_T (0x1 << 4)
+#define VFE31_OUTPUT_MODE_P_ALL_CHNLS (0x1 << 5)
#define CSI_EMBED_DATA 0x12
#define CSI_YUV422_8 0x1E
@@ -206,8 +211,12 @@
struct msm_vfe_phy_info {
uint32_t sbuf_phy;
- uint32_t y_phy;
- uint32_t cbcr_phy;
+ uint32_t planar0_off;
+ uint32_t planar1_off;
+ uint32_t planar2_off;
+ uint32_t p0_phy;
+ uint32_t p1_phy;
+ uint32_t p2_phy;
uint8_t output_id; /* VFE31_OUTPUT_MODE_PT/S/V */
uint32_t frame_id;
};
@@ -238,8 +247,8 @@
};
struct msm_vpe_buf_info {
- uint32_t y_phy;
- uint32_t cbcr_phy;
+ uint32_t p0_phy;
+ uint32_t p1_phy;
struct timespec ts;
uint32_t frame_id;
struct video_crop_t vpe_crop;
@@ -303,7 +312,7 @@
struct msm_camvpe_fn {
int (*vpe_reg)(struct msm_vpe_callback *);
int (*vpe_cfg_update) (void *);
- void (*send_frame_to_vpe) (uint32_t y_phy, uint32_t cbcr_phy,
+ void (*send_frame_to_vpe) (uint32_t planar0_off, uint32_t planar1_off,
struct timespec *ts, int output_id);
int (*vpe_config)(struct msm_vpe_cfg_cmd *, void *);
void (*vpe_cfg_offset)(int frame_pack, uint32_t pyaddr,
diff --git a/arch/arm/mach-msm/include/mach/irqs-copper.h b/arch/arm/mach-msm/include/mach/irqs-copper.h
index 24da0a4..821eaeb 100644
--- a/arch/arm/mach-msm/include/mach/irqs-copper.h
+++ b/arch/arm/mach-msm/include/mach/irqs-copper.h
@@ -34,7 +34,7 @@
#define TLMM_MSM_SUMMARY_IRQ (GIC_SPI_START + 16)
#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105)
-#define NR_MSM_IRQS 256
+#define NR_MSM_IRQS 1020 /* Should be 256 - but higher due to bug in sim */
#define NR_GPIO_IRQS 156
#define NR_BOARD_IRQS 100
#define NR_TLMM_MSM_DIR_CONN_IRQ 8
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index 9cd73db..e1fc054 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/include/mach/memory.h
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-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
@@ -23,8 +23,13 @@
#define MAX_PHYSMEM_BITS 32
#define SECTION_SIZE_BITS 28
-/* Maximum number of Memory Regions */
-#define MAX_NR_REGIONS 4
+/* Maximum number of Memory Regions
+* The largest system can have 4 memory banks, each divided into 8 regions
+*/
+#define MAX_NR_REGIONS 32
+
+/* The number of regions each memory bank is divided into */
+#define NR_REGIONS_PER_BANK 8
/* Certain configurations of MSM7x30 have multiple memory banks.
* One or more of these banks can contain holes in the memory map as well.
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
index 7f5bd75..15b2856 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
@@ -77,4 +77,25 @@
#define APQ8064_IMEM_PHYS 0x2A03F000
#define APQ8064_IMEM_SIZE SZ_4K
+#define APQ8064_RPM_PHYS 0x00108000
+#define APQ8064_RPM_SIZE SZ_4K
+
+#define APQ8064_RPM_MPM_PHYS 0x00200000
+#define APQ8064_RPM_MPM_SIZE SZ_4K
+
+#define APQ8064_SAW0_PHYS 0x02089000
+#define APQ8064_SAW0_SIZE SZ_4K
+
+#define APQ8064_SAW1_PHYS 0x02099000
+#define APQ8064_SAW1_SIZE SZ_4K
+
+#define APQ8064_SAW2_PHYS 0x020A9000
+#define APQ8064_SAW2_SIZE SZ_4K
+
+#define APQ8064_SAW3_PHYS 0x020B9000
+#define APQ8064_SAW3_SIZE SZ_4K
+
+#define APQ8064_SAW_L2_PHYS 0x02012000
+#define APQ8064_SAW_L2_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 dd01c62..ff0b368 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -75,8 +75,10 @@
#define MSM_RPM_BASE IOMEM(0xFA801000) /* 4K */
#define MSM_RPM_MPM_BASE IOMEM(0xFA802000) /* 4K */
#define MSM_QFPROM_BASE IOMEM(0xFA700000) /* 4K */
-#define MSM_L2CC_BASE IOMEM(0xFA701000) /* 4K */
-#define MSM_APCS_GLB_BASE IOMEM(0xFA702000) /* 4K */
+#define MSM_L2CC_BASE IOMEM(0xFA701000) /* 4K */
+#define MSM_APCS_GLB_BASE IOMEM(0xFA702000) /* 4K */
+#define MSM_SAW2_BASE IOMEM(0xFA703000) /* 4k */
+#define MSM_SAW3_BASE IOMEM(0xFA704000) /* 4k */
#if defined(CONFIG_ARCH_MSM9615)
#define MSM_SHARED_RAM_SIZE SZ_1M
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 2d5b0a4..9622a4c 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -265,6 +265,13 @@
MSM_CHIP_DEVICE(MMSS_CLK_CTL, APQ8064),
MSM_CHIP_DEVICE(LPASS_CLK_CTL, APQ8064),
MSM_CHIP_DEVICE(APCS_GCC, APQ8064),
+ MSM_CHIP_DEVICE(RPM, APQ8064),
+ MSM_CHIP_DEVICE(RPM_MPM, APQ8064),
+ MSM_CHIP_DEVICE(SAW0, APQ8064),
+ MSM_CHIP_DEVICE(SAW1, APQ8064),
+ MSM_CHIP_DEVICE(SAW2, APQ8064),
+ MSM_CHIP_DEVICE(SAW3, APQ8064),
+ MSM_CHIP_DEVICE(SAW_L2, APQ8064),
MSM_CHIP_DEVICE(IMEM, APQ8064),
{
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
diff --git a/arch/arm/mach-msm/memory_topology.c b/arch/arm/mach-msm/memory_topology.c
index 5854a23..6208a0d 100644
--- a/arch/arm/mach-msm/memory_topology.c
+++ b/arch/arm/mach-msm/memory_topology.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
@@ -31,11 +31,11 @@
/* reserved for future use */
u64 num_partitions;
int state;
- int mask;
- struct mutex state_mutex;
} mem_regions[MAX_NR_REGIONS];
+static struct mutex mem_regions_mutex;
static unsigned int nr_mem_regions;
+static int mem_regions_mask;
enum {
STATE_POWER_DOWN = 0x0,
@@ -43,14 +43,6 @@
STATE_DEFAULT = STATE_ACTIVE
};
-enum {
- MEM_NO_CHANGE = 0x0,
- MEM_DEEP_POWER_DOWN,
- MEM_SELF_REFRESH,
-};
-
-static unsigned int dmm_mode;
-
static int default_mask = ~0x0;
/* Return the number of chipselects populated with a memory bank */
@@ -111,50 +103,55 @@
}
}
-static int switch_memory_state(int id, int new_state)
+static int switch_memory_state(int mask, int new_state, int start_region,
+ int end_region)
{
- int mask = 0;
- int power_down_masks[MAX_NR_REGIONS] = { 0xFFFFFF00, 0xFFFF00FF,
- 0xFF00FFFF, 0x00FFFFFF };
- int self_refresh_masks[MAX_NR_REGIONS] = { 0xFFFFFFF0, 0xFFFFFF0F,
- 0xFFFFF0FF, 0xFFFF0FFF };
- mutex_lock(&mem_regions[id].state_mutex);
+ int final_mask = 0;
+ int i;
- if (new_state == mem_regions[id].state)
- goto no_change;
+ mutex_lock(&mem_regions_mutex);
- pr_info("request memory %d state switch (%d->%d) mode %d\n", id,
- mem_regions[id].state, new_state, dmm_mode);
- if (new_state == STATE_POWER_DOWN) {
- if (dmm_mode == MEM_DEEP_POWER_DOWN)
- mask = mem_regions[id].mask & power_down_masks[id];
- else
- mask = mem_regions[id].mask & self_refresh_masks[id];
- } else if (new_state == STATE_ACTIVE) {
- if (dmm_mode == MEM_DEEP_POWER_DOWN)
- mask = mem_regions[id].mask | (~power_down_masks[id]);
- else
- mask = mem_regions[id].mask | (~self_refresh_masks[id]);
+ for (i = start_region; i <= end_region; i++) {
+ if (new_state == mem_regions[i].state)
+ goto no_change;
+ /* All region states must be the same to change them */
+ if (mem_regions[i].state != mem_regions[start_region].state)
+ goto no_change;
}
- if (rpm_change_memory_state(mask, mask) == 0) {
- mem_regions[id].state = new_state;
- mem_regions[id].mask = mask;
- pr_info("completed memory %d state switch to %d mode %d\n",
- id, new_state, dmm_mode);
- mutex_unlock(&mem_regions[id].state_mutex);
+ if (new_state == STATE_POWER_DOWN)
+ final_mask = mem_regions_mask & mask;
+ else if (new_state == STATE_ACTIVE)
+ final_mask = mem_regions_mask | ~mask;
+ else
+ goto no_change;
+
+ pr_info("request memory %d to %d state switch (%d->%d)\n",
+ start_region, end_region, mem_regions[start_region].state,
+ new_state);
+ if (rpm_change_memory_state(final_mask, final_mask) == 0) {
+ for (i = start_region; i <= end_region; i++)
+ mem_regions[i].state = new_state;
+ mem_regions_mask = final_mask;
+
+ pr_info("completed memory %d to %d state switch to %d\n",
+ start_region, end_region, new_state);
+ mutex_unlock(&mem_regions_mutex);
return 0;
}
- pr_err("failed memory %d state switch (%d->%d) mode %d\n", id,
- mem_regions[id].state, new_state, dmm_mode);
+ pr_err("failed memory %d to %d state switch (%d->%d)\n",
+ start_region, end_region, mem_regions[start_region].state,
+ new_state);
+
no_change:
- mutex_unlock(&mem_regions[id].state_mutex);
+ mutex_unlock(&mem_regions_mutex);
return -EINVAL;
}
#else
-static int switch_memory_state(int id, int new_state)
+static int switch_memory_state(int mask, int new_state, int start_region,
+ int end_region)
{
return -EINVAL;
}
@@ -165,29 +162,34 @@
*/
int soc_change_memory_power(u64 start, u64 size, int change)
{
-
int i = 0;
- int match = 0;
-
- /* Find the memory region starting just below start */
- for (i = 0; i < nr_mem_regions; i++) {
- if (mem_regions[i].start <= start &&
- mem_regions[i].start >= mem_regions[match].start) {
- match = i;
- }
- }
-
- if (start + size > mem_regions[match].start + mem_regions[match].size) {
- pr_info("passed size exceeds size of memory bank\n");
- return 0;
- }
+ int mask = default_mask;
+ u64 end = start + size;
+ int start_region = 0;
+ int end_region = 0;
if (change != STATE_ACTIVE && change != STATE_POWER_DOWN) {
pr_info("requested state transition invalid\n");
return 0;
}
+ /* Find the memory regions that fall within the range */
+ for (i = 0; i < nr_mem_regions; i++) {
+ if (mem_regions[i].start <= start &&
+ mem_regions[i].start >=
+ mem_regions[start_region].start) {
+ start_region = i;
+ }
+ if (end <= mem_regions[i].start + mem_regions[i].size) {
+ end_region = i;
+ break;
+ }
+ }
- if (!switch_memory_state(match, change))
+ /* Set the bitmask for each region in the range */
+ for (i = start_region; i <= end_region; i++)
+ mask &= ~(0x1 << i);
+
+ if (!switch_memory_state(mask, change, start_region, end_region))
return size;
else
return 0;
@@ -212,9 +214,10 @@
int __init meminfo_init(unsigned int type, unsigned int min_bank_size)
{
- unsigned int i;
+ unsigned int i, j;
unsigned long bank_size;
unsigned long bank_start;
+ unsigned long region_size;
struct smem_ram_ptable *ram_ptable;
/* physical memory banks */
unsigned int nr_mem_banks = 0;
@@ -229,40 +232,35 @@
return -EINVAL;
}
- /* Determine power control mode based on the hw version */
- /* This check will be removed when PASR is fully supported */
- if (cpu_is_msm8960() &&
- SOCINFO_VERSION_MAJOR(socinfo_get_version()) < 2)
- dmm_mode = MEM_DEEP_POWER_DOWN;
- else
- dmm_mode = MEM_SELF_REFRESH;
-
pr_info("meminfo_init: smem ram ptable found: ver: %d len: %d\n",
ram_ptable->version, ram_ptable->len);
for (i = 0; i < ram_ptable->len; i++) {
+ /* A bank is valid only if is greater than min_bank_size. If
+ * non-valid memory (e.g. modem memory) became greater than
+ * min_bank_size, there is currently no way to differentiate.
+ */
if (ram_ptable->parts[i].type == type &&
ram_ptable->parts[i].size >= min_bank_size) {
bank_start = ram_ptable->parts[i].start;
bank_size = ram_ptable->parts[i].size;
- /* Divide into logical memory regions of same size */
- while (bank_size) {
+ region_size = bank_size / NR_REGIONS_PER_BANK;
+
+ for (j = 0; j < NR_REGIONS_PER_BANK; j++) {
mem_regions[nr_mem_regions].start =
bank_start;
mem_regions[nr_mem_regions].size =
- MIN_MEMORY_BLOCK_SIZE;
- mutex_init(&mem_regions[nr_mem_regions]
- .state_mutex);
+ region_size;
mem_regions[nr_mem_regions].state =
STATE_DEFAULT;
- mem_regions[nr_mem_regions].mask = default_mask;
- bank_start += MIN_MEMORY_BLOCK_SIZE;
- bank_size -= MIN_MEMORY_BLOCK_SIZE;
+ bank_start += region_size;
nr_mem_regions++;
}
nr_mem_banks++;
}
}
+ mutex_init(&mem_regions_mutex);
+ mem_regions_mask = default_mask;
pr_info("Found %d memory banks grouped into %d memory regions\n",
nr_mem_banks, nr_mem_regions);
return 0;
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
index 8175738..feabe04 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.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
@@ -305,7 +305,13 @@
*info->link_info.sel_bw += add_bw;
info->pnode[index].sel_bw = &info->pnode[index].bw[ctx];
- info->pnode[index].sel_clk = &info->pnode[index].clk[ctx];
+
+ /**
+ * To select the right clock, AND the context with
+ * client active flag.
+ */
+ info->pnode[index].sel_clk = &info->pnode[index].clk[ctx &
+ cl_active_flag];
*info->pnode[index].sel_bw += add_bw;
info->link_info.num_tiers = info->node_info->num_tiers;
@@ -345,7 +351,8 @@
*hop->link_info.sel_bw += add_bw;
hop->pnode[index].sel_bw = &hop->pnode[index].bw[ctx];
- hop->pnode[index].sel_clk = &hop->pnode[index].clk[ctx];
+ hop->pnode[index].sel_clk = &hop->pnode[index].clk[ctx &
+ cl_active_flag];
if (!hop->node_info->buswidth) {
MSM_BUS_WARN("No bus width found. Using default\n");
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index b06e5dd..3b178b5 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.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
@@ -216,6 +216,13 @@
struct msm_bus_fabric *fabric = to_msm_bus_fabric(fabdev);
struct nodeclk *nodeclk;
+ /**
+ * Integration for clock rates is not required if context is not
+ * same as client's active-only flag
+ */
+ if (ctx != cl_active_flag)
+ goto skip_set_clks;
+
/* Maximum for this gateway */
for (i = 0; i <= slave->num_pnodes; i++) {
if (i == index && (req_clk_hz < curr_clk_hz))
@@ -272,13 +279,7 @@
if (clk_flag) {
nodeclk = &fabric->info.nodeclk[ctx];
- /**
- * Send a clock request only when the client requests in active
- * context and the ACTIVE_CTX clock rate is selected OR the
- * client request is in normal context and normal clock rate
- * is selected.
- */
- if (nodeclk->clk && (!((ctx == ACTIVE_CTX) ^ cl_active_flag))) {
+ if (nodeclk->clk) {
MSM_BUS_DBG("clks: id: %d set-clk: %lu bwsum_hz:%lu\n",
fabric->fabdev.id, *pclk, bwsum_hz);
if (nodeclk->rate != *pclk) {
@@ -289,7 +290,7 @@
}
} else {
nodeclk = &slave->nodeclk[ctx];
- if (nodeclk->clk && (!((ctx == ACTIVE_CTX) ^ cl_active_flag))) {
+ if (nodeclk->clk) {
rate = *pclk;
MSM_BUS_DBG("AXI_clks: id: %d set-clk: %lu "
"bwsum_hz: %lu\n" , slave->node_info->priv_id, rate,
@@ -299,8 +300,7 @@
nodeclk->rate = rate;
}
}
- if (!status && slave->memclk.clk &&
- (!((ctx == ACTIVE_CTX) ^ cl_active_flag))) {
+ if (!status && slave->memclk.clk) {
rate = *slave->link_info.sel_clk;
if (slave->memclk.rate != rate) {
slave->memclk.rate = rate;
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index d73d4a0..f1c6c48 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -31,13 +31,8 @@
int pen_release = -1;
-/* Initialize the present map (cpu_set(i, cpu_present_map)). */
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
-
- for (i = 0; i < max_cpus; i++)
- cpu_set(i, cpu_present_map);
}
void __init smp_init_cpus(void)
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index ecfe93c..ce65e93 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -125,14 +125,6 @@
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
-
- /*
- * Initialise the present map, which describes the set of CPUs
- * actually populated at the present time.
- */
- for (i = 0; i < max_cpus; i++)
- set_cpu_present(i, true);
/*
* Initialise the SCU and wake up the secondary core using
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 963bf0d..4ae943b 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -68,14 +68,6 @@
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
-
- /*
- * Initialise the present map, which describes the set of CPUs
- * actually populated at the present time.
- */
- for (i = 0; i < max_cpus; i++)
- set_cpu_present(i, true);
scu_enable(scu_base_addr());
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
index f3888fe..66f9806 100644
--- a/arch/arm/mach-shmobile/platsmp.c
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -64,10 +64,5 @@
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
-
- for (i = 0; i < max_cpus; i++)
- set_cpu_present(i, true);
-
shmobile_smp_prepare_cpus();
}
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index b8ae3c9..1a594dc 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -129,14 +129,6 @@
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
-
- /*
- * Initialise the present map, which describes the set of CPUs
- * actually populated at the present time.
- */
- for (i = 0; i < max_cpus; i++)
- set_cpu_present(i, true);
scu_enable(scu_base);
}
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 0c527fe..a33df5f 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -172,14 +172,6 @@
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
-
- /*
- * Initialise the present map, which describes the set of CPUs
- * actually populated at the present time.
- */
- for (i = 0; i < max_cpus; i++)
- set_cpu_present(i, true);
scu_enable(scu_base_addr());
wakeup_secondary();
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 765a71f..bfd32f5 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -229,10 +229,6 @@
static void ct_ca9x4_smp_enable(unsigned int max_cpus)
{
- int i;
- for (i = 0; i < max_cpus; i++)
- set_cpu_present(i, true);
-
scu_enable(MMIO_P2V(A9_MPCORE_SCU));
}
#endif
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 101697f..4e78152 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -2,7 +2,7 @@
* HCI_SMD (HCI Shared Memory Driver) is Qualcomm's Shared memory driver
* for the BT HCI protocol.
*
- * Copyright (c) 2000-2001, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum. All rights reserved.
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
*
@@ -51,8 +51,7 @@
struct wake_lock wake_lock_tx;
struct wake_lock wake_lock_rx;
struct timer_list rx_q_timer;
- struct tasklet_struct hci_event_task;
- struct tasklet_struct hci_data_task;
+ struct tasklet_struct rx_task;
};
static struct hci_smd_data hs;
@@ -129,111 +128,95 @@
kfree(hdev->driver_data);
}
-static void hci_smd_recv_data(unsigned long arg)
+static void hci_smd_recv_data(void)
{
int len = 0;
int rc = 0;
struct sk_buff *skb = NULL;
- unsigned char *buf = NULL;
struct hci_smd_data *hsmd = &hs;
wake_lock(&hs.wake_lock_rx);
len = smd_read_avail(hsmd->data_channel);
if (len > HCI_MAX_FRAME_SIZE) {
- BT_ERR("Frame larger than the allowed size");
+ BT_ERR("Frame larger than the allowed size, flushing frame");
+ smd_read(hsmd->data_channel, NULL, len);
goto out_data;
}
- while (len > 0) {
- skb = bt_skb_alloc(len, GFP_ATOMIC);
- if (!skb) {
- BT_ERR("Error in allocating socket buffer");
- goto out_data;
- }
- buf = kmalloc(len, GFP_ATOMIC);
- if (!buf) {
- BT_ERR("Error in allocating buffer");
- rc = -ENOMEM;
- goto out_data;
- }
+ if (len <= 0)
+ goto out_data;
- rc = smd_read(hsmd->data_channel, (void *)buf, len);
- if (rc < len) {
- BT_ERR("Error in reading from the channel");
- goto out_data;
- }
-
- memcpy(skb_put(skb, len), buf, len);
- skb->dev = (void *)hsmd->hdev;
- bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
-
- skb_orphan(skb);
-
- rc = hci_recv_frame(skb);
- if (rc < 0) {
- BT_ERR("Error in passing the packet to HCI Layer");
- /*
- * skb is getting freed in hci_recv_frame, making it
- * to null to avoid multiple access
- */
- skb = NULL;
- goto out_data;
- }
-
- kfree(buf);
- buf = NULL;
- len = smd_read_avail(hsmd->data_channel);
- /*
- * Start the timer to monitor whether the Rx queue is
- * empty for releasing the Rx wake lock
- */
- BT_DBG("Rx Timer is starting");
- mod_timer(&hsmd->rx_q_timer,
- jiffies + msecs_to_jiffies(RX_Q_MONITOR));
+ skb = bt_skb_alloc(len, GFP_ATOMIC);
+ if (!skb) {
+ BT_ERR("Error in allocating socket buffer");
+ smd_read(hsmd->data_channel, NULL, len);
+ goto out_data;
}
+
+ rc = smd_read(hsmd->data_channel, skb_put(skb, len), len);
+ if (rc < len) {
+ BT_ERR("Error in reading from the channel");
+ goto out_data;
+ }
+
+ skb->dev = (void *)hsmd->hdev;
+ bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
+ skb_orphan(skb);
+
+ rc = hci_recv_frame(skb);
+ if (rc < 0) {
+ BT_ERR("Error in passing the packet to HCI Layer");
+ /*
+ * skb is getting freed in hci_recv_frame, making it
+ * to null to avoid multiple access
+ */
+ skb = NULL;
+ goto out_data;
+ }
+
+ /*
+ * Start the timer to monitor whether the Rx queue is
+ * empty for releasing the Rx wake lock
+ */
+ BT_DBG("Rx Timer is starting");
+ mod_timer(&hsmd->rx_q_timer,
+ jiffies + msecs_to_jiffies(RX_Q_MONITOR));
+
out_data:
release_lock();
- if (rc) {
- if (skb)
- kfree_skb(skb);
- kfree(buf);
- }
+ if (rc)
+ kfree_skb(skb);
}
-static void hci_smd_recv_event(unsigned long arg)
+static void hci_smd_recv_event(void)
{
int len = 0;
int rc = 0;
struct sk_buff *skb = NULL;
- unsigned char *buf = NULL;
struct hci_smd_data *hsmd = &hs;
wake_lock(&hs.wake_lock_rx);
len = smd_read_avail(hsmd->event_channel);
if (len > HCI_MAX_FRAME_SIZE) {
- BT_ERR("Frame larger than the allowed size");
+ BT_ERR("Frame larger than the allowed size, flushing frame");
+ rc = smd_read(hsmd->event_channel, NULL, len);
goto out_event;
}
while (len > 0) {
skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!skb) {
- BT_ERR("Error in allocating socket buffer");
+ BT_ERR("Error in allocating socket buffer");
+ smd_read(hsmd->event_channel, NULL, len);
goto out_event;
}
- buf = kmalloc(len, GFP_ATOMIC);
- if (!buf) {
- BT_ERR("Error in allocating buffer");
- rc = -ENOMEM;
- goto out_event;
- }
- rc = smd_read(hsmd->event_channel, (void *)buf, len);
+
+ rc = smd_read(hsmd->event_channel, skb_put(skb, len), len);
if (rc < len) {
BT_ERR("Error in reading from the event channel");
goto out_event;
}
- memcpy(skb_put(skb, len), buf, len);
skb->dev = (void *)hsmd->hdev;
bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
@@ -250,8 +233,6 @@
goto out_event;
}
- kfree(buf);
- buf = NULL;
len = smd_read_avail(hsmd->event_channel);
/*
* Start the timer to monitor whether the Rx queue is
@@ -263,11 +244,8 @@
}
out_event:
release_lock();
- if (rc) {
- if (skb)
- kfree_skb(skb);
- kfree(buf);
- }
+ if (rc)
+ kfree_skb(skb);
}
static int hci_smd_send_frame(struct sk_buff *skb)
@@ -314,6 +292,16 @@
return ret;
}
+static void hci_smd_rx(unsigned long arg)
+{
+ struct hci_smd_data *hsmd = &hs;
+
+ while ((smd_read_avail(hsmd->event_channel) > 0) ||
+ (smd_read_avail(hsmd->data_channel) > 0)) {
+ hci_smd_recv_event();
+ hci_smd_recv_data();
+ }
+}
static void hci_smd_notify_event(void *data, unsigned int event)
{
@@ -330,7 +318,7 @@
case SMD_EVENT_DATA:
len = smd_read_avail(hsmd->event_channel);
if (len > 0)
- tasklet_hi_schedule(&hs.hci_event_task);
+ tasklet_hi_schedule(&hs.rx_task);
else if (len < 0)
BT_ERR("Failed to read event from smd %d", len);
@@ -355,7 +343,7 @@
int len = 0;
if (!hdev) {
- BT_ERR("HCI device (hdev=NULL)");
+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return;
}
@@ -363,7 +351,7 @@
case SMD_EVENT_DATA:
len = smd_read_avail(hsmd->data_channel);
if (len > 0)
- tasklet_hi_schedule(&hs.hci_data_task);
+ tasklet_hi_schedule(&hs.rx_task);
else if (len < 0)
BT_ERR("Failed to read data from smd %d", len);
break;
@@ -402,10 +390,9 @@
hdev->destruct = hci_smd_destruct;
hdev->owner = THIS_MODULE;
- tasklet_init(&hsmd->hci_event_task,
- hci_smd_recv_event, (unsigned long) hsmd);
- tasklet_init(&hsmd->hci_data_task,
- hci_smd_recv_data, (unsigned long) hsmd);
+
+ tasklet_init(&hsmd->rx_task,
+ hci_smd_rx, (unsigned long) hsmd);
/*
* Setup the timer to monitor whether the Rx queue is empty,
* to control the wake lock release
@@ -445,6 +432,8 @@
static void hci_smd_deregister_dev(struct hci_smd_data *hsmd)
{
+ tasklet_kill(&hs.rx_task);
+
if (hsmd->hdev) {
if (hci_unregister_dev(hsmd->hdev) < 0)
BT_ERR("Can't unregister HCI device %s",
@@ -468,9 +457,6 @@
hs.rx_q_timer.function = NULL;
hs.rx_q_timer.data = 0;
}
-
- tasklet_kill(&hs.hci_event_task);
- tasklet_kill(&hs.hci_data_task);
}
static int hcismd_set_enable(const char *val, struct kernel_param *kp)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 4168c88..c44cde8 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -2,3 +2,6 @@
config CLKDEV_LOOKUP
bool
select HAVE_CLK
+
+config HAVE_CLK_PREPARE
+ bool
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 34145fe..386593f5 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1315,12 +1315,14 @@
/* now map it to userspace */
ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma,
flags);
- mutex_unlock(&buffer->lock);
+
+ buffer->umap_cnt++;
if (ret) {
pr_err("%s: failure mapping buffer to userspace\n",
__func__);
goto err2;
}
+ mutex_unlock(&buffer->lock);
vma->vm_ops = &ion_vm_ops;
/* move the handle into the vm_private_data so we can access it from
@@ -1335,6 +1337,7 @@
err2:
buffer->umap_cnt--;
+ mutex_unlock(&buffer->lock);
/* drop the reference to the handle */
err1:
ion_handle_put(handle);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index c29da39..6ab9534 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -631,9 +631,33 @@
void kgsl_pre_hwaccess(struct kgsl_device *device)
{
BUG_ON(!mutex_is_locked(&device->mutex));
- if (device->state & (KGSL_STATE_SLEEP | KGSL_STATE_NAP |
- KGSL_STATE_SLUMBER))
+ switch (device->state) {
+ case KGSL_STATE_ACTIVE:
+ return;
+ case KGSL_STATE_NAP:
+ case KGSL_STATE_SLEEP:
+ case KGSL_STATE_SLUMBER:
kgsl_pwrctrl_wake(device);
+ break;
+ case KGSL_STATE_SUSPEND:
+ kgsl_check_suspended(device);
+ break;
+ case KGSL_STATE_INIT:
+ case KGSL_STATE_HUNG:
+ case KGSL_STATE_DUMP_AND_RECOVER:
+ if (test_bit(KGSL_PWRFLAGS_CLK_ON,
+ &device->pwrctrl.power_flags))
+ break;
+ else
+ KGSL_PWR_ERR(device,
+ "hw access while clocks off from state %d\n",
+ device->state);
+ break;
+ default:
+ KGSL_PWR_ERR(device, "hw access while in unknown state %d\n",
+ device->state);
+ break;
+ }
}
EXPORT_SYMBOL(kgsl_pre_hwaccess);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3c98a75..2453b6b 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -306,6 +306,12 @@
u8 t7_data[T7_DATA_SIZE];
u16 t7_start_addr;
u8 t9_ctrl;
+ u32 keyarray_old;
+ u32 keyarray_new;
+ u8 t9_max_reportid;
+ u8 t9_min_reportid;
+ u8 t15_max_reportid;
+ u8 t15_min_reportid;
};
static bool mxt_object_readable(unsigned int type)
@@ -670,16 +676,48 @@
mxt_input_report(data, id);
}
+static void mxt_handle_key_array(struct mxt_data *data,
+ struct mxt_message *message)
+{
+ u32 keys_changed;
+ int i;
+
+ if (!data->pdata->key_codes) {
+ dev_err(&data->client->dev, "keyarray is not supported\n");
+ return;
+ }
+
+ data->keyarray_new = message->message[1] |
+ (message->message[2] << 8) |
+ (message->message[3] << 16) |
+ (message->message[4] << 24);
+
+ keys_changed = data->keyarray_old ^ data->keyarray_new;
+
+ if (!keys_changed) {
+ dev_dbg(&data->client->dev, "no keys changed\n");
+ return;
+ }
+
+ for (i = 0; i < MXT_KEYARRAY_MAX_KEYS; i++) {
+ if (!(keys_changed & (1 << i)))
+ continue;
+
+ input_report_key(data->input_dev, data->pdata->key_codes[i],
+ (data->keyarray_new & (1 << i)));
+ input_sync(data->input_dev);
+ }
+
+ data->keyarray_old = data->keyarray_new;
+}
+
static irqreturn_t mxt_interrupt(int irq, void *dev_id)
{
struct mxt_data *data = dev_id;
struct mxt_message message;
- struct mxt_object *object;
struct device *dev = &data->client->dev;
int id;
u8 reportid;
- u8 max_reportid;
- u8 min_reportid;
do {
if (mxt_read_message(data, &message)) {
@@ -688,16 +726,20 @@
}
reportid = message.reportid;
- /* whether reportid is thing of MXT_TOUCH_MULTI_T9 */
- object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
- if (!object)
- goto end;
- max_reportid = object->max_reportid;
- min_reportid = max_reportid - object->num_report_ids + 1;
- id = reportid - min_reportid;
+ if (!reportid) {
+ dev_dbg(dev, "Report id 0 is reserved\n");
+ continue;
+ }
- if (reportid >= min_reportid && reportid <= max_reportid)
+ /* check whether report id is part of T9 or T15 */
+ id = reportid - data->t9_min_reportid;
+
+ if (reportid >= data->t9_min_reportid &&
+ reportid <= data->t9_max_reportid)
mxt_input_touchevent(data, &message, id);
+ else if (reportid >= data->t15_min_reportid &&
+ reportid <= data->t15_max_reportid)
+ mxt_handle_key_array(data, &message);
else
mxt_dump_message(dev, &message);
} while (reportid != 0xff);
@@ -857,6 +899,8 @@
u8 val;
u8 command_register;
struct mxt_object *t7_object;
+ struct mxt_object *t9_object;
+ struct mxt_object *t15_object;
error = mxt_get_info(data);
if (error)
@@ -903,6 +947,28 @@
goto free_object_table;
}
+ /* Store T9, T15's min and max report ids */
+ t9_object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
+ if (!t9_object) {
+ dev_err(&client->dev, "Failed to get T9 object\n");
+ error = -EINVAL;
+ goto free_object_table;
+ }
+ data->t9_max_reportid = t9_object->max_reportid;
+ data->t9_min_reportid = t9_object->max_reportid -
+ t9_object->num_report_ids + 1;
+
+ if (data->pdata->key_codes) {
+ t15_object = mxt_get_object(data, MXT_TOUCH_KEYARRAY_T15);
+ if (!t15_object)
+ dev_dbg(&client->dev, "T15 object is not available\n");
+ else {
+ data->t15_max_reportid = t15_object->max_reportid;
+ data->t15_min_reportid = t15_object->max_reportid -
+ t15_object->num_report_ids + 1;
+ }
+ }
+
/* Backup to memory */
mxt_write_object(data, MXT_GEN_COMMAND_T6,
MXT_COMMAND_BACKUPNV,
@@ -1562,7 +1628,7 @@
const struct mxt_platform_data *pdata = client->dev.platform_data;
struct mxt_data *data;
struct input_dev *input_dev;
- int error;
+ int error, i;
if (!pdata)
return -EINVAL;
@@ -1608,6 +1674,15 @@
input_set_abs_params(input_dev, ABS_MT_PRESSURE,
0, 255, 0, 0);
+ /* set key array supported keys */
+ if (pdata->key_codes) {
+ for (i = 0; i < MXT_KEYARRAY_MAX_KEYS; i++) {
+ if (pdata->key_codes[i])
+ input_set_capability(input_dev, EV_KEY,
+ pdata->key_codes[i]);
+ }
+ }
+
input_set_drvdata(input_dev, data);
i2c_set_clientdata(client, data);
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 835f8c4..ff0e00d 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -97,6 +97,7 @@
struct hci_fm_riva_poke riva_data_req;
struct hci_fm_ssbi_req ssbi_data_accs;
struct hci_fm_ssbi_peek ssbi_peek_reg;
+ struct hci_fm_sig_threshold_rsp sig_th;
};
static struct video_device *priv_videodev;
@@ -1587,13 +1588,11 @@
{
struct hci_fm_sig_threshold_rsp *rsp = (void *)skb->data;
struct iris_device *radio = video_get_drvdata(video_get_dev());
- struct v4l2_control *v4l_ctl = radio->g_ctl;
if (rsp->status)
return;
- v4l_ctl->value = rsp->sig_threshold;
-
+ memcpy(&radio->sig_th, rsp, sizeof(struct hci_fm_sig_threshold_rsp));
radio_hci_req_complete(hdev, rsp->status);
}
@@ -2086,7 +2085,8 @@
struct sk_buff *skb)
{
struct iris_device *radio = video_get_drvdata(video_get_dev());
- if (radio->fm_st_rsp.station_rsp.serv_avble)
+ u8 serv_avble = skb->data[0];
+ if (serv_avble)
iris_q_event(radio, IRIS_EVT_ABOVE_TH);
else
iris_q_event(radio, IRIS_EVT_BELOW_TH);
@@ -2432,6 +2432,11 @@
break;
case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
retval = hci_cmd(HCI_FM_GET_SIGNAL_TH_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in get signal threshold %d\n", retval);
+ return retval;
+ }
+ ctrl->value = radio->sig_th.sig_threshold;
break;
case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
ctrl->value = radio->srch_rds.srch_pty;
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
index 65b33c2..dbf0eae 100644
--- a/drivers/media/video/msm/msm_camera.c
+++ b/drivers/media/video/msm/msm_camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -279,16 +279,18 @@
{
if (info->offset < len &&
info->offset + info->len <= len &&
- info->y_off < len &&
- info->cbcr_off < len)
+ info->planar0_off < len &&
+ info->planar1_off < len &&
+ info->planar2_off < len)
return 0;
- pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
+ pr_err("%s: check failed: off %d len %d y 0x%x cbcr_p1 0x%x p2_add 0x%x(total len %d)\n",
__func__,
info->offset,
info->len,
- info->y_off,
- info->cbcr_off,
+ info->planar0_off,
+ info->planar1_off,
+ info->planar2_off,
len);
return -EINVAL;
}
@@ -352,8 +354,10 @@
hlist_add_head(&(region->list), ptype);
spin_unlock_irqrestore(pmem_spinlock, flags);
- CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx\n",
- __func__, info->type, paddr, (unsigned long)info->vaddr);
+ CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx p0_add = 0x%x"
+ "p1_addr = 0x%x p2_addr = 0x%x\n",
+ __func__, info->type, paddr, (unsigned long)info->vaddr,
+ info->planar0_off, info->planar1_off, info->planar2_off);
return 0;
out2:
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -439,8 +443,9 @@
}
static int msm_pmem_frame_ptov_lookup(struct msm_sync *sync,
- unsigned long pyaddr,
- unsigned long pcbcraddr,
+ unsigned long p0addr,
+ unsigned long p1addr,
+ unsigned long p2addr,
struct msm_pmem_info *pmem_info,
int clear_active)
{
@@ -450,10 +455,10 @@
spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
- if (pyaddr == (region->paddr + region->info.y_off) &&
- pcbcraddr == (region->paddr +
- region->info.cbcr_off) &&
- region->info.active) {
+ if (p0addr == (region->paddr + region->info.planar0_off) &&
+ p1addr == (region->paddr + region->info.planar1_off) &&
+ p2addr == (region->paddr + region->info.planar2_off) &&
+ region->info.active) {
/* offset since we could pass vaddr inside
* a registerd pmem buffer
*/
@@ -466,12 +471,13 @@
}
}
/* After lookup failure, dump all the list entries... */
- pr_err("%s, for pyaddr 0x%lx, pcbcraddr 0x%lx\n",
- __func__, pyaddr, pcbcraddr);
+ pr_err("%s, for plane0 addr = 0x%lx, plane1 addr = 0x%lx plane2 addr = 0x%lx\n",
+ __func__, p0addr, p1addr, p2addr);
hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
- pr_err("listed pyaddr 0x%lx, pcbcraddr 0x%lx, active = %d",
- (region->paddr + region->info.y_off),
- (region->paddr + region->info.cbcr_off),
+ pr_err("listed p0addr 0x%lx, p1addr 0x%lx, p2addr 0x%lx, active = %d",
+ (region->paddr + region->info.planar0_off),
+ (region->paddr + region->info.planar1_off),
+ (region->paddr + region->info.planar2_off),
region->info.active);
}
@@ -480,7 +486,7 @@
}
static int msm_pmem_frame_ptov_lookup2(struct msm_sync *sync,
- unsigned long pyaddr,
+ unsigned long p0_phy,
struct msm_pmem_info *pmem_info,
int clear_active)
{
@@ -490,7 +496,7 @@
spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
- if (pyaddr == (region->paddr + region->info.y_off) &&
+ if (p0_phy == (region->paddr + region->info.planar0_off) &&
region->info.active) {
/* offset since we could pass vaddr inside
* a registerd pmem buffer
@@ -541,8 +547,8 @@
}
static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync,
- unsigned long buffer,
- uint32_t yoff, uint32_t cbcroff, int fd, int change_flag)
+ unsigned long buffer, uint32_t p0_off, uint32_t p1_off,
+ uint32_t p2_off, int fd, int change_flag)
{
struct msm_pmem_region *region;
struct hlist_node *node, *n;
@@ -552,8 +558,9 @@
hlist_for_each_entry_safe(region,
node, n, &sync->pmem_frames, list) {
if (((unsigned long)(region->info.vaddr) == buffer) &&
- (region->info.y_off == yoff) &&
- (region->info.cbcr_off == cbcroff) &&
+ (region->info.planar0_off == p0_off) &&
+ (region->info.planar1_off == p1_off) &&
+ (region->info.planar2_off == p2_off) &&
(region->info.fd == fd) &&
(region->info.active == 0)) {
if (change_flag)
@@ -564,13 +571,16 @@
}
}
/* After lookup failure, dump all the list entries... */
- pr_err("%s, failed for vaddr 0x%lx, yoff %d cbcroff %d\n",
- __func__, buffer, yoff, cbcroff);
+ pr_err("%s, failed for vaddr 0x%lx, p0_off %d p1_off %d\n",
+ __func__, buffer, p0_off, p1_off);
hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
- pr_err("listed vaddr 0x%p, cbcroff %d, active = %d",
- (region->info.vaddr),
- (region->info.cbcr_off),
- region->info.active);
+ pr_err("%s, listed vaddr 0x%lx, r_p0 = 0x%x p0_off 0x%x"
+ "r_p1 = 0x%x, p1_off 0x%x, r_p2 = 0x%x, p2_off = 0x%x"
+ " active = %d\n", __func__, buffer,
+ region->info.planar0_off,
+ p0_off, region->info.planar1_off,
+ p1_off, region->info.planar2_off, p2_off,
+ region->info.active);
}
spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
@@ -741,33 +751,36 @@
vdata = (struct msm_vfe_resp *)(qcmd->command);
pphy = &vdata->phy;
+ CDBG("%s, pphy->p2_phy = 0x%x\n", __func__, pphy->p2_phy);
rc = msm_pmem_frame_ptov_lookup(sync,
- pphy->y_phy,
- pphy->cbcr_phy,
+ pphy->p0_phy,
+ pphy->p1_phy,
+ pphy->p2_phy,
&pmem_info,
1); /* Clear the active flag */
if (rc < 0) {
- pr_err("%s: cannot get frame, invalid lookup address "
- "y %x cbcr %x\n",
- __func__,
- pphy->y_phy,
- pphy->cbcr_phy);
+ pr_err("%s: cannot get frame, invalid lookup address"
+ "plane0 add %x plane1 add %x plane2 add%x\n",
+ __func__,
+ pphy->p0_phy,
+ pphy->p1_phy,
+ pphy->p2_phy);
goto err;
}
frame->ts = qcmd->ts;
frame->buffer = (unsigned long)pmem_info.vaddr;
- frame->y_off = pmem_info.y_off;
- frame->cbcr_off = pmem_info.cbcr_off;
+ frame->planar0_off = pmem_info.planar0_off;
+ frame->planar1_off = pmem_info.planar1_off;
+ frame->planar2_off = pmem_info.planar2_off;
frame->fd = pmem_info.fd;
frame->path = vdata->phy.output_id;
frame->frame_id = vdata->phy.frame_id;
-
- CDBG("%s: y %x, cbcr %x, qcmd %x, virt_addr %x\n",
- __func__,
- pphy->y_phy, pphy->cbcr_phy, (int) qcmd, (int) frame->buffer);
+ CDBG("%s: plane0 %x, plane1 %x, plane2 %x,qcmd %x, virt_addr %x\n",
+ __func__, pphy->p0_phy, pphy->p1_phy, pphy->p2_phy,
+ (int) qcmd, (int) frame->buffer);
err:
free_qcmd(qcmd);
@@ -1078,8 +1091,8 @@
return -EINVAL;
}
- rc = msm_pmem_frame_ptov_lookup(sync, data->phy.y_phy,
- data->phy.cbcr_phy, &pinfo,
+ rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+ data->phy.p1_phy, data->phy.p2_phy, &pinfo,
0); /* do not clear the active flag */
if (rc < 0) {
@@ -1088,8 +1101,8 @@
}
buf.fmain.buffer = (unsigned long)pinfo.vaddr;
- buf.fmain.y_off = pinfo.y_off;
- buf.fmain.cbcr_off = pinfo.cbcr_off;
+ buf.fmain.planar0_off = pinfo.planar0_off;
+ buf.fmain.planar1_off = pinfo.planar1_off;
buf.fmain.fd = pinfo.fd;
CDBG("%s: buf 0x%x fd %d\n", __func__, (unsigned int)buf.fmain.buffer,
@@ -1119,14 +1132,14 @@
buf.type = OUTPUT_TYPE_ST_R;
} else {
if (se->resptype == MSM_CAM_RESP_STEREO_OP_1) {
- rc = msm_pmem_frame_ptov_lookup(sync, data->phy.y_phy,
- data->phy.cbcr_phy, &pinfo,
- 1); /* do clear the active flag */
+ rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+ data->phy.p1_phy, data->phy.p2_phy, &pinfo,
+ 1); /* do clear the active flag */
buf.buf_info.path = path;
} else if (se->resptype == MSM_CAM_RESP_STEREO_OP_2) {
- rc = msm_pmem_frame_ptov_lookup(sync, data->phy.y_phy,
- data->phy.cbcr_phy, &pinfo,
- 0); /* do not clear the active flag */
+ rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+ data->phy.p1_phy, data->phy.p2_phy, &pinfo,
+ 0); /* do not clear the active flag */
buf.buf_info.path = path;
} else
CDBG("%s: Invalid resptype = %d\n", __func__,
@@ -1184,8 +1197,9 @@
buf.buf_info.buffer = (unsigned long)pinfo.vaddr;
buf.buf_info.phy_offset = pinfo.offset;
- buf.buf_info.y_off = pinfo.y_off;
- buf.buf_info.cbcr_off = pinfo.cbcr_off;
+ buf.buf_info.planar0_off = pinfo.planar0_off;
+ buf.buf_info.planar1_off = pinfo.planar1_off;
+ buf.buf_info.planar2_off = pinfo.planar2_off;
buf.buf_info.fd = pinfo.fd;
CDBG("%s: buf 0x%x fd %d\n", __func__,
@@ -1837,6 +1851,7 @@
}
break;
+ case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
case CMD_AXI_CFG_VIDEO:
pmem_type = MSM_PMEM_PREVIEW;
axi_data.bufnum1 =
@@ -1889,6 +1904,7 @@
}
break;
+ case CMD_AXI_CFG_ZSL_ALL_CHNLS:
case CMD_AXI_CFG_ZSL:
CDBG("%s, CMD_AXI_CFG_ZSL, type = %d\n", __func__,
cfgcmd->cmd_type);
@@ -2044,7 +2060,7 @@
/* Change the active flag. */
pphy = msm_pmem_frame_vtop_lookup(sync,
pb->buffer,
- pb->y_off, pb->cbcr_off, pb->fd, 1);
+ pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
if (pphy != 0) {
CDBG("%s: rel: vaddr %lx, paddr %lx\n",
@@ -2072,7 +2088,7 @@
pphy = msm_pmem_frame_vtop_lookup(sync,
pb->buffer,
- pb->y_off, pb->cbcr_off, pb->fd, 1);
+ pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
if (pphy != 0) {
CDBG("%s: rel: vaddr %lx, paddr %lx\n",
@@ -2295,6 +2311,8 @@
case CMD_AXI_CFG_SNAP:
case CMD_RAW_PICT_AXI_CFG:
case CMD_AXI_CFG_ZSL:
+ case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
+ case CMD_AXI_CFG_ZSL_ALL_CHNLS:
CDBG("%s, cfgcmd.cmd_type = %d\n", __func__, cfgcmd.cmd_type);
return msm_frame_axi_cfg(sync, &cfgcmd);
@@ -2340,21 +2358,21 @@
pphy = &vdata->phy;
rc = msm_pmem_frame_ptov_lookup2(sync,
- pphy->y_phy,
+ pphy->p0_phy,
&pmem_info,
1); /* mark pic frame in use */
if (rc < 0) {
pr_err("%s: cannot get pic frame, invalid lookup"
- " address y %x cbcr %x\n",
- __func__, pphy->y_phy, pphy->cbcr_phy);
+ " address p0_phy add %x p1_phy add%x\n",
+ __func__, pphy->p0_phy, pphy->p1_phy);
goto err;
}
frame->ts = qcmd->ts;
frame->buffer = (unsigned long)pmem_info.vaddr;
- frame->y_off = pmem_info.y_off;
- frame->cbcr_off = pmem_info.cbcr_off;
+ frame->planar0_off = pmem_info.planar0_off;
+ frame->planar1_off = pmem_info.planar1_off;
frame->fd = pmem_info.fd;
if (sync->stereocam_enabled &&
sync->stereo_state != STEREO_RAW_SNAP_STARTED) {
@@ -2365,20 +2383,20 @@
} else
frame->path = vdata->phy.output_id;
- CDBG("%s: y %x, cbcr %x, qcmd %x, virt_addr %x\n",
- __func__, pphy->y_phy,
- pphy->cbcr_phy, (int) qcmd, (int) frame->buffer);
+ CDBG("%s:p0_phy add %x, p0_phy add %x, qcmd %x, virt_addr %x\n",
+ __func__, pphy->p0_phy,
+ pphy->p1_phy, (int) qcmd, (int) frame->buffer);
} else { /* PP */
pframe = (struct msm_frame *)(qcmd->command);
frame->ts = qcmd->ts;
frame->buffer = pframe->buffer;
- frame->y_off = pframe->y_off;
- frame->cbcr_off = pframe->cbcr_off;
+ frame->planar0_off = pframe->planar0_off;
+ frame->planar1_off = pframe->planar1_off;
frame->fd = pframe->fd;
frame->path = pframe->path;
CDBG("%s: PP y_off %x, cbcr_off %x, path %d vaddr 0x%x\n",
- __func__, frame->y_off, frame->cbcr_off, frame->path,
- (int) frame->buffer);
+ __func__, frame->planar0_off, frame->planar1_off, frame->path,
+ (int) frame->buffer);
}
err:
@@ -2604,13 +2622,13 @@
vfe_rp = (struct msm_vfe_resp *)qcmd->command;
CDBG("%s: Left Py = 0x%x y_off = %d cbcr_off = %d\n",
- __func__, vfe_rp->phy.y_phy,
- stereo_frame_half.L.buf_y_off,
- stereo_frame_half.L.buf_cbcr_off);
+ __func__, vfe_rp->phy.p0_phy,
+ stereo_frame_half.L.buf_p0_off,
+ stereo_frame_half.L.buf_p1_off);
sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
- vfe_rp->phy.y_phy + stereo_frame_half.L.buf_y_off,
- vfe_rp->phy.y_phy + stereo_frame_half.L.buf_cbcr_off,
+ vfe_rp->phy.p0_phy + stereo_frame_half.L.buf_p0_off,
+ vfe_rp->phy.p1_phy + stereo_frame_half.L.buf_p1_off,
&(qcmd->ts), OUTPUT_TYPE_ST_L, stereo_frame_half.L,
stereo_frame_half.frame_id);
@@ -2626,14 +2644,15 @@
st_pphy = msm_pmem_frame_vtop_lookup(sync,
stereo_frame_half.buf_info.buffer,
- stereo_frame_half.buf_info.y_off,
- stereo_frame_half.buf_info.cbcr_off,
+ stereo_frame_half.buf_info.planar0_off,
+ stereo_frame_half.buf_info.planar1_off,
+ stereo_frame_half.buf_info.planar2_off,
stereo_frame_half.buf_info.fd,
0); /* Do not change the active flag. */
sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
- st_pphy + stereo_frame_half.R.buf_y_off,
- st_pphy + stereo_frame_half.R.buf_cbcr_off,
+ st_pphy + stereo_frame_half.R.buf_p0_off,
+ st_pphy + stereo_frame_half.R.buf_p1_off,
NULL, OUTPUT_TYPE_ST_R, stereo_frame_half.R,
stereo_frame_half.frame_id);
@@ -3332,10 +3351,10 @@
switch (vdata->type) {
case VFE_MSG_OUTPUT_P:
if (sync->pp_mask & PP_PREV) {
- CDBG("%s: PP_PREV in progress: phy_y %x phy_cbcr %x\n",
+ CDBG("%s: PP_PREV in progress: p0_add %x p1_add %x\n",
__func__,
- vdata->phy.y_phy,
- vdata->phy.cbcr_phy);
+ vdata->phy.p0_phy,
+ vdata->phy.p1_phy);
spin_lock_irqsave(&pp_prev_spinlock, flags);
if (sync->pp_prev)
CDBG("%s: overwriting pp_prev!\n",
@@ -3493,8 +3512,8 @@
vdata->vpe_bf.vpe_crop =
*(struct video_crop_t *)(sync->cropinfo);
- vdata->vpe_bf.y_phy = vdata->phy.y_phy;
- vdata->vpe_bf.cbcr_phy = vdata->phy.cbcr_phy;
+ vdata->vpe_bf.p0_phy = vdata->phy.p0_phy;
+ vdata->vpe_bf.p1_phy = vdata->phy.p1_phy;
vdata->vpe_bf.ts = (qcmd->ts);
vdata->vpe_bf.frame_id = vdata->phy.frame_id;
qcmd->command = vdata;
@@ -3506,8 +3525,8 @@
"= %ld\n", __func__, qcmd->ts.tv_nsec);
sync->vpefn.send_frame_to_vpe(
- vdata->phy.y_phy,
- vdata->phy.cbcr_phy,
+ vdata->phy.p0_phy,
+ vdata->phy.p1_phy,
&(qcmd->ts), OUTPUT_TYPE_V);
free_qcmd(qcmd);
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index c13e7e5..b631981 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.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
@@ -84,16 +84,16 @@
{
if (info->offset < len &&
info->offset + info->len <= len &&
- info->y_off < len &&
- info->cbcr_off < len)
+ info->planar0_off < len &&
+ info->planar1_off < len)
return 0;
pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
__func__,
info->offset,
info->len,
- info->y_off,
- info->cbcr_off,
+ info->planar0_off,
+ info->planar1_off,
len);
return -EINVAL;
}
diff --git a/drivers/media/video/msm/msm_vfe31.c b/drivers/media/video/msm/msm_vfe31.c
index b22b6c5..2b3732c 100644
--- a/drivers/media/video/msm/msm_vfe31.c
+++ b/drivers/media/video/msm/msm_vfe31.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
@@ -337,10 +337,12 @@
break;
}
pinfo->output_id = outid;
- pinfo->y_phy =
- ((struct vfe_message *)data)->_u.msgOut.yBuffer;
- pinfo->cbcr_phy =
- ((struct vfe_message *)data)->_u.msgOut.cbcrBuffer;
+ pinfo->p0_phy =
+ ((struct vfe_message *)data)->_u.msgOut.p0_addr;
+ pinfo->p1_phy =
+ ((struct vfe_message *)data)->_u.msgOut.p1_addr;
+ pinfo->p2_phy =
+ ((struct vfe_message *)data)->_u.msgOut.p2_addr;
pinfo->frame_id =
((struct vfe_message *)data)->_u.msgOut.frameCounter;
@@ -458,8 +460,8 @@
GFP_ATOMIC);
}
-static void vfe_send_outmsg(uint8_t msgid, uint32_t pyaddr,
- uint32_t pcbcraddr)
+static void vfe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
+ uint32_t p1_addr, uint32_t p2_addr)
{
struct vfe_message msg;
uint8_t outid;
@@ -485,9 +487,10 @@
break;
}
msg._u.msgOut.output_id = msgid;
- msg._u.msgOut.yBuffer = pyaddr;
- msg._u.msgOut.cbcrBuffer = pcbcraddr;
-
+ msg._u.msgOut.p0_addr = p0_addr;
+ msg._u.msgOut.p1_addr = p1_addr;
+ msg._u.msgOut.p2_addr = p2_addr;
+ CDBG("%s p2_addr = 0x%x\n", __func__, p2_addr);
vfe31_proc_ops(msgid, &msg, sizeof(struct vfe_message));
return;
}
@@ -542,7 +545,7 @@
}
static int vfe31_add_free_buf2(struct vfe31_output_ch *outch,
- uint32_t paddr, uint32_t y_off, uint32_t cbcr_off)
+ uint32_t paddr, uint32_t p0_off, uint32_t p1_off, uint32_t p2_off)
{
struct vfe31_free_buf *free_buf = NULL;
unsigned long flags = 0;
@@ -552,20 +555,23 @@
spin_lock_irqsave(&outch->free_buf_lock, flags);
free_buf->paddr = paddr;
- free_buf->y_off = y_off;
- free_buf->cbcr_off = cbcr_off;
+ free_buf->planar0_off = p0_off;
+ free_buf->planar1_off = p1_off;
+ free_buf->planar2_off = p2_off;
list_add_tail(&free_buf->node, &outch->free_buf_head);
CDBG("%s: free_buf paddr = 0x%x, y_off = %d, cbcr_off = %d\n",
- __func__, free_buf->paddr, free_buf->y_off,
- free_buf->cbcr_off);
+ __func__, free_buf->paddr, free_buf->planar0_off,
+ free_buf->planar1_off);
spin_unlock_irqrestore(&outch->free_buf_lock, flags);
return 0;
}
#define vfe31_add_free_buf(outch, regptr) \
- vfe31_add_free_buf2(outch, regptr->paddr, regptr->info.y_off, \
- regptr->info.cbcr_off)
+ vfe31_add_free_buf2(outch, regptr->paddr, \
+ regptr->info.planar0_off, \
+ regptr->info.planar1_off, \
+ regptr->info.planar2_off)
#define vfe31_free_buf_available(outch) \
(!list_empty(&outch.free_buf_head))
@@ -662,10 +668,10 @@
for (i = 0; i < 2; i++) {
p1 = ao + 6 + i; /* wm0 for y */
- *p1 = (regp1->paddr + regp1->info.y_off);
+ *p1 = (regp1->paddr + regp1->info.planar0_off);
p1 = ao + 12 + i; /* wm1 for cbcr */
- *p1 = (regp1->paddr + regp1->info.cbcr_off);
+ *p1 = (regp1->paddr + regp1->info.planar1_off);
regp1++;
}
ret = vfe31_add_free_buf(outp1, regp1);
@@ -694,47 +700,47 @@
/* Parse the buffers!!! */
if (ad->bufnum2 == 1) { /* assuming bufnum1 = bufnum2 */
p1 = ao + 6; /* wm0 ping */
- *p1++ = (regp1->paddr + regp1->info.y_off);
+ *p1++ = (regp1->paddr + regp1->info.planar0_off);
/* this is to duplicate ping address to pong.*/
- *p1 = (regp1->paddr + regp1->info.y_off);
+ *p1 = (regp1->paddr + regp1->info.planar0_off);
p1 = ao + 30; /* wm4 ping */
- *p1++ = (regp1->paddr + regp1->info.cbcr_off);
+ *p1++ = (regp1->paddr + regp1->info.planar1_off);
CDBG("%s: regp1->info.cbcr_off = 0x%x\n", __func__,
- regp1->info.cbcr_off);
+ regp1->info.planar1_off);
/* this is to duplicate ping address to pong.*/
- *p1 = (regp1->paddr + regp1->info.cbcr_off);
+ *p1 = (regp1->paddr + regp1->info.planar1_off);
p1 = ao + 12; /* wm1 ping */
- *p1++ = (regp2->paddr + regp2->info.y_off);
+ *p1++ = (regp2->paddr + regp2->info.planar0_off);
/* pong = ping,*/
- *p1 = (regp2->paddr + regp2->info.y_off);
+ *p1 = (regp2->paddr + regp2->info.planar0_off);
p1 = ao + 36; /* wm5 */
- *p1++ = (regp2->paddr + regp2->info.cbcr_off);
+ *p1++ = (regp2->paddr + regp2->info.planar1_off);
CDBG("%s: regp2->info.cbcr_off = 0x%x\n", __func__,
- regp2->info.cbcr_off);
+ regp2->info.planar1_off);
/* pong = ping,*/
- *p1 = (regp2->paddr + regp2->info.cbcr_off);
+ *p1 = (regp2->paddr + regp2->info.planar1_off);
} else { /* more than one snapshot */
/* first fill ping & pong */
for (i = 0; i < 2; i++) {
p1 = ao + 6 + i; /* wm0 for y */
- *p1 = (regp1->paddr + regp1->info.y_off);
+ *p1 = (regp1->paddr + regp1->info.planar0_off);
p1 = ao + 30 + i; /* wm4 for cbcr */
- *p1 = (regp1->paddr + regp1->info.cbcr_off);
+ *p1 = (regp1->paddr + regp1->info.planar1_off);
regp1--;
}
for (i = 0; i < 2; i++) {
p2 = ao + 12 + i; /* wm1 for y */
- *p2 = (regp2->paddr + regp2->info.y_off);
+ *p2 = (regp2->paddr + regp2->info.planar0_off);
p2 = ao + 36 + i; /* wm5 for cbcr */
- *p2 = (regp2->paddr + regp2->info.cbcr_off);
+ *p2 = (regp2->paddr + regp2->info.planar1_off);
regp2--;
}
@@ -783,25 +789,25 @@
/* first fill ping & pong */
for (i = 0; i < 2; i++) {
p1 = ao + 6 + i; /* wm0 for y */
- *p1 = (regp1->paddr + regp1->info.y_off);
+ *p1 = (regp1->paddr + regp1->info.planar0_off);
p1 = ao + 30 + i; /* wm4 for cbcr */
- *p1 = (regp1->paddr + regp1->info.cbcr_off);
+ *p1 = (regp1->paddr + regp1->info.planar1_off);
regp1++;
}
for (i = 0; i < 2; i++) {
p2 = ao + 12 + i; /* wm1 for y */
- *p2 = (regp2->paddr + regp2->info.y_off);
+ *p2 = (regp2->paddr + regp2->info.planar0_off);
p2 = ao + 36 + i; /* wm5 for cbcr */
- *p2 = (regp2->paddr + regp2->info.cbcr_off);
+ *p2 = (regp2->paddr + regp2->info.planar1_off);
regp2++;
}
for (i = 0; i < 2; i++) {
p3 = ao + 18 + i; /* wm2 for y */
- *p3 = (regp3->paddr + regp3->info.y_off);
+ *p3 = (regp3->paddr + regp3->info.planar0_off);
p3 = ao + 42 + i; /* wm6 for cbcr */
- *p3 = (regp3->paddr + regp3->info.cbcr_off);
+ *p3 = (regp3->paddr + regp3->info.planar1_off);
regp3++;
}
@@ -827,6 +833,80 @@
}
break;
+ case OUTPUT_ZSL_ALL_CHNLS:
+ CDBG("%s: OUTPUT_ZSL_ALL_CHNLS", __func__);
+ CDBG("%s: %d %d %d", __func__, ad->bufnum1, ad->bufnum2,
+ ad->bufnum3);
+ /* use wm0& 4 for postview, wm1&5 for preview.*/
+ /* use wm2& 6 for main img */
+ if ((ad->bufnum1 < 1) || (ad->bufnum2 < 1) || (ad->bufnum3 < 1))
+ return -EINVAL;
+ vfe31_ctrl->outpath.output_mode |=
+ VFE31_OUTPUT_MODE_S; /* main image.*/
+ vfe31_ctrl->outpath.output_mode |=
+ VFE31_OUTPUT_MODE_P_ALL_CHNLS; /* preview. */
+ vfe31_ctrl->outpath.output_mode |=
+ VFE31_OUTPUT_MODE_T; /* thumbnail. */
+
+ /* this is preview buffer. */
+ regp1 = &(ad->region[0]);
+ /* this is thumbnail buffer. */
+ regp2 = &(ad->region[ad->bufnum1]);
+ /* this is main image buffer. */
+ regp3 = &(ad->region[ad->bufnum1+ad->bufnum2]);
+ outp1 = &(vfe31_ctrl->outpath.out0);
+ outp2 = &(vfe31_ctrl->outpath.out1);
+ outp3 = &(vfe31_ctrl->outpath.out2);
+
+ /* Parse the buffers!!! */
+ /* first fill ping & pong */
+ for (i = 0; i < 2; i++) {
+ p1 = ao + 6 + i; /* wm0 for y */
+ *p1 = (regp2->paddr + regp2->info.planar0_off);
+ p1 = ao + 12 + i; /* wm1 for cbcr */
+ *p1 = (regp2->paddr + regp2->info.planar1_off);
+ regp2++;
+ }
+
+ for (i = 0; i < 2; i++) {
+ p2 = ao + 30 + i; /* wm4 for y */
+ *p2 = (regp1->paddr + regp1->info.planar0_off);
+ p2 = ao + 36 + i; /* wm5 for cbcr */
+ *p2 = (regp1->paddr + regp1->info.planar1_off);
+ p2 = ao + 42 + i; /* wm5 for cbcr */
+ *p2 = (regp1->paddr + regp1->info.planar2_off);
+ regp1++;
+ }
+
+ for (i = 0; i < 2; i++) {
+ p3 = ao + 18 + i; /* wm2 for y */
+ *p3 = (regp3->paddr + regp3->info.planar0_off);
+ p3 = ao + 24 + i; /* wm3 for cbcr */
+ *p3 = (regp3->paddr + regp3->info.planar1_off);
+ regp3++;
+ }
+ for (i = 2; i < ad->bufnum1; i++) {
+ ret = vfe31_add_free_buf(outp1, regp1);
+ if (ret < 0)
+ return ret;
+ regp1++;
+ }
+
+ for (i = 2; i < ad->bufnum2; i++) {
+ ret = vfe31_add_free_buf(outp2, regp2);
+ if (ret < 0)
+ return ret;
+ regp2++;
+ }
+
+ for (i = 2; i < ad->bufnum3; i++) {
+ ret = vfe31_add_free_buf(outp3, regp3);
+ if (ret < 0)
+ return ret;
+ regp3++;
+ }
+ break;
+
case OUTPUT_1_AND_3: {
/* use wm0&4 for preview, wm1&5 for video.*/
if ((ad->bufnum1 < 2) || (ad->bufnum2 < 2))
@@ -849,19 +929,19 @@
for (i = 0; i < 2; i++) {
p1 = ao + 6 + i; /* wm0 for y */
- *p1 = (regp1->paddr + regp1->info.y_off);
+ *p1 = (regp1->paddr + regp1->info.planar0_off);
p1 = ao + 30 + i; /* wm4 for cbcr */
- *p1 = (regp1->paddr + regp1->info.cbcr_off);
+ *p1 = (regp1->paddr + regp1->info.planar1_off);
regp1++;
}
for (i = 0; i < 2; i++) {
p2 = ao + 12 + i; /* wm1 for y */
- *p2 = (regp2->paddr + regp2->info.y_off);
+ *p2 = (regp2->paddr + regp2->info.planar0_off);
p2 = ao + 36 + i; /* wm5 for cbcr */
- *p2 = (regp2->paddr + regp2->info.cbcr_off);
+ *p2 = (regp2->paddr + regp2->info.planar1_off);
regp2++;
}
for (i = 2; i < ad->bufnum1; i++) {
@@ -879,6 +959,52 @@
}
}
break;
+
+ case OUTPUT_VIDEO_ALL_CHNLS: {
+ /* use wm0&4 for preview, wm1&5 for video.*/
+ vfe31_ctrl->outpath.output_mode |=
+ VFE31_OUTPUT_MODE_V; /* video*/
+ vfe31_ctrl->outpath.output_mode |=
+ VFE31_OUTPUT_MODE_P_ALL_CHNLS;
+ regp1 = &(ad->region[0]);
+ regp2 = &(ad->region[ad->bufnum1]);
+ outp1 = &(vfe31_ctrl->outpath.out0);
+ outp2 = &(vfe31_ctrl->outpath.out2);
+
+ for (i = 0; i < 2; i++) {
+ p1 = ao + 6 + i; /* wm0 for y */
+ *p1 = (regp1->paddr + regp1->info.planar0_off);
+
+ p1 = ao + 12 + i; /* wm1 for cbcr */
+ *p1 = (regp1->paddr + regp1->info.planar1_off);
+
+ p1 = ao + 18 + i; /* wm2 for cbcr */
+ *p1 = (regp1->paddr + regp1->info.planar2_off);
+ regp1++;
+ }
+ for (i = 0; i < 2; i++) {
+ p2 = ao + 30 + i; /* wm4 for y */
+ *p2 = (regp2->paddr + regp2->info.planar0_off);
+
+ p2 = ao + 36 + i; /* wm5 for cbcr */
+ *p2 = (regp2->paddr + regp2->info.planar1_off);
+ regp2++;
+ }
+ for (i = 2; i < ad->bufnum1; i++) {
+ ret = vfe31_add_free_buf(outp1, regp1);
+ if (ret < 0)
+ return ret;
+ regp1++;
+ }
+ for (i = 2; i < ad->bufnum2; i++) {
+ ret = vfe31_add_free_buf(outp2, regp2);
+ if (ret < 0)
+ return ret;
+ regp2++;
+ }
+ }
+ break;
+
case CAMIF_TO_AXI_VIA_OUTPUT_2: { /* use wm0 only */
if (ad->bufnum2 < 1)
return -EINVAL;
@@ -887,7 +1013,7 @@
regp1 = &(ad->region[ad->bufnum1]);
vfe31_ctrl->outpath.output_mode |= VFE31_OUTPUT_MODE_S;
p1 = ao + 6; /* wm0 for y */
- *p1 = (regp1->paddr + regp1->info.y_off);
+ *p1 = (regp1->paddr + regp1->info.planar0_off);
if (p_sync->stereocam_enabled)
p_sync->stereo_state = STEREO_RAW_SNAP_IDLE;
}
@@ -1193,6 +1319,11 @@
irq_comp_mask |=
((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
(0x1 << (vfe31_ctrl->outpath.out0.ch1)));
+ } else if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+ irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+ 0x1 << vfe31_ctrl->outpath.out0.ch1 |
+ 0x1 << vfe31_ctrl->outpath.out0.ch2);
}
if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
irq_comp_mask |=
@@ -1209,6 +1340,14 @@
vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
msm_io_w(1, vfe31_ctrl->vfebase +
vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+ } else if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+ msm_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+ msm_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+ msm_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
}
if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
msm_io_w(1, vfe31_ctrl->vfebase +
@@ -1302,12 +1441,22 @@
if ((vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_CONTINUOUS) &&
(vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_VIDEO))
return 0;
- irq_comp_mask =
+ irq_comp_mask =
msm_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
0x1 << vfe31_ctrl->outpath.out0.ch1);
+ if (vfe31_ctrl->outpath.out0.ch2 >= 0)
+ irq_comp_mask |=
+ (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+ 0x1 << vfe31_ctrl->outpath.out0.ch1 |
+ 0x1 << vfe31_ctrl->outpath.out0.ch2);
+ } else if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+ irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+ 0x1 << vfe31_ctrl->outpath.out0.ch1 |
+ 0x1 << vfe31_ctrl->outpath.out0.ch2);
}
if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_V) {
@@ -1323,7 +1472,19 @@
vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
msm_io_w(1, vfe31_ctrl->vfebase +
vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+ if (vfe31_ctrl->outpath.out0.ch2 >= 0)
+ msm_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+ } else if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+ msm_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+ msm_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+ msm_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
}
+
if (p_sync->stereocam_enabled)
msm_camio_set_perf_lvl(S_STEREO_VIDEO);
else
@@ -2240,7 +2401,8 @@
break;
}
- ret = vfe31_add_free_buf2(outch, p, b->y_off, b->cbcr_off);
+ ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
+ b->planar1_off, b->planar2_off);
if (ret < 0)
return ret;
break;
@@ -2267,7 +2429,8 @@
} else
return -EFAULT;
- ret = vfe31_add_free_buf2(outch, p, b->y_off, b->cbcr_off);
+ ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
+ b->planar1_off, b->planar2_off);
if (ret < 0)
return ret;
break;
@@ -2403,6 +2566,32 @@
}
break;
+ case CMD_AXI_CFG_ZSL_ALL_CHNLS: {
+ struct axidata *axid;
+ uint32_t *axio;
+ CDBG("%s, CMD_AXI_CFG_ZSL\n", __func__);
+ axid = data;
+ if (!axid)
+ return -EFAULT;
+ axio =
+ kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe31_config_axi(OUTPUT_ZSL_ALL_CHNLS, axid, axio);
+ kfree(axio);
+ }
+ break;
+
case CMD_AXI_CFG_VIDEO: {
struct axidata *axid;
uint32_t *axio = NULL;
@@ -2431,6 +2620,34 @@
break;
}
+ case CMD_AXI_CFG_VIDEO_ALL_CHNLS: {
+ struct axidata *axid;
+ uint32_t *axio = NULL;
+ axid = data;
+ if (!axid) {
+ rc = -EFAULT;
+ break;
+ }
+
+ axio =
+ kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe31_config_axi(OUTPUT_VIDEO_ALL_CHNLS, axid, axio);
+ kfree(axio);
+ break;
+ }
+
default:
break;
}
@@ -2804,7 +3021,7 @@
static void vfe31_process_output_path_irq_0(uint32_t ping_pong)
{
- uint32_t pyaddr, pcbcraddr;
+ uint32_t p0_addr, p1_addr, p2_addr;
#ifdef CONFIG_MSM_CAMERA_V4L2
uint32_t pyaddr_ping, pcbcraddr_ping, pyaddr_pong, pcbcraddr_pong;
#endif
@@ -2816,26 +3033,37 @@
if (free_buf) {
/* Y channel */
- pyaddr = vfe31_get_ch_addr(ping_pong,
+ p0_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out0.ch0);
/* Chroma channel */
- pcbcraddr = vfe31_get_ch_addr(ping_pong,
+ p1_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out0.ch1);
-
- CDBG("output path 0, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
- pyaddr, pcbcraddr);
+ if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+ p2_addr = vfe31_get_ch_addr(ping_pong,
+ vfe31_ctrl->outpath.out0.ch2);
+ } else {
+ p2_addr = p0_addr;
+ }
+ CDBG("Output path 0, p0_addr = 0x%x, p1_addr = 0x%x,"
+ "p2_addr = 0x%x\n", p0_addr, p1_addr, p2_addr);
/* Y channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out0.ch0,
- free_buf->paddr + free_buf->y_off);
+ free_buf->paddr + free_buf->planar0_off);
/* Chroma channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out0.ch1,
- free_buf->paddr + free_buf->cbcr_off);
-
- kfree(free_buf);
- /* if continuous mode, for display. (preview) */
- vfe_send_outmsg(MSG_ID_OUTPUT_P, pyaddr, pcbcraddr);
+ free_buf->paddr + free_buf->planar1_off);
+ if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_P_ALL_CHNLS)
+ vfe31_put_ch_addr(ping_pong,
+ vfe31_ctrl->outpath.out0.ch2,
+ free_buf->paddr + free_buf->planar2_off);
+ kfree(free_buf);
+ /* if continuous mode, for display. (preview) */
+ vfe_send_outmsg(MSG_ID_OUTPUT_P, p0_addr, p1_addr,
+ p2_addr);
} else {
vfe31_ctrl->outpath.out0.frame_drop_cnt++;
pr_warning("path_irq_0 - no free buffer!\n");
@@ -2880,54 +3108,54 @@
static void vfe31_process_snapshot_frame(uint32_t ping_pong)
{
- uint32_t pyaddr, pcbcraddr;
+ uint32_t p0_addr, p1_addr;
struct vfe31_free_buf *free_buf = NULL;
/* Y channel- Main Image */
- pyaddr = vfe31_get_ch_addr(ping_pong,
+ p0_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch0);
/* Chroma channel - TN Image */
- pcbcraddr = vfe31_get_ch_addr(ping_pong,
+ p1_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch1);
free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
- CDBG("%s: snapshot main, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
- __func__, pyaddr, pcbcraddr);
+ CDBG("%s: snapshot main, p0_addr = 0x%x, p1_addr = 0x%x\n",
+ __func__, p0_addr, p1_addr);
if (free_buf) {
/* Y channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch0,
- free_buf->paddr + free_buf->y_off);
+ free_buf->paddr + free_buf->planar0_off);
/* Chroma channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch1,
- free_buf->paddr + free_buf->cbcr_off);
+ free_buf->paddr + free_buf->planar1_off);
kfree(free_buf);
}
- vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr);
+ vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
/* Y channel- TN Image */
- pyaddr = vfe31_get_ch_addr(ping_pong,
+ p0_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out0.ch0);
/* Chroma channel - TN Image */
- pcbcraddr = vfe31_get_ch_addr(ping_pong,
+ p1_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out0.ch1);
free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out0);
- CDBG("%s: snapshot TN, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
- __func__, pyaddr, pcbcraddr);
+ CDBG("%s: snapshot TN, p0_addr = 0x%x, p1_addr = 0x%x\n",
+ __func__, p0_addr, p1_addr);
if (free_buf) {
/* Y channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out0.ch0,
- free_buf->paddr + free_buf->y_off);
+ free_buf->paddr + free_buf->planar0_off);
/* Chroma channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out0.ch1,
- free_buf->paddr + free_buf->cbcr_off);
+ free_buf->paddr + free_buf->planar1_off);
kfree(free_buf);
}
- vfe_send_outmsg(MSG_ID_OUTPUT_T, pyaddr, pcbcraddr);
+ vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
/* in snapshot mode if done then send
snapshot done message */
@@ -2964,14 +3192,14 @@
/* Y channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch0,
- free_buf->paddr + free_buf->y_off);
+ free_buf->paddr + free_buf->planar0_off);
/* Chroma channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch1,
- free_buf->paddr + free_buf->cbcr_off);
+ free_buf->paddr + free_buf->planar1_off);
kfree(free_buf);
}
- vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr);
+ vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr, 0);
/* in snapshot mode if done then send
snapshot done message */
@@ -2986,54 +3214,54 @@
}
static void vfe31_process_zsl_frame(uint32_t ping_pong)
{
- uint32_t pyaddr, pcbcraddr;
+ uint32_t p0_addr, p1_addr;
struct vfe31_free_buf *free_buf = NULL;
/* Y channel- Main Image */
- pyaddr = vfe31_get_ch_addr(ping_pong,
+ p0_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out2.ch0);
/* Chroma channel - Main Image */
- pcbcraddr = vfe31_get_ch_addr(ping_pong,
+ p1_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out2.ch1);
free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out2);
CDBG("%s: snapshot main, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
- __func__, pyaddr, pcbcraddr);
+ __func__, p0_addr, p1_addr);
if (free_buf) {
/* Y channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out2.ch0,
- free_buf->paddr + free_buf->y_off);
+ free_buf->paddr + free_buf->planar0_off);
/* Chroma channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out2.ch1,
- free_buf->paddr + free_buf->cbcr_off);
+ free_buf->paddr + free_buf->planar1_off);
kfree(free_buf);
}
- vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr);
+ vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
/* Y channel- TN Image */
- pyaddr = vfe31_get_ch_addr(ping_pong,
+ p0_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch0);
/* Chroma channel - TN Image */
- pcbcraddr = vfe31_get_ch_addr(ping_pong,
+ p1_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch1);
free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
CDBG("%s: snapshot TN, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
- __func__, pyaddr, pcbcraddr);
+ __func__, p0_addr, p1_addr);
if (free_buf) {
/* Y channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch0,
- free_buf->paddr + free_buf->y_off);
+ free_buf->paddr + free_buf->planar0_off);
/* Chroma channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out1.ch1,
- free_buf->paddr + free_buf->cbcr_off);
+ free_buf->paddr + free_buf->planar1_off);
kfree(free_buf);
}
- vfe_send_outmsg(MSG_ID_OUTPUT_T, pyaddr, pcbcraddr);
+ vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
}
static void vfe31_process_output_path_irq_1(uint32_t ping_pong)
@@ -3105,7 +3333,7 @@
static void vfe31_process_output_path_irq_2(uint32_t ping_pong)
{
- uint32_t pyaddr, pcbcraddr;
+ uint32_t p0_addr, p1_addr, p2_addr;
struct vfe31_free_buf *free_buf = NULL;
#ifdef CONFIG_MSM_CAMERA_V4L2
@@ -3135,25 +3363,25 @@
if (free_buf) {
/* Y channel */
- pyaddr = vfe31_get_ch_addr(ping_pong,
+ p0_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out2.ch0);
/* Chroma channel */
- pcbcraddr = vfe31_get_ch_addr(ping_pong,
+ p1_addr = vfe31_get_ch_addr(ping_pong,
vfe31_ctrl->outpath.out2.ch1);
-
+ p2_addr = p0_addr;
CDBG("video output, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
- pyaddr, pcbcraddr);
+ p0_addr, p1_addr);
/* Y channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out2.ch0,
- free_buf->paddr + free_buf->y_off);
+ free_buf->paddr + free_buf->planar0_off);
/* Chroma channel */
vfe31_put_ch_addr(ping_pong,
vfe31_ctrl->outpath.out2.ch1,
- free_buf->paddr + free_buf->cbcr_off);
+ free_buf->paddr + free_buf->planar1_off);
kfree(free_buf);
- vfe_send_outmsg(MSG_ID_OUTPUT_V, pyaddr, pcbcraddr);
+ vfe_send_outmsg(MSG_ID_OUTPUT_V, p0_addr, p1_addr, p2_addr);
} else {
vfe31_ctrl->outpath.out2.frame_drop_cnt++;
pr_warning("path_irq_2 - no free buffer!\n");
diff --git a/drivers/media/video/msm/msm_vfe31.h b/drivers/media/video/msm/msm_vfe31.h
index c47c7de..d1df2dd 100644
--- a/drivers/media/video/msm/msm_vfe31.h
+++ b/drivers/media/video/msm/msm_vfe31.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -842,8 +842,9 @@
struct vfe_msg_output {
uint8_t output_id;
- uint32_t yBuffer;
- uint32_t cbcrBuffer;
+ uint32_t p0_addr;
+ uint32_t p1_addr;
+ uint32_t p2_addr;
struct vfe_frame_bpc_info bpcInfo;
struct vfe_frame_asf_info asfInfo;
uint32_t frameCounter;
@@ -878,7 +879,9 @@
struct vfe31_free_buf {
struct list_head node;
uint32_t paddr;
- uint32_t y_off;
+ uint32_t planar0_off;
+ uint32_t planar1_off;
+ uint32_t planar2_off;
uint32_t cbcr_off;
};
diff --git a/drivers/media/video/msm/msm_vfe7x.c b/drivers/media/video/msm/msm_vfe7x.c
index 316aacf..d74bebc 100644
--- a/drivers/media/video/msm/msm_vfe7x.c
+++ b/drivers/media/video/msm/msm_vfe7x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -72,14 +72,14 @@
{
switch (type) {
case VFE_MSG_OUTPUT_P: {
- pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
- pinfo->cbcr_phy =
+ pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
+ pinfo->p1_phy =
((struct vfe_endframe *)data)->cbcr_address;
-
+ pinfo->p2_phy = pinfo->p0_phy;
pinfo->output_id = OUTPUT_TYPE_P;
CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
- pinfo->y_phy, pinfo->cbcr_phy);
+ pinfo->p0_phy, pinfo->p1_phy);
((struct vfe_frame_extra *)extdata)->bl_evencol =
((struct vfe_endframe *)data)->blacklevelevencolumn;
@@ -99,20 +99,22 @@
break;
case VFE_MSG_OUTPUT_S: {
- pinfo->y_phy = paddr_s_y;
- pinfo->cbcr_phy = paddr_s_cbcr;
+ pinfo->p0_phy = paddr_s_y;
+ pinfo->p1_phy = paddr_s_cbcr;
+ pinfo->p2_phy = pinfo->p0_phy;
pinfo->output_id = OUTPUT_TYPE_S;
CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
- pinfo->y_phy, pinfo->cbcr_phy);
+ pinfo->p0_phy, pinfo->p1_phy);
}
break;
case VFE_MSG_OUTPUT_T: {
- pinfo->y_phy = paddr_t_y;
- pinfo->cbcr_phy = paddr_t_cbcr;
+ pinfo->p0_phy = paddr_t_y;
+ pinfo->p1_phy = paddr_t_cbcr;
+ pinfo->p2_phy = pinfo->p0_phy;
pinfo->output_id = OUTPUT_TYPE_T;
CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
- pinfo->y_phy, pinfo->cbcr_phy);
+ pinfo->p0_phy, pinfo->p1_phy);
}
break;
@@ -372,19 +374,19 @@
CDBG("bufnum1 = %d\n", ad->bufnum1);
if (mode == OUTPUT_1_AND_2) {
- paddr_t_y = regptr->paddr + regptr->info.y_off;
- paddr_t_cbcr = regptr->paddr + regptr->info.cbcr_off;
+ paddr_t_y = regptr->paddr + regptr->info.planar0_off;
+ paddr_t_cbcr = regptr->paddr + regptr->info.planar1_off;
}
CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
- regptr->paddr, regptr->info.y_off,
- regptr->info.cbcr_off);
+ regptr->paddr, regptr->info.planar0_off,
+ regptr->info.planar1_off);
bptr = &ao->output1buffer1_y_phy;
for (cnt = 0; cnt < ad->bufnum1; cnt++) {
- *bptr = regptr->paddr + regptr->info.y_off;
+ *bptr = regptr->paddr + regptr->info.planar0_off;
bptr++;
- *bptr = regptr->paddr + regptr->info.cbcr_off;
+ *bptr = regptr->paddr + regptr->info.planar1_off;
bptr++;
regptr++;
@@ -392,9 +394,9 @@
regptr--;
for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
- *bptr = regptr->paddr + regptr->info.y_off;
+ *bptr = regptr->paddr + regptr->info.planar0_off;
bptr++;
- *bptr = regptr->paddr + regptr->info.cbcr_off;
+ *bptr = regptr->paddr + regptr->info.planar1_off;
bptr++;
}
} /* if OUTPUT1 or Both */
@@ -403,16 +405,17 @@
regptr = &(ad->region[ad->bufnum1]);
CDBG("bufnum2 = %d\n", ad->bufnum2);
- paddr_s_y = regptr->paddr + regptr->info.y_off;
- paddr_s_cbcr = regptr->paddr + regptr->info.cbcr_off;
+ paddr_s_y = regptr->paddr + regptr->info.planar0_off;
+ paddr_s_cbcr = regptr->paddr + regptr->info.planar1_off;
CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
- regptr->paddr, regptr->info.y_off, regptr->info.cbcr_off);
+ regptr->paddr, regptr->info.planar0_off,
+ regptr->info.planar1_off);
bptr = &ao->output2buffer1_y_phy;
for (cnt = 0; cnt < ad->bufnum2; cnt++) {
- *bptr = regptr->paddr + regptr->info.y_off;
+ *bptr = regptr->paddr + regptr->info.planar0_off;
bptr++;
- *bptr = regptr->paddr + regptr->info.cbcr_off;
+ *bptr = regptr->paddr + regptr->info.planar1_off;
bptr++;
regptr++;
@@ -420,9 +423,9 @@
regptr--;
for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
- *bptr = regptr->paddr + regptr->info.y_off;
+ *bptr = regptr->paddr + regptr->info.planar0_off;
bptr++;
- *bptr = regptr->paddr + regptr->info.cbcr_off;
+ *bptr = regptr->paddr + regptr->info.planar1_off;
bptr++;
}
}
@@ -584,10 +587,10 @@
fack.header = VFE_FRAME_ACK;
fack.output2newybufferaddress =
- (void *)(p + b->y_off);
+ (void *)(p + b->planar0_off);
fack.output2newcbcrbufferaddress =
- (void *)(p + b->cbcr_off);
+ (void *)(p + b->planar1_off);
vfecmd->queue = QDSP_CMDQUEUE;
vfecmd->length = sizeof(struct vfe_outputack);
diff --git a/drivers/media/video/msm/msm_vfe7x27a.c b/drivers/media/video/msm/msm_vfe7x27a.c
index 9f7dff7..337085d 100644
--- a/drivers/media/video/msm/msm_vfe7x27a.c
+++ b/drivers/media/video/msm/msm_vfe7x27a.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
@@ -72,14 +72,14 @@
{
switch (type) {
case VFE_MSG_OUTPUT_P: {
- pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
- pinfo->cbcr_phy =
+ pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
+ pinfo->p1_phy =
((struct vfe_endframe *)data)->cbcr_address;
-
+ pinfo->p2_phy = pinfo->p0_phy;
pinfo->output_id = OUTPUT_TYPE_P;
CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
- pinfo->y_phy, pinfo->cbcr_phy);
+ pinfo->p0_phy, pinfo->p1_phy);
memcpy(((struct vfe_frame_extra *)extdata),
&((struct vfe_endframe *)data)->extra,
@@ -92,19 +92,21 @@
}
break;
case VFE_MSG_OUTPUT_S: {
- pinfo->y_phy = paddr_s_y;
- pinfo->cbcr_phy = paddr_s_cbcr;
+ pinfo->p0_phy = paddr_s_y;
+ pinfo->p1_phy = paddr_s_cbcr;
+ pinfo->p2_phy = pinfo->p0_phy;
pinfo->output_id = OUTPUT_TYPE_S;
CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
- pinfo->y_phy, pinfo->cbcr_phy);
+ pinfo->p0_phy, pinfo->p1_phy);
}
break;
case VFE_MSG_OUTPUT_T: {
- pinfo->y_phy = paddr_t_y;
- pinfo->cbcr_phy = paddr_t_cbcr;
+ pinfo->p0_phy = paddr_t_y;
+ pinfo->p1_phy = paddr_t_cbcr;
+ pinfo->p2_phy = pinfo->p0_phy;
pinfo->output_id = OUTPUT_TYPE_T;
CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
- pinfo->y_phy, pinfo->cbcr_phy);
+ pinfo->p0_phy, pinfo->p1_phy);
}
break;
case VFE_MSG_STATS_AF:
@@ -354,19 +356,20 @@
CDBG("bufnum1 = %d\n", ad->bufnum1);
if (mode == OUTPUT_1_AND_2) {
- paddr_t_y = regptr->paddr + regptr->info.y_off;
- paddr_t_cbcr = regptr->paddr + regptr->info.cbcr_off;
+ paddr_t_y = regptr->paddr + regptr->info.planar0_off;
+ paddr_t_cbcr = regptr->paddr +
+ regptr->info.planar1_off;
}
CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
- regptr->paddr, regptr->info.y_off,
- regptr->info.cbcr_off);
+ regptr->paddr, regptr->info.planar0_off,
+ regptr->info.planar1_off);
bptr = &ao->output1buffer1_y_phy;
for (cnt = 0; cnt < ad->bufnum1; cnt++) {
- *bptr = regptr->paddr + regptr->info.y_off;
+ *bptr = regptr->paddr + regptr->info.planar0_off;
bptr++;
- *bptr = regptr->paddr + regptr->info.cbcr_off;
+ *bptr = regptr->paddr + regptr->info.planar1_off;
bptr++;
regptr++;
@@ -374,9 +377,9 @@
regptr--;
for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
- *bptr = regptr->paddr + regptr->info.y_off;
+ *bptr = regptr->paddr + regptr->info.planar0_off;
bptr++;
- *bptr = regptr->paddr + regptr->info.cbcr_off;
+ *bptr = regptr->paddr + regptr->info.planar1_off;
bptr++;
}
}
@@ -385,17 +388,18 @@
regptr = &(ad->region[ad->bufnum1]);
CDBG("bufnum2 = %d\n", ad->bufnum2);
- paddr_s_y = regptr->paddr + regptr->info.y_off;
- paddr_s_cbcr = regptr->paddr + regptr->info.cbcr_off;
+ paddr_s_y = regptr->paddr + regptr->info.planar0_off;
+ paddr_s_cbcr = regptr->paddr + regptr->info.planar1_off;
CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
- regptr->paddr, regptr->info.y_off, regptr->info.cbcr_off);
+ regptr->paddr, regptr->info.planar0_off,
+ regptr->info.planar1_off);
bptr = &ao->output2buffer1_y_phy;
for (cnt = 0; cnt < ad->bufnum2; cnt++) {
- *bptr = regptr->paddr + regptr->info.y_off;
+ *bptr = regptr->paddr + regptr->info.planar0_off;
bptr++;
- *bptr = regptr->paddr + regptr->info.cbcr_off;
+ *bptr = regptr->paddr + regptr->info.planar1_off;
bptr++;
regptr++;
@@ -403,9 +407,9 @@
regptr--;
for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
- *bptr = regptr->paddr + regptr->info.y_off;
+ *bptr = regptr->paddr + regptr->info.planar0_off;
bptr++;
- *bptr = regptr->paddr + regptr->info.cbcr_off;
+ *bptr = regptr->paddr + regptr->info.planar1_off;
bptr++;
}
}
@@ -563,10 +567,10 @@
fack.header = VFE_FRAME_ACK;
fack.output2newybufferaddress =
- (void *)(p + b->y_off);
+ (void *)(p + b->planar0_off);
fack.output2newcbcrbufferaddress =
- (void *)(p + b->cbcr_off);
+ (void *)(p + b->planar1_off);
vfecmd->queue = QDSP_CMDQUEUE;
vfecmd->length = sizeof(struct vfe_outputack);
diff --git a/drivers/media/video/msm/msm_vfe8x.c b/drivers/media/video/msm/msm_vfe8x.c
index 0bf1785..a99c6f1 100644
--- a/drivers/media/video/msm/msm_vfe8x.c
+++ b/drivers/media/video/msm/msm_vfe8x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* 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
@@ -122,10 +122,10 @@
for (j = 0; j < ao->output1.fragmentCount; j++) {
- *p1 = regptr->paddr + regptr->info.y_off;
+ *p1 = regptr->paddr + regptr->info.planar0_off;
p1++;
- *p2 = regptr->paddr + regptr->info.cbcr_off;
+ *p2 = regptr->paddr + regptr->info.planar1_off;
p2++;
}
regptr++;
@@ -144,15 +144,16 @@
CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
"cbcr_off = %d\n", regptr->paddr,
- regptr->info.y_off, regptr->info.cbcr_off);
+ regptr->info.planar0_off,
+ regptr->info.planar1_off);
for (j = 0; j < ao->output2.fragmentCount; j++) {
- *p1 = regptr->paddr + regptr->info.y_off;
+ *p1 = regptr->paddr + regptr->info.planar0_off;
CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
p1++;
- *p2 = regptr->paddr + regptr->info.cbcr_off;
+ *p2 = regptr->paddr + regptr->info.planar1_off;
CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
p2++;
}
@@ -174,15 +175,15 @@
CDBG("config_axi: O1, phy = 0x%lx, y_off = %d, "\
"cbcr_off = %d\n", regptr->paddr,
- regptr->info.y_off, regptr->info.cbcr_off);
+ regptr->info.planar0_off, regptr->info.planar1_off);
for (j = 0; j < ao->output1.fragmentCount; j++) {
- *p1 = regptr->paddr + regptr->info.y_off;
+ *p1 = regptr->paddr + regptr->info.planar0_off;
CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
p1++;
- *p2 = regptr->paddr + regptr->info.cbcr_off;
+ *p2 = regptr->paddr + regptr->info.planar1_off;
CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
p2++;
}
@@ -194,15 +195,15 @@
CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
"cbcr_off = %d\n", regptr1->paddr,
- regptr1->info.y_off, regptr1->info.cbcr_off);
+ regptr1->info.planar0_off, regptr1->info.planar1_off);
for (j = 0; j < ao->output2.fragmentCount; j++) {
-
- *p1 = regptr1->paddr + regptr1->info.y_off;
+ *p1 = regptr1->paddr +
+ regptr1->info.planar0_off;
CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
p1++;
-
- *p2 = regptr1->paddr + regptr1->info.cbcr_off;
+ *p2 = regptr1->paddr +
+ r1->info.planar1_off;
CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
p2++;
}
@@ -689,9 +690,9 @@
b = (struct msm_frame *)(cmd->value);
p = *(unsigned long *)data;
- fack.ybufaddr[0] = (uint32_t) (p + b->y_off);
+ fack.ybufaddr[0] = (uint32_t) (p + b->planar0_off);
- fack.chromabufaddr[0] = (uint32_t) (p + b->cbcr_off);
+ fack.chromabufaddr[0] = (uint32_t) (p + b->planar1_off);
if (b->path == OUTPUT_TYPE_P)
vfe_output_p_ack(&fack);
diff --git a/drivers/media/video/msm/msm_vfe8x_proc.c b/drivers/media/video/msm/msm_vfe8x_proc.c
index 9764557..055b244 100644
--- a/drivers/media/video/msm/msm_vfe8x_proc.c
+++ b/drivers/media/video/msm/msm_vfe8x_proc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -608,11 +608,12 @@
switch (type) {
case VFE_MSG_OUTPUT_P:
case VFE_MSG_OUTPUT_V:{
- pinfo->y_phy =
+ pinfo->planar0_off =
((struct vfe_message *)data)->_u.msgOutput2.yBuffer;
- pinfo->cbcr_phy =
+ pinfo->planar1_off =
((struct vfe_message *)data)->_u.msgOutput2.
cbcrBuffer;
+ pinfo->planar2_off = pinfo->planar0_off;
ctrl->extdata.bpcInfo =
((struct vfe_message *)data)->_u.msgOutput2.bpcInfo;
ctrl->extdata.asfInfo =
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index 3a7faa2..fcf2495 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -466,6 +466,11 @@
struct msm_vpe_resp rp;
memset(&rp, 0, sizeof(rp));
spin_lock_irqsave(&vpe_ctrl->lock, flags);
+ if (vpe_ctrl->state == VPE_STATE_IDLE) {
+ pr_err("%s VPE is in IDLE state. Ignore the ack msg", __func__);
+ spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+ return;
+ }
rp.type = vpe_ctrl->pp_frame_info->pp_frame_cmd.path;
rp.extdata = (void *)vpe_ctrl->pp_frame_info;
rp.extlen = sizeof(*vpe_ctrl->pp_frame_info);
@@ -558,7 +563,6 @@
spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
return rc;
}
- vpe_ctrl->state = VPE_STATE_IDLE;
spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
@@ -569,6 +573,9 @@
vpe_ctrl->fs_vpe = NULL;
disable_irq(vpe_ctrl->vpeirq->start);
tasklet_kill(&vpe_tasklet);
+ spin_lock_irqsave(&vpe_ctrl->lock, flags);
+ vpe_ctrl->state = VPE_STATE_IDLE;
+ spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
return rc;
}
diff --git a/drivers/media/video/msm/msm_vpe1.c b/drivers/media/video/msm/msm_vpe1.c
index 891816f..5f128e1 100644
--- a/drivers/media/video/msm/msm_vpe1.c
+++ b/drivers/media/video/msm/msm_vpe1.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
@@ -709,15 +709,15 @@
return 1;
}
-void msm_send_frame_to_vpe(uint32_t pyaddr, uint32_t pcbcraddr,
+void msm_send_frame_to_vpe(uint32_t p0_phy_add, uint32_t p1_phy_add,
struct timespec *ts, int output_type)
{
uint32_t temp_pyaddr = 0, temp_pcbcraddr = 0;
- CDBG("vpe input, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
- pyaddr, pcbcraddr);
- msm_io_w(pyaddr, vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET);
- msm_io_w(pcbcraddr, vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET);
+ CDBG("vpe input, p0_phy_add = 0x%x, p1_phy_add = 0x%x\n",
+ p0_phy_add, p1_phy_add);
+ msm_io_w(p0_phy_add, vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET);
+ msm_io_w(p1_phy_add, vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET);
if (vpe_ctrl->state == VPE_STATE_ACTIVE)
CDBG(" =====VPE is busy!!! Wrong!========\n");
@@ -881,7 +881,7 @@
vpe_update_scaler_with_dis(&(vpe_buf->vpe_crop),
&(vpe_ctrl->dis_offset));
- msm_send_frame_to_vpe(vpe_buf->y_phy, vpe_buf->cbcr_phy,
+ msm_send_frame_to_vpe(vpe_buf->p0_phy, vpe_buf->p1_phy,
&(vpe_buf->ts), OUTPUT_TYPE_V);
if (!qcmd || !atomic_read(&qcmd->on_heap)) {
@@ -919,10 +919,10 @@
CDBG("In vpe_addr_convert output_id = %d\n", pinfo->output_id);
- pinfo->y_phy =
- ((struct vpe_message *)data)->_u.msgOut.yBuffer;
- pinfo->cbcr_phy =
- ((struct vpe_message *)data)->_u.msgOut.cbcrBuffer;
+ pinfo->p0_phy =
+ ((struct vpe_message *)data)->_u.msgOut.p0_Buffer;
+ pinfo->p1_phy =
+ ((struct vpe_message *)data)->_u.msgOut.p1_Buffer;
*ext = vpe_ctrl->extdata;
*elen = vpe_ctrl->extlen;
}
@@ -987,10 +987,10 @@
regp1 = &(ad->region[0]);
/* for video Y address */
- p1 = (regp1->paddr + regp1->info.y_off);
+ p1 = (regp1->paddr + regp1->info.planar0_off);
msm_io_w(p1, vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET);
/* for video CbCr address */
- p1 = (regp1->paddr + regp1->info.cbcr_off);
+ p1 = (regp1->paddr + regp1->info.planar1_off);
msm_io_w(p1, vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET);
return 0;
@@ -1048,8 +1048,8 @@
vpe_ctrl->frame_pack = frame_pack;
vpe_ctrl->output_type = output_id;
- input_stride = (st_half.buf_cbcr_stride * (1<<16)) +
- st_half.buf_y_stride;
+ input_stride = (st_half.buf_p1_stride * (1<<16)) +
+ st_half.buf_p0_stride;
msm_io_w(input_stride, vpe_device->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
@@ -1059,15 +1059,16 @@
msm_send_frame_to_vpe(pyaddr, pcbcraddr, ts, output_id);
}
-static void vpe_send_outmsg(uint8_t msgid, uint32_t pyaddr,
- uint32_t pcbcraddr)
+static void vpe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
+ uint32_t p1_addr, uint32_t p2_addr)
{
struct vpe_message msg;
uint8_t outid;
msg._d = outid = msgid;
msg._u.msgOut.output_id = msgid;
- msg._u.msgOut.yBuffer = pyaddr;
- msg._u.msgOut.cbcrBuffer = pcbcraddr;
+ msg._u.msgOut.p0_Buffer = p0_addr;
+ msg._u.msgOut.p1_Buffer = p1_addr;
+ msg._u.msgOut.p2_Buffer = p2_addr;
vpe_proc_ops(outid, &msg, sizeof(struct vpe_message));
return;
}
@@ -1203,10 +1204,11 @@
if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_R) {
CDBG("vpe send out R msg.\n");
vpe_send_outmsg(MSG_ID_VPE_OUTPUT_ST_R, pyaddr,
- pcbcraddr);
+ pcbcraddr, pyaddr);
} else if (vpe_ctrl->output_type == OUTPUT_TYPE_V) {
CDBG("vpe send out V msg.\n");
- vpe_send_outmsg(MSG_ID_VPE_OUTPUT_V, pyaddr, pcbcraddr);
+ vpe_send_outmsg(MSG_ID_VPE_OUTPUT_V, pyaddr,
+ pcbcraddr, pyaddr);
}
vpe_ctrl->output_type = 0;
diff --git a/drivers/media/video/msm/msm_vpe1.h b/drivers/media/video/msm/msm_vpe1.h
index ed7112e..f4d328d 100644
--- a/drivers/media/video/msm/msm_vpe1.h
+++ b/drivers/media/video/msm/msm_vpe1.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 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
@@ -212,8 +212,9 @@
struct vpe_msg_output {
uint8_t output_id;
- uint32_t yBuffer;
- uint32_t cbcrBuffer;
+ uint32_t p0_Buffer;
+ uint32_t p1_Buffer;
+ uint32_t p2_Buffer;
uint32_t frameCounter;
};
diff --git a/drivers/mfd/timpani-codec.c b/drivers/mfd/timpani-codec.c
index d2c2eb4..4b9aef2 100644
--- a/drivers/mfd/timpani-codec.c
+++ b/drivers/mfd/timpani-codec.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
@@ -2819,7 +2819,7 @@
u8 reg_mask = 0;
int rc = 0;
- for (i = 0; i < 0xEF; i++) {
+ for (i = 0; i < ARRAY_SIZE(timpani_regset); i++) {
if (timpani_regset[i].reg_addr == reg) {
for (j = 0; j < TIMPANI_MAX_FIELDS; j++) {
fld_mask = timpani_regset[i].fld_ref_cnt[j].mask
diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c
index 7ee7c11..f0d523e 100644
--- a/drivers/misc/pmem.c
+++ b/drivers/misc/pmem.c
@@ -1,7 +1,7 @@
/* drivers/android/pmem.c
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-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
@@ -2594,6 +2594,7 @@
{
int i, index = 0, id;
struct vm_struct *pmem_vma = NULL;
+ struct page *page;
if (id_count >= PMEM_MAX_DEVICES) {
pr_alert("pmem: %s: unable to register driver(%s) - no more "
@@ -2794,6 +2795,11 @@
pmem[id].base = allocate_contiguous_memory_nomap(pmem[id].size,
pmem[id].memory_type, PAGE_SIZE);
+ if (!pmem[id].base) {
+ pr_err("pmem: Cannot allocate from reserved memory for %s\n",
+ pdata->name);
+ goto err_misc_deregister;
+ }
pr_info("allocating %lu bytes at %p (%lx physical) for %s\n",
pmem[id].size, pmem[id].vbase, pmem[id].base, pmem[id].name);
@@ -2810,7 +2816,7 @@
if (!pmem_vma) {
pr_err("pmem: Failed to allocate virtual space for "
"%s\n", pdata->name);
- goto out_put_kobj;
+ goto err_free;
}
pr_err("pmem: Reserving virtual address range %lx - %lx for"
" %s\n", (unsigned long) pmem_vma->addr,
@@ -2821,7 +2827,12 @@
} else
pmem[id].area = NULL;
- pmem[id].garbage_pfn = page_to_pfn(alloc_page(GFP_KERNEL));
+ page = alloc_page(GFP_KERNEL);
+ if (!page) {
+ pr_err("pmem: Failed to allocate page for %s\n", pdata->name);
+ goto cleanup_vm;
+ }
+ pmem[id].garbage_pfn = page_to_pfn(page);
atomic_set(&pmem[id].allocation_cnt, 0);
if (pdata->setup_region)
@@ -2835,6 +2846,12 @@
return 0;
+cleanup_vm:
+ remove_vm_area(pmem_vma);
+err_free:
+ free_contiguous_memory_by_paddr(pmem[id].base);
+err_misc_deregister:
+ misc_deregister(&pmem[id].dev);
err_cant_register_device:
out_put_kobj:
kobject_put(&pmem[id].kobj);
@@ -2872,6 +2889,19 @@
int id = pdev->id;
__free_page(pfn_to_page(pmem[id].garbage_pfn));
pm_runtime_disable(&pdev->dev);
+ if (pmem[id].vbase)
+ iounmap(pmem[id].vbase);
+ if (pmem[id].map_on_demand && !pmem[id].reusable && pmem[id].area)
+ free_vm_area(pmem[id].area);
+ if (pmem[id].base)
+ free_contiguous_memory_by_paddr(pmem[id].base);
+ kobject_put(&pmem[id].kobj);
+ if (pmem[id].allocator_type == PMEM_ALLOCATORTYPE_BUDDYBESTFIT)
+ kfree(pmem[id].allocator.buddy_bestfit.buddy_bitmap);
+ else if (pmem[id].allocator_type == PMEM_ALLOCATORTYPE_BITMAP) {
+ kfree(pmem[id].allocator.bitmap.bitmap);
+ kfree(pmem[id].allocator.bitmap.bitm_alloc);
+ }
misc_deregister(&pmem[id].dev);
return 0;
}
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index dce8d6d..c3a756d 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -234,7 +234,6 @@
if (!skb->protocol)
skb->protocol = eth_type_trans(skb, dev->net);
- skb->protocol = eth_type_trans (skb, dev->net);
dev->net->stats.rx_packets++;
dev->net->stats.rx_bytes += skb->len;
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 9f689f1..19c0115 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -19,10 +19,12 @@
*/
#include <linux/errno.h>
+#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/string.h>
+#include <linux/slab.h>
/* For archs that don't support NO_IRQ (such as x86), provide a dummy value */
#ifndef NO_IRQ
@@ -386,3 +388,110 @@
return i;
}
+
+struct intc_desc {
+ struct list_head list;
+ struct device_node *dev;
+ struct device_node *interrupt_parent;
+};
+
+/**
+ * of_irq_init - Scan and init matching interrupt controllers in DT
+ * @matches: 0 terminated array of nodes to match and init function to call
+ *
+ * This function scans the device tree for matching interrupt controller nodes,
+ * and calls their initialization functions in order with parents first.
+ */
+void __init of_irq_init(const struct of_device_id *matches)
+{
+ struct device_node *np, *parent = NULL;
+ struct intc_desc *desc, *temp_desc;
+ struct list_head intc_desc_list, intc_parent_list;
+
+ INIT_LIST_HEAD(&intc_desc_list);
+ INIT_LIST_HEAD(&intc_parent_list);
+
+ for_each_matching_node(np, matches) {
+ if (!of_find_property(np, "interrupt-controller", NULL))
+ continue;
+ /*
+ * Here, we allocate and populate an intc_desc with the node
+ * pointer, interrupt-parent device_node etc.
+ */
+ desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+ if (WARN_ON(!desc))
+ goto err;
+
+ desc->dev = np;
+ desc->interrupt_parent = of_irq_find_parent(np);
+ if (desc->interrupt_parent == np)
+ desc->interrupt_parent = NULL;
+ list_add_tail(&desc->list, &intc_desc_list);
+ }
+
+ /*
+ * The root irq controller is the one without an interrupt-parent.
+ * That one goes first, followed by the controllers that reference it,
+ * followed by the ones that reference the 2nd level controllers, etc.
+ */
+ while (!list_empty(&intc_desc_list)) {
+ /*
+ * Process all controllers with the current 'parent'.
+ * First pass will be looking for NULL as the parent.
+ * The assumption is that NULL parent means a root controller.
+ */
+ list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
+ const struct of_device_id *match;
+ int ret;
+ of_irq_init_cb_t irq_init_cb;
+
+ if (desc->interrupt_parent != parent)
+ continue;
+
+ list_del(&desc->list);
+ match = of_match_node(matches, desc->dev);
+ if (WARN(!match->data,
+ "of_irq_init: no init function for %s\n",
+ match->compatible)) {
+ kfree(desc);
+ continue;
+ }
+
+ pr_debug("of_irq_init: init %s @ %p, parent %p\n",
+ match->compatible,
+ desc->dev, desc->interrupt_parent);
+ irq_init_cb = match->data;
+ ret = irq_init_cb(desc->dev, desc->interrupt_parent);
+ if (ret) {
+ kfree(desc);
+ continue;
+ }
+
+ /*
+ * This one is now set up; add it to the parent list so
+ * its children can get processed in a subsequent pass.
+ */
+ list_add_tail(&desc->list, &intc_parent_list);
+ }
+
+ /* Get the next pending parent that might have children */
+ desc = list_first_entry(&intc_parent_list, typeof(*desc), list);
+ if (list_empty(&intc_parent_list) || !desc) {
+ pr_err("of_irq_init: children remain, but no parents\n");
+ break;
+ }
+ list_del(&desc->list);
+ parent = desc->dev;
+ kfree(desc);
+ }
+
+ list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
+ list_del(&desc->list);
+ kfree(desc);
+ }
+err:
+ list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
+ list_del(&desc->list);
+ kfree(desc);
+ }
+}
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5b2328d..2b58215 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1319,6 +1319,40 @@
}
EXPORT_SYMBOL_GPL(regulator_get);
+static void devm_regulator_release(struct device *dev, void *res)
+{
+ regulator_put(*(struct regulator **)res);
+}
+
+/**
+ * devm_regulator_get - Resource managed regulator_get()
+ * @dev: device for regulator "consumer"
+ * @id: Supply name or regulator ID.
+ *
+ * Managed regulator_get(). Regulators returned from this function are
+ * automatically regulator_put() on driver detach. See regulator_get() for more
+ * information.
+ */
+struct regulator *devm_regulator_get(struct device *dev, const char *id)
+{
+ struct regulator **ptr, *regulator;
+
+ ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ regulator = regulator_get(dev, id);
+ if (!IS_ERR(regulator)) {
+ *ptr = regulator;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return regulator;
+}
+EXPORT_SYMBOL_GPL(devm_regulator_get);
+
/**
* regulator_get_exclusive - obtain exclusive access to a regulator.
* @dev: device for regulator "consumer"
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index e13b4c4..a0763da 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -3,6 +3,7 @@
* Android IPC Subsystem
*
* Copyright (C) 2007-2008 Google, Inc.
+ * 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
@@ -97,9 +98,9 @@
BINDER_DEBUG_BUFFER_ALLOC = 1U << 13,
BINDER_DEBUG_PRIORITY_CAP = 1U << 14,
BINDER_DEBUG_BUFFER_ALLOC_ASYNC = 1U << 15,
+ BINDER_DEBUG_TOP_ERRORS = 1U << 16,
};
-static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |
- BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
+static uint32_t binder_debug_mask;
module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
static int binder_debug_no_lock;
@@ -638,7 +639,8 @@
goto free_range;
if (vma == NULL) {
- printk(KERN_ERR "binder: %d: binder_alloc_buf failed to "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: %d: binder_alloc_buf failed to "
"map pages in userspace, no vma\n", proc->pid);
goto err_no_vma;
}
@@ -651,7 +653,8 @@
BUG_ON(*page);
*page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (*page == NULL) {
- printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: %d: binder_alloc_buf failed "
"for page at %p\n", proc->pid, page_addr);
goto err_alloc_page_failed;
}
@@ -660,7 +663,8 @@
page_array_ptr = page;
ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr);
if (ret) {
- printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: %d: binder_alloc_buf failed "
"to map page at %p in kernel\n",
proc->pid, page_addr);
goto err_map_kernel_failed;
@@ -669,7 +673,8 @@
(uintptr_t)page_addr + proc->user_buffer_offset;
ret = vm_insert_page(vma, user_page_addr, page[0]);
if (ret) {
- printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: %d: binder_alloc_buf failed "
"to map page at %lx in userspace\n",
proc->pid, user_page_addr);
goto err_vm_insert_page_failed;
@@ -718,7 +723,8 @@
size_t size;
if (proc->vma == NULL) {
- printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n",
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: %d: binder_alloc_buf, no vma\n",
proc->pid);
return NULL;
}
@@ -756,7 +762,8 @@
}
}
if (best_fit == NULL) {
- printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: %d: binder_alloc_buf size %zd failed, "
"no address space\n", proc->pid, size);
return NULL;
}
@@ -991,7 +998,8 @@
node->internal_strong_refs == 0 &&
!(node == binder_context_mgr_node &&
node->has_strong_ref)) {
- printk(KERN_ERR "binder: invalid inc strong "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: invalid inc strong "
"node for %d\n", node->debug_id);
return -EINVAL;
}
@@ -1007,7 +1015,8 @@
node->local_weak_refs++;
if (!node->has_weak_ref && list_empty(&node->work.entry)) {
if (target_list == NULL) {
- printk(KERN_ERR "binder: invalid inc weak node "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: invalid inc weak node "
"for %d\n", node->debug_id);
return -EINVAL;
}
@@ -1044,7 +1053,7 @@
if (node->proc) {
rb_erase(&node->rb_node, &node->proc->nodes);
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
- "binder: refless node %d deleted\n",
+ "binder: refless node %d deleted\n",
node->debug_id);
} else {
hlist_del(&node->dead_node);
@@ -1263,14 +1272,16 @@
binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
"binder: send failed reply for "
"transaction %d to %d:%d\n",
- t->debug_id, target_thread->proc->pid,
+ t->debug_id,
+ target_thread->proc->pid,
target_thread->pid);
binder_pop_transaction(target_thread, t);
target_thread->return_error = error_code;
wake_up_interruptible(&target_thread->wait);
} else {
- printk(KERN_ERR "binder: reply failed, target "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: reply failed, target "
"thread, %d:%d, has error code %d "
"already\n", target_thread->proc->pid,
target_thread->pid,
@@ -1308,14 +1319,15 @@
int debug_id = buffer->debug_id;
binder_debug(BINDER_DEBUG_TRANSACTION,
- "binder: %d buffer release %d, size %zd-%zd, failed at %p\n",
- proc->pid, buffer->debug_id,
+ "binder: %d buffer release %d, size %zd-%zd, failed at"
+ " %p\n", proc->pid, buffer->debug_id,
buffer->data_size, buffer->offsets_size, failed_at);
if (buffer->target_node)
binder_dec_node(buffer->target_node, 1, 0);
- offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *)));
+ offp = (size_t *)(buffer->data + ALIGN(buffer->data_size,
+ sizeof(void *)));
if (failed_at)
off_end = failed_at;
else
@@ -1325,7 +1337,8 @@
if (*offp > buffer->data_size - sizeof(*fp) ||
buffer->data_size < sizeof(*fp) ||
!IS_ALIGNED(*offp, sizeof(void *))) {
- printk(KERN_ERR "binder: transaction release %d bad"
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: transaction release %d bad"
"offset %zd, size %zd\n", debug_id,
*offp, buffer->data_size);
continue;
@@ -1334,29 +1347,35 @@
switch (fp->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
- struct binder_node *node = binder_get_node(proc, fp->binder);
+ struct binder_node *node = binder_get_node(proc,
+ fp->binder);
if (node == NULL) {
- printk(KERN_ERR "binder: transaction release %d"
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: transaction release %d"
" bad node %p\n", debug_id, fp->binder);
break;
}
binder_debug(BINDER_DEBUG_TRANSACTION,
" node %d u%p\n",
node->debug_id, node->ptr);
- binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
+ binder_dec_node(node, fp->type == BINDER_TYPE_BINDER,
+ 0);
} break;
case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE: {
- struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+ struct binder_ref *ref = binder_get_ref(proc,
+ fp->handle);
if (ref == NULL) {
- printk(KERN_ERR "binder: transaction release %d"
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: transaction release %d"
" bad handle %ld\n", debug_id,
fp->handle);
break;
}
binder_debug(BINDER_DEBUG_TRANSACTION,
" ref %d desc %d (node %d)\n",
- ref->debug_id, ref->desc, ref->node->debug_id);
+ ref->debug_id, ref->desc,
+ ref->node->debug_id);
binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE);
} break;
@@ -1368,7 +1387,8 @@
break;
default:
- printk(KERN_ERR "binder: transaction release %d bad "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: transaction release %d bad "
"object type %lx\n", debug_id, fp->type);
break;
}
@@ -1594,15 +1614,19 @@
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
struct binder_ref *ref;
- struct binder_node *node = binder_get_node(proc, fp->binder);
+ struct binder_node *node = binder_get_node(proc,
+ fp->binder);
if (node == NULL) {
- node = binder_new_node(proc, fp->binder, fp->cookie);
+ node = binder_new_node(proc, fp->binder,
+ fp->cookie);
if (node == NULL) {
return_error = BR_FAILED_REPLY;
goto err_binder_new_node_failed;
}
- node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
- node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
+ node->min_priority = fp->flags &
+ FLAT_BINDER_FLAG_PRIORITY_MASK;
+ node->accept_fds = !!(fp->flags &
+ FLAT_BINDER_FLAG_ACCEPTS_FDS);
}
if (fp->cookie != node->cookie) {
binder_user_error("binder: %d:%d sending u%p "
@@ -1632,7 +1656,8 @@
} break;
case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE: {
- struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+ struct binder_ref *ref = binder_get_ref(proc,
+ fp->handle);
if (ref == NULL) {
binder_user_error("binder: %d:%d got "
"transaction with invalid "
@@ -1648,24 +1673,31 @@
fp->type = BINDER_TYPE_WEAK_BINDER;
fp->binder = ref->node->ptr;
fp->cookie = ref->node->cookie;
- binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
+ binder_inc_node(ref->node, fp->type ==
+ BINDER_TYPE_BINDER, 0, NULL);
binder_debug(BINDER_DEBUG_TRANSACTION,
- " ref %d desc %d -> node %d u%p\n",
- ref->debug_id, ref->desc, ref->node->debug_id,
- ref->node->ptr);
+ " ref %d desc %d -> node %d u%p\n",
+ ref->debug_id, ref->desc,
+ ref->node->debug_id,
+ ref->node->ptr);
} else {
struct binder_ref *new_ref;
- new_ref = binder_get_ref_for_node(target_proc, ref->node);
+ new_ref = binder_get_ref_for_node(target_proc,
+ ref->node);
if (new_ref == NULL) {
return_error = BR_FAILED_REPLY;
goto err_binder_get_ref_for_node_failed;
}
fp->handle = new_ref->desc;
- binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
+ binder_inc_ref(new_ref, fp->type ==
+ BINDER_TYPE_HANDLE, NULL);
binder_debug(BINDER_DEBUG_TRANSACTION,
- " ref %d desc %d -> ref %d desc %d (node %d)\n",
- ref->debug_id, ref->desc, new_ref->debug_id,
- new_ref->desc, ref->node->debug_id);
+ " ref %d desc %d -> ref %d"
+ " desc %d (node %d)\n",
+ ref->debug_id, ref->desc,
+ new_ref->debug_id,
+ new_ref->desc,
+ ref->node->debug_id);
}
} break;
@@ -1675,13 +1707,19 @@
if (reply) {
if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
- binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
- proc->pid, thread->pid, fp->handle);
+ binder_user_error("binder: %d:%d got"
+ " reply with fd, %ld, but"
+ " target does not allow fds\n",
+ proc->pid, thread->pid,
+ fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fd_not_allowed;
}
} else if (!target_node->accept_fds) {
- binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
+ binder_user_error(
+ "binder: %d:%d got transaction"
+ " with fd, %ld, but target does"
+ " not allow fds\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fd_not_allowed;
@@ -1689,12 +1727,15 @@
file = fget(fp->handle);
if (file == NULL) {
- binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
+ binder_user_error(
+ "binder: %d:%d got transaction"
+ " with invalid fd, %ld\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fget_failed;
}
- target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
+ target_fd = task_get_unused_fd_flags(target_proc,
+ O_CLOEXEC);
if (target_fd < 0) {
fput(file);
return_error = BR_FAILED_REPLY;
@@ -1702,7 +1743,8 @@
}
task_fd_install(target_proc, target_fd, file);
binder_debug(BINDER_DEBUG_TRANSACTION,
- " fd %ld -> %d\n", fp->handle, target_fd);
+ " fd %ld -> %d\n", fp->handle,
+ target_fd);
/* TODO: fput? */
fp->handle = target_fd;
} break;
@@ -1851,9 +1893,11 @@
break;
}
binder_debug(BINDER_DEBUG_USER_REFS,
- "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n",
- proc->pid, thread->pid, debug_string, ref->debug_id,
- ref->desc, ref->strong, ref->weak, ref->node->debug_id);
+ "binder: %d:%d %s ref %d desc %d s %d w %d"
+ " for node %d\n", proc->pid, thread->pid,
+ debug_string, ref->debug_id, ref->desc,
+ ref->strong, ref->weak,
+ ref->node->debug_id);
break;
}
case BC_INCREFS_DONE:
@@ -1914,15 +1958,19 @@
binder_debug(BINDER_DEBUG_USER_REFS,
"binder: %d:%d %s node %d ls %d lw %d\n",
proc->pid, thread->pid,
- cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
- node->debug_id, node->local_strong_refs, node->local_weak_refs);
+ cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE"
+ : "BC_ACQUIRE_DONE",
+ node->debug_id, node->local_strong_refs,
+ node->local_weak_refs);
break;
}
case BC_ATTEMPT_ACQUIRE:
- printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n");
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: BC_ATTEMPT_ACQUIRE not supported\n");
return -EINVAL;
case BC_ACQUIRE_RESULT:
- printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n");
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: BC_ACQUIRE_RESULT not supported\n");
return -EINVAL;
case BC_FREE_BUFFER: {
@@ -1948,9 +1996,11 @@
break;
}
binder_debug(BINDER_DEBUG_FREE_BUFFER,
- "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
- proc->pid, thread->pid, data_ptr, buffer->debug_id,
- buffer->transaction ? "active" : "finished");
+ "binder: %d:%d BC_FREE_BUFFER u%p found"
+ " buffer %d for %s transaction\n",
+ proc->pid, thread->pid, data_ptr,
+ buffer->debug_id, buffer->transaction ?
+ "active" : "finished");
if (buffer->transaction) {
buffer->transaction->buffer = NULL;
@@ -2047,13 +2097,15 @@
}
binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
- "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
+ "binder: %d:%d %s %p ref %d desc %d s %d"
+ " w %d for node %d\n",
proc->pid, thread->pid,
cmd == BC_REQUEST_DEATH_NOTIFICATION ?
"BC_REQUEST_DEATH_NOTIFICATION" :
"BC_CLEAR_DEATH_NOTIFICATION",
cookie, ref->debug_id, ref->desc,
- ref->strong, ref->weak, ref->node->debug_id);
+ ref->strong, ref->weak,
+ ref->node->debug_id);
if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
if (ref->death) {
@@ -2067,10 +2119,12 @@
death = kzalloc(sizeof(*death), GFP_KERNEL);
if (death == NULL) {
thread->return_error = BR_ERROR;
- binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
- "binder: %d:%d "
- "BC_REQUEST_DEATH_NOTIFICATION failed\n",
- proc->pid, thread->pid);
+ binder_debug(
+ BINDER_DEBUG_FAILED_TRANSACTION,
+ "binder: %d:%d "
+ "BC_REQUEST_DEATH_NOTIFICATION"
+ " failed\n",
+ proc->pid, thread->pid);
break;
}
binder_stats_created(BINDER_STAT_DEATH);
@@ -2159,7 +2213,8 @@
} break;
default:
- printk(KERN_ERR "binder: %d:%d unknown command %d\n",
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: %d:%d unknown command %d\n",
proc->pid, thread->pid, cmd);
return -EINVAL;
}
@@ -2629,9 +2684,11 @@
unsigned int size = _IOC_SIZE(cmd);
void __user *ubuf = (void __user *)arg;
- /*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/
+ /*binder_debug(BINDER_DEBUG_TOP_ERRORS, "binder_ioctl: %d:%d %x %lx\n",
+ proc->pid, current->pid, cmd, arg);*/
- ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
+ ret = wait_event_interruptible(binder_user_error_wait,
+ binder_stop_on_user_error < 2);
if (ret)
return ret;
@@ -2688,20 +2745,23 @@
break;
}
case BINDER_SET_MAX_THREADS:
- if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
+ if (copy_from_user(&proc->max_threads, ubuf,
+ sizeof(proc->max_threads))) {
ret = -EINVAL;
goto err;
}
break;
case BINDER_SET_CONTEXT_MGR:
if (binder_context_mgr_node != NULL) {
- printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: BINDER_SET_CONTEXT_MGR already set\n");
ret = -EBUSY;
goto err;
}
if (binder_context_mgr_uid != -1) {
if (binder_context_mgr_uid != current->cred->euid) {
- printk(KERN_ERR "binder: BINDER_SET_"
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: BINDER_SET_"
"CONTEXT_MGR bad uid %d != %d\n",
current->cred->euid,
binder_context_mgr_uid);
@@ -2747,7 +2807,9 @@
mutex_unlock(&binder_lock);
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret && ret != -ERESTARTSYS)
- printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: %d:%d ioctl %x %lx returned %d\n",
+ proc->pid, current->pid, cmd, arg, ret);
return ret;
}
@@ -2821,7 +2883,9 @@
#ifdef CONFIG_CPU_CACHE_VIPT
if (cache_is_vipt_aliasing()) {
while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) {
- printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder_mmap: %d %lx-%lx maps %p bad alignment\n",
+ proc->pid, vma->vm_start, vma->vm_end, proc->buffer);
vma->vm_start += PAGE_SIZE;
}
}
@@ -2852,7 +2916,8 @@
proc->files = get_files_struct(current);
proc->vma = vma;
- /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
+ /*binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder_mmap: %d %lx-%lx maps %p\n",
proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
return 0;
@@ -2865,7 +2930,8 @@
err_get_vm_area_failed:
err_already_mapped:
err_bad_arg:
- printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder_mmap: %d %lx-%lx %s failed %d\n",
proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
return ret;
}
@@ -3020,7 +3086,8 @@
if (t) {
t->buffer = NULL;
buffer->transaction = NULL;
- printk(KERN_ERR "binder: release proc %d, "
+ binder_debug(BINDER_DEBUG_TOP_ERRORS,
+ "binder: release proc %d, "
"transaction %d, not freed\n",
proc->pid, t->debug_id);
/*BUG();*/
diff --git a/drivers/staging/qcache/qcache-main.c b/drivers/staging/qcache/qcache-main.c
index b6de268..f6838d1 100644
--- a/drivers/staging/qcache/qcache-main.c
+++ b/drivers/staging/qcache/qcache-main.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp.
* Copyright (c) 2010,2011, Nitin Gupta
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Qcache provides an in-kernel "host implementation" for transcendent memory
* and, thus indirectly, for cleancache and frontswap. Qcache includes a
@@ -230,7 +230,6 @@
budnum = zbud_budnum(zh);
BUG_ON(size == 0 || size > zbud_max_buddy_size());
zbpg = container_of(zh, struct zbud_page, buddy[budnum]);
- ASSERT_SPINLOCK(&zbpg->lock);
p = (char *)zbpg;
if (budnum == 0)
p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) &
@@ -270,7 +269,6 @@
ASSERT_SENTINEL(zbpg, ZBPG);
BUG_ON(!list_empty(&zbpg->bud_list));
- ASSERT_SPINLOCK(&zbpg->lock);
BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid));
BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid));
INVERT_SENTINEL(zbpg, ZBPG);
@@ -312,7 +310,6 @@
return;
}
size = zbud_free(zh);
- ASSERT_SPINLOCK(&zbpg->lock);
zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0];
if (zh_other->size == 0) { /* was unbuddied: unlist and free */
chunks = zbud_size_to_chunks(size) ;
@@ -372,7 +369,6 @@
goto init_zh;
found_unbuddied:
- ASSERT_SPINLOCK(&zbpg->lock);
zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1];
BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0)));
if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */
diff --git a/drivers/staging/qcache/tmem.h b/drivers/staging/qcache/tmem.h
index 344561f..9f6bfbb 100644
--- a/drivers/staging/qcache/tmem.h
+++ b/drivers/staging/qcache/tmem.h
@@ -4,7 +4,7 @@
* Transcendent memory
*
* Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*/
#ifndef _TMEM_H_
@@ -49,8 +49,6 @@
#define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0)
#endif
-#define ASSERT_SPINLOCK(_l) WARN_ON(!spin_is_locked(_l))
-
/*
* A pool is the highest-level data structure managed by tmem and
* usually corresponds to a large independent set of pages such as
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 1369f4f..23e0da8 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -602,7 +602,7 @@
struct bam_ch_info *d;
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
if (!port || !port->port_usb)
goto free_buf_out;
@@ -619,7 +619,7 @@
dev_kfree_skb_any(skb);
free_buf_out:
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
}
@@ -643,9 +643,9 @@
unsigned long flags;
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
port->port_usb = 0;
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
/* disable endpoints */
@@ -664,13 +664,13 @@
unsigned long flags;
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
if (!port->port_usb) {
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
return;
}
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
if (!test_bit(BAM_CH_READY, &d->flags))
@@ -714,9 +714,9 @@
}
port->gr->out->driver_data = port;
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
port->port_usb = port->gr;
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
@@ -775,10 +775,10 @@
/* if usb is online, try opening bam_ch */
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
if (port->port_usb)
queue_work(gbam_wq, &port->connect_w);
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
break;
@@ -807,12 +807,12 @@
d = &port->data_ch;
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
if (port->port_usb) {
ep_in = port->port_usb->in;
ep_out = port->port_usb->out;
}
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
if (ep_in)
@@ -946,7 +946,7 @@
if (!port)
continue;
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
d = &port->data_ch;
@@ -969,7 +969,7 @@
test_bit(BAM_CH_OPENED, &d->flags),
test_bit(BAM_CH_READY, &d->flags));
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
}
@@ -994,7 +994,7 @@
continue;
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
d = &port->data_ch;
@@ -1004,7 +1004,7 @@
d->tohost_drp_cnt = 0;
d->tomodem_drp_cnt = 0;
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
}
return count;
@@ -1071,10 +1071,10 @@
gbam_free_buffers(port);
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
port->port_usb = 0;
n_tx_req_queued = 0;
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
/* disable endpoints */
@@ -1136,7 +1136,7 @@
gr->out->driver_data = port;
spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock_irqsave(&port->port_lock_dl, flags);
+ spin_lock(&port->port_lock_dl);
port->port_usb = gr;
d->to_host = 0;
@@ -1144,7 +1144,7 @@
d->pending_with_bam = 0;
d->tohost_drp_cnt = 0;
d->tomodem_drp_cnt = 0;
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
+ spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
}
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 1066f38..787514c 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1592,14 +1592,15 @@
{
struct msm_otg *motg = container_of(w, struct msm_otg, chg_work.work);
struct otg_transceiver *otg = &motg->otg;
- bool is_dcd, tmout, vout, is_aca;
+ bool is_dcd = false, tmout, vout, is_aca;
unsigned long delay;
dev_dbg(otg->dev, "chg detection work\n");
switch (motg->chg_state) {
case USB_CHG_STATE_UNDEFINED:
msm_chg_block_on(motg);
- msm_chg_enable_dcd(motg);
+ if (motg->pdata->enable_dcd)
+ msm_chg_enable_dcd(motg);
msm_chg_enable_aca_det(motg);
motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
motg->dcd_retries = 0;
@@ -1619,10 +1620,12 @@
break;
}
}
- is_dcd = msm_chg_check_dcd(motg);
+ if (motg->pdata->enable_dcd)
+ is_dcd = msm_chg_check_dcd(motg);
tmout = ++motg->dcd_retries == MSM_CHG_DCD_MAX_RETRIES;
if (is_dcd || tmout) {
- msm_chg_disable_dcd(motg);
+ if (motg->pdata->enable_dcd)
+ msm_chg_disable_dcd(motg);
msm_chg_enable_primary_det(motg);
delay = MSM_CHG_PRIMARY_DET_TIME;
motg->chg_state = USB_CHG_STATE_DCD_DONE;
@@ -1713,11 +1716,12 @@
else
clear_bit(B_SESS_VLD, &motg->inputs);
} else if (pdata->otg_control == OTG_PMIC_CONTROL) {
- if (irq_read_line(motg->pdata->pmic_id_irq))
- set_bit(ID, &motg->inputs);
- else
- clear_bit(ID, &motg->inputs);
-
+ if (pdata->pmic_id_irq) {
+ if (irq_read_line(pdata->pmic_id_irq))
+ set_bit(ID, &motg->inputs);
+ else
+ clear_bit(ID, &motg->inputs);
+ }
/*
* VBUS initial state is reported after PMIC
* driver initialization. Wait for it.
@@ -1730,10 +1734,18 @@
break;
case USB_PERIPHERAL:
set_bit(ID, &motg->inputs);
- if (otgsc & OTGSC_BSV)
- set_bit(B_SESS_VLD, &motg->inputs);
- else
- clear_bit(B_SESS_VLD, &motg->inputs);
+ if (pdata->otg_control == OTG_PHY_CONTROL) {
+ if (otgsc & OTGSC_BSV)
+ set_bit(B_SESS_VLD, &motg->inputs);
+ else
+ clear_bit(B_SESS_VLD, &motg->inputs);
+ } else if (pdata->otg_control == OTG_PMIC_CONTROL) {
+ /*
+ * VBUS initial state is reported after PMIC
+ * driver initialization. Wait for it.
+ */
+ wait_for_completion(&pmic_vbus_init);
+ }
break;
default:
break;
@@ -2511,7 +2523,8 @@
goto free_irq;
}
- if (motg->pdata->otg_control == OTG_PMIC_CONTROL) {
+ if (motg->pdata->mode == USB_OTG &&
+ motg->pdata->otg_control == OTG_PMIC_CONTROL) {
if (motg->pdata->pmic_id_irq) {
ret = request_irq(motg->pdata->pmic_id_irq,
msm_pmic_id_irq,
@@ -2545,7 +2558,8 @@
if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY) {
if (motg->pdata->otg_control == OTG_PMIC_CONTROL &&
- motg->pdata->pmic_id_irq)
+ (!(motg->pdata->mode == USB_OTG) ||
+ motg->pdata->pmic_id_irq))
motg->caps = ALLOW_PHY_POWER_COLLAPSE |
ALLOW_PHY_RETENTION |
ALLOW_PHY_COMP_DISABLE;
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index c795a94..2a243cd 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 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
@@ -136,10 +136,10 @@
480, 10, 2, 33, TRUE, 25200, 60000, FALSE, TRUE}
#define HDMI_SETTINGS_720x480p60_4_3 \
{HDMI_VFRMT_720x480p60_4_3, 720, 16, 62, 60, TRUE, \
- 480, 9, 6, 30, TRUE, 27027, 60000, FALSE, TRUE}
+ 480, 9, 6, 30, TRUE, 27030, 60000, FALSE, TRUE}
#define HDMI_SETTINGS_720x480p60_16_9 \
{HDMI_VFRMT_720x480p60_16_9, 720, 16, 62, 60, TRUE, \
- 480, 9, 6, 30, TRUE, 27027, 60000, FALSE, TRUE}
+ 480, 9, 6, 30, TRUE, 27030, 60000, FALSE, TRUE}
#define HDMI_SETTINGS_1280x720p60_16_9 \
{HDMI_VFRMT_1280x720p60_16_9, 1280, 110, 40, 220, FALSE, \
720, 5, 5, 20, FALSE, 74250, 60000, FALSE, TRUE}
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index aaad2df..fc6054f 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.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
@@ -2324,29 +2324,6 @@
msm_hdmi_init_ddc();
- /* Read Bksv 5 bytes at 0x00 in HDCP port */
- ret = hdmi_msm_ddc_read(0x74, 0x00, bksv, 5, 5, "Bksv", TRUE);
- if (ret) {
- DEV_ERR("%s(%d): Read BKSV failed", __func__, __LINE__);
- goto error;
- }
- /* check there are 20 ones in BKSV */
- if (hdmi_msm_count_one(bksv, 5) != 20) {
- DEV_ERR("HDCP: BKSV read from Sink doesn't have "
- "20 1's and 20 0's, FAIL (BKSV="
- "%02x%02x%02x%02x%02x)\n",
- bksv[4], bksv[3], bksv[2], bksv[1], bksv[0]);
- ret = -EINVAL;
- goto error;
- }
-
- link0_bksv_0 = bksv[3];
- link0_bksv_0 = (link0_bksv_0 << 8) | bksv[2];
- link0_bksv_0 = (link0_bksv_0 << 8) | bksv[1];
- link0_bksv_0 = (link0_bksv_0 << 8) | bksv[0];
- link0_bksv_1 = bksv[4];
- DEV_DBG("HDCP: BKSV=%02x%08x\n", link0_bksv_1, link0_bksv_0);
-
/* read Bcaps at 0x40 in HDCP Port */
ret = hdmi_msm_ddc_read(0x74, 0x40, &bcaps, 1, 5, "Bcaps",
TRUE);
@@ -2494,6 +2471,29 @@
DEV_DBG("HDCP: Link0-AKSV=%02x%08x\n",
link0_aksv_1 & 0xFF, link0_aksv_0);
+ /* Read Bksv 5 bytes at 0x00 in HDCP port */
+ ret = hdmi_msm_ddc_read(0x74, 0x00, bksv, 5, 5, "Bksv", TRUE);
+ if (ret) {
+ DEV_ERR("%s(%d): Read BKSV failed", __func__, __LINE__);
+ goto error;
+ }
+ /* check there are 20 ones in BKSV */
+ if (hdmi_msm_count_one(bksv, 5) != 20) {
+ DEV_ERR("HDCP: BKSV read from Sink doesn't have "
+ "20 1's and 20 0's, FAIL (BKSV="
+ "%02x%02x%02x%02x%02x)\n",
+ bksv[4], bksv[3], bksv[2], bksv[1], bksv[0]);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ link0_bksv_0 = bksv[3];
+ link0_bksv_0 = (link0_bksv_0 << 8) | bksv[2];
+ link0_bksv_0 = (link0_bksv_0 << 8) | bksv[1];
+ link0_bksv_0 = (link0_bksv_0 << 8) | bksv[0];
+ link0_bksv_1 = bksv[4];
+ DEV_DBG("HDCP: BKSV=%02x%08x\n", link0_bksv_1, link0_bksv_0);
+
/* 0x0134 HDCP_RCVPORT_DATA0
[31:0] LINK0_BKSV_0 */
HDMI_OUTP(0x0134, link0_bksv_0);
@@ -3073,7 +3073,7 @@
{4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000},
{12288, 27000}, {25088, 30000}, {24576, 27000} }),
/* 27.027MHz */
- HDMI_MSM_AUDIO_ARCS(27027, {
+ HDMI_MSM_AUDIO_ARCS(27030, {
{4096, 27027}, {6272, 30030}, {6144, 27027}, {12544, 30030},
{12288, 27027}, {25088, 30030}, {24576, 27027} }),
/* 74.250MHz */
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index a905ec0..5ad6de3f 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -451,6 +451,29 @@
complete(&dma->comp);
}
+static void mdp4_overlay_lcdc_prefill(struct msm_fb_data_type *mfd)
+{
+ unsigned long flag;
+
+ if (lcdc_pipe->blt_addr) {
+ mdp4_overlay_lcdc_dma_busy_wait(mfd);
+
+ mdp4_lcdc_blt_ov_update(lcdc_pipe);
+ lcdc_pipe->ov_cnt++;
+
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE);
+ mdp_intr_mask |= INTR_OVERLAY0_DONE;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ mdp_enable_irq(MDP_OVERLAY0_TERM);
+ mfd->dma->busy = TRUE;
+ mb(); /* make sure all registers updated */
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ outpdw(MDP_BASE + 0x0004, 0); /* kickoff overlay engine */
+ mdp4_stat.kickoff_ov0++;
+ mb();
+ }
+}
/*
* make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile
* has enough space h * w * 3 * 2
@@ -490,6 +513,10 @@
msleep(20);
mdp4_overlayproc_cfg(lcdc_pipe);
mdp4_overlay_dmap_xy(lcdc_pipe);
+ if (lcdc_pipe->blt_addr) {
+ mdp4_overlay_lcdc_prefill(mfd);
+ mdp4_overlay_lcdc_prefill(mfd);
+ }
MDP_OUTP(MDP_BASE + LCDC_BASE, 1); /* start lcdc */
}
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 6025139..89ccbb9 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2556,6 +2556,7 @@
int ret;
struct msmfb_overlay_data req;
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+ struct msm_fb_panel_data *pdata;
if (mfd->overlay_play_enable == 0) /* nothing to do */
return 0;
@@ -2579,6 +2580,19 @@
ret = mdp4_overlay_play(info, &req);
+ if (unset_bl_level && !bl_updated) {
+ pdata = (struct msm_fb_panel_data *)mfd->pdev->
+ dev.platform_data;
+ if ((pdata) && (pdata->set_backlight)) {
+ down(&mfd->sem);
+ mfd->bl_level = unset_bl_level;
+ pdata->set_backlight(mfd);
+ bl_level_old = unset_bl_level;
+ up(&mfd->sem);
+ }
+ bl_updated = 1;
+ }
+
return ret;
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index c1941ae..7ccf4c2 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, 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
@@ -63,7 +63,7 @@
}
addr->alloc_handle = ion_alloc(
ddl_context->video_ion_client, alloc_size, SZ_4K,
- (1<<res_trk_get_mem_type()));
+ res_trk_get_mem_type());
if (IS_ERR_OR_NULL(addr->alloc_handle)) {
DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
__func__);
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 868df6f..795d1e3 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
@@ -28,6 +28,8 @@
static unsigned int vidc_clk_table[3] = {
48000000, 133330000, 200000000
};
+static unsigned int restrk_mmu_subsystem[] = {
+ MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
static struct res_trk_context resource_context;
#define VIDC_FW "vidc_1080p.fw"
@@ -49,6 +51,129 @@
static u32 res_trk_get_clk(void);
static void res_trk_put_clk(void);
+static void *res_trk_pmem_map
+ (struct ddl_buf_addr *addr, size_t sz, u32 alignment)
+{
+ u32 offset = 0, flags = 0;
+ u32 index = 0;
+ struct ddl_context *ddl_context;
+ struct msm_mapped_buffer *mapped_buffer = NULL;
+ ddl_context = ddl_get_context();
+ if (!addr->alloced_phys_addr) {
+ pr_err(" %s() alloced addres NULL", __func__);
+ goto bail_out;
+ }
+ flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR;
+ if (alignment == DDL_KILO_BYTE(128))
+ index = 1;
+ else if (alignment > SZ_4K)
+ flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K;
+
+ addr->mapped_buffer =
+ msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr,
+ sz, flags, &restrk_mmu_subsystem[index],
+ sizeof(restrk_mmu_subsystem[index])/sizeof(unsigned int));
+ if (IS_ERR(addr->mapped_buffer)) {
+ pr_err(" %s() buffer map failed", __func__);
+ goto bail_out;
+ }
+ mapped_buffer = addr->mapped_buffer;
+ if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
+ pr_err("%s() map buffers failed\n", __func__);
+ goto bail_out;
+ }
+ addr->physical_base_addr = (u8 *)mapped_buffer->iova[0];
+ addr->virtual_base_addr = mapped_buffer->vaddr;
+ addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
+ addr->physical_base_addr, alignment);
+ offset = (u32)(addr->align_physical_addr -
+ addr->physical_base_addr);
+ addr->align_virtual_addr = addr->virtual_base_addr + offset;
+ addr->buffer_size = sz;
+ return addr->virtual_base_addr;
+bail_out:
+ return NULL;
+}
+
+static void *res_trk_pmem_alloc
+ (struct ddl_buf_addr *addr, size_t sz, u32 alignment)
+{
+ u32 alloc_size;
+ struct ddl_context *ddl_context;
+ int rc = -EINVAL;
+ ion_phys_addr_t phyaddr = 0;
+ size_t len = 0;
+ DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
+ if (!addr) {
+ DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__);
+ goto bail_out;
+ }
+ ddl_context = ddl_get_context();
+ res_trk_set_mem_type(addr->mem_type);
+ alloc_size = (sz + alignment);
+ if (res_trk_get_enable_ion()) {
+ if (!ddl_context->video_ion_client)
+ ddl_context->video_ion_client =
+ res_trk_get_ion_client();
+ if (!ddl_context->video_ion_client) {
+ DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n",
+ __func__);
+ goto bail_out;
+ }
+ addr->alloc_handle = ion_alloc(
+ ddl_context->video_ion_client, alloc_size, SZ_4K,
+ res_trk_get_mem_type());
+ if (IS_ERR_OR_NULL(addr->alloc_handle)) {
+ DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
+ __func__);
+ goto bail_out;
+ }
+ rc = ion_phys(ddl_context->video_ion_client,
+ addr->alloc_handle, &phyaddr,
+ &len);
+ if (rc || !phyaddr) {
+ DDL_MSG_ERROR("%s():DDL ION client physical failed\n",
+ __func__);
+ goto free_acm_ion_alloc;
+ }
+ addr->alloced_phys_addr = phyaddr;
+ } else {
+ addr->alloced_phys_addr = (phys_addr_t)
+ allocate_contiguous_memory_nomap(alloc_size,
+ res_trk_get_mem_type(), SZ_4K);
+ if (!addr->alloced_phys_addr) {
+ DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n",
+ __func__, alloc_size);
+ goto bail_out;
+ }
+ }
+
+ addr->buffer_size = sz;
+ return (void *)addr->alloced_phys_addr;
+
+free_acm_ion_alloc:
+ if (ddl_context->video_ion_client) {
+ if (addr->alloc_handle) {
+ ion_free(ddl_context->video_ion_client,
+ addr->alloc_handle);
+ addr->alloc_handle = NULL;
+ }
+ }
+bail_out:
+ return NULL;
+}
+
+static void res_trk_pmem_unmap(struct ddl_buf_addr *addr)
+{
+ if (!addr) {
+ pr_err("%s() invalid args\n", __func__);
+ return;
+ }
+ if (addr->mapped_buffer)
+ msm_subsystem_unmap_buffer(addr->mapped_buffer);
+ addr->mapped_buffer = NULL;
+}
+
static u32 res_trk_get_clk()
{
if (resource_context.vcodec_clk ||
@@ -263,6 +388,7 @@
u32 res_trk_power_down(void)
{
VCDRES_MSG_LOW("clk_regime_rail_disable");
+ res_trk_pmem_unmap(&resource_context.firmware_addr);
#ifdef CONFIG_MSM_BUS_SCALING
msm_bus_scale_client_update_request(resource_context.pcl, 0);
msm_bus_scale_unregister_client(resource_context.pcl);
@@ -310,7 +436,6 @@
if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0)
bus_clk_index = 2;
-
bus_clk_index = (bus_clk_index << 1) + (client_type + 1);
VCDRES_MSG_LOW("%s(), bus_clk_index = %d", __func__, bus_clk_index);
VCDRES_MSG_LOW("%s(),context.pcl = %x", __func__, resource_context.pcl);
@@ -426,6 +551,7 @@
} else {
memset(&resource_context, 0, sizeof(resource_context));
mutex_init(&resource_context.lock);
+ mutex_init(&resource_context.secure_lock);
resource_context.device = device;
resource_context.irq_num = irq;
resource_context.vidc_platform_data =
@@ -446,7 +572,7 @@
return;
}
resource_context.fw_mem_type =
- resource_context.vidc_platform_data->memtype;
+ ION_MM_FIRMWARE_HEAP_ID;
resource_context.cmd_mem_type =
ION_CP_MFC_HEAP_ID;
}
@@ -465,12 +591,12 @@
}
resource_context.core_type = VCD_CORE_1080P;
resource_context.firmware_addr.mem_type = DDL_FW_MEM;
- if (!ddl_pmem_alloc(&resource_context.firmware_addr,
+ if (!res_trk_pmem_alloc(&resource_context.firmware_addr,
VIDC_FW_SIZE, DDL_KILO_BYTE(128))) {
pr_err("%s() Firmware buffer allocation failed",
__func__);
memset(&resource_context.firmware_addr, 0,
- sizeof(resource_context.firmware_addr));
+ sizeof(resource_context.firmware_addr));
}
}
}
@@ -481,27 +607,48 @@
u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr)
{
- int status = -1;
- if (resource_context.firmware_addr.mapped_buffer) {
- memcpy(firm_addr, &resource_context.firmware_addr,
- sizeof(struct ddl_buf_addr));
- status = 0;
+ if (!firm_addr || resource_context.firmware_addr.mapped_buffer) {
+ pr_err("%s() invalid params", __func__);
+ return -EINVAL;
}
- return status;
+ if (!res_trk_pmem_map(&resource_context.firmware_addr,
+ resource_context.firmware_addr.buffer_size,
+ DDL_KILO_BYTE(128))) {
+ pr_err("%s() Firmware buffer mapping failed",
+ __func__);
+ return -EINVAL;
+ }
+ memcpy(firm_addr, &resource_context.firmware_addr,
+ sizeof(struct ddl_buf_addr));
+ return 0;
}
-u32 res_trk_get_mem_type(void)
+int res_trk_get_mem_type(void)
{
+ int mem_type = -1;
switch (resource_context.res_mem_type) {
case DDL_FW_MEM:
- return resource_context.fw_mem_type;
+ mem_type = resource_context.fw_mem_type;
+ break;
case DDL_MM_MEM:
- return resource_context.memtype;
+ mem_type = resource_context.memtype;
+ break;
case DDL_CMD_MEM:
- return resource_context.memtype;
+ if (res_trk_check_for_sec_session())
+ mem_type = resource_context.cmd_mem_type;
+ else
+ mem_type = resource_context.memtype;
+ break;
default:
- return 0;
+ return mem_type;
}
+ if (resource_context.vidc_platform_data->enable_ion) {
+ if (res_trk_check_for_sec_session())
+ mem_type = (ION_HEAP(mem_type) | ION_SECURE);
+ else
+ mem_type = ION_HEAP(mem_type);
+ }
+ return mem_type;
}
u32 res_trk_get_enable_ion(void)
@@ -584,3 +731,56 @@
}
return 0;
}
+
+int res_trk_check_for_sec_session()
+{
+ int rc;
+ mutex_lock(&resource_context.secure_lock);
+ rc = (resource_context.secure_session) ? -EBUSY : 0;
+ mutex_unlock(&resource_context.secure_lock);
+ return rc;
+}
+int res_trk_open_secure_session()
+{
+ int rc;
+ mutex_lock(&resource_context.secure_lock);
+ if (resource_context.secure_session) {
+ pr_err("Secure session already open");
+ rc = -EBUSY;
+ goto error_open;
+ }
+ resource_context.secure_session = 1;
+ rc = res_trk_enable_iommu_clocks();
+ if (rc) {
+ pr_err("IOMMU clock enabled failed while open");
+ goto error_open;
+ }
+ msm_ion_secure_heap(ION_HEAP(resource_context.memtype));
+ msm_ion_secure_heap(ION_HEAP(resource_context.cmd_mem_type));
+ res_trk_disable_iommu_clocks();
+ mutex_unlock(&resource_context.secure_lock);
+ return 0;
+error_open:
+ mutex_unlock(&resource_context.secure_lock);
+ return rc;
+}
+
+int res_trk_close_secure_session()
+{
+ int rc;
+ mutex_lock(&resource_context.secure_lock);
+ rc = res_trk_enable_iommu_clocks();
+ if (rc) {
+ pr_err("IOMMU clock enabled failed while close");
+ goto error_close;
+ }
+ msm_ion_unsecure_heap(ION_HEAP(resource_context.memtype));
+ msm_ion_unsecure_heap(ION_HEAP(resource_context.cmd_mem_type));
+ res_trk_disable_iommu_clocks();
+ resource_context.secure_session = 0;
+ mutex_unlock(&resource_context.secure_lock);
+ return 0;
+error_close:
+ mutex_unlock(&resource_context.secure_lock);
+ return rc;
+}
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
index bba0868..bf8607d 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
@@ -54,6 +54,8 @@
u32 disable_fullhd;
enum ddl_mem_area res_mem_type;
u32 mmu_clks_on;
+ u32 secure_session;
+ struct mutex secure_lock;
};
#if DEBUG
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
index d5e53f5..f91ddb5 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
@@ -29,7 +29,7 @@
u32 res_trk_download_firmware(void);
u32 res_trk_get_core_type(void);
u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr);
-u32 res_trk_get_mem_type(void);
+int res_trk_get_mem_type(void);
u32 res_trk_get_enable_ion(void);
u32 res_trk_get_disable_fullhd(void);
struct ion_client *res_trk_get_ion_client(void);
@@ -37,4 +37,7 @@
void res_trk_set_mem_type(enum ddl_mem_area mem_type);
int res_trk_enable_iommu_clocks(void);
int res_trk_disable_iommu_clocks(void);
+int res_trk_check_for_sec_session(void);
+int res_trk_open_secure_session(void);
+int res_trk_close_secure_session(void);
#endif
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
index ee76ff1..7c3325a 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
@@ -728,3 +728,18 @@
{
return 0;
}
+
+int res_trk_check_for_sec_session()
+{
+ return 0;
+}
+
+int res_trk_open_secure_session()
+{
+ return -EINVAL;
+}
+
+int res_trk_close_secure_session()
+{
+ return 0;
+}
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
index 3012858..2b92a42 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -35,6 +35,7 @@
struct msm_vidc_platform_data *vidc_platform_data;
u32 core_type;
int memtype;
+ u32 secure_session;
};
#if DEBUG
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
index 34f2103..237d143 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
@@ -32,4 +32,7 @@
u32 res_trk_get_enable_ion(void);
struct ion_client *res_trk_get_ion_client(void);
void res_trk_set_mem_type(enum ddl_mem_area mem_type);
+int res_trk_check_for_sec_session(void);
+int res_trk_open_secure_session(void);
+int res_trk_close_secure_session(void);
#endif
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index b90248e..980ec21 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.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
@@ -29,6 +29,7 @@
#include <linux/clk.h>
#include <linux/timer.h>
#include <mach/msm_subsystem_map.h>
+#include "vcd_res_tracker_api.h"
#include "vidc_type.h"
#include "vcd_api.h"
#include "vdec_internal.h"
@@ -40,11 +41,13 @@
#define INFO(x...) pr_info(x)
#define ERR(x...) pr_err(x)
-#define VID_DEC_NAME "msm_vidc_dec"
+#define VID_DEC_NAME "msm_vidc_dec"
+static char *node_name[2] = {"", "_sec"};
static struct vid_dec_dev *vid_dec_device_p;
static dev_t vid_dec_dev_num;
static struct class *vid_dec_class;
+
static unsigned int vidc_mmu_subsystem[] = {
MSM_SUBSYSTEM_VIDEO};
static s32 vid_dec_get_empty_client_index(void)
@@ -1958,34 +1961,30 @@
return true;
}
-static int vid_dec_open(struct inode *inode, struct file *file)
+struct video_client_ctx *vid_dec_open_client(void)
{
s32 client_index;
struct video_client_ctx *client_ctx;
u32 vcd_status = VCD_ERR_FAIL;
- u8 client_count = 0;
-
- DBG("msm_vidc_dec: Inside %s()", __func__);
- mutex_lock(&vid_dec_device_p->lock);
+ u8 client_count;
client_count = vcd_get_num_of_clients();
if (client_count == VIDC_MAX_NUM_CLIENTS) {
ERR("ERROR : vid_dec_open() max number of clients"
- "limit reached\n");
- mutex_unlock(&vid_dec_device_p->lock);
- return -ENODEV;
+ "limit reached\n");
+ goto client_failure;
}
DBG(" Virtual Address of ioremap is %p\n", vid_dec_device_p->virt_base);
if (!vid_dec_device_p->num_clients) {
if (!vidc_load_firmware())
- return -ENODEV;
+ goto client_failure;
}
client_index = vid_dec_get_empty_client_index();
if (client_index == -1) {
ERR("%s() : No free clients client_index == -1\n", __func__);
- return -ENODEV;
+ goto client_failure;
}
client_ctx = &vid_dec_device_p->vdec_clients[client_index];
vid_dec_device_p->num_clients++;
@@ -2002,30 +2001,84 @@
client_ctx->user_ion_client = vcd_get_ion_client();
if (!client_ctx->user_ion_client) {
ERR("vcd_open ion client get failed");
- return -EFAULT;
+ goto client_failure;
}
}
vcd_status = vcd_open(vid_dec_device_p->device_handle, true,
- vid_dec_vcd_cb, client_ctx);
+ vid_dec_vcd_cb, client_ctx);
if (!vcd_status) {
wait_for_completion(&client_ctx->event);
if (client_ctx->event_status) {
ERR("callback for vcd_open returned error: %u",
client_ctx->event_status);
- mutex_unlock(&vid_dec_device_p->lock);
- return -EFAULT;
+ goto client_failure;
}
} else {
ERR("vcd_open returned error: %u", vcd_status);
- mutex_unlock(&vid_dec_device_p->lock);
- return -EFAULT;
+ goto client_failure;
}
client_ctx->seq_header_set = false;
- file->private_data = client_ctx;
+ return client_ctx;
+client_failure:
+ return NULL;
+}
+
+static int vid_dec_open_secure(struct inode *inode, struct file *file)
+{
+ mutex_lock(&vid_dec_device_p->lock);
+ if (res_trk_check_for_sec_session() || vcd_get_num_of_clients()) {
+ ERR("Secure session present return failure\n");
+ mutex_unlock(&vid_dec_device_p->lock);
+ return -ENODEV;
+ }
+ if (res_trk_open_secure_session()) {
+ ERR("Secure session operation failure\n");
+ mutex_unlock(&vid_dec_device_p->lock);
+ return -ENODEV;
+ }
+ file->private_data = vid_dec_open_client();
+ if (!file->private_data) {
+ res_trk_close_secure_session();
+ mutex_unlock(&vid_dec_device_p->lock);
+ return -ENODEV;
+ }
mutex_unlock(&vid_dec_device_p->lock);
return 0;
}
+static int vid_dec_open(struct inode *inode, struct file *file)
+{
+ INFO("msm_vidc_dec: Inside %s()", __func__);
+ mutex_lock(&vid_dec_device_p->lock);
+ if (res_trk_check_for_sec_session()) {
+ ERR("Secure session present return failure\n");
+ mutex_unlock(&vid_dec_device_p->lock);
+ return -ENODEV;
+ }
+ file->private_data = vid_dec_open_client();
+ if (!file->private_data) {
+ mutex_unlock(&vid_dec_device_p->lock);
+ return -ENODEV;
+ }
+ mutex_unlock(&vid_dec_device_p->lock);
+ return 0;
+}
+
+static int vid_dec_release_secure(struct inode *inode, struct file *file)
+{
+ struct video_client_ctx *client_ctx = file->private_data;
+
+ INFO("msm_vidc_dec: Inside %s()", __func__);
+ res_trk_close_secure_session();
+ vid_dec_close_client(client_ctx);
+ vidc_release_firmware();
+#ifndef USE_RES_TRACKER
+ vidc_disable_clk();
+#endif
+ INFO("msm_vidc_dec: Return from %s()", __func__);
+ return 0;
+}
+
static int vid_dec_release(struct inode *inode, struct file *file)
{
struct video_client_ctx *client_ctx = file->private_data;
@@ -2040,11 +2093,20 @@
return 0;
}
-static const struct file_operations vid_dec_fops = {
- .owner = THIS_MODULE,
- .open = vid_dec_open,
- .release = vid_dec_release,
- .unlocked_ioctl = vid_dec_ioctl,
+static const struct file_operations vid_dec_fops[2] = {
+ {
+ .owner = THIS_MODULE,
+ .open = vid_dec_open,
+ .release = vid_dec_release,
+ .unlocked_ioctl = vid_dec_ioctl,
+ },
+ {
+ .owner = THIS_MODULE,
+ .open = vid_dec_open_secure,
+ .release = vid_dec_release_secure,
+ .unlocked_ioctl = vid_dec_ioctl,
+ },
+
};
void vid_dec_interrupt_deregister(void)
@@ -2110,7 +2172,7 @@
static int __init vid_dec_init(void)
{
- int rc = 0;
+ int rc = 0, i = 0, j = 0;
struct device *class_devp;
DBG("msm_vidc_dec: Inside %s()", __func__);
@@ -2121,7 +2183,8 @@
return -ENOMEM;
}
- rc = alloc_chrdev_region(&vid_dec_dev_num, 0, 1, VID_DEC_NAME);
+ rc = alloc_chrdev_region(&vid_dec_dev_num, 0, NUM_OF_DRIVER_NODES,
+ VID_DEC_NAME);
if (rc < 0) {
ERR("%s: alloc_chrdev_region Failed rc = %d\n",
__func__, rc);
@@ -2136,49 +2199,59 @@
goto error_vid_dec_class_create;
}
+ for (i = 0; i < NUM_OF_DRIVER_NODES; i++) {
+ class_devp = device_create(vid_dec_class, NULL,
+ (vid_dec_dev_num + i),
+ NULL, VID_DEC_NAME "%s",
+ node_name[i]);
- class_devp = device_create(vid_dec_class, NULL, vid_dec_dev_num, NULL,
- VID_DEC_NAME);
+ if (IS_ERR(class_devp)) {
+ rc = PTR_ERR(class_devp);
+ ERR("%s: class device_create failed %d\n",
+ __func__, rc);
+ if (!i)
+ goto error_vid_dec_class_device_create;
+ else
+ goto error_vid_dec_cdev_add;
+ }
- if (IS_ERR(class_devp)) {
- rc = PTR_ERR(class_devp);
- ERR("%s: class device_create failed %d\n",
- __func__, rc);
- goto error_vid_dec_class_device_create;
- }
+ vid_dec_device_p->device[i] = class_devp;
- vid_dec_device_p->device = class_devp;
+ cdev_init(&vid_dec_device_p->cdev[i], &vid_dec_fops[i]);
+ vid_dec_device_p->cdev[i].owner = THIS_MODULE;
+ rc = cdev_add(&(vid_dec_device_p->cdev[i]),
+ (vid_dec_dev_num+i), 1);
- cdev_init(&vid_dec_device_p->cdev, &vid_dec_fops);
- vid_dec_device_p->cdev.owner = THIS_MODULE;
- rc = cdev_add(&(vid_dec_device_p->cdev), vid_dec_dev_num, 1);
-
- if (rc < 0) {
- ERR("%s: cdev_add failed %d\n", __func__, rc);
- goto error_vid_dec_cdev_add;
+ if (rc < 0) {
+ ERR("%s: cdev_add failed %d\n", __func__, rc);
+ goto error_vid_dec_cdev_add;
+ }
}
vid_dec_vcd_init();
return 0;
error_vid_dec_cdev_add:
+ for (j = i-1; j >= 0; j--)
+ cdev_del(&(vid_dec_device_p->cdev[j]));
device_destroy(vid_dec_class, vid_dec_dev_num);
error_vid_dec_class_device_create:
class_destroy(vid_dec_class);
error_vid_dec_class_create:
- unregister_chrdev_region(vid_dec_dev_num, 1);
+ unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
error_vid_dec_alloc_chrdev_region:
kfree(vid_dec_device_p);
-
return rc;
}
static void __exit vid_dec_exit(void)
{
- DBG("msm_vidc_dec: Inside %s()", __func__);
- cdev_del(&(vid_dec_device_p->cdev));
+ int i = 0;
+ INFO("msm_vidc_dec: Inside %s()", __func__);
+ for (i = 0; i < NUM_OF_DRIVER_NODES; i++)
+ cdev_del(&(vid_dec_device_p->cdev[i]));
device_destroy(vid_dec_class, vid_dec_dev_num);
class_destroy(vid_dec_class);
- unregister_chrdev_region(vid_dec_dev_num, 1);
+ unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
kfree(vid_dec_device_p);
DBG("msm_vidc_dec: Return from %s()", __func__);
}
diff --git a/drivers/video/msm/vidc/common/dec/vdec_internal.h b/drivers/video/msm/vidc/common/dec/vdec_internal.h
index 867c3b3..f310e25 100644
--- a/drivers/video/msm/vidc/common/dec/vdec_internal.h
+++ b/drivers/video/msm/vidc/common/dec/vdec_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 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,14 +18,16 @@
#include <linux/cdev.h>
#include "vidc_init.h"
+#define NUM_OF_DRIVER_NODES 2
+
struct vid_dec_msg {
struct list_head list;
struct vdec_msginfo vdec_msg_info;
};
struct vid_dec_dev {
- struct cdev cdev;
- struct device *device;
+ struct cdev cdev[NUM_OF_DRIVER_NODES];
+ struct device *device[NUM_OF_DRIVER_NODES];
resource_size_t phys_base;
void __iomem *virt_base;
unsigned int irq;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 3cd4e76..97fc758 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.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
@@ -32,6 +32,7 @@
#include "vcd_api.h"
#include "venc_internal.h"
#include "vidc_init.h"
+#include "vcd_res_tracker_api.h"
#define VID_ENC_NAME "msm_vidc_enc"
@@ -516,9 +517,10 @@
stop_cmd = 0;
client_count = vcd_get_num_of_clients();
- if (client_count == VIDC_MAX_NUM_CLIENTS) {
+ if (client_count == VIDC_MAX_NUM_CLIENTS ||
+ res_trk_check_for_sec_session()) {
ERR("ERROR : vid_enc_open() max number of clients"
- "limit reached\n");
+ "limit reached or secure session is open\n");
mutex_unlock(&vid_enc_device_p->lock);
return -ENODEV;
}
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index e4bd50d..1709cc2 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.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
@@ -502,7 +502,7 @@
} else {
buff_ion_handle = ion_import_fd(
client_ctx->user_ion_client, pmem_fd);
- if (!buff_ion_handle) {
+ if (IS_ERR_OR_NULL(buff_ion_handle)) {
ERR("%s(): get_ION_handle failed\n",
__func__);
goto ion_error;
@@ -558,7 +558,7 @@
ion_error:
if (*kernel_vaddr)
ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle);
- if (buff_ion_handle)
+ if (!IS_ERR_OR_NULL(buff_ion_handle))
ion_free(client_ctx->user_ion_client, buff_ion_handle);
bail_out_add:
mutex_unlock(&client_ctx->enrty_queue_lock);
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.c b/drivers/video/msm/vidc/common/vcd/vcd_api.c
index 4889761..5e9fd55 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_api.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.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
@@ -89,7 +89,10 @@
return VCD_ERR_ILLEGAL_PARM;
}
-
+ if (res_trk_check_for_sec_session() && vcd_get_num_of_clients()) {
+ VCD_MSG_ERROR("Secure session in progress");
+ return VCD_ERR_BAD_STATE;
+ }
drv_ctxt = vcd_get_drv_context();
mutex_lock(&drv_ctxt->dev_mutex);
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index bb3e652..b5fcc1c 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -69,7 +69,7 @@
} else {
map_buffer->alloc_handle = ion_alloc(
cctxt->vcd_ion_client, sz, SZ_4K,
- (1<<memtype));
+ memtype);
if (!map_buffer->alloc_handle) {
pr_err("%s() ION alloc failed", __func__);
goto bailout;
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index d61b934..9aa557a 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 2010 Samsung Electronics Co.Ltd
* Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * 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 as published by the
@@ -26,6 +26,9 @@
#define MXT_ROTATED_180 0x6
#define MXT_DIAGONAL_COUNTER 0x7
+/* MXT_TOUCH_KEYARRAY_T15 */
+#define MXT_KEYARRAY_MAX_KEYS 32
+
/* The platform data for the Atmel maXTouch touchscreen driver */
struct mxt_platform_data {
const u8 *config;
@@ -38,6 +41,7 @@
bool digital_pwr_regulator;
int reset_gpio;
int irq_gpio;
+ int *key_codes;
u8(*read_chg) (void);
int (*init_hw) (bool);
diff --git a/include/linux/ion.h b/include/linux/ion.h
index f46d478..41f99e4 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -70,6 +70,7 @@
ION_CP_WB_HEAP_ID = 16, /* 8660 only */
ION_CAMERA_HEAP_ID = 20, /* 8660 only */
ION_SF_HEAP_ID = 24,
+ ION_QSECOM_HEAP_ID = 27,
ION_AUDIO_HEAP_ID = 28,
ION_MM_FIRMWARE_HEAP_ID = 29,
@@ -97,6 +98,7 @@
#define ION_MFC_HEAP_NAME "mfc"
#define ION_WB_HEAP_NAME "wb"
#define ION_MM_FIRMWARE_HEAP_NAME "mm_fw"
+#define ION_QSECOM_HEAP_NAME "qsecom"
#define CACHED 1
#define UNCACHED 0
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index cd2e61c..d0307ee 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -33,6 +33,8 @@
u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
};
+typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
+
/*
* Workarounds only applied to 32bit powermac machines
*/
@@ -73,6 +75,7 @@
struct resource *res, int nr_irqs);
extern struct device_node *of_irq_find_parent(struct device_node *child);
+extern void of_irq_init(const struct of_device_id *matches);
#endif /* CONFIG_OF_IRQ */
#endif /* CONFIG_OF */
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index fb5d4e4..f46449a 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -135,6 +135,8 @@
/* regulator get and put */
struct regulator *__must_check regulator_get(struct device *dev,
const char *id);
+struct regulator *__must_check devm_regulator_get(struct device *dev,
+ const char *id);
struct regulator *__must_check regulator_get_exclusive(struct device *dev,
const char *id);
void regulator_put(struct regulator *regulator);
@@ -202,6 +204,13 @@
*/
return NULL;
}
+
+static inline struct regulator *__must_check
+devm_regulator_get(struct device *dev, const char *id)
+{
+ return NULL;
+}
+
static inline void regulator_put(struct regulator *regulator)
{
}
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 9373064..e03944d 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -160,6 +160,9 @@
* @disable_reset_on_disconnect: perform USB PHY and LINK reset
* on USB cable disconnection.
* @swfi_latency: miminum latency to allow swfi.
+ * @enable_dcd: Enable Data Contact Detection circuit. if not set
+ * wait for 600msec before proceeding to primary
+ * detection.
*/
struct msm_otg_platform_data {
int *phy_init_seq;
@@ -174,6 +177,7 @@
bool mhl_enable;
bool disable_reset_on_disconnect;
u32 swfi_latency;
+ bool enable_dcd;
};
/**
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 423a849..a984943 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -396,11 +396,11 @@
#define CMD_AXI_CFG_ZSL 43
#define CMD_AXI_CFG_SNAP_VPE 44
#define CMD_AXI_CFG_SNAP_THUMB_VPE 45
-#define CMD_AXI_CFG_VIDEO_ALL_CHNLS 46
-#define CMD_AXI_CFG_ZSL_ALL_CHNLS 47
-#define CMD_CONFIG_PING_ADDR 48
-#define CMD_CONFIG_PONG_ADDR 49
-#define CMD_CONFIG_FREE_BUF_ADDR 50
+#define CMD_CONFIG_PING_ADDR 46
+#define CMD_CONFIG_PONG_ADDR 47
+#define CMD_CONFIG_FREE_BUF_ADDR 48
+#define CMD_AXI_CFG_ZSL_ALL_CHNLS 49
+#define CMD_AXI_CFG_VIDEO_ALL_CHNLS 50
/* vfe config command: config command(from config thread)*/
struct msm_vfe_cfg_cmd {
@@ -467,6 +467,9 @@
uint32_t len;
uint32_t y_off;
uint32_t cbcr_off;
+ uint32_t planar0_off;
+ uint32_t planar1_off;
+ uint32_t planar2_off;
uint8_t active;
};
@@ -487,8 +490,9 @@
#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
#define OUTPUT_1_2_AND_3 7
#define OUTPUT_ALL_CHNLS 8
-#define OUTPUT_ZSL_ALL_CHNLS 9
-#define LAST_AXI_OUTPUT_MODE_ENUM OUTPUT_ZSL_ALL_CHNLS
+#define OUTPUT_VIDEO_ALL_CHNLS 9
+#define OUTPUT_ZSL_ALL_CHNLS 10
+#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_ZSL_ALL_CHNLS
#define MSM_FRAME_PREV_1 0
#define MSM_FRAME_PREV_2 1
@@ -528,6 +532,9 @@
uint32_t phy_offset;
uint32_t y_off;
uint32_t cbcr_off;
+ uint32_t planar0_off;
+ uint32_t planar1_off;
+ uint32_t planar2_off;
int fd;
void *cropinfo;
@@ -557,10 +564,10 @@
};
struct msm_st_half {
- uint32_t buf_y_off;
- uint32_t buf_cbcr_off;
- uint32_t buf_y_stride;
- uint32_t buf_cbcr_stride;
+ uint32_t buf_p0_off;
+ uint32_t buf_p1_off;
+ uint32_t buf_p0_stride;
+ uint32_t buf_p1_stride;
uint32_t pix_x_off;
uint32_t pix_y_off;
struct msm_st_crop stCropInfo;
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 30536a2..312de3f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -294,8 +294,6 @@
struct l2cap_conf_prm {
__u8 fcs;
- __le16 retrans_timeout;
- __le16 monitor_timeout;
__le32 flush_to;
};
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index cf6cf59..ded74dc 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3212,6 +3212,44 @@
return chan;
}
+static void l2cap_get_ertm_timeouts(struct l2cap_conf_rfc *rfc,
+ struct l2cap_pinfo *pi)
+{
+ if (pi->amp_id && pi->ampcon) {
+ u64 ertm_to = pi->ampcon->hdev->amp_be_flush_to;
+
+ /* Class 1 devices have must have ERTM timeouts
+ * exceeding the Link Supervision Timeout. The
+ * default Link Supervision Timeout for AMP
+ * controllers is 10 seconds.
+ *
+ * Class 1 devices use 0xffffffff for their
+ * best-effort flush timeout, so the clamping logic
+ * will result in a timeout that meets the above
+ * requirement. ERTM timeouts are 16-bit values, so
+ * the maximum timeout is 65.535 seconds.
+ */
+
+ /* Convert timeout to milliseconds and round */
+ ertm_to = div_u64(ertm_to + 999, 1000);
+
+ /* This is the recommended formula for class 2 devices
+ * that start ERTM timers when packets are sent to the
+ * controller.
+ */
+ ertm_to = 3 * ertm_to + 500;
+
+ if (ertm_to > 0xffff)
+ ertm_to = 0xffff;
+
+ rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
+ rfc->monitor_timeout = rfc->retrans_timeout;
+ } else {
+ rfc->retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
+ rfc->monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+ }
+}
+
int l2cap_build_conf_req(struct sock *sk, void *data)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
@@ -3262,10 +3300,10 @@
rfc.txwin_size = L2CAP_TX_WIN_MAX_ENHANCED;
else
rfc.txwin_size = pi->tx_win;
- rfc.max_transmit = pi->max_tx;
- rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
- rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
- rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+ rfc.max_transmit = pi->max_tx;
+ rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+ l2cap_get_ertm_timeouts(&rfc, pi);
+
if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->imtu)
rfc.max_pdu_size = cpu_to_le16(pi->imtu);
@@ -3337,30 +3375,16 @@
struct l2cap_conf_req *req = data;
struct l2cap_conf_rfc rfc = { .mode = pi->mode };
void *ptr = req->data;
- u32 be_flush_to;
BT_DBG("sk %p", sk);
- /* convert to milliseconds, round up */
- be_flush_to = (pi->conn->hcon->hdev->amp_be_flush_to + 999) / 1000;
-
switch (pi->mode) {
case L2CAP_MODE_ERTM:
rfc.mode = L2CAP_MODE_ERTM;
rfc.txwin_size = pi->tx_win;
rfc.max_transmit = pi->max_tx;
- if (pi->amp_move_id) {
- rfc.retrans_timeout =
- cpu_to_le16((3 * be_flush_to) + 500);
- rfc.monitor_timeout =
- cpu_to_le16((3 * be_flush_to) + 500);
- } else {
- rfc.retrans_timeout =
- cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
- rfc.monitor_timeout =
- cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
- }
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+ l2cap_get_ertm_timeouts(&rfc, pi);
if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->imtu)
rfc.max_pdu_size = cpu_to_le16(pi->imtu);
@@ -3374,17 +3398,16 @@
(unsigned long) &rfc);
if (pi->conn->feat_mask & L2CAP_FEAT_FCS) {
-
/* TODO assign fcs for br/edr based on socket config option */
- if (pi->amp_move_id)
+ /* FCS is not used with AMP because it is redundant - lower
+ * layers already include a checksum. */
+ if (pi->amp_id)
pi->local_conf.fcs = L2CAP_FCS_NONE;
else
pi->local_conf.fcs = L2CAP_FCS_CRC16;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
- pi->local_conf.fcs);
-
- pi->fcs = pi->local_conf.fcs | pi->remote_conf.fcs;
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->local_conf.fcs);
+ pi->fcs = pi->local_conf.fcs | pi->remote_conf.fcs;
}
req->dcid = cpu_to_le16(pi->dcid);
@@ -3546,15 +3569,9 @@
case L2CAP_MODE_ERTM:
if (!(pi->conf_state & L2CAP_CONF_EXT_WIN_RECV))
pi->remote_tx_win = rfc.txwin_size;
-
pi->remote_max_tx = rfc.max_transmit;
-
pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
-
- rfc.retrans_timeout =
- cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
- rfc.monitor_timeout =
- cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+ l2cap_get_ertm_timeouts(&rfc, pi);
pi->conf_state |= L2CAP_CONF_MODE_DONE;
@@ -3660,9 +3677,6 @@
case L2CAP_CONF_RFC:
if (olen == sizeof(rfc))
memcpy(&rfc, (void *) val, olen);
- if (pi->mode != rfc.mode ||
- rfc.mode == L2CAP_MODE_BASIC)
- result = L2CAP_CONF_UNACCEPT;
break;
case L2CAP_CONF_FCS:
@@ -3698,6 +3712,9 @@
BT_DBG("result 0x%2.2x cur mode 0x%2.2x req mode 0x%2.2x",
result, pi->mode, rfc.mode);
+ if (pi->mode != rfc.mode || rfc.mode == L2CAP_MODE_BASIC)
+ result = L2CAP_CONF_UNACCEPT;
+
if (result == L2CAP_CONF_SUCCESS) {
/* Configure output options and let the other side know
* which ones we don't like. */
@@ -3717,38 +3734,26 @@
pi->remote_tx_win);
}
+ pi->remote_mps = rfc.max_pdu_size;
+
if (rfc.mode == L2CAP_MODE_ERTM) {
- pi->remote_conf.retrans_timeout =
- le16_to_cpu(rfc.retrans_timeout);
- pi->remote_conf.monitor_timeout =
- le16_to_cpu(rfc.monitor_timeout);
-
- BT_DBG("remote conf monitor timeout %d",
- pi->remote_conf.monitor_timeout);
-
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
- sizeof(rfc), (unsigned long) &rfc);
+ l2cap_get_ertm_timeouts(&rfc, pi);
+ } else {
+ rfc.retrans_timeout = 0;
+ rfc.monitor_timeout = 0;
}
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+ sizeof(rfc), (unsigned long) &rfc);
}
if (result != L2CAP_CONF_SUCCESS)
goto done;
- pi->fcs = pi->remote_conf.fcs | pi->local_conf.fcs ;
+ pi->fcs = pi->remote_conf.fcs | pi->local_conf.fcs;
- if (pi->rx_state == L2CAP_ERTM_RX_STATE_WAIT_F_FLAG) {
+ if (pi->rx_state == L2CAP_ERTM_RX_STATE_WAIT_F_FLAG)
pi->flush_to = pi->remote_conf.flush_to;
- pi->retrans_timeout = pi->remote_conf.retrans_timeout;
-
- if (pi->amp_move_id)
- pi->monitor_timeout = pi->remote_conf.monitor_timeout;
- else
- pi->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
- BT_DBG("mode %d monitor timeout %d",
- pi->mode, pi->monitor_timeout);
-
- }
done:
rsp->scid = cpu_to_le16(pi->dcid);
@@ -3972,34 +3977,41 @@
if (type == L2CAP_CONF_RFC) {
if (olen == sizeof(rfc))
memcpy(&rfc, (void *)val, olen);
- if (rfc.mode != pi->mode &&
- rfc.mode != L2CAP_MODE_ERTM) {
- err = -ECONNREFUSED;
- goto done;
+
+ if (rfc.mode != pi->mode) {
+ l2cap_send_disconn_req(pi->conn, sk,
+ ECONNRESET);
+ return -ECONNRESET;
}
- break;
+
+ goto done;
}
}
}
+ BT_ERR("Expected RFC option was missing, using existing values");
+
+ rfc.mode = pi->mode;
+ rfc.retrans_timeout = cpu_to_le16(pi->retrans_timeout);
+ rfc.monitor_timeout = cpu_to_le16(pi->monitor_timeout);
+
done:
l2cap_ertm_stop_ack_timer(pi);
l2cap_ertm_stop_retrans_timer(pi);
l2cap_ertm_stop_monitor_timer(pi);
+ pi->mps = le16_to_cpu(rfc.max_pdu_size);
+ if (pi->mode == L2CAP_MODE_ERTM) {
+ pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+ pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
+ }
+
if (l2cap_pi(sk)->reconf_state == L2CAP_RECONF_ACC) {
l2cap_pi(sk)->reconf_state = L2CAP_RECONF_NONE;
/* Respond to poll */
err = l2cap_answer_move_poll(sk);
-
} else if (l2cap_pi(sk)->reconf_state == L2CAP_RECONF_INT) {
-
- /* If moving to BR/EDR, use default timeout defined by
- * the spec */
- if (pi->amp_move_id == 0)
- pi->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
-
if (pi->mode == L2CAP_MODE_ERTM) {
l2cap_ertm_tx(sk, NULL, NULL,
L2CAP_ERTM_EVENT_EXPLICIT_POLL);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 93e7b04..94cacde 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1,6 +1,6 @@
/*
BlueZ - Bluetooth protocol stack for Linux
- Copyright (C) 2000-2001 Qualcomm Incorporated
+ Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum. All rights reserved.
Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Copyright (C) 2010 Google Inc.
@@ -1123,8 +1123,6 @@
static void set_default_config(struct l2cap_conf_prm *conf_prm)
{
conf_prm->fcs = L2CAP_FCS_CRC16;
- conf_prm->retrans_timeout = 0;
- conf_prm->monitor_timeout = 0;
conf_prm->flush_to = L2CAP_DEFAULT_FLUSH_TO;
}
@@ -1186,14 +1184,6 @@
pi->extended_control = 0;
pi->local_conf.fcs = pi->fcs;
- if (pi->mode == L2CAP_MODE_BASIC) {
- pi->local_conf.retrans_timeout = 0;
- pi->local_conf.monitor_timeout = 0;
- } else {
- pi->local_conf.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
- pi->local_conf.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
- }
-
pi->local_conf.flush_to = pi->flush_to;
set_default_config(&pi->remote_conf);
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 472fcae..cec01f1 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -41,6 +41,8 @@
#define TABLA_TX_DAI_ID 2
#define TABLA_CFILT_FAST_MODE 0x00
#define TABLA_CFILT_SLOW_MODE 0x40
+#define MBHC_FW_READ_ATTEMPTS 15
+#define MBHC_FW_READ_TIMEOUT 2000000
#define TABLA_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR)
@@ -104,6 +106,7 @@
u16 dce_mb;
u16 sta_z;
u16 sta_mb;
+ u32 t_sta_dce;
u32 t_dce;
u32 t_sta;
u32 micb_mv;
@@ -186,6 +189,10 @@
/* Callback function to enable MCLK */
int (*mclk_cb) (struct snd_soc_codec*, int);
+
+ /* Work to perform MBHC Firmware Read */
+ struct delayed_work mbhc_firmware_dwork;
+ const struct firmware *mbhc_fw;
};
#ifdef CONFIG_DEBUG_FS
@@ -3075,6 +3082,8 @@
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x4);
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x0);
+ usleep_range(tabla->mbhc_data.t_sta_dce,
+ tabla->mbhc_data.t_sta_dce);
snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x4);
usleep_range(tabla->mbhc_data.t_dce,
tabla->mbhc_data.t_dce);
@@ -3083,7 +3092,8 @@
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x2);
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x0);
- usleep_range(50, 50);
+ usleep_range(tabla->mbhc_data.t_sta_dce,
+ tabla->mbhc_data.t_sta_dce);
snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x2);
usleep_range(tabla->mbhc_data.t_sta,
tabla->mbhc_data.t_sta);
@@ -3380,19 +3390,8 @@
nmeas = TABLA_MBHC_CAL_BTN_DET_PTR(tabla->calibration)->n_meas;
navg = TABLA_MBHC_CAL_GENERAL_PTR(tabla->calibration)->mbhc_navg;
mclk_rate = tabla->mclk_freq;
- dce_wait = (1000 * 512 * ncic * nmeas) / (mclk_rate / 1000);
- if (tabla->mclk_freq == TABLA_MCLK_RATE_12288KHZ)
- dce_wait = dce_wait + 10000;
- else if (tabla->mclk_freq == TABLA_MCLK_RATE_9600KHZ)
- dce_wait = dce_wait + 9810;
- else
- WARN(1, "Unsupported mclk freq %d\n", tabla->mclk_freq);
-
- sta_wait = (1000 * 128 * navg) / (mclk_rate / 1000);
-
- /* Add 10 microseconds to handle error margin */
- dce_wait = dce_wait + 10;
- sta_wait = sta_wait + 10;
+ dce_wait = (1000 * 512 * ncic * (nmeas + 1)) / (mclk_rate / 1000);
+ sta_wait = (1000 * 128 * (navg + 1)) / (mclk_rate / 1000);
tabla->mbhc_data.t_dce = dce_wait;
tabla->mbhc_data.t_sta = sta_wait;
@@ -3509,8 +3508,11 @@
tabla->mbhc_data.nready = 2;
tabla->mbhc_data.npoll = 7;
tabla->mbhc_data.nbounce_wait = 23;
- }
+ } else
+ WARN(1, "Unsupported mclk freq %d\n", tabla->mclk_freq);
+ tabla->mbhc_data.t_sta_dce = ((1000 * 256) / (tabla->mclk_freq / 1000) *
+ tabla->mbhc_data.nready) + 10;
tabla->mbhc_data.v_ins_hu =
tabla_codec_v_sta_dce(codec, STA, plug_type->v_hs_max);
tabla->mbhc_data.v_ins_h =
@@ -3592,6 +3594,91 @@
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_B1_CTL, 0x02, 0x02);
}
+static bool tabla_mbhc_fw_validate(const struct firmware *fw)
+{
+ u32 cfg_offset;
+ struct tabla_mbhc_imped_detect_cfg *imped_cfg;
+ struct tabla_mbhc_btn_detect_cfg *btn_cfg;
+
+ if (fw->size < TABLA_MBHC_CAL_MIN_SIZE)
+ return false;
+
+ /* previous check guarantees that there is enough fw data up
+ * to num_btn
+ */
+ btn_cfg = TABLA_MBHC_CAL_BTN_DET_PTR(fw->data);
+ cfg_offset = (u32) ((void *) btn_cfg - (void *) fw->data);
+ if (fw->size < (cfg_offset + TABLA_MBHC_CAL_BTN_SZ(btn_cfg)))
+ return false;
+
+ /* previous check guarantees that there is enough fw data up
+ * to start of impedance detection configuration
+ */
+ imped_cfg = TABLA_MBHC_CAL_IMPED_DET_PTR(fw->data);
+ cfg_offset = (u32) ((void *) imped_cfg - (void *) fw->data);
+
+ if (fw->size < (cfg_offset + TABLA_MBHC_CAL_IMPED_MIN_SZ))
+ return false;
+
+ if (fw->size < (cfg_offset + TABLA_MBHC_CAL_IMPED_SZ(imped_cfg)))
+ return false;
+
+ return true;
+}
+static void mbhc_fw_read(struct work_struct *work)
+{
+ struct delayed_work *dwork;
+ struct tabla_priv *tabla;
+ struct snd_soc_codec *codec;
+ const struct firmware *fw;
+ int ret = -1, retry = 0, rc;
+
+ dwork = to_delayed_work(work);
+ tabla = container_of(dwork, struct tabla_priv,
+ mbhc_firmware_dwork);
+ codec = tabla->codec;
+
+ while (retry < MBHC_FW_READ_ATTEMPTS) {
+ retry++;
+ pr_info("%s:Attempt %d to request MBHC firmware\n",
+ __func__, retry);
+ ret = request_firmware(&fw, "wcd9310/wcd9310_mbhc.bin",
+ codec->dev);
+
+ if (ret != 0) {
+ usleep_range(MBHC_FW_READ_TIMEOUT,
+ MBHC_FW_READ_TIMEOUT);
+ } else {
+ pr_info("%s: MBHC Firmware read succesful\n", __func__);
+ break;
+ }
+ }
+
+ if (ret != 0) {
+ pr_err("%s: Cannot load MBHC firmware use default cal\n",
+ __func__);
+ } else if (tabla_mbhc_fw_validate(fw) == false) {
+ pr_err("%s: Invalid MBHC cal data size use default cal\n",
+ __func__);
+ release_firmware(fw);
+ } else {
+ tabla->calibration = (void *)fw->data;
+ tabla->mbhc_fw = fw;
+ }
+
+ tabla->mclk_cb(codec, 1);
+ tabla_mbhc_init(codec);
+ tabla_mbhc_cal(codec);
+ tabla_mbhc_calc_thres(codec);
+ tabla->mclk_cb(codec, 0);
+ tabla_codec_calibrate_hs_polling(codec);
+ rc = tabla_codec_enable_hs_detect(codec, 1);
+
+ if (IS_ERR_VALUE(rc))
+ pr_err("%s: Failed to setup MBHC detection\n", __func__);
+
+}
+
int tabla_hs_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *headset_jack,
struct snd_soc_jack *button_jack,
@@ -3600,7 +3687,7 @@
int read_fw_bin, u32 mclk_rate)
{
struct tabla_priv *tabla;
- int rc;
+ int rc = 0;
if (!codec || !calibration) {
pr_err("Error: no codec or calibration\n");
@@ -3618,7 +3705,7 @@
/* Put CFILT in fast mode by default */
snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
0x40, TABLA_CFILT_FAST_MODE);
-
+ INIT_DELAYED_WORK(&tabla->mbhc_firmware_dwork, mbhc_fw_read);
INIT_DELAYED_WORK(&tabla->btn0_dwork, btn0_lpress_fn);
INIT_WORK(&tabla->hphlocp_work, hphlocp_off_report);
INIT_WORK(&tabla->hphrocp_work, hphrocp_off_report);
@@ -3632,8 +3719,8 @@
tabla_codec_calibrate_hs_polling(codec);
rc = tabla_codec_enable_hs_detect(codec, 1);
} else {
- pr_err("%s: MBHC firmware read not supported\n", __func__);
- rc = -EINVAL;
+ schedule_delayed_work(&tabla->mbhc_firmware_dwork,
+ usecs_to_jiffies(MBHC_FW_READ_TIMEOUT));
}
if (!IS_ERR_VALUE(rc)) {
@@ -4386,6 +4473,7 @@
/* Make sure mbhc intenal calibration data is zeroed out */
memset(&tabla->mbhc_data, 0,
sizeof(struct mbhc_internal_cal_data));
+ tabla->mbhc_data.t_sta_dce = DEFAULT_DCE_STA_WAIT;
tabla->mbhc_data.t_dce = DEFAULT_DCE_WAIT;
tabla->mbhc_data.t_sta = DEFAULT_STA_WAIT;
snd_soc_codec_set_drvdata(codec, tabla);
@@ -4552,6 +4640,8 @@
tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION, tabla);
tabla_codec_disable_clock_block(codec);
tabla_codec_enable_bandgap(codec, TABLA_BANDGAP_OFF);
+ if (tabla->mbhc_fw)
+ release_firmware(tabla->mbhc_fw);
kfree(tabla);
return 0;
}
diff --git a/sound/soc/codecs/wcd9310.h b/sound/soc/codecs/wcd9310.h
index 66c3e39..77bfc73 100644
--- a/sound/soc/codecs/wcd9310.h
+++ b/sound/soc/codecs/wcd9310.h
@@ -21,7 +21,7 @@
#define TABLA_REG_VAL(reg, val) {reg, 0, val}
-
+#define DEFAULT_DCE_STA_WAIT 55
#define DEFAULT_DCE_WAIT 60000
#define DEFAULT_STA_WAIT 5000
@@ -197,3 +197,29 @@
sizeof(TABLA_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_high[0])))) \
)
+/* minimum size of calibration data assuming there is only one button and
+ * one rload.
+ */
+#define TABLA_MBHC_CAL_MIN_SIZE ( \
+ sizeof(struct tabla_mbhc_general_cfg) + \
+ sizeof(struct tabla_mbhc_plug_detect_cfg) + \
+ sizeof(struct tabla_mbhc_plug_type_cfg) + \
+ sizeof(struct tabla_mbhc_btn_detect_cfg) + \
+ sizeof(struct tabla_mbhc_imped_detect_cfg) + \
+ (sizeof(u16) * 2))
+
+#define TABLA_MBHC_CAL_BTN_SZ(cfg_ptr) ( \
+ sizeof(struct tabla_mbhc_btn_detect_cfg) + \
+ (cfg_ptr->num_btn * (sizeof(cfg_ptr->_v_btn_low[0]) + \
+ sizeof(cfg_ptr->_v_btn_high[0]))))
+
+#define TABLA_MBHC_CAL_IMPED_MIN_SZ ( \
+ sizeof(struct tabla_mbhc_imped_detect_cfg) + \
+ sizeof(u16) * 2)
+
+#define TABLA_MBHC_CAL_IMPED_SZ(cfg_ptr) ( \
+ sizeof(struct tabla_mbhc_imped_detect_cfg) + \
+ (cfg_ptr->_n_rload * (sizeof(cfg_ptr->_rload[0]) + \
+ sizeof(cfg_ptr->_alpha[0]))))
+
+
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 590d4af..d0497b1 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -47,10 +47,10 @@
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = 1200 * 1024 * 2,
- .period_bytes_min = 60 * 1024,
+ .period_bytes_min = 4800,
.period_bytes_max = 1200 * 1024,
.periods_min = 2,
- .periods_max = 40,
+ .periods_max = 512,
.fifo_size = 0,
};
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 16d149e..fea11d9 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.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
@@ -236,6 +236,19 @@
.ops = &msm_fe_dai_ops,
.name = "AFE-PROXY",
},
+ {
+ .playback = {
+ .stream_name = "HDMI_Rx Hostless Playback",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "HDMI_HOSTLESS"
+ },
};
static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 2815daa..1331ebf 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.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
@@ -1128,6 +1128,8 @@
0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
+
/* Backend AIF */
/* Stream name equals to backend dai link stream name
*/
@@ -1312,6 +1314,7 @@
{"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
+ {"HDMI", NULL, "HDMI_DL_HL"},
{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
{"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 60fa5f3..0dc3b57 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -724,6 +724,14 @@
},
};
+static struct snd_soc_dsp_link hdmi_rx_hl = {
+ .playback = true,
+ .trigger = {
+ SND_SOC_DSP_TRIGGER_POST,
+ SND_SOC_DSP_TRIGGER_POST
+ },
+};
+
static int msm8960_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -1010,6 +1018,18 @@
.dsp_link = &lpa_fe_media,
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
},
+ /* HDMI Hostless */
+ {
+ .name = "HDMI_RX_HOSTLESS",
+ .stream_name = "HDMI_RX_HOSTLESS",
+ .cpu_dai_name = "HDMI_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dsp_link = &hdmi_rx_hl,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .no_codec = 1,
+ .ignore_suspend = 1,
+ },
/* Backend DAI Links */
{
.name = LPASS_BE_SLIMBUS_0_RX,
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index 21bbcf2..74a66945 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -56,6 +56,7 @@
pr_debug("task_name = %s pid = %d\n",
this_afe.task->comm, this_afe.task->pid);
send_sig(SIGUSR1, this_afe.task, 0);
+ return 0;
}
if (data->payload_size) {
uint32_t *payload;
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index ab7f9f7..62168d2 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -515,6 +515,7 @@
pr_err("%s:map_buffer failed,"
"error = %ld\n",
__func__, PTR_ERR((void *)buf[cnt].mem_buffer));
+ mutex_unlock(&ac->cmd_lock);
goto fail;
}
buf[cnt].data =
@@ -522,6 +523,7 @@
if (!buf[cnt].data) {
pr_err("%s:invalid vaddr,"
" iomap failed\n", __func__);
+ mutex_unlock(&ac->cmd_lock);
goto fail;
}
buf[cnt].used = 1;
@@ -944,6 +946,7 @@
idx = port->cpu_buf;
if (port->buf == NULL) {
pr_debug("%s:Buffer pointer null\n", __func__);
+ mutex_unlock(&port->lock);
return NULL;
}
/* dir 0: used = 0 means buf in use