Skip to content

Commit

Permalink
修改bcm_rust
Browse files Browse the repository at this point in the history
尝试修改 probe 中的 unsafe 代码
改进 of_property_read_u32

Signed-off-by: Nostalgia <[email protected]>
  • Loading branch information
lvyuemeng committed Aug 14, 2024
1 parent af39c01 commit cf03d19
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 39 deletions.
34 changes: 21 additions & 13 deletions drivers/i2c/busses/i2c_bcm2835_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,11 +560,20 @@ impl platform::Driver for Bcm2835I2cDriver {
let bus_clk = i2c_dev.bcm2835_i2c_register_div(mclk)?;

let mut bus_clk_rate = 0;
if let Err(_) = dev.of_property_read_u32(c_str!("clock-frequency"), &mut bus_clk_rate) {
if let Err(_) = dev
.of_node()
.read_u32(c_str!("clock-frequency"), &mut bus_clk_rate)
{
dev_warn!(pdev, "Could not read clock-frequency property\n");
bus_clk_rate = bindings::I2C_MAX_STANDARD_MODE_FREQ;
};
dev_info!(pdev, "I2c bus device clock-frequency: {}\n", bus_clk_rate);

if let Err(_) = i2c_dev.bus_clk.set_rate_exclusive(bus_clk_rate as u64) {
dev_err!(pdev, "Could not set clock frequency\n");
}

/*
let ret =
unsafe { bindings::clk_set_rate_exclusive(bus_clk.as_ptr(), bus_clk_rate as u64) };
if ret < 0 {
Expand All @@ -574,7 +583,7 @@ impl platform::Driver for Bcm2835I2cDriver {
to_result(ret)
);
to_result(ret)?;
}
}*/

i2c_dev.bus_clk.prepare_enable()?;

Expand All @@ -595,30 +604,27 @@ impl platform::Driver for Bcm2835I2cDriver {
to_result(ret)?;
}*/

request_irq(
if let Err(_) = request_irq(
irq as u32,
Bcm2835I2cIrqHandler,
IRQF_SHARED as u64,
c_str!("i2c_bcm2835_rust"),
&i2c_dev,
)?;
) {
dev_err!(pdev, "Could not request IRQ\n");
}
i2c_dev.irq = irq;

// TODO: setup i2c_adapter
let quirks = I2cAdapterQuirks::new().set_flags(i2c::I2C_AQ_NO_CLK_STRETCH as u64);
// let mut adap = i2c_dev.adapter;
unsafe {
i2c_dev.adapter.i2c_set_adapdata(i2c_dev.as_ptr());
// TODO: set owner
// i2c_dev.adapter.set_owner((&bindings::__this_module) as *const _ as *mut _);
i2c_dev.adapter.set_class(bindings::I2C_CLASS_DEPRECATED);
let full_name = bindings::of_node_full_name((*pdev.raw_device()).of_node);
let adap_name =
CString::try_from_fmt(fmt!("bcm2835 ({})", CStr::from_char_ptr(full_name)))?;
i2c_dev.adapter.set_name(&adap_name);
i2c_dev.adapter.set_algorithm::<Bcm2835I2cAlgo>();
}
// i2c_dev.adapter = adap;

/*
* Disable the hardware clock stretching timeout. SMBUS
Expand All @@ -642,8 +648,7 @@ impl platform::Driver for Bcm2835I2cDriver {
// let mut adap = i2c_dev.adapter;
unsafe {
i2c_dev.adapter.i2c_set_adapdata(i2c_dev.as_ptr());
// TODO: set owner
// i2c_dev.adapter.set_owner((&bindings::__this_module) as *const _ as *mut _);
i2c_dev.adapter.set_owner(&THIS_MODULE);
i2c_dev.adapter.set_class(bindings::I2C_CLASS_DEPRECATED);
let full_name = bindings::of_node_full_name((*pdev.raw_device()).of_node);
let adap_name =
Expand All @@ -660,14 +665,17 @@ impl platform::Driver for Bcm2835I2cDriver {
i2c_dev.bcm2835_i2c_writel(BCM2835_I2C_CLKT, 0);
i2c_dev.bcm2835_i2c_writel(BCM2835_I2C_C, 0);

let ret = unsafe { bindings::i2c_add_adapter(i2c_dev.adapter.as_ptr()) };
dbg!("Try to add I2C adapter...");
i2c_dev.adapter.i2c_add_adapter()?;
dbg!("I2C adapter added!");
/*let ret = unsafe { bindings::i2c_add_adapter(i2c_dev.adapter.as_ptr()) };
if ret < 0 {
dev_info!(pdev, "Could not add I2C adapter: {:?}\n", to_result(ret));
unsafe {
bindings::free_irq(irq as u32, i2c_dev_ptr as *mut core::ffi::c_void);
}
}
let _ = to_result(ret)?;
let _ = to_result(ret)?;*/

let item = unsafe { Box::from_raw(i2c_dev_ptr) };
let dev_data = kernel::new_device_data!((), (), *item, "BCM2835_I2C device data")?;
Expand Down
17 changes: 0 additions & 17 deletions rust/kernel/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,23 +257,6 @@ impl Device {
// return ptr must be null.
Ok(ptr as *mut T)
}

// Find and read an array of 32 bit from a property.
pub fn of_property_read_u32(&self, propname: &'static CStr, out_values: &mut u32) -> Result {
// SAFETY: The safety requirements are satisfied by the existence of `RawDevice` and its
// safety requirements.
let ret = unsafe {
let np = (*self.raw_device()).of_node;
bindings::of_property_read_variable_u32_array(
np,
propname.as_char_ptr(),
out_values as *mut u32,
1,
0,
)
};
to_result(ret)
}
}

// SAFETY: The device returned by `raw_device` is the one for which we hold a reference.
Expand Down
22 changes: 14 additions & 8 deletions rust/kernel/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
prelude::ENOTSUPP,
str::CStr,
types::{ForeignOwnable, Opaque},
ThisModule,
};
use alloc::vec::Vec;
use core::{ffi::c_void, marker::PhantomData};
Expand Down Expand Up @@ -148,28 +149,33 @@ impl I2cAdapter {
self.0.name[len] = 0;
}

