Commit 5e1ff6480fbe7cf1b2be1f8a13086b217b2f8578

Authored by Simon Glass
1 parent ac206a0f4e

dm: mailbox: Update uclass to support livetree

Update the mailbox uclass to support livetree. Fix the xlate() method
in all callers.

Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 3 changed files with 10 additions and 14 deletions Inline Diff

drivers/mailbox/mailbox-uclass.c
1 /* 1 /*
2 * Copyright (c) 2016, NVIDIA CORPORATION. 2 * Copyright (c) 2016, NVIDIA CORPORATION.
3 * 3 *
4 * SPDX-License-Identifier: GPL-2.0 4 * SPDX-License-Identifier: GPL-2.0
5 */ 5 */
6 6
7 #include <common.h> 7 #include <common.h>
8 #include <dm.h> 8 #include <dm.h>
9 #include <fdtdec.h>
10 #include <mailbox.h> 9 #include <mailbox.h>
11 #include <mailbox-uclass.h> 10 #include <mailbox-uclass.h>
12 11
13 DECLARE_GLOBAL_DATA_PTR; 12 DECLARE_GLOBAL_DATA_PTR;
14 13
15 static inline struct mbox_ops *mbox_dev_ops(struct udevice *dev) 14 static inline struct mbox_ops *mbox_dev_ops(struct udevice *dev)
16 { 15 {
17 return (struct mbox_ops *)dev->driver->ops; 16 return (struct mbox_ops *)dev->driver->ops;
18 } 17 }
19 18
20 static int mbox_of_xlate_default(struct mbox_chan *chan, 19 static int mbox_of_xlate_default(struct mbox_chan *chan,
21 struct fdtdec_phandle_args *args) 20 struct ofnode_phandle_args *args)
22 { 21 {
23 debug("%s(chan=%p)\n", __func__, chan); 22 debug("%s(chan=%p)\n", __func__, chan);
24 23
25 if (args->args_count != 1) { 24 if (args->args_count != 1) {
26 debug("Invaild args_count: %d\n", args->args_count); 25 debug("Invaild args_count: %d\n", args->args_count);
27 return -EINVAL; 26 return -EINVAL;
28 } 27 }
29 28
30 chan->id = args->args[0]; 29 chan->id = args->args[0];
31 30
32 return 0; 31 return 0;
33 } 32 }
34 33
35 int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan) 34 int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan)
36 { 35 {
37 struct fdtdec_phandle_args args; 36 struct ofnode_phandle_args args;
38 int ret; 37 int ret;
39 struct udevice *dev_mbox; 38 struct udevice *dev_mbox;
40 struct mbox_ops *ops; 39 struct mbox_ops *ops;
41 40
42 debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan); 41 debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan);
43 42
44 ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), 43 ret = dev_read_phandle_with_args(dev, "mboxes", "#mbox-cells", 0, index,
45 "mboxes", "#mbox-cells", 0, 44 &args);
46 index, &args);
47 if (ret) { 45 if (ret) {
48 debug("%s: fdtdec_parse_phandle_with_args failed: %d\n", 46 debug("%s: dev_read_phandle_with_args failed: %d\n", __func__,
49 __func__, ret); 47 ret);
50 return ret; 48 return ret;
51 } 49 }
52 50
53 ret = uclass_get_device_by_of_offset(UCLASS_MAILBOX, args.node, 51 ret = uclass_get_device_by_ofnode(UCLASS_MAILBOX, args.node, &dev_mbox);
54 &dev_mbox);
55 if (ret) { 52 if (ret) {
56 debug("%s: uclass_get_device_by_of_offset failed: %d\n", 53 debug("%s: uclass_get_device_by_of_offset failed: %d\n",
57 __func__, ret); 54 __func__, ret);
58 return ret; 55 return ret;
59 } 56 }
60 ops = mbox_dev_ops(dev_mbox); 57 ops = mbox_dev_ops(dev_mbox);
61 58
62 chan->dev = dev_mbox; 59 chan->dev = dev_mbox;
63 if (ops->of_xlate) 60 if (ops->of_xlate)
64 ret = ops->of_xlate(chan, &args); 61 ret = ops->of_xlate(chan, &args);
65 else 62 else
66 ret = mbox_of_xlate_default(chan, &args); 63 ret = mbox_of_xlate_default(chan, &args);
67 if (ret) { 64 if (ret) {
68 debug("of_xlate() failed: %d\n", ret); 65 debug("of_xlate() failed: %d\n", ret);
69 return ret; 66 return ret;
70 } 67 }
71 68
72 ret = ops->request(chan); 69 ret = ops->request(chan);
73 if (ret) { 70 if (ret) {
74 debug("ops->request() failed: %d\n", ret); 71 debug("ops->request() failed: %d\n", ret);
75 return ret; 72 return ret;
76 } 73 }
77 74
78 return 0; 75 return 0;
79 } 76 }
80 77
81 int mbox_get_by_name(struct udevice *dev, const char *name, 78 int mbox_get_by_name(struct udevice *dev, const char *name,
82 struct mbox_chan *chan) 79 struct mbox_chan *chan)
83 { 80 {
84 int index; 81 int index;
85 82
86 debug("%s(dev=%p, name=%s, chan=%p)\n", __func__, dev, name, chan); 83 debug("%s(dev=%p, name=%s, chan=%p)\n", __func__, dev, name, chan);
87 84
88 index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev), 85 index = dev_read_stringlist_search(dev, "mbox-names", name);
89 "mbox-names", name);
90 if (index < 0) { 86 if (index < 0) {
91 debug("fdt_stringlist_search() failed: %d\n", index); 87 debug("fdt_stringlist_search() failed: %d\n", index);
92 return index; 88 return index;
93 } 89 }
94 90
95 return mbox_get_by_index(dev, index, chan); 91 return mbox_get_by_index(dev, index, chan);
96 } 92 }
97 93
98 int mbox_free(struct mbox_chan *chan) 94 int mbox_free(struct mbox_chan *chan)
99 { 95 {
100 struct mbox_ops *ops = mbox_dev_ops(chan->dev); 96 struct mbox_ops *ops = mbox_dev_ops(chan->dev);
101 97
102 debug("%s(chan=%p)\n", __func__, chan); 98 debug("%s(chan=%p)\n", __func__, chan);
103 99
104 return ops->free(chan); 100 return ops->free(chan);
105 } 101 }
106 102
107 int mbox_send(struct mbox_chan *chan, const void *data) 103 int mbox_send(struct mbox_chan *chan, const void *data)
108 { 104 {
109 struct mbox_ops *ops = mbox_dev_ops(chan->dev); 105 struct mbox_ops *ops = mbox_dev_ops(chan->dev);
110 106
111 debug("%s(chan=%p, data=%p)\n", __func__, chan, data); 107 debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
112 108
113 return ops->send(chan, data); 109 return ops->send(chan, data);
114 } 110 }
115 111
116 int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us) 112 int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us)
117 { 113 {
118 struct mbox_ops *ops = mbox_dev_ops(chan->dev); 114 struct mbox_ops *ops = mbox_dev_ops(chan->dev);
119 ulong start_time; 115 ulong start_time;
120 int ret; 116 int ret;
121 117
122 debug("%s(chan=%p, data=%p, timeout_us=%ld)\n", __func__, chan, data, 118 debug("%s(chan=%p, data=%p, timeout_us=%ld)\n", __func__, chan, data,
123 timeout_us); 119 timeout_us);
124 120
125 start_time = timer_get_us(); 121 start_time = timer_get_us();
126 /* 122 /*
127 * Account for partial us ticks, but if timeout_us is 0, ensure we 123 * Account for partial us ticks, but if timeout_us is 0, ensure we
128 * still don't wait at all. 124 * still don't wait at all.
129 */ 125 */
130 if (timeout_us) 126 if (timeout_us)
131 timeout_us++; 127 timeout_us++;
132 128
133 for (;;) { 129 for (;;) {
134 ret = ops->recv(chan, data); 130 ret = ops->recv(chan, data);
135 if (ret != -ENODATA) 131 if (ret != -ENODATA)
136 return ret; 132 return ret;
137 if ((timer_get_us() - start_time) >= timeout_us) 133 if ((timer_get_us() - start_time) >= timeout_us)
138 return -ETIMEDOUT; 134 return -ETIMEDOUT;
139 } 135 }
140 } 136 }
141 137
142 UCLASS_DRIVER(mailbox) = { 138 UCLASS_DRIVER(mailbox) = {
143 .id = UCLASS_MAILBOX, 139 .id = UCLASS_MAILBOX,
144 .name = "mailbox", 140 .name = "mailbox",
145 }; 141 };
146 142
drivers/mailbox/tegra-hsp.c
1 /* 1 /*
2 * Copyright (c) 2016, NVIDIA CORPORATION. 2 * Copyright (c) 2016, NVIDIA CORPORATION.
3 * 3 *
4 * SPDX-License-Identifier: GPL-2.0 4 * SPDX-License-Identifier: GPL-2.0
5 */ 5 */
6 6
7 #include <common.h> 7 #include <common.h>
8 #include <asm/io.h> 8 #include <asm/io.h>
9 #include <dm.h> 9 #include <dm.h>
10 #include <mailbox-uclass.h> 10 #include <mailbox-uclass.h>
11 #include <dt-bindings/mailbox/tegra186-hsp.h> 11 #include <dt-bindings/mailbox/tegra186-hsp.h>
12 12
13 #define TEGRA_HSP_INT_DIMENSIONING 0x380 13 #define TEGRA_HSP_INT_DIMENSIONING 0x380
14 #define TEGRA_HSP_INT_DIMENSIONING_NSI_SHIFT 16 14 #define TEGRA_HSP_INT_DIMENSIONING_NSI_SHIFT 16
15 #define TEGRA_HSP_INT_DIMENSIONING_NSI_MASK 0xf 15 #define TEGRA_HSP_INT_DIMENSIONING_NSI_MASK 0xf
16 #define TEGRA_HSP_INT_DIMENSIONING_NDB_SHIFT 12 16 #define TEGRA_HSP_INT_DIMENSIONING_NDB_SHIFT 12
17 #define TEGRA_HSP_INT_DIMENSIONING_NDB_MASK 0xf 17 #define TEGRA_HSP_INT_DIMENSIONING_NDB_MASK 0xf
18 #define TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT 8 18 #define TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT 8
19 #define TEGRA_HSP_INT_DIMENSIONING_NAS_MASK 0xf 19 #define TEGRA_HSP_INT_DIMENSIONING_NAS_MASK 0xf
20 #define TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT 4 20 #define TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT 4
21 #define TEGRA_HSP_INT_DIMENSIONING_NSS_MASK 0xf 21 #define TEGRA_HSP_INT_DIMENSIONING_NSS_MASK 0xf
22 #define TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT 0 22 #define TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT 0
23 #define TEGRA_HSP_INT_DIMENSIONING_NSM_MASK 0xf 23 #define TEGRA_HSP_INT_DIMENSIONING_NSM_MASK 0xf
24 24
25 #define TEGRA_HSP_DB_REG_TRIGGER 0x0 25 #define TEGRA_HSP_DB_REG_TRIGGER 0x0
26 #define TEGRA_HSP_DB_REG_ENABLE 0x4 26 #define TEGRA_HSP_DB_REG_ENABLE 0x4
27 #define TEGRA_HSP_DB_REG_RAW 0x8 27 #define TEGRA_HSP_DB_REG_RAW 0x8
28 #define TEGRA_HSP_DB_REG_PENDING 0xc 28 #define TEGRA_HSP_DB_REG_PENDING 0xc
29 29
30 #define TEGRA_HSP_DB_ID_CCPLEX 1 30 #define TEGRA_HSP_DB_ID_CCPLEX 1
31 #define TEGRA_HSP_DB_ID_BPMP 3 31 #define TEGRA_HSP_DB_ID_BPMP 3
32 #define TEGRA_HSP_DB_ID_NUM 7 32 #define TEGRA_HSP_DB_ID_NUM 7
33 33
34 struct tegra_hsp { 34 struct tegra_hsp {
35 fdt_addr_t regs; 35 fdt_addr_t regs;
36 uint32_t db_base; 36 uint32_t db_base;
37 }; 37 };
38 38
39 DECLARE_GLOBAL_DATA_PTR; 39 DECLARE_GLOBAL_DATA_PTR;
40 40
41 static uint32_t *tegra_hsp_reg(struct tegra_hsp *thsp, uint32_t db_id, 41 static uint32_t *tegra_hsp_reg(struct tegra_hsp *thsp, uint32_t db_id,
42 uint32_t reg) 42 uint32_t reg)
43 { 43 {
44 return (uint32_t *)(thsp->regs + thsp->db_base + (db_id * 0x100) + reg); 44 return (uint32_t *)(thsp->regs + thsp->db_base + (db_id * 0x100) + reg);
45 } 45 }
46 46
47 static uint32_t tegra_hsp_readl(struct tegra_hsp *thsp, uint32_t db_id, 47 static uint32_t tegra_hsp_readl(struct tegra_hsp *thsp, uint32_t db_id,
48 uint32_t reg) 48 uint32_t reg)
49 { 49 {
50 uint32_t *r = tegra_hsp_reg(thsp, db_id, reg); 50 uint32_t *r = tegra_hsp_reg(thsp, db_id, reg);
51 return readl(r); 51 return readl(r);
52 } 52 }
53 53
54 static void tegra_hsp_writel(struct tegra_hsp *thsp, uint32_t val, 54 static void tegra_hsp_writel(struct tegra_hsp *thsp, uint32_t val,
55 uint32_t db_id, uint32_t reg) 55 uint32_t db_id, uint32_t reg)
56 { 56 {
57 uint32_t *r = tegra_hsp_reg(thsp, db_id, reg); 57 uint32_t *r = tegra_hsp_reg(thsp, db_id, reg);
58 58
59 writel(val, r); 59 writel(val, r);
60 readl(r); 60 readl(r);
61 } 61 }
62 62
63 static int tegra_hsp_db_id(ulong chan_id) 63 static int tegra_hsp_db_id(ulong chan_id)
64 { 64 {
65 switch (chan_id) { 65 switch (chan_id) {
66 case (HSP_MBOX_TYPE_DB << 16) | HSP_DB_MASTER_BPMP: 66 case (HSP_MBOX_TYPE_DB << 16) | HSP_DB_MASTER_BPMP:
67 return TEGRA_HSP_DB_ID_BPMP; 67 return TEGRA_HSP_DB_ID_BPMP;
68 default: 68 default:
69 debug("Invalid channel ID\n"); 69 debug("Invalid channel ID\n");
70 return -EINVAL; 70 return -EINVAL;
71 } 71 }
72 } 72 }
73 73
74 static int tegra_hsp_of_xlate(struct mbox_chan *chan, 74 static int tegra_hsp_of_xlate(struct mbox_chan *chan,
75 struct fdtdec_phandle_args *args) 75 struct ofnode_phandle_args *args)
76 { 76 {
77 debug("%s(chan=%p)\n", __func__, chan); 77 debug("%s(chan=%p)\n", __func__, chan);
78 78
79 if (args->args_count != 2) { 79 if (args->args_count != 2) {
80 debug("Invaild args_count: %d\n", args->args_count); 80 debug("Invaild args_count: %d\n", args->args_count);
81 return -EINVAL; 81 return -EINVAL;
82 } 82 }
83 83
84 chan->id = (args->args[0] << 16) | args->args[1]; 84 chan->id = (args->args[0] << 16) | args->args[1];
85 85
86 return 0; 86 return 0;
87 } 87 }
88 88
89 static int tegra_hsp_request(struct mbox_chan *chan) 89 static int tegra_hsp_request(struct mbox_chan *chan)
90 { 90 {
91 int db_id; 91 int db_id;
92 92
93 debug("%s(chan=%p)\n", __func__, chan); 93 debug("%s(chan=%p)\n", __func__, chan);
94 94
95 db_id = tegra_hsp_db_id(chan->id); 95 db_id = tegra_hsp_db_id(chan->id);
96 if (db_id < 0) { 96 if (db_id < 0) {
97 debug("tegra_hsp_db_id() failed: %d\n", db_id); 97 debug("tegra_hsp_db_id() failed: %d\n", db_id);
98 return -EINVAL; 98 return -EINVAL;
99 } 99 }
100 100
101 return 0; 101 return 0;
102 } 102 }
103 103
104 static int tegra_hsp_free(struct mbox_chan *chan) 104 static int tegra_hsp_free(struct mbox_chan *chan)
105 { 105 {
106 debug("%s(chan=%p)\n", __func__, chan); 106 debug("%s(chan=%p)\n", __func__, chan);
107 107
108 return 0; 108 return 0;
109 } 109 }
110 110
111 static int tegra_hsp_send(struct mbox_chan *chan, const void *data) 111 static int tegra_hsp_send(struct mbox_chan *chan, const void *data)
112 { 112 {
113 struct tegra_hsp *thsp = dev_get_priv(chan->dev); 113 struct tegra_hsp *thsp = dev_get_priv(chan->dev);
114 int db_id; 114 int db_id;
115 115
116 debug("%s(chan=%p, data=%p)\n", __func__, chan, data); 116 debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
117 117
118 db_id = tegra_hsp_db_id(chan->id); 118 db_id = tegra_hsp_db_id(chan->id);
119 tegra_hsp_writel(thsp, 1, db_id, TEGRA_HSP_DB_REG_TRIGGER); 119 tegra_hsp_writel(thsp, 1, db_id, TEGRA_HSP_DB_REG_TRIGGER);
120 120
121 return 0; 121 return 0;
122 } 122 }
123 123
124 static int tegra_hsp_recv(struct mbox_chan *chan, void *data) 124 static int tegra_hsp_recv(struct mbox_chan *chan, void *data)
125 { 125 {
126 struct tegra_hsp *thsp = dev_get_priv(chan->dev); 126 struct tegra_hsp *thsp = dev_get_priv(chan->dev);
127 uint32_t db_id = TEGRA_HSP_DB_ID_CCPLEX; 127 uint32_t db_id = TEGRA_HSP_DB_ID_CCPLEX;
128 uint32_t val; 128 uint32_t val;
129 129
130 debug("%s(chan=%p, data=%p)\n", __func__, chan, data); 130 debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
131 131
132 val = tegra_hsp_readl(thsp, db_id, TEGRA_HSP_DB_REG_RAW); 132 val = tegra_hsp_readl(thsp, db_id, TEGRA_HSP_DB_REG_RAW);
133 if (!(val & BIT(chan->id))) 133 if (!(val & BIT(chan->id)))
134 return -ENODATA; 134 return -ENODATA;
135 135
136 tegra_hsp_writel(thsp, BIT(chan->id), db_id, TEGRA_HSP_DB_REG_RAW); 136 tegra_hsp_writel(thsp, BIT(chan->id), db_id, TEGRA_HSP_DB_REG_RAW);
137 137
138 return 0; 138 return 0;
139 } 139 }
140 140
141 static int tegra_hsp_bind(struct udevice *dev) 141 static int tegra_hsp_bind(struct udevice *dev)
142 { 142 {
143 debug("%s(dev=%p)\n", __func__, dev); 143 debug("%s(dev=%p)\n", __func__, dev);
144 144
145 return 0; 145 return 0;
146 } 146 }
147 147
148 static int tegra_hsp_probe(struct udevice *dev) 148 static int tegra_hsp_probe(struct udevice *dev)
149 { 149 {
150 struct tegra_hsp *thsp = dev_get_priv(dev); 150 struct tegra_hsp *thsp = dev_get_priv(dev);
151 u32 val; 151 u32 val;
152 int nr_sm, nr_ss, nr_as; 152 int nr_sm, nr_ss, nr_as;
153 153
154 debug("%s(dev=%p)\n", __func__, dev); 154 debug("%s(dev=%p)\n", __func__, dev);
155 155
156 thsp->regs = devfdt_get_addr(dev); 156 thsp->regs = devfdt_get_addr(dev);
157 if (thsp->regs == FDT_ADDR_T_NONE) 157 if (thsp->regs == FDT_ADDR_T_NONE)
158 return -ENODEV; 158 return -ENODEV;
159 159
160 val = readl(thsp->regs + TEGRA_HSP_INT_DIMENSIONING); 160 val = readl(thsp->regs + TEGRA_HSP_INT_DIMENSIONING);
161 nr_sm = (val >> TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT) & 161 nr_sm = (val >> TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT) &
162 TEGRA_HSP_INT_DIMENSIONING_NSM_MASK; 162 TEGRA_HSP_INT_DIMENSIONING_NSM_MASK;
163 nr_ss = (val >> TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT) & 163 nr_ss = (val >> TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT) &
164 TEGRA_HSP_INT_DIMENSIONING_NSS_MASK; 164 TEGRA_HSP_INT_DIMENSIONING_NSS_MASK;
165 nr_as = (val >> TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT) & 165 nr_as = (val >> TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT) &
166 TEGRA_HSP_INT_DIMENSIONING_NAS_MASK; 166 TEGRA_HSP_INT_DIMENSIONING_NAS_MASK;
167 167
168 thsp->db_base = (1 + (nr_sm >> 1) + nr_ss + nr_as) << 16; 168 thsp->db_base = (1 + (nr_sm >> 1) + nr_ss + nr_as) << 16;
169 169
170 return 0; 170 return 0;
171 } 171 }
172 172
173 static const struct udevice_id tegra_hsp_ids[] = { 173 static const struct udevice_id tegra_hsp_ids[] = {
174 { .compatible = "nvidia,tegra186-hsp" }, 174 { .compatible = "nvidia,tegra186-hsp" },
175 { } 175 { }
176 }; 176 };
177 177
178 struct mbox_ops tegra_hsp_mbox_ops = { 178 struct mbox_ops tegra_hsp_mbox_ops = {
179 .of_xlate = tegra_hsp_of_xlate, 179 .of_xlate = tegra_hsp_of_xlate,
180 .request = tegra_hsp_request, 180 .request = tegra_hsp_request,
181 .free = tegra_hsp_free, 181 .free = tegra_hsp_free,
182 .send = tegra_hsp_send, 182 .send = tegra_hsp_send,
183 .recv = tegra_hsp_recv, 183 .recv = tegra_hsp_recv,
184 }; 184 };
185 185
186 U_BOOT_DRIVER(tegra_hsp) = { 186 U_BOOT_DRIVER(tegra_hsp) = {
187 .name = "tegra-hsp", 187 .name = "tegra-hsp",
188 .id = UCLASS_MAILBOX, 188 .id = UCLASS_MAILBOX,
189 .of_match = tegra_hsp_ids, 189 .of_match = tegra_hsp_ids,
190 .bind = tegra_hsp_bind, 190 .bind = tegra_hsp_bind,
191 .probe = tegra_hsp_probe, 191 .probe = tegra_hsp_probe,
192 .priv_auto_alloc_size = sizeof(struct tegra_hsp), 192 .priv_auto_alloc_size = sizeof(struct tegra_hsp),
193 .ops = &tegra_hsp_mbox_ops, 193 .ops = &tegra_hsp_mbox_ops,
194 }; 194 };
195 195
include/mailbox-uclass.h
1 /* 1 /*
2 * Copyright (c) 2016, NVIDIA CORPORATION. 2 * Copyright (c) 2016, NVIDIA CORPORATION.
3 * 3 *
4 * SPDX-License-Identifier: GPL-2.0 4 * SPDX-License-Identifier: GPL-2.0
5 */ 5 */
6 6
7 #ifndef _MAILBOX_UCLASS_H 7 #ifndef _MAILBOX_UCLASS_H
8 #define _MAILBOX_UCLASS_H 8 #define _MAILBOX_UCLASS_H
9 9
10 /* See mailbox.h for background documentation. */ 10 /* See mailbox.h for background documentation. */
11 11
12 #include <mailbox.h> 12 #include <mailbox.h>
13 13
14 struct udevice; 14 struct udevice;
15 15
16 /** 16 /**
17 * struct mbox_ops - The functions that a mailbox driver must implement. 17 * struct mbox_ops - The functions that a mailbox driver must implement.
18 */ 18 */
19 struct mbox_ops { 19 struct mbox_ops {
20 /** 20 /**
21 * of_xlate - Translate a client's device-tree (OF) mailbox specifier. 21 * of_xlate - Translate a client's device-tree (OF) mailbox specifier.
22 * 22 *
23 * The mailbox core calls this function as the first step in 23 * The mailbox core calls this function as the first step in
24 * implementing a client's mbox_get_by_*() call. 24 * implementing a client's mbox_get_by_*() call.
25 * 25 *
26 * If this function pointer is set to NULL, the mailbox core will use 26 * If this function pointer is set to NULL, the mailbox core will use
27 * a default implementation, which assumes #mbox-cells = <1>, and that 27 * a default implementation, which assumes #mbox-cells = <1>, and that
28 * the DT cell contains a simple integer channel ID. 28 * the DT cell contains a simple integer channel ID.
29 * 29 *
30 * At present, the mailbox API solely supports device-tree. If this 30 * At present, the mailbox API solely supports device-tree. If this
31 * changes, other xxx_xlate() functions may be added to support those 31 * changes, other xxx_xlate() functions may be added to support those
32 * other mechanisms. 32 * other mechanisms.
33 * 33 *
34 * @chan: The channel to hold the translation result. 34 * @chan: The channel to hold the translation result.
35 * @args: The mailbox specifier values from device tree. 35 * @args: The mailbox specifier values from device tree.
36 * @return 0 if OK, or a negative error code. 36 * @return 0 if OK, or a negative error code.
37 */ 37 */
38 int (*of_xlate)(struct mbox_chan *chan, 38 int (*of_xlate)(struct mbox_chan *chan,
39 struct fdtdec_phandle_args *args); 39 struct ofnode_phandle_args *args);
40 /** 40 /**
41 * request - Request a translated channel. 41 * request - Request a translated channel.
42 * 42 *
43 * The mailbox core calls this function as the second step in 43 * The mailbox core calls this function as the second step in
44 * implementing a client's mbox_get_by_*() call, following a successful 44 * implementing a client's mbox_get_by_*() call, following a successful
45 * xxx_xlate() call. 45 * xxx_xlate() call.
46 * 46 *
47 * @chan: The channel to request; this has been filled in by a 47 * @chan: The channel to request; this has been filled in by a
48 * previoux xxx_xlate() function call. 48 * previoux xxx_xlate() function call.
49 * @return 0 if OK, or a negative error code. 49 * @return 0 if OK, or a negative error code.
50 */ 50 */
51 int (*request)(struct mbox_chan *chan); 51 int (*request)(struct mbox_chan *chan);
52 /** 52 /**
53 * free - Free a previously requested channel. 53 * free - Free a previously requested channel.
54 * 54 *
55 * This is the implementation of the client mbox_free() API. 55 * This is the implementation of the client mbox_free() API.
56 * 56 *
57 * @chan: The channel to free. 57 * @chan: The channel to free.
58 * @return 0 if OK, or a negative error code. 58 * @return 0 if OK, or a negative error code.
59 */ 59 */
60 int (*free)(struct mbox_chan *chan); 60 int (*free)(struct mbox_chan *chan);
61 /** 61 /**
62 * send - Send a message over a mailbox channel 62 * send - Send a message over a mailbox channel
63 * 63 *
64 * @chan: The channel to send to the message to. 64 * @chan: The channel to send to the message to.
65 * @data: A pointer to the message to send. 65 * @data: A pointer to the message to send.
66 * @return 0 if OK, or a negative error code. 66 * @return 0 if OK, or a negative error code.
67 */ 67 */
68 int (*send)(struct mbox_chan *chan, const void *data); 68 int (*send)(struct mbox_chan *chan, const void *data);
69 /** 69 /**
70 * recv - Receive any available message from the channel. 70 * recv - Receive any available message from the channel.
71 * 71 *
72 * This function does not block. If not message is immediately 72 * This function does not block. If not message is immediately
73 * available, the function should return an error. 73 * available, the function should return an error.
74 * 74 *
75 * @chan: The channel to receive to the message from. 75 * @chan: The channel to receive to the message from.
76 * @data: A pointer to the buffer to hold the received message. 76 * @data: A pointer to the buffer to hold the received message.
77 * @return 0 if OK, -ENODATA if no message was available, or a negative 77 * @return 0 if OK, -ENODATA if no message was available, or a negative
78 * error code. 78 * error code.
79 */ 79 */
80 int (*recv)(struct mbox_chan *chan, void *data); 80 int (*recv)(struct mbox_chan *chan, void *data);
81 }; 81 };
82 82
83 #endif 83 #endif
84 84