@mytechtoday/augment-extensions 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/augment-extensions/coding-standards/c/CHANGELOG.md +55 -0
- package/augment-extensions/coding-standards/c/LICENSE +22 -0
- package/augment-extensions/coding-standards/c/README.md +167 -0
- package/augment-extensions/coding-standards/c/config/defaults.json +26 -0
- package/augment-extensions/coding-standards/c/config/examples/embedded.yaml +25 -0
- package/augment-extensions/coding-standards/c/config/examples/systems.json +31 -0
- package/augment-extensions/coding-standards/c/config/schema.json +244 -0
- package/augment-extensions/coding-standards/c/docs/API.md +613 -0
- package/augment-extensions/coding-standards/c/docs/CONFIGURATION.md +259 -0
- package/augment-extensions/coding-standards/c/docs/USER_GUIDE.md +567 -0
- package/augment-extensions/coding-standards/c/examples/drivers/Makefile +33 -0
- package/augment-extensions/coding-standards/c/examples/drivers/README.md +192 -0
- package/augment-extensions/coding-standards/c/examples/drivers/dma-example.c +224 -0
- package/augment-extensions/coding-standards/c/examples/drivers/example.dts +64 -0
- package/augment-extensions/coding-standards/c/examples/drivers/platform-driver.c +174 -0
- package/augment-extensions/coding-standards/c/examples/embedded/README.md +167 -0
- package/augment-extensions/coding-standards/c/examples/embedded/gpio-control.c +172 -0
- package/augment-extensions/coding-standards/c/examples/embedded/timer-isr.c +198 -0
- package/augment-extensions/coding-standards/c/examples/embedded/uart-communication.c +212 -0
- package/augment-extensions/coding-standards/c/examples/kernel/Makefile +82 -0
- package/augment-extensions/coding-standards/c/examples/kernel/README.md +168 -0
- package/augment-extensions/coding-standards/c/examples/kernel/char-device.c +198 -0
- package/augment-extensions/coding-standards/c/examples/kernel/proc-file.c +131 -0
- package/augment-extensions/coding-standards/c/examples/kernel/simple-module.c +111 -0
- package/augment-extensions/coding-standards/c/examples/legacy/Makefile +62 -0
- package/augment-extensions/coding-standards/c/examples/legacy/README.md +255 -0
- package/augment-extensions/coding-standards/c/examples/legacy/c89-to-c11-migration.c +268 -0
- package/augment-extensions/coding-standards/c/examples/legacy/compatibility-layer.c +239 -0
- package/augment-extensions/coding-standards/c/examples/networking/Makefile +35 -0
- package/augment-extensions/coding-standards/c/examples/networking/README.md +207 -0
- package/augment-extensions/coding-standards/c/examples/networking/protocol-parser.c +270 -0
- package/augment-extensions/coding-standards/c/examples/networking/tcp-server.c +197 -0
- package/augment-extensions/coding-standards/c/examples/networking/udp-multicast.c +220 -0
- package/augment-extensions/coding-standards/c/examples/realtime/Makefile +53 -0
- package/augment-extensions/coding-standards/c/examples/realtime/README.md +199 -0
- package/augment-extensions/coding-standards/c/examples/realtime/deadline-monitoring.c +260 -0
- package/augment-extensions/coding-standards/c/examples/realtime/priority-scheduling.c +258 -0
- package/augment-extensions/coding-standards/c/examples/systems/Makefile +34 -0
- package/augment-extensions/coding-standards/c/examples/systems/README.md +123 -0
- package/augment-extensions/coding-standards/c/examples/systems/ipc-pipes.c +181 -0
- package/augment-extensions/coding-standards/c/examples/systems/process-management.c +153 -0
- package/augment-extensions/coding-standards/c/examples/systems/signal-handling.c +162 -0
- package/augment-extensions/coding-standards/c/module.json +149 -0
- package/augment-extensions/coding-standards/c/rules/categories/drivers.md +635 -0
- package/augment-extensions/coding-standards/c/rules/categories/embedded.md +510 -0
- package/augment-extensions/coding-standards/c/rules/categories/kernel.md +653 -0
- package/augment-extensions/coding-standards/c/rules/categories/legacy.md +526 -0
- package/augment-extensions/coding-standards/c/rules/categories/networking.md +735 -0
- package/augment-extensions/coding-standards/c/rules/categories/realtime.md +631 -0
- package/augment-extensions/coding-standards/c/rules/categories/systems.md +586 -0
- package/augment-extensions/coding-standards/c/rules/universal/const-correctness.md +275 -0
- package/augment-extensions/coding-standards/c/rules/universal/documentation.md +251 -0
- package/augment-extensions/coding-standards/c/rules/universal/error-handling.md +250 -0
- package/augment-extensions/coding-standards/c/rules/universal/header-guards.md +254 -0
- package/augment-extensions/coding-standards/c/rules/universal/memory-safety.md +233 -0
- package/augment-extensions/coding-standards/c/rules/universal/naming.md +146 -0
- package/augment-extensions/coding-standards/c/src/conflict-detector.ts +461 -0
- package/augment-extensions/coding-standards/c/src/prompt-generator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-evaluator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-override.ts +427 -0
- package/augment-extensions/coding-standards/c/src/template-engine.ts +217 -0
- package/augment-extensions/coding-standards/c/templates/prompts/drivers.txt +191 -0
- package/augment-extensions/coding-standards/c/templates/prompts/embedded.txt +164 -0
- package/augment-extensions/coding-standards/c/templates/prompts/kernel.txt +175 -0
- package/augment-extensions/coding-standards/c/templates/prompts/legacy.txt +280 -0
- package/augment-extensions/coding-standards/c/templates/prompts/networking.txt +259 -0
- package/augment-extensions/coding-standards/c/templates/prompts/realtime.txt +219 -0
- package/augment-extensions/coding-standards/c/templates/prompts/systems.txt +147 -0
- package/augment-extensions/coding-standards/c/tests/integration/category-specific.test.ts +356 -0
- package/augment-extensions/coding-standards/c/tests/integration/end-to-end-workflow.test.ts +377 -0
- package/augment-extensions/coding-standards/c/tests/performance/benchmarks.test.ts +407 -0
- package/augment-extensions/coding-standards/c/tests/unit/config-manager.test.ts +345 -0
- package/augment-extensions/coding-standards/c/tests/unit/conflict-detector.test.ts +294 -0
- package/augment-extensions/coding-standards/c/tests/unit/prompt-generator.test.ts +174 -0
- package/augment-extensions/coding-standards/c/tests/unit/registry.test.ts +313 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-evaluator.test.ts +318 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-override.test.ts +326 -0
- package/augment-extensions/coding-standards/c/tests/unit/template-engine.test.ts +314 -0
- package/augment-extensions/coding-standards/go/CHARACTER-COUNT-REPORT.md +135 -0
- package/augment-extensions/coding-standards/go/PHASE1-COMPLETION.md +146 -0
- package/augment-extensions/coding-standards/go/PHASE4-COMPLETION.md +184 -0
- package/augment-extensions/coding-standards/go/README.md +200 -0
- package/augment-extensions/coding-standards/go/VALIDATION-CHECKLIST.md +154 -0
- package/augment-extensions/coding-standards/go/config/examples/example-cli.json +15 -0
- package/augment-extensions/coding-standards/go/config/examples/example-microservices.json +21 -0
- package/augment-extensions/coding-standards/go/config/examples/example-multi-category.yaml +24 -0
- package/augment-extensions/coding-standards/go/config/examples/example-web.json +15 -0
- package/augment-extensions/coding-standards/go/config/schema.json +110 -0
- package/augment-extensions/coding-standards/go/docs/CATEGORIES.md +221 -0
- package/augment-extensions/coding-standards/go/docs/CONFIGURATION.md +198 -0
- package/augment-extensions/coding-standards/go/docs/TROUBLESHOOTING.md +285 -0
- package/augment-extensions/coding-standards/go/examples/cli/cobra-app.go +287 -0
- package/augment-extensions/coding-standards/go/examples/cloud-native-app.go +217 -0
- package/augment-extensions/coding-standards/go/examples/devops-tool.go +250 -0
- package/augment-extensions/coding-standards/go/examples/distributed-system.go +247 -0
- package/augment-extensions/coding-standards/go/examples/microservices/grpc-service.go +253 -0
- package/augment-extensions/coding-standards/go/examples/rest-api.go +270 -0
- package/augment-extensions/coding-standards/go/examples/web/http-server.go +224 -0
- package/augment-extensions/coding-standards/go/module.json +139 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/api-versioning.md +149 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rate-limiting.md +209 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rest-api-design.md +183 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/cloud-config.md +193 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/health-checks.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/kubernetes.md +180 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/automation.md +179 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/ci-cd-integration.md +147 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/infrastructure-as-code.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/caching.md +150 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/consensus.md +187 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/event-sourcing.md +246 -0
- package/augment-extensions/coding-standards/go/rules/cli/command-parsing.md +264 -0
- package/augment-extensions/coding-standards/go/rules/cli/configuration.md +268 -0
- package/augment-extensions/coding-standards/go/rules/cli/cross-platform.md +324 -0
- package/augment-extensions/coding-standards/go/rules/microservices/distributed-tracing.md +253 -0
- package/augment-extensions/coding-standards/go/rules/microservices/grpc.md +257 -0
- package/augment-extensions/coding-standards/go/rules/microservices/metrics.md +278 -0
- package/augment-extensions/coding-standards/go/rules/microservices/service-discovery.md +249 -0
- package/augment-extensions/coding-standards/go/rules/universal/code-organization.md +221 -0
- package/augment-extensions/coding-standards/go/rules/universal/documentation.md +269 -0
- package/augment-extensions/coding-standards/go/rules/universal/performance.md +323 -0
- package/augment-extensions/coding-standards/go/rules/universal/testing.md +162 -0
- package/augment-extensions/coding-standards/go/rules/web/graceful-shutdown.md +249 -0
- package/augment-extensions/coding-standards/go/rules/web/http-handlers.md +164 -0
- package/augment-extensions/coding-standards/go/rules/web/middleware.md +234 -0
- package/augment-extensions/coding-standards/go/rules/web/routing.md +251 -0
- package/augment-extensions/coding-standards/go/templates/prompts/api.md +160 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cli.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cloud-native.md +121 -0
- package/augment-extensions/coding-standards/go/templates/prompts/devops.md +146 -0
- package/augment-extensions/coding-standards/go/templates/prompts/distributed.md +133 -0
- package/augment-extensions/coding-standards/go/templates/prompts/microservices.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/web.md +181 -0
- package/augment-extensions/coding-standards/go/tests/integration/module-integration.test.ts +164 -0
- package/augment-extensions/coding-standards/go/tests/unit/category-selection.test.ts +147 -0
- package/augment-extensions/coding-standards/go/tests/unit/module-structure.test.ts +154 -0
- package/augment-extensions/coding-standards/go/tests/validate-character-count.ps1 +13 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.ps1 +148 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.sh +135 -0
- package/cli/dist/analysis/ast-parser.d.ts +47 -0
- package/cli/dist/analysis/ast-parser.d.ts.map +1 -0
- package/cli/dist/analysis/ast-parser.js +161 -0
- package/cli/dist/analysis/ast-parser.js.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts +27 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.js +189 -0
- package/cli/dist/analysis/complexity-analyzer.js.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts +23 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.js +237 -0
- package/cli/dist/analysis/dependency-analyzer.js.map +1 -0
- package/cli/dist/analysis/index.d.ts +9 -0
- package/cli/dist/analysis/index.d.ts.map +1 -0
- package/cli/dist/analysis/index.js +25 -0
- package/cli/dist/analysis/index.js.map +1 -0
- package/cli/dist/analysis/security-scanner.d.ts +11 -0
- package/cli/dist/analysis/security-scanner.d.ts.map +1 -0
- package/cli/dist/analysis/security-scanner.js +294 -0
- package/cli/dist/analysis/security-scanner.js.map +1 -0
- package/cli/dist/analysis/types.d.ts +151 -0
- package/cli/dist/analysis/types.d.ts.map +1 -0
- package/cli/dist/analysis/types.js +6 -0
- package/cli/dist/analysis/types.js.map +1 -0
- package/cli/dist/cli.js +24 -0
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/code-analysis.d.ts +11 -0
- package/cli/dist/commands/code-analysis.d.ts.map +1 -0
- package/cli/dist/commands/code-analysis.js +412 -0
- package/cli/dist/commands/code-analysis.js.map +1 -0
- package/modules.md +99 -3
- package/package.json +14 -2
- package/cli/dist/commands/agent.d.ts +0 -37
- package/cli/dist/commands/agent.d.ts.map +0 -1
- package/cli/dist/commands/agent.js +0 -222
- package/cli/dist/commands/agent.js.map +0 -1
- package/cli/dist/commands/beads.d.ts +0 -64
- package/cli/dist/commands/beads.d.ts.map +0 -1
- package/cli/dist/commands/beads.js +0 -377
- package/cli/dist/commands/beads.js.map +0 -1
- package/cli/dist/commands/change.d.ts +0 -54
- package/cli/dist/commands/change.d.ts.map +0 -1
- package/cli/dist/commands/change.js +0 -243
- package/cli/dist/commands/change.js.map +0 -1
- package/cli/dist/commands/clean.d.ts +0 -15
- package/cli/dist/commands/clean.d.ts.map +0 -1
- package/cli/dist/commands/clean.js +0 -63
- package/cli/dist/commands/clean.js.map +0 -1
- package/cli/dist/commands/clone.d.ts +0 -15
- package/cli/dist/commands/clone.d.ts.map +0 -1
- package/cli/dist/commands/clone.js +0 -49
- package/cli/dist/commands/clone.js.map +0 -1
- package/cli/dist/commands/config.d.ts +0 -33
- package/cli/dist/commands/config.d.ts.map +0 -1
- package/cli/dist/commands/config.js +0 -166
- package/cli/dist/commands/config.js.map +0 -1
- package/cli/dist/commands/context.d.ts +0 -38
- package/cli/dist/commands/context.d.ts.map +0 -1
- package/cli/dist/commands/context.js +0 -205
- package/cli/dist/commands/context.js.map +0 -1
- package/cli/dist/commands/create.d.ts +0 -18
- package/cli/dist/commands/create.d.ts.map +0 -1
- package/cli/dist/commands/create.js +0 -178
- package/cli/dist/commands/create.js.map +0 -1
- package/cli/dist/commands/diff.d.ts +0 -19
- package/cli/dist/commands/diff.d.ts.map +0 -1
- package/cli/dist/commands/diff.js +0 -104
- package/cli/dist/commands/diff.js.map +0 -1
- package/cli/dist/commands/doctor.d.ts +0 -14
- package/cli/dist/commands/doctor.d.ts.map +0 -1
- package/cli/dist/commands/doctor.js +0 -62
- package/cli/dist/commands/doctor.js.map +0 -1
- package/cli/dist/commands/export.d.ts +0 -28
- package/cli/dist/commands/export.d.ts.map +0 -1
- package/cli/dist/commands/export.js +0 -135
- package/cli/dist/commands/export.js.map +0 -1
- package/cli/dist/commands/import.d.ts +0 -23
- package/cli/dist/commands/import.d.ts.map +0 -1
- package/cli/dist/commands/import.js +0 -118
- package/cli/dist/commands/import.js.map +0 -1
- package/cli/dist/commands/prompt.d.ts +0 -45
- package/cli/dist/commands/prompt.d.ts.map +0 -1
- package/cli/dist/commands/prompt.js +0 -223
- package/cli/dist/commands/prompt.js.map +0 -1
- package/cli/dist/commands/spec.d.ts +0 -57
- package/cli/dist/commands/spec.d.ts.map +0 -1
- package/cli/dist/commands/spec.js +0 -279
- package/cli/dist/commands/spec.js.map +0 -1
- package/cli/dist/commands/stats.d.ts +0 -18
- package/cli/dist/commands/stats.d.ts.map +0 -1
- package/cli/dist/commands/stats.js +0 -85
- package/cli/dist/commands/stats.js.map +0 -1
- package/cli/dist/commands/task.d.ts +0 -65
- package/cli/dist/commands/task.d.ts.map +0 -1
- package/cli/dist/commands/task.js +0 -282
- package/cli/dist/commands/task.js.map +0 -1
- package/cli/dist/commands/template.d.ts +0 -17
- package/cli/dist/commands/template.d.ts.map +0 -1
- package/cli/dist/commands/template.js +0 -55
- package/cli/dist/commands/template.js.map +0 -1
- package/cli/dist/utils/agent-config.d.ts +0 -129
- package/cli/dist/utils/agent-config.d.ts.map +0 -1
- package/cli/dist/utils/agent-config.js +0 -297
- package/cli/dist/utils/agent-config.js.map +0 -1
- package/cli/dist/utils/beads-graph.d.ts +0 -17
- package/cli/dist/utils/beads-graph.d.ts.map +0 -1
- package/cli/dist/utils/beads-graph.js +0 -150
- package/cli/dist/utils/beads-graph.js.map +0 -1
- package/cli/dist/utils/beads-integration.d.ts +0 -112
- package/cli/dist/utils/beads-integration.d.ts.map +0 -1
- package/cli/dist/utils/beads-integration.js +0 -312
- package/cli/dist/utils/beads-integration.js.map +0 -1
- package/cli/dist/utils/beads-reporter.d.ts +0 -17
- package/cli/dist/utils/beads-reporter.d.ts.map +0 -1
- package/cli/dist/utils/beads-reporter.js +0 -160
- package/cli/dist/utils/beads-reporter.js.map +0 -1
- package/cli/dist/utils/cache-manager.d.ts +0 -55
- package/cli/dist/utils/cache-manager.d.ts.map +0 -1
- package/cli/dist/utils/cache-manager.js +0 -150
- package/cli/dist/utils/cache-manager.js.map +0 -1
- package/cli/dist/utils/change-manager.d.ts +0 -70
- package/cli/dist/utils/change-manager.d.ts.map +0 -1
- package/cli/dist/utils/change-manager.js +0 -412
- package/cli/dist/utils/change-manager.js.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.d.ts +0 -66
- package/cli/dist/utils/config-manager-enhanced.d.ts.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.js +0 -77
- package/cli/dist/utils/config-manager-enhanced.js.map +0 -1
- package/cli/dist/utils/context-manager.d.ts +0 -96
- package/cli/dist/utils/context-manager.d.ts.map +0 -1
- package/cli/dist/utils/context-manager.js +0 -258
- package/cli/dist/utils/context-manager.js.map +0 -1
- package/cli/dist/utils/diff-engine.d.ts +0 -78
- package/cli/dist/utils/diff-engine.d.ts.map +0 -1
- package/cli/dist/utils/diff-engine.js +0 -233
- package/cli/dist/utils/diff-engine.js.map +0 -1
- package/cli/dist/utils/export-system.d.ts +0 -101
- package/cli/dist/utils/export-system.d.ts.map +0 -1
- package/cli/dist/utils/export-system.js +0 -289
- package/cli/dist/utils/export-system.js.map +0 -1
- package/cli/dist/utils/health-checker.d.ts +0 -66
- package/cli/dist/utils/health-checker.d.ts.map +0 -1
- package/cli/dist/utils/health-checker.js +0 -285
- package/cli/dist/utils/health-checker.js.map +0 -1
- package/cli/dist/utils/import-system.d.ts +0 -74
- package/cli/dist/utils/import-system.d.ts.map +0 -1
- package/cli/dist/utils/import-system.js +0 -317
- package/cli/dist/utils/import-system.js.map +0 -1
- package/cli/dist/utils/module-cloner.d.ts +0 -40
- package/cli/dist/utils/module-cloner.d.ts.map +0 -1
- package/cli/dist/utils/module-cloner.js +0 -136
- package/cli/dist/utils/module-cloner.js.map +0 -1
- package/cli/dist/utils/prompt-manager.d.ts +0 -90
- package/cli/dist/utils/prompt-manager.d.ts.map +0 -1
- package/cli/dist/utils/prompt-manager.js +0 -302
- package/cli/dist/utils/prompt-manager.js.map +0 -1
- package/cli/dist/utils/spec-manager.d.ts +0 -65
- package/cli/dist/utils/spec-manager.d.ts.map +0 -1
- package/cli/dist/utils/spec-manager.js +0 -329
- package/cli/dist/utils/spec-manager.js.map +0 -1
- package/cli/dist/utils/stats-collector.d.ts +0 -74
- package/cli/dist/utils/stats-collector.d.ts.map +0 -1
- package/cli/dist/utils/stats-collector.js +0 -164
- package/cli/dist/utils/stats-collector.js.map +0 -1
- package/cli/dist/utils/template-engine.d.ts +0 -47
- package/cli/dist/utils/template-engine.d.ts.map +0 -1
- package/cli/dist/utils/template-engine.js +0 -204
- package/cli/dist/utils/template-engine.js.map +0 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Device Drivers Examples
|
|
2
|
+
|
|
3
|
+
This directory contains Linux device driver examples demonstrating advanced driver development.
|
|
4
|
+
|
|
5
|
+
## Examples
|
|
6
|
+
|
|
7
|
+
### 1. platform-driver.c
|
|
8
|
+
Platform device driver with device tree support:
|
|
9
|
+
- Platform driver registration
|
|
10
|
+
- Device tree binding and parsing
|
|
11
|
+
- Resource management with devm_* functions
|
|
12
|
+
- Probe and remove functions
|
|
13
|
+
- Memory-mapped I/O
|
|
14
|
+
|
|
15
|
+
**Key Concepts:**
|
|
16
|
+
- Use `devm_*` functions for automatic cleanup
|
|
17
|
+
- Parse device tree properties
|
|
18
|
+
- Handle resources (memory, IRQ)
|
|
19
|
+
- Proper error handling in probe
|
|
20
|
+
|
|
21
|
+
### 2. dma-example.c
|
|
22
|
+
DMA (Direct Memory Access) usage:
|
|
23
|
+
- Coherent DMA allocation
|
|
24
|
+
- Streaming DMA mapping
|
|
25
|
+
- DMA direction handling
|
|
26
|
+
- DMA mask configuration
|
|
27
|
+
- Proper cleanup
|
|
28
|
+
|
|
29
|
+
**Key Concepts:**
|
|
30
|
+
- Choose coherent vs streaming DMA appropriately
|
|
31
|
+
- Always check `dma_mapping_error()`
|
|
32
|
+
- Unmap before freeing buffers
|
|
33
|
+
- Set appropriate DMA mask
|
|
34
|
+
|
|
35
|
+
### 3. example.dts
|
|
36
|
+
Device tree source file:
|
|
37
|
+
- Device node definitions
|
|
38
|
+
- Register address mapping
|
|
39
|
+
- Interrupt configuration
|
|
40
|
+
- DMA bindings
|
|
41
|
+
- Custom properties
|
|
42
|
+
|
|
43
|
+
## Building
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Build all drivers
|
|
47
|
+
make
|
|
48
|
+
|
|
49
|
+
# Build device tree blob
|
|
50
|
+
make dtb
|
|
51
|
+
|
|
52
|
+
# Clean
|
|
53
|
+
make clean
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Device Tree
|
|
57
|
+
|
|
58
|
+
### Compiling Device Tree
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Compile DTS to DTB
|
|
62
|
+
dtc -I dts -O dtb -o example.dtb example.dts
|
|
63
|
+
|
|
64
|
+
# Decompile DTB to DTS
|
|
65
|
+
dtc -I dtb -O dts -o example.dts example.dtb
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Device Tree Properties
|
|
69
|
+
|
|
70
|
+
```dts
|
|
71
|
+
example_device@40000000 {
|
|
72
|
+
compatible = "example,platform-device"; /* Driver matching */
|
|
73
|
+
reg = <0x40000000 0x1000>; /* Base addr, size */
|
|
74
|
+
interrupts = <0 32 4>; /* IRQ configuration */
|
|
75
|
+
status = "okay"; /* Enable device */
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Loading and Testing
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Load drivers
|
|
83
|
+
sudo insmod platform-driver.ko
|
|
84
|
+
sudo insmod dma-example.ko
|
|
85
|
+
|
|
86
|
+
# Check kernel logs
|
|
87
|
+
dmesg | tail -30
|
|
88
|
+
|
|
89
|
+
# List loaded modules
|
|
90
|
+
lsmod | grep -E 'platform|dma'
|
|
91
|
+
|
|
92
|
+
# Unload drivers
|
|
93
|
+
sudo rmmod dma-example
|
|
94
|
+
sudo rmmod platform-driver
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## DMA Usage Guidelines
|
|
98
|
+
|
|
99
|
+
### Coherent DMA
|
|
100
|
+
Use for buffers accessed simultaneously by CPU and device:
|
|
101
|
+
```c
|
|
102
|
+
void *buf = dma_alloc_coherent(dev, size, &dma_handle, GFP_KERNEL);
|
|
103
|
+
/* Use buffer */
|
|
104
|
+
dma_free_coherent(dev, size, buf, dma_handle);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Streaming DMA
|
|
108
|
+
Use for one-directional transfers:
|
|
109
|
+
```c
|
|
110
|
+
void *buf = kmalloc(size, GFP_KERNEL);
|
|
111
|
+
dma_addr_t dma_handle = dma_map_single(dev, buf, size, DMA_TO_DEVICE);
|
|
112
|
+
if (dma_mapping_error(dev, dma_handle)) { /* error */ }
|
|
113
|
+
/* Transfer data */
|
|
114
|
+
dma_unmap_single(dev, dma_handle, size, DMA_TO_DEVICE);
|
|
115
|
+
kfree(buf);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### DMA Directions
|
|
119
|
+
- `DMA_TO_DEVICE`: CPU writes, device reads
|
|
120
|
+
- `DMA_FROM_DEVICE`: Device writes, CPU reads
|
|
121
|
+
- `DMA_BIDIRECTIONAL`: Both directions
|
|
122
|
+
|
|
123
|
+
## Best Practices
|
|
124
|
+
|
|
125
|
+
1. **Resource Management**
|
|
126
|
+
- Use `devm_*` functions when possible
|
|
127
|
+
- Clean up in reverse order of allocation
|
|
128
|
+
- Handle all error paths
|
|
129
|
+
|
|
130
|
+
2. **DMA Safety**
|
|
131
|
+
- Always check `dma_mapping_error()`
|
|
132
|
+
- Set appropriate DMA mask
|
|
133
|
+
- Unmap before freeing
|
|
134
|
+
- Use correct DMA direction
|
|
135
|
+
|
|
136
|
+
3. **Device Tree**
|
|
137
|
+
- Use standard property names
|
|
138
|
+
- Document custom properties
|
|
139
|
+
- Validate in driver code
|
|
140
|
+
|
|
141
|
+
4. **Error Handling**
|
|
142
|
+
- Return appropriate error codes
|
|
143
|
+
- Log errors with `dev_err()`
|
|
144
|
+
- Clean up on failure
|
|
145
|
+
|
|
146
|
+
## Common Pitfalls
|
|
147
|
+
|
|
148
|
+
1. **Missing DMA Unmap**
|
|
149
|
+
```c
|
|
150
|
+
// WRONG
|
|
151
|
+
dma_addr = dma_map_single(dev, buf, size, DMA_TO_DEVICE);
|
|
152
|
+
kfree(buf); // Forgot to unmap!
|
|
153
|
+
|
|
154
|
+
// CORRECT
|
|
155
|
+
dma_addr = dma_map_single(dev, buf, size, DMA_TO_DEVICE);
|
|
156
|
+
dma_unmap_single(dev, dma_addr, size, DMA_TO_DEVICE);
|
|
157
|
+
kfree(buf);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
2. **Wrong DMA Direction**
|
|
161
|
+
```c
|
|
162
|
+
// WRONG - Device writes to buffer
|
|
163
|
+
dma_map_single(dev, buf, size, DMA_TO_DEVICE);
|
|
164
|
+
|
|
165
|
+
// CORRECT
|
|
166
|
+
dma_map_single(dev, buf, size, DMA_FROM_DEVICE);
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
3. **Incomplete Cleanup**
|
|
170
|
+
```c
|
|
171
|
+
// WRONG
|
|
172
|
+
static int probe(struct platform_device *pdev) {
|
|
173
|
+
base = devm_ioremap_resource(&pdev->dev, res);
|
|
174
|
+
data = kmalloc(size, GFP_KERNEL); // Not devm!
|
|
175
|
+
return 0; // Memory leak on driver removal
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// CORRECT
|
|
179
|
+
static int probe(struct platform_device *pdev) {
|
|
180
|
+
base = devm_ioremap_resource(&pdev->dev, res);
|
|
181
|
+
data = devm_kmalloc(&pdev->dev, size, GFP_KERNEL);
|
|
182
|
+
return 0; // Auto-freed on removal
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## References
|
|
187
|
+
|
|
188
|
+
- Linux Device Drivers (LDD3)
|
|
189
|
+
- Linux Kernel DMA API: Documentation/core-api/dma-api.rst
|
|
190
|
+
- Device Tree Specification: https://www.devicetree.org/
|
|
191
|
+
- Platform Devices: Documentation/driver-api/driver-model/platform.rst
|
|
192
|
+
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file dma-example.c
|
|
3
|
+
* @brief Example DMA (Direct Memory Access) usage in Linux kernel
|
|
4
|
+
*
|
|
5
|
+
* This example demonstrates:
|
|
6
|
+
* - DMA buffer allocation
|
|
7
|
+
* - DMA mapping and unmapping
|
|
8
|
+
* - Coherent vs streaming DMA
|
|
9
|
+
* - DMA direction handling
|
|
10
|
+
* - Proper cleanup
|
|
11
|
+
*
|
|
12
|
+
* Build: make
|
|
13
|
+
* Load: sudo insmod dma-example.ko
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#include <linux/module.h>
|
|
17
|
+
#include <linux/kernel.h>
|
|
18
|
+
#include <linux/platform_device.h>
|
|
19
|
+
#include <linux/dma-mapping.h>
|
|
20
|
+
#include <linux/slab.h>
|
|
21
|
+
|
|
22
|
+
MODULE_LICENSE("GPL");
|
|
23
|
+
MODULE_AUTHOR("Example Author");
|
|
24
|
+
MODULE_DESCRIPTION("Example DMA usage driver");
|
|
25
|
+
MODULE_VERSION("1.0");
|
|
26
|
+
|
|
27
|
+
#define DMA_BUFFER_SIZE 4096
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @brief Device private data
|
|
31
|
+
*/
|
|
32
|
+
struct dma_device {
|
|
33
|
+
struct device *dev;
|
|
34
|
+
|
|
35
|
+
/* Coherent DMA buffer */
|
|
36
|
+
void *coherent_buffer;
|
|
37
|
+
dma_addr_t coherent_dma_handle;
|
|
38
|
+
|
|
39
|
+
/* Streaming DMA buffer */
|
|
40
|
+
void *streaming_buffer;
|
|
41
|
+
dma_addr_t streaming_dma_handle;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @brief Example: Allocate and use coherent DMA buffer
|
|
46
|
+
*
|
|
47
|
+
* Coherent DMA is used for buffers shared between CPU and device
|
|
48
|
+
* that need to be accessed simultaneously.
|
|
49
|
+
*/
|
|
50
|
+
static int coherent_dma_example(struct dma_device *dma_dev)
|
|
51
|
+
{
|
|
52
|
+
dev_info(dma_dev->dev, "Allocating coherent DMA buffer\n");
|
|
53
|
+
|
|
54
|
+
/* Allocate coherent DMA buffer */
|
|
55
|
+
dma_dev->coherent_buffer = dma_alloc_coherent(dma_dev->dev,
|
|
56
|
+
DMA_BUFFER_SIZE,
|
|
57
|
+
&dma_dev->coherent_dma_handle,
|
|
58
|
+
GFP_KERNEL);
|
|
59
|
+
if (!dma_dev->coherent_buffer) {
|
|
60
|
+
dev_err(dma_dev->dev, "Failed to allocate coherent DMA buffer\n");
|
|
61
|
+
return -ENOMEM;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
dev_info(dma_dev->dev, "Coherent DMA buffer allocated\n");
|
|
65
|
+
dev_info(dma_dev->dev, "Virtual address: %p\n", dma_dev->coherent_buffer);
|
|
66
|
+
dev_info(dma_dev->dev, "DMA address: 0x%llx\n",
|
|
67
|
+
(unsigned long long)dma_dev->coherent_dma_handle);
|
|
68
|
+
|
|
69
|
+
/* Use the buffer - CPU can write directly */
|
|
70
|
+
memset(dma_dev->coherent_buffer, 0xAA, DMA_BUFFER_SIZE);
|
|
71
|
+
|
|
72
|
+
/* Program device with DMA address */
|
|
73
|
+
/* Example: writel(dma_dev->coherent_dma_handle, device_dma_addr_reg); */
|
|
74
|
+
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @brief Example: Allocate and use streaming DMA buffer
|
|
80
|
+
*
|
|
81
|
+
* Streaming DMA is used for one-directional transfers where
|
|
82
|
+
* CPU and device don't access the buffer simultaneously.
|
|
83
|
+
*/
|
|
84
|
+
static int streaming_dma_example(struct dma_device *dma_dev)
|
|
85
|
+
{
|
|
86
|
+
dev_info(dma_dev->dev, "Setting up streaming DMA\n");
|
|
87
|
+
|
|
88
|
+
/* Allocate regular kernel memory */
|
|
89
|
+
dma_dev->streaming_buffer = kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL);
|
|
90
|
+
if (!dma_dev->streaming_buffer) {
|
|
91
|
+
dev_err(dma_dev->dev, "Failed to allocate streaming buffer\n");
|
|
92
|
+
return -ENOMEM;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Fill buffer with data */
|
|
96
|
+
memset(dma_dev->streaming_buffer, 0x55, DMA_BUFFER_SIZE);
|
|
97
|
+
|
|
98
|
+
/* Map buffer for DMA (device will read from it) */
|
|
99
|
+
dma_dev->streaming_dma_handle = dma_map_single(dma_dev->dev,
|
|
100
|
+
dma_dev->streaming_buffer,
|
|
101
|
+
DMA_BUFFER_SIZE,
|
|
102
|
+
DMA_TO_DEVICE);
|
|
103
|
+
|
|
104
|
+
if (dma_mapping_error(dma_dev->dev, dma_dev->streaming_dma_handle)) {
|
|
105
|
+
dev_err(dma_dev->dev, "Failed to map streaming DMA buffer\n");
|
|
106
|
+
kfree(dma_dev->streaming_buffer);
|
|
107
|
+
dma_dev->streaming_buffer = NULL;
|
|
108
|
+
return -ENOMEM;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
dev_info(dma_dev->dev, "Streaming DMA buffer mapped\n");
|
|
112
|
+
dev_info(dma_dev->dev, "DMA address: 0x%llx\n",
|
|
113
|
+
(unsigned long long)dma_dev->streaming_dma_handle);
|
|
114
|
+
|
|
115
|
+
/* Program device with DMA address */
|
|
116
|
+
/* Example: writel(dma_dev->streaming_dma_handle, device_dma_addr_reg); */
|
|
117
|
+
|
|
118
|
+
/* Start DMA transfer */
|
|
119
|
+
/* Example: writel(DMA_START, device_control_reg); */
|
|
120
|
+
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @brief Cleanup coherent DMA resources
|
|
126
|
+
*/
|
|
127
|
+
static void cleanup_coherent_dma(struct dma_device *dma_dev)
|
|
128
|
+
{
|
|
129
|
+
if (dma_dev->coherent_buffer) {
|
|
130
|
+
dma_free_coherent(dma_dev->dev,
|
|
131
|
+
DMA_BUFFER_SIZE,
|
|
132
|
+
dma_dev->coherent_buffer,
|
|
133
|
+
dma_dev->coherent_dma_handle);
|
|
134
|
+
dma_dev->coherent_buffer = NULL;
|
|
135
|
+
dev_info(dma_dev->dev, "Coherent DMA buffer freed\n");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @brief Cleanup streaming DMA resources
|
|
141
|
+
*/
|
|
142
|
+
static void cleanup_streaming_dma(struct dma_device *dma_dev)
|
|
143
|
+
{
|
|
144
|
+
if (dma_dev->streaming_buffer) {
|
|
145
|
+
/* Unmap DMA buffer */
|
|
146
|
+
dma_unmap_single(dma_dev->dev,
|
|
147
|
+
dma_dev->streaming_dma_handle,
|
|
148
|
+
DMA_BUFFER_SIZE,
|
|
149
|
+
DMA_TO_DEVICE);
|
|
150
|
+
|
|
151
|
+
/* Free kernel memory */
|
|
152
|
+
kfree(dma_dev->streaming_buffer);
|
|
153
|
+
dma_dev->streaming_buffer = NULL;
|
|
154
|
+
dev_info(dma_dev->dev, "Streaming DMA buffer freed\n");
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @brief Platform driver probe function
|
|
160
|
+
*/
|
|
161
|
+
static int dma_probe(struct platform_device *pdev)
|
|
162
|
+
{
|
|
163
|
+
struct dma_device *dma_dev;
|
|
164
|
+
int ret;
|
|
165
|
+
|
|
166
|
+
dev_info(&pdev->dev, "Probing DMA example device\n");
|
|
167
|
+
|
|
168
|
+
/* Allocate private data */
|
|
169
|
+
dma_dev = devm_kzalloc(&pdev->dev, sizeof(*dma_dev), GFP_KERNEL);
|
|
170
|
+
if (!dma_dev)
|
|
171
|
+
return -ENOMEM;
|
|
172
|
+
|
|
173
|
+
dma_dev->dev = &pdev->dev;
|
|
174
|
+
platform_set_drvdata(pdev, dma_dev);
|
|
175
|
+
|
|
176
|
+
/* Set DMA mask (32-bit addressing) */
|
|
177
|
+
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
|
|
178
|
+
if (ret) {
|
|
179
|
+
dev_err(&pdev->dev, "Failed to set DMA mask\n");
|
|
180
|
+
return ret;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Example 1: Coherent DMA */
|
|
184
|
+
ret = coherent_dma_example(dma_dev);
|
|
185
|
+
if (ret)
|
|
186
|
+
return ret;
|
|
187
|
+
|
|
188
|
+
/* Example 2: Streaming DMA */
|
|
189
|
+
ret = streaming_dma_example(dma_dev);
|
|
190
|
+
if (ret) {
|
|
191
|
+
cleanup_coherent_dma(dma_dev);
|
|
192
|
+
return ret;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
dev_info(&pdev->dev, "DMA example device probed successfully\n");
|
|
196
|
+
return 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @brief Platform driver remove function
|
|
201
|
+
*/
|
|
202
|
+
static int dma_remove(struct platform_device *pdev)
|
|
203
|
+
{
|
|
204
|
+
struct dma_device *dma_dev = platform_get_drvdata(pdev);
|
|
205
|
+
|
|
206
|
+
dev_info(&pdev->dev, "Removing DMA example device\n");
|
|
207
|
+
|
|
208
|
+
cleanup_streaming_dma(dma_dev);
|
|
209
|
+
cleanup_coherent_dma(dma_dev);
|
|
210
|
+
|
|
211
|
+
dev_info(&pdev->dev, "DMA example device removed\n");
|
|
212
|
+
return 0;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
static struct platform_driver dma_driver = {
|
|
216
|
+
.probe = dma_probe,
|
|
217
|
+
.remove = dma_remove,
|
|
218
|
+
.driver = {
|
|
219
|
+
.name = "dma-example",
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
module_platform_driver(dma_driver);
|
|
224
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file example.dts
|
|
3
|
+
* @brief Example Device Tree Source for platform driver
|
|
4
|
+
*
|
|
5
|
+
* This file demonstrates device tree bindings for the platform driver.
|
|
6
|
+
*
|
|
7
|
+
* To compile:
|
|
8
|
+
* dtc -I dts -O dtb -o example.dtb example.dts
|
|
9
|
+
*
|
|
10
|
+
* To decompile:
|
|
11
|
+
* dtc -I dtb -O dts -o example.dts example.dtb
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/dts-v1/;
|
|
15
|
+
|
|
16
|
+
/ {
|
|
17
|
+
model = "Example Platform";
|
|
18
|
+
compatible = "example,platform";
|
|
19
|
+
#address-cells = <1>;
|
|
20
|
+
#size-cells = <1>;
|
|
21
|
+
|
|
22
|
+
/* Example platform device */
|
|
23
|
+
example_device@40000000 {
|
|
24
|
+
compatible = "example,platform-device";
|
|
25
|
+
reg = <0x40000000 0x1000>; /* Base address and size */
|
|
26
|
+
interrupts = <0 32 4>; /* IRQ number and flags */
|
|
27
|
+
status = "okay";
|
|
28
|
+
|
|
29
|
+
/* Custom properties */
|
|
30
|
+
clock-frequency = <50000000>;
|
|
31
|
+
device-id = <0>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/* Another example device */
|
|
35
|
+
example_device@40001000 {
|
|
36
|
+
compatible = "example,platform-device";
|
|
37
|
+
reg = <0x40001000 0x1000>;
|
|
38
|
+
interrupts = <0 33 4>;
|
|
39
|
+
status = "okay";
|
|
40
|
+
|
|
41
|
+
clock-frequency = <50000000>;
|
|
42
|
+
device-id = <1>;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/* DMA controller example */
|
|
46
|
+
dma_controller@40002000 {
|
|
47
|
+
compatible = "example,dma-controller";
|
|
48
|
+
reg = <0x40002000 0x1000>;
|
|
49
|
+
interrupts = <0 34 4>;
|
|
50
|
+
#dma-cells = <1>;
|
|
51
|
+
status = "okay";
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/* Device using DMA */
|
|
55
|
+
uart@40003000 {
|
|
56
|
+
compatible = "example,uart";
|
|
57
|
+
reg = <0x40003000 0x100>;
|
|
58
|
+
interrupts = <0 35 4>;
|
|
59
|
+
dmas = <&dma_controller 0>;
|
|
60
|
+
dma-names = "tx-rx";
|
|
61
|
+
status = "okay";
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file platform-driver.c
|
|
3
|
+
* @brief Example Linux platform device driver
|
|
4
|
+
*
|
|
5
|
+
* This example demonstrates:
|
|
6
|
+
* - Platform driver registration
|
|
7
|
+
* - Device tree binding
|
|
8
|
+
* - Probe and remove functions
|
|
9
|
+
* - Resource management (devm_* functions)
|
|
10
|
+
* - Platform device matching
|
|
11
|
+
*
|
|
12
|
+
* Device Tree Example:
|
|
13
|
+
* example_device {
|
|
14
|
+
* compatible = "example,platform-device";
|
|
15
|
+
* reg = <0x40000000 0x1000>;
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* Build: make
|
|
19
|
+
* Load: sudo insmod platform-driver.ko
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
#include <linux/module.h>
|
|
23
|
+
#include <linux/kernel.h>
|
|
24
|
+
#include <linux/platform_device.h>
|
|
25
|
+
#include <linux/of.h>
|
|
26
|
+
#include <linux/io.h>
|
|
27
|
+
#include <linux/slab.h>
|
|
28
|
+
|
|
29
|
+
MODULE_LICENSE("GPL");
|
|
30
|
+
MODULE_AUTHOR("Example Author");
|
|
31
|
+
MODULE_DESCRIPTION("Example platform device driver");
|
|
32
|
+
MODULE_VERSION("1.0");
|
|
33
|
+
|
|
34
|
+
#define DRIVER_NAME "example-platform"
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @brief Private device data structure
|
|
38
|
+
*/
|
|
39
|
+
struct example_device {
|
|
40
|
+
void __iomem *base;
|
|
41
|
+
struct device *dev;
|
|
42
|
+
int irq;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @brief Platform driver probe function
|
|
47
|
+
* @param pdev Platform device
|
|
48
|
+
* @return 0 on success, negative error code on failure
|
|
49
|
+
*/
|
|
50
|
+
static int example_probe(struct platform_device *pdev)
|
|
51
|
+
{
|
|
52
|
+
struct example_device *priv;
|
|
53
|
+
struct resource *res;
|
|
54
|
+
int ret;
|
|
55
|
+
|
|
56
|
+
dev_info(&pdev->dev, "Probing device\n");
|
|
57
|
+
|
|
58
|
+
/* Allocate private data using devm (auto-freed on remove) */
|
|
59
|
+
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
|
60
|
+
if (!priv)
|
|
61
|
+
return -ENOMEM;
|
|
62
|
+
|
|
63
|
+
priv->dev = &pdev->dev;
|
|
64
|
+
|
|
65
|
+
/* Get memory resource from device tree or platform data */
|
|
66
|
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
67
|
+
if (!res) {
|
|
68
|
+
dev_err(&pdev->dev, "Failed to get memory resource\n");
|
|
69
|
+
return -ENODEV;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* Map device registers (auto-unmapped on remove) */
|
|
73
|
+
priv->base = devm_ioremap_resource(&pdev->dev, res);
|
|
74
|
+
if (IS_ERR(priv->base)) {
|
|
75
|
+
dev_err(&pdev->dev, "Failed to map registers\n");
|
|
76
|
+
return PTR_ERR(priv->base);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* Get IRQ (optional) */
|
|
80
|
+
priv->irq = platform_get_irq(pdev, 0);
|
|
81
|
+
if (priv->irq < 0) {
|
|
82
|
+
dev_warn(&pdev->dev, "No IRQ specified\n");
|
|
83
|
+
priv->irq = -1;
|
|
84
|
+
} else {
|
|
85
|
+
dev_info(&pdev->dev, "IRQ: %d\n", priv->irq);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Store private data in platform device */
|
|
89
|
+
platform_set_drvdata(pdev, priv);
|
|
90
|
+
|
|
91
|
+
/* Initialize hardware */
|
|
92
|
+
/* Example: Write to control register */
|
|
93
|
+
/* iowrite32(0x1, priv->base + CTRL_REG_OFFSET); */
|
|
94
|
+
|
|
95
|
+
dev_info(&pdev->dev, "Device probed successfully\n");
|
|
96
|
+
dev_info(&pdev->dev, "Base address: %p\n", priv->base);
|
|
97
|
+
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @brief Platform driver remove function
|
|
103
|
+
* @param pdev Platform device
|
|
104
|
+
* @return 0 on success
|
|
105
|
+
*/
|
|
106
|
+
static int example_remove(struct platform_device *pdev)
|
|
107
|
+
{
|
|
108
|
+
struct example_device *priv = platform_get_drvdata(pdev);
|
|
109
|
+
|
|
110
|
+
dev_info(&pdev->dev, "Removing device\n");
|
|
111
|
+
|
|
112
|
+
/* Shutdown hardware */
|
|
113
|
+
/* Example: Disable device */
|
|
114
|
+
/* iowrite32(0x0, priv->base + CTRL_REG_OFFSET); */
|
|
115
|
+
|
|
116
|
+
/* Resources allocated with devm_* are automatically freed */
|
|
117
|
+
|
|
118
|
+
dev_info(&pdev->dev, "Device removed\n");
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @brief Device tree match table
|
|
124
|
+
*/
|
|
125
|
+
static const struct of_device_id example_of_match[] = {
|
|
126
|
+
{ .compatible = "example,platform-device", },
|
|
127
|
+
{ /* sentinel */ }
|
|
128
|
+
};
|
|
129
|
+
MODULE_DEVICE_TABLE(of, example_of_match);
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @brief Platform driver structure
|
|
133
|
+
*/
|
|
134
|
+
static struct platform_driver example_driver = {
|
|
135
|
+
.probe = example_probe,
|
|
136
|
+
.remove = example_remove,
|
|
137
|
+
.driver = {
|
|
138
|
+
.name = DRIVER_NAME,
|
|
139
|
+
.of_match_table = example_of_match,
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @brief Module initialization
|
|
145
|
+
*/
|
|
146
|
+
static int __init example_init(void)
|
|
147
|
+
{
|
|
148
|
+
int ret;
|
|
149
|
+
|
|
150
|
+
pr_info("example_platform: Registering platform driver\n");
|
|
151
|
+
|
|
152
|
+
ret = platform_driver_register(&example_driver);
|
|
153
|
+
if (ret) {
|
|
154
|
+
pr_err("example_platform: Failed to register driver\n");
|
|
155
|
+
return ret;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
pr_info("example_platform: Driver registered\n");
|
|
159
|
+
return 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @brief Module cleanup
|
|
164
|
+
*/
|
|
165
|
+
static void __exit example_exit(void)
|
|
166
|
+
{
|
|
167
|
+
pr_info("example_platform: Unregistering platform driver\n");
|
|
168
|
+
platform_driver_unregister(&example_driver);
|
|
169
|
+
pr_info("example_platform: Driver unregistered\n");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module_init(example_init);
|
|
173
|
+
module_exit(example_exit);
|
|
174
|
+
|