aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/sep/sep_driver.c
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2010-12-08 10:57:26 +0000
committerAlan Cox <alan@linux.intel.com>2010-12-08 10:57:26 +0000
commit70b449357c5e7211d3c5b7a37f6d64c8992f2162 (patch)
treef6c45ff5bad70070c1a36d2ab984e896dc9d4250 /drivers/staging/sep/sep_driver.c
parent8b137d1a0a5da49c202c46bb9063aa38857724a2 (diff)
downloadmrst-s0i3-test-70b449357c5e7211d3c5b7a37f6d64c8992f2162.tar.gz
mrst-s0i3-test-70b449357c5e7211d3c5b7a37f6d64c8992f2162.tar.xz
mrst-s0i3-test-70b449357c5e7211d3c5b7a37f6d64c8992f2162.zip
Return-Path: <mark.a.allyn@intel.com>
X-Original-To: alan@linux.intel.com Delivered-To: alan@linux.intel.com Received: from fmsmga001.fm.intel.com (fmsmga001.fm.intel.com [10.253.24.23]) by linux.intel.com (Postfix) with ESMTP id 434D46A4023 for <alan@linux.intel.com>; Tue, 21 Sep 2010 13:57:57 -0700 (PDT) X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.56,402,1280732400"; d="scan'208";a="839695177" Received: from allyn-test.jf.intel.com (HELO localhost.localdomain) ([134.134.158.107]) by fmsmga001.fm.intel.com with ESMTP; 21 Sep 2010 13:57:49 -0700 From: Mark Allyn <mark.a.allyn@intel.com> To: alan@linux.intel.com, jayant.mangalampalli@intel.com, venkat.r.gokulrangan@intel.com, amit.kumar@intel.com, mark.a.allyn@intel.com Subject: [PATCH 16/20] staging: sep: update start and init handlers Date: Tue, 21 Sep 2010 14:05:20 -0700 Message-Id: <1285103120-6818-1-git-send-email-mark.a.allyn@intel.com> X-Mailer: git-send-email 1.6.3.3 Signed-off-by: Mark A. Allyn <mark.a.allyn@intel.com>
Diffstat (limited to 'drivers/staging/sep/sep_driver.c')
-rw-r--r--drivers/staging/sep/sep_driver.c248
1 files changed, 151 insertions, 97 deletions
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
index 5f73add54c9..839fa360702 100644
--- a/drivers/staging/sep/sep_driver.c
+++ b/drivers/staging/sep/sep_driver.c
@@ -3097,14 +3097,15 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep,
}
/*
- ?
+ This function starts the sep device
+ @sep: pointer to struct sep_device
*/
static int sep_start_handler(struct sep_device *sep)
{
unsigned long reg_val;
unsigned long error = 0;
- dbg("SEP Driver:--------> sep_start_handler start\n");
+ dev_dbg(&sep->pdev->dev, "sep_start_handler start\n");
/* wait in polling for message from SEP */
do
@@ -3115,140 +3116,193 @@ static int sep_start_handler(struct sep_device *sep)
if (reg_val == 0x1)
/* fatal error - read error status from GPRO */
error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
- dbg("SEP Driver:<-------- sep_start_handler end\n");
+ dev_dbg(&sep->pdev->dev, "sep_start_handler end\n");
return error;
}
/*
+ This function performs a checsum for messages that are sent
+ to the sep
+*/
+static u32 sep_check_sum_calc(u8 *data, u32 length)
+{
+ u32 sum = 0;
+ u16 *Tdata = (u16 *)data;
+
+ while (length > 1) {
+ /* This is the inner loop */
+ sum += *Tdata++;
+ length -= 2;
+ }
+
+ /* Add left-over byte, if any */
+ if (length > 0)
+ sum += *(u8 *)Tdata;
+
+ /* Fold 32-bit sum to 16 bits */
+ while (sum>>16)
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ return ~sum & 0xFFFF;
+}
+
+/*
this function handles the request for SEP initialization
*/
static int sep_init_handler(struct sep_device *sep, unsigned long arg)
{
- unsigned long message_word;
- unsigned long *message_ptr;
+ u32 message_buff[14];
+ u32 counter;
+ int error = 0;
+ u32 reg_val;
+ dma_addr_t new_base_addr;
struct sep_driver_init_t command_args;
- unsigned long counter;
- unsigned long error;
- unsigned long reg_val;
- dbg("SEP Driver:--------> sep_init_handler start\n");
+ dev_dbg(&sep->pdev->dev, "sep_init_handler start\n");
error = 0;
- error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t));
-
- dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user \n");
+ /* make sure that we have not initialized already */
+ reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
- if (error)
+ if (reg_val != 0x2) {
+ error = SEP_ALREADY_INITIALIZED_ERR;
+ dev_warn(&sep->pdev->dev,
+ "init; device already initialized\n");
goto end_function;
+ }
- /* PATCH - configure the DMA to single -burst instead of multi-burst */
- /*sep_configure_dma_burst(); */
+ /* only root can initialize */
+ if (!capable(CAP_SYS_ADMIN)) {
+ dev_warn(&sep->pdev->dev,
+ "init; only root can init\n");
+ error = -EACCES;
+ goto end_function;
+ }
- dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n");
+ /* copy in the parameters */
+ error = copy_from_user(&command_args, (void *) arg,
+ sizeof(struct sep_driver_init_t));
- message_ptr = (unsigned long *) command_args.message_addr;
+ if (error) {
+ dev_warn(&sep->pdev->dev,
+ "init; copy_from_user failed %x\n", error);
+ goto end_function;
+ }
- /* set the base address of the SRAM */
- sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS);
+ /* validate parameters */
+ if (!command_args.message_addr || !command_args.sep_sram_addr ||
+ command_args.message_size_in_words > 14) {
- for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) {
- get_user(message_word, message_ptr);
- /* write data to SRAM */
- sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, message_word);
- edbg("SEP Driver:message_word is %lu\n", message_word);
- /* wait for write complete */
- sep_wait_sram_write(sep);
+ dev_warn(&sep->pdev->dev,
+ "init; parameter error\n");
+ error = -EINVAL;
+ goto end_function;
}
- dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n");
- /* signal SEP */
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1);
- do
- reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
- while (!(reg_val & 0xFFFFFFFD));
+ /* copy in the sep init message */
+ error = copy_from_user(message_buff,
+ command_args.message_addr,
+ command_args.message_size_in_words*sizeof(u32));
- dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n");
+ if (error) {
- /* check the value */
- if (reg_val == 0x1) {
- edbg("SEP Driver:init failed\n");
+ dev_warn(&sep->pdev->dev,
+ "init; copy sep init message failed %x\n", error);
+ goto end_function;
+ }
- error = sep_read_reg(sep, 0x8060);
- edbg("SEP Driver:sw monitor is %lu\n", error);
+ /* load resident, cache, and extapp firmware */
+ error = sep_load_firmware(sep);
- /* fatal error - read erro status from GPRO */
- error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
- edbg("SEP Driver:error is %lu\n", error);
+ if (error) {
+
+ dev_warn(&sep->pdev->dev,
+ "init; copy sep init message failed %x\n", error);
+ goto end_function;
}
-end_function:
- dbg("SEP Driver:<-------- sep_init_handler end\n");
- return error;
-}
+ /* compute the base address */
+ new_base_addr = sep->shared_bus;
-/*
- this function handles the request cache and resident reallocation
-*/
-static int sep_realloc_cache_resident_handler(struct sep_device *sep,
- unsigned long arg)
-{
- struct sep_driver_realloc_cache_resident_t command_args;
- int error;
+ if (sep->resident_bus < new_base_addr)
+ new_base_addr = sep->resident_bus;
- /* copy cache and resident to the their intended locations */
- error = sep_load_firmware(sep);
- if (error)
- return error;
+ if (sep->cache_bus < new_base_addr)
+ new_base_addr = sep->cache_bus;
- command_args.new_base_addr = sep->shared_bus;
+ if (sep->dcache_bus < new_base_addr)
+ new_base_addr = sep->dcache_bus;
- /* find the new base address according to the lowest address between
- cache, resident and shared area */
- if (sep->resident_bus < command_args.new_base_addr)
- command_args.new_base_addr = sep->resident_bus;
- if (sep->rar_bus < command_args.new_base_addr)
- command_args.new_base_addr = sep->rar_bus;
+ /* put physical addresses in sep message */
+ message_buff[3] = (u32)new_base_addr;
+ message_buff[4] = (u32)sep->shared_bus;
+ message_buff[6] = (u32)sep->resident_bus;
+ message_buff[7] = (u32)sep->cache_bus;
+ message_buff[8] = (u32)sep->dcache_bus;
- /* set the return parameters */
- command_args.new_cache_addr = sep->rar_bus;
- command_args.new_resident_addr = sep->resident_bus;
+ message_buff[command_args.message_size_in_words - 1] = 0x0;
+ message_buff[command_args.message_size_in_words - 1] =
+ sep_check_sum_calc((u8 *)message_buff,
+ command_args.message_size_in_words*sizeof(u32));
- /* set the new shared area */
- command_args.new_shared_area_addr = sep->shared_bus;
+ /* debug print of message */
+ for (counter = 0; counter < command_args.message_size_in_words;
+ counter++)
- edbg("SEP Driver:command_args.new_shared_addr is %08llx\n", command_args.new_shared_area_addr);
- edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr);
- edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr);
- edbg("SEP Driver:command_args.new_rar_addr is %08llx\n", command_args.new_cache_addr);
+ dev_dbg(&sep->pdev->dev,
+ "init; sep message word %d is %x\n",
+ counter, message_buff[counter]);
- /* return to user */
- if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t)))
- return -EFAULT;
- return 0;
-}
+ /* tell the sep the sram address */
+ sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, command_args.sep_sram_addr);
-/**
- * sep_get_time_handler - time request from user space
- * @sep: sep we are to set the time for
- * @arg: pointer to user space arg buffer
- *
- * This function reports back the time and the address in the SEP
- * shared buffer at which it has been placed. (Do we really need this!!!)
- */
+ /* push the message to the sep */
+ for (counter = 0; counter < command_args.message_size_in_words;
+ counter++) {
-static int sep_get_time_handler(struct sep_device *sep, unsigned long arg)
-{
- struct sep_driver_get_time_t command_args;
+ sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR,
+ message_buff[counter]);
- mutex_lock(&sep_mutex);
- command_args.time_value = sep_set_time(sep);
- command_args.time_physical_address = (unsigned long)sep_time_address(sep);
- mutex_unlock(&sep_mutex);
- if (copy_to_user((void __user *)arg,
- &command_args, sizeof(struct sep_driver_get_time_t)))
- return -EFAULT;
- return 0;
+ sep_wait_sram_write(sep);
+ }
+ /* signal sep that message is ready and to init */
+ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1);
+
+ /* wait for acknowledge */
+ dev_dbg(&sep->pdev->dev, "init; waiting for msg response\n");
+
+ do
+ reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+ while (!(reg_val & 0xFFFFFFFD));
+
+ if (reg_val == 0x1) {
+
+ dev_warn(&sep->pdev->dev, "init; device int failed\n");
+ error = sep_read_reg(sep, 0x8060);
+ dev_warn(&sep->pdev->dev, "init; sw monitor is %x\n", error);
+ error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
+ dev_warn(&sep->pdev->dev, "init; error is %x\n", error);
+ goto end_function;
+ }
+
+ dev_dbg(&sep->pdev->dev, "init; end CC INIT, reg_val is %x\n",
+ reg_val);
+
+ /* signal sep to zero the GPR3 */
+ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x10);
+
+ /* wait for response */
+ dev_dbg(&sep->pdev->dev, "init; waiting for zero set response\n");
+
+ do
+ reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+ while (reg_val != 0);
+
+
+end_function:
+ dev_dbg(&sep->pdev->dev, "init is done\n");
+ return error;
}
/*