pub unsafe fn set_owner(&mut self, owner: *mut bindings::module) {
self.0.owner = owner
pub unsafe fn set_owner(mut self, owner: &'static ThisModule) -> Self {
self.0.owner = owner.as_ptr();
self
}

pub fn set_class(&mut self, class: u32) {
self.0.class = class
pub fn set_class(mut self, class: u32) -> Self {
self.0.class = class;
self
}

pub unsafe fn set_algorithm<T: I2cAlgorithm>(&mut self) {
self.0.algo = Adapter::<T>::build()
pub unsafe fn set_algorithm<T: I2cAlgorithm>(mut self) -> Self {
self.0.algo = Adapter::<T>::build();
self
}

pub unsafe fn setup_device(&mut self, device: &Device) {
pub unsafe fn setup_device(mut self, device: &Device) -> Self {
let dev_ptr = device.raw_device();
self.0.dev.parent = dev_ptr;
unsafe {
self.0.dev.of_node = (*dev_ptr).of_node;
}
self
}

pub unsafe fn set_quirks(&mut self, quirks: &I2cAdapterQuirks) {
pub unsafe fn set_quirks(mut self, quirks: &I2cAdapterQuirks) -> Self {
self.0.quirks = &quirks.0 as *const _;
self
}

pub fn timeout(&self) -> usize {
Expand Down
25 changes: 24 additions & 1 deletion rust/kernel/of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
//!
//! C header: [`include/linux/of_*.h`](../../../../include/linux/of_*.h)
use crate::{bindings, driver::RawDeviceId, str::BStr};
use crate::{
bindings,
driver::RawDeviceId,
error::{to_result, Result},
str::{BStr, CStr},
};

/// An open firmware device id.
#[derive(Clone, Copy)]
Expand Down Expand Up @@ -114,4 +119,22 @@ impl DeviceNode {
pub fn flags(&self) -> u64 {
self.0._flags
}

// Note: Try to implement in a award way. Wait for imporvement.
fn read_u32_array(&self, propname: &'static CStr, out_value: &mut u32, sz: usize) -> Result {
let ret = unsafe {
bindings::of_property_read_variable_u32_array(
self.as_ptr(),
propname.as_char_ptr(),
out_value,
sz,
0,
)
};
to_result(ret)
}

pub fn read_u32(&self, propname: &'static CStr, out_value: &mut u32) -> Result {
self.read_u32_array(propname, out_value, 1)
}
}

0 comments on commit cf03d19

Please sign in to comment.