blob: d294ee09350a56d0f71f5bbcdf4be8d64a8235e9 [file] [log] [blame]
Mark Kettenis72d73012022-01-22 20:38:14 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
4 * (C) Copyright 2021 Copyright The Asahi Linux Contributors
5 */
6
Mark Kettenis72d73012022-01-22 20:38:14 +01007#include <mailbox.h>
8#include <malloc.h>
9
10#include <asm/arch/rtkit.h>
11#include <linux/apple-mailbox.h>
12#include <linux/bitfield.h>
Tom Rinidec7ea02024-05-20 13:35:03 -060013#include <linux/errno.h>
Hector Martin0b9e2da2025-04-20 13:58:04 +020014#include <linux/sizes.h>
Tom Rinidec7ea02024-05-20 13:35:03 -060015#include <linux/types.h>
Mark Kettenis72d73012022-01-22 20:38:14 +010016
17#define APPLE_RTKIT_EP_MGMT 0
18#define APPLE_RTKIT_EP_CRASHLOG 1
19#define APPLE_RTKIT_EP_SYSLOG 2
20#define APPLE_RTKIT_EP_DEBUG 3
21#define APPLE_RTKIT_EP_IOREPORT 4
Hector Martin007b1852025-04-20 13:58:06 +020022#define APPLE_RTKIT_EP_OSLOG 8
Janne Grunaue3a438f2022-06-14 09:09:07 +020023#define APPLE_RTKIT_EP_TRACEKIT 10
Mark Kettenis72d73012022-01-22 20:38:14 +010024
25/* Messages for management endpoint. */
26#define APPLE_RTKIT_MGMT_TYPE GENMASK(59, 52)
27
28#define APPLE_RTKIT_MGMT_PWR_STATE GENMASK(15, 0)
29
30#define APPLE_RTKIT_MGMT_HELLO 1
31#define APPLE_RTKIT_MGMT_HELLO_REPLY 2
32#define APPLE_RTKIT_MGMT_HELLO_MINVER GENMASK(15, 0)
33#define APPLE_RTKIT_MGMT_HELLO_MAXVER GENMASK(31, 16)
34
35#define APPLE_RTKIT_MGMT_STARTEP 5
36#define APPLE_RTKIT_MGMT_STARTEP_EP GENMASK(39, 32)
37#define APPLE_RTKIT_MGMT_STARTEP_FLAG BIT(1)
38
39#define APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE 6
40#define APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK 7
Hector Martinaa4e96b2025-04-20 13:58:03 +020041#define APPLE_RTKIT_MGMT_SET_AP_PWR_STATE 11
Mark Kettenis72d73012022-01-22 20:38:14 +010042
43#define APPLE_RTKIT_MGMT_EPMAP 8
44#define APPLE_RTKIT_MGMT_EPMAP_LAST BIT(51)
45#define APPLE_RTKIT_MGMT_EPMAP_BASE GENMASK(34, 32)
46#define APPLE_RTKIT_MGMT_EPMAP_BITMAP GENMASK(31, 0)
47
48#define APPLE_RTKIT_MGMT_EPMAP_REPLY 8
49#define APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE BIT(0)
50
Hector Martin007b1852025-04-20 13:58:06 +020051#define APPLE_RTKIT_OSLOG_TYPE GENMASK_ULL(63, 56)
52#define APPLE_RTKIT_OSLOG_BUFFER_REQUEST 1
53#define APPLE_RTKIT_OSLOG_SIZE GENMASK_ULL(55, 36)
54#define APPLE_RTKIT_OSLOG_IOVA GENMASK_ULL(35, 0)
55
Mark Kettenis72d73012022-01-22 20:38:14 +010056#define APPLE_RTKIT_MIN_SUPPORTED_VERSION 11
57#define APPLE_RTKIT_MAX_SUPPORTED_VERSION 12
58
59/* Messages for internal endpoints. */
60#define APPLE_RTKIT_BUFFER_REQUEST 1
61#define APPLE_RTKIT_BUFFER_REQUEST_SIZE GENMASK(51, 44)
62#define APPLE_RTKIT_BUFFER_REQUEST_IOVA GENMASK(41, 0)
63
Janne Grunau16eda4e2022-06-14 09:09:09 +020064#define TIMEOUT_1SEC_US 1000000
65
Janne Grunaue3a438f2022-06-14 09:09:07 +020066struct apple_rtkit {
67 struct mbox_chan *chan;
68 void *cookie;
69 apple_rtkit_shmem_setup shmem_setup;
70 apple_rtkit_shmem_destroy shmem_destroy;
71
72 struct apple_rtkit_buffer syslog_buffer;
73 struct apple_rtkit_buffer crashlog_buffer;
74 struct apple_rtkit_buffer ioreport_buffer;
Hector Martin007b1852025-04-20 13:58:06 +020075 struct apple_rtkit_buffer oslog_buffer;
Hector Martinaa4e96b2025-04-20 13:58:03 +020076
77 int iop_pwr;
78 int ap_pwr;
Janne Grunaue3a438f2022-06-14 09:09:07 +020079};
80
81struct apple_rtkit *apple_rtkit_init(struct mbox_chan *chan, void *cookie,
82 apple_rtkit_shmem_setup shmem_setup,
83 apple_rtkit_shmem_destroy shmem_destroy)
84{
85 struct apple_rtkit *rtk;
86
87 rtk = calloc(sizeof(*rtk), 1);
88 if (!rtk)
89 return NULL;
90
91 rtk->chan = chan;
92 rtk->cookie = cookie;
93 rtk->shmem_setup = shmem_setup;
94 rtk->shmem_destroy = shmem_destroy;
95
96 return rtk;
97}
98
99void apple_rtkit_free(struct apple_rtkit *rtk)
100{
101 if (rtk->shmem_destroy) {
102 if (rtk->syslog_buffer.buffer)
103 rtk->shmem_destroy(rtk->cookie, &rtk->syslog_buffer);
104 if (rtk->crashlog_buffer.buffer)
105 rtk->shmem_destroy(rtk->cookie, &rtk->crashlog_buffer);
106 if (rtk->ioreport_buffer.buffer)
107 rtk->shmem_destroy(rtk->cookie, &rtk->ioreport_buffer);
Hector Martin007b1852025-04-20 13:58:06 +0200108 if (rtk->oslog_buffer.buffer)
109 rtk->shmem_destroy(rtk->cookie, &rtk->oslog_buffer);
Hector Martin0b9e2da2025-04-20 13:58:04 +0200110 } else {
111 if (rtk->syslog_buffer.buffer)
112 free(rtk->syslog_buffer.buffer);
113 if (rtk->crashlog_buffer.buffer)
114 free(rtk->crashlog_buffer.buffer);
115 if (rtk->ioreport_buffer.buffer)
116 free(rtk->ioreport_buffer.buffer);
Hector Martin007b1852025-04-20 13:58:06 +0200117 if (rtk->oslog_buffer.buffer)
118 free(rtk->oslog_buffer.buffer);
Janne Grunaue3a438f2022-06-14 09:09:07 +0200119 }
120 free(rtk);
121}
122
123static int rtkit_handle_buf_req(struct apple_rtkit *rtk, int endpoint, struct apple_mbox_msg *msg)
124{
125 struct apple_rtkit_buffer *buf;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200126 int ret;
127
Janne Grunaue3a438f2022-06-14 09:09:07 +0200128 switch (endpoint) {
129 case APPLE_RTKIT_EP_CRASHLOG:
130 buf = &rtk->crashlog_buffer;
131 break;
132 case APPLE_RTKIT_EP_SYSLOG:
133 buf = &rtk->syslog_buffer;
134 break;
135 case APPLE_RTKIT_EP_IOREPORT:
136 buf = &rtk->ioreport_buffer;
137 break;
Hector Martin007b1852025-04-20 13:58:06 +0200138 case APPLE_RTKIT_EP_OSLOG:
139 buf = &rtk->oslog_buffer;
140 break;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200141 default:
142 printf("%s: unexpected endpoint %d\n", __func__, endpoint);
143 return -1;
144 }
145
Hector Martin007b1852025-04-20 13:58:06 +0200146 switch (endpoint) {
147 case APPLE_RTKIT_EP_OSLOG:
148 buf->size = FIELD_GET(APPLE_RTKIT_OSLOG_SIZE, msg->msg0);
149 buf->dva = FIELD_GET(APPLE_RTKIT_OSLOG_IOVA, msg->msg0 << 12);
150 break;
151 default:
152 buf->size = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_SIZE, msg->msg0) << 12;
153 buf->dva = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg->msg0);
154 break;
155 }
156
157 if (buf->size == 0) {
158 printf("%s: unexpected request for buffer without size\n", __func__);
159 return -1;
160 }
161
Janne Grunaue3a438f2022-06-14 09:09:07 +0200162 buf->dva = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg->msg0);
Hector Martin0b9e2da2025-04-20 13:58:04 +0200163 buf->is_mapped = !!buf->dva;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200164
165 if (rtk->shmem_setup) {
166 ret = rtk->shmem_setup(rtk->cookie, buf);
167 if (ret < 0) {
168 printf("%s: shmen_setup failed for endpoint %d\n", __func__,
169 endpoint);
170 return ret;
171 }
Hector Martin0b9e2da2025-04-20 13:58:04 +0200172 } else if (!buf->is_mapped){
173 buf->buffer = memalign(SZ_16K, ALIGN(buf->size, SZ_16K));
174 if (!buf->buffer)
175 return -ENOMEM;
176
177 buf->dva = (u64)buf->buffer;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200178 }
179
180 if (!buf->is_mapped) {
Hector Martin007b1852025-04-20 13:58:06 +0200181 /* oslog uses different fields */
182 if (endpoint == APPLE_RTKIT_EP_OSLOG) {
183 msg->msg0 = FIELD_PREP(APPLE_RTKIT_OSLOG_TYPE,
184 APPLE_RTKIT_OSLOG_BUFFER_REQUEST);
185 msg->msg0 |= FIELD_PREP(APPLE_RTKIT_OSLOG_SIZE, buf->size);
186 msg->msg0 |= FIELD_PREP(APPLE_RTKIT_OSLOG_IOVA, buf->dva >> 12);
187 } else {
188 msg->msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE,
189 APPLE_RTKIT_BUFFER_REQUEST);
190 msg->msg0 |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE, buf->size >> 12);
191 msg->msg0 |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA, buf->dva);
192 }
Janne Grunaue3a438f2022-06-14 09:09:07 +0200193
194 return mbox_send(rtk->chan, msg);
195 }
196
197 return 0;
198}
199
Hector Martinaa4e96b2025-04-20 13:58:03 +0200200int apple_rtkit_poll(struct apple_rtkit *rtk, ulong timeout)
201{
202 struct apple_mbox_msg msg;
203 int ret;
204 int endpoint;
205 int msgtype;
206
207 ret = mbox_recv(rtk->chan, &msg, timeout);
208 if (ret < 0)
209 return ret;
210
211 endpoint = msg.msg1;
212 msgtype = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg.msg0);
213
214 if (endpoint == APPLE_RTKIT_EP_CRASHLOG ||
215 endpoint == APPLE_RTKIT_EP_SYSLOG ||
216 endpoint == APPLE_RTKIT_EP_IOREPORT) {
217 if (msgtype == APPLE_RTKIT_BUFFER_REQUEST) {
218 ret = rtkit_handle_buf_req(rtk, endpoint, &msg);
219 if (ret < 0)
220 return ret;
221 return 0;
Hector Martin007b1852025-04-20 13:58:06 +0200222 }
223 }
224
225 if (endpoint == APPLE_RTKIT_EP_OSLOG) {
226 msgtype = FIELD_GET(APPLE_RTKIT_OSLOG_TYPE, msg.msg0);
227
228 if (msgtype == APPLE_RTKIT_OSLOG_BUFFER_REQUEST) {
229 ret = rtkit_handle_buf_req(rtk, endpoint, &msg);
230 if (ret < 0)
231 return ret;
232 return 0;
233 } else {
234 /* Ignore */
235 return 0;
Hector Martinaa4e96b2025-04-20 13:58:03 +0200236 }
237 }
238
239 if (endpoint == APPLE_RTKIT_EP_IOREPORT) {
240 // these two messages have to be ack-ed for proper startup
241 if (msgtype == 0xc || msgtype == 0x8) {
242 ret = mbox_send(rtk->chan, &msg);
243 if (ret < 0)
244 return ret;
245 return 0;
246 }
247 }
248
249 if (endpoint == APPLE_RTKIT_EP_SYSLOG) {
250 /* Ignore init */
251 if (msgtype == 0x8)
252 return 0;
253
254 /* Ack logs */
255 if (msgtype == 0x5) {
256 ret = mbox_send(rtk->chan, &msg);
257 if (ret < 0)
258 return ret;
259 return 0;
260 }
261 }
262
263 if (endpoint != APPLE_RTKIT_EP_MGMT) {
264 printf("%s: unexpected endpoint %d\n", __func__, endpoint);
265 return -EINVAL;
266 }
267
268 switch (msgtype) {
269 case APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK:
270 rtk->iop_pwr = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg.msg0);
271 return 0;
272 case APPLE_RTKIT_MGMT_SET_AP_PWR_STATE:
273 rtk->ap_pwr = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg.msg0);
274 return 0;
275 default:
276 printf("%s: unexpected message type %d\n", __func__, msgtype);
277
278 /* Just ignore it */
279 return 0;
280 }
281}
282
Janne Grunaue3a438f2022-06-14 09:09:07 +0200283int apple_rtkit_boot(struct apple_rtkit *rtk)
Mark Kettenis72d73012022-01-22 20:38:14 +0100284{
285 struct apple_mbox_msg msg;
286 int endpoints[256];
287 int nendpoints = 0;
288 int endpoint;
289 int min_ver, max_ver, want_ver;
Hector Martinaa4e96b2025-04-20 13:58:03 +0200290 int msgtype;
Mark Kettenis72d73012022-01-22 20:38:14 +0100291 u64 reply;
292 u32 bitmap, base;
293 int i, ret;
294
295 /* Wakup the IOP. */
296 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE) |
297 FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, APPLE_RTKIT_PWR_STATE_ON);
298 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200299 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100300 if (ret < 0)
301 return ret;
302
303 /* Wait for protocol version negotiation message. */
Janne Grunau16eda4e2022-06-14 09:09:09 +0200304 ret = mbox_recv(rtk->chan, &msg, TIMEOUT_1SEC_US);
Mark Kettenis72d73012022-01-22 20:38:14 +0100305 if (ret < 0)
306 return ret;
307
308 endpoint = msg.msg1;
309 msgtype = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg.msg0);
310 if (endpoint != APPLE_RTKIT_EP_MGMT) {
311 printf("%s: unexpected endpoint %d\n", __func__, endpoint);
312 return -EINVAL;
313 }
314 if (msgtype != APPLE_RTKIT_MGMT_HELLO) {
315 printf("%s: unexpected message type %d\n", __func__, msgtype);
316 return -EINVAL;
317 }
318
319 min_ver = FIELD_GET(APPLE_RTKIT_MGMT_HELLO_MINVER, msg.msg0);
320 max_ver = FIELD_GET(APPLE_RTKIT_MGMT_HELLO_MAXVER, msg.msg0);
321 want_ver = min(APPLE_RTKIT_MAX_SUPPORTED_VERSION, max_ver);
322
323 if (min_ver > APPLE_RTKIT_MAX_SUPPORTED_VERSION) {
324 printf("%s: firmware min version %d is too new\n",
325 __func__, min_ver);
326 return -ENOTSUPP;
327 }
328
329 if (max_ver < APPLE_RTKIT_MIN_SUPPORTED_VERSION) {
330 printf("%s: firmware max version %d is too old\n",
331 __func__, max_ver);
332 return -ENOTSUPP;
333 }
334
335 /* Ack version. */
336 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_HELLO_REPLY) |
337 FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MINVER, want_ver) |
338 FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MAXVER, want_ver);
339 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200340 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100341 if (ret < 0)
342 return ret;
343
344wait_epmap:
345 /* Wait for endpoint map message. */
Janne Grunau16eda4e2022-06-14 09:09:09 +0200346 ret = mbox_recv(rtk->chan, &msg, TIMEOUT_1SEC_US);
Mark Kettenis72d73012022-01-22 20:38:14 +0100347 if (ret < 0)
348 return ret;
349
350 endpoint = msg.msg1;
351 msgtype = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg.msg0);
352 if (endpoint != APPLE_RTKIT_EP_MGMT) {
353 printf("%s: unexpected endpoint %d\n", __func__, endpoint);
354 return -EINVAL;
355 }
356 if (msgtype != APPLE_RTKIT_MGMT_EPMAP) {
357 printf("%s: unexpected message type %d\n", __func__, msgtype);
358 return -EINVAL;
359 }
360
361 bitmap = FIELD_GET(APPLE_RTKIT_MGMT_EPMAP_BITMAP, msg.msg0);
362 base = FIELD_GET(APPLE_RTKIT_MGMT_EPMAP_BASE, msg.msg0);
363 for (i = 0; i < 32; i++) {
364 if (bitmap & (1U << i))
365 endpoints[nendpoints++] = base * 32 + i;
366 }
367
368 /* Ack endpoint map. */
369 reply = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_EPMAP_REPLY) |
370 FIELD_PREP(APPLE_RTKIT_MGMT_EPMAP_BASE, base);
371 if (msg.msg0 & APPLE_RTKIT_MGMT_EPMAP_LAST)
372 reply |= APPLE_RTKIT_MGMT_EPMAP_LAST;
373 else
374 reply |= APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE;
375 msg.msg0 = reply;
376 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200377 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100378 if (ret < 0)
379 return ret;
380
381 if (reply & APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE)
382 goto wait_epmap;
383
384 for (i = 0; i < nendpoints; i++) {
Janne Grunaue3a438f2022-06-14 09:09:07 +0200385 /* Start only necessary endpoints. The syslog endpoint is
386 * particularly noisy and its message can't easily be handled
387 * within U-Boot.
388 */
389 switch (endpoints[i]) {
390 case APPLE_RTKIT_EP_MGMT:
391 case APPLE_RTKIT_EP_SYSLOG:
392 case APPLE_RTKIT_EP_DEBUG:
393 case APPLE_RTKIT_EP_TRACEKIT:
Mark Kettenis72d73012022-01-22 20:38:14 +0100394 continue;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200395 default:
396 break;
397 }
Mark Kettenis72d73012022-01-22 20:38:14 +0100398
399 /* Request endpoint. */
400 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_STARTEP) |
401 FIELD_PREP(APPLE_RTKIT_MGMT_STARTEP_EP, endpoints[i]) |
402 APPLE_RTKIT_MGMT_STARTEP_FLAG;
403 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200404 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100405 if (ret < 0)
406 return ret;
407 }
408
Hector Martinaa4e96b2025-04-20 13:58:03 +0200409 rtk->iop_pwr = APPLE_RTKIT_PWR_STATE_SLEEP;
410 rtk->ap_pwr = APPLE_RTKIT_PWR_STATE_QUIESCED;
411
412 while (rtk->iop_pwr != APPLE_RTKIT_PWR_STATE_ON) {
413 ret = apple_rtkit_poll(rtk, TIMEOUT_1SEC_US);
Mark Kettenis72d73012022-01-22 20:38:14 +0100414 if (ret < 0)
415 return ret;
Hector Martinaa4e96b2025-04-20 13:58:03 +0200416 }
Mark Kettenis72d73012022-01-22 20:38:14 +0100417
Hector Martinaa4e96b2025-04-20 13:58:03 +0200418 return 0;
419}
Mark Kettenis72d73012022-01-22 20:38:14 +0100420
Hector Martinaa4e96b2025-04-20 13:58:03 +0200421int apple_rtkit_set_ap_power(struct apple_rtkit *rtk, int pwrstate)
422{
423 struct apple_mbox_msg msg;
424 int ret;
Mark Kettenis72d73012022-01-22 20:38:14 +0100425
Hector Martinaa4e96b2025-04-20 13:58:03 +0200426 if (rtk->ap_pwr == pwrstate)
427 return 0;
Mark Kettenis72d73012022-01-22 20:38:14 +0100428
Hector Martinaa4e96b2025-04-20 13:58:03 +0200429 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_SET_AP_PWR_STATE) |
430 FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, pwrstate);
431 msg.msg1 = APPLE_RTKIT_EP_MGMT;
432 ret = mbox_send(rtk->chan, &msg);
433 if (ret < 0)
434 return ret;
Mark Kettenis72d73012022-01-22 20:38:14 +0100435
Hector Martinaa4e96b2025-04-20 13:58:03 +0200436 while (rtk->ap_pwr != pwrstate) {
437 ret = apple_rtkit_poll(rtk, TIMEOUT_1SEC_US);
438 if (ret < 0)
439 return ret;
Mark Kettenis72d73012022-01-22 20:38:14 +0100440 }
441
442 return 0;
443}
444
Janne Grunaue3a438f2022-06-14 09:09:07 +0200445int apple_rtkit_shutdown(struct apple_rtkit *rtk, int pwrstate)
Mark Kettenis72d73012022-01-22 20:38:14 +0100446{
447 struct apple_mbox_msg msg;
448 int ret;
449
Hector Martinaa4e96b2025-04-20 13:58:03 +0200450 if (rtk->ap_pwr != APPLE_RTKIT_PWR_STATE_QUIESCED) {
451 ret = apple_rtkit_set_ap_power(rtk, APPLE_RTKIT_PWR_STATE_QUIESCED);
452 if (ret < 0)
453 return ret;
454 }
455
Mark Kettenis72d73012022-01-22 20:38:14 +0100456 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE) |
457 FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, pwrstate);
458 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200459 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100460 if (ret < 0)
461 return ret;
462
Hector Martinaa4e96b2025-04-20 13:58:03 +0200463 while (rtk->iop_pwr != pwrstate) {
464 ret = apple_rtkit_poll(rtk, TIMEOUT_1SEC_US);
465 if (ret < 0)
466 return ret;
467 }
Mark Kettenis72d73012022-01-22 20:38:14 +0100468
469 return 0;
470}