Skip to content

Commit 3ed9cc7

Browse files
WhatAmISupposedToPutHerejannau
authored andcommitted
rust: soc: apple: Add Apple mailbox abstractions
Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
1 parent a771853 commit 3ed9cc7

7 files changed

Lines changed: 123 additions & 2 deletions

File tree

drivers/soc/apple/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ config APPLE_SART
3838

3939
Say 'y' here if you have an Apple SoC.
4040

41+
config RUST_APPLE_MAILBOX
42+
bool
43+
depends on PM
44+
depends on RUST
45+
select APPLE_MAILBOX
46+
4147
config RUST_APPLE_RTKIT
4248
bool
4349
depends on PM

drivers/soc/apple/mailbox.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
#include <linux/of_platform.h>
2929
#include <linux/platform_device.h>
3030
#include <linux/pm_runtime.h>
31+
#include <linux/soc/apple/mailbox.h>
3132
#include <linux/spinlock.h>
3233
#include <linux/types.h>
33-
#include "mailbox.h"
3434

3535
#define APPLE_ASC_MBOX_CONTROL_FULL BIT(16)
3636
#define APPLE_ASC_MBOX_CONTROL_EMPTY BIT(17)

drivers/soc/apple/rtkit-internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
#include <linux/kernel.h>
1616
#include <linux/module.h>
1717
#include <linux/slab.h>
18+
#include <linux/soc/apple/mailbox.h>
1819
#include <linux/soc/apple/rtkit.h>
1920
#include <linux/workqueue.h>
20-
#include "mailbox.h"
2121

2222
#define APPLE_RTKIT_APP_ENDPOINT_START 0x20
2323
#define APPLE_RTKIT_MAX_ENDPOINTS 0x100

rust/bindings/bindings_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
#include <linux/sched.h>
8686
#include <linux/security.h>
8787
#include <linux/slab.h>
88+
#include <linux/soc/apple/mailbox.h>
8889
#include <linux/soc/apple/rtkit.h>
8990
#include <linux/task_work.h>
9091
#include <linux/tracepoint.h>

rust/kernel/soc/apple/mailbox.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
3+
//! Support for Apple ASC Mailbox.
4+
//!
5+
//! C header: [`include/linux/soc/apple/mailbox.h`](../../../../include/linux/gpio/driver.h)
6+
7+
use crate::{
8+
bindings,
9+
device,
10+
error::{
11+
from_err_ptr,
12+
to_result, //
13+
},
14+
prelude::*,
15+
str::CStrExt,
16+
types::{
17+
ForeignOwnable,
18+
ScopeGuard, //
19+
}, //
20+
};
21+
22+
use core::marker::PhantomData;
23+
24+
/// 96-bit message. What it means is up to the upper layer
25+
pub type Message = bindings::apple_mbox_msg;
26+
27+
/// Mailbox receive callback
28+
pub trait MailCallback {
29+
/// Callback context
30+
type Data: ForeignOwnable + Send + Sync;
31+
32+
/// The actual callback. Called in an interrupt context.
33+
fn recv_message(data: <Self::Data as ForeignOwnable>::Borrowed<'_>, msg: Message);
34+
}
35+
36+
/// Wrapper over `struct apple_mbox *`
37+
#[repr(transparent)]
38+
pub struct Mailbox<T: MailCallback> {
39+
mbox: *mut bindings::apple_mbox,
40+
_p: PhantomData<T>,
41+
}
42+
43+
extern "C" fn mailbox_rx_callback<T: MailCallback>(
44+
_mbox: *mut bindings::apple_mbox,
45+
msg: Message,
46+
cookie: *mut crate::ffi::c_void,
47+
) {
48+
// SAFETY: cookie came from a call to `into_foreign`
49+
T::recv_message(unsafe { T::Data::borrow(cookie.cast()) }, msg);
50+
}
51+
52+
impl<T: MailCallback> Mailbox<T> {
53+
/// Creates a mailbox for the specified name.
54+
pub fn new_byname(
55+
dev: &device::Device,
56+
mbox_name: &'static CStr,
57+
data: T::Data,
58+
) -> Result<Mailbox<T>> {
59+
let ptr: *mut crate::ffi::c_void = data.into_foreign().cast();
60+
let guard = ScopeGuard::new(|| {
61+
// SAFETY: `ptr` came from a previous call to `into_foreign`.
62+
unsafe { T::Data::from_foreign(ptr.cast()) };
63+
});
64+
// SAFETY: Just calling the c function, all values are valid.
65+
let mbox = unsafe {
66+
from_err_ptr(bindings::apple_mbox_get_byname(
67+
dev.as_raw(),
68+
mbox_name.as_char_ptr(),
69+
))?
70+
};
71+
// SAFETY: mbox is a valid pointer
72+
unsafe {
73+
(*mbox).cookie = ptr;
74+
(*mbox).rx = Some(mailbox_rx_callback::<T>);
75+
to_result(bindings::apple_mbox_start(mbox))?;
76+
}
77+
guard.dismiss();
78+
Ok(Mailbox {
79+
mbox,
80+
_p: PhantomData,
81+
})
82+
}
83+
/// Sends the specified message
84+
pub fn send(&self, msg: Message, atomic: bool) -> Result<()> {
85+
// SAFETY: Calling the c function, `mbox` is a valid pointer
86+
to_result(unsafe { bindings::apple_mbox_send(self.mbox, msg, atomic) })
87+
}
88+
}
89+
90+
impl<T: MailCallback> Drop for Mailbox<T> {
91+
fn drop(&mut self) {
92+
// SAFETY: mbox is a valid pointer
93+
unsafe { bindings::apple_mbox_stop(self.mbox) };
94+
// SAFETY: `cookie` came from `into_foreign`
95+
unsafe { T::Data::from_foreign((*self.mbox).cookie.cast()) };
96+
}
97+
}
98+
99+
unsafe impl<T> Sync for Mailbox<T>
100+
where
101+
T: MailCallback,
102+
T::Data: Sync,
103+
{
104+
}
105+
106+
unsafe impl<T> Send for Mailbox<T>
107+
where
108+
T: MailCallback,
109+
T::Data: Send,
110+
{
111+
}

rust/kernel/soc/apple/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ pub mod rtkit;
77

88
#[cfg(any(CONFIG_APPLE_AOP = "y", CONFIG_APPLE_AOP = "m"))]
99
pub mod aop;
10+
11+
#[cfg(CONFIG_RUST_APPLE_MAILBOX = "y")]
12+
pub mod mailbox;

0 commit comments

Comments
 (0)