.. | .. |
---|
224 | 224 | |
---|
225 | 225 | dev_dbg(&rdev->dev, "device %s registered\n", dev_name(&rdev->dev)); |
---|
226 | 226 | |
---|
| 227 | + return rdev; |
---|
| 228 | + |
---|
227 | 229 | err_device_add: |
---|
228 | 230 | put_device(&rdev->dev); |
---|
229 | 231 | |
---|
.. | .. |
---|
266 | 268 | /* common code that starts a transfer */ |
---|
267 | 269 | static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) |
---|
268 | 270 | { |
---|
| 271 | + u32 int_mask, status; |
---|
| 272 | + bool timeout; |
---|
| 273 | + |
---|
269 | 274 | if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) { |
---|
270 | 275 | dev_dbg(rsb->dev, "RSB transfer still in progress\n"); |
---|
271 | 276 | return -EBUSY; |
---|
.. | .. |
---|
273 | 278 | |
---|
274 | 279 | reinit_completion(&rsb->complete); |
---|
275 | 280 | |
---|
276 | | - writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER, |
---|
277 | | - rsb->regs + RSB_INTE); |
---|
| 281 | + int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; |
---|
| 282 | + writel(int_mask, rsb->regs + RSB_INTE); |
---|
278 | 283 | writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, |
---|
279 | 284 | rsb->regs + RSB_CTRL); |
---|
280 | 285 | |
---|
281 | | - if (!wait_for_completion_io_timeout(&rsb->complete, |
---|
282 | | - msecs_to_jiffies(100))) { |
---|
| 286 | + if (irqs_disabled()) { |
---|
| 287 | + timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, |
---|
| 288 | + status, (status & int_mask), |
---|
| 289 | + 10, 100000); |
---|
| 290 | + writel(status, rsb->regs + RSB_INTS); |
---|
| 291 | + } else { |
---|
| 292 | + timeout = !wait_for_completion_io_timeout(&rsb->complete, |
---|
| 293 | + msecs_to_jiffies(100)); |
---|
| 294 | + status = rsb->status; |
---|
| 295 | + } |
---|
| 296 | + |
---|
| 297 | + if (timeout) { |
---|
283 | 298 | dev_dbg(rsb->dev, "RSB timeout\n"); |
---|
284 | 299 | |
---|
285 | 300 | /* abort the transfer */ |
---|
.. | .. |
---|
291 | 306 | return -ETIMEDOUT; |
---|
292 | 307 | } |
---|
293 | 308 | |
---|
294 | | - if (rsb->status & RSB_INTS_LOAD_BSY) { |
---|
| 309 | + if (status & RSB_INTS_LOAD_BSY) { |
---|
295 | 310 | dev_dbg(rsb->dev, "RSB busy\n"); |
---|
296 | 311 | return -EBUSY; |
---|
297 | 312 | } |
---|
298 | 313 | |
---|
299 | | - if (rsb->status & RSB_INTS_TRANS_ERR) { |
---|
300 | | - if (rsb->status & RSB_INTS_TRANS_ERR_ACK) { |
---|
| 314 | + if (status & RSB_INTS_TRANS_ERR) { |
---|
| 315 | + if (status & RSB_INTS_TRANS_ERR_ACK) { |
---|
301 | 316 | dev_dbg(rsb->dev, "RSB slave nack\n"); |
---|
302 | 317 | return -EINVAL; |
---|
303 | 318 | } |
---|
304 | 319 | |
---|
305 | | - if (rsb->status & RSB_INTS_TRANS_ERR_DATA) { |
---|
| 320 | + if (status & RSB_INTS_TRANS_ERR_DATA) { |
---|
306 | 321 | dev_dbg(rsb->dev, "RSB transfer data error\n"); |
---|
307 | 322 | return -EIO; |
---|
308 | 323 | } |
---|
.. | .. |
---|
651 | 666 | return PTR_ERR(rsb->regs); |
---|
652 | 667 | |
---|
653 | 668 | irq = platform_get_irq(pdev, 0); |
---|
654 | | - if (irq < 0) { |
---|
655 | | - dev_err(dev, "failed to retrieve irq: %d\n", irq); |
---|
| 669 | + if (irq < 0) |
---|
656 | 670 | return irq; |
---|
657 | | - } |
---|
658 | 671 | |
---|
659 | 672 | rsb->clk = devm_clk_get(dev, NULL); |
---|
660 | 673 | if (IS_ERR(rsb->clk)) { |
---|
.. | .. |
---|
768 | 781 | return ret; |
---|
769 | 782 | } |
---|
770 | 783 | |
---|
771 | | - return platform_driver_register(&sunxi_rsb_driver); |
---|
| 784 | + ret = platform_driver_register(&sunxi_rsb_driver); |
---|
| 785 | + if (ret) { |
---|
| 786 | + bus_unregister(&sunxi_rsb_bus); |
---|
| 787 | + return ret; |
---|
| 788 | + } |
---|
| 789 | + |
---|
| 790 | + return 0; |
---|
772 | 791 | } |
---|
773 | 792 | module_init(sunxi_rsb_init); |
---|
774 | 793 | |
---|