From: Boris Brezillon <boris.brezillon@bootlin.com>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: David Woodhouse <dwmw2@infradead.org>,
Brian Norris <computersforpeace@gmail.com>,
Boris Brezillon <boris.brezillon@free-electrons.com>,
Marek Vasut <marek.vasut@gmail.com>,
Richard Weinberger <richard@nod.at>,
linux-mtd@lists.infradead.org
Subject: Re: [PATCH 2/2 v2] mtd: physmap_of_gemini: Handle pin control
Date: Tue, 20 Nov 2018 15:36:02 +0100 [thread overview]
Message-ID: <20181120153602.166842f0@bbrezillon> (raw)
In-Reply-To: <20181112210729.23580-2-linus.walleij@linaro.org>
On Mon, 12 Nov 2018 22:07:29 +0100
Linus Walleij <linus.walleij@linaro.org> wrote:
> This enables the complex mapping for the Gemini and kicks in
> custom read/write functions that will wrap the existing
> simple functions in calls to enable/disable the parallel
> flash pins using pin controls.
>
> This is necessary on some hardware such as the D-Link
> DIR-685 where all flash pins are patched in/out at the same
> time, but some of the flash pins are in practice unused by
> the flash and have anyway been reused as GPIO.
>
> This concerns specifically CE1 on the Gemini. There is only
> one flash chip, so only CE0 is used, and the line for CE1
> has been reused as chip select for the emulated SPI port
> connected to the display. If we try to use the same lines
> for flash and GPIO at the same time, one of them will loose:
> the GPIO line will disappear because it gets disconnected
> from the pin when the flash group is muxed out.
>
> Fix this by introducing two pin control states named simply
> "enabled" and "disabled" and only enable the flash lines
> when absolutely necessary (during read/write/copy). This
> way, they are available for GPIO at all other times and
> the display works.
Okay, so your GPIOs might be unavailable when the flash is accessed?
How does that work in practice? Is CE1 muxed as a GPIO on demand? What
happens if the flash and SPI bus are accessed at the same time? Do you
get -EBUSY? Not sure all MTD users retry when they get -EBUSY...
>
> Collect all the state variables in a struct named
> struct gemini_flash and allocate this struct at probe
> time.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v1->v2:
> - Rebase on latest MTD development branch
> ---
> drivers/mtd/maps/Kconfig | 1 +
> drivers/mtd/maps/physmap-gemini.c | 110 +++++++++++++++++++++++++++++-
> 2 files changed, 110 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
> index 2edd8bcdbe1c..e0cf869c8544 100644
> --- a/drivers/mtd/maps/Kconfig
> +++ b/drivers/mtd/maps/Kconfig
> @@ -88,6 +88,7 @@ config MTD_PHYSMAP_GEMINI
> bool "Cortina Gemini OF-based physical memory map handling"
> depends on MTD_PHYSMAP_OF
> depends on MFD_SYSCON
> + select MTD_COMPLEX_MAPPINGS
> default ARCH_GEMINI
> help
> This provides some extra DT physmap parsing for the Gemini
> diff --git a/drivers/mtd/maps/physmap-gemini.c b/drivers/mtd/maps/physmap-gemini.c
> index 1cf128a0526d..60775b208fc9 100644
> --- a/drivers/mtd/maps/physmap-gemini.c
> +++ b/drivers/mtd/maps/physmap-gemini.c
> @@ -10,9 +10,11 @@
> #include <linux/of.h>
> #include <linux/of_device.h>
> #include <linux/mtd/map.h>
> +#include <linux/mtd/xip.h>
> #include <linux/mfd/syscon.h>
> #include <linux/regmap.h>
> #include <linux/bitops.h>
> +#include <linux/pinctrl/consumer.h>
> #include "physmap-gemini.h"
>
> /*
> @@ -44,6 +46,82 @@
>
> #define FLASH_PARALLEL_HIGH_PIN_CNT (1 << 20) /* else low pin cnt */
>
> +static const struct of_device_id syscon_match[] = {
> + { .compatible = "cortina,gemini-syscon" },
> + { },
> +};
> +
> +struct gemini_flash {
> + struct device *dev;
> + struct pinctrl *p;
> + struct pinctrl_state *enabled_state;
> + struct pinctrl_state *disabled_state;
> +};
> +
> +/* Static local state */
> +static struct gemini_flash *gf;
> +
> +static void gemini_flash_enable_pins(void)
> +{
> + int ret;
> +
> + if (IS_ERR(gf->enabled_state))
> + return;
> + ret = pinctrl_select_state(gf->p, gf->enabled_state);
> + if (ret)
> + dev_err(gf->dev, "failed to enable pins\n");
> +}
> +
> +static void gemini_flash_disable_pins(void)
> +{
> + int ret;
> +
> + if (IS_ERR(gf->disabled_state))
> + return;
> + ret = pinctrl_select_state(gf->p, gf->disabled_state);
> + if (ret)
> + dev_err(gf->dev, "failed to disable pins\n");
> +}
> +
> +static map_word __xipram gemini_flash_map_read(struct map_info *map,
> + unsigned long ofs)
> +{
> + map_word __xipram ret;
> +
> + gemini_flash_enable_pins();
> + ret = inline_map_read(map, ofs);
> + gemini_flash_disable_pins();
> +
> + return ret;
> +}
> +
> +static void __xipram gemini_flash_map_write(struct map_info *map,
> + const map_word datum,
> + unsigned long ofs)
> +{
> + gemini_flash_enable_pins();
> + inline_map_write(map, datum, ofs);
> + gemini_flash_disable_pins();
> +}
> +
> +static void __xipram gemini_flash_map_copy_from(struct map_info *map,
> + void *to, unsigned long from,
> + ssize_t len)
> +{
> + gemini_flash_enable_pins();
> + inline_map_copy_from(map, to, from, len);
> + gemini_flash_disable_pins();
> +}
> +
> +static void __xipram gemini_flash_map_copy_to(struct map_info *map,
> + unsigned long to,
> + const void *from, ssize_t len)
> +{
> + gemini_flash_enable_pins();
> + inline_map_copy_to(map, to, from, len);
> + gemini_flash_disable_pins();
> +}
> +
> int of_flash_probe_gemini(struct platform_device *pdev,
> struct device_node *np,
> struct map_info *map)
> @@ -57,6 +135,11 @@ int of_flash_probe_gemini(struct platform_device *pdev,
> if (!of_device_is_compatible(np, "cortina,gemini-flash"))
> return 0;
>
> + gf = devm_kzalloc(dev, sizeof(*gf), GFP_KERNEL);
> + if (!gf)
> + return -ENOMEM;
> + gf->dev = dev;
> +
> rmap = syscon_regmap_lookup_by_phandle(np, "syscon");
> if (IS_ERR(rmap)) {
> dev_err(dev, "no syscon\n");
> @@ -91,7 +174,32 @@ int of_flash_probe_gemini(struct platform_device *pdev,
> map->bankwidth * 8);
> }
>
> - dev_info(&pdev->dev, "initialized Gemini-specific physmap control\n");
> + gf->p = devm_pinctrl_get(dev);
> + if (IS_ERR(gf->p)) {
> + dev_err(dev, "no pinctrl handle\n");
> + ret = PTR_ERR(gf->p);
> + return ret;
> + }
> +
> + gf->enabled_state = pinctrl_lookup_state(gf->p, "enabled");
> + if (IS_ERR(gf->enabled_state))
> + dev_err(dev, "no enabled pin control state\n");
> +
> + gf->disabled_state = pinctrl_lookup_state(gf->p, "disabled");
> + if (IS_ERR(gf->enabled_state)) {
> + dev_err(dev, "no disabled pin control state\n");
> + } else {
> + ret = pinctrl_select_state(gf->p, gf->disabled_state);
> + if (ret)
> + dev_err(gf->dev, "failed to disable pins\n");
> + }
> +
> + map->read = gemini_flash_map_read;
> + map->write = gemini_flash_map_write;
> + map->copy_from = gemini_flash_map_copy_from;
> + map->copy_to = gemini_flash_map_copy_to;
> +
> + dev_info(dev, "initialized Gemini-specific physmap control\n");
>
> return 0;
> }
next prev parent reply other threads:[~2018-11-20 14:36 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-12 21:07 [PATCH 1/2 v2] mtd: maps: Leave assigned complex mappings Linus Walleij
2018-11-12 21:07 ` [PATCH 2/2 v2] mtd: physmap_of_gemini: Handle pin control Linus Walleij
2018-11-20 14:36 ` Boris Brezillon [this message]
2018-11-22 14:10 ` Linus Walleij
2018-11-30 11:17 ` Boris Brezillon
2018-11-30 15:14 ` Linus Walleij
2018-11-20 13:43 ` [PATCH 1/2 v2] mtd: maps: Leave assigned complex mappings Boris Brezillon
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=20181120153602.166842f0@bbrezillon \
--to=boris.brezillon@bootlin.com \
--cc=boris.brezillon@free-electrons.com \
--cc=computersforpeace@gmail.com \
--cc=dwmw2@infradead.org \
--cc=linus.walleij@linaro.org \
--cc=linux-mtd@lists.infradead.org \
--cc=marek.vasut@gmail.com \
--cc=richard@nod.at \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox