From: Marek Vasut <marex@denx.de>
To: Cyrille Pitchen <cyrille.pitchen@atmel.com>,
computersforpeace@gmail.com, linux-mtd@lists.infradead.org
Cc: nicolas.ferre@atmel.com, boris.brezillon@free-electrons.com,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH RFC 8/8] mtd: atmel-quadspi: add driver for Atmel QSPI controller
Date: Sat, 16 Apr 2016 00:17:31 +0200 [thread overview]
Message-ID: <5711687B.5030209@denx.de> (raw)
In-Reply-To: <be9fcd1c8dd7a6ae076b700ff6a54f028021295a.1460567256.git.cyrille.pitchen@atmel.com>
On 04/13/2016 07:23 PM, Cyrille Pitchen wrote:
> This driver add support to the new Atmel QSPI controller embedded into
> sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
> controller.
>
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
[...]
> +static int atmel_qspi_run_transfer(struct atmel_qspi *aq,
> + const struct atmel_qspi_command *cmd)
> +{
> + void __iomem *ahb_mem;
> +
> + /* Then fallback to a PIO transfer (memcpy() DOES NOT work!) */
My first reaction when reading this comment was "HUH?" . Can you explain
the problem a bit better please ?
> + ahb_mem = aq->mem;
> + if (cmd->enable.bits.address)
> + ahb_mem += cmd->address;
> + if (cmd->tx_buf)
> + _memcpy_toio(ahb_mem, cmd->tx_buf, cmd->buf_len);
> + else
> + _memcpy_fromio(cmd->rx_buf, ahb_mem, cmd->buf_len);
Why the leading underscore ?
> + return 0;
> +}
[...]
> +static int atmel_qspi_probe(struct platform_device *pdev)
> +{
> + struct device_node *child, *np = pdev->dev.of_node;
> + struct spi_nor_modes modes = {
> + .id_modes = (SNOR_MODE_1_1_1 |
> + SNOR_MODE_2_2_2 |
> + SNOR_MODE_4_4_4),
> + .rd_modes = (SNOR_MODE_SLOW |
> + SNOR_MODE_1_1_1 |
> + SNOR_MODE_1_1_2 |
> + SNOR_MODE_1_2_2 |
> + SNOR_MODE_2_2_2 |
> + SNOR_MODE_1_1_4 |
> + SNOR_MODE_1_4_4 |
> + SNOR_MODE_4_4_4),
> + .wr_modes = (SNOR_MODE_1_1_1 |
> + SNOR_MODE_1_1_2 |
> + SNOR_MODE_1_2_2 |
> + SNOR_MODE_2_2_2 |
> + SNOR_MODE_1_1_4 |
> + SNOR_MODE_1_4_4 |
> + SNOR_MODE_4_4_4),
> + };
> + char modalias[SPI_NAME_SIZE];
> + const char *name = NULL;
> + struct atmel_qspi *aq;
> + struct resource *res;
> + struct spi_nor *nor;
> + struct mtd_info *mtd;
> + int irq, err = 0;
> +
> + if (of_get_child_count(np) != 1)
> + return -ENODEV;
> + child = of_get_next_child(np, NULL);
> +
> + aq = devm_kzalloc(&pdev->dev, sizeof(*aq), GFP_KERNEL);
> + if (!aq) {
> + err = -ENOMEM;
> + goto exit;
> + }
> +
> + platform_set_drvdata(pdev, aq);
> + init_completion(&aq->cmd_completion);
> + aq->pdev = pdev;
> +
> + /* Map the registers */
> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base");
> + aq->regs = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(aq->regs)) {
> + dev_err(&pdev->dev, "missing registers\n");
> + err = PTR_ERR(aq->regs);
> + goto exit;
> + }
> +
> + /* Map the AHB memory */
> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mmap");
> + aq->mem = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(aq->mem)) {
> + dev_err(&pdev->dev, "missing AHB memory\n");
> + err = PTR_ERR(aq->mem);
> + goto exit;
> + }
> +
> + /* Get the peripheral clock */
> + aq->clk = devm_clk_get(&pdev->dev, NULL);
> + if (IS_ERR(aq->clk)) {
> + dev_err(&pdev->dev, "missing peripheral clock\n");
> + err = PTR_ERR(aq->clk);
> + goto exit;
> + }
> +
> + /* Enable the peripheral clock */
> + err = clk_prepare_enable(aq->clk);
> + if (err) {
> + dev_err(&pdev->dev, "failed to enable the peripheral clock\n");
> + goto exit;
> + }
> +
> + /* Request the IRQ */
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0) {
> + dev_err(&pdev->dev, "missing IRQ\n");
> + err = irq;
> + goto disable_clk;
> + }
> + err = devm_request_irq(&pdev->dev, irq, atmel_qspi_interrupt,
> + 0, dev_name(&pdev->dev), aq);
> + if (err)
> + goto disable_clk;
> +
> + /* Setup the spi-nor */
Can you extract this into a separate function? I think this "setup spi
nor" part is starting to turn into a nice boilerplate code :) It'd be
nice to have it readily isolated and prepared for factoring out once
the time comes.
Does this controller support multiple SPI NORs ?
> + nor = &aq->nor;
> + mtd = &nor->mtd;
> +
> + nor->dev = &pdev->dev;
> + spi_nor_set_flash_node(nor, child);
> + nor->priv = aq;
> + mtd->priv = nor;
> +
> + nor->read_reg = atmel_qspi_read_reg;
> + nor->write_reg = atmel_qspi_write_reg;
> + nor->read = atmel_qspi_read;
> + nor->write = atmel_qspi_write;
> + nor->erase = atmel_qspi_erase;
> +
> + err = of_modalias_node(child, modalias, sizeof(modalias));
> + if (err < 0)
> + goto disable_clk;
> +
> + if (strcmp(modalias, "spi-nor"))
> + name = modalias;
> +
> + err = of_property_read_u32(child, "spi-max-frequency", &aq->clk_rate);
> + if (err < 0)
> + goto disable_clk;
> +
> + err = atmel_qspi_init(aq);
> + if (err)
> + goto disable_clk;
> +
> + err = spi_nor_scan(nor, name, &modes);
> + if (err)
> + goto disable_clk;
> +
> + err = mtd_device_register(mtd, NULL, 0);
> + if (err)
> + goto disable_clk;
> +
> + of_node_put(child);
> +
> + return 0;
> +
> +disable_clk:
> + clk_disable_unprepare(aq->clk);
> +exit:
> + of_node_put(child);
> +
> + return err;
> +}
> +
> +static int atmel_qspi_remove(struct platform_device *pdev)
> +{
> + struct atmel_qspi *aq = platform_get_drvdata(pdev);
> +
> + mtd_device_unregister(&aq->nor.mtd);
> + qspi_writel(aq, QSPI_CR, QSPI_CR_QSPIDIS);
> + clk_disable_unprepare(aq->clk);
> + return 0;
> +}
> +
> +
> +static const struct of_device_id atmel_qspi_dt_ids[] = {
> + { .compatible = "atmel,sama5d2-qspi" },
Oh neat :)
> + { /* sentinel */ }
> +};
> +
> +MODULE_DEVICE_TABLE(of, atmel_qspi_dt_ids);
> +
> +static struct platform_driver atmel_qspi_driver = {
> + .driver = {
> + .name = "atmel_qspi",
> + .of_match_table = atmel_qspi_dt_ids,
> + },
> + .probe = atmel_qspi_probe,
> + .remove = atmel_qspi_remove,
> +};
> +module_platform_driver(atmel_qspi_driver);
> +
> +MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@atmel.com>");
> +MODULE_DESCRIPTION("Atmel QSPI Controller driver");
> +MODULE_LICENSE("GPL v2");
>
--
Best regards,
Marek Vasut
next prev parent reply other threads:[~2016-04-15 22:18 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-13 17:23 [PATCH RFC 0/8] mtd: spi-nor: fix support of Quad SPI memories Cyrille Pitchen
2016-04-13 17:23 ` [PATCH RFC 1/8] mtd: spi-nor: add an alternative method to support memory >16MiB Cyrille Pitchen
2016-04-13 17:23 ` [PATCH RFC 2/8] mtd: spi-nor: allow different flash_info entries to share the same JEDEC ID Cyrille Pitchen
2016-04-13 17:23 ` [PATCH RFC 3/8] mtd: spi-nor: add entry for Macronix mx25l25673g Cyrille Pitchen
2016-04-13 17:23 ` [PATCH RFC 4/8] mtd: spi-nor: fix support of Dual (x-y-2) and Quad (x-y-4) SPI protocols Cyrille Pitchen
2016-04-15 22:09 ` Marek Vasut
2016-04-25 12:01 ` Cyrille Pitchen
2016-04-24 5:06 ` R, Vignesh
2016-04-25 9:34 ` Cyrille Pitchen
2016-04-13 17:23 ` [PATCH RFC 5/8] mtd: m25p80: add support of dual and quad spi protocols to all commands Cyrille Pitchen
2016-04-13 17:23 ` [PATCH RFC 6/8] mtd: spi-nor: add support for Micron Dual and Quad SPI memories Cyrille Pitchen
2016-04-13 17:23 ` [PATCH RFC 7/8] Documentation: atmel-quadspi: add binding file for Atmel QSPI driver Cyrille Pitchen
2016-04-13 17:23 ` [PATCH RFC 8/8] mtd: atmel-quadspi: add driver for Atmel QSPI controller Cyrille Pitchen
2016-04-15 22:17 ` Marek Vasut [this message]
2016-04-15 21:48 ` [PATCH RFC 0/8] mtd: spi-nor: fix support of Quad SPI memories Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5711687B.5030209@denx.de \
--to=marex@denx.de \
--cc=boris.brezillon@free-electrons.com \
--cc=computersforpeace@gmail.com \
--cc=cyrille.pitchen@atmel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=nicolas.ferre@atmel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.