From: John Jacques <john.jacq...@intel.com>

Signed-off-by: John Jacques <john.jacq...@intel.com>
---
 drivers/misc/axxia-oem.c  | 207 ++++++++++++++++++++++++++++++++++++++++------
 include/linux/axxia-oem.h |  10 +++
 2 files changed, 190 insertions(+), 27 deletions(-)

diff --git a/drivers/misc/axxia-oem.c b/drivers/misc/axxia-oem.c
index e7436dd..5f787cd 100644
--- a/drivers/misc/axxia-oem.c
+++ b/drivers/misc/axxia-oem.c
@@ -90,11 +90,8 @@ axxia_dspc_write(struct file *file, const char __user 
*buffer,
                 size_t count, loff_t *ppos)
 {
        char *input;
-       unsigned long mask;
-       int ret;
 
        input = kmalloc(count, __GFP_RECLAIMABLE);
-       memset(input, 0, count);
 
        if (NULL == input)
                return -ENOSPC;
@@ -102,13 +99,10 @@ axxia_dspc_write(struct file *file, const char __user 
*buffer,
        if (copy_from_user(input, buffer, count))
                return -EFAULT;
 
-       ret = kstrtoul(input, 0, &mask);
-       if (ret) {
-               pr_err("Failed axxia_dspc_write mask conversion\n");
-               return -EFAULT;
-       }
+       input[count] = 0;
+
+       axxia_dspc_set_state(simple_strtoul(input, NULL, 0));
 
-       axxia_dspc_set_state((unsigned int)mask);
        return count;
 }
 
@@ -149,11 +143,8 @@ axxia_actlr_el3_write(struct file *file, const char __user 
*buffer,
                      size_t count, loff_t *ppos)
 {
        char *input;
-       unsigned long data = 0;
-       int ret = 0;
 
        input = kmalloc(count, __GFP_RECLAIMABLE);
-       memset(input, 0, count);
 
        if (NULL == input)
                return -ENOSPC;
@@ -161,12 +152,9 @@ axxia_actlr_el3_write(struct file *file, const char __user 
*buffer,
        if (copy_from_user(input, buffer, count))
                return -EFAULT;
 
-       ret = kstrtoul(input, 0, &data);
-       if (ret) {
-               pr_err("axxia_actlr_el3_write failed conversion\n");
-               return ret;
-       }
-       axxia_actlr_el3_set(data);
+       input[count] = 0;
+
+       axxia_actlr_el3_set(simple_strtoul(input, NULL, 0));
 
        return count;
 }
@@ -208,11 +196,8 @@ axxia_actlr_el2_write(struct file *file, const char __user 
*buffer,
                      size_t count, loff_t *ppos)
 {
        char *input;
-       unsigned long data = 0;
-       int ret = 0;
 
        input = kmalloc(count, __GFP_RECLAIMABLE);
-       memset(input, 0, count);
 
        if (NULL == input)
                return -ENOSPC;
@@ -220,12 +205,9 @@ axxia_actlr_el2_write(struct file *file, const char __user 
*buffer,
        if (copy_from_user(input, buffer, count))
                return -EFAULT;
 
-       ret = kstrtoul(input, 0, &data);
-       if (ret) {
-               pr_err("axxia_actlr_el2_write failed conversion\n");
-               return ret;
-       }
-       axxia_actlr_el2_set(data);
+       input[count] = 0;
+
+       axxia_actlr_el2_set(simple_strtoul(input, NULL, 0));
 
        return count;
 }
@@ -237,6 +219,123 @@ static const struct file_operations 
axxia_actlr_el2_proc_ops = {
 };
 
 /*
+  CCN Access
+*/
+
+static unsigned long ccn_offset;
+
+static ssize_t
+axxia_ccn_offset_read(struct file *filp, char *buffer, size_t length,
+                     loff_t *offset)
+{
+       static int finished;
+       char return_buffer[80];
+
+       if (0 != finished) {
+               finished = 0;
+
+               return 0;
+       }
+
+       finished = 1;
+       sprintf(return_buffer, "0x%lx\n", ccn_offset);
+
+       if (copy_to_user(buffer, return_buffer, strlen(return_buffer)))
+               return -EFAULT;
+
+       return strlen(return_buffer);
+}
+
+static ssize_t
+axxia_ccn_offset_write(struct file *file, const char __user *buffer,
+                      size_t count, loff_t *ppos)
+{
+       char *input;
+       unsigned int new_ccn_offset;
+
+       input = kmalloc(count, __GFP_RECLAIMABLE);
+
+       if (NULL == input)
+               return -ENOSPC;
+
+       if (copy_from_user(input, buffer, count))
+               return -EFAULT;
+
+       input[count] = 0;
+
+       new_ccn_offset = (unsigned int)simple_strtoul(input, NULL, 0);
+
+       if (of_find_compatible_node(NULL, NULL, "axxia,axc6732")) {
+               if (0x9cff00 < new_ccn_offset)
+                       pr_err("Invalid CCN Offset!\n");
+       } else if (of_find_compatible_node(NULL, NULL, "axxia,axm5616")) {
+               if (0x94ff00 < new_ccn_offset)
+                       pr_err("Invalid CCN Offset!\n");
+       } else {
+               pr_err("Internal Error!\n");
+       }
+
+       ccn_offset = (unsigned int)new_ccn_offset;
+
+       return count;
+}
+
+static const struct file_operations axxia_ccn_offset_proc_ops = {
+       .read       = axxia_ccn_offset_read,
+       .write      = axxia_ccn_offset_write,
+       .llseek     = noop_llseek,
+};
+
+static ssize_t
+axxia_ccn_value_read(struct file *filp, char *buffer, size_t length,
+                    loff_t *offset)
+{
+       static int finished;
+       char return_buffer[80];
+
+       if (0 != finished) {
+               finished = 0;
+
+               return 0;
+       }
+
+       finished = 1;
+       sprintf(return_buffer, "0x%lx\n", axxia_ccn_get(ccn_offset));
+
+       if (copy_to_user(buffer, return_buffer, strlen(return_buffer)))
+               return -EFAULT;
+
+       return strlen(return_buffer);
+}
+
+static ssize_t
+axxia_ccn_value_write(struct file *file, const char __user *buffer,
+                      size_t count, loff_t *ppos)
+{
+       char *input;
+
+       input = kmalloc(count, __GFP_RECLAIMABLE);
+
+       if (NULL == input)
+               return -ENOSPC;
+
+       if (copy_from_user(input, buffer, count))
+               return -EFAULT;
+
+       input[count] = 0;
+
+       axxia_ccn_set(ccn_offset, simple_strtoul(input, NULL, 0));
+
+       return count;
+}
+
+static const struct file_operations axxia_ccn_value_proc_ops = {
+       .read       = axxia_ccn_value_read,
+       .write      = axxia_ccn_value_write,
+       .llseek     = noop_llseek,
+};
+
+/*
   
==============================================================================
   
==============================================================================
   Public
@@ -374,6 +473,47 @@ EXPORT_SYMBOL(axxia_actlr_el2_set);
 
 /*
   
------------------------------------------------------------------------------
+  axxia_ccn_get
+*/
+
+unsigned long
+axxia_ccn_get(unsigned int offset)
+{
+       struct oem_parameters parameters;
+
+       parameters.reg0 = 0xc3000006;
+       parameters.reg1 = offset;
+       invoke_oem_fn(&parameters);
+
+       if (0 != parameters.reg0)
+               pr_warn("Getting CCN Register Failed!\n");
+
+       return parameters.reg1;
+}
+EXPORT_SYMBOL(axxia_ccn_get);
+
+/*
+  
------------------------------------------------------------------------------
+  axxia_ccn_set
+*/
+
+void
+axxia_ccn_set(unsigned int offset, unsigned long value)
+{
+       struct oem_parameters parameters;
+
+       parameters.reg0 = 0xc3000007;
+       parameters.reg1 = offset;
+       parameters.reg2 = value;
+       invoke_oem_fn(&parameters);
+
+       if (0 != parameters.reg0)
+               pr_warn("Getting CCN Register Failed!\n");
+}
+EXPORT_SYMBOL(axxia_ccn_set);
+
+/*
+  
------------------------------------------------------------------------------
   axxia_dspc_init
 */
 
@@ -401,6 +541,19 @@ axxia_oem_init(void)
        else
                pr_info("Axxia ACTLR_EL3 Control Initialized\n");
 
+       /* For CCN access, create two files, offset and value. */
+
+       ccn_offset = 0;
+
+       if (NULL == proc_create("driver/axxia_ccn_offset", S_IWUSR, NULL,
+                               &axxia_ccn_offset_proc_ops))
+               pr_err("Could not create /proc/driver/axxia_ccn_offset!\n");
+       else if (NULL == proc_create("driver/axxia_ccn_value", S_IWUSR, NULL,
+                                    &axxia_ccn_value_proc_ops))
+               pr_err("Could not create /proc/driver/axxia_ccn_value!\n");
+       else
+               pr_info("Axxia CCN Initialized\n");
+
        return 0;
 }
 
diff --git a/include/linux/axxia-oem.h b/include/linux/axxia-oem.h
index b3721a8..101cf71 100644
--- a/include/linux/axxia-oem.h
+++ b/include/linux/axxia-oem.h
@@ -31,4 +31,14 @@ void axxia_actlr_el3_set(unsigned long);
 unsigned long axxia_actlr_el2_get(void);
 void axxia_actlr_el2_set(unsigned long);
 
+/*
+  CCN504 (5600)
+  CCN512 (6700)
+
+  64 bit registers.
+*/
+
+unsigned long axxia_ccn_get(unsigned int);
+void axxia_ccn_set(unsigned int, unsigned long);
+
 #endif /* __DRIVERS_MISC_AXXIA_DSPC_H */
-- 
2.7.4

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to