diff options
Diffstat (limited to 'drivers/uwb/whc-rc.c')
-rw-r--r-- | drivers/uwb/whc-rc.c | 53 |
1 files changed, 9 insertions, 44 deletions
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c index 5f00386e26c7..19a1dd129212 100644 --- a/drivers/uwb/whc-rc.c +++ b/drivers/uwb/whc-rc.c | |||
@@ -48,10 +48,8 @@ | |||
48 | #include <linux/uwb.h> | 48 | #include <linux/uwb.h> |
49 | #include <linux/uwb/whci.h> | 49 | #include <linux/uwb/whci.h> |
50 | #include <linux/uwb/umc.h> | 50 | #include <linux/uwb/umc.h> |
51 | #include "uwb-internal.h" | ||
52 | 51 | ||
53 | #define D_LOCAL 0 | 52 | #include "uwb-internal.h" |
54 | #include <linux/uwb/debug.h> | ||
55 | 53 | ||
56 | /** | 54 | /** |
57 | * Descriptor for an instance of the UWB Radio Control Driver that | 55 | * Descriptor for an instance of the UWB Radio Control Driver that |
@@ -97,13 +95,8 @@ static int whcrc_cmd(struct uwb_rc *uwb_rc, | |||
97 | struct device *dev = &whcrc->umc_dev->dev; | 95 | struct device *dev = &whcrc->umc_dev->dev; |
98 | u32 urccmd; | 96 | u32 urccmd; |
99 | 97 | ||
100 | d_fnstart(3, dev, "(%p, %p, %zu)\n", uwb_rc, cmd, cmd_size); | 98 | if (cmd_size >= 4096) |
101 | might_sleep(); | 99 | return -EINVAL; |
102 | |||
103 | if (cmd_size >= 4096) { | ||
104 | result = -E2BIG; | ||
105 | goto error; | ||
106 | } | ||
107 | 100 | ||
108 | /* | 101 | /* |
109 | * If the URC is halted, then the hardware has reset itself. | 102 | * If the URC is halted, then the hardware has reset itself. |
@@ -114,16 +107,14 @@ static int whcrc_cmd(struct uwb_rc *uwb_rc, | |||
114 | if (le_readl(whcrc->rc_base + URCSTS) & URCSTS_HALTED) { | 107 | if (le_readl(whcrc->rc_base + URCSTS) & URCSTS_HALTED) { |
115 | dev_err(dev, "requesting reset of halted radio controller\n"); | 108 | dev_err(dev, "requesting reset of halted radio controller\n"); |
116 | uwb_rc_reset_all(uwb_rc); | 109 | uwb_rc_reset_all(uwb_rc); |
117 | result = -EIO; | 110 | return -EIO; |
118 | goto error; | ||
119 | } | 111 | } |
120 | 112 | ||
121 | result = wait_event_timeout(whcrc->cmd_wq, | 113 | result = wait_event_timeout(whcrc->cmd_wq, |
122 | !(le_readl(whcrc->rc_base + URCCMD) & URCCMD_ACTIVE), HZ/2); | 114 | !(le_readl(whcrc->rc_base + URCCMD) & URCCMD_ACTIVE), HZ/2); |
123 | if (result == 0) { | 115 | if (result == 0) { |
124 | dev_err(dev, "device is not ready to execute commands\n"); | 116 | dev_err(dev, "device is not ready to execute commands\n"); |
125 | result = -ETIMEDOUT; | 117 | return -ETIMEDOUT; |
126 | goto error; | ||
127 | } | 118 | } |
128 | 119 | ||
129 | memmove(whcrc->cmd_buf, cmd, cmd_size); | 120 | memmove(whcrc->cmd_buf, cmd, cmd_size); |
@@ -136,10 +127,7 @@ static int whcrc_cmd(struct uwb_rc *uwb_rc, | |||
136 | whcrc->rc_base + URCCMD); | 127 | whcrc->rc_base + URCCMD); |
137 | spin_unlock(&whcrc->irq_lock); | 128 | spin_unlock(&whcrc->irq_lock); |
138 | 129 | ||
139 | error: | 130 | return 0; |
140 | d_fnend(3, dev, "(%p, %p, %zu) = %d\n", | ||
141 | uwb_rc, cmd, cmd_size, result); | ||
142 | return result; | ||
143 | } | 131 | } |
144 | 132 | ||
145 | static int whcrc_reset(struct uwb_rc *rc) | 133 | static int whcrc_reset(struct uwb_rc *rc) |
@@ -166,34 +154,25 @@ static int whcrc_reset(struct uwb_rc *rc) | |||
166 | static | 154 | static |
167 | void whcrc_enable_events(struct whcrc *whcrc) | 155 | void whcrc_enable_events(struct whcrc *whcrc) |
168 | { | 156 | { |
169 | struct device *dev = &whcrc->umc_dev->dev; | ||
170 | u32 urccmd; | 157 | u32 urccmd; |
171 | 158 | ||
172 | d_fnstart(4, dev, "(whcrc %p)\n", whcrc); | ||
173 | |||
174 | le_writeq(whcrc->evt_dma_buf, whcrc->rc_base + URCEVTADDR); | 159 | le_writeq(whcrc->evt_dma_buf, whcrc->rc_base + URCEVTADDR); |
175 | 160 | ||
176 | spin_lock(&whcrc->irq_lock); | 161 | spin_lock(&whcrc->irq_lock); |
177 | urccmd = le_readl(whcrc->rc_base + URCCMD) & ~URCCMD_ACTIVE; | 162 | urccmd = le_readl(whcrc->rc_base + URCCMD) & ~URCCMD_ACTIVE; |
178 | le_writel(urccmd | URCCMD_EARV, whcrc->rc_base + URCCMD); | 163 | le_writel(urccmd | URCCMD_EARV, whcrc->rc_base + URCCMD); |
179 | spin_unlock(&whcrc->irq_lock); | 164 | spin_unlock(&whcrc->irq_lock); |
180 | |||
181 | d_fnend(4, dev, "(whcrc %p) = void\n", whcrc); | ||
182 | } | 165 | } |
183 | 166 | ||
184 | static void whcrc_event_work(struct work_struct *work) | 167 | static void whcrc_event_work(struct work_struct *work) |
185 | { | 168 | { |
186 | struct whcrc *whcrc = container_of(work, struct whcrc, event_work); | 169 | struct whcrc *whcrc = container_of(work, struct whcrc, event_work); |
187 | struct device *dev = &whcrc->umc_dev->dev; | ||
188 | size_t size; | 170 | size_t size; |
189 | u64 urcevtaddr; | 171 | u64 urcevtaddr; |
190 | 172 | ||
191 | urcevtaddr = le_readq(whcrc->rc_base + URCEVTADDR); | 173 | urcevtaddr = le_readq(whcrc->rc_base + URCEVTADDR); |
192 | size = urcevtaddr & URCEVTADDR_OFFSET_MASK; | 174 | size = urcevtaddr & URCEVTADDR_OFFSET_MASK; |
193 | 175 | ||
194 | d_printf(3, dev, "received %zu octet event\n", size); | ||
195 | d_dump(4, dev, whcrc->evt_buf, size > 32 ? 32 : size); | ||
196 | |||
197 | uwb_rc_neh_grok(whcrc->uwb_rc, whcrc->evt_buf, size); | 176 | uwb_rc_neh_grok(whcrc->uwb_rc, whcrc->evt_buf, size); |
198 | whcrc_enable_events(whcrc); | 177 | whcrc_enable_events(whcrc); |
199 | } | 178 | } |
@@ -216,22 +195,15 @@ irqreturn_t whcrc_irq_cb(int irq, void *_whcrc) | |||
216 | return IRQ_NONE; | 195 | return IRQ_NONE; |
217 | le_writel(urcsts & URCSTS_INT_MASK, whcrc->rc_base + URCSTS); | 196 | le_writel(urcsts & URCSTS_INT_MASK, whcrc->rc_base + URCSTS); |
218 | 197 | ||
219 | d_printf(4, dev, "acked 0x%08x, urcsts 0x%08x\n", | ||
220 | le_readl(whcrc->rc_base + URCSTS), urcsts); | ||
221 | |||
222 | if (urcsts & URCSTS_HSE) { | 198 | if (urcsts & URCSTS_HSE) { |
223 | dev_err(dev, "host system error -- hardware halted\n"); | 199 | dev_err(dev, "host system error -- hardware halted\n"); |
224 | /* FIXME: do something sensible here */ | 200 | /* FIXME: do something sensible here */ |
225 | goto out; | 201 | goto out; |
226 | } | 202 | } |
227 | if (urcsts & URCSTS_ER) { | 203 | if (urcsts & URCSTS_ER) |
228 | d_printf(3, dev, "ER: event ready\n"); | ||
229 | schedule_work(&whcrc->event_work); | 204 | schedule_work(&whcrc->event_work); |
230 | } | 205 | if (urcsts & URCSTS_RCI) |
231 | if (urcsts & URCSTS_RCI) { | ||
232 | d_printf(3, dev, "RCI: ready to execute another command\n"); | ||
233 | wake_up_all(&whcrc->cmd_wq); | 206 | wake_up_all(&whcrc->cmd_wq); |
234 | } | ||
235 | out: | 207 | out: |
236 | return IRQ_HANDLED; | 208 | return IRQ_HANDLED; |
237 | } | 209 | } |
@@ -250,8 +222,7 @@ int whcrc_setup_rc_umc(struct whcrc *whcrc) | |||
250 | whcrc->area = umc_dev->resource.start; | 222 | whcrc->area = umc_dev->resource.start; |
251 | whcrc->rc_len = umc_dev->resource.end - umc_dev->resource.start + 1; | 223 | whcrc->rc_len = umc_dev->resource.end - umc_dev->resource.start + 1; |
252 | result = -EBUSY; | 224 | result = -EBUSY; |
253 | if (request_mem_region(whcrc->area, whcrc->rc_len, KBUILD_MODNAME) | 225 | if (request_mem_region(whcrc->area, whcrc->rc_len, KBUILD_MODNAME) == NULL) { |
254 | == NULL) { | ||
255 | dev_err(dev, "can't request URC region (%zu bytes @ 0x%lx): %d\n", | 226 | dev_err(dev, "can't request URC region (%zu bytes @ 0x%lx): %d\n", |
256 | whcrc->rc_len, whcrc->area, result); | 227 | whcrc->rc_len, whcrc->area, result); |
257 | goto error_request_region; | 228 | goto error_request_region; |
@@ -286,8 +257,6 @@ int whcrc_setup_rc_umc(struct whcrc *whcrc) | |||
286 | dev_err(dev, "Can't allocate evt transfer buffer\n"); | 257 | dev_err(dev, "Can't allocate evt transfer buffer\n"); |
287 | goto error_evt_buffer; | 258 | goto error_evt_buffer; |
288 | } | 259 | } |
289 | d_printf(3, dev, "UWB RC Interface: %zu bytes at 0x%p, irq %u\n", | ||
290 | whcrc->rc_len, whcrc->rc_base, umc_dev->irq); | ||
291 | return 0; | 260 | return 0; |
292 | 261 | ||
293 | error_evt_buffer: | 262 | error_evt_buffer: |
@@ -396,7 +365,6 @@ int whcrc_probe(struct umc_dev *umc_dev) | |||
396 | struct whcrc *whcrc; | 365 | struct whcrc *whcrc; |
397 | struct device *dev = &umc_dev->dev; | 366 | struct device *dev = &umc_dev->dev; |
398 | 367 | ||
399 | d_fnstart(3, dev, "(umc_dev %p)\n", umc_dev); | ||
400 | result = -ENOMEM; | 368 | result = -ENOMEM; |
401 | uwb_rc = uwb_rc_alloc(); | 369 | uwb_rc = uwb_rc_alloc(); |
402 | if (uwb_rc == NULL) { | 370 | if (uwb_rc == NULL) { |
@@ -428,7 +396,6 @@ int whcrc_probe(struct umc_dev *umc_dev) | |||
428 | if (result < 0) | 396 | if (result < 0) |
429 | goto error_rc_add; | 397 | goto error_rc_add; |
430 | umc_set_drvdata(umc_dev, whcrc); | 398 | umc_set_drvdata(umc_dev, whcrc); |
431 | d_fnend(3, dev, "(umc_dev %p) = 0\n", umc_dev); | ||
432 | return 0; | 399 | return 0; |
433 | 400 | ||
434 | error_rc_add: | 401 | error_rc_add: |
@@ -438,7 +405,6 @@ error_setup_rc_umc: | |||
438 | error_alloc: | 405 | error_alloc: |
439 | uwb_rc_put(uwb_rc); | 406 | uwb_rc_put(uwb_rc); |
440 | error_rc_alloc: | 407 | error_rc_alloc: |
441 | d_fnend(3, dev, "(umc_dev %p) = %d\n", umc_dev, result); | ||
442 | return result; | 408 | return result; |
443 | } | 409 | } |
444 | 410 | ||
@@ -461,7 +427,6 @@ static void whcrc_remove(struct umc_dev *umc_dev) | |||
461 | whcrc_release_rc_umc(whcrc); | 427 | whcrc_release_rc_umc(whcrc); |
462 | kfree(whcrc); | 428 | kfree(whcrc); |
463 | uwb_rc_put(uwb_rc); | 429 | uwb_rc_put(uwb_rc); |
464 | d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc); | ||
465 | } | 430 | } |
466 | 431 | ||
467 | static int whcrc_pre_reset(struct umc_dev *umc) | 432 | static int whcrc_pre_reset(struct umc_dev *umc) |