Skip to content

MiSTer-v6.18: carried patch series + config + out-of-tree drivers on top of vanilla 6.18.38 - #75

Open
mcfbytes wants to merge 38 commits into
MiSTer-devel:MiSTer-v6.18from
mcfbytes:MiSTer-v6.18
Open

MiSTer-v6.18: carried patch series + config + out-of-tree drivers on top of vanilla 6.18.38#75
mcfbytes wants to merge 38 commits into
MiSTer-devel:MiSTer-v6.18from
mcfbytes:MiSTer-v6.18

Conversation

@mcfbytes

@mcfbytes mcfbytes commented Jul 16, 2026

Copy link
Copy Markdown

Per #74 — this builds directly on d9ac12a69 (v6.18.38), so it's a fast-forward: 38 commits ahead, 0 behind, nothing of yours restated or rewritten.

Thanks for creating the vanilla base; parenting on the tarball commit rather than a branch tip is exactly right, and it made this straightforward.

Updated. This branch now also carries your loop= patch, forward-ported to 6.18 — see the comment below for why it doesn't apply as-is and what the port had to do. The vendored rtl8814au driver is gone, replaced by the in-kernel rtw88_8814au.

What's in it

31 commits the carried MiSTer patch series, one per change, original authorship preserved (yours, Michael Huang's, Nolan Nicholson's, Aurora's, eniva's, …)
1 commit loop= support (3d95de58f), forward-ported to 6.18 — see below
1 commit arch/arm/configs/MiSTer_defconfig
3 commits vendored out-of-tree drivers, verbatim upstream, hash-verified
2 commits build-mister-modules.sh + EXPORT.md

Vendored drivers

path upstream pin
drivers/hid/xone dlundqvist/xone f2aa9fe
drivers/net/wireless/realtek/rtl8812au morrownr/8812au-20210820 8cac6f4
drivers/net/wireless/realtek/rtl8821au morrownr/8821au-20210708 3a7cdb5

These build against 6.18 with zero compatibility patches — worth noting since the 5.15 copies are from 2023 and would likely need real work against three years of netdev/cfg80211 churn.

rtl8814au is no longer vendored. 6.18 has an in-kernel mac80211 driver for it (CONFIG_RTW88_8814AU, same USB IDs), so the out-of-tree copy is redundant — that's ~457k lines of vendored driver removed in favour of a maintained in-tree one.

Building

make ARCH=arm MiSTer_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LOCALVERSION= zImage modules
./build-mister-modules.sh

Verified end-to-end with a real ARM toolchain: 8812au.ko, 8821au.ko, and 9 xone modules all build clean, and the tree builds a zImage standalone from MiSTer_defconfig with zero warnings from the MiSTer changes. Needs lz4 on the host (CONFIG_KERNEL_LZ4).

Two details on the middle line that cost me time:

  • LOCALVERSION= — empty but set. This is a git tree with commits over the v6.18.38 base, so setlocalversion appends +6.18.38+, which lands in vermagic and makes modprobe reject every module. Setting it suppresses that.
  • modules, not just zImage — external modules link against Module.symvers, which only make modules writes (it needs vmlinux first). modules_prepare isn't enough; skip it and modpost reports "skb_pull" [8812au.ko] undefined!, which looks like a broken driver and isn't.

Why the drivers aren't wired into Kconfig

I tried that first. The Realtek Makefiles do this, above their own ifneq ($(KERNELRELEASE),) guard:

export TopDIR ?= $(shell pwd)
$(shell cp $(TopDIR)/autoconf_..._linux.h $(TopDIR)/include/autoconf.h)

Parse-time filesystem work keyed off pwd. In an in-tree build pwd is the kernel root rather than the module directory, so TopDIR points at the wrong tree and the driver's generated autoconf.h silently never appears — $(shell ...) swallows the error. They're 2594-line Makefiles written on the assumption they're never in-tree, across ~1900 files.

So build-mister-modules.sh builds them out-of-tree, which is upstream's own supported path. Happy to do the in-tree integration instead if you'd prefer it — it just seemed wrong to hand you wiring no upstream tests.

This tree is not quite the kernel we ship

It is that kernel plus exactly one patch: your loop= commit. Our own build boots through an initramfs /init instead, so we don't apply it — but it's how every stock MiSTer boots, and a 6.18 branch without it wouldn't boot any of them. Deleting it to keep our two trees identical would have been the wrong trade.

EXPORT.md in the branch states this up front and tables the reason, so nobody has to reverse-engineer the difference. Everything else in the tree is byte-for-byte what we build.

What was carried, what wasn't, and why

The reasonable thing to be sceptical about here is what got left behind. Every commit on MiSTer-v5.15 was reconciled individually against real 6.18.38 source, with a disposition and cited evidence for each — not judged from memory:

  • docs/patch-provenance.md — the disposition table. One row per fork change: carried (with the 00xx-*.patch that carries it), superseded upstream (with the vanilla commit id that supersedes it, plus a file:line and a quoted hunk), or deliberately dropped (with the reason).
  • docs/kernel-recon/ — the per-commit evidence records behind those rows.
  • MISTER-KERNEL-PATCH-RECON.md — the method, including why the earlier provenance doc was treated as a hypothesis to re-test rather than as truth.

Worth knowing that no git command can answer "is this commit in 6.18?" — across this much context drift git patch-id matches nothing, so for anything reimplemented upstream the answer is semantic, not mechanical. That's why it's a document rather than a script.

Where it comes from

Generated from the patch series in Buildroot_MiSTer by a script, deterministically — same inputs, same SHAs, verified by regenerating twice and diffing the tip. A 6.18.39 bump is a version + hash change and a re-run; driver bumps are a pin change.

Reconstructing Buildroot's own recipe from scratch (pristine hash-verified tarball + the series applied with patch -p1) and diffing it against this branch's kernel source shows the loop= patch and nothing else. Separately, arch/arm/configs/MiSTer_defconfig here produces a .config byte-identical to the one Buildroot builds with, so the config can't drift from the image either.


One small thing, take it or leave it: d9ac12a69's tree is missing Documentation/.renames.txt relative to kernel.org's v6.18.38 (tree 4efcf6f42 vs d13b0d25d) — the same .gitignore-eats-a-tracked-file effect that cost the v5.15.1 base 11 files. No build impact. git add --force after extracting avoids it if you ever regenerate the base.


🤖 Generated with Claude Code

sorgelig and others added 30 commits July 17, 2017 15:38
The Keyrah C64/Amiga USB keyboard adapter reports its extra
"Europe 1" scancode (HID usage 0x32) as USB HID keycode 0x32, which
hid_keyboard[] maps to Linux keycode 43 (KEY_BACKSLASH) by default --
colliding with the adapter's real backslash key. Remaps it to
KEY_F24 (194), an otherwise-unused code Main_MiSTer can bind freely.

Provenance
----------
Origin:       70e391b
              "HID: map key Europe 1(0x32) to F24 code (for Keyrah)."
              MiSTer-devel/Linux-Kernel_MiSTer, 2017-07-17, against v5.15.
              MiSTer-devel@70e391b
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No (verified: drivers/hid/hid-input.c's hid_keyboard[]
              table entry for USB keycode 0x32 is still 43, not 194).
              Disposition "carry" (docs/patch-provenance.md class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Byte-identical hunk; hid_keyboard[] is unchanged since 5.15.

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
Most DE10-Nano boards don't have the optional RTC add-on fitted on
the i2c-gpio bus (see 0004-dts-de10nano-MiSTer.patch's rtc_at_51/68/6F
child nodes), so every boot logs a dev_err "controller timed out" from
the bit-banged i2c-designware-master.c bus scan. Downgrade it to
dev_dbg -- cosmetic, silences boot spam with no add-on board fitted.

Provenance
----------
Origin:       71c5830
              "Disable RTC error messages." (i2c-designware-master.c half
              only -- the accompanying rtc-m41t80.c hunk is upstream via
              c7622a4e44d9 "rtc: m41t80: reduce verbosity", 2025-05-26,
              and is not carried here.)
              MiSTer-devel/Linux-Kernel_MiSTer, 2018-01-09, against v5.15.
              MiSTer-devel@71c5830
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No, i2c-designware-master.c half only (verified: the
              "controller timed out" dev_err is still present at its new
              call site, see below). Disposition "carry"
              (docs/patch-provenance.md class F-5).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              i2c_dw_xfer() was refactored upstream into a small
              i2c_dw_wait_transfer() helper plus a caller that checks its
              return value; the same dev_err -> dev_dbg change is applied
              at the new call site (i2c_dw_xfer(), around the
              i2c_dw_wait_transfer() call), preserving the original's
              intent exactly.

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
usbhid's `jspoll` module parameter (override the USB interrupt
polling interval) only matched HID_GD_JOYSTICK in usbhid_start()'s
application-collection switch. Devices whose top-level usage is
HID_GD_GAMEPAD instead (increasingly common) were silently left at
their hardware-default interval. Add HID_GD_GAMEPAD to the same case.

Provenance
----------
Origin:       f0982bf
              "usbhid: apply jspoll for gamepad usage as well."
              MiSTer-devel/Linux-Kernel_MiSTer, 2019-11-20, against v5.15.
              MiSTer-devel@f0982bf
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No (verified: drivers/hid/usbhid/hid-core.c's usbhid_start()
              switch still has only `case HID_GD_JOYSTICK:` for
              hid_jspoll_interval). Disposition "carry"
              (docs/patch-provenance.md class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Dropped the fork's 3 added pr_info() debug lines (would
              print on every single HID endpoint of every USB HID device
              at every attach -- unconditional dmesg spam unrelated to
              the actual fix); kept the functional
              `case HID_GD_GAMEPAD:` fallthrough addition.

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
…B to mousedev itself

Main_MiSTer reads a USB mouse through *two* nodes at once: it opens
/dev/input/eventN (evdev) for identification and button/axis events, and
/dev/input/mouseN (mousedev) for the actual pointer data -- it switches
the mouse into ImPS/2 mode and parses the 4-byte PS/2 packets
(Main_MiSTer input.cpp:5177 opens every "event*" *and* "mouse*" node;
:5237 writes the ImPS/2 magic sequence; :6144 reads the 4-byte packets).
Whenever a core is running or the OSD is up it also grabs every fd in
that pool for exclusive use -- including the evdev node of the very mouse
whose mousedev node it is reading (input.cpp:6463, input_switch(), and
:5528 on hotplug).

Those two facts are in direct conflict on a stock kernel, and that is what
this patch resolves. Two independent changes:

1. drivers/input/input.c + include/linux/input.h -- THE LOAD-BEARING HALF.

   input_pass_values() short-circuits on dev->grab: when a handle holds an
   exclusive grab (only evdev ever takes one -- input_grab_device() has no
   other caller in the tree), the event batch is delivered to that handle
   *and to nobody else*. Every other handle attached to the device --
   mousedev, joydev, sysrq -- is starved for the duration of the grab.

   So on an unpatched kernel, the moment Main_MiSTer issues
   EVIOCGRAB on the mouse's evdev node, /dev/input/mouseN goes silent, and
   with it the pointer in *every* core. The mouse works in the file browser
   (not grabbed) and dies the moment you launch something. This is not a
   peripheral quirk; it affects every MiSTer user who plugs in a mouse.

   The fix: a new opt-in flag on struct input_handler, ->ignore_grab.
   input_pass_values() still delivers to the grabbing handle first, and
   then makes a second pass over the device's open handles delivering the
   same batch to any handler that set the flag. mousedev sets it; nothing
   else does. Semantics are deliberately narrow:
     - exempt handlers see the batch *after* the grabbing handle has seen
       it (an evdev grab still wins, and a filter that ate an event still
       hides it);
     - their return value is discarded -- an exempt handler observes the
       stream, it does not get to shorten it for the autorepeat pass;
     - an unopened exempt handle is skipped, as before;
     - with no grab in force, nothing changes at all: the flag is only
       read on the dev->grab path.

   The original does this by string-matching handle->name against "mouse"
   inside the input core. That works only because mousedev happens to name
   its handles "mouse%d", couples the core to a naming convention, and puts
   a strncmp() in the event hot path. The flag says the same thing exactly
   (mousedev is the only handler with handles named mouse*), says it where
   the policy belongs -- in the handler that wants the exemption -- and
   costs a byte and a predictable branch.

2. drivers/input/mousedev.c -- EVIOCGRAB support on mousedev itself.

   Main_MiSTer issues EVIOCGRAB on *every* descriptor in its pool, mouseN
   nodes included. mousedev has no ->unlocked_ioctl at all in mainline, so
   that ioctl returns -ENOTTY; Main_MiSTer ignores the error, and the
   result is that the mouse node is not actually exclusive. This half gives
   mousedev the same grab semantics evdev has, at the mousedev-client level:

     ioctl(fd, EVIOCGRAB, 1) -> this client becomes the sole recipient of
                               packets from that mousedev; -EBUSY if
                               another client already holds the grab.
     ioctl(fd, EVIOCGRAB, 0) -> release; -EINVAL if this client is not the
                               holder.

   A grab is per-mousedev, not global: grabbing /dev/input/mouse0 does not
   silence /dev/input/mice, because mousedev_event() feeds the mixdev
   through a separate mousedev_notify_readers() call. The grab is dropped
   automatically on close (mousedev_release()), so a crashed client cannot
   wedge the node. Any other ioctl returns -ENOTTY, exactly as before this
   patch -- the original returned -EINVAL for unknown commands, which would
   have been a gratuitous ABI change for anything that probes the node.

   Implementation mirrors evdev's grab/ungrab verbatim (RCU-protected
   ->grab pointer, mutex-serialised, synchronize_rcu() on release);
   mousedev_notify_readers() is split so the per-client body can be reused
   for the single grabbed client and for the client-list walk.
   ->compat_ioctl is wired to the native handler because EVIOCGRAB's
   argument is a truth value, not a pointer, so no compat_ptr() translation
   is needed. (CONFIG_COMPAT is off on 32-bit ARM, so this path is not
   compiled for the DE10-Nano; it is kept correct for other arches.)

