Пример #1
0
int api_init_complete2(void)
{
    int status = 0;
    struct cfg_devnode *dev_node;
    struct dev_object *hdev_obj;
    struct drv_data *drv_datap;
    u8 dev_type;

    for (hdev_obj = dev_get_first(); hdev_obj != NULL;
            hdev_obj = dev_get_next(hdev_obj)) {
        if (dev_get_dev_node(hdev_obj, &dev_node))
            continue;

        if (dev_get_dev_type(hdev_obj, &dev_type))
            continue;

        if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) {
            drv_datap = dev_get_drvdata(bridge);

            if (drv_datap && drv_datap->base_img)
                proc_auto_start(dev_node, hdev_obj);
        }
    }

    return status;
}
Пример #2
0
/*
 *  ======== api_init_complete2 ========
 *  Purpose:
 *      Perform any required bridge initialization which cannot
 *      be performed in api_init() or dev_start_device() due
 *      to the fact that some services are not yet
 *      completely initialized.
 *  Parameters:
 *  Returns:
 *      0:	Allow this device to load
 *      -EPERM:      Failure.
 *  Requires:
 *      Bridge API initialized.
 *  Ensures:
 */
int api_init_complete2(void)
{
	int status = 0;
	struct cfg_devnode *dev_node;
	struct dev_object *hdev_obj;
	struct drv_data *drv_datap;
	u8 dev_type;

	/*  Walk the list of DevObjects, get each devnode, and attempting to
	 *  autostart the board. Note that this requires COF loading, which
	 *  requires KFILE. */
	for (hdev_obj = dev_get_first(); hdev_obj != NULL;
	     hdev_obj = dev_get_next(hdev_obj)) {
		if (dev_get_dev_node(hdev_obj, &dev_node))
			continue;

		if (dev_get_dev_type(hdev_obj, &dev_type))
			continue;

		if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) {
			drv_datap = dev_get_drvdata(bridge);

			if (drv_datap && drv_datap->base_img)
				proc_auto_start(dev_node, hdev_obj);
		}
	}

	return status;
}
static void bridge_recover(struct work_struct *work)
{
	struct dev_object *dev;
	struct cfg_devnode *dev_node;
	if (atomic_read(&bridge_cref)) {
		INIT_COMPLETION(bridge_comp);
		while (!wait_for_completion_timeout(&bridge_comp,
						msecs_to_jiffies(REC_TIMEOUT)))
			pr_info("%s:%d handle(s) still opened\n",
					__func__, atomic_read(&bridge_cref));
	}
	dev = dev_get_first();
	dev_get_dev_node(dev, &dev_node);
	if (!dev_node || proc_auto_start(dev_node, dev))
		pr_err("DSP could not be restarted\n");
	recover = false;
	complete_all(&bridge_open_comp);
}
Пример #4
0
/*
 *  ======== mgr_enum_processor_info ========
 *      Enumerate and get configuration information about available
 *      DSP processors.
 */
