Merge "spmi-pmic-arb: improve error reporting"
diff --git a/drivers/md/dm-req-crypt.c b/drivers/md/dm-req-crypt.c
index 48dca3c..799fc21 100644
--- a/drivers/md/dm-req-crypt.c
+++ b/drivers/md/dm-req-crypt.c
@@ -23,6 +23,10 @@
#include <linux/backing-dev.h>
#include <linux/atomic.h>
#include <linux/scatterlist.h>
+#include <linux/device-mapper.h>
+#include <linux/printk.h>
+#include <linux/pft.h>
+
#include <crypto/scatterwalk.h>
#include <asm/page.h>
#include <asm/unaligned.h>
@@ -31,9 +35,6 @@
#include <crypto/algapi.h>
#include <mach/qcrypto.h>
-#include <linux/device-mapper.h>
-
-
#define DM_MSG_PREFIX "req-crypt"
#define MAX_SG_LIST 1024
@@ -46,20 +47,23 @@
#define DM_REQ_CRYPT_ERROR -1
#define DM_REQ_CRYPT_ERROR_AFTER_PAGE_MALLOC -2
-#define FDE_CRYPTO_DEVICE 0
struct req_crypt_result {
struct completion completion;
int err;
};
-struct dm_dev *dev;
+#define FDE_KEY_ID 0
+#define PFE_KEY_ID 1
+
+static struct dm_dev *dev;
static struct kmem_cache *_req_crypt_io_pool;
-sector_t start_sector_orig;
-struct workqueue_struct *req_crypt_queue;
-mempool_t *req_io_pool;
-mempool_t *req_page_pool;
-struct crypto_ablkcipher *tfm;
+static sector_t start_sector_orig;
+static struct workqueue_struct *req_crypt_queue;
+static mempool_t *req_io_pool;
+static mempool_t *req_page_pool;
+static bool is_fde_enabled;
+static struct crypto_ablkcipher *tfm;
struct req_dm_crypt_io {
struct work_struct work;
@@ -67,12 +71,83 @@
int error;
atomic_t pending;
struct timespec start_time;
+ bool should_encrypt;
+ bool should_decrypt;
+ u32 key_id;
};
static void req_crypt_cipher_complete
(struct crypto_async_request *req, int err);
+static bool req_crypt_should_encrypt(struct req_dm_crypt_io *req)
+{
+ int ret;
+ bool should_encrypt = false;
+ struct bio *bio = NULL;
+ struct inode *inode = NULL;
+ u32 key_id = 0;
+ bool is_encrypted = false;
+ bool is_inplace = false;
+
+ if (!req || !req->cloned_request || !req->cloned_request->bio)
+ return false;
+
+ bio = req->cloned_request->bio;
+
+ if (!bio->bi_io_vec || !bio->bi_io_vec->bv_page ||
+ !bio->bi_io_vec->bv_page->mapping)
+ return false;
+
+ inode = bio->bi_io_vec->bv_page->mapping->host;
+
+ ret = pft_get_key_index(inode, &key_id, &is_encrypted, &is_inplace);
+ /* req->key_id = key_id; @todo support more than 1 pfe key */
+ if ((ret == 0) && (is_encrypted || is_inplace)) {
+ should_encrypt = true;
+ req->key_id = PFE_KEY_ID;
+ } else if (is_fde_enabled) {
+ should_encrypt = true;
+ req->key_id = FDE_KEY_ID;
+ }
+
+ return should_encrypt;
+}
+
+static bool req_crypt_should_deccrypt(struct req_dm_crypt_io *req)
+{
+ int ret;
+ bool should_deccrypt = false;
+ struct bio *bio = NULL;
+ struct inode *inode = NULL;
+ u32 key_id = 0;
+ bool is_encrypted = false;
+ bool is_inplace = false;
+
+ if (!req || !req->cloned_request || !req->cloned_request->bio)
+ return false;
+
+ bio = req->cloned_request->bio;
+
+ if (!bio->bi_io_vec || !bio->bi_io_vec->bv_page ||
+ !bio->bi_io_vec->bv_page->mapping)
+ return false;
+
+ inode = bio->bi_io_vec->bv_page->mapping->host;
+
+ ret = pft_get_key_index(inode, &key_id, &is_encrypted, &is_inplace);
+ /* req->key_id = key_id; @todo support more than 1 pfe key */
+ if ((ret == 0) && (is_encrypted && !is_inplace)) {
+ should_deccrypt = true;
+ req->key_id = PFE_KEY_ID;
+ } else if (is_fde_enabled) {
+ should_deccrypt = true;
+ req->key_id = FDE_KEY_ID;
+ }
+
+ return should_deccrypt;
+}
+
static void req_crypt_inc_pending(struct req_dm_crypt_io *io)
{
atomic_inc(&io->pending);
@@ -197,7 +272,7 @@
ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
req_crypt_cipher_complete, &result);
init_completion(&result.completion);
- err = qcrypto_cipher_set_device(req, FDE_CRYPTO_DEVICE);
+ err = qcrypto_cipher_set_device(req, io->key_id);
if (err != 0) {
DMERR("%s qcrypto_cipher_set_device failed with err %d\n",
__func__, err);
@@ -278,6 +353,26 @@
}
/*
+ * This callback is called by the worker queue to perform non-decrypt reads
+ * and use the dm function to complete the bios and requests.
+ */
+static void req_cryptd_crypt_read_plain(struct req_dm_crypt_io *io)
+{
+ struct request *clone = NULL;
+ int error = 0;
+
+ if (!io || !io->cloned_request) {
+ DMERR("%s io is invalid\n", __func__);
+ BUG(); /* should not happen */
+ }
+
+ clone = io->cloned_request;
+
+ dm_end_request(clone, error);
+ mempool_free(io, req_io_pool);
+}
+
+/*
* The callback that will be called by the worker queue to perform Encryption
* for writes and submit the request using the elevelator.
*/
@@ -299,6 +394,7 @@
struct page *page = NULL;
u8 IV[AES_XTS_IV_LEN];
int remaining_size = 0;
+ int err = 0;
if (io) {
if (io->cloned_request) {
@@ -330,10 +426,10 @@
req_crypt_cipher_complete, &result);
init_completion(&result.completion);
- error = qcrypto_cipher_set_device(req, FDE_CRYPTO_DEVICE);
- if (error != 0) {
- DMERR("%s qcrypto_cipher_set_device failed with error %d\n",
- __func__, error);
+ err = qcrypto_cipher_set_device(req, io->key_id);
+ if (err != 0) {
+ DMERR("%s qcrypto_cipher_set_device failed with err %d\n",
+ __func__, err);
error = DM_REQ_CRYPT_ERROR;
goto ablkcipher_req_alloc_failure;
}
@@ -475,19 +571,44 @@
req_crypt_dec_pending_encrypt(io);
}
+/*
+ * This callback is called by the worker queue to perform non-encrypted writes
+ * and submit the request using the elevelator.
+ */
+static void req_cryptd_crypt_write_plain(struct req_dm_crypt_io *io)
+{
+ struct request *clone = NULL;
+
+ if (!io || !io->cloned_request) {
+ DMERR("%s io is invalid\n", __func__);
+ BUG(); /* should not happen */
+ }
+
+ clone = io->cloned_request;
+ io->error = 0;
+ dm_dispatch_request(clone);
+}
+
/* Queue callback function that will get triggered */
static void req_cryptd_crypt(struct work_struct *work)
{
struct req_dm_crypt_io *io =
container_of(work, struct req_dm_crypt_io, work);
- if (rq_data_dir(io->cloned_request) == WRITE)
- req_cryptd_crypt_write_convert(io);
- else if (rq_data_dir(io->cloned_request) == READ)
- req_cryptd_crypt_read_convert(io);
- else
- DMERR("%s received non-read/write request for Clone %u\n",
+ if (rq_data_dir(io->cloned_request) == WRITE) {
+ if (io->should_encrypt)
+ req_cryptd_crypt_write_convert(io);
+ else
+ req_cryptd_crypt_write_plain(io);
+ } else if (rq_data_dir(io->cloned_request) == READ) {
+ if (io->should_decrypt)
+ req_cryptd_crypt_read_convert(io);
+ else
+ req_cryptd_crypt_read_plain(io);
+ } else {
+ DMERR("%s received non-write request for Clone %u\n",
__func__, (unsigned int)io->cloned_request);
+ }
}
static void req_cryptd_queue_crypt(struct req_dm_crypt_io *io)
@@ -552,7 +673,7 @@
bvec = NULL;
if (rq_data_dir(clone) == WRITE) {
rq_for_each_segment(bvec, clone, iter1) {
- if (bvec->bv_offset == 0) {
+ if (req_io->should_encrypt && bvec->bv_offset == 0) {
mempool_free(bvec->bv_page, req_page_pool);
bvec->bv_page = NULL;
} else
@@ -580,7 +701,6 @@
* For a read request no pre-processing is required the request
* is returned to dm once mapping is done
*/
-
static int req_crypt_map(struct dm_target *ti, struct request *clone,
union map_info *map_context)
{
@@ -609,6 +729,11 @@
map_context->ptr = req_io;
atomic_set(&req_io->pending, 0);
+ if (rq_data_dir(clone) == WRITE)
+ req_io->should_encrypt = req_crypt_should_encrypt(req_io);
+ if (rq_data_dir(clone) == READ)
+ req_io->should_decrypt = req_crypt_should_deccrypt(req_io);
+
/* Get the queue of the underlying original device */
clone->q = bdev_get_queue(dev->bdev);
clone->rq_disk = dev->bdev->bd_disk;
@@ -656,6 +781,8 @@
static void req_crypt_dtr(struct dm_target *ti)
{
+ DMDEBUG("dm-req-crypt Destructor.\n");
+
if (req_crypt_queue) {
destroy_workqueue(req_crypt_queue);
req_crypt_queue = NULL;
@@ -685,6 +812,8 @@
char dummy;
int err = DM_REQ_CRYPT_ERROR;
+ DMDEBUG("dm-req-crypt Constructor.\n");
+
if (argc < 5) {
DMERR(" %s Not enough args\n", __func__);
err = DM_REQ_CRYPT_ERROR;
@@ -711,13 +840,24 @@
goto ctr_exit;
}
} else {
- DMERR(" %s Arg[4]invalid\n", __func__);
+ DMERR(" %s Arg[4] invalid\n", __func__);
err = DM_REQ_CRYPT_ERROR;
goto ctr_exit;
}
start_sector_orig = tmpll;
+ if (argv[5]) {
+ if (!strcmp(argv[5], "fde_enabled"))
+ is_fde_enabled = true;
+ else
+ is_fde_enabled = false;
+ } else {
+ DMERR(" %s Arg[5] invalid, set FDE eanbled.\n", __func__);
+ is_fde_enabled = true; /* backward compatible */
+ }
+ DMDEBUG("%s is_fde_enabled=%d\n", __func__, is_fde_enabled);
+
req_crypt_queue = alloc_workqueue("req_cryptd",
WQ_NON_REENTRANT |
WQ_HIGHPRI |
@@ -740,6 +880,7 @@
}
req_io_pool = mempool_create_slab_pool(MIN_IOS, _req_crypt_io_pool);
+ BUG_ON(!req_io_pool);
if (!req_io_pool) {
DMERR("%s req_io_pool not allocated\n", __func__);
err = DM_REQ_CRYPT_ERROR;
@@ -806,6 +947,8 @@
kmem_cache_destroy(_req_crypt_io_pool);
}
+ DMINFO("dm-req-crypt successfully initalized.\n");
+
return r;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 69c5190..e8702e4 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -355,6 +355,7 @@
struct msm_vfe_src_info src_info[VFE_SRC_MAX];
uint16_t stream_handle_cnt;
unsigned long event_mask;
+ uint32_t burst_len;
};
struct msm_vfe_stats_hardware_info {
@@ -397,6 +398,7 @@
uint16_t stream_handle_cnt;
atomic_t stats_update;
uint32_t stats_mask;
+ uint32_t stats_burst_len;
};
struct msm_vfe_tasklet_queue_cmd {
@@ -480,8 +482,7 @@
struct list_head tasklet_q;
struct tasklet_struct vfe_tasklet;
struct msm_vfe_tasklet_queue_cmd
- tasklet_queue_cmd[MSM_VFE_TASKLETQ_SIZE];
-
+ tasklet_queue_cmd[MSM_VFE_TASKLETQ_SIZE];
uint32_t soc_hw_version;
uint32_t vfe_hw_version;
struct msm_vfe_hardware_info *hw_info;
@@ -498,6 +499,7 @@
void __iomem *p_avtimer_lsw;
uint8_t ignore_error;
struct msm_isp_statistics *stats;
+ uint32_t vfe_ub_size;
};
#endif
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index e817680..353b55f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -36,10 +36,10 @@
#define VFE40_8x26_VERSION 0x20000013
#define VFE40_8x26V2_VERSION 0x20010014
-#define VFE40_BURST_LEN 1
-#define VFE40_STATS_BURST_LEN 1
-#define VFE40_UB_SIZE 1536
-#define VFE40_EQUAL_SLICE_UB 228
+
+/* STATS_SIZE (BE + BG + BF+ RS + CS + IHIST + BHIST ) = 392 */
+#define VFE40_STATS_SIZE 392
+
#define VFE40_WM_BASE(idx) (0x6C + 0x24 * idx)
#define VFE40_RDI_BASE(idx) (0x2E8 + 0x4 * idx)
#define VFE40_XBAR_BASE(idx) (0x58 + 0x4 * (idx / 2))
@@ -971,6 +971,11 @@
uint8_t plane_idx)
{
uint32_t val;
+
+ struct msm_vfe_axi_shared_data *axi_data =
+ &vfe_dev->axi_data;
+ uint32_t burst_len = axi_data->burst_len;
+
uint32_t wm_base = VFE40_WM_BASE(stream_info->wm[plane_idx]);
if (!stream_info->frame_based) {
@@ -992,7 +997,7 @@
plane_idx].output_stride) << 16 |
(stream_info->plane_cfg[
plane_idx].output_height - 1) << 4 |
- VFE40_BURST_LEN;
+ burst_len;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
} else {
msm_camera_io_w(0x2, vfe_dev->vfe_base + wm_base);
@@ -1002,7 +1007,7 @@
plane_idx].output_width) << 16 |
(stream_info->plane_cfg[
plane_idx].output_height - 1) << 4 |
- VFE40_BURST_LEN;
+ burst_len;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
}
@@ -1117,6 +1122,7 @@
uint8_t num_used_wms = 0;
uint32_t prop_size = 0;
uint32_t wm_ub_size;
+ uint32_t axi_wm_ub;
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
if (axi_data->free_wm[i] > 0) {
@@ -1124,7 +1130,9 @@
total_image_size += axi_data->wm_image_size[i];
}
}
- prop_size = MSM_ISP40_TOTAL_WM_UB -
+ axi_wm_ub = vfe_dev->vfe_ub_size - VFE40_STATS_SIZE;
+
+ prop_size = axi_wm_ub -
axi_data->hw_info->min_wm_ub * num_used_wms;
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
if (axi_data->free_wm[i]) {
@@ -1149,10 +1157,14 @@
int i;
uint32_t ub_offset = 0;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+ uint32_t axi_equal_slice_ub =
+ (vfe_dev->vfe_ub_size - VFE40_STATS_SIZE)/
+ (axi_data->hw_info->num_wm - 1);
+
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
- msm_camera_io_w(ub_offset << 16 | (VFE40_EQUAL_SLICE_UB - 1),
+ msm_camera_io_w(ub_offset << 16 | (axi_equal_slice_ub - 1),
vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10);
- ub_offset += VFE40_EQUAL_SLICE_UB;
+ ub_offset += axi_equal_slice_ub;
}
}
@@ -1334,7 +1346,11 @@
static void msm_vfe40_stats_cfg_ub(struct vfe_device *vfe_dev)
{
int i;
- uint32_t ub_offset = VFE40_UB_SIZE;
+ struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+ uint32_t ub_offset = vfe_dev->vfe_ub_size;
+ uint32_t stats_burst_len = stats_data->stats_burst_len;
+
+
uint32_t ub_size[VFE40_NUM_STATS_TYPE] = {
64, /*MSM_ISP_STATS_BE*/
128, /*MSM_ISP_STATS_BG*/
@@ -1348,7 +1364,7 @@
for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
ub_offset -= ub_size[i];
- msm_camera_io_w(VFE40_STATS_BURST_LEN << 30 |
+ msm_camera_io_w(stats_burst_len << 30 |
ub_offset << 16 | (ub_size[i] - 1),
vfe_dev->vfe_base + VFE40_STATS_BASE(i) + 0xC);
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 4c3a3d5..d11ea68 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -524,7 +524,9 @@
stream_info->format_factor / ISP_Q2;
} else {
int rdi = SRC_TO_INTF(stream_info->stream_src);
- stream_info->bandwidth = axi_data->src_info[rdi].pixel_clock;
+ if (rdi < VFE_SRC_MAX)
+ stream_info->bandwidth =
+ axi_data->src_info[rdi].pixel_clock;
}
}
@@ -534,6 +536,7 @@
uint32_t io_format = 0;
struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd = arg;
struct msm_vfe_axi_stream *stream_info;
+ struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
rc = msm_isp_axi_create_stream(
&vfe_dev->axi_data, stream_cfg_cmd);
@@ -581,6 +584,8 @@
msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd);
stream_info->vt_enable = stream_cfg_cmd->vt_enable;
+ axi_data->burst_len = stream_cfg_cmd->burst_len;
+
if (stream_info->vt_enable) {
vfe_dev->vt_enable = stream_info->vt_enable;
#ifdef CONFIG_MSM_AVTIMER
@@ -853,8 +858,11 @@
struct msm_isp_event_data buf_event;
struct timeval *time_stamp;
uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle);
- uint32_t frame_id = vfe_dev->axi_data.
- src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id;
+ uint32_t src_intf = SRC_TO_INTF(stream_info->stream_src);
+ uint32_t frame_id = 0;
+ if (src_intf < VFE_SRC_MAX) {
+ frame_id = vfe_dev->axi_data.src_info[src_intf].frame_id;
+ }
if (buf && ts) {
if (vfe_dev->vt_enable) {
@@ -1196,7 +1204,7 @@
enum msm_isp_camif_update_state camif_update)
{
int i, rc = 0;
- uint8_t src_state, wait_for_complete = 0;
+ uint8_t src_state = 0, wait_for_complete = 0;
uint32_t wm_reload_mask = 0x0;
struct msm_vfe_axi_stream *stream_info;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
@@ -1212,8 +1220,9 @@
}
stream_info = &axi_data->stream_info[
HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
- src_state = axi_data->src_info[
- SRC_TO_INTF(stream_info->stream_src)].active;
+ if (SRC_TO_INTF(stream_info->stream_src) < VFE_SRC_MAX)
+ src_state = axi_data->src_info[
+ SRC_TO_INTF(stream_info->stream_src)].active;
msm_isp_calculate_bandwidth(axi_data, stream_info);
msm_isp_reset_framedrop(vfe_dev, stream_info);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index 6bd7585..d4c86a5 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -490,6 +490,9 @@
{
int rc = 0;
struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd = arg;
+ struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+ stats_data->stats_burst_len = stream_cfg_cmd->stats_burst_len;
+
if (vfe_dev->stats_data.num_active_stream == 0)
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_ub(vfe_dev);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index ebdca89..a81c7bb 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -701,6 +701,10 @@
}
break;
}
+ case SET_WM_UB_SIZE: {
+ vfe_dev->vfe_ub_size = *cfg_data;
+ break;
+ }
}
return 0;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
old mode 100644
new mode 100755
index 071f698..9f0dac4
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -3467,13 +3467,13 @@
capability->height.min);
rc = -ENOTSUPP;
}
-
- if (!rc) {
- rc = call_hfi_op(hdev, capability_check,
- inst->fmts[OUTPUT_PORT]->fourcc,
- inst->prop.width[CAPTURE_PORT],
- &capability->width.max,
- &capability->height.max);
+ if (!rc && (inst->prop.width[CAPTURE_PORT] >
+ capability->width.max)) {
+ dprintk(VIDC_ERR,
+ "Unsupported width = %u supported max width = %u",
+ inst->prop.width[CAPTURE_PORT],
+ capability->width.max);
+ rc = -ENOTSUPP;
}
if (!rc && (inst->prop.height[CAPTURE_PORT]
* inst->prop.width[CAPTURE_PORT] >
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
old mode 100644
new mode 100755
index 475683c..0ac6fc4
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -20,7 +20,6 @@
int msm_fw_debug = 0x18;
int msm_fw_debug_mode = 0x1;
int msm_fw_low_power_mode = 0x1;
-int msm_vp8_low_tier = 0x1;
int msm_vidc_hw_rsp_timeout = 1000;
struct debug_buffer {
@@ -184,11 +183,6 @@
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
goto failed_create_dir;
}
- if (!debugfs_create_u32("vp8_low_tier", S_IRUGO | S_IWUSR,
- parent, &msm_vp8_low_tier)) {
- dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
- goto failed_create_dir;
- }
if (!debugfs_create_u32("debug_output", S_IRUGO | S_IWUSR,
parent, &msm_vidc_debug_out)) {
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
diff --git a/drivers/media/platform/msm/vidc/q6_hfi.c b/drivers/media/platform/msm/vidc/q6_hfi.c
old mode 100644
new mode 100755
index bbba29a..486d740
--- a/drivers/media/platform/msm/vidc/q6_hfi.c
+++ b/drivers/media/platform/msm/vidc/q6_hfi.c
@@ -1318,24 +1318,6 @@
return rc;
}
-int q6_hfi_capability_check(u32 fourcc, u32 width,
- u32 *max_width, u32 *max_height)
-{
- int rc = 0;
- if (!max_width || !max_height) {
- dprintk(VIDC_ERR, "%s - invalid parameter\n", __func__);
- return -EINVAL;
- }
-
- if (width > *max_width) {
- dprintk(VIDC_ERR,
- "Unsupported width = %u supported max width = %u\n",
- width, *max_width);
- rc = -ENOTSUPP;
- }
- return rc;
-}
-
static void q6_hfi_unload_fw(void *hfi_device_data)
{
struct q6_hfi_device *device = hfi_device_data;
@@ -1390,7 +1372,6 @@
hdev->unset_ocmem = q6_hfi_unset_ocmem;
hdev->iommu_get_domain_partition = q6_hfi_iommu_get_domain_partition;
hdev->load_fw = q6_hfi_load_fw;
- hdev->capability_check = q6_hfi_capability_check;
hdev->unload_fw = q6_hfi_unload_fw;
hdev->get_stride_scanline = q6_hfi_get_stride_scanline;
}
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
old mode 100644
new mode 100755
index 30ee45d..448fe3b
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -3747,29 +3747,6 @@
return rc;
}
-int venus_hfi_capability_check(u32 fourcc, u32 width,
- u32 *max_width, u32 *max_height)
-{
- int rc = 0;
- if (!max_width || !max_height) {
- dprintk(VIDC_ERR, "%s - invalid parameter\n", __func__);
- return -EINVAL;
- }
-
- if (msm_vp8_low_tier && fourcc == V4L2_PIX_FMT_VP8) {
- *max_width = DEFAULT_WIDTH;
- *max_height = DEFAULT_HEIGHT;
- }
-
- if (width > *max_width) {
- dprintk(VIDC_ERR,
- "Unsupported width = %u supported max width = %u\n",
- width, *max_width);
- rc = -ENOTSUPP;
- }
- return rc;
-}
-
static void *venus_hfi_add_device(u32 device_id,
struct msm_vidc_platform_resources *res,
hfi_cmd_response_callback callback)
@@ -3932,7 +3909,6 @@
hdev->get_info = venus_hfi_get_info;
hdev->get_stride_scanline = venus_hfi_get_stride_scanline;
hdev->get_core_capabilities = venus_hfi_get_core_capabilities;
- hdev->capability_check = venus_hfi_capability_check;
hdev->power_enable = venus_hfi_power_enable;
}
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
old mode 100644
new mode 100755
index 62507a1..38c5bdb
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -1168,8 +1168,6 @@
int (*get_info) (void *dev, enum dev_info info);
int (*get_stride_scanline)(int color_fmt, int width,
int height, int *stride, int *scanlines);
- int (*capability_check)(u32 fourcc, u32 width,
- u32 *max_width, u32 *max_height);
int (*session_clean)(void *sess);
int (*get_core_capabilities)(void);
int (*power_enable)(void *dev);
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 72cb8d5..457deb7 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1380,8 +1380,10 @@
if (todo & DSI_EV_MDP_FIFO_UNDERFLOW) {
if (ctrl->recovery) {
+ mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);
mdss_dsi_sw_reset_restore(ctrl);
ctrl->recovery->fxn(ctrl->recovery->data);
+ mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
}
}
@@ -1396,7 +1398,9 @@
spin_unlock_irqrestore(&ctrl->mdp_lock, flag);
/* enable dsi error interrupt */
+ mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);
mdss_dsi_err_intr_ctrl(ctrl, DSI_INTR_ERROR_MASK, 1);
+ mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
}
}
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index c14f936..da2ae5f 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -454,6 +454,7 @@
mfd->ext_ad_ctrl = -1;
mfd->bl_level = 0;
+ mfd->bl_level_prev_scaled = 0;
mfd->bl_scale = 1024;
mfd->bl_min_lvl = 30;
mfd->fb_imgType = MDP_RGBA_8888;
@@ -782,6 +783,7 @@
pdata = dev_get_platdata(&mfd->pdev->dev);
if ((pdata) && (pdata->set_backlight)) {
+ mfd->bl_level_prev_scaled = mfd->bl_level_scaled;
if (!IS_CALIB_MODE_BL(mfd))
mdss_fb_scale_bl(mfd, &temp);
/*
@@ -792,13 +794,13 @@
* as well as setting bl_level to bkl_lvl even though the
* backlight has been set to the scaled value.
*/
- if (mfd->bl_level_old == temp) {
+ if (mfd->bl_level_scaled == temp) {
mfd->bl_level = bkl_lvl;
return;
}
pdata->set_backlight(pdata, temp);
mfd->bl_level = bkl_lvl;
- mfd->bl_level_old = temp;
+ mfd->bl_level_scaled = temp;
if (mfd->mdp.update_ad_input) {
update_ad_input = mfd->mdp.update_ad_input;
@@ -821,7 +823,7 @@
if ((pdata) && (pdata->set_backlight)) {
mfd->bl_level = mfd->unset_bl_level;
pdata->set_backlight(pdata, mfd->bl_level);
- mfd->bl_level_old = mfd->unset_bl_level;
+ mfd->bl_level_scaled = mfd->unset_bl_level;
mfd->bl_updated = 1;
}
}
@@ -858,6 +860,13 @@
schedule_delayed_work(&mfd->idle_notify_work,
msecs_to_jiffies(mfd->idle_time));
}
+
+ mutex_lock(&mfd->bl_lock);
+ if (!mfd->bl_updated) {
+ mfd->bl_updated = 1;
+ mdss_fb_set_backlight(mfd, mfd->bl_level_prev_scaled);
+ }
+ mutex_unlock(&mfd->bl_lock);
break;
case FB_BLANK_VSYNC_SUSPEND:
@@ -879,8 +888,9 @@
mfd->op_enable = false;
curr_pwr_state = mfd->panel_power_on;
- mfd->panel_power_on = false;
mutex_lock(&mfd->bl_lock);
+ mdss_fb_set_backlight(mfd, 0);
+ mfd->panel_power_on = false;
mfd->bl_updated = 0;
mutex_unlock(&mfd->bl_lock);
@@ -1687,7 +1697,11 @@
u32 wait_for_finish = disp_commit->wait_for_finish;
int ret = 0;
- if (!mfd || (!mfd->op_enable) || (!mfd->panel_power_on))
+ if (!mfd || (!mfd->op_enable))
+ return -EPERM;
+
+ if ((!mfd->panel_power_on) && !((mfd->dcm_state == DCM_ENTER) &&
+ (mfd->panel.type == MIPI_CMD_PANEL)))
return -EPERM;
if (var->xoffset > (info->var.xres_virtual - info->var.xres))
@@ -1739,7 +1753,11 @@
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- if ((!mfd->op_enable) || (!mfd->panel_power_on))
+ if (!mfd->op_enable)
+ return -EPERM;
+
+ if ((!mfd->panel_power_on) && !((mfd->dcm_state == DCM_ENTER) &&
+ (mfd->panel.type == MIPI_CMD_PANEL)))
return -EPERM;
if (var->xoffset > (info->var.xres_virtual - info->var.xres))
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 3416b9e..ce0a7f9 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -189,7 +189,8 @@
u32 bl_min_lvl;
u32 unset_bl_level;
u32 bl_updated;
- u32 bl_level_old;
+ u32 bl_level_scaled;
+ u32 bl_level_prev_scaled;
struct mutex bl_lock;
struct mutex lock;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 52c220f..fdfa2b0 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1605,7 +1605,8 @@
if (mutex_lock_interruptible(&mdp5_data->ov_lock))
return;
- if (!mfd->panel_power_on) {
+ if ((!mfd->panel_power_on) && !((mfd->dcm_state == DCM_ENTER) &&
+ (mfd->panel.type == MIPI_CMD_PANEL))) {
mutex_unlock(&mdp5_data->ov_lock);
return;
}
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 30e7d06..e627977 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -154,6 +154,7 @@
uint8_t buf_divert; /* if TRUE no vb2 buf done. */
/*Return values*/
uint32_t axi_stream_handle;
+ uint32_t burst_len;
};
struct msm_vfe_axi_stream_release_cmd {
@@ -225,6 +226,7 @@
uint8_t num_streams;
uint32_t stream_handle[MSM_ISP_STATS_MAX];
uint8_t enable;
+ uint32_t stats_burst_len;
};
enum msm_vfe_reg_cfg_type {
@@ -242,6 +244,7 @@
GET_MAX_CLK_RATE,
VFE_HW_UPDATE_LOCK,
VFE_HW_UPDATE_UNLOCK,
+ SET_WM_UB_SIZE,
};
struct msm_vfe_cfg_cmd2 {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cf82dbd..5bc3663 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1963,8 +1963,8 @@
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_NEW_KEY);
- if (IS_ERR(hdr))
- return PTR_ERR(hdr);
+ if (!hdr)
+ return -ENOBUFS;
cookie.msg = msg;
cookie.idx = key_idx;
@@ -5409,6 +5409,9 @@
NL80211_CMD_TESTMODE);
struct nlattr *tmdata;
+ if (!hdr)
+ break;
+
if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx) < 0) {
genlmsg_cancel(skb, hdr);
break;
@@ -5817,9 +5820,8 @@
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_REMAIN_ON_CHANNEL);
-
- if (IS_ERR(hdr)) {
- err = PTR_ERR(hdr);
+ if (!hdr) {
+ err = -ENOBUFS;
goto free_msg;
}
@@ -6100,9 +6102,8 @@
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_FRAME);
-
- if (IS_ERR(hdr)) {
- err = PTR_ERR(hdr);
+ if (!hdr) {
+ err = -ENOBUFS;
goto free_msg;
}
}
@@ -6662,9 +6663,8 @@
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_PROBE_CLIENT);
-
- if (IS_ERR(hdr)) {
- err = PTR_ERR(hdr);
+ if (!hdr) {
+ err = -ENOBUFS;
goto free_msg;
}
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 87547ca..94c06df 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -65,11 +65,45 @@
return is_all_idle;
}
+
+static bool cfg80211_is_all_countryie_ignore(void)
+{
+ struct cfg80211_registered_device *rdev;
+ struct wireless_dev *wdev;
+ bool is_all_countryie_ignore = true;
+
+ mutex_lock(&cfg80211_mutex);
+
+ list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+ cfg80211_lock_rdev(rdev);
+ list_for_each_entry(wdev, &rdev->netdev_list, list) {
+ wdev_lock(wdev);
+ if (!(wdev->wiphy->country_ie_pref &
+ NL80211_COUNTRY_IE_IGNORE_CORE)) {
+ is_all_countryie_ignore = false;
+ wdev_unlock(wdev);
+ cfg80211_unlock_rdev(rdev);
+ goto out;
+ }
+ wdev_unlock(wdev);
+ }
+ cfg80211_unlock_rdev(rdev);
+ }
+out:
+ mutex_unlock(&cfg80211_mutex);
+
+ return is_all_countryie_ignore;
+}
+
+
static void disconnect_work(struct work_struct *work)
{
if (!cfg80211_is_all_idle())
return;
+ if (cfg80211_is_all_countryie_ignore())
+ return;
+
regulatory_hint_disconnect();
}
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 4c5d327..5602dd1 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -2555,9 +2555,10 @@
WCD9XXX_CLSH_STATE_LO,
WCD9XXX_CLSH_REQ_ENABLE,
WCD9XXX_CLSH_EVENT_POST_PA);
- pr_debug("%s: sleeping 3 ms after %s PA turn on\n",
+ pr_debug("%s: sleeping 5 ms after %s PA turn on\n",
__func__, w->name);
- usleep_range(3000, 3000);
+ /* Wait for CnP time after PA enable */
+ usleep_range(5000, 5100);
break;
case SND_SOC_DAPM_POST_PMD:
wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
@@ -2565,6 +2566,10 @@
WCD9XXX_CLSH_REQ_DISABLE,
WCD9XXX_CLSH_EVENT_POST_PA);
snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
+ pr_debug("%s: sleeping 5 ms after %s PA turn off\n",
+ __func__, w->name);
+ /* Wait for CnP time after PA disable */
+ usleep_range(5000, 5100);
break;
}
return 0;
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index fce1940..f6702c5 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -129,6 +129,8 @@
uint32_t stream_available;
uint32_t next_stream;
+ uint64_t marker_timestamp;
+
struct msm_compr_gapless_state gapless_state;
atomic_t start;
@@ -1064,6 +1066,7 @@
prtd->app_pointer = 0;
prtd->bytes_received = 0;
prtd->bytes_sent = 0;
+ prtd->marker_timestamp = 0;
atomic_set(&prtd->xrun, 0);
spin_unlock_irqrestore(&prtd->lock, flags);
@@ -1196,6 +1199,8 @@
prtd->first_buffer = 1;
prtd->last_buffer = 0;
prtd->gapless_state.gapless_transition = 1;
+ prtd->marker_timestamp = 0;
+
/*
Don't reset these as these vars map to
total_bytes_transferred and total_bytes_available
@@ -1251,23 +1256,23 @@
q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id);
prtd->cmd_ack = 0;
spin_unlock_irqrestore(&prtd->lock, flags);
- pr_debug("%s:issue CMD_FLUSH ac->stream_id %d",
- __func__, ac->stream_id);
- q6asm_stream_cmd(ac, CMD_FLUSH, ac->stream_id);
- wait_event_timeout(prtd->flush_wait,
- prtd->cmd_ack, 1 * HZ / 4);
+ /*
+ * Cache this time as last known time
+ */
+ q6asm_get_session_time(prtd->audio_client,
+ &prtd->marker_timestamp);
spin_lock_irqsave(&prtd->lock, flags);
/*
- Don't reset these as these vars map to
- total_bytes_transferred and total_bytes_available
- directly, only total_bytes_transferred will be updated
- in the next avail() ioctl
- prtd->copied_total = 0;
- prtd->bytes_received = 0;
- do not reset prtd->bytes_sent as well as the same
- session is used for gapless playback
- */
+ * Don't reset these as these vars map to
+ * total_bytes_transferred and total_bytes_available.
+ * Just total_bytes_transferred will be updated
+ * in the next avail() ioctl.
+ * prtd->copied_total = 0;
+ * prtd->bytes_received = 0;
+ * do not reset prtd->bytes_sent as well as the same
+ * session is used for gapless playback
+ */
prtd->byte_offset = 0;
prtd->app_pointer = 0;
@@ -1275,8 +1280,15 @@
prtd->last_buffer = 0;
atomic_set(&prtd->drain, 0);
atomic_set(&prtd->xrun, 1);
- q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
spin_unlock_irqrestore(&prtd->lock, flags);
+
+ pr_debug("%s:issue CMD_FLUSH ac->stream_id %d",
+ __func__, ac->stream_id);
+ q6asm_stream_cmd(ac, CMD_FLUSH, ac->stream_id);
+ wait_event_timeout(prtd->flush_wait,
+ prtd->cmd_ack, 1 * HZ / 4);
+
+ q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
}
prtd->cmd_interrupt = 0;
break;
@@ -1404,6 +1416,8 @@
__func__, timestamp);
return -EAGAIN;
}
+ } else {
+ timestamp = prtd->marker_timestamp;
}
/* DSP returns timestamp in usec */