static int btusb_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct btusb_data *data = hci_get_drvdata(hdev); struct usb_ctrlrequest *dr; struct urb *urb; unsigned int pipe; int err; BT_DBG("%s", hdev->name); if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; dr = kmalloc(sizeof(*dr), GFP_ATOMIC); if (!dr) { usb_free_urb(urb); return -ENOMEM; } dr->bRequestType = data->cmdreq_type; dr->bRequest = 0; dr->wIndex = 0; dr->wValue = 0; dr->wLength = __cpu_to_le16(skb->len); pipe = usb_sndctrlpipe(data->udev, 0x00); usb_fill_control_urb(urb, data->udev, pipe, (void *) dr, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: if (!data->bulk_tx_ep) return -ENODEV; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) return -ENODEV; urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); if (!urb) return -ENOMEM; pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); usb_fill_int_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_isoc_tx_complete, skb, data->isoc_tx_ep->bInterval); urb->transfer_flags = URB_ISO_ASAP; __fill_isoc_descriptor(urb, skb->len, le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); hdev->stat.sco_tx++; goto skip_waking; default: return -EILSEQ; } err = inc_tx(data); if (err) { usb_anchor_urb(urb, &data->deferred); schedule_work(&data->waker); err = 0; goto done; } skip_waking: usb_anchor_urb(urb, &data->tx_anchor); err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p submission failed (%d)", hdev->name, urb, -err); kfree(urb->setup_packet); usb_unanchor_urb(urb); } else { usb_mark_last_busy(data->udev); } done: usb_free_urb(urb); return err; }
static int lge_hsd_probe(struct platform_device *pdev) { int ret = 0; struct max1462x_platform_data *pdata = pdev->dev.platform_data; struct hsd_info *hi; HSD_DBG("lge_hsd_probe\n"); hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL); if (hi == NULL) { HSD_ERR("Failed to allloate headset per device info\n"); return -ENOMEM; } if (pdev->dev.of_node) { pdata = devm_kzalloc(&pdev->dev, sizeof(struct max1462x_platform_data), GFP_KERNEL); if (!pdata) { HSD_ERR("Failed to allocate memory\n"); return -ENOMEM; } pdev->dev.platform_data = pdata; max1462x_parse_dt(&pdev->dev, pdata); } else { pdata = devm_kzalloc(&pdev->dev, sizeof(struct max1462x_platform_data), GFP_KERNEL); if (!pdata) { HSD_ERR("Failed to allocate memory\n"); return -ENOMEM; } else { pdata = pdev->dev.platform_data; } } 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); atomic_set(&hi->irq_key_enabled, FALSE); hi->gpio_mic_en = pdata->gpio_mic_en; hi->gpio_detect = pdata->gpio_detect; hi->gpio_key = pdata->gpio_key; hi->gpio_set_value_func = pdata->gpio_set_value_func; hi->gpio_get_value_func = pdata->gpio_get_value_func; hi->latency_for_key = msecs_to_jiffies(50); /* convert milli to jiffies */ mutex_init(&hi->mutex_lock); INIT_WORK(&hi->work, detect_work); INIT_DELAYED_WORK(&hi->work_for_key_pressed, button_pressed); INIT_DELAYED_WORK(&hi->work_for_key_released, button_released); 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_02; } ret = gpio_direction_output(hi->gpio_mic_en, 0); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_direction_input\n", hi->gpio_mic_en); goto error_02; } HSD_DBG("gpio_get_value_cansleep(hi->gpio_mic_en) = %d\n", gpio_get_value_cansleep(hi->gpio_mic_en)); /* init gpio_detect */ ret = gpio_request(hi->gpio_detect, "gpio_detect"); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_request\n", hi->gpio_detect); goto error_03; } ret = gpio_direction_input(hi->gpio_detect); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_direction_input\n", hi->gpio_detect); goto error_03; } /*init 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_04; } 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 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; } ret = request_threaded_irq(hi->irq_key, NULL, button_irq_handler, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, hi); if (ret) { HSD_ERR("failed to request button irq\n"); goto error_06; } ret = irq_set_irq_wake(hi->irq_key, 1); if (ret < 0) { HSD_ERR("Failed to set irq_key interrupt wake\n"); goto error_06; } 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_07; } ret = request_threaded_irq(hi->irq_detect, NULL, earjack_det_irq_handler, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, hi); if (ret) { HSD_ERR("failed to request button irq\n"); goto error_07; } ret = irq_set_irq_wake(hi->irq_detect, 1); if (ret < 0) { HSD_ERR("Failed to set gpio_detect interrupt wake\n"); goto error_07; } /* initialize switch device */ hi->sdev.name = pdata->switch_name; hi->sdev.print_state = lge_hsd_print_state; ret = switch_dev_register(&hi->sdev); if (ret < 0) { HSD_ERR("Failed to register switch device\n"); goto error_08; } /* initialize input device */ hi->input = input_allocate_device(); if (!hi->input) { HSD_ERR("Failed to allocate input device\n"); ret = -ENOMEM; goto error_09; } hi->input->name = pdata->keypad_name; hi->input->id.vendor = 0x0001; hi->input->id.product = 1; hi->input->id.version = 1; 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); input_set_capability(hi->input, EV_KEY, KEY_MEDIA); input_set_capability(hi->input, EV_KEY, 582); input_set_capability(hi->input, EV_KEY, KEY_VOLUMEUP); input_set_capability(hi->input, EV_KEY, KEY_VOLUMEDOWN); ret = input_register_device(hi->input); if (ret) { HSD_ERR("Failed to register input device\n"); goto error_09; } if (!(hi->gpio_get_value_func(hi->gpio_detect))) #ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE /* to detect in initialization with eacjack insertion */ queue_work(local_max1462x_workqueue, &(hi->work)); #else /* to detect in initialization with eacjack insertion */ schedule_work(&(hi->work)); #endif return ret; error_09: input_free_device(hi->input); error_08: switch_dev_unregister(&hi->sdev); error_07: free_irq(hi->irq_detect, 0); error_06: free_irq(hi->irq_key, 0); error_04: gpio_free(hi->gpio_key); error_03: gpio_free(hi->gpio_detect); error_02: gpio_free(hi->gpio_mic_en); kfree(hi); return ret; }
static int rfkill_init(struct platform_device *sdev) { /* add rfkill */ int retval; /* keep the hardware wireless state */ get_wireless_state_ec_standard(); rfk_bluetooth = rfkill_alloc("msi-bluetooth", &sdev->dev, RFKILL_TYPE_BLUETOOTH, &rfkill_bluetooth_ops, NULL); if (!rfk_bluetooth) { retval = -ENOMEM; goto err_bluetooth; } retval = rfkill_register(rfk_bluetooth); if (retval) goto err_bluetooth; rfk_wlan = rfkill_alloc("msi-wlan", &sdev->dev, RFKILL_TYPE_WLAN, &rfkill_wlan_ops, NULL); if (!rfk_wlan) { retval = -ENOMEM; goto err_wlan; } retval = rfkill_register(rfk_wlan); if (retval) goto err_wlan; if (threeg_exists) { rfk_threeg = rfkill_alloc("msi-threeg", &sdev->dev, RFKILL_TYPE_WWAN, &rfkill_threeg_ops, NULL); if (!rfk_threeg) { retval = -ENOMEM; goto err_threeg; } retval = rfkill_register(rfk_threeg); if (retval) goto err_threeg; } /* schedule to run rfkill state initial */ if (quirks->ec_delay) { schedule_delayed_work(&msi_rfkill_init, round_jiffies_relative(1 * HZ)); } else schedule_work(&msi_rfkill_work); return 0; err_threeg: rfkill_destroy(rfk_threeg); if (rfk_wlan) rfkill_unregister(rfk_wlan); err_wlan: rfkill_destroy(rfk_wlan); if (rfk_bluetooth) rfkill_unregister(rfk_bluetooth); err_bluetooth: rfkill_destroy(rfk_bluetooth); return retval; }
static void bch_l2l1(struct hisax_if *ifc, int pr, void *arg) { struct hfc4s8s_btype *bch = ifc->priv; struct hfc4s8s_l1 *l1 = bch->l1p; struct sk_buff *skb = (struct sk_buff *) arg; long mode = (long) arg; u_long flags; switch (pr) { case (PH_DATA | REQUEST): if (!l1->enabled || (bch->mode == L1_MODE_NULL)) { dev_kfree_skb(skb); break; } spin_lock_irqsave(&l1->lock, flags); skb_queue_tail(&bch->tx_queue, skb); if (!bch->tx_skb && (bch->tx_cnt <= 0)) { l1->hw->mr.r_irq_fifo_blx[l1->st_num] |= ((bch->bchan == 1) ? 1 : 4); spin_unlock_irqrestore(&l1->lock, flags); schedule_work(&l1->hw->tqueue); } else spin_unlock_irqrestore(&l1->lock, flags); break; case (PH_ACTIVATE | REQUEST): case (PH_DEACTIVATE | REQUEST): if (!l1->enabled) break; if (pr == (PH_DEACTIVATE | REQUEST)) mode = L1_MODE_NULL; switch (mode) { case L1_MODE_HDLC: spin_lock_irqsave(&l1->lock, flags); l1->hw->mr.timer_usg_cnt++; l1->hw->mr. fifo_slow_timer_service[l1-> st_num] |= ((bch->bchan == 1) ? 0x2 : 0x8); Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_CON_HDLC, 0xc); /* HDLC mode, flag fill, connect ST */ Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ Write_hfc8(l1->hw, A_IRQ_MSK, 1); /* enable TX interrupts for hdlc */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ wait_busy(l1->hw); Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 1 : 3))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_CON_HDLC, 0xc); /* HDLC mode, flag fill, connect ST */ Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ Write_hfc8(l1->hw, A_IRQ_MSK, 1); /* enable RX interrupts for hdlc */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); l1->hw->mr.r_ctrl0 |= (bch->bchan & 3); Write_hfc8(l1->hw, A_ST_CTRL0, l1->hw->mr.r_ctrl0); bch->mode = L1_MODE_HDLC; spin_unlock_irqrestore(&l1->lock, flags); bch->b_if.ifc.l1l2(&bch->b_if.ifc, PH_ACTIVATE | INDICATION, NULL); break; case L1_MODE_TRANS: spin_lock_irqsave(&l1->lock, flags); l1->hw->mr. fifo_rx_trans_enables[l1-> st_num] |= ((bch->bchan == 1) ? 0x2 : 0x8); l1->hw->mr.timer_usg_cnt++; Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_CON_HDLC, 0xf); /* Transparent mode, 1 fill, connect ST */ Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable TX interrupts */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ wait_busy(l1->hw); Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 1 : 3))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_CON_HDLC, 0xf); /* Transparent mode, 1 fill, connect ST */ Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable RX interrupts */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); l1->hw->mr.r_ctrl0 |= (bch->bchan & 3); Write_hfc8(l1->hw, A_ST_CTRL0, l1->hw->mr.r_ctrl0); bch->mode = L1_MODE_TRANS; spin_unlock_irqrestore(&l1->lock, flags); bch->b_if.ifc.l1l2(&bch->b_if.ifc, PH_ACTIVATE | INDICATION, NULL); break; default: if (bch->mode == L1_MODE_NULL) break; spin_lock_irqsave(&l1->lock, flags); l1->hw->mr. fifo_slow_timer_service[l1-> st_num] &= ~((bch->bchan == 1) ? 0x3 : 0xc); l1->hw->mr. fifo_rx_trans_enables[l1-> st_num] &= ~((bch->bchan == 1) ? 0x3 : 0xc); l1->hw->mr.timer_usg_cnt--; Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable TX interrupts */ wait_busy(l1->hw); Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 1 : 3))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable RX interrupts */ Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); l1->hw->mr.r_ctrl0 &= ~(bch->bchan & 3); Write_hfc8(l1->hw, A_ST_CTRL0, l1->hw->mr.r_ctrl0); spin_unlock_irqrestore(&l1->lock, flags); bch->mode = L1_MODE_NULL; bch->b_if.ifc.l1l2(&bch->b_if.ifc, PH_DEACTIVATE | INDICATION, NULL); if (bch->tx_skb) { dev_kfree_skb(bch->tx_skb); bch->tx_skb = NULL; } if (bch->rx_skb) { dev_kfree_skb(bch->rx_skb); bch->rx_skb = NULL; } skb_queue_purge(&bch->tx_queue); bch->tx_cnt = 0; bch->rx_ptr = NULL; break; } /* timer is only used when at least one b channel */ /* is set up to transparent mode */ if (l1->hw->mr.timer_usg_cnt) { Write_hfc8(l1->hw, R_IRQMSK_MISC, M_TI_IRQMSK); } else { Write_hfc8(l1->hw, R_IRQMSK_MISC, 0); } break; default: printk(KERN_INFO "HFC-4S/8S: Unknown B-chan cmd 0x%x received, ignored\n", pr); break; } if (!l1->enabled) bch->b_if.ifc.l1l2(&bch->b_if.ifc, PH_DEACTIVATE | INDICATION, NULL); } /* bch_l2l1 */
void bl_timer_callback(unsigned long data) { schedule_work(&bl_off_work); }
void lbs_set_multicast_list(struct net_device *dev) { struct lbs_private *priv = dev->ml_priv; schedule_work(&priv->mcast_work); }
static void hotplug_decision_work_fn(struct work_struct *work) { unsigned int running, disable_load, sampling_rate, enable_load, avg_running = 0; unsigned int online_cpus, available_cpus, i, j; #if DEBUG unsigned int k; #endif online_cpus = num_online_cpus(); available_cpus = CPUS_AVAILABLE; disable_load = DISABLE_LOAD_THRESHOLD * online_cpus; enable_load = ENABLE_LOAD_THRESHOLD * online_cpus; /* * Multiply nr_running() by 100 so we don't have to * use fp division to get the average. */ running = nr_running() * 100; history[index] = running; #if DEBUG pr_info("online_cpus is: %d\n", online_cpus); pr_info("enable_load is: %d\n", enable_load); pr_info("disable_load is: %d\n", disable_load); pr_info("index is: %d\n", index); pr_info("running is: %d\n", running); #endif /* * Use a circular buffer to calculate the average load * over the sampling periods. * This will absorb load spikes of short duration where * we don't want additional cores to be onlined because * the cpufreq driver should take care of those load spikes. */ for (i = 0, j = index; i < SAMPLING_PERIODS; i++, j--) { avg_running += history[j]; if (unlikely(j == 0)) j = INDEX_MAX_VALUE; } /* * If we are at the end of the buffer, return to the beginning. */ if (unlikely(index++ == INDEX_MAX_VALUE)) index = 0; #if DEBUG pr_info("array contents: "); for (k = 0; k < SAMPLING_PERIODS; k++) { pr_info("%d: %d\t",k, history[k]); } pr_info("\n"); pr_info("avg_running before division: %d\n", avg_running); #endif avg_running = avg_running / SAMPLING_PERIODS; #if DEBUG pr_info("average_running is: %d\n", avg_running); #endif if (likely(!(flags & HOTPLUG_DISABLED))) { if (unlikely((avg_running >= ENABLE_ALL_LOAD_THRESHOLD) && (online_cpus < available_cpus) && (max_online_cpus > online_cpus))) { pr_info("auto_hotplug: Onlining all CPUs, avg running: %d\n", avg_running); /* * Flush any delayed offlining work from the workqueue. * No point in having expensive unnecessary hotplug transitions. * We still online after flushing, because load is high enough to * warrant it. * We set the paused flag so the sampling can continue but no more * hotplug events will occur. */ flags |= HOTPLUG_PAUSED; if (delayed_work_pending(&hotplug_offline_work)) cancel_delayed_work(&hotplug_offline_work); schedule_work(&hotplug_online_all_work); return; } else if (flags & HOTPLUG_PAUSED) { schedule_delayed_work_on(0, &hotplug_decision_work, MIN_SAMPLING_RATE); return; } else if ((avg_running >= enable_load) && (online_cpus < available_cpus) && (max_online_cpus > online_cpus)) { pr_info("auto_hotplug: Onlining single CPU, avg running: %d\n", avg_running); if (delayed_work_pending(&hotplug_offline_work)) cancel_delayed_work(&hotplug_offline_work); schedule_work(&hotplug_online_single_work); return; } else if ((avg_running <= disable_load) && (min_online_cpus < online_cpus)) { /* Only queue a cpu_down() if there isn't one already pending */ if (!(delayed_work_pending(&hotplug_offline_work))) { pr_info("auto_hotplug: Offlining CPU, avg running: %d\n", avg_running); schedule_delayed_work_on(0, &hotplug_offline_work, HZ); } /* If boostpulse is active, clear the flags */ if (flags & BOOSTPULSE_ACTIVE) { flags &= ~BOOSTPULSE_ACTIVE; pr_info("auto_hotplug: Clearing boostpulse flags\n"); } } } /* * Reduce the sampling rate dynamically based on online cpus. */ sampling_rate = MIN_SAMPLING_RATE * (online_cpus * online_cpus); #if DEBUG pr_info("sampling_rate is: %d\n", jiffies_to_msecs(sampling_rate)); #endif schedule_delayed_work_on(0, &hotplug_decision_work, sampling_rate); }
/* Resets the Xen limit, sets new target, and kicks off processing. */ static void balloon_set_new_target(unsigned long target) { /* No need for lock. Not read-modify-write updates. */ balloon_stats.target_pages = target; schedule_work(&balloon_worker); }
int lbs_process_event(struct lbs_private *priv, u32 event) { int ret = 0; lbs_deb_enter(LBS_DEB_CMD); switch (event) { case MACREG_INT_CODE_LINK_SENSED: printk("EVENT: link sensed\n");//掉线 break; case MACREG_INT_CODE_DEAUTHENTICATED: printk("EVENT: deauthenticated\n"); //lbs_mac_event_disconnected(priv); break; case MACREG_INT_CODE_DISASSOCIATED: printk("EVENT: disassociated\n"); //lbs_mac_event_disconnected(priv); break; case MACREG_INT_CODE_LINK_LOST_NO_SCAN: printk("EVENT: link lost\n"); //lbs_mac_event_disconnected(priv); break; case MACREG_INT_CODE_PS_SLEEP: printk("EVENT: ps sleep\n"); /* handle unexpected PS SLEEP event */ if (priv->psstate == PS_STATE_FULL_POWER) { printk("EVENT: in FULL POWER mode, ignoreing PS_SLEEP\n"); break; } priv->psstate = PS_STATE_PRE_SLEEP; //lbs_ps_confirm_sleep(priv); break; case MACREG_INT_CODE_HOST_AWAKE: printk("EVENT: host awake\n"); //lbs_send_confirmwake(priv); break; case MACREG_INT_CODE_PS_AWAKE: printk("EVENT: ps awake\n"); /* handle unexpected PS AWAKE event */ if (priv->psstate == PS_STATE_FULL_POWER) { printk( "EVENT: In FULL POWER mode - ignore PS AWAKE\n"); break; } priv->psstate = PS_STATE_AWAKE; if (priv->needtowakeup) { /* * wait for the command processing to finish * before resuming sending * priv->needtowakeup will be set to FALSE * in lbs_ps_wakeup() */ printk("waking up ...\n"); //lbs_ps_wakeup(priv, 0); } break; case MACREG_INT_CODE_MIC_ERR_UNICAST: printk("EVENT: UNICAST MIC ERROR\n"); //handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST); break; case MACREG_INT_CODE_MIC_ERR_MULTICAST: printk("EVENT: MULTICAST MIC ERROR\n"); //handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST); break; case MACREG_INT_CODE_MIB_CHANGED: printk("EVENT: MIB CHANGED\n"); break; case MACREG_INT_CODE_INIT_DONE: printk("EVENT: INIT DONE\n"); break; case MACREG_INT_CODE_ADHOC_BCN_LOST: printk("EVENT: ADHOC beacon lost\n"); break; case MACREG_INT_CODE_RSSI_LOW: printk("EVENT: rssi low\n"); break; case MACREG_INT_CODE_SNR_LOW: printk("EVENT: snr low\n"); break; case MACREG_INT_CODE_MAX_FAIL: printk("EVENT: max fail\n"); break; case MACREG_INT_CODE_RSSI_HIGH: printk("EVENT: rssi high\n"); break; case MACREG_INT_CODE_SNR_HIGH: printk("EVENT: snr high\n"); break; #ifdef MASK_DEBUG case MACREG_INT_CODE_MESH_AUTO_STARTED: /* Ignore spurious autostart events if autostart is disabled */ if (!priv->mesh_autostart_enabled) { lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n"); break; } lbs_pr_info("EVENT: MESH_AUTO_STARTED\n"); priv->mesh_connect_status = LBS_CONNECTED; if (priv->mesh_open) { netif_carrier_on(priv->mesh_dev); if (!priv->tx_pending_len) netif_wake_queue(priv->mesh_dev); } priv->mode = IW_MODE_ADHOC; schedule_work(&priv->sync_channel); break; #endif default: printk("EVENT: unknown event id %d\n", event); break; } lbs_deb_leave_args(LBS_DEB_CMD, ret); return ret; }
static int apanic_proc_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { schedule_work(&proc_removal_work); return count; }
static void balloon_alarm(unsigned long unused) { schedule_work(&balloon_worker); }
void pwr_trig_fscreen(void) { if (mutex_trylock(&scr_lock)) schedule_work(&screenwake_presspwr_work); }
static void bcm203x_complete(struct urb *urb) { struct bcm203x_data *data = urb->context; struct usb_device *udev = urb->dev; int len; BT_DBG("udev %p urb %p", udev, urb); if (urb->status) { BT_ERR("URB failed with status %d", urb->status); data->state = BCM203X_ERROR; return; } switch (data->state) { case BCM203X_LOAD_MINIDRV: memcpy(data->buffer, "#", 1); usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP), data->buffer, 1, bcm203x_complete, data); data->state = BCM203X_SELECT_MEMORY; schedule_work(&data->work); break; case BCM203X_SELECT_MEMORY: usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP), data->buffer, 32, bcm203x_complete, data, 1); data->state = BCM203X_CHECK_MEMORY; if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) BT_ERR("Can't submit URB"); break; case BCM203X_CHECK_MEMORY: if (data->buffer[0] != '#') { BT_ERR("Memory select failed"); data->state = BCM203X_ERROR; break; } data->state = BCM203X_LOAD_FIRMWARE; case BCM203X_LOAD_FIRMWARE: if (data->fw_sent == data->fw_size) { usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP), data->buffer, 32, bcm203x_complete, data, 1); data->state = BCM203X_CHECK_FIRMWARE; } else { len = min_t(uint, data->fw_size - data->fw_sent, 4096); usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP), data->fw_data + data->fw_sent, len, bcm203x_complete, data); data->fw_sent += len; } if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) BT_ERR("Can't submit URB"); break; case BCM203X_CHECK_FIRMWARE: if (data->buffer[0] != '.') { BT_ERR("Firmware loading failed"); data->state = BCM203X_ERROR; break; } data->state = BCM203X_RESET; break; } }
static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id *id) { const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); struct bcm203x_data *data; int size; BT_DBG("intf %p id %p", intf, id); if (intf->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { BT_ERR("Can't allocate memory for data structure"); return -ENOMEM; } data->udev = udev; data->state = BCM203X_LOAD_MINIDRV; data->urb = usb_alloc_urb(0, GFP_KERNEL); if (!data->urb) { BT_ERR("Can't allocate URB"); kfree(data); return -ENOMEM; } if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) { BT_ERR("Mini driver request failed"); usb_free_urb(data->urb); kfree(data); return -EIO; } BT_DBG("minidrv data %p size %zu", firmware->data, firmware->size); size = max_t(uint, firmware->size, 4096); data->buffer = kmalloc(size, GFP_KERNEL); if (!data->buffer) { BT_ERR("Can't allocate memory for mini driver"); release_firmware(firmware); usb_free_urb(data->urb); kfree(data); return -ENOMEM; } memcpy(data->buffer, firmware->data, firmware->size); usb_fill_bulk_urb(data->urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP), data->buffer, firmware->size, bcm203x_complete, data); release_firmware(firmware); if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) { BT_ERR("Firmware request failed"); usb_free_urb(data->urb); kfree(data->buffer); kfree(data); return -EIO; } BT_DBG("firmware data %p size %zu", firmware->data, firmware->size); data->fw_data = kmalloc(firmware->size, GFP_KERNEL); if (!data->fw_data) { BT_ERR("Can't allocate memory for firmware image"); release_firmware(firmware); usb_free_urb(data->urb); kfree(data->buffer); kfree(data); return -ENOMEM; } memcpy(data->fw_data, firmware->data, firmware->size); data->fw_size = firmware->size; data->fw_sent = 0; release_firmware(firmware); INIT_WORK(&data->work, bcm203x_work); usb_set_intfdata(intf, data); schedule_work(&data->work); return 0; }
static int fsa9485_detect_dev(struct fsa9485_usbsw *usbsw) { int device_type, ret; unsigned int dev1, dev2, adc; struct fsa9485_platform_data *pdata = usbsw->pdata; struct i2c_client *client = usbsw->client; #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) // u8 mhl_ret = 0; #endif pr_info("%s", __func__); device_type = i2c_smbus_read_word_data(client, FSA9485_REG_DEV_T1); if (device_type < 0) { dev_err(&client->dev, "%s: err %d\n", __func__, device_type); return device_type; } dev1 = device_type & 0xff; dev2 = device_type >> 8; adc = i2c_smbus_read_byte_data(client, FSA9485_REG_ADC); if (usbsw->dock_attached) pdata->dock_cb(FSA9485_DETACHED_DOCK); if (local_usbsw->dock_ready == 1) { if (adc == 0x10) dev2 = DEV_SMARTDOCK; else if (adc == 0x12) dev2 = DEV_AUDIO_DOCK; } dev_info(&client->dev, "dev1: 0x%02x, dev2: 0x%02x, adc: 0x%02x\n", dev1, dev2, adc); /* Attached */ if (dev1 || dev2) { /* USB */ if (dev1 & DEV_USB || dev2 & DEV_T2_USB_MASK) { dev_info(&client->dev, "usb connect\n"); if (pdata->usb_cb) pdata->usb_cb(FSA9485_ATTACHED); if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, usbsw->mansw); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* USB_CDP */ } else if (dev1 & DEV_USB_CHG) { dev_info(&client->dev, "usb_cdp connect\n"); if (pdata->usb_cdp_cb) pdata->usb_cdp_cb(FSA9485_ATTACHED); if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, usbsw->mansw); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* UART */ } else if (dev1 & DEV_T1_UART_MASK || dev2 & DEV_T2_UART_MASK) { uart_connecting = 1; dev_info(&client->dev, "uart connect\n"); i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1E); if (pdata->uart_cb) pdata->uart_cb(FSA9485_ATTACHED); if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_UART); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* CHARGER */ } else if (dev1 & DEV_T1_CHARGER_MASK) { dev_info(&client->dev, "charger connect\n"); if (pdata->charger_cb) pdata->charger_cb(FSA9485_ATTACHED); /* for SAMSUNG OTG */ } else if (dev1 & DEV_USB_OTG) { dev_info(&client->dev, "otg connect\n"); if (pdata->otg_cb) pdata->otg_cb(FSA9485_ATTACHED); i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, 0x27); i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW2, 0x02); msleep(50); i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1a); /* JIG */ } else if (dev2 & DEV_T2_JIG_MASK) { dev_info(&client->dev, "jig connect\n"); if (pdata->jig_cb) pdata->jig_cb(FSA9485_ATTACHED); /* Desk Dock */ } else if (dev2 & DEV_AV) { if ((adc & 0x1F) == ADC_DESKDOCK) { dev_info(&client->dev, "FSA Deskdock Attach\n"); FSA9485_CheckAndHookAudioDock(1); usbsw->deskdock = 1; #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) isDeskdockconnected = 1; #endif i2c_smbus_write_byte_data(client, FSA9485_REG_RESERVED_20, 0x08); } else { dev_info(&client->dev, "FSA MHL Attach\n"); i2c_smbus_write_byte_data(client, FSA9485_REG_RESERVED_20, 0x08); #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) DisableFSA9485Interrupts(); isMhlAttached = MHL_ATTACHED; schedule_work(&usbsw->mhl_work); EnableFSA9485Interrupts(); #else dev_info(&client->dev, "FSA mhl attach, but not support MHL feature!\n"); #endif } /* Car Dock */ } else if (dev2 & DEV_JIG_UART_ON) { #if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK) if (usbsw->is_factory_start) { #endif dev_info(&client->dev, "car dock connect\n"); if (pdata->dock_cb) pdata->dock_cb(FSA9485_ATTACHED_CAR_DOCK); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_AUDIO); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); usbsw->dock_attached = FSA9485_ATTACHED; #if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK) } else { uart_connecting = 1; dev_info(&client->dev, "uart connect\n"); i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1E); if (pdata->uart_cb) pdata->uart_cb(FSA9485_ATTACHED); if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_UART); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } } #endif /* !CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK */ /* SmartDock */ } else if (dev2 & DEV_SMARTDOCK) { usbsw->adc = adc; dev_info(&client->dev, "smart dock connect\n"); usbsw->mansw = SW_DHOST; ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_DHOST); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); if (pdata->smartdock_cb) pdata->smartdock_cb(FSA9485_ATTACHED); #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) // mhl_onoff_ex(1); #endif } else if (dev2 & DEV_AUDIO_DOCK) { usbsw->adc = adc; dev_info(&client->dev, "audio dock connect\n"); usbsw->mansw = SW_DHOST; ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_DHOST); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); if (pdata->audio_dock_cb) pdata->audio_dock_cb(FSA9485_ATTACHED); } /* Detached */ } else { /* USB */ if (usbsw->dev1 & DEV_USB || usbsw->dev2 & DEV_T2_USB_MASK) { if (pdata->usb_cb) pdata->usb_cb(FSA9485_DETACHED); } else if (usbsw->dev1 & DEV_USB_CHG) { if (pdata->usb_cdp_cb) pdata->usb_cdp_cb(FSA9485_DETACHED); /* UART */ } else if (usbsw->dev1 & DEV_T1_UART_MASK || usbsw->dev2 & DEV_T2_UART_MASK) { if (pdata->uart_cb) pdata->uart_cb(FSA9485_DETACHED); uart_connecting = 0; dev_info(&client->dev, "[FSA9485] uart disconnect\n"); /* CHARGER */ } else if (usbsw->dev1 & DEV_T1_CHARGER_MASK) { if (pdata->charger_cb) pdata->charger_cb(FSA9485_DETACHED); /* for SAMSUNG OTG */ } else if (usbsw->dev1 & DEV_USB_OTG) { if (pdata->otg_cb) pdata->otg_cb(FSA9485_DETACHED); i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1E); /* JIG */ } else if (usbsw->dev2 & DEV_T2_JIG_MASK) { if (pdata->jig_cb) pdata->jig_cb(FSA9485_DETACHED); /* Desk Dock */ } else if (usbsw->dev2 & DEV_AV) { pr_info("FSA MHL Detach\n"); i2c_smbus_write_byte_data(client, FSA9485_REG_RESERVED_20, 0x04); #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) if (isDeskdockconnected) FSA9485_CheckAndHookAudioDock(0); isMhlAttached = MHL_DETACHED; schedule_work(&usbsw->mhl_work); isDeskdockconnected = 0; #else if (usbsw->deskdock) { FSA9485_CheckAndHookAudioDock(0); usbsw->deskdock = 0; } else { pr_info("FSA detach mhl cable, but not support MHL feature\n"); } #endif /* Car Dock */ } else if (usbsw->dev2 & DEV_JIG_UART_ON) { #if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK) if (usbsw->is_factory_start) { #endif if (pdata->dock_cb) pdata->dock_cb(FSA9485_DETACHED_DOCK); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); usbsw->dock_attached = FSA9485_DETACHED; #if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK) } else { if (pdata->uart_cb) pdata->uart_cb(FSA9485_DETACHED); uart_connecting = 0; dev_info(&client->dev, "[FSA9485] uart disconnect\n"); } #endif /* !CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK */ } else if (usbsw->adc == 0x10) { dev_info(&client->dev, "smart dock disconnect\n"); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); if (pdata->smartdock_cb) pdata->smartdock_cb(FSA9485_DETACHED); usbsw->adc = 0; #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) // mhl_onoff_ex(false); #endif } else if (usbsw->adc == 0x12) { dev_info(&client->dev, "audio dock disconnect\n"); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); if (pdata->audio_dock_cb) pdata->audio_dock_cb(FSA9485_DETACHED); usbsw->adc = 0; } } usbsw->dev1 = dev1; usbsw->dev2 = dev2; return adc; }
static int cpmac_poll(struct napi_struct *napi, int budget) { struct sk_buff *skb; struct cpmac_desc *desc, *restart; struct cpmac_priv *priv = container_of(napi, struct cpmac_priv, napi); int received = 0, processed = 0; spin_lock(&priv->rx_lock); if (unlikely(!priv->rx_head)) { if (netif_msg_rx_err(priv) && net_ratelimit()) printk(KERN_WARNING "%s: rx: polling, but no queue\n", priv->dev->name); spin_unlock(&priv->rx_lock); napi_complete(napi); return 0; } desc = priv->rx_head; restart = NULL; while (((desc->dataflags & CPMAC_OWN) == 0) && (received < budget)) { processed++; if ((desc->dataflags & CPMAC_EOQ) != 0) { /* The last update to eoq->hw_next didn't happen * soon enough, and the receiver stopped here. *Remember this descriptor so we can restart * the receiver after freeing some space. */ if (unlikely(restart)) { if (netif_msg_rx_err(priv)) printk(KERN_ERR "%s: poll found a" " duplicate EOQ: %p and %p\n", priv->dev->name, restart, desc); goto fatal_error; } restart = desc->next; } skb = cpmac_rx_one(priv, desc); if (likely(skb)) { netif_receive_skb(skb); received++; } desc = desc->next; } if (desc != priv->rx_head) { /* We freed some buffers, but not the whole ring, * add what we did free to the rx list */ desc->prev->hw_next = (u32)0; priv->rx_head->prev->hw_next = priv->rx_head->mapping; } /* Optimization: If we did not actually process an EOQ (perhaps because * of quota limits), check to see if the tail of the queue has EOQ set. * We should immediately restart in that case so that the receiver can * restart and run in parallel with more packet processing. * This lets us handle slightly larger bursts before running * out of ring space (assuming dev->weight < ring_size) */ if (!restart && (priv->rx_head->prev->dataflags & (CPMAC_OWN|CPMAC_EOQ)) == CPMAC_EOQ && (priv->rx_head->dataflags & CPMAC_OWN) != 0) { /* reset EOQ so the poll loop (above) doesn't try to * restart this when it eventually gets to this descriptor. */ priv->rx_head->prev->dataflags &= ~CPMAC_EOQ; restart = priv->rx_head; } if (restart) { priv->dev->stats.rx_errors++; priv->dev->stats.rx_fifo_errors++; if (netif_msg_rx_err(priv) && net_ratelimit()) printk(KERN_WARNING "%s: rx dma ring overrun\n", priv->dev->name); if (unlikely((restart->dataflags & CPMAC_OWN) == 0)) { if (netif_msg_drv(priv)) printk(KERN_ERR "%s: cpmac_poll is trying to " "restart rx from a descriptor that's " "not free: %p\n", priv->dev->name, restart); goto fatal_error; } cpmac_write(priv->regs, CPMAC_RX_PTR(0), restart->mapping); } priv->rx_head = desc; spin_unlock(&priv->rx_lock); if (unlikely(netif_msg_rx_status(priv))) printk(KERN_DEBUG "%s: poll processed %d packets\n", priv->dev->name, received); if (processed == 0) { /* we ran out of packets to read, * revert to interrupt-driven mode */ napi_complete(napi); cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1); return 0; } return 1; fatal_error: /* Something went horribly wrong. * Reset hardware to try to recover rather than wedging. */ if (netif_msg_drv(priv)) { printk(KERN_ERR "%s: cpmac_poll is confused. " "Resetting hardware\n", priv->dev->name); cpmac_dump_all_desc(priv->dev); printk(KERN_DEBUG "%s: RX_PTR(0)=0x%08x RX_ACK(0)=0x%08x\n", priv->dev->name, cpmac_read(priv->regs, CPMAC_RX_PTR(0)), cpmac_read(priv->regs, CPMAC_RX_ACK(0))); } spin_unlock(&priv->rx_lock); napi_complete(napi); netif_tx_stop_all_queues(priv->dev); napi_disable(&priv->napi); atomic_inc(&priv->reset_pending); cpmac_hw_stop(priv->dev); if (!schedule_work(&priv->reset_work)) atomic_dec(&priv->reset_pending); return 0; }
/* * Main event dispatcher. Called from other parts and drivers. * Send the event on the appropriate channels. * May be called from interrupt context. */ void wireless_send_event(struct net_device * dev, unsigned int cmd, union iwreq_data * wrqu, const char * extra) { const struct iw_ioctl_description * descr = NULL; int extra_len = 0; struct iw_event *event; /* Mallocated whole event */ int event_len; /* Its size */ int hdr_len; /* Size of the event header */ int wrqu_off = 0; /* Offset in wrqu */ /* Don't "optimise" the following variable, it will crash */ unsigned cmd_index; /* *MUST* be unsigned */ struct sk_buff *skb; struct nlmsghdr *nlh; struct nlattr *nla; #ifdef CONFIG_COMPAT struct __compat_iw_event *compat_event; struct compat_iw_point compat_wrqu; struct sk_buff *compskb; #endif /* * Nothing in the kernel sends scan events with data, be safe. * This is necessary because we cannot fix up scan event data * for compat, due to being contained in 'extra', but normally * applications are required to retrieve the scan data anyway * and no data is included in the event, this codifies that * practice. */ if (WARN_ON(cmd == SIOCGIWSCAN && extra)) extra = NULL; /* Get the description of the Event */ if (cmd <= SIOCIWLAST) { cmd_index = IW_IOCTL_IDX(cmd); if (cmd_index < standard_ioctl_num) descr = &(standard_ioctl[cmd_index]); } else { cmd_index = IW_EVENT_IDX(cmd); if (cmd_index < standard_event_num) descr = &(standard_event[cmd_index]); } /* Don't accept unknown events */ if (descr == NULL) { /* Note : we don't return an error to the driver, because * the driver would not know what to do about it. It can't * return an error to the user, because the event is not * initiated by a user request. * The best the driver could do is to log an error message. * We will do it ourselves instead... */ netdev_err(dev, "(WE) : Invalid/Unknown Wireless Event (0x%04X)\n", cmd); return; } /* Check extra parameters and set extra_len */ if (descr->header_type == IW_HEADER_TYPE_POINT) { /* Check if number of token fits within bounds */ if (wrqu->data.length > descr->max_tokens) { netdev_err(dev, "(WE) : Wireless Event too big (%d)\n", wrqu->data.length); return; } if (wrqu->data.length < descr->min_tokens) { netdev_err(dev, "(WE) : Wireless Event too small (%d)\n", wrqu->data.length); return; } /* Calculate extra_len - extra is NULL for restricted events */ if (extra != NULL) extra_len = wrqu->data.length * descr->token_size; /* Always at an offset in wrqu */ wrqu_off = IW_EV_POINT_OFF; } /* Total length of the event */ hdr_len = event_type_size[descr->header_type]; event_len = hdr_len + extra_len; /* * The problem for 64/32 bit. * * On 64-bit, a regular event is laid out as follows: * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | event.len | event.cmd | p a d d i n g | * | wrqu data ... (with the correct size) | * * This padding exists because we manipulate event->u, * and 'event' is not packed. * * An iw_point event is laid out like this instead: * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | event.len | event.cmd | p a d d i n g | * | iwpnt.len | iwpnt.flg | p a d d i n g | * | extra data ... * * The second padding exists because struct iw_point is extended, * but this depends on the platform... * * On 32-bit, all the padding shouldn't be there. */ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!skb) return; /* Send via the RtNetlink event channel */ nlh = rtnetlink_ifinfo_prep(dev, skb); if (WARN_ON(!nlh)) { kfree_skb(skb); return; } /* Add the wireless events in the netlink packet */ nla = nla_reserve(skb, IFLA_WIRELESS, event_len); if (!nla) { kfree_skb(skb); return; } event = nla_data(nla); /* Fill event - first clear to avoid data leaking */ memset(event, 0, hdr_len); event->len = event_len; event->cmd = cmd; memcpy(&event->u, ((char *) wrqu) + wrqu_off, hdr_len - IW_EV_LCP_LEN); if (extra_len) memcpy(((char *) event) + hdr_len, extra, extra_len); nlmsg_end(skb, nlh); #ifdef CONFIG_COMPAT hdr_len = compat_event_type_size[descr->header_type]; event_len = hdr_len + extra_len; compskb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!compskb) { kfree_skb(skb); return; } /* Send via the RtNetlink event channel */ nlh = rtnetlink_ifinfo_prep(dev, compskb); if (WARN_ON(!nlh)) { kfree_skb(skb); kfree_skb(compskb); return; } /* Add the wireless events in the netlink packet */ nla = nla_reserve(compskb, IFLA_WIRELESS, event_len); if (!nla) { kfree_skb(skb); kfree_skb(compskb); return; } compat_event = nla_data(nla); compat_event->len = event_len; compat_event->cmd = cmd; if (descr->header_type == IW_HEADER_TYPE_POINT) { compat_wrqu.length = wrqu->data.length; compat_wrqu.flags = wrqu->data.flags; memcpy(&compat_event->pointer, ((char *) &compat_wrqu) + IW_EV_COMPAT_POINT_OFF, hdr_len - IW_EV_COMPAT_LCP_LEN); if (extra_len) memcpy(((char *) compat_event) + hdr_len, extra, extra_len); } else { /* extra_len must be zero, so no if (extra) needed */ memcpy(&compat_event->pointer, wrqu, hdr_len - IW_EV_COMPAT_LCP_LEN); } nlmsg_end(compskb, nlh); skb_shinfo(skb)->frag_list = compskb; #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) skb_queue_tail(&dev_net(dev)->wext_nlevents, skb); schedule_work(&wireless_nlevent_work); #else skb_queue_tail(&wireless_nlevent_queue, skb); tasklet_schedule(&wireless_nlevent_tasklet); #endif }
/* * OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have have * some differences in how we want to handle flow control. */ static void omap_8250_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_8250_port *up = up_to_u8250p(port); struct omap8250_priv *priv = up->port.private_data; unsigned char cval = 0; unsigned int baud; switch (termios->c_cflag & CSIZE) { case CS5: cval = UART_LCR_WLEN5; break; case CS6: cval = UART_LCR_WLEN6; break; case CS7: cval = UART_LCR_WLEN7; break; default: case CS8: cval = UART_LCR_WLEN8; break; } if (termios->c_cflag & CSTOPB) cval |= UART_LCR_STOP; if (termios->c_cflag & PARENB) cval |= UART_LCR_PARITY; if (!(termios->c_cflag & PARODD)) cval |= UART_LCR_EPAR; if (termios->c_cflag & CMSPAR) cval |= UART_LCR_SPAR; /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 16 / 0xffff, port->uartclk / 13); omap_8250_get_divisor(port, baud, priv); /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ pm_runtime_get_sync(port->dev); spin_lock_irq(&port->lock); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; if (termios->c_iflag & INPCK) up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; if (termios->c_iflag & (IGNBRK | PARMRK)) up->port.read_status_mask |= UART_LSR_BI; /* * Characters to ignore */ up->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; if (termios->c_iflag & IGNBRK) { up->port.ignore_status_mask |= UART_LSR_BI; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) up->port.ignore_status_mask |= UART_LSR_OE; } /* * ignore all characters if CREAD is not set */ if ((termios->c_cflag & CREAD) == 0) up->port.ignore_status_mask |= UART_LSR_DR; /* * Modem status interrupts */ up->ier &= ~UART_IER_MSI; if (UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; up->lcr = cval; /* Up to here it was mostly serial8250_do_set_termios() */ /* * We enable TRIG_GRANU for RX and TX and additionaly we set * SCR_TX_EMPTY bit. The result is the following: * - RX_TRIGGER amount of bytes in the FIFO will cause an interrupt. * - less than RX_TRIGGER number of bytes will also cause an interrupt * once the UART decides that there no new bytes arriving. * - Once THRE is enabled, the interrupt will be fired once the FIFO is * empty - the trigger level is ignored here. * * Once DMA is enabled: * - UART will assert the TX DMA line once there is room for TX_TRIGGER * bytes in the TX FIFO. On each assert the DMA engine will move * TX_TRIGGER bytes into the FIFO. * - UART will assert the RX DMA line once there are RX_TRIGGER bytes in * the FIFO and move RX_TRIGGER bytes. * This is because threshold and trigger values are the same. */ up->fcr = UART_FCR_ENABLE_FIFO; up->fcr |= TRIGGER_FCR_MASK(TX_TRIGGER) << OMAP_UART_FCR_TX_TRIG; up->fcr |= TRIGGER_FCR_MASK(RX_TRIGGER) << OMAP_UART_FCR_RX_TRIG; priv->scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK | OMAP_UART_SCR_TX_EMPTY | OMAP_UART_SCR_TX_TRIG_GRANU1_MASK; if (up->dma) priv->scr |= OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL; priv->xon = termios->c_cc[VSTART]; priv->xoff = termios->c_cc[VSTOP]; priv->efr = 0; up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; priv->efr |= UART_EFR_CTS; } else if (up->port.flags & UPF_SOFT_FLOW) { /* * OMAP rx s/w flow control is borked; the transmitter remains * stuck off even if rx flow control is subsequently disabled */ /* * IXOFF Flag: * Enable XON/XOFF flow control on output. * Transmit XON1, XOFF1 */ if (termios->c_iflag & IXOFF) { up->port.status |= UPSTAT_AUTOXOFF; priv->efr |= OMAP_UART_SW_TX; } } omap8250_restore_regs(up); spin_unlock_irq(&up->port.lock); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); /* calculate wakeup latency constraint */ priv->calc_latency = USEC_PER_SEC * 64 * 8 / baud; priv->latency = priv->calc_latency; schedule_work(&priv->qos_work); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); }
static void serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_omap_port *up = to_uart_omap_port(port); unsigned char cval = 0; unsigned long flags = 0; unsigned int baud, quot; switch (termios->c_cflag & CSIZE) { case CS5: cval = UART_LCR_WLEN5; break; case CS6: cval = UART_LCR_WLEN6; break; case CS7: cval = UART_LCR_WLEN7; break; default: case CS8: cval = UART_LCR_WLEN8; break; } if (termios->c_cflag & CSTOPB) cval |= UART_LCR_STOP; if (termios->c_cflag & PARENB) cval |= UART_LCR_PARITY; if (!(termios->c_cflag & PARODD)) cval |= UART_LCR_EPAR; if (termios->c_cflag & CMSPAR) cval |= UART_LCR_SPAR; /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); quot = serial_omap_get_divisor(port, baud); /* calculate wakeup latency constraint */ up->calc_latency = (USEC_PER_SEC * up->port.fifosize) / (baud / 8); up->latency = up->calc_latency; schedule_work(&up->qos_work); up->dll = quot & 0xff; up->dlh = quot >> 8; up->mdr1 = UART_OMAP_MDR1_DISABLE; up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | UART_FCR_ENABLE_FIFO; /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ pm_runtime_get_sync(up->dev); spin_lock_irqsave(&up->port.lock, flags); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; if (termios->c_iflag & INPCK) up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; if (termios->c_iflag & (BRKINT | PARMRK)) up->port.read_status_mask |= UART_LSR_BI; /* * Characters to ignore */ up->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; if (termios->c_iflag & IGNBRK) { up->port.ignore_status_mask |= UART_LSR_BI; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) up->port.ignore_status_mask |= UART_LSR_OE; } /* * ignore all characters if CREAD is not set */ if ((termios->c_cflag & CREAD) == 0) up->port.ignore_status_mask |= UART_LSR_DR; /* * Modem status interrupts */ up->ier &= ~UART_IER_MSI; if (UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, cval); /* reset DLAB */ up->lcr = cval; up->scr = 0; /* FIFOs and DMA Settings */ /* FCR can be changed only when the * baud clock is not running * DLL_REG and DLH_REG set to 0. */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_DLL, 0); serial_out(up, UART_DLM, 0); serial_out(up, UART_LCR, 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR) & ~UART_EFR_ECB; up->efr &= ~UART_EFR_SCD; serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); up->mcr = serial_in(up, UART_MCR) & ~UART_MCR_TCRTLR; serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; /* * NOTE: Setting OMAP_UART_SCR_RX_TRIG_GRANU1_MASK * sets Enables the granularity of 1 for TRIGGER RX * level. Along with setting RX FIFO trigger level * to 1 (as noted below, 16 characters) and TLR[3:0] * to zero this will result RX FIFO threshold level * to 1 character, instead of 16 as noted in comment * below. */ /* Set receive FIFO threshold to 16 characters and * transmit FIFO threshold to 32 spaces */ up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK; up->fcr &= ~OMAP_UART_FCR_TX_FIFO_TRIG_MASK; up->fcr |= UART_FCR6_R_TRIGGER_16 | UART_FCR6_T_TRIGGER_24 | UART_FCR_ENABLE_FIFO; serial_out(up, UART_FCR, up->fcr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_OMAP_SCR, up->scr); /* Reset UART_MCR_TCRTLR: this must be done with the EFR_ECB bit set */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); /* Protocol, Baud Rate, and Interrupt Settings */ if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) serial_omap_mdr1_errataset(up, up->mdr1); else serial_out(up, UART_OMAP_MDR1, up->mdr1); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_DLL, up->dll); /* LS of divisor */ serial_out(up, UART_DLM, up->dlh); /* MS of divisor */ serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, cval); if (!serial_omap_baud_is_mode16(port, baud)) up->mdr1 = UART_OMAP_MDR1_13X_MODE; else up->mdr1 = UART_OMAP_MDR1_16X_MODE; if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) serial_omap_mdr1_errataset(up, up->mdr1); else serial_out(up, UART_OMAP_MDR1, up->mdr1); /* Configure flow control */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* XON1/XOFF1 accessible mode B, TCRTLR=0, ECB=0 */ serial_out(up, UART_XON1, termios->c_cc[VSTART]); serial_out(up, UART_XOFF1, termios->c_cc[VSTOP]); /* Enable access to TCR/TLR */ serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; up->efr |= UART_EFR_CTS; } else { /* Disable AUTORTS and AUTOCTS */ up->efr &= ~(UART_EFR_CTS | UART_EFR_RTS); } if (up->port.flags & UPF_SOFT_FLOW) { /* clear SW control mode bits */ up->efr &= OMAP_UART_SW_CLR; /* * IXON Flag: * Enable XON/XOFF flow control on input. * Receiver compares XON1, XOFF1. */ if (termios->c_iflag & IXON) up->efr |= OMAP_UART_SW_RX; /* * IXOFF Flag: * Enable XON/XOFF flow control on output. * Transmit XON1, XOFF1 */ if (termios->c_iflag & IXOFF) { up->port.status |= UPSTAT_AUTOXOFF; up->efr |= OMAP_UART_SW_TX; } /* * IXANY Flag: * Enable any character to restart output. * Operation resumes after receiving any * character after recognition of the XOFF character */ if (termios->c_iflag & IXANY) up->mcr |= UART_MCR_XONANY; else up->mcr &= ~UART_MCR_XONANY; } serial_out(up, UART_MCR, up->mcr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, up->lcr); serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); }
/* * lkkbd_interrupt() is called by the low level driver when a character * is received. */ static irqreturn_t lkkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags) { struct lkkbd *lk = serio_get_drvdata(serio); struct input_dev *input_dev = lk->dev; unsigned int keycode; int i; DBG(KERN_INFO "Got byte 0x%02x\n", data); if (lk->ignore_bytes > 0) { DBG(KERN_INFO "Ignoring a byte on %s\n", lk->name); lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; if (lk->ignore_bytes == 0) lkkbd_detection_done(lk); return IRQ_HANDLED; } switch (data) { case LK_ALL_KEYS_UP: for (i = 0; i < ARRAY_SIZE(lkkbd_keycode); i++) input_report_key(input_dev, lk->keycode[i], 0); input_sync(input_dev); break; case 0x01: DBG(KERN_INFO "Got 0x01, scheduling re-initialization\n"); lk->ignore_bytes = LK_NUM_IGNORE_BYTES; lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; schedule_work(&lk->tq); break; case LK_METRONOME: case LK_OUTPUT_ERROR: case LK_INPUT_ERROR: case LK_KBD_LOCKED: case LK_KBD_TEST_MODE_ACK: case LK_PREFIX_KEY_DOWN: case LK_MODE_CHANGE_ACK: case LK_RESPONSE_RESERVED: DBG(KERN_INFO "Got %s and don't know how to handle...\n", response_name(data)); break; default: keycode = lk->keycode[data]; if (keycode != KEY_RESERVED) { input_report_key(input_dev, keycode, !test_bit(keycode, input_dev->key)); input_sync(input_dev); } else { #ifdef CONFIG_DEBUG_PRINTK printk(KERN_WARNING "%s: Unknown key with scancode 0x%02x on %s.\n", __FILE__, data, lk->name); #else ; #endif } } return IRQ_HANDLED; }
static void dch_l2l1(struct hisax_d_if *iface, int pr, void *arg) { struct hfc4s8s_l1 *l1 = iface->ifc.priv; struct sk_buff *skb = (struct sk_buff *) arg; u_long flags; switch (pr) { case (PH_DATA | REQUEST): if (!l1->enabled) { dev_kfree_skb(skb); break; } spin_lock_irqsave(&l1->lock, flags); skb_queue_tail(&l1->d_tx_queue, skb); if ((skb_queue_len(&l1->d_tx_queue) == 1) && (l1->tx_cnt <= 0)) { l1->hw->mr.r_irq_fifo_blx[l1->st_num] |= 0x10; spin_unlock_irqrestore(&l1->lock, flags); schedule_work(&l1->hw->tqueue); } else spin_unlock_irqrestore(&l1->lock, flags); break; case (PH_ACTIVATE | REQUEST): if (!l1->enabled) break; if (!l1->nt_mode) { if (l1->l1_state < 6) { spin_lock_irqsave(&l1->lock, flags); Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); Write_hfc8(l1->hw, A_ST_WR_STA, 0x60); mod_timer(&l1->l1_timer, jiffies + L1_TIMER_T3); spin_unlock_irqrestore(&l1->lock, flags); } else if (l1->l1_state == 7) l1->d_if.ifc.l1l2(&l1->d_if.ifc, PH_ACTIVATE | INDICATION, NULL); } else { if (l1->l1_state != 3) { spin_lock_irqsave(&l1->lock, flags); Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); Write_hfc8(l1->hw, A_ST_WR_STA, 0x60); spin_unlock_irqrestore(&l1->lock, flags); } else if (l1->l1_state == 3) l1->d_if.ifc.l1l2(&l1->d_if.ifc, PH_ACTIVATE | INDICATION, NULL); } break; default: printk(KERN_INFO "HFC-4S/8S: Unknown D-chan cmd 0x%x received, ignored\n", pr); break; } if (!l1->enabled) l1->d_if.ifc.l1l2(&l1->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); } /* dch_l2l1 */
static void hisax_sched_event(struct IsdnCardState *cs, int event) { test_and_set_bit(event, &cs->event); schedule_work(&cs->tqueue); }
static void brcmf_netdev_set_multicast_list(struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); schedule_work(&ifp->multicast_work); }
static void hisax_b_sched_event(struct BCState *bcs, int event) { test_and_set_bit(event, &bcs->event); schedule_work(&bcs->tqueue); }
static void gpio_keys_timer(unsigned long _data) { struct gpio_button_data *data = (struct gpio_button_data *)_data; schedule_work(&data->work); }
static irqreturn_t register_handler(int irq, void *data) { schedule_work(&work); return IRQ_HANDLED; }
static void serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned char cval = 0; unsigned char efr = 0; unsigned long flags = 0; unsigned int baud, quot; switch (termios->c_cflag & CSIZE) { case CS5: cval = UART_LCR_WLEN5; break; case CS6: cval = UART_LCR_WLEN6; break; case CS7: cval = UART_LCR_WLEN7; break; default: case CS8: cval = UART_LCR_WLEN8; break; } if (termios->c_cflag & CSTOPB) cval |= UART_LCR_STOP; if (termios->c_cflag & PARENB) cval |= UART_LCR_PARITY; if (!(termios->c_cflag & PARODD)) cval |= UART_LCR_EPAR; /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); quot = serial_omap_get_divisor(port, baud); /* calculate wakeup latency constraint */ up->calc_latency = (1000000 * up->port.fifosize) / (1000 * baud / 8); up->latency = up->calc_latency; schedule_work(&up->qos_work); up->dll = quot & 0xff; up->dlh = quot >> 8; up->mdr1 = UART_OMAP_MDR1_DISABLE; up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | UART_FCR_ENABLE_FIFO; if (up->use_dma) up->fcr |= UART_FCR_DMA_SELECT; /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ pm_runtime_get_sync(&up->pdev->dev); spin_lock_irqsave(&up->port.lock, flags); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; if (termios->c_iflag & INPCK) up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; if (termios->c_iflag & (BRKINT | PARMRK)) up->port.read_status_mask |= UART_LSR_BI; /* * Characters to ignore */ up->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; if (termios->c_iflag & IGNBRK) { up->port.ignore_status_mask |= UART_LSR_BI; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) up->port.ignore_status_mask |= UART_LSR_OE; } /* * ignore all characters if CREAD is not set */ if ((termios->c_cflag & CREAD) == 0) up->port.ignore_status_mask |= UART_LSR_DR; /* * Modem status interrupts */ up->ier &= ~UART_IER_MSI; if (UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, cval); /* reset DLAB */ up->lcr = cval; up->scr = OMAP_UART_SCR_TX_EMPTY; /* FIFOs and DMA Settings */ /* FCR can be changed only when the * baud clock is not running * DLL_REG and DLH_REG set to 0. */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_DLL, 0); serial_out(up, UART_DLM, 0); serial_out(up, UART_LCR, 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ serial_out(up, UART_FCR, up->fcr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); if (up->use_dma) { serial_out(up, UART_TI752_TLR, 0); up->scr |= (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8); } serial_out(up, UART_OMAP_SCR, up->scr); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr); /* Protocol, Baud Rate, and Interrupt Settings */ if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) serial_omap_mdr1_errataset(up, up->mdr1); else serial_out(up, UART_OMAP_MDR1, up->mdr1); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_DLL, up->dll); /* LS of divisor */ serial_out(up, UART_DLM, up->dlh); /* MS of divisor */ serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, cval); if (baud > 230400 && baud != 3000000) up->mdr1 = UART_OMAP_MDR1_13X_MODE; else up->mdr1 = UART_OMAP_MDR1_16X_MODE; if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) serial_omap_mdr1_errataset(up, up->mdr1); else serial_out(up, UART_OMAP_MDR1, up->mdr1); /* Hardware Flow Control Configuration */ if (termios->c_cflag & CRTSCTS) { efr |= (UART_EFR_CTS | UART_EFR_RTS); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); serial_out(up, UART_EFR, efr); /* Enable AUTORTS and AUTOCTS */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr | UART_MCR_RTS); serial_out(up, UART_LCR, cval); } serial_omap_set_mctrl(&up->port, up->port.mctrl); /* Software Flow Control Configuration */ serial_omap_configure_xonxoff(up, termios); spin_unlock_irqrestore(&up->port.lock, flags); pm_runtime_put(&up->pdev->dev); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); }
static void kgdboc_restore_input(void) { schedule_work(&kgdboc_restore_input_work); }
/* * Called from timekeeping and resume code to reprogramm the hrtimer * interrupt device on all cpus. */ void clock_was_set_delayed(void) { schedule_work(&hrtimer_work); }
int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) { struct wl_priv *wl = wlcfg_drv_priv; char powermode_val = 0; char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; uint32 regaddr; static uint32 saved_reg66; static uint32 saved_reg41; static uint32 saved_reg68; static bool saved_status = FALSE; #ifdef COEX_DHCP char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; struct btcoex_info *btco_inf = wl->btcoex_info; #endif /* COEX_DHCP */ #ifdef PKT_FILTER_SUPPORT dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); int i; #endif /* Figure out powermode 1 or o command */ strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1); if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__)); #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 1; /* Disable packet filtering */ if (dhd_pkt_filter_enable && dhd->early_suspended) { WL_TRACE(("DHCP in progressing , disable packet filter!!!\n")); for (i = 0; i < dhd->pktfilter_count; i++) { dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], 0, dhd_master_mode); } } #endif /* Retrieve and saved orig regs value */ if ((saved_status == FALSE) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { saved_status = TRUE; WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", saved_reg66, saved_reg41, saved_reg68)); /* Disable PM mode during dhpc session */ /* Disable PM mode during dhpc session */ #ifdef COEX_DHCP /* Start BT timer only for SCO connection */ if (btcoex_is_sco_active(dev)) { /* btc_params 66 */ dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg66va_dhcp_on[0], sizeof(buf_reg66va_dhcp_on)); /* btc_params 41 0x33 */ dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg41va_dhcp_on[0], sizeof(buf_reg41va_dhcp_on)); /* btc_params 68 0x190 */ dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg68va_dhcp_on[0], sizeof(buf_reg68va_dhcp_on)); saved_status = TRUE; btco_inf->bt_state = BT_DHCP_START; btco_inf->timer_on = 1; mod_timer(&btco_inf->timer, btco_inf->timer.expires); WL_TRACE(("%s enable BT DHCP Timer\n", __FUNCTION__)); } #endif /* COEX_DHCP */ } else if (saved_status == TRUE) { WL_ERR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__)); } } else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 0; /* Enable packet filtering */ if (dhd_pkt_filter_enable && dhd->early_suspended) { WL_TRACE(("DHCP is complete , enable packet filter!!!\n")); for (i = 0; i < dhd->pktfilter_count; i++) { dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], 1, dhd_master_mode); } } #endif /* Restoring PM mode */ #ifdef COEX_DHCP /* Stop any bt timer because DHCP session is done */ WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__)); if (btco_inf->timer_on) { btco_inf->timer_on = 0; del_timer_sync(&btco_inf->timer); if (btco_inf->bt_state != BT_DHCP_IDLE) { /* need to restore original btc flags & extra btc params */ WL_TRACE(("%s bt->bt_state:%d\n", __FUNCTION__, btco_inf->bt_state)); /* wake up btcoex thread to restore btlags+params */ schedule_work(&btco_inf->work); } } /* Restoring btc_flag paramter anyway */ if (saved_status == TRUE) dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); #endif /* COEX_DHCP */ /* Restore original values */ if (saved_status == TRUE) { regaddr = 66; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg66); regaddr = 41; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg41); regaddr = 68; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg68); WL_TRACE(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", saved_reg66, saved_reg41, saved_reg68)); } saved_status = FALSE; } else { WL_ERR(("%s Unkwown yet power setting, ignored\n", __FUNCTION__)); } snprintf(command, 3, "OK"); return (strlen("OK")); }