Merge "msm: acpuclock-krait: Fix HFPLL regulator voting in regulator_init()"
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index aafd175..0d443a6 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -79,7 +79,6 @@
CONFIG_ARM_ARCH_TIMER=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
-CONFIG_HIGHMEM=y
CONFIG_COMPACTION=y
CONFIG_CC_STACKPROTECTOR=y
CONFIG_ENABLE_VMALLOC_SAVING=y
@@ -358,6 +357,8 @@
CONFIG_UIO=y
CONFIG_UIO_MSM_SHAREDMEM=y
CONFIG_STAGING=y
+CONFIG_ZRAM=y
+CONFIG_ZSMALLOC=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ASHMEM=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index fa520b7..f467b95 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -80,7 +80,6 @@
CONFIG_ARM_ARCH_TIMER=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
-CONFIG_HIGHMEM=y
CONFIG_COMPACTION=y
CONFIG_CC_STACKPROTECTOR=y
CONFIG_ENABLE_VMALLOC_SAVING=y
@@ -382,6 +381,8 @@
CONFIG_UIO=y
CONFIG_UIO_MSM_SHAREDMEM=y
CONFIG_STAGING=y
+CONFIG_ZRAM=y
+CONFIG_ZSMALLOC=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ASHMEM=y
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 34ae4e6..ac6ccf3b 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -885,8 +885,9 @@
MLM(VMALLOC_START, VMALLOC_END),
MLM(PAGE_OFFSET, (unsigned long)high_memory));
#endif
-#ifdef CONFIG_HIGHMEM
+
printk(KERN_NOTICE
+#ifdef CONFIG_HIGHMEM
" pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
#endif
#ifdef CONFIG_MODULES
diff --git a/drivers/crypto/msm/qce.c b/drivers/crypto/msm/qce.c
index 7778477..8037187 100644
--- a/drivers/crypto/msm/qce.c
+++ b/drivers/crypto/msm/qce.c
@@ -1949,6 +1949,12 @@
else
q_req->cryptlen = areq->cryptlen - authsize;
+ if ((q_req->cryptlen > ULONG_MAX - ivsize) ||
+ (q_req->cryptlen + ivsize > ULONG_MAX - areq->assoclen)) {
+ pr_err("Integer overflow on total aead req length.\n");
+ return -EINVAL;
+ }
+
totallen = q_req->cryptlen + ivsize + areq->assoclen;
pad_len = ALIGN(totallen, ADM_CE_BLOCK_SIZE) - totallen;
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 4c05978..a4154c1 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -43,13 +43,17 @@
#define QCE_MAX_NUM_DSCR 0x500
#define QCE_SECTOR_SIZE 0x200
-static DEFINE_MUTEX(bam_register_cnt);
+static DEFINE_MUTEX(bam_register_lock);
struct bam_registration_info {
+ struct list_head qlist;
uint32_t handle;
uint32_t cnt;
+ uint32_t bam_mem;
+ void __iomem *bam_iobase;
+ bool support_cmd_dscr;
};
-static struct bam_registration_info bam_registry;
-static bool ce_bam_registered;
+static LIST_HEAD(qce50_bam_list);
+
/*
* CE HW device structure.
* Each engine has an instance of the structure.
@@ -58,11 +62,14 @@
*/
struct qce_device {
struct device *pdev; /* Handle to platform_device structure */
+ struct bam_registration_info *pbam;
unsigned char *coh_vmem; /* Allocated coherent virtual memory */
dma_addr_t coh_pmem; /* Allocated coherent physical memory */
int memsize; /* Memory allocated */
- int is_shared; /* CE HW is shared */
+ uint32_t bam_mem; /* bam physical address, from DT */
+ uint32_t bam_mem_size; /* bam io size, from DT */
+ int is_shared; /* CE HW is shared */
bool support_cmd_dscr;
bool support_hw_key;
@@ -2162,25 +2169,93 @@
sps_connect_info->desc.phys_base);
sps_free_endpoint(sps_pipe_info);
}
-/**
- * Initialize SPS HW connected with CE core
- *
- * This function register BAM HW resources with
- * SPS driver and then initialize 2 SPS endpoints
- *
- * This function should only be called once typically
- * during driver probe.
- *
- * @pce_dev - Pointer to qce_device structure
- *
- * @return - 0 if successful else negative value.
- *
- */
-static int qce_sps_init(struct qce_device *pce_dev)
+
+static void qce_sps_release_bam(struct qce_device *pce_dev)
+{
+ struct bam_registration_info *pbam;
+
+ mutex_lock(&bam_register_lock);
+ pbam = pce_dev->pbam;
+ if (pbam == NULL)
+ goto ret;
+
+ pbam->cnt--;
+ if (pbam->cnt > 0)
+ goto ret;
+
+ if (pce_dev->ce_sps.bam_handle) {
+ sps_deregister_bam_device(pce_dev->ce_sps.bam_handle);
+
+ pr_debug("deregister bam handle %x\n",
+ pce_dev->ce_sps.bam_handle);
+ pce_dev->ce_sps.bam_handle = 0;
+ }
+ iounmap(pbam->bam_iobase);
+ pr_debug("delete bam 0x%x\n", pbam->bam_mem);
+ list_del(&pbam->qlist);
+ kfree(pbam);
+
+ pce_dev->pbam = NULL;
+ret:
+ mutex_unlock(&bam_register_lock);
+}
+
+static int qce_sps_get_bam(struct qce_device *pce_dev)
{
int rc = 0;
struct sps_bam_props bam = {0};
- bool register_bam = false;
+ struct bam_registration_info *pbam = NULL;
+ struct bam_registration_info *p;
+ uint32_t bam_cfg = 0 ;
+
+
+ mutex_lock(&bam_register_lock);
+
+ list_for_each_entry(p, &qce50_bam_list, qlist) {
+ if (p->bam_mem == pce_dev->bam_mem) {
+ pbam = p; /* found */
+ break;
+ }
+ }
+
+ if (pbam) {
+ pr_debug("found bam 0x%x\n", pbam->bam_mem);
+ pbam->cnt++;
+ pce_dev->ce_sps.bam_handle = pbam->handle;
+ pce_dev->ce_sps.bam_mem = pbam->bam_mem;
+ pce_dev->ce_sps.bam_iobase = pbam->bam_iobase;
+ pce_dev->pbam = pbam;
+ pce_dev->support_cmd_dscr = pbam->support_cmd_dscr;
+ goto ret;
+ }
+
+ pbam = kzalloc(sizeof(struct bam_registration_info), GFP_KERNEL);
+ if (!pbam) {
+ pr_err("qce50 Memory allocation of bam FAIL, error %ld\n",
+ PTR_ERR(pbam));
+
+ rc = -ENOMEM;
+ goto ret;
+ }
+ pbam->cnt = 1;
+ pbam->bam_mem = pce_dev->bam_mem;
+ pbam->bam_iobase = ioremap_nocache(pce_dev->bam_mem,
+ pce_dev->bam_mem_size);
+ if (!pbam->bam_iobase) {
+ kfree(pbam);
+ rc = -ENOMEM;
+ pr_err("Can not map BAM io memory\n");
+ goto ret;
+ }
+ pce_dev->ce_sps.bam_mem = pbam->bam_mem;
+ pce_dev->ce_sps.bam_iobase = pbam->bam_iobase;
+ pbam->handle = 0;
+ pr_debug("allocate bam 0x%x\n", pbam->bam_mem);
+ bam_cfg = readl_relaxed(pce_dev->ce_sps.bam_iobase +
+ CRYPTO_BAM_CNFG_BITS_REG);
+ pbam->support_cmd_dscr = (bam_cfg & CRYPTO_BAM_CD_ENABLE_MASK) ?
+ true : false;
+ pce_dev->support_cmd_dscr = pbam->support_cmd_dscr;
bam.phys_addr = pce_dev->ce_sps.bam_mem;
bam.virt_addr = pce_dev->ce_sps.bam_iobase;
@@ -2212,27 +2287,46 @@
pr_debug("bam physical base=0x%x\n", (u32)bam.phys_addr);
pr_debug("bam virtual base=0x%x\n", (u32)bam.virt_addr);
- mutex_lock(&bam_register_cnt);
- if (ce_bam_registered == false) {
- bam_registry.handle = 0;
- bam_registry.cnt = 0;
+ /* Register CE Peripheral BAM device to SPS driver */
+ rc = sps_register_bam_device(&bam, &pbam->handle);
+ if (rc) {
+ pr_err("sps_register_bam_device() failed! err=%d", rc);
+ rc = -EIO;
+ iounmap(pbam->bam_iobase);
+ kfree(pbam);
+ goto ret;
}
- if ((bam_registry.handle == 0) && (bam_registry.cnt == 0)) {
- /* Register CE Peripheral BAM device to SPS driver */
- rc = sps_register_bam_device(&bam, &bam_registry.handle);
- if (rc) {
- mutex_unlock(&bam_register_cnt);
- pr_err("sps_register_bam_device() failed! err=%d", rc);
- return -EIO;
- }
- bam_registry.cnt++;
- register_bam = true;
- ce_bam_registered = true;
- } else {
- bam_registry.cnt++;
- }
- mutex_unlock(&bam_register_cnt);
- pce_dev->ce_sps.bam_handle = bam_registry.handle;
+
+ pce_dev->pbam = pbam;
+ list_add_tail(&pbam->qlist, &qce50_bam_list);
+ pce_dev->ce_sps.bam_handle = pbam->handle;
+
+ret:
+ mutex_unlock(&bam_register_lock);
+
+ return rc;
+}
+/**
+ * Initialize SPS HW connected with CE core
+ *
+ * This function register BAM HW resources with
+ * SPS driver and then initialize 2 SPS endpoints
+ *
+ * This function should only be called once typically
+ * during driver probe.
+ *
+ * @pce_dev - Pointer to qce_device structure
+ *
+ * @return - 0 if successful else negative value.
+ *
+ */
+static int qce_sps_init(struct qce_device *pce_dev)
+{
+ int rc = 0;
+
+ rc = qce_sps_get_bam(pce_dev);
+ if (rc)
+ return rc;
pr_debug("BAM device registered. bam_handle=0x%x",
pce_dev->ce_sps.bam_handle);
@@ -2253,14 +2347,7 @@
sps_connect_consumer_err:
qce_sps_exit_ep_conn(pce_dev, &pce_dev->ce_sps.producer);
sps_connect_producer_err:
- if (register_bam) {
- mutex_lock(&bam_register_cnt);
- sps_deregister_bam_device(pce_dev->ce_sps.bam_handle);
- ce_bam_registered = false;
- bam_registry.handle = 0;
- bam_registry.cnt = 0;
- mutex_unlock(&bam_register_cnt);
- }
+ qce_sps_release_bam(pce_dev);
return rc;
}
@@ -2280,17 +2367,7 @@
{
qce_sps_exit_ep_conn(pce_dev, &pce_dev->ce_sps.consumer);
qce_sps_exit_ep_conn(pce_dev, &pce_dev->ce_sps.producer);
- mutex_lock(&bam_register_cnt);
- if ((bam_registry.handle != 0) && (bam_registry.cnt == 1)) {
- sps_deregister_bam_device(pce_dev->ce_sps.bam_handle);
- bam_registry.cnt = 0;
- bam_registry.handle = 0;
- }
- if ((bam_registry.handle != 0) && (bam_registry.cnt > 1))
- bam_registry.cnt--;
- mutex_unlock(&bam_register_cnt);
-
- iounmap(pce_dev->ce_sps.bam_iobase);
+ qce_sps_release_bam(pce_dev);
}
static void _aead_sps_producer_callback(struct sps_event_notify *notify)
@@ -4069,22 +4146,15 @@
resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"crypto-bam-base");
if (resource) {
- pce_dev->ce_sps.bam_mem = resource->start;
- pce_dev->ce_sps.bam_iobase = ioremap_nocache(resource->start,
- resource_size(resource));
- if (!pce_dev->ce_sps.bam_iobase) {
- rc = -ENOMEM;
- pr_err("Can not map BAM io memory\n");
- goto err_getting_bam_info;
- }
+ pce_dev->bam_mem = resource->start;
+ pce_dev->bam_mem_size = resource_size(resource);
} else {
pr_err("CRYPTO BAM mem unavailable.\n");
rc = -ENODEV;
goto err_getting_bam_info;
}
- pr_warn("ce_bam_phy_reg_base=0x%x ", pce_dev->ce_sps.bam_mem);
- pr_warn("ce_bam_virt_reg_base=0x%x\n",
- (uint32_t)pce_dev->ce_sps.bam_iobase);
+ pr_warn("ce_bam_phy_reg_base=0x%x ", pce_dev->bam_mem);
+
resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (resource) {
pce_dev->ce_sps.bam_irq = resource->start;
@@ -4250,7 +4320,6 @@
void *qce_open(struct platform_device *pdev, int *rc)
{
struct qce_device *pce_dev;
- uint32_t bam_cfg = 0 ;
pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
if (!pce_dev) {
@@ -4293,15 +4362,9 @@
}
*rc = 0;
- bam_cfg = readl_relaxed(pce_dev->ce_sps.bam_iobase +
- CRYPTO_BAM_CNFG_BITS_REG);
- pce_dev->support_cmd_dscr = (bam_cfg & CRYPTO_BAM_CD_ENABLE_MASK) ?
- true : false;
qce_init_ce_cfg_val(pce_dev);
- qce_setup_ce_sps_data(pce_dev);
qce_sps_init(pce_dev);
-
-
+ qce_setup_ce_sps_data(pce_dev);
qce_disable_clk(pce_dev);
return pce_dev;
@@ -4313,8 +4376,6 @@
dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
pce_dev->coh_vmem, pce_dev->coh_pmem);
err_iobase:
- if (pce_dev->ce_sps.bam_iobase)
- iounmap(pce_dev->ce_sps.bam_iobase);
if (pce_dev->iobase)
iounmap(pce_dev->iobase);
err_pce_dev:
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 81a90fe..4845f11 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1339,7 +1339,7 @@
areq->cipher_op_req.vbuf.src[0].len))
return -EFAULT;
- k_align_src += areq->cipher_op_req.vbuf.src[0].len;
+ k_align_src += byteoffset + areq->cipher_op_req.vbuf.src[0].len;
for (i = 1; i < areq->cipher_op_req.entries; i++) {
user_src =
@@ -1602,11 +1602,6 @@
static int qcedev_check_cipher_key(struct qcedev_cipher_op_req *req,
struct qcedev_control *podev)
{
-
- if (req->encklen < 0) {
- pr_err("%s: Invalid key size: %d\n", __func__, req->encklen);
- return -EINVAL;
- }
/* if intending to use HW key make sure key fields are set
* correctly and HW key is indeed supported in target
*/
@@ -1701,6 +1696,13 @@
goto error;
}
}
+
+ if (req->data_len < req->byteoffset) {
+ pr_err("%s: req data length %u is less than byteoffset %u\n",
+ __func__, req->data_len, req->byteoffset);
+ goto error;
+ }
+
/* Ensure zer ivlen for ECB mode */
if (req->ivlen > 0) {
if ((req->mode == QCEDEV_AES_MODE_ECB) ||
@@ -1716,16 +1718,28 @@
}
}
/* Check for sum of all dst length is equal to data_len */
- for (i = 0; (i < QCEDEV_MAX_BUFFERS) && (total < req->data_len); i++)
+ for (i = 0; (i < QCEDEV_MAX_BUFFERS) && (total < req->data_len); i++) {
+ if (req->vbuf.dst[i].len > ULONG_MAX - total) {
+ pr_err("%s: Integer overflow on total req dst vbuf length\n",
+ __func__);
+ goto error;
+ }
total += req->vbuf.dst[i].len;
+ }
if (total != req->data_len) {
pr_err("%s: Total (i=%d) dst(%d) buf size != data_len (%d)\n",
__func__, i, total, req->data_len);
goto error;
}
/* Check for sum of all src length is equal to data_len */
- for (i = 0, total = 0; i < req->entries; i++)
+ for (i = 0, total = 0; i < req->entries; i++) {
+ if (req->vbuf.src[i].len > ULONG_MAX - total) {
+ pr_err("%s: Integer overflow on total req src vbuf length\n",
+ __func__);
+ goto error;
+ }
total += req->vbuf.src[i].len;
+ }
if (total != req->data_len) {
pr_err("%s: Total src(%d) buf size != data_len (%d)\n",
__func__, total, req->data_len);
@@ -1781,8 +1795,15 @@
}
/* Check for sum of all src length is equal to data_len */
- for (i = 0, total = 0; i < req->entries; i++)
+ for (i = 0, total = 0; i < req->entries; i++) {
+ if (req->data[i].len > ULONG_MAX - total) {
+ pr_err("%s: Integer overflow on total req buf length\n",
+ __func__);
+ goto sha_error;
+ }
total += req->data[i].len;
+ }
+
if (total != req->data_len) {
pr_err("%s: Total src(%d) buf size != data_len (%d)\n",
__func__, total, req->data_len);
@@ -2112,21 +2133,21 @@
int len = 0;
pstat = &_qcedev_stat;
- len = snprintf(_debug_read_buf, DEBUG_MAX_RW_BUF - 1,
+ len = scnprintf(_debug_read_buf, DEBUG_MAX_RW_BUF - 1,
"\nQualcomm QCE dev driver %d Statistics:\n",
id + 1);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" Encryption operation success : %d\n",
pstat->qcedev_enc_success);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" Encryption operation fail : %d\n",
pstat->qcedev_enc_fail);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" Decryption operation success : %d\n",
pstat->qcedev_dec_success);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" Encryption operation fail : %d\n",
pstat->qcedev_dec_fail);
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index ae57d6c..6606706 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -409,7 +409,7 @@
{
int i;
- for (i = 0; nbytes > 0; i++, sg = scatterwalk_sg_next(sg))
+ for (i = 0; nbytes > 0 && sg != NULL; i++, sg = scatterwalk_sg_next(sg))
nbytes -= sg->length;
return i;
@@ -628,98 +628,98 @@
int len = 0;
pstat = &_qcrypto_stat;
- len = snprintf(_debug_read_buf, DEBUG_MAX_RW_BUF - 1,
+ len = scnprintf(_debug_read_buf, DEBUG_MAX_RW_BUF - 1,
"\nQualcomm crypto accelerator %d Statistics:\n",
id + 1);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" ABLK AES CIPHER encryption : %d\n",
pstat->ablk_cipher_aes_enc);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" ABLK AES CIPHER decryption : %d\n",
pstat->ablk_cipher_aes_dec);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" ABLK DES CIPHER encryption : %d\n",
pstat->ablk_cipher_des_enc);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" ABLK DES CIPHER decryption : %d\n",
pstat->ablk_cipher_des_dec);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" ABLK 3DES CIPHER encryption : %d\n",
pstat->ablk_cipher_3des_enc);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" ABLK 3DES CIPHER decryption : %d\n",
pstat->ablk_cipher_3des_dec);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" ABLK CIPHER operation success: %d\n",
pstat->ablk_cipher_op_success);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" ABLK CIPHER operation fail : %d\n",
pstat->ablk_cipher_op_fail);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD SHA1-AES encryption : %d\n",
pstat->aead_sha1_aes_enc);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD SHA1-AES decryption : %d\n",
pstat->aead_sha1_aes_dec);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD SHA1-DES encryption : %d\n",
pstat->aead_sha1_des_enc);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD SHA1-DES decryption : %d\n",
pstat->aead_sha1_des_dec);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD SHA1-3DES encryption : %d\n",
pstat->aead_sha1_3des_enc);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD SHA1-3DES decryption : %d\n",
pstat->aead_sha1_3des_dec);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD CCM-AES encryption : %d\n",
pstat->aead_ccm_aes_enc);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD CCM-AES decryption : %d\n",
pstat->aead_ccm_aes_dec);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD operation success : %d\n",
pstat->aead_op_success);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD operation fail : %d\n",
pstat->aead_op_fail);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" AEAD bad message : %d\n",
pstat->aead_bad_msg);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" SHA1 digest : %d\n",
pstat->sha1_digest);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" SHA256 digest : %d\n",
pstat->sha256_digest);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" SHA operation fail : %d\n",
pstat->sha_op_fail);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" SHA operation success : %d\n",
pstat->sha_op_success);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" SHA1 HMAC digest : %d\n",
pstat->sha1_hmac_digest);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" SHA256 HMAC digest : %d\n",
pstat->sha256_hmac_digest);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" SHA HMAC operation fail : %d\n",
pstat->sha_hmac_op_fail);
- len += snprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
+ len += scnprintf(_debug_read_buf + len, DEBUG_MAX_RW_BUF - len - 1,
" SHA HMAC operation success : %d\n",
pstat->sha_hmac_op_success);
return len;
@@ -1423,8 +1423,20 @@
rctx->orig_src = req->src;
rctx->orig_dst = req->dst;
+
+ if ((MAX_ALIGN_SIZE*2 > ULONG_MAX - req->assoclen) ||
+ ((MAX_ALIGN_SIZE*2 + req->assoclen) >
+ ULONG_MAX - qreq.authsize) ||
+ ((MAX_ALIGN_SIZE*2 + req->assoclen +
+ qreq.authsize) >
+ ULONG_MAX - req->cryptlen)) {
+ pr_err("Integer overflow on aead req length.\n");
+ return -EINVAL;
+ }
+
rctx->data = kzalloc((req->cryptlen + qreq.assoclen +
- qreq.authsize + 64*2), GFP_ATOMIC);
+ qreq.authsize + MAX_ALIGN_SIZE*2),
+ GFP_ATOMIC);
if (rctx->data == NULL) {
pr_err("Mem Alloc fail rctx->data, err %ld\n",
PTR_ERR(rctx->data));
@@ -1486,6 +1498,16 @@
* include assoicated data, ciphering data stream,
* generated MAC, and CCM padding.
*/
+ if ((MAX_ALIGN_SIZE * 2 > ULONG_MAX - req->assoclen) ||
+ ((MAX_ALIGN_SIZE * 2 + req->assoclen) >
+ ULONG_MAX - qreq.ivsize) ||
+ ((MAX_ALIGN_SIZE * 2 + req->assoclen
+ + qreq.ivsize)
+ > ULONG_MAX - req->cryptlen)) {
+ pr_err("Integer overflow on aead req length.\n");
+ return -EINVAL;
+ }
+
rctx->data = kzalloc(
(req->cryptlen +
req->assoclen +
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 44bb86f..e1b3383 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -212,7 +212,7 @@
err1:
kfree(table);
err:
- list_for_each_entry(info, &pages, list) {
+ list_for_each_entry_safe(info, tmp_info, &pages, list) {
free_buffer_page(sys_heap, buffer, info->page, info->order);
kfree(info);
}
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index a30607c..093b001 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -91,7 +91,6 @@
static struct class *driver_class;
static dev_t qseecom_device_no;
-static struct cdev qseecom_cdev;
static DEFINE_MUTEX(qsee_bw_mutex);
static DEFINE_MUTEX(app_access_lock);
@@ -162,6 +161,7 @@
uint32_t qsee_perf_client;
struct qseecom_clk qsee;
struct qseecom_clk ce_drv;
+ struct cdev cdev;
};
struct qseecom_client_handle {
@@ -3330,7 +3330,7 @@
if (IS_ERR(driver_class)) {
rc = -ENOMEM;
pr_err("class_create failed %d\n", rc);
- goto unregister_chrdev_region;
+ goto exit_unreg_chrdev_region;
}
class_dev = device_create(driver_class, NULL, qseecom_device_no, NULL,
@@ -3338,16 +3338,16 @@
if (!class_dev) {
pr_err("class_device_create failed %d\n", rc);
rc = -ENOMEM;
- goto class_destroy;
+ goto exit_destroy_class;
}
- cdev_init(&qseecom_cdev, &qseecom_fops);
- qseecom_cdev.owner = THIS_MODULE;
+ cdev_init(&qseecom.cdev, &qseecom_fops);
+ qseecom.cdev.owner = THIS_MODULE;
- rc = cdev_add(&qseecom_cdev, MKDEV(MAJOR(qseecom_device_no), 0), 1);
+ rc = cdev_add(&qseecom.cdev, MKDEV(MAJOR(qseecom_device_no), 0), 1);
if (rc < 0) {
pr_err("cdev_add failed %d\n", rc);
- goto err;
+ goto exit_destroy_device;
}
INIT_LIST_HEAD(&qseecom.registered_listener_list_head);
@@ -3363,7 +3363,7 @@
&qsee_not_legacy, sizeof(qsee_not_legacy));
if (rc) {
pr_err("Failed to retrieve QSEOS version information %d\n", rc);
- goto err;
+ goto exit_del_cdev;
}
if (qsee_not_legacy) {
uint32_t feature = 10;
@@ -3373,14 +3373,14 @@
&qseecom.qsee_version, sizeof(qseecom.qsee_version));
if (rc) {
pr_err("Failed to get QSEE version info %d\n", rc);
- goto err;
+ goto exit_del_cdev;
}
qseecom.qseos_version = QSEOS_VERSION_14;
} else {
pr_err("QSEE legacy version is not supported:");
pr_err("Support for TZ1.3 and earlier is deprecated\n");
rc = -EINVAL;
- goto err;
+ goto exit_del_cdev;
}
qseecom.commonlib_loaded = false;
qseecom.pdev = class_dev;
@@ -3389,7 +3389,7 @@
if (qseecom.ion_clnt == NULL) {
pr_err("Ion client cannot be created\n");
rc = -ENOMEM;
- goto err;
+ goto exit_del_cdev;
}
/* register client for bus scaling */
@@ -3401,7 +3401,7 @@
pr_err("Fail to get disk-encrypt pipe pair information.\n");
qseecom.ce_info.disk_encrypt_pipe = 0xff;
rc = -EINVAL;
- goto err;
+ goto exit_destroy_ion_client;
} else {
pr_warn("bam_pipe_pair=0x%x",
qseecom.ce_info.disk_encrypt_pipe);
@@ -3413,7 +3413,7 @@
pr_err("Fail to get qsee ce hw instance information.\n");
qseecom.ce_info.qsee_ce_hw_instance = 0xff;
rc = -EINVAL;
- goto err;
+ goto exit_destroy_ion_client;
} else {
pr_warn("qsee-ce-hw-instance=0x%x",
qseecom.ce_info.qsee_ce_hw_instance);
@@ -3425,7 +3425,7 @@
pr_err("Fail to get hlos ce hw instance information.\n");
qseecom.ce_info.hlos_ce_hw_instance = 0xff;
rc = -EINVAL;
- goto err;
+ goto exit_destroy_ion_client;
} else {
pr_warn("hlos-ce-hw-instance=0x%x",
qseecom.ce_info.hlos_ce_hw_instance);
@@ -3436,13 +3436,13 @@
ret = __qseecom_init_clk(CLK_QSEE);
if (ret)
- goto err;
+ goto exit_destroy_ion_client;
if (qseecom.qsee.instance != qseecom.ce_drv.instance) {
ret = __qseecom_init_clk(CLK_CE_DRV);
if (ret) {
__qseecom_deinit_clk(CLK_QSEE);
- goto err;
+ goto exit_destroy_ion_client;
}
} else {
struct qseecom_clk *qclk;
@@ -3472,7 +3472,7 @@
} else {
pr_err("Fail to get secure app region info\n");
rc = -EINVAL;
- goto err;
+ goto exit_destroy_ion_client;
}
rc = scm_call(SCM_SVC_TZSCHEDULER, 1, &req, sizeof(req),
&resp, sizeof(resp));
@@ -3480,7 +3480,7 @@
pr_err("send secapp reg fail %d resp.res %d\n",
rc, resp.result);
rc = -EINVAL;
- goto err;
+ goto exit_destroy_ion_client;
}
}
} else {
@@ -3494,11 +3494,16 @@
if (!qseecom.qsee_perf_client)
pr_err("Unable to register bus client\n");
return 0;
-err:
+
+exit_destroy_ion_client:
+ ion_client_destroy(qseecom.ion_clnt);
+exit_del_cdev:
+ cdev_del(&qseecom.cdev);
+exit_destroy_device:
device_destroy(driver_class, qseecom_device_no);
-class_destroy:
+exit_destroy_class:
class_destroy(driver_class);
-unregister_chrdev_region:
+exit_unreg_chrdev_region:
unregister_chrdev_region(qseecom_device_no, 1);
return rc;
}
@@ -3509,69 +3514,64 @@
unsigned long flags = 0;
int ret = 0;
- if (pdev->dev.platform_data != NULL)
- msm_bus_scale_unregister_client(qseecom.qsee_perf_client);
-
spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
- kclient = list_entry((&qseecom.registered_kclient_list_head)->next,
- struct qseecom_registered_kclient_list, list);
- if (list_empty(&kclient->list)) {
- spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock,
- flags);
- return 0;
- }
+
list_for_each_entry(kclient, &qseecom.registered_kclient_list_head,
- list) {
- if (kclient)
- list_del(&kclient->list);
- break;
- }
- spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock, flags);
+ list) {
+ if (!kclient)
+ goto exit_irqrestore;
+ /* Break the loop if client handle is NULL */
+ if (!kclient->handle)
+ goto exit_free_kclient;
- while (kclient->handle != NULL) {
+ if (list_empty(&kclient->list))
+ goto exit_free_kc_handle;
+
+ list_del(&kclient->list);
ret = qseecom_unload_app(kclient->handle->dev);
- if (ret == 0) {
+ if (!ret) {
kzfree(kclient->handle->dev);
kzfree(kclient->handle);
kzfree(kclient);
}
- spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
- kclient = list_entry(
- (&qseecom.registered_kclient_list_head)->next,
- struct qseecom_registered_kclient_list, list);
- if (list_empty(&kclient->list)) {
- spin_unlock_irqrestore(
- &qseecom.registered_kclient_list_lock, flags);
- return 0;
- }
- list_for_each_entry(kclient,
- &qseecom.registered_kclient_list_head, list) {
- if (kclient)
- list_del(&kclient->list);
- break;
- }
- spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock,
- flags);
- if (!kclient) {
- ret = 0;
- break;
- }
}
- if (qseecom.qseos_version > QSEEE_VERSION_00)
+
+exit_free_kc_handle:
+ kzfree(kclient->handle);
+exit_free_kclient:
+ kzfree(kclient);
+exit_irqrestore:
+ spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock, flags);
+
+ if (qseecom.qseos_version > QSEEE_VERSION_00)
qseecom_unload_commonlib_image();
if (qseecom.qsee_perf_client)
msm_bus_scale_client_update_request(qseecom.qsee_perf_client,
0);
+ if (pdev->dev.platform_data != NULL)
+ msm_bus_scale_unregister_client(qseecom.qsee_perf_client);
+
/* register client for bus scaling */
if (pdev->dev.of_node) {
__qseecom_deinit_clk(CLK_QSEE);
if (qseecom.qsee.instance != qseecom.ce_drv.instance)
__qseecom_deinit_clk(CLK_CE_DRV);
}
+
+ ion_client_destroy(qseecom.ion_clnt);
+
+ cdev_del(&qseecom.cdev);
+
+ device_destroy(driver_class, qseecom_device_no);
+
+ class_destroy(driver_class);
+
+ unregister_chrdev_region(qseecom_device_no, 1);
+
return ret;
-};
+}
static struct of_device_id qseecom_match[] = {
{
@@ -3597,10 +3597,7 @@
static void __devexit qseecom_exit(void)
{
- device_destroy(driver_class, qseecom_device_no);
- class_destroy(driver_class);
- unregister_chrdev_region(qseecom_device_no, 1);
- ion_client_destroy(qseecom.ion_clnt);
+ platform_driver_unregister(&qseecom_plat_driver);
}
MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index 36bdf45..3d69473 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -1821,7 +1821,7 @@
}
if (filter->priority >= TSPP_NUM_PRIORITIES) {
- pr_err("tspp invalid source");
+ pr_err("tspp invalid filter priority");
return -ENOSR;
}
@@ -1950,6 +1950,10 @@
pr_err("tspp_remove: can't find device %i", dev);
return -ENODEV;
}
+ if (filter->priority >= TSPP_NUM_PRIORITIES) {
+ pr_err("tspp invalid filter priority");
+ return -ENOSR;
+ }
channel = &pdev->channels[channel_id];
src = channel->src;
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 9727787..aa4e016 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -1876,7 +1876,7 @@
if (batt_terminal_uv >= chip->max_voltage_uv - VDD_MAX_ERR) {
chip->soc_at_cv = soc;
chip->prev_chg_soc = soc;
- chip->ibat_at_cv_ua = ibat_ua;
+ chip->ibat_at_cv_ua = params->iavg_ua;
pr_debug("CC_TO_CV ibat_ua = %d CHG SOC %d\n",
ibat_ua, soc);
} else {
@@ -1927,7 +1927,7 @@
soc_ibat = bound_soc(linear_interpolate(chip->soc_at_cv,
chip->ibat_at_cv_ua,
100, -1 * chip->chg_term_ua,
- ibat_ua));
+ params->iavg_ua));
weight_ibat = bound_soc(linear_interpolate(1, chip->soc_at_cv,
100, 100, chip->prev_chg_soc));
weight_cc = 100 - weight_ibat;
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 91d94b5..83fa657 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -32,6 +32,7 @@
#include <linux/lzo.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
+#include <linux/ratelimit.h>
#include "zram_drv.h"
@@ -39,6 +40,12 @@
static int zram_major;
static struct zram *zram_devices;
+/*
+ * We don't need to see memory allocation errors more than once every 1
+ * second to know that a problem is occurring.
+ */
+#define ALLOC_ERROR_LOG_RATE_MS 1000
+
/* Module params (documentation at end) */
static unsigned int num_devices = 1;
@@ -221,7 +228,8 @@
goto free_buffer;
}
- meta->mem_pool = zs_create_pool(GFP_NOIO | __GFP_HIGHMEM);
+ meta->mem_pool = zs_create_pool(GFP_NOIO | __GFP_HIGHMEM |
+ __GFP_NOWARN);
if (!meta->mem_pool) {
pr_err("Error creating memory pool\n");
goto free_table;
@@ -399,6 +407,7 @@
struct page *page;
unsigned char *user_mem, *cmem, *src, *uncmem = NULL;
struct zram_meta *meta = zram->meta;
+ static unsigned long zram_rs_time;
page = bvec->bv_page;
src = meta->compress_buffer;
@@ -472,8 +481,10 @@
handle = zs_malloc(meta->mem_pool, clen);
if (!handle) {
- pr_info("Error allocating memory for compressed page: %u, size=%zu\n",
- index, clen);
+ if (printk_timed_ratelimit(&zram_rs_time,
+ ALLOC_ERROR_LOG_RATE_MS))
+ pr_info("Error allocating memory for compressed page: %u, size=%zu\n",
+ index, clen);
ret = -ENOMEM;
goto out;
}
diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h
index 97a3acf..508a19f 100644
--- a/drivers/staging/zram/zram_drv.h
+++ b/drivers/staging/zram/zram_drv.h
@@ -32,7 +32,7 @@
* Pages that compress to size greater than this are stored
* uncompressed in memory.
*/
-static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
+static const size_t max_zpage_size = PAGE_SIZE / 10 * 9;
/*
* NOTE: max_zpage_size must be less than or equal to:
diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c
index 1a67537..523b937 100644
--- a/drivers/staging/zsmalloc/zsmalloc-main.c
+++ b/drivers/staging/zsmalloc/zsmalloc-main.c
@@ -472,7 +472,7 @@
set_page_private(page, 0);
page->mapping = NULL;
page->freelist = NULL;
- page_mapcount_reset(page);
+ reset_page_mapcount(page);
}
static void free_zspage(struct page *first_page)
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index d642093..c4986ef 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -184,11 +184,11 @@
u32 mdp_interrupt = 0;
spin_lock(&mdata->irq_lock);
- if (!mdata->irq_mask) {
+ if (!mdata->irq_mask)
pr_err("spurious interrupt\n");
- spin_unlock(&mdata->irq_lock);
- return IRQ_HANDLED;
- }
+
+ clk_enable(mdp3_res->clocks[MDP3_CLK_AHB]);
+ clk_enable(mdp3_res->clocks[MDP3_CLK_CORE]);
mdp_interrupt = MDP3_REG_READ(MDP3_REG_INTR_STATUS);
MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, mdp_interrupt);
@@ -202,6 +202,10 @@
mdp_interrupt = mdp_interrupt >> 1;
i++;
}
+
+ clk_disable(mdp3_res->clocks[MDP3_CLK_AHB]);
+ clk_disable(mdp3_res->clocks[MDP3_CLK_CORE]);
+
spin_unlock(&mdata->irq_lock);
return IRQ_HANDLED;
@@ -281,8 +285,6 @@
spin_lock_irqsave(&mdp3_res->irq_lock, flag);
memset(mdp3_res->irq_ref_count, 0, sizeof(u32) * MDP3_MAX_INTR);
mdp3_res->irq_mask = 0;
- MDP3_REG_WRITE(MDP3_REG_INTR_ENABLE, 0);
- MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, 0xfffffff);
disable_irq_nosync(mdp3_res->irq);
spin_unlock_irqrestore(&mdp3_res->irq_lock, flag);
}
@@ -415,10 +417,10 @@
count = mdp3_res->clock_ref_count[clk_idx];
if (count == 1 && enable) {
pr_debug("clk=%d en=%d\n", clk_idx, enable);
- ret = clk_prepare_enable(clk);
+ ret = clk_enable(clk);
} else if (count == 0) {
pr_debug("clk=%d disable\n", clk_idx);
- clk_disable_unprepare(clk);
+ clk_disable(clk);
ret = 0;
} else if (count < 0) {
pr_err("clk=%d count=%d\n", clk_idx, count);
@@ -554,7 +556,7 @@
clk_put(mdp3_res->clocks[MDP3_CLK_DSI]);
}
-int mdp3_clk_enable(int enable)
+int mdp3_clk_enable(int enable, int dsi_clk)
{
int rc;
@@ -564,7 +566,79 @@
rc = mdp3_clk_update(MDP3_CLK_AHB, enable);
rc |= mdp3_clk_update(MDP3_CLK_CORE, enable);
rc |= mdp3_clk_update(MDP3_CLK_VSYNC, enable);
- rc |= mdp3_clk_update(MDP3_CLK_DSI, enable);
+ if (dsi_clk)
+ rc |= mdp3_clk_update(MDP3_CLK_DSI, enable);
+ mutex_unlock(&mdp3_res->res_mutex);
+ return rc;
+}
+
+int mdp3_clk_prepare(void)
+{
+ int rc = 0;
+
+ mutex_lock(&mdp3_res->res_mutex);
+ mdp3_res->clk_prepare_count++;
+ if (mdp3_res->clk_prepare_count == 1) {
+ rc = clk_prepare(mdp3_res->clocks[MDP3_CLK_AHB]);
+ if (rc < 0)
+ goto error0;
+ rc = clk_prepare(mdp3_res->clocks[MDP3_CLK_CORE]);
+ if (rc < 0)
+ goto error1;
+ rc = clk_prepare(mdp3_res->clocks[MDP3_CLK_VSYNC]);
+ if (rc < 0)
+ goto error2;
+ rc = clk_prepare(mdp3_res->clocks[MDP3_CLK_DSI]);
+ if (rc < 0)
+ goto error3;
+ }
+ mutex_unlock(&mdp3_res->res_mutex);
+ return rc;
+
+error3:
+ clk_unprepare(mdp3_res->clocks[MDP3_CLK_VSYNC]);
+error2:
+ clk_unprepare(mdp3_res->clocks[MDP3_CLK_CORE]);
+error1:
+ clk_unprepare(mdp3_res->clocks[MDP3_CLK_AHB]);
+error0:
+ mdp3_res->clk_prepare_count--;
+ mutex_unlock(&mdp3_res->res_mutex);
+ return rc;
+}
+
+void mdp3_clk_unprepare(void)
+{
+ mutex_lock(&mdp3_res->res_mutex);
+ mdp3_res->clk_prepare_count--;
+ if (mdp3_res->clk_prepare_count == 0) {
+ clk_unprepare(mdp3_res->clocks[MDP3_CLK_AHB]);
+ clk_unprepare(mdp3_res->clocks[MDP3_CLK_CORE]);
+ clk_unprepare(mdp3_res->clocks[MDP3_CLK_VSYNC]);
+ clk_unprepare(mdp3_res->clocks[MDP3_CLK_DSI]);
+ } else if (mdp3_res->clk_prepare_count < 0) {
+ pr_err("mdp3 clk unprepare mismatch\n");
+ }
+ mutex_unlock(&mdp3_res->res_mutex);
+}
+
+int mdp3_get_mdp_dsi_clk(void)
+{
+ int rc;
+
+ mutex_lock(&mdp3_res->res_mutex);
+ clk_prepare(mdp3_res->clocks[MDP3_CLK_DSI]);
+ rc = mdp3_clk_update(MDP3_CLK_DSI, 1);
+ mutex_unlock(&mdp3_res->res_mutex);
+ return rc;
+}
+
+int mdp3_put_mdp_dsi_clk(void)
+{
+ int rc;
+ mutex_lock(&mdp3_res->res_mutex);
+ rc = mdp3_clk_update(MDP3_CLK_DSI, 0);
+ clk_unprepare(mdp3_res->clocks[MDP3_CLK_DSI]);
mutex_unlock(&mdp3_res->res_mutex);
return rc;
}
@@ -1512,8 +1586,17 @@
static int mdp3_init(struct msm_fb_data_type *mfd)
{
int rc;
+
rc = mdp3_ctrl_init(mfd);
- rc |= mdp3_ppp_res_init(mfd);
+ if (rc) {
+ pr_err("mdp3 ctl init fail\n");
+ return rc;
+ }
+
+ rc = mdp3_ppp_res_init(mfd);
+ if (rc)
+ pr_err("mdp3 ppp res init fail\n");
+
return rc;
}
@@ -1740,9 +1823,16 @@
pr_debug("mdp3__continuous_splash_on\n");
- rc = mdp3_clk_enable(1);
+ rc = mdp3_clk_prepare();
+ if (rc) {
+ pr_err("fail to prepare clk\n");
+ return rc;
+ }
+
+ rc = mdp3_clk_enable(1, 1);
if (rc) {
pr_err("fail to enable clk\n");
+ mdp3_clk_unprepare();
return rc;
}
@@ -1779,8 +1869,10 @@
return 0;
splash_on_err:
- if (mdp3_clk_enable(0))
+ if (mdp3_clk_enable(0, 1))
pr_err("%s: Unable to disable mdp3 clocks\n", __func__);
+
+ mdp3_clk_unprepare();
return rc;
}
@@ -1813,10 +1905,13 @@
static void mdp3_debug_enable_clock(int on)
{
- if (on)
- mdp3_clk_enable(1);
- else
- mdp3_clk_enable(0);
+ if (on) {
+ mdp3_clk_prepare();
+ mdp3_clk_enable(1, 0);
+ } else {
+ mdp3_clk_enable(0, 0);
+ mdp3_clk_unprepare();
+ }
}
static int mdp3_debug_init(struct platform_device *pdev)
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index e66b5ac..e0dd021 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -152,6 +152,8 @@
struct mdss_panel_cfg pan_cfg;
u32 splash_mem_addr;
u32 splash_mem_size;
+
+ int clk_prepare_count;
};
struct mdp3_img_data {
@@ -175,7 +177,9 @@
void mdp3_irq_register(void);
void mdp3_irq_deregister(void);
int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate, int client);
-int mdp3_clk_enable(int enable);
+int mdp3_clk_enable(int enable, int dsi_clk);
+int mdp3_clk_prepare(void);
+void mdp3_clk_unprepare(void);
int mdp3_bus_scale_set_quota(int client, u64 ab_quota, u64 ib_quota);
int mdp3_put_img(struct mdp3_img_data *data, int client);
int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data,
@@ -187,6 +191,8 @@
int mdp3_parse_dt_splash(struct msm_fb_data_type *mfd);
void mdp3_release_splash_memory(void);
int mdp3_create_sysfs_link(struct device *dev);
+int mdp3_get_mdp_dsi_clk(void);
+int mdp3_put_mdp_dsi_clk(void);
#define MDP3_REG_WRITE(addr, val) writel_relaxed(val, mdp3_res->mdp_base + addr)
#define MDP3_REG_READ(addr) readl_relaxed(mdp3_res->mdp_base + addr)
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index b123ccb..de4e9a1 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -118,7 +118,9 @@
}
mutex_lock(&mdp3_session->lock);
+ mdp3_clk_enable(1, 0);
mdp3_session->dma->vsync_enable(mdp3_session->dma, arg);
+ mdp3_clk_enable(0, 0);
if (enable && mdp3_session->status == 1 && !mdp3_session->intf->active)
mod_timer(&mdp3_session->vsync_timer,
jiffies + msecs_to_jiffies(mdp3_session->vsync_period));
@@ -236,12 +238,24 @@
mdp3_clk_set_rate(MDP3_CLK_VSYNC, MDP_VSYNC_CLK_RATE,
MDP3_CLIENT_DMA_P);
- rc = mdp3_clk_enable(true);
- if (rc)
+ rc = mdp3_clk_prepare();
+ if (rc) {
+ pr_err("mdp3 clk prepare fail\n");
return rc;
+ }
+ rc = mdp3_clk_enable(1, 1);
+ if (rc) {
+ pr_err("mdp3 clk enable fail\n");
+ mdp3_clk_unprepare();
+ return rc;
+ }
} else {
- rc = mdp3_clk_enable(false);
+ rc = mdp3_clk_enable(0, 1);
+ if (rc)
+ pr_err("mdp3 clk disable fail\n");
+ else
+ mdp3_clk_unprepare();
}
return rc;
}
@@ -517,19 +531,21 @@
goto off_error;
}
+ mdp3_clk_enable(1, 0);
+
mdp3_histogram_stop(mdp3_session, MDP_BLOCK_DMA_P);
rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
if (rc)
pr_debug("fail to stop the MDP3 dma\n");
+ mdp3_clk_enable(0, 0);
+
if (panel->event_handler)
rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
if (rc)
pr_err("fail to turn off the panel\n");
-
-
mdp3_irq_deregister();
pr_debug("mdp3_ctrl_off stop clock\n");
@@ -650,7 +666,7 @@
if (rc)
pr_err("fail to turn off panel\n");
- rc = mdp3_ctrl_res_req_clk(mfd, 0);
+ rc = mdp3_put_mdp_dsi_clk();
if (rc) {
pr_err("fail to release mdp clocks\n");
goto reset_error;
@@ -680,7 +696,7 @@
goto reset_error;
}
- rc = mdp3_ctrl_res_req_clk(mfd, 1);
+ rc = mdp3_get_mdp_dsi_clk();
if (rc) {
pr_err("fail to turn on mdp clks\n");
goto reset_error;
@@ -845,9 +861,11 @@
data = mdp3_bufq_pop(&mdp3_session->bufq_in);
if (data) {
+ mdp3_clk_enable(1, 0);
mdp3_session->dma->update(mdp3_session->dma,
(void *)data->addr,
mdp3_session->intf);
+ mdp3_clk_enable(0, 0);
mdp3_bufq_push(&mdp3_session->bufq_out, data);
}
@@ -912,6 +930,7 @@
goto pan_error;
}
+ mdp3_clk_enable(1, 0);
if (mfd->fbi->screen_base) {
mdp3_session->dma->update(mdp3_session->dma,
(void *)mfd->iova + offset,
@@ -920,6 +939,7 @@
pr_debug("mdp3_ctrl_pan_display no memory, stop interface");
mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
}
+ mdp3_clk_enable(0, 0);
if (mdp3_session->first_commit) {
/*wait for one frame time to ensure frame is sent to panel*/
@@ -1034,10 +1054,11 @@
if (session->histo_status) {
pr_err("mdp3_histogram_start already started\n");
- ret = -EBUSY;
- goto histogram_start_err;
+ mutex_unlock(&session->histo_lock);
+ return -EBUSY;
}
+ mdp3_clk_enable(1, 0);
ret = session->dma->histo_op(session->dma, MDP3_DMA_HISTO_OP_RESET);
if (ret) {
pr_err("mdp3_histogram_start reset error\n");
@@ -1063,6 +1084,8 @@
session->histo_status = 1;
histogram_start_err:
+ if (ret)
+ mdp3_clk_enable(0, 0);
mutex_unlock(&session->histo_lock);
return ret;
}
@@ -1086,6 +1109,7 @@
}
ret = session->dma->histo_op(session->dma, MDP3_DMA_HISTO_OP_CANCEL);
+ mdp3_clk_enable(0, 0);
if (ret)
pr_err("mdp3_histogram_stop error\n");
@@ -1199,7 +1223,9 @@
ccs.post_lv = data->csc_data.csc_post_lv;
mutex_lock(&session->lock);
+ mdp3_clk_enable(1, 0);
ret = session->dma->config_ccs(session->dma, &config, &ccs);
+ mdp3_clk_enable(0, 0);
mutex_unlock(&session->lock);
return ret;
}
@@ -1341,8 +1367,10 @@
return -EPERM;
}
+ mdp3_clk_enable(1, 0);
rc = mdp3_session->dma->config_lut(mdp3_session->dma, &lut_config,
&lut);
+ mdp3_clk_enable(0, 0);
if (rc)
pr_err("mdp3_ctrl_lut_update failed\n");
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index 89f3e27..3a2c94b 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.c
@@ -828,6 +828,9 @@
MDP3_DMA_CALLBACK_TYPE_DMA_DONE);
mdp3_irq_disable(MDP3_INTR_LCDC_UNDERFLOW);
+ MDP3_REG_WRITE(MDP3_REG_INTR_ENABLE, 0);
+ MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, 0xfffffff);
+
init_completion(&dma->dma_comp);
dma->vsync_client.handler = NULL;
return ret;
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index 83787c3..6187db4 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -372,14 +372,14 @@
ib = (ab * 3) / 2;
}
mdp3_clk_set_rate(MDP3_CLK_CORE, rate, MDP3_CLIENT_PPP);
- rc = mdp3_clk_enable(on_off);
+ rc = mdp3_clk_enable(on_off, 0);
if (rc < 0) {
pr_err("%s: mdp3_clk_enable failed\n", __func__);
return rc;
}
rc = mdp3_bus_scale_set_quota(MDP3_CLIENT_PPP, ab, ib);
if (rc < 0) {
- mdp3_clk_enable(!on_off);
+ mdp3_clk_enable(!on_off, 0);
pr_err("%s: scale_set_quota failed\n", __func__);
return rc;
}
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 4bbd07a..8da837b 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -90,8 +90,8 @@
* unusual file system layouts.
*/
if (ext4_block_in_group(sb, ext4_block_bitmap(sb, gdp), block_group)) {
- block_cluster = EXT4_B2C(sbi, (start -
- ext4_block_bitmap(sb, gdp)));
+ block_cluster = EXT4_B2C(sbi,
+ ext4_block_bitmap(sb, gdp) - start);
if (block_cluster < num_clusters)
block_cluster = -1;
else if (block_cluster == num_clusters) {
@@ -102,7 +102,7 @@
if (ext4_block_in_group(sb, ext4_inode_bitmap(sb, gdp), block_group)) {
inode_cluster = EXT4_B2C(sbi,
- start - ext4_inode_bitmap(sb, gdp));
+ ext4_inode_bitmap(sb, gdp) - start);
if (inode_cluster < num_clusters)
inode_cluster = -1;
else if (inode_cluster == num_clusters) {
@@ -114,7 +114,7 @@
itbl_blk = ext4_inode_table(sb, gdp);
for (i = 0; i < sbi->s_itb_per_group; i++) {
if (ext4_block_in_group(sb, itbl_blk + i, block_group)) {
- c = EXT4_B2C(sbi, start - itbl_blk + i);
+ c = EXT4_B2C(sbi, itbl_blk + i - start);
if ((c < num_clusters) || (c == inode_cluster) ||
(c == block_cluster) || (c == itbl_cluster))
continue;
diff --git a/include/linux/tspp.h b/include/linux/tspp.h
index c790c28..ddddbfb 100644
--- a/include/linux/tspp.h
+++ b/include/linux/tspp.h
@@ -34,7 +34,7 @@
int pid;
int mask;
enum tspp_mode mode;
- int priority; /* 0 - 15 */
+ unsigned int priority; /* 0 - 15 */
int decrypt;
enum tspp_source source;
};
diff --git a/mm/page_io.c b/mm/page_io.c
index e60e43f..1499e1c 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -20,8 +20,15 @@
#include <linux/swapops.h>
#include <linux/writeback.h>
#include <linux/blkdev.h>
+#include <linux/ratelimit.h>
#include <asm/pgtable.h>
+/*
+ * We don't need to see swap errors more than once every 1 second to know
+ * that a problem is occurring.
+ */
+#define SWAP_ERROR_LOG_RATE_MS 1000
+
static struct bio *get_swap_bio(gfp_t gfp_flags,
struct page *page, bio_end_io_t end_io)
{
@@ -46,6 +53,7 @@
{
const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct page *page = bio->bi_io_vec[0].bv_page;
+ static unsigned long swap_error_rs_time;
if (!uptodate) {
SetPageError(page);
@@ -58,7 +66,9 @@
* Also clear PG_reclaim to avoid rotate_reclaimable_page()
*/
set_page_dirty(page);
- printk(KERN_ALERT "Write-error on swap-device (%u:%u:%Lu)\n",
+ if (printk_timed_ratelimit(&swap_error_rs_time,
+ SWAP_ERROR_LOG_RATE_MS))
+ printk(KERN_ALERT "Write-error on swap-device (%u:%u:%Lu)\n",
imajor(bio->bi_bdev->bd_inode),
iminor(bio->bi_bdev->bd_inode),
(unsigned long long)bio->bi_sector);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9e95109..d0e40e5 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -474,6 +474,8 @@
if (!PageWriteback(page)) {
/* synchronous write or broken a_ops? */
ClearPageReclaim(page);
+ if (PageError(page))
+ return PAGE_ACTIVATE;
}
trace_mm_vmscan_writepage(page, trace_reclaim_flags(page));
inc_zone_page_state(page, NR_VMSCAN_WRITE);
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index d235a69..39cb470 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -281,6 +281,17 @@
.rate_min = 8000,
.rate_max = 192000,
},
+ .capture = {
+ .stream_name = "MultiMedia8 Capture",
+ .aif_name = "MM_UL8",
+ .rates = (SNDRV_PCM_RATE_8000_48000|
+ SNDRV_PCM_RATE_KNOT),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia8",
},
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 99f196c..b34750a 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -2158,7 +2158,7 @@
.name = "MSM8974 Compr4",
.stream_name = "COMPR4",
.cpu_dai_name = "MultiMedia8",
- .platform_name = "msm-compress-dsp",
+ .platform_name = "msm-compr-dsp",
.dynamic = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile
index 15128c9..5aa84a0 100644
--- a/sound/soc/msm/qdsp6v2/Makefile
+++ b/sound/soc/msm/qdsp6v2/Makefile
@@ -1,6 +1,7 @@
snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o msm-pcm-routing-v2.o \
- msm-compress-q6-v2.o msm-multi-ch-pcm-q6-v2.o \
- msm-pcm-lpa-v2.o msm-pcm-afe-v2.o msm-pcm-voip-v2.o \
+ msm-compress-q6-v2.o msm-compr-q6-v2.o \
+ msm-multi-ch-pcm-q6-v2.o msm-pcm-lpa-v2.o \
+ msm-pcm-afe-v2.o msm-pcm-voip-v2.o \
msm-pcm-voice-v2.o msm-dai-q6-hdmi-v2.o \
msm-lsm-client.o
obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index b626fa4..bb325d8 100755
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -52,6 +52,9 @@
#define COMPRESSED_LR_VOL_MAX_STEPS 0x20002000
#define MAX_AC3_PARAM_SIZE (18*2*sizeof(int))
+#define AMR_WB_BAND_MODE 8
+#define AMR_WB_DTX_MODE 0
+
const DECLARE_TLV_DB_LINEAR(compr_rx_vol_gain, 0,
COMPRESSED_LR_VOL_MAX_STEPS);
@@ -108,12 +111,30 @@
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
};
+/* Add supported codecs for compress capture path */
+static uint32_t supported_compr_capture_codecs[] = {
+ SND_AUDIOCODEC_AMRWB
+};
+
static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
.count = ARRAY_SIZE(supported_sample_rates),
.list = supported_sample_rates,
.mask = 0,
};
+static bool msm_compr_capture_codecs(uint32_t req_codec)
+{
+ int i;
+ pr_debug("%s req_codec:%d\n", __func__, req_codec);
+ if (req_codec == 0)
+ return false;
+ for (i = 0; i < ARRAY_SIZE(supported_compr_capture_codecs); i++) {
+ if (req_codec == supported_compr_capture_codecs[i])
+ return true;
+ }
+ return false;
+}
+
static void compr_event_handler(uint32_t opcode,
uint32_t token, uint32_t *payload, void *priv)
{
@@ -428,6 +449,11 @@
prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
prtd->pcm_irq_pos = 0;
+ if (!msm_compr_capture_codecs(codec->id)) {
+ /*request codec invalid or not supported,
+ use default compress format*/
+ codec->id = SND_AUDIOCODEC_AMRWB;
+ }
/* rate and channels are sent to audio driver */
prtd->samp_rate = runtime->rate;
prtd->channel_mode = runtime->channels;
@@ -441,8 +467,12 @@
pr_debug("SND_AUDIOCODEC_AMRWB\n");
ret = q6asm_enc_cfg_blk_amrwb(prtd->audio_client,
MAX_NUM_FRAMES_PER_BUFFER,
- codec->options.generic.reserved[0] /*bitrate 0-8*/,
- codec->options.generic.reserved[1] /*dtx mode 0/1*/);
+ /* use fixed band mode and dtx mode
+ * band mode - 23.85 kbps
+ */
+ AMR_WB_BAND_MODE,
+ /* dtx mode - disable */
+ AMR_WB_DTX_MODE);
if (ret < 0)
pr_err("%s: CMD Format block" \
"failed: %d\n", __func__, ret);
@@ -500,6 +530,13 @@
prtd->pcm_irq_pos = 0;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ if (!msm_compr_capture_codecs(
+ compr->info.codec_param.codec.id)) {
+ /*request codec invalid or not supported,
+ use default compress format*/
+ compr->info.codec_param.codec.id =
+ SND_AUDIOCODEC_AMRWB;
+ }
switch (compr->info.codec_param.codec.id) {
case SND_AUDIOCODEC_AMRWB:
break;
@@ -834,6 +871,13 @@
pr_err("%s: Send SoftVolume Param failed ret=%d\n",
__func__, ret);
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ if (!msm_compr_capture_codecs(
+ compr->info.codec_param.codec.id)) {
+ /*request codec invalid or not supported,
+ use default compress format*/
+ compr->info.codec_param.codec.id =
+ SND_AUDIOCODEC_AMRWB;
+ }
switch (compr->info.codec_param.codec.id) {
case SND_AUDIOCODEC_AMRWB:
pr_debug("q6asm_open_read(FORMAT_AMRWB)\n");
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 79f0a97..55d50ed 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -372,9 +372,11 @@
COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
prtd->compr_cap.max_fragments =
COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
- prtd->compr_cap.num_codecs = 2;
+ prtd->compr_cap.num_codecs = 4;
prtd->compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
prtd->compr_cap.codecs[1] = SND_AUDIOCODEC_AAC;
+ prtd->compr_cap.codecs[2] = SND_AUDIOCODEC_AC3;
+ prtd->compr_cap.codecs[3] = SND_AUDIOCODEC_EAC3;
}
static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
@@ -400,6 +402,10 @@
if (ret < 0)
pr_err("%s: CMD Format block failed\n", __func__);
break;
+ case FORMAT_AC3:
+ break;
+ case FORMAT_EAC3:
+ break;
default:
pr_debug("%s, unsupported format, skip", __func__);
break;
@@ -685,6 +691,16 @@
break;
}
+ case SND_AUDIOCODEC_AC3: {
+ prtd->codec = FORMAT_AC3;
+ break;
+ }
+
+ case SND_AUDIOCODEC_EAC3: {
+ prtd->codec = FORMAT_EAC3;
+ break;
+ }
+
default:
pr_err("codec not supported, id =%d\n", params->codec.id);
return -EINVAL;
@@ -1226,6 +1242,10 @@
(SND_AUDIOSTREAMFORMAT_MP4ADTS |
SND_AUDIOSTREAMFORMAT_RAW);
break;
+ case SND_AUDIOCODEC_AC3:
+ break;
+ case SND_AUDIOCODEC_EAC3:
+ break;
default:
pr_err("%s: Unsupported audio codec %d\n",
__func__, codec->codec);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index 0612805..d80ca19 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -40,8 +40,8 @@
#define MIN_CAPTURE_PERIOD_SIZE (128 * 2 * 4)
#define MAX_CAPTURE_PERIOD_SIZE (128 * 2 * 2 * 6 * 4)
-#define MIN_CAPTURE_NUM_PERIODS (32 * 4)
-#define MAX_CAPTURE_NUM_PERIODS (384 * 4)
+#define MIN_CAPTURE_NUM_PERIODS (32)
+#define MAX_CAPTURE_NUM_PERIODS (384)
static struct snd_pcm_hardware msm_afe_hardware_playback = {
.info = (SNDRV_PCM_INFO_MMAP |
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 1b4fae9..121c2ea 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1933,6 +1933,31 @@
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new mmul8_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+
static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -2938,6 +2963,7 @@
SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
@@ -3114,6 +3140,8 @@
mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)),
SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0,
mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)),
+ SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0,
+ mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)),
SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -3300,11 +3328,15 @@
{"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"},
{"MultiMedia4 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"},
+ {"MultiMedia8 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"},
{"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
{"MultiMedia4 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
+ {"MultiMedia8 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
{"MultiMedia1 Mixer", "SLIM_4_TX", "SLIMBUS_4_TX"},
{"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
@@ -3398,18 +3430,22 @@
{"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MultiMedia4 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MM_UL1", NULL, "MultiMedia1 Mixer"},
{"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MM_UL2", NULL, "MultiMedia2 Mixer"},
{"MM_UL4", NULL, "MultiMedia4 Mixer"},
{"MM_UL5", NULL, "MultiMedia5 Mixer"},
+ {"MM_UL8", NULL, "MultiMedia8 Mixer"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},