From 6b3938aed04587dab42f9df83122a40c596f495a Mon Sep 17 00:00:00 2001 From: Sourav Poddar Date: Fri, 6 Dec 2013 19:54:43 +0530 Subject: spi/qspi: parse register by name. Modify the qspi driver to parse reg information by name. If "reg names" is not found, then revert back to normal get resource. Signed-off-by: Sourav Poddar Signed-off-by: Mark Brown --- drivers/spi/spi-ti-qspi.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'drivers/spi/spi-ti-qspi.c') diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 0b71270fbf67..1211b663c814 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -46,6 +46,8 @@ struct ti_qspi { struct spi_master *master; void __iomem *base; + void __iomem *ctrl_base; + void __iomem *mmap_base; struct clk *fclk; struct device *dev; @@ -54,6 +56,8 @@ struct ti_qspi { u32 spi_max_frequency; u32 cmd; u32 dc; + + bool ctrl_mod; }; #define QSPI_PID (0x0) @@ -437,7 +441,7 @@ static int ti_qspi_probe(struct platform_device *pdev) { struct ti_qspi *qspi; struct spi_master *master; - struct resource *r; + struct resource *r, *res_ctrl, *res_mmap; struct device_node *np = pdev->dev.of_node; u32 max_freq; int ret = 0, num_cs, irq; @@ -465,7 +469,35 @@ static int ti_qspi_probe(struct platform_device *pdev) qspi->master = master; qspi->dev = &pdev->dev; - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base"); + if (r == NULL) { + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "missing platform data\n"); + return -ENODEV; + } + } + + res_mmap = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "qspi_mmap"); + if (res_mmap == NULL) { + res_mmap = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res_mmap == NULL) { + dev_err(&pdev->dev, + "memory mapped resource not required\n"); + return -ENODEV; + } + } + + res_ctrl = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "qspi_ctrlmod"); + if (res_ctrl == NULL) { + res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 2); + if (res_ctrl == NULL) { + dev_dbg(&pdev->dev, + "control module resources not required\n"); + } + } irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -481,6 +513,23 @@ static int ti_qspi_probe(struct platform_device *pdev) goto free_master; } + if (res_ctrl) { + qspi->ctrl_mod = true; + qspi->ctrl_base = devm_ioremap_resource(&pdev->dev, res_ctrl); + if (IS_ERR(qspi->ctrl_base)) { + ret = PTR_ERR(qspi->ctrl_base); + goto free_master; + } + } + + if (res_mmap) { + qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap); + if (IS_ERR(qspi->mmap_base)) { + ret = PTR_ERR(qspi->mmap_base); + goto free_master; + } + } + ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0, dev_name(&pdev->dev), qspi); if (ret < 0) { -- cgit v1.2.3 From f17414c4fcf138740dbbd463171101026b6f78de Mon Sep 17 00:00:00 2001 From: Sourav Poddar Date: Fri, 20 Dec 2013 18:22:57 +0530 Subject: spi/qspi: Fix runtime resume path Due to the following commit commit 160a061301c7adf54c40696e7ceedc73f6b747dd Author: Wei Yongjun Date: Mon Nov 11 14:13:41 2013 +0800 spi/qspi: set correct platform drvdata in ti_qspi_probe() The ti_qspi_remove() use the platform drvdata as a type of struct ti_qspi, we should pass correct platform drvdata to platform_set_drvdata() in ti_qspi_probe(). Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown platform_set_drvdata was changed in the probe, so we need to correspondingly change deferencing of qspi in runtime resume path. Else, this will lead to a NULL dereference pointer. Based on v3.13-rc3 Signed-off-by: Sourav Poddar Signed-off-by: Mark Brown --- drivers/spi/spi-ti-qspi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/spi/spi-ti-qspi.c') diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 4396bd448540..06ee18956160 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -417,10 +417,8 @@ out: static int ti_qspi_runtime_resume(struct device *dev) { struct ti_qspi *qspi; - struct spi_master *master; - master = dev_get_drvdata(dev); - qspi = spi_master_get_devdata(master); + qspi = dev_get_drvdata(dev); ti_qspi_restore_ctx(qspi); return 0; -- cgit v1.2.3 From e3d8bee38543b1f3e6731916c4f11bea4d9f760f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 7 Jan 2014 19:04:03 +0800 Subject: spi: ti-qspi: Fix getting correct address for qspi Now platform_get_drvdata() returns the address of qspi rather than master. Also drop unneeded spi_unregister_master() call in ti_qspi_remove() because we use devm_spi_register_master() in probe. commit cbcabb7a300b "spi/qspi: Fix qspi remove path" assumes platform_get_drvdata() returns address of master. However, commit 160a061301c7 "spi/qspi: set correct platform drvdata in ti_qspi_probe()" pass qspi to platform_set_drvdata(). Signed-off-by: Axel Lin Reviewed-by: Sourav Poddar Signed-off-by: Mark Brown --- drivers/spi/spi-ti-qspi.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/spi/spi-ti-qspi.c') diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 06ee18956160..286cf8d6764b 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -514,13 +514,9 @@ free_master: static int ti_qspi_remove(struct platform_device *pdev) { - struct spi_master *master; - struct ti_qspi *qspi; + struct ti_qspi *qspi = platform_get_drvdata(pdev); int ret; - master = platform_get_drvdata(pdev); - qspi = spi_master_get_devdata(master); - ret = pm_runtime_get_sync(qspi->dev); if (ret < 0) { dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); @@ -532,8 +528,6 @@ static int ti_qspi_remove(struct platform_device *pdev) pm_runtime_put(qspi->dev); pm_runtime_disable(&pdev->dev); - spi_unregister_master(master); - return 0; } -- cgit v1.2.3 From 3ab546205411a245ef0f60ec708467a072855c6f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 12 Jan 2014 14:40:22 +0800 Subject: spi: ti-qspi: Simplify qspi_write_msg and qspi_read_msg implementation Make the unit of wlen to be byte, and simplify the code to avoid duplicate code for different wlen cases. Signed-off-by: Axel Lin Acked-by: Sourav Poddar Signed-off-by: Mark Brown --- drivers/spi/spi-ti-qspi.c | 61 ++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 41 deletions(-) (limited to 'drivers/spi/spi-ti-qspi.c') diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 1211b663c814..a850b403b51b 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -208,53 +208,36 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) txbuf = t->tx_buf; cmd = qspi->cmd | QSPI_WR_SNGL; count = t->len; - wlen = t->bits_per_word; + wlen = t->bits_per_word >> 3; /* in bytes */ while (count) { switch (wlen) { - case 8: + case 1: dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n", cmd, qspi->dc, *txbuf); writeb(*txbuf, qspi->base + QSPI_SPI_DATA_REG); - ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); - ret = wait_for_completion_timeout(&qspi->transfer_complete, - QSPI_COMPLETION_TIMEOUT); - if (ret == 0) { - dev_err(qspi->dev, "write timed out\n"); - return -ETIMEDOUT; - } - txbuf += 1; - count -= 1; break; - case 16: + case 2: dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %04x\n", cmd, qspi->dc, *txbuf); writew(*((u16 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); - ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); - ret = wait_for_completion_timeout(&qspi->transfer_complete, - QSPI_COMPLETION_TIMEOUT); - if (ret == 0) { - dev_err(qspi->dev, "write timed out\n"); - return -ETIMEDOUT; - } - txbuf += 2; - count -= 2; break; - case 32: + case 4: dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %08x\n", cmd, qspi->dc, *txbuf); writel(*((u32 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); - ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); - ret = wait_for_completion_timeout(&qspi->transfer_complete, - QSPI_COMPLETION_TIMEOUT); - if (ret == 0) { - dev_err(qspi->dev, "write timed out\n"); - return -ETIMEDOUT; - } - txbuf += 4; - count -= 4; break; } + + ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); + ret = wait_for_completion_timeout(&qspi->transfer_complete, + QSPI_COMPLETION_TIMEOUT); + if (ret == 0) { + dev_err(qspi->dev, "write timed out\n"); + return -ETIMEDOUT; + } + txbuf += wlen; + count -= wlen; } return 0; @@ -280,7 +263,7 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) break; } count = t->len; - wlen = t->bits_per_word; + wlen = t->bits_per_word >> 3; /* in bytes */ while (count) { dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc); @@ -292,22 +275,18 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) return -ETIMEDOUT; } switch (wlen) { - case 8: + case 1: *rxbuf = readb(qspi->base + QSPI_SPI_DATA_REG); - rxbuf += 1; - count -= 1; break; - case 16: + case 2: *((u16 *)rxbuf) = readw(qspi->base + QSPI_SPI_DATA_REG); - rxbuf += 2; - count -= 2; break; - case 32: + case 4: *((u32 *)rxbuf) = readl(qspi->base + QSPI_SPI_DATA_REG); - rxbuf += 4; - count -= 4; break; } + rxbuf += wlen; + count -= wlen; } return 0; -- cgit v1.2.3 From 5a33d30ff1b8fdfb5bd8f4fa46dd473bf768aeff Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 12 Jan 2014 15:02:32 +0800 Subject: spi: ti-qspi: Fixup driver name The driver name in current code looks like a compatible string which is not the naming convention for platform drivers. Fix it and also add modalias since this driver can be built as a module. Signed-off-by: Axel Lin Acked-by: Sourav Poddar Signed-off-by: Mark Brown --- drivers/spi/spi-ti-qspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/spi/spi-ti-qspi.c') diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index a850b403b51b..251e43f72dbb 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -560,7 +560,7 @@ static struct platform_driver ti_qspi_driver = { .probe = ti_qspi_probe, .remove = ti_qspi_remove, .driver = { - .name = "ti,dra7xxx-qspi", + .name = "ti-qspi", .owner = THIS_MODULE, .pm = &ti_qspi_pm_ops, .of_match_table = ti_qspi_match, @@ -572,3 +572,4 @@ module_platform_driver(ti_qspi_driver); MODULE_AUTHOR("Sourav Poddar "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("TI QSPI controller driver"); +MODULE_ALIAS("platform:ti-qspi"); -- cgit v1.2.3