Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * Wireless Host Controller (WHC) hardware access helpers.
  3  *
  4  * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
  5  *
  6  * This program is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU General Public License version
  8  * 2 as published by the Free Software Foundation.
  9  *
 10  * This program is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  * GNU General Public License for more details.
 14  *
 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/>.
 17  */
 18 #include <linux/kernel.h>
 19 #include <linux/dma-mapping.h>
 20 #include <linux/uwb/umc.h>
 21 
 22 #include "../../wusbcore/wusbhc.h"
 23 
 24 #include "whcd.h"
 25 
 26 void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val)
 27 {
 28         unsigned long flags;
 29         u32 cmd;
 30 
 31         spin_lock_irqsave(&whc->lock, flags);
 32 
 33         cmd = le_readl(whc->base + WUSBCMD);
 34         cmd = (cmd & ~mask) | val;
 35         le_writel(cmd, whc->base + WUSBCMD);
 36 
 37         spin_unlock_irqrestore(&whc->lock, flags);
 38 }
 39 
 40 /**
 41  * whc_do_gencmd - start a generic command via the WUSBGENCMDSTS register
 42  * @whc:    the WHCI HC
 43  * @cmd:    command to start.
 44  * @params: parameters for the command (the WUSBGENCMDPARAMS register value).
 45  * @addr:   pointer to any data for the command (may be NULL).
 46  * @len:    length of the data (if any).
 47  */
 48 int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len)
 49 {
 50         unsigned long flags;
 51         dma_addr_t dma_addr;
 52         int t;
 53         int ret = 0;
 54 
 55         mutex_lock(&whc->mutex);
 56 
 57         /* Wait for previous command to complete. */
 58         t = wait_event_timeout(whc->cmd_wq,
 59                                (le_readl(whc->base + WUSBGENCMDSTS) & WUSBGENCMDSTS_ACTIVE) == 0,
 60                                WHC_GENCMD_TIMEOUT_MS);
 61         if (t == 0) {
 62                 dev_err(&whc->umc->dev, "generic command timeout (%04x/%04x)\n",
 63                         le_readl(whc->base + WUSBGENCMDSTS),
 64                         le_readl(whc->base + WUSBGENCMDPARAMS));
 65                 ret = -ETIMEDOUT;
 66                 goto out;
 67         }
 68 
 69         if (addr) {
 70                 memcpy(whc->gen_cmd_buf, addr, len);
 71                 dma_addr = whc->gen_cmd_buf_dma;
 72         } else
 73                 dma_addr = 0;
 74 
 75         /* Poke registers to start cmd. */
 76         spin_lock_irqsave(&whc->lock, flags);
 77 
 78         le_writel(params, whc->base + WUSBGENCMDPARAMS);
 79         le_writeq(dma_addr, whc->base + WUSBGENADDR);
 80 
 81         le_writel(WUSBGENCMDSTS_ACTIVE | WUSBGENCMDSTS_IOC | cmd,
 82                   whc->base + WUSBGENCMDSTS);
 83 
 84         spin_unlock_irqrestore(&whc->lock, flags);
 85 out:
 86         mutex_unlock(&whc->mutex);
 87 
 88         return ret;
 89 }
 90 
 91 /**
 92  * whc_hw_error - recover from a hardware error
 93  * @whc:    the WHCI HC that broke.
 94  * @reason: a description of the failure.
 95  *
 96  * Recover from broken hardware with a full reset.
 97  */
 98 void whc_hw_error(struct whc *whc, const char *reason)
 99 {
100         struct wusbhc *wusbhc = &whc->wusbhc;
101 
102         dev_err(&whc->umc->dev, "hardware error: %s\n", reason);
103         wusbhc_reset_all(wusbhc);
104 }
105 
  This page was automatically generated by the LXR engine.