int mgr_enum_processor_info(u32 processor_id,
				   struct dsp_processorinfo *
				   processor_info, u32 processor_info_size,
				   u8 *pu_num_procs)
{
	int status = 0;
	int status1 = 0;
	int status2 = 0;
	struct dsp_uuid temp_uuid;
	u32 temp_index = 0;
	u32 proc_index = 0;
	struct dcd_genericobj gen_obj;
	struct mgr_object *pmgr_obj = NULL;
	struct mgr_processorextinfo *ext_info;
	struct dev_object *hdev_obj;
	struct drv_object *hdrv_obj;
	u8 dev_type;
	struct cfg_devnode *dev_node;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);
	bool proc_detect = false;

	*pu_num_procs = 0;

	/* Retrieve the Object handle from the driver data */
	if (!drv_datap || !drv_datap->drv_object) {
		status = -ENODATA;
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
	} else {
		hdrv_obj = drv_datap->drv_object;
	}

	if (!status) {
		status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
		if (!status) {
			status = dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
			status = dev_get_dev_node(hdev_obj, &dev_node);
			if (dev_type != DSP_UNIT)
				status = -EPERM;

			if (!status)
				processor_info->processor_type = DSPTYPE64;
		}
	}
	if (status)
		goto func_end;

	/* Get The Manager Object from the driver data */
	if (drv_datap && drv_datap->mgr_object) {
		pmgr_obj = drv_datap->mgr_object;
	} else {
		dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
		goto func_end;
	}
	/* Forever loop till we hit no more items in the
	 * Enumeration. We will exit the loop other than 0; */
	while (status1 == 0) {
		status1 = dcd_enumerate_object(temp_index++,
					       DSP_DCDPROCESSORTYPE,
					       &temp_uuid);
		if (status1 != 0)
			break;

		proc_index++;
		/* Get the Object properties to find the Device/Processor
		 * Type */
		if (proc_detect != false)
			continue;

		status2 = dcd_get_object_def(pmgr_obj->dcd_mgr,
					     (struct dsp_uuid *)&temp_uuid,
					     DSP_DCDPROCESSORTYPE, &gen_obj);
		if (!status2) {
			/* Get the Obj def */
			if (processor_info_size <
			    sizeof(struct mgr_processorextinfo)) {
				*processor_info = gen_obj.obj_data.proc_info;
			} else {
				/* extended info */
				ext_info = (struct mgr_processorextinfo *)
				    processor_info;
				*ext_info = gen_obj.obj_data.ext_proc_obj;
			}
			dev_dbg(bridge, "%s: Got proctype  from DCD %x\n",
				__func__, processor_info->processor_type);
			/* See if we got the needed processor */
			if (dev_type == DSP_UNIT) {
				if (processor_info->processor_type ==
				    DSPPROCTYPE_C64)
					proc_detect = true;
			} else if (dev_type == IVA_UNIT) {
				if (processor_info->processor_type ==
				    IVAPROCTYPE_ARM7)
					proc_detect = true;
			}
			/* User applications only check for chip type, so
			 * this is a clumsy overwrite */
			processor_info->processor_type = DSPTYPE64;
		} else {
			dev_dbg(bridge, "%s: Failed to get DCD processor info "
				"%x\n", __func__, status2);
			status = -EPERM;
		}
	}
	*pu_num_procs = proc_index;
	if (proc_detect == false) {
		dev_dbg(bridge, "%s: Failed to get proc info from DCD, so use "
			"CFG registry\n", __func__);
		processor_info->processor_type = DSPTYPE64;
	}
func_end:
	return status;
}
Пример #5
0
int bridge_io_create(struct io_mgr **io_man,
			    struct dev_object *hdev_obj,
			    const struct io_attrs *mgr_attrts)
{
	struct io_mgr *pio_mgr = NULL;
	struct bridge_dev_context *hbridge_context = NULL;
	struct cfg_devnode *dev_node_obj;
	struct chnl_mgr *hchnl_mgr;
	u8 dev_type;

	
	if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0)
		return -EFAULT;

	*io_man = NULL;

	dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
	if (!hchnl_mgr || hchnl_mgr->iomgr)
		return -EFAULT;

	dev_get_bridge_context(hdev_obj, &hbridge_context);
	if (!hbridge_context)
		return -EFAULT;

	dev_get_dev_type(hdev_obj, &dev_type);

	
	pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL);
	if (!pio_mgr)
		return -ENOMEM;

	
	pio_mgr->chnl_mgr = hchnl_mgr;
	pio_mgr->word_size = mgr_attrts->word_size;

	if (dev_type == DSP_UNIT) {
		
		tasklet_init(&pio_mgr->dpc_tasklet, io_dpc, (u32) pio_mgr);

		
		pio_mgr->dpc_req = 0;
		pio_mgr->dpc_sched = 0;

		spin_lock_init(&pio_mgr->dpc_lock);

		if (dev_get_dev_node(hdev_obj, &dev_node_obj)) {
			bridge_io_destroy(pio_mgr);
			return -EIO;
		}
	}

	pio_mgr->bridge_context = hbridge_context;
	pio_mgr->shared_irq = mgr_attrts->irq_shared;
	if (dsp_wdt_init()) {
		bridge_io_destroy(pio_mgr);
		return -EPERM;
	}

	
	hchnl_mgr->iomgr = pio_mgr;
	*io_man = pio_mgr;

	return 0;
}