static int set_fault_type(int tag, int argv[], int argc)
{
    write_info_t    pkg_ap;
    uint8_t fault_type = 0;
    int ret = -1;

    if (argc == 0){
        return -1;
    }

    fault_type = argv[0] & 0xFF;

    memset(&pkg_ap, 0, sizeof(pkg_ap));

    pkg_ap.tag = TAG_FAULT;
    pkg_ap.cmd=CMD_SET_FAULT_TYPE_REQ;
    pkg_ap.wr_buf=&fault_type;
    pkg_ap.wr_len=sizeof(fault_type);

    hwlog_info("set_fault_type, %s, fault type:%s\n", obj_tag_str[tag], fault_type_table[fault_type]);

    if ((ret = write_customize_cmd(&pkg_ap, NULL)) != 0) {
        hwlog_err("set fault type %s failed, ret = %d in %s\n", fault_type_table[fault_type], ret, __func__);
        return -1;
    }
	
    hwlog_info("set fault type %s success\n", fault_type_table[fault_type]);

    return 0;
}
static void bootloader_logger_dump_old(struct bootloader_logger *logger)
{
    int i;
    char *p = logger->old_log;

    if (!p)
        return;

    hwlog_info( "*****************************"
            "bootloader_log_%s begin"
            "*****************************\n", logger->tag);
    for (i = 0; i < logger->old_log_size; i++) {
        if (logger->old_log[i] == '\0')
            logger->old_log[i] = ' ';
        if (logger->old_log[i] == '\n') {
            logger->old_log[i] = '\0';
            printk(KERN_INFO "bootloader_log_%s: %s\n", logger->tag, p);
            logger->old_log[i] = '\n';
            p = &logger->old_log[i + 1];
        }
    }
    hwlog_info( "******************************"
            "bootloader_log_%s end"
            "******************************\n", logger->tag);
}
static int  inputhub_mcu_init(void)
{
    int ret;
    init_completion(&send_complete);
#ifdef CONFIG_IOM3_RECOVERY
    atomic_set(&iom3_rec_state, IOM3_RECOVERY_UNINIT);
    iom3_rec_wq = create_singlethread_workqueue("iom3_rec_wq");
    if (!iom3_rec_wq)
    {
        hwlog_err("--------------------> faild in create iom3 wq in %s!\n", __func__);
        return -1;
    }
    INIT_DELAYED_WORK(&iom3_rec_work, iom3_recovery_work);
    init_completion(&iom3_rec_done);
    wake_lock_init(&iom3_rec_wl, WAKE_LOCK_SUSPEND, "iom3_rec_wl");
#endif
    ret = inputhub_route_init();
    inputhub_mcu_connect();
    if (NULL == mbox) {
        hwlog_err("--------------------> faild to get mailbox in %s!\n", __func__);
        return -1;
    } else {
        hwlog_info("--------------------> succeed to get mailbox in %s!\n", __func__);
    }
    boot_iom3();
    setSensorMcuMode(1);
    shb_dclient = dsm_register_client(&dsm_sensorhub);
    hwlog_info("----%s--->\n",__func__);
    return ret;
}
static int bootloader_logger_init(struct bootloader_logger *logger, char *old_buf)
{
    struct bootloader_logger_buffer *buffer = logger->buffer;

    hwlog_info( "bootloader_logger_%s: buffer=%p, size=%d\n",
            logger->tag, logger->buffer, logger->buffer_size);

    if (buffer->sig == bootloader_logger_SIG) {
        if (buffer->size > logger->buffer_size)
            hwlog_info("bootloader_logger_%s: found existing invalid "
                   "buffer, size %d \n",
                   logger->tag, buffer->size);
        else {
            hwlog_info("bootloader_logger_%s: found existing buffer, "
                   "size %d \n",
                   logger->tag, buffer->size);
            if (buffer->size > 0)
                bootloader_logger_save_old(logger, old_buf);
        }
    } else {
        hwlog_info("bootloader_logger_%s: no valid data in buffer "
               "(sig = 0x%08x)\n", logger->tag, buffer->sig);
    }

    /* Erase old bootloader log */
    buffer->sig = 0;
    buffer->size = 0;

    return 0;
}
static int switch_usb_dev_register(struct switch_usb_dev *sdev)
{
    int ret = 0;

    if (IS_ERR_OR_NULL(switch_usb_class)) {
        hwlog_info("%s: switch_usb_class is ERR or NULL, and create_switch_usb_class will start.", __func__);
        ret = create_switch_usb_class();
        if (ret < 0){
            hwlog_err("%s: create_switch_usb_class error!!! sdev->name=%s\n", __func__, sdev->name);
            goto err_create_file;
        }
    }
    hwlog_info("%s: device_create will start.", __func__);
    sdev->dev = device_create(switch_usb_class, NULL,
        MKDEV(0, 0), NULL, sdev->name);
    if (IS_ERR(sdev->dev))
    {
        ret = PTR_ERR(sdev->dev);
        hwlog_err("%s: device_create error!!! sdev->name=%s\n", __func__, sdev->name);
        goto err_create_file;
    }

    return 0;

err_create_file:

    return ret;
}
//Store usb state to sys node
static int switch_usb_set_state(struct switch_usb_dev *sdev, int state)
{
    int ret = 0;
    hwlog_info("%s: ------entry.\n", __func__);
    if ((state < USB_TO_AP) || (state > USB_OFF))
    {
        hwlog_err("%s: swstate[%d] is invalid!!!\n", __func__, state);
        ret = -EINVAL;
        return ret;
    }

    if (sdev->state == state)
    {
        hwlog_info("%s: swstate is not changed. sdev->state[%d] and state[%d]\n", __func__, sdev->state, state);
        ret = -EINVAL;
        return ret;
    }

    set_reg_to_target_state(USB_OFF);
    msleep (1000);

    if (state != USB_OFF)
    {
        set_reg_to_target_state(state);
    }

    // update the sys value
    sdev->state = state;

    //notify_switch_state(state);

    hwlog_info("%s: ------end.\n", __func__);
    return ret;
}
//This funciton is Only for Test:
//I2C address should be modified by virtual address. This virtual address is for Test. 
//And Tools out can put data into system for simulating
static int set_sensor_slave_addr(int tag, int argv[], int argc)
{
    write_info_t    pkg_ap;
    read_info_t pkg_mcu;
    unsigned int i2c_address = 0;
    int ret = -1;

    if (argc == 0){
        return -1;
    }

    i2c_address = argv[0] & 0xFF;
    memset(&pkg_ap, 0, sizeof(pkg_ap));
    memset(&pkg_mcu, 0, sizeof(pkg_mcu));

    pkg_ap.tag = tag;
    pkg_ap.cmd=CMD_SET_SLAVE_ADDR_REQ;
    pkg_ap.wr_buf=&i2c_address;
    pkg_ap.wr_len=sizeof(i2c_address);

    hwlog_info("set_sensor_slave_addr, %s, i2c_addr:0x%x\n", obj_tag_str[tag], i2c_address);

    if ((ret = write_customize_cmd(&pkg_ap, &pkg_mcu)) != 0) {
        hwlog_err("set %s slave addr failed, ret = %d in %s\n", obj_tag_str[tag], ret, __func__);
        return -1;
    }

    if (pkg_mcu.errno != 0) {
        hwlog_err("set %s slave addr failed errno = %d in %s\n", obj_tag_str[tag], pkg_mcu.errno, __func__);
    } else {
        hwlog_info("set %s new slave addr:0x%x success\n", obj_tag_str[tag], i2c_address);
    }

    return 0;
}
int ext_modem_init(void)
{
    ext_modem_t* p_ext_modem = &g_ext_modem;
    int ret = 0;

    hwlog_info("%s %d: Enter.\n", __func__, __LINE__);
    /* initialize semaphore used as bus lock */
    sema_init(&p_ext_modem->m_bus_sema, 1);

    p_ext_modem->m_mdm_bus_ready = 0;

    /* create a workqueue thread for modem reset */
    p_ext_modem->pm_reset_wq = create_singlethread_workqueue("mdm_rst_wq");

    if (NULL == p_ext_modem->pm_reset_wq)
    {
        hwlog_err("%s %d: error create modem reset workqueue\n", __func__, __LINE__);
        return -1;
    }

    INIT_WORK(&p_ext_modem->m_reset_work, modem_reset_work);

    /* initialize waitqueue for ap host resume status */
    init_waitqueue_head(&p_ext_modem->m_ap_resume_waitq);
    atomic_set(&p_ext_modem->m_ap_resume_atom, AP_BUS_RESUMED);
    hwlog_info("%s %d: Exit.\n", __func__, __LINE__);
    /* initialize complete, return success */
    return ret;
}
static irqreturn_t modem_reset_indication_irq(int irq, void *data)
{
    int rst_level = 0;
    if(GPIO_OEM_VALID(cbp_rst_ind_gpio )){
        hwlog_info("%s %d oem_gpio_get_value_cansleep(GPIO_VIATEL_MDM_RST_IND)=%d \n",__func__,__LINE__,oem_gpio_get_cbp_rst_ind_value());
        if(oem_gpio_get_cbp_rst_ind_value()){
            if(first_irq_flag == 1){
                hwlog_info("%s %d first irq read rest_gpio is high,return. \n",__func__,__LINE__);
                return IRQ_HANDLED;
            }
            wake_lock_timeout(&vmdata->wlock, MDM_RST_LOCK_TIME * HZ);
            modem_notify_event(MDM_EVT_NOTIFY_RESET_ON);
            via_modem_state = MODEM_STATE_POWER;
            via_monitor_uevent_notify(MODEM_STATE_POWER);
            rst_level = 1;
        }else{
            if(first_irq_flag == 1){
                hwlog_info("%s %d set first_irq_flag=0. \n",__func__,__LINE__);
                first_irq_flag = 0;
            }
            modem_notify_event(MDM_EVT_NOTIFY_RESET_OFF);
            rst_level = 0;
        }
        if (1 == atomic_read(&cbp_backup_timer_started)) {
            del_timer(&cbp_backup_timer);
        }
    }
    irq_set_irq_type(irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
    gpio_irq_cbp_rst_ind(rst_level);
    oem_gpio_irq_unmask(cbp_rst_ind_gpio);
    return IRQ_HANDLED;
}
static void modem_reset_work(struct work_struct* pt_work)
{
    int i = 0;
    hwlog_info("%s %d: Enter.\n", __func__, __LINE__);

    /* wait ap host controller to resume */
    msleep(AP_HOST_CONTROLLER_RESUME_TIME);

    for (i = 0; i < MODEM_BUS_MAX_NUM; i++)
    {
        if (g_ext_modem.m_arr_reset_handle[i])
        {
            hwlog_info("%s %d: current bus mdm_reset_handle not NULL.\n", __func__, __LINE__);
            g_ext_modem.m_arr_reset_handle[i]();
        }
        else
        {
            hwlog_info("%s %d: Warning: current bus mdm_reset_handle is NULL.\n", __func__, __LINE__);
        }
    }

    modem_channels_reset();

    four_wire_reset();
    hwlog_info("%s %d: Exit.\n", __func__, __LINE__);
}
/**
 * typec_intb_work() - handle the public interrupt work which is triggered by interrupts from type-c chips.
 */
void typec_intb_work(struct work_struct *work)
{
    int attach_status, port_mode, input_current, cc_orient;
    static int otg_attach = 0;
    struct typec_device_info *di = container_of(work, struct typec_device_info, g_intb_work);

    mutex_lock(&di->typec_lock);

    attach_status = typec_detect_attachment_status();
    if (TYPEC_ATTACH == attach_status) {
        hwlog_info("%s: typec attach\n", __func__);

        port_mode = typec_detect_port_mode();
        if (TYPEC_DEV_PORT_MODE_DFP == port_mode) {
            hwlog_info("%s: UFP OTG detected\n", __func__);
            otg_attach = 1;
            typec_open_otg();
        } else if (TYPEC_DEV_PORT_MODE_UFP == port_mode) {
            hwlog_info("%s: DFP HOST detected\n", __func__);
        } else {
            hwlog_err("%s: cannot detect a correct port mode\n", __func__);
        }

        input_current = typec_detect_input_current();
        if (TYPEC_DEV_CURRENT_HIGH == input_current) {
            hwlog_info("%s: detected type c current is 3A\n", __func__);
        } else if (TYPEC_DEV_CURRENT_MID == input_current) {
            hwlog_info("%s: detected type c current is 1.5A\n", __func__);
        } else if (TYPEC_DEV_CURRENT_DEFAULT == input_current) {
            hwlog_info("%s: detected type c current is default\n", __func__);
        } else {
            hwlog_err("%s: cannot detect a correct input current\n", __func__);
        }

        cc_orient = typec_detect_cc_orientation();
        if (TYPEC_ORIENT_CC1 == cc_orient) {
            hwlog_info("%s: CC1 detected\n", __func__);
        } else if (TYPEC_ORIENT_CC2 == cc_orient) {
            hwlog_info("%s: CC2 detected\n", __func__);
        } else {
            hwlog_err("%s: cannot detect a cc orientation\n", __func__);
        }
    } else if (TYPEC_DETACH == attach_status) {
        hwlog_info("%s: typec detach\n", __func__);

        if (1 == otg_attach) {
            hwlog_info("%s: UFP OTG detach\n", __func__);
            otg_attach = 0;
            typec_close_otg();
        }
    } else {
        hwlog_err("%s: cannot detect a correct attachment status\n", __func__);
    }

    mutex_unlock(&di->typec_lock);

    typec_clean_int_mask();
}
//init function for switch_usb_class mode
static int __init switch_usb_class_init(void)
{
    int ret = 0;
    hwlog_info("%s: ------entry.\n", __func__);
    ret = platform_driver_register(&usb_switch_driver);
    hwlog_info("%s: ------end. ret=%d\n", __func__, ret);

    return ret;
}
ssize_t modem_sim_switch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    if( !strncmp(buf, "1", strlen("1"))){
        oem_gpio_direction_output(cbp_sim_switch_gpio, 1);
        hwlog_info("Switch sim connection to VIA\n");
    }else if( !strncmp(buf, "0", strlen("0"))){
        oem_gpio_direction_output(cbp_sim_switch_gpio, 0);
        hwlog_info("Switch sim connection to Balong\n");
    }else{
        hwlog_info("Unknow command.\n");
    }
        return count;
}
static ssize_t modem_boot_set(struct device *pdev, struct device_attribute *attr, const char *buf, size_t count)
{
    int state;

    hwlog_info("Power PHY set to %s\n", buf);

    if (kstrtoint(buf, 10, &state)) {
        hwlog_err("%s:%d kstrtoint %s fail\n", __func__, __LINE__, buf);
        return -EINVAL;
    }

	switch(state){
		case POWER_SET_DEBUGOFF:
			modem_boot_change_state(state);
			oem_power_off_modem();
			break;
		case POWER_SET_DEBUGON:
			modem_boot_change_state(state);
			oem_power_on_modem();
			break;
		case POWER_SET_OFF:
			modem_boot_change_state(state);
			via_modem_state = MODEM_STATE_OFF;
			via_monitor_uevent_notify(MODEM_STATE_OFF);
			oem_power_off_modem();
			break;
		case POWER_SET_ON:
			modem_boot_change_state(state);
			oem_power_on_modem();
			break;
		case MODEM_CTRL_RESET:
			oem_reset_modem();
			break;
		case MODEM_CTRL_DIE:
			oem_let_cbp_die();
			break;
		case MODEM_CTRL_WAKE_LOCK:
			hwlog_info("hold on wakelock.\n");
			wake_lock(&vmdata->wlock);
			break;
		case MODEM_CTRL_WAKE_LOCK_RELEASE:
			hwlog_info("release wakelock.\n");
			wake_unlock(&vmdata->wlock);
			break;
		default:
			hwlog_info("default: do nothing!\n");
			break;
	}

    return count;
}
static int create_switch_usb_class(void)
{
    hwlog_info("%s: ------entry.\n", __func__);
    if (NULL==switch_usb_class) {
        hwlog_info("%s: switch_usb_class=NULL and class_create will start.\n", __func__);
        switch_usb_class = class_create(THIS_MODULE, "usbswitch");
        if (IS_ERR(switch_usb_class)){
            hwlog_err("%s: class_create error!!! switch_usb_class=%p\n", __func__, switch_usb_class);
            return PTR_ERR(switch_usb_class);
        }
    }
    hwlog_info("%s: ------end.\n", __func__);
    return 0;
}
static ssize_t attr_get_tp_color_info(struct device *dev, struct device_attribute *attr, char *buf)
{
	int ret=0;
	u8 lcd_id=0;
	u8 phone_color=0;
	lcd_id = read_tp_color();
	if (lcd_id != 0xff) {
		hwlog_info("lcd id is %u from read tp color\n", lcd_id);
	}
	hwlog_info("%s:tp id=%x   lcd id=%x.\n", __func__, cypress_tp_color[0], lcd_id);
	if(is_color_correct(cypress_tp_color[0]))
		phone_color=cypress_tp_color[0];
	else if(is_color_correct(lcd_id))
		phone_color=lcd_id;
	else
	{
		ret=read_tp_color_from_nv(buf);
		if(ret) strncpy(buf,"", sizeof(""));
		return strlen(buf);
	}
	switch(phone_color)
	{
	case WHITE:
			strncpy(buf,"white", sizeof("white"));
			break;
	case BLACK:
			strncpy(buf,"black", sizeof("black"));
			break;
	case PINK:
			strncpy(buf,"pink", sizeof("pink"));
			break;
	case RED:
			strncpy(buf,"red", sizeof("red"));
			break;
	case YELLOW:
			strncpy(buf,"yellow", sizeof("yellow"));
			break;
	case BLUE:
			strncpy(buf,"blue", sizeof("blue"));
			break;
	case GOLD:
			strncpy(buf,"gold", sizeof("gold"));
			break;
	default:
			strncpy(buf,"", sizeof(""));
			break;
	}
	return strlen(buf);
}
void ext_modem_exit(void)
{
    ext_modem_t* p_ext_modem = &g_ext_modem;

    hwlog_info("%s %d: Enter.\n", __func__, __LINE__);
    p_ext_modem->m_mdm_bus_ready = 0;

    cancel_work_sync(&p_ext_modem->m_reset_work);
    if (p_ext_modem->pm_reset_wq)
    {
        destroy_workqueue(p_ext_modem->pm_reset_wq);
    }

    hwlog_info("%s %d: Exit.\n", __func__, __LINE__);
}
void oem_power_on_modem(void)
{
   oem_gpio_direction_output(cbp_rst_gpio, 0);
   hwlog_info("%s cbp_rst_gpio:%d\n", __func__, cbp_rst_gpio);
   mdelay(MDM_RST_HOLD_DELAY);
   hwlog_info("%s cbp_pwr_en_gpio:%d\n", __func__, cbp_pwr_en_gpio);
   oem_gpio_direction_output(cbp_pwr_en_gpio, 1);
   mdelay(MDM_PWR_HOLD_DELAY);

   if (cbp_need_apr){
       schedule_delayed_work(&apr_log_wk, msecs_to_jiffies(60*1000));/*wait for 1 minute due to ramdump may later*/
       cbp_need_apr = 0;
   }
   hwlog_info("Warnning: power on vmodem\n");
}
ssize_t modem_via_resetinfo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    int ret = -1;

    hwlog_info("%s %d: start to call modem_via_resetinfo_store\n", __func__,__LINE__);
    if( !strncmp(buf, VIA_RESETINFO_WR_CLEAR, strlen(VIA_RESETINFO_WR_CLEAR)) ) {
        ret = via_resetinfo_write(VIA_RESETINFO_WR_CLEAR, VIA_RESETINFO_WR_COVER);
        if(ret != 0) {
            hwlog_err("%s %d: via_resetinfo_write write failed!\n", __func__,__LINE__);
            count = -1;
        }
        hwlog_info("%s %d: resetinfo has been clean.\n", __func__,__LINE__);
    }
    return count;
}
static int hw_dmp_power_reset_for_recovery_iom3(void)
{
	int ret = 0;
	hwlog_info("DMP powerdown!\n");
/*TODO: power off*/
	return 0;
}
ssize_t modem_via_resetinfo_show(struct device *dev, struct device_attribute *attr, char *buf)
{
    int count = -1;
    hwlog_info("%s %d: start to read resetinfo from g_cbp_resetinfo", __func__,__LINE__);
    count = via_resetinfo_read(buf, PAGE_SIZE);
    return count;
}
/* wait AP host controller to resumed */
int wait_ap_bus_resumed(void)
{
    unsigned long remain_time = 0;
    unsigned int timeout_cnt = 0;

    hwlog_debug("%s %d entered\n", __func__, __LINE__);

    do
    {
        remain_time = wait_event_timeout(g_ext_modem.m_ap_resume_waitq, (AP_BUS_RESUMED == atomic_read(&g_ext_modem.m_ap_resume_atom)) || \
                                         (0 == get_modem_bus_state()), msecs_to_jiffies(WAIT_APCP_BUS_RESUME_TIMEOUT));

        if (0 == get_modem_bus_state())
        {
            hwlog_err("%s %d: VIA modem reset happened\n", __func__, __LINE__);
            return -1;
        }
        else if (0 == remain_time)
        {
            hwlog_info("%s %d: wait ap host controller to resume timeout\n", __func__, __LINE__);
            timeout_cnt++;

            if (timeout_cnt >= MAX_WAIT_BUS_RESUME_TIMES)
            {
                hwlog_err("%s %d: FAIL to wait ap host to resume with MAX retries\n", __func__, __LINE__);
                return -2;
            }
        }
    }
    while (0 == remain_time);

    return 0;
}
static void oem_cbp_reset_by_ap(struct cbp_reset_info_s resetinfo)
{
    char rst_buf[MDM_RESETINFO_SIZE] = {0};
    if(via_modem_state != MODEM_STATE_READY) {
        hwlog_err("%s %d: VIA is in reset!\n", __func__, __LINE__);
        return;
    }

    snprintf(rst_buf, MDM_RESETINFO_SIZE, "system reboot reason: %s\n"
        "reboot_task:0x0\ntask_name:%s\nreboot_int:0xffffffff\nmodid:0x%x\n"
        "<system_error> ccore enter system error!\nstack:\n%s\nsemGive\n",
        resetinfo.task_name, resetinfo.task_name, resetinfo.modid, resetinfo.stack);
    hwlog_info("%s %d: resetinfo:%s", __func__, __LINE__, rst_buf);

    if(via_resetinfo_write(rst_buf, VIA_RESETINFO_WR_COVER)) {
        hwlog_err("%s %d:via_resetinfo_write write failed!\n", __func__,__LINE__);
    }

    if (0 == atomic_read(&cbp_backup_timer_started)) {
            mod_timer(&cbp_backup_timer, jiffies + msecs_to_jiffies(WAIT_CBP_BACKUP_RAMDUMP_RST_TIME));
            atomic_set(&cbp_backup_timer_started, 1);
    }

    oem_reset_modem_by_backup();
}
static void modem_signal_user(int event)
{
    if(vmdata && vmdata->fasync){
        hwlog_info("%s: evnet %d.\n",__FUNCTION__,  event);
        kill_fasync(&vmdata->fasync, SIGIO, event);
    }
}
static void hall_work(struct work_struct *work)
{
	int ret = 0;

	packet_data event_value = 0;
	struct hall_dev *phall_dev = NULL;

	phall_dev = container_of(work, struct hall_dev, hall_work);

	if (phall_dev->ops && phall_dev->ops->packet_event_data) {
		event_value = phall_dev->ops->packet_event_data(phall_dev);
	} else {
		hwlog_err("[hall][%s] packet event data failed!\n", __func__);
		return ;
	}

	if(phall_dev->ops && phall_dev->ops->hall_event_report) {
		ret = phall_dev->ops->hall_event_report(event_value);
		if(!ret) {
			hwlog_err("[hall][%s] hall report value failed.\n", __func__);
			return ;
		}
	} else {
		hwlog_err("[hall][%s]ops null\n", __func__);
	}
	hwlog_info("[hall][%s] hall report value :%d.\n", __func__, event_value);
	return ;
}
static int __init modem_boot_init(void)
{
    int ret = 0;

    ret = platform_driver_register(&modem_boot_driver);
    if(ret < 0)
    {
        hwlog_err("platform_driver_register failed\n");
        goto err_platform_driver_register;
    }

    ret = misc_register(&misc_modem_device);
    if(ret < 0)
    {
        hwlog_err("misc regiser via modem failed\n");
        goto err_misc_device_register;
    }
	hwlog_info("%s %d: Exit.\n", __func__, __LINE__);
    return ret;

err_misc_device_register:
    platform_driver_unregister(&modem_boot_driver);
err_platform_driver_register:

    return ret;
}
static int cpu_buck_probe(struct platform_device *pdev)
{
    struct device_node* np;
    struct cpu_buck_device_info* di;

    np = pdev->dev.of_node;
    if(NULL == np)
    {
        hwlog_err("np is NULL\n");
        return -1;
    }
    di = kzalloc(sizeof(*di), GFP_KERNEL);
    if (!di)
    {
        hwlog_err("di is NULL\n");
        return -ENOMEM;
    }
    if (!cpu_buck_client)
    {
        cpu_buck_client = dsm_register_client(&dsm_cpu_buck);
    }
    if (NULL == cpu_buck_client)
    {
        hwlog_err("cpu_buck register dsm fail\n");
        return -1;
    }
    INIT_DELAYED_WORK(&di->cpu_buck_delayed_work, cpu_buck_work);
    schedule_delayed_work(&di->cpu_buck_delayed_work, 10);
    hwlog_info("cpu_buck probe ok!\n");
    return 0;
}
static int hall_request_irq(struct hall_dev *phall_dev)
{
	int i = 0;
	int irq = 0;
	int ret = 0;
	int wake_flag;
	int trigger_value = 0;

	if (NULL == phall_dev) {
		hwlog_err("[hall][%s] invalid pointer!\n", __func__);
		return -EINVAL;
	}

	wake_flag = phall_dev->wake_up;
	for ( i = 0; i < HALL_IRQ_NUM; i++) {
		irq = phall_dev->irq_info[i].irq;
		trigger_value = phall_dev->irq_info[i].trigger_value;
		if (irq) {
			ret = request_irq(irq, hall_event_handler,
				trigger_value | wake_flag, phall_dev->irq_info[i].name, phall_dev);
				hwlog_info("[hall][%s]irq:%d, trigger_value:%d, wake_flag:%d.\n", \
				__func__, irq, trigger_value, wake_flag);
		}
	}

/*
  * report the current magnetic field approach status to the initialized magnetic field status approach identification.
  */
	if (phall_dev->ops && phall_dev->ops->hall_device_irq_top_handler && hall_work_status == phall_dev->hall_status) {
		phall_dev->ops->hall_device_irq_top_handler(irq, phall_dev);
		queue_work(hall_wq, &phall_dev->hall_work);
	}

	return ret;
}
static void cpu_buck_work(struct work_struct *work)
{
    int i = 0;
    struct cpu_buck_sample* cbs = g_cbs;
    bool already_notified = false;

    if (!fault_happened)
        return;
    while(cbs)
    {
        for (i = 0; i < cbs->info_size; ++i)
        {
            if ((cbs->cbi[i].error_mask & cbs->reg[cbs->cbi[i].reg_number]) == cbs->cbi[i].error_mask)
            {
                if (!dsm_client_ocuppy(cpu_buck_client))
                {
                    already_notified = true;
                    hwlog_info("cpu_buck record and notify: %s\n", cbs->cbi[i].error_info);
                    dsm_client_record(cpu_buck_client, "cpu_buck %s happened!\n", cbs->cbi[i].error_info);
                    dsm_client_notify(cpu_buck_client, ERROR_NO_CPU_BUCK_BASE + cbs->cbi[i].err_no);
                    break;
                }
            }
        }
        if (already_notified)
        {
            break;
        }
        cbs = cbs->cbs;
    }
}
/*******************************************************************************************
Function:       shb_ioctl
Description:    定义/dev/sensorhub节点的ioctl函数,主要用于设置传感器命令和获取MCU是否存在
Data Accessed:  无
Data Updated:   无
Input:          struct file *file, unsigned int cmd, unsigned long arg,cmd是命令码,arg是命令跟的参数
Output:         无
Return:         成功或者失败信息
*******************************************************************************************/
static long shb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    void __user *argp = (void __user *)arg;
    /*begin huangwen 20120706*/
    int sensorMcuMode;
    /*end huangwen 20120706*/


    switch (cmd) {
    case SHB_IOCTL_APP_ENABLE_SENSOR:
        get_acc_calibrate_data();
        get_mag_calibrate_data();
        get_cap_prox_calibrate_data();
        get_airpress_calibrate_data();
        break;
    case SHB_IOCTL_APP_DISABLE_SENSOR:
        break;
    /*begin huangwen 20120706*/
    case SHB_IOCTL_APP_GET_SENSOR_MCU_MODE:
        sensorMcuMode = getSensorMcuMode();
        hwlog_info( "isSensorMcuMode [%d]\n", sensorMcuMode );
        if (copy_to_user(argp, &sensorMcuMode, sizeof(sensorMcuMode)))
            return -EFAULT;
        return 0;
        break;
    /*end huangwen 20120706*/
    case SHB_IOCTL_APP_DELAY_ACCEL:
    case SHB_IOCTL_APP_DELAY_LIGHT:
    case SHB_IOCTL_APP_DELAY_PROXI:
    case SHB_IOCTL_APP_DELAY_GYRO:
    case SHB_IOCTL_APP_DELAY_GRAVITY:
    case SHB_IOCTL_APP_DELAY_MAGNETIC:
    case SHB_IOCTL_APP_DELAY_ROTATESCREEN:
    case SHB_IOCTL_APP_DELAY_LINEARACCELERATE:
    case SHB_IOCTL_APP_DELAY_ORIENTATION:
    case SHB_IOCTL_APP_DELAY_ROTATEVECTOR:
    case SHB_IOCTL_APP_DELAY_PRESSURE:
    case SHB_IOCTL_APP_DELAY_TEMPERATURE:
    case SHB_IOCTL_APP_DELAY_RELATIVE_HUMIDITY:
    case SHB_IOCTL_APP_DELAY_AMBIENT_TEMPERATURE:
    case SHB_IOCTL_APP_DELAY_MCU_LABC:
    case SHB_IOCTL_APP_DELAY_HALL:
    case SHB_IOCTL_APP_DELAY_MAGNETIC_FIELD_UNCALIBRATED:
    case SHB_IOCTL_APP_DELAY_GAME_ROTATION_VECTOR:
    case SHB_IOCTL_APP_DELAY_GYROSCOPE_UNCALIBRATED:
    case SHB_IOCTL_APP_DELAY_SIGNIFICANT_MOTION:
    case SHB_IOCTL_APP_DELAY_STEP_DETECTOR:
    case SHB_IOCTL_APP_DELAY_STEP_COUNTER:
    case SHB_IOCTL_APP_DELAY_GEOMAGNETIC_ROTATION_VECTOR:
    case SHB_IOCTL_APP_DELAY_AIRPRESS:
    case SHB_IOCTL_APP_DELAY_HANDPRESS:
    case SHB_IOCTL_APP_DELAY_CAP_PROX:
        break;
    default:
        hwlog_err("shb_ioctl unknown cmd : %d\n", cmd);
        return -ENOTTY;
    }
    return inputhub_route_cmd(ROUTE_SHB_PORT,cmd,arg);

}