LKML Archive on lore.kernel.org
 help / color / Atom feed
* [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up
@ 2021-03-04 21:38 Hector Martin
  2021-03-04 21:38 ` [RFT PATCH v3 01/27] arm64: Cope with CPUs stuck in VHE mode Hector Martin
                   ` (27 more replies)
  0 siblings, 28 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This series brings up initial support for the Apple M1 SoC, used in the
2020 Mac Mini, MacBook Pro, and MacBook Air models.

The following features are supported in this initial port:

- UART (samsung-style) with earlycon support
- Interrupts, including affinity and IPIs (Apple Interrupt Controller)
- SMP (through standard spin-table support)
- simplefb-based framebuffer
- Devicetree for the Mac Mini (should work for the others too at this
  stage)

See below for an overview of changes since v2.

== Merge notes ==

This patchset depends on both the nVHE changes that are already in
5.12-rc1, as well as the FIQ support work currently being reviewed
at [1]. A tree containing this patchset on top of the required
dependencies is available at [2][3]. Alternatively, you may apply
this series on top of Mark's tree at the arm64-fiq-20210302 tag [4][5].

This series is expected to be merged by Arnd via the SoC tree.
Maintainers, please ack if you are happy with the patches. We will
coordinate with Arnd and Mark on the FIQ series to make sure all
that goes smoothly.

This is marked RFT as it needs some basic testing on other on other
ARM platforms; in particular the Samsung UART driver changes need to be
tested, and the ioremap()/timer changes could use at least a smoke test
on some other arm64 platform. I would appreciate any test reports.

[1] https://lore.kernel.org/linux-arm-kernel/20210302101211.2328-1-mark.rutland@arm.com/T/#t
[2] git://github.com/AsahiLinux/linux.git upstream-bringup-v3
[3] https://github.com/AsahiLinux/linux/tree/upstream-bringup-v3
[4] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64-fiq-20210302
[5] https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/tag/?h=arm64-fiq-20210302

== Testing notes ==

This has been tested on an Apple M1 Mac Mini booting to a framebuffer
and serial console, with SMP and (newly tested since v2) KASLR, with
an arm64 defconfig (+ CONFIG_FB_SIMPLE for the fb).

An arm32 build has been smoke-tested in qemu with the smdkc210 machine,
to test the samsung_tty changes on non-Apple (emulated) hardware.

== Patch overview ==

- 01    Cope with CPUs stuck in VHE mode
        This is a follow-up to the recent nVHE/cpufeature changes in
        mainline by Mark, adding a workaround for the M1's lack of
        nVHE mode.
- 02-03 Core platform DT bindings
- 04-05 CPU DT bindings and MIDR defines
- 06-07 Add interrupt-names support to the ARM timer driver
        This is used to cleanly express the lack of a secure timer;
        platforms in the past have used various hacks like dummy
        IRQs here.
- 08-12 ioremap_np() (nGnRnE) support
        The fabric in these SoCs only supports nGnRnE accesses for
        standard MMIO, except for PCI ranges which use nGnRE. Linux
        currently defaults to the latter on ARM64, so this adds a new
        ioremap type and DT properties to automatically select it for
        drivers using OF and devm abstractions, under buses specified
        in DT.
- 13-16 AIC (Apple Interrupt Controller) driver and support defines
        This also embeds FIQ handling for this platform.
- 17    Introduce CONFIG_ARCH_APPLE & add it to defconfig
- 18-25 Add Apple SoC support to the samsung_tty driver
        This includes several refactoring patches to be able to more
        cleanly introduce this, as well as a switch to
        devm_ioremap_resource to be able to use the nGnRnE support
        introduced above. Earlycon support is included with a
        special-case nGnRnE hack, as earlycon is too early to use the
        generic infrastructure.
- 26    simple-framebuffer bindings for Apple (trivial)
- 27    Add the initial M1 Mac Mini (j274) devicetree

== About the hardware ==

These machines officially support booting unsigned/user-provided
XNU-like kernels, with a very different boot protocol and devicetree
format. We are developing an initial bootloader, m1n1 [1], to take care
of as many hardware peculiarities as possible and present a standard
Linux arm64 boot protocol and device tree. In the future, I expect that
production setups will add U-Boot and perhaps GRUB into the boot chain,
to make the boot process similar to other ARM64 platforms.

The machines expose their debug UART over USB Type C, triggered with
vendor-specific USB-PD commands. Currently, the easiest way to get a
serial console on these machines is to use a second M1 box and a simple
USB C cable [2]. You can also build a DIY interface using an Arduino, a
FUSB302 chip or board, and a 1.2V UART-TTL adapter [3]. In the coming
weeks we will be designing an open hardware project to provide
serial/debug connectivity to these machines (and, hopefully, also
support other UART-over-Type C setups from other vendors). Please
contact me privately if you are interested in getting an early prototype
version of one of these devices.

A quickstart guide to booting Linux kernels on these machines is
available at [4], and we are documenting the hardware at [5].

[1] https://github.com/AsahiLinux/m1n1/
[2] https://github.com/AsahiLinux/macvdmtool/
[3] https://github.com/AsahiLinux/vdmtool/
[4] https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart
[5] https://github.com/AsahiLinux/docs/wiki

== Project Blurb ==

Asahi Linux is an open community project dedicated to developing and
maintaining mainline support for Apple Silicon on Linux. Feel free to
drop by #asahi and #asahi-dev on freenode to chat with us, or check
our website for more information on the project:

https://asahilinux.org/

== Changes since v2 ==

* Removed FIQ support patches, as this is now being handled as a
  separate series.
* Added nVHE workaround patch from Marc
* Renamed dts(i) files to better match conventions used in other
  platforms
* Renamed 'm1' in compatible/dts names to 't8103', to be better
  prepared for the chance of multiple SoCs being released under the
  same marketing name.
* Reworded device tree binding text for the platform.
* Changed the default ioremap_np() implementation to return NULL,
  like ioremap_uc().
* Added general documentation for ioremap() variants, including the
  newly introduced one.
* Reworked virtual IPI support in the AIC driver, and attempted
  to thoroughly shave the memory ordering yak.
* Moved GIC registers to sysregs.h instead of including that in the AIC
  driver.
* Added _EL1 suffixes to Apple sysregs.
* Addressed further review comments and feedback.


Arnd Bergmann (1):
  docs: driver-api: device-io: Document I/O access functions

Hector Martin (25):
  dt-bindings: vendor-prefixes: Add apple prefix
  dt-bindings: arm: apple: Add bindings for Apple ARM platforms
  dt-bindings: arm: cpus: Add apple,firestorm & icestorm compatibles
  arm64: cputype: Add CPU implementor & types for the Apple M1 cores
  dt-bindings: timer: arm,arch_timer: Add interrupt-names support
  arm64: arch_timer: implement support for interrupt-names
  asm-generic/io.h:  Add a non-posted variant of ioremap()
  docs: driver-api: device-io: Document ioremap() variants & access
    funcs
  arm64: Implement ioremap_np() to map MMIO as nGnRnE
  of/address: Add infrastructure to declare MMIO as non-posted
  arm64: Add Apple vendor-specific system registers
  arm64: move ICH_ sysreg bits from arm-gic-v3.h to sysreg.h
  dt-bindings: interrupt-controller: Add DT bindings for apple-aic
  irqchip/apple-aic: Add support for the Apple Interrupt Controller
  arm64: Kconfig: Introduce CONFIG_ARCH_APPLE
  tty: serial: samsung_tty: Separate S3C64XX ops structure
  tty: serial: samsung_tty: Add ucon_mask parameter
  tty: serial: samsung_tty: Add s3c24xx_port_type
  tty: serial: samsung_tty: IRQ rework
  tty: serial: samsung_tty: Use devm_ioremap_resource
  dt-bindings: serial: samsung: Add apple,s5l-uart compatible
  tty: serial: samsung_tty: Add support for Apple UARTs
  tty: serial: samsung_tty: Add earlycon support for Apple UARTs
  dt-bindings: display: Add apple,simple-framebuffer
  arm64: apple: Add initial Apple Mac mini (M1, 2020) devicetree

Marc Zyngier (1):
  arm64: Cope with CPUs stuck in VHE mode

 .../devicetree/bindings/arm/apple.yaml        |  64 ++
 .../devicetree/bindings/arm/cpus.yaml         |   2 +
 .../bindings/display/simple-framebuffer.yaml  |   5 +
 .../interrupt-controller/apple,aic.yaml       |  88 +++
 .../bindings/serial/samsung_uart.yaml         |   4 +-
 .../bindings/timer/arm,arch_timer.yaml        |  14 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 Documentation/driver-api/device-io.rst        | 356 +++++++++
 .../driver-api/driver-model/devres.rst        |   1 +
 MAINTAINERS                                   |  15 +
 arch/arm64/Kconfig.platforms                  |   8 +
 arch/arm64/boot/dts/Makefile                  |   1 +
 arch/arm64/boot/dts/apple/Makefile            |   2 +
 arch/arm64/boot/dts/apple/t8103-j274.dts      |  45 ++
 arch/arm64/boot/dts/apple/t8103.dtsi          | 135 ++++
 arch/arm64/configs/defconfig                  |   1 +
 arch/arm64/include/asm/cputype.h              |   6 +
 arch/arm64/include/asm/io.h                   |   1 +
 arch/arm64/include/asm/sysreg.h               |  60 ++
 arch/arm64/include/asm/sysreg_apple.h         |  69 ++
 arch/arm64/kernel/head.S                      |  33 +-
 arch/arm64/kernel/hyp-stub.S                  |  28 +-
 arch/sparc/include/asm/io_64.h                |   4 +
 drivers/clocksource/arm_arch_timer.c          |  24 +-
 drivers/irqchip/Kconfig                       |   8 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-apple-aic.c               | 710 ++++++++++++++++++
 drivers/of/address.c                          |  72 +-
 drivers/tty/serial/Kconfig                    |   2 +-
 drivers/tty/serial/samsung_tty.c              | 496 +++++++++---
 include/asm-generic/io.h                      |  22 +-
 include/asm-generic/iomap.h                   |   9 +
 include/clocksource/arm_arch_timer.h          |   1 +
 .../interrupt-controller/apple-aic.h          |  15 +
 include/linux/cpuhotplug.h                    |   1 +
 include/linux/io.h                            |   2 +
 include/linux/ioport.h                        |   1 +
 include/linux/irqchip/arm-gic-v3.h            |  56 --
 include/linux/of_address.h                    |   1 +
 include/linux/serial_s3c.h                    |  16 +
 lib/devres.c                                  |  22 +
 41 files changed, 2228 insertions(+), 175 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/apple.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
 create mode 100644 arch/arm64/boot/dts/apple/Makefile
 create mode 100644 arch/arm64/boot/dts/apple/t8103-j274.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8103.dtsi
 create mode 100644 arch/arm64/include/asm/sysreg_apple.h
 create mode 100644 drivers/irqchip/irq-apple-aic.c
 create mode 100644 include/dt-bindings/interrupt-controller/apple-aic.h

--
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 01/27] arm64: Cope with CPUs stuck in VHE mode
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-24 18:05   ` Will Deacon
  2021-03-04 21:38 ` [RFT PATCH v3 02/27] dt-bindings: vendor-prefixes: Add apple prefix Hector Martin
                   ` (26 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

From: Marc Zyngier <maz@kernel.org>

It seems that the CPU known as Apple M1 has the terrible habit
of being stuck with HCR_EL2.E2H==1, in violation of the architecture.

Try and work around this deplorable state of affairs by detecting
the stuck bit early and short-circuit the nVHE dance. It is still
unknown whether there are many more such nuggets to be found...

Reported-by: Hector Martin <marcan@marcan.st>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kernel/head.S     | 33 ++++++++++++++++++++++++++++++---
 arch/arm64/kernel/hyp-stub.S | 28 ++++++++++++++++++++++++----
 2 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 66b0e0b66e31..673002b11865 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -477,14 +477,13 @@ EXPORT_SYMBOL(kimage_vaddr)
  * booted in EL1 or EL2 respectively.
  */
 SYM_FUNC_START(init_kernel_el)
-	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
-	msr	sctlr_el1, x0
-
 	mrs	x0, CurrentEL
 	cmp	x0, #CurrentEL_EL2
 	b.eq	init_el2
 
 SYM_INNER_LABEL(init_el1, SYM_L_LOCAL)
+	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
+	msr	sctlr_el1, x0
 	isb
 	mov_q	x0, INIT_PSTATE_EL1
 	msr	spsr_el1, x0
@@ -504,6 +503,34 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
 	msr	vbar_el2, x0
 	isb
 
+	/*
+	 * Fruity CPUs seem to have HCR_EL2.E2H set to RES1,
+	 * making it impossible to start in nVHE mode. Is that
+	 * compliant with the architecture? Absolutely not!
+	 */
+	mrs	x0, hcr_el2
+	and	x0, x0, #HCR_E2H
+	cbz	x0, 1f
+
+	/* Switching to VHE requires a sane SCTLR_EL1 as a start */
+	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
+	msr_s	SYS_SCTLR_EL12, x0
+
+	/*
+	 * Force an eret into a helper "function", and let it return
+	 * to our original caller... This makes sure that we have
+	 * initialised the basic PSTATE state.
+	 */
+	mov	x0, #INIT_PSTATE_EL2
+	msr	spsr_el1, x0
+	adr_l	x0, stick_to_vhe
+	msr	elr_el1, x0
+	eret
+
+1:
+	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
+	msr	sctlr_el1, x0
+
 	msr	elr_el2, lr
 	mov	w0, #BOOT_CPU_MODE_EL2
 	eret
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 5eccbd62fec8..c7601030ee82 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -27,12 +27,12 @@ SYM_CODE_START(__hyp_stub_vectors)
 	ventry	el2_fiq_invalid			// FIQ EL2t
 	ventry	el2_error_invalid		// Error EL2t
 
-	ventry	el2_sync_invalid		// Synchronous EL2h
+	ventry	elx_sync			// Synchronous EL2h
 	ventry	el2_irq_invalid			// IRQ EL2h
 	ventry	el2_fiq_invalid			// FIQ EL2h
 	ventry	el2_error_invalid		// Error EL2h
 
-	ventry	el1_sync			// Synchronous 64-bit EL1
+	ventry	elx_sync			// Synchronous 64-bit EL1
 	ventry	el1_irq_invalid			// IRQ 64-bit EL1
 	ventry	el1_fiq_invalid			// FIQ 64-bit EL1
 	ventry	el1_error_invalid		// Error 64-bit EL1
@@ -45,7 +45,7 @@ SYM_CODE_END(__hyp_stub_vectors)
 
 	.align 11
 
-SYM_CODE_START_LOCAL(el1_sync)
+SYM_CODE_START_LOCAL(elx_sync)
 	cmp	x0, #HVC_SET_VECTORS
 	b.ne	1f
 	msr	vbar_el2, x1
@@ -71,7 +71,7 @@ SYM_CODE_START_LOCAL(el1_sync)
 
 9:	mov	x0, xzr
 	eret
-SYM_CODE_END(el1_sync)
+SYM_CODE_END(elx_sync)
 
 // nVHE? No way! Give me the real thing!
 SYM_CODE_START_LOCAL(mutate_to_vhe)
@@ -243,3 +243,23 @@ SYM_FUNC_START(switch_to_vhe)
 #endif
 	ret
 SYM_FUNC_END(switch_to_vhe)
+
+SYM_FUNC_START(stick_to_vhe)
+	/*
+	 * Make sure the switch to VHE cannot fail, by overriding the
+	 * override. This is hilarious.
+	 */
+	adr_l	x1, id_aa64mmfr1_override
+	add	x1, x1, #FTR_OVR_MASK_OFFSET
+	dc 	civac, x1
+	dsb	sy
+	isb
+	ldr	x0, [x1]
+	bic	x0, x0, #(0xf << ID_AA64MMFR1_VHE_SHIFT)
+	str	x0, [x1]
+
+	mov	x0, #HVC_VHE_RESTART
+	hvc	#0
+	mov	x0, #BOOT_CPU_MODE_EL2
+	ret
+SYM_FUNC_END(stick_to_vhe)
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 02/27] dt-bindings: vendor-prefixes: Add apple prefix
  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-04 21:38 ` 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
                   ` (25 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This is different from the legacy AAPL prefix used on PPC, but
consensus is that we prefer `apple` for these new platforms.

Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index f6064d84a424..7b59b6d3f526 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -103,6 +103,8 @@ patternProperties:
     description: Anvo-Systems Dresden GmbH
   "^apm,.*":
     description: Applied Micro Circuits Corporation (APM)
+  "^apple,.*":
+    description: Apple Inc.
   "^aptina,.*":
     description: Aptina Imaging
   "^arasan,.*":
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 03/27] dt-bindings: arm: apple: Add bindings for Apple ARM platforms
  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-04 21:38 ` [RFT PATCH v3 02/27] dt-bindings: vendor-prefixes: Add apple prefix Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (24 subsequent siblings)
  27 siblings, 2 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This introduces bindings for all three 2020 Apple M1 devices:

* apple,j274 - Mac mini (M1, 2020)
* apple,j293 - MacBook Pro (13-inch, M1, 2020)
* apple,j313 - MacBook Air (M1, 2020)

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 .../devicetree/bindings/arm/apple.yaml        | 64 +++++++++++++++++++
 MAINTAINERS                                   | 10 +++
 2 files changed, 74 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/apple.yaml

diff --git a/Documentation/devicetree/bindings/arm/apple.yaml b/Documentation/devicetree/bindings/arm/apple.yaml
new file mode 100644
index 000000000000..1e772c85206c
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/apple.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/apple.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple ARM Machine Device Tree Bindings
+
+maintainers:
+  - Hector Martin <marcan@marcan.st>
+
+description: |
+  ARM platforms using SoCs designed by Apple Inc., branded "Apple Silicon".
+
+  This currently includes devices based on the "M1" SoC, starting with the
+  three Mac models released in late 2020:
+
+  - Mac mini (M1, 2020)
+  - MacBook Pro (13-inch, M1, 2020)
+  - MacBook Air (M1, 2020)
+
+  The compatible property should follow this format:
+
+  compatible = "apple,<targettype>", "apple,<socid>", "apple,arm-platform";
+
+  <targettype> represents the board/device and comes from the `target-type`
+  property of the root node of the Apple Device Tree, lowercased. It can be
+  queried on macOS using the following command:
+
+  $ ioreg -d2 -l | grep target-type
+
+  <socid> is the lowercased SoC ID. Apple uses at least *five* different
+  names for their SoCs:
+
+  - Marketing name ("M1")
+  - Internal name ("H13G")
+  - Codename ("Tonga")
+  - SoC ID ("T8103")
+  - Package/IC part number ("APL1102")
+
+  Devicetrees should use the lowercased SoC ID, to avoid confusion if
+  multiple SoCs share the same marketing name. This can be obtained from
+  the `compatible` property of the arm-io node of the Apple Device Tree,
+  which can be queried as follows on macOS:
+
+  $ ioreg -n arm-io | grep compatible
+
+properties:
+  $nodename:
+    const: "/"
+  compatible:
+    oneOf:
+      - description: Apple M1 SoC based platforms
+        items:
+          - enum:
+              - apple,j274 # Mac mini (M1, 2020)
+              - apple,j293 # MacBook Pro (13-inch, M1, 2020)
+              - apple,j313 # MacBook Air (M1, 2020)
+          - const: apple,t8103
+          - const: apple,arm-platform
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index d92f85ca831d..aec14fbd61b8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1637,6 +1637,16 @@ F:	arch/arm/mach-alpine/
 F:	arch/arm64/boot/dts/amazon/
 F:	drivers/*/*alpine*
 
+ARM/APPLE MACHINE SUPPORT
+M:	Hector Martin <marcan@marcan.st>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+W:	https://asahilinux.org
+B:	https://github.com/AsahiLinux/linux/issues
+C:	irc://chat.freenode.net/asahi-dev
+T:	git https://github.com/AsahiLinux/linux.git
+F:	Documentation/devicetree/bindings/arm/apple.yaml
+
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
 M:	Lars Persson <lars.persson@axis.com>
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 04/27] dt-bindings: arm: cpus: Add apple,firestorm & icestorm compatibles
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (2 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 03/27] dt-bindings: arm: apple: Add bindings for Apple ARM platforms Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (23 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

These are the CPU cores in the "Apple Silicon" M1 SoC.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 Documentation/devicetree/bindings/arm/cpus.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml
index 26b886b20b27..c299423dc7cb 100644
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -85,6 +85,8 @@ properties:
 
   compatible:
     enum:
+      - apple,icestorm
+      - apple,firestorm
       - arm,arm710t
       - arm,arm720t
       - arm,arm740t
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 05/27] arm64: cputype: Add CPU implementor & types for the Apple M1 cores
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (3 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 04/27] dt-bindings: arm: cpus: Add apple,firestorm & icestorm compatibles Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (22 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

The implementor will be used to condition the FIQ support quirk.

The specific CPU types are not used at the moment, but let's add them
for documentation purposes.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/include/asm/cputype.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index ef5b040dee44..6231e1f0abe7 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -59,6 +59,7 @@
 #define ARM_CPU_IMP_NVIDIA		0x4E
 #define ARM_CPU_IMP_FUJITSU		0x46
 #define ARM_CPU_IMP_HISI		0x48
+#define ARM_CPU_IMP_APPLE		0x61
 
 #define ARM_CPU_PART_AEM_V8		0xD0F
 #define ARM_CPU_PART_FOUNDATION		0xD00
@@ -99,6 +100,9 @@
 
 #define HISI_CPU_PART_TSV110		0xD01
 
+#define APPLE_CPU_PART_M1_ICESTORM	0x022
+#define APPLE_CPU_PART_M1_FIRESTORM	0x023
+
 #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
 #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
 #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
@@ -127,6 +131,8 @@
 #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL)
 #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)
 #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110)
+#define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)
+#define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)
 
 /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
 #define MIDR_FUJITSU_ERRATUM_010001		MIDR_FUJITSU_A64FX
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (4 preceding siblings ...)
  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-04 21:38 ` Hector Martin
  2021-03-05 10:18   ` Linus Walleij
                     ` (3 more replies)
  2021-03-04 21:38 ` [RFT PATCH v3 07/27] arm64: arch_timer: implement support for interrupt-names Hector Martin
                   ` (21 subsequent siblings)
  27 siblings, 4 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

Not all platforms provide the same set of timers/interrupts, and Linux
only needs one (plus kvm/guest ones); some platforms are working around
this by using dummy fake interrupts. Implementing interrupt-names allows
the devicetree to specify an arbitrary set of available interrupts, so
the timer code can pick the right one.

This also adds the hyp-virt timer/interrupt, which was previously not
expressed in the fixed 4-interrupt form.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 .../devicetree/bindings/timer/arm,arch_timer.yaml  | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
index 2c75105c1398..ebe9b0bebe41 100644
--- a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
+++ b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
@@ -34,11 +34,25 @@ properties:
               - arm,armv8-timer
 
   interrupts:
+    minItems: 1
+    maxItems: 5
     items:
       - description: secure timer irq
       - description: non-secure timer irq
       - description: virtual timer irq
       - description: hypervisor timer irq
+      - description: hypervisor virtual timer irq
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 5
+    items:
+      enum:
+        - phys-secure
+        - phys
+        - virt
+        - hyp-phys
+        - hyp-virt
 
   clock-frequency:
     description: The frequency of the main counter, in Hz. Should be present
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 07/27] arm64: arch_timer: implement support for interrupt-names
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (5 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (20 subsequent siblings)
  27 siblings, 2 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This allows the devicetree to correctly represent the available set of
timers, which varies from device to device, without the need for fake
dummy interrupts for unavailable slots.

Also add the hyp-virt timer/PPI, which is not currently used, but worth
representing.

Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Tony Lindgren <tony@atomide.com>
---
 drivers/clocksource/arm_arch_timer.c | 24 +++++++++++++++++++++---
 include/clocksource/arm_arch_timer.h |  1 +
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index d0177824c518..ee2501a17697 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -63,6 +63,14 @@ struct arch_timer {
 static u32 arch_timer_rate;
 static int arch_timer_ppi[ARCH_TIMER_MAX_TIMER_PPI];
 
+static const char *arch_timer_ppi_names[ARCH_TIMER_MAX_TIMER_PPI] = {
+	[ARCH_TIMER_PHYS_SECURE_PPI]	= "phys-secure",
+	[ARCH_TIMER_PHYS_NONSECURE_PPI]	= "phys",
+	[ARCH_TIMER_VIRT_PPI]		= "virt",
+	[ARCH_TIMER_HYP_PPI]		= "hyp-phys",
+	[ARCH_TIMER_HYP_VIRT_PPI]	= "hyp-virt",
+};
+
 static struct clock_event_device __percpu *arch_timer_evt;
 
 static enum arch_timer_ppi_nr arch_timer_uses_ppi = ARCH_TIMER_VIRT_PPI;
@@ -1280,8 +1288,9 @@ static void __init arch_timer_populate_kvm_info(void)
 
 static int __init arch_timer_of_init(struct device_node *np)
 {
-	int i, ret;
+	int i, irq, ret;
 	u32 rate;
+	bool has_names;
 
 	if (arch_timers_present & ARCH_TIMER_TYPE_CP15) {
 		pr_warn("multiple nodes in dt, skipping\n");
@@ -1289,8 +1298,17 @@ static int __init arch_timer_of_init(struct device_node *np)
 	}
 
 	arch_timers_present |= ARCH_TIMER_TYPE_CP15;
-	for (i = ARCH_TIMER_PHYS_SECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++)
-		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
+
+	has_names = of_property_read_bool(np, "interrupt-names");
+
+	for (i = ARCH_TIMER_PHYS_SECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++) {
+		if (has_names)
+			irq = of_irq_get_byname(np, arch_timer_ppi_names[i]);
+		else
+			irq = of_irq_get(np, i);
+		if (irq > 0)
+			arch_timer_ppi[i] = irq;
+	}
 
 	arch_timer_populate_kvm_info();
 
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index 1d68d5613dae..73c7139c866f 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -32,6 +32,7 @@ enum arch_timer_ppi_nr {
 	ARCH_TIMER_PHYS_NONSECURE_PPI,
 	ARCH_TIMER_VIRT_PPI,
 	ARCH_TIMER_HYP_PPI,
+	ARCH_TIMER_HYP_VIRT_PPI,
 	ARCH_TIMER_MAX_TIMER_PPI
 };
 
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 08/27] asm-generic/io.h:  Add a non-posted variant of ioremap()
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (6 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 07/27] arm64: arch_timer: implement support for interrupt-names Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-05 14:45   ` Andy Shevchenko
                     ` (2 more replies)
  2021-03-04 21:38 ` [RFT PATCH v3 09/27] docs: driver-api: device-io: Document I/O access functions Hector Martin
                   ` (19 subsequent siblings)
  27 siblings, 3 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

ARM64 currently defaults to posted MMIO (nGnRnE), but some devices
require the use of non-posted MMIO (nGnRE). Introduce a new ioremap()
variant to handle this case. ioremap_np() is aliased to ioremap() by
default on arches that do not implement this variant.

sparc64 is the only architecture that needs to be touched directly,
because it includes neither of the generic io.h or iomap.h headers.

This adds the IORESOURCE_MEM_NONPOSTED flag, which maps to this
variant and marks a given resource as requiring non-posted mappings.
This is implemented in the resource system because it is a SoC-level
requirement, so existing drivers do not need special-case code to pick
this ioremap variant.

Then this is implemented in devres by introducing devm_ioremap_np(),
and making devm_ioremap_resource() automatically select this variant
when the resource has the IORESOURCE_MEM_NONPOSTED flag set.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 .../driver-api/driver-model/devres.rst        |  1 +
 arch/sparc/include/asm/io_64.h                |  4 ++++
 include/asm-generic/io.h                      | 22 ++++++++++++++++++-
 include/asm-generic/iomap.h                   |  9 ++++++++
 include/linux/io.h                            |  2 ++
 include/linux/ioport.h                        |  1 +
 lib/devres.c                                  | 22 +++++++++++++++++++
 7 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
index cd8b6e657b94..2f45877a539d 100644
--- a/Documentation/driver-api/driver-model/devres.rst
+++ b/Documentation/driver-api/driver-model/devres.rst
@@ -309,6 +309,7 @@ IOMAP
   devm_ioremap()
   devm_ioremap_uc()
   devm_ioremap_wc()
+  devm_ioremap_np()
   devm_ioremap_resource() : checks resource, requests memory region, ioremaps
   devm_ioremap_resource_wc()
   devm_platform_ioremap_resource() : calls devm_ioremap_resource() for platform device
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index 9bb27e5c22f1..9fbfc9574432 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -409,6 +409,10 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
 #define ioremap_uc(X,Y)			ioremap((X),(Y))
 #define ioremap_wc(X,Y)			ioremap((X),(Y))
 #define ioremap_wt(X,Y)			ioremap((X),(Y))
+static inline void __iomem *ioremap_np(unsigned long offset, unsigned long size)
+{
+	return NULL;
+}
 
 static inline void iounmap(volatile void __iomem *addr)
 {
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index c6af40ce03be..082e0c96db6e 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -942,7 +942,9 @@ static inline void *phys_to_virt(unsigned long address)
  *
  * ioremap_wc() and ioremap_wt() can provide more relaxed caching attributes
  * for specific drivers if the architecture choses to implement them.  If they
- * are not implemented we fall back to plain ioremap.
+ * are not implemented we fall back to plain ioremap. Conversely, ioremap_np()
+ * can provide stricter non-posted write semantics if the architecture
+ * implements them.
  */
 #ifndef CONFIG_MMU
 #ifndef ioremap
@@ -993,6 +995,24 @@ static inline void __iomem *ioremap_uc(phys_addr_t offset, size_t size)
 {
 	return NULL;
 }
+
+/*
+ * ioremap_np needs an explicit architecture implementation, as it
+ * requests stronger semantics than regular ioremap(). Portable drivers
+ * should instead use one of the higher-level abstractions, like
+ * devm_ioremap_resource(), to choose the correct variant for any given
+ * device and bus. Portable drivers with a good reason to want non-posted
+ * write semantics should always provide an ioremap() fallback in case
+ * ioremap_np() is not available.
+ */
+#ifndef ioremap_np
+#define ioremap_np ioremap_np
+static inline void __iomem *ioremap_np(phys_addr_t offset, size_t size)
+{
+	return NULL;
+}
+#endif
+
 #endif
 
 #ifdef CONFIG_HAS_IOPORT_MAP
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index 649224664969..9b3eb6d86200 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -101,6 +101,15 @@ extern void ioport_unmap(void __iomem *);
 #define ioremap_wt ioremap
 #endif
 
+#ifndef ARCH_HAS_IOREMAP_NP
+/* See the comment in asm-generic/io.h about ioremap_np(). */
+#define ioremap_np ioremap_np
+static inline void __iomem *ioremap_np(phys_addr_t offset, size_t size)
+{
+	return NULL;
+}
+#endif
+
 #ifdef CONFIG_PCI
 /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
diff --git a/include/linux/io.h b/include/linux/io.h
index 8394c56babc2..d718354ed3e1 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -68,6 +68,8 @@ void __iomem *devm_ioremap_uc(struct device *dev, resource_size_t offset,
 				   resource_size_t size);
 void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
 				   resource_size_t size);
+void __iomem *devm_ioremap_np(struct device *dev, resource_size_t offset,
+				   resource_size_t size);
 void devm_iounmap(struct device *dev, void __iomem *addr);
 int check_signature(const volatile void __iomem *io_addr,
 			const unsigned char *signature, int length);
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 55de385c839c..1de6c2e40c32 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -108,6 +108,7 @@ struct resource {
 #define IORESOURCE_MEM_32BIT		(3<<3)
 #define IORESOURCE_MEM_SHADOWABLE	(1<<5)	/* dup: IORESOURCE_SHADOWABLE */
 #define IORESOURCE_MEM_EXPANSIONROM	(1<<6)
+#define IORESOURCE_MEM_NONPOSTED	(1<<7)
 
 /* PnP I/O specific bits (IORESOURCE_BITS) */
 #define IORESOURCE_IO_16BIT_ADDR	(1<<0)
diff --git a/lib/devres.c b/lib/devres.c
index 2a4ff5d64288..4679dbb1bf5f 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -10,6 +10,7 @@ enum devm_ioremap_type {
 	DEVM_IOREMAP = 0,
 	DEVM_IOREMAP_UC,
 	DEVM_IOREMAP_WC,
+	DEVM_IOREMAP_NP,
 };
 
 void devm_ioremap_release(struct device *dev, void *res)
@@ -42,6 +43,9 @@ static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
 	case DEVM_IOREMAP_WC:
 		addr = ioremap_wc(offset, size);
 		break;
+	case DEVM_IOREMAP_NP:
+		addr = ioremap_np(offset, size);
+		break;
 	}
 
 	if (addr) {
@@ -98,6 +102,21 @@ void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
 }
 EXPORT_SYMBOL(devm_ioremap_wc);
 
+/**
+ * devm_ioremap_np - Managed ioremap_np()
+ * @dev: Generic device to remap IO address for
+ * @offset: Resource address to map
+ * @size: Size of map
+ *
+ * Managed ioremap_np().  Map is automatically unmapped on driver detach.
+ */
+void __iomem *devm_ioremap_np(struct device *dev, resource_size_t offset,
+			      resource_size_t size)
+{
+	return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_NP);
+}
+EXPORT_SYMBOL(devm_ioremap_np);
+
 /**
  * devm_iounmap - Managed iounmap()
  * @dev: Generic device to unmap for
@@ -128,6 +147,9 @@ __devm_ioremap_resource(struct device *dev, const struct resource *res,
 		return IOMEM_ERR_PTR(-EINVAL);
 	}
 
+	if (type == DEVM_IOREMAP && res->flags & IORESOURCE_MEM_NONPOSTED)
+		type = DEVM_IOREMAP_NP;
+
 	size = resource_size(res);
 
 	if (res->name)
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 09/27] docs: driver-api: device-io: Document I/O access functions
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (7 preceding siblings ...)
  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-04 21:38 ` Hector Martin
  2021-03-05 10:22   ` Linus Walleij
  2021-03-04 21:38 ` [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs Hector Martin
                   ` (18 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel,
	Arnd Bergmann

From: Arnd Bergmann <arnd@arndb.de>

This adds more detailed descriptions of the various read/write
primitives available for use with I/O memory/ports.

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

diff --git a/Documentation/driver-api/device-io.rst b/Documentation/driver-api/device-io.rst
index 764963876d08..b20864b3ddc7 100644
--- a/Documentation/driver-api/device-io.rst
+++ b/Documentation/driver-api/device-io.rst
@@ -146,6 +146,144 @@ There are also equivalents to memcpy. The ins() and
 outs() functions copy bytes, words or longs to the given
 port.
 
+__iomem pointer tokens
+======================
+
+The data type for an MMIO address is an ``__iomem`` qualified pointer, such as
+``void __iomem *reg``. On most architectures it is a regular pointer that
+points to a virtual memory address and can be offset or dereferenced, but in
+portable code, it must only be passed from and to functions that explicitly
+operated on an ``__iomem`` token, in particular the ioremap() and
+readl()/writel() functions. The 'sparse' semantic code checker can be used to
+verify that this is done correctly.
+
+While on most architectures, ioremap() creates a page table entry for an
+uncached virtual address pointing to the physical MMIO address, some
+architectures require special instructions for MMIO, and the ``__iomem`` pointer
+just encodes the physical address or an offsettable cookie that is interpreted
+by readl()/writel().
+
+Differences between I/O access functions
+========================================
+
+readq(), readl(), readw(), readb(), writeq(), writel(), writew(), writeb()
+
+  These are the most generic accessors, providing serialization against other
+  MMIO accesses and DMA accesses as well as fixed endianness for accessing
+  little-endian PCI devices and on-chip peripherals. Portable device drivers
+  should generally use these for any access to ``__iomem`` pointers.
+
+  Note that posted writes are not strictly ordered against a spinlock, see
+  Documentation/driver-api/io_ordering.rst.
+
+readq_relaxed(), readl_relaxed(), readw_relaxed(), readb_relaxed(),
+writeq_relaxed(), writel_relaxed(), writew_relaxed(), writeb_relaxed()
+
+  On architectures that require an expensive barrier for serializing against
+  DMA, these "relaxed" versions of the MMIO accessors only serialize against
+  each other, but contain a less expensive barrier operation. A device driver
+  might use these in a particularly performance sensitive fast path, with a
+  comment that explains why the usage in a specific location is safe without
+  the extra barriers.
+
+  See memory-barriers.txt for a more detailed discussion on the precise ordering
+  guarantees of the non-relaxed and relaxed versions.
+
+ioread64(), ioread32(), ioread16(), ioread8(),
+iowrite64(), iowrite32(), iowrite16(), iowrite8()
+
+  These are an alternative to the normal readl()/writel() functions, with almost
+  identical behavior, but they can also operate on ``__iomem`` tokens returned
+  for mapping PCI I/O space with pci_iomap() or ioport_map(). On architectures
+  that require special instructions for I/O port access, this adds a small
+  overhead for an indirect function call implemented in lib/iomap.c, while on
+  other architectures, these are simply aliases.
+
+ioread64be(), ioread32be(), ioread16be()
+iowrite64be(), iowrite32be(), iowrite16be()
+
+  These behave in the same way as the ioread32()/iowrite32() family, but with
+  reversed byte order, for accessing devices with big-endian MMIO registers.
+  Device drivers that can operate on either big-endian or little-endian
+  registers may have to implement a custom wrapper function that picks one or
+  the other depending on which device was found.
+
+  Note: On some architectures, the normal readl()/writel() functions
+  traditionally assume that devices are the same endianness as the CPU, while
+  using a hardware byte-reverse on the PCI bus when running a big-endian kernel.
+  Drivers that use readl()/writel() this way are generally not portable, but
+  tend to be limited to a particular SoC.
+
+hi_lo_readq(), lo_hi_readq(), hi_lo_readq_relaxed(), lo_hi_readq_relaxed(),
+ioread64_lo_hi(), ioread64_hi_lo(), ioread64be_lo_hi(), ioread64be_hi_lo(),
+hi_lo_writeq(), lo_hi_writeq(), hi_lo_writeq_relaxed(), lo_hi_writeq_relaxed(),
+iowrite64_lo_hi(), iowrite64_hi_lo(), iowrite64be_lo_hi(), iowrite64be_hi_lo()
+
+  Some device drivers have 64-bit registers that cannot be accessed atomically
+  on 32-bit architectures but allow two consecutive 32-bit accesses instead.
+  Since it depends on the particular device which of the two halves has to be
+  accessed first, a helper is provided for each combination of 64-bit accessors
+  with either low/high or high/low word ordering. A device driver must include
+  either <linux/io-64-nonatomic-lo-hi.h> or <linux/io-64-nonatomic-hi-lo.h> to
+  get the function definitions along with helpers that redirect the normal
+  readq()/writeq() to them on architectures that do not provide 64-bit access
+  natively.
+
+__raw_readq(), __raw_readl(), __raw_readw(), __raw_readb(),
+__raw_writeq(), __raw_writel(), __raw_writew(), __raw_writeb()
+
+  These are low-level MMIO accessors without barriers or byteorder changes and
+  architecture specific behavior. Accesses are usually atomic in the sense that
+  a four-byte __raw_readl() does not get split into individual byte loads, but
+  multiple consecutive accesses can be combined on the bus. In portable code, it
+  is only safe to use these to access memory behind a device bus but not MMIO
+  registers, as there are no ordering guarantees with regard to other MMIO
+  accesses or even spinlocks. The byte order is generally the same as for normal
+  memory, so unlike the other functions, these can be used to copy data between
+  kernel memory and device memory.
+
+inl(), inw(), inb(), outl(), outw(), outb()
+
+  PCI I/O port resources traditionally require separate helpers as they are
+  implemented using special instructions on the x86 architecture. On most other
+  architectures, these are mapped to readl()/writel() style accessors
+  internally, usually pointing to a fixed area in virtual memory. Instead of an
+  ``__iomem`` pointer, the address is a 32-bit integer token to identify a port
+  number. PCI requires I/O port access to be non-posted, meaning that an outb()
+  must complete before the following code executes, while a normal writeb() may
+  still be in progress. On architectures that correctly implement this, I/O port
+  access is therefore ordered against spinlocks. Many non-x86 PCI host bridge
+  implementations and CPU architectures however fail to implement non-posted I/O
+  space on PCI, so they can end up being posted on such hardware.
+
+  In some architectures, the I/O port number space has a 1:1 mapping to
+  ``__iomem`` pointers, but this is not recommended and device drivers should
+  not rely on that for portability. Similarly, an I/O port number as described
+  in a PCI base address register may not correspond to the port number as seen
+  by a device driver. Portable drivers need to read the port number for the
+  resource provided by the kernel.
+
+  There are no direct 64-bit I/O port accessors, but pci_iomap() in combination
+  with ioread64/iowrite64 can be used instead.
+
+inl_p(), inw_p(), inb_p(), outl_p(), outw_p(), outb_p()
+
+  On ISA devices that require specific timing, the _p versions of the I/O
+  accessors add a small delay. On architectures that do not have ISA buses,
+  these are aliases to the normal inb/outb helpers.
+
+readsq, readsl, readsw, readsb
+writesq, writesl, writesw, writesb
+ioread64_rep, ioread32_rep, ioread16_rep, ioread8_rep
+iowrite64_rep, iowrite32_rep, iowrite16_rep, iowrite8_rep
+insl, insw, insb, outsl, outsw, outsb
+
+  These are helpers that access the same address multiple times, usually to copy
+  data between kernel memory byte stream and a FIFO buffer. Unlike the normal
+  MMIO accessors, these do not perform a byteswap on big-endian kernels, so the
+  first byte in the FIFO register corresponds to the first byte in the memory
+  buffer regardless of the architecture.
+
 Public Functions Provided
 =========================
 
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (8 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 09/27] docs: driver-api: device-io: Document I/O access functions Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-05 10:25   ` Linus Walleij
  2021-03-04 21:38 ` [RFT PATCH v3 11/27] arm64: Implement ioremap_np() to map MMIO as nGnRnE Hector Martin
                   ` (17 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

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


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 11/27] arm64: Implement ioremap_np() to map MMIO as nGnRnE
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (9 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (16 subsequent siblings)
  27 siblings, 2 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This is used on Apple ARM platforms, which require most MMIO
(except PCI devices) to be mapped as nGnRnE.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/include/asm/io.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 5ea8656a2030..953b8703af60 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -169,6 +169,7 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 
 #define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
+#define ioremap_np(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRnE))
 
 /*
  * PCI configuration space mapping function.
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (10 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 11/27] arm64: Implement ioremap_np() to map MMIO as nGnRnE Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-05 10:28   ` Linus Walleij
                     ` (2 more replies)
  2021-03-04 21:38 ` [RFT PATCH v3 13/27] arm64: Add Apple vendor-specific system registers Hector Martin
                   ` (15 subsequent siblings)
  27 siblings, 3 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This implements the 'nonposted-mmio' and 'posted-mmio' boolean
properties. Placing these properties in a bus marks all child devices as
requiring non-posted or posted MMIO mappings. If no such properties are
found, the default is posted MMIO.

of_mmio_is_nonposted() performs the tree walking to determine if a given
device has requested non-posted MMIO.

of_address_to_resource() uses this to set the IORESOURCE_MEM_NONPOSTED
flag on resources that require non-posted MMIO.

of_iomap() and of_io_request_and_map() then use this flag to pick the
correct ioremap() variant.

This mechanism is currently restricted to Apple ARM platforms, as an
optimization.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/of/address.c       | 72 ++++++++++++++++++++++++++++++++++++--
 include/linux/of_address.h |  1 +
 2 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 73ddf2540f3f..6114dceb1ba6 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -847,6 +847,9 @@ static int __of_address_to_resource(struct device_node *dev,
 		return -EINVAL;
 	memset(r, 0, sizeof(struct resource));
 
+	if (of_mmio_is_nonposted(dev))
+		flags |= IORESOURCE_MEM_NONPOSTED;
+
 	r->start = taddr;
 	r->end = taddr + size - 1;
 	r->flags = flags;
@@ -896,7 +899,10 @@ void __iomem *of_iomap(struct device_node *np, int index)
 	if (of_address_to_resource(np, index, &res))
 		return NULL;
 
-	return ioremap(res.start, resource_size(&res));
+	if (res.flags & IORESOURCE_MEM_NONPOSTED)
+		return ioremap_np(res.start, resource_size(&res));
+	else
+		return ioremap(res.start, resource_size(&res));
 }
 EXPORT_SYMBOL(of_iomap);
 
@@ -928,7 +934,11 @@ void __iomem *of_io_request_and_map(struct device_node *np, int index,
 	if (!request_mem_region(res.start, resource_size(&res), name))
 		return IOMEM_ERR_PTR(-EBUSY);
 
-	mem = ioremap(res.start, resource_size(&res));
+	if (res.flags & IORESOURCE_MEM_NONPOSTED)
+		mem = ioremap_np(res.start, resource_size(&res));
+	else
+		mem = ioremap(res.start, resource_size(&res));
+
 	if (!mem) {
 		release_mem_region(res.start, resource_size(&res));
 		return IOMEM_ERR_PTR(-ENOMEM);
@@ -1094,3 +1104,61 @@ bool of_dma_is_coherent(struct device_node *np)
 	return false;
 }
 EXPORT_SYMBOL_GPL(of_dma_is_coherent);
+
+static bool of_nonposted_mmio_quirk(void)
+{
+	if (IS_ENABLED(CONFIG_ARCH_APPLE)) {
+		/* To save cycles, we cache the result for global "Apple ARM" setting */
+		static int quirk_state = -1;
+
+		/* Make quirk cached */
+		if (quirk_state < 0)
+			quirk_state = of_machine_is_compatible("apple,arm-platform");
+		return !!quirk_state;
+	}
+	return false;
+}
+
+/**
+ * of_mmio_is_nonposted - Check if device uses non-posted MMIO
+ * @np:	device node
+ *
+ * Returns true if the "nonposted-mmio" property was found for
+ * the device's bus or a parent. "posted-mmio" has the opposite
+ * effect, terminating recursion and overriding any
+ * "nonposted-mmio" properties in parent buses.
+ *
+ * Recursion terminates if reach a non-translatable boundary
+ * (a node without a 'ranges' property).
+ *
+ * This is currently only enabled on Apple ARM devices, as an
+ * optimization.
+ */
+bool of_mmio_is_nonposted(struct device_node *np)
+{
+	struct device_node *node;
+	struct device_node *parent;
+
+	if (!of_nonposted_mmio_quirk())
+		return false;
+
+	node = of_get_parent(np);
+
+	while (node) {
+		if (!of_property_read_bool(node, "ranges")) {
+			break;
+		} else if (of_property_read_bool(node, "nonposted-mmio")) {
+			of_node_put(node);
+			return true;
+		} else if (of_property_read_bool(node, "posted-mmio")) {
+			break;
+		}
+		parent = of_get_parent(node);
+		of_node_put(node);
+		node = parent;
+	}
+
+	of_node_put(node);
+	return false;
+}
+EXPORT_SYMBOL_GPL(of_mmio_is_nonposted);
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 88bc943405cd..88f6333fee6c 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -62,6 +62,7 @@ extern struct of_pci_range *of_pci_range_parser_one(
 					struct of_pci_range_parser *parser,
 					struct of_pci_range *range);
 extern bool of_dma_is_coherent(struct device_node *np);
+extern bool of_mmio_is_nonposted(struct device_node *np);
 #else /* CONFIG_OF_ADDRESS */
 static inline void __iomem *of_io_request_and_map(struct device_node *device,
 						  int index, const char *name)
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 13/27] arm64: Add Apple vendor-specific system registers
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (11 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-24 18:38   ` Will Deacon
  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
                   ` (14 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

Apple ARM64 SoCs have a ton of vendor-specific registers we're going to
have to deal with, and those don't really belong in sysreg.h with all
the architectural registers. Make a new home for them, and add some
registers which are useful for early bring-up.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 MAINTAINERS                           |  1 +
 arch/arm64/include/asm/sysreg_apple.h | 69 +++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 arch/arm64/include/asm/sysreg_apple.h

diff --git a/MAINTAINERS b/MAINTAINERS
index aec14fbd61b8..3a352c687d4b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1646,6 +1646,7 @@ B:	https://github.com/AsahiLinux/linux/issues
 C:	irc://chat.freenode.net/asahi-dev
 T:	git https://github.com/AsahiLinux/linux.git
 F:	Documentation/devicetree/bindings/arm/apple.yaml
+F:	arch/arm64/include/asm/sysreg_apple.h
 
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
diff --git a/arch/arm64/include/asm/sysreg_apple.h b/arch/arm64/include/asm/sysreg_apple.h
new file mode 100644
index 000000000000..48347a51d564
--- /dev/null
+++ b/arch/arm64/include/asm/sysreg_apple.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Apple SoC vendor-defined system register definitions
+ *
+ * Copyright The Asahi Linux Contributors
+
+ * This file contains only well-understood registers that are useful to
+ * Linux. If you are looking for things to add here, you should visit:
+ *
+ * https://github.com/AsahiLinux/docs/wiki/HW:ARM-System-Registers
+ */
+
+#ifndef __ASM_SYSREG_APPLE_H
+#define __ASM_SYSREG_APPLE_H
+
+#include <asm/sysreg.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
+
+/*
+ * Keep these registers in encoding order, except for register arrays;
+ * those should be listed in array order starting from the position of
+ * the encoding of the first register.
+ */
+
+#define SYS_APL_PMCR0_EL1		sys_reg(3, 1, 15, 0, 0)
+#define PMCR0_IMODE			GENMASK(10, 8)
+#define PMCR0_IMODE_OFF			0
+#define PMCR0_IMODE_PMI			1
+#define PMCR0_IMODE_AIC			2
+#define PMCR0_IMODE_HALT		3
+#define PMCR0_IMODE_FIQ			4
+#define PMCR0_IACT			BIT(11)
+
+/* IPI request registers */
+#define SYS_APL_IPI_RR_LOCAL_EL1	sys_reg(3, 5, 15, 0, 0)
+#define SYS_APL_IPI_RR_GLOBAL_EL1	sys_reg(3, 5, 15, 0, 1)
+#define IPI_RR_CPU			GENMASK(7, 0)
+/* Cluster only used for the GLOBAL register */
+#define IPI_RR_CLUSTER			GENMASK(23, 16)
+#define IPI_RR_TYPE			GENMASK(29, 28)
+#define IPI_RR_IMMEDIATE		0
+#define IPI_RR_RETRACT			1
+#define IPI_RR_DEFERRED			2
+#define IPI_RR_NOWAKE			3
+
+/* IPI status register */
+#define SYS_APL_IPI_SR_EL1		sys_reg(3, 5, 15, 1, 1)
+#define IPI_SR_PENDING			BIT(0)
+
+/* Guest timer FIQ enable register */
+#define SYS_APL_VM_TMR_FIQ_ENA_EL1	sys_reg(3, 5, 15, 1, 3)
+#define VM_TMR_FIQ_ENABLE_V		BIT(0)
+#define VM_TMR_FIQ_ENABLE_P		BIT(1)
+
+/* Deferred IPI countdown register */
+#define SYS_APL_IPI_CR_EL1		sys_reg(3, 5, 15, 3, 1)
+
+#define SYS_APL_UPMCR0_EL1		sys_reg(3, 7, 15, 0, 4)
+#define UPMCR0_IMODE			GENMASK(18, 16)
+#define UPMCR0_IMODE_OFF		0
+#define UPMCR0_IMODE_AIC		2
+#define UPMCR0_IMODE_HALT		3
+#define UPMCR0_IMODE_FIQ		4
+
+#define SYS_APL_UPMSR_EL1		sys_reg(3, 7, 15, 6, 4)
+#define UPMSR_IACT			BIT(0)
+
+#endif	/* __ASM_SYSREG_APPLE_H */
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 14/27] arm64: move ICH_ sysreg bits from arm-gic-v3.h to sysreg.h
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (12 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 13/27] arm64: Add Apple vendor-specific system registers Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (13 subsequent siblings)
  27 siblings, 2 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

These definitions are in arm-gic-v3.h for historical reasons which no
longer apply. Move them to sysreg.h so the AIC driver can use them, as
it needs to peek into vGIC registers to deal with the GIC maintentance
interrupt.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/include/asm/sysreg.h    | 60 ++++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-v3.h | 56 ----------------------------
 2 files changed, 60 insertions(+), 56 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index dfd4edbfe360..645926490ada 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1024,6 +1024,66 @@
 #define TRFCR_ELx_ExTRE			BIT(1)
 #define TRFCR_ELx_E0TRE			BIT(0)
 
+
+/* GIC Hypervisor interface registers */
+/* ICH_MISR_EL2 bit definitions */
+#define ICH_MISR_EOI		(1 << 0)
+#define ICH_MISR_U		(1 << 1)
+
+/* ICH_LR*_EL2 bit definitions */
+#define ICH_LR_VIRTUAL_ID_MASK	((1ULL << 32) - 1)
+
+#define ICH_LR_EOI		(1ULL << 41)
+#define ICH_LR_GROUP		(1ULL << 60)
+#define ICH_LR_HW		(1ULL << 61)
+#define ICH_LR_STATE		(3ULL << 62)
+#define ICH_LR_PENDING_BIT	(1ULL << 62)
+#define ICH_LR_ACTIVE_BIT	(1ULL << 63)
+#define ICH_LR_PHYS_ID_SHIFT	32
+#define ICH_LR_PHYS_ID_MASK	(0x3ffULL << ICH_LR_PHYS_ID_SHIFT)
+#define ICH_LR_PRIORITY_SHIFT	48
+#define ICH_LR_PRIORITY_MASK	(0xffULL << ICH_LR_PRIORITY_SHIFT)
+
+/* ICH_HCR_EL2 bit definitions */
+#define ICH_HCR_EN		(1 << 0)
+#define ICH_HCR_UIE		(1 << 1)
+#define ICH_HCR_NPIE		(1 << 3)
+#define ICH_HCR_TC		(1 << 10)
+#define ICH_HCR_TALL0		(1 << 11)
+#define ICH_HCR_TALL1		(1 << 12)
+#define ICH_HCR_EOIcount_SHIFT	27
+#define ICH_HCR_EOIcount_MASK	(0x1f << ICH_HCR_EOIcount_SHIFT)
+
+/* ICH_VMCR_EL2 bit definitions */
+#define ICH_VMCR_ACK_CTL_SHIFT	2
+#define ICH_VMCR_ACK_CTL_MASK	(1 << ICH_VMCR_ACK_CTL_SHIFT)
+#define ICH_VMCR_FIQ_EN_SHIFT	3
+#define ICH_VMCR_FIQ_EN_MASK	(1 << ICH_VMCR_FIQ_EN_SHIFT)
+#define ICH_VMCR_CBPR_SHIFT	4
+#define ICH_VMCR_CBPR_MASK	(1 << ICH_VMCR_CBPR_SHIFT)
+#define ICH_VMCR_EOIM_SHIFT	9
+#define ICH_VMCR_EOIM_MASK	(1 << ICH_VMCR_EOIM_SHIFT)
+#define ICH_VMCR_BPR1_SHIFT	18
+#define ICH_VMCR_BPR1_MASK	(7 << ICH_VMCR_BPR1_SHIFT)
+#define ICH_VMCR_BPR0_SHIFT	21
+#define ICH_VMCR_BPR0_MASK	(7 << ICH_VMCR_BPR0_SHIFT)
+#define ICH_VMCR_PMR_SHIFT	24
+#define ICH_VMCR_PMR_MASK	(0xffUL << ICH_VMCR_PMR_SHIFT)
+#define ICH_VMCR_ENG0_SHIFT	0
+#define ICH_VMCR_ENG0_MASK	(1 << ICH_VMCR_ENG0_SHIFT)
+#define ICH_VMCR_ENG1_SHIFT	1
+#define ICH_VMCR_ENG1_MASK	(1 << ICH_VMCR_ENG1_SHIFT)
+
+/* ICH_VTR_EL2 bit definitions */
+#define ICH_VTR_PRI_BITS_SHIFT	29
+#define ICH_VTR_PRI_BITS_MASK	(7 << ICH_VTR_PRI_BITS_SHIFT)
+#define ICH_VTR_ID_BITS_SHIFT	23
+#define ICH_VTR_ID_BITS_MASK	(7 << ICH_VTR_ID_BITS_SHIFT)
+#define ICH_VTR_SEIS_SHIFT	22
+#define ICH_VTR_SEIS_MASK	(1 << ICH_VTR_SEIS_SHIFT)
+#define ICH_VTR_A3V_SHIFT	21
+#define ICH_VTR_A3V_MASK	(1 << ICH_VTR_A3V_SHIFT)
+
 #ifdef __ASSEMBLY__
 
 	.irp	num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index f6d092fdb93d..81cbf85f73de 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -575,67 +575,11 @@
 #define ICC_SRE_EL1_DFB			(1U << 1)
 #define ICC_SRE_EL1_SRE			(1U << 0)
 
-/*
- * Hypervisor interface registers (SRE only)
- */
-#define ICH_LR_VIRTUAL_ID_MASK		((1ULL << 32) - 1)
-
-#define ICH_LR_EOI			(1ULL << 41)
-#define ICH_LR_GROUP			(1ULL << 60)
-#define ICH_LR_HW			(1ULL << 61)
-#define ICH_LR_STATE			(3ULL << 62)
-#define ICH_LR_PENDING_BIT		(1ULL << 62)
-#define ICH_LR_ACTIVE_BIT		(1ULL << 63)
-#define ICH_LR_PHYS_ID_SHIFT		32
-#define ICH_LR_PHYS_ID_MASK		(0x3ffULL << ICH_LR_PHYS_ID_SHIFT)
-#define ICH_LR_PRIORITY_SHIFT		48
-#define ICH_LR_PRIORITY_MASK		(0xffULL << ICH_LR_PRIORITY_SHIFT)
-
 /* These are for GICv2 emulation only */
 #define GICH_LR_VIRTUALID		(0x3ffUL << 0)
 #define GICH_LR_PHYSID_CPUID_SHIFT	(10)
 #define GICH_LR_PHYSID_CPUID		(7UL << GICH_LR_PHYSID_CPUID_SHIFT)
 
-#define ICH_MISR_EOI			(1 << 0)
-#define ICH_MISR_U			(1 << 1)
-
-#define ICH_HCR_EN			(1 << 0)
-#define ICH_HCR_UIE			(1 << 1)
-#define ICH_HCR_NPIE			(1 << 3)
-#define ICH_HCR_TC			(1 << 10)
-#define ICH_HCR_TALL0			(1 << 11)
-#define ICH_HCR_TALL1			(1 << 12)
-#define ICH_HCR_EOIcount_SHIFT		27
-#define ICH_HCR_EOIcount_MASK		(0x1f << ICH_HCR_EOIcount_SHIFT)
-
-#define ICH_VMCR_ACK_CTL_SHIFT		2
-#define ICH_VMCR_ACK_CTL_MASK		(1 << ICH_VMCR_ACK_CTL_SHIFT)
-#define ICH_VMCR_FIQ_EN_SHIFT		3
-#define ICH_VMCR_FIQ_EN_MASK		(1 << ICH_VMCR_FIQ_EN_SHIFT)
-#define ICH_VMCR_CBPR_SHIFT		4
-#define ICH_VMCR_CBPR_MASK		(1 << ICH_VMCR_CBPR_SHIFT)
-#define ICH_VMCR_EOIM_SHIFT		9
-#define ICH_VMCR_EOIM_MASK		(1 << ICH_VMCR_EOIM_SHIFT)
-#define ICH_VMCR_BPR1_SHIFT		18
-#define ICH_VMCR_BPR1_MASK		(7 << ICH_VMCR_BPR1_SHIFT)
-#define ICH_VMCR_BPR0_SHIFT		21
-#define ICH_VMCR_BPR0_MASK		(7 << ICH_VMCR_BPR0_SHIFT)
-#define ICH_VMCR_PMR_SHIFT		24
-#define ICH_VMCR_PMR_MASK		(0xffUL << ICH_VMCR_PMR_SHIFT)
-#define ICH_VMCR_ENG0_SHIFT		0
-#define ICH_VMCR_ENG0_MASK		(1 << ICH_VMCR_ENG0_SHIFT)
-#define ICH_VMCR_ENG1_SHIFT		1
-#define ICH_VMCR_ENG1_MASK		(1 << ICH_VMCR_ENG1_SHIFT)
-
-#define ICH_VTR_PRI_BITS_SHIFT		29
-#define ICH_VTR_PRI_BITS_MASK		(7 << ICH_VTR_PRI_BITS_SHIFT)
-#define ICH_VTR_ID_BITS_SHIFT		23
-#define ICH_VTR_ID_BITS_MASK		(7 << ICH_VTR_ID_BITS_SHIFT)
-#define ICH_VTR_SEIS_SHIFT		22
-#define ICH_VTR_SEIS_MASK		(1 << ICH_VTR_SEIS_SHIFT)
-#define ICH_VTR_A3V_SHIFT		21
-#define ICH_VTR_A3V_MASK		(1 << ICH_VTR_A3V_SHIFT)
-
 #define ICC_IAR1_EL1_SPURIOUS		0x3ff
 
 #define ICC_SRE_EL2_SRE			(1 << 0)
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 15/27] dt-bindings: interrupt-controller: Add DT bindings for apple-aic
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (13 preceding siblings ...)
  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-04 21:38 ` 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
                   ` (12 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

AIC is the Apple Interrupt Controller found on Apple ARM SoCs, such as
the M1.

Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 .../interrupt-controller/apple,aic.yaml       | 88 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 .../interrupt-controller/apple-aic.h          | 15 ++++
 3 files changed, 104 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
 create mode 100644 include/dt-bindings/interrupt-controller/apple-aic.h

diff --git a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
new file mode 100644
index 000000000000..cf6c091a07b1
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/apple,aic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple Interrupt Controller
+
+maintainers:
+  - Hector Martin <marcan@marcan.st>
+
+description: |
+  The Apple Interrupt Controller is a simple interrupt controller present on
+  Apple ARM SoC platforms, including various iPhone and iPad devices and the
+  "Apple Silicon" Macs.
+
+  It provides the following features:
+
+  - Level-triggered hardware IRQs wired to SoC blocks
+    - Single mask bit per IRQ
+    - Per-IRQ affinity setting
+    - Automatic masking on event delivery (auto-ack)
+    - Software triggering (ORed with hw line)
+  - 2 per-CPU IPIs (meant as "self" and "other", but they are interchangeable
+    if not symmetric)
+  - Automatic prioritization (single event/ack register per CPU, lower IRQs =
+    higher priority)
+  - Automatic masking on ack
+  - Default "this CPU" register view and explicit per-CPU views
+
+  This device also represents the FIQ interrupt sources on platforms using AIC,
+  which do not go through a discrete interrupt controller.
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: apple,t8103-aic
+      - const: apple,aic
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    const: 3
+    description: |
+      The 1st cell contains the interrupt type:
+        - 0: Hardware IRQ
+        - 1: FIQ
+
+      The 2nd cell contains the interrupt number.
+        - HW IRQs: interrupt number
+        - FIQs:
+          - 0: physical HV timer
+          - 1: virtual HV timer
+          - 2: physical guest timer
+          - 3: virtual guest timer
+
+      The 3rd cell contains the interrupt flags. This is normally
+      IRQ_TYPE_LEVEL_HIGH (4).
+
+  reg:
+    description: |
+      Specifies base physical address and size of the AIC registers.
+    maxItems: 1
+
+required:
+  - compatible
+  - '#interrupt-cells'
+  - interrupt-controller
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        aic: interrupt-controller@23b100000 {
+            compatible = "apple,t8103-aic", "apple,aic";
+            #interrupt-cells = <3>;
+            interrupt-controller;
+            reg = <0x2 0x3b100000 0x0 0x8000>;
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 3a352c687d4b..744e086d28cd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1646,6 +1646,7 @@ B:	https://github.com/AsahiLinux/linux/issues
 C:	irc://chat.freenode.net/asahi-dev
 T:	git https://github.com/AsahiLinux/linux.git
 F:	Documentation/devicetree/bindings/arm/apple.yaml
+F:	Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
 F:	arch/arm64/include/asm/sysreg_apple.h
 
 ARM/ARTPEC MACHINE SUPPORT
diff --git a/include/dt-bindings/interrupt-controller/apple-aic.h b/include/dt-bindings/interrupt-controller/apple-aic.h
new file mode 100644
index 000000000000..9ac56a7e6d3f
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/apple-aic.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define AIC_IRQ	0
+#define AIC_FIQ	1
+
+#define AIC_TMR_HV_PHYS		0
+#define AIC_TMR_HV_VIRT		1
+#define AIC_TMR_GUEST_PHYS	2
+#define AIC_TMR_GUEST_VIRT	3
+
+#endif
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (14 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 15/27] dt-bindings: interrupt-controller: Add DT bindings for apple-aic Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-05 15:05   ` Andy Shevchenko
                     ` (2 more replies)
  2021-03-04 21:38 ` [RFT PATCH v3 17/27] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE Hector Martin
                   ` (11 subsequent siblings)
  27 siblings, 3 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This is the root interrupt controller used on Apple ARM SoCs such as the
M1. This irqchip driver performs multiple functions:

* Handles both IRQs and FIQs

* Drives the AIC peripheral itself (which handles IRQs)

* Dispatches FIQs to downstream hard-wired clients (currently the ARM
  timer).

* Implements a virtual IPI multiplexer to funnel multiple Linux IPIs
  into a single hardware IPI

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 MAINTAINERS                     |   2 +
 drivers/irqchip/Kconfig         |   8 +
 drivers/irqchip/Makefile        |   1 +
 drivers/irqchip/irq-apple-aic.c | 710 ++++++++++++++++++++++++++++++++
 include/linux/cpuhotplug.h      |   1 +
 5 files changed, 722 insertions(+)
 create mode 100644 drivers/irqchip/irq-apple-aic.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 744e086d28cd..28bd46f4f7a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1648,6 +1648,8 @@ T:	git https://github.com/AsahiLinux/linux.git
 F:	Documentation/devicetree/bindings/arm/apple.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
 F:	arch/arm64/include/asm/sysreg_apple.h
+F:	drivers/irqchip/irq-apple-aic.c
+F:	include/dt-bindings/interrupt-controller/apple-aic.h
 
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 15536e321df5..d3a14f304ec8 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -577,4 +577,12 @@ config MST_IRQ
 	help
 	  Support MStar Interrupt Controller.
 
+config APPLE_AIC
+	bool "Apple Interrupt Controller (AIC)"
+	depends on ARM64
+	default ARCH_APPLE
+	help
+	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
+	  such as the M1.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c59b95a0532c..eb6a515f0f64 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -113,3 +113,4 @@ obj-$(CONFIG_LOONGSON_PCH_MSI)		+= irq-loongson-pch-msi.o
 obj-$(CONFIG_MST_IRQ)			+= irq-mst-intc.o
 obj-$(CONFIG_SL28CPLD_INTC)		+= irq-sl28cpld.o
 obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
+obj-$(CONFIG_APPLE_AIC)			+= irq-apple-aic.o
diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
new file mode 100644
index 000000000000..ddc0856f36a5
--- /dev/null
+++ b/drivers/irqchip/irq-apple-aic.c
@@ -0,0 +1,710 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright The Asahi Linux Contributors
+ *
+ * Based on irq-lpc32xx:
+ *   Copyright 2015-2016 Vladimir Zapolskiy <vz@mleia.com>
+ * Based on irq-bcm2836:
+ *   Copyright 2015 Broadcom
+ */
+
+/*
+ * AIC is a fairly simple interrupt controller with the following features:
+ *
+ * - 896 level-triggered hardware IRQs
+ *   - Single mask bit per IRQ
+ *   - Per-IRQ affinity setting
+ *   - Automatic masking on event delivery (auto-ack)
+ *   - Software triggering (ORed with hw line)
+ * - 2 per-CPU IPIs (meant as "self" and "other", but they are
+ *   interchangeable if not symmetric)
+ * - Automatic prioritization (single event/ack register per CPU, lower IRQs =
+ *   higher priority)
+ * - Automatic masking on ack
+ * - Default "this CPU" register view and explicit per-CPU views
+ *
+ * In addition, this driver also handles FIQs, as these are routed to the same
+ * IRQ vector. These are used for Fast IPIs (TODO), the ARMv8 timer IRQs, and
+ * performance counters (TODO).
+ *
+ * Implementation notes:
+ *
+ * - This driver creates two IRQ domains, one for HW IRQs and internal FIQs,
+ *   and one for IPIs.
+ * - Since Linux needs more than 2 IPIs, we implement a software IRQ controller
+ *   and funnel all IPIs into one per-CPU IPI (the second "self" IPI is unused).
+ * - FIQ hwirq numbers are assigned after true hwirqs, and are per-cpu.
+ * - DT bindings use 3-cell form (like GIC):
+ *   - <0 nr flags> - hwirq #nr
+ *   - <1 nr flags> - FIQ #nr
+ *     - nr=0  Physical HV timer
+ *     - nr=1  Virtual HV timer
+ *     - nr=2  Physical guest timer
+ *     - nr=3  Virtual guest timer
+ *
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/bits.h>
+#include <linux/bitfield.h>
+#include <linux/cpuhotplug.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <asm/exception.h>
+#include <asm/sysreg.h>
+#include <asm/sysreg_apple.h>
+
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+
+#define AIC_INFO		0x0004
+#define AIC_INFO_NR_HW		GENMASK(15, 0)
+
+#define AIC_CONFIG		0x0010
+
+#define AIC_WHOAMI		0x2000
+#define AIC_EVENT		0x2004
+#define AIC_EVENT_TYPE		GENMASK(31, 16)
+#define AIC_EVENT_NUM		GENMASK(15, 0)
+
+#define AIC_EVENT_TYPE_HW	1
+#define AIC_EVENT_TYPE_IPI	4
+#define AIC_EVENT_IPI_OTHER	1
+#define AIC_EVENT_IPI_SELF	2
+
+#define AIC_IPI_SEND		0x2008
+#define AIC_IPI_ACK		0x200c
+#define AIC_IPI_MASK_SET	0x2024
+#define AIC_IPI_MASK_CLR	0x2028
+
+#define AIC_IPI_SEND_CPU(cpu)	BIT(cpu)
+
+#define AIC_IPI_OTHER		BIT(0)
+#define AIC_IPI_SELF		BIT(31)
+
+#define AIC_TARGET_CPU		0x3000
+#define AIC_SW_SET		0x4000
+#define AIC_SW_CLR		0x4080
+#define AIC_MASK_SET		0x4100
+#define AIC_MASK_CLR		0x4180
+
+#define AIC_CPU_IPI_SET(cpu)	(0x5008 + ((cpu) << 7))
+#define AIC_CPU_IPI_CLR(cpu)	(0x500c + ((cpu) << 7))
+#define AIC_CPU_IPI_MASK_SET(cpu) (0x5024 + ((cpu) << 7))
+#define AIC_CPU_IPI_MASK_CLR(cpu) (0x5028 + ((cpu) << 7))
+
+#define MASK_REG(x)		(4 * ((x) >> 5))
+#define MASK_BIT(x)		BIT((x) & 0x1f)
+
+#define AIC_NR_FIQ		4
+#define AIC_NR_SWIPI		32
+
+/*
+ * Max 31 bits in IPI SEND register (top bit is self).
+ * >=32-core chips will need code changes anyway.
+ */
+#define AIC_MAX_CPUS		31
+
+struct aic_irq_chip {
+	void __iomem *base;
+	struct irq_domain *hw_domain;
+	struct irq_domain *ipi_domain;
+	int nr_hw;
+	int ipi_hwirq;
+};
+
+static atomic_t aic_vipi_flag[AIC_MAX_CPUS];
+static atomic_t aic_vipi_enable[AIC_MAX_CPUS];
+
+static struct aic_irq_chip *aic_irqc;
+
+static void aic_handle_ipi(struct pt_regs *regs);
+
+static u32 aic_ic_read(struct aic_irq_chip *ic, u32 reg)
+{
+	return readl_relaxed(ic->base + reg);
+}
+
+static void aic_ic_write(struct aic_irq_chip *ic, u32 reg, u32 val)
+{
+	writel_relaxed(val, ic->base + reg);
+}
+
+/*
+ * IRQ irqchip
+ */
+
+static void aic_irq_mask(struct irq_data *d)
+{
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+
+	aic_ic_write(ic, AIC_MASK_SET + MASK_REG(d->hwirq),
+		     MASK_BIT(d->hwirq));
+}
+
+static void aic_irq_unmask(struct irq_data *d)
+{
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+
+	aic_ic_write(ic, AIC_MASK_CLR + MASK_REG(d->hwirq),
+		     MASK_BIT(d->hwirq));
+}
+
+static void aic_irq_eoi(struct irq_data *d)
+{
+	/*
+	 * Reading the interrupt reason automatically acknowledges and masks
+	 * the IRQ, so we just unmask it here if needed.
+	 */
+	if (!irqd_irq_disabled(d) && !irqd_irq_masked(d))
+		aic_irq_unmask(d);
+}
+
+static void __exception_irq_entry aic_handle_irq(struct pt_regs *regs)
+{
+	struct aic_irq_chip *ic = aic_irqc;
+	u32 event, type, irq;
+
+	do {
+		/*
+		 * We cannot use a relaxed read here, as DMA needs to be
+		 * ordered with respect to the IRQ firing.
+		 */
+		event = readl(ic->base + AIC_EVENT);
+		type = FIELD_GET(AIC_EVENT_TYPE, event);
+		irq = FIELD_GET(AIC_EVENT_NUM, event);
+
+		if (type == AIC_EVENT_TYPE_HW)
+			handle_domain_irq(aic_irqc->hw_domain, irq, regs);
+		else if (type == AIC_EVENT_TYPE_IPI && irq == 1)
+			aic_handle_ipi(regs);
+		else if (event != 0)
+			pr_err("Unknown IRQ event %d, %d\n", type, irq);
+	} while (event);
+
+	/*
+	 * vGIC maintenance interrupts end up here too, so we need to check
+	 * for them separately. Just report and disable vGIC for now, until
+	 * we implement this properly.
+	 */
+	if ((read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EN) &&
+		read_sysreg_s(SYS_ICH_MISR_EL2) != 0) {
+		pr_err("vGIC IRQ fired, disabling.\n");
+		sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EN, 0);
+	}
+}
+
+static int aic_irq_set_affinity(struct irq_data *d,
+				const struct cpumask *mask_val, bool force)
+{
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+	int cpu;
+
+	if (hwirq > ic->nr_hw)
+		return -EINVAL;
+
+	if (force)
+		cpu = cpumask_first(mask_val);
+	else
+		cpu = cpumask_any_and(mask_val, cpu_online_mask);
+
+	aic_ic_write(ic, AIC_TARGET_CPU + hwirq * 4, BIT(cpu));
+	irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
+	return IRQ_SET_MASK_OK;
+}
+
+static int aic_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL;
+}
+
+static struct irq_chip aic_chip = {
+	.name = "AIC",
+	.irq_mask = aic_irq_mask,
+	.irq_unmask = aic_irq_unmask,
+	.irq_eoi = aic_irq_eoi,
+	.irq_set_affinity = aic_irq_set_affinity,
+	.irq_set_type = aic_irq_set_type,
+};
+
+/*
+ * FIQ irqchip
+ */
+
+static void aic_fiq_mask(struct irq_data *d)
+{
+	/* Only the guest timers have real mask bits, unfortunately. */
+	switch (d->hwirq) {
+	case AIC_TMR_GUEST_PHYS:
+		sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, VM_TMR_FIQ_ENABLE_P, 0);
+		break;
+	case AIC_TMR_GUEST_VIRT:
+		sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, VM_TMR_FIQ_ENABLE_V, 0);
+		break;
+	}
+}
+
+static void aic_fiq_unmask(struct irq_data *d)
+{
+	switch (d->hwirq) {
+	case AIC_TMR_GUEST_PHYS:
+		sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, 0, VM_TMR_FIQ_ENABLE_P);
+		break;
+	case AIC_TMR_GUEST_VIRT:
+		sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, 0, VM_TMR_FIQ_ENABLE_V);
+		break;
+	}
+}
+
+static void aic_fiq_eoi(struct irq_data *d)
+{
+	/* We mask to ack (where we can), so we need to unmask at EOI. */
+	if (!irqd_irq_disabled(d) && !irqd_irq_masked(d))
+		aic_fiq_unmask(d);
+}
+
+#define TIMER_FIRING(x)                                                        \
+	(((x) & (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_MASK |            \
+		 ARCH_TIMER_CTRL_IT_STAT)) ==                                  \
+	 (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT))
+
+static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs)
+{
+	/*
+	 * It would be really nice if we had a system register that lets us get
+	 * the FIQ source state without having to peek down into sources...
+	 * but such a register does not seem to exist.
+	 *
+	 * So, we have these potential sources to test for:
+	 *  - Fast IPIs (not yet used)
+	 *  - The 4 timers (CNTP, CNTV for each of HV and guest)
+	 *  - Per-core PMCs (not yet supported)
+	 *  - Per-cluster uncore PMCs (not yet supported)
+	 *
+	 * Since not dealing with any of these results in a FIQ storm,
+	 * we check for everything here, even things we don't support yet.
+	 */
+
+	if (read_sysreg_s(SYS_APL_IPI_SR_EL1) & IPI_SR_PENDING) {
+		pr_warn("Fast IPI fired. Acking.\n");
+		write_sysreg_s(IPI_SR_PENDING, SYS_APL_IPI_SR_EL1);
+	}
+
+	if (TIMER_FIRING(read_sysreg(cntp_ctl_el0)))
+		handle_domain_irq(aic_irqc->hw_domain,
+				  aic_irqc->nr_hw + AIC_TMR_HV_PHYS, regs);
+
+	if (TIMER_FIRING(read_sysreg(cntv_ctl_el0)))
+		handle_domain_irq(aic_irqc->hw_domain,
+				  aic_irqc->nr_hw + AIC_TMR_HV_VIRT, regs);
+
+	if (TIMER_FIRING(read_sysreg_s(SYS_CNTP_CTL_EL02)))
+		handle_domain_irq(aic_irqc->hw_domain,
+				  aic_irqc->nr_hw + AIC_TMR_GUEST_PHYS, regs);
+
+	if (TIMER_FIRING(read_sysreg_s(SYS_CNTV_CTL_EL02)))
+		handle_domain_irq(aic_irqc->hw_domain,
+				  aic_irqc->nr_hw + AIC_TMR_GUEST_VIRT, regs);
+
+	if ((read_sysreg_s(SYS_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT))
+			== (FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) {
+		/*
+		 * Not supported yet, let's figure out how to handle this when
+		 * we implement these proprietary performance counters. For now,
+		 * just mask it and move on.
+		 */
+		pr_warn("PMC FIQ fired. Masking.\n");
+		sysreg_clear_set_s(SYS_APL_PMCR0_EL1, PMCR0_IMODE | PMCR0_IACT,
+				   FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_OFF));
+	}
+
+	if (FIELD_GET(UPMCR0_IMODE, read_sysreg_s(SYS_APL_UPMCR0_EL1)) == UPMCR0_IMODE_FIQ &&
+			(read_sysreg_s(SYS_APL_UPMSR_EL1) & UPMSR_IACT)) {
+		/* Same story with uncore PMCs */
+		pr_warn("Uncore PMC FIQ fired. Masking.\n");
+		sysreg_clear_set_s(SYS_APL_UPMCR0_EL1, UPMCR0_IMODE,
+				   FIELD_PREP(UPMCR0_IMODE, UPMCR0_IMODE_OFF));
+	}
+}
+
+static struct irq_chip fiq_chip = {
+	.name = "AIC-FIQ",
+	.irq_mask = aic_fiq_mask,
+	.irq_unmask = aic_fiq_unmask,
+	.irq_ack = aic_fiq_mask,
+	.irq_eoi = aic_fiq_eoi,
+	.irq_set_type = aic_irq_set_type,
+};
+
+/*
+ * Main IRQ domain
+ */
+
+static int aic_irq_domain_map(struct irq_domain *id, unsigned int irq,
+			      irq_hw_number_t hw)
+{
+	struct aic_irq_chip *ic = id->host_data;
+
+	if (hw < ic->nr_hw) {
+		irq_domain_set_info(id, irq, hw, &aic_chip, id->host_data,
+				    handle_fasteoi_irq, NULL, NULL);
+		irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
+	} else {
+		irq_set_percpu_devid(irq);
+		irq_domain_set_info(id, irq, hw, &fiq_chip, id->host_data,
+				    handle_percpu_devid_irq, NULL, NULL);
+	}
+
+	return 0;
+}
+
+static int aic_irq_domain_translate(struct irq_domain *id,
+				    struct irq_fwspec *fwspec,
+				    unsigned long *hwirq,
+				    unsigned int *type)
+{
+	struct aic_irq_chip *ic = id->host_data;
+
+	if (fwspec->param_count != 3 || !is_of_node(fwspec->fwnode))
+		return -EINVAL;
+
+	switch (fwspec->param[0]) {
+	case AIC_IRQ:
+		if (fwspec->param[1] >= ic->nr_hw)
+			return -EINVAL;
+		*hwirq = 0;
+		break;
+	case AIC_FIQ:
+		if (fwspec->param[1] >= AIC_NR_FIQ)
+			return -EINVAL;
+		*hwirq = ic->nr_hw;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	*hwirq += fwspec->param[1];
+	*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
+
+	return 0;
+}
+
+static int aic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				unsigned int nr_irqs, void *arg)
+{
+	unsigned int type = IRQ_TYPE_NONE;
+	struct irq_fwspec *fwspec = arg;
+	irq_hw_number_t hwirq;
+	int i, ret;
+
+	ret = aic_irq_domain_translate(domain, fwspec, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nr_irqs; i++) {
+		ret = aic_irq_domain_map(domain, virq + i, hwirq + i);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void aic_irq_domain_free(struct irq_domain *domain, unsigned int virq,
+				unsigned int nr_irqs)
+{
+	int i;
+
+	for (i = 0; i < nr_irqs; i++) {
+		struct irq_data *d = irq_domain_get_irq_data(domain, virq + i);
+
+		irq_set_handler(virq + i, NULL);
+		irq_domain_reset_irq_data(d);
+	}
+}
+
+static const struct irq_domain_ops aic_irq_domain_ops = {
+	.translate	= aic_irq_domain_translate,
+	.alloc		= aic_irq_domain_alloc,
+	.free		= aic_irq_domain_free,
+};
+
+/*
+ * IPI irqchip
+ */
+
+static void aic_ipi_mask(struct irq_data *d)
+{
+	u32 irq_bit = BIT(irqd_to_hwirq(d));
+	int this_cpu = smp_processor_id();
+
+	/* No specific ordering requirements needed here. */
+	atomic_andnot(irq_bit, &aic_vipi_enable[this_cpu]);
+}
+
+static void aic_ipi_unmask(struct irq_data *d)
+{
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+	u32 irq_bit = BIT(irqd_to_hwirq(d));
+	int this_cpu = smp_processor_id();
+
+	/*
+	 * This must complete before the atomic_read_acquire() below to avoid
+	 * racing aic_ipi_send_mask(). Use a dummy fetch op with release
+	 * semantics for this. This is arch-specific: ARMv8 B2.3.3 specifies
+	 * that writes with Release semantics are Barrier-ordered-before reads
+	 * with Acquire semantics, even though the Linux arch-independent
+	 * definition of these atomic ops does not.
+	 */
+	(void)atomic_fetch_or_release(irq_bit, &aic_vipi_enable[this_cpu]);
+
+	/*
+	 * If a pending vIPI was unmasked, raise a HW IPI to ourselves.
+	 * No barriers needed here since this is a self-IPI.
+	 */
+	if (atomic_read_acquire(&aic_vipi_flag[this_cpu]) & irq_bit)
+		aic_ic_write(ic, AIC_IPI_SEND, AIC_IPI_SEND_CPU(this_cpu));
+}
+
+static void aic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask)
+{
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+	u32 irq_bit = BIT(irqd_to_hwirq(d));
+	u32 send = 0;
+	int cpu;
+	unsigned long pending;
+
+	for_each_cpu(cpu, mask) {
+		/*
+		 * This sequence is the mirror of the one in aic_ipi_unmask();
+		 * see the comment there. Additionally, release semantics
+		 * ensure that the vIPI flag set is ordered after any shared
+		 * memory accesses that precede it. This therefore also pairs
+		 * with the atomic_fetch_andnot in aic_handle_ipi().
+		 */
+		pending = atomic_fetch_or_release(irq_bit, &aic_vipi_flag[cpu]);
+
+		if (!(pending & irq_bit) && (atomic_read_acquire(&aic_vipi_enable[cpu]) & irq_bit))
+			send |= AIC_IPI_SEND_CPU(cpu);
+	}
+
+	/*
+	 * The flag writes must complete before the physical IPI is issued
+	 * to another CPU. This is implied by the control dependency on
+	 * the result of atomic_read_acquire() above, which is itself
+	 * already ordered after the vIPI flag write.
+	 */
+	if (send)
+		aic_ic_write(ic, AIC_IPI_SEND, send);
+}
+
+static struct irq_chip ipi_chip = {
+	.name = "AIC-IPI",
+	.irq_mask = aic_ipi_mask,
+	.irq_unmask = aic_ipi_unmask,
+	.ipi_send_mask = aic_ipi_send_mask,
+};
+
+/*
+ * IPI IRQ domain
+ */
+
+static void aic_handle_ipi(struct pt_regs *regs)
+{
+	int this_cpu = smp_processor_id();
+	int i;
+	unsigned long enabled, firing;
+
+	/*
+	 * Ack the IPI. We need to order this after the AIC event read, but
+	 * that is enforced by normal MMIO ordering guarantees.
+	 */
+	aic_ic_write(aic_irqc, AIC_IPI_ACK, AIC_IPI_OTHER);
+
+	/*
+	 * The mask read does not need to be ordered. Only we can change
+	 * our own mask anyway, so no races are possible here, as long as
+	 * we are properly in the interrupt handler (which is covered by
+	 * the barrier that is part of the top-level AIC handler's readl()).
+	 */
+	enabled = atomic_read(&aic_vipi_enable[this_cpu]);
+
+	/*
+	 * Clear the IPIs we are about to handle. This pairs with the
+	 * atomic_fetch_or_release() in aic_ipi_send_mask(), and needs to be
+	 * ordered after the aic_ic_write() above (to avoid dropping vIPIs) and
+	 * before IPI handling code (to avoid races handling vIPIs before they
+	 * are signaled). The former is taken care of by the release semantics
+	 * of the write portion, while the latter is taken care of by the
+	 * acquire semantics of the read portion.
+	 */
+	firing = atomic_fetch_andnot(enabled, &aic_vipi_flag[this_cpu]) & enabled;
+
+	for_each_set_bit(i, &firing, AIC_NR_SWIPI) {
+		handle_domain_irq(aic_irqc->ipi_domain, i, regs);
+	}
+
+	/*
+	 * No ordering needed here; at worst this just changes the timing of
+	 * when the next IPI will be delivered.
+	 */
+	aic_ic_write(aic_irqc, AIC_IPI_MASK_CLR, AIC_IPI_OTHER);
+}
+
+static int aic_ipi_alloc(struct irq_domain *d, unsigned int virq,
+			 unsigned int nr_irqs, void *args)
+{
+	int i;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_set_percpu_devid(virq + i);
+		irq_domain_set_info(d, virq + i, i, &ipi_chip, d->host_data,
+				    handle_percpu_devid_irq, NULL, NULL);
+	}
+
+	return 0;
+}
+
+static void aic_ipi_free(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs)
+{
+	/* Not freeing IPIs */
+}
+
+static const struct irq_domain_ops aic_ipi_domain_ops = {
+	.alloc = aic_ipi_alloc,
+	.free = aic_ipi_free,
+};
+
+static int aic_init_smp(struct aic_irq_chip *irqc, struct device_node *node)
+{
+	int base_ipi;
+
+	irqc->ipi_domain = irq_domain_create_linear(irqc->hw_domain->fwnode, AIC_NR_SWIPI,
+						    &aic_ipi_domain_ops, irqc);
+	if (WARN_ON(!irqc->ipi_domain))
+		return -ENODEV;
+
+	irqc->ipi_domain->flags |= IRQ_DOMAIN_FLAG_IPI_SINGLE;
+	irq_domain_update_bus_token(irqc->ipi_domain, DOMAIN_BUS_IPI);
+
+	base_ipi = __irq_domain_alloc_irqs(irqc->ipi_domain, -1, AIC_NR_SWIPI,
+					   NUMA_NO_NODE, NULL, false, NULL);
+
+	if (WARN_ON(!base_ipi)) {
+		irq_domain_remove(irqc->ipi_domain);
+		return -ENODEV;
+	}
+
+	set_smp_ipi_range(base_ipi, AIC_NR_SWIPI);
+
+	return 0;
+}
+
+static int aic_init_cpu(unsigned int cpu)
+{
+	/* Mask all hard-wired per-CPU IRQ/FIQ sources */
+
+	/* vGIC maintenance IRQ */
+	sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EN, 0);
+
+	/* Pending Fast IPI FIQs */
+	write_sysreg_s(IPI_SR_PENDING, SYS_APL_IPI_SR_EL1);
+
+	/* Timer FIQs */
+	sysreg_clear_set(cntp_ctl_el0, 0, ARCH_TIMER_CTRL_IT_MASK);
+	sysreg_clear_set(cntv_ctl_el0, 0, ARCH_TIMER_CTRL_IT_MASK);
+	sysreg_clear_set_s(SYS_CNTP_CTL_EL02, 0, ARCH_TIMER_CTRL_IT_MASK);
+	sysreg_clear_set_s(SYS_CNTV_CTL_EL02, 0, ARCH_TIMER_CTRL_IT_MASK);
+
+	/* PMC FIQ */
+	sysreg_clear_set_s(SYS_APL_PMCR0_EL1, PMCR0_IMODE | PMCR0_IACT,
+			   FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_OFF));
+
+	/* Uncore PMC FIQ */
+	sysreg_clear_set_s(SYS_APL_UPMCR0_EL1, UPMCR0_IMODE,
+			   FIELD_PREP(UPMCR0_IMODE, UPMCR0_IMODE_OFF));
+
+	/*
+	 * Make sure the kernel's idea of logical CPU order is the same as AIC's
+	 * If we ever end up with a mismatch here, we will have to introduce
+	 * a mapping table similar to what other irqchip drivers do.
+	 */
+	WARN_ON(aic_ic_read(aic_irqc, AIC_WHOAMI) != smp_processor_id());
+
+	/*
+	 * Always keep IPIs unmasked at the hardware level (except auto-masking
+	 * by AIC during processing). We manage masks at the vIPI level.
+	 */
+	aic_ic_write(aic_irqc, AIC_IPI_ACK, AIC_IPI_SELF | AIC_IPI_OTHER);
+	aic_ic_write(aic_irqc, AIC_IPI_MASK_SET, AIC_IPI_SELF);
+	aic_ic_write(aic_irqc, AIC_IPI_MASK_CLR, AIC_IPI_OTHER);
+
+	return 0;
+
+}
+
+static int __init aic_of_ic_init(struct device_node *node, struct device_node *parent)
+{
+	int i;
+	void __iomem *regs;
+	u32 info;
+	struct aic_irq_chip *irqc;
+
+	regs = of_iomap(node, 0);
+	if (WARN_ON(!regs))
+		return -EIO;
+
+	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
+	if (!irqc)
+		return -ENOMEM;
+
+	aic_irqc = irqc;
+	irqc->base = regs;
+
+	info = aic_ic_read(irqc, AIC_INFO);
+	irqc->nr_hw = FIELD_GET(AIC_INFO_NR_HW, info);
+
+	irqc->hw_domain = irq_domain_create_linear(of_node_to_fwnode(node),
+						   irqc->nr_hw + AIC_NR_FIQ,
+						   &aic_irq_domain_ops, irqc);
+	if (WARN_ON(!irqc->hw_domain)) {
+		iounmap(irqc->base);
+		kfree(irqc);
+		return -ENODEV;
+	}
+
+	irq_domain_update_bus_token(irqc->hw_domain, DOMAIN_BUS_WIRED);
+
+	if (aic_init_smp(irqc, node)) {
+		irq_domain_remove(irqc->hw_domain);
+		iounmap(irqc->base);
+		kfree(irqc);
+		return -ENODEV;
+	}
+
+	set_handle_irq(aic_handle_irq);
+	set_handle_fiq(aic_handle_fiq);
+
+	for (i = 0; i < BITS_TO_U32(irqc->nr_hw); i++)
+		aic_ic_write(irqc, AIC_MASK_SET + i * 4, ~0);
+	for (i = 0; i < BITS_TO_U32(irqc->nr_hw); i++)
+		aic_ic_write(irqc, AIC_SW_CLR + i * 4, ~0);
+	for (i = 0; i < irqc->nr_hw; i++)
+		aic_ic_write(irqc, AIC_TARGET_CPU + i * 4, 1);
+
+	cpuhp_setup_state(CPUHP_AP_IRQ_APPLE_AIC_STARTING,
+			  "irqchip/apple-aic/ipi:starting",
+			  aic_init_cpu, NULL);
+
+	pr_info("AIC: initialized with %d IRQs, %d FIQs, %d vIPIs\n",
+		irqc->nr_hw, AIC_NR_FIQ, AIC_NR_SWIPI);
+
+	return 0;
+}
+
+IRQCHIP_DECLARE(apple_m1_aic, "apple,aic", aic_of_ic_init);
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index f14adb882338..f56eee992c75 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -100,6 +100,7 @@ enum cpuhp_state {
 	CPUHP_AP_CPU_PM_STARTING,
 	CPUHP_AP_IRQ_GIC_STARTING,
 	CPUHP_AP_IRQ_HIP04_STARTING,
+	CPUHP_AP_IRQ_APPLE_AIC_STARTING,
 	CPUHP_AP_IRQ_ARMADA_XP_STARTING,
 	CPUHP_AP_IRQ_BCM2836_STARTING,
 	CPUHP_AP_IRQ_MIPS_GIC_STARTING,
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 17/27] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (15 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-08 15:35   ` Marc Zyngier
  2021-03-04 21:38 ` [RFT PATCH v3 18/27] tty: serial: samsung_tty: Separate S3C64XX ops structure Hector Martin
                   ` (10 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This adds a Kconfig option to toggle support for Apple ARM SoCs.
At this time this targets the M1 and later "Apple Silicon" Mac SoCs.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/Kconfig.platforms | 8 ++++++++
 arch/arm64/configs/defconfig | 1 +
 2 files changed, 9 insertions(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index cdfd5fed457f..c2b5791e3d69 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -36,6 +36,14 @@ config ARCH_ALPINE
 	  This enables support for the Annapurna Labs Alpine
 	  Soc family.
 
+config ARCH_APPLE
+	bool "Apple Silicon SoC family"
+	select APPLE_AIC
+	select ARM64_FIQ_SUPPORT
+	help
+	  This enables support for Apple's in-house ARM SoC family, starting
+	  with the Apple M1.
+
 config ARCH_BCM2835
 	bool "Broadcom BCM2835 family"
 	select TIMER_OF
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index d612f633b771..54fb257e55f7 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -31,6 +31,7 @@ CONFIG_ARCH_ACTIONS=y
 CONFIG_ARCH_AGILEX=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
+CONFIG_ARCH_APPLE=y
 CONFIG_ARCH_BCM2835=y
 CONFIG_ARCH_BCM4908=y
 CONFIG_ARCH_BCM_IPROC=y
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 18/27] tty: serial: samsung_tty: Separate S3C64XX ops structure
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (16 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 17/27] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (9 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

Instead of patching a single global ops structure depending on the port
type, use a separate s3c64xx_serial_ops for the S3C64XX type. This
allows us to mark the structures as const.

Also split out s3c64xx_serial_shutdown into a separate function now that
we have a separate ops structure; this avoids excessive branching
control flow and mirrors s3c64xx_serial_startup. tx_claimed and
rx_claimed are only used in the S3C24XX functions.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/tty/serial/samsung_tty.c | 71 ++++++++++++++++++++++++--------
 1 file changed, 54 insertions(+), 17 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 8ae3e03fbd8c..78dc6e9240fb 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -1098,27 +1098,36 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
 
 	if (ourport->tx_claimed) {
-		if (!s3c24xx_serial_has_interrupt_mask(port))
-			free_irq(ourport->tx_irq, ourport);
+		free_irq(ourport->tx_irq, ourport);
 		ourport->tx_enabled = 0;
 		ourport->tx_claimed = 0;
 		ourport->tx_mode = 0;
 	}
 
 	if (ourport->rx_claimed) {
-		if (!s3c24xx_serial_has_interrupt_mask(port))
-			free_irq(ourport->rx_irq, ourport);
+		free_irq(ourport->rx_irq, ourport);
 		ourport->rx_claimed = 0;
 		ourport->rx_enabled = 0;
 	}
 
-	/* Clear pending interrupts and mask all interrupts */
-	if (s3c24xx_serial_has_interrupt_mask(port)) {
-		free_irq(port->irq, ourport);
+	if (ourport->dma)
+		s3c24xx_serial_release_dma(ourport);
 
-		wr_regl(port, S3C64XX_UINTP, 0xf);
-		wr_regl(port, S3C64XX_UINTM, 0xf);
-	}
+	ourport->tx_in_progress = 0;
+}
+
+static void s3c64xx_serial_shutdown(struct uart_port *port)
+{
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+	ourport->tx_enabled = 0;
+	ourport->tx_mode = 0;
+	ourport->rx_enabled = 0;
+
+	free_irq(port->irq, ourport);
+
+	wr_regl(port, S3C64XX_UINTP, 0xf);
+	wr_regl(port, S3C64XX_UINTM, 0xf);
 
 	if (ourport->dma)
 		s3c24xx_serial_release_dma(ourport);
@@ -1193,9 +1202,7 @@ static int s3c64xx_serial_startup(struct uart_port *port)
 
 	/* For compatibility with s3c24xx Soc's */
 	ourport->rx_enabled = 1;
-	ourport->rx_claimed = 1;
 	ourport->tx_enabled = 0;
-	ourport->tx_claimed = 1;
 
 	spin_lock_irqsave(&port->lock, flags);
 
@@ -1608,7 +1615,7 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port,
 			 unsigned char c);
 #endif
 
-static struct uart_ops s3c24xx_serial_ops = {
+static const struct uart_ops s3c24xx_serial_ops = {
 	.pm		= s3c24xx_serial_pm,
 	.tx_empty	= s3c24xx_serial_tx_empty,
 	.get_mctrl	= s3c24xx_serial_get_mctrl,
@@ -1631,6 +1638,29 @@ static struct uart_ops s3c24xx_serial_ops = {
 #endif
 };
 
+static const struct uart_ops s3c64xx_serial_ops = {
+	.pm		= s3c24xx_serial_pm,
+	.tx_empty	= s3c24xx_serial_tx_empty,
+	.get_mctrl	= s3c24xx_serial_get_mctrl,
+	.set_mctrl	= s3c24xx_serial_set_mctrl,
+	.stop_tx	= s3c24xx_serial_stop_tx,
+	.start_tx	= s3c24xx_serial_start_tx,
+	.stop_rx	= s3c24xx_serial_stop_rx,
+	.break_ctl	= s3c24xx_serial_break_ctl,
+	.startup	= s3c64xx_serial_startup,
+	.shutdown	= s3c64xx_serial_shutdown,
+	.set_termios	= s3c24xx_serial_set_termios,
+	.type		= s3c24xx_serial_type,
+	.release_port	= s3c24xx_serial_release_port,
+	.request_port	= s3c24xx_serial_request_port,
+	.config_port	= s3c24xx_serial_config_port,
+	.verify_port	= s3c24xx_serial_verify_port,
+#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
+	.poll_get_char = s3c24xx_serial_get_poll_char,
+	.poll_put_char = s3c24xx_serial_put_poll_char,
+#endif
+};
+
 static struct uart_driver s3c24xx_uart_drv = {
 	.owner		= THIS_MODULE,
 	.driver_name	= "s3c2410_serial",
@@ -1868,10 +1898,6 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 	/* setup info for port */
 	port->dev	= &platdev->dev;
 
-	/* Startup sequence is different for s3c64xx and higher SoC's */
-	if (s3c24xx_serial_has_interrupt_mask(port))
-		s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
-
 	port->uartclk = 1;
 
 	if (cfg->uart_flags & UPF_CONS_FLOW) {
@@ -2019,6 +2045,17 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 			dev_get_platdata(&pdev->dev) :
 			ourport->drv_data->def_cfg;
 
+	switch (ourport->info->type) {
+	case PORT_S3C2410:
+	case PORT_S3C2412:
+	case PORT_S3C2440:
+		ourport->port.ops = &s3c24xx_serial_ops;
+		break;
+	case PORT_S3C6400:
+		ourport->port.ops = &s3c64xx_serial_ops;
+		break;
+	}
+
 	if (np) {
 		of_property_read_u32(np,
 			"samsung,uart-fifosize", &ourport->port.fifosize);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 19/27] tty: serial: samsung_tty: Add ucon_mask parameter
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (17 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 18/27] tty: serial: samsung_tty: Separate S3C64XX ops structure Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (8 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This simplifies the code by removing the only distinction between the
S3C2410 and S3C2440 codepaths.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/tty/serial/samsung_tty.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 78dc6e9240fb..33b421dbeb83 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -70,6 +70,7 @@ struct s3c24xx_uart_info {
 	unsigned long		num_clks;
 	unsigned long		clksel_mask;
 	unsigned long		clksel_shift;
+	unsigned long		ucon_mask;
 
 	/* uart port features */
 
@@ -1736,14 +1737,9 @@ static void s3c24xx_serial_resetport(struct uart_port *port,
 {
 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
 	unsigned long ucon = rd_regl(port, S3C2410_UCON);
-	unsigned int ucon_mask;
 
-	ucon_mask = info->clksel_mask;
-	if (info->type == PORT_S3C2440)
-		ucon_mask |= S3C2440_UCON0_DIVMASK;
-
-	ucon &= ucon_mask;
-	wr_regl(port, S3C2410_UCON,  ucon | cfg->ucon);
+	ucon &= (info->clksel_mask | info->ucon_mask);
+	wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
 
 	/* reset both fifos */
 	wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
@@ -2486,6 +2482,7 @@ static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
 		.num_clks	= 4,
 		.clksel_mask	= S3C2412_UCON_CLKMASK,
 		.clksel_shift	= S3C2412_UCON_CLKSHIFT,
+		.ucon_mask	= S3C2440_UCON0_DIVMASK,
 	},
 	.def_cfg = &(struct s3c2410_uartcfg) {
 		.ucon		= S3C2410_UCON_DEFAULT,
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 20/27] tty: serial: samsung_tty: Add s3c24xx_port_type
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (18 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 19/27] tty: serial: samsung_tty: Add ucon_mask parameter Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (7 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This decouples the TTY layer PORT_ types, which are exposed to
userspace, from the driver-internal flag of what kind of port this is.

This removes s3c24xx_serial_has_interrupt_mask, which was just checking
for a specific type anyway.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/tty/serial/samsung_tty.c | 112 +++++++++++++++++++------------
 1 file changed, 70 insertions(+), 42 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 33b421dbeb83..39b2eb165bdc 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -56,9 +56,15 @@
 /* flag to ignore all characters coming in */
 #define RXSTAT_DUMMY_READ (0x10000000)
 
+enum s3c24xx_port_type {
+	TYPE_S3C24XX,
+	TYPE_S3C6400,
+};
+
 struct s3c24xx_uart_info {
 	char			*name;
-	unsigned int		type;
+	enum s3c24xx_port_type	type;
+	unsigned int		port_type;
 	unsigned int		fifosize;
 	unsigned long		rx_fifomask;
 	unsigned long		rx_fifoshift;
@@ -229,16 +235,6 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
 	return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE;
 }
 
-/*
- * s3c64xx and later SoC's include the interrupt mask and status registers in
- * the controller itself, unlike the s3c24xx SoC's which have these registers
- * in the interrupt controller. Check if the port type is s3c64xx or higher.
- */
-static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
-{
-	return to_ourport(port)->info->type == PORT_S3C6400;
-}
-
 static void s3c24xx_serial_rx_enable(struct uart_port *port)
 {
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
@@ -290,10 +286,14 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
 	if (!ourport->tx_enabled)
 		return;
 
-	if (s3c24xx_serial_has_interrupt_mask(port))
+	switch (ourport->info->type) {
+	case TYPE_S3C6400:
 		s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
-	else
+		break;
+	default:
 		disable_irq_nosync(ourport->tx_irq);
+		break;
+	}
 
 	if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) {
 		dmaengine_pause(dma->tx_chan);
@@ -354,10 +354,14 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
 	u32 ucon;
 
 	/* Mask Tx interrupt */
-	if (s3c24xx_serial_has_interrupt_mask(port))
+	switch (ourport->info->type) {
+	case TYPE_S3C6400:
 		s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
-	else
+		break;
+	default:
 		disable_irq_nosync(ourport->tx_irq);
+		break;
+	}
 
 	/* Enable tx dma mode */
 	ucon = rd_regl(port, S3C2410_UCON);
@@ -387,11 +391,15 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
 	wr_regl(port,  S3C2410_UCON, ucon);
 
 	/* Unmask Tx interrupt */
-	if (s3c24xx_serial_has_interrupt_mask(port))
+	switch (ourport->info->type) {
+	case TYPE_S3C6400:
 		s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
 				  S3C64XX_UINTM);
-	else
+		break;
+	default:
 		enable_irq(ourport->tx_irq);
+		break;
+	}
 
 	ourport->tx_mode = S3C24XX_TX_PIO;
 }
@@ -514,11 +522,15 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
 
 	if (ourport->rx_enabled) {
 		dev_dbg(port->dev, "stopping rx\n");
-		if (s3c24xx_serial_has_interrupt_mask(port))
+		switch (ourport->info->type) {
+		case TYPE_S3C6400:
 			s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
 					S3C64XX_UINTM);
-		else
+			break;
+		default:
 			disable_irq_nosync(ourport->rx_irq);
+			break;
+		}
 		ourport->rx_enabled = 0;
 	}
 	if (dma && dma->rx_chan) {
@@ -1543,14 +1555,12 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
 
 static const char *s3c24xx_serial_type(struct uart_port *port)
 {
-	switch (port->type) {
-	case PORT_S3C2410:
-		return "S3C2410";
-	case PORT_S3C2440:
-		return "S3C2440";
-	case PORT_S3C2412:
-		return "S3C2412";
-	case PORT_S3C6400:
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+	switch (ourport->info->type) {
+	case TYPE_S3C24XX:
+		return "S3C24XX";
+	case TYPE_S3C6400:
 		return "S3C6400/10";
 	default:
 		return NULL;
@@ -1577,7 +1587,7 @@ static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
 
 	if (flags & UART_CONFIG_TYPE &&
 	    s3c24xx_serial_request_port(port) == 0)
-		port->type = info->type;
+		port->type = info->port_type;
 }
 
 /*
@@ -1588,7 +1598,7 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
 {
 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
 
-	if (ser->type != PORT_UNKNOWN && ser->type != info->type)
+	if (ser->type != PORT_UNKNOWN && ser->type != info->port_type)
 		return -EINVAL;
 
 	return 0;
@@ -1927,11 +1937,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 		ourport->tx_irq = ret + 1;
 	}
 
-	if (!s3c24xx_serial_has_interrupt_mask(port)) {
+	switch (ourport->info->type) {
+	case TYPE_S3C24XX:
 		ret = platform_get_irq(platdev, 1);
 		if (ret > 0)
 			ourport->tx_irq = ret;
+		break;
+	default:
+		break;
 	}
+
 	/*
 	 * DMA is currently supported only on DT platforms, if DMA properties
 	 * are specified.
@@ -1967,10 +1982,14 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 		pr_warn("uart: failed to enable baudclk\n");
 
 	/* Keep all interrupts masked and cleared */
-	if (s3c24xx_serial_has_interrupt_mask(port)) {
+	switch (ourport->info->type) {
+	case TYPE_S3C6400:
 		wr_regl(port, S3C64XX_UINTM, 0xf);
 		wr_regl(port, S3C64XX_UINTP, 0xf);
 		wr_regl(port, S3C64XX_UINTSP, 0xf);
+		break;
+	default:
+		break;
 	}
 
 	dev_dbg(port->dev, "port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n",
@@ -2042,12 +2061,10 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 			ourport->drv_data->def_cfg;
 
 	switch (ourport->info->type) {
-	case PORT_S3C2410:
-	case PORT_S3C2412:
-	case PORT_S3C2440:
+	case TYPE_S3C24XX:
 		ourport->port.ops = &s3c24xx_serial_ops;
 		break;
-	case PORT_S3C6400:
+	case TYPE_S3C6400:
 		ourport->port.ops = &s3c64xx_serial_ops;
 		break;
 	}
@@ -2175,7 +2192,8 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
 
 	if (port) {
 		/* restore IRQ mask */
-		if (s3c24xx_serial_has_interrupt_mask(port)) {
+		switch (ourport->info->type) {
+		case TYPE_S3C6400: {
 			unsigned int uintm = 0xf;
 
 			if (ourport->tx_enabled)
@@ -2189,6 +2207,10 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
 			if (!IS_ERR(ourport->baudclk))
 				clk_disable_unprepare(ourport->baudclk);
 			clk_disable_unprepare(ourport->clk);
+			break;
+		}
+		default:
+			break;
 		}
 	}
 
@@ -2413,7 +2435,8 @@ static struct console s3c24xx_serial_console = {
 static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
 	.info = &(struct s3c24xx_uart_info) {
 		.name		= "Samsung S3C2410 UART",
-		.type		= PORT_S3C2410,
+		.type		= TYPE_S3C24XX,
+		.port_type	= PORT_S3C2410,
 		.fifosize	= 16,
 		.rx_fifomask	= S3C2410_UFSTAT_RXMASK,
 		.rx_fifoshift	= S3C2410_UFSTAT_RXSHIFT,
@@ -2440,7 +2463,8 @@ static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
 static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
 	.info = &(struct s3c24xx_uart_info) {
 		.name		= "Samsung S3C2412 UART",
-		.type		= PORT_S3C2412,
+		.type		= TYPE_S3C24XX,
+		.port_type	= PORT_S3C2412,
 		.fifosize	= 64,
 		.has_divslot	= 1,
 		.rx_fifomask	= S3C2440_UFSTAT_RXMASK,
@@ -2469,7 +2493,8 @@ static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
 static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
 	.info = &(struct s3c24xx_uart_info) {
 		.name		= "Samsung S3C2440 UART",
-		.type		= PORT_S3C2440,
+		.type		= TYPE_S3C24XX,
+		.port_type	= PORT_S3C2440,
 		.fifosize	= 64,
 		.has_divslot	= 1,
 		.rx_fifomask	= S3C2440_UFSTAT_RXMASK,
@@ -2498,7 +2523,8 @@ static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
 static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
 	.info = &(struct s3c24xx_uart_info) {
 		.name		= "Samsung S3C6400 UART",
-		.type		= PORT_S3C6400,
+		.type		= TYPE_S3C6400,
+		.port_type	= PORT_S3C6400,
 		.fifosize	= 64,
 		.has_divslot	= 1,
 		.rx_fifomask	= S3C2440_UFSTAT_RXMASK,
@@ -2526,7 +2552,8 @@ static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
 static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
 	.info = &(struct s3c24xx_uart_info) {
 		.name		= "Samsung S5PV210 UART",
-		.type		= PORT_S3C6400,
+		.type		= TYPE_S3C6400,
+		.port_type	= PORT_S3C6400,
 		.has_divslot	= 1,
 		.rx_fifomask	= S5PV210_UFSTAT_RXMASK,
 		.rx_fifoshift	= S5PV210_UFSTAT_RXSHIFT,
@@ -2554,7 +2581,8 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
 #define EXYNOS_COMMON_SERIAL_DRV_DATA				\
 	.info = &(struct s3c24xx_uart_info) {			\
 		.name		= "Samsung Exynos UART",	\
-		.type		= PORT_S3C6400,			\
+		.type		= TYPE_S3C6400,			\
+		.port_type	= PORT_S3C6400,			\
 		.has_divslot	= 1,				\
 		.rx_fifomask	= S5PV210_UFSTAT_RXMASK,	\
 		.rx_fifoshift	= S5PV210_UFSTAT_RXSHIFT,	\
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (19 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 20/27] tty: serial: samsung_tty: Add s3c24xx_port_type Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-05 10:51   ` Krzysztof Kozlowski
  2021-03-05 15:17   ` Andy Shevchenko
  2021-03-04 21:38 ` [RFT PATCH v3 22/27] tty: serial: samsung_tty: Use devm_ioremap_resource Hector Martin
                   ` (6 subsequent siblings)
  27 siblings, 2 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

* Split out s3c24xx_serial_tx_chars from s3c24xx_serial_tx_irq,
  where only the latter acquires the port lock. This will be necessary
  on platforms which have edge-triggered IRQs, as we need to call
  s3c24xx_serial_tx_chars to kick off transmission from outside IRQ
  context, with the port lock held.

* Rename s3c24xx_serial_rx_chars to s3c24xx_serial_rx_irq for
  consistency with the above. All it does now is call two other
  functions anyway.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/tty/serial/samsung_tty.c | 34 +++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 39b2eb165bdc..7106eb238d8c 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -827,7 +827,7 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
+static irqreturn_t s3c24xx_serial_rx_irq(int irq, void *dev_id)
 {
 	struct s3c24xx_uart_port *ourport = dev_id;
 
@@ -836,16 +836,12 @@ static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
 	return s3c24xx_serial_rx_chars_pio(dev_id);
 }
 
-static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
+static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
 {
-	struct s3c24xx_uart_port *ourport = id;
 	struct uart_port *port = &ourport->port;
 	struct circ_buf *xmit = &port->state->xmit;
-	unsigned long flags;
 	int count, dma_count = 0;
 
-	spin_lock_irqsave(&port->lock, flags);
-
 	count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
 
 	if (ourport->dma && ourport->dma->tx_chan &&
@@ -862,7 +858,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
 		wr_reg(port, S3C2410_UTXH, port->x_char);
 		port->icount.tx++;
 		port->x_char = 0;
-		goto out;
+		return;
 	}
 
 	/* if there isn't anything more to transmit, or the uart is now
@@ -871,7 +867,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
 
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
 		s3c24xx_serial_stop_tx(port);
-		goto out;
+		return;
 	}
 
 	/* try and drain the buffer... */
@@ -893,7 +889,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
 
 	if (!count && dma_count) {
 		s3c24xx_serial_start_tx_dma(ourport, dma_count);
-		goto out;
+		return;
 	}
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
@@ -904,8 +900,18 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
 
 	if (uart_circ_empty(xmit))
 		s3c24xx_serial_stop_tx(port);
+}
+
+static irqreturn_t s3c24xx_serial_tx_irq(int irq, void *id)
+{
+	struct s3c24xx_uart_port *ourport = id;
+	struct uart_port *port = &ourport->port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	s3c24xx_serial_tx_chars(ourport);
 
-out:
 	spin_unlock_irqrestore(&port->lock, flags);
 	return IRQ_HANDLED;
 }
@@ -919,11 +925,11 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
 	irqreturn_t ret = IRQ_HANDLED;
 
 	if (pend & S3C64XX_UINTM_RXD_MSK) {
-		ret = s3c24xx_serial_rx_chars(irq, id);
+		ret = s3c24xx_serial_rx_irq(irq, id);
 		wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
 	}
 	if (pend & S3C64XX_UINTM_TXD_MSK) {
-		ret = s3c24xx_serial_tx_chars(irq, id);
+		ret = s3c24xx_serial_tx_irq(irq, id);
 		wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
 	}
 	return ret;
@@ -1155,7 +1161,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
 
 	ourport->rx_enabled = 1;
 
-	ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
+	ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_irq, 0,
 			  s3c24xx_serial_portname(port), ourport);
 
 	if (ret != 0) {
@@ -1169,7 +1175,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
 
 	ourport->tx_enabled = 1;
 
-	ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
+	ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_irq, 0,
 			  s3c24xx_serial_portname(port), ourport);
 
 	if (ret) {
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 22/27] tty: serial: samsung_tty: Use devm_ioremap_resource
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (20 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-05 10:54   ` Krzysztof Kozlowski
  2021-03-04 21:38 ` [RFT PATCH v3 23/27] dt-bindings: serial: samsung: Add apple,s5l-uart compatible Hector Martin
                   ` (5 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This picks up the non-posted I/O mode needed for Apple platforms to
work properly.

This removes the request/release functions, which are no longer
necessary, since devm_ioremap_resource takes care of that already. Most
other drivers already do it this way, anyway.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/tty/serial/samsung_tty.c | 25 +++----------------------
 1 file changed, 3 insertions(+), 22 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 7106eb238d8c..26cb05992e9f 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -1573,26 +1573,11 @@ static const char *s3c24xx_serial_type(struct uart_port *port)
 	}
 }
 
-#define MAP_SIZE (0x100)
-
-static void s3c24xx_serial_release_port(struct uart_port *port)
-{
-	release_mem_region(port->mapbase, MAP_SIZE);
-}
-
-static int s3c24xx_serial_request_port(struct uart_port *port)
-{
-	const char *name = s3c24xx_serial_portname(port);
-
-	return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
-}
-
 static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
 {
 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
 
-	if (flags & UART_CONFIG_TYPE &&
-	    s3c24xx_serial_request_port(port) == 0)
+	if (flags & UART_CONFIG_TYPE)
 		port->type = info->port_type;
 }
 
@@ -1645,8 +1630,6 @@ static const struct uart_ops s3c24xx_serial_ops = {
 	.shutdown	= s3c24xx_serial_shutdown,
 	.set_termios	= s3c24xx_serial_set_termios,
 	.type		= s3c24xx_serial_type,
-	.release_port	= s3c24xx_serial_release_port,
-	.request_port	= s3c24xx_serial_request_port,
 	.config_port	= s3c24xx_serial_config_port,
 	.verify_port	= s3c24xx_serial_verify_port,
 #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
@@ -1668,8 +1651,6 @@ static const struct uart_ops s3c64xx_serial_ops = {
 	.shutdown	= s3c64xx_serial_shutdown,
 	.set_termios	= s3c24xx_serial_set_termios,
 	.type		= s3c24xx_serial_type,
-	.release_port	= s3c24xx_serial_release_port,
-	.request_port	= s3c24xx_serial_request_port,
 	.config_port	= s3c24xx_serial_config_port,
 	.verify_port	= s3c24xx_serial_verify_port,
 #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
@@ -1927,8 +1908,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 
 	dev_dbg(port->dev, "resource %pR)\n", res);
 
-	port->membase = devm_ioremap(port->dev, res->start, resource_size(res));
-	if (!port->membase) {
+	port->membase = devm_ioremap_resource(port->dev, res);
+	if (IS_ERR(port->membase)) {
 		dev_err(port->dev, "failed to remap controller address\n");
 		return -EBUSY;
 	}
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 23/27] dt-bindings: serial: samsung: Add apple,s5l-uart compatible
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (21 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 22/27] tty: serial: samsung_tty: Use devm_ioremap_resource Hector Martin
@ 2021-03-04 21:38 ` 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
                   ` (4 subsequent siblings)
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

Apple mobile devices originally used Samsung SoCs (starting with the
S5L8900), and their current in-house SoCs continue to use compatible
UART peripherals. We'll call this UART variant apple,s5l-uart.

Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 Documentation/devicetree/bindings/serial/samsung_uart.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
index 21ee627b2ced..a59be11acd4f 100644
--- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml
+++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/serial/samsung_uart.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Samsung S3C, S5P and Exynos SoC UART Controller
+title: Samsung S3C, S5P, Exynos, and S5L (Apple SoC) SoC UART Controller
 
 maintainers:
   - Krzysztof Kozlowski <krzk@kernel.org>
@@ -19,6 +19,7 @@ properties:
   compatible:
     items:
       - enum:
+          - apple,s5l-uart
           - samsung,s3c2410-uart
           - samsung,s3c2412-uart
           - samsung,s3c2440-uart
@@ -96,6 +97,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - apple,s5l-uart
               - samsung,exynos4210-uart
     then:
       properties:
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 24/27] tty: serial: samsung_tty: Add support for Apple UARTs
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (22 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 23/27] dt-bindings: serial: samsung: Add apple,s5l-uart compatible Hector Martin
@ 2021-03-04 21:38 ` Hector Martin
  2021-03-05 10:58   ` Krzysztof Kozlowski
  2021-03-05 15:28   ` Andy Shevchenko
  2021-03-04 21:39 ` [RFT PATCH v3 25/27] tty: serial: samsung_tty: Add earlycon " Hector Martin
                   ` (3 subsequent siblings)
  27 siblings, 2 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

Apple SoCs are a distant descendant of Samsung designs and use yet
another variant of their UART style, with different interrupt handling.

In particular, this variant has the following differences with existing
ones:

* It includes a built-in interrupt controller with different registers,
  using only a single platform IRQ

* Internal interrupt sources are treated as edge-triggered, even though
  the IRQ output is level-triggered. This chiefly affects the TX IRQ
  path: the driver can no longer rely on the TX buffer empty IRQ
  immediately firing after TX is enabled, but instead must prime the
  FIFO with data directly.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/tty/serial/Kconfig       |   2 +-
 drivers/tty/serial/samsung_tty.c | 238 +++++++++++++++++++++++++++++--
 include/linux/serial_s3c.h       |  16 +++
 3 files changed, 247 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 0c4cd4a348f4..3ba31ea20d8a 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -236,7 +236,7 @@ config SERIAL_CLPS711X_CONSOLE
 
 config SERIAL_SAMSUNG
 	tristate "Samsung SoC serial support"
-	depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
+	depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || ARCH_APPLE || COMPILE_TEST
 	select SERIAL_CORE
 	help
 	  Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 26cb05992e9f..5ef37c4538ce 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -59,6 +59,7 @@
 enum s3c24xx_port_type {
 	TYPE_S3C24XX,
 	TYPE_S3C6400,
+	TYPE_APPLE_S5L,
 };
 
 struct s3c24xx_uart_info {
@@ -151,6 +152,8 @@ struct s3c24xx_uart_port {
 #endif
 };
 
+static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport);
+
 /* conversion functions */
 
 #define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
@@ -290,6 +293,9 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
 	case TYPE_S3C6400:
 		s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
 		break;
+	case TYPE_APPLE_S5L:
+		s3c24xx_clear_bit(port, APPLE_S5L_UCON_TXTHRESH_ENA, S3C2410_UCON);
+		break;
 	default:
 		disable_irq_nosync(ourport->tx_irq);
 		break;
@@ -358,6 +364,9 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
 	case TYPE_S3C6400:
 		s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
 		break;
+	case TYPE_APPLE_S5L:
+		WARN_ON(1); // No DMA
+		break;
 	default:
 		disable_irq_nosync(ourport->tx_irq);
 		break;
@@ -396,12 +405,23 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
 		s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
 				  S3C64XX_UINTM);
 		break;
+	case TYPE_APPLE_S5L:
+		ucon |= APPLE_S5L_UCON_TXTHRESH_ENA_MSK;
+		wr_regl(port, S3C2410_UCON, ucon);
+		break;
 	default:
 		enable_irq(ourport->tx_irq);
 		break;
 	}
 
 	ourport->tx_mode = S3C24XX_TX_PIO;
+
+	/*
+	 * The Apple version only has edge triggered TX IRQs, so we need
+	 * to kick off the process by sending some characters here.
+	 */
+	if (ourport->info->type == TYPE_APPLE_S5L)
+		s3c24xx_serial_tx_chars(ourport);
 }
 
 static void s3c24xx_serial_start_tx_pio(struct s3c24xx_uart_port *ourport)
@@ -527,6 +547,10 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
 			s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
 					S3C64XX_UINTM);
 			break;
+		case TYPE_APPLE_S5L:
+			s3c24xx_clear_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON);
+			s3c24xx_clear_bit(port, APPLE_S5L_UCON_RXTO_ENA, S3C2410_UCON);
+			break;
 		default:
 			disable_irq_nosync(ourport->rx_irq);
 			break;
@@ -664,14 +688,18 @@ static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
 
 	/* set Rx mode to DMA mode */
 	ucon = rd_regl(port, S3C2410_UCON);
-	ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
-			S3C64XX_UCON_EMPTYINT_EN |
-			S3C64XX_UCON_DMASUS_EN |
-			S3C64XX_UCON_TIMEOUT_EN |
-			S3C64XX_UCON_RXMODE_MASK);
-	ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
-			S3C64XX_UCON_TIMEOUT_EN |
-			S3C64XX_UCON_RXMODE_CPU;
+	ucon &= ~S3C64XX_UCON_RXMODE_MASK;
+	ucon |= S3C64XX_UCON_RXMODE_CPU;
+
+	/* Apple types use these bits for IRQ masks */
+	if (ourport->info->type != TYPE_APPLE_S5L) {
+		ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
+				S3C64XX_UCON_EMPTYINT_EN |
+				S3C64XX_UCON_DMASUS_EN |
+				S3C64XX_UCON_TIMEOUT_EN);
+		ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
+				S3C64XX_UCON_TIMEOUT_EN;
+	}
 	wr_regl(port, S3C2410_UCON, ucon);
 
 	ourport->rx_mode = S3C24XX_RX_PIO;
@@ -935,6 +963,27 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
 	return ret;
 }
 
+/* interrupt handler for Apple SoC's.*/
+static irqreturn_t apple_serial_handle_irq(int irq, void *id)
+{
+	struct s3c24xx_uart_port *ourport = id;
+	struct uart_port *port = &ourport->port;
+	unsigned int pend = rd_regl(port, S3C2410_UTRSTAT);
+	irqreturn_t ret = IRQ_NONE;
+
+	if (pend & (APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO)) {
+		wr_regl(port, S3C2410_UTRSTAT,
+			APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO);
+		ret = s3c24xx_serial_rx_irq(irq, id);
+	}
+	if (pend & APPLE_S5L_UTRSTAT_TXTHRESH) {
+		wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_TXTHRESH);
+		ret = s3c24xx_serial_tx_irq(irq, id);
+	}
+
+	return ret;
+}
+
 static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
 {
 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
@@ -1154,6 +1203,32 @@ static void s3c64xx_serial_shutdown(struct uart_port *port)
 	ourport->tx_in_progress = 0;
 }
 
+static void apple_s5l_serial_shutdown(struct uart_port *port)
+{
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+	unsigned int ucon;
+
+	ucon = rd_regl(port, S3C2410_UCON);
+	ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
+		  APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
+		  APPLE_S5L_UCON_RXTO_ENA_MSK);
+	wr_regl(port, S3C2410_UCON, ucon);
+
+	wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
+
+	free_irq(port->irq, ourport);
+
+	ourport->tx_enabled = 0;
+	ourport->tx_mode = 0;
+	ourport->rx_enabled = 0;
+
+	if (ourport->dma)
+		s3c24xx_serial_release_dma(ourport);
+
+	ourport->tx_in_progress = 0;
+}
+
 static int s3c24xx_serial_startup(struct uart_port *port)
 {
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
@@ -1241,6 +1316,45 @@ static int s3c64xx_serial_startup(struct uart_port *port)
 	return ret;
 }
 
+static int apple_s5l_serial_startup(struct uart_port *port)
+{
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+	unsigned long flags;
+	unsigned int ufcon;
+	int ret;
+
+	wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
+
+	ret = request_irq(port->irq, apple_serial_handle_irq, 0,
+			  s3c24xx_serial_portname(port), ourport);
+	if (ret) {
+		dev_err(port->dev, "cannot get irq %d\n", port->irq);
+		return ret;
+	}
+
+	/* For compatibility with s3c24xx Soc's */
+	ourport->rx_enabled = 1;
+	ourport->tx_enabled = 0;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	ufcon = rd_regl(port, S3C2410_UFCON);
+	ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
+	if (!uart_console(port))
+		ufcon |= S3C2410_UFCON_RESETTX;
+	wr_regl(port, S3C2410_UFCON, ufcon);
+
+	enable_rx_pio(ourport);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	/* Enable Rx Interrupt */
+	s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON);
+	s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTO_ENA, S3C2410_UCON);
+
+	return ret;
+}
+
 /* power power management control */
 
 static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
@@ -1568,6 +1682,8 @@ static const char *s3c24xx_serial_type(struct uart_port *port)
 		return "S3C24XX";
 	case TYPE_S3C6400:
 		return "S3C6400/10";
+	case TYPE_APPLE_S5L:
+		return "APPLE S5L";
 	default:
 		return NULL;
 	}
@@ -1659,6 +1775,27 @@ static const struct uart_ops s3c64xx_serial_ops = {
 #endif
 };
 
+static const struct uart_ops apple_s5l_serial_ops = {
+	.pm		= s3c24xx_serial_pm,
+	.tx_empty	= s3c24xx_serial_tx_empty,
+	.get_mctrl	= s3c24xx_serial_get_mctrl,
+	.set_mctrl	= s3c24xx_serial_set_mctrl,
+	.stop_tx	= s3c24xx_serial_stop_tx,
+	.start_tx	= s3c24xx_serial_start_tx,
+	.stop_rx	= s3c24xx_serial_stop_rx,
+	.break_ctl	= s3c24xx_serial_break_ctl,
+	.startup	= apple_s5l_serial_startup,
+	.shutdown	= apple_s5l_serial_shutdown,
+	.set_termios	= s3c24xx_serial_set_termios,
+	.type		= s3c24xx_serial_type,
+	.config_port	= s3c24xx_serial_config_port,
+	.verify_port	= s3c24xx_serial_verify_port,
+#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
+	.poll_get_char = s3c24xx_serial_get_poll_char,
+	.poll_put_char = s3c24xx_serial_put_poll_char,
+#endif
+};
+
 static struct uart_driver s3c24xx_uart_drv = {
 	.owner		= THIS_MODULE,
 	.driver_name	= "s3c2410_serial",
@@ -1975,6 +2112,18 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 		wr_regl(port, S3C64XX_UINTP, 0xf);
 		wr_regl(port, S3C64XX_UINTSP, 0xf);
 		break;
+	case TYPE_APPLE_S5L: {
+		unsigned int ucon;
+
+		ucon = rd_regl(port, S3C2410_UCON);
+		ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
+			APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
+			APPLE_S5L_UCON_RXTO_ENA_MSK);
+		wr_regl(port, S3C2410_UCON, ucon);
+
+		wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
+		break;
+	}
 	default:
 		break;
 	}
@@ -2054,6 +2203,9 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 	case TYPE_S3C6400:
 		ourport->port.ops = &s3c64xx_serial_ops;
 		break;
+	case TYPE_APPLE_S5L:
+		ourport->port.ops = &apple_s5l_serial_ops;
+		break;
 	}
 
 	if (np) {
@@ -2196,6 +2348,43 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
 			clk_disable_unprepare(ourport->clk);
 			break;
 		}
+		case TYPE_APPLE_S5L: {
+			unsigned int ucon;
+			int ret;
+
+			ret = clk_prepare_enable(ourport->clk);
+			if (ret) {
+				dev_err(dev, "clk_enable clk failed: %d\n", ret);
+				return ret;
+			}
+			if (!IS_ERR(ourport->baudclk)) {
+				ret = clk_prepare_enable(ourport->baudclk);
+				if (ret) {
+					dev_err(dev, "clk_enable baudclk failed: %d\n", ret);
+					clk_disable_unprepare(ourport->clk);
+					return ret;
+				}
+			}
+
+			ucon = rd_regl(port, S3C2410_UCON);
+
+			ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
+				  APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
+				  APPLE_S5L_UCON_RXTO_ENA_MSK);
+
+			if (ourport->tx_enabled)
+				ucon |= APPLE_S5L_UCON_TXTHRESH_ENA_MSK;
+			if (ourport->rx_enabled)
+				ucon |= APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
+					APPLE_S5L_UCON_RXTO_ENA_MSK;
+
+			wr_regl(port, S3C2410_UCON, ucon);
+
+			if (!IS_ERR(ourport->baudclk))
+				clk_disable_unprepare(ourport->baudclk);
+			clk_disable_unprepare(ourport->clk);
+			break;
+		}
 		default:
 			break;
 		}
@@ -2605,6 +2794,34 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
 #define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL
 #endif
 
+#ifdef CONFIG_ARCH_APPLE
+static struct s3c24xx_serial_drv_data s5l_serial_drv_data = {
+	.info = &(struct s3c24xx_uart_info) {
+		.name		= "Apple S5L UART",
+		.type		= TYPE_APPLE_S5L,
+		.port_type	= PORT_8250,
+		.fifosize	= 16,
+		.rx_fifomask	= S3C2410_UFSTAT_RXMASK,
+		.rx_fifoshift	= S3C2410_UFSTAT_RXSHIFT,
+		.rx_fifofull	= S3C2410_UFSTAT_RXFULL,
+		.tx_fifofull	= S3C2410_UFSTAT_TXFULL,
+		.tx_fifomask	= S3C2410_UFSTAT_TXMASK,
+		.tx_fifoshift	= S3C2410_UFSTAT_TXSHIFT,
+		.def_clk_sel	= S3C2410_UCON_CLKSEL0,
+		.num_clks	= 1,
+		.clksel_mask	= 0,
+		.clksel_shift	= 0,
+	},
+	.def_cfg = &(struct s3c2410_uartcfg) {
+		.ucon		= APPLE_S5L_UCON_DEFAULT,
+		.ufcon		= S3C2410_UFCON_DEFAULT,
+	},
+};
+#define S5L_SERIAL_DRV_DATA ((kernel_ulong_t)&s5l_serial_drv_data)
+#else
+#define S5L_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
+#endif
+
 static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
 	{
 		.name		= "s3c2410-uart",
@@ -2627,6 +2844,9 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
 	}, {
 		.name		= "exynos5433-uart",
 		.driver_data	= EXYNOS5433_SERIAL_DRV_DATA,
+	}, {
+		.name		= "s5l-uart",
+		.driver_data	= S5L_SERIAL_DRV_DATA,
 	},
 	{ },
 };
@@ -2648,6 +2868,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = {
 		.data = (void *)EXYNOS4210_SERIAL_DRV_DATA },
 	{ .compatible = "samsung,exynos5433-uart",
 		.data = (void *)EXYNOS5433_SERIAL_DRV_DATA },
+	{ .compatible = "apple,s5l-uart",
+		.data = (void *)S5L_SERIAL_DRV_DATA },
 	{},
 };
 MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h
index ca2c5393dc6b..f6c3323fc4c5 100644
--- a/include/linux/serial_s3c.h
+++ b/include/linux/serial_s3c.h
@@ -246,6 +246,22 @@
 				 S5PV210_UFCON_TXTRIG4 |	\
 				 S5PV210_UFCON_RXTRIG4)
 
+#define APPLE_S5L_UCON_RXTO_ENA		9
+#define APPLE_S5L_UCON_RXTHRESH_ENA	12
+#define APPLE_S5L_UCON_TXTHRESH_ENA	13
+#define APPLE_S5L_UCON_RXTO_ENA_MSK	(1 << APPLE_S5L_UCON_RXTO_ENA)
+#define APPLE_S5L_UCON_RXTHRESH_ENA_MSK	(1 << APPLE_S5L_UCON_RXTHRESH_ENA)
+#define APPLE_S5L_UCON_TXTHRESH_ENA_MSK	(1 << APPLE_S5L_UCON_TXTHRESH_ENA)
+
+#define APPLE_S5L_UCON_DEFAULT		(S3C2410_UCON_TXIRQMODE | \
+					 S3C2410_UCON_RXIRQMODE | \
+					 S3C2410_UCON_RXFIFO_TOI)
+
+#define APPLE_S5L_UTRSTAT_RXTHRESH	(1<<4)
+#define APPLE_S5L_UTRSTAT_TXTHRESH	(1<<5)
+#define APPLE_S5L_UTRSTAT_RXTO		(1<<9)
+#define APPLE_S5L_UTRSTAT_ALL_FLAGS	(0x3f0)
+
 #ifndef __ASSEMBLY__
 
 #include <linux/serial_core.h>
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 25/27] tty: serial: samsung_tty: Add earlycon support for Apple UARTs
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (23 preceding siblings ...)
  2021-03-04 21:38 ` [RFT PATCH v3 24/27] tty: serial: samsung_tty: Add support for Apple UARTs Hector Martin
@ 2021-03-04 21:39 ` 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
                   ` (2 subsequent siblings)
  27 siblings, 2 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel,
	Arnd Bergmann

Earlycon support is identical to S3C2410, but Apple SoCs also need
MMIO mapped as nGnRnE. This is handled generically for normal drivers
including the normal UART path here, but earlycon uses fixmap and
runs before that scaffolding is ready.

Since this is the only case where we need this fix, it makes more
sense to do it here in the UART driver instead of introducing a
whole fdt nonposted-mmio resolver just for earlycon/fixmap.

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/tty/serial/samsung_tty.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 5ef37c4538ce..80df842bf4c7 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -3001,6 +3001,23 @@ OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart",
 			s5pv210_early_console_setup);
 OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart",
 			s5pv210_early_console_setup);
+
+/* Apple S5L */
+static int __init apple_s5l_early_console_setup(struct earlycon_device *device,
+						const char *opt)
+{
+	/* Close enough to S3C2410 for earlycon... */
+	device->port.private_data = &s3c2410_early_console_data;
+
+#ifdef CONFIG_ARM64
+	/* ... but we need to override the existing fixmap entry as nGnRnE */
+	__set_fixmap(FIX_EARLYCON_MEM_BASE, device->port.mapbase,
+		     __pgprot(PROT_DEVICE_nGnRnE));
+#endif
+	return samsung_early_console_setup(device, opt);
+}
+
+OF_EARLYCON_DECLARE(s5l, "apple,s5l-uart", apple_s5l_early_console_setup);
 #endif
 
 MODULE_ALIAS("platform:samsung-uart");
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 26/27] dt-bindings: display: Add apple,simple-framebuffer
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (24 preceding siblings ...)
  2021-03-04 21:39 ` [RFT PATCH v3 25/27] tty: serial: samsung_tty: Add earlycon " Hector Martin
@ 2021-03-04 21:39 ` Hector Martin
  2021-03-08 21:18   ` Rob Herring
  2021-03-09 16:37   ` Linus Walleij
  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 10:11 ` [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
  27 siblings, 2 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

Apple SoCs run firmware that sets up a simplefb-compatible framebuffer
for us. Add a compatible for it, and two missing supported formats.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 .../devicetree/bindings/display/simple-framebuffer.yaml      | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
index eaf8c54fcf50..c2499a7906f5 100644
--- a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
+++ b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
@@ -54,6 +54,7 @@ properties:
   compatible:
     items:
       - enum:
+          - apple,simple-framebuffer
           - allwinner,simple-framebuffer
           - amlogic,simple-framebuffer
       - const: simple-framebuffer
@@ -84,9 +85,13 @@ properties:
       Format of the framebuffer:
         * `a8b8g8r8` - 32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r
         * `r5g6b5` - 16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b
+        * `x2r10g10b10` - 32-bit pixels, d[29:20]=r, d[19:10]=g, d[9:0]=b
+        * `x8r8g8b8` - 32-bit pixels, d[23:16]=r, d[15:8]=g, d[7:0]=b
     enum:
       - a8b8g8r8
       - r5g6b5
+      - x2r10g10b10
+      - x8r8g8b8
 
   display:
     $ref: /schemas/types.yaml#/definitions/phandle
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* [RFT PATCH v3 27/27] arm64: apple: Add initial Apple Mac mini (M1, 2020) devicetree
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (25 preceding siblings ...)
  2021-03-04 21:39 ` [RFT PATCH v3 26/27] dt-bindings: display: Add apple,simple-framebuffer Hector Martin
@ 2021-03-04 21:39 ` Hector Martin
  2021-03-05 11:03   ` Krzysztof Kozlowski
  2021-03-05 10:11 ` [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
  27 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-04 21:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hector Martin, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

This currently supports:

* SMP (via spin-tables)
* AIC IRQs
* Serial (with earlycon)
* Framebuffer

A number of properties are dynamic, and based on system firmware
decisions that vary from version to version. These are expected
to be filled in by the loader.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 MAINTAINERS                              |   1 +
 arch/arm64/boot/dts/Makefile             |   1 +
 arch/arm64/boot/dts/apple/Makefile       |   2 +
 arch/arm64/boot/dts/apple/t8103-j274.dts |  45 ++++++++
 arch/arm64/boot/dts/apple/t8103.dtsi     | 135 +++++++++++++++++++++++
 5 files changed, 184 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/Makefile
 create mode 100644 arch/arm64/boot/dts/apple/t8103-j274.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8103.dtsi

diff --git a/MAINTAINERS b/MAINTAINERS
index 28bd46f4f7a7..d5e4d93a536a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1647,6 +1647,7 @@ C:	irc://chat.freenode.net/asahi-dev
 T:	git https://github.com/AsahiLinux/linux.git
 F:	Documentation/devicetree/bindings/arm/apple.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
+F:	arch/arm64/boot/dts/apple/
 F:	arch/arm64/include/asm/sysreg_apple.h
 F:	drivers/irqchip/irq-apple-aic.c
 F:	include/dt-bindings/interrupt-controller/apple-aic.h
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index f1173cd93594..639e01a4d855 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -6,6 +6,7 @@ subdir-y += amazon
 subdir-y += amd
 subdir-y += amlogic
 subdir-y += apm
+subdir-y += apple
 subdir-y += arm
 subdir-y += bitmain
 subdir-y += broadcom
diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
new file mode 100644
index 000000000000..cbbd701ebf05
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_APPLE) += t8103-j274.dtb
diff --git a/arch/arm64/boot/dts/apple/t8103-j274.dts b/arch/arm64/boot/dts/apple/t8103-j274.dts
new file mode 100644
index 000000000000..8afc2ed70361
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8103-j274.dts
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple Mac mini (M1, 2020)
+ *
+ * target-type: J174
+ *
+ * Copyright The Asahi Linux Contributors
+ */
+
+/dts-v1/;
+
+#include "t8103.dtsi"
+
+/ {
+	compatible = "apple,j274", "apple,t8103", "apple,arm-platform";
+	model = "Apple Mac mini (M1, 2020)";
+
+	aliases {
+		serial0 = &serial0;
+	};
+
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		stdout-path = "serial0";
+
+		framebuffer0: framebuffer@0 {
+			compatible = "apple,simple-framebuffer", "simple-framebuffer";
+			reg = <0 0 0 0>; /* To be filled by loader */
+			/* Format properties will be added by loader */
+			status = "disabled";
+		};
+	};
+
+	memory@800000000 {
+		device_type = "memory";
+		reg = <0x8 0 0x2 0>; /* To be filled by loader */
+	};
+};
+
+&serial0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
new file mode 100644
index 000000000000..aac9e4e6abc5
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T8103 "M1" SoC
+ *
+ * Other names: H13G, "Tonga"
+ *
+ * Copyright The Asahi Linux Contributors
+ */
+
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	compatible = "apple,t8103", "apple,arm-platform";
+
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			compatible = "apple,icestorm";
+			device_type = "cpu";
+			reg = <0x0 0x0>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+		};
+
+		cpu1: cpu@1 {
+			compatible = "apple,icestorm";
+			device_type = "cpu";
+			reg = <0x0 0x1>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+		};
+
+		cpu2: cpu@2 {
+			compatible = "apple,icestorm";
+			device_type = "cpu";
+			reg = <0x0 0x2>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+		};
+
+		cpu3: cpu@3 {
+			compatible = "apple,icestorm";
+			device_type = "cpu";
+			reg = <0x0 0x3>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+		};
+
+		cpu4: cpu@10100 {
+			compatible = "apple,firestorm";
+			device_type = "cpu";
+			reg = <0x0 0x10100>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+		};
+
+		cpu5: cpu@10101 {
+			compatible = "apple,firestorm";
+			device_type = "cpu";
+			reg = <0x0 0x10101>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+		};
+
+		cpu6: cpu@10102 {
+			compatible = "apple,firestorm";
+			device_type = "cpu";
+			reg = <0x0 0x10102>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+		};
+
+		cpu7: cpu@10103 {
+			compatible = "apple,firestorm";
+			device_type = "cpu";
+			reg = <0x0 0x10103>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&aic>;
+		interrupt-names = "hyp-phys", "hyp-virt", "phys", "virt";
+		interrupts = <AIC_FIQ AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>,
+			     <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>,
+			     <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>,
+			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	clk24: clock-24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "clk24";
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges;
+		nonposted-mmio;
+
+		aic: interrupt-controller@23b100000 {
+			compatible = "apple,t8103-aic", "apple,aic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x2 0x3b100000 0x0 0x8000>;
+		};
+
+		serial0: serial@235200000 {
+			compatible = "apple,s5l-uart";
+			reg = <0x2 0x35200000 0x0 0x1000>;
+			reg-io-width = <4>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 605 IRQ_TYPE_LEVEL_HIGH>;
+			/*
+			 * TODO: figure out the clocking properly, there may
+			 * be a third selectable clock.
+			 */
+			clocks = <&clk24>, <&clk24>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+	};
+};
-- 
2.30.0


^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up
  2021-03-04 21:38 [RFT PATCH v3 00/27] Apple M1 SoC platform bring-up Hector Martin
                   ` (26 preceding siblings ...)
  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 10:11 ` Hector Martin
  27 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-05 10:11 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On 05/03/2021 06.38, Hector Martin wrote:
> == Merge notes ==
> 
> This patchset depends on both the nVHE changes that are already in
> 5.12-rc1, as well as the FIQ support work currently being reviewed
> at [1]. A tree containing this patchset on top of the required
> dependencies is available at [2][3]. Alternatively, you may apply
> this series on top of Mark's tree at the arm64-fiq-20210302 tag [4][5].

Important warning: these trees are all based on v5.12-rc1, which has a 
bad bug that causes your filesystems to go kaboom if you use a swap file 
[1].

This doesn't affect M1 since we don't *have* storage, but for folks 
testing for regressions on on e.g. Samsung or other ARM boards, please 
make sure you don't use swap files.

[1] 
https://lore.kernel.org/lkml/CAHk-=wjnzdLSP3oDxhf9eMTYo7GF-QjaNLBUH1Zk3c4A7X75YA@mail.gmail.com/

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 03/27] dt-bindings: arm: apple: Add bindings for Apple ARM platforms
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Linus Walleij @ 2021-03-05 10:16 UTC (permalink / raw)
  To: Hector Martin
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On Thu, Mar 4, 2021 at 10:39 PM Hector Martin <marcan@marcan.st> wrote:

> This introduces bindings for all three 2020 Apple M1 devices:
>
> * apple,j274 - Mac mini (M1, 2020)
> * apple,j293 - MacBook Pro (13-inch, M1, 2020)
> * apple,j313 - MacBook Air (M1, 2020)
>
> Signed-off-by: Hector Martin <marcan@marcan.st>

This way of specifying the SoC makes sense to me.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support
  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
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 136+ messages in thread
From: Linus Walleij @ 2021-03-05 10:18 UTC (permalink / raw)
  To: Hector Martin
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On Thu, Mar 4, 2021 at 10:40 PM Hector Martin <marcan@marcan.st> wrote:

> Not all platforms provide the same set of timers/interrupts, and Linux
> only needs one (plus kvm/guest ones); some platforms are working around
> this by using dummy fake interrupts. Implementing interrupt-names allows
> the devicetree to specify an arbitrary set of available interrupts, so
> the timer code can pick the right one.
>
> This also adds the hyp-virt timer/interrupt, which was previously not
> expressed in the fixed 4-interrupt form.
>
> Signed-off-by: Hector Martin <marcan@marcan.st>

This looks good to me.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 07/27] arm64: arch_timer: implement support for interrupt-names
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Linus Walleij @ 2021-03-05 10:19 UTC (permalink / raw)
  To: Hector Martin
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On Thu, Mar 4, 2021 at 10:40 PM Hector Martin <marcan@marcan.st> wrote:

> This allows the devicetree to correctly represent the available set of
> timers, which varies from device to device, without the need for fake
> dummy interrupts for unavailable slots.
>
> Also add the hyp-virt timer/PPI, which is not currently used, but worth
> representing.
>
> Signed-off-by: Hector Martin <marcan@marcan.st>
> Reviewed-by: Tony Lindgren <tony@atomide.com>

This is the right solution.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 09/27] docs: driver-api: device-io: Document I/O access functions
  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
  0 siblings, 0 replies; 136+ messages in thread
From: Linus Walleij @ 2021-03-05 10:22 UTC (permalink / raw)
  To: Hector Martin
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel, Arnd Bergmann

On Thu, Mar 4, 2021 at 10:40 PM Hector Martin <marcan@marcan.st> wrote:

> From: Arnd Bergmann <arnd@arndb.de>
>
> This adds more detailed descriptions of the various read/write
> primitives available for use with I/O memory/ports.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Hector Martin <marcan@marcan.st>

Excellent work!
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs
  2021-03-04 21:38 ` [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs Hector Martin
@ 2021-03-05 10:25   ` Linus Walleij
  2021-03-05 15:09     ` Andy Shevchenko
  0 siblings, 1 reply; 136+ messages in thread
From: Linus Walleij @ 2021-03-05 10:25 UTC (permalink / raw)
  To: Hector Martin
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On Thu, Mar 4, 2021 at 10:40 PM Hector Martin <marcan@marcan.st> wrote:

> 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>

I like this, I just want one change:

Put the common ioremap() on top in all paragraphs, so the norm
comes before the exceptions.

I.e. it is weird to mention ioremap_np() before mentioning ioremap().

With that change:
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  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 17:39   ` Rob Herring
  2 siblings, 0 replies; 136+ messages in thread
From: Linus Walleij @ 2021-03-05 10:28 UTC (permalink / raw)
  To: Hector Martin
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On Thu, Mar 4, 2021 at 10:40 PM Hector Martin <marcan@marcan.st> wrote:

> This implements the 'nonposted-mmio' and 'posted-mmio' boolean
> properties. Placing these properties in a bus marks all child devices as
> requiring non-posted or posted MMIO mappings. If no such properties are
> found, the default is posted MMIO.
>
> of_mmio_is_nonposted() performs the tree walking to determine if a given
> device has requested non-posted MMIO.
>
> of_address_to_resource() uses this to set the IORESOURCE_MEM_NONPOSTED
> flag on resources that require non-posted MMIO.
>
> of_iomap() and of_io_request_and_map() then use this flag to pick the
> correct ioremap() variant.
>
> This mechanism is currently restricted to Apple ARM platforms, as an
> optimization.
>
> Signed-off-by: Hector Martin <marcan@marcan.st>

This is fine with me atleast given that the nonposted IO is acceptable.
Caching the quirk state in a static local is maybe a bit overoptimized
but if the compiler can't see it but we can, why not.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 18/27] tty: serial: samsung_tty: Separate S3C64XX ops structure
  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
  0 siblings, 0 replies; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-05 10:30 UTC (permalink / raw)
  To: Hector Martin, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel

On 04/03/2021 22:38, Hector Martin wrote:
> Instead of patching a single global ops structure depending on the port
> type, use a separate s3c64xx_serial_ops for the S3C64XX type. This
> allows us to mark the structures as const.
> 
> Also split out s3c64xx_serial_shutdown into a separate function now that
> we have a separate ops structure; this avoids excessive branching
> control flow and mirrors s3c64xx_serial_startup. tx_claimed and
> rx_claimed are only used in the S3C24XX functions.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/tty/serial/samsung_tty.c | 71 ++++++++++++++++++++++++--------
>  1 file changed, 54 insertions(+), 17 deletions(-)


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 19/27] tty: serial: samsung_tty: Add ucon_mask parameter
  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
  0 siblings, 0 replies; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-05 10:34 UTC (permalink / raw)
  To: Hector Martin, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel

On 04/03/2021 22:38, Hector Martin wrote:
> This simplifies the code by removing the only distinction between the
> S3C2410 and S3C2440 codepaths.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/tty/serial/samsung_tty.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> index 78dc6e9240fb..33b421dbeb83 100644
> --- a/drivers/tty/serial/samsung_tty.c
> +++ b/drivers/tty/serial/samsung_tty.c
> @@ -70,6 +70,7 @@ struct s3c24xx_uart_info {
>  	unsigned long		num_clks;
>  	unsigned long		clksel_mask;
>  	unsigned long		clksel_shift;
> +	unsigned long		ucon_mask;
>  
>  	/* uart port features */
>  
> @@ -1736,14 +1737,9 @@ static void s3c24xx_serial_resetport(struct uart_port *port,
>  {
>  	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
>  	unsigned long ucon = rd_regl(port, S3C2410_UCON);
> -	unsigned int ucon_mask;
>  
> -	ucon_mask = info->clksel_mask;
> -	if (info->type == PORT_S3C2440)
> -		ucon_mask |= S3C2440_UCON0_DIVMASK;
> -
> -	ucon &= ucon_mask;
> -	wr_regl(port, S3C2410_UCON,  ucon | cfg->ucon);
> +	ucon &= (info->clksel_mask | info->ucon_mask);
> +	wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);

This line (wr_regl()) is not related, please split it to separate
white-space cleanups.

With the change:

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 20/27] tty: serial: samsung_tty: Add s3c24xx_port_type
  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
  0 siblings, 0 replies; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-05 10:49 UTC (permalink / raw)
  To: Hector Martin, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel


On 04/03/2021 22:38, Hector Martin wrote:
> This decouples the TTY layer PORT_ types, which are exposed to
> userspace, from the driver-internal flag of what kind of port this is.

s/This decouples/Decouple

> 
> This removes s3c24xx_serial_has_interrupt_mask, which was just checking

s/This removes/Remove/

https://elixir.bootlin.com/linux/latest/source/Documentation/process/submitting-patches.rst#L89

This actually also applies to your patch 19 and 21... and maybe more.

> for a specific type anyway.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/tty/serial/samsung_tty.c | 112 +++++++++++++++++++------------
>  1 file changed, 70 insertions(+), 42 deletions(-)
> 
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-05 10:51 UTC (permalink / raw)
  To: Hector Martin, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel

On 04/03/2021 22:38, Hector Martin wrote:
> * Split out s3c24xx_serial_tx_chars from s3c24xx_serial_tx_irq,
>   where only the latter acquires the port lock. This will be necessary
>   on platforms which have edge-triggered IRQs, as we need to call
>   s3c24xx_serial_tx_chars to kick off transmission from outside IRQ
>   context, with the port lock held.
> 
> * Rename s3c24xx_serial_rx_chars to s3c24xx_serial_rx_irq for
>   consistency with the above. All it does now is call two other
>   functions anyway.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/tty/serial/samsung_tty.c | 34 +++++++++++++++++++-------------
>  1 file changed, 20 insertions(+), 14 deletions(-)
> 

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 22/27] tty: serial: samsung_tty: Use devm_ioremap_resource
  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
  0 siblings, 1 reply; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-05 10:54 UTC (permalink / raw)
  To: Hector Martin, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel

On 04/03/2021 22:38, Hector Martin wrote:
> This picks up the non-posted I/O mode needed for Apple platforms to
> work properly.
> 
> This removes the request/release functions, which are no longer
> necessary, since devm_ioremap_resource takes care of that already. Most
> other drivers already do it this way, anyway.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/tty/serial/samsung_tty.c | 25 +++----------------------
>  1 file changed, 3 insertions(+), 22 deletions(-)

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 25/27] tty: serial: samsung_tty: Add earlycon support for Apple UARTs
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-05 10:55 UTC (permalink / raw)
  To: Hector Martin, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel, Arnd Bergmann

On 04/03/2021 22:39, Hector Martin wrote:
> Earlycon support is identical to S3C2410, but Apple SoCs also need
> MMIO mapped as nGnRnE. This is handled generically for normal drivers
> including the normal UART path here, but earlycon uses fixmap and
> runs before that scaffolding is ready.
> 
> Since this is the only case where we need this fix, it makes more
> sense to do it here in the UART driver instead of introducing a
> whole fdt nonposted-mmio resolver just for earlycon/fixmap.
> 
> Suggested-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/tty/serial/samsung_tty.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 24/27] tty: serial: samsung_tty: Add support for Apple UARTs
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-05 10:58 UTC (permalink / raw)
  To: Hector Martin, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel

On 04/03/2021 22:38, Hector Martin wrote:
> Apple SoCs are a distant descendant of Samsung designs and use yet
> another variant of their UART style, with different interrupt handling.
> 
> In particular, this variant has the following differences with existing
> ones:
> 
> * It includes a built-in interrupt controller with different registers,
>   using only a single platform IRQ
> 
> * Internal interrupt sources are treated as edge-triggered, even though
>   the IRQ output is level-triggered. This chiefly affects the TX IRQ
>   path: the driver can no longer rely on the TX buffer empty IRQ
>   immediately firing after TX is enabled, but instead must prime the
>   FIFO with data directly.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/tty/serial/Kconfig       |   2 +-
>  drivers/tty/serial/samsung_tty.c | 238 +++++++++++++++++++++++++++++--
>  include/linux/serial_s3c.h       |  16 +++
>  3 files changed, 247 insertions(+), 9 deletions(-)
> 

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 27/27] arm64: apple: Add initial Apple Mac mini (M1, 2020) devicetree
  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
  0 siblings, 1 reply; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-05 11:03 UTC (permalink / raw)
  To: Hector Martin, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel

On 04/03/2021 22:39, Hector Martin wrote:
> This currently supports:
> 
> * SMP (via spin-tables)
> * AIC IRQs
> * Serial (with earlycon)
> * Framebuffer
> 
> A number of properties are dynamic, and based on system firmware
> decisions that vary from version to version. These are expected
> to be filled in by the loader.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  MAINTAINERS                              |   1 +
>  arch/arm64/boot/dts/Makefile             |   1 +
>  arch/arm64/boot/dts/apple/Makefile       |   2 +
>  arch/arm64/boot/dts/apple/t8103-j274.dts |  45 ++++++++
>  arch/arm64/boot/dts/apple/t8103.dtsi     | 135 +++++++++++++++++++++++
>  5 files changed, 184 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/apple/Makefile
>  create mode 100644 arch/arm64/boot/dts/apple/t8103-j274.dts
>  create mode 100644 arch/arm64/boot/dts/apple/t8103.dtsi
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 28bd46f4f7a7..d5e4d93a536a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1647,6 +1647,7 @@ C:	irc://chat.freenode.net/asahi-dev
>  T:	git https://github.com/AsahiLinux/linux.git
>  F:	Documentation/devicetree/bindings/arm/apple.yaml
>  F:	Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
> +F:	arch/arm64/boot/dts/apple/
>  F:	arch/arm64/include/asm/sysreg_apple.h
>  F:	drivers/irqchip/irq-apple-aic.c
>  F:	include/dt-bindings/interrupt-controller/apple-aic.h
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index f1173cd93594..639e01a4d855 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -6,6 +6,7 @@ subdir-y += amazon
>  subdir-y += amd
>  subdir-y += amlogic
>  subdir-y += apm
> +subdir-y += apple
>  subdir-y += arm
>  subdir-y += bitmain
>  subdir-y += broadcom
> diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
> new file mode 100644
> index 000000000000..cbbd701ebf05
> --- /dev/null
> +++ b/arch/arm64/boot/dts/apple/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_ARCH_APPLE) += t8103-j274.dtb
> diff --git a/arch/arm64/boot/dts/apple/t8103-j274.dts b/arch/arm64/boot/dts/apple/t8103-j274.dts
> new file mode 100644
> index 000000000000..8afc2ed70361
> --- /dev/null
> +++ b/arch/arm64/boot/dts/apple/t8103-j274.dts
> @@ -0,0 +1,45 @@
> +// SPDX-License-Identifier: GPL-2.0+ OR MIT
> +/*
> + * Apple Mac mini (M1, 2020)
> + *
> + * target-type: J174
> + *
> + * Copyright The Asahi Linux Contributors
> + */
> +
> +/dts-v1/;
> +
> +#include "t8103.dtsi"
> +
> +/ {
> +	compatible = "apple,j274", "apple,t8103", "apple,arm-platform";
> +	model = "Apple Mac mini (M1, 2020)";
> +
> +	aliases {
> +		serial0 = &serial0;
> +	};
> +
> +	chosen {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		stdout-path = "serial0";
> +
> +		framebuffer0: framebuffer@0 {
> +			compatible = "apple,simple-framebuffer", "simple-framebuffer";
> +			reg = <0 0 0 0>; /* To be filled by loader */
> +			/* Format properties will be added by loader */
> +			status = "disabled";
> +		};
> +	};
> +
> +	memory@800000000 {
> +		device_type = "memory";
> +		reg = <0x8 0 0x2 0>; /* To be filled by loader */

Shouldn't this be 0x800000000 with ~0x80000000 length (or whatever is
more common)? Or did I miss some ranges?

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 27/27] arm64: apple: Add initial Apple Mac mini (M1, 2020) devicetree
  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
  0 siblings, 2 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-05 11:14 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel

On 05/03/2021 20.03, Krzysztof Kozlowski wrote:
>> +	memory@800000000 {
>> +		device_type = "memory";
>> +		reg = <0x8 0 0x2 0>; /* To be filled by loader */
> 
> Shouldn't this be 0x800000000 with ~0x80000000 length (or whatever is
> more common)? Or did I miss some ranges?

The base model has 8GB of RAM, and RAM always starts at 0x800000000, 
hence that reg property.

It's not actually useful to try to boot Linux like this, because it'll 
step all over device carveouts on both ends and break, but since those 
are potentially dynamic it doesn't really make sense to use a more 
specific example for the dts.

E.g. on my system, with my current firmware version, this ends up 
getting patched to:

reg = <0x8 0x0134c000 0x1 0xda294000>

Thanks,
-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 27/27] arm64: apple: Add initial Apple Mac mini (M1, 2020) devicetree
  2021-03-05 11:14     ` Hector Martin
@ 2021-03-05 11:45       ` Krzysztof Kozlowski
  2021-03-05 15:59       ` Mark Kettenis
  1 sibling, 0 replies; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-05 11:45 UTC (permalink / raw)
  To: Hector Martin, linux-arm-kernel
  Cc: Marc Zyngier, Rob Herring, Arnd Bergmann, Olof Johansson,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Andy Shevchenko, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	linux-serial, linux-doc, linux-samsung-soc, linux-arch,
	linux-kernel

On 05/03/2021 12:14, Hector Martin wrote:
> On 05/03/2021 20.03, Krzysztof Kozlowski wrote:
>>> +	memory@800000000 {
>>> +		device_type = "memory";
>>> +		reg = <0x8 0 0x2 0>; /* To be filled by loader */
>>
>> Shouldn't this be 0x800000000 with ~0x80000000 length (or whatever is
>> more common)? Or did I miss some ranges?
> 
> The base model has 8GB of RAM, and RAM always starts at 0x800000000, 
> hence that reg property.

Ah, I messed up the unit addressing and number of zeros... it's OK.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 08/27] asm-generic/io.h: Add a non-posted variant of ioremap()
  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
  2 siblings, 1 reply; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-05 14:45 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On Thu, Mar 4, 2021 at 11:40 PM Hector Martin <marcan@marcan.st> wrote:
>
> ARM64 currently defaults to posted MMIO (nGnRnE), but some devices
> require the use of non-posted MMIO (nGnRE). Introduce a new ioremap()
> variant to handle this case. ioremap_np() is aliased to ioremap() by
> default on arches that do not implement this variant.

Hmm... But isn't it basically a requirement to those device drivers to
use readX()/writeX() instead of readX_relaxed() / writeX_relaxed()?

...

>  #define IORESOURCE_MEM_32BIT           (3<<3)
>  #define IORESOURCE_MEM_SHADOWABLE      (1<<5)  /* dup: IORESOURCE_SHADOWABLE */
>  #define IORESOURCE_MEM_EXPANSIONROM    (1<<6)
> +#define IORESOURCE_MEM_NONPOSTED       (1<<7)

Not sure it's the right location (in a bit field) for this flag.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  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-26 13:40     ` Hector Martin
  2021-03-08 13:31   ` Marc Zyngier
  2021-03-24 19:57   ` Will Deacon
  2 siblings, 2 replies; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-05 15:05 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On Thu, Mar 4, 2021 at 11:41 PM Hector Martin <marcan@marcan.st> wrote:
>
> This is the root interrupt controller used on Apple ARM SoCs such as the
> M1. This irqchip driver performs multiple functions:
>
> * Handles both IRQs and FIQs
>
> * Drives the AIC peripheral itself (which handles IRQs)
>
> * Dispatches FIQs to downstream hard-wired clients (currently the ARM
>   timer).
>
> * Implements a virtual IPI multiplexer to funnel multiple Linux IPIs
>   into a single hardware IPI

...

> + *   - <0 nr flags> - hwirq #nr
> + *   - <1 nr flags> - FIQ #nr
> + *     - nr=0  Physical HV timer
> + *     - nr=1  Virtual HV timer
> + *     - nr=2  Physical guest timer
> + *     - nr=3  Virtual guest timer

> + *

Unneeded blank line.

> + */

...

> +#define pr_fmt(fmt) "%s: " fmt, __func__

This is not needed, really, if you have unique / distinguishable
messages in the first place.
Rather people include module names, which may be useful.

...

> +#define MASK_REG(x)            (4 * ((x) >> 5))
> +#define MASK_BIT(x)            BIT((x) & 0x1f)

GENMASK(4,0)

...

> +/*
> + * Max 31 bits in IPI SEND register (top bit is self).
> + * >=32-core chips will need code changes anyway.
> + */
> +#define AIC_MAX_CPUS           31

I would put it as (32 - 1) to show that the register is actually 32-bit long.

...

> +static atomic_t aic_vipi_flag[AIC_MAX_CPUS];
> +static atomic_t aic_vipi_enable[AIC_MAX_CPUS];

Isn't it easier to handle these when they are full width, i.e. 32
items per the array?

...

> +static int aic_irq_set_affinity(struct irq_data *d,
> +                               const struct cpumask *mask_val, bool force)
> +{
> +       irq_hw_number_t hwirq = irqd_to_hwirq(d);
> +       struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
> +       int cpu;
> +
> +       if (hwirq > ic->nr_hw)

>= ?

> +               return -EINVAL;
> +
> +       if (force)
> +               cpu = cpumask_first(mask_val);
> +       else
> +               cpu = cpumask_any_and(mask_val, cpu_online_mask);
> +
> +       aic_ic_write(ic, AIC_TARGET_CPU + hwirq * 4, BIT(cpu));
> +       irq_data_update_effective_affinity(d, cpumask_of(cpu));
> +
> +       return IRQ_SET_MASK_OK;
> +}

...

> +static void aic_fiq_mask(struct irq_data *d)
> +{
> +       /* Only the guest timers have real mask bits, unfortunately. */
> +       switch (d->hwirq) {
> +       case AIC_TMR_GUEST_PHYS:
> +               sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, VM_TMR_FIQ_ENABLE_P, 0);
> +               break;
> +       case AIC_TMR_GUEST_VIRT:
> +               sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, VM_TMR_FIQ_ENABLE_V, 0);
> +               break;

default case? // some compilers may not be happy
Ditto for all similar places in the series.

> +       }
> +}

...

> +#define TIMER_FIRING(x)                                                        \
> +       (((x) & (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_MASK |            \
> +                ARCH_TIMER_CTRL_IT_STAT)) ==                                  \
> +        (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT))

It's a bit hard to read. Perhaps

#define FOO_MASK  (_ENABLE | _STAT)
#define _FIRING ... (FOO_MASK | _MASK == FOO_MASK)

?

...

> +       if ((read_sysreg_s(SYS_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT))
> +                       == (FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) {

It's better to have == on the previous line.

...

> +       for_each_set_bit(i, &firing, AIC_NR_SWIPI) {
> +               handle_domain_irq(aic_irqc->ipi_domain, i, regs);
> +       }

No {} needed.

...

> +static int aic_init_smp(struct aic_irq_chip *irqc, struct device_node *node)
> +{
> +       int base_ipi;

Introducing a temporary variable may help with readability

...  *d = irqc->hw_domain;

> +       irqc->ipi_domain = irq_domain_create_linear(irqc->hw_domain->fwnode, AIC_NR_SWIPI,
> +                                                   &aic_ipi_domain_ops, irqc);
> +       if (WARN_ON(!irqc->ipi_domain))
> +               return -ENODEV;
> +
> +       irqc->ipi_domain->flags |= IRQ_DOMAIN_FLAG_IPI_SINGLE;
> +       irq_domain_update_bus_token(irqc->ipi_domain, DOMAIN_BUS_IPI);
> +
> +       base_ipi = __irq_domain_alloc_irqs(irqc->ipi_domain, -1, AIC_NR_SWIPI,
> +                                          NUMA_NO_NODE, NULL, false, NULL);
> +
> +       if (WARN_ON(!base_ipi)) {
> +               irq_domain_remove(irqc->ipi_domain);
> +               return -ENODEV;
> +       }
> +
> +       set_smp_ipi_range(base_ipi, AIC_NR_SWIPI);
> +
> +       return 0;
> +}

...

> +       return 0;
> +

Extra blank line.

...

> +       irqc->hw_domain = irq_domain_create_linear(of_node_to_fwnode(node),
> +                                                  irqc->nr_hw + AIC_NR_FIQ,
> +                                                  &aic_irq_domain_ops, irqc);

If you are sure it will be always OF-only, why not to use
irq_domain_add_linear()?

...

> +       for (i = 0; i < BITS_TO_U32(irqc->nr_hw); i++)
> +               aic_ic_write(irqc, AIC_MASK_SET + i * 4, ~0);
> +       for (i = 0; i < BITS_TO_U32(irqc->nr_hw); i++)
> +               aic_ic_write(irqc, AIC_SW_CLR + i * 4, ~0);

~0 is a beast when it suddenly gets into > int size.

I would recommend using either GENMASK() if it's a bit field, or
type_MAX values if it's a plain number.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs
  2021-03-05 10:25   ` Linus Walleij
@ 2021-03-05 15:09     ` Andy Shevchenko
  2021-03-05 15:51       ` Arnd Bergmann
  0 siblings, 1 reply; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-05 15:09 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Hector Martin, Linux ARM, Marc Zyngier, Rob Herring,
	Arnd Bergmann, Olof Johansson, Krzysztof Kozlowski,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On Fri, Mar 5, 2021 at 12:25 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> On Thu, Mar 4, 2021 at 10:40 PM Hector Martin <marcan@marcan.st> wrote:
>
> > 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>
>
> I like this, I just want one change:
>
> Put the common ioremap() on top in all paragraphs, so the norm
> comes before the exceptions.
>
> I.e. it is weird to mention ioremap_np() before mentioning ioremap().

+1 here. That is what I have stumbled upon reading carefully.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  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:05     ` Rob Herring
  2021-03-05 17:39   ` Rob Herring
  2 siblings, 2 replies; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-05 15:13 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On Thu, Mar 4, 2021 at 11:40 PM Hector Martin <marcan@marcan.st> wrote:
>
> This implements the 'nonposted-mmio' and 'posted-mmio' boolean
> properties. Placing these properties in a bus marks all child devices as
> requiring non-posted or posted MMIO mappings. If no such properties are
> found, the default is posted MMIO.
>
> of_mmio_is_nonposted() performs the tree walking to determine if a given
> device has requested non-posted MMIO.
>
> of_address_to_resource() uses this to set the IORESOURCE_MEM_NONPOSTED
> flag on resources that require non-posted MMIO.
>
> of_iomap() and of_io_request_and_map() then use this flag to pick the
> correct ioremap() variant.
>
> This mechanism is currently restricted to Apple ARM platforms, as an
> optimization.

...

> @@ -896,7 +899,10 @@ void __iomem *of_iomap(struct device_node *np, int index)
>         if (of_address_to_resource(np, index, &res))
>                 return NULL;
>
> -       return ioremap(res.start, resource_size(&res));
> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> +               return ioremap_np(res.start, resource_size(&res));
> +       else
> +               return ioremap(res.start, resource_size(&res));

This doesn't sound right. Why _np is so exceptional? Why don't we have
other flavours (it also rings a bell to my previous comment that the
flag in ioresource is not in the right place)?

...

> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> +               mem = ioremap_np(res.start, resource_size(&res));
> +       else
> +               mem = ioremap(res.start, resource_size(&res));
> +

Ditto.

...

> +       while (node) {
> +               if (!of_property_read_bool(node, "ranges")) {
> +                       break;
> +               } else if (of_property_read_bool(node, "nonposted-mmio")) {
> +                       of_node_put(node);
> +                       return true;
> +               } else if (of_property_read_bool(node, "posted-mmio")) {
> +                       break;
> +               }
> +               parent = of_get_parent(node);
> +               of_node_put(node);
> +               node = parent;
> +       }

I believe above can be slightly optimized. Don't we have helpers to
traverse to all parents?

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework
  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
  1 sibling, 1 reply; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-05 15:17 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On Thu, Mar 4, 2021 at 11:41 PM Hector Martin <marcan@marcan.st> wrote:
>
> * Split out s3c24xx_serial_tx_chars from s3c24xx_serial_tx_irq,
>   where only the latter acquires the port lock. This will be necessary
>   on platforms which have edge-triggered IRQs, as we need to call
>   s3c24xx_serial_tx_chars to kick off transmission from outside IRQ
>   context, with the port lock held.
>
> * Rename s3c24xx_serial_rx_chars to s3c24xx_serial_rx_irq for
>   consistency with the above. All it does now is call two other
>   functions anyway.
>
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/tty/serial/samsung_tty.c | 34 +++++++++++++++++++-------------
>  1 file changed, 20 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> index 39b2eb165bdc..7106eb238d8c 100644
> --- a/drivers/tty/serial/samsung_tty.c
> +++ b/drivers/tty/serial/samsung_tty.c
> @@ -827,7 +827,7 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id)
>         return IRQ_HANDLED;
>  }
>
> -static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
> +static irqreturn_t s3c24xx_serial_rx_irq(int irq, void *dev_id)
>  {
>         struct s3c24xx_uart_port *ourport = dev_id;
>
> @@ -836,16 +836,12 @@ static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
>         return s3c24xx_serial_rx_chars_pio(dev_id);
>  }
>
> -static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
> +static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
>  {
> -       struct s3c24xx_uart_port *ourport = id;
>         struct uart_port *port = &ourport->port;
>         struct circ_buf *xmit = &port->state->xmit;
> -       unsigned long flags;
>         int count, dma_count = 0;
>
> -       spin_lock_irqsave(&port->lock, flags);
> -
>         count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
>
>         if (ourport->dma && ourport->dma->tx_chan &&
> @@ -862,7 +858,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>                 wr_reg(port, S3C2410_UTXH, port->x_char);
>                 port->icount.tx++;
>                 port->x_char = 0;
> -               goto out;
> +               return;
>         }
>
>         /* if there isn't anything more to transmit, or the uart is now
> @@ -871,7 +867,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>
>         if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
>                 s3c24xx_serial_stop_tx(port);
> -               goto out;
> +               return;
>         }
>
>         /* try and drain the buffer... */
> @@ -893,7 +889,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>
>         if (!count && dma_count) {
>                 s3c24xx_serial_start_tx_dma(ourport, dma_count);
> -               goto out;
> +               return;
>         }
>
>         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
> @@ -904,8 +900,18 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>
>         if (uart_circ_empty(xmit))
>                 s3c24xx_serial_stop_tx(port);
> +}
> +
> +static irqreturn_t s3c24xx_serial_tx_irq(int irq, void *id)
> +{
> +       struct s3c24xx_uart_port *ourport = id;
> +       struct uart_port *port = &ourport->port;
> +       unsigned long flags;
> +


> +       spin_lock_irqsave(&port->lock, flags);
> +
> +       s3c24xx_serial_tx_chars(ourport);
>
> -out:
>         spin_unlock_irqrestore(&port->lock, flags);

Add a separate change that removes flags from the spin lock in the IRQ handler.

>         return IRQ_HANDLED;
>  }
> @@ -919,11 +925,11 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
>         irqreturn_t ret = IRQ_HANDLED;
>
>         if (pend & S3C64XX_UINTM_RXD_MSK) {
> -               ret = s3c24xx_serial_rx_chars(irq, id);
> +               ret = s3c24xx_serial_rx_irq(irq, id);
>                 wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
>         }
>         if (pend & S3C64XX_UINTM_TXD_MSK) {
> -               ret = s3c24xx_serial_tx_chars(irq, id);
> +               ret = s3c24xx_serial_tx_irq(irq, id);
>                 wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
>         }
>         return ret;
> @@ -1155,7 +1161,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
>
>         ourport->rx_enabled = 1;
>
> -       ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
> +       ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_irq, 0,
>                           s3c24xx_serial_portname(port), ourport);
>
>         if (ret != 0) {
> @@ -1169,7 +1175,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
>
>         ourport->tx_enabled = 1;
>
> -       ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
> +       ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_irq, 0,
>                           s3c24xx_serial_portname(port), ourport);
>
>         if (ret) {
> --
> 2.30.0
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 22/27] tty: serial: samsung_tty: Use devm_ioremap_resource
  2021-03-05 10:54   ` Krzysztof Kozlowski
@ 2021-03-05 15:19     ` Andy Shevchenko
  0 siblings, 0 replies; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-05 15:19 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Hector Martin, linux-arm Mailing List, Marc Zyngier, Rob Herring,
	Arnd Bergmann, Olof Johansson, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	open list:SERIAL DRIVERS, Linux Documentation List,
	Linux Samsung SOC, Linux-Arch, Linux Kernel Mailing List

On Fri, Mar 5, 2021 at 12:55 PM Krzysztof Kozlowski
<krzysztof.kozlowski@canonical.com> wrote:
>
> On 04/03/2021 22:38, Hector Martin wrote:
> > This picks up the non-posted I/O mode needed for Apple platforms to
> > work properly.
> >
> > This removes the request/release functions, which are no longer
> > necessary, since devm_ioremap_resource takes care of that already. Most
> > other drivers already do it this way, anyway.
> >

For the patches 18-22, with Krzysztof's and mine comments addressed
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> > Signed-off-by: Hector Martin <marcan@marcan.st>
> > ---
> >  drivers/tty/serial/samsung_tty.c | 25 +++----------------------
> >  1 file changed, 3 insertions(+), 22 deletions(-)
>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
> Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
>
> Best regards,
> Krzysztof



-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 08/27] asm-generic/io.h: Add a non-posted variant of ioremap()
  2021-03-05 14:45   ` Andy Shevchenko
@ 2021-03-05 15:19     ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-05 15:19 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On 05/03/2021 23.45, Andy Shevchenko wrote:
> On Thu, Mar 4, 2021 at 11:40 PM Hector Martin <marcan@marcan.st> wrote:
>>
>> ARM64 currently defaults to posted MMIO (nGnRnE), but some devices
>> require the use of non-posted MMIO (nGnRE). Introduce a new ioremap()
>> variant to handle this case. ioremap_np() is aliased to ioremap() by
>> default on arches that do not implement this variant.
> 
> Hmm... But isn't it basically a requirement to those device drivers to
> use readX()/writeX() instead of readX_relaxed() / writeX_relaxed()?

No, the write ops used do not matter. It's just that on these Apple SoCs 
the fabric requires the mappings to be nGnRnE, else it just throws 
SErrors on all writes and ignores them.

The difference between _relaxed and not is barrier behavior with regards 
to DMA/memory accesses; this applies regardless of whether the writes 
are E or nE. You can have relaxed accesses with nGnRnE and then you 
would still have race conditions if you do not have a barrier between 
the MMIO and accessing DMA memory. What nGnRnE buys you (on 
platforms/buses where it works properly) is that you do need a dummy 
read after a write to ensure completion.

All of this is to some extent moot on these SoCs; it's not that we need 
the drivers to use nGnRnE for some correctness reason, it's that the 
SoCs force us to use it or else everything breaks, which was the 
motivation for this change. But since on most other SoCs both are valid 
options, this does allow some other drivers/platforms to opt into nGnRnE 
if they have a good reason to do so.

Though you just made me notice two mistakes in the commit description: 
first, it describes the old v2 version, for v3 I made ioremap_np() just 
return NULL on arches that don't implement it. Second, nGnRnE and nGnRE 
are backwards. Oops. I'll fix it for the next version.

>>   #define IORESOURCE_MEM_32BIT           (3<<3)
>>   #define IORESOURCE_MEM_SHADOWABLE      (1<<5)  /* dup: IORESOURCE_SHADOWABLE */
>>   #define IORESOURCE_MEM_EXPANSIONROM    (1<<6)
>> +#define IORESOURCE_MEM_NONPOSTED       (1<<7)
> 
> Not sure it's the right location (in a bit field) for this flag.

Do you have a better suggestion? It seemed logical to put it here, as a 
flag on memory-type I/O resources.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 24/27] tty: serial: samsung_tty: Add support for Apple UARTs
  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
  1 sibling, 1 reply; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-05 15:28 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On Thu, Mar 4, 2021 at 11:42 PM Hector Martin <marcan@marcan.st> wrote:
>
> Apple SoCs are a distant descendant of Samsung designs and use yet
> another variant of their UART style, with different interrupt handling.
>
> In particular, this variant has the following differences with existing
> ones:
>
> * It includes a built-in interrupt controller with different registers,
>   using only a single platform IRQ
>
> * Internal interrupt sources are treated as edge-triggered, even though
>   the IRQ output is level-triggered. This chiefly affects the TX IRQ
>   path: the driver can no longer rely on the TX buffer empty IRQ
>   immediately firing after TX is enabled, but instead must prime the
>   FIFO with data directly.

...

> +       case TYPE_APPLE_S5L:
> +               WARN_ON(1); // No DMA

Oh, no, please use the ONCE variant.

...

> +       /* Apple types use these bits for IRQ masks */
> +       if (ourport->info->type != TYPE_APPLE_S5L) {
> +               ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
> +                               S3C64XX_UCON_EMPTYINT_EN |
> +                               S3C64XX_UCON_DMASUS_EN |
> +                               S3C64XX_UCON_TIMEOUT_EN);
> +               ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |

Can you spell 0xf with named constant(s), please?

In case they are repetitive via the code, introduce either a temporary
variable (in case it scoped to one function only), or define it as a
constant.

> +                               S3C64XX_UCON_TIMEOUT_EN;
> +       }

...

> +/* interrupt handler for Apple SoC's.*/
> +static irqreturn_t apple_serial_handle_irq(int irq, void *id)
> +{
> +       struct s3c24xx_uart_port *ourport = id;
> +       struct uart_port *port = &ourport->port;
> +       unsigned int pend = rd_regl(port, S3C2410_UTRSTAT);

> +       irqreturn_t ret = IRQ_NONE;

Redundant. You may return directly.

> +
> +       if (pend & (APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO)) {
> +               wr_regl(port, S3C2410_UTRSTAT,
> +                       APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO);
> +               ret = s3c24xx_serial_rx_irq(irq, id);
> +       }
> +       if (pend & APPLE_S5L_UTRSTAT_TXTHRESH) {
> +               wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_TXTHRESH);
> +               ret = s3c24xx_serial_tx_irq(irq, id);
> +       }

No IO serialization?

> +       return ret;
> +}

...

> +static void apple_s5l_serial_shutdown(struct uart_port *port)
> +{
> +       struct s3c24xx_uart_port *ourport = to_ourport(port);

> +

Extra blank line (check your entire series for a such)

> +       unsigned int ucon;

> +       ourport->tx_in_progress = 0;
> +}

...

> +       ourport->rx_enabled = 1;
> +       ourport->tx_enabled = 0;

How are these protected against race?

...

> +               case TYPE_APPLE_S5L: {
> +                       unsigned int ucon;
> +                       int ret;
> +
> +                       ret = clk_prepare_enable(ourport->clk);
> +                       if (ret) {
> +                               dev_err(dev, "clk_enable clk failed: %d\n", ret);
> +                               return ret;
> +                       }
> +                       if (!IS_ERR(ourport->baudclk)) {
> +                               ret = clk_prepare_enable(ourport->baudclk);
> +                               if (ret) {
> +                                       dev_err(dev, "clk_enable baudclk failed: %d\n", ret);
> +                                       clk_disable_unprepare(ourport->clk);
> +                                       return ret;
> +                               }
> +                       }

Wouldn't it be better to use CLK bulk API?

> +                       ucon = rd_regl(port, S3C2410_UCON);
> +
> +                       ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
> +                                 APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
> +                                 APPLE_S5L_UCON_RXTO_ENA_MSK);
> +
> +                       if (ourport->tx_enabled)
> +                               ucon |= APPLE_S5L_UCON_TXTHRESH_ENA_MSK;
> +                       if (ourport->rx_enabled)
> +                               ucon |= APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
> +                                       APPLE_S5L_UCON_RXTO_ENA_MSK;
> +
> +                       wr_regl(port, S3C2410_UCON, ucon);
> +
> +                       if (!IS_ERR(ourport->baudclk))
> +                               clk_disable_unprepare(ourport->baudclk);
> +                       clk_disable_unprepare(ourport->clk);
> +                       break;
> +               }

...

> +#ifdef CONFIG_ARCH_APPLE

Why? Wouldn't you like the one kernel to work on many SoCs?

> +static struct s3c24xx_serial_drv_data s5l_serial_drv_data = {
> +       .info = &(struct s3c24xx_uart_info) {
> +               .name           = "Apple S5L UART",
> +               .type           = TYPE_APPLE_S5L,
> +               .port_type      = PORT_8250,
> +               .fifosize       = 16,
> +               .rx_fifomask    = S3C2410_UFSTAT_RXMASK,
> +               .rx_fifoshift   = S3C2410_UFSTAT_RXSHIFT,
> +               .rx_fifofull    = S3C2410_UFSTAT_RXFULL,
> +               .tx_fifofull    = S3C2410_UFSTAT_TXFULL,
> +               .tx_fifomask    = S3C2410_UFSTAT_TXMASK,
> +               .tx_fifoshift   = S3C2410_UFSTAT_TXSHIFT,
> +               .def_clk_sel    = S3C2410_UCON_CLKSEL0,
> +               .num_clks       = 1,
> +               .clksel_mask    = 0,
> +               .clksel_shift   = 0,
> +       },
> +       .def_cfg = &(struct s3c2410_uartcfg) {
> +               .ucon           = APPLE_S5L_UCON_DEFAULT,
> +               .ufcon          = S3C2410_UFCON_DEFAULT,
> +       },
> +};
> +#define S5L_SERIAL_DRV_DATA ((kernel_ulong_t)&s5l_serial_drv_data)
> +#else
> +#define S5L_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
> +#endif

...

> +#define APPLE_S5L_UCON_RXTO_ENA_MSK    (1 << APPLE_S5L_UCON_RXTO_ENA)
> +#define APPLE_S5L_UCON_RXTHRESH_ENA_MSK        (1 << APPLE_S5L_UCON_RXTHRESH_ENA)
> +#define APPLE_S5L_UCON_TXTHRESH_ENA_MSK        (1 << APPLE_S5L_UCON_TXTHRESH_ENA)

BIT() ?

...

> +#define APPLE_S5L_UCON_DEFAULT         (S3C2410_UCON_TXIRQMODE | \
> +                                        S3C2410_UCON_RXIRQMODE | \
> +                                        S3C2410_UCON_RXFIFO_TOI)

Indentation level is too high. Hint: start a value of the definition
on the new line.

...

> +#define APPLE_S5L_UTRSTAT_RXTHRESH     (1<<4)
> +#define APPLE_S5L_UTRSTAT_TXTHRESH     (1<<5)
> +#define APPLE_S5L_UTRSTAT_RXTO         (1<<9)
> +#define APPLE_S5L_UTRSTAT_ALL_FLAGS    (0x3f0)

BIT() ?

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs
  2021-03-05 15:09     ` Andy Shevchenko
@ 2021-03-05 15:51       ` Arnd Bergmann
  2021-03-09 20:29         ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-05 15:51 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Linus Walleij, Hector Martin, Linux ARM, Marc Zyngier,
	Rob Herring, Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On Fri, Mar 5, 2021 at 4:09 PM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
> On Fri, Mar 5, 2021 at 12:25 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> > On Thu, Mar 4, 2021 at 10:40 PM Hector Martin <marcan@marcan.st> wrote:
> >
> > > 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>
> >
> > I like this, I just want one change:
> >
> > Put the common ioremap() on top in all paragraphs, so the norm
> > comes before the exceptions.
> >
> > I.e. it is weird to mention ioremap_np() before mentioning ioremap().
>
> +1 here. That is what I have stumbled upon reading carefully.

In that case, the order should probably be:

ioremap
ioremap_wc
ioremap_wt
ioremap_np
ioremap_uc
ioremap_cache

Going from most common to least common, rather than going from
strongest to weakest.

       Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  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:05     ` Rob Herring
  1 sibling, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-05 15:55 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On 06/03/2021 00.13, Andy Shevchenko wrote:
>> @@ -896,7 +899,10 @@ void __iomem *of_iomap(struct device_node *np, int index)
>>          if (of_address_to_resource(np, index, &res))
>>                  return NULL;
>>
>> -       return ioremap(res.start, resource_size(&res));
>> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
>> +               return ioremap_np(res.start, resource_size(&res));
>> +       else
>> +               return ioremap(res.start, resource_size(&res));
> 
> This doesn't sound right. Why _np is so exceptional? Why don't we have
> other flavours (it also rings a bell to my previous comment that the
> flag in ioresource is not in the right place)?

This is different from other variants, because until now *drivers* have 
made the choice of what ioremap mode to use based on device requirements 
(which means ioremap() 99% of the time, and then framebuffers and other 
memory-ish things such use something else). Now we have a *SoC fabric* 
that is calling the shots on what ioremap mode we have to use - and 
*every* non-PCIe driver needs to use ioremap_np() on these SoCs, or they 
break. So it seems a lot cleaner to make the choice for drivers here to 
upgrade ioremap() to ioremap_np() for SoCs that need it.

If we don't do something like this here or in otherwise common code, 
we'd have to have an open-coded "if apple then ioremap_np, else ioremap" 
in every driver that runs on-die devices on these SoCs, even ones that 
are otherwise standard and need few or no Apple-specific quirks.

We're still going to have to patch some drivers to use managed APIs that 
can properly hit this conditional (like I did for samsung_tty) in cases 
where they currently don't, but that's a lot cleaner than an open-coded 
conditional, I think (and often comes with other benefits anyway).

Note that wholesale making ioremap() behave like ioremap_np() at the 
arch level as as SoC quirk is not an option - for extenal PCIe devices, 
we still need to use ioremap(). We tried this approach initially but it 
doesn't work. Hence we arrived at this solution which describes the 
required mode in the devicetree, at the bus level (which makes sense, 
since that represents the fabric), and then these wrappers can use that 
information, carried over via the bit in struct device, to pick the 
right ioremap mode.

It doesn't really make sense to include the other variants here, because 
_np is strictly stronger than the default. Downgrading ioremap to any 
other variant would break most drivers, badly. However, upgrading to 
ioremap_np() is always correct (if possibly slower), on platforms where 
it is allowed by the bus. In fact, I bet that on many systems nGnRE 
already behaves like nGnRnE anyway. I don't know why Apple didn't just 
allow nGnRE mappings to work (behaving like nGnRnE) instead of making 
them explode, which is the whole reason we have to do this.

>> +       while (node) {
>> +               if (!of_property_read_bool(node, "ranges")) {
>> +                       break;
>> +               } else if (of_property_read_bool(node, "nonposted-mmio")) {
>> +                       of_node_put(node);
>> +                       return true;
>> +               } else if (of_property_read_bool(node, "posted-mmio")) {
>> +                       break;
>> +               }
>> +               parent = of_get_parent(node);
>> +               of_node_put(node);
>> +               node = parent;
>> +       }
> 
> I believe above can be slightly optimized. Don't we have helpers to
> traverse to all parents?

Keep in mind the logic here is that it stops on the first instance of 
either property, and does not traverse non-translatable boundaries. Are 
there helpers that can implement this kind of complex logic? It's not a 
simple recursive property lookup.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 27/27] arm64: apple: Add initial Apple Mac mini (M1, 2020) devicetree
  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
  1 sibling, 1 reply; 136+ messages in thread
From: Mark Kettenis @ 2021-03-05 15:59 UTC (permalink / raw)
  To: Hector Martin
  Cc: krzysztof.kozlowski, linux-arm-kernel, maz, robh, arnd, olof,
	tony, mohamed.mediouni, stan, graf, will, linus.walleij,
	mark.rutland, andy.shevchenko, gregkh, corbet, catalin.marinas,
	hch, davem, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

> From: Hector Martin <marcan@marcan.st>
> Date: Fri, 5 Mar 2021 20:14:10 +0900
> 
> On 05/03/2021 20.03, Krzysztof Kozlowski wrote:
> >> +	memory@800000000 {
> >> +		device_type = "memory";
> >> +		reg = <0x8 0 0x2 0>; /* To be filled by loader */
> > 
> > Shouldn't this be 0x800000000 with ~0x80000000 length (or whatever is
> > more common)? Or did I miss some ranges?
> 
> The base model has 8GB of RAM, and RAM always starts at 0x800000000, 
> hence that reg property.
> 
> It's not actually useful to try to boot Linux like this, because it'll 
> step all over device carveouts on both ends and break, but since those 
> are potentially dynamic it doesn't really make sense to use a more 
> specific example for the dts.
> 
> E.g. on my system, with my current firmware version, this ends up 
> getting patched to:
> 
> reg = <0x8 0x0134c000 0x1 0xda294000>

It may be better to handle the memory reserved by the firmware using a
"/reserved-memory" node.  I think the benefit of that could be that it
communicates the entire range of physical memory to the kernel, which
means it could use large mappings in the page tables.  Unless the
"/reserved-memory" node defines a region that has the "no-map"
property of course.

That doesn't really have an impact on this diff though.  The
firmware/bootloader would still have to modify the property on 16GB
models.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-05 15:13   ` Andy Shevchenko
  2021-03-05 15:55     ` Hector Martin
@ 2021-03-05 16:05     ` Rob Herring
  1 sibling, 0 replies; 136+ messages in thread
From: Rob Herring @ 2021-03-05 16:05 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Hector Martin, linux-arm Mailing List, Marc Zyngier,
	Arnd Bergmann, Olof Johansson, Krzysztof Kozlowski,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree,
	open list:SERIAL DRIVERS, Linux Documentation List,
	Linux Samsung SOC, Linux-Arch, Linux Kernel Mailing List

On Fri, Mar 5, 2021 at 9:13 AM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
>
> On Thu, Mar 4, 2021 at 11:40 PM Hector Martin <marcan@marcan.st> wrote:
> >
> > This implements the 'nonposted-mmio' and 'posted-mmio' boolean
> > properties. Placing these properties in a bus marks all child devices as
> > requiring non-posted or posted MMIO mappings. If no such properties are
> > found, the default is posted MMIO.
> >
> > of_mmio_is_nonposted() performs the tree walking to determine if a given
> > device has requested non-posted MMIO.
> >
> > of_address_to_resource() uses this to set the IORESOURCE_MEM_NONPOSTED
> > flag on resources that require non-posted MMIO.
> >
> > of_iomap() and of_io_request_and_map() then use this flag to pick the
> > correct ioremap() variant.
> >
> > This mechanism is currently restricted to Apple ARM platforms, as an
> > optimization.
>
> ...
>
> > @@ -896,7 +899,10 @@ void __iomem *of_iomap(struct device_node *np, int index)
> >         if (of_address_to_resource(np, index, &res))
> >                 return NULL;
> >
> > -       return ioremap(res.start, resource_size(&res));
> > +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> > +               return ioremap_np(res.start, resource_size(&res));
> > +       else
> > +               return ioremap(res.start, resource_size(&res));
>
> This doesn't sound right. Why _np is so exceptional? Why don't we have
> other flavours (it also rings a bell to my previous comment that the
> flag in ioresource is not in the right place)?
>
> ...
>
> > +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> > +               mem = ioremap_np(res.start, resource_size(&res));
> > +       else
> > +               mem = ioremap(res.start, resource_size(&res));
> > +
>
> Ditto.
>
> ...
>
> > +       while (node) {
> > +               if (!of_property_read_bool(node, "ranges")) {
> > +                       break;
> > +               } else if (of_property_read_bool(node, "nonposted-mmio")) {
> > +                       of_node_put(node);
> > +                       return true;
> > +               } else if (of_property_read_bool(node, "posted-mmio")) {
> > +                       break;
> > +               }
> > +               parent = of_get_parent(node);
> > +               of_node_put(node);
> > +               node = parent;
> > +       }
>
> I believe above can be slightly optimized. Don't we have helpers to
> traverse to all parents?

We don't. I only found a handful of cases mostly in arch/powerpc.
Given that and this series is big enough already, I don't think we
need a helper as part of it. But patches welcome.

Rob

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-05 15:55     ` Hector Martin
@ 2021-03-05 16:08       ` Andy Shevchenko
  2021-03-05 16:43         ` Arnd Bergmann
  0 siblings, 1 reply; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-05 16:08 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On Fri, Mar 5, 2021 at 5:55 PM Hector Martin <marcan@marcan.st> wrote:
> On 06/03/2021 00.13, Andy Shevchenko wrote:

...

> >> -       return ioremap(res.start, resource_size(&res));
> >> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> >> +               return ioremap_np(res.start, resource_size(&res));
> >> +       else
> >> +               return ioremap(res.start, resource_size(&res));
> >
> > This doesn't sound right. Why _np is so exceptional? Why don't we have
> > other flavours (it also rings a bell to my previous comment that the
> > flag in ioresource is not in the right place)?
>
> This is different from other variants, because until now *drivers* have
> made the choice of what ioremap mode to use based on device requirements
> (which means ioremap() 99% of the time, and then framebuffers and other
> memory-ish things such use something else). Now we have a *SoC fabric*
> that is calling the shots on what ioremap mode we have to use - and
> *every* non-PCIe driver needs to use ioremap_np() on these SoCs, or they
> break. So it seems a lot cleaner to make the choice for drivers here to
> upgrade ioremap() to ioremap_np() for SoCs that need it.

Yes, that is a good idea. Once we discussed x86 and _uc cases and
actually on x86 it makes a lot of sense to have ioremap() ==
ioremap_uc(). Can't be this a similar case here?
Arnd, what do you think of actually providing an ioremap() as some
kind of "best for the architecture the code is running on"?

Otherwise if the same driver happens to be needed on different
architectures, oops, ifdeffery or simple conditionals over the code is
really not the best way to solve it.

> If we don't do something like this here or in otherwise common code,
> we'd have to have an open-coded "if apple then ioremap_np, else ioremap"
> in every driver that runs on-die devices on these SoCs, even ones that
> are otherwise standard and need few or no Apple-specific quirks.

Exactly! But what about architectures where _uc is that one? So, why
does your patch only take part of _np case?
(Hint we have x86 Device Tree based platforms)

> We're still going to have to patch some drivers to use managed APIs that
> can properly hit this conditional (like I did for samsung_tty) in cases
> where they currently don't, but that's a lot cleaner than an open-coded
> conditional, I think (and often comes with other benefits anyway).
>
> Note that wholesale making ioremap() behave like ioremap_np() at the
> arch level as as SoC quirk is not an option - for extenal PCIe devices,
> we still need to use ioremap(). We tried this approach initially but it
> doesn't work. Hence we arrived at this solution which describes the
> required mode in the devicetree, at the bus level (which makes sense,
> since that represents the fabric), and then these wrappers can use that
> information, carried over via the bit in struct device, to pick the
> right ioremap mode.
>
> It doesn't really make sense to include the other variants here, because
> _np is strictly stronger than the default. Downgrading ioremap to any
> other variant would break most drivers, badly. However, upgrading to
> ioremap_np() is always correct (if possibly slower), on platforms where
> it is allowed by the bus. In fact, I bet that on many systems nGnRE
> already behaves like nGnRnE anyway. I don't know why Apple didn't just
> allow nGnRE mappings to work (behaving like nGnRnE) instead of making
> them explode, which is the whole reason we have to do this.

Yep, and why not to make ioremap() == ioremap_nc() on architecture
that requires it?
Can it be detected at run time?

...

> >> +       while (node) {
> >> +               if (!of_property_read_bool(node, "ranges")) {
> >> +                       break;
> >> +               } else if (of_property_read_bool(node, "nonposted-mmio")) {
> >> +                       of_node_put(node);
> >> +                       return true;
> >> +               } else if (of_property_read_bool(node, "posted-mmio")) {
> >> +                       break;
> >> +               }
> >> +               parent = of_get_parent(node);
> >> +               of_node_put(node);
> >> +               node = parent;
> >> +       }
> >
> > I believe above can be slightly optimized. Don't we have helpers to
> > traverse to all parents?
>
> Keep in mind the logic here is that it stops on the first instance of
> either property, and does not traverse non-translatable boundaries. Are
> there helpers that can implement this kind of complex logic? It's not a
> simple recursive property lookup.

I am aware of what it does and I believe if we don't have such a
helper yet we may introduce it and maybe even existing users of
something similar can utilize it.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework
  2021-03-05 15:17   ` Andy Shevchenko
@ 2021-03-05 16:16     ` Hector Martin
  2021-03-05 16:20       ` Andy Shevchenko
  0 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-05 16:16 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On 06/03/2021 00.17, Andy Shevchenko wrote:
> Add a separate change that removes flags from the spin lock in the IRQ handler.

This commit should have no functional changes; I am just splitting an 
existing function into two, where one takes the lock and the other does 
the work. Do you mean using a different locking function? I'm not 
entirely sure what you're suggesting.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework
  2021-03-05 16:16     ` Hector Martin
@ 2021-03-05 16:20       ` Andy Shevchenko
  2021-03-05 16:29         ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-05 16:20 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On Fri, Mar 5, 2021 at 6:16 PM Hector Martin <marcan@marcan.st> wrote:
>
> On 06/03/2021 00.17, Andy Shevchenko wrote:
> > Add a separate change that removes flags from the spin lock in the IRQ handler.
>
> This commit should have no functional changes;

Exactly my point why I'm suggesting to have _separate_ change!

> I am just splitting an
> existing function into two, where one takes the lock and the other does
> the work. Do you mean using a different locking function? I'm not
> entirely sure what you're suggesting.

Yes, as a prerequisite

spin_lock_irqsave -> spin_lock().

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework
  2021-03-05 16:20       ` Andy Shevchenko
@ 2021-03-05 16:29         ` Hector Martin
  2021-03-07 11:34           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-05 16:29 UTC (permalink / raw)
  To: Andy Shevchenko, Krzysztof Kozlowski
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Mark Kettenis, Tony Lindgren, Mohamed Mediouni,
	Stan Skowronek, Alexander Graf, Will Deacon, Linus Walleij,
	Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	open list:SERIAL DRIVERS, Linux Documentation List,
	Linux Samsung SOC, Linux-Arch, Linux Kernel Mailing List

On 06/03/2021 01.20, Andy Shevchenko wrote:
>> I am just splitting an
>> existing function into two, where one takes the lock and the other does
>> the work. Do you mean using a different locking function? I'm not
>> entirely sure what you're suggesting.
> 
> Yes, as a prerequisite
> 
> spin_lock_irqsave -> spin_lock().

Krzysztof, is this something you want in this series? I was trying to 
avoid logic changes to the non-Apple paths.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-05 16:08       ` Andy Shevchenko
@ 2021-03-05 16:43         ` Arnd Bergmann
  2021-03-05 17:19           ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-05 16:43 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Hector Martin, linux-arm Mailing List, Marc Zyngier, Rob Herring,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On Fri, Mar 5, 2021 at 5:08 PM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
>
> On Fri, Mar 5, 2021 at 5:55 PM Hector Martin <marcan@marcan.st> wrote:
> > On 06/03/2021 00.13, Andy Shevchenko wrote:
>
> ...
>
> > >> -       return ioremap(res.start, resource_size(&res));
> > >> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> > >> +               return ioremap_np(res.start, resource_size(&res));
> > >> +       else
> > >> +               return ioremap(res.start, resource_size(&res));
> > >
> > > This doesn't sound right. Why _np is so exceptional? Why don't we have
> > > other flavours (it also rings a bell to my previous comment that the
> > > flag in ioresource is not in the right place)?
> >
> > This is different from other variants, because until now *drivers* have
> > made the choice of what ioremap mode to use based on device requirements
> > (which means ioremap() 99% of the time, and then framebuffers and other
> > memory-ish things such use something else). Now we have a *SoC fabric*
> > that is calling the shots on what ioremap mode we have to use - and
> > *every* non-PCIe driver needs to use ioremap_np() on these SoCs, or they
> > break. So it seems a lot cleaner to make the choice for drivers here to
> > upgrade ioremap() to ioremap_np() for SoCs that need it.
>
> Yes, that is a good idea. Once we discussed x86 and _uc cases and
> actually on x86 it makes a lot of sense to have ioremap() ==
> ioremap_uc(). Can't be this a similar case here?

The difference is that ioremap() should be ioremap_uc() on /all/
architectures, it's just that x86 and ia64 for a long time were the
exception and defined ioremap() as 'do whatever the mtrr says'.

> Arnd, what do you think of actually providing an ioremap() as some
> kind of "best for the architecture the code is running on"?

Linus has been pretty clear about wanting all the default functions
to have similar behavior across architectures and be at least as
strict as x86. In case of ioremap() that usually means that writes
are posted, because they are that way on PCI buses on x86.

There are definitely some advantages of making all writes non-posted
by default on Arm because that would be a simpler model, but there
are some important downsides:

- non-posted writes can be much slower than posted ones, depending
  on the specific hardware

- it would change the behavior of all Arm platforms, with no easy
  way to validate it

- setting ioremap() on PCI buses non-posted only makes them
  only slower but not more reliable, because the non-posted flag
  on the bus is discarded by the PCI host bridge.

> Otherwise if the same driver happens to be needed on different
> architectures, oops, ifdeffery or simple conditionals over the code is
> really not the best way to solve it.

The behavior of devm_platform_ioremap_resource() is now to
do the right thing automatically, and I think that is good enough. For
all I can tell, we can use that in all drivers without conditional
compilation.

> > If we don't do something like this here or in otherwise common code,
> > we'd have to have an open-coded "if apple then ioremap_np, else ioremap"
> > in every driver that runs on-die devices on these SoCs, even ones that
> > are otherwise standard and need few or no Apple-specific quirks.
>
> Exactly! But what about architectures where _uc is that one? So, why
> does your patch only take part of _np case?
> (Hint we have x86 Device Tree based platforms)

Usually, the driver knows the requirements, and they are independent
of the platform. If a driver wants _wc or _wt mappings, it will want that
on all machines, and should be able to deal with platforms that implement
that through a stricter mapping.

The two drivers that need to override ioremap() to ioremap_uc()
in order to override the mtrr already have that logic. You are right
that these are a bit like the _np() case in that the device needs
something stricter than the default mapping, but the difference is
that for x86 ioremap_uc() this is needed to work around broken
firmware, while for the apple ioremap_np() case we trust the firmware
to tell us what to do.

> Yep, and why not to make ioremap() == ioremap_nc() on architecture
> that requires it?
> Can it be detected at run time?

I think doing this requires auditing a lot of legacy driver code,
especially drivers/video/fbdev. Once all drivers that need write-combining
mappings explicitly ask for them, the default ioremap can be changed
over to act like ioremap_nc() on the remaining two architectures that
don't do that yet.

There has been a lot of work toward that goal, but the problem
is knowing exactly which drivers need it.

       Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 27/27] arm64: apple: Add initial Apple Mac mini (M1, 2020) devicetree
  2021-03-05 15:59       ` Mark Kettenis
@ 2021-03-05 16:50         ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-05 16:50 UTC (permalink / raw)
  To: Mark Kettenis
  Cc: krzysztof.kozlowski, linux-arm-kernel, maz, robh, arnd, olof,
	tony, mohamed.mediouni, stan, graf, will, linus.walleij,
	mark.rutland, andy.shevchenko, gregkh, corbet, catalin.marinas,
	hch, davem, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On 06/03/2021 00.59, Mark Kettenis wrote:
> It may be better to handle the memory reserved by the firmware using a
> "/reserved-memory" node.  I think the benefit of that could be that it
> communicates the entire range of physical memory to the kernel, which
> means it could use large mappings in the page tables.  Unless the
> "/reserved-memory" node defines a region that has the "no-map"
> property of course.

We actually need no-map, because otherwise the CPU could speculate its 
way into these carveouts (it's not just firmware, there's stuff in here 
the CPU really can't be allowed to touch, e.g. the SEP carveout). It 
also breaks simplefb mapping the framebuffer. I thought of the 
reserved-memory approach, but then figured it wouldn't buy us anything 
for this reason.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 24/27] tty: serial: samsung_tty: Add support for Apple UARTs
  2021-03-05 15:28   ` Andy Shevchenko
@ 2021-03-05 17:04     ` Hector Martin
  2021-03-07 11:40       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-05 17:04 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On 06/03/2021 00.28, Andy Shevchenko wrote:
>> +       case TYPE_APPLE_S5L:
>> +               WARN_ON(1); // No DMA
> 
> Oh, no, please use the ONCE variant.

Thanks, changing this for v4.

> 
> ...
> 
>> +       /* Apple types use these bits for IRQ masks */
>> +       if (ourport->info->type != TYPE_APPLE_S5L) {
>> +               ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
>> +                               S3C64XX_UCON_EMPTYINT_EN |
>> +                               S3C64XX_UCON_DMASUS_EN |
>> +                               S3C64XX_UCON_TIMEOUT_EN);
>> +               ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
> 
> Can you spell 0xf with named constant(s), please?
> 
> In case they are repetitive via the code, introduce either a temporary
> variable (in case it scoped to one function only), or define it as a
> constant.

I'm just moving this code; as far as I can tell this is a timeout value 
(so just an integer), but I don't know if there is any special meaning 
to 0xf here. Note that this codepath is for *non-Apple* chips, as the 
Apple ones don't even have this field (at least not here).

>> +       irqreturn_t ret = IRQ_NONE;
> 
> Redundant. You may return directly.

What if both interrupts are pending?

> No IO serialization?

There is no DMA on the Apple variants (as far as I know; it's not 
implemented anyway), so there is no need for serializing IO with DMA. In 
any case, dealing with that is the DMA code's job, the interrupt handler 
shouldn't need to care.

If you mean serializing IO with the IRQ: CPU-wise, I would hope that's 
the irqchip's job (AIC does this with a readl on the event). If you mean 
ensuring all writes are complete (i.e. posted write issue), on the Apple 
chips everything is non-posted as explained in the previous patches.

> Extra blank line (check your entire series for a such)

Thanks, noted. I'll check the declaration blocks in other patches.

>> +       ourport->rx_enabled = 1;
>> +       ourport->tx_enabled = 0;
> 
> How are these protected against race?

The serial core should be holding the port mutex for pretty much every 
call into the driver, as far as I can tell.

> 
> ...
> 
>> +               case TYPE_APPLE_S5L: {
>> +                       unsigned int ucon;
>> +                       int ret;
>> +
>> +                       ret = clk_prepare_enable(ourport->clk);
>> +                       if (ret) {
>> +                               dev_err(dev, "clk_enable clk failed: %d\n", ret);
>> +                               return ret;
>> +                       }
>> +                       if (!IS_ERR(ourport->baudclk)) {
>> +                               ret = clk_prepare_enable(ourport->baudclk);
>> +                               if (ret) {
>> +                                       dev_err(dev, "clk_enable baudclk failed: %d\n", ret);
>> +                                       clk_disable_unprepare(ourport->clk);
>> +                                       return ret;
>> +                               }
>> +                       }
> 
> Wouldn't it be better to use CLK bulk API?

Ah, I guess that could save a line or two of code here, even though it 
requires setting up the array. I'll give it a shot.

>> +#ifdef CONFIG_ARCH_APPLE
> 
> Why? Wouldn't you like the one kernel to work on many SoCs?

This *adds* Apple support, it is not mutually exclusive with all the 
other SoCs. You can enable all of those options and get a driver that 
works on all of them. This is the same pattern used throughout the 
driver for all the other Samsung variants. There is no reason to have 
Apple SoC support in the samsung driver if the rest of the kernel 
doesn't have Apple SoC support either, of course.

>> +#define APPLE_S5L_UCON_RXTO_ENA_MSK    (1 << APPLE_S5L_UCON_RXTO_ENA)
>> +#define APPLE_S5L_UCON_RXTHRESH_ENA_MSK        (1 << APPLE_S5L_UCON_RXTHRESH_ENA)
>> +#define APPLE_S5L_UCON_TXTHRESH_ENA_MSK        (1 << APPLE_S5L_UCON_TXTHRESH_ENA)
> 
> BIT() ?

I'm trying to keep the style of the rest of the file here, which doesn't 
use BIT() anywhere. I agree this header could use some work though... I 
wonder if I've met my required quota of cleanups to this driver for this 
patchset ;-)

>> +#define APPLE_S5L_UCON_DEFAULT         (S3C2410_UCON_TXIRQMODE | \
>> +                                        S3C2410_UCON_RXIRQMODE | \
>> +                                        S3C2410_UCON_RXFIFO_TOI)
> 
> Indentation level is too high. Hint: start a value of the definition
> on the new line.

Is it that bad? It's within 80 cols, putting one bit per line is more 
readable than several on one line, and this is how the rest of the 
header is written. Is it really better to do

#define APPLE_S5L_UCON_DEFAULT \
	(S3C2410_UCON_TXIRQMODE | S3C2410_UCON_RXIRQMODE | \
	 S3C2410_UCON_RXFIFO_TOI)

or

#define APPLE_S5L_UCON_DEFAULT \
		(S3C2410_UCON_TXIRQMODE | \
		 S3C2410_UCON_RXIRQMODE | \
		 S3C2410_UCON_RXFIFO_TOI)

here? Those don't look like an obvious improvement to me, I'd even say 
overlapping the bits and the macro name in the same columns makes it 
less readable to my eyes.

>> +#define APPLE_S5L_UTRSTAT_RXTHRESH     (1<<4)
>> +#define APPLE_S5L_UTRSTAT_TXTHRESH     (1<<5)
>> +#define APPLE_S5L_UTRSTAT_RXTO         (1<<9)
>> +#define APPLE_S5L_UTRSTAT_ALL_FLAGS    (0x3f0)
> 
> BIT() ?

See above.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-05 16:43         ` Arnd Bergmann
@ 2021-03-05 17:19           ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-05 17:19 UTC (permalink / raw)
  To: Arnd Bergmann, Andy Shevchenko
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On 06/03/2021 01.43, Arnd Bergmann wrote:
> - setting ioremap() on PCI buses non-posted only makes them
>    only slower but not more reliable, because the non-posted flag
>    on the bus is discarded by the PCI host bridge.

Note that this doesn't work here *anyway*. The fabric is picky in both 
directions: thou shalt use nGnRnE for on-SoC MMIO and nGnRE for PCIe 
windows, or else, SError.

Since these devices can support *any* PCI device via Thunderbolt, making 
PCI drivers be the oddball ones needing special APIs would mean hundreds 
of changes needed - the vast majority of PCI drivers in the kernel use 
plain ioremap variants that don't have any flags to look at.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  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 17:39   ` Rob Herring
  2021-03-05 18:18     ` Hector Martin
  2 siblings, 1 reply; 136+ messages in thread
From: Rob Herring @ 2021-03-05 17:39 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Thu, Mar 4, 2021 at 3:40 PM Hector Martin <marcan@marcan.st> wrote:
>
> This implements the 'nonposted-mmio' and 'posted-mmio' boolean
> properties. Placing these properties in a bus marks all child devices as
> requiring non-posted or posted MMIO mappings. If no such properties are
> found, the default is posted MMIO.

I'm still a little hesitant to add these properties and having some
default. I worry about a similar situation as 'dma-coherent' where the
assumed default on non-coherent on Arm doesn't work for PowerPC which
defaults coherent. More below on this.

> of_mmio_is_nonposted() performs the tree walking to determine if a given
> device has requested non-posted MMIO.
>
> of_address_to_resource() uses this to set the IORESOURCE_MEM_NONPOSTED
> flag on resources that require non-posted MMIO.
>
> of_iomap() and of_io_request_and_map() then use this flag to pick the
> correct ioremap() variant.
>
> This mechanism is currently restricted to Apple ARM platforms, as an
> optimization.
>
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/of/address.c       | 72 ++++++++++++++++++++++++++++++++++++--
>  include/linux/of_address.h |  1 +
>  2 files changed, 71 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 73ddf2540f3f..6114dceb1ba6 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -847,6 +847,9 @@ static int __of_address_to_resource(struct device_node *dev,
>                 return -EINVAL;
>         memset(r, 0, sizeof(struct resource));
>
> +       if (of_mmio_is_nonposted(dev))
> +               flags |= IORESOURCE_MEM_NONPOSTED;
> +
>         r->start = taddr;
>         r->end = taddr + size - 1;
>         r->flags = flags;
> @@ -896,7 +899,10 @@ void __iomem *of_iomap(struct device_node *np, int index)
>         if (of_address_to_resource(np, index, &res))
>                 return NULL;
>
> -       return ioremap(res.start, resource_size(&res));
> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> +               return ioremap_np(res.start, resource_size(&res));
> +       else
> +               return ioremap(res.start, resource_size(&res));

This and the devm variants all scream for a ioremap_extended()
function. IOW, it would be better if the ioremap flavor was a
parameter. Unless we could implement that just for arm64 first, that's
a lot of refactoring...

>  }
>  EXPORT_SYMBOL(of_iomap);
>
> @@ -928,7 +934,11 @@ void __iomem *of_io_request_and_map(struct device_node *np, int index,
>         if (!request_mem_region(res.start, resource_size(&res), name))
>                 return IOMEM_ERR_PTR(-EBUSY);
>
> -       mem = ioremap(res.start, resource_size(&res));
> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> +               mem = ioremap_np(res.start, resource_size(&res));
> +       else
> +               mem = ioremap(res.start, resource_size(&res));
> +
>         if (!mem) {
>                 release_mem_region(res.start, resource_size(&res));
>                 return IOMEM_ERR_PTR(-ENOMEM);
> @@ -1094,3 +1104,61 @@ bool of_dma_is_coherent(struct device_node *np)
>         return false;
>  }
>  EXPORT_SYMBOL_GPL(of_dma_is_coherent);
> +
> +static bool of_nonposted_mmio_quirk(void)
> +{
> +       if (IS_ENABLED(CONFIG_ARCH_APPLE)) {
> +               /* To save cycles, we cache the result for global "Apple ARM" setting */
> +               static int quirk_state = -1;
> +
> +               /* Make quirk cached */
> +               if (quirk_state < 0)
> +                       quirk_state = of_machine_is_compatible("apple,arm-platform");
> +               return !!quirk_state;
> +       }
> +       return false;
> +}
> +
> +/**
> + * of_mmio_is_nonposted - Check if device uses non-posted MMIO
> + * @np:        device node
> + *
> + * Returns true if the "nonposted-mmio" property was found for
> + * the device's bus or a parent. "posted-mmio" has the opposite
> + * effect, terminating recursion and overriding any
> + * "nonposted-mmio" properties in parent buses.
> + *
> + * Recursion terminates if reach a non-translatable boundary
> + * (a node without a 'ranges' property).
> + *
> + * This is currently only enabled on Apple ARM devices, as an
> + * optimization.
> + */
> +bool of_mmio_is_nonposted(struct device_node *np)
> +{
> +       struct device_node *node;
> +       struct device_node *parent;
> +
> +       if (!of_nonposted_mmio_quirk())
> +               return false;
> +
> +       node = of_get_parent(np);
> +
> +       while (node) {
> +               if (!of_property_read_bool(node, "ranges")) {
> +                       break;
> +               } else if (of_property_read_bool(node, "nonposted-mmio")) {
> +                       of_node_put(node);
> +                       return true;
> +               } else if (of_property_read_bool(node, "posted-mmio")) {
> +                       break;
> +               }
> +               parent = of_get_parent(node);
> +               of_node_put(node);
> +               node = parent;
> +       }
> +
> +       of_node_put(node);
> +       return false;

What's the code path using these functions on the M1 where we need to
return 'posted'? It's just downstream PCI mappings (PCI memory space),
right? Those would never hit these paths because they don't have a DT
node or if they do the memory space is not part of it. So can't the
check just be:

bool of_mmio_is_nonposted(struct device_node *np)
{
    return np && of_machine_is_compatible("apple,arm-platform");
}

Note in theory we could use 'assigned-addresses' with PCI, but that's
pretty much never the case with FDT. If we did, we could detect the
device node is a PCI device in that case.

Rob

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-05 17:39   ` Rob Herring
@ 2021-03-05 18:18     ` Hector Martin
  2021-03-05 21:17       ` Arnd Bergmann
  0 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-05 18:18 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, Marc Zyngier, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On 06/03/2021 02.39, Rob Herring wrote:
> I'm still a little hesitant to add these properties and having some
> default. I worry about a similar situation as 'dma-coherent' where the
> assumed default on non-coherent on Arm doesn't work for PowerPC which
> defaults coherent. More below on this.

The intent of the default here is that it matches what ioremap() does on 
other platforms already (where it does not make any claims of being 
posted, though it could be on some platforms). It could be per-platform 
what that means... but either way it should be what drivers get today 
without asking for anything special.

>> -       return ioremap(res.start, resource_size(&res));
>> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
>> +               return ioremap_np(res.start, resource_size(&res));
>> +       else
>> +               return ioremap(res.start, resource_size(&res));
> 
> This and the devm variants all scream for a ioremap_extended()
> function. IOW, it would be better if the ioremap flavor was a
> parameter. Unless we could implement that just for arm64 first, that's
> a lot of refactoring...

I agree, but yeah... that's one big refactor to try to do now...

> What's the code path using these functions on the M1 where we need to
> return 'posted'? It's just downstream PCI mappings (PCI memory space),
> right? Those would never hit these paths because they don't have a DT
> node or if they do the memory space is not part of it. So can't the
> check just be:
> 
> bool of_mmio_is_nonposted(struct device_node *np)
> {
>      return np && of_machine_is_compatible("apple,arm-platform");
> }

Yes; the implementation was trying to be generic, but AIUI we don't need 
this on M1 because the PCI mappings don't go through this codepath, and 
nothing else needs posted mode. My first hack was something not too 
unlike this, then I was going to get rid of apple,arm-platform and just 
have this be a generic mechanism with the properties, but then we added 
the optimization to not do the lookups on other platforms, and now we're 
coming full circle... :-)

If you prefer to handle it this way for now I can do it like this. I 
think we should still have the DT bindings and properties though (even 
if not used), as they do describe the hardware properly, and in the 
future we might want to use them instead of having a quirk.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-05 18:18     ` Hector Martin
@ 2021-03-05 21:17       ` Arnd Bergmann
  2021-03-08 15:56         ` Rob Herring
  0 siblings, 1 reply; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-05 21:17 UTC (permalink / raw)
  To: Hector Martin
  Cc: Rob Herring, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Fri, Mar 5, 2021 at 7:18 PM Hector Martin <marcan@marcan.st> wrote:
>
> On 06/03/2021 02.39, Rob Herring wrote:
> >> -       return ioremap(res.start, resource_size(&res));
> >> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> >> +               return ioremap_np(res.start, resource_size(&res));
> >> +       else
> >> +               return ioremap(res.start, resource_size(&res));
> >
> > This and the devm variants all scream for a ioremap_extended()
> > function. IOW, it would be better if the ioremap flavor was a
> > parameter. Unless we could implement that just for arm64 first, that's
> > a lot of refactoring...
>
> I agree, but yeah... that's one big refactor to try to do now...

FWIW, there is ioremap_prot() that Christoph introduced in 2019
for a few architectures.  I suppose it would be nice to lift
that out architecture specific code and completely replace the
unusual variants, leaving only ioremap(), ioremap_prot() and
memremap() but dropping the _nc, _cached, _wc, _wt and _np
versions in favor of an extensible set of flags.

Then again, I would not make that a prerequisite for the merge
of the M1 support.

> > What's the code path using these functions on the M1 where we need to
> > return 'posted'? It's just downstream PCI mappings (PCI memory space),
> > right? Those would never hit these paths because they don't have a DT
> > node or if they do the memory space is not part of it. So can't the
> > check just be:
> >
> > bool of_mmio_is_nonposted(struct device_node *np)
> > {
> >      return np && of_machine_is_compatible("apple,arm-platform");
> > }
>
> Yes; the implementation was trying to be generic, but AIUI we don't need
> this on M1 because the PCI mappings don't go through this codepath, and
> nothing else needs posted mode. My first hack was something not too
> unlike this, then I was going to get rid of apple,arm-platform and just
> have this be a generic mechanism with the properties, but then we added
> the optimization to not do the lookups on other platforms, and now we're
> coming full circle... :-)

I never liked the idea of having a list of platforms that need a
special hack, please let's not go back to that.

         Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework
  2021-03-05 16:29         ` Hector Martin
@ 2021-03-07 11:34           ` Krzysztof Kozlowski
  2021-03-07 16:01             ` Arnd Bergmann
  0 siblings, 1 reply; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-07 11:34 UTC (permalink / raw)
  To: Hector Martin, Andy Shevchenko
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Mark Kettenis, Tony Lindgren, Mohamed Mediouni,
	Stan Skowronek, Alexander Graf, Will Deacon, Linus Walleij,
	Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	open list:SERIAL DRIVERS, Linux Documentation List,
	Linux Samsung SOC, Linux-Arch, Linux Kernel Mailing List

On 05/03/2021 17:29, Hector Martin wrote:
> On 06/03/2021 01.20, Andy Shevchenko wrote:
>>> I am just splitting an
>>> existing function into two, where one takes the lock and the other does
>>> the work. Do you mean using a different locking function? I'm not
>>> entirely sure what you're suggesting.
>>
>> Yes, as a prerequisite
>>
>> spin_lock_irqsave -> spin_lock().
> 
> Krzysztof, is this something you want in this series? I was trying to 
> avoid logic changes to the non-Apple paths.

I don't quite get the need for such change (the code will be still
called in interrupt handler, right?), but assuming the "why?" is
properly documented, it can be a separate patch here.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 24/27] tty: serial: samsung_tty: Add support for Apple UARTs
  2021-03-05 17:04     ` Hector Martin
@ 2021-03-07 11:40       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-07 11:40 UTC (permalink / raw)
  To: Hector Martin, Andy Shevchenko
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Mark Kettenis, Tony Lindgren, Mohamed Mediouni,
	Stan Skowronek, Alexander Graf, Will Deacon, Linus Walleij,
	Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller, devicetree,
	open list:SERIAL DRIVERS, Linux Documentation List,
	Linux Samsung SOC, Linux-Arch, Linux Kernel Mailing List

On 05/03/2021 18:04, Hector Martin wrote:
> On 06/03/2021 00.28, Andy Shevchenko wrote:
>>> +       case TYPE_APPLE_S5L:
>>> +               WARN_ON(1); // No DMA
>>
>> Oh, no, please use the ONCE variant.
> 
> Thanks, changing this for v4.
> 
>>
>> ...
>>
>>> +       /* Apple types use these bits for IRQ masks */
>>> +       if (ourport->info->type != TYPE_APPLE_S5L) {
>>> +               ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
>>> +                               S3C64XX_UCON_EMPTYINT_EN |
>>> +                               S3C64XX_UCON_DMASUS_EN |
>>> +                               S3C64XX_UCON_TIMEOUT_EN);
>>> +               ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
>>
>> Can you spell 0xf with named constant(s), please?
>>
>> In case they are repetitive via the code, introduce either a temporary
>> variable (in case it scoped to one function only), or define it as a
>> constant.
> 
> I'm just moving this code; as far as I can tell this is a timeout value 
> (so just an integer), but I don't know if there is any special meaning 
> to 0xf here. Note that this codepath is for *non-Apple* chips, as the 
> Apple ones don't even have this field (at least not here).

I agree here with Hector. Andi, you propose here unrelated change (which
without documentation might not be doable by Hector).

> 
>>> +       irqreturn_t ret = IRQ_NONE;
>>
>> Redundant. You may return directly.
> 
> What if both interrupts are pending?
> 
>> No IO serialization?
> 
> There is no DMA on the Apple variants (as far as I know; it's not 
> implemented anyway), so there is no need for serializing IO with DMA. In 
> any case, dealing with that is the DMA code's job, the interrupt handler 
> shouldn't need to care.
> 
> If you mean serializing IO with the IRQ: CPU-wise, I would hope that's 
> the irqchip's job (AIC does this with a readl on the event). If you mean 
> ensuring all writes are complete (i.e. posted write issue), on the Apple 
> chips everything is non-posted as explained in the previous patches.
> 
>> Extra blank line (check your entire series for a such)
> 
> Thanks, noted. I'll check the declaration blocks in other patches.
> 
>>> +       ourport->rx_enabled = 1;
>>> +       ourport->tx_enabled = 0;
>>
>> How are these protected against race?
> 
> The serial core should be holding the port mutex for pretty much every 
> call into the driver, as far as I can tell.
> 
>>
>> ...
>>
>>> +               case TYPE_APPLE_S5L: {
>>> +                       unsigned int ucon;
>>> +                       int ret;
>>> +
>>> +                       ret = clk_prepare_enable(ourport->clk);
>>> +                       if (ret) {
>>> +                               dev_err(dev, "clk_enable clk failed: %d\n", ret);
>>> +                               return ret;
>>> +                       }
>>> +                       if (!IS_ERR(ourport->baudclk)) {
>>> +                               ret = clk_prepare_enable(ourport->baudclk);
>>> +                               if (ret) {
>>> +                                       dev_err(dev, "clk_enable baudclk failed: %d\n", ret);
>>> +                                       clk_disable_unprepare(ourport->clk);
>>> +                                       return ret;
>>> +                               }
>>> +                       }
>>
>> Wouldn't it be better to use CLK bulk API?
> 
> Ah, I guess that could save a line or two of code here, even though it 
> requires setting up the array. I'll give it a shot.
> 
>>> +#ifdef CONFIG_ARCH_APPLE
>>
>> Why? Wouldn't you like the one kernel to work on many SoCs?
> 
> This *adds* Apple support, it is not mutually exclusive with all the 
> other SoCs. You can enable all of those options and get a driver that 
> works on all of them. This is the same pattern used throughout the 
> driver for all the other Samsung variants. There is no reason to have 
> Apple SoC support in the samsung driver if the rest of the kernel 
> doesn't have Apple SoC support either, of course.

How ifdef on ARCH_APLLE makes it non-working on many SoCs? All new
platforms are multi... The true question is - do the ifdefs in the code
make it more difficult to read/review?

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework
  2021-03-07 11:34           ` Krzysztof Kozlowski
@ 2021-03-07 16:01             ` Arnd Bergmann
  2021-03-07 19:51               ` Krzysztof Kozlowski
  0 siblings, 1 reply; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-07 16:01 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Hector Martin, Andy Shevchenko, linux-arm Mailing List,
	Marc Zyngier, Rob Herring, Olof Johansson, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On Sun, Mar 7, 2021 at 12:34 PM Krzysztof Kozlowski
<krzysztof.kozlowski@canonical.com> wrote:
> On 05/03/2021 17:29, Hector Martin wrote:
> > On 06/03/2021 01.20, Andy Shevchenko wrote:
> >>> I am just splitting an
> >>> existing function into two, where one takes the lock and the other does
> >>> the work. Do you mean using a different locking function? I'm not
> >>> entirely sure what you're suggesting.
> >>
> >> Yes, as a prerequisite
> >>
> >> spin_lock_irqsave -> spin_lock().
> >
> > Krzysztof, is this something you want in this series? I was trying to
> > avoid logic changes to the non-Apple paths.
>
> I don't quite get the need for such change (the code will be still
> called in interrupt handler, right?), but assuming the "why?" is
> properly documented, it can be a separate patch here.

This is only for readability: the common rule is to not disable
interrupts when they are already disabled, so a reader might wonder
if this instance of the handler is special in some case that it might
be called with interrupts enabled.

There is also a small overhead in accessing the global irq mask
register on some architectures, but for a uart that does not make
any difference of course.

While I'm generally in favor of that kind of cleanup, I'd also
prefer to leave it out of this series -- once you get into details
like this the series gets harder to review.

        Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework
  2021-03-07 16:01             ` Arnd Bergmann
@ 2021-03-07 19:51               ` Krzysztof Kozlowski
  0 siblings, 0 replies; 136+ messages in thread
From: Krzysztof Kozlowski @ 2021-03-07 19:51 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hector Martin, Andy Shevchenko, linux-arm Mailing List,
	Marc Zyngier, Rob Herring, Olof Johansson, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On 07/03/2021 17:01, Arnd Bergmann wrote:
> On Sun, Mar 7, 2021 at 12:34 PM Krzysztof Kozlowski
> <krzysztof.kozlowski@canonical.com> wrote:
>> On 05/03/2021 17:29, Hector Martin wrote:
>>> On 06/03/2021 01.20, Andy Shevchenko wrote:
>>>>> I am just splitting an
>>>>> existing function into two, where one takes the lock and the other does
>>>>> the work. Do you mean using a different locking function? I'm not
>>>>> entirely sure what you're suggesting.
>>>>
>>>> Yes, as a prerequisite
>>>>
>>>> spin_lock_irqsave -> spin_lock().
>>>
>>> Krzysztof, is this something you want in this series? I was trying to
>>> avoid logic changes to the non-Apple paths.
>>
>> I don't quite get the need for such change (the code will be still
>> called in interrupt handler, right?), but assuming the "why?" is
>> properly documented, it can be a separate patch here.
> 
> This is only for readability: the common rule is to not disable
> interrupts when they are already disabled, so a reader might wonder
> if this instance of the handler is special in some case that it might
> be called with interrupts enabled.
> 
> There is also a small overhead in accessing the global irq mask
> register on some architectures, but for a uart that does not make
> any difference of course.
> 
> While I'm generally in favor of that kind of cleanup, I'd also
> prefer to leave it out of this series -- once you get into details
> like this the series gets harder to review.

So it's only about the spinlock in the IRQ handler (which does not need
to disable the IRQs). Makes sense but not related at all to the topic of
bringing up Apple M1, therefore should not stop the review/merging.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support
  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
  3 siblings, 0 replies; 136+ messages in thread
From: Marc Zyngier @ 2021-03-08 11:12 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Thu, 04 Mar 2021 21:38:41 +0000,
Hector Martin <marcan@marcan.st> wrote:
> 
> Not all platforms provide the same set of timers/interrupts, and Linux
> only needs one (plus kvm/guest ones); some platforms are working around
> this by using dummy fake interrupts. Implementing interrupt-names allows
> the devicetree to specify an arbitrary set of available interrupts, so
> the timer code can pick the right one.
> 
> This also adds the hyp-virt timer/interrupt, which was previously not
> expressed in the fixed 4-interrupt form.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>

Acked-by: Marc Zyngier <maz@kernel.org>

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 07/27] arm64: arch_timer: implement support for interrupt-names
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Marc Zyngier @ 2021-03-08 11:13 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Thu, 04 Mar 2021 21:38:42 +0000,
Hector Martin <marcan@marcan.st> wrote:
> 
> This allows the devicetree to correctly represent the available set of
> timers, which varies from device to device, without the need for fake
> dummy interrupts for unavailable slots.
> 
> Also add the hyp-virt timer/PPI, which is not currently used, but worth
> representing.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> Reviewed-by: Tony Lindgren <tony@atomide.com>

Reviewed-by: Marc Zyngier <maz@kernel.org>

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 08/27] asm-generic/io.h:  Add a non-posted variant of ioremap()
  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-08 11:20   ` Marc Zyngier
  2021-03-24 18:12   ` Will Deacon
  2 siblings, 0 replies; 136+ messages in thread
From: Marc Zyngier @ 2021-03-08 11:20 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Thu, 04 Mar 2021 21:38:43 +0000,
Hector Martin <marcan@marcan.st> wrote:
> 
> ARM64 currently defaults to posted MMIO (nGnRnE), but some devices
> require the use of non-posted MMIO (nGnRE). Introduce a new ioremap()
> variant to handle this case. ioremap_np() is aliased to ioremap() by
> default on arches that do not implement this variant.
> 
> sparc64 is the only architecture that needs to be touched directly,
> because it includes neither of the generic io.h or iomap.h headers.
> 
> This adds the IORESOURCE_MEM_NONPOSTED flag, which maps to this
> variant and marks a given resource as requiring non-posted mappings.
> This is implemented in the resource system because it is a SoC-level
> requirement, so existing drivers do not need special-case code to pick
> this ioremap variant.
> 
> Then this is implemented in devres by introducing devm_ioremap_np(),
> and making devm_ioremap_resource() automatically select this variant
> when the resource has the IORESOURCE_MEM_NONPOSTED flag set.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>

Acked-by: Marc Zyngier <maz@kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 11/27] arm64: Implement ioremap_np() to map MMIO as nGnRnE
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Marc Zyngier @ 2021-03-08 11:22 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Thu, 04 Mar 2021 21:38:46 +0000,
Hector Martin <marcan@marcan.st> wrote:
> 
> This is used on Apple ARM platforms, which require most MMIO
> (except PCI devices) to be mapped as nGnRnE.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>

Acked-by: Marc Zyngier <maz@kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 14/27] arm64: move ICH_ sysreg bits from arm-gic-v3.h to sysreg.h
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Marc Zyngier @ 2021-03-08 11:39 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Thu, 04 Mar 2021 21:38:49 +0000,
Hector Martin <marcan@marcan.st> wrote:
> 
> These definitions are in arm-gic-v3.h for historical reasons which no
> longer apply. Move them to sysreg.h so the AIC driver can use them, as
> it needs to peek into vGIC registers to deal with the GIC maintentance
> interrupt.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>

Acked-by: Marc Zyngier <maz@kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  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
  1 sibling, 1 reply; 136+ messages in thread
From: Marc Zyngier @ 2021-03-08 11:50 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Hector Martin, linux-arm Mailing List, Rob Herring,
	Arnd Bergmann, Olof Johansson, Krzysztof Kozlowski,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree,
	open list:SERIAL DRIVERS, Linux Documentation List,
	Linux Samsung SOC, Linux-Arch, Linux Kernel Mailing List

On Fri, 05 Mar 2021 15:05:08 +0000,
Andy Shevchenko <andy.shevchenko@gmail.com> wrote:

[...]

> > +#define TIMER_FIRING(x)                                                        \
> > +       (((x) & (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_MASK |            \
> > +                ARCH_TIMER_CTRL_IT_STAT)) ==                                  \
> > +        (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT))
> 
> It's a bit hard to read. Perhaps
> 
> #define FOO_MASK  (_ENABLE | _STAT)
> #define _FIRING ... (FOO_MASK | _MASK == FOO_MASK)

The expression above is a direct translation of the architecture
reference manual, and I'd rather not have that hidden behind a bunch
of obscure macros.

[...]

> > +       irqc->hw_domain = irq_domain_create_linear(of_node_to_fwnode(node),
> > +                                                  irqc->nr_hw + AIC_NR_FIQ,
> > +                                                  &aic_irq_domain_ops, irqc);
> 
> If you are sure it will be always OF-only, why not to use
> irq_domain_add_linear()?

The OF-only API is deprecated, and there is no point in using it for
*new* code, specially when things like IPI allocation require the use
of the modern API. For arm64 root controllers, that's the way to go.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-03-08 11:50     ` Marc Zyngier
@ 2021-03-08 12:02       ` Andy Shevchenko
  0 siblings, 0 replies; 136+ messages in thread
From: Andy Shevchenko @ 2021-03-08 12:02 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Hector Martin, linux-arm Mailing List, Rob Herring,
	Arnd Bergmann, Olof Johansson, Krzysztof Kozlowski,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Will Deacon, Linus Walleij, Mark Rutland,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree,
	open list:SERIAL DRIVERS, Linux Documentation List,
	Linux Samsung SOC, Linux-Arch, Linux Kernel Mailing List

On Mon, Mar 8, 2021 at 1:50 PM Marc Zyngier <maz@kernel.org> wrote:
> On Fri, 05 Mar 2021 15:05:08 +0000,
> Andy Shevchenko <andy.shevchenko@gmail.com> wrote:

...

> > > +#define TIMER_FIRING(x)                                                        \
> > > +       (((x) & (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_MASK |            \
> > > +                ARCH_TIMER_CTRL_IT_STAT)) ==                                  \
> > > +        (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT))
> >
> > It's a bit hard to read. Perhaps
> >
> > #define FOO_MASK  (_ENABLE | _STAT)
> > #define _FIRING ... (FOO_MASK | _MASK == FOO_MASK)
>
> The expression above is a direct translation of the architecture
> reference manual, and I'd rather not have that hidden behind a bunch
> of obscure macros.

OK!

...

> > > +       irqc->hw_domain = irq_domain_create_linear(of_node_to_fwnode(node),
> > > +                                                  irqc->nr_hw + AIC_NR_FIQ,
> > > +                                                  &aic_irq_domain_ops, irqc);
> >
> > If you are sure it will be always OF-only, why not to use
> > irq_domain_add_linear()?
>
> The OF-only API is deprecated, and there is no point in using it for
> *new* code, specially when things like IPI allocation require the use
> of the modern API. For arm64 root controllers, that's the way to go.

Good to know, thanks!

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  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 13:31   ` Marc Zyngier
  2021-03-26  7:57     ` Hector Martin
  2021-03-24 19:57   ` Will Deacon
  2 siblings, 1 reply; 136+ messages in thread
From: Marc Zyngier @ 2021-03-08 13:31 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Thu, 04 Mar 2021 21:38:51 +0000,
Hector Martin <marcan@marcan.st> wrote:
> 
> This is the root interrupt controller used on Apple ARM SoCs such as the
> M1. This irqchip driver performs multiple functions:
> 
> * Handles both IRQs and FIQs
> 
> * Drives the AIC peripheral itself (which handles IRQs)
> 
> * Dispatches FIQs to downstream hard-wired clients (currently the ARM
>   timer).
> 
> * Implements a virtual IPI multiplexer to funnel multiple Linux IPIs
>   into a single hardware IPI
>

[...]

> Signed-off-by: Hector Martin <marcan@marcan.st>
> +static void __exception_irq_entry aic_handle_irq(struct pt_regs *regs)
> +{
> +	struct aic_irq_chip *ic = aic_irqc;
> +	u32 event, type, irq;
> +
> +	do {
> +		/*
> +		 * We cannot use a relaxed read here, as DMA needs to be
> +		 * ordered with respect to the IRQ firing.
> +		 */
> +		event = readl(ic->base + AIC_EVENT);
> +		type = FIELD_GET(AIC_EVENT_TYPE, event);
> +		irq = FIELD_GET(AIC_EVENT_NUM, event);
> +
> +		if (type == AIC_EVENT_TYPE_HW)
> +			handle_domain_irq(aic_irqc->hw_domain, irq, regs);
> +		else if (type == AIC_EVENT_TYPE_IPI && irq == 1)
> +			aic_handle_ipi(regs);
> +		else if (event != 0)
> +			pr_err("Unknown IRQ event %d, %d\n", type, irq);
> +	} while (event);
> +
> +	/*
> +	 * vGIC maintenance interrupts end up here too, so we need to check
> +	 * for them separately. Just report and disable vGIC for now, until
> +	 * we implement this properly.
> +	 */
> +	if ((read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EN) &&
> +		read_sysreg_s(SYS_ICH_MISR_EL2) != 0) {
> +		pr_err("vGIC IRQ fired, disabling.\n");

Please add a _ratelimited here. Whilst debugging KVM on this machine,
I ended up with this firing at such a rate that it was impossible to
do anything useful. Ratelimiting it allowed me to pinpoint the
problem.

[...]

> +/*
> + * FIQ irqchip
> + */
> +
> +static void aic_fiq_mask(struct irq_data *d)
> +{
> +	/* Only the guest timers have real mask bits, unfortunately. */
> +	switch (d->hwirq) {
> +	case AIC_TMR_GUEST_PHYS:
> +		sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, VM_TMR_FIQ_ENABLE_P, 0);
> +		break;
> +	case AIC_TMR_GUEST_VIRT:
> +		sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, VM_TMR_FIQ_ENABLE_V, 0);
> +		break;
> +	}
> +}
> +
> +static void aic_fiq_unmask(struct irq_data *d)
> +{
> +	switch (d->hwirq) {
> +	case AIC_TMR_GUEST_PHYS:
> +		sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, 0, VM_TMR_FIQ_ENABLE_P);
> +		break;
> +	case AIC_TMR_GUEST_VIRT:
> +		sysreg_clear_set_s(SYS_APL_VM_TMR_FIQ_ENA_EL1, 0, VM_TMR_FIQ_ENABLE_V);
> +		break;
> +	}
> +}
> +
> +static void aic_fiq_eoi(struct irq_data *d)
> +{
> +	/* We mask to ack (where we can), so we need to unmask at EOI. */
> +	if (!irqd_irq_disabled(d) && !irqd_irq_masked(d))

Ah, be careful here: irqd_irq_masked() doesn't do what you think it
does for per-CPU interrupts. It's been on my list to fix for the rVIC
implementation, but I never got around to doing it, and all decent ICs
hide this from SW by having a HW-managed mask, similar to what is on
the IRQ side.

I can see two possibilities:

- you can track the masked state directly and use that instead of
  these predicates

- you can just drop the masking altogether as this is only useful to a
  hosted hypervisor (KVM), which will have to do its own masking
  behind the scenes anyway

> +		aic_fiq_unmask(d);
> +}
> +

The rest looks good to me.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 17/27] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE
  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
  0 siblings, 1 reply; 136+ messages in thread
From: Marc Zyngier @ 2021-03-08 15:35 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Thu, 04 Mar 2021 21:38:52 +0000,
Hector Martin <marcan@marcan.st> wrote:
> 
> This adds a Kconfig option to toggle support for Apple ARM SoCs.
> At this time this targets the M1 and later "Apple Silicon" Mac SoCs.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  arch/arm64/Kconfig.platforms | 8 ++++++++
>  arch/arm64/configs/defconfig | 1 +
>  2 files changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index cdfd5fed457f..c2b5791e3d69 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -36,6 +36,14 @@ config ARCH_ALPINE
>  	  This enables support for the Annapurna Labs Alpine
>  	  Soc family.
>  
> +config ARCH_APPLE
> +	bool "Apple Silicon SoC family"
> +	select APPLE_AIC
> +	select ARM64_FIQ_SUPPORT

Do we still need this FIQ symbol? I though it was now gone...

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-05 21:17       ` Arnd Bergmann
@ 2021-03-08 15:56         ` Rob Herring
  2021-03-08 20:29           ` Arnd Bergmann
  0 siblings, 1 reply; 136+ messages in thread
From: Rob Herring @ 2021-03-08 15:56 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Fri, Mar 5, 2021 at 2:17 PM Arnd Bergmann <arnd@kernel.org> wrote:
>
> On Fri, Mar 5, 2021 at 7:18 PM Hector Martin <marcan@marcan.st> wrote:
> >
> > On 06/03/2021 02.39, Rob Herring wrote:
> > >> -       return ioremap(res.start, resource_size(&res));
> > >> +       if (res.flags & IORESOURCE_MEM_NONPOSTED)
> > >> +               return ioremap_np(res.start, resource_size(&res));
> > >> +       else
> > >> +               return ioremap(res.start, resource_size(&res));
> > >
> > > This and the devm variants all scream for a ioremap_extended()
> > > function. IOW, it would be better if the ioremap flavor was a
> > > parameter. Unless we could implement that just for arm64 first, that's
> > > a lot of refactoring...
> >
> > I agree, but yeah... that's one big refactor to try to do now...
>
> FWIW, there is ioremap_prot() that Christoph introduced in 2019
> for a few architectures.  I suppose it would be nice to lift
> that out architecture specific code and completely replace the
> unusual variants, leaving only ioremap(), ioremap_prot() and
> memremap() but dropping the _nc, _cached, _wc, _wt and _np
> versions in favor of an extensible set of flags.
>
> Then again, I would not make that a prerequisite for the merge
> of the M1 support.
>
> > > What's the code path using these functions on the M1 where we need to
> > > return 'posted'? It's just downstream PCI mappings (PCI memory space),
> > > right? Those would never hit these paths because they don't have a DT
> > > node or if they do the memory space is not part of it. So can't the
> > > check just be:
> > >
> > > bool of_mmio_is_nonposted(struct device_node *np)
> > > {
> > >      return np && of_machine_is_compatible("apple,arm-platform");
> > > }
> >
> > Yes; the implementation was trying to be generic, but AIUI we don't need
> > this on M1 because the PCI mappings don't go through this codepath, and
> > nothing else needs posted mode. My first hack was something not too
> > unlike this, then I was going to get rid of apple,arm-platform and just
> > have this be a generic mechanism with the properties, but then we added
> > the optimization to not do the lookups on other platforms, and now we're
> > coming full circle... :-)
>
> I never liked the idea of having a list of platforms that need a
> special hack, please let's not go back to that.

I'm a fan of generic solutions as much as anyone, but not when there's
a single user. Yes, there could be more, but we haven't seen any yet
and Apple seems to have a knack for doing special things. I'm pretty
sure posted vs. non-posted has been a possibility with AXI buses from
the start, so it's not like this is a new thing we're going to see
frequently on new platforms.

A generic property we have to support forever because there's zero
visibility if someone uses them. At least with something platform
specific, we know if it's in use or can be removed. That's something I
just checked recently with some of the PPC irq work-arounds (spoiler:
yes, those 'old world Mac' are). I'm a bit less worried about this
aspect given we can probably assume someone will still be using M1
Macs in 20+ years.

The other situation I worry about here is another arch has implicitly
defaulted to non-posted instead of posted. It could just be non-posted
was what worked everywhere and Linux couldn't distinguish. Now someone
sees we have this new posted vs. non-posted handling and can optimize
some mappings on their platform and we have to have per arch defaults
(like 'dma-coherent' now).

Rob

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support
  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
  3 siblings, 0 replies; 136+ messages in thread
From: Tony Lindgren @ 2021-03-08 17:14 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

* Hector Martin <marcan@marcan.st> [210304 21:40]:
> Not all platforms provide the same set of timers/interrupts, and Linux
> only needs one (plus kvm/guest ones); some platforms are working around
> this by using dummy fake interrupts. Implementing interrupt-names allows
> the devicetree to specify an arbitrary set of available interrupts, so
> the timer code can pick the right one.
> 
> This also adds the hyp-virt timer/interrupt, which was previously not
> expressed in the fixed 4-interrupt form.

I like this one too:

Reviewed-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 02/27] dt-bindings: vendor-prefixes: Add apple prefix
  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
  0 siblings, 0 replies; 136+ messages in thread
From: Rob Herring @ 2021-03-08 20:26 UTC (permalink / raw)
  To: Hector Martin
  Cc: Alexander Graf, Andy Shevchenko, linux-serial, linux-doc,
	linux-arch, Catalin Marinas, Christoph Hellwig, devicetree,
	Tony Lindgren, Olof Johansson, Mark Kettenis, Greg Kroah-Hartman,
	linux-samsung-soc, Krzysztof Kozlowski, Jonathan Corbet,
	Linus Walleij, David S. Miller, Arnd Bergmann, Will Deacon,
	linux-kernel, Mark Rutland, linux-arm-kernel, Marc Zyngier,
	Mohamed Mediouni, Stan Skowronek

On Fri, 05 Mar 2021 06:38:37 +0900, Hector Martin wrote:
> This is different from the legacy AAPL prefix used on PPC, but
> consensus is that we prefer `apple` for these new platforms.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 03/27] dt-bindings: arm: apple: Add bindings for Apple ARM platforms
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Rob Herring @ 2021-03-08 20:27 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-serial, Marc Zyngier, Arnd Bergmann, Mark Rutland,
	Andy Shevchenko, linux-samsung-soc, linux-doc,
	Krzysztof Kozlowski, Olof Johansson, David S. Miller,
	Alexander Graf, Greg Kroah-Hartman, Stan Skowronek,
	Tony Lindgren, Linus Walleij, linux-arm-kernel, devicetree,
	Catalin Marinas, Jonathan Corbet, Will Deacon, Mark Kettenis,
	Christoph Hellwig, linux-kernel, linux-arch, Mohamed Mediouni

On Fri, 05 Mar 2021 06:38:38 +0900, Hector Martin wrote:
> This introduces bindings for all three 2020 Apple M1 devices:
> 
> * apple,j274 - Mac mini (M1, 2020)
> * apple,j293 - MacBook Pro (13-inch, M1, 2020)
> * apple,j313 - MacBook Air (M1, 2020)
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  .../devicetree/bindings/arm/apple.yaml        | 64 +++++++++++++++++++
>  MAINTAINERS                                   | 10 +++
>  2 files changed, 74 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/apple.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 04/27] dt-bindings: arm: cpus: Add apple,firestorm & icestorm compatibles
  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
  0 siblings, 0 replies; 136+ messages in thread
From: Rob Herring @ 2021-03-08 20:27 UTC (permalink / raw)
  To: Hector Martin
  Cc: Alexander Graf, Arnd Bergmann, Mark Rutland, linux-serial,
	Mark Kettenis, Tony Lindgren, Will Deacon, linux-doc,
	Andy Shevchenko, linux-arch, linux-samsung-soc, linux-arm-kernel,
	Catalin Marinas, devicetree, David S. Miller, Mohamed Mediouni,
	Christoph Hellwig, Marc Zyngier, Krzysztof Kozlowski,
	Jonathan Corbet, Olof Johansson, Linus Walleij,
	Greg Kroah-Hartman, Stan Skowronek, linux-kernel

On Fri, 05 Mar 2021 06:38:39 +0900, Hector Martin wrote:
> These are the CPU cores in the "Apple Silicon" M1 SoC.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  Documentation/devicetree/bindings/arm/cpus.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-08 15:56         ` Rob Herring
@ 2021-03-08 20:29           ` Arnd Bergmann
  2021-03-08 21:13             ` Rob Herring
  0 siblings, 1 reply; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-08 20:29 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Mon, Mar 8, 2021 at 4:56 PM Rob Herring <robh@kernel.org> wrote:
> On Fri, Mar 5, 2021 at 2:17 PM Arnd Bergmann <arnd@kernel.org> wrote:
> > On Fri, Mar 5, 2021 at 7:18 PM Hector Martin <marcan@marcan.st> wrote:
>
> > > > What's the code path using these functions on the M1 where we need to
> > > > return 'posted'? It's just downstream PCI mappings (PCI memory space),
> > > > right? Those would never hit these paths because they don't have a DT
> > > > node or if they do the memory space is not part of it. So can't the
> > > > check just be:
> > > >
> > > > bool of_mmio_is_nonposted(struct device_node *np)
> > > > {
> > > >      return np && of_machine_is_compatible("apple,arm-platform");
> > > > }
> > >
> > > Yes; the implementation was trying to be generic, but AIUI we don't need
> > > this on M1 because the PCI mappings don't go through this codepath, and
> > > nothing else needs posted mode. My first hack was something not too
> > > unlike this, then I was going to get rid of apple,arm-platform and just
> > > have this be a generic mechanism with the properties, but then we added
> > > the optimization to not do the lookups on other platforms, and now we're
> > > coming full circle... :-)
> >
> > I never liked the idea of having a list of platforms that need a
> > special hack, please let's not go back to that.
>
> I'm a fan of generic solutions as much as anyone, but not when there's
> a single user. Yes, there could be more, but we haven't seen any yet
> and Apple seems to have a knack for doing special things. I'm pretty
> sure posted vs. non-posted has been a possibility with AXI buses from
> the start, so it's not like this is a new thing we're going to see
> frequently on new platforms.

Ok, but if we make it a platform specific bit, I would prefer not
to do the IORESOURCE_MEM_NONPOSTED flag either but
instead keep the logic in the device drivers that call ioremap().

This is obviously more work for the drivers, but at least it keeps
the common code free of the hack while also allowing drivers to
use ioremap_np() intentionally on other platforms.

> The other situation I worry about here is another arch has implicitly
> defaulted to non-posted instead of posted. It could just be non-posted
> was what worked everywhere and Linux couldn't distinguish. Now someone
> sees we have this new posted vs. non-posted handling and can optimize
> some mappings on their platform and we have to have per arch defaults
> (like 'dma-coherent' now).

I think one of the dark secrets of MMIO is that a lot of drivers
get the posted behavior wrong by assuming that a writel() before
a spin_unlock() is protected by that unlock. This may in fact work
on many architectures but is broken on PCI and on local devices
for ARM.

Having a properly working (on non-PCI) ioremap_np() interface
would be nice here, as it could be used to document when drivers
rely on non-posted behavior, and cause the ioremap to fail when
running on architectures that don't support nonposted maps.

       Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support
  2021-03-04 21:38 ` [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support Hector Martin
                     ` (2 preceding siblings ...)
  2021-03-08 17:14   ` Tony Lindgren
@ 2021-03-08 20:38   ` Rob Herring
  2021-03-08 22:42     ` Marc Zyngier
  3 siblings, 1 reply; 136+ messages in thread
From: Rob Herring @ 2021-03-08 20:38 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Fri, Mar 05, 2021 at 06:38:41AM +0900, Hector Martin wrote:
> Not all platforms provide the same set of timers/interrupts, and Linux
> only needs one (plus kvm/guest ones); some platforms are working around
> this by using dummy fake interrupts. Implementing interrupt-names allows
> the devicetree to specify an arbitrary set of available interrupts, so
> the timer code can pick the right one.
> 
> This also adds the hyp-virt timer/interrupt, which was previously not
> expressed in the fixed 4-interrupt form.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  .../devicetree/bindings/timer/arm,arch_timer.yaml  | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
> index 2c75105c1398..ebe9b0bebe41 100644
> --- a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
> +++ b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
> @@ -34,11 +34,25 @@ properties:
>                - arm,armv8-timer
>  
>    interrupts:
> +    minItems: 1
> +    maxItems: 5
>      items:
>        - description: secure timer irq
>        - description: non-secure timer irq
>        - description: virtual timer irq
>        - description: hypervisor timer irq
> +      - description: hypervisor virtual timer irq
> +
> +  interrupt-names:
> +    minItems: 1
> +    maxItems: 5
> +    items:
> +      enum:
> +        - phys-secure
> +        - phys
> +        - virt
> +        - hyp-phys
> +        - hyp-virt

phys-secure and hyp-phys is not very consistent. secure-phys or sec-phys 
instead?

This allows any order which is not ideal (unfortunately json-schema 
doesn't have a way to define order with optional entries in the middle). 
How many possible combinations are there which make sense? If that's a 
reasonable number, I'd rather see them listed out.

Rob

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-08 20:29           ` Arnd Bergmann
@ 2021-03-08 21:13             ` Rob Herring
  2021-03-08 21:56               ` Arnd Bergmann
  2021-03-09 11:14               ` Linus Walleij
  0 siblings, 2 replies; 136+ messages in thread
From: Rob Herring @ 2021-03-08 21:13 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Mon, Mar 08, 2021 at 09:29:54PM +0100, Arnd Bergmann wrote:
> On Mon, Mar 8, 2021 at 4:56 PM Rob Herring <robh@kernel.org> wrote:
> > On Fri, Mar 5, 2021 at 2:17 PM Arnd Bergmann <arnd@kernel.org> wrote:
> > > On Fri, Mar 5, 2021 at 7:18 PM Hector Martin <marcan@marcan.st> wrote:
> >
> > > > > What's the code path using these functions on the M1 where we need to
> > > > > return 'posted'? It's just downstream PCI mappings (PCI memory space),
> > > > > right? Those would never hit these paths because they don't have a DT
> > > > > node or if they do the memory space is not part of it. So can't the
> > > > > check just be:
> > > > >
> > > > > bool of_mmio_is_nonposted(struct device_node *np)
> > > > > {
> > > > >      return np && of_machine_is_compatible("apple,arm-platform");
> > > > > }
> > > >
> > > > Yes; the implementation was trying to be generic, but AIUI we don't need
> > > > this on M1 because the PCI mappings don't go through this codepath, and
> > > > nothing else needs posted mode. My first hack was something not too
> > > > unlike this, then I was going to get rid of apple,arm-platform and just
> > > > have this be a generic mechanism with the properties, but then we added
> > > > the optimization to not do the lookups on other platforms, and now we're
> > > > coming full circle... :-)
> > >
> > > I never liked the idea of having a list of platforms that need a
> > > special hack, please let's not go back to that.
> >
> > I'm a fan of generic solutions as much as anyone, but not when there's
> > a single user. Yes, there could be more, but we haven't seen any yet
> > and Apple seems to have a knack for doing special things. I'm pretty
> > sure posted vs. non-posted has been a possibility with AXI buses from
> > the start, so it's not like this is a new thing we're going to see
> > frequently on new platforms.
> 
> Ok, but if we make it a platform specific bit, I would prefer not
> to do the IORESOURCE_MEM_NONPOSTED flag either but
> instead keep the logic in the device drivers that call ioremap().

That seems like an orthogonal decision to me.

> This is obviously more work for the drivers, but at least it keeps
> the common code free of the hack while also allowing drivers to
> use ioremap_np() intentionally on other platforms.

I don't agree. The problem is within the interconnect. The device and 
its driver are unaware of this.

The other idea I had was doing a compatible other than 'simple-bus' for 
the bus node which could imply non-posted io and any other quirks in 
Apple's bus implementation. However, something different there means 
updates in lots of places (schemas, dtc checks, etc.) unless we kept 
'simple-bus' as a fallback.

Let's just stick with 'nonposted-mmio', but drop 'posted-mmio'. I'd 
rather know if and when we need 'posted-mmio'. It does need to be added 
to the DT spec[1] and schema[2] though (GH PRs are fine for both).

> > The other situation I worry about here is another arch has implicitly
> > defaulted to non-posted instead of posted. It could just be non-posted
> > was what worked everywhere and Linux couldn't distinguish. Now someone
> > sees we have this new posted vs. non-posted handling and can optimize
> > some mappings on their platform and we have to have per arch defaults
> > (like 'dma-coherent' now).
> 
> I think one of the dark secrets of MMIO is that a lot of drivers
> get the posted behavior wrong by assuming that a writel() before
> a spin_unlock() is protected by that unlock. This may in fact work
> on many architectures but is broken on PCI and on local devices
> for ARM.
> 
> Having a properly working (on non-PCI) ioremap_np() interface
> would be nice here, as it could be used to document when drivers
> rely on non-posted behavior, and cause the ioremap to fail when
> running on architectures that don't support nonposted maps.

Good to know.

Rob

[1] https://github.com/devicetree-org/devicetree-specification
[2] https://github.com/devicetree-org/dt-schema

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 15/27] dt-bindings: interrupt-controller: Add DT bindings for apple-aic
  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
  0 siblings, 0 replies; 136+ messages in thread
From: Rob Herring @ 2021-03-08 21:16 UTC (permalink / raw)
  To: Hector Martin
  Cc: Tony Lindgren, Greg Kroah-Hartman, linux-arch, linux-arm-kernel,
	linux-kernel, Andy Shevchenko, Mohamed Mediouni, Jonathan Corbet,
	Krzysztof Kozlowski, Mark Rutland, Marc Zyngier, Will Deacon,
	devicetree, Olof Johansson, Catalin Marinas, David S. Miller,
	Alexander Graf, linux-doc, Mark Kettenis, Linus Walleij,
	Christoph Hellwig, Arnd Bergmann, linux-serial,
	linux-samsung-soc, Stan Skowronek

On Fri, 05 Mar 2021 06:38:50 +0900, Hector Martin wrote:
> AIC is the Apple Interrupt Controller found on Apple ARM SoCs, such as
> the M1.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  .../interrupt-controller/apple,aic.yaml       | 88 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  .../interrupt-controller/apple-aic.h          | 15 ++++
>  3 files changed, 104 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
>  create mode 100644 include/dt-bindings/interrupt-controller/apple-aic.h
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 23/27] dt-bindings: serial: samsung: Add apple,s5l-uart compatible
  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
  0 siblings, 0 replies; 136+ messages in thread
From: Rob Herring @ 2021-03-08 21:17 UTC (permalink / raw)
  To: Hector Martin
  Cc: David S. Miller, Krzysztof Kozlowski, linux-samsung-soc,
	Stan Skowronek, Linus Walleij, linux-arm-kernel, linux-kernel,
	Mark Kettenis, devicetree, Greg Kroah-Hartman, Tony Lindgren,
	Jonathan Corbet, Catalin Marinas, linux-doc, Marc Zyngier,
	Olof Johansson, Alexander Graf, Christoph Hellwig, Will Deacon,
	Arnd Bergmann, Andy Shevchenko, linux-arch, Mark Rutland,
	Mohamed Mediouni, linux-serial

On Fri, 05 Mar 2021 06:38:58 +0900, Hector Martin wrote:
> Apple mobile devices originally used Samsung SoCs (starting with the
> S5L8900), and their current in-house SoCs continue to use compatible
> UART peripherals. We'll call this UART variant apple,s5l-uart.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  Documentation/devicetree/bindings/serial/samsung_uart.yaml | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 26/27] dt-bindings: display: Add apple,simple-framebuffer
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Rob Herring @ 2021-03-08 21:18 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-samsung-soc, Stan Skowronek, Andy Shevchenko,
	Greg Kroah-Hartman, Krzysztof Kozlowski, Catalin Marinas,
	Olof Johansson, linux-arm-kernel, Mark Kettenis, Alexander Graf,
	linux-serial, devicetree, Mohamed Mediouni, David S. Miller,
	Arnd Bergmann, Jonathan Corbet, linux-arch, linux-doc,
	Tony Lindgren, linux-kernel, Marc Zyngier, Will Deacon,
	Mark Rutland, Linus Walleij, Christoph Hellwig

On Fri, 05 Mar 2021 06:39:01 +0900, Hector Martin wrote:
> Apple SoCs run firmware that sets up a simplefb-compatible framebuffer
> for us. Add a compatible for it, and two missing supported formats.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  .../devicetree/bindings/display/simple-framebuffer.yaml      | 5 +++++
>  1 file changed, 5 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-08 21:13             ` Rob Herring
@ 2021-03-08 21:56               ` Arnd Bergmann
  2021-03-09 15:48                 ` Rob Herring
  2021-03-09 11:14               ` Linus Walleij
  1 sibling, 1 reply; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-08 21:56 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Mon, Mar 8, 2021 at 10:14 PM Rob Herring <robh@kernel.org> wrote:
> On Mon, Mar 08, 2021 at 09:29:54PM +0100, Arnd Bergmann wrote:
> > On Mon, Mar 8, 2021 at 4:56 PM Rob Herring <robh@kernel.org> wrote:
>
> Let's just stick with 'nonposted-mmio', but drop 'posted-mmio'. I'd
> rather know if and when we need 'posted-mmio'. It does need to be added
> to the DT spec[1] and schema[2] though (GH PRs are fine for both).

I think the reason for having "posted-mmio" is that you cannot properly
define the PCI host controller nodes on the M1 without that: Since
nonposted-mmio applies to all child nodes, this would mean the PCI
memory space gets declared as nonposted by the DT, but the hardware
requires it to be mapped as posted.

       Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support
  2021-03-08 20:38   ` Rob Herring
@ 2021-03-08 22:42     ` Marc Zyngier
  2021-03-09 16:11       ` Rob Herring
  0 siblings, 1 reply; 136+ messages in thread
From: Marc Zyngier @ 2021-03-08 22:42 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hector Martin, linux-arm-kernel, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Mon, 08 Mar 2021 20:38:41 +0000,
Rob Herring <robh@kernel.org> wrote:
> 
> On Fri, Mar 05, 2021 at 06:38:41AM +0900, Hector Martin wrote:
> > Not all platforms provide the same set of timers/interrupts, and Linux
> > only needs one (plus kvm/guest ones); some platforms are working around
> > this by using dummy fake interrupts. Implementing interrupt-names allows
> > the devicetree to specify an arbitrary set of available interrupts, so
> > the timer code can pick the right one.
> > 
> > This also adds the hyp-virt timer/interrupt, which was previously not
> > expressed in the fixed 4-interrupt form.
> > 
> > Signed-off-by: Hector Martin <marcan@marcan.st>
> > ---
> >  .../devicetree/bindings/timer/arm,arch_timer.yaml  | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
> > index 2c75105c1398..ebe9b0bebe41 100644
> > --- a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
> > +++ b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
> > @@ -34,11 +34,25 @@ properties:
> >                - arm,armv8-timer
> >  
> >    interrupts:
> > +    minItems: 1
> > +    maxItems: 5
> >      items:
> >        - description: secure timer irq
> >        - description: non-secure timer irq
> >        - description: virtual timer irq
> >        - description: hypervisor timer irq
> > +      - description: hypervisor virtual timer irq
> > +
> > +  interrupt-names:
> > +    minItems: 1
> > +    maxItems: 5
> > +    items:
> > +      enum:
> > +        - phys-secure
> > +        - phys
> > +        - virt
> > +        - hyp-phys
> > +        - hyp-virt
> 
> phys-secure and hyp-phys is not very consistent. secure-phys or sec-phys 
> instead?
> 
> This allows any order which is not ideal (unfortunately json-schema 
> doesn't have a way to define order with optional entries in the middle). 
> How many possible combinations are there which make sense? If that's a 
> reasonable number, I'd rather see them listed out.

The available of interrupts are a function of the number of security
states, privileged exception levels and architecture revisions, as
described in D11.1.1:

<quote>
- An EL1 physical timer.
- A Non-secure EL2 physical timer.
- An EL3 physical timer.
- An EL1 virtual timer.
- A Non-secure EL2 virtual timer.
- A Secure EL2 virtual timer.
- A Secure EL2 physical timer.
</quote>

* Single security state, EL1 only, ARMv7 & ARMv8.0+ (assumed NS):
  - physical, virtual

* Single security state, EL1 + EL2, ARMv7 & ARMv8.0 (assumed NS)
  - physical, virtual, hyp physical

* Single security state, EL1 + EL2, ARMv8.1+ (assumed NS)
  - physical, virtual, hyp physical, hyp virtual

* Two security states, EL1 + EL3, ARMv7 & ARMv8.0+:
  - secure physical, physical, virtual

* Two security states, EL1 + EL2 + EL3, ARMv7 & ARMv8.0
  - secure physical, physical, virtual, hyp physical

* Two security states, EL1 + EL2 + EL3, ARMv8.1+
  - secure physical, physical, virtual, hyp physical, hyp virtual

* Two security states, EL1 + EL2 + S-EL2 + EL3, ARMv8.4+
  - secure physical, physical, virtual, hyp physical, hyp virtual,
    secure hyp physical, secure hyp virtual

Nobody has seen the last combination in the wild (that is, outside of
a SW model).

I'm really not convinced we want to express this kind of complexity in
the binding (each of the 7 cases), specially given that we don't
encode the underlying HW architecture level or number of exception
levels anywhere, and have ho way to validate such information.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-08 21:13             ` Rob Herring
  2021-03-08 21:56               ` Arnd Bergmann
@ 2021-03-09 11:14               ` Linus Walleij
  2021-03-09 12:41                 ` Arnd Bergmann
  1 sibling, 1 reply; 136+ messages in thread
From: Linus Walleij @ 2021-03-09 11:14 UTC (permalink / raw)
  To: Rob Herring
  Cc: Arnd Bergmann, Hector Martin, linux-arm-kernel, Marc Zyngier,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Mon, Mar 8, 2021 at 10:13 PM Rob Herring <robh@kernel.org> wrote:
> On Mon, Mar 08, 2021 at 09:29:54PM +0100, Arnd Bergmann wrote:

> > This is obviously more work for the drivers, but at least it keeps
> > the common code free of the hack while also allowing drivers to
> > use ioremap_np() intentionally on other platforms.
>
> I don't agree. The problem is within the interconnect. The device and
> its driver are unaware of this.

If it is possible that a driver needs to use posted access on one
SoC and nonposted on another SoC then clearly the nature
of the access need to be part of the memory access abstraction,
obviously ioremap() one way or another.

Having the driver conditionally use different ioremap_*
functions depending on SoC seems awkward. We had different
execution paths for OF and ACPI drivers and have been working
hard to create fwnode to abstract this away for drivers used with
both abstractions for example. If we can hide it from drivers
from day 1 I think we can save maintenance costs in the long
run.

Given that the Apple silicon through it's heritage from Samsung
S3C (the genealogy is unclear to me) already share drivers with
this platform, this seems to already be the case so it's not a
theoretical use case.

The core argument here seems to be "will this become common
practice or is it an Apple-ism?"

That is a question to someone who is deep down there
synthesizing SoCs. It appears the market for custom silicon
laptops has just begun. There are people that can answer this
question but I doubt that we have access to them or that they
would tell us. What is an educated guess? It seems Arnds
position is that it's an Apple-ism and I kind of trust him on this.
At the same time I know that in emerging markets, what
copycats are likely to do is say "give me exactly what Apple
has, exactly that thing".

Just my €0.01
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-09 11:14               ` Linus Walleij
@ 2021-03-09 12:41                 ` Arnd Bergmann
  2021-03-09 15:40                   ` Linus Walleij
  0 siblings, 1 reply; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-09 12:41 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rob Herring, Hector Martin, linux-arm-kernel, Marc Zyngier,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Tue, Mar 9, 2021 at 12:14 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> On Mon, Mar 8, 2021 at 10:13 PM Rob Herring <robh@kernel.org> wrote:
> > On Mon, Mar 08, 2021 at 09:29:54PM +0100, Arnd Bergmann wrote:
>
> > > This is obviously more work for the drivers, but at least it keeps
> > > the common code free of the hack while also allowing drivers to
> > > use ioremap_np() intentionally on other platforms.
> >
> > I don't agree. The problem is within the interconnect. The device and
> > its driver are unaware of this.
>
> If it is possible that a driver needs to use posted access on one
> SoC and nonposted on another SoC then clearly the nature
> of the access need to be part of the memory access abstraction,
> obviously ioremap() one way or another.

There are two possible scenarios:

- drivers that we already know are shared between apple and
  other vendors (s3c-serial, pasemi i2c) would need to use
  nonposted mmio on Apple but can use either one on other
  platforms. On non-ARM CPUs, the ioremap_np() function
  might fail when the hardware only supports posted writes.

- A driver writer may want to choose between posted and
  nonposted mmio based on performance considerations:
  if writes are never serialized, posted writes should always
  be faster. However, if the driver uses a spinlock to serialize
  writes, then a nonposted write is likely faster than a posted
  write followed by a read that serializes the spin_unlock.
  In this case we want the driver to explicitly pick one over
  the other, and not have rely on bus specific magic.

> Having the driver conditionally use different ioremap_*
> functions depending on SoC seems awkward. We had different
> execution paths for OF and ACPI drivers and have been working
> hard to create fwnode to abstract this away for drivers used with
> both abstractions for example. If we can hide it from drivers
> from day 1 I think we can save maintenance costs in the long
> run.
>
> Given that the Apple silicon through it's heritage from Samsung
> S3C (the genealogy is unclear to me) already share drivers with
> this platform, this seems to already be the case so it's not a
> theoretical use case.

As far as I can tell, there are only a handful of soc specific drivers
that are actually shared with other platforms. Aside from serial
and i2c, these are the ones that I can see being shared:

- there is an on-chip nvme host controller that is not PCI. So far,
  nobody else does this, but it can clearly happen in the future

- I think one of the USB controllers is a standard designware
  part, while the others are PCI devices.

- The PCI host bridge may be close enough to the standard
   that we can use the generic driver for config space access.

        Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-09 12:41                 ` Arnd Bergmann
@ 2021-03-09 15:40                   ` Linus Walleij
  0 siblings, 0 replies; 136+ messages in thread
From: Linus Walleij @ 2021-03-09 15:40 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rob Herring, Hector Martin, linux-arm-kernel, Marc Zyngier,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Tue, Mar 9, 2021 at 1:41 PM Arnd Bergmann <arnd@kernel.org> wrote:

> - A driver writer may want to choose between posted and
>   nonposted mmio based on performance considerations:
>   if writes are never serialized, posted writes should always
>   be faster. However, if the driver uses a spinlock to serialize
>   writes, then a nonposted write is likely faster than a posted
>   write followed by a read that serializes the spin_unlock.
>   In this case we want the driver to explicitly pick one over
>   the other, and not have rely on bus specific magic.

OK then I am all for having drivers explicitly choose access
method. Openness to speed optimization is a well established
Linux kernel design principle.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-08 21:56               ` Arnd Bergmann
@ 2021-03-09 15:48                 ` Rob Herring
  2021-03-09 20:23                   ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Rob Herring @ 2021-03-09 15:48 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Mon, Mar 8, 2021 at 2:56 PM Arnd Bergmann <arnd@kernel.org> wrote:
>
> On Mon, Mar 8, 2021 at 10:14 PM Rob Herring <robh@kernel.org> wrote:
> > On Mon, Mar 08, 2021 at 09:29:54PM +0100, Arnd Bergmann wrote:
> > > On Mon, Mar 8, 2021 at 4:56 PM Rob Herring <robh@kernel.org> wrote:
> >
> > Let's just stick with 'nonposted-mmio', but drop 'posted-mmio'. I'd
> > rather know if and when we need 'posted-mmio'. It does need to be added
> > to the DT spec[1] and schema[2] though (GH PRs are fine for both).
>
> I think the reason for having "posted-mmio" is that you cannot properly
> define the PCI host controller nodes on the M1 without that: Since
> nonposted-mmio applies to all child nodes, this would mean the PCI
> memory space gets declared as nonposted by the DT, but the hardware
> requires it to be mapped as posted.

I don't think so. PCI devices wouldn't use any of the code paths in
this patch. They would map their memory space with plain ioremap()
which is posted.

Rob

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support
  2021-03-08 22:42     ` Marc Zyngier
@ 2021-03-09 16:11       ` Rob Herring
  2021-03-09 20:28         ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Rob Herring @ 2021-03-09 16:11 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Hector Martin, linux-arm-kernel, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Mon, Mar 8, 2021 at 3:42 PM Marc Zyngier <maz@kernel.org> wrote:
>
> On Mon, 08 Mar 2021 20:38:41 +0000,
> Rob Herring <robh@kernel.org> wrote:
> >
> > On Fri, Mar 05, 2021 at 06:38:41AM +0900, Hector Martin wrote:
> > > Not all platforms provide the same set of timers/interrupts, and Linux
> > > only needs one (plus kvm/guest ones); some platforms are working around
> > > this by using dummy fake interrupts. Implementing interrupt-names allows
> > > the devicetree to specify an arbitrary set of available interrupts, so
> > > the timer code can pick the right one.
> > >
> > > This also adds the hyp-virt timer/interrupt, which was previously not
> > > expressed in the fixed 4-interrupt form.
> > >
> > > Signed-off-by: Hector Martin <marcan@marcan.st>
> > > ---
> > >  .../devicetree/bindings/timer/arm,arch_timer.yaml  | 14 ++++++++++++++
> > >  1 file changed, 14 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
> > > index 2c75105c1398..ebe9b0bebe41 100644
> > > --- a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
> > > +++ b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
> > > @@ -34,11 +34,25 @@ properties:
> > >                - arm,armv8-timer
> > >
> > >    interrupts:
> > > +    minItems: 1
> > > +    maxItems: 5
> > >      items:
> > >        - description: secure timer irq
> > >        - description: non-secure timer irq
> > >        - description: virtual timer irq
> > >        - description: hypervisor timer irq
> > > +      - description: hypervisor virtual timer irq
> > > +
> > > +  interrupt-names:
> > > +    minItems: 1
> > > +    maxItems: 5
> > > +    items:
> > > +      enum:
> > > +        - phys-secure
> > > +        - phys
> > > +        - virt
> > > +        - hyp-phys
> > > +        - hyp-virt
> >
> > phys-secure and hyp-phys is not very consistent. secure-phys or sec-phys
> > instead?
> >
> > This allows any order which is not ideal (unfortunately json-schema
> > doesn't have a way to define order with optional entries in the middle).
> > How many possible combinations are there which make sense? If that's a
> > reasonable number, I'd rather see them listed out.
>
> The available of interrupts are a function of the number of security
> states, privileged exception levels and architecture revisions, as
> described in D11.1.1:
>
> <quote>
> - An EL1 physical timer.
> - A Non-secure EL2 physical timer.
> - An EL3 physical timer.
> - An EL1 virtual timer.
> - A Non-secure EL2 virtual timer.
> - A Secure EL2 virtual timer.
> - A Secure EL2 physical timer.
> </quote>
>
> * Single security state, EL1 only, ARMv7 & ARMv8.0+ (assumed NS):
>   - physical, virtual
>
> * Single security state, EL1 + EL2, ARMv7 & ARMv8.0 (assumed NS)
>   - physical, virtual, hyp physical
>
> * Single security state, EL1 + EL2, ARMv8.1+ (assumed NS)
>   - physical, virtual, hyp physical, hyp virtual
>
> * Two security states, EL1 + EL3, ARMv7 & ARMv8.0+:
>   - secure physical, physical, virtual
>
> * Two security states, EL1 + EL2 + EL3, ARMv7 & ARMv8.0
>   - secure physical, physical, virtual, hyp physical
>
> * Two security states, EL1 + EL2 + EL3, ARMv8.1+
>   - secure physical, physical, virtual, hyp physical, hyp virtual
>
> * Two security states, EL1 + EL2 + S-EL2 + EL3, ARMv8.4+
>   - secure physical, physical, virtual, hyp physical, hyp virtual,
>     secure hyp physical, secure hyp virtual
>
> Nobody has seen the last combination in the wild (that is, outside of
> a SW model).
>
> I'm really not convinced we want to express this kind of complexity in
> the binding (each of the 7 cases), specially given that we don't
> encode the underlying HW architecture level or number of exception
> levels anywhere, and have ho way to validate such information.

Actually, we can simplify this down to 2 cases:

oneOf:
  - minItems: 2
    items:
      - const: phys
      - const: virt
      - const: hyp-phys
      - const: hyp-virt
  - minItems: 3
    items:
      - const: sec-phys
      - const: phys
      - const: virt
      - const: hyp-phys
      - const: hyp-virt
      - const: sec-hyp-phy
      - const: sec-hyp-virt

And that's below my threshold for not worth the complexity.

Rob

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 26/27] dt-bindings: display: Add apple,simple-framebuffer
  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
  1 sibling, 1 reply; 136+ messages in thread
From: Linus Walleij @ 2021-03-09 16:37 UTC (permalink / raw)
  To: Hector Martin
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On Thu, Mar 4, 2021 at 10:42 PM Hector Martin <marcan@marcan.st> wrote:

> Apple SoCs run firmware that sets up a simplefb-compatible framebuffer
> for us. Add a compatible for it, and two missing supported formats.
>
> Signed-off-by: Hector Martin <marcan@marcan.st>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Marcan: tell me if you need me to apply this to the drm-misc tree
and I'll fix it.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-09 15:48                 ` Rob Herring
@ 2021-03-09 20:23                   ` Hector Martin
  2021-03-09 22:06                     ` Rob Herring
  0 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-09 20:23 UTC (permalink / raw)
  To: Rob Herring, Arnd Bergmann
  Cc: linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On 10/03/2021 00.48, Rob Herring wrote:
> On Mon, Mar 8, 2021 at 2:56 PM Arnd Bergmann <arnd@kernel.org> wrote:
>>
>> On Mon, Mar 8, 2021 at 10:14 PM Rob Herring <robh@kernel.org> wrote:
>>> On Mon, Mar 08, 2021 at 09:29:54PM +0100, Arnd Bergmann wrote:
>>>> On Mon, Mar 8, 2021 at 4:56 PM Rob Herring <robh@kernel.org> wrote:
>>>
>>> Let's just stick with 'nonposted-mmio', but drop 'posted-mmio'. I'd
>>> rather know if and when we need 'posted-mmio'. It does need to be added
>>> to the DT spec[1] and schema[2] though (GH PRs are fine for both).
>>
>> I think the reason for having "posted-mmio" is that you cannot properly
>> define the PCI host controller nodes on the M1 without that: Since
>> nonposted-mmio applies to all child nodes, this would mean the PCI
>> memory space gets declared as nonposted by the DT, but the hardware
>> requires it to be mapped as posted.
> 
> I don't think so. PCI devices wouldn't use any of the code paths in
> this patch. They would map their memory space with plain ioremap()
> which is posted.

My main concern here is that this creates an inconsistency in the device 
tree representation that only works because PCI drivers happen not to 
use these code paths. Logically, having "nonposted-mmio" above the PCI 
controller would imply that it applies to that bus too. Sure, it doesn't 
matter for Linux since it is ignored, but this creates an implicit 
exception that PCI buses always use posted modes.

Then if a device comes along that due to some twisted fabric logic needs 
nonposted nGnRnE mappings for PCIe (even though the actual PCIe ops will 
end up posted at the bus anyway)... how do we represent that? Declare 
that another "nonposted-mmio" on the PCIe bus means "no, really, use 
nonposted mmio for this"?

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 06/27] dt-bindings: timer: arm,arch_timer: Add interrupt-names support
  2021-03-09 16:11       ` Rob Herring
@ 2021-03-09 20:28         ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-09 20:28 UTC (permalink / raw)
  To: Rob Herring, Marc Zyngier
  Cc: linux-arm-kernel, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On 10/03/2021 01.11, Rob Herring wrote:
> On Mon, Mar 8, 2021 at 3:42 PM Marc Zyngier <maz@kernel.org> wrote:
>>
>> On Mon, 08 Mar 2021 20:38:41 +0000,
>> Rob Herring <robh@kernel.org> wrote:
>>>
>>> On Fri, Mar 05, 2021 at 06:38:41AM +0900, Hector Martin wrote:
>>>> Not all platforms provide the same set of timers/interrupts, and Linux
>>>> only needs one (plus kvm/guest ones); some platforms are working around
>>>> this by using dummy fake interrupts. Implementing interrupt-names allows
>>>> the devicetree to specify an arbitrary set of available interrupts, so
>>>> the timer code can pick the right one.
>>>>
>>>> This also adds the hyp-virt timer/interrupt, which was previously not
>>>> expressed in the fixed 4-interrupt form.
>>>>
>>>> Signed-off-by: Hector Martin <marcan@marcan.st>
>>>> ---
>>>>   .../devicetree/bindings/timer/arm,arch_timer.yaml  | 14 ++++++++++++++
>>>>   1 file changed, 14 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
>>>> index 2c75105c1398..ebe9b0bebe41 100644
>>>> --- a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
>>>> +++ b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
>>>> @@ -34,11 +34,25 @@ properties:
>>>>                 - arm,armv8-timer
>>>>
>>>>     interrupts:
>>>> +    minItems: 1
>>>> +    maxItems: 5
>>>>       items:
>>>>         - description: secure timer irq
>>>>         - description: non-secure timer irq
>>>>         - description: virtual timer irq
>>>>         - description: hypervisor timer irq
>>>> +      - description: hypervisor virtual timer irq
>>>> +
>>>> +  interrupt-names:
>>>> +    minItems: 1
>>>> +    maxItems: 5
>>>> +    items:
>>>> +      enum:
>>>> +        - phys-secure
>>>> +        - phys
>>>> +        - virt
>>>> +        - hyp-phys
>>>> +        - hyp-virt
>>>
>>> phys-secure and hyp-phys is not very consistent. secure-phys or sec-phys
>>> instead?
>>>
>>> This allows any order which is not ideal (unfortunately json-schema
>>> doesn't have a way to define order with optional entries in the middle).
>>> How many possible combinations are there which make sense? If that's a
>>> reasonable number, I'd rather see them listed out.
>>
>> The available of interrupts are a function of the number of security
>> states, privileged exception levels and architecture revisions, as
>> described in D11.1.1:
>>
>> <quote>
>> - An EL1 physical timer.
>> - A Non-secure EL2 physical timer.
>> - An EL3 physical timer.
>> - An EL1 virtual timer.
>> - A Non-secure EL2 virtual timer.
>> - A Secure EL2 virtual timer.
>> - A Secure EL2 physical timer.
>> </quote>
>>
>> * Single security state, EL1 only, ARMv7 & ARMv8.0+ (assumed NS):
>>    - physical, virtual
>>
>> * Single security state, EL1 + EL2, ARMv7 & ARMv8.0 (assumed NS)
>>    - physical, virtual, hyp physical
>>
>> * Single security state, EL1 + EL2, ARMv8.1+ (assumed NS)
>>    - physical, virtual, hyp physical, hyp virtual
>>
>> * Two security states, EL1 + EL3, ARMv7 & ARMv8.0+:
>>    - secure physical, physical, virtual
>>
>> * Two security states, EL1 + EL2 + EL3, ARMv7 & ARMv8.0
>>    - secure physical, physical, virtual, hyp physical
>>
>> * Two security states, EL1 + EL2 + EL3, ARMv8.1+
>>    - secure physical, physical, virtual, hyp physical, hyp virtual
>>
>> * Two security states, EL1 + EL2 + S-EL2 + EL3, ARMv8.4+
>>    - secure physical, physical, virtual, hyp physical, hyp virtual,
>>      secure hyp physical, secure hyp virtual
>>
>> Nobody has seen the last combination in the wild (that is, outside of
>> a SW model).
>>
>> I'm really not convinced we want to express this kind of complexity in
>> the binding (each of the 7 cases), specially given that we don't
>> encode the underlying HW architecture level or number of exception
>> levels anywhere, and have ho way to validate such information.
> 
> Actually, we can simplify this down to 2 cases:
> 
> oneOf:
>    - minItems: 2
>      items:
>        - const: phys
>        - const: virt
>        - const: hyp-phys
>        - const: hyp-virt
>    - minItems: 3
>      items:
>        - const: sec-phys
>        - const: phys
>        - const: virt
>        - const: hyp-phys
>        - const: hyp-virt
>        - const: sec-hyp-phy
>        - const: sec-hyp-virt
> 
> And that's below my threshold for not worth the complexity.

This makes sense. Since we aren't using the sec-hyp stuff here, and 
those go at the end of the list, we can omit them from this patch for 
now and add them whenever they're needed for a platform. Does that sound OK?

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs
  2021-03-05 15:51       ` Arnd Bergmann
@ 2021-03-09 20:29         ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-09 20:29 UTC (permalink / raw)
  To: Arnd Bergmann, Andy Shevchenko
  Cc: Linus Walleij, Linux ARM, Marc Zyngier, Rob Herring,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet,
	Catalin Marinas, Christoph Hellwig, David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On 06/03/2021 00.51, Arnd Bergmann wrote:
> On Fri, Mar 5, 2021 at 4:09 PM Andy Shevchenko
> <andy.shevchenko@gmail.com> wrote:
>> On Fri, Mar 5, 2021 at 12:25 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>>> On Thu, Mar 4, 2021 at 10:40 PM Hector Martin <marcan@marcan.st> wrote:
>>>
>>>> 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>
>>>
>>> I like this, I just want one change:
>>>
>>> Put the common ioremap() on top in all paragraphs, so the norm
>>> comes before the exceptions.
>>>
>>> I.e. it is weird to mention ioremap_np() before mentioning ioremap().
>>
>> +1 here. That is what I have stumbled upon reading carefully.
> 
> In that case, the order should probably be:
> 
> ioremap
> ioremap_wc
> ioremap_wt
> ioremap_np
> ioremap_uc
> ioremap_cache
> 
> Going from most common to least common, rather than going from
> strongest to weakest.

Yeah, I was dwelling on the issue of ioremap_np being first when I wrote 
that... this alternative works for me, I'll sort it like this then. 
It'll just need some re-wording to make it all flow properly.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 17/27] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE
  2021-03-08 15:35   ` Marc Zyngier
@ 2021-03-09 20:30     ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-09 20:30 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On 09/03/2021 00.35, Marc Zyngier wrote:
> On Thu, 04 Mar 2021 21:38:52 +0000,
> Hector Martin <marcan@marcan.st> wrote:
>>
>> This adds a Kconfig option to toggle support for Apple ARM SoCs.
>> At this time this targets the M1 and later "Apple Silicon" Mac SoCs.
>>
>> Signed-off-by: Hector Martin <marcan@marcan.st>
>> ---
>>   arch/arm64/Kconfig.platforms | 8 ++++++++
>>   arch/arm64/configs/defconfig | 1 +
>>   2 files changed, 9 insertions(+)
>>
>> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
>> index cdfd5fed457f..c2b5791e3d69 100644
>> --- a/arch/arm64/Kconfig.platforms
>> +++ b/arch/arm64/Kconfig.platforms
>> @@ -36,6 +36,14 @@ config ARCH_ALPINE
>>   	  This enables support for the Annapurna Labs Alpine
>>   	  Soc family.
>>   
>> +config ARCH_APPLE
>> +	bool "Apple Silicon SoC family"
>> +	select APPLE_AIC
>> +	select ARM64_FIQ_SUPPORT
> 
> Do we still need this FIQ symbol? I though it was now gone...

Whoops! Thanks for the catch, this can go away.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 26/27] dt-bindings: display: Add apple,simple-framebuffer
  2021-03-09 16:37   ` Linus Walleij
@ 2021-03-09 20:35     ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-09 20:35 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel

On 10/03/2021 01.37, Linus Walleij wrote:
> On Thu, Mar 4, 2021 at 10:42 PM Hector Martin <marcan@marcan.st> wrote:
> 
>> Apple SoCs run firmware that sets up a simplefb-compatible framebuffer
>> for us. Add a compatible for it, and two missing supported formats.
>>
>> Signed-off-by: Hector Martin <marcan@marcan.st>
> 
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> 
> Marcan: tell me if you need me to apply this to the drm-misc tree
> and I'll fix it.

I think Arnd is okay merging this one through the SoC tree.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-09 20:23                   ` Hector Martin
@ 2021-03-09 22:06                     ` Rob Herring
  2021-03-10  8:26                       ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Rob Herring @ 2021-03-09 22:06 UTC (permalink / raw)
  To: Hector Martin
  Cc: Arnd Bergmann, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Tue, Mar 9, 2021 at 1:24 PM Hector Martin <marcan@marcan.st> wrote:
>
> On 10/03/2021 00.48, Rob Herring wrote:
> > On Mon, Mar 8, 2021 at 2:56 PM Arnd Bergmann <arnd@kernel.org> wrote:
> >>
> >> On Mon, Mar 8, 2021 at 10:14 PM Rob Herring <robh@kernel.org> wrote:
> >>> On Mon, Mar 08, 2021 at 09:29:54PM +0100, Arnd Bergmann wrote:
> >>>> On Mon, Mar 8, 2021 at 4:56 PM Rob Herring <robh@kernel.org> wrote:
> >>>
> >>> Let's just stick with 'nonposted-mmio', but drop 'posted-mmio'. I'd
> >>> rather know if and when we need 'posted-mmio'. It does need to be added
> >>> to the DT spec[1] and schema[2] though (GH PRs are fine for both).
> >>
> >> I think the reason for having "posted-mmio" is that you cannot properly
> >> define the PCI host controller nodes on the M1 without that: Since
> >> nonposted-mmio applies to all child nodes, this would mean the PCI
> >> memory space gets declared as nonposted by the DT, but the hardware
> >> requires it to be mapped as posted.
> >
> > I don't think so. PCI devices wouldn't use any of the code paths in
> > this patch. They would map their memory space with plain ioremap()
> > which is posted.
>
> My main concern here is that this creates an inconsistency in the device
> tree representation that only works because PCI drivers happen not to
> use these code paths. Logically, having "nonposted-mmio" above the PCI
> controller would imply that it applies to that bus too. Sure, it doesn't
> matter for Linux since it is ignored, but this creates an implicit
> exception that PCI buses always use posted modes.

We could be stricter that "nonposted-mmio" must be in the immediate
parent. That's kind of in line with how addressing already works.
Every level has to have 'ranges' to be an MMIO address, and the
address cell size is set by the immediate parent.

> Then if a device comes along that due to some twisted fabric logic needs
> nonposted nGnRnE mappings for PCIe (even though the actual PCIe ops will
> end up posted at the bus anyway)... how do we represent that? Declare
> that another "nonposted-mmio" on the PCIe bus means "no, really, use
> nonposted mmio for this"?

If we're strict, yes. The PCI host bridge would have to have "nonposted-mmio".

Rob

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-09 22:06                     ` Rob Herring
@ 2021-03-10  8:26                       ` Hector Martin
  2021-03-10 17:01                         ` Rob Herring
  0 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-10  8:26 UTC (permalink / raw)
  To: Rob Herring
  Cc: Arnd Bergmann, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On 10/03/2021 07.06, Rob Herring wrote:
>> My main concern here is that this creates an inconsistency in the device
>> tree representation that only works because PCI drivers happen not to
>> use these code paths. Logically, having "nonposted-mmio" above the PCI
>> controller would imply that it applies to that bus too. Sure, it doesn't
>> matter for Linux since it is ignored, but this creates an implicit
>> exception that PCI buses always use posted modes.
> 
> We could be stricter that "nonposted-mmio" must be in the immediate
> parent. That's kind of in line with how addressing already works.
> Every level has to have 'ranges' to be an MMIO address, and the
> address cell size is set by the immediate parent.
> 
>> Then if a device comes along that due to some twisted fabric logic needs
>> nonposted nGnRnE mappings for PCIe (even though the actual PCIe ops will
>> end up posted at the bus anyway)... how do we represent that? Declare
>> that another "nonposted-mmio" on the PCIe bus means "no, really, use
>> nonposted mmio for this"?
> 
> If we're strict, yes. The PCI host bridge would have to have "nonposted-mmio".

Works for me; then let's just make it non-recursive.

Do you think we can get rid of the Apple-only optimization if we do 
this? It would mean only looking at the parent during address 
resolution, not recursing all the way to the top, so presumably the 
performance impact would be quite minimal.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-10  8:26                       ` Hector Martin
@ 2021-03-10 17:01                         ` Rob Herring
  2021-03-11  9:12                           ` Arnd Bergmann
  0 siblings, 1 reply; 136+ messages in thread
From: Rob Herring @ 2021-03-10 17:01 UTC (permalink / raw)
  To: Hector Martin
  Cc: Arnd Bergmann, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Wed, Mar 10, 2021 at 1:27 AM Hector Martin <marcan@marcan.st> wrote:
>
> On 10/03/2021 07.06, Rob Herring wrote:
> >> My main concern here is that this creates an inconsistency in the device
> >> tree representation that only works because PCI drivers happen not to
> >> use these code paths. Logically, having "nonposted-mmio" above the PCI
> >> controller would imply that it applies to that bus too. Sure, it doesn't
> >> matter for Linux since it is ignored, but this creates an implicit
> >> exception that PCI buses always use posted modes.
> >
> > We could be stricter that "nonposted-mmio" must be in the immediate
> > parent. That's kind of in line with how addressing already works.
> > Every level has to have 'ranges' to be an MMIO address, and the
> > address cell size is set by the immediate parent.
> >
> >> Then if a device comes along that due to some twisted fabric logic needs
> >> nonposted nGnRnE mappings for PCIe (even though the actual PCIe ops will
> >> end up posted at the bus anyway)... how do we represent that? Declare
> >> that another "nonposted-mmio" on the PCIe bus means "no, really, use
> >> nonposted mmio for this"?
> >
> > If we're strict, yes. The PCI host bridge would have to have "nonposted-mmio".
>
> Works for me; then let's just make it non-recursive.
>
> Do you think we can get rid of the Apple-only optimization if we do
> this? It would mean only looking at the parent during address
> resolution, not recursing all the way to the top, so presumably the
> performance impact would be quite minimal.

Yeah, that should be fine. I'd keep an IS_ENABLED() config check
though. Then I'll also know if anyone else needs this.

Rob

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 25/27] tty: serial: samsung_tty: Add earlycon support for Apple UARTs
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Linus Walleij @ 2021-03-10 23:11 UTC (permalink / raw)
  To: Hector Martin
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:SERIAL DRIVERS, Linux Doc Mailing List,
	linux-samsung-soc, Linux-Arch, linux-kernel, Arnd Bergmann

On Thu, Mar 4, 2021 at 10:42 PM Hector Martin <marcan@marcan.st> wrote:

> Earlycon support is identical to S3C2410, but Apple SoCs also need
> MMIO mapped as nGnRnE. This is handled generically for normal drivers
> including the normal UART path here, but earlycon uses fixmap and
> runs before that scaffolding is ready.
>
> Since this is the only case where we need this fix, it makes more
> sense to do it here in the UART driver instead of introducing a
> whole fdt nonposted-mmio resolver just for earlycon/fixmap.
>
> Suggested-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Hector Martin <marcan@marcan.st>

This is as elegant as it gets!
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-10 17:01                         ` Rob Herring
@ 2021-03-11  9:12                           ` Arnd Bergmann
  2021-03-11 12:11                             ` Hector Martin
  2021-03-11 16:07                             ` Rob Herring
  0 siblings, 2 replies; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-11  9:12 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Wed, Mar 10, 2021 at 6:01 PM Rob Herring <robh@kernel.org> wrote:
>
> On Wed, Mar 10, 2021 at 1:27 AM Hector Martin <marcan@marcan.st> wrote:
> >
> > On 10/03/2021 07.06, Rob Herring wrote:
> > >> My main concern here is that this creates an inconsistency in the device
> > >> tree representation that only works because PCI drivers happen not to
> > >> use these code paths. Logically, having "nonposted-mmio" above the PCI
> > >> controller would imply that it applies to that bus too. Sure, it doesn't
> > >> matter for Linux since it is ignored, but this creates an implicit
> > >> exception that PCI buses always use posted modes.
> > >
> > > We could be stricter that "nonposted-mmio" must be in the immediate
> > > parent. That's kind of in line with how addressing already works.
> > > Every level has to have 'ranges' to be an MMIO address, and the
> > > address cell size is set by the immediate parent.
> > >
> > >> Then if a device comes along that due to some twisted fabric logic needs
> > >> nonposted nGnRnE mappings for PCIe (even though the actual PCIe ops will
> > >> end up posted at the bus anyway)... how do we represent that? Declare
> > >> that another "nonposted-mmio" on the PCIe bus means "no, really, use
> > >> nonposted mmio for this"?
> > >
> > > If we're strict, yes. The PCI host bridge would have to have "nonposted-mmio".
> >
> > Works for me; then let's just make it non-recursive.
> >
> > Do you think we can get rid of the Apple-only optimization if we do
> > this? It would mean only looking at the parent during address
> > resolution, not recursing all the way to the top, so presumably the
> > performance impact would be quite minimal.

Works for me.

> Yeah, that should be fine. I'd keep an IS_ENABLED() config check
> though. Then I'll also know if anyone else needs this.

Ok, makes sense.

Conceptually, I'd like to then see a check that verifies that the
property is only set for nodes whose parent also has it set, since
that is how AXI defines it: A bus can wait for the ack from its
child node, or it can acknowledge the write to its parent early.
However, this breaks down as soon as a bus does the early ack:
all its children by definition use posted writes (as seen by the
CPU), even if they wait for stores that come from other masters.

Does this make sense to you?

       Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  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
  1 sibling, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-11 12:11 UTC (permalink / raw)
  To: Arnd Bergmann, Rob Herring
  Cc: linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On 11/03/2021 18.12, Arnd Bergmann wrote:
> On Wed, Mar 10, 2021 at 6:01 PM Rob Herring <robh@kernel.org> wrote:
>>
>> On Wed, Mar 10, 2021 at 1:27 AM Hector Martin <marcan@marcan.st> wrote:
>>>
>>> On 10/03/2021 07.06, Rob Herring wrote:
>>>>> My main concern here is that this creates an inconsistency in the device
>>>>> tree representation that only works because PCI drivers happen not to
>>>>> use these code paths. Logically, having "nonposted-mmio" above the PCI
>>>>> controller would imply that it applies to that bus too. Sure, it doesn't
>>>>> matter for Linux since it is ignored, but this creates an implicit
>>>>> exception that PCI buses always use posted modes.
>>>>
>>>> We could be stricter that "nonposted-mmio" must be in the immediate
>>>> parent. That's kind of in line with how addressing already works.
>>>> Every level has to have 'ranges' to be an MMIO address, and the
>>>> address cell size is set by the immediate parent.
>>>>
>>>>> Then if a device comes along that due to some twisted fabric logic needs
>>>>> nonposted nGnRnE mappings for PCIe (even though the actual PCIe ops will
>>>>> end up posted at the bus anyway)... how do we represent that? Declare
>>>>> that another "nonposted-mmio" on the PCIe bus means "no, really, use
>>>>> nonposted mmio for this"?
>>>>
>>>> If we're strict, yes. The PCI host bridge would have to have "nonposted-mmio".
>>>
>>> Works for me; then let's just make it non-recursive.
>>>
>>> Do you think we can get rid of the Apple-only optimization if we do
>>> this? It would mean only looking at the parent during address
>>> resolution, not recursing all the way to the top, so presumably the
>>> performance impact would be quite minimal.
> 
> Works for me.

Incidentally, even though it would now be unused, I'd like to keep the 
apple,arm-platform compatible at this point; we've already been pretty 
close to a use case for it, and I don't want to have to fall back to a 
list of SoC compatibles if we ever need another quirk for all Apple ARM 
SoCs (or break backwards compat). It doesn't really hurt to have it in 
the binding and devicetrees, right?

>> Yeah, that should be fine. I'd keep an IS_ENABLED() config check
>> though. Then I'll also know if anyone else needs this.
> 
> Ok, makes sense.
> 
> Conceptually, I'd like to then see a check that verifies that the
> property is only set for nodes whose parent also has it set, since
> that is how AXI defines it: A bus can wait for the ack from its
> child node, or it can acknowledge the write to its parent early.
> However, this breaks down as soon as a bus does the early ack:
> all its children by definition use posted writes (as seen by the
> CPU), even if they wait for stores that come from other masters.
> 
> Does this make sense to you?

Makes sense. This shouldn't really be something the kernel concerns 
itself with at runtime, just something for the dts linting, right?

I assume this isn't representable in json-schema, so it would presumably 
need some ad-hoc validation code.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-11 12:11                             ` Hector Martin
@ 2021-03-11 13:35                               ` Arnd Bergmann
  0 siblings, 0 replies; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-11 13:35 UTC (permalink / raw)
  To: Hector Martin
  Cc: Rob Herring, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Thu, Mar 11, 2021 at 1:11 PM Hector Martin <marcan@marcan.st> wrote:
> On 11/03/2021 18.12, Arnd Bergmann wrote:
> > On Wed, Mar 10, 2021 at 6:01 PM Rob Herring <robh@kernel.org> wrote:
> >> On Wed, Mar 10, 2021 at 1:27 AM Hector Martin <marcan@marcan.st> wrote:
> >>> Works for me; then let's just make it non-recursive.
> >>>
> >>> Do you think we can get rid of the Apple-only optimization if we do
> >>> this? It would mean only looking at the parent during address
> >>> resolution, not recursing all the way to the top, so presumably the
> >>> performance impact would be quite minimal.
> >
> > Works for me.
>
> Incidentally, even though it would now be unused, I'd like to keep the
> apple,arm-platform compatible at this point; we've already been pretty
> close to a use case for it, and I don't want to have to fall back to a
> list of SoC compatibles if we ever need another quirk for all Apple ARM
> SoCs (or break backwards compat). It doesn't really hurt to have it in
> the binding and devicetrees, right?

Yes, keeping the compatible string is a good idea regardless.

> >> Yeah, that should be fine. I'd keep an IS_ENABLED() config check
> >> though. Then I'll also know if anyone else needs this.
> >
> > Ok, makes sense.
> >
> > Conceptually, I'd like to then see a check that verifies that the
> > property is only set for nodes whose parent also has it set, since
> > that is how AXI defines it: A bus can wait for the ack from its
> > child node, or it can acknowledge the write to its parent early.
> > However, this breaks down as soon as a bus does the early ack:
> > all its children by definition use posted writes (as seen by the
> > CPU), even if they wait for stores that come from other masters.
> >
> > Does this make sense to you?
>
> Makes sense. This shouldn't really be something the kernel concerns
> itself with at runtime, just something for the dts linting, right?
>
> I assume this isn't representable in json-schema, so it would presumably
> need some ad-hoc validation code.

Agreed, having a check in either dtc or expressed in the json scheme
is better than a runtime check. I assume Rob would know how to best
add such a check.

     Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-11  9:12                           ` Arnd Bergmann
  2021-03-11 12:11                             ` Hector Martin
@ 2021-03-11 16:07                             ` Rob Herring
  2021-03-11 16:48                               ` Arnd Bergmann
  1 sibling, 1 reply; 136+ messages in thread
From: Rob Herring @ 2021-03-11 16:07 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Thu, Mar 11, 2021 at 2:12 AM Arnd Bergmann <arnd@kernel.org> wrote:
>
> On Wed, Mar 10, 2021 at 6:01 PM Rob Herring <robh@kernel.org> wrote:
> >
> > On Wed, Mar 10, 2021 at 1:27 AM Hector Martin <marcan@marcan.st> wrote:
> > >
> > > On 10/03/2021 07.06, Rob Herring wrote:
> > > >> My main concern here is that this creates an inconsistency in the device
> > > >> tree representation that only works because PCI drivers happen not to
> > > >> use these code paths. Logically, having "nonposted-mmio" above the PCI
> > > >> controller would imply that it applies to that bus too. Sure, it doesn't
> > > >> matter for Linux since it is ignored, but this creates an implicit
> > > >> exception that PCI buses always use posted modes.
> > > >
> > > > We could be stricter that "nonposted-mmio" must be in the immediate
> > > > parent. That's kind of in line with how addressing already works.
> > > > Every level has to have 'ranges' to be an MMIO address, and the
> > > > address cell size is set by the immediate parent.
> > > >
> > > >> Then if a device comes along that due to some twisted fabric logic needs
> > > >> nonposted nGnRnE mappings for PCIe (even though the actual PCIe ops will
> > > >> end up posted at the bus anyway)... how do we represent that? Declare
> > > >> that another "nonposted-mmio" on the PCIe bus means "no, really, use
> > > >> nonposted mmio for this"?
> > > >
> > > > If we're strict, yes. The PCI host bridge would have to have "nonposted-mmio".
> > >
> > > Works for me; then let's just make it non-recursive.
> > >
> > > Do you think we can get rid of the Apple-only optimization if we do
> > > this? It would mean only looking at the parent during address
> > > resolution, not recursing all the way to the top, so presumably the
> > > performance impact would be quite minimal.
>
> Works for me.
>
> > Yeah, that should be fine. I'd keep an IS_ENABLED() config check
> > though. Then I'll also know if anyone else needs this.
>
> Ok, makes sense.
>
> Conceptually, I'd like to then see a check that verifies that the
> property is only set for nodes whose parent also has it set, since
> that is how AXI defines it: A bus can wait for the ack from its
> child node, or it can acknowledge the write to its parent early.
> However, this breaks down as soon as a bus does the early ack:
> all its children by definition use posted writes (as seen by the
> CPU), even if they wait for stores that come from other masters.
>
> Does this make sense to you?

BTW, I don't think it's clear in this thread, but the current
definition proposed for the spec[1] and schema is 'nonposted-mmio' is
specific to 'simple-bus'. I like this restriction and we can expand
where 'nonposted-mmio' is allowed later if needed.

It's possible to express in json-schema, but I think it wouldn't be
pretty. Json-schema is not great for expressing inter-property
constraints and it gets worse if we're talking inter-node constraints.
I'd like to define a way to do python snippets of code for something
like this, but that's way down on the wish list.

Rob

[1] https://github.com/devicetree-org/devicetree-specification/pull/40

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-11 16:07                             ` Rob Herring
@ 2021-03-11 16:48                               ` Arnd Bergmann
  2021-03-11 18:10                                 ` Rob Herring
  0 siblings, 1 reply; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-11 16:48 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Thu, Mar 11, 2021 at 5:10 PM Rob Herring <robh@kernel.org> wrote:
> On Thu, Mar 11, 2021 at 2:12 AM Arnd Bergmann <arnd@kernel.org> wrote:
> > On Wed, Mar 10, 2021 at 6:01 PM Rob Herring <robh@kernel.org> wrote:
> > Ok, makes sense.
> >
> > Conceptually, I'd like to then see a check that verifies that the
> > property is only set for nodes whose parent also has it set, since
> > that is how AXI defines it: A bus can wait for the ack from its
> > child node, or it can acknowledge the write to its parent early.
> > However, this breaks down as soon as a bus does the early ack:
> > all its children by definition use posted writes (as seen by the
> > CPU), even if they wait for stores that come from other masters.
> >
> > Does this make sense to you?
>
> BTW, I don't think it's clear in this thread, but the current
> definition proposed for the spec[1] and schema is 'nonposted-mmio' is
> specific to 'simple-bus'. I like this restriction and we can expand
> where 'nonposted-mmio' is allowed later if needed.

That sounds ok, as long as we can express everything for the mac
at the moment. Do we need to explicitly add a description to allow
the property in the root node in addition to simple-bus to be able
to enforce the rule about parent buses also having it?

       Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-11 16:48                               ` Arnd Bergmann
@ 2021-03-11 18:10                                 ` Rob Herring
  2021-03-12 10:20                                   ` Arnd Bergmann
  0 siblings, 1 reply; 136+ messages in thread
From: Rob Herring @ 2021-03-11 18:10 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Thu, Mar 11, 2021 at 9:48 AM Arnd Bergmann <arnd@kernel.org> wrote:
>
> On Thu, Mar 11, 2021 at 5:10 PM Rob Herring <robh@kernel.org> wrote:
> > On Thu, Mar 11, 2021 at 2:12 AM Arnd Bergmann <arnd@kernel.org> wrote:
> > > On Wed, Mar 10, 2021 at 6:01 PM Rob Herring <robh@kernel.org> wrote:
> > > Ok, makes sense.
> > >
> > > Conceptually, I'd like to then see a check that verifies that the
> > > property is only set for nodes whose parent also has it set, since
> > > that is how AXI defines it: A bus can wait for the ack from its
> > > child node, or it can acknowledge the write to its parent early.
> > > However, this breaks down as soon as a bus does the early ack:
> > > all its children by definition use posted writes (as seen by the
> > > CPU), even if they wait for stores that come from other masters.
> > >
> > > Does this make sense to you?
> >
> > BTW, I don't think it's clear in this thread, but the current
> > definition proposed for the spec[1] and schema is 'nonposted-mmio' is
> > specific to 'simple-bus'. I like this restriction and we can expand
> > where 'nonposted-mmio' is allowed later if needed.
>
> That sounds ok, as long as we can express everything for the mac
> at the moment. Do we need to explicitly add a description to allow
> the property in the root node in addition to simple-bus to be able
> to enforce the rule about parent buses also having it?

IMO it should not be allowed in the root node. That's a failure to
define a bus node. Also, would that mean your memory has to be
non-posted!?

Rob

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 12/27] of/address: Add infrastructure to declare MMIO as non-posted
  2021-03-11 18:10                                 ` Rob Herring
@ 2021-03-12 10:20                                   ` Arnd Bergmann
  0 siblings, 0 replies; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-12 10:20 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	Linux Doc Mailing List, linux-samsung-soc,
	open list:GENERIC INCLUDE/ASM HEADER FILES, linux-kernel

On Thu, Mar 11, 2021 at 7:10 PM Rob Herring <robh@kernel.org> wrote:
>
> On Thu, Mar 11, 2021 at 9:48 AM Arnd Bergmann <arnd@kernel.org> wrote:
> >
> > On Thu, Mar 11, 2021 at 5:10 PM Rob Herring <robh@kernel.org> wrote:
> > > On Thu, Mar 11, 2021 at 2:12 AM Arnd Bergmann <arnd@kernel.org> wrote:
> > > > On Wed, Mar 10, 2021 at 6:01 PM Rob Herring <robh@kernel.org> wrote:
> > > > Ok, makes sense.
> > > >
> > > > Conceptually, I'd like to then see a check that verifies that the
> > > > property is only set for nodes whose parent also has it set, since
> > > > that is how AXI defines it: A bus can wait for the ack from its
> > > > child node, or it can acknowledge the write to its parent early.
> > > > However, this breaks down as soon as a bus does the early ack:
> > > > all its children by definition use posted writes (as seen by the
> > > > CPU), even if they wait for stores that come from other masters.
> > > >
> > > > Does this make sense to you?
> > >
> > > BTW, I don't think it's clear in this thread, but the current
> > > definition proposed for the spec[1] and schema is 'nonposted-mmio' is
> > > specific to 'simple-bus'. I like this restriction and we can expand
> > > where 'nonposted-mmio' is allowed later if needed.
> >
> > That sounds ok, as long as we can express everything for the mac
> > at the moment. Do we need to explicitly add a description to allow
> > the property in the root node in addition to simple-bus to be able
> > to enforce the rule about parent buses also having it?
>
> IMO it should not be allowed in the root node. That's a failure to
> define a bus node.

My interpretation would be that the root node defines the first bus
connected to the CPU(s) themselves, which may already have
posted writes. If writes on that bus are posted, then no child could
be non-posted.

I suppose it depends a bit on the mental model of what the nodes
refer to. If you say that there cannot be a device with registers
directly on the root node, but every bus defines its own space,
then we don't need this, but I think a lot of machines would break
if you try to enforce the rule that there cannot be devices on
the root node.

> Also, would that mean your memory has to be non-posted!?

Good question. You could argue that this should not be because you
don't want to use ioremap_np() flags but instead want this to be
normal cacheable memory instead of device memory.

On the other hand, you definitely don't want memory stores to be
posted, as that would break coherency between the CPUs when
a wmb() no longer has an effect.

       Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 01/27] arm64: Cope with CPUs stuck in VHE mode
  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
  0 siblings, 1 reply; 136+ messages in thread
From: Will Deacon @ 2021-03-24 18:05 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Fri, Mar 05, 2021 at 06:38:36AM +0900, Hector Martin wrote:
> From: Marc Zyngier <maz@kernel.org>
> 
> It seems that the CPU known as Apple M1 has the terrible habit
> of being stuck with HCR_EL2.E2H==1, in violation of the architecture.
> 
> Try and work around this deplorable state of affairs by detecting
> the stuck bit early and short-circuit the nVHE dance. It is still
> unknown whether there are many more such nuggets to be found...
> 
> Reported-by: Hector Martin <marcan@marcan.st>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/kernel/head.S     | 33 ++++++++++++++++++++++++++++++---
>  arch/arm64/kernel/hyp-stub.S | 28 ++++++++++++++++++++++++----
>  2 files changed, 54 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 66b0e0b66e31..673002b11865 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -477,14 +477,13 @@ EXPORT_SYMBOL(kimage_vaddr)
>   * booted in EL1 or EL2 respectively.
>   */
>  SYM_FUNC_START(init_kernel_el)
> -	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
> -	msr	sctlr_el1, x0
> -
>  	mrs	x0, CurrentEL
>  	cmp	x0, #CurrentEL_EL2
>  	b.eq	init_el2
>  
>  SYM_INNER_LABEL(init_el1, SYM_L_LOCAL)
> +	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
> +	msr	sctlr_el1, x0
>  	isb
>  	mov_q	x0, INIT_PSTATE_EL1
>  	msr	spsr_el1, x0
> @@ -504,6 +503,34 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
>  	msr	vbar_el2, x0
>  	isb
>  
> +	/*
> +	 * Fruity CPUs seem to have HCR_EL2.E2H set to RES1,
> +	 * making it impossible to start in nVHE mode. Is that
> +	 * compliant with the architecture? Absolutely not!
> +	 */
> +	mrs	x0, hcr_el2
> +	and	x0, x0, #HCR_E2H
> +	cbz	x0, 1f
> +
> +	/* Switching to VHE requires a sane SCTLR_EL1 as a start */
> +	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
> +	msr_s	SYS_SCTLR_EL12, x0
> +
> +	/*
> +	 * Force an eret into a helper "function", and let it return
> +	 * to our original caller... This makes sure that we have
> +	 * initialised the basic PSTATE state.
> +	 */
> +	mov	x0, #INIT_PSTATE_EL2
> +	msr	spsr_el1, x0
> +	adr_l	x0, stick_to_vhe
> +	msr	elr_el1, x0
> +	eret
> +
> +1:
> +	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
> +	msr	sctlr_el1, x0
> +
>  	msr	elr_el2, lr
>  	mov	w0, #BOOT_CPU_MODE_EL2
>  	eret
> diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
> index 5eccbd62fec8..c7601030ee82 100644
> --- a/arch/arm64/kernel/hyp-stub.S
> +++ b/arch/arm64/kernel/hyp-stub.S
> @@ -27,12 +27,12 @@ SYM_CODE_START(__hyp_stub_vectors)
>  	ventry	el2_fiq_invalid			// FIQ EL2t
>  	ventry	el2_error_invalid		// Error EL2t
>  
> -	ventry	el2_sync_invalid		// Synchronous EL2h
> +	ventry	elx_sync			// Synchronous EL2h
>  	ventry	el2_irq_invalid			// IRQ EL2h
>  	ventry	el2_fiq_invalid			// FIQ EL2h
>  	ventry	el2_error_invalid		// Error EL2h
>  
> -	ventry	el1_sync			// Synchronous 64-bit EL1
> +	ventry	elx_sync			// Synchronous 64-bit EL1
>  	ventry	el1_irq_invalid			// IRQ 64-bit EL1
>  	ventry	el1_fiq_invalid			// FIQ 64-bit EL1
>  	ventry	el1_error_invalid		// Error 64-bit EL1
> @@ -45,7 +45,7 @@ SYM_CODE_END(__hyp_stub_vectors)
>  
>  	.align 11
>  
> -SYM_CODE_START_LOCAL(el1_sync)
> +SYM_CODE_START_LOCAL(elx_sync)
>  	cmp	x0, #HVC_SET_VECTORS
>  	b.ne	1f
>  	msr	vbar_el2, x1
> @@ -71,7 +71,7 @@ SYM_CODE_START_LOCAL(el1_sync)
>  
>  9:	mov	x0, xzr
>  	eret
> -SYM_CODE_END(el1_sync)
> +SYM_CODE_END(elx_sync)
>  
>  // nVHE? No way! Give me the real thing!
>  SYM_CODE_START_LOCAL(mutate_to_vhe)
> @@ -243,3 +243,23 @@ SYM_FUNC_START(switch_to_vhe)
>  #endif
>  	ret
>  SYM_FUNC_END(switch_to_vhe)
> +
> +SYM_FUNC_START(stick_to_vhe)
> +	/*
> +	 * Make sure the switch to VHE cannot fail, by overriding the
> +	 * override. This is hilarious.
> +	 */
> +	adr_l	x1, id_aa64mmfr1_override
> +	add	x1, x1, #FTR_OVR_MASK_OFFSET
> +	dc 	civac, x1
> +	dsb	sy
> +	isb

Why do we need an ISB here?

> +	ldr	x0, [x1]
> +	bic	x0, x0, #(0xf << ID_AA64MMFR1_VHE_SHIFT)
> +	str	x0, [x1]

I find it a bit bizarre doing this here, as for the primary CPU we're still
a way away from parsing the early paramaters and for secondary CPUs this
doesn't need to be done for each one. Furthermore, this same code is run
on the resume path, which can probably then race with itself.

Is it possible to do it later on the boot CPU only, e.g. in
init_feature_override()? We should probably also log a warning that we're
ignoring the option because nVHE is not available.

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 08/27] asm-generic/io.h:  Add a non-posted variant of ioremap()
  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-08 11:20   ` Marc Zyngier
@ 2021-03-24 18:12   ` Will Deacon
  2021-03-24 19:09     ` Arnd Bergmann
  2 siblings, 1 reply; 136+ messages in thread
From: Will Deacon @ 2021-03-24 18:12 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Fri, Mar 05, 2021 at 06:38:43AM +0900, Hector Martin wrote:
> ARM64 currently defaults to posted MMIO (nGnRnE), but some devices
> require the use of non-posted MMIO (nGnRE). Introduce a new ioremap()
> variant to handle this case. ioremap_np() is aliased to ioremap() by
> default on arches that do not implement this variant.
> 
> sparc64 is the only architecture that needs to be touched directly,
> because it includes neither of the generic io.h or iomap.h headers.
> 
> This adds the IORESOURCE_MEM_NONPOSTED flag, which maps to this
> variant and marks a given resource as requiring non-posted mappings.
> This is implemented in the resource system because it is a SoC-level
> requirement, so existing drivers do not need special-case code to pick
> this ioremap variant.
> 
> Then this is implemented in devres by introducing devm_ioremap_np(),
> and making devm_ioremap_resource() automatically select this variant
> when the resource has the IORESOURCE_MEM_NONPOSTED flag set.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  .../driver-api/driver-model/devres.rst        |  1 +
>  arch/sparc/include/asm/io_64.h                |  4 ++++
>  include/asm-generic/io.h                      | 22 ++++++++++++++++++-
>  include/asm-generic/iomap.h                   |  9 ++++++++
>  include/linux/io.h                            |  2 ++
>  include/linux/ioport.h                        |  1 +
>  lib/devres.c                                  | 22 +++++++++++++++++++
>  7 files changed, 60 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
> index cd8b6e657b94..2f45877a539d 100644
> --- a/Documentation/driver-api/driver-model/devres.rst
> +++ b/Documentation/driver-api/driver-model/devres.rst
> @@ -309,6 +309,7 @@ IOMAP
>    devm_ioremap()
>    devm_ioremap_uc()
>    devm_ioremap_wc()
> +  devm_ioremap_np()
>    devm_ioremap_resource() : checks resource, requests memory region, ioremaps
>    devm_ioremap_resource_wc()
>    devm_platform_ioremap_resource() : calls devm_ioremap_resource() for platform device
> diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
> index 9bb27e5c22f1..9fbfc9574432 100644
> --- a/arch/sparc/include/asm/io_64.h
> +++ b/arch/sparc/include/asm/io_64.h
> @@ -409,6 +409,10 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
>  #define ioremap_uc(X,Y)			ioremap((X),(Y))
>  #define ioremap_wc(X,Y)			ioremap((X),(Y))
>  #define ioremap_wt(X,Y)			ioremap((X),(Y))
> +static inline void __iomem *ioremap_np(unsigned long offset, unsigned long size)
> +{
> +	return NULL;
> +}
>  
>  static inline void iounmap(volatile void __iomem *addr)
>  {
> diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
> index c6af40ce03be..082e0c96db6e 100644
> --- a/include/asm-generic/io.h
> +++ b/include/asm-generic/io.h
> @@ -942,7 +942,9 @@ static inline void *phys_to_virt(unsigned long address)
>   *
>   * ioremap_wc() and ioremap_wt() can provide more relaxed caching attributes
>   * for specific drivers if the architecture choses to implement them.  If they
> - * are not implemented we fall back to plain ioremap.
> + * are not implemented we fall back to plain ioremap. Conversely, ioremap_np()
> + * can provide stricter non-posted write semantics if the architecture
> + * implements them.
>   */
>  #ifndef CONFIG_MMU
>  #ifndef ioremap
> @@ -993,6 +995,24 @@ static inline void __iomem *ioremap_uc(phys_addr_t offset, size_t size)
>  {
>  	return NULL;
>  }
> +
> +/*
> + * ioremap_np needs an explicit architecture implementation, as it
> + * requests stronger semantics than regular ioremap(). Portable drivers
> + * should instead use one of the higher-level abstractions, like
> + * devm_ioremap_resource(), to choose the correct variant for any given
> + * device and bus. Portable drivers with a good reason to want non-posted
> + * write semantics should always provide an ioremap() fallback in case
> + * ioremap_np() is not available.
> + */
> +#ifndef ioremap_np
> +#define ioremap_np ioremap_np
> +static inline void __iomem *ioremap_np(phys_addr_t offset, size_t size)
> +{
> +	return NULL;
> +}
> +#endif

Can we implement the generic pci_remap_cfgspace() in terms of ioremap_np()
if it is supported by the architecture? That way, we could avoid defining
both on arm64.

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 05/27] arm64: cputype: Add CPU implementor & types for the Apple M1 cores
  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
  0 siblings, 0 replies; 136+ messages in thread
From: Will Deacon @ 2021-03-24 18:13 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Fri, Mar 05, 2021 at 06:38:40AM +0900, Hector Martin wrote:
> The implementor will be used to condition the FIQ support quirk.
> 
> The specific CPU types are not used at the moment, but let's add them
> for documentation purposes.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  arch/arm64/include/asm/cputype.h | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index ef5b040dee44..6231e1f0abe7 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -59,6 +59,7 @@
>  #define ARM_CPU_IMP_NVIDIA		0x4E
>  #define ARM_CPU_IMP_FUJITSU		0x46
>  #define ARM_CPU_IMP_HISI		0x48
> +#define ARM_CPU_IMP_APPLE		0x61
>  
>  #define ARM_CPU_PART_AEM_V8		0xD0F
>  #define ARM_CPU_PART_FOUNDATION		0xD00
> @@ -99,6 +100,9 @@
>  
>  #define HISI_CPU_PART_TSV110		0xD01
>  
> +#define APPLE_CPU_PART_M1_ICESTORM	0x022
> +#define APPLE_CPU_PART_M1_FIRESTORM	0x023
> +
>  #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
>  #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
>  #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
> @@ -127,6 +131,8 @@
>  #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL)
>  #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)
>  #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110)
> +#define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)
> +#define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)

We usually only merge these when they're needed, but this SoC seems broken
enough that I can see the value in having them from the start :(

Acked-by: Will Deacon <will@kernel.org>

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 11/27] arm64: Implement ioremap_np() to map MMIO as nGnRnE
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Will Deacon @ 2021-03-24 18:18 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Fri, Mar 05, 2021 at 06:38:46AM +0900, Hector Martin wrote:
> This is used on Apple ARM platforms, which require most MMIO
> (except PCI devices) to be mapped as nGnRnE.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  arch/arm64/include/asm/io.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
> index 5ea8656a2030..953b8703af60 100644
> --- a/arch/arm64/include/asm/io.h
> +++ b/arch/arm64/include/asm/io.h
> @@ -169,6 +169,7 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
>  
>  #define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
>  #define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
> +#define ioremap_np(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRnE))

Probably worth noting that whether or not this actually results in a
non-posted mapping depends on the system architecture, but this is the
best we can do, so:

Acked-by: Will Deacon <will@kernel.org>

I would personally prefer that drivers didn't have to care about this, and
ioremap on arm64 figured out the right attributes based on the region being
mapped, but I haven't followed the discussion closely so I won't die on that
hill.

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 14/27] arm64: move ICH_ sysreg bits from arm-gic-v3.h to sysreg.h
  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
  1 sibling, 0 replies; 136+ messages in thread
From: Will Deacon @ 2021-03-24 18:23 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Fri, Mar 05, 2021 at 06:38:49AM +0900, Hector Martin wrote:
> These definitions are in arm-gic-v3.h for historical reasons which no
> longer apply. Move them to sysreg.h so the AIC driver can use them, as
> it needs to peek into vGIC registers to deal with the GIC maintentance
> interrupt.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  arch/arm64/include/asm/sysreg.h    | 60 ++++++++++++++++++++++++++++++
>  include/linux/irqchip/arm-gic-v3.h | 56 ----------------------------
>  2 files changed, 60 insertions(+), 56 deletions(-)

This would be much easier to remove if you just moved the definitions,
rather than reordered than and changed the comments at the same time!

But I *think* nothing had changed, so:

Acked-by: Will Deacon <will@kernel.org>

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 13/27] arm64: Add Apple vendor-specific system registers
  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
  0 siblings, 1 reply; 136+ messages in thread
From: Will Deacon @ 2021-03-24 18:38 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Fri, Mar 05, 2021 at 06:38:48AM +0900, Hector Martin wrote:
> Apple ARM64 SoCs have a ton of vendor-specific registers we're going to
> have to deal with, and those don't really belong in sysreg.h with all
> the architectural registers. Make a new home for them, and add some
> registers which are useful for early bring-up.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  MAINTAINERS                           |  1 +
>  arch/arm64/include/asm/sysreg_apple.h | 69 +++++++++++++++++++++++++++
>  2 files changed, 70 insertions(+)
>  create mode 100644 arch/arm64/include/asm/sysreg_apple.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index aec14fbd61b8..3a352c687d4b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1646,6 +1646,7 @@ B:	https://github.com/AsahiLinux/linux/issues
>  C:	irc://chat.freenode.net/asahi-dev
>  T:	git https://github.com/AsahiLinux/linux.git
>  F:	Documentation/devicetree/bindings/arm/apple.yaml
> +F:	arch/arm64/include/asm/sysreg_apple.h

(this isn't needed with my suggestion below).

>  ARM/ARTPEC MACHINE SUPPORT
>  M:	Jesper Nilsson <jesper.nilsson@axis.com>
> diff --git a/arch/arm64/include/asm/sysreg_apple.h b/arch/arm64/include/asm/sysreg_apple.h
> new file mode 100644
> index 000000000000..48347a51d564
> --- /dev/null
> +++ b/arch/arm64/include/asm/sysreg_apple.h

I doubt apple are the only folks doing this, so can we instead have
sysreg-impdef.h please, and then have an Apple section in there for these
registers? That way, we could also have an imp_sys_reg() macro to limit
CRn to 11 or 15, which is the reserved encoding space for these registers.

We'll cc you for any patches touching the Apple parts, as we don't have
the first clue about what's hiding in there.

> @@ -0,0 +1,69 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Apple SoC vendor-defined system register definitions
> + *
> + * Copyright The Asahi Linux Contributors
> +
> + * This file contains only well-understood registers that are useful to
> + * Linux. If you are looking for things to add here, you should visit:
> + *
> + * https://github.com/AsahiLinux/docs/wiki/HW:ARM-System-Registers
> + */
> +
> +#ifndef __ASM_SYSREG_APPLE_H
> +#define __ASM_SYSREG_APPLE_H
> +
> +#include <asm/sysreg.h>
> +#include <linux/bits.h>
> +#include <linux/bitfield.h>
> +
> +/*
> + * Keep these registers in encoding order, except for register arrays;
> + * those should be listed in array order starting from the position of
> + * the encoding of the first register.
> + */
> +
> +#define SYS_APL_PMCR0_EL1		sys_reg(3, 1, 15, 0, 0)
> +#define PMCR0_IMODE			GENMASK(10, 8)
> +#define PMCR0_IMODE_OFF			0
> +#define PMCR0_IMODE_PMI			1
> +#define PMCR0_IMODE_AIC			2
> +#define PMCR0_IMODE_HALT		3
> +#define PMCR0_IMODE_FIQ			4
> +#define PMCR0_IACT			BIT(11)

The Arm ARM says this about imp-def sysregs:

  | The Arm architecture guarantees not to define any register name
  | prefixed with IMP_ as part of the standard Arm architecture.
  |
  | Note
  | Arm strongly recommends that any register names created in the
  | IMPLEMENTATION DEFINED register spaces be prefixed with IMP_ and
  | postfixed with _ELx, where appropriate.

and it seems like we could follow that here without much effort, if you
don't mind.

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 13/27] arm64: Add Apple vendor-specific system registers
  2021-03-24 18:38   ` Will Deacon
@ 2021-03-24 18:59     ` Mark Rutland
  2021-03-24 19:04       ` Will Deacon
  0 siblings, 1 reply; 136+ messages in thread
From: Mark Rutland @ 2021-03-24 18:59 UTC (permalink / raw)
  To: Will Deacon
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Rob Herring,
	Arnd Bergmann, Olof Johansson, Krzysztof Kozlowski,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Linus Walleij, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

On Wed, Mar 24, 2021 at 06:38:18PM +0000, Will Deacon wrote:
> On Fri, Mar 05, 2021 at 06:38:48AM +0900, Hector Martin wrote:
> > Apple ARM64 SoCs have a ton of vendor-specific registers we're going to
> > have to deal with, and those don't really belong in sysreg.h with all
> > the architectural registers. Make a new home for them, and add some
> > registers which are useful for early bring-up.
> > 
> > Signed-off-by: Hector Martin <marcan@marcan.st>
> > ---
> >  MAINTAINERS                           |  1 +
> >  arch/arm64/include/asm/sysreg_apple.h | 69 +++++++++++++++++++++++++++
> >  2 files changed, 70 insertions(+)
> >  create mode 100644 arch/arm64/include/asm/sysreg_apple.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index aec14fbd61b8..3a352c687d4b 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1646,6 +1646,7 @@ B:	https://github.com/AsahiLinux/linux/issues
> >  C:	irc://chat.freenode.net/asahi-dev
> >  T:	git https://github.com/AsahiLinux/linux.git
> >  F:	Documentation/devicetree/bindings/arm/apple.yaml
> > +F:	arch/arm64/include/asm/sysreg_apple.h
> 
> (this isn't needed with my suggestion below).
> 
> >  ARM/ARTPEC MACHINE SUPPORT
> >  M:	Jesper Nilsson <jesper.nilsson@axis.com>
> > diff --git a/arch/arm64/include/asm/sysreg_apple.h b/arch/arm64/include/asm/sysreg_apple.h
> > new file mode 100644
> > index 000000000000..48347a51d564
> > --- /dev/null
> > +++ b/arch/arm64/include/asm/sysreg_apple.h
> 
> I doubt apple are the only folks doing this, so can we instead have
> sysreg-impdef.h please, and then have an Apple section in there for these
> registers? That way, we could also have an imp_sys_reg() macro to limit
> CRn to 11 or 15, which is the reserved encoding space for these registers.
> 
> We'll cc you for any patches touching the Apple parts, as we don't have
> the first clue about what's hiding in there.

For existing IMP-DEF sysregs (e.g. the Kryo L2 control registers), we've
put the definitions in the drivers, rather than collating
non-architectural bits under arch/arm64/.

So far we've kept arch/arm64/ largely devoid of IMP-DEF bits, and it
seems a shame to add something with the sole purpose of collating that,
especially given arch code shouldn't need to touch these if FW and
bootloader have done their jobs right.

Can we put the definitions in the relevant drivers? That would sidestep
any pain with MAINTAINERS, too.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 13/27] arm64: Add Apple vendor-specific system registers
  2021-03-24 18:59     ` Mark Rutland
@ 2021-03-24 19:04       ` Will Deacon
  2021-03-26  6:23         ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Will Deacon @ 2021-03-24 19:04 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Hector Martin, linux-arm-kernel, Marc Zyngier, Rob Herring,
	Arnd Bergmann, Olof Johansson, Krzysztof Kozlowski,
	Mark Kettenis, Tony Lindgren, Mohamed Mediouni, Stan Skowronek,
	Alexander Graf, Linus Walleij, Andy Shevchenko,
	Greg Kroah-Hartman, Jonathan Corbet, Catalin Marinas,
	Christoph Hellwig, David S. Miller, devicetree, linux-serial,
	linux-doc, linux-samsung-soc, linux-arch, linux-kernel

On Wed, Mar 24, 2021 at 06:59:21PM +0000, Mark Rutland wrote:
> On Wed, Mar 24, 2021 at 06:38:18PM +0000, Will Deacon wrote:
> > On Fri, Mar 05, 2021 at 06:38:48AM +0900, Hector Martin wrote:
> > > Apple ARM64 SoCs have a ton of vendor-specific registers we're going to
> > > have to deal with, and those don't really belong in sysreg.h with all
> > > the architectural registers. Make a new home for them, and add some
> > > registers which are useful for early bring-up.
> > > 
> > > Signed-off-by: Hector Martin <marcan@marcan.st>
> > > ---
> > >  MAINTAINERS                           |  1 +
> > >  arch/arm64/include/asm/sysreg_apple.h | 69 +++++++++++++++++++++++++++
> > >  2 files changed, 70 insertions(+)
> > >  create mode 100644 arch/arm64/include/asm/sysreg_apple.h
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index aec14fbd61b8..3a352c687d4b 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -1646,6 +1646,7 @@ B:	https://github.com/AsahiLinux/linux/issues
> > >  C:	irc://chat.freenode.net/asahi-dev
> > >  T:	git https://github.com/AsahiLinux/linux.git
> > >  F:	Documentation/devicetree/bindings/arm/apple.yaml
> > > +F:	arch/arm64/include/asm/sysreg_apple.h
> > 
> > (this isn't needed with my suggestion below).
> > 
> > >  ARM/ARTPEC MACHINE SUPPORT
> > >  M:	Jesper Nilsson <jesper.nilsson@axis.com>
> > > diff --git a/arch/arm64/include/asm/sysreg_apple.h b/arch/arm64/include/asm/sysreg_apple.h
> > > new file mode 100644
> > > index 000000000000..48347a51d564
> > > --- /dev/null
> > > +++ b/arch/arm64/include/asm/sysreg_apple.h
> > 
> > I doubt apple are the only folks doing this, so can we instead have
> > sysreg-impdef.h please, and then have an Apple section in there for these
> > registers? That way, we could also have an imp_sys_reg() macro to limit
> > CRn to 11 or 15, which is the reserved encoding space for these registers.
> > 
> > We'll cc you for any patches touching the Apple parts, as we don't have
> > the first clue about what's hiding in there.
> 
> For existing IMP-DEF sysregs (e.g. the Kryo L2 control registers), we've
> put the definitions in the drivers, rather than collating
> non-architectural bits under arch/arm64/.

Yeah, but we could include those here as well.

> So far we've kept arch/arm64/ largely devoid of IMP-DEF bits, and it
> seems a shame to add something with the sole purpose of collating that,
> especially given arch code shouldn't need to touch these if FW and
> bootloader have done their jobs right.
> 
> Can we put the definitions in the relevant drivers? That would sidestep
> any pain with MAINTAINERS, too.

If we can genuinely ignore these in arch code, then sure. I just don't know
how long that is going to be the case, and ending up in a situation where
these are scattered randomly throughout the tree sounds horrible to me.

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 08/27] asm-generic/io.h: Add a non-posted variant of ioremap()
  2021-03-24 18:12   ` Will Deacon
@ 2021-03-24 19:09     ` Arnd Bergmann
  2021-03-25 14:07       ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Arnd Bergmann @ 2021-03-24 19:09 UTC (permalink / raw)
  To: Will Deacon
  Cc: Hector Martin, Linux ARM, Marc Zyngier, Rob Herring,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	open list:DOCUMENTATION,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES, linux-arch,
	Linux Kernel Mailing List

On Wed, Mar 24, 2021 at 7:12 PM Will Deacon <will@kernel.org> wrote:
>
> > +/*
> > + * ioremap_np needs an explicit architecture implementation, as it
> > + * requests stronger semantics than regular ioremap(). Portable drivers
> > + * should instead use one of the higher-level abstractions, like
> > + * devm_ioremap_resource(), to choose the correct variant for any given
> > + * device and bus. Portable drivers with a good reason to want non-posted
> > + * write semantics should always provide an ioremap() fallback in case
> > + * ioremap_np() is not available.
> > + */
> > +#ifndef ioremap_np
> > +#define ioremap_np ioremap_np
> > +static inline void __iomem *ioremap_np(phys_addr_t offset, size_t size)
> > +{
> > +     return NULL;
> > +}
> > +#endif
>
> Can we implement the generic pci_remap_cfgspace() in terms of ioremap_np()
> if it is supported by the architecture? That way, we could avoid defining
> both on arm64.

Good idea. It needs a fallback in case the ioremap_np() fails on most
architectures, but that sounds easy enough.

Since pci_remap_cfgspace() only has custom implementations, it sounds like
we can actually make the generic implementation unconditional in the end,
but that requires adding ioremap_np() on 32-bit as well, and I would keep
that separate from this series.

        Arnd

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  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 13:31   ` Marc Zyngier
@ 2021-03-24 19:57   ` Will Deacon
  2021-03-26  8:58     ` Hector Martin
  2 siblings, 1 reply; 136+ messages in thread
From: Will Deacon @ 2021-03-24 19:57 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

Hi Hector,

Sorry it took me so long to get to this. Some comments below.

On Fri, Mar 05, 2021 at 06:38:51AM +0900, Hector Martin wrote:
> This is the root interrupt controller used on Apple ARM SoCs such as the
> M1. This irqchip driver performs multiple functions:
> 
> * Handles both IRQs and FIQs
> 
> * Drives the AIC peripheral itself (which handles IRQs)
> 
> * Dispatches FIQs to downstream hard-wired clients (currently the ARM
>   timer).
> 
> * Implements a virtual IPI multiplexer to funnel multiple Linux IPIs
>   into a single hardware IPI
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  MAINTAINERS                     |   2 +
>  drivers/irqchip/Kconfig         |   8 +
>  drivers/irqchip/Makefile        |   1 +
>  drivers/irqchip/irq-apple-aic.c | 710 ++++++++++++++++++++++++++++++++
>  include/linux/cpuhotplug.h      |   1 +
>  5 files changed, 722 insertions(+)
>  create mode 100644 drivers/irqchip/irq-apple-aic.c

[...]

> + * Implementation notes:
> + *
> + * - This driver creates two IRQ domains, one for HW IRQs and internal FIQs,
> + *   and one for IPIs.
> + * - Since Linux needs more than 2 IPIs, we implement a software IRQ controller
> + *   and funnel all IPIs into one per-CPU IPI (the second "self" IPI is unused).
> + * - FIQ hwirq numbers are assigned after true hwirqs, and are per-cpu.
> + * - DT bindings use 3-cell form (like GIC):
> + *   - <0 nr flags> - hwirq #nr
> + *   - <1 nr flags> - FIQ #nr
> + *     - nr=0  Physical HV timer
> + *     - nr=1  Virtual HV timer
> + *     - nr=2  Physical guest timer
> + *     - nr=3  Virtual guest timer
> + *
> + */
> +
> +#define pr_fmt(fmt) "%s: " fmt, __func__

General nit: but I suspect many of the prints in here probably want to be
using the *_ratelimited variants.

> +static void __exception_irq_entry aic_handle_irq(struct pt_regs *regs)
> +{
> +	struct aic_irq_chip *ic = aic_irqc;
> +	u32 event, type, irq;
> +
> +	do {
> +		/*
> +		 * We cannot use a relaxed read here, as DMA needs to be
> +		 * ordered with respect to the IRQ firing.
> +		 */

I think this could be a bit clearer: the readl() doesn't order any DMA
accesses, but instead means that subsequent reads by the CPU are ordered
(which may be from a buffer which was DMA'd to) are ordered after the
read of the MMIO register.

> +		event = readl(ic->base + AIC_EVENT);
> +		type = FIELD_GET(AIC_EVENT_TYPE, event);
> +		irq = FIELD_GET(AIC_EVENT_NUM, event);
> +
> +		if (type == AIC_EVENT_TYPE_HW)
> +			handle_domain_irq(aic_irqc->hw_domain, irq, regs);
> +		else if (type == AIC_EVENT_TYPE_IPI && irq == 1)
> +			aic_handle_ipi(regs);
> +		else if (event != 0)
> +			pr_err("Unknown IRQ event %d, %d\n", type, irq);
> +	} while (event);
> +
> +	/*
> +	 * vGIC maintenance interrupts end up here too, so we need to check
> +	 * for them separately. Just report and disable vGIC for now, until
> +	 * we implement this properly.
> +	 */
> +	if ((read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EN) &&
> +		read_sysreg_s(SYS_ICH_MISR_EL2) != 0) {
> +		pr_err("vGIC IRQ fired, disabling.\n");
> +		sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EN, 0);
> +	}

What prevents all these system register accesses being speculated up before
the handler?

> +}
> +
> +static int aic_irq_set_affinity(struct irq_data *d,
> +				const struct cpumask *mask_val, bool force)
> +{
> +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> +	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
> +	int cpu;
> +
> +	if (hwirq > ic->nr_hw)
> +		return -EINVAL;
> +
> +	if (force)
> +		cpu = cpumask_first(mask_val);
> +	else
> +		cpu = cpumask_any_and(mask_val, cpu_online_mask);
> +
> +	aic_ic_write(ic, AIC_TARGET_CPU + hwirq * 4, BIT(cpu));
> +	irq_data_update_effective_affinity(d, cpumask_of(cpu));
> +
> +	return IRQ_SET_MASK_OK;
> +}
> +
> +static int aic_irq_set_type(struct irq_data *d, unsigned int type)
> +{
> +	return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL;
> +}
> +
> +static struct irq_chip aic_chip = {
> +	.name = "AIC",
> +	.irq_mask = aic_irq_mask,
> +	.irq_unmask = aic_irq_unmask,

I know these are driven by the higher-level irq chip code, but I'm a bit
confused as to what provides ordering if, e.g. something ends up calling:

	aic_chip.irq_mask(d);
	...
	aic_chip.irq_unmask(d);

I can't see any ISBs in here and they're writing to two different registers,
so can we end up with the IRQ masked after this sequence?

> +/*
> + * IPI irqchip
> + */
> +
> +static void aic_ipi_mask(struct irq_data *d)
> +{
> +	u32 irq_bit = BIT(irqd_to_hwirq(d));
> +	int this_cpu = smp_processor_id();
> +
> +	/* No specific ordering requirements needed here. */
> +	atomic_andnot(irq_bit, &aic_vipi_enable[this_cpu]);
> +}

Why not use a per-cpu variable here instead of an array of atomics? The pcpu
API has things for atomic updates (e.g. or, and, xchg).

> +static void aic_ipi_unmask(struct irq_data *d)
> +{
> +	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
> +	u32 irq_bit = BIT(irqd_to_hwirq(d));
> +	int this_cpu = smp_processor_id();
> +
> +	/*
> +	 * This must complete before the atomic_read_acquire() below to avoid
> +	 * racing aic_ipi_send_mask(). Use a dummy fetch op with release
> +	 * semantics for this. This is arch-specific: ARMv8 B2.3.3 specifies
> +	 * that writes with Release semantics are Barrier-ordered-before reads
> +	 * with Acquire semantics, even though the Linux arch-independent
> +	 * definition of these atomic ops does not.
> +	 */

I think a more idiomatic (and portable) way to do this would be to use
the relaxed accessors, but with smp_mb__after_atomic() between them. Do you
have a good reason for _not_ doing it like that?

> +	(void)atomic_fetch_or_release(irq_bit, &aic_vipi_enable[this_cpu]);
> +
> +	/*
> +	 * If a pending vIPI was unmasked, raise a HW IPI to ourselves.
> +	 * No barriers needed here since this is a self-IPI.
> +	 */
> +	if (atomic_read_acquire(&aic_vipi_flag[this_cpu]) & irq_bit)

"No barriers needed here" right before an acquire is confusing ;)

> +		aic_ic_write(ic, AIC_IPI_SEND, AIC_IPI_SEND_CPU(this_cpu));
> +}
> +
> +static void aic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask)
> +{
> +	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
> +	u32 irq_bit = BIT(irqd_to_hwirq(d));
> +	u32 send = 0;
> +	int cpu;
> +	unsigned long pending;
> +
> +	for_each_cpu(cpu, mask) {
> +		/*
> +		 * This sequence is the mirror of the one in aic_ipi_unmask();
> +		 * see the comment there. Additionally, release semantics
> +		 * ensure that the vIPI flag set is ordered after any shared
> +		 * memory accesses that precede it. This therefore also pairs
> +		 * with the atomic_fetch_andnot in aic_handle_ipi().
> +		 */
> +		pending = atomic_fetch_or_release(irq_bit, &aic_vipi_flag[cpu]);

(same here)

> +		if (!(pending & irq_bit) && (atomic_read_acquire(&aic_vipi_enable[cpu]) & irq_bit))
> +			send |= AIC_IPI_SEND_CPU(cpu);
> +	}
> +
> +	/*
> +	 * The flag writes must complete before the physical IPI is issued
> +	 * to another CPU. This is implied by the control dependency on
> +	 * the result of atomic_read_acquire() above, which is itself
> +	 * already ordered after the vIPI flag write.
> +	 */
> +	if (send)
> +		aic_ic_write(ic, AIC_IPI_SEND, send);
> +}
> +
> +static struct irq_chip ipi_chip = {
> +	.name = "AIC-IPI",
> +	.irq_mask = aic_ipi_mask,
> +	.irq_unmask = aic_ipi_unmask,
> +	.ipi_send_mask = aic_ipi_send_mask,
> +};
> +
> +/*
> + * IPI IRQ domain
> + */
> +
> +static void aic_handle_ipi(struct pt_regs *regs)
> +{
> +	int this_cpu = smp_processor_id();
> +	int i;
> +	unsigned long enabled, firing;
> +
> +	/*
> +	 * Ack the IPI. We need to order this after the AIC event read, but
> +	 * that is enforced by normal MMIO ordering guarantees.
> +	 */
> +	aic_ic_write(aic_irqc, AIC_IPI_ACK, AIC_IPI_OTHER);
> +
> +	/*
> +	 * The mask read does not need to be ordered. Only we can change
> +	 * our own mask anyway, so no races are possible here, as long as
> +	 * we are properly in the interrupt handler (which is covered by
> +	 * the barrier that is part of the top-level AIC handler's readl()).
> +	 */
> +	enabled = atomic_read(&aic_vipi_enable[this_cpu]);
> +
> +	/*
> +	 * Clear the IPIs we are about to handle. This pairs with the
> +	 * atomic_fetch_or_release() in aic_ipi_send_mask(), and needs to be
> +	 * ordered after the aic_ic_write() above (to avoid dropping vIPIs) and
> +	 * before IPI handling code (to avoid races handling vIPIs before they
> +	 * are signaled). The former is taken care of by the release semantics
> +	 * of the write portion, while the latter is taken care of by the
> +	 * acquire semantics of the read portion.
> +	 */
> +	firing = atomic_fetch_andnot(enabled, &aic_vipi_flag[this_cpu]) & enabled;

Does this also need to be ordered after the Ack? For example, if we have
something like:

CPU 0						CPU 1
						<some other IPI>
aic_ipi_send_mask()
						atomic_fetch_andnot(flag)
	atomic_fetch_or_release(flag)
	aic_ic_write(AIC_IPI_SEND)
						aic_ic_write(AIC_IPI_ACK)

sorry if it's a stupid question, I'm just not sure about the cases in which
the hardware will pend things for you.

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 01/27] arm64: Cope with CPUs stuck in VHE mode
  2021-03-24 18:05   ` Will Deacon
@ 2021-03-24 20:00     ` Marc Zyngier
  2021-03-26  7:54       ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Marc Zyngier @ 2021-03-24 20:00 UTC (permalink / raw)
  To: Will Deacon
  Cc: Hector Martin, linux-arm-kernel, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On Wed, 24 Mar 2021 18:05:46 +0000,
Will Deacon <will@kernel.org> wrote:
> 
> On Fri, Mar 05, 2021 at 06:38:36AM +0900, Hector Martin wrote:
> > From: Marc Zyngier <maz@kernel.org>
> > 
> > It seems that the CPU known as Apple M1 has the terrible habit
> > of being stuck with HCR_EL2.E2H==1, in violation of the architecture.
> > 
> > Try and work around this deplorable state of affairs by detecting
> > the stuck bit early and short-circuit the nVHE dance. It is still
> > unknown whether there are many more such nuggets to be found...
> > 
> > Reported-by: Hector Martin <marcan@marcan.st>
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm64/kernel/head.S     | 33 ++++++++++++++++++++++++++++++---
> >  arch/arm64/kernel/hyp-stub.S | 28 ++++++++++++++++++++++++----
> >  2 files changed, 54 insertions(+), 7 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> > index 66b0e0b66e31..673002b11865 100644
> > --- a/arch/arm64/kernel/head.S
> > +++ b/arch/arm64/kernel/head.S
> > @@ -477,14 +477,13 @@ EXPORT_SYMBOL(kimage_vaddr)
> >   * booted in EL1 or EL2 respectively.
> >   */
> >  SYM_FUNC_START(init_kernel_el)
> > -	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
> > -	msr	sctlr_el1, x0
> > -
> >  	mrs	x0, CurrentEL
> >  	cmp	x0, #CurrentEL_EL2
> >  	b.eq	init_el2
> >  
> >  SYM_INNER_LABEL(init_el1, SYM_L_LOCAL)
> > +	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
> > +	msr	sctlr_el1, x0
> >  	isb
> >  	mov_q	x0, INIT_PSTATE_EL1
> >  	msr	spsr_el1, x0
> > @@ -504,6 +503,34 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
> >  	msr	vbar_el2, x0
> >  	isb
> >  
> > +	/*
> > +	 * Fruity CPUs seem to have HCR_EL2.E2H set to RES1,
> > +	 * making it impossible to start in nVHE mode. Is that
> > +	 * compliant with the architecture? Absolutely not!
> > +	 */
> > +	mrs	x0, hcr_el2
> > +	and	x0, x0, #HCR_E2H
> > +	cbz	x0, 1f
> > +
> > +	/* Switching to VHE requires a sane SCTLR_EL1 as a start */
> > +	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
> > +	msr_s	SYS_SCTLR_EL12, x0
> > +
> > +	/*
> > +	 * Force an eret into a helper "function", and let it return
> > +	 * to our original caller... This makes sure that we have
> > +	 * initialised the basic PSTATE state.
> > +	 */
> > +	mov	x0, #INIT_PSTATE_EL2
> > +	msr	spsr_el1, x0
> > +	adr_l	x0, stick_to_vhe
> > +	msr	elr_el1, x0
> > +	eret
> > +
> > +1:
> > +	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
> > +	msr	sctlr_el1, x0
> > +
> >  	msr	elr_el2, lr
> >  	mov	w0, #BOOT_CPU_MODE_EL2
> >  	eret
> > diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
> > index 5eccbd62fec8..c7601030ee82 100644
> > --- a/arch/arm64/kernel/hyp-stub.S
> > +++ b/arch/arm64/kernel/hyp-stub.S
> > @@ -27,12 +27,12 @@ SYM_CODE_START(__hyp_stub_vectors)
> >  	ventry	el2_fiq_invalid			// FIQ EL2t
> >  	ventry	el2_error_invalid		// Error EL2t
> >  
> > -	ventry	el2_sync_invalid		// Synchronous EL2h
> > +	ventry	elx_sync			// Synchronous EL2h
> >  	ventry	el2_irq_invalid			// IRQ EL2h
> >  	ventry	el2_fiq_invalid			// FIQ EL2h
> >  	ventry	el2_error_invalid		// Error EL2h
> >  
> > -	ventry	el1_sync			// Synchronous 64-bit EL1
> > +	ventry	elx_sync			// Synchronous 64-bit EL1
> >  	ventry	el1_irq_invalid			// IRQ 64-bit EL1
> >  	ventry	el1_fiq_invalid			// FIQ 64-bit EL1
> >  	ventry	el1_error_invalid		// Error 64-bit EL1
> > @@ -45,7 +45,7 @@ SYM_CODE_END(__hyp_stub_vectors)
> >  
> >  	.align 11
> >  
> > -SYM_CODE_START_LOCAL(el1_sync)
> > +SYM_CODE_START_LOCAL(elx_sync)
> >  	cmp	x0, #HVC_SET_VECTORS
> >  	b.ne	1f
> >  	msr	vbar_el2, x1
> > @@ -71,7 +71,7 @@ SYM_CODE_START_LOCAL(el1_sync)
> >  
> >  9:	mov	x0, xzr
> >  	eret
> > -SYM_CODE_END(el1_sync)
> > +SYM_CODE_END(elx_sync)
> >  
> >  // nVHE? No way! Give me the real thing!
> >  SYM_CODE_START_LOCAL(mutate_to_vhe)
> > @@ -243,3 +243,23 @@ SYM_FUNC_START(switch_to_vhe)
> >  #endif
> >  	ret
> >  SYM_FUNC_END(switch_to_vhe)
> > +
> > +SYM_FUNC_START(stick_to_vhe)
> > +	/*
> > +	 * Make sure the switch to VHE cannot fail, by overriding the
> > +	 * override. This is hilarious.
> > +	 */
> > +	adr_l	x1, id_aa64mmfr1_override
> > +	add	x1, x1, #FTR_OVR_MASK_OFFSET
> > +	dc 	civac, x1
> > +	dsb	sy
> > +	isb
> 
> Why do we need an ISB here?

Hmmm. Probably me being paranoid and trying to come up with something
for Hector to test before I had access to the HW. The DSB is more than
enough to order CMO and load/store.

> > +	ldr	x0, [x1]
> > +	bic	x0, x0, #(0xf << ID_AA64MMFR1_VHE_SHIFT)
> > +	str	x0, [x1]
> 
> I find it a bit bizarre doing this here, as for the primary CPU we're still
> a way away from parsing the early paramaters and for secondary CPUs this
> doesn't need to be done for each one. Furthermore, this same code is run
> on the resume path, which can probably then race with itself.

Agreed, this isn't great.

> Is it possible to do it later on the boot CPU only, e.g. in
> init_feature_override()? We should probably also log a warning that we're
> ignoring the option because nVHE is not available.

I've come up with this on top of the original patch, spitting a
warning when the right conditions are met. It's pretty ugly, but hey,
so is the HW this runs on.

	M.

diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index c7601030ee82..e6fa5cdd790a 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -245,19 +245,6 @@ SYM_FUNC_START(switch_to_vhe)
 SYM_FUNC_END(switch_to_vhe)
 
 SYM_FUNC_START(stick_to_vhe)
-	/*
-	 * Make sure the switch to VHE cannot fail, by overriding the
-	 * override. This is hilarious.
-	 */
-	adr_l	x1, id_aa64mmfr1_override
-	add	x1, x1, #FTR_OVR_MASK_OFFSET
-	dc 	civac, x1
-	dsb	sy
-	isb
-	ldr	x0, [x1]
-	bic	x0, x0, #(0xf << ID_AA64MMFR1_VHE_SHIFT)
-	str	x0, [x1]
-
 	mov	x0, #HVC_VHE_RESTART
 	hvc	#0
 	mov	x0, #BOOT_CPU_MODE_EL2
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index 83f1c4b92095..ec07e150cf5c 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -195,6 +195,8 @@ static __init void parse_cmdline(void)
 		__parse_cmdline(prop, true);
 }
 
+static bool nvhe_impaired __initdata;
+
 /* Keep checkers quiet */
 void init_feature_override(void);
 
@@ -211,9 +213,32 @@ asmlinkage void __init init_feature_override(void)
 
 	parse_cmdline();
 
+	/*
+	 * If we ever reach this point while running VHE, we're
+	 * guaranteed to be on one of these funky, VHE-stuck CPUs. If
+	 * the user was trying to force nVHE on us, proceed with
+	 * attitude adjustment.
+	 */
+	if (is_kernel_in_hyp_mode()) {
+		u64 mask = 0xfUL << ID_AA64MMFR1_VHE_SHIFT;
+
+		if ((id_aa64mmfr1_override.mask & mask) &&
+		    !(id_aa64mmfr1_override.val & mask)) {
+			nvhe_impaired = true;
+			id_aa64mmfr1_override.mask &= ~mask;
+		}
+	}
+
 	for (i = 0; i < ARRAY_SIZE(regs); i++) {
 		if (regs[i]->override)
 			__flush_dcache_area(regs[i]->override,
 					    sizeof(*regs[i]->override));
 	}
 }
+
+static int __init check_feature_override(void)
+{
+	WARN_ON(nvhe_impaired);
+	return 0;
+}
+core_initcall(check_feature_override);

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 08/27] asm-generic/io.h: Add a non-posted variant of ioremap()
  2021-03-24 19:09     ` Arnd Bergmann
@ 2021-03-25 14:07       ` Hector Martin
  2021-03-25 14:49         ` Will Deacon
  0 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-25 14:07 UTC (permalink / raw)
  To: Arnd Bergmann, Will Deacon
  Cc: Linux ARM, Marc Zyngier, Rob Herring, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Linus Walleij,
	Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	open list:DOCUMENTATION,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES, linux-arch,
	Linux Kernel Mailing List

On 25/03/2021 04.09, Arnd Bergmann wrote:
> On Wed, Mar 24, 2021 at 7:12 PM Will Deacon <will@kernel.org> wrote:
>>
>>> +/*
>>> + * ioremap_np needs an explicit architecture implementation, as it
>>> + * requests stronger semantics than regular ioremap(). Portable drivers
>>> + * should instead use one of the higher-level abstractions, like
>>> + * devm_ioremap_resource(), to choose the correct variant for any given
>>> + * device and bus. Portable drivers with a good reason to want non-posted
>>> + * write semantics should always provide an ioremap() fallback in case
>>> + * ioremap_np() is not available.
>>> + */
>>> +#ifndef ioremap_np
>>> +#define ioremap_np ioremap_np
>>> +static inline void __iomem *ioremap_np(phys_addr_t offset, size_t size)
>>> +{
>>> +     return NULL;
>>> +}
>>> +#endif
>>
>> Can we implement the generic pci_remap_cfgspace() in terms of ioremap_np()
>> if it is supported by the architecture? That way, we could avoid defining
>> both on arm64.
> 
> Good idea. It needs a fallback in case the ioremap_np() fails on most
> architectures, but that sounds easy enough.
> 
> Since pci_remap_cfgspace() only has custom implementations, it sounds like
> we can actually make the generic implementation unconditional in the end,
> but that requires adding ioremap_np() on 32-bit as well, and I would keep
> that separate from this series.

Sounds good; I'm adding a patch to adjust the generic implementation and 
remove the arm64 one in v4, and we can then complete the cleanup for 
other arches later.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 08/27] asm-generic/io.h: Add a non-posted variant of ioremap()
  2021-03-25 14:07       ` Hector Martin
@ 2021-03-25 14:49         ` Will Deacon
  0 siblings, 0 replies; 136+ messages in thread
From: Will Deacon @ 2021-03-25 14:49 UTC (permalink / raw)
  To: Hector Martin
  Cc: Arnd Bergmann, Linux ARM, Marc Zyngier, Rob Herring,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, DTML, open list:SERIAL DRIVERS,
	open list:DOCUMENTATION,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES, linux-arch,
	Linux Kernel Mailing List

On Thu, Mar 25, 2021 at 11:07:40PM +0900, Hector Martin wrote:
> On 25/03/2021 04.09, Arnd Bergmann wrote:
> > On Wed, Mar 24, 2021 at 7:12 PM Will Deacon <will@kernel.org> wrote:
> > > 
> > > > +/*
> > > > + * ioremap_np needs an explicit architecture implementation, as it
> > > > + * requests stronger semantics than regular ioremap(). Portable drivers
> > > > + * should instead use one of the higher-level abstractions, like
> > > > + * devm_ioremap_resource(), to choose the correct variant for any given
> > > > + * device and bus. Portable drivers with a good reason to want non-posted
> > > > + * write semantics should always provide an ioremap() fallback in case
> > > > + * ioremap_np() is not available.
> > > > + */
> > > > +#ifndef ioremap_np
> > > > +#define ioremap_np ioremap_np
> > > > +static inline void __iomem *ioremap_np(phys_addr_t offset, size_t size)
> > > > +{
> > > > +     return NULL;
> > > > +}
> > > > +#endif
> > > 
> > > Can we implement the generic pci_remap_cfgspace() in terms of ioremap_np()
> > > if it is supported by the architecture? That way, we could avoid defining
> > > both on arm64.
> > 
> > Good idea. It needs a fallback in case the ioremap_np() fails on most
> > architectures, but that sounds easy enough.
> > 
> > Since pci_remap_cfgspace() only has custom implementations, it sounds like
> > we can actually make the generic implementation unconditional in the end,
> > but that requires adding ioremap_np() on 32-bit as well, and I would keep
> > that separate from this series.
> 
> Sounds good; I'm adding a patch to adjust the generic implementation and
> remove the arm64 one in v4, and we can then complete the cleanup for other
> arches later.

Cheers. Don't forget to update the comment in the generic code which
complains about the lack of an ioremap() API for non-posted writes ;)

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 13/27] arm64: Add Apple vendor-specific system registers
  2021-03-24 19:04       ` Will Deacon
@ 2021-03-26  6:23         ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-26  6:23 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On 25/03/2021 04.04, Will Deacon wrote:
> On Wed, Mar 24, 2021 at 06:59:21PM +0000, Mark Rutland wrote:
>> So far we've kept arch/arm64/ largely devoid of IMP-DEF bits, and it
>> seems a shame to add something with the sole purpose of collating that,
>> especially given arch code shouldn't need to touch these if FW and
>> bootloader have done their jobs right.
>>
>> Can we put the definitions in the relevant drivers? That would sidestep
>> any pain with MAINTAINERS, too.
> 
> If we can genuinely ignore these in arch code, then sure. I just don't know
> how long that is going to be the case, and ending up in a situation where
> these are scattered randomly throughout the tree sounds horrible to me.

I thought we would need some in KVM code, but given the direction Marc's 
series ended up in, it seems we won't. So I'm happy keeping these in the 
respective drivers; if this ends up being messy in the future it 
shouldn't be a big deal to refactor it all into one file again.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 01/27] arm64: Cope with CPUs stuck in VHE mode
  2021-03-24 20:00     ` Marc Zyngier
@ 2021-03-26  7:54       ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-26  7:54 UTC (permalink / raw)
  To: Marc Zyngier, Will Deacon
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Linus Walleij,
	Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On 25/03/2021 05.00, Marc Zyngier wrote:
> I've come up with this on top of the original patch, spitting a
> warning when the right conditions are met. It's pretty ugly, but hey,
> so is the HW this runs on.

[...]

Folded into v4 and tested; works fine with `kvm-arm.mode=nvhe`, throwing 
the ugly WARN.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-03-08 13:31   ` Marc Zyngier
@ 2021-03-26  7:57     ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-26  7:57 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, Rob Herring, Arnd Bergmann, Olof Johansson,
	Krzysztof Kozlowski, Mark Kettenis, Tony Lindgren,
	Mohamed Mediouni, Stan Skowronek, Alexander Graf, Will Deacon,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

On 08/03/2021 22.31, Marc Zyngier wrote:
>> +	if ((read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EN) &&
>> +		read_sysreg_s(SYS_ICH_MISR_EL2) != 0) {
>> +		pr_err("vGIC IRQ fired, disabling.\n");
> 
> Please add a _ratelimited here. Whilst debugging KVM on this machine,
> I ended up with this firing at such a rate that it was impossible to
> do anything useful. Ratelimiting it allowed me to pinpoint the
> problem.

Ouch. Done for v4.

>> +static void aic_fiq_eoi(struct irq_data *d)
>> +{
>> +	/* We mask to ack (where we can), so we need to unmask at EOI. */
>> +	if (!irqd_irq_disabled(d) && !irqd_irq_masked(d))
> 
> Ah, be careful here: irqd_irq_masked() doesn't do what you think it
> does for per-CPU interrupts. It's been on my list to fix for the rVIC
> implementation, but I never got around to doing it, and all decent ICs
> hide this from SW by having a HW-managed mask, similar to what is on
> the IRQ side.
> 
> I can see two possibilities:
> 
> - you can track the masked state directly and use that instead of
>    these predicates
> 
> - you can just drop the masking altogether as this is only useful to a
>    hosted hypervisor (KVM), which will have to do its own masking
>    behind the scenes anyway
> 

Since you're using the masking in KVM after all, I'm tracking the mask 
state in a percpu variable now. Also folded in your two minor bugfixes 
from the KVM series. Cheers!


-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-03-24 19:57   ` Will Deacon
@ 2021-03-26  8:58     ` Hector Martin
  2021-03-29 12:04       ` Will Deacon
  0 siblings, 1 reply; 136+ messages in thread
From: Hector Martin @ 2021-03-26  8:58 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

Hi Will,

No worries, I was busy until a couple days ago anyway.

On 25/03/2021 04.57, Will Deacon wrote:
>> +#define pr_fmt(fmt) "%s: " fmt, __func__
> 
> General nit: but I suspect many of the prints in here probably want to be
> using the *_ratelimited variants.

You're right, everything complaining about spurious/unsupported stuff is 
probably safer rate-limited. I also made them all pr_err_ratelimited, 
since nothing should be trying to use that hardware before we get around 
to supporting it in this driver.

>> +static void __exception_irq_entry aic_handle_irq(struct pt_regs *regs)
>> +{
>> +	struct aic_irq_chip *ic = aic_irqc;
>> +	u32 event, type, irq;
>> +
>> +	do {
>> +		/*
>> +		 * We cannot use a relaxed read here, as DMA needs to be
>> +		 * ordered with respect to the IRQ firing.
>> +		 */
> 
> I think this could be a bit clearer: the readl() doesn't order any DMA
> accesses, but instead means that subsequent reads by the CPU are ordered
> (which may be from a buffer which was DMA'd to) are ordered after the
> read of the MMIO register.

Good point, reworded it for v4:

/*
  * We cannot use a relaxed read here, as reads from DMA buffers
  * need to be ordered after the IRQ fires.
  */

> 
>> +		event = readl(ic->base + AIC_EVENT);
>> +		type = FIELD_GET(AIC_EVENT_TYPE, event);
>> +		irq = FIELD_GET(AIC_EVENT_NUM, event);
>> +
>> +		if (type == AIC_EVENT_TYPE_HW)
>> +			handle_domain_irq(aic_irqc->hw_domain, irq, regs);
>> +		else if (type == AIC_EVENT_TYPE_IPI && irq == 1)
>> +			aic_handle_ipi(regs);
>> +		else if (event != 0)
>> +			pr_err("Unknown IRQ event %d, %d\n", type, irq);
>> +	} while (event);
>> +
>> +	/*
>> +	 * vGIC maintenance interrupts end up here too, so we need to check
>> +	 * for them separately. Just report and disable vGIC for now, until
>> +	 * we implement this properly.
>> +	 */
>> +	if ((read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EN) &&
>> +		read_sysreg_s(SYS_ICH_MISR_EL2) != 0) {
>> +		pr_err("vGIC IRQ fired, disabling.\n");
>> +		sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EN, 0);
>> +	}
> 
> What prevents all these system register accesses being speculated up before
> the handler?

Nothing, but that's not a problem, is it? If the condition is met, it 
means the vGIC IRQ *is* firing and needs clearing. We don't particularly 
care if this happens before, after, or during the rest of the IRQ handling.

I changed the message to this, because we actually should never hit this 
path with correctly-working KVM code (it takes care of it before this 
handler runs):

pr_err_ratelimited("vGIC IRQ fired and not handled by KVM, disabling.\n");

>> +static struct irq_chip aic_chip = {
>> +	.name = "AIC",
>> +	.irq_mask = aic_irq_mask,
>> +	.irq_unmask = aic_irq_unmask,
> 
> I know these are driven by the higher-level irq chip code, but I'm a bit
> confused as to what provides ordering if, e.g. something ends up calling:
> 
> 	aic_chip.irq_mask(d);
> 	...
> 	aic_chip.irq_unmask(d);
> 
> I can't see any ISBs in here and they're writing to two different registers,
> so can we end up with the IRQ masked after this sequence?

Wait, aren't MMIO writes to the same peripheral using device-nGnRnE 
memory modes always ordered with respect to each other? I thought the 
_relaxed versions were only trouble when mixed with memory/DMA buffers, 
and MMIO for any given peripheral always takes effect in program order.

>> +static void aic_ipi_mask(struct irq_data *d)
>> +{
>> +	u32 irq_bit = BIT(irqd_to_hwirq(d));
>> +	int this_cpu = smp_processor_id();
>> +
>> +	/* No specific ordering requirements needed here. */
>> +	atomic_andnot(irq_bit, &aic_vipi_enable[this_cpu]);
>> +}
> 
> Why not use a per-cpu variable here instead of an array of atomics? The pcpu
> API has things for atomic updates (e.g. or, and, xchg).

One CPU still needs to be able to mutate the flags of another CPU to 
fire an IPI; AIUI the per-cpu ops are *not* atomic for concurrent access 
by multiple CPUs, and in fact there is no API for that, only for "this CPU".

>> +static void aic_ipi_unmask(struct irq_data *d)
>> +{
>> +	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
>> +	u32 irq_bit = BIT(irqd_to_hwirq(d));
>> +	int this_cpu = smp_processor_id();
>> +
>> +	/*
>> +	 * This must complete before the atomic_read_acquire() below to avoid
>> +	 * racing aic_ipi_send_mask(). Use a dummy fetch op with release
>> +	 * semantics for this. This is arch-specific: ARMv8 B2.3.3 specifies
>> +	 * that writes with Release semantics are Barrier-ordered-before reads
>> +	 * with Acquire semantics, even though the Linux arch-independent
>> +	 * definition of these atomic ops does not.
>> +	 */
> 
> I think a more idiomatic (and portable) way to do this would be to use
> the relaxed accessors, but with smp_mb__after_atomic() between them. Do you
> have a good reason for _not_ doing it like that?

Not particularly, other than symmetry with the case below.

>> +		/*
>> +		 * This sequence is the mirror of the one in aic_ipi_unmask();
>> +		 * see the comment there. Additionally, release semantics
>> +		 * ensure that the vIPI flag set is ordered after any shared
>> +		 * memory accesses that precede it. This therefore also pairs
>> +		 * with the atomic_fetch_andnot in aic_handle_ipi().
>> +		 */
>> +		pending = atomic_fetch_or_release(irq_bit, &aic_vipi_flag[cpu]);

We do need the return data here, and the release semantics (or another 
barrier before it). But the read below can be made relaxed and a barrier 
used instead, and then the same patern above except with a plain 
atomic_or().

>> +		if (!(pending & irq_bit) && (atomic_read_acquire(&aic_vipi_enable[cpu]) & irq_bit))
>> +			send |= AIC_IPI_SEND_CPU(cpu);
>> +	}

[...]

>> +	/*
>> +	 * Clear the IPIs we are about to handle. This pairs with the
>> +	 * atomic_fetch_or_release() in aic_ipi_send_mask(), and needs to be
>> +	 * ordered after the aic_ic_write() above (to avoid dropping vIPIs) and
>> +	 * before IPI handling code (to avoid races handling vIPIs before they
>> +	 * are signaled). The former is taken care of by the release semantics
>> +	 * of the write portion, while the latter is taken care of by the
>> +	 * acquire semantics of the read portion.
>> +	 */
>> +	firing = atomic_fetch_andnot(enabled, &aic_vipi_flag[this_cpu]) & enabled;
> 
> Does this also need to be ordered after the Ack? For example, if we have
> something like:
> 
> CPU 0						CPU 1
> 						<some other IPI>
> aic_ipi_send_mask()
> 						atomic_fetch_andnot(flag)
> 	atomic_fetch_or_release(flag)
> 	aic_ic_write(AIC_IPI_SEND)
> 						aic_ic_write(AIC_IPI_ACK)
> 
> sorry if it's a stupid question, I'm just not sure about the cases in which
> the hardware will pend things for you.

It is ordered, right? As the comment says, it "needs to be ordered after 
the aic_ic_write() above". atomic_fetch_andnot() is *supposed* to be 
fully ordered and that should include against the writel_relaxed() on 
AIC_IPI_FLAG. On ARM it turns out it's not quite fully ordered, but the 
acquire semantics of the read half are sufficient for this case, as they 
guarantee the flags are always read after the FIQ has been ACKed.

Cheeers,
-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-03-05 15:05   ` Andy Shevchenko
  2021-03-08 11:50     ` Marc Zyngier
@ 2021-03-26 13:40     ` Hector Martin
  1 sibling, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-03-26 13:40 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-arm Mailing List, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Will Deacon, Linus Walleij, Mark Rutland, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, open list:SERIAL DRIVERS,
	Linux Documentation List, Linux Samsung SOC, Linux-Arch,
	Linux Kernel Mailing List

On 06/03/2021 00.05, Andy Shevchenko wrote:
>> +#define pr_fmt(fmt) "%s: " fmt, __func__
> 
> This is not needed, really, if you have unique / distinguishable
> messages in the first place.
> Rather people include module names, which may be useful.

Makes sense, I'll switch to KBUILD_MODNAME.

>> +#define MASK_BIT(x)            BIT((x) & 0x1f)
> 
> GENMASK(4,0)

It's not really a register bitmask, but rather extracting the low bits 
of an index... but sure, GENMASK also expresses that. Changed.

>> +static atomic_t aic_vipi_flag[AIC_MAX_CPUS];
>> +static atomic_t aic_vipi_enable[AIC_MAX_CPUS];
> 
> Isn't it easier to handle these when they are full width, i.e. 32
> items per the array?

I don't think so, it doesn't really buy us anything. It's just a maximum 
beyond which the driver doesn't work in its current state anyway (if the 
number were much larger it'd make sense to dynamically allocate these, 
but not at this point).

>> +static int aic_irq_set_affinity(struct irq_data *d,
>> +                               const struct cpumask *mask_val, bool force)
>> +{
>> +       irq_hw_number_t hwirq = irqd_to_hwirq(d);
>> +       struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
>> +       int cpu;
>> +
>> +       if (hwirq > ic->nr_hw)
> 
> >= ?

Good catch, but this is actually obsolete. Higher IRQs go into the FIQ 
irqchip, so this should never happen (it's a leftover from when they 
were a single one). I'll remove it.

Ack on the other comments, thanks!

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-03-26  8:58     ` Hector Martin
@ 2021-03-29 12:04       ` Will Deacon
  2021-04-01 13:16         ` Hector Martin
  0 siblings, 1 reply; 136+ messages in thread
From: Will Deacon @ 2021-03-29 12:04 UTC (permalink / raw)
  To: Hector Martin
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

Hi Hector,

On Fri, Mar 26, 2021 at 05:58:15PM +0900, Hector Martin wrote:
> On 25/03/2021 04.57, Will Deacon wrote:
> > > +		event = readl(ic->base + AIC_EVENT);
> > > +		type = FIELD_GET(AIC_EVENT_TYPE, event);
> > > +		irq = FIELD_GET(AIC_EVENT_NUM, event);
> > > +
> > > +		if (type == AIC_EVENT_TYPE_HW)
> > > +			handle_domain_irq(aic_irqc->hw_domain, irq, regs);
> > > +		else if (type == AIC_EVENT_TYPE_IPI && irq == 1)
> > > +			aic_handle_ipi(regs);
> > > +		else if (event != 0)
> > > +			pr_err("Unknown IRQ event %d, %d\n", type, irq);
> > > +	} while (event);
> > > +
> > > +	/*
> > > +	 * vGIC maintenance interrupts end up here too, so we need to check
> > > +	 * for them separately. Just report and disable vGIC for now, until
> > > +	 * we implement this properly.
> > > +	 */
> > > +	if ((read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EN) &&
> > > +		read_sysreg_s(SYS_ICH_MISR_EL2) != 0) {
> > > +		pr_err("vGIC IRQ fired, disabling.\n");
> > > +		sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EN, 0);
> > > +	}
> > 
> > What prevents all these system register accesses being speculated up before
> > the handler?
> 
> Nothing, but that's not a problem, is it? If the condition is met, it means
> the vGIC IRQ *is* firing and needs clearing. We don't particularly care if
> this happens before, after, or during the rest of the IRQ handling.
> 
> I changed the message to this, because we actually should never hit this
> path with correctly-working KVM code (it takes care of it before this
> handler runs):
> 
> pr_err_ratelimited("vGIC IRQ fired and not handled by KVM, disabling.\n");

Looks good.

> > > +static struct irq_chip aic_chip = {
> > > +	.name = "AIC",
> > > +	.irq_mask = aic_irq_mask,
> > > +	.irq_unmask = aic_irq_unmask,
> > 
> > I know these are driven by the higher-level irq chip code, but I'm a bit
> > confused as to what provides ordering if, e.g. something ends up calling:
> > 
> > 	aic_chip.irq_mask(d);
> > 	...
> > 	aic_chip.irq_unmask(d);
> > 
> > I can't see any ISBs in here and they're writing to two different registers,
> > so can we end up with the IRQ masked after this sequence?
> 
> Wait, aren't MMIO writes to the same peripheral using device-nGnRnE memory
> modes always ordered with respect to each other? I thought the _relaxed
> versions were only trouble when mixed with memory/DMA buffers, and MMIO for
> any given peripheral always takes effect in program order.

Sorry, this was my mistake -- I seem to have mixed up the MMIO parts with
the system register parts. In this case, aic_irq_[un]mask() are MMIO writes,
so things work out. It's the FIQ mask/unmask code that needs the ISBs.

> > > +static void aic_ipi_mask(struct irq_data *d)
> > > +{
> > > +	u32 irq_bit = BIT(irqd_to_hwirq(d));
> > > +	int this_cpu = smp_processor_id();
> > > +
> > > +	/* No specific ordering requirements needed here. */
> > > +	atomic_andnot(irq_bit, &aic_vipi_enable[this_cpu]);
> > > +}
> > 
> > Why not use a per-cpu variable here instead of an array of atomics? The pcpu
> > API has things for atomic updates (e.g. or, and, xchg).
> 
> One CPU still needs to be able to mutate the flags of another CPU to fire an
> IPI; AIUI the per-cpu ops are *not* atomic for concurrent access by multiple
> CPUs, and in fact there is no API for that, only for "this CPU".

Huh, I really thought we had an API for that, but you're right. Oh well! But
I'd still suggest a per-cpu atomic_t in that case, rather than the array.

> > > +static void aic_ipi_unmask(struct irq_data *d)
> > > +{
> > > +	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
> > > +	u32 irq_bit = BIT(irqd_to_hwirq(d));
> > > +	int this_cpu = smp_processor_id();
> > > +
> > > +	/*
> > > +	 * This must complete before the atomic_read_acquire() below to avoid
> > > +	 * racing aic_ipi_send_mask(). Use a dummy fetch op with release
> > > +	 * semantics for this. This is arch-specific: ARMv8 B2.3.3 specifies
> > > +	 * that writes with Release semantics are Barrier-ordered-before reads
> > > +	 * with Acquire semantics, even though the Linux arch-independent
> > > +	 * definition of these atomic ops does not.
> > > +	 */
> > 
> > I think a more idiomatic (and portable) way to do this would be to use
> > the relaxed accessors, but with smp_mb__after_atomic() between them. Do you
> > have a good reason for _not_ doing it like that?
> 
> Not particularly, other than symmetry with the case below.

I think it would be better not to rely on arm64-specific ordering unless
there's a good reason to.

> > > +		/*
> > > +		 * This sequence is the mirror of the one in aic_ipi_unmask();
> > > +		 * see the comment there. Additionally, release semantics
> > > +		 * ensure that the vIPI flag set is ordered after any shared
> > > +		 * memory accesses that precede it. This therefore also pairs
> > > +		 * with the atomic_fetch_andnot in aic_handle_ipi().
> > > +		 */
> > > +		pending = atomic_fetch_or_release(irq_bit, &aic_vipi_flag[cpu]);
> 
> We do need the return data here, and the release semantics (or another
> barrier before it). But the read below can be made relaxed and a barrier
> used instead, and then the same patern above except with a plain
> atomic_or().

Yes, I think using atomic_fetch_or() followed by atomic_read() would be
best (obviously with the relevant comments!)

> 
> > > +		if (!(pending & irq_bit) && (atomic_read_acquire(&aic_vipi_enable[cpu]) & irq_bit))
> > > +			send |= AIC_IPI_SEND_CPU(cpu);
> > > +	}
> 
> [...]
> 
> > > +	/*
> > > +	 * Clear the IPIs we are about to handle. This pairs with the
> > > +	 * atomic_fetch_or_release() in aic_ipi_send_mask(), and needs to be
> > > +	 * ordered after the aic_ic_write() above (to avoid dropping vIPIs) and
> > > +	 * before IPI handling code (to avoid races handling vIPIs before they
> > > +	 * are signaled). The former is taken care of by the release semantics
> > > +	 * of the write portion, while the latter is taken care of by the
> > > +	 * acquire semantics of the read portion.
> > > +	 */
> > > +	firing = atomic_fetch_andnot(enabled, &aic_vipi_flag[this_cpu]) & enabled;
> > 
> > Does this also need to be ordered after the Ack? For example, if we have
> > something like:
> > 
> > CPU 0						CPU 1
> > 						<some other IPI>
> > aic_ipi_send_mask()
> > 						atomic_fetch_andnot(flag)
> > 	atomic_fetch_or_release(flag)
> > 	aic_ic_write(AIC_IPI_SEND)
> > 						aic_ic_write(AIC_IPI_ACK)
> > 
> > sorry if it's a stupid question, I'm just not sure about the cases in which
> > the hardware will pend things for you.
> 
> It is ordered, right? As the comment says, it "needs to be ordered after the
> aic_ic_write() above". atomic_fetch_andnot() is *supposed* to be fully
> ordered and that should include against the writel_relaxed() on
> AIC_IPI_FLAG. On ARM it turns out it's not quite fully ordered, but the
> acquire semantics of the read half are sufficient for this case, as they
> guarantee the flags are always read after the FIQ has been ACKed.

Sorry, I missed that the answer to my question was already written in the
comment. However, I'm still a bit unsure about whether the memory barriers
give you what you need here. The barrier in atomic_fetch_andnot() will
order the previous aic_ic_write(AIC_IPI_ACK) for the purposes of other
CPUs reading those locations, but it doesn't say anything about when the
interrupt controller actually changes state after the Ack.

Given that the AIC is mapped Device-nGnRnE, the Arm ARM offers:

  | Additionally, for Device-nGnRnE memory, a read or write of a Location
  | in a Memory-mapped peripheral that exhibits side-effects is complete
  | only when the read or write both:
  |
  | * Can begin to affect the state of the Memory-mapped peripheral.
  | * Can trigger all associated side-effects, whether they affect other
  |   peripheral devices, PEs, or memory.

so without AIC documentation I can't tell whether completion of the Ack write
just begins the process of an Ack (in which case we might need something like
a read-back), or whether the write response back from the AIC only occurs once
the Ack has taken effect. Any ideas?

> Cheeers,

No prooblem :)

Will

^ permalink raw reply	[flat|nested] 136+ messages in thread

* Re: [RFT PATCH v3 16/27] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-03-29 12:04       ` Will Deacon
@ 2021-04-01 13:16         ` Hector Martin
  0 siblings, 0 replies; 136+ messages in thread
From: Hector Martin @ 2021-04-01 13:16 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-arm-kernel, Marc Zyngier, Rob Herring, Arnd Bergmann,
	Olof Johansson, Krzysztof Kozlowski, Mark Kettenis,
	Tony Lindgren, Mohamed Mediouni, Stan Skowronek, Alexander Graf,
	Linus Walleij, Mark Rutland, Andy Shevchenko, Greg Kroah-Hartman,
	Jonathan Corbet, Catalin Marinas, Christoph Hellwig,
	David S. Miller, devicetree, linux-serial, linux-doc,
	linux-samsung-soc, linux-arch, linux-kernel

Hi Will,

On 29/03/2021 21.04, Will Deacon wrote:
>> One CPU still needs to be able to mutate the flags of another CPU to fire an
>> IPI; AIUI the per-cpu ops are *not* atomic for concurrent access by multiple
>> CPUs, and in fact there is no API for that, only for "this CPU".
> 
> Huh, I really thought we had an API for that, but you're right. Oh well! But
> I'd still suggest a per-cpu atomic_t in that case, rather than the array.

Yeah, after digging into the per-cpu stuff earlier and understanding how 
it works, I agree that a per-cpu atomic makes sense here. Switched it to 
that (which simplified out a bunch of smp_processor_id() calls too). Thanks!

>>> I think a more idiomatic (and portable) way to do this would be to use
>>> the relaxed accessors, but with smp_mb__after_atomic() between them. Do you
>>> have a good reason for _not_ doing it like that?
>>
>> Not particularly, other than symmetry with the case below.
> 
> I think it would be better not to rely on arm64-specific ordering unless
> there's a good reason to.

Sounds reasonable, I'll switch to the barrier version.

>> We do need the return data here, and the release semantics (or another
>> barrier before it). But the read below can be made relaxed and a barrier
>> used instead, and then the same patern above except with a plain
>> atomic_or().
> 
> Yes, I think using atomic_fetch_or() followed by atomic_read() would be
> best (obviously with the relevant comments!)

atomic_fetch_or_release is sufficient here (atomic_fetch_or is stronger; 
atomic_fetch_or_relaxed would not be strong enough as this needs to be 
ordered after any writes prior to sending the IPI; in this case release 
semantics also make logical sense).

>> It is ordered, right? As the comment says, it "needs to be ordered after the
>> aic_ic_write() above". atomic_fetch_andnot() is *supposed* to be fully
>> ordered and that should include against the writel_relaxed() on
>> AIC_IPI_FLAG. On ARM it turns out it's not quite fully ordered, but the
>> acquire semantics of the read half are sufficient for this case, as they
>> guarantee the flags are always read after the FIQ has been ACKed.
> 
> Sorry, I missed that the answer to my question was already written in the
> comment. However, I'm still a bit unsure about whether the memory barriers
> give you what you need here. The barrier in atomic_fetch_andnot() will
> order the previous aic_ic_write(AIC_IPI_ACK) for the purposes of other
> CPUs reading those locations, but it doesn't say anything about when the
> interrupt controller actually changes state after the Ack.
> 
> Given that the AIC is mapped Device-nGnRnE, the Arm ARM offers:
> 
>    | Additionally, for Device-nGnRnE memory, a read or write of a Location
>    | in a Memory-mapped peripheral that exhibits side-effects is complete
>    | only when the read or write both:
>    |
>    | * Can begin to affect the state of the Memory-mapped peripheral.
>    | * Can trigger all associated side-effects, whether they affect other
>    |   peripheral devices, PEs, or memory.
> 
> so without AIC documentation I can't tell whether completion of the Ack write
> just begins the process of an Ack (in which case we might need something like
> a read-back), or whether the write response back from the AIC only occurs once
> the Ack has taken effect. Any ideas?

Ahh, you're talking about latency within AIC itself... I obviously don't 
have an authoritative answer to this, though the hardware designer in me 
wants to say this really ought to be single-cycle type stuff that isn't 
internally pipelined in a way that would create races.

I tried to set up an SMP test case for the atomic-to-AIC sequence in 
m1n1, but unfortunately I couldn't hit the race window in deliberately 
racy code (i.e. ack after clearing flags) without widening it even 
further with at least one dummy load in between, and of course I didn't 
experience any races with the proper code either.

What I can say is that a simple set IPI; ack IPI (in adjacent str 
instructions) sequence always yields a cleared IPI, and the converse 
always yields a set IPI. So if there is latency to the operations it 
seems it would at least be the same for sets and acks and would imply 
readbacks block, which should still yield equivalently correct results. 
But of course this is a single-CPU test, so it is not fully 
representative of what could happen in an SMP scenario.

At this point all I can say is I'm inclined to shrug and say we have no 
evidence of this being something that can happen, and it shouldn't in 
sane hardware, and hope for the best :-)

Thanks,
-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

^ permalink raw reply	[flat|nested] 136+ messages in thread

end of thread, back to index

Thread overview: 136+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [RFT PATCH v3 10/27] docs: driver-api: device-io: Document ioremap() variants & access funcs Hector Martin
2021-03-05 10:25   ` 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

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git