Example #1
0
/****************************************************************************
*
*  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);
}
Example #2
0
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;
}