/**************************************************************************** * * bcm_fuse_kril_init_module(void); * * Init module. * ***************************************************************************/ static int __init bcm_fuse_kril_init_module(void) { int ret = 0; pr_info("KRIL Support 1.00 (BUILD TIME "__DATE__" "__TIME__")\n" ); // check for AP only boot mode if ( AP_ONLY_BOOT == get_ap_boot_mode() ) { // AP only, so don't continue with KRIL init KRIL_DEBUG(DBG_INFO, "bcm_fuse_kril_init_module: AP only; don't register driver\n"); return ret; } if (( ret = register_chrdev( BCM_KRIL_MAJOR, "bcm_kril", &kril_ops )) < 0 ) { KRIL_DEBUG(DBG_ERROR, "kril: register_chrdev failed for major %d\n", BCM_KRIL_MAJOR ); goto out; } kril_class = class_create(THIS_MODULE, "bcm_kril"); if (IS_ERR(kril_class)) { return PTR_ERR(kril_class); } device_create(kril_class, NULL, MKDEV(BCM_KRIL_MAJOR, 0),NULL, "bcm_kril"); KRIL_DEBUG(DBG_INFO, "%s driver(major %d) installed.\n", "bcm_kril", BCM_KRIL_MAJOR); /** Register callbacks with the IPC module Note: does not depend on the channel */ ret = CAPI2_ClientInit(); /** Init KRIL Driver */ ret = KRIL_Init(); if (ret) { ret = -1; KRIL_DEBUG(DBG_ERROR, "KRIL_Init fail...!\n"); goto out_unregister; } return ret; out_unregister: unregister_chrdev( BCM_KRIL_MAJOR, "bcm_kril"); out: return(ret); }
static int __init ipcs_module_init(void) { int rc = 0; int readyChkCnt = 0; struct timespec startTime, endTime; IPC_DEBUG(DBG_INFO,"[ipc]: ipcs_module_init start..\n"); init_MUTEX_LOCKED(&g_ipc_info.ipc_sem); g_ipc_info.ipc_state = 0; g_ipc_info.devnum = MKDEV(IPC_MAJOR, 0); rc = register_chrdev_region(g_ipc_info.devnum, 1, "bcm_fuse_ipc"); if (rc < 0) { IPC_DEBUG(DBG_ERROR,"Error registering the IPC device\n"); goto out; } cdev_init(&g_ipc_info.cdev, &ipc_ops); g_ipc_info.cdev.owner = THIS_MODULE; rc = cdev_add(&g_ipc_info.cdev, g_ipc_info.devnum, 1); if (rc) { IPC_DEBUG(DBG_ERROR,"[ipc]: cdev_add errpr\n"); goto out_unregister; } IPC_DEBUG(DBG_INFO, "[ipc]: create_workqueue\n"); INIT_WORK(&g_ipc_info.cp_crash_dump_wq, ProcessCPCrashedDump); INIT_WORK(&g_ipc_info.intr_work, ipcs_intr_workqueue_process); g_ipc_info.intr_workqueue = create_workqueue("ipc-wq"); if (!g_ipc_info.intr_workqueue) { IPC_DEBUG(DBG_ERROR,"[ipc]: cannot create workqueue\n"); goto out_unregister; } IPC_DEBUG(DBG_INFO, "[ipc]: request_irq\n"); rc = request_irq(IRQ_IPC_C2A, ipcs_interrupt, IRQF_NO_SUSPEND, "ipc-intr", &g_ipc_info); if (rc) { IPC_DEBUG(DBG_ERROR,"[ipc]: request_irq error\n"); goto out_del; } /** Make sure this is not cache'd because CP has to know about any changes we write to this memory immediately. */ IPC_DEBUG(DBG_INFO, "[ipc]: ioremap_nocache IPC_BASE\n"); g_ipc_info.apcp_shmem = ioremap_nocache(IPC_BASE, IPC_SIZE); if (!g_ipc_info.apcp_shmem) { rc = -ENOMEM; IPC_DEBUG(DBG_ERROR,"[ipc]: Could not map shmem\n"); goto out_del; } #ifdef CONFIG_HAS_WAKELOCK wake_lock_init(&ipc_wake_lock, WAKE_LOCK_SUSPEND, "ipc_wake_lock"); #endif IPC_DEBUG(DBG_INFO, "[ipc]: ipcs_init\n"); if (ipcs_init((void *)g_ipc_info.apcp_shmem, IPC_SIZE)) { rc = -1; IPC_DEBUG(DBG_ERROR,"[ipc]: ipcs_init() failed\n"); goto out_del; } if ( sEarlyCPInterrupt ) { IPC_DEBUG(DBG_INFO,"[ipc]: early CP interrupt - doing crash dump...\n"); #ifdef CONFIG_HAS_WAKELOCK wake_lock(&ipc_wake_lock); #endif schedule_work(&g_ipc_info.cp_crash_dump_wq); } // check for AP only boot mode if ( AP_ONLY_BOOT == get_ap_boot_mode() ) { IPC_DEBUG(DBG_INFO,"[ipc]: AP only boot - not waiting for CP\n"); } else { // wait for CP to have IPC setup as well; if we exit module init // before IPC is ready, RPC module will likely crash during its // own init startTime = current_kernel_time(); while ( !g_ipc_info.ipc_state ) { IPC_DEBUG(DBG_INFO, "[ipc]: CP IPC not ready, sleeping...\n"); msleep(20); readyChkCnt++; if ( readyChkCnt > 100 ) { IPC_DEBUG(DBG_ERROR, "[ipc]: IPC init timeout - no response from CP\n"); rc = -1; goto out_del; } } endTime = current_kernel_time(); IPC_DEBUG(DBG_INFO,"readyChkCnt=%d time=%ldus\n", readyChkCnt, ((endTime.tv_sec - startTime.tv_sec)*1000000L+(endTime.tv_nsec - startTime.tv_nsec)/1000L)); IPC_DEBUG(DBG_INFO,"[ipc]: ipcs_module_init ok\n"); } return 0; out_del: cdev_del(&g_ipc_info.cdev); out_unregister: unregister_chrdev_region(g_ipc_info.devnum, 1); out: IPC_DEBUG(DBG_ERROR,"IPC Driver Failed to initialise!\n"); return rc; }