linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hector Martin <marcan@marcan.st>
To: linux-arm-kernel@lists.infradead.org
Cc: Hector Martin <marcan@marcan.st>, Marc Zyngier <maz@kernel.org>,
	Rob Herring <robh@kernel.org>, Arnd Bergmann <arnd@kernel.org>,
	Olof Johansson <olof@lixom.net>,
	Krzysztof Kozlowski <krzk@kernel.org>,
	Mark Kettenis <mark.kettenis@xs4all.nl>,
	Tony Lindgren <tony@atomide.com>,
	Mohamed Mediouni <mohamed.mediouni@caramail.com>,
	Stan Skowronek <stan@corellium.com>,
	Alexander Graf <graf@amazon.com>, Will Deacon <will@kernel.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Andy Shevchenko <andy.shevchenko@gmail.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jonathan Corbet <corbet@lwn.net>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Christoph Hellwig <hch@infradead.org>,
	"David S. Miller" <davem@davemloft.net>,
	devicetree@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-samsung-soc@vger.kernel.org,
	linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs
Date: Fri,  5 Mar 2021 06:38:45 +0900	[thread overview]
Message-ID: <20210304213902.83903-11-marcan@marcan.st> (raw)
In-Reply-To: <20210304213902.83903-1-marcan@marcan.st>

This documents the newly introduced ioremap_np() along with all the
other common ioremap() variants, and some higher-level abstractions
available.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 Documentation/driver-api/device-io.rst | 218 +++++++++++++++++++++++++
 1 file changed, 218 insertions(+)

diff --git a/Documentation/driver-api/device-io.rst b/Documentation/driver-api/device-io.rst
index b20864b3ddc7..0e12a1d3592b 100644
--- a/Documentation/driver-api/device-io.rst
+++ b/Documentation/driver-api/device-io.rst
@@ -284,6 +284,224 @@ insl, insw, insb, outsl, outsw, outsb
   first byte in the FIFO register corresponds to the first byte in the memory
   buffer regardless of the architecture.
 
