/** Connect an IRQ handler to a task. * * @param inr IRQ number. * @param devno Device number. * @param imethod Interface and method to be associated with the notification. * @param ucode Uspace pointer to the top-half pseudocode. * * @return EPERM or a return code returned by ipc_irq_register(). * */ sysarg_t sys_irq_register(inr_t inr, devno_t devno, sysarg_t imethod, irq_code_t *ucode) { if (!(cap_get(TASK) & CAP_IRQ_REG)) return EPERM; return ipc_irq_register(&TASK->answerbox, inr, devno, imethod, ucode); }
/* * function: ipcm module init * input: void * output: NULL * return: 0: success, -1: failed * Notes: * This initial function create handle table, * * create kernel receive thread, * timer initial, register irq and so on * */ static int __init ipcm_vdd_init(void) { hisi_ipc_dev_t *ipc_dev; unsigned int flag_value; struct gic_sgi_handle ipc_irq; unsigned long ipcm_handshake_timeout; mcc_trace(IPCM_DBG_LEVEL, "local_cpu_id = %d\n", cpuid); /* Init ipcm device */ ipc_dev = &hisi_ipc_dev; ipc_dev->local_cpu_id = cpuid; ipc_dev->gic_cpu_inf_base = CFG_GIC_CPU_BASE; ipc_dev->gic_dist_base = CFG_GIC_DIST_BASE; ipc_dev->data_reg_base = IPC_DATA_REG_BASE; ipc_dev->irq = IPC_GIC_IRQ; ipc_dev->remote_map_flag = 0; ipc_dev->sended_irqs = 0; ipc_dev->received_irqs = 0; #ifdef CONFIG_HIIPCM_IRQ_STATISTIC_ENABLE /* create and add the kobj for hi-ipcm */ hi_ipcm_kobj = kobject_create_and_add("hi-ipcm", NULL); if (NULL == hi_ipcm_kobj) { mcc_trace(IPCM_ERR_LEVEL, "create and add kobj failed!\n"); return -1; } if (sysfs_create_group(hi_ipcm_kobj, &attr_group)) { kobject_put(hi_ipcm_kobj); mcc_trace(IPCM_ERR_LEVEL, "create sysfs file failed!\n"); return -1; } #endif /* Init timer */ init_timer(&(ipc_dev->timer)); /* Init shared memory */ hisi_ipcm_shared_mem_init(); /* Register interrupt process function */ ipc_irq.irq = ipc_dev->irq; ipc_irq.handle = hisi_ipcm_handle_irq; ipc_irq_register(&ipc_irq); /* The slave cpu send initial data to the master cpu */ if (ipc_dev->local_cpu_id & 0x1) { ipcm_handshake_timeout = jiffies + CONFIG_HIIPCM_WAIT_TIMEOUT * HZ; while (1) { flag_value = readl((void *)ipc_dev->data_reg_base + GET_DATA_REG_OFFSET(A7_CPU_INTRF, 3)); if (flag_value & IPCM_HANDSHAKE_FLAG) { ipcm_send_initial_data(); break; } udelay(10); if (!time_before(jiffies, ipcm_handshake_timeout)) { mcc_trace(IPCM_ERR_LEVEL, "Wait A17 handshake flag is timeout!\n"); return -1; } } } else /* Set the handshake flag */ writel(IPCM_HANDSHAKE_FLAG, (void *)ipc_dev->data_reg_base + GET_DATA_REG_OFFSET(A7_CPU_INTRF, 3)); mcc_trace(IPCM_INFO_LEVEL, "IPCM hardware initialized successfully!\n"); return 0; }