diff options
Diffstat (limited to 'drivers/i3c/master/i3c-master-cdns.c')
-rw-r--r-- | drivers/i3c/master/i3c-master-cdns.c | 90 |
1 files changed, 24 insertions, 66 deletions
diff --git a/drivers/i3c/master/i3c-master-cdns.c b/drivers/i3c/master/i3c-master-cdns.c index fd3752cea654..97b151564d3d 100644 --- a/drivers/i3c/master/i3c-master-cdns.c +++ b/drivers/i3c/master/i3c-master-cdns.c @@ -23,6 +23,8 @@ #include <linux/spinlock.h> #include <linux/workqueue.h> +#include "../internals.h" + #define DEV_ID 0x0 #define DEV_ID_I3C_MASTER 0x5034 @@ -412,7 +414,6 @@ struct cdns_i3c_master { } xferqueue; void __iomem *regs; struct clk *sysclk; - struct clk *pclk; struct cdns_i3c_master_caps caps; unsigned long i3c_scl_lim; const struct cdns_i3c_data *devdata; @@ -427,25 +428,13 @@ to_cdns_i3c_master(struct i3c_master_controller *master) static void cdns_i3c_master_wr_to_tx_fifo(struct cdns_i3c_master *master, const u8 *bytes, int nbytes) { - writesl(master->regs + TX_FIFO, bytes, nbytes / 4); - if (nbytes & 3) { - u32 tmp = 0; - - memcpy(&tmp, bytes + (nbytes & ~3), nbytes & 3); - writesl(master->regs + TX_FIFO, &tmp, 1); - } + i3c_writel_fifo(master->regs + TX_FIFO, bytes, nbytes); } static void cdns_i3c_master_rd_from_rx_fifo(struct cdns_i3c_master *master, u8 *bytes, int nbytes) { - readsl(master->regs + RX_FIFO, bytes, nbytes / 4); - if (nbytes & 3) { - u32 tmp; - - readsl(master->regs + RX_FIFO, &tmp, 1); - memcpy(bytes + (nbytes & ~3), &tmp, nbytes & 3); - } + i3c_readl_fifo(master->regs + RX_FIFO, bytes, nbytes); } static bool cdns_i3c_master_supports_ccc_cmd(struct i3c_master_controller *m, @@ -742,7 +731,7 @@ static int cdns_i3c_master_priv_xfers(struct i3c_dev_desc *dev, for (i = 0; i < nxfers; i++) { if (xfers[i].len > CMD0_FIFO_PL_LEN_MAX) - return -ENOTSUPP; + return -EOPNOTSUPP; } if (!nxfers) @@ -750,7 +739,7 @@ static int cdns_i3c_master_priv_xfers(struct i3c_dev_desc *dev, if (nxfers > master->caps.cmdfifodepth || nxfers > master->caps.cmdrfifodepth) - return -ENOTSUPP; + return -EOPNOTSUPP; /* * First make sure that all transactions (block of transfers separated @@ -765,7 +754,7 @@ static int cdns_i3c_master_priv_xfers(struct i3c_dev_desc *dev, if (rxslots > master->caps.rxfifodepth || txslots > master->caps.txfifodepth) - return -ENOTSUPP; + return -EOPNOTSUPP; cdns_xfer = cdns_i3c_master_alloc_xfer(master, nxfers); if (!cdns_xfer) @@ -822,11 +811,11 @@ static int cdns_i3c_master_i2c_xfers(struct i2c_dev_desc *dev, int i, ret = 0; if (nxfers > master->caps.cmdfifodepth) - return -ENOTSUPP; + return -EOPNOTSUPP; for (i = 0; i < nxfers; i++) { if (xfers[i].len > CMD0_FIFO_PL_LEN_MAX) - return -ENOTSUPP; + return -EOPNOTSUPP; if (xfers[i].flags & I2C_M_RD) nrxwords += DIV_ROUND_UP(xfers[i].len, 4); @@ -836,7 +825,7 @@ static int cdns_i3c_master_i2c_xfers(struct i2c_dev_desc *dev, if (ntxwords > master->caps.txfifodepth || nrxwords > master->caps.rxfifodepth) - return -ENOTSUPP; + return -EOPNOTSUPP; xfer = cdns_i3c_master_alloc_xfer(master, nxfers); if (!xfer) @@ -863,7 +852,7 @@ static int cdns_i3c_master_i2c_xfers(struct i2c_dev_desc *dev, } cdns_i3c_master_queue_xfer(master, xfer); - if (!wait_for_completion_timeout(&xfer->comp, msecs_to_jiffies(1000))) + if (!wait_for_completion_timeout(&xfer->comp, m->i2c.timeout)) cdns_i3c_master_unqueue_xfer(master, xfer); ret = xfer->ret; @@ -1330,12 +1319,7 @@ static void cdns_i3c_master_handle_ibi(struct cdns_i3c_master *master, buf = slot->data; nbytes = IBIR_XFER_BYTES(ibir); - readsl(master->regs + IBI_DATA_FIFO, buf, nbytes / 4); - if (nbytes % 3) { - u32 tmp = __raw_readl(master->regs + IBI_DATA_FIFO); - - memcpy(buf + (nbytes & ~3), &tmp, nbytes & 3); - } + i3c_readl_fifo(master->regs + IBI_DATA_FIFO, buf, nbytes); slot->len = min_t(unsigned int, IBIR_XFER_BYTES(ibir), dev->ibi->max_payload_len); @@ -1566,6 +1550,7 @@ MODULE_DEVICE_TABLE(of, cdns_i3c_master_of_ids); static int cdns_i3c_master_probe(struct platform_device *pdev) { struct cdns_i3c_master *master; + struct clk *pclk; int ret, irq; u32 val; @@ -1581,11 +1566,11 @@ static int cdns_i3c_master_probe(struct platform_device *pdev) if (IS_ERR(master->regs)) return PTR_ERR(master->regs); - master->pclk = devm_clk_get(&pdev->dev, "pclk"); - if (IS_ERR(master->pclk)) - return PTR_ERR(master->pclk); + pclk = devm_clk_get_enabled(&pdev->dev, "pclk"); + if (IS_ERR(pclk)) + return PTR_ERR(pclk); - master->sysclk = devm_clk_get(&pdev->dev, "sysclk"); + master->sysclk = devm_clk_get_enabled(&pdev->dev, "sysclk"); if (IS_ERR(master->sysclk)) return PTR_ERR(master->sysclk); @@ -1593,18 +1578,8 @@ static int cdns_i3c_master_probe(struct platform_device *pdev) if (irq < 0) return irq; - ret = clk_prepare_enable(master->pclk); - if (ret) - return ret; - - ret = clk_prepare_enable(master->sysclk); - if (ret) - goto err_disable_pclk; - - if (readl(master->regs + DEV_ID) != DEV_ID_I3C_MASTER) { - ret = -EINVAL; - goto err_disable_sysclk; - } + if (readl(master->regs + DEV_ID) != DEV_ID_I3C_MASTER) + return -EINVAL; spin_lock_init(&master->xferqueue.lock); INIT_LIST_HEAD(&master->xferqueue.list); @@ -1615,7 +1590,7 @@ static int cdns_i3c_master_probe(struct platform_device *pdev) ret = devm_request_irq(&pdev->dev, irq, cdns_i3c_master_interrupt, 0, dev_name(&pdev->dev), master); if (ret) - goto err_disable_sysclk; + return ret; platform_set_drvdata(pdev, master); @@ -1637,29 +1612,15 @@ static int cdns_i3c_master_probe(struct platform_device *pdev) master->ibi.slots = devm_kcalloc(&pdev->dev, master->ibi.num_slots, sizeof(*master->ibi.slots), GFP_KERNEL); - if (!master->ibi.slots) { - ret = -ENOMEM; - goto err_disable_sysclk; - } + if (!master->ibi.slots) + return -ENOMEM; writel(IBIR_THR(1), master->regs + CMD_IBI_THR_CTRL); writel(MST_INT_IBIR_THR, master->regs + MST_IER); writel(DEVS_CTRL_DEV_CLR_ALL, master->regs + DEVS_CTRL); - ret = i3c_master_register(&master->base, &pdev->dev, - &cdns_i3c_master_ops, false); - if (ret) - goto err_disable_sysclk; - - return 0; - -err_disable_sysclk: - clk_disable_unprepare(master->sysclk); - -err_disable_pclk: - clk_disable_unprepare(master->pclk); - - return ret; + return i3c_master_register(&master->base, &pdev->dev, + &cdns_i3c_master_ops, false); } static void cdns_i3c_master_remove(struct platform_device *pdev) @@ -1668,9 +1629,6 @@ static void cdns_i3c_master_remove(struct platform_device *pdev) cancel_work_sync(&master->hj_work); i3c_master_unregister(&master->base); - - clk_disable_unprepare(master->sysclk); - clk_disable_unprepare(master->pclk); } static struct platform_driver cdns_i3c_master = { |