| .. | .. |
|---|
| 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 | |
|---|