Commit 0af367c0 authored by Arun Gopalakrishnan's avatar Arun Gopalakrishnan Committed by Hari Kanigeri

ARM OMAP4 Syslink IPC Multiproc

This patch can be used to synk with the syslink drop 2.0.0.6
for multiproc module
The major changes are
1. The atomic function usage came in the above modules
2. Some logical changes came in some of the fuinctions
3. The ioctl interface modified to sync with syslink
Signed-off-by: default avatarArun M G <arunmg@ti.com>
parent 9d914d8c
/* /*
* multiproc.h * multiproc.h
* *
* Many multi-processor modules have the concept of processor id. MultiProc * Many multi-processor modules have the concept of processor id. multiproc
* centeralizes the processor id management. * centeralizes the processor id management.
* *
* Copyright (C) 2008-2009 Texas Instruments, Inc. * Copyright (C) 2008-2009 Texas Instruments, Inc.
...@@ -21,6 +21,11 @@ ...@@ -21,6 +21,11 @@
#include <linux/types.h> #include <linux/types.h>
/*
* Unique module ID
*/
#define MULTIPROC_MODULEID (u16)0xB522
/* Macro to define invalid processor id */ /* Macro to define invalid processor id */
#define MULTIPROC_INVALIDID ((u16)0xFFFF) #define MULTIPROC_INVALIDID ((u16)0xFFFF)
...@@ -30,11 +35,37 @@ ...@@ -30,11 +35,37 @@
*/ */
#define MULTIPROC_MAXPROCESSORS 4 #define MULTIPROC_MAXPROCESSORS 4
/*
* Max name length for a processor name
*/
#define MULTIPROC_MAXNAMELENGTH 32
/*
* Configuration structure for multiproc module
*/
struct multiproc_config {
s32 max_processors; /* Max number of procs for particular system */
char name_list[MULTIPROC_MAXPROCESSORS][MULTIPROC_MAXNAMELENGTH];
/* Name List for processors in the system */
u16 id; /* Local Proc ID. This needs to be set before calling any
other APIs */
};
/* ============================================================================= /* =============================================================================
* APIs * APIs
* ============================================================================= * =============================================================================
*/ */
/* Function to set Local processor Id */
/* Function to get the default configuration for the multiproc module. */
void multiproc_get_config(struct multiproc_config *cfg);
/* Function to setup the multiproc Module */
s32 multiproc_setup(struct multiproc_config *cfg);
/* Function to destroy the multiproc module */
s32 multiproc_destroy(void);
/* Function to set local processor Id */
int multiproc_set_local_id(u16 proc_id); int multiproc_set_local_id(u16 proc_id);
/* Function to get processor id from processor name. */ /* Function to get processor id from processor name. */
......
...@@ -25,56 +25,63 @@ ...@@ -25,56 +25,63 @@
#include <multiproc.h> #include <multiproc.h>
enum CMD_MULTIPROC { enum CMD_MULTIPROC {
MULTIPROC_GETID = MULTIPROC_BASE_CMD, MULTIPROC_SETUP = MULTIPROC_BASE_CMD,
MULTIPROC_GETNAME, MULTIPROC_DESTROY,
MULTIPROC_GETMAXID, MULTIPROC_GETCONFIG,
MULTIPROC_SETLOCALID
}; };
/* ----------------------------------------------------------------------------
* IOCTL command IDs for MultiProc
* ----------------------------------------------------------------------------
*/
/* /*
* Command for multiproc_get_id * Command for multiproc_setup
*/ */
#define CMD_MULTIPROC_GETID _IOWR(IPC_IOC_MAGIC, MULTIPROC_GETID, \ #define CMD_MULTIPROC_SETUP _IOWR(IPC_IOC_MAGIC, MULTIPROC_SETUP, \
struct multiproc_cmd_args) struct multiproc_cmd_args)
/* /*
* Command for multiproc_get_name * Command for multiproc_destroy
*/ */
#define CMD_MULTIPROC_GETNAME _IOWR(IPC_IOC_MAGIC, MULTIPROC_GETNAME, \ #define CMD_MULTIPROC_DESTROY _IOWR(IPC_IOC_MAGIC, MULTIPROC_DESTROY, \
struct multiproc_cmd_args) struct multiproc_cmd_args)
/* /*
* Command for multiproc_get_max_processors * Command for multiproc_get_config
*/ */
#define CMD_MULTIPROC_GETMAXID _IOWR(IPC_IOC_MAGIC, MULTIPROC_GETMAXID, \ #define CMD_MULTIPROC_GETCONFIG _IOWR(IPC_IOC_MAGIC, MULTIPROC_GETCONFIG, \
struct multiproc_cmd_args) struct multiproc_cmd_args)
/*
* Command for multiproc_set_local_id
*/
#define CMD_MULTIPROC_SETLOCALID _IOWR(IPC_IOC_MAGIC, MULTIPROC_SETLOCALID, \
struct multiproc_cmd_args)
/* /*
* Command arguments for multiproc * Command arguments for multiproc
*/ */
union multiproc_arg { union multiproc_arg {
struct { struct {
u16 *proc_id; struct multiproc_config *config;
char *name; } get_config;
u32 name_len;
} get_id;
struct { struct {
u16 proc_id; struct multiproc_config *config;
char *name; } setup;
} get_name;
struct { struct {
u16 *max_id; u16 id;
} get_max_id; } set_local_id;
}; };
/* /*
* Command arguments for multiproc * Command arguments for multiproc
*/ */
struct multiproc_cmd_args { struct multiproc_cmd_args {
union multiproc_arg cmd_arg; union multiproc_arg args;
s32 api_status; s32 api_status;
}; };
......
...@@ -26,36 +26,112 @@ ...@@ -26,36 +26,112 @@
/* Standard headers */ /* Standard headers */
#include <linux/types.h> #include <linux/types.h>
#include <linux/module.h> #include <linux/module.h>
#include <syslink/atomic_linux.h>
/* Utilities headers */ /* Utilities headers */
#include <linux/string.h> #include <linux/string.h>
/* Module level headers */ /* Module level headers */
#include <multiproc.h> #include <multiproc.h>
#define MULTIPROC_MAXPROCESSORS 4 /* Macro to make a correct module magic number with ref_count */
#define MULTIPROC_MAKE_MAGICSTAMP(x) ((MULTIPROC_MODULEID << 12u) | (x))
/* /*
* Local processor's id. It has to be set before any module init. * multiproc module state object
*/ */
struct multiproc_module_object { struct multiproc_module_object {
u16 local_id; struct multiproc_config cfg; /* Module configuration structure */
struct multiproc_config def_cfg; /* Default module configuration */
atomic_t ref_count; /* Reference count */
}; };
/* TDO:Add these back to the StateObject and configure them during Driver static struct multiproc_module_object multiproc_state;
* bootup using a Module_Init function.
/*
* ======== multiproc_get_config ========
* Purpose:
* This will get the default configuration for the multiproc module
*/
void multiproc_get_config(struct multiproc_config *cfg)
{
BUG_ON(cfg == NULL);
if (atomic_cmpmask_and_lt(
&(multiproc_state.ref_count),
MULTIPROC_MAKE_MAGICSTAMP(0),
MULTIPROC_MAKE_MAGICSTAMP(1)) == true) {
/* (If setup has not yet been called) */
memcpy(cfg, &multiproc_state.def_cfg,
sizeof(struct multiproc_config));
} else {
memcpy(cfg, &multiproc_state.cfg,
sizeof(struct multiproc_config));
}
}
EXPORT_SYMBOL(multiproc_get_config);
/*
* ======== multiproc_setup ========
* Purpose:
* This function sets up the multiproc module. This function
* must be called before any other instance-level APIs can be
* invoked
*/
s32 multiproc_setup(struct multiproc_config *cfg)
{
s32 status = 0;
struct multiproc_config tmp_cfg;
/* This sets the ref_count variable is not initialized, upper 16 bits is
* written with module Id to ensure correctness of ref_count variable.
*/ */
static char modena[32] = "MPU"; atomic_cmpmask_and_set(&multiproc_state.ref_count,
static char tesla[32] = "Tesla"; MULTIPROC_MAKE_MAGICSTAMP(0),
static char sysm3[32] = "SysM3"; MULTIPROC_MAKE_MAGICSTAMP(0));
static char appm3[32] = "AppM3";
static struct multiproc_module_object multiproc_local_state if (atomic_inc_return(&multiproc_state.ref_count)
= { MULTIPROC_INVALIDID }; != MULTIPROC_MAKE_MAGICSTAMP(1u)) {
static struct multiproc_module_object *module = &multiproc_local_state; status = -EEXIST;
static char *multiproc_namelist[] = { modena, tesla, sysm3, appm3 }; } else {
if (cfg == NULL) {
multiproc_get_config(&tmp_cfg);
cfg = &tmp_cfg;
}
memcpy(&multiproc_state.cfg, cfg,
sizeof(struct multiproc_config));
}
return status;
}
EXPORT_SYMBOL(multiproc_setup);
/*
* ======== multiproc_setup ========
* Purpose:
* This function destroy the multiproc module.
* Once this function is called, other multiproc module APIs,
* except for the multiproc_get_config API cannot be called
* anymore.
*/
s32 multiproc_destroy(void)
{
int status = 0;
if (atomic_cmpmask_and_lt(
&(multiproc_state.ref_count),
MULTIPROC_MAKE_MAGICSTAMP(0),
MULTIPROC_MAKE_MAGICSTAMP(1)) == true) {
status = -ENODEV;
goto exit;
}
atomic_dec_return(&multiproc_state.ref_count);
exit:
return status;
}
EXPORT_SYMBOL(multiproc_destroy);
/* /*
* ======== multiProc_set_local_id ======== * ======== multiProc_set_local_id ========
...@@ -66,17 +142,28 @@ int multiproc_set_local_id(u16 proc_id) ...@@ -66,17 +142,28 @@ int multiproc_set_local_id(u16 proc_id)
{ {
int status = 0; int status = 0;
if (proc_id >= MULTIPROC_MAXPROCESSORS) if (WARN_ON(atomic_cmpmask_and_lt(
&(multiproc_state.ref_count),
MULTIPROC_MAKE_MAGICSTAMP(0),
MULTIPROC_MAKE_MAGICSTAMP(1)) == true)) {
status = -ENODEV;
goto exit;
}
if (WARN_ON(proc_id >= MULTIPROC_MAXPROCESSORS)) {
status = -EINVAL; status = -EINVAL;
else goto exit;
module->local_id = proc_id; }
multiproc_state.cfg.id = proc_id;
exit:
return status; return status;
} }
EXPORT_SYMBOL(multiproc_set_local_id); EXPORT_SYMBOL(multiproc_set_local_id);
/* /*
* ======== multiProc_set_local_id ======== * ======== multiProc_get_local_id ========
* Purpose: * Purpose:
* This will get the processor id from proccessor name * This will get the processor id from proccessor name
*/ */
...@@ -85,19 +172,26 @@ u16 multiproc_get_id(const char *proc_name) ...@@ -85,19 +172,26 @@ u16 multiproc_get_id(const char *proc_name)
s32 i; s32 i;
u16 proc_id = MULTIPROC_INVALIDID; u16 proc_id = MULTIPROC_INVALIDID;
if (WARN_ON(atomic_cmpmask_and_lt(
&(multiproc_state.ref_count),
MULTIPROC_MAKE_MAGICSTAMP(0),
MULTIPROC_MAKE_MAGICSTAMP(1)) == true))
goto exit;
/* If the name is NULL, just return the local id */ /* If the name is NULL, just return the local id */
if (proc_name == NULL) { if (proc_name == NULL)
proc_id = module->local_id; proc_id = multiproc_state.cfg.id;
} else { else {
for (i = 0; i < MULTIPROC_MAXPROCESSORS; i++) { for (i = 0; i < multiproc_state.cfg.max_processors ; i++) {
if ((multiproc_namelist[i] != NULL) && if (strcmp(proc_name,
(strcmp(proc_name, &multiproc_state.cfg.name_list[i][0]) == 0) {
multiproc_namelist[i]) == 0)) {
proc_id = i; proc_id = i;
break; break;
} }
} }
} }
exit:
return proc_id; return proc_id;
} }
EXPORT_SYMBOL(multiproc_get_id); EXPORT_SYMBOL(multiproc_get_id);
...@@ -111,12 +205,19 @@ char *multiproc_get_name(u16 proc_id) ...@@ -111,12 +205,19 @@ char *multiproc_get_name(u16 proc_id)
{ {
char *proc_name = NULL; char *proc_name = NULL;
if (proc_id >= MULTIPROC_MAXPROCESSORS) /* On error condition return NULL pointer, else entry from name list */
goto end; if (WARN_ON(atomic_cmpmask_and_lt(
&(multiproc_state.ref_count),
MULTIPROC_MAKE_MAGICSTAMP(0),
MULTIPROC_MAKE_MAGICSTAMP(1)) == true))
goto exit;
if (WARN_ON(proc_id >= MULTIPROC_MAXPROCESSORS))
goto exit;
proc_name = multiproc_namelist[proc_id]; proc_name = multiproc_state.cfg.name_list[proc_id];
end: exit:
return proc_name; return proc_name;
} }
EXPORT_SYMBOL(multiproc_get_name); EXPORT_SYMBOL(multiproc_get_name);
...@@ -128,7 +229,8 @@ EXPORT_SYMBOL(multiproc_get_name); ...@@ -128,7 +229,8 @@ EXPORT_SYMBOL(multiproc_get_name);
*/ */
u16 multiproc_get_max_processors(void) u16 multiproc_get_max_processors(void)
{ {
u16 proc_id = MULTIPROC_MAXPROCESSORS; return multiproc_state.cfg.max_processors;
return proc_id;
} }
EXPORT_SYMBOL(multiproc_get_max_processors); EXPORT_SYMBOL(multiproc_get_max_processors);
...@@ -18,135 +18,74 @@ ...@@ -18,135 +18,74 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/mm.h>
#include <gt.h>
#include <multiproc.h> #include <multiproc.h>
#include <multiproc_ioctl.h> #include <multiproc_ioctl.h>
/* /*
* ======== mproc_ioctl_get_id ======== * ======== mproc_ioctl_setup ========
* Purpose: * Purpose:
* This wrapper function will call the multproc function * This wrapper function will call the multproc function
* to get proccesor Id from proccessor name * to setup the module
*/ */
static int mproc_ioctl_get_id(struct multiproc_cmd_args *args) static int mproc_ioctl_setup(struct multiproc_cmd_args *cargs)
{ {
struct multiproc_cmd_args uarg; struct multiproc_config config;
struct multiproc_cmd_args *cargs = &uarg; s32 status = 0;
char *name = NULL; ulong size;
s32 retval = 0;
ulong size = 0;
u16 proc_id;
size = copy_from_user(cargs, args,
sizeof(struct multiproc_cmd_args));
if (size) {
retval = -EFAULT;
goto exit;
}
name = kmalloc(cargs->cmd_arg.get_id.name_len, GFP_KERNEL);
if (name == NULL) {
retval = -ENOMEM;
goto exit;
}
size = copy_from_user(name, cargs->cmd_arg.get_id.name, size = copy_from_user(&config,
cargs->cmd_arg.get_id.name_len); cargs->args.setup.config,
/* Handle partial copy */ sizeof(struct multiproc_config));
if (size) {
retval = -EFAULT;
goto name_from_usr_error;
}
proc_id = multiproc_get_id(name);
size = copy_to_user(cargs->cmd_arg.get_id.proc_id,
&proc_id, sizeof(u16));
if (size) { if (size) {
retval = -EFAULT; status = -EFAULT;
goto proc_id_to_usr_error; goto exit;
} }
kfree(name); cargs->api_status = multiproc_setup(&config);
return 0;
proc_id_to_usr_error: /* Fall through */
name_from_usr_error:
kfree(name);
exit: exit:
return retval; return status;
} }
/* /*
* ======== mproc_ioctl_get_name ======== * ======== mproc_ioctl_destroy ========
* Purpose: * Purpose:
* This wrapper function will call the multproc function * This wrapper function will call the multproc function
* to get get name from processor id * to destroy the module
*/ */
static int mproc_ioctl_get_name(struct multiproc_cmd_args *args) static int mproc_ioctl_destroy(struct multiproc_cmd_args *cargs)
{ {
struct multiproc_cmd_args uarg; cargs->api_status = multiproc_destroy();
struct multiproc_cmd_args *cargs = &uarg;
s32 retval = 0;
char *name = NULL;
ulong size = 0;
size = copy_from_user(cargs, args,
sizeof(struct multiproc_cmd_args));
if (size) {
retval = -EFAULT;
goto exit;
}
name = multiproc_get_name(cargs->cmd_arg.get_name.proc_id);
size = copy_to_user(cargs->cmd_arg.get_name.name, name,
strlen(name));
/* Handle partial copy */
if (size) {
retval = -EFAULT;
goto exit;
}
return 0; return 0;
exit:
return retval;
} }
/* ======== mproc_ioctl_get_max_processors ======== /*
* ======== mproc_ioctl_get_config ========
* Purpose: * Purpose:
* This wrapper function will call the multproc function * This wrapper function will call the multproc function
* to get maximum proc Id in the system. * to get the default configuration the module
*/ */
static int mproc_ioctl_get_max_processors(struct multiproc_cmd_args *args) static int mproc_ioctl_get_config(struct multiproc_cmd_args *cargs)
{ {
struct multiproc_cmd_args uarg; struct multiproc_config config;
struct multiproc_cmd_args *cargs = &uarg;
u16 max_id;
s32 size = 0;
s32 retval = 0;
size = copy_from_user(cargs, args, multiproc_get_config(&config);
sizeof(struct multiproc_cmd_args)); cargs->api_status = 0;
if (size) { return 0;
retval = -EFAULT;
goto exit;
}
max_id = multiproc_get_max_processors();
size = copy_to_user(cargs->cmd_arg.get_max_id.max_id,
&max_id, sizeof(u16));
if (size) {
retval = -EFAULT;
goto exit;
}
exit:
return retval;
} }
/*
* ======== mproc_ioctl_setup ========
* Purpose:
* This wrapper function will call the multproc function
* to setup the module
*/
static int multiproc_ioctl_set_local_id(struct multiproc_cmd_args *cargs)
{
cargs->api_status = multiproc_set_local_id(cargs->args.set_local_id.id);
return 0;
}
/* /*
* ======== multiproc_ioctl ======== * ======== multiproc_ioctl ========
...@@ -156,43 +95,63 @@ exit: ...@@ -156,43 +95,63 @@ exit:
int multiproc_ioctl(struct inode *inode, struct file *filp, int multiproc_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long args) unsigned int cmd, unsigned long args)
{ {
s32 status = 0;
s32 size = 0;
struct multiproc_cmd_args __user *uarg = struct multiproc_cmd_args __user *uarg =
(struct multiproc_cmd_args __user *)args; (struct multiproc_cmd_args __user *)args;
s32 retval = 0; struct multiproc_cmd_args cargs;
gt_4trace(curTrace, GT_ENTER, "multiproc_ioctl"
"inode: %x, filp: %x,\n cmd: %x, args: %x",
inode, filp, cmd, args);
if (_IOC_DIR(cmd) & _IOC_READ) if (_IOC_DIR(cmd) & _IOC_READ)
retval = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE) else if (_IOC_DIR(cmd) & _IOC_WRITE)
retval = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd));
if (status) {
status = -EFAULT;
goto exit;
}
if (retval) { /* Copy the full args from user-side */
retval = -EFAULT; size = copy_from_user(&cargs, uarg,
sizeof(struct multiproc_cmd_args));
if (size) {
status = -EFAULT;
goto exit; goto exit;
} }
switch (cmd) { switch (cmd) {
case CMD_MULTIPROC_GETID: case CMD_MULTIPROC_SETUP:
retval = mproc_ioctl_get_id(uarg); status = mproc_ioctl_setup(uarg);
break; break;
case CMD_MULTIPROC_GETNAME: case CMD_MULTIPROC_DESTROY:
retval = mproc_ioctl_get_name(uarg); status = mproc_ioctl_destroy(uarg);
break; break;
case CMD_MULTIPROC_GETMAXID: case CMD_MULTIPROC_GETCONFIG:
retval = mproc_ioctl_get_max_processors(uarg); status = mproc_ioctl_get_config(uarg);
break;
case CMD_MULTIPROC_SETLOCALID:
status = multiproc_ioctl_set_local_id(uarg);
break; break;
default: default:
WARN_ON(cmd); WARN_ON(cmd);
retval = -ENOTTY; status = -ENOTTY;
break; break;
} }
/* Copy the full args to the user-side. */
size = copy_to_user(uarg, &cargs, sizeof(struct multiproc_cmd_args));
if (size) {
status = -EFAULT;
goto exit;
}
exit: exit:
return retval; return status;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment