static int __init tegra_sleep_info_init(void) { /* Register callback from idle for all cpus */ rq_wq = create_singlethread_workqueue("rq_stats"); BUG_ON(!rq_wq); INIT_DELAYED_WORK_DEFERRABLE(&rq_info.rq_work, rq_work_fn); INIT_DELAYED_WORK_DEFERRABLE(&rq_info.def_timer_work, def_work_fn); init_rq_attribs(); return 0; }
static int __init msm_sleep_info_init(void) { int err = 0; int cpu; struct sleep_data *sleep_info = NULL; /* Register callback from idle for all cpus */ msm_idle_register_cb(idle_enter, idle_exit); rq_wq = create_singlethread_workqueue("rq_stats"); BUG_ON(!rq_wq); INIT_DELAYED_WORK_DEFERRABLE(&rq_info.rq_work, rq_work_fn); INIT_DELAYED_WORK_DEFERRABLE(&rq_info.def_timer_work, def_work_fn); init_rq_attribs(); for_each_possible_cpu(cpu) { printk(KERN_INFO "msm_sleep_stats: Initializing sleep stats " "for CPU[%d]\n", cpu); sleep_info = &per_cpu(core_sleep_info, cpu); sleep_info->cpu = cpu; INIT_WORK(&sleep_info->work, notify_uspace_work_fn); /* Initialize high resolution timer */ hrtimer_init(&sleep_info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); sleep_info->timer.function = timer_func; /* Register for cpufreq policy changes */ sleep_info->nb.notifier_call = policy_change_notifier; err = cpufreq_register_notifier(&sleep_info->nb, CPUFREQ_POLICY_NOTIFIER); if (err) goto cleanup; /* Create sysfs object */ err = add_sysfs_objects(sleep_info); if (err) goto cleanup; continue; cleanup: printk(KERN_INFO "msm_sleep_stats: Failed to initialize sleep " "stats for CPU[%d]\n", cpu); sleep_info->cpu = -1; cpufreq_unregister_notifier(&sleep_info->nb, CPUFREQ_POLICY_NOTIFIER); remove_sysfs_objects(sleep_info); } return 0; }
/** * sr_class1p5_start() - class 1p5 init * @voltdm: sr voltage domain * @class_priv_data: private data for the class * * we do class specific initialization like creating sysfs/debugfs entries * needed, spawning of a kthread if needed etc. */ static int sr_class1p5_start(struct voltagedomain *voltdm, void *class_priv_data) { struct sr_class1p5_work_data *work_data; int idx; if (IS_ERR_OR_NULL(voltdm) || IS_ERR_OR_NULL(class_priv_data)) { pr_err("%s: bad parameters!\n", __func__); return -EINVAL; } /* setup our work params */ work_data = get_sr1p5_work(voltdm); if (!IS_ERR_OR_NULL(work_data)) { pr_err("%s: ooopps.. class already initialized for %s! bug??\n", __func__, voltdm->name); return -EINVAL; } work_data = NULL; /* get the next spare work_data */ for (idx = 0; idx < MAX_VDDS; idx++) { if (!class_1p5_data.work_data[idx].voltdm) { work_data = &class_1p5_data.work_data[idx]; break; } } if (!work_data) { pr_err("%s: no more space for work data for domains!\n", __func__); return -ENOMEM; } work_data->voltdm = voltdm; INIT_DELAYED_WORK_DEFERRABLE(&work_data->work, do_calibrate); return 0; }
/** * sr_class1p5_driver_init() - register class 1p5 as default * * board files call this function to use class 1p5, we register with the * smartreflex subsystem */ static int __init sr_class1p5_driver_init(void) { int r; /* Enable this class only for OMAP3630 and OMAP4 */ if (!(cpu_is_omap3630() || cpu_is_omap44xx())) return -EINVAL; r = sr_register_class(&class1p5_data); if (r) { pr_err("SmartReflex class 1.5 driver: " "failed to register with %d\n", r); } else { #if CONFIG_OMAP_SR_CLASS1P5_RECALIBRATION_DELAY INIT_DELAYED_WORK_DEFERRABLE(&recal_work, sr_class1p5_recal_work); schedule_delayed_work(&recal_work, msecs_to_jiffies (CONFIG_OMAP_SR_CLASS1P5_RECALIBRATION_DELAY)); #endif pr_info("SmartReflex class 1.5 driver: initialized (%dms)\n", CONFIG_OMAP_SR_CLASS1P5_RECALIBRATION_DELAY); } return r; }
/** * sr_class1p5_init() - class 1p5 init * @voltdm: sr voltage domain * @voltdm_cdata: voltage domain specific private class data * allocated by class init with work item data * freed by deinit. * @class_priv_data: private data for the class (unused) * * we do class specific initialization like creating sysfs/debugfs entries * needed, spawning of a kthread if needed etc. */ static int sr_class1p5_init(struct voltagedomain *voltdm, void **voltdm_cdata, void *class_priv_data) { struct sr_class1p5_work_data *work_data; if (IS_ERR_OR_NULL(voltdm) || IS_ERR_OR_NULL(voltdm_cdata)) { pr_err("%s: bad parameters!\n", __func__); return -EINVAL; } if (!IS_ERR_OR_NULL(*voltdm_cdata)) { pr_err("%s: ooopps.. class already initialized for %s! bug??\n", __func__, voltdm->name); return -EINVAL; } /* setup our work params */ work_data = kzalloc(sizeof(struct sr_class1p5_work_data), GFP_KERNEL); if (!work_data) { pr_err("%s: no memory to allocate work data on domain %s\n", __func__, voltdm->name); return -ENOMEM; } work_data->voltdm = voltdm; INIT_DELAYED_WORK_DEFERRABLE(&work_data->work, sr_class1p5_calib_work); *voltdm_cdata = (void *)work_data; return 0; }
static __devinit int sec_therm_probe(struct platform_device *pdev) { struct sec_therm_platform_data *pdata = dev_get_platdata(&pdev->dev); struct sec_therm_info *info; int ret = 0; dev_info(&pdev->dev, "%s: SEC Thermistor Driver Loading\n", __func__); info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; platform_set_drvdata(pdev, info); info->dev = &pdev->dev; info->pdata = pdata; info->padc = s3c_adc_register(pdev, NULL, NULL, 0); ret = sysfs_create_group(&info->dev->kobj, &sec_therm_group); if (ret) { dev_err(info->dev, "failed to create sysfs attribute group\n"); } INIT_DELAYED_WORK_DEFERRABLE(&info->polling_work, sec_therm_polling_work); schedule_delayed_work(&info->polling_work, msecs_to_jiffies(info->pdata->polling_interval)); return ret; }
int __init init_display_devices(void) { int ret; ret = fb_register_client(&framebuffer_nb); if (ret) pr_warning("Failed to register framebuffer notifier\n"); ret = mcde_dss_register_notifier(&display_nb); if (ret) pr_warning("Failed to register dss notifier\n"); #ifdef CONFIG_DISPLAY_GENERIC_PRIMARY if (display_initialized_during_boot) generic_display0.power_mode = MCDE_DISPLAY_PM_STANDBY; ret = mcde_display_device_register(&generic_display0); if (ret) pr_warning("Failed to register generic display device 0\n"); #endif #ifdef CONFIG_DISPLAY_AV8100_TERTIARY INIT_DELAYED_WORK_DEFERRABLE(&work_dispreg_hdmi, delayed_work_dispreg_hdmi); schedule_delayed_work(&work_dispreg_hdmi, msecs_to_jiffies(DISPREG_HDMI_DELAY)); #endif return ret; }
/** * sr_classp5_init() - class p5 init * @sr: SR to init * @class_priv_data: private data for the class (unused) * * we do class specific initialization like creating sysfs/debugfs entries * needed, spawning of a kthread if needed etc. */ static int sr_classp5_init(struct omap_sr *sr, void *class_priv_data) { void **voltdm_cdata = NULL; struct sr_classp5_calib_data *work_data = NULL; if (IS_ERR_OR_NULL(sr) || IS_ERR_OR_NULL(sr->voltdm)) { pr_err("%s: bad parameters!\n", __func__); return -EINVAL; } voltdm_cdata = &sr->voltdm_cdata; if (*voltdm_cdata) { pr_err("%s: ooopps.. class already initialized for %s! bug??\n", __func__, sr->name); return -EINVAL; } /* setup our work params */ work_data = kzalloc(sizeof(struct sr_classp5_calib_data), GFP_KERNEL); if (!work_data) { pr_err("%s: no memory to allocate work data on domain %s\n", __func__, sr->name); return -ENOMEM; } work_data->sr = sr; INIT_DELAYED_WORK_DEFERRABLE(&work_data->work, sr_classp5_calib_work); *voltdm_cdata = (void *)work_data; pm_qos_add_request(&work_data->qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); return 0; }
int omap4_dpll_low_power_cascade_check_entry() { int delay = usecs_to_jiffies(LP_DELAY); INIT_DELAYED_WORK_DEFERRABLE(&lpmode_work, omap4_dpll_low_power_cascade_check_timer); return schedule_delayed_work_on(0, &lpmode_work, delay); }
/*********************************************************** *调频任务初始化 ***********************************************************/ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) { /* We want all CPUs to do sampling nearly on same jiffy */ unsigned long delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); if (NULL == dbs_info) { cpufreq_err("!!!!!!dbs_timer_init!!!!!!error\n"); return; } INIT_DELAYED_WORK_DEFERRABLE(&(dbs_info->work), balong_do_dbs_timer);/*lint !e613*/ schedule_delayed_work_on(dbs_info->cpu, &(dbs_info->work), delay);/*lint !e613*/ }
bool sec_hal_fg_init(struct i2c_client *client) { struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client); mutex_init(&fuelgauge->info.adclock); INIT_DELAYED_WORK_DEFERRABLE(&fuelgauge->info.monitor_work, adc_monitor_work); schedule_delayed_work(&fuelgauge->info.monitor_work, HZ); return true; }
void mlx4_sense_init(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_sense *sense = &priv->sense; int port; sense->dev = dev; for (port = 1; port <= dev->caps.num_ports; port++) sense->do_sense_port[port] = 1; INIT_DELAYED_WORK_DEFERRABLE(&sense->sense_poll, mlx4_sense_port); }
static int __devinit smb347_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int ret, irq_num, i; uint8_t val, buf[15]; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; charger = kzalloc(sizeof(*charger), GFP_KERNEL); if (!charger) return -ENOMEM; charger->client = client; charger->dev = &client->dev; i2c_set_clientdata(client, charger); /* Restore default setting: APSD Enable & 5/1/HC mode Pin control */ smb347_default_setback(); ret = sysfs_create_group(&client->dev.kobj, &smb347_group); if (ret) { dev_err(&client->dev, "smb347_probe: unable to create the sysfs\n"); } mutex_init(&charger->cable_lock); smb347_wq = create_singlethread_workqueue("smb347_wq"); INIT_DELAYED_WORK_DEFERRABLE(&charger->inok_isr_work, inok_isr_work_function); //INIT_DELAYED_WORK(&charger->regs_dump_work, regs_dump_work_func); ret = smb347_inok_irq(charger); if (ret) { dev_err(&client->dev, "%s(): Failed in requesting ACOK# pin isr\n", __func__); goto error; } //queue_delayed_work(smb347_wq, &charger->regs_dump_work, 30*HZ); cable_type_detect(); ret = register_otg_callback( (callback_t)smb347_otg_status, charger); if (ret < 0) goto error; return 0; error: kfree(charger); return ret; }
static int __init init_rq_avg(void) { rq_data = kzalloc(sizeof(struct runqueue_data), GFP_KERNEL); if (rq_data == NULL) { pr_err("%s cannot allocate memory\n", __func__); return -ENOMEM; } spin_lock_init(&rq_data->lock); rq_data->update_rate = RQ_AVG_TIMER_RATE; INIT_DELAYED_WORK_DEFERRABLE(&rq_data->work, rq_work_fn); return 0; }
static __devinit int wm831x_backup_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_backup *devdata; struct power_supply *backup; int ret; int irq = gpio_to_irq(MX53_SMD_DC_DET); devdata = kzalloc(sizeof(struct wm831x_backup), GFP_KERNEL); if (devdata == NULL) return -ENOMEM; devdata->wm831x = wm831x; platform_set_drvdata(pdev, devdata); backup = &devdata->backup; /* We ignore configuration failures since we can still read * back the status without enabling the charger (which may * already be enabled anyway). */ wm831x_config_backup(wm831x); backup->name = "wm831x-backup"; backup->type = POWER_SUPPLY_TYPE_BATTERY; backup->properties = wm831x_backup_props; backup->num_properties = ARRAY_SIZE(wm831x_backup_props); backup->get_property = wm831x_backup_get_prop; ret = power_supply_register(&pdev->dev, backup); if (ret) goto err_kmalloc; wm831x_update_status(irq, devdata); wm831x_get_cap(devdata); INIT_DELAYED_WORK_DEFERRABLE(&devdata->work, wm831x_work); schedule_delayed_work(&devdata->work, WM831X_DELAY); ret = request_irq(irq, wm831x_update_status, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, backup->name, devdata); if (ret != 0) { free_irq(irq, devdata); printk("request irq fail\n"); } return ret; err_kmalloc: kfree(devdata); return ret; }
static void sr_classp5_recal_init(void) { unsigned long delay; INIT_DELAYED_WORK_DEFERRABLE(&recal_work, sr_classp5_recal_work); pm_qos_add_request(&recal_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); delay = msecs_to_jiffies(CONFIG_OMAP_SR_CLASS1_P5_RECALIBRATION_DELAY); schedule_delayed_work(&recal_work, delay); next_recal_time = jiffies + delay; sr_classp5_recal_register_sleep_pm_notifier(); recal_scheduled = true; pr_info("SmartReflex Recalibration delay = %dms\n", CONFIG_OMAP_SR_CLASS1_P5_RECALIBRATION_DELAY); }
int user_init_device(struct fb_info *fb_info) { int i, error = 0; struct omap3epfb_par *par = fb_info->par; fb_info->class_flag |= FB_SYSFS_FLAG_ATTR; mutex_init(&par->area_mutex); for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { error = device_create_file(fb_info->dev, &device_attrs[i]); if (error) break; } if (error) { while (--i >= 0) device_remove_file(fb_info->dev, &device_attrs[i]); fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; } INIT_DELAYED_WORK_DEFERRABLE(&par->lost_update, omap3epfb_lost_update); INIT_DELAYED_WORK_DEFERRABLE(&par->clear_work, omap3epfb_clear_work); INIT_DELAYED_WORK_DEFERRABLE(&par->disable_work, omap3epfb_disable_work); // Start with page flip mode active. par->pgflip_refresh = 1; // Disabled as default. par->clear_delay = 0; par->effect_active = 0; strncpy(par->effect_active_debug, "--------", EFFECT_ARRAY_SIZE); par->effect_active_debug[EFFECT_ARRAY_SIZE] = 0; return 0; }
static int __init auto_hotplug_init(void) { pr_info("auto_hotplug: v0.220 by _thalamus\n"); pr_info("auto_hotplug: %d CPUs detected\n", CPUS_AVAILABLE); INIT_DELAYED_WORK(&hotplug_decision_work, hotplug_decision_work_fn); INIT_DELAYED_WORK_DEFERRABLE(&hotplug_unpause_work, hotplug_unpause_work_fn); INIT_WORK(&hotplug_online_all_work, hotplug_online_all_work_fn); INIT_WORK(&hotplug_online_single_work, hotplug_online_single_work_fn); INIT_WORK(&hotplug_offline_all_work, hotplug_offline_all_work_fn); INIT_DELAYED_WORK_DEFERRABLE(&hotplug_offline_work, hotplug_offline_work_fn); /* * Give the system time to boot before fiddling with hotplugging. */ flags |= HOTPLUG_PAUSED; schedule_delayed_work_on(0, &hotplug_decision_work, HZ * 5); schedule_delayed_work(&hotplug_unpause_work, HZ * 10); #ifdef CONFIG_HAS_EARLYSUSPEND register_early_suspend(&auto_hotplug_suspend); #endif return 0; }
bool sec_hal_fg_init(struct i2c_client *client) { struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client); fuelgauge->info.last_vcell_check_time.tv_sec = 0; fuelgauge->info.is_init = 2; adc_get_reset_percentage(fuelgauge); mutex_init(&fuelgauge->info.adclock); INIT_DELAYED_WORK_DEFERRABLE(&fuelgauge->info.monitor_work, adc_monitor_work); schedule_delayed_work(&fuelgauge->info.monitor_work, HZ); return true; }
int hardlimit_init(void) { #ifdef CPUFREQ_HARDLIMIT_LEGACY_INTERFACE int legacy_hardlimit_retval; #endif int hardlimit_retval; /* Enable the legacy sysfs interface */ #ifdef CPUFREQ_HARDLIMIT_LEGACY_INTERFACE legacy_hardlimit_kobj = kobject_create_and_add("cpufreq", kernel_kobj); if (!legacy_hardlimit_kobj) { return -ENOMEM; } legacy_hardlimit_retval = sysfs_create_group(legacy_hardlimit_kobj, &legacy_hardlimit_attr_group); if (legacy_hardlimit_retval) kobject_put(legacy_hardlimit_kobj); #endif /* Enable the new sysfs interface */ hardlimit_kobj = kobject_create_and_add("cpufreq_hardlimit", kernel_kobj); if (!hardlimit_kobj) { return -ENOMEM; } hardlimit_retval = sysfs_create_group(hardlimit_kobj, &hardlimit_attr_group); if (hardlimit_retval) kobject_put(hardlimit_kobj); #ifdef CPUFREQ_HARDLIMIT_LEGACY_INTERFACE if (!hardlimit_retval && !legacy_hardlimit_retval) { #else if (!hardlimit_retval) { #endif /* Only register to powersuspend and delayed work if we were able to create the sysfs interface */ register_power_suspend(&cpufreq_hardlimit_suspend_data); INIT_DELAYED_WORK_DEFERRABLE(&stop_wakeup_kick_work, stop_wakeup_kick); } return (hardlimit_retval); } /* end sysfs interface */ void hardlimit_exit(void) { unregister_power_suspend(&cpufreq_hardlimit_suspend_data); kobject_put(hardlimit_kobj); }
static __devinit int sec_therm_probe(struct platform_device *pdev) { int ret = 0; struct sec_therm_platform_data *pdata = fill_therm_pdata(pdev); struct sec_therm_info *info; dev_info(&pdev->dev, "%s: SEC Thermistor Driver Loading\n", __func__); info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; info->dev = &pdev->dev; info->pdata = pdata; info->vadc_dev = qpnp_get_vadc(info->dev, "therm"); therm_vadc_dev = info->vadc_dev; if (IS_ERR(info->vadc_dev)) { ret = PTR_ERR(info->vadc_dev); pr_err("%s:ret=%d\n",__func__,ret); if (ret != -EPROBE_DEFER) pr_err("vadc property missing\n"); else goto err_therm; } dev_set_drvdata(&pdev->dev, info); ret = sysfs_create_group(&info->dev->kobj, &sec_therm_group); if (ret) { dev_err(info->dev, "failed to create sysfs attribute group\n"); } if (!(pdata->no_polling)) { INIT_DELAYED_WORK_DEFERRABLE(&info->polling_work, sec_therm_polling_work); schedule_delayed_work(&info->polling_work, msecs_to_jiffies(info->pdata->polling_interval)); } return ret; err_therm: kfree(info); return ret; }
int mlx4_sense_init(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_sense *sense = &priv->sense; int port; sense->dev = dev; sense->sense_wq = create_singlethread_workqueue("mlx4_sense"); if (!sense->sense_wq) return -ENOMEM; for (port = 1; port <= dev->caps.num_ports; port++) sense->do_sense_port[port] = 1; INIT_DELAYED_WORK_DEFERRABLE(&sense->sense_poll, mlx4_sense_port); return 0; }
static int __init pantech_debug_opt_init(void) { int rc; printk(KERN_ERR "%s is called\n", __func__); rc = platform_driver_register(&pantech_debug_opt_driver); if (rc < 0) { printk(KERN_ERR "%s: platform_driver_register rc = %d\n", __func__, rc); } INIT_DELAYED_WORK_DEFERRABLE(&pantech_debug_work, pantech_debug_work_init); schedule_delayed_work(&pantech_debug_work, 700); return rc; }
/* To create a bunch of /sys entries for DFMS application. We need a dummy power supply so we can have an entry /sys/class/power_supply without breaking all the for_each_class calls in the rest of the charging. We also attach a dummy device to the sec device class device can be part of the /sys/devices/virtual/sec path */ int make_dfms_battery_device (void) { charger_extra_sysfs.polling_queue = create_singlethread_workqueue("ab8500_charging_monitor"); INIT_DELAYED_WORK_DEFERRABLE(&charger_extra_sysfs.polling_work,ab8500_charger_polling_periodic_work); charger_extra_sysfs.btemp_psy.name = "battery"; charger_extra_sysfs.btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY; charger_extra_sysfs.btemp_psy.properties = ab8500_battery_props; charger_extra_sysfs.btemp_psy.num_properties = ARRAY_SIZE(ab8500_battery_props); charger_extra_sysfs.btemp_psy.get_property = battery_get_property; charger_extra_sysfs.btemp_psy.supplied_to = ab8500_battery_supplied_to; charger_extra_sysfs.btemp_psy.num_supplicants = ARRAY_SIZE(ab8500_battery_supplied_to); charger_extra_sysfs.btemp_psy.external_power_changed =battery_power_changed; power_supply_register( NULL, &charger_extra_sysfs.btemp_psy) ; add_adc_attributes(charger_extra_sysfs.btemp_psy.dev ) ; add_average_attributes(charger_extra_sysfs.btemp_psy.dev ) ; add_misc_attributes(charger_extra_sysfs.btemp_psy.dev); add_callback_attributes(charger_extra_sysfs.btemp_psy.dev); add_power_supply_attributes(charger_extra_sysfs.btemp_psy.dev ); return 0 ; }
/******************************* * kernel module init function ********************************/ static int __init mt_hotplug_mechanism_init(void) { struct proc_dir_entry *entry = NULL; struct proc_dir_entry *mt_hotplug_dir = NULL; HOTPLUG_INFO("mt_hotplug_mechanism_init"); mt_hotplug_dir = proc_mkdir("mt_hotplug", NULL); if (!mt_hotplug_dir) { HOTPLUG_INFO("mkdir /proc/mt_hotplug failed"); } else { entry = create_proc_entry("test0", S_IRUGO | S_IWUSR, mt_hotplug_dir); if (entry) { entry->read_proc = mt_hotplug_mechanism_read_test0; entry->write_proc = mt_hotplug_mechanism_write_test0; } entry = create_proc_entry("test1", S_IRUGO | S_IWUSR, mt_hotplug_dir); if (entry) { entry->read_proc = mt_hotplug_mechanism_read_test1; entry->write_proc = mt_hotplug_mechanism_write_test1; } } #ifdef CONFIG_HAS_EARLYSUSPEND mt_hotplug_mechanism_early_suspend_handler.suspend = mt_hotplug_mechanism_early_suspend; mt_hotplug_mechanism_early_suspend_handler.resume = mt_hotplug_mechanism_late_resume; register_early_suspend(&mt_hotplug_mechanism_early_suspend_handler); INIT_DELAYED_WORK_DEFERRABLE(&hotplug_delayed_work, hotplug_delayed_work_handler); wake_lock_init(&hotplug_wake_lock, WAKE_LOCK_SUSPEND, "hotplug"); #endif //#ifdef CONFIG_HAS_EARLYSUSPEND return 0; }
static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct max17047_fuelgauge_data *fg_data; int ret; u8 i2c_data[2]; int rawsoc, firstsoc; pr_info("%s: max17047 Fuel gauge Driver Loading\n", __func__); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; fg_data = kzalloc(sizeof(struct max17047_fuelgauge_data), GFP_KERNEL); if (!fg_data) return -ENOMEM; fg_data->client = client; fg_data->pdata = client->dev.platform_data; i2c_set_clientdata(client, fg_data); mutex_init(&fg_data->irq_lock); wake_lock_init(&fg_data->update_wake_lock, WAKE_LOCK_SUSPEND, "fuel-update"); /* Initialize full_soc, set this before fisrt SOC reading */ fg_data->full_soc = FULL_SOC_DEFAULT; /* first full_soc update */ rawsoc = max17047_get_rawsoc(fg_data->client); if (rawsoc > FULL_SOC_DEFAULT) max17047_adjust_fullsoc(client); firstsoc = max17047_get_soc(client); pr_info("%s: rsoc=%d, fsoc=%d, soc=%d\n", __func__, rawsoc, fg_data->full_soc, firstsoc); if (fg_data->pdata->psy_name) fg_data->fuelgauge.name = fg_data->pdata->psy_name; else fg_data->fuelgauge.name = "max17047-fuelgauge"; fg_data->fuelgauge.type = POWER_SUPPLY_TYPE_BATTERY; fg_data->fuelgauge.properties = max17047_fuelgauge_props; fg_data->fuelgauge.num_properties = ARRAY_SIZE(max17047_fuelgauge_props); fg_data->fuelgauge.get_property = max17047_get_property; fg_data->fuelgauge.set_property = max17047_set_property; ret = power_supply_register(&client->dev, &fg_data->fuelgauge); if (ret) { pr_err("%s: failed power supply register\n", __func__); goto err_psy_reg_fg; } /* Initialize fuelgauge registers */ max17047_reg_init(fg_data); /* Initialize fuelgauge alert */ max17047_alert_init(fg_data); /* Request IRQ */ fg_data->irq = gpio_to_irq(fg_data->pdata->irq_gpio); ret = gpio_request(fg_data->pdata->irq_gpio, "fuelgauge-irq"); if (ret) { pr_err("%s: failed requesting gpio %d\n", __func__, fg_data->pdata->irq_gpio); goto err_irq; } gpio_direction_input(fg_data->pdata->irq_gpio); gpio_free(fg_data->pdata->irq_gpio); ret = request_threaded_irq(fg_data->irq, NULL, max17047_fuelgauge_isr, IRQF_TRIGGER_FALLING, "max17047-alert", fg_data); if (ret < 0) { pr_err("%s: fail to request max17047 irq: %d: %d\n", __func__, fg_data->irq, ret); goto err_irq; } ret = enable_irq_wake(fg_data->irq); if (ret < 0) { pr_err("%s: failed enable irq wake %d\n", __func__, fg_data->irq); goto err_enable_irq; } INIT_DELAYED_WORK_DEFERRABLE(&fg_data->update_work, max17047_update_work); #ifdef DEBUG_FUELGAUGE_POLLING INIT_DELAYED_WORK_DEFERRABLE(&fg_data->polling_work, max17047_polling_work); schedule_delayed_work(&fg_data->polling_work, 0); #else max17047_test_read(fg_data); #endif max17047_i2c_read(client, MAX17047_REG_VERSION, i2c_data); pr_info("max17047 fuelgauge(rev.%d%d) initialized.\n", i2c_data[0], i2c_data[1]); #if defined(CONFIG_TARGET_LOCALE_KOR) #ifdef CONFIG_DEBUG_FS fg_data->fg_debugfs_dir = debugfs_create_dir("fg_debug", NULL); if (fg_data->fg_debugfs_dir) { if (!debugfs_create_file("max17047_regs", 0644, fg_data->fg_debugfs_dir, fg_data, &max17047_debugfs_fops)) pr_err("%s : debugfs_create_file, error\n", __func__); if (!debugfs_create_file("default_data", 0644, fg_data->fg_debugfs_dir, fg_data, &max17047_debugfs_fops2)) pr_err("%s : debugfs_create_file2, error\n", __func__); } else pr_err("%s : debugfs_create_dir, error\n", __func__); #endif #endif return 0; err_enable_irq: free_irq(fg_data->irq, fg_data); err_irq: power_supply_unregister(&fg_data->fuelgauge); err_psy_reg_fg: wake_lock_destroy(&fg_data->update_wake_lock); mutex_destroy(&fg_data->irq_lock); kfree(fg_data); return ret; }
static int __init rmnet_init(void) { int ret; struct device *d; struct net_device *dev; struct rmnet_private *p; unsigned n; #ifdef CONFIG_MSM_RMNET_DEBUG timeout_us = 0; #ifdef CONFIG_HAS_EARLYSUSPEND timeout_suspend_us = 0; #endif #endif #ifdef CONFIG_MSM_RMNET_DEBUG rmnet_wq = create_workqueue("rmnet"); #endif for (n = 0; n < 3; n++) { dev = alloc_netdev(sizeof(struct rmnet_private), "rmnet%d", rmnet_setup); if (!dev) return -ENOMEM; d = &(dev->dev); p = netdev_priv(dev); p->chname = ch_name[n]; wake_lock_init(&p->wake_lock, WAKE_LOCK_SUSPEND, ch_name[n]); #ifdef CONFIG_MSM_RMNET_DEBUG p->timeout_us = timeout_us; p->awake_time_ms = p->wakeups_xmit = p->wakeups_rcv = 0; p->active_countdown = p->restart_count = 0; INIT_DELAYED_WORK_DEFERRABLE(&p->work, do_check_active); #endif ret = register_netdev(dev); if (ret) { free_netdev(dev); return ret; } #ifdef CONFIG_MSM_RMNET_DEBUG if (device_create_file(d, &dev_attr_timeout)) continue; if (device_create_file(d, &dev_attr_wakeups_xmit)) continue; if (device_create_file(d, &dev_attr_wakeups_rcv)) continue; if (device_create_file(d, &dev_attr_awake_time_ms)) continue; #ifdef CONFIG_HAS_EARLYSUSPEND if (device_create_file(d, &dev_attr_timeout_suspend)) continue; /* Only care about rmnet0 for suspend/resume tiemout hooks. */ if (n == 0) rmnet0 = d; #endif #endif } return 0; }
static int __devinit sec_fuelgauge_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct sec_fuelgauge_info *fuelgauge; int ret = 0; bool fuelalert_init_ret = false; union power_supply_propval raw_soc_val; dev_dbg(&client->dev, "%s: SEC Fuelgauge Driver Loading\n", __func__); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; fuelgauge = kzalloc(sizeof(*fuelgauge), GFP_KERNEL); if (!fuelgauge) return -ENOMEM; mutex_init(&fuelgauge->fg_lock); fuelgauge->client = client; fuelgauge->pdata = client->dev.platform_data; i2c_set_clientdata(client, fuelgauge); fuelgauge->psy_fg.name = "sec-fuelgauge"; fuelgauge->psy_fg.type = POWER_SUPPLY_TYPE_UNKNOWN; fuelgauge->psy_fg.get_property = sec_fg_get_property; fuelgauge->psy_fg.set_property = sec_fg_set_property; fuelgauge->psy_fg.properties = sec_fuelgauge_props; fuelgauge->psy_fg.num_properties = ARRAY_SIZE(sec_fuelgauge_props); fuelgauge->capacity_max = fuelgauge->pdata->capacity_max; raw_soc_val.intval = SEC_FUELGAUGE_CAPACITY_TYPE_RAW; sec_hal_fg_get_property(fuelgauge->client, POWER_SUPPLY_PROP_CAPACITY, &raw_soc_val); raw_soc_val.intval /= 10; if(raw_soc_val.intval > fuelgauge->pdata->capacity_max) sec_fg_calculate_dynamic_scale(fuelgauge); if (!fuelgauge->pdata->fg_gpio_init()) { dev_err(&client->dev, "%s: Failed to Initialize GPIO\n", __func__); goto err_free; } if (!sec_hal_fg_init(fuelgauge->client)) { dev_err(&client->dev, "%s: Failed to Initialize Fuelgauge\n", __func__); goto err_free; } ret = power_supply_register(&client->dev, &fuelgauge->psy_fg); if (ret) { dev_err(&client->dev, "%s: Failed to Register psy_fg\n", __func__); goto err_free; } if (fuelgauge->pdata->fg_irq) { INIT_DELAYED_WORK_DEFERRABLE( &fuelgauge->isr_work, sec_fg_isr_work); ret = request_threaded_irq(fuelgauge->pdata->fg_irq, NULL, sec_fg_irq_thread, fuelgauge->pdata->fg_irq_attr, "fuelgauge-irq", fuelgauge); if (ret) { dev_err(&client->dev, "%s: Failed to Reqeust IRQ\n", __func__); goto err_supply_unreg; } ret = enable_irq_wake(fuelgauge->pdata->fg_irq); if (ret < 0) dev_err(&client->dev, "%s: Failed to Enable Wakeup Source(%d)\n", __func__, ret); } fuelgauge->is_fuel_alerted = false; if (fuelgauge->pdata->fuel_alert_soc >= 0) { fuelalert_init_ret = sec_hal_fg_fuelalert_init(fuelgauge->client, fuelgauge->pdata->fuel_alert_soc); if (fuelalert_init_ret) wake_lock_init(&fuelgauge->fuel_alert_wake_lock, WAKE_LOCK_SUSPEND, "fuel_alerted"); else { dev_err(&client->dev, "%s: Failed to Initialize Fuel-alert\n", __func__); goto err_irq; } } fuelgauge->initial_update_of_soc = true; ret = sec_fg_create_attrs(fuelgauge->psy_fg.dev); if (ret) { dev_err(&client->dev, "%s : Failed to create_attrs\n", __func__); goto err_irq; } dev_dbg(&client->dev, "%s: SEC Fuelgauge Driver Loaded\n", __func__); return 0; err_irq: if (fuelgauge->pdata->fg_irq) free_irq(fuelgauge->pdata->fg_irq, fuelgauge); if (fuelalert_init_ret) wake_lock_destroy(&fuelgauge->fuel_alert_wake_lock); err_supply_unreg: power_supply_unregister(&fuelgauge->psy_fg); err_free: mutex_destroy(&fuelgauge->fg_lock); kfree(fuelgauge); return ret; }
static irqreturn_t tmu_irq(int irq, void *id) { struct tmu_info *info = id; unsigned int status; disable_irq_nosync(irq); status = __raw_readl(info->tmu_base + INTSTAT); /* To handle multiple interrupt pending, * interrupt by high temperature are serviced with priority. */ #if defined(CONFIG_TC_VOLTAGE) if (status & INTSTAT_FALL0) { pr_info("TC interrupt occured..!\n"); __raw_writel(INTCLEAR_FALL0, info->tmu_base + INTCLEAR); info->tmu_state = TMU_STATUS_TC; } else if (status & INTSTAT_RISE2) { #else if (status & INTSTAT_RISE2) { #endif pr_info("Tripping interrupt occured..!\n"); info->tmu_state = TMU_STATUS_TRIPPED; __raw_writel(INTCLEAR_RISE2, info->tmu_base + INTCLEAR); } else if (status & INTSTAT_RISE1) { pr_info("Warning interrupt occured..!\n"); __raw_writel(INTCLEAR_RISE1, info->tmu_base + INTCLEAR); info->tmu_state = TMU_STATUS_WARNING; } else if (status & INTSTAT_RISE0) { pr_info("Throttling interrupt occured..!\n"); __raw_writel(INTCLEAR_RISE0, info->tmu_base + INTCLEAR); info->tmu_state = TMU_STATUS_THROTTLED; } else { pr_err("%s: TMU interrupt error\n", __func__); return -ENODEV; } queue_delayed_work_on(0, tmu_monitor_wq, &info->polling, usecs_to_jiffies(1 * 1000)); return IRQ_HANDLED; } static irqreturn_t exynos4210_tmu_irq(int irq, void *id) { struct tmu_info *info = id; unsigned int status; disable_irq_nosync(irq); status = __raw_readl(info->tmu_base + INTSTAT); if (status & INTSTAT2) { pr_info("Tripping interrupt occured..!\n"); info->tmu_state = TMU_STATUS_TRIPPED; __raw_writel(INTCLEAR2, info->tmu_base + INTCLEAR); } else if (status & INTSTAT1) { pr_info("Warning interrupt occured..!\n"); __raw_writel(INTCLEAR1, info->tmu_base + INTCLEAR); info->tmu_state = TMU_STATUS_WARNING; } else if (status & INTSTAT0) { pr_info("Throttling interrupt occured..!\n"); __raw_writel(INTCLEAR0, info->tmu_base + INTCLEAR); info->tmu_state = TMU_STATUS_THROTTLED; } else { pr_err("%s: TMU interrupt error\n", __func__); return -ENODEV; } queue_delayed_work_on(0, tmu_monitor_wq, &info->polling, usecs_to_jiffies(1000)); return IRQ_HANDLED; } static int __devinit tmu_probe(struct platform_device *pdev) { struct tmu_info *info; struct resource *res; int ret = 0; pr_debug("%s: probe=%p\n", __func__, pdev); info = kzalloc(sizeof(struct tmu_info), GFP_KERNEL); if (!info) { dev_err(&pdev->dev, "failed to alloc memory!\n"); ret = -ENOMEM; goto err_nomem; } pr_emerg("TMU: Memory Allocation Sucessful\n"); platform_set_drvdata(pdev, info); pr_emerg("TMU: Platform data set\n"); info->dev = &pdev->dev; pr_emerg("TMU: Copied the Dev access Information \n"); info->irq = platform_get_irq(pdev, 0); if (info->irq < 0) { dev_err(&pdev->dev, "no irq for thermal\n"); ret = -ENOENT; goto err_noirq; } if (soc_is_exynos4210()) ret = request_irq(info->irq, exynos4210_tmu_irq, IRQF_DISABLED, "tmu interrupt", info); else ret = request_irq(info->irq, tmu_irq, IRQF_DISABLED, "tmu interrupt", info); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq, ret); goto err_noirq; } pr_emerg("TMU: IRQ Granted!\n"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get memory region resource\n"); ret = -ENODEV; goto err_nores; } pr_emerg("TMU: IO Resource alloced on Memory\n"); info->ioarea = request_mem_region(res->start, res->end-res->start+1, pdev->name); if (!(info->ioarea)) { dev_err(&pdev->dev, "failed to reserve memory region\n"); ret = -EBUSY; goto err_nores; } pr_emerg("TMU: Memory area resersed\n"); info->tmu_base = ioremap(res->start, (res->end - res->start) + 1); if (!(info->tmu_base)) { dev_err(&pdev->dev, "failed ioremap()\n"); ret = -EINVAL; goto err_nomap; } pr_emerg("TMU: IO Memory Remapped\n"); if (thermal_create_sysfs_file(&pdev->dev)) goto err_sysfs; pr_emerg("TMU: Created Sysfs\n"); tmu_monitor_wq = create_freezable_workqueue("tmu"); if (!tmu_monitor_wq) { dev_err(&pdev->dev, "Creation of tmu_monitor_wq failed\n"); ret = -EFAULT; goto err_wq; } pr_emerg("TMU: Workqueue Created\n"); INIT_DELAYED_WORK_DEFERRABLE(&info->polling, tmu_monitor); pr_emerg("TMU: Work Created\n"); #ifdef CONFIG_TMU_DEBUG INIT_DELAYED_WORK_DEFERRABLE(&info->monitor, cur_temp_monitor); #endif print_temperature_params(info); pr_emerg("TMU: Printed Parameters\n"); ret = tmu_initialize(pdev); if (ret < 0) goto err_noinit; #ifdef CONFIG_TMU_DEBUG queue_delayed_work_on(0, tmu_monitor_wq, &info->monitor, info->sampling_rate); #endif pr_info("Tmu Initialization is sucessful...!\n"); return ret; err_noinit: destroy_workqueue(tmu_monitor_wq); err_wq: thermal_remove_sysfs_file(&pdev->dev); err_sysfs: iounmap(info->tmu_base); err_nomap: release_resource(info->ioarea); err_nores: free_irq(info->irq, info); err_noirq: kfree(info); info = NULL; err_nomem: dev_err(&pdev->dev, "initialization failed.\n"); return ret; } static int __devinit tmu_remove(struct platform_device *pdev) { struct tmu_info *info = platform_get_drvdata(pdev); cancel_delayed_work(&info->polling); destroy_workqueue(tmu_monitor_wq); thermal_remove_sysfs_file(&pdev->dev); iounmap(info->tmu_base); release_resource(info->ioarea); free_irq(info->irq, (void *)pdev); kfree(info); info = NULL; pr_info("%s is removed\n", dev_name(&pdev->dev)); return 0; } #ifdef CONFIG_PM static int tmu_suspend(struct platform_device *pdev, pm_message_t state) { struct tmu_info *info = platform_get_drvdata(pdev); pm_tmu_save(info); return 0; } static int tmu_resume(struct platform_device *pdev) { struct tmu_info *info = platform_get_drvdata(pdev); #if defined(CONFIG_TC_VOLTAGE) struct tmu_data *data = info->dev->platform_data; #endif pm_tmu_restore(info); #if defined(CONFIG_TC_VOLTAGE) /* s/w workaround for fast service when interrupt is not occured, * such as current temp is lower than tc interrupt temperature * or current temp is continuosly increased. */ mdelay(1); if (get_cur_temp(info) <= data->ts.start_tc) { disable_irq_nosync(info->irq); if (exynos_tc_volt(info, 1) < 0) pr_err("%s\n", __func__); info->tmu_state = TMU_STATUS_TC; already_limit = 1; queue_delayed_work_on(0, tmu_monitor_wq, &info->polling, usecs_to_jiffies(1 * 1000)); } #endif return 0; } #else #define tmu_suspend NULL #define tmu_resume NULL #endif static struct platform_driver tmu_driver = { .probe = tmu_probe, .remove = tmu_remove, .suspend = tmu_suspend, .resume = tmu_resume, .driver = { .name = "tmu", .owner = THIS_MODULE, }, }; static int __init tmu_driver_init(void) { return platform_driver_register(&tmu_driver); } late_initcall(tmu_driver_init);
static __devinit int max8903_probe(struct platform_device *pdev) { struct max8903_data *data; struct max8903_data *ac_data; struct device *dev = &pdev->dev; struct max8903_pdata *pdata = pdev->dev.platform_data; int ret = 0; int gpio = 0; int ta_in = 0; int usb_in = 0; int error; data = kzalloc(sizeof(struct max8903_data), GFP_KERNEL); if (data == NULL) { dev_err(dev, "Cannot allocate memory.\n"); return -ENOMEM; } data->pdata = pdata; data->dev = dev; platform_set_drvdata(pdev, data); if (pdata->dc_valid == false && pdata->usb_valid == false) { dev_err(dev, "No valid power sources.\n"); ret = -EINVAL; goto err; } if (pdata->dc_valid) { if (pdata->dok && gpio_is_valid(pdata->dok) && pdata->dcm && gpio_is_valid(pdata->dcm)) { gpio = pdata->dok; /* PULL_UPed Interrupt */ ta_in = gpio_get_value(gpio) ? 0 : 1; gpio = pdata->dcm; /* Output */ gpio_set_value(gpio, ta_in); } else if (pdata->dok && gpio_is_valid(pdata->dok) && pdata->dcm_always_high) { gpio = pdata->dok; /* PULL_UPed Interrupt */ error = gpio_request(gpio, "chg_dc"); if (error < 0) { dev_err(dev, "failed to configure" " request/direction for GPIO %d, error %d\n", gpio, error); goto err; } gpio_direction_input(gpio); ta_in = gpio_get_value(gpio) ? 0 : 1; if (ta_in) data->ta_in = true; else data->ta_in = false; } else { dev_err(dev, "When DC is wired, DOK and DCM should" " be wired as well." " or set dcm always high\n"); ret = -EINVAL; goto err; } } else { if (pdata->dcm) { if (gpio_is_valid(pdata->dcm)) gpio_set_value(pdata->dcm, 0); else { dev_err(dev, "Invalid pin: dcm.\n"); ret = -EINVAL; goto err; } } } if (pdata->usb_valid) { if (pdata->uok && gpio_is_valid(pdata->uok)) { gpio = pdata->uok; error = gpio_request(gpio, "chg_usb"); if (error < 0) { dev_err(dev, "failed to configure" " request/direction for GPIO %d, error %d\n", gpio, error); goto err; } gpio_direction_input(gpio); usb_in = gpio_get_value(gpio) ? 0 : 1; if (usb_in) data->usb_in = true; else data->usb_in = false; } else { dev_err(dev, "When USB is wired, UOK should be wired." "as well.\n"); ret = -EINVAL; goto err; } } if (pdata->cen) { if (gpio_is_valid(pdata->cen)) { gpio_set_value(pdata->cen, (ta_in || usb_in) ? 0 : 1); } else { dev_err(dev, "Invalid pin: cen.\n"); ret = -EINVAL; goto err; } } if (pdata->chg) { if (!gpio_is_valid(pdata->chg)) { dev_err(dev, "Invalid pin: chg.\n"); ret = -EINVAL; goto err; } error = gpio_request(pdata->chg, "chg_status"); if (error < 0) { dev_err(dev, "failed to configure" " request/direction for GPIO %d, error %d\n", pdata->chg, error); goto err; } error = gpio_direction_input(pdata->chg); } if (pdata->flt) { if (!gpio_is_valid(pdata->flt)) { dev_err(dev, "Invalid pin: flt.\n"); ret = -EINVAL; goto err; } error = gpio_request(pdata->flt, "chg_fault"); if (error < 0) { dev_err(dev, "failed to configure" " request/direction for GPIO %d, error %d\n", pdata->flt, error); goto err; } error = gpio_direction_input(pdata->flt); } if (pdata->usus) { if (!gpio_is_valid(pdata->usus)) { dev_err(dev, "Invalid pin: usus.\n"); ret = -EINVAL; goto err; } } data->fault = false; data->ta_in = ta_in; data->usb_in = usb_in; data->acpsy.name = "max8903-ac"; data->acpsy.type = POWER_SUPPLY_TYPE_MAINS; data->acpsy.get_property = max8903_get_ac_property; data->acpsy.properties = max8903_ac_props; data->acpsy.num_properties = ARRAY_SIZE(max8903_ac_props); ret = power_supply_register(dev, &data->acpsy); if (ret) { dev_err(dev, "failed: power supply register.\n"); goto err; } data->psy.name = "max8903-charger"; data->psy.type = POWER_SUPPLY_TYPE_BATTERY; data->psy.get_property = max8903_get_property; data->psy.properties = max8903_charger_props; data->psy.num_properties = ARRAY_SIZE(max8903_charger_props); ret = power_supply_register(dev, &data->psy); if (ret) { dev_err(dev, "failed: power supply register.\n"); goto err; } if (pdata->dc_valid) { ret = request_threaded_irq(gpio_to_irq(pdata->dok), NULL, max8903_dcin, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "MAX8903 DC IN", data); if (ret) { dev_err(dev, "Cannot request irq %d for DC (%d)\n", gpio_to_irq(pdata->dok), ret); goto err_psy; } } if (pdata->usb_valid) { ret = request_threaded_irq(gpio_to_irq(pdata->uok), NULL, max8903_usbin, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "MAX8903 USB IN", data); if (ret) { dev_err(dev, "Cannot request irq %d for USB (%d)\n", gpio_to_irq(pdata->uok), ret); goto err_dc_irq; } } if (pdata->flt) { ret = request_threaded_irq(gpio_to_irq(pdata->flt), NULL, max8903_fault, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "MAX8903 Fault", data); if (ret) { dev_err(dev, "Cannot request irq %d for Fault (%d)\n", gpio_to_irq(pdata->flt), ret); goto err_usb_irq; } } /* should remove this if capacity is supported */ data->cap = 90; INIT_DELAYED_WORK_DEFERRABLE(&data->work, max8903_work); power_supply_changed(&data->psy); power_supply_changed(&data->acpsy); schedule_delayed_work(&data->work, MAX8903_DELAY); return 0; err_usb_irq: if (pdata->usb_valid) free_irq(gpio_to_irq(pdata->uok), data); err_dc_irq: if (pdata->dc_valid) free_irq(gpio_to_irq(pdata->dok), data); err_psy: power_supply_unregister(&data->psy); power_supply_unregister(&data->acpsy); err: if (pdata->uok) gpio_free(pdata->uok); if (pdata->dok) gpio_free(pdata->dok); if (pdata->flt) gpio_free(pdata->flt); if (pdata->chg) gpio_free(pdata->chg); kfree(data); return ret; }