Skip to content

gpio: share line requests across read/write instances on the same pin#31508

Open
andig wants to merge 3 commits into
masterfrom
fix/gpio-shared-pin
Open

gpio: share line requests across read/write instances on the same pin#31508
andig wants to merge 3 commits into
masterfrom
fix/gpio-shared-pin

Conversation

@andig

@andig andig commented Jul 5, 2026

Copy link
Copy Markdown
Member

fixes #31506

PR #27815 replaced go-rpio (direct register mmap, no exclusive line ownership) with go-gpiocdev (Linux GPIO character-device uAPI, exclusive per-line requests). Any config using the same GPIO pin for both a read function and a write function - as switchsocket configs commonly do, reading back a relay's own driven state on the same pin used to switch it - now fails at startup with "failed to open GPIO: device or resource busy", since the second RequestLine call for that pin is rejected by the kernel.

  • gpio plugin instances now request lines through a shared per-(chip,pin) registry instead of each calling gpiocdev.RequestLine independently
  • a line already open for input is reconfigured to output on demand (an output line's driven value can still be read back), so whichever instance needs write access "wins" the direction while read instances keep working off the same line
  • this restores behavior equivalent to pre-Gpio plugin: Raspberry Pi 5 compatibility #27815, without reverting the Raspberry Pi 5 compatibility fix

Not unit-tested: this file is //go:build linux-only and talks to real /dev/gpiochipN hardware, consistent with it having no existing tests before this change. Verified via GOOS=linux GOARCH=arm(64) go build/vet and golangci-lint.

@andig andig added the bug Something isn't working label Jul 5, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="plugin/gpio_linux.go" line_range="40-41" />
<code_context>
+
+	key := chip + ":" + strconv.Itoa(pin)
+
+	if sl, ok := lines[key]; ok {
+		if output && !sl.isOutput {
+			if err := sl.line.Reconfigure(gpiocdev.AsOutput(0)); err != nil {
+				return nil, fmt.Errorf("failed to reconfigure GPIO: %w", err)
</code_context>
<issue_to_address>
**issue (bug_risk):** Line reconfiguration should be synchronized with sharedLine.mu to avoid races with concurrent reads/writes.

In `acquireLine`, reconfiguration of an existing line only holds `linesMu` while calling `sl.line.Reconfigure` and updating `sl.isOutput`, whereas getters/setters use `sl.mu`. This allows `Value`/`SetValue` to run concurrently with reconfiguration, risking races at the driver/kernel level. Please also hold `sl.mu` when reconfiguring (e.g., lock `sl.mu` before `Reconfigure` and updating `isOutput`) so all accesses to `sl.line` use the same mutex.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread plugin/gpio_linux.go
@andig andig added the waiting for feedback Suspended progress label Jul 5, 2026
@andig

andig commented Jul 12, 2026

Copy link
Copy Markdown
Member Author

/build

@github-actions

Copy link
Copy Markdown

✅ Build finished.

@github-actions github-actions Bot mentioned this pull request Jul 12, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working waiting for feedback Suspended progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GPIO auf Raspberry Pi 3

1 participant