forked from mirrors/linux
		
	 25601e8544
			
		
	
	
		25601e8544
		
	
	
	
	
		
			
			Here is the big set of char, misc, iio, and other smaller driver
 subsystems for 6.15-rc1.  Lots of stuff in here, including:
   - loads of IIO changes and driver updates
   - counter driver updates
   - w1 driver updates
   - faux conversions for some drivers that were abusing the platform bus
     interface
   - coresight driver updates
   - rust miscdevice binding updates based on real-world-use
   - other minor driver updates
 
 All of these have been in linux-next with no reported issues for quite a
 while.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZ+mNdQ8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ylktACfYJix41jCCDbiFjnu7Hz4OIdcrUsAnRyF164M
 1n5MhEhsEmvQj7WBwQLE
 =AmmW
 -----END PGP SIGNATURE-----
Merge tag 'char-misc-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char / misc / IIO driver updates from Greg KH:
 "Here is the big set of char, misc, iio, and other smaller driver
  subsystems for 6.15-rc1. Lots of stuff in here, including:
   - loads of IIO changes and driver updates
   - counter driver updates
   - w1 driver updates
   - faux conversions for some drivers that were abusing the platform
     bus interface
   - coresight driver updates
   - rust miscdevice binding updates based on real-world-use
   - other minor driver updates
  All of these have been in linux-next with no reported issues for quite
  a while"
* tag 'char-misc-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (292 commits)
  samples: rust_misc_device: fix markup in top-level docs
  Coresight: Fix a NULL vs IS_ERR() bug in probe
  misc: lis3lv02d: convert to use faux_device
  tlclk: convert to use faux_device
  regulator: dummy: convert to use the faux device interface
  bus: mhi: host: Fix race between unprepare and queue_buf
  coresight: configfs: Constify struct config_item_type
  doc: iio: ad7380: describe offload support
  iio: ad7380: add support for SPI offload
  iio: light: Add check for array bounds in veml6075_read_int_time_ms
  iio: adc: ti-ads7924 Drop unnecessary function parameters
  staging: iio: ad9834: Use devm_regulator_get_enable()
  staging: iio: ad9832: Use devm_regulator_get_enable()
  iio: gyro: bmg160_spi: add of_match_table
  dt-bindings: iio: adc: Add i.MX94 and i.MX95 support
  iio: adc: ad7768-1: remove unnecessary locking
  Documentation: ABI: add wideband filter type to sysfs-bus-iio
  iio: adc: ad7768-1: set MOSI idle state to prevent accidental reset
  iio: adc: ad7768-1: Fix conversion result sign
  iio: adc: ad7124: Benefit of dev = indio_dev->dev.parent in ad7124_parse_channel_config()
  ...
		
	
			
		
			
				
	
	
		
			239 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			239 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| 
 | |
| // Copyright (C) 2024 Google LLC.
 | |
| 
 | |
| //! Rust misc device sample.
 | |
| //!
 | |
| //! Below is an example userspace C program that exercises this sample's functionality.
 | |
| //!
 | |
| //! ```c
 | |
| //! #include <stdio.h>
 | |
| //! #include <stdlib.h>
 | |
| //! #include <errno.h>
 | |
| //! #include <fcntl.h>
 | |
| //! #include <unistd.h>
 | |
| //! #include <sys/ioctl.h>
 | |
| //!
 | |
| //! #define RUST_MISC_DEV_FAIL _IO('|', 0)
 | |
| //! #define RUST_MISC_DEV_HELLO _IO('|', 0x80)
 | |
| //! #define RUST_MISC_DEV_GET_VALUE _IOR('|', 0x81, int)
 | |
| //! #define RUST_MISC_DEV_SET_VALUE _IOW('|', 0x82, int)
 | |
| //!
 | |
| //! int main() {
 | |
| //!   int value, new_value;
 | |
| //!   int fd, ret;
 | |
| //!
 | |
| //!   // Open the device file
 | |
| //!   printf("Opening /dev/rust-misc-device for reading and writing\n");
 | |
| //!   fd = open("/dev/rust-misc-device", O_RDWR);
 | |
| //!   if (fd < 0) {
 | |
| //!     perror("open");
 | |
| //!     return errno;
 | |
| //!   }
 | |
