void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend) { unsigned long up_delay, top_freq, bottom_freq; if (!is_g_cluster_present()) return; if (hp_state == TEGRA_HP_DISABLED) return; if (suspend) { hp_state = TEGRA_HP_IDLE; /* Switch to G-mode if suspend rate is high enough */ if (is_lp_cluster() && (cpu_freq >= idle_bottom_freq)) { if (!clk_set_parent(cpu_clk, cpu_g_clk)) { hp_stats_update(CONFIG_NR_CPUS, false); hp_stats_update(0, true); } } return; } if (is_lp_cluster()) { up_delay = up2g0_delay; top_freq = idle_top_freq; bottom_freq = 0; } else { up_delay = up2gn_delay; top_freq = idle_bottom_freq; bottom_freq = idle_bottom_freq; } if (pm_qos_request(PM_QOS_MIN_ONLINE_CPUS) >= 2) { if (hp_state != TEGRA_HP_UP) { hp_state = TEGRA_HP_UP; queue_delayed_work( hotplug_wq, &hotplug_work, up_delay); } return; } switch (hp_state) { case TEGRA_HP_IDLE: if (cpu_freq > top_freq) { hp_state = TEGRA_HP_UP; queue_delayed_work( hotplug_wq, &hotplug_work, up_delay); } else if (cpu_freq <= bottom_freq) { hp_state = TEGRA_HP_DOWN; queue_delayed_work( hotplug_wq, &hotplug_work, down_delay); } break; case TEGRA_HP_DOWN: if (cpu_freq > top_freq) { hp_state = TEGRA_HP_UP; queue_delayed_work( hotplug_wq, &hotplug_work, up_delay); } else if (cpu_freq > bottom_freq) { hp_state = TEGRA_HP_IDLE; } break; case TEGRA_HP_UP: if (cpu_freq <= bottom_freq) { hp_state = TEGRA_HP_DOWN; queue_delayed_work( hotplug_wq, &hotplug_work, down_delay); } else if (cpu_freq <= top_freq) { hp_state = TEGRA_HP_IDLE; } break; default: pr_err("%s: invalid tegra hotplug state %d\n", __func__, hp_state); BUG(); } }
static void panel_esd_start_check(struct mipi_dsi_data *dsi_data) { queue_delayed_work(dsi_data->esd_wq, &dsi_data->esd_work, PANEL_ESD_CHECK_PERIOD); }
extern void pm8058_drvx_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct pm8058_led_data *ldata; int *pduties; int id, mode; int lut_flag; int milliamps; int enable = 0; ldata = container_of(led_cdev, struct pm8058_led_data, ldev); pwm_disable(ldata->pwm_led); cancel_delayed_work_sync(&ldata->led_delayed_work); id = bank_to_id(ldata->bank); mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 : PM_PWM_CONF_PWM1 + (ldata->bank - 4); brightness = (brightness > LED_FULL) ? LED_FULL : brightness; brightness = (brightness < LED_OFF) ? LED_OFF : brightness; LED_INFO_LOG("%s: bank %d brightness %d +\n", __func__, ldata->bank, brightness); enable = (brightness) ? 1 : 0; if (strcmp(ldata->ldev.name, "charming-led") == 0) charming_led_enable(enable); lut_flag = ldata->lut_flag & ~(PM_PWM_LUT_LOOP | PM_PWM_LUT_REVERSE); if (brightness) { milliamps = (ldata->flags & PM8058_LED_DYNAMIC_BRIGHTNESS_EN) ? ldata->out_current * brightness / LED_FULL : ldata->out_current; printk(KERN_INFO "%s: flags %d current %d\n", __func__, ldata->flags, milliamps); pm8058_pwm_config_led(ldata->pwm_led, id, mode, milliamps); if (ldata->flags & PM8058_LED_LTU_EN) { pduties = &duties[ldata->start_index]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index, ldata->duites_size, 0, 0, lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 0); pm8058_pwm_lut_enable(ldata->pwm_led, 1); } else { pwm_config(ldata->pwm_led, 64000, 64000); pwm_enable(ldata->pwm_led); } } else { if (ldata->flags & PM8058_LED_LTU_EN) { wake_lock(&pmic_led_wake_lock); pduties = &duties[ldata->start_index + ldata->duites_size]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index + ldata->duites_size, ldata->duites_size, 0, 0, lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 1); queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(ldata->duty_time_ms * ldata->duty_time_ms)); LED_INFO_LOG("%s: bank %d fade out brightness %d -\n", __func__, ldata->bank, brightness); return; } else pwm_disable(ldata->pwm_led); pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); } LED_INFO_LOG("%s: bank %d brightness %d -\n", __func__, ldata->bank, brightness); }
static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct ieee80211_conf *conf = &hw->conf; if (mac->skip_scan) return 1; mutex_lock(&rtlpriv->locks.conf_mutex); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /* BIT(2) */ RT_TRACE(COMP_MAC80211, DBG_LOUD, ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n")); } /*For IPS */ if (changed & IEEE80211_CONF_CHANGE_IDLE) { if (hw->conf.flags & IEEE80211_CONF_IDLE) rtl_ips_nic_off(hw); else rtl_ips_nic_on(hw); } else { /* *although rfoff may not cause by ips, but we will *check the reason in set_rf_power_state function */ if (unlikely(ppsc->rfpwr_state == ERFOFF)) rtl_ips_nic_on(hw); } /*For LPS */ if (changed & IEEE80211_CONF_CHANGE_PS) { cancel_delayed_work(&rtlpriv->works.ps_work); cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); if (conf->flags & IEEE80211_CONF_PS) { rtlpriv->psc.sw_ps_enabled = true; /* sleep here is must, or we may recv the beacon and * cause mac80211 into wrong ps state, this will cause * power save nullfunc send fail, and further cause * pkt loss, So sleep must quickly but not immediately * because that will cause nullfunc send by mac80211 * fail, and cause pkt loss, we have tested that 5mA * is worked very well */ if (!rtlpriv->psc.multi_buffered) queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); } else { rtl_swlps_rf_awake(hw); rtlpriv->psc.sw_ps_enabled = false; } } if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { RT_TRACE(COMP_MAC80211, DBG_LOUD, ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", hw->conf.long_frame_max_tx_count)); mac->retry_long = hw->conf.long_frame_max_tx_count; mac->retry_short = hw->conf.long_frame_max_tx_count; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, (u8 *) (&hw->conf.long_frame_max_tx_count)); } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *channel = hw->conf.chandef.chan; enum nl80211_channel_type channel_type = cfg80211_get_chandef_type(&(hw->conf.chandef)); u8 wide_chan = (u8) channel->hw_value; if (mac->act_scanning) mac->n_channels++; if (rtlpriv->dm.supp_phymode_switch && mac->link_state < MAC80211_LINKED && !mac->act_scanning) { if (rtlpriv->cfg->ops->check_switch_to_dmdp) rtlpriv->cfg->ops->check_switch_to_dmdp(hw); } /* *because we should back channel to *current_network.chan in in scanning, *So if set_chan == current_network.chan *we should set it. *because mac80211 tell us wrong bw40 *info for cisco1253 bw20, so we modify *it here based on UPPER & LOWER */ switch (channel_type) { case NL80211_CHAN_HT20: case NL80211_CHAN_NO_HT: /* SC */ mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_DONT_CARE; rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20; mac->bw_40 = false; break; case NL80211_CHAN_HT40MINUS: /* SC */ mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER; rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20_40; mac->bw_40 = true; /*wide channel */ wide_chan -= 2; break; case NL80211_CHAN_HT40PLUS: /* SC */ mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER; rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20_40; mac->bw_40 = true; /*wide channel */ wide_chan += 2; break; default: mac->bw_40 = false; RT_TRACE(COMP_ERR, DBG_EMERG, ("switch case not processed \n")); break; } if (wide_chan <= 0) wide_chan = 1; /* in scanning, when before we offchannel we may send a ps=1 * null to AP, and then we may send a ps = 0 null to AP quickly, * but first null have cause AP's put lots of packet to hw tx * buffer, these packet must be tx before off channel so we must * delay more time to let AP flush these packets before * offchannel, or dis-association or delete BA will happen by AP */ if (rtlpriv->mac80211.offchan_deley) { rtlpriv->mac80211.offchan_deley = false; mdelay(50); } rtlphy->current_channel = wide_chan; rtlpriv->cfg->ops->switch_channel(hw); rtlpriv->cfg->ops->set_channel_access(hw); rtlpriv->cfg->ops->set_bw_mode(hw, channel_type); } mutex_unlock(&rtlpriv->locks.conf_mutex); return 0; }
static void insert_headset(struct work_struct *work) { struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct hsd_info *hi = container_of(dwork, struct hsd_info, work_for_insert); int earjack_type; int value = gpio_get_value_cansleep(hi->gpio_detect); if(value != EARJACK_INSERTED) { HSD_ERR("insert_headset but actually Fake inserted state!!\n"); return; } else { #ifdef HEADSET_REMOVE_ERROR insert_state_check = 1; #endif // mutex_lock(&hi->mutex_lock); // switch_set_state(&hi->sdev, LGE_HEADSET); // mutex_unlock(&hi->mutex_lock); } HSD_DBG("insert_headset"); if (hi->set_headset_mic_bias) hi->set_headset_mic_bias(TRUE); gpio_set_value_cansleep(hi->gpio_mic_en, 1); msleep(hi->latency_for_detection); // 75 -> 10 ms earjack_type = gpio_get_value_cansleep(hi->gpio_jpole); if (earjack_type == EARJACK_TYPE_3_POLE) { HSD_DBG("3 polarity earjack"); if (hi->set_headset_mic_bias) hi->set_headset_mic_bias(FALSE); atomic_set(&hi->is_3_pole_or_not, 1); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, LGE_HEADSET_NO_MIC); mutex_unlock(&hi->mutex_lock); input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1); input_sync(hi->input); } else { HSD_DBG("4 polarity earjack"); atomic_set(&hi->is_3_pole_or_not, 0); cancel_delayed_work_sync(&(hi->work_for_key_det_enable)); queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_key_det_enable), FSA8008_KEY_EN_DELAY_MS ); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, LGE_HEADSET); mutex_unlock(&hi->mutex_lock); input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1); input_sync(hi->input); // 2012-07-01, [email protected] - to prevent a lost uevent of earjack inserted input_report_switch(hi->input, SW_MICROPHONE_INSERT, 1); input_sync(hi->input); } #ifdef HEADSET_REMOVE_ERROR insert_state_check = 0; #endif }
static void aliasguid_query_handler(int status, struct ib_sa_guidinfo_rec *guid_rec, void *context) { struct mlx4_ib_dev *dev; struct mlx4_alias_guid_work_context *cb_ctx = context; u8 port_index ; int i; struct mlx4_sriov_alias_guid_info_rec_det *rec; unsigned long flags, flags1; if (!context) return; dev = cb_ctx->dev; port_index = cb_ctx->port - 1; rec = &dev->sriov.alias_guid.ports_guid[port_index]. all_rec_per_port[cb_ctx->block_num]; if (status) { rec->status = MLX4_GUID_INFO_STATUS_IDLE; pr_debug("(port: %d) failed: status = %d\n", cb_ctx->port, status); goto out; } if (guid_rec->block_num != cb_ctx->block_num) { pr_err("block num mismatch: %d != %d\n", cb_ctx->block_num, guid_rec->block_num); goto out; } pr_debug("lid/port: %d/%d, block_num: %d\n", be16_to_cpu(guid_rec->lid), cb_ctx->port, guid_rec->block_num); rec = &dev->sriov.alias_guid.ports_guid[port_index]. all_rec_per_port[guid_rec->block_num]; rec->status = MLX4_GUID_INFO_STATUS_SET; rec->method = MLX4_GUID_INFO_RECORD_SET; for (i = 0 ; i < NUM_ALIAS_GUID_IN_REC; i++) { __be64 tmp_cur_ag; tmp_cur_ag = *(__be64 *)&guid_rec->guid_info_list[i * GUID_REC_SIZE]; /* check if the SM didn't assign one of the records. * if it didn't, if it was not sysadmin request: * ask the SM to give a new GUID, (instead of the driver request). */ if (tmp_cur_ag == MLX4_NOT_SET_GUID) { mlx4_ib_warn(&dev->ib_dev, "%s:Record num %d in " "block_num: %d was declined by SM, " "ownership by %d (0 = driver, 1=sysAdmin," " 2=None)\n", __func__, i, guid_rec->block_num, rec->ownership); if (rec->ownership == MLX4_GUID_DRIVER_ASSIGN) { /* if it is driver assign, asks for new GUID from SM*/ *(__be64 *)&rec->all_recs[i * GUID_REC_SIZE] = MLX4_NOT_SET_GUID; /* Mark the record as not assigned, and let it * be sent again in the next work sched.*/ rec->status = MLX4_GUID_INFO_STATUS_IDLE; rec->guid_indexes |= mlx4_ib_get_aguid_comp_mask_from_ix(i); } } else { /* properly assigned record. */ /* We save the GUID we just got from the SM in the * admin_guid in order to be persistent, and in the * request from the sm the process will ask for the same GUID */ if (rec->ownership == MLX4_GUID_SYSADMIN_ASSIGN && tmp_cur_ag != *(__be64 *)&rec->all_recs[i * GUID_REC_SIZE]) { /* the sysadmin assignment failed.*/ mlx4_ib_warn(&dev->ib_dev, "%s: Failed to set" " admin guid after SysAdmin " "configuration. " "Record num %d in block_num:%d " "was declined by SM, " "new val(0x%llx) was kept\n", __func__, i, guid_rec->block_num, (long long)be64_to_cpu(*(__be64 *) & rec->all_recs[i * GUID_REC_SIZE])); } else { memcpy(&rec->all_recs[i * GUID_REC_SIZE], &guid_rec->guid_info_list[i * GUID_REC_SIZE], GUID_REC_SIZE); } } } /* The func is call here to close the cases when the sm doesn't send smp, so in the sa response the driver notifies the slave. */ mlx4_ib_notify_slaves_on_guid_change(dev, guid_rec->block_num, cb_ctx->port, guid_rec->guid_info_list); out: spin_lock_irqsave(&dev->sriov.going_down_lock, flags); spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1); if (!dev->sriov.is_going_down) queue_delayed_work(dev->sriov.alias_guid.ports_guid[port_index].wq, &dev->sriov.alias_guid.ports_guid[port_index]. alias_guid_work, 0); if (cb_ctx->sa_query) { list_del(&cb_ctx->list); kfree(cb_ctx); } else complete(&cb_ctx->done); spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1); spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags); }
static int p3_get_bat_level(struct power_supply *bat_ps) { struct battery_data *battery = container_of(bat_ps, struct battery_data, psy_battery); int fg_soc; int fg_vfsoc; int fg_vcell; int fg_current; int avg_current; int recover_flag = 0; recover_flag = fg_check_cap_corruption(); /* check VFcapacity every five minutes */ if (!(battery->fg_chk_cnt++ % 10)) { fg_check_vf_fullcap_range(); battery->fg_chk_cnt = 1; } fg_soc = get_fuelgauge_value(FG_LEVEL); if (fg_soc < 0) { pr_info("Can't read soc!!!"); fg_soc = battery->info.level; } if (!check_jig_on() && !max17042_chip_data->info.low_batt_comp_flag) { if (((fg_soc+5) < max17042_chip_data->info.previous_repsoc) || (fg_soc > (max17042_chip_data->info.previous_repsoc+5))) battery->fg_skip = 1; } /* skip one time (maximum 30 seconds) because of corruption. */ if (battery->fg_skip) { pr_info("%s: skip update until corruption check " "is done (fg_skip_cnt:%d)\n", __func__, ++battery->fg_skip_cnt); fg_soc = battery->info.level; if (recover_flag || battery->fg_skip_cnt > 10) { battery->fg_skip = 0; battery->fg_skip_cnt = 0; } } if (battery->low_batt_boot_flag) { fg_soc = 0; if (check_ta_conn(battery) && !check_UV_charging_case()) { fg_adjust_capacity(); battery->low_batt_boot_flag = 0; } if (!check_ta_conn(battery)) battery->low_batt_boot_flag = 0; } fg_vcell = get_fuelgauge_value(FG_VOLTAGE); if (fg_vcell < 0) { pr_info("Can't read vcell!!!"); fg_vcell = battery->info.batt_vol; } else battery->info.batt_vol = fg_vcell; fg_current = get_fuelgauge_value(FG_CURRENT); #if !defined(CONFIG_MACH_SAMSUNG_P4) || !defined(CONFIG_MACH_SAMSUNG_P4WIFI) || !defined(CONFIG_MACH_SAMSUNG_P4LTE) avg_current = get_fuelgauge_value(FG_CURRENT_AVG); fg_vfsoc = get_fuelgauge_value(FG_VF_SOC); // Algorithm for reducing time to fully charged (from MAXIM) if(battery->info.charging_enabled && // Charging is enabled !battery->info.batt_is_recharging && // Not Recharging (battery->info.charging_source == CHARGER_AC || (battery->info.charging_source == CHARGER_USB && battery->info.force_usb_charging)) && !battery->is_first_check && // Skip when first check after boot up (fg_vfsoc>70 && (fg_current>20 && fg_current<250) && (avg_current>20 && avg_current<260))) { if(battery->full_check_flag == 2) { pr_info("%s: force fully charged SOC !! (%d)", __func__, battery->full_check_flag); fg_set_full_charged(); fg_soc = get_fuelgauge_value(FG_LEVEL); } else if(battery->full_check_flag < 2) pr_info("%s: full_check_flag (%d)", __func__, battery->full_check_flag); if(battery->full_check_flag++ > 10000) // prevent overflow battery->full_check_flag = 3; } else battery->full_check_flag = 0; #endif if ((battery->info.charging_source == CHARGER_AC || (battery->info.charging_source == CHARGER_USB && battery->info.force_usb_charging)) && battery->info.batt_improper_ta == 0) { if (is_over_abs_time(battery)) { fg_soc = 100; battery->info.batt_is_full = 1; pr_info("%s: charging time is over", __func__); pr_info("%s: fg_vcell = %d, fg_soc = %d," " is_full = %d\n", __func__, fg_vcell, fg_soc, battery->info.batt_is_full); p3_set_chg_en(battery, 0); goto __end__; } } if (fg_vcell <= battery->pdata->recharge_voltage) { if (battery->info.batt_is_full && !battery->info.charging_enabled) { if (++battery->recharging_cnt > 1) { pr_info("recharging(under full)"); battery->info.batt_is_recharging = 1; p3_set_chg_en(battery, 1); battery->recharging_cnt = 0; pr_info("%s: fg_vcell = %d, fg_soc = %d," " is_recharging = %d\n", __func__, fg_vcell, fg_soc, battery->info.batt_is_recharging); } } else battery->recharging_cnt = 0; } else battery->recharging_cnt = 0; if (fg_soc > 100) fg_soc = 100; /* Checks vcell level and tries to compensate SOC if needed.*/ /* If jig cable is connected, then skip low batt compensation check. */ #ifdef CONFIG_TARGET_LOCALE_KOR pr_info("%s : chek point 1, cond: %d!\n",__func__, max17042_chip_data->low_comp_pre_cond); if (!check_jig_on() && !battery->info.charging_enabled && max17042_chip_data->low_comp_pre_cond == 0) { if (p3_low_batt_compensation(fg_soc, fg_vcell, fg_current) == 1) pr_info("error "); } if(max17042_chip_data->pre_cond_ok == 1) { max17042_chip_data->low_comp_pre_cond = 1; pr_info("%s : schedule low batt compensation! pre_count(%d), pre_condition(%d)\n", __func__, max17042_chip_data->pre_cond_ok, max17042_chip_data->low_comp_pre_cond); wake_lock(&battery->low_comp_wake_lock); queue_delayed_work(battery->low_bat_comp_workqueue, &battery->low_comp_work, 0); } #else if (!check_jig_on() && !battery->info.charging_enabled) fg_soc = p3_low_batt_compensation(fg_soc, fg_vcell, fg_current); #endif __end__: pr_debug("fg_vcell = %d, fg_soc = %d, is_full = %d", fg_vcell, fg_soc, battery->info.batt_is_full); #if !defined(CONFIG_MACH_SAMSUNG_P4) || !defined(CONFIG_MACH_SAMSUNG_P4WIFI) || !defined(CONFIG_MACH_SAMSUNG_P4LTE) if(battery->is_first_check) battery->is_first_check = false; #endif if (battery->info.batt_is_full && (battery->info.charging_source != CHARGER_USB || battery->info.force_usb_charging)) fg_soc = 100; #if 0 // not used else { if (fg_soc >= 100) fg_soc = 99; } #endif return fg_soc; }
static void asuspec_stresstest_work_function(struct work_struct *dat) { asuspec_i2c_read_data(ec_chip->client); queue_delayed_work(asuspec_wq, &asuspec_stress_work, HZ/ec_chip->polling_rate); }
static int __devinit asuspec_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = 0; ASUSPEC_INFO("asuspec probe\n"); err = sysfs_create_group(&client->dev.kobj, &asuspec_smbus_group); if (err) { ASUSPEC_ERR("Unable to create the sysfs\n"); goto exit; } ec_chip = kzalloc(sizeof (struct asuspec_chip), GFP_KERNEL); if (!ec_chip) { ASUSPEC_ERR("Memory allocation fails\n"); err = -ENOMEM; goto exit; } i2c_set_clientdata(client, ec_chip); ec_chip->client = client; ec_chip->client->driver = &asuspec_driver; ec_chip->client->flags = 1; init_timer(&ec_chip->asuspec_timer); ec_chip->asuspec_timer.function = asuspec_enter_s3_timer; wake_lock_init(&ec_chip->wake_lock, WAKE_LOCK_SUSPEND, "asuspec_wake"); mutex_init(&ec_chip->lock); mutex_init(&ec_chip->irq_lock); mutex_init(&ec_chip->state_change_lock); ec_chip->ec_ram_init = 0; ec_chip->audio_recording = 0; ec_chip->status = 0; ec_chip->ec_in_s3 = 0; ec_chip->apwake_disabled = 0; asuspec_dockram_init(client); cdev_add(asuspec_cdev,asuspec_dev,1) ; ec_chip->pad_sdev.name = PAD_SDEV_NAME; ec_chip->pad_sdev.print_name = asuspec_switch_name; ec_chip->pad_sdev.print_state = asuspec_switch_state; if(switch_dev_register(&ec_chip->pad_sdev) < 0){ ASUSPEC_ERR("switch_dev_register for pad failed!\n"); } switch_set_state(&ec_chip->pad_sdev, 0); asuspec_wq = create_singlethread_workqueue("asuspec_wq"); INIT_DELAYED_WORK_DEFERRABLE(&ec_chip->asuspec_work, asuspec_work_function); INIT_DELAYED_WORK_DEFERRABLE(&ec_chip->asuspec_init_work, asuspec_init_work_function); INIT_DELAYED_WORK_DEFERRABLE(&ec_chip->asuspec_fw_update_work, asuspec_fw_update_work_function); INIT_DELAYED_WORK_DEFERRABLE(&ec_chip->asuspec_enter_s3_work, asuspec_enter_s3_work_function); INIT_DELAYED_WORK_DEFERRABLE(&asuspec_stress_work, asuspec_stresstest_work_function); asuspec_irq_ec_request(client); asuspec_irq_ec_apwake(client); queue_delayed_work(asuspec_wq, &ec_chip->asuspec_init_work, 0); return 0; exit: return err; }
/* * Internal function. Schedule delayed work in the MMC work queue. */ static int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) { return queue_delayed_work(workqueue, work, delay); }
static void asuspec_enter_s3_timer(unsigned long data){ queue_delayed_work(asuspec_wq, &ec_chip->asuspec_enter_s3_work, 0); }
static int max8997_muic_probe(struct platform_device *pdev) { struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent); struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev); struct max8997_muic_info *info; int delay_jiffies; int ret, i; info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info), GFP_KERNEL); if (!info) return -ENOMEM; info->dev = &pdev->dev; info->muic = max8997->muic; platform_set_drvdata(pdev, info); mutex_init(&info->mutex); INIT_WORK(&info->irq_work, max8997_muic_irq_work); for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) { struct max8997_muic_irq *muic_irq = &muic_irqs[i]; unsigned int virq = 0; virq = irq_create_mapping(max8997->irq_domain, muic_irq->irq); if (!virq) { ret = -EINVAL; goto err_irq; } muic_irq->virq = virq; ret = request_threaded_irq(virq, NULL, max8997_muic_irq_handler, IRQF_NO_SUSPEND, muic_irq->name, info); if (ret) { dev_err(&pdev->dev, "failed: irq request (IRQ: %d, error :%d)\n", muic_irq->irq, ret); goto err_irq; } } /* External connector */ info->edev = devm_extcon_dev_allocate(&pdev->dev, max8997_extcon_cable); if (IS_ERR(info->edev)) { dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); ret = -ENOMEM; goto err_irq; } ret = devm_extcon_dev_register(&pdev->dev, info->edev); if (ret) { dev_err(&pdev->dev, "failed to register extcon device\n"); goto err_irq; } if (pdata && pdata->muic_pdata) { struct max8997_muic_platform_data *muic_pdata = pdata->muic_pdata; /* Initialize registers according to platform data */ for (i = 0; i < muic_pdata->num_init_data; i++) { max8997_write_reg(info->muic, muic_pdata->init_data[i].addr, muic_pdata->init_data[i].data); } /* * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB * h/w path of COMP2/COMN1 on CONTROL1 register. */ if (muic_pdata->path_uart) info->path_uart = muic_pdata->path_uart; else info->path_uart = CONTROL1_SW_UART; if (muic_pdata->path_usb) info->path_usb = muic_pdata->path_usb; else info->path_usb = CONTROL1_SW_USB; /* * Default delay time for detecting cable state * after certain time. */ if (muic_pdata->detcable_delay_ms) delay_jiffies = msecs_to_jiffies(muic_pdata->detcable_delay_ms); else delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); } else { info->path_uart = CONTROL1_SW_UART; info->path_usb = CONTROL1_SW_USB; delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); } /* Set initial path for UART */ max8997_muic_set_path(info, info->path_uart, true); /* Set ADC debounce time */ max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS); /* * Detect accessory after completing the initialization of platform * * - Use delayed workqueue to detect cable state and then * notify cable state to notifiee/platform through uevent. * After completing the booting of platform, the extcon provider * driver should notify cable state to upper layer. */ INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq); queue_delayed_work(system_power_efficient_wq, &info->wq_detcable, delay_jiffies); return 0; err_irq: while (--i >= 0) free_irq(muic_irqs[i].virq, info); return ret; }
/** * dwc3_otg_sm_work - workqueue function. * * @w: Pointer to the dwc3 otg workqueue * * NOTE: After any change in phy->state, * we must reschdule the state machine. */ static void dwc3_otg_sm_work(struct work_struct *w) { struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work.work); struct usb_phy *phy = dotg->otg.phy; struct dwc3_charger *charger = dotg->charger; bool work = 0; int ret = 0; unsigned long delay = 0; pm_runtime_resume(phy->dev); dev_info(phy->dev, "%s state\n", otg_state_string(phy->state)); /* Check OTG state */ switch (phy->state) { case OTG_STATE_UNDEFINED: dwc3_otg_init_sm(dotg); if (!dotg->psy) { dotg->psy = power_supply_get_by_name("usb"); if (!dotg->psy) dev_err(phy->dev, "couldn't get usb power supply\n"); } /* Switch to A or B-Device according to ID / BSV */ if (!test_bit(ID, &dotg->inputs)) { dev_dbg(phy->dev, "!id\n"); phy->state = OTG_STATE_A_IDLE; work = 1; } else if (test_bit(B_SESS_VLD, &dotg->inputs)) { dev_dbg(phy->dev, "b_sess_vld\n"); phy->state = OTG_STATE_B_IDLE; work = 1; } else { phy->state = OTG_STATE_B_IDLE; dev_dbg(phy->dev, "No device, trying to suspend\n"); pm_runtime_put_sync(phy->dev); } break; case OTG_STATE_B_IDLE: if (!test_bit(ID, &dotg->inputs)) { dev_dbg(phy->dev, "!id\n"); phy->state = OTG_STATE_A_IDLE; work = 1; dotg->charger_retry_count = 0; if (charger) { if (charger->chg_type == DWC3_INVALID_CHARGER) charger->start_detection(dotg->charger, false); else charger->chg_type = DWC3_INVALID_CHARGER; } } else if (test_bit(B_SESS_VLD, &dotg->inputs)) { dev_dbg(phy->dev, "b_sess_vld\n"); if (charger) { /* Has charger been detected? If no detect it */ switch (charger->chg_type) { case DWC3_DCP_CHARGER: case DWC3_PROPRIETARY_CHARGER: dev_dbg(phy->dev, "lpm, DCP charger\n"); dwc3_otg_set_power(phy, DWC3_IDEV_CHG_MAX); pm_runtime_put_sync(phy->dev); break; case DWC3_CDP_CHARGER: dwc3_otg_set_power(phy, DWC3_IDEV_CHG_MAX); dwc3_otg_start_peripheral(&dotg->otg, 1); phy->state = OTG_STATE_B_PERIPHERAL; work = 1; break; case DWC3_SDP_CHARGER: dwc3_otg_start_peripheral(&dotg->otg, 1); phy->state = OTG_STATE_B_PERIPHERAL; work = 1; break; case DWC3_FLOATED_CHARGER: if (dotg->charger_retry_count < max_chgr_retry_count) dotg->charger_retry_count++; /* * In case of floating charger, if * retry count equal to max retry count * notify PMIC about floating charger * and put Hw in low power mode. Else * perform charger detection again by * calling start_detection() with false * and then with true argument. */ if (dotg->charger_retry_count == max_chgr_retry_count) { dwc3_otg_set_power(phy, 0); qpnp_chg_notify_invalid_usb(); pm_runtime_put_sync(phy->dev); break; } charger->start_detection(dotg->charger, false); default: dev_dbg(phy->dev, "chg_det started\n"); charger->start_detection(charger, true); break; } } else { /* no charger registered, start peripheral */ if (dwc3_otg_start_peripheral(&dotg->otg, 1)) { /* * Probably set_peripheral not called * yet. We will re-try as soon as it * will be called */ dev_err(phy->dev, "enter lpm as\n" "unable to start B-device\n"); phy->state = OTG_STATE_UNDEFINED; pm_runtime_put_sync(phy->dev); return; } } } else { if (charger) charger->start_detection(dotg->charger, false); dotg->charger_retry_count = 0; dwc3_otg_set_power(phy, 0); dev_dbg(phy->dev, "No device, trying to suspend\n"); pm_runtime_put_sync(phy->dev); } break; case OTG_STATE_B_PERIPHERAL: if (!test_bit(B_SESS_VLD, &dotg->inputs) || !test_bit(ID, &dotg->inputs)) { dev_dbg(phy->dev, "!id || !bsv\n"); dwc3_otg_start_peripheral(&dotg->otg, 0); phy->state = OTG_STATE_B_IDLE; if (charger) charger->chg_type = DWC3_INVALID_CHARGER; work = 1; } break; case OTG_STATE_A_IDLE: /* Switch to A-Device*/ if (test_bit(ID, &dotg->inputs)) { dev_dbg(phy->dev, "id\n"); phy->state = OTG_STATE_B_IDLE; dotg->vbus_retry_count = 0; work = 1; clear_bit(A_VBUS_DROP_DET, &dotg->inputs); } else if (test_bit(A_VBUS_DROP_DET, &dotg->inputs)) { dev_dbg(phy->dev, "vbus_drop_det\n"); /* staying on here until exit from A-Device */ } else { phy->state = OTG_STATE_A_HOST; ret = dwc3_otg_start_host(&dotg->otg, 1); if ((ret == -EPROBE_DEFER) && dotg->vbus_retry_count < 3) { /* * Get regulator failed as regulator driver is * not up yet. Will try to start host after 1sec */ phy->state = OTG_STATE_A_IDLE; dev_dbg(phy->dev, "Unable to get vbus regulator. Retrying...\n"); delay = VBUS_REG_CHECK_DELAY; work = 1; dotg->vbus_retry_count++; } else if (ret) { /* * Probably set_host was not called yet. * We will re-try as soon as it will be called */ dev_dbg(phy->dev, "enter lpm as\n" "unable to start A-device\n"); phy->state = OTG_STATE_A_IDLE; pm_runtime_put_sync(phy->dev); return; } } break; case OTG_STATE_A_HOST: if (test_bit(ID, &dotg->inputs)) { dev_dbg(phy->dev, "id\n"); dwc3_otg_start_host(&dotg->otg, 0); phy->state = OTG_STATE_B_IDLE; dotg->vbus_retry_count = 0; work = 1; clear_bit(A_VBUS_DROP_DET, &dotg->inputs); } else if (test_bit(A_VBUS_DROP_DET, &dotg->inputs)) { dev_dbg(phy->dev, "vbus_drop_det\n"); dwc3_otg_start_host(&dotg->otg, 0); phy->state = OTG_STATE_A_IDLE; work = 1; #ifdef CONFIG_USB_HOST_EXTRA_NOTIFICATION host_send_uevent(USB_HOST_EXT_EVENT_VBUS_DROP); #endif } break; default: dev_err(phy->dev, "%s: invalid otg-state\n", __func__); } if (work) queue_delayed_work(system_nrt_wq, &dotg->sm_work, delay); }
/** * dwc3_ext_event_notify - callback to handle events from external transceiver * @otg: Pointer to the otg transceiver structure * @event: Event reported by transceiver * * Returns 0 on success */ static void dwc3_ext_event_notify(struct usb_otg *otg, enum dwc3_ext_events event) { static bool init; struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg); struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv; struct usb_phy *phy = dotg->otg.phy; int ret = 0; /* Flush processing any pending events before handling new ones */ if (init) flush_delayed_work(&dotg->sm_work); if (event == DWC3_EVENT_PHY_RESUME) { if (!pm_runtime_status_suspended(phy->dev)) { dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n"); } else { dev_dbg(phy->dev, "ext PHY_RESUME event received\n"); /* ext_xceiver would have taken h/w out of LPM by now */ ret = pm_runtime_get(phy->dev); if ((phy->state == OTG_STATE_A_HOST) && dotg->host_bus_suspend) dotg->host_bus_suspend = 0; if (ret == -EACCES) { /* pm_runtime_get may fail during system resume with -EACCES error */ pm_runtime_disable(phy->dev); pm_runtime_set_active(phy->dev); pm_runtime_enable(phy->dev); } else if (ret < 0) { dev_warn(phy->dev, "pm_runtime_get failed!\n"); } } } else if (event == DWC3_EVENT_XCEIV_STATE) { if (pm_runtime_status_suspended(phy->dev)) { dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n"); ret = pm_runtime_get(phy->dev); if (ret < 0) dev_warn(phy->dev, "pm_runtime_get failed!!\n"); } if (ext_xceiv->id == DWC3_ID_FLOAT) { dev_info(phy->dev, "XCVR: ID set\n"); set_bit(ID, &dotg->inputs); } else { dev_info(phy->dev, "XCVR: ID clear\n"); clear_bit(ID, &dotg->inputs); } if (ext_xceiv->bsv) { dev_info(phy->dev, "XCVR: BSV set\n"); set_bit(B_SESS_VLD, &dotg->inputs); } else { dev_info(phy->dev, "XCVR: BSV clear\n"); clear_bit(B_SESS_VLD, &dotg->inputs); } if (ext_xceiv->ocp) { dev_dbg(phy->dev, "XCVR: OCP set\n"); ext_xceiv->ocp = false; set_bit(A_VBUS_DROP_DET, &dotg->inputs); } if (!init) { init = true; if (!work_busy(&dotg->sm_work.work)) queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0); complete(&dotg->dwc3_xcvr_vbus_init); dev_dbg(phy->dev, "XCVR: BSV init complete\n"); return; } queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0); } }
static void pm8xxx_led_current_set_flagged(struct led_classdev *led_cdev, enum led_brightness brightness, int blink) { struct pm8xxx_led_data *led = container_of(led_cdev, struct pm8xxx_led_data, cdev); int rc, offset; u8 level; int *pduties; LED_INFO("%s, bank:%d, brightness:%d\n", __func__, led->bank, brightness); cancel_delayed_work_sync(&led->fade_delayed_work); virtual_key_state = brightness; if (flag_hold_virtual_key == 1) { LED_INFO("%s, key control \n", __func__); return; } if(brightness) { level = (led->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK; offset = PM8XXX_LED_OFFSET(led->id); led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK; led->reg |= level; rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg); if (rc) LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc); if (led->function_flags & LED_BRETH_FUNCTION) { if (blink == 0) { buttons_led_is_on = 1; // no blink needed pduties = led->duties; pm8xxx_pwm_lut_config(led->pwm_led, led->period_us, pduties, led->duty_time_ms, led->start_index, led->duites_size, 0, 0, led->lut_flag); } else { pduties = led->duties; // LUT_LOOP for blinking pm8xxx_pwm_lut_config(led->pwm_led, led->period_us, pduties, led->duty_time_ms, // slower, 2x led->start_index, led->duites_size * 8, // 16 duty entries -> original size * 2, + 6 * 8 zeroes for pause 0, 0, PM_PWM_LUT_LOOP | PM_PWM_LUT_PAUSE_HI_EN); } pm8xxx_pwm_lut_enable(led->pwm_led, 0); pm8xxx_pwm_lut_enable(led->pwm_led, 1); } else { pwm_config(led->pwm_led, 64000, 64000); pwm_enable(led->pwm_led); } } else { if (led->function_flags & LED_BRETH_FUNCTION) { buttons_led_is_on = 0; wake_lock_timeout(&pmic_led_wake_lock, HZ*2); pduties = led->duties + led->duites_size; pm8xxx_pwm_lut_config(led->pwm_led, led->period_us, pduties, led->duty_time_ms, led->start_index, led->duites_size, 0, 0, led->lut_flag); pm8xxx_pwm_lut_enable(led->pwm_led, 0); pm8xxx_pwm_lut_enable(led->pwm_led, 1); queue_delayed_work(g_led_work_queue, &led->fade_delayed_work, msecs_to_jiffies(led->duty_time_ms*led->duites_size)); } else { pwm_disable(led->pwm_led); level = (0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK; offset = PM8XXX_LED_OFFSET(led->id); led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK; led->reg |= level; rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg); if (rc) LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc); } } }
/* * tuple format: (key_code, key_param) * * old-architecture: * key-press = (key_code, 0) * key-release = (0xff, key_code) * * new-architecutre: * key-press = (key_code, 0) * key-release = (key_code, 0xff) */ static void report_hs_key(uint32_t key_code, uint32_t key_parm) { int key, temp_key_code; printk("+%s %d+\n",__func__,__LINE__); if (key_code == HS_REL_K) key = hs_find_key(key_parm); else key = hs_find_key(key_code); temp_key_code = key_code; if (key_parm == HS_REL_K) key_code = key_parm; switch (key) { case KEY_POWER: case KEY_END: key = KEY_POWER; case KEY_MEDIA: case KEY_VOLUMEUP: case KEY_VOLUMEDOWN: input_report_key(hs->ipdev, key, (key_code != HS_REL_K)); printk("%s %d report pwr key\n",__func__,__LINE__); { if(key == KEY_POWER) { if(key_code == HS_REL_K) { pwrkey_down = 0; cancel_delayed_work_sync(&pwrkey_work); } else { pwrkey_down = 1; queue_delayed_work(pwrkey_wqueue, &pwrkey_work, 8*HZ); } } else if(key == KEY_END && pwrkey_down == 1) { if(key_code == HS_REL_K) { pwrkey_down = 0; cancel_delayed_work_sync(&pwrkey_work); } } } break; case SW_HEADPHONE_INSERT_W_MIC: hs->mic_on = hs->hs_on = (key_code != HS_REL_K) ? 1 : 0; input_report_switch(hs->ipdev, SW_HEADPHONE_INSERT, hs->hs_on); input_report_switch(hs->ipdev, SW_MICROPHONE_INSERT, hs->mic_on); update_state(); break; case SW_HEADPHONE_INSERT: hs->hs_on = (key_code != HS_REL_K) ? 1 : 0; input_report_switch(hs->ipdev, key, hs->hs_on); update_state(); break; case SW_MICROPHONE_INSERT: hs->mic_on = (key_code != HS_REL_K) ? 1 : 0; input_report_switch(hs->ipdev, key, hs->mic_on); update_state(); break; case KEY_BATTERY: #ifdef CONFIG_BATTERY_QSD if(key_code == HS_BAD_BATT_K) { qsd_bat_update_usb_status(CHG_EVENT_GAGIC_BATT_GOOD); } else if(key_code == HS_CHARGING_ON_K) { qsd_bat_update_usb_status(AC_STATUS_AC_IN); #ifdef CONFIG_HW_AUSTIN q6audio_update_AC_5V_status(1); #endif //CONFIG_HW_AUSTIN } else if(key_code == HS_CHARGING_OFF_K) { qsd_bat_update_usb_status(AC_STATUS_AC_NONE); #ifdef CONFIG_HW_AUSTIN q6audio_update_AC_5V_status(0); #endif //CONFIG_HW_AUSTIN } else if(key_code == HS_BAT_LOW_K) { qsd_bat_update_usb_status(CHG_EVENT_PMIC_BATT_LOW); } #endif printk("-%s ret bat %d-\n",__func__,__LINE__); return; //break; case -1: printk(KERN_ERR "%s: No mapping for remote handset event %d\n", __func__, temp_key_code); printk("-%s ret -1 %d-\n",__func__,__LINE__); return; } input_sync(hs->ipdev); printk("-%s ret normal %d-\n",__func__,__LINE__); }
static ssize_t pm8xxx_led_blink_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct led_classdev *led_cdev; struct pm8xxx_led_data *ldata; int val; int level, offset; val = -1; sscanf(buf, "%u", &val); if (val < 0 || val > 255) return -EINVAL; current_blink= val; led_cdev = (struct led_classdev *) dev_get_drvdata(dev); ldata = container_of(led_cdev, struct pm8xxx_led_data, cdev); LED_INFO("%s: bank %d blink %d sync %d\n", __func__, ldata->bank, val, ldata->led_sync); printk("[BB] blink value: %d\n",val); switch (val) { case BLINK_STOP: if (ldata->gpio_status_switch != NULL) ldata->gpio_status_switch(0); pwm_disable(ldata->pwm_led); if(ldata->led_sync) { if (!strcmp(ldata->cdev.name, "green")) { if (green_back_led_data->gpio_status_switch != NULL) green_back_led_data->gpio_status_switch(0); pwm_disable(green_back_led_data->pwm_led); } if (!strcmp(ldata->cdev.name, "amber")) { if (amber_back_led_data->gpio_status_switch != NULL) amber_back_led_data->gpio_status_switch(0); pwm_disable(amber_back_led_data->pwm_led); } } if (bln > 0) { pm8xxx_buttons_blink(0); } break; case BLINK_UNCHANGE: pwm_disable(ldata->pwm_led); if (led_cdev->brightness) { if (ldata->gpio_status_switch != NULL) ldata->gpio_status_switch(1); pwm_config(ldata->pwm_led, 6400 * ldata->pwm_coefficient / 100, 6400); pwm_enable(ldata->pwm_led); if(ldata->led_sync) { if (!strcmp(ldata->cdev.name, "green")) { if (green_back_led_data->gpio_status_switch != NULL) green_back_led_data->gpio_status_switch(1); pwm_config(green_back_led_data->pwm_led, 64000, 64000); pwm_enable(green_back_led_data->pwm_led); } if (!strcmp(ldata->cdev.name, "amber")) { if (amber_back_led_data->gpio_status_switch != NULL) amber_back_led_data->gpio_status_switch(1); pwm_config(amber_back_led_data->pwm_led, 64000, 64000); pwm_enable(amber_back_led_data->pwm_led); } } if (bln > 0 && val > 0) { pm8xxx_buttons_blink(1); } } else { pwm_disable(ldata->pwm_led); if (ldata->gpio_status_switch != NULL) ldata->gpio_status_switch(0); if(ldata->led_sync) { if (!strcmp(ldata->cdev.name, "green")){ if (green_back_led_data->gpio_status_switch != NULL) green_back_led_data->gpio_status_switch(0); pwm_disable(green_back_led_data->pwm_led); level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK; offset = PM8XXX_LED_OFFSET(green_back_led_data->id); green_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK; green_back_led_data->reg |= level; pm8xxx_writeb(green_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), green_back_led_data->reg); } if (!strcmp(ldata->cdev.name, "amber")){ if (amber_back_led_data->gpio_status_switch != NULL) amber_back_led_data->gpio_status_switch(0); pwm_disable(amber_back_led_data->pwm_led); level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK; offset = PM8XXX_LED_OFFSET(amber_back_led_data->id); amber_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK; amber_back_led_data->reg |= level; pm8xxx_writeb(amber_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), amber_back_led_data->reg); } } if (bln > 0) { pm8xxx_buttons_blink(0); } } break; case BLINK_64MS_PER_2SEC: if (ldata->gpio_status_switch != NULL) ldata->gpio_status_switch(1); pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 64000, 2000000); pwm_enable(ldata->pwm_led); if(ldata->led_sync) { if (!strcmp(ldata->cdev.name, "green")) { if (green_back_led_data->gpio_status_switch != NULL) green_back_led_data->gpio_status_switch(1); pwm_disable(green_back_led_data->pwm_led); pwm_config(green_back_led_data->pwm_led, 64000, 2000000); pwm_enable(green_back_led_data->pwm_led); } if (!strcmp(ldata->cdev.name, "amber")) { if (amber_back_led_data->gpio_status_switch != NULL) amber_back_led_data->gpio_status_switch(1); pwm_disable(amber_back_led_data->pwm_led); pwm_config(amber_back_led_data->pwm_led, 64000, 2000000); pwm_enable(amber_back_led_data->pwm_led); } } if (bln > 0 && val > 0) { pm8xxx_buttons_blink(1); } break; case BLINK_64MS_ON_310MS_PER_2SEC: cancel_delayed_work_sync(&ldata->blink_delayed_work); pwm_disable(ldata->pwm_led); ldata->duty_time_ms = 64; ldata->period_us = 2000000; if(ldata->led_sync) { if (!strcmp(ldata->cdev.name, "green")) { pwm_disable(green_back_led_data->pwm_led); green_back_led_data->duty_time_ms = 64; green_back_led_data->period_us = 2000000; } if (!strcmp(ldata->cdev.name, "amber")) { pwm_disable(amber_back_led_data->pwm_led); amber_back_led_data->duty_time_ms = 64; amber_back_led_data->period_us = 2000000; } } queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work, msecs_to_jiffies(310)); break; case BLINK_64MS_ON_2SEC_PER_2SEC: cancel_delayed_work_sync(&ldata->blink_delayed_work); pwm_disable(ldata->pwm_led); ldata->duty_time_ms = 64; ldata->period_us = 2000000; if(ldata->led_sync) { if (!strcmp(ldata->cdev.name, "green")) { pwm_disable(green_back_led_data->pwm_led); green_back_led_data->duty_time_ms = 64; green_back_led_data->period_us = 2000000; } if (!strcmp(ldata->cdev.name, "amber")) { pwm_disable(amber_back_led_data->pwm_led); amber_back_led_data->duty_time_ms = 64; amber_back_led_data->period_us = 2000000; } } queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work, msecs_to_jiffies(1000)); break; case BLINK_1SEC_PER_2SEC: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 1000000, 2000000); pwm_enable(ldata->pwm_led); if(ldata->led_sync) { if (!strcmp(ldata->cdev.name, "green")) { pwm_disable(green_back_led_data->pwm_led); pwm_config(green_back_led_data->pwm_led, 1000000, 2000000); pwm_enable(green_back_led_data->pwm_led); } if (!strcmp(ldata->cdev.name, "amber")) { pwm_disable(amber_back_led_data->pwm_led); pwm_config(amber_back_led_data->pwm_led, 1000000, 2000000); pwm_enable(amber_back_led_data->pwm_led); } } break; default: LED_ERR("%s: bank %d did not support blink type %d\n", __func__, ldata->bank, val); return -EINVAL; } return count; }
static void usb_rx_retry_work(struct work_struct *work) { int ret = 0; struct usb_link_device *usb_ld = container_of(work, struct usb_link_device, rx_retry_work.work); struct urb *urb = usb_ld->retry_urb; struct if_usb_devdata *pipe_data = urb->context; struct io_device *iod; int iod_format; if (!usb_ld->if_usb_connected || !usb_ld->usbdev) return; if (usb_ld->usbdev) usb_mark_last_busy(usb_ld->usbdev); switch (pipe_data->format) { case IF_USB_FMT_EP: if (usb_ld->if_usb_is_main) { pr_urb("IPC-RX, retry", urb); iod_format = IPC_FMT; } else { iod_format = IPC_BOOT; } break; case IF_USB_RAW_EP: iod_format = IPC_MULTI_RAW; break; case IF_USB_RFS_EP: iod_format = IPC_RFS; pr_urb("RFS-RX, retry", urb); break; case IF_USB_CMD_EP: iod_format = IPC_CMD; break; default: iod_format = -1; break; } iod = link_get_iod_with_format(&usb_ld->ld, iod_format); if (iod) { ret = iod->recv(iod, &usb_ld->ld, (char *)urb->transfer_buffer, urb->actual_length); if (ret == -ENOMEM) { /* TODO: check the retry count */ /* retry the delay work after 20ms and resubit*/ mif_err("ENOMEM, +retry 20ms\n"); if (usb_ld->usbdev) usb_mark_last_busy(usb_ld->usbdev); usb_ld->retry_urb = urb; if (usb_ld->rx_retry_cnt++ < 10) queue_delayed_work(usb_ld->ld.tx_wq, &usb_ld->rx_retry_work, 10); return; } if (ret < 0) mif_err("io device recv error (%d)\n", ret); usb_ld->rx_retry_cnt = 0; } if (usb_ld->usbdev) usb_mark_last_busy(usb_ld->usbdev); usb_rx_submit(usb_ld, pipe_data, GFP_ATOMIC); }
static int set_guid_rec(struct ib_device *ibdev, u8 port, int index, struct mlx4_sriov_alias_guid_info_rec_det *rec_det) { int err; struct mlx4_ib_dev *dev = to_mdev(ibdev); struct ib_sa_guidinfo_rec guid_info_rec; ib_sa_comp_mask comp_mask; struct ib_port_attr attr; struct mlx4_alias_guid_work_context *callback_context; unsigned long resched_delay, flags, flags1; struct list_head *head = &dev->sriov.alias_guid.ports_guid[port - 1].cb_list; err = __mlx4_ib_query_port(ibdev, port, &attr, 1); if (err) { pr_debug("mlx4_ib_query_port failed (err: %d), port: %d\n", err, port); return err; } /*check the port was configured by the sm, otherwise no need to send */ if (attr.state != IB_PORT_ACTIVE) { pr_debug("port %d not active...rescheduling\n", port); resched_delay = 5 * HZ; err = -EAGAIN; goto new_schedule; } callback_context = kmalloc(sizeof *callback_context, GFP_KERNEL); if (!callback_context) { err = -ENOMEM; resched_delay = HZ * 5; goto new_schedule; } callback_context->port = port; callback_context->dev = dev; callback_context->block_num = index; memset(&guid_info_rec, 0, sizeof (struct ib_sa_guidinfo_rec)); guid_info_rec.lid = cpu_to_be16(attr.lid); guid_info_rec.block_num = index; memcpy(guid_info_rec.guid_info_list, rec_det->all_recs, GUID_REC_SIZE * NUM_ALIAS_GUID_IN_REC); comp_mask = IB_SA_GUIDINFO_REC_LID | IB_SA_GUIDINFO_REC_BLOCK_NUM | rec_det->guid_indexes; init_completion(&callback_context->done); spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1); list_add_tail(&callback_context->list, head); spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1); callback_context->query_id = ib_sa_guid_info_rec_query(dev->sriov.alias_guid.sa_client, ibdev, port, &guid_info_rec, comp_mask, rec_det->method, 1000, GFP_KERNEL, aliasguid_query_handler, callback_context, &callback_context->sa_query); if (callback_context->query_id < 0) { pr_debug("ib_sa_guid_info_rec_query failed, query_id: " "%d. will reschedule to the next 1 sec.\n", callback_context->query_id); spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1); list_del(&callback_context->list); kfree(callback_context); spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1); resched_delay = 1 * HZ; err = -EAGAIN; goto new_schedule; } err = 0; goto out; new_schedule: spin_lock_irqsave(&dev->sriov.going_down_lock, flags); spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1); invalidate_guid_record(dev, port, index); if (!dev->sriov.is_going_down) { queue_delayed_work(dev->sriov.alias_guid.ports_guid[port - 1].wq, &dev->sriov.alias_guid.ports_guid[port - 1].alias_guid_work, resched_delay); } spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1); spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags); out: return err; }
static void usb_rx_complete(struct urb *urb) { struct if_usb_devdata *pipe_data = urb->context; struct usb_link_device *usb_ld = pipe_data->usb_ld; struct io_device *iod; int iod_format; int ret; if (usb_ld->usbdev) usb_mark_last_busy(usb_ld->usbdev); switch (urb->status) { case -ENOENT: /* case for 'link pm suspended but rx data had remained' */ mif_debug("urb->status = -ENOENT\n"); case 0: if (!urb->actual_length) { mif_debug("urb has zero length!\n"); goto rx_submit; } usb_ld->link_pm_data->rx_cnt++; /* call iod recv */ /* how we can distinguish boot ch with fmt ch ?? */ switch (pipe_data->format) { case IF_USB_FMT_EP: if (usb_ld->if_usb_is_main) { #if 0 pr_urb("IPC-RX", urb); #endif iod_format = IPC_FMT; } else { iod_format = IPC_BOOT; } break; case IF_USB_RAW_EP: iod_format = IPC_MULTI_RAW; break; case IF_USB_RFS_EP: iod_format = IPC_RFS; break; case IF_USB_CMD_EP: iod_format = IPC_CMD; break; default: iod_format = -1; break; } /* flow control CMD by CP, not use io device */ if (unlikely(iod_format == IPC_CMD)) { ret = link_rx_flowctl_cmd(&usb_ld->ld, (char *)urb->transfer_buffer, urb->actual_length); if (ret < 0) mif_err("no multi raw device (%d)\n", ret); goto rx_submit; } iod = link_get_iod_with_format(&usb_ld->ld, iod_format); if (iod) { ret = iod->recv(iod, &usb_ld->ld, (char *)urb->transfer_buffer, urb->actual_length); if (ret == -ENOMEM) { /* retry the delay work and resubit*/ mif_err("ENOMEM, retry\n"); if (usb_ld->usbdev) usb_mark_last_busy(usb_ld->usbdev); usb_ld->retry_urb = urb; queue_delayed_work(usb_ld->ld.tx_wq, &usb_ld->rx_retry_work, 0); return; } if (ret < 0) mif_err("io device recv error (%d)\n", ret); } rx_submit: if (urb->status == 0) { if (usb_ld->usbdev) usb_mark_last_busy(usb_ld->usbdev); usb_rx_submit(usb_ld, pipe_data, GFP_ATOMIC); } break; default: mif_err("urb err status = %d\n", urb->status); break; } }
/* * Internal function. Schedule delayed work in the MMC work queue. */ static int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) { wake_lock(&mmc_delayed_work_wake_lock); return queue_delayed_work(workqueue, work, delay); }
static void usb_tx_work(struct work_struct *work) { int ret = 0; struct link_device *ld = container_of(work, struct link_device, tx_delayed_work.work); struct usb_link_device *usb_ld = to_usb_link_device(ld); struct sk_buff *skb; struct link_pm_data *pm_data = usb_ld->link_pm_data; if (!usb_ld->usbdev) { mif_info("usbdev is invalid\n"); return; } pm_data->tx_cnt++; while (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen) { /* request and check usb runtime pm first */ ret = link_pm_runtime_get_active(pm_data); if (ret < 0) { if (ret == -ENODEV) { mif_err("link not avail, retry reconnect.\n"); goto exit; } goto retry_tx_work; } /* If AP try to tx when interface disconnect->reconnect probe, * usbdev was created but one of interface channel device are * probing, _usb_tx_work return to -ENOENT then runtime usage * count allways positive and never enter to L2 */ if (!usb_ld->if_usb_connected_last) { mif_info("link is available, but if was not readey\n"); goto retry_tx_work; } pm_runtime_get_sync(&usb_ld->usbdev->dev); ret = 0; /* send skb from fmt_txq and raw_txq,*/ /* one by one for fair flow control */ skb = skb_dequeue(&ld->sk_fmt_tx_q); if (skb) ret = _usb_tx_work(skb); if (ret) { mif_err("usb_tx_urb_with_skb for fmt_q %d\n", ret); skb_queue_head(&ld->sk_fmt_tx_q, skb); if (ret == -ENODEV || ret == -ENOENT) goto exit; /* tx fail and usbdev alived, retry tx work */ pm_runtime_put(&usb_ld->usbdev->dev); goto retry_tx_work; } skb = skb_dequeue(&ld->sk_raw_tx_q); if (skb) ret = _usb_tx_work(skb); if (ret) { mif_err("usb_tx_urb_with_skb for raw_q %d\n", ret); skb_queue_head(&ld->sk_raw_tx_q, skb); if (ret == -ENODEV || ret == -ENOENT) goto exit; pm_runtime_put(&usb_ld->usbdev->dev); goto retry_tx_work; } pm_runtime_put(&usb_ld->usbdev->dev); } wake_unlock(&pm_data->tx_async_wake); exit: return; retry_tx_work: queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, msecs_to_jiffies(20)); return; }
void r92su_hw_queue_service_work(struct r92su *r92su) { queue_delayed_work(system_unbound_wq, &r92su->service_work, 2 * HZ); }
static int start_ipc(struct link_device *ld, struct io_device *iod) { struct sk_buff *skb; char data[1] = {'a'}; int err; struct usb_link_device *usb_ld = to_usb_link_device(ld); struct link_pm_data *pm_data = usb_ld->link_pm_data; struct device *dev = &usb_ld->usbdev->dev; struct if_usb_devdata *pipe_data = &usb_ld->devdata[IF_USB_FMT_EP]; if (!usb_ld->if_usb_connected) { mif_err("HSIC not connected, skip start ipc\n"); err = -ENODEV; goto exit; } retry: if (ld->mc->phone_state != STATE_ONLINE) { mif_err("MODEM is not online, skip start ipc\n"); err = -ENODEV; goto exit; } /* check usb runtime pm first */ if (dev->power.runtime_status != RPM_ACTIVE) { if (!pm_data->resume_requested) { mif_debug("QW PM\n"); INIT_COMPLETION(pm_data->active_done); queue_delayed_work(pm_data->wq, &pm_data->link_pm_work, 0); } mif_debug("Wait pm\n"); err = wait_for_completion_timeout(&pm_data->active_done, msecs_to_jiffies(500)); /* timeout or -ERESTARTSYS */ if (err <= 0) goto retry; } pm_runtime_get_sync(dev); mif_err("send 'a'\n"); skb = alloc_skb(16, GFP_ATOMIC); if (unlikely(!skb)) { pm_runtime_put(dev); return -ENOMEM; } memcpy(skb_put(skb, 1), data, 1); skbpriv(skb)->iod = iod; skbpriv(skb)->ld = ld; if (!usb_ld->if_usb_connected || !usb_ld->usbdev) return -ENODEV; usb_mark_last_busy(usb_ld->usbdev); err = usb_tx_urb_with_skb(usb_ld->usbdev, skb, pipe_data); if (err < 0) { mif_err("usb_tx_urb fail\n"); dev_kfree_skb_any(skb); } pm_runtime_put(dev); exit: return err; }
static int lge_hsd_probe(struct platform_device *pdev) { int ret = 0; struct fsa8008_platform_data *pdata = pdev->dev.platform_data; struct hsd_info *hi; HSD_DBG("lge_hsd_probe"); hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL); if (NULL == hi) { HSD_ERR("Failed to allloate headset per device info\n"); return -ENOMEM; } hi->key_code = pdata->key_code; platform_set_drvdata(pdev, hi); atomic_set(&hi->btn_state, 0); atomic_set(&hi->is_3_pole_or_not, 1); hi->gpio_detect = pdata->gpio_detect; hi->gpio_mic_en = pdata->gpio_mic_en; hi->gpio_jpole = pdata->gpio_jpole; hi->gpio_key = pdata->gpio_key; hi->set_headset_mic_bias = pdata->set_headset_mic_bias; hi->latency_for_detection = pdata->latency_for_detection; #ifdef CONFIG_LGE_AUDIO_FSA8008_MODIFY hi->latency_for_key = FSA8008_KEY_PRESS_DLY_MS; hi->gpio_key_cnt = 0; INIT_DELAYED_WORK(&hi->work_for_insert, insert_headset); INIT_DELAYED_WORK(&hi->work_for_remove, remove_headset); INIT_DELAYED_WORK(&hi->work_for_key_det_enable, button_enable); #else hi->latency_for_key = 200 /* milli */ * HZ / 1000; /* convert milli to jiffies */ INIT_DELAYED_WORK(&hi->work, detect_work); #endif mutex_init(&hi->mutex_lock); INIT_DELAYED_WORK(&hi->work_for_key_pressed, button_pressed); INIT_DELAYED_WORK(&hi->work_for_key_released, button_released); /* initialize gpio_detect */ ret = gpio_request(hi->gpio_detect, "gpio_detect"); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_detect) gpio_request\n", hi->gpio_detect); goto error_01; } ret = gpio_direction_input(hi->gpio_detect); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_detect) gpio_direction_input\n", hi->gpio_detect); goto error_02; } /* initialize gpio_jpole */ ret = gpio_request(hi->gpio_jpole, "gpio_jpole"); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_jpole) gpio_request\n", hi->gpio_jpole); goto error_02; } ret = gpio_direction_input(hi->gpio_jpole); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_jpole) gpio_direction_input\n", hi->gpio_jpole); goto error_03; } /* initialize gpio_key */ ret = gpio_request(hi->gpio_key, "gpio_key"); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_request\n", hi->gpio_key); goto error_03; } ret = gpio_direction_input(hi->gpio_key); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_direction_input\n", hi->gpio_key); goto error_04; } /* initialize gpio_mic_en */ ret = gpio_request(hi->gpio_mic_en, "gpio_mic_en"); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_request\n", hi->gpio_mic_en); goto error_04; } ret = gpio_direction_output(hi->gpio_mic_en, 0); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_direction_output\n", hi->gpio_mic_en); goto error_05; } /* initialize irq of gpio_jpole */ hi->irq_detect = gpio_to_irq(hi->gpio_detect); HSD_DBG("hi->irq_detect = %d\n", hi->irq_detect); if (hi->irq_detect < 0) { HSD_ERR("Failed to get interrupt number\n"); ret = hi->irq_detect; goto error_05; } //LGE_START, MYUNGWON.KIM, When Sleep IRQ Doesn't work ret = request_threaded_irq(hi->irq_detect, NULL, gpio_irq_handler, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_NO_SUSPEND, pdev->name, hi); //LGE_END, MYUNGWON.KIM if (ret) { HSD_ERR("failed to request button irq"); goto error_05; } ret = irq_set_irq_wake(hi->irq_detect, 1); if (ret < 0) { HSD_ERR("Failed to set irq_detect interrupt wake\n"); goto error_06; } /* initialize irq of gpio_key */ hi->irq_key = gpio_to_irq(hi->gpio_key); HSD_DBG("hi->irq_key = %d\n", hi->irq_key); if (hi->irq_key < 0) { HSD_ERR("Failed to get interrupt number\n"); ret = hi->irq_key; goto error_06; } //LGE_START, MYUNGWON.KIM, When Sleep IRQ Doesn't work ret = request_threaded_irq(hi->irq_key, NULL, button_irq_handler, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_NO_SUSPEND, pdev->name, hi); //LGE_END, MYUNGWON.KIM if (ret) { HSD_ERR("failed to request button irq"); goto error_06; } disable_irq(hi->irq_key); ret = irq_set_irq_wake(hi->irq_key, 1); if (ret < 0) { HSD_ERR("Failed to set irq_key interrupt wake\n"); goto error_07; } /* initialize switch device */ hi->sdev.name = pdata->switch_name; hi->sdev.print_state = lge_hsd_print_state; hi->sdev.print_name = lge_hsd_print_name; ret = switch_dev_register(&hi->sdev); if (ret < 0) { HSD_ERR("Failed to register switch device\n"); goto error_07; } /* initialize input device */ hi->input = input_allocate_device(); if (!hi->input) { HSD_ERR("Failed to allocate input device\n"); ret = -ENOMEM; goto error_08; } hi->input->name = pdata->keypad_name; hi->input->id.vendor = 0x0001; hi->input->id.product = 1; hi->input->id.version = 1; /*input_set_capability(hi->input, EV_SW, SW_HEADPHONE_INSERT);*/ set_bit(EV_SYN, hi->input->evbit); set_bit(EV_KEY, hi->input->evbit); set_bit(EV_SW, hi->input->evbit); set_bit(hi->key_code, hi->input->keybit); set_bit(SW_HEADPHONE_INSERT, hi->input->swbit); set_bit(SW_MICROPHONE_INSERT, hi->input->swbit); ret = input_register_device(hi->input); if (ret) { HSD_ERR("Failed to register input device\n"); goto error_09; } #ifdef CONFIG_LGE_AUDIO_FSA8008_MODIFY if (gpio_get_value_cansleep(hi->gpio_detect) == EARJACK_INSERTED) { queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_insert), 0); /* to detect in initialization with eacjack insertion */ } #else if (!gpio_get_value_cansleep(hi->gpio_detect)) #ifdef CONFIG_FSA8008_USE_LOCAL_WORK_QUEUE queue_delayed_work(local_fsa8008_workqueue, &(hi->work), 0); /* to detect in initialization with eacjack insertion */ #else schedule_delayed_work(&(hi->work), 0); /* to detect in initialization with eacjack insertion */ #endif #endif #ifdef AT_TEST_GPKD err = device_create_file(&pdev->dev, &dev_attr_hookkeylog); #endif return ret; error_09: input_free_device(hi->input); error_08: switch_dev_unregister(&hi->sdev); error_07: free_irq(hi->irq_key, 0); error_06: free_irq(hi->irq_detect, 0); error_05: gpio_free(hi->gpio_mic_en); error_04: gpio_free(hi->gpio_key); error_03: gpio_free(hi->gpio_jpole); error_02: gpio_free(hi->gpio_detect); error_01: mutex_destroy(&hi->mutex_lock); kfree(hi); return ret; }
static void link_pm_runtime_work(struct work_struct *work) { int ret; struct link_pm_data *pm_data = container_of(work, struct link_pm_data, link_pm_work.work); struct device *dev = &pm_data->usb_ld->usbdev->dev; if (!pm_data->usb_ld->if_usb_connected || pm_data->dpm_suspending) return; if (pm_data->usb_ld->ld.com_state == COM_NONE) return; mif_debug("for dev 0x%p : current %d\n", dev, dev->power.runtime_status); switch (dev->power.runtime_status) { case RPM_ACTIVE: pm_data->resume_retry_cnt = 0; pm_data->resume_requested = false; complete(&pm_data->active_done); return; case RPM_SUSPENDED: if (pm_data->resume_requested) break; pm_data->resume_requested = true; wake_lock(&pm_data->rpm_wake); ret = link_pm_slave_wake(pm_data); if (ret < 0) { mif_err("slave wake fail\n"); wake_unlock(&pm_data->rpm_wake); break; } if (!pm_data->usb_ld->if_usb_connected) { wake_unlock(&pm_data->rpm_wake); return; } ret = pm_runtime_resume(dev); if (ret < 0) { mif_err("resume error(%d)\n", ret); if (!pm_data->usb_ld->if_usb_connected) { wake_unlock(&pm_data->rpm_wake); return; } /* force to go runtime idle before retry resume */ if (dev->power.timer_expires == 0 && !dev->power.request_pending) { mif_debug("run time idle\n"); pm_runtime_idle(dev); } } wake_unlock(&pm_data->rpm_wake); break; default: break; } pm_data->resume_requested = false; /* check until runtime_status goes to active */ /* attemp 10 times, or re-establish modem-link */ /* if pm_runtime_resume run properly, rpm status must be in ACTIVE */ if (dev->power.runtime_status == RPM_ACTIVE) { pm_data->resume_retry_cnt = 0; complete(&pm_data->active_done); } else if (pm_data->resume_retry_cnt++ > 10) { mif_err("runtime_status(%d), retry_cnt(%d)\n", dev->power.runtime_status, pm_data->resume_retry_cnt); link_pm_change_modem_state(pm_data, STATE_CRASH_RESET); } else queue_delayed_work(pm_data->wq, &pm_data->link_pm_work, msecs_to_jiffies(20)); }
static void mcs6000_work(struct work_struct *work) { int x1=0, y1 = 0; #ifdef LG_FW_MULTI_TOUCH int x2=0, y2 = 0; static int pre_x1, pre_x2, pre_y1, pre_y2; static unsigned int s_input_type = NON_TOUCHED_STATE; #endif unsigned int input_type; unsigned int key_touch; unsigned char read_buf[READ_NUM]; static int key_pressed = 0; static int touch_pressed = 0; struct mcs6000_ts_device *dev = container_of(to_delayed_work(work), struct mcs6000_ts_device, work); dev->pendown = !gpio_get_value(dev->intr_gpio); /* read the registers of MCS6000 IC */ if ( i2c_smbus_read_i2c_block_data(dev->client, MCS6000_TS_INPUT_INFO, READ_NUM, read_buf) < 0) { printk(KERN_ERR "%s touch ic read error\n", __FUNCTION__); goto touch_retry; } input_type = read_buf[0] & 0x0f; key_touch = (read_buf[0] & 0xf0) >> 4; x1 = y1 =0; #ifdef LG_FW_MULTI_TOUCH x2 = y2 = 0; #endif x1 = (read_buf[1] & 0xf0) << 4; y1 = (read_buf[1] & 0x0f) << 8; x1 |= read_buf[2]; y1 |= read_buf[3]; #ifdef LG_FW_MULTI_TOUCH if(input_type == MULTI_POINT_TOUCH) { s_input_type = input_type; x2 = (read_buf[5] & 0xf0) << 4; y2 = (read_buf[5] & 0x0f) << 8; x2 |= read_buf[6]; y2 |= read_buf[7]; } #endif if (dev->pendown) { /* touch pressed case */ #ifdef LG_FW_HARDKEY_BLOCK if(dev->hardkey_block == 0) #endif if(key_touch && key_pressed != key_touch) { if(key_pressed) mcs6000_key_event_touch(key_pressed, RELEASED, dev); mcs6000_key_event_touch(key_touch, PRESSED, dev); key_pressed = key_touch; } if(input_type) { touch_pressed = 1; #ifdef LG_FW_MULTI_TOUCH if(input_type == MULTI_POINT_TOUCH) { mcs6000_multi_ts_event_touch(x1, y1, x2, y2, PRESSED, dev); pre_x1 = x1; pre_y1 = y1; pre_x2 = x2; pre_y2 = y2; } else if(input_type == SINGLE_POINT_TOUCH) { mcs6000_multi_ts_event_touch(x1, y1, -1, -1, PRESSED, dev); s_input_type = SINGLE_POINT_TOUCH; } #else if(input_type == SINGLE_POINT_TOUCH) { mcs6000_single_ts_event_touch(x1, y1, PRESSED, dev); } #endif #ifdef LG_FW_HARDKEY_BLOCK dev->hardkey_block = 1; #endif } } else { /* touch released case */ if(key_pressed) { mcs6000_key_event_touch(key_pressed, RELEASED, dev); key_pressed = 0; } if(touch_pressed) { #ifdef LG_FW_MULTI_TOUCH if(s_input_type == MULTI_POINT_TOUCH) { DMSG("%s: multi touch release...(%d, %d), (%d, %d)\n", __FUNCTION__,pre_x1,pre_y1,pre_x2,pre_y2); mcs6000_multi_ts_event_touch(pre_x1, pre_y1, pre_x2, pre_y2, RELEASED, dev); s_input_type = NON_TOUCHED_STATE; pre_x1 = -1; pre_y1 = -1; pre_x2 = -1; pre_y2 = -1; } else { DMSG("%s: single touch release... %d, %d\n", __FUNCTION__, x1, y1); mcs6000_multi_ts_event_touch(x1, y1, -1, -1, RELEASED, dev); } #else DMSG("%s: single release... %d, %d\n", __FUNCTION__, x1, y1); mcs6000_single_ts_event_touch (x1, y1, RELEASED, dev); touch_pressed = 0; #endif #ifdef LG_FW_HARDKEY_BLOCK hrtimer_cancel(&dev->touch_timer); hrtimer_start(&dev->touch_timer, ktime_set(0, 800), HRTIMER_MODE_REL); #endif } } touch_retry: if (dev->pendown) { //ret = schedule_delayed_work(&dev->work, msecs_to_jiffies(TS_POLLING_TIME)); queue_delayed_work(dev->ts_wq, &dev->work,msecs_to_jiffies(TS_POLLING_TIME)); } else { enable_irq(dev->num_irq); DMSG("%s: irq enable\n", __FUNCTION__); } }
static int hdmi_probe(struct platform_device *pdev) { struct s5p_hdmi_platdata *pdata = NULL; struct device *dev = &pdev->dev; struct resource *res; struct i2c_adapter *phy_adapter; struct hdmi_device *hdmi_dev = NULL; struct hdmi_driver_data *drv_data; int ret; dev_info(dev, "probe start\n"); hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(struct hdmi_device), GFP_KERNEL); if (!hdmi_dev) { dev_err(&pdev->dev, "no memory for hdmi device\n"); return -ENOMEM; } hdmi_dev->dev = dev; hdmi_dev->pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!hdmi_dev->pdata) { dev_err(&pdev->dev, "no memory for state\n"); return -ENOMEM; } /* store platform data ptr to mixer context */ if (dev->of_node) { of_property_read_u32(dev->of_node, "ip_ver", &hdmi_dev->pdata->ip_ver); pdata = hdmi_dev->pdata; } else { hdmi_dev->pdata = dev->platform_data; pdata = hdmi_dev->pdata; } dev_info(dev, "HDMI ip version %d\n", pdata->ip_ver); /* mapping HDMI registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "get hdmi memory resource failed.\n"); return -ENXIO; } hdmi_dev->regs = devm_request_and_ioremap(&pdev->dev, res); if (hdmi_dev->regs == NULL) { dev_err(dev, "failed to claim register region for hdmi\n"); return -ENOENT; } /* mapping HDMIPHY_APB registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res) { dev_err(dev, "get hdmiphy memory resource failed.\n"); return -ENXIO; } hdmi_dev->phy_regs = devm_request_and_ioremap(&pdev->dev, res); if (hdmi_dev->phy_regs == NULL) { dev_err(dev, "failed to claim register region for hdmiphy\n"); return -ENOENT; } /* Internal hpd */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "get internal interrupt resource failed.\n"); return -ENXIO; } ret = devm_request_irq(dev, res->start, hdmi_irq_handler, 0, "hdmi-int", hdmi_dev); if (ret) { dev_err(dev, "request int interrupt failed.\n"); return ret; } else { hdmi_dev->int_irq = res->start; disable_irq(hdmi_dev->int_irq); dev_info(dev, "success request hdmi-int irq\n"); } /* setting v4l2 name to prevent WARN_ON in v4l2_device_register */ strlcpy(hdmi_dev->v4l2_dev.name, dev_name(dev), sizeof(hdmi_dev->v4l2_dev.name)); /* passing NULL owner prevents driver from erasing drvdata */ ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev); if (ret) { dev_err(dev, "could not register v4l2 device.\n"); goto fail; } INIT_WORK(&hdmi_dev->hpd_work, hdmi_hpd_work); INIT_DELAYED_WORK(&hdmi_dev->hpd_work_ext, hdmi_hpd_work_ext); /* setting the clocks */ ret = hdmi_resources_init(hdmi_dev); if (ret) goto fail_vdev; /* setting the GPIO */ ret = hdmi_set_gpio(hdmi_dev); if (ret) { dev_err(dev, "failed to get GPIO\n"); goto fail_clk; } /* register the switch device for HPD */ hdmi_dev->hpd_switch.name = "hdmi"; ret = switch_dev_register(&hdmi_dev->hpd_switch); if (ret) { dev_err(dev, "request switch class failed.\n"); goto fail_gpio; } dev_info(dev, "success register switch device\n"); /* External hpd */ hdmi_dev->ext_irq = gpio_to_irq(hdmi_dev->res.gpio_hpd); ret = devm_request_irq(dev, hdmi_dev->ext_irq, hdmi_irq_handler_ext, IRQ_TYPE_EDGE_BOTH, "hdmi-ext", hdmi_dev); if (ret) { dev_err(dev, "request ext interrupt failed.\n"); goto fail_switch; } else { dev_info(dev, "success request hdmi-ext irq\n"); } mutex_init(&hdmi_dev->mutex); if (soc_is_exynos5250()) { drv_data = (struct hdmi_driver_data *) platform_get_device_id(pdev)->driver_data; dev_info(dev, "hdmiphy i2c bus number = %d\n", drv_data->hdmiphy_bus); phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus); if (phy_adapter == NULL) { dev_err(dev, "adapter request failed\n"); ret = -ENXIO; goto fail_mutex; } hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev, phy_adapter, &hdmiphy_info, NULL); /* on failure or not adapter is no longer useful */ i2c_put_adapter(phy_adapter); if (hdmi_dev->phy_sd == NULL) { dev_err(dev, "missing subdev for hdmiphy\n"); ret = -ENODEV; goto fail_mutex; } } hdmi_dev->cur_timings = hdmi_conf[HDMI_DEFAULT_TIMINGS_IDX].dv_timings; /* FIXME: missing fail preset is not supported */ hdmi_dev->cur_conf = hdmi_conf[HDMI_DEFAULT_TIMINGS_IDX].conf; /* default audio configuration : disable audio */ hdmi_dev->audio_enable = 0; hdmi_dev->audio_channel_count = 2; hdmi_dev->sample_rate = DEFAULT_SAMPLE_RATE; hdmi_dev->color_range = HDMI_RGB709_0_255; hdmi_dev->bits_per_sample = DEFAULT_BITS_PER_SAMPLE; hdmi_dev->audio_codec = DEFAULT_AUDIO_CODEC; /* hdmi audio master clock */ ret = hdmi_get_audio_master(hdmi_dev); if (ret) { hdmi_dev->audio_master_clk = 0; dev_warn(dev, "failed to get audio master information\n"); } /* default aspect ratio is 16:9 */ hdmi_dev->aspect = HDMI_ASPECT_RATIO_16_9; /* default HDMI streaming is stoped */ hdmi_dev->streaming = HDMI_STOP; /* register hdmi subdev as entity */ ret = hdmi_register_entity(hdmi_dev); if (ret) goto fail_mutex; hdmi_entity_info_print(hdmi_dev); pm_runtime_enable(dev); /* initialize hdcp resource */ ret = hdcp_prepare(hdmi_dev); if (ret) goto fail_mutex; /* work after booting */ queue_delayed_work(system_nrt_wq, &hdmi_dev->hpd_work_ext, msecs_to_jiffies(1500)); /* TODO : Check the PHY power off is implemented at pm_domains * If not, PHY power off should be applied at here */ dev_info(dev, "probe sucessful\n"); hdmi_debugfs_init(hdmi_dev); return 0; fail_mutex: mutex_destroy(&hdmi_dev->mutex); fail_switch: switch_dev_unregister(&hdmi_dev->hpd_switch); fail_gpio: gpio_free(hdmi_dev->res.gpio_hpd); gpio_free(hdmi_dev->res.gpio_ls); gpio_free(hdmi_dev->res.gpio_dcdc); fail_clk: hdmi_resources_cleanup(hdmi_dev); fail_vdev: v4l2_device_unregister(&hdmi_dev->v4l2_dev); fail: dev_err(dev, "probe failed\n"); return ret; }
static ssize_t pm8058_led_blink_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct led_classdev *led_cdev; struct pm8058_led_data *ldata; int id, mode; int val; int enable = 0; #ifdef CONFIG_HTC_HEADSET_MISC int *pduties; #endif /*struct timespec ts1, ts2;*/ val = -1; sscanf(buf, "%u", &val); if (val < 0 || val > 255) return -EINVAL; led_cdev = (struct led_classdev *) dev_get_drvdata(dev); ldata = container_of(led_cdev, struct pm8058_led_data, ldev); id = bank_to_id(ldata->bank); mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 : PM_PWM_CONF_PWM1 + (ldata->bank - 4); if (ldata->flags & PM8058_LED_BLINK_EN) pm8058_pwm_config_led(ldata->pwm_led, id, mode, ldata->out_current); LED_INFO_LOG("%s: bank %d blink %d\n", __func__, ldata->bank, val); enable = (val > 0) ? 1 : 0; if (strcmp(ldata->ldev.name, "charming-led") == 0) charming_led_enable(enable); switch (val) { case -1: /* stop flashing */ pwm_disable(ldata->pwm_led); if (ldata->flags & PM8058_LED_BLINK_EN) pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); break; case 0: pwm_disable(ldata->pwm_led); if (led_cdev->brightness) { pwm_config(ldata->pwm_led, 64000, 64000); pwm_enable(ldata->pwm_led); } else { if (ldata->flags & PM8058_LED_BLINK_EN) pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); } break; case 1: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 64000, 2000000); pwm_enable(ldata->pwm_led); break; case 2: cancel_delayed_work_sync(&ldata->led_delayed_work); pwm_disable(ldata->pwm_led); ldata->duty_time_ms = 64; ldata->period_us = 2000000; queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(310)); break; case 3: cancel_delayed_work_sync(&ldata->led_delayed_work); pwm_disable(ldata->pwm_led); ldata->duty_time_ms = 64; ldata->period_us = 2000000; queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(1000)); break; case 4: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 1000000, 2000000); #if 0 pwm_conf.pwm_size = 9; pwm_conf.clk = PM_PWM_CLK_1KHZ; pwm_conf.pre_div = PM_PWM_PREDIVIDE_2; pwm_conf.pre_div_exp = 1; pwm_conf.pwm_value = 512/2; pwm_conf.bypass_lut = 1; pwm_configure(ldata->pwm_led, &pwm_conf); #endif pwm_enable(ldata->pwm_led); break; case 5: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 100000, 200000); pwm_enable(ldata->pwm_led); break; #ifdef CONFIG_HTC_HEADSET_MISC case 6: pm8058_pwm_config_led(ldata->pwm_led, id, mode, ldata->out_current); pduties = &duties[ldata->start_index]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index, ldata->duites_size, 0, 0, ldata->lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 0); pm8058_pwm_lut_enable(ldata->pwm_led, 1); break; case 7: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 64000, 4000000); pwm_enable(ldata->pwm_led); break; #endif default: LED_ERR_LOG(KERN_INFO "%s: bank %d not support blink %d\n", __func__, ldata->bank, val); return -EINVAL; } return count; }
static void tegra_auto_hotplug_work_func(struct work_struct *work) { bool up = false; unsigned int cpu = nr_cpu_ids; unsigned long now = jiffies; static unsigned long last_change_time; mutex_lock(tegra3_cpu_lock); switch (hp_state) { case TEGRA_HP_DISABLED: case TEGRA_HP_IDLE: break; case TEGRA_HP_DOWN: cpu = tegra_get_slowest_cpu_n(); if (cpu < nr_cpu_ids) { up = false; } else if (!is_lp_cluster() && !no_lp && !pm_qos_request(PM_QOS_MIN_ONLINE_CPUS)) { if(!clk_set_parent(cpu_clk, cpu_lp_clk)) { hp_stats_update(CONFIG_NR_CPUS, true); hp_stats_update(0, false); /* catch-up with governor target speed */ tegra_cpu_set_speed_cap(NULL); break; } } queue_delayed_work( hotplug_wq, &hotplug_work, down_delay); break; case TEGRA_HP_UP: if (is_lp_cluster() && !no_lp) { if(!clk_set_parent(cpu_clk, cpu_g_clk)) { hp_stats_update(CONFIG_NR_CPUS, false); hp_stats_update(0, true); /* catch-up with governor target speed */ tegra_cpu_set_speed_cap(NULL); } } else { switch (tegra_cpu_speed_balance()) { /* cpu speed is up and balanced - one more on-line */ case TEGRA_CPU_SPEED_BALANCED: cpu = cpumask_next_zero(0, cpu_online_mask); if (cpu < nr_cpu_ids) up = true; break; /* cpu speed is up, but skewed - remove one core */ case TEGRA_CPU_SPEED_SKEWED: cpu = tegra_get_slowest_cpu_n(); if (cpu < nr_cpu_ids) up = false; break; /* cpu speed is up, but under-utilized - do nothing */ case TEGRA_CPU_SPEED_BIASED: default: break; } } queue_delayed_work( hotplug_wq, &hotplug_work, up2gn_delay); break; default: pr_err("%s: invalid tegra hotplug state %d\n", __func__, hp_state); } if (!up && ((now - last_change_time) < down_delay)) cpu = nr_cpu_ids; if (cpu < nr_cpu_ids) { last_change_time = now; hp_stats_update(cpu, up); } mutex_unlock(tegra3_cpu_lock); if (cpu < nr_cpu_ids) { if (up){ printk("cpu_up(%u)+\n",cpu); cpu_up(cpu); printk("cpu_up(%u)-\n",cpu); }else{ printk("cpu_down(%u)+\n",cpu); cpu_down(cpu); printk("cpu_down(%u)-\n",cpu); } } }