blob: f3561543a356020f500dbe6e0996a0dcf7f639f7 [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;
Hector Martin45a648b2025-04-20 13:58:07 +0200164 buf->endpoint = endpoint;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200165
166 if (rtk->shmem_setup) {
167 ret = rtk->shmem_setup(rtk->cookie, buf);
168 if (ret < 0) {
169 printf("%s: shmen_setup failed for endpoint %d\n", __func__,
170 endpoint);
171 return ret;
172 }
Hector Martin0b9e2da2025-04-20 13:58:04 +0200173 } else if (!buf->is_mapped){
174 buf->buffer = memalign(SZ_16K, ALIGN(buf->size, SZ_16K));
175 if (!buf->buffer)
176 return -ENOMEM;
177
178 buf->dva = (u64)buf->buffer;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200179 }
180
181 if (!buf->is_mapped) {
Hector Martin007b1852025-04-20 13:58:06 +0200182 /* oslog uses different fields */
183 if (endpoint == APPLE_RTKIT_EP_OSLOG) {
184 msg->msg0 = FIELD_PREP(APPLE_RTKIT_OSLOG_TYPE,
185 APPLE_RTKIT_OSLOG_BUFFER_REQUEST);
186 msg->msg0 |= FIELD_PREP(APPLE_RTKIT_OSLOG_SIZE, buf->size);
187 msg->msg0 |= FIELD_PREP(APPLE_RTKIT_OSLOG_IOVA, buf->dva >> 12);
188 } else {
189 msg->msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE,
190 APPLE_RTKIT_BUFFER_REQUEST);
191 msg->msg0 |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE, buf->size >> 12);
192 msg->msg0 |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA, buf->dva);
193 }
Janne Grunaue3a438f2022-06-14 09:09:07 +0200194
195 return mbox_send(rtk->chan, msg);
196 }
197
198 return 0;
199}
200
Hector Martinaa4e96b2025-04-20 13:58:03 +0200201int apple_rtkit_poll(struct apple_rtkit *rtk, ulong timeout)
202{
203 struct apple_mbox_msg msg;
204 int ret;
205 int endpoint;
206 int msgtype;
207
208 ret = mbox_recv(rtk->chan, &msg, timeout);
209 if (ret < 0)
210 return ret;
211
212 endpoint = msg.msg1;
213 msgtype = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg.msg0);
214
215 if (endpoint == APPLE_RTKIT_EP_CRASHLOG ||
216 endpoint == APPLE_RTKIT_EP_SYSLOG ||
217 endpoint == APPLE_RTKIT_EP_IOREPORT) {
218 if (msgtype == APPLE_RTKIT_BUFFER_REQUEST) {
219 ret = rtkit_handle_buf_req(rtk, endpoint, &msg);
220 if (ret < 0)
221 return ret;
222 return 0;
Hector Martin007b1852025-04-20 13:58:06 +0200223 }
224 }
225
226 if (endpoint == APPLE_RTKIT_EP_OSLOG) {
227 msgtype = FIELD_GET(APPLE_RTKIT_OSLOG_TYPE, msg.msg0);
228
229 if (msgtype == APPLE_RTKIT_OSLOG_BUFFER_REQUEST) {
230 ret = rtkit_handle_buf_req(rtk, endpoint, &msg);
231 if (ret < 0)
232 return ret;
233 return 0;
234 } else {
235 /* Ignore */
236 return 0;
Hector Martinaa4e96b2025-04-20 13:58:03 +0200237 }
238 }
239
240 if (endpoint == APPLE_RTKIT_EP_IOREPORT) {
241 // these two messages have to be ack-ed for proper startup
242 if (msgtype == 0xc || msgtype == 0x8) {
243 ret = mbox_send(rtk->chan, &msg);
244 if (ret < 0)
245 return ret;
246 return 0;
247 }
248 }
249
250 if (endpoint == APPLE_RTKIT_EP_SYSLOG) {
251 /* Ignore init */
252 if (msgtype == 0x8)
253 return 0;
254
255 /* Ack logs */
256 if (msgtype == 0x5) {
257 ret = mbox_send(rtk->chan, &msg);
258 if (ret < 0)
259 return ret;
260 return 0;
261 }
262 }
263
264 if (endpoint != APPLE_RTKIT_EP_MGMT) {
265 printf("%s: unexpected endpoint %d\n", __func__, endpoint);
266 return -EINVAL;
267 }
268
269 switch (msgtype) {
270 case APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK:
271 rtk->iop_pwr = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg.msg0);
272 return 0;
273 case APPLE_RTKIT_MGMT_SET_AP_PWR_STATE:
274 rtk->ap_pwr = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg.msg0);
275 return 0;
276 default:
277 printf("%s: unexpected message type %d\n", __func__, msgtype);
278
279 /* Just ignore it */
280 return 0;
281 }
282}
283
Janne Grunaue3a438f2022-06-14 09:09:07 +0200284int apple_rtkit_boot(struct apple_rtkit *rtk)
Mark Kettenis72d73012022-01-22 20:38:14 +0100285{
286 struct apple_mbox_msg msg;
287 int endpoints[256];
288 int nendpoints = 0;
289 int endpoint;
290 int min_ver, max_ver, want_ver;
Hector Martinaa4e96b2025-04-20 13:58:03 +0200291 int msgtype;
Mark Kettenis72d73012022-01-22 20:38:14 +0100292 u64 reply;
293 u32 bitmap, base;
294 int i, ret;
295
296 /* Wakup the IOP. */
297 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE) |
298 FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, APPLE_RTKIT_PWR_STATE_ON);
299 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200300 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100301 if (ret < 0)
302 return ret;
303
304 /* Wait for protocol version negotiation message. */
Janne Grunau16eda4e2022-06-14 09:09:09 +0200305 ret = mbox_recv(rtk->chan, &msg, TIMEOUT_1SEC_US);
Mark Kettenis72d73012022-01-22 20:38:14 +0100306 if (ret < 0)
307 return ret;
308
309 endpoint = msg.msg1;
310 msgtype = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg.msg0);
311 if (endpoint != APPLE_RTKIT_EP_MGMT) {
312 printf("%s: unexpected endpoint %d\n", __func__, endpoint);
313 return -EINVAL;
314 }
315 if (msgtype != APPLE_RTKIT_MGMT_HELLO) {
316 printf("%s: unexpected message type %d\n", __func__, msgtype);
317 return -EINVAL;
318 }
319
320 min_ver = FIELD_GET(APPLE_RTKIT_MGMT_HELLO_MINVER, msg.msg0);
321 max_ver = FIELD_GET(APPLE_RTKIT_MGMT_HELLO_MAXVER, msg.msg0);
322 want_ver = min(APPLE_RTKIT_MAX_SUPPORTED_VERSION, max_ver);
323
324 if (min_ver > APPLE_RTKIT_MAX_SUPPORTED_VERSION) {
325 printf("%s: firmware min version %d is too new\n",
326 __func__, min_ver);
327 return -ENOTSUPP;
328 }
329
330 if (max_ver < APPLE_RTKIT_MIN_SUPPORTED_VERSION) {
331 printf("%s: firmware max version %d is too old\n",
332 __func__, max_ver);
333 return -ENOTSUPP;
334 }
335
336 /* Ack version. */
337 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_HELLO_REPLY) |
338 FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MINVER, want_ver) |
339 FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MAXVER, want_ver);
340 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200341 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100342 if (ret < 0)
343 return ret;
344
345wait_epmap:
346 /* Wait for endpoint map message. */
Janne Grunau16eda4e2022-06-14 09:09:09 +0200347 ret = mbox_recv(rtk->chan, &msg, TIMEOUT_1SEC_US);
Mark Kettenis72d73012022-01-22 20:38:14 +0100348 if (ret < 0)
349 return ret;
350
351 endpoint = msg.msg1;
352 msgtype = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg.msg0);
353 if (endpoint != APPLE_RTKIT_EP_MGMT) {
354 printf("%s: unexpected endpoint %d\n", __func__, endpoint);
355 return -EINVAL;
356 }
357 if (msgtype != APPLE_RTKIT_MGMT_EPMAP) {
358 printf("%s: unexpected message type %d\n", __func__, msgtype);
359 return -EINVAL;
360 }
361
362 bitmap = FIELD_GET(APPLE_RTKIT_MGMT_EPMAP_BITMAP, msg.msg0);
363 base = FIELD_GET(APPLE_RTKIT_MGMT_EPMAP_BASE, msg.msg0);
364 for (i = 0; i < 32; i++) {
365 if (bitmap & (1U << i))
366 endpoints[nendpoints++] = base * 32 + i;
367 }
368
369 /* Ack endpoint map. */
370 reply = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_EPMAP_REPLY) |
371 FIELD_PREP(APPLE_RTKIT_MGMT_EPMAP_BASE, base);
372 if (msg.msg0 & APPLE_RTKIT_MGMT_EPMAP_LAST)
373 reply |= APPLE_RTKIT_MGMT_EPMAP_LAST;
374 else
375 reply |= APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE;
376 msg.msg0 = reply;
377 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200378 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100379 if (ret < 0)
380 return ret;
381
382 if (reply & APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE)
383 goto wait_epmap;
384
385 for (i = 0; i < nendpoints; i++) {
Janne Grunaue3a438f2022-06-14 09:09:07 +0200386 /* Start only necessary endpoints. The syslog endpoint is
387 * particularly noisy and its message can't easily be handled
388 * within U-Boot.
389 */
390 switch (endpoints[i]) {
391 case APPLE_RTKIT_EP_MGMT:
392 case APPLE_RTKIT_EP_SYSLOG:
393 case APPLE_RTKIT_EP_DEBUG:
394 case APPLE_RTKIT_EP_TRACEKIT:
Mark Kettenis72d73012022-01-22 20:38:14 +0100395 continue;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200396 default:
397 break;
398 }
Mark Kettenis72d73012022-01-22 20:38:14 +0100399
400 /* Request endpoint. */
401 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_STARTEP) |
402 FIELD_PREP(APPLE_RTKIT_MGMT_STARTEP_EP, endpoints[i]) |
403 APPLE_RTKIT_MGMT_STARTEP_FLAG;
404 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200405 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100406 if (ret < 0)
407 return ret;
408 }
409
Hector Martinaa4e96b2025-04-20 13:58:03 +0200410 rtk->iop_pwr = APPLE_RTKIT_PWR_STATE_SLEEP;
411 rtk->ap_pwr = APPLE_RTKIT_PWR_STATE_QUIESCED;
412
413 while (rtk->iop_pwr != APPLE_RTKIT_PWR_STATE_ON) {
414 ret = apple_rtkit_poll(rtk, TIMEOUT_1SEC_US);
Mark Kettenis72d73012022-01-22 20:38:14 +0100415 if (ret < 0)
416 return ret;
Hector Martinaa4e96b2025-04-20 13:58:03 +0200417 }
Mark Kettenis72d73012022-01-22 20:38:14 +0100418
Hector Martinaa4e96b2025-04-20 13:58:03 +0200419 return 0;
420}
Mark Kettenis72d73012022-01-22 20:38:14 +0100421
Hector Martinaa4e96b2025-04-20 13:58:03 +0200422int apple_rtkit_set_ap_power(struct apple_rtkit *rtk, int pwrstate)
423{
424 struct apple_mbox_msg msg;
425 int ret;
Mark Kettenis72d73012022-01-22 20:38:14 +0100426
Hector Martinaa4e96b2025-04-20 13:58:03 +0200427 if (rtk->ap_pwr == pwrstate)
428 return 0;
Mark Kettenis72d73012022-01-22 20:38:14 +0100429
Hector Martinaa4e96b2025-04-20 13:58:03 +0200430 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_SET_AP_PWR_STATE) |
431 FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, pwrstate);
432 msg.msg1 = APPLE_RTKIT_EP_MGMT;
433 ret = mbox_send(rtk->chan, &msg);
434 if (ret < 0)
435 return ret;
Mark Kettenis72d73012022-01-22 20:38:14 +0100436
Hector Martinaa4e96b2025-04-20 13:58:03 +0200437 while (rtk->ap_pwr != pwrstate) {
438 ret = apple_rtkit_poll(rtk, TIMEOUT_1SEC_US);
439 if (ret < 0)
440 return ret;
Mark Kettenis72d73012022-01-22 20:38:14 +0100441 }
442
443 return 0;
444}
445
Janne Grunaue3a438f2022-06-14 09:09:07 +0200446int apple_rtkit_shutdown(struct apple_rtkit *rtk, int pwrstate)
Mark Kettenis72d73012022-01-22 20:38:14 +0100447{
448 struct apple_mbox_msg msg;
449 int ret;
450
Hector Martinaa4e96b2025-04-20 13:58:03 +0200451 if (rtk->ap_pwr != APPLE_RTKIT_PWR_STATE_QUIESCED) {
452 ret = apple_rtkit_set_ap_power(rtk, APPLE_RTKIT_PWR_STATE_QUIESCED);
453 if (ret < 0)
454 return ret;
455 }
456
Mark Kettenis72d73012022-01-22 20:38:14 +0100457 msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE) |
458 FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, pwrstate);
459 msg.msg1 = APPLE_RTKIT_EP_MGMT;
Janne Grunaue3a438f2022-06-14 09:09:07 +0200460 ret = mbox_send(rtk->chan, &msg);
Mark Kettenis72d73012022-01-22 20:38:14 +0100461 if (ret < 0)
462 return ret;
463
Hector Martinaa4e96b2025-04-20 13:58:03 +0200464 while (rtk->iop_pwr != pwrstate) {
465 ret = apple_rtkit_poll(rtk, TIMEOUT_1SEC_US);
466 if (ret < 0)
467 return ret;
468 }
Mark Kettenis72d73012022-01-22 20:38:14 +0100469
470 return 0;
471}