201 lines
4.2 KiB
C
201 lines
4.2 KiB
C
/*
|
|
* This file contains Linux-specific MCC library functions
|
|
*
|
|
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
*
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+ and/or BSD-3-Clause
|
|
* The GPL-2.0+ license for this file can be found in the COPYING.GPL file
|
|
* included with this distribution or at
|
|
* http://www.gnu.org/licenses/gpl-2.0.html
|
|
* The BSD-3-Clause License for this file can be found in the COPYING.BSD file
|
|
* included with this distribution or at
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
#include <linux/io.h>
|
|
#include <linux/string.h>
|
|
#include <linux/wait.h>
|
|
#include <linux/imx_sema4.h>
|
|
#include "mcc_config.h"
|
|
#include <linux/mcc_imx6sx.h>
|
|
|
|
/* Global variables */
|
|
static unsigned long mcc_shm_offset;
|
|
|
|
MCC_BOOKEEPING_STRUCT *bookeeping_data;
|
|
|
|
/*!
|
|
* \brief This function initializes the hw semaphore (SEMA4).
|
|
*
|
|
* Calls core-mutex driver to create a core mutex.
|
|
*
|
|
* \param[in] sem_num SEMA4 gate number.
|
|
*/
|
|
int mcc_init_semaphore(unsigned int sem_num)
|
|
{
|
|
/* Create a core mutex */
|
|
mcc_shm_ptr = imx_sema4_mutex_create(0, sem_num);
|
|
|
|
if (NULL == mcc_shm_ptr)
|
|
return MCC_ERR_SEMAPHORE;
|
|
else
|
|
return MCC_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
* \brief This function de-initializes the hw semaphore (SEMA4).
|
|
*
|
|
* Calls core-mutex driver to destroy a core mutex.
|
|
*
|
|
* \param[in] sem_num SEMA4 gate number.
|
|
*/
|
|
int mcc_deinit_semaphore(unsigned int sem_num)
|
|
{
|
|
/* Destroy the core mutex */
|
|
if (0 == imx_sema4_mutex_destroy(mcc_shm_ptr))
|
|
return MCC_SUCCESS;
|
|
else
|
|
return MCC_ERR_SEMAPHORE;
|
|
}
|
|
|
|
/*!
|
|
* \brief This function locks the specified core mutex.
|
|
*
|
|
* Calls core-mutex driver to lock the core mutex.
|
|
*
|
|
*/
|
|
int mcc_get_semaphore(void)
|
|
{
|
|
if (imx_mcc_bsp_int_disable()) {
|
|
pr_err("ERR:failed to disable mcc int.\n");
|
|
return MCC_ERR_SEMAPHORE;
|
|
}
|
|
|
|
if (0 == imx_sema4_mutex_lock(mcc_shm_ptr)) {
|
|
return MCC_SUCCESS;
|
|
} else {
|
|
if (imx_mcc_bsp_int_enable()) {
|
|
pr_err("ERR:failed to enable mcc int.\n");
|
|
return MCC_ERR_INT;
|
|
}
|
|
return MCC_ERR_SEMAPHORE;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief This function unlocks the specified core mutex.
|
|
*
|
|
* Calls core-mutex driver to unlock the core mutex.
|
|
*
|
|
*/
|
|
int mcc_release_semaphore(void)
|
|
{
|
|
if (0 == imx_sema4_mutex_unlock(mcc_shm_ptr)) {
|
|
/*
|
|
* Enable the cpu-to-cpu isr just in case imx_semae_mutex_unlock
|
|
* function has not woke up another task waiting for the core
|
|
* mutex.
|
|
*/
|
|
if (mcc_shm_ptr->gate_val != (MCC_CORE_NUMBER + 1))
|
|
imx_mcc_bsp_int_enable();
|
|
return MCC_SUCCESS;
|
|
}
|
|
|
|
return MCC_ERR_SEMAPHORE;
|
|
}
|
|
|
|
/*!
|
|
* \brief This function registers the CPU-to-CPU interrupt.
|
|
*
|
|
* Calls interrupt component functions to install and enable the
|
|
* CPU-to-CPU interrupt.
|
|
*
|
|
*/
|
|
int mcc_register_cpu_to_cpu_isr(void)
|
|
{
|
|
/*
|
|
* CPU to CPU ISR had been registered in MU driver.
|
|
* return success directly.
|
|
*/
|
|
return MCC_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
* \brief This function triggers an interrupt to other core(s).
|
|
*
|
|
*/
|
|
int mcc_generate_cpu_to_cpu_interrupt(void)
|
|
{
|
|
int ret;
|
|
|
|
/*
|
|
* Assert directed CPU interrupts for all processors except
|
|
* the requesting core
|
|
*/
|
|
ret = mcc_triger_cpu_to_cpu_interrupt();
|
|
|
|
if (ret == 0)
|
|
return MCC_SUCCESS;
|
|
else
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
* \brief This function copies data.
|
|
*
|
|
* Copies the number of single-addressable units from the source address
|
|
* to destination address.
|
|
*
|
|
* \param[in] src Source address.
|
|
* \param[in] dest Destination address.
|
|
* \param[in] size Number of single-addressable units to copy.
|
|
*/
|
|
void mcc_memcpy(void *src, void *dest, unsigned int size)
|
|
{
|
|
memcpy(dest, src, size);
|
|
}
|
|
|
|
void *mcc_virt_to_phys(void *x)
|
|
{
|
|
if (null == x)
|
|
return NULL;
|
|
else
|
|
return (void *)((unsigned long) (x) - mcc_shm_offset);
|
|
}
|
|
|
|
void *mcc_phys_to_virt(void *x)
|
|
{
|
|
if (null == x)
|
|
return NULL;
|
|
else
|
|
return (void *)((unsigned long) (x) + mcc_shm_offset);
|
|
}
|
|
|
|
int mcc_init_os_sync(void)
|
|
{
|
|
/* No used in linux */
|
|
return MCC_SUCCESS;
|
|
}
|
|
|
|
int mcc_deinit_os_sync(void)
|
|
{
|
|
/* No used in linux */
|
|
return MCC_SUCCESS;
|
|
}
|
|
|
|
void mcc_clear_os_sync_for_ep(MCC_ENDPOINT *endpoint)
|
|
{
|
|
/* No used in linux */
|
|
}
|
|
|
|
MCC_BOOKEEPING_STRUCT *mcc_get_bookeeping_data(void)
|
|
{
|
|
bookeeping_data = (MCC_BOOKEEPING_STRUCT *)ioremap_nocache
|
|
(MCC_BASE_ADDRESS, sizeof(struct mcc_bookeeping_struct));
|
|
mcc_shm_offset = (unsigned long)bookeeping_data
|
|
- (unsigned long)MCC_BASE_ADDRESS;
|
|
|
|
return bookeeping_data;
|
|
}
|