Merge "Bluetooth: If link is encrypted, do not send encrpt link request" into msm-3.0
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 9c6ebdf..23b4668 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -319,12 +319,18 @@
CONFIG_MFD_PM8XXX_BATT_ALARM=y
CONFIG_REGULATOR_GPIO=y
CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_DEV=y
# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_USB_VIDEO_CLASS=y
-CONFIG_IMX074=y
+CONFIG_MSM_CAMERA_V4L2=y
CONFIG_WEBCAM_OV9726=y
CONFIG_MT9E013=y
+CONFIG_IMX074=y
+CONFIG_IMX074_ACT=y
+CONFIG_OV7692=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
CONFIG_MSM_GEMINI=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index aae900a..fddd385 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -320,12 +320,18 @@
CONFIG_MFD_PM8XXX_BATT_ALARM=y
CONFIG_REGULATOR_GPIO=y
CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_DEV=y
# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_USB_VIDEO_CLASS=y
-CONFIG_IMX074=y
+CONFIG_MSM_CAMERA_V4L2=y
CONFIG_WEBCAM_OV9726=y
CONFIG_MT9E013=y
+CONFIG_IMX074=y
+CONFIG_IMX074_ACT=y
+CONFIG_OV7692=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
CONFIG_MSM_GEMINI=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index dc2db27..b5a17cd 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -90,6 +90,7 @@
CONFIG_MSM_CACHE_ERP=y
CONFIG_MSM_L2_ERP_2BIT_PANIC=y
CONFIG_MSM_DCVS=y
+CONFIG_MSM_HSIC_SYSMON=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index ba616b0..e18f0ea 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -97,6 +97,7 @@
CONFIG_MSM_DCVS=y
CONFIG_MSM_CACHE_DUMP=y
CONFIG_MSM_CACHE_DUMP_ON_PANIC=y
+CONFIG_MSM_HSIC_SYSMON=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index 3dfb62f..7a5b21a 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -141,7 +141,7 @@
unsigned int msmsdcc_fmax;
bool nonremovable;
bool pclk_src_dfab;
- int (*cfg_mpm_sdiowakeup)(struct device *, unsigned);
+ unsigned int mpm_sdiowakeup_int;
unsigned int wpswitch_gpio;
unsigned char wpswitch_polarity;
struct msm_mmc_slot_reg_data *vreg_data;
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 33c84a6..4ea24a4 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -2275,4 +2275,21 @@
want to dump the L1 and L2 caches on panic before any flush occurs.
If unsure, say N
+config MSM_HSIC_SYSMON
+ tristate "MSM HSIC system monitor driver"
+ depends on USB
+ help
+ Add support for bridging with the system monitor interface of MDM
+ over HSIC. This driver allows the local system monitor to
+ communicate with the remote system monitor interface.
+
+config MSM_HSIC_SYSMON_TEST
+ tristate "MSM HSIC system monitor bridge test"
+ depends on USB && MSM_HSIC_SYSMON && DEBUG_FS
+ help
+ Enable the test hook for the Qualcomm system monitor HSIC driver.
+ This will create a debugfs file entry named "hsic_sysmon_test" which
+ can be read and written to send character data to the sysmon port of
+ the modem over USB.
+
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 14bae2d..3ef61f4 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -345,3 +345,6 @@
obj-$(CONFIG_MSM_RTB) += msm_rtb.o
obj-$(CONFIG_MSM_CACHE_ERP) += cache_erp.o
obj-$(CONFIG_MSM_CACHE_DUMP) += msm_cache_dump.o
+
+obj-$(CONFIG_MSM_HSIC_SYSMON) += hsic_sysmon.o
+obj-$(CONFIG_MSM_HSIC_SYSMON_TEST) += hsic_sysmon_test.o
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 2d1c31c..0d1c72d 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -412,9 +412,11 @@
.cam_bus_scale_table = &cam_bus_client_pdata,
},
{
- .ioclk.mclk_clk_rate = 24000000,
- .ioclk.vfe_clk_rate = 228570000,
.csid_core = 2,
+ .is_csiphy = 1,
+ .is_csid = 1,
+ .is_ispif = 1,
+ .is_vpe = 1,
.cam_bus_scale_table = &cam_bus_client_pdata,
},
};
diff --git a/arch/arm/mach-msm/board-msm8x60-camera.c b/arch/arm/mach-msm/board-msm8x60-camera.c
index 95561e4..c12dce6 100644
--- a/arch/arm/mach-msm/board-msm8x60-camera.c
+++ b/arch/arm/mach-msm/board-msm8x60-camera.c
@@ -12,7 +12,6 @@
*/
#include <asm/mach-types.h>
-#include <devices-msm8x60.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/mfd/pmic8901.h>
@@ -20,6 +19,7 @@
#include <mach/board-msm8660.h>
#include <mach/gpiomux.h>
#include <mach/msm_bus_board.h>
+#include "devices-msm8x60.h"
#include "devices.h"
#define GPIO_EXT_CAMIF_PWR_EN1 (PM8901_MPP_BASE + PM8901_MPPS + 13)
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 824cad8..7832b878 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2630,7 +2630,7 @@
#endif /* CONFIG_FB_MSM_OVERLAY1_WRITEBACK */
#define MSM_PMEM_KERNEL_EBI1_SIZE 0x3BC000
-#define MSM_PMEM_ADSP_SIZE 0x2000000
+#define MSM_PMEM_ADSP_SIZE 0x4200000
#define MSM_PMEM_AUDIO_SIZE 0x4CF000
#define MSM_SMI_BASE 0x38000000
@@ -8311,45 +8311,10 @@
}
#endif
#endif
+#endif
-#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+#define MSM_MPM_PIN_SDC3_DAT1 21
#define MSM_MPM_PIN_SDC4_DAT1 23
-static int msm_sdcc_cfg_mpm_sdiowakeup(struct device *dev, unsigned mode)
-{
- struct platform_device *pdev;
- unsigned int pin;
- int ret = 0;
-
- pdev = container_of(dev, struct platform_device, dev);
-
- /* Only SDCC4 slot connected to WLAN chip has wakeup capability */
- if (pdev->id == 4)
- pin = MSM_MPM_PIN_SDC4_DAT1;
- else
- return -EINVAL;
-
- switch (mode) {
- case SDC_DAT1_DISABLE:
- ret = msm_mpm_enable_pin(pin, 0);
- break;
- case SDC_DAT1_ENABLE:
- ret = msm_mpm_set_pin_type(pin, IRQ_TYPE_LEVEL_LOW);
- ret = msm_mpm_enable_pin(pin, 1);
- break;
- case SDC_DAT1_ENWAKE:
- ret = msm_mpm_set_pin_wake(pin, 1);
- break;
- case SDC_DAT1_DISWAKE:
- ret = msm_mpm_set_pin_wake(pin, 0);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-#endif
-#endif
#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
static struct mmc_platform_data msm8x60_sdc1_data = {
@@ -8416,7 +8381,7 @@
.msmsdcc_fmax = 48000000,
.nonremovable = 0,
.pclk_src_dfab = 1,
- .cfg_mpm_sdiowakeup = msm_sdcc_cfg_mpm_sdiowakeup,
+ .mpm_sdiowakeup_int = MSM_MPM_PIN_SDC4_DAT1,
};
#endif
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 17719d6..ef14b93 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -2848,7 +2848,7 @@
.bus_freq = 0,
},
},
- .init_level = 0,
+ .init_level = 1,
.num_levels = ARRAY_SIZE(grp3d_freq) + 1,
.set_grp_async = NULL,
.idle_timeout = HZ/12,
diff --git a/arch/arm/mach-msm/hsic_sysmon.c b/arch/arm/mach-msm/hsic_sysmon.c
new file mode 100644
index 0000000..2dedbac
--- /dev/null
+++ b/arch/arm/mach-msm/hsic_sysmon.c
@@ -0,0 +1,449 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* add additional information to our printk's */
+#define pr_fmt(fmt) "%s: " fmt "\n", __func__
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kref.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/debugfs.h>
+
+#include "hsic_sysmon.h"
+#include "sysmon.h"
+
+#define DRIVER_DESC "HSIC System monitor driver"
+
+enum hsic_sysmon_op {
+ HSIC_SYSMON_OP_READ = 0,
+ HSIC_SYSMON_OP_WRITE,
+ NUM_OPS
+};
+
+struct hsic_sysmon {
+ struct usb_device *udev;
+ struct usb_interface *ifc;
+ __u8 in_epaddr;
+ __u8 out_epaddr;
+ unsigned int pipe[NUM_OPS];
+ struct kref kref;
+ struct platform_device pdev;
+ int id;
+
+ /* debugging counters */
+ atomic_t dbg_bytecnt[NUM_OPS];
+ atomic_t dbg_pending[NUM_OPS];
+};
+static struct hsic_sysmon *hsic_sysmon_devices[NUM_HSIC_SYSMON_DEVS];
+
+static void hsic_sysmon_delete(struct kref *kref)
+{
+ struct hsic_sysmon *hs = container_of(kref, struct hsic_sysmon, kref);
+
+ usb_put_dev(hs->udev);
+ hsic_sysmon_devices[hs->id] = NULL;
+ kfree(hs);
+}
+
+/**
+ * hsic_sysmon_open() - Opens the system monitor bridge.
+ * @id: the HSIC system monitor device to open
+ *
+ * This should only be called after the platform_device "sys_mon" with id
+ * SYSMON_SS_EXT_MODEM has been added. The simplest way to do that is to
+ * register a platform_driver and its probe will be called when the HSIC
+ * device is ready.
+ */
+int hsic_sysmon_open(enum hsic_sysmon_device_id id)
+{
+ struct hsic_sysmon *hs;
+
+ if (id >= NUM_HSIC_SYSMON_DEVS) {
+ pr_err("invalid dev id(%d)", id);
+ return -ENODEV;
+ }
+
+ hs = hsic_sysmon_devices[id];
+ if (!hs) {
+ pr_err("dev is null");
+ return -ENODEV;
+ }
+
+ kref_get(&hs->kref);
+
+ return 0;
+}
+EXPORT_SYMBOL(hsic_sysmon_open);
+
+/**
+ * hsic_sysmon_close() - Closes the system monitor bridge.
+ * @id: the HSIC system monitor device to close
+ */
+void hsic_sysmon_close(enum hsic_sysmon_device_id id)
+{
+ struct hsic_sysmon *hs;
+
+ if (id >= NUM_HSIC_SYSMON_DEVS) {
+ pr_err("invalid dev id(%d)", id);
+ return;
+ }
+
+ hs = hsic_sysmon_devices[id];
+ kref_put(&hs->kref, hsic_sysmon_delete);
+}
+EXPORT_SYMBOL(hsic_sysmon_close);
+
+/**
+ * hsic_sysmon_readwrite() - Common function to send read/write over HSIC
+ */
+static int hsic_sysmon_readwrite(enum hsic_sysmon_device_id id, void *data,
+ size_t len, size_t *actual_len, int timeout,
+ enum hsic_sysmon_op op)
+{
+ struct hsic_sysmon *hs;
+ int ret;
+ const char *opstr = (op == HSIC_SYSMON_OP_READ) ?
+ "read" : "write";
+
+ pr_debug("%s: id:%d, data len:%d, timeout:%d", opstr, id, len, timeout);
+
+ if (id >= NUM_HSIC_SYSMON_DEVS) {
+ pr_err("invalid dev id(%d)", id);
+ return -ENODEV;
+ }
+
+ if (!len) {
+ pr_err("length(%d) must be greater than 0", len);
+ return -EINVAL;
+ }
+
+ hs = hsic_sysmon_devices[id];
+ if (!hs) {
+ pr_err("device was not opened");
+ return -ENODEV;
+ }
+
+ if (!hs->ifc) {
+ dev_err(&hs->udev->dev, "can't %s, device disconnected\n",
+ opstr);
+ return -ENODEV;
+ }
+
+ ret = usb_autopm_get_interface(hs->ifc);
+ if (ret < 0) {
+ dev_err(&hs->udev->dev, "can't %s, autopm_get failed:%d\n",
+ opstr, ret);
+ return ret;
+ }
+
+ atomic_inc(&hs->dbg_pending[op]);
+
+ ret = usb_bulk_msg(hs->udev, hs->pipe[op], data, len, actual_len,
+ timeout);
+
+ atomic_dec(&hs->dbg_pending[op]);
+
+ if (ret)
+ dev_err(&hs->udev->dev,
+ "can't %s, usb_bulk_msg failed, err:%d\n", opstr, ret);
+ else
+ atomic_add(*actual_len, &hs->dbg_bytecnt[op]);
+
+ usb_autopm_put_interface(hs->ifc);
+ return ret;
+}
+
+/**
+ * hsic_sysmon_read() - Read data from the HSIC sysmon interface.
+ * @id: the HSIC system monitor device to open
+ * @data: pointer to caller-allocated buffer to fill in
+ * @len: length in bytes of the buffer
+ * @actual_len: pointer to a location to put the actual length read
+ * in bytes
+ * @timeout: time in msecs to wait for the message to complete before
+ * timing out (if 0 the wait is forever)
+ *
+ * Context: !in_interrupt ()
+ *
+ * Synchronously reads data from the HSIC interface. The call will return
+ * after the read has completed, encountered an error, or timed out. Upon
+ * successful return actual_len will reflect the number of bytes read.
+ *
+ * If successful, it returns 0, otherwise a negative error number. The number
+ * of actual bytes transferred will be stored in the actual_len paramater.
+ */
+int hsic_sysmon_read(enum hsic_sysmon_device_id id, char *data, size_t len,
+ size_t *actual_len, int timeout)
+{
+ return hsic_sysmon_readwrite(id, data, len, actual_len,
+ timeout, HSIC_SYSMON_OP_READ);
+}
+EXPORT_SYMBOL(hsic_sysmon_read);
+
+/**
+ * hsic_sysmon_write() - Write data to the HSIC sysmon interface.
+ * @id: the HSIC system monitor device to open
+ * @data: pointer to caller-allocated buffer to write
+ * @len: length in bytes of the data in buffer to write
+ * @actual_len: pointer to a location to put the actual length written
+ * in bytes
+ * @timeout: time in msecs to wait for the message to complete before
+ * timing out (if 0 the wait is forever)
+ *
+ * Context: !in_interrupt ()
+ *
+ * Synchronously writes data to the HSIC interface. The call will return
+ * after the write has completed, encountered an error, or timed out. Upon
+ * successful return actual_len will reflect the number of bytes written.
+ *
+ * If successful, it returns 0, otherwise a negative error number. The number
+ * of actual bytes transferred will be stored in the actual_len paramater.
+ */
+int hsic_sysmon_write(enum hsic_sysmon_device_id id, const char *data,
+ size_t len, int timeout)
+{
+ size_t actual_len;
+ return hsic_sysmon_readwrite(id, (void *)data, len, &actual_len,
+ timeout, HSIC_SYSMON_OP_WRITE);
+}
+EXPORT_SYMBOL(hsic_sysmon_write);
+
+#if defined(CONFIG_DEBUG_FS)
+#define DEBUG_BUF_SIZE 512
+static ssize_t sysmon_debug_read_stats(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int i, ret = 0;
+
+ buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ for (i = 0; i < NUM_HSIC_SYSMON_DEVS; i++) {
+ struct hsic_sysmon *hs = hsic_sysmon_devices[i];
+ if (!hs)
+ continue;
+
+ ret += scnprintf(buf, DEBUG_BUF_SIZE,
+ "---HSIC Sysmon #%d---\n"
+ "epin:%d, epout:%d\n"
+ "bytes to host: %d\n"
+ "bytes to mdm: %d\n"
+ "pending reads: %d\n"
+ "pending writes: %d\n",
+ i, hs->in_epaddr & ~0x80, hs->out_epaddr,
+ atomic_read(
+ &hs->dbg_bytecnt[HSIC_SYSMON_OP_READ]),
+ atomic_read(
+ &hs->dbg_bytecnt[HSIC_SYSMON_OP_WRITE]),
+ atomic_read(
+ &hs->dbg_pending[HSIC_SYSMON_OP_READ]),
+ atomic_read(
+ &hs->dbg_pending[HSIC_SYSMON_OP_WRITE])
+ );
+ }
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t sysmon_debug_reset_stats(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int i;
+
+ for (i = 0; i < NUM_HSIC_SYSMON_DEVS; i++) {
+ struct hsic_sysmon *hs = hsic_sysmon_devices[i];
+ if (hs) {
+ atomic_set(&hs->dbg_bytecnt[HSIC_SYSMON_OP_READ], 0);
+ atomic_set(&hs->dbg_bytecnt[HSIC_SYSMON_OP_WRITE], 0);
+ atomic_set(&hs->dbg_pending[HSIC_SYSMON_OP_READ], 0);
+ atomic_set(&hs->dbg_pending[HSIC_SYSMON_OP_WRITE], 0);
+ }
+ }
+
+ return count;
+}
+
+const struct file_operations sysmon_stats_ops = {
+ .read = sysmon_debug_read_stats,
+ .write = sysmon_debug_reset_stats,
+};
+
+static struct dentry *dent;
+
+static void hsic_sysmon_debugfs_init(void)
+{
+ struct dentry *dfile;
+
+ dent = debugfs_create_dir("hsic_sysmon", 0);
+ if (IS_ERR(dent))
+ return;
+
+ dfile = debugfs_create_file("status", 0444, dent, 0, &sysmon_stats_ops);
+ if (!dfile || IS_ERR(dfile))
+ debugfs_remove(dent);
+}
+
+static void hsic_sysmon_debugfs_cleanup(void)
+{
+ if (dent) {
+ debugfs_remove_recursive(dent);
+ dent = NULL;
+ }
+}
+#else
+static inline void hsic_sysmon_debugfs_init(void) { }
+static inline void hsic_sysmon_debugfs_cleanup(void) { }
+#endif
+
+static int
+hsic_sysmon_probe(struct usb_interface *ifc, const struct usb_device_id *id)
+{
+ struct hsic_sysmon *hs;
+ struct usb_host_interface *ifc_desc;
+ struct usb_endpoint_descriptor *ep_desc;
+ int i;
+ int ret = -ENOMEM;
+ __u8 ifc_num;
+
+ pr_debug("id:%lu", id->driver_info);
+
+ ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber;
+
+ /* is this the interface we're looking for? */
+ if (ifc_num != id->driver_info)
+ return -ENODEV;
+
+ hs = kzalloc(sizeof(*hs), GFP_KERNEL);
+ if (!hs) {
+ pr_err("unable to allocate hsic_sysmon");
+ return -ENOMEM;
+ }
+
+ hs->udev = usb_get_dev(interface_to_usbdev(ifc));
+ hs->ifc = ifc;
+ kref_init(&hs->kref);
+
+ ifc_desc = ifc->cur_altsetting;
+ for (i = 0; i < ifc_desc->desc.bNumEndpoints; i++) {
+ ep_desc = &ifc_desc->endpoint[i].desc;
+
+ if (!hs->in_epaddr && usb_endpoint_is_bulk_in(ep_desc)) {
+ hs->in_epaddr = ep_desc->bEndpointAddress;
+ hs->pipe[HSIC_SYSMON_OP_READ] =
+ usb_rcvbulkpipe(hs->udev, hs->in_epaddr);
+ }
+
+ if (!hs->out_epaddr && usb_endpoint_is_bulk_out(ep_desc)) {
+ hs->out_epaddr = ep_desc->bEndpointAddress;
+ hs->pipe[HSIC_SYSMON_OP_WRITE] =
+ usb_sndbulkpipe(hs->udev, hs->out_epaddr);
+ }
+ }
+
+ if (!(hs->in_epaddr && hs->out_epaddr)) {
+ pr_err("could not find bulk in and bulk out endpoints");
+ ret = -ENODEV;
+ goto error;
+ }
+
+ hs->id = HSIC_SYSMON_DEV_EXT_MODEM;
+ hsic_sysmon_devices[HSIC_SYSMON_DEV_EXT_MODEM] = hs;
+ usb_set_intfdata(ifc, hs);
+
+ hs->pdev.name = "sys_mon";
+ hs->pdev.id = SYSMON_SS_EXT_MODEM;
+ platform_device_register(&hs->pdev);
+
+ pr_debug("complete");
+
+ return 0;
+
+error:
+ if (hs)
+ kref_put(&hs->kref, hsic_sysmon_delete);
+
+ return ret;
+}
+
+static void hsic_sysmon_disconnect(struct usb_interface *ifc)
+{
+ struct hsic_sysmon *hs = usb_get_intfdata(ifc);
+
+ platform_device_unregister(&hs->pdev);
+ kref_put(&hs->kref, hsic_sysmon_delete);
+ usb_set_intfdata(ifc, NULL);
+}
+
+static int hsic_sysmon_suspend(struct usb_interface *ifc, pm_message_t message)
+{
+ return 0;
+}
+
+static int hsic_sysmon_resume(struct usb_interface *ifc)
+{
+ return 0;
+}
+
+/* driver_info maps to the interface number corresponding to sysmon */
+static const struct usb_device_id hsic_sysmon_ids[] = {
+ { USB_DEVICE(0x5c6, 0x9048), .driver_info = 1, },
+ { USB_DEVICE(0x5c6, 0x904C), .driver_info = 1, },
+ {} /* terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, hsic_sysmon_ids);
+
+static struct usb_driver hsic_sysmon_driver = {
+ .name = "hsic_sysmon",
+ .probe = hsic_sysmon_probe,
+ .disconnect = hsic_sysmon_disconnect,
+ .suspend = hsic_sysmon_suspend,
+ .resume = hsic_sysmon_resume,
+ .id_table = hsic_sysmon_ids,
+ .supports_autosuspend = 1,
+};
+
+static int __init hsic_sysmon_init(void)
+{
+ int ret;
+
+ ret = usb_register(&hsic_sysmon_driver);
+ if (ret) {
+ pr_err("unable to register " DRIVER_DESC);
+ return ret;
+ }
+
+ hsic_sysmon_debugfs_init();
+ return 0;
+}
+
+static void __exit hsic_sysmon_exit(void)
+{
+ hsic_sysmon_debugfs_cleanup();
+ usb_deregister(&hsic_sysmon_driver);
+}
+
+module_init(hsic_sysmon_init);
+module_exit(hsic_sysmon_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/hsic_sysmon.h b/arch/arm/mach-msm/hsic_sysmon.h
new file mode 100644
index 0000000..aa57b93
--- /dev/null
+++ b/arch/arm/mach-msm/hsic_sysmon.h
@@ -0,0 +1,56 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __HSIC_SYSMON_H__
+#define __HSIC_SYSMON_H__
+
+/**
+ * enum hsic_sysmon_device_id - Supported HSIC subsystem devices
+ */
+enum hsic_sysmon_device_id {
+ HSIC_SYSMON_DEV_EXT_MODEM,
+ NUM_HSIC_SYSMON_DEVS
+};
+
+#if defined(CONFIG_MSM_HSIC_SYSMON) || defined(CONFIG_MSM_HSIC_SYSMON_MODULE)
+
+extern int hsic_sysmon_open(enum hsic_sysmon_device_id id);
+extern void hsic_sysmon_close(enum hsic_sysmon_device_id id);
+extern int hsic_sysmon_read(enum hsic_sysmon_device_id id, char *data,
+ size_t len, size_t *actual_len, int timeout);
+extern int hsic_sysmon_write(enum hsic_sysmon_device_id id, const char *data,
+ size_t len, int timeout);
+
+#else /* CONFIG_MSM_HSIC_SYSMON || CONFIG_MSM_HSIC_SYSMON_MODULE */
+
+static inline int hsic_sysmon_open(enum hsic_sysmon_device_id id)
+{
+ return -ENODEV;
+}
+
+static inline void hsic_sysmon_close(enum hsic_sysmon_device_id id) { }
+
+static inline int hsic_sysmon_read(enum hsic_sysmon_device_id id, char *data,
+ size_t len, size_t *actual_len, int timeout)
+{
+ return -ENODEV;
+}
+
+static inline int hsic_sysmon_write(enum hsic_sysmon_device_id id,
+ const char *data, size_t len, int timeout)
+{
+ return -ENODEV;
+}
+
+#endif /* CONFIG_MSM_HSIC_SYSMON || CONFIG_MSM_HSIC_SYSMON_MODULE */
+
+#endif /* __HSIC_SYSMON_H__ */
diff --git a/arch/arm/mach-msm/hsic_sysmon_test.c b/arch/arm/mach-msm/hsic_sysmon_test.c
new file mode 100644
index 0000000..9929cb7
--- /dev/null
+++ b/arch/arm/mach-msm/hsic_sysmon_test.c
@@ -0,0 +1,118 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* add additional information to our printk's */
+#define pr_fmt(fmt) "%s: " fmt "\n", __func__
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include "hsic_sysmon.h"
+#include "sysmon.h"
+
+#define DRIVER_DESC "HSIC System monitor driver test"
+
+#define RD_BUF_SIZE 4096
+
+struct sysmon_test_dev {
+ int buflen;
+ char buf[RD_BUF_SIZE];
+};
+static struct sysmon_test_dev *sysmon_dev;
+
+static ssize_t sysmon_test_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct sysmon_test_dev *dev = sysmon_dev;
+ int ret;
+
+ if (!dev)
+ return -ENODEV;
+
+ ret = hsic_sysmon_read(HSIC_SYSMON_DEV_EXT_MODEM, dev->buf, RD_BUF_SIZE,
+ &dev->buflen, 3000);
+ if (!ret)
+ return simple_read_from_buffer(ubuf, count, ppos,
+ dev->buf, dev->buflen);
+
+ return 0;
+}
+
+static ssize_t sysmon_test_write(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct sysmon_test_dev *dev = sysmon_dev;
+ int ret;
+
+ if (!dev)
+ return -ENODEV;
+
+ if (copy_from_user(dev->buf, ubuf, count)) {
+ pr_err("error copying for writing");
+ return 0;
+ }
+
+ ret = hsic_sysmon_write(HSIC_SYSMON_DEV_EXT_MODEM,
+ dev->buf, count, 1000);
+ if (ret < 0) {
+ pr_err("error writing to hsic_sysmon");
+ return ret;
+ }
+
+ return count;
+}
+
+static int sysmon_test_open(struct inode *inode, struct file *file)
+{
+ return hsic_sysmon_open(HSIC_SYSMON_DEV_EXT_MODEM);
+}
+
+static int sysmon_test_release(struct inode *inode, struct file *file)
+{
+ hsic_sysmon_close(HSIC_SYSMON_DEV_EXT_MODEM);
+ return 0;
+}
+
+static struct dentry *dfile;
+const struct file_operations sysmon_test_ops = {
+ .read = sysmon_test_read,
+ .write = sysmon_test_write,
+ .open = sysmon_test_open,
+ .release = sysmon_test_release
+};
+
+static int __init sysmon_test_init(void)
+{
+ sysmon_dev = kzalloc(sizeof(*sysmon_dev), GFP_KERNEL);
+ if (!sysmon_dev)
+ return -ENOMEM;
+
+ dfile = debugfs_create_file("hsic_sysmon_test", 0666, NULL,
+ 0, &sysmon_test_ops);
+ return 0;
+}
+
+static void __exit sysmon_test_exit(void)
+{
+ if (dfile)
+ debugfs_remove(dfile);
+ kfree(sysmon_dev);
+}
+
+module_init(sysmon_test_init);
+module_exit(sysmon_test_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sysmon.c b/arch/arm/mach-msm/sysmon.c
index 3d3824a..ddb8502 100644
--- a/arch/arm/mach-msm/sysmon.c
+++ b/arch/arm/mach-msm/sysmon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -24,20 +24,34 @@
#include <mach/msm_smd.h>
#include <mach/subsystem_notif.h>
+#include "hsic_sysmon.h"
#include "sysmon.h"
#define MAX_MSG_LENGTH 50
#define TIMEOUT_MS 5000
+enum transports {
+ TRANSPORT_SMD,
+ TRANSPORT_HSIC,
+};
+
struct sysmon_subsys {
struct mutex lock;
struct smd_channel *chan;
bool chan_open;
struct completion resp_ready;
char rx_buf[MAX_MSG_LENGTH];
+ enum transports transport;
};
-static struct sysmon_subsys subsys[SYSMON_NUM_SS];
+static struct sysmon_subsys subsys[SYSMON_NUM_SS] = {
+ [SYSMON_SS_MODEM].transport = TRANSPORT_SMD,
+ [SYSMON_SS_LPASS].transport = TRANSPORT_SMD,
+ [SYSMON_SS_WCNSS].transport = TRANSPORT_SMD,
+ [SYSMON_SS_DSPS].transport = TRANSPORT_SMD,
+ [SYSMON_SS_Q6FW].transport = TRANSPORT_SMD,
+ [SYSMON_SS_EXT_MODEM].transport = TRANSPORT_HSIC,
+};
static const char *notif_name[SUBSYS_NOTIF_TYPE_COUNT] = {
[SUBSYS_BEFORE_SHUTDOWN] = "before_shutdown",
@@ -46,6 +60,39 @@
[SUBSYS_AFTER_POWERUP] = "after_powerup",
};
+static int sysmon_send_smd(struct sysmon_subsys *ss, char *tx_buf, size_t len)
+{
+ int ret;
+
+ if (!ss->chan_open)
+ return -ENODEV;
+
+ init_completion(&ss->resp_ready);
+ pr_debug("Sending SMD message: %s\n", tx_buf);
+ smd_write(ss->chan, tx_buf, len);
+ ret = wait_for_completion_timeout(&ss->resp_ready,
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int sysmon_send_hsic(struct sysmon_subsys *ss, char *tx_buf, size_t len)
+{
+ int ret;
+ size_t actual_len;
+
+ pr_debug("Sending HSIC message: %s\n", tx_buf);
+ ret = hsic_sysmon_write(HSIC_SYSMON_DEV_EXT_MODEM,
+ tx_buf, len, TIMEOUT_MS);
+ if (ret)
+ return ret;
+ ret = hsic_sysmon_read(HSIC_SYSMON_DEV_EXT_MODEM, ss->rx_buf,
+ ARRAY_SIZE(ss->rx_buf), &actual_len, TIMEOUT_MS);
+ return ret;
+}
+
int sysmon_send_event(enum subsys_id dest_ss, const char *event_ss,
enum subsys_notif_type notif)
{
@@ -58,31 +105,34 @@
event_ss == NULL)
return -EINVAL;
- if (!ss->chan_open)
- return -ENODEV;
-
- mutex_lock(&ss->lock);
- init_completion(&ss->resp_ready);
snprintf(tx_buf, ARRAY_SIZE(tx_buf), "ssr:%s:%s", event_ss,
notif_name[notif]);
- pr_debug("Sending message: %s\n", tx_buf);
- smd_write(ss->chan, tx_buf, ARRAY_SIZE(tx_buf));
- ret = wait_for_completion_timeout(&ss->resp_ready,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- ret = -ETIMEDOUT;
- } else if (strncmp(ss->rx_buf, "ssr:ack", ARRAY_SIZE(ss->rx_buf))) {
- pr_debug("Received response: %s\n", ss->rx_buf);
- ret = -ENOSYS;
- } else {
- ret = 0;
- }
- mutex_unlock(&ss->lock);
+ mutex_lock(&ss->lock);
+ switch (ss->transport) {
+ case TRANSPORT_SMD:
+ ret = sysmon_send_smd(ss, tx_buf, ARRAY_SIZE(tx_buf));
+ break;
+ case TRANSPORT_HSIC:
+ ret = sysmon_send_hsic(ss, tx_buf, ARRAY_SIZE(tx_buf));
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ if (ret)
+ goto out;
+
+ pr_debug("Received response: %s\n", ss->rx_buf);
+ if (strncmp(ss->rx_buf, "ssr:ack", ARRAY_SIZE(ss->rx_buf)))
+ ret = -ENOSYS;
+ else
+ ret = 0;
+out:
+ mutex_unlock(&ss->lock);
return ret;
}
-static void sysmon_notify(void *priv, unsigned int smd_event)
+static void sysmon_smd_notify(void *priv, unsigned int smd_event)
{
struct sysmon_subsys *ss = priv;
@@ -104,44 +154,61 @@
}
}
-static const uint32_t ss_map[SMD_NUM_TYPE] = {
- [SMD_APPS_MODEM] = SYSMON_SS_MODEM,
- [SMD_APPS_QDSP] = SYSMON_SS_LPASS,
- [SMD_APPS_WCNSS] = SYSMON_SS_WCNSS,
- [SMD_APPS_DSPS] = SYSMON_SS_DSPS,
- [SMD_APPS_Q6FW] = SYSMON_SS_Q6FW,
-};
-
static int sysmon_probe(struct platform_device *pdev)
{
struct sysmon_subsys *ss;
int ret;
- if (pdev == NULL)
- return -EINVAL;
-
- if (pdev->id < 0 || pdev->id >= SMD_NUM_TYPE ||
- ss_map[pdev->id] < 0 || ss_map[pdev->id] >= SYSMON_NUM_SS)
+ if (pdev->id < 0 || pdev->id >= SYSMON_NUM_SS)
return -ENODEV;
- ss = &subsys[ss_map[pdev->id]];
+ ss = &subsys[pdev->id];
mutex_init(&ss->lock);
- /* Open and configure the SMD channel */
- ret = smd_named_open_on_edge("sys_mon", pdev->id, &ss->chan,
- ss, sysmon_notify);
- if (ret) {
- pr_err("SMD open failed\n");
- return -ENOSYS;
+ switch (ss->transport) {
+ case TRANSPORT_SMD:
+ if (pdev->id >= SMD_NUM_TYPE)
+ return -EINVAL;
+
+ ret = smd_named_open_on_edge("sys_mon", pdev->id, &ss->chan, ss,
+ sysmon_smd_notify);
+ if (ret) {
+ pr_err("SMD open failed\n");
+ return ret;
+ }
+
+ smd_disable_read_intr(ss->chan);
+ break;
+ case TRANSPORT_HSIC:
+ if (pdev->id < SMD_NUM_TYPE)
+ return -EINVAL;
+
+ ret = hsic_sysmon_open(HSIC_SYSMON_DEV_EXT_MODEM);
+ if (ret) {
+ pr_err("HSIC open failed\n");
+ return ret;
+ }
+ break;
+ default:
+ return -EINVAL;
}
- smd_disable_read_intr(ss->chan);
return 0;
}
static int __devexit sysmon_remove(struct platform_device *pdev)
{
- smd_close(subsys[ss_map[pdev->id]].chan);
+ struct sysmon_subsys *ss = &subsys[pdev->id];
+
+ switch (ss->transport) {
+ case TRANSPORT_SMD:
+ smd_close(ss->chan);
+ break;
+ case TRANSPORT_HSIC:
+ hsic_sysmon_close(HSIC_SYSMON_DEV_EXT_MODEM);
+ break;
+ }
+
return 0;
}
diff --git a/arch/arm/mach-msm/sysmon.h b/arch/arm/mach-msm/sysmon.h
index 429a155..d014187 100644
--- a/arch/arm/mach-msm/sysmon.h
+++ b/arch/arm/mach-msm/sysmon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,21 +15,25 @@
#ifndef __MSM_SYSMON_H
#define __MSM_SYSMON_H
+#include <mach/msm_smd.h>
#include <mach/subsystem_notif.h>
/**
* enum subsys_id - Destination subsystems for events.
*/
enum subsys_id {
- SYSMON_SS_MODEM,
- SYSMON_SS_LPASS,
- SYSMON_SS_WCNSS,
- SYSMON_SS_DSPS,
- SYSMON_SS_Q6FW,
+ /* SMD subsystems */
+ SYSMON_SS_MODEM = SMD_APPS_MODEM,
+ SYSMON_SS_LPASS = SMD_APPS_QDSP,
+ SYSMON_SS_WCNSS = SMD_APPS_WCNSS,
+ SYSMON_SS_DSPS = SMD_APPS_DSPS,
+ SYSMON_SS_Q6FW = SMD_APPS_Q6FW,
+
+ /* Non-SMD subsystems */
+ SYSMON_SS_EXT_MODEM = SMD_NUM_TYPE,
SYSMON_NUM_SS
};
-
/**
* sysmon_send_event() - Notify a subsystem of another's state change.
* @dest_ss: ID of subsystem the notification should be sent to.
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index c76bfd0..83f402b 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -988,17 +988,47 @@
return status;
}
+/* Find a memory structure attached to an adreno context */
+
+struct kgsl_memdesc *adreno_find_ctxtmem(struct kgsl_device *device,
+ unsigned int pt_base, unsigned int gpuaddr, unsigned int size)
+{
+ struct kgsl_context *context;
+ struct adreno_context *adreno_context = NULL;
+ int next = 0;
+
+ while (1) {
+ context = idr_get_next(&device->context_idr, &next);
+ if (context == NULL)
+ break;
+
+ adreno_context = (struct adreno_context *)context->devctxt;
+
+ if (kgsl_mmu_pt_equal(adreno_context->pagetable, pt_base)) {
+ struct kgsl_memdesc *desc;
+
+ desc = &adreno_context->gpustate;
+ if (kgsl_gpuaddr_in_memdesc(desc, gpuaddr, size))
+ return desc;
+
+ desc = &adreno_context->context_gmem_shadow.gmemshadow;
+ if (kgsl_gpuaddr_in_memdesc(desc, gpuaddr, size))
+ return desc;
+ }
+ next = next + 1;
+ }
+
+ return NULL;
+}
+
struct kgsl_memdesc *adreno_find_region(struct kgsl_device *device,
unsigned int pt_base,
unsigned int gpuaddr,
unsigned int size)
{
- struct kgsl_memdesc *result = NULL;
struct kgsl_mem_entry *entry;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_ringbuffer *ringbuffer = &adreno_dev->ringbuffer;
- struct kgsl_context *context;
- int next = 0;
if (kgsl_gpuaddr_in_memdesc(&ringbuffer->buffer_desc, gpuaddr, size))
return &ringbuffer->buffer_desc;
@@ -1018,34 +1048,7 @@
if (entry)
return &entry->memdesc;
- while (1) {
- struct adreno_context *adreno_context = NULL;
- context = idr_get_next(&device->context_idr, &next);
- if (context == NULL)
- break;
-
- adreno_context = (struct adreno_context *)context->devctxt;
-
- if (kgsl_mmu_pt_equal(adreno_context->pagetable, pt_base)) {
- struct kgsl_memdesc *desc;
-
- desc = &adreno_context->gpustate;
- if (kgsl_gpuaddr_in_memdesc(desc, gpuaddr, size)) {
- result = desc;
- return result;
- }
-
- desc = &adreno_context->context_gmem_shadow.gmemshadow;
- if (kgsl_gpuaddr_in_memdesc(desc, gpuaddr, size)) {
- result = desc;
- return result;
- }
- }
- next = next + 1;
- }
-
- return NULL;
-
+ return adreno_find_ctxtmem(device, pt_base, gpuaddr, size);
}
uint8_t *adreno_convertaddr(struct kgsl_device *device, unsigned int pt_base,
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 4885312..48e70c8 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -128,6 +128,9 @@
uint8_t *adreno_convertaddr(struct kgsl_device *device,
unsigned int pt_base, unsigned int gpuaddr, unsigned int size);
+struct kgsl_memdesc *adreno_find_ctxtmem(struct kgsl_device *device,
+ unsigned int pt_base, unsigned int gpuaddr, unsigned int size);
+
void *adreno_snapshot(struct kgsl_device *device, void *snapshot, int *remain,
int hang);
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index bca7040..e8cb734 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -657,17 +657,31 @@
parse_ibs = 0;
if (parse_ibs && adreno_cmd_is_ib(rbptr[index])) {
+ unsigned int ibaddr = rbptr[index + 1];
+ unsigned int ibsize = rbptr[index + 2];
+
/*
- * The IB from CP_IB1_BASE goes into the snapshot, all
+ * This will return non NULL if the IB happens to be
+ * part of the context memory (i.e - context switch
+ * command buffers)
+ */
+
+ struct kgsl_memdesc *memdesc =
+ adreno_find_ctxtmem(device, ptbase, ibaddr,
+ ibsize);
+
+ /*
+ * The IB from CP_IB1_BASE and the IBs for legacy
+ * context switch go into the snapshot all
* others get marked at GPU objects
*/
- if (rbptr[index + 1] == ibbase)
+
+ if (ibaddr == ibbase || memdesc != NULL)
push_object(device, SNAPSHOT_OBJ_TYPE_IB,
- ptbase, rbptr[index + 1],
- rbptr[index + 2]);
+ ptbase, ibaddr, ibsize);
else
- ib_add_gpu_object(device, ptbase,
- rbptr[index + 1], rbptr[index + 2]);
+ ib_add_gpu_object(device, ptbase, ibaddr,
+ ibsize);
}
index = index + 1;
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index a908a3f..a93529a 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -617,7 +617,6 @@
mutex_lock(&device->mutex);
device->pwrctrl.restore_slumber = 0;
kgsl_pwrctrl_wake(device);
- kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_TURBO);
mutex_unlock(&device->mutex);
kgsl_check_idle(device);
KGSL_PWR_WARN(device, "late resume end\n");
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 17f978e..6fa7da2 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -505,6 +505,7 @@
}
pwr->num_pwrlevels = pdata->num_levels;
pwr->active_pwrlevel = pdata->init_level;
+ pwr->default_pwrlevel = pdata->init_level;
for (i = 0; i < pdata->num_levels; i++) {
pwr->pwrlevels[i].gpu_freq =
(pdata->pwrlevel[i].gpu_freq > 0) ?
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 7dd429f..a677fec 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -46,6 +46,7 @@
struct kgsl_pwrlevel pwrlevels[KGSL_MAX_PWRLEVELS];
unsigned int active_pwrlevel;
int thermal_pwrlevel;
+ unsigned int default_pwrlevel;
unsigned int num_pwrlevels;
unsigned int interval_timeout;
bool strtstp_sleepwake;
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index 4b8c938..e0825c3 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.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
@@ -116,7 +116,7 @@
priv->governor == TZ_GOVERNOR_ONDEMAND &&
device->pwrctrl.restore_slumber == 0)
kgsl_pwrctrl_pwrlevel_change(device,
- device->pwrctrl.thermal_pwrlevel);
+ device->pwrctrl.default_pwrlevel);
}
static void tz_idle(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index c24576d..553dc60 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -28,6 +28,7 @@
unsigned int gpuaddr;
unsigned int ptbase;
unsigned int size;
+ unsigned int offset;
int type;
struct kgsl_mem_entry *entry;
struct list_head node;
@@ -229,7 +230,7 @@
* then offset the source pointer
*/
- offset = obj->gpuaddr - obj->entry->memdesc.gpuaddr;
+ offset = obj->offset;
/*
* Then adjust it to account for the offset for the output
@@ -348,6 +349,7 @@
obj->gpuaddr = gpuaddr;
obj->ptbase = ptbase;
obj->size = size;
+ obj->offset = offset;
list_add(&obj->node, &device->snapshot_obj_list);
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 212e5d5..741c3a1 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -1465,6 +1465,7 @@
xfr_buf[1] = GET_ABS_VAL(band_low);
xfr_buf[2] = RSH_DATA(band_high, 8);
xfr_buf[3] = GET_ABS_VAL(band_high);
+ xfr_buf[4] = 0; /* Active LOW */
retval = sync_write_xfr(radio, RADIO_CONFIG, xfr_buf);
if (retval < 0) {
FMDERR("Could not set regional settings\n");
@@ -3037,8 +3038,8 @@
} else if (ctrl->value == FM_ANALOG_PATH) {
FMDBG("Analog audio path enabled ...\n");
retval = tavarua_set_audio_path(
- TAVARUA_AUDIO_OUT_ANALOG_ON,
- TAVARUA_AUDIO_OUT_DIGITAL_OFF);
+ TAVARUA_AUDIO_OUT_DIGITAL_OFF,
+ TAVARUA_AUDIO_OUT_ANALOG_ON);
if (retval < 0) {
FMDERR("Error in tavarua_set_audio_path"
" %d\n", retval);
@@ -3891,10 +3892,27 @@
{
struct tavarua_device *radio = private_data;
int rx_on = radio->registers[RDCTRL] & FM_RECV;
+ int retval = 0;
if (!radio)
return -ENOMEM;
/* RX */
FMDBG("%s: digital: %d analog: %d\n", __func__, digital_on, analog_on);
+ if ((radio->pdata != NULL) && (radio->pdata->config_i2s_gpio != NULL)) {
+ if (digital_on) {
+ retval = radio->pdata->config_i2s_gpio(FM_I2S_ON);
+ if (retval) {
+ pr_err("%s: config_i2s_gpio failed\n",
+ __func__);
+ }
+ } else {
+ retval = radio->pdata->config_i2s_gpio(FM_I2S_OFF);
+ if (retval) {
+ pr_err("%s: config_i2s_gpio failed\n",
+ __func__);
+ }
+ }
+ }
+
SET_REG_FIELD(radio->registers[AUDIOCTRL],
((rx_on && analog_on) ? 1 : 0),
AUDIORX_ANALOG_OFFSET,
diff --git a/drivers/media/video/msm/sensors/mt9e013_v4l2.c b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
index e6e2d52..7f0fbc3 100644
--- a/drivers/media/video/msm/sensors/mt9e013_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
@@ -271,6 +271,8 @@
ARRAY_SIZE(mt9e013_prev_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
{&mt9e013_hfr60_settings[0],
ARRAY_SIZE(mt9e013_hfr60_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {&mt9e013_hfr60_settings[0],
+ ARRAY_SIZE(mt9e013_hfr60_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
{&mt9e013_hfr90_settings[0],
ARRAY_SIZE(mt9e013_hfr90_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
{&mt9e013_hfr120_settings[0],
@@ -310,6 +312,15 @@
.y_output = 0x212,
.line_length_pclk = 0x970,
.frame_length_lines = 0x2A1,
+ .vt_pixel_clk = 98400000,
+ .op_pixel_clk = 98400000,
+ .binning_factor = 1,
+ },
+ {
+ .x_output = 0x340,
+ .y_output = 0x212,
+ .line_length_pclk = 0x970,
+ .frame_length_lines = 0x2A1,
.vt_pixel_clk = 146400000,
.op_pixel_clk = 146400000,
.binning_factor = 1,
@@ -339,6 +350,7 @@
&mt9e013_csi_params,
&mt9e013_csi_params,
&mt9e013_csi_params,
+ &mt9e013_csi_params,
};
static struct msm_sensor_output_reg_addr_t mt9e013_reg_addr = {
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 50c115a..e1a6ffd 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -54,6 +54,7 @@
#include <mach/clk.h>
#include <mach/dma.h>
#include <mach/sdio_al.h>
+#include <mach/mpm.h>
#include "msm_sdcc.h"
#include "msm_sdcc_dml.h"
@@ -2395,6 +2396,37 @@
return rc;
}
+static int msmsdcc_cfg_mpm_sdiowakeup(struct msmsdcc_host *host,
+ unsigned mode)
+{
+ int ret = 0;
+ unsigned int pin = host->plat->mpm_sdiowakeup_int;
+
+ if (!pin)
+ return 0;
+
+ switch (mode) {
+ case SDC_DAT1_DISABLE:
+ ret = msm_mpm_enable_pin(pin, 0);
+ break;
+ case SDC_DAT1_ENABLE:
+ ret = msm_mpm_set_pin_type(pin, IRQ_TYPE_LEVEL_LOW);
+ ret = msm_mpm_enable_pin(pin, 1);
+ break;
+ case SDC_DAT1_ENWAKE:
+ ret = msm_mpm_set_pin_wake(pin, 1);
+ break;
+ case SDC_DAT1_DISWAKE:
+ ret = msm_mpm_set_pin_wake(pin, 0);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
static u32 msmsdcc_setup_pwr(struct msmsdcc_host *host, struct mmc_ios *ios)
{
u32 pwr = 0;
@@ -2415,9 +2447,7 @@
switch (ios->power_mode) {
case MMC_POWER_OFF:
pwr = MCI_PWR_OFF;
- if (host->plat->cfg_mpm_sdiowakeup)
- host->plat->cfg_mpm_sdiowakeup(
- mmc_dev(mmc), SDC_DAT1_DISABLE);
+ msmsdcc_cfg_mpm_sdiowakeup(host, SDC_DAT1_DISABLE);
/*
* As VDD pad rail is always on, set low voltage for VDD
* pad rail when slot is unused (when card is not present
@@ -2429,9 +2459,7 @@
case MMC_POWER_UP:
/* writing PWR_UP bit is redundant */
pwr = MCI_PWR_UP;
- if (host->plat->cfg_mpm_sdiowakeup)
- host->plat->cfg_mpm_sdiowakeup(
- mmc_dev(mmc), SDC_DAT1_ENABLE);
+ msmsdcc_cfg_mpm_sdiowakeup(host, SDC_DAT1_ENABLE);
msmsdcc_set_vddp_high_vol(host);
msmsdcc_setup_pins(host, true);
@@ -2519,9 +2547,7 @@
writel_relaxed(MCI_SDIOINTMASK,
host->base + MMCIMASK0);
mb();
- if (host->plat->cfg_mpm_sdiowakeup)
- host->plat->cfg_mpm_sdiowakeup(
- mmc_dev(mmc), SDC_DAT1_ENWAKE);
+ msmsdcc_cfg_mpm_sdiowakeup(host, SDC_DAT1_ENWAKE);
/* configure sdcc core interrupt as wakeup interrupt */
msmsdcc_enable_irq_wake(host);
} else {
@@ -2543,9 +2569,7 @@
*/
writel_relaxed(MCI_SDIOINTMASK, host->base + MMCICLEAR);
msmsdcc_sync_reg_wr(host);
- if (host->plat->cfg_mpm_sdiowakeup)
- host->plat->cfg_mpm_sdiowakeup(
- mmc_dev(mmc), SDC_DAT1_DISWAKE);
+ msmsdcc_cfg_mpm_sdiowakeup(host, SDC_DAT1_DISWAKE);
msmsdcc_disable_irq_wake(host);
} else if (!host->sdio_wakeupirq_disabled) {
disable_irq_nosync(host->plat->sdiowakeup_irq);
@@ -4571,7 +4595,7 @@
mmc->caps |= (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 |
MMC_CAP_SET_XPC_180);
- mmc->caps2 |= MMC_CAP2_BOOTPART_NOACC;
+ mmc->caps2 |= (MMC_CAP2_BOOTPART_NOACC | MMC_CAP2_DETECT_ON_ERR);
if (pdev->dev.of_node) {
if (of_get_property((&pdev->dev)->of_node,
"qcom,sdcc-hs200", NULL))
@@ -4642,7 +4666,7 @@
}
}
- if (plat->cfg_mpm_sdiowakeup) {
+ if (host->plat->mpm_sdiowakeup_int) {
wake_lock_init(&host->sdio_wlock, WAKE_LOCK_SUSPEND,
mmc_hostname(mmc));
}
@@ -5088,7 +5112,7 @@
* the SDIO work will be processed.
*/
if (mmc->card && mmc_card_sdio(mmc->card)) {
- if ((host->plat->cfg_mpm_sdiowakeup ||
+ if ((host->plat->mpm_sdiowakeup_int ||
host->plat->sdiowakeup_irq) &&
wake_lock_active(&host->sdio_wlock))
wake_lock_timeout(&host->sdio_wlock, 1);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 6b6b75c..41eeee1 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -2111,9 +2111,9 @@
} else {
pr_debug("chg_work cancel");
cancel_delayed_work_sync(&motg->chg_work);
- msm_otg_notify_charger(motg, 0);
motg->chg_state = USB_CHG_STATE_UNDEFINED;
motg->chg_type = USB_INVALID_CHARGER;
+ msm_otg_notify_charger(motg, 0);
msm_otg_reset(otg);
pm_runtime_put_noidle(otg->dev);
pm_runtime_suspend(otg->dev);
@@ -2152,11 +2152,11 @@
test_bit(ID_B, &motg->inputs) ||
!test_bit(B_SESS_VLD, &motg->inputs)) {
pr_debug("!id || id_a/b || !b_sess_vld\n");
+ motg->chg_state = USB_CHG_STATE_UNDEFINED;
+ motg->chg_type = USB_INVALID_CHARGER;
msm_otg_notify_charger(motg, 0);
srp_reqd = otg->gadget->otg_srp_reqd;
msm_otg_start_peripheral(otg, 0);
- motg->chg_state = USB_CHG_STATE_UNDEFINED;
- motg->chg_type = USB_INVALID_CHARGER;
if (test_bit(ID_B, &motg->inputs))
clear_bit(ID_B, &motg->inputs);
clear_bit(B_BUS_REQ, &motg->inputs);
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 562c0c8..b768784 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -467,6 +467,14 @@
{
/* empty */
}
+static inline void mdp4_dtv_overlay_blt_start(struct msm_fb_data_type *mfd)
+{
+ return;
+}
+static inline void mdp4_dtv_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+ return;
+}
#endif
void mdp4_dtv_set_black_screen(void);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 04d4ca4..0068c2a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -67,7 +67,7 @@
* It can be used to eliminate pops between different playback streams, e.g.
* between two audio tracks.
*/
-static int pmdown_time = 5000;
+static int pmdown_time;
module_param(pmdown_time, int, 0);
MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");