diff options
Diffstat (limited to 'drivers/i3c')
| -rw-r--r-- | drivers/i3c/master.c | 2 | ||||
| -rw-r--r-- | drivers/i3c/master/dw-i3c-master.c | 25 | ||||
| -rw-r--r-- | drivers/i3c/master/i3c-master-cdns.c | 4 |
3 files changed, 17 insertions, 14 deletions
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index c39f89d2deba..2dc628d4f1ae 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c | |||
| @@ -1828,7 +1828,7 @@ int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master, | |||
| 1828 | 1828 | ||
| 1829 | ret = i3c_master_retrieve_dev_info(newdev); | 1829 | ret = i3c_master_retrieve_dev_info(newdev); |
| 1830 | if (ret) | 1830 | if (ret) |
| 1831 | goto err_free_dev; | 1831 | goto err_detach_dev; |
| 1832 | 1832 | ||
| 1833 | olddev = i3c_master_search_i3c_dev_duplicate(newdev); | 1833 | olddev = i3c_master_search_i3c_dev_duplicate(newdev); |
| 1834 | if (olddev) { | 1834 | if (olddev) { |
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c index b532e2c9cf5c..bb03079fbade 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c | |||
| @@ -419,12 +419,9 @@ static void dw_i3c_master_enqueue_xfer(struct dw_i3c_master *master, | |||
| 419 | spin_unlock_irqrestore(&master->xferqueue.lock, flags); | 419 | spin_unlock_irqrestore(&master->xferqueue.lock, flags); |
| 420 | } | 420 | } |
| 421 | 421 | ||
| 422 | static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master, | 422 | static void dw_i3c_master_dequeue_xfer_locked(struct dw_i3c_master *master, |
| 423 | struct dw_i3c_xfer *xfer) | 423 | struct dw_i3c_xfer *xfer) |
| 424 | { | 424 | { |
| 425 | unsigned long flags; | ||
| 426 | |||
| 427 | spin_lock_irqsave(&master->xferqueue.lock, flags); | ||
| 428 | if (master->xferqueue.cur == xfer) { | 425 | if (master->xferqueue.cur == xfer) { |
| 429 | u32 status; | 426 | u32 status; |
| 430 | 427 | ||
| @@ -439,6 +436,15 @@ static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master, | |||
| 439 | } else { | 436 | } else { |
| 440 | list_del_init(&xfer->node); | 437 | list_del_init(&xfer->node); |
| 441 | } | 438 | } |
| 439 | } | ||
| 440 | |||
| 441 | static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master, | ||
| 442 | struct dw_i3c_xfer *xfer) | ||
| 443 | { | ||
| 444 | unsigned long flags; | ||
| 445 | |||
| 446 | spin_lock_irqsave(&master->xferqueue.lock, flags); | ||
| 447 | dw_i3c_master_dequeue_xfer_locked(master, xfer); | ||
| 442 | spin_unlock_irqrestore(&master->xferqueue.lock, flags); | 448 | spin_unlock_irqrestore(&master->xferqueue.lock, flags); |
| 443 | } | 449 | } |
| 444 | 450 | ||
| @@ -494,7 +500,7 @@ static void dw_i3c_master_end_xfer_locked(struct dw_i3c_master *master, u32 isr) | |||
| 494 | complete(&xfer->comp); | 500 | complete(&xfer->comp); |
| 495 | 501 | ||
| 496 | if (ret < 0) { | 502 | if (ret < 0) { |
| 497 | dw_i3c_master_dequeue_xfer(master, xfer); | 503 | dw_i3c_master_dequeue_xfer_locked(master, xfer); |
| 498 | writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_RESUME, | 504 | writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_RESUME, |
| 499 | master->regs + DEVICE_CTRL); | 505 | master->regs + DEVICE_CTRL); |
| 500 | } | 506 | } |
| @@ -901,9 +907,6 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev, | |||
| 901 | master->regs + | 907 | master->regs + |
| 902 | DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); | 908 | DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); |
| 903 | 909 | ||
| 904 | if (!old_dyn_addr) | ||
| 905 | return 0; | ||
| 906 | |||
| 907 | master->addrs[data->index] = dev->info.dyn_addr; | 910 | master->addrs[data->index] = dev->info.dyn_addr; |
| 908 | 911 | ||
| 909 | return 0; | 912 | return 0; |
| @@ -925,11 +928,11 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) | |||
| 925 | return -ENOMEM; | 928 | return -ENOMEM; |
| 926 | 929 | ||
| 927 | data->index = pos; | 930 | data->index = pos; |
| 928 | master->addrs[pos] = dev->info.dyn_addr; | 931 | master->addrs[pos] = dev->info.dyn_addr ? : dev->info.static_addr; |
| 929 | master->free_pos &= ~BIT(pos); | 932 | master->free_pos &= ~BIT(pos); |
| 930 | i3c_dev_set_master_data(dev, data); | 933 | i3c_dev_set_master_data(dev, data); |
| 931 | 934 | ||
| 932 | writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr), | 935 | writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->addrs[pos]), |
| 933 | master->regs + | 936 | master->regs + |
| 934 | DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); | 937 | DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); |
| 935 | 938 | ||
diff --git a/drivers/i3c/master/i3c-master-cdns.c b/drivers/i3c/master/i3c-master-cdns.c index bbd79b8b1a80..8889a4fdb454 100644 --- a/drivers/i3c/master/i3c-master-cdns.c +++ b/drivers/i3c/master/i3c-master-cdns.c | |||
| @@ -1556,8 +1556,8 @@ static int cdns_i3c_master_probe(struct platform_device *pdev) | |||
| 1556 | return PTR_ERR(master->pclk); | 1556 | return PTR_ERR(master->pclk); |
| 1557 | 1557 | ||
| 1558 | master->sysclk = devm_clk_get(&pdev->dev, "sysclk"); | 1558 | master->sysclk = devm_clk_get(&pdev->dev, "sysclk"); |
| 1559 | if (IS_ERR(master->pclk)) | 1559 | if (IS_ERR(master->sysclk)) |
| 1560 | return PTR_ERR(master->pclk); | 1560 | return PTR_ERR(master->sysclk); |
| 1561 | 1561 | ||
| 1562 | irq = platform_get_irq(pdev, 0); | 1562 | irq = platform_get_irq(pdev, 0); |
| 1563 | if (irq < 0) | 1563 | if (irq < 0) |
