Merge "mmc: msm_sdcc: remove CONFIG_MMC_MSM_SDIO_SUPPORT completely" into msm-3.0
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 35e8eba..ec71565 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -171,7 +171,7 @@
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
{ 0, 400000, ACPU_PLL_4, 6, 1, 50000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
@@ -186,7 +186,7 @@
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 120000 },
{ 0, 400000, ACPU_PLL_4, 6, 1, 50000, 3, 4, 120000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
@@ -200,8 +200,8 @@
{ 0, 300000, ACPU_PLL_2, 2, 3, 37500, 3, 4, 122880 },
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
- { 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+ { 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 160000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
@@ -215,8 +215,8 @@
{ 0, 300000, ACPU_PLL_2, 2, 3, 37500, 3, 4, 122880 },
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
- { 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+ { 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 160000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
@@ -229,8 +229,8 @@
{ 1, 245760, ACPU_PLL_1, 1, 0, 30720, 3, 3, 61440 },
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
- { 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 200000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
+ { 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 160000 },
{ 1, 1209600, ACPU_PLL_4, 6, 0, 151200, 3, 7, 200000},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
@@ -243,8 +243,8 @@
{ 1, 196608, ACPU_PLL_1, 1, 0, 24576, 3, 3, 98304 },
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
- { 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 200000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
+ { 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 160000 },
{ 1, 1209600, ACPU_PLL_4, 6, 0, 151200, 3, 7, 200000},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
@@ -273,7 +273,7 @@
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
{ 0, 400000, ACPU_PLL_4, 6, 1, 50000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
@@ -288,7 +288,7 @@
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 120000 },
{ 0, 400000, ACPU_PLL_4, 6, 1, 50000, 3, 4, 120000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
@@ -302,8 +302,8 @@
{ 0, 300000, ACPU_PLL_2, 2, 3, 37500, 3, 4, 122880 },
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
- { 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+ { 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 160000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
@@ -317,8 +317,8 @@
{ 0, 300000, ACPU_PLL_2, 2, 3, 37500, 3, 4, 122880 },
{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
- { 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
- { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+ { 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 160000 },
+ { 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 9080e60..c7b3af5 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -499,6 +499,41 @@
.sensor_type = BAYER_SENSOR,
};
+static struct camera_vreg_t apq_8064_s5k3l1yx_vreg[] = {
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vio", REG_VS, 0, 0, 0},
+ {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_csi_lane_params s5k3l1yx_csi_lane_params = {
+ .csi_lane_assign = 0xE4,
+ .csi_lane_mask = 0xF,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_s5k3l1yx = {
+ .mount_angle = 90,
+ .cam_vreg = apq_8064_s5k3l1yx_vreg,
+ .num_vreg = ARRAY_SIZE(apq_8064_s5k3l1yx_vreg),
+ .gpio_conf = &apq8064_back_cam_gpio_conf,
+ .i2c_conf = &apq8064_back_cam_i2c_conf,
+ .csi_lane_params = &s5k3l1yx_csi_lane_params,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_s5k3l1yx_data = {
+ .sensor_name = "s5k3l1yx",
+ .pdata = &msm_camera_csi_device_data[0],
+ .flash_data = &flash_s5k3l1yx,
+ .sensor_platform_info = &sensor_board_info_s5k3l1yx,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+};
+
static struct camera_vreg_t apq_8064_mt9m114_vreg[] = {
{"cam_vio", REG_VS, 0, 0, 0},
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
@@ -603,6 +638,10 @@
I2C_BOARD_INFO("imx091", 0x34),
.platform_data = &msm_camera_sensor_imx091_data,
},
+ {
+ I2C_BOARD_INFO("s5k3l1yx", 0x20),
+ .platform_data = &msm_camera_sensor_s5k3l1yx_data,
+ },
};
struct msm_camera_board_info apq8064_camera_board_info = {
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 24df393..ae2de20 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -62,6 +62,7 @@
REGULATOR_SUPPLY("cam_vana", "4-0048"),
REGULATOR_SUPPLY("cam_vana", "4-006c"),
REGULATOR_SUPPLY("cam_vana", "4-0034"),
+ REGULATOR_SUPPLY("cam_vana", "4-0020"),
};
VREG_CONSUMERS(L9) = {
REGULATOR_SUPPLY("8921_l9", NULL),
@@ -80,6 +81,7 @@
REGULATOR_SUPPLY("cam_vdig", "4-0048"),
REGULATOR_SUPPLY("cam_vdig", "4-006c"),
REGULATOR_SUPPLY("cam_vdig", "4-0034"),
+ REGULATOR_SUPPLY("cam_vdig", "4-0020"),
REGULATOR_SUPPLY("8921_l12", NULL),
};
VREG_CONSUMERS(L14) = {
@@ -94,6 +96,7 @@
REGULATOR_SUPPLY("cam_vaf", "4-0048"),
REGULATOR_SUPPLY("cam_vaf", "4-006c"),
REGULATOR_SUPPLY("cam_vaf", "4-0034"),
+ REGULATOR_SUPPLY("cam_vaf", "4-0020"),
};
VREG_CONSUMERS(L17) = {
REGULATOR_SUPPLY("8921_l17", NULL),
@@ -197,6 +200,7 @@
REGULATOR_SUPPLY("cam_vio", "4-0048"),
REGULATOR_SUPPLY("cam_vio", "4-006c"),
REGULATOR_SUPPLY("cam_vio", "4-0034"),
+ REGULATOR_SUPPLY("cam_vio", "4-0020"),
};
VREG_CONSUMERS(LVS6) = {
REGULATOR_SUPPLY("8921_lvs6", NULL),
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index e96284a..e2076f8 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -28,7 +28,7 @@
#include "board-msm7627a.h"
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
-#define MSM_FB_SIZE 0x261000
+#define MSM_FB_SIZE 0x2FD000
#define MSM7x25A_MSM_FB_SIZE 0xE1000
#else
#define MSM_FB_SIZE 0x196000
@@ -684,6 +684,18 @@
}
};
+static struct msm_panel_common_pdata mipi_NT35516_pdata = {
+ .pmic_backlight = NULL,
+};
+
+static struct platform_device mipi_dsi_NT35516_panel_device = {
+ .name = "mipi_truly_tft540960_1_e",
+ .id = 0,
+ .dev = {
+ .platform_data = &mipi_NT35516_pdata,
+ }
+};
+
static struct platform_device *msm_fb_devices[] __initdata = {
&msm_fb_device,
&lcdc_toshiba_panel_device,
@@ -708,6 +720,7 @@
static struct platform_device *evb_fb_devices[] __initdata = {
&msm_fb_device,
&mipi_dsi_NT35510_panel_device,
+ &mipi_dsi_NT35516_panel_device,
};
void __init msm_msm7627a_allocate_memory_regions(void)
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 60457cc..7b27c4e 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -797,9 +797,9 @@
ARRAY_SIZE(qrd7627a_devices));
}
- if (machine_is_msm7627a_qrd3())
+ if (machine_is_msm7627a_qrd3() || machine_is_msm7627a_evb())
platform_add_devices(qrd3_devices,
- ARRAY_SIZE(qrd3_devices));
+ ARRAY_SIZE(qrd3_devices));
platform_add_devices(common_devices,
ARRAY_SIZE(common_devices));
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 794c342..7d1bcf3 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5007,6 +5007,7 @@
CLK_LOOKUP("core_clk", amp_clk.c, ""),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-001a"),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0034"),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0020"),
CLK_LOOKUP("cam_clk", cam1_clk.c, "4-0048"),
CLK_LOOKUP("cam_clk", cam1_clk.c, "4-006c"),
CLK_LOOKUP("csi_src_clk", csi0_src_clk.c, "msm_csid.0"),
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
index dd5ddd8..bd303b2 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
@@ -135,6 +135,8 @@
uint16_t event_types;
/* Input event source */
enum us_input_event_src_type event_src;
+ /* Bitmap of types of events from devs, conflicting with USF */
+ uint16_t conflicting_event_types;
};
struct us_tx_info_type {
@@ -208,6 +210,8 @@
/* Time (sec) to wait for data or special values: */
/* USF_NO_WAIT_TIMEOUT, USF_INFINITIVE_TIMEOUT, USF_DEFAULT_TIMEOUT */
uint32_t timeout;
+/* Events (from conflicting devs) to be disabled/enabled */
+ uint16_t event_filters;
/* Input transparent data: */
/* Parameters size */
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile b/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
index 540119b..0be1303 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
@@ -1,2 +1,2 @@
-obj-y += q6usm.o usf.o
+obj-y += q6usm.o usf.o usfcdev.o
EXTRA_CFLAGS += -I$(src)/..
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
index 64f70c5..b4a0a7f 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
@@ -24,9 +24,10 @@
#include <sound/apr_audio.h>
#include <mach/qdsp6v2/usf.h>
#include "q6usm.h"
+#include "usfcdev.h"
/* The driver version*/
-#define DRV_VERSION "1.2"
+#define DRV_VERSION "1.3"
/* Standard timeout in the asynchronous ops */
#define USF_TIMEOUT_JIFFIES (3*HZ) /* 3 sec */
@@ -111,6 +112,10 @@
struct input_dev *input_if;
/* The event source */
int event_src;
+ /* Bitmap of types of events, conflicting to USF's ones */
+ uint16_t conflicting_event_types;
+ /* Bitmap of types of events from devs, conflicting with USF */
+ uint16_t conflicting_event_filters;
};
/* The MAX number of the supported devices */
@@ -126,6 +131,9 @@
/* The opened devices container */
static int s_opened_devs[MAX_DEVS_NUMBER];
+#define USF_NAME_PREFIX "USF_"
+#define USF_NAME_PREFIX_SIZE 4
+
static void usf_rx_cb(uint32_t opcode, uint32_t token,
uint32_t *payload, void *priv)
{
@@ -316,11 +324,70 @@
return rc;
}
+static bool usf_match(uint16_t event_type_ind, struct input_dev *dev)
+{
+ bool rc = false;
+
+ rc = (event_type_ind < MAX_EVENT_TYPE_NUM) &&
+ ((dev->name == NULL) ||
+ strncmp(dev->name, USF_NAME_PREFIX, USF_NAME_PREFIX_SIZE));
+ pr_debug("%s: name=[%s]; rc=%d\n",
+ __func__, dev->name, rc);
+
+ return rc;
+}
+
+static bool usf_register_conflicting_events(uint16_t event_types)
+{
+ bool rc = true;
+ uint16_t ind = 0;
+ uint16_t mask = 1;
+
+ for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) {
+ if (event_types & mask) {
+ rc = usfcdev_register(ind, usf_match);
+ if (!rc)
+ break;
+ }
+ mask = mask << 1;
+ }
+
+ return rc;
+}
+
+static void usf_unregister_conflicting_events(uint16_t event_types)
+{
+ uint16_t ind = 0;
+ uint16_t mask = 1;
+
+ for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) {
+ if (event_types & mask)
+ usfcdev_unregister(ind);
+ mask = mask << 1;
+ }
+}
+
+static void usf_set_event_filters(struct usf_type *usf, uint16_t event_filters)
+{
+ uint16_t ind = 0;
+ uint16_t mask = 1;
+
+ if (usf->conflicting_event_filters != event_filters) {
+ for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) {
+ if (usf->conflicting_event_types & mask)
+ usfcdev_set_filter(ind, event_filters&mask);
+ mask = mask << 1;
+ }
+ usf->conflicting_event_filters = event_filters;
+ }
+}
+
static int register_input_device(struct usf_type *usf_info,
struct us_input_info_type *input_info)
{
int rc = 0;
struct input_dev *input_dev = NULL;
+ bool ret = true;
if ((usf_info == NULL) ||
(input_info == NULL) ||
@@ -417,6 +484,11 @@
usf_info->event_types = input_info->event_types;
pr_debug("%s: input device[%s] was registered\n",
__func__, input_dev->name);
+ ret = usf_register_conflicting_events(
+ input_info->conflicting_event_types);
+ if (ret)
+ usf_info->conflicting_event_types =
+ input_info->conflicting_event_types;
}
return rc;
@@ -826,6 +898,7 @@
}
if (!usf_xx->user_upd_info_na) {
+ usf_set_event_filters(usf, upd_tx_info.event_filters);
handle_input_event(usf,
upd_tx_info.event_counter,
upd_tx_info.event);
@@ -963,16 +1036,23 @@
return rc;
} /* usf_set_rx_update */
+static void usf_release_input(struct usf_type *usf)
+{
+ if (usf->input_if != NULL) {
+ usf_unregister_conflicting_events(
+ usf->conflicting_event_types);
+ usf->conflicting_event_types = 0;
+ input_unregister_device(usf->input_if);
+ usf->input_if = NULL;
+ pr_debug("%s input_unregister_device\n", __func__);
+ }
+} /* usf_release_input */
+
static int usf_stop_tx(struct usf_type *usf)
{
struct usf_xx_type *usf_xx = &usf->usf_tx;
- if (usf->input_if != NULL) {
- input_unregister_device(usf->input_if);
- usf->input_if = NULL;
- pr_debug("%s input_unregister_device",
- __func__);
- }
+ usf_release_input(usf);
usf_disable(usf_xx);
return 0;
@@ -1225,18 +1305,13 @@
return 0;
}
-
static int usf_release(struct inode *inode, struct file *file)
{
struct usf_type *usf = file->private_data;
pr_debug("%s: release entry\n", __func__);
- if (usf->input_if != NULL) {
- input_unregister_device(usf->input_if);
- usf->input_if = NULL;
- pr_debug("%s input_unregister_device\n", __func__);
- }
+ usf_release_input(usf);
usf_disable(&usf->usf_tx);
usf_disable(&usf->usf_rx);
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
new file mode 100644
index 0000000..b99a9b0
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
@@ -0,0 +1,236 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include "usfcdev.h"
+
+struct usfcdev_event {
+ bool (*match_cb)(uint16_t, struct input_dev *dev);
+ bool registered_event;
+ bool filter;
+};
+static struct usfcdev_event s_usfcdev_events[MAX_EVENT_TYPE_NUM];
+
+static bool usfcdev_filter(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value);
+static bool usfcdev_match(struct input_handler *handler,
+ struct input_dev *dev);
+static int usfcdev_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ const struct input_device_id *id);
+static void usfcdev_disconnect(struct input_handle *handle);
+
+static const struct input_device_id usfc_tsc_ids[] = {
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_KEYBIT |
+ INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
+ .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
+ .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
+ },
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(input, usfc_tsc_ids);
+
+static struct input_handler s_usfc_handlers[MAX_EVENT_TYPE_NUM] = {
+ { /* TSC handler */
+ .filter = usfcdev_filter,
+ .match = usfcdev_match,
+ .connect = usfcdev_connect,
+ .disconnect = usfcdev_disconnect,
+ /* .minor can be used as index in the container, */
+ /* because .fops isn't supported */
+ .minor = TSC_EVENT_TYPE_IND,
+ .name = "usfc_tsc_handler",
+ .id_table = usfc_tsc_ids,
+ },
+};
+
+/* For each event type, one conflicting device (and handle) is supported */
+static struct input_handle s_usfc_handles[MAX_EVENT_TYPE_NUM] = {
+ { /* TSC handle */
+ .handler = &s_usfc_handlers[TSC_EVENT_TYPE_IND],
+ .name = "usfc_tsc_handle",
+ },
+};
+
+static bool usfcdev_match(struct input_handler *handler, struct input_dev *dev)
+{
+ bool rc = false;
+ int ind = handler->minor;
+
+ pr_debug("%s: name=[%s]; ind=%d\n", __func__, dev->name, ind);
+ if (s_usfcdev_events[ind].registered_event &&
+ s_usfcdev_events[ind].match_cb) {
+ rc = (*s_usfcdev_events[ind].match_cb)((uint16_t)ind, dev);
+ pr_debug("%s: [%s]; rc=%d\n", __func__, dev->name, rc);
+ }
+
+ return rc;
+}
+
+static int usfcdev_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
+{
+ int ret = 0;
+ uint16_t ind = handler->minor;
+
+ s_usfc_handles[ind].dev = dev;
+ ret = input_register_handle(&s_usfc_handles[ind]);
+ if (ret) {
+ pr_err("%s: input_register_handle[%d] failed: ret=%d\n",
+ __func__,
+ ind,
+ ret);
+ } else {
+ ret = input_open_device(&s_usfc_handles[ind]);
+ if (ret) {
+ pr_err("%s: input_open_device[%d] failed: ret=%d\n",
+ __func__,
+ ind,
+ ret);
+ input_unregister_handle(&s_usfc_handles[ind]);
+ } else
+ pr_debug("%s: device[%d] is opened\n",
+ __func__,
+ ind);
+ }
+
+ return ret;
+}
+
+static void usfcdev_disconnect(struct input_handle *handle)
+{
+ input_unregister_handle(handle);
+ pr_debug("%s: handle[%d] is disconnect\n",
+ __func__,
+ handle->handler->minor);
+}
+
+static bool usfcdev_filter(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value)
+{
+ uint16_t ind = (uint16_t)handle->handler->minor;
+
+ pr_debug("%s: event_type=%d; filter=%d\n",
+ __func__,
+ ind,
+ s_usfcdev_events[ind].filter);
+
+ return s_usfcdev_events[ind].filter;
+}
+
+bool usfcdev_register(
+ uint16_t event_type_ind,
+ bool (*match_cb)(uint16_t, struct input_dev *dev))
+{
+ int ret = 0;
+ bool rc = false;
+
+ if ((event_type_ind >= MAX_EVENT_TYPE_NUM) || !match_cb) {
+ pr_err("%s: wrong input: event_type_ind=%d; match_cb=0x%p\n",
+ __func__,
+ event_type_ind,
+ match_cb);
+ return false;
+ }
+
+ if (s_usfcdev_events[event_type_ind].registered_event) {
+ pr_info("%s: handler[%d] was already registered\n",
+ __func__,
+ event_type_ind);
+ return true;
+ }
+
+ s_usfcdev_events[event_type_ind].registered_event = true;
+ s_usfcdev_events[event_type_ind].match_cb = match_cb;
+ s_usfcdev_events[event_type_ind].filter = false;
+ ret = input_register_handler(&s_usfc_handlers[event_type_ind]);
+ if (!ret) {
+ rc = true;
+ pr_debug("%s: handler[%d] was registered\n",
+ __func__,
+ event_type_ind);
+ } else {
+ s_usfcdev_events[event_type_ind].registered_event = false;
+ s_usfcdev_events[event_type_ind].match_cb = NULL;
+ pr_err("%s: handler[%d] registration failed: ret=%d\n",
+ __func__,
+ event_type_ind,
+ ret);
+ }
+
+ return rc;
+}
+
+void usfcdev_unregister(uint16_t event_type_ind)
+{
+ if (event_type_ind >= MAX_EVENT_TYPE_NUM) {
+ pr_err("%s: wrong input: event_type_ind=%d\n",
+ __func__,
+ event_type_ind);
+ return;
+ }
+ if (s_usfcdev_events[event_type_ind].registered_event) {
+ input_unregister_handler(&s_usfc_handlers[event_type_ind]);
+ pr_debug("%s: handler[%d] was unregistered\n",
+ __func__,
+ event_type_ind);
+ s_usfcdev_events[event_type_ind].registered_event = false;
+ s_usfcdev_events[event_type_ind].match_cb = NULL;
+ s_usfcdev_events[event_type_ind].filter = false;
+ }
+}
+
+bool usfcdev_set_filter(uint16_t event_type_ind, bool filter)
+{
+ bool rc = true;
+
+ if (event_type_ind >= MAX_EVENT_TYPE_NUM) {
+ pr_err("%s: wrong input: event_type_ind=%d\n",
+ __func__,
+ event_type_ind);
+ return false;
+ }
+
+ if (s_usfcdev_events[event_type_ind].registered_event) {
+ s_usfcdev_events[event_type_ind].filter = filter;
+ pr_debug("%s: event_type[%d]; filter=%d\n",
+ __func__,
+ event_type_ind,
+ filter
+ );
+ } else {
+ pr_err("%s: event_type[%d] isn't registered\n",
+ __func__,
+ event_type_ind);
+ rc = false;
+ }
+
+ return rc;
+}
+
+static int __init usfcdev_init(void)
+{
+ return 0;
+}
+
+device_initcall(usfcdev_init);
+
+MODULE_DESCRIPTION("Handle of events from devices, conflicting with USF");
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
new file mode 100644
index 0000000..042b293
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __USFCDEV_H__
+#define __USFCDEV_H__
+
+#include <linux/input.h>
+
+/* TSC event type index in the containers of the handlers & handles */
+#define TSC_EVENT_TYPE_IND 0
+/* Number of supported event types to be filtered */
+#define MAX_EVENT_TYPE_NUM 1
+
+bool usfcdev_register(
+ uint16_t event_type_ind,
+ bool (*match_cb)(uint16_t, struct input_dev *dev));
+void usfcdev_unregister(uint16_t event_type_ind);
+bool usfcdev_set_filter(uint16_t event_type_ind, bool filter);
+#endif /* __USFCDEV_H__ */
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 28850d0..68e0f41 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -83,6 +83,8 @@
{2, "APPS_RIVA_BT_ACL", NULL, SMD_APPS_WCNSS},
{3, "APPS_RIVA_BT_CMD", NULL, SMD_APPS_WCNSS},
{4, "MBALBRIDGE", NULL, SMD_APPS_MODEM},
+ {5, "APPS_RIVA_ANT_CMD", NULL, SMD_APPS_WCNSS},
+ {6, "APPS_RIVA_ANT_DATA", NULL, SMD_APPS_WCNSS},
{7, "DATA1", NULL, SMD_APPS_MODEM},
{11, "DATA11", NULL, SMD_APPS_MODEM},
{21, "DATA21", NULL, SMD_APPS_MODEM},
diff --git a/drivers/base/base.h b/drivers/base/base.h
index a34dca0..9641309 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -105,6 +105,7 @@
extern void driver_detach(struct device_driver *drv);
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
+extern void driver_deferred_probe_del(struct device *dev);
static inline int driver_match_device(struct device_driver *drv,
struct device *dev)
{
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 78445f4..14cdf13 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -589,6 +589,7 @@
{
dev->kobj.kset = devices_kset;
kobject_init(&dev->kobj, &device_ktype);
+ INIT_LIST_HEAD(&dev->deferred_probe);
INIT_LIST_HEAD(&dev->dma_pools);
mutex_init(&dev->mutex);
lockdep_set_novalidate_class(&dev->mutex);
@@ -1120,6 +1121,7 @@
device_remove_file(dev, &uevent_attr);
device_remove_attrs(dev);
bus_remove_device(dev);
+ driver_deferred_probe_del(dev);
/*
* Some platform devices are driven without driver attached
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 6658da7..455b502 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -28,6 +28,133 @@
#include "base.h"
#include "power/power.h"
+/*
+ * Deferred Probe infrastructure.
+ *
+ * Sometimes driver probe order matters, but the kernel doesn't always have
+ * dependency information which means some drivers will get probed before a
+ * resource it depends on is available. For example, an SDHCI driver may
+ * first need a GPIO line from an i2c GPIO controller before it can be
+ * initialized. If a required resource is not available yet, a driver can
+ * request probing to be deferred by returning -EPROBE_DEFER from its probe hook
+ *
+ * Deferred probe maintains two lists of devices, a pending list and an active
+ * list. A driver returning -EPROBE_DEFER causes the device to be added to the
+ * pending list. A successful driver probe will trigger moving all devices
+ * from the pending to the active list so that the workqueue will eventually
+ * retry them.
+ *
+ * The deferred_probe_mutex must be held any time the deferred_probe_*_list
+ * of the (struct device*)->deferred_probe pointers are manipulated
+ */
+static DEFINE_MUTEX(deferred_probe_mutex);
+static LIST_HEAD(deferred_probe_pending_list);
+static LIST_HEAD(deferred_probe_active_list);
+static struct workqueue_struct *deferred_wq;
+
+/**
+ * deferred_probe_work_func() - Retry probing devices in the active list.
+ */
+static void deferred_probe_work_func(struct work_struct *work)
+{
+ struct device *dev;
+ /*
+ * This block processes every device in the deferred 'active' list.
+ * Each device is removed from the active list and passed to
+ * bus_probe_device() to re-attempt the probe. The loop continues
+ * until every device in the active list is removed and retried.
+ *
+ * Note: Once the device is removed from the list and the mutex is
+ * released, it is possible for the device get freed by another thread
+ * and cause a illegal pointer dereference. This code uses
+ * get/put_device() to ensure the device structure cannot disappear
+ * from under our feet.
+ */
+ mutex_lock(&deferred_probe_mutex);
+ while (!list_empty(&deferred_probe_active_list)) {
+ dev = list_first_entry(&deferred_probe_active_list,
+ typeof(*dev), deferred_probe);
+ list_del_init(&dev->deferred_probe);
+
+ get_device(dev);
+
+ /* Drop the mutex while probing each device; the probe path
+ * may manipulate the deferred list */
+ mutex_unlock(&deferred_probe_mutex);
+ dev_dbg(dev, "Retrying from deferred list\n");
+ bus_probe_device(dev);
+ mutex_lock(&deferred_probe_mutex);
+
+ put_device(dev);
+ }
+ mutex_unlock(&deferred_probe_mutex);
+}
+static DECLARE_WORK(deferred_probe_work, deferred_probe_work_func);
+
+static void driver_deferred_probe_add(struct device *dev)
+{
+ mutex_lock(&deferred_probe_mutex);
+ if (list_empty(&dev->deferred_probe)) {
+ dev_dbg(dev, "Added to deferred list\n");
+ list_add(&dev->deferred_probe, &deferred_probe_pending_list);
+ }
+ mutex_unlock(&deferred_probe_mutex);
+}
+
+void driver_deferred_probe_del(struct device *dev)
+{
+ mutex_lock(&deferred_probe_mutex);
+ if (!list_empty(&dev->deferred_probe)) {
+ dev_dbg(dev, "Removed from deferred list\n");
+ list_del_init(&dev->deferred_probe);
+ }
+ mutex_unlock(&deferred_probe_mutex);
+}
+
+static bool driver_deferred_probe_enable = false;
+/**
+ * driver_deferred_probe_trigger() - Kick off re-probing deferred devices
+ *
+ * This functions moves all devices from the pending list to the active
+ * list and schedules the deferred probe workqueue to process them. It
+ * should be called anytime a driver is successfully bound to a device.
+ */
+static void driver_deferred_probe_trigger(void)
+{
+ if (!driver_deferred_probe_enable)
+ return;
+
+ /* A successful probe means that all the devices in the pending list
+ * should be triggered to be reprobed. Move all the deferred devices
+ * into the active list so they can be retried by the workqueue */
+ mutex_lock(&deferred_probe_mutex);
+ list_splice_tail_init(&deferred_probe_pending_list,
+ &deferred_probe_active_list);
+ mutex_unlock(&deferred_probe_mutex);
+
+ /* Kick the re-probe thread. It may already be scheduled, but
+ * it is safe to kick it again. */
+ queue_work(deferred_wq, &deferred_probe_work);
+}
+
+/**
+ * deferred_probe_initcall() - Enable probing of deferred devices
+ *
+ * We don't want to get in the way when the bulk of drivers are getting probed.
+ * Instead, this initcall makes sure that deferred probing is delayed until
+ * late_initcall time.
+ */
+static int deferred_probe_initcall(void)
+{
+ deferred_wq = create_singlethread_workqueue("deferwq");
+ if (WARN_ON(!deferred_wq))
+ return -ENOMEM;
+
+ driver_deferred_probe_enable = true;
+ driver_deferred_probe_trigger();
+ return 0;
+}
+late_initcall(deferred_probe_initcall);
static void driver_bound(struct device *dev)
{
@@ -42,6 +169,11 @@
klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
+ /* Make sure the device is no longer in one of the deferred lists
+ * and kick off retrying all pending devices */
+ driver_deferred_probe_del(dev);
+ driver_deferred_probe_trigger();
+
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_BOUND_DRIVER, dev);
@@ -142,7 +274,11 @@
driver_sysfs_remove(dev);
dev->driver = NULL;
- if (ret != -ENODEV && ret != -ENXIO) {
+ if (ret == -EPROBE_DEFER) {
+ /* Driver requested deferred probing */
+ dev_info(dev, "Driver %s requests probe deferral\n", drv->name);
+ driver_deferred_probe_add(dev);
+ } else if (ret != -ENODEV && ret != -ENXIO) {
/* driver matched but the probe failed */
printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 4f5c783..fdf7304 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -46,6 +46,7 @@
#define A3XX_RBBM_HW_VERSION 0x000
#define A3XX_RBBM_HW_RELEASE 0x001
#define A3XX_RBBM_HW_CONFIGURATION 0x002
+#define A3XX_RBBM_SP_HYST_CNT 0x012
#define A3XX_RBBM_SW_RESET_CMD 0x018
#define A3XX_RBBM_AHB_CTL0 0x020
#define A3XX_RBBM_AHB_CTL1 0x021
@@ -54,6 +55,7 @@
#define A3XX_RBBM_GPR0_CTL 0x02E
/* This the same register as on A2XX, just in a different place */
#define A3XX_RBBM_STATUS 0x030
+#define A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL 0x33
#define A3XX_RBBM_INTERFACE_HANG_INT_CTL 0x50
#define A3XX_RBBM_INTERFACE_HANG_MASK_CTL0 0x51
#define A3XX_RBBM_INTERFACE_HANG_MASK_CTL1 0x54
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index c01e676..2761b60 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2576,6 +2576,10 @@
/* Make all blocks contribute to the GPU BUSY perf counter */
adreno_regwrite(device, A3XX_RBBM_GPU_BUSY_MASKED, 0xFFFFFFFF);
+ /* Tune the hystersis counters for SP and CP idle detection */
+ adreno_regwrite(device, A3XX_RBBM_SP_HYST_CNT, 0x10);
+ adreno_regwrite(device, A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10);
+
/* Enable the RBBM error reporting bits. This lets us get
useful information on failure */
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 7c26947..deb35cc 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,16 @@
} fmt;
};
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+struct v4l2_create_buffers32 {
+ __u32 index; /* output: buffers index...index + count - 1 have been created */
+ __u32 count;
+ enum v4l2_memory memory;
+ struct v4l2_format32 format; /* filled in by the user, plane sizes calculated by the driver */
+ __u32 reserved[8];
+};
+
+static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
{
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
- get_user(kp->type, &up->type))
- return -EFAULT;
switch (kp->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +197,24 @@
}
}
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
- put_user(kp->type, &up->type))
- return -EFAULT;
+ if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
+ get_user(kp->type, &up->type))
+ return -EFAULT;
+ return __get_v4l2_format32(kp, up);
+}
+
+static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+ if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+ copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
+ return -EFAULT;
+ return __get_v4l2_format32(&kp->format, &up->format);
+}
+
+static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
switch (kp->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +243,22 @@
}
}
+static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
+ put_user(kp->type, &up->type))
+ return -EFAULT;
+ return __put_v4l2_format32(kp, up);
+}
+
+static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+ copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
+ return -EFAULT;
+ return __put_v4l2_format32(&kp->format, &up->format);
+}
+
struct v4l2_standard32 {
__u32 index;
__u32 id[2]; /* __u64 would get the alignment wrong */
@@ -675,6 +709,8 @@
#define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32)
#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
+#define VIDIOC_CREATE_BUFS32 _IOWR('V', 92, struct v4l2_create_buffers32)
+#define VIDIOC_PREPARE_BUF32 _IOWR('V', 93, struct v4l2_buffer32)
#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
#define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
@@ -693,6 +729,7 @@
struct v4l2_input v2i;
struct v4l2_standard v2s;
struct v4l2_ext_controls v2ecs;
+ struct v4l2_create_buffers v2crt;
unsigned long vx;
int vi;
} karg;
@@ -722,6 +759,8 @@
case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
+ case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
+ case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
}
switch (cmd) {
@@ -746,6 +785,12 @@
compatible_arg = 0;
break;
+ case VIDIOC_CREATE_BUFS:
+ err = get_v4l2_create32(&karg.v2crt, up);
+ compatible_arg = 0;
+ break;
+
+ case VIDIOC_PREPARE_BUF:
case VIDIOC_QUERYBUF:
case VIDIOC_QBUF:
case VIDIOC_DQBUF:
@@ -824,6 +869,10 @@
err = put_v4l2_format32(&karg.v2f, up);
break;
+ case VIDIOC_CREATE_BUFS:
+ err = put_v4l2_create32(&karg.v2crt, up);
+ break;
+
case VIDIOC_QUERYBUF:
case VIDIOC_QBUF:
case VIDIOC_DQBUF:
@@ -922,6 +971,8 @@
case VIDIOC_DQEVENT:
case VIDIOC_SUBSCRIBE_EVENT:
case VIDIOC_UNSUBSCRIBE_EVENT:
+ case VIDIOC_CREATE_BUFS32:
+ case VIDIOC_PREPARE_BUF32:
ret = do_video_ioctl(file, cmd, arg);
break;
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index bda252f..5e44c90 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -259,6 +259,8 @@
[_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT",
[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT",
[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
+ [_IOC_NR(VIDIOC_CREATE_BUFS)] = "VIDIOC_CREATE_BUFS",
+ [_IOC_NR(VIDIOC_PREPARE_BUF)] = "VIDIOC_PREPARE_BUF",
};
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
@@ -2196,6 +2198,40 @@
dbgarg(cmd, "type=0x%8.8x", sub->type);
break;
}
+ case VIDIOC_CREATE_BUFS:
+ {
+ struct v4l2_create_buffers *create = arg;
+
+ if (!ops->vidioc_create_bufs)
+ break;
+ /*if (ret_prio) {
+ ret = ret_prio;
+ break;
+ }*/
+ ret = check_fmt(ops, create->format.type);
+ if (ret)
+ break;
+
+ ret = ops->vidioc_create_bufs(file, fh, create);
+
+ dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
+ break;
+ }
+ case VIDIOC_PREPARE_BUF:
+ {
+ struct v4l2_buffer *b = arg;
+
+ if (!ops->vidioc_prepare_buf)
+ break;
+ ret = check_fmt(ops, b->type);
+ if (ret)
+ break;
+
+ ret = ops->vidioc_prepare_buf(file, fh, b);
+
+ dbgarg(cmd, "index=%d", b->index);
+ break;
+ }
default:
{
bool valid_prio = true;
diff --git a/include/linux/device.h b/include/linux/device.h
index e4f62d8..b44a3b1 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -506,6 +506,10 @@
* @mutex: Mutex to synchronize calls to its driver.
* @bus: Type of bus device is on.
* @driver: Which driver has allocated this
+ * @deferred_probe: entry in deferred_probe_list which is used to retry the
+ * binding of drivers which were unable to get all the resources
+ * needed by the device; typically because it depends on another
+ * driver getting probed first.
* @platform_data: Platform data specific to the device.
* Example: For devices on custom boards, as typical of embedded
* and SOC based hardware, Linux often uses platform_data to point
@@ -564,6 +568,7 @@
struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
+ struct list_head deferred_probe;
void *platform_data; /* Platform specific data, device
core doesn't touch it */
struct dev_pm_info power;
diff --git a/include/linux/errno.h b/include/linux/errno.h
index 4668583..2d09bfa 100644
--- a/include/linux/errno.h
+++ b/include/linux/errno.h
@@ -16,6 +16,7 @@
#define ERESTARTNOHAND 514 /* restart if no handler.. */
#define ENOIOCTLCMD 515 /* No ioctl command */
#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
+#define EPROBE_DEFER 517 /* Driver requests probe retry */
/* Defined for the NFSv3 protocol */
#define EBADHANDLE 521 /* Illegal NFS file handle */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 175b54f..0a0fb1b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -652,6 +652,10 @@
#define V4L2_BUF_FLAG_ERROR 0x0040
#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */
+#define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */
+/* Cache handling flags */
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000
/*
* O V E R L A Y P R E V I E W
@@ -2035,6 +2039,15 @@
__u32 revision; /* chip revision, chip specific */
} __attribute__ ((packed));
+/* VIDIOC_CREATE_BUFS */
+struct v4l2_create_buffers {
+ __u32 index; /* output: buffers index...index + count - 1 have been created */
+ __u32 count;
+ enum v4l2_memory memory;
+ struct v4l2_format format; /* "type" is used always, the rest if sizeimage == 0 */
+ __u32 reserved[8];
+};
+
/*
* I O C T L C O D E S F O R V I D E O D E V I C E S
*
@@ -2125,6 +2138,11 @@
#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription)
#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
+/* Experimental, the below two ioctls may change over the next couple of kernel
+ versions */
+#define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers)
+#define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer)
+
/* Reminder: when adding new ioctls please add support for them to
drivers/media/video/v4l2-compat-ioctl32.c as well! */
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index dd9f1e7..4d1c74a 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -122,6 +122,8 @@
int (*vidioc_qbuf) (struct file *file, void *fh, struct v4l2_buffer *b);
int (*vidioc_dqbuf) (struct file *file, void *fh, struct v4l2_buffer *b);
+ int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
+ int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b);
int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
int (*vidioc_g_fbuf) (struct file *file, void *fh,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f57113b..74d0851 100755
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2783,6 +2783,12 @@
if (!conn->ssp_mode && conn->auth_initiator &&
(conn->pending_sec_level == BT_SECURITY_HIGH))
conn->pending_sec_level = BT_SECURITY_MEDIUM;
+
+ if (conn->ssp_mode && conn->auth_initiator &&
+ conn->io_capability != 0x03) {
+ conn->pending_sec_level = BT_SECURITY_HIGH;
+ conn->auth_type = HCI_AT_DEDICATED_BONDING_MITM;
+ }
}
if (conn->state != BT_CONFIG)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 52c1fe6..bcd0dd7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1614,13 +1614,9 @@
hci_dev_lock_bh(hdev);
io_cap = cp->io_cap;
- if (io_cap == 0x03) {
- sec_level = BT_SECURITY_MEDIUM;
- auth_type = HCI_AT_DEDICATED_BONDING;
- } else {
- sec_level = BT_SECURITY_HIGH;
- auth_type = HCI_AT_DEDICATED_BONDING_MITM;
- }
+
+ sec_level = BT_SECURITY_MEDIUM;
+ auth_type = HCI_AT_DEDICATED_BONDING;
entry = hci_find_adv_entry(hdev, &cp->bdaddr);
if (entry && entry->flags & 0x04) {