aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/whci/wusb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/whci/wusb.c')
-rw-r--r--drivers/usb/host/whci/wusb.c43
1 files changed, 12 insertions, 31 deletions
diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c
index 66e4ddcd961d..f24efdebad17 100644
--- a/drivers/usb/host/whci/wusb.c
+++ b/drivers/usb/host/whci/wusb.c
@@ -15,47 +15,19 @@
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18#include <linux/version.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/init.h> 19#include <linux/init.h>
21#include <linux/uwb/umc.h> 20#include <linux/uwb/umc.h>
22#define D_LOCAL 1
23#include <linux/uwb/debug.h>
24 21
25#include "../../wusbcore/wusbhc.h" 22#include "../../wusbcore/wusbhc.h"
26 23
27#include "whcd.h" 24#include "whcd.h"
28 25
29#if D_LOCAL >= 1
30static void dump_di(struct whc *whc, int idx)
31{
32 struct di_buf_entry *di = &whc->di_buf[idx];
33 struct device *dev = &whc->umc->dev;
34 char buf[128];
35
36 bitmap_scnprintf(buf, sizeof(buf), (unsigned long *)di->availability_info, UWB_NUM_MAS);
37
38 d_printf(1, dev, "DI[%d]\n", idx);
39 d_printf(1, dev, " availability: %s\n", buf);
40 d_printf(1, dev, " %c%c key idx: %d dev addr: %d\n",
41 (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ',
42 (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ',
43 (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8,
44 (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK));
45}
46#else
47static inline void dump_di(struct whc *whc, int idx)
48{
49}
50#endif
51
52static int whc_update_di(struct whc *whc, int idx) 26static int whc_update_di(struct whc *whc, int idx)
53{ 27{
54 int offset = idx / 32; 28 int offset = idx / 32;
55 u32 bit = 1 << (idx % 32); 29 u32 bit = 1 << (idx % 32);
56 30
57 dump_di(whc, idx);
58
59 le_writel(bit, whc->base + WUSBDIBUPDATED + offset); 31 le_writel(bit, whc->base + WUSBDIBUPDATED + offset);
60 32
61 return whci_wait_for(&whc->umc->dev, 33 return whci_wait_for(&whc->umc->dev,
@@ -64,8 +36,9 @@ static int whc_update_di(struct whc *whc, int idx)
64} 36}
65 37
66/* 38/*
67 * WHCI starts and stops MMCs based on there being a valid GTK so 39 * WHCI starts MMCs based on there being a valid GTK so these need
68 * these need only start/stop the asynchronous and periodic schedules. 40 * only start/stop the asynchronous and periodic schedules and send a
41 * channel stop command.
69 */ 42 */
70 43
71int whc_wusbhc_start(struct wusbhc *wusbhc) 44int whc_wusbhc_start(struct wusbhc *wusbhc)
@@ -78,12 +51,20 @@ int whc_wusbhc_start(struct wusbhc *wusbhc)
78 return 0; 51 return 0;
79} 52}
80 53
81void whc_wusbhc_stop(struct wusbhc *wusbhc) 54void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay)
82{ 55{
83 struct whc *whc = wusbhc_to_whc(wusbhc); 56 struct whc *whc = wusbhc_to_whc(wusbhc);
57 u32 stop_time, now_time;
58 int ret;
84 59
85 pzl_stop(whc); 60 pzl_stop(whc);
86 asl_stop(whc); 61 asl_stop(whc);
62
63 now_time = le_readl(whc->base + WUSBTIME) & WUSBTIME_CHANNEL_TIME_MASK;
64 stop_time = (now_time + ((delay * 8) << 7)) & 0x00ffffff;
65 ret = whc_do_gencmd(whc, WUSBGENCMDSTS_CHAN_STOP, stop_time, NULL, 0);
66 if (ret == 0)
67 msleep(delay);
87} 68}
88 69
89int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, 70int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,