Commit 6a88a4fe authored by Omar Ramirez Luna's avatar Omar Ramirez Luna Committed by Greg Kroah-Hartman
Browse files

staging: ti dspbridge: add services

parent 7227b671
Loading
Loading
Loading
Loading
+253 −0
Original line number Diff line number Diff line
/*
 * cfg.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Implementation of platform specific config services.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/std.h>
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

/*  ----------------------------------- OS Adaptation Layer */

/*  ----------------------------------- This */
#include <dspbridge/cfg.h>
#include <dspbridge/drv.h>

struct drv_ext {
	struct list_head link;
	char sz_string[MAXREGPATHLENGTH];
};

/*
 *  ======== cfg_exit ========
 *  Purpose:
 *      Discontinue usage of the CFG module.
 */
void cfg_exit(void)
{
	/* Do nothing */
}

/*
 *  ======== cfg_get_auto_start ========
 *  Purpose:
 *      Retreive the autostart mask, if any, for this board.
 */
int cfg_get_auto_start(struct cfg_devnode *dev_node_obj,
			      OUT u32 *pdwAutoStart)
{
	int status = 0;
	u32 dw_buf_size;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	dw_buf_size = sizeof(*pdwAutoStart);
	if (!dev_node_obj)
		status = -EFAULT;
	if (!pdwAutoStart || !drv_datap)
		status = -EFAULT;
	if (DSP_SUCCEEDED(status))
		*pdwAutoStart = (drv_datap->base_img) ? 1 : 0;

	DBC_ENSURE((status == 0 &&
		    (*pdwAutoStart == 0 || *pdwAutoStart == 1))
		   || status != 0);
	return status;
}

/*
 *  ======== cfg_get_dev_object ========
 *  Purpose:
 *      Retrieve the Device Object handle for a given devnode.
 */
int cfg_get_dev_object(struct cfg_devnode *dev_node_obj,
			      OUT u32 *pdwValue)
{
	int status = 0;
	u32 dw_buf_size;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	if (!drv_datap)
		status = -EPERM;

	if (!dev_node_obj)
		status = -EFAULT;

	if (!pdwValue)
		status = -EFAULT;

	dw_buf_size = sizeof(pdwValue);
	if (DSP_SUCCEEDED(status)) {

		/* check the device string and then store dev object */
		if (!
		    (strcmp
		     ((char *)((struct drv_ext *)dev_node_obj)->sz_string,
		      "TIOMAP1510")))
			*pdwValue = (u32)drv_datap->dev_object;
	}
	if (DSP_FAILED(status))
		pr_err("%s: Failed, status 0x%x\n", __func__, status);
	return status;
}

/*
 *  ======== cfg_get_exec_file ========
 *  Purpose:
 *      Retreive the default executable, if any, for this board.
 */
int cfg_get_exec_file(struct cfg_devnode *dev_node_obj, u32 ul_buf_size,
			     OUT char *pstrExecFile)
{
	int status = 0;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	if (!dev_node_obj)
		status = -EFAULT;

	else if (!pstrExecFile || !drv_datap)
		status = -EFAULT;

	if (strlen(drv_datap->base_img) > ul_buf_size)
		status = -EINVAL;

	if (DSP_SUCCEEDED(status) && drv_datap->base_img)
		strcpy(pstrExecFile, drv_datap->base_img);

	if (DSP_FAILED(status))
		pr_err("%s: Failed, status 0x%x\n", __func__, status);
	DBC_ENSURE(((status == 0) &&
		    (strlen(pstrExecFile) <= ul_buf_size))
		   || (status != 0));
	return status;
}

/*
 *  ======== cfg_get_object ========
 *  Purpose:
 *      Retrieve the Object handle from the Registry
 */
int cfg_get_object(OUT u32 *pdwValue, u8 dw_type)
{
	int status = -EINVAL;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	DBC_REQUIRE(pdwValue != NULL);

	if (!drv_datap)
		return -EPERM;

	switch (dw_type) {
	case (REG_DRV_OBJECT):
		if (drv_datap->drv_object) {
			*pdwValue = (u32)drv_datap->drv_object;
			status = 0;
		} else {
			status = -ENODATA;
		}
		break;
	case (REG_MGR_OBJECT):
		if (drv_datap->mgr_object) {
			*pdwValue = (u32)drv_datap->mgr_object;
			status = 0;
		} else {
			status = -ENODATA;
		}
		break;

	default:
		break;
	}
	if (DSP_FAILED(status)) {
		*pdwValue = 0;
		pr_err("%s: Failed, status 0x%x\n", __func__, status);
	}
	DBC_ENSURE((DSP_SUCCEEDED(status) && *pdwValue != 0) ||
		   (DSP_FAILED(status) && *pdwValue == 0));
	return status;
}

/*
 *  ======== cfg_init ========
 *  Purpose:
 *      Initialize the CFG module's private state.
 */
bool cfg_init(void)
{
	return true;
}

/*
 *  ======== cfg_set_dev_object ========
 *  Purpose:
 *      Store the Device Object handle and dev_node pointer for a given devnode.
 */
