Merge changes Ib1cd158f,Ide80d824 into msm-3.0
* changes:
USB: EHCI: Add registers support for SMSC hsic hub
defconfig: msm8960: enable I2C support for smsc hsic hub
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 36a81b6..edb5cb5 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2561,7 +2561,6 @@
acpuclk_init(&acpuclk_8064_soc_data);
msm_spm_l2_init(msm_spm_l2_data);
msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
- msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
msm_pm_data);
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index e500632..37085f4 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -2076,7 +2076,6 @@
slim_register_board_info(msm_slim_devices,
ARRAY_SIZE(msm_slim_devices));
msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
- msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
msm_pm_data);
change_memory_power = &msm8930_change_memory_power;
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 9fa7c0b..94166c4 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2847,7 +2847,6 @@
slim_register_board_info(msm_slim_devices,
ARRAY_SIZE(msm_slim_devices));
msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
- msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
msm_pm_data);
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
@@ -2879,7 +2878,6 @@
slim_register_board_info(msm_slim_devices,
ARRAY_SIZE(msm_slim_devices));
msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
- msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
msm_pm_data);
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
@@ -2958,7 +2956,6 @@
ARRAY_SIZE(msm_slim_devices));
msm8960_init_dsps();
msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
- msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
msm_pm_data);
change_memory_power = &msm8960_change_memory_power;
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 8a8e575..595b7d5 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -796,7 +796,6 @@
slim_register_board_info(msm_slim_devices,
ARRAY_SIZE(msm_slim_devices));
msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
- msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
msm_pm_data);
msm_pm_boot_pdata.p_addr = allocate_contiguous_ebi_nomap(SZ_8, SZ_64K);
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 39061a6..3cecfa7 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -10508,7 +10508,6 @@
#endif
msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
- msm_pm_set_rpm_wakeup_irq(RPM_SCSS_CPU0_WAKE_UP_IRQ);
msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
msm_pm_data);
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 9ce10df9..35a54da 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -3345,7 +3345,6 @@
F_GFX3D(200000000, pll2, 1, 4),
F_GFX3D(228571000, pll2, 2, 7),
F_GFX3D(266667000, pll2, 1, 3),
- F_GFX3D(300000000, pll3, 1, 4),
F_GFX3D(320000000, pll2, 2, 5),
F_GFX3D(400000000, pll2, 1, 2),
F_GFX3D(450000000, pll15, 1, 2),
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index 6512872..63534a4 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -88,13 +88,13 @@
struct cpufreq_work_struct *cpu_work = NULL;
cpumask_var_t mask;
- if (!alloc_cpumask_var(&mask, GFP_KERNEL))
- return -ENOMEM;
-
if (!cpu_active(policy->cpu)) {
pr_info("cpufreq: cpu %d is not active.\n", policy->cpu);
return -ENODEV;
}
+
+ if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+ return -ENOMEM;
#endif
mutex_lock(&per_cpu(cpufreq_suspend, policy->cpu).suspend_mutex);
@@ -138,13 +138,15 @@
wait_for_completion(&cpu_work->complete);
}
- free_cpumask_var(mask);
ret = cpu_work->status;
#else
ret = set_cpu_freq(policy, table[index].frequency);
#endif
done:
+#ifdef CONFIG_SMP
+ free_cpumask_var(mask);
+#endif
mutex_unlock(&per_cpu(cpufreq_suspend, policy->cpu).suspend_mutex);
return ret;
}
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 092a4f5..5d6a3ae 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -1730,6 +1730,7 @@
},
.irq_ack = RPM_APCC_CPU0_GP_HIGH_IRQ,
.irq_err = RPM_APCC_CPU0_GP_LOW_IRQ,
+ .irq_wakeup = RPM_APCC_CPU0_WAKE_UP_IRQ,
.ipc_rpm_reg = MSM_APCS_GCC_BASE + 0x008,
.ipc_rpm_val = 4,
.target_id = {
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index 583c12d..85e927e 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -40,6 +40,7 @@
},
.irq_ack = RPM_APCC_CPU0_GP_HIGH_IRQ,
.irq_err = RPM_APCC_CPU0_GP_LOW_IRQ,
+ .irq_wakeup = RPM_APCC_CPU0_WAKE_UP_IRQ,
.ipc_rpm_reg = MSM_APCS_GCC_BASE + 0x008,
.ipc_rpm_val = 4,
.target_id = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 63c799e..375aa8d 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -2984,6 +2984,7 @@
},
.irq_ack = RPM_APCC_CPU0_GP_HIGH_IRQ,
.irq_err = RPM_APCC_CPU0_GP_LOW_IRQ,
+ .irq_wakeup = RPM_APCC_CPU0_WAKE_UP_IRQ,
.ipc_rpm_reg = MSM_APCS_GCC_BASE + 0x008,
.ipc_rpm_val = 4,
.target_id = {
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 3c671ed..60bcdce 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -905,6 +905,7 @@
},
.irq_ack = RPM_APCC_CPU0_GP_HIGH_IRQ,
.irq_err = RPM_APCC_CPU0_GP_LOW_IRQ,
+ .irq_wakeup = RPM_APCC_CPU0_WAKE_UP_IRQ,
.ipc_rpm_reg = MSM_APCS_GCC_BASE + 0x008,
.ipc_rpm_val = 4,
.target_id = {
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index bedd133..608ca27 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -2582,6 +2582,7 @@
},
.irq_ack = RPM_SCSS_CPU0_GP_HIGH_IRQ,
.irq_err = RPM_SCSS_CPU0_GP_LOW_IRQ,
+ .irq_wakeup = RPM_SCSS_CPU0_WAKE_UP_IRQ,
.ipc_rpm_reg = MSM_GCC_BASE + 0x008,
.ipc_rpm_val = 4,
.target_id = {
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb.h b/arch/arm/mach-msm/include/mach/msm_hsusb.h
index 8dd761c..3069916 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb.h
@@ -20,6 +20,8 @@
#include <linux/types.h>
#include <linux/pm_qos_params.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
#define PHY_TYPE_MASK 0x0F
#define PHY_TYPE_MODE 0xF0
@@ -60,6 +62,21 @@
#define phy_id_state_c(ints) (phy_id_state((ints)) == PHY_ID_C)
#endif
+/*
+ * The following are bit fields describing the usb_request.udc_priv word.
+ * These bit fields are set by function drivers that wish to queue
+ * usb_requests with sps/bam parameters.
+ */
+#define MSM_PIPE_ID_MASK (0x1F)
+#define MSM_TX_PIPE_ID_OFS (16)
+#define MSM_SPS_MODE BIT(5)
+#define MSM_IS_FINITE_TRANSFER BIT(6)
+#define MSM_PRODUCER BIT(7)
+#define MSM_DISABLE_WB BIT(8)
+#define MSM_ETD_IOC BIT(9)
+#define MSM_INTERNAL_MEM BIT(10)
+#define MSM_VENDOR_ID BIT(16)
+
/* used to detect the OTG Mode */
enum otg_mode {
OTG_ID = 0, /* ID pin detection */
@@ -185,4 +202,8 @@
struct clk *ebi1_clk;
};
+int msm_ep_config(struct usb_ep *ep);
+int msm_ep_unconfig(struct usb_ep *ep);
+int msm_data_fifo_config(struct usb_ep *ep, u32 addr, u32 size);
+
#endif
diff --git a/arch/arm/mach-msm/include/mach/rpm.h b/arch/arm/mach-msm/include/mach/rpm.h
index 140b7c9..98621be 100644
--- a/arch/arm/mach-msm/include/mach/rpm.h
+++ b/arch/arm/mach-msm/include/mach/rpm.h
@@ -883,6 +883,7 @@
void __iomem *reg_base_addrs[MSM_RPM_PAGE_COUNT];
unsigned int irq_ack;
unsigned int irq_err;
+ unsigned int irq_wakeup;
void *ipc_rpm_reg;
unsigned int ipc_rpm_val;
struct msm_rpm_map_data target_id[MSM_RPM_ID_LAST];
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 6de0660..40ddf8e 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -79,7 +79,6 @@
*****************************************************************************/
static struct msm_pm_platform_data *msm_pm_modes;
-static int rpm_cpu0_wakeup_irq;
void __init msm_pm_set_platform_data(
struct msm_pm_platform_data *data, int count)
@@ -88,11 +87,6 @@
msm_pm_modes = data;
}
-void __init msm_pm_set_rpm_wakeup_irq(unsigned int irq)
-{
- rpm_cpu0_wakeup_irq = irq;
-}
-
enum {
MSM_PM_MODE_ATTR_SUSPEND,
MSM_PM_MODE_ATTR_IDLE,
@@ -763,15 +757,6 @@
return collapsed;
}
-static irqreturn_t msm_pm_rpm_wakeup_interrupt(int irq, void *dev_id)
-{
- if (dev_id != &msm_pm_rpm_wakeup_interrupt)
- return IRQ_NONE;
-
- return IRQ_HANDLED;
-}
-
-
/******************************************************************************
* External Idle/Suspend Functions
*****************************************************************************/
@@ -1167,7 +1152,6 @@
#ifdef CONFIG_MSM_IDLE_STATS
struct proc_dir_entry *d_entry;
#endif
- int ret;
/* Page table for cores to come back up safely. */
pc_pgd = pgd_alloc(&init_mm);
@@ -1205,22 +1189,6 @@
clean_caches((unsigned long)&msm_pm_pc_pgd, sizeof(msm_pm_pc_pgd),
virt_to_phys(&msm_pm_pc_pgd));
- ret = request_irq(rpm_cpu0_wakeup_irq,
- msm_pm_rpm_wakeup_interrupt, IRQF_TRIGGER_RISING,
- "pm_drv", msm_pm_rpm_wakeup_interrupt);
- if (ret) {
- pr_err("%s: failed to request irq %u: %d\n",
- __func__, rpm_cpu0_wakeup_irq, ret);
- return ret;
- }
-
- ret = irq_set_irq_wake(rpm_cpu0_wakeup_irq, 1);
- if (ret) {
- pr_err("%s: failed to set wakeup irq %u: %d\n",
- __func__, rpm_cpu0_wakeup_irq, ret);
- return ret;
- }
-
#ifdef CONFIG_MSM_IDLE_STATS
for_each_possible_cpu(cpu) {
struct msm_pm_time_stats *stats =
diff --git a/arch/arm/mach-msm/rpm.c b/arch/arm/mach-msm/rpm.c
index b0fa3d2..44e50dd 100644
--- a/arch/arm/mach-msm/rpm.c
+++ b/arch/arm/mach-msm/rpm.c
@@ -54,7 +54,6 @@
static uint32_t msm_rpm_sel_mask_size;
static struct msm_rpm_platform_data msm_rpm_data;
-
static DEFINE_MUTEX(msm_rpm_mutex);
static DEFINE_SPINLOCK(msm_rpm_lock);
static DEFINE_SPINLOCK(msm_rpm_irq_lock);
@@ -936,9 +935,16 @@
}
}
+static irqreturn_t msm_pm_rpm_wakeup_interrupt(int irq, void *dev_id)
+{
+ if (dev_id != &msm_pm_rpm_wakeup_interrupt)
+ return IRQ_NONE;
+
+ return IRQ_HANDLED;
+}
+
int __init msm_rpm_init(struct msm_rpm_platform_data *data)
{
- unsigned int irq;
int rc;
memcpy(&msm_rpm_data, data, sizeof(struct msm_rpm_platform_data));
@@ -971,21 +977,19 @@
msm_rpm_write(MSM_RPM_PAGE_CTRL,
target_ctrl(MSM_RPM_CTRL_VERSION_BUILD), msm_rpm_data.ver[2]);
- irq = data->irq_ack;
-
- rc = request_irq(irq, msm_rpm_ack_interrupt,
+ rc = request_irq(data->irq_ack, msm_rpm_ack_interrupt,
IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
"rpm_drv", msm_rpm_ack_interrupt);
if (rc) {
pr_err("%s: failed to request irq %d: %d\n",
- __func__, irq, rc);
+ __func__, data->irq_ack, rc);
return rc;
}
- rc = irq_set_irq_wake(irq, 1);
+ rc = irq_set_irq_wake(data->irq_ack, 1);
if (rc) {
pr_err("%s: failed to set wakeup irq %u: %d\n",
- __func__, irq, rc);
+ __func__, data->irq_ack, rc);
return rc;
}
@@ -997,6 +1001,22 @@
return rc;
}
+ rc = request_irq(data->irq_wakeup,
+ msm_pm_rpm_wakeup_interrupt, IRQF_TRIGGER_RISING,
+ "pm_drv", msm_pm_rpm_wakeup_interrupt);
+ if (rc) {
+ pr_err("%s: failed to request irq %u: %d\n",
+ __func__, data->irq_wakeup, rc);
+ return rc;
+ }
+
+ rc = irq_set_irq_wake(data->irq_wakeup, 1);
+ if (rc) {
+ pr_err("%s: failed to set wakeup irq %u: %d\n",
+ __func__, data->irq_wakeup, rc);
+ return rc;
+ }
+
msm_rpm_populate_map(data);
return platform_driver_register(&msm_rpm_platform_driver);
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 5f835a2..430a4c0 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -40,7 +40,7 @@
#ifdef CONFIG_ARCH_FSM9XXX
#define NUM_SMD_PKT_PORTS 4
#else
-#define NUM_SMD_PKT_PORTS 13
+#define NUM_SMD_PKT_PORTS 14
#endif
#define LOOPBACK_INX (NUM_SMD_PKT_PORTS - 1)
@@ -657,6 +657,7 @@
"smd_sns_dsps",
"apr_apps2",
"smdcntl8",
+ "smd_sns_adsp",
"smd_pkt_loopback",
};
@@ -673,6 +674,7 @@
"SENSOR",
"apr_apps2",
"DATA40_CNTL",
+ "SENSOR",
"LOOPBACK",
};
@@ -689,6 +691,7 @@
SMD_APPS_DSPS,
SMD_APPS_QDSP,
SMD_APPS_MODEM,
+ SMD_APPS_QDSP,
SMD_APPS_MODEM,
};
#endif
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index 59013e3..be6c8e4 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -106,12 +106,19 @@
#define checkoffset(offset, size, max_size) \
((size) > (max_size) || (offset) > ((max_size) - (size)))
+struct msm_rotator_fd_info {
+ int pid;
+ int ref_cnt;
+ struct list_head list;
+};
+
struct msm_rotator_dev {
void __iomem *io_base;
int irq;
struct msm_rotator_img_info *img_info[MAX_SESSIONS];
struct clk *core_clk;
- int pid_list[MAX_SESSIONS];
+ struct msm_rotator_fd_info *fd_info[MAX_SESSIONS];
+ struct list_head fd_list;
struct clk *pclk;
int rot_clk_state;
struct regulator *regulator;
@@ -1162,7 +1169,8 @@
}
-static int msm_rotator_start(unsigned long arg, int pid)
+static int msm_rotator_start(unsigned long arg,
+ struct msm_rotator_fd_info *fd_info)
{
struct msm_rotator_img_info info;
int rc = 0;
@@ -1256,7 +1264,7 @@
(unsigned int)msm_rotator_dev->img_info[s]
)) {
*(msm_rotator_dev->img_info[s]) = info;
- msm_rotator_dev->pid_list[s] = pid;
+ msm_rotator_dev->fd_info[s] = fd_info;
if (msm_rotator_dev->last_session_idx == s)
msm_rotator_dev->last_session_idx =
@@ -1284,7 +1292,7 @@
info.session_id = (unsigned int)
msm_rotator_dev->img_info[first_free_index];
*(msm_rotator_dev->img_info[first_free_index]) = info;
- msm_rotator_dev->pid_list[first_free_index] = pid;
+ msm_rotator_dev->fd_info[first_free_index] = fd_info;
if (copy_to_user((void __user *)arg, &info, sizeof(info)))
rc = -EFAULT;
@@ -1319,7 +1327,7 @@
INVALID_SESSION;
kfree(msm_rotator_dev->img_info[s]);
msm_rotator_dev->img_info[s] = NULL;
- msm_rotator_dev->pid_list[s] = 0;
+ msm_rotator_dev->fd_info[s] = NULL;
break;
}
}
@@ -1337,24 +1345,45 @@
static int
msm_rotator_open(struct inode *inode, struct file *filp)
{
- int *id;
+ struct msm_rotator_fd_info *tmp, *fd_info = NULL;
int i;
if (filp->private_data)
return -EBUSY;
mutex_lock(&msm_rotator_dev->rotator_lock);
- id = &msm_rotator_dev->pid_list[0];
- for (i = 0; i < MAX_SESSIONS; i++, id++) {
- if (*id == 0)
+ for (i = 0; i < MAX_SESSIONS; i++) {
+ if (msm_rotator_dev->fd_info[i] == NULL)
break;
}
+
+ if (i == MAX_SESSIONS) {
+ mutex_unlock(&msm_rotator_dev->rotator_lock);
+ return -EBUSY;
+ }
+
+ list_for_each_entry(tmp, &msm_rotator_dev->fd_list, list) {
+ if (tmp->pid == current->pid) {
+ fd_info = tmp;
+ break;
+ }
+ }
+
+ if (!fd_info) {
+ fd_info = kzalloc(sizeof(*fd_info), GFP_KERNEL);
+ if (!fd_info) {
+ mutex_unlock(&msm_rotator_dev->rotator_lock);
+ pr_err("%s: insufficient memory to alloc resources\n",
+ __func__);
+ return -ENOMEM;
+ }
+ list_add(&fd_info->list, &msm_rotator_dev->fd_list);
+ fd_info->pid = current->pid;
+ }
+ fd_info->ref_cnt++;
mutex_unlock(&msm_rotator_dev->rotator_lock);
- if (i == MAX_SESSIONS)
- return -EBUSY;
-
- filp->private_data = (void *)current->pid;
+ filp->private_data = fd_info;
return 0;
}
@@ -1362,21 +1391,33 @@
static int
msm_rotator_close(struct inode *inode, struct file *filp)
{
+ struct msm_rotator_fd_info *fd_info;
int s;
- int pid;
- pid = (int)filp->private_data;
+ fd_info = (struct msm_rotator_fd_info *)filp->private_data;
+
mutex_lock(&msm_rotator_dev->rotator_lock);
+ if (--fd_info->ref_cnt > 0) {
+ mutex_unlock(&msm_rotator_dev->rotator_lock);
+ return 0;
+ }
+
for (s = 0; s < MAX_SESSIONS; s++) {
if (msm_rotator_dev->img_info[s] != NULL &&
- msm_rotator_dev->pid_list[s] == pid) {
+ msm_rotator_dev->fd_info[s] == fd_info) {
+ pr_debug("%s: freeing rotator session %p (pid %d)\n",
+ __func__, msm_rotator_dev->img_info[s],
+ fd_info->pid);
kfree(msm_rotator_dev->img_info[s]);
msm_rotator_dev->img_info[s] = NULL;
+ msm_rotator_dev->fd_info[s] = NULL;
if (msm_rotator_dev->last_session_idx == s)
msm_rotator_dev->last_session_idx =
INVALID_SESSION;
}
}
+ list_del(&fd_info->list);
+ kfree(fd_info);
mutex_unlock(&msm_rotator_dev->rotator_lock);
return 0;
@@ -1385,16 +1426,16 @@
static long msm_rotator_ioctl(struct file *file, unsigned cmd,
unsigned long arg)
{
- int pid;
+ struct msm_rotator_fd_info *fd_info;
if (_IOC_TYPE(cmd) != MSM_ROTATOR_IOCTL_MAGIC)
return -ENOTTY;
- pid = (int)file->private_data;
+ fd_info = (struct msm_rotator_fd_info *)file->private_data;
switch (cmd) {
case MSM_ROTATOR_IOCTL_START:
- return msm_rotator_start(arg, pid);
+ return msm_rotator_start(arg, fd_info);
case MSM_ROTATOR_IOCTL_ROTATE:
return msm_rotator_do_rotate(arg);
case MSM_ROTATOR_IOCTL_FINISH:
@@ -1437,6 +1478,7 @@
msm_rotator_dev->imem_owner = IMEM_NO_OWNER;
mutex_init(&msm_rotator_dev->imem_lock);
+ INIT_LIST_HEAD(&msm_rotator_dev->fd_list);
msm_rotator_dev->imem_clk_state = CLK_DIS;
INIT_DELAYED_WORK(&msm_rotator_dev->imem_clk_work,
msm_rotator_imem_clk_work_f);
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index ba39fe1..21774fa 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1011,6 +1011,10 @@
if (kgsl_gpuaddr_in_memdesc(&device->memstore, gpuaddr, size))
return &device->memstore;
+ if (kgsl_gpuaddr_in_memdesc(&device->mmu.setstate_memory, gpuaddr,
+ size))
+ return &device->mmu.setstate_memory;
+
entry = kgsl_get_mem_entry(pt_base, gpuaddr, size);
if (entry)
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 3e8d599..e0fa962 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -623,8 +623,6 @@
msm_sensor_disable_i2c_mux(
data->sensor_platform_info->i2c_conf);
- s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
- msleep(20);
if (data->sensor_platform_info->ext_power_ctrl != NULL)
data->sensor_platform_info->ext_power_ctrl(0);
msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 3622ff3..122c891 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2213,24 +2213,28 @@
return 0;
}
+/*
+ * Any function calling msmsdcc_setup_clocks must
+ * acquire clk_mutex. May sleep.
+ */
static inline void msmsdcc_setup_clocks(struct msmsdcc_host *host, bool enable)
{
if (enable) {
if (!IS_ERR_OR_NULL(host->dfab_pclk))
- clk_enable(host->dfab_pclk);
+ clk_prepare_enable(host->dfab_pclk);
if (!IS_ERR(host->pclk))
- clk_enable(host->pclk);
- clk_enable(host->clk);
+ clk_prepare_enable(host->pclk);
+ clk_prepare_enable(host->clk);
mb();
msmsdcc_delay(host);
} else {
mb();
msmsdcc_delay(host);
- clk_disable(host->clk);
+ clk_disable_unprepare(host->clk);
if (!IS_ERR(host->pclk))
- clk_disable(host->pclk);
+ clk_disable_unprepare(host->pclk);
if (!IS_ERR_OR_NULL(host->dfab_pclk))
- clk_disable(host->dfab_pclk);
+ clk_disable_unprepare(host->dfab_pclk);
}
}
@@ -2541,7 +2545,6 @@
unsigned long flags;
unsigned int clock;
- DBG(host, "ios->clock = %u\n", ios->clock);
/*
* Disable SDCC core interrupt until set_ios is completed.
@@ -2549,8 +2552,12 @@
* when turning on/off the clocks. One possible
* scenario is SDIO operational interrupt while the clock
* is turned off.
+ * host->lock is being released intermittently below.
+ * Thus, prevent concurrent access to host.
*/
+ mutex_lock(&host->clk_mutex);
+ DBG(host, "ios->clock = %u\n", ios->clock);
spin_lock_irqsave(&host->lock, flags);
if (!host->sdcc_irq_disabled) {
spin_unlock_irqrestore(&host->lock, flags);
@@ -2565,7 +2572,9 @@
spin_lock_irqsave(&host->lock, flags);
if (ios->clock) {
if (!host->clks_on) {
+ spin_unlock_irqrestore(&host->lock, flags);
msmsdcc_setup_clocks(host, true);
+ spin_lock_irqsave(&host->lock, flags);
host->clks_on = 1;
writel_relaxed(host->mci_irqenable,
host->base + MMCIMASK0);
@@ -2596,7 +2605,9 @@
}
if (clock != host->clk_rate) {
+ spin_unlock_irqrestore(&host->lock, flags);
rc = clk_set_rate(host->clk, clock);
+ spin_lock_irqsave(&host->lock, flags);
if (rc < 0)
pr_err("%s: failed to set clk rate %u\n",
mmc_hostname(mmc), clock);
@@ -2667,7 +2678,13 @@
if (!(clk & MCI_CLK_ENABLE) && host->clks_on) {
msmsdcc_cfg_sdio_wakeup(host, true);
+ spin_unlock_irqrestore(&host->lock, flags);
+ /*
+ * May get a wake-up interrupt the instant we disable the
+ * clocks. This would disable the wake-up interrupt.
+ */
msmsdcc_setup_clocks(host, false);
+ spin_lock_irqsave(&host->lock, flags);
host->clks_on = 0;
}
@@ -2682,6 +2699,7 @@
}
spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->clk_mutex);
}
int msmsdcc_set_pwrsave(struct mmc_host *mmc, int pwrsave)
@@ -2832,12 +2850,16 @@
msmsdcc_pm_qos_update_latency(host, 1);
+ mutex_lock(&host->clk_mutex);
spin_lock_irqsave(&host->lock, flags);
if (!host->clks_on) {
+ spin_unlock_irqrestore(&host->lock, flags);
msmsdcc_setup_clocks(host, true);
+ spin_lock_irqsave(&host->lock, flags);
host->clks_on = 1;
}
spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->clk_mutex);
return 0;
}
@@ -2852,12 +2874,16 @@
if (mmc->card && mmc_card_sdio(mmc->card))
return 0;
+ mutex_lock(&host->clk_mutex);
spin_lock_irqsave(&host->lock, flags);
if (host->clks_on) {
+ spin_unlock_irqrestore(&host->lock, flags);
msmsdcc_setup_clocks(host, false);
+ spin_lock_irqsave(&host->lock, flags);
host->clks_on = 0;
}
spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->clk_mutex);
return 0;
}
@@ -3510,18 +3536,8 @@
host->sdio_wakeupirq_disabled = 1;
}
if (host->plat->is_sdio_al_client) {
- if (!host->clks_on) {
- msmsdcc_setup_clocks(host, true);
- host->clks_on = 1;
- }
- if (host->sdcc_irq_disabled) {
- writel_relaxed(host->mci_irqenable,
- host->base + MMCIMASK0);
- mb();
- enable_irq(host->core_irqres->start);
- host->sdcc_irq_disabled = 0;
- }
wake_lock(&host->sdio_wlock);
+ mmc_signal_sdio_irq(host->mmc);
}
spin_unlock(&host->lock);
@@ -4380,6 +4396,7 @@
host->dmares = dmares;
host->dma_crci_res = dma_crci_res;
spin_lock_init(&host->lock);
+ mutex_init(&host->clk_mutex);
#ifdef CONFIG_MMC_EMBEDDED_SDIO
if (plat->embedded_sdio)
@@ -4416,7 +4433,7 @@
ret = clk_set_rate(host->dfab_pclk, 64000000);
if (ret)
goto dfab_pclk_put;
- ret = clk_enable(host->dfab_pclk);
+ ret = clk_prepare_enable(host->dfab_pclk);
if (ret)
goto dfab_pclk_put;
} else
@@ -4428,7 +4445,7 @@
*/
host->pclk = clk_get(&pdev->dev, "iface_clk");
if (!IS_ERR(host->pclk)) {
- ret = clk_enable(host->pclk);
+ ret = clk_prepare_enable(host->pclk);
if (ret)
goto pclk_put;
@@ -4450,7 +4467,7 @@
goto clk_put;
}
- ret = clk_enable(host->clk);
+ ret = clk_prepare_enable(host->clk);
if (ret)
goto clk_put;
@@ -4771,12 +4788,12 @@
clk_put(host->clk);
pclk_disable:
if (!IS_ERR(host->pclk))
- clk_disable(host->pclk);
+ clk_disable_unprepare(host->pclk);
pclk_put:
if (!IS_ERR(host->pclk))
clk_put(host->pclk);
if (!IS_ERR_OR_NULL(host->dfab_pclk))
- clk_disable(host->dfab_pclk);
+ clk_disable_unprepare(host->dfab_pclk);
dfab_pclk_put:
if (!IS_ERR_OR_NULL(host->dfab_pclk))
clk_put(host->dfab_pclk);
@@ -4874,6 +4891,7 @@
struct msmsdcc_host *host = mmc_priv(mmc);
unsigned long flags;
+ mutex_lock(&host->clk_mutex);
spin_lock_irqsave(&host->lock, flags);
pr_debug("%s: %sabling LPM\n", mmc_hostname(mmc),
enable ? "En" : "Dis");
@@ -4886,7 +4904,9 @@
}
if (host->clks_on) {
+ spin_unlock_irqrestore(&host->lock, flags);
msmsdcc_setup_clocks(host, false);
+ spin_lock_irqsave(&host->lock, flags);
host->clks_on = 0;
}
@@ -4919,7 +4939,9 @@
}
if (!host->clks_on) {
+ spin_unlock_irqrestore(&host->lock, flags);
msmsdcc_setup_clocks(host, true);
+ spin_lock_irqsave(&host->lock, flags);
host->clks_on = 1;
}
@@ -4932,6 +4954,7 @@
}
}
spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->clk_mutex);
return 0;
}
#else
@@ -5121,7 +5144,7 @@
* during suspend and not allowing TCXO.
*/
- if (host->clks_on) {
+ if (host->clks_on && !host->plat->is_sdio_al_client) {
pr_warn("%s: clocks are on after suspend, aborting system "
"suspend\n", mmc_hostname(mmc));
rc = -EAGAIN;
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 832e437..406af4f 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -399,6 +399,7 @@
bool sdcc_irq_disabled;
bool sdcc_suspended;
bool sdio_wakeupirq_disabled;
+ struct mutex clk_mutex;
};
int msmsdcc_set_pwrsave(struct mmc_host *mmc, int pwrsave);
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index 29968a6..5bc8e1b 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -833,7 +833,7 @@
}
#if defined(CONFIG_DEBUG_FS)
-#define DEBUG_BUF_SIZE 1024
+#define DEBUG_BUF_SIZE 4096
static ssize_t rmnet_usb_ctrl_read_stats(struct file *file, char __user *ubuf,
size_t count, loff_t *ppos)
{
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 1454ca9..d24ce3f 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -1223,9 +1223,19 @@
/ (high_voltage - low_voltage);
}
+static int get_prop_batt_present(struct pm8921_chg_chip *chip)
+{
+ return pm_chg_get_rt_status(chip, BATT_INSERTED_IRQ);
+}
+
static int get_prop_batt_capacity(struct pm8921_chg_chip *chip)
{
- int percent_soc = pm8921_bms_get_percent_charge();
+ int percent_soc;
+
+ if (!get_prop_batt_present(chip))
+ percent_soc = voltage_based_capacity(chip);
+ else
+ percent_soc = pm8921_bms_get_percent_charge();
if (percent_soc == -ENXIO)
percent_soc = voltage_based_capacity(chip);
@@ -1278,11 +1288,6 @@
return POWER_SUPPLY_HEALTH_GOOD;
}
-static int get_prop_batt_present(struct pm8921_chg_chip *chip)
-{
- return pm_chg_get_rt_status(chip, BATT_INSERTED_IRQ);
-}
-
static int get_prop_charge_type(struct pm8921_chg_chip *chip)
{
int temp;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index d1299d4..4e6091e 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -20,20 +20,736 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/usb/msm_hsusb.h>
#include <linux/delay.h>
#include <linux/of.h>
+#include <linux/list.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/msm_hsusb.h>
+
+#include "core.h"
+#include "gadget.h"
+
+/**
+ * USB DBM Hardware registers.
+ *
+ */
+#define DBM_EP_CFG(n) (0x00 + 4 * (n))
+#define DBM_DATA_FIFO(n) (0x10 + 4 * (n))
+#define DBM_DATA_FIFO_SIZE(n) (0x20 + 4 * (n))
+#define DBM_DATA_FIFO_EN (0x30)
+#define DBM_GEVNTADR (0x34)
+#define DBM_GEVNTSIZ (0x38)
+#define DBM_DBG_CNFG (0x3C)
+#define DBM_HW_TRB0_EP(n) (0x40 + 4 * (n))
+#define DBM_HW_TRB1_EP(n) (0x50 + 4 * (n))
+#define DBM_HW_TRB2_EP(n) (0x60 + 4 * (n))
+#define DBM_HW_TRB3_EP(n) (0x70 + 4 * (n))
+#define DBM_PIPE_CFG (0x80)
+#define DBM_SOFT_RESET (0x84)
+
+/**
+ * USB DBM Hardware registers bitmask.
+ *
+ */
+/* DBM_EP_CFG */
+#define DBM_EN_EP 0x00000000
+#define DBM_USB3_EP_NUM 0x0000003E
+#define DBM_BAM_PIPE_NUM 0x000000C0
+#define DBM_PRODUCER 0x00000100
+#define DBM_DISABLE_WB 0x00000200
+#define DBM_INT_RAM_ACC 0x00000400
+
+/* DBM_DATA_FIFO_SIZE */
+#define DBM_DATA_FIFO_SIZE_MASK 0x0000ffff
+
+/* DBM_GEVNTSIZ */
+#define DBM_GEVNTSIZ_MASK 0x0000ffff
+
+/* DBM_DBG_CNFG */
+#define DBM_ENABLE_IOC_MASK 0x0000000f
+
+/* DBM_SOFT_RESET */
+#define DBM_SFT_RST_EP0 0x00000001
+#define DBM_SFT_RST_EP1 0x00000002
+#define DBM_SFT_RST_EP2 0x00000004
+#define DBM_SFT_RST_EP3 0x00000008
+#define DBM_SFT_RST_EPS 0x0000000F
+#define DBM_SFT_RST 0x80000000
#define DBM_MAX_EPS 4
+struct dwc3_msm_req_complete {
+ struct list_head list_item;
+ struct usb_request *req;
+ void (*orig_complete)(struct usb_ep *ep,
+ struct usb_request *req);
+};
+
struct dwc3_msm {
struct platform_device *dwc3;
struct device *dev;
void __iomem *base;
u32 resource_size;
int dbm_num_eps;
+ u8 ep_num_mapping[DBM_MAX_EPS];
+ const struct usb_ep_ops *original_ep_ops[DWC3_ENDPOINTS_NUM];
+ struct list_head req_complete_list;
};
+static struct dwc3_msm *context;
+
+/**
+ *
+ * Read register with debug info.
+ *
+ * @base - DWC3 base virtual address.
+ * @offset - register offset.
+ *
+ * @return u32
+ */
+static inline u32 dwc3_msm_read_reg(void *base, u32 offset)
+{
+ u32 val = ioread32(base + offset);
+ return val;
+}
+
+/**
+ * Read register masked field with debug info.
+ *
+ * @base - DWC3 base virtual address.
+ * @offset - register offset.
+ * @mask - register bitmask.
+ *
+ * @return u32
+ */
+static inline u32 dwc3_msm_read_reg_field(void *base,
+ u32 offset,
+ const u32 mask)
+{
+ u32 shift = find_first_bit((void *)&mask, 32);
+ u32 val = ioread32(base + offset);
+ val &= mask; /* clear other bits */
+ val >>= shift;
+ return val;
+}
+
+/**
+ *
+ * Write register with debug info.
+ *
+ * @base - DWC3 base virtual address.
+ * @offset - register offset.
+ * @val - value to write.
+ *
+ */
+static inline void dwc3_msm_write_reg(void *base, u32 offset, u32 val)
+{
+ iowrite32(val, base + offset);
+}
+
+/**
+ * Write register masked field with debug info.
+ *
+ * @base - DWC3 base virtual address.
+ * @offset - register offset.
+ * @mask - register bitmask.
+ * @val - value to write.
+ *
+ */
+static inline void dwc3_msm_write_reg_field(void *base, u32 offset,
+ const u32 mask, u32 val)
+{
+ u32 shift = find_first_bit((void *)&mask, 32);
+ u32 tmp = ioread32(base + offset);
+
+ tmp &= ~mask; /* clear written bits */
+ val = tmp | (val << shift);
+ iowrite32(val, base + offset);
+}
+
+/**
+ * Return DBM EP number which is not already configured.
+ *
+ */
+static int dwc3_msm_find_avail_dbm_ep(void)
+{
+ int i;
+
+ for (i = 0; i < context->dbm_num_eps; i++)
+ if (!context->ep_num_mapping[i])
+ return i;
+
+ return -ENODEV; /* Not found */
+}
+
+/**
+ * Return DBM EP number according to usb endpoint number.
+ *
+ */
+static int dwc3_msm_find_matching_dbm_ep(u8 usb_ep)
+{
+ int i;
+
+ for (i = 0; i < context->dbm_num_eps; i++)
+ if (context->ep_num_mapping[i] == usb_ep)
+ return i;
+
+ return -ENODEV; /* Not found */
+}
+
+/**
+ * Return number of configured DBM endpoints.
+ *
+ */
+static int dwc3_msm_configured_dbm_ep_num(void)
+{
+ int i;
+ int count = 0;
+
+ for (i = 0; i < context->dbm_num_eps; i++)
+ if (context->ep_num_mapping[i])
+ count++;
+
+ return count;
+}
+
+/**
+ * Configure the DBM with the USB3 core event buffer.
+ * This function is called by the SNPS UDC upon initialization.
+ *
+ * @addr - address of the event buffer.
+ * @size - size of the event buffer.
+ *
+ */
+static int dwc3_msm_event_buffer_config(u32 addr, u16 size)
+{
+ dev_dbg(context->dev, "%s\n", __func__);
+
+ dwc3_msm_write_reg(context->base, DBM_GEVNTADR, addr);
+ dwc3_msm_write_reg_field(context->base, DBM_GEVNTSIZ,
+ DBM_GEVNTSIZ_MASK, size);
+
+ return 0;
+}
+
+/**
+ * Reset the DBM registers upon initialization.
+ *
+ */
+static int dwc3_msm_dbm_soft_reset(void)
+{
+ dev_dbg(context->dev, "%s\n", __func__);
+
+ dwc3_msm_write_reg_field(context->base, DBM_SOFT_RESET,
+ DBM_SFT_RST, 1);
+
+ return 0;
+}
+
+/**
+ * Soft reset specific DBM ep.
+ * This function is called by the function driver upon events
+ * such as transfer aborting, USB re-enumeration and USB
+ * disconnection.
+ *
+ * @dbm_ep - DBM ep number.
+ * @enter_reset - should we enter a reset state or get out of it.
+ *
+ */
+static int dwc3_msm_dbm_ep_soft_reset(u8 dbm_ep, bool enter_reset)
+{
+ dev_dbg(context->dev, "%s\n", __func__);
+
+ if (dbm_ep >= context->dbm_num_eps) {
+ dev_err(context->dev,
+ "%s: Invalid DBM ep index\n", __func__);
+ return -ENODEV;
+ }
+
+ if (enter_reset) {
+ dwc3_msm_write_reg_field(context->base, DBM_SOFT_RESET,
+ DBM_SFT_RST_EPS, 1 << dbm_ep);
+ } else {
+ dwc3_msm_write_reg_field(context->base, DBM_SOFT_RESET,
+ DBM_SFT_RST_EPS, 0);
+ }
+
+ return 0;
+}
+
+/**
+ * Configure a USB DBM ep to work in BAM mode.
+ *
+ *
+ * @usb_ep - USB physical EP number.
+ * @producer - producer/consumer.
+ * @disable_wb - disable write back to system memory.
+ * @internal_mem - use internal USB memory for data fifo.
+ * @ioc - enable interrupt on completion.
+ *
+ * @return int - DBM ep number.
+ */
+static int dwc3_msm_dbm_ep_config(u8 usb_ep, u8 bam_pipe,
+ bool producer, bool disable_wb,
+ bool internal_mem, bool ioc)
+{
+ u8 dbm_ep;
+ u8 ioc_mask;
+
+ dev_dbg(context->dev, "%s\n", __func__);
+
+ dbm_ep = dwc3_msm_find_avail_dbm_ep();
+ if (dbm_ep < 0) {
+ dev_err(context->dev, "%s: No more DBM eps\n", __func__);
+ return -ENODEV;
+ }
+
+ context->ep_num_mapping[dbm_ep] = usb_ep;
+
+ /* First, reset the dbm endpoint */
+ dwc3_msm_dbm_ep_soft_reset(dbm_ep, false);
+
+ ioc_mask = dwc3_msm_read_reg_field(context->base, DBM_DBG_CNFG,
+ DBM_ENABLE_IOC_MASK);
+ ioc_mask &= ~(ioc << dbm_ep); /* Clear ioc bit for dbm_ep */
+ /* Set ioc bit for dbm_ep if needed */
+ dwc3_msm_write_reg_field(context->base, DBM_DBG_CNFG,
+ DBM_ENABLE_IOC_MASK, ioc_mask | (ioc << dbm_ep));
+
+ dwc3_msm_write_reg(context->base, DBM_EP_CFG(dbm_ep),
+ producer | disable_wb | internal_mem);
+ dwc3_msm_write_reg_field(context->base, DBM_EP_CFG(dbm_ep),
+ DBM_USB3_EP_NUM, usb_ep);
+ dwc3_msm_write_reg_field(context->base, DBM_EP_CFG(dbm_ep),
+ DBM_BAM_PIPE_NUM, bam_pipe);
+ dwc3_msm_write_reg_field(context->base, DBM_EP_CFG(dbm_ep),
+ DBM_EN_EP, 1);
+
+ return dbm_ep;
+}
+
+/**
+ * Configure a USB DBM ep to work in normal mode.
+ *
+ * @usb_ep - USB ep number.
+ *
+ */
+static int dwc3_msm_dbm_ep_unconfig(u8 usb_ep)
+{
+ u8 dbm_ep;
+
+ dev_dbg(context->dev, "%s\n", __func__);
+
+ dbm_ep = dwc3_msm_find_matching_dbm_ep(usb_ep);
+
+ if (dbm_ep < 0) {
+ dev_err(context->dev,
+ "%s: Invalid usb ep index\n", __func__);
+ return -ENODEV;
+ }
+
+ context->ep_num_mapping[dbm_ep] = 0;
+
+ dwc3_msm_write_reg(context->base, DBM_EP_CFG(dbm_ep), 0);
+
+ /* Reset the dbm endpoint */
+ dwc3_msm_dbm_ep_soft_reset(dbm_ep, true);
+
+ return 0;
+}
+
+/**
+ * Configure the DBM with the BAM's data fifo.
+ * This function is called by the USB BAM Driver
+ * upon initialization.
+ *
+ * @ep - pointer to usb endpoint.
+ * @addr - address of data fifo.
+ * @size - size of data fifo.
+ *
+ */
+int msm_data_fifo_config(struct usb_ep *ep, u32 addr, u32 size)
+{
+ u8 dbm_ep;
+ struct dwc3_ep *dep = to_dwc3_ep(ep);
+
+ dev_dbg(context->dev, "%s\n", __func__);
+
+ dbm_ep = dwc3_msm_find_matching_dbm_ep(dep->number);
+
+ if (dbm_ep >= context->dbm_num_eps) {
+ dev_err(context->dev,
+ "%s: Invalid DBM ep index\n", __func__);
+ return -ENODEV;
+ }
+
+ dwc3_msm_write_reg(context->base, DBM_DATA_FIFO(dbm_ep), addr);
+ dwc3_msm_write_reg_field(context->base, DBM_DATA_FIFO_SIZE(dbm_ep),
+ DBM_DATA_FIFO_SIZE_MASK, size);
+
+ return 0;
+}
+
+/**
+* Cleanups for msm endpoint on request complete.
+*
+* Also call original request complete.
+*
+* @usb_ep - pointer to usb_ep instance.
+* @request - pointer to usb_request instance.
+*
+* @return int - 0 on success, negetive on error.
+*/
+static void dwc3_msm_req_complete_func(struct usb_ep *ep,
+ struct usb_request *request)
+{
+ struct dwc3_request *req = to_dwc3_request(request);
+ struct dwc3_ep *dep = to_dwc3_ep(ep);
+ struct dwc3_msm_req_complete *req_complete = NULL;
+
+ /* Find original request complete function and remove it from list */
+ list_for_each_entry(req_complete,
+ &context->req_complete_list,
+ list_item) {
+ if (req_complete->req == request)
+ break;
+ }
+ if (!req_complete || req_complete->req != request) {
+ dev_err(dep->dwc->dev, "%s: could not find the request\n",
+ __func__);
+ return;
+ }
+ list_del(&req_complete->list_item);
+
+ /*
+ * Release another one TRB to the pool since DBM queue took 2 TRBs
+ * (normal and link), and the dwc3/gadget.c :: dwc3_gadget_giveback
+ * released only one.
+ */
+ if (req->queued)
+ dep->busy_slot++;
+
+ /* Unconfigure dbm ep */
+ dwc3_msm_dbm_ep_unconfig(dep->number);
+
+ /*
+ * If this is the last endpoint we unconfigured, than reset also
+ * the event buffers.
+ */
+ if (0 == dwc3_msm_configured_dbm_ep_num())
+ dwc3_msm_event_buffer_config(0, 0);
+
+ /*
+ * Call original complete function, notice that dwc->lock is already
+ * taken by the caller of this function (dwc3_gadget_giveback()).
+ */
+ request->complete = req_complete->orig_complete;
+ request->complete(ep, request);
+
+ kfree(req_complete);
+}
+
+/**
+* Helper function.
+* See the header of the dwc3_msm_ep_queue function.
+*
+* @dwc3_ep - pointer to dwc3_ep instance.
+* @req - pointer to dwc3_request instance.
+*
+* @return int - 0 on success, negetive on error.
+*/
+static int __dwc3_msm_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
+{
+ struct dwc3_trb_hw *trb_hw;
+ struct dwc3_trb_hw *trb_link_hw;
+ struct dwc3_trb trb;
+ struct dwc3_gadget_ep_cmd_params params;
+ u32 cmd;
+ int ret = 0;
+
+ if ((req->request.udc_priv & MSM_IS_FINITE_TRANSFER) &&
+ (req->request.length > 0)) {
+ /* Map the request to a DMA. */
+ dwc3_map_buffer_to_dma(req);
+ }
+
+ /* We push the request to the dep->req_queued list to indicate that
+ * this request is issued with start transfer. The request will be out
+ * from this list in 2 cases. The first is that the transfer will be
+ * completed (not if the transfer is endless using a circular TRBs with
+ * with link TRB). The second case is an option to do stop stransfer,
+ * this can be initiated by the function driver when calling dequeue.
+ */
+ req->queued = true;
+ list_add_tail(&req->list, &dep->req_queued);
+
+ /* First, prepare a normal TRB, point to the fake buffer */
+ trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
+ dep->free_slot++;
+ memset(&trb, 0, sizeof(trb));
+
+ req->trb = trb_hw;
+
+ trb.bplh = req->request.dma;
+ trb.lst = 0;
+ trb.trbctl = DWC3_TRBCTL_NORMAL;
+ trb.length = req->request.length;
+ trb.hwo = true;
+
+ dwc3_trb_to_hw(&trb, trb_hw);
+ req->trb_dma = dep->trb_pool_dma;
+
+ /* Second, prepare a Link TRB that points to the first TRB*/
+ trb_link_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
+ dep->free_slot++;
+ memset(&trb, 0, sizeof(trb));
+
+ trb.bplh = dep->trb_pool_dma;
+ trb.trbctl = DWC3_TRBCTL_LINK_TRB;
+ trb.hwo = true;
+
+ dwc3_trb_to_hw(&trb, trb_link_hw);
+
+ /*
+ * Now start the transfer
+ */
+ memset(¶ms, 0, sizeof(params));
+ params.param0 = upper_32_bits(req->trb_dma);
+ params.param1 = lower_32_bits(req->trb_dma);
+ cmd = DWC3_DEPCMD_STARTTRANSFER;
+ ret = dwc3_send_gadget_ep_cmd(dep->dwc, dep->number, cmd, ¶ms);
+ if (ret < 0) {
+ dev_dbg(dep->dwc->dev,
+ "%s: failed to send STARTTRANSFER command\n",
+ __func__);
+
+ dwc3_unmap_buffer_from_dma(req);
+ list_del(&req->list);
+ return ret;
+ }
+
+ return ret;
+}
+
+/**
+* Queue a usb request to the DBM endpoint.
+* This function should be called after the endpoint
+* was enabled by the ep_enable.
+*
+* This function prepares special structure of TRBs which
+* is familier with the DBM HW, so it will possible to use
+* this endpoint in DBM mode.
+*
+* The TRBs prepared by this function, is one normal TRB
+* which point to a fake buffer, followed by a link TRB
+* that points to the first TRB.
+*
+* The API of this function follow the regular API of
+* usb_ep_queue (see usb_ep_ops in include/linuk/usb/gadget.h).
+*
+* @usb_ep - pointer to usb_ep instance.
+* @request - pointer to usb_request instance.
+* @gfp_flags - possible flags.
+*
+* @return int - 0 on success, negetive on error.
+*/
+static int dwc3_msm_ep_queue(struct usb_ep *ep,
+ struct usb_request *request, gfp_t gfp_flags)
+{
+ struct dwc3_request *req = to_dwc3_request(request);
+ struct dwc3_ep *dep = to_dwc3_ep(ep);
+ struct dwc3 *dwc = dep->dwc;
+ struct dwc3_msm_req_complete *req_complete;
+ unsigned long flags;
+ int ret = 0;
+ u8 bam_pipe;
+ bool producer;
+ bool disable_wb;
+ bool internal_mem;
+ bool ioc;
+
+ if (!(request->udc_priv & MSM_SPS_MODE)) {
+ /* Not SPS mode, call original queue */
+ dev_vdbg(dwc->dev, "%s: not sps mode, use regular queue\n",
+ __func__);
+
+ return (context->original_ep_ops[dep->number])->queue(ep,
+ request,
+ gfp_flags);
+ }
+
+ if (!dep->endpoint.desc) {
+ dev_err(dwc->dev,
+ "%s: trying to queue request %p to disabled ep %s\n",
+ __func__, request, ep->name);
+ return -EPERM;
+ }
+
+ if (dep->number == 0 || dep->number == 1) {
+ dev_err(dwc->dev,
+ "%s: trying to queue dbm request %p to control ep %s\n",
+ __func__, request, ep->name);
+ return -EPERM;
+ }
+
+ if (dep->free_slot > 0 || dep->busy_slot > 0 ||
+ !list_empty(&dep->request_list) ||
+ !list_empty(&dep->req_queued)) {
+
+ dev_err(dwc->dev,
+ "%s: trying to queue dbm request %p tp ep %s\n",
+ __func__, request, ep->name);
+ return -EPERM;
+ }
+
+ /*
+ * Override req->complete function, but before doing that,
+ * store it's original pointer in the req_complete_list.
+ */
+ req_complete = kzalloc(sizeof(*req_complete), GFP_KERNEL);
+ if (!req_complete) {
+ dev_err(dep->dwc->dev, "%s: not enough memory\n", __func__);
+ return -ENOMEM;
+ }
+ req_complete->req = request;
+ req_complete->orig_complete = request->complete;
+ list_add_tail(&req_complete->list_item, &context->req_complete_list);
+ request->complete = dwc3_msm_req_complete_func;
+
+ /*
+ * Configure dbm event buffers if this is the first
+ * dbm endpoint we about to configure.
+ */
+ if (0 == dwc3_msm_configured_dbm_ep_num())
+ dwc3_msm_event_buffer_config(dwc->ev_buffs[0]->dma,
+ dwc->ev_buffs[0]->length);
+
+ /*
+ * Configure the DBM endpoint
+ */
+ bam_pipe = (request->udc_priv & MSM_PIPE_ID_MASK);
+ producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
+ disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
+ internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
+ ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);
+
+ ret = dwc3_msm_dbm_ep_config(dep->number,
+ bam_pipe, producer,
+ disable_wb, internal_mem, ioc);
+ if (ret < 0) {
+ dev_err(context->dev,
+ "error %d after calling dwc3_msm_dbm_ep_config\n",
+ ret);
+ return ret;
+ }
+
+ dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n",
+ __func__, request, ep->name, request->length);
+
+ /*
+ * We must obtain the lock of the dwc3 core driver,
+ * including disabling interrupts, so we will be sure
+ * that we are the only ones that configure the HW device
+ * core and ensure that we queuing the request will finish
+ * as soon as possible so we will release back the lock.
+ */
+ spin_lock_irqsave(&dwc->lock, flags);
+ ret = __dwc3_msm_ep_queue(dep, req);
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ if (ret < 0) {
+ dev_err(context->dev,
+ "error %d after calling __dwc3_msm_ep_queue\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * Configure MSM endpoint.
+ * This function do specific configurations
+ * to an endpoint which need specific implementaion
+ * in the MSM architecture.
+ *
+ * This function should be called by usb function/class
+ * layer which need a support from the specific MSM HW
+ * which wrap the USB3 core. (like DBM specific endpoints)
+ *
+ * @ep - a pointer to some usb_ep instance
+ *
+ * @return int - 0 on success, negetive on error.
+ */
+int msm_ep_config(struct usb_ep *ep)
+{
+ struct dwc3_ep *dep = to_dwc3_ep(ep);
+ struct usb_ep_ops *new_ep_ops;
+
+ /* Save original ep ops for future restore*/
+ if (context->original_ep_ops[dep->number]) {
+ dev_err(context->dev,
+ "ep [%s,%d] already configured as msm endpoint\n",
+ ep->name, dep->number);
+ return -EPERM;
+ }
+ context->original_ep_ops[dep->number] = ep->ops;
+
+ /* Set new usb ops as we like */
+ new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), GFP_KERNEL);
+ if (!new_ep_ops) {
+ dev_err(context->dev,
+ "%s: unable to allocate mem for new usb ep ops\n",
+ __func__);
+ return -ENOMEM;
+ }
+ (*new_ep_ops) = (*ep->ops);
+ new_ep_ops->queue = dwc3_msm_ep_queue;
+ ep->ops = new_ep_ops;
+
+ /*
+ * Do HERE more usb endpoint configurations
+ * which are specific to MSM.
+ */
+
+ return 0;
+}
+EXPORT_SYMBOL(msm_ep_config);
+
+/**
+ * Un-configure MSM endpoint.
+ * Tear down configurations done in the
+ * dwc3_msm_ep_config function.
+ *
+ * @ep - a pointer to some usb_ep instance
+ *
+ * @return int - 0 on success, negetive on error.
+ */
+int msm_ep_unconfig(struct usb_ep *ep)
+{
+ struct dwc3_ep *dep = to_dwc3_ep(ep);
+ struct usb_ep_ops *old_ep_ops;
+
+ /* Restore original ep ops */
+ if (!context->original_ep_ops[dep->number]) {
+ dev_err(context->dev,
+ "ep [%s,%d] was not configured as msm endpoint\n",
+ ep->name, dep->number);
+ return -EINVAL;
+ }
+ old_ep_ops = (struct usb_ep_ops *)ep->ops;
+ ep->ops = context->original_ep_ops[dep->number];
+ context->original_ep_ops[dep->number] = NULL;
+ kfree(old_ep_ops);
+
+ /*
+ * Do HERE more usb endpoint un-configurations
+ * which are specific to MSM.
+ */
+
+ return 0;
+}
+EXPORT_SYMBOL(msm_ep_unconfig);
+
static int __devinit dwc3_msm_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
@@ -49,6 +765,9 @@
}
platform_set_drvdata(pdev, msm);
+ context = msm;
+
+ INIT_LIST_HEAD(&msm->req_complete_list);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -107,6 +826,9 @@
goto err1;
}
+ /* Reset the DBM */
+ dwc3_msm_dbm_soft_reset();
+
return 0;
err1:
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index fa824cf..2341441 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1327,7 +1327,7 @@
const struct dwc3_event_depevt *event, int status)
{
struct dwc3_request *req;
- struct dwc3_trb trb;
+ struct dwc3_trb trb = {0};
unsigned int count;
unsigned int s_pkt = 0;
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 8e0bef0..54d041a 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -64,6 +64,7 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
+#include <linux/usb/msm_hsusb.h>
#include "ci13xxx_udc.h"
@@ -1676,7 +1677,7 @@
if (CI13XX_REQ_VENDOR_ID(mReq->req.udc_priv) == MSM_VENDOR_ID) {
if (mReq->req.udc_priv & MSM_SPS_MODE) {
mReq->ptr->token = TD_STATUS_ACTIVE;
- if (mReq->req.udc_priv & MSM_TBE)
+ if (mReq->req.udc_priv & MSM_IS_FINITE_TRANSFER)
mReq->ptr->next = TD_TERMINATE;
else
mReq->ptr->next = MSM_ETD_TYPE | mReq->dma;
@@ -1794,7 +1795,7 @@
if (CI13XX_REQ_VENDOR_ID(mReq->req.udc_priv) == MSM_VENDOR_ID)
if ((mReq->req.udc_priv & MSM_SPS_MODE) &&
- (mReq->req.udc_priv & MSM_TBE))
+ (mReq->req.udc_priv & MSM_IS_FINITE_TRANSFER))
return -EBUSY;
if (mReq->zptr) {
if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 684517b..0c811e1 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -30,15 +30,8 @@
*/
#define CI13XX_REQ_VENDOR_ID(id) (id & 0xFFFF0000UL)
-/* MSM specific */
-#define MSM_PIPE_ID_MASK (0x1F)
-#define MSM_TX_PIPE_ID_OFS (16)
-#define MSM_SPS_MODE BIT(5)
-#define MSM_TBE BIT(6)
-#define MSM_ETD_TYPE BIT(1)
-#define MSM_ETD_IOC BIT(9)
-#define MSM_VENDOR_ID BIT(16)
-#define MSM_EP_PIPE_ID_RESET_VAL 0x1F001F
+#define MSM_ETD_TYPE BIT(1)
+#define MSM_EP_PIPE_ID_RESET_VAL 0x1F001F
/******************************************************************************
* STRUCTURES
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index b086428..958ed31 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -414,23 +414,6 @@
kfree(f->name);
}
-static void frmnet_suspend(struct usb_function *f)
-{
- struct f_rmnet *dev = func_to_rmnet(f);
- unsigned port_num;
-
- if (!atomic_read(&dev->online))
- return;
- /* This is a workaround for a bug in Windows 7/XP hosts in which
- * the DTR bit is not set low when going into suspend. Hence force it
- * low here when this function driver is suspended.
- */
- if (dev->port.notify_modem) {
- port_num = rmnet_ports[dev->port_num].ctrl_xport_num;
- dev->port.notify_modem(&dev->port, port_num, ~ACM_CTRL_DTR);
- }
-}
-
static void frmnet_disable(struct usb_function *f)
{
struct f_rmnet *dev = func_to_rmnet(f);
@@ -929,7 +912,6 @@
f->disable = frmnet_disable;
f->set_alt = frmnet_set_alt;
f->setup = frmnet_setup;
- f->suspend = frmnet_suspend;
dev->port.send_cpkt_response = frmnet_send_cpkt_response;
dev->port.disconnect = frmnet_disconnect;
dev->port.connect = frmnet_connect;
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 36270d4..3113c45 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -79,10 +79,6 @@
#define BAM_CH_OPENED BIT(0)
#define BAM_CH_READY BIT(1)
-#define SPS_PARAMS_PIPE_ID_MASK (0x1F)
-#define SPS_PARAMS_SPS_MODE BIT(5)
-#define SPS_PARAMS_TBE BIT(6)
-#define MSM_VENDOR_ID BIT(16)
struct bam_ch_info {
unsigned long flags;
@@ -741,8 +737,8 @@
d->rx_req->context = port;
d->rx_req->complete = gbam_endless_rx_complete;
d->rx_req->length = 0;
- sps_params = (SPS_PARAMS_SPS_MODE | d->src_pipe_idx |
- MSM_VENDOR_ID) & ~SPS_PARAMS_TBE;
+ sps_params = (MSM_SPS_MODE | d->src_pipe_idx |
+ MSM_VENDOR_ID) & ~MSM_IS_FINITE_TRANSFER;
d->rx_req->udc_priv = sps_params;
d->tx_req = usb_ep_alloc_request(port->port_usb->in, GFP_KERNEL);
if (!d->tx_req)
@@ -751,8 +747,8 @@
d->tx_req->context = port;
d->tx_req->complete = gbam_endless_tx_complete;
d->tx_req->length = 0;
- sps_params = (SPS_PARAMS_SPS_MODE | d->dst_pipe_idx |
- MSM_VENDOR_ID) & ~SPS_PARAMS_TBE;
+ sps_params = (MSM_SPS_MODE | d->dst_pipe_idx |
+ MSM_VENDOR_ID) & ~MSM_IS_FINITE_TRANSFER;
d->tx_req->udc_priv = sps_params;
/* queue in & out requests */
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 29d500a..0d2bfd8 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -1190,7 +1190,6 @@
static void hdmi_edid_extract_extended_data_blocks(const uint8 *in_buf)
{
uint8 len = 0;
- uint8 const *prev_etag = in_buf;
uint32 start_offset = DBC_START_OFFSET;
/* A Tage code of 7 identifies extended data blocks */
@@ -1239,8 +1238,7 @@
}
/* There could be more that one extended data block */
- start_offset = etag - prev_etag + len + 1;
- prev_etag = etag;
+ start_offset = etag - in_buf + len + 1;
etag = hdmi_edid_find_block(in_buf, start_offset, 7, &len);
}
}
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index fe56263..603bad8 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1246,70 +1246,72 @@
complete(&dma->comp);
}
}
-#ifndef CONFIG_FB_MSM_MDP22
- if (mdp_interrupt & MDP_HIST_DONE) {
- hist_interrupt = inp32(MDP_DMA_P_HIST_INTR_STATUS);
- outp32(MDP_BASE + 0x94018, 0x3);
- outp32(MDP_INTR_CLEAR, MDP_HIST_DONE);
- if (hist_interrupt & INTR_HIST_RESET_SEQ_DONE)
- __mdp_histogram_kickoff();
+ if (mdp_rev >= MDP_REV_30) {
+ if (mdp_interrupt & MDP_HIST_DONE) {
+ hist_interrupt = inp32(MDP_DMA_P_HIST_INTR_STATUS);
+ outp32(MDP_BASE + 0x94018, 0x3);
+ outp32(MDP_INTR_CLEAR, MDP_HIST_DONE);
+ if (hist_interrupt & INTR_HIST_RESET_SEQ_DONE)
+ __mdp_histogram_kickoff();
- if (hist_interrupt & INTR_HIST_DONE) {
- if (waitqueue_active(&mdp_hist_comp.wait)) {
- if (!queue_work(mdp_hist_wq,
+ if (hist_interrupt & INTR_HIST_DONE) {
+ if (waitqueue_active(&mdp_hist_comp.wait)) {
+ if (!queue_work(mdp_hist_wq,
&mdp_histogram_worker)) {
- pr_err("%s: can't queue hist_read\n",
+ pr_err("%s: can't queue hist_read\n",
__func__);
+ }
+ } else {
+ __mdp_histogram_reset();
}
- } else
- __mdp_histogram_reset();
+ }
}
- }
- /* LCDC UnderFlow */
- if (mdp_interrupt & LCDC_UNDERFLOW) {
- mdp_lcdc_underflow_cnt++;
- /*when underflow happens HW resets all the histogram
- registers that were set before so restore them back
- to normal.*/
- MDP_OUTP(MDP_BASE + 0x94010, 1);
- MDP_OUTP(MDP_BASE + 0x9401c, INTR_HIST_DONE);
- mdp_is_hist_valid = FALSE;
- __mdp_histogram_reset();
- }
+ /* LCDC UnderFlow */
+ if (mdp_interrupt & LCDC_UNDERFLOW) {
+ mdp_lcdc_underflow_cnt++;
+ /*when underflow happens HW resets all the histogram
+ registers that were set before so restore them back
+ to normal.*/
+ MDP_OUTP(MDP_BASE + 0x94010, 1);
+ MDP_OUTP(MDP_BASE + 0x9401c, INTR_HIST_DONE);
+ mdp_is_hist_valid = FALSE;
+ __mdp_histogram_reset();
+ }
- /* LCDC Frame Start */
- if (mdp_interrupt & LCDC_FRAME_START) {
- dma = &dma2_data;
- spin_lock_irqsave(&mdp_spin_lock, flag);
- /* let's disable LCDC interrupt */
- mdp_intr_mask &= ~LCDC_FRAME_START;
- outp32(MDP_INTR_ENABLE, mdp_intr_mask);
- if (dma->waiting) {
- dma->waiting = FALSE;
+ /* LCDC Frame Start */
+ if (mdp_interrupt & LCDC_FRAME_START) {
+ dma = &dma2_data;
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ /* let's disable LCDC interrupt */
+ mdp_intr_mask &= ~LCDC_FRAME_START;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ if (dma->waiting) {
+ dma->waiting = FALSE;
+ complete(&dma->comp);
+ }
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ }
+
+ /* DMA2 LCD-Out Complete */
+ if (mdp_interrupt & MDP_DMA_S_DONE) {
+ dma = &dma_s_data;
+ dma->busy = FALSE;
+ mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF,
+ TRUE);
complete(&dma->comp);
}
- spin_unlock_irqrestore(&mdp_spin_lock, flag);
- }
- /* DMA2 LCD-Out Complete */
- if (mdp_interrupt & MDP_DMA_S_DONE) {
- dma = &dma_s_data;
- dma->busy = FALSE;
- mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+ /* DMA_E LCD-Out Complete */
+ if (mdp_interrupt & MDP_DMA_E_DONE) {
+ dma = &dma_s_data;
+ dma->busy = FALSE;
+ mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_OFF,
+ TRUE);
complete(&dma->comp);
+ }
}
- /* DMA_E LCD-Out Complete */
- if (mdp_interrupt & MDP_DMA_E_DONE) {
- dma = &dma_s_data;
- dma->busy = FALSE;
- mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
- complete(&dma->comp);
- }
-
-#endif
-
/* DMA2 LCD-Out Complete */
if (mdp_interrupt & MDP_DMA_P_DONE) {
struct timeval now;
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 02d87a8..a731774 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -19,10 +19,27 @@
#define __ASM_ARCH_MSM_HSUSB_H
#include <linux/types.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
#include <linux/wakelock.h>
#include <linux/pm_qos_params.h>
+/*
+ * The following are bit fields describing the usb_request.udc_priv word.
+ * These bit fields are set by function drivers that wish to queue
+ * usb_requests with sps/bam parameters.
+ */
+#define MSM_PIPE_ID_MASK (0x1F)
+#define MSM_TX_PIPE_ID_OFS (16)
+#define MSM_SPS_MODE BIT(5)
+#define MSM_IS_FINITE_TRANSFER BIT(6)
+#define MSM_PRODUCER BIT(7)
+#define MSM_DISABLE_WB BIT(8)
+#define MSM_ETD_IOC BIT(9)
+#define MSM_INTERNAL_MEM BIT(10)
+#define MSM_VENDOR_ID BIT(16)
+
/**
* Supported USB modes
*
@@ -359,4 +376,9 @@
HSUSB_BAM = 0,
HSIC_BAM,
};
+
+int msm_ep_config(struct usb_ep *ep);
+int msm_ep_unconfig(struct usb_ep *ep);
+int msm_data_fifo_config(struct usb_ep *ep, u32 addr, u32 size);
+
#endif
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index de3ab22..3b5ad95 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -7539,6 +7539,17 @@
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+
+ if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
+ result == L2CAP_CR_SUCCESS) {
+ char buf[128];
+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
+ l2cap_send_cmd(conn, l2cap_get_ident(conn),
+ L2CAP_CONF_REQ,
+ l2cap_build_conf_req(sk, buf),
+ buf);
+ l2cap_pi(sk)->num_conf_req++;
+ }
}
bh_unlock_sock(sk);
diff --git a/sound/soc/msm/msm7201.c b/sound/soc/msm/msm7201.c
index f814a21..a6a3266 100644
--- a/sound/soc/msm/msm7201.c
+++ b/sound/soc/msm/msm7201.c
@@ -84,11 +84,12 @@
spin_lock_irq(&the_locks.mixer_lock);
change = (msm_vol_ctl.volume != volume);
if (change) {
- msm_vol_ctl.update = 1;
msm_vol_ctl.volume = volume;
+ msm_audio_volume_update(PCMPLAYBACK_DECODERID,
+ msm_vol_ctl.volume, msm_vol_ctl.pan);
}
spin_unlock_irq(&the_locks.mixer_lock);
- return change;
+ return 0;
}
static int snd_msm_device_info(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/msm/msm7k-pcm.c b/sound/soc/msm/msm7k-pcm.c
index 6ef924f..1f23a92 100644
--- a/sound/soc/msm/msm7k-pcm.c
+++ b/sound/soc/msm/msm7k-pcm.c
@@ -414,11 +414,12 @@
return ret;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- msm_vol_ctl.update = 1; /* Update Volume, with Cached value */
runtime->hw = msm_pcm_playback_hardware;
prtd->dir = SNDRV_PCM_STREAM_PLAYBACK;
prtd->playback_substream = substream;
prtd->eos_ack = 0;
+ ret = msm_audio_volume_update(PCMPLAYBACK_DECODERID,
+ msm_vol_ctl.volume, msm_vol_ctl.pan);
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
runtime->hw = msm_pcm_capture_hardware;
prtd->dir = SNDRV_PCM_STREAM_CAPTURE;
@@ -468,12 +469,6 @@
alsa_audio_configure(prtd);
mutex_unlock(&the_locks.lock);
}
- if ((prtd->running) && (msm_vol_ctl.update)) {
- rc = msm_audio_volume_update(PCMPLAYBACK_DECODERID,
- msm_vol_ctl.volume, msm_vol_ctl.pan);
- msm_vol_ctl.update = 0;
- }
-
return rc;
}