Merge "bluetooth: Reset BT stack when wcnss chip resets" into msm-3.0
diff --git a/Documentation/genlock.txt b/Documentation/genlock.txt
index d3a44e2..6f24a76 100644
--- a/Documentation/genlock.txt
+++ b/Documentation/genlock.txt
@@ -82,15 +82,13 @@
Release a handle.
* struct genlock * genlock_create_lock(struct genlock_handle *)
-Create a new lock and attach it to the handle.
+Create a new lock and attach it to the handle. Once a lock is attached to a
+handle it stays attached until the handle is destroyed.
* struct genlock * genlock_attach_lock(struct genlock_handle *handle, int fd)
Given a valid file descriptor, get the lock associated with it and attach it to
the handle.
-* void genlock_release_lock(struct genlock_handle *)
-Release a lock attached to a handle.
-
* int genlock_lock(struct genlock_handle *, int op, int flags, u32 timeout)
Lock or unlock the lock attached to the handle. A zero timeout value will
be treated just like if the GENOCK_NOBLOCK flag is passed; if the lock
@@ -155,7 +153,4 @@
-EINVAL if a zero timeout is passed, or -ETIMEDOUT if the timeout expires.
* GENLOCK_IOC_RELEASE
-Use this to release an existing lock. This is useful if you wish to attach a
-different lock to the same handle. You do not need to call this under normal
-circumstances; when the handle is closed the reference to the lock is released.
-No data is passed from the user for this ioctl.
+This ioctl has been deprecated. Do not use.
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index fc1d81a..76ff09c 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -201,6 +201,7 @@
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 3cf01a1..3ddb0c9 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -201,6 +201,7 @@
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h
index d493d0b..ec4b8b8 100644
--- a/arch/arm/include/asm/fiq.h
+++ b/arch/arm/include/asm/fiq.h
@@ -33,11 +33,22 @@
void *dev_id;
};
+#ifdef CONFIG_FIQ
extern int claim_fiq(struct fiq_handler *f);
extern void release_fiq(struct fiq_handler *f);
extern void set_fiq_handler(void *start, unsigned int length);
extern void enable_fiq(int fiq);
extern void disable_fiq(int fiq);
+#else
+static inline int claim_fiq(struct fiq_handler *f)
+{
+ return 0;
+}
+static inline void release_fiq(struct fiq_handler *f) { }
+static inline void set_fiq_handler(void *start, unsigned int length) { }
+static inline void enable_fiq(int fiq) { }
+static inline void disable_fiq(int fiq) { }
+#endif
/* helpers defined in fiqasm.S: */
extern void __set_fiq_regs(unsigned long const *regs);
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index fa82e34..05c5a2b 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1795,7 +1795,7 @@
if (bam_tx_pipe == NULL) {
pr_err("%s: tx alloc endpoint failed\n", __func__);
ret = -ENOMEM;
- goto register_bam_failed;
+ goto tx_alloc_endpoint_failed;
}
ret = sps_get_config(bam_tx_pipe, &tx_connection);
if (ret) {
@@ -1815,7 +1815,7 @@
if (tx_desc_mem_buf.base == NULL) {
pr_err("%s: tx memory alloc failed\n", __func__);
ret = -ENOMEM;
- goto tx_mem_failed;
+ goto tx_get_config_failed;
}
tx_desc_mem_buf.phys_base = dma_addr;
memset(tx_desc_mem_buf.base, 0x0, tx_desc_mem_buf.size);
@@ -1832,7 +1832,7 @@
if (bam_rx_pipe == NULL) {
pr_err("%s: rx alloc endpoint failed\n", __func__);
ret = -ENOMEM;
- goto tx_connect_failed;
+ goto rx_alloc_endpoint_failed;
}
ret = sps_get_config(bam_rx_pipe, &rx_connection);
if (ret) {
@@ -1901,15 +1901,16 @@
dma_free_coherent(NULL, rx_desc_mem_buf.size, rx_desc_mem_buf.base,
rx_desc_mem_buf.phys_base);
rx_mem_failed:
- sps_disconnect(bam_tx_pipe);
rx_get_config_failed:
sps_free_endpoint(bam_rx_pipe);
+rx_alloc_endpoint_failed:
+ sps_disconnect(bam_tx_pipe);
tx_connect_failed:
dma_free_coherent(NULL, tx_desc_mem_buf.size, tx_desc_mem_buf.base,
tx_desc_mem_buf.phys_base);
tx_get_config_failed:
sps_free_endpoint(bam_tx_pipe);
-tx_mem_failed:
+tx_alloc_endpoint_failed:
sps_deregister_bam_device(h);
/*
* sps_deregister_bam_device() calls iounmap. calling iounmap on the
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index c652238..6c01764 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -70,6 +70,9 @@
REGULATOR_SUPPLY("iris_vddio", "wcnss_wlan.0"),
REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
REGULATOR_SUPPLY("sdc_vccq", "msm_sdcc.1"),
+ REGULATOR_SUPPLY("VDDIO_CDC", "sitar-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_TX", "sitar-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_RX", "sitar-slim"),
};
VREG_CONSUMERS(L12) = {
REGULATOR_SUPPLY("8038_l12", NULL),
@@ -97,6 +100,8 @@
};
VREG_CONSUMERS(L20) = {
REGULATOR_SUPPLY("8038_l20", NULL),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "sitar-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "sitar-slim"),
};
VREG_CONSUMERS(L21) = {
REGULATOR_SUPPLY("8038_l21", NULL),
@@ -138,6 +143,7 @@
};
VREG_CONSUMERS(S4) = {
REGULATOR_SUPPLY("8038_s4", NULL),
+ REGULATOR_SUPPLY("CDC_VDD_CP", "sitar-slim"),
};
VREG_CONSUMERS(S5) = {
REGULATOR_SUPPLY("8038_s5", NULL),
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index fc91337..f9601a6 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1475,8 +1475,8 @@
27, 0, 5, 1, 0, 0, 8, 8, 0, 0,
/* T9 Object */
131, 0, 0, 19, 11, 0, 16, 35, 1, 3,
- 10, 15, 1, 11, 4, 5, 40, 10, 54, 2,
- 43, 4, 0, 0, 0, 0, 143, 40, 143, 80,
+ 10, 15, 1, 11, 4, 5, 40, 10, 43, 4,
+ 54, 2, 0, 0, 0, 0, 143, 40, 143, 80,
18, 15, 50, 50, 2,
/* T15 Object */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1513,10 +1513,10 @@
struct kobj_attribute *attr, char *buf)
{
return snprintf(buf, 200,
- __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":65:938:90:90"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":208:938:90:90"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":348:938:90:90"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":490:938:90:90"
+ __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":57:1030:90:90"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":206:1030:90:90"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":366:1030:90:90"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":503:1030:90:90"
"\n");
}
@@ -1568,8 +1568,10 @@
static struct mxt_platform_data mxt_platform_data_8930 = {
.config_array = mxt_config_array,
.config_array_size = ARRAY_SIZE(mxt_config_array),
- .x_size = 1067,
- .y_size = 566,
+ .x_size = 540,
+ .y_size = 960,
+ .touch_x_size = 566,
+ .touch_y_size = 1067,
.irqflags = IRQF_TRIGGER_FALLING,
#ifdef MSM8930_PHASE_2
.digital_pwr_regulator = true,
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 2d5ae78..1bb9c86 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -631,7 +631,8 @@
bank_info = &bank_masks->bank1_mask;
ns_mask = bank_info->ns_mask;
- md_val = readl_relaxed(bank_info->md_reg);
+ md_val = bank_info->md_reg ?
+ readl_relaxed(bank_info->md_reg) : 0;
} else {
ns_mask = clk->ns_mask;
md_val = clk->md_reg ? readl_relaxed(clk->md_reg) : 0;
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 11b9092..5eccf06 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -66,6 +66,28 @@
.notifier_call = riva_notifier_cb,
};
+static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
+ void *ss_handle)
+{
+ int ret;
+ switch (code) {
+ case SUBSYS_BEFORE_SHUTDOWN:
+ pr_debug("%s: M-Notify: Shutdown started\n", __func__);
+ ret = sysmon_send_event(SYSMON_SS_LPASS, "modem",
+ SUBSYS_BEFORE_SHUTDOWN);
+ if (ret < 0)
+ pr_err("%s: sysmon_send_event error %d", __func__,
+ ret);
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+static void *ssr_modem_notif_hdle;
+static struct notifier_block mnb = {
+ .notifier_call = modem_notifier_cb,
+};
+
static void lpass_fatal_fn(struct work_struct *work)
{
pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
@@ -213,6 +235,18 @@
goto out;
}
+ ssr_modem_notif_hdle = subsys_notif_register_notifier("modem",
+ &mnb);
+ if (IS_ERR(ssr_modem_notif_hdle) < 0) {
+ ret = PTR_ERR(ssr_modem_notif_hdle);
+ pr_err("%s: subsys_register_notifier for Modem: err = %d\n",
+ __func__, ret);
+ subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+ iounmap(q6_wakeup_intr);
+ free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+ goto out;
+ }
+
pr_info("%s: lpass SSR driver init'ed.\n", __func__);
out:
return ret;
@@ -221,6 +255,7 @@
static void __exit lpass_fatal_exit(void)
{
subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+ subsys_notif_unregister_notifier(ssr_modem_notif_hdle, &mnb);
iounmap(q6_wakeup_intr);
free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
}
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index 27717e0..1507915 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -496,12 +496,7 @@
return ret;
}
-/**
- * genlock_release_lock - Release a lock attached to a handle
- * @handle - Pointer to the handle holding the lock
- */
-
-void genlock_release_lock(struct genlock_handle *handle)
+static void genlock_release_lock(struct genlock_handle *handle)
{
unsigned long flags;
@@ -522,7 +517,6 @@
handle->lock = NULL;
handle->active = 0;
}
-EXPORT_SYMBOL(genlock_release_lock);
/*
* Release function called when all references to a handle are released
@@ -671,8 +665,13 @@
return genlock_wait(handle, param.timeout);
}
case GENLOCK_IOC_RELEASE: {
- genlock_release_lock(handle);
- return 0;
+ /*
+ * Return error - this ioctl has been deprecated.
+ * Locks should only be released when the handle is
+ * destroyed
+ */
+ GENLOCK_LOG_ERR("Deprecated RELEASE ioctl called\n");
+ return -EINVAL;
}
default:
GENLOCK_LOG_ERR("Invalid ioctl\n");
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 71bdcde..4e81567 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -303,6 +303,8 @@
struct mxt_info info;
struct mxt_finger finger[MXT_MAX_FINGER];
unsigned int irq;
+ unsigned int touch_x_size;
+ unsigned int touch_y_size;
struct regulator *vcc_ana;
struct regulator *vcc_dig;
struct regulator *vcc_i2c;
@@ -667,9 +669,9 @@
x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
y = (message->message[2] << 4) | ((message->message[3] & 0xf));
- if (data->pdata->x_size < 1024)
+ if (data->touch_x_size < 1024)
x = x >> 2;
- if (data->pdata->y_size < 1024)
+ if (data->touch_y_size < 1024)
y = y >> 2;
area = message->message[4];
@@ -1809,7 +1811,7 @@
goto err_free_mem;
}
- input_dev->name = "Atmel maXTouch Touchscreen";
+ input_dev->name = "atmel_mxt_ts";
input_dev->id.bustype = BUS_I2C;
input_dev->dev.parent = &client->dev;
input_dev->open = mxt_input_open;
@@ -1842,6 +1844,16 @@
input_set_abs_params(input_dev, ABS_MT_PRESSURE,
0, 255, 0, 0);
+ if (pdata->touch_x_size)
+ data->touch_x_size = pdata->touch_x_size;
+ else
+ data->touch_x_size = pdata->x_size;
+
+ if (pdata->touch_y_size)
+ data->touch_y_size = pdata->touch_y_size;
+ else
+ data->touch_y_size = pdata->y_size;
+
/* set key array supported keys */
if (pdata->key_codes) {
for (i = 0; i < MXT_KEYARRAY_MAX_KEYS; i++) {
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index 283f985..eb0048a 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -132,6 +132,9 @@
#define UART_PATH_SEL_MASK 0x60
#define UART_PATH_SEL_SHIFT 0x5
+#define USB_ID_PU_EN_MASK 0x10 /* PM8921 family only */
+#define USB_ID_PU_EN_SHIFT 4
+
/* Shutdown/restart delays to allow for LDO 7/dVdd regulator load settling. */
#define PM8901_DELAY_AFTER_REG_DISABLE_MS 4
#define PM8901_DELAY_BEFORE_SHUTDOWN_MS 8
@@ -944,6 +947,48 @@
}
EXPORT_SYMBOL(pm8xxx_uart_gpio_mux_ctrl);
+/**
+ * pm8xxx_usb_id_pullup - Control a pullup for USB ID
+ *
+ * @enable: enable (1) or disable (0) the pullup
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_usb_id_pullup(int enable)
+{
+ struct pm8xxx_misc_chip *chip;
+ unsigned long flags;
+ int rc = -ENXIO;
+
+ spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+ /* Loop over all attached PMICs and call specific functions for them. */
+ list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+ switch (chip->version) {
+ case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8922:
+ case PM8XXX_VERSION_8917:
+ case PM8XXX_VERSION_8038:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8XXX_GPIO_MUX_CTRL, USB_ID_PU_EN_MASK,
+ enable << USB_ID_PU_EN_SHIFT);
+
+ if (rc)
+ pr_err("Fail: reg=%x, rc=%d\n",
+ REG_PM8XXX_GPIO_MUX_CTRL, rc);
+ break;
+ default:
+ /* Functionality not supported */
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_usb_id_pullup);
+
static int __pm8901_preload_dVdd(struct pm8xxx_misc_chip *chip)
{
int rc;
diff --git a/drivers/mfd/pm8xxx-pwm.c b/drivers/mfd/pm8xxx-pwm.c
index b5e2092..05f02c4 100644
--- a/drivers/mfd/pm8xxx-pwm.c
+++ b/drivers/mfd/pm8xxx-pwm.c
@@ -27,8 +27,14 @@
#define PM8XXX_PWM_CHANNELS 3
-#define PM8XXX_LPG_BANKS 8
-#define PM8XXX_LPG_PWM_CHANNELS PM8XXX_LPG_BANKS
+/*
+ * For the lack of better term to distinguish functional
+ * differences, hereby, LPG version 0 (V0, v0) denotes
+ * PM8058/8921, and version 1 (V1, v1) denotes
+ * PM8922/8038.
+ */
+#define PM8XXX_LPG_V0_PWM_CHANNELS 8
+#define PM8XXX_LPG_V1_PWM_CHANNELS 6
#define PM8XXX_LPG_CTL_REGS 7
/* PM8XXX PWM */
@@ -149,12 +155,10 @@
#define NSEC_32768HZ (NSEC_PER_SEC / 32768)
#define NSEC_19P2MHZ (NSEC_PER_SEC / 19200000)
-#define CLK_PERIOD_MIN NSEC_19P2MHZ
-#define CLK_PERIOD_MAX NSEC_1024HZ
-
#define NUM_LPG_PRE_DIVIDE 4
#define NUM_PWM_PRE_DIVIDE 2
+#define PRE_DIVIDE_1 1 /* v1 */
#define PRE_DIVIDE_2 2
#define PRE_DIVIDE_3 3
#define PRE_DIVIDE_5 5
@@ -1339,11 +1343,19 @@
if (version == PM8XXX_VERSION_8921 ||
version == PM8XXX_VERSION_8058 ||
- version == PM8XXX_VERSION_8922) {
+ version == PM8XXX_VERSION_8922 ||
+ version == PM8XXX_VERSION_8038) {
chip->is_lpg_supported = 1;
}
if (chip->is_lpg_supported) {
- chip->pwm_channels = PM8XXX_LPG_PWM_CHANNELS;
+ if (version == PM8XXX_VERSION_8922 ||
+ version == PM8XXX_VERSION_8038) {
+ for (i = 0; i < NUM_CLOCKS; i++)
+ pt_t[0][i] /= PRE_DIVIDE_2;
+ chip->pwm_channels = PM8XXX_LPG_V1_PWM_CHANNELS;
+ } else {
+ chip->pwm_channels = PM8XXX_LPG_V0_PWM_CHANNELS;
+ }
chip->pwm_total_pre_divs = NUM_LPG_PRE_DIVIDE;
} else {
chip->pwm_channels = PM8XXX_PWM_CHANNELS;
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index c40f13e..51ec91c 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -263,6 +263,7 @@
enum pm8921_chg_hot_thr hot_thr;
};
+static int usb_max_current;
static int charging_disabled;
static int thermal_mitigation;
@@ -575,6 +576,22 @@
return 0;
}
+struct usb_ma_limit_entry {
+ int usb_ma;
+ u8 chg_iusb_value;
+};
+
+static struct usb_ma_limit_entry usb_ma_table[] = {
+ {100, 0},
+ {500, 1},
+ {700, 2},
+ {850, 3},
+ {900, 4},
+ {1100, 5},
+ {1300, 6},
+ {1500, 7},
+};
+
#define PM8921_CHG_IUSB_MASK 0x1C
#define PM8921_CHG_IUSB_MAX 7
#define PM8921_CHG_IUSB_MIN 0
@@ -591,6 +608,26 @@
temp);
}
+static int pm_chg_iusbmax_get(struct pm8921_chg_chip *chip, int *mA)
+{
+ u8 temp;
+ int i, rc;
+
+ *mA = 0;
+ rc = pm8xxx_readb(chip->dev->parent, PBL_ACCESS2, &temp);
+ if (rc) {
+ pr_err("err=%d reading PBL_ACCESS2\n", rc);
+ return rc;
+ }
+ temp &= PM8921_CHG_IUSB_MASK;
+ temp = temp >> 2;
+ for (i = ARRAY_SIZE(usb_ma_table) - 1; i >= 0; i--) {
+ if (usb_ma_table[i].chg_iusb_value == temp)
+ *mA = usb_ma_table[i].usb_ma;
+ }
+ return rc;
+}
+
#define PM8921_CHG_WD_MASK 0x1F
static int pm_chg_disable_wd(struct pm8921_chg_chip *chip)
{
@@ -1209,27 +1246,17 @@
}
}
-struct usb_ma_limit_entry {
- int usb_ma;
- u8 chg_iusb_value;
-};
-
-static struct usb_ma_limit_entry usb_ma_table[] = {
- {100, 0},
- {500, 1},
- {700, 2},
- {850, 3},
- {900, 4},
- {1100, 5},
- {1300, 6},
- {1500, 7},
-};
-
/* assumes vbus_lock is held */
static void __pm8921_charger_vbus_draw(unsigned int mA)
{
int i, rc;
+ if (usb_max_current && mA > usb_max_current) {
+ pr_warn("restricting usb current to %d instead of %d\n",
+ usb_max_current, mA);
+ mA = usb_max_current;
+ }
+
if (mA > 0 && mA <= 2) {
usb_chg_current = 0;
rc = pm_chg_iusbmax_set(the_chip,
@@ -2391,6 +2418,28 @@
param_get_uint,
&thermal_mitigation, 0644);
+static int set_usb_max_current(const char *val, struct kernel_param *kp)
+{
+ int ret, mA;
+ struct pm8921_chg_chip *chip = the_chip;
+
+ ret = param_set_int(val, kp);
+ if (ret) {
+ pr_err("error setting value %d\n", ret);
+ return ret;
+ }
+ if (chip) {
+ pr_warn("setting current max to %d\n", usb_max_current);
+ pm_chg_iusbmax_get(chip, &mA);
+ if (mA > usb_max_current)
+ pm8921_charger_vbus_draw(usb_max_current);
+ return 0;
+ }
+ return -EINVAL;
+}
+module_param_call(usb_max_current, set_usb_max_current, param_get_uint,
+ &usb_max_current, 0644);
+
static void free_irqs(struct pm8921_chg_chip *chip)
{
int i;
@@ -3200,6 +3249,7 @@
enable_irq_wake(chip->pmic_chg_irq[USBIN_UV_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[BAT_TEMP_OK_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[VBATDET_LOW_IRQ]);
+ enable_irq_wake(chip->pmic_chg_irq[FASTCHG_IRQ]);
/*
* if both the cool_temp_dc and warm_temp_dc are invalid device doesnt
* care for jeita compliance
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index ee7a2a9..c0c6c1e 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -1493,6 +1493,7 @@
}
static struct platform_driver android_platform_driver = {
+ .probe = android_probe,
.driver = { .name = "android_usb"},
};
@@ -1527,7 +1528,7 @@
composite_driver.setup = android_setup;
composite_driver.disconnect = android_disconnect;
- ret = platform_driver_probe(&android_platform_driver, android_probe);
+ ret = platform_driver_register(&android_platform_driver);
if (ret) {
pr_err("%s(): Failed to register android"
"platform driver\n", __func__);
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index 10a9256..987ae65 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -525,7 +525,6 @@
if (rc) {
ERROR(dev->cdev, "can't enable %s, result %d\n",
dev->in->name, rc);
- dev->in->driver_data = NULL;
return rc;
}
dev->out->driver_data = dev;
@@ -534,8 +533,6 @@
ERROR(dev->cdev, "can't enable %s, result %d\n",
dev->out->name, rc);
usb_ep_disable(dev->in);
- dev->in->driver_data = NULL;
- dev->out->driver_data = NULL;
return rc;
}
schedule_work(&dev->config_work);
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index f59b683..2049dc0 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -5,7 +5,7 @@
* Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
* Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
* Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -116,6 +116,8 @@
atomic_t online;
atomic_t notify_count;
+ struct platform_driver pdrv;
+ u8 is_pdrv_used;
struct rmnet_smd_ch_info smd_ctl;
struct rmnet_smd_ch_info smd_data;
@@ -134,6 +136,8 @@
unsigned long cpkts_to_modem;
};
+static struct rmnet_smd_dev *rmnet_smd;
+
static struct usb_interface_descriptor rmnet_smd_interface_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
@@ -856,6 +860,10 @@
list_add_tail(&qmi->list, &dev->qmi_resp_pool);
}
+ if (dev->is_pdrv_used) {
+ platform_driver_unregister(&dev->pdrv);
+ dev->is_pdrv_used = 0;
+ }
}
/* SMD close may sleep
@@ -894,7 +902,18 @@
ret = smd_open(rmnet_ctl_ch, &dev->smd_ctl.ch,
&dev->smd_ctl, rmnet_smd_event_notify);
if (ret) {
- ERROR(cdev, "Unable to open control smd channel\n");
+ ERROR(cdev, "Unable to open control smd channel: %d\n", ret);
+ /*
+ * Register platform driver to be notified in case SMD channels
+ * later becomes ready to be opened.
+ */
+ ret = platform_driver_register(&dev->pdrv);
+ if (ret)
+ ERROR(cdev, "Platform driver %s register failed %d\n",
+ dev->pdrv.driver.name, ret);
+ else
+ dev->is_pdrv_used = 1;
+
return;
}
wait_event(dev->smd_ctl.wait, test_bit(CH_OPENED,
@@ -916,6 +935,15 @@
rmnet_smd_start_rx(dev);
}
+static int rmnet_smd_ch_probe(struct platform_device *pdev)
+{
+ DBG(rmnet_smd->cdev, "Probe called for device: %s\n", pdev->name);
+
+ queue_work(rmnet_smd->wq, &rmnet_smd->connect_work);
+
+ return 0;
+}
+
/* SMD open may sleep.
* Schedule a work to open smd channels and enable
* endpoints if smd channels are opened successfully.
@@ -1272,6 +1300,8 @@
if (!dev)
return -ENOMEM;
+ rmnet_smd = dev;
+
dev->wq = create_singlethread_workqueue("k_rmnet_work");
if (!dev->wq) {
ret = -ENOMEM;
@@ -1299,6 +1329,10 @@
init_waitqueue_head(&dev->smd_ctl.wait);
init_waitqueue_head(&dev->smd_data.wait);
+ dev->pdrv.probe = rmnet_smd_ch_probe;
+ dev->pdrv.driver.name = CONFIG_RMNET_SMD_CTL_CHANNEL;
+ dev->pdrv.driver.owner = THIS_MODULE;
+
INIT_LIST_HEAD(&dev->qmi_req_pool);
INIT_LIST_HEAD(&dev->qmi_req_q);
INIT_LIST_HEAD(&dev->qmi_resp_pool);
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index d9a901b..de8c8ed 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -477,7 +477,6 @@
if (gser->notify->driver_data) {
DBG(cdev, "reset generic ctl ttyGS%d\n", gser->port_num);
usb_ep_disable(gser->notify);
- gser->notify->driver_data = NULL;
}
gser->notify_desc = ep_choose(cdev->gadget,
gser->hs.notify,
@@ -520,7 +519,6 @@
#ifdef CONFIG_MODEM_SUPPORT
usb_ep_fifo_flush(gser->notify);
usb_ep_disable(gser->notify);
- gser->notify->driver_data = NULL;
#endif
gser->online = 0;
}
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ca298cd..0360f56 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -2766,17 +2766,14 @@
if (fsg->bulk_in_enabled) {
usb_ep_disable(fsg->bulk_in);
fsg->bulk_in_enabled = 0;
- fsg_bulk_in->driver_data = NULL;
}
if (fsg->bulk_out_enabled) {
usb_ep_disable(fsg->bulk_out);
fsg->bulk_out_enabled = 0;
- fsg_bulk_out->driver_data = NULL;
}
if (fsg->intr_in_enabled) {
usb_ep_disable(fsg->intr_in);
fsg->intr_in_enabled = 0;
- fsg_intr_in->driver_data = NULL;
}
fsg->running = 0;
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index edba510..a55fc77 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -59,7 +59,7 @@
struct grmnet *port_usb;
spinlock_t port_lock;
- struct work_struct connect_w;
+ struct delayed_work connect_w;
};
static struct rmnet_ctrl_ports {
@@ -320,7 +320,7 @@
static void grmnet_ctrl_smd_connect_w(struct work_struct *w)
{
struct rmnet_ctrl_port *port =
- container_of(w, struct rmnet_ctrl_port, connect_w);
+ container_of(w, struct rmnet_ctrl_port, connect_w.work);
struct smd_ch_info *c = &port->ctrl_ch;
unsigned long flags;
int ret;
@@ -332,8 +332,16 @@
ret = smd_open(c->name, &c->ch, port, grmnet_ctrl_smd_notify);
if (ret) {
- pr_err("%s: Unable to open smd ch:%s err:%d\n",
- __func__, c->name, ret);
+ if (ret == -EAGAIN) {
+ /* port not ready - retry */
+ pr_debug("%s: SMD port not ready - rescheduling:%s err:%d\n",
+ __func__, c->name, ret);
+ queue_delayed_work(grmnet_ctrl_wq, &port->connect_w,
+ msecs_to_jiffies(250));
+ } else {
+ pr_err("%s: unable to open smd port:%s err:%d\n",
+ __func__, c->name, ret);
+ }
return;
}
@@ -370,7 +378,7 @@
gr->notify_modem = gsmd_ctrl_send_cbits_tomodem;
spin_unlock_irqrestore(&port->port_lock, flags);
- queue_work(grmnet_ctrl_wq, &port->connect_w);
+ queue_delayed_work(grmnet_ctrl_wq, &port->connect_w, 0);
return 0;
}
@@ -442,7 +450,8 @@
/* if usb is online, try opening smd_ch */
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_usb)
- queue_work(grmnet_ctrl_wq, &port->connect_w);
+ queue_delayed_work(grmnet_ctrl_wq,
+ &port->connect_w, 0);
spin_unlock_irqrestore(&port->port_lock, flags);
break;
@@ -503,7 +512,7 @@
port->port_num = portno;
spin_lock_init(&port->port_lock);
- INIT_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
+ INIT_DELAYED_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
c = &port->ctrl_ch;
c->name = rmnet_ctrl_names[portno];
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 5caecfb..896f21b 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1864,7 +1864,6 @@
otg->state = OTG_STATE_B_PERIPHERAL;
break;
case USB_SDP_CHARGER:
- msm_otg_notify_charger(motg, IUNIT);
msm_otg_start_peripheral(otg, 1);
otg->state = OTG_STATE_B_PERIPHERAL;
break;
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h
index c47b6ec..de8d490 100644
--- a/drivers/usb/serial/usb-wwan.h
+++ b/drivers/usb/serial/usb-wwan.h
@@ -31,10 +31,10 @@
/* per port private data */
-#define N_IN_URB 4
-#define N_OUT_URB 4
-#define IN_BUFLEN 4096
-#define OUT_BUFLEN 4096
+#define N_IN_URB 5
+#define N_OUT_URB 5
+#define IN_BUFLEN 65536
+#define OUT_BUFLEN 65536
struct usb_wwan_intf_private {
spinlock_t susp_lock;
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index fcf4b08..2a08101 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -410,6 +410,7 @@
tty->raw = 1;
tty->real_raw = 1;
+ set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);
dbg("%s", __func__);
/* Start reading from the IN endpoint */
@@ -552,7 +553,7 @@
init_usb_anchor(&portdata->delayed);
for (j = 0; j < N_IN_URB; j++) {
- buffer = (u8 *) __get_free_page(GFP_KERNEL);
+ buffer = kmalloc(IN_BUFLEN, GFP_KERNEL);
if (!buffer)
goto bail_out_error;
portdata->in_buffer[j] = buffer;
@@ -581,8 +582,7 @@
kfree(portdata->out_buffer[j]);
bail_out_error:
for (j = 0; j < N_IN_URB; j++)
- if (portdata->in_buffer[j])
- free_page((unsigned long)portdata->in_buffer[j]);
+ kfree(portdata->in_buffer[j]);
kfree(portdata);
return 1;
}
@@ -628,8 +628,7 @@
for (j = 0; j < N_IN_URB; j++) {
usb_free_urb(portdata->in_urbs[j]);
- free_page((unsigned long)
- portdata->in_buffer[j]);
+ kfree(portdata->in_buffer[j]);
portdata->in_urbs[j] = NULL;
}
for (j = 0; j < N_OUT_URB; j++) {
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 1449c8e..512480c 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1326,10 +1326,9 @@
struct msm_fb_panel_data *pdata = NULL;
int rc;
resource_size_t size ;
+ unsigned long flag;
#ifdef CONFIG_FB_MSM_MDP40
int intf, if_no;
-#else
- unsigned long flag;
#endif
#if defined(CONFIG_FB_MSM_MIPI_DSI) && defined(CONFIG_FB_MSM_MDP40)
struct mipi_panel_info *mipi;
@@ -1474,6 +1473,17 @@
mfd->vsync_gpio = -1;
#ifdef CONFIG_FB_MSM_MDP40
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ mdp_intr_mask |= INTR_OVERLAY0_DONE;
+ if (mdp_hw_revision < MDP4_REVISION_V2_1) {
+ /* dmas dmap switch */
+ mdp_intr_mask |= INTR_DMA_S_DONE;
+ }
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
if (mfd->panel.type == EBI2_PANEL)
intf = EBI2_INTF;
else
@@ -1530,10 +1540,8 @@
case MIPI_CMD_PANEL:
#ifndef CONFIG_FB_MSM_MDP303
mfd->dma_fnc = mdp4_dsi_cmd_overlay;
-#ifdef CONFIG_FB_MSM_MDP40
mipi = &mfd->panel_info.mipi;
configure_mdp_core_clk_table((mipi->dsi_pclk_rate) * 3 / 2);
-#endif
if (mfd->panel_info.pdest == DISPLAY_1) {
if_no = PRIMARY_INTF_SEL;
mfd->dma = &dma2_data;
@@ -1544,6 +1552,13 @@
mfd->lut_update = mdp_lut_update_nonlcdc;
mfd->do_histogram = mdp_do_histogram;
mdp4_display_intf_sel(if_no, DSI_CMD_INTF);
+
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ mdp_intr_mask |= INTR_OVERLAY0_DONE;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
#else
mfd->dma_fnc = mdp_dma2_update;
mfd->do_histogram = mdp_do_histogram;
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index db1580e..3862823 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -130,8 +130,7 @@
#define INTR_OVERLAY2_DONE BIT(30)
#ifdef CONFIG_FB_MSM_OVERLAY
-#define MDP4_ANY_INTR_MASK (INTR_OVERLAY0_DONE|INTR_DMA_S_DONE | \
- INTR_DMA_P_HISTOGRAM)
+#define MDP4_ANY_INTR_MASK (INTR_DMA_P_HISTOGRAM)
#else
#define MDP4_ANY_INTR_MASK (INTR_DMA_P_DONE| \
INTR_DMA_P_HISTOGRAM)
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index a262cc4..3a1a9aa 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -455,7 +455,7 @@
if (!(data & 0x1) || (pipe == NULL))
return;
wait_for_completion_timeout(&dtv_pipe->comp,
- msecs_to_jiffies(VSYNC_PERIOD));
+ msecs_to_jiffies(VSYNC_PERIOD*2));
mdp_disable_irq(MDP_OVERLAY1_TERM);
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index d2969b6..51a72c8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1457,6 +1457,7 @@
vcd_status = VCD_S_SUCCESS;
}
}
+ break;
case VCD_I_INTRA_REFRESH:
{
struct vcd_property_intra_refresh_mb_number
diff --git a/include/linux/genlock.h b/include/linux/genlock.h
index 2e9f9d6..9351a15 100644
--- a/include/linux/genlock.h
+++ b/include/linux/genlock.h
@@ -12,7 +12,7 @@
struct genlock *genlock_create_lock(struct genlock_handle *);
struct genlock *genlock_attach_lock(struct genlock_handle *, int fd);
int genlock_wait(struct genlock_handle *handle, u32 timeout);
-void genlock_release_lock(struct genlock_handle *);
+/* genlock_release_lock was deprecated */
int genlock_lock(struct genlock_handle *handle, int op, int flags,
u32 timeout);
#endif
@@ -39,6 +39,8 @@
struct genlock_lock)
#define GENLOCK_IOC_LOCK _IOW(GENLOCK_IOC_MAGIC, 3, \
struct genlock_lock)
+
+/* Deprecated */
#define GENLOCK_IOC_RELEASE _IO(GENLOCK_IOC_MAGIC, 4)
#define GENLOCK_IOC_WAIT _IOW(GENLOCK_IOC_MAGIC, 5, \
struct genlock_lock)
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 7ae8342..500ee6b 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -46,6 +46,8 @@
unsigned int x_size;
unsigned int y_size;
+ unsigned int touch_x_size;
+ unsigned int touch_y_size;
unsigned long irqflags;
bool i2c_pull_up;
bool digital_pwr_regulator;
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index f9fc498..c4f601b 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -172,6 +172,15 @@
*/
int pm8xxx_preload_dVdd(void);
+/**
+ * pm8xxx_usb_id_pullup - Control a pullup for USB ID
+ *
+ * @enable: enable (1) or disable (0) the pullup
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_usb_id_pullup(int enable);
+
#else
static inline int pm8xxx_reset_pwr_off(int reset)
@@ -212,6 +221,10 @@
{
return -ENODEV;
}
+static inline int pm8xxx_usb_id_pullup(int enable)
+{
+ return -ENODEV;
+}
#endif
#endif
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 4918caa..0a3b91d 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -1158,6 +1158,7 @@
if (skb->len < sizeof(*grsp))
goto cpl_finished;
grsp = (struct a2mp_getinfo_rsp *) skb_pull(skb, sizeof(*hdr));
+ skb_pull(skb, sizeof(*grsp));
if (grsp->status)
goto cpl_finished;
if (grsp->id != ctx->d.cpl.remote_id)
@@ -1171,7 +1172,6 @@
ctrl->min_latency = le32_to_cpu(grsp->min_latency);
ctrl->pal_cap = le16_to_cpu(grsp->pal_cap);
ctrl->max_assoc_size = le16_to_cpu(grsp->assoc_size);
- skb_pull(skb, sizeof(*grsp));
ctx->d.cpl.max_len = ctrl->max_assoc_size;
@@ -1191,8 +1191,6 @@
goto cpl_finished;
hdr = (void *) skb->data;
arsp = (void *) skb_pull(skb, sizeof(*hdr));
- if (arsp->id != ctx->d.cpl.remote_id)
- goto cpl_finished;
if (arsp->status != 0)
goto cpl_finished;
@@ -1200,12 +1198,12 @@
assoc = (u8 *) skb_pull(skb, sizeof(*arsp));
ctx->d.cpl.len_so_far = 0;
ctx->d.cpl.rem_len = hdr->len - sizeof(*arsp);
+ skb_pull(skb, ctx->d.cpl.rem_len);
rassoc = kmalloc(ctx->d.cpl.rem_len, GFP_ATOMIC);
if (!rassoc)
goto cpl_finished;
memcpy(rassoc, assoc, ctx->d.cpl.rem_len);
ctx->d.cpl.remote_assoc = rassoc;
- skb_pull(skb, ctx->d.cpl.rem_len);
/* set up CPL command */
ctx->d.cpl.phy_handle = physlink_handle(ctx->hdev);
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 92d72b7..0719874 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -523,6 +523,7 @@
struct sock *sk = sock->sk;
struct hci_dev *hdev;
struct sk_buff *skb;
+ int reserve = 0;
int err;
BT_DBG("sock %p sk %p", sock, sk);
@@ -560,10 +561,18 @@
goto done;
}
- skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
+ /* Allocate extra headroom for Qualcomm PAL */
+ if (hdev->dev_type == HCI_AMP && hdev->manufacturer == 0x001d)
+ reserve = BT_SKB_RESERVE_80211;
+
+ skb = bt_skb_send_alloc(sk, len + reserve,
+ msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
goto done;
+ if (reserve)
+ skb_reserve(skb, reserve);
+
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
err = -EFAULT;
goto drop;
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 96260ab..27a27ec 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -420,6 +420,7 @@
switch (dai->id) {
case PRIMARY_I2S_TX:
case PRIMARY_I2S_RX:
+ case SECONDARY_I2S_RX:
rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream);
break;
case MI2S_RX:
@@ -820,6 +821,7 @@
case PRIMARY_I2S_TX:
case PRIMARY_I2S_RX:
case MI2S_RX:
+ case SECONDARY_I2S_RX:
rc = msm_dai_q6_cdc_set_fmt(dai, fmt);
break;
default:
@@ -1086,6 +1088,7 @@
switch (pdev->id) {
case PRIMARY_I2S_RX:
+ case SECONDARY_I2S_RX:
rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_rx_dai);
break;
case PRIMARY_I2S_TX:
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 1331ebf..94ed504 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -118,6 +118,7 @@
{ VOICE_RECORD_RX, 0, NULL, 0, 0},
{ VOICE_RECORD_TX, 0, NULL, 0, 0},
{ MI2S_RX, 0, NULL, 0, 0},
+ { SECONDARY_I2S_RX, 0, NULL, 0, 0},
};
@@ -668,6 +669,21 @@
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_I2S_RX ,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -824,6 +840,15 @@
msm_routing_put_voice_mixer),
};
+static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = {
+ SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+};
+
static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -1134,6 +1159,8 @@
/* Stream name equals to backend dai link stream name
*/
SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback",
+ 0, 0, 0 , 0),
SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
@@ -1166,6 +1193,8 @@
/* Mixer definitions */
SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+ sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
@@ -1186,6 +1215,10 @@
SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
ARRAY_SIZE(pri_rx_voice_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_RX_Voice Mixer",
+ SND_SOC_NOPM, 0, 0,
+ sec_i2s_rx_voice_mixer_controls,
+ ARRAY_SIZE(sec_i2s_rx_voice_mixer_controls)),
SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
SND_SOC_NOPM, 0, 0,
slimbus_rx_voice_mixer_controls,
@@ -1230,6 +1263,12 @@
{"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
+ {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"},
+
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -1295,6 +1334,10 @@
{"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
+ {"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
+ {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
+
{"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index a8d2d91..25efb58 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,7 @@
#define LPASS_BE_VOICE_PLAYBACK_TX "(Backend) VOICE_PLAYBACK_TX"
#define LPASS_BE_INCALL_RECORD_RX "(Backend) INCALL_RECORD_TX"
#define LPASS_BE_INCALL_RECORD_TX "(Backend) INCALL_RECORD_RX"
+#define LPASS_BE_SEC_I2S_RX "(Backend) SECONDARY_I2S_RX"
#define LPASS_BE_MI2S_RX "(Backend) MI2S_RX"
@@ -71,6 +72,7 @@
MSM_BACKEND_DAI_INCALL_RECORD_RX,
MSM_BACKEND_DAI_INCALL_RECORD_TX,
MSM_BACKEND_DAI_MI2S_RX,
+ MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_BACKEND_DAI_MAX,
};