MiSTer-v6.18: carried patch series + config + out-of-tree drivers on top of vanilla 6.18.38 - #75
MiSTer-v6.18: carried patch series + config + out-of-tree drivers on top of vanilla 6.18.38#75mcfbytes wants to merge 38 commits into
Conversation
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>
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.
|
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 .set_boost = cpufreq_boost_set_sw,
.boost_enabled = false,The 1.0/1.2 GHz rows are The previous forward-port set Re-verified after the rebase, against Buildroot'''s own recipe (pristine hash-verified tarball + the series applied with |
|
I didn't check very precise, but it doesn't look good.
|
|
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. 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. |
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.
What's in it
loop=support (3d95de58f), forward-ported to 6.18 — see belowarch/arm/configs/MiSTer_defconfigbuild-mister-modules.sh+EXPORT.mdVendored drivers
drivers/hid/xonedlundqvist/xonef2aa9fedrivers/net/wireless/realtek/rtl8812aumorrownr/8812au-202108208cac6f4drivers/net/wireless/realtek/rtl8821aumorrownr/8821au-202107083a7cdb5These 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.
rtl8814auis 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
Verified end-to-end with a real ARM toolchain:
8812au.ko,8821au.ko, and 9 xone modules all build clean, and the tree builds azImagestandalone fromMiSTer_defconfigwith zero warnings from the MiSTer changes. Needslz4on 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 thev6.18.38base, sosetlocalversionappends+→6.18.38+, which lands in vermagic and makes modprobe reject every module. Setting it suppresses that.modules, not justzImage— external modules link againstModule.symvers, which onlymake moduleswrites (it needs vmlinux first).modules_prepareisn'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:Parse-time filesystem work keyed off
pwd. In an in-tree buildpwdis the kernel root rather than the module directory, soTopDIRpoints at the wrong tree and the driver's generatedautoconf.hsilently 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.shbuilds 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/initinstead, 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.mdin 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.15was 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 the00xx-*.patchthat 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-idmatches 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 theloop=patch and nothing else. Separately,arch/arm/configs/MiSTer_defconfighere produces a.configbyte-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 missingDocumentation/.renames.txtrelative to kernel.org's v6.18.38 (tree4efcf6f42vsd13b0d25d) — the same.gitignore-eats-a-tracked-file effect that cost the v5.15.1 base 11 files. No build impact.git add --forceafter extracting avoids it if you ever regenerate the base.🤖 Generated with Claude Code