+Device memory mapping modes
+===========================
+
+Some architectures support multiple modes for mapping device memory.
+ioremap_*() variants provide a common abstraction around these
+architecture-specific modes, with a shared set of semantics.
+
+ioremap() is the most common mapping type, and is applicable to typical device
+memory (e.g. I/O registers). Other modes can offer weaker or stronger
+guarantees, if supported by the architecture. In order from strongest to
+weakest, they are as follows:
+
+ioremap_np()
+------------
+
+Like ioremap(), but explicitly requests non-posted write semantics. On some
+architectures and buses, ioremap() mappings have posted write semantics, which
+means that writes can appear to "complete" from the point of view of the
+CPU before the written data actually arrives at the target device. Writes are
+still ordered with respect to other writes and reads from the same device, but
+due to the posted write semantics, this is not the case with respect to other
+devices. ioremap_np() explicitly requests non-posted semantics, which means
+that the write instruction will not appear to complete until the device has
+received (and to some platform-specific extent acknowledged) the written data.
+
+This mapping mode primarily exists to cater for platforms with bus fabrics that
+require this particular mapping mode to work correctly. These platforms set the
+``IORESOURCE_MEM_NONPOSTED`` flag for a resource that requires ioremap_np()
+semantics and portable drivers should use an abstraction that automatically
+selects it where appropriate (see the `Higher-level ioremap abstractions`_
+section below).
+
+The bare ioremap_np() is only available on some architectures; on others, it
+always returns NULL. Drivers should not normally use it, unless they are
+platform-specific or they derive benefit from non-posted writes where
+supported, and can fall back to ioremap() otherwise. The normal approach to
+ensure posted write completion is to do a dummy read after a write as
+explained in `Accessing the device`_, which works with ioremap() on all
+platforms.
+
+ioremap_np() should never be used for PCI drivers. PCI memory space writes are
+always posted, even on architectures that otherwise implement ioremap_np().
+Using ioremap_np() for PCI BARs will at best result in posted write semantics,
+and at worst result in complete breakage.
+
+Note that non-posted write semantics are orthogonal to CPU-side ordering
+guarantees. A CPU may still choose to issue other reads or writes before a
+non-posted write instruction retires. See the previous section on MMIO access
+functions for details on the CPU side of things.
+
+ioremap()
+---------
+
+The default mode, suitable for most memory-mapped devices, e.g. control
+registers. Memory mapped using ioremap() has the following characteristics:
+
+* Uncached - CPU-side caches are bypassed, and all reads and writes are handled
+  directly by the device
+* No speculative operations - the CPU may not issue a read or write to this
+  memory, unless the instruction that does so has been reached in committed
+  program flow.
+* No reordering - The CPU may not reorder accesses to this memory mapping with
+  respect to each other. On some architectures, this relies on barriers in
+  readl_relaxed()/writel_relaxed().
+* No repetition - The CPU may not issue multiple reads or writes for a single
+  program instruction.
+* No write-combining - Each I/O operation results in one discrete read or write
+  being issued to the device, and multiple writes are not combined into larger
+  writes. This may or may not be enforced when using __raw I/O accessors or
+  pointer dereferences.
+* Non-executable - The CPU is not allowed to speculate instruction execution
+  from this memory (it probably goes without saying, but you're also not
+  allowed to jump into device memory).
+
+On many platforms and buses (e.g. PCI), writes issued through ioremap()
+mappings are posted, which means that the CPU does not wait for the write to
+actually reach the target device before retiring the write instruction.
+
+On many platforms, I/O accesses must be aligned with respect to the access
+size; failure to do so will result in an exception or unpredictable results.
+
+ioremap_uc()
+------------
+
+ioremap_uc() behaves like ioremap() except that on the x86 architecture without
+'PAT' mode, it marks memory as uncached even when the MTRR has designated
+it as cacheable, see Documentation/x86/pat.rst.
+
+This should not be used in portable drivers.
+
+ioremap_wc()
+------------
+
+Maps I/O memory as normal memory with write combining. Unlike ioremap(),
+
+* The CPU may speculatively issue reads from the device that the program
+  didn't actually execute, and may choose to basically read whatever it wants.
+* The CPU may reorder operations as long as the result is consistent from the
+  program's point of view.
+* The CPU may write to the same location multiple times, even when the program
+  issued a single write.
+* The CPU may combine several writes into a single larger write.
+
+This mode is typically used for video framebuffers, where it can increase
+performance of writes. It can also be used for other blocks of memory in
+devices (e.g. buffers or shared memory), but care must be taken as accesses are
+not guaranteed to be ordered with respect to normal ioremap() MMIO register
+accesses without explicit barriers.
+
+On a PCI bus, it is usually safe to use ioremap_wc() on MMIO areas marked as
+``IORESOURCE_PREFETCH``, but it may not be used on those without the flag.
+For on-chip devices, there is no corresponding flag, but a driver can use
+ioremap_wc() on a device that is known to be safe.
+
+ioremap_wt()
+------------
+
+Maps I/O memory as normal memory with write-through caching. Like ioremap_wc(),
+but also,
+
+* The CPU may cache writes issued to and reads from the device, and serve reads
+  from that cache.
+
+This mode is sometimes used for video framebuffers, where drivers still expect
+writes to reach the device in a timely manner (and not be stuck in the CPU
+cache), but reads may be served from the cache for efficiency. However, it is
+rarely useful these days, as framebuffer drivers usually perform writes only,
+for which ioremap_wc() is more efficient (as it doesn't needlessly trash the
+cache). Most drivers should not use this.
+
+ioremap_cache()
+---------------
+
+ioremap_cache() effectively maps I/O memory as normal RAM. CPU write-back
+caches can be used, and the CPU is free to treat the device as if it were a
+block of RAM. This should never be used for device memory which has side
+effects of any kind, or which does not return the data previously written on
+read.
+
+It should also not be used for actual RAM, as the returned pointer is an
+``__iomem`` token. memremap() can be used for mapping normal RAM that is outside
+of the linear kernel memory area to a regular pointer.
+
+Portable drivers should avoid the use of ioremap_cache().
+
+Architecture example
+--------------------
+
+Here is how the above modes map to memory attribute settings on the ARM64
+architecture:
+
++------------------------+--------------------------------------------+
+| API                    | Memory region type and cacheability        |
++------------------------+--------------------------------------------+
+| ioremap_np()           | Device-nGnRnE                              |
++------------------------+--------------------------------------------+
+| ioremap()              | Device-nGnRE                               |
++------------------------+--------------------------------------------+
+| ioremap_uc()           | (not implemented)                          |
++------------------------+--------------------------------------------+
+| ioremap_wc()           | Normal-Non Cacheable                       |
++------------------------+--------------------------------------------+
+| ioremap_wt()           | (not implemented; fallback to ioremap)     |
++------------------------+--------------------------------------------+
+| ioremap_cache()        | Normal-Write-Back Cacheable                |
++------------------------+--------------------------------------------+
+
+Higher-level ioremap abstractions
+=================================
+
+Instead of using the above raw ioremap() modes, drivers are encouraged to use
+higher-level APIs. These APIs may implement platform-specific logic to
+automatically choose an appropriate ioremap mode on any given bus, allowing for
+a platform-agnostic driver to work on those platforms without any special
+cases. At the time of this writing, the following ioremap() wrappers have such
+logic:
+
+devm_ioremap_resource()
+
+  Can automatically select ioremap_np() over ioremap() according to platform
+  requirements, if the ``IORESOURCE_MEM_NONPOSTED`` flag is set on the struct
+  resource. Uses devres to automatically unmap the resource when the driver
+  probe() function fails or a device in unbound from its driver.
+
+  Documented in Documentation/driver-api/driver-model/devres.rst.
+
+of_address_to_resource()
+
+  Automatically sets the ``IORESOURCE_MEM_NONPOSTED`` flag for platforms that
+  require non-posted writes for certain buses (see the nonposted-mmio and
+  posted-mmio device tree properties).
+
+of_iomap()
+
+  Maps the resource described in a ``reg`` property in the device tree, doing
+  all required translations. Automatically selects ioremap_np() according to
+  platform requirements, as above.
+
+pci_ioremap_bar(), pci_ioremap_wc_bar()
+
+  Maps the resource described in a PCI base address without having to extract
+  the physical address first.
+
+pci_iomap(), pci_iomap_wc()
+
+  Like pci_ioremap_bar()/pci_ioremap_bar(), but also works on I/O space when
+  used together with ioread32()/iowrite32() and similar accessors
+
+pcim_iomap()
+
+  Like pci_iomap(), but uses devres to automatically unmap the resource when
+  the driver probe() function fails or a device in unbound from its driver
+
+  Documented in Documentation/driver-api/driver-model/devres.rst.
+
+Not using these wrappers may make drivers unusable on certain platforms with
+stricter rules for mapping I/O memory.
+
 Public Functions Provided
 =========================
 
