Commit 33a77e11 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 472692cd
/*
* 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.
*
* Copyright (C) 2008-2009 Texas Instruments, Inc.
......@@ -21,8 +21,13 @@
#include <linux/types.h>
/*
* Unique module ID
*/
#define MULTIPROC_MODULEID (u16)0xB522
/* Macro to define invalid processor id */
#define MULTIPROC_INVALIDID ((u16)0xFFFF)
#define MULTIPROC_INVALIDID ((u16)0xFFFF)
/*
* Maximum number of processors in the system
......@@ -30,11 +35,37 @@
*/
#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
* =============================================================================
*/
/* 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);
/* Function to get processor id from processor name. */
......
......@@ -25,56 +25,63 @@
#include <multiproc.h>
enum CMD_MULTIPROC {
MULTIPROC_GETID = MULTIPROC_BASE_CMD,
MULTIPROC_GETNAME,
MULTIPROC_GETMAXID,
MULTIPROC_SETUP = MULTIPROC_BASE_CMD,
MULTIPROC_DESTROY,
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)
/*
* 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)
/*
* 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)
/*
* Command for multiproc_set_local_id
*/
#define CMD_MULTIPROC_SETLOCALID _IOWR(IPC_IOC_MAGIC, MULTIPROC_SETLOCALID, \
struct multiproc_cmd_args)
/*
* Command arguments for multiproc
*/
union multiproc_arg {
struct {
u16 *proc_id;
char *name;
u32 name_len;
} get_id;
struct multiproc_config *config;
} get_config;
struct {
u16 proc_id;
char *name;
} get_name;
struct multiproc_config *config;
} setup;
struct {
u16 *max_id;
} get_max_id;
u16 id;
} set_local_id;
};
/*
* Command arguments for multiproc
*/
struct multiproc_cmd_args {
union multiproc_arg cmd_arg;
union multiproc_arg args;
s32 api_status;
};
......
......@@ -26,36 +26,112 @@
/* Standard headers */
#include <linux/types.h>
#include <linux/module.h>
#include <syslink/atomic_linux.h>
/* Utilities headers */
#include <linux/string.h>
/* Module level headers */
#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 {
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
* bootup using a Module_Init function.
static struct multiproc_module_object multiproc_state;
/*
* ======== 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.
*/
atomic_cmpmask_and_set(&multiproc_state.ref_count,
MULTIPROC_MAKE_MAGICSTAMP(0),
MULTIPROC_MAKE_MAGICSTAMP(0));
if (atomic_inc_return(&multiproc_state.ref_count)
!= MULTIPROC_MAKE_MAGICSTAMP(1u)) {
status = -EEXIST;
} 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.
*/
static char modena[32] = "MPU";
static char tesla[32] = "Tesla";
static char sysm3[32] = "SysM3";
static char appm3[32] = "AppM3";
s32 multiproc_destroy(void)
{
int status = 0;
static struct multiproc_module_object multiproc_local_state
= { MULTIPROC_INVALIDID };
static struct multiproc_module_object *module = &multiproc_local_state;
static char *multiproc_namelist[] = { modena, tesla, sysm3, appm3 };
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 ========
......@@ -66,38 +142,56 @@ int multiproc_set_local_id(u16 proc_id)
{
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;
else
module->local_id = proc_id;
goto exit;
}
multiproc_state.cfg.id = proc_id;
exit:
return status;
}
EXPORT_SYMBOL(multiproc_set_local_id);
/*
* ======== multiProc_set_local_id ========
* ======== multiProc_get_local_id ========
* Purpose:
* This will get the processor id from proccessor name
*/
u16 multiproc_get_id(const char *proc_name)
{
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 (proc_name == NULL) {
proc_id = module->local_id;
} else {
for (i = 0; i < MULTIPROC_MAXPROCESSORS; i++) {
if ((multiproc_namelist[i] != NULL) &&
(strcmp(proc_name,
multiproc_namelist[i]) == 0)) {
if (proc_name == NULL)
proc_id = multiproc_state.cfg.id;
else {
for (i = 0; i < multiproc_state.cfg.max_processors ; i++) {
if (strcmp(proc_name,
&multiproc_state.cfg.name_list[i][0]) == 0) {
proc_id = i;
break;
}
}
}
exit:
return proc_id;
}
EXPORT_SYMBOL(multiproc_get_id);
......@@ -111,12 +205,19 @@ char *multiproc_get_name(u16 proc_id)
{
char *proc_name = NULL;
if (proc_id >= MULTIPROC_MAXPROCESSORS)
goto end;
/* On error condition return NULL pointer, else entry from name list */
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;
}
EXPORT_SYMBOL(multiproc_get_name);
......@@ -128,7 +229,8 @@ EXPORT_SYMBOL(multiproc_get_name);
*/
u16 multiproc_get_max_processors(void)
{
u16 proc_id = MULTIPROC_MAXPROCESSORS;
return proc_id;
return multiproc_state.cfg.max_processors;
}
EXPORT_SYMBOL(multiproc_get_max_processors);
......@@ -18,135 +18,74 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <gt.h>
#include <linux/mm.h>
#include <multiproc.h>
#include <multiproc_ioctl.h>
/*
* ======== mproc_ioctl_get_id ========
* ======== mproc_ioctl_setup ========
* Purpose:
* 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_cmd_args *cargs = &uarg;
char *name = NULL;
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;
}
struct multiproc_config config;
s32 status = 0;
ulong size;
size = copy_from_user(name, cargs->cmd_arg.get_id.name,
cargs->cmd_arg.get_id.name_len);
/* Handle partial copy */
size = copy_from_user(&config,
cargs->args.setup.config,
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) {
retval = -EFAULT;
goto proc_id_to_usr_error;
status = -EFAULT;
goto exit;
}
kfree(name);
return 0;
proc_id_to_usr_error: /* Fall through */
name_from_usr_error:
kfree(name);
cargs->api_status = multiproc_setup(&config);
exit:
return retval;
return status;
}
/*
* ======== mproc_ioctl_get_name ========
* Purpose:
* This wrapper function will call the multproc function
* to get get name from processor id
* ======== mproc_ioctl_destroy ========
* Purpose:
* This wrapper function will call the multproc function
* 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;
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;
}
cargs->api_status = multiproc_destroy();
return 0;
exit:
return retval;
}
/* ======== mproc_ioctl_get_max_processors ========
* Purpose:
* This wrapper function will call the multproc function
* to get maximum proc Id in the system.
/*
* ======== mproc_ioctl_get_config ========
* Purpose:
* This wrapper function will call the multproc function
* 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_cmd_args *cargs = &uarg;
u16 max_id;
s32 size = 0;
s32 retval = 0;
size = copy_from_user(cargs, args,
sizeof(struct multiproc_cmd_args));
if (size) {
retval = -EFAULT;
goto exit;
}
struct multiproc_config config;
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;
multiproc_get_config(&config);
cargs->api_status = 0;
return 0;
}
/*
* ======== 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 ========
......@@ -156,43 +95,63 @@ exit:
int multiproc_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long args)
{
s32 status = 0;
s32 size = 0;
struct multiproc_cmd_args __user *uarg =
(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)
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)
retval = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd));
status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd));
if (retval) {
retval = -EFAULT;
if (status) {
status = -EFAULT;
goto exit;
}
/* Copy the full args from user-side */
size = copy_from_user(&cargs, uarg,
sizeof(struct multiproc_cmd_args));
if (size) {
status = -EFAULT;
goto exit;
}
switch (cmd) {
case CMD_MULTIPROC_GETID:
retval = mproc_ioctl_get_id(uarg);
case CMD_MULTIPROC_SETUP:
status = mproc_ioctl_setup(uarg);
break;
case CMD_MULTIPROC_GETNAME:
retval = mproc_ioctl_get_name(uarg);
case CMD_MULTIPROC_DESTROY:
status = mproc_ioctl_destroy(uarg);
break;
case CMD_MULTIPROC_GETMAXID:
retval = mproc_ioctl_get_max_processors(uarg);
case CMD_MULTIPROC_GETCONFIG:
status = mproc_ioctl_get_config(uarg);
break;
case CMD_MULTIPROC_SETLOCALID:
status = multiproc_ioctl_set_local_id(uarg);
break;
default:
WARN_ON(cmd);
retval = -ENOTTY;
status = -ENOTTY;
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:
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