summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/qcom/Kconfig10
-rw-r--r--drivers/soc/qcom/Makefile1
-rw-r--r--drivers/soc/qcom/scm.c102
-rw-r--r--drivers/soc/qcom/shenqi_nv.c195
4 files changed, 247 insertions, 61 deletions
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 81db4fe93dbc..6bb3162bf13c 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -178,16 +178,6 @@ config MSM_SMP2P
32-bit values by specifying a unique string and
remote processor ID.
-config MSM_SMP2P_TEST
- bool "SMSM Point-to-Point Test"
- depends on MSM_SMP2P
- help
- Enables loopback and unit testing support for
- SMP2P. Loopback support is used by other
- processors to do unit testing. Unit tests
- are used to verify the local and remote
- implementations.
-
config MSM_QMI_INTERFACE
depends on IPC_ROUTER
depends on QMI_ENCDEC
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 12482ee2aa79..b421fd71a7b1 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -113,3 +113,4 @@ obj-$(CONFIG_MSM_CACHE_M4M_ERP64) += cache_m4m_erp64.o
obj-$(CONFIG_MSM_HAB) += hab/
obj-$(CONFIG_QCOM_QDSS_BRIDGE) += qdss_bridge.o
obj-$(CONFIG_MFSE_QMI) += mfse_qmi_v01.o mfse_qmi.o
+obj-y += shenqi_nv.o
diff --git a/drivers/soc/qcom/scm.c b/drivers/soc/qcom/scm.c
index f4125113efff..96a2f962734f 100644
--- a/drivers/soc/qcom/scm.c
+++ b/drivers/soc/qcom/scm.c
@@ -194,9 +194,9 @@ static int scm_remap_error(int err)
static u32 smc(u32 cmd_addr)
{
int context_id;
- register u32 r0 asm("r0") = 1;
- register u32 r1 asm("r1") = (uintptr_t)&context_id;
- register u32 r2 asm("r2") = cmd_addr;
+ register u32 r0 asm(R0_STR) = 1;
+ register u32 r1 asm(R1_STR) = (uintptr_t)&context_id;
+ register u32 r2 asm(R2_STR) = cmd_addr;
do {
asm volatile(
__asmeq("%0", R0_STR)
@@ -209,7 +209,7 @@ static u32 smc(u32 cmd_addr)
"smc #0\n"
: "=r" (r0)
: "r" (r0), "r" (r1), "r" (r2)
- : "r3");
+ : R3_STR);
} while (r0 == SCM_INTERRUPTED);
return r0;
@@ -382,13 +382,13 @@ int scm_call_noalloc(u32 svc_id, u32 cmd_id, const void *cmd_buf,
static int __scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
u64 *ret1, u64 *ret2, u64 *ret3)
{
- register u64 r0 asm("r0") = x0;
- register u64 r1 asm("r1") = x1;
- register u64 r2 asm("r2") = x2;
- register u64 r3 asm("r3") = x3;
- register u64 r4 asm("r4") = x4;
- register u64 r5 asm("r5") = x5;
- register u64 r6 asm("r6") = 0;
+ register u64 r0 asm("x0") = x0;
+ register u64 r1 asm("x1") = x1;
+ register u64 r2 asm("x2") = x2;
+ register u64 r3 asm("x3") = x3;
+ register u64 r4 asm("x4") = x4;
+ register u64 r5 asm("x5") = x5;
+ register u64 r6 asm("x6") = 0;
do {
asm volatile(
@@ -431,13 +431,13 @@ static int __scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
static int __scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
u64 *ret1, u64 *ret2, u64 *ret3)
{
- register u32 r0 asm("r0") = w0;
- register u32 r1 asm("r1") = w1;
- register u32 r2 asm("r2") = w2;
- register u32 r3 asm("r3") = w3;
- register u32 r4 asm("r4") = w4;
- register u32 r5 asm("r5") = w5;
- register u32 r6 asm("r6") = 0;
+ register u32 r0 asm("w0") = w0;
+ register u32 r1 asm("w1") = w1;
+ register u32 r2 asm("w2") = w2;
+ register u32 r3 asm("w3") = w3;
+ register u32 r4 asm("w4") = w4;
+ register u32 r5 asm("w5") = w5;
+ register u32 r6 asm("w6") = 0;
do {
asm volatile(
@@ -843,9 +843,9 @@ EXPORT_SYMBOL(scm_call);
s32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
{
int context_id;
- register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 1);
- register u32 r1 asm("r1") = (uintptr_t)&context_id;
- register u32 r2 asm("r2") = arg1;
+ register u32 r0 asm(R0_STR) = SCM_ATOMIC(svc, cmd, 1);
+ register u32 r1 asm(R1_STR) = (uintptr_t)&context_id;
+ register u32 r2 asm(R2_STR) = arg1;
asm volatile(
__asmeq("%0", R0_STR)
@@ -858,7 +858,7 @@ s32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
"smc #0\n"
: "=r" (r0)
: "r" (r0), "r" (r1), "r" (r2)
- : "r3");
+ : R3_STR);
return r0;
}
EXPORT_SYMBOL(scm_call_atomic1);
@@ -876,9 +876,9 @@ EXPORT_SYMBOL(scm_call_atomic1);
s32 scm_call_atomic1_1(u32 svc, u32 cmd, u32 arg1, u32 *ret1)
{
int context_id;
- register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 1);
- register u32 r1 asm("r1") = (uintptr_t)&context_id;
- register u32 r2 asm("r2") = arg1;
+ register u32 r0 asm(R0_STR) = SCM_ATOMIC(svc, cmd, 1);
+ register u32 r1 asm(R1_STR) = (uintptr_t)&context_id;
+ register u32 r2 asm(R2_STR) = arg1;
asm volatile(
__asmeq("%0", R0_STR)
@@ -892,7 +892,7 @@ s32 scm_call_atomic1_1(u32 svc, u32 cmd, u32 arg1, u32 *ret1)
"smc #0\n"
: "=r" (r0), "=r" (r1)
: "r" (r0), "r" (r1), "r" (r2)
- : "r3");
+ : R3_STR);
if (ret1)
*ret1 = r1;
return r0;
@@ -912,10 +912,10 @@ EXPORT_SYMBOL(scm_call_atomic1_1);
s32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
{
int context_id;
- register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 2);
- register u32 r1 asm("r1") = (uintptr_t)&context_id;
- register u32 r2 asm("r2") = arg1;
- register u32 r3 asm("r3") = arg2;
+ register u32 r0 asm(R0_STR) = SCM_ATOMIC(svc, cmd, 2);
+ register u32 r1 asm(R1_STR) = (uintptr_t)&context_id;
+ register u32 r2 asm(R2_STR) = arg1;
+ register u32 r3 asm(R3_STR) = arg2;
asm volatile(
__asmeq("%0", R0_STR)
@@ -947,11 +947,11 @@ EXPORT_SYMBOL(scm_call_atomic2);
s32 scm_call_atomic3(u32 svc, u32 cmd, u32 arg1, u32 arg2, u32 arg3)
{
int context_id;
- register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 3);
- register u32 r1 asm("r1") = (uintptr_t)&context_id;
- register u32 r2 asm("r2") = arg1;
- register u32 r3 asm("r3") = arg2;
- register u32 r4 asm("r4") = arg3;
+ register u32 r0 asm(R0_STR) = SCM_ATOMIC(svc, cmd, 3);
+ register u32 r1 asm(R1_STR) = (uintptr_t)&context_id;
+ register u32 r2 asm(R2_STR) = arg1;
+ register u32 r3 asm(R3_STR) = arg2;
+ register u32 r4 asm(R4_STR) = arg3;
asm volatile(
__asmeq("%0", R0_STR)
@@ -975,12 +975,12 @@ s32 scm_call_atomic4_3(u32 svc, u32 cmd, u32 arg1, u32 arg2,
{
int ret;
int context_id;
- register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 4);
- register u32 r1 asm("r1") = (uintptr_t)&context_id;
- register u32 r2 asm("r2") = arg1;
- register u32 r3 asm("r3") = arg2;
- register u32 r4 asm("r4") = arg3;
- register u32 r5 asm("r5") = arg4;
+ register u32 r0 asm(R0_STR) = SCM_ATOMIC(svc, cmd, 4);
+ register u32 r1 asm(R1_STR) = (uintptr_t)&context_id;
+ register u32 r2 asm(R2_STR) = arg1;
+ register u32 r3 asm(R3_STR) = arg2;
+ register u32 r4 asm(R4_STR) = arg3;
+ register u32 r5 asm(R5_STR) = arg4;
asm volatile(
__asmeq("%0", R0_STR)
@@ -1026,13 +1026,13 @@ s32 scm_call_atomic5_3(u32 svc, u32 cmd, u32 arg1, u32 arg2,
{
int ret;
int context_id;
- register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 5);
- register u32 r1 asm("r1") = (uintptr_t)&context_id;
- register u32 r2 asm("r2") = arg1;
- register u32 r3 asm("r3") = arg2;
- register u32 r4 asm("r4") = arg3;
- register u32 r5 asm("r5") = arg4;
- register u32 r6 asm("r6") = arg5;
+ register u32 r0 asm(R0_STR) = SCM_ATOMIC(svc, cmd, 5);
+ register u32 r1 asm(R1_STR) = (uintptr_t)&context_id;
+ register u32 r2 asm(R2_STR) = arg1;
+ register u32 r3 asm(R3_STR) = arg2;
+ register u32 r4 asm(R4_STR) = arg3;
+ register u32 r5 asm(R5_STR) = arg4;
+ register u32 r6 asm(R6_STR) = arg5;
asm volatile(
__asmeq("%0", R0_STR)
@@ -1066,8 +1066,8 @@ u32 scm_get_version(void)
{
int context_id;
static u32 version = -1;
- register u32 r0 asm("r0");
- register u32 r1 asm("r1");
+ register u32 r0 asm(R0_STR);
+ register u32 r1 asm(R1_STR);
if (version != -1)
return version;
@@ -1088,7 +1088,7 @@ u32 scm_get_version(void)
"smc #0\n"
: "=r" (r0), "=r" (r1)
: "r" (r0), "r" (r1)
- : "r2", "r3");
+ : R2_STR, R3_STR);
} while (r0 == SCM_INTERRUPTED);
version = r1;
diff --git a/drivers/soc/qcom/shenqi_nv.c b/drivers/soc/qcom/shenqi_nv.c
new file mode 100644
index 000000000000..596837758db6
--- /dev/null
+++ b/drivers/soc/qcom/shenqi_nv.c
@@ -0,0 +1,195 @@
+/*
+* Based on the work of Tony Sun
+* Zhenglq : Add for Get nv data from modem using SMEM.
+*/
+
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include "smd_private.h"
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+
+#define NV_WIFI_ADDR_SIZE 6
+#define NV_BT_ADDR_SIZE 6
+#define NV_MAX_SIZE 512
+
+struct smem_nv {
+ unsigned char nv_wifi[NV_WIFI_ADDR_SIZE];
+ unsigned char nv_bt[NV_BT_ADDR_SIZE];
+};
+
+static struct smem_nv *psmem_nv = NULL;
+
+static int smem_read_nv(void)
+{
+ struct smem_nv *buf;
+
+ buf = smem_alloc(SMEM_ID_VENDOR_READ_NV, NV_MAX_SIZE,SMEM_APPS, 2);
+ if (!buf) {
+ printk(KERN_ERR "SMEM_ID_VENDOR_READ_NV smem_alloc failed\n");
+ return 1;
+ }
+
+ psmem_nv = kzalloc(sizeof(struct smem_nv), GFP_KERNEL);
+ if (!psmem_nv) {
+ printk(KERN_ERR "++++++++++++++++++++++=malloc psmem_nv fail\n");
+ return 1;
+ }
+
+ memcpy(psmem_nv, buf, sizeof(struct smem_nv));
+
+ return 0;
+}
+
+static long dump_wifi_addr(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ loff_t pos = *f_pos;
+ int ret;
+
+ ret = smem_read_nv();
+ if (ret) {
+ pr_info("%s: smem_read_nv() failed", __func__);
+ return ret;
+ }
+
+ if (!psmem_nv)
+ {
+ printk(KERN_ERR "Could not get smem for wlan mac nv\n");
+ return 0;
+ }
+
+ if (pos >= NV_WIFI_ADDR_SIZE) {
+ count = 0;
+ goto out;
+ }
+
+ if (count > (NV_WIFI_ADDR_SIZE - pos))
+ count = NV_WIFI_ADDR_SIZE - pos;
+
+ pos += count;
+
+ if (copy_to_user(buf, psmem_nv->nv_wifi + *f_pos,count)) {
+ count = -EFAULT;
+ goto out;
+ }
+
+ *f_pos = pos;
+
+out:
+ return count;
+}
+
+int wlan_get_nv_mac(char* buf)
+{
+ int ret;
+
+ ret = smem_read_nv();
+ if (ret) {
+ pr_info("%s: smem_read_nv() failed", __func__);
+ return ret;
+ }
+
+ if (!psmem_nv){
+ printk(KERN_ERR "Could not get smem for wlan mac nv\n");
+ return -1;
+ }
+
+ memcpy(buf, psmem_nv->nv_wifi, NV_WIFI_ADDR_SIZE);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wlan_get_nv_mac);
+
+#define DECLARE_FOPS(name) static const struct file_operations name## _fops = { \
+ .read = name, \
+};
+
+static long dump_bt_addr(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ loff_t pos = *f_pos;
+ size_t len;
+
+ if (!psmem_nv)
+ smem_read_nv();
+
+ if (!psmem_nv) {
+ printk(KERN_ERR "Could not get smem for bt mac nv\n");
+ return 0;
+ }
+
+ len = sizeof(psmem_nv->nv_bt);
+
+ if(pos >= len ) {
+ count = 0;
+ goto out;
+ }
+
+ if(count > (len - pos))
+ count = len - pos;
+
+ pos += count;
+
+ if(copy_to_user(buf,psmem_nv->nv_bt + (*f_pos),count)){
+ count = -EFAULT;
+ goto out;
+ }
+
+ *f_pos = pos;
+
+out:
+ return count;
+}
+
+DECLARE_FOPS(dump_wifi_addr)
+DECLARE_FOPS(dump_bt_addr)
+
+static int show_nv(void)
+{
+ struct proc_dir_entry *wifi_addr_entry;
+ struct proc_dir_entry *bt_addr_entry;
+
+ wifi_addr_entry = proc_create("mac_wifi", 0, NULL, &dump_wifi_addr_fops);
+ bt_addr_entry = proc_create("mac_bt", 0, NULL, &dump_bt_addr_fops);
+
+ if (!wifi_addr_entry) {
+ pr_info("%s: failed to create mac_wifi entry", __func__);
+ remove_proc_entry("mac_wifi", NULL);
+ return 1;
+ }
+
+ if (!bt_addr_entry) {
+ pr_info("%s: failed to create mac_bt entry", __func__);
+ remove_proc_entry("mac_bt", NULL);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int __init shenqi_nv_init(void)
+{
+ int ret = 0;
+ printk("%s(),%d\n" ,__func__, __LINE__);
+
+ ret = show_nv();
+ if (ret) {
+ pr_info("%s: show_nv() failed", __func__);
+ return 0;
+ }
+
+ return 1;
+}
+
+static void __exit shenqi_nv_exit(void)
+{
+ printk("%s(),%d\n", __func__, __LINE__);
+ kfree(psmem_nv);
+ psmem_nv = NULL;
+}
+
+late_initcall(shenqi_nv_init);
+module_exit(shenqi_nv_exit);