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; }
/* * ======== 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); }
/* * ======== 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; }
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; }