-- 
2.30.0


  parent reply	other threads:[~2021-03-04 21:42 UTC|newest]

Thread overview: 136+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
2021-03-04 21:38 ` [RFT PATCH v3 01/27] arm64: Cope with CPUs stuck in VHE mode Hector Martin
2021-03-24 18:05   ` Will Deacon
2021-03-24 20:00     ` Marc Zyngier
2021-03-26  7:54       ` Hector Martin
2021-03-04 21:38 ` [RFT PATCH v3 02/27] dt-bindings: vendor-prefixes: Add apple prefix Hector Martin
2021-03-08 20:26   ` Rob Herring
2021-03-04 21:38 ` [RFT PATCH v3 03/27] dt-bindings: arm: apple: Add bindings for Apple ARM platforms Hector Martin
2021-03-05 10:16   ` Linus Walleij
2021-03-08 20:27   ` Rob Herring
2021-03-04 21:38 ` [RFT PATCH v3 04/27] dt-bindings: arm: cpus: Add apple,firestorm & icestorm compatibles Hector Martin
2021-03-08 20:27   ` Rob Herring
2021-03-04 21:38 ` [RFT PATCH v3 05/27] arm64: cputype: Add CPU implementor & types for the Apple M1 cores Hector Martin
2021-03-24 18:13   ` Will Deacon
2021-03-04 21:38 ` [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support Hector Martin
2021-03-05 10:18   ` Linus Walleij
2021-03-08 11:12   ` Marc Zyngier
2021-03-08 17:14   ` Tony Lindgren
2021-03-08 20:38   ` Rob Herring
2021-03-08 22:42     ` Marc Zyngier
2021-03-09 16:11       ` Rob Herring
2021-03-09 20:28         ` Hector Martin
2021-03-04 21:38 ` [RFT PATCH v3 07/27] arm64: arch_timer: implement support for interrupt-names Hector Martin
2021-03-05 10:19   ` Linus Walleij
2021-03-08 11:13   ` Marc Zyngier
2021-03-04 21:38 ` [RFT PATCH v3 08/27] asm-generic/io.h: Add a non-posted variant of ioremap() Hector Martin
2021-03-05 14:45   ` Andy Shevchenko
2021-03-05 15:19     ` Hector Martin
2021-03-08 11:20   ` Marc Zyngier
2021-03-24 18:12   ` Will Deacon
2021-03-24 19:09     ` Arnd Bergmann
2021-03-25 14:07       ` Hector Martin
2021-03-25 14:49         ` Will Deacon
2021-03-04 21:38 ` [RFT PATCH v3 09/27] docs: driver-api: device-io: Document I/O access functions Hector Martin
2021-03-05 10:22   ` Linus Walleij
2021-03-04 21:38 ` Hector Martin [this message]
2021-03-05 10:25   ` [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs Linus Walleij
2021-03-05 15:09     ` Andy Shevchenko
2021-03-05 15:51       ` Arnd Bergmann
2021-03-09 20:29         ` Hector Martin
2021-03-04 21:38 ` [RFT PATCH v3 11/27] arm64: Implement ioremap_np() to map MMIO as nGnRnE Hector Martin
2021-03-08 11:22   ` Marc Zyngier
2021-03-24 18:18   ` Will Deacon
2021-03-04 21:38 ` [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted Hector Martin
2021-03-05 10:28   ` Linus Walleij
2021-03-05 15:13   ` Andy Shevchenko
2021-03-05 15:55     ` Hector Martin
2021-03-05 16:08       ` Andy Shevchenko
2021-03-05 16:43         ` Arnd Bergmann
2021-03-05 17:19           ` Hector Martin
2021-03-05 16:05     ` Rob Herring
2021-03-05 17:39   ` Rob Herring
2021-03-05 18:18     ` Hector Martin
2021-03-05 21:17       ` Arnd Bergmann
2021-03-08 15:56         ` Rob Herring
2021-03-08 20:29           ` Arnd Bergmann
2021-03-08 21:13             ` Rob Herring
2021-03-08 21:56               ` Arnd Bergmann
2021-03-09 15:48                 ` Rob Herring
2021-03-09 20:23                   ` Hector Martin
2021-03-09 22:06                     ` Rob Herring
2021-03-10  8:26                       ` Hector Martin
2021-03-10 17:01                         ` Rob Herring
2021-03-11  9:12                           ` Arnd Bergmann
2021-03-11 12:11                             ` Hector Martin
2021-03-11 13:35                               ` Arnd Bergmann
2021-03-11 16:07                             ` Rob Herring
2021-03-11 16:48                               ` Arnd Bergmann
2021-03-11 18:10                                 ` Rob Herring
2021-03-12 10:20                                   ` Arnd Bergmann
2021-03-09 11:14               ` Linus Walleij
2021-03-09 12:41                 ` Arnd Bergmann
2021-03-09 15:40                   ` Linus Walleij
2021-03-04 21:38 ` [RFT PATCH v3 13/27] arm64: Add Apple vendor-specific system registers Hector Martin
2021-03-24 18:38   ` Will Deacon
2021-03-24 18:59     ` Mark Rutland
2021-03-24 19:04       ` Will Deacon
2021-03-26  6:23         ` Hector Martin
2021-03-04 21:38 ` [RFT PATCH v3 14/27] arm64: move ICH_ sysreg bits from arm-gic-v3.h to sysreg.h Hector Martin
2021-03-08 11:39   ` Marc Zyngier
2021-03-24 18:23   ` Will Deacon
2021-03-04 21:38 ` [RFT PATCH v3 15/27] dt-bindings: interrupt-controller: Add DT bindings for apple-aic Hector Martin
2021-03-08 21:16   ` Rob Herring
2021-03-04 21:38 ` [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller Hector Martin
2021-03-05 15:05   ` Andy Shevchenko
2021-03-08 11:50     ` Marc Zyngier
2021-03-08 12:02       ` Andy Shevchenko
2021-03-26 13:40     ` Hector Martin
2021-03-08 13:31   ` Marc Zyngier
2021-03-26  7:57     ` Hector Martin
2021-03-24 19:57   ` Will Deacon
2021-03-26  8:58     ` Hector Martin
2021-03-29 12:04       ` Will Deacon
2021-04-01 13:16         ` Hector Martin
2021-03-04 21:38 ` [RFT PATCH v3 17/27] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE Hector Martin
2021-03-08 15:35   ` Marc Zyngier
2021-03-09 20:30     ` Hector Martin
2021-03-04 21:38 ` [RFT PATCH v3 18/27] tty: serial: samsung_tty: Separate S3C64XX ops structure Hector Martin
2021-03-05 10:30   ` Krzysztof Kozlowski
2021-03-04 21:38 ` [RFT PATCH v3 19/27] tty: serial: samsung_tty: Add ucon_mask parameter Hector Martin
2021-03-05 10:34   ` Krzysztof Kozlowski
2021-03-04 21:38 ` [RFT PATCH v3 20/27] tty: serial: samsung_tty: Add s3c24xx_port_type Hector Martin
2021-03-05 10:49   ` Krzysztof Kozlowski
2021-03-04 21:38 ` [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework Hector Martin
2021-03-05 10:51   ` Krzysztof Kozlowski
2021-03-05 15:17   ` Andy Shevchenko
2021-03-05 16:16     ` Hector Martin
2021-03-05 16:20       ` Andy Shevchenko
2021-03-05 16:29         ` Hector Martin
2021-03-07 11:34           ` Krzysztof Kozlowski
2021-03-07 16:01             ` Arnd Bergmann
2021-03-07 19:51               ` Krzysztof Kozlowski
2021-03-04 21:38 ` [RFT PATCH v3 22/27] tty: serial: samsung_tty: Use devm_ioremap_resource Hector Martin
2021-03-05 10:54   ` Krzysztof Kozlowski
2021-03-05 15:19     ` Andy Shevchenko
2021-03-04 21:38 ` [RFT PATCH v3 23/27] dt-bindings: serial: samsung: Add apple,s5l-uart compatible Hector Martin
2021-03-08 21:17   ` Rob Herring
2021-03-04 21:38 ` [RFT PATCH v3 24/27] tty: serial: samsung_tty: Add support for Apple UARTs Hector Martin
2021-03-05 10:58   ` Krzysztof Kozlowski
2021-03-05 15:28   ` Andy Shevchenko
2021-03-05 17:04     ` Hector Martin
2021-03-07 11:40       ` Krzysztof Kozlowski
2021-03-04 21:39 ` [RFT PATCH v3 25/27] tty: serial: samsung_tty: Add earlycon " Hector Martin
2021-03-05 10:55   ` Krzysztof Kozlowski
2021-03-10 23:11   ` Linus Walleij
2021-03-04 21:39 ` [RFT PATCH v3 26/27] dt-bindings: display: Add apple,simple-framebuffer Hector Martin
2021-03-08 21:18   ` Rob Herring
2021-03-09 16:37   ` Linus Walleij
2021-03-09 20:35     ` Hector Martin
2021-03-04 21:39 ` [RFT PATCH v3 27/27] arm64: apple: Add initial Apple Mac mini (M1, 2020) devicetree Hector Martin
2021-03-05 11:03   ` Krzysztof Kozlowski
2021-03-05 11:14     ` Hector Martin
2021-03-05 11:45       ` Krzysztof Kozlowski
2021-03-05 15:59       ` Mark Kettenis
2021-03-05 16:50         ` Hector Martin
2021-03-05 10:11 ` [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin

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=20210304213902.83903-11-marcan@marcan.st \
    --to=marcan@marcan.st \
    --cc=andy.shevchenko@gmail.com \
    --cc=arnd@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=graf@amazon.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hch@infradead.org \
    --cc=krzk@kernel.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=mark.kettenis@xs4all.nl \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=mohamed.mediouni@caramail.com \
    --cc=olof@lixom.net \
    --cc=robh@kernel.org \
    --cc=stan@corellium.com \
    --cc=tony@atomide.com \
    --cc=will@kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).