1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <memory>
6
7 #include <assert.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 #include <ddk/binding.h>
13 #include <ddk/debug.h>
14 #include <ddk/device.h>
15 #include <ddk/driver.h>
16 #include <ddk/platform-defs.h>
17 #include <ddk/protocol/platform/bus.h>
18
19 #include <zircon/process.h>
20 #include <zircon/syscalls.h>
21 #include <zircon/assert.h>
22
23 #include "test.h"
24 #include "test-resources.h"
25
26 namespace board_test {
27
DdkRelease()28 void TestBoard::DdkRelease() {
29 delete this;
30 }
31
Thread()32 int TestBoard::Thread() {
33 zx_status_t status;
34
35 status = GpioInit();
36 if (status != ZX_OK) {
37 zxlogf(ERROR, "%s: GpioInit failed: %d\n", __func__, status);
38 }
39
40 status = TestInit();
41 if (status != ZX_OK) {
42 zxlogf(ERROR, "%s: TestInit failed: %d\n", __func__, status);
43 }
44 return 0;
45 }
46
Start()47 zx_status_t TestBoard::Start() {
48 int rc = thrd_create_with_name(&thread_,
49 [](void* arg) -> int {
50 return reinterpret_cast<TestBoard*>(arg)->Thread();
51 },
52 this,
53 "test-board-start-thread");
54 if (rc != thrd_success) {
55 return ZX_ERR_INTERNAL;
56 }
57 return ZX_OK;
58 }
59
Create(zx_device_t * parent)60 zx_status_t TestBoard::Create(zx_device_t* parent) {
61 pbus_protocol_t pbus;
62 if (device_get_protocol(parent, ZX_PROTOCOL_PBUS, &pbus) != ZX_OK) {
63 return ZX_ERR_NOT_SUPPORTED;
64 }
65
66 auto board = std::make_unique<TestBoard>(parent, &pbus);
67
68 zx_status_t status = board->DdkAdd("test-board", DEVICE_ADD_NON_BINDABLE);
69 if (status != ZX_OK) {
70 zxlogf(ERROR, "TestBoard::Create: DdkAdd failed: %d\n", status);
71 return status;
72 }
73
74 status = board->Start();
75 if (status == ZX_OK) {
76 // devmgr is now in charge of the device.
77 __UNUSED auto* dummy = board.release();
78 }
79
80 return status;
81 }
82
test_bind(void * ctx,zx_device_t * parent)83 zx_status_t test_bind(void* ctx, zx_device_t* parent) {
84 return TestBoard::Create(parent);
85 }
86
__anone9525d590202()87 static zx_driver_ops_t driver_ops = [](){
88 zx_driver_ops_t ops;
89 ops.version = DRIVER_OPS_VERSION;
90 ops.bind = test_bind;
91 return ops;
92 }();
93
94 } // namespace board_test
95
96 ZIRCON_DRIVER_BEGIN(test_bus, board_test::driver_ops, "zircon", "0.1", 3)
97 BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PBUS),
98 BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_TEST),
99 BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_PBUS_TEST),
100 ZIRCON_DRIVER_END(test_bus)
101