Skip to content

Commit b690fb7

Browse files
committed
fixup! soc: apple: Add support for the AOP co-processor.
Adjust to newer DMA coherent allocator series. Signed-off-by: Janne Grunau <j@jannau.net>
1 parent 044cb9a commit b690fb7

1 file changed

Lines changed: 42 additions & 63 deletions

File tree

drivers/soc/apple/aop.rs

Lines changed: 42 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
use core::{arch::asm, mem, ptr, slice};
99

1010
use kernel::{
11-
bindings, c_str, device, dma,
11+
bindings, c_str, device,
12+
devres::Devres,
13+
dma::CoherentAllocation,
1214
error::from_err_ptr,
1315
io_mem::IoMem,
1416
module_platform_driver, new_condvar, new_mutex, of, platform,
@@ -145,7 +147,7 @@ struct AFKRingBuffer {
145147

146148
struct AFKEndpoint {
147149
index: u8,
148-
iomem: Option<dma::CoherentAllocation<u8, dma::CoherentAllocator>>,
150+
iomem: Option<CoherentAllocation<u8>>,
149151
txbuf: Option<AFKRingBuffer>,
150152
rxbuf: Option<AFKRingBuffer>,
151153
seq: u16,
@@ -199,7 +201,7 @@ impl AFKEndpoint {
199201
);
200202
return Err(EIO);
201203
}
202-
self.rxbuf = Some(self.parse_ring_buf(&client.dev, msg)?);
204+
self.rxbuf = Some(self.parse_ring_buf(msg)?);
203205
if self.txbuf.is_some() {
204206
rtkit.send_message(self.index, AFK_MSG_START)?;
205207
}
@@ -213,7 +215,7 @@ impl AFKEndpoint {
213215
);
214216
return Err(EIO);
215217
}
216-
self.txbuf = Some(self.parse_ring_buf(&client.dev, msg)?);
218+
self.txbuf = Some(self.parse_ring_buf(msg)?);
217219
if self.rxbuf.is_some() {
218220
rtkit.send_message(self.index, AFK_MSG_START)?;
219221
}
@@ -234,72 +236,49 @@ impl AFKEndpoint {
234236
Ok(())
235237
}
236238

237-
fn parse_ring_buf(&self, dev: &ARef<device::Device>, msg: u64) -> Result<AFKRingBuffer> {
239+
fn parse_ring_buf(&self, msg: u64) -> Result<AFKRingBuffer> {
238240
let msg = msg as usize;
239241
let size = ((msg >> 16) & 0xFFFF) * AFK_RB_BLOCK_STEP;
240242
let offset = ((msg >> 32) & 0xFFFF) * AFK_RB_BLOCK_STEP;
241-
let buf_size = self.iomem_read32(dev, offset)? as usize;
243+
let buf_size = self.iomem_read32(offset)? as usize;
242244
let block_size = (size - buf_size) / 3;
243245
Ok(AFKRingBuffer {
244246
offset,
245247
block_size,
246248
buf_size,
247249
})
248250
}
249-
fn iomem_write32(&mut self, dev: &ARef<device::Device>, off: usize, data: u32) -> Result<()> {
250-
let iomem = self.iomem.as_mut().unwrap();
251-
if off + mem::size_of::<u32>() > iomem.count() {
252-
dev_err!(dev, "Out of bounds iomem write");
253-
return Err(EIO);
254-
}
255-
unsafe {
256-
let ptr = iomem.first_ptr_mut().offset(off as isize) as *mut u32;
257-
*ptr = data;
258-
}
251+
fn iomem_write32(&mut self, off: usize, data: u32) -> Result<()> {
252+
let size = core::mem::size_of::<u32>();
253+
let data = data.to_le_bytes();
254+
let iomem = self.iomem.as_ref().unwrap();
255+
let buf = unsafe { iomem.as_slice_mut(off, size)? };
256+
buf.copy_from_slice(&data);
259257
Ok(())
260258
}
261-
fn iomem_read32(&self, dev: &ARef<device::Device>, off: usize) -> Result<u32> {
259+
fn iomem_read32(&self, off: usize) -> Result<u32> {
260+
let size = core::mem::size_of::<u32>();
262261
let iomem = self.iomem.as_ref().unwrap();
263-
if off + mem::size_of::<u32>() > iomem.count() {
264-
dev_err!(dev, "Out of bounds iomem read");
265-
return Err(EIO);
266-
}
267-
// SAFETY: all bit patterns are valid u32s
268-
unsafe {
269-
let ptr = iomem.first_ptr().offset(off as isize) as *const u32;
270-
Ok(*ptr)
271-
}
262+
let buf = unsafe { iomem.as_slice(off, size)? };
263+
Ok(u32::from_le_bytes(buf.try_into().unwrap()))
272264
}
273-
fn memcpy_from_iomem(
274-
&self,
275-
dev: &ARef<device::Device>,
276-
off: usize,
277-
target: &mut [u8],
278-
) -> Result<()> {
265+
fn memcpy_from_iomem(&self, off: usize, target: &mut [u8]) -> Result<()> {
279266
let iomem = self.iomem.as_ref().unwrap();
280-
if off + target.len() > iomem.count() {
281-
dev_err!(dev, "Out of bounds iomem read");
282-
return Err(EIO);
283-
}
284-
// SAFETY: We checked that it is in bounds above
267+
// SAFETY:
268+
// as_slice() checks that off and target.len() are whithin iomem's limits.
285269
unsafe {
286-
let ptr = iomem.first_ptr().offset(off as isize);
287-
let src = slice::from_raw_parts(ptr, target.len());
270+
let src = iomem.as_slice(off, target.len())?;
288271
target.copy_from_slice(src);
289272
}
290273
Ok(())
291274
}
292275

293-
fn memcpy_to_iomem(&self, dev: &ARef<device::Device>, off: usize, src: &[u8]) -> Result<()> {
276+
fn memcpy_to_iomem(&self, off: usize, src: &[u8]) -> Result<()> {
294277
let iomem = self.iomem.as_ref().unwrap();
295-
if off + src.len() > iomem.count() {
296-
dev_err!(dev, "Out of bounds iomem write");
297-
return Err(EIO);
298-
}
299-
// SAFETY: We checked that it is in bounds above
278+
// SAFETY:
279+
// as_slice_mut() checks that off and src.len() are whithin iomem's limits.
300280
unsafe {
301-
let ptr = iomem.first_ptr_mut().offset(off as isize);
302-
let target = slice::from_raw_parts_mut(ptr, src.len());
281+
let target = iomem.as_slice_mut(off, src.len())?;
303282
target.copy_from_slice(src);
304283
}
305284
Ok(())
@@ -320,8 +299,8 @@ impl AFKEndpoint {
320299
);
321300
return Err(EIO);
322301
}
323-
let iomem = dma::try_alloc_coherent(dev, size, false)?;
324-
rtkit.send_message(self.index, AFK_MSG_GET_BUF_ACK | iomem.dma_handle)?;
302+
let iomem = CoherentAllocation::<u8>::alloc_coherent(dev, size, GFP_KERNEL)?;
303+
rtkit.send_message(self.index, AFK_MSG_GET_BUF_ACK | iomem.dma_handle())?;
325304
self.iomem = Some(iomem);
326305
Ok(())
327306
}
@@ -338,15 +317,15 @@ impl AFKEndpoint {
338317
return Err(EIO);
339318
}
340319
};
341-
let mut rptr = self.iomem_read32(&client.dev, buf_offset + block_size)? as usize;
342-
let mut wptr = self.iomem_read32(&client.dev, buf_offset + block_size * 2)?;
320+
let mut rptr = self.iomem_read32(buf_offset + block_size)? as usize;
321+
let mut wptr = self.iomem_read32(buf_offset + block_size * 2)?;
343322
mem_sync();
344323
let base = buf_offset + block_size * 3;
345324
let mut msg_buf = KVec::new();
346325
const QEH_SIZE: usize = mem::size_of::<QEHeader>();
347326
while wptr as usize != rptr {
348327
let mut qeh_bytes = [0; QEH_SIZE];
349-
self.memcpy_from_iomem(&client.dev, base + rptr, &mut qeh_bytes)?;
328+
self.memcpy_from_iomem(base + rptr, &mut qeh_bytes)?;
350329
let mut qeh = unsafe { &*(qeh_bytes.as_ptr() as *const QEHeader) };
351330
if qeh.magic != QE_MAGIC1 && qeh.magic != QE_MAGIC2 {
352331
let magic = qeh.magic;
@@ -360,7 +339,7 @@ impl AFKEndpoint {
360339
}
361340
if qeh.size as usize > (buf_size - rptr - QEH_SIZE) {
362341
rptr = 0;
363-
self.memcpy_from_iomem(&client.dev, base + rptr, &mut qeh_bytes)?;
342+
self.memcpy_from_iomem(base + rptr, &mut qeh_bytes)?;
364343
qeh = unsafe { &*(qeh_bytes.as_ptr() as *const QEHeader) };
365344

366345
if qeh.magic != QE_MAGIC1 && qeh.magic != QE_MAGIC2 {
@@ -375,14 +354,14 @@ impl AFKEndpoint {
375354
}
376355
}
377356
msg_buf.resize(qeh.size as usize, 0, GFP_KERNEL)?;
378-
self.memcpy_from_iomem(&client.dev, base + rptr + QEH_SIZE, &mut msg_buf)?;
357+
self.memcpy_from_iomem(base + rptr + QEH_SIZE, &mut msg_buf)?;
379358
let (hdr_bytes, msg) = msg_buf.split_at(mem::size_of::<EPICHeader>());
380359
let header = unsafe { &*(hdr_bytes.as_ptr() as *const EPICHeader) };
381360
self.handle_ipc(client, qeh, header, msg)?;
382361
rptr = align_up(rptr + QEH_SIZE + qeh.size as usize, block_size) % buf_size;
383362
mem_sync();
384-
self.iomem_write32(&client.dev, buf_offset + block_size, rptr as u32)?;
385-
wptr = self.iomem_read32(&client.dev, buf_offset + block_size * 2)?;
363+
self.iomem_write32(buf_offset + block_size, rptr as u32)?;
364+
wptr = self.iomem_read32(buf_offset + block_size * 2)?;
386365
mem_sync();
387366
}
388367
Ok(())
@@ -483,8 +462,8 @@ impl AFKEndpoint {
483462
};
484463
let base = buf_offset + block_size * 3;
485464
mem_sync();
486-
let rptr = self.iomem_read32(&client.dev, buf_offset + block_size)? as usize;
487-
let mut wptr = self.iomem_read32(&client.dev, buf_offset + block_size * 2)? as usize;
465+
let rptr = self.iomem_read32(buf_offset + block_size)? as usize;
466+
let mut wptr = self.iomem_read32(buf_offset + block_size * 2)? as usize;
488467
const QEH_SIZE: usize = mem::size_of::<QEHeader>();
489468
if wptr < rptr && wptr + QEH_SIZE >= rptr {
490469
dev_err!(client.dev, "Tx buffer full at endpoint {}", self.index);
@@ -503,15 +482,15 @@ impl AFKEndpoint {
503482
mem::size_of::<QEHeader>(),
504483
)
505484
};
506-
self.memcpy_to_iomem(&client.dev, base + wptr, qeh_bytes)?;
485+
self.memcpy_to_iomem(base + wptr, qeh_bytes)?;
507486
if payload_len > buf_size - wptr - QEH_SIZE {
508487
wptr = 0;
509-
self.memcpy_to_iomem(&client.dev, base + wptr, qeh_bytes)?;
488+
self.memcpy_to_iomem(base + wptr, qeh_bytes)?;
510489
}
511-
self.memcpy_to_iomem(&client.dev, base + wptr + QEH_SIZE, header)?;
512-
self.memcpy_to_iomem(&client.dev, base + wptr + QEH_SIZE + header.len(), data)?;
490+
self.memcpy_to_iomem(base + wptr + QEH_SIZE, header)?;
491+
self.memcpy_to_iomem(base + wptr + QEH_SIZE + header.len(), data)?;
513492
wptr = align_up(wptr + QEH_SIZE + payload_len, block_size) % buf_size;
514-
self.iomem_write32(&client.dev, buf_offset + block_size * 2, wptr as u32)?;
493+
self.iomem_write32(buf_offset + block_size * 2, wptr as u32)?;
515494
let msg = wptr as u64 | (AFK_OPC_SEND << 48);
516495
rtkit.send_message(self.index, msg)
517496
}

0 commit comments

Comments
 (0)