| //!
 | |
| //!   // Make call into driver to say "hello"
 | |
| //!   printf("Calling Hello\n");
 | |
| //!   ret = ioctl(fd, RUST_MISC_DEV_HELLO, NULL);
 | |
| //!   if (ret < 0) {
 | |
| //!     perror("ioctl: Failed to call into Hello");
 | |
| //!     close(fd);
 | |
| //!     return errno;
 | |
| //!   }
 | |
| //!
 | |
| //!   // Get initial value
 | |
| //!   printf("Fetching initial value\n");
 | |
| //!   ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &value);
 | |
| //!   if (ret < 0) {
 | |
| //!     perror("ioctl: Failed to fetch the initial value");
 | |
| //!     close(fd);
 | |
| //!     return errno;
 | |
| //!   }
 | |
| //!
 | |
| //!   value++;
 | |
| //!
 | |
| //!   // Set value to something different
 | |
| //!   printf("Submitting new value (%d)\n", value);
 | |
| //!   ret = ioctl(fd, RUST_MISC_DEV_SET_VALUE, &value);
 | |
| //!   if (ret < 0) {
 | |
| //!     perror("ioctl: Failed to submit new value");
 | |
| //!     close(fd);
 | |
| //!     return errno;
 | |
| //!   }
 | |
| //!
 | |
| //!   // Ensure new value was applied
 | |
| //!   printf("Fetching new value\n");
 | |
| //!   ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &new_value);
 | |
| //!   if (ret < 0) {
 | |
| //!     perror("ioctl: Failed to fetch the new value");
 | |
| //!     close(fd);
 | |
| //!     return errno;
 | |
| //!   }
 | |
| //!
 | |
| //!   if (value != new_value) {
 | |
| //!     printf("Failed: Committed and retrieved values are different (%d - %d)\n", value, new_value);
 | |
| //!     close(fd);
 | |
| //!     return -1;
 | |
| //!   }
 | |
| //!
 | |
| //!   // Call the unsuccessful ioctl
 | |
| //!   printf("Attempting to call in to an non-existent IOCTL\n");
 | |
| //!   ret = ioctl(fd, RUST_MISC_DEV_FAIL, NULL);
 | |
| //!   if (ret < 0) {
 | |
| //!     perror("ioctl: Succeeded to fail - this was expected");
 | |
| //!   } else {
 | |
| //!     printf("ioctl: Failed to fail\n");
 | |
| //!     close(fd);
 | |
| //!     return -1;
 | |
| //!   }
 | |
| //!
 | |
| //!   // Close the device file
 | |
| //!   printf("Closing /dev/rust-misc-device\n");
 | |
| //!   close(fd);
 | |
| //!
 | |
| //!   printf("Success\n");
 | |
| //!   return 0;
 | |
| //! }
 | |
| //! ```
 | |
| 
 | |
| use core::pin::Pin;
 | |
| 
 | |
| use kernel::{
 | |
|     c_str,
 | |
|     device::Device,
 | |
|     fs::File,
 | |
|     ioctl::{_IO, _IOC_SIZE, _IOR, _IOW},
 | |
|     miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
 | |
|     new_mutex,
 | |
|     prelude::*,
 | |
|     sync::Mutex,
 | |
|     types::ARef,
 | |
|     uaccess::{UserSlice, UserSliceReader, UserSliceWriter},
 | |
| };
 | |
| 
 | |
| const RUST_MISC_DEV_HELLO: u32 = _IO('|' as u32, 0x80);
 | |
| const RUST_MISC_DEV_GET_VALUE: u32 = _IOR::<i32>('|' as u32, 0x81);
 | |
| const RUST_MISC_DEV_SET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x82);
 | |
| 
 | |
| module! {
 | |
|     type: RustMiscDeviceModule,
 | |
|     name: "rust_misc_device",
 | |
|     authors: ["Lee Jones"],
 | |
|     description: "Rust misc device sample",
 | |
|     license: "GPL",
 | |
| }
 | |
| 
 | |
| #[pin_data]
 | |
| struct RustMiscDeviceModule {
 | |
|     #[pin]
 | |
|     _miscdev: MiscDeviceRegistration<RustMiscDevice>,
 | |
| }
 | |
| 
 | |