3. drivers/input/mousedev.c -- tap-to-click suppression for DS4/DualSense.

   mousedev's touchpad emulation synthesises a left-click when a touch is
   released inside tap_time. A DualShock 4 / DualSense touchpad is used as
   a plain pointing device on MiSTer (Main_MiSTer QUIRK_DS4TOUCH reads it
   through the same mouseN node), where that synthetic click is a misfire:
   every time you lift a finger you get a spurious button-1 press. Suppress
   it for the four Sony controller IDs the original names, via a per-device
   dis_t2c flag set at mousedev_create() time.

   Known gap, carried deliberately: the DualSense Edge (054c:0df2) is *not*
   in the list, because it is not in the original either (it postdates it).
   An Edge used as a touchpad-mouse will still tap-to-click. Fixing that is
   a one-line table addition, but it is a behaviour change relative to
   stock MiSTer, not a forward-port, so it is left out of this patch.

Provenance
----------
Origin:       2ac0aa1
              "input: support for mouseX and mice in EVIOCGRAB mode."
              MiSTer-devel/Linux-Kernel_MiSTer, 2019-05-26.
              MiSTer-devel@2ac0aa1
              52a56ae
              "mousedev: disable touch to click on DualShock4 and DualSense."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-08-20.
              MiSTer-devel@52a56ae
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No, and not plausibly upstreamable as-is. Verified against
              6.18.38: input_pass_values() (drivers/input/input.c:111)
              still delivers to dev->grab exclusively, and mousedev's
              file_operations (drivers/input/mousedev.c:773) still has no
              ->unlocked_ioctl. Mainline's position is that a process which
              grabs a device gets it all; an application wanting both evdev
              and mousedev views of one mouse is a MiSTer-specific shape.
              Disposition "carry" (docs/patch-provenance.md class D,
              constraint A12).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9
              (escalated to [OPUS] per TASKS.md P1.9: core input subsystem,
              not a HID quirk).
              * input_to_handler() no longer exists. Upstream commit
                d469647bafd9 ("Input: simplify event handling logic",
                Dmitry Torokhov, 2024-07-03, v6.11) replaced it with a
                per-handle ->handle_events() method, bound once at
                registration by input_handle_setup_event_handler()
                (drivers/input/input.c:2583) to one of
                input_handle_events_{default,filter,null} or the handler's
                own ->events; 071b24b54d2d (v6.12) then fixed where that
                binding happens. And 21d8dd0daf4c ("Input: use guard
                notation in input core", 2024-11-06, v6.14) turned the RCU
                read section into a scoped_guard(rcu) block, so the grab
                fast path now exits with `break`, not an explicit
                rcu_read_unlock() + return. Both hunks were rewritten
                against that structure; the 5.15 diff does not apply in
                any form.
              * struct input_handler already has an unrelated field named
                ->passive_observer (do not power the device up just for
                this handler); the new flag is ->ignore_grab to avoid any
                confusion with it.
              * mousedev.c itself is structurally unchanged since 5.15, so
                the mousedev hunks are near-mechanical -- but the ioctl,
                the -ENOTTY default, and the RCU annotations were rewritten
                to evdev's idiom (rcu_dereference_protected() with an
                explicit lockdep_is_held() rather than a bare __rcu
                dereference).

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
mt76x2u_device_table[] claims 045e:02e6 and 045e:02fe (the Xbox
One Wireless Adapter's Wi-Fi-radio-alike USB IDs, from an early silicon
run that shared IDs with a MediaTek Wi-Fi chipset). Left in place, mt76
wins the driver-matching race against xone (package/xone), which is
the driver that actually understands the adapter's Xbox GIP wireless
protocol. Remove both entries so xone can bind.

Provenance
----------
Origin:       817ace7
              "Remove XBox One Wireless Adapter USB IDs from mt76 driver
              to allow 'xow' driver compatibility."
              MiSTer-devel/Linux-Kernel_MiSTer, 2020-10-21, against v5.15.
              MiSTer-devel@817ace7
Author:       sofakng <jklimek@gmail.com>
Upstream:     No (verified: drivers/net/wireless/mediatek/mt76/mt76x2/
              usb.c still claims 0x045e,0x02e6 and 0x045e,0x02fe).
              Disposition "carry" (docs/patch-provenance.md class D/E).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Byte-identical removal; replaced the deleted lines with an
              explanatory comment (the original left none) so a future
              mt76 sync doesn't silently reintroduce them.

