Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
whc-rc.c
Go to the documentation of this file.
1 /*
2  * Wireless Host Controller: Radio Control Interface (WHCI v0.95[2.3])
3  * Radio Control command/event transport to the UWB stack
4  *
5  * Copyright (C) 2005-2006 Intel Corporation
6  * Inaky Perez-Gonzalez <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version
10  * 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA.
21  *
22  *
23  * Initialize and hook up the Radio Control interface.
24  *
25  * For each device probed, creates an 'struct whcrc' which contains
26  * just the representation of the UWB Radio Controller, and the logic
27  * for reading notifications and passing them to the UWB Core.
28  *
29  * So we initialize all of those, register the UWB Radio Controller
30  * and setup the notification/event handle to pipe the notifications
31  * to the UWB management Daemon.
32  *
33  * Once uwb_rc_add() is called, the UWB stack takes control, resets
34  * the radio and readies the device to take commands the UWB
35  * API/user-space.
36  *
37  * Note this driver is just a transport driver; the commands are
38  * formed at the UWB stack and given to this driver who will deliver
39  * them to the hw and transfer the replies/notifications back to the
40  * UWB stack through the UWB daemon (UWBD).
41  */
42 #include <linux/init.h>
43 #include <linux/module.h>
44 #include <linux/pci.h>
45 #include <linux/sched.h>
46 #include <linux/dma-mapping.h>
47 #include <linux/interrupt.h>
48 #include <linux/slab.h>
49 #include <linux/workqueue.h>
50 #include <linux/uwb.h>
51 #include <linux/uwb/whci.h>
52 #include <linux/uwb/umc.h>
53 
54 #include "uwb-internal.h"
55 
63 struct whcrc {
64  struct umc_dev *umc_dev;
65  struct uwb_rc *uwb_rc; /* UWB host controller */
66 
67  unsigned long area;
69  size_t rc_len;
71 
72  void *evt_buf, *cmd_buf;
76 };
77 
92 static int whcrc_cmd(struct uwb_rc *uwb_rc,
93  const struct uwb_rccb *cmd, size_t cmd_size)
94 {
95  int result = 0;
96  struct whcrc *whcrc = uwb_rc->priv;
97  struct device *dev = &whcrc->umc_dev->dev;
98  u32 urccmd;
99 
100  if (cmd_size >= 4096)
101  return -EINVAL;
102 
103  /*
104  * If the URC is halted, then the hardware has reset itself.
105  * Attempt to recover by restarting the device and then return
106  * an error as it's likely that the current command isn't
107  * valid for a newly started RC.
108  */
109  if (le_readl(whcrc->rc_base + URCSTS) & URCSTS_HALTED) {
110  dev_err(dev, "requesting reset of halted radio controller\n");
111  uwb_rc_reset_all(uwb_rc);
112  return -EIO;
113  }
114 
115  result = wait_event_timeout(whcrc->cmd_wq,
116  !(le_readl(whcrc->rc_base + URCCMD) & URCCMD_ACTIVE), HZ/2);
117  if (result == 0) {
118  dev_err(dev, "device is not ready to execute commands\n");
119  return -ETIMEDOUT;
120  }
121 
122  memmove(whcrc->cmd_buf, cmd, cmd_size);
123  le_writeq(whcrc->cmd_dma_buf, whcrc->rc_base + URCCMDADDR);
124 
125  spin_lock(&whcrc->irq_lock);
126  urccmd = le_readl(whcrc->rc_base + URCCMD);
127  urccmd &= ~(URCCMD_EARV | URCCMD_SIZE_MASK);
128  le_writel(urccmd | URCCMD_ACTIVE | URCCMD_IWR | cmd_size,
129  whcrc->rc_base + URCCMD);
130  spin_unlock(&whcrc->irq_lock);
131 
132  return 0;
133 }
134 
135 static int whcrc_reset(struct uwb_rc *rc)
136 {
137  struct whcrc *whcrc = rc->priv;
138 
139  return umc_controller_reset(whcrc->umc_dev);
140 }
141 
156 static
157 void whcrc_enable_events(struct whcrc *whcrc)
158 {
159  u32 urccmd;
160 
161  le_writeq(whcrc->evt_dma_buf, whcrc->rc_base + URCEVTADDR);
162 
163  spin_lock(&whcrc->irq_lock);
164  urccmd = le_readl(whcrc->rc_base + URCCMD) & ~URCCMD_ACTIVE;
165  le_writel(urccmd | URCCMD_EARV, whcrc->rc_base + URCCMD);
166  spin_unlock(&whcrc->irq_lock);
167 }
168 
169 static void whcrc_event_work(struct work_struct *work)
170 {
171  struct whcrc *whcrc = container_of(work, struct whcrc, event_work);
172  size_t size;
173  u64 urcevtaddr;
174 
175  urcevtaddr = le_readq(whcrc->rc_base + URCEVTADDR);
176  size = urcevtaddr & URCEVTADDR_OFFSET_MASK;
177 
178  uwb_rc_neh_grok(whcrc->uwb_rc, whcrc->evt_buf, size);
179  whcrc_enable_events(whcrc);
180 }
181 
188 static
189 irqreturn_t whcrc_irq_cb(int irq, void *_whcrc)
190 {
191  struct whcrc *whcrc = _whcrc;
192  struct device *dev = &whcrc->umc_dev->dev;
193  u32 urcsts;
194 
195  urcsts = le_readl(whcrc->rc_base + URCSTS);
196  if (!(urcsts & URCSTS_INT_MASK))
197  return IRQ_NONE;
198  le_writel(urcsts & URCSTS_INT_MASK, whcrc->rc_base + URCSTS);
199 
200  if (urcsts & URCSTS_HSE) {
201  dev_err(dev, "host system error -- hardware halted\n");
202  /* FIXME: do something sensible here */
203  goto out;
204  }
205  if (urcsts & URCSTS_ER)
206  schedule_work(&whcrc->event_work);
207  if (urcsts & URCSTS_RCI)
208  wake_up_all(&whcrc->cmd_wq);
209 out:
210  return IRQ_HANDLED;
211 }
212 
213 
217 static
218 int whcrc_setup_rc_umc(struct whcrc *whcrc)
219 {
220  int result = 0;
221  struct device *dev = &whcrc->umc_dev->dev;
222  struct umc_dev *umc_dev = whcrc->umc_dev;
223 
224  whcrc->area = umc_dev->resource.start;
225  whcrc->rc_len = resource_size(&umc_dev->resource);
226  result = -EBUSY;
227  if (request_mem_region(whcrc->area, whcrc->rc_len, KBUILD_MODNAME) == NULL) {
228  dev_err(dev, "can't request URC region (%zu bytes @ 0x%lx): %d\n",
229  whcrc->rc_len, whcrc->area, result);
230  goto error_request_region;
231  }
232 
233  whcrc->rc_base = ioremap_nocache(whcrc->area, whcrc->rc_len);
234  if (whcrc->rc_base == NULL) {
235  dev_err(dev, "can't ioremap registers (%zu bytes @ 0x%lx): %d\n",
236  whcrc->rc_len, whcrc->area, result);
237  goto error_ioremap_nocache;
238  }
239 
240  result = request_irq(umc_dev->irq, whcrc_irq_cb, IRQF_SHARED,
241  KBUILD_MODNAME, whcrc);
242  if (result < 0) {
243  dev_err(dev, "can't allocate IRQ %d: %d\n",
244  umc_dev->irq, result);
245  goto error_request_irq;
246  }
247 
248  result = -ENOMEM;
249  whcrc->cmd_buf = dma_alloc_coherent(&umc_dev->dev, PAGE_SIZE,
250  &whcrc->cmd_dma_buf, GFP_KERNEL);
251  if (whcrc->cmd_buf == NULL) {
252  dev_err(dev, "Can't allocate cmd transfer buffer\n");
253  goto error_cmd_buffer;
254  }
255 
256  whcrc->evt_buf = dma_alloc_coherent(&umc_dev->dev, PAGE_SIZE,
257  &whcrc->evt_dma_buf, GFP_KERNEL);
258  if (whcrc->evt_buf == NULL) {
259  dev_err(dev, "Can't allocate evt transfer buffer\n");
260  goto error_evt_buffer;
261  }
262  return 0;
263 
264 error_evt_buffer:
265  dma_free_coherent(&umc_dev->dev, PAGE_SIZE, whcrc->cmd_buf,
266  whcrc->cmd_dma_buf);
267 error_cmd_buffer:
268  free_irq(umc_dev->irq, whcrc);
269 error_request_irq:
270  iounmap(whcrc->rc_base);
271 error_ioremap_nocache:
272  release_mem_region(whcrc->area, whcrc->rc_len);
273 error_request_region:
274  return result;
275 }
276 
277 
281 static
282 void whcrc_release_rc_umc(struct whcrc *whcrc)
283 {
284  struct umc_dev *umc_dev = whcrc->umc_dev;
285 
286  dma_free_coherent(&umc_dev->dev, PAGE_SIZE, whcrc->evt_buf,
287  whcrc->evt_dma_buf);
288  dma_free_coherent(&umc_dev->dev, PAGE_SIZE, whcrc->cmd_buf,
289  whcrc->cmd_dma_buf);
290  free_irq(umc_dev->irq, whcrc);
291  iounmap(whcrc->rc_base);
292  release_mem_region(whcrc->area, whcrc->rc_len);
293 }
294 
295 
303 static int whcrc_start_rc(struct uwb_rc *rc)
304 {
305  struct whcrc *whcrc = rc->priv;
306  struct device *dev = &whcrc->umc_dev->dev;
307 
308  /* Reset the thing */
309  le_writel(URCCMD_RESET, whcrc->rc_base + URCCMD);
310  if (whci_wait_for(dev, whcrc->rc_base + URCCMD, URCCMD_RESET, 0,
311  5000, "hardware reset") < 0)
312  return -EBUSY;
313 
314  /* Set the event buffer, start the controller (enable IRQs later) */
315  le_writel(0, whcrc->rc_base + URCINTR);
316  le_writel(URCCMD_RS, whcrc->rc_base + URCCMD);
317  if (whci_wait_for(dev, whcrc->rc_base + URCSTS, URCSTS_HALTED, 0,
318  5000, "radio controller start") < 0)
319  return -ETIMEDOUT;
320  whcrc_enable_events(whcrc);
321  le_writel(URCINTR_EN_ALL, whcrc->rc_base + URCINTR);
322  return 0;
323 }
324 
325 
333 static
334 void whcrc_stop_rc(struct uwb_rc *rc)
335 {
336  struct whcrc *whcrc = rc->priv;
337  struct umc_dev *umc_dev = whcrc->umc_dev;
338 
339  le_writel(0, whcrc->rc_base + URCINTR);
340  cancel_work_sync(&whcrc->event_work);
341 
342  le_writel(0, whcrc->rc_base + URCCMD);
343  whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS,
344  URCSTS_HALTED, URCSTS_HALTED, 100, "radio controller stop");
345 }
346 
347 static void whcrc_init(struct whcrc *whcrc)
348 {
349  spin_lock_init(&whcrc->irq_lock);
350  init_waitqueue_head(&whcrc->cmd_wq);
351  INIT_WORK(&whcrc->event_work, whcrc_event_work);
352 }
353 
362 static
363 int whcrc_probe(struct umc_dev *umc_dev)
364 {
365  int result;
366  struct uwb_rc *uwb_rc;
367  struct whcrc *whcrc;
368  struct device *dev = &umc_dev->dev;
369 
370  result = -ENOMEM;
371  uwb_rc = uwb_rc_alloc();
372  if (uwb_rc == NULL) {
373  dev_err(dev, "unable to allocate RC instance\n");
374  goto error_rc_alloc;
375  }
376  whcrc = kzalloc(sizeof(*whcrc), GFP_KERNEL);
377  if (whcrc == NULL) {
378  dev_err(dev, "unable to allocate WHC-RC instance\n");
379  goto error_alloc;
380  }
381  whcrc_init(whcrc);
382  whcrc->umc_dev = umc_dev;
383 
384  result = whcrc_setup_rc_umc(whcrc);
385  if (result < 0) {
386  dev_err(dev, "Can't setup RC UMC interface: %d\n", result);
387  goto error_setup_rc_umc;
388  }
389  whcrc->uwb_rc = uwb_rc;
390 
391  uwb_rc->owner = THIS_MODULE;
392  uwb_rc->cmd = whcrc_cmd;
393  uwb_rc->reset = whcrc_reset;
394  uwb_rc->start = whcrc_start_rc;
395  uwb_rc->stop = whcrc_stop_rc;
396 
397  result = uwb_rc_add(uwb_rc, dev, whcrc);
398  if (result < 0)
399  goto error_rc_add;
400  umc_set_drvdata(umc_dev, whcrc);
401  return 0;
402 
403 error_rc_add:
404  whcrc_release_rc_umc(whcrc);
405 error_setup_rc_umc:
406  kfree(whcrc);
407 error_alloc:
408  uwb_rc_put(uwb_rc);
409 error_rc_alloc:
410  return result;
411 }
412 
422 static void whcrc_remove(struct umc_dev *umc_dev)
423 {
424  struct whcrc *whcrc = umc_get_drvdata(umc_dev);
425  struct uwb_rc *uwb_rc = whcrc->uwb_rc;
426 
427  umc_set_drvdata(umc_dev, NULL);
428  uwb_rc_rm(uwb_rc);
429  whcrc_release_rc_umc(whcrc);
430  kfree(whcrc);
431  uwb_rc_put(uwb_rc);
432 }
433 
434 static int whcrc_pre_reset(struct umc_dev *umc)
435 {
436  struct whcrc *whcrc = umc_get_drvdata(umc);
437  struct uwb_rc *uwb_rc = whcrc->uwb_rc;
438 
439  uwb_rc_pre_reset(uwb_rc);
440  return 0;
441 }
442 
443 static int whcrc_post_reset(struct umc_dev *umc)
444 {
445  struct whcrc *whcrc = umc_get_drvdata(umc);
446  struct uwb_rc *uwb_rc = whcrc->uwb_rc;
447 
448  return uwb_rc_post_reset(uwb_rc);
449 }
450 
451 /* PCI device ID's that we handle [so it gets loaded] */
452 static struct pci_device_id __used whcrc_id_table[] = {
454  { /* empty last entry */ }
455 };
456 MODULE_DEVICE_TABLE(pci, whcrc_id_table);
457 
458 static struct umc_driver whcrc_driver = {
459  .name = "whc-rc",
460  .cap_id = UMC_CAP_ID_WHCI_RC,
461  .probe = whcrc_probe,
462  .remove = whcrc_remove,
463  .pre_reset = whcrc_pre_reset,
464  .post_reset = whcrc_post_reset,
465 };
466 
467 static int __init whcrc_driver_init(void)
468 {
469  return umc_driver_register(&whcrc_driver);
470 }
471 module_init(whcrc_driver_init);
472 
473 static void __exit whcrc_driver_exit(void)
474 {
475  umc_driver_unregister(&whcrc_driver);
476 }
477 module_exit(whcrc_driver_exit);
478 
479 MODULE_AUTHOR("Inaky Perez-Gonzalez <[email protected]>");
480 MODULE_DESCRIPTION("Wireless Host Controller Radio Control Driver");
481 MODULE_LICENSE("GPL");