Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.2-rc3 82 lines 1.9 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Wireless Host Controller (WHC) interrupt handling. 4 * 5 * Copyright (C) 2007 Cambridge Silicon Radio Ltd. 6 */ 7#include <linux/kernel.h> 8#include <linux/uwb/umc.h> 9 10#include "../../wusbcore/wusbhc.h" 11 12#include "whcd.h" 13 14static void transfer_done(struct whc *whc) 15{ 16 queue_work(whc->workqueue, &whc->async_work); 17 queue_work(whc->workqueue, &whc->periodic_work); 18} 19 20irqreturn_t whc_int_handler(struct usb_hcd *hcd) 21{ 22 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(hcd); 23 struct whc *whc = wusbhc_to_whc(wusbhc); 24 u32 sts; 25 26 sts = le_readl(whc->base + WUSBSTS); 27 if (!(sts & WUSBSTS_INT_MASK)) 28 return IRQ_NONE; 29 le_writel(sts & WUSBSTS_INT_MASK, whc->base + WUSBSTS); 30 31 if (sts & WUSBSTS_GEN_CMD_DONE) 32 wake_up(&whc->cmd_wq); 33 34 if (sts & WUSBSTS_HOST_ERR) 35 dev_err(&whc->umc->dev, "FIXME: host system error\n"); 36 37 if (sts & WUSBSTS_ASYNC_SCHED_SYNCED) 38 wake_up(&whc->async_list_wq); 39 40 if (sts & WUSBSTS_PERIODIC_SCHED_SYNCED) 41 wake_up(&whc->periodic_list_wq); 42 43 if (sts & WUSBSTS_DNTS_INT) 44 queue_work(whc->workqueue, &whc->dn_work); 45 46 /* 47 * A transfer completed (see [WHCI] section 4.7.1.2 for when 48 * this occurs). 49 */ 50 if (sts & (WUSBSTS_INT | WUSBSTS_ERR_INT)) 51 transfer_done(whc); 52 53 return IRQ_HANDLED; 54} 55 56static int process_dn_buf(struct whc *whc) 57{ 58 struct wusbhc *wusbhc = &whc->wusbhc; 59 struct dn_buf_entry *dn; 60 int processed = 0; 61 62 for (dn = whc->dn_buf; dn < whc->dn_buf + WHC_N_DN_ENTRIES; dn++) { 63 if (dn->status & WHC_DN_STATUS_VALID) { 64 wusbhc_handle_dn(wusbhc, dn->src_addr, 65 (struct wusb_dn_hdr *)dn->dn_data, 66 dn->msg_size); 67 dn->status &= ~WHC_DN_STATUS_VALID; 68 processed++; 69 } 70 } 71 return processed; 72} 73 74void whc_dn_work(struct work_struct *work) 75{ 76 struct whc *whc = container_of(work, struct whc, dn_work); 77 int processed; 78 79 do { 80 processed = process_dn_buf(whc); 81 } while (processed); 82}