Signed-off-by: sofakng <jklimek@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
Replaces vanilla's five auto-assigned ":white:player-N" LED classdevs on
the DualSense with stock MiSTer's single writable "<hid-dev>:player_id"
LED (brightness 0-6; 0 = off, 6 = stock's player-6 pattern BIT(4)|BIT(0)).
Main_MiSTer was co-designed against this interface: get_led_path()/
update_num_hw() (input.cpp:2642-2726) write the player slot to exactly
this node; on vanilla the write fails silently and player indication
falls back to the DS4 lightbar-color path. The IDA player-id allocation
is kept (shared with DualShock 4 teardown), but no LED pattern is
auto-lit at connect -- userspace owns the row, as on stock.

Provenance
----------
Origin:       f845439
              "dualsense: add player id led control."
              plus b76b4bc
              "dualsense: leds config for player 6." (folded: the 7-entry
              pattern table and the >6 clamp are its content)
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-07-10, against v5.15.
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No. Vanilla 6.18.38 exposes five separate per-player LEDs
              (8c0ab553b072) auto-assigned from IDA connect order; the
              single writable player_id classdev does not exist upstream.
              patch-provenance.md:337's Class-C "drop" for these commits
              was a misclassification (docs/kernel-recon, sonnet-verified).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-15, kernel patch
              reconciliation carry decision MiSTer-devel#2. Re-implemented on 6.18's
              ps_device framework: dualsense_set_player_leds() takes the
              player id as a parameter, the five ps_led_register calls and
              their brightness handlers are removed, ps_device_set_player_id
              is retained for teardown symmetry with DS4. The shared-state
              writes in dualsense_set_player_leds() take ds->base.lock
              (scoped_guard, matching the handler this patch removes):
              unlike vanilla's probe-time-only caller, the setter is now
              reachable from sysfs at runtime and races the output worker
              (ultrareview finding, 2026-07-15).
Barrot 8041a02-based fake CSR dongles self-report a consistent
manufacturer/hci_rev/lmp_subver of 0x2512 -- above every legitimate CSR
build number -- so they pass vanilla's consistency check and exceed every
ranged lmp_subver check (top tier 0x22bb), escaping all six is_fake
branches and missing the clone quirks entirely (broken stored link keys,
broken err-data-reporting, suspend workarounds). Adds an exact-match
branch at the end of the chain. Stock has shipped this detection since
2021; upstream still patches around the same clone family by other means
(2c1dda2acc41, 2024).

Provenance
----------
Origin:       b02a4a0
              "btusb: support for more CSR clones."
              (partial: the 0x2512 detection half; the fork's Barrot
              pm_runtime-workaround narrowing is superseded by 6.18's own
              reworked CSR handling)
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-08-19, against v5.15.
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No. Verified structurally absent from v6.18.38
              btusb_setup_csr (git grep/log -S 0x2512 empty over the file's
              history; docs/kernel-recon record, sonnet-verified,
              confidence medium pending clone-hardware test).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-15, kernel patch
              reconciliation carry decision MiSTer-devel#3 (match stock behavior).
Vanilla handles the DualSense mic-mute button entirely in-kernel: a
press toggles the hardware microphone and mute LED, invisible to
userspace. Stock MiSTer instead reports the button as BTN_Z -- giving
the controller one extra mappable input -- and exposes the mute LED as
a writable "<hid-dev>:mute" LED class device so userspace owns it. The
in-kernel toggle is removed (nothing on MiSTer records from the
controller microphone).

Provenance
----------
Origin:       60e0895
              "dualsense: give mute button and led to system."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-07-10, against v5.15.
              MiSTer-devel@60e0895
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No. v6.18.38 still toggles the mic in-kernel
              (hid-playstation.c: last_btn_mic_state) with no BTN_Z and no
              writable mute LED. patch-provenance.md's original Class-C
              "drop" grouping for this commit was the canary
              misclassification that motivated the full reconciliation
              (docs/kernel-recon, sonnet-verified).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-15, kernel patch
              reconciliation carry decision. BTN_Z capability is declared
              per-device via input_set_capability() instead of editing the
              ps_gamepad_buttons[] table, which 6.18 shares with
              DualShock 4 (the fork's 5.15 table was DualSense-only).
              Mute-LED handler uses 6.18's scoped_guard locking and
              dualsense_schedule_work().
MiSTer's framebuffer. A platform driver bound to the DT node
`compatible = "MiSTer_fb"` (reg = <0x22000000 0x800000>, IRQ 40) — the
window the FPGA "frame reader" scans out. The driver memremap()s that
window, publishes it as /dev/fb0 (pixels at fb_res->start + 4096; the
first 4 KiB hold the pseudo-palette), and turns the FPGA's per-frame
interrupt into FBIO_WAITFORVSYNC.

Provenance
----------
Origin:       d1002ec
              "Implement MiSTer frame buffer device."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-08-20, against v5.15.
              MiSTer-devel@d1002ec
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No, and never submitted. MiSTer-specific — a soft-IP frame
              reader in DE10-Nano FPGA fabric; mainline has no equivalent
              and would not take this as-is. Disposition "carry"
              (docs/patch-provenance.md §3.1, §5).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.4.
              The origin commit also touched
              arch/arm/boot/dts/socfpga_cyclone5_de10_nano.dts; that hunk
              belongs to 0004-dts-de10nano-MiSTer.patch (P1.7), not here.

ABI — unchanged by this forward-port (docs/abi-contract.md §4)
--------------------------------------------------------------
  * /dev/fb0, a standard fbdev node.
  * Exactly one ioctl: FBIO_WAITFORVSYNC = _IOW('F', 0x20, __u32) =
    0x40044620. That is *mainline* UAPI (include/uapi/linux/fb.h), byte
    identical in 5.15 and 6.18, and architecture-independent (fixed-width
    __u32 argument). *arg must be 0, else -ENODEV; any other cmd is -ENOTTY;
    a vsync that does not arrive within VSYNC_TIMEOUT_MSEC (50 ms) is
    -ETIMEDOUT. There is no custom ioctl and therefore no ioctl drift.
  * /sys/module/MiSTer_fb/parameters/mode — mode 0664, RW, module_param_cb.
    Five unsigned ints, "format rb width height stride". Writing it wipes
    the window, reconfigures fb_info and bumps res_count. This — not the
    ioctl — is the real custom ABI; Main_MiSTer writes it with a plain
    shell redirect, so it must stay a genuine sysfs attribute.
  * /sys/module/MiSTer_fb/parameters/{width,height,stride,format,rb,
    frame_count,res_count} — mode 0444, RO.
Not one line below touches any of that.

6.18 API churn (everything not listed here is the 5.15 file verbatim)
---------------------------------------------------------------------
Required — the 5.15 file does not build on 6.18 without these:

 1. fb_read/fb_write/fb_mmap are no longer implicit. Until v6.7 the fbdev
    core supplied them whenever a driver left the callbacks NULL — the
    fallback used the __iomem accessors and vm_iomap_memory() on
    fix.smem_start. v6.8 commit 8813e86f6d82 ("fbdev: Remove default
    file-I/O implementations") deleted that fallback; a driver with no
    .fb_mmap now gets a WARN and -ENODEV out of fb_mmap().
    Resolved with __FB_DEFAULT_IOMEM_OPS_RDWR and __FB_DEFAULT_IOMEM_OPS_MMAP
    (fb_io_read / fb_io_write / fb_io_mmap), which is precisely what the old
    core fallback did — so behaviour is preserved, not invented.
    It has to be the *iomem* variants: this window is FPGA memory above the
    `mem=511M` line, has no struct pages, and can only be mapped by
    vm_iomap_memory() on the physical fix.smem_start. (6.18 offers no sysmem
    mmap helper at all — only __FB_DEFAULT_SYSMEM_OPS_{RDWR,DRAW}.)
    The *drawing* ops stay on sys_fillrect/sys_copyarea/sys_imageblit exactly
    as in 5.15: memremap(MEMREMAP_WT) returns a normal-memory mapping, so the
    direct-deref helpers are correct there. Only fbcon consumes any of this;
    Main_MiSTer never mmap()s /dev/fb0 (docs/abi-contract.md §4.1).
 2. `info->flags = FBINFO_FLAG_DEFAULT;` dropped: FBINFO_DEFAULT /
    FBINFO_FLAG_DEFAULT were removed in v6.6 by commit 0444fa357c16
    ("fbdev: Remove FBINFO_DEFAULT and FBINFO_FLAG_DEFAULT"). The macro
    expanded to 0 and this fb_info is embedded in a devm_kzalloc()'d struct,
    so deleting the store is a no-op — info->flags is still 0.
 3. platform_driver::remove() returns void since v6.11, commit 0edb555a65d1
    ("platform: Make platform_driver::remove() return void"). fb_remove()
    changed from int to void; it only ever returned 0.
 4. `void fb_set()` -> `static void fb_set()`. -Wmissing-prototypes has been
    on in the default build since v6.8, commit 0fcb70851fbf
    ("Makefile.extrawarn: turn on missing-prototypes globally"), and this is
    the one warning the 5.15 file still produces on 6.18. fb_set() is
    file-local and was never meant to be a vmlinux-global symbol.
 5. Kconfig: FB_SYS_{FILLRECT,COPYAREA,IMAGEBLIT} all still exist in 6.18 and
    are kept, *plus* FB_IOMEM_FOPS for the fops in (1). Deliberately not the
    aggregate FB_SYSMEM_HELPERS that docs/kernel-config-deltas.md §4.1
    suggested: that selects FB_SYSMEM_FOPS (fb_sys_read/fb_sys_write) and
    still leaves the driver with no mmap. Also `depends on OF` — it is a
    DT-only driver.

Not required, done anyway (both are pure hardening, zero behavioural change):

 6. `struct fb_ops ops` -> `const struct fb_ops ops`, and the of_device_id
    table made const. NOTE: docs/patch-provenance.md §5 lists the fb_ops
    const-ness as a *hazard* ("will not compile"). It is not one.
    fb_info::fbops has been `const struct fb_ops *` since v5.6 (bf9e25ec1287),
    i.e. already in 5.15; assigning a non-const object to it was legal then
    and is legal now. Constified because the data is read-only, not because
    the compiler demanded it.

 7. Two error-path fixes, neither reachable with a correctly-described DT node,
    neither touching the ABI:
      - memremap() returns NULL on failure, not an ERR_PTR. The 5.15 code
        tested IS_ERR(), which is false for NULL, so a failed mapping fell
        straight through to screen_base = 0x1000 and oopsed on the first fbcon
        draw. Test for NULL, return -ENOMEM.
      - the accompanying dev_err() names devm_ioremap_resource(), a function
        this driver does not call. Say memremap.

CONFIG_FB_MISTER=y goes into board/mister/de10nano/linux.config in the same
commit — P1.3 deferred the symbol to this task (docs/kernel-config-deltas.md
§4.1) because kconfig would have discarded it before the driver existed.
CONFIG_FB_DEVICE=y (a new 6.x symbol) is what creates /dev/fb0 and must not
drift off.

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
The MiSTer audio path is two kernel-side pieces that only work together.

1. sound/drivers/MiSTer-audio-spi.c -- an SPI driver, and NOT an ALSA driver:
   no card, no PCM, no substream.  It creates the /dev/MrAudio character
   device.  write()s of raw PCM are copied into a 512 KiB dma_alloc_coherent()
   ring (~2.6 s of audio) and a 16-byte {addr,len,ptr,reserved} descriptor is
   spi_write()n to the FPGA, which plays it.  The write length is truncated to
   a multiple of 4 ("userBufLen & ~3"), i.e. to whole S16_LE *stereo* frames.

2. sound/drivers/dummy.c -- two edits, and they are load-bearing.

   MiSTer's /etc/asound.conf makes the ALSA default PCM:

       plug -> rate(format S16_LE, rate 48000) -> file("/dev/MrAudio") -> hw:0

   ALSA's "file" plugin *tees*: it writes the raw PCM to /dev/MrAudio and also
   passes it to its slave, hw:0.  Card 0 is snd-dummy, acting as the sink that
   ALSA needs in order to have a real device to hang timing off.

   Note what asound.conf pins and what it does not: it pins the *format* and
   the *rate*, but it says nothing about the *channel count*.  Channels are
   negotiated against hw:0.  Stock snd-dummy advertises channels 1..2, so a
   mono client would negotiate 1ch the whole way down and tee MONO into
   /dev/MrAudio -- which the driver above feeds to the FPGA as 4-byte stereo
   frames.  So snd-dummy is given a "MiSTer" model (S16_LE, 48 kHz, 2 ch,
   32 KiB buffer) and it is force-selected as the default, which pins the chain
   to stereo and makes the top-level "plug" convert everything into it.
   /dev/MrAudio therefore always sees exactly S16_LE / 48000 / 2ch.

   fake_buffer is also defaulted to 0, as stock ships it, so that the card
   presents a real (if discarded) ring buffer rather than ops_no_buf's single
   shared page.

   *** Omit the dummy.c hunks and audio is wrong or silent, even though
   /dev/MrAudio itself is perfectly healthy.  They ship together. ***

Origin:          https://github.com/MiSTer-devel/Linux-Kernel_MiSTer
                 commit 333d49b
                 ("Implement MiSTer audio driver."), branch MiSTer-v5.15
Original author: Sorgelig <pour.garbage@gmail.com>
Upstream status: Not upstream, and not upstreamable as-is (a hardware-specific
                 chrdev with no ALSA PCM; the dummy.c hunks change a generic
                 driver's defaults for one board).  Carried indefinitely.
ABI contract:    docs/abi-contract.md A12 / section 8 -- /dev/MrAudio, the
                 patched snd-dummy as card 0, and the verbatim /etc/asound.conf.
Rebased-from:    v5.15.1 to v6.18.38 by Michael C. Ferguson (task P1.5).

Forward-port notes (5.15 -> 6.18).  Behaviour-preserving; no userland-visible
change.  See docs/patch-provenance.md section 5 for the full write-up.

  * class_create() lost its leading "struct module *" argument in v6.4-rc1:
    1aaba11da9aa ("driver core: class: remove module * from class_create()").
  * struct spi_driver::remove became void in v5.18-rc1:
    a0386bba7093 ("spi: make remove callback a void function"), Uwe Kleine-Koenig.
    (This is an SPI driver, so v6.11's platform_driver::remove change does not
    apply to it.)
  * class_create() and device_create() return ERR_PTR() on failure, never NULL.
    The 5.15 code tested "== NULL", so both error paths were dead code and a
    failed device_create() was treated as success.  Both now use IS_ERR().
    The success path is bit-for-bit unchanged.
  * "major" is now dev_t rather than int -- it always held a dev_t, since
    alloc_chrdev_region() writes MKDEV(major, 0) into it.  ARM_LPAE is off on
    Cyclone V, so dev_t and dma_addr_t are both u32 and every printk format
    (and the value printed) is unchanged.
  * cleanup() resets major/myclass, so a re-probe after a failed probe does not
    act on stale values.
  * Kconfig gained "depends on SPI" (the driver cannot link without it) and
    kernel-standard tab indentation.  The symbol CONFIG_SND_MISTER_AUDIO and
    its "default n" are unchanged.
  * dummy.c's model_MiSTer is const, like every other model in the file
    (struct snd_dummy::model is already a const pointer).  5.15's was non-const.

Everything that is ABI is carried verbatim: DRIVER_NAME "MrAudio", the
"MrAudio_proc" chrdev region, the "MrAudio_sys" class, the dynamic major, the
512 KiB ring, the 4-byte write alignment, the "> BUFFER_LEN => -EFAULT" rule,
the Info_t descriptor, and the read() status string.

NOT included here, on purpose: the fork's 13-line socfpga_cyclone5_de10_nano.dts
hunk adding &spi0/spiusb (compatible = "MiSTer,spi-audio", spi-cpha, spi-cpol,
spi-max-frequency = <10000000>).  Without an SPI device that matches, this
driver never probes and /dev/MrAudio never appears.  The DTS is authored from
scratch against mainline in task P1.7 (0004-dts-de10nano-MiSTer.patch), which
owns that node.

BUG FIX (behaviour change vs. the 5.15 original -- bogus diagnostics on SPI
failure):

  device_open() computed the reported ring-buffer `len` even when spi_read()
  had failed, producing a nonsense value exactly when SPI was broken -- i.e.
  precisely when someone is reading this diagnostic to find out why.

  On failure rptr stays -1. `-1 >> 8` is still -1 (arithmetic shift), so the
  `rptr >= 0` guard is skipped; but the `(unsigned int)rptr` cast in the len
  expression then compares it as 0xffffffff, so `MrBufferInfo.ptr < (unsigned)
  rptr` is ALWAYS true and the ring-wraparound branch is always taken:

      len = MrBufferInfo.ptr + MrBufferInfo.len - (-1)
          = ptr + len + 1

  i.e. a reported "length" larger than the entire ring buffer.

  There is NO memory-safety issue: msg[] is 1024 bytes and that format cannot
  overflow it. Nothing in userland parses the string either -- /etc/asound.conf
  only *writes* to /dev/MrAudio (type file), and Main_MiSTer contains no ALSA
  code at all -- so the text is free to change. device_open() now reports the
  SPI failure explicitly instead of inventing a number. The wptr conversion is
  also corrected to %u (MrBufferInfo.ptr is unsigned int, printed with %d).

  Reported by static review on PR MiSTer-devel#2. PRE-EXISTING in the MiSTer fork, not a
  forward-porting regression -- present verbatim in the 5.15 source
  (sound/drivers/MiSTer-audio-spi.c, device_open()).

Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
mmc_start_request() unconditionally flashes host->led on every
command, including MMC_SEND_STATUS polls the core issues continuously
while idle-polling card presence/state. On the DE10-Nano this drives
hps_led0 (the on-screen SD activity indicator, see 0029), so the LED
never settles -- it flickers even when nothing is actually being
read or written. Skip the trigger for MMC_SEND_STATUS specifically.

Provenance
----------
Origin:       2d39e76
              "mmc: don't activate LED on status command."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-08-26, against v5.15.
              MiSTer-devel@2d39e76
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No (verified: drivers/mmc/core/core.c has no
              MMC_SEND_STATUS check around the led_trigger_event() call).
              Disposition "carry" (docs/patch-provenance.md class F-1).
              Renumbered from PLAN §6's original 0020 slot, which was the
              usb-storage Realtek CD-ROM blacklist -- see report/
              patch-provenance.md: that hunk is dropped, already upstream
              via a3dc32c635ba.
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Reformatted the fork's single-line
              `if (...) led_trigger_event(...)` to kernel multi-line
              style; otherwise unchanged (context around the call site
              picked up an unrelated uhs2_sd_tran hunk upstream, but the
              call site itself is byte-identical to 5.15).

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
Vanilla 6.18's nescon table maps A->BTN_SOUTH/B->BTN_EAST; stock MiSTer
maps A->BTN_EAST/B->BTN_SOUTH (the same assignment vanilla itself uses
for snescon). User .map files created on stock kernels encode the stock
codes, so keeping vanilla's assignment silently breaks existing NES/
Famicom mappings. Swaps A/B in nescon_button_mappings and
famicom_r_button_mappings (patch 0015) to the stock assignment.

Provenance
----------
Origin:       e155f6a
              "hid-nintendo: support for Switch NES and SNES controllers."
              (partial: only the A/B assignment; the controllers themselves
              are supported upstream via 94f18bb19945)
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-09-04, against v5.15.
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     Divergent. Upstream supports NES/SNES controllers but with
              A/B swapped relative to stock on the NES pads (SNES already
              matches). Verified byte-for-byte in docs/kernel-recon
              records (sonnet-verified, corroborates patch-provenance §9.2).
Forward-port: 6.18.38 mapping-table edit, Michael C. Ferguson, 2026-07-15,
              kernel patch reconciliation carry decision MiSTer-devel#5. Also aligns
              the Famicom tables introduced by 0015 with stock.
Vanilla 6.18 tolerates a failing home-LED *set* (returns 0) but still
fails the whole probe if home-LED classdev *registration* fails
(hid-nintendo.c:2319-2323), leaving Pro-Controller-compatible clones
without home-LED support completely dead. Stock MiSTer tolerates both.
Only Pro Controller and right Joy-Con reach this branch
(jc_type_has_right()).

Provenance
----------
Origin:       6082105
              "hid-nintendo: don't fail if home led is not present."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-08-12, against v5.15.
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     Partial. 8b30fb40f8f2 + 928276075f16 made the set-failure
              path non-fatal upstream; the registration-failure path is
              still fatal in v6.18.38 (docs/kernel-recon, sonnet-verified:
              equivalence "partial", provenance row 334 misclassified).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-15, kernel patch
              reconciliation carry decision MiSTer-devel#5 (clone-hardware tolerance).
Routes the ControllaBLE Bluetooth gamepad (a Twin-USB-Joystick-
protocol clone, VID:PID 1209:FACA -- a pid.codes shared/test ID) through
hid-pl.c's existing PANTHERLORD dual-PSX-adapter quirk instead of
falling back to generic HID-input mapping.

Provenance
----------
Origin:       5bdbf2f
              "hid: add quirk for ControllaBLE."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-09-08, against v5.15.
              MiSTer-devel@5bdbf2f
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No (verified: no 0x1209/0xFACA entry in hid-pl.c or
              hid-quirks.c). Disposition "carry" (docs/patch-provenance.md
              class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Compiles unmodified. Fixed a copy-paste artifact in the
              original: the new hid-pl.c device-table entry carried the
              comment "/* Twin USB Joystick */" left over from the
              adjacent GAMERON entry; changed to "/* ControllaBLE */".

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
K400r/K400 Plus keyboards ship with "Fn Lock" (aka FEATURE_NEW_FN_
INVERSION, HID++ feature 0x40A2) enabled by default, swapping media
keys and F-keys. Main_MiSTer's UI expects bare media keys. Sends a
HID++ SetFeature(0x10, enable=0) against that feature once, on every
connect event, disabling the swap.

Provenance
----------
Origin:       fc8f3c2
              "Logitech K400r: disable Fn swap."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-08-19, against v5.15.
              MiSTer-devel@fc8f3c2
              + b745ce6
                "fix Logitech K400 Plus FN problem (MiSTer-devel#15)", HGD73,
                2021-12-24 (folded in: K400 Plus device-table entry).
Author:       Sorgelig <pour.garbage@gmail.com>; HGD73.
Upstream:     No. Disposition "carry" (docs/patch-provenance.md class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
                - hidpp_root_get_feature() dropped its `feature_type`
                  output parameter upstream (3 args now, was 4); the new
                  k400_enable_fn() helper is written against the current
                  signature.
                - k400_connect() lost its `bool connected` parameter
                  upstream (hidpp_connect_event() now calls it with just
                  `hdev`); the Fn-disable call is added to the 1-arg form.
                - Fixed a latent bug in the fork's own patch: it reused
                  k400->feature_index (k400_disable_tap_to_click()'s
                  cache for the HIDPP_PAGE_TOUCHPAD_FW_ITEMS feature) to
                  also cache the unrelated FEATURE_NEW_FN_INVERSION
                  index. Since k400_connect() calls the Fn-disable helper
                  first, tap-to-click's own lookup would see a non-zero
                  cached index left behind by the Fn lookup and skip
                  resolving its own feature, sending the tap-to-click
                  SetFeature at the wrong feature index. Added a
                  dedicated `fn_feature_index` field instead of sharing.

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
Adds the `loop=` boot parameter: the in-kernel half of MiSTer's boot, and
the reason a MiSTer SD card can be a single plain exFAT partition that the
user manages from a PC with no Linux tooling at all.

    root=/dev/mmcblk0p1 loop=linux/linux.img

With `loop=` set, mount_block_root() no longer mounts root= as the root
filesystem. Instead it mounts root= as exFAT on /root2, creates /dev/loop8,
attaches /root2/<loop=path> to it, mounts /dev/loop8 as the real root, and
bind-mounts /root2 onto /root/media/fat -- so the card the system was booted
from stays visible at the path everything in MiSTer userspace expects. With
`loop=` unset not a line of it runs and mount_block_root() behaves exactly as
before. MS_NOATIME|MS_NODIRATIME also join the default root_mountflags, for
every root and not just the looped one: the root device is an SD card, where
an atime update is a read-modify-write of an erase block whose result nothing
ever reads back.

Doing this in the kernel rather than in an initramfs is what keeps the
distribution a single file. There is no cpio to regenerate when the rootfs
image changes, no second copy of the kernel's view of the card, and no
userspace on the FAT partition to go stale: `losetup` is effectively
open-coded here because there is no userspace yet to run it.

Forward-port to 6.18 (from v5.15)
---------------------------------
The 5.15 version of this patch does not compile on 6.18 -- not because the
loop device changed, but because both halves of the code it hooked into were
rewritten. Each change below is a consequence of that, not a redesign; the
boot-time behaviour above is the 5.15 behaviour.

 1. sys_ioctl() and sys_close() are gone from init code, and this patch was
    built on them. Init-time filesystem work now goes through the explicit
    helpers in fs/init.c, declared in <linux/init_syscalls.h>: init_mount(),
    init_mkdir(), init_umount() and so on. There is no init_ioctl() in that
    list -- an ioctl is driver-defined, so there is nothing generic to wrap.
    vfs_ioctl() is static to fs/ioctl.c, and do_vfs_ioctl() carries a comment
    there saying it is "not for drivers and not intended to be
    EXPORT_SYMBOL()'d".

    So the ioctl is not faked from init/. The loop driver exports the
    operation instead, as loop_set_backing_fd(), whose body is exactly
    lo_ioctl()'s LOOP_SET_FD case -- a zeroed struct loop_config carrying only
    the backing descriptor, and BLK_OPEN_READ|BLK_OPEN_WRITE for the mode,
    which is what the O_RDWR open() in the 5.15 code produced. Not passing
    BLK_OPEN_EXCL keeps loop_configure() on its bd_prepare_to_claim() path,
    the same path an ioctl on a non-exclusive fd takes, so the claim semantics
    are not quietly different from the userspace route.

    The alternative -- reaching through file_bdev(f)->bd_disk->fops->ioctl()
    from init/ -- would skip blkdev_ioctl()'s checks and hard-code the loop
    driver's dispatch table into init/. It was rejected for that reason.

 2. The descriptor half stays in init/, because loop_configure() fget()s
    config.fd and there is no reasonable way around that short of splitting
    loop_configure() itself. 5.15's hand-rolled m_open() is therefore kept in
    substance -- get_unused_fd_flags() followed by fd_install() -- with its
    one bug fixed: it leaked the filp_open() reference whenever the descriptor
    allocation failed, so the fput() moves onto that error path. On the
    success path fd_install() consumes the reference and no fput() is owed.
    The corresponding sys_close() is now close_fd() from <linux/fdtable.h>.

    fs/init.c's init_dup() looks like the sanctioned helper for this and is
    not: despite the name it does not return a descriptor. It calls
    get_unused_fd_flags(), fd_install()s a reference of its own via get_file(),
    and returns 0. It was written for console_on_rootfs(), whose callers only
    check for failure. Building on it here would have bound fd 0 rather than
    the fd it allocated, and fd 0 at this point in the boot is /dev/console --
    console_on_rootfs() runs in kernel_init_freeable() before
    prepare_namespace() -- so loop_configure() would have fget()ed the console,
    loop_validate_file() would have rejected the character device with -EINVAL,
    loop8 would have stayed unbound, and mounting /dev/loop8 as root would have
    panicked on every boot. The close_fd(0) on the way out would additionally
    have closed init's console stdin while leaking the real descriptor.

 3. -Wmissing-prototypes is on globally in the default build (0fcb70851fbf,
    "Makefile.extrawarn: turn on missing-prototypes globally"), so the two
    exported functions need a prototype visible in loop.c or they warn. 6.18
    has nowhere to put one: there is no include/linux/loop.h, and there is no
    drivers/block/loop.h either -- the driver's private header was folded into
    loop.c, which reaches straight for <uapi/linux/loop.h>.

    So this restores include/linux/loop.h, as a two-declaration header, which
    also gives init/do_mounts.c the declarations it needs. It re-includes
    <uapi/linux/loop.h> so that it is a strict superset of the UAPI header it
    now shadows on the include path: LINUXINCLUDE searches include/ before
    include/uapi/, so a `#include <linux/loop.h>` that had been resolving to
    the UAPI header -- which is exactly how the 5.15 patch got LOOP_SET_FD
    into init/do_mounts.c -- would otherwise silently stop seeing the ioctl
    definitions. loop.c's own include is switched to <linux/loop.h>
    accordingly. (Nothing else in 6.18 includes <linux/loop.h>; the only hit
    in the tree is tools/include/nolibc, which does not use these paths.)

 4. init/do_mounts.c was refactored. The `#ifdef CONFIG_BLOCK` block inside
    mount_root() that the 5.15 patch edited is now the body of a separate
    mount_block_root(char *root_device_name), and mount_root() has become a
    switch over ROOT_DEV that dispatches to it. The hook therefore moves into
    mount_block_root(), which is the same code at the same point in the boot.
    5.15's mount_block_root(name, flags) -- the "mount this device as root,
    trying each filesystem" primitive -- is 6.18's
    mount_root_generic(name, pretty_name, flags); the two calls the patch made
    to it are translated accordingly.

    Relatedly, root_device_name is no longer a file-global in 6.18 but a
    parameter threaded down from prepare_namespace(). The bind-mount failure
    message that printed it still does, off the parameter -- but the literal
    "/dev/" that message prefixed it with in 5.15 is dropped, because what the
    parameter holds has changed. 5.15's prepare_namespace() advanced
    root_device_name past its "/dev/" prefix before use; 6.18's does not, and
    there is no such adjustment anywhere else in the file, so the name now
    arrives fully qualified. Keeping the literal would print
    "Failed to bind-mount /dev//dev/mmcblk0p1 ..." on the real MiSTer cmdline.

 5. The loop= body moves out of mount_block_root() into its own
    mount_loop_root(), for a reason that is not cosmetic: it has to be
    compiled out under CONFIG_BLK_DEV_LOOP=m. loop_set_backing_fd() and
    loop_max_part() are then in a module that cannot possibly be loaded before
    the root filesystem is mounted, and referencing them from always-built-in
    init/do_mounts.c would fail the vmlinux link of every =m configuration,
    allmodconfig included. (The 5.15 patch has this bug: it links only because
    MiSTer's own config sets CONFIG_BLK_DEV_LOOP=y.) The IS_BUILTIN() stub
    panics with the reason rather than falling back to mounting root= directly
    -- that would try to boot the exFAT data partition as the root filesystem,
    which fails several confusing steps later, or on some configurations
    "succeeds" with something that is not the system the user asked for.

 6. `sprintf(lname, "/root2/%s", loop_name)` into a `char lname[32]` is a stack
    buffer overflow for any loop= argument longer than 24 characters --
    reachable from the boot command line, which is bounded only by
    COMMAND_LINE_SIZE. It is now a kasprintf(); slab is up long before
    prepare_namespace() runs.

 7. Error paths return the actual errno (or PTR_ERR) instead of 1 and -1, and
    say which errno in the log. The messages' intent is unchanged. The 5.15
    error path also issued LOOP_CLR_FD after a failed LOOP_SET_FD; that is
    dropped because loop_configure() unwinds its own partial state and leaves
    lo_state == Lo_unbound, so there is nothing to clear.

 8. One dependency of the 5.15 code survives but is now on notice, and the
    port makes that explicit rather than inheriting it silently. /dev/loop8 is
    one past CONFIG_BLK_DEV_LOOP_MIN_COUNT's default of 8 devices, so the
    driver has not created it and the filp_open() of the node is what brings
    it into existence: blkdev_get_no_open() finds no inode, calls
    blk_request_module(), and that reaches the loop driver's loop_probe() via
    blk_probe_dev(). In 6.18 that fallthrough is conditional on
    CONFIG_BLOCK_LEGACY_AUTOLOAD, whose help text describes it as a historic
    feature and which pr_warn_ratelimited()s that it "will be removed". It is
    `default y` and is therefore y in MiSTer's build, and the boot works -- but
    when the symbol goes, loop= stops working, and the failure would otherwise
    surface as an unexplained -ENXIO. The open-failure path now names the
    symbol, so that day yields an actionable message instead of a puzzle.

The one thing that did NOT need changing, having been checked rather than
assumed: /dev/loop8's minor is still (max_part + 1) * 8, because loop_add()
still assigns disk->first_minor = i << part_shift with part_shift derived from
max_part. loop_max_part() is therefore the 5.15 patch's export carried over
verbatim.

Not applied to the Buildroot_MiSTer image
-----------------------------------------
Buildroot_MiSTer does not carry this patch in the kernel it ships. It boots
the same card layout through an initramfs /init that does the equivalent
mounts from userspace, where they can be debugged, and where a failure prints
something better than a pr_emerg() from prepare_namespace(). That is recorded
in docs/kernel-recon/reconciliation.md as carried-upstream-only: the commit is
carried, for the exported tree, and is deliberately not applied to the image
Buildroot builds. It is explicitly not a drop -- the functionality lives on in
the patch series below.

The patch lives in board/mister/de10nano/linux-patches-upstream/, a series
applied only when exporting the tree to Linux-Kernel_MiSTer -- never by
BR2_LINUX_KERNEL_PATCH -- so that the exported branch keeps upstream's boot
mechanism working for everyone building from it, while the image Buildroot
produces is byte-for-byte unaffected.

Provenance
----------
Origin:       3d95de5
              "Support for init loop device."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-11-08, against v5.15.
              MiSTer-devel@3d95de5
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No, and never submitted. Mounting a loop device from
              prepare_namespace() is MiSTer-specific policy that mainline
              expects an initramfs to implement; it would not be accepted.
              Carried indefinitely on the MiSTer branch.
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-18. Compile-tested
              only. On top of the carried MiSTer series, with MiSTer's board
              config (CONFIG_BLK_DEV_LOOP=y, CONFIG_EXFAT_FS=y,
              CONFIG_BLOCK_LEGACY_AUTOLOAD=y by Kconfig default) a full
              ARCH=arm vmlinux links warning-free and carries __ksymtab entries
              for both new symbols; init/do_mounts.o and drivers/block/loop.o
              also build warning-free with CONFIG_BLK_DEV_LOOP=m, which selects
              the panicking stub and leaves init/do_mounts.o with no reference
              to either export. It has NOT been booted on hardware from this
              tree, because Buildroot_MiSTer's own image does not apply it --
              see above.
Not shipped:  board/mister/de10nano/linux-patches-upstream/ (export-only
              series; docs/kernel-recon/reconciliation.md records commit
              3d95de5 as carried-upstream-only).

Not-in-image: Buildroot_MiSTer boots through an initramfs /init that performs these mounts from userspace, so the in-kernel loop= path would be unreachable code in the image it builds; every stock MiSTer boots through it, so the exported tree has to keep it working.
New driver, hid-guncon3.c. Another raw usb_driver, for the Namco
GunCon 3 IR gun controller (0b9a:0800). Talks a proprietary
challenge/response-keyed two-endpoint protocol (guncon3_decode()) to
extract aim (ABS_X/Y, negated for MiSTer's coordinate convention),
joystick axes, a d-pad (mapped to BTN_TRIGGER_HAPPY1-4 by default) and
9 buttons.

Provenance
----------
Origin:       8179ac7
              "Add driver for Namco Guncon 3 (MiSTer-devel#20)"
              MiSTer-devel/Linux-Kernel_MiSTer, 2022-03-05, against v5.15.
              MiSTer-devel@8179ac7
              + 9b9aebf
                "hid-guncon3: fix warnings.", Sorgelig, 2022-04-13 (folded in).
Author:       Nolan Nicholson <NolanNicholson@users.noreply.github.com>
Upstream:     No (verified against 6.18.38: no drivers/hid/hid-guncon3.c,
              no USB_PRODUCT_ID_NAMCO_GUNCON3). Disposition "carry"
              (docs/patch-provenance.md class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
                - usb_maxpacket() lost its 3rd (direction) argument
                  upstream; the two call sites in guncon3_init_output()/
                  guncon3_init_input() are updated to the 2-arg form.
                - sprintf(name, "guncon3") -> strscpy(); the debug printk
                  in usb_guncon3_probe() referenced an uninitialized
                  `path` buffer in the original -- removed, and the
                  return value of input_register_device() is now
                  actually checked (the original discarded it and always
                  returned 0).
                - printk(KERN_*) -> pr_*() for consistency; comment style.

Signed-off-by: Nolan Nicholson <NolanNicholson@users.noreply.github.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
New driver pair, hid-ftec.c (probe/sysfs/LEDs) + hid-ftecff.c
(memless force-feedback timer implementation), for Fanatec CSL
Elite/CSR Elite/ClubSport/Podium wheelbases and pedal sets. Ports the
long-running gotzl/hid-fanatecff out-of-tree project. hid-ftec.c
handles device identification, brake load-cell calibration and RPM
LEDs; hid-ftecff.c implements FF_CONSTANT/SPRING/DAMPER/PERIODIC via
an hrtimer-driven slot scheduler and per-model sysfs tuning knobs.

Provenance
----------
Origin:       e82a592
              "Add Fanatec wheel driver (MiSTer-devel#24)"
              MiSTer-devel/Linux-Kernel_MiSTer, 2022-04-17, against v5.15.
              MiSTer-devel@e82a592
              + 8908e0f
                "Fix module compile for Fanatec driver (MiSTer-devel#25)", Michael Huang,
                2022-04-19 (folded in: composite hid-fanatec.ko module).
              + ed8f8e6
                "Fix warning.", Sorgelig, 2023-03-13 (folded in).
Author:       Michael Huang <coolbho3k@users.noreply.github.com>;
              upstream project: gotzl/hid-fanatecff (never merged into
              mainline Linux).
Upstream:     No (verified against 6.18.38: no hid-ftec.c/hid-ftecff.c,
              no HID_FTEC). Disposition "carry" (docs/patch-provenance.md
              class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
                - hrtimer_init(&hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL)
                  followed by hrtimer.function = ftecff_timer_hires; is
                  gone upstream (hrtimer_setup() combines both steps,
                  v6.12). Replaced with a single hrtimer_setup() call.
                - -Wmissing-prototypes (default-on since v6.8, 0fcb70851fbf)
                  required: ftecff_send_cmd()/ftecff_update_slot() marked
                  static (only used within hid-ftecff.c); ftecff_init()/
                  ftecff_remove() (called from hid-ftec.c) now declared in
                  the shared hid-ftec.h instead of a local forward
                  declaration in hid-ftec.c, so hid-ftecff.c's own
                  definitions are visible to the compiler too.
                - Dropped two now-dead locals (unused `s1`/`s2` sign bits
                  in ftecff_update_slot(), a leftover from an incomplete
                  original implementation) and an unused `ret` in
                  ftec_tuning_write() -- all -Wunused-but-set-variable.

Signed-off-by: Michael Huang <coolbho3k@users.noreply.github.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
A cpufreq driver (.name = "socfpga") for the Intel/Altera Cyclone V SoC FPGA
that reprograms the main PLL VCO and the MPU / main / dbg-AT / cfg-s2f-user0
dividers together, giving 400 / 800 (stock) / 1000 / 1200 MHz.  The non-CPU
dividers are recomputed for every operating point so that mainclk and dbgatclk
stay at 400 MHz and cfgs2fuser0clk stays at 100 MHz regardless of the VCO --
everything else on the DE10-Nano hangs off the peripheral PLL and is unaffected.

The 1000/1200 MHz rows are flagged CPUFREQ_BOOST_FREQ so the core does not
select them on boot; overclocking stays opt-in.

  *** WHY THIS CANNOT BE cpufreq-dt + OPP TABLES ON 6.18 ***

  Checked against mainline v6.18.38 (see docs/patch-provenance.md section 5):

    - The gen5 socfpga clock driver is READ-ONLY.  Neither clk-pll.c,
      clk-periph.c, clk-gate.c nor clk.c implements a .set_rate op:
      clk_pll_ops and periclk_ops are { .recalc_rate } only, and gateclk_ops
      adds only .determine_rate/.get_parent/.set_parent.  clk_set_rate() on the
      MPU clock therefore cannot change the frequency -- which is precisely what
      cpufreq-dt requires.  socfpga_clk_determine_rate() even ignores the
      requested rate and returns best_parent_rate/div, i.e. the current rate.
    - The cpu@0/cpu@1 nodes in socfpga.dtsi have no "clocks" property, so
      cpufreq-dt's clk_get(cpu_dev) would fail with -ENOENT regardless.
    - Nothing named altr/socfpga appears in cpufreq-dt-platdev.c's allowlist.
    - A single OPP "clock + regulator" cannot express this transition: four
      clocks derived from one VCO must be reprogrammed as one atomic,
      order-dependent sequence (bypass the main PLL, then apply dividers and VCO
      in an order that depends on whether the target VCO is above or below the
      current one).

  Making cpufreq-dt work would mean adding .set_rate/.determine_rate to a clock
  driver shared by every Cyclone V board.  Out of scope; carry this.

Origin:          https://github.com/MiSTer-devel/Linux-Kernel_MiSTer
                 commit 3d72b9d
                 ("Add cpufreq/overclock driver (MiSTer-devel#34)"), squashed with
                 commit e6df8e3
                 ("Improve clock transition stability and get OSC1 freq from
                 DT (MiSTer-devel#35)"), branch MiSTer-v5.15.
Original author: Michael Huang <coolbho3000@gmail.com>
Upstream status: Not upstream.  Never submitted to linux-pm.  Not upstreamable
                 as-is: it pokes the clock manager behind the CCF's back instead
                 of teaching drivers/clk/socfpga how to set rates.  Carried
                 indefinitely.
ABI contract:    docs/abi-contract.md section 7.3 / section 12 -- the standard
                 cpufreq sysfs under /sys/devices/system/cpu/cpu*/cpufreq/.
                 Main_MiSTer does NOT read cpufreq (verified: no "cpufreq" and no
                 "scaling_" anywhere in its sources); the consumers are the
                 community overclock scripts on /media/fat.
Rebased-from:    v5.15.1 to v6.18.38 by Michael C. Ferguson (task P1.6).

Forward-port notes (5.15 -> 6.18).  The first three are hard build failures; the
fourth is a silent runtime failure.  Behaviour on hardware is otherwise unchanged.

  * cpufreq_frequency_table_verify() lost its "table" argument -- it now takes
    only (struct cpufreq_policy_data *) and reads policy->freq_table itself.  The
    5.15 two-argument call is "error: too many arguments to function".
  * struct cpufreq_driver::exit() returns void, not int.  The 5.15 int-returning
    socfpga_cpu_exit() is "error: initialization of 'void (*)(struct
    cpufreq_policy *)' from incompatible pointer type 'int (*)(struct
    cpufreq_policy *)'".
  * "void inline wait_for_fsm(void)" is -Wold-style-declaration, and being
    non-static it is also -Wmissing-prototypes (a default warning since 6.8).
    It is now "static void".  socfpga_cpufreq_clk_mgr_base_addr is static too; it
    was needlessly global.
  * *** scaling_available_frequencies must NOT be listed in ->attr any more. ***
    Since 6.x, cpufreq_add_dev_interface() creates that file itself for every
    policy that has a freq_table.  Leaving it in the driver's ->attr array makes
    the core's second sysfs_create_file() return -EEXIST, which aborts policy
    creation -- the driver would compile and then simply never register.
    scaling_boost_frequencies is also core-created once the driver advertises
    boost support via ->set_boost (see "OVERCLOCK IS OPT-IN" below), so it too
    must be left out of ->attr for the same -EEXIST reason.  ->attr is now empty.

OVERCLOCK IS OPT-IN (the fix in this revision).  The board must NOT overclock on
its own: it boots at the stock 800 MHz and reaches 1.0/1.2 GHz only when a user
explicitly enables the standard cpufreq boost knob:

    echo 1 > /sys/devices/system/cpu/cpufreq/boost      # opt in to 1.0/1.2 GHz
    echo 0 > /sys/devices/system/cpu/cpufreq/boost      # back to stock 800 MHz

Mechanism: the 1000/1200 rows are CPUFREQ_BOOST_FREQ, .set_boost =
cpufreq_boost_set_sw toggles them, and .boost_enabled = false keeps boost off at
registration.  With boost off, cpufreq_frequency_table_cpuinfo() skips the boost
rows, so cpuinfo_max_freq and the default scaling_max_freq are the stock 800 MHz;
enabling boost re-includes them and lifts the ceiling to 1.2 GHz.

    /sys/devices/system/cpu/cpufreq/boost               default "0" (off)
    /sys/devices/system/cpu/cpu[01]/cpufreq/
        scaling_driver                  "socfpga"
        scaling_governor                default "performance"
        cpuinfo_min_freq                400000
        cpuinfo_max_freq                800000 (boost off) / 1200000 (boost on)
        scaling_max_freq                default 800000; <= cpuinfo_max_freq
        scaling_available_frequencies   "800000 400000"    (core-created)
        scaling_boost_frequencies       "1200000 1000000"  (core-created)

*** WHY THIS CHANGED vs the 5.15 fork (the bug this revision fixes). ***
The fork set policy->cpuinfo.max_freq = 1200000 in ->init and shipped no
->set_boost, expecting scaling_max_freq to stay writable to 1.2 GHz while the
CPUFREQ_BOOST_FREQ flag kept the governor off the boost rows by default.  On 6.18
that breaks: the default policy->max resolves FREQ_QOS_MAX (default "unbounded")
against cpuinfo.max_freq, so an explicit 1.2 GHz cpuinfo.max_freq BECOMES the
default scaling_max_freq, and the "performance" default governor drives straight
to it.  The board therefore overclocked ITSELF to 1.2 GHz on every boot -- silent,
unrequested, and unstable under load on passively-cooled boards (observed as
CPU-0 RCU stalls / hard lockups during heavy SD I/O).  Real software-boost support
makes the boost rows genuinely opt-in and restores the stock-800-MHz default.

REQUIRES A DTS HUNK (task P1.7).  The driver reads osc1's rate from
/clkmgr@ffd04000/clocks/osc1/clock-frequency.  Mainline's socfpga.dtsi declares
osc1 as a bare "fixed-clock" with no rate, no mainline Cyclone V board DTS
overrides it, and the MiSTer U-Boot has no socfpga FDT fixup (no ft_board_setup,
no CONFIG_OF_BOARD_SETUP, no fdt_setprop anywhere under arch/arm/mach-socfpga).
The stock MiSTer DTB does carry it (work/stock.dts:107-112, clock-frequency =
<0x17d7840> = 25000000).  So socfpga_cyclone5_de10nano.dts must add:

    &osc1 {
            clock-frequency = <25000000>;
    };

Unlike the 5.15 original -- which passed of_get_property()'s result straight to
be32_to_cpup() and would have oopsed on NULL -- this version fails the DT lookups
gracefully and returns -ENODEV, so a missing DTS hunk costs you cpufreq rather
than the boot.  It also drops the reference on the intermediate "clocks" node,
which the original leaked.

KNOWN LATENT BUG, DELIBERATELY PRESERVED.  wait_for_fsm() calls wait_on_bit(word,
bit, mode) with an __iomem pointer and passes CLKMGR_STAT_BUSY (a MASK, BIT(0) ==
1) where a BIT NUMBER is expected, so it polls bit 1 of CLKMGR_STAT rather than
bit 0.  wait_on_bit() also does a plain test_bit() on MMIO instead of readl(), and
if the bit were ever seen set it would sleep on a wait queue that no hardware can
ever wake.  In practice it returns immediately and PLL settling is covered by the
register write latency, which is why the stock kernel works.  Fixing it means
changing PLL transition timing, which cannot be validated without a DE10-Nano on
the bench -- and a forward-port is the wrong place to smuggle in an untested
change to clock sequencing.  Carried verbatim and tracked for hardware bring-up.

Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
When an endpoint's wMaxPacketSize is not a multiple of 4, dwc2 sets
up a DMA bounce buffer (chan->align_buf) for unaligned destinations --
but only copied data back out of that buffer for isochronous
split-IN transfers (dwc2_xfercomp_isoc_split_in()). Every other
split-IN transfer type (interrupt, bulk, control) with an unaligned
destination silently dropped its received data: the bounce buffer was
filled by the controller but never copied to the URB. Moves the copy
into the shared dwc2_hc_xfercomp_intr() completion path, gated on
`chan->align_buf && chan->ep_is_in && qtd->complete_split`, using
dwc2_get_actual_xfer_length() for the real byte count instead of the
isochronous-only `len`.

Provenance
----------
Origin:       d7adb20
              "Fix for unaligned IN data. (MiSTer-devel#57)"
              MiSTer-devel/Linux-Kernel_MiSTer, 2025-01-13, against v5.15.
              MiSTer-devel@d7adb20
Author:       Martin Donlon <wickerwaka@users.noreply.github.com>
Upstream:     No (verified: drivers/usb/dwc2/hcd_intr.c:922-928 still has
              the old unconditional align_buf copy confined to
              dwc2_xfercomp_isoc_split_in()). This is a real, general
              dwc2 host-controller bug affecting any split-IN transfer
              with an unaligned wMaxPacketSize, not a MiSTer-specific
              quirk -- Martin Donlon's PR description explicitly frames
              it as a fix worth sending upstream. Recommend submitting it
              to the dwc2 maintainers independently of this fork.
              Disposition "carry" (docs/patch-provenance.md class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              docs/patch-provenance.md originally flagged this patch for
              [OPUS] escalation on the theory that a "real bug fix, not a
              quirk" needed more careful handling than a mechanical quirk
              port. On inspection, dwc2_hc_xfercomp_intr() and
              dwc2_xfercomp_isoc_split_in() are structurally unchanged
              since 5.15 (same helper dwc2_get_actual_xfer_length(),
              same call sites) -- no upstream reorganization to navigate
              -- so it was carried here rather than escalated; see the
              P1.9 report for the full reasoning.

Signed-off-by: Martin Donlon <wickerwaka@users.noreply.github.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
Sets LED_BRIGHT_HW_CHANGED on every gpio_led_data.cdev and calls
led_classdev_notify_brightness_hw_changed() from gpio_led_set()
whenever the level actually changes, publishing
/sys/class/leds/<name>/brightness_hw_changed. KEPT per explicit Phase 0
ruling (TASKS.md P1.9): Main_MiSTer polls brightness_hw_changed on
hps_led0 (the DE10-Nano's on-board LED, wired to the mmc0 activity
trigger by 0004-dts-de10nano-MiSTer.patch) to drive the on-screen
disk-activity indicator -- dropping this patch silently breaks a
visible, load-bearing feature.

Provenance
----------
Origin:       b62efee
              "hps_led: enable brightness change notification."
              MiSTer-devel/Linux-Kernel_MiSTer, 2019-06-09, against v5.15.
              MiSTer-devel@b62efee
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No (verified: drivers/leds/leds-gpio.c's gpio_led_set() has
              no brightness_hw_changed notification and create_gpio_led()
              never sets LED_BRIGHT_HW_CHANGED). Disposition "carry",
              explicitly reaffirmed at P0.9/P1.9 (docs/patch-provenance.md
              class F-2; TASKS.md P1.9 "[P0] Keep the leds-gpio patch").
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Byte-identical hunks; struct gpio_led_data, gpio_led_set()
              and create_gpio_led() are unchanged since 5.15.
              platform_driver::remove() returning void instead of int
              (v6.11, 0edb555a65d1, flagged by P1.4) does not apply here
              -- gpio_led_driver has no .remove callback at all.

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
The Nintendo Switch Online Famicom controllers (the reproduction pair sold
to NSO subscribers) report themselves over Bluetooth with the Joy-Con (R)
product ID, 057e:2007, so they already match this driver's device table.
What they do *not* do is report a controller type the driver knows: the
device-info subcommand returns 0x07 for controller I and 0x08 for
controller II. Every type helper in hid-nintendo returns false for those
values, so on an unmodified 6.18 kernel the pads probe successfully, create
an input device, and then register *no buttons and no axes at all* -- a
completely silent, completely dead gamepad, with nothing in dmesg.

This adds the two types and wires them into the two dispatch chains
(joycon_parse_report() and joycon_input_create()):

  * JOYCON_CTLR_TYPE_FAML (0x07), Famicom controller I, is a NES pad in a
    different shell -- same buttons, same report bits -- so it reuses
    nescon_button_mappings verbatim.

  * JOYCON_CTLR_TYPE_FAMR (0x08), Famicom controller II, has no SELECT and
    no START (on a real Famicom those live on controller I). In their place
    it carries a microphone and a volume slider. It gets its own four-entry
    table -- A, B, and the two rail buttons -- so those two bits are simply
    never reported rather than fabricated. The microphone is not exposed;
    the original commit says so in its subject ("no mic for Famicom R") and
    this port does not add it either.

Nothing else needs touching, and that is worth stating explicitly because
it is where a mechanical port of the original goes wrong (see below): in
6.18 the capability helpers -- joycon_has_imu(), joycon_has_joysticks(),
joycon_has_rumble() -- are *positive* lists naming the controllers that DO
have the capability. A newly added type is excluded from all three by
construction. No rumble, no IMU, no sticks, correctly, with no code.

Provenance
----------
Origin:       484f681
              "input: Add support for the NSO Famicom controllers
              (no mic for Famicom R) (MiSTer-devel#62)"
              MiSTer-devel/Linux-Kernel_MiSTer, 2025-06-16, against v5.15.
              MiSTer-devel@484f681
Author:       Aurora <AuroraWright@users.noreply.github.com>
Upstream:     No. Verified against 6.18.38: drivers/hid/hid-nintendo.c
              enum joycon_ctlr_type (:314) has JCL/JCR/PRO/NESL/NESR/SNES/
              GEN/N64 and no Famicom types; no helper anywhere tests for
              0x07 or 0x08. Upstream hid-nintendo does support the other
              NSO controllers -- NES, SNES, N64, Genesis -- via 94f18bb19945
              ("HID: nintendo: add support for nso controllers", Ryan
              McClelland, 2023-12-04), which is why those MiSTer commits
              were dropped as superseded (docs/patch-provenance.md class C)
              and only the Famicom gap remains. Worth sending upstream:
              it is a small, self-contained addition in the driver's own
              idiom.
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9
              (escalated to [OPUS]: this is a re-implementation, not a
              rebase -- the original diff does not apply in any form).

              94f18bb19945 rewrote the driver's type detection between the
              fork's 5.15 base and 6.18. The original patch is written
              against the old idiom and every one of its hunks is now
              obsolete:

              * Old: `#define jc_type_is_nescon(ctlr)` etc., macros that
                AND the USB product ID with the ctlr_type byte. New: typed
                `static inline bool joycon_type_is_*(struct joycon_ctlr *)`
                helpers that test ctlr_type alone, in three documented
                tiers (device / type / capability, hid-nintendo.c:658-767).
                The product ID is deliberately no longer consulted -- NSO
                pads lie about it -- so the original's "product == JOYCONR
                && type == FAMIR" conjunction is redundant; type alone is
                the authority. Added joycon_type_is_left_famicom() and
                joycon_type_is_right_famicom() in that idiom.
              * Old: `jc_type_is_joycon` had to be taught to exclude the
                new Famicom types, or a Famicom (which reports the Joy-Con
                (R) product ID) would have been misdetected as a Joy-Con.
                New: joycon_type_is_any_joycon() is type-based, so it is
                already false for 0x07/0x08. Hunk dropped.
              * Old: `jc_type_is_nso` (a roll-up of the NSO types) gated a
                shared reporting block. New: no such helper exists; each
                type gets its own arm in joycon_parse_report() and
                joycon_input_create(). Hunk dropped, replaced by the two
                new arms.
              * Old: `jc_has_rumble` was a *negative* list (everything
                except nescon/snescon/mdcon) and had to be taught about
                Famicom or the pads would have been given a rumble device
                they do not have. New: joycon_has_rumble() is a positive
                list. Hunk dropped -- see the note above.
              * Old: button sets were flat arrays of BTN_* codes
                (`famircon_button_inputs[]`) and the bit->code mapping was
                open-coded in a long if/else in the report handler. New:
                `struct joycon_ctlr_button_mapping` tables of
                {code, bit} pairs, consumed by joycon_config_buttons() and
                joycon_report_buttons(). The original's array cannot be
                carried; famicom_r_button_mappings[] was authored against
                the new structure, with the JC_BTN_* bits taken from the
                shared NSO decode block the original patch relied on
                (JC_BTN_A/B/L/R, hid-nintendo.c:341-362 -- the bit
                assignments are unchanged from 5.15).

              Behaviour note, A/B: the original reports "A" as BTN_EAST and
              "B" as BTN_SOUTH for all NSO controllers. Upstream 6.18 maps
              NES-family pads positionally instead -- "A" -> BTN_SOUTH,
              "B" -> BTN_EAST (nescon_button_mappings; cf. the explicit
              "mapped positionally, rather than by label" comment on
              gencon_button_mappings). This port follows *upstream's*
              convention, because Famicom controller I shares
              nescon_button_mappings and the two pads of one set must not
              disagree with each other. Consequence: A and B are swapped
              relative to stock MiSTer -- but they are swapped for the NSO
              NES, SNES, N64 and Genesis pads too, which is a pre-existing
              consequence of taking upstream's hid-nintendo instead of the
              fork's, not something this patch introduces. Users re-map in
              the MiSTer OSD; flag for P3.13 hardware verification.

              Not hardware-tested: no NSO Famicom pair available here. The
              type bytes (0x07/0x08), the button set, and the absence of
              SELECT/START on controller II are taken from the original
              commit, whose author has the hardware.

Signed-off-by: Aurora <AuroraWright@users.noreply.github.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
… report

Some 3rd-party wired DualShock4 clones don't implement Sony's
vendor DS4_FEATURE_REPORT_PAIRING_INFO report (used only to read the
controller's own MAC address for hdev->uniq and device-list dedup).
Treat a failed read as non-fatal -- log and continue with whatever
(possibly zeroed) buffer came back -- rather than refusing to bind
the controller at all.

Provenance
----------
Origin:       5c410e9
              "hid-sony: fix for 3rd party DS4 failing to connect by wire."
              MiSTer-devel/Linux-Kernel_MiSTer, 2025-11-06, against v5.15.
              MiSTer-devel@5c410e9
              NOT ported: 1412bd7
                "hid-sony: fix divide by 0 exception.", Sorgelig,
                2019-03-20 -- already superseded upstream. Both DualSense
                and DualShock4 calibration setup in hid-playstation.c
                (added by 8e5198a12d64 et al.) sanity-check every
                sens_denom for zero at calibration-parse time and
                substitute a safe default (DS_GYRO_RANGE/S16_MAX etc.),
                which is a more thorough fix than the fork's per-report-
                parse `calib->sens_denom ? mult_frac(...) : 0` guard.
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No -- but the file moved. The fork's fix targets
              hid-sony.c's sony_check_add(); DualShock4 support
              (including MAC-address retrieval) was split out to the new
              upstream hid-playstation.c
              (8c0ab553b072/8e5198a12d64 et al.), whose
              dualshock4_get_mac_address() has the identical hard-fail-
              on-read-error bug in its new home. Disposition "carry",
              retargeted (docs/patch-provenance.md class D --
              renamed from "0022-hid-sony-fixes.patch").
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Applied the same non-fatal-on-read-failure change to
              dualshock4_get_mac_address() in hid-playstation.c (the
              function ps_get_report() failure path), instead of
              hid-sony.c's sony_check_add() (which no longer handles DS4
              at all). Removed the resulting unreferenced `err_free:`
              label (-Wunused-label) now that nothing gotos it.

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
Three independent fixes: (1) propagate hdev->uniq to every wiimote
extension input_dev (core + accel/ir/nunchuk/classic/bboard/pro/
drums/guitar/mp), so userspace can tell multiple paired Wiimotes
apart; (2) remap d-pad/plus/minus from generic KEY_LEFT/RIGHT/UP/
DOWN/NEXT/PREVIOUS to BTN_DPAD_*/BTN_START/BTN_SELECT (both the base
Wiimote and Classic Controller extension), matching gamepad
conventions instead of remote-control ones; (3) correct the Nunchuk's
analog stick range (was -120..120, actually -100..100) and the
Classic Controller's analog trigger range (was a signed -30..30,
actually an unsigned 0..62).

Provenance
----------
Origin:       0d7778d
              "wiimote: set uniq field."
              MiSTer-devel/Linux-Kernel_MiSTer, 2019-05-05, against v5.15.
              MiSTer-devel@0d7778d
              + 47dc53a
                "wiimote: fix the buttons codes.", Sorgelig, 2019-05-05.
              + 15968bc
                "wiimote: fix analog ranges.", Sorgelig, 2019-05-05.
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No. Disposition "carry" (docs/patch-provenance.md class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Compiles unmodified against 6.18's hid-wiimote-core.c/
              hid-wiimote-modules.c (function/struct layout unchanged).
              Extended the uniq-field fix to wiimod_turntable_probe()
              (DJ Hero turntable extension) as well: that module was
              added to hid-wiimote-modules.c after the fork's 5.15 base
              and the original patch never saw it, but the same
              rationale (distinguish multiple paired peripherals) applies
              -- added here for consistency with the other 10 sites this
              fix already touches.

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
The Elite 2 controller reports its 4 back paddles as a vendor
"consumer" usage (HID_UP_CONSUMER | 0x0081) that generic hid-input
mapping ignores; a second usage (0x0099) is a trigger-scale switch
that should be dropped entirely rather than exposed as an axis. Adds
MS_QUIRK_ELITE2_PADDLES: ms_input_mapping() claims and registers
BTN_GRIPL/L2/R/R2 for the paddle usage and discards the trigger-scale
usage; ms_event() decodes the paddle bitmask and reports the 4 keys.

Provenance
----------
Origin:       c784a68
              "hid-microsoft: support for XBox Elite 2 paddles."
              MiSTer-devel/Linux-Kernel_MiSTer, 2026-04-08, against v5.15.
              MiSTer-devel@c784a68
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     Partially. 6.18 already binds the Elite 2 controller
              (USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797_BLE, a rename
              of the fork's USB_DEVICE_ID_MS_XBOX_ELITE2_CONTROLLER --
              same ID, 0x0b22) with MS_QUIRK_FF, and BTN_GRIPL/R/L2/R2 are
              mainline UAPI (97c01e65ef4c). The paddle-usage remapping
              logic itself (MS_QUIRK_ELITE2_PADDLES) is not upstream.
              Disposition "carry" (docs/patch-provenance.md class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Device-table edit retargeted from the fork's
              USB_DEVICE_ID_MS_XBOX_ELITE2_CONTROLLER to 6.18's renamed
              USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797_BLE (same
              numeric ID, 0x0b22). Dropped the fork's
              "#ifndef BTN_GRIPL / #define BTN_GRIPL 0x224 ... #endif"
              guard block: those macros are unconditionally provided by
              6.18's <linux/input-event-codes.h> now, so the guard was
              always false and the block dead code.

Signed-off-by: Sorgelig <pour.garbage@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
…put)

Four independent deltas curated on top of 6.18's own (already very
different from the 5.15 base) xpad.c:
  1. `cpoll` module param overriding the USB interrupt-endpoint polling
     interval for XInput pads (both directions).
  2. Qanba Obsidian Arcade Joystick (2c22:2303) forced into XTYPE_XBOX360
     mode, plus vendor-wide match for 0x2c22.
  3. GIP-capable Xbox One/Series controllers (045e:02d1/02dd/02e3/02ea/
     0b00/0b12) excluded from xpad_device[] AND from binding at all
     (bInterfaceSubClass 0x47 / bInterfaceProtocol 0xd0 check in
     xpad_probe()) so the xone driver (package/xone) claims them instead.
  4. Flydigi Vader 3/4/5 Pro: wired/RF-dongle extra buttons (C/Z/M1-M4/
     Circle) decoded from extra report bytes when MAP_VADER4 is set
     (Vader 3/4, detected by USB product-string match); Vader 5 Pro
     additionally gets a full "Flydigi V2" raw-mode client (a second USB
     interface, checksum-framed command/report protocol, toggled by a
     Circle+Turbo chord) implemented from scratch in this driver file.

Provenance
----------
Origin:       f3c75eb
              "XInput polling rate param + Qanba Obsidian XInput mode
              support", eniva, 2019-11-21, against v5.15 (delta 1, 2).
              MiSTer-devel@f3c75eb
              + a2242dd
                "xpad: exclude GIP-capable controllers.", Sorgelig,
                2026-04-08 (delta 3).
              + c035c21
                "xpad: support for extra buttons on Flydigi Vader 3/4/5
                Pro in wired and RF dongle modes.", Sorgelig, 2026-04-15
                (delta 4).
              NOT ported: af27afc
                "Update xpad driver (MiSTer-devel#63)", zakk4223, 2025-09-29 -- a
                wholesale resync of xpad.c to a much newer upstream
                version. Its content is superseded by 6.18's own xpad.c,
                which already carries MAP_PADDLES/MAP_SHARE_BUTTON/
                MAP_PROFILE_BUTTON, the paddle report path
                (BTN_GRIPL/R/L2/R2), Flydigi Apex 5, and
                XPAD_XBOX360_VENDOR(0x2c22) is the only piece of it this
                patch still needs to add itself (see delta 2).
Author:       eniva; Sorgelig (deltas 3, 4).
Upstream:     No (cpoll, the GIP exclusion, Vader 3/4/5 Pro support and
              the Qanba entry are all absent from 6.18.38's xpad.c).
              Disposition "carry" (docs/patch-provenance.md class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Curated by hand against 6.18's actual xpad.c (not diffed
              from the fork's post-resync xpad.c) -- see report for the
              full hazard list. Notable fixes beyond the original:
                - xpad_device[]'s `mapping` field widened u8->u16 to fit
                  MAP_VADER4=BIT(8) (struct usb_xpad's own `mapping` was
                  already `int`, unaffected).
                - usb_maxpacket()'s dropped 3rd argument does NOT affect
                  this file (xpad.c never called it); noted for parity
                  with 0011/0028, which did hit it.
                - Added a NULL check on udev->product before strstr()
                  (VADER3/VADER4 product-string detection) -- the
                  original would crash probing any device that omits a
                  USB product string descriptor.
                - flydigi_send_command()'s kmalloc failure path now
                  returns -ENOMEM instead of a bare -1; flydigi_init()
                  NULLs flydigi_idata after a failed URB allocation to
                  avoid a dangling pointer reaching xpad_disconnect()'s
                  cleanup on a later probe retry.
                - Dropped 3 unconditional pr_info() bInterval debug
                  prints (would spam dmesg on every XInput pad attach);
                  kept the functional interval override.
                - Qanba's xpad_device[] entry moved into its
                  numerically-sorted position (0x2993 < 0x2c22 < 0x2dc8);
                  the fork inserted it out of order at the top of the
                  table, against the file's own "keep this list sorted"
                  comment.
              HW verification pending (flag for P3.13): Vader 5 Pro's
              raw/extended-mode protocol (flydigi_*()) and the GIP-
              exclusion/xone hand-off are unverified against real
              hardware -- ported from the fork's protocol implementation
              and structurally sound, but not bench-tested here.

Signed-off-by: eniva <58012997+eniva@users.noreply.github.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
New driver, hid-vader4.c. The Vader 4 Pro reports several of its
extra buttons (grip paddles, a 4th face button, MODE) as generic
consumer-page keys (KEY_ENTER/KEY_TV/KEY_CHANNELUP/etc.) when paired
over Bluetooth in D-Input mode. This driver's .event hook intercepts
those usages and re-reports them as BTN_C/BTN_Z/BTN_GRIPL(2)/
BTN_GRIPR(2)/BTN_TRIGGER_HAPPY3/BTN_MODE instead.

Provenance
----------
Origin:       b1b168e
              "input: add HID driver to fix Flydigi Vader 4 Pro mapping
              in D-Input over Bluetooth."
              MiSTer-devel/Linux-Kernel_MiSTer, 2026-04-15, against v5.15.
              MiSTer-devel@b1b168e
Author:       Alexey Melnikov (commit authored under the Sorgelig account).
Upstream:     No. Disposition "carry" (docs/patch-provenance.md class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Compiles unmodified. BTN_GRIPL/BTN_GRIPL2/BTN_GRIPR/
              BTN_GRIPR2 are mainline UAPI since 97c01e65ef4c (v6.18) with
              the same numeric values the fork used locally; no header
              conflict.

Signed-off-by: Alexey Melnikov
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
New driver, hid-gamecube-adapter.c, for the official Nintendo
WUP-028 GameCube Controller Adapter (057e:0337, 4 ports). Ports
ToadKing/wii-u-gc-adapter's protocol handling: an INIT command kicks
the adapter into polling mode, then each interrupt report carries all
4 ports' state, hot-plugged in/out via per-port work items. Optional
force feedback (CONFIG_HID_GAMECUBE_ADAPTER_FF) rumbles official
first-party pads.

Provenance
----------
Origin:       77862a6
              "Add support for official gamecube-adapter (MiSTer-devel#48)"
              MiSTer-devel/Linux-Kernel_MiSTer, 2023-07-23, against v5.15.
              MiSTer-devel@77862a6
Author:       James McCarthy <clockworkjb@gmail.com>
Upstream:     No (verified against 6.18.38: no hid-gamecube-adapter.c, no
              USB_DEVICE_ID_NINTENDO_GAMECUBE_ADAPTER). Disposition
              "carry" (docs/patch-provenance.md class D; not in PLAN §6's
              original list, added by the P0.4 triage).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              hid_is_using_ll_driver(hdev, &usb_hid_driver) no longer
              compiles: usb_hid_driver became `static` inside
              usbhid/hid-core.c once the USB-specific hid_is_usb(hdev)
              helper was added upstream to replace open-coded ll_driver
              pointer comparisons (c122c07f470a4, v5.2). Replaced the one
              call site in gamecube_fixup_urb_in() with hid_is_usb(hdev).
              Everything else (usbhid_device.urbin, hid->driver_data cast)
              is unchanged.

BUG FIX (behaviour change vs. the 5.15 original -- use-after-free on unplug):

  The original teardown cancelled only adpt->work_rumble. The four per-port
  ctrl->work_connect items were never cancelled, and gamecube_adpt_destroy()
  then kfree()'d the adapter. work_connect is embedded in adpt->ctrls[], and
  its handler container_of()s back to the ctrl and dereferences
  ctrl->adpt->hdev -- so an item still pending at the kfree() ran against
  freed memory. It can also call gamecube_ctrl_create(), i.e. register an
  input_dev bound to the freed adapter.

  work_connect is scheduled from gamecube_ctrl_update_flags(), which runs from
  the HID report path -- so a controller being plugged into the adapter while
  the adapter itself is unplugged is enough to hit it. The same defect exists
  on the probe error path (err_close is reachable only after hid_hw_open() has
  succeeded, so reports are already flowing).

  Fixed in both places. The ordering in gamecube_adpt_destroy() is deliberate:
    1. hid_hw_close()/hid_hw_stop() FIRST -- the report path is the only thing
       that can schedule work_connect, so cancelling before the stop would
       race (a report arriving between the cancel and the stop re-arms it).
    2. cancel_work_sync(work_connect) x4 -- drained BEFORE the inputs are
       unregistered, because a pending item may still call
       gamecube_ctrl_create(); any input_dev it registers is then torn down by
       step 3. Draining after step 3 would leak that device and leave it
       pointing at an adapter about to be freed.
    3. gamecube_ctrl_destroy() x4 -- unregistering the inputs closes the
       userspace force-feedback path, the only thing that schedules
       work_rumble. (A rumble slipping through between step 1 and here is
       harmless: hid_hw_output_report() on a stopped device returns -ENOSYS.)
    4. cancel_work_sync(work_rumble), then kfree().

  Reported by static review on PR MiSTer-devel#2. This is a PRE-EXISTING bug in the MiSTer
  fork, not a forward-porting regression -- it is present verbatim in the 5.15
  source (drivers/hid/hid-gamecube-adapter.c, gamecube_adpt_destroy()).

Signed-off-by: James McCarthy <clockworkjb@gmail.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
Mainline's socfpga_cyclone5_de10nano.dts (144616a80889, v6.14) describes a
bare Terasic DE10-Nano: ethernet, the three GPIO banks, i2c0 + the on-board
accelerometer, mmc0 and uart0. MiSTer needs considerably more of the SoC
switched on. This adds, all of it diffed value-by-value against the DTB
decompiled from a running stock MiSTer (docs/stock-inventory/stock.dts):

  - usb1                 dr_mode = "host", disable-over-current
  - fpga_bridge0/1/2     lwhps2fpga, hps2fpga, fpga2hps (fpga2sdram stays off)
  - spi0 + spiusb@0      "MiSTer,spi-audio" @10 MHz, cpha/cpol  -> patch 0002
  - spi1 + spidev@0      "rohm,dh2228fv" @25 MHz -> /dev/spidev1.0  (see below)
  - i2c2                 the third of exactly three i2c adapters (see A14)
  - uart1                enabled; DMA deleted from BOTH uarts (DW UART DMA is
                         unreliable on this SoC; stock deletes it too)
  - MiSTer_fb@22000000   reg = <0x22000000 0x800000>, GIC SPI 40 -> patch 0001
  - gmac1                phy-mode "rgmii" + all 12 KSZ9031 *-skew-ps values +
                         max-frame-size = <3800>
  - i2c_gpio             bit-banged RTC bus on portb 22/23, three candidate
                         RTCs (only one is populated on any given add-on board)
  - gpio-leds hps0       label "hps_led0" (ABI: Main_MiSTer polls
                         /sys/class/leds/hps_led0/brightness_hw_changed)
  - regulator_3_3v       + mmc0 vmmc-supply/vqmmc-supply
  - aliases/ethernet0    U-Boot's fdt_fixup_ethernet() needs it to inject $ethaddr

A14 -- THE CONSTRAINT THIS PATCH MUST NOT BREAK
-----------------------------------------------
Main_MiSTer refuses to scan past /dev/i2c-2 (Main:smbus.cpp:214,
"if (force_bus > 2) return -1") and finds the ADV7513 HDMI transmitter by
probing 0x39 on each of /dev/i2c-0..2 (Main:video.cpp:1448). If this DTB ever
enables a FOURTH i2c adapter, the transmitter can land on /dev/i2c-3 and HDMI
dies with no error message at all.

This DTB enables exactly three i2c adapters -- i2c0 (0xffc04000), i2c2
(0xffc06000) and the bit-banged i2c_gpio -- the same three, on the same pins,
as stock. i2c1 and i2c3 stay disabled. There are no "i2c" aliases, so
i2c_add_adapter() takes the dynamic path (i2c-core-base.c:1662-1677) and
idr_alloc()s from __i2c_first_dynamic_bus_num, which is 0: nothing here calls
i2c_register_board_info(), and i2c_init()'s of_alias_get_highest_id("i2c")
finds no alias to raise it. Three adapters numbered from zero can only be
{0,1,2}. See docs/dts-comparison.md ("A14") for the full argument.

/dev/spidev1.0 WITHOUT A KERNEL PATCH
-------------------------------------
Stock's spi1 child used compatible = "altspi", which is not a mainline binding
-- it worked only because the fork added that one string to spidev_dt_ids[]
(fork commit 246984f). Since we author our own DTS we instead use
"rohm,dh2228fv", which mainline's spidev already accepts (6.18
drivers/spi/spidev.c, spidev_dt_ids[]), so the fork's spidev hunk (planned as
0005-spidev-accept-altspi-compatible.patch) is DROPPED, not carried. The node
still lands on SPI bus 1 CS 0 -> /dev/spidev1.0, which is what
Main_MiSTer/brightness.cpp opens. spidev_of_check() only rejects the literal
string "spidev" in DT and is satisfied by this compatible.

Provenance
----------
Origin:       aa8afe1 "de10-nano dts" plus 12 follow-ups (e40563a,
              2548c29, 6827e76, 6c2d539, 246984f, 1337de1,
              c4d12c7, 7d2df2d, c506676, 071d909, f526901,
              077c2c3) in MiSTer-devel/Linux-Kernel_MiSTer, against v5.15.
              https://github.com/MiSTer-devel/Linux-Kernel_MiSTer
Author:       Sorgelig <pour.garbage@gmail.com>; 6827e76 by antoniovillena.
Upstream:     No. Mainline gained a minimal de10nano DTS in 144616a80889
              (v6.14) which is insufficient (PLAN.md 4.1a). The MiSTer nodes
              (MiSTer_fb, MiSTer,spi-audio) reference out-of-tree drivers and
              are not upstreamable as-is. Disposition "carry"
              (docs/patch-provenance.md 3.1, 5).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.7.
              Re-authored on top of mainline's board DTS rather than replayed:
              the fork's file was a full board DTS at the old path
              arch/arm/boot/dts/socfpga_cyclone5_de10_nano.dts (note the
              underscores), and 6.18 moved the tree into vendor subdirs. Node
              labels are unchanged, so every &node override applies as-is.
              The fork also carried a hunk in the SHARED socfpga.dtsi
              (i2c1 clock-frequency). It is NOT carried: i2c1 is disabled on
              this board in stock and here, so the property is never read, and
              dropping it keeps this patch off a file shared by every socfpga
              board.
Divergences from stock, each with its justification, are tabulated in
docs/dts-comparison.md. Verified: dtbs builds with zero new dtc warnings
(default flags AND W=1); the built DTB was decompiled and compared node-by-node
against docs/stock-inventory/stock.dts.

Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
New driver, hid-guncon2.c. A raw usb_driver (not a HID driver -- it
bypasses the HID report-descriptor parser entirely and reads the
device's fixed 6-byte interrupt-IN report directly), for the Namco
GunCon 2 USB light gun (0b9a:016a). Maps aim to ABS_X/ABS_Y, the
trigger to BTN_X, and face buttons/d-pad to BTN_A/B/Y/START/SELECT
and ABS_HAT0X/Y.

Provenance
----------
Origin:       e503d19
              "Add driver for Namco GunCon 2"
              MiSTer-devel/Linux-Kernel_MiSTer, 2022-02-03, against v5.15.
              MiSTer-devel@e503d19
Author:       Nolan Nicholson <NolanNicholson@users.noreply.github.com>
Upstream:     No (verified against 6.18.38: no drivers/hid/hid-guncon2.c,
              no USB_VENDOR_ID_NAMCO/USB_PRODUCT_ID_NAMCO_GUNCON2 in
              hid-ids.h). Disposition "carry" (docs/patch-provenance.md
              class D).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-12, task P1.9.
              Compiles unmodified against 6.18's USB/input APIs
              (usb_find_common_endpoints, usb_fill_int_urb, strlcat,
              devm_input_allocate_device all unchanged). Whitespace/style
              only: brace placement, // -> /* */ comments.

Signed-off-by: Nolan Nicholson <NolanNicholson@users.noreply.github.com>
Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
mcfbytes and others added 8 commits July 14, 2026 11:20
MiSTer's arcade organizer builds its entire _Organized tree out of
symlinks on the exFAT data partition, so ADR 0010's "symlinks appear
unused" finding is wrong in the way its own §Rationale warned it might
be (n=1 evidence). Mainline exfat has no symlink support at all; this
adds it, byte-compatible with the on-disk format of the out-of-tree
Samsung driver that every stock MiSTer kernel has shipped, so symlink
trees already on users' cards keep resolving:

  * a symlink is an ordinary file dentry set whose attributes carry
    the DOS "system" bit (0x0004, EXFAT_ATTR_SYMLINK), and whose file
    data is the target path, NOT NUL-terminated
    (i_size == strlen(target));
  * 0x0040 (EXFAT_ATTR_SYMLINK_OLD), the marker used by even older
    Samsung releases, is honoured on read and upgraded to 0x0004 on
    the next attr writeback, never written on create.

Unlike the Samsung driver (a parallel 20-file filesystem
implementation), this reuses the vanilla infrastructure: creation goes
through exfat_add_entry() + page_symlink() (which writes exactly len-1
bytes -- the Samsung format falls straight out), and readback is
page_get_link(), whose nd_terminate_link() handles the on-disk string
having no NUL. The symlink inode needs inode_nohighmem() because
page_get_link() uses page_address() directly.

Locking: exfat_get_block() takes sbi->s_lock, so exfat_symlink() must
drop s_lock before page_symlink(). If the data write fails, the
just-created dentry set is removed again (same incantation as
exfat_unlink()); only once that removal has durably reached the disk
is nlink cleared so eviction frees the allocated cluster -- on a
removal failure the entry is left alive instead, because a live
on-disk entry must never point at freed clusters. On dirsync mounts
(MiSTer mounts /media/fat with sync,dirsync) the target write is
flushed with write_inode_now() before the symlink is instantiated.

Four sharp edges found in review, all handled here:

  * ei->type stays TYPE_FILE: TYPE_SYMLINK exists only as a creation-
    time dispatch code for exfat_add_entry()/exfat_set_entry_type().
    An in-core type of its own would defeat __exfat_truncate()'s type
    guard, leaking the target's cluster on every same-mount
    create+delete (the arcade organizer's reorganize pattern), and
    fsck.exfat does not even flag the orphaned bitmap bits.
  * The SET_ATTRIBUTES ioctl pins EXFAT_ATTR_SYMLINK to its current
    state on non-directories: the system bit now encodes S_IFMT, and
    flipping it on a live inode would hand setattr an S_IFLNK/S_IFREG
    type swap the VFS cannot express.
  * readdir derives d_type with fs_umode_to_dtype(exfat_make_mode()),
    the same classifier lstat uses, so getdents and stat can never
    disagree about linkness (GNU find trusts d_type -- a DT_REG lie
    here is exactly why ADR 0010's evidence scan missed the symlinks).
  * The one attr predicate lives in EXFAT_ATTR_SYMLINK_ANY, consumed
    by both exfat_make_mode() and exfat_fill_inode().

Semantics concession, inherited from stock: any non-directory entry
carrying attribute 0x0004 or 0x0040 is presented as a symlink, even if
it is a genuine Windows "system" file (e.g. IndexerVolumeGuid inside
System Volume Information). Stock MiSTer kernels have behaved this way
since 2021; matching that behaviour is the point of this patch.

Scope concession: exFAT only. The Samsung driver also mounted
FAT12/16/32 and gave them the same symlinks; mainline vfat has no
symlink support and does not get any here. A FAT32-formatted MiSTer
card with an organized arcade tree still loses its symlinks (ADR 0019).

Provenance
----------
Origin:       df35bdb
              "Add exFAT with symlinks support."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-08-30, against v5.15.
              MiSTer-devel@df35bdb
              Origin of the ON-DISK FORMAT only (exfat_super.c:676
              exfat_symlink(), exfat_core.c:2629 exfat_set_entry_type()
              TYPE_SYMLINK, exfat_api.h:65 ATTR_SYMLINK/ATTR_SYMLINK_OLD).
              The code below is a fresh implementation against mainline
              fs/exfat, not a forward-port of the Samsung driver.
Author:       Michael C. Ferguson (new code); format by Samsung, carried
              into MiSTer by Sorgelig <pour.garbage@gmail.com>.
Upstream:     No, and not upstreamable as-is: it overloads a real FAT
              attribute bit that Windows assigns to ordinary files, so
              upstream would (reasonably) reject the ambiguity. Carried
              indefinitely; fs/exfat churn is low (6 files, all touching
              stable functions). Disposition "carry"
              (docs/patch-provenance.md §3.8 class G, option (c);
              decision reversal recorded in ADR 0019, which amends
              ADR 0010).
Forward-port: n/a (written against 6.18.38 directly, 2026-07-14).

Signed-off-by: Michael C. Ferguson <michael.christopher.ferguson@gmail.com>
Registers a virtual LED classdev named "<hid-dev>:combo" on each Joy-Con
(L and R). There is no hardware behind it: Main_MiSTer uses the node as a
pairing mailbox -- a button-combo gesture writes a shared id to one
Joy-Con's :combo LED and the rescan path reads it back from both to bind
the pair into one combined controller (input.cpp:4704/4715 read,
:4822-4823 write, bind at :4729-4730). Without this node Joy-Con
combining is entirely and silently non-functional; no manual pairing
path exists in Main_MiSTer. Also downgrades the two dropped-IMU-report
compensation messages from hid_warn_ratelimited to hid_dbg, matching
stock's quiet behavior with flaky/clone Joy-Cons.

Provenance
----------
Origin:       4528378
              "hid-nintendo: add virtual combo led, don't warn by IMU compensation."
              MiSTer-devel/Linux-Kernel_MiSTer, 2021-08-14, against v5.15.
              MiSTer-devel@4528378
Author:       Sorgelig <pour.garbage@gmail.com>
Upstream:     No. Vanilla 6.18.38 hid-nintendo has no combo LED (git log
              -S'combo' over the file's history is empty). The provenance
              doc's Class-C grouping of this commit under 2af16c1f846b was
              a misclassification (docs/kernel-recon records, sonnet-verified).
Forward-port: 5.15 -> 6.18.38, Michael C. Ferguson, 2026-07-15, kernel patch
              reconciliation carry decision MiSTer-devel#1 (docs/kernel-recon/
              silent-regressions.md). Registration made non-fatal (warn +
              continue) instead of the fork's ignored return value; the
              6.18 joycon type constants and the hid_warn_ratelimited
              call sites replace their 5.15 equivalents. The combo LED
              is registered directly after the home_led: label, ahead of
              the home-LED block, so the home-LED early-return paths
              (set failure upstream; registration failure once 0035 makes
              it non-fatal) cannot skip it on a right Joy-Con
              (ultrareview finding, 2026-07-15).
The kernel configuration this board ships, in the kernel's own minimized
defconfig form, so the tree builds standalone without Buildroot:

    make ARCH=arm MiSTer_defconfig
    make ARCH=arm zImage

copied verbatim from linux.config, which is the exact configuration Buildroot builds
(BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE) — the image and this tree cannot drift.

This is deliberately the minimized form rather than a full expanded .config: an
expanded one bakes in the generating toolchain (CONFIG_CC_VERSION_TEXT) and
every default, which pins a config to one machine and buries the ~500 lines that
are actually a decision under ~4000 that are not.

Generated by scripts/export-kernel-tree.sh in Buildroot_MiSTer.
…/net/wireless/realtek/rtl8812au

Out-of-tree kernel module the MiSTer image ships, vendored here so this tree
builds what MiSTer actually runs rather than a kernel silently missing it.

  upstream  $(call github,morrownr,8812au-20210820,$(RTL8812AU_VERSION))
  pin       8cac6f43316a56cc89cc8cb532cd6c6ae14c4805
  sha256    3834d979416ff65844799962bc1d6a8d212c0d5307028ba0b79081df459b30ec

Sources are verbatim upstream, at the path the 5.15 branch uses. They are NOT
wired into Kconfig -- build them with ./build-mister-modules.sh, which uses this
package's own supported out-of-tree recipe. See that script for why.

Generated by scripts/export-kernel-tree.sh in Buildroot_MiSTer; the pin lives in
package/rtl8812au/rtl8812au.mk there.
…t drivers/net/wireless/realtek/rtl8821au

Out-of-tree kernel module the MiSTer image ships, vendored here so this tree
builds what MiSTer actually runs rather than a kernel silently missing it.

  upstream  $(call github,morrownr,8821au-20210708,$(RTL8821AU_MORROWNR_VERSION))
  pin       3a7cdb591b64d99d2670e455bde67c8ab338525b
  sha256    dc7877556b849a24b968be5237b30e0d0d29792e6da5d5f465ed18e1aadb7b78

Sources are verbatim upstream, at the path the 5.15 branch uses. They are NOT
wired into Kconfig -- build them with ./build-mister-modules.sh, which uses this
package's own supported out-of-tree recipe. See that script for why.

Generated by scripts/export-kernel-tree.sh in Buildroot_MiSTer; the pin lives in
package/rtl8821au-morrownr/rtl8821au-morrownr.mk there.
…xone

Out-of-tree kernel module the MiSTer image ships, vendored here so this tree
builds what MiSTer actually runs rather than a kernel silently missing it.

  upstream  $(call github,dlundqvist,xone,$(XONE_VERSION))
  pin       f2aa9fe01103d7600553b505b298ff0bd47ff280
  sha256    a41601d1c4eb974fe5f9edd8e5ed45ef738e73b8f478e5e605cc59cd9a9960fc

Sources are verbatim upstream, at the path the 5.15 branch uses. They are NOT
wired into Kconfig -- build them with ./build-mister-modules.sh, which uses this
package's own supported out-of-tree recipe. See that script for why.

Generated by scripts/export-kernel-tree.sh in Buildroot_MiSTer; the pin lives in
package/xone/xone.mk there.
The vendored drivers are not wired into Kconfig, so `make zImage` does not build
them. This does, using each package's own supported out-of-tree recipe as taken
from its Buildroot .mk -- the same invocation that builds the shipped image, not
a reimplementation of it.

Generated by scripts/export-kernel-tree.sh in Buildroot_MiSTer.
Names the source of truth, states that direct edits are erased by the next
regeneration, and records where to look for the disposition of each 5.15 fork
commit.

It also states, with a table, that this tree is the kernel the MiSTer image
ships PLUS the upstream-only patches listed there -- patches Buildroot
deliberately does not apply -- so nothing here claims the two are identical when
they are not. See scripts/export-kernel-tree.sh in Buildroot_MiSTer.
Copilot AI review requested due to automatic review settings July 16, 2026 16:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@mcfbytes

Copy link
Copy Markdown
Author

Force-pushed — the branch previously carried an older revision of the cpufreq patch that overclocked the DE10-Nano to 1.2 GHz on boot, which is not stable on all boards. That was my error: the tree was generated from a stale checkout that predated the fix.

The corrected 0003 makes overclocking opt-in, which is the intended behaviour:

.set_boost     = cpufreq_boost_set_sw,
.boost_enabled = false,

The 1.0/1.2 GHz rows are CPUFREQ_BOOST_FREQ, so with boost off cpufreq_frequency_table_cpuinfo() skips them and cpuinfo_max_freq is the stock 800 MHz. Opting in is the standard knob:

echo 1 > /sys/devices/system/cpu/cpufreq/boost   # 1.0/1.2 GHz
echo 0 > /sys/devices/system/cpu/cpufreq/boost   # back to stock 800 MHz

The previous forward-port set cpuinfo.max_freq = 1200000 directly; on 6.18 that leaks into the default policy->max via the FREQ_QOS_MAX resolve, so with the performance governor the board silently ran overclocked from boot.

Re-verified after the rebase, against Buildroot'''s own recipe (pristine hash-verified tarball + the series applied with patch -p1): 0 of 91,200 kernel source files differ from this branch. Still a fast-forward on d9ac12a69.

@sorgelig

sorgelig commented Jul 16, 2026

Copy link
Copy Markdown
Member

I didn't check very precise, but it doesn't look good.

  1. When you port to a new kernel, it's important port commits one by one. I mean, don't try to squash the commits. When you squash them, original logic of change got lost and further support of specific feature become more hard. Most commits in 5.15 were migrated from earlier kernel versions and before migrating i squashed all possible commits without loosing changelog logic. So DON'T try to squash then further.
  2. If imported driver (like XOne or Realtek) is still absent in new Kernel but has no compatibility issue, then it must be copied as-is from current (5.15) kernel. Don't try to update without the reason. Newer doesn't mean better. Older drivers are already tested, they may have specific patches already. Replacing it by newer version will lead to unpredictable results, and testing so many new imported drivers is impossible. For example, i don't have all devices. So users may have problems.
  3. I don't see some important commits like "Support for init loop device." which will make MiSTer non-bootable. So, we come to the (1) - need to port all commits one by one (unless it's impossible or deprecated).
  4. Kernel should be independent from buildroot. It should be a plug-in replacement in place of 5.15. I understand that Linux also need to be re-compiled because of new kernel version, but that's another story.

@mcfbytes

Copy link
Copy Markdown
Author

Thanks @sorgelig -- Picking back up here from Patrteon. Yes, there are definitely some things left behind. Please see https://github.com/mcfbytes/Buildroot_MiSTer/blob/master/docs/kernel-recon/reconciliation.md for the full analysis and reconciliation of what happened with each commit. The kernel loop mount removal would def break without other changes, apologies as I should have pointed that out. In my Buildroot that is being handled differently -- the kernel first mounts a tiny built-in initramfs (also created by Buildroot) that is baked into the kernel as a ~370 KB static-musl BusyBox cpio. board/mister/de10nano/initramfs-overlay/init then handles the loop mounting etc to get the real image in place. Basically, Buildroot_MiSTer moves the code in do_mounts.c to userspace to reduce kernel patching and improve general compatibility with upstream Linux.

I'll take a look into the other items also. Many drivers have moved into vanilla from out-of-tree repos, where they'll probably be better maintained, so I would suggest picking up the in-tree drivers vs. the out-of-tree drivers for those targets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

10 participants