| impl kernel::InPlaceModule for RustMiscDeviceModule {
 | |
|     fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
 | |
|         pr_info!("Initialising Rust Misc Device Sample\n");
 | |
| 
 | |
|         let options = MiscDeviceOptions {
 | |
|             name: c_str!("rust-misc-device"),
 | |
|         };
 | |
| 
 | |
|         try_pin_init!(Self {
 | |
|             _miscdev <- MiscDeviceRegistration::register(options),
 | |
|         })
 | |
|     }
 | |
| }
 | |
| 
 | |
| struct Inner {
 | |
|     value: i32,
 | |
| }
 | |
| 
 | |
| #[pin_data(PinnedDrop)]
 | |
| struct RustMiscDevice {
 | |
|     #[pin]
 | |
|     inner: Mutex<Inner>,
 | |
|     dev: ARef<Device>,
 | |
| }
 | |
| 
 | |
| #[vtable]
 | |
| impl MiscDevice for RustMiscDevice {
 | |
|     type Ptr = Pin<KBox<Self>>;
 | |
| 
 | |
|     fn open(_file: &File, misc: &MiscDeviceRegistration<Self>) -> Result<Pin<KBox<Self>>> {
 | |
|         let dev = ARef::from(misc.device());
 | |
| 
 | |
|         dev_info!(dev, "Opening Rust Misc Device Sample\n");
 | |
| 
 | |
|         KBox::try_pin_init(
 | |
|             try_pin_init! {
 | |
|                 RustMiscDevice {
 | |
|                     inner <- new_mutex!( Inner{ value: 0_i32 } ),
 | |
|                     dev: dev,
 | |
|                 }
 | |
|             },
 | |
|             GFP_KERNEL,
 | |
|         )
 | |
|     }
 | |
| 
 | |
|     fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize) -> Result<isize> {
 | |
|         dev_info!(me.dev, "IOCTLing Rust Misc Device Sample\n");
 | |
| 
 | |
|         let size = _IOC_SIZE(cmd);
 | |
| 
 | |
|         match cmd {
 | |
|             RUST_MISC_DEV_GET_VALUE => me.get_value(UserSlice::new(arg, size).writer())?,
 | |
|             RUST_MISC_DEV_SET_VALUE => me.set_value(UserSlice::new(arg, size).reader())?,
 | |
|             RUST_MISC_DEV_HELLO => me.hello()?,
 | |
|             _ => {
 | |
|                 dev_err!(me.dev, "-> IOCTL not recognised: {}\n", cmd);
 | |
|                 return Err(ENOTTY);
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         Ok(0)
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[pinned_drop]
 | |
| impl PinnedDrop for RustMiscDevice {
 | |
|     fn drop(self: Pin<&mut Self>) {
 | |
|         dev_info!(self.dev, "Exiting the Rust Misc Device Sample\n");
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl RustMiscDevice {
 | |
|     fn set_value(&self, mut reader: UserSliceReader) -> Result<isize> {
 | |
|         let new_value = reader.read::<i32>()?;
 | |
|         let mut guard = self.inner.lock();
 | |
| 
 | |
|         dev_info!(
 | |
|             self.dev,
 | |
|             "-> Copying data from userspace (value: {})\n",
 | |
|             new_value
 | |
|         );
 | |
| 
 | |
|         guard.value = new_value;
 | |
|         Ok(0)
 | |
|     }
 | |
| 
 | |
|     fn get_value(&self, mut writer: UserSliceWriter) -> Result<isize> {
 | |
|         let guard = self.inner.lock();
 | |
|         let value = guard.value;
 | |
| 
 | |
|         // Free-up the lock and use our locally cached instance from here
 | |
|         drop(guard);
 | |
| 
 | |
|         dev_info!(
 | |
|             self.dev,
 | |
|             "-> Copying data to userspace (value: {})\n",
 | |
|             &value
 | |
|         );
 | |
| 
 | |
|         writer.write::<i32>(&value)?;
 | |
|         Ok(0)
 | |
|     }
 | |
| 
 | |
|     fn hello(&self) -> Result<isize> {
 | |
|         dev_info!(self.dev, "-> Hello from the Rust Misc Device\n");
 | |
| 
 | |
|         Ok(0)
 | |
|     }
 | |
| }
 |