int cfg_set_dev_object(struct cfg_devnode *dev_node_obj, u32 dwValue)
{
	int status = 0;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	if (!drv_datap) {
		pr_err("%s: Failed, status 0x%x\n", __func__, status);
		return -EPERM;
	}

	if (!dev_node_obj)
		status = -EFAULT;

	if (DSP_SUCCEEDED(status)) {
		/* Store the Bridge device object in the Registry */

		if (!(strcmp((char *)dev_node_obj, "TIOMAP1510")))
			drv_datap->dev_object = (void *) dwValue;
	}
	if (DSP_FAILED(status))
		pr_err("%s: Failed, status 0x%x\n", __func__, status);

	return status;
}

/*
 *  ======== cfg_set_object ========
 *  Purpose:
 *      Store the Driver Object handle
 */
int cfg_set_object(u32 dwValue, u8 dw_type)
{
	int status = -EINVAL;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	if (!drv_datap)
		return -EPERM;

	switch (dw_type) {
	case (REG_DRV_OBJECT):
		drv_datap->drv_object = (void *)dwValue;
		status = 0;
		break;
	case (REG_MGR_OBJECT):
		drv_datap->mgr_object = (void *)dwValue;
		status = 0;
		break;
	default:
		break;
	}
	if (DSP_FAILED(status))
		pr_err("%s: Failed, status 0x%x\n", __func__, status);
	return status;
}
+31 −0
Original line number Diff line number Diff line
/*
 * ntfy.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Manage lists of notification events.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/*  ----------------------------------- This */
#include <dspbridge/ntfy.h>

int dsp_notifier_event(struct notifier_block *this, unsigned long event,
			   void *data)
{
	struct  ntfy_event *ne = container_of(this, struct ntfy_event,
							noti_block);
	if (ne->event & event)
		sync_set_event(&ne->sync_obj);
	return NOTIFY_OK;
}
+69 −0
Original line number Diff line number Diff line
/*
 * services.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Provide SERVICES loading.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <dspbridge/host_os.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/std.h>
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

/*  ----------------------------------- OS Adaptation Layer */
#include <dspbridge/cfg.h>
#include <dspbridge/ntfy.h>
#include <dspbridge/sync.h>
#include <dspbridge/clk.h>

/*  ----------------------------------- This */
#include <dspbridge/services.h>

/*
 *  ======== services_exit ========
 *  Purpose:
 *      Discontinue usage of module; free resources when reference count
 *      reaches 0.
 */
void services_exit(void)
{
	cfg_exit();
}

/*
 *  ======== services_init ========
 *  Purpose:
 *      Initializes SERVICES modules.
 */
bool services_init(void)
{
	bool ret = true;
	bool fcfg;

	/* Perform required initialization of SERVICES modules. */
	fcfg = cfg_init();

	ret = fcfg;

	if (!ret) {
		if (fcfg)
			cfg_exit();
	}

	return ret;
}
+104 −0
Original line number Diff line number Diff line
/*
 * sync.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Synchronization services.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/*  ----------------------------------- Host OS */
#include <dspbridge/host_os.h>

/*  ----------------------------------- This */
#include <dspbridge/sync.h>

DEFINE_SPINLOCK(sync_lock);

/**
 * sync_set_event() - set or signal and specified event
 * @event:	Event to be set..
 *
 * set the @event, if there is an thread waiting for the event
 * it will be waken up, this function only wakes one thread.
 */

void sync_set_event(struct sync_object *event)
{
	spin_lock_bh(&sync_lock);
	complete(&event->comp);
	if (event->multi_comp)
		complete(event->multi_comp);
	spin_unlock_bh(&sync_lock);
}

/**
 * sync_wait_on_multiple_events() - waits for multiple events to be set.
 * @events:	Array of events to wait for them.
 * @count:	number of elements of the array.
 * @timeout	timeout on waiting for the evetns.
 * @pu_index	index of the event set.
 *
 * This functios will wait until any of the array element is set or until
 * timeout. In case of success the function will return 0 and
 * @pu_index will store the index of the array element set or in case
 * of timeout the function will return -ETIME or in case of
 * interrupting by a signal it will return -EPERM.
 */

int sync_wait_on_multiple_events(struct sync_object **events,
				     unsigned count, unsigned timeout,
				     unsigned *index)
{
	unsigned i;
	int status = -EPERM;
	struct completion m_comp;

	init_completion(&m_comp);

	if (SYNC_INFINITE == timeout)
		timeout = MAX_SCHEDULE_TIMEOUT;

	spin_lock_bh(&sync_lock);
	for (i = 0; i < count; i++) {
		if (completion_done(&events[i]->comp)) {
			INIT_COMPLETION(events[i]->comp);
			*index = i;
			spin_unlock_bh(&sync_lock);
			status = 0;
			goto func_end;
		}
	}

	for (i = 0; i < count; i++)
		events[i]->multi_comp = &m_comp;

	spin_unlock_bh(&sync_lock);

	if (!wait_for_completion_interruptible_timeout(&m_comp,
					msecs_to_jiffies(timeout)))
		status = -ETIME;

	spin_lock_bh(&sync_lock);
	for (i = 0; i < count; i++) {
		if (completion_done(&events[i]->comp)) {
			INIT_COMPLETION(events[i]->comp);
			*index = i;
			status = 0;
		}
		events[i]->multi_comp = NULL;
	}
	spin_unlock_bh(&sync_lock);
func_end